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 */ 805bd9c17dSSaurabh Gorecha void qti_setup_page_tables(uintptr_t total_base, 815bd9c17dSSaurabh Gorecha size_t total_size, 825bd9c17dSSaurabh Gorecha uintptr_t code_start, 835bd9c17dSSaurabh Gorecha uintptr_t code_limit, 845bd9c17dSSaurabh Gorecha uintptr_t rodata_start, 855bd9c17dSSaurabh Gorecha uintptr_t rodata_limit, 865bd9c17dSSaurabh Gorecha uintptr_t coh_start, uintptr_t coh_limit) 875bd9c17dSSaurabh Gorecha { 885bd9c17dSSaurabh Gorecha /* 895bd9c17dSSaurabh Gorecha * Map the Trusted SRAM with appropriate memory attributes. 905bd9c17dSSaurabh Gorecha * Subsequent mappings will adjust the attributes for specific regions. 915bd9c17dSSaurabh Gorecha */ 925bd9c17dSSaurabh Gorecha VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n", 935bd9c17dSSaurabh Gorecha (void *)total_base, (void *)(total_base + total_size)); 945bd9c17dSSaurabh Gorecha mmap_add_region(total_base, total_base, 955bd9c17dSSaurabh Gorecha total_size, MT_MEMORY | MT_RW | MT_SECURE); 965bd9c17dSSaurabh Gorecha 975bd9c17dSSaurabh Gorecha /* Re-map the code section */ 985bd9c17dSSaurabh Gorecha VERBOSE("Code region: %p - %p\n", 995bd9c17dSSaurabh Gorecha (void *)code_start, (void *)code_limit); 1005bd9c17dSSaurabh Gorecha mmap_add_region(code_start, code_start, 1015bd9c17dSSaurabh Gorecha code_limit - code_start, MT_CODE | MT_SECURE); 1025bd9c17dSSaurabh Gorecha 1035bd9c17dSSaurabh Gorecha /* Re-map the read-only data section */ 1045bd9c17dSSaurabh Gorecha VERBOSE("Read-only data region: %p - %p\n", 1055bd9c17dSSaurabh Gorecha (void *)rodata_start, (void *)rodata_limit); 1065bd9c17dSSaurabh Gorecha mmap_add_region(rodata_start, rodata_start, 1075bd9c17dSSaurabh Gorecha rodata_limit - rodata_start, MT_RO_DATA | MT_SECURE); 1085bd9c17dSSaurabh Gorecha 1095bd9c17dSSaurabh Gorecha /* Re-map the coherent memory region */ 1105bd9c17dSSaurabh Gorecha VERBOSE("Coherent region: %p - %p\n", 1115bd9c17dSSaurabh Gorecha (void *)coh_start, (void *)coh_limit); 1125bd9c17dSSaurabh Gorecha mmap_add_region(coh_start, coh_start, 1135bd9c17dSSaurabh Gorecha coh_limit - coh_start, MT_DEVICE | MT_RW | MT_SECURE); 1145bd9c17dSSaurabh Gorecha 1155bd9c17dSSaurabh Gorecha /* Now (re-)map the platform-specific memory regions */ 1165bd9c17dSSaurabh Gorecha mmap_add(plat_qti_mmap); 1175bd9c17dSSaurabh Gorecha 1185bd9c17dSSaurabh Gorecha /* Create the page tables to reflect the above mappings */ 1195bd9c17dSSaurabh Gorecha init_xlat_tables(); 1205bd9c17dSSaurabh Gorecha } 1215bd9c17dSSaurabh Gorecha 1225bd9c17dSSaurabh Gorecha static inline void qti_align_mem_region(uintptr_t addr, size_t size, 1235bd9c17dSSaurabh Gorecha uintptr_t *aligned_addr, 1245bd9c17dSSaurabh Gorecha size_t *aligned_size) 1255bd9c17dSSaurabh Gorecha { 1265bd9c17dSSaurabh Gorecha *aligned_addr = round_down(addr, PAGE_SIZE); 1275bd9c17dSSaurabh Gorecha *aligned_size = round_up(addr - *aligned_addr + size, PAGE_SIZE); 1285bd9c17dSSaurabh Gorecha } 1295bd9c17dSSaurabh Gorecha 1305bd9c17dSSaurabh Gorecha int qti_mmap_add_dynamic_region(uintptr_t base_pa, size_t size, 1315bd9c17dSSaurabh Gorecha unsigned int attr) 1325bd9c17dSSaurabh Gorecha { 1335bd9c17dSSaurabh Gorecha uintptr_t aligned_pa; 1345bd9c17dSSaurabh Gorecha size_t aligned_size; 1355bd9c17dSSaurabh Gorecha 1365bd9c17dSSaurabh Gorecha qti_align_mem_region(base_pa, size, &aligned_pa, &aligned_size); 1375bd9c17dSSaurabh Gorecha 1385bd9c17dSSaurabh Gorecha if (qti_is_overlap_atf_rg(base_pa, size)) { 1395bd9c17dSSaurabh Gorecha /* Memory shouldn't overlap with TF-A range. */ 1405bd9c17dSSaurabh Gorecha return -EPERM; 1415bd9c17dSSaurabh Gorecha } 1425bd9c17dSSaurabh Gorecha 1435bd9c17dSSaurabh Gorecha return mmap_add_dynamic_region(aligned_pa, aligned_pa, aligned_size, 1445bd9c17dSSaurabh Gorecha attr); 1455bd9c17dSSaurabh Gorecha } 1465bd9c17dSSaurabh Gorecha 1475bd9c17dSSaurabh Gorecha int qti_mmap_remove_dynamic_region(uintptr_t base_va, size_t size) 1485bd9c17dSSaurabh Gorecha { 1495bd9c17dSSaurabh Gorecha qti_align_mem_region(base_va, size, &base_va, &size); 1505bd9c17dSSaurabh Gorecha return mmap_remove_dynamic_region(base_va, size); 1515bd9c17dSSaurabh Gorecha } 1524b918452SSaurabh Gorecha 1534b918452SSaurabh Gorecha /* 1544b918452SSaurabh Gorecha * This function returns soc version which mainly consist of below fields 1554b918452SSaurabh Gorecha * 1564b918452SSaurabh Gorecha * soc_version[30:24] = JEP-106 continuation code for the SiP 1574b918452SSaurabh Gorecha * soc_version[23:16] = JEP-106 identification code with parity bit for the SiP 1584b918452SSaurabh Gorecha * soc_version[0:15] = Implementation defined SoC ID 1594b918452SSaurabh Gorecha */ 1604b918452SSaurabh Gorecha int32_t plat_get_soc_version(void) 1614b918452SSaurabh Gorecha { 1624b918452SSaurabh Gorecha uint32_t soc_version = (QTI_SOC_VERSION & 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); 1654b918452SSaurabh Gorecha return (int32_t)(jep106az_code | (soc_version)); 1664b918452SSaurabh Gorecha } 1674b918452SSaurabh Gorecha 1684b918452SSaurabh Gorecha /* 1694b918452SSaurabh Gorecha * This function returns soc revision in below format 1704b918452SSaurabh Gorecha * 1714b918452SSaurabh Gorecha * soc_revision[0:30] = SOC revision of specific SOC 1724b918452SSaurabh Gorecha */ 1734b918452SSaurabh Gorecha int32_t plat_get_soc_revision(void) 1744b918452SSaurabh Gorecha { 1754b918452SSaurabh Gorecha return mmio_read_32(QTI_SOC_REVISION_REG) & QTI_SOC_REVISION_MASK; 1764b918452SSaurabh Gorecha } 1774b918452SSaurabh Gorecha 1784b918452SSaurabh Gorecha /***************************************************************************** 179*7a0f795eSSaurabh Gorecha * plat_is_smccc_feature_available() - This function checks whether SMCCC feature 1804b918452SSaurabh Gorecha * is availabile for the platform or not. 1814b918452SSaurabh Gorecha * @fid: SMCCC function id 1824b918452SSaurabh Gorecha * 1834b918452SSaurabh Gorecha * Return SMC_ARCH_CALL_SUCCESS if SMCCC feature is available and 1844b918452SSaurabh Gorecha * SMC_ARCH_CALL_NOT_SUPPORTED otherwise. 1854b918452SSaurabh Gorecha *****************************************************************************/ 186*7a0f795eSSaurabh Gorecha int32_t plat_is_smccc_feature_available(u_register_t fid) 1874b918452SSaurabh Gorecha { 1884b918452SSaurabh Gorecha switch (fid) { 1894b918452SSaurabh Gorecha case SMCCC_ARCH_SOC_ID: 1904b918452SSaurabh Gorecha return SMC_ARCH_CALL_SUCCESS; 1914b918452SSaurabh Gorecha default: 1924b918452SSaurabh Gorecha return SMC_ARCH_CALL_NOT_SUPPORTED; 1934b918452SSaurabh Gorecha } 1944b918452SSaurabh Gorecha } 195