Annotation of sys/arch/hppa/dev/dino.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: dino.c,v 1.22 2007/05/23 18:07:19 kettenis Exp $ */
2:
3: /*
4: * Copyright (c) 2003-2005 Michael Shalayeff
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19: * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22: * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26: * THE POSSIBILITY OF SUCH DAMAGE.
27: */
28:
29: #include "cardbus.h"
30:
31: #include <sys/param.h>
32: #include <sys/systm.h>
33: #include <sys/device.h>
34: #include <sys/reboot.h>
35: #include <sys/malloc.h>
36: #include <sys/extent.h>
37:
38: #include <machine/iomod.h>
39: #include <machine/autoconf.h>
40:
41: #include <hppa/dev/cpudevs.h>
42:
43: #if NCARDBUS > 0
44: #include <dev/cardbus/rbus.h>
45: #endif
46:
47: #include <dev/pci/pcireg.h>
48: #include <dev/pci/pcivar.h>
49: #include <dev/pci/pcidevs.h>
50:
51: #include <machine/pdc.h>
52: #include <dev/cons.h>
53:
54: #define DINO_MEM_CHUNK 0x800000
55: #define DINO_MEM_WINDOW (2 * DINO_MEM_CHUNK)
56:
57: struct dino_regs {
58: u_int32_t pad0; /* 0x000 */
59: u_int32_t iar0; /* 0x004 rw intr addr reg 0 */
60: u_int32_t iodc; /* 0x008 rw iodc data/addr */
61: u_int32_t irr0; /* 0x00c r intr req reg 0 */
62: u_int32_t iar1; /* 0x010 rw intr addr reg 1 */
63: u_int32_t irr1; /* 0x014 r intr req reg 1 */
64: u_int32_t imr; /* 0x018 rw intr mask reg */
65: u_int32_t ipr; /* 0x01c rw intr pending reg */
66: u_int32_t toc_addr; /* 0x020 rw TOC addr reg */
67: u_int32_t icr; /* 0x024 rw intr control reg */
68: u_int32_t ilr; /* 0x028 r intr level reg */
69: u_int32_t pad1; /* 0x02c */
70: u_int32_t io_command; /* 0x030 w command register */
71: u_int32_t io_status; /* 0x034 r status register */
72: u_int32_t io_control; /* 0x038 rw control register */
73: u_int32_t pad2; /* 0x03c AUX registers follow */
74: u_int32_t io_gsc_err_addr;/* 0x040 GSC error address */
75: u_int32_t io_err_info; /* 0x044 error info register */
76: u_int32_t io_pci_err_addr;/* 0x048 PCI error address */
77: u_int32_t pad3[4]; /* 0x04c */
78: u_int32_t io_fbb_en; /* 0x05c fast back2back enable reg */
79: u_int32_t io_addr_en; /* 0x060 address enable reg */
80: u_int32_t pci_addr; /* 0x064 PCI conf/io/mem addr reg */
81: u_int32_t pci_conf_data; /* 0x068 PCI conf data reg */
82: u_int32_t pci_io_data; /* 0x06c PCI io data reg */
83: u_int32_t pci_mem_data; /* 0x070 PCI memory data reg */
84: u_int32_t pad4[0x740/4]; /* 0x074 */
85: u_int32_t gsc2x_config; /* 0x7b4 GSC2X config reg */
86: u_int32_t pad5[0x48/4]; /* 0x7b8: BSRS registers follow */
87: u_int32_t gmask; /* 0x800 GSC arbitration mask */
88: u_int32_t pamr; /* 0x804 PCI arbitration mask */
89: u_int32_t papr; /* 0x808 PCI arbitration priority */
90: u_int32_t damode; /* 0x80c PCI arbitration mode */
91: u_int32_t pcicmd; /* 0x810 PCI command register */
92: u_int32_t pcists; /* 0x814 PCI status register */
93: u_int32_t pad6; /* 0x818 */
94: u_int32_t mltim; /* 0x81c PCI master latency timer */
95: u_int32_t brdg_feat; /* 0x820 PCI bridge feature enable */
96: u_int32_t pciror; /* 0x824 PCI read optimization reg */
97: u_int32_t pciwor; /* 0x828 PCI write optimization reg */
98: u_int32_t pad7; /* 0x82c */
99: u_int32_t tltim; /* 0x830 PCI target latency reg */
100: };
101:
102: struct dino_softc {
103: struct device sc_dv;
104:
105: int sc_ver;
106: void *sc_ih;
107: u_int32_t sc_imr;
108: bus_space_tag_t sc_bt;
109: bus_space_handle_t sc_bh;
110: bus_dma_tag_t sc_dmat;
111: volatile struct dino_regs *sc_regs;
112:
113: struct hppa_pci_chipset_tag sc_pc;
114: struct hppa_bus_space_tag sc_iot;
115: char sc_ioexname[20];
116: struct extent *sc_ioex;
117: struct hppa_bus_space_tag sc_memt;
118: char sc_memexname[20];
119: struct extent *sc_memex;
120: struct hppa_bus_dma_tag sc_dmatag;
121:
122: u_int32_t io_shadow;
123: };
124:
125: int dinomatch(struct device *, void *, void *);
126: void dinoattach(struct device *, struct device *, void *);
127: int dino_intr(void *);
128:
129: struct cfattach dino_ca = {
130: sizeof(struct dino_softc), dinomatch, dinoattach
131: };
132:
133: struct cfdriver dino_cd = {
134: NULL, "dino", DV_DULL
135: };
136:
137: int
138: dinomatch(parent, cfdata, aux)
139: struct device *parent;
140: void *cfdata;
141: void *aux;
142: {
143: struct confargs *ca = aux;
144: /* struct cfdata *cf = cfdata; */
145:
146: /* there will be only one */
147: if (ca->ca_type.iodc_type != HPPA_TYPE_BRIDGE ||
148: ca->ca_type.iodc_sv_model != HPPA_BRIDGE_DINO)
149: return (0);
150:
151: /* do not match on the elroy family */
152: if (ca->ca_type.iodc_model == 0x78)
153: return (0);
154:
155: return (1);
156: }
157:
158: void dino_attach_hook(struct device *, struct device *,
159: struct pcibus_attach_args *);
160: int dino_maxdevs(void *, int);
161: pcitag_t dino_make_tag(void *, int, int, int);
162: void dino_decompose_tag(void *, pcitag_t, int *, int *, int *);
163: pcireg_t dino_conf_read(void *, pcitag_t, int);
164: void dino_conf_write(void *, pcitag_t, int, pcireg_t);
165: int dino_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
166: const char *dino_intr_string(void *, pci_intr_handle_t);
167: void * dino_intr_establish(void *, pci_intr_handle_t, int, int (*)(void *),
168: void *, char *);
169: void dino_intr_disestablish(void *, void *);
170: int dino_iomap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *);
171: int dino_memmap(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *);
172: int dino_subregion(void *, bus_space_handle_t, bus_size_t, bus_size_t,
173: bus_space_handle_t *);
174: int dino_ioalloc(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,
175: bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
176: int dino_memalloc(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,
177: bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
178: void dino_unmap(void *, bus_space_handle_t, bus_size_t);
179: void dino_free(void *, bus_space_handle_t, bus_size_t);
180: void dino_barrier(void *, bus_space_handle_t, bus_size_t, bus_size_t, int);
181: void * dino_alloc_parent(struct device *, struct pci_attach_args *, int);
182: u_int8_t dino_r1(void *, bus_space_handle_t, bus_size_t);
183: u_int16_t dino_r2(void *, bus_space_handle_t, bus_size_t);
184: u_int32_t dino_r4(void *, bus_space_handle_t, bus_size_t);
185: u_int64_t dino_r8(void *, bus_space_handle_t, bus_size_t);
186: void dino_w1(void *, bus_space_handle_t, bus_size_t, u_int8_t);
187: void dino_w2(void *, bus_space_handle_t, bus_size_t, u_int16_t);
188: void dino_w4(void *, bus_space_handle_t, bus_size_t, u_int32_t);
189: void dino_w8(void *, bus_space_handle_t, bus_size_t, u_int64_t);
190: void dino_rm_1(void *, bus_space_handle_t, bus_size_t, u_int8_t *,
191: bus_size_t);
192: void dino_rm_2(void *, bus_space_handle_t, bus_size_t, u_int16_t *,
193: bus_size_t);
194: void dino_rm_4(void *, bus_space_handle_t, bus_size_t, u_int32_t *,
195: bus_size_t);
196: void dino_rm_8(void *, bus_space_handle_t, bus_size_t, u_int64_t *,
197: bus_size_t);
198: void dino_wm_1(void *, bus_space_handle_t, bus_size_t, const u_int8_t *,
199: bus_size_t);
200: void dino_wm_2(void *, bus_space_handle_t, bus_size_t, const u_int16_t *,
201: bus_size_t);
202: void dino_wm_4(void *, bus_space_handle_t, bus_size_t, const u_int32_t *,
203: bus_size_t);
204: void dino_wm_8(void *, bus_space_handle_t, bus_size_t, const u_int64_t *,
205: bus_size_t);
206: void dino_sm_1(void *, bus_space_handle_t, bus_size_t, u_int8_t, bus_size_t);
207: void dino_sm_2(void *, bus_space_handle_t, bus_size_t, u_int16_t,
208: bus_size_t);
209: void dino_sm_4(void *, bus_space_handle_t, bus_size_t, u_int32_t,
210: bus_size_t);
211: void dino_sm_8(void *, bus_space_handle_t, bus_size_t, u_int64_t,
212: bus_size_t);
213: void dino_rrm_2(void *, bus_space_handle_t, bus_size_t, u_int8_t *,
214: bus_size_t);
215: void dino_rrm_4(void *, bus_space_handle_t, bus_size_t, u_int8_t *,
216: bus_size_t);
217: void dino_rrm_8(void *, bus_space_handle_t, bus_size_t, u_int8_t *,
218: bus_size_t);
219: void dino_wrm_2(void *, bus_space_handle_t, bus_size_t, const u_int8_t *,
220: bus_size_t);
221: void dino_wrm_4(void *, bus_space_handle_t, bus_size_t, const u_int8_t *,
222: bus_size_t);
223: void dino_wrm_8(void *, bus_space_handle_t, bus_size_t, const u_int8_t *,
224: bus_size_t);
225: void dino_rr_1(void *, bus_space_handle_t, bus_size_t, u_int8_t *,
226: bus_size_t);
227: void dino_rr_2(void *, bus_space_handle_t, bus_size_t, u_int16_t *,
228: bus_size_t);
229: void dino_rr_4(void *, bus_space_handle_t, bus_size_t, u_int32_t *,
230: bus_size_t);
231: void dino_rr_8(void *, bus_space_handle_t, bus_size_t, u_int64_t *,
232: bus_size_t);
233: void dino_wr_1(void *, bus_space_handle_t, bus_size_t, const u_int8_t *,
234: bus_size_t);
235: void dino_wr_2(void *, bus_space_handle_t, bus_size_t, const u_int16_t *,
236: bus_size_t);
237: void dino_wr_4(void *, bus_space_handle_t, bus_size_t, const u_int32_t *,
238: bus_size_t);
239: void dino_wr_8(void *, bus_space_handle_t, bus_size_t, const u_int64_t *,
240: bus_size_t);
241: void dino_rrr_2(void *, bus_space_handle_t, bus_size_t, u_int8_t *,
242: bus_size_t);
243: void dino_rrr_4(void *, bus_space_handle_t, bus_size_t, u_int8_t *,
244: bus_size_t);
245: void dino_rrr_8(void *, bus_space_handle_t, bus_size_t, u_int8_t *,
246: bus_size_t);
247: void dino_wrr_2(void *, bus_space_handle_t, bus_size_t, const u_int8_t *,
248: bus_size_t);
249: void dino_wrr_4(void *, bus_space_handle_t, bus_size_t, const u_int8_t *,
250: bus_size_t);
251: void dino_wrr_8(void *, bus_space_handle_t, bus_size_t, const u_int8_t *,
252: bus_size_t);
253: void dino_sr_1(void *, bus_space_handle_t, bus_size_t, u_int8_t, bus_size_t);
254: void dino_sr_2(void *, bus_space_handle_t, bus_size_t, u_int16_t,
255: bus_size_t);
256: void dino_sr_4(void *, bus_space_handle_t, bus_size_t, u_int32_t,
257: bus_size_t);
258: void dino_sr_8(void *, bus_space_handle_t, bus_size_t, u_int64_t,
259: bus_size_t);
260: void dino_cp_1(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
261: bus_size_t, bus_size_t);
262: void dino_cp_2(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
263: bus_size_t, bus_size_t);
264: void dino_cp_4(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
265: bus_size_t, bus_size_t);
266: void dino_cp_8(void *, bus_space_handle_t, bus_size_t, bus_space_handle_t,
267: bus_size_t, bus_size_t);
268: int dino_dmamap_create(void *, bus_size_t, int, bus_size_t, bus_size_t, int,
269: bus_dmamap_t *);
270: void dino_dmamap_destroy(void *, bus_dmamap_t);
271: int dino_dmamap_load(void *, bus_dmamap_t, void *, bus_size_t,
272: struct proc *, int);
273: int dino_dmamap_load_mbuf(void *, bus_dmamap_t, struct mbuf *, int);
274: int dino_dmamap_load_uio(void *, bus_dmamap_t, struct uio *, int);
275: int dino_dmamap_load_raw(void *, bus_dmamap_t, bus_dma_segment_t *, int,
276: bus_size_t, int);
277: void dino_dmamap_unload(void *, bus_dmamap_t);
278: void dino_dmamap_sync(void *, bus_dmamap_t, bus_addr_t, bus_size_t, int);
279: int dino_dmamem_alloc(void *, bus_size_t, bus_size_t, bus_size_t,
280: bus_dma_segment_t *, int, int *, int);
281: void dino_dmamem_free(void *, bus_dma_segment_t *, int);
282: int dino_dmamem_map(void *, bus_dma_segment_t *, int, size_t, caddr_t *,
283: int);
284: void dino_dmamem_unmap(void *, caddr_t, size_t);
285: paddr_t dino_dmamem_mmap(void *, bus_dma_segment_t *, int, off_t, int, int);
286: int dinoprint(void *, const char *);
287: void dino_clear_pdc_mappings(void *);
288:
289: void
290: dino_attach_hook(struct device *parent, struct device *self,
291: struct pcibus_attach_args *pba)
292: {
293:
294: }
295:
296: int
297: dino_maxdevs(void *v, int bus)
298: {
299: return (32);
300: }
301:
302: pcitag_t
303: dino_make_tag(void *v, int bus, int dev, int func)
304: {
305: if (bus > 255 || dev > 31 || func > 7)
306: panic("dino_make_tag: bad request");
307:
308: return ((bus << 16) | (dev << 11) | (func << 8));
309: }
310:
311: void
312: dino_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func)
313: {
314: *bus = (tag >> 16) & 0xff;
315: *dev = (tag >> 11) & 0x1f;
316: *func= (tag >> 8) & 0x07;
317: }
318:
319: pcireg_t
320: dino_conf_read(void *v, pcitag_t tag, int reg)
321: {
322: struct dino_softc *sc = v;
323: volatile struct dino_regs *r = sc->sc_regs;
324: pcireg_t data;
325: u_int32_t pamr;
326:
327: /* fix arbitration errata by disabling all pci devs on config read */
328: pamr = r->pamr;
329: r->pamr = 0;
330:
331: r->pci_addr = tag | reg;
332: data = r->pci_conf_data;
333:
334: /* restore arbitration */
335: r->pamr = pamr;
336:
337: return (letoh32(data));
338: }
339:
340: void
341: dino_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
342: {
343: struct dino_softc *sc = v;
344: volatile struct dino_regs *r = sc->sc_regs;
345: pcireg_t data1;
346: u_int32_t pamr;
347:
348: /* fix arbitration errata by disabling all pci devs on config read */
349: pamr = r->pamr;
350: r->pamr = 0;
351:
352: r->pci_addr = tag | reg;
353: r->pci_conf_data = htole32(data);
354:
355: /* fix coalescing config and io writes by interleaving w/ a read */
356: r->pci_addr = tag | PCI_ID_REG;
357: data1 = r->pci_conf_data;
358:
359: /* restore arbitration */
360: r->pamr = pamr;
361: }
362:
363: int
364: dino_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
365: {
366: /* struct dino_softc *sc = v;
367: volatile struct dino_regs *r = sc->sc_regs; */
368: pci_chipset_tag_t pc = pa->pa_pc;
369: pcitag_t tag = pa->pa_tag;
370: pcireg_t reg;
371:
372: reg = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
373: *ihp = PCI_INTERRUPT_LINE(reg) + 1;
374: return (*ihp == 0);
375: }
376:
377: const char *
378: dino_intr_string(void *v, pci_intr_handle_t ih)
379: {
380: static char buf[32];
381:
382: snprintf(buf, 32, "irq %ld", ih);
383:
384: return (buf);
385: }
386:
387: void *
388: dino_intr_establish(void *v, pci_intr_handle_t ih,
389: int pri, int (*handler)(void *), void *arg, char *name)
390: {
391: struct dino_softc *sc = v;
392: volatile struct dino_regs *r = sc->sc_regs;
393: void *iv;
394:
395: /* no mapping or bogus */
396: if (ih <= 0 || ih > 11)
397: return (NULL);
398:
399: if ((iv = cpu_intr_map(sc->sc_ih, pri, ih - 1, handler, arg, name))) {
400: if (cold)
401: sc->sc_imr |= (1 << (ih - 1));
402: else
403: r->imr = sc->sc_imr |= (1 << (ih - 1));
404: }
405:
406: return (iv);
407: }
408:
409: void
410: dino_intr_disestablish(void *v, void *cookie)
411: {
412: #if 0
413: struct dino_softc *sc = v;
414: volatile struct dino_regs *r = sc->sc_regs;
415:
416: r->imr &= ~(1 << (ih - 1));
417:
418: TODO cpu_intr_unmap(sc->sc_ih, cookie);
419: #endif
420: }
421:
422: int
423: dino_iomap(void *v, bus_addr_t bpa, bus_size_t size,
424: int flags, bus_space_handle_t *bshp)
425: {
426: struct dino_softc *sc = v;
427: int error;
428:
429: if ((error = extent_alloc_region(sc->sc_ioex, bpa, size, EX_NOWAIT)))
430: return (error);
431:
432: if (bshp)
433: *bshp = bpa;
434:
435: return (0);
436: }
437:
438: int
439: dino_memmap(void *v, bus_addr_t bpa, bus_size_t size,
440: int flags, bus_space_handle_t *bshp)
441: {
442: struct dino_softc *sc = v;
443: volatile struct dino_regs *r = sc->sc_regs;
444: bus_addr_t sbpa;
445: bus_space_handle_t bush;
446: u_int32_t reg;
447: int first = 1;
448: int error;
449:
450: while (size != 0) {
451: sbpa = bpa & 0xff800000;
452: reg = sc->io_shadow;
453: reg |= 1 << ((bpa >> 23) & 0x1f);
454: #ifdef DEBUG
455: if (reg & 0x80000001)
456: panic("mapping outside the mem extent range");
457: #endif
458: /* map into the upper bus space, if not yet mapped this 8M */
459: if (reg != sc->io_shadow) {
460:
461: if ((error = bus_space_map(sc->sc_bt, sbpa,
462: DINO_MEM_CHUNK, flags, &bush))) {
463: return (error);
464: }
465: r->io_addr_en |= reg;
466: sc->io_shadow = reg;
467:
468: if (first) {
469: if (bshp)
470: *bshp = bush + (bpa - sbpa);
471: }
472: } else {
473: if (first) {
474: if (bshp)
475: *bshp = bpa;
476: }
477: }
478:
479: if (first) {
480: size += (bpa - sbpa);
481: first = 0;
482: }
483:
484: if (size < DINO_MEM_CHUNK)
485: size = 0;
486: else {
487: size -= DINO_MEM_CHUNK;
488: bpa = sbpa + DINO_MEM_CHUNK;
489: }
490: }
491:
492: return (0);
493: }
494:
495: int
496: dino_subregion(void *v, bus_space_handle_t bsh, bus_size_t offset,
497: bus_size_t size, bus_space_handle_t *nbshp)
498: {
499: *nbshp = bsh + offset;
500: return (0);
501: }
502:
503: int
504: dino_ioalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
505: bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
506: bus_space_handle_t *bshp)
507: {
508: struct dino_softc *sc = v;
509: struct extent *ex = sc->sc_ioex;
510: bus_addr_t bpa;
511: int error;
512:
513: if (rstart < ex->ex_start || rend > ex->ex_end)
514: panic("dino_ioalloc: bad region start/end");
515:
516: if ((error = extent_alloc_subregion(ex, rstart, rend, size,
517: align, 0, boundary, EX_NOWAIT, &bpa)))
518: return (error);
519:
520: if (addrp)
521: *addrp = bpa;
522: if (bshp)
523: *bshp = bpa;
524:
525: return (0);
526: }
527:
528: int
529: dino_memalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
530: bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
531: bus_space_handle_t *bshp)
532: {
533: struct dino_softc *sc = v;
534: volatile struct dino_regs *r = sc->sc_regs;
535: u_int32_t reg;
536:
537: if (bus_space_alloc(sc->sc_bt, rstart, rend, size,
538: align, boundary, flags, addrp, bshp))
539: return (ENOMEM);
540:
541: reg = sc->io_shadow;
542: reg |= 1 << ((*addrp >> 23) & 0x1f);
543: #ifdef DEBUG
544: if (reg & 0x80000001)
545: panic("mapping outside the mem extent range");
546: #endif
547: r->io_addr_en |= reg;
548: sc->io_shadow = reg;
549:
550: return (0);
551: }
552:
553: void
554: dino_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
555: {
556: struct dino_softc *sc = v;
557: struct extent *ex;
558: bus_addr_t bpa;
559:
560: bpa = bsh;
561: if (bsh & 0xf0000000) {
562: /* TODO dino_unmap mem */
563: /* TODO unmap from the upper bus if the last use in this 8M */
564: return;
565: } else
566: ex = sc->sc_ioex;
567:
568: if (extent_free(ex, bpa, size, EX_NOWAIT))
569: printf("dino_unmap: ps 0x%lx, size 0x%lx\n"
570: "dino_unmap: can't free region\n", bpa, size);
571: }
572:
573: void
574: dino_free(void *v, bus_space_handle_t bh, bus_size_t size)
575: {
576: /* should be enough */
577: dino_unmap(v, bh, size);
578: }
579:
580: void
581: dino_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op)
582: {
583: sync_caches();
584: }
585:
586: #if NCARDBUS > 0
587: void *
588: dino_alloc_parent(struct device *self, struct pci_attach_args *pa, int io)
589: {
590: struct dino_softc *sc = pa->pa_pc->_cookie;
591: struct extent *ex;
592: bus_space_tag_t tag;
593: bus_addr_t start;
594: bus_size_t size;
595:
596: if (io) {
597: ex = sc->sc_ioex;
598: tag = pa->pa_iot;
599: start = 0xa000;
600: size = 0x1000;
601: } else {
602: if (!sc->sc_memex) {
603: bus_space_handle_t memh;
604: bus_addr_t mem_start;
605:
606: if (dino_memalloc(sc, 0xf0800000, 0xff7fffff,
607: DINO_MEM_WINDOW, DINO_MEM_WINDOW, EX_NOBOUNDARY,
608: 0, &mem_start, &memh))
609: return (NULL);
610:
611: snprintf(sc->sc_memexname, sizeof(sc->sc_memexname),
612: "%s_mem", sc->sc_dv.dv_xname);
613: if ((sc->sc_memex = extent_create(sc->sc_memexname,
614: mem_start, mem_start + DINO_MEM_WINDOW, M_DEVBUF,
615: NULL, 0, EX_NOWAIT | EX_MALLOCOK)) == NULL) {
616: extent_destroy(sc->sc_ioex);
617: bus_space_free(sc->sc_bt, memh,
618: DINO_MEM_WINDOW);
619: return (NULL);
620: }
621: }
622: ex = sc->sc_memex;
623: tag = pa->pa_memt;
624: start = ex->ex_start;
625: size = DINO_MEM_CHUNK;
626: }
627:
628: if (extent_alloc_subregion(ex, start, ex->ex_end, size, size, 0,
629: EX_NOBOUNDARY, EX_NOWAIT, &start))
630: return (NULL);
631:
632: extent_free(ex, start, size, EX_NOWAIT);
633: return rbus_new_root_share(tag, ex, start, size, 0);
634: }
635: #endif
636:
637: u_int8_t
638: dino_r1(void *v, bus_space_handle_t h, bus_size_t o)
639: {
640: h += o;
641: if (h & 0xf0000000)
642: return *(volatile u_int8_t *)h;
643: else {
644: struct dino_softc *sc = v;
645: volatile struct dino_regs *r = sc->sc_regs;
646: u_int8_t data;
647:
648: r->pci_addr = h;
649: data = *((volatile u_int8_t *)&r->pci_io_data + (h & 3));
650: return (data);
651: }
652: }
653:
654: u_int16_t
655: dino_r2(void *v, bus_space_handle_t h, bus_size_t o)
656: {
657: volatile u_int16_t *p;
658:
659: h += o;
660: if (h & 0xf0000000)
661: p = (volatile u_int16_t *)h;
662: else {
663: struct dino_softc *sc = v;
664: volatile struct dino_regs *r = sc->sc_regs;
665:
666: r->pci_addr = h;
667: p = (volatile u_int16_t *)&r->pci_io_data;
668: if (h & 2)
669: p++;
670: }
671:
672: return (letoh16(*p));
673: }
674:
675: u_int32_t
676: dino_r4(void *v, bus_space_handle_t h, bus_size_t o)
677: {
678: u_int32_t data;
679:
680: h += o;
681: if (h & 0xf0000000)
682: data = *(volatile u_int32_t *)h;
683: else {
684: struct dino_softc *sc = v;
685: volatile struct dino_regs *r = sc->sc_regs;
686:
687: r->pci_addr = h;
688: data = r->pci_io_data;
689: }
690:
691: return (letoh32(data));
692: }
693:
694: u_int64_t
695: dino_r8(void *v, bus_space_handle_t h, bus_size_t o)
696: {
697: u_int64_t data;
698:
699: h += o;
700: if (h & 0xf0000000)
701: data = *(volatile u_int64_t *)h;
702: else
703: panic("dino_r8: not implemented");
704:
705: return (letoh64(data));
706: }
707:
708: void
709: dino_w1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv)
710: {
711: h += o;
712: if (h & 0xf0000000)
713: *(volatile u_int8_t *)h = vv;
714: else {
715: struct dino_softc *sc = v;
716: volatile struct dino_regs *r = sc->sc_regs;
717:
718: r->pci_addr = h;
719: *((volatile u_int8_t *)&r->pci_io_data + (h & 3)) = vv;
720: }
721: }
722:
723: void
724: dino_w2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv)
725: {
726: volatile u_int16_t *p;
727:
728: h += o;
729: if (h & 0xf0000000)
730: p = (volatile u_int16_t *)h;
731: else {
732: struct dino_softc *sc = v;
733: volatile struct dino_regs *r = sc->sc_regs;
734:
735: r->pci_addr = h;
736: p = (volatile u_int16_t *)&r->pci_io_data;
737: if (h & 2)
738: p++;
739: }
740:
741: *p = htole16(vv);
742: }
743:
744: void
745: dino_w4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv)
746: {
747: h += o;
748: vv = htole32(vv);
749: if (h & 0xf0000000)
750: *(volatile u_int32_t *)h = vv;
751: else {
752: struct dino_softc *sc = v;
753: volatile struct dino_regs *r = sc->sc_regs;
754:
755: r->pci_addr = h;
756: r->pci_io_data = vv;
757: }
758: }
759:
760: void
761: dino_w8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv)
762: {
763: h += o;
764: if (h & 0xf0000000)
765: *(volatile u_int64_t *)h = htole64(vv);
766: else
767: panic("dino_w8: not implemented");
768: }
769:
770:
771: void
772: dino_rm_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t *a, bus_size_t c)
773: {
774: volatile u_int8_t *p;
775:
776: h += o;
777: if (h & 0xf0000000)
778: p = (volatile u_int8_t *)h;
779: else {
780: struct dino_softc *sc = v;
781: volatile struct dino_regs *r = sc->sc_regs;
782:
783: r->pci_addr = h;
784: p = (volatile u_int8_t *)&r->pci_io_data + (h & 3);
785: }
786:
787: while (c--)
788: *a++ = *p;
789: }
790:
791: void
792: dino_rm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
793: {
794: volatile u_int16_t *p;
795:
796: h += o;
797: if (h & 0xf0000000)
798: p = (volatile u_int16_t *)h;
799: else {
800: struct dino_softc *sc = v;
801: volatile struct dino_regs *r = sc->sc_regs;
802:
803: r->pci_addr = h;
804: p = (volatile u_int16_t *)&r->pci_io_data;
805: if (h & 2)
806: p++;
807: }
808:
809: while (c--)
810: *a++ = letoh16(*p);
811: }
812:
813: void
814: dino_rm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
815: {
816: volatile u_int32_t *p;
817:
818: h += o;
819: if (h & 0xf0000000)
820: p = (volatile u_int32_t *)h;
821: else {
822: struct dino_softc *sc = v;
823: volatile struct dino_regs *r = sc->sc_regs;
824:
825: r->pci_addr = h;
826: p = (volatile u_int32_t *)&r->pci_io_data;
827: }
828:
829: while (c--)
830: *a++ = letoh32(*p);
831: }
832:
833: void
834: dino_rm_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c)
835: {
836: panic("dino_rm_8: not implemented");
837: }
838:
839: void
840: dino_wm_1(void *v, bus_space_handle_t h, bus_size_t o, const u_int8_t *a, bus_size_t c)
841: {
842: volatile u_int8_t *p;
843:
844: h += o;
845: if (h & 0xf0000000)
846: p = (volatile u_int8_t *)h;
847: else {
848: struct dino_softc *sc = v;
849: volatile struct dino_regs *r = sc->sc_regs;
850:
851: r->pci_addr = h;
852: p = (volatile u_int8_t *)&r->pci_io_data + (h & 3);
853: }
854:
855: while (c--)
856: *p = *a++;
857: }
858:
859: void
860: dino_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
861: {
862: volatile u_int16_t *p;
863:
864: h += o;
865: if (h & 0xf0000000)
866: p = (volatile u_int16_t *)h;
867: else {
868: struct dino_softc *sc = v;
869: volatile struct dino_regs *r = sc->sc_regs;
870:
871: r->pci_addr = h;
872: p = (volatile u_int16_t *)&r->pci_io_data;
873: if (h & 2)
874: p++;
875: }
876:
877: while (c--)
878: *p = htole16(*a++);
879: }
880:
881: void
882: dino_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
883: {
884: volatile u_int32_t *p;
885:
886: h += o;
887: if (h & 0xf0000000)
888: p = (volatile u_int32_t *)h;
889: else {
890: struct dino_softc *sc = v;
891: volatile struct dino_regs *r = sc->sc_regs;
892:
893: r->pci_addr = h;
894: p = (volatile u_int32_t *)&r->pci_io_data;
895: }
896:
897: while (c--)
898: *p = htole32(*a++);
899: }
900:
901: void
902: dino_wm_8(void *v, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c)
903: {
904: panic("dino_wm_8: not implemented");
905: }
906:
907: void
908: dino_sm_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv, bus_size_t c)
909: {
910: volatile u_int8_t *p;
911:
912: h += o;
913: if (h & 0xf0000000)
914: p = (volatile u_int8_t *)h;
915: else {
916: struct dino_softc *sc = v;
917: volatile struct dino_regs *r = sc->sc_regs;
918:
919: r->pci_addr = h;
920: p = (volatile u_int8_t *)&r->pci_io_data + (h & 3);
921: }
922:
923: while (c--)
924: *p = vv;
925: }
926:
927: void
928: dino_sm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
929: {
930: volatile u_int16_t *p;
931:
932: h += o;
933: if (h & 0xf0000000)
934: p = (volatile u_int16_t *)h;
935: else {
936: struct dino_softc *sc = v;
937: volatile struct dino_regs *r = sc->sc_regs;
938:
939: r->pci_addr = h;
940: p = (volatile u_int16_t *)&r->pci_io_data;
941: if (h & 2)
942: p++;
943: }
944:
945: vv = htole16(vv);
946: while (c--)
947: *p = vv;
948: }
949:
950: void
951: dino_sm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
952: {
953: volatile u_int32_t *p;
954:
955: h += o;
956: if (h & 0xf0000000)
957: p = (volatile u_int32_t *)h;
958: else {
959: struct dino_softc *sc = v;
960: volatile struct dino_regs *r = sc->sc_regs;
961:
962: r->pci_addr = h;
963: p = (volatile u_int32_t *)&r->pci_io_data;
964: }
965:
966: vv = htole32(vv);
967: while (c--)
968: *p = vv;
969: }
970:
971: void
972: dino_sm_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv, bus_size_t c)
973: {
974: panic("dino_sm_8: not implemented");
975: }
976:
977: void
978: dino_rrm_2(void *v, bus_space_handle_t h, bus_size_t o,
979: u_int8_t *a, bus_size_t c)
980: {
981: volatile u_int16_t *p, *q = (u_int16_t *)a;
982:
983: h += o;
984: if (h & 0xf0000000)
985: p = (volatile u_int16_t *)h;
986: else {
987: struct dino_softc *sc = v;
988: volatile struct dino_regs *r = sc->sc_regs;
989:
990: r->pci_addr = h;
991: p = (volatile u_int16_t *)&r->pci_io_data;
992: if (h & 2)
993: p++;
994: }
995:
996: c /= 2;
997: while (c--)
998: *q++ = *p;
999: }
1000:
1001: void
1002: dino_rrm_4(void *v, bus_space_handle_t h, bus_size_t o,
1003: u_int8_t *a, bus_size_t c)
1004: {
1005: volatile u_int32_t *p, *q = (u_int32_t *)a;
1006:
1007: h += o;
1008: if (h & 0xf0000000)
1009: p = (volatile u_int32_t *)h;
1010: else {
1011: struct dino_softc *sc = v;
1012: volatile struct dino_regs *r = sc->sc_regs;
1013:
1014: r->pci_addr = h;
1015: p = (volatile u_int32_t *)&r->pci_io_data;
1016: }
1017:
1018: c /= 4;
1019: while (c--)
1020: *q++ = *p;
1021: }
1022:
1023: void
1024: dino_rrm_8(void *v, bus_space_handle_t h, bus_size_t o,
1025: u_int8_t *a, bus_size_t c)
1026: {
1027: panic("dino_rrm_8: not implemented");
1028: }
1029:
1030: void
1031: dino_wrm_2(void *v, bus_space_handle_t h, bus_size_t o,
1032: const u_int8_t *a, bus_size_t c)
1033: {
1034: volatile u_int16_t *p;
1035: const u_int16_t *q = (const u_int16_t *)a;
1036:
1037: h += o;
1038: if (h & 0xf0000000)
1039: p = (volatile u_int16_t *)h;
1040: else {
1041: struct dino_softc *sc = v;
1042: volatile struct dino_regs *r = sc->sc_regs;
1043:
1044: r->pci_addr = h;
1045: p = (volatile u_int16_t *)&r->pci_io_data;
1046: if (h & 2)
1047: p++;
1048: }
1049:
1050: c /= 2;
1051: while (c--)
1052: *p = *q++;
1053: }
1054:
1055: void
1056: dino_wrm_4(void *v, bus_space_handle_t h, bus_size_t o,
1057: const u_int8_t *a, bus_size_t c)
1058: {
1059: volatile u_int32_t *p;
1060: const u_int32_t *q = (const u_int32_t *)a;
1061:
1062: h += o;
1063: if (h & 0xf0000000)
1064: p = (volatile u_int32_t *)h;
1065: else {
1066: struct dino_softc *sc = v;
1067: volatile struct dino_regs *r = sc->sc_regs;
1068:
1069: r->pci_addr = h;
1070: p = (volatile u_int32_t *)&r->pci_io_data;
1071: }
1072:
1073: c /= 4;
1074: while (c--)
1075: *p = *q++;
1076: }
1077:
1078: void
1079: dino_wrm_8(void *v, bus_space_handle_t h, bus_size_t o,
1080: const u_int8_t *a, bus_size_t c)
1081: {
1082: panic("dino_wrm_8: not implemented");
1083: }
1084:
1085: void
1086: dino_rr_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t *a, bus_size_t c)
1087: {
1088: volatile u_int8_t *p;
1089:
1090: h += o;
1091: if (h & 0xf0000000) {
1092: p = (volatile u_int8_t *)h;
1093: while (c--)
1094: *a++ = *p++;
1095: } else {
1096: struct dino_softc *sc = v;
1097: volatile struct dino_regs *r = sc->sc_regs;
1098:
1099: for (; c--; h++) {
1100: r->pci_addr = h;
1101: p = (volatile u_int8_t *)&r->pci_io_data + (h & 3);
1102: *a++ = *p;
1103: }
1104: }
1105: }
1106:
1107: void
1108: dino_rr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
1109: {
1110: volatile u_int16_t *p, data;
1111:
1112: h += o;
1113: if (h & 0xf0000000) {
1114: p = (volatile u_int16_t *)h;
1115: while (c--) {
1116: data = *p++;
1117: *a++ = letoh16(data);
1118: }
1119: } else {
1120: struct dino_softc *sc = v;
1121: volatile struct dino_regs *r = sc->sc_regs;
1122:
1123: for (; c--; h += 2) {
1124: r->pci_addr = h;
1125: p = (volatile u_int16_t *)&r->pci_io_data;
1126: if (h & 2)
1127: p++;
1128: data = *p;
1129: *a++ = letoh16(data);
1130: }
1131: }
1132: }
1133:
1134: void
1135: dino_rr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
1136: {
1137: volatile u_int32_t *p, data;
1138:
1139: h += o;
1140: if (h & 0xf0000000) {
1141: p = (volatile u_int32_t *)h;
1142: while (c--) {
1143: data = *p++;
1144: *a++ = letoh32(data);
1145: }
1146: } else {
1147: struct dino_softc *sc = v;
1148: volatile struct dino_regs *r = sc->sc_regs;
1149:
1150: for (; c--; h += 4) {
1151: r->pci_addr = h;
1152: data = r->pci_io_data;
1153: *a++ = letoh32(data);
1154: }
1155: }
1156: }
1157:
1158: void
1159: dino_rr_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c)
1160: {
1161: panic("dino_rr_8: not implemented");
1162: }
1163:
1164: void
1165: dino_wr_1(void *v, bus_space_handle_t h, bus_size_t o, const u_int8_t *a, bus_size_t c)
1166: {
1167: volatile u_int8_t *p;
1168:
1169: h += o;
1170: if (h & 0xf0000000) {
1171: p = (volatile u_int8_t *)h;
1172: while (c--)
1173: *p++ = *a++;
1174: } else {
1175: struct dino_softc *sc = v;
1176: volatile struct dino_regs *r = sc->sc_regs;
1177:
1178: for (; c--; h++) {
1179: r->pci_addr = h;
1180: p = (volatile u_int8_t *)&r->pci_io_data + (h & 3);
1181: *p = *a++;
1182: }
1183: }
1184: }
1185:
1186: void
1187: dino_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
1188: {
1189: volatile u_int16_t *p, data;
1190:
1191: h += o;
1192: if (h & 0xf0000000) {
1193: p = (volatile u_int16_t *)h;
1194: while (c--) {
1195: data = *a++;
1196: *p++ = htole16(data);
1197: }
1198: } else {
1199: struct dino_softc *sc = v;
1200: volatile struct dino_regs *r = sc->sc_regs;
1201:
1202: for (; c--; h += 2) {
1203: r->pci_addr = h;
1204: p = (volatile u_int16_t *)&r->pci_io_data;
1205: if (h & 2)
1206: p++;
1207: data = *a++;
1208: *p = htole16(data);
1209: }
1210: }
1211: }
1212:
1213: void
1214: dino_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
1215: {
1216: volatile u_int32_t *p, data;
1217:
1218: h += o;
1219: if (h & 0xf0000000) {
1220: p = (volatile u_int32_t *)h;
1221: while (c--) {
1222: data = *a++;
1223: *p++ = htole32(data);
1224: }
1225: } else {
1226: struct dino_softc *sc = v;
1227: volatile struct dino_regs *r = sc->sc_regs;
1228:
1229: for (; c--; h += 4) {
1230: r->pci_addr = h;
1231: data = *a++;
1232: r->pci_io_data = htole32(data);
1233: }
1234: }
1235: }
1236:
1237: void
1238: dino_wr_8(void *v, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c)
1239: {
1240: panic("dino_wr_8: not implemented");
1241: }
1242:
1243: void
1244: dino_rrr_2(void *v, bus_space_handle_t h, bus_size_t o,
1245: u_int8_t *a, bus_size_t c)
1246: {
1247: volatile u_int16_t *p, *q = (u_int16_t *)a;
1248:
1249: c /= 2;
1250: h += o;
1251: if (h & 0xf0000000) {
1252: p = (volatile u_int16_t *)h;
1253: while (c--)
1254: *q++ = *p++;
1255: } else {
1256: struct dino_softc *sc = v;
1257: volatile struct dino_regs *r = sc->sc_regs;
1258:
1259: for (; c--; h += 2) {
1260: r->pci_addr = h;
1261: p = (volatile u_int16_t *)&r->pci_io_data;
1262: if (h & 2)
1263: p++;
1264: *q++ = *p;
1265: }
1266: }
1267: }
1268:
1269: void
1270: dino_rrr_4(void *v, bus_space_handle_t h, bus_size_t o,
1271: u_int8_t *a, bus_size_t c)
1272: {
1273: volatile u_int32_t *p, *q = (u_int32_t *)a;
1274:
1275: c /= 4;
1276: h += o;
1277: if (h & 0xf0000000) {
1278: p = (volatile u_int32_t *)h;
1279: while (c--)
1280: *q++ = *p++;
1281: } else {
1282: struct dino_softc *sc = v;
1283: volatile struct dino_regs *r = sc->sc_regs;
1284:
1285: for (; c--; h += 4) {
1286: r->pci_addr = h;
1287: *q++ = r->pci_io_data;
1288: }
1289: }
1290: }
1291:
1292: void
1293: dino_rrr_8(void *v, bus_space_handle_t h, bus_size_t o,
1294: u_int8_t *a, bus_size_t c)
1295: {
1296: panic("dino_rrr_8: not implemented");
1297: }
1298:
1299: void
1300: dino_wrr_2(void *v, bus_space_handle_t h, bus_size_t o,
1301: const u_int8_t *a, bus_size_t c)
1302: {
1303: volatile u_int16_t *p;
1304: const u_int16_t *q = (u_int16_t *)a;
1305:
1306: c /= 2;
1307: h += o;
1308: if (h & 0xf0000000) {
1309: p = (volatile u_int16_t *)h;
1310: while (c--)
1311: *p++ = *q++;
1312: } else {
1313: struct dino_softc *sc = v;
1314: volatile struct dino_regs *r = sc->sc_regs;
1315:
1316: for (; c--; h += 2) {
1317: r->pci_addr = h;
1318: p = (volatile u_int16_t *)&r->pci_io_data;
1319: if (h & 2)
1320: p++;
1321: *p = *q++;
1322: }
1323: }
1324: }
1325:
1326: void
1327: dino_wrr_4(void *v, bus_space_handle_t h, bus_size_t o,
1328: const u_int8_t *a, bus_size_t c)
1329: {
1330: volatile u_int32_t *p;
1331: const u_int32_t *q = (u_int32_t *)a;
1332:
1333: c /= 4;
1334: h += o;
1335: if (h & 0xf0000000) {
1336: p = (volatile u_int32_t *)h;
1337: while (c--)
1338: *p++ = *q++;
1339: } else {
1340: struct dino_softc *sc = v;
1341: volatile struct dino_regs *r = sc->sc_regs;
1342:
1343: for (; c--; h += 4) {
1344: r->pci_addr = h;
1345: r->pci_io_data = *q++;
1346: }
1347: }
1348: }
1349:
1350: void
1351: dino_wrr_8(void *v, bus_space_handle_t h, bus_size_t o,
1352: const u_int8_t *a, bus_size_t c)
1353: {
1354: panic("dino_wrr_8: not implemented");
1355: }
1356:
1357: void
1358: dino_sr_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv, bus_size_t c)
1359: {
1360: volatile u_int8_t *p;
1361:
1362: h += o;
1363: if (h & 0xf0000000) {
1364: p = (volatile u_int8_t *)h;
1365: while (c--)
1366: *p++ = vv;
1367: } else {
1368: struct dino_softc *sc = v;
1369: volatile struct dino_regs *r = sc->sc_regs;
1370:
1371: for (; c--; h++) {
1372: r->pci_addr = h;
1373: p = (volatile u_int8_t *)&r->pci_io_data + (h & 3);
1374: *p = vv;
1375: }
1376: }
1377: }
1378:
1379: void
1380: dino_sr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
1381: {
1382: volatile u_int16_t *p;
1383:
1384: h += o;
1385: vv = htole16(vv);
1386: if (h & 0xf0000000) {
1387: p = (volatile u_int16_t *)h;
1388: while (c--)
1389: *p++ = vv;
1390: } else {
1391: struct dino_softc *sc = v;
1392: volatile struct dino_regs *r = sc->sc_regs;
1393:
1394: for (; c--; h += 2) {
1395: r->pci_addr = h;
1396: p = (volatile u_int16_t *)&r->pci_io_data;
1397: if (h & 2)
1398: p++;
1399: *p = vv;
1400: }
1401: }
1402: }
1403:
1404: void
1405: dino_sr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
1406: {
1407: volatile u_int32_t *p;
1408:
1409: h += o;
1410: vv = htole32(vv);
1411: if (h & 0xf0000000) {
1412: p = (volatile u_int32_t *)h;
1413: while (c--)
1414: *p++ = vv;
1415: } else {
1416: struct dino_softc *sc = v;
1417: volatile struct dino_regs *r = sc->sc_regs;
1418:
1419: for (; c--; h += 4) {
1420: r->pci_addr = h;
1421: r->pci_io_data = vv;
1422: }
1423: }
1424: }
1425:
1426: void
1427: dino_sr_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv, bus_size_t c)
1428: {
1429: panic("dino_sr_8: not implemented");
1430: }
1431:
1432: void
1433: dino_cp_1(void *v, bus_space_handle_t h1, bus_size_t o1,
1434: bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1435: {
1436: while (c--)
1437: dino_w1(v, h1, o1++, dino_r1(v, h2, o2++));
1438: }
1439:
1440: void
1441: dino_cp_2(void *v, bus_space_handle_t h1, bus_size_t o1,
1442: bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1443: {
1444: while (c--) {
1445: dino_w2(v, h1, o1, dino_r2(v, h2, o2));
1446: o1 += 2;
1447: o2 += 2;
1448: }
1449: }
1450:
1451: void
1452: dino_cp_4(void *v, bus_space_handle_t h1, bus_size_t o1,
1453: bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1454: {
1455: while (c--) {
1456: dino_w4(v, h1, o1, dino_r4(v, h2, o2));
1457: o1 += 4;
1458: o2 += 4;
1459: }
1460: }
1461:
1462: void
1463: dino_cp_8(void *v, bus_space_handle_t h1, bus_size_t o1,
1464: bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1465: {
1466: while (c--) {
1467: dino_w8(v, h1, o1, dino_r8(v, h2, o2));
1468: o1 += 8;
1469: o2 += 8;
1470: }
1471: }
1472:
1473:
1474: const struct hppa_bus_space_tag dino_iomemt = {
1475: NULL,
1476:
1477: NULL, dino_unmap, dino_subregion, NULL, dino_free,
1478: dino_barrier, NULL,
1479: dino_r1, dino_r2, dino_r4, dino_r8,
1480: dino_w1, dino_w2, dino_w4, dino_w8,
1481: dino_rm_1, dino_rm_2, dino_rm_4, dino_rm_8,
1482: dino_wm_1, dino_wm_2, dino_wm_4, dino_wm_8,
1483: dino_sm_1, dino_sm_2, dino_sm_4, dino_sm_8,
1484: dino_rrm_2, dino_rrm_4, dino_rrm_8,
1485: dino_wrm_2, dino_wrm_4, dino_wrm_8,
1486: dino_rr_1, dino_rr_2, dino_rr_4, dino_rr_8,
1487: dino_wr_1, dino_wr_2, dino_wr_4, dino_wr_8,
1488: dino_rrr_2, dino_rrr_4, dino_rrr_8,
1489: dino_wrr_2, dino_wrr_4, dino_wrr_8,
1490: dino_sr_1, dino_sr_2, dino_sr_4, dino_sr_8,
1491: dino_cp_1, dino_cp_2, dino_cp_4, dino_cp_8
1492: };
1493:
1494: int
1495: dino_dmamap_create(void *v, bus_size_t size, int nsegments,
1496: bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
1497: {
1498: struct dino_softc *sc = v;
1499:
1500: /* TODO check the addresses, boundary, enable dma */
1501:
1502: return (bus_dmamap_create(sc->sc_dmat, size, nsegments,
1503: maxsegsz, boundary, flags, dmamp));
1504: }
1505:
1506: void
1507: dino_dmamap_destroy(void *v, bus_dmamap_t map)
1508: {
1509: struct dino_softc *sc = v;
1510:
1511: bus_dmamap_destroy(sc->sc_dmat, map);
1512: }
1513:
1514: int
1515: dino_dmamap_load(void *v, bus_dmamap_t map, void *addr, bus_size_t size,
1516: struct proc *p, int flags)
1517: {
1518: struct dino_softc *sc = v;
1519:
1520: return (bus_dmamap_load(sc->sc_dmat, map, addr, size, p, flags));
1521: }
1522:
1523: int
1524: dino_dmamap_load_mbuf(void *v, bus_dmamap_t map, struct mbuf *m, int flags)
1525: {
1526: struct dino_softc *sc = v;
1527:
1528: return (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, flags));
1529: }
1530:
1531: int
1532: dino_dmamap_load_uio(void *v, bus_dmamap_t map, struct uio *uio, int flags)
1533: {
1534: struct dino_softc *sc = v;
1535:
1536: return (bus_dmamap_load_uio(sc->sc_dmat, map, uio, flags));
1537: }
1538:
1539: int
1540: dino_dmamap_load_raw(void *v, bus_dmamap_t map, bus_dma_segment_t *segs,
1541: int nsegs, bus_size_t size, int flags)
1542: {
1543: struct dino_softc *sc = v;
1544:
1545: return (bus_dmamap_load_raw(sc->sc_dmat, map, segs, nsegs, size, flags));
1546: }
1547:
1548: void
1549: dino_dmamap_unload(void *v, bus_dmamap_t map)
1550: {
1551: struct dino_softc *sc = v;
1552:
1553: bus_dmamap_unload(sc->sc_dmat, map);
1554: }
1555:
1556: void
1557: dino_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t off,
1558: bus_size_t len, int ops)
1559: {
1560: struct dino_softc *sc = v;
1561:
1562: return (bus_dmamap_sync(sc->sc_dmat, map, off, len, ops));
1563: }
1564:
1565: int
1566: dino_dmamem_alloc(void *v, bus_size_t size, bus_size_t alignment,
1567: bus_size_t boundary, bus_dma_segment_t *segs,
1568: int nsegs, int *rsegs, int flags)
1569: {
1570: struct dino_softc *sc = v;
1571:
1572: return (bus_dmamem_alloc(sc->sc_dmat, size, alignment, boundary,
1573: segs, nsegs, rsegs, flags));
1574: }
1575:
1576: void
1577: dino_dmamem_free(void *v, bus_dma_segment_t *segs, int nsegs)
1578: {
1579: struct dino_softc *sc = v;
1580:
1581: bus_dmamem_free(sc->sc_dmat, segs, nsegs);
1582: }
1583:
1584: int
1585: dino_dmamem_map(void *v, bus_dma_segment_t *segs, int nsegs, size_t size,
1586: caddr_t *kvap, int flags)
1587: {
1588: struct dino_softc *sc = v;
1589:
1590: return (bus_dmamem_map(sc->sc_dmat, segs, nsegs, size, kvap, flags));
1591: }
1592:
1593: void
1594: dino_dmamem_unmap(void *v, caddr_t kva, size_t size)
1595: {
1596: struct dino_softc *sc = v;
1597:
1598: bus_dmamem_unmap(sc->sc_dmat, kva, size);
1599: }
1600:
1601: paddr_t
1602: dino_dmamem_mmap(void *v, bus_dma_segment_t *segs, int nsegs, off_t off,
1603: int prot, int flags)
1604: {
1605: struct dino_softc *sc = v;
1606:
1607: return (bus_dmamem_mmap(sc->sc_dmat, segs, nsegs, off, prot, flags));
1608: }
1609:
1610: const struct hppa_bus_dma_tag dino_dmat = {
1611: NULL,
1612: dino_dmamap_create, dino_dmamap_destroy,
1613: dino_dmamap_load, dino_dmamap_load_mbuf,
1614: dino_dmamap_load_uio, dino_dmamap_load_raw,
1615: dino_dmamap_unload, dino_dmamap_sync,
1616:
1617: dino_dmamem_alloc, dino_dmamem_free, dino_dmamem_map,
1618: dino_dmamem_unmap, dino_dmamem_mmap
1619: };
1620:
1621: const struct hppa_pci_chipset_tag dino_pc = {
1622: NULL,
1623: dino_attach_hook, dino_maxdevs, dino_make_tag, dino_decompose_tag,
1624: dino_conf_read, dino_conf_write,
1625: dino_intr_map, dino_intr_string,
1626: dino_intr_establish, dino_intr_disestablish,
1627: #if NCARDBUS > 0
1628: dino_alloc_parent
1629: #else
1630: NULL
1631: #endif
1632: };
1633:
1634: int
1635: dinoprint(void *aux, const char *pnp)
1636: {
1637: struct pcibus_attach_args *pba = aux;
1638:
1639: if (pnp)
1640: printf("%s at %s\n", pba->pba_busname, pnp);
1641: return (UNCONF);
1642: }
1643:
1644: void
1645: dinoattach(parent, self, aux)
1646: struct device *parent;
1647: struct device *self;
1648: void *aux;
1649: {
1650: struct dino_softc *sc = (struct dino_softc *)self;
1651: struct confargs *ca = (struct confargs *)aux;
1652: struct pcibus_attach_args pba;
1653: volatile struct dino_regs *r;
1654: const char *p = NULL;
1655: u_int data;
1656: int s;
1657:
1658: sc->sc_bt = ca->ca_iot;
1659: sc->sc_dmat = ca->ca_dmatag;
1660: if (bus_space_map(sc->sc_bt, ca->ca_hpa, PAGE_SIZE, 0, &sc->sc_bh)) {
1661: printf(": can't map space\n");
1662: return;
1663: }
1664:
1665: sc->sc_regs = r = (volatile struct dino_regs *)sc->sc_bh;
1666: r->pciror = 0;
1667: r->pciwor = 0;
1668:
1669: /*
1670: * Do not reset enabled io mappings mask if we are still running
1671: * with PDC console - we'll do it after autoconf.
1672: */
1673: if (cn_tab->cn_putc != pdccnputc)
1674: r->io_addr_en = 0;
1675: sc->io_shadow = 0;
1676:
1677: r->gmask &= ~1; /* allow GSC bus req */
1678: r->brdg_feat &= ~0xf00;
1679: r->brdg_feat |= 3;
1680: #ifdef notyet_card_mode
1681: r->io_control = 0x80;
1682: r->pamr = 0;
1683: r->papr = 0;
1684: r->io_fbb_en |= 1;
1685: r->damode = 0;
1686: r->brdg_feat = 0xc0000000 XXX;
1687: r->mltim = 0x40; /* 64 clocks */
1688: r->tltim = 0x8c; /* 12 clocks */
1689:
1690: /* PCI reset */
1691: r->pcicmd = 0x6f;
1692: DELAY(10000); /* 10ms for reset to settle */
1693: #endif
1694:
1695: snprintf(sc->sc_ioexname, sizeof(sc->sc_ioexname),
1696: "%s_io", sc->sc_dv.dv_xname);
1697: if ((sc->sc_ioex = extent_create(sc->sc_ioexname, 0, 0xffff,
1698: M_DEVBUF, NULL, 0, EX_NOWAIT | EX_MALLOCOK)) == NULL) {
1699: printf(": cannot allocate I/O extent map\n");
1700: bus_space_unmap(sc->sc_bt, sc->sc_bh, PAGE_SIZE);
1701: return;
1702: }
1703:
1704: /* TODO reserve dino's pci space ? */
1705:
1706: s = splhigh();
1707: r->imr = ~0;
1708: data = r->irr0;
1709: data = r->irr1;
1710: r->imr = 0;
1711: __asm __volatile ("" ::: "memory");
1712: r->icr = 0;
1713: r->iar0 = cpu_gethpa(0) | (31 - ca->ca_irq);
1714: splx(s);
1715:
1716: sc->sc_ih = cpu_intr_establish(IPL_NESTED, ca->ca_irq,
1717: dino_intr, (void *)sc->sc_regs, sc->sc_dv.dv_xname);
1718: /* TODO establish the bus error interrupt */
1719:
1720: sc->sc_ver = ca->ca_type.iodc_revision;
1721: switch ((ca->ca_type.iodc_model << 4) |
1722: (ca->ca_type.iodc_revision >> 4)) {
1723: case 0x05d: /* j2240 */
1724: p = "Dino(card)";
1725: case 0x680:
1726: if (!p)
1727: p = "Dino";
1728: switch (ca->ca_type.iodc_revision & 0xf) {
1729: case 0: sc->sc_ver = 0x20; break;
1730: case 1: sc->sc_ver = 0x21; break;
1731: case 2: sc->sc_ver = 0x30; break;
1732: case 3: sc->sc_ver = 0x31; break;
1733: }
1734: break;
1735:
1736: case 0x682:
1737: p = "Cujo";
1738: switch (ca->ca_type.iodc_revision & 0xf) {
1739: case 0: sc->sc_ver = 0x10; break;
1740: case 1: sc->sc_ver = 0x20; break;
1741: }
1742: break;
1743:
1744: default:
1745: p = "Mojo";
1746: break;
1747: }
1748:
1749: printf(": %s V%d.%d\n", p, sc->sc_ver >> 4, sc->sc_ver & 0xf);
1750:
1751: sc->sc_iot = dino_iomemt;
1752: sc->sc_iot.hbt_cookie = sc;
1753: sc->sc_iot.hbt_map = dino_iomap;
1754: sc->sc_iot.hbt_alloc = dino_ioalloc;
1755: sc->sc_memt = dino_iomemt;
1756: sc->sc_memt.hbt_cookie = sc;
1757: sc->sc_memt.hbt_map = dino_memmap;
1758: sc->sc_memt.hbt_alloc = dino_memalloc;
1759: sc->sc_pc = dino_pc;
1760: sc->sc_pc._cookie = sc;
1761: sc->sc_dmatag = dino_dmat;
1762: sc->sc_dmatag._cookie = sc;
1763:
1764: /* scan for ps2 kbd/ms, serial, and flying toasters */
1765: ca->ca_hpamask = -1;
1766: pdc_scanbus(self, ca, MAXMODBUS, 0);
1767:
1768: pba.pba_busname = "pci";
1769: pba.pba_iot = &sc->sc_iot;
1770: pba.pba_memt = &sc->sc_memt;
1771: pba.pba_dmat = &sc->sc_dmatag;
1772: pba.pba_pc = &sc->sc_pc;
1773: pba.pba_domain = pci_ndomains++;
1774: pba.pba_bus = 0;
1775: pba.pba_bridgetag = NULL;
1776: config_found(self, &pba, dinoprint);
1777:
1778: /* postpone cleanup if necessary */
1779: if (r->io_addr_en != sc->io_shadow)
1780: startuphook_establish(dino_clear_pdc_mappings, sc);
1781:
1782: /* enable interrupts now that all the devices are there */
1783: r->imr = sc->sc_imr;
1784: }
1785:
1786: void
1787: dino_clear_pdc_mappings(void *v)
1788: {
1789: struct dino_softc *sc = (struct dino_softc *)v;
1790: volatile struct dino_regs *r;
1791:
1792: if (cn_tab->cn_putc == pdccnputc) {
1793: /* damn! */
1794: return;
1795: }
1796:
1797: r = sc->sc_regs;
1798: r->io_addr_en = sc->io_shadow;
1799: }
CVSweb