Home | History | Annotate | Download | only in common
      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