Skip to content

Commit 80115d0

Browse files
authored
Merge pull request #334 from AlessandroA/virtualize_nvic_systemreset
Virtualize NVIC_SystemReset
2 parents 068ddcc + 7907d36 commit 80115d0

File tree

7 files changed

+40
-16
lines changed

7 files changed

+40
-16
lines changed

api/inc/cmsis_nvic_virtual.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define __UVISOR_API_NVIC_VIRTUAL_H__
1919

2020
#include "api/inc/interrupts.h"
21+
#include "api/inc/unvic_exports.h"
2122

2223
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
2324
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
@@ -29,5 +30,6 @@
2930
#define NVIC_GetActive __NVIC_GetActive
3031
#define NVIC_SetPriority vIRQ_SetPriority
3132
#define NVIC_GetPriority vIRQ_GetPriority
33+
#define NVIC_SystemReset() vIRQ_SystemReset(RESET_REASON_NO_REASON)
3234

3335
#endif /* __UVISOR_API_NVIC_VIRTUAL_H__ */

api/inc/halt_exports.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
typedef enum {
3131
USER_NOT_ALLOWED = 1,
32+
DEBUG_BOX_HALT,
3233
} THaltUserError;
3334

3435
typedef enum {

api/inc/interrupts.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef __UVISOR_API_INTERRUPTS_H__
1818
#define __UVISOR_API_INTERRUPTS_H__
1919

20+
#include "api/inc/unvic_exports.h"
2021
#include "api/inc/uvisor_exports.h"
2122
#include <stdint.h>
2223

@@ -60,4 +61,10 @@ UVISOR_EXTERN void vIRQ_DisableAll(void);
6061
* ::vIRQ_DisableAll for more information. */
6162
UVISOR_EXTERN void vIRQ_EnableAll(void);
6263

64+
/** Reset the device.
65+
* @warning Currently only the debug box can reset the device.
66+
* @param reason[in] Reason for rebooting. Currently not used.
67+
*/
68+
UVISOR_EXTERN void vIRQ_SystemReset(TResetReason reason);
69+
6370
#endif /* __UVISOR_API_INTERRUPTS_H__ */

api/inc/unvic_exports.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@
2828
* priorities available to them */
2929
#define UVISOR_VIRQ_MAX_PRIORITY ((uint32_t) (1 << __NVIC_PRIO_BITS) - 1 - __UVISOR_NVIC_MIN_PRIORITY)
3030

31+
/* Reasons for rebooting */
32+
typedef enum {
33+
RESET_REASON_NO_REASON = 0,
34+
RESET_REASON_HALT,
35+
__TRESETREASON_MAX /* Always keep the last element of the enum. */
36+
} TResetReason;
37+
3138
/* Offset of NVIC interrupts with respect to handler 0 */
3239
#define NVIC_OFFSET 16
3340

api/src/interrupts.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,13 @@ int vIRQ_GetLevel(void)
165165
return UVISOR_SVC(UVISOR_SVC_ID_IRQ_LEVEL_GET, "");
166166
}
167167
}
168+
169+
void vIRQ_SystemReset(TResetReason reason)
170+
{
171+
if(__uvisor_mode == 0) {
172+
NVIC_SystemReset();
173+
}
174+
else {
175+
UVISOR_SVC(UVISOR_SVC_ID_DEBUG_REBOOT, "", reason);
176+
}
177+
}

core/debug/inc/debug.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ void debug_map_addr_to_periph(uint32_t address);
4747
void debug_register_driver(const TUvisorDebugDriver * const driver);
4848
uint32_t debug_get_version(void);
4949
void debug_halt_error(THaltError reason);
50-
void debug_reboot(void);
50+
void debug_reboot(TResetReason reason);
5151

5252
#define DEBUG_PRINT_HEAD(x) {\
5353
DPRINTF("\n***********************************************************\n");\

core/debug/src/debug.c

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -156,32 +156,29 @@ void debug_fault(THaltError reason, uint32_t lr, uint32_t sp)
156156
DEBUG_PRINT_END();
157157
}
158158

159-
static void __debug_reboot(void)
159+
static void debug_die(void)
160160
{
161-
UVISOR_SVC(UVISOR_SVC_ID_DEBUG_REBOOT, "");
161+
UVISOR_SVC(UVISOR_SVC_ID_HALT_USER_ERR, "", DEBUG_BOX_HALT);
162162
}
163163

164-
/* This function must be called as an SVCall handler.
165-
* All debug handlers that are required to reboot upon exit should use the
166-
* __debug_reboot function as return value, which triggers the SVCall. This note
167-
* applies to uVisor internally, as the actual debug box does not need to care
168-
* about this. */
169-
void debug_reboot(void)
164+
void debug_reboot(TResetReason reason)
170165
{
171-
/* FIXME: The halt will be replaced with a proper return code. An ACL will
172-
* be created to allow single boxes to reset the device. */
173166
if (!g_debug_box.initialized || g_active_box != g_debug_box.box_id) {
174167
HALT_ERROR(NOT_ALLOWED, "This function can only be called from the context of an initialized debug box.\n\r");
175168
}
176169

170+
/* Note: Currently we do not act differently based on the reset reason. */
171+
if (reason >= __TRESETREASON_MAX) {
172+
HALT_ERROR(NOT_ALLOWED, "Invalid reset reason: %d.\r\n", reason);
173+
}
174+
177175
/* Reboot.
178176
* If called from unprivileged code, NVIC_SystemReset causes a fault. */
179177
NVIC_SystemReset();
180178
}
181179

182180
/* FIXME: Currently it is not possible to return to a regular execution flow
183-
* after the execution of the debug box handler. It is possible to
184-
* reboot, though. */
181+
* after the execution of the debug box handler. */
185182
static void debug_deprivilege_and_return(void * debug_handler, void * return_handler,
186183
uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3)
187184
{
@@ -230,7 +227,7 @@ void debug_halt_error(THaltError reason)
230227
/* If the debug box does not exist (or it has not been initialized yet), or
231228
* the debug box was already called once, just loop forever. */
232229
if (!g_debug_box.initialized || debugged_once_before) {
233-
while(1);
230+
while (1);
234231
} else {
235232
/* Remember that debug_deprivilege_and_return() has been called once.
236233
* We'll reboot after the debug handler is run, so this will go back to
@@ -239,8 +236,8 @@ void debug_halt_error(THaltError reason)
239236

240237
/* The following arguments are passed to the destination function:
241238
* 1. reason
242-
* Upon return from the debug handler, the system will reboot. */
243-
debug_deprivilege_and_return(g_debug_box.driver->halt_error, __debug_reboot, reason, 0, 0, 0);
239+
* Upon return from the debug handler, the system will die. */
240+
debug_deprivilege_and_return(g_debug_box.driver->halt_error, debug_die, reason, 0, 0, 0);
244241
}
245242
}
246243

0 commit comments

Comments
 (0)