19
19
#include "context.h"
20
20
#include "linker.h"
21
21
#include "secure_transitions.h"
22
+ #include "vmpu_mpu.h"
23
+ #include "vmpu_unpriv_access.h"
24
+
25
+ extern uint32_t g_debug_interrupt_sp [];
22
26
23
27
void debug_die (void )
24
28
{
@@ -29,15 +33,48 @@ void debug_die(void)
29
33
void debug_deprivilege_and_return (void * debug_handler , void * return_handler ,
30
34
uint32_t a0 , uint32_t a1 , uint32_t a2 , uint32_t a3 )
31
35
{
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));
41
78
SECURE_TRANSITION_S_TO_NS (caller , a0 , a1 , a2 , a3 );
42
79
((void (* )(void )) return_handler )();
43
80
}
0 commit comments