Skip to content

Commit 01f8cfe

Browse files
committed
fix(zaparoo): shut down frontend before FPGA reconfig to stop launch freeze
Launching a core from the launcher frontend could hard-freeze the device (silent black screen, reboot required) — reliably reproduced on atari5200 /atari800. The frontend process stays alive holding mmaps into /dev/fb0, the HPS framebuffer the FPGA scans out over the f2sdram bridge. fpga_load_rbf calls do_bridge(0) to reset that bridge while the frontend is still mapped to it, deadlocking the AXI bus mid-reconfiguration. Upstream has no frontend, so it never hits this. Move the frontend teardown ahead of reconfiguration: call alt_launcher_shutdown() at the top of fpga_load_rbf so the frontend (and its framebuffer) is gone before do_bridge(0)/socfpga_load. The call is idempotent, so app_restart's existing call is left untouched. Also harden the frontend VT takeover: replace the unbounded video_chvt() (VT_WAITACTIVE blocks forever if the frontend stalls bringing up video) with a bounded VT_ACTIVATE + VT_GETSTATE poll, and defer the takeover until the FPGA is ready. This fixes a separate poll-cothread wedge during menu+frontend bring-up after a 15kHz core.
1 parent 492b3bf commit 01f8cfe

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

fpga_io.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,10 @@ static int make_env(const char *name, const char *cfg)
427427

428428
int fpga_load_rbf(const char *name, const char *cfg, const char *xml)
429429
{
430+
// Tear down the launcher frontend (and its HPS framebuffer mmaps) before any
431+
// FPGA reconfiguration. A live frontend scanning out /dev/fb0 over the f2sdram
432+
// bridge deadlocks the AXI bus when do_bridge(0) resets it during load.
433+
alt_launcher_shutdown();
430434
OsdDisable();
431435
static char path[1024];
432436
int ret = 0;

support/zaparoo/alt_launcher.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <sys/wait.h>
1818
#include "cfg.h"
1919
#include "file_io.h"
20+
#include "fpga_io.h"
2021
#include "hardware.h"
2122
#include "input.h"
2223
#include "menu.h"
@@ -472,10 +473,33 @@ static void exec_launcher_child(const char *path)
472473
_exit(1);
473474
}
474475

476+
// Bounded replacement for video_chvt(): its VT_WAITACTIVE blocks forever if the
477+
// frontend stalls bringing up video, which would wedge the poll cothread.
478+
static void switch_to_launcher_vt(void)
479+
{
480+
int fd = open("/dev/tty0", O_RDONLY | O_CLOEXEC);
481+
if (fd < 0) return;
482+
483+
if (ioctl(fd, VT_ACTIVATE, s_vt)) printf("alt_launcher: VT_ACTIVATE fails\n");
484+
485+
for (int i = 0; i < 50; i++)
486+
{
487+
struct vt_stat st;
488+
if (!ioctl(fd, VT_GETSTATE, &st) && st.v_active == s_vt) break;
489+
usleep(10000);
490+
}
491+
492+
close(fd);
493+
}
494+
475495
static void finalize_spawn(void)
476496
{
497+
// Defer the VT/fb takeover until the FPGA/HDMI has settled; s_tty_deadline
498+
// stays armed so this retries on a later alt_launcher_poll pass.
499+
if (!is_fpga_ready(1)) return;
500+
477501
s_tty_deadline = 0;
478-
video_chvt(s_vt);
502+
switch_to_launcher_vt();
479503
if (!s_native_crt)
480504
video_fb_enable(1);
481505
else

0 commit comments

Comments
 (0)