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