davidcunado-arm
7 years ago
committed by
GitHub
23 changed files with 768 additions and 675 deletions
@ -0,0 +1,72 @@ |
|||
/*
|
|||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef __XLAT_TABLES_AARCH32_H__ |
|||
#define __XLAT_TABLES_AARCH32_H__ |
|||
|
|||
#include <arch.h> |
|||
#include <utils_def.h> |
|||
#include <xlat_tables_defs.h> |
|||
|
|||
#if !defined(PAGE_SIZE) |
|||
#error "PAGE_SIZE is not defined." |
|||
#endif |
|||
|
|||
/*
|
|||
* In AArch32 state, the MMU only supports 4KB page granularity, which means |
|||
* that the first translation table level is either 1 or 2. Both of them are |
|||
* allowed to have block and table descriptors. See section G4.5.6 of the |
|||
* ARMv8-A Architecture Reference Manual (DDI 0487A.k) for more information. |
|||
* |
|||
* The define below specifies the first table level that allows block |
|||
* descriptors. |
|||
*/ |
|||
#if PAGE_SIZE != (4 * 1024) |
|||
#error "Invalid granule size. AArch32 supports 4KB pages only." |
|||
#endif |
|||
|
|||
#define MIN_LVL_BLOCK_DESC U(1) |
|||
|
|||
#define XLAT_TABLE_LEVEL_MIN U(1) |
|||
|
|||
/*
|
|||
* Define the architectural limits of the virtual address space in AArch32 |
|||
* state. |
|||
* |
|||
* TTBCR.TxSZ is calculated as 32 minus the width of said address space. The |
|||
* value of TTBCR.TxSZ must be in the range 0 to 7 [1], which means that the |
|||
* virtual address space width must be in the range 32 to 25 bits. |
|||
* |
|||
* [1] See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more |
|||
* information, Section G4.6.5 |
|||
*/ |
|||
#define MIN_VIRT_ADDR_SPACE_SIZE (ULL(1) << (32 - TTBCR_TxSZ_MAX)) |
|||
#define MAX_VIRT_ADDR_SPACE_SIZE (ULL(1) << (32 - TTBCR_TxSZ_MIN)) |
|||
|
|||
/*
|
|||
* Here we calculate the initial lookup level from the value of the given |
|||
* virtual address space size. For a 4 KB page size, |
|||
* - level 1 supports virtual address spaces of widths 32 to 31 bits; |
|||
* - level 2 from 30 to 25. |
|||
* |
|||
* Wider or narrower address spaces are not supported. As a result, level 3 |
|||
* cannot be used as the initial lookup level with 4 KB granularity. |
|||
* See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more |
|||
* information, Section G4.6.5 |
|||
* |
|||
* For example, for a 31-bit address space (i.e. virt_addr_space_size == |
|||
* 1 << 31), TTBCR.TxSZ will be programmed to (32 - 31) = 1. According to Table |
|||
* G4-5 in the ARM ARM, the initial lookup level for an address space like that |
|||
* is 1. |
|||
* |
|||
* Note that this macro assumes that the given virtual address space size is |
|||
* valid. Therefore, the caller is expected to check it is the case using the |
|||
* CHECK_VIRT_ADDR_SPACE_SIZE() macro first. |
|||
*/ |
|||
#define GET_XLAT_TABLE_LEVEL_BASE(virt_addr_space_size) \ |
|||
(((virt_addr_space_size) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) ? 1 : 2) |
|||
|
|||
#endif /* __XLAT_TABLES_AARCH32_H__ */ |
@ -0,0 +1,78 @@ |
|||
/*
|
|||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef __XLAT_TABLES_AARCH64_H__ |
|||
#define __XLAT_TABLES_AARCH64_H__ |
|||
|
|||
#include <arch.h> |
|||
#include <utils_def.h> |
|||
#include <xlat_tables_defs.h> |
|||
|
|||
#if !defined(PAGE_SIZE) |
|||
#error "PAGE_SIZE is not defined." |
|||
#endif |
|||
|
|||
/*
|
|||
* In AArch64 state, the MMU may support 4 KB, 16 KB and 64 KB page |
|||
* granularity. For 4KB granularity, a level 0 table descriptor doesn't support |
|||
* block translation. For 16KB, the same thing happens to levels 0 and 1. For |
|||
* 64KB, same for level 1. See section D4.3.1 of the ARMv8-A Architecture |
|||
* Reference Manual (DDI 0487A.k) for more information. |
|||
* |
|||
* The define below specifies the first table level that allows block |
|||
* descriptors. |
|||
*/ |
|||
#if PAGE_SIZE == (4 * 1024) |
|||
# define MIN_LVL_BLOCK_DESC U(1) |
|||
#elif PAGE_SIZE == (16 * 1024) || PAGE_SIZE == (64 * 1024) |
|||
# define MIN_LVL_BLOCK_DESC U(2) |
|||
#endif |
|||
|
|||
#define XLAT_TABLE_LEVEL_MIN U(0) |
|||
|
|||
/*
|
|||
* Define the architectural limits of the virtual address space in AArch64 |
|||
* state. |
|||
* |
|||
* TCR.TxSZ is calculated as 64 minus the width of said address space. |
|||
* The value of TCR.TxSZ must be in the range 16 to 39 [1], which means that |
|||
* the virtual address space width must be in the range 48 to 25 bits. |
|||
* |
|||
* [1] See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more |
|||
* information: |
|||
* Page 1730: 'Input address size', 'For all translation stages'. |
|||
*/ |
|||
#define MIN_VIRT_ADDR_SPACE_SIZE (ULL(1) << (64 - TCR_TxSZ_MAX)) |
|||
#define MAX_VIRT_ADDR_SPACE_SIZE (ULL(1) << (64 - TCR_TxSZ_MIN)) |
|||
|
|||
/*
|
|||
* Here we calculate the initial lookup level from the value of the given |
|||
* virtual address space size. For a 4 KB page size, |
|||
* - level 0 supports virtual address spaces of widths 48 to 40 bits; |
|||
* - level 1 from 39 to 31; |
|||
* - level 2 from 30 to 25. |
|||
* |
|||
* Wider or narrower address spaces are not supported. As a result, level 3 |
|||
* cannot be used as initial lookup level with 4 KB granularity. See section |
|||
* D4.2.5 in the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more |
|||
* information. |
|||
* |
|||
* For example, for a 35-bit address space (i.e. virt_addr_space_size == |
|||
* 1 << 35), TCR.TxSZ will be programmed to (64 - 35) = 29. According to Table |
|||
* D4-11 in the ARM ARM, the initial lookup level for an address space like that |
|||
* is 1. |
|||
* |
|||
* Note that this macro assumes that the given virtual address space size is |
|||
* valid. Therefore, the caller is expected to check it is the case using the |
|||
* CHECK_VIRT_ADDR_SPACE_SIZE() macro first. |
|||
*/ |
|||
#define GET_XLAT_TABLE_LEVEL_BASE(virt_addr_space_size) \ |
|||
(((virt_addr_space_size) > (ULL(1) << L0_XLAT_ADDRESS_SHIFT)) \ |
|||
? 0 \ |
|||
: (((virt_addr_space_size) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) \ |
|||
? 1 : 2)) |
|||
|
|||
#endif /* __XLAT_TABLES_AARCH64_H__ */ |
@ -0,0 +1,43 @@ |
|||
/*
|
|||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef __XLAT_TABLES_ARCH_H__ |
|||
#define __XLAT_TABLES_ARCH_H__ |
|||
|
|||
#ifdef AARCH32 |
|||
#include "aarch32/xlat_tables_aarch32.h" |
|||
#else |
|||
#include "aarch64/xlat_tables_aarch64.h" |
|||
#endif |
|||
|
|||
/*
|
|||
* Evaluates to 1 if the given virtual address space size is valid, or 0 if it's |
|||
* not. |
|||
* |
|||
* A valid size is one that is a power of 2 and is within the architectural |
|||
* limits. Not that these limits are different for AArch32 and AArch64. |
|||
*/ |
|||
#define CHECK_VIRT_ADDR_SPACE_SIZE(size) \ |
|||
(((size) >= MIN_VIRT_ADDR_SPACE_SIZE) && \ |
|||
((size) <= MAX_VIRT_ADDR_SPACE_SIZE) && \ |
|||
IS_POWER_OF_TWO(size)) |
|||
|
|||
/*
|
|||
* Evaluates to 1 if the given physical address space size is a power of 2, |
|||
* or 0 if it's not. |
|||
*/ |
|||
#define CHECK_PHY_ADDR_SPACE_SIZE(size) \ |
|||
(IS_POWER_OF_TWO(size)) |
|||
|
|||
/*
|
|||
* Compute the number of entries required at the initial lookup level to address |
|||
* the whole virtual address space. |
|||
*/ |
|||
#define GET_NUM_BASE_LEVEL_ENTRIES(addr_space_size) \ |
|||
((addr_space_size) >> \ |
|||
XLAT_ADDR_SHIFT(GET_XLAT_TABLE_LEVEL_BASE(addr_space_size))) |
|||
|
|||
#endif /* __XLAT_TABLES_ARCH_H__ */ |
@ -0,0 +1,151 @@ |
|||
/*
|
|||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
/*
|
|||
* This header file contains internal definitions that are not supposed to be |
|||
* used outside of this library code. |
|||
*/ |
|||
|
|||
#ifndef __XLAT_TABLES_V2_HELPERS_H__ |
|||
#define __XLAT_TABLES_V2_HELPERS_H__ |
|||
|
|||
#ifndef __XLAT_TABLES_V2_H__ |
|||
#error "Do not include this header file directly. Include xlat_tables_v2.h instead." |
|||
#endif |
|||
|
|||
#ifndef __ASSEMBLY__ |
|||
|
|||
#include <cassert.h> |
|||
#include <platform_def.h> |
|||
#include <stddef.h> |
|||
#include <xlat_tables_arch.h> |
|||
#include <xlat_tables_defs.h> |
|||
|
|||
/* Forward declaration */ |
|||
struct mmap_region; |
|||
|
|||
/* Struct that holds all information about the translation tables. */ |
|||
struct xlat_ctx { |
|||
/*
|
|||
* Max allowed Virtual and Physical Addresses. |
|||
*/ |
|||
unsigned long long pa_max_address; |
|||
uintptr_t va_max_address; |
|||
|
|||
/*
|
|||
* Array of all memory regions stored in order of ascending end address |
|||
* and ascending size to simplify the code that allows overlapping |
|||
* regions. The list is terminated by the first entry with size == 0. |
|||
* The max size of the list is stored in `mmap_num`. `mmap` points to an |
|||
* array of mmap_num + 1 elements, so that there is space for the final |
|||
* null entry. |
|||
*/ |
|||
struct mmap_region *mmap; |
|||
unsigned int mmap_num; |
|||
|
|||
/*
|
|||
* Array of finer-grain translation tables. |
|||
* For example, if the initial lookup level is 1 then this array would |
|||
* contain both level-2 and level-3 entries. |
|||
*/ |
|||
uint64_t (*tables)[XLAT_TABLE_ENTRIES]; |
|||
unsigned int tables_num; |
|||
/*
|
|||
* Keep track of how many regions are mapped in each table. The base |
|||
* table can't be unmapped so it isn't needed to keep track of it. |
|||
*/ |
|||
#if PLAT_XLAT_TABLES_DYNAMIC |
|||
int *tables_mapped_regions; |
|||
#endif /* PLAT_XLAT_TABLES_DYNAMIC */ |
|||
|
|||
unsigned int next_table; |
|||
|
|||
/*
|
|||
* Base translation table. It doesn't need to have the same amount of |
|||
* entries as the ones used for other levels. |
|||
*/ |
|||
uint64_t *base_table; |
|||
unsigned int base_table_entries; |
|||
|
|||
/*
|
|||
* Max Physical and Virtual addresses currently in use by the |
|||
* translation tables. These might get updated as we map/unmap memory |
|||
* regions but they will never go beyond pa/va_max_address. |
|||
*/ |
|||
unsigned long long max_pa; |
|||
uintptr_t max_va; |
|||
|
|||
/* Level of the base translation table. */ |
|||
unsigned int base_level; |
|||
|
|||
/* Set to 1 when the translation tables are initialized. */ |
|||
unsigned int initialized; |
|||
|
|||
/*
|
|||
* Bit mask that has to be ORed to the rest of a translation table |
|||
* descriptor in order to prohibit execution of code at the exception |
|||
* level of this translation context. |
|||
*/ |
|||
uint64_t execute_never_mask; |
|||
}; |
|||
|
|||
#if PLAT_XLAT_TABLES_DYNAMIC |
|||
#define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \ |
|||
static int _ctx_name##_mapped_regions[_xlat_tables_count]; |
|||
|
|||
#define _REGISTER_DYNMAP_STRUCT(_ctx_name) \ |
|||
.tables_mapped_regions = _ctx_name##_mapped_regions, |
|||
#else |
|||
#define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \ |
|||
/* do nothing */ |
|||
|
|||
#define _REGISTER_DYNMAP_STRUCT(_ctx_name) \ |
|||
/* do nothing */ |
|||
#endif /* PLAT_XLAT_TABLES_DYNAMIC */ |
|||
|
|||
|
|||
#define _REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \ |
|||
_virt_addr_space_size, _phy_addr_space_size) \ |
|||
CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(_virt_addr_space_size), \ |
|||
assert_invalid_virtual_addr_space_size_for_##_ctx_name); \ |
|||
\ |
|||
CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size), \ |
|||
assert_invalid_physical_addr_space_sizefor_##_ctx_name); \ |
|||
\ |
|||
static mmap_region_t _ctx_name##_mmap[_mmap_count + 1]; \ |
|||
\ |
|||
static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count] \ |
|||
[XLAT_TABLE_ENTRIES] \ |
|||
__aligned(XLAT_TABLE_SIZE) __section("xlat_table"); \ |
|||
\ |
|||
static uint64_t _ctx_name##_base_xlat_table \ |
|||
[GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \ |
|||
__aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size) \ |
|||
* sizeof(uint64_t)); \ |
|||
\ |
|||
_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \ |
|||
\ |
|||
static xlat_ctx_t _ctx_name##_xlat_ctx = { \ |
|||
.va_max_address = (_virt_addr_space_size) - 1, \ |
|||
.pa_max_address = (_phy_addr_space_size) - 1, \ |
|||
.mmap = _ctx_name##_mmap, \ |
|||
.mmap_num = _mmap_count, \ |
|||
.base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size), \ |
|||
.base_table = _ctx_name##_base_xlat_table, \ |
|||
.base_table_entries = \ |
|||
GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size), \ |
|||
.tables = _ctx_name##_xlat_tables, \ |
|||
.tables_num = _xlat_tables_count, \ |
|||
_REGISTER_DYNMAP_STRUCT(_ctx_name) \ |
|||
.max_pa = 0, \ |
|||
.max_va = 0, \ |
|||
.next_table = 0, \ |
|||
.initialized = 0, \ |
|||
} |
|||
|
|||
#endif /*__ASSEMBLY__*/ |
|||
|
|||
#endif /* __XLAT_TABLES_V2_HELPERS_H__ */ |
@ -0,0 +1,29 @@ |
|||
/* ===-- ctzdi2.c - Implement __ctzdi2 -------------------------------------===
|
|||
* |
|||
* The LLVM Compiler Infrastructure |
|||
* |
|||
* This file is dual licensed under the MIT and the University of Illinois Open |
|||
* Source Licenses. See LICENSE.TXT for details. |
|||
* |
|||
* ===----------------------------------------------------------------------=== |
|||
* |
|||
* This file implements __ctzdi2 for the compiler_rt library. |
|||
* |
|||
* ===----------------------------------------------------------------------=== |
|||
*/ |
|||
|
|||
#include "int_lib.h" |
|||
|
|||
/* Returns: the number of trailing 0-bits */ |
|||
|
|||
/* Precondition: a != 0 */ |
|||
|
|||
COMPILER_RT_ABI si_int |
|||
__ctzdi2(di_int a) |
|||
{ |
|||
dwords x; |
|||
x.all = a; |
|||
const si_int f = -(x.s.low == 0); |
|||
return __builtin_ctz((x.s.high & f) | (x.s.low & ~f)) + |
|||
(f & ((si_int)(sizeof(si_int) * CHAR_BIT))); |
|||
} |
@ -1,72 +0,0 @@ |
|||
/*
|
|||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef __XLAT_TABLES_ARCH_H__ |
|||
#define __XLAT_TABLES_ARCH_H__ |
|||
|
|||
#include <arch.h> |
|||
#include <platform_def.h> |
|||
#include <xlat_tables_defs.h> |
|||
#include "../xlat_tables_private.h" |
|||
|
|||
/*
|
|||
* In AArch32 state, the MMU only supports 4KB page granularity, which means |
|||
* that the first translation table level is either 1 or 2. Both of them are |
|||
* allowed to have block and table descriptors. See section G4.5.6 of the |
|||
* ARMv8-A Architecture Reference Manual (DDI 0487A.k) for more information. |
|||
* |
|||
* The define below specifies the first table level that allows block |
|||
* descriptors. |
|||
*/ |
|||
|
|||
#define MIN_LVL_BLOCK_DESC 1 |
|||
|
|||
/*
|
|||
* Each platform can define the size of the virtual address space, which is |
|||
* defined in PLAT_VIRT_ADDR_SPACE_SIZE. TTBCR.TxSZ is calculated as 32 minus |
|||
* the width of said address space. The value of TTBCR.TxSZ must be in the |
|||
* range 0 to 7 [1], which means that the virtual address space width must be |
|||
* in the range 32 to 25 bits. |
|||
* |
|||
* Here we calculate the initial lookup level from the value of |
|||
* PLAT_VIRT_ADDR_SPACE_SIZE. For a 4 KB page size, level 1 supports virtual |
|||
* address spaces of widths 32 to 31 bits, and level 2 from 30 to 25. Wider or |
|||
* narrower address spaces are not supported. As a result, level 3 cannot be |
|||
* used as initial lookup level with 4 KB granularity [1]. |
|||
* |
|||
* For example, for a 31-bit address space (i.e. PLAT_VIRT_ADDR_SPACE_SIZE == |
|||
* 1 << 31), TTBCR.TxSZ will be programmed to (32 - 31) = 1. According to Table |
|||
* G4-5 in the ARM ARM, the initial lookup level for an address space like that |
|||
* is 1. |
|||
* |
|||
* See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more |
|||
* information: |
|||
* [1] Section G4.6.5 |
|||
*/ |
|||
|
|||
#if PLAT_VIRT_ADDR_SPACE_SIZE > (1ULL << (32 - TTBCR_TxSZ_MIN)) |
|||
|
|||
# error "PLAT_VIRT_ADDR_SPACE_SIZE is too big." |
|||
|
|||
#elif PLAT_VIRT_ADDR_SPACE_SIZE > (1 << L1_XLAT_ADDRESS_SHIFT) |
|||
|
|||
# define XLAT_TABLE_LEVEL_BASE 1 |
|||
# define NUM_BASE_LEVEL_ENTRIES \ |
|||
(PLAT_VIRT_ADDR_SPACE_SIZE >> L1_XLAT_ADDRESS_SHIFT) |
|||
|
|||
#elif PLAT_VIRT_ADDR_SPACE_SIZE >= (1 << (32 - TTBCR_TxSZ_MAX)) |
|||
|
|||
# define XLAT_TABLE_LEVEL_BASE 2 |
|||
# define NUM_BASE_LEVEL_ENTRIES \ |
|||
(PLAT_VIRT_ADDR_SPACE_SIZE >> L2_XLAT_ADDRESS_SHIFT) |
|||
|
|||
#else |
|||
|
|||
# error "PLAT_VIRT_ADDR_SPACE_SIZE is too small." |
|||
|
|||
#endif |
|||
|
|||
#endif /* __XLAT_TABLES_ARCH_H__ */ |
@ -1,85 +0,0 @@ |
|||
/*
|
|||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef __XLAT_TABLES_ARCH_H__ |
|||
#define __XLAT_TABLES_ARCH_H__ |
|||
|
|||
#include <arch.h> |
|||
#include <platform_def.h> |
|||
#include <xlat_tables_defs.h> |
|||
#include "../xlat_tables_private.h" |
|||
|
|||
/*
|
|||
* In AArch64 state, the MMU may support 4 KB, 16 KB and 64 KB page |
|||
* granularity. For 4KB granularity, a level 0 table descriptor doesn't support |
|||
* block translation. For 16KB, the same thing happens to levels 0 and 1. For |
|||
* 64KB, same for level 1. See section D4.3.1 of the ARMv8-A Architecture |
|||
* Reference Manual (DDI 0487A.k) for more information. |
|||
* |
|||
* The define below specifies the first table level that allows block |
|||
* descriptors. |
|||
*/ |
|||
|
|||
#if PAGE_SIZE == (4*1024) /* 4KB */ |
|||
# define MIN_LVL_BLOCK_DESC 1 |
|||
#else /* 16KB or 64KB */ |
|||
# define MIN_LVL_BLOCK_DESC 2 |
|||
#endif |
|||
|
|||
/*
|
|||
* Each platform can define the size of the virtual address space, which is |
|||
* defined in PLAT_VIRT_ADDR_SPACE_SIZE. TCR.TxSZ is calculated as 64 minus the |
|||
* width of said address space. The value of TCR.TxSZ must be in the range 16 |
|||
* to 39 [1], which means that the virtual address space width must be in the |
|||
* range 48 to 25 bits. |
|||
* |
|||
* Here we calculate the initial lookup level from the value of |
|||
* PLAT_VIRT_ADDR_SPACE_SIZE. For a 4 KB page size, level 0 supports virtual |
|||
* address spaces of widths 48 to 40 bits, level 1 from 39 to 31, and level 2 |
|||
* from 30 to 25. Wider or narrower address spaces are not supported. As a |
|||
* result, level 3 cannot be used as initial lookup level with 4 KB |
|||
* granularity. [2] |
|||
* |
|||
* For example, for a 35-bit address space (i.e. PLAT_VIRT_ADDR_SPACE_SIZE == |
|||
* 1 << 35), TCR.TxSZ will be programmed to (64 - 35) = 29. According to Table |
|||
* D4-11 in the ARM ARM, the initial lookup level for an address space like |
|||
* that is 1. |
|||
* |
|||
* See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more |
|||
* information: |
|||
* [1] Page 1730: 'Input address size', 'For all translation stages'. |
|||
* [2] Section D4.2.5 |
|||
*/ |
|||
|
|||
#if PLAT_VIRT_ADDR_SPACE_SIZE > (1ULL << (64 - TCR_TxSZ_MIN)) |
|||
|
|||
# error "PLAT_VIRT_ADDR_SPACE_SIZE is too big." |
|||
|
|||
#elif PLAT_VIRT_ADDR_SPACE_SIZE > (1ULL << L0_XLAT_ADDRESS_SHIFT) |
|||
|
|||
# define XLAT_TABLE_LEVEL_BASE 0 |
|||
# define NUM_BASE_LEVEL_ENTRIES \ |
|||
(PLAT_VIRT_ADDR_SPACE_SIZE >> L0_XLAT_ADDRESS_SHIFT) |
|||
|
|||
#elif PLAT_VIRT_ADDR_SPACE_SIZE > (1 << L1_XLAT_ADDRESS_SHIFT) |
|||
|
|||
# define XLAT_TABLE_LEVEL_BASE 1 |
|||
# define NUM_BASE_LEVEL_ENTRIES \ |
|||
(PLAT_VIRT_ADDR_SPACE_SIZE >> L1_XLAT_ADDRESS_SHIFT) |
|||
|
|||
#elif PLAT_VIRT_ADDR_SPACE_SIZE >= (1 << (64 - TCR_TxSZ_MAX)) |
|||
|
|||
# define XLAT_TABLE_LEVEL_BASE 2 |
|||
# define NUM_BASE_LEVEL_ENTRIES \ |
|||
(PLAT_VIRT_ADDR_SPACE_SIZE >> L2_XLAT_ADDRESS_SHIFT) |
|||
|
|||
#else |
|||
|
|||
# error "PLAT_VIRT_ADDR_SPACE_SIZE is too small." |
|||
|
|||
#endif |
|||
|
|||
#endif /* __XLAT_TABLES_ARCH_H__ */ |
@ -1,144 +0,0 @@ |
|||
/*
|
|||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <arch.h> |
|||
#include <arch_helpers.h> |
|||
#include <assert.h> |
|||
#include <cassert.h> |
|||
#include <common_def.h> |
|||
#include <debug.h> |
|||
#include <errno.h> |
|||
#include <platform_def.h> |
|||
#include <string.h> |
|||
#include <types.h> |
|||
#include <utils.h> |
|||
#include <xlat_tables_v2.h> |
|||
#ifdef AARCH32 |
|||
# include "aarch32/xlat_tables_arch.h" |
|||
#else |
|||
# include "aarch64/xlat_tables_arch.h" |
|||
#endif |
|||
#include "xlat_tables_private.h" |
|||
|
|||
/*
|
|||
* Private variables used by the TF |
|||
*/ |
|||
static mmap_region_t tf_mmap[MAX_MMAP_REGIONS + 1]; |
|||
|
|||
static uint64_t tf_xlat_tables[MAX_XLAT_TABLES][XLAT_TABLE_ENTRIES] |
|||
__aligned(XLAT_TABLE_SIZE) __section("xlat_table"); |
|||
|
|||
static uint64_t tf_base_xlat_table[NUM_BASE_LEVEL_ENTRIES] |
|||
__aligned(NUM_BASE_LEVEL_ENTRIES * sizeof(uint64_t)); |
|||
|
|||
#if PLAT_XLAT_TABLES_DYNAMIC |
|||
static int xlat_tables_mapped_regions[MAX_XLAT_TABLES]; |
|||
#endif /* PLAT_XLAT_TABLES_DYNAMIC */ |
|||
|
|||
xlat_ctx_t tf_xlat_ctx = { |
|||
|
|||
.pa_max_address = PLAT_PHY_ADDR_SPACE_SIZE - 1, |
|||
.va_max_address = PLAT_VIRT_ADDR_SPACE_SIZE - 1, |
|||
|
|||
.mmap = tf_mmap, |
|||
.mmap_num = MAX_MMAP_REGIONS, |
|||
|
|||
.tables = tf_xlat_tables, |
|||
.tables_num = MAX_XLAT_TABLES, |
|||
#if PLAT_XLAT_TABLES_DYNAMIC |
|||
.tables_mapped_regions = xlat_tables_mapped_regions, |
|||
#endif /* PLAT_XLAT_TABLES_DYNAMIC */ |
|||
|
|||
.base_table = tf_base_xlat_table, |
|||
.base_table_entries = NUM_BASE_LEVEL_ENTRIES, |
|||
|
|||
.max_pa = 0, |
|||
.max_va = 0, |
|||
|
|||
.next_table = 0, |
|||
|
|||
.base_level = XLAT_TABLE_LEVEL_BASE, |
|||
|
|||
.initialized = 0 |
|||
}; |
|||
|
|||
void mmap_add_region(unsigned long long base_pa, uintptr_t base_va, |
|||
size_t size, mmap_attr_t attr) |
|||
{ |
|||
mmap_region_t mm = { |
|||
.base_va = base_va, |
|||
.base_pa = base_pa, |
|||
.size = size, |
|||
.attr = attr, |
|||
}; |
|||
mmap_add_region_ctx(&tf_xlat_ctx, (mmap_region_t *)&mm); |
|||
} |
|||
|
|||
void mmap_add(const mmap_region_t *mm) |
|||
{ |
|||
while (mm->size) { |
|||
mmap_add_region_ctx(&tf_xlat_ctx, (mmap_region_t *)mm); |
|||
mm++; |
|||
} |
|||
} |
|||
|
|||
#if PLAT_XLAT_TABLES_DYNAMIC |
|||
|
|||
int mmap_add_dynamic_region(unsigned long long base_pa, |
|||
uintptr_t base_va, size_t size, mmap_attr_t attr) |
|||
{ |
|||
mmap_region_t mm = { |
|||
.base_va = base_va, |
|||
.base_pa = base_pa, |
|||
.size = size, |
|||
.attr = attr, |
|||
}; |
|||
return mmap_add_dynamic_region_ctx(&tf_xlat_ctx, &mm); |
|||
} |
|||
|
|||
int mmap_remove_dynamic_region(uintptr_t base_va, size_t size) |
|||
{ |
|||
return mmap_remove_dynamic_region_ctx(&tf_xlat_ctx, base_va, size); |
|||
} |
|||
|
|||
#endif /* PLAT_XLAT_TABLES_DYNAMIC */ |
|||
|
|||
void init_xlat_tables(void) |
|||
{ |
|||
assert(!is_mmu_enabled()); |
|||
assert(!tf_xlat_ctx.initialized); |
|||
print_mmap(tf_xlat_ctx.mmap); |
|||
tf_xlat_ctx.execute_never_mask = |
|||
xlat_arch_get_xn_desc(xlat_arch_current_el()); |
|||
init_xlation_table(&tf_xlat_ctx); |
|||
xlat_tables_print(&tf_xlat_ctx); |
|||
|
|||
assert(tf_xlat_ctx.max_va <= PLAT_VIRT_ADDR_SPACE_SIZE - 1); |
|||
assert(tf_xlat_ctx.max_pa <= PLAT_PHY_ADDR_SPACE_SIZE - 1); |
|||
|
|||
init_xlat_tables_arch(tf_xlat_ctx.max_pa); |
|||
} |
|||
|
|||
#ifdef AARCH32 |
|||
|
|||
void enable_mmu_secure(unsigned int flags) |
|||
{ |
|||
enable_mmu_arch(flags, tf_xlat_ctx.base_table); |
|||
} |
|||
|
|||
#else |
|||
|
|||
void enable_mmu_el1(unsigned int flags) |
|||
{ |
|||
enable_mmu_arch(flags, tf_xlat_ctx.base_table); |
|||
} |
|||
|
|||
void enable_mmu_el3(unsigned int flags) |
|||
{ |
|||
enable_mmu_arch(flags, tf_xlat_ctx.base_table); |
|||
} |
|||
|
|||
#endif /* AARCH32 */ |
Loading…
Reference in new issue