2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
35 #include <machine/bus.h>
36 #include <sys/interrupt.h>
37 #include <sys/sysctl.h>
40 #include <pci/pcivar.h>
41 #include <machine/chipset.h>
42 #include <machine/cpuconf.h>
43 #include <machine/resource.h>
44 #include <machine/md_var.h>
45 #include <alpha/pci/pcibus.h>
46 #include <alpha/isa/isavar.h>
48 char chipset_type[10];
50 long chipset_ports = 0;
51 long chipset_memory = 0;
52 long chipset_dense = 0;
53 long chipset_hae_mask = 0;
55 SYSCTL_NODE(_hw, OID_AUTO, chipset, CTLFLAG_RW, 0, "PCI chipset information");
56 SYSCTL_STRING(_hw_chipset, OID_AUTO, type, CTLFLAG_RD, chipset_type, 0,
58 SYSCTL_INT(_hw_chipset, OID_AUTO, bwx, CTLFLAG_RD, &chipset_bwx, 0,
59 "PCI chipset supports BWX access");
60 SYSCTL_LONG(_hw_chipset, OID_AUTO, ports, CTLFLAG_RD, &chipset_ports,
61 "PCI chipset port address");
62 SYSCTL_LONG(_hw_chipset, OID_AUTO, memory, CTLFLAG_RD, &chipset_memory,
63 "PCI chipset memory address");
64 SYSCTL_LONG(_hw_chipset, OID_AUTO, dense, CTLFLAG_RD, &chipset_dense,
65 "PCI chipset dense memory address");
66 SYSCTL_LONG(_hw_chipset, OID_AUTO, hae_mask, CTLFLAG_RD, &chipset_hae_mask,
67 "PCI chipset mask for HAE register");
71 /* return max number of devices on the bus */
73 pci_maxdevs(pcicfgregs *cfg)
75 return chipset.maxdevs(cfg->bus);
80 /* read configuration space register */
83 pci_cfgread(pcicfgregs *cfg, int reg, int bytes)
87 return chipset.cfgreadb(cfg->hose, cfg->bus,
88 cfg->slot, cfg->func, reg);
90 return chipset.cfgreadw(cfg->hose, cfg->bus,
91 cfg->slot, cfg->func, reg);
93 return chipset.cfgreadl(cfg->hose, cfg->bus,
94 cfg->slot, cfg->func, reg);
100 /* write configuration space register */
103 pci_cfgwrite(pcicfgregs *cfg, int reg, int data, int bytes)
107 return chipset.cfgwriteb(cfg->hose, cfg->bus,
108 cfg->slot, cfg->func, reg, data);
110 return chipset.cfgwritew(cfg->hose, cfg->bus,
111 cfg->slot, cfg->func, reg, data);
113 return chipset.cfgwritel(cfg->hose, cfg->bus,
114 cfg->slot, cfg->func, reg, data);
119 pci_cvt_to_dense(vm_offset_t sparse)
121 if(chipset.cvt_to_dense)
122 return ALPHA_PHYS_TO_K0SEG(chipset.cvt_to_dense(sparse));
128 pci_cvt_to_bwx(vm_offset_t sparse)
130 if(chipset.cvt_to_bwx)
131 return ALPHA_PHYS_TO_K0SEG(chipset.cvt_to_bwx(sparse));
137 alpha_platform_assign_pciintr(pcicfgregs *cfg)
139 if(platform.pci_intr_map)
140 platform.pci_intr_map((void *)cfg);
144 alpha_platform_setup_ide_intr(int chan, driver_intr_t *fn, void *arg)
146 if (platform.pci_setup_ide_intr)
147 return platform.pci_setup_ide_intr(chan, fn, arg);
149 int irqs[2] = { 14, 15 };
151 struct resource *res;
152 res = isa_alloc_intr(0, 0, irqs[chan]);
154 return isa_setup_intr(0, 0, res, INTR_TYPE_BIO,
161 static struct rman irq_rman, port_rman, mem_rman;
163 void pci_init_resources()
165 irq_rman.rm_start = 0;
166 irq_rman.rm_end = 64;
167 irq_rman.rm_type = RMAN_ARRAY;
168 irq_rman.rm_descr = "PCI Interrupt request lines";
169 if (rman_init(&irq_rman)
170 || rman_manage_region(&irq_rman, 0, 63))
171 panic("pci_init_resources irq_rman");
173 port_rman.rm_start = 0;
174 port_rman.rm_end = ~0u;
175 port_rman.rm_type = RMAN_ARRAY;
176 port_rman.rm_descr = "I/O ports";
177 if (rman_init(&port_rman)
178 || rman_manage_region(&port_rman, 0x0, (1L << 32)))
179 panic("pci_init_resources port_rman");
181 mem_rman.rm_start = 0;
182 mem_rman.rm_end = ~0u;
183 mem_rman.rm_type = RMAN_ARRAY;
184 mem_rman.rm_descr = "I/O memory";
185 if (rman_init(&mem_rman)
186 || rman_manage_region(&mem_rman, 0x0, (1L << 32)))
187 panic("pci_init_resources mem_rman");
191 * Allocate a resource on behalf of child. NB: child is usually going to be a
192 * child of one of our descendants, not a direct child of the pci chipset.
195 pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
196 u_long start, u_long end, u_long count, u_int flags)
218 rv = rman_reserve_resource(rm, start, end, count, flags, child);
224 rman_set_bustag(rv, ALPHA_BUS_SPACE_MEM);
225 rman_set_bushandle(rv, rv->r_start);
226 if (flags & PCI_RF_DENSE)
227 rman_set_virtual(rv, pci_cvt_to_dense(rv->r_start));
228 else if (flags & PCI_RF_BWX)
229 rman_set_virtual(rv, pci_cvt_to_bwx(rv->r_start));
231 rman_set_virtual(rv, (void *) rv->r_start); /* maybe NULL? */
235 rman_set_bustag(rv, ALPHA_BUS_SPACE_IO);
236 rman_set_bushandle(rv, rv->r_start);
244 pci_activate_resource(device_t bus, device_t child, int type, int rid,
247 return (rman_activate_resource(r));
251 pci_deactivate_resource(device_t bus, device_t child, int type, int rid,
254 return (rman_deactivate_resource(r));
258 pci_release_resource(device_t bus, device_t child, int type, int rid,
261 return (rman_release_resource(r));
265 memcpy_fromio(void *d, u_int32_t s, size_t size)
274 memcpy_toio(u_int32_t d, void *s, size_t size)
283 memcpy_io(u_int32_t d, u_int32_t s, size_t size)
286 writeb(d++, readb(s++));
290 memset_io(u_int32_t d, int val, size_t size)
297 memsetw(void *d, int val, size_t size)
306 memsetw_io(u_int32_t d, int val, size_t size)
310 d += sizeof(u_int16_t);
318 DB_COMMAND(in, db_in)
327 while ((c = *modif++) != '\0') {
342 db_printf("bad size\n");
346 if (count <= 0) count = 1;
347 while (--count >= 0) {
348 db_printf("%08lx:\t", addr);
351 db_printf("%02x\n", inb(addr));
354 db_printf("%04x\n", inw(addr));
357 db_printf("%08x\n", inl(addr));