1*f83db12cSthorpej /* $NetBSD: bus_space.h,v 1.1 2024/01/02 07:41:00 thorpej Exp $ */
2*f83db12cSthorpej
3*f83db12cSthorpej /*-
4*f83db12cSthorpej * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
5*f83db12cSthorpej * All rights reserved.
6*f83db12cSthorpej *
7*f83db12cSthorpej * This code is derived from software contributed to The NetBSD Foundation
8*f83db12cSthorpej * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9*f83db12cSthorpej * NASA Ames Research Center.
10*f83db12cSthorpej *
11*f83db12cSthorpej * Redistribution and use in source and binary forms, with or without
12*f83db12cSthorpej * modification, are permitted provided that the following conditions
13*f83db12cSthorpej * are met:
14*f83db12cSthorpej * 1. Redistributions of source code must retain the above copyright
15*f83db12cSthorpej * notice, this list of conditions and the following disclaimer.
16*f83db12cSthorpej * 2. Redistributions in binary form must reproduce the above copyright
17*f83db12cSthorpej * notice, this list of conditions and the following disclaimer in the
18*f83db12cSthorpej * documentation and/or other materials provided with the distribution.
19*f83db12cSthorpej *
20*f83db12cSthorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21*f83db12cSthorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22*f83db12cSthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23*f83db12cSthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24*f83db12cSthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25*f83db12cSthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26*f83db12cSthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27*f83db12cSthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28*f83db12cSthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29*f83db12cSthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30*f83db12cSthorpej * POSSIBILITY OF SUCH DAMAGE.
31*f83db12cSthorpej */
32*f83db12cSthorpej
33*f83db12cSthorpej /*
34*f83db12cSthorpej * Copyright (C) 1997 Scott Reynolds. All rights reserved.
35*f83db12cSthorpej *
36*f83db12cSthorpej * Redistribution and use in source and binary forms, with or without
37*f83db12cSthorpej * modification, are permitted provided that the following conditions
38*f83db12cSthorpej * are met:
39*f83db12cSthorpej * 1. Redistributions of source code must retain the above copyright
40*f83db12cSthorpej * notice, this list of conditions and the following disclaimer.
41*f83db12cSthorpej * 2. Redistributions in binary form must reproduce the above copyright
42*f83db12cSthorpej * notice, this list of conditions and the following disclaimer in the
43*f83db12cSthorpej * documentation and/or other materials provided with the distribution.
44*f83db12cSthorpej * 3. The name of the author may not be used to endorse or promote products
45*f83db12cSthorpej * derived from this software without specific prior written permission
46*f83db12cSthorpej *
47*f83db12cSthorpej * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
48*f83db12cSthorpej * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49*f83db12cSthorpej * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
50*f83db12cSthorpej * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
51*f83db12cSthorpej * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
52*f83db12cSthorpej * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
53*f83db12cSthorpej * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
54*f83db12cSthorpej * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55*f83db12cSthorpej * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
56*f83db12cSthorpej * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57*f83db12cSthorpej */
58*f83db12cSthorpej
59*f83db12cSthorpej #ifndef _VIRT68K_BUS_SPACE_H_
60*f83db12cSthorpej #define _VIRT68K_BUS_SPACE_H_
61*f83db12cSthorpej
62*f83db12cSthorpej /*
63*f83db12cSthorpej * Addresses (in bus space).
64*f83db12cSthorpej */
65*f83db12cSthorpej typedef u_long bus_addr_t;
66*f83db12cSthorpej typedef u_long bus_size_t;
67*f83db12cSthorpej
68*f83db12cSthorpej #define PRIxBUSADDR "lx"
69*f83db12cSthorpej #define PRIxBUSSIZE "lx"
70*f83db12cSthorpej #define PRIuBUSSIZE "lu"
71*f83db12cSthorpej
72*f83db12cSthorpej /*
73*f83db12cSthorpej * Access methods for bus resources and address space.
74*f83db12cSthorpej */
75*f83db12cSthorpej struct virt68k_bus_space_tag;
76*f83db12cSthorpej typedef struct virt68k_bus_space_tag *bus_space_tag_t;
77*f83db12cSthorpej typedef u_long bus_space_handle_t;
78*f83db12cSthorpej
79*f83db12cSthorpej #define PRIxBSH "lx"
80*f83db12cSthorpej
81*f83db12cSthorpej struct virt68k_bus_space_tag {
82*f83db12cSthorpej void *bs_cookie;
83*f83db12cSthorpej int (*bs_map)(void *, bus_addr_t, bus_size_t,
84*f83db12cSthorpej int, bus_space_handle_t *);
85*f83db12cSthorpej void (*bs_unmap)(void *, bus_space_handle_t, bus_size_t);
86*f83db12cSthorpej int (*bs_peek_1)(void *, bus_space_handle_t,
87*f83db12cSthorpej bus_size_t, uint8_t *);
88*f83db12cSthorpej int (*bs_peek_2)(void *, bus_space_handle_t,
89*f83db12cSthorpej bus_size_t, uint16_t *);
90*f83db12cSthorpej int (*bs_peek_4)(void *, bus_space_handle_t,
91*f83db12cSthorpej bus_size_t, uint32_t *);
92*f83db12cSthorpej #if 0
93*f83db12cSthorpej int (*bs_peek_8)(void *, bus_space_handle_t,
94*f83db12cSthorpej bus_size_t, uint64_t *);
95*f83db12cSthorpej #endif
96*f83db12cSthorpej int (*bs_poke_1)(void *, bus_space_handle_t,
97*f83db12cSthorpej bus_size_t, uint8_t);
98*f83db12cSthorpej int (*bs_poke_2)(void *, bus_space_handle_t,
99*f83db12cSthorpej bus_size_t, uint16_t);
100*f83db12cSthorpej int (*bs_poke_4)(void *, bus_space_handle_t,
101*f83db12cSthorpej bus_size_t, uint32_t);
102*f83db12cSthorpej #if 0
103*f83db12cSthorpej int (*bs_poke_8)(void *, bus_space_handle_t,
104*f83db12cSthorpej bus_size_t, uint64_t);
105*f83db12cSthorpej #endif
106*f83db12cSthorpej };
107*f83db12cSthorpej
108*f83db12cSthorpej /*
109*f83db12cSthorpej * int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
110*f83db12cSthorpej * bus_size_t size, int flags,
111*f83db12cSthorpej * bus_space_handle_t *bshp);
112*f83db12cSthorpej *
113*f83db12cSthorpej * Map a region of bus space.
114*f83db12cSthorpej */
115*f83db12cSthorpej #define bus_space_map(tag, offset, size, flags, handlep) \
116*f83db12cSthorpej (*((tag)->bs_map))((tag)->bs_cookie, (offset), (size), (flags), (handlep))
117*f83db12cSthorpej
118*f83db12cSthorpej /*
119*f83db12cSthorpej * Possible values for the 'flags' parameter of bus_space_map()
120*f83db12cSthorpej */
121*f83db12cSthorpej #define BUS_SPACE_MAP_CACHEABLE 0x01
122*f83db12cSthorpej #define BUS_SPACE_MAP_LINEAR 0x02
123*f83db12cSthorpej #define BUS_SPACE_MAP_PREFETCHABLE 0x04
124*f83db12cSthorpej
125*f83db12cSthorpej /*
126*f83db12cSthorpej * void bus_space_unmap(bus_space_tag_t t,
127*f83db12cSthorpej * bus_space_handle_t bsh, bus_size_t size);
128*f83db12cSthorpej *
129*f83db12cSthorpej * Unmap a region of bus space.
130*f83db12cSthorpej */
131*f83db12cSthorpej #define bus_space_unmap(tag, handle, size) \
132*f83db12cSthorpej (*((tag)->bs_unmap))((tag)->bs_cookie, (handle), (size))
133*f83db12cSthorpej
134*f83db12cSthorpej /*
135*f83db12cSthorpej * int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h
136*f83db12cSthorpej * bus_addr_t offset, bus_size_t size, bus_space_handle_t *newh);
137*f83db12cSthorpej *
138*f83db12cSthorpej * Allocate a sub-region of an existing map
139*f83db12cSthorpej */
140*f83db12cSthorpej #define bus_space_subregion(t, h, o, s, hp) \
141*f83db12cSthorpej ((*(hp)=(h)+(o)), 0)
142*f83db12cSthorpej
143*f83db12cSthorpej /*
144*f83db12cSthorpej * Allocation and deallocation operations.
145*f83db12cSthorpej */
146*f83db12cSthorpej #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) \
147*f83db12cSthorpej (-1)
148*f83db12cSthorpej
149*f83db12cSthorpej #define bus_space_free(t, h, s)
150*f83db12cSthorpej
151*f83db12cSthorpej /*
152*f83db12cSthorpej * int bus_space_peek_N(bus_space_tag_t tag,
153*f83db12cSthorpej * bus_space_handle_t bsh, bus_size_t offset, uintN_t *valuep);
154*f83db12cSthorpej *
155*f83db12cSthorpej * Cautiously read 1, 2, 4 or 8 byte quantity from bus space described
156*f83db12cSthorpej * by tag/handle/offset.
157*f83db12cSthorpej * If no hardware responds to the read access, the function returns a
158*f83db12cSthorpej * non-zero value. Otherwise the value read is placed in `valuep'.
159*f83db12cSthorpej */
160*f83db12cSthorpej #define bus_space_peek_1(t, h, o, vp) \
161*f83db12cSthorpej (*((t)->bs_peek_1))((t)->bs_cookie, (h), (o), (vp))
162*f83db12cSthorpej
163*f83db12cSthorpej #define bus_space_peek_2(t, h, o, vp) \
164*f83db12cSthorpej (*((t)->bs_peek_2))((t)->bs_cookie, (h), (o), (vp))
165*f83db12cSthorpej
166*f83db12cSthorpej #define bus_space_peek_4(t, h, o, vp) \
167*f83db12cSthorpej (*((t)->bs_peek_4))((t)->bs_cookie, (h), (o), (vp))
168*f83db12cSthorpej
169*f83db12cSthorpej /*
170*f83db12cSthorpej * int bus_space_poke_N(bus_space_tag_t tag,
171*f83db12cSthorpej * bus_space_handle_t bsh, bus_size_t offset, uintN_t value);
172*f83db12cSthorpej *
173*f83db12cSthorpej * Cautiously write 1, 2, 4 or 8 byte quantity to bus space described
174*f83db12cSthorpej * by tag/handle/offset.
175*f83db12cSthorpej * If no hardware responds to the write access, the function returns a
176*f83db12cSthorpej * non-zero value.
177*f83db12cSthorpej */
178*f83db12cSthorpej #define bus_space_poke_1(t, h, o, v) \
179*f83db12cSthorpej (*((t)->bs_poke_1))((t)->bs_cookie, (h), (o), (v))
180*f83db12cSthorpej
181*f83db12cSthorpej #define bus_space_poke_2(t, h, o, v) \
182*f83db12cSthorpej (*((t)->bs_poke_2))((t)->bs_cookie, (h), (o), (v))
183*f83db12cSthorpej
184*f83db12cSthorpej #define bus_space_poke_4(t, h, o, v) \
185*f83db12cSthorpej (*((t)->bs_poke_4))((t)->bs_cookie, (h), (o), (v))
186*f83db12cSthorpej
187*f83db12cSthorpej /*
188*f83db12cSthorpej * uintN_t bus_space_read_N(bus_space_tag_t tag,
189*f83db12cSthorpej * bus_space_handle_t bsh, bus_size_t offset);
190*f83db12cSthorpej *
191*f83db12cSthorpej * Read a 1, 2, 4, or 8 byte quantity from bus space
192*f83db12cSthorpej * described by tag/handle/offset.
193*f83db12cSthorpej */
194*f83db12cSthorpej static inline uint8_t
bus_space_read_1(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)195*f83db12cSthorpej bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
196*f83db12cSthorpej {
197*f83db12cSthorpej (void) t;
198*f83db12cSthorpej return *(volatile uint8_t *)((intptr_t)(h + o));
199*f83db12cSthorpej }
200*f83db12cSthorpej
201*f83db12cSthorpej static inline uint16_t
bus_space_read_2(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)202*f83db12cSthorpej bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
203*f83db12cSthorpej {
204*f83db12cSthorpej (void) t;
205*f83db12cSthorpej return *(volatile uint16_t *)((intptr_t)(h + o));
206*f83db12cSthorpej }
207*f83db12cSthorpej
208*f83db12cSthorpej static inline uint32_t
bus_space_read_4(bus_space_tag_t t,bus_space_handle_t h,bus_size_t o)209*f83db12cSthorpej bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
210*f83db12cSthorpej {
211*f83db12cSthorpej (void) t;
212*f83db12cSthorpej return *(volatile uint32_t *)((intptr_t)(h + o));
213*f83db12cSthorpej }
214*f83db12cSthorpej
215*f83db12cSthorpej /*
216*f83db12cSthorpej * void bus_space_read_multi_N(bus_space_tag_t tag,
217*f83db12cSthorpej * bus_space_handle_t bsh, bus_size_t offset,
218*f83db12cSthorpej * uintN_t *addr, size_t count);
219*f83db12cSthorpej *
220*f83db12cSthorpej * Read `count' 1, 2, 4, or 8 byte quantities from bus space
221*f83db12cSthorpej * described by tag/handle/offset and copy into buffer provided.
222*f83db12cSthorpej */
223*f83db12cSthorpej
224*f83db12cSthorpej #define bus_space_read_multi_1(t, h, o, a, c) do { \
225*f83db12cSthorpej (void) t; \
226*f83db12cSthorpej __asm volatile (" \
227*f83db12cSthorpej movl %0,%%a0 ; \
228*f83db12cSthorpej movl %1,%%a1 ; \
229*f83db12cSthorpej movl %2,%%d0 ; \
230*f83db12cSthorpej 1: movb %%a0@,%%a1@+ ; \
231*f83db12cSthorpej subql #1,%%d0 ; \
232*f83db12cSthorpej jne 1b" : \
233*f83db12cSthorpej : \
234*f83db12cSthorpej "r" ((h) + (o)), "g" (a), "g" (c) : \
235*f83db12cSthorpej "a0","a1","d0","memory"); \
236*f83db12cSthorpej } while (0);
237*f83db12cSthorpej
238*f83db12cSthorpej #define bus_space_read_multi_2(t, h, o, a, c) do { \
239*f83db12cSthorpej (void) t; \
240*f83db12cSthorpej __asm volatile (" \
241*f83db12cSthorpej movl %0,%%a0 ; \
242*f83db12cSthorpej movl %1,%%a1 ; \
243*f83db12cSthorpej movl %2,%%d0 ; \
244*f83db12cSthorpej 1: movw %%a0@,%%a1@+ ; \
245*f83db12cSthorpej subql #1,%%d0 ; \
246*f83db12cSthorpej jne 1b" : \
247*f83db12cSthorpej : \
248*f83db12cSthorpej "r" ((h) + (o)), "g" (a), "g" (c) : \
249*f83db12cSthorpej "a0","a1","d0","memory"); \
250*f83db12cSthorpej } while (0);
251*f83db12cSthorpej
252*f83db12cSthorpej #define bus_space_read_multi_4(t, h, o, a, c) do { \
253*f83db12cSthorpej (void) t; \
254*f83db12cSthorpej __asm volatile (" \
255*f83db12cSthorpej movl %0,%%a0 ; \
256*f83db12cSthorpej movl %1,%%a1 ; \
257*f83db12cSthorpej movl %2,%%d0 ; \
258*f83db12cSthorpej 1: movl %%a0@,%%a1@+ ; \
259*f83db12cSthorpej subql #1,%%d0 ; \
260*f83db12cSthorpej jne 1b" : \
261*f83db12cSthorpej : \
262*f83db12cSthorpej "r" ((h) + (o)), "g" (a), "g" (c) : \
263*f83db12cSthorpej "a0","a1","d0","memory"); \
264*f83db12cSthorpej } while (0);
265*f83db12cSthorpej
266*f83db12cSthorpej /*
267*f83db12cSthorpej * void bus_space_read_region_N(bus_space_tag_t tag,
268*f83db12cSthorpej * bus_space_handle_t bsh, bus_size_t offset,
269*f83db12cSthorpej * uintN_t *addr, size_t count);
270*f83db12cSthorpej *
271*f83db12cSthorpej * Read `count' 1, 2, 4, or 8 byte quantities from bus space
272*f83db12cSthorpej * described by tag/handle and starting at `offset' and copy into
273*f83db12cSthorpej * buffer provided.
274*f83db12cSthorpej */
275*f83db12cSthorpej
276*f83db12cSthorpej #define bus_space_read_region_1(t, h, o, a, c) do { \
277*f83db12cSthorpej (void) t; \
278*f83db12cSthorpej __asm volatile (" \
279*f83db12cSthorpej movl %0,%%a0 ; \
280*f83db12cSthorpej movl %1,%%a1 ; \
281*f83db12cSthorpej movl %2,%%d0 ; \
282*f83db12cSthorpej 1: movb %%a0@+,%%a1@+ ; \
283*f83db12cSthorpej subql #1,%%d0 ; \
284*f83db12cSthorpej jne 1b" : \
285*f83db12cSthorpej : \
286*f83db12cSthorpej "r" ((h) + (o)), "g" (a), "g" (c) : \
287*f83db12cSthorpej "a0","a1","d0","memory"); \
288*f83db12cSthorpej } while (0);
289*f83db12cSthorpej
290*f83db12cSthorpej #define bus_space_read_region_2(t, h, o, a, c) do { \
291*f83db12cSthorpej (void) t; \
292*f83db12cSthorpej __asm volatile (" \
293*f83db12cSthorpej movl %0,%%a0 ; \
294*f83db12cSthorpej movl %1,%%a1 ; \
295*f83db12cSthorpej movl %2,%%d0 ; \
296*f83db12cSthorpej 1: movw %%a0@+,%%a1@+ ; \
297*f83db12cSthorpej subql #1,%%d0 ; \
298*f83db12cSthorpej jne 1b" : \
299*f83db12cSthorpej : \
300*f83db12cSthorpej "r" ((h) + (o)), "g" (a), "g" (c) : \
301*f83db12cSthorpej "a0","a1","d0","memory"); \
302*f83db12cSthorpej } while (0);
303*f83db12cSthorpej
304*f83db12cSthorpej #define bus_space_read_region_4(t, h, o, a, c) do { \
305*f83db12cSthorpej (void) t; \
306*f83db12cSthorpej __asm volatile (" \
307*f83db12cSthorpej movl %0,%%a0 ; \
308*f83db12cSthorpej movl %1,%%a1 ; \
309*f83db12cSthorpej movl %2,%%d0 ; \
310*f83db12cSthorpej 1: movl %%a0@+,%%a1@+ ; \
311*f83db12cSthorpej subql #1,%%d0 ; \
312*f83db12cSthorpej jne 1b" : \
313*f83db12cSthorpej : \
314*f83db12cSthorpej "r" ((h) + (o)), "g" (a), "g" (c) : \
315*f83db12cSthorpej "a0","a1","d0","memory"); \
316*f83db12cSthorpej } while (0);
317*f83db12cSthorpej
318*f83db12cSthorpej /*
319*f83db12cSthorpej * void bus_space_write_N(bus_space_tag_t tag,
320*f83db12cSthorpej * bus_space_handle_t bsh, bus_size_t offset,
321*f83db12cSthorpej * uintN_t value);
322*f83db12cSthorpej *
323*f83db12cSthorpej * Write the 1, 2, 4, or 8 byte value `value' to bus space
324*f83db12cSthorpej * described by tag/handle/offset.
325*f83db12cSthorpej */
326*f83db12cSthorpej #define bus_space_write_1(t,h,o,v) \
327*f83db12cSthorpej do { \
328*f83db12cSthorpej (void) t; \
329*f83db12cSthorpej *((volatile uint8_t *)(intptr_t)((h) + (o))) = (v); \
330*f83db12cSthorpej } while (/*CONSTCOND*/0)
331*f83db12cSthorpej #define bus_space_write_2(t,h,o,v) \
332*f83db12cSthorpej do { \
333*f83db12cSthorpej (void) t; \
334*f83db12cSthorpej *((volatile uint16_t *)(intptr_t)((h) + (o))) = (v); \
335*f83db12cSthorpej } while (/*CONSTCOND*/0)
336*f83db12cSthorpej #define bus_space_write_4(t,h,o,v) \
337*f83db12cSthorpej do { \
338*f83db12cSthorpej (void) t; \
339*f83db12cSthorpej *((volatile uint32_t *)(intptr_t)((h) + (o))) = (v); \
340*f83db12cSthorpej } while (/*CONSTCOND*/0)
341*f83db12cSthorpej
342*f83db12cSthorpej /*
343*f83db12cSthorpej * void bus_space_write_multi_N(bus_space_tag_t tag,
344*f83db12cSthorpej * bus_space_handle_t bsh, bus_size_t offset,
345*f83db12cSthorpej * const uintN_t *addr, size_t count);
346*f83db12cSthorpej *
347*f83db12cSthorpej * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
348*f83db12cSthorpej * provided to bus space described by tag/handle/offset.
349*f83db12cSthorpej */
350*f83db12cSthorpej
351*f83db12cSthorpej #define bus_space_write_multi_1(t, h, o, a, c) do { \
352*f83db12cSthorpej (void) t; \
353*f83db12cSthorpej __asm volatile (" \
354*f83db12cSthorpej movl %0,%%a0 ; \
355*f83db12cSthorpej movl %1,%%a1 ; \
356*f83db12cSthorpej movl %2,%%d0 ; \
357*f83db12cSthorpej 1: movb %%a1@+,%%a0@ ; \
358*f83db12cSthorpej subql #1,%%d0 ; \
359*f83db12cSthorpej jne 1b" : \
360*f83db12cSthorpej : \
361*f83db12cSthorpej "r" ((h) + (o)), "g" (a), "g" (c) : \
362*f83db12cSthorpej "a0","a1","d0"); \
363*f83db12cSthorpej } while (0);
364*f83db12cSthorpej
365*f83db12cSthorpej #define bus_space_write_multi_2(t, h, o, a, c) do { \
366*f83db12cSthorpej (void) t; \
367*f83db12cSthorpej __asm volatile (" \
368*f83db12cSthorpej movl %0,%%a0 ; \
369*f83db12cSthorpej movl %1,%%a1 ; \
370*f83db12cSthorpej movl %2,%%d0 ; \
371*f83db12cSthorpej 1: movw %%a1@+,%%a0@ ; \
372*f83db12cSthorpej subql #1,%%d0 ; \
373*f83db12cSthorpej jne 1b" : \
374*f83db12cSthorpej : \
375*f83db12cSthorpej "r" ((h) + (o)), "g" (a), "g" (c) : \
376*f83db12cSthorpej "a0","a1","d0"); \
377*f83db12cSthorpej } while (0);
378*f83db12cSthorpej
379*f83db12cSthorpej #define bus_space_write_multi_4(t, h, o, a, c) do { \
380*f83db12cSthorpej (void) t; \
381*f83db12cSthorpej __asm volatile (" \
382*f83db12cSthorpej movl %0,%%a0 ; \
383*f83db12cSthorpej movl %1,%%a1 ; \
384*f83db12cSthorpej movl %2,%%d0 ; \
385*f83db12cSthorpej 1: movl a1@+,%%a0@ ; \
386*f83db12cSthorpej subql #1,%%d0 ; \
387*f83db12cSthorpej jne 1b" : \
388*f83db12cSthorpej : \
389*f83db12cSthorpej "r" ((h) + (o)), "g" (a), "g" (c) : \
390*f83db12cSthorpej "a0","a1","d0"); \
391*f83db12cSthorpej } while (0);
392*f83db12cSthorpej
393*f83db12cSthorpej /*
394*f83db12cSthorpej * void bus_space_write_region_N(bus_space_tag_t tag,
395*f83db12cSthorpej * bus_space_handle_t bsh, bus_size_t offset,
396*f83db12cSthorpej * const uintN_t *addr, size_t count);
397*f83db12cSthorpej *
398*f83db12cSthorpej * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
399*f83db12cSthorpej * to bus space described by tag/handle starting at `offset'.
400*f83db12cSthorpej */
401*f83db12cSthorpej
402*f83db12cSthorpej #define bus_space_write_region_1(t, h, o, a, c) do { \
403*f83db12cSthorpej (void) t; \
404*f83db12cSthorpej __asm volatile (" \
405*f83db12cSthorpej movl %0,%%a0 ; \
406*f83db12cSthorpej movl %1,%%a1 ; \
407*f83db12cSthorpej movl %2,%%d0 ; \
408*f83db12cSthorpej 1: movb %%a1@+,%%a0@+ ; \
409*f83db12cSthorpej subql #1,%%d0 ; \
410*f83db12cSthorpej jne 1b" : \
411*f83db12cSthorpej : \
412*f83db12cSthorpej "r" ((h) + (o)), "g" (a), "g" (c) : \
413*f83db12cSthorpej "a0","a1","d0"); \
414*f83db12cSthorpej } while (0);
415*f83db12cSthorpej
416*f83db12cSthorpej #define bus_space_write_region_2(t, h, o, a, c) do { \
417*f83db12cSthorpej (void) t; \
418*f83db12cSthorpej __asm volatile (" \
419*f83db12cSthorpej movl %0,%%a0 ; \
420*f83db12cSthorpej movl %1,%%a1 ; \
421*f83db12cSthorpej movl %2,%%d0 ; \
422*f83db12cSthorpej 1: movw %%a1@+,%%a0@+ ; \
423*f83db12cSthorpej subql #1,%%d0 ; \
424*f83db12cSthorpej jne 1b" : \
425*f83db12cSthorpej : \
426*f83db12cSthorpej "r" ((h) + (o)), "g" (a), "g" (c) : \
427*f83db12cSthorpej "a0","a1","d0"); \
428*f83db12cSthorpej } while (0);
429*f83db12cSthorpej
430*f83db12cSthorpej #define bus_space_write_region_4(t, h, o, a, c) do { \
431*f83db12cSthorpej (void) t; \
432*f83db12cSthorpej __asm volatile (" \
433*f83db12cSthorpej movl %0,%%a0 ; \
434*f83db12cSthorpej movl %1,%%a1 ; \
435*f83db12cSthorpej movl %2,%%d0 ; \
436*f83db12cSthorpej 1: movl %%a1@+,%%a0@+ ; \
437*f83db12cSthorpej subql #1,%%d0 ; \
438*f83db12cSthorpej jne 1b" : \
439*f83db12cSthorpej : \
440*f83db12cSthorpej "r" ((h) + (o)), "g" (a), "g" (c) : \
441*f83db12cSthorpej "a0","a1","d0"); \
442*f83db12cSthorpej } while (0);
443*f83db12cSthorpej
444*f83db12cSthorpej /*
445*f83db12cSthorpej * void bus_space_set_multi_N(bus_space_tag_t tag,
446*f83db12cSthorpej * bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
447*f83db12cSthorpej * size_t count);
448*f83db12cSthorpej *
449*f83db12cSthorpej * Write the 1, 2, 4, or 8 byte value `val' to bus space described
450*f83db12cSthorpej * by tag/handle/offset `count' times.
451*f83db12cSthorpej */
452*f83db12cSthorpej
453*f83db12cSthorpej #define bus_space_set_multi_1(t, h, o, val, c) do { \
454*f83db12cSthorpej (void) t; \
455*f83db12cSthorpej __asm volatile (" \
456*f83db12cSthorpej movl %0,%%a0 ; \
457*f83db12cSthorpej movl %1,%%d1 ; \
458*f83db12cSthorpej movl %2,%%d0 ; \
459*f83db12cSthorpej 1: movb %%d1,%%a0@ ; \
460*f83db12cSthorpej subql #1,%%d0 ; \
461*f83db12cSthorpej jne 1b" : \
462*f83db12cSthorpej : \
463*f83db12cSthorpej "r" ((h) + (o)), "g" (val), "g" (c) : \
464*f83db12cSthorpej "a0","d0","d1"); \
465*f83db12cSthorpej } while (0);
466*f83db12cSthorpej
467*f83db12cSthorpej #define bus_space_set_multi_2(t, h, o, val, c) do { \
468*f83db12cSthorpej (void) t; \
469*f83db12cSthorpej __asm volatile (" \
470*f83db12cSthorpej movl %0,%%a0 ; \
471*f83db12cSthorpej movl %1,%%d1 ; \
472*f83db12cSthorpej movl %2,%%d0 ; \
473*f83db12cSthorpej 1: movw %%d1,%%a0@ ; \
474*f83db12cSthorpej subql #1,%%d0 ; \
475*f83db12cSthorpej jne 1b" : \
476*f83db12cSthorpej : \
477*f83db12cSthorpej "r" ((h) + (o)), "g" (val), "g" (c) : \
478*f83db12cSthorpej "a0","d0","d1"); \
479*f83db12cSthorpej } while (0);
480*f83db12cSthorpej
481*f83db12cSthorpej #define bus_space_set_multi_4(t, h, o, val, c) do { \
482*f83db12cSthorpej (void) t; \
483*f83db12cSthorpej __asm volatile (" \
484*f83db12cSthorpej movl %0,%%a0 ; \
485*f83db12cSthorpej movl %1,%%d1 ; \
486*f83db12cSthorpej movl %2,%%d0 ; \
487*f83db12cSthorpej 1: movl %%d1,%%a0@ ; \
488*f83db12cSthorpej subql #1,%%d0 ; \
489*f83db12cSthorpej jne 1b" : \
490*f83db12cSthorpej : \
491*f83db12cSthorpej "r" ((h) + (o)), "g" (val), "g" (c) : \
492*f83db12cSthorpej "a0","d0","d1"); \
493*f83db12cSthorpej } while (0);
494*f83db12cSthorpej
495*f83db12cSthorpej /*
496*f83db12cSthorpej * void bus_space_set_region_N(bus_space_tag_t tag,
497*f83db12cSthorpej * bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
498*f83db12cSthorpej * size_t count);
499*f83db12cSthorpej *
500*f83db12cSthorpej * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
501*f83db12cSthorpej * by tag/handle starting at `offset'.
502*f83db12cSthorpej */
503*f83db12cSthorpej
504*f83db12cSthorpej #define bus_space_set_region_1(t, h, o, val, c) do { \
505*f83db12cSthorpej (void) t; \
506*f83db12cSthorpej __asm volatile (" \
507*f83db12cSthorpej movl %0,%%a0 ; \
508*f83db12cSthorpej movl %1,%%d1 ; \
509*f83db12cSthorpej movl %2,%%d0 ; \
510*f83db12cSthorpej 1: movb %%d1,%%a0@+ ; \
511*f83db12cSthorpej subql #1,%%d0 ; \
512*f83db12cSthorpej jne 1b" : \
513*f83db12cSthorpej : \
514*f83db12cSthorpej "r" ((h) + (o)), "g" (val), "g" (c) : \
515*f83db12cSthorpej "a0","d0","d1"); \
516*f83db12cSthorpej } while (0);
517*f83db12cSthorpej
518*f83db12cSthorpej #define bus_space_set_region_2(t, h, o, val, c) do { \
519*f83db12cSthorpej (void) t; \
520*f83db12cSthorpej __asm volatile (" \
521*f83db12cSthorpej movl %0,%%a0 ; \
522*f83db12cSthorpej movl %1,%%d1 ; \
523*f83db12cSthorpej movl %2,%%d0 ; \
524*f83db12cSthorpej 1: movw %%d1,%%a0@+ ; \
525*f83db12cSthorpej subql #1,%%d0 ; \
526*f83db12cSthorpej jne 1b" : \
527*f83db12cSthorpej : \
528*f83db12cSthorpej "r" ((h) + (o)), "g" (val), "g" (c) : \
529*f83db12cSthorpej "a0","d0","d1"); \
530*f83db12cSthorpej } while (0);
531*f83db12cSthorpej
532*f83db12cSthorpej #define bus_space_set_region_4(t, h, o, val, c) do { \
533*f83db12cSthorpej (void) t; \
534*f83db12cSthorpej __asm volatile (" \
535*f83db12cSthorpej movl %0,%%a0 ; \
536*f83db12cSthorpej movl %1,%%d1 ; \
537*f83db12cSthorpej movl %2,%%d0 ; \
538*f83db12cSthorpej 1: movl d1,%%a0@+ ; \
539*f83db12cSthorpej subql #1,%%d0 ; \
540*f83db12cSthorpej jne 1b" : \
541*f83db12cSthorpej : \
542*f83db12cSthorpej "r" ((h) + (o)), "g" (val), "g" (c) : \
543*f83db12cSthorpej "a0","d0","d1"); \
544*f83db12cSthorpej } while (0);
545*f83db12cSthorpej
546*f83db12cSthorpej /*
547*f83db12cSthorpej * void bus_space_copy_N(bus_space_tag_t tag,
548*f83db12cSthorpej * bus_space_handle_t bsh1, bus_size_t off1,
549*f83db12cSthorpej * bus_space_handle_t bsh2, bus_size_t off2,
550*f83db12cSthorpej * size_t count);
551*f83db12cSthorpej *
552*f83db12cSthorpej * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
553*f83db12cSthorpej * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
554*f83db12cSthorpej */
555*f83db12cSthorpej
556*f83db12cSthorpej #define __VIRT68K_copy_region_N(BYTES) \
557*f83db12cSthorpej static __inline void __CONCAT(bus_space_copy_region_,BYTES) \
558*f83db12cSthorpej (bus_space_tag_t, \
559*f83db12cSthorpej bus_space_handle_t bsh1, bus_size_t off1, \
560*f83db12cSthorpej bus_space_handle_t bsh2, bus_size_t off2, \
561*f83db12cSthorpej bus_size_t count); \
562*f83db12cSthorpej \
563*f83db12cSthorpej static __inline void \
564*f83db12cSthorpej __CONCAT(bus_space_copy_region_,BYTES)( \
565*f83db12cSthorpej bus_space_tag_t t, \
566*f83db12cSthorpej bus_space_handle_t h1, \
567*f83db12cSthorpej bus_size_t o1, \
568*f83db12cSthorpej bus_space_handle_t h2, \
569*f83db12cSthorpej bus_size_t o2, \
570*f83db12cSthorpej bus_size_t c) \
571*f83db12cSthorpej { \
572*f83db12cSthorpej bus_size_t o; \
573*f83db12cSthorpej (void) t; \
574*f83db12cSthorpej \
575*f83db12cSthorpej if ((h1 + o1) >= (h2 + o2)) { \
576*f83db12cSthorpej /* src after dest: copy forward */ \
577*f83db12cSthorpej for (o = 0; c != 0; c--, o += BYTES) \
578*f83db12cSthorpej __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
579*f83db12cSthorpej __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
580*f83db12cSthorpej } else { \
581*f83db12cSthorpej /* dest after src: copy backwards */ \
582*f83db12cSthorpej for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \
583*f83db12cSthorpej __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
584*f83db12cSthorpej __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
585*f83db12cSthorpej } \
586*f83db12cSthorpej }
587*f83db12cSthorpej __VIRT68K_copy_region_N(1)
588*f83db12cSthorpej __VIRT68K_copy_region_N(2)
589*f83db12cSthorpej __VIRT68K_copy_region_N(4)
590*f83db12cSthorpej
591*f83db12cSthorpej #undef __VIRT68K_copy_region_N
592*f83db12cSthorpej
593*f83db12cSthorpej /*
594*f83db12cSthorpej * Bus read/write barrier methods.
595*f83db12cSthorpej *
596*f83db12cSthorpej * void bus_space_barrier(bus_space_tag_t tag,
597*f83db12cSthorpej * bus_space_handle_t bsh, bus_size_t offset,
598*f83db12cSthorpej * bus_size_t len, int flags);
599*f83db12cSthorpej *
600*f83db12cSthorpej * Note: the 680x0 does not currently require barriers, but we must
601*f83db12cSthorpej * provide the flags to MI code.
602*f83db12cSthorpej */
603*f83db12cSthorpej #define bus_space_barrier(t, h, o, l, f) \
604*f83db12cSthorpej ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
605*f83db12cSthorpej #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
606*f83db12cSthorpej #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
607*f83db12cSthorpej
608*f83db12cSthorpej #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
609*f83db12cSthorpej
610*f83db12cSthorpej
611*f83db12cSthorpej #ifdef _VIRT68K_BUS_SPACE_PRIVATE
612*f83db12cSthorpej extern int _bus_space_map(void *, bus_addr_t, bus_size_t,
613*f83db12cSthorpej int, bus_space_handle_t *);
614*f83db12cSthorpej extern void _bus_space_unmap(void *, bus_space_handle_t, bus_size_t);
615*f83db12cSthorpej extern int _bus_space_peek_1(void *, bus_space_handle_t,
616*f83db12cSthorpej bus_size_t, uint8_t *);
617*f83db12cSthorpej extern int _bus_space_peek_2(void *, bus_space_handle_t,
618*f83db12cSthorpej bus_size_t, uint16_t *);
619*f83db12cSthorpej extern int _bus_space_peek_4(void *, bus_space_handle_t,
620*f83db12cSthorpej bus_size_t, uint32_t *);
621*f83db12cSthorpej extern int _bus_space_poke_1(void *, bus_space_handle_t, bus_size_t, uint8_t);
622*f83db12cSthorpej extern int _bus_space_poke_2(void *, bus_space_handle_t, bus_size_t, uint16_t);
623*f83db12cSthorpej extern int _bus_space_poke_4(void *, bus_space_handle_t, bus_size_t, uint32_t);
624*f83db12cSthorpej #endif /* _VIRT68K_BUS_SPACE_PRIVATE */
625*f83db12cSthorpej
626*f83db12cSthorpej #endif /* _VIRT68K_BUS_SPACE_H_ */
627