#include <rt/arch/dcb.h>
#include <rt/arch/fp.h>
#include <rt/arch/mpu.h>
#include <rt/arch/nvic.h>
#include <rt/arch/scb.h>
#include <rt/arch/semihosting.h>
#include <rt/arch/syscall.h>
#include <rt/arch/systick.h>
#include <rt/log.h>
#include <rt/panic.h>
#include <rt/stack.h>
#include <rt/start.h>
#include <rt/tick.h>
#include <rt/trap.h>
static RT_STACK(stack, 512);
extern char __rx_region__[], __rx_region_size__[];
extern char __priv_rw_region__[], __priv_rw_region_size__[];
extern char __rw_region__[], __rw_region_size__[];
void start(void);
__attribute__((noreturn)) void rt_panic(const char *msg)
{
semihosting_write0(msg);
semihosting_write0("\n");
semihosting_exception(ADP_STOPPED_OS_SPECIFIC);
}
__attribute__((noreturn)) void rt_trap(void)
{
semihosting_exit(0);
}
__attribute__((noreturn)) static void nmi_handler(void)
{
semihosting_write0("nmi\n");
semihosting_exception(ADP_STOPPED_FIQ);
}
__attribute__((noreturn)) static void hardfault_handler(void)
{
semihosting_write0("hardfault\n");
semihosting_exception(ADP_STOPPED_INTERNAL_ERROR);
}
__attribute__((noreturn)) static void memmanagefault_handler(void)
{
semihosting_write0("memmanagefault\n");
semihosting_exception(ADP_STOPPED_ADDRESS_EXCEPTION);
}
__attribute__((noreturn)) static void busfault_handler(void)
{
semihosting_write0("busfault\n");
semihosting_exception(ADP_STOPPED_DATA_ABORT);
}
__attribute__((noreturn)) static void usagefault_handler(void)
{
semihosting_write0("usagefault\n");
semihosting_exception(ADP_STOPPED_UNDEFINED_INSTR);
}
__attribute__((noreturn)) static void securefault_handler(void)
{
semihosting_write0("securefault\n");
semihosting_exception(ADP_STOPPED_RUNTIME_ERROR_UNKNOWN);
}
__attribute__((noreturn)) static void debugmonitor_handler(void)
{
semihosting_write0("debugmonitor\n");
semihosting_exception(ADP_STOPPED_BREAKPOINT);
}
__attribute__((noreturn)) static void spurious_interrupt_handler(void)
{
semihosting_write0("spurious interrupt\n");
semihosting_exception(ADP_STOPPED_IRQ);
}
#define NUM_INTERRUPTS 96
__attribute__((aligned(512), section(".vector")))
const struct nvic_vector vector = {
.sp_init = &stack[sizeof stack],
.reset = start,
.nmi = nmi_handler,
.hardfault = hardfault_handler,
.memmanagefault = memmanagefault_handler,
.busfault = busfault_handler,
.usagefault = usagefault_handler,
.securefault = securefault_handler,
.svcall = rt_svcall_handler,
.debugmonitor = debugmonitor_handler,
.pendsv = rt_pendsv_handler,
.systick = rt_tick_advance,
.interrupt_handlers =
{
[0 ... NUM_INTERRUPTS - 1] = spurious_interrupt_handler,
},
};
void init(void);
void init(void)
{
SCB->vtor = &vector;
__asm__("dsb; isb" ::: "memory");
#if RT_ARM_FP
SCB->cpacr |= SCB_CPACR_ENABLE_FPU;
#endif
rt_mpu_attr_init();
rt_mpu_attr_set(0, RT_MPU_ATTR_WB_RWALLOC);
rt_mpu_attr_set(1, RT_MPU_ATTR_DEVICE_NGNRNE);
rt_mpu_region_set(0, (uintptr_t)__rx_region__, (size_t)__rx_region_size__,
RT_MPU_ATTR_RO | RT_MPU_ATTR_INDEX(0) |
RT_MPU_ATTR_ENABLE);
rt_mpu_region_set(1, (uintptr_t)__priv_rw_region__,
(size_t)__priv_rw_region_size__,
RT_MPU_ATTR_RW_PRIV | RT_MPU_ATTR_XN | RT_MPU_ATTR_PXN |
RT_MPU_ATTR_INDEX(0) | RT_MPU_ATTR_ENABLE);
rt_mpu_region_set(2, 0xE0000000UL, 0x20000000UL,
RT_MPU_ATTR_RW_PRIV | RT_MPU_ATTR_XN | RT_MPU_ATTR_PXN |
RT_MPU_ATTR_INDEX(1) | RT_MPU_ATTR_ENABLE);
rt_mpu_region_set(3, (uintptr_t)__rw_region__, (size_t)__rw_region_size__,
RT_MPU_ATTR_RW | RT_MPU_ATTR_XN | RT_MPU_ATTR_PXN |
RT_MPU_ATTR_INDEX(0) | RT_MPU_ATTR_ENABLE);
#if !RT_MPU_TASK_REGIONS_ENABLE
extern char __task_stack_region__[], __task_stack_region_size__[];
rt_mpu_region_set(4, (uintptr_t)__task_stack_region__,
(size_t)__task_stack_region_size__,
RT_MPU_ATTR_RW | RT_MPU_ATTR_XN | RT_MPU_ATTR_PXN |
RT_MPU_ATTR_INDEX(0) | RT_MPU_ATTR_ENABLE);
#endif
rt_mpu_privileged_default_enable();
rt_mpu_enable();
SCB->shpr1.securefault = NVIC_PRIORITY_LOWEST;
SCB->shpr2.svcall = NVIC_PRIORITY_LOWEST;
SCB->shpr3.pendsv = NVIC_PRIORITY_LOWEST;
SCB->shpr3.systick = NVIC_PRIORITY_LOWEST - NVIC_PRIORITY_STEP;
SCB->shcsr |= (SCB_SHCSR_SECUREFAULTENA | SCB_SHCSR_USAGEFAULTENA |
SCB_SHCSR_BUSFAULTENA | SCB_SHCSR_MEMFAULTENA);
DCB->demcr |= DCB_DEMCR_TRCENA | DCB_DEMCR_MON_EN;
SYSTICK->rvr = 32000U - 1U;
SYSTICK->cvr = 0;
SYSTICK->csr =
SYSTICK_CSR_CLKSOURCE | SYSTICK_CSR_TICKINT | SYSTICK_CSR_ENABLE;
}
#if RT_LOG_ENABLE
void rt_logf(const char *format, ...)
{
(void)format;
}
void rt_log_flush(void)
{
}
#endif