diff options
-rw-r--r-- | arch/mips/Kconfig | 3 | ||||
-rw-r--r-- | arch/mips/cavium-octeon/smp.c | 20 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h | 15 |
3 files changed, 33 insertions, 5 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 80832aa8e4fb..7cb4b0e5f49a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -910,6 +910,7 @@ config CAVIUM_OCTEON_SOC select NR_CPUS_DEFAULT_16 select BUILTIN_DTB select MTD_COMPLEX_MAPPINGS + select SYS_SUPPORTS_RELOCATABLE help This option supports all of the Octeon reference boards from Cavium Networks. It builds a kernel that dynamically determines the Octeon @@ -2571,7 +2572,7 @@ config SYS_SUPPORTS_NUMA config RELOCATABLE bool "Relocatable kernel" - depends on SYS_SUPPORTS_RELOCATABLE && (CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_MIPS32_R6 || CPU_MIPS64_R6) + depends on SYS_SUPPORTS_RELOCATABLE && (CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_MIPS32_R6 || CPU_MIPS64_R6 || CAVIUM_OCTEON_SOC) help This builds a kernel image that retains relocation information so it can be loaded someplace besides the default 1MB. diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 256fe6f65cf2..889c3f49dbc0 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -24,12 +24,17 @@ volatile unsigned long octeon_processor_boot = 0xff; volatile unsigned long octeon_processor_sp; volatile unsigned long octeon_processor_gp; +#ifdef CONFIG_RELOCATABLE +volatile unsigned long octeon_processor_relocated_kernel_entry; +#endif /* CONFIG_RELOCATABLE */ #ifdef CONFIG_HOTPLUG_CPU uint64_t octeon_bootloader_entry_addr; EXPORT_SYMBOL(octeon_bootloader_entry_addr); #endif +extern void kernel_entry(unsigned long arg1, ...); + static void octeon_icache_flush(void) { asm volatile ("synci 0($0)\n"); @@ -180,6 +185,19 @@ static void __init octeon_smp_setup(void) octeon_smp_hotplug_setup(); } + +#ifdef CONFIG_RELOCATABLE +int plat_post_relocation(long offset) +{ + unsigned long entry = (unsigned long)kernel_entry; + + /* Send secondaries into relocated kernel */ + octeon_processor_relocated_kernel_entry = entry + offset; + + return 0; +} +#endif /* CONFIG_RELOCATABLE */ + /** * Firmware CPU startup hook * @@ -333,8 +351,6 @@ void play_dead(void) ; } -extern void kernel_entry(unsigned long arg1, ...); - static void start_after_reset(void) { kernel_entry(0, 0, 0); /* set a2 = 0 for secondary core */ diff --git a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h index c4873e8594ef..c38b38ce5a3d 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h +++ b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h @@ -99,9 +99,20 @@ # to begin # - # This is the variable where the next core to boot os stored - PTR_LA t0, octeon_processor_boot octeon_spin_wait_boot: +#ifdef CONFIG_RELOCATABLE + PTR_LA t0, octeon_processor_relocated_kernel_entry + LONG_L t0, (t0) + beq zero, t0, 1f + nop + + jr t0 + nop +1: +#endif /* CONFIG_RELOCATABLE */ + + # This is the variable where the next core to boot is stored + PTR_LA t0, octeon_processor_boot # Get the core id of the next to be booted LONG_L t1, (t0) # Keep looping if it isn't me |