1f86214b6SMitsuru IWASAKI /*- 2f86214b6SMitsuru IWASAKI * Copyright (c) 2001 Mitsuru IWASAKI 3f86214b6SMitsuru IWASAKI * All rights reserved. 4f86214b6SMitsuru IWASAKI * 5f86214b6SMitsuru IWASAKI * Redistribution and use in source and binary forms, with or without 6f86214b6SMitsuru IWASAKI * modification, are permitted provided that the following conditions 7f86214b6SMitsuru IWASAKI * are met: 8f86214b6SMitsuru IWASAKI * 1. Redistributions of source code must retain the above copyright 9f86214b6SMitsuru IWASAKI * notice, this list of conditions and the following disclaimer. 10f86214b6SMitsuru IWASAKI * 2. Redistributions in binary form must reproduce the above copyright 11f86214b6SMitsuru IWASAKI * notice, this list of conditions and the following disclaimer in the 12f86214b6SMitsuru IWASAKI * documentation and/or other materials provided with the distribution. 13f86214b6SMitsuru IWASAKI * 14f86214b6SMitsuru IWASAKI * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15f86214b6SMitsuru IWASAKI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16f86214b6SMitsuru IWASAKI * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17f86214b6SMitsuru IWASAKI * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18f86214b6SMitsuru IWASAKI * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19f86214b6SMitsuru IWASAKI * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20f86214b6SMitsuru IWASAKI * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21f86214b6SMitsuru IWASAKI * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22f86214b6SMitsuru IWASAKI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23f86214b6SMitsuru IWASAKI * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24f86214b6SMitsuru IWASAKI * SUCH DAMAGE. 25f86214b6SMitsuru IWASAKI */ 26f86214b6SMitsuru IWASAKI 2712ea2cfeSDavid E. O'Brien #include <sys/cdefs.h> 2812ea2cfeSDavid E. O'Brien __FBSDID("$FreeBSD$"); 2912ea2cfeSDavid E. O'Brien 30f86214b6SMitsuru IWASAKI #include <sys/param.h> 31f86214b6SMitsuru IWASAKI #include <sys/bus.h> 325217af30SJohn Baldwin #include <sys/kernel.h> 335217af30SJohn Baldwin #include <sys/module.h> 34c66d2b38SJung-uk Kim #include <sys/sysctl.h> 35d95e7f5aSJohn Baldwin #include <vm/vm.h> 36d95e7f5aSJohn Baldwin #include <vm/pmap.h> 37f86214b6SMitsuru IWASAKI 38129d3046SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 39d95e7f5aSJohn Baldwin #include <contrib/dev/acpica/include/accommon.h> 40d95e7f5aSJohn Baldwin #include <contrib/dev/acpica/include/actables.h> 41129d3046SJung-uk Kim 42f86214b6SMitsuru IWASAKI #include <dev/acpica/acpivar.h> 43f86214b6SMitsuru IWASAKI 445217af30SJohn Baldwin #include <machine/nexusvar.h> 455217af30SJohn Baldwin 46c66d2b38SJung-uk Kim SYSCTL_DECL(_debug_acpi); 47c66d2b38SJung-uk Kim 48d2b227cdSJung-uk Kim int acpi_resume_beep; 49c66d2b38SJung-uk Kim TUNABLE_INT("debug.acpi.resume_beep", &acpi_resume_beep); 50d2b227cdSJung-uk Kim SYSCTL_INT(_debug_acpi, OID_AUTO, resume_beep, CTLFLAG_RW, &acpi_resume_beep, 51c66d2b38SJung-uk Kim 0, "Beep the PC speaker when resuming"); 52d2b227cdSJung-uk Kim 53d2b227cdSJung-uk Kim int acpi_reset_video; 54c66d2b38SJung-uk Kim TUNABLE_INT("hw.acpi.reset_video", &acpi_reset_video); 55c66d2b38SJung-uk Kim 568848ad86SPeter Wemm static int intr_model = ACPI_INTR_PIC; 57c66d2b38SJung-uk Kim static struct apm_clone_data acpi_clone; 588848ad86SPeter Wemm 59f86214b6SMitsuru IWASAKI int 60f86214b6SMitsuru IWASAKI acpi_machdep_init(device_t dev) 61f86214b6SMitsuru IWASAKI { 62f86214b6SMitsuru IWASAKI struct acpi_softc *sc; 63f86214b6SMitsuru IWASAKI 64e8802274SPeter Wemm sc = devclass_get_softc(devclass_find("acpi"), 0); 65c66d2b38SJung-uk Kim 66c66d2b38SJung-uk Kim /* Create a fake clone for /dev/acpi. */ 67c66d2b38SJung-uk Kim STAILQ_INIT(&sc->apm_cdevs); 68c66d2b38SJung-uk Kim acpi_clone.cdev = sc->acpi_dev_t; 69c66d2b38SJung-uk Kim acpi_clone.acpi_sc = sc; 70c66d2b38SJung-uk Kim ACPI_LOCK(acpi); 71c66d2b38SJung-uk Kim STAILQ_INSERT_TAIL(&sc->apm_cdevs, &acpi_clone, entries); 72c66d2b38SJung-uk Kim ACPI_UNLOCK(acpi); 73c66d2b38SJung-uk Kim sc->acpi_clone = &acpi_clone; 74f86214b6SMitsuru IWASAKI acpi_install_wakeup_handler(sc); 75f86214b6SMitsuru IWASAKI 768848ad86SPeter Wemm if (intr_model != ACPI_INTR_PIC) 778848ad86SPeter Wemm acpi_SetIntrModel(intr_model); 788848ad86SPeter Wemm 79c66d2b38SJung-uk Kim SYSCTL_ADD_UINT(&sc->acpi_sysctl_ctx, 80c66d2b38SJung-uk Kim SYSCTL_CHILDREN(sc->acpi_sysctl_tree), OID_AUTO, 81c66d2b38SJung-uk Kim "reset_video", CTLFLAG_RW, &acpi_reset_video, 0, 82c66d2b38SJung-uk Kim "Call the VESA reset BIOS vector on the resume path"); 83c66d2b38SJung-uk Kim 84f86214b6SMitsuru IWASAKI return (0); 85f86214b6SMitsuru IWASAKI } 868848ad86SPeter Wemm 878848ad86SPeter Wemm void 888848ad86SPeter Wemm acpi_SetDefaultIntrModel(int model) 898848ad86SPeter Wemm { 908848ad86SPeter Wemm 918848ad86SPeter Wemm intr_model = model; 928848ad86SPeter Wemm } 931a26ea7fSNate Lawson 941a26ea7fSNate Lawson int 951a26ea7fSNate Lawson acpi_machdep_quirks(int *quirks) 961a26ea7fSNate Lawson { 971a26ea7fSNate Lawson return (0); 981a26ea7fSNate Lawson } 9931ad3b88SNate Lawson 10031ad3b88SNate Lawson void 10131ad3b88SNate Lawson acpi_cpu_c1() 10231ad3b88SNate Lawson { 10331ad3b88SNate Lawson __asm __volatile("sti; hlt"); 10431ad3b88SNate Lawson } 1055217af30SJohn Baldwin 1065217af30SJohn Baldwin /* 107d95e7f5aSJohn Baldwin * Support for mapping ACPI tables during early boot. Currently this 108d95e7f5aSJohn Baldwin * uses the crashdump map to map each table. However, the crashdump 109d95e7f5aSJohn Baldwin * map is created in pmap_bootstrap() right after the direct map, so 110d95e7f5aSJohn Baldwin * we should be able to just use pmap_mapbios() here instead. 111d95e7f5aSJohn Baldwin * 112d95e7f5aSJohn Baldwin * This makes the following assumptions about how we use this KVA: 113d95e7f5aSJohn Baldwin * pages 0 and 1 are used to map in the header of each table found via 114d95e7f5aSJohn Baldwin * the RSDT or XSDT and pages 2 to n are used to map in the RSDT or 115d95e7f5aSJohn Baldwin * XSDT. This has to use 2 pages for the table headers in case a 116d95e7f5aSJohn Baldwin * header spans a page boundary. 117d95e7f5aSJohn Baldwin * 118d95e7f5aSJohn Baldwin * XXX: We don't ensure the table fits in the available address space 119d95e7f5aSJohn Baldwin * in the crashdump map. 120d95e7f5aSJohn Baldwin */ 121d95e7f5aSJohn Baldwin 122d95e7f5aSJohn Baldwin /* 123d95e7f5aSJohn Baldwin * Map some memory using the crashdump map. 'offset' is an offset in 124d95e7f5aSJohn Baldwin * pages into the crashdump map to use for the start of the mapping. 125d95e7f5aSJohn Baldwin */ 126d95e7f5aSJohn Baldwin static void * 127d95e7f5aSJohn Baldwin table_map(vm_paddr_t pa, int offset, vm_offset_t length) 128d95e7f5aSJohn Baldwin { 129d95e7f5aSJohn Baldwin vm_offset_t va, off; 130d95e7f5aSJohn Baldwin void *data; 131d95e7f5aSJohn Baldwin 132d95e7f5aSJohn Baldwin off = pa & PAGE_MASK; 133d95e7f5aSJohn Baldwin length = roundup(length + off, PAGE_SIZE); 134d95e7f5aSJohn Baldwin pa = pa & PG_FRAME; 135d95e7f5aSJohn Baldwin va = (vm_offset_t)pmap_kenter_temporary(pa, offset) + 136d95e7f5aSJohn Baldwin (offset * PAGE_SIZE); 137d95e7f5aSJohn Baldwin data = (void *)(va + off); 138d95e7f5aSJohn Baldwin length -= PAGE_SIZE; 139d95e7f5aSJohn Baldwin while (length > 0) { 140d95e7f5aSJohn Baldwin va += PAGE_SIZE; 141d95e7f5aSJohn Baldwin pa += PAGE_SIZE; 142d95e7f5aSJohn Baldwin length -= PAGE_SIZE; 143d95e7f5aSJohn Baldwin pmap_kenter(va, pa); 144d95e7f5aSJohn Baldwin invlpg(va); 145d95e7f5aSJohn Baldwin } 146d95e7f5aSJohn Baldwin return (data); 147d95e7f5aSJohn Baldwin } 148d95e7f5aSJohn Baldwin 149d95e7f5aSJohn Baldwin /* Unmap memory previously mapped with table_map(). */ 150d95e7f5aSJohn Baldwin static void 151d95e7f5aSJohn Baldwin table_unmap(void *data, vm_offset_t length) 152d95e7f5aSJohn Baldwin { 153d95e7f5aSJohn Baldwin vm_offset_t va, off; 154d95e7f5aSJohn Baldwin 155d95e7f5aSJohn Baldwin va = (vm_offset_t)data; 156d95e7f5aSJohn Baldwin off = va & PAGE_MASK; 157d95e7f5aSJohn Baldwin length = roundup(length + off, PAGE_SIZE); 158d95e7f5aSJohn Baldwin va &= ~PAGE_MASK; 159d95e7f5aSJohn Baldwin while (length > 0) { 160d95e7f5aSJohn Baldwin pmap_kremove(va); 161d95e7f5aSJohn Baldwin invlpg(va); 162d95e7f5aSJohn Baldwin va += PAGE_SIZE; 163d95e7f5aSJohn Baldwin length -= PAGE_SIZE; 164d95e7f5aSJohn Baldwin } 165d95e7f5aSJohn Baldwin } 166d95e7f5aSJohn Baldwin 167d95e7f5aSJohn Baldwin /* 168d95e7f5aSJohn Baldwin * Map a table at a given offset into the crashdump map. It first 169d95e7f5aSJohn Baldwin * maps the header to determine the table length and then maps the 170d95e7f5aSJohn Baldwin * entire table. 171d95e7f5aSJohn Baldwin */ 172d95e7f5aSJohn Baldwin static void * 173d95e7f5aSJohn Baldwin map_table(vm_paddr_t pa, int offset, const char *sig) 174d95e7f5aSJohn Baldwin { 175d95e7f5aSJohn Baldwin ACPI_TABLE_HEADER *header; 176d95e7f5aSJohn Baldwin vm_offset_t length; 177d95e7f5aSJohn Baldwin void *table; 178d95e7f5aSJohn Baldwin 179d95e7f5aSJohn Baldwin header = table_map(pa, offset, sizeof(ACPI_TABLE_HEADER)); 180d95e7f5aSJohn Baldwin if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) { 181d95e7f5aSJohn Baldwin table_unmap(header, sizeof(ACPI_TABLE_HEADER)); 182d95e7f5aSJohn Baldwin return (NULL); 183d95e7f5aSJohn Baldwin } 184d95e7f5aSJohn Baldwin length = header->Length; 185d95e7f5aSJohn Baldwin table_unmap(header, sizeof(ACPI_TABLE_HEADER)); 186d95e7f5aSJohn Baldwin table = table_map(pa, offset, length); 187d95e7f5aSJohn Baldwin if (ACPI_FAILURE(AcpiTbChecksum(table, length))) { 188d95e7f5aSJohn Baldwin if (bootverbose) 189d95e7f5aSJohn Baldwin printf("ACPI: Failed checksum for table %s\n", sig); 190d95e7f5aSJohn Baldwin table_unmap(table, length); 191d95e7f5aSJohn Baldwin return (NULL); 192d95e7f5aSJohn Baldwin } 193d95e7f5aSJohn Baldwin return (table); 194d95e7f5aSJohn Baldwin } 195d95e7f5aSJohn Baldwin 196d95e7f5aSJohn Baldwin /* 197d95e7f5aSJohn Baldwin * See if a given ACPI table is the requested table. Returns the 198d95e7f5aSJohn Baldwin * length of the able if it matches or zero on failure. 199d95e7f5aSJohn Baldwin */ 200d95e7f5aSJohn Baldwin static int 201d95e7f5aSJohn Baldwin probe_table(vm_paddr_t address, const char *sig) 202d95e7f5aSJohn Baldwin { 203d95e7f5aSJohn Baldwin ACPI_TABLE_HEADER *table; 204d95e7f5aSJohn Baldwin 205d95e7f5aSJohn Baldwin table = table_map(address, 0, sizeof(ACPI_TABLE_HEADER)); 206d95e7f5aSJohn Baldwin if (table == NULL) { 207d95e7f5aSJohn Baldwin if (bootverbose) 208d95e7f5aSJohn Baldwin printf("ACPI: Failed to map table at 0x%jx\n", 209d95e7f5aSJohn Baldwin (uintmax_t)address); 210d95e7f5aSJohn Baldwin return (0); 211d95e7f5aSJohn Baldwin } 212d95e7f5aSJohn Baldwin if (bootverbose) 213d95e7f5aSJohn Baldwin printf("Table '%.4s' at 0x%jx\n", table->Signature, 214d95e7f5aSJohn Baldwin (uintmax_t)address); 215d95e7f5aSJohn Baldwin 216d95e7f5aSJohn Baldwin if (strncmp(table->Signature, sig, ACPI_NAME_SIZE) != 0) { 217d95e7f5aSJohn Baldwin table_unmap(table, sizeof(ACPI_TABLE_HEADER)); 218d95e7f5aSJohn Baldwin return (0); 219d95e7f5aSJohn Baldwin } 220d95e7f5aSJohn Baldwin table_unmap(table, sizeof(ACPI_TABLE_HEADER)); 221d95e7f5aSJohn Baldwin return (1); 222d95e7f5aSJohn Baldwin } 223d95e7f5aSJohn Baldwin 224d95e7f5aSJohn Baldwin /* 225d95e7f5aSJohn Baldwin * Try to map a table at a given physical address previously returned 226d95e7f5aSJohn Baldwin * by acpi_find_table(). 227d95e7f5aSJohn Baldwin */ 228d95e7f5aSJohn Baldwin void * 229d95e7f5aSJohn Baldwin acpi_map_table(vm_paddr_t pa, const char *sig) 230d95e7f5aSJohn Baldwin { 231d95e7f5aSJohn Baldwin 232d95e7f5aSJohn Baldwin return (map_table(pa, 0, sig)); 233d95e7f5aSJohn Baldwin } 234d95e7f5aSJohn Baldwin 235d95e7f5aSJohn Baldwin /* Unmap a table previously mapped via acpi_map_table(). */ 236d95e7f5aSJohn Baldwin void 237d95e7f5aSJohn Baldwin acpi_unmap_table(void *table) 238d95e7f5aSJohn Baldwin { 239d95e7f5aSJohn Baldwin ACPI_TABLE_HEADER *header; 240d95e7f5aSJohn Baldwin 241d95e7f5aSJohn Baldwin header = (ACPI_TABLE_HEADER *)table; 242d95e7f5aSJohn Baldwin table_unmap(table, header->Length); 243d95e7f5aSJohn Baldwin } 244d95e7f5aSJohn Baldwin 245d95e7f5aSJohn Baldwin /* 246d95e7f5aSJohn Baldwin * Return the physical address of the requested table or zero if one 247d95e7f5aSJohn Baldwin * is not found. 248d95e7f5aSJohn Baldwin */ 249d95e7f5aSJohn Baldwin vm_paddr_t 250d95e7f5aSJohn Baldwin acpi_find_table(const char *sig) 251d95e7f5aSJohn Baldwin { 252d95e7f5aSJohn Baldwin ACPI_PHYSICAL_ADDRESS rsdp_ptr; 253d95e7f5aSJohn Baldwin ACPI_TABLE_RSDP *rsdp; 254d95e7f5aSJohn Baldwin ACPI_TABLE_RSDT *rsdt; 255d95e7f5aSJohn Baldwin ACPI_TABLE_XSDT *xsdt; 256d95e7f5aSJohn Baldwin ACPI_TABLE_HEADER *table; 257d95e7f5aSJohn Baldwin vm_paddr_t addr; 258d95e7f5aSJohn Baldwin int i, count; 259d95e7f5aSJohn Baldwin 260d95e7f5aSJohn Baldwin if (resource_disabled("acpi", 0)) 261d95e7f5aSJohn Baldwin return (0); 262d95e7f5aSJohn Baldwin 263d95e7f5aSJohn Baldwin /* 264d95e7f5aSJohn Baldwin * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn 265d95e7f5aSJohn Baldwin * calls pmap_mapbios() to find the RSDP, we assume that we can use 266d95e7f5aSJohn Baldwin * pmap_mapbios() to map the RSDP. 267d95e7f5aSJohn Baldwin */ 268d95e7f5aSJohn Baldwin if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0) 269d95e7f5aSJohn Baldwin return (0); 270d95e7f5aSJohn Baldwin rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP)); 271d95e7f5aSJohn Baldwin if (rsdp == NULL) { 272d95e7f5aSJohn Baldwin if (bootverbose) 273d95e7f5aSJohn Baldwin printf("ACPI: Failed to map RSDP\n"); 274d95e7f5aSJohn Baldwin return (0); 275d95e7f5aSJohn Baldwin } 276d95e7f5aSJohn Baldwin 277d95e7f5aSJohn Baldwin /* 278d95e7f5aSJohn Baldwin * For ACPI >= 2.0, use the XSDT if it is available. 279d95e7f5aSJohn Baldwin * Otherwise, use the RSDT. We map the XSDT or RSDT at page 2 280d95e7f5aSJohn Baldwin * in the crashdump area. Pages 0 and 1 are used to map in the 281d95e7f5aSJohn Baldwin * headers of candidate ACPI tables. 282d95e7f5aSJohn Baldwin */ 283d95e7f5aSJohn Baldwin addr = 0; 284d95e7f5aSJohn Baldwin if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) { 285d95e7f5aSJohn Baldwin /* 286d95e7f5aSJohn Baldwin * AcpiOsGetRootPointer only verifies the checksum for 287d95e7f5aSJohn Baldwin * the version 1.0 portion of the RSDP. Version 2.0 has 288d95e7f5aSJohn Baldwin * an additional checksum that we verify first. 289d95e7f5aSJohn Baldwin */ 290d95e7f5aSJohn Baldwin if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) { 291d95e7f5aSJohn Baldwin if (bootverbose) 292d95e7f5aSJohn Baldwin printf("ACPI: RSDP failed extended checksum\n"); 293d95e7f5aSJohn Baldwin return (0); 294d95e7f5aSJohn Baldwin } 295d95e7f5aSJohn Baldwin xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT); 296d95e7f5aSJohn Baldwin if (xsdt == NULL) { 297d95e7f5aSJohn Baldwin if (bootverbose) 298d95e7f5aSJohn Baldwin printf("ACPI: Failed to map XSDT\n"); 299d95e7f5aSJohn Baldwin return (0); 300d95e7f5aSJohn Baldwin } 301d95e7f5aSJohn Baldwin count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) / 302d95e7f5aSJohn Baldwin sizeof(UINT64); 303d95e7f5aSJohn Baldwin for (i = 0; i < count; i++) 304d95e7f5aSJohn Baldwin if (probe_table(xsdt->TableOffsetEntry[i], sig)) { 305d95e7f5aSJohn Baldwin addr = xsdt->TableOffsetEntry[i]; 306d95e7f5aSJohn Baldwin break; 307d95e7f5aSJohn Baldwin } 308d95e7f5aSJohn Baldwin acpi_unmap_table(xsdt); 309d95e7f5aSJohn Baldwin } else { 310d95e7f5aSJohn Baldwin rsdt = map_table(rsdp->RsdtPhysicalAddress, 2, ACPI_SIG_RSDT); 311d95e7f5aSJohn Baldwin if (rsdt == NULL) { 312d95e7f5aSJohn Baldwin if (bootverbose) 313d95e7f5aSJohn Baldwin printf("ACPI: Failed to map RSDT\n"); 314d95e7f5aSJohn Baldwin return (0); 315d95e7f5aSJohn Baldwin } 316d95e7f5aSJohn Baldwin count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) / 317d95e7f5aSJohn Baldwin sizeof(UINT32); 318d95e7f5aSJohn Baldwin for (i = 0; i < count; i++) 319d95e7f5aSJohn Baldwin if (probe_table(rsdt->TableOffsetEntry[i], sig)) { 320d95e7f5aSJohn Baldwin addr = rsdt->TableOffsetEntry[i]; 321d95e7f5aSJohn Baldwin break; 322d95e7f5aSJohn Baldwin } 323d95e7f5aSJohn Baldwin acpi_unmap_table(rsdt); 324d95e7f5aSJohn Baldwin } 325d95e7f5aSJohn Baldwin pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); 326d95e7f5aSJohn Baldwin if (addr == 0) { 327d95e7f5aSJohn Baldwin if (bootverbose) 328d95e7f5aSJohn Baldwin printf("ACPI: No %s table found\n", sig); 329d95e7f5aSJohn Baldwin return (0); 330d95e7f5aSJohn Baldwin } 331d95e7f5aSJohn Baldwin if (bootverbose) 332d95e7f5aSJohn Baldwin printf("%s: Found table at 0x%jx\n", sig, (uintmax_t)addr); 333d95e7f5aSJohn Baldwin 334d95e7f5aSJohn Baldwin /* 335d95e7f5aSJohn Baldwin * Verify that we can map the full table and that its checksum is 336d95e7f5aSJohn Baldwin * correct, etc. 337d95e7f5aSJohn Baldwin */ 338d95e7f5aSJohn Baldwin table = map_table(addr, 0, sig); 339d95e7f5aSJohn Baldwin if (table == NULL) 340d95e7f5aSJohn Baldwin return (0); 341d95e7f5aSJohn Baldwin acpi_unmap_table(table); 342d95e7f5aSJohn Baldwin 343d95e7f5aSJohn Baldwin return (addr); 344d95e7f5aSJohn Baldwin } 345d95e7f5aSJohn Baldwin 346d95e7f5aSJohn Baldwin /* 3475217af30SJohn Baldwin * ACPI nexus(4) driver. 3485217af30SJohn Baldwin */ 3495217af30SJohn Baldwin static int 3505217af30SJohn Baldwin nexus_acpi_probe(device_t dev) 3515217af30SJohn Baldwin { 3525217af30SJohn Baldwin int error; 3535217af30SJohn Baldwin 3545217af30SJohn Baldwin error = acpi_identify(); 3555217af30SJohn Baldwin if (error) 3565217af30SJohn Baldwin return (error); 3575217af30SJohn Baldwin 3585217af30SJohn Baldwin return (BUS_PROBE_DEFAULT); 3595217af30SJohn Baldwin } 3605217af30SJohn Baldwin 3615217af30SJohn Baldwin static int 3625217af30SJohn Baldwin nexus_acpi_attach(device_t dev) 3635217af30SJohn Baldwin { 3645217af30SJohn Baldwin 3655217af30SJohn Baldwin nexus_init_resources(); 3665217af30SJohn Baldwin bus_generic_probe(dev); 3675217af30SJohn Baldwin if (BUS_ADD_CHILD(dev, 10, "acpi", 0) == NULL) 3685217af30SJohn Baldwin panic("failed to add acpi0 device"); 3695217af30SJohn Baldwin 3705217af30SJohn Baldwin return (bus_generic_attach(dev)); 3715217af30SJohn Baldwin } 3725217af30SJohn Baldwin 3735217af30SJohn Baldwin static device_method_t nexus_acpi_methods[] = { 3745217af30SJohn Baldwin /* Device interface */ 3755217af30SJohn Baldwin DEVMETHOD(device_probe, nexus_acpi_probe), 3765217af30SJohn Baldwin DEVMETHOD(device_attach, nexus_acpi_attach), 3775217af30SJohn Baldwin 3785217af30SJohn Baldwin { 0, 0 } 3795217af30SJohn Baldwin }; 3805217af30SJohn Baldwin 3815217af30SJohn Baldwin DEFINE_CLASS_1(nexus, nexus_acpi_driver, nexus_acpi_methods, 1, nexus_driver); 3825217af30SJohn Baldwin static devclass_t nexus_devclass; 3835217af30SJohn Baldwin 3845217af30SJohn Baldwin DRIVER_MODULE(nexus_acpi, root, nexus_acpi_driver, nexus_devclass, 0, 0); 385