diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2017-05-03 15:13:45 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2017-05-03 15:13:46 +0000 |
commit | b0a8cc4ed7a173314898fb75a286f3179b1a69e1 (patch) | |
tree | 948f07e5a12136390492873062470470155fdfe1 /firmware/os | |
parent | 57b9756da4a5953a3c0eaa9d41d9e0ebdd9b8084 (diff) | |
parent | 1870f0680a5388a729bb2e5c954c47abee468814 (diff) | |
download | contexthub-b0a8cc4ed7a173314898fb75a286f3179b1a69e1.tar.gz |
Merge "mpu: actually enable the mpu (for real this time)"android-wear-o-preview-4android-wear-o-preview-3android-o-preview-2
Diffstat (limited to 'firmware/os')
-rw-r--r-- | firmware/os/cpu/cortexm4/cpu.c | 35 | ||||
-rw-r--r-- | firmware/os/cpu/cortexm4/inc/cpu/cmsis.h | 3 | ||||
-rw-r--r-- | firmware/os/inc/mpu.h | 1 | ||||
-rw-r--r-- | firmware/os/platform/stm32/inc/plat/cmsis.h | 1 | ||||
-rw-r--r-- | firmware/os/platform/stm32/mpu.c | 166 |
5 files changed, 152 insertions, 54 deletions
diff --git a/firmware/os/cpu/cortexm4/cpu.c b/firmware/os/cpu/cortexm4/cpu.c index 51058106..927db359 100644 --- a/firmware/os/cpu/cortexm4/cpu.c +++ b/firmware/os/cpu/cortexm4/cpu.c @@ -32,14 +32,23 @@ #define HARD_FAULT_DROPBOX_MAGIC_HAVE_DROP 0x00002000 #define HARD_FAULT_DROPBOX_MAGIC_DATA_MASK 0x00001FFF +union TidTrig { + struct { + uint32_t tid : 16; + uint32_t trig : 2; + uint32_t RFU : 14; + }; + uint32_t rw; +}; + +// These registers only support word accesses (r/w) +// Make sure to only use uint32_t's struct RamPersistedDataAndDropbox { uint32_t magic; // and part of dropbox uint32_t r[16]; uint32_t sr_hfsr_cfsr_lo; uint32_t bits; - uint16_t tid; - uint16_t trig:2; - uint16_t RFU:14; + union TidTrig tid_trig; // only access via tid_trig.rw }; /* //if your device persists ram, you can use this instead: @@ -106,9 +115,10 @@ static void cpuUnpackSrBits(uint32_t srcLo, uint32_t srcHi, uint32_t *srP, uint3 static void cpuDbxDump(struct RamPersistedDataAndDropbox *dbx) { - uint32_t i, hfsr, cfsr, sr, code; + uint32_t i, hfsr, cfsr, sr; + union TidTrig tid_trig; const char *trigName; - static const char *trigNames[] = { "UNKNOWN", "HARD FAULT", "WDT" }; + static const char *trigNames[] = { "UNKNOWN", "HARD FAULT", "WDT", "MPU" }; if (dbx) { for (i = 0; i < 8; i++) @@ -120,12 +130,13 @@ static void cpuDbxDump(struct RamPersistedDataAndDropbox *dbx) osLog(LOG_ERROR, " xPSR = 0x%08lX HFSR = 0x%08lX\n", sr, hfsr); osLog(LOG_ERROR, " CFSR = 0x%08lX BITS = 0x%08lX\n", cfsr, dbx->bits); // reboot source (if known), reported as TRIG - // so far we have 2 reboot sources reported here: + // so far we have 3 reboot sources reported here: // 1 - HARD FAULT // 2 - WDT - code = dbx->trig; - trigName = trigNames[code < ARRAY_SIZE(trigNames) ? code : 0]; - osLog(LOG_ERROR, " TID = 0x%04" PRIX16 " TRIG = 0x%04" PRIX16 " [%s]\n", dbx->tid, dbx->trig, trigName); + // 3 - MPU + tid_trig.rw = dbx->tid_trig.rw; + trigName = trigNames[tid_trig.trig < ARRAY_SIZE(trigNames) ? tid_trig.trig : 0]; + osLog(LOG_ERROR, " TID = 0x%04" PRIX16 " TRIG = 0x%04" PRIX16 " [%s]\n\n", tid_trig.tid, tid_trig.trig, trigName); } } @@ -259,6 +270,7 @@ static void __attribute__((used)) logHardFault(uintptr_t *excRegs, uintptr_t* ot { struct RamPersistedDataAndDropbox *dbx = getInitedPersistedData(); uint32_t i, hi; + union TidTrig tid_trig; wdtPing(); @@ -273,8 +285,9 @@ static void __attribute__((used)) logHardFault(uintptr_t *excRegs, uintptr_t* ot cpuPackSrBits(&dbx->sr_hfsr_cfsr_lo, &hi, excRegs[7], SCB->HFSR, SCB->CFSR); dbx->magic |= HARD_FAULT_DROPBOX_MAGIC_HAVE_DROP | (hi & HARD_FAULT_DROPBOX_MAGIC_DATA_MASK); - dbx->tid = osGetCurrentTid(); - dbx->trig = code; + tid_trig.tid = osGetCurrentTid(); + tid_trig.trig = code; + dbx->tid_trig.rw = tid_trig.rw; if (!tinyStack) { osLog(LOG_ERROR, "*HARD FAULT*\n"); diff --git a/firmware/os/cpu/cortexm4/inc/cpu/cmsis.h b/firmware/os/cpu/cortexm4/inc/cpu/cmsis.h index d740542d..8cb6d370 100644 --- a/firmware/os/cpu/cortexm4/inc/cpu/cmsis.h +++ b/firmware/os/cpu/cortexm4/inc/cpu/cmsis.h @@ -22,9 +22,6 @@ extern "C" { #endif -#define __NVIC_PRIO_BITS 4 -#define __FPU_PRESENT 1 - #include <cpu/cmsis/core_cm4.h> #ifdef __cplusplus diff --git a/firmware/os/inc/mpu.h b/firmware/os/inc/mpu.h index 45bf7a9a..a331bdc1 100644 --- a/firmware/os/inc/mpu.h +++ b/firmware/os/inc/mpu.h @@ -32,6 +32,7 @@ extern "C" { void mpuStart(void); void mpuAllowRamExecution(bool allowSvcExecute); /* for Supervisor only, if possible */ void mpuAllowRomWrite(bool allowSvcWrite); /* for Supervisor only, if possible */ +void mpuShow(void); #ifdef __cplusplus diff --git a/firmware/os/platform/stm32/inc/plat/cmsis.h b/firmware/os/platform/stm32/inc/plat/cmsis.h index 8b79368d..53c7f2ba 100644 --- a/firmware/os/platform/stm32/inc/plat/cmsis.h +++ b/firmware/os/platform/stm32/inc/plat/cmsis.h @@ -24,6 +24,7 @@ extern "C" { #define __NVIC_PRIO_BITS 4 #define __FPU_PRESENT 1 +#define __MPU_PRESENT 1 diff --git a/firmware/os/platform/stm32/mpu.c b/firmware/os/platform/stm32/mpu.c index f45a1531..1a2f0a3a 100644 --- a/firmware/os/platform/stm32/mpu.c +++ b/firmware/os/platform/stm32/mpu.c @@ -22,64 +22,75 @@ #include <mpu.h> #include <platform.h> -struct CortexMpu { - volatile uint32_t CTRL; - volatile uint32_t RNR; - volatile uint32_t RBAR; - volatile uint32_t RASR; -}; +#include <plat/cmsis.h> -#define MPU ((struct CortexMpu*)0xE000ED94UL) - -#define MPU_REG_ROM 0 -#define MPU_REG_RAM 1 -#define MPU_REG_NULL_PAGE 2 +#define MPU_REG_DEFAULT 0 +#define MPU_REG_ROM 1 +#define MPU_REG_RAM 2 +#define MPU_REG_PERIPH 3 +#define MPU_REG_PRIV_PERIPH 4 +#define MPU_RASR_S 0x00040000 +#define MPU_RASR_C 0x00020000 +#define MPU_RASR_B 0x00010000 /* region type */ -#define MPU_TYPE_DEVICE (0x10UL << 16) -#define MPU_TYPE_MEMORY (0x0FUL << 16) +#define MPU_TYPE_SRAM (MPU_RASR_S | MPU_RASR_C) +#define MPU_TYPE_FLASH (MPU_RASR_C) +#define MPU_TYPE_PERIPH (MPU_RASR_S | MPU_RASR_B) /* region execute priviledges */ -#define MPU_BIT_XN (1UL << 28) /* no execute */ +#define MPU_BIT_XN (1UL << 28) /* no execute */ /* region access priviledges */ -#define MPU_NA (0UL << 24) /* S: no access U: no access */ -#define MPU_U_NA_S_RW (1UL << 24) /* S: RW U: no access */ -#define MPU_U_RO_S_RW (2UL << 24) /* S: RW U: RO */ -#define MPU_RW (3UL << 24) /* S: RW U: RW */ -#define MPU_U_NA_S_RO (5UL << 24) /* S: RO U: no access */ -#define MPU_U_RO_S_RO (6UL << 24) /* S: RO U: RO */ +#define MPU_NA (0UL << 24) /* S: no access U: no access */ +#define MPU_U_NA_S_RW (1UL << 24) /* S: RW U: no access */ +#define MPU_U_RO_S_RW (2UL << 24) /* S: RW U: RO */ +#define MPU_RW (3UL << 24) /* S: RW U: RW */ +#define MPU_U_NA_S_RO (5UL << 24) /* S: RO U: no access */ +#define MPU_U_RO_S_RO (6UL << 24) /* S: RO U: RO */ -/* subregion mask (not used so all ones) */ -#define MPU_SRD_BITS 0xFF00UL -#define MPU_BIT_ENABLE 1UL +/* subregion disable (not used so all zeroes) */ +#define MPU_SRD_BITS 0x0000UL +#define MPU_BIT_ENABLE 1UL /* these define rom */ extern uint8_t __shared_end[]; extern uint8_t __ram_start[]; extern uint8_t __ram_end[]; -static void mpuRegionCfg(uint32_t regionNo, uint32_t start, uint32_t len, uint32_t attrs) /* region will be rounded to acceptable boundaries (32B minimum, self-aligned) by GROWTH */ +void MemoryManagemntFault_Handler(void); +void __attribute__((naked)) MemoryManagemntFault_Handler(void) { - uint32_t proposedStart, proposedLen, lenVal = 1; - uint64_t intState; + asm volatile( + "mov r0, #3 \n" + "b cpuCommonFaultCode \n" + ); +} + +static bool mpuRegionCfg(uint32_t regionNo, uint32_t start, uint32_t end, uint32_t attrs) /* region will be rounded to acceptable boundaries (32B minimum, self-aligned) by GROWTH */ +{ + uint32_t proposedStart, lenVal = 1; + uint64_t len, proposedLen, intState; + + if (start > end) + return false; + else + len = end - start + UINT64_C(1); /* expand until it works */ do { - /* special case 4GB region */ - if (lenVal == 32) { - proposedStart = 0; - break; - } - - proposedStart = start &~ ((1ULL << lenVal) - 1); + proposedStart = start &~ ((UINT64_C(1) << lenVal) - 1); proposedLen = start + len - proposedStart; if (proposedLen < 32) proposedLen = 32; - lenVal = (proposedLen & (proposedLen - 1)) ? 32 - __builtin_clz(proposedLen) : 31 - __builtin_clz(proposedLen); + lenVal = (proposedLen & (proposedLen - UINT64_C(1))) ? 64 - __builtin_clzll(proposedLen) : 63 - __builtin_clzll(proposedLen); - } while (proposedStart & ((1ULL << lenVal) - 1)); + } while (proposedStart & ((UINT64_C(1) << lenVal) - UINT64_C(1))); + + /* minimum size: 32 bytes */ + if (lenVal < 5) + lenVal = 5; intState = cpuIntsOff(); asm volatile("dsb\nisb"); @@ -87,30 +98,44 @@ static void mpuRegionCfg(uint32_t regionNo, uint32_t start, uint32_t len, uint32 MPU->RNR = regionNo; MPU->RASR = 0; /* disable region before changing it */ MPU->RBAR = proposedStart; - MPU->RASR = MPU_SRD_BITS | MPU_BIT_ENABLE | attrs | (lenVal << 1); + MPU->RASR = MPU_SRD_BITS | MPU_BIT_ENABLE | attrs | ((lenVal-1) << 1); asm volatile("dsb\nisb"); cpuIntsRestore(intState); + + return true; } static void mpuCfgRom(bool allowSvcWrite) { - mpuRegionCfg(MPU_REG_ROM, (uint32_t)&BL, __shared_end - (uint8_t*)&BL, MPU_TYPE_MEMORY | (allowSvcWrite ? MPU_U_RO_S_RW : MPU_U_RO_S_RO)); + mpuRegionCfg(MPU_REG_ROM, (uint32_t)&BL, (uint32_t)&__shared_end - 1, MPU_TYPE_FLASH | (allowSvcWrite ? MPU_U_RO_S_RW : MPU_U_RO_S_RO)); } static void mpuCfgRam(bool allowSvcExecute) { - mpuRegionCfg(MPU_REG_RAM, (uint32_t)&__ram_start, __ram_end - __ram_start, MPU_TYPE_MEMORY | MPU_RW | (allowSvcExecute ? 0 : MPU_BIT_XN)); + mpuRegionCfg(MPU_REG_RAM, (uint32_t)&__ram_start, (uint32_t)&__ram_end - 1, MPU_TYPE_SRAM | MPU_RW | (allowSvcExecute ? 0 : MPU_BIT_XN)); } void mpuStart(void) { - MPU->CTRL = 0x07; //MPU on, even during faults, supervisor default: allow, user default: default deny + MPU->CTRL = 0x00; // disable MPU + + /* 0x00000000 - 0xFFFFFFFF */ + mpuRegionCfg(MPU_REG_DEFAULT, 0, 0xFFFFFFFF, MPU_NA | MPU_BIT_XN); mpuCfgRom(false); mpuCfgRam(false); - mpuRegionCfg(MPU_REG_NULL_PAGE, 0, 4096, MPU_TYPE_MEMORY | MPU_NA | MPU_BIT_XN); + + /* 0x40000000 - 0x4003FFFF */ + mpuRegionCfg(MPU_REG_PERIPH, 0x40000000, 0x4003FFFF, MPU_TYPE_PERIPH | MPU_U_NA_S_RW | MPU_BIT_XN); + + /* 0xE0000000 - 0xE00FFFFF */ + mpuRegionCfg(MPU_REG_PRIV_PERIPH, 0xE0000000, 0xE00FFFFF, MPU_TYPE_PERIPH | MPU_U_NA_S_RW | MPU_BIT_XN); + + //MPU on, even during faults, supervisor default: allow, user default: default deny + MPU->CTRL = MPU_CTRL_ENABLE_Msk | MPU_CTRL_HFNMIENA_Msk | MPU_CTRL_PRIVDEFENA_Msk; + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; } void mpuAllowRamExecution(bool allowSvcExecute) @@ -123,3 +148,64 @@ void mpuAllowRomWrite(bool allowSvcWrite) mpuCfgRom(allowSvcWrite); } +void mpuShow() +{ + int i, regions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos; + uint32_t addr, rasr; + uint8_t ap; + bool xn; + char *s, *u; + + osLog(LOG_INFO, "MPU: %d HFNMIENA: %d PRIVDEFENA: %d\n", + !!(MPU->CTRL & MPU_CTRL_ENABLE_Msk), + !!(MPU->CTRL & MPU_CTRL_HFNMIENA_Msk), + !!(MPU->CTRL & MPU_CTRL_PRIVDEFENA_Msk)); + for (i=0; i<regions; i++) { + MPU->RNR = i; + addr = MPU->RBAR & MPU_RBAR_ADDR_Msk; + rasr = MPU->RASR; + xn = rasr & MPU_RASR_XN_Msk; + ap = (rasr & MPU_RASR_AP_Msk) >> MPU_RASR_AP_Pos; + if (ap == 0) { + s = "---"; + } else if (ap == 1 || ap == 2 || ap == 3) { + if (xn) + s = "RW-"; + else + s = "RWX"; + } else if (ap == 5 || ap == 6 || ap == 7) { + if (xn) + s = "R--"; + else + s = "R-X"; + } else { + s = "???"; + } + if (ap == 0 || ap == 1 || ap == 5) { + u = "---"; + } else if (ap == 3) { + if (xn) + u = "RW-"; + else + u = "RWX"; + } else if (ap == 2 || ap == 6 || ap == 7) { + if (xn) + u = "R--"; + else + u = "R-X"; + } else { + u = "???"; + } + osLog(LOG_INFO, + "%d: %c %08lx-%08lx S: %s U: %s TEX: %ld %c%c%c %02lx\n", + i, (rasr & MPU_RASR_ENABLE_Msk) ? 'E' : 'D', + addr, + addr + (1 << (((rasr & MPU_RASR_SIZE_Msk) >> MPU_RASR_SIZE_Pos) + 1))-1, + s, u, + (rasr & MPU_RASR_TEX_Msk) >> MPU_RASR_TEX_Pos, + (rasr & MPU_RASR_S_Msk) ? 'S' : ' ', + (rasr & MPU_RASR_C_Msk) ? 'C' : ' ', + (rasr & MPU_RASR_B_Msk) ? 'B' : ' ', + (rasr & MPU_RASR_SRD_Msk) >> MPU_RASR_SRD_Pos); + } +} |