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