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 #ifdef CFG_PL011 54 static struct pl011_data console_data; 55 #else 56 static struct ns16550_data console_data; 57 #endif 58 59 register_phys_mem_pgdir(MEM_AREA_IO_NSEC, CONSOLE_UART_BASE, 60 CORE_MMU_PGDIR_SIZE); 61 #if !defined(PLATFORM_FLAVOR_lx2160aqds) && !defined(PLATFORM_FLAVOR_lx2160ardb) 62 register_phys_mem_pgdir(MEM_AREA_IO_SEC, GIC_BASE, CORE_MMU_PGDIR_SIZE); 63 #endif 64 65 #if defined(PLATFORM_FLAVOR_lx2160ardb) || defined(PLATFORM_FLAVOR_lx2160aqds) 66 register_ddr(CFG_DRAM0_BASE, (CFG_TZDRAM_START - CFG_DRAM0_BASE)); 67 #ifdef CFG_DRAM1_BASE 68 register_ddr(CFG_DRAM1_BASE, CFG_DRAM1_SIZE); 69 #endif 70 #endif 71 #ifdef DCFG_BASE 72 register_phys_mem_pgdir(MEM_AREA_IO_NSEC, DCFG_BASE, CORE_MMU_PGDIR_SIZE); 73 #endif 74 75 #ifdef CFG_ARM32_core 76 void plat_primary_init_early(void) 77 { 78 vaddr_t addr; 79 80 #if defined(CFG_BOOT_SECONDARY_REQUEST) 81 /* set secondary entry address */ 82 io_write32(DCFG_BASE + DCFG_SCRATCHRW1, 83 __compiler_bswap32(TEE_LOAD_ADDR)); 84 85 /* release secondary cores */ 86 io_write32(DCFG_BASE + DCFG_CCSR_BRR /* cpu1 */, 87 __compiler_bswap32(0x1 << 1)); 88 dsb(); 89 sev(); 90 #endif 91 92 /* configure CSU */ 93 94 /* first grant all peripherals */ 95 for (addr = CSU_BASE + CSU_CSL_START; 96 addr != CSU_BASE + CSU_CSL_END; 97 addr += 4) 98 io_write32(addr, __compiler_bswap32(CSU_ACCESS_ALL)); 99 100 /* restrict key preipherals from NS */ 101 io_write32(CSU_BASE + CSU_CSL30, 102 __compiler_bswap32(CSU_ACCESS_SEC_ONLY)); 103 io_write32(CSU_BASE + CSU_CSL37, 104 __compiler_bswap32(CSU_ACCESS_SEC_ONLY)); 105 106 /* lock the settings */ 107 for (addr = CSU_BASE + CSU_CSL_START; 108 addr != CSU_BASE + CSU_CSL_END; 109 addr += 4) 110 io_setbits32(addr, 111 __compiler_bswap32(CSU_SETTING_LOCK)); 112 } 113 #endif 114 115 void plat_console_init(void) 116 { 117 #ifdef CFG_PL011 118 /* 119 * Everything for uart driver initialization is done in bootloader. 120 * So not reinitializing console. 121 */ 122 pl011_init(&console_data, CONSOLE_UART_BASE, 0, 0); 123 #else 124 ns16550_init(&console_data, CONSOLE_UART_BASE, IO_WIDTH_U8, 0); 125 #endif 126 register_serial_console(&console_data.chip); 127 } 128 129 #if defined(PLATFORM_FLAVOR_lx2160aqds) || defined(PLATFORM_FLAVOR_lx2160ardb) 130 static TEE_Result get_gic_base_addr_from_dt(paddr_t *gic_addr) 131 { 132 paddr_t paddr = 0; 133 size_t size = 0; 134 135 void *fdt = get_embedded_dt(); 136 int gic_offset = 0; 137 138 gic_offset = fdt_path_offset(fdt, "/soc/interrupt-controller@6000000"); 139 140 if (gic_offset < 0) 141 gic_offset = fdt_path_offset(fdt, 142 "/interrupt-controller@6000000"); 143 144 if (gic_offset < 0) { 145 EMSG("Unable to get gic offset node"); 146 return TEE_ERROR_ITEM_NOT_FOUND; 147 } 148 149 if (fdt_reg_info(fdt, gic_offset, &paddr, &size)) { 150 EMSG("GIC: Unable to get base addr or size from DT"); 151 return TEE_ERROR_ITEM_NOT_FOUND; 152 } 153 154 /* make entry in page table */ 155 if (!core_mmu_add_mapping(MEM_AREA_IO_SEC, paddr, size)) { 156 EMSG("GIC controller base MMU PA mapping failure"); 157 return TEE_ERROR_GENERIC; 158 } 159 160 *gic_addr = paddr; 161 return TEE_SUCCESS; 162 } 163 #endif 164 165 #define SVR_MINOR_MASK 0xF 166 167 static void get_gic_offset(uint32_t *offsetc, uint32_t *offsetd) 168 { 169 #ifdef PLATFORM_FLAVOR_ls1043ardb 170 vaddr_t addr = 0; 171 uint32_t rev = 0; 172 173 addr = (vaddr_t)phys_to_virt(DCFG_BASE + DCFG_SVR_OFFSET, 174 MEM_AREA_IO_NSEC, 1); 175 if (!addr) { 176 EMSG("Failed to get virtual address for SVR register"); 177 panic(); 178 } 179 180 rev = get_be32((void *)addr); 181 182 if ((rev & SVR_MINOR_MASK) == 1) { 183 *offsetc = GICC_OFFSET_REV1_1; 184 *offsetd = GICD_OFFSET_REV1_1; 185 } else { 186 *offsetc = GICC_OFFSET_REV1; 187 *offsetd = GICD_OFFSET_REV1; 188 } 189 #else 190 *offsetc = GICC_OFFSET; 191 *offsetd = GICD_OFFSET; 192 #endif 193 } 194 195 void boot_primary_init_intc(void) 196 { 197 paddr_t gic_base = 0; 198 uint32_t gicc_offset = 0; 199 uint32_t gicd_offset = 0; 200 201 #if defined(PLATFORM_FLAVOR_lx2160aqds) || defined(PLATFORM_FLAVOR_lx2160ardb) 202 if (get_gic_base_addr_from_dt(&gic_base)) 203 EMSG("Failed to get GIC base addr from DT"); 204 #else 205 gic_base = GIC_BASE; 206 #endif 207 get_gic_offset(&gicc_offset, &gicd_offset); 208 gic_init(gic_base + gicc_offset, gic_base + gicd_offset); 209 } 210 211 void boot_secondary_init_intc(void) 212 { 213 gic_init_per_cpu(); 214 } 215