1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright 2018 NXP 4 * Copyright (C) 2015 Freescale Semiconductor, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <platform_config.h> 31 32 #include <arm.h> 33 #include <console.h> 34 #include <drivers/gic.h> 35 #ifdef CFG_PL011 36 #include <drivers/pl011.h> 37 #else 38 #include <drivers/ns16550.h> 39 #endif 40 #include <io.h> 41 #include <kernel/boot.h> 42 #include <kernel/dt.h> 43 #include <kernel/misc.h> 44 #include <kernel/panic.h> 45 #include <kernel/thread.h> 46 #include <kernel/tz_ssvce_def.h> 47 #include <libfdt.h> 48 #include <mm/core_memprot.h> 49 #include <sm/optee_smc.h> 50 #include <kernel/tee_common_otp.h> 51 #include <mm/core_mmu.h> 52 53 static struct gic_data gic_data; 54 #ifdef CFG_PL011 55 static struct pl011_data console_data; 56 #else 57 static struct ns16550_data console_data; 58 #endif 59 60 register_phys_mem_pgdir(MEM_AREA_IO_NSEC, CONSOLE_UART_BASE, 61 CORE_MMU_PGDIR_SIZE); 62 #if !defined(PLATFORM_FLAVOR_lx2160aqds) && !defined(PLATFORM_FLAVOR_lx2160ardb) 63 register_phys_mem_pgdir(MEM_AREA_IO_SEC, GIC_BASE, CORE_MMU_PGDIR_SIZE); 64 #endif 65 66 #if defined(PLATFORM_FLAVOR_lx2160ardb) || defined(PLATFORM_FLAVOR_lx2160aqds) 67 register_ddr(CFG_DRAM0_BASE, (CFG_TZDRAM_START - CFG_DRAM0_BASE)); 68 #ifdef CFG_DRAM1_BASE 69 register_ddr(CFG_DRAM1_BASE, CFG_DRAM1_SIZE); 70 #endif 71 #endif 72 #ifdef DCFG_BASE 73 register_phys_mem_pgdir(MEM_AREA_IO_NSEC, DCFG_BASE, CORE_MMU_PGDIR_SIZE); 74 #endif 75 76 #ifdef CFG_ARM32_core 77 void plat_primary_init_early(void) 78 { 79 vaddr_t addr; 80 81 #if defined(CFG_BOOT_SECONDARY_REQUEST) 82 /* set secondary entry address */ 83 io_write32(DCFG_BASE + DCFG_SCRATCHRW1, 84 __compiler_bswap32(TEE_LOAD_ADDR)); 85 86 /* release secondary cores */ 87 io_write32(DCFG_BASE + DCFG_CCSR_BRR /* cpu1 */, 88 __compiler_bswap32(0x1 << 1)); 89 dsb(); 90 sev(); 91 #endif 92 93 /* configure CSU */ 94 95 /* first grant all peripherals */ 96 for (addr = CSU_BASE + CSU_CSL_START; 97 addr != CSU_BASE + CSU_CSL_END; 98 addr += 4) 99 io_write32(addr, __compiler_bswap32(CSU_ACCESS_ALL)); 100 101 /* restrict key preipherals from NS */ 102 io_write32(CSU_BASE + CSU_CSL30, 103 __compiler_bswap32(CSU_ACCESS_SEC_ONLY)); 104 io_write32(CSU_BASE + CSU_CSL37, 105 __compiler_bswap32(CSU_ACCESS_SEC_ONLY)); 106 107 /* lock the settings */ 108 for (addr = CSU_BASE + CSU_CSL_START; 109 addr != CSU_BASE + CSU_CSL_END; 110 addr += 4) 111 io_setbits32(addr, 112 __compiler_bswap32(CSU_SETTING_LOCK)); 113 } 114 #endif 115 116 void console_init(void) 117 { 118 #ifdef CFG_PL011 119 /* 120 * Everything for uart driver initialization is done in bootloader. 121 * So not reinitializing console. 122 */ 123 pl011_init(&console_data, CONSOLE_UART_BASE, 0, 0); 124 #else 125 ns16550_init(&console_data, CONSOLE_UART_BASE, IO_WIDTH_U8, 0); 126 #endif 127 register_serial_console(&console_data.chip); 128 } 129 130 #if defined(PLATFORM_FLAVOR_lx2160aqds) || defined(PLATFORM_FLAVOR_lx2160ardb) 131 static TEE_Result get_gic_base_addr_from_dt(paddr_t *gic_addr) 132 { 133 paddr_t paddr = 0; 134 size_t size = 0; 135 136 void *fdt = get_embedded_dt(); 137 int gic_offset = 0; 138 139 gic_offset = fdt_path_offset(fdt, "/soc/interrupt-controller@6000000"); 140 141 if (gic_offset < 0) 142 gic_offset = fdt_path_offset(fdt, 143 "/interrupt-controller@6000000"); 144 145 if (gic_offset > 0) { 146 paddr = _fdt_reg_base_address(fdt, gic_offset); 147 if (paddr == DT_INFO_INVALID_REG) { 148 EMSG("GIC: Unable to get base addr from DT"); 149 return TEE_ERROR_ITEM_NOT_FOUND; 150 } 151 152 size = _fdt_reg_size(fdt, gic_offset); 153 if (size == DT_INFO_INVALID_REG_SIZE) { 154 EMSG("GIC: Unable to get size of base addr from DT"); 155 return TEE_ERROR_ITEM_NOT_FOUND; 156 } 157 } else { 158 EMSG("Unable to get gic offset node"); 159 return TEE_ERROR_ITEM_NOT_FOUND; 160 } 161 162 /* make entry in page table */ 163 if (!core_mmu_add_mapping(MEM_AREA_IO_SEC, paddr, size)) { 164 EMSG("GIC controller base MMU PA mapping failure"); 165 return TEE_ERROR_GENERIC; 166 } 167 168 *gic_addr = paddr; 169 return TEE_SUCCESS; 170 } 171 #endif 172 173 #define SVR_MINOR_MASK 0xF 174 175 static void get_gic_offset(uint32_t *offsetc, uint32_t *offsetd) 176 { 177 #ifdef PLATFORM_FLAVOR_ls1043ardb 178 vaddr_t addr = 0; 179 uint32_t rev = 0; 180 181 addr = (vaddr_t)phys_to_virt(DCFG_BASE + DCFG_SVR_OFFSET, 182 MEM_AREA_IO_NSEC, 1); 183 if (!addr) { 184 EMSG("Failed to get virtual address for SVR register"); 185 panic(); 186 } 187 188 rev = get_be32((void *)addr); 189 190 if ((rev & SVR_MINOR_MASK) == 1) { 191 *offsetc = GICC_OFFSET_REV1_1; 192 *offsetd = GICD_OFFSET_REV1_1; 193 } else { 194 *offsetc = GICC_OFFSET_REV1; 195 *offsetd = GICD_OFFSET_REV1; 196 } 197 #else 198 *offsetc = GICC_OFFSET; 199 *offsetd = GICD_OFFSET; 200 #endif 201 } 202 203 void main_init_gic(void) 204 { 205 paddr_t gic_base = 0; 206 uint32_t gicc_offset = 0; 207 uint32_t gicd_offset = 0; 208 209 #if defined(PLATFORM_FLAVOR_lx2160aqds) || defined(PLATFORM_FLAVOR_lx2160ardb) 210 if (get_gic_base_addr_from_dt(&gic_base)) 211 EMSG("Failed to get GIC base addr from DT"); 212 #else 213 gic_base = GIC_BASE; 214 #endif 215 get_gic_offset(&gicc_offset, &gicd_offset); 216 217 #if defined(CFG_WITH_ARM_TRUSTED_FW) 218 /* On ARMv8, GIC configuration is initialized in ARM-TF */ 219 gic_init_base_addr(&gic_data, gic_base + gicc_offset, 220 gic_base + gicd_offset); 221 #else 222 /* Initialize GIC */ 223 gic_init(&gic_data, gic_base + gicc_offset, gic_base + gicd_offset); 224 #endif 225 itr_init(&gic_data.chip); 226 } 227 228 void main_secondary_init_gic(void) 229 { 230 gic_cpu_init(&gic_data); 231 } 232