diff options
author | Thorsten Lockert <tholo@cvs.openbsd.org> | 2005-06-02 20:09:40 +0000 |
---|---|---|
committer | Thorsten Lockert <tholo@cvs.openbsd.org> | 2005-06-02 20:09:40 +0000 |
commit | c2b861c0e32dd295ee7538db6b2aac4dd7c87de2 (patch) | |
tree | 7da2e9ae4792b3d3765f32971ba6c6c0ad4de685 /sys/arch/amd64 | |
parent | 204533b59784a2ed890ea3c6aad96531b3989704 (diff) |
Start on a basic ACPI framework -- does not do much more than read out the
ACPI tables into kernel memory and attach ACPI and HPET timers currently.
In order to test this code, enabling the devices in GENERIC as well as
the ACPI_ENABLE option is needed. This code does not do any thermal
control yet, so this should be done with care depending on the platform.
In the tree so more people can contribute to making this more fully
featured.
Ok niklas@ grange@ tedu@
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r-- | sys/arch/amd64/amd64/acpi_machdep.c | 154 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/conf.c | 4 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/machdep.c | 16 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/mainbus.c | 24 | ||||
-rw-r--r-- | sys/arch/amd64/conf/GENERIC | 9 | ||||
-rw-r--r-- | sys/arch/amd64/conf/files.amd64 | 8 | ||||
-rw-r--r-- | sys/arch/amd64/include/conf.h | 9 |
7 files changed, 212 insertions, 12 deletions
diff --git a/sys/arch/amd64/amd64/acpi_machdep.c b/sys/arch/amd64/amd64/acpi_machdep.c new file mode 100644 index 00000000000..c9596fe5368 --- /dev/null +++ b/sys/arch/amd64/amd64/acpi_machdep.c @@ -0,0 +1,154 @@ +/* $OpenBSD: acpi_machdep.c,v 1.1 2005/06/02 20:09:38 tholo Exp $ */ +/* + * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/malloc.h> + +#include <uvm/uvm_extern.h> + +#include <machine/bus.h> +#include <machine/biosvar.h> + +#include <dev/isa/isareg.h> +#include <dev/acpi/acpireg.h> +#include <dev/acpi/acpivar.h> + +#define ACPI_BIOS_RSDP_WINDOW_BASE 0xe0000 +#define ACPI_BIOS_RSDP_WINDOW_SIZE 0x20000 + +u_int8_t *acpi_scan(struct acpi_mem_map *, paddr_t, size_t); + +int +acpi_map(paddr_t pa, size_t len, struct acpi_mem_map *handle) +{ + paddr_t pgpa = x86_trunc_page(pa); + paddr_t endpa = x86_round_page(pa + len); + vaddr_t va = uvm_km_valloc(kernel_map, endpa - pgpa); + + if (va == 0) + return (ENOMEM); + + handle->baseva = va; + handle->va = (u_int8_t *)(va + (pa & PGOFSET)); + handle->vsize = endpa - pgpa; + handle->pa = pa; + + do { + pmap_kenter_pa(va, pgpa, VM_PROT_READ); + va += NBPG; + pgpa += NBPG; + } while (pgpa < endpa); + + return 0; +} + +void +acpi_unmap(struct acpi_mem_map *handle) +{ + pmap_kremove(handle->baseva, handle->vsize); + uvm_km_free(kernel_map, handle->baseva, handle->vsize); +} + +u_int8_t * +acpi_scan(struct acpi_mem_map *handle, paddr_t pa, size_t len) +{ + size_t i; + u_int8_t *ptr; + struct acpi_rsdp1 *rsdp; + + if (acpi_map(pa, len, handle)) + return (NULL); + for (ptr = handle->va, i = 0; + i < len; + ptr += 16, i += 16) + if (memcmp(ptr, RSDP_SIG, sizeof(RSDP_SIG) - 1) == 0) { + rsdp = (struct acpi_rsdp1 *)ptr; + /* + * Only checksum whichever portion of the + * RSDP that is actually present + */ + if (rsdp->revision == 0 && + acpi_checksum(ptr, sizeof(struct acpi_rsdp1)) == 0) + return (ptr); + else if (rsdp->revision == 2 && + acpi_checksum(ptr, sizeof(struct acpi_rsdp)) == 0) + return (ptr); + } + acpi_unmap(handle); + + return (NULL); +} + +int +acpi_probe(struct device *parent, struct cfdata *match, struct acpi_attach_args *aaa) +{ + struct acpi_mem_map handle; + u_int8_t *ptr; + paddr_t ebda; + bios_memmap_t *im; + + /* + * First look for ACPI entries in the BIOS memory map + */ + for (im = bios_memmap; im->type != BIOS_MAP_END; im++) + if (im->type == BIOS_MAP_ACPI) { + if ((ptr = acpi_scan(&handle, im->addr, im->size))) + goto havebase; + } + + /* + * Next try to find ACPI table entries in the EBDA + */ + if (acpi_map(0, NBPG, &handle)) + printf("acpi: failed to map BIOS data area\n"); + else { + ebda = *(const u_int16_t *)(&handle.va[0x40e]); + ebda <<= 4; + acpi_unmap(&handle); + + if (ebda && ebda < IOM_BEGIN) { + if ((ptr = acpi_scan(&handle, ebda, 1024))) + goto havebase; + } + } + + /* + * Finally try to find the ACPI table entries in the + * BIOS memory + */ + if ((ptr = acpi_scan(&handle, ACPI_BIOS_RSDP_WINDOW_BASE, + ACPI_BIOS_RSDP_WINDOW_SIZE))) + goto havebase; + + return (0); + +havebase: + aaa->aaa_pbase = ptr - handle.va + handle.pa; + acpi_unmap(&handle); + + return (1); +} + +void +acpi_attach_machdep(struct acpi_softc *sc) +{ + sc->sc_interrupt = intr_establish(sc->sc_fadt->sci_int, &i8259_pic, sc->sc_fadt->sci_int, + IST_LEVEL, IPL_TTY, acpi_interrupt, sc, "acpi"); +} diff --git a/sys/arch/amd64/amd64/conf.c b/sys/arch/amd64/amd64/conf.c index ffa6fb787c9..d2fa2a4e57d 100644 --- a/sys/arch/amd64/amd64/conf.c +++ b/sys/arch/amd64/amd64/conf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.c,v 1.6 2004/05/30 08:11:26 grange Exp $ */ +/* $OpenBSD: conf.c,v 1.7 2005/06/02 20:09:38 tholo Exp $ */ /* * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. @@ -159,6 +159,7 @@ cdev_decl(mcd); #include "midi.h" #include "sequencer.h" cdev_decl(music); +#include "acpi.h" #include "iop.h" #ifdef XFS #include <xfs/nxfs.h> @@ -297,6 +298,7 @@ struct cdevsw cdevsw[] = cdev_notdef(), /* 80: gpr? XXX */ cdev_ptm_init(NPTY,ptm), /* 81: pseudo-tty ptm device */ cdev_hotplug_init(NHOTPLUG,hotplug), /* 82: devices hot plugging */ + cdev_acpi_init(NACPI,acpi), /* 83: ACPI */ }; int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]); diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index 7ce605412d7..cdd4ffa0843 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.30 2004/08/03 00:56:22 art Exp $ */ +/* $OpenBSD: machdep.c,v 1.31 2005/06/02 20:09:38 tholo Exp $ */ /* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */ /*- @@ -131,16 +131,22 @@ #include <dev/isa/isareg.h> #include <machine/isa_machdep.h> #include <dev/ic/i8042reg.h> +#include <dev/acpi/acpivar.h> #ifdef DDB #include <machine/db_machdep.h> #include <ddb/db_extern.h> #endif +#include "acpi.h" #include "isa.h" #include "isadma.h" #include "ksyms.h" +#if NACPI > 0 +extern struct acpi_softc *acpi_softc; +#endif + /* the following is used externally (sysctl_hw) */ char machine[] = "amd64"; /* cpu "architecture" */ char machine_arch[] = "amd64"; /* machine == machine_arch */ @@ -893,9 +899,11 @@ haltsys: if (howto & RB_HALT) { if (howto & RB_POWERDOWN) { #if NACPI > 0 - delay(500000); - acpi_enter_sleep_state(acpi_softc, ACPI_STATE_S5); - printf("WARNING: powerdown failed!\n"); + if (acpi_softc) { + delay(500000); + acpi_enter_sleep_state(acpi_softc, ACPI_STATE_S5); + printf("WARNING: powerdown failed!\n"); + } #endif } diff --git a/sys/arch/amd64/amd64/mainbus.c b/sys/arch/amd64/amd64/mainbus.c index e4c5e6d32fd..8625cb64de5 100644 --- a/sys/arch/amd64/amd64/mainbus.c +++ b/sys/arch/amd64/amd64/mainbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mainbus.c,v 1.1 2004/01/28 01:39:39 mickey Exp $ */ +/* $OpenBSD: mainbus.c,v 1.2 2005/06/02 20:09:38 tholo Exp $ */ /* $NetBSD: mainbus.c,v 1.1 2003/04/26 18:39:29 fvdl Exp $ */ /* @@ -44,14 +44,16 @@ #include "pci.h" #include "isa.h" +#include "acpi.h" #include <machine/cpuvar.h> #include <machine/i82093var.h> #include <machine/mpbiosvar.h> -/* - * XXXfvdl ACPI - */ +#if NACPI > 0 +#include <dev/acpi/acpireg.h> +#include <dev/acpi/acpivar.h> +#endif int mainbus_match(struct device *, void *, void *); void mainbus_attach(struct device *, struct device *, void *); @@ -72,6 +74,9 @@ union mainbus_attach_args { struct isabus_attach_args mba_iba; struct cpu_attach_args mba_caa; struct apic_attach_args aaa_caa; +#if NACPI > 0 + struct acpi_attach_args mba_aaa; +#endif }; /* @@ -131,6 +136,17 @@ mainbus_attach(parent, self, aux) printf("\n"); +#if NACPI > 0 + { + memset(&mba.mba_aaa, 0, sizeof(mba.mba_aaa)); + mba.mba_aaa.aaa_name = "acpi"; + mba.mba_aaa.aaa_iot = X86_BUS_SPACE_IO; + mba.mba_aaa.aaa_memt = X86_BUS_SPACE_MEM; + + config_found(self, &mba.mba_aaa, mainbus_print); + } +#endif + #ifdef MPBIOS mpbios_present = mpbios_probe(self); #endif diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC index c213f546627..8d9be42b133 100644 --- a/sys/arch/amd64/conf/GENERIC +++ b/sys/arch/amd64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.70 2005/05/27 06:36:23 jason Exp $ +# $OpenBSD: GENERIC,v 1.71 2005/06/02 20:09:39 tholo Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -41,6 +41,13 @@ isa0 at mainbus0 #isa0 at pcib? pci* at mainbus0 +#acpi0 at mainbus? +#acpitimer* at acpi? +#hpet* at acpi? + +#option ACPIVERBOSE +#option ACPI_ENABLE + option PCIVERBOSE option USBVERBOSE diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64 index e77341ac1b3..f45e713e16f 100644 --- a/sys/arch/amd64/conf/files.amd64 +++ b/sys/arch/amd64/conf/files.amd64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.amd64,v 1.11 2005/05/27 06:28:41 jason Exp $ +# $OpenBSD: files.amd64,v 1.12 2005/06/02 20:09:39 tholo Exp $ maxpartitions 16 maxusers 2 16 128 @@ -142,6 +142,12 @@ file dev/isa/fd.c fd needs-flag include "dev/usb/files.usb" # +# ACPI +# +include "../../../dev/acpi/files.acpi" +file arch/amd64/amd64/acpi_machdep.c acpi + +# # device major numbers # diff --git a/sys/arch/amd64/include/conf.h b/sys/arch/amd64/include/conf.h index 0eeee30a029..688c8eda04d 100644 --- a/sys/arch/amd64/include/conf.h +++ b/sys/arch/amd64/include/conf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.h,v 1.1 2004/01/28 01:39:39 mickey Exp $ */ +/* $OpenBSD: conf.h,v 1.2 2005/06/02 20:09:39 tholo Exp $ */ /* $NetBSD: conf.h,v 1.2 1996/05/05 19:28:34 christos Exp $ */ /* @@ -43,3 +43,10 @@ cdev_decl(spkr); #define biosselect seltrue cdev_decl(bios); + +#define cdev_acpi_init(c,n) {\ + dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \ + (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \ + (dev_type_stop((*))) enodev, 0, (dev_type_poll((*))) enodev, \ + (dev_type_mmap((*))) enodev, D_KQFILTER, dev_init(c,n,kqfilter) } +cdev_decl(acpi); |