1 /* $OpenBSD: elroy.c,v 1.13 2024/05/22 14:25:47 jsg Exp $ */
2
3 /*
4 * Copyright (c) 2005 Michael Shalayeff
5 * All rights reserved.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
16 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 #include "cardbus.h"
21
22 #include <sys/param.h>
23 #include <sys/systm.h>
24 #include <sys/device.h>
25 #include <sys/reboot.h>
26 #include <sys/malloc.h>
27 #include <sys/extent.h>
28
29 #include <machine/iomod.h>
30 #include <machine/autoconf.h>
31
32 #include <arch/hppa/dev/cpudevs.h>
33
34 #if NCARDBUS > 0
35 #include <dev/cardbus/rbus.h>
36 #endif
37
38 #include <dev/pci/pcireg.h>
39 #include <dev/pci/pcivar.h>
40 #include <dev/pci/pcidevs.h>
41
42 #include <hppa/dev/elroyreg.h>
43 #include <hppa/dev/elroyvar.h>
44
45 #define ELROY_MEM_CHUNK 0x800000
46 #define ELROY_MEM_WINDOW (2 * ELROY_MEM_CHUNK)
47
48 int elroy_match(struct device *, void *, void *);
49 void elroy_attach(struct device *, struct device *, void *);
50
51 const struct cfattach elroy_ca = {
52 sizeof(struct elroy_softc), elroy_match, elroy_attach
53 };
54
55 struct cfdriver elroy_cd = {
56 NULL, "elroy", DV_DULL
57 };
58
59 void elroy_attach_hook(struct device *parent, struct device *self,
60 struct pcibus_attach_args *pba);
61 int elroy_maxdevs(void *v, int bus);
62 pcitag_t elroy_make_tag(void *v, int bus, int dev, int func);
63 void elroy_decompose_tag(void *v, pcitag_t tag, int *bus,
64 int *dev, int *func);
65 int elroy_conf_size(void *v, pcitag_t tag);
66 pcireg_t elroy_conf_read(void *v, pcitag_t tag, int reg);
67 void elroy_conf_write(void *v, pcitag_t tag, int reg,
68 pcireg_t data);
69 int elroy_iomap(void *v, bus_addr_t bpa, bus_size_t size,
70 int flags, bus_space_handle_t *bshp);
71 int elroy_memmap(void *v, bus_addr_t bpa, bus_size_t size,
72 int flags, bus_space_handle_t *bshp);
73 int elroy_subregion(void *v, bus_space_handle_t bsh,
74 bus_size_t offset, bus_size_t size,
75 bus_space_handle_t *nbshp);
76 int elroy_ioalloc(void *v, bus_addr_t rstart, bus_addr_t rend,
77 bus_size_t size, bus_size_t align, bus_size_t boundary,
78 int flags, bus_addr_t *addrp, bus_space_handle_t *bshp);
79 int elroy_memalloc(void *v, bus_addr_t rstart, bus_addr_t rend,
80 bus_size_t size, bus_size_t align, bus_size_t boundary,
81 int flags, bus_addr_t *addrp, bus_space_handle_t *bshp);
82 void elroy_unmap(void *v, bus_space_handle_t bsh,
83 bus_size_t size);
84 void elroy_free(void *v, bus_space_handle_t bh, bus_size_t size);
85 void elroy_barrier(void *v, bus_space_handle_t h, bus_size_t o,
86 bus_size_t l, int op);
87 void * elroy_alloc_parent(struct device *self,
88 struct pci_attach_args *pa, int io);
89 void * elroy_vaddr(void *v, bus_space_handle_t h);
90 u_int8_t elroy_r1(void *v, bus_space_handle_t h, bus_size_t o);
91 u_int16_t elroy_r2(void *v, bus_space_handle_t h, bus_size_t o);
92 u_int32_t elroy_r4(void *v, bus_space_handle_t h, bus_size_t o);
93 u_int64_t elroy_r8(void *v, bus_space_handle_t h, bus_size_t o);
94 void elroy_w1(void *v, bus_space_handle_t h, bus_size_t o,
95 u_int8_t vv);
96 void elroy_w2(void *v, bus_space_handle_t h, bus_size_t o,
97 u_int16_t vv);
98 void elroy_w4(void *v, bus_space_handle_t h, bus_size_t o,
99 u_int32_t vv);
100 void elroy_w8(void *v, bus_space_handle_t h, bus_size_t o,
101 u_int64_t vv);
102 void elroy_rm_1(void *v, bus_space_handle_t h, bus_size_t o,
103 u_int8_t *a, bus_size_t c);
104 void elroy_rm_2(void *v, bus_space_handle_t h, bus_size_t o,
105 u_int16_t *a, bus_size_t c);
106 void elroy_rm_4(void *v, bus_space_handle_t h, bus_size_t o,
107 u_int32_t *a, bus_size_t c);
108 void elroy_rm_8(void *v, bus_space_handle_t h, bus_size_t o,
109 u_int64_t *a, bus_size_t c);
110 void elroy_wm_1(void *v, bus_space_handle_t h, bus_size_t o,
111 const u_int8_t *a, bus_size_t c);
112 void elroy_wm_2(void *v, bus_space_handle_t h, bus_size_t o,
113 const u_int16_t *a, bus_size_t c);
114 void elroy_wm_4(void *v, bus_space_handle_t h, bus_size_t o,
115 const u_int32_t *a, bus_size_t c);
116 void elroy_wm_8(void *v, bus_space_handle_t h, bus_size_t o,
117 const u_int64_t *a, bus_size_t c);
118 void elroy_sm_1(void *v, bus_space_handle_t h, bus_size_t o,
119 u_int8_t vv, bus_size_t c);
120 void elroy_sm_2(void *v, bus_space_handle_t h, bus_size_t o,
121 u_int16_t vv, bus_size_t c);
122 void elroy_sm_4(void *v, bus_space_handle_t h, bus_size_t o,
123 u_int32_t vv, bus_size_t c);
124 void elroy_sm_8(void *v, bus_space_handle_t h, bus_size_t o,
125 u_int64_t vv, bus_size_t c);
126 void elroy_rrm_2(void *v, bus_space_handle_t h, bus_size_t o,
127 u_int8_t *a, bus_size_t c);
128 void elroy_rrm_4(void *v, bus_space_handle_t h, bus_size_t o,
129 u_int8_t *a, bus_size_t c);
130 void elroy_rrm_8(void *v, bus_space_handle_t h, bus_size_t o,
131 u_int8_t *a, bus_size_t c);
132 void elroy_wrm_2(void *v, bus_space_handle_t h, bus_size_t o,
133 const u_int8_t *a, bus_size_t c);
134 void elroy_wrm_4(void *v, bus_space_handle_t h, bus_size_t o,
135 const u_int8_t *a, bus_size_t c);
136 void elroy_wrm_8(void *v, bus_space_handle_t h, bus_size_t o,
137 const u_int8_t *a, bus_size_t c);
138 void elroy_rr_1(void *v, bus_space_handle_t h, bus_size_t o,
139 u_int8_t *a, bus_size_t c);
140 void elroy_rr_2(void *v, bus_space_handle_t h, bus_size_t o,
141 u_int16_t *a, bus_size_t c);
142 void elroy_rr_4(void *v, bus_space_handle_t h, bus_size_t o,
143 u_int32_t *a, bus_size_t c);
144 void elroy_rr_8(void *v, bus_space_handle_t h, bus_size_t o,
145 u_int64_t *a, bus_size_t c);
146 void elroy_wr_1(void *v, bus_space_handle_t h, bus_size_t o,
147 const u_int8_t *a, bus_size_t c);
148 void elroy_wr_2(void *v, bus_space_handle_t h, bus_size_t o,
149 const u_int16_t *a, bus_size_t c);
150 void elroy_wr_4(void *v, bus_space_handle_t h, bus_size_t o,
151 const u_int32_t *a, bus_size_t c);
152 void elroy_wr_8(void *v, bus_space_handle_t h, bus_size_t o,
153 const u_int64_t *a, bus_size_t c);
154 void elroy_rrr_2(void *v, bus_space_handle_t h, bus_size_t o,
155 u_int8_t *a, bus_size_t c);
156 void elroy_rrr_4(void *v, bus_space_handle_t h, bus_size_t o,
157 u_int8_t *a, bus_size_t c);
158 void elroy_rrr_8(void *v, bus_space_handle_t h, bus_size_t o,
159 u_int8_t *a, bus_size_t c);
160 void elroy_wrr_2(void *v, bus_space_handle_t h, bus_size_t o,
161 const u_int8_t *a, bus_size_t c);
162 void elroy_wrr_4(void *v, bus_space_handle_t h, bus_size_t o,
163 const u_int8_t *a, bus_size_t c);
164 void elroy_wrr_8(void *v, bus_space_handle_t h, bus_size_t o,
165 const u_int8_t *a, bus_size_t c);
166 void elroy_sr_1(void *v, bus_space_handle_t h, bus_size_t o,
167 u_int8_t vv, bus_size_t c);
168 void elroy_sr_2(void *v, bus_space_handle_t h, bus_size_t o,
169 u_int16_t vv, bus_size_t c);
170 void elroy_sr_4(void *v, bus_space_handle_t h, bus_size_t o,
171 u_int32_t vv, bus_size_t c);
172 void elroy_sr_8(void *v, bus_space_handle_t h, bus_size_t o,
173 u_int64_t vv, bus_size_t c);
174 void elroy_cp_1(void *v, bus_space_handle_t h1, bus_size_t o1,
175 bus_space_handle_t h2, bus_size_t o2, bus_size_t c);
176 void elroy_cp_2(void *v, bus_space_handle_t h1, bus_size_t o1,
177 bus_space_handle_t h2, bus_size_t o2, bus_size_t c);
178 void elroy_cp_4(void *v, bus_space_handle_t h1, bus_size_t o1,
179 bus_space_handle_t h2, bus_size_t o2, bus_size_t c);
180 void elroy_cp_8(void *v, bus_space_handle_t h1, bus_size_t o1,
181 bus_space_handle_t h2, bus_size_t o2, bus_size_t c);
182
183 int
elroy_match(struct device * parent,void * cfdata,void * aux)184 elroy_match(struct device *parent, void *cfdata, void *aux)
185 {
186 struct confargs *ca = aux;
187 /* struct cfdata *cf = cfdata; */
188
189 if ((ca->ca_name && !strcmp(ca->ca_name, "lba")) ||
190 (ca->ca_type.iodc_type == HPPA_TYPE_BRIDGE &&
191 ca->ca_type.iodc_sv_model == HPPA_BRIDGE_DINO &&
192 ca->ca_type.iodc_model == 0x78))
193 return (1);
194
195 return (0);
196 }
197
198 void
elroy_write32(volatile u_int32_t * p,u_int32_t v)199 elroy_write32(volatile u_int32_t *p, u_int32_t v)
200 {
201 *p = v;
202 }
203
204 u_int32_t
elroy_read32(volatile u_int32_t * p)205 elroy_read32(volatile u_int32_t *p)
206 {
207 return *p;
208 }
209
210 void
elroy_attach_hook(struct device * parent,struct device * self,struct pcibus_attach_args * pba)211 elroy_attach_hook(struct device *parent, struct device *self,
212 struct pcibus_attach_args *pba)
213 {
214
215 }
216
217 int
elroy_maxdevs(void * v,int bus)218 elroy_maxdevs(void *v, int bus)
219 {
220 return (32);
221 }
222
223 pcitag_t
elroy_make_tag(void * v,int bus,int dev,int func)224 elroy_make_tag(void *v, int bus, int dev, int func)
225 {
226 if (bus > 255 || dev > 31 || func > 7)
227 panic("elroy_make_tag: bad request");
228
229 return ((bus << 16) | (dev << 11) | (func << 8));
230 }
231
232 void
elroy_decompose_tag(void * v,pcitag_t tag,int * bus,int * dev,int * func)233 elroy_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func)
234 {
235 if (bus)
236 *bus = (tag >> 16) & 0xff;
237 if (dev)
238 *dev = (tag >> 11) & 0x1f;
239 if (func)
240 *func= (tag >> 8) & 0x07;
241 }
242
243 int
elroy_conf_size(void * v,pcitag_t tag)244 elroy_conf_size(void *v, pcitag_t tag)
245 {
246 return PCI_CONFIG_SPACE_SIZE;
247 }
248
249 pcireg_t
elroy_conf_read(void * v,pcitag_t tag,int reg)250 elroy_conf_read(void *v, pcitag_t tag, int reg)
251 {
252 struct elroy_softc *sc = v;
253 volatile struct elroy_regs *r = sc->sc_regs;
254 u_int32_t arb_mask, err_cfg, control;
255 pcireg_t data, data1;
256
257 /* printf("elroy_conf_read(%p, 0x%08x, 0x%x)", v, tag, reg); */
258 arb_mask = elroy_read32(&r->arb_mask);
259 err_cfg = elroy_read32(&r->err_cfg);
260 control = elroy_read32(&r->control);
261 if (!arb_mask)
262 elroy_write32(&r->arb_mask, htole32(ELROY_ARB_ENABLE));
263 elroy_write32(&r->err_cfg, err_cfg |
264 htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM));
265 elroy_write32(&r->control, (control | htole32(ELROY_CONTROL_CE)) &
266 ~htole32(ELROY_CONTROL_HF));
267
268 elroy_write32(&r->pci_conf_addr, htole32(tag | reg));
269 data1 = elroy_read32(&r->pci_conf_addr);
270 data = elroy_read32(&r->pci_conf_data);
271
272 elroy_write32(&r->control, control |
273 htole32(ELROY_CONTROL_CE|ELROY_CONTROL_CL));
274 elroy_write32(&r->control, control);
275 elroy_write32(&r->err_cfg, err_cfg);
276 if (!arb_mask)
277 elroy_write32(&r->arb_mask, arb_mask);
278
279 data = letoh32(data);
280 /* printf("=0x%08x (@ 0x%08x)\n", data, letoh32(data1)); */
281 return (data);
282 }
283
284 void
elroy_conf_write(void * v,pcitag_t tag,int reg,pcireg_t data)285 elroy_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
286 {
287 struct elroy_softc *sc = v;
288 volatile struct elroy_regs *r = sc->sc_regs;
289 u_int32_t arb_mask, err_cfg, control;
290 pcireg_t data1;
291
292 /* printf("elroy_conf_write(%p, 0x%08x, 0x%x, 0x%x)\n", v, tag, reg, data); */
293 arb_mask = elroy_read32(&r->arb_mask);
294 err_cfg = elroy_read32(&r->err_cfg);
295 control = elroy_read32(&r->control);
296 if (!arb_mask)
297 elroy_write32(&r->arb_mask, htole32(ELROY_ARB_ENABLE));
298 elroy_write32(&r->err_cfg, err_cfg |
299 htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM));
300 elroy_write32(&r->control, (control | htole32(ELROY_CONTROL_CE)) &
301 ~htole32(ELROY_CONTROL_HF));
302
303 /* fix coalescing config writes errata by interleaving w/ a read */
304 elroy_write32(&r->pci_conf_addr, htole32(tag | PCI_ID_REG));
305 data1 = elroy_read32(&r->pci_conf_addr);
306 data1 = elroy_read32(&r->pci_conf_data);
307
308 elroy_write32(&r->pci_conf_addr, htole32(tag | reg));
309 data1 = elroy_read32(&r->pci_conf_addr);
310 elroy_write32(&r->pci_conf_data, htole32(data));
311 data1 = elroy_read32(&r->pci_conf_addr);
312
313 elroy_write32(&r->control, control |
314 htole32(ELROY_CONTROL_CE|ELROY_CONTROL_CL));
315 elroy_write32(&r->control, control);
316 elroy_write32(&r->err_cfg, err_cfg);
317 if (!arb_mask)
318 elroy_write32(&r->arb_mask, arb_mask);
319 }
320
321 int
elroy_iomap(void * v,bus_addr_t bpa,bus_size_t size,int flags,bus_space_handle_t * bshp)322 elroy_iomap(void *v, bus_addr_t bpa, bus_size_t size,
323 int flags, bus_space_handle_t *bshp)
324 {
325 struct elroy_softc *sc = v;
326 /* volatile struct elroy_regs *r = sc->sc_regs; */
327 int error;
328
329 if ((error = bus_space_map(sc->sc_bt, bpa + sc->sc_iobase, size,
330 flags, bshp)))
331 return (error);
332
333 return (0);
334 }
335
336 int
elroy_memmap(void * v,bus_addr_t bpa,bus_size_t size,int flags,bus_space_handle_t * bshp)337 elroy_memmap(void *v, bus_addr_t bpa, bus_size_t size,
338 int flags, bus_space_handle_t *bshp)
339 {
340 struct elroy_softc *sc = v;
341 /* volatile struct elroy_regs *r = sc->sc_regs; */
342 int error;
343
344 if ((error = bus_space_map(sc->sc_bt, bpa, size, flags, bshp)))
345 return (error);
346
347 return (0);
348 }
349
350 int
elroy_subregion(void * v,bus_space_handle_t bsh,bus_size_t offset,bus_size_t size,bus_space_handle_t * nbshp)351 elroy_subregion(void *v, bus_space_handle_t bsh, bus_size_t offset,
352 bus_size_t size, bus_space_handle_t *nbshp)
353 {
354 *nbshp = bsh + offset;
355 return (0);
356 }
357
358 int
elroy_ioalloc(void * v,bus_addr_t rstart,bus_addr_t rend,bus_size_t size,bus_size_t align,bus_size_t boundary,int flags,bus_addr_t * addrp,bus_space_handle_t * bshp)359 elroy_ioalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
360 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
361 bus_space_handle_t *bshp)
362 {
363 struct elroy_softc *sc = v;
364 volatile struct elroy_regs *r = sc->sc_regs;
365 bus_addr_t iostart, ioend;
366
367 iostart = r->io_base & ~htole32(ELROY_BASE_RE);
368 ioend = iostart + ~htole32(r->io_mask) + 1;
369 if (rstart < iostart || rend > ioend)
370 panic("elroy_ioalloc: bad region start/end");
371
372 rstart += sc->sc_iobase;
373 rend += sc->sc_iobase;
374 if (bus_space_alloc(sc->sc_bt, rstart, rend, size,
375 align, boundary, flags, addrp, bshp))
376 return (ENOMEM);
377
378 return (0);
379 }
380
381 int
elroy_memalloc(void * v,bus_addr_t rstart,bus_addr_t rend,bus_size_t size,bus_size_t align,bus_size_t boundary,int flags,bus_addr_t * addrp,bus_space_handle_t * bshp)382 elroy_memalloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size,
383 bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp,
384 bus_space_handle_t *bshp)
385 {
386 struct elroy_softc *sc = v;
387 /* volatile struct elroy_regs *r = sc->sc_regs; */
388
389 if (bus_space_alloc(sc->sc_bt, rstart, rend, size,
390 align, boundary, flags, addrp, bshp))
391 return (ENOMEM);
392
393 return (0);
394 }
395
396 void
elroy_unmap(void * v,bus_space_handle_t bsh,bus_size_t size)397 elroy_unmap(void *v, bus_space_handle_t bsh, bus_size_t size)
398 {
399 struct elroy_softc *sc = v;
400
401 bus_space_free(sc->sc_bt, bsh, size);
402 }
403
404 void
elroy_free(void * v,bus_space_handle_t bh,bus_size_t size)405 elroy_free(void *v, bus_space_handle_t bh, bus_size_t size)
406 {
407 /* should be enough */
408 elroy_unmap(v, bh, size);
409 }
410
411 void
elroy_barrier(void * v,bus_space_handle_t h,bus_size_t o,bus_size_t l,int op)412 elroy_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op)
413 {
414 struct elroy_softc *sc = v;
415 volatile struct elroy_regs *r = sc->sc_regs;
416 u_int32_t data;
417
418 sync_caches();
419 if (op & BUS_SPACE_BARRIER_WRITE) {
420 data = r->pci_id; /* flush write fifo */
421 sync_caches();
422 }
423 }
424
425 #if NCARDBUS > 0
426 void *
elroy_alloc_parent(struct device * self,struct pci_attach_args * pa,int io)427 elroy_alloc_parent(struct device *self, struct pci_attach_args *pa, int io)
428 {
429 #if 0 /* TODO */
430
431 struct elroy_softc *sc = pa->pa_pc->_cookie;
432 struct extent *ex;
433 bus_space_tag_t tag;
434 bus_addr_t start;
435 bus_size_t size;
436
437 if (io) {
438 ex = sc->sc_ioex;
439 tag = pa->pa_iot;
440 start = 0xa000;
441 size = 0x1000;
442 } else {
443 if (!sc->sc_memex) {
444 bus_space_handle_t memh;
445 bus_addr_t mem_start;
446
447 if (elroy_memalloc(sc, 0xf0800000, 0xff7fffff,
448 ELROY_MEM_WINDOW, ELROY_MEM_WINDOW, EX_NOBOUNDARY,
449 0, &mem_start, &memh))
450 return (NULL);
451
452 snprintf(sc->sc_memexname, sizeof(sc->sc_memexname),
453 "%s_mem", sc->sc_dv.dv_xname);
454 if ((sc->sc_memex = extent_create(sc->sc_memexname,
455 mem_start, mem_start + ELROY_MEM_WINDOW, M_DEVBUF,
456 NULL, 0, EX_NOWAIT | EX_MALLOCOK)) == NULL) {
457 extent_destroy(sc->sc_ioex);
458 bus_space_free(sc->sc_bt, memh,
459 ELROY_MEM_WINDOW);
460 return (NULL);
461 }
462 }
463 ex = sc->sc_memex;
464 tag = pa->pa_memt;
465 start = ex->ex_start;
466 size = ELROY_MEM_CHUNK;
467 }
468
469 if (extent_alloc_subregion(ex, start, ex->ex_end, size, size, 0,
470 EX_NOBOUNDARY, EX_NOWAIT, &start))
471 return (NULL);
472
473 extent_free(ex, start, size, EX_NOWAIT);
474 return rbus_new_root_share(tag, ex, start, size);
475 #else
476 return (NULL);
477 #endif
478 }
479 #endif
480
481 void *
elroy_vaddr(void * v,bus_space_handle_t h)482 elroy_vaddr(void *v, bus_space_handle_t h)
483 {
484 return ((void *)h);
485 }
486
487 u_int8_t
elroy_r1(void * v,bus_space_handle_t h,bus_size_t o)488 elroy_r1(void *v, bus_space_handle_t h, bus_size_t o)
489 {
490 h += o;
491 return *(volatile u_int8_t *)h;
492 }
493
494 u_int16_t
elroy_r2(void * v,bus_space_handle_t h,bus_size_t o)495 elroy_r2(void *v, bus_space_handle_t h, bus_size_t o)
496 {
497 volatile u_int16_t *p;
498
499 h += o;
500 p = (volatile u_int16_t *)h;
501 return (letoh16(*p));
502 }
503
504 u_int32_t
elroy_r4(void * v,bus_space_handle_t h,bus_size_t o)505 elroy_r4(void *v, bus_space_handle_t h, bus_size_t o)
506 {
507 u_int32_t data;
508
509 h += o;
510 data = *(volatile u_int32_t *)h;
511 return (letoh32(data));
512 }
513
514 u_int64_t
elroy_r8(void * v,bus_space_handle_t h,bus_size_t o)515 elroy_r8(void *v, bus_space_handle_t h, bus_size_t o)
516 {
517 u_int64_t data;
518
519 h += o;
520 data = *(volatile u_int64_t *)h;
521 return (letoh64(data));
522 }
523
524 void
elroy_w1(void * v,bus_space_handle_t h,bus_size_t o,u_int8_t vv)525 elroy_w1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv)
526 {
527 h += o;
528 *(volatile u_int8_t *)h = vv;
529 }
530
531 void
elroy_w2(void * v,bus_space_handle_t h,bus_size_t o,u_int16_t vv)532 elroy_w2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv)
533 {
534 volatile u_int16_t *p;
535
536 h += o;
537 p = (volatile u_int16_t *)h;
538 *p = htole16(vv);
539 }
540
541 void
elroy_w4(void * v,bus_space_handle_t h,bus_size_t o,u_int32_t vv)542 elroy_w4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv)
543 {
544 h += o;
545 vv = htole32(vv);
546 *(volatile u_int32_t *)h = vv;
547 }
548
549 void
elroy_w8(void * v,bus_space_handle_t h,bus_size_t o,u_int64_t vv)550 elroy_w8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv)
551 {
552 h += o;
553 *(volatile u_int64_t *)h = htole64(vv);
554 }
555
556
557 void
elroy_rm_1(void * v,bus_space_handle_t h,bus_size_t o,u_int8_t * a,bus_size_t c)558 elroy_rm_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t *a, bus_size_t c)
559 {
560 volatile u_int8_t *p;
561
562 h += o;
563 p = (volatile u_int8_t *)h;
564 while (c--)
565 *a++ = *p;
566 }
567
568 void
elroy_rm_2(void * v,bus_space_handle_t h,bus_size_t o,u_int16_t * a,bus_size_t c)569 elroy_rm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
570 {
571 volatile u_int16_t *p;
572
573 h += o;
574 p = (volatile u_int16_t *)h;
575 while (c--)
576 *a++ = letoh16(*p);
577 }
578
579 void
elroy_rm_4(void * v,bus_space_handle_t h,bus_size_t o,u_int32_t * a,bus_size_t c)580 elroy_rm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
581 {
582 volatile u_int32_t *p;
583
584 h += o;
585 p = (volatile u_int32_t *)h;
586 while (c--)
587 *a++ = letoh32(*p);
588 }
589
590 void
elroy_rm_8(void * v,bus_space_handle_t h,bus_size_t o,u_int64_t * a,bus_size_t c)591 elroy_rm_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c)
592 {
593 volatile u_int64_t *p;
594
595 h += o;
596 p = (volatile u_int64_t *)h;
597 while (c--)
598 *a++ = letoh64(*p);
599 }
600
601 void
elroy_wm_1(void * v,bus_space_handle_t h,bus_size_t o,const u_int8_t * a,bus_size_t c)602 elroy_wm_1(void *v, bus_space_handle_t h, bus_size_t o, const u_int8_t *a, bus_size_t c)
603 {
604 volatile u_int8_t *p;
605
606 h += o;
607 p = (volatile u_int8_t *)h;
608 while (c--)
609 *p = *a++;
610 }
611
612 void
elroy_wm_2(void * v,bus_space_handle_t h,bus_size_t o,const u_int16_t * a,bus_size_t c)613 elroy_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
614 {
615 volatile u_int16_t *p;
616
617 h += o;
618 p = (volatile u_int16_t *)h;
619 while (c--)
620 *p = htole16(*a++);
621 }
622
623 void
elroy_wm_4(void * v,bus_space_handle_t h,bus_size_t o,const u_int32_t * a,bus_size_t c)624 elroy_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
625 {
626 volatile u_int32_t *p;
627
628 h += o;
629 p = (volatile u_int32_t *)h;
630 while (c--)
631 *p = htole32(*a++);
632 }
633
634 void
elroy_wm_8(void * v,bus_space_handle_t h,bus_size_t o,const u_int64_t * a,bus_size_t c)635 elroy_wm_8(void *v, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c)
636 {
637 volatile u_int64_t *p;
638
639 h += o;
640 p = (volatile u_int64_t *)h;
641 while (c--)
642 *p = htole64(*a++);
643 }
644
645 void
elroy_sm_1(void * v,bus_space_handle_t h,bus_size_t o,u_int8_t vv,bus_size_t c)646 elroy_sm_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv, bus_size_t c)
647 {
648 volatile u_int8_t *p;
649
650 h += o;
651 p = (volatile u_int8_t *)h;
652 while (c--)
653 *p = vv;
654 }
655
656 void
elroy_sm_2(void * v,bus_space_handle_t h,bus_size_t o,u_int16_t vv,bus_size_t c)657 elroy_sm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
658 {
659 volatile u_int16_t *p;
660
661 h += o;
662 p = (volatile u_int16_t *)h;
663 vv = htole16(vv);
664 while (c--)
665 *p = vv;
666 }
667
668 void
elroy_sm_4(void * v,bus_space_handle_t h,bus_size_t o,u_int32_t vv,bus_size_t c)669 elroy_sm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
670 {
671 volatile u_int32_t *p;
672
673 h += o;
674 p = (volatile u_int32_t *)h;
675 vv = htole32(vv);
676 while (c--)
677 *p = vv;
678 }
679
680 void
elroy_sm_8(void * v,bus_space_handle_t h,bus_size_t o,u_int64_t vv,bus_size_t c)681 elroy_sm_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv, bus_size_t c)
682 {
683 volatile u_int64_t *p;
684
685 h += o;
686 p = (volatile u_int64_t *)h;
687 vv = htole64(vv);
688 while (c--)
689 *p = vv;
690 }
691
692 void
elroy_rrm_2(void * v,bus_space_handle_t h,bus_size_t o,u_int8_t * a,bus_size_t c)693 elroy_rrm_2(void *v, bus_space_handle_t h, bus_size_t o,
694 u_int8_t *a, bus_size_t c)
695 {
696 volatile u_int16_t *p, *q = (u_int16_t *)a;
697
698 h += o;
699 p = (volatile u_int16_t *)h;
700 c /= 2;
701 while (c--)
702 *q++ = *p;
703 }
704
705 void
elroy_rrm_4(void * v,bus_space_handle_t h,bus_size_t o,u_int8_t * a,bus_size_t c)706 elroy_rrm_4(void *v, bus_space_handle_t h, bus_size_t o,
707 u_int8_t *a, bus_size_t c)
708 {
709 volatile u_int32_t *p, *q = (u_int32_t *)a;
710
711 h += o;
712 p = (volatile u_int32_t *)h;
713 c /= 4;
714 while (c--)
715 *q++ = *p;
716 }
717
718 void
elroy_rrm_8(void * v,bus_space_handle_t h,bus_size_t o,u_int8_t * a,bus_size_t c)719 elroy_rrm_8(void *v, bus_space_handle_t h, bus_size_t o,
720 u_int8_t *a, bus_size_t c)
721 {
722 volatile u_int64_t *p, *q = (u_int64_t *)a;
723
724 h += o;
725 p = (volatile u_int64_t *)h;
726 c /= 8;
727 while (c--)
728 *q++ = *p;
729 }
730
731 void
elroy_wrm_2(void * v,bus_space_handle_t h,bus_size_t o,const u_int8_t * a,bus_size_t c)732 elroy_wrm_2(void *v, bus_space_handle_t h, bus_size_t o,
733 const u_int8_t *a, bus_size_t c)
734 {
735 volatile u_int16_t *p;
736 const u_int16_t *q = (const u_int16_t *)a;
737
738 h += o;
739 p = (volatile u_int16_t *)h;
740 c /= 2;
741 while (c--)
742 *p = *q++;
743 }
744
745 void
elroy_wrm_4(void * v,bus_space_handle_t h,bus_size_t o,const u_int8_t * a,bus_size_t c)746 elroy_wrm_4(void *v, bus_space_handle_t h, bus_size_t o,
747 const u_int8_t *a, bus_size_t c)
748 {
749 volatile u_int32_t *p;
750 const u_int32_t *q = (const u_int32_t *)a;
751
752 h += o;
753 p = (volatile u_int32_t *)h;
754 c /= 4;
755 while (c--)
756 *p = *q++;
757 }
758
759 void
elroy_wrm_8(void * v,bus_space_handle_t h,bus_size_t o,const u_int8_t * a,bus_size_t c)760 elroy_wrm_8(void *v, bus_space_handle_t h, bus_size_t o,
761 const u_int8_t *a, bus_size_t c)
762 {
763 volatile u_int64_t *p;
764 const u_int64_t *q = (const u_int64_t *)a;
765
766 h += o;
767 p = (volatile u_int64_t *)h;
768 c /= 8;
769 while (c--)
770 *p = *q++;
771 }
772
773 void
elroy_rr_1(void * v,bus_space_handle_t h,bus_size_t o,u_int8_t * a,bus_size_t c)774 elroy_rr_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t *a, bus_size_t c)
775 {
776 volatile u_int8_t *p;
777
778 h += o;
779 p = (volatile u_int8_t *)h;
780 while (c--)
781 *a++ = *p++;
782 }
783
784 void
elroy_rr_2(void * v,bus_space_handle_t h,bus_size_t o,u_int16_t * a,bus_size_t c)785 elroy_rr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
786 {
787 volatile u_int16_t *p, data;
788
789 h += o;
790 p = (volatile u_int16_t *)h;
791 while (c--) {
792 data = *p++;
793 *a++ = letoh16(data);
794 }
795 }
796
797 void
elroy_rr_4(void * v,bus_space_handle_t h,bus_size_t o,u_int32_t * a,bus_size_t c)798 elroy_rr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
799 {
800 volatile u_int32_t *p, data;
801
802 h += o;
803 p = (volatile u_int32_t *)h;
804 while (c--) {
805 data = *p++;
806 *a++ = letoh32(data);
807 }
808 }
809
810 void
elroy_rr_8(void * v,bus_space_handle_t h,bus_size_t o,u_int64_t * a,bus_size_t c)811 elroy_rr_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t *a, bus_size_t c)
812 {
813 volatile u_int64_t *p, data;
814
815 h += o;
816 p = (volatile u_int64_t *)h;
817 while (c--) {
818 data = *p++;
819 *a++ = letoh64(data);
820 }
821 }
822
823 void
elroy_wr_1(void * v,bus_space_handle_t h,bus_size_t o,const u_int8_t * a,bus_size_t c)824 elroy_wr_1(void *v, bus_space_handle_t h, bus_size_t o, const u_int8_t *a, bus_size_t c)
825 {
826 volatile u_int8_t *p;
827
828 h += o;
829 p = (volatile u_int8_t *)h;
830 while (c--)
831 *p++ = *a++;
832 }
833
834 void
elroy_wr_2(void * v,bus_space_handle_t h,bus_size_t o,const u_int16_t * a,bus_size_t c)835 elroy_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
836 {
837 volatile u_int16_t *p, data;
838
839 h += o;
840 p = (volatile u_int16_t *)h;
841 while (c--) {
842 data = *a++;
843 *p++ = htole16(data);
844 }
845 }
846
847 void
elroy_wr_4(void * v,bus_space_handle_t h,bus_size_t o,const u_int32_t * a,bus_size_t c)848 elroy_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
849 {
850 volatile u_int32_t *p, data;
851
852 h += o;
853 p = (volatile u_int32_t *)h;
854 while (c--) {
855 data = *a++;
856 *p++ = htole32(data);
857 }
858 }
859
860 void
elroy_wr_8(void * v,bus_space_handle_t h,bus_size_t o,const u_int64_t * a,bus_size_t c)861 elroy_wr_8(void *v, bus_space_handle_t h, bus_size_t o, const u_int64_t *a, bus_size_t c)
862 {
863 volatile u_int64_t *p, data;
864
865 h += o;
866 p = (volatile u_int64_t *)h;
867 while (c--) {
868 data = *a++;
869 *p++ = htole64(data);
870 }
871 }
872
873 void
elroy_rrr_2(void * v,bus_space_handle_t h,bus_size_t o,u_int8_t * a,bus_size_t c)874 elroy_rrr_2(void *v, bus_space_handle_t h, bus_size_t o,
875 u_int8_t *a, bus_size_t c)
876 {
877 volatile u_int16_t *p, *q = (u_int16_t *)a;
878
879 c /= 2;
880 h += o;
881 p = (volatile u_int16_t *)h;
882 while (c--)
883 *q++ = *p++;
884 }
885
886 void
elroy_rrr_4(void * v,bus_space_handle_t h,bus_size_t o,u_int8_t * a,bus_size_t c)887 elroy_rrr_4(void *v, bus_space_handle_t h, bus_size_t o,
888 u_int8_t *a, bus_size_t c)
889 {
890 volatile u_int32_t *p, *q = (u_int32_t *)a;
891
892 c /= 4;
893 h += o;
894 p = (volatile u_int32_t *)h;
895 while (c--)
896 *q++ = *p++;
897 }
898
899 void
elroy_rrr_8(void * v,bus_space_handle_t h,bus_size_t o,u_int8_t * a,bus_size_t c)900 elroy_rrr_8(void *v, bus_space_handle_t h, bus_size_t o,
901 u_int8_t *a, bus_size_t c)
902 {
903 volatile u_int64_t *p, *q = (u_int64_t *)a;
904
905 c /= 8;
906 h += o;
907 p = (volatile u_int64_t *)h;
908 while (c--)
909 *q++ = *p++;
910 }
911
912 void
elroy_wrr_2(void * v,bus_space_handle_t h,bus_size_t o,const u_int8_t * a,bus_size_t c)913 elroy_wrr_2(void *v, bus_space_handle_t h, bus_size_t o,
914 const u_int8_t *a, bus_size_t c)
915 {
916 volatile u_int16_t *p;
917 const u_int16_t *q = (u_int16_t *)a;
918
919 c /= 2;
920 h += o;
921 p = (volatile u_int16_t *)h;
922 while (c--)
923 *p++ = *q++;
924 }
925
926 void
elroy_wrr_4(void * v,bus_space_handle_t h,bus_size_t o,const u_int8_t * a,bus_size_t c)927 elroy_wrr_4(void *v, bus_space_handle_t h, bus_size_t o,
928 const u_int8_t *a, bus_size_t c)
929 {
930 volatile u_int32_t *p;
931 const u_int32_t *q = (u_int32_t *)a;
932
933 c /= 4;
934 h += o;
935 p = (volatile u_int32_t *)h;
936 while (c--)
937 *p++ = *q++;
938 }
939
940 void
elroy_wrr_8(void * v,bus_space_handle_t h,bus_size_t o,const u_int8_t * a,bus_size_t c)941 elroy_wrr_8(void *v, bus_space_handle_t h, bus_size_t o,
942 const u_int8_t *a, bus_size_t c)
943 {
944 volatile u_int64_t *p;
945 const u_int64_t *q = (u_int64_t *)a;
946
947 c /= 8;
948 h += o;
949 p = (volatile u_int64_t *)h;
950 while (c--)
951 *p++ = *q++;
952 }
953
954 void
elroy_sr_1(void * v,bus_space_handle_t h,bus_size_t o,u_int8_t vv,bus_size_t c)955 elroy_sr_1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv, bus_size_t c)
956 {
957 volatile u_int8_t *p;
958
959 h += o;
960 p = (volatile u_int8_t *)h;
961 while (c--)
962 *p++ = vv;
963 }
964
965 void
elroy_sr_2(void * v,bus_space_handle_t h,bus_size_t o,u_int16_t vv,bus_size_t c)966 elroy_sr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
967 {
968 volatile u_int16_t *p;
969
970 h += o;
971 vv = htole16(vv);
972 p = (volatile u_int16_t *)h;
973 while (c--)
974 *p++ = vv;
975 }
976
977 void
elroy_sr_4(void * v,bus_space_handle_t h,bus_size_t o,u_int32_t vv,bus_size_t c)978 elroy_sr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
979 {
980 volatile u_int32_t *p;
981
982 h += o;
983 vv = htole32(vv);
984 p = (volatile u_int32_t *)h;
985 while (c--)
986 *p++ = vv;
987 }
988
989 void
elroy_sr_8(void * v,bus_space_handle_t h,bus_size_t o,u_int64_t vv,bus_size_t c)990 elroy_sr_8(void *v, bus_space_handle_t h, bus_size_t o, u_int64_t vv, bus_size_t c)
991 {
992 volatile u_int64_t *p;
993
994 h += o;
995 vv = htole64(vv);
996 p = (volatile u_int64_t *)h;
997 while (c--)
998 *p++ = vv;
999 }
1000
1001 void
elroy_cp_1(void * v,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t c)1002 elroy_cp_1(void *v, bus_space_handle_t h1, bus_size_t o1,
1003 bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1004 {
1005 while (c--)
1006 elroy_w1(v, h1, o1++, elroy_r1(v, h2, o2++));
1007 }
1008
1009 void
elroy_cp_2(void * v,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t c)1010 elroy_cp_2(void *v, bus_space_handle_t h1, bus_size_t o1,
1011 bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1012 {
1013 while (c--) {
1014 elroy_w2(v, h1, o1, elroy_r2(v, h2, o2));
1015 o1 += 2;
1016 o2 += 2;
1017 }
1018 }
1019
1020 void
elroy_cp_4(void * v,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t c)1021 elroy_cp_4(void *v, bus_space_handle_t h1, bus_size_t o1,
1022 bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1023 {
1024 while (c--) {
1025 elroy_w4(v, h1, o1, elroy_r4(v, h2, o2));
1026 o1 += 4;
1027 o2 += 4;
1028 }
1029 }
1030
1031 void
elroy_cp_8(void * v,bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t c)1032 elroy_cp_8(void *v, bus_space_handle_t h1, bus_size_t o1,
1033 bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
1034 {
1035 while (c--) {
1036 elroy_w8(v, h1, o1, elroy_r8(v, h2, o2));
1037 o1 += 8;
1038 o2 += 8;
1039 }
1040 }
1041
1042 const struct hppa_bus_space_tag elroy_iomemt = {
1043 NULL,
1044
1045 NULL, elroy_unmap, elroy_subregion, NULL, elroy_free,
1046 elroy_barrier, elroy_vaddr,
1047 elroy_r1, elroy_r2, elroy_r4, elroy_r8,
1048 elroy_w1, elroy_w2, elroy_w4, elroy_w8,
1049 elroy_rm_1, elroy_rm_2, elroy_rm_4, elroy_rm_8,
1050 elroy_wm_1, elroy_wm_2, elroy_wm_4, elroy_wm_8,
1051 elroy_sm_1, elroy_sm_2, elroy_sm_4, elroy_sm_8,
1052 elroy_rrm_2, elroy_rrm_4, elroy_rrm_8,
1053 elroy_wrm_2, elroy_wrm_4, elroy_wrm_8,
1054 elroy_rr_1, elroy_rr_2, elroy_rr_4, elroy_rr_8,
1055 elroy_wr_1, elroy_wr_2, elroy_wr_4, elroy_wr_8,
1056 elroy_rrr_2, elroy_rrr_4, elroy_rrr_8,
1057 elroy_wrr_2, elroy_wrr_4, elroy_wrr_8,
1058 elroy_sr_1, elroy_sr_2, elroy_sr_4, elroy_sr_8,
1059 elroy_cp_1, elroy_cp_2, elroy_cp_4, elroy_cp_8
1060 };
1061
1062 int elroy_dmamap_create(void *v, bus_size_t size,
1063 int nsegments, bus_size_t maxsegsz,
1064 bus_size_t boundary, int flags,
1065 bus_dmamap_t *dmamp);
1066 void elroy_dmamap_destroy(void *v, bus_dmamap_t map);
1067 int elroy_dmamap_load(void *v, bus_dmamap_t map,
1068 void *addr, bus_size_t size,
1069 struct proc *p, int flags);
1070 int elroy_dmamap_load_mbuf(void *v, bus_dmamap_t map,
1071 struct mbuf *m, int flags);
1072 int elroy_dmamap_load_uio(void *v, bus_dmamap_t map,
1073 struct uio *uio, int flags);
1074 int elroy_dmamap_load_raw(void *v, bus_dmamap_t map,
1075 bus_dma_segment_t *segs,
1076 int nsegs, bus_size_t size, int flags);
1077 void elroy_dmamap_unload(void *v, bus_dmamap_t map);
1078 void elroy_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t off,
1079 bus_size_t len, int ops);
1080 int elroy_dmamem_alloc(void *v, bus_size_t size,
1081 bus_size_t alignment, bus_size_t boundary,
1082 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
1083 void elroy_dmamem_free(void *v, bus_dma_segment_t *segs,
1084 int nsegs);
1085 int elroy_dmamem_map(void *v, bus_dma_segment_t *segs, int nsegs,
1086 size_t size, caddr_t *kvap, int flags);
1087 void elroy_dmamem_unmap(void *v, caddr_t kva, size_t size);
1088 paddr_t elroy_dmamem_mmap(void *v, bus_dma_segment_t *segs,
1089 int nsegs, off_t off, int prot, int flags);
1090
1091 int
elroy_dmamap_create(void * v,bus_size_t size,int nsegments,bus_size_t maxsegsz,bus_size_t boundary,int flags,bus_dmamap_t * dmamp)1092 elroy_dmamap_create(void *v, bus_size_t size, int nsegments,
1093 bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
1094 {
1095 struct elroy_softc *sc = v;
1096
1097 /* TODO check the addresses, boundary, enable dma */
1098
1099 return (bus_dmamap_create(sc->sc_dmat, size, nsegments,
1100 maxsegsz, boundary, flags, dmamp));
1101 }
1102
1103 void
elroy_dmamap_destroy(void * v,bus_dmamap_t map)1104 elroy_dmamap_destroy(void *v, bus_dmamap_t map)
1105 {
1106 struct elroy_softc *sc = v;
1107
1108 bus_dmamap_destroy(sc->sc_dmat, map);
1109 }
1110
1111 int
elroy_dmamap_load(void * v,bus_dmamap_t map,void * addr,bus_size_t size,struct proc * p,int flags)1112 elroy_dmamap_load(void *v, bus_dmamap_t map, void *addr, bus_size_t size,
1113 struct proc *p, int flags)
1114 {
1115 struct elroy_softc *sc = v;
1116
1117 return (bus_dmamap_load(sc->sc_dmat, map, addr, size, p, flags));
1118 }
1119
1120 int
elroy_dmamap_load_mbuf(void * v,bus_dmamap_t map,struct mbuf * m,int flags)1121 elroy_dmamap_load_mbuf(void *v, bus_dmamap_t map, struct mbuf *m, int flags)
1122 {
1123 struct elroy_softc *sc = v;
1124
1125 return (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, flags));
1126 }
1127
1128 int
elroy_dmamap_load_uio(void * v,bus_dmamap_t map,struct uio * uio,int flags)1129 elroy_dmamap_load_uio(void *v, bus_dmamap_t map, struct uio *uio, int flags)
1130 {
1131 struct elroy_softc *sc = v;
1132
1133 return (bus_dmamap_load_uio(sc->sc_dmat, map, uio, flags));
1134 }
1135
1136 int
elroy_dmamap_load_raw(void * v,bus_dmamap_t map,bus_dma_segment_t * segs,int nsegs,bus_size_t size,int flags)1137 elroy_dmamap_load_raw(void *v, bus_dmamap_t map, bus_dma_segment_t *segs,
1138 int nsegs, bus_size_t size, int flags)
1139 {
1140 struct elroy_softc *sc = v;
1141
1142 return (bus_dmamap_load_raw(sc->sc_dmat, map, segs, nsegs, size, flags));
1143 }
1144
1145 void
elroy_dmamap_unload(void * v,bus_dmamap_t map)1146 elroy_dmamap_unload(void *v, bus_dmamap_t map)
1147 {
1148 struct elroy_softc *sc = v;
1149
1150 bus_dmamap_unload(sc->sc_dmat, map);
1151 }
1152
1153 void
elroy_dmamap_sync(void * v,bus_dmamap_t map,bus_addr_t off,bus_size_t len,int ops)1154 elroy_dmamap_sync(void *v, bus_dmamap_t map, bus_addr_t off,
1155 bus_size_t len, int ops)
1156 {
1157 struct elroy_softc *sc = v;
1158
1159 bus_dmamap_sync(sc->sc_dmat, map, off, len, ops);
1160 }
1161
1162 int
elroy_dmamem_alloc(void * v,bus_size_t size,bus_size_t alignment,bus_size_t boundary,bus_dma_segment_t * segs,int nsegs,int * rsegs,int flags)1163 elroy_dmamem_alloc(void *v, bus_size_t size, bus_size_t alignment,
1164 bus_size_t boundary, bus_dma_segment_t *segs,
1165 int nsegs, int *rsegs, int flags)
1166 {
1167 struct elroy_softc *sc = v;
1168
1169 return (bus_dmamem_alloc(sc->sc_dmat, size, alignment, boundary,
1170 segs, nsegs, rsegs, flags));
1171 }
1172
1173 void
elroy_dmamem_free(void * v,bus_dma_segment_t * segs,int nsegs)1174 elroy_dmamem_free(void *v, bus_dma_segment_t *segs, int nsegs)
1175 {
1176 struct elroy_softc *sc = v;
1177
1178 bus_dmamem_free(sc->sc_dmat, segs, nsegs);
1179 }
1180
1181 int
elroy_dmamem_map(void * v,bus_dma_segment_t * segs,int nsegs,size_t size,caddr_t * kvap,int flags)1182 elroy_dmamem_map(void *v, bus_dma_segment_t *segs, int nsegs, size_t size,
1183 caddr_t *kvap, int flags)
1184 {
1185 struct elroy_softc *sc = v;
1186
1187 return (bus_dmamem_map(sc->sc_dmat, segs, nsegs, size, kvap, flags));
1188 }
1189
1190 void
elroy_dmamem_unmap(void * v,caddr_t kva,size_t size)1191 elroy_dmamem_unmap(void *v, caddr_t kva, size_t size)
1192 {
1193 struct elroy_softc *sc = v;
1194
1195 bus_dmamem_unmap(sc->sc_dmat, kva, size);
1196 }
1197
1198 paddr_t
elroy_dmamem_mmap(void * v,bus_dma_segment_t * segs,int nsegs,off_t off,int prot,int flags)1199 elroy_dmamem_mmap(void *v, bus_dma_segment_t *segs, int nsegs, off_t off,
1200 int prot, int flags)
1201 {
1202 struct elroy_softc *sc = v;
1203
1204 return (bus_dmamem_mmap(sc->sc_dmat, segs, nsegs, off, prot, flags));
1205 }
1206
1207 const struct hppa_bus_dma_tag elroy_dmat = {
1208 NULL,
1209 elroy_dmamap_create, elroy_dmamap_destroy,
1210 elroy_dmamap_load, elroy_dmamap_load_mbuf,
1211 elroy_dmamap_load_uio, elroy_dmamap_load_raw,
1212 elroy_dmamap_unload, elroy_dmamap_sync,
1213
1214 elroy_dmamem_alloc, elroy_dmamem_free, elroy_dmamem_map,
1215 elroy_dmamem_unmap, elroy_dmamem_mmap
1216 };
1217
1218 const struct hppa_pci_chipset_tag elroy_pc = {
1219 NULL,
1220 elroy_attach_hook, elroy_maxdevs, elroy_make_tag, elroy_decompose_tag,
1221 elroy_conf_size, elroy_conf_read, elroy_conf_write,
1222 apic_intr_map, apic_intr_string,
1223 apic_intr_establish, apic_intr_disestablish,
1224 #if NCARDBUS > 0
1225 elroy_alloc_parent
1226 #else
1227 NULL
1228 #endif
1229 };
1230
1231 int elroy_print(void *aux, const char *pnp);
1232
1233 int
elroy_print(void * aux,const char * pnp)1234 elroy_print(void *aux, const char *pnp)
1235 {
1236 struct pcibus_attach_args *pba = aux;
1237
1238 if (pnp)
1239 printf("%s at %s\n", pba->pba_busname, pnp);
1240 return (UNCONF);
1241 }
1242
1243 void
elroy_attach(struct device * parent,struct device * self,void * aux)1244 elroy_attach(struct device *parent, struct device *self, void *aux)
1245 {
1246 struct elroy_softc *sc = (struct elroy_softc *)self;
1247 struct confargs *ca = (struct confargs *)aux;
1248 struct pcibus_attach_args pba;
1249 volatile struct elroy_regs *r;
1250 const char *p = NULL, *q;
1251 int i;
1252
1253 sc->sc_hpa = ca->ca_hpa;
1254 sc->sc_bt = ca->ca_iot;
1255 sc->sc_dmat = ca->ca_dmatag;
1256 if (bus_space_map(sc->sc_bt, ca->ca_hpa, ca->ca_hpasz, 0, &sc->sc_bh)) {
1257 printf(": can't map space\n");
1258 return;
1259 }
1260
1261 sc->sc_regs = r = bus_space_vaddr(sc->sc_bt, sc->sc_bh);
1262 elroy_write32(&r->pci_cmdstat, htole32(PCI_COMMAND_IO_ENABLE |
1263 PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE));
1264
1265 elroy_write32(&r->control, elroy_read32(&r->control) &
1266 ~htole32(ELROY_CONTROL_RF));
1267 for (i = 5000; i-- &&
1268 elroy_read32(&r->status) & htole32(ELROY_STATUS_RC); DELAY(10));
1269 if (i < 0) {
1270 printf(": reset failed; status %b\n",
1271 htole32(r->status), ELROY_STATUS_BITS);
1272 return;
1273 }
1274
1275 q = "";
1276 sc->sc_ver = PCI_REVISION(letoh32(elroy_read32(&r->pci_class)));
1277 switch ((ca->ca_type.iodc_model << 4) |
1278 (ca->ca_type.iodc_revision >> 4)) {
1279 case 0x782:
1280 p = "Elroy";
1281 switch (sc->sc_ver) {
1282 default:
1283 q = "+";
1284 case 5: sc->sc_ver = 0x40; break;
1285 case 4: sc->sc_ver = 0x30; break;
1286 case 3: sc->sc_ver = 0x22; break;
1287 case 2: sc->sc_ver = 0x21; break;
1288 case 1: sc->sc_ver = 0x20; break;
1289 case 0: sc->sc_ver = 0x10; break;
1290 }
1291 break;
1292
1293 case 0x783:
1294 p = "Mercury";
1295 break;
1296
1297 case 0x784:
1298 p = "Quicksilver";
1299 break;
1300
1301 default:
1302 p = "Mojo";
1303 break;
1304 }
1305
1306 printf(": %s TR%d.%d%s", p, sc->sc_ver >> 4, sc->sc_ver & 0xf, q);
1307 apic_attach(sc);
1308 printf("\n");
1309
1310 elroy_write32(&r->imask, htole32(0xffffffff << 30));
1311 elroy_write32(&r->ibase, htole32(ELROY_BASE_RE));
1312
1313 /* TODO reserve elroy's pci space ? */
1314
1315 #if 0
1316 printf("lmm %llx/%llx gmm %llx/%llx wlm %llx/%llx wgm %llx/%llx io %llx/%llx eio %llx/%llx\n",
1317 letoh64(r->lmmio_base), letoh64(r->lmmio_mask),
1318 letoh64(r->gmmio_base), letoh64(r->gmmio_mask),
1319 letoh64(r->wlmmio_base), letoh64(r->wlmmio_mask),
1320 letoh64(r->wgmmio_base), letoh64(r->wgmmio_mask),
1321 letoh64(r->io_base), letoh64(r->io_mask),
1322 letoh64(r->eio_base), letoh64(r->eio_mask));
1323 #endif
1324
1325 /* XXX evil hack! */
1326 sc->sc_iobase = 0xfee00000;
1327
1328 sc->sc_iot = elroy_iomemt;
1329 sc->sc_iot.hbt_cookie = sc;
1330 sc->sc_iot.hbt_map = elroy_iomap;
1331 sc->sc_iot.hbt_alloc = elroy_ioalloc;
1332 sc->sc_memt = elroy_iomemt;
1333 sc->sc_memt.hbt_cookie = sc;
1334 sc->sc_memt.hbt_map = elroy_memmap;
1335 sc->sc_memt.hbt_alloc = elroy_memalloc;
1336 sc->sc_pc = elroy_pc;
1337 sc->sc_pc._cookie = sc;
1338 sc->sc_dmatag = elroy_dmat;
1339 sc->sc_dmatag._cookie = sc;
1340
1341 bzero(&pba, sizeof(pba));
1342 pba.pba_busname = "pci";
1343 pba.pba_iot = &sc->sc_iot;
1344 pba.pba_memt = &sc->sc_memt;
1345 pba.pba_dmat = &sc->sc_dmatag;
1346 pba.pba_pc = &sc->sc_pc;
1347 pba.pba_domain = pci_ndomains++;
1348 pba.pba_bus = 0; /* (letoh32(elroy_read32(&r->busnum)) & 0xff) >> 4; */
1349 config_found(self, &pba, elroy_print);
1350 }
1351