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