blob: 4ae57e5344cc965f590f4b74fcd25352b50ff0c1 [file] [log] [blame]
Roberto Vargasa1c16b62017-08-03 09:16:43 +01001/*
Roberto Vargas2ca18d92018-02-12 12:36:17 +00002 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
Roberto Vargasa1c16b62017-08-03 09:16:43 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Roberto Vargasa1c16b62017-08-03 09:16:43 +01007#include <platform_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008
9#include <common/debug.h>
10#include <drivers/cfi/v2m_flash.h>
11#include <lib/psci/psci.h>
12#include <lib/mmio.h>
13#include <lib/utils.h>
14
15#include <plat_arm.h>
Roberto Vargas550eb082018-01-05 16:00:05 +000016
17/*
18 * DRAM1 is used also to load the NS boot loader. For this reason we
19 * cannot clear the full DRAM1, because in that case we would clear
20 * the NS images (especially for RESET_TO_BL31 and RESET_TO_SPMIN cases).
21 * For this reason we reserve 64 MB for the NS images and protect the RAM
22 * until the end of DRAM1.
23 * We limit the size of DRAM2 to 1 GB to avoid big delays while booting
24 */
25#define DRAM1_NS_IMAGE_LIMIT (PLAT_ARM_NS_IMAGE_OFFSET + (32 << TWO_MB_SHIFT))
26#define DRAM1_PROTECTED_SIZE (ARM_NS_DRAM1_END+1u - DRAM1_NS_IMAGE_LIMIT)
27
Roberto Vargas2ca18d92018-02-12 12:36:17 +000028static mem_region_t arm_ram_ranges[] = {
Roberto Vargas550eb082018-01-05 16:00:05 +000029 {DRAM1_NS_IMAGE_LIMIT, DRAM1_PROTECTED_SIZE},
Roberto Vargasf8fda102017-08-08 11:27:20 +010030#ifdef AARCH64
Roberto Vargas550eb082018-01-05 16:00:05 +000031 {ARM_DRAM2_BASE, 1u << ONE_GB_SHIFT},
Roberto Vargasf8fda102017-08-08 11:27:20 +010032#endif
Roberto Vargasa1c16b62017-08-03 09:16:43 +010033};
34
35/*******************************************************************************
36 * Function that reads the content of the memory protect variable that
37 * enables clearing of non secure memory when system boots. This variable
38 * should be stored in a secure NVRAM.
39 ******************************************************************************/
40int arm_psci_read_mem_protect(int *enabled)
41{
42 int tmp;
43
44 tmp = *(int *) PLAT_ARM_MEM_PROT_ADDR;
Roberto Vargas550eb082018-01-05 16:00:05 +000045 *enabled = (tmp == 1) ? 1 : 0;
Roberto Vargasa1c16b62017-08-03 09:16:43 +010046 return 0;
47}
48
49/*******************************************************************************
50 * Function that writes the content of the memory protect variable that
51 * enables overwritten of non secure memory when system boots.
52 ******************************************************************************/
53int arm_nor_psci_write_mem_protect(int val)
54{
Sathees Balya30952cc2018-09-27 14:41:02 +010055 unsigned long enable = (val != 0) ? 1UL : 0UL;
Roberto Vargasa1c16b62017-08-03 09:16:43 +010056
57 if (nor_unlock(PLAT_ARM_MEM_PROT_ADDR) != 0) {
58 ERROR("unlocking memory protect variable\n");
59 return -1;
60 }
61
Sathees Balya30952cc2018-09-27 14:41:02 +010062 if (enable == 1UL) {
Roberto Vargasa1c16b62017-08-03 09:16:43 +010063 /*
64 * If we want to write a value different than 0
65 * then we have to erase the full block because
66 * otherwise we cannot ensure that the value programmed
67 * into the flash is going to be the same than the value
68 * requested by the caller
69 */
70 if (nor_erase(PLAT_ARM_MEM_PROT_ADDR) != 0) {
71 ERROR("erasing block containing memory protect variable\n");
72 return -1;
73 }
74 }
75
76 if (nor_word_program(PLAT_ARM_MEM_PROT_ADDR, enable) != 0) {
77 ERROR("programming memory protection variable\n");
78 return -1;
79 }
80 return 0;
81}
82
83/*******************************************************************************
84 * Function used for required psci operations performed when
85 * system boots
86 ******************************************************************************/
Roberto Vargas550eb082018-01-05 16:00:05 +000087/*
88 * PLAT_MEM_PROTECT_VA_FRAME is a address specifically
89 * selected in a way that is not needed an additional
90 * translation table for memprotect. It happens because
91 * we use a chunk of size 2MB and it means that it can
92 * be mapped in a level 2 table and the level 2 table
93 * for 0xc0000000 is already used and the entry for
94 * 0xc0000000 is not used.
95 */
96#if defined(PLAT_XLAT_TABLES_DYNAMIC)
97void arm_nor_psci_do_dyn_mem_protect(void)
Roberto Vargasa1c16b62017-08-03 09:16:43 +010098{
99 int enable;
100
101 arm_psci_read_mem_protect(&enable);
Roberto Vargas550eb082018-01-05 16:00:05 +0000102 if (enable == 0)
Roberto Vargasa1c16b62017-08-03 09:16:43 +0100103 return;
Roberto Vargas550eb082018-01-05 16:00:05 +0000104
105 INFO("PSCI: Overwriting non secure memory\n");
106 clear_map_dyn_mem_regions(arm_ram_ranges,
107 ARRAY_SIZE(arm_ram_ranges),
108 PLAT_ARM_MEM_PROTEC_VA_FRAME,
109 1 << TWO_MB_SHIFT);
110}
111#endif
112
113/*******************************************************************************
114 * Function used for required psci operations performed when
115 * system boots and dynamic memory is not used.
116 ******************************************************************************/
117void arm_nor_psci_do_static_mem_protect(void)
118{
119 int enable;
120
Antonio Nino Diazfec756f2018-07-18 16:24:16 +0100121 (void) arm_psci_read_mem_protect(&enable);
Roberto Vargas550eb082018-01-05 16:00:05 +0000122 if (enable == 0)
123 return;
124
125 INFO("PSCI: Overwriting non secure memory\n");
126 clear_mem_regions(arm_ram_ranges,
127 ARRAY_SIZE(arm_ram_ranges));
Antonio Nino Diazfec756f2018-07-18 16:24:16 +0100128 (void) arm_nor_psci_write_mem_protect(0);
Roberto Vargasa1c16b62017-08-03 09:16:43 +0100129}
130
131/*******************************************************************************
132 * Function that checks if a region is protected by the memory protect
133 * mechanism
134 ******************************************************************************/
135int arm_psci_mem_protect_chk(uintptr_t base, u_register_t length)
136{
137 return mem_region_in_array_chk(arm_ram_ranges,
138 ARRAY_SIZE(arm_ram_ranges),
139 base, length);
140}