diff --git a/hal/arm/Makefile b/hal/arm/Makefile new file mode 100644 index 000000000..c0be07d50 --- /dev/null +++ b/hal/arm/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for HAL ARM common functions +# +# Copyright 2023 Phoenix Systems +# + +# TODO handle other common ARM stuff (e.g GIC) and +# select relevant components here + +OBJS += $(addprefix $(PREFIX_O)hal/arm/, nvic.o scb.o) diff --git a/hal/armv7m/armv7m.h b/hal/arm/barriers.h similarity index 84% rename from hal/armv7m/armv7m.h rename to hal/arm/barriers.h index bb70757dd..d52f01612 100644 --- a/hal/armv7m/armv7m.h +++ b/hal/arm/barriers.h @@ -3,7 +3,7 @@ * * Operating system kernel * - * ARMv7 Cortex-M related routines + * ARM barriers * * Copyright 2021 Phoenix Systems * Author: Hubert Buczynski @@ -13,8 +13,8 @@ * %LICENSE% */ -#ifndef _HAL_ARMV7M_H_ -#define _HAL_ARMV7M_H_ +#ifndef HAL_ARM_BARRIERS_H_ +#define HAL_ARM_BARRIERS_H_ static inline void hal_cpuDataMemoryBarrier(void) @@ -34,4 +34,5 @@ static inline void hal_cpuInstrBarrier(void) __asm__ volatile ("isb"); } + #endif diff --git a/hal/arm/nvic.c b/hal/arm/nvic.c new file mode 100644 index 000000000..3efd060d0 --- /dev/null +++ b/hal/arm/nvic.c @@ -0,0 +1,77 @@ +/* + * Phoenix-RTOS + * + * Operating system kernel + * + * Nested Vector Interrupt Controller + * + * Copyright 2017, 2020, 2022, 2024 Phoenix Systems + * Author: Pawel Pisarczyk, Hubert Buczynski, Damian Loewnau, Aleksander Kaminski + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + + +#include +#include "nvic.h" + + +struct nvic_s { + volatile u32 iser; + u32 _res0[31]; + volatile u32 icer; + u32 _res1[31]; + volatile u32 ispr; + u32 _res2[31]; + volatile u32 icpr; + u32 _res3[31]; + volatile u32 iabr; + u32 _res4[63]; + volatile u32 ip; +}; + + +static struct { + struct nvic_s *nvic; +} nvic_common; + + +void _hal_nvicSetIRQ(s8 irqn, u8 state) +{ + volatile u32 *ptr = (state != 0) ? &nvic_common.nvic->iser : &nvic_common.nvic->icer; + + *(ptr + ((u8)irqn >> 5)) = 1u << (irqn & 0x1f); + + hal_cpuDataSyncBarrier(); + hal_cpuInstrBarrier(); +} + + +void _hal_nvicSetPriority(s8 irqn, u32 priority) +{ + volatile u8 *ptr = (volatile u8 *)&nvic_common.nvic->ip; + + *(ptr + irqn) = (priority << 4) & 0xff; + + hal_cpuDataSyncBarrier(); + hal_cpuInstrBarrier(); +} + + +void _hal_nvicSetPending(s8 irqn) +{ + volatile u32 *ptr = &nvic_common.nvic->ispr; + + *(ptr + ((u8)irqn >> 5)) = 1u << (irqn & 0x1f); + + hal_cpuDataSyncBarrier(); + hal_cpuInstrBarrier(); +} + + +void _hal_nvicInit(void) +{ + nvic_common.nvic = (void *)0xe000e100; +} diff --git a/hal/arm/nvic.h b/hal/arm/nvic.h new file mode 100644 index 000000000..abb0c671b --- /dev/null +++ b/hal/arm/nvic.h @@ -0,0 +1,36 @@ +/* + * Phoenix-RTOS + * + * Operating system kernel + * + * Nested Vector Interrupt Controller + * + * Copyright 2017, 2020, 2022, 2024 Phoenix Systems + * Author: Pawel Pisarczyk, Hubert Buczynski, Damian Loewnau, Aleksander Kaminski + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + + +#ifndef HAL_ARMV_NVIC_H_ +#define HAL_ARMV_NVIC_H_ + + +#include "hal/types.h" + + +void _hal_nvicSetIRQ(s8 irqn, u8 state); + + +void _hal_nvicSetPriority(s8 irqn, u32 priority); + + +void _hal_nvicSetPending(s8 irqn); + + +void _hal_nvicInit(void); + + +#endif diff --git a/hal/arm/scb.c b/hal/arm/scb.c new file mode 100644 index 000000000..1f73dd285 --- /dev/null +++ b/hal/arm/scb.c @@ -0,0 +1,303 @@ +/* + * Phoenix-RTOS + * + * Operating system kernel + * + * System Control Block + * + * Copyright 2017, 2020, 2022, 2024 Phoenix Systems + * Author: Pawel Pisarczyk, Hubert Buczynski, Gerard Swiderski, Aleksander Kaminski + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + + +#include +#include "scb.h" + + +struct scb_s { + u32 _res0[2]; + volatile u32 actlr; + u32 _res1; + volatile u32 csr; + volatile u32 rvr; + volatile u32 cvr; + volatile u32 calib; + u32 _res2[824]; + volatile u32 cpuid; + volatile u32 icsr; + volatile u32 vtor; + volatile u32 aircr; + volatile u32 scr; + volatile u32 ccr; + volatile u32 shpr1; + volatile u32 shpr2; + volatile u32 shpr3; + volatile u32 shcsr; + volatile u32 cfsr; + volatile u32 hfsr; + u32 _res3; + volatile u32 mmfar; + volatile u32 bfar; + volatile u32 afsr; + u32 _res4[14]; + volatile u32 clidr; + volatile u32 ctr; + volatile u32 ccsidr; + volatile u32 csselr; + volatile u32 cpacr; + u32 _res5[106]; + volatile u32 fpccr; + volatile u32 fpcar; + volatile u32 fpdscr; + u32 _res6[4]; + volatile u32 iciallu; + u32 _res7; + volatile u32 icimvau; + volatile u32 scimvac; + volatile u32 dcisw; + volatile u32 dccmvau; + volatile u32 dccvac; + volatile u32 dccsw; + volatile u32 dccimvac; + volatile u32 dccisw; + u32 _res8[6]; + volatile u32 itcmcr; + volatile u32 dtcmcr; + volatile u32 ahbpcr; + volatile u32 cacr; + volatile u32 ahbscr; + u32 _res9; + volatile u32 abfsr; +}; + + +static struct { + struct scb_s *scb; +} scb_common; + + +void _hal_scbSetPriorityGrouping(u32 group) +{ + u32 t; + + /* Get register value and clear bits to set */ + t = scb_common.scb->aircr & ~0xffff0700; + + /* Set AIRCR.PRIGROUP to 3: 16 priority groups and 16 subgroups + The value is same as for armv7m4-stm32l4x6 target + Setting various priorities is not supported on Phoenix-RTOS, so it's just default value */ + scb_common.scb->aircr = t | 0x5fa0000 | ((group & 7) << 8); +} + + +void _hal_scbSetPriority(s8 excpn, u32 priority) +{ + volatile u8 *ptr = (u8 *)&scb_common.scb->shpr1 + excpn - 4; + + /* We set only group priority field */ + *ptr = (priority << 4) & 0xff; +} + + +void _hal_scbSystemReset(void) +{ + scb_common.scb->aircr = ((0x5fau << 16) | (scb_common.scb->aircr & (0x700u)) | (1u << 2)); + + hal_cpuDataSyncBarrier(); + + for (;;) { + hal_cpuHalt(); + } +} + + +unsigned int _hal_scbCpuid(void) +{ + return scb_common.scb->cpuid; +} + + +void _hal_scbSetFPU(int state) +{ + if (state != 0) { + scb_common.scb->cpacr |= 0xf << 20; + } + else { + scb_common.scb->cpacr = 0; + scb_common.scb->fpccr = 0; + } + hal_cpuDataSyncBarrier(); +} + + +static int _hal_scbCacheIsSupported(void) +{ + u32 partno = ((_hal_scbCpuid() >> 4) & 0xfff); + + /* Only supported on Cortex-M7 for now */ + if (partno == 0xc27) { + return 1; + } + + return 0; +} + + +void _hal_scbEnableDCache(void) +{ + u32 ccsidr, sets, ways; + + if (_hal_scbCacheIsSupported() == 0) { + return; + } + + if ((scb_common.scb->ccr & (1 << 16)) == 0) { + scb_common.scb->csselr = 0; + hal_cpuDataSyncBarrier(); + + ccsidr = scb_common.scb->ccsidr; + + /* Invalidate D$ */ + sets = (ccsidr >> 13) & 0x7fff; + do { + ways = (ccsidr >> 3) & 0x3ff; + do { + scb_common.scb->dcisw = ((sets & 0x1ff) << 5) | ((ways & 0x3) << 30); + } while (ways-- != 0); + } while (sets-- != 0); + hal_cpuDataSyncBarrier(); + + scb_common.scb->ccr |= 1 << 16; + + hal_cpuDataSyncBarrier(); + hal_cpuInstrBarrier(); + } +} + + +void _hal_scbDisableDCache(void) +{ + register u32 ccsidr, sets, ways; + + if (_hal_scbCacheIsSupported() == 0) { + return; + } + + scb_common.scb->csselr = 0; + hal_cpuDataSyncBarrier(); + + scb_common.scb->ccr &= ~(1 << 16); + hal_cpuDataSyncBarrier(); + + ccsidr = scb_common.scb->ccsidr; + + sets = (ccsidr >> 13) & 0x7fff; + do { + ways = (ccsidr >> 3) & 0x3ff; + do { + scb_common.scb->dcisw = ((sets & 0x1ff) << 5) | ((ways & 0x3) << 30); + } while (ways-- != 0); + } while (sets-- != 0); + + hal_cpuDataSyncBarrier(); + hal_cpuInstrBarrier(); +} + + +void _hal_scbCleanInvalDCacheAddr(void *addr, u32 sz) +{ + u32 daddr; + int dsize; + + if (_hal_scbCacheIsSupported() == 0) { + return; + } + + if (sz == 0u) { + return; + } + + daddr = (((u32)addr) & ~0x1fu); + dsize = sz + ((u32)addr & 0x1fu); + + hal_cpuDataSyncBarrier(); + + do { + scb_common.scb->dccimvac = daddr; + daddr += 0x20u; + dsize -= 0x20; + } while (dsize > 0); + + hal_cpuDataSyncBarrier(); + hal_cpuInstrBarrier(); +} + + +void _hal_scbEnableICache(void) +{ + if (_hal_scbCacheIsSupported() == 0) { + return; + } + + if ((scb_common.scb->ccr & (1 << 17)) == 0) { + hal_cpuDataSyncBarrier(); + hal_cpuInstrBarrier(); + scb_common.scb->iciallu = 0; /* Invalidate I$ */ + hal_cpuDataSyncBarrier(); + hal_cpuInstrBarrier(); + scb_common.scb->ccr |= 1 << 17; + hal_cpuDataSyncBarrier(); + hal_cpuInstrBarrier(); + } +} + + +void _hal_scbDisableICache(void) +{ + if (_hal_scbCacheIsSupported() == 0) { + return; + } + + hal_cpuDataSyncBarrier(); + hal_cpuInstrBarrier(); + scb_common.scb->ccr &= ~(1 << 17); + scb_common.scb->iciallu = 0; + hal_cpuDataSyncBarrier(); + hal_cpuInstrBarrier(); +} + + +void _hal_scbSetDeepSleep(int state) +{ + if (state != 0) { + scb_common.scb->scr |= 1 << 2; + scb_common.scb->csr &= ~1; + } + else { + scb_common.scb->scr &= ~(1 << 2); + scb_common.scb->csr |= 1; + } +} + + +void _hal_scbSystickInit(u32 load) +{ + scb_common.scb->rvr = load; + scb_common.scb->cvr = 0; + + /* Enable systick */ + scb_common.scb->csr |= 0x7; +} + + +void _hal_scbInit(void) +{ + scb_common.scb = (void *)0xe000e000; + + /* Enable UsageFault, BusFault and MemManage exceptions */ + scb_common.scb->shcsr |= (1u << 16) | (1u << 17) | (1u << 18); +} diff --git a/hal/arm/scb.h b/hal/arm/scb.h new file mode 100644 index 000000000..b0e6e74a0 --- /dev/null +++ b/hal/arm/scb.h @@ -0,0 +1,63 @@ +/* + * Phoenix-RTOS + * + * Operating system kernel + * + * System Control Block + * + * Copyright 2017, 2020, 2022, 2024 Phoenix Systems + * Author: Pawel Pisarczyk, Hubert Buczynski, Damian Loewnau, Aleksander Kaminski + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ + + +#ifndef HAL_ARMV_SCB_H_ +#define HAL_ARMV_SCB_H_ + + +#include "hal/types.h" + + +void _hal_scbSetPriorityGrouping(u32 group); + + +void _hal_scbSetPriority(s8 excpn, u32 priority); + + +void _hal_scbSystemReset(void); + + +unsigned int _hal_scbCpuid(void); + + +void _hal_scbSetFPU(int state); + + +void _hal_scbEnableDCache(void); + + +void _hal_scbDisableDCache(void); + + +void _hal_scbCleanInvalDCacheAddr(void *addr, u32 sz); + + +void _hal_scbEnableICache(void); + + +void _hal_scbDisableICache(void); + + +void _hal_scbSetDeepSleep(int state); + + +void _hal_scbSystickInit(u32 load); + + +void _hal_scbInit(void); + + +#endif diff --git a/hal/armv7m/Makefile b/hal/armv7m/Makefile index a3e134968..4b54a514c 100644 --- a/hal/armv7m/Makefile +++ b/hal/armv7m/Makefile @@ -13,4 +13,7 @@ else ifneq (, $(findstring imxrt, $(TARGET_SUBFAMILY))) CFLAGS += -Ihal/armv7m/imxrt -Ihal/armv7m endif +include hal/arm/Makefile +CFLAGS += -Ihal/arm + OBJS += $(addprefix $(PREFIX_O)hal/armv7m/, string.o spinlock.o cpu.o hal.o pmap.o exceptions.o _memcpy.o _memset.o) diff --git a/hal/armv7m/arch/cpu.h b/hal/armv7m/arch/cpu.h index 0f4e917b9..1f48ee795 100644 --- a/hal/armv7m/arch/cpu.h +++ b/hal/armv7m/arch/cpu.h @@ -53,6 +53,8 @@ #ifndef __ASSEMBLY__ +#include "hal/arm/scb.h" +#include "hal/arm/barriers.h" #define SYSTICK_INTERVAL 1000 diff --git a/hal/armv7m/arch/interrupts.h b/hal/armv7m/arch/interrupts.h index 33bae5526..303d27541 100644 --- a/hal/armv7m/arch/interrupts.h +++ b/hal/armv7m/arch/interrupts.h @@ -18,6 +18,7 @@ #define _HAL_ARMV7M_INTERRUPTS_H_ #include "cpu.h" +#include "hal/arm/nvic.h" #define SVC_IRQ 11 #define PENDSV_IRQ 14 diff --git a/hal/armv7m/cpu.c b/hal/armv7m/cpu.c index aa5617d4a..d8eca4d46 100644 --- a/hal/armv7m/cpu.c +++ b/hal/armv7m/cpu.c @@ -57,11 +57,7 @@ void hal_cpuLowPower(time_t us, spinlock_t *spinlock, spinlock_ctx_t *sc) void hal_cpuGetCycles(cycles_t *cb) { -#ifdef CPU_STM32 - *cb = _stm32_systickGet(); -#elif defined(CPU_IMXRT) *cb = (cycles_t)hal_timerGetUs(); -#endif } @@ -199,16 +195,7 @@ void hal_cpuSigreturn(void *kstack, void *ustack, cpu_context_t **ctx) char *hal_cpuInfo(char *info) { int i; - unsigned int cpuinfo; - -#ifdef CPU_STM32 - cpuinfo = _stm32_cpuid(); -#elif defined(CPU_IMXRT) - cpuinfo = _imxrt_cpuid(); -#else - hal_strcpy(info, "unknown"); - return info; -#endif + unsigned int cpuinfo = _hal_scbCpuid(); hal_strcpy(info, HAL_NAME_PLATFORM); i = sizeof(HAL_NAME_PLATFORM) - 1; @@ -289,11 +276,7 @@ void hal_wdgReload(void) void hal_cpuReboot(void) { -#ifdef CPU_STM32 - _stm32_nvicSystemReset(); -#elif defined(CPU_IMXRT) - _imxrt_nvicSystemReset(); -#endif + _hal_scbSystemReset(); } @@ -302,13 +285,7 @@ void hal_cpuReboot(void) void hal_cleanDCache(ptr_t start, size_t len) { -#ifdef CPU_IMXRT - _imxrt_cleanInvalDCacheAddr((void *)start, len); -#else - /* TODO */ - (void)start; - (void)len; -#endif + _hal_scbCleanInvalDCacheAddr((void *)start, len); } diff --git a/hal/armv7m/hal.c b/hal/armv7m/hal.c index 97e0df454..37787e242 100644 --- a/hal/armv7m/hal.c +++ b/hal/armv7m/hal.c @@ -56,6 +56,8 @@ void hal_lockScheduler(void) void _hal_init(void) { + hal_common.started = 0; + _hal_spinlockInit(); _hal_exceptionsInit(); _hal_interruptsInit(); @@ -63,7 +65,5 @@ void _hal_init(void) _hal_consoleInit(); _hal_timerInit(SYSTICK_INTERVAL); - hal_common.started = 0; - return; } diff --git a/hal/armv7m/imxrt/10xx/console.c b/hal/armv7m/imxrt/10xx/console.c index c3662daba..266eb1291 100644 --- a/hal/armv7m/imxrt/10xx/console.c +++ b/hal/armv7m/imxrt/10xx/console.c @@ -13,10 +13,10 @@ * %LICENSE% */ -#include "hal/armv7m/armv7m.h" #include "hal/console.h" #include "include/arch/armv7m/imxrt/10xx/imxrt10xx.h" #include "imxrt10xx.h" +#include #include diff --git a/hal/armv7m/imxrt/10xx/imxrt10xx.c b/hal/armv7m/imxrt/10xx/imxrt10xx.c index fce39e959..d5d22eb15 100644 --- a/hal/armv7m/imxrt/10xx/imxrt10xx.c +++ b/hal/armv7m/imxrt/10xx/imxrt10xx.c @@ -13,7 +13,6 @@ * %LICENSE% */ -#include "hal/armv7m/armv7m.h" #include "hal/cpu.h" #include "hal/spinlock.h" #include "hal/armv7m/imxrt/halsyspage.h" @@ -21,6 +20,9 @@ #include "include/errno.h" #include "include/arch/armv7m/imxrt/10xx/imxrt10xx.h" +#include "hal/arm/nvic.h" +#include "hal/arm/scb.h" + #include "imxrt10xx.h" #include "config.h" @@ -51,9 +53,7 @@ struct { volatile u32 *iomuxc; volatile u32 *iomuxgpr; volatile u32 *iomuxsnvs; - volatile u32 *nvic; volatile u32 *stk; - volatile u32 *scb; volatile u16 *wdog1; volatile u16 *wdog2; volatile u32 *rtwdog; @@ -116,19 +116,6 @@ enum { src_scr = 0, src_sbmr1, src_srsr, src_sbmr2 = 7, src_gpr1, src_gpr2, src_ src_gpr5, src_gpr6, src_gpr7, src_gpr8, src_gpr9, src_gpr10 }; -enum { scb_cpuid = 0, scb_icsr, scb_vtor, scb_aircr, scb_scr, scb_ccr, scb_shp0, scb_shp1, - scb_shp2, scb_shcsr, scb_cfsr, scb_hfsr, scb_dfsr, scb_mmfar, scb_bfar, scb_afsr, scb_pfr0, - scb_pfr1, scb_dfr, scb_afr, scb_mmfr0, scb_mmfr1, scb_mmfr2, scb_mmf3, scb_isar0, scb_isar1, - scb_isar2, scb_isar3, scb_isar4, /* reserved */ scb_clidr = 30, scb_ctr, scb_ccsidr, scb_csselr, - scb_cpacr, /* 93 reserved */ scb_stir = 128, /* 15 reserved */ scb_mvfr0 = 144, scb_mvfr1, - scb_mvfr2, /* reserved */ scb_iciallu = 148, /* reserved */ scb_icimvau = 150, scb_scimvac, - scb_dcisw, scb_dccmvau, scb_dccmvac, scb_dccsw, scb_dccimvac, scb_dccisw, /* 6 reserved */ - scb_itcmcr = 164, scb_dtcmcr, scb_ahbpcr, scb_cacr, scb_ahbscr, /* reserved */ scb_abfsr = 170 }; - -enum { nvic_iser = 0, nvic_icer = 32, nvic_ispr = 64, nvic_icpr = 96, nvic_iabr = 128, - nvic_ip = 192, nvic_stir = 896 }; - - enum { wdog_wcr = 0, wdog_wsr, wdog_wrsr, wdog_wicr, wdog_wmcr }; @@ -560,7 +547,7 @@ int hal_platformctl(void *ptr) case pctl_reboot: if (data->action == pctl_set) { if (data->reboot.magic == PCTL_REBOOT_MAGIC) { - _imxrt_nvicSystemReset(); + _hal_scbSystemReset(); } } else if (data->action == pctl_get) { @@ -572,12 +559,12 @@ int hal_platformctl(void *ptr) case pctl_devcache: if (data->action == pctl_set) { if (data->devcache.state == 0) { - _imxrt_disableDCache(); - _imxrt_disableICache(); + _hal_scbDisableDCache(); + _hal_scbDisableICache(); } else { - _imxrt_enableDCache(); - _imxrt_enableICache(); + _hal_scbEnableDCache(); + _hal_scbEnableICache(); } ret = EOK; @@ -586,7 +573,7 @@ int hal_platformctl(void *ptr) case pctl_cleanInvalDCache: if (data->action == pctl_set) { - _imxrt_cleanInvalDCacheAddr(data->cleanInvalDCache.addr, data->cleanInvalDCache.sz); + _hal_scbCleanInvalDCacheAddr(data->cleanInvalDCache.addr, data->cleanInvalDCache.sz); ret = EOK; } break; @@ -1793,113 +1780,6 @@ void _imxrt_ccmSetMode(int mode) } -/* SCB */ - - -void _imxrt_scbSetPriorityGrouping(u32 group) -{ - u32 t; - - /* Get register value and clear bits to set */ - t = *(imxrt_common.scb + scb_aircr) & ~0xffff0700; - - /* Store new value */ - *(imxrt_common.scb + scb_aircr) = t | 0x5fa0000 | ((group & 7) << 8); -} - - -u32 _imxrt_scbGetPriorityGrouping(void) -{ - return (*(imxrt_common.scb + scb_aircr) & 0x700) >> 8; -} - - -void _imxrt_scbSetPriority(s8 excpn, u32 priority) -{ - volatile u8 *ptr; - - ptr = &((u8*)(imxrt_common.scb + scb_shp0))[excpn - 4]; - - *ptr = (priority << 4) & 0x0ff; -} - - -u32 _imxrt_scbGetPriority(s8 excpn) -{ - volatile u8 *ptr; - - ptr = &((u8*)(imxrt_common.scb + scb_shp0))[excpn - 4]; - - return *ptr >> 4; -} - - -/* NVIC (Nested Vectored Interrupt Controller */ - - -void _imxrt_nvicSetIRQ(s8 irqn, u8 state) -{ - volatile u32 *ptr = imxrt_common.nvic + ((u8)irqn >> 5) + (state ? nvic_iser : nvic_icer); - *ptr = 1 << (irqn & 0x1F); - - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); -} - - -u32 _imxrt_nvicGetPendingIRQ(s8 irqn) -{ - volatile u32 *ptr = imxrt_common.nvic + ((u8)irqn >> 5) + nvic_ispr; - return !!(*ptr & (1 << (irqn & 0x1F))); -} - - -void _imxrt_nvicSetPendingIRQ(s8 irqn, u8 state) -{ - volatile u32 *ptr = imxrt_common.nvic + ((u8)irqn >> 5) + (state ? nvic_ispr: nvic_icpr); - *ptr = 1 << (irqn & 0x1F); -} - - -u32 _imxrt_nvicGetActive(s8 irqn) -{ - volatile u32 *ptr = imxrt_common.nvic + ((u8)irqn >> 5) + nvic_iabr; - return !!(*ptr & (1 << (irqn & 0x1F))); -} - - -void _imxrt_nvicSetPriority(s8 irqn, u32 priority) -{ - volatile u8 *ptr; - - ptr = ((u8*)(imxrt_common.nvic + nvic_ip)) + irqn; - - *ptr = (priority << 4) & 0x0ff; -} - - -u8 _imxrt_nvicGetPriority(s8 irqn) -{ - volatile u8 *ptr; - - ptr = ((u8*)(imxrt_common.nvic + nvic_ip)) + irqn; - - return *ptr >> 4; -} - - -void _imxrt_nvicSystemReset(void) -{ - hal_cpuDataSyncBarrier(); - *(imxrt_common.scb + scb_aircr) = ((0x5fa << 16) | (*(imxrt_common.scb + scb_aircr) & (0x700)) | (1 << 0x02)); - - hal_cpuDataSyncBarrier(); - - for (;;) { - } -} - - /* GPIO */ @@ -1996,119 +1876,6 @@ int _imxrt_gpioGetPort(unsigned int d, u32 *val) } -/* Cache */ - - -void _imxrt_enableDCache(void) -{ - u32 ccsidr, sets, ways; - - if ((*(imxrt_common.scb + scb_ccr) & (1 << 16)) == 0) { - *(imxrt_common.scb + scb_csselr) = 0; - hal_cpuDataSyncBarrier(); - - ccsidr = *(imxrt_common.scb + scb_ccsidr); - - /* Invalidate D$ */ - sets = (ccsidr >> 13) & 0x7fff; - do { - ways = (ccsidr >> 3) & 0x3ff; - do { - *(imxrt_common.scb + scb_dcisw) = ((sets & 0x1ff) << 5) | ((ways & 0x3) << 30); - } while (ways-- != 0); - } while (sets-- != 0); - hal_cpuDataSyncBarrier(); - - *(imxrt_common.scb + scb_ccr) |= 1 << 16; - - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); - } -} - - -void _imxrt_disableDCache(void) -{ - register u32 ccsidr, sets, ways; - - *(imxrt_common.scb + scb_csselr) = 0; - hal_cpuDataSyncBarrier(); - - *(imxrt_common.scb + scb_ccr) &= ~(1 << 16); - hal_cpuDataSyncBarrier(); - - ccsidr = *(imxrt_common.scb + scb_ccsidr); - - sets = (ccsidr >> 13) & 0x7fff; - do { - ways = (ccsidr >> 3) & 0x3ff; - do { - *(imxrt_common.scb + scb_dcisw) = ((sets & 0x1ff) << 5) | ((ways & 0x3) << 30); - } while (ways-- != 0); - } while (sets-- != 0); - - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); -} - - -void _imxrt_cleanInvalDCacheAddr(void *addr, u32 sz) -{ - u32 daddr; - int dsize; - - if (sz == 0u) { - return; - } - - daddr = (((u32)addr) & ~0x1fu); - dsize = sz + ((u32)addr & 0x1fu); - - hal_cpuDataSyncBarrier(); - - do { - *(imxrt_common.scb + scb_dccimvac) = daddr; - daddr += 0x20u; - dsize -= 0x20; - } while (dsize > 0); - - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); -} - - -void _imxrt_enableICache(void) -{ - if ((*(imxrt_common.scb + scb_ccr) & (1 << 17)) == 0) { - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); - *(imxrt_common.scb + scb_iciallu) = 0; /* Invalidate I$ */ - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); - *(imxrt_common.scb + scb_ccr) |= 1 << 17; - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); - } -} - - -void _imxrt_disableICache(void) -{ - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); - *(imxrt_common.scb + scb_ccr) &= ~(1 << 17); - *(imxrt_common.scb + scb_iciallu) = 0; - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); -} - - -unsigned int _imxrt_cpuid(void) -{ - return *(imxrt_common.scb + scb_cpuid); -} - - void _imxrt_wdgReload(void) { #if defined(WATCHDOG) @@ -2145,8 +1912,6 @@ void _imxrt_init(void) imxrt_common.iomuxgpr = (void *)0x400ac000; imxrt_common.iomuxc = (void *)0x401f8000; imxrt_common.iomuxsnvs = (void *)0x400a8000; - imxrt_common.nvic = (void *)0xe000e100; - imxrt_common.scb = (void *)0xe000ed00; imxrt_common.stk = (void *)0xe000e010; imxrt_common.wdog1 = (void *)0x400b8000; imxrt_common.wdog2 = (void *)0x400d0000; @@ -2156,6 +1921,9 @@ void _imxrt_init(void) imxrt_common.xtaloscFreq = 24000000; imxrt_common.cpuclk = 528000000; /* Default system clock */ + _hal_scbInit(); + _hal_nvicInit(); + /* Disable watchdogs */ if ((*(imxrt_common.wdog1 + wdog_wcr) & (1 << 2)) != 0) { *(imxrt_common.wdog1 + wdog_wcr) &= ~(1 << 2); @@ -2195,8 +1963,8 @@ void _imxrt_init(void) } /* Configure cache */ - _imxrt_enableDCache(); - _imxrt_enableICache(); + _hal_scbEnableDCache(); + _hal_scbEnableICache(); _imxrt_ccmControlGate(pctl_clk_iomuxc, clk_state_run_wait); @@ -2249,9 +2017,9 @@ void _imxrt_init(void) *(imxrt_common.aips[i] + aipstz_opacr4) &= ~0x44444444; } - /* Enable UsageFault, BusFault and MemManage exceptions */ - *(imxrt_common.scb + scb_shcsr) |= (1 << 16) | (1 << 17) | (1 << 18); - /* Enable system HP timer clock gate */ _imxrt_ccmControlGate(GPT_BUS_CLK, clk_state_run_wait); + + /* Enable FPU */ + _hal_scbSetFPU(1); } diff --git a/hal/armv7m/imxrt/10xx/imxrt10xx.h b/hal/armv7m/imxrt/10xx/imxrt10xx.h index 821ae810c..4b9c48b43 100644 --- a/hal/armv7m/imxrt/10xx/imxrt10xx.h +++ b/hal/armv7m/imxrt/10xx/imxrt10xx.h @@ -168,39 +168,6 @@ extern void _imxrt_ccmControlGate(int dev, int state); extern void _imxrt_ccmSetMode(int mode); -extern void _imxrt_scbSetPriorityGrouping(u32 group); - - -extern u32 _imxrt_scbGetPriorityGrouping(void); - - -extern void _imxrt_scbSetPriority(s8 excpn, u32 priority); - - -extern u32 _imxrt_scbGetPriority(s8 excpn); - - -extern void _imxrt_nvicSetIRQ(s8 irqn, u8 state); - - -extern u32 _imxrt_nvicGetPendingIRQ(s8 irqn); - - -extern void _imxrt_nvicSetPendingIRQ(s8 irqn, u8 state); - - -extern u32 _imxrt_nvicGetActive(s8 irqn); - - -extern void _imxrt_nvicSetPriority(s8 irqn, u32 priority); - - -extern u8 _imxrt_nvicGetPriority(s8 irqn); - - -extern void _imxrt_nvicSystemReset(void); - - extern int _imxrt_gpioConfig(unsigned int d, u8 pin, u8 dir); @@ -225,24 +192,6 @@ extern int _imxrt_setIOpad(int pad, char hys, char pus, char pue, char pke, char extern int _imxrt_setIOisel(int isel, char daisy); -extern void _imxrt_enableDCache(void); - - -extern void _imxrt_cleanInvalDCacheAddr(void *addr, u32 sz); - - -extern void _imxrt_disableDCache(void); - - -extern void _imxrt_enableICache(void); - - -extern void _imxrt_disableICache(void); - - -extern unsigned int _imxrt_cpuid(void); - - extern void _imxrt_wdgReload(void); diff --git a/hal/armv7m/imxrt/117x/console.c b/hal/armv7m/imxrt/117x/console.c index e8fdc5d7d..146edac8b 100644 --- a/hal/armv7m/imxrt/117x/console.c +++ b/hal/armv7m/imxrt/117x/console.c @@ -13,10 +13,10 @@ * %LICENSE% */ -#include "hal/armv7m/armv7m.h" #include "hal/console.h" #include "include/arch/armv7m/imxrt/11xx/imxrt1170.h" #include "imxrt117x.h" +#include #include diff --git a/hal/armv7m/imxrt/117x/imxrt117x.c b/hal/armv7m/imxrt/117x/imxrt117x.c index f618cba77..295f83ce6 100644 --- a/hal/armv7m/imxrt/117x/imxrt117x.c +++ b/hal/armv7m/imxrt/117x/imxrt117x.c @@ -13,7 +13,6 @@ * %LICENSE% */ -#include "hal/armv7m/armv7m.h" #include "hal/spinlock.h" #include "hal/cpu.h" #include "hal/armv7m/imxrt/halsyspage.h" @@ -23,6 +22,9 @@ #include "imxrt117x.h" #include "config.h" +#include "hal/arm/nvic.h" +#include "hal/arm/scb.h" + #include #define RTWDOG_UNLOCK_KEY 0xd928c520u @@ -48,16 +50,6 @@ enum { stk_ctrl = 0, stk_load, stk_val, stk_calib }; enum { aipstz_mpr = 0, aipstz_opacr = 16, aipstz_opacr1, aipstz_opacr2, aipstz_opacr3, aipstz_opacr4 }; -enum { scb_cpuid = 0, scb_icsr, scb_vtor, scb_aircr, scb_scr, scb_ccr, scb_shp0, scb_shp1, - scb_shp2, scb_shcsr, scb_cfsr, scb_hfsr, scb_dfsr, scb_mmfar, scb_bfar, scb_afsr, scb_pfr0, - scb_pfr1, scb_dfr, scb_afr, scb_mmfr0, scb_mmfr1, scb_mmfr2, scb_mmf3, scb_isar0, scb_isar1, - scb_isar2, scb_isar3, scb_isar4, /* reserved */ scb_clidr = 30, scb_ctr, scb_ccsidr, scb_csselr, - scb_cpacr, /* 93 reserved */ scb_stir = 128, /* 15 reserved */ scb_mvfr0 = 144, scb_mvfr1, - scb_mvfr2, /* reserved */ scb_iciallu = 148, /* reserved */ scb_icimvau = 150, scb_scimvac, - scb_dcisw, scb_dccmvau, scb_dccmvac, scb_dccsw, scb_dccimvac, scb_dccisw, /* 6 reserved */ - scb_itcmcr = 164, scb_dtcmcr, scb_ahbpcr, scb_cacr, scb_ahbscr, /* reserved */ scb_abfsr = 170 }; - - enum { src_scr = 0, src_srmr, src_sbmr1, src_sbmr2, src_srsr, src_gpr1, src_gpr2, src_gpr3, src_gpr4, src_gpr5, src_gpr6, src_gpr7, src_gpr8, src_gpr9, src_gpr10, @@ -66,10 +58,6 @@ enum { src_scr = 0, src_srmr, src_sbmr1, src_sbmr2, src_srsr, src_authen = 128, src_ctrl, src_setpoint, src_domain, src_stat }; -enum { nvic_iser = 0, nvic_icer = 32, nvic_ispr = 64, nvic_icpr = 96, nvic_iabr = 128, - nvic_ip = 256, nvic_stir = 896 }; - - enum { wdog_wcr = 0, wdog_wsr, wdog_wrsr, wdog_wicr, wdog_wmcr }; @@ -80,9 +68,7 @@ enum { rtwdog_cs = 0, rtwdog_cnt, rtwdog_toval, rtwdog_win }; struct { volatile u32 *aips[4]; - volatile u32 *nvic; volatile u32 *stk; - volatile u32 *scb; volatile u32 *src; volatile u16 *wdog1; volatile u16 *wdog2; @@ -101,12 +87,6 @@ struct { } imxrt_common; -unsigned int _imxrt_cpuid(void) -{ - return *(imxrt_common.scb + scb_cpuid); -} - - void _imxrt_wdgReload(void) { #if defined(WATCHDOG) @@ -382,49 +362,6 @@ static int _imxrt_getIOisel(int isel, char *daisy) } -/* SCB */ - - -void _imxrt_scbSetPriorityGrouping(u32 group) -{ - u32 t; - - /* Get register value and clear bits to set */ - t = *(imxrt_common.scb + scb_aircr) & ~0xffff0700; - - /* Store new value */ - *(imxrt_common.scb + scb_aircr) = t | 0x5fa0000 | ((group & 7) << 8); - hal_cpuDataMemoryBarrier(); -} - - -u32 _imxrt_scbGetPriorityGrouping(void) -{ - return (*(imxrt_common.scb + scb_aircr) & 0x700) >> 8; -} - - -void _imxrt_scbSetPriority(s8 excpn, u32 priority) -{ - volatile u8 *ptr; - - ptr = &((u8*)(imxrt_common.scb + scb_shp0))[excpn - 4]; - - *ptr = (priority << 4) & 0x0ff; - hal_cpuDataMemoryBarrier(); -} - - -u32 _imxrt_scbGetPriority(s8 excpn) -{ - volatile u8 *ptr; - - ptr = &((u8*)(imxrt_common.scb + scb_shp0))[excpn - 4]; - - return *ptr >> 4; -} - - /* SRC */ @@ -438,181 +375,6 @@ void _imxrt_resetSlice(unsigned int index) } -/* NVIC (Nested Vectored Interrupt Controller */ - - -void _imxrt_nvicSetIRQ(s8 irqn, u8 state) -{ - volatile u32 *ptr = imxrt_common.nvic + ((u8)irqn >> 5) + (state ? nvic_iser: nvic_icer); - *ptr = 1 << (irqn & 0x1F); - - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); -} - - -u32 _imxrt_nvicGetPendingIRQ(s8 irqn) -{ - volatile u32 *ptr = imxrt_common.nvic + ((u8)irqn >> 5) + nvic_ispr; - return !!(*ptr & (1 << (irqn & 0x1F))); -} - - -void _imxrt_nvicSetPendingIRQ(s8 irqn, u8 state) -{ - volatile u32 *ptr = imxrt_common.nvic + ((u8)irqn >> 5) + (state ? nvic_ispr: nvic_icpr); - *ptr = 1 << (irqn & 0x1F); - hal_cpuDataMemoryBarrier(); -} - - -u32 _imxrt_nvicGetActive(s8 irqn) -{ - volatile u32 *ptr = imxrt_common.nvic + ((u8)irqn >> 5) + nvic_iabr; - return !!(*ptr & (1 << (irqn & 0x1F))); -} - - -void _imxrt_nvicSetPriority(s8 irqn, u32 priority) -{ - volatile u8 *ptr; - - ptr = (u8*)(imxrt_common.nvic + irqn + nvic_ip); - - *ptr = (priority << 4) & 0x0ff; -} - - -u8 _imxrt_nvicGetPriority(s8 irqn) -{ - volatile u8 *ptr; - - ptr = (u8*)(imxrt_common.nvic + irqn + nvic_ip); - - return *ptr >> 4; -} - - -void _imxrt_nvicSystemReset(void) -{ - hal_cpuDataSyncBarrier(); - *(imxrt_common.scb + scb_aircr) = ((0x5fa << 16) | (*(imxrt_common.scb + scb_aircr) & (0x700)) | (1 << 0x02)); - - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); - - for (;;) { - } -} - - -/* Cache */ - - -void _imxrt_enableDCache(void) -{ - u32 ccsidr, sets, ways; - - if ((*(imxrt_common.scb + scb_ccr) & (1 << 16)) == 0) { - *(imxrt_common.scb + scb_csselr) = 0; - hal_cpuDataSyncBarrier(); - - ccsidr = *(imxrt_common.scb + scb_ccsidr); - - /* Invalidate D$ */ - sets = (ccsidr >> 13) & 0x7fff; - do { - ways = (ccsidr >> 3) & 0x3ff; - do { - *(imxrt_common.scb + scb_dcisw) = ((sets & 0x1ff) << 5) | ((ways & 0x3) << 30); - } while (ways-- != 0); - } while (sets-- != 0); - hal_cpuDataSyncBarrier(); - - *(imxrt_common.scb + scb_ccr) |= 1 << 16; - - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); - } -} - - -void _imxrt_disableDCache(void) -{ - register u32 ccsidr, sets, ways; - - *(imxrt_common.scb + scb_csselr) = 0; - hal_cpuDataSyncBarrier(); - - *(imxrt_common.scb + scb_ccr) &= ~(1 << 16); - hal_cpuDataSyncBarrier(); - - ccsidr = *(imxrt_common.scb + scb_ccsidr); - - sets = (ccsidr >> 13) & 0x7fff; - do { - ways = (ccsidr >> 3) & 0x3ff; - do { - *(imxrt_common.scb + scb_dcisw) = ((sets & 0x1ff) << 5) | ((ways & 0x3) << 30); - } while (ways-- != 0); - } while (sets-- != 0); - - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); -} - - -void _imxrt_cleanInvalDCacheAddr(void *addr, u32 sz) -{ - u32 daddr; - int dsize; - - if (sz == 0u) { - return; - } - - daddr = (((u32)addr) & ~0x1fu); - dsize = sz + ((u32)addr & 0x1fu); - - hal_cpuDataSyncBarrier(); - - do { - *(imxrt_common.scb + scb_dccimvac) = daddr; - daddr += 0x20u; - dsize -= 0x20; - } while (dsize > 0); - - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); -} - - -void _imxrt_enableICache(void) -{ - if ((*(imxrt_common.scb + scb_ccr) & (1 << 17)) == 0) { - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); - *(imxrt_common.scb + scb_iciallu) = 0; /* Invalidate I$ */ - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); - *(imxrt_common.scb + scb_ccr) |= 1 << 17; - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); - } -} - - -void _imxrt_disableICache(void) -{ - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); - *(imxrt_common.scb + scb_ccr) &= ~(1 << 17); - *(imxrt_common.scb + scb_iciallu) = 0; - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); -} - - /* CCM */ int _imxrt_setDevClock(int clock, int div, int mux, int mfd, int mfn, int state) @@ -905,7 +667,7 @@ int hal_platformctl(void *ptr) case pctl_reboot: if (data->action == pctl_set) { if (data->reboot.magic == PCTL_REBOOT_MAGIC) { - _imxrt_nvicSystemReset(); + _hal_scbSystemReset(); } } else if (data->action == pctl_get) { @@ -917,12 +679,12 @@ int hal_platformctl(void *ptr) case pctl_devcache: if (data->action == pctl_set) { if (data->devcache.state == 0) { - _imxrt_disableDCache(); - _imxrt_disableICache(); + _hal_scbDisableDCache(); + _hal_scbDisableICache(); } else { - _imxrt_enableDCache(); - _imxrt_enableICache(); + _hal_scbEnableDCache(); + _hal_scbEnableICache(); } ret = EOK; @@ -931,7 +693,7 @@ int hal_platformctl(void *ptr) case pctl_cleanInvalDCache: if (data->action == pctl_set) { - _imxrt_cleanInvalDCacheAddr(data->cleanInvalDCache.addr, data->cleanInvalDCache.sz); + _hal_scbCleanInvalDCacheAddr(data->cleanInvalDCache.addr, data->cleanInvalDCache.sz); ret = EOK; } break; @@ -980,8 +742,6 @@ void _imxrt_init(void) imxrt_common.aips[2] = (void *)0x40800000; imxrt_common.aips[3] = (void *)0x40c00000; imxrt_common.ccm = (void *)0x40cc0000; - imxrt_common.nvic = (void *)0xe000e100; - imxrt_common.scb = (void *)0xe000ed00; imxrt_common.stk = (void *)0xe000e010; imxrt_common.wdog1 = (void *)0x40030000; imxrt_common.wdog2 = (void *)0x40034000; @@ -996,6 +756,9 @@ void _imxrt_init(void) imxrt_common.cpuclk = 696000000; + _hal_scbInit(); + _hal_nvicInit(); + /* Disable watchdogs (WDOG1, WDOG2) */ if ((*(imxrt_common.wdog1 + wdog_wcr) & (1u << 2u)) != 0u) { *(imxrt_common.wdog1 + wdog_wcr) &= ~(1u << 2u); @@ -1049,4 +812,7 @@ void _imxrt_init(void) /* Enable system HP timer clock gate, select SYS_PLL3_DIV2 as BUS clk */ _imxrt_setDevClock(GPT_BUS_CLK, 0, 4, 0, 0, 1); + + /* Enable FPU */ + _hal_scbSetFPU(1); } diff --git a/hal/armv7m/imxrt/117x/imxrt117x.h b/hal/armv7m/imxrt/117x/imxrt117x.h index b414a81d0..df5d69048 100644 --- a/hal/armv7m/imxrt/117x/imxrt117x.h +++ b/hal/armv7m/imxrt/117x/imxrt117x.h @@ -23,24 +23,6 @@ extern int hal_platformctl(void *ptr); -extern unsigned int _imxrt_cpuid(void); - - -extern void _imxrt_cleanInvalDCacheAddr(void *addr, u32 sz); - - -extern void _imxrt_nvicSetIRQ(s8 irqn, u8 state); - - -extern void _imxrt_nvicSetPriority(s8 irqn, u32 priority); - - -extern void _imxrt_scbSetPriorityGrouping(u32 group); - - -extern void _imxrt_scbSetPriority(s8 excpn, u32 priority); - - extern void _imxrt_wdgReload(void); @@ -71,10 +53,4 @@ extern void _imxrt_platformInit(void); extern void _imxrt_init(void); -extern void _imxrt_nvicSetIRQ(s8 irqn, u8 state); - - -extern void _imxrt_nvicSystemReset(void); - - #endif diff --git a/hal/armv7m/imxrt/_init.S b/hal/armv7m/imxrt/_init.S index d28b65c39..2c891aa8f 100644 --- a/hal/armv7m/imxrt/_init.S +++ b/hal/armv7m/imxrt/_init.S @@ -70,20 +70,6 @@ _start: ldr r8, =syspage str r9, [r8] - /* Enable FPU */ - ldr r0, =0xe000ed88 - ldr r1, [r0] - orr r1, r1, #(0xf << 20) - str r1, [r0] - isb - dmb - - /* Enable FPU ctx */ - mrs r0, control - orr r0, r0, #(1 << 2) - msr control, r0 - isb - /* Init vector table and stack pointer */ ldr r0, =0xe000ed08 ldr r1, =_init_vectors diff --git a/hal/armv7m/imxrt/interrupts.c b/hal/armv7m/imxrt/interrupts.c index 56c21dc97..4e2a1749e 100644 --- a/hal/armv7m/imxrt/interrupts.c +++ b/hal/armv7m/imxrt/interrupts.c @@ -72,8 +72,8 @@ int hal_interruptsSetHandler(intr_handler_t *h) HAL_LIST_ADD(&interrupts.handlers[h->n], h); if (h->n >= 0x10) { - _imxrt_nvicSetPriority(h->n - 0x10, 0); - _imxrt_nvicSetIRQ(h->n - 0x10, 1); + _hal_nvicSetPriority(h->n - 0x10, 0); + _hal_nvicSetIRQ(h->n - 0x10, 1); } hal_spinlockClear(&interrupts.spinlock, &sc); @@ -92,7 +92,7 @@ int hal_interruptsDeleteHandler(intr_handler_t *h) HAL_LIST_REMOVE(&interrupts.handlers[h->n], h); if (h->n >= 0x10 && interrupts.handlers[h->n] == NULL) - _imxrt_nvicSetIRQ(h->n - 0x10, 0); + _hal_nvicSetIRQ(h->n - 0x10, 0); hal_spinlockClear(&interrupts.spinlock, &sc); @@ -120,12 +120,12 @@ __attribute__ ((section (".init"))) void _hal_interruptsInit(void) hal_spinlockCreate(&interrupts.spinlock, "interrupts.spinlock"); - _imxrt_scbSetPriority(SYSTICK_IRQ, 0); - _imxrt_scbSetPriority(PENDSV_IRQ, 0); - _imxrt_scbSetPriority(SVC_IRQ, 0); + _hal_scbSetPriority(SYSTICK_IRQ, 0); + _hal_scbSetPriority(PENDSV_IRQ, 0); + _hal_scbSetPriority(SVC_IRQ, 0); /* Set no subprorities in Interrupt Group Priority */ - _imxrt_scbSetPriorityGrouping(3); + _hal_scbSetPriorityGrouping(3); return; } diff --git a/hal/armv7m/imxrt/timer.c b/hal/armv7m/imxrt/timer.c index 238bd8357..9ed93fc61 100644 --- a/hal/armv7m/imxrt/timer.c +++ b/hal/armv7m/imxrt/timer.c @@ -14,7 +14,6 @@ */ #include "hal/timer.h" -#include "hal/armv7m/armv7m.h" #include "config.h" #include #include diff --git a/hal/armv7m/pmap.c b/hal/armv7m/pmap.c index a3e56e7d6..2527dcbac 100644 --- a/hal/armv7m/pmap.c +++ b/hal/armv7m/pmap.c @@ -18,7 +18,6 @@ #include "syspage.h" #include "halsyspage.h" #include -#include "armv7m.h" #include enum { mpu_type, mpu_ctrl, mpu_rnr, mpu_rbar, mpu_rasr, mpu_rbar_a1, mpu_rasr_a1, mpu_rbar_a2, mpu_rasr_a2, diff --git a/hal/armv7m/stm32/interrupts.c b/hal/armv7m/stm32/interrupts.c index 844b3be19..a04d759b9 100644 --- a/hal/armv7m/stm32/interrupts.c +++ b/hal/armv7m/stm32/interrupts.c @@ -81,8 +81,8 @@ int hal_interruptsSetHandler(intr_handler_t *h) HAL_LIST_ADD(&interrupts.handlers[h->n], h); if (h->n >= 0x10) { - _stm32_nvicSetPriority(h->n - 0x10, 1); - _stm32_nvicSetIRQ(h->n - 0x10, 1); + _hal_nvicSetPriority(h->n - 0x10, 1); + _hal_nvicSetIRQ(h->n - 0x10, 1); } hal_spinlockClear(&interrupts.spinlock, &sc); @@ -101,7 +101,7 @@ int hal_interruptsDeleteHandler(intr_handler_t *h) HAL_LIST_REMOVE(&interrupts.handlers[h->n], h); if (h->n >= 0x10 && interrupts.handlers[h->n] == NULL) - _stm32_nvicSetIRQ(h->n - 0x10, 0); + _hal_nvicSetIRQ(h->n - 0x10, 0); hal_spinlockClear(&interrupts.spinlock, &sc); @@ -129,12 +129,12 @@ __attribute__ ((section (".init"))) void _hal_interruptsInit(void) hal_spinlockCreate(&interrupts.spinlock, "interrupts.spinlock"); - _stm32_scbSetPriority(SYSTICK_IRQ, 1); - _stm32_scbSetPriority(PENDSV_IRQ, 0); - _stm32_scbSetPriority(SVC_IRQ, 0); + _hal_scbSetPriority(SYSTICK_IRQ, 1); + _hal_scbSetPriority(PENDSV_IRQ, 0); + _hal_scbSetPriority(SVC_IRQ, 0); /* Set no subprorities in Interrupt Group Priority */ - _stm32_scbSetPriorityGrouping(3); + _hal_scbSetPriorityGrouping(3); return; } diff --git a/hal/armv7m/stm32/l4/console.c b/hal/armv7m/stm32/l4/console.c index db2394b8c..34af81ee5 100644 --- a/hal/armv7m/stm32/l4/console.c +++ b/hal/armv7m/stm32/l4/console.c @@ -15,7 +15,6 @@ #include "hal/console.h" #include "hal/cpu.h" -#include "hal/armv7m/armv7m.h" #include "stm32.h" diff --git a/hal/armv7m/stm32/l4/stm32l4.c b/hal/armv7m/stm32/l4/stm32l4.c index 41cef787a..f5b6cf39c 100644 --- a/hal/armv7m/stm32/l4/stm32l4.c +++ b/hal/armv7m/stm32/l4/stm32l4.c @@ -18,9 +18,11 @@ #include "hal/armv7m/stm32/halsyspage.h" #include "hal/cpu.h" -#include "hal/armv7m/armv7m.h" #include "include/errno.h" +#include "hal/arm/nvic.h" +#include "hal/arm/scb.h" + #include #if defined(WATCHDOG) && defined(WATCHDOG_TIMEOUT_MS) @@ -32,9 +34,7 @@ struct { volatile u32 *rcc; volatile u32 *gpio[9]; volatile u32 *pwr; - volatile u32 *scb; volatile u32 *rtc; - volatile u32 *nvic; volatile u32 *exti; volatile u32 *syscfg; volatile u32 *iwdg; @@ -74,22 +74,10 @@ enum { rtc_tr = 0, rtc_dr, rtc_cr, rtc_isr, rtc_prer, rtc_wutr, rtc_alrmar = rtc rtc_bkpr }; -enum { scb_actlr = 2, scb_cpuid = 832, scb_icsr, scb_vtor, scb_aircr, scb_scr, scb_ccr, scb_shp1, scb_shp2, - scb_shp3, scb_shcsr, scb_cfsr, scb_mmsr, scb_bfsr, scb_ufsr, scb_hfsr, scb_mmar, scb_bfar, scb_afsr, - scb_cpacr = 866, scb_fpccr = 973, scb_fpcar, scb_fpdscr }; - - -enum { nvic_iser = 0, nvic_icer = 32, nvic_ispr = 64, nvic_icpr = 96, nvic_iabr = 128, - nvic_ip = 192, nvic_stir = 896 }; - - enum { exti_imr1 = 0, exti_emr1, exti_rtsr1, exti_ftsr1, exti_swier1, exti_pr1, exti_imr2 = 8, exti_emr2, exti_rtsr2, exti_ftsr2, exti_swier2, exti_pr2 }; -enum { syst_csr = 4, syst_rvr, syst_cvr, syst_calib }; - - enum { syscfg_memrmp = 0, syscfg_cfgr1, syscfg_exticr1, syscfg_exticr2, syscfg_exticr3, syscfg_exticr4, syscfg_scsr, syscfg_cfgr2, syscfg_swpr, syscfg_skr, syscfg_swpr2 }; @@ -139,8 +127,9 @@ int hal_platformctl(void *ptr) break; case pctl_reboot: if (data->action == pctl_set) { - if (data->reboot.magic == PCTL_REBOOT_MAGIC) - _stm32_nvicSystemReset(); + if (data->reboot.magic == PCTL_REBOOT_MAGIC) { + _hal_scbSystemReset(); + } } else if (data->action == pctl_get) { data->reboot.reason = syspage->hs.bootReason; @@ -485,9 +474,7 @@ time_t _stm32_pwrEnterLPStop(time_t us) hal_cpuDataMemoryBarrier(); /* Set SLEEPDEEP bit of Cortex System Control Register */ - *(stm32_common.scb + scb_scr) |= 1 << 2; - - *(stm32_common.scb + syst_csr) &= ~1; + _hal_scbSetDeepSleep(1); timer_setAlarm(us); @@ -498,9 +485,7 @@ time_t _stm32_pwrEnterLPStop(time_t us) nop; "); /* Reset SLEEPDEEP bit of Cortex System Control Register */ - *(stm32_common.scb + scb_scr) &= ~(1 << 2); - - *(stm32_common.scb + syst_csr) |= 1; + _hal_scbSetDeepSleep(0); if (restoreMsi != 0) { /* Restore pre-sleep MSI clock */ @@ -516,112 +501,6 @@ time_t _stm32_pwrEnterLPStop(time_t us) } -/* SCB */ - - -void _stm32_scbSetPriorityGrouping(u32 group) -{ - u32 t; - - /* Get register value and clear bits to set */ - t = *(stm32_common.scb + scb_aircr) & ~0xffff0700; - - /* Store new value */ - *(stm32_common.scb + scb_aircr) = t | 0x5fa0000 | ((group & 7) << 8); -} - - -u32 _stm32_scbGetPriorityGrouping(void) -{ - return (*(stm32_common.scb + scb_aircr) & 0x700) >> 8; -} - - -void _stm32_scbSetPriority(s8 excpn, u32 priority) -{ - volatile u8 *ptr; - - ptr = &((u8*)(stm32_common.scb + scb_shp1))[excpn - 4]; - - *ptr = (priority << 4) & 0xff; -} - - -u32 _stm32_scbGetPriority(s8 excpn) -{ - volatile u8 *ptr; - - ptr = &((u8*)(stm32_common.scb + scb_shp1))[excpn - 4]; - - return *ptr >> 4; -} - - -/* NVIC (Nested Vectored Interrupt Controller */ - - -void _stm32_nvicSetIRQ(s8 irqn, u8 state) -{ - volatile u32 *ptr = stm32_common.nvic + ((u8)irqn >> 5) + (state ? nvic_iser: nvic_icer); - *ptr = 1 << (irqn & 0x1F); - - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); -} - - -u32 _stm32_nvicGetPendingIRQ(s8 irqn) -{ - volatile u32 *ptr = stm32_common.nvic + ((u8)irqn >> 5) + nvic_ispr; - return !!(*ptr & (1 << (irqn & 0x1F))); -} - - -void _stm32_nvicSetPendingIRQ(s8 irqn, u8 state) -{ - volatile u32 *ptr = stm32_common.nvic + ((u8)irqn >> 5) + (state ? nvic_ispr: nvic_icpr); - *ptr = 1 << (irqn & 0x1F); -} - - -u32 _stm32_nvicGetActive(s8 irqn) -{ - volatile u32 *ptr = stm32_common.nvic + ((u8)irqn >> 5) + nvic_iabr; - return !!(*ptr & (1 << (irqn & 0x1F))); -} - - -void _stm32_nvicSetPriority(s8 irqn, u32 priority) -{ - volatile u8 *ptr; - - ptr = ((u8*)(stm32_common.nvic + nvic_ip)) + irqn; - - *ptr = (priority << 4) & 0xff; -} - - -u8 _stm32_nvicGetPriority(s8 irqn) -{ - volatile u8 *ptr; - - ptr = ((u8*)(stm32_common.nvic + nvic_ip)) + irqn; - - return *ptr >> 4; -} - - -void _stm32_nvicSystemReset(void) -{ - *(stm32_common.scb + scb_aircr) = ((0x5fa << 16) | (*(stm32_common.scb + scb_aircr) & (0x700)) | (1 << 0x02)); - - __asm__ volatile ("dsb"); - - for (;;) { - } -} - - /* EXTI */ @@ -699,33 +578,16 @@ int _stm32_extiSoftInterrupt(u32 line) int _stm32_systickInit(u32 interval) { u64 load = ((u64) interval * stm32_common.cpuclk) / 1000000; - if (load > 0x00ffffff) + if (load > 0x00ffffff) { return -EINVAL; + } - *(stm32_common.scb + syst_rvr) = (u32)load; - *(stm32_common.scb + syst_cvr) = 0; - - /* Enable systick */ - *(stm32_common.scb + syst_csr) |= 0x7; + _hal_scbSystickInit(load); return EOK; } -u32 _stm32_systickGet(void) -{ - u32 cb; - - cb = ((*(stm32_common.scb + syst_rvr) - *(stm32_common.scb + syst_cvr)) * 1000) / *(stm32_common.scb + syst_rvr); - - /* Add 1000 us if there's systick pending */ - if (*(stm32_common.scb + scb_icsr) & (1 << 26)) - cb += 1000; - - return cb; -} - - /* GPIO */ @@ -828,15 +690,6 @@ int _stm32_gpioGetPort(unsigned int d, u16 *val) } -/* CPU info */ - - -unsigned int _stm32_cpuid(void) -{ - return *(stm32_common.scb + scb_cpuid); -} - - /* Watchdog */ @@ -857,9 +710,7 @@ void _stm32_init(void) /* Base addresses init */ stm32_common.rcc = (void *)0x40021000; stm32_common.pwr = (void *)0x40007000; - stm32_common.scb = (void *)0xe000e000; stm32_common.rtc = (void *)0x40002800; - stm32_common.nvic = (void *)0xe000e100; stm32_common.exti = (void *)0x40010400; stm32_common.syscfg = (void *)0x40010000; stm32_common.iwdg = (void *)0x40003000; @@ -874,6 +725,9 @@ void _stm32_init(void) stm32_common.gpio[8] = (void *)0x48002000; /* GPIOI */ stm32_common.flash = (void *)0x40022000; + _hal_scbInit(); + _hal_nvicInit(); + /* Enable System configuration controller */ _stm32_rccSetDevClock(pctl_syscfg, 1); @@ -964,12 +818,8 @@ void _stm32_init(void) *(u32 *)0xE0042004 = 0; #endif - /* Enable UsageFault, BusFault and MemManage exceptions */ - *(stm32_common.scb + scb_shcsr) |= (1 << 16) | (1 << 17) | (1 << 18); - /* Disable FPU */ - *(stm32_common.scb + scb_cpacr) = 0; - *(stm32_common.scb + scb_fpccr) = 0; + _hal_scbSetFPU(0); /* Enable internal wakeup line */ *(stm32_common.pwr + pwr_cr3) |= 1 << 15; diff --git a/hal/armv7m/stm32/l4/timer.c b/hal/armv7m/stm32/l4/timer.c index e9d03fec1..b1379718e 100644 --- a/hal/armv7m/stm32/l4/timer.c +++ b/hal/armv7m/stm32/l4/timer.c @@ -14,7 +14,6 @@ */ #include "hal/armv7m/stm32/config.h" -#include "hal/armv7m/armv7m.h" #include "hal/timer.h" #include "hal/interrupts.h" #include "hal/spinlock.h" diff --git a/hal/armv8m/Makefile b/hal/armv8m/Makefile index 832e5612a..e228a508d 100644 --- a/hal/armv8m/Makefile +++ b/hal/armv8m/Makefile @@ -13,4 +13,8 @@ else ifneq (, $(findstring mcx, $(TARGET_SUBFAMILY))) CFLAGS += -Ihal/armv8m endif -OBJS += $(addprefix $(PREFIX_O)hal/armv8m/, string.o spinlock.o cpu.o hal.o pmap.o exceptions.o _memcpy.o _memset.o) +include hal/arm/Makefile +CFLAGS += -Ihal/arm + +OBJS += $(addprefix $(PREFIX_O)hal/armv8m/, string.o spinlock.o cpu.o hal.o \ + pmap.o exceptions.o _memcpy.o _memset.o interrupts.o) diff --git a/hal/armv8m/arch/cpu.h b/hal/armv8m/arch/cpu.h index 2ca964119..6c606568e 100644 --- a/hal/armv8m/arch/cpu.h +++ b/hal/armv8m/arch/cpu.h @@ -37,6 +37,8 @@ #ifndef __ASSEMBLY__ +#include "hal/arm/scb.h" +#include "hal/arm/barriers.h" #define SYSTICK_INTERVAL 1000 diff --git a/hal/armv8m/arch/interrupts.h b/hal/armv8m/arch/interrupts.h index bf1f5a5b0..fdeae4f64 100644 --- a/hal/armv8m/arch/interrupts.h +++ b/hal/armv8m/arch/interrupts.h @@ -18,6 +18,7 @@ #define _HAL_ARMV8M_INTERRUPTS_H_ #include "cpu.h" +#include "hal/arm/nvic.h" #define SVC_IRQ 11 #define PENDSV_IRQ 14 diff --git a/hal/armv8m/armv8m.h b/hal/armv8m/armv8m.h deleted file mode 100644 index 32c9a46e5..000000000 --- a/hal/armv8m/armv8m.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Phoenix-RTOS - * - * Operating system kernel - * - * ARMv8 Cortex-M related routines - * - * Copyright 2021, 2022 Phoenix Systems - * Author: Hubert Buczynski, Damian Loewnau - * - * This file is part of Phoenix-RTOS. - * - * %LICENSE% - */ - -#ifndef _HAL_ARMV8M_H_ -#define _HAL_ARMV8M_H_ - - -static inline void hal_cpuDataMemoryBarrier(void) -{ - __asm__ volatile("dmb"); -} - - -static inline void hal_cpuDataSyncBarrier(void) -{ - __asm__ volatile("dsb"); -} - - -static inline void hal_cpuInstrBarrier(void) -{ - __asm__ volatile("isb"); -} - -#endif diff --git a/hal/armv8m/cpu.c b/hal/armv8m/cpu.c index 587a446c5..c80f72797 100644 --- a/hal/armv8m/cpu.c +++ b/hal/armv8m/cpu.c @@ -68,6 +68,7 @@ void hal_cpuSetDevBusy(int s) hal_spinlockClear(&cpu_common.busySp, &scp); } + int hal_cpuCreateContext(cpu_context_t **nctx, void *start, void *kstack, size_t kstacksz, void *ustack, void *arg, hal_tls_t *tls) { cpu_context_t *ctx; @@ -180,16 +181,7 @@ void hal_cpuSigreturn(void *kstack, void *ustack, cpu_context_t **ctx) char *hal_cpuInfo(char *info) { int i; - unsigned int cpuinfo; - -#if defined(__CPU_NRF9160) - cpuinfo = _nrf91_cpuid(); -#elif defined(__CPU_MCXN94X) - cpuinfo = _mcxn94x_cpuid(); -#else - hal_strcpy(info, "unknown"); - return info; -#endif + unsigned int cpuinfo = _hal_scbCpuid(); hal_strcpy(info, HAL_NAME_PLATFORM); i = sizeof(HAL_NAME_PLATFORM) - 1; @@ -255,7 +247,7 @@ void hal_wdgReload(void) void hal_cpuReboot(void) { - _interrupts_nvicSystemReset(); + _hal_scbSystemReset(); } diff --git a/hal/armv8m/hal.c b/hal/armv8m/hal.c index 5db76757e..5acf0b7ca 100644 --- a/hal/armv8m/hal.c +++ b/hal/armv8m/hal.c @@ -56,12 +56,12 @@ void hal_lockScheduler(void) void _hal_init(void) { + hal_common.started = 0; + _hal_spinlockInit(); _hal_exceptionsInit(); _hal_interruptsInit(); _hal_cpuInit(); _hal_consoleInit(); _hal_timerInit(SYSTICK_INTERVAL); - - hal_common.started = 0; } diff --git a/hal/armv8m/mcx/interrupts.c b/hal/armv8m/interrupts.c similarity index 63% rename from hal/armv8m/mcx/interrupts.c rename to hal/armv8m/interrupts.c index 6a5a2a7d1..6f21383e1 100644 --- a/hal/armv8m/mcx/interrupts.c +++ b/hal/armv8m/interrupts.c @@ -17,7 +17,6 @@ #include "hal/spinlock.h" #include "hal/cpu.h" #include "hal/list.h" -#include "hal/armv8m/armv8m.h" #include "hal/armv8m/mcx/n94x/mcxn94x.h" #include "proc/userintr.h" @@ -25,66 +24,15 @@ #include "config.h" static struct { - volatile u32 *nvic; - volatile u32 *scb; spinlock_t spinlock; intr_handler_t *handlers[SIZE_INTERRUPTS]; unsigned int counters[SIZE_INTERRUPTS]; } interrupts; -/* clang-format off */ -enum { nvic_iser = 0, nvic_icer = 32, nvic_ispr = 64, nvic_icpr = 96, nvic_iabr = 128, - nvic_ip = 192 }; -/* clang-format on */ - - extern int threads_schedule(unsigned int n, cpu_context_t *context, void *arg); -void _interrupts_nvicSetIRQ(s8 irqn, u8 state) -{ - volatile u32 *ptr = interrupts.nvic + ((u8)irqn >> 5) + ((state != 0) ? nvic_iser : nvic_icer); - *ptr = 1u << (irqn & 0x1f); - - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); -} - - -void _interrupts_nvicSetPriority(s8 irqn, u32 priority) -{ - volatile u32 *ptr; - - ptr = ((u32 *)(interrupts.nvic + nvic_ip)) + (irqn / 4); - - /* We set only group priority field */ - *ptr = (priority << (8 * (irqn % 4) + 4)); -} - - -void _interrupts_nvicSetPending(s8 irqn) -{ - volatile u32 *ptr = interrupts.nvic + ((u8)irqn >> 5) + nvic_ispr; - - *ptr = 1u << (irqn & 0x1f); - - hal_cpuDataSyncBarrier(); -} - - -void _interrupts_nvicSystemReset(void) -{ - *(interrupts.scb + scb_aircr) = ((0x5fau << 16) | (*(interrupts.scb + scb_aircr) & (0x700u)) | (1u << 2)); - - hal_cpuDataSyncBarrier(); - - for (;;) { - hal_cpuHalt(); - } -} - - void interrupts_dispatch(unsigned int n, cpu_context_t *ctx) { intr_handler_t *h; @@ -133,8 +81,8 @@ int hal_interruptsSetHandler(intr_handler_t *h) HAL_LIST_ADD(&interrupts.handlers[h->n], h); if (h->n >= 0x10) { - _interrupts_nvicSetPriority(h->n - 0x10, 1); - _interrupts_nvicSetIRQ(h->n - 0x10, 1); + _hal_nvicSetPriority(h->n - 0x10, 1); + _hal_nvicSetIRQ(h->n - 0x10, 1); } hal_spinlockClear(&interrupts.spinlock, &sc); @@ -154,7 +102,7 @@ int hal_interruptsDeleteHandler(intr_handler_t *h) HAL_LIST_REMOVE(&interrupts.handlers[h->n], h); if (h->n >= 0x10 && interrupts.handlers[h->n] == NULL) { - _interrupts_nvicSetIRQ(h->n - 0x10, 0); + _hal_nvicSetIRQ(h->n - 0x10, 0); } hal_spinlockClear(&interrupts.spinlock, &sc); @@ -181,17 +129,14 @@ __attribute__((section(".init"))) void _hal_interruptsInit(void) interrupts.counters[n] = 0; } - interrupts.nvic = (void *)0xe000e100; - interrupts.scb = (void *)0xe000e000; - hal_spinlockCreate(&interrupts.spinlock, "interrupts.spinlock"); - _mcxn94x_scbSetPriority(SYSTICK_IRQ, 1); - _mcxn94x_scbSetPriority(PENDSV_IRQ, 1); - _mcxn94x_scbSetPriority(SVC_IRQ, 0); + _hal_scbSetPriority(SYSTICK_IRQ, 1); + _hal_scbSetPriority(PENDSV_IRQ, 1); + _hal_scbSetPriority(SVC_IRQ, 0); /* Set no subprorities in Interrupt Group Priority */ - _mcxn94x_scbSetPriorityGrouping(3); + _hal_scbSetPriorityGrouping(3); return; } diff --git a/hal/armv8m/mcx/Makefile b/hal/armv8m/mcx/Makefile index 46e6c2439..3481c3899 100644 --- a/hal/armv8m/mcx/Makefile +++ b/hal/armv8m/mcx/Makefile @@ -9,4 +9,4 @@ ifneq (, $(findstring mcxn94x, $(TARGET_SUBFAMILY))) include hal/armv8m/mcx/n94x/Makefile endif -OBJS += $(addprefix $(PREFIX_O)hal/armv8m/mcx/, _init.o interrupts.o) +OBJS += $(addprefix $(PREFIX_O)hal/armv8m/mcx/, _init.o) diff --git a/hal/armv8m/mcx/n94x/console.c b/hal/armv8m/mcx/n94x/console.c index 01aceaa5b..e752fbaa5 100644 --- a/hal/armv8m/mcx/n94x/console.c +++ b/hal/armv8m/mcx/n94x/console.c @@ -19,7 +19,6 @@ #include "hal/cpu.h" #include "hal/string.h" #include "hal/spinlock.h" -#include "hal/armv8m/armv8m.h" #include diff --git a/hal/armv8m/mcx/n94x/mcxn94x.c b/hal/armv8m/mcx/n94x/mcxn94x.c index 51630e802..7558172d2 100644 --- a/hal/armv8m/mcx/n94x/mcxn94x.c +++ b/hal/armv8m/mcx/n94x/mcxn94x.c @@ -15,8 +15,10 @@ #include "mcxn94x.h" +#include "hal/arm/nvic.h" +#include "hal/arm/scb.h" + #include "hal/cpu.h" -#include "hal/armv8m/armv8m.h" #include "include/errno.h" @@ -141,7 +143,6 @@ enum { static struct { - volatile u32 *scb; volatile u32 *syscon; volatile u32 *port[6]; volatile u32 *inputmux; @@ -549,7 +550,7 @@ int hal_platformctl(void *ptr) case pctl_reboot: if (data->action == pctl_set) { if (data->reboot.magic == PCTL_REBOOT_MAGIC) { - _interrupts_nvicSystemReset(); + _hal_scbSystemReset(); } } else { @@ -613,43 +614,8 @@ void _hal_platformInit(void) } -/* SCB */ - - -void _mcxn94x_scbSetPriorityGrouping(u32 group) -{ - u32 t; - - /* Get register value and clear bits to set */ - t = *(n94x_common.scb + scb_aircr) & ~0xffff0700; - - /* Set AIRCR.PRIGROUP to 3: 16 priority groups and 16 subgroups - The value is same as for armv7m4-stm32l4x6 target - Setting various priorities is not supported on Phoenix-RTOS, so it's just default value */ - *(n94x_common.scb + scb_aircr) = t | 0x5fa0000 | ((group & 7) << 8); -} - - -void _mcxn94x_scbSetPriority(s8 excpn, u32 priority) -{ - volatile u8 *ptr; - - ptr = &((u8 *)(n94x_common.scb + scb_shp1))[excpn - 4]; - - /* We set only group priority field */ - *ptr = (priority << 4) & 0xff; -} - - -unsigned int _mcxn94x_cpuid(void) -{ - return *(n94x_common.scb + scb_cpuid); -} - - void _mcxn94x_init(void) { - n94x_common.scb = (void *)0xe000e000; n94x_common.syscon = (void *)0x40000000; n94x_common.port[0] = (void *)0x40116000; n94x_common.port[1] = (void *)0x40117000; @@ -659,5 +625,8 @@ void _mcxn94x_init(void) n94x_common.port[5] = (void *)0x40042000; n94x_common.inputmux = (void *)0x40006000; + _hal_scbInit(); + _hal_nvicInit(); + /* resetFlags TODO */ } diff --git a/hal/armv8m/mcx/n94x/mcxn94x.h b/hal/armv8m/mcx/n94x/mcxn94x.h index 8832f5a0e..1a5a72faf 100644 --- a/hal/armv8m/mcx/n94x/mcxn94x.h +++ b/hal/armv8m/mcx/n94x/mcxn94x.h @@ -22,14 +22,6 @@ #include "include/arch/armv8m/mcx/n94x/mcxn94x.h" -/* clang-format off */ -enum { - scb_actlr = 2, scb_cpuid = 832, scb_icsr, scb_vtor, scb_aircr, scb_scr, scb_ccr, scb_shp1, scb_shp2, - scb_shp3, scb_shcsr, scb_cfsr, scb_mmsr, scb_bfsr, scb_ufsr, scb_hfsr, scb_mmar, scb_bfar, scb_afsr -}; -/* clang-format on */ - - extern int _mcxn94x_portPinConfig(int pin, int mux, int options); diff --git a/hal/armv8m/mcx/n94x/timer.c b/hal/armv8m/mcx/n94x/timer.c index 86ca38484..54fdc7cca 100644 --- a/hal/armv8m/mcx/n94x/timer.c +++ b/hal/armv8m/mcx/n94x/timer.c @@ -14,7 +14,6 @@ */ #include "config.h" -#include "hal/armv8m/armv8m.h" #include "hal/timer.h" #include "hal/interrupts.h" #include "hal/spinlock.h" @@ -120,7 +119,7 @@ void hal_timerSetWakeup(u32 waitUs) ((*(timer_common.base + ostimer_oseventctrl) & 1) == 0)) { /* We just missed the timer value and be the interrupt won't * be generated. Trigger the interrupt manually instead. */ - _interrupts_nvicSetPending(ostimer0_irq - 0x10); + _hal_nvicSetPending(ostimer0_irq - 0x10); } hal_spinlockClear(&timer_common.lock, &sc); diff --git a/hal/armv8m/nrf/91/console.c b/hal/armv8m/nrf/91/console.c index 07b6f5534..821e36ca7 100644 --- a/hal/armv8m/nrf/91/console.c +++ b/hal/armv8m/nrf/91/console.c @@ -19,7 +19,6 @@ #include "hal/cpu.h" #include "hal/string.h" #include "hal/spinlock.h" -#include "hal/armv8m/armv8m.h" #include #define TX_DMA_SIZE 64 @@ -44,11 +43,11 @@ static struct { /* clang-format off */ -enum { uarte_startrx = 0, uarte_stoprx, uarte_starttx, uarte_stoptx, - uarte_events_cts = 64, uarte_events_txdrdy = 71, uarte_events_endtx, uarte_events_error, uarte_events_txstarted = 84, - uarte_inten = 192, uarte_errorsrc = 288, uarte_intenset, uarte_intenclr, uarte_enable = 320, - uarte_psel_rts = 322, uarte_psel_txd, uarte_psel_cts, uarte_psel_rxd, uarte_baudrate = 329, - uarte_rxd_ptr = 333, uarte_rxd_maxcnt, uarte_rxd_amount, uarte_txd_ptr = 337, uarte_txd_maxcnt, uarte_txd_amount, +enum { uarte_startrx = 0, uarte_stoprx, uarte_starttx, uarte_stoptx, + uarte_events_cts = 64, uarte_events_txdrdy = 71, uarte_events_endtx, uarte_events_error, uarte_events_txstarted = 84, + uarte_inten = 192, uarte_errorsrc = 288, uarte_intenset, uarte_intenclr, uarte_enable = 320, + uarte_psel_rts = 322, uarte_psel_txd, uarte_psel_cts, uarte_psel_rxd, uarte_baudrate = 329, + uarte_rxd_ptr = 333, uarte_rxd_maxcnt, uarte_rxd_amount, uarte_txd_ptr = 337, uarte_txd_maxcnt, uarte_txd_amount, uarte_config = 347 }; /* clang-format on */ diff --git a/hal/armv8m/nrf/91/nrf91.c b/hal/armv8m/nrf/91/nrf91.c index 99b388919..44f748f22 100644 --- a/hal/armv8m/nrf/91/nrf91.c +++ b/hal/armv8m/nrf/91/nrf91.c @@ -15,8 +15,10 @@ #include "nrf91.h" +#include "hal/arm/nvic.h" +#include "hal/arm/scb.h" + #include "hal/cpu.h" -#include "hal/armv8m/armv8m.h" #include "include/errno.h" @@ -157,62 +159,8 @@ int _nrf91_gpioSet(u8 pin, u8 val) } -/* SCB */ - - -void _nrf91_scbSetPriorityGrouping(u32 group) -{ - u32 t; - - /* Get register value and clear bits to set */ - t = *(nrf91_common.scb + scb_aircr) & ~0xffff0700; - - /* Set AIRCR.PRIGROUP to 3: 16 priority groups and 16 subgroups - The value is same as for armv7m4-stm32l4x6 target - Setting various priorities is not supported on Phoenix-RTOS, so it's just default value */ - *(nrf91_common.scb + scb_aircr) = t | 0x5fa0000 | ((group & 7) << 8); -} - - -u32 _nrf91_scbGetPriorityGrouping(void) -{ - return (*(nrf91_common.scb + scb_aircr) & 0x700) >> 8; -} - - -void _nrf91_scbSetPriority(s8 excpn, u32 priority) -{ - volatile u8 *ptr; - - ptr = &((u8 *)(nrf91_common.scb + scb_shp1))[excpn - 4]; - - /* We set only group priority field */ - *ptr = (priority << 4) & 0xff; -} - - -u32 _nrf91_scbGetPriority(s8 excpn) -{ - volatile u8 *ptr; - - ptr = &((u8 *)(nrf91_common.scb + scb_shp1))[excpn - 4]; - - return *ptr >> 4; -} - - -/* CPU info */ - - -unsigned int _nrf91_cpuid(void) -{ - return *(nrf91_common.scb + scb_cpuid); -} - - void _nrf91_init(void) { - nrf91_common.scb = (void *)0xe000e000; nrf91_common.power = (void *)0x50005000; nrf91_common.clock = (void *)0x50005000; nrf91_common.gpio = (void *)0x50842500; @@ -220,6 +168,8 @@ void _nrf91_init(void) nrf91_common.resetFlags = *(nrf91_common.power + power_resetreas); *(nrf91_common.power + power_resetreas) = 0x70017; + _hal_scbInit(); + _hal_nvicInit(); /* Based on nRF9160 product specification there is fixed cpu frequency */ nrf91_common.cpuclk = 64 * 1000 * 1000; @@ -243,10 +193,6 @@ void _nrf91_init(void) *(nrf91_common.clock + clock_hfclkrun) = 0u; hal_cpuDataMemoryBarrier(); - /* Enable UsageFault, BusFault and MemManage exceptions */ - *(nrf91_common.scb + scb_shcsr) |= (1u << 16) | (1u << 17) | (1u << 18); - /* Disable FPU */ - *(nrf91_common.scb + fpu_cpacr) = 0u; - *(nrf91_common.scb + fpu_fpccr) = 0u; + _hal_scbSetFPU(0); } diff --git a/hal/armv8m/nrf/91/timer.c b/hal/armv8m/nrf/91/timer.c index 596cb2c40..537735f44 100644 --- a/hal/armv8m/nrf/91/timer.c +++ b/hal/armv8m/nrf/91/timer.c @@ -14,7 +14,6 @@ */ #include "config.h" -#include "hal/armv8m/armv8m.h" #include "hal/timer.h" #include "hal/interrupts.h" #include "hal/spinlock.h" diff --git a/hal/armv8m/nrf/Makefile b/hal/armv8m/nrf/Makefile index 4cfebc8bf..e12f0e689 100644 --- a/hal/armv8m/nrf/Makefile +++ b/hal/armv8m/nrf/Makefile @@ -9,4 +9,4 @@ ifneq (, $(findstring nrf91, $(TARGET_SUBFAMILY))) include hal/armv8m/nrf/91/Makefile endif -OBJS += $(addprefix $(PREFIX_O)hal/armv8m/nrf/, _init.o interrupts.o) +OBJS += $(addprefix $(PREFIX_O)hal/armv8m/nrf/, _init.o) diff --git a/hal/armv8m/nrf/interrupts.c b/hal/armv8m/nrf/interrupts.c deleted file mode 100644 index 591913894..000000000 --- a/hal/armv8m/nrf/interrupts.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Phoenix-RTOS - * - * Operating system kernel - * - * Interrupt handling - * - * Copyright 2017, 2020, 2022 Phoenix Systems - * Author: Pawel Pisarczyk, Hubert Buczynski, Damian Loewnau - * - * This file is part of Phoenix-RTOS. - * - * %LICENSE% - */ - -#include "hal/interrupts.h" -#include "hal/spinlock.h" -#include "hal/cpu.h" -#include "hal/list.h" -#include "hal/armv8m/armv8m.h" -#include "hal/armv8m/nrf/91/nrf91.h" - -#include "proc/userintr.h" - -#include "config.h" - -static struct { - volatile u32 *nvic; - volatile u32 *scb; - spinlock_t spinlock; - intr_handler_t *handlers[SIZE_INTERRUPTS]; - unsigned int counters[SIZE_INTERRUPTS]; -} interrupts; - - -/* clang-format off */ -enum { nvic_iser = 0, nvic_icer = 32, nvic_ispr = 64, nvic_icpr = 96, nvic_iabr = 128, - nvic_ip = 192 }; -/* clang-format on */ - - -extern int threads_schedule(unsigned int n, cpu_context_t *context, void *arg); - - -void _interrupts_nvicSetIRQ(s8 irqn, u8 state) -{ - volatile u32 *ptr = interrupts.nvic + ((u8)irqn >> 5) + ((state != 0) ? nvic_iser : nvic_icer); - *ptr = 1u << (irqn & 0x1f); - - hal_cpuDataSyncBarrier(); - hal_cpuInstrBarrier(); -} - - -void _interrupts_nvicSetPriority(s8 irqn, u32 priority) -{ - volatile u32 *ptr; - - ptr = ((u32 *)(interrupts.nvic + nvic_ip)) + (irqn / 4); - - /* We set only group priority field */ - *ptr = (priority << (8 * (irqn % 4) + 4)); -} - - -void _interrupts_nvicSystemReset(void) -{ - *(interrupts.scb + scb_aircr) = ((0x5fau << 16) | (*(interrupts.scb + scb_aircr) & (0x700u)) | (1u << 2)); - - hal_cpuDataSyncBarrier(); - - for (;;) { - } -} - - -void interrupts_dispatch(unsigned int n, cpu_context_t *ctx) -{ - intr_handler_t *h; - int reschedule = 0; - spinlock_ctx_t sc; - - if (n >= SIZE_INTERRUPTS) { - return; - } - - hal_spinlockSet(&interrupts.spinlock, &sc); - - interrupts.counters[n]++; - - h = interrupts.handlers[n]; - if (h != NULL) { - do { - hal_cpuSetGot(h->got); - if (h->f(n, ctx, h->data) != 0) { - reschedule = 1; - } - h = h->next; - } while (h != interrupts.handlers[n]); - } - - hal_spinlockClear(&interrupts.spinlock, &sc); - - if (reschedule != 0) { - threads_schedule(n, ctx, NULL); - } -} - - -int hal_interruptsSetHandler(intr_handler_t *h) -{ - spinlock_ctx_t sc; - - if (h == NULL || h->f == NULL || h->n >= SIZE_INTERRUPTS) { - return -1; - } - - hal_spinlockSet(&interrupts.spinlock, &sc); - h->got = hal_cpuGetGot(); - - /* adding to interrupt handlers tree */ - HAL_LIST_ADD(&interrupts.handlers[h->n], h); - - if (h->n >= 0x10) { - _interrupts_nvicSetPriority(h->n - 0x10, 1); - _interrupts_nvicSetIRQ(h->n - 0x10, 1); - } - hal_spinlockClear(&interrupts.spinlock, &sc); - - return 0; -} - - -int hal_interruptsDeleteHandler(intr_handler_t *h) -{ - spinlock_ctx_t sc; - - if (h == NULL || h->f == NULL || h->n >= SIZE_INTERRUPTS) { - return -1; - } - - hal_spinlockSet(&interrupts.spinlock, &sc); - HAL_LIST_REMOVE(&interrupts.handlers[h->n], h); - - if (h->n >= 0x10 && interrupts.handlers[h->n] == NULL) { - _interrupts_nvicSetIRQ(h->n - 0x10, 0); - } - - hal_spinlockClear(&interrupts.spinlock, &sc); - - return 0; -} - - -char *hal_interruptsFeatures(char *features, unsigned int len) -{ - hal_strncpy(features, "Using NVIC interrupt controller", len); - features[len - 1] = 0; - - return features; -} - - -__attribute__((section(".init"))) void _hal_interruptsInit(void) -{ - unsigned int n; - - for (n = 0; n < SIZE_INTERRUPTS; ++n) { - interrupts.handlers[n] = NULL; - interrupts.counters[n] = 0; - } - - interrupts.nvic = (void *)0xe000e100; - interrupts.scb = (void *)0xe000e000; - - hal_spinlockCreate(&interrupts.spinlock, "interrupts.spinlock"); - - _nrf91_scbSetPriority(SYSTICK_IRQ, 1); - _nrf91_scbSetPriority(PENDSV_IRQ, 1); - _nrf91_scbSetPriority(SVC_IRQ, 0); - - /* Set no subprorities in Interrupt Group Priority */ - _nrf91_scbSetPriorityGrouping(3); - - return; -}