xref: /optee_os/core/arch/arm/plat-stm/main.c (revision 55ab8f06a831946a49717446cd2e4495a2b5d659)
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