summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--docs/change-log.rst4
-rw-r--r--docs/cpu-specific-build-macros.rst10
-rw-r--r--docs/platform-migration-guide.rst13
-rw-r--r--docs/porting-guide.rst32
-rw-r--r--docs/user-guide.rst10
-rw-r--r--include/lib/psci/psci.h2
-rw-r--r--include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h72
-rw-r--r--include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h78
-rw-r--r--include/lib/xlat_tables/xlat_tables_arch.h43
-rw-r--r--include/lib/xlat_tables/xlat_tables_defs.h12
-rw-r--r--include/lib/xlat_tables/xlat_tables_v2.h72
-rw-r--r--include/lib/xlat_tables/xlat_tables_v2_helpers.h151
-rw-r--r--include/plat/arm/css/common/css_def.h18
-rw-r--r--include/plat/arm/soc/common/soc_css_def.h4
-rw-r--r--lib/compiler-rt/builtins/ctzdi2.c29
-rw-r--r--lib/compiler-rt/compiler-rt.mk3
-rw-r--r--lib/psci/psci_on.c13
-rw-r--r--lib/psci/psci_suspend.c11
-rw-r--r--lib/stdlib/assert.c4
-rw-r--r--lib/xlat_tables/aarch32/xlat_tables.c53
-rw-r--r--lib/xlat_tables/aarch64/xlat_tables.c61
-rw-r--r--lib/xlat_tables/xlat_tables_private.h39
-rw-r--r--lib/xlat_tables_v2/aarch32/xlat_tables_arch.c79
-rw-r--r--lib/xlat_tables_v2/aarch32/xlat_tables_arch.h72
-rw-r--r--lib/xlat_tables_v2/aarch64/xlat_tables_arch.c130
-rw-r--r--lib/xlat_tables_v2/aarch64/xlat_tables_arch.h85
-rw-r--r--lib/xlat_tables_v2/xlat_tables.mk1
-rw-r--r--lib/xlat_tables_v2/xlat_tables_common.c144
-rw-r--r--lib/xlat_tables_v2/xlat_tables_internal.c170
-rw-r--r--lib/xlat_tables_v2/xlat_tables_private.h119
-rw-r--r--plat/arm/board/common/board_css_common.c1
-rw-r--r--plat/arm/board/fvp/fvp_common.c13
-rw-r--r--plat/arm/board/juno/include/platform_def.h8
-rw-r--r--plat/arm/css/common/css_bl2_setup.c7
-rw-r--r--plat/arm/css/common/css_bl2u_setup.c9
-rw-r--r--plat/arm/css/common/css_common.mk4
-rw-r--r--plat/arm/css/common/css_scp_bootloader.h12
-rw-r--r--plat/arm/css/drivers/scp/css_bom_bootloader.c (renamed from plat/arm/css/common/css_scp_bootloader.c)26
-rw-r--r--plat/arm/css/drivers/scp/css_scp.h26
-rw-r--r--plat/arm/css/drivers/scpi/css_scpi.h12
-rw-r--r--plat/hisilicon/hikey/hikey_bl1_setup.c5
-rw-r--r--plat/hisilicon/hikey/include/hi6553.h1
-rw-r--r--plat/nvidia/tegra/common/tegra_pm.c18
-rw-r--r--plat/socionext/uniphier/platform.mk1
-rw-r--r--readme.rst6
-rw-r--r--tools/fiptool/Makefile2
-rw-r--r--tools/fiptool/fiptool.c1
-rw-r--r--tools/fiptool/fiptool.h3
-rw-r--r--tools/fiptool/tbbr_config.c3
50 files changed, 948 insertions, 748 deletions
diff --git a/Makefile b/Makefile
index 6aa4e9aa..23ebcaa9 100644
--- a/Makefile
+++ b/Makefile
@@ -438,6 +438,7 @@ $(eval $(call assert_boolean,ENABLE_PLAT_COMPAT))
$(eval $(call assert_boolean,ENABLE_PMF))
$(eval $(call assert_boolean,ENABLE_PSCI_STAT))
$(eval $(call assert_boolean,ENABLE_RUNTIME_INSTRUMENTATION))
+$(eval $(call assert_boolean,ENABLE_SPE_FOR_LOWER_ELS))
$(eval $(call assert_boolean,ERROR_DEPRECATED))
$(eval $(call assert_boolean,GENERATE_COT))
$(eval $(call assert_boolean,HW_ASSISTED_COHERENCY))
@@ -454,7 +455,6 @@ $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
$(eval $(call assert_boolean,USE_COHERENT_MEM))
$(eval $(call assert_boolean,USE_TBBR_DEFS))
$(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
-$(eval $(call assert_boolean,ENABLE_SPE_FOR_LOWER_ELS))
$(eval $(call assert_numeric,ARM_ARCH_MAJOR))
$(eval $(call assert_numeric,ARM_ARCH_MINOR))
@@ -477,6 +477,7 @@ $(eval $(call add_define,ENABLE_PLAT_COMPAT))
$(eval $(call add_define,ENABLE_PMF))
$(eval $(call add_define,ENABLE_PSCI_STAT))
$(eval $(call add_define,ENABLE_RUNTIME_INSTRUMENTATION))
+$(eval $(call add_define,ENABLE_SPE_FOR_LOWER_ELS))
$(eval $(call add_define,ERROR_DEPRECATED))
$(eval $(call add_define,HW_ASSISTED_COHERENCY))
$(eval $(call add_define,LOAD_IMAGE_V2))
@@ -494,7 +495,6 @@ $(eval $(call add_define,TRUSTED_BOARD_BOOT))
$(eval $(call add_define,USE_COHERENT_MEM))
$(eval $(call add_define,USE_TBBR_DEFS))
$(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
-$(eval $(call add_define,ENABLE_SPE_FOR_LOWER_ELS))
# Define the EL3_PAYLOAD_BASE flag only if it is provided.
ifdef EL3_PAYLOAD_BASE
diff --git a/docs/change-log.rst b/docs/change-log.rst
index 708ec057..f5ad5623 100644
--- a/docs/change-log.rst
+++ b/docs/change-log.rst
@@ -266,7 +266,7 @@ New features
pre-empted SMC during PSCI power management requests.
Issues resolved since last release
-==================================
+----------------------------------
- ARM TF can be built with the latest mbed TLS version (v2.4.2). The earlier
version 2.3.0 cannot be used due to build warnings that the ARM TF build
@@ -280,7 +280,7 @@ Issues resolved since last release
shutdown request using the PSCI SYSTEM_OFF API.
Known Issues
-============
+------------
- Building TF with compiler optimisations disabled (-O0) fails.
diff --git a/docs/cpu-specific-build-macros.rst b/docs/cpu-specific-build-macros.rst
index ce564a2d..5738927c 100644
--- a/docs/cpu-specific-build-macros.rst
+++ b/docs/cpu-specific-build-macros.rst
@@ -51,10 +51,20 @@ For Cortex-A53, following errata build flags are defined :
- ``ERRATA_A53_826319``: This applies errata 826319 workaround to Cortex-A53
CPU. This needs to be enabled only for revision <= r0p2 of the CPU.
+- ``ERRATA_A53_835769``: This applies erratum 835769 workaround at compile and
+ link time to Cortex-A53 CPU. This needs to be enabled for some variants of
+ revision <= r0p4. This workaround can lead the linker to create ``*.stub``
+ sections.
+
- ``ERRATA_A53_836870``: This applies errata 836870 workaround to Cortex-A53
CPU. This needs to be enabled only for revision <= r0p3 of the CPU. From
r0p4 and onwards, this errata is enabled by default in hardware.
+- ``ERRATA_A53_843419``: This applies erratum 843419 workaround at link time
+ to Cortex-A53 CPU. This needs to be enabled for some variants of revision
+ <= r0p4. This workaround can lead the linker to emit ``*.stub`` sections
+ which are 4kB aligned.
+
- ``ERRATA_A53_855873``: This applies errata 855873 workaround to Cortex-A53
CPUs. Though the erratum is present in every revision of the CPU,
this workaround is only applied to CPUs from r0p3 onwards, which feature
diff --git a/docs/platform-migration-guide.rst b/docs/platform-migration-guide.rst
index 5e8eeba1..638033e4 100644
--- a/docs/platform-migration-guide.rst
+++ b/docs/platform-migration-guide.rst
@@ -146,6 +146,7 @@ for the ``plat_psci_ops`` structure which is declared as :
void (*cpu_standby)(plat_local_state_t cpu_state);
int (*pwr_domain_on)(u_register_t mpidr);
void (*pwr_domain_off)(const psci_power_state_t *target_state);
+ void (*pwr_domain_suspend_early)(const psci_power_state_t *target_state);
void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
void (*pwr_domain_suspend_finish)(
@@ -170,12 +171,12 @@ convert the power-state parameter (possibly encoding a composite power state)
passed in a PSCI ``CPU_SUSPEND`` to the ``psci_power_state`` format. This handler
is now mandatory for PSCI ``CPU_SUSPEND`` support.
-The ``plat_psci_ops`` handlers, ``pwr_domain_off`` and ``pwr_domain_suspend``, are
-passed the target local state for each affected power domain. The platform
-must execute operations specific to these target states. Similarly,
-``pwr_domain_on_finish`` and ``pwr_domain_suspend_finish`` are passed the local
-states of the affected power domains before wakeup. The platform
-must execute actions to restore these power domains from these specific
+The ``plat_psci_ops`` handlers, ``pwr_domain_off``, ``pwr_domain_suspend_early``
+and ``pwr_domain_suspend``, are passed the target local state for each affected
+power domain. The platform must execute operations specific to these target
+states. Similarly, ``pwr_domain_on_finish`` and ``pwr_domain_suspend_finish``
+are passed the local states of the affected power domains before wakeup. The
+platform must execute actions to restore these power domains from these specific
local states.
- Difference in invocation
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 66fe0f1d..bf8dea7b 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -60,11 +60,16 @@ A platform port must enable the Memory Management Unit (MMU) as well as the
instruction and data caches for each BL stage. Setting up the translation
tables is the responsibility of the platform port because memory maps differ
across platforms. A memory translation library (see ``lib/xlat_tables/``) is
-provided to help in this setup. Note that although this library supports
-non-identity mappings, this is intended only for re-mapping peripheral physical
-addresses and allows platforms with high I/O addresses to reduce their virtual
-address space. All other addresses corresponding to code and data must currently
-use an identity mapping.
+provided to help in this setup.
+
+Note that although this library supports non-identity mappings, this is intended
+only for re-mapping peripheral physical addresses and allows platforms with high
+I/O addresses to reduce their virtual address space. All other addresses
+corresponding to code and data must currently use an identity mapping.
+
+Also, the only translation granule size supported in Trusted Firmware is 4KB, as
+various parts of the code assume that is the case. It is not possible to switch
+to 16 KB or 64 KB granule sizes at the moment.
In ARM standard platforms, each BL stage configures the MMU in the
platform-specific architecture setup function, ``blX_plat_arch_setup()``, and uses
@@ -2055,6 +2060,23 @@ power down state where as it could be either power down, retention or run state
for the higher power domain levels depending on the result of state
coordination. The generic code expects the handler to succeed.
+plat\_psci\_ops.pwr\_domain\_suspend\_pwrdown\_early() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This optional function may be used as a performance optimization to replace
+or complement pwr_domain_suspend() on some platforms. Its calling semantics
+are identical to pwr_domain_suspend(), except the PSCI implementation only
+calls this function when suspending to a power down state, and it guarantees
+that data caches are enabled.
+
+When HW_ASSISTED_COHERENCY = 0, the PSCI implementation disables data caches
+before calling pwr_domain_suspend(). If the target_state corresponds to a
+power down state and it is safe to perform some or all of the platform
+specific actions in that function with data caches enabled, it may be more
+efficient to move those actions to this function. When HW_ASSISTED_COHERENCY
+= 1, data caches remain enabled throughout, and so there is no advantage to
+moving platform specific actions to this function.
+
plat\_psci\_ops.pwr\_domain\_suspend()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 6b82e3d1..ec8c2333 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -337,6 +337,11 @@ Common build options
Currently, only PSCI is instrumented. Enabling this option enables
the ``ENABLE_PMF`` build option as well. Default is 0.
+- ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling
+ extensions. This is an optional architectural feature available only for
+ AArch64 8.2 onwards. This option defaults to 1 but is automatically
+ disabled when the target architecture is AArch32 or AArch64 8.0/8.1.
+
- ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
checks in GCC. Allowed values are "all", "strong" and "0" (default).
"strong" is the recommended stack protection level if this feature is
@@ -563,11 +568,6 @@ Common build options
cluster platforms). If this option is enabled, then warm boot path
enables D-caches immediately after enabling MMU. This option defaults to 0.
-- ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling
- extensions. This is an optional architectural feature available only for
- AArch64 8.2 onwards. This option defaults to 1 but is automatically
- disabled when the target architecture is AArch32 or AArch64 8.0/8.1.
-
ARM development platform specific build options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index fee6a24f..0ed39c9a 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -267,6 +267,8 @@ typedef struct plat_psci_ops {
void (*cpu_standby)(plat_local_state_t cpu_state);
int (*pwr_domain_on)(u_register_t mpidr);
void (*pwr_domain_off)(const psci_power_state_t *target_state);
+ void (*pwr_domain_suspend_pwrdown_early)(
+ const psci_power_state_t *target_state);
void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
void (*pwr_domain_suspend_finish)(
diff --git a/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
new file mode 100644
index 00000000..a418d2dd
--- /dev/null
+++ b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
@@ -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__ */
diff --git a/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
new file mode 100644
index 00000000..7381bc82
--- /dev/null
+++ b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.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__ */
diff --git a/include/lib/xlat_tables/xlat_tables_arch.h b/include/lib/xlat_tables/xlat_tables_arch.h
new file mode 100644
index 00000000..165b161d
--- /dev/null
+++ b/include/lib/xlat_tables/xlat_tables_arch.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__ */
diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h
index 4b993a04..008ae9bc 100644
--- a/include/lib/xlat_tables/xlat_tables_defs.h
+++ b/include/lib/xlat_tables/xlat_tables_defs.h
@@ -48,7 +48,11 @@
#define TABLE_ADDR_MASK ULL(0x0000FFFFFFFFF000)
-#define PAGE_SIZE_SHIFT FOUR_KB_SHIFT /* 4, 16 or 64 KB */
+/*
+ * The ARMv8-A architecture allows translation granule sizes of 4KB, 16KB or
+ * 64KB. However, TF only supports the 4KB case at the moment.
+ */
+#define PAGE_SIZE_SHIFT FOUR_KB_SHIFT
#define PAGE_SIZE (U(1) << PAGE_SIZE_SHIFT)
#define PAGE_SIZE_MASK (PAGE_SIZE - 1)
#define IS_PAGE_ALIGNED(addr) (((addr) & PAGE_SIZE_MASK) == 0)
@@ -59,12 +63,6 @@
#define XLAT_TABLE_SIZE_SHIFT PAGE_SIZE_SHIFT /* Size of one complete table */
#define XLAT_TABLE_SIZE (U(1) << XLAT_TABLE_SIZE_SHIFT)
-#ifdef AARCH32
-#define XLAT_TABLE_LEVEL_MIN U(1)
-#else
-#define XLAT_TABLE_LEVEL_MIN U(0)
-#endif /* AARCH32 */
-
#define XLAT_TABLE_LEVEL_MAX U(3)
/* Values for number of entries in each MMU translation table */
diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index 9db67191..288a8e0b 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -13,6 +13,7 @@
#include <stddef.h>
#include <stdint.h>
#include <xlat_mmu_helpers.h>
+#include <xlat_tables_v2_helpers.h>
/* Helper macro to define entries for mmap_region_t. It creates
* identity mappings for each region.
@@ -82,7 +83,51 @@ typedef struct mmap_region {
mmap_attr_t attr;
} mmap_region_t;
-/* Generic translation table APIs */
+/*
+ * Declare the translation context type.
+ * Its definition is private.
+ */
+typedef struct xlat_ctx xlat_ctx_t;
+
+/*
+ * Statically allocate a translation context and associated structures. Also
+ * initialize them.
+ *
+ * _ctx_name:
+ * Prefix for the translation context variable.
+ * E.g. If _ctx_name is 'foo', the variable will be called 'foo_xlat_ctx'.
+ * Useful to distinguish multiple contexts from one another.
+ *
+ * _mmap_count:
+ * Number of mmap_region_t to allocate.
+ * Would typically be MAX_MMAP_REGIONS for the translation context describing
+ * the BL image currently executing.
+ *
+ * _xlat_tables_count:
+ * Number of sub-translation tables to allocate.
+ * Would typically be MAX_XLAT_TABLES for the translation context describing
+ * the BL image currently executing.
+ * Note that this is only for sub-tables ; at the initial lookup level, there
+ * is always a single table.
+ *
+ * _virt_addr_space_size, _phy_addr_space_size:
+ * Size (in bytes) of the virtual (resp. physical) address space.
+ * Would typically be PLAT_VIRT_ADDR_SPACE_SIZE
+ * (resp. PLAT_PHY_ADDR_SPACE_SIZE) for the translation context describing the
+ * BL image currently executing.
+ */
+#define REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \
+ _virt_addr_space_size, _phy_addr_space_size) \
+ _REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \
+ _virt_addr_space_size, _phy_addr_space_size)
+
+/******************************************************************************
+ * Generic translation table APIs.
+ * Each API comes in 2 variants:
+ * - one that acts on the current translation context for this BL image
+ * - another that acts on the given translation context instead. This variant
+ * is named after the 1st version, with an additional '_ctx' suffix.
+ *****************************************************************************/
/*
* Initialize translation tables from the current list of mmap regions. Calling
@@ -90,6 +135,7 @@ typedef struct mmap_region {
* longer be added.
*/
void init_xlat_tables(void);
+void init_xlat_tables_ctx(xlat_ctx_t *ctx);
/*
* Add a static region with defined base PA and base VA. This function can only
@@ -98,8 +144,19 @@ void init_xlat_tables(void);
*/
void mmap_add_region(unsigned long long base_pa, uintptr_t base_va,
size_t size, mmap_attr_t attr);
+void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm);
/*
+ * Add an array of static regions with defined base PA and base VA. This
+ * function can only be used before initializing the translation tables. The
+ * regions cannot be removed afterwards.
+ */
+void mmap_add(const mmap_region_t *mm);
+void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm);
+
+
+#if PLAT_XLAT_TABLES_DYNAMIC
+/*
* Add a dynamic region with defined base PA and base VA. This type of region
* can be added and removed even after the translation tables are initialized.
*
@@ -112,13 +169,7 @@ void mmap_add_region(unsigned long long base_pa, uintptr_t base_va,
*/
int mmap_add_dynamic_region(unsigned long long base_pa, uintptr_t base_va,
size_t size, mmap_attr_t attr);
-
-/*
- * Add an array of static regions with defined base PA and base VA. This
- * function can only be used before initializing the translation tables. The
- * regions cannot be removed afterwards.
- */
-void mmap_add(const mmap_region_t *mm);
+int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm);
/*
* Remove a region with the specified base VA and size. Only dynamic regions can
@@ -131,6 +182,11 @@ void mmap_add(const mmap_region_t *mm);
* EPERM: Trying to remove a static region.
*/
int mmap_remove_dynamic_region(uintptr_t base_va, size_t size);
+int mmap_remove_dynamic_region_ctx(xlat_ctx_t *ctx,
+ uintptr_t base_va,
+ size_t size);
+
+#endif /* PLAT_XLAT_TABLES_DYNAMIC */
#endif /*__ASSEMBLY__*/
#endif /* __XLAT_TABLES_V2_H__ */
diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
new file mode 100644
index 00000000..f5e31006
--- /dev/null
+++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.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__ */
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index 0b74cede..9d025f66 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -128,16 +128,22 @@
* an SCP_BL2/SCP_BL2U image.
*/
#if CSS_LOAD_SCP_IMAGES
+
+#if ARM_BL31_IN_DRAM
+#error "SCP_BL2 is not expected to be loaded by BL2 for ARM_BL31_IN_DRAM config"
+#endif
+
/*
* Load address of SCP_BL2 in CSS platform ports
- * SCP_BL2 is loaded to the same place as BL31. Once SCP_BL2 is transferred to the
- * SCP, it is discarded and BL31 is loaded over the top.
+ * SCP_BL2 is loaded to the same place as BL31 but it shouldn't overwrite BL1
+ * rw data. Once SCP_BL2 is transferred to the SCP, it is discarded and BL31
+ * is loaded over the top.
*/
-#define SCP_BL2_BASE BL31_BASE
-#define SCP_BL2_LIMIT (SCP_BL2_BASE + PLAT_CSS_MAX_SCP_BL2_SIZE)
+#define SCP_BL2_BASE (BL1_RW_BASE - PLAT_CSS_MAX_SCP_BL2_SIZE)
+#define SCP_BL2_LIMIT BL1_RW_BASE
-#define SCP_BL2U_BASE BL31_BASE
-#define SCP_BL2U_LIMIT (SCP_BL2U_BASE + PLAT_CSS_MAX_SCP_BL2U_SIZE)
+#define SCP_BL2U_BASE (BL1_RW_BASE - PLAT_CSS_MAX_SCP_BL2U_SIZE)
+#define SCP_BL2U_LIMIT BL1_RW_BASE
#endif /* CSS_LOAD_SCP_IMAGES */
/* Load address of Non-Secure Image for CSS platform ports */
diff --git a/include/plat/arm/soc/common/soc_css_def.h b/include/plat/arm/soc/common/soc_css_def.h
index dc3d7dc1..3206f4e2 100644
--- a/include/plat/arm/soc/common/soc_css_def.h
+++ b/include/plat/arm/soc/common/soc_css_def.h
@@ -24,8 +24,8 @@
#define SOC_CSS_UART0_BASE 0x7ff80000
#define SOC_CSS_UART1_BASE 0x7ff70000
-#define SOC_CSS_UART0_CLK_IN_HZ 7273800
-#define SOC_CSS_UART1_CLK_IN_HZ 7273800
+#define SOC_CSS_UART0_CLK_IN_HZ 7372800
+#define SOC_CSS_UART1_CLK_IN_HZ 7372800
/* SoC NIC-400 Global Programmers View (GPV) */
#define SOC_CSS_NIC400_BASE 0x7fd00000
diff --git a/lib/compiler-rt/builtins/ctzdi2.c b/lib/compiler-rt/builtins/ctzdi2.c
new file mode 100644
index 00000000..db3c6fdc
--- /dev/null
+++ b/lib/compiler-rt/builtins/ctzdi2.c
@@ -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)));
+}
diff --git a/lib/compiler-rt/compiler-rt.mk b/lib/compiler-rt/compiler-rt.mk
index 3bdd3190..cb5ab31c 100644
--- a/lib/compiler-rt/compiler-rt.mk
+++ b/lib/compiler-rt/compiler-rt.mk
@@ -30,5 +30,6 @@
ifeq (${ARCH},aarch32)
COMPILER_RT_SRCS := lib/compiler-rt/builtins/arm/aeabi_uldivmod.S \
- lib/compiler-rt/builtins/udivmoddi4.c
+ lib/compiler-rt/builtins/udivmoddi4.c \
+ lib/compiler-rt/builtins/ctzdi2.c
endif
diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c
index 16b22c2a..d3d0e2ff 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -64,7 +64,20 @@ int psci_cpu_on_start(u_register_t target_cpu,
/*
* Generic management: Ensure that the cpu is off to be
* turned on.
+ * Perform cache maintanence ahead of reading the target CPU state to
+ * ensure that the data is not stale.
+ * There is a theoretical edge case where the cache may contain stale
+ * data for the target CPU data - this can occur under the following
+ * conditions:
+ * - the target CPU is in another cluster from the current
+ * - the target CPU was the last CPU to shutdown on its cluster
+ * - the cluster was removed from coherency as part of the CPU shutdown
+ *
+ * In this case the cache maintenace that was performed as part of the
+ * target CPUs shutdown was not seen by the current CPU's cluster. And
+ * so the cache may contain stale data for the target CPU.
*/
+ flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
rc = cpu_on_validate_state(psci_get_aff_info_state_by_idx(target_idx));
if (rc != PSCI_E_SUCCESS)
goto exit;
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index 0d1589ee..40ecdeea 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -80,6 +80,17 @@ static void psci_suspend_to_pwrdown_start(unsigned int end_pwrlvl,
if (psci_spd_pm && psci_spd_pm->svc_suspend)
psci_spd_pm->svc_suspend(max_off_lvl);
+#if !HW_ASSISTED_COHERENCY
+ /*
+ * Plat. management: Allow the platform to perform any early
+ * actions required to power down the CPU. This might be useful for
+ * HW_ASSISTED_COHERENCY = 0 platforms that can safely perform these
+ * actions with data caches enabled.
+ */
+ if (psci_plat_pm_ops->pwr_domain_suspend_pwrdown_early)
+ psci_plat_pm_ops->pwr_domain_suspend_pwrdown_early(state_info);
+#endif
+
/*
* Store the re-entry information for the non-secure world.
*/
diff --git a/lib/stdlib/assert.c b/lib/stdlib/assert.c
index 41f70703..97fab4b0 100644
--- a/lib/stdlib/assert.c
+++ b/lib/stdlib/assert.c
@@ -17,14 +17,14 @@
#if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_VERBOSE
void __assert(const char *file, unsigned int line, const char *assertion)
{
- tf_printf("ASSERT: %s <%d> : %s\n", file, line, assertion);
+ tf_printf("ASSERT: %s:%d:%s\n", file, line, assertion);
console_flush();
plat_panic_handler();
}
#elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
void __assert(const char *file, unsigned int line)
{
- tf_printf("ASSERT: %s <%d>\n", file, line);
+ tf_printf("ASSERT: %s:%d\n", file, line);
console_flush();
plat_panic_handler();
}
diff --git a/lib/xlat_tables/aarch32/xlat_tables.c b/lib/xlat_tables/aarch32/xlat_tables.c
index 9c156240..c7e34f20 100644
--- a/lib/xlat_tables/aarch32/xlat_tables.c
+++ b/lib/xlat_tables/aarch32/xlat_tables.c
@@ -7,56 +7,17 @@
#include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
-#include <cassert.h>
#include <platform_def.h>
#include <utils.h>
+#include <xlat_tables_arch.h>
#include <xlat_tables.h>
#include "../xlat_tables_private.h"
-/*
- * 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."
+#define XLAT_TABLE_LEVEL_BASE \
+ GET_XLAT_TABLE_LEVEL_BASE(PLAT_VIRT_ADDR_SPACE_SIZE)
-#endif
+#define NUM_BASE_LEVEL_ENTRIES \
+ GET_NUM_BASE_LEVEL_ENTRIES(PLAT_VIRT_ADDR_SPACE_SIZE)
static uint64_t base_xlation_table[NUM_BASE_LEVEL_ENTRIES]
__aligned(NUM_BASE_LEVEL_ENTRIES * sizeof(uint64_t));
@@ -127,13 +88,13 @@ void enable_mmu_secure(unsigned int flags)
ttbcr = TTBCR_EAE_BIT |
TTBCR_SH0_NON_SHAREABLE | TTBCR_RGN0_OUTER_NC |
TTBCR_RGN0_INNER_NC |
- (32 - __builtin_ctzl((uintptr_t)PLAT_VIRT_ADDR_SPACE_SIZE));
+ (32 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE));
} else {
/* Inner & outer WBWA & shareable. */
ttbcr = TTBCR_EAE_BIT |
TTBCR_SH0_INNER_SHAREABLE | TTBCR_RGN0_OUTER_WBA |
TTBCR_RGN0_INNER_WBA |
- (32 - __builtin_ctzl((uintptr_t)PLAT_VIRT_ADDR_SPACE_SIZE));
+ (32 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE));
}
ttbcr |= TTBCR_EPD1_BIT;
write_ttbcr(ttbcr);
diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c
index 309cb9bd..2ddf8cba 100644
--- a/lib/xlat_tables/aarch64/xlat_tables.c
+++ b/lib/xlat_tables/aarch64/xlat_tables.c
@@ -8,66 +8,19 @@
#include <arch_helpers.h>
#include <assert.h>
#include <bl_common.h>
-#include <cassert.h>
#include <common_def.h>
#include <platform_def.h>
#include <sys/types.h>
#include <utils.h>
#include <xlat_tables.h>
+#include <xlat_tables_arch.h>
#include "../xlat_tables_private.h"
-/*
- * 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."
+#define XLAT_TABLE_LEVEL_BASE \
+ GET_XLAT_TABLE_LEVEL_BASE(PLAT_VIRT_ADDR_SPACE_SIZE)
-#endif
+#define NUM_BASE_LEVEL_ENTRIES \
+ GET_NUM_BASE_LEVEL_ENTRIES(PLAT_VIRT_ADDR_SPACE_SIZE)
static uint64_t base_xlation_table[NUM_BASE_LEVEL_ENTRIES]
__aligned(NUM_BASE_LEVEL_ENTRIES * sizeof(uint64_t));
@@ -192,12 +145,12 @@ void init_xlat_tables(void)
/* Inner & outer non-cacheable non-shareable. */\
tcr = TCR_SH_NON_SHAREABLE | \
TCR_RGN_OUTER_NC | TCR_RGN_INNER_NC | \
- (64 - __builtin_ctzl(PLAT_VIRT_ADDR_SPACE_SIZE));\
+ (64 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE));\
} else { \
/* Inner & outer WBWA & shareable. */ \
tcr = TCR_SH_INNER_SHAREABLE | \
TCR_RGN_OUTER_WBA | TCR_RGN_INNER_WBA | \
- (64 - __builtin_ctzl(PLAT_VIRT_ADDR_SPACE_SIZE));\
+ (64 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE));\
} \
tcr |= _tcr_extra; \
write_tcr_el##_el(tcr); \
diff --git a/lib/xlat_tables/xlat_tables_private.h b/lib/xlat_tables/xlat_tables_private.h
index b5c3ac84..50d6bd59 100644
--- a/lib/xlat_tables/xlat_tables_private.h
+++ b/lib/xlat_tables/xlat_tables_private.h
@@ -9,7 +9,7 @@
#include <cassert.h>
#include <platform_def.h>
-#include <utils_def.h>
+#include <xlat_tables_arch.h>
/*
* If the platform hasn't defined a physical and a virtual address space size
@@ -28,41 +28,14 @@
# endif
#endif
-/* The virtual and physical address space sizes must be powers of two. */
-CASSERT(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE),
+CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(PLAT_VIRT_ADDR_SPACE_SIZE),
assert_valid_virt_addr_space_size);
-CASSERT(IS_POWER_OF_TWO(PLAT_PHY_ADDR_SPACE_SIZE),
- assert_valid_phy_addr_space_size);
-
-/*
- * 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.
- *
- * 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.
- */
-#ifdef AARCH32
-
-# define XLAT_BLOCK_LEVEL_MIN 1
-
-#else /* if AArch64 */
-
-# if PAGE_SIZE == (4*1024) /* 4KB */
-# define XLAT_BLOCK_LEVEL_MIN 1
-# else /* 16KB or 64KB */
-# define XLAT_BLOCK_LEVEL_MIN 2
-# endif
+CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(PLAT_PHY_ADDR_SPACE_SIZE),
+ assert_valid_phy_addr_space_size);
-#endif /* AARCH32 */
+/* Alias to retain compatibility with the old #define name */
+#define XLAT_BLOCK_LEVEL_MIN MIN_LVL_BLOCK_DESC
void print_mmap(void);
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index 40fd2d0b..be18552e 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
@@ -14,7 +14,7 @@
#include "../xlat_tables_private.h"
#if ENABLE_ASSERTIONS
-static unsigned long long xlat_arch_get_max_supported_pa(void)
+unsigned long long xlat_arch_get_max_supported_pa(void)
{
/* Physical address space size for long descriptor format. */
return (1ull << 40) - 1ull;
@@ -81,24 +81,22 @@ uint64_t xlat_arch_get_xn_desc(int el __unused)
return UPPER_ATTRS(XN);
}
-void init_xlat_tables_arch(unsigned long long max_pa)
-{
- assert((PLAT_PHY_ADDR_SPACE_SIZE - 1) <=
- xlat_arch_get_max_supported_pa());
-}
-
/*******************************************************************************
- * Function for enabling the MMU in Secure PL1, assuming that the
- * page-tables have already been created.
+ * Function for enabling the MMU in Secure PL1, assuming that the page tables
+ * have already been created.
******************************************************************************/
-void enable_mmu_internal_secure(unsigned int flags, uint64_t *base_table)
-
+void enable_mmu_arch(unsigned int flags,
+ uint64_t *base_table,
+ unsigned long long max_pa,
+ uintptr_t max_va)
{
u_register_t mair0, ttbcr, sctlr;
uint64_t ttbr0;
assert(IS_IN_SECURE());
- assert((read_sctlr() & SCTLR_M_BIT) == 0);
+
+ sctlr = read_sctlr();
+ assert((sctlr & SCTLR_M_BIT) == 0);
/* Invalidate TLBs at the current exception level */
tlbiall();
@@ -109,29 +107,56 @@ void enable_mmu_internal_secure(unsigned int flags, uint64_t *base_table)
ATTR_IWBWA_OWBWA_NTR_INDEX);
mair0 |= MAIR0_ATTR_SET(ATTR_NON_CACHEABLE,
ATTR_NON_CACHEABLE_INDEX);
- write_mair0(mair0);
/*
- * Set TTBCR bits as well. Set TTBR0 table properties. Disable TTBR1.
+ * Configure the control register for stage 1 of the PL1&0 translation
+ * regime.
+ */
+
+ /* Use the Long-descriptor translation table format. */
+ ttbcr = TTBCR_EAE_BIT;
+
+ /*
+ * Disable translation table walk for addresses that are translated
+ * using TTBR1. Therefore, only TTBR0 is used.
+ */
+ ttbcr |= TTBCR_EPD1_BIT;
+
+ /*
+ * Limit the input address ranges and memory region sizes translated
+ * using TTBR0 to the given virtual address space size, if smaller than
+ * 32 bits.
+ */
+ if (max_va != UINT32_MAX) {
+ uintptr_t virtual_addr_space_size = max_va + 1;
+ assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
+ /*
+ * __builtin_ctzll(0) is undefined but here we are guaranteed
+ * that virtual_addr_space_size is in the range [1, UINT32_MAX].
+ */
+ ttbcr |= 32 - __builtin_ctzll(virtual_addr_space_size);
+ }
+
+ /*
+ * Set the cacheability and shareability attributes for memory
+ * associated with translation table walks using TTBR0.
*/
if (flags & XLAT_TABLE_NC) {
/* Inner & outer non-cacheable non-shareable. */
- ttbcr = TTBCR_EAE_BIT |
- TTBCR_SH0_NON_SHAREABLE | TTBCR_RGN0_OUTER_NC |
- TTBCR_RGN0_INNER_NC |
- (32 - __builtin_ctzl((uintptr_t)PLAT_VIRT_ADDR_SPACE_SIZE));
+ ttbcr |= TTBCR_SH0_NON_SHAREABLE | TTBCR_RGN0_OUTER_NC |
+ TTBCR_RGN0_INNER_NC;
} else {
/* Inner & outer WBWA & shareable. */
- ttbcr = TTBCR_EAE_BIT |
- TTBCR_SH0_INNER_SHAREABLE | TTBCR_RGN0_OUTER_WBA |
- TTBCR_RGN0_INNER_WBA |
- (32 - __builtin_ctzl((uintptr_t)PLAT_VIRT_ADDR_SPACE_SIZE));
+ ttbcr |= TTBCR_SH0_INNER_SHAREABLE | TTBCR_RGN0_OUTER_WBA |
+ TTBCR_RGN0_INNER_WBA;
}
- ttbcr |= TTBCR_EPD1_BIT;
- write_ttbcr(ttbcr);
/* Set TTBR0 bits as well */
ttbr0 = (uint64_t)(uintptr_t) base_table;
+
+ /* Now program the relevant system registers */
+ write_mair0(mair0);
+ write_ttbcr(ttbcr);
write64_ttbr0(ttbr0);
write64_ttbr1(0);
@@ -144,7 +169,6 @@ void enable_mmu_internal_secure(unsigned int flags, uint64_t *base_table)
dsbish();
isb();
- sctlr = read_sctlr();
sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT;
if (flags & DISABLE_DCACHE)
@@ -157,8 +181,3 @@ void enable_mmu_internal_secure(unsigned int flags, uint64_t *base_table)
/* Ensure the MMU enable takes effect immediately */
isb();
}
-
-void enable_mmu_arch(unsigned int flags, uint64_t *base_table)
-{
- enable_mmu_internal_secure(flags, base_table);
-}
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.h b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.h
deleted file mode 100644
index f75ab791..00000000
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.h
+++ /dev/null
@@ -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__ */
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 14f6cd6a..61eac106 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -22,8 +22,6 @@
# define IMAGE_EL 1
#endif
-static unsigned long long tcr_ps_bits;
-
static unsigned long long calc_physical_addr_size_bits(
unsigned long long max_addr)
{
@@ -60,7 +58,7 @@ static const unsigned int pa_range_bits_arr[] = {
PARANGE_0101
};
-static unsigned long long xlat_arch_get_max_supported_pa(void)
+unsigned long long xlat_arch_get_max_supported_pa(void)
{
u_register_t pa_range = read_id_aa64mmfr0_el1() &
ID_AA64MMFR0_EL1_PARANGE_MASK;
@@ -146,73 +144,28 @@ uint64_t xlat_arch_get_xn_desc(int el)
}
}
-void init_xlat_tables_arch(unsigned long long max_pa)
-{
- assert((PLAT_PHY_ADDR_SPACE_SIZE - 1) <=
- xlat_arch_get_max_supported_pa());
-
- /*
- * If dynamic allocation of new regions is enabled the code can't make
- * assumptions about the max physical address because it could change
- * after adding new regions. If this functionality is disabled it is
- * safer to restrict the max physical address as much as possible.
- */
-#ifdef PLAT_XLAT_TABLES_DYNAMIC
- tcr_ps_bits = calc_physical_addr_size_bits(PLAT_PHY_ADDR_SPACE_SIZE);
-#else
- tcr_ps_bits = calc_physical_addr_size_bits(max_pa);
-#endif
-}
-
/*******************************************************************************
* Macro generating the code for the function enabling the MMU in the given
* exception level, assuming that the pagetables have already been created.
*
* _el: Exception level at which the function will run
- * _tcr_extra: Extra bits to set in the TCR register. This mask will
- * be OR'ed with the default TCR value.
* _tlbi_fct: Function to invalidate the TLBs at the current
* exception level
******************************************************************************/
-#define DEFINE_ENABLE_MMU_EL(_el, _tcr_extra, _tlbi_fct) \
- void enable_mmu_internal_el##_el(unsigned int flags, \
- uint64_t *base_table) \
+#define DEFINE_ENABLE_MMU_EL(_el, _tlbi_fct) \
+ static void enable_mmu_internal_el##_el(int flags, \
+ uint64_t mair, \
+ uint64_t tcr, \
+ uint64_t ttbr) \
{ \
- uint64_t mair, tcr, ttbr; \
- uint32_t sctlr; \
- \
- assert(IS_IN_EL(_el)); \
- assert((read_sctlr_el##_el() & SCTLR_M_BIT) == 0); \
+ uint32_t sctlr = read_sctlr_el##_el(); \
+ assert((sctlr & SCTLR_M_BIT) == 0); \
\
/* Invalidate TLBs at the current exception level */ \
_tlbi_fct(); \
\
- /* Set attributes in the right indices of the MAIR */ \
- mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); \
- mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, \
- ATTR_IWBWA_OWBWA_NTR_INDEX); \
- mair |= MAIR_ATTR_SET(ATTR_NON_CACHEABLE, \
- ATTR_NON_CACHEABLE_INDEX); \
write_mair_el##_el(mair); \
- \
- /* Set TCR bits as well. */ \
- /* Set T0SZ to (64 - width of virtual address space) */ \
- if (flags & XLAT_TABLE_NC) { \
- /* Inner & outer non-cacheable non-shareable. */\
- tcr = TCR_SH_NON_SHAREABLE | \
- TCR_RGN_OUTER_NC | TCR_RGN_INNER_NC | \
- (64 - __builtin_ctzl(PLAT_VIRT_ADDR_SPACE_SIZE));\
- } else { \
- /* Inner & outer WBWA & shareable. */ \
- tcr = TCR_SH_INNER_SHAREABLE | \
- TCR_RGN_OUTER_WBA | TCR_RGN_INNER_WBA | \
- (64 - __builtin_ctzl(PLAT_VIRT_ADDR_SPACE_SIZE));\
- } \
- tcr |= _tcr_extra; \
write_tcr_el##_el(tcr); \
- \
- /* Set TTBR bits as well */ \
- ttbr = (uint64_t) base_table; \
write_ttbr0_el##_el(ttbr); \
\
/* Ensure all translation table writes have drained */ \
@@ -222,9 +175,7 @@ void init_xlat_tables_arch(unsigned long long max_pa)
dsbish(); \
isb(); \
\
- sctlr = read_sctlr_el##_el(); \
sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT; \
- \
if (flags & DISABLE_DCACHE) \
sctlr &= ~SCTLR_C_BIT; \
else \
@@ -238,22 +189,69 @@ void init_xlat_tables_arch(unsigned long long max_pa)
/* Define EL1 and EL3 variants of the function enabling the MMU */
#if IMAGE_EL == 1
-DEFINE_ENABLE_MMU_EL(1,
- (tcr_ps_bits << TCR_EL1_IPS_SHIFT),
- tlbivmalle1)
+DEFINE_ENABLE_MMU_EL(1, tlbivmalle1)
#elif IMAGE_EL == 3
-DEFINE_ENABLE_MMU_EL(3,
- TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT),
- tlbialle3)
+DEFINE_ENABLE_MMU_EL(3, tlbialle3)
#endif
-void enable_mmu_arch(unsigned int flags, uint64_t *base_table)
+void enable_mmu_arch(unsigned int flags,
+ uint64_t *base_table,
+ unsigned long long max_pa,
+ uintptr_t max_va)
{
+ uint64_t mair, ttbr, tcr;
+
+ /* Set attributes in the right indices of the MAIR. */
+ mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);
+ mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, ATTR_IWBWA_OWBWA_NTR_INDEX);
+ mair |= MAIR_ATTR_SET(ATTR_NON_CACHEABLE, ATTR_NON_CACHEABLE_INDEX);
+
+ ttbr = (uint64_t) base_table;
+
+ /*
+ * Set TCR bits as well.
+ */
+
+ /*
+ * Limit the input address ranges and memory region sizes translated
+ * using TTBR0 to the given virtual address space size.
+ */
+ assert(max_va < UINTPTR_MAX);
+ uintptr_t virtual_addr_space_size = max_va + 1;
+ assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
+ /*
+ * __builtin_ctzll(0) is undefined but here we are guaranteed that
+ * virtual_addr_space_size is in the range [1,UINTPTR_MAX].
+ */
+ tcr = 64 - __builtin_ctzll(virtual_addr_space_size);
+
+ /*
+ * Set the cacheability and shareability attributes for memory
+ * associated with translation table walks.
+ */
+ if (flags & XLAT_TABLE_NC) {
+ /* Inner & outer non-cacheable non-shareable. */
+ tcr |= TCR_SH_NON_SHAREABLE |
+ TCR_RGN_OUTER_NC | TCR_RGN_INNER_NC;
+ } else {
+ /* Inner & outer WBWA & shareable. */
+ tcr |= TCR_SH_INNER_SHAREABLE |
+ TCR_RGN_OUTER_WBA | TCR_RGN_INNER_WBA;
+ }
+
+ /*
+ * It is safer to restrict the max physical address accessible by the
+ * hardware as much as possible.
+ */
+ unsigned long long tcr_ps_bits = calc_physical_addr_size_bits(max_pa);
+
#if IMAGE_EL == 1
assert(IS_IN_EL(1));
- enable_mmu_internal_el1(flags, base_table);
+ tcr |= tcr_ps_bits << TCR_EL1_IPS_SHIFT;
+ enable_mmu_internal_el1(flags, mair, tcr, ttbr);
#elif IMAGE_EL == 3
assert(IS_IN_EL(3));
- enable_mmu_internal_el3(flags, base_table);
+ tcr |= TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT);
+ enable_mmu_internal_el3(flags, mair, tcr, ttbr);
#endif
}
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.h b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.h
deleted file mode 100644
index caccb736..00000000
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.h
+++ /dev/null
@@ -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__ */
diff --git a/lib/xlat_tables_v2/xlat_tables.mk b/lib/xlat_tables_v2/xlat_tables.mk
index 4f804341..b94ce5d0 100644
--- a/lib/xlat_tables_v2/xlat_tables.mk
+++ b/lib/xlat_tables_v2/xlat_tables.mk
@@ -6,5 +6,4 @@
XLAT_TABLES_LIB_SRCS := $(addprefix lib/xlat_tables_v2/, \
${ARCH}/xlat_tables_arch.c \
- xlat_tables_common.c \
xlat_tables_internal.c)
diff --git a/lib/xlat_tables_v2/xlat_tables_common.c b/lib/xlat_tables_v2/xlat_tables_common.c
deleted file mode 100644
index f20bf93a..00000000
--- a/lib/xlat_tables_v2/xlat_tables_common.c
+++ /dev/null
@@ -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 */
diff --git a/lib/xlat_tables_v2/xlat_tables_internal.c b/lib/xlat_tables_v2/xlat_tables_internal.c
index f60d78c1..cd6e11c0 100644
--- a/lib/xlat_tables_v2/xlat_tables_internal.c
+++ b/lib/xlat_tables_v2/xlat_tables_internal.c
@@ -7,7 +7,6 @@
#include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
-#include <cassert.h>
#include <common_def.h>
#include <debug.h>
#include <errno.h>
@@ -15,14 +14,37 @@
#include <string.h>
#include <types.h>
#include <utils.h>
+#include <xlat_tables_arch.h>
+#include <xlat_tables_defs.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"
+/*
+ * Each platform can define the size of its physical and virtual address spaces.
+ * If the platform hasn't defined one or both of them, default to
+ * ADDR_SPACE_SIZE. The latter is deprecated, though.
+ */
+#if ERROR_DEPRECATED
+# ifdef ADDR_SPACE_SIZE
+# error "ADDR_SPACE_SIZE is deprecated. Use PLAT_xxx_ADDR_SPACE_SIZE instead."
+# endif
+#elif defined(ADDR_SPACE_SIZE)
+# ifndef PLAT_PHY_ADDR_SPACE_SIZE
+# define PLAT_PHY_ADDR_SPACE_SIZE ADDR_SPACE_SIZE
+# endif
+# ifndef PLAT_VIRT_ADDR_SPACE_SIZE
+# define PLAT_VIRT_ADDR_SPACE_SIZE ADDR_SPACE_SIZE
+# endif
+#endif
+
+/*
+ * Allocate and initialise the default translation context for the BL image
+ * currently executing.
+ */
+REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES,
+ PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE);
+
#if PLAT_XLAT_TABLES_DYNAMIC
/*
@@ -335,7 +357,7 @@ static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
*/
static action_t xlat_tables_map_region_action(const mmap_region_t *mm,
const int desc_type, const unsigned long long dest_pa,
- const uintptr_t table_entry_base_va, const int level)
+ const uintptr_t table_entry_base_va, const unsigned int level)
{
uintptr_t mm_end_va = mm->base_va + mm->size - 1;
uintptr_t table_entry_end_va =
@@ -666,7 +688,7 @@ static int mmap_add_region_check(xlat_ctx_t *ctx, unsigned long long base_pa,
return 0;
}
-void mmap_add_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
+void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
{
mmap_region_t *mm_cursor = ctx->mmap;
mmap_region_t *mm_last = mm_cursor + ctx->mmap_num;
@@ -743,6 +765,34 @@ void mmap_add_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
ctx->max_va = end_va;
}
+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, &mm);
+}
+
+
+void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
+{
+ while (mm->size) {
+ mmap_add_region_ctx(ctx, mm);
+ mm++;
+ }
+}
+
+void mmap_add(const mmap_region_t *mm)
+{
+ mmap_add_ctx(&tf_xlat_ctx, mm);
+}
+
#if PLAT_XLAT_TABLES_DYNAMIC
int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
@@ -839,6 +889,18 @@ int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
return 0;
}
+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);
+}
+
/*
* Removes the region with given base Virtual Address and size from the given
* context.
@@ -914,6 +976,12 @@ int mmap_remove_dynamic_region_ctx(xlat_ctx_t *ctx, uintptr_t base_va,
return 0;
}
+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 */
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
@@ -1042,15 +1110,47 @@ static void xlat_tables_print_internal(const uintptr_t table_base_va,
void xlat_tables_print(xlat_ctx_t *ctx)
{
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+ VERBOSE("Translation tables state:\n");
+ VERBOSE(" Max allowed PA: 0x%llx\n", ctx->pa_max_address);
+ VERBOSE(" Max allowed VA: %p\n", (void *) ctx->va_max_address);
+ VERBOSE(" Max mapped PA: 0x%llx\n", ctx->max_pa);
+ VERBOSE(" Max mapped VA: %p\n", (void *) ctx->max_va);
+
+ VERBOSE(" Initial lookup level: %i\n", ctx->base_level);
+ VERBOSE(" Entries @initial lookup level: %i\n",
+ ctx->base_table_entries);
+
+ int used_page_tables;
+#if PLAT_XLAT_TABLES_DYNAMIC
+ used_page_tables = 0;
+ for (unsigned int i = 0; i < ctx->tables_num; ++i) {
+ if (ctx->tables_mapped_regions[i] != 0)
+ ++used_page_tables;
+ }
+#else
+ used_page_tables = ctx->next_table;
+#endif
+ VERBOSE(" Used %i sub-tables out of %i (spare: %i)\n",
+ used_page_tables, ctx->tables_num,
+ ctx->tables_num - used_page_tables);
+
xlat_tables_print_internal(0, ctx->base_table, ctx->base_table_entries,
ctx->base_level, ctx->execute_never_mask);
#endif /* LOG_LEVEL >= LOG_LEVEL_VERBOSE */
}
-void init_xlation_table(xlat_ctx_t *ctx)
+void init_xlat_tables_ctx(xlat_ctx_t *ctx)
{
mmap_region_t *mm = ctx->mmap;
+ assert(!is_mmu_enabled());
+ assert(!ctx->initialized);
+
+ print_mmap(mm);
+
+ ctx->execute_never_mask =
+ xlat_arch_get_xn_desc(xlat_arch_current_el());
+
/* All tables must be zeroed before mapping any region. */
for (unsigned int i = 0; i < ctx->base_table_entries; i++)
@@ -1078,5 +1178,57 @@ void init_xlation_table(xlat_ctx_t *ctx)
mm++;
}
+ assert(ctx->pa_max_address <= xlat_arch_get_max_supported_pa());
+ assert(ctx->max_va <= ctx->va_max_address);
+ assert(ctx->max_pa <= ctx->pa_max_address);
+
ctx->initialized = 1;
+
+ xlat_tables_print(ctx);
+}
+
+void init_xlat_tables(void)
+{
+ init_xlat_tables_ctx(&tf_xlat_ctx);
+}
+
+/*
+ * If dynamic allocation of new regions is disabled then by the time we call the
+ * function enabling the MMU, we'll have registered all the memory regions to
+ * map for the system's lifetime. Therefore, at this point we know the maximum
+ * physical address that will ever be mapped.
+ *
+ * If dynamic allocation is enabled then we can't make any such assumption
+ * because the maximum physical address could get pushed while adding a new
+ * region. Therefore, in this case we have to assume that the whole address
+ * space size might be mapped.
+ */
+#ifdef PLAT_XLAT_TABLES_DYNAMIC
+#define MAX_PHYS_ADDR tf_xlat_ctx.pa_max_address
+#else
+#define MAX_PHYS_ADDR tf_xlat_ctx.max_pa
+#endif
+
+#ifdef AARCH32
+
+void enable_mmu_secure(unsigned int flags)
+{
+ enable_mmu_arch(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+ tf_xlat_ctx.va_max_address);
}
+
+#else
+
+void enable_mmu_el1(unsigned int flags)
+{
+ enable_mmu_arch(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+ tf_xlat_ctx.va_max_address);
+}
+
+void enable_mmu_el3(unsigned int flags)
+{
+ enable_mmu_arch(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+ tf_xlat_ctx.va_max_address);
+}
+
+#endif /* AARCH32 */
diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h
index 83e0b6ea..d352583c 100644
--- a/lib/xlat_tables_v2/xlat_tables_private.h
+++ b/lib/xlat_tables_v2/xlat_tables_private.h
@@ -7,99 +7,8 @@
#ifndef __XLAT_TABLES_PRIVATE_H__
#define __XLAT_TABLES_PRIVATE_H__
-#include <cassert.h>
#include <platform_def.h>
-#include <utils_def.h>
-
-/*
- * If the platform hasn't defined a physical and a virtual address space size
- * default to ADDR_SPACE_SIZE.
- */
-#if ERROR_DEPRECATED
-# ifdef ADDR_SPACE_SIZE
-# error "ADDR_SPACE_SIZE is deprecated. Use PLAT_xxx_ADDR_SPACE_SIZE instead."
-# endif
-#elif defined(ADDR_SPACE_SIZE)
-# ifndef PLAT_PHY_ADDR_SPACE_SIZE
-# define PLAT_PHY_ADDR_SPACE_SIZE ADDR_SPACE_SIZE
-# endif
-# ifndef PLAT_VIRT_ADDR_SPACE_SIZE
-# define PLAT_VIRT_ADDR_SPACE_SIZE ADDR_SPACE_SIZE
-# endif
-#endif
-
-/* The virtual and physical address space sizes must be powers of two. */
-CASSERT(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE),
- assert_valid_virt_addr_space_size);
-CASSERT(IS_POWER_OF_TWO(PLAT_PHY_ADDR_SPACE_SIZE),
- assert_valid_phy_addr_space_size);
-
-/* Struct that holds all information about the translation tables. */
-typedef struct {
-
- /*
- * 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.
- */
- mmap_region_t *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;
-
-} xlat_ctx_t;
+#include <xlat_tables_defs.h>
#if PLAT_XLAT_TABLES_DYNAMIC
/*
@@ -138,13 +47,6 @@ void xlat_arch_tlbi_va(uintptr_t va);
*/
void xlat_arch_tlbi_va_sync(void);
-/* Add a dynamic region to the specified context. */
-int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm);
-
-/* Remove a dynamic region from the specified context. */
-int mmap_remove_dynamic_region_ctx(xlat_ctx_t *ctx, uintptr_t base_va,
- size_t size);
-
#endif /* PLAT_XLAT_TABLES_DYNAMIC */
/* Print VA, PA, size and attributes of all regions in the mmap array. */
@@ -157,15 +59,6 @@ void print_mmap(mmap_region_t *const mmap);
void xlat_tables_print(xlat_ctx_t *ctx);
/*
- * Initialize the translation tables by mapping all regions added to the
- * specified context.
- */
-void init_xlation_table(xlat_ctx_t *ctx);
-
-/* Add a static region to the specified context. */
-void mmap_add_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm);
-
-/*
* Architecture-specific initialization code.
*/
@@ -179,11 +72,15 @@ int xlat_arch_current_el(void);
*/
uint64_t xlat_arch_get_xn_desc(int el);
-/* Execute architecture-specific translation table initialization code. */
-void init_xlat_tables_arch(unsigned long long max_pa);
+/*
+ * Return the maximum physical address supported by the hardware.
+ * This value depends on the execution state (AArch32/AArch64).
+ */
+unsigned long long xlat_arch_get_max_supported_pa(void);
/* Enable MMU and configure it to use the specified translation tables. */
-void enable_mmu_arch(unsigned int flags, uint64_t *base_table);
+void enable_mmu_arch(unsigned int flags, uint64_t *base_table,
+ unsigned long long pa, uintptr_t max_va);
/* Return 1 if the MMU of this Exception Level is enabled, 0 otherwise. */
int is_mmu_enabled(void);
diff --git a/plat/arm/board/common/board_css_common.c b/plat/arm/board/common/board_css_common.c
index 42f754e2..f6a554f3 100644
--- a/plat/arm/board/common/board_css_common.c
+++ b/plat/arm/board/common/board_css_common.c
@@ -19,6 +19,7 @@ const mmap_region_t plat_arm_mmap[] = {
CSS_MAP_DEVICE,
SOC_CSS_MAP_DEVICE,
#if TRUSTED_BOARD_BOOT
+ /* Map DRAM to authenticate NS_BL2U image. */
ARM_MAP_NS_DRAM1,
#endif
{0}
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index eb37f113..2f5d7fcf 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -36,6 +36,10 @@ arm_config_t arm_config;
DEVICE1_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
+/*
+ * Need to be mapped with write permissions in order to set a new non-volatile
+ * counter value.
+ */
#define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \
DEVICE2_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
@@ -56,8 +60,10 @@ const mmap_region_t plat_arm_mmap[] = {
V2M_MAP_IOFPGA,
MAP_DEVICE0,
MAP_DEVICE1,
- MAP_DEVICE2,
#if TRUSTED_BOARD_BOOT
+ /* To access the Root of Trust Public Key registers. */
+ MAP_DEVICE2,
+ /* Map DRAM to authenticate NS_BL2U image. */
ARM_MAP_NS_DRAM1,
#endif
{0}
@@ -70,9 +76,12 @@ const mmap_region_t plat_arm_mmap[] = {
V2M_MAP_IOFPGA,
MAP_DEVICE0,
MAP_DEVICE1,
- MAP_DEVICE2,
ARM_MAP_NS_DRAM1,
ARM_MAP_TSP_SEC_MEM,
+#if TRUSTED_BOARD_BOOT
+ /* To access the Root of Trust Public Key registers. */
+ MAP_DEVICE2,
+#endif
#if ARM_BL31_IN_DRAM
ARM_MAP_BL31_SEC_DRAM,
#endif
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index ea128b6e..46afb71e 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -106,7 +106,7 @@
* little space for growth.
*/
#if TRUSTED_BOARD_BOOT
-# define PLAT_ARM_MAX_BL2_SIZE 0x1D000
+# define PLAT_ARM_MAX_BL2_SIZE 0x18000
#else
# define PLAT_ARM_MAX_BL2_SIZE 0xC000
#endif
@@ -172,13 +172,13 @@
* PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
* SCP_BL2 size plus a little space for growth.
*/
-#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x1D000
+#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x14000
/*
* PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
* SCP_BL2U size plus a little space for growth.
*/
-#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x1D000
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x14000
/*
* Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
diff --git a/plat/arm/css/common/css_bl2_setup.c b/plat/arm/css/common/css_bl2_setup.c
index 73549aa0..0712e3a9 100644
--- a/plat/arm/css/common/css_bl2_setup.c
+++ b/plat/arm/css/common/css_bl2_setup.c
@@ -11,7 +11,7 @@
#include <plat_arm.h>
#include <string.h>
#include <utils.h>
-#include "css_scp_bootloader.h"
+#include "../drivers/scp/css_scp.h"
/* Weak definition may be overridden in specific CSS based platform */
#if LOAD_IMAGE_V2
@@ -34,10 +34,13 @@ int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info)
INFO("BL2: Initiating SCP_BL2 transfer to SCP\n");
- ret = scp_bootloader_transfer((void *)scp_bl2_image_info->image_base,
+ ret = css_scp_boot_image_xfer((void *)scp_bl2_image_info->image_base,
scp_bl2_image_info->image_size);
if (ret == 0)
+ ret = css_scp_boot_ready();
+
+ if (ret == 0)
INFO("BL2: SCP_BL2 transferred to SCP\n");
else
ERROR("BL2: SCP_BL2 transfer failure\n");
diff --git a/plat/arm/css/common/css_bl2u_setup.c b/plat/arm/css/common/css_bl2u_setup.c
index cc187582..d225151b 100644
--- a/plat/arm/css/common/css_bl2u_setup.c
+++ b/plat/arm/css/common/css_bl2u_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,7 +7,7 @@
#include <bl_common.h>
#include <debug.h>
#include <plat_arm.h>
-#include "css_scp_bootloader.h"
+#include "../drivers/scp/css_scp.h"
/* Weak definition may be overridden in specific CSS based platform */
#pragma weak bl2u_plat_handle_scp_bl2u
@@ -40,10 +40,13 @@ int bl2u_plat_handle_scp_bl2u(void)
INFO("BL2U: Initiating SCP_BL2U transfer to SCP\n");
- ret = scp_bootloader_transfer((void *)scp_bl2u_image_info.image_base,
+ ret = css_scp_boot_image_xfer((void *)scp_bl2u_image_info.image_base,
scp_bl2u_image_info.image_size);
if (ret == 0)
+ ret = css_scp_boot_ready();
+
+ if (ret == 0)
INFO("BL2U: SCP_BL2U transferred to SCP\n");
else
ERROR("BL2U: SCP_BL2U transfer failure\n");
diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk
index c2ae9215..9381e4cd 100644
--- a/plat/arm/css/common/css_common.mk
+++ b/plat/arm/css/common/css_common.mk
@@ -56,8 +56,8 @@ ifeq (${CSS_LOAD_SCP_IMAGES},1)
$(eval $(call FWU_FIP_ADD_IMG,SCP_BL2U,--scp-fwu-cfg))
endif
- BL2U_SOURCES += plat/arm/css/common/css_scp_bootloader.c
- BL2_SOURCES += plat/arm/css/common/css_scp_bootloader.c
+ BL2U_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c
+ BL2_SOURCES += plat/arm/css/drivers/scp/css_bom_bootloader.c
endif
# Enable option to detect whether the SCP ROM firmware in use predates version
diff --git a/plat/arm/css/common/css_scp_bootloader.h b/plat/arm/css/common/css_scp_bootloader.h
deleted file mode 100644
index 0d6a6a2a..00000000
--- a/plat/arm/css/common/css_scp_bootloader.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __CSS_SCP_BOOTLOADER_H__
-#define __CSS_SCP_BOOTLOADER_H__
-
-int scp_bootloader_transfer(void *image, unsigned int image_size);
-
-#endif /* __CSS_SCP_BOOTLOADER_H__ */
diff --git a/plat/arm/css/common/css_scp_bootloader.c b/plat/arm/css/drivers/scp/css_bom_bootloader.c
index 3db5cf58..047e0696 100644
--- a/plat/arm/css/common/css_scp_bootloader.c
+++ b/plat/arm/css/drivers/scp/css_bom_bootloader.c
@@ -1,18 +1,17 @@
/*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <assert.h>
+#include <cassert.h>
#include <css_def.h>
#include <debug.h>
#include <platform.h>
#include <stdint.h>
-#include "../drivers/scpi/css_mhu.h"
-#include "../drivers/scpi/css_scpi.h"
-#include "css_scp_bootloader.h"
+#include "../scpi/css_mhu.h"
/* ID of the MHU slot used for the BOM protocol */
#define BOM_MHU_SLOT_ID 0
@@ -46,6 +45,18 @@ typedef struct {
uint32_t block_size;
} cmd_data_payload_t;
+/*
+ * All CSS platforms load SCP_BL2/SCP_BL2U just below BL rw-data and above
+ * BL2/BL2U (this is where BL31 usually resides except when ARM_BL31_IN_DRAM is
+ * set. Ensure that SCP_BL2/SCP_BL2U do not overflow into BL1 rw-data nor
+ * BL2/BL2U.
+ */
+CASSERT(SCP_BL2_LIMIT <= BL1_RW_BASE, assert_scp_bl2_overwrite_bl1);
+CASSERT(SCP_BL2U_LIMIT <= BL1_RW_BASE, assert_scp_bl2u_overwrite_bl1);
+
+CASSERT(SCP_BL2_BASE >= BL2_LIMIT, assert_scp_bl2_overwrite_bl2);
+CASSERT(SCP_BL2U_BASE >= BL2U_LIMIT, assert_scp_bl2u_overwrite_bl2u);
+
static void scp_boot_message_start(void)
{
mhu_secure_message_start(BOM_MHU_SLOT_ID);
@@ -88,7 +99,7 @@ static void scp_boot_message_end(void)
mhu_secure_message_end(BOM_MHU_SLOT_ID);
}
-int scp_bootloader_transfer(void *image, unsigned int image_size)
+int css_scp_boot_image_xfer(void *image, unsigned int image_size)
{
uint32_t response;
uint32_t checksum;
@@ -170,8 +181,5 @@ int scp_bootloader_transfer(void *image, unsigned int image_size)
return -1;
}
- VERBOSE("Waiting for SCP to signal it is ready to go on\n");
-
- /* Wait for SCP to signal it's ready */
- return scpi_wait_ready();
+ return 0;
}
diff --git a/plat/arm/css/drivers/scp/css_scp.h b/plat/arm/css/drivers/scp/css_scp.h
index 165226d2..097a9f58 100644
--- a/plat/arm/css/drivers/scp/css_scp.h
+++ b/plat/arm/css/drivers/scp/css_scp.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,13 +7,31 @@
#ifndef __CSS_SCP_H__
#define __CSS_SCP_H__
-#include <psci.h>
+#include <types.h>
+#include "../scpi/css_scpi.h"
-void css_scp_suspend(const psci_power_state_t *target_state);
-void css_scp_off(const psci_power_state_t *target_state);
+/* Forward declarations */
+struct psci_power_state;
+
+/* API for power management by SCP */
+void css_scp_suspend(const struct psci_power_state *target_state);
+void css_scp_off(const struct psci_power_state *target_state);
void css_scp_on(u_register_t mpidr);
int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level);
void __dead2 css_scp_sys_shutdown(void);
void __dead2 css_scp_sys_reboot(void);
+/* API for SCP Boot Image transfer. Return 0 on success, -1 on error */
+int css_scp_boot_image_xfer(void *image, unsigned int image_size);
+
+/*
+ * API to wait for SCP to signal till it's ready after booting the transferred
+ * image.
+ */
+static inline int css_scp_boot_ready(void)
+{
+ VERBOSE("Waiting for SCP to signal it is ready to go on\n");
+ return scpi_wait_ready();
+}
+
#endif /* __CSS_SCP_H__ */
diff --git a/plat/arm/css/drivers/scpi/css_scpi.h b/plat/arm/css/drivers/scpi/css_scpi.h
index 0e26c3df..2a7e624a 100644
--- a/plat/arm/css/drivers/scpi/css_scpi.h
+++ b/plat/arm/css/drivers/scpi/css_scpi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -97,11 +97,11 @@ typedef enum {
scpi_system_reset = 2
} scpi_system_state_t;
-extern int scpi_wait_ready(void);
-extern void scpi_set_css_power_state(unsigned int mpidr,
- scpi_power_state_t cpu_state,
- scpi_power_state_t cluster_state,
- scpi_power_state_t css_state);
+int scpi_wait_ready(void);
+void scpi_set_css_power_state(unsigned int mpidr,
+ scpi_power_state_t cpu_state,
+ scpi_power_state_t cluster_state,
+ scpi_power_state_t css_state);
int scpi_get_css_power_state(unsigned int mpidr, unsigned int *cpu_state_p,
unsigned int *cluster_state_p);
uint32_t scpi_sys_power_state(scpi_system_state_t system_state);
diff --git a/plat/hisilicon/hikey/hikey_bl1_setup.c b/plat/hisilicon/hikey/hikey_bl1_setup.c
index b0058746..05e2e35d 100644
--- a/plat/hisilicon/hikey/hikey_bl1_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl1_setup.c
@@ -288,6 +288,11 @@ static void hikey_hi6553_init(void)
/* select 32.764KHz */
mmio_write_8(HI6553_CLK19M2_600_586_EN, 0x01);
+
+ /* Disable vbus_det interrupts */
+ data = mmio_read_8(HI6553_IRQ2_MASK);
+ data = data | 0x3;
+ mmio_write_8(HI6553_IRQ2_MASK, data);
}
static void init_mmc0_pll(void)
diff --git a/plat/hisilicon/hikey/include/hi6553.h b/plat/hisilicon/hikey/include/hi6553.h
index 76cb8ff1..a80d36df 100644
--- a/plat/hisilicon/hikey/include/hi6553.h
+++ b/plat/hisilicon/hikey/include/hi6553.h
@@ -19,6 +19,7 @@
#define DISABLE6_XO_CLK_RF2 (1 << 4)
#define HI6553_VERSION_REG (PMUSSI_BASE + (0x000 << 2))
+#define HI6553_IRQ2_MASK (PMUSSI_BASE + (0x008 << 2))
#define HI6553_ENABLE2_LDO1_8 (PMUSSI_BASE + (0x029 << 2))
#define HI6553_DISABLE2_LDO1_8 (PMUSSI_BASE + (0x02a << 2))
#define HI6553_ONOFF_STATUS2_LDO1_8 (PMUSSI_BASE + (0x02b << 2))
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index 0c25934c..86021ba9 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -36,6 +36,7 @@ uint8_t tegra_fake_system_suspend;
* The following platform setup functions are weakly defined. They
* provide typical implementations that will be overridden by a SoC.
*/
+#pragma weak tegra_soc_pwr_domain_suspend_pwrdown_early
#pragma weak tegra_soc_pwr_domain_suspend
#pragma weak tegra_soc_pwr_domain_on
#pragma weak tegra_soc_pwr_domain_off
@@ -45,6 +46,11 @@ uint8_t tegra_fake_system_suspend;
#pragma weak tegra_soc_prepare_system_off
#pragma weak tegra_soc_get_target_pwr_state
+int tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+ return PSCI_E_NOT_SUPPORTED;
+}
+
int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
return PSCI_E_NOT_SUPPORTED;
@@ -145,6 +151,17 @@ void tegra_pwr_domain_off(const psci_power_state_t *target_state)
/*******************************************************************************
* Handler called when a power domain is about to be suspended. The
* target_state encodes the power state that each level should transition to.
+ * This handler is called with SMP and data cache enabled, when
+ * HW_ASSISTED_COHERENCY = 0
+ ******************************************************************************/
+void tegra_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state)
+{
+ tegra_soc_pwr_domain_suspend_pwrdown_early(target_state);
+}
+
+/*******************************************************************************
+ * Handler called when a power domain is about to be suspended. The
+ * target_state encodes the power state that each level should transition to.
******************************************************************************/
void tegra_pwr_domain_suspend(const psci_power_state_t *target_state)
{
@@ -315,6 +332,7 @@ static const plat_psci_ops_t tegra_plat_psci_ops = {
.cpu_standby = tegra_cpu_standby,
.pwr_domain_on = tegra_pwr_domain_on,
.pwr_domain_off = tegra_pwr_domain_off,
+ .pwr_domain_suspend_pwrdown_early = tegra_pwr_domain_suspend_pwrdown_early,
.pwr_domain_suspend = tegra_pwr_domain_suspend,
.pwr_domain_on_finish = tegra_pwr_domain_on_finish,
.pwr_domain_suspend_finish = tegra_pwr_domain_suspend_finish,
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index 7ea0f108..72792f8a 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -38,7 +38,6 @@ IO_SOURCES := drivers/io/io_block.c \
# common sources for BL1, BL2, BL31
PLAT_BL_COMMON_SOURCES += drivers/console/aarch64/console.S \
lib/xlat_tables_v2/aarch64/xlat_tables_arch.c \
- lib/xlat_tables_v2/xlat_tables_common.c \
lib/xlat_tables_v2/xlat_tables_internal.c \
$(PLAT_PATH)/uniphier_console.S \
$(PLAT_PATH)/uniphier_helpers.S \
diff --git a/readme.rst b/readme.rst
index a83338ff..c3c0319e 100644
--- a/readme.rst
+++ b/readme.rst
@@ -27,13 +27,15 @@ described in the `Contributing Guidelines`_.
This project contains code from other projects as listed below. The original
license text is included in those source files.
-- The stdlib source code is derived from FreeBSD code.
+- The stdlib source code is derived from FreeBSD code, which uses various
+ BSD licenses, including BSD-3-Clause and BSD-2-Clause.
- The libfdt source code is dual licensed. It is used by this project under
the terms of the BSD-2-Clause license.
- The LLVM compiler-rt source code is dual licensed. It is used by this
- project under the terms of the University of Illinois "BSD-Like" license.
+ project under the terms of the NCSA license (also known as the University of
+ Illinois/NCSA Open Source License).
This Release
------------
diff --git a/tools/fiptool/Makefile b/tools/fiptool/Makefile
index 5e2ecc13..e0e39236 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -27,7 +27,7 @@ else
Q :=
endif
-INCLUDE_PATHS := -I. -I../../include/tools_share
+INCLUDE_PATHS := -I../../include/tools_share
HOSTCC ?= gcc
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index 65e4a25c..4d80f2f1 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -19,6 +19,7 @@
#include <unistd.h>
#include <openssl/sha.h>
+
#include <firmware_image_package.h>
#include "fiptool.h"
diff --git a/tools/fiptool/fiptool.h b/tools/fiptool/fiptool.h
index 889b0fde..4b5cdd91 100644
--- a/tools/fiptool/fiptool.h
+++ b/tools/fiptool/fiptool.h
@@ -7,11 +7,10 @@
#ifndef __FIPTOOL_H__
#define __FIPTOOL_H__
-#include <firmware_image_package.h>
-
#include <stddef.h>
#include <stdint.h>
+#include <firmware_image_package.h>
#include <uuid.h>
#define NELEM(x) (sizeof (x) / sizeof *(x))
diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c
index 6231cd4e..7c6c24be 100644
--- a/tools/fiptool/tbbr_config.c
+++ b/tools/fiptool/tbbr_config.c
@@ -4,9 +4,10 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <firmware_image_package.h>
#include <stddef.h>
+#include <firmware_image_package.h>
+
#include "tbbr_config.h"
/* The images used depends on the platform. */