X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=arch%2Farm%2Fcpu%2Farmv7%2Fvirt-v7.c;h=b69fd37c189c51f338ad7f1cbf766404952fc36d;hb=b050898efa6b4f0272f12885a7365f044ab4c08e;hp=2cd604f97fa1802462ffa41ddf6bb3e362888d0d;hpb=f833e790b47236115894c751d4e34070a4db62fd;p=u-boot diff --git a/arch/arm/cpu/armv7/virt-v7.c b/arch/arm/cpu/armv7/virt-v7.c index 2cd604f97f..b69fd37c18 100644 --- a/arch/arm/cpu/armv7/virt-v7.c +++ b/arch/arm/cpu/armv7/virt-v7.c @@ -13,16 +13,7 @@ #include #include #include - -unsigned long gic_dist_addr; - -static unsigned int read_cpsr(void) -{ - unsigned int reg; - - asm volatile ("mrs %0, cpsr\n" : "=r" (reg)); - return reg; -} +#include static unsigned int read_id_pfr1(void) { @@ -37,25 +28,8 @@ static unsigned long get_gicd_base_address(void) #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)); @@ -72,6 +46,18 @@ static unsigned long get_gicd_base_address(void) #endif } +static void relocate_secure_section(void) +{ +#ifdef CONFIG_ARMV7_SECURE_BASE + size_t sz = __secure_end - __secure_start; + + memcpy((void *)CONFIG_ARMV7_SECURE_BASE, __secure_start, sz); + flush_dcache_range(CONFIG_ARMV7_SECURE_BASE, + CONFIG_ARMV7_SECURE_BASE + sz + 1); + invalidate_icache_all(); +#endif +} + static void kick_secondary_cpus_gic(unsigned long gicdaddr) { /* kick all CPUs (except this one) by writing to GICD_SGIR */ @@ -80,41 +66,20 @@ static void kick_secondary_cpus_gic(unsigned long gicdaddr) void __weak smp_kick_all_cpus(void) { - kick_secondary_cpus_gic(gic_dist_addr); -} - -int armv7_switch_hyp(void) -{ - unsigned int reg; - - /* check whether we are in HYP mode already */ - if ((read_cpsr() & 0x1f) == 0x1a) { - debug("CPU already in HYP mode\n"); - return 0; - } - - /* check whether the CPU supports the virtualization extensions */ - reg = read_id_pfr1(); - if ((reg & CPUID_ARM_VIRT_MASK) != 1 << CPUID_ARM_VIRT_SHIFT) { - printf("HYP mode: Virtualization extensions not implemented.\n"); - return -1; - } + unsigned long gic_dist_addr; - /* call the HYP switching code on this CPU also */ - _switch_to_hyp(); - - if ((read_cpsr() & 0x1F) != 0x1a) { - printf("HYP mode: switch not successful.\n"); - return -1; - } + gic_dist_addr = get_gicd_base_address(); + if (gic_dist_addr == -1) + return; - return 0; + kick_secondary_cpus_gic(gic_dist_addr); } -int armv7_switch_nonsec(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(); @@ -147,11 +112,13 @@ int armv7_switch_nonsec(void) for (i = 1; i <= itlinesnr; i++) writel((unsigned)-1, gic_dist_addr + GICD_IGROUPRn + 4 * i); - smp_set_core_boot_addr((unsigned long)_smp_pen, -1); +#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 */ - _nonsec_init(); - + relocate_secure_section(); + secure_ram_addr(_nonsec_init)(); return 0; }