1 /*
2  * Copyright (c) 2022-2023, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <common/debug.h>
8 #include <emi_mpu.h>
9 #include <mtk_sip_svc.h>
10 
11 #define MPU_PHYSICAL_ADDR_SHIFT_BITS	(16)
12 
set_emi_mpu_regions(void)13 void set_emi_mpu_regions(void)
14 {
15 	struct emi_region_info_t region_info;
16 
17 	/* SCP core0 DRAM */
18 	region_info.start = 0x50000000ULL;
19 	region_info.end = 0x528FFFFFULL;
20 	region_info.region = 2;
21 	SET_ACCESS_PERMISSION(region_info.apc, 1,
22 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
23 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
24 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
25 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
26 	emi_mpu_set_protection(&region_info);
27 
28 	/* SCP core1 DRAM */
29 	region_info.start = 0x70000000ULL;
30 	region_info.end = 0x729FFFFFULL;
31 	region_info.region = 3;
32 	SET_ACCESS_PERMISSION(region_info.apc, 1,
33 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
34 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
35 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
36 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
37 	emi_mpu_set_protection(&region_info);
38 
39 	/* DSP protect address */
40 	region_info.start = 0x60000000ULL;
41 	region_info.end = 0x610FFFFFULL;
42 	region_info.region = 4;
43 	SET_ACCESS_PERMISSION(region_info.apc, 1,
44 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
45 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
46 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION,
47 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, NO_PROTECTION);
48 	emi_mpu_set_protection(&region_info);
49 
50 	/* All default settings */
51 	region_info.start = 0x40000000ULL;
52 	region_info.end = 0x1FFFF0000ULL;
53 	region_info.region = 31;
54 	SET_ACCESS_PERMISSION(region_info.apc, 1,
55 			      FORBIDDEN, FORBIDDEN, NO_PROTECTION, NO_PROTECTION,
56 			      NO_PROTECTION, FORBIDDEN, NO_PROTECTION, NO_PROTECTION,
57 			      NO_PROTECTION, SEC_R_NSEC_RW, NO_PROTECTION, FORBIDDEN,
58 			      NO_PROTECTION, NO_PROTECTION, NO_PROTECTION, NO_PROTECTION);
59 	emi_mpu_set_protection(&region_info);
60 }
61 
set_apu_emi_mpu_region(void)62 int set_apu_emi_mpu_region(void)
63 {
64 	struct emi_region_info_t region_info;
65 
66 	region_info.start = (unsigned long long)APUSYS_SEC_BUF_PA;
67 	region_info.end = (unsigned long long)(APUSYS_SEC_BUF_PA + APUSYS_SEC_BUF_SZ) - 1;
68 	region_info.region = APUSYS_SEC_BUF_EMI_REGION;
69 
70 	SET_ACCESS_PERMISSION(region_info.apc, UNLOCK,
71 			      FORBIDDEN,     FORBIDDEN, FORBIDDEN,     FORBIDDEN,
72 			      FORBIDDEN,     FORBIDDEN, FORBIDDEN,     FORBIDDEN,
73 			      NO_PROTECTION, FORBIDDEN, NO_PROTECTION, FORBIDDEN,
74 			      FORBIDDEN,     FORBIDDEN, FORBIDDEN,     SEC_RW);
75 
76 	return emi_mpu_set_protection(&region_info);
77 }
78 
get_decoded_phys_addr(uint64_t addr)79 static inline uint64_t get_decoded_phys_addr(uint64_t addr)
80 {
81 	return (addr << MPU_PHYSICAL_ADDR_SHIFT_BITS);
82 }
83 
get_decoded_zone_id(uint32_t info)84 static inline uint32_t get_decoded_zone_id(uint32_t info)
85 {
86 	return ((info & 0xFFFF0000) >> MPU_PHYSICAL_ADDR_SHIFT_BITS);
87 }
88 
emi_mpu_optee_handler(uint64_t encoded_addr,uint64_t zone_size,uint64_t zone_info)89 int emi_mpu_optee_handler(uint64_t encoded_addr, uint64_t zone_size,
90 						  uint64_t zone_info)
91 {
92 	uint64_t phys_addr = get_decoded_phys_addr(encoded_addr);
93 	struct emi_region_info_t region_info;
94 	enum MPU_REQ_ORIGIN_ZONE_ID zone_id = get_decoded_zone_id(zone_info);
95 
96 	INFO("encoded_addr = 0x%lx, zone_size = 0x%lx, zone_info = 0x%lx\n",
97 	     encoded_addr, zone_size, zone_info);
98 
99 	if (zone_id != MPU_REQ_ORIGIN_TEE_ZONE_SVP) {
100 		ERROR("Invalid param %s, %d\n", __func__, __LINE__);
101 		return MTK_SIP_E_INVALID_PARAM;
102 	}
103 
104 	/* SVP DRAM */
105 	region_info.start = phys_addr;
106 	region_info.end = phys_addr + zone_size;
107 	region_info.region = 4;
108 	SET_ACCESS_PERMISSION(region_info.apc, 1,
109 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
110 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
111 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, FORBIDDEN,
112 			      FORBIDDEN, FORBIDDEN, FORBIDDEN, SEC_RW);
113 
114 	emi_mpu_set_protection(&region_info);
115 
116 	return 0;
117 }