@@ -141,6 +141,40 @@ static void emu_update_vfs_interrupts(vm_t *vm)
141141}
142142#endif
143143
144+ static inline void emu_tick_peripherals (emu_state_t * emu )
145+ {
146+ vm_t * vm = & emu -> vm ;
147+
148+ if (emu -> peripheral_update_ctr -- == 0 ) {
149+ emu -> peripheral_update_ctr = 64 ;
150+
151+ u8250_check_ready (& emu -> uart );
152+ if (emu -> uart .in_ready )
153+ emu_update_uart_interrupts (vm );
154+
155+ #if SEMU_HAS (VIRTIONET )
156+ virtio_net_refresh_queue (& emu -> vnet );
157+ if (emu -> vnet .InterruptStatus )
158+ emu_update_vnet_interrupts (vm );
159+ #endif
160+
161+ #if SEMU_HAS (VIRTIOBLK )
162+ if (emu -> vblk .InterruptStatus )
163+ emu_update_vblk_interrupts (vm );
164+ #endif
165+
166+ #if SEMU_HAS (VIRTIOSND )
167+ if (emu -> vsnd .InterruptStatus )
168+ emu_update_vsnd_interrupts (vm );
169+ #endif
170+
171+ #if SEMU_HAS (VIRTIOFS )
172+ if (emu -> vfs .InterruptStatus )
173+ emu_update_vfs_interrupts (vm );
174+ #endif
175+ }
176+ }
177+
144178static void mem_load (hart_t * hart ,
145179 uint32_t addr ,
146180 uint8_t width ,
@@ -796,13 +830,19 @@ static void hart_exec_loop(void *arg)
796830 while (!emu -> stopped ) {
797831 /* Check if hart is ready to execute (HSM state) */
798832 if (hart -> hsm_status != SBI_HSM_STATE_STARTED ) {
833+ emu_tick_peripherals (emu );
834+ emu_update_timer_interrupt (hart );
835+ emu_update_swi_interrupt (hart );
799836 /* Hart not started yet, yield and wait */
800837 coro_yield ();
801838 continue ;
802839 }
803840
804841 /* Execute a batch of instructions before yielding */
805842 for (int i = 0 ; i < 64 ; i ++ ) {
843+ emu_tick_peripherals (emu );
844+ emu_update_timer_interrupt (hart );
845+ emu_update_swi_interrupt (hart );
806846 /* Execute one instruction */
807847 vm_step (hart );
808848
@@ -842,34 +882,7 @@ static int semu_step(emu_state_t *emu)
842882 * RFENCE extension is completely implemented.
843883 */
844884 for (uint32_t i = 0 ; i < vm -> n_hart ; i ++ ) {
845- if (emu -> peripheral_update_ctr -- == 0 ) {
846- emu -> peripheral_update_ctr = 64 ;
847-
848- u8250_check_ready (& emu -> uart );
849- if (emu -> uart .in_ready )
850- emu_update_uart_interrupts (vm );
851-
852- #if SEMU_HAS (VIRTIONET )
853- virtio_net_refresh_queue (& emu -> vnet );
854- if (emu -> vnet .InterruptStatus )
855- emu_update_vnet_interrupts (vm );
856- #endif
857-
858- #if SEMU_HAS (VIRTIOBLK )
859- if (emu -> vblk .InterruptStatus )
860- emu_update_vblk_interrupts (vm );
861- #endif
862-
863- #if SEMU_HAS (VIRTIOSND )
864- if (emu -> vsnd .InterruptStatus )
865- emu_update_vsnd_interrupts (vm );
866- #endif
867-
868- #if SEMU_HAS (VIRTIOFS )
869- if (emu -> vfs .InterruptStatus )
870- emu_update_vfs_interrupts (vm );
871- #endif
872- }
885+ emu_tick_peripherals (emu );
873886
874887 emu_update_timer_interrupt (vm -> hart [i ]);
875888 emu_update_swi_interrupt (vm -> hart [i ]);
@@ -993,41 +1006,7 @@ static int semu_run(emu_state_t *emu)
9931006 }
9941007#endif
9951008
996- /* Update peripherals periodically */
9971009 while (!emu -> stopped ) {
998- /* Update peripherals every 64 instructions */
999- if (emu -> peripheral_update_ctr -- == 0 ) {
1000- emu -> peripheral_update_ctr = 64 ;
1001-
1002- u8250_check_ready (& emu -> uart );
1003- if (emu -> uart .in_ready )
1004- emu_update_uart_interrupts (vm );
1005-
1006- #if SEMU_HAS (VIRTIONET )
1007- virtio_net_refresh_queue (& emu -> vnet );
1008- if (emu -> vnet .InterruptStatus )
1009- emu_update_vnet_interrupts (vm );
1010- #endif
1011- #if SEMU_HAS (VIRTIOBLK )
1012- if (emu -> vblk .InterruptStatus )
1013- emu_update_vblk_interrupts (vm );
1014- #endif
1015- #if SEMU_HAS (VIRTIOSND )
1016- if (emu -> vsnd .InterruptStatus )
1017- emu_update_vsnd_interrupts (vm );
1018- #endif
1019- #if SEMU_HAS (VIRTIOFS )
1020- if (emu -> vfs .InterruptStatus )
1021- emu_update_vfs_interrupts (vm );
1022- #endif
1023- }
1024-
1025- /* Update timer and software interrupts for all harts */
1026- for (uint32_t i = 0 ; i < vm -> n_hart ; i ++ ) {
1027- emu_update_timer_interrupt (vm -> hart [i ]);
1028- emu_update_swi_interrupt (vm -> hart [i ]);
1029- }
1030-
10311010 /* Resume each hart's coroutine in round-robin fashion */
10321011 for (uint32_t i = 0 ; i < vm -> n_hart ; i ++ ) {
10331012 coro_resume_hart (i );
0 commit comments