#include <asm/io.h>
#include <asm/secure.h>
-unsigned long gic_dist_addr;
-
static unsigned int read_id_pfr1(void)
{
unsigned int reg;
#ifdef CONFIG_ARM_GIC_BASE_ADDRESS
return CONFIG_ARM_GIC_BASE_ADDRESS + GIC_DIST_OFFSET;
#else
- unsigned midr;
unsigned periphbase;
- /* check whether we are an Cortex-A15 or A7.
- * The actual HYP switch should work with all CPUs supporting
- * the virtualization extension, but we need the GIC address,
- * which we know only for sure for those two CPUs.
- */
- asm("mrc p15, 0, %0, c0, c0, 0\n" : "=r"(midr));
- switch (midr & MIDR_PRIMARY_PART_MASK) {
- case MIDR_CORTEX_A9_R0P1:
- case MIDR_CORTEX_A15_R0P0:
- case MIDR_CORTEX_A7_R0P0:
- break;
- default:
- printf("nonsec: could not determine GIC address.\n");
- return -1;
- }
-
/* get the GIC base address from the CBAR register */
asm("mrc p15, 4, %0, c15, c0, 0\n" : "=r" (periphbase));
#endif
}
+/* Define a specific version of this function to enable any available
+ * hardware protections for the reserved region */
+void __weak protect_secure_section(void) {}
+
static void relocate_secure_section(void)
{
#ifdef CONFIG_ARMV7_SECURE_BASE
size_t sz = __secure_end - __secure_start;
+ unsigned long szflush = ALIGN(sz + 1, CONFIG_SYS_CACHELINE_SIZE);
memcpy((void *)CONFIG_ARMV7_SECURE_BASE, __secure_start, sz);
+
flush_dcache_range(CONFIG_ARMV7_SECURE_BASE,
- CONFIG_ARMV7_SECURE_BASE + sz + 1);
+ CONFIG_ARMV7_SECURE_BASE + szflush);
+ protect_secure_section();
invalidate_icache_all();
#endif
}
void __weak smp_kick_all_cpus(void)
{
+ unsigned long gic_dist_addr;
+
+ gic_dist_addr = get_gicd_base_address();
+ if (gic_dist_addr == -1)
+ return;
+
kick_secondary_cpus_gic(gic_dist_addr);
}
+__weak void psci_board_init(void)
+{
+}
+
int armv7_init_nonsec(void)
{
unsigned int reg;
unsigned itlinesnr, i;
+ unsigned long gic_dist_addr;
/* check whether the CPU supports the security extensions */
reg = read_id_pfr1();
for (i = 1; i <= itlinesnr; i++)
writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i);
+ psci_board_init();
+
+ /*
+ * Relocate secure section before any cpu runs in secure ram.
+ * smp_kick_all_cpus may enable other cores and runs into secure
+ * ram, so need to relocate secure section before enabling other
+ * cores.
+ */
+ relocate_secure_section();
+
#ifndef CONFIG_ARMV7_PSCI
smp_set_core_boot_addr((unsigned long)secure_ram_addr(_smp_pen), -1);
smp_kick_all_cpus();
#endif
/* call the non-sec switching code on this CPU also */
- relocate_secure_section();
secure_ram_addr(_nonsec_init)();
return 0;
}