1*97ef5305SMario Bălănică /* 2*97ef5305SMario Bălănică * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. 3*97ef5305SMario Bălănică * 4*97ef5305SMario Bălănică * SPDX-License-Identifier: BSD-3-Clause 5*97ef5305SMario Bălănică */ 6*97ef5305SMario Bălănică 7*97ef5305SMario Bălănică #include <assert.h> 8*97ef5305SMario Bălănică #include <inttypes.h> 9*97ef5305SMario Bălănică #include <stdint.h> 10*97ef5305SMario Bălănică 11*97ef5305SMario Bălănică #include <arch_helpers.h> 12*97ef5305SMario Bălănică #include <common/bl_common.h> 13*97ef5305SMario Bălănică #include <drivers/arm/gicv2.h> 14*97ef5305SMario Bălănică #include <lib/mmio.h> 15*97ef5305SMario Bălănică #include <lib/xlat_tables/xlat_mmu_helpers.h> 16*97ef5305SMario Bălănică #include <lib/xlat_tables/xlat_tables_defs.h> 17*97ef5305SMario Bălănică #include <lib/xlat_tables/xlat_tables_v2.h> 18*97ef5305SMario Bălănică #include <plat/common/platform.h> 19*97ef5305SMario Bălănică #include <platform_def.h> 20*97ef5305SMario Bălănică 21*97ef5305SMario Bălănică #include <rpi_shared.h> 22*97ef5305SMario Bălănică 23*97ef5305SMario Bălănică /* 24*97ef5305SMario Bălănică * Fields at the beginning of armstub8.bin. 25*97ef5305SMario Bălănică * While building the BL31 image, we put the stub magic into the binary. 26*97ef5305SMario Bălănică * The GPU firmware detects this at boot time, clears that field as a 27*97ef5305SMario Bălănică * confirmation and puts the kernel and DT address in the following words. 28*97ef5305SMario Bălănică */ 29*97ef5305SMario Bălănică extern uint32_t stub_magic; 30*97ef5305SMario Bălănică extern uint32_t dtb_ptr32; 31*97ef5305SMario Bălănică extern uint32_t kernel_entry32; 32*97ef5305SMario Bălănică 33*97ef5305SMario Bălănică static const gicv2_driver_data_t rpi4_gic_data = { 34*97ef5305SMario Bălănică .gicd_base = RPI4_GIC_GICD_BASE, 35*97ef5305SMario Bălănică .gicc_base = RPI4_GIC_GICC_BASE, 36*97ef5305SMario Bălănică }; 37*97ef5305SMario Bălănică 38*97ef5305SMario Bălănică /* 39*97ef5305SMario Bălănică * To be filled by the code below. At the moment BL32 is not supported. 40*97ef5305SMario Bălănică * In the future these might be passed down from BL2. 41*97ef5305SMario Bălănică */ 42*97ef5305SMario Bălănică static entry_point_info_t bl32_image_ep_info; 43*97ef5305SMario Bălănică static entry_point_info_t bl33_image_ep_info; 44*97ef5305SMario Bălănică 45*97ef5305SMario Bălănică /******************************************************************************* 46*97ef5305SMario Bălănică * Return a pointer to the 'entry_point_info' structure of the next image for 47*97ef5305SMario Bălănică * the security state specified. BL33 corresponds to the non-secure image type 48*97ef5305SMario Bălănică * while BL32 corresponds to the secure image type. A NULL pointer is returned 49*97ef5305SMario Bălănică * if the image does not exist. 50*97ef5305SMario Bălănică ******************************************************************************/ 51*97ef5305SMario Bălănică entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) 52*97ef5305SMario Bălănică { 53*97ef5305SMario Bălănică entry_point_info_t *next_image_info; 54*97ef5305SMario Bălănică 55*97ef5305SMario Bălănică assert(sec_state_is_valid(type) != 0); 56*97ef5305SMario Bălănică 57*97ef5305SMario Bălănică next_image_info = (type == NON_SECURE) 58*97ef5305SMario Bălănică ? &bl33_image_ep_info : &bl32_image_ep_info; 59*97ef5305SMario Bălănică 60*97ef5305SMario Bălănică /* None of the images can have 0x0 as the entrypoint. */ 61*97ef5305SMario Bălănică if (next_image_info->pc) { 62*97ef5305SMario Bălănică return next_image_info; 63*97ef5305SMario Bălănică } else { 64*97ef5305SMario Bălănică return NULL; 65*97ef5305SMario Bălănică } 66*97ef5305SMario Bălănică } 67*97ef5305SMario Bălănică 68*97ef5305SMario Bălănică uintptr_t plat_get_ns_image_entrypoint(void) 69*97ef5305SMario Bălănică { 70*97ef5305SMario Bălănică #ifdef PRELOADED_BL33_BASE 71*97ef5305SMario Bălănică return PRELOADED_BL33_BASE; 72*97ef5305SMario Bălănică #else 73*97ef5305SMario Bălănică /* Cleared by the GPU if kernel address is valid. */ 74*97ef5305SMario Bălănică if (stub_magic == 0) 75*97ef5305SMario Bălănică return kernel_entry32; 76*97ef5305SMario Bălănică 77*97ef5305SMario Bălănică WARN("Stub magic failure, using default kernel address 0x80000\n"); 78*97ef5305SMario Bălănică return 0x80000; 79*97ef5305SMario Bălănică #endif 80*97ef5305SMario Bălănică } 81*97ef5305SMario Bălănică 82*97ef5305SMario Bălănică uintptr_t rpi4_get_dtb_address(void) 83*97ef5305SMario Bălănică { 84*97ef5305SMario Bălănică #ifdef RPI3_PRELOADED_DTB_BASE 85*97ef5305SMario Bălănică return RPI3_PRELOADED_DTB_BASE; 86*97ef5305SMario Bălănică #else 87*97ef5305SMario Bălănică /* Cleared by the GPU if DTB address is valid. */ 88*97ef5305SMario Bălănică if (stub_magic == 0) 89*97ef5305SMario Bălănică return dtb_ptr32; 90*97ef5305SMario Bălănică 91*97ef5305SMario Bălănică WARN("Stub magic failure, DTB address unknown\n"); 92*97ef5305SMario Bălănică return 0; 93*97ef5305SMario Bălănică #endif 94*97ef5305SMario Bălănică } 95*97ef5305SMario Bălănică 96*97ef5305SMario Bălănică static void ldelay(register_t delay) 97*97ef5305SMario Bălănică { 98*97ef5305SMario Bălănică __asm__ volatile ( 99*97ef5305SMario Bălănică "1:\tcbz %0, 2f\n\t" 100*97ef5305SMario Bălănică "sub %0, %0, #1\n\t" 101*97ef5305SMario Bălănică "b 1b\n" 102*97ef5305SMario Bălănică "2:" 103*97ef5305SMario Bălănică : "=&r" (delay) : "0" (delay) 104*97ef5305SMario Bălănică ); 105*97ef5305SMario Bălănică } 106*97ef5305SMario Bălănică 107*97ef5305SMario Bălănică /******************************************************************************* 108*97ef5305SMario Bălănică * Perform any BL31 early platform setup. Here is an opportunity to copy 109*97ef5305SMario Bălănică * parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before 110*97ef5305SMario Bălănică * they are lost (potentially). This needs to be done before the MMU is 111*97ef5305SMario Bălănică * initialized so that the memory layout can be used while creating page 112*97ef5305SMario Bălănică * tables. BL2 has flushed this information to memory, so we are guaranteed 113*97ef5305SMario Bălănică * to pick up good data. 114*97ef5305SMario Bălănică ******************************************************************************/ 115*97ef5305SMario Bălănică void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, 116*97ef5305SMario Bălănică u_register_t arg2, u_register_t arg3) 117*97ef5305SMario Bălănică 118*97ef5305SMario Bălănică { 119*97ef5305SMario Bălănică /* 120*97ef5305SMario Bălănică * LOCAL_CONTROL: 121*97ef5305SMario Bălănică * Bit 9 clear: Increment by 1 (vs. 2). 122*97ef5305SMario Bălănică * Bit 8 clear: Timer source is 19.2MHz crystal (vs. APB). 123*97ef5305SMario Bălănică */ 124*97ef5305SMario Bălănică mmio_write_32(RPI4_LOCAL_CONTROL_BASE_ADDRESS, 0); 125*97ef5305SMario Bălănică 126*97ef5305SMario Bălănică /* LOCAL_PRESCALER; divide-by (0x80000000 / register_val) == 1 */ 127*97ef5305SMario Bălănică mmio_write_32(RPI4_LOCAL_CONTROL_PRESCALER, 0x80000000); 128*97ef5305SMario Bălănică 129*97ef5305SMario Bălănică /* Early GPU firmware revisions need a little break here. */ 130*97ef5305SMario Bălănică ldelay(100000); 131*97ef5305SMario Bălănică 132*97ef5305SMario Bălănică /* Initialize the console to provide early debug support. */ 133*97ef5305SMario Bălănică rpi3_console_init(); 134*97ef5305SMario Bălănică 135*97ef5305SMario Bălănică bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); 136*97ef5305SMario Bălănică bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry(); 137*97ef5305SMario Bălănică SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); 138*97ef5305SMario Bălănică 139*97ef5305SMario Bălănică #if RPI3_DIRECT_LINUX_BOOT 140*97ef5305SMario Bălănică # if RPI3_BL33_IN_AARCH32 141*97ef5305SMario Bălănică /* 142*97ef5305SMario Bălănică * According to the file ``Documentation/arm/Booting`` of the Linux 143*97ef5305SMario Bălănică * kernel tree, Linux expects: 144*97ef5305SMario Bălănică * r0 = 0 145*97ef5305SMario Bălănică * r1 = machine type number, optional in DT-only platforms (~0 if so) 146*97ef5305SMario Bălănică * r2 = Physical address of the device tree blob 147*97ef5305SMario Bălănică */ 148*97ef5305SMario Bălănică VERBOSE("rpi: Preparing to boot 32-bit Linux kernel\n"); 149*97ef5305SMario Bălănică bl33_image_ep_info.args.arg0 = 0U; 150*97ef5305SMario Bălănică bl33_image_ep_info.args.arg1 = ~0U; 151*97ef5305SMario Bălănică bl33_image_ep_info.args.arg2 = rpi4_get_dtb_address(); 152*97ef5305SMario Bălănică # else 153*97ef5305SMario Bălănică /* 154*97ef5305SMario Bălănică * According to the file ``Documentation/arm64/booting.txt`` of the 155*97ef5305SMario Bălănică * Linux kernel tree, Linux expects the physical address of the device 156*97ef5305SMario Bălănică * tree blob (DTB) in x0, while x1-x3 are reserved for future use and 157*97ef5305SMario Bălănică * must be 0. 158*97ef5305SMario Bălănică */ 159*97ef5305SMario Bălănică VERBOSE("rpi: Preparing to boot 64-bit Linux kernel\n"); 160*97ef5305SMario Bălănică bl33_image_ep_info.args.arg0 = rpi4_get_dtb_address(); 161*97ef5305SMario Bălănică bl33_image_ep_info.args.arg1 = 0ULL; 162*97ef5305SMario Bălănică bl33_image_ep_info.args.arg2 = 0ULL; 163*97ef5305SMario Bălănică bl33_image_ep_info.args.arg3 = 0ULL; 164*97ef5305SMario Bălănică # endif /* RPI3_BL33_IN_AARCH32 */ 165*97ef5305SMario Bălănică #endif /* RPI3_DIRECT_LINUX_BOOT */ 166*97ef5305SMario Bălănică } 167*97ef5305SMario Bălănică 168*97ef5305SMario Bălănică void bl31_plat_arch_setup(void) 169*97ef5305SMario Bălănică { 170*97ef5305SMario Bălănică /* 171*97ef5305SMario Bălănică * Is the dtb_ptr32 pointer valid? If yes, map the DTB region. 172*97ef5305SMario Bălănică * We map the 2MB region the DTB start address lives in, plus 173*97ef5305SMario Bălănică * the next 2MB, to have enough room for expansion. 174*97ef5305SMario Bălănică */ 175*97ef5305SMario Bălănică if (stub_magic == 0) { 176*97ef5305SMario Bălănică unsigned long long dtb_region = dtb_ptr32; 177*97ef5305SMario Bălănică 178*97ef5305SMario Bălănică dtb_region &= ~0x1fffff; /* Align to 2 MB. */ 179*97ef5305SMario Bălănică mmap_add_region(dtb_region, dtb_region, 4U << 20, 180*97ef5305SMario Bălănică MT_MEMORY | MT_RW | MT_NS); 181*97ef5305SMario Bălănică } 182*97ef5305SMario Bălănică /* 183*97ef5305SMario Bălănică * Add the first page of memory, which holds the stub magic, 184*97ef5305SMario Bălănică * the kernel and the DT address. 185*97ef5305SMario Bălănică * This also holds the secondary CPU's entrypoints and mailboxes. 186*97ef5305SMario Bălănică */ 187*97ef5305SMario Bălănică mmap_add_region(0, 0, 4096, MT_NON_CACHEABLE | MT_RW | MT_SECURE); 188*97ef5305SMario Bălănică 189*97ef5305SMario Bălănică rpi3_setup_page_tables(BL31_BASE, BL31_END - BL31_BASE, 190*97ef5305SMario Bălănică BL_CODE_BASE, BL_CODE_END, 191*97ef5305SMario Bălănică BL_RO_DATA_BASE, BL_RO_DATA_END 192*97ef5305SMario Bălănică #if USE_COHERENT_MEM 193*97ef5305SMario Bălănică , BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END 194*97ef5305SMario Bălănică #endif 195*97ef5305SMario Bălănică ); 196*97ef5305SMario Bălănică 197*97ef5305SMario Bălănică enable_mmu_el3(0); 198*97ef5305SMario Bălănică } 199*97ef5305SMario Bălănică 200*97ef5305SMario Bălănică void bl31_platform_setup(void) 201*97ef5305SMario Bălănică { 202*97ef5305SMario Bălănică /* Configure the interrupt controller */ 203*97ef5305SMario Bălănică gicv2_driver_init(&rpi4_gic_data); 204*97ef5305SMario Bălănică gicv2_distif_init(); 205*97ef5305SMario Bălănică gicv2_pcpu_distif_init(); 206*97ef5305SMario Bălănică gicv2_cpuif_enable(); 207*97ef5305SMario Bălănică 208*97ef5305SMario Bălănică plat_rpi_bl31_custom_setup(); 209*97ef5305SMario Bălănică } 210