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 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 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 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 ******************************************************************************/ 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 ******************************************************************************/ 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 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 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 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 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); 212*92752355SSalman Nabi 213*92752355SSalman Nabi console_flush(); 214*92752355SSalman Nabi console_switch_state(CONSOLE_FLAG_RUNTIME); 215c35d59a3SSumit Garg } 216c35d59a3SSumit Garg 217c35d59a3SSumit Garg void bl31_plat_arch_setup(void) 218c35d59a3SSumit Garg { 219434454a2SArd Biesheuvel static const mmap_region_t secure_partition_mmap[] = { 2203f3c341aSPaul Beesley #if SPM_MM 221434454a2SArd Biesheuvel MAP_REGION_FLAT(PLAT_SPM_BUF_BASE, 222434454a2SArd Biesheuvel PLAT_SPM_BUF_SIZE, 223434454a2SArd Biesheuvel MT_RW_DATA | MT_SECURE), 224434454a2SArd Biesheuvel MAP_REGION_FLAT(PLAT_SQ_SP_PRIV_BASE, 225434454a2SArd Biesheuvel PLAT_SQ_SP_PRIV_SIZE, 226434454a2SArd Biesheuvel MT_RW_DATA | MT_SECURE), 227434454a2SArd Biesheuvel #endif 22848ab3904SJassi Brar #if !RESET_TO_BL31 22948ab3904SJassi Brar MAP_REGION_FLAT(BL2_MAILBOX_BASE, 23048ab3904SJassi Brar BL2_MAILBOX_SIZE, 23148ab3904SJassi Brar MT_RW | MT_SECURE), 23248ab3904SJassi Brar #endif 233434454a2SArd Biesheuvel {0}, 234434454a2SArd Biesheuvel }; 235434454a2SArd Biesheuvel 236434454a2SArd Biesheuvel sq_mmap_setup(BL31_BASE, BL31_SIZE, secure_partition_mmap); 2378cd37d7bSSumit Garg enable_mmu_el3(XLAT_TABLE_NC); 238434454a2SArd Biesheuvel 2393f3c341aSPaul Beesley #if SPM_MM 240434454a2SArd Biesheuvel memcpy((void *)SPM_SHIM_EXCEPTIONS_START, 241434454a2SArd Biesheuvel (void *)SPM_SHIM_EXCEPTIONS_LMA, 242434454a2SArd Biesheuvel (uintptr_t)SPM_SHIM_EXCEPTIONS_END - 243434454a2SArd Biesheuvel (uintptr_t)SPM_SHIM_EXCEPTIONS_START); 244434454a2SArd Biesheuvel #endif 2458cd37d7bSSumit Garg } 2468cd37d7bSSumit Garg 2478cd37d7bSSumit Garg void bl31_plat_enable_mmu(uint32_t flags) 2488cd37d7bSSumit Garg { 2498cd37d7bSSumit Garg enable_mmu_el3(flags | XLAT_TABLE_NC); 250c35d59a3SSumit Garg } 251