11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2abe38974SJens Wiklander /*
39dc1c9edSEtienne Carriere * Copyright (c) 2014-2016, STMicroelectronics International N.V.
4abe38974SJens Wiklander */
52e5831a9SPascal Brand
69dc1c9edSEtienne Carriere #include <arm32.h>
72e5831a9SPascal Brand #include <console.h>
805efe1e1SEtienne Carriere #include <drivers/gic.h>
939e661bcSEtienne Carriere #include <drivers/stih_asc.h>
109dc1c9edSEtienne Carriere #include <io.h>
1165401337SJens Wiklander #include <kernel/boot.h>
129dc1c9edSEtienne Carriere #include <kernel/misc.h>
13abe38974SJens Wiklander #include <kernel/panic.h>
14aaf56f28SJens Wiklander #include <kernel/tz_ssvce_pl310.h>
15c6c3cd92SJens Wiklander #include <mm/core_memprot.h>
16e9f46c74SJens Wiklander #include <mm/core_mmu.h>
17abe38974SJens Wiklander #include <platform_config.h>
182e5831a9SPascal Brand #include <stdint.h>
195c781c55SJens Wiklander #include <tee/entry_fast.h>
20e9f46c74SJens Wiklander #include <tee/entry_std.h>
219dc1c9edSEtienne Carriere #include <trace.h>
228cd89706SEtienne Carriere #include <util.h>
23abe38974SJens Wiklander
24a5e82dc7SJerome Forissier register_phys_mem_pgdir(MEM_AREA_IO_SEC, CPU_IOMEM_BASE, CPU_IOMEM_SIZE);
25a5e82dc7SJerome Forissier register_phys_mem_pgdir(MEM_AREA_IO_SEC, RNG_BASE, RNG_SIZE);
26a5e82dc7SJerome Forissier register_phys_mem_pgdir(MEM_AREA_IO_NSEC, UART_CONSOLE_BASE, STIH_ASC_REG_SIZE);
279dc1c9edSEtienne Carriere
28ae9fdf98SEtienne Carriere #ifdef DRAM0_BASE
29c8a8dd8fSEtienne Carriere register_ddr(DRAM0_BASE, DRAM0_SIZE);
30ae9fdf98SEtienne Carriere #endif
31ae9fdf98SEtienne Carriere #ifdef DRAM1_BASE
32c8a8dd8fSEtienne Carriere register_ddr(DRAM1_BASE, DRAM1_SIZE);
33ae9fdf98SEtienne Carriere #endif
34ae9fdf98SEtienne Carriere
3523660121SJerome Forissier static struct stih_asc_pd console_data;
360cb71d15SEtienne Carriere
379dc1c9edSEtienne Carriere #if defined(PLATFORM_FLAVOR_b2260)
ns_resources_ready(void)389dc1c9edSEtienne Carriere static bool ns_resources_ready(void)
399dc1c9edSEtienne Carriere {
409dc1c9edSEtienne Carriere return true;
419dc1c9edSEtienne Carriere }
429dc1c9edSEtienne Carriere #else
439dc1c9edSEtienne Carriere /* some nonsecure resource might not be ready (uart) */
4423660121SJerome Forissier static int boot_is_completed;
ns_resources_ready(void)459dc1c9edSEtienne Carriere static bool ns_resources_ready(void)
469dc1c9edSEtienne Carriere {
479dc1c9edSEtienne Carriere return !!boot_is_completed;
489dc1c9edSEtienne Carriere }
492dd2ca5fSJens Wiklander
502dd2ca5fSJens Wiklander /* Overriding the default __weak tee_entry_std() */
tee_entry_std(struct optee_msg_arg * arg,uint32_t num_params)51453d8327SJens Wiklander TEE_Result tee_entry_std(struct optee_msg_arg *arg, uint32_t num_params)
529dc1c9edSEtienne Carriere {
539dc1c9edSEtienne Carriere boot_is_completed = 1;
542dd2ca5fSJens Wiklander
552dd2ca5fSJens Wiklander return __tee_entry_std(arg, num_params);
569dc1c9edSEtienne Carriere }
579dc1c9edSEtienne Carriere #endif
589dc1c9edSEtienne Carriere
plat_console_init(void)59*55ab8f06SAlvin Chang void plat_console_init(void)
606ef34537SSY Chiu {
610cb71d15SEtienne Carriere stih_asc_init(&console_data, UART_CONSOLE_BASE);
626ef34537SSY Chiu }
636ef34537SSY Chiu
console_putc(int ch)64abe38974SJens Wiklander void console_putc(int ch)
65abe38974SJens Wiklander {
660cb71d15SEtienne Carriere
679dc1c9edSEtienne Carriere if (ns_resources_ready()) {
680cb71d15SEtienne Carriere struct serial_chip *cons = &console_data.chip;
6939e661bcSEtienne Carriere
709dc1c9edSEtienne Carriere if (ch == '\n')
710cb71d15SEtienne Carriere cons->ops->putc(cons, '\r');
720cb71d15SEtienne Carriere cons->ops->putc(cons, ch);
73abe38974SJens Wiklander }
749dc1c9edSEtienne Carriere }
75abe38974SJens Wiklander
console_flush(void)76abe38974SJens Wiklander void console_flush(void)
77abe38974SJens Wiklander {
780cb71d15SEtienne Carriere if (ns_resources_ready()) {
790cb71d15SEtienne Carriere struct serial_chip *cons = &console_data.chip;
800cb71d15SEtienne Carriere
817b84e23dSJerome Forissier if (cons->ops->flush)
820cb71d15SEtienne Carriere cons->ops->flush(cons);
830cb71d15SEtienne Carriere }
84abe38974SJens Wiklander }
85aaf56f28SJens Wiklander
pl310_base(void)86aaf56f28SJens Wiklander vaddr_t pl310_base(void)
87aaf56f28SJens Wiklander {
8823660121SJerome Forissier static void *va;
89aaf56f28SJens Wiklander
90aaf56f28SJens Wiklander if (cpu_mmu_enabled()) {
91aaf56f28SJens Wiklander if (!va)
92c2e4eb43SAnton Rybakov va = phys_to_virt(PL310_BASE, MEM_AREA_IO_SEC, 1);
93aaf56f28SJens Wiklander return (vaddr_t)va;
94aaf56f28SJens Wiklander }
95aaf56f28SJens Wiklander return PL310_BASE;
96aaf56f28SJens Wiklander }
979dc1c9edSEtienne Carriere
arm_cl2_config(vaddr_t pl310)989dc1c9edSEtienne Carriere void arm_cl2_config(vaddr_t pl310)
999dc1c9edSEtienne Carriere {
1009dc1c9edSEtienne Carriere /* pl310 off */
10179f948c6SEtienne Carriere io_write32(pl310 + PL310_CTRL, 0);
1029dc1c9edSEtienne Carriere
1038cd89706SEtienne Carriere /* config PL310 */
10479f948c6SEtienne Carriere io_write32(pl310 + PL310_TAG_RAM_CTRL, PL310_TAG_RAM_CTRL_INIT);
10579f948c6SEtienne Carriere io_write32(pl310 + PL310_DATA_RAM_CTRL, PL310_DATA_RAM_CTRL_INIT);
10679f948c6SEtienne Carriere io_write32(pl310 + PL310_AUX_CTRL, PL310_AUX_CTRL_INIT);
10779f948c6SEtienne Carriere io_write32(pl310 + PL310_PREFETCH_CTRL, PL310_PREFETCH_CTRL_INIT);
10879f948c6SEtienne Carriere io_write32(pl310 + PL310_POWER_CTRL, PL310_POWER_CTRL_INIT);
1099dc1c9edSEtienne Carriere
1109dc1c9edSEtienne Carriere /* invalidate all pl310 cache ways */
1119dc1c9edSEtienne Carriere arm_cl2_invbyway(pl310);
1129dc1c9edSEtienne Carriere }
1139dc1c9edSEtienne Carriere
plat_primary_init_early(void)114665fa256SJens Wiklander void plat_primary_init_early(void)
1159dc1c9edSEtienne Carriere {
1169dc1c9edSEtienne Carriere int i;
1179dc1c9edSEtienne Carriere
1189dc1c9edSEtienne Carriere assert(!cpu_mmu_enabled());
1199dc1c9edSEtienne Carriere
12079f948c6SEtienne Carriere io_write32(SCU_BASE + SCU_SAC, SCU_SAC_INIT);
12179f948c6SEtienne Carriere io_write32(SCU_BASE + SCU_NSAC, SCU_NSAC_INIT);
12279f948c6SEtienne Carriere io_write32(SCU_BASE + SCU_FILT_EA, CPU_PORT_FILT_END);
12379f948c6SEtienne Carriere io_write32(SCU_BASE + SCU_FILT_SA, CPU_PORT_FILT_START);
12479f948c6SEtienne Carriere io_write32(SCU_BASE + SCU_CTRL, SCU_CTRL_INIT);
1259dc1c9edSEtienne Carriere
12679f948c6SEtienne Carriere io_write32(pl310_base() + PL310_ADDR_FILT_END, CPU_PORT_FILT_END);
12779f948c6SEtienne Carriere io_write32(pl310_base() + PL310_ADDR_FILT_START,
12879f948c6SEtienne Carriere CPU_PORT_FILT_START | PL310_CTRL_ENABLE_BIT);
1299dc1c9edSEtienne Carriere
13005efe1e1SEtienne Carriere /* TODO: gic_init scan fails, pre-init all SPIs are nonsecure */
1319dc1c9edSEtienne Carriere for (i = 0; i < (31 * 4); i += 4)
13279f948c6SEtienne Carriere io_write32(GIC_DIST_BASE + GIC_DIST_ISR1 + i, 0xFFFFFFFF);
1339dc1c9edSEtienne Carriere }
13405efe1e1SEtienne Carriere
boot_primary_init_intc(void)135df913c6dSAlvin Chang void boot_primary_init_intc(void)
13605efe1e1SEtienne Carriere {
13767e55c51SEtienne Carriere gic_init(GIC_CPU_BASE, GIC_DIST_BASE);
13805efe1e1SEtienne Carriere }
13905efe1e1SEtienne Carriere
boot_secondary_init_intc(void)1408aae4669SAlvin Chang void boot_secondary_init_intc(void)
14105efe1e1SEtienne Carriere {
142b6ffde32SJens Wiklander gic_init_per_cpu();
14305efe1e1SEtienne Carriere }
144