diff options
author | Marcin Nowakowski <marcin.nowakowski@imgtec.com> | 2016-12-02 10:49:10 +0100 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2016-12-09 08:56:27 +0100 |
commit | 83a53ce9248fbcdf9dcac507b895d818db8c1706 (patch) | |
tree | ab0f0c93cf5c8e75df11345eeba0ab70ed38507e /kexec/arch/mips/kexec-elf-mips.c | |
parent | 18bf48b15c289e88cb65cdc758749e2735eac291 (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.c | 34 |
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; } |