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>
20*39fdd3d8SBharath N #include <qti_map_chipinfo.h>
215bd9c17dSSaurabh Gorecha #include <qti_plat.h>
225bd9c17dSSaurabh Gorecha #include <qtiseclib_interface.h>
235bd9c17dSSaurabh Gorecha
245bd9c17dSSaurabh Gorecha /*
255bd9c17dSSaurabh Gorecha * Table of regions for various BL stages to map using the MMU.
265bd9c17dSSaurabh Gorecha * This doesn't include TZRAM as the 'mem_layout' argument passed to
275bd9c17dSSaurabh Gorecha * qti_configure_mmu_elx() will give the available subset of that,
285bd9c17dSSaurabh Gorecha */
295bd9c17dSSaurabh Gorecha
305bd9c17dSSaurabh Gorecha const mmap_region_t plat_qti_mmap[] = {
315bd9c17dSSaurabh Gorecha MAP_REGION_FLAT(QTI_DEVICE_BASE, QTI_DEVICE_SIZE,
325bd9c17dSSaurabh Gorecha MT_DEVICE | MT_RW | MT_SECURE),
335bd9c17dSSaurabh Gorecha MAP_REGION_FLAT(QTI_AOP_CMD_DB_BASE, QTI_AOP_CMD_DB_SIZE,
345bd9c17dSSaurabh Gorecha MT_NS | MT_RO | MT_EXECUTE_NEVER),
355bd9c17dSSaurabh Gorecha {0}
365bd9c17dSSaurabh Gorecha };
375bd9c17dSSaurabh Gorecha
385bd9c17dSSaurabh Gorecha CASSERT(ARRAY_SIZE(plat_qti_mmap) <= MAX_MMAP_REGIONS, assert_max_mmap_regions);
395bd9c17dSSaurabh Gorecha
405bd9c17dSSaurabh Gorecha
qti_is_overlap_atf_rg(unsigned long long addr,size_t size)415bd9c17dSSaurabh Gorecha bool qti_is_overlap_atf_rg(unsigned long long addr, size_t size)
425bd9c17dSSaurabh Gorecha {
435bd9c17dSSaurabh Gorecha if (addr > addr + size
445bd9c17dSSaurabh Gorecha || (BL31_BASE < addr + size && BL31_LIMIT > addr)) {
455bd9c17dSSaurabh Gorecha return true;
465bd9c17dSSaurabh Gorecha }
475bd9c17dSSaurabh Gorecha return false;
485bd9c17dSSaurabh Gorecha }
495bd9c17dSSaurabh Gorecha
505bd9c17dSSaurabh Gorecha /*
515bd9c17dSSaurabh Gorecha * unsigned int plat_qti_my_cluster_pos(void)
525bd9c17dSSaurabh Gorecha * definition to get the cluster index of the calling CPU.
535bd9c17dSSaurabh Gorecha * - In ARM v8 (MPIDR_EL1[24]=0)
545bd9c17dSSaurabh Gorecha * ClusterId = MPIDR_EL1[15:8]
555bd9c17dSSaurabh Gorecha * - In ARM v8.1 & Later version (MPIDR_EL1[24]=1)
565bd9c17dSSaurabh Gorecha * ClusterId = MPIDR_EL1[23:15]
575bd9c17dSSaurabh Gorecha */
plat_qti_my_cluster_pos(void)585bd9c17dSSaurabh Gorecha unsigned int plat_qti_my_cluster_pos(void)
595bd9c17dSSaurabh Gorecha {
605bd9c17dSSaurabh Gorecha unsigned int mpidr, cluster_id;
615bd9c17dSSaurabh Gorecha
625bd9c17dSSaurabh Gorecha mpidr = read_mpidr_el1();
635bd9c17dSSaurabh Gorecha if ((mpidr & MPIDR_MT_MASK) == 0) { /* MT not supported */
645bd9c17dSSaurabh Gorecha cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
655bd9c17dSSaurabh Gorecha } else { /* MT supported */
665bd9c17dSSaurabh Gorecha cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
675bd9c17dSSaurabh Gorecha }
685bd9c17dSSaurabh Gorecha assert(cluster_id < PLAT_CLUSTER_COUNT);
695bd9c17dSSaurabh Gorecha return cluster_id;
705bd9c17dSSaurabh Gorecha }
715bd9c17dSSaurabh Gorecha
725bd9c17dSSaurabh Gorecha /*
735bd9c17dSSaurabh Gorecha * Set up the page tables for the generic and platform-specific memory regions.
745bd9c17dSSaurabh Gorecha * The extents of the generic memory regions are specified by the function
755bd9c17dSSaurabh Gorecha * arguments and consist of:
765bd9c17dSSaurabh Gorecha * - Trusted SRAM seen by the BL image;
775bd9c17dSSaurabh Gorecha * - Code section;
785bd9c17dSSaurabh Gorecha * - Read-only data section;
795bd9c17dSSaurabh Gorecha * - Coherent memory region, if applicable.
805bd9c17dSSaurabh Gorecha */
qti_setup_page_tables(uintptr_t total_base,size_t total_size,uintptr_t code_start,uintptr_t code_limit,uintptr_t rodata_start,uintptr_t rodata_limit)816cc743cfSSaurabh Gorecha void qti_setup_page_tables(
826cc743cfSSaurabh Gorecha uintptr_t total_base,
835bd9c17dSSaurabh Gorecha size_t total_size,
845bd9c17dSSaurabh Gorecha uintptr_t code_start,
855bd9c17dSSaurabh Gorecha uintptr_t code_limit,
865bd9c17dSSaurabh Gorecha uintptr_t rodata_start,
876cc743cfSSaurabh Gorecha uintptr_t rodata_limit
886cc743cfSSaurabh Gorecha )
895bd9c17dSSaurabh Gorecha {
905bd9c17dSSaurabh Gorecha /*
915bd9c17dSSaurabh Gorecha * Map the Trusted SRAM with appropriate memory attributes.
925bd9c17dSSaurabh Gorecha * Subsequent mappings will adjust the attributes for specific regions.
935bd9c17dSSaurabh Gorecha */
945bd9c17dSSaurabh Gorecha VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n",
955bd9c17dSSaurabh Gorecha (void *)total_base, (void *)(total_base + total_size));
965bd9c17dSSaurabh Gorecha mmap_add_region(total_base, total_base,
975bd9c17dSSaurabh Gorecha total_size, MT_MEMORY | MT_RW | MT_SECURE);
985bd9c17dSSaurabh Gorecha
995bd9c17dSSaurabh Gorecha /* Re-map the code section */
1005bd9c17dSSaurabh Gorecha VERBOSE("Code region: %p - %p\n",
1015bd9c17dSSaurabh Gorecha (void *)code_start, (void *)code_limit);
1025bd9c17dSSaurabh Gorecha mmap_add_region(code_start, code_start,
1035bd9c17dSSaurabh Gorecha code_limit - code_start, MT_CODE | MT_SECURE);
1045bd9c17dSSaurabh Gorecha
1055bd9c17dSSaurabh Gorecha /* Re-map the read-only data section */
1065bd9c17dSSaurabh Gorecha VERBOSE("Read-only data region: %p - %p\n",
1075bd9c17dSSaurabh Gorecha (void *)rodata_start, (void *)rodata_limit);
1085bd9c17dSSaurabh Gorecha mmap_add_region(rodata_start, rodata_start,
1095bd9c17dSSaurabh Gorecha rodata_limit - rodata_start, MT_RO_DATA | MT_SECURE);
1105bd9c17dSSaurabh Gorecha
1115bd9c17dSSaurabh Gorecha /* Now (re-)map the platform-specific memory regions */
1125bd9c17dSSaurabh Gorecha mmap_add(plat_qti_mmap);
1135bd9c17dSSaurabh Gorecha
1145bd9c17dSSaurabh Gorecha /* Create the page tables to reflect the above mappings */
1155bd9c17dSSaurabh Gorecha init_xlat_tables();
1165bd9c17dSSaurabh Gorecha }
1175bd9c17dSSaurabh Gorecha
qti_align_mem_region(uintptr_t addr,size_t size,uintptr_t * aligned_addr,size_t * aligned_size)1185bd9c17dSSaurabh Gorecha static inline void qti_align_mem_region(uintptr_t addr, size_t size,
1195bd9c17dSSaurabh Gorecha uintptr_t *aligned_addr,
1205bd9c17dSSaurabh Gorecha size_t *aligned_size)
1215bd9c17dSSaurabh Gorecha {
1225bd9c17dSSaurabh Gorecha *aligned_addr = round_down(addr, PAGE_SIZE);
1235bd9c17dSSaurabh Gorecha *aligned_size = round_up(addr - *aligned_addr + size, PAGE_SIZE);
1245bd9c17dSSaurabh Gorecha }
1255bd9c17dSSaurabh Gorecha
qti_mmap_add_dynamic_region(uintptr_t base_pa,size_t size,unsigned int attr)1265bd9c17dSSaurabh Gorecha int qti_mmap_add_dynamic_region(uintptr_t base_pa, size_t size,
1275bd9c17dSSaurabh Gorecha unsigned int attr)
1285bd9c17dSSaurabh Gorecha {
1295bd9c17dSSaurabh Gorecha uintptr_t aligned_pa;
1305bd9c17dSSaurabh Gorecha size_t aligned_size;
1315bd9c17dSSaurabh Gorecha
1325bd9c17dSSaurabh Gorecha qti_align_mem_region(base_pa, size, &aligned_pa, &aligned_size);
1335bd9c17dSSaurabh Gorecha
1345bd9c17dSSaurabh Gorecha if (qti_is_overlap_atf_rg(base_pa, size)) {
1355bd9c17dSSaurabh Gorecha /* Memory shouldn't overlap with TF-A range. */
1365bd9c17dSSaurabh Gorecha return -EPERM;
1375bd9c17dSSaurabh Gorecha }
1385bd9c17dSSaurabh Gorecha
1395bd9c17dSSaurabh Gorecha return mmap_add_dynamic_region(aligned_pa, aligned_pa, aligned_size,
1405bd9c17dSSaurabh Gorecha attr);
1415bd9c17dSSaurabh Gorecha }
1425bd9c17dSSaurabh Gorecha
qti_mmap_remove_dynamic_region(uintptr_t base_va,size_t size)1435bd9c17dSSaurabh Gorecha int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
1445bd9c17dSSaurabh Gorecha {
1455bd9c17dSSaurabh Gorecha qti_align_mem_region(base_va, size, &base_va, &size);
1465bd9c17dSSaurabh Gorecha return mmap_remove_dynamic_region(base_va, size);
1475bd9c17dSSaurabh Gorecha }
1484b918452SSaurabh Gorecha
1494b918452SSaurabh Gorecha /*
1504b918452SSaurabh Gorecha * This function returns soc version which mainly consist of below fields
1514b918452SSaurabh Gorecha *
1524b918452SSaurabh Gorecha * soc_version[30:24] = JEP-106 continuation code for the SiP
1534b918452SSaurabh Gorecha * soc_version[23:16] = JEP-106 identification code with parity bit for the SiP
1544b918452SSaurabh Gorecha * soc_version[0:15] = Implementation defined SoC ID
1554b918452SSaurabh Gorecha */
plat_get_soc_version(void)1564b918452SSaurabh Gorecha int32_t plat_get_soc_version(void)
1574b918452SSaurabh Gorecha {
158*39fdd3d8SBharath N int i = 0;
159*39fdd3d8SBharath N /* Variant other than in mapped g_map_jtag_chipinfo_id variable will have
160*39fdd3d8SBharath N * default chipinfo id as 0xFFFF
161*39fdd3d8SBharath N */
162*39fdd3d8SBharath N uint32_t soc_version = (QTI_DEFAULT_CHIPINFO_ID & QTI_SOC_VERSION_MASK);
1634b918452SSaurabh Gorecha uint32_t jep106az_code = (JEDEC_QTI_BKID << QTI_SOC_CONTINUATION_SHIFT)
1644b918452SSaurabh Gorecha | (JEDEC_QTI_MFID << QTI_SOC_IDENTIFICATION_SHIFT);
165*39fdd3d8SBharath N uint32_t jtag_id = mmio_read_32(QTI_JTAG_ID_REG);
166*39fdd3d8SBharath N uint32_t jtag_id_val = (jtag_id >> QTI_JTAG_ID_SHIFT)
167*39fdd3d8SBharath N & QTI_SOC_VERSION_MASK;
168*39fdd3d8SBharath N
169*39fdd3d8SBharath N for (i = 0; i < ARRAY_SIZE(g_map_jtag_chipinfo_id); i++) {
170*39fdd3d8SBharath N if (g_map_jtag_chipinfo_id[i].jtag_id == jtag_id_val)
171*39fdd3d8SBharath N soc_version = g_map_jtag_chipinfo_id[i].chipinfo_id
172*39fdd3d8SBharath N & QTI_SOC_VERSION_MASK;
173*39fdd3d8SBharath N }
1744b918452SSaurabh Gorecha return (int32_t)(jep106az_code | (soc_version));
1754b918452SSaurabh Gorecha }
1764b918452SSaurabh Gorecha
1774b918452SSaurabh Gorecha /*
1784b918452SSaurabh Gorecha * This function returns soc revision in below format
1794b918452SSaurabh Gorecha *
1804b918452SSaurabh Gorecha * soc_revision[0:30] = SOC revision of specific SOC
1814b918452SSaurabh Gorecha */
plat_get_soc_revision(void)1824b918452SSaurabh Gorecha int32_t plat_get_soc_revision(void)
1834b918452SSaurabh Gorecha {
1844b918452SSaurabh Gorecha return mmio_read_32(QTI_SOC_REVISION_REG) & QTI_SOC_REVISION_MASK;
1854b918452SSaurabh Gorecha }
1864b918452SSaurabh Gorecha
1874b918452SSaurabh Gorecha /*****************************************************************************
1887a0f795eSSaurabh Gorecha * plat_is_smccc_feature_available() - This function checks whether SMCCC feature
1894b918452SSaurabh Gorecha * is availabile for the platform or not.
1904b918452SSaurabh Gorecha * @fid: SMCCC function id
1914b918452SSaurabh Gorecha *
1924b918452SSaurabh Gorecha * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and
1934b918452SSaurabh Gorecha * SMC_ARCH_CALL_NOT_SUPPORTED otherwise.
1944b918452SSaurabh Gorecha *****************************************************************************/
plat_is_smccc_feature_available(u_register_t fid)1957a0f795eSSaurabh Gorecha int32_t plat_is_smccc_feature_available(u_register_t fid)
1964b918452SSaurabh Gorecha {
1974b918452SSaurabh Gorecha switch (fid) {
1984b918452SSaurabh Gorecha case SMCCC_ARCH_SOC_ID:
1994b918452SSaurabh Gorecha return SMC_ARCH_CALL_SUCCESS;
2004b918452SSaurabh Gorecha default:
2014b918452SSaurabh Gorecha return SMC_ARCH_CALL_NOT_SUPPORTED;
2024b918452SSaurabh Gorecha }
2034b918452SSaurabh Gorecha }
204