1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * Copyright (c) 2019-2023, Intel Corporation. All rights reserved. 4*91f16700Schasinglulu * 5*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 6*91f16700Schasinglulu */ 7*91f16700Schasinglulu 8*91f16700Schasinglulu #include <assert.h> 9*91f16700Schasinglulu #include <arch.h> 10*91f16700Schasinglulu #include <arch_helpers.h> 11*91f16700Schasinglulu #include <common/bl_common.h> 12*91f16700Schasinglulu #include <drivers/arm/gic_common.h> 13*91f16700Schasinglulu #include <drivers/arm/gicv3.h> 14*91f16700Schasinglulu #include <drivers/ti/uart/uart_16550.h> 15*91f16700Schasinglulu #include <lib/mmio.h> 16*91f16700Schasinglulu #include <lib/xlat_tables/xlat_mmu_helpers.h> 17*91f16700Schasinglulu #include <lib/xlat_tables/xlat_tables_v2.h> 18*91f16700Schasinglulu #include <plat/common/platform.h> 19*91f16700Schasinglulu 20*91f16700Schasinglulu #include "agilex5_power_manager.h" 21*91f16700Schasinglulu #include "ccu/ncore_ccu.h" 22*91f16700Schasinglulu #include "socfpga_mailbox.h" 23*91f16700Schasinglulu #include "socfpga_private.h" 24*91f16700Schasinglulu #include "socfpga_reset_manager.h" 25*91f16700Schasinglulu 26*91f16700Schasinglulu /* Get non-secure SPSR for BL33. Zephyr and Linux */ 27*91f16700Schasinglulu uint32_t arm_get_spsr_for_bl33_entry(void); 28*91f16700Schasinglulu 29*91f16700Schasinglulu static entry_point_info_t bl32_image_ep_info; 30*91f16700Schasinglulu static entry_point_info_t bl33_image_ep_info; 31*91f16700Schasinglulu 32*91f16700Schasinglulu /* The GICv3 driver only needs to be initialized in EL3 */ 33*91f16700Schasinglulu static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; 34*91f16700Schasinglulu 35*91f16700Schasinglulu #define SMMU_SDMMC 36*91f16700Schasinglulu 37*91f16700Schasinglulu entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) 38*91f16700Schasinglulu { 39*91f16700Schasinglulu entry_point_info_t *next_image_info; 40*91f16700Schasinglulu 41*91f16700Schasinglulu next_image_info = (type == NON_SECURE) ? 42*91f16700Schasinglulu &bl33_image_ep_info : &bl32_image_ep_info; 43*91f16700Schasinglulu 44*91f16700Schasinglulu /* None of the images on this platform can have 0x0 as the entrypoint */ 45*91f16700Schasinglulu if (next_image_info->pc) 46*91f16700Schasinglulu return next_image_info; 47*91f16700Schasinglulu else 48*91f16700Schasinglulu return NULL; 49*91f16700Schasinglulu } 50*91f16700Schasinglulu 51*91f16700Schasinglulu void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, 52*91f16700Schasinglulu u_register_t arg2, u_register_t arg3) 53*91f16700Schasinglulu { 54*91f16700Schasinglulu static console_t console; 55*91f16700Schasinglulu 56*91f16700Schasinglulu mmio_write_64(PLAT_SEC_ENTRY, PLAT_SEC_WARM_ENTRY); 57*91f16700Schasinglulu 58*91f16700Schasinglulu console_16550_register(PLAT_INTEL_UART_BASE, PLAT_UART_CLOCK, 59*91f16700Schasinglulu PLAT_BAUDRATE, &console); 60*91f16700Schasinglulu 61*91f16700Schasinglulu init_ncore_ccu(); 62*91f16700Schasinglulu setup_smmu_stream_id(); 63*91f16700Schasinglulu 64*91f16700Schasinglulu /* 65*91f16700Schasinglulu * Check params passed from BL31 should not be NULL, 66*91f16700Schasinglulu */ 67*91f16700Schasinglulu void *from_bl2 = (void *) arg0; 68*91f16700Schasinglulu 69*91f16700Schasinglulu #if RESET_TO_BL31 70*91f16700Schasinglulu /* There are no parameters from BL2 if BL31 is a reset vector */ 71*91f16700Schasinglulu assert(from_bl2 == NULL); 72*91f16700Schasinglulu void *plat_params_from_bl2 = (void *) arg3; 73*91f16700Schasinglulu 74*91f16700Schasinglulu assert(plat_params_from_bl2 == NULL); 75*91f16700Schasinglulu 76*91f16700Schasinglulu /* Populate entry point information for BL33 */ 77*91f16700Schasinglulu SET_PARAM_HEAD(&bl33_image_ep_info, 78*91f16700Schasinglulu PARAM_EP, 79*91f16700Schasinglulu VERSION_1, 80*91f16700Schasinglulu 0); 81*91f16700Schasinglulu 82*91f16700Schasinglulu # if ARM_LINUX_KERNEL_AS_BL33 83*91f16700Schasinglulu /* 84*91f16700Schasinglulu * According to the file ``Documentation/arm64/booting.txt`` of the 85*91f16700Schasinglulu * Linux kernel tree, Linux expects the physical address of the device 86*91f16700Schasinglulu * tree blob (DTB) in x0, while x1-x3 are reserved for future use and 87*91f16700Schasinglulu * must be 0. 88*91f16700Schasinglulu */ 89*91f16700Schasinglulu bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE; 90*91f16700Schasinglulu bl33_image_ep_info.args.arg1 = 0U; 91*91f16700Schasinglulu bl33_image_ep_info.args.arg2 = 0U; 92*91f16700Schasinglulu bl33_image_ep_info.args.arg3 = 0U; 93*91f16700Schasinglulu # endif 94*91f16700Schasinglulu 95*91f16700Schasinglulu #else /* RESET_TO_BL31 */ 96*91f16700Schasinglulu bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; 97*91f16700Schasinglulu 98*91f16700Schasinglulu assert(params_from_bl2 != NULL); 99*91f16700Schasinglulu 100*91f16700Schasinglulu /* 101*91f16700Schasinglulu * Copy BL32 (if populated by BL31) and BL33 entry point information. 102*91f16700Schasinglulu * They are stored in Secure RAM, in BL31's address space. 103*91f16700Schasinglulu */ 104*91f16700Schasinglulu 105*91f16700Schasinglulu if (params_from_bl2->h.type == PARAM_BL_PARAMS && 106*91f16700Schasinglulu params_from_bl2->h.version >= VERSION_2) { 107*91f16700Schasinglulu 108*91f16700Schasinglulu bl_params_node_t *bl_params = params_from_bl2->head; 109*91f16700Schasinglulu 110*91f16700Schasinglulu while (bl_params) { 111*91f16700Schasinglulu if (bl_params->image_id == BL33_IMAGE_ID) { 112*91f16700Schasinglulu bl33_image_ep_info = *bl_params->ep_info; 113*91f16700Schasinglulu } 114*91f16700Schasinglulu bl_params = bl_params->next_params_info; 115*91f16700Schasinglulu } 116*91f16700Schasinglulu } else { 117*91f16700Schasinglulu struct socfpga_bl31_params *arg_from_bl2 = 118*91f16700Schasinglulu (struct socfpga_bl31_params *) from_bl2; 119*91f16700Schasinglulu 120*91f16700Schasinglulu assert(arg_from_bl2->h.type == PARAM_BL31); 121*91f16700Schasinglulu assert(arg_from_bl2->h.version >= VERSION_1); 122*91f16700Schasinglulu 123*91f16700Schasinglulu bl32_image_ep_info = *arg_from_bl2->bl32_ep_info; 124*91f16700Schasinglulu bl33_image_ep_info = *arg_from_bl2->bl33_ep_info; 125*91f16700Schasinglulu } 126*91f16700Schasinglulu 127*91f16700Schasinglulu bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE; 128*91f16700Schasinglulu bl33_image_ep_info.args.arg1 = 0U; 129*91f16700Schasinglulu bl33_image_ep_info.args.arg2 = 0U; 130*91f16700Schasinglulu bl33_image_ep_info.args.arg3 = 0U; 131*91f16700Schasinglulu #endif 132*91f16700Schasinglulu 133*91f16700Schasinglulu /* 134*91f16700Schasinglulu * Tell BL31 where the non-trusted software image 135*91f16700Schasinglulu * is located and the entry state information 136*91f16700Schasinglulu */ 137*91f16700Schasinglulu bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); 138*91f16700Schasinglulu bl33_image_ep_info.spsr = arm_get_spsr_for_bl33_entry(); 139*91f16700Schasinglulu 140*91f16700Schasinglulu SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); 141*91f16700Schasinglulu } 142*91f16700Schasinglulu 143*91f16700Schasinglulu static const interrupt_prop_t agx5_interrupt_props[] = { 144*91f16700Schasinglulu PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(INTR_GROUP1S), 145*91f16700Schasinglulu PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(INTR_GROUP0) 146*91f16700Schasinglulu }; 147*91f16700Schasinglulu 148*91f16700Schasinglulu static const gicv3_driver_data_t plat_gicv3_gic_data = { 149*91f16700Schasinglulu .gicd_base = PLAT_INTEL_SOCFPGA_GICD_BASE, 150*91f16700Schasinglulu .gicr_base = PLAT_INTEL_SOCFPGA_GICR_BASE, 151*91f16700Schasinglulu .interrupt_props = agx5_interrupt_props, 152*91f16700Schasinglulu .interrupt_props_num = ARRAY_SIZE(agx5_interrupt_props), 153*91f16700Schasinglulu .rdistif_num = PLATFORM_CORE_COUNT, 154*91f16700Schasinglulu .rdistif_base_addrs = rdistif_base_addrs, 155*91f16700Schasinglulu }; 156*91f16700Schasinglulu 157*91f16700Schasinglulu /******************************************************************************* 158*91f16700Schasinglulu * Perform any BL3-1 platform setup code 159*91f16700Schasinglulu ******************************************************************************/ 160*91f16700Schasinglulu void bl31_platform_setup(void) 161*91f16700Schasinglulu { 162*91f16700Schasinglulu socfpga_delay_timer_init(); 163*91f16700Schasinglulu 164*91f16700Schasinglulu /* Initialize the gic cpu and distributor interfaces */ 165*91f16700Schasinglulu gicv3_driver_init(&plat_gicv3_gic_data); 166*91f16700Schasinglulu gicv3_distif_init(); 167*91f16700Schasinglulu gicv3_rdistif_init(plat_my_core_pos()); 168*91f16700Schasinglulu gicv3_cpuif_enable(plat_my_core_pos()); 169*91f16700Schasinglulu mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL); 170*91f16700Schasinglulu #if !defined(SIMICS_RUN) 171*91f16700Schasinglulu ncore_enable_ocram_firewall(); 172*91f16700Schasinglulu #endif 173*91f16700Schasinglulu 174*91f16700Schasinglulu } 175*91f16700Schasinglulu 176*91f16700Schasinglulu const mmap_region_t plat_agilex_mmap[] = { 177*91f16700Schasinglulu MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS), 178*91f16700Schasinglulu MAP_REGION_FLAT(PSS_BASE, PSS_SIZE, MT_DEVICE | MT_RW | MT_NS), 179*91f16700Schasinglulu MAP_REGION_FLAT(MPFE_BASE, MPFE_SIZE, MT_DEVICE | MT_RW | MT_SECURE), 180*91f16700Schasinglulu MAP_REGION_FLAT(OCRAM_BASE, OCRAM_SIZE, MT_NON_CACHEABLE | MT_RW | MT_SECURE), 181*91f16700Schasinglulu MAP_REGION_FLAT(CCU_BASE, CCU_SIZE, MT_DEVICE | MT_RW | MT_SECURE), 182*91f16700Schasinglulu MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE, MT_DEVICE | MT_RW | MT_NS), 183*91f16700Schasinglulu MAP_REGION_FLAT(GIC_BASE, GIC_SIZE, MT_DEVICE | MT_RW | MT_SECURE), 184*91f16700Schasinglulu {0} 185*91f16700Schasinglulu }; 186*91f16700Schasinglulu 187*91f16700Schasinglulu /******************************************************************************* 188*91f16700Schasinglulu * Perform the very early platform specific architectural setup here. At the 189*91f16700Schasinglulu * moment this is only intializes the mmu in a quick and dirty way. 190*91f16700Schasinglulu ******************************************************************************/ 191*91f16700Schasinglulu void bl31_plat_arch_setup(void) 192*91f16700Schasinglulu { 193*91f16700Schasinglulu uint32_t boot_core = 0x00; 194*91f16700Schasinglulu uint32_t cpuid = 0x00; 195*91f16700Schasinglulu 196*91f16700Schasinglulu cpuid = read_mpidr(); 197*91f16700Schasinglulu boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00); 198*91f16700Schasinglulu NOTICE("BL31: Boot Core = %x\n", boot_core); 199*91f16700Schasinglulu NOTICE("BL31: CPU ID = %x\n", cpuid); 200*91f16700Schasinglulu 201*91f16700Schasinglulu } 202*91f16700Schasinglulu 203*91f16700Schasinglulu /* Get non-secure image entrypoint for BL33. Zephyr and Linux */ 204*91f16700Schasinglulu uintptr_t plat_get_ns_image_entrypoint(void) 205*91f16700Schasinglulu { 206*91f16700Schasinglulu #ifdef PRELOADED_BL33_BASE 207*91f16700Schasinglulu return PRELOADED_BL33_BASE; 208*91f16700Schasinglulu #else 209*91f16700Schasinglulu return PLAT_NS_IMAGE_OFFSET; 210*91f16700Schasinglulu #endif 211*91f16700Schasinglulu } 212*91f16700Schasinglulu 213*91f16700Schasinglulu /* Get non-secure SPSR for BL33. Zephyr and Linux */ 214*91f16700Schasinglulu uint32_t arm_get_spsr_for_bl33_entry(void) 215*91f16700Schasinglulu { 216*91f16700Schasinglulu unsigned int mode; 217*91f16700Schasinglulu uint32_t spsr; 218*91f16700Schasinglulu 219*91f16700Schasinglulu /* Figure out what mode we enter the non-secure world in */ 220*91f16700Schasinglulu mode = (el_implemented(2) != EL_IMPL_NONE) ? MODE_EL2 : MODE_EL1; 221*91f16700Schasinglulu 222*91f16700Schasinglulu /* 223*91f16700Schasinglulu * TODO: Consider the possibility of specifying the SPSR in 224*91f16700Schasinglulu * the FIP ToC and allowing the platform to have a say as 225*91f16700Schasinglulu * well. 226*91f16700Schasinglulu */ 227*91f16700Schasinglulu spsr = SPSR_64((uint64_t)mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); 228*91f16700Schasinglulu return spsr; 229*91f16700Schasinglulu } 230*91f16700Schasinglulu 231*91f16700Schasinglulu /* SMP: Secondary cores BL31 setup reset vector */ 232*91f16700Schasinglulu void bl31_plat_set_secondary_cpu_entrypoint(unsigned int cpu_id) 233*91f16700Schasinglulu { 234*91f16700Schasinglulu unsigned int pch_cpu = 0x00; 235*91f16700Schasinglulu unsigned int pchctlr_old = 0x00; 236*91f16700Schasinglulu unsigned int pchctlr_new = 0x00; 237*91f16700Schasinglulu uint32_t boot_core = 0x00; 238*91f16700Schasinglulu 239*91f16700Schasinglulu boot_core = (mmio_read_32(AGX5_PWRMGR(MPU_BOOTCONFIG)) & 0xC00); 240*91f16700Schasinglulu /* Update the p-channel based on cpu id */ 241*91f16700Schasinglulu pch_cpu = 1 << cpu_id; 242*91f16700Schasinglulu 243*91f16700Schasinglulu if (boot_core == 0x00) { 244*91f16700Schasinglulu /* Update reset vector to 0x00 */ 245*91f16700Schasinglulu mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU2, 246*91f16700Schasinglulu (uint64_t) plat_secondary_cpus_bl31_entry >> 2); 247*91f16700Schasinglulu } else { 248*91f16700Schasinglulu /* Update reset vector to 0x00 */ 249*91f16700Schasinglulu mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU0, 250*91f16700Schasinglulu (uint64_t) plat_secondary_cpus_bl31_entry >> 2); 251*91f16700Schasinglulu } 252*91f16700Schasinglulu 253*91f16700Schasinglulu /* Update reset vector to 0x00 */ 254*91f16700Schasinglulu mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU1, (uint64_t) plat_secondary_cpus_bl31_entry >> 2); 255*91f16700Schasinglulu mmio_write_64(RSTMGR_CPUxRESETBASELOW_CPU3, (uint64_t) plat_secondary_cpus_bl31_entry >> 2); 256*91f16700Schasinglulu 257*91f16700Schasinglulu /* On all cores - temporary */ 258*91f16700Schasinglulu pchctlr_old = mmio_read_32(AGX5_PWRMGR(MPU_PCHCTLR)); 259*91f16700Schasinglulu pchctlr_new = pchctlr_old | (pch_cpu<<1); 260*91f16700Schasinglulu mmio_write_32(AGX5_PWRMGR(MPU_PCHCTLR), pchctlr_new); 261*91f16700Schasinglulu 262*91f16700Schasinglulu /* We will only release the target secondary CPUs */ 263*91f16700Schasinglulu /* Bit mask for each CPU BIT0-3 */ 264*91f16700Schasinglulu mmio_write_32(RSTMGR_CPUSTRELEASE_CPUx, pch_cpu); 265*91f16700Schasinglulu } 266*91f16700Schasinglulu 267*91f16700Schasinglulu void bl31_plat_set_secondary_cpu_off(void) 268*91f16700Schasinglulu { 269*91f16700Schasinglulu unsigned int pch_cpu = 0x00; 270*91f16700Schasinglulu unsigned int pch_cpu_off = 0x00; 271*91f16700Schasinglulu unsigned int cpu_id = plat_my_core_pos(); 272*91f16700Schasinglulu 273*91f16700Schasinglulu pch_cpu_off = 1 << cpu_id; 274*91f16700Schasinglulu 275*91f16700Schasinglulu pch_cpu = mmio_read_32(AGX5_PWRMGR(MPU_PCHCTLR)); 276*91f16700Schasinglulu pch_cpu = pch_cpu & ~(pch_cpu_off << 1); 277*91f16700Schasinglulu 278*91f16700Schasinglulu mmio_write_32(AGX5_PWRMGR(MPU_PCHCTLR), pch_cpu); 279*91f16700Schasinglulu } 280*91f16700Schasinglulu 281*91f16700Schasinglulu void bl31_plat_enable_mmu(uint32_t flags) 282*91f16700Schasinglulu { 283*91f16700Schasinglulu /* TODO: Enable mmu when needed */ 284*91f16700Schasinglulu } 285