f69881
From 806711fca9e9d52a677bf090565c32c858f2b12e Mon Sep 17 00:00:00 2001
f69881
From: Julian Winkler <julian.winkler1@web.de>
f69881
Date: Thu, 23 Feb 2023 07:01:07 +0100
f69881
Subject: [PATCH 3/6] x86: add devicetree support
f69881
f69881
Since linux kernel has dropped support for simple firmware interface
f69881
(SFI), the only way of boot newer versions on intel MID platform is
f69881
using devicetree
f69881
f69881
Signed-off-by: Julian Winkler <julian.winkler1@web.de>
f69881
Signed-off-by: Simon Horman <horms@kernel.org>
f69881
---
f69881
 kexec/arch/i386/include/arch/options.h |  4 +++-
f69881
 kexec/arch/i386/kexec-beoboot-x86.c    |  2 +-
f69881
 kexec/arch/i386/kexec-bzImage.c        | 21 ++++++++++++++++++++-
f69881
 kexec/arch/i386/kexec-x86.h            |  1 +
f69881
 kexec/arch/i386/x86-linux-setup.c      | 15 +++++++++++++++
f69881
 kexec/arch/i386/x86-linux-setup.h      |  2 ++
f69881
 kexec/arch/x86_64/kexec-bzImage64.c    |  2 +-
f69881
 7 files changed, 43 insertions(+), 4 deletions(-)
f69881
f69881
diff --git a/kexec/arch/i386/include/arch/options.h b/kexec/arch/i386/include/arch/options.h
f69881
index 0e57951..89e0a95 100644
f69881
--- a/kexec/arch/i386/include/arch/options.h
f69881
+++ b/kexec/arch/i386/include/arch/options.h
f69881
@@ -33,6 +33,7 @@
f69881
 #define OPT_PASS_MEMMAP_CMDLINE	(OPT_ARCH_MAX+11)
f69881
 #define OPT_NOEFI		(OPT_ARCH_MAX+12)
f69881
 #define OPT_REUSE_VIDEO_TYPE	(OPT_ARCH_MAX+13)
f69881
+#define OPT_DTB			(OPT_ARCH_MAX+14)
f69881
 
f69881
 /* Options relevant to the architecture (excluding loader-specific ones): */
f69881
 #define KEXEC_ARCH_OPTIONS \
f69881
@@ -76,7 +77,8 @@
f69881
 	{ "args-none",		0, NULL, OPT_ARGS_NONE },	\
f69881
 	{ "module",		1, 0, OPT_MOD },		\
f69881
 	{ "real-mode",		0, NULL, OPT_REAL_MODE },	\
f69881
-	{ "entry-32bit",	0, NULL, OPT_ENTRY_32BIT },
f69881
+	{ "entry-32bit",	0, NULL, OPT_ENTRY_32BIT },	\
f69881
+	{ "dtb",		1, NULL, OPT_DTB },
f69881
 
f69881
 #define KEXEC_ALL_OPT_STR KEXEC_ARCH_OPT_STR
f69881
 
f69881
diff --git a/kexec/arch/i386/kexec-beoboot-x86.c b/kexec/arch/i386/kexec-beoboot-x86.c
f69881
index b121834..d949ab8 100644
f69881
--- a/kexec/arch/i386/kexec-beoboot-x86.c
f69881
+++ b/kexec/arch/i386/kexec-beoboot-x86.c
f69881
@@ -125,7 +125,7 @@ int beoboot_load(int argc, char **argv, const char *buf, off_t UNUSED(len),
f69881
 		kernel,        bb_header.kernel_size,
f69881
 		command_line,  bb_header.cmdline_size,
f69881
 		initrd,        bb_header.initrd_size,
f69881
-		real_mode_entry);
f69881
+		0, 0, real_mode_entry);
f69881
 
f69881
 	return result;
f69881
 }
f69881
diff --git a/kexec/arch/i386/kexec-bzImage.c b/kexec/arch/i386/kexec-bzImage.c
f69881
index df8985d..1b8f20c 100644
f69881
--- a/kexec/arch/i386/kexec-bzImage.c
f69881
+++ b/kexec/arch/i386/kexec-bzImage.c
f69881
@@ -95,6 +95,7 @@ void bzImage_usage(void)
f69881
 		"    --reuse-cmdline       Use kernel command line from running system.\n"
