2019-12-10 19:12:55 +00:00
|
|
|
// supervisor call functions
|
|
|
|
|
|
|
|
#define SVC_ENABLE_IRQ 0
|
|
|
|
#define SVC_DISABLE_IRQ 1
|
|
|
|
#define SVC_SET_PRIORITY 2
|
2021-06-14 11:28:25 +00:00
|
|
|
#define SVC_SHUTDOWN 4
|
2022-04-11 11:27:48 +00:00
|
|
|
#define SVC_REBOOT_TO_BOOTLOADER 5
|
2021-06-14 11:28:25 +00:00
|
|
|
|
|
|
|
// from util.s
|
|
|
|
extern void shutdown_privileged(void);
|
2022-04-11 11:27:48 +00:00
|
|
|
extern void reboot_to_bootloader(void);
|
2019-12-10 19:12:55 +00:00
|
|
|
|
2020-01-23 18:18:59 +00:00
|
|
|
static inline uint32_t is_mode_unprivileged(void) {
|
|
|
|
uint32_t r0;
|
|
|
|
__asm__ volatile("mrs %0, control" : "=r"(r0));
|
|
|
|
return r0 & 1;
|
2019-12-10 19:12:55 +00:00
|
|
|
}
|
|
|
|
|
2022-08-09 17:16:54 +00:00
|
|
|
static inline uint32_t is_mode_handler(void) {
|
|
|
|
uint32_t r0;
|
|
|
|
__asm__ volatile("mrs %0, ipsr" : "=r"(r0));
|
|
|
|
return (r0 & 0x1FF) != 0;
|
|
|
|
}
|
|
|
|
|
2020-01-23 18:18:59 +00:00
|
|
|
static inline void svc_enableIRQ(uint32_t IRQn) {
|
2022-08-09 17:16:54 +00:00
|
|
|
if (is_mode_unprivileged() && !is_mode_handler()) {
|
2020-01-23 18:18:59 +00:00
|
|
|
register uint32_t r0 __asm__("r0") = IRQn;
|
|
|
|
__asm__ __volatile__("svc %0" ::"i"(SVC_ENABLE_IRQ), "r"(r0) : "memory");
|
|
|
|
} else {
|
|
|
|
HAL_NVIC_EnableIRQ(IRQn);
|
|
|
|
}
|
2019-12-10 19:12:55 +00:00
|
|
|
}
|
|
|
|
|
2020-01-23 18:18:59 +00:00
|
|
|
static inline void svc_disableIRQ(uint32_t IRQn) {
|
2022-08-09 17:16:54 +00:00
|
|
|
if (is_mode_unprivileged() && !is_mode_handler()) {
|
2020-01-23 18:18:59 +00:00
|
|
|
register uint32_t r0 __asm__("r0") = IRQn;
|
|
|
|
__asm__ __volatile__("svc %0" ::"i"(SVC_DISABLE_IRQ), "r"(r0) : "memory");
|
|
|
|
} else {
|
|
|
|
HAL_NVIC_DisableIRQ(IRQn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void svc_setpriority(uint32_t IRQn, uint32_t priority) {
|
2022-08-09 17:16:54 +00:00
|
|
|
if (is_mode_unprivileged() && !is_mode_handler()) {
|
2020-01-23 18:18:59 +00:00
|
|
|
register uint32_t r0 __asm__("r0") = IRQn;
|
|
|
|
register uint32_t r1 __asm__("r1") = priority;
|
|
|
|
__asm__ __volatile__("svc %0" ::"i"(SVC_SET_PRIORITY), "r"(r0), "r"(r1)
|
2020-01-24 08:59:57 +00:00
|
|
|
: "memory");
|
2020-01-23 18:18:59 +00:00
|
|
|
} else {
|
|
|
|
NVIC_SetPriority(IRQn, priority);
|
|
|
|
}
|
2019-12-10 19:12:55 +00:00
|
|
|
}
|
2021-06-14 11:28:25 +00:00
|
|
|
|
|
|
|
static inline void svc_shutdown(void) {
|
2022-08-09 17:16:54 +00:00
|
|
|
if (is_mode_unprivileged() && !is_mode_handler()) {
|
2021-06-14 11:28:25 +00:00
|
|
|
__asm__ __volatile__("svc %0" ::"i"(SVC_SHUTDOWN) : "memory");
|
|
|
|
} else {
|
|
|
|
shutdown_privileged();
|
|
|
|
}
|
|
|
|
}
|
2022-04-11 11:27:48 +00:00
|
|
|
static inline void svc_reboot_to_bootloader(void) {
|
2022-08-09 17:16:54 +00:00
|
|
|
if (is_mode_unprivileged() && !is_mode_handler()) {
|
2022-04-11 11:27:48 +00:00
|
|
|
__asm__ __volatile__("svc %0" ::"i"(SVC_REBOOT_TO_BOOTLOADER) : "memory");
|
|
|
|
} else {
|
|
|
|
reboot_to_bootloader();
|
|
|
|
}
|
|
|
|
}
|