summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kexec/arch/i386/kexec-x86-common.c43
-rw-r--r--kexec/arch/i386/kexec-x86.h1
-rw-r--r--kexec/arch/i386/x86-linux-setup.c3
-rw-r--r--kexec/arch/i386/x86-linux-setup.h1
4 files changed, 46 insertions, 2 deletions
diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c
index de99758..5c55ec8 100644
--- a/kexec/arch/i386/kexec-x86-common.c
+++ b/kexec/arch/i386/kexec-x86-common.c
@@ -39,6 +39,7 @@
#include "../../firmware_memmap.h"
#include "../../crashdump.h"
#include "kexec-x86.h"
+#include "x86-linux-setup.h"
#include "../../kexec-xen.h"
/* Used below but not present in (older?) xenctrl.h */
@@ -392,4 +393,46 @@ int get_memory_ranges(struct memory_range **range, int *ranges,
return ret;
}
+static uint64_t bootparam_get_acpi_rsdp(void) {
+ uint64_t acpi_rsdp = 0;
+ off_t offset = offsetof(struct x86_linux_param_header, acpi_rsdp_addr);
+ if (get_bootparam(&acpi_rsdp, offset, sizeof(acpi_rsdp)))
+ return 0;
+
+ return acpi_rsdp;
+}
+
+static uint64_t efi_get_acpi_rsdp(void) {
+ FILE *fp;
+ char line[MAX_LINE], *s;
+ uint64_t acpi_rsdp = 0;
+
+ fp = fopen("/sys/firmware/efi/systab", "r");
+ if (!fp)
+ return acpi_rsdp;
+
+ while(fgets(line, sizeof(line), fp) != 0) {
+ /* ACPI20= always goes before ACPI= */
+ if ((strstr(line, "ACPI20=")) || (strstr(line, "ACPI="))) {
+ s = strchr(line, '=') + 1;
+ sscanf(s, "0x%lx", &acpi_rsdp);
+ break;
+ }
+ }
+ fclose(fp);
+
+ return acpi_rsdp;
+}
+
+uint64_t get_acpi_rsdp(void)
+{
+ uint64_t acpi_rsdp = 0;
+
+ acpi_rsdp = bootparam_get_acpi_rsdp();
+
+ if (!acpi_rsdp)
+ acpi_rsdp = efi_get_acpi_rsdp();
+
+ return acpi_rsdp;
+}
diff --git a/kexec/arch/i386/kexec-x86.h b/kexec/arch/i386/kexec-x86.h
index c2bcd37..1b58c3b 100644
--- a/kexec/arch/i386/kexec-x86.h
+++ b/kexec/arch/i386/kexec-x86.h
@@ -86,4 +86,5 @@ int nbi_load(int argc, char **argv, const char *buf, off_t len,
void nbi_usage(void);
extern unsigned xen_e820_to_kexec_type(uint32_t type);
+extern uint64_t get_acpi_rsdp(void);
#endif /* KEXEC_X86_H */
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
index b643c8b..da5de97 100644
--- a/kexec/arch/i386/x86-linux-setup.c
+++ b/kexec/arch/i386/x86-linux-setup.c
@@ -123,7 +123,6 @@ void setup_linux_bootloader_parameters_high(
cmdline_ptr[cmdline_len - 1] = '\0';
}
-static int get_bootparam(void *buf, off_t offset, size_t size);
static int setup_linux_vesafb(struct x86_linux_param_header *real_mode)
{
struct fb_fix_screeninfo fix;
@@ -460,7 +459,7 @@ char *find_mnt_by_type(char *type)
return mntdir;
}
-static int get_bootparam(void *buf, off_t offset, size_t size)
+int get_bootparam(void *buf, off_t offset, size_t size)
{
int data_file;
char *debugfs_mnt, *sysfs_mnt;
diff --git a/kexec/arch/i386/x86-linux-setup.h b/kexec/arch/i386/x86-linux-setup.h
index f5d23d3..0c651e5 100644
--- a/kexec/arch/i386/x86-linux-setup.h
+++ b/kexec/arch/i386/x86-linux-setup.h
@@ -21,6 +21,7 @@ static inline void setup_linux_bootloader_parameters(
}
void setup_linux_system_parameters(struct kexec_info *info,
struct x86_linux_param_header *real_mode);
+int get_bootparam(void *buf, off_t offset, size_t size);
#define SETUP_BASE 0x90000