xref: /rk3399_ARM-atf/plat/qti/common/src/qti_common.c (revision 6cc743cf0fa9b216f2af8ff87c716dcc0bb6f6a0)
15bd9c17dSSaurabh Gorecha /*
25bd9c17dSSaurabh Gorecha  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
35bd9c17dSSaurabh Gorecha  * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
45bd9c17dSSaurabh Gorecha  *
55bd9c17dSSaurabh Gorecha  * SPDX-License-Identifier: BSD-3-Clause
65bd9c17dSSaurabh Gorecha  */
75bd9c17dSSaurabh Gorecha 
85bd9c17dSSaurabh Gorecha #include <assert.h>
95bd9c17dSSaurabh Gorecha #include <errno.h>
105bd9c17dSSaurabh Gorecha #include <stdbool.h>
115bd9c17dSSaurabh Gorecha #include <stdint.h>
125bd9c17dSSaurabh Gorecha 
135bd9c17dSSaurabh Gorecha #include <common/debug.h>
144b918452SSaurabh Gorecha #include <lib/mmio.h>
154b918452SSaurabh Gorecha #include <lib/smccc.h>
165bd9c17dSSaurabh Gorecha #include <lib/xlat_tables/xlat_tables_v2.h>
174b918452SSaurabh Gorecha #include <services/arm_arch_svc.h>
185bd9c17dSSaurabh Gorecha 
195bd9c17dSSaurabh Gorecha #include <platform_def.h>
205bd9c17dSSaurabh Gorecha #include <qti_plat.h>
215bd9c17dSSaurabh Gorecha #include <qtiseclib_interface.h>
225bd9c17dSSaurabh Gorecha 
235bd9c17dSSaurabh Gorecha /*
245bd9c17dSSaurabh Gorecha  * Table of regions for various BL stages to map using the MMU.
255bd9c17dSSaurabh Gorecha  * This doesn't include TZRAM as the 'mem_layout' argument passed to
265bd9c17dSSaurabh Gorecha  * qti_configure_mmu_elx() will give the available subset of that,
275bd9c17dSSaurabh Gorecha  */
285bd9c17dSSaurabh Gorecha 
295bd9c17dSSaurabh Gorecha const mmap_region_t plat_qti_mmap[] = {
305bd9c17dSSaurabh Gorecha 	MAP_REGION_FLAT(QTI_DEVICE_BASE, QTI_DEVICE_SIZE,
315bd9c17dSSaurabh Gorecha 			MT_DEVICE | MT_RW | MT_SECURE),
325bd9c17dSSaurabh Gorecha 	MAP_REGION_FLAT(QTI_AOP_CMD_DB_BASE, QTI_AOP_CMD_DB_SIZE,
335bd9c17dSSaurabh Gorecha 			MT_NS | MT_RO | MT_EXECUTE_NEVER),
345bd9c17dSSaurabh Gorecha 	{0}
355bd9c17dSSaurabh Gorecha };
365bd9c17dSSaurabh Gorecha 
375bd9c17dSSaurabh Gorecha CASSERT(ARRAY_SIZE(plat_qti_mmap) <= MAX_MMAP_REGIONS, assert_max_mmap_regions);
385bd9c17dSSaurabh Gorecha 
395bd9c17dSSaurabh Gorecha 
405bd9c17dSSaurabh Gorecha bool qti_is_overlap_atf_rg(unsigned long long addr, size_t size)
415bd9c17dSSaurabh Gorecha {
425bd9c17dSSaurabh Gorecha 	if (addr > addr + size
435bd9c17dSSaurabh Gorecha 			|| (BL31_BASE < addr + size && BL31_LIMIT > addr)) {
445bd9c17dSSaurabh Gorecha 		return true;
455bd9c17dSSaurabh Gorecha 	}
465bd9c17dSSaurabh Gorecha 	return false;
475bd9c17dSSaurabh Gorecha }
485bd9c17dSSaurabh Gorecha 
495bd9c17dSSaurabh Gorecha /*
505bd9c17dSSaurabh Gorecha  *  unsigned int plat_qti_my_cluster_pos(void)
515bd9c17dSSaurabh Gorecha  *  definition to get the cluster index of the calling CPU.
525bd9c17dSSaurabh Gorecha  *  - In ARM v8   (MPIDR_EL1[24]=0)
535bd9c17dSSaurabh Gorecha  *    ClusterId = MPIDR_EL1[15:8]
545bd9c17dSSaurabh Gorecha  *  - In ARM v8.1 & Later version (MPIDR_EL1[24]=1)
555bd9c17dSSaurabh Gorecha  *    ClusterId = MPIDR_EL1[23:15]
565bd9c17dSSaurabh Gorecha  */
575bd9c17dSSaurabh Gorecha unsigned int plat_qti_my_cluster_pos(void)
585bd9c17dSSaurabh Gorecha {
595bd9c17dSSaurabh Gorecha 	unsigned int mpidr, cluster_id;
605bd9c17dSSaurabh Gorecha 
615bd9c17dSSaurabh Gorecha 	mpidr = read_mpidr_el1();
625bd9c17dSSaurabh Gorecha 	if ((mpidr & MPIDR_MT_MASK) == 0) {	/* MT not supported */
635bd9c17dSSaurabh Gorecha 		cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
645bd9c17dSSaurabh Gorecha 	} else {		/* MT supported */
655bd9c17dSSaurabh Gorecha 		cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
665bd9c17dSSaurabh Gorecha 	}
675bd9c17dSSaurabh Gorecha 	assert(cluster_id < PLAT_CLUSTER_COUNT);
685bd9c17dSSaurabh Gorecha 	return cluster_id;
695bd9c17dSSaurabh Gorecha }
705bd9c17dSSaurabh Gorecha 
715bd9c17dSSaurabh Gorecha /*
725bd9c17dSSaurabh Gorecha  * Set up the page tables for the generic and platform-specific memory regions.
735bd9c17dSSaurabh Gorecha  * The extents of the generic memory regions are specified by the function
745bd9c17dSSaurabh Gorecha  * arguments and consist of:
755bd9c17dSSaurabh Gorecha  * - Trusted SRAM seen by the BL image;
765bd9c17dSSaurabh Gorecha  * - Code section;
775bd9c17dSSaurabh Gorecha  * - Read-only data section;
785bd9c17dSSaurabh Gorecha  * - Coherent memory region, if applicable.
795bd9c17dSSaurabh Gorecha  */
80*6cc743cfSSaurabh Gorecha void qti_setup_page_tables(
81*6cc743cfSSaurabh Gorecha 			   uintptr_t total_base,
825bd9c17dSSaurabh Gorecha 			   size_t total_size,
835bd9c17dSSaurabh Gorecha 			   uintptr_t code_start,
845bd9c17dSSaurabh Gorecha 			   uintptr_t code_limit,
855bd9c17dSSaurabh Gorecha 			   uintptr_t rodata_start,
86*6cc743cfSSaurabh Gorecha 			   uintptr_t rodata_limit
87*6cc743cfSSaurabh Gorecha 			  )
885bd9c17dSSaurabh Gorecha {
895bd9c17dSSaurabh Gorecha 	/*
905bd9c17dSSaurabh Gorecha 	 * Map the Trusted SRAM with appropriate memory attributes.
915bd9c17dSSaurabh Gorecha 	 * Subsequent mappings will adjust the attributes for specific regions.
925bd9c17dSSaurabh Gorecha 	 */
935bd9c17dSSaurabh Gorecha 	VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n",
945bd9c17dSSaurabh Gorecha 		(void *)total_base, (void *)(total_base + total_size));
955bd9c17dSSaurabh Gorecha 	mmap_add_region(total_base, total_base,
965bd9c17dSSaurabh Gorecha 			total_size, MT_MEMORY | MT_RW | MT_SECURE);
975bd9c17dSSaurabh Gorecha 
985bd9c17dSSaurabh Gorecha 	/* Re-map the code section */
995bd9c17dSSaurabh Gorecha 	VERBOSE("Code region: %p - %p\n",
1005bd9c17dSSaurabh Gorecha 		(void *)code_start, (void *)code_limit);
1015bd9c17dSSaurabh Gorecha 	mmap_add_region(code_start, code_start,
1025bd9c17dSSaurabh Gorecha 			code_limit - code_start, MT_CODE | MT_SECURE);
1035bd9c17dSSaurabh Gorecha 
1045bd9c17dSSaurabh Gorecha 	/* Re-map the read-only data section */
1055bd9c17dSSaurabh Gorecha 	VERBOSE("Read-only data region: %p - %p\n",
1065bd9c17dSSaurabh Gorecha 		(void *)rodata_start, (void *)rodata_limit);
1075bd9c17dSSaurabh Gorecha 	mmap_add_region(rodata_start, rodata_start,
1085bd9c17dSSaurabh Gorecha 			rodata_limit - rodata_start, MT_RO_DATA | MT_SECURE);
1095bd9c17dSSaurabh Gorecha 
1105bd9c17dSSaurabh Gorecha 	/* Now (re-)map the platform-specific memory regions */
1115bd9c17dSSaurabh Gorecha 	mmap_add(plat_qti_mmap);
1125bd9c17dSSaurabh Gorecha 
1135bd9c17dSSaurabh Gorecha 	/* Create the page tables to reflect the above mappings */
1145bd9c17dSSaurabh Gorecha 	init_xlat_tables();
1155bd9c17dSSaurabh Gorecha }
1165bd9c17dSSaurabh Gorecha 
1175bd9c17dSSaurabh Gorecha static inline void qti_align_mem_region(uintptr_t addr, size_t size,
1185bd9c17dSSaurabh Gorecha 					uintptr_t *aligned_addr,
1195bd9c17dSSaurabh Gorecha 					size_t *aligned_size)
1205bd9c17dSSaurabh Gorecha {
1215bd9c17dSSaurabh Gorecha 	*aligned_addr = round_down(addr, PAGE_SIZE);
1225bd9c17dSSaurabh Gorecha 	*aligned_size = round_up(addr - *aligned_addr + size, PAGE_SIZE);
1235bd9c17dSSaurabh Gorecha }
1245bd9c17dSSaurabh Gorecha 
1255bd9c17dSSaurabh Gorecha int qti_mmap_add_dynamic_region(uintptr_t base_pa, size_t size,
1265bd9c17dSSaurabh Gorecha 				unsigned int attr)
1275bd9c17dSSaurabh Gorecha {
1285bd9c17dSSaurabh Gorecha 	uintptr_t aligned_pa;
1295bd9c17dSSaurabh Gorecha 	size_t aligned_size;
1305bd9c17dSSaurabh Gorecha 
1315bd9c17dSSaurabh Gorecha 	qti_align_mem_region(base_pa, size, &aligned_pa, &aligned_size);
1325bd9c17dSSaurabh Gorecha 
1335bd9c17dSSaurabh Gorecha 	if (qti_is_overlap_atf_rg(base_pa, size)) {
1345bd9c17dSSaurabh Gorecha 		/* Memory shouldn't overlap with TF-A range. */
1355bd9c17dSSaurabh Gorecha 		return -EPERM;
1365bd9c17dSSaurabh Gorecha 	}
1375bd9c17dSSaurabh Gorecha 
1385bd9c17dSSaurabh Gorecha 	return mmap_add_dynamic_region(aligned_pa, aligned_pa, aligned_size,
1395bd9c17dSSaurabh Gorecha 				       attr);
1405bd9c17dSSaurabh Gorecha }
1415bd9c17dSSaurabh Gorecha 
1425bd9c17dSSaurabh Gorecha int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
1435bd9c17dSSaurabh Gorecha {
1445bd9c17dSSaurabh Gorecha 	qti_align_mem_region(base_va, size, &base_va, &size);
1455bd9c17dSSaurabh Gorecha 	return mmap_remove_dynamic_region(base_va, size);
1465bd9c17dSSaurabh Gorecha }
1474b918452SSaurabh Gorecha 
1484b918452SSaurabh Gorecha /*
1494b918452SSaurabh Gorecha  * This function returns soc version which mainly consist of below fields
1504b918452SSaurabh Gorecha  *
1514b918452SSaurabh Gorecha  * soc_version[30:24] = JEP-106 continuation code for the SiP
1524b918452SSaurabh Gorecha  * soc_version[23:16] = JEP-106 identification code with parity bit for the SiP
1534b918452SSaurabh Gorecha  * soc_version[0:15]  = Implementation defined SoC ID
1544b918452SSaurabh Gorecha  */
1554b918452SSaurabh Gorecha int32_t plat_get_soc_version(void)
1564b918452SSaurabh Gorecha {
1574b918452SSaurabh Gorecha 	uint32_t soc_version = (QTI_SOC_VERSION & QTI_SOC_VERSION_MASK);
1584b918452SSaurabh Gorecha 	uint32_t jep106az_code = (JEDEC_QTI_BKID << QTI_SOC_CONTINUATION_SHIFT)
1594b918452SSaurabh Gorecha 			 | (JEDEC_QTI_MFID << QTI_SOC_IDENTIFICATION_SHIFT);
1604b918452SSaurabh Gorecha 	return (int32_t)(jep106az_code | (soc_version));
1614b918452SSaurabh Gorecha }
1624b918452SSaurabh Gorecha 
1634b918452SSaurabh Gorecha /*
1644b918452SSaurabh Gorecha  * This function returns soc revision in below format
1654b918452SSaurabh Gorecha  *
1664b918452SSaurabh Gorecha  *   soc_revision[0:30] = SOC revision of specific SOC
1674b918452SSaurabh Gorecha  */
1684b918452SSaurabh Gorecha int32_t plat_get_soc_revision(void)
1694b918452SSaurabh Gorecha {
1704b918452SSaurabh Gorecha 	return mmio_read_32(QTI_SOC_REVISION_REG) & QTI_SOC_REVISION_MASK;
1714b918452SSaurabh Gorecha }
1724b918452SSaurabh Gorecha 
1734b918452SSaurabh Gorecha /*****************************************************************************
1747a0f795eSSaurabh Gorecha  * plat_is_smccc_feature_available() - This function checks whether SMCCC feature
1754b918452SSaurabh Gorecha  *                                  is availabile for the platform or not.
1764b918452SSaurabh Gorecha  * @fid: SMCCC function id
1774b918452SSaurabh Gorecha  *
1784b918452SSaurabh Gorecha  * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
1794b918452SSaurabh Gorecha  * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
1804b918452SSaurabh Gorecha  *****************************************************************************/
1817a0f795eSSaurabh Gorecha int32_t plat_is_smccc_feature_available(u_register_t fid)
1824b918452SSaurabh Gorecha {
1834b918452SSaurabh Gorecha 	switch (fid) {
1844b918452SSaurabh Gorecha 	case SMCCC_ARCH_SOC_ID:
1854b918452SSaurabh Gorecha 		return SMC_ARCH_CALL_SUCCESS;
1864b918452SSaurabh Gorecha 	default:
1874b918452SSaurabh Gorecha 		return SMC_ARCH_CALL_NOT_SUPPORTED;
1884b918452SSaurabh Gorecha 	}
1894b918452SSaurabh Gorecha }
190