Merge pull request #1043 from tekkamanninja/qemu_xlat_tables_v2_upstream
qemu: use translation tables library v2 as default.
diff --git a/Makefile b/Makefile
index 6aa4e9a..23ebcaa 100644
--- a/Makefile
+++ b/Makefile
@@ -438,6 +438,7 @@
$(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,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_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,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 708ec05..f5ad562 100644
--- a/docs/change-log.rst
+++ b/docs/change-log.rst
@@ -266,7 +266,7 @@
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 @@
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 ce564a2..5738927 100644
--- a/docs/cpu-specific-build-macros.rst
+++ b/docs/cpu-specific-build-macros.rst
@@ -51,10 +51,20 @@
- ``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 5e8eeba..638033e 100644
--- a/docs/platform-migration-guide.rst
+++ b/docs/platform-migration-guide.rst
@@ -146,6 +146,7 @@
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 @@
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 66fe0f1..bf8dea7 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -60,11 +60,16 @@
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 @@
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 6b82e3d..ec8c233 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -337,6 +337,11 @@
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 @@
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 fee6a24..0ed39c9 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -267,6 +267,8 @@
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 0000000..a418d2d
--- /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 0000000..7381bc8
--- /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 0000000..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 4b993a0..008ae9b 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 9db6719..288a8e0 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,14 +83,59 @@
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
* this function marks the transition point after which static regions can no
* 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,7 +144,18 @@
*/
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,15 +169,9 @@
*/
int mmap_add_dynamic_region(unsigned long long base_pa, uintptr_t base_va,
size_t size, mmap_attr_t attr);
+int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, 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);
-
-/*
* Remove a region with the specified base VA and size. Only dynamic regions can
* be removed, and they can be removed even if the translation tables are
* initialized.
@@ -131,6 +182,11 @@
* 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 0000000..f5e3100
--- /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 0b74ced..9d025f6 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 dc3d7dc..3206f4e 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 0000000..db3c6fd
--- /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 3bdd319..cb5ab31 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 16b22c2..d3d0e2f 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -64,7 +64,20 @@
/*
* 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 0d1589e..40ecdee 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -80,6 +80,17 @@
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 41f7070..97fab4b 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 9c15624..c7e34f2 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
- */
+#define XLAT_TABLE_LEVEL_BASE \
+ GET_XLAT_TABLE_LEVEL_BASE(PLAT_VIRT_ADDR_SPACE_SIZE)
-#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
+#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 @@
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 309cb9b..2ddf8cb 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 @@
/* 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 b5c3ac8..50d6bd5 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 40fd2d0..be18552 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 @@
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 @@
ATTR_IWBWA_OWBWA_NTR_INDEX);
mair0 |= MAIR0_ATTR_SET(ATTR_NON_CACHEABLE,
ATTR_NON_CACHEABLE_INDEX);
- write_mair0(mair0);
+
+ /*
+ * 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;
/*
- * Set TTBCR bits as well. Set TTBR0 table properties. Disable TTBR1.
+ * 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 @@
dsbish();
isb();
- sctlr = read_sctlr();
sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT;
if (flags & DISABLE_DCACHE)
@@ -157,8 +181,3 @@
/* 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 f75ab79..0000000
--- 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 14f6cd6..61eac10 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 @@
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 @@
}
}
-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 @@
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 @@
/* 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 caccb73..0000000
--- 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 4f80434..b94ce5d 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 f20bf93..0000000
--- 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 f60d78c..cd6e11c 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 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 83e0b6e..d352583 100644
--- a/lib/xlat_tables_v2/xlat_tables_private.h
+++ b/lib/xlat_tables_v2/xlat_tables_private.h
@@ -7,100 +7,9 @@
#ifndef __XLAT_TABLES_PRIVATE_H__
#define __XLAT_TABLES_PRIVATE_H__
-#include <cassert.h>
#include <platform_def.h>
-#include <utils_def.h>
+#include <xlat_tables_defs.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;
-
#if PLAT_XLAT_TABLES_DYNAMIC
/*
* Shifts and masks to access fields of an mmap_attr_t
@@ -138,13 +47,6 @@
*/
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 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 @@
*/
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 42f754e..f6a554f 100644
--- a/plat/arm/board/common/board_css_common.c
+++ b/plat/arm/board/common/board_css_common.c
@@ -19,6 +19,7 @@
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 eb37f11..2f5d7fc 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -36,6 +36,10 @@
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 @@
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 @@
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 ea128b6..46afb71 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 73549aa..0712e3a 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 @@
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 cc18758..d225151 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 @@
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 c2ae921..9381e4c 100644
--- a/plat/arm/css/common/css_common.mk
+++ b/plat/arm/css/common/css_common.mk
@@ -56,8 +56,8 @@
$(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 0d6a6a2..0000000
--- 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
similarity index 85%
rename from plat/arm/css/common/css_scp_bootloader.c
rename to plat/arm/css/drivers/scp/css_bom_bootloader.c
index 3db5cf5..047e069 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 @@
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 @@
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 @@
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 165226d..097a9f5 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 0e26c3d..2a7e624 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 @@
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 b005874..05e2e35 100644
--- a/plat/hisilicon/hikey/hikey_bl1_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl1_setup.c
@@ -288,6 +288,11 @@
/* 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 76cb8ff..a80d36d 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 0c25934..86021ba 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -36,6 +36,7 @@
* 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 @@
#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 @@
/*******************************************************************************
* 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 @@
.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 7ea0f10..72792f8 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -38,7 +38,6 @@
# 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 a83338f..c3c0319 100644
--- a/readme.rst
+++ b/readme.rst
@@ -27,13 +27,15 @@
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 5e2ecc1..e0e3923 100644
--- a/tools/fiptool/Makefile
+++ b/tools/fiptool/Makefile
@@ -27,7 +27,7 @@
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 65e4a25..4d80f2f 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 889b0fd..4b5cdd9 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 6231cd4..7c6c24b 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. */