Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 239665a3 authored by Len Brown's avatar Len Brown
Browse files

ACPI: tables: complete searching upon RSDP w/ bad checksum.

ACPI tables follow a tree structure in memory.
The root of the tree is the RSDP (Root System Description Pointer).

To find the RSDP, the OS searches for the signature "RSD PTR "
in well known physical memory locations.  Then the OS computes
a table checksum to verify that the signature is really part
of a valid table header.

Some systems have a proper signature but an invalid checksum;
followed elsewhere by a proper signature with valid checksum.

http://bugzilla.kernel.org/show_bug.cgi?id=9444



The Linux RSDP scanning code bailed out on those systems
and as a result they booted with ACPI disabled.

Fix this by deleting the Linux RSDP scanning code and
plugging in the ACPICA RSDP scanning code.

Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 2ffbb837
Loading
Loading
Loading
Loading
+14 −12
Original line number Diff line number Diff line
@@ -69,6 +69,20 @@ unsigned int acpi_cpei_phys_cpuid;

unsigned long acpi_wakeup_address = 0;

#ifdef CONFIG_IA64_GENERIC
static unsigned long __init acpi_find_rsdp(void)
{
	unsigned long rsdp_phys = 0;

	if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
		rsdp_phys = efi.acpi20;
	else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
		printk(KERN_WARNING PREFIX
		       "v1.0/r0.71 tables no longer supported\n");
	return rsdp_phys;
}
#endif

const char __init *
acpi_get_sysname(void)
{
@@ -631,18 +645,6 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)
	return 0;
}

unsigned long __init acpi_find_rsdp(void)
{
	unsigned long rsdp_phys = 0;

	if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
		rsdp_phys = efi.acpi20;
	else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
		printk(KERN_WARNING PREFIX
		       "v1.0/r0.71 tables no longer supported\n");
	return rsdp_phys;
}

int __init acpi_boot_init(void)
{

+0 −40
Original line number Diff line number Diff line
@@ -581,25 +581,6 @@ int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)

EXPORT_SYMBOL(acpi_unregister_ioapic);

static unsigned long __init
acpi_scan_rsdp(unsigned long start, unsigned long length)
{
	unsigned long offset = 0;
	unsigned long sig_len = sizeof("RSD PTR ") - 1;

	/*
	 * Scan all 16-byte boundaries of the physical memory region for the
	 * RSDP signature.
	 */
	for (offset = 0; offset < length; offset += 16) {
		if (strncmp((char *)(phys_to_virt(start) + offset), "RSD PTR ", sig_len))
			continue;
		return (start + offset);
	}

	return 0;
}

static int __init acpi_parse_sbf(struct acpi_table_header *table)
{
	struct acpi_table_boot *sb;
@@ -742,27 +723,6 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)
	return 0;
}

unsigned long __init acpi_find_rsdp(void)
{
	unsigned long rsdp_phys = 0;

	if (efi_enabled) {
		if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
			return efi.acpi20;
		else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
			return efi.acpi;
	}
	/*
	 * Scan memory looking for the RSDP signature. First search EBDA (low
	 * memory) paragraphs and then search upper memory (E0000-FFFFF).
	 */
	rsdp_phys = acpi_scan_rsdp(0, 0x400);
	if (!rsdp_phys)
		rsdp_phys = acpi_scan_rsdp(0xE0000, 0x20000);

	return rsdp_phys;
}

#ifdef	CONFIG_X86_LOCAL_APIC
/*
 * Parse LAPIC entries in MADT
+1 −1
Original line number Diff line number Diff line
@@ -276,7 +276,7 @@ int __init get_memcfg_from_srat(void)
	int tables = 0;
	int i = 0;

	rsdp_address = acpi_find_rsdp();
	rsdp_address = acpi_os_get_root_pointer();
	if (!rsdp_address) {
		printk("%s: System description tables not found\n",
		       __FUNCTION__);
+6 −2
Original line number Diff line number Diff line
@@ -207,8 +207,12 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
			       "System description tables not found\n");
			return 0;
		}
	} else
		return acpi_find_rsdp();
	} else {
		acpi_physical_address pa = 0;

		acpi_find_root_pointer(&pa);
		return pa;
	}
}

void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
+1 −1
Original line number Diff line number Diff line
@@ -2,6 +2,6 @@
# Makefile for all Linux ACPI interpreter subdirectories
#

obj-y := tbxface.o tbinstal.o  tbutils.o tbfind.o tbfadt.o
obj-y := tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o

EXTRA_CFLAGS += $(ACPI_CFLAGS)
Loading