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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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