1919#include  "context.h" 
2020#include  "linker.h" 
2121#include  "secure_transitions.h" 
22+ #include  "vmpu_mpu.h" 
23+ #include  "vmpu_unpriv_access.h" 
24+ 
25+ extern  uint32_t  g_debug_interrupt_sp [];
2226
2327void  debug_die (void )
2428{
@@ -29,15 +33,48 @@ void debug_die(void)
2933void  debug_deprivilege_and_return (void  *  debug_handler , void  *  return_handler ,
3034                                  uint32_t  a0 , uint32_t  a1 , uint32_t  a2 , uint32_t  a3 )
3135{
32-     /* Switch to the debug box. 
33-      * We use a regular process switch, so we don't need a dedicated stack for 
34-      * the debug box. */ 
35-     uint8_t  box_id  =  g_debug_box .box_id ;
36-     context_switch_in (CONTEXT_SWITCH_FUNCTION_DEBUG , box_id , __TZ_get_SP_NS (), g_context_current_states [box_id ].sp );
37- 
38-     /* De-privilege, call the debug box handler, re-privilege, call the return 
39-      * handler. */ 
40-     uint32_t  caller  =  UVISOR_GET_NS_ALIAS (UVISOR_GET_NS_ADDRESS ((uint32_t ) debug_handler ));
36+     /* Source box: Get the current stack pointer. */ 
37+     /* Note: The source stack pointer is only used to assess the stack 
38+      *       alignment and to read the xpsr. */ 
39+     uint32_t  src_sp  =  context_validate_exc_sf (__TZ_get_SP_NS ());
40+ 
41+     /* Destination box: The debug box. */ 
42+     uint8_t  dst_id  =  g_debug_box .box_id ;
43+ 
44+     /* Copy the xPSR from the source exception stack frame. */ 
45+     uint32_t  *  xpsr_p  =  & ((uint32_t  * ) src_sp )[7 ];
46+     uint32_t  xpsr  =  xPSR_T_Msk ;
47+     if  (vmpu_buffer_access_is_ok (g_active_box , xpsr_p , sizeof (* xpsr_p ))) {
48+         xpsr  =  vmpu_unpriv_uint32_read ((uint32_t ) xpsr_p );
49+     }
50+ 
51+     /* FIXME: This makes the debug box overwrite the top of the interrupt stack! */ 
52+     g_context_current_states [dst_id ].sp  =  g_debug_interrupt_sp [dst_id ];
53+ 
54+     /* Destination box: Forge the destination stack frame. */ 
55+     /* Note: We manually have to set the 4 parameters on the destination stack, 
56+     *       so we will set the API to have nargs=0. */ 
57+     uint32_t  dst_sp  =  context_forge_exc_sf (src_sp , dst_id , (uint32_t ) debug_handler , (uint32_t ) return_handler , xPSR_T_Msk , 0 );
58+     ((uint32_t  * ) dst_sp )[0 ] =  a0 ;
59+     ((uint32_t  * ) dst_sp )[1 ] =  a1 ;
60+     ((uint32_t  * ) dst_sp )[2 ] =  a2 ;
61+     ((uint32_t  * ) dst_sp )[3 ] =  a3 ;
62+ 
63+     /* Suspend the OS. */ 
64+     //g_priv_sys_hooks.priv_os_suspend(); 
65+ 
66+     /* Stop all lower-than-SVC-priority interrupts. FIXME Enable debug box to 
67+     * do things that require interrupts. One idea would be to provide an SVC 
68+     * to re-enable interrupts that can only be called by the debug box during 
69+     * debug handling. */ 
70+     __set_BASEPRI (__UVISOR_NVIC_MIN_PRIORITY  << (8U  -  __NVIC_PRIO_BITS ));
71+ 
72+     context_switch_in (CONTEXT_SWITCH_FUNCTION_DEBUG , dst_id , src_sp , dst_sp );
73+ 
74+     /* Upon execution return debug_handler will be executed. Upon return from 
75+     * debug_handler, return_handler will be executed. */ 
76+ 
77+     //uint32_t caller = UVISOR_GET_NS_ALIAS(UVISOR_GET_NS_ADDRESS((uint32_t) debug_handler)); 
4178    SECURE_TRANSITION_S_TO_NS (caller , a0 , a1 , a2 , a3 );
4279    ((void  (* )(void )) return_handler )();
4380}
0 commit comments