diff options
-rw-r--r-- | kexec/arch/i386/kexec-x86-common.c | 43 | ||||
-rw-r--r-- | kexec/arch/i386/kexec-x86.h | 1 | ||||
-rw-r--r-- | kexec/arch/i386/x86-linux-setup.c | 3 | ||||
-rw-r--r-- | kexec/arch/i386/x86-linux-setup.h | 1 |
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 |