parent
9627b30439
commit
21dbf721f5
@ -1,126 +0,0 @@
|
||||
#include STM32_HAL_H
|
||||
|
||||
#include <model.h>
|
||||
|
||||
#include "../mpu.h"
|
||||
#include "common.h"
|
||||
#include "display.h"
|
||||
#include "irq.h"
|
||||
#include "supervise.h"
|
||||
|
||||
#ifdef ARM_USER_MODE
|
||||
|
||||
void svc_init(void) {
|
||||
NVIC_SetPriority(SVCall_IRQn, IRQ_PRI_HIGHEST);
|
||||
|
||||
// We need to ensure that SysTick has the expected priority.
|
||||
// The SysTick priority is configured in the boardloader,
|
||||
// and some early versions didn't set this properly.
|
||||
NVIC_SetPriority(SysTick_IRQn, IRQ_PRI_HIGHEST);
|
||||
}
|
||||
|
||||
#ifdef STM32U5
|
||||
extern uint32_t g_boot_command;
|
||||
__attribute__((noreturn)) static void _reboot_to_bootloader(
|
||||
boot_command_t boot_command) {
|
||||
g_boot_command = boot_command;
|
||||
disable_irq();
|
||||
delete_secrets();
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#else
|
||||
__attribute__((noreturn)) static void _reboot_to_bootloader(
|
||||
boot_command_t boot_command) {
|
||||
display_deinit(DISPLAY_RESET_CONTENT);
|
||||
#ifdef ENSURE_COMPATIBLE_SETTINGS
|
||||
ensure_compatible_settings();
|
||||
#endif
|
||||
mpu_config_bootloader();
|
||||
jump_to_with_flag(IMAGE_CODE_ALIGN(BOOTLOADER_START + IMAGE_HEADER_SIZE),
|
||||
boot_command);
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
void svc_reboot_to_bootloader(void) {
|
||||
boot_command_t boot_command = bootargs_get_command();
|
||||
if (is_mode_unprivileged() && !is_mode_handler()) {
|
||||
register uint32_t r0 __asm__("r0") = boot_command;
|
||||
__asm__ __volatile__("svc %0" ::"i"(SVC_REBOOT_TO_BOOTLOADER), "r"(r0)
|
||||
: "memory");
|
||||
} else {
|
||||
_reboot_to_bootloader(boot_command);
|
||||
}
|
||||
}
|
||||
|
||||
void svc_reboot(void) {
|
||||
if (is_mode_unprivileged() && !is_mode_handler()) {
|
||||
__asm__ __volatile__("svc %0" ::"i"(SVC_REBOOT) : "memory");
|
||||
} else {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
|
||||
void SVC_C_Handler(uint32_t *stack) {
|
||||
uint8_t svc_number = ((uint8_t *)stack[6])[-2];
|
||||
switch (svc_number) {
|
||||
case SVC_ENABLE_IRQ:
|
||||
NVIC_EnableIRQ(stack[0]);
|
||||
break;
|
||||
case SVC_DISABLE_IRQ:
|
||||
NVIC_DisableIRQ(stack[0]);
|
||||
break;
|
||||
case SVC_SET_PRIORITY:
|
||||
NVIC_SetPriority(stack[0], stack[1]);
|
||||
break;
|
||||
#ifdef SYSTEM_VIEW
|
||||
case SVC_GET_DWT_CYCCNT:
|
||||
cyccnt_cycles = *DWT_CYCCNT_ADDR;
|
||||
break;
|
||||
#endif
|
||||
case SVC_SHUTDOWN:
|
||||
shutdown_privileged();
|
||||
for (;;)
|
||||
;
|
||||
break;
|
||||
case SVC_REBOOT_TO_BOOTLOADER:
|
||||
|
||||
__asm__ volatile("msr control, %0" ::"r"(0x0));
|
||||
__asm__ volatile("isb");
|
||||
|
||||
// The input stack[0] argument comes from R0 saved when SVC was called
|
||||
// from svc_reboot_to_bootloader. The __asm__ directive expects address as
|
||||
// argument, hence the & in front of it, otherwise it would try
|
||||
// to dereference the value and fault
|
||||
__asm__ volatile(
|
||||
"mov r0, %[boot_command]" ::[boot_command] "r"(&stack[0]));
|
||||
|
||||
// See stack layout in
|
||||
// https://developer.arm.com/documentation/ka004005/latest We are changing
|
||||
// return address in PC to land into reboot to avoid any bug with ROP and
|
||||
// raising privileges.
|
||||
stack[6] = (uintptr_t)_reboot_to_bootloader;
|
||||
return;
|
||||
case SVC_REBOOT:
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
default:
|
||||
stack[0] = 0xffffffff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((naked)) void SVC_Handler(void) {
|
||||
__asm volatile(
|
||||
" tst lr, #4 \n" // Test Bit 3 to see which stack pointer we should
|
||||
// use
|
||||
" ite eq \n" // Tell the assembler that the nest 2 instructions
|
||||
// are if-then-else
|
||||
" mrseq r0, msp \n" // Make R0 point to main stack pointer
|
||||
" mrsne r0, psp \n" // Make R0 point to process stack pointer
|
||||
" b SVC_C_Handler \n" // Off to C land
|
||||
);
|
||||
}
|
||||
|
||||
#endif // ARM_USER_MODE
|
@ -1,74 +0,0 @@
|
||||
// supervisor call functions
|
||||
|
||||
#define SVC_ENABLE_IRQ 0
|
||||
#define SVC_DISABLE_IRQ 1
|
||||
#define SVC_SET_PRIORITY 2
|
||||
#define SVC_SHUTDOWN 4
|
||||
#define SVC_REBOOT_TO_BOOTLOADER 5
|
||||
#define SVC_REBOOT 6
|
||||
|
||||
#include <string.h>
|
||||
#include "boot_args.h"
|
||||
#include "common.h"
|
||||
#include "image.h"
|
||||
|
||||
// from util.s
|
||||
extern void shutdown_privileged(void);
|
||||
|
||||
// Initializes the supervise module
|
||||
//
|
||||
// Must be called before invoking the first `svc_xxx` call
|
||||
void svc_init(void);
|
||||
|
||||
static inline uint32_t is_mode_unprivileged(void) {
|
||||
uint32_t r0;
|
||||
__asm__ volatile("mrs %0, control" : "=r"(r0));
|
||||
return r0 & 1;
|
||||
}
|
||||
|
||||
static inline uint32_t is_mode_handler(void) {
|
||||
uint32_t r0;
|
||||
__asm__ volatile("mrs %0, ipsr" : "=r"(r0));
|
||||
return (r0 & 0x1FF) != 0;
|
||||
}
|
||||
|
||||
static inline void svc_enableIRQ(uint32_t IRQn) {
|
||||
if (is_mode_unprivileged() && !is_mode_handler()) {
|
||||
register uint32_t r0 __asm__("r0") = IRQn;
|
||||
__asm__ __volatile__("svc %0" ::"i"(SVC_ENABLE_IRQ), "r"(r0) : "memory");
|
||||
} else {
|
||||
NVIC_EnableIRQ(IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void svc_disableIRQ(uint32_t IRQn) {
|
||||
if (is_mode_unprivileged() && !is_mode_handler()) {
|
||||
register uint32_t r0 __asm__("r0") = IRQn;
|
||||
__asm__ __volatile__("svc %0" ::"i"(SVC_DISABLE_IRQ), "r"(r0) : "memory");
|
||||
} else {
|
||||
NVIC_DisableIRQ(IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void svc_setpriority(uint32_t IRQn, uint32_t priority) {
|
||||
if (is_mode_unprivileged() && !is_mode_handler()) {
|
||||
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)
|
||||
: "memory");
|
||||
} else {
|
||||
NVIC_SetPriority(IRQn, priority);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void svc_shutdown(void) {
|
||||
if (is_mode_unprivileged() && !is_mode_handler()) {
|
||||
__asm__ __volatile__("svc %0" ::"i"(SVC_SHUTDOWN) : "memory");
|
||||
} else {
|
||||
shutdown_privileged();
|
||||
}
|
||||
}
|
||||
|
||||
void svc_reboot_to_bootloader(void);
|
||||
|
||||
void svc_reboot(void);
|
@ -1 +0,0 @@
|
||||
../stm32f4/supervise.c
|
@ -1 +0,0 @@
|
||||
../stm32f4/supervise.h
|
Loading…
Reference in new issue