-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cortex-M: NVIC and SCB code duplication cleanup
JIRA: RTOS-886
- Loading branch information
1 parent
fa2cb46
commit ef753d4
Showing
42 changed files
with
509 additions
and
1,214 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* 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 <arch/cpu.h> | ||
#include "nvic.h" | ||
|
||
|
||
static struct { | ||
volatile u32 *nvic; | ||
} nvic_common; | ||
|
||
|
||
/* 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 */ | ||
|
||
|
||
void _hal_nvicSetIRQ(s8 irqn, u8 state) | ||
{ | ||
volatile u32 *ptr = nvic_common.nvic + ((u8)irqn >> 5) + ((state != 0) ? nvic_iser : nvic_icer); | ||
*ptr = 1u << (irqn & 0x1f); | ||
|
||
hal_cpuDataSyncBarrier(); | ||
hal_cpuInstrBarrier(); | ||
} | ||
|
||
|
||
void _hal_nvicSetPriority(s8 irqn, u32 priority) | ||
{ | ||
volatile u32 *ptr; | ||
|
||
ptr = ((u32 *)(nvic_common.nvic + nvic_ip)) + (irqn / 4); | ||
|
||
/* We set only group priority field */ | ||
*ptr = (priority << (8 * (irqn % 4) + 4)); | ||
} | ||
|
||
|
||
void _hal_nvicSetPending(s8 irqn) | ||
{ | ||
volatile u32 *ptr = nvic_common.nvic + ((u8)irqn >> 5) + nvic_ispr; | ||
|
||
*ptr = 1u << (irqn & 0x1f); | ||
|
||
hal_cpuDataSyncBarrier(); | ||
} | ||
|
||
|
||
void _hal_nvicInit(void) | ||
{ | ||
nvic_common.nvic = (void *)0xe000e100; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,244 @@ | ||
/* | ||
* 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 <arch/cpu.h> | ||
#include "scb.h" | ||
|
||
|
||
static struct { | ||
volatile u32 *scb; | ||
volatile u32 *systick; | ||
} scb_common; | ||
|
||
|
||
/* clang-format off */ | ||
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, /* 12 reserved */ scb_fpccr = 141, /* 2 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 { syst_csr = 4, syst_rvr, syst_cvr, syst_calib }; | ||
/* clang-format on */ | ||
|
||
|
||
void _hal_scbSetPriorityGrouping(u32 group) | ||
{ | ||
u32 t; | ||
|
||
/* Get register value and clear bits to set */ | ||
t = *(scb_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 */ | ||
*(scb_common.scb + scb_aircr) = t | 0x5fa0000 | ((group & 7) << 8); | ||
} | ||
|
||
|
||
void _hal_scbSetPriority(s8 excpn, u32 priority) | ||
{ | ||
volatile u8 *ptr; | ||
|
||
ptr = &((u8 *)(scb_common.scb + scb_shp1))[excpn - 4]; | ||
|
||
/* We set only group priority field */ | ||
*ptr = (priority << 4) & 0xff; | ||
} | ||
|
||
|
||
void _hal_scbSystemReset(void) | ||
{ | ||
*(scb_common.scb + scb_aircr) = ((0x5fau << 16) | (*(scb_common.scb + scb_aircr) & (0x700u)) | (1u << 2)); | ||
|
||
hal_cpuDataSyncBarrier(); | ||
|
||
for (;;) { | ||
hal_cpuHalt(); | ||
} | ||
} | ||
|
||
|
||
unsigned int _hal_scbCpuid(void) | ||
{ | ||
return *(scb_common.scb + scb_cpuid); | ||
} | ||
|
||
|
||
void _hal_scbSetFPU(int state) | ||
{ | ||
if (state != 0) { | ||
*(scb_common.scb + scb_cpacr) |= 0xf << 20; | ||
|
||
/* Enable FPU ctx */ | ||
/* TODO remove this and make sure correct control | ||
* is set after that (first process) */ | ||
__asm__ volatile ( | ||
"mrs r0, control\n\t" | ||
"orr r0, r0, #(1 << 2)\n\t" | ||
"msr control, r0\n\t" | ||
"isb" | ||
); | ||
} | ||
else { | ||
*(scb_common.scb + scb_cpacr) = 0; | ||
*(scb_common.scb + scb_fpccr) = 0; | ||
} | ||
hal_cpuDataSyncBarrier(); | ||
} | ||
|
||
|
||
void _hal_scbEnableDCache(void) | ||
{ | ||
u32 ccsidr, sets, ways; | ||
|
||
if ((*(scb_common.scb + scb_ccr) & (1 << 16)) == 0) { | ||
*(scb_common.scb + scb_csselr) = 0; | ||
hal_cpuDataSyncBarrier(); | ||
|
||
ccsidr = *(scb_common.scb + scb_ccsidr); | ||
|
||
/* Invalidate D$ */ | ||
sets = (ccsidr >> 13) & 0x7fff; | ||
do { | ||
ways = (ccsidr >> 3) & 0x3ff; | ||
do { | ||
*(scb_common.scb + scb_dcisw) = ((sets & 0x1ff) << 5) | ((ways & 0x3) << 30); | ||
} while (ways-- != 0); | ||
} while (sets-- != 0); | ||
hal_cpuDataSyncBarrier(); | ||
|
||
*(scb_common.scb + scb_ccr) |= 1 << 16; | ||
|
||
hal_cpuDataSyncBarrier(); | ||
hal_cpuInstrBarrier(); | ||
} | ||
} | ||
|
||
|
||
void _hal_scbDisableDCache(void) | ||
{ | ||
register u32 ccsidr, sets, ways; | ||
|
||
*(scb_common.scb + scb_csselr) = 0; | ||
hal_cpuDataSyncBarrier(); | ||
|
||
*(scb_common.scb + scb_ccr) &= ~(1 << 16); | ||
hal_cpuDataSyncBarrier(); | ||
|
||
ccsidr = *(scb_common.scb + scb_ccsidr); | ||
|
||
sets = (ccsidr >> 13) & 0x7fff; | ||
do { | ||
ways = (ccsidr >> 3) & 0x3ff; | ||
do { | ||
*(scb_common.scb + 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 (sz == 0u) { | ||
return; | ||
} | ||
|
||
daddr = (((u32)addr) & ~0x1fu); | ||
dsize = sz + ((u32)addr & 0x1fu); | ||
|
||
hal_cpuDataSyncBarrier(); | ||
|
||
do { | ||
*(scb_common.scb + scb_dccimvac) = daddr; | ||
daddr += 0x20u; | ||
dsize -= 0x20; | ||
} while (dsize > 0); | ||
|
||
hal_cpuDataSyncBarrier(); | ||
hal_cpuInstrBarrier(); | ||
} | ||
|
||
|
||
void _hal_scbEnableICache(void) | ||
{ | ||
if ((*(scb_common.scb + scb_ccr) & (1 << 17)) == 0) { | ||
hal_cpuDataSyncBarrier(); | ||
hal_cpuInstrBarrier(); | ||
*(scb_common.scb + scb_iciallu) = 0; /* Invalidate I$ */ | ||
hal_cpuDataSyncBarrier(); | ||
hal_cpuInstrBarrier(); | ||
*(scb_common.scb + scb_ccr) |= 1 << 17; | ||
hal_cpuDataSyncBarrier(); | ||
hal_cpuInstrBarrier(); | ||
} | ||
} | ||
|
||
|
||
void _hal_scbDisableICache(void) | ||
{ | ||
hal_cpuDataSyncBarrier(); | ||
hal_cpuInstrBarrier(); | ||
*(scb_common.scb + scb_ccr) &= ~(1 << 17); | ||
*(scb_common.scb + scb_iciallu) = 0; | ||
hal_cpuDataSyncBarrier(); | ||
hal_cpuInstrBarrier(); | ||
} | ||
|
||
|
||
void _hal_scbSetDeepSleep(int state) | ||
{ | ||
if (state != 0) { | ||
*(scb_common.scb + scb_scr) &= ~(1 << 2); | ||
*(scb_common.systick + syst_csr) &= ~1; | ||
} | ||
else { | ||
*(scb_common.scb + scb_scr) |= 1 << 2; | ||
*(scb_common.systick + syst_csr) |= 1; | ||
} | ||
} | ||
|
||
|
||
void _hal_scbSystickInit(u32 load) | ||
{ | ||
*(scb_common.systick + syst_rvr) = (u32)load; | ||
*(scb_common.systick + syst_cvr) = 0; | ||
|
||
/* Enable systick */ | ||
*(scb_common.systick + syst_csr) |= 0x7; | ||
} | ||
|
||
|
||
void _hal_scbInit(void) | ||
{ | ||
scb_common.scb = (void *)0xe000ed00; | ||
scb_common.systick = (void *)0xe000e000; | ||
|
||
/* Enable UsageFault, BusFault and MemManage exceptions */ | ||
*(scb_common.scb + scb_shcsr) |= (1u << 16) | (1u << 17) | (1u << 18); | ||
} |
Oops, something went wrong.