/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
*/
void clear_mem_regions(mem_region_t *tbl, size_t nregions);
+/*
+ * zero_normalmem all the regions defined in region. It dynamically
+ * maps chunks of 'chunk_size' in 'va' virtual address and clears them.
+ * For this reason memory regions must be multiple of chunk_size and
+ * must be aligned to it as well. chunk_size and va can be selected
+ * in a way that they minimize the number of entries used in the
+ * translation tables.
+ */
+void clear_map_dyn_mem_regions(mem_region_t *region,
+ size_t nregions,
+ uintptr_t va,
+ size_t chunk_size);
/*
* checks that a region (addr + nbytes-1) of memory is totally covered by
#elif defined(IMAGE_BL2U)
# define PLATFORM_STACK_SIZE 0x200
#elif defined(IMAGE_BL31)
+#ifdef PLAT_XLAT_TABLES_DYNAMIC
+# define PLATFORM_STACK_SIZE 0x800
+#else
# define PLATFORM_STACK_SIZE 0x400
+#endif
#elif defined(IMAGE_BL32)
# define PLATFORM_STACK_SIZE 0x440
#endif
# define PLAT_SP_IMAGE_MMAP_REGIONS 7
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
# else
-# define PLAT_ARM_MMAP_ENTRIES 7
+# define PLAT_ARM_MMAP_ENTRIES 8
# define MAX_XLAT_TABLES 5
# endif
#elif defined(IMAGE_BL32)
-# define PLAT_ARM_MMAP_ENTRIES 7
+# define PLAT_ARM_MMAP_ENTRIES 8
# define MAX_XLAT_TABLES 5
#else
# define PLAT_ARM_MMAP_ENTRIES 11
void arm_program_trusted_mailbox(uintptr_t address);
int arm_psci_read_mem_protect(int *enabled);
int arm_nor_psci_write_mem_protect(int val);
-void arm_nor_psci_do_mem_protect(void);
+void arm_nor_psci_do_static_mem_protect(void);
+void arm_nor_psci_do_dyn_mem_protect(void);
int arm_psci_mem_protect_chk(uintptr_t base, u_register_t length);
/* Topology utility function */
#endif /* CSS_LOAD_SCP_IMAGES */
/* Load address of Non-Secure Image for CSS platform ports */
-#define PLAT_ARM_NS_IMAGE_OFFSET 0xE0000000
+#define PLAT_ARM_NS_IMAGE_OFFSET U(0xE0000000)
/* TZC related constants */
#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT_ALL
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
}
}
+#if defined(PLAT_XLAT_TABLES_DYNAMIC)
+/*
+ * zero_normalmem all the regions defined in regions.
+ * It assumes that MMU is enabled and the memory is Normal memory.
+ * regions must be a valid pointer to a memory mem_region_t array,
+ * nregions is the size of the array. va is the virtual address
+ * where we want to map the physical pages that are going to
+ * be cleared, and chunk is the amount of memory mapped and
+ * cleared in every iteration.
+ */
+void clear_map_dyn_mem_regions(mem_region_t *regions,
+ size_t nregions,
+ uintptr_t va,
+ size_t chunk)
+{
+ uintptr_t begin;
+ int r;
+ size_t size;
+ const mmap_attr_t attr = MT_MEMORY|MT_RW|MT_NS;
+
+ assert(regions != NULL);
+ assert(nregions > 0 && chunk > 0);
+
+ for ( ; nregions--; regions++) {
+ begin = regions->base;
+ size = regions->nbytes;
+ if ((begin & (chunk-1)) != 0 || (size & (chunk-1)) != 0) {
+ INFO("PSCI: Not correctly aligned region\n");
+ panic();
+ }
+
+ while (size > 0) {
+ r = mmap_add_dynamic_region(begin, va, chunk, attr);
+ if (r != 0) {
+ INFO("PSCI: mmap_add_dynamic_region failed with %d\n", r);
+ panic();
+ }
+
+ zero_normalmem((void *) va, chunk);
+
+ r = mmap_remove_dynamic_region(va, chunk);
+ if (r != 0) {
+ INFO("PSCI: mmap_remove_dynamic_region failed with %d\n", r);
+ panic();
+ }
+
+ begin += chunk;
+ size -= chunk;
+ }
+ }
+}
+#endif
+
/*
* This function checks that a region (addr + nbytes-1) of memory is totally
* covered by one of the regions defined in tbl.
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
const mmap_region_t plat_arm_mmap[] = {
#ifdef AARCH32
ARM_MAP_SHARED_RAM,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+ ARM_V2M_MAP_MEM_PROTECT,
+#endif
#endif
V2M_MAP_IOFPGA,
CSS_MAP_DEVICE,
*/
.get_sys_suspend_power_state = fvp_get_sys_suspend_power_state,
#endif
-#if !RESET_TO_BL31 && !RESET_TO_SP_MIN
- /*
- * mem_protect is not supported in RESET_TO_BL31 and RESET_TO_SP_MIN,
- * as that would require mapping in all of NS DRAM into BL31 or BL32.
- */
.mem_protect_chk = arm_psci_mem_protect_chk,
.read_mem_protect = arm_psci_read_mem_protect,
.write_mem_protect = arm_nor_psci_write_mem_protect,
-#endif
};
#ifndef __PLATFORM_DEF_H__
#define __PLATFORM_DEF_H__
+/* Enable the dynamic translation tables library. */
+#ifdef AARCH32
+# if defined(IMAGE_BL32) && RESET_TO_SP_MIN
+# define PLAT_XLAT_TABLES_DYNAMIC 1
+# endif
+#else
+# if defined(IMAGE_BL31) && RESET_TO_BL31
+# define PLAT_XLAT_TABLES_DYNAMIC 1
+# endif
+#endif /* AARCH32 */
+
#include <arm_def.h>
#include <arm_spm_def.h>
#include <board_arm_def.h>
#define PLAT_ARM_TRUSTED_DRAM_BASE 0x06000000
#define PLAT_ARM_TRUSTED_DRAM_SIZE 0x02000000 /* 32 MB */
+/* virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME 0xc0000000
+
/* No SCP in FVP */
#define PLAT_ARM_SCP_TZC_DRAM1_SIZE ULL(0x0)
/*
* Load address of BL33 for this platform port
*/
-#define PLAT_ARM_NS_IMAGE_OFFSET (ARM_DRAM1_BASE + 0x8000000)
+#define PLAT_ARM_NS_IMAGE_OFFSET (ARM_DRAM1_BASE + U(0x8000000))
/*
#ifndef __PLATFORM_DEF_H__
#define __PLATFORM_DEF_H__
+/* Enable the dynamic translation tables library. */
+#ifdef AARCH32
+# if defined(IMAGE_BL32) && RESET_TO_SP_MIN
+# define PLAT_XLAT_TABLES_DYNAMIC 1
+# endif
+#else
+# if defined(IMAGE_BL31) && RESET_TO_BL31
+# define PLAT_XLAT_TABLES_DYNAMIC 1
+# endif
+#endif /* AARCH32 */
+
+
#include <arm_def.h>
#include <board_arm_def.h>
#include <board_css_def.h>
/* Use the bypass address */
#define PLAT_ARM_TRUSTED_ROM_BASE V2M_FLASH0_BASE + BL1_ROM_BYPASS_OFFSET
+/* virtual address used by dynamic mem_protect for chunk_base */
+#define PLAT_ARM_MEM_PROTEC_VA_FRAME 0xc0000000
+
/*
* Actual ROM size on Juno is 64 KB, but TBB currently requires at least 80 KB
* in debug mode. We can test TBB on Juno bypassing the ROM and using 128 KB of
#endif
#ifdef IMAGE_BL32
-# define PLAT_ARM_MMAP_ENTRIES 5
+# define PLAT_ARM_MMAP_ENTRIES 6
# define MAX_XLAT_TABLES 4
#endif
plat_arm_security_setup();
#if defined(PLAT_ARM_MEM_PROT_ADDR)
- arm_nor_psci_do_mem_protect();
+ arm_nor_psci_do_static_mem_protect();
#endif
}
*/
plat_arm_security_setup();
+#if defined(PLAT_ARM_MEM_PROT_ADDR)
+ arm_nor_psci_do_dyn_mem_protect();
+#endif /* PLAT_ARM_MEM_PROT_ADDR */
+
#endif /* RESET_TO_BL31 */
/* Enable and initialize the System level generic timer */
#include <psci.h>
#include <utils.h>
+
+/*
+ * DRAM1 is used also to load the NS boot loader. For this reason we
+ * cannot clear the full DRAM1, because in that case we would clear
+ * the NS images (especially for RESET_TO_BL31 and RESET_TO_SPMIN cases).
+ * For this reason we reserve 64 MB for the NS images and protect the RAM
+ * until the end of DRAM1.
+ * We limit the size of DRAM2 to 1 GB to avoid big delays while booting
+ */
+#define DRAM1_NS_IMAGE_LIMIT (PLAT_ARM_NS_IMAGE_OFFSET + (32 << TWO_MB_SHIFT))
+#define DRAM1_PROTECTED_SIZE (ARM_NS_DRAM1_END+1u - DRAM1_NS_IMAGE_LIMIT)
+
static mem_region_t arm_ram_ranges[] = {
- {ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_SIZE},
+ {DRAM1_NS_IMAGE_LIMIT, DRAM1_PROTECTED_SIZE},
#ifdef AARCH64
- {ARM_DRAM2_BASE, ARM_DRAM2_SIZE},
+ {ARM_DRAM2_BASE, 1u << ONE_GB_SHIFT},
#endif
};
int tmp;
tmp = *(int *) PLAT_ARM_MEM_PROT_ADDR;
- *enabled = (tmp == 1);
+ *enabled = (tmp == 1) ? 1 : 0;
return 0;
}
return -1;
}
- if (enable) {
+ if (enable != 0) {
/*
* If we want to write a value different than 0
* then we have to erase the full block because
* Function used for required psci operations performed when
* system boots
******************************************************************************/
-void arm_nor_psci_do_mem_protect(void)
+/*
+ * PLAT_MEM_PROTECT_VA_FRAME is a address specifically
+ * selected in a way that is not needed an additional
+ * translation table for memprotect. It happens because
+ * we use a chunk of size 2MB and it means that it can
+ * be mapped in a level 2 table and the level 2 table
+ * for 0xc0000000 is already used and the entry for
+ * 0xc0000000 is not used.
+ */
+#if defined(PLAT_XLAT_TABLES_DYNAMIC)
+void arm_nor_psci_do_dyn_mem_protect(void)
{
int enable;
arm_psci_read_mem_protect(&enable);
- if (!enable)
+ if (enable == 0)
return;
- INFO("PSCI: Overwritting non secure memory\n");
- clear_mem_regions(arm_ram_ranges, ARRAY_SIZE(arm_ram_ranges));
+
+ INFO("PSCI: Overwriting non secure memory\n");
+ clear_map_dyn_mem_regions(arm_ram_ranges,
+ ARRAY_SIZE(arm_ram_ranges),
+ PLAT_ARM_MEM_PROTEC_VA_FRAME,
+ 1 << TWO_MB_SHIFT);
+}
+#endif
+
+/*******************************************************************************
+ * Function used for required psci operations performed when
+ * system boots and dynamic memory is not used.
+ ******************************************************************************/
+void arm_nor_psci_do_static_mem_protect(void)
+{
+ int enable;
+
+ arm_psci_read_mem_protect(&enable);
+ if (enable == 0)
+ return;
+
+ INFO("PSCI: Overwriting non secure memory\n");
+ clear_mem_regions(arm_ram_ranges,
+ ARRAY_SIZE(arm_ram_ranges));
arm_nor_psci_write_mem_protect(0);
}
*/
#if RESET_TO_SP_MIN
plat_arm_security_setup();
+
+#if defined(PLAT_ARM_MEM_PROT_ADDR)
+ arm_nor_psci_do_dyn_mem_protect();
+#endif /* PLAT_ARM_MEM_PROT_ADDR */
+
#endif
/* Enable and initialize the System level generic timer */
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
.translate_power_state_by_mpidr = css_translate_power_state_by_mpidr,
.get_node_hw_state = css_node_hw_state,
.get_sys_suspend_power_state = css_get_sys_suspend_power_state,
-/*
- * mem_protect is not supported in RESET_TO_BL31 and RESET_TO_SP_MIN,
- * as that would require mapping in all of NS DRAM into BL31 or BL32.
- */
-#if defined(PLAT_ARM_MEM_PROT_ADDR) && !RESET_TO_BL31 && !RESET_TO_SP_MIN
+
+#if defined(PLAT_ARM_MEM_PROT_ADDR)
.mem_protect_chk = arm_psci_mem_protect_chk,
.read_mem_protect = arm_psci_read_mem_protect,
.write_mem_protect = arm_nor_psci_write_mem_protect,