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 73 #ifdef CFG_ARM32_core 74 void plat_primary_init_early(void) 75 { 76 vaddr_t addr; 77 78 #if defined(CFG_BOOT_SECONDARY_REQUEST) 79 /* set secondary entry address */ 80 io_write32(DCFG_BASE + DCFG_SCRATCHRW1, 81 __compiler_bswap32(TEE_LOAD_ADDR)); 82 83 /* release secondary cores */ 84 io_write32(DCFG_BASE + DCFG_CCSR_BRR /* cpu1 */, 85 __compiler_bswap32(0x1 << 1)); 86 dsb(); 87 sev(); 88 #endif 89 90 /* configure CSU */ 91 92 /* first grant all peripherals */ 93 for (addr = CSU_BASE + CSU_CSL_START; 94 addr != CSU_BASE + CSU_CSL_END; 95 addr += 4) 96 io_write32(addr, __compiler_bswap32(CSU_ACCESS_ALL)); 97 98 /* restrict key preipherals from NS */ 99 io_write32(CSU_BASE + CSU_CSL30, 100 __compiler_bswap32(CSU_ACCESS_SEC_ONLY)); 101 io_write32(CSU_BASE + CSU_CSL37, 102 __compiler_bswap32(CSU_ACCESS_SEC_ONLY)); 103 104 /* lock the settings */ 105 for (addr = CSU_BASE + CSU_CSL_START; 106 addr != CSU_BASE + CSU_CSL_END; 107 addr += 4) 108 io_setbits32(addr, 109 __compiler_bswap32(CSU_SETTING_LOCK)); 110 } 111 #endif 112 113 void console_init(void) 114 { 115 #ifdef CFG_PL011 116 /* 117 * Everything for uart driver initialization is done in bootloader. 118 * So not reinitializing console. 119 */ 120 pl011_init(&console_data, CONSOLE_UART_BASE, 0, 0); 121 #else 122 ns16550_init(&console_data, CONSOLE_UART_BASE, IO_WIDTH_U8, 0); 123 #endif 124 register_serial_console(&console_data.chip); 125 } 126 127 #if defined(PLATFORM_FLAVOR_lx2160aqds) || defined(PLATFORM_FLAVOR_lx2160ardb) 128 static TEE_Result get_gic_base_addr_from_dt(paddr_t *gic_addr) 129 { 130 paddr_t paddr = 0; 131 ssize_t size = 0; 132 133 void *fdt = get_embedded_dt(); 134 int gic_offset = 0; 135 136 gic_offset = fdt_path_offset(fdt, "/soc/interrupt-controller@6000000"); 137 138 if (gic_offset < 0) 139 gic_offset = fdt_path_offset(fdt, 140 "/interrupt-controller@6000000"); 141 142 if (gic_offset > 0) { 143 paddr = _fdt_reg_base_address(fdt, gic_offset); 144 if (paddr == DT_INFO_INVALID_REG) { 145 EMSG("GIC: Unable to get base addr from DT"); 146 return TEE_ERROR_ITEM_NOT_FOUND; 147 } 148 149 size = _fdt_reg_size(fdt, gic_offset); 150 if (size < 0) { 151 EMSG("GIC: Unable to get size of base addr from DT"); 152 return TEE_ERROR_ITEM_NOT_FOUND; 153 } 154 } else { 155 EMSG("Unable to get gic offset node"); 156 return TEE_ERROR_ITEM_NOT_FOUND; 157 } 158 159 /* make entry in page table */ 160 if (!core_mmu_add_mapping(MEM_AREA_IO_SEC, paddr, size)) { 161 EMSG("GIC controller base MMU PA mapping failure"); 162 return TEE_ERROR_GENERIC; 163 } 164 165 *gic_addr = paddr; 166 return TEE_SUCCESS; 167 } 168 #endif 169 170 void main_init_gic(void) 171 { 172 vaddr_t gicc_base = 0; 173 vaddr_t gicd_base = 0; 174 175 paddr_t gic_base = 0; 176 uint32_t gicc_offset = 0; 177 uint32_t gicd_offset = 0; 178 179 #if defined(PLATFORM_FLAVOR_lx2160aqds) || defined(PLATFORM_FLAVOR_lx2160ardb) 180 if (get_gic_base_addr_from_dt(&gic_base)) 181 EMSG("Failed to get GIC base addr from DT"); 182 #else 183 gic_base = GIC_BASE; 184 gicc_offset = GICC_OFFSET; 185 gicd_offset = GICD_OFFSET; 186 #endif 187 188 gicc_base = (vaddr_t)phys_to_virt(gic_base + gicc_offset, 189 MEM_AREA_IO_SEC); 190 gicd_base = (vaddr_t)phys_to_virt(gic_base + gicd_offset, 191 MEM_AREA_IO_SEC); 192 if (!gicc_base || !gicd_base) 193 panic(); 194 195 #if defined(CFG_WITH_ARM_TRUSTED_FW) 196 /* On ARMv8, GIC configuration is initialized in ARM-TF */ 197 gic_init_base_addr(&gic_data, gicc_base, gicd_base); 198 #else 199 /* Initialize GIC */ 200 gic_init(&gic_data, gicc_base, gicd_base); 201 #endif 202 itr_init(&gic_data.chip); 203 } 204 205 void main_secondary_init_gic(void) 206 { 207 gic_cpu_init(&gic_data); 208 } 209