| // SPDX-License-Identifier: BSD-2-Clause |
| /* |
| * Copyright (c) 2014-2016, STMicroelectronics International N.V. |
| */ |
| |
| #include <arm32.h> |
| #include <console.h> |
| #include <drivers/gic.h> |
| #include <drivers/stih_asc.h> |
| #include <io.h> |
| #include <kernel/generic_boot.h> |
| #include <kernel/interrupt.h> |
| #include <kernel/misc.h> |
| #include <kernel/panic.h> |
| #include <kernel/pm_stubs.h> |
| #include <kernel/tz_ssvce_pl310.h> |
| #include <mm/core_memprot.h> |
| #include <mm/core_mmu.h> |
| #include <platform_config.h> |
| #include <stdint.h> |
| #include <tee/entry_fast.h> |
| #include <tee/entry_std.h> |
| #include <trace.h> |
| #include <util.h> |
| |
| register_phys_mem_pgdir(MEM_AREA_IO_SEC, CPU_IOMEM_BASE, CPU_IOMEM_SIZE); |
| register_phys_mem_pgdir(MEM_AREA_IO_SEC, RNG_BASE, RNG_SIZE); |
| register_phys_mem_pgdir(MEM_AREA_IO_NSEC, UART_CONSOLE_BASE, STIH_ASC_REG_SIZE); |
| |
| #ifdef DRAM0_BASE |
| register_ddr(DRAM0_BASE, DRAM0_SIZE); |
| #endif |
| #ifdef DRAM1_BASE |
| register_ddr(DRAM1_BASE, DRAM1_SIZE); |
| #endif |
| |
| static struct gic_data gic_data; |
| static struct stih_asc_pd console_data; |
| |
| #if defined(PLATFORM_FLAVOR_b2260) |
| static bool ns_resources_ready(void) |
| { |
| return true; |
| } |
| #else |
| /* some nonsecure resource might not be ready (uart) */ |
| static int boot_is_completed; |
| static bool ns_resources_ready(void) |
| { |
| return !!boot_is_completed; |
| } |
| |
| /* Overriding the default __weak tee_entry_std() */ |
| uint32_t tee_entry_std(struct optee_msg_arg *arg, uint32_t num_params) |
| { |
| boot_is_completed = 1; |
| |
| return __tee_entry_std(arg, num_params); |
| } |
| #endif |
| |
| static const struct thread_handlers handlers = { |
| .cpu_on = pm_panic, |
| .cpu_off = pm_panic, |
| .cpu_suspend = pm_panic, |
| .cpu_resume = pm_panic, |
| .system_off = pm_panic, |
| .system_reset = pm_panic, |
| }; |
| |
| const struct thread_handlers *generic_boot_get_handlers(void) |
| { |
| return &handlers; |
| } |
| |
| void console_init(void) |
| { |
| stih_asc_init(&console_data, UART_CONSOLE_BASE); |
| } |
| |
| void console_putc(int ch) |
| { |
| |
| if (ns_resources_ready()) { |
| struct serial_chip *cons = &console_data.chip; |
| |
| if (ch == '\n') |
| cons->ops->putc(cons, '\r'); |
| cons->ops->putc(cons, ch); |
| } |
| } |
| |
| void console_flush(void) |
| { |
| if (ns_resources_ready()) { |
| struct serial_chip *cons = &console_data.chip; |
| |
| cons->ops->flush(cons); |
| } |
| } |
| |
| vaddr_t pl310_base(void) |
| { |
| static void *va; |
| |
| if (cpu_mmu_enabled()) { |
| if (!va) |
| va = phys_to_virt(PL310_BASE, MEM_AREA_IO_SEC); |
| return (vaddr_t)va; |
| } |
| return PL310_BASE; |
| } |
| |
| void arm_cl2_config(vaddr_t pl310) |
| { |
| /* pl310 off */ |
| io_write32(pl310 + PL310_CTRL, 0); |
| |
| /* config PL310 */ |
| io_write32(pl310 + PL310_TAG_RAM_CTRL, PL310_TAG_RAM_CTRL_INIT); |
| io_write32(pl310 + PL310_DATA_RAM_CTRL, PL310_DATA_RAM_CTRL_INIT); |
| io_write32(pl310 + PL310_AUX_CTRL, PL310_AUX_CTRL_INIT); |
| io_write32(pl310 + PL310_PREFETCH_CTRL, PL310_PREFETCH_CTRL_INIT); |
| io_write32(pl310 + PL310_POWER_CTRL, PL310_POWER_CTRL_INIT); |
| |
| /* invalidate all pl310 cache ways */ |
| arm_cl2_invbyway(pl310); |
| } |
| |
| void plat_primary_init_early(void) |
| { |
| int i; |
| |
| assert(!cpu_mmu_enabled()); |
| |
| io_write32(SCU_BASE + SCU_SAC, SCU_SAC_INIT); |
| io_write32(SCU_BASE + SCU_NSAC, SCU_NSAC_INIT); |
| io_write32(SCU_BASE + SCU_FILT_EA, CPU_PORT_FILT_END); |
| io_write32(SCU_BASE + SCU_FILT_SA, CPU_PORT_FILT_START); |
| io_write32(SCU_BASE + SCU_CTRL, SCU_CTRL_INIT); |
| |
| io_write32(pl310_base() + PL310_ADDR_FILT_END, CPU_PORT_FILT_END); |
| io_write32(pl310_base() + PL310_ADDR_FILT_START, |
| CPU_PORT_FILT_START | PL310_CTRL_ENABLE_BIT); |
| |
| /* TODO: gic_init scan fails, pre-init all SPIs are nonsecure */ |
| for (i = 0; i < (31 * 4); i += 4) |
| io_write32(GIC_DIST_BASE + GIC_DIST_ISR1 + i, 0xFFFFFFFF); |
| } |
| |
| void main_init_gic(void) |
| { |
| vaddr_t gicc_base; |
| vaddr_t gicd_base; |
| |
| gicc_base = (vaddr_t)phys_to_virt(GIC_CPU_BASE, MEM_AREA_IO_SEC); |
| gicd_base = (vaddr_t)phys_to_virt(GIC_DIST_BASE, MEM_AREA_IO_SEC); |
| |
| if (!gicc_base || !gicd_base) |
| panic(); |
| |
| gic_init(&gic_data, gicc_base, gicd_base); |
| itr_init(&gic_data.chip); |
| } |
| |
| void main_secondary_init_gic(void) |
| { |
| gic_cpu_init(&gic_data); |
| } |
| |
| void itr_core_handler(void) |
| { |
| gic_it_handle(&gic_data); |
| } |