summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@chromium.org>2021-11-08 17:58:45 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-10 23:33:06 +0000
commitd1e69bd30f451e15816a7d031776589df6c771cf (patch)
tree6456fd05e8432512e056781795d7c4a60a1d8106
parentc80689153e8833d036cd7e86f71b01ce1e7ace5b (diff)
downloadchrome-ec-stabilize-14345.B-cr50_stab.tar.gz
BUG=b:200823466 TEST=make buildall -j Change-Id: I32b77ab6a5f63c6313a65cf28bb69fa88cec122e Signed-off-by: Mary Ruthven <mruthven@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3273185 Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org>
-rw-r--r--core/cortex-m/build.mk1
-rw-r--r--core/cortex-m/include/mpu.h122
-rw-r--r--core/cortex-m/mpu.c266
3 files changed, 0 insertions, 389 deletions
diff --git a/core/cortex-m/build.mk b/core/cortex-m/build.mk
index 1066f71137..2d78a9dc46 100644
--- a/core/cortex-m/build.mk
+++ b/core/cortex-m/build.mk
@@ -41,4 +41,3 @@ core-$(CONFIG_ARMV7M_CACHE)+=cache.o
core-$(CONFIG_COMMON_PANIC_OUTPUT)+=panic.o
core-$(CONFIG_COMMON_RUNTIME)+=switch.o task.o
core-$(CONFIG_WATCHDOG)+=watchdog.o
-core-$(CONFIG_MPU)+=mpu.o
diff --git a/core/cortex-m/include/mpu.h b/core/cortex-m/include/mpu.h
deleted file mode 100644
index 62e9b8bbec..0000000000
--- a/core/cortex-m/include/mpu.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Copyright 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* MPU module for Cortex-M3 */
-
-#ifndef __CROS_EC_MPU_H
-#define __CROS_EC_MPU_H
-
-#include "common.h"
-#include "config.h" /* chips might override MPU attribute settings */
-
-/*
- * Region assignment. 7 as the highest, a higher index has a higher priority.
- * For example, using 7 for .iram.text allows us to mark entire RAM XN except
- * .iram.text, which is used for hibernation.
- * Region assignment is currently wasteful and can be changed if more
- * regions are needed in the future. For example, a second region may not
- * be necessary for all types, and REGION_CODE_RAM / REGION_STORAGE can be
- * made mutually exclusive.
- */
-enum mpu_region {
- REGION_DATA_RAM = 0, /* For internal data RAM */
- REGION_DATA_RAM2 = 1, /* Second region for unaligned size */
- REGION_CODE_RAM = 2, /* For internal code RAM */
- REGION_CODE_RAM2 = 3, /* Second region for unaligned size */
- REGION_STORAGE = 4, /* For mapped internal storage */
- REGION_STORAGE2 = 5, /* Second region for unaligned size */
- REGION_DATA_RAM_TEXT = 6, /* Exempt region of data RAM */
- REGION_CHIP_RESERVED = 7, /* Reserved for use in chip/ */
- /* only for chips with MPU supporting 16 regions */
- REGION_UNCACHED_RAM = 8, /* For uncached data RAM */
- REGION_UNCACHED_RAM2 = 9, /* Second region for unaligned size */
- REGION_ROLLBACK = 10, /* For rollback */
-};
-
-#define MPU_TYPE REG32(0xe000ed90)
-#define MPU_CTRL REG32(0xe000ed94)
-#define MPU_NUMBER REG32(0xe000ed98)
-#define MPU_BASE REG32(0xe000ed9c)
-#define MPU_SIZE REG16(0xe000eda0)
-#define MPU_ATTR REG16(0xe000eda2)
-
-#define MPU_TYPE_UNIFIED_MASK 0x00FF0001
-#define MPU_TYPE_REG_COUNT(t) (((t) >> 8) & 0xFF)
-
-#define MPU_CTRL_PRIVDEFEN BIT(2)
-#define MPU_CTRL_HFNMIENA BIT(1)
-#define MPU_CTRL_ENABLE BIT(0)
-
-/*
- * XN (execute never) bit. It's bit 12 if accessed by halfword.
- * 0: XN off
- * 1: XN on
- */
-#define MPU_ATTR_XN BIT(12)
-
-/* AP bit. See table 3-5 of Stellaris LM4F232H5QC datasheet for details */
-#define MPU_ATTR_NO_NO (0 << 8) /* previleged no access, unprev no access */
-#define MPU_ATTR_RW_NO (1 << 8) /* previleged ReadWrite, unprev no access */
-#define MPU_ATTR_RW_RO (2 << 8) /* previleged ReadWrite, unprev Read-only */
-#define MPU_ATTR_RW_RW (3 << 8) /* previleged ReadWrite, unprev ReadWrite */
-#define MPU_ATTR_RO_NO (5 << 8) /* previleged Read-only, unprev no access */
-
-/* Suggested value for TEX S/C/B bit. See table 3-6 of Stellaris LM4F232H5QC
- * datasheet and table 38 of STM32F10xxx Cortex-M3 programming manual. */
-#ifndef MPU_ATTR_INTERNAL_SRAM
-#define MPU_ATTR_INTERNAL_SRAM 6 /* for Internal SRAM */
-#endif
-#ifndef MPU_ATTR_FLASH_MEMORY
-#define MPU_ATTR_FLASH_MEMORY 2 /* for flash memory */
-#endif
-
-/**
- * Enable MPU
- */
-void mpu_enable(void);
-
-/**
- * Returns the value of MPU type register
- *
- * Bit fields:
- * [15:8] Number of the data regions implemented or 0 if MPU is not present.
- * [1] 0: unified (no distinction between instruction and data)
- * 1: separated
- */
-uint32_t mpu_get_type(void);
-
-/* Location of iram.text */
-extern char __iram_text_start;
-extern char __iram_text_end;
-
-/**
- * Protect RAM from code execution
- */
-int mpu_protect_data_ram(void);
-
-/**
- * Protect code RAM from being overwritten
- */
-int mpu_protect_code_ram(void);
-
-/**
- * Protect internal mapped flash memory from code execution
- */
-int mpu_lock_ro_flash(void);
-int mpu_lock_rw_flash(void);
-
-/**
- * Protect/unprotect rollback region readback.
- */
-int mpu_lock_rollback(int lock);
-
-/**
- * Initialize MPU.
- * It disables all regions if MPU is implemented. Otherwise, returns
- * EC_ERROR_UNIMPLEMENTED.
- */
-int mpu_pre_init(void);
-
-#endif /* __CROS_EC_MPU_H */
diff --git a/core/cortex-m/mpu.c b/core/cortex-m/mpu.c
deleted file mode 100644
index fa6efb5951..0000000000
--- a/core/cortex-m/mpu.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/* Copyright 2013 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* MPU module for Chrome EC */
-
-#include "mpu.h"
-#include "console.h"
-#include "cpu.h"
-#include "registers.h"
-#include "task.h"
-#include "util.h"
-
-/**
- * Update a memory region.
- *
- * region: index of the region to update
- * addr: base address of the region
- * size_bit: size of the region in power of two.
- * attr: attribute bits. Current value will be overwritten if enable is true.
- * enable: enables the region if non zero. Otherwise, disables the region.
- * srd: subregion mask to partition region into 1/8ths, 0 = subregion enabled.
- *
- * Based on 3.1.4.1 'Updating an MPU Region' of Stellaris LM4F232H5QC Datasheet
- */
-static void mpu_update_region(uint8_t region, uint32_t addr, uint8_t size_bit,
- uint16_t attr, uint8_t enable, uint8_t srd)
-{
- asm volatile("isb; dsb;");
-
- MPU_NUMBER = region;
- MPU_SIZE &= ~1; /* Disable */
- if (enable) {
- MPU_BASE = addr;
- /*
- * MPU_ATTR = attr;
- * MPU_SIZE = (srd << 8) | ((size_bit - 1) << 1) | 1;
- *
- * WORKAROUND: the 2 half-word accesses above should work
- * according to the doc, but they don't ..., do a single 32-bit
- * one.
- */
- REG32(&MPU_SIZE) = ((uint32_t)attr << 16)
- | (srd << 8) | ((size_bit - 1) << 1) | 1;
- }
-
- asm volatile("isb; dsb;");
-}
-
-/**
- * Configure a region
- *
- * region: index of the region to update
- * addr: Base address of the region
- * size: Size of the region in bytes
- * attr: Attribute bits. Current value will be overwritten if enable is set.
- * enable: Enables the region if non zero. Otherwise, disables the region.
- *
- * Returns EC_SUCCESS on success or -EC_ERROR_INVAL if a parameter is invalid.
- */
-static int mpu_config_region(uint8_t region, uint32_t addr, uint32_t size,
- uint16_t attr, uint8_t enable)
-{
- int size_bit = 0;
- uint8_t blocks, srd1, srd2;
-
- if (!size)
- return EC_SUCCESS;
-
- /* Bit position of first '1' in size */
- size_bit = 31 - __builtin_clz(size);
- /* Min. region size is 32 bytes */
- if (size_bit < 5)
- return -EC_ERROR_INVAL;
-
- /* If size is a power of 2 then represent it with a single MPU region */
- if (POWER_OF_TWO(size)) {
- mpu_update_region(region, addr, size_bit, attr, enable, 0);
- return EC_SUCCESS;
- }
-
- /* Sub-regions are not supported for region <= 128 bytes */
- if (size_bit < 7)
- return -EC_ERROR_INVAL;
- /* Verify we can represent range with <= 2 regions */
- if (size & ~(0x3f << (size_bit - 5)))
- return -EC_ERROR_INVAL;
-
- /*
- * Round up size of first region to power of 2.
- * Calculate the number of fully occupied blocks (block size =
- * region size / 8) in the first region.
- */
- blocks = size >> (size_bit - 2);
-
- /* Represent occupied blocks of two regions with srd mask. */
- srd1 = BIT(blocks) - 1;
- srd2 = (1 << ((size >> (size_bit - 5)) & 0x7)) - 1;
-
- /*
- * Second region not supported for DATA_RAM_TEXT, also verify size of
- * second region is sufficient to support sub-regions.
- */
- if (srd2 && (region == REGION_DATA_RAM_TEXT || size_bit < 10))
- return -EC_ERROR_INVAL;
-
- /* Write first region. */
- mpu_update_region(region, addr, size_bit + 1, attr, enable, ~srd1);
-
- /*
- * Second protection region (if necessary) begins at the first block
- * we marked unoccupied in the first region.
- * Size of the second region is the block size of first region.
- */
- addr += (1 << (size_bit - 2)) * blocks;
-
- /*
- * Now represent occupied blocks in the second region. It's possible
- * that the first region completely represented the occupied area, if
- * so then no second protection region is required.
- */
- if (srd2)
- mpu_update_region(region + 1, addr, size_bit - 2, attr, enable,
- ~srd2);
-
- return EC_SUCCESS;
-}
-
-/**
- * Set a region executable and read-write.
- *
- * region: index of the region
- * addr: base address of the region
- * size: size of the region in bytes
- * texscb: TEX and SCB bit field
- */
-static int mpu_unlock_region(uint8_t region, uint32_t addr, uint32_t size,
- uint8_t texscb)
-{
- return mpu_config_region(region, addr, size,
- MPU_ATTR_RW_RW | texscb, 1);
-}
-
-void mpu_enable(void)
-{
- MPU_CTRL |= MPU_CTRL_PRIVDEFEN | MPU_CTRL_HFNMIENA | MPU_CTRL_ENABLE;
-}
-
-static void mpu_disable(void)
-{
- MPU_CTRL &= ~(MPU_CTRL_PRIVDEFEN | MPU_CTRL_HFNMIENA | MPU_CTRL_ENABLE);
-}
-
-uint32_t mpu_get_type(void)
-{
- return MPU_TYPE;
-}
-
-int mpu_protect_data_ram(void)
-{
- int ret;
-
- /* Prevent code execution from data RAM */
- ret = mpu_config_region(REGION_DATA_RAM,
- CONFIG_RAM_BASE,
- CONFIG_DATA_RAM_SIZE,
- MPU_ATTR_XN |
- MPU_ATTR_RW_RW |
- MPU_ATTR_INTERNAL_SRAM,
- 1);
- if (ret != EC_SUCCESS)
- return ret;
-
- /* Exempt the __iram_text section */
- return mpu_unlock_region(
- REGION_DATA_RAM_TEXT, (uint32_t)&__iram_text_start,
- (uint32_t)(&__iram_text_end - &__iram_text_start),
- MPU_ATTR_INTERNAL_SRAM);
-}
-
-#if defined(CONFIG_EXTERNAL_STORAGE) || !defined(CONFIG_FLASH_PHYSICAL)
-int mpu_protect_code_ram(void)
-{
- /* Prevent write access to code RAM */
- return mpu_config_region(REGION_STORAGE,
- CONFIG_PROGRAM_MEMORY_BASE + CONFIG_RO_MEM_OFF,
- CONFIG_CODE_RAM_SIZE,
- MPU_ATTR_RO_NO | MPU_ATTR_INTERNAL_SRAM,
- 1);
-}
-#else
-int mpu_lock_ro_flash(void)
-{
- /* Prevent execution from internal mapped RO flash */
- return mpu_config_region(REGION_STORAGE,
- CONFIG_MAPPED_STORAGE_BASE + CONFIG_RO_MEM_OFF,
- CONFIG_RO_SIZE,
- MPU_ATTR_XN | MPU_ATTR_RW_RW |
- MPU_ATTR_FLASH_MEMORY, 1);
-}
-
-int mpu_lock_rw_flash(void)
-{
- /* Prevent execution from internal mapped RW flash */
- return mpu_config_region(REGION_STORAGE,
- CONFIG_MAPPED_STORAGE_BASE + CONFIG_RW_MEM_OFF,
- CONFIG_RW_SIZE,
- MPU_ATTR_XN | MPU_ATTR_RW_RW |
- MPU_ATTR_FLASH_MEMORY, 1);
-}
-#endif /* !CONFIG_EXTERNAL_STORAGE */
-
-#ifdef CONFIG_ROLLBACK_MPU_PROTECT
-int mpu_lock_rollback(int lock)
-{
- return mpu_config_region(REGION_ROLLBACK,
- CONFIG_MAPPED_STORAGE_BASE + CONFIG_ROLLBACK_OFF,
- CONFIG_ROLLBACK_SIZE, MPU_ATTR_XN | MPU_ATTR_NO_NO,
- lock);
-}
-#endif
-
-#ifdef CONFIG_CHIP_UNCACHED_REGION
-/* Store temporarily the regions ranges to use them for the MPU configuration */
-#define REGION(_name, _flag, _start, _size) \
- static const uint32_t CONCAT2(_region_start_, _name) \
- __attribute__((unused, section(".unused"))) = _start; \
- static const uint32_t CONCAT2(_region_size_, _name) \
- __attribute__((unused, section(".unused"))) = _size;
-#include "memory_regions.inc"
-#undef REGION
-#endif /* CONFIG_CHIP_UNCACHED_REGION */
-
-int mpu_pre_init(void)
-{
- int i;
- uint32_t mpu_type = mpu_get_type();
-
- /* Supports MPU with 8 or 16 unified regions */
- if ((mpu_type & MPU_TYPE_UNIFIED_MASK) ||
- (MPU_TYPE_REG_COUNT(mpu_type) != 8 &&
- MPU_TYPE_REG_COUNT(mpu_type) != 16))
- return EC_ERROR_UNIMPLEMENTED;
-
- mpu_disable();
- for (i = 0; i < MPU_TYPE_REG_COUNT(mpu_type); ++i)
- mpu_config_region(i, CONFIG_RAM_BASE, CONFIG_RAM_SIZE, 0, 0);
-
-#ifdef CONFIG_ROLLBACK_MPU_PROTECT
- mpu_lock_rollback(1);
-#endif
-
-#ifdef CONFIG_ARMV7M_CACHE
-#ifdef CONFIG_CHIP_UNCACHED_REGION
- mpu_config_region(REGION_UNCACHED_RAM,
- CONCAT2(_region_start_, CONFIG_CHIP_UNCACHED_REGION),
- CONCAT2(_region_size_, CONFIG_CHIP_UNCACHED_REGION),
- MPU_ATTR_XN | MPU_ATTR_RW_RW, 1);
- mpu_enable();
-#endif /* CONFIG_CHIP_UNCACHED_REGION */
- cpu_enable_caches();
-#endif /* CONFIG_ARMV7M_CACHE */
-
- return EC_SUCCESS;
-}