xref: /rk3399_ARM-atf/plat/socionext/synquacer/sq_bl31_setup.c (revision 72ac9810449b32ac321b85f495e3753ac955ca4d)
1c35d59a3SSumit Garg /*
2*92752355SSalman Nabi  * Copyright (c) 2018-2024, ARM Limited and Contributors. All rights reserved.
3c35d59a3SSumit Garg  *
4c35d59a3SSumit Garg  * SPDX-License-Identifier: BSD-3-Clause
5c35d59a3SSumit Garg  */
6c35d59a3SSumit Garg 
709d40e0eSAntonio Nino Diaz #include <assert.h>
809d40e0eSAntonio Nino Diaz 
909d40e0eSAntonio Nino Diaz #include <platform_def.h>
1009d40e0eSAntonio Nino Diaz 
11c35d59a3SSumit Garg #include <arch.h>
12c35d59a3SSumit Garg #include <arch_helpers.h>
1309d40e0eSAntonio Nino Diaz #include <common/bl_common.h>
1409d40e0eSAntonio Nino Diaz #include <common/debug.h>
1509d40e0eSAntonio Nino Diaz #include <drivers/arm/pl011.h>
1609d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
170eb275c9SSumit Garg #include <sq_common.h>
18c35d59a3SSumit Garg 
19f695e1e0SAndre Przywara static console_t console;
205e5cfc21SSumit Garg static entry_point_info_t bl32_image_ep_info;
215e5cfc21SSumit Garg static entry_point_info_t bl33_image_ep_info;
225e5cfc21SSumit Garg 
23434454a2SArd Biesheuvel IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_START__, SPM_SHIM_EXCEPTIONS_START);
24434454a2SArd Biesheuvel IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_END__,   SPM_SHIM_EXCEPTIONS_END);
25434454a2SArd Biesheuvel IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_LMA__,   SPM_SHIM_EXCEPTIONS_LMA);
26434454a2SArd Biesheuvel 
plat_get_syscnt_freq2(void)274d4911d7SMasahisa Kojima unsigned int plat_get_syscnt_freq2(void)
284d4911d7SMasahisa Kojima {
294d4911d7SMasahisa Kojima 	unsigned int counter_base_frequency;
304d4911d7SMasahisa Kojima 
314d4911d7SMasahisa Kojima 	/* Read the frequency from Frequency modes table */
324d4911d7SMasahisa Kojima 	counter_base_frequency = mmio_read_32(SQ_SYS_CNTCTL_BASE + CNTFID_OFF);
334d4911d7SMasahisa Kojima 
344d4911d7SMasahisa Kojima 	/* The first entry of the frequency modes table must not be 0 */
354d4911d7SMasahisa Kojima 	if (counter_base_frequency == 0)
364d4911d7SMasahisa Kojima 		panic();
374d4911d7SMasahisa Kojima 
384d4911d7SMasahisa Kojima 	return counter_base_frequency;
394d4911d7SMasahisa Kojima }
404d4911d7SMasahisa Kojima 
bl31_plat_get_next_image_ep_info(uint32_t type)415e5cfc21SSumit Garg entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
425e5cfc21SSumit Garg {
435e5cfc21SSumit Garg 	assert(sec_state_is_valid(type));
445e5cfc21SSumit Garg 	return type == NON_SECURE ? &bl33_image_ep_info : &bl32_image_ep_info;
455e5cfc21SSumit Garg }
465e5cfc21SSumit Garg 
4748ab3904SJassi Brar #if !RESET_TO_BL31
bl31_early_platform_setup2(u_register_t arg0,u_register_t arg1,u_register_t arg2,u_register_t arg3)4848ab3904SJassi Brar void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
4948ab3904SJassi Brar 				u_register_t arg2, u_register_t arg3)
5048ab3904SJassi Brar {
5148ab3904SJassi Brar 	void *from_bl2 = (void *) arg0;
5248ab3904SJassi Brar 	bl_params_node_t *bl_params = ((bl_params_t *) from_bl2)->head;
5348ab3904SJassi Brar 
5448ab3904SJassi Brar 	/* Initialize the console to provide early debug support */
5548ab3904SJassi Brar 	(void)console_pl011_register(PLAT_SQ_BOOT_UART_BASE,
5648ab3904SJassi Brar 			       PLAT_SQ_BOOT_UART_CLK_IN_HZ,
5748ab3904SJassi Brar 			       SQ_CONSOLE_BAUDRATE, &console);
5848ab3904SJassi Brar 
5948ab3904SJassi Brar 	console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
6048ab3904SJassi Brar 
6148ab3904SJassi Brar 	/* Initialize power controller before setting up topology */
6248ab3904SJassi Brar 	plat_sq_pwrc_setup();
6348ab3904SJassi Brar 
6448ab3904SJassi Brar 	while (bl_params) {
6548ab3904SJassi Brar 		if (bl_params->image_id == BL32_IMAGE_ID)
6648ab3904SJassi Brar 			bl32_image_ep_info = *bl_params->ep_info;
6748ab3904SJassi Brar 
6848ab3904SJassi Brar 		if (bl_params->image_id == BL33_IMAGE_ID)
6948ab3904SJassi Brar 			bl33_image_ep_info = *bl_params->ep_info;
7048ab3904SJassi Brar 
7148ab3904SJassi Brar 		bl_params = bl_params->next_params_info;
7248ab3904SJassi Brar 	}
7348ab3904SJassi Brar }
7448ab3904SJassi Brar 
7548ab3904SJassi Brar #else
765e5cfc21SSumit Garg /*******************************************************************************
775e5cfc21SSumit Garg  * Gets SPSR for BL32 entry
785e5cfc21SSumit Garg  ******************************************************************************/
sq_get_spsr_for_bl32_entry(void)795e5cfc21SSumit Garg uint32_t sq_get_spsr_for_bl32_entry(void)
805e5cfc21SSumit Garg {
815e5cfc21SSumit Garg 	/*
825e5cfc21SSumit Garg 	 * The Secure Payload Dispatcher service is responsible for
835e5cfc21SSumit Garg 	 * setting the SPSR prior to entry into the BL32 image.
845e5cfc21SSumit Garg 	 */
855e5cfc21SSumit Garg 	return 0;
865e5cfc21SSumit Garg }
875e5cfc21SSumit Garg 
885e5cfc21SSumit Garg /*******************************************************************************
895e5cfc21SSumit Garg  * Gets SPSR for BL33 entry
905e5cfc21SSumit Garg  ******************************************************************************/
sq_get_spsr_for_bl33_entry(void)915e5cfc21SSumit Garg uint32_t sq_get_spsr_for_bl33_entry(void)
925e5cfc21SSumit Garg {
935e5cfc21SSumit Garg 	unsigned long el_status;
945e5cfc21SSumit Garg 	unsigned int mode;
955e5cfc21SSumit Garg 	uint32_t spsr;
965e5cfc21SSumit Garg 
975e5cfc21SSumit Garg 	/* Figure out what mode we enter the non-secure world in */
985e5cfc21SSumit Garg 	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
995e5cfc21SSumit Garg 	el_status &= ID_AA64PFR0_ELX_MASK;
1005e5cfc21SSumit Garg 
1015e5cfc21SSumit Garg 	mode = (el_status) ? MODE_EL2 : MODE_EL1;
1025e5cfc21SSumit Garg 
1035e5cfc21SSumit Garg 	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
1045e5cfc21SSumit Garg 	return spsr;
1055e5cfc21SSumit Garg }
10667b40070SSumit Garg 
bl31_early_platform_setup2(u_register_t arg0,u_register_t arg1,u_register_t arg2,u_register_t arg3)107ce1f43acSAntonio Nino Diaz void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
108ce1f43acSAntonio Nino Diaz 				u_register_t arg2, u_register_t arg3)
109c35d59a3SSumit Garg {
11067b40070SSumit Garg 	/* Initialize the console to provide early debug support */
11167b40070SSumit Garg 	(void)console_pl011_register(PLAT_SQ_BOOT_UART_BASE,
11267b40070SSumit Garg 			       PLAT_SQ_BOOT_UART_CLK_IN_HZ,
11367b40070SSumit Garg 			       SQ_CONSOLE_BAUDRATE, &console);
11467b40070SSumit Garg 
115f695e1e0SAndre Przywara 	console_set_scope(&console, CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME);
11667b40070SSumit Garg 
117c35d59a3SSumit Garg 	/* There are no parameters from BL2 if BL31 is a reset vector */
118ce1f43acSAntonio Nino Diaz 	assert(arg0 == 0U);
119ce1f43acSAntonio Nino Diaz 	assert(arg1 == 0U);
1205e5cfc21SSumit Garg 
1216cb2a397SSumit Garg 	/* Initialize power controller before setting up topology */
1226cb2a397SSumit Garg 	plat_sq_pwrc_setup();
1236cb2a397SSumit Garg 
124e373b6a2SArd Biesheuvel #ifdef SPD_opteed
1256cb2a397SSumit Garg 	struct draminfo di = {0};
1266cb2a397SSumit Garg 
127b67d2029SMasahisa Kojima 	sq_scp_get_draminfo(&di);
1286cb2a397SSumit Garg 
1296cb2a397SSumit Garg 	/*
1306cb2a397SSumit Garg 	 * Check if OP-TEE has been loaded in Secure RAM allocated
1316cb2a397SSumit Garg 	 * from DRAM1 region
1326cb2a397SSumit Garg 	 */
1336cb2a397SSumit Garg 	if ((di.base1 + di.size1) <= BL32_BASE) {
1346cb2a397SSumit Garg 		NOTICE("OP-TEE has been loaded by SCP firmware\n");
1355e5cfc21SSumit Garg 		/* Populate entry point information for BL32 */
1365e5cfc21SSumit Garg 		SET_PARAM_HEAD(&bl32_image_ep_info,
1375e5cfc21SSumit Garg 					PARAM_EP,
1385e5cfc21SSumit Garg 					VERSION_1,
1395e5cfc21SSumit Garg 					0);
1405e5cfc21SSumit Garg 		SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
1415e5cfc21SSumit Garg 		bl32_image_ep_info.pc = BL32_BASE;
1425e5cfc21SSumit Garg 		bl32_image_ep_info.spsr = sq_get_spsr_for_bl32_entry();
1436cb2a397SSumit Garg 	} else {
1446cb2a397SSumit Garg 		NOTICE("OP-TEE has not been loaded by SCP firmware\n");
1456cb2a397SSumit Garg 	}
146e373b6a2SArd Biesheuvel #endif /* SPD_opteed */
1475e5cfc21SSumit Garg 
1485e5cfc21SSumit Garg 	/* Populate entry point information for BL33 */
1495e5cfc21SSumit Garg 	SET_PARAM_HEAD(&bl33_image_ep_info,
1505e5cfc21SSumit Garg 				PARAM_EP,
1515e5cfc21SSumit Garg 				VERSION_1,
1525e5cfc21SSumit Garg 				0);
1535e5cfc21SSumit Garg 	/*
1545e5cfc21SSumit Garg 	 * Tell BL31 where the non-trusted software image
1555e5cfc21SSumit Garg 	 * is located and the entry state information
1565e5cfc21SSumit Garg 	 */
1575e5cfc21SSumit Garg 	bl33_image_ep_info.pc = PRELOADED_BL33_BASE;
1585e5cfc21SSumit Garg 	bl33_image_ep_info.spsr = sq_get_spsr_for_bl33_entry();
1595e5cfc21SSumit Garg 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
160c35d59a3SSumit Garg }
16148ab3904SJassi Brar #endif
162c35d59a3SSumit Garg 
sq_configure_sys_timer(void)1635931fdacSSumit Garg static void sq_configure_sys_timer(void)
1645931fdacSSumit Garg {
1655931fdacSSumit Garg 	unsigned int reg_val;
1664d4911d7SMasahisa Kojima 	unsigned int freq_val = plat_get_syscnt_freq2();
1675931fdacSSumit Garg 
1685931fdacSSumit Garg 	reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT);
1695931fdacSSumit Garg 	reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT);
1705931fdacSSumit Garg 	reg_val |= (1 << CNTACR_RWVT_SHIFT) | (1 << CNTACR_RWPT_SHIFT);
1715931fdacSSumit Garg 	mmio_write_32(SQ_SYS_TIMCTL_BASE +
1725931fdacSSumit Garg 		      CNTACR_BASE(PLAT_SQ_NSTIMER_FRAME_ID), reg_val);
1735931fdacSSumit Garg 
1745931fdacSSumit Garg 	reg_val = (1 << CNTNSAR_NS_SHIFT(PLAT_SQ_NSTIMER_FRAME_ID));
1755931fdacSSumit Garg 	mmio_write_32(SQ_SYS_TIMCTL_BASE + CNTNSAR, reg_val);
1764d4911d7SMasahisa Kojima 
1774d4911d7SMasahisa Kojima 	/* Initialize CNTFRQ register in CNTCTLBase frame */
1784d4911d7SMasahisa Kojima 	mmio_write_32(SQ_SYS_TIMCTL_BASE + CNTCTLBASE_CNTFRQ, freq_val);
1794d4911d7SMasahisa Kojima 
1804d4911d7SMasahisa Kojima 	/*
1814d4911d7SMasahisa Kojima 	 * Initialize CNTFRQ register in Non-secure CNTBase frame.
1824d4911d7SMasahisa Kojima 	 * This is required for SynQuacer, because it does not
1834d4911d7SMasahisa Kojima 	 * follow ARM ARM in that the value updated in CNTFRQ is not
1844d4911d7SMasahisa Kojima 	 * reflected in CNTBASEN_CNTFRQ. Hence update the value manually.
1854d4911d7SMasahisa Kojima 	 */
1864d4911d7SMasahisa Kojima 	mmio_write_32(SQ_SYS_CNT_BASE_NS + CNTBASEN_CNTFRQ, freq_val);
1875931fdacSSumit Garg }
1885931fdacSSumit Garg 
bl31_platform_setup(void)189c35d59a3SSumit Garg void bl31_platform_setup(void)
190c35d59a3SSumit Garg {
1910eb275c9SSumit Garg 	/* Initialize the CCN interconnect */
1920eb275c9SSumit Garg 	plat_sq_interconnect_init();
1930eb275c9SSumit Garg 	plat_sq_interconnect_enter_coherency();
194b529799fSSumit Garg 
195b529799fSSumit Garg 	/* Initialize the GIC driver, cpu and distributor interfaces */
196b529799fSSumit Garg 	sq_gic_driver_init();
197b529799fSSumit Garg 	sq_gic_init();
1985931fdacSSumit Garg 
1995931fdacSSumit Garg 	/* Enable and initialize the System level generic timer */
2005931fdacSSumit Garg 	mmio_write_32(SQ_SYS_CNTCTL_BASE + CNTCR_OFF,
201c9512bcaSAntonio Nino Diaz 			CNTCR_FCREQ(0U) | CNTCR_EN);
2025931fdacSSumit Garg 
2035931fdacSSumit Garg 	/* Allow access to the System counter timer module */
2045931fdacSSumit Garg 	sq_configure_sys_timer();
205c35d59a3SSumit Garg }
206c35d59a3SSumit Garg 
bl31_plat_runtime_setup(void)207c35d59a3SSumit Garg void bl31_plat_runtime_setup(void)
208c35d59a3SSumit Garg {
209cfe19f85SArd Biesheuvel 	struct draminfo *di = (struct draminfo *)(unsigned long)DRAMINFO_BASE;
210cfe19f85SArd Biesheuvel 
211b67d2029SMasahisa Kojima 	sq_scp_get_draminfo(di);
212c35d59a3SSumit Garg }
213c35d59a3SSumit Garg 
bl31_plat_arch_setup(void)214c35d59a3SSumit Garg void bl31_plat_arch_setup(void)
215c35d59a3SSumit Garg {
216434454a2SArd Biesheuvel 	static const mmap_region_t secure_partition_mmap[] = {
2173f3c341aSPaul Beesley #if SPM_MM
218434454a2SArd Biesheuvel 		MAP_REGION_FLAT(PLAT_SPM_BUF_BASE,
219434454a2SArd Biesheuvel 				PLAT_SPM_BUF_SIZE,
220434454a2SArd Biesheuvel 				MT_RW_DATA | MT_SECURE),
221434454a2SArd Biesheuvel 		MAP_REGION_FLAT(PLAT_SQ_SP_PRIV_BASE,
222434454a2SArd Biesheuvel 				PLAT_SQ_SP_PRIV_SIZE,
223434454a2SArd Biesheuvel 				MT_RW_DATA | MT_SECURE),
224434454a2SArd Biesheuvel #endif
22548ab3904SJassi Brar #if !RESET_TO_BL31
22648ab3904SJassi Brar 		MAP_REGION_FLAT(BL2_MAILBOX_BASE,
22748ab3904SJassi Brar 				BL2_MAILBOX_SIZE,
22848ab3904SJassi Brar 				MT_RW | MT_SECURE),
22948ab3904SJassi Brar #endif
230434454a2SArd Biesheuvel 		{0},
231434454a2SArd Biesheuvel 	};
232434454a2SArd Biesheuvel 
233434454a2SArd Biesheuvel 	sq_mmap_setup(BL31_BASE, BL31_SIZE, secure_partition_mmap);
2348cd37d7bSSumit Garg 	enable_mmu_el3(XLAT_TABLE_NC);
235434454a2SArd Biesheuvel 
2363f3c341aSPaul Beesley #if SPM_MM
237434454a2SArd Biesheuvel 	memcpy((void *)SPM_SHIM_EXCEPTIONS_START,
238434454a2SArd Biesheuvel 	       (void *)SPM_SHIM_EXCEPTIONS_LMA,
239434454a2SArd Biesheuvel 	       (uintptr_t)SPM_SHIM_EXCEPTIONS_END -
240434454a2SArd Biesheuvel 	       (uintptr_t)SPM_SHIM_EXCEPTIONS_START);
241434454a2SArd Biesheuvel #endif
2428cd37d7bSSumit Garg }
2438cd37d7bSSumit Garg 
bl31_plat_enable_mmu(uint32_t flags)2448cd37d7bSSumit Garg void bl31_plat_enable_mmu(uint32_t flags)
2458cd37d7bSSumit Garg {
2468cd37d7bSSumit Garg 	enable_mmu_el3(flags | XLAT_TABLE_NC);
247c35d59a3SSumit Garg }
248