2 * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
9 #include <platform_def.h>
12 #include <arch_helpers.h>
13 #include <common/debug.h>
14 #include <common/romlib.h>
16 #include <lib/xlat_tables/xlat_tables_compat.h>
17 #include <plat/arm/common/plat_arm.h>
18 #include <plat/common/platform.h>
19 #include <services/secure_partition.h>
21 /* Weak definitions may be overridden in specific ARM standard platform */
22 #pragma weak plat_get_ns_image_entrypoint
23 #pragma weak plat_arm_get_mmap
25 /* Conditionally provide a weak definition of plat_get_syscnt_freq2 to avoid
26 * conflicts with the definition in plat/common. */
27 #pragma weak plat_get_syscnt_freq2
30 void arm_setup_romlib(void)
33 if (!rom_lib_init(ROMLIB_VERSION
))
38 uintptr_t plat_get_ns_image_entrypoint(void)
40 #ifdef PRELOADED_BL33_BASE
41 return PRELOADED_BL33_BASE
;
43 return PLAT_ARM_NS_IMAGE_BASE
;
47 /*******************************************************************************
48 * Gets SPSR for BL32 entry
49 ******************************************************************************/
50 uint32_t arm_get_spsr_for_bl32_entry(void)
53 * The Secure Payload Dispatcher service is responsible for
54 * setting the SPSR prior to entry into the BL32 image.
59 /*******************************************************************************
60 * Gets SPSR for BL33 entry
61 ******************************************************************************/
63 uint32_t arm_get_spsr_for_bl33_entry(void)
68 /* Figure out what mode we enter the non-secure world in */
69 mode
= (el_implemented(2) != EL_IMPL_NONE
) ? MODE_EL2
: MODE_EL1
;
72 * TODO: Consider the possibility of specifying the SPSR in
73 * the FIP ToC and allowing the platform to have a say as
76 spsr
= SPSR_64(mode
, MODE_SP_ELX
, DISABLE_ALL_EXCEPTIONS
);
80 /*******************************************************************************
81 * Gets SPSR for BL33 entry
82 ******************************************************************************/
83 uint32_t arm_get_spsr_for_bl33_entry(void)
85 unsigned int hyp_status
, mode
, spsr
;
87 hyp_status
= GET_VIRT_EXT(read_id_pfr1());
89 mode
= (hyp_status
) ? MODE32_hyp
: MODE32_svc
;
92 * TODO: Consider the possibility of specifying the SPSR in
93 * the FIP ToC and allowing the platform to have a say as
96 spsr
= SPSR_MODE32(mode
, plat_get_ns_image_entrypoint() & 0x1,
97 SPSR_E_LITTLE
, DISABLE_ALL_EXCEPTIONS
);
102 /*******************************************************************************
103 * Configures access to the system counter timer module.
104 ******************************************************************************/
105 #ifdef ARM_SYS_TIMCTL_BASE
106 void arm_configure_sys_timer(void)
108 unsigned int reg_val
;
110 /* Read the frequency of the system counter */
111 unsigned int freq_val
= plat_get_syscnt_freq2();
113 #if ARM_CONFIG_CNTACR
114 reg_val
= (1U << CNTACR_RPCT_SHIFT
) | (1U << CNTACR_RVCT_SHIFT
);
115 reg_val
|= (1U << CNTACR_RFRQ_SHIFT
) | (1U << CNTACR_RVOFF_SHIFT
);
116 reg_val
|= (1U << CNTACR_RWVT_SHIFT
) | (1U << CNTACR_RWPT_SHIFT
);
117 mmio_write_32(ARM_SYS_TIMCTL_BASE
+ CNTACR_BASE(PLAT_ARM_NSTIMER_FRAME_ID
), reg_val
);
118 #endif /* ARM_CONFIG_CNTACR */
120 reg_val
= (1U << CNTNSAR_NS_SHIFT(PLAT_ARM_NSTIMER_FRAME_ID
));
121 mmio_write_32(ARM_SYS_TIMCTL_BASE
+ CNTNSAR
, reg_val
);
124 * Initialize CNTFRQ register in CNTCTLBase frame. The CNTFRQ
125 * system register initialized during psci_arch_setup() is different
126 * from this and has to be updated independently.
128 mmio_write_32(ARM_SYS_TIMCTL_BASE
+ CNTCTLBASE_CNTFRQ
, freq_val
);
130 #if defined(PLAT_juno) || defined(PLAT_n1sdp)
132 * Initialize CNTFRQ register in Non-secure CNTBase frame.
133 * This is only required for Juno and N1SDP, because they do not
134 * follow ARM ARM in that the value updated in CNTFRQ is not
135 * reflected in CNTBASEN_CNTFRQ. Hence update the value manually.
137 mmio_write_32(ARM_SYS_CNT_BASE_NS
+ CNTBASEN_CNTFRQ
, freq_val
);
140 #endif /* ARM_SYS_TIMCTL_BASE */
142 /*******************************************************************************
143 * Returns ARM platform specific memory map regions.
144 ******************************************************************************/
145 const mmap_region_t
*plat_arm_get_mmap(void)
147 return plat_arm_mmap
;
150 #ifdef ARM_SYS_CNTCTL_BASE
152 unsigned int plat_get_syscnt_freq2(void)
154 unsigned int counter_base_frequency
;
156 /* Read the frequency from Frequency modes table */
157 counter_base_frequency
= mmio_read_32(ARM_SYS_CNTCTL_BASE
+ CNTFID_OFF
);
159 /* The first entry of the frequency modes table must not be 0 */
160 if (counter_base_frequency
== 0U)
163 return counter_base_frequency
;
166 #endif /* ARM_SYS_CNTCTL_BASE */
170 * Translate SDEI entry point to PA, and perform standard ARM entry point
173 int plat_sdei_validate_entry_point(uintptr_t ep
, unsigned int client_mode
)
178 /* Doing Non-secure address translation requires SCR_EL3.NS set */
179 scr_el3
= read_scr_el3();
180 write_scr_el3(scr_el3
| SCR_NS_BIT
);
183 assert((client_mode
== MODE_EL2
) || (client_mode
== MODE_EL1
));
184 if (client_mode
== MODE_EL2
) {
186 * Translate entry point to Physical Address using the EL2
187 * translation regime.
192 * Translate entry point to Physical Address using the EL1&0
193 * translation regime, including stage 2.
198 par
= read_par_el1();
200 /* Restore original SCRL_EL3 */
201 write_scr_el3(scr_el3
);
204 /* If the translation resulted in fault, return failure */
205 if ((par
& PAR_F_MASK
) != 0)
208 /* Extract Physical Address from PAR */
209 pa
= (par
& (PAR_ADDR_MASK
<< PAR_ADDR_SHIFT
));
211 /* Perform NS entry point validation on the physical address */
212 return arm_validate_ns_entrypoint(pa
);