1144513Simp/*-
2144604Simp * Copyright (c) KATO Takenori, 1999.
3144604Simp *
4144604Simp * All rights reserved.  Unpublished rights reserved under the copyright
5144604Simp * laws of Japan.
6144604Simp *
7144604Simp * Redistribution and use in source and binary forms, with or without
8144604Simp * modification, are permitted provided that the following conditions
9144604Simp * are met:
10144604Simp *
11144604Simp * 1. Redistributions of source code must retain the above copyright
12144604Simp *    notice, this list of conditions and the following disclaimer as
13144604Simp *    the first lines of this file unmodified.
14144604Simp * 2. Redistributions in binary form must reproduce the above copyright
15144604Simp *    notice, this list of conditions and the following disclaimer in the
16144604Simp *    documentation and/or other materials provided with the distribution.
17144604Simp * 3. The name of the author may not be used to endorse or promote products
18144604Simp *    derived from this software without specific prior written permission.
19144604Simp *
20144604Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21144604Simp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22144604Simp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23144604Simp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24144604Simp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25144604Simp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26144604Simp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27144604Simp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28144604Simp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29144604Simp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30144604Simp *
31144604Simp * $FreeBSD$
32144513Simp */
33144513Simp
34144604Simp/*	$NecBSD: busio.h,v 3.25.4.2.2.1 2000/06/12 03:53:08 honda Exp $	*/
35144604Simp/*	$NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $	*/
36144604Simp
37144604Simp/*-
38144604Simp * [NetBSD for NEC PC-98 series]
39144604Simp *  Copyright (c) 1997, 1998
40144604Simp *	NetBSD/pc98 porting staff. All rights reserved.
41144604Simp *
42144604Simp * [Ported for FreeBSD]
43144604Simp *  Copyright (c) 2001
44144604Simp *	TAKAHASHI Yoshihiro. All rights reserved.
45144604Simp *
46144604Simp *  Redistribution and use in source and binary forms, with or without
47144604Simp *  modification, are permitted provided that the following conditions
48144604Simp *  are met:
49144604Simp *  1. Redistributions of source code must retain the above copyright
50144604Simp *     notice, this list of conditions and the following disclaimer.
51144604Simp *  2. Redistributions in binary form must reproduce the above copyright
52144604Simp *     notice, this list of conditions and the following disclaimer in the
53144604Simp *     documentation and/or other materials provided with the distribution.
54144604Simp *  3. The name of the author may not be used to endorse or promote products
55144604Simp *     derived from this software without specific prior written permission.
56144604Simp *
57144604Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
58144604Simp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59144604Simp * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60144604Simp * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
61144604Simp * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62144604Simp * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
63144604Simp * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64144604Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
65144604Simp * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
66144604Simp * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
67144604Simp * POSSIBILITY OF SUCH DAMAGE.
68144604Simp */
69144604Simp
70144604Simp/*
71144604Simp * Copyright (c) 1997, 1998
72144604Simp *	Naofumi HONDA.  All rights reserved.
73144604Simp *
74144604Simp * This module support generic bus address relocation mechanism.
75144604Simp * To reduce a function call overhead, we employ pascal call methods.
76144604Simp */
77144604Simp
78144604Simp#ifndef _PC98_BUS_H_
79144604Simp#define _PC98_BUS_H_
80144604Simp
81291716Sken#ifdef _KERNEL
82144604Simp#include <sys/systm.h>
83291716Sken#endif /* _KERNEL */
84144604Simp
85145253Simp#include <machine/_bus.h>
86144604Simp#include <machine/cpufunc.h>
87144604Simp
88144604Simp#define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
89144604Simp#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
90144604Simp#define BUS_SPACE_MAXSIZE	0xFFFFFFFF
91144604Simp#define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
92144604Simp#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
93144604Simp#define BUS_SPACE_MAXADDR	0xFFFFFFFF
94144604Simp
95144604Simp#define BUS_SPACE_UNRESTRICTED	(~0)
96144604Simp
97291716Sken#ifdef _KERNEL
98291716Sken
99182836Snyan/*
100182836Snyan * address relocation table
101182836Snyan */
102145300Simp#define BUS_SPACE_IAT_MAXSIZE	33
103182836Snyantypedef bus_addr_t *bus_space_iat_t;
104145300Simp
105182836Snyan#define BUS_SPACE_IAT_SZ(IOTARRAY) (sizeof(IOTARRAY)/sizeof(bus_addr_t))
106182836Snyan
107144604Simp/*
108144604Simp * Access methods for bus resources and address space.
109144604Simp */
110144604Simpstruct resource;
111144604Simp
112144604Simp/*
113145300Simp * bus space tag
114144604Simp */
115145300Simp#define	_PASCAL_CALL	(void)
116145300Simp
117145300Simp#define	_BUS_SPACE_CALL_FUNCS_TAB(NAME,TYPE,BWN) \
118145300Simp	NAME##_space_read_##BWN, 				\
119145300Simp	NAME##_space_read_multi_##BWN, 				\
120145300Simp	NAME##_space_read_region_##BWN,				\
121145300Simp	NAME##_space_write_##BWN, 				\
122145300Simp	NAME##_space_write_multi_##BWN, 			\
123145300Simp	NAME##_space_write_region_##BWN,			\
124145300Simp	NAME##_space_set_multi_##BWN,				\
125145300Simp	NAME##_space_set_region_##BWN,				\
126145300Simp	NAME##_space_copy_region_##BWN
127145300Simp
128145300Simp#define	_BUS_SPACE_CALL_FUNCS_PROTO(NAME,TYPE,BWN) \
129145300Simp	TYPE NAME##_space_read_##BWN _PASCAL_CALL;		\
130145300Simp	void NAME##_space_read_multi_##BWN _PASCAL_CALL;	\
131145300Simp	void NAME##_space_read_region_##BWN _PASCAL_CALL;	\
132145300Simp	void NAME##_space_write_##BWN _PASCAL_CALL;		\
133145300Simp	void NAME##_space_write_multi_##BWN _PASCAL_CALL;	\
134145300Simp	void NAME##_space_write_region_##BWN _PASCAL_CALL;	\
135145300Simp	void NAME##_space_set_multi_##BWN _PASCAL_CALL;		\
136145300Simp	void NAME##_space_set_region_##BWN _PASCAL_CALL;	\
137145300Simp	void NAME##_space_copy_region_##BWN _PASCAL_CALL;
138145300Simp
139145300Simp#define	_BUS_SPACE_CALL_FUNCS(NAME,TYPE,BWN) \
140145300Simp	TYPE (* NAME##_read_##BWN) _PASCAL_CALL;		\
141145300Simp	void (* NAME##_read_multi_##BWN) _PASCAL_CALL;		\
142145300Simp	void (* NAME##_read_region_##BWN) _PASCAL_CALL;		\
143145300Simp	void (* NAME##_write_##BWN) _PASCAL_CALL;		\
144145300Simp	void (* NAME##_write_multi_##BWN) _PASCAL_CALL;		\
145145300Simp	void (* NAME##_write_region_##BWN) _PASCAL_CALL;	\
146145300Simp	void (* NAME##_set_multi_##BWN) _PASCAL_CALL;		\
147145300Simp	void (* NAME##_set_region_##BWN) _PASCAL_CALL;		\
148145300Simp	void (* NAME##_copy_region_##BWN) _PASCAL_CALL;
149145300Simp
150145300Simpstruct bus_space_access_methods {
151145300Simp	/* 8 bits access methods */
152145300Simp	_BUS_SPACE_CALL_FUNCS(bs,u_int8_t,1)
153145300Simp
154145300Simp	/* 16 bits access methods */
155145300Simp	_BUS_SPACE_CALL_FUNCS(bs,u_int16_t,2)
156145300Simp
157145300Simp	/* 32 bits access methods */
158145300Simp	_BUS_SPACE_CALL_FUNCS(bs,u_int32_t,4)
159145300Simp};
160145300Simp
161145300Simp/*
162145300Simp * Access methods for bus resources and address space.
163145300Simp */
164145300Simpstruct bus_space_tag {
165214584Snyan#define	BUS_SPACE_TAG_IO	0
166214584Snyan#define	BUS_SPACE_TAG_MEM	1
167145300Simp	u_int	bs_tag;			/* bus space flags */
168145300Simp
169145300Simp	struct bus_space_access_methods bs_da;	/* direct access */
170145300Simp	struct bus_space_access_methods bs_ra;	/* relocate access */
171145300Simp#if	0
172145300Simp	struct bus_space_access_methods bs_ida;	/* indexed direct access */
173145300Simp#endif
174145300Simp};
175145300Simp
176145300Simp/*
177145300Simp * bus space handle
178145300Simp */
179145300Simpstruct bus_space_handle {
180145300Simp	bus_addr_t	bsh_base;
181145300Simp	size_t		bsh_sz;
182145300Simp
183145300Simp	bus_addr_t	bsh_iat[BUS_SPACE_IAT_MAXSIZE];
184145300Simp	size_t		bsh_maxiatsz;
185145300Simp	size_t		bsh_iatsz;
186145300Simp
187145300Simp	struct resource	**bsh_res;
188145300Simp	size_t		bsh_ressz;
189145300Simp
190145300Simp	struct bus_space_access_methods bsh_bam;
191145300Simp};
192145300Simp
193145300Simp/*
194145300Simp * Values for the pc98 bus space tag, not to be used directly by MI code.
195145300Simp */
196144604Simpextern struct bus_space_tag SBUS_io_space_tag;
197144604Simpextern struct bus_space_tag SBUS_mem_space_tag;
198144604Simp
199216592Stijl#define X86_BUS_SPACE_IO	(&SBUS_io_space_tag)
200216592Stijl#define X86_BUS_SPACE_MEM	(&SBUS_mem_space_tag)
201144604Simp
202144604Simp/*
203144604Simp * Allocate/Free bus_space_handle
204144604Simp */
205144604Simpint i386_bus_space_handle_alloc(bus_space_tag_t t, bus_addr_t bpa,
206144604Simp				bus_size_t size, bus_space_handle_t *bshp);
207144604Simpvoid i386_bus_space_handle_free(bus_space_tag_t t, bus_space_handle_t bsh,
208144604Simp				size_t size);
209144604Simp
210144604Simp/*
211144604Simp *      int bus_space_map (bus_space_tag_t t, bus_addr_t addr,
212144604Simp *          bus_size_t size, int flag, bus_space_handle_t *bshp);
213144604Simp *
214144604Simp * Map a region of bus space.
215144604Simp */
216144604Simp
217144604Simpint i386_memio_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
218144604Simp		   int flag, bus_space_handle_t *bshp);
219144604Simp
220144604Simp#define bus_space_map(t, a, s, f, hp)					\
221144604Simp	i386_memio_map((t), (a), (s), (f), (hp))
222144604Simp
223144604Simp/*
224144604Simp *      int bus_space_unmap (bus_space_tag_t t,
225144604Simp *          bus_space_handle_t bsh, bus_size_t size);
226144604Simp *
227144604Simp * Unmap a region of bus space.
228144604Simp */
229144604Simp
230144604Simpvoid i386_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
231144604Simp		       bus_size_t size);
232144604Simp
233144604Simp#define bus_space_unmap(t, h, s)					\
234144604Simp	i386_memio_unmap((t), (h), (s))
235144604Simp
236144604Simp/*
237182836Snyan *      int bus_space_map_load (bus_space_tag_t t, bus_space_handle_t bsh,
238182836Snyan *          bus_size_t size, bus_space_iat_t iat, u_int flags);
239182836Snyan *
240182836Snyan * Load I/O address table of bus space.
241182836Snyan */
242182836Snyan
243182836Snyanint i386_memio_map_load(bus_space_tag_t t, bus_space_handle_t bsh,
244182836Snyan			bus_size_t size, bus_space_iat_t iat, u_int flags);
245182836Snyan
246182836Snyan#define bus_space_map_load(t, h, s, iat, f)				\
247182836Snyan	i386_memio_map_load((t), (h), (s), (iat), (f))
248182836Snyan
249182836Snyan/*
250144604Simp *      int bus_space_subregion (bus_space_tag_t t,
251144604Simp *          bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
252144604Simp *          bus_space_handle_t *nbshp);
253144604Simp *
254144604Simp * Get a new handle for a subregion of an already-mapped area of bus space.
255144604Simp */
256144604Simp
257144604Simpint i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
258144604Simp			 bus_size_t offset, bus_size_t size,
259144604Simp			 bus_space_handle_t *nbshp);
260144604Simp
261144604Simp#define bus_space_subregion(t, h, o, s, nhp)				\
262144604Simp	i386_memio_subregion((t), (h), (o), (s), (nhp))
263144604Simp
264144604Simp/*
265144604Simp *      int bus_space_free (bus_space_tag_t t,
266144604Simp *          bus_space_handle_t bsh, bus_size_t size);
267144604Simp *
268144604Simp * Free a region of bus space.
269144604Simp */
270144604Simp
271144604Simpvoid i386_memio_free(bus_space_tag_t t, bus_space_handle_t bsh,
272144604Simp		     bus_size_t size);
273144604Simp
274144604Simp#define bus_space_free(t, h, s)						\
275144604Simp	i386_memio_free((t), (h), (s))
276144604Simp
277144604Simp/*
278180303Snyan *      int bus_space_compare (bus_space_tag_t t1, bus_space_handle_t bsh1,
279180303Snyan *          bus_space_tag_t t2, bus_space_handle_t bsh2);
280180303Snyan *
281180303Snyan * Compare two resources.
282180303Snyan */
283180303Snyanint i386_memio_compare(bus_space_tag_t t1, bus_space_handle_t bsh1,
284180303Snyan		       bus_space_tag_t t2, bus_space_handle_t bsh2);
285180303Snyan
286182836Snyan#define bus_space_compare(t1, h1, t2, h2)				\
287182836Snyan	i386_memio_compare((t1), (h1), (t2), (h2))
288182836Snyan
289180303Snyan/*
290144604Simp * Access methods for bus resources and address space.
291144604Simp */
292144604Simp#define	_BUS_ACCESS_METHODS_PROTO(TYPE,BWN) \
293144604Simp	static __inline TYPE bus_space_read_##BWN 			\
294144604Simp	(bus_space_tag_t, bus_space_handle_t, bus_size_t offset);	\
295144604Simp	static __inline void bus_space_read_multi_##BWN			\
296144604Simp	(bus_space_tag_t, bus_space_handle_t,				\
297144604Simp	     bus_size_t, TYPE *, size_t);				\
298144604Simp	static __inline void bus_space_read_region_##BWN		\
299144604Simp	(bus_space_tag_t, bus_space_handle_t,				\
300144604Simp	     bus_size_t, TYPE *, size_t);				\
301144604Simp	static __inline void bus_space_write_##BWN			\
302144604Simp	(bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE);	\
303144604Simp	static __inline void bus_space_write_multi_##BWN		\
304144604Simp	(bus_space_tag_t, bus_space_handle_t,				\
305144604Simp	     bus_size_t, const TYPE *, size_t);				\
306144604Simp	static __inline void bus_space_write_region_##BWN		\
307144604Simp	(bus_space_tag_t, bus_space_handle_t,				\
308144604Simp	     bus_size_t, const TYPE *, size_t);				\
309144604Simp	static __inline void bus_space_set_multi_##BWN			\
310144604Simp	(bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE, size_t);\
311144604Simp	static __inline void bus_space_set_region_##BWN			\
312144604Simp	(bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE, size_t);\
313144604Simp	static __inline void bus_space_copy_region_##BWN		\
314144604Simp	(bus_space_tag_t, bus_space_handle_t, bus_size_t,		\
315144604Simp	     bus_space_handle_t, bus_size_t, size_t);
316144604Simp
317144604Simp_BUS_ACCESS_METHODS_PROTO(u_int8_t,1)
318144604Simp_BUS_ACCESS_METHODS_PROTO(u_int16_t,2)
319144604Simp_BUS_ACCESS_METHODS_PROTO(u_int32_t,4)
320144604Simp
321144604Simp/*
322144604Simp * read methods
323144604Simp */
324242866Snyan#define	_BUS_SPACE_READ(TYPE,BWN)					\
325242866Snyanstatic __inline TYPE							\
326242866Snyanbus_space_read_##BWN (bus_space_tag_t tag, bus_space_handle_t bsh,	\
327242866Snyan	bus_size_t offset)						\
328242866Snyan{									\
329242866Snyan	register TYPE result;						\
330242866Snyan									\
331242866Snyan	__asm __volatile("call *%2"  					\
332242866Snyan			:"=a" (result),					\
333242866Snyan			 "=d" (offset)					\
334242866Snyan			:"o" (bsh->bsh_bam.bs_read_##BWN),		\
335242866Snyan			 "b" (bsh),					\
336242866Snyan			 "1" (offset)					\
337242866Snyan			);						\
338242866Snyan									\
339242866Snyan	return result;							\
340144604Simp}
341144604Simp
342144604Simp_BUS_SPACE_READ(u_int8_t,1)
343144604Simp_BUS_SPACE_READ(u_int16_t,2)
344144604Simp_BUS_SPACE_READ(u_int32_t,4)
345144604Simp
346144604Simp/*
347144604Simp * write methods
348144604Simp */
349242866Snyan#define	_BUS_SPACE_WRITE(TYPE,BWN)					\
350242866Snyanstatic __inline void							\
351242866Snyanbus_space_write_##BWN (bus_space_tag_t tag, bus_space_handle_t bsh,	\
352242866Snyan	bus_size_t offset, TYPE  val)					\
353242866Snyan{									\
354242866Snyan									\
355242866Snyan	__asm __volatile("call *%1"					\
356242866Snyan			:"=d" (offset)					\
357242866Snyan			:"o" (bsh->bsh_bam.bs_write_##BWN),		\
358242866Snyan			 "a" (val),					\
359242866Snyan			 "b" (bsh),					\
360242866Snyan			 "0" (offset)					\
361242866Snyan			);						\
362144604Simp}
363144604Simp
364144604Simp_BUS_SPACE_WRITE(u_int8_t,1)
365144604Simp_BUS_SPACE_WRITE(u_int16_t,2)
366144604Simp_BUS_SPACE_WRITE(u_int32_t,4)
367144604Simp
368144604Simp/*
369144604Simp * multi read
370144604Simp */
371144604Simp#define	_BUS_SPACE_READ_MULTI(TYPE,BWN)					\
372144604Simpstatic __inline void							\
373242866Snyanbus_space_read_multi_##BWN (bus_space_tag_t tag, bus_space_handle_t bsh, \
374242866Snyan	bus_size_t offset, TYPE *buf, size_t cnt) 			\
375144604Simp{									\
376216143Sbrucec									\
377144604Simp	__asm __volatile("call *%3"					\
378144604Simp			:"=c" (cnt),					\
379144604Simp			 "=d" (offset),					\
380144604Simp			 "=D" (buf)					\
381144604Simp			:"o" (bsh->bsh_bam.bs_read_multi_##BWN),	\
382144604Simp			 "b" (bsh),					\
383144604Simp			 "0" (cnt),					\
384144604Simp			 "1" (offset),					\
385144604Simp			 "2" (buf)					\
386144604Simp			:"memory");					\
387144604Simp}
388144604Simp
389144604Simp_BUS_SPACE_READ_MULTI(u_int8_t,1)
390144604Simp_BUS_SPACE_READ_MULTI(u_int16_t,2)
391144604Simp_BUS_SPACE_READ_MULTI(u_int32_t,4)
392144604Simp
393144604Simp/*
394144604Simp * multi write
395144604Simp */
396144604Simp#define	_BUS_SPACE_WRITE_MULTI(TYPE,BWN)				\
397144604Simpstatic __inline void							\
398242866Snyanbus_space_write_multi_##BWN (bus_space_tag_t tag, bus_space_handle_t bsh, \
399242866Snyan	bus_size_t offset, const TYPE *buf, size_t cnt) 		\
400144604Simp{									\
401216143Sbrucec									\
402144604Simp	__asm __volatile("call *%3"					\
403144604Simp			:"=c" (cnt),					\
404144604Simp			 "=d" (offset),					\
405144604Simp			 "=S" (buf)					\
406144604Simp			:"o" (bsh->bsh_bam.bs_write_multi_##BWN),	\
407144604Simp			 "b" (bsh),					\
408144604Simp			 "0" (cnt),					\
409144604Simp			 "1" (offset),					\
410144604Simp			 "2" (buf)					\
411144604Simp			);						\
412144604Simp}
413144604Simp
414144604Simp_BUS_SPACE_WRITE_MULTI(u_int8_t,1)
415144604Simp_BUS_SPACE_WRITE_MULTI(u_int16_t,2)
416144604Simp_BUS_SPACE_WRITE_MULTI(u_int32_t,4)
417144604Simp
418144604Simp/*
419144604Simp * region read
420144604Simp */
421144604Simp#define	_BUS_SPACE_READ_REGION(TYPE,BWN)				\
422144604Simpstatic __inline void							\
423242866Snyanbus_space_read_region_##BWN (bus_space_tag_t tag, bus_space_handle_t bsh, \
424242866Snyan	bus_size_t offset, TYPE *buf, size_t cnt) 			\
425144604Simp{									\
426216143Sbrucec									\
427144604Simp	__asm __volatile("call *%3"					\
428144604Simp			:"=c" (cnt),					\
429144604Simp			 "=d" (offset),					\
430144604Simp			 "=D" (buf)					\
431144604Simp			:"o" (bsh->bsh_bam.bs_read_region_##BWN),	\
432144604Simp			 "b" (bsh),					\
433144604Simp			 "0" (cnt),					\
434144604Simp			 "1" (offset),					\
435144604Simp			 "2" (buf)					\
436144604Simp			:"memory");					\
437144604Simp}
438144604Simp
439144604Simp_BUS_SPACE_READ_REGION(u_int8_t,1)
440144604Simp_BUS_SPACE_READ_REGION(u_int16_t,2)
441144604Simp_BUS_SPACE_READ_REGION(u_int32_t,4)
442144604Simp
443144604Simp/*
444144604Simp * region write
445144604Simp */
446144604Simp#define	_BUS_SPACE_WRITE_REGION(TYPE,BWN)				\
447144604Simpstatic __inline void							\
448242866Snyanbus_space_write_region_##BWN (bus_space_tag_t tag, bus_space_handle_t bsh, \
449242866Snyan	bus_size_t offset, const TYPE *buf, size_t cnt) 		\
450144604Simp{									\
451216143Sbrucec									\
452144604Simp	__asm __volatile("call *%3"					\
453144604Simp			:"=c" (cnt),					\
454144604Simp			 "=d" (offset),					\
455144604Simp			 "=S" (buf)					\
456144604Simp			:"o" (bsh->bsh_bam.bs_write_region_##BWN),	\
457144604Simp			 "b" (bsh),					\
458144604Simp			 "0" (cnt),					\
459144604Simp			 "1" (offset),					\
460144604Simp			 "2" (buf)					\
461144604Simp			);						\
462144604Simp}
463144604Simp
464144604Simp_BUS_SPACE_WRITE_REGION(u_int8_t,1)
465144604Simp_BUS_SPACE_WRITE_REGION(u_int16_t,2)
466144604Simp_BUS_SPACE_WRITE_REGION(u_int32_t,4)
467144604Simp
468144604Simp/*
469144604Simp * multi set
470144604Simp */
471144604Simp#define	_BUS_SPACE_SET_MULTI(TYPE,BWN)					\
472144604Simpstatic __inline void							\
473242866Snyanbus_space_set_multi_##BWN (bus_space_tag_t tag, bus_space_handle_t bsh,	\
474242866Snyan	bus_size_t offset, TYPE val, size_t cnt)	 		\
475144604Simp{									\
476216143Sbrucec									\
477144604Simp	__asm __volatile("call *%2"					\
478144604Simp			:"=c" (cnt),					\
479144604Simp			 "=d" (offset)					\
480144604Simp			:"o" (bsh->bsh_bam.bs_set_multi_##BWN),		\
481144604Simp			 "a" (val),					\
482144604Simp			 "b" (bsh),					\
483144604Simp			 "0" (cnt),					\
484144604Simp			 "1" (offset)					\
485144604Simp			);						\
486144604Simp}
487144604Simp
488144604Simp_BUS_SPACE_SET_MULTI(u_int8_t,1)
489144604Simp_BUS_SPACE_SET_MULTI(u_int16_t,2)
490144604Simp_BUS_SPACE_SET_MULTI(u_int32_t,4)
491144604Simp
492144604Simp/*
493144604Simp * region set
494144604Simp */
495144604Simp#define	_BUS_SPACE_SET_REGION(TYPE,BWN)					\
496144604Simpstatic __inline void							\
497242866Snyanbus_space_set_region_##BWN (bus_space_tag_t tag, bus_space_handle_t bsh, \
498242866Snyan	bus_size_t offset, TYPE val, size_t cnt) 			\
499144604Simp{									\
500216143Sbrucec									\
501144604Simp	__asm __volatile("call *%2"					\
502144604Simp			:"=c" (cnt),					\
503144604Simp			 "=d" (offset)					\
504144604Simp			:"o" (bsh->bsh_bam.bs_set_region_##BWN),	\
505144604Simp			 "a" (val),					\
506144604Simp			 "b" (bsh),					\
507144604Simp			 "0" (cnt),					\
508144604Simp			 "1" (offset)					\
509144604Simp			);						\
510144604Simp}
511144604Simp
512144604Simp_BUS_SPACE_SET_REGION(u_int8_t,1)
513144604Simp_BUS_SPACE_SET_REGION(u_int16_t,2)
514144604Simp_BUS_SPACE_SET_REGION(u_int32_t,4)
515144604Simp
516144604Simp/*
517144604Simp * copy
518144604Simp */
519144604Simp#define	_BUS_SPACE_COPY_REGION(BWN)					\
520144604Simpstatic __inline void							\
521242866Snyanbus_space_copy_region_##BWN (bus_space_tag_t tag, bus_space_handle_t sbsh, \
522242866Snyan	bus_size_t src, bus_space_handle_t dbsh, bus_size_t dst, size_t cnt) \
523144604Simp{									\
524144604Simp									\
525144604Simp	if (dbsh->bsh_bam.bs_copy_region_1 != sbsh->bsh_bam.bs_copy_region_1) \
526144604Simp		panic("bus_space_copy_region: funcs mismatch (ENOSUPPORT)");\
527144604Simp									\
528144604Simp	__asm __volatile("call *%3"					\
529144604Simp			:"=c" (cnt),					\
530144604Simp			 "=S" (src),					\
531144604Simp			 "=D" (dst)					\
532144604Simp			:"o" (dbsh->bsh_bam.bs_copy_region_##BWN),	\
533144604Simp			 "a" (sbsh),					\
534144604Simp			 "b" (dbsh),					\
535144604Simp			 "0" (cnt),					\
536144604Simp			 "1" (src),					\
537144604Simp			 "2" (dst)					\
538144604Simp			);						\
539144604Simp}
540144604Simp
541144604Simp_BUS_SPACE_COPY_REGION(1)
542144604Simp_BUS_SPACE_COPY_REGION(2)
543144604Simp_BUS_SPACE_COPY_REGION(4)
544144604Simp
545144604Simp/*
546144604Simp * Bus read/write barrier methods.
547144604Simp *
548144604Simp *	void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
549144604Simp *			       bus_size_t offset, bus_size_t len, int flags);
550144604Simp *
551144604Simp *
552144604Simp * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
553144604Simp * prevent reordering by the compiler; all Intel x86 processors currently
554144604Simp * retire operations outside the CPU in program order.
555144604Simp */
556144604Simp#define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
557144604Simp#define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
558144604Simp
559144604Simpstatic __inline void
560144604Simpbus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
561144604Simp		  bus_size_t offset, bus_size_t len, int flags)
562144604Simp{
563144604Simp	if (flags & BUS_SPACE_BARRIER_READ)
564144604Simp		__asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
565144604Simp	else
566241374Sattilio		__compiler_membar();
567144604Simp}
568144604Simp
569153110Sru#ifdef BUS_SPACE_NO_LEGACY
570144604Simp#undef inb
571144604Simp#undef outb
572144604Simp#define inb(a) compiler_error
573144604Simp#define inw(a) compiler_error
574144604Simp#define inl(a) compiler_error
575144604Simp#define outb(a, b) compiler_error
576144604Simp#define outw(a, b) compiler_error
577144604Simp#define outl(a, b) compiler_error
578144604Simp#endif
579144604Simp
580144604Simp#include <machine/bus_dma.h>
581144604Simp
582144604Simp/*
583144604Simp * Stream accesses are the same as normal accesses on i386/pc98; there are no
584144604Simp * supported bus systems with an endianess different from the host one.
585144604Simp */
586144604Simp#define	bus_space_read_stream_1(t, h, o)	bus_space_read_1((t), (h), (o))
587144604Simp#define	bus_space_read_stream_2(t, h, o)	bus_space_read_2((t), (h), (o))
588144604Simp#define	bus_space_read_stream_4(t, h, o)	bus_space_read_4((t), (h), (o))
589144604Simp
590144604Simp#define	bus_space_read_multi_stream_1(t, h, o, a, c) \
591144604Simp	bus_space_read_multi_1((t), (h), (o), (a), (c))
592144604Simp#define	bus_space_read_multi_stream_2(t, h, o, a, c) \
593144604Simp	bus_space_read_multi_2((t), (h), (o), (a), (c))
594144604Simp#define	bus_space_read_multi_stream_4(t, h, o, a, c) \
595144604Simp	bus_space_read_multi_4((t), (h), (o), (a), (c))
596144604Simp
597144604Simp#define	bus_space_write_stream_1(t, h, o, v) \
598144604Simp	bus_space_write_1((t), (h), (o), (v))
599144604Simp#define	bus_space_write_stream_2(t, h, o, v) \
600144604Simp	bus_space_write_2((t), (h), (o), (v))
601144604Simp#define	bus_space_write_stream_4(t, h, o, v) \
602144604Simp	bus_space_write_4((t), (h), (o), (v))
603144604Simp
604144604Simp#define	bus_space_write_multi_stream_1(t, h, o, a, c) \
605144604Simp	bus_space_write_multi_1((t), (h), (o), (a), (c))
606144604Simp#define	bus_space_write_multi_stream_2(t, h, o, a, c) \
607144604Simp	bus_space_write_multi_2((t), (h), (o), (a), (c))
608144604Simp#define	bus_space_write_multi_stream_4(t, h, o, a, c) \
609144604Simp	bus_space_write_multi_4((t), (h), (o), (a), (c))
610144604Simp
611144604Simp#define	bus_space_set_multi_stream_1(t, h, o, v, c) \
612144604Simp	bus_space_set_multi_1((t), (h), (o), (v), (c))
613144604Simp#define	bus_space_set_multi_stream_2(t, h, o, v, c) \
614144604Simp	bus_space_set_multi_2((t), (h), (o), (v), (c))
615144604Simp#define	bus_space_set_multi_stream_4(t, h, o, v, c) \
616144604Simp	bus_space_set_multi_4((t), (h), (o), (v), (c))
617144604Simp
618144604Simp#define	bus_space_read_region_stream_1(t, h, o, a, c) \
619144604Simp	bus_space_read_region_1((t), (h), (o), (a), (c))
620144604Simp#define	bus_space_read_region_stream_2(t, h, o, a, c) \
621144604Simp	bus_space_read_region_2((t), (h), (o), (a), (c))
622144604Simp#define	bus_space_read_region_stream_4(t, h, o, a, c) \
623144604Simp	bus_space_read_region_4((t), (h), (o), (a), (c))
624144604Simp
625144604Simp#define	bus_space_write_region_stream_1(t, h, o, a, c) \
626144604Simp	bus_space_write_region_1((t), (h), (o), (a), (c))
627144604Simp#define	bus_space_write_region_stream_2(t, h, o, a, c) \
628144604Simp	bus_space_write_region_2((t), (h), (o), (a), (c))
629144604Simp#define	bus_space_write_region_stream_4(t, h, o, a, c) \
630144604Simp	bus_space_write_region_4((t), (h), (o), (a), (c))
631144604Simp
632144604Simp#define	bus_space_set_region_stream_1(t, h, o, v, c) \
633144604Simp	bus_space_set_region_1((t), (h), (o), (v), (c))
634144604Simp#define	bus_space_set_region_stream_2(t, h, o, v, c) \
635144604Simp	bus_space_set_region_2((t), (h), (o), (v), (c))
636144604Simp#define	bus_space_set_region_stream_4(t, h, o, v, c) \
637144604Simp	bus_space_set_region_4((t), (h), (o), (v), (c))
638144604Simp
639144604Simp#define	bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
640144604Simp	bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
641144604Simp#define	bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
642144604Simp	bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
643144604Simp#define	bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
644144604Simp	bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
645144604Simp
646291716Sken#endif /* _KERNEL */
647291716Sken
648144604Simp#endif /* _PC98_BUS_H_ */
649