1 /*
2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <debug.h>
8 #include <mmio.h>
9 #include <norflash.h>
10 #include <plat_arm.h>
11 #include <platform_def.h>
12 #include <psci.h>
13 #include <utils.h>
14
15 mem_region_t arm_ram_ranges[] = {
16 {ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_SIZE},
17 #ifdef AARCH64
18 {ARM_DRAM2_BASE, ARM_DRAM2_SIZE},
19 #endif
20 };
21
22 /*******************************************************************************
23 * Function that reads the content of the memory protect variable that
24 * enables clearing of non secure memory when system boots. This variable
25 * should be stored in a secure NVRAM.
26 ******************************************************************************/
arm_psci_read_mem_protect(int * enabled)27 int arm_psci_read_mem_protect(int *enabled)
28 {
29 int tmp;
30
31 tmp = *(int *) PLAT_ARM_MEM_PROT_ADDR;
32 *enabled = (tmp == 1);
33 return 0;
34 }
35
36 /*******************************************************************************
37 * Function that writes the content of the memory protect variable that
38 * enables overwritten of non secure memory when system boots.
39 ******************************************************************************/
arm_nor_psci_write_mem_protect(int val)40 int arm_nor_psci_write_mem_protect(int val)
41 {
42 int enable = (val != 0);
43
44 if (nor_unlock(PLAT_ARM_MEM_PROT_ADDR) != 0) {
45 ERROR("unlocking memory protect variable\n");
46 return -1;
47 }
48
49 if (enable) {
50 /*
51 * If we want to write a value different than 0
52 * then we have to erase the full block because
53 * otherwise we cannot ensure that the value programmed
54 * into the flash is going to be the same than the value
55 * requested by the caller
56 */
57 if (nor_erase(PLAT_ARM_MEM_PROT_ADDR) != 0) {
58 ERROR("erasing block containing memory protect variable\n");
59 return -1;
60 }
61 }
62
63 if (nor_word_program(PLAT_ARM_MEM_PROT_ADDR, enable) != 0) {
64 ERROR("programming memory protection variable\n");
65 return -1;
66 }
67 return 0;
68 }
69
70 /*******************************************************************************
71 * Function used for required psci operations performed when
72 * system boots
73 ******************************************************************************/
arm_nor_psci_do_mem_protect(void)74 void arm_nor_psci_do_mem_protect(void)
75 {
76 int enable;
77
78 arm_psci_read_mem_protect(&enable);
79 if (!enable)
80 return;
81 INFO("PSCI: Overwritting non secure memory\n");
82 clear_mem_regions(arm_ram_ranges, ARRAY_SIZE(arm_ram_ranges));
83 arm_nor_psci_write_mem_protect(0);
84 }
85
86 /*******************************************************************************
87 * Function that checks if a region is protected by the memory protect
88 * mechanism
89 ******************************************************************************/
arm_psci_mem_protect_chk(uintptr_t base,u_register_t length)90 int arm_psci_mem_protect_chk(uintptr_t base, u_register_t length)
91 {
92 return mem_region_in_array_chk(arm_ram_ranges,
93 ARRAY_SIZE(arm_ram_ranges),
94 base, length);
95 }
96