arch: arm: core: aarch32: introduce basic ARMv7 MMU support
An initial implementation for memory management using the ARMv7 MMU. A single L1 translation table for the whole 4 GB address space is al- ways present, a configurable number of L2 page tables are linked to the L1 table based on the static memory area configuration at boot time, or whenever arch_mem_map/arch_mem_unmap are called at run-time. Currently, a CPU with the Multiprocessor Extensions and execution at PL1 are always assumed. Userspace-related features or thread stack guard pages are not yet supported. Neither are LPAE, PXN or TEX re- mapping. All mappings are currently assigned to the same domain. Re- garding the permissions model, access permissions are specified using the AP[2:1] model rather than the older AP[2:0] model, which, accor- ding to ARM's documentation, is deprecated and should no longer be used. The newer model adds some complexity when it comes to mapping pages as unaccessible (the AP[2:1] model doesn't support explicit specification of "no R, no W" permissions, it's always at least "RO"), this is accomplished by invalidating the ID bits of the respective page's PTE. Includes sources, Kconfig integration, adjusted CMakeLists and the modified linker command file (proper section alignment!). Signed-off-by: Immo Birnbaum <Immo.Birnbaum@weidmueller.com>
This commit is contained in:
parent
eac90eeb52
commit
70c403c215
10 changed files with 1475 additions and 2 deletions
|
@ -71,6 +71,8 @@ extern "C" {
|
|||
*/
|
||||
#if defined(CONFIG_USERSPACE)
|
||||
#define Z_THREAD_MIN_STACK_ALIGN CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
|
||||
#elif defined(CONFIG_ARM_MMU)
|
||||
#define Z_THREAD_MIN_STACK_ALIGN CONFIG_ARM_MMU_REGION_MIN_ALIGN_AND_SIZE
|
||||
#else
|
||||
#define Z_THREAD_MIN_STACK_ALIGN ARCH_STACK_PTR_ALIGN
|
||||
#endif
|
||||
|
@ -190,6 +192,9 @@ extern "C" {
|
|||
#include <arch/arm/aarch32/mpu/nxp_mpu.h>
|
||||
#endif /* CONFIG_CPU_HAS_NXP_MPU */
|
||||
#endif /* CONFIG_ARM_MPU */
|
||||
#ifdef CONFIG_ARM_AARCH32_MMU
|
||||
#include <arch/arm/aarch32/mmu/arm_mmu.h>
|
||||
#endif /* CONFIG_ARM_AARCH32_MMU */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -58,6 +58,8 @@
|
|||
*/
|
||||
#if defined(CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE)
|
||||
_region_min_align = CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE;
|
||||
#elif defined(CONFIG_ARM_AARCH32_MMU)
|
||||
_region_min_align = CONFIG_MMU_PAGE_SIZE;
|
||||
#else
|
||||
/* If building without MPU support, use default 4-byte alignment. */
|
||||
_region_min_align = 4;
|
||||
|
@ -72,6 +74,8 @@ _region_min_align = 4;
|
|||
. = ALIGN(_region_min_align)
|
||||
#endif
|
||||
|
||||
#define BSS_ALIGN ALIGN(_region_min_align)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE
|
||||
|
@ -127,7 +131,11 @@ SECTIONS
|
|||
|
||||
SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
|
||||
{
|
||||
. = ALIGN(_region_min_align);
|
||||
__text_region_start = .;
|
||||
#ifndef CONFIG_XIP
|
||||
z_mapped_start = .;
|
||||
#endif
|
||||
|
||||
#include <linker/kobject-text.ld>
|
||||
|
||||
|
@ -144,6 +152,7 @@ SECTIONS
|
|||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
__text_region_end = .;
|
||||
. = ALIGN(_region_min_align);
|
||||
|
||||
#if defined (CONFIG_CPLUSPLUS)
|
||||
SECTION_PROLOGUE(.ARM.extab,,)
|
||||
|
@ -170,6 +179,7 @@ SECTIONS
|
|||
__exidx_end = .;
|
||||
} GROUP_LINK_IN(ROMABLE_REGION)
|
||||
|
||||
. = ALIGN(_region_min_align);
|
||||
__rodata_region_start = .;
|
||||
|
||||
#include <linker/common-rom.ld>
|
||||
|
@ -210,6 +220,7 @@ SECTIONS
|
|||
|
||||
__rodata_region_end = .;
|
||||
__rom_region_end = .;
|
||||
MPU_ALIGN(__rodata_region_end - __rom_region_start);
|
||||
_image_rom_end_order = (LOG2CEIL(__rom_region_end) - 1) << 1;
|
||||
|
||||
GROUP_END(ROMABLE_REGION)
|
||||
|
@ -234,6 +245,9 @@ SECTIONS
|
|||
*/
|
||||
. = ALIGN(_region_min_align);
|
||||
_image_ram_start = .;
|
||||
#ifdef CONFIG_XIP
|
||||
z_mapped_start = .;
|
||||
#endif
|
||||
|
||||
/* Located in generated directory. This file is populated by the
|
||||
* zephyr_linker_sources() Cmake function.
|
||||
|
@ -250,7 +264,7 @@ SECTIONS
|
|||
_app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
||||
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD),)
|
||||
SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD), BSS_ALIGN)
|
||||
{
|
||||
/*
|
||||
* For performance, BSS section is assumed to be 4 byte aligned and
|
||||
|
@ -316,8 +330,10 @@ SECTIONS
|
|||
|
||||
/* Define linker symbols */
|
||||
|
||||
. = ALIGN(_region_min_align);
|
||||
_image_ram_end = .;
|
||||
_end = .; /* end of image */
|
||||
z_mapped_end = .;
|
||||
|
||||
__kernel_ram_end = RAM_ADDR + RAM_SIZE;
|
||||
__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;
|
||||
|
|
105
include/arch/arm/aarch32/mmu/arm_mmu.h
Normal file
105
include/arch/arm/aarch32/mmu/arm_mmu.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* ARMv7 MMU support
|
||||
*
|
||||
* Copyright (c) 2021 Weidmueller Interface GmbH & Co. KG
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_AARCH32_ARM_MMU_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_AARCH32_ARM_MMU_H_
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
/*
|
||||
* Comp.:
|
||||
* ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition,
|
||||
* ARM document ID DDI0406C Rev. d, March 2018
|
||||
* Memory type definitions:
|
||||
* Table B3-10, chap. B3.8.2, p. B3-1363f.
|
||||
* Outer / inner cache attributes for cacheable memory:
|
||||
* Table B3-11, chap. B3.8.2, p. B3-1364
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following definitions are used when specifying a memory
|
||||
* range to be mapped at boot time using the MMU_REGION_ENTRY
|
||||
* macro.
|
||||
*/
|
||||
#define MT_STRONGLY_ORDERED BIT(0)
|
||||
#define MT_DEVICE BIT(1)
|
||||
#define MT_NORMAL BIT(2)
|
||||
#define MT_MASK 0x7
|
||||
|
||||
#define MPERM_R BIT(3)
|
||||
#define MPERM_W BIT(4)
|
||||
#define MPERM_X BIT(5)
|
||||
#define MPERM_UNPRIVILEGED BIT(6)
|
||||
|
||||
#define MATTR_NON_SECURE BIT(7)
|
||||
#define MATTR_NON_GLOBAL BIT(8)
|
||||
#define MATTR_SHARED BIT(9)
|
||||
#define MATTR_CACHE_OUTER_WB_WA BIT(10)
|
||||
#define MATTR_CACHE_OUTER_WT_nWA BIT(11)
|
||||
#define MATTR_CACHE_OUTER_WB_nWA BIT(12)
|
||||
#define MATTR_CACHE_INNER_WB_WA BIT(13)
|
||||
#define MATTR_CACHE_INNER_WT_nWA BIT(14)
|
||||
#define MATTR_CACHE_INNER_WB_nWA BIT(15)
|
||||
|
||||
#define MATTR_MAY_MAP_L1_SECTION BIT(16)
|
||||
|
||||
/*
|
||||
* The following macros are used for adding constant entries
|
||||
* mmu_regions array of the mmu_config struct. Use MMU_REGION_ENTRY
|
||||
* for the specification of mappings whose PA and VA differ,
|
||||
* the use of MMU_REGION_FLAT_ENTRY always results in an identity
|
||||
* mapping, which are used for the mappings of the Zephyr image's
|
||||
* code and data.
|
||||
*/
|
||||
#define MMU_REGION_ENTRY(_name, _base_pa, _base_va, _size, _attrs) \
|
||||
{\
|
||||
.name = _name, \
|
||||
.base_pa = _base_pa, \
|
||||
.base_va = _base_va, \
|
||||
.size = _size, \
|
||||
.attrs = _attrs, \
|
||||
}
|
||||
|
||||
#define MMU_REGION_FLAT_ENTRY(name, adr, sz, attrs) \
|
||||
MMU_REGION_ENTRY(name, adr, adr, sz, attrs)
|
||||
|
||||
/* Region definition data structure */
|
||||
struct arm_mmu_region {
|
||||
/* Region Base Physical Address */
|
||||
uintptr_t base_pa;
|
||||
/* Region Base Virtual Address */
|
||||
uintptr_t base_va;
|
||||
/* Region size */
|
||||
size_t size;
|
||||
/* Region Name */
|
||||
const char *name;
|
||||
/* Region Attributes */
|
||||
uint32_t attrs;
|
||||
};
|
||||
|
||||
/* MMU configuration data structure */
|
||||
struct arm_mmu_config {
|
||||
/* Number of regions */
|
||||
uint32_t num_regions;
|
||||
/* Regions */
|
||||
const struct arm_mmu_region *mmu_regions;
|
||||
};
|
||||
|
||||
/*
|
||||
* Reference to the MMU configuration.
|
||||
*
|
||||
* This struct is defined and populated for each SoC (in the SoC definition),
|
||||
* and holds the build-time configuration information for the fixed MMU
|
||||
* regions enabled during kernel initialization.
|
||||
*/
|
||||
extern const struct arm_mmu_config mmu_config;
|
||||
|
||||
int z_arm_mmu_init(void);
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_AARCH32_ARM_MMU_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue