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