Skip to content

Commit 515e011

Browse files
committed
Trap guestOS to run SDL-oriented applications
To trap the guest OS SDL applications, virtual memory translation should be handled when accessing the bidirectional event queues in syscall_sdl.c. Additionally, when using the guest OS, the SDL application might be launched and terminated multiple times. To enhance the user experience, it is heuristic to properly handle three main types of exits: 1, SDL application built-in exit: The source code of the SDL application should be modified to call the syscall_exit(syscall number: 93) somewhere when executing cleanup routine before exit(). 2. Ctrl-c (SIGINT) exit: Detect the ctrl-c keycode. 3. SDL window Quit event: The source code of the SDL application should be modified to call the syscall_exit(syscall number: 93) when receiving SDL window Quit event. The main reason for handling these three types of exits is that SDL2_Mixer may malfunction if not properly initialized and destroyed, as it runs on the host side not on the guest side. Additionally, when terminating an SDL application in the guest OS, the previous SDL window should be closed. Moreover, the default audio backend of SDL2_Mixer(downloadable from brew or Linux distro pkg managers), FluidSynth, occasionally generates the warning: "fluidsynth: warning: Ringbuffer full, try increasing synth.polyphony!" This issue causes the audio to hang, leading to an unstable playback experience. Thus, dropping FluidSynth in favor of the Timidity backend, which provides a stable audio playback experience. Known issue: Calling SDL_DestroyWindow() on macOS does not close the previous SDL window. Close: #510
1 parent 80658a8 commit 515e011

File tree

5 files changed

+226
-28
lines changed

5 files changed

+226
-28
lines changed

src/devices/uart.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include <unistd.h>
1313

1414
#include "uart.h"
15-
1615
/* Emulate 8250 (plain, without loopback mode support) */
1716

1817
#define U8250_INTR_THRE 1
@@ -66,10 +65,22 @@ static uint8_t u8250_handle_in(u8250_state_t *uart)
6665
if (value == 1) { /* start of heading (Ctrl-a) */
6766
if (getchar() == 120) { /* keyboard x */
6867
printf("\n"); /* end emulator with newline */
69-
exit(0);
68+
exit(EXIT_SUCCESS);
7069
}
7170
}
7271

72+
#if RV32_HAS(SDL) && RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER)
73+
/*
74+
* The guestOS may repeatedly open and close the SDL window,
75+
* and the user could close the application by pressing the ctrl-c key.
76+
* Need to trap the ctrl-c key and ensure the SDL window and
77+
* SDL mixer are destroyed properly.
78+
*/
79+
extern void sdl_video_audio_cleanup();
80+
if (value == 3) /* ctrl-c */
81+
sdl_video_audio_cleanup();
82+
#endif
83+
7384
return value;
7485
}
7586

src/emulate.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,22 @@ void ecall_handler(riscv_t *rv)
12991299
syscall_handler(rv);
13001300
#elif RV32_HAS(SYSTEM)
13011301
if (rv->priv_mode == RV_PRIV_U_MODE) {
1302-
SET_CAUSE_AND_TVAL_THEN_TRAP(rv, ECALL_U, 0);
1302+
switch (rv_get_reg(
1303+
rv,
1304+
rv_reg_a7)) { /* trap guestOS's SDL-oriented application syscall */
1305+
case 0xBEEF:
1306+
case 0xC0DE:
1307+
case 0xFEED:
1308+
case 0xBABE:
1309+
case 0xD00D:
1310+
case 93:
1311+
syscall_handler(rv);
1312+
rv->PC += 4;
1313+
break;
1314+
default:
1315+
SET_CAUSE_AND_TVAL_THEN_TRAP(rv, ECALL_U, 0);
1316+
break;
1317+
}
13031318
} else if (rv->priv_mode ==
13041319
RV_PRIV_S_MODE) { /* trap to SBI syscall handler */
13051320
rv->PC += 4;

src/syscall.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,20 @@ static void syscall_write(riscv_t *rv)
132132
rv_set_reg(rv, rv_reg_a0, -1);
133133
}
134134

135-
136135
static void syscall_exit(riscv_t *rv)
137136
{
137+
#if RV32_HAS(SDL) && RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER)
138+
/*
139+
* The guestOS may repeatedly open and close the SDL window,
140+
* and the user could close the application using the application’s
141+
* built-in exit function. Need to trap the built-in exit and
142+
* ensure the SDL window and SDL mixer are destroyed properly.
143+
*/
144+
extern void sdl_video_audio_cleanup();
145+
sdl_video_audio_cleanup();
146+
return;
147+
#endif
148+
138149
/* simply halt cpu and save exit code.
139150
* the application decides the usage of exit code
140151
*/

0 commit comments

Comments
 (0)