diff options
| author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-09-21 15:06:57 +0000 |
|---|---|---|
| committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-09-21 15:07:54 +0000 |
| commit | 5cf554af1079ca06b1b977788f9c0fb796f68945 (patch) | |
| tree | 8a710a5a1335d11a8c0bd8528ce8eb822b4e06bc | |
| parent | 6a41e7224f5dce21547e07eced881016dac9e18a (diff) | |
| download | illumos-joyent-5cf554af1079ca06b1b977788f9c0fb796f68945.tar.gz | |
OS-5614 acpidump cannot find RSDP on some machines
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Approved by: Patrick Mooney <patrick.mooney@joyent.com>
| -rw-r--r-- | usr/src/cmd/acpi/acpidump/osillumostbl.c | 88 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/io/xsvc/xsvc.c | 17 |
2 files changed, 80 insertions, 25 deletions
diff --git a/usr/src/cmd/acpi/acpidump/osillumostbl.c b/usr/src/cmd/acpi/acpidump/osillumostbl.c index d4f38b2604..8e8375f9a2 100644 --- a/usr/src/cmd/acpi/acpidump/osillumostbl.c +++ b/usr/src/cmd/acpi/acpidump/osillumostbl.c @@ -357,44 +357,84 @@ AcpiOsGetTableByIndex(UINT32 Index, ACPI_TABLE_HEADER **Table, * RETURN: Status * * DESCRIPTION: Scan and load RSDP. - * + * See the find_rsdp() function in usr/src/uts/i86pc/os/fakebop.c, which is how + * the kernel finds the RSDP. That algorithm matches AcpiFindRootPointer(). + * The code here is derived from AcpiFindRootPointer, except that we will try + * the BIOS if the EBDA fails, and we will copy the table if found. */ static ACPI_STATUS OslLoadRsdp(void) { - ACPI_TABLE_HEADER *MappedTable; - UINT8 *RsdpAddress; - ACPI_PHYSICAL_ADDRESS RsdpBase; - ACPI_SIZE RsdpSize; + UINT8 *mapp; + ACPI_TABLE_HEADER *tblp; + ACPI_SIZE mapsize; + ACPI_PHYSICAL_ADDRESS physaddr; - /* Get RSDP from memory */ + /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ + mapp = AcpiOsMapMemory((ACPI_PHYSICAL_ADDRESS)ACPI_EBDA_PTR_LOCATION, + ACPI_EBDA_PTR_LENGTH); + if (mapp == NULL) + goto try_bios; + + ACPI_MOVE_16_TO_32(&physaddr, mapp); + + /* Convert segment part to physical address */ + physaddr <<= 4; + AcpiOsUnmapMemory(mapp, ACPI_EBDA_PTR_LENGTH); + + /* EBDA present? */ + if (physaddr <= 0x400) + goto try_bios; + + /* + * 1b) Search EBDA paragraphs (EBDA is required to be a minimum of 1K + * length) + */ + mapp = AcpiOsMapMemory(physaddr, ACPI_EBDA_WINDOW_SIZE); + if (mapp == NULL) { + (void) fprintf(stderr, "EBDA (0x%p) found, but is not " + "mappable\n", physaddr); + goto try_bios; + } + + tblp = ACPI_CAST_PTR(ACPI_TABLE_HEADER, + AcpiTbScanMemoryForRsdp(mapp, ACPI_EBDA_WINDOW_SIZE)); + if (tblp != NULL) { + physaddr += (ACPI_PHYSICAL_ADDRESS) ACPI_PTR_DIFF(tblp, mapp); + Gbl_RsdpAddress = physaddr; + memcpy(&Gbl_Rsdp, tblp, sizeof (ACPI_TABLE_RSDP)); + AcpiOsUnmapMemory(mapp, ACPI_EBDA_WINDOW_SIZE); + + return (AE_OK); + } + AcpiOsUnmapMemory(mapp, ACPI_EBDA_WINDOW_SIZE); - RsdpSize = sizeof (ACPI_TABLE_RSDP); - if (Gbl_RsdpBase) { - RsdpBase = Gbl_RsdpBase; +try_bios: + /* Try to get RSDP from BIOS memory */ + if (Gbl_RsdpBase != NULL) { + physaddr = Gbl_RsdpBase; + mapsize = sizeof (ACPI_TABLE_RSDP); } else { - RsdpBase = ACPI_HI_RSDP_WINDOW_BASE; - RsdpSize = ACPI_HI_RSDP_WINDOW_SIZE; + physaddr = ACPI_HI_RSDP_WINDOW_BASE; + mapsize = ACPI_HI_RSDP_WINDOW_SIZE; } - RsdpAddress = AcpiOsMapMemory(RsdpBase, RsdpSize); - if (RsdpAddress == NULL) { + mapp = AcpiOsMapMemory(physaddr, mapsize); + if (mapp == NULL) return (OslGetLastStatus(AE_BAD_ADDRESS)); - } /* Search low memory for the RSDP */ - - MappedTable = ACPI_CAST_PTR(ACPI_TABLE_HEADER, - AcpiTbScanMemoryForRsdp(RsdpAddress, RsdpSize)); - if (MappedTable == NULL) { - AcpiOsUnmapMemory(RsdpAddress, RsdpSize); + tblp = ACPI_CAST_PTR(ACPI_TABLE_HEADER, + AcpiTbScanMemoryForRsdp(mapp, mapsize)); + if (tblp == NULL) { + AcpiOsUnmapMemory(mapp, mapsize); return (AE_NOT_FOUND); } - Gbl_RsdpAddress = RsdpBase + (ACPI_CAST8(MappedTable) - RsdpAddress); - - memcpy(&Gbl_Rsdp, MappedTable, sizeof (ACPI_TABLE_RSDP)); - AcpiOsUnmapMemory(RsdpAddress, RsdpSize); + physaddr += (ACPI_PHYSICAL_ADDRESS) ACPI_PTR_DIFF(tblp, mapp); + Gbl_RsdpAddress = physaddr; + memcpy(&Gbl_Rsdp, tblp, sizeof (ACPI_TABLE_RSDP)); + AcpiOsUnmapMemory(mapp, mapsize); return (AE_OK); } @@ -1013,5 +1053,5 @@ AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Size) offset = (ulong_t)LogicalAddress % pagesize; - (void)munmap(LogicalAddress - offset, Size + offset); + (void) munmap(LogicalAddress - offset, Size + offset); } diff --git a/usr/src/uts/i86pc/io/xsvc/xsvc.c b/usr/src/uts/i86pc/io/xsvc/xsvc.c index 1d0b9741b0..de3b727544 100644 --- a/usr/src/uts/i86pc/io/xsvc/xsvc.c +++ b/usr/src/uts/i86pc/io/xsvc/xsvc.c @@ -22,6 +22,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2016 Joyent, Inc. */ #include <sys/errno.h> @@ -807,7 +809,7 @@ xsvc_mnode_key_compare(const void *q, const void *e) /*ARGSUSED*/ static int xsvc_devmap(dev_t dev, devmap_cookie_t dhp, offset_t off, size_t len, - size_t *maplen, uint_t model) + size_t *maplen, uint_t model) { ddi_umem_cookie_t cookie; xsvc_state_t *state; @@ -874,6 +876,19 @@ xsvc_devmap(dev_t dev, devmap_cookie_t dhp, offset_t off, size_t len, kvai = kva; for (i = 0; i < npages; i++) { + page_t *pp = page_numtopp_nolock(pfn); + + /* + * Preemptively check for panic conditions from + * hat_devload and error out instead. + */ + if (pp != NULL && (PP_ISFREE(pp) || + (!PAGE_LOCKED(pp) && !PP_ISNORELOC(pp)))) { + err = DDI_FAILURE; + npages = i; + goto devmapfail_cookie_alloc; + } + hat_devload(kas.a_hat, kvai, PAGESIZE, pfn, PROT_READ | PROT_WRITE, HAT_LOAD_LOCK); pfn++; |
