summaryrefslogtreecommitdiff
path: root/plat/arm/common/arm_nor_psci_mem_protect.c
blob: c5263fd8516c449fa0e3e7ccd520e03f9bf02e86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <debug.h>
#include <mmio.h>
#include <norflash.h>
#include <plat_arm.h>
#include <platform_def.h>
#include <psci.h>
#include <utils.h>

mem_region_t arm_ram_ranges[] = {
	{ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_SIZE},
#ifdef AARCH64
	{ARM_DRAM2_BASE, ARM_DRAM2_SIZE},
#endif
};

/*******************************************************************************
 * Function that reads the content of the memory protect variable that
 * enables clearing of non secure memory when system boots. This variable
 * should be stored in a secure NVRAM.
 ******************************************************************************/
int arm_psci_read_mem_protect(int *enabled)
{
	int tmp;

	tmp = *(int *) PLAT_ARM_MEM_PROT_ADDR;
	*enabled = (tmp == 1);
	return 0;
}

/*******************************************************************************
 * Function that writes the content of the memory protect variable that
 * enables overwritten of non secure memory when system boots.
 ******************************************************************************/
int arm_nor_psci_write_mem_protect(int val)
{
	int enable = (val != 0);

	if (nor_unlock(PLAT_ARM_MEM_PROT_ADDR) != 0) {
		ERROR("unlocking memory protect variable\n");
		return -1;
	}

	if (enable) {
		/*
		 * If we want to write a value different than 0
		 * then we have to erase the full block because
		 * otherwise we cannot ensure that the value programmed
		 * into the flash is going to be the same than the value
		 * requested by the caller
		 */
		if (nor_erase(PLAT_ARM_MEM_PROT_ADDR) != 0) {
			ERROR("erasing block containing memory protect variable\n");
			return -1;
		}
	}

	if (nor_word_program(PLAT_ARM_MEM_PROT_ADDR, enable) != 0) {
		ERROR("programming memory protection variable\n");
		return -1;
	}
	return 0;
}

/*******************************************************************************
 * Function used for required psci operations performed when
 * system boots
 ******************************************************************************/
void arm_nor_psci_do_mem_protect(void)
{
	int enable;

	arm_psci_read_mem_protect(&enable);
	if (!enable)
		return;
	INFO("PSCI: Overwritting non secure memory\n");
	clear_mem_regions(arm_ram_ranges, ARRAY_SIZE(arm_ram_ranges));
	arm_nor_psci_write_mem_protect(0);
}

/*******************************************************************************
 * Function that checks if a region is protected by the memory protect
 * mechanism
 ******************************************************************************/
int arm_psci_mem_protect_chk(uintptr_t base, u_register_t length)
{
	return mem_region_in_array_chk(arm_ram_ranges,
				       ARRAY_SIZE(arm_ram_ranges),
				       base, length);
}