diff options
author | Jordan Hargrave <jordan@cvs.openbsd.org> | 2006-01-19 00:08:47 +0000 |
---|---|---|
committer | Jordan Hargrave <jordan@cvs.openbsd.org> | 2006-01-19 00:08:47 +0000 |
commit | 97fbdf7f13b5ad1043c40b5ca7cc312a14c85420 (patch) | |
tree | 4127c3ce64f8cbedeba5882e1bf747c585e0e889 /sys/dev/acpi | |
parent | 25cf9c89d6e1cebddc1b115c8b0e14ef9d6e5295 (diff) |
Added support for read/write of PCI Config space
Help jason@
ok marco@
Diffstat (limited to 'sys/dev/acpi')
-rw-r--r-- | sys/dev/acpi/acpi.c | 62 | ||||
-rw-r--r-- | sys/dev/acpi/acpireg.h | 11 |
2 files changed, 71 insertions, 2 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index c078719f397..f961c0d713b 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi.c,v 1.21 2006/01/18 22:25:44 jordan Exp $ */ +/* $OpenBSD: acpi.c,v 1.22 2006/01/19 00:08:46 jordan Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> @@ -29,6 +29,7 @@ #include <machine/conf.h> #include <machine/bus.h> +#include <dev/pci/pcivar.h> #include <dev/acpi/acpireg.h> #include <dev/acpi/acpivar.h> #include <dev/acpi/amltypes.h> @@ -91,6 +92,9 @@ acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address, void *pb; bus_space_handle_t ioh; struct acpi_mem_map mh; + pci_chipset_tag_t pc; + pcitag_t tag; + int reg, idx, ival, sval; switch (iospace) { case GAS_SYSTEM_MEMORY: @@ -142,6 +146,62 @@ acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address, break; case GAS_PCI_CFG_SPACE: + /* format of address: + * bits 00..15 = register + * bits 16..31 = function + * bits 32..47 = device + * bits 48..63 = bus + */ + pc = NULL; + pb = buffer; + tag = pci_make_tag(pc, + ACPI_PCI_BUS(address), + ACPI_PCI_DEV(address), + ACPI_PCI_FN(address)); + + /* XXX: This is ugly.. read-modify-write does a byte at a time */ + reg = ACPI_PCI_REG(address); + for (idx=reg; idx<reg+len; idx++) { + ival = pci_conf_read(pc, tag, idx & ~0x3); + if (iodir == ACPI_IOREAD) { + switch (idx & 0x3) { + case 0: + *(u_int8_t *)pb = ival; + break; + case 1: + *(u_int8_t *)pb = (ival >> 8); + break; + case 2: + *(u_int8_t *)pb = (ival >> 16); + break; + case 3: + *(u_int8_t *)pb = (ival >> 24); + break; + } + } + else { + sval = *(uint8_t *)pb; + switch (idx & 0x3) { + case 0: + ival &= ~0xFF; + ival |= sval; + break; + case 1: + ival &= ~0xFF00; + ival |= (sval << 8L); + break; + case 2: + ival &= ~0xFF0000; + ival |= (sval << 16L); + break; + case 3: + ival &= ~0xFF000000L; + ival |= (sval << 24L); + break; + } + } + pb++; + } break; } } diff --git a/sys/dev/acpi/acpireg.h b/sys/dev/acpi/acpireg.h index 528d3d1dd5f..8f0ef03a375 100644 --- a/sys/dev/acpi/acpireg.h +++ b/sys/dev/acpi/acpireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: acpireg.h,v 1.8 2006/01/06 16:22:46 grange Exp $ */ +/* $OpenBSD: acpireg.h,v 1.9 2006/01/19 00:08:46 jordan Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * Copyright (c) 2005 Marco Peereboom <marco@opebsd.org> @@ -399,6 +399,15 @@ struct acpi_facs { #define ACPI_FREQUENCY 3579545 /* Per ACPI spec */ /* + * PCI Configuration space + */ +#define ACPI_PCI_BUS(addr) (u_int16_t)((addr) >> 48) +#define ACPI_PCI_DEV(addr) (u_int16_t)((addr) >> 32) +#define ACPI_PCI_FN(addr) (u_int16_t)((addr) >> 16) +#define ACPI_PCI_REG(addr) (u_int16_t)(addr) +#define ACPI_PCI_ADDR(b,d,f,r) ((u_int64_t)(b)<<48LL | (u_int64_t)(d)<<32LL | (f)<<16LL | (r)) + +/* * PM1 Status Registers Fixed Hardware Feature Status Bits */ #define ACPI_PM1_STATUS 0x00 |