| /* |
| * Copyright 2018-2022 NXP |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| * |
| */ |
| |
| #include <assert.h> |
| |
| #include <arch.h> |
| #include <arch_helpers.h> |
| #include <common/debug.h> |
| #include <lib/mmio.h> |
| #include <lib/xlat_tables/xlat_tables_v2.h> |
| #include <mmu_def.h> |
| #include <plat/common/platform.h> |
| |
| #include "plat_common.h" |
| #include "platform_def.h" |
| |
| const mmap_region_t *plat_ls_get_mmap(void); |
| |
| /* |
| * Table of memory regions for various BL stages to map using the MMU. |
| * This doesn't include Trusted SRAM as arm_setup_page_tables() already |
| * takes care of mapping it. |
| * |
| * The flash needs to be mapped as writable in order to erase the FIP's Table of |
| * Contents in case of unrecoverable error (see plat_error_handler()). |
| */ |
| #ifdef IMAGE_BL2 |
| const mmap_region_t plat_ls_mmap[] = { |
| LS_MAP_CCSR, |
| {0} |
| }; |
| #endif |
| |
| #ifdef IMAGE_BL31 |
| const mmap_region_t plat_ls_mmap[] = { |
| LS_MAP_CCSR, |
| #ifdef NXP_DCSR_ADDR |
| LS_MAP_DCSR, |
| #endif |
| LS_MAP_OCRAM, |
| {0} |
| }; |
| #endif |
| #ifdef IMAGE_BL32 |
| const mmap_region_t plat_ls_mmap[] = { |
| LS_MAP_CCSR, |
| LS_MAP_BL32_SEC_MEM, |
| {0} |
| }; |
| #endif |
| |
| /* Weak definitions may be overridden in specific NXP SoC */ |
| #pragma weak plat_get_ns_image_entrypoint |
| #pragma weak plat_ls_get_mmap |
| |
| #if defined(IMAGE_BL31) || !defined(CONFIG_DDR_FIP_IMAGE) |
| static void mmap_add_ddr_regions_statically(void) |
| { |
| int i = 0; |
| dram_regions_info_t *info_dram_regions = get_dram_regions_info(); |
| /* MMU map for Non-Secure DRAM Regions */ |
| VERBOSE("DRAM Region %d: %p - %p\n", i, |
| (void *) info_dram_regions->region[i].addr, |
| (void *) (info_dram_regions->region[i].addr |
| + info_dram_regions->region[i].size |
| - 1)); |
| mmap_add_region(info_dram_regions->region[i].addr, |
| info_dram_regions->region[i].addr, |
| info_dram_regions->region[i].size, |
| MT_MEMORY | MT_RW | MT_NS); |
| |
| /* MMU map for Secure DDR Region on DRAM-0 */ |
| if (info_dram_regions->region[i].size > |
| (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE)) { |
| VERBOSE("Secure DRAM Region %d: %p - %p\n", i, |
| (void *) (info_dram_regions->region[i].addr |
| + info_dram_regions->region[i].size), |
| (void *) (info_dram_regions->region[i].addr |
| + info_dram_regions->region[i].size |
| + NXP_SECURE_DRAM_SIZE |
| + NXP_SP_SHRD_DRAM_SIZE |
| - 1)); |
| mmap_add_region((info_dram_regions->region[i].addr |
| + info_dram_regions->region[i].size), |
| (info_dram_regions->region[i].addr |
| + info_dram_regions->region[i].size), |
| (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE), |
| MT_MEMORY | MT_RW | MT_SECURE); |
| } |
| |
| #ifdef IMAGE_BL31 |
| for (i = 1; i < info_dram_regions->num_dram_regions; i++) { |
| if (info_dram_regions->region[i].size == 0) |
| break; |
| VERBOSE("DRAM Region %d: %p - %p\n", i, |
| (void *) info_dram_regions->region[i].addr, |
| (void *) (info_dram_regions->region[i].addr |
| + info_dram_regions->region[i].size |
| - 1)); |
| mmap_add_region(info_dram_regions->region[i].addr, |
| info_dram_regions->region[i].addr, |
| info_dram_regions->region[i].size, |
| MT_MEMORY | MT_RW | MT_NS); |
| } |
| #endif |
| } |
| #endif |
| |
| #if defined(PLAT_XLAT_TABLES_DYNAMIC) |
| void mmap_add_ddr_region_dynamically(void) |
| { |
| int ret, i = 0; |
| |
| dram_regions_info_t *info_dram_regions = get_dram_regions_info(); |
| /* MMU map for Non-Secure DRAM Regions */ |
| VERBOSE("DRAM Region %d: %p - %p\n", i, |
| (void *) info_dram_regions->region[i].addr, |
| (void *) (info_dram_regions->region[i].addr |
| + info_dram_regions->region[i].size |
| - 1)); |
| ret = mmap_add_dynamic_region(info_dram_regions->region[i].addr, |
| info_dram_regions->region[i].addr, |
| info_dram_regions->region[i].size, |
| MT_MEMORY | MT_RW | MT_NS); |
| if (ret != 0) { |
| ERROR("Failed to add dynamic memory region\n"); |
| panic(); |
| } |
| |
| /* MMU map for Secure DDR Region on DRAM-0 */ |
| if (info_dram_regions->region[i].size > |
| (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE)) { |
| VERBOSE("Secure DRAM Region %d: %p - %p\n", i, |
| (void *) (info_dram_regions->region[i].addr |
| + info_dram_regions->region[i].size), |
| (void *) (info_dram_regions->region[i].addr |
| + info_dram_regions->region[i].size |
| + NXP_SECURE_DRAM_SIZE |
| + NXP_SP_SHRD_DRAM_SIZE |
| - 1)); |
| ret = mmap_add_dynamic_region((info_dram_regions->region[i].addr |
| + info_dram_regions->region[i].size), |
| (info_dram_regions->region[i].addr |
| + info_dram_regions->region[i].size), |
| (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE), |
| MT_MEMORY | MT_RW | MT_SECURE); |
| if (ret != 0) { |
| ERROR("Failed to add dynamic memory region\n"); |
| panic(); |
| } |
| } |
| |
| #ifdef IMAGE_BL31 |
| for (i = 1; i < info_dram_regions->num_dram_regions; i++) { |
| if (info_dram_regions->region[i].size == 0) { |
| break; |
| } |
| VERBOSE("DRAM Region %d: %p - %p\n", i, |
| (void *) info_dram_regions->region[i].addr, |
| (void *) (info_dram_regions->region[i].addr |
| + info_dram_regions->region[i].size |
| - 1)); |
| ret = mmap_add_dynamic_region(info_dram_regions->region[i].addr, |
| info_dram_regions->region[i].addr, |
| info_dram_regions->region[i].size, |
| MT_MEMORY | MT_RW | MT_NS); |
| if (ret != 0) { |
| ERROR("Failed to add dynamic memory region\n"); |
| panic(); |
| } |
| } |
| #endif |
| } |
| #endif |
| |
| /* |
| * Set up the page tables for the generic and platform-specific memory regions. |
| * The extents of the generic memory regions are specified by the function |
| * arguments and consist of: |
| * - Trusted SRAM seen by the BL image; |
| * - Code section; |
| * - Read-only data section; |
| * - Coherent memory region, if applicable. |
| */ |
| void ls_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 |
| #if USE_COHERENT_MEM |
| , |
| uintptr_t coh_start, |
| uintptr_t coh_limit |
| #endif |
| ) |
| { |
| /* |
| * Map the Trusted SRAM with appropriate memory attributes. |
| * Subsequent mappings will adjust the attributes for specific regions. |
| */ |
| VERBOSE("Memory seen by this BL image: %p - %p\n", |
| (void *) total_base, (void *) (total_base + total_size)); |
| mmap_add_region(total_base, total_base, |
| total_size, |
| MT_MEMORY | MT_RW | MT_SECURE); |
| |
| /* Re-map the code section */ |
| VERBOSE("Code region: %p - %p\n", |
| (void *) code_start, (void *) code_limit); |
| mmap_add_region(code_start, code_start, |
| code_limit - code_start, |
| MT_CODE | MT_SECURE); |
| |
| /* Re-map the read-only data section */ |
| VERBOSE("Read-only data region: %p - %p\n", |
| (void *) rodata_start, (void *) rodata_limit); |
| mmap_add_region(rodata_start, rodata_start, |
| rodata_limit - rodata_start, |
| MT_RO_DATA | MT_SECURE); |
| |
| #if USE_COHERENT_MEM |
| /* Re-map the coherent memory region */ |
| VERBOSE("Coherent region: %p - %p\n", |
| (void *) coh_start, (void *) coh_limit); |
| mmap_add_region(coh_start, coh_start, |
| coh_limit - coh_start, |
| MT_DEVICE | MT_RW | MT_SECURE); |
| #endif |
| |
| /* Now (re-)map the platform-specific memory regions */ |
| mmap_add(plat_ls_get_mmap()); |
| |
| |
| #if defined(IMAGE_BL31) || !defined(CONFIG_DDR_FIP_IMAGE) |
| mmap_add_ddr_regions_statically(); |
| #endif |
| |
| /* Create the page tables to reflect the above mappings */ |
| init_xlat_tables(); |
| } |
| |
| /******************************************************************************* |
| * Returns NXP platform specific memory map regions. |
| ******************************************************************************/ |
| const mmap_region_t *plat_ls_get_mmap(void) |
| { |
| return plat_ls_mmap; |
| } |
| |
| /* |
| * This function get the number of clusters and cores count per cluster |
| * in the SoC. |
| */ |
| void get_cluster_info(const struct soc_type *soc_list, uint8_t ps_count, |
| uint8_t *num_clusters, uint8_t *cores_per_cluster) |
| { |
| const soc_info_t *soc_info = get_soc_info(); |
| *num_clusters = NUMBER_OF_CLUSTERS; |
| *cores_per_cluster = CORES_PER_CLUSTER; |
| unsigned int i; |
| |
| for (i = 0U; i < ps_count; i++) { |
| if (soc_list[i].version == soc_info->svr_reg.bf_ver.version) { |
| *num_clusters = soc_list[i].num_clusters; |
| *cores_per_cluster = soc_list[i].cores_per_cluster; |
| break; |
| } |
| } |
| |
| VERBOSE("NUM of cluster = 0x%x, Cores per cluster = 0x%x\n", |
| *num_clusters, *cores_per_cluster); |
| } |