@@ -141,7 +141,7 @@ uint32_t uvm32_run(uvm32_state_t *vmst, uvm32_evt_t *evt, uint32_t instr_meter)
141141 uint32_t num_instr = 0 ;
142142
143143 if (vmst -> stack_canary != UVM32_NULL && * vmst -> stack_canary != STACK_CANARY_VALUE ) {
144- setStatusErr (vmst , UVM32_ERR_STACKOVERFLOW );
144+ setStatusErr (vmst , UVM32_ERR_INTERNAL_CORE );
145145 setup_err_evt (vmst , evt );
146146 return num_instr ;
147147 }
@@ -159,50 +159,58 @@ uint32_t uvm32_run(uvm32_state_t *vmst, uvm32_evt_t *evt, uint32_t instr_meter)
159159 uint64_t elapsedUs = 1 ;
160160 uint32_t ret ;
161161 ret = MiniRV32IMAStep (vmst , & vmst -> core , vmst -> memory , 0 , elapsedUs , 1 );
162- if (3 == ret ) {
163- // Fetch registers used by syscall
164- const uint32_t syscall = vmst -> core .regs [17 ]; // a7
165- // on exception we should jump to mtvec, but we handle directly
166- // and skip over the ecall instruction
167- vmst -> core .pc += 4 ;
168- switch (syscall ) {
169- // inbuilt syscalls
170- case UVM32_SYSCALL_HALT :
171- setStatus (vmst , UVM32_STATUS_ENDED );
172- break ;
173- case UVM32_SYSCALL_STACKPROTECT : {
174- // don't allow errant code to change it once set
175- if (vmst -> stack_canary == (uint8_t * )UVM32_NULL ) {
176- uint32_t param0 = vmst -> core .regs [10 ]; // a0
177- uint32_t mem_offset = param0 - MINIRV32_RAM_IMAGE_OFFSET ;
178-
179- // check data fits in ram
180- if (mem_offset > UVM32_MEMORY_SIZE ) {
181- setStatusErr (vmst , UVM32_ERR_STACKOVERFLOW );
182- setup_err_evt (vmst , evt );
183- }
184- // check canary is inside valid memory
185- if (mem_offset < UVM32_MEMORY_SIZE ) {
186- // set canary
187- vmst -> stack_canary = & vmst -> memory [mem_offset ];
188- * vmst -> stack_canary = STACK_CANARY_VALUE ;
162+
163+ switch (ret ) {
164+ case 0 : // ok
165+ break ;
166+ case 12 : { // ecall
167+ // Fetch registers used by syscall
168+ const uint32_t syscall = vmst -> core .regs [17 ]; // a7
169+ // on exception we should jump to mtvec, but we handle directly
170+ // and skip over the ecall instruction
171+ vmst -> core .pc += 4 ;
172+ switch (syscall ) {
173+ // inbuilt syscalls
174+ case UVM32_SYSCALL_HALT :
175+ setStatus (vmst , UVM32_STATUS_ENDED );
176+ break ;
177+ case UVM32_SYSCALL_STACKPROTECT : {
178+ // don't allow errant code to change it once set
179+ if (vmst -> stack_canary == (uint8_t * )UVM32_NULL ) {
180+ uint32_t param0 = vmst -> core .regs [10 ]; // a0
181+ uint32_t mem_offset = param0 - MINIRV32_RAM_IMAGE_OFFSET ;
182+ mem_offset &= ~0xF ; // round up by 16 bytes
183+ mem_offset += 16 * 4 ;
184+
185+ // check data fits in ram
186+ if (mem_offset > UVM32_MEMORY_SIZE ) {
187+ setStatusErr (vmst , UVM32_ERR_INTERNAL_CORE );
188+ setup_err_evt (vmst , evt );
189+ }
190+ // check canary is inside valid memory
191+ if (mem_offset < UVM32_MEMORY_SIZE ) {
192+ // set canary
193+ vmst -> stack_canary = & vmst -> memory [mem_offset ];
194+ * vmst -> stack_canary = STACK_CANARY_VALUE ;
195+ }
189196 }
190- }
191- } break ;
192- default :
193- // user defined syscalls
194- vmst -> ioevt .typ = UVM32_EVT_SYSCALL ;
195- vmst -> ioevt .data .syscall .code = syscall ;
196- vmst -> ioevt .data .syscall .ret = & vmst -> core .regs [12 ]; // a2
197- vmst -> ioevt .data .syscall .params [0 ] = & vmst -> core .regs [10 ]; // a0
198- vmst -> ioevt .data .syscall .params [1 ] = & vmst -> core .regs [11 ]; // a1
199- setStatus (vmst , UVM32_STATUS_PAUSED );
200- break ;
201- }
202- } else if (ret != 0 ) {
203- // unhandled exception
204- setStatusErr (vmst , UVM32_ERR_INTERNAL_CORE );
205- setup_err_evt (vmst , evt );
197+ } break ;
198+ default :
199+ // user defined syscalls
200+ vmst -> ioevt .typ = UVM32_EVT_SYSCALL ;
201+ vmst -> ioevt .data .syscall .code = syscall ;
202+ vmst -> ioevt .data .syscall .ret = & vmst -> core .regs [12 ]; // a2
203+ vmst -> ioevt .data .syscall .params [0 ] = & vmst -> core .regs [10 ]; // a0
204+ vmst -> ioevt .data .syscall .params [1 ] = & vmst -> core .regs [11 ]; // a1
205+ setStatus (vmst , UVM32_STATUS_PAUSED );
206+ break ;
207+ } // end switch(syscall)
208+ } break ; // end ecall
209+ default :
210+ // unhandled exception
211+ setStatusErr (vmst , UVM32_ERR_INTERNAL_CORE );
212+ setup_err_evt (vmst , evt );
213+ break ;
206214 }
207215
208216 num_instr ++ ;
@@ -213,8 +221,10 @@ uint32_t uvm32_run(uvm32_state_t *vmst, uvm32_evt_t *evt, uint32_t instr_meter)
213221 setup_err_evt (vmst , evt );
214222 return num_instr ;
215223 }
224+
216225 }
217226
227+
218228 if (vmst -> status == UVM32_STATUS_ENDED ) {
219229 evt -> typ = UVM32_EVT_END ;
220230 return num_instr ;
0 commit comments