xref: /rk3399_ARM-atf/plat/qti/common/src/qti_common.c (revision 6dc5979a6cb2121e4c16e7bd62e24030e0f42755)
1 /*
2  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3  * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <assert.h>
9 #include <errno.h>
10 #include <stdbool.h>
11 #include <stdint.h>
12 
13 #include <common/debug.h>
14 #include <lib/mmio.h>
15 #include <lib/smccc.h>
16 #include <lib/xlat_tables/xlat_tables_v2.h>
17 #include <services/arm_arch_svc.h>
18 
19 #include <platform_def.h>
20 #include <qti_plat.h>
21 #include <qtiseclib_interface.h>
22 
23 /*
24  * Table of regions for various BL stages to map using the MMU.
25  * This doesn't include TZRAM as the 'mem_layout' argument passed to
26  * qti_configure_mmu_elx() will give the available subset of that,
27  */
28 
29 const mmap_region_t plat_qti_mmap[] = {
30 	MAP_REGION_FLAT(QTI_DEVICE_BASE, QTI_DEVICE_SIZE,
31 			MT_DEVICE | MT_RW | MT_SECURE),
32 	MAP_REGION_FLAT(QTI_AOP_CMD_DB_BASE, QTI_AOP_CMD_DB_SIZE,
33 			MT_NS | MT_RO | MT_EXECUTE_NEVER),
34 	{0}
35 };
36 
37 CASSERT(ARRAY_SIZE(plat_qti_mmap) <= MAX_MMAP_REGIONS, assert_max_mmap_regions);
38 
39 
40 bool qti_is_overlap_atf_rg(unsigned long long addr, size_t size)
41 {
42 	if (addr > addr + size
43 			|| (BL31_BASE < addr + size && BL31_LIMIT > addr)) {
44 		return true;
45 	}
46 	return false;
47 }
48 
49 /*
50  *  unsigned int plat_qti_my_cluster_pos(void)
51  *  definition to get the cluster index of the calling CPU.
52  *  - In ARM v8   (MPIDR_EL1[24]=0)
53  *    ClusterId = MPIDR_EL1[15:8]
54  *  - In ARM v8.1 & Later version (MPIDR_EL1[24]=1)
55  *    ClusterId = MPIDR_EL1[23:15]
56  */
57 unsigned int plat_qti_my_cluster_pos(void)
58 {
59 	unsigned int mpidr, cluster_id;
60 
61 	mpidr = read_mpidr_el1();
62 	if ((mpidr & MPIDR_MT_MASK) == 0) {	/* MT not supported */
63 		cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
64 	} else {		/* MT supported */
65 		cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
66 	}
67 	assert(cluster_id < PLAT_CLUSTER_COUNT);
68 	return cluster_id;
69 }
70 
71 /*
72  * Set up the page tables for the generic and platform-specific memory regions.
73  * The extents of the generic memory regions are specified by the function
74  * arguments and consist of:
75  * - Trusted SRAM seen by the BL image;
76  * - Code section;
77  * - Read-only data section;
78  * - Coherent memory region, if applicable.
79  */
80 void qti_setup_page_tables(
81 			   uintptr_t total_base,
82 			   size_t total_size,
83 			   uintptr_t code_start,
84 			   uintptr_t code_limit,
85 			   uintptr_t rodata_start,
86 			   uintptr_t rodata_limit
87 			  )
88 {
89 	/*
90 	 * Map the Trusted SRAM with appropriate memory attributes.
91 	 * Subsequent mappings will adjust the attributes for specific regions.
92 	 */
93 	VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n",
94 		(void *)total_base, (void *)(total_base + total_size));
95 	mmap_add_region(total_base, total_base,
96 			total_size, MT_MEMORY | MT_RW | MT_SECURE);
97 
98 	/* Re-map the code section */
99 	VERBOSE("Code region: %p - %p\n",
100 		(void *)code_start, (void *)code_limit);
101 	mmap_add_region(code_start, code_start,
102 			code_limit - code_start, MT_CODE | MT_SECURE);
103 
104 	/* Re-map the read-only data section */
105 	VERBOSE("Read-only data region: %p - %p\n",
106 		(void *)rodata_start, (void *)rodata_limit);
107 	mmap_add_region(rodata_start, rodata_start,
108 			rodata_limit - rodata_start, MT_RO_DATA | MT_SECURE);
109 
110 	/* Now (re-)map the platform-specific memory regions */
111 	mmap_add(plat_qti_mmap);
112 
113 	/* Create the page tables to reflect the above mappings */
114 	init_xlat_tables();
115 }
116 
117 static inline void qti_align_mem_region(uintptr_t addr, size_t size,
118 					uintptr_t *aligned_addr,
119 					size_t *aligned_size)
120 {
121 	*aligned_addr = round_down(addr, PAGE_SIZE);
122 	*aligned_size = round_up(addr - *aligned_addr + size, PAGE_SIZE);
123 }
124 
125 int qti_mmap_add_dynamic_region(uintptr_t base_pa, size_t size,
126 				unsigned int attr)
127 {
128 	uintptr_t aligned_pa;
129 	size_t aligned_size;
130 
131 	qti_align_mem_region(base_pa, size, &aligned_pa, &aligned_size);
132 
133 	if (qti_is_overlap_atf_rg(base_pa, size)) {
134 		/* Memory shouldn't overlap with TF-A range. */
135 		return -EPERM;
136 	}
137 
138 	return mmap_add_dynamic_region(aligned_pa, aligned_pa, aligned_size,
139 				       attr);
140 }
141 
142 int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
143 {
144 	qti_align_mem_region(base_va, size, &base_va, &size);
145 	return mmap_remove_dynamic_region(base_va, size);
146 }
147 
148 /*
149  * This function returns soc version which mainly consist of below fields
150  *
151  * soc_version[30:24] = JEP-106 continuation code for the SiP
152  * soc_version[23:16] = JEP-106 identification code with parity bit for the SiP
153  * soc_version[0:15]  = Implementation defined SoC ID
154  */
155 int32_t plat_get_soc_version(void)
156 {
157 	uint32_t soc_version = (QTI_SOC_VERSION & QTI_SOC_VERSION_MASK);
158 	uint32_t jep106az_code = (JEDEC_QTI_BKID << QTI_SOC_CONTINUATION_SHIFT)
159 			 | (JEDEC_QTI_MFID << QTI_SOC_IDENTIFICATION_SHIFT);
160 	return (int32_t)(jep106az_code | (soc_version));
161 }
162 
163 /*
164  * This function returns soc revision in below format
165  *
166  *   soc_revision[0:30] = SOC revision of specific SOC
167  */
168 int32_t plat_get_soc_revision(void)
169 {
170 	return mmio_read_32(QTI_SOC_REVISION_REG) & QTI_SOC_REVISION_MASK;
171 }
172 
173 /*****************************************************************************
174  * plat_is_smccc_feature_available() - This function checks whether SMCCC feature
175  *                                  is availabile for the platform or not.
176  * @fid: SMCCC function id
177  *
178  * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
179  * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
180  *****************************************************************************/
181 int32_t plat_is_smccc_feature_available(u_register_t fid)
182 {
183 	switch (fid) {
184 	case SMCCC_ARCH_SOC_ID:
185 		return SMC_ARCH_CALL_SUCCESS;
186 	default:
187 		return SMC_ARCH_CALL_NOT_SUPPORTED;
188 	}
189 }
190