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