summaryrefslogtreecommitdiff
path: root/kexec/arch/mips/kexec-elf-mips.c
diff options
context:
space:
mode:
authorMarcin Nowakowski <marcin.nowakowski@imgtec.com>2016-12-02 10:49:10 +0100
committerSimon Horman <horms@verge.net.au>2016-12-09 08:56:27 +0100
commit83a53ce9248fbcdf9dcac507b895d818db8c1706 (patch)
treeab0f0c93cf5c8e75df11345eeba0ab70ed38507e /kexec/arch/mips/kexec-elf-mips.c
parent18bf48b15c289e88cb65cdc758749e2735eac291 (diff)
mips: add dtb loading support
Kexec for MIPS currently does not support loading devicetrees, unless they are embedded in the kernel elf file. Add an option to either pass a new dtb file or - if not specified - to be generated from existing device tree on the device. As new generic platforms require a dtb to be passed separately this is required for such platforms and will be ignored by the kernel otherwise. Generic kexec infrastructure for dtb support is used. Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: linux-mips@linux-mips.org Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'kexec/arch/mips/kexec-elf-mips.c')
-rw-r--r--kexec/arch/mips/kexec-elf-mips.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/kexec/arch/mips/kexec-elf-mips.c b/kexec/arch/mips/kexec-elf-mips.c
index 7cb06f1..6ca7ca0 100644
--- a/kexec/arch/mips/kexec-elf-mips.c
+++ b/kexec/arch/mips/kexec-elf-mips.c
@@ -29,13 +29,16 @@
#include "kexec-mips.h"
#include "crashdump-mips.h"
#include <arch/options.h>
+#include "../../fs2dt.h"
+#include "../../dt-ops.h"
static const int probe_debug = 0;
#define BOOTLOADER "kexec"
-#define MAX_COMMAND_LINE 256
#define UPSZ(X) _ALIGN_UP(sizeof(X), 4)
-static char cmdline_buf[256] = "kexec ";
+
+#define CMDLINE_PREFIX "kexec "
+static char cmdline_buf[COMMAND_LINE_SIZE] = CMDLINE_PREFIX;
int elf_mips_probe(const char *buf, off_t len)
{
@@ -74,6 +77,10 @@ int elf_mips_load(int argc, char **argv, const char *buf, off_t len,
int result;
unsigned long cmdline_addr;
size_t i;
+ off_t dtb_length;
+ char *dtb_buf;
+ unsigned long long kernel_addr = 0, kernel_size = 0;
+ unsigned long pagesize = getpagesize();
/* Need to append some command line parameters internally in case of
* taking crash dumps.
@@ -92,8 +99,11 @@ int elf_mips_load(int argc, char **argv, const char *buf, off_t len,
for (i = 0; i < ehdr.e_phnum; i++) {
struct mem_phdr *phdr;
phdr = &ehdr.e_phdr[i];
- if (phdr->p_type == PT_LOAD)
+ if (phdr->p_type == PT_LOAD) {
phdr->p_paddr = virt_to_phys(phdr->p_paddr);
+ kernel_addr = phdr->p_paddr;
+ kernel_size = phdr->p_memsz;
+ }
}
/* Load the Elf data */
@@ -130,10 +140,28 @@ int elf_mips_load(int argc, char **argv, const char *buf, off_t len,
else
cmdline_addr = 0;
+ /* MIPS systems that have been converted to use device tree
+ * passed through UHI will use commandline in the DTB and
+ * the DTB passed as a separate buffer. Note that
+ * CMDLINE_PREFIX is skipped here intentionally, as it is
+ * used only in the legacy method */
+
+ if (arch_options.dtb_file) {
+ dtb_buf = slurp_file(arch_options.dtb_file, &dtb_length);
+ } else {
+ create_flatten_tree(&dtb_buf, &dtb_length, cmdline_buf + strlen(CMDLINE_PREFIX));
+ }
+
+ /* This is a legacy method for commandline passing used
+ * currently by Octeon CPUs only */
add_buffer(info, cmdline_buf, sizeof(cmdline_buf),
sizeof(cmdline_buf), sizeof(void *),
cmdline_addr, 0x0fffffff, 1);
+ add_buffer(info, dtb_buf, dtb_length, dtb_length, 0,
+ _ALIGN_UP(kernel_addr + kernel_size, pagesize),
+ 0x0fffffff, 1);
+
return 0;
}