1 /* 2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <debug.h> 9 #include <platform_def.h> 10 #include <stdint.h> 11 #include <string.h> 12 #include <utils_def.h> 13 #include "hikey_private.h" 14 15 #define PORTNUM_MAX 5 16 17 #define MDDRC_SECURITY_BASE 0xF7121000 18 19 struct int_en_reg { 20 unsigned in_en:1; 21 unsigned reserved:31; 22 }; 23 24 struct rgn_map_reg { 25 unsigned rgn_base_addr:24; 26 unsigned rgn_size:6; 27 unsigned reserved:1; 28 unsigned rgn_en:1; 29 }; 30 31 struct rgn_attr_reg { 32 unsigned sp:4; 33 unsigned security_inv:1; 34 unsigned reserved_0:3; 35 unsigned mid_en:1; 36 unsigned mid_inv:1; 37 unsigned reserved_1:6; 38 unsigned rgn_en:1; 39 unsigned subrgn_disable:16; 40 }; 41 42 static volatile struct int_en_reg *get_int_en_reg(uint32_t base) 43 { 44 uint64_t addr = base + 0x20; 45 return (struct int_en_reg *)addr; 46 } 47 48 static volatile struct rgn_map_reg *get_rgn_map_reg(uint32_t base, int region, int port) 49 { 50 uint64_t addr = base + 0x100 + 0x10 * region + 0x400 * (uint64_t)port; 51 return (struct rgn_map_reg *)addr; 52 } 53 54 static volatile struct rgn_attr_reg *get_rgn_attr_reg(uint32_t base, int region, 55 int port) 56 { 57 uint64_t addr = base + 0x104 + 0x10 * region + 0x400 * (uint64_t)port; 58 return (struct rgn_attr_reg *)addr; 59 } 60 61 /* 62 * Configure secure memory region 63 * region_size must be a power of 2 and at least 64KB 64 * region_base must be region_size aligned 65 */ 66 static void sec_protect(uint32_t region_base, uint32_t region_size, 67 int region) 68 { 69 volatile struct int_en_reg *int_en; 70 volatile struct rgn_map_reg *rgn_map; 71 volatile struct rgn_attr_reg *rgn_attr; 72 uint32_t i = 0; 73 74 /* ensure secure region number is between 1-15 */ 75 assert(region > 0 && region < 16); 76 /* ensure secure region size is a power of 2 >= 64KB */ 77 assert(IS_POWER_OF_TWO(region_size) && region_size >= 0x10000); 78 /* ensure secure region address is aligned to region size */ 79 assert(!(region_base & (region_size - 1))); 80 81 INFO("BL2: TrustZone: protecting %u bytes of memory at 0x%x\n", region_size, 82 region_base); 83 84 int_en = get_int_en_reg(MDDRC_SECURITY_BASE); 85 int_en->in_en = 0x1; 86 87 for (i = 0; i < PORTNUM_MAX; i++) { 88 rgn_map = get_rgn_map_reg(MDDRC_SECURITY_BASE, region, i); 89 rgn_attr = get_rgn_attr_reg(MDDRC_SECURITY_BASE, region, i); 90 rgn_map->rgn_base_addr = region_base >> 16; 91 rgn_attr->subrgn_disable = 0x0; 92 rgn_attr->sp = (i == 3) ? 0xC : 0x0; 93 rgn_map->rgn_size = __builtin_ffs(region_size) - 2; 94 rgn_map->rgn_en = 0x1; 95 } 96 } 97 98 /******************************************************************************* 99 * Initialize the secure environment. 100 ******************************************************************************/ 101 void hikey_security_setup(void) 102 { 103 sec_protect(DDR_SEC_BASE, DDR_SEC_SIZE, 1); 104 sec_protect(DDR_SDP_BASE, DDR_SDP_SIZE, 2); 105 } 106