xref: /rk3399_ARM-atf/plat/arm/common/arm_nor_psci_mem_protect.c (revision f145403c2a1a7064cb55670ac0674dc6586398ab)
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 };
18 
19 /*******************************************************************************
20  * Function that reads the content of the memory protect variable that
21  * enables clearing of non secure memory when system boots. This variable
22  * should be stored in a secure NVRAM.
23  ******************************************************************************/
24 int arm_psci_read_mem_protect(int *enabled)
25 {
26 	int tmp;
27 
28 	tmp = *(int *) PLAT_ARM_MEM_PROT_ADDR;
29 	*enabled = (tmp == 1);
30 	return 0;
31 }
32 
33 /*******************************************************************************
34  * Function that writes the content of the memory protect variable that
35  * enables overwritten of non secure memory when system boots.
36  ******************************************************************************/
37 int arm_nor_psci_write_mem_protect(int val)
38 {
39 	int enable = (val != 0);
40 
41 	if (nor_unlock(PLAT_ARM_MEM_PROT_ADDR) != 0) {
42 		ERROR("unlocking memory protect variable\n");
43 		return -1;
44 	}
45 
46 	if (enable) {
47 		/*
48 		 * If we want to write a value different than 0
49 		 * then we have to erase the full block because
50 		 * otherwise we cannot ensure that the value programmed
51 		 * into the flash is going to be the same than the value
52 		 * requested by the caller
53 		 */
54 		if (nor_erase(PLAT_ARM_MEM_PROT_ADDR) != 0) {
55 			ERROR("erasing block containing memory protect variable\n");
56 			return -1;
57 		}
58 	}
59 
60 	if (nor_word_program(PLAT_ARM_MEM_PROT_ADDR, enable) != 0) {
61 		ERROR("programming memory protection variable\n");
62 		return -1;
63 	}
64 	return 0;
65 }
66 
67 /*******************************************************************************
68  * Function used for required psci operations performed when
69  * system boots
70  ******************************************************************************/
71 void arm_nor_psci_do_mem_protect(void)
72 {
73 	int enable;
74 
75 	arm_psci_read_mem_protect(&enable);
76 	if (!enable)
77 		return;
78 	INFO("PSCI: Overwritting non secure memory\n");
79 	clear_mem_regions(arm_ram_ranges, ARRAY_SIZE(arm_ram_ranges));
80 	arm_nor_psci_write_mem_protect(0);
81 }
82 
83 /*******************************************************************************
84  * Function that checks if a region is protected by the memory protect
85  * mechanism
86  ******************************************************************************/
87 int arm_psci_mem_protect_chk(uintptr_t base, u_register_t length)
88 {
89 	return mem_region_in_array_chk(arm_ram_ranges,
90 				       ARRAY_SIZE(arm_ram_ranges),
91 				       base, length);
92 }
93