summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/setup.c')
-rw-r--r--arch/mips/kernel/setup.c79
1 files changed, 70 insertions, 9 deletions
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 4f607341a793..ef408a03e818 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -26,6 +26,7 @@
#include <linux/sizes.h>
#include <linux/device.h>
#include <linux/dma-contiguous.h>
+#include <linux/decompress/generic.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
@@ -52,13 +53,6 @@ struct screen_info screen_info;
#endif
/*
- * Despite it's name this variable is even if we don't have PCI
- */
-unsigned int PCI_DMA_BUS_IS_PHYS;
-
-EXPORT_SYMBOL(PCI_DMA_BUS_IS_PHYS);
-
-/*
* Setup information
*
* These are initialized so they are in the .data section
@@ -250,6 +244,35 @@ disable:
return 0;
}
+/* In some conditions (e.g. big endian bootloader with a little endian
+ kernel), the initrd might appear byte swapped. Try to detect this and
+ byte swap it if needed. */
+static void __init maybe_bswap_initrd(void)
+{
+#if defined(CONFIG_CPU_CAVIUM_OCTEON)
+ u64 buf;
+
+ /* Check for CPIO signature */
+ if (!memcmp((void *)initrd_start, "070701", 6))
+ return;
+
+ /* Check for compressed initrd */
+ if (decompress_method((unsigned char *)initrd_start, 8, NULL))
+ return;
+
+ /* Try again with a byte swapped header */
+ buf = swab64p((u64 *)initrd_start);
+ if (!memcmp(&buf, "070701", 6) ||
+ decompress_method((unsigned char *)(&buf), 8, NULL)) {
+ unsigned long i;
+
+ pr_info("Byteswapped initrd detected\n");
+ for (i = initrd_start; i < ALIGN(initrd_end, 8); i += 8)
+ swab64s((u64 *)i);
+ }
+#endif
+}
+
static void __init finalize_initrd(void)
{
unsigned long size = initrd_end - initrd_start;
@@ -263,6 +286,8 @@ static void __init finalize_initrd(void)
goto disable;
}
+ maybe_bswap_initrd();
+
reserve_bootmem(__pa(initrd_start), size, BOOTMEM_DEFAULT);
initrd_below_start_ok = 1;
@@ -469,6 +494,29 @@ static void __init bootmem_init(void)
*/
reserve_bootmem(PFN_PHYS(mapstart), bootmap_size, BOOTMEM_DEFAULT);
+#ifdef CONFIG_RELOCATABLE
+ /*
+ * The kernel reserves all memory below its _end symbol as bootmem,
+ * but the kernel may now be at a much higher address. The memory
+ * between the original and new locations may be returned to the system.
+ */
+ if (__pa_symbol(_text) > __pa_symbol(VMLINUX_LOAD_ADDRESS)) {
+ unsigned long offset;
+ extern void show_kernel_relocation(const char *level);
+
+ offset = __pa_symbol(_text) - __pa_symbol(VMLINUX_LOAD_ADDRESS);
+ free_bootmem(__pa_symbol(VMLINUX_LOAD_ADDRESS), offset);
+
+#if defined(CONFIG_DEBUG_KERNEL) && defined(CONFIG_DEBUG_INFO)
+ /*
+ * This information is necessary when debugging the kernel
+ * But is a security vulnerability otherwise!
+ */
+ show_kernel_relocation(KERN_INFO);
+#endif
+ }
+#endif
+
/*
* Reserve initrd memory if needed.
*/
@@ -624,6 +672,8 @@ static void __init request_crashkernel(struct resource *res)
#define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
#define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
#define EXTEND_WITH_PROM IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
+#define BUILTIN_EXTEND_WITH_PROM \
+ IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND)
static void __init arch_mem_init(char **cmdline_p)
{
@@ -657,15 +707,23 @@ static void __init arch_mem_init(char **cmdline_p)
strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
if (EXTEND_WITH_PROM && arcs_cmdline[0]) {
- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+ if (boot_command_line[0])
+ strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
}
#if defined(CONFIG_CMDLINE_BOOL)
if (builtin_cmdline[0]) {
- strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+ if (boot_command_line[0])
+ strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
strlcat(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
}
+
+ if (BUILTIN_EXTEND_WITH_PROM && arcs_cmdline[0]) {
+ if (boot_command_line[0])
+ strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+ strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+ }
#endif
#endif
strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
@@ -706,6 +764,9 @@ static void __init arch_mem_init(char **cmdline_p)
for_each_memblock(reserved, reg)
if (reg->size != 0)
reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
+
+ reserve_bootmem_region(__pa_symbol(&__nosave_begin),
+ __pa_symbol(&__nosave_end)); /* Reserve for hibernation */
}
static void __init resource_init(void)