xref: /rk3399_ARM-atf/drivers/qti/accesscontrol/access_control.c (revision 5de3e03dbd7c2da6748e294f423c83f9582f459c)
1*6ae8fce3SJorge Ramirez-Ortiz /*
2*6ae8fce3SJorge Ramirez-Ortiz  * Copyright (c) 2026, Qualcomm Technologies, Inc. and/or its subsidiaries.
3*6ae8fce3SJorge Ramirez-Ortiz  *
4*6ae8fce3SJorge Ramirez-Ortiz  * SPDX-License-Identifier: BSD-3-Clause
5*6ae8fce3SJorge Ramirez-Ortiz  */
6*6ae8fce3SJorge Ramirez-Ortiz 
7*6ae8fce3SJorge Ramirez-Ortiz #include <assert.h>
8*6ae8fce3SJorge Ramirez-Ortiz #include <stddef.h>
9*6ae8fce3SJorge Ramirez-Ortiz #include <stdint.h>
10*6ae8fce3SJorge Ramirez-Ortiz 
11*6ae8fce3SJorge Ramirez-Ortiz #include <arch_helpers.h>
12*6ae8fce3SJorge Ramirez-Ortiz #include <common/debug.h>
13*6ae8fce3SJorge Ramirez-Ortiz #include <drivers/console.h>
14*6ae8fce3SJorge Ramirez-Ortiz #include <drivers/qti/accesscontrol/accesscontrol.h>
15*6ae8fce3SJorge Ramirez-Ortiz #include <lib/mmio.h>
16*6ae8fce3SJorge Ramirez-Ortiz #include <lib/spinlock.h>
17*6ae8fce3SJorge Ramirez-Ortiz #include <vmidmt.h>
18*6ae8fce3SJorge Ramirez-Ortiz #include <xpu_target_info.h>
19*6ae8fce3SJorge Ramirez-Ortiz 
20*6ae8fce3SJorge Ramirez-Ortiz #include <qti_interrupt_svc.h>
21*6ae8fce3SJorge Ramirez-Ortiz 
22*6ae8fce3SJorge Ramirez-Ortiz #define AC_PERM_X 0x1
23*6ae8fce3SJorge Ramirez-Ortiz #define AC_PERM_W 0x2
24*6ae8fce3SJorge Ramirez-Ortiz #define AC_PERM_R 0x4
25*6ae8fce3SJorge Ramirez-Ortiz 
26*6ae8fce3SJorge Ramirez-Ortiz static spinlock_t mem_assign_lock;
27*6ae8fce3SJorge Ramirez-Ortiz 
28*6ae8fce3SJorge Ramirez-Ortiz enum virtual_machine_id {
29*6ae8fce3SJorge Ramirez-Ortiz 	AC_VM_NONE = 0,
30*6ae8fce3SJorge Ramirez-Ortiz 	AC_VM_HLOS = 3,
31*6ae8fce3SJorge Ramirez-Ortiz 	AC_VM_MSS_MSA = 15,
32*6ae8fce3SJorge Ramirez-Ortiz 	AC_VM_MSS_NAV = 43,
33*6ae8fce3SJorge Ramirez-Ortiz 	AC_VM_LAST = 44,
34*6ae8fce3SJorge Ramirez-Ortiz 	AC_VM_MAX = 0x7FFFFFFF,
35*6ae8fce3SJorge Ramirez-Ortiz };
36*6ae8fce3SJorge Ramirez-Ortiz 
37*6ae8fce3SJorge Ramirez-Ortiz enum ac_error {
38*6ae8fce3SJorge Ramirez-Ortiz 	AC_SUCCESS = 0,
39*6ae8fce3SJorge Ramirez-Ortiz 	AC_FAILURE = 1,
40*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_VM_CREATE_FAIL = 2,
41*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_VM_MAP_FAIL1 = 3,
42*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_RAM_PARTITION_TABLE = 4,
43*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_VM_MAP_FAIL2 = 5,
44*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_VM_UNMAP_FAIL1 = 6,
45*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_VM_MAP_FAIL3 = 7,
46*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_VM_UNMAP_FAIL2 = 8,
47*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_TRANSLATION_SET1 = 9,
48*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_TRANSLATION_SET2 = 10,
49*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_TRANSLATION_SET3 = 11,
50*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_VALIDATION_FAIL1 = 12,
51*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_INCORRECT_VM = 13,
52*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_IO_ADDRESS_MISMATCH = 14,
53*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_SHARED_MEMORY_SINGLE_SOURCE = 15,
54*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_SHARED_MEMORY_SOURCE_MISMATCH = 16,
55*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_NOT_SHARED_MEMORY_MULTIPLE_SOURCE_GIVEN = 17,
56*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MAPPING_TYPE_NOT_SUPPORTED = 18,
57*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MAPPING_NOT_FOUND = 19,
58*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_REMOVE_MEMORY_FROM_LIST_FAIL = 20,
59*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_CLEAR_MEMORY_FAIL = 21,
60*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_IS_DEVICE_MEMORY = 22,
61*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_VMISMAPPED_FAILED = 23,
62*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_UNCACHED_ALLOC_FAILED = 24,
63*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MEMORY_NOT_OWNED_BY_SOURCE_VM = 25,
64*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_TZ_ASSIGN_SMC_FAILED = 26,
65*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_VM_UNMAP_FAIL3 = 27,
66*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_VM_MAP_FAIL4 = 28,
67*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MEMORY_FULL = 29,
68*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MEMORY_IN_OWNED_BY_TZ = 30,
69*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MEMORY_IN_USE_BY_TZ = 31,
70*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_XPU_TYPE_NOT_SUPPORTED = 32,
71*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_XPU_REMOVE_MAPPING_FAILED = 33,
72*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_XPU_ADD_MAPPING_FAILED = 34,
73*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MEMORY_NOT_FOUND_IN_LIST = 35,
74*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MEMORY_ALREADY_IN_LIST = 36,
75*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_ADD_MEMORY_FROM_LIST_FAIL = 37,
76*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_SIZE_GREATER_THAN_32BITS = 38,
77*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_INVALID_INDEX = 39,
78*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_UPDATING_RAM_PARTITION_TABLE = 40,
79*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_NOT_4K_ALIGNED = 41,
80*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MEMORY_NOT_IN_LIST = 42,
81*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_NOT_DDR_MEMORY = 43,
82*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_IPA_OVERFLOW = 44,
83*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_SRC_SIZE_ZERO = 45,
84*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_SRC_LIST_NULL = 46,
85*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_DST_SIZE_ZERO = 47,
86*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_DST_LIST_NULL = 48,
87*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_SID2VM_SMMU_API_FAILED = 49,
88*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_SID_VALIDATION_FAIL = 50,
89*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_UNABLE_TO_XPU_LOCK = 51,
90*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_STRUCT_SIZE_LESS_THAN_EXPECTED = 52,
91*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_INVALID_POINTER = 53,
92*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_IPA_LIST_NULL = 54,
93*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_IPA_LIST_SIZE_ZER0 = 55,
94*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MMU_ADD_MAPPING_FAILED = 56,
95*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MMU_REMOVE_MAPPING_FAILED = 57,
96*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_INVALID_PERM_TYPE = 58,
97*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MPU_LOCK_MEMORY_FAILED = 59,
98*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MPU_UNLOCK_MEMORY_FAILED = 60,
99*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_USECASE_NOT_SUPPORTED = 61,
100*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_SRC_VM_TZ_INVALID = 62,
101*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_NULL_POINTER = 63,
102*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_TZ_IO_ASSIGN_SMC_FAILED = 64,
103*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_NOT_DEVICE_MEMORY = 65,
104*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_SMMU_CFG_TYPE_INVALID = 66,
105*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_INCORRECT_PERM = 67,
106*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MEMORY_IS_SHARED = 68,
107*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_CANNOT_CHANGE_HLOS_RO_MEMORY = 69,
108*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_UNABLE_TO_XPU_UNLOCK = 70,
109*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_ADD_CLEAR_REGION_FAILED = 71,
110*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_REMOVE_CLEAR_REGION_FAILED = 72,
111*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_OVERLAPPING_MEMORY = 73,
112*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_DEVICE_RANGE_CHECK_OVERFLOW = 74,
113*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_ITS_A_SECURE_DEVICE = 75,
114*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_NOT_IN_WHITELIST = 76,
115*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_API_FAILED = 77,
116*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_SRC_NUM_INVALID = 78,
117*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_NUM_MAPPING_OVERFLOW = 79,
118*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_DST_NUM_INVALID = 80,
119*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_INCORRECT_DEVICE = 81,
120*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_DEVICE_NOT_FOUND = 82,
121*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_XPU_PARTIAL_MAPPING_NOT_ALLOWED = 83,
122*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_HASH_OVERFLOW = 84,
123*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_RULE_NOT_FOUND = 85,
124*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_TZ_SHM_CREATE_SMC_FAILED = 86,
125*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_VM_SIZE_OVERFLOW = 87,
126*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_SHM_BRIDGE_NOT_FOUND = 88,
127*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_GETTING_RANDOM_NUMBER = 89,
128*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_CALLER_VM_ID_INCORRECT = 90,
129*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_SHM_RULE_NOT_FOUND = 91,
130*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MUTEX_ACQUIRE_FAIL = 92,
131*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MUTEX_RELEASE_FAIL = 93,
132*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_OUTPUT_ADDRESS_MISMATCH = 94,
133*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_DST_VM_TZ_INVALID = 95,
134*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MPU_UPDATE_LOCK_MEMORY_FAILED = 96,
135*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_DDR_MPU_STATIC_CFG_BLACKLIST_UPDATE = 97,
136*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_FATAL_ACCESS_CONTROL = 98,
137*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_LAST,
138*6ae8fce3SJorge Ramirez-Ortiz 	AC_ERR_MAX = 0x7FFFFFFF,
139*6ae8fce3SJorge Ramirez-Ortiz };
140*6ae8fce3SJorge Ramirez-Ortiz 
141*6ae8fce3SJorge Ramirez-Ortiz #define ACC_INT_XPU_NON_SEC_DESC "SPI XPU NonSec"
142*6ae8fce3SJorge Ramirez-Ortiz #define ACC_INT_XPU_SEC_DESC "SPI XPU Sec"
143*6ae8fce3SJorge Ramirez-Ortiz 
144*6ae8fce3SJorge Ramirez-Ortiz static int xpu_err_non_sec_ctx = XPU_ERR_NON_SEC_CTX;
145*6ae8fce3SJorge Ramirez-Ortiz static int xpu_err_sec_ctx = XPU_ERR_SEC_CTX;
146*6ae8fce3SJorge Ramirez-Ortiz 
update_master_side_mpu(struct xpu_instance * instance,uint32_t dynamic_partition_count,enum domain_type domain,uintptr_t start_addr,uintptr_t end_addr,uint32_t perm_r,uint32_t perm_w)147*6ae8fce3SJorge Ramirez-Ortiz static int update_master_side_mpu(struct xpu_instance *instance,
148*6ae8fce3SJorge Ramirez-Ortiz 				  uint32_t dynamic_partition_count,
149*6ae8fce3SJorge Ramirez-Ortiz 				  enum domain_type domain, uintptr_t start_addr,
150*6ae8fce3SJorge Ramirez-Ortiz 				  uintptr_t end_addr, uint32_t perm_r,
151*6ae8fce3SJorge Ramirez-Ortiz 				  uint32_t perm_w)
152*6ae8fce3SJorge Ramirez-Ortiz {
153*6ae8fce3SJorge Ramirez-Ortiz 	uint64_t last_index = instance->part_range_arr_size;
154*6ae8fce3SJorge Ramirez-Ortiz 	uint64_t first_index = last_index - dynamic_partition_count;
155*6ae8fce3SJorge Ramirez-Ortiz 	struct rg_partition_range *range_base = instance->partition_range;
156*6ae8fce3SJorge Ramirez-Ortiz 	struct rg_domain_ownership *owner_base = instance->rg_owner;
157*6ae8fce3SJorge Ramirez-Ortiz 	struct rg_domain_ownership *found_owner = NULL;
158*6ae8fce3SJorge Ramirez-Ortiz 	struct rg_partition_range *found_range = NULL;
159*6ae8fce3SJorge Ramirez-Ortiz 	struct rg_domain_ownership *owner;
160*6ae8fce3SJorge Ramirez-Ortiz 	struct rg_partition_range *range;
161*6ae8fce3SJorge Ramirez-Ortiz 	uint64_t idx;
162*6ae8fce3SJorge Ramirez-Ortiz 
163*6ae8fce3SJorge Ramirez-Ortiz 	range = range_base + first_index;
164*6ae8fce3SJorge Ramirez-Ortiz 	owner = owner_base + first_index + 1; /* +1 for unmapped entry */
165*6ae8fce3SJorge Ramirez-Ortiz 
166*6ae8fce3SJorge Ramirez-Ortiz 	for (idx = first_index; idx < last_index; idx++, range++, owner++) {
167*6ae8fce3SJorge Ramirez-Ortiz 		/* Check if this RG already covers the requested range */
168*6ae8fce3SJorge Ramirez-Ortiz 		if (range->start_addr == start_addr &&
169*6ae8fce3SJorge Ramirez-Ortiz 		    range->end_addr == end_addr) {
170*6ae8fce3SJorge Ramirez-Ortiz 			/* Free region */
171*6ae8fce3SJorge Ramirez-Ortiz 			if (domain == APPS_NS_DOMAIN) {
172*6ae8fce3SJorge Ramirez-Ortiz 				start_addr = 0xfffffffful;
173*6ae8fce3SJorge Ramirez-Ortiz 				end_addr = 0xfffffffful;
174*6ae8fce3SJorge Ramirez-Ortiz 				domain = NO_DOMAIN;
175*6ae8fce3SJorge Ramirez-Ortiz 
176*6ae8fce3SJorge Ramirez-Ortiz 				INFO("freeing RG for xpu 0x%lx idx:%llu\n",
177*6ae8fce3SJorge Ramirez-Ortiz 				     (unsigned long)instance->xpu_base_addr,
178*6ae8fce3SJorge Ramirez-Ortiz 				     (unsigned long long)idx);
179*6ae8fce3SJorge Ramirez-Ortiz 			}
180*6ae8fce3SJorge Ramirez-Ortiz 
181*6ae8fce3SJorge Ramirez-Ortiz 			found_range = range;
182*6ae8fce3SJorge Ramirez-Ortiz 			found_owner = owner;
183*6ae8fce3SJorge Ramirez-Ortiz 			break;
184*6ae8fce3SJorge Ramirez-Ortiz 		}
185*6ae8fce3SJorge Ramirez-Ortiz 
186*6ae8fce3SJorge Ramirez-Ortiz 		/*
187*6ae8fce3SJorge Ramirez-Ortiz 		 * Keep the first free RG; might be overridden if we later
188*6ae8fce3SJorge Ramirez-Ortiz 		 * find an exact range match.
189*6ae8fce3SJorge Ramirez-Ortiz 		 */
190*6ae8fce3SJorge Ramirez-Ortiz 		if (owner->owner_domain == NO_DOMAIN &&
191*6ae8fce3SJorge Ramirez-Ortiz 		    range->start_addr == 0xfffffffful &&
192*6ae8fce3SJorge Ramirez-Ortiz 		    range->end_addr == 0xfffffffful) {
193*6ae8fce3SJorge Ramirez-Ortiz 			if (!found_range) {
194*6ae8fce3SJorge Ramirez-Ortiz 				found_range = range;
195*6ae8fce3SJorge Ramirez-Ortiz 				found_owner = owner;
196*6ae8fce3SJorge Ramirez-Ortiz 			}
197*6ae8fce3SJorge Ramirez-Ortiz 		}
198*6ae8fce3SJorge Ramirez-Ortiz 	}
199*6ae8fce3SJorge Ramirez-Ortiz 
200*6ae8fce3SJorge Ramirez-Ortiz 	if (!found_range) {
201*6ae8fce3SJorge Ramirez-Ortiz 		ERROR("No free RG xpu addr : 0x%lx",
202*6ae8fce3SJorge Ramirez-Ortiz 		      (unsigned long)instance->xpu_base_addr);
203*6ae8fce3SJorge Ramirez-Ortiz 		return 1;
204*6ae8fce3SJorge Ramirez-Ortiz 	}
205*6ae8fce3SJorge Ramirez-Ortiz 
206*6ae8fce3SJorge Ramirez-Ortiz 	found_owner->owner_domain = domain;
207*6ae8fce3SJorge Ramirez-Ortiz 	found_range->start_addr = start_addr;
208*6ae8fce3SJorge Ramirez-Ortiz 	found_range->end_addr = end_addr;
209*6ae8fce3SJorge Ramirez-Ortiz 
210*6ae8fce3SJorge Ramirez-Ortiz 	return xpu_lock_down_assets_dynamic(instance, 1, instance->xpu_id,
211*6ae8fce3SJorge Ramirez-Ortiz 					    found_range->rg_num, perm_r,
212*6ae8fce3SJorge Ramirez-Ortiz 					    perm_w);
213*6ae8fce3SJorge Ramirez-Ortiz }
214*6ae8fce3SJorge Ramirez-Ortiz 
mpu_master_mpus_range(enum device_type dev_type,enum domain_type domain,uintptr_t start_addr,uintptr_t end_addr,uint32_t perm_r,uint32_t perm_w)215*6ae8fce3SJorge Ramirez-Ortiz static int mpu_master_mpus_range(enum device_type dev_type,
216*6ae8fce3SJorge Ramirez-Ortiz 				 enum domain_type domain, uintptr_t start_addr,
217*6ae8fce3SJorge Ramirez-Ortiz 				 uintptr_t end_addr, uint32_t perm_r,
218*6ae8fce3SJorge Ramirez-Ortiz 				 uint32_t perm_w)
219*6ae8fce3SJorge Ramirez-Ortiz {
220*6ae8fce3SJorge Ramirez-Ortiz 	struct mpu_ranges *range = msm_mpu_ranges;
221*6ae8fce3SJorge Ramirez-Ortiz 	uint32_t i, j;
222*6ae8fce3SJorge Ramirez-Ortiz 	int ret = 0;
223*6ae8fce3SJorge Ramirez-Ortiz 
224*6ae8fce3SJorge Ramirez-Ortiz 	for (i = 0; i < msm_mpu_ranges_count; i++, range++) {
225*6ae8fce3SJorge Ramirez-Ortiz 		if (range->device != dev_type)
226*6ae8fce3SJorge Ramirez-Ortiz 			continue;
227*6ae8fce3SJorge Ramirez-Ortiz 
228*6ae8fce3SJorge Ramirez-Ortiz 		struct xpu_instance *mpu = range->mpus;
229*6ae8fce3SJorge Ramirez-Ortiz 
230*6ae8fce3SJorge Ramirez-Ortiz 		for (j = 0; j < range->mpus_count; j++, mpu++) {
231*6ae8fce3SJorge Ramirez-Ortiz 			ret = update_master_side_mpu(mpu,
232*6ae8fce3SJorge Ramirez-Ortiz 						     range->device_prtn_cnt,
233*6ae8fce3SJorge Ramirez-Ortiz 						     domain, start_addr,
234*6ae8fce3SJorge Ramirez-Ortiz 						     end_addr, perm_r, perm_w);
235*6ae8fce3SJorge Ramirez-Ortiz 			if (ret)
236*6ae8fce3SJorge Ramirez-Ortiz 				goto error;
237*6ae8fce3SJorge Ramirez-Ortiz 		}
238*6ae8fce3SJorge Ramirez-Ortiz 
239*6ae8fce3SJorge Ramirez-Ortiz 		/* We found the device; no need to scan the rest. */
240*6ae8fce3SJorge Ramirez-Ortiz 		break;
241*6ae8fce3SJorge Ramirez-Ortiz 	}
242*6ae8fce3SJorge Ramirez-Ortiz 
243*6ae8fce3SJorge Ramirez-Ortiz 	return 0;
244*6ae8fce3SJorge Ramirez-Ortiz 
245*6ae8fce3SJorge Ramirez-Ortiz error:
246*6ae8fce3SJorge Ramirez-Ortiz 	ERROR("Access control fatal (%x)\n",
247*6ae8fce3SJorge Ramirez-Ortiz 	      AC_ERR_MPU_UPDATE_LOCK_MEMORY_FAILED);
248*6ae8fce3SJorge Ramirez-Ortiz 
249*6ae8fce3SJorge Ramirez-Ortiz 	for (;;)
250*6ae8fce3SJorge Ramirez-Ortiz 		wfi();
251*6ae8fce3SJorge Ramirez-Ortiz 
252*6ae8fce3SJorge Ramirez-Ortiz 	return ret;
253*6ae8fce3SJorge Ramirez-Ortiz }
254*6ae8fce3SJorge Ramirez-Ortiz 
255*6ae8fce3SJorge Ramirez-Ortiz static enum ac_error
process_sources(const uint32_t * src_vm_list,uint32_t src_vm_count,const qti_accesscontrol_perm_t * dst_vm_list,uint32_t dst_vm_count,enum device_type * device,enum domain_type * domain)256*6ae8fce3SJorge Ramirez-Ortiz process_sources(const uint32_t *src_vm_list, uint32_t src_vm_count,
257*6ae8fce3SJorge Ramirez-Ortiz 		const qti_accesscontrol_perm_t *dst_vm_list,
258*6ae8fce3SJorge Ramirez-Ortiz 		uint32_t dst_vm_count, enum device_type *device,
259*6ae8fce3SJorge Ramirez-Ortiz 		enum domain_type *domain)
260*6ae8fce3SJorge Ramirez-Ortiz {
261*6ae8fce3SJorge Ramirez-Ortiz 	const uint32_t *src_vm;
262*6ae8fce3SJorge Ramirez-Ortiz 	const qti_accesscontrol_perm_t *dst_vm;
263*6ae8fce3SJorge Ramirez-Ortiz 	const qti_accesscontrol_perm_t *dst_vm_limit;
264*6ae8fce3SJorge Ramirez-Ortiz 	uint32_t src_index;
265*6ae8fce3SJorge Ramirez-Ortiz 	uint32_t dst_index;
266*6ae8fce3SJorge Ramirez-Ortiz 	uint32_t vm_also_in_other_list = 0U;
267*6ae8fce3SJorge Ramirez-Ortiz 
268*6ae8fce3SJorge Ramirez-Ortiz 	src_vm = src_vm_list;
269*6ae8fce3SJorge Ramirez-Ortiz 
270*6ae8fce3SJorge Ramirez-Ortiz 	for (src_index = 0U; src_index < src_vm_count; src_index++, src_vm++) {
271*6ae8fce3SJorge Ramirez-Ortiz 		uint32_t src_vm_id = *src_vm;
272*6ae8fce3SJorge Ramirez-Ortiz 
273*6ae8fce3SJorge Ramirez-Ortiz 		if (src_vm_id != AC_VM_MSS_MSA && src_vm_id != AC_VM_MSS_NAV)
274*6ae8fce3SJorge Ramirez-Ortiz 			continue;
275*6ae8fce3SJorge Ramirez-Ortiz 
276*6ae8fce3SJorge Ramirez-Ortiz 		/* Check if same VM appears as destination */
277*6ae8fce3SJorge Ramirez-Ortiz 		dst_vm = dst_vm_list;
278*6ae8fce3SJorge Ramirez-Ortiz 		dst_vm_limit =
279*6ae8fce3SJorge Ramirez-Ortiz 			dst_vm_list + ((dst_vm_count < (uint32_t)AC_VM_LAST) ?
280*6ae8fce3SJorge Ramirez-Ortiz 					       dst_vm_count :
281*6ae8fce3SJorge Ramirez-Ortiz 					       (uint32_t)AC_VM_LAST);
282*6ae8fce3SJorge Ramirez-Ortiz 
283*6ae8fce3SJorge Ramirez-Ortiz 		for (dst_index = 0U; dst_vm < dst_vm_limit;
284*6ae8fce3SJorge Ramirez-Ortiz 		     dst_index++, dst_vm++) {
285*6ae8fce3SJorge Ramirez-Ortiz 			if (dst_vm->dst_vm != src_vm_id)
286*6ae8fce3SJorge Ramirez-Ortiz 				continue;
287*6ae8fce3SJorge Ramirez-Ortiz 
288*6ae8fce3SJorge Ramirez-Ortiz 			vm_also_in_other_list = 1U;
289*6ae8fce3SJorge Ramirez-Ortiz 			break;
290*6ae8fce3SJorge Ramirez-Ortiz 		}
291*6ae8fce3SJorge Ramirez-Ortiz 
292*6ae8fce3SJorge Ramirez-Ortiz 		if (vm_also_in_other_list != 0U) {
293*6ae8fce3SJorge Ramirez-Ortiz 			vm_also_in_other_list = 0U;
294*6ae8fce3SJorge Ramirez-Ortiz 			continue;
295*6ae8fce3SJorge Ramirez-Ortiz 		}
296*6ae8fce3SJorge Ramirez-Ortiz 
297*6ae8fce3SJorge Ramirez-Ortiz 		if (src_vm_id == AC_VM_MSS_MSA)
298*6ae8fce3SJorge Ramirez-Ortiz 			*device = DEVICE_MODEM;
299*6ae8fce3SJorge Ramirez-Ortiz 		else if (src_vm_id == AC_VM_MSS_NAV)
300*6ae8fce3SJorge Ramirez-Ortiz 			*device = DEVICE_MSS_NAV;
301*6ae8fce3SJorge Ramirez-Ortiz 		else
302*6ae8fce3SJorge Ramirez-Ortiz 			return AC_ERR_XPU_TYPE_NOT_SUPPORTED;
303*6ae8fce3SJorge Ramirez-Ortiz 
304*6ae8fce3SJorge Ramirez-Ortiz 		*domain = APPS_NS_DOMAIN;
305*6ae8fce3SJorge Ramirez-Ortiz 	}
306*6ae8fce3SJorge Ramirez-Ortiz 
307*6ae8fce3SJorge Ramirez-Ortiz 	return AC_SUCCESS;
308*6ae8fce3SJorge Ramirez-Ortiz }
309*6ae8fce3SJorge Ramirez-Ortiz 
310*6ae8fce3SJorge Ramirez-Ortiz static enum ac_error
process_destinations(const uint32_t * src_vm_list,uint32_t src_vm_count,const qti_accesscontrol_perm_t * dst_vm_list,uint32_t dst_vm_count,enum device_type * device,enum domain_type * domain,uint32_t * read_perm_domain,uint32_t * write_perm_domain)311*6ae8fce3SJorge Ramirez-Ortiz process_destinations(const uint32_t *src_vm_list, uint32_t src_vm_count,
312*6ae8fce3SJorge Ramirez-Ortiz 		     const qti_accesscontrol_perm_t *dst_vm_list,
313*6ae8fce3SJorge Ramirez-Ortiz 		     uint32_t dst_vm_count, enum device_type *device,
314*6ae8fce3SJorge Ramirez-Ortiz 		     enum domain_type *domain, uint32_t *read_perm_domain,
315*6ae8fce3SJorge Ramirez-Ortiz 		     uint32_t *write_perm_domain)
316*6ae8fce3SJorge Ramirez-Ortiz {
317*6ae8fce3SJorge Ramirez-Ortiz 	const qti_accesscontrol_perm_t *dst_vm;
318*6ae8fce3SJorge Ramirez-Ortiz 	const uint32_t *src_check;
319*6ae8fce3SJorge Ramirez-Ortiz 	uint32_t vm_also_in_other_list = 0U;
320*6ae8fce3SJorge Ramirez-Ortiz 	uint32_t dst_index;
321*6ae8fce3SJorge Ramirez-Ortiz 	uint32_t src_index;
322*6ae8fce3SJorge Ramirez-Ortiz 
323*6ae8fce3SJorge Ramirez-Ortiz 	dst_vm = dst_vm_list;
324*6ae8fce3SJorge Ramirez-Ortiz 
325*6ae8fce3SJorge Ramirez-Ortiz 	for (dst_index = 0U; dst_index < dst_vm_count; dst_index++, dst_vm++) {
326*6ae8fce3SJorge Ramirez-Ortiz 		uint32_t dst_vm_id = dst_vm->dst_vm;
327*6ae8fce3SJorge Ramirez-Ortiz 		uint32_t dst_vm_perm = dst_vm->dst_vm_perm;
328*6ae8fce3SJorge Ramirez-Ortiz 
329*6ae8fce3SJorge Ramirez-Ortiz 		if (dst_vm_id != AC_VM_MSS_MSA && dst_vm_id != AC_VM_MSS_NAV)
330*6ae8fce3SJorge Ramirez-Ortiz 			continue;
331*6ae8fce3SJorge Ramirez-Ortiz 
332*6ae8fce3SJorge Ramirez-Ortiz 		/* Check if same VM exists in source list */
333*6ae8fce3SJorge Ramirez-Ortiz 		src_check = src_vm_list;
334*6ae8fce3SJorge Ramirez-Ortiz 		for (src_index = 0U; src_index < src_vm_count;
335*6ae8fce3SJorge Ramirez-Ortiz 		     src_index++, src_check++) {
336*6ae8fce3SJorge Ramirez-Ortiz 			if (dst_vm_id != *src_check)
337*6ae8fce3SJorge Ramirez-Ortiz 				continue;
338*6ae8fce3SJorge Ramirez-Ortiz 
339*6ae8fce3SJorge Ramirez-Ortiz 			vm_also_in_other_list = 1U;
340*6ae8fce3SJorge Ramirez-Ortiz 			break;
341*6ae8fce3SJorge Ramirez-Ortiz 		}
342*6ae8fce3SJorge Ramirez-Ortiz 
343*6ae8fce3SJorge Ramirez-Ortiz 		if (vm_also_in_other_list != 0U) {
344*6ae8fce3SJorge Ramirez-Ortiz 			vm_also_in_other_list = 0U;
345*6ae8fce3SJorge Ramirez-Ortiz 			continue;
346*6ae8fce3SJorge Ramirez-Ortiz 		}
347*6ae8fce3SJorge Ramirez-Ortiz 
348*6ae8fce3SJorge Ramirez-Ortiz 		if (dst_vm_id == AC_VM_MSS_MSA)
349*6ae8fce3SJorge Ramirez-Ortiz 			*device = DEVICE_MODEM;
350*6ae8fce3SJorge Ramirez-Ortiz 		else if (dst_vm_id == AC_VM_MSS_NAV)
351*6ae8fce3SJorge Ramirez-Ortiz 			*device = DEVICE_MSS_NAV;
352*6ae8fce3SJorge Ramirez-Ortiz 		else
353*6ae8fce3SJorge Ramirez-Ortiz 			return AC_ERR_XPU_TYPE_NOT_SUPPORTED;
354*6ae8fce3SJorge Ramirez-Ortiz 
355*6ae8fce3SJorge Ramirez-Ortiz 		/* Permissions */
356*6ae8fce3SJorge Ramirez-Ortiz 		if ((dst_vm_perm & AC_PERM_W) != 0U)
357*6ae8fce3SJorge Ramirez-Ortiz 			*write_perm_domain = MSA_DOMAIN;
358*6ae8fce3SJorge Ramirez-Ortiz 
359*6ae8fce3SJorge Ramirez-Ortiz 		if ((dst_vm_perm & AC_PERM_R) != 0U)
360*6ae8fce3SJorge Ramirez-Ortiz 			*read_perm_domain = MSA_DOMAIN;
361*6ae8fce3SJorge Ramirez-Ortiz 
362*6ae8fce3SJorge Ramirez-Ortiz 		/* Modem keeps secure RG ownership permanently */
363*6ae8fce3SJorge Ramirez-Ortiz 		*domain = APPS_S_DOMAIN;
364*6ae8fce3SJorge Ramirez-Ortiz 	}
365*6ae8fce3SJorge Ramirez-Ortiz 
366*6ae8fce3SJorge Ramirez-Ortiz 	return AC_SUCCESS;
367*6ae8fce3SJorge Ramirez-Ortiz }
368*6ae8fce3SJorge Ramirez-Ortiz 
assign_regions(const qti_accesscontrol_mem_t * mem_regions,uint32_t mem_region_count,enum device_type device,enum domain_type domain,uint32_t read_perm_domain,uint32_t write_perm_domain)369*6ae8fce3SJorge Ramirez-Ortiz static enum ac_error assign_regions(const qti_accesscontrol_mem_t *mem_regions,
370*6ae8fce3SJorge Ramirez-Ortiz 				    uint32_t mem_region_count,
371*6ae8fce3SJorge Ramirez-Ortiz 				    enum device_type device,
372*6ae8fce3SJorge Ramirez-Ortiz 				    enum domain_type domain,
373*6ae8fce3SJorge Ramirez-Ortiz 				    uint32_t read_perm_domain,
374*6ae8fce3SJorge Ramirez-Ortiz 				    uint32_t write_perm_domain)
375*6ae8fce3SJorge Ramirez-Ortiz {
376*6ae8fce3SJorge Ramirez-Ortiz 	const qti_accesscontrol_mem_t *mem_region = mem_regions;
377*6ae8fce3SJorge Ramirez-Ortiz 	uint32_t mem_index;
378*6ae8fce3SJorge Ramirez-Ortiz 
379*6ae8fce3SJorge Ramirez-Ortiz 	for (mem_index = 0U; mem_index < mem_region_count;
380*6ae8fce3SJorge Ramirez-Ortiz 	     mem_index++, mem_region++) {
381*6ae8fce3SJorge Ramirez-Ortiz 		uintptr_t region_base = mem_region->mem_addr;
382*6ae8fce3SJorge Ramirez-Ortiz 		uintptr_t region_size = mem_region->mem_size;
383*6ae8fce3SJorge Ramirez-Ortiz 		uintptr_t region_end = region_base + region_size;
384*6ae8fce3SJorge Ramirez-Ortiz 		int rc;
385*6ae8fce3SJorge Ramirez-Ortiz 
386*6ae8fce3SJorge Ramirez-Ortiz 		rc = mpu_master_mpus_range(device, domain, region_base,
387*6ae8fce3SJorge Ramirez-Ortiz 					   region_end, read_perm_domain,
388*6ae8fce3SJorge Ramirez-Ortiz 					   write_perm_domain);
389*6ae8fce3SJorge Ramirez-Ortiz 		if (rc != 0)
390*6ae8fce3SJorge Ramirez-Ortiz 			return AC_ERR_XPU_ADD_MAPPING_FAILED;
391*6ae8fce3SJorge Ramirez-Ortiz 	}
392*6ae8fce3SJorge Ramirez-Ortiz 
393*6ae8fce3SJorge Ramirez-Ortiz 	return AC_SUCCESS;
394*6ae8fce3SJorge Ramirez-Ortiz }
395*6ae8fce3SJorge Ramirez-Ortiz 
mem_assign(const qti_accesscontrol_mem_t * mem_regions,uint32_t mem_region_count,const uint32_t * src_vm_list,uint32_t src_vm_count,const qti_accesscontrol_perm_t * dst_vm_list,uint32_t dst_vm_count)396*6ae8fce3SJorge Ramirez-Ortiz static uint64_t mem_assign(const qti_accesscontrol_mem_t *mem_regions,
397*6ae8fce3SJorge Ramirez-Ortiz 			   uint32_t mem_region_count,
398*6ae8fce3SJorge Ramirez-Ortiz 			   const uint32_t *src_vm_list, uint32_t src_vm_count,
399*6ae8fce3SJorge Ramirez-Ortiz 			   const qti_accesscontrol_perm_t *dst_vm_list,
400*6ae8fce3SJorge Ramirez-Ortiz 			   uint32_t dst_vm_count)
401*6ae8fce3SJorge Ramirez-Ortiz {
402*6ae8fce3SJorge Ramirez-Ortiz 	enum ac_error result = AC_SUCCESS;
403*6ae8fce3SJorge Ramirez-Ortiz 	uint32_t write_perm_domain = NO_DOMAIN;
404*6ae8fce3SJorge Ramirez-Ortiz 	uint32_t read_perm_domain = NO_DOMAIN;
405*6ae8fce3SJorge Ramirez-Ortiz 	enum domain_type domain = NO_DOMAIN;
406*6ae8fce3SJorge Ramirez-Ortiz 	enum device_type device = 0;
407*6ae8fce3SJorge Ramirez-Ortiz 
408*6ae8fce3SJorge Ramirez-Ortiz 	spin_lock(&mem_assign_lock);
409*6ae8fce3SJorge Ramirez-Ortiz 
410*6ae8fce3SJorge Ramirez-Ortiz 	result = process_sources(src_vm_list, src_vm_count, dst_vm_list,
411*6ae8fce3SJorge Ramirez-Ortiz 				 dst_vm_count, &device, &domain);
412*6ae8fce3SJorge Ramirez-Ortiz 	if (result != AC_SUCCESS)
413*6ae8fce3SJorge Ramirez-Ortiz 		goto out;
414*6ae8fce3SJorge Ramirez-Ortiz 
415*6ae8fce3SJorge Ramirez-Ortiz 	result = process_destinations(src_vm_list, src_vm_count, dst_vm_list,
416*6ae8fce3SJorge Ramirez-Ortiz 				      dst_vm_count, &device, &domain,
417*6ae8fce3SJorge Ramirez-Ortiz 				      &read_perm_domain, &write_perm_domain);
418*6ae8fce3SJorge Ramirez-Ortiz 	if (result != AC_SUCCESS)
419*6ae8fce3SJorge Ramirez-Ortiz 		goto out;
420*6ae8fce3SJorge Ramirez-Ortiz 
421*6ae8fce3SJorge Ramirez-Ortiz 	result = assign_regions(mem_regions, mem_region_count, device, domain,
422*6ae8fce3SJorge Ramirez-Ortiz 				read_perm_domain, write_perm_domain);
423*6ae8fce3SJorge Ramirez-Ortiz 	if (result != AC_SUCCESS)
424*6ae8fce3SJorge Ramirez-Ortiz 		goto out;
425*6ae8fce3SJorge Ramirez-Ortiz 
426*6ae8fce3SJorge Ramirez-Ortiz out:
427*6ae8fce3SJorge Ramirez-Ortiz 	spin_unlock(&mem_assign_lock);
428*6ae8fce3SJorge Ramirez-Ortiz 
429*6ae8fce3SJorge Ramirez-Ortiz 	if (result != AC_SUCCESS) {
430*6ae8fce3SJorge Ramirez-Ortiz 		ERROR("Access Control: memory assignment failed %x\n", result);
431*6ae8fce3SJorge Ramirez-Ortiz 		return (uint64_t)-1;
432*6ae8fce3SJorge Ramirez-Ortiz 	}
433*6ae8fce3SJorge Ramirez-Ortiz 
434*6ae8fce3SJorge Ramirez-Ortiz 	return 0;
435*6ae8fce3SJorge Ramirez-Ortiz }
436*6ae8fce3SJorge Ramirez-Ortiz 
xpu_isr(uint32_t int_num,void * ctx)437*6ae8fce3SJorge Ramirez-Ortiz static void *xpu_isr(uint32_t int_num, void *ctx)
438*6ae8fce3SJorge Ramirez-Ortiz {
439*6ae8fce3SJorge Ramirez-Ortiz 	xpu_print_log(ctx);
440*6ae8fce3SJorge Ramirez-Ortiz 	console_flush();
441*6ae8fce3SJorge Ramirez-Ortiz 
442*6ae8fce3SJorge Ramirez-Ortiz 	return ctx;
443*6ae8fce3SJorge Ramirez-Ortiz }
444*6ae8fce3SJorge Ramirez-Ortiz 
xpu_register_interrupts(void)445*6ae8fce3SJorge Ramirez-Ortiz static int xpu_register_interrupts(void)
446*6ae8fce3SJorge Ramirez-Ortiz {
447*6ae8fce3SJorge Ramirez-Ortiz 	int err = 0;
448*6ae8fce3SJorge Ramirez-Ortiz 
449*6ae8fce3SJorge Ramirez-Ortiz 	err = qti_interrupt_svc_register(QTISECLIB_INT_ID_XPU_SEC, xpu_isr,
450*6ae8fce3SJorge Ramirez-Ortiz 					 &xpu_err_sec_ctx);
451*6ae8fce3SJorge Ramirez-Ortiz 	if (err)
452*6ae8fce3SJorge Ramirez-Ortiz 		return err;
453*6ae8fce3SJorge Ramirez-Ortiz 
454*6ae8fce3SJorge Ramirez-Ortiz 	err = qti_interrupt_svc_register(QTISECLIB_INT_ID_XPU_NON_SEC, xpu_isr,
455*6ae8fce3SJorge Ramirez-Ortiz 					 &xpu_err_non_sec_ctx);
456*6ae8fce3SJorge Ramirez-Ortiz 	if (err)
457*6ae8fce3SJorge Ramirez-Ortiz 		qti_interrupt_svc_unregister(QTISECLIB_INT_ID_XPU_SEC);
458*6ae8fce3SJorge Ramirez-Ortiz 
459*6ae8fce3SJorge Ramirez-Ortiz 	return err;
460*6ae8fce3SJorge Ramirez-Ortiz }
461*6ae8fce3SJorge Ramirez-Ortiz 
enable_interrupts(const struct xpu_intr_reg_dtls * nsec,const struct xpu_intr_reg_dtls * sec)462*6ae8fce3SJorge Ramirez-Ortiz static void enable_interrupts(const struct xpu_intr_reg_dtls *nsec,
463*6ae8fce3SJorge Ramirez-Ortiz 			      const struct xpu_intr_reg_dtls *sec)
464*6ae8fce3SJorge Ramirez-Ortiz {
465*6ae8fce3SJorge Ramirez-Ortiz 	for (size_t i = 0; i < ACC_XPU_ERR_INT_REG_NUM; i++) {
466*6ae8fce3SJorge Ramirez-Ortiz 		if (nsec) {
467*6ae8fce3SJorge Ramirez-Ortiz 			mmio_setbits_32(nsec->xpu_intr_reg_addr,
468*6ae8fce3SJorge Ramirez-Ortiz 					nsec->xpu_intr_reg_mask);
469*6ae8fce3SJorge Ramirez-Ortiz 			nsec++;
470*6ae8fce3SJorge Ramirez-Ortiz 		}
471*6ae8fce3SJorge Ramirez-Ortiz 
472*6ae8fce3SJorge Ramirez-Ortiz 		if (sec) {
473*6ae8fce3SJorge Ramirez-Ortiz 			mmio_setbits_32(sec->xpu_intr_reg_addr,
474*6ae8fce3SJorge Ramirez-Ortiz 					sec->xpu_intr_reg_mask);
475*6ae8fce3SJorge Ramirez-Ortiz 			sec++;
476*6ae8fce3SJorge Ramirez-Ortiz 		}
477*6ae8fce3SJorge Ramirez-Ortiz 	}
478*6ae8fce3SJorge Ramirez-Ortiz }
479*6ae8fce3SJorge Ramirez-Ortiz 
xpu_static_config(void)480*6ae8fce3SJorge Ramirez-Ortiz static void xpu_static_config(void)
481*6ae8fce3SJorge Ramirez-Ortiz {
482*6ae8fce3SJorge Ramirez-Ortiz 	xpu_master_mpu_init(msm_mpu_ranges, msm_mpu_ranges_count);
483*6ae8fce3SJorge Ramirez-Ortiz 	xpu_lock_down_assets(msm_xpu_cfg, msm_xpu_cfg_count);
484*6ae8fce3SJorge Ramirez-Ortiz 	xpu_configure_tz();
485*6ae8fce3SJorge Ramirez-Ortiz 	dsbsy();
486*6ae8fce3SJorge Ramirez-Ortiz 
487*6ae8fce3SJorge Ramirez-Ortiz 	enable_interrupts(xpu_non_sec_intr_en_reg, xpu_sec_intr_en_reg);
488*6ae8fce3SJorge Ramirez-Ortiz }
489*6ae8fce3SJorge Ramirez-Ortiz 
qti_accesscontrol_mem_assign(const qti_accesscontrol_mem_t * mem,uint32_t mem_len,const uint32_t * src,uint32_t src_len,const qti_accesscontrol_perm_t * perm,uint32_t perm_len)490*6ae8fce3SJorge Ramirez-Ortiz uint64_t qti_accesscontrol_mem_assign(const qti_accesscontrol_mem_t *mem,
491*6ae8fce3SJorge Ramirez-Ortiz 				      uint32_t mem_len, const uint32_t *src,
492*6ae8fce3SJorge Ramirez-Ortiz 				      uint32_t src_len,
493*6ae8fce3SJorge Ramirez-Ortiz 				      const qti_accesscontrol_perm_t *perm,
494*6ae8fce3SJorge Ramirez-Ortiz 				      uint32_t perm_len)
495*6ae8fce3SJorge Ramirez-Ortiz {
496*6ae8fce3SJorge Ramirez-Ortiz 	return mem_assign(mem, mem_len, src, src_len, perm, perm_len);
497*6ae8fce3SJorge Ramirez-Ortiz }
498*6ae8fce3SJorge Ramirez-Ortiz 
qti_accesscontrol_init(void)499*6ae8fce3SJorge Ramirez-Ortiz void qti_accesscontrol_init(void)
500*6ae8fce3SJorge Ramirez-Ortiz {
501*6ae8fce3SJorge Ramirez-Ortiz 	int rc;
502*6ae8fce3SJorge Ramirez-Ortiz 
503*6ae8fce3SJorge Ramirez-Ortiz 	rc = vmidmt_configure();
504*6ae8fce3SJorge Ramirez-Ortiz 	if (rc) {
505*6ae8fce3SJorge Ramirez-Ortiz 		ERROR("Error configuring the VMIDMT, fatal (%d)\n", rc);
506*6ae8fce3SJorge Ramirez-Ortiz 		goto error;
507*6ae8fce3SJorge Ramirez-Ortiz 	}
508*6ae8fce3SJorge Ramirez-Ortiz 
509*6ae8fce3SJorge Ramirez-Ortiz 	xpu_static_config();
510*6ae8fce3SJorge Ramirez-Ortiz 
511*6ae8fce3SJorge Ramirez-Ortiz 	rc = xpu_register_interrupts();
512*6ae8fce3SJorge Ramirez-Ortiz 	if (rc) {
513*6ae8fce3SJorge Ramirez-Ortiz 		ERROR("Error registering the XPU interrupts, fatal\n");
514*6ae8fce3SJorge Ramirez-Ortiz 		goto error;
515*6ae8fce3SJorge Ramirez-Ortiz 	}
516*6ae8fce3SJorge Ramirez-Ortiz 
517*6ae8fce3SJorge Ramirez-Ortiz 	return;
518*6ae8fce3SJorge Ramirez-Ortiz error:
519*6ae8fce3SJorge Ramirez-Ortiz 	for (;;)
520*6ae8fce3SJorge Ramirez-Ortiz 		wfi();
521*6ae8fce3SJorge Ramirez-Ortiz }
522