13d5d9f5aSJerome Forissier /* 23d5d9f5aSJerome Forissier * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. 33d5d9f5aSJerome Forissier * 43d5d9f5aSJerome Forissier * SPDX-License-Identifier: BSD-3-Clause 53d5d9f5aSJerome Forissier */ 63d5d9f5aSJerome Forissier 73d5d9f5aSJerome Forissier #include <assert.h> 83d5d9f5aSJerome Forissier #include <debug.h> 93d5d9f5aSJerome Forissier #include <platform_def.h> 103d5d9f5aSJerome Forissier #include <stdint.h> 11*93c78ed2SAntonio Nino Diaz #include <string.h> 123d5d9f5aSJerome Forissier #include <utils_def.h> 133d5d9f5aSJerome Forissier #include "hikey_private.h" 143d5d9f5aSJerome Forissier 153d5d9f5aSJerome Forissier #define PORTNUM_MAX 5 163d5d9f5aSJerome Forissier 173d5d9f5aSJerome Forissier #define MDDRC_SECURITY_BASE 0xF7121000 183d5d9f5aSJerome Forissier 193d5d9f5aSJerome Forissier struct int_en_reg { 203d5d9f5aSJerome Forissier unsigned in_en:1; 213d5d9f5aSJerome Forissier unsigned reserved:31; 223d5d9f5aSJerome Forissier }; 233d5d9f5aSJerome Forissier 243d5d9f5aSJerome Forissier struct rgn_map_reg { 253d5d9f5aSJerome Forissier unsigned rgn_base_addr:24; 263d5d9f5aSJerome Forissier unsigned rgn_size:6; 273d5d9f5aSJerome Forissier unsigned reserved:1; 283d5d9f5aSJerome Forissier unsigned rgn_en:1; 293d5d9f5aSJerome Forissier }; 303d5d9f5aSJerome Forissier 313d5d9f5aSJerome Forissier struct rgn_attr_reg { 323d5d9f5aSJerome Forissier unsigned sp:4; 333d5d9f5aSJerome Forissier unsigned security_inv:1; 343d5d9f5aSJerome Forissier unsigned reserved_0:3; 353d5d9f5aSJerome Forissier unsigned mid_en:1; 363d5d9f5aSJerome Forissier unsigned mid_inv:1; 373d5d9f5aSJerome Forissier unsigned reserved_1:6; 383d5d9f5aSJerome Forissier unsigned rgn_en:1; 393d5d9f5aSJerome Forissier unsigned subrgn_disable:16; 403d5d9f5aSJerome Forissier }; 413d5d9f5aSJerome Forissier 423d5d9f5aSJerome Forissier static volatile struct int_en_reg *get_int_en_reg(uint32_t base) 433d5d9f5aSJerome Forissier { 443d5d9f5aSJerome Forissier uint64_t addr = base + 0x20; 453d5d9f5aSJerome Forissier return (struct int_en_reg *)addr; 463d5d9f5aSJerome Forissier } 473d5d9f5aSJerome Forissier 483d5d9f5aSJerome Forissier static volatile struct rgn_map_reg *get_rgn_map_reg(uint32_t base, int region, int port) 493d5d9f5aSJerome Forissier { 503d5d9f5aSJerome Forissier uint64_t addr = base + 0x100 + 0x10 * region + 0x400 * (uint64_t)port; 513d5d9f5aSJerome Forissier return (struct rgn_map_reg *)addr; 523d5d9f5aSJerome Forissier } 533d5d9f5aSJerome Forissier 543d5d9f5aSJerome Forissier static volatile struct rgn_attr_reg *get_rgn_attr_reg(uint32_t base, int region, 553d5d9f5aSJerome Forissier int port) 563d5d9f5aSJerome Forissier { 573d5d9f5aSJerome Forissier uint64_t addr = base + 0x104 + 0x10 * region + 0x400 * (uint64_t)port; 583d5d9f5aSJerome Forissier return (struct rgn_attr_reg *)addr; 593d5d9f5aSJerome Forissier } 603d5d9f5aSJerome Forissier 613d5d9f5aSJerome Forissier /* 623d5d9f5aSJerome Forissier * Configure secure memory region 633d5d9f5aSJerome Forissier * region_size must be a power of 2 and at least 64KB 643d5d9f5aSJerome Forissier * region_base must be region_size aligned 653d5d9f5aSJerome Forissier */ 6652988b38SPeter Griffin static void sec_protect(uint32_t region_base, uint32_t region_size, 6752988b38SPeter Griffin int region) 683d5d9f5aSJerome Forissier { 693d5d9f5aSJerome Forissier volatile struct int_en_reg *int_en; 703d5d9f5aSJerome Forissier volatile struct rgn_map_reg *rgn_map; 713d5d9f5aSJerome Forissier volatile struct rgn_attr_reg *rgn_attr; 723d5d9f5aSJerome Forissier uint32_t i = 0; 733d5d9f5aSJerome Forissier 74d5d5595aSVictor Chong /* ensure secure region number is between 1-15 */ 75d5d5595aSVictor Chong assert(region > 0 && region < 16); 76d5d5595aSVictor Chong /* ensure secure region size is a power of 2 >= 64KB */ 77d5d5595aSVictor Chong assert(IS_POWER_OF_TWO(region_size) && region_size >= 0x10000); 78d5d5595aSVictor Chong /* ensure secure region address is aligned to region size */ 79d5d5595aSVictor Chong assert(!(region_base & (region_size - 1))); 803d5d9f5aSJerome Forissier 813d5d9f5aSJerome Forissier INFO("BL2: TrustZone: protecting %u bytes of memory at 0x%x\n", region_size, 823d5d9f5aSJerome Forissier region_base); 833d5d9f5aSJerome Forissier 843d5d9f5aSJerome Forissier int_en = get_int_en_reg(MDDRC_SECURITY_BASE); 853d5d9f5aSJerome Forissier int_en->in_en = 0x1; 863d5d9f5aSJerome Forissier 873d5d9f5aSJerome Forissier for (i = 0; i < PORTNUM_MAX; i++) { 8852988b38SPeter Griffin rgn_map = get_rgn_map_reg(MDDRC_SECURITY_BASE, region, i); 8952988b38SPeter Griffin rgn_attr = get_rgn_attr_reg(MDDRC_SECURITY_BASE, region, i); 903d5d9f5aSJerome Forissier rgn_map->rgn_base_addr = region_base >> 16; 913d5d9f5aSJerome Forissier rgn_attr->subrgn_disable = 0x0; 923d5d9f5aSJerome Forissier rgn_attr->sp = (i == 3) ? 0xC : 0x0; 933d5d9f5aSJerome Forissier rgn_map->rgn_size = __builtin_ffs(region_size) - 2; 943d5d9f5aSJerome Forissier rgn_map->rgn_en = 0x1; 953d5d9f5aSJerome Forissier } 963d5d9f5aSJerome Forissier } 973d5d9f5aSJerome Forissier 983d5d9f5aSJerome Forissier /******************************************************************************* 993d5d9f5aSJerome Forissier * Initialize the secure environment. 1003d5d9f5aSJerome Forissier ******************************************************************************/ 1013d5d9f5aSJerome Forissier void hikey_security_setup(void) 1023d5d9f5aSJerome Forissier { 10352988b38SPeter Griffin sec_protect(DDR_SEC_BASE, DDR_SEC_SIZE, 1); 10452988b38SPeter Griffin sec_protect(DDR_SDP_BASE, DDR_SDP_SIZE, 2); 1053d5d9f5aSJerome Forissier } 106