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@xxxxxxxxxx> Cc: Ralf Baechle <ralf@xxxxxxxxxxxxxx> Cc: linux-mips@xxxxxxxxxxxxxx --- kexec/arch/mips/Makefile | 13 +++++++++++++ kexec/arch/mips/crashdump-mips.c | 3 +++ kexec/arch/mips/include/arch/options.h | 5 ++++- kexec/arch/mips/kexec-elf-mips.c | 34 +++++++++++++++++++++++++++++++--- kexec/arch/mips/kexec-mips.c | 8 ++++++++ kexec/arch/mips/kexec-mips.h | 9 +++++++++ 6 files changed, 68 insertions(+), 4 deletions(-) diff --git a/kexec/arch/mips/Makefile b/kexec/arch/mips/Makefile index 03bdb9a..1fe7886 100644 --- a/kexec/arch/mips/Makefile +++ b/kexec/arch/mips/Makefile @@ -6,6 +6,19 @@ mips_KEXEC_SRCS += kexec/arch/mips/kexec-elf-mips.c mips_KEXEC_SRCS += kexec/arch/mips/kexec-elf-rel-mips.c mips_KEXEC_SRCS += kexec/arch/mips/crashdump-mips.c +mips_FS2DT = kexec/fs2dt.c +mips_FS2DT_INCLUDE = \ + -include $(srcdir)/kexec/arch/mips/crashdump-mips.h \ + -include $(srcdir)/kexec/arch/mips/kexec-mips.h + +mips_DT_OPS += kexec/dt-ops.c + +include $(srcdir)/kexec/libfdt/Makefile.libfdt + +libfdt_SRCS += $(LIBFDT_SRCS:%=kexec/libfdt/%) +mips_CPPFLAGS += -I$(srcdir)/kexec/libfdt +mips_KEXEC_SRCS += $(libfdt_SRCS) + mips_ADD_BUFFER = mips_ADD_SEGMENT = mips_VIRT_TO_PHYS = diff --git a/kexec/arch/mips/crashdump-mips.c b/kexec/arch/mips/crashdump-mips.c index 278ee01..d6cff5a 100644 --- a/kexec/arch/mips/crashdump-mips.c +++ b/kexec/arch/mips/crashdump-mips.c @@ -39,6 +39,9 @@ * A separate program header is created for backup region */ static struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES]; +/* Not used currently but required by generic fs2dt code */ +struct memory_ranges usablemem_rgns; + /* Memory region reserved for storing panic kernel and other data. */ static struct memory_range crash_reserved_mem; diff --git a/kexec/arch/mips/include/arch/options.h b/kexec/arch/mips/include/arch/options.h index a18251b..86b620f 100644 --- a/kexec/arch/mips/include/arch/options.h +++ b/kexec/arch/mips/include/arch/options.h @@ -3,6 +3,7 @@ #define OPT_ARCH_MAX (OPT_MAX+0) #define OPT_APPEND (OPT_ARCH_MAX+0) +#define OPT_DTB (OPT_ARCH_MAX+1) /* Options relevant to the architecture (excluding loader-specific ones), * in this case none: @@ -10,7 +11,9 @@ #define KEXEC_ARCH_OPTIONS \ KEXEC_OPTIONS \ {"command-line", 1, 0, OPT_APPEND}, \ - {"append", 1, 0, OPT_APPEND}, + {"append", 1, 0, OPT_APPEND}, \ + {"dtb", 1, 0, OPT_DTB }, + #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" 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; } diff --git a/kexec/arch/mips/kexec-mips.c b/kexec/arch/mips/kexec-mips.c index 867e9c3..2605c17 100644 --- a/kexec/arch/mips/kexec-mips.c +++ b/kexec/arch/mips/kexec-mips.c @@ -21,6 +21,10 @@ #include "kexec-mips.h" #include <arch/options.h> +/* Currently not used but required by top-level fs2dt code */ +off_t initrd_base = 0; +off_t initrd_size = 0; + static struct memory_range memory_range[MAX_MEMORY_RANGES]; /* Return a sorted list of memory ranges. */ @@ -77,6 +81,7 @@ void arch_usage(void) printf( " --command-line=STRING Set the kernel command line to STRING.\n" " --append=STRING Set the kernel command line to STRING.\n" + " --dtb=FILE Use FILE as the device tree blob.\n" ); } @@ -103,6 +108,9 @@ int arch_process_options(int argc, char **argv) case OPT_APPEND: arch_options.command_line = optarg; break; + case OPT_DTB: + arch_options.dtb_file = optarg; + break; default: break; } diff --git a/kexec/arch/mips/kexec-mips.h b/kexec/arch/mips/kexec-mips.h index 2991b2d..a609fb5 100644 --- a/kexec/arch/mips/kexec-mips.h +++ b/kexec/arch/mips/kexec-mips.h @@ -1,6 +1,11 @@ #ifndef KEXEC_MIPS_H #define KEXEC_MIPS_H +#include <sys/types.h> + +#define BOOT_BLOCK_VERSION 17 +#define BOOT_BLOCK_LAST_COMP_VERSION 16 + #define MAX_MEMORY_RANGES 64 #define MAX_LINE 160 @@ -14,7 +19,11 @@ void elf_mips_usage(void); struct arch_options_t { char *command_line; + char *dtb_file; int core_header_type; }; +extern struct memory_ranges usablemem_rgns; +extern off_t initrd_base, initrd_size; + #endif /* KEXEC_MIPS_H */ -- 2.7.4