Skip to content

Commit d6254a5

Browse files
authored
Merge pull request #13 from ZaparooProject/fix/atari-frontend-launch-freeze
fix(zaparoo): shut down frontend before FPGA reconfig to stop atari launch freeze
2 parents 82f4021 + a2eacf8 commit d6254a5

2 files changed

Lines changed: 34 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: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
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"
24+
#include "scheduler.h"
2325
#include "shmem.h"
2426
#include "user_io.h"
2527
#include "video.h"
@@ -472,10 +474,37 @@ static void exec_launcher_child(const char *path)
472474
_exit(1);
473475
}
474476

477+
// Bounded replacement for video_chvt(): its VT_WAITACTIVE blocks forever if the
478+
// frontend stalls bringing up video, which would wedge the poll cothread.
479+
static void switch_to_launcher_vt(void)
480+
{
481+
int fd = open("/dev/tty0", O_RDONLY | O_CLOEXEC);
482+
if (fd < 0) return;
483+
484+
if (ioctl(fd, VT_ACTIVATE, s_vt)) printf("alt_launcher: VT_ACTIVATE fails\n");
485+
486+
// Yield to the scheduler rather than usleep() so the poll cothread stays
487+
// cooperative while we wait (bounded) for the VT to become active.
488+
unsigned long deadline = GetTimer(500);
489+
for (;;)
490+
{
491+
struct vt_stat st;
492+
if (!ioctl(fd, VT_GETSTATE, &st) && st.v_active == s_vt) break;
493+
if (CheckTimer(deadline)) break;
494+
scheduler_yield();
495+
}
496+
497+
close(fd);
498+
}
499+
475500
static void finalize_spawn(void)
476501
{
502+
// Defer the VT/fb takeover until the FPGA/HDMI has settled; s_tty_deadline
503+
// stays armed so this retries on a later alt_launcher_poll pass.
504+
if (!is_fpga_ready(1)) return;
505+
477506
s_tty_deadline = 0;
478-
video_chvt(s_vt);
507+
switch_to_launcher_vt();
479508
if (!s_native_crt)
480509
video_fb_enable(1);
481510
else

0 commit comments

Comments
 (0)