#include <rt/arch/dcb.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 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);
}
__attribute__((aligned(256), 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,
.svcall = rt_svcall_handler,
.debugmonitor = debugmonitor_handler,
.pendsv = rt_pendsv_handler,
.systick = rt_tick_advance,
.interrupt_handlers =
{
[0 ... 239] = spurious_interrupt_handler,
},
};
void init(void);
void init(void)
{
SCB->cpacr |= SCB_CPACR_ENABLE_FPU;
rt_mpu_region_set(0, (uintptr_t)__rx_region__, (size_t)__rx_region_size__,
RT_MPU_ATTR_RO | RT_MPU_ATTR_CACHED_WB_RWALLOC |
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_CACHED_WB_RWALLOC | RT_MPU_ATTR_ENABLE);
rt_mpu_region_set(2, 0xE0000000UL, 0x20000000UL,
RT_MPU_ATTR_RW_PRIV | RT_MPU_ATTR_XN |
RT_MPU_ATTR_STRONGLY_ORDERED | 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_CACHED_WB_RWALLOC | RT_MPU_ATTR_ENABLE);
rt_mpu_enable();
SCB->shpr2.svcall = NVIC_PRIORITY_LOWEST;
SCB->shpr3.pendsv = NVIC_PRIORITY_LOWEST;
SCB->shpr3.systick = SCB->shpr2.svcall - 1;
#if !RT_ARM_V6M
SCB->shcsr |= (SCB_SHCSR_USAGEFAULTENA | SCB_SHCSR_BUSFAULTENA |
SCB_SHCSR_MEMFAULTENA);
DCB->demcr |= DCB_DEMCR_TRCENA | DCB_DEMCR_MON_EN;
#endif
SCB->vtor = &vector;
SYSTICK->rvr = 25000U - 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