For no good reason I had assumed that ACPI table headers would be page

aligned (or at least not cross a page boundary).  However, it turns out
that on at least one machine one table header does cross a page boundary.
This caused problems with the MADT early probe as it uses the crash dump
map to load ACPI tables by loading the RSDT/XSDT into pages 1 ... N and
loading the header of each ACPI table header into page 0 looking for the
MADT.  However, if a table header crossed a page boundary, then page 1
would get trashed resulting in a panic.  Fix this by reserving the first
2 pages for ACPI table headers (headers are less than a page in size,
so 2 pages will be sufficient) and use pages 2 .. N for the RSDT and XSDT.

Note: amd64 should probably be simplified to just use pmap_mapbios()
for all these tables which will use the direct map and not need the
crash dump hack.

MFC after:	5 days
Tested on:	i386
Reported by:	Pete French  petefrench of ticketswitch.com
This commit is contained in:
John Baldwin 2008-01-31 16:51:43 +00:00
parent 990132f07d
commit 7157eae462
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=175859
2 changed files with 14 additions and 10 deletions

View file

@ -109,9 +109,11 @@ static struct apic_enumerator madt_enumerator = {
/*
* Code to abuse the crashdump map to map in the tables for the early
* probe. We cheat and make the following assumptions about how we
* use this KVA: page 0 is used to map in the first page of each table
* found via the RSDT or XSDT and pages 1 to n are used to map in the
* RSDT or XSDT. The offset is in pages; the length is in bytes.
* use this KVA: pages 0 and 1 are used to map in the header of each
* table found via the RSDT or XSDT and pages 2 to n are used to map
* in the RSDT or XSDT. We have to use 2 pages for the table headers
* in case a header spans a page boundary. The offset is in pages;
* the length is in bytes.
*/
static void *
madt_map(vm_paddr_t pa, int offset, vm_offset_t length)
@ -232,7 +234,7 @@ madt_probe(void)
printf("MADT: RSDP failed extended checksum\n");
return (ENXIO);
}
xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 1,
xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 2,
ACPI_SIG_XSDT);
if (xsdt == NULL) {
if (bootverbose)
@ -246,7 +248,7 @@ madt_probe(void)
break;
madt_unmap_table(xsdt);
} else {
rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 1,
rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 2,
ACPI_SIG_RSDT);
if (rsdt == NULL) {
if (bootverbose)

View file

@ -109,9 +109,11 @@ static struct apic_enumerator madt_enumerator = {
/*
* Code to abuse the crashdump map to map in the tables for the early
* probe. We cheat and make the following assumptions about how we
* use this KVA: page 0 is used to map in the first page of each table
* found via the RSDT or XSDT and pages 1 to n are used to map in the
* RSDT or XSDT. The offset is in pages; the length is in bytes.
* use this KVA: pages 0 and 1 are used to map in the header of each
* table found via the RSDT or XSDT and pages 2 to n are used to map
* in the RSDT or XSDT. We have to use 2 pages for the table headers
* in case a header spans a page boundary. The offset is in pages;
* the length is in bytes.
*/
static void *
madt_map(vm_paddr_t pa, int offset, vm_offset_t length)
@ -232,7 +234,7 @@ madt_probe(void)
printf("MADT: RSDP failed extended checksum\n");
return (ENXIO);
}
xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 1,
xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 2,
ACPI_SIG_XSDT);
if (xsdt == NULL) {
if (bootverbose)
@ -246,7 +248,7 @@ madt_probe(void)
break;
madt_unmap_table(xsdt);
} else {
rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 1,
rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 2,
ACPI_SIG_RSDT);
if (rsdt == NULL) {
if (bootverbose)