diff options
author | dfr <dfr@FreeBSD.org> | 2000-08-28 21:48:13 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 2000-08-28 21:48:13 +0000 |
commit | dd8b44b3958fa67d802cbbec7c7d82f7fb476229 (patch) | |
tree | 61496c144b3ecd15192a2e07e755754e18346bc9 /sys/alpha/pci/t2_pci.c | |
parent | 9ed8ded4d312c58a27de9402fd9802e78a591cb9 (diff) | |
download | FreeBSD-src-dd8b44b3958fa67d802cbbec7c7d82f7fb476229.zip FreeBSD-src-dd8b44b3958fa67d802cbbec7c7d82f7fb476229.tar.gz |
* Completely rewrite the alpha busspace to hide the implementation from
the drivers.
* Remove legacy inx/outx support from chipset and replace with macros
which call busspace.
* Rework pci config accesses to route through the pcib device instead of
calling a MD function directly.
With these changes it is possible to cleanly support machines which have
more than one independantly numbered PCI busses. As a bonus, the new
busspace implementation should be measurably faster than the old one.
Diffstat (limited to 'sys/alpha/pci/t2_pci.c')
-rw-r--r-- | sys/alpha/pci/t2_pci.c | 114 |
1 files changed, 113 insertions, 1 deletions
diff --git a/sys/alpha/pci/t2_pci.c b/sys/alpha/pci/t2_pci.c index 2213bb3..5d3eb21 100644 --- a/sys/alpha/pci/t2_pci.c +++ b/sys/alpha/pci/t2_pci.c @@ -34,6 +34,15 @@ #include <machine/bus.h> #include <sys/rman.h> #include <pci/pcivar.h> +#include <machine/swiz.h> + +#include <alpha/pci/t2reg.h> +#include <alpha/pci/t2var.h> + +#include "alphapci_if.h" +#include "pcib_if.h" + +#define KV(pa) ALPHA_PHYS_TO_K0SEG(pa) static devclass_t pcib_devclass; @@ -53,13 +62,108 @@ t2_pcib_probe(device_t dev) static int t2_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result) { - if (which == PCIB_IVAR_HOSE) { + if (which == PCIB_IVAR_BUS) { *result = 0; return 0; } return ENOENT; } +static void * +t2_pcib_cvt_dense(device_t dev, vm_offset_t addr) +{ + addr &= 0xffffffffUL; + return (void *) KV(addr | T2_PCI_DENSE); +} + +static int +t2_pcib_maxslots(device_t dev) +{ + return 31; +} + +#define T2_CFGOFF(b, s, f, r) \ + ((b) ? (((b) << 16) | ((s) << 11) | ((f) << 8) | (r)) \ + : ((1 << ((s) + 11)) | ((f) << 8) | (r))) + +#define T2_TYPE1_SETUP(b,s,old_hae3) if((b)) { \ + do { \ + (s) = splhigh(); \ + (old_hae3) = REGVAL(T2_HAE0_3); \ + alpha_mb(); \ + REGVAL(T2_HAE0_3) = (old_hae3) | (1<<30); \ + alpha_mb(); \ + } while(0); \ +} + +#define T2_TYPE1_TEARDOWN(b,s,old_hae3) if((b)) { \ + do { \ + alpha_mb(); \ + REGVAL(T2_HAE0_3) = (old_hae3); \ + alpha_mb(); \ + splx((s)); \ + } while(0); \ +} + +#define SWIZ_CFGREAD(b, s, f, r, width, type) do { \ + type val = ~0; \ + int ipl = 0; \ + u_int32_t old_hae3 = 0; \ + vm_offset_t off = T2_CFGOFF(b, s, f, r); \ + vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(T2_PCI_CONF), off); \ + alpha_mb(); \ + T2_TYPE1_SETUP(b,ipl,old_hae3); \ + if (!badaddr((caddr_t)kv, sizeof(type))) { \ + val = SPARSE_##width##_EXTRACT(off, SPARSE_READ(kv)); \ + } \ + T2_TYPE1_TEARDOWN(b,ipl,old_hae3); \ + return val; \ +} while (0) + +#define SWIZ_CFGWRITE(b, s, f, r, data, width, type) do { \ + int ipl = 0; \ + u_int32_t old_hae3 = 0; \ + vm_offset_t off = T2_CFGOFF(b, s, f, r); \ + vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(T2_PCI_CONF), off); \ + alpha_mb(); \ + T2_TYPE1_SETUP(b,ipl,old_hae3); \ + if (!badaddr((caddr_t)kv, sizeof(type))) { \ + SPARSE_WRITE(kv, SPARSE_##width##_INSERT(off, data)); \ + alpha_wmb(); \ + } \ + T2_TYPE1_TEARDOWN(b,ipl,old_hae3); \ + return; \ +} while (0) + +static u_int32_t +t2_pcib_read_config(device_t dev, int b, int s, int f, + int reg, int width) +{ + switch (width) { + case 1: + SWIZ_CFGREAD(b, s, f, reg, BYTE, u_int8_t); + case 2: + SWIZ_CFGREAD(b, s, f, reg, WORD, u_int16_t); + case 4: + SWIZ_CFGREAD(b, s, f, reg, LONG, u_int32_t); + } + return ~0; +} + +static void +t2_pcib_write_config(device_t dev, int b, int s, int f, + int reg, u_int32_t val, int width) +{ + switch (width) { + case 1: + SWIZ_CFGWRITE(b, s, f, reg, val, BYTE, u_int8_t); + case 2: + SWIZ_CFGWRITE(b, s, f, reg, val, WORD, u_int16_t); + case 4: + SWIZ_CFGWRITE(b, s, f, reg, val, LONG, u_int32_t); + } +} + static device_method_t t2_pcib_methods[] = { /* Device interface */ DEVMETHOD(device_probe, t2_pcib_probe), @@ -75,6 +179,14 @@ static device_method_t t2_pcib_methods[] = { DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + /* alphapci interface */ + DEVMETHOD(alphapci_cvt_dense, t2_pcib_cvt_dense), + + /* pcib interface */ + DEVMETHOD(pcib_maxslots, t2_pcib_maxslots), + DEVMETHOD(pcib_read_config, t2_pcib_read_config), + DEVMETHOD(pcib_write_config, t2_pcib_write_config), + { 0, 0 } }; |