f69881
 		"    --initrd=FILE         Use FILE as the kernel's initial ramdisk.\n"
f69881
 		"    --ramdisk=FILE        Use FILE as the kernel's initial ramdisk.\n"
f69881
+		"    --dtb=FILE            Use FILE as devicetree.\n"
f69881
 		);
f69881
        
f69881
 }
f69881
@@ -103,6 +104,7 @@ int do_bzImage_load(struct kexec_info *info,
f69881
 	const char *kernel, off_t kernel_len,
f69881
 	const char *command_line, off_t command_line_len,
f69881
 	const char *initrd, off_t initrd_len,
f69881
+	const char *dtb, off_t dtb_len,
f69881
 	int real_mode_entry)
f69881
 {
f69881
 	struct x86_linux_header setup_header;
f69881
@@ -373,6 +375,10 @@ int do_bzImage_load(struct kexec_info *info,
f69881
 		setup_linux_system_parameters(info, real_mode);
f69881
 	}
f69881
 
f69881
+	if (dtb) {
f69881
+		setup_linux_dtb(info, real_mode, dtb, dtb_len);
f69881
+	}
f69881
+
f69881
 	return 0;
f69881
 }
f69881
 	
f69881
@@ -381,13 +387,15 @@ int bzImage_load(int argc, char **argv, const char *buf, off_t len,
f69881
 {
f69881
 	char *command_line = NULL;
f69881
 	char *tmp_cmdline = NULL;
f69881
-	const char *ramdisk, *append = NULL;
f69881
+	const char *ramdisk, *append = NULL, *dtb;
f69881
 	char *ramdisk_buf;
f69881
 	off_t ramdisk_length;
f69881
 	int command_line_len;
f69881
 	int real_mode_entry;
f69881
 	int opt;
f69881
 	int result;
f69881
+	char *dtb_buf;
f69881
+	off_t dtb_length;
f69881
 
f69881
 	/* See options.h -- add any more there, too. */
f69881
 	static const struct option options[] = {
f69881
@@ -398,6 +406,7 @@ int bzImage_load(int argc, char **argv, const char *buf, off_t len,
f69881
 		{ "initrd",		1, 0, OPT_RAMDISK },
f69881
 		{ "ramdisk",		1, 0, OPT_RAMDISK },
f69881
 		{ "real-mode",		0, 0, OPT_REAL_MODE },
f69881
+		{ "dtb",		1, 0, OPT_DTB },
f69881
 		{ 0, 			0, 0, 0 },
f69881
 	};
f69881
 	static const char short_options[] = KEXEC_ARCH_OPT_STR "d";
f69881
@@ -405,6 +414,8 @@ int bzImage_load(int argc, char **argv, const char *buf, off_t len,
f69881
 	real_mode_entry = 0;
f69881
 	ramdisk = 0;
f69881
 	ramdisk_length = 0;
f69881
+	dtb = 0;
f69881
+	dtb_length = 0;
f69881
 	while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) {
f69881
 		switch(opt) {
f69881
 		default:
f69881
@@ -424,6 +435,9 @@ int bzImage_load(int argc, char **argv, const char *buf, off_t len,
f69881
 		case OPT_REAL_MODE:
f69881
 			real_mode_entry = 1;
f69881
 			break;
f69881
+		case OPT_DTB:
f69881
+			dtb = optarg;
f69881
+			break;
f69881
 		}
f69881
 	}
f69881
 	command_line = concat_cmdline(tmp_cmdline, append);
f69881
@@ -441,10 +455,15 @@ int bzImage_load(int argc, char **argv, const char *buf, off_t len,
f69881
 	if (ramdisk) {
f69881
 		ramdisk_buf = slurp_file(ramdisk, &ramdisk_length);
f69881
 	}
f69881
+	dtb_buf = 0;
f69881
+	if (dtb) {
f69881
+		dtb_buf = slurp_file(dtb, &dtb_length);
f69881
+	}
f69881
 	result = do_bzImage_load(info,
f69881
 		buf, len,
f69881
 		command_line, command_line_len,
f69881
 		ramdisk_buf, ramdisk_length,
f69881
+		dtb_buf, dtb_length,
f69881
 		real_mode_entry);
f69881
 
f69881
 	free(command_line);
f69881
diff --git a/kexec/arch/i386/kexec-x86.h b/kexec/arch/i386/kexec-x86.h
f69881
index 71e4329..46e2898 100644
f69881
--- a/kexec/arch/i386/kexec-x86.h
f69881
+++ b/kexec/arch/i386/kexec-x86.h
f69881
@@ -79,6 +79,7 @@ int do_bzImage_load(struct kexec_info *info,
f69881
 	const char *kernel, off_t kernel_len,
f69881
 	const char *command_line, off_t command_line_len,
f69881
 	const char *initrd, off_t initrd_len,
f69881
+	const char *dtb, off_t dtb_len,
f69881
 	int real_mode_entry);
f69881
 
f69881
 int beoboot_probe(const char *buf, off_t len);
f69881
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
f69881
index 14263b0..9a281dc 100644
f69881
--- a/kexec/arch/i386/x86-linux-setup.c
f69881
+++ b/kexec/arch/i386/x86-linux-setup.c
f69881
@@ -954,3 +954,18 @@ void setup_linux_system_parameters(struct kexec_info *info,
f69881
 	/* Always try to fill acpi_rsdp_addr */
f69881
 	real_mode->acpi_rsdp_addr = get_acpi_rsdp();
f69881
 }
f69881
+
f69881
+void setup_linux_dtb(struct kexec_info *info, struct x86_linux_param_header *real_mode,
f69881
+				   const char *dtb_buf, int dtb_len)
f69881
+{
f69881
+	struct setup_data *sd;
f69881
+
f69881
+	sd = xmalloc(sizeof(struct setup_data) + dtb_len);
f69881
+	sd->next = 0;
f69881
+	sd->len = dtb_len;
f69881
+	sd->type = SETUP_DTB;
f69881
+	memcpy(sd->data, dtb_buf, dtb_len);
f69881
+
f69881
+
f69881
+	add_setup_data(info, real_mode, sd);
f69881
+}
f69881
diff --git a/kexec/arch/i386/x86-linux-setup.h b/kexec/arch/i386/x86-linux-setup.h
f69881
index 0c651e5..b5e1ad5 100644
f69881
--- a/kexec/arch/i386/x86-linux-setup.h
f69881
+++ b/kexec/arch/i386/x86-linux-setup.h
f69881
@@ -21,6 +21,8 @@ static inline void setup_linux_bootloader_parameters(
f69881
 }
f69881
 void setup_linux_system_parameters(struct kexec_info *info,
f69881
 	struct x86_linux_param_header *real_mode);
f69881
+void setup_linux_dtb(struct kexec_info *info, struct x86_linux_param_header *real_mode,
f69881
+				   const char *dtb_buf, int dtb_len);
f69881
 int get_bootparam(void *buf, off_t offset, size_t size);
f69881
 
f69881
 
f69881
diff --git a/kexec/arch/x86_64/kexec-bzImage64.c b/kexec/arch/x86_64/kexec-bzImage64.c
f69881
index ba8dc48..aba4e3b 100644
f69881
--- a/kexec/arch/x86_64/kexec-bzImage64.c
f69881
+++ b/kexec/arch/x86_64/kexec-bzImage64.c
f69881
@@ -386,7 +386,7 @@ int bzImage64_load(int argc, char **argv, const char *buf, off_t len,
f69881
 	if (entry_16bit || entry_32bit)
f69881
 		result = do_bzImage_load(info, buf, len, command_line,
f69881
 					command_line_len, ramdisk_buf,
f69881
-					ramdisk_length, entry_16bit);
f69881
+					ramdisk_length, 0, 0, entry_16bit);
f69881
 	else
f69881
 		result = do_bzImage64_load(info, buf, len, command_line,
f69881
 					command_line_len, ramdisk_buf,
f69881
-- 
f69881
2.33.1
f69881