bus.h revision 145119
132517Sgibbs/*-
258762Skato * Copyright (c) KATO Takenori, 1999.
332517Sgibbs *
458762Skato * All rights reserved.  Unpublished rights reserved under the copyright
558762Skato * laws of Japan.
632517Sgibbs *
732517Sgibbs * Redistribution and use in source and binary forms, with or without
832517Sgibbs * modification, are permitted provided that the following conditions
932517Sgibbs * are met:
1058762Skato *
1132517Sgibbs * 1. Redistributions of source code must retain the above copyright
1258762Skato *    notice, this list of conditions and the following disclaimer as
1358762Skato *    the first lines of this file unmodified.
1432517Sgibbs * 2. Redistributions in binary form must reproduce the above copyright
1532517Sgibbs *    notice, this list of conditions and the following disclaimer in the
1632517Sgibbs *    documentation and/or other materials provided with the distribution.
1758762Skato * 3. The name of the author may not be used to endorse or promote products
1858762Skato *    derived from this software without specific prior written permission.
1958762Skato *
2032517Sgibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2132517Sgibbs * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2232517Sgibbs * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2332517Sgibbs * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2432517Sgibbs * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2532517Sgibbs * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2632517Sgibbs * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2732517Sgibbs * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2832517Sgibbs * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2932517Sgibbs * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3058762Skato *
3158762Skato * $FreeBSD: head/sys/amd64/include/bus.h 145119 2005-04-15 18:38:59Z peter $
3232517Sgibbs */
3332517Sgibbs
34145119Speter/*	$NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $	*/
35145119Speter
36145119Speter/*-
37145119Speter * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
38145119Speter * All rights reserved.
39145119Speter *
40145119Speter * This code is derived from software contributed to The NetBSD Foundation
41145119Speter * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
42145119Speter * NASA Ames Research Center.
43145119Speter *
44145119Speter * Redistribution and use in source and binary forms, with or without
45145119Speter * modification, are permitted provided that the following conditions
46145119Speter * are met:
47145119Speter * 1. Redistributions of source code must retain the above copyright
48145119Speter *    notice, this list of conditions and the following disclaimer.
49145119Speter * 2. Redistributions in binary form must reproduce the above copyright
50145119Speter *    notice, this list of conditions and the following disclaimer in the
51145119Speter *    documentation and/or other materials provided with the distribution.
52145119Speter * 3. All advertising materials mentioning features or use of this software
53145119Speter *    must display the following acknowledgement:
54145119Speter *	This product includes software developed by the NetBSD
55145119Speter *	Foundation, Inc. and its contributors.
56145119Speter * 4. Neither the name of The NetBSD Foundation nor the names of its
57145119Speter *    contributors may be used to endorse or promote products derived
58145119Speter *    from this software without specific prior written permission.
59145119Speter *
60145119Speter * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
61145119Speter * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
62145119Speter * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
63145119Speter * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
64145119Speter * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
65145119Speter * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
66145119Speter * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
67145119Speter * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
68145119Speter * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
69145119Speter * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
70145119Speter * POSSIBILITY OF SUCH DAMAGE.
71145119Speter */
72145119Speter
73145119Speter/*-
74145119Speter * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
75145119Speter * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
76145119Speter *
77145119Speter * Redistribution and use in source and binary forms, with or without
78145119Speter * modification, are permitted provided that the following conditions
79145119Speter * are met:
80145119Speter * 1. Redistributions of source code must retain the above copyright
81145119Speter *    notice, this list of conditions and the following disclaimer.
82145119Speter * 2. Redistributions in binary form must reproduce the above copyright
83145119Speter *    notice, this list of conditions and the following disclaimer in the
84145119Speter *    documentation and/or other materials provided with the distribution.
85145119Speter * 3. All advertising materials mentioning features or use of this software
86145119Speter *    must display the following acknowledgement:
87145119Speter *      This product includes software developed by Christopher G. Demetriou
88145119Speter *	for the NetBSD Project.
89145119Speter * 4. The name of the author may not be used to endorse or promote products
90145119Speter *    derived from this software without specific prior written permission
91145119Speter *
92145119Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
93145119Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
94145119Speter * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
95145119Speter * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
96145119Speter * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97145119Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
98145119Speter * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
99145119Speter * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100145119Speter * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
101145119Speter * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102145119Speter */
103145119Speter
104114930Speter#ifndef _AMD64_BUS_H_
105114930Speter#define _AMD64_BUS_H_
10632517Sgibbs
107145119Speter#include <machine/cpufunc.h>
108145119Speter
109145119Speter/*
110145119Speter * To remain compatible with NetBSD's interface, default to both memio and
111145119Speter * pio when neither of them is defined.
112145119Speter */
113145119Speter#if !defined(_AMD64_BUS_PIO_H_) && !defined(_AMD64_BUS_MEMIO_H_)
114145119Speter#define _AMD64_BUS_PIO_H_
115145119Speter#define _AMD64_BUS_MEMIO_H_
116145119Speter#endif
117145119Speter
118145119Speter/*
119145119Speter * Values for the amd64 bus space tag, not to be used directly by MI code.
120145119Speter */
121145119Speter#define	AMD64_BUS_SPACE_IO	0	/* space is i/o space */
122145119Speter#define AMD64_BUS_SPACE_MEM	1	/* space is mem space */
123145119Speter
124145119Speter/*
125145119Speter * Bus address and size types
126145119Speter */
127145119Spetertypedef uint64_t bus_addr_t;
128145119Spetertypedef uint64_t bus_size_t;
129145119Speter
130145119Speter#define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
131145119Speter#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
132145119Speter#define BUS_SPACE_MAXSIZE	0xFFFFFFFF
133145119Speter#define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
134145119Speter#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
135145119Speter#define BUS_SPACE_MAXADDR	0xFFFFFFFFFFFFFFFFULL
136145119Speter
137145119Speter#define BUS_SPACE_UNRESTRICTED	(~0)
138145119Speter
139145119Speter/*
140145119Speter * Access methods for bus resources and address space.
141145119Speter */
142145119Spetertypedef	uint64_t bus_space_tag_t;
143145119Spetertypedef	uint64_t bus_space_handle_t;
144145119Speter
145145119Speter/*
146145119Speter * Map a region of device bus space into CPU virtual address space.
147145119Speter */
148145119Speter
149145119Speterstatic __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
150145119Speter				  bus_size_t size, int flags,
151145119Speter				  bus_space_handle_t *bshp);
152145119Speter
153145119Speterstatic __inline int
154145119Speterbus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
155145119Speter	      bus_size_t size __unused, int flags __unused,
156145119Speter	      bus_space_handle_t *bshp)
157145119Speter{
158145119Speter
159145119Speter	*bshp = addr;
160145119Speter	return (0);
161145119Speter}
162145119Speter
163145119Speter/*
164145119Speter * Unmap a region of device bus space.
165145119Speter */
166145119Speter
167145119Speterstatic __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
168145119Speter				     bus_size_t size);
169145119Speter
170145119Speterstatic __inline void
171145119Speterbus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
172145119Speter		bus_size_t size __unused)
173145119Speter{
174145119Speter}
175145119Speter
176145119Speter/*
177145119Speter * Get a new handle for a subregion of an already-mapped area of bus space.
178145119Speter */
179145119Speter
180145119Speterstatic __inline int bus_space_subregion(bus_space_tag_t t,
181145119Speter					bus_space_handle_t bsh,
182145119Speter					bus_size_t offset, bus_size_t size,
183145119Speter					bus_space_handle_t *nbshp);
184145119Speter
185145119Speterstatic __inline int
186145119Speterbus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
187145119Speter		    bus_size_t offset, bus_size_t size __unused,
188145119Speter		    bus_space_handle_t *nbshp)
189145119Speter{
190145119Speter
191145119Speter	*nbshp = bsh + offset;
192145119Speter	return (0);
193145119Speter}
194145119Speter
195145119Speter/*
196145119Speter * Allocate a region of memory that is accessible to devices in bus space.
197145119Speter */
198145119Speter
199145119Speterint	bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
200145119Speter			bus_addr_t rend, bus_size_t size, bus_size_t align,
201145119Speter			bus_size_t boundary, int flags, bus_addr_t *addrp,
202145119Speter			bus_space_handle_t *bshp);
203145119Speter
204145119Speter/*
205145119Speter * Free a region of bus space accessible memory.
206145119Speter */
207145119Speter
208145119Speterstatic __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
209145119Speter				    bus_size_t size);
210145119Speter
211145119Speterstatic __inline void
212145119Speterbus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
213145119Speter	       bus_size_t size __unused)
214145119Speter{
215145119Speter}
216145119Speter
217145119Speter
218145119Speter#if defined(_AMD64_BUS_PIO_H_) || defined(_AMD64_BUS_MEMIO_H_)
219145119Speter
220145119Speter/*
221145119Speter * Read a 1, 2, 4, or 8 byte quantity from bus space
222145119Speter * described by tag/handle/offset.
223145119Speter */
224145119Speterstatic __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
225145119Speter					  bus_space_handle_t handle,
226145119Speter					  bus_size_t offset);
227145119Speter
228145119Speterstatic __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
229145119Speter					   bus_space_handle_t handle,
230145119Speter					   bus_size_t offset);
231145119Speter
232145119Speterstatic __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
233145119Speter					   bus_space_handle_t handle,
234145119Speter					   bus_size_t offset);
235145119Speter
236145119Speterstatic __inline u_int8_t
237145119Speterbus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
238145119Speter		 bus_size_t offset)
239145119Speter{
240145119Speter#if defined (_AMD64_BUS_PIO_H_)
241145119Speter#if defined (_AMD64_BUS_MEMIO_H_)
242145119Speter	if (tag == AMD64_BUS_SPACE_IO)
243145119Speter#endif
244145119Speter		return (inb(handle + offset));
245145119Speter#endif
246145119Speter#if defined (_AMD64_BUS_MEMIO_H_)
247145119Speter	return (*(volatile u_int8_t *)(handle + offset));
248145119Speter#endif
249145119Speter}
250145119Speter
251145119Speterstatic __inline u_int16_t
252145119Speterbus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
253145119Speter		 bus_size_t offset)
254145119Speter{
255145119Speter#if defined(_AMD64_BUS_PIO_H_)
256145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
257145119Speter	if (tag == AMD64_BUS_SPACE_IO)
258145119Speter#endif
259145119Speter		return (inw(handle + offset));
260145119Speter#endif
261145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
262145119Speter	return (*(volatile u_int16_t *)(handle + offset));
263145119Speter#endif
264145119Speter}
265145119Speter
266145119Speterstatic __inline u_int32_t
267145119Speterbus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
268145119Speter		 bus_size_t offset)
269145119Speter{
270145119Speter#if defined(_AMD64_BUS_PIO_H_)
271145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
272145119Speter	if (tag == AMD64_BUS_SPACE_IO)
273145119Speter#endif
274145119Speter		return (inl(handle + offset));
275145119Speter#endif
276145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
277145119Speter	return (*(volatile u_int32_t *)(handle + offset));
278145119Speter#endif
279145119Speter}
280145119Speter
281145119Speter#if 0	/* Cause a link error for bus_space_read_8 */
282145119Speter#define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
283145119Speter#endif
284145119Speter
285145119Speter/*
286145119Speter * Read `count' 1, 2, 4, or 8 byte quantities from bus space
287145119Speter * described by tag/handle/offset and copy into buffer provided.
288145119Speter */
289145119Speterstatic __inline void bus_space_read_multi_1(bus_space_tag_t tag,
290145119Speter					    bus_space_handle_t bsh,
291145119Speter					    bus_size_t offset, u_int8_t *addr,
292145119Speter					    size_t count);
293145119Speter
294145119Speterstatic __inline void bus_space_read_multi_2(bus_space_tag_t tag,
295145119Speter					    bus_space_handle_t bsh,
296145119Speter					    bus_size_t offset, u_int16_t *addr,
297145119Speter					    size_t count);
298145119Speter
299145119Speterstatic __inline void bus_space_read_multi_4(bus_space_tag_t tag,
300145119Speter					    bus_space_handle_t bsh,
301145119Speter					    bus_size_t offset, u_int32_t *addr,
302145119Speter					    size_t count);
303145119Speter
304145119Speterstatic __inline void
305145119Speterbus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
306145119Speter		       bus_size_t offset, u_int8_t *addr, size_t count)
307145119Speter{
308145119Speter#if defined(_AMD64_BUS_PIO_H_)
309145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
310145119Speter	if (tag == AMD64_BUS_SPACE_IO)
311145119Speter#endif
312145119Speter		insb(bsh + offset, addr, count);
313145119Speter#endif
314145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
315145119Speter#if defined(_AMD64_BUS_PIO_H_)
316145119Speter	else
317145119Speter#endif
318145119Speter	{
319145119Speter#ifdef __GNUCLIKE_ASM
320145119Speter		__asm __volatile("				\n\
321145119Speter			cld					\n\
322145119Speter		1:	movb (%2),%%al				\n\
323145119Speter			stosb					\n\
324145119Speter			loop 1b"				:
325145119Speter		    "=D" (addr), "=c" (count)			:
326145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
327145119Speter		    "%eax", "memory");
328145119Speter#endif
329145119Speter	}
330145119Speter#endif
331145119Speter}
332145119Speter
333145119Speterstatic __inline void
334145119Speterbus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
335145119Speter		       bus_size_t offset, u_int16_t *addr, size_t count)
336145119Speter{
337145119Speter#if defined(_AMD64_BUS_PIO_H_)
338145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
339145119Speter	if (tag == AMD64_BUS_SPACE_IO)
340145119Speter#endif
341145119Speter		insw(bsh + offset, addr, count);
342145119Speter#endif
343145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
344145119Speter#if defined(_AMD64_BUS_PIO_H_)
345145119Speter	else
346145119Speter#endif
347145119Speter	{
348145119Speter#ifdef __GNUCLIKE_ASM
349145119Speter		__asm __volatile("				\n\
350145119Speter			cld					\n\
351145119Speter		1:	movw (%2),%%ax				\n\
352145119Speter			stosw					\n\
353145119Speter			loop 1b"				:
354145119Speter		    "=D" (addr), "=c" (count)			:
355145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
356145119Speter		    "%eax", "memory");
357145119Speter#endif
358145119Speter	}
359145119Speter#endif
360145119Speter}
361145119Speter
362145119Speterstatic __inline void
363145119Speterbus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
364145119Speter		       bus_size_t offset, u_int32_t *addr, size_t count)
365145119Speter{
366145119Speter#if defined(_AMD64_BUS_PIO_H_)
367145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
368145119Speter	if (tag == AMD64_BUS_SPACE_IO)
369145119Speter#endif
370145119Speter		insl(bsh + offset, addr, count);
371145119Speter#endif
372145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
373145119Speter#if defined(_AMD64_BUS_PIO_H_)
374145119Speter	else
375145119Speter#endif
376145119Speter	{
377145119Speter#ifdef __GNUCLIKE_ASM
378145119Speter		__asm __volatile("				\n\
379145119Speter			cld					\n\
380145119Speter		1:	movl (%2),%%eax				\n\
381145119Speter			stosl					\n\
382145119Speter			loop 1b"				:
383145119Speter		    "=D" (addr), "=c" (count)			:
384145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
385145119Speter		    "%eax", "memory");
386145119Speter#endif
387145119Speter	}
388145119Speter#endif
389145119Speter}
390145119Speter
391145119Speter#if 0	/* Cause a link error for bus_space_read_multi_8 */
392145119Speter#define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
393145119Speter#endif
394145119Speter
395145119Speter/*
396145119Speter * Read `count' 1, 2, 4, or 8 byte quantities from bus space
397145119Speter * described by tag/handle and starting at `offset' and copy into
398145119Speter * buffer provided.
399145119Speter */
400145119Speterstatic __inline void bus_space_read_region_1(bus_space_tag_t tag,
401145119Speter					     bus_space_handle_t bsh,
402145119Speter					     bus_size_t offset, u_int8_t *addr,
403145119Speter					     size_t count);
404145119Speter
405145119Speterstatic __inline void bus_space_read_region_2(bus_space_tag_t tag,
406145119Speter					     bus_space_handle_t bsh,
407145119Speter					     bus_size_t offset, u_int16_t *addr,
408145119Speter					     size_t count);
409145119Speter
410145119Speterstatic __inline void bus_space_read_region_4(bus_space_tag_t tag,
411145119Speter					     bus_space_handle_t bsh,
412145119Speter					     bus_size_t offset, u_int32_t *addr,
413145119Speter					     size_t count);
414145119Speter
415145119Speter
416145119Speterstatic __inline void
417145119Speterbus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
418145119Speter			bus_size_t offset, u_int8_t *addr, size_t count)
419145119Speter{
420145119Speter#if defined(_AMD64_BUS_PIO_H_)
421145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
422145119Speter	if (tag == AMD64_BUS_SPACE_IO)
423145119Speter#endif
424145119Speter	{
425145119Speter		int _port_ = bsh + offset;
426145119Speter#ifdef __GNUCLIKE_ASM
427145119Speter		__asm __volatile("				\n\
428145119Speter			cld					\n\
429145119Speter		1:	inb %w2,%%al				\n\
430145119Speter			stosb					\n\
431145119Speter			incl %2					\n\
432145119Speter			loop 1b"				:
433145119Speter		    "=D" (addr), "=c" (count), "=d" (_port_)	:
434145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
435145119Speter		    "%eax", "memory", "cc");
436145119Speter#endif
437145119Speter	}
438145119Speter#endif
439145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
440145119Speter#if defined(_AMD64_BUS_PIO_H_)
441145119Speter	else
442145119Speter#endif
443145119Speter	{
444145119Speter		bus_space_handle_t _port_ = bsh + offset;
445145119Speter#ifdef __GNUCLIKE_ASM
446145119Speter		__asm __volatile("				\n\
447145119Speter			cld					\n\
448145119Speter			repne					\n\
449145119Speter			movsb"					:
450145119Speter		    "=D" (addr), "=c" (count), "=S" (_port_)	:
451145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
452145119Speter		    "memory", "cc");
453145119Speter#endif
454145119Speter	}
455145119Speter#endif
456145119Speter}
457145119Speter
458145119Speterstatic __inline void
459145119Speterbus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
460145119Speter			bus_size_t offset, u_int16_t *addr, size_t count)
461145119Speter{
462145119Speter#if defined(_AMD64_BUS_PIO_H_)
463145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
464145119Speter	if (tag == AMD64_BUS_SPACE_IO)
465145119Speter#endif
466145119Speter	{
467145119Speter		int _port_ = bsh + offset;
468145119Speter#ifdef __GNUCLIKE_ASM
469145119Speter		__asm __volatile("				\n\
470145119Speter			cld					\n\
471145119Speter		1:	inw %w2,%%ax				\n\
472145119Speter			stosw					\n\
473145119Speter			addl $2,%2				\n\
474145119Speter			loop 1b"				:
475145119Speter		    "=D" (addr), "=c" (count), "=d" (_port_)	:
476145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
477145119Speter		    "%eax", "memory", "cc");
478145119Speter#endif
479145119Speter	}
480145119Speter#endif
481145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
482145119Speter#if defined(_AMD64_BUS_PIO_H_)
483145119Speter	else
484145119Speter#endif
485145119Speter	{
486145119Speter		bus_space_handle_t _port_ = bsh + offset;
487145119Speter#ifdef __GNUCLIKE_ASM
488145119Speter		__asm __volatile("				\n\
489145119Speter			cld					\n\
490145119Speter			repne					\n\
491145119Speter			movsw"					:
492145119Speter		    "=D" (addr), "=c" (count), "=S" (_port_)	:
493145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
494145119Speter		    "memory", "cc");
495145119Speter#endif
496145119Speter	}
497145119Speter#endif
498145119Speter}
499145119Speter
500145119Speterstatic __inline void
501145119Speterbus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
502145119Speter			bus_size_t offset, u_int32_t *addr, size_t count)
503145119Speter{
504145119Speter#if defined(_AMD64_BUS_PIO_H_)
505145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
506145119Speter	if (tag == AMD64_BUS_SPACE_IO)
507145119Speter#endif
508145119Speter	{
509145119Speter		int _port_ = bsh + offset;
510145119Speter#ifdef __GNUCLIKE_ASM
511145119Speter		__asm __volatile("				\n\
512145119Speter			cld					\n\
513145119Speter		1:	inl %w2,%%eax				\n\
514145119Speter			stosl					\n\
515145119Speter			addl $4,%2				\n\
516145119Speter			loop 1b"				:
517145119Speter		    "=D" (addr), "=c" (count), "=d" (_port_)	:
518145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
519145119Speter		    "%eax", "memory", "cc");
520145119Speter#endif
521145119Speter	}
522145119Speter#endif
523145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
524145119Speter#if defined(_AMD64_BUS_PIO_H_)
525145119Speter	else
526145119Speter#endif
527145119Speter	{
528145119Speter		bus_space_handle_t _port_ = bsh + offset;
529145119Speter#ifdef __GNUCLIKE_ASM
530145119Speter		__asm __volatile("				\n\
531145119Speter			cld					\n\
532145119Speter			repne					\n\
533145119Speter			movsl"					:
534145119Speter		    "=D" (addr), "=c" (count), "=S" (_port_)	:
535145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
536145119Speter		    "memory", "cc");
537145119Speter#endif
538145119Speter	}
539145119Speter#endif
540145119Speter}
541145119Speter
542145119Speter#if 0	/* Cause a link error for bus_space_read_region_8 */
543145119Speter#define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
544145119Speter#endif
545145119Speter
546145119Speter/*
547145119Speter * Write the 1, 2, 4, or 8 byte value `value' to bus space
548145119Speter * described by tag/handle/offset.
549145119Speter */
550145119Speter
551145119Speterstatic __inline void bus_space_write_1(bus_space_tag_t tag,
552145119Speter				       bus_space_handle_t bsh,
553145119Speter				       bus_size_t offset, u_int8_t value);
554145119Speter
555145119Speterstatic __inline void bus_space_write_2(bus_space_tag_t tag,
556145119Speter				       bus_space_handle_t bsh,
557145119Speter				       bus_size_t offset, u_int16_t value);
558145119Speter
559145119Speterstatic __inline void bus_space_write_4(bus_space_tag_t tag,
560145119Speter				       bus_space_handle_t bsh,
561145119Speter				       bus_size_t offset, u_int32_t value);
562145119Speter
563145119Speterstatic __inline void
564145119Speterbus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
565145119Speter		       bus_size_t offset, u_int8_t value)
566145119Speter{
567145119Speter#if defined(_AMD64_BUS_PIO_H_)
568145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
569145119Speter	if (tag == AMD64_BUS_SPACE_IO)
570145119Speter#endif
571145119Speter		outb(bsh + offset, value);
572145119Speter#endif
573145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
574145119Speter#if defined(_AMD64_BUS_PIO_H_)
575145119Speter	else
576145119Speter#endif
577145119Speter		*(volatile u_int8_t *)(bsh + offset) = value;
578145119Speter#endif
579145119Speter}
580145119Speter
581145119Speterstatic __inline void
582145119Speterbus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
583145119Speter		       bus_size_t offset, u_int16_t value)
584145119Speter{
585145119Speter#if defined(_AMD64_BUS_PIO_H_)
586145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
587145119Speter	if (tag == AMD64_BUS_SPACE_IO)
588145119Speter#endif
589145119Speter		outw(bsh + offset, value);
590145119Speter#endif
591145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
592145119Speter#if defined(_AMD64_BUS_PIO_H_)
593145119Speter	else
594145119Speter#endif
595145119Speter		*(volatile u_int16_t *)(bsh + offset) = value;
596145119Speter#endif
597145119Speter}
598145119Speter
599145119Speterstatic __inline void
600145119Speterbus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
601145119Speter		       bus_size_t offset, u_int32_t value)
602145119Speter{
603145119Speter#if defined(_AMD64_BUS_PIO_H_)
604145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
605145119Speter	if (tag == AMD64_BUS_SPACE_IO)
606145119Speter#endif
607145119Speter		outl(bsh + offset, value);
608145119Speter#endif
609145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
610145119Speter#if defined(_AMD64_BUS_PIO_H_)
611145119Speter	else
612145119Speter#endif
613145119Speter		*(volatile u_int32_t *)(bsh + offset) = value;
614145119Speter#endif
615145119Speter}
616145119Speter
617145119Speter#if 0	/* Cause a link error for bus_space_write_8 */
618145119Speter#define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
619145119Speter#endif
620145119Speter
621145119Speter/*
622145119Speter * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
623145119Speter * provided to bus space described by tag/handle/offset.
624145119Speter */
625145119Speter
626145119Speterstatic __inline void bus_space_write_multi_1(bus_space_tag_t tag,
627145119Speter					     bus_space_handle_t bsh,
628145119Speter					     bus_size_t offset,
629145119Speter					     const u_int8_t *addr,
630145119Speter					     size_t count);
631145119Speterstatic __inline void bus_space_write_multi_2(bus_space_tag_t tag,
632145119Speter					     bus_space_handle_t bsh,
633145119Speter					     bus_size_t offset,
634145119Speter					     const u_int16_t *addr,
635145119Speter					     size_t count);
636145119Speter
637145119Speterstatic __inline void bus_space_write_multi_4(bus_space_tag_t tag,
638145119Speter					     bus_space_handle_t bsh,
639145119Speter					     bus_size_t offset,
640145119Speter					     const u_int32_t *addr,
641145119Speter					     size_t count);
642145119Speter
643145119Speterstatic __inline void
644145119Speterbus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
645145119Speter			bus_size_t offset, const u_int8_t *addr, size_t count)
646145119Speter{
647145119Speter#if defined(_AMD64_BUS_PIO_H_)
648145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
649145119Speter	if (tag == AMD64_BUS_SPACE_IO)
650145119Speter#endif
651145119Speter		outsb(bsh + offset, addr, count);
652145119Speter#endif
653145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
654145119Speter#if defined(_AMD64_BUS_PIO_H_)
655145119Speter	else
656145119Speter#endif
657145119Speter	{
658145119Speter#ifdef __GNUCLIKE_ASM
659145119Speter		__asm __volatile("				\n\
660145119Speter			cld					\n\
661145119Speter		1:	lodsb					\n\
662145119Speter			movb %%al,(%2)				\n\
663145119Speter			loop 1b"				:
664145119Speter		    "=S" (addr), "=c" (count)			:
665145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
666145119Speter		    "%eax", "memory", "cc");
667145119Speter#endif
668145119Speter	}
669145119Speter#endif
670145119Speter}
671145119Speter
672145119Speterstatic __inline void
673145119Speterbus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
674145119Speter			bus_size_t offset, const u_int16_t *addr, size_t count)
675145119Speter{
676145119Speter#if defined(_AMD64_BUS_PIO_H_)
677145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
678145119Speter	if (tag == AMD64_BUS_SPACE_IO)
679145119Speter#endif
680145119Speter		outsw(bsh + offset, addr, count);
681145119Speter#endif
682145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
683145119Speter#if defined(_AMD64_BUS_PIO_H_)
684145119Speter	else
685145119Speter#endif
686145119Speter	{
687145119Speter#ifdef __GNUCLIKE_ASM
688145119Speter		__asm __volatile("				\n\
689145119Speter			cld					\n\
690145119Speter		1:	lodsw					\n\
691145119Speter			movw %%ax,(%2)				\n\
692145119Speter			loop 1b"				:
693145119Speter		    "=S" (addr), "=c" (count)			:
694145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
695145119Speter		    "%eax", "memory", "cc");
696145119Speter#endif
697145119Speter	}
698145119Speter#endif
699145119Speter}
700145119Speter
701145119Speterstatic __inline void
702145119Speterbus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
703145119Speter			bus_size_t offset, const u_int32_t *addr, size_t count)
704145119Speter{
705145119Speter#if defined(_AMD64_BUS_PIO_H_)
706145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
707145119Speter	if (tag == AMD64_BUS_SPACE_IO)
708145119Speter#endif
709145119Speter		outsl(bsh + offset, addr, count);
710145119Speter#endif
711145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
712145119Speter#if defined(_AMD64_BUS_PIO_H_)
713145119Speter	else
714145119Speter#endif
715145119Speter	{
716145119Speter#ifdef __GNUCLIKE_ASM
717145119Speter		__asm __volatile("				\n\
718145119Speter			cld					\n\
719145119Speter		1:	lodsl					\n\
720145119Speter			movl %%eax,(%2)				\n\
721145119Speter			loop 1b"				:
722145119Speter		    "=S" (addr), "=c" (count)			:
723145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
724145119Speter		    "%eax", "memory", "cc");
725145119Speter#endif
726145119Speter	}
727145119Speter#endif
728145119Speter}
729145119Speter
730145119Speter#if 0	/* Cause a link error for bus_space_write_multi_8 */
731145119Speter#define	bus_space_write_multi_8(t, h, o, a, c)				\
732145119Speter			!!! bus_space_write_multi_8 unimplemented !!!
733145119Speter#endif
734145119Speter
735145119Speter/*
736145119Speter * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
737145119Speter * to bus space described by tag/handle starting at `offset'.
738145119Speter */
739145119Speter
740145119Speterstatic __inline void bus_space_write_region_1(bus_space_tag_t tag,
741145119Speter					      bus_space_handle_t bsh,
742145119Speter					      bus_size_t offset,
743145119Speter					      const u_int8_t *addr,
744145119Speter					      size_t count);
745145119Speterstatic __inline void bus_space_write_region_2(bus_space_tag_t tag,
746145119Speter					      bus_space_handle_t bsh,
747145119Speter					      bus_size_t offset,
748145119Speter					      const u_int16_t *addr,
749145119Speter					      size_t count);
750145119Speterstatic __inline void bus_space_write_region_4(bus_space_tag_t tag,
751145119Speter					      bus_space_handle_t bsh,
752145119Speter					      bus_size_t offset,
753145119Speter					      const u_int32_t *addr,
754145119Speter					      size_t count);
755145119Speter
756145119Speterstatic __inline void
757145119Speterbus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
758145119Speter			 bus_size_t offset, const u_int8_t *addr, size_t count)
759145119Speter{
760145119Speter#if defined(_AMD64_BUS_PIO_H_)
761145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
762145119Speter	if (tag == AMD64_BUS_SPACE_IO)
763145119Speter#endif
764145119Speter	{
765145119Speter		int _port_ = bsh + offset;
766145119Speter#ifdef __GNUCLIKE_ASM
767145119Speter		__asm __volatile("				\n\
768145119Speter			cld					\n\
769145119Speter		1:	lodsb					\n\
770145119Speter			outb %%al,%w0				\n\
771145119Speter			incl %0					\n\
772145119Speter			loop 1b"				:
773145119Speter		    "=d" (_port_), "=S" (addr), "=c" (count)	:
774145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
775145119Speter		    "%eax", "memory", "cc");
776145119Speter#endif
777145119Speter	}
778145119Speter#endif
779145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
780145119Speter#if defined(_AMD64_BUS_PIO_H_)
781145119Speter	else
782145119Speter#endif
783145119Speter	{
784145119Speter		bus_space_handle_t _port_ = bsh + offset;
785145119Speter#ifdef __GNUCLIKE_ASM
786145119Speter		__asm __volatile("				\n\
787145119Speter			cld					\n\
788145119Speter			repne					\n\
789145119Speter			movsb"					:
790145119Speter		    "=D" (_port_), "=S" (addr), "=c" (count)	:
791145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
792145119Speter		    "memory", "cc");
793145119Speter#endif
794145119Speter	}
795145119Speter#endif
796145119Speter}
797145119Speter
798145119Speterstatic __inline void
799145119Speterbus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
800145119Speter			 bus_size_t offset, const u_int16_t *addr, size_t count)
801145119Speter{
802145119Speter#if defined(_AMD64_BUS_PIO_H_)
803145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
804145119Speter	if (tag == AMD64_BUS_SPACE_IO)
805145119Speter#endif
806145119Speter	{
807145119Speter		int _port_ = bsh + offset;
808145119Speter#ifdef __GNUCLIKE_ASM
809145119Speter		__asm __volatile("				\n\
810145119Speter			cld					\n\
811145119Speter		1:	lodsw					\n\
812145119Speter			outw %%ax,%w0				\n\
813145119Speter			addl $2,%0				\n\
814145119Speter			loop 1b"				:
815145119Speter		    "=d" (_port_), "=S" (addr), "=c" (count)	:
816145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
817145119Speter		    "%eax", "memory", "cc");
818145119Speter#endif
819145119Speter	}
820145119Speter#endif
821145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
822145119Speter#if defined(_AMD64_BUS_PIO_H_)
823145119Speter	else
824145119Speter#endif
825145119Speter	{
826145119Speter		bus_space_handle_t _port_ = bsh + offset;
827145119Speter#ifdef __GNUCLIKE_ASM
828145119Speter		__asm __volatile("				\n\
829145119Speter			cld					\n\
830145119Speter			repne					\n\
831145119Speter			movsw"					:
832145119Speter		    "=D" (_port_), "=S" (addr), "=c" (count)	:
833145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
834145119Speter		    "memory", "cc");
835145119Speter#endif
836145119Speter	}
837145119Speter#endif
838145119Speter}
839145119Speter
840145119Speterstatic __inline void
841145119Speterbus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
842145119Speter			 bus_size_t offset, const u_int32_t *addr, size_t count)
843145119Speter{
844145119Speter#if defined(_AMD64_BUS_PIO_H_)
845145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
846145119Speter	if (tag == AMD64_BUS_SPACE_IO)
847145119Speter#endif
848145119Speter	{
849145119Speter		int _port_ = bsh + offset;
850145119Speter#ifdef __GNUCLIKE_ASM
851145119Speter		__asm __volatile("				\n\
852145119Speter			cld					\n\
853145119Speter		1:	lodsl					\n\
854145119Speter			outl %%eax,%w0				\n\
855145119Speter			addl $4,%0				\n\
856145119Speter			loop 1b"				:
857145119Speter		    "=d" (_port_), "=S" (addr), "=c" (count)	:
858145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
859145119Speter		    "%eax", "memory", "cc");
860145119Speter#endif
861145119Speter	}
862145119Speter#endif
863145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
864145119Speter#if defined(_AMD64_BUS_PIO_H_)
865145119Speter	else
866145119Speter#endif
867145119Speter	{
868145119Speter		bus_space_handle_t _port_ = bsh + offset;
869145119Speter#ifdef __GNUCLIKE_ASM
870145119Speter		__asm __volatile("				\n\
871145119Speter			cld					\n\
872145119Speter			repne					\n\
873145119Speter			movsl"					:
874145119Speter		    "=D" (_port_), "=S" (addr), "=c" (count)	:
875145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
876145119Speter		    "memory", "cc");
877145119Speter#endif
878145119Speter	}
879145119Speter#endif
880145119Speter}
881145119Speter
882145119Speter#if 0	/* Cause a link error for bus_space_write_region_8 */
883145119Speter#define	bus_space_write_region_8					\
884145119Speter			!!! bus_space_write_region_8 unimplemented !!!
885145119Speter#endif
886145119Speter
887145119Speter/*
888145119Speter * Write the 1, 2, 4, or 8 byte value `val' to bus space described
889145119Speter * by tag/handle/offset `count' times.
890145119Speter */
891145119Speter
892145119Speterstatic __inline void bus_space_set_multi_1(bus_space_tag_t tag,
893145119Speter					   bus_space_handle_t bsh,
894145119Speter					   bus_size_t offset,
895145119Speter					   u_int8_t value, size_t count);
896145119Speterstatic __inline void bus_space_set_multi_2(bus_space_tag_t tag,
897145119Speter					   bus_space_handle_t bsh,
898145119Speter					   bus_size_t offset,
899145119Speter					   u_int16_t value, size_t count);
900145119Speterstatic __inline void bus_space_set_multi_4(bus_space_tag_t tag,
901145119Speter					   bus_space_handle_t bsh,
902145119Speter					   bus_size_t offset,
903145119Speter					   u_int32_t value, size_t count);
904145119Speter
905145119Speterstatic __inline void
906145119Speterbus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
907145119Speter		      bus_size_t offset, u_int8_t value, size_t count)
908145119Speter{
909145119Speter	bus_space_handle_t addr = bsh + offset;
910145119Speter
911145119Speter#if defined(_AMD64_BUS_PIO_H_)
912145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
913145119Speter	if (tag == AMD64_BUS_SPACE_IO)
914145119Speter#endif
915145119Speter		while (count--)
916145119Speter			outb(addr, value);
917145119Speter#endif
918145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
919145119Speter#if defined(_AMD64_BUS_PIO_H_)
920145119Speter	else
921145119Speter#endif
922145119Speter		while (count--)
923145119Speter			*(volatile u_int8_t *)(addr) = value;
924145119Speter#endif
925145119Speter}
926145119Speter
927145119Speterstatic __inline void
928145119Speterbus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
929145119Speter		     bus_size_t offset, u_int16_t value, size_t count)
930145119Speter{
931145119Speter	bus_space_handle_t addr = bsh + offset;
932145119Speter
933145119Speter#if defined(_AMD64_BUS_PIO_H_)
934145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
935145119Speter	if (tag == AMD64_BUS_SPACE_IO)
936145119Speter#endif
937145119Speter		while (count--)
938145119Speter			outw(addr, value);
939145119Speter#endif
940145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
941145119Speter#if defined(_AMD64_BUS_PIO_H_)
942145119Speter	else
943145119Speter#endif
944145119Speter		while (count--)
945145119Speter			*(volatile u_int16_t *)(addr) = value;
946145119Speter#endif
947145119Speter}
948145119Speter
949145119Speterstatic __inline void
950145119Speterbus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
951145119Speter		      bus_size_t offset, u_int32_t value, size_t count)
952145119Speter{
953145119Speter	bus_space_handle_t addr = bsh + offset;
954145119Speter
955145119Speter#if defined(_AMD64_BUS_PIO_H_)
956145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
957145119Speter	if (tag == AMD64_BUS_SPACE_IO)
958145119Speter#endif
959145119Speter		while (count--)
960145119Speter			outl(addr, value);
961145119Speter#endif
962145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
963145119Speter#if defined(_AMD64_BUS_PIO_H_)
964145119Speter	else
965145119Speter#endif
966145119Speter		while (count--)
967145119Speter			*(volatile u_int32_t *)(addr) = value;
968145119Speter#endif
969145119Speter}
970145119Speter
971145119Speter#if 0	/* Cause a link error for bus_space_set_multi_8 */
972145119Speter#define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
973145119Speter#endif
974145119Speter
975145119Speter/*
976145119Speter * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
977145119Speter * by tag/handle starting at `offset'.
978145119Speter */
979145119Speter
980145119Speterstatic __inline void bus_space_set_region_1(bus_space_tag_t tag,
981145119Speter					    bus_space_handle_t bsh,
982145119Speter					    bus_size_t offset, u_int8_t value,
983145119Speter					    size_t count);
984145119Speterstatic __inline void bus_space_set_region_2(bus_space_tag_t tag,
985145119Speter					    bus_space_handle_t bsh,
986145119Speter					    bus_size_t offset, u_int16_t value,
987145119Speter					    size_t count);
988145119Speterstatic __inline void bus_space_set_region_4(bus_space_tag_t tag,
989145119Speter					    bus_space_handle_t bsh,
990145119Speter					    bus_size_t offset, u_int32_t value,
991145119Speter					    size_t count);
992145119Speter
993145119Speterstatic __inline void
994145119Speterbus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
995145119Speter		       bus_size_t offset, u_int8_t value, size_t count)
996145119Speter{
997145119Speter	bus_space_handle_t addr = bsh + offset;
998145119Speter
999145119Speter#if defined(_AMD64_BUS_PIO_H_)
1000145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
1001145119Speter	if (tag == AMD64_BUS_SPACE_IO)
1002145119Speter#endif
1003145119Speter		for (; count != 0; count--, addr++)
1004145119Speter			outb(addr, value);
1005145119Speter#endif
1006145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
1007145119Speter#if defined(_AMD64_BUS_PIO_H_)
1008145119Speter	else
1009145119Speter#endif
1010145119Speter		for (; count != 0; count--, addr++)
1011145119Speter			*(volatile u_int8_t *)(addr) = value;
1012145119Speter#endif
1013145119Speter}
1014145119Speter
1015145119Speterstatic __inline void
1016145119Speterbus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
1017145119Speter		       bus_size_t offset, u_int16_t value, size_t count)
1018145119Speter{
1019145119Speter	bus_space_handle_t addr = bsh + offset;
1020145119Speter
1021145119Speter#if defined(_AMD64_BUS_PIO_H_)
1022145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
1023145119Speter	if (tag == AMD64_BUS_SPACE_IO)
1024145119Speter#endif
1025145119Speter		for (; count != 0; count--, addr += 2)
1026145119Speter			outw(addr, value);
1027145119Speter#endif
1028145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
1029145119Speter#if defined(_AMD64_BUS_PIO_H_)
1030145119Speter	else
1031145119Speter#endif
1032145119Speter		for (; count != 0; count--, addr += 2)
1033145119Speter			*(volatile u_int16_t *)(addr) = value;
1034145119Speter#endif
1035145119Speter}
1036145119Speter
1037145119Speterstatic __inline void
1038145119Speterbus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
1039145119Speter		       bus_size_t offset, u_int32_t value, size_t count)
1040145119Speter{
1041145119Speter	bus_space_handle_t addr = bsh + offset;
1042145119Speter
1043145119Speter#if defined(_AMD64_BUS_PIO_H_)
1044145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
1045145119Speter	if (tag == AMD64_BUS_SPACE_IO)
1046145119Speter#endif
1047145119Speter		for (; count != 0; count--, addr += 4)
1048145119Speter			outl(addr, value);
1049145119Speter#endif
1050145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
1051145119Speter#if defined(_AMD64_BUS_PIO_H_)
1052145119Speter	else
1053145119Speter#endif
1054145119Speter		for (; count != 0; count--, addr += 4)
1055145119Speter			*(volatile u_int32_t *)(addr) = value;
1056145119Speter#endif
1057145119Speter}
1058145119Speter
1059145119Speter#if 0	/* Cause a link error for bus_space_set_region_8 */
1060145119Speter#define	bus_space_set_region_8	!!! bus_space_set_region_8 unimplemented !!!
1061145119Speter#endif
1062145119Speter
1063145119Speter/*
1064145119Speter * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
1065145119Speter * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
1066145119Speter */
1067145119Speter
1068145119Speterstatic __inline void bus_space_copy_region_1(bus_space_tag_t tag,
1069145119Speter					     bus_space_handle_t bsh1,
1070145119Speter					     bus_size_t off1,
1071145119Speter					     bus_space_handle_t bsh2,
1072145119Speter					     bus_size_t off2, size_t count);
1073145119Speter
1074145119Speterstatic __inline void bus_space_copy_region_2(bus_space_tag_t tag,
1075145119Speter					     bus_space_handle_t bsh1,
1076145119Speter					     bus_size_t off1,
1077145119Speter					     bus_space_handle_t bsh2,
1078145119Speter					     bus_size_t off2, size_t count);
1079145119Speter
1080145119Speterstatic __inline void bus_space_copy_region_4(bus_space_tag_t tag,
1081145119Speter					     bus_space_handle_t bsh1,
1082145119Speter					     bus_size_t off1,
1083145119Speter					     bus_space_handle_t bsh2,
1084145119Speter					     bus_size_t off2, size_t count);
1085145119Speter
1086145119Speterstatic __inline void
1087145119Speterbus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
1088145119Speter			bus_size_t off1, bus_space_handle_t bsh2,
1089145119Speter			bus_size_t off2, size_t count)
1090145119Speter{
1091145119Speter	bus_space_handle_t addr1 = bsh1 + off1;
1092145119Speter	bus_space_handle_t addr2 = bsh2 + off2;
1093145119Speter
1094145119Speter#if defined(_AMD64_BUS_PIO_H_)
1095145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
1096145119Speter	if (tag == AMD64_BUS_SPACE_IO)
1097145119Speter#endif
1098145119Speter	{
1099145119Speter		if (addr1 >= addr2) {
1100145119Speter			/* src after dest: copy forward */
1101145119Speter			for (; count != 0; count--, addr1++, addr2++)
1102145119Speter				outb(addr2, inb(addr1));
1103145119Speter		} else {
1104145119Speter			/* dest after src: copy backwards */
1105145119Speter			for (addr1 += (count - 1), addr2 += (count - 1);
1106145119Speter			    count != 0; count--, addr1--, addr2--)
1107145119Speter				outb(addr2, inb(addr1));
1108145119Speter		}
1109145119Speter	}
1110145119Speter#endif
1111145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
1112145119Speter#if defined(_AMD64_BUS_PIO_H_)
1113145119Speter	else
1114145119Speter#endif
1115145119Speter	{
1116145119Speter		if (addr1 >= addr2) {
1117145119Speter			/* src after dest: copy forward */
1118145119Speter			for (; count != 0; count--, addr1++, addr2++)
1119145119Speter				*(volatile u_int8_t *)(addr2) =
1120145119Speter				    *(volatile u_int8_t *)(addr1);
1121145119Speter		} else {
1122145119Speter			/* dest after src: copy backwards */
1123145119Speter			for (addr1 += (count - 1), addr2 += (count - 1);
1124145119Speter			    count != 0; count--, addr1--, addr2--)
1125145119Speter				*(volatile u_int8_t *)(addr2) =
1126145119Speter				    *(volatile u_int8_t *)(addr1);
1127145119Speter		}
1128145119Speter	}
1129145119Speter#endif
1130145119Speter}
1131145119Speter
1132145119Speterstatic __inline void
1133145119Speterbus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
1134145119Speter			bus_size_t off1, bus_space_handle_t bsh2,
1135145119Speter			bus_size_t off2, size_t count)
1136145119Speter{
1137145119Speter	bus_space_handle_t addr1 = bsh1 + off1;
1138145119Speter	bus_space_handle_t addr2 = bsh2 + off2;
1139145119Speter
1140145119Speter#if defined(_AMD64_BUS_PIO_H_)
1141145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
1142145119Speter	if (tag == AMD64_BUS_SPACE_IO)
1143145119Speter#endif
1144145119Speter	{
1145145119Speter		if (addr1 >= addr2) {
1146145119Speter			/* src after dest: copy forward */
1147145119Speter			for (; count != 0; count--, addr1 += 2, addr2 += 2)
1148145119Speter				outw(addr2, inw(addr1));
1149145119Speter		} else {
1150145119Speter			/* dest after src: copy backwards */
1151145119Speter			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
1152145119Speter			    count != 0; count--, addr1 -= 2, addr2 -= 2)
1153145119Speter				outw(addr2, inw(addr1));
1154145119Speter		}
1155145119Speter	}
1156145119Speter#endif
1157145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
1158145119Speter#if defined(_AMD64_BUS_PIO_H_)
1159145119Speter	else
1160145119Speter#endif
1161145119Speter	{
1162145119Speter		if (addr1 >= addr2) {
1163145119Speter			/* src after dest: copy forward */
1164145119Speter			for (; count != 0; count--, addr1 += 2, addr2 += 2)
1165145119Speter				*(volatile u_int16_t *)(addr2) =
1166145119Speter				    *(volatile u_int16_t *)(addr1);
1167145119Speter		} else {
1168145119Speter			/* dest after src: copy backwards */
1169145119Speter			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
1170145119Speter			    count != 0; count--, addr1 -= 2, addr2 -= 2)
1171145119Speter				*(volatile u_int16_t *)(addr2) =
1172145119Speter				    *(volatile u_int16_t *)(addr1);
1173145119Speter		}
1174145119Speter	}
1175145119Speter#endif
1176145119Speter}
1177145119Speter
1178145119Speterstatic __inline void
1179145119Speterbus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
1180145119Speter			bus_size_t off1, bus_space_handle_t bsh2,
1181145119Speter			bus_size_t off2, size_t count)
1182145119Speter{
1183145119Speter	bus_space_handle_t addr1 = bsh1 + off1;
1184145119Speter	bus_space_handle_t addr2 = bsh2 + off2;
1185145119Speter
1186145119Speter#if defined(_AMD64_BUS_PIO_H_)
1187145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
1188145119Speter	if (tag == AMD64_BUS_SPACE_IO)
1189145119Speter#endif
1190145119Speter	{
1191145119Speter		if (addr1 >= addr2) {
1192145119Speter			/* src after dest: copy forward */
1193145119Speter			for (; count != 0; count--, addr1 += 4, addr2 += 4)
1194145119Speter				outl(addr2, inl(addr1));
1195145119Speter		} else {
1196145119Speter			/* dest after src: copy backwards */
1197145119Speter			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1198145119Speter			    count != 0; count--, addr1 -= 4, addr2 -= 4)
1199145119Speter				outl(addr2, inl(addr1));
1200145119Speter		}
1201145119Speter	}
1202145119Speter#endif
1203145119Speter#if defined(_AMD64_BUS_MEMIO_H_)
1204145119Speter#if defined(_AMD64_BUS_PIO_H_)
1205145119Speter	else
1206145119Speter#endif
1207145119Speter	{
1208145119Speter		if (addr1 >= addr2) {
1209145119Speter			/* src after dest: copy forward */
1210145119Speter			for (; count != 0; count--, addr1 += 4, addr2 += 4)
1211145119Speter				*(volatile u_int32_t *)(addr2) =
1212145119Speter				    *(volatile u_int32_t *)(addr1);
1213145119Speter		} else {
1214145119Speter			/* dest after src: copy backwards */
1215145119Speter			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1216145119Speter			    count != 0; count--, addr1 -= 4, addr2 -= 4)
1217145119Speter				*(volatile u_int32_t *)(addr2) =
1218145119Speter				    *(volatile u_int32_t *)(addr1);
1219145119Speter		}
1220145119Speter	}
1221145119Speter#endif
1222145119Speter}
1223145119Speter
1224145119Speter#endif /* defined(_AMD64_BUS_PIO_H_) || defined(_AMD64_MEM_IO_H_) */
1225145119Speter
1226145119Speter#if 0	/* Cause a link error for bus_space_copy_8 */
1227145119Speter#define	bus_space_copy_region_8	!!! bus_space_copy_region_8 unimplemented !!!
1228145119Speter#endif
1229145119Speter
1230145119Speter/*
1231145119Speter * Bus read/write barrier methods.
1232145119Speter *
1233145119Speter *	void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
1234145119Speter *			       bus_size_t offset, bus_size_t len, int flags);
1235145119Speter *
1236145119Speter *
1237145119Speter * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
1238145119Speter * prevent reordering by the compiler; all Intel x86 processors currently
1239145119Speter * retire operations outside the CPU in program order.
1240145119Speter */
1241145119Speter#define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
1242145119Speter#define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
1243145119Speter
1244145119Speterstatic __inline void
1245145119Speterbus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
1246145119Speter		  bus_size_t offset __unused, bus_size_t len __unused, int flags)
1247145119Speter{
1248145119Speter#ifdef __GNUCLIKE_ASM
1249145119Speter	if (flags & BUS_SPACE_BARRIER_READ)
1250145119Speter		__asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory");
1251145119Speter	else
1252145119Speter		__asm __volatile("" : : : "memory");
1253145119Speter#endif
1254145119Speter}
1255145119Speter
125684593Snyan#include <machine/bus_dma.h>
125748527Simp
125891394Stmm/*
1259114930Speter * Stream accesses are the same as normal accesses on amd64; there are no
126091394Stmm * supported bus systems with an endianess different from the host one.
126191394Stmm */
126291394Stmm#define	bus_space_read_stream_1(t, h, o)	bus_space_read_1((t), (h), (o))
126391394Stmm#define	bus_space_read_stream_2(t, h, o)	bus_space_read_2((t), (h), (o))
126491394Stmm#define	bus_space_read_stream_4(t, h, o)	bus_space_read_4((t), (h), (o))
126591394Stmm
126691394Stmm#define	bus_space_read_multi_stream_1(t, h, o, a, c) \
126791394Stmm	bus_space_read_multi_1((t), (h), (o), (a), (c))
126891394Stmm#define	bus_space_read_multi_stream_2(t, h, o, a, c) \
126991394Stmm	bus_space_read_multi_2((t), (h), (o), (a), (c))
127091394Stmm#define	bus_space_read_multi_stream_4(t, h, o, a, c) \
127191394Stmm	bus_space_read_multi_4((t), (h), (o), (a), (c))
127291394Stmm
127391394Stmm#define	bus_space_write_stream_1(t, h, o, v) \
127491394Stmm	bus_space_write_1((t), (h), (o), (v))
127591394Stmm#define	bus_space_write_stream_2(t, h, o, v) \
127691394Stmm	bus_space_write_2((t), (h), (o), (v))
127791394Stmm#define	bus_space_write_stream_4(t, h, o, v) \
127891394Stmm	bus_space_write_4((t), (h), (o), (v))
127991394Stmm
128091394Stmm#define	bus_space_write_multi_stream_1(t, h, o, a, c) \
128191394Stmm	bus_space_write_multi_1((t), (h), (o), (a), (c))
128291394Stmm#define	bus_space_write_multi_stream_2(t, h, o, a, c) \
128391394Stmm	bus_space_write_multi_2((t), (h), (o), (a), (c))
128491394Stmm#define	bus_space_write_multi_stream_4(t, h, o, a, c) \
128591394Stmm	bus_space_write_multi_4((t), (h), (o), (a), (c))
128691394Stmm
128791394Stmm#define	bus_space_set_multi_stream_1(t, h, o, v, c) \
128891394Stmm	bus_space_set_multi_1((t), (h), (o), (v), (c))
128991394Stmm#define	bus_space_set_multi_stream_2(t, h, o, v, c) \
129091394Stmm	bus_space_set_multi_2((t), (h), (o), (v), (c))
129191394Stmm#define	bus_space_set_multi_stream_4(t, h, o, v, c) \
129291394Stmm	bus_space_set_multi_4((t), (h), (o), (v), (c))
129391394Stmm
129491394Stmm#define	bus_space_read_region_stream_1(t, h, o, a, c) \
129591394Stmm	bus_space_read_region_1((t), (h), (o), (a), (c))
129691394Stmm#define	bus_space_read_region_stream_2(t, h, o, a, c) \
129791394Stmm	bus_space_read_region_2((t), (h), (o), (a), (c))
129891394Stmm#define	bus_space_read_region_stream_4(t, h, o, a, c) \
129991394Stmm	bus_space_read_region_4((t), (h), (o), (a), (c))
130091394Stmm
130191394Stmm#define	bus_space_write_region_stream_1(t, h, o, a, c) \
130291394Stmm	bus_space_write_region_1((t), (h), (o), (a), (c))
130391394Stmm#define	bus_space_write_region_stream_2(t, h, o, a, c) \
130491394Stmm	bus_space_write_region_2((t), (h), (o), (a), (c))
130591394Stmm#define	bus_space_write_region_stream_4(t, h, o, a, c) \
130691394Stmm	bus_space_write_region_4((t), (h), (o), (a), (c))
130791394Stmm
130891394Stmm#define	bus_space_set_region_stream_1(t, h, o, v, c) \
130991394Stmm	bus_space_set_region_1((t), (h), (o), (v), (c))
131091394Stmm#define	bus_space_set_region_stream_2(t, h, o, v, c) \
131191394Stmm	bus_space_set_region_2((t), (h), (o), (v), (c))
131291394Stmm#define	bus_space_set_region_stream_4(t, h, o, v, c) \
131391394Stmm	bus_space_set_region_4((t), (h), (o), (v), (c))
131491394Stmm
131591394Stmm#define	bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
131691394Stmm	bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
131791394Stmm#define	bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
131891394Stmm	bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
131991394Stmm#define	bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
132091394Stmm	bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
132191394Stmm
1322114930Speter#endif /* _AMD64_BUS_H_ */
1323