xref: /openbsd-src/sys/arch/hppa/dev/elroy.c (revision 32ffafad193fd9d5bc1743017cf37d821be47b78)
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