bus.h revision 156699
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 156699 2006-03-14 00:01:56Z 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
107145253Simp#include <machine/_bus.h>
108145119Speter#include <machine/cpufunc.h>
109145119Speter
110145119Speter/*
111145119Speter * Values for the amd64 bus space tag, not to be used directly by MI code.
112145119Speter */
113145119Speter#define	AMD64_BUS_SPACE_IO	0	/* space is i/o space */
114145119Speter#define AMD64_BUS_SPACE_MEM	1	/* space is mem space */
115145119Speter
116145119Speter#define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
117145119Speter#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
118145119Speter#define BUS_SPACE_MAXSIZE	0xFFFFFFFF
119145119Speter#define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
120145119Speter#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
121145119Speter#define BUS_SPACE_MAXADDR	0xFFFFFFFFFFFFFFFFULL
122145119Speter
123145119Speter#define BUS_SPACE_UNRESTRICTED	(~0)
124145119Speter
125145119Speter/*
126145119Speter * Map a region of device bus space into CPU virtual address space.
127145119Speter */
128145119Speter
129145119Speterstatic __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
130145119Speter				  bus_size_t size, int flags,
131145119Speter				  bus_space_handle_t *bshp);
132145119Speter
133145119Speterstatic __inline int
134145119Speterbus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
135145119Speter	      bus_size_t size __unused, int flags __unused,
136145119Speter	      bus_space_handle_t *bshp)
137145119Speter{
138145119Speter
139145119Speter	*bshp = addr;
140145119Speter	return (0);
141145119Speter}
142145119Speter
143145119Speter/*
144145119Speter * Unmap a region of device bus space.
145145119Speter */
146145119Speter
147145119Speterstatic __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
148145119Speter				     bus_size_t size);
149145119Speter
150145119Speterstatic __inline void
151145119Speterbus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
152145119Speter		bus_size_t size __unused)
153145119Speter{
154145119Speter}
155145119Speter
156145119Speter/*
157145119Speter * Get a new handle for a subregion of an already-mapped area of bus space.
158145119Speter */
159145119Speter
160145119Speterstatic __inline int bus_space_subregion(bus_space_tag_t t,
161145119Speter					bus_space_handle_t bsh,
162145119Speter					bus_size_t offset, bus_size_t size,
163145119Speter					bus_space_handle_t *nbshp);
164145119Speter
165145119Speterstatic __inline int
166145119Speterbus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
167145119Speter		    bus_size_t offset, bus_size_t size __unused,
168145119Speter		    bus_space_handle_t *nbshp)
169145119Speter{
170145119Speter
171145119Speter	*nbshp = bsh + offset;
172145119Speter	return (0);
173145119Speter}
174145119Speter
175145119Speter/*
176145119Speter * Allocate a region of memory that is accessible to devices in bus space.
177145119Speter */
178145119Speter
179145119Speterint	bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
180145119Speter			bus_addr_t rend, bus_size_t size, bus_size_t align,
181145119Speter			bus_size_t boundary, int flags, bus_addr_t *addrp,
182145119Speter			bus_space_handle_t *bshp);
183145119Speter
184145119Speter/*
185145119Speter * Free a region of bus space accessible memory.
186145119Speter */
187145119Speter
188145119Speterstatic __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
189145119Speter				    bus_size_t size);
190145119Speter
191145119Speterstatic __inline void
192145119Speterbus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
193145119Speter	       bus_size_t size __unused)
194145119Speter{
195145119Speter}
196145119Speter
197145119Speter
198145119Speter/*
199145119Speter * Read a 1, 2, 4, or 8 byte quantity from bus space
200145119Speter * described by tag/handle/offset.
201145119Speter */
202145119Speterstatic __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
203145119Speter					  bus_space_handle_t handle,
204145119Speter					  bus_size_t offset);
205145119Speter
206145119Speterstatic __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
207145119Speter					   bus_space_handle_t handle,
208145119Speter					   bus_size_t offset);
209145119Speter
210145119Speterstatic __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
211145119Speter					   bus_space_handle_t handle,
212145119Speter					   bus_size_t offset);
213145119Speter
214145119Speterstatic __inline u_int8_t
215145119Speterbus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
216145119Speter		 bus_size_t offset)
217145119Speter{
218146734Snyan
219145119Speter	if (tag == AMD64_BUS_SPACE_IO)
220145119Speter		return (inb(handle + offset));
221145119Speter	return (*(volatile u_int8_t *)(handle + offset));
222145119Speter}
223145119Speter
224145119Speterstatic __inline u_int16_t
225145119Speterbus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
226145119Speter		 bus_size_t offset)
227145119Speter{
228146734Snyan
229145119Speter	if (tag == AMD64_BUS_SPACE_IO)
230145119Speter		return (inw(handle + offset));
231145119Speter	return (*(volatile u_int16_t *)(handle + offset));
232145119Speter}
233145119Speter
234145119Speterstatic __inline u_int32_t
235145119Speterbus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
236145119Speter		 bus_size_t offset)
237145119Speter{
238146734Snyan
239145119Speter	if (tag == AMD64_BUS_SPACE_IO)
240145119Speter		return (inl(handle + offset));
241145119Speter	return (*(volatile u_int32_t *)(handle + offset));
242145119Speter}
243145119Speter
244145119Speter#if 0	/* Cause a link error for bus_space_read_8 */
245145119Speter#define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
246145119Speter#endif
247145119Speter
248145119Speter/*
249145119Speter * Read `count' 1, 2, 4, or 8 byte quantities from bus space
250145119Speter * described by tag/handle/offset and copy into buffer provided.
251145119Speter */
252145119Speterstatic __inline void bus_space_read_multi_1(bus_space_tag_t tag,
253145119Speter					    bus_space_handle_t bsh,
254145119Speter					    bus_size_t offset, u_int8_t *addr,
255145119Speter					    size_t count);
256145119Speter
257145119Speterstatic __inline void bus_space_read_multi_2(bus_space_tag_t tag,
258145119Speter					    bus_space_handle_t bsh,
259145119Speter					    bus_size_t offset, u_int16_t *addr,
260145119Speter					    size_t count);
261145119Speter
262145119Speterstatic __inline void bus_space_read_multi_4(bus_space_tag_t tag,
263145119Speter					    bus_space_handle_t bsh,
264145119Speter					    bus_size_t offset, u_int32_t *addr,
265145119Speter					    size_t count);
266145119Speter
267145119Speterstatic __inline void
268145119Speterbus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
269145119Speter		       bus_size_t offset, u_int8_t *addr, size_t count)
270145119Speter{
271146734Snyan
272145119Speter	if (tag == AMD64_BUS_SPACE_IO)
273145119Speter		insb(bsh + offset, addr, count);
274146734Snyan	else {
275145119Speter#ifdef __GNUCLIKE_ASM
276145119Speter		__asm __volatile("				\n\
277145119Speter			cld					\n\
278145119Speter		1:	movb (%2),%%al				\n\
279145119Speter			stosb					\n\
280145119Speter			loop 1b"				:
281145119Speter		    "=D" (addr), "=c" (count)			:
282145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
283145119Speter		    "%eax", "memory");
284145119Speter#endif
285145119Speter	}
286145119Speter}
287145119Speter
288145119Speterstatic __inline void
289145119Speterbus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
290145119Speter		       bus_size_t offset, u_int16_t *addr, size_t count)
291145119Speter{
292146734Snyan
293145119Speter	if (tag == AMD64_BUS_SPACE_IO)
294145119Speter		insw(bsh + offset, addr, count);
295146734Snyan	else {
296145119Speter#ifdef __GNUCLIKE_ASM
297145119Speter		__asm __volatile("				\n\
298145119Speter			cld					\n\
299145119Speter		1:	movw (%2),%%ax				\n\
300145119Speter			stosw					\n\
301145119Speter			loop 1b"				:
302145119Speter		    "=D" (addr), "=c" (count)			:
303145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
304145119Speter		    "%eax", "memory");
305145119Speter#endif
306145119Speter	}
307145119Speter}
308145119Speter
309145119Speterstatic __inline void
310145119Speterbus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
311145119Speter		       bus_size_t offset, u_int32_t *addr, size_t count)
312145119Speter{
313146734Snyan
314145119Speter	if (tag == AMD64_BUS_SPACE_IO)
315145119Speter		insl(bsh + offset, addr, count);
316146734Snyan	else {
317145119Speter#ifdef __GNUCLIKE_ASM
318145119Speter		__asm __volatile("				\n\
319145119Speter			cld					\n\
320145119Speter		1:	movl (%2),%%eax				\n\
321145119Speter			stosl					\n\
322145119Speter			loop 1b"				:
323145119Speter		    "=D" (addr), "=c" (count)			:
324145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
325145119Speter		    "%eax", "memory");
326145119Speter#endif
327145119Speter	}
328145119Speter}
329145119Speter
330145119Speter#if 0	/* Cause a link error for bus_space_read_multi_8 */
331145119Speter#define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
332145119Speter#endif
333145119Speter
334145119Speter/*
335145119Speter * Read `count' 1, 2, 4, or 8 byte quantities from bus space
336145119Speter * described by tag/handle and starting at `offset' and copy into
337145119Speter * buffer provided.
338145119Speter */
339145119Speterstatic __inline void bus_space_read_region_1(bus_space_tag_t tag,
340145119Speter					     bus_space_handle_t bsh,
341145119Speter					     bus_size_t offset, u_int8_t *addr,
342145119Speter					     size_t count);
343145119Speter
344145119Speterstatic __inline void bus_space_read_region_2(bus_space_tag_t tag,
345145119Speter					     bus_space_handle_t bsh,
346145119Speter					     bus_size_t offset, u_int16_t *addr,
347145119Speter					     size_t count);
348145119Speter
349145119Speterstatic __inline void bus_space_read_region_4(bus_space_tag_t tag,
350145119Speter					     bus_space_handle_t bsh,
351145119Speter					     bus_size_t offset, u_int32_t *addr,
352145119Speter					     size_t count);
353145119Speter
354145119Speter
355145119Speterstatic __inline void
356145119Speterbus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
357145119Speter			bus_size_t offset, u_int8_t *addr, size_t count)
358145119Speter{
359146734Snyan
360146734Snyan	if (tag == AMD64_BUS_SPACE_IO) {
361145119Speter		int _port_ = bsh + offset;
362145119Speter#ifdef __GNUCLIKE_ASM
363145119Speter		__asm __volatile("				\n\
364145119Speter			cld					\n\
365145119Speter		1:	inb %w2,%%al				\n\
366145119Speter			stosb					\n\
367145119Speter			incl %2					\n\
368145119Speter			loop 1b"				:
369145119Speter		    "=D" (addr), "=c" (count), "=d" (_port_)	:
370145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
371145119Speter		    "%eax", "memory", "cc");
372145119Speter#endif
373146734Snyan	} else {
374145119Speter		bus_space_handle_t _port_ = bsh + offset;
375145119Speter#ifdef __GNUCLIKE_ASM
376145119Speter		__asm __volatile("				\n\
377145119Speter			cld					\n\
378145119Speter			repne					\n\
379145119Speter			movsb"					:
380145119Speter		    "=D" (addr), "=c" (count), "=S" (_port_)	:
381145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
382145119Speter		    "memory", "cc");
383145119Speter#endif
384145119Speter	}
385145119Speter}
386145119Speter
387145119Speterstatic __inline void
388145119Speterbus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
389145119Speter			bus_size_t offset, u_int16_t *addr, size_t count)
390145119Speter{
391146734Snyan
392146734Snyan	if (tag == AMD64_BUS_SPACE_IO) {
393145119Speter		int _port_ = bsh + offset;
394145119Speter#ifdef __GNUCLIKE_ASM
395145119Speter		__asm __volatile("				\n\
396145119Speter			cld					\n\
397145119Speter		1:	inw %w2,%%ax				\n\
398145119Speter			stosw					\n\
399145119Speter			addl $2,%2				\n\
400145119Speter			loop 1b"				:
401145119Speter		    "=D" (addr), "=c" (count), "=d" (_port_)	:
402145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
403145119Speter		    "%eax", "memory", "cc");
404145119Speter#endif
405146734Snyan	} else {
406145119Speter		bus_space_handle_t _port_ = bsh + offset;
407145119Speter#ifdef __GNUCLIKE_ASM
408145119Speter		__asm __volatile("				\n\
409145119Speter			cld					\n\
410145119Speter			repne					\n\
411145119Speter			movsw"					:
412145119Speter		    "=D" (addr), "=c" (count), "=S" (_port_)	:
413145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
414145119Speter		    "memory", "cc");
415145119Speter#endif
416145119Speter	}
417145119Speter}
418145119Speter
419145119Speterstatic __inline void
420145119Speterbus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
421145119Speter			bus_size_t offset, u_int32_t *addr, size_t count)
422145119Speter{
423146734Snyan
424146734Snyan	if (tag == AMD64_BUS_SPACE_IO) {
425145119Speter		int _port_ = bsh + offset;
426145119Speter#ifdef __GNUCLIKE_ASM
427145119Speter		__asm __volatile("				\n\
428145119Speter			cld					\n\
429145119Speter		1:	inl %w2,%%eax				\n\
430145119Speter			stosl					\n\
431145119Speter			addl $4,%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
437146734Snyan	} else {
438145119Speter		bus_space_handle_t _port_ = bsh + offset;
439145119Speter#ifdef __GNUCLIKE_ASM
440145119Speter		__asm __volatile("				\n\
441145119Speter			cld					\n\
442145119Speter			repne					\n\
443145119Speter			movsl"					:
444145119Speter		    "=D" (addr), "=c" (count), "=S" (_port_)	:
445145119Speter		    "0" (addr), "1" (count), "2" (_port_)	:
446145119Speter		    "memory", "cc");
447145119Speter#endif
448145119Speter	}
449145119Speter}
450145119Speter
451145119Speter#if 0	/* Cause a link error for bus_space_read_region_8 */
452145119Speter#define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
453145119Speter#endif
454145119Speter
455145119Speter/*
456145119Speter * Write the 1, 2, 4, or 8 byte value `value' to bus space
457145119Speter * described by tag/handle/offset.
458145119Speter */
459145119Speter
460145119Speterstatic __inline void bus_space_write_1(bus_space_tag_t tag,
461145119Speter				       bus_space_handle_t bsh,
462145119Speter				       bus_size_t offset, u_int8_t value);
463145119Speter
464145119Speterstatic __inline void bus_space_write_2(bus_space_tag_t tag,
465145119Speter				       bus_space_handle_t bsh,
466145119Speter				       bus_size_t offset, u_int16_t value);
467145119Speter
468145119Speterstatic __inline void bus_space_write_4(bus_space_tag_t tag,
469145119Speter				       bus_space_handle_t bsh,
470145119Speter				       bus_size_t offset, u_int32_t value);
471145119Speter
472145119Speterstatic __inline void
473145119Speterbus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
474145119Speter		       bus_size_t offset, u_int8_t value)
475145119Speter{
476146734Snyan
477145119Speter	if (tag == AMD64_BUS_SPACE_IO)
478145119Speter		outb(bsh + offset, value);
479145119Speter	else
480145119Speter		*(volatile u_int8_t *)(bsh + offset) = value;
481145119Speter}
482145119Speter
483145119Speterstatic __inline void
484145119Speterbus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
485145119Speter		       bus_size_t offset, u_int16_t value)
486145119Speter{
487146734Snyan
488145119Speter	if (tag == AMD64_BUS_SPACE_IO)
489145119Speter		outw(bsh + offset, value);
490145119Speter	else
491145119Speter		*(volatile u_int16_t *)(bsh + offset) = value;
492145119Speter}
493145119Speter
494145119Speterstatic __inline void
495145119Speterbus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
496145119Speter		       bus_size_t offset, u_int32_t value)
497145119Speter{
498146734Snyan
499145119Speter	if (tag == AMD64_BUS_SPACE_IO)
500145119Speter		outl(bsh + offset, value);
501145119Speter	else
502145119Speter		*(volatile u_int32_t *)(bsh + offset) = value;
503145119Speter}
504145119Speter
505145119Speter#if 0	/* Cause a link error for bus_space_write_8 */
506145119Speter#define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
507145119Speter#endif
508145119Speter
509145119Speter/*
510145119Speter * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
511145119Speter * provided to bus space described by tag/handle/offset.
512145119Speter */
513145119Speter
514145119Speterstatic __inline void bus_space_write_multi_1(bus_space_tag_t tag,
515145119Speter					     bus_space_handle_t bsh,
516145119Speter					     bus_size_t offset,
517145119Speter					     const u_int8_t *addr,
518145119Speter					     size_t count);
519145119Speterstatic __inline void bus_space_write_multi_2(bus_space_tag_t tag,
520145119Speter					     bus_space_handle_t bsh,
521145119Speter					     bus_size_t offset,
522145119Speter					     const u_int16_t *addr,
523145119Speter					     size_t count);
524145119Speter
525145119Speterstatic __inline void bus_space_write_multi_4(bus_space_tag_t tag,
526145119Speter					     bus_space_handle_t bsh,
527145119Speter					     bus_size_t offset,
528145119Speter					     const u_int32_t *addr,
529145119Speter					     size_t count);
530145119Speter
531145119Speterstatic __inline void
532145119Speterbus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
533145119Speter			bus_size_t offset, const u_int8_t *addr, size_t count)
534145119Speter{
535146734Snyan
536145119Speter	if (tag == AMD64_BUS_SPACE_IO)
537145119Speter		outsb(bsh + offset, addr, count);
538146734Snyan	else {
539145119Speter#ifdef __GNUCLIKE_ASM
540145119Speter		__asm __volatile("				\n\
541145119Speter			cld					\n\
542145119Speter		1:	lodsb					\n\
543145119Speter			movb %%al,(%2)				\n\
544145119Speter			loop 1b"				:
545145119Speter		    "=S" (addr), "=c" (count)			:
546145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
547145119Speter		    "%eax", "memory", "cc");
548145119Speter#endif
549145119Speter	}
550145119Speter}
551145119Speter
552145119Speterstatic __inline void
553145119Speterbus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
554145119Speter			bus_size_t offset, const u_int16_t *addr, size_t count)
555145119Speter{
556146734Snyan
557145119Speter	if (tag == AMD64_BUS_SPACE_IO)
558145119Speter		outsw(bsh + offset, addr, count);
559146734Snyan	else {
560145119Speter#ifdef __GNUCLIKE_ASM
561145119Speter		__asm __volatile("				\n\
562145119Speter			cld					\n\
563145119Speter		1:	lodsw					\n\
564145119Speter			movw %%ax,(%2)				\n\
565145119Speter			loop 1b"				:
566145119Speter		    "=S" (addr), "=c" (count)			:
567145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
568145119Speter		    "%eax", "memory", "cc");
569145119Speter#endif
570145119Speter	}
571145119Speter}
572145119Speter
573145119Speterstatic __inline void
574145119Speterbus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
575145119Speter			bus_size_t offset, const u_int32_t *addr, size_t count)
576145119Speter{
577146734Snyan
578145119Speter	if (tag == AMD64_BUS_SPACE_IO)
579145119Speter		outsl(bsh + offset, addr, count);
580146734Snyan	else {
581145119Speter#ifdef __GNUCLIKE_ASM
582145119Speter		__asm __volatile("				\n\
583145119Speter			cld					\n\
584145119Speter		1:	lodsl					\n\
585145119Speter			movl %%eax,(%2)				\n\
586145119Speter			loop 1b"				:
587145119Speter		    "=S" (addr), "=c" (count)			:
588145119Speter		    "r" (bsh + offset), "0" (addr), "1" (count)	:
589145119Speter		    "%eax", "memory", "cc");
590145119Speter#endif
591145119Speter	}
592145119Speter}
593145119Speter
594145119Speter#if 0	/* Cause a link error for bus_space_write_multi_8 */
595145119Speter#define	bus_space_write_multi_8(t, h, o, a, c)				\
596145119Speter			!!! bus_space_write_multi_8 unimplemented !!!
597145119Speter#endif
598145119Speter
599145119Speter/*
600145119Speter * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
601145119Speter * to bus space described by tag/handle starting at `offset'.
602145119Speter */
603145119Speter
604145119Speterstatic __inline void bus_space_write_region_1(bus_space_tag_t tag,
605145119Speter					      bus_space_handle_t bsh,
606145119Speter					      bus_size_t offset,
607145119Speter					      const u_int8_t *addr,
608145119Speter					      size_t count);
609145119Speterstatic __inline void bus_space_write_region_2(bus_space_tag_t tag,
610145119Speter					      bus_space_handle_t bsh,
611145119Speter					      bus_size_t offset,
612145119Speter					      const u_int16_t *addr,
613145119Speter					      size_t count);
614145119Speterstatic __inline void bus_space_write_region_4(bus_space_tag_t tag,
615145119Speter					      bus_space_handle_t bsh,
616145119Speter					      bus_size_t offset,
617145119Speter					      const u_int32_t *addr,
618145119Speter					      size_t count);
619145119Speter
620145119Speterstatic __inline void
621145119Speterbus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
622145119Speter			 bus_size_t offset, const u_int8_t *addr, size_t count)
623145119Speter{
624146734Snyan
625146734Snyan	if (tag == AMD64_BUS_SPACE_IO) {
626145119Speter		int _port_ = bsh + offset;
627145119Speter#ifdef __GNUCLIKE_ASM
628145119Speter		__asm __volatile("				\n\
629145119Speter			cld					\n\
630145119Speter		1:	lodsb					\n\
631145119Speter			outb %%al,%w0				\n\
632145119Speter			incl %0					\n\
633145119Speter			loop 1b"				:
634145119Speter		    "=d" (_port_), "=S" (addr), "=c" (count)	:
635145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
636145119Speter		    "%eax", "memory", "cc");
637145119Speter#endif
638146734Snyan	} else {
639145119Speter		bus_space_handle_t _port_ = bsh + offset;
640145119Speter#ifdef __GNUCLIKE_ASM
641145119Speter		__asm __volatile("				\n\
642145119Speter			cld					\n\
643145119Speter			repne					\n\
644145119Speter			movsb"					:
645145119Speter		    "=D" (_port_), "=S" (addr), "=c" (count)	:
646145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
647145119Speter		    "memory", "cc");
648145119Speter#endif
649145119Speter	}
650145119Speter}
651145119Speter
652145119Speterstatic __inline void
653145119Speterbus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
654145119Speter			 bus_size_t offset, const u_int16_t *addr, size_t count)
655145119Speter{
656146734Snyan
657146734Snyan	if (tag == AMD64_BUS_SPACE_IO) {
658145119Speter		int _port_ = bsh + offset;
659145119Speter#ifdef __GNUCLIKE_ASM
660145119Speter		__asm __volatile("				\n\
661145119Speter			cld					\n\
662145119Speter		1:	lodsw					\n\
663145119Speter			outw %%ax,%w0				\n\
664145119Speter			addl $2,%0				\n\
665145119Speter			loop 1b"				:
666145119Speter		    "=d" (_port_), "=S" (addr), "=c" (count)	:
667145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
668145119Speter		    "%eax", "memory", "cc");
669145119Speter#endif
670146734Snyan	} else {
671145119Speter		bus_space_handle_t _port_ = bsh + offset;
672145119Speter#ifdef __GNUCLIKE_ASM
673145119Speter		__asm __volatile("				\n\
674145119Speter			cld					\n\
675145119Speter			repne					\n\
676145119Speter			movsw"					:
677145119Speter		    "=D" (_port_), "=S" (addr), "=c" (count)	:
678145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
679145119Speter		    "memory", "cc");
680145119Speter#endif
681145119Speter	}
682145119Speter}
683145119Speter
684145119Speterstatic __inline void
685145119Speterbus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
686145119Speter			 bus_size_t offset, const u_int32_t *addr, size_t count)
687145119Speter{
688146734Snyan
689146734Snyan	if (tag == AMD64_BUS_SPACE_IO) {
690145119Speter		int _port_ = bsh + offset;
691145119Speter#ifdef __GNUCLIKE_ASM
692145119Speter		__asm __volatile("				\n\
693145119Speter			cld					\n\
694145119Speter		1:	lodsl					\n\
695145119Speter			outl %%eax,%w0				\n\
696145119Speter			addl $4,%0				\n\
697145119Speter			loop 1b"				:
698145119Speter		    "=d" (_port_), "=S" (addr), "=c" (count)	:
699145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
700145119Speter		    "%eax", "memory", "cc");
701145119Speter#endif
702146734Snyan	} else {
703145119Speter		bus_space_handle_t _port_ = bsh + offset;
704145119Speter#ifdef __GNUCLIKE_ASM
705145119Speter		__asm __volatile("				\n\
706145119Speter			cld					\n\
707145119Speter			repne					\n\
708145119Speter			movsl"					:
709145119Speter		    "=D" (_port_), "=S" (addr), "=c" (count)	:
710145119Speter		    "0" (_port_), "1" (addr), "2" (count)	:
711145119Speter		    "memory", "cc");
712145119Speter#endif
713145119Speter	}
714145119Speter}
715145119Speter
716145119Speter#if 0	/* Cause a link error for bus_space_write_region_8 */
717145119Speter#define	bus_space_write_region_8					\
718145119Speter			!!! bus_space_write_region_8 unimplemented !!!
719145119Speter#endif
720145119Speter
721145119Speter/*
722145119Speter * Write the 1, 2, 4, or 8 byte value `val' to bus space described
723145119Speter * by tag/handle/offset `count' times.
724145119Speter */
725145119Speter
726145119Speterstatic __inline void bus_space_set_multi_1(bus_space_tag_t tag,
727145119Speter					   bus_space_handle_t bsh,
728145119Speter					   bus_size_t offset,
729145119Speter					   u_int8_t value, size_t count);
730145119Speterstatic __inline void bus_space_set_multi_2(bus_space_tag_t tag,
731145119Speter					   bus_space_handle_t bsh,
732145119Speter					   bus_size_t offset,
733145119Speter					   u_int16_t value, size_t count);
734145119Speterstatic __inline void bus_space_set_multi_4(bus_space_tag_t tag,
735145119Speter					   bus_space_handle_t bsh,
736145119Speter					   bus_size_t offset,
737145119Speter					   u_int32_t value, size_t count);
738145119Speter
739145119Speterstatic __inline void
740145119Speterbus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
741145119Speter		      bus_size_t offset, u_int8_t value, size_t count)
742145119Speter{
743145119Speter	bus_space_handle_t addr = bsh + offset;
744145119Speter
745145119Speter	if (tag == AMD64_BUS_SPACE_IO)
746145119Speter		while (count--)
747145119Speter			outb(addr, value);
748145119Speter	else
749145119Speter		while (count--)
750145119Speter			*(volatile u_int8_t *)(addr) = value;
751145119Speter}
752145119Speter
753145119Speterstatic __inline void
754145119Speterbus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
755145119Speter		     bus_size_t offset, u_int16_t value, size_t count)
756145119Speter{
757145119Speter	bus_space_handle_t addr = bsh + offset;
758145119Speter
759145119Speter	if (tag == AMD64_BUS_SPACE_IO)
760145119Speter		while (count--)
761145119Speter			outw(addr, value);
762145119Speter	else
763145119Speter		while (count--)
764145119Speter			*(volatile u_int16_t *)(addr) = value;
765145119Speter}
766145119Speter
767145119Speterstatic __inline void
768145119Speterbus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
769145119Speter		      bus_size_t offset, u_int32_t value, size_t count)
770145119Speter{
771145119Speter	bus_space_handle_t addr = bsh + offset;
772145119Speter
773145119Speter	if (tag == AMD64_BUS_SPACE_IO)
774145119Speter		while (count--)
775145119Speter			outl(addr, value);
776145119Speter	else
777145119Speter		while (count--)
778145119Speter			*(volatile u_int32_t *)(addr) = value;
779145119Speter}
780145119Speter
781145119Speter#if 0	/* Cause a link error for bus_space_set_multi_8 */
782145119Speter#define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
783145119Speter#endif
784145119Speter
785145119Speter/*
786145119Speter * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
787145119Speter * by tag/handle starting at `offset'.
788145119Speter */
789145119Speter
790145119Speterstatic __inline void bus_space_set_region_1(bus_space_tag_t tag,
791145119Speter					    bus_space_handle_t bsh,
792145119Speter					    bus_size_t offset, u_int8_t value,
793145119Speter					    size_t count);
794145119Speterstatic __inline void bus_space_set_region_2(bus_space_tag_t tag,
795145119Speter					    bus_space_handle_t bsh,
796145119Speter					    bus_size_t offset, u_int16_t value,
797145119Speter					    size_t count);
798145119Speterstatic __inline void bus_space_set_region_4(bus_space_tag_t tag,
799145119Speter					    bus_space_handle_t bsh,
800145119Speter					    bus_size_t offset, u_int32_t value,
801145119Speter					    size_t count);
802145119Speter
803145119Speterstatic __inline void
804145119Speterbus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
805145119Speter		       bus_size_t offset, u_int8_t value, size_t count)
806145119Speter{
807145119Speter	bus_space_handle_t addr = bsh + offset;
808145119Speter
809145119Speter	if (tag == AMD64_BUS_SPACE_IO)
810145119Speter		for (; count != 0; count--, addr++)
811145119Speter			outb(addr, value);
812145119Speter	else
813145119Speter		for (; count != 0; count--, addr++)
814145119Speter			*(volatile u_int8_t *)(addr) = value;
815145119Speter}
816145119Speter
817145119Speterstatic __inline void
818145119Speterbus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
819145119Speter		       bus_size_t offset, u_int16_t value, size_t count)
820145119Speter{
821145119Speter	bus_space_handle_t addr = bsh + offset;
822145119Speter
823145119Speter	if (tag == AMD64_BUS_SPACE_IO)
824145119Speter		for (; count != 0; count--, addr += 2)
825145119Speter			outw(addr, value);
826145119Speter	else
827145119Speter		for (; count != 0; count--, addr += 2)
828145119Speter			*(volatile u_int16_t *)(addr) = value;
829145119Speter}
830145119Speter
831145119Speterstatic __inline void
832145119Speterbus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
833145119Speter		       bus_size_t offset, u_int32_t value, size_t count)
834145119Speter{
835145119Speter	bus_space_handle_t addr = bsh + offset;
836145119Speter
837145119Speter	if (tag == AMD64_BUS_SPACE_IO)
838145119Speter		for (; count != 0; count--, addr += 4)
839145119Speter			outl(addr, value);
840145119Speter	else
841145119Speter		for (; count != 0; count--, addr += 4)
842145119Speter			*(volatile u_int32_t *)(addr) = value;
843145119Speter}
844145119Speter
845145119Speter#if 0	/* Cause a link error for bus_space_set_region_8 */
846145119Speter#define	bus_space_set_region_8	!!! bus_space_set_region_8 unimplemented !!!
847145119Speter#endif
848145119Speter
849145119Speter/*
850145119Speter * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
851145119Speter * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
852145119Speter */
853145119Speter
854145119Speterstatic __inline void bus_space_copy_region_1(bus_space_tag_t tag,
855145119Speter					     bus_space_handle_t bsh1,
856145119Speter					     bus_size_t off1,
857145119Speter					     bus_space_handle_t bsh2,
858145119Speter					     bus_size_t off2, size_t count);
859145119Speter
860145119Speterstatic __inline void bus_space_copy_region_2(bus_space_tag_t tag,
861145119Speter					     bus_space_handle_t bsh1,
862145119Speter					     bus_size_t off1,
863145119Speter					     bus_space_handle_t bsh2,
864145119Speter					     bus_size_t off2, size_t count);
865145119Speter
866145119Speterstatic __inline void bus_space_copy_region_4(bus_space_tag_t tag,
867145119Speter					     bus_space_handle_t bsh1,
868145119Speter					     bus_size_t off1,
869145119Speter					     bus_space_handle_t bsh2,
870145119Speter					     bus_size_t off2, size_t count);
871145119Speter
872145119Speterstatic __inline void
873145119Speterbus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
874145119Speter			bus_size_t off1, bus_space_handle_t bsh2,
875145119Speter			bus_size_t off2, size_t count)
876145119Speter{
877145119Speter	bus_space_handle_t addr1 = bsh1 + off1;
878145119Speter	bus_space_handle_t addr2 = bsh2 + off2;
879145119Speter
880146734Snyan	if (tag == AMD64_BUS_SPACE_IO) {
881145119Speter		if (addr1 >= addr2) {
882145119Speter			/* src after dest: copy forward */
883145119Speter			for (; count != 0; count--, addr1++, addr2++)
884145119Speter				outb(addr2, inb(addr1));
885145119Speter		} else {
886145119Speter			/* dest after src: copy backwards */
887145119Speter			for (addr1 += (count - 1), addr2 += (count - 1);
888145119Speter			    count != 0; count--, addr1--, addr2--)
889145119Speter				outb(addr2, inb(addr1));
890145119Speter		}
891146734Snyan	} else {
892145119Speter		if (addr1 >= addr2) {
893145119Speter			/* src after dest: copy forward */
894145119Speter			for (; count != 0; count--, addr1++, addr2++)
895145119Speter				*(volatile u_int8_t *)(addr2) =
896145119Speter				    *(volatile u_int8_t *)(addr1);
897145119Speter		} else {
898145119Speter			/* dest after src: copy backwards */
899145119Speter			for (addr1 += (count - 1), addr2 += (count - 1);
900145119Speter			    count != 0; count--, addr1--, addr2--)
901145119Speter				*(volatile u_int8_t *)(addr2) =
902145119Speter				    *(volatile u_int8_t *)(addr1);
903145119Speter		}
904145119Speter	}
905145119Speter}
906145119Speter
907145119Speterstatic __inline void
908145119Speterbus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
909145119Speter			bus_size_t off1, bus_space_handle_t bsh2,
910145119Speter			bus_size_t off2, size_t count)
911145119Speter{
912145119Speter	bus_space_handle_t addr1 = bsh1 + off1;
913145119Speter	bus_space_handle_t addr2 = bsh2 + off2;
914145119Speter
915146734Snyan	if (tag == AMD64_BUS_SPACE_IO) {
916145119Speter		if (addr1 >= addr2) {
917145119Speter			/* src after dest: copy forward */
918145119Speter			for (; count != 0; count--, addr1 += 2, addr2 += 2)
919145119Speter				outw(addr2, inw(addr1));
920145119Speter		} else {
921145119Speter			/* dest after src: copy backwards */
922145119Speter			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
923145119Speter			    count != 0; count--, addr1 -= 2, addr2 -= 2)
924145119Speter				outw(addr2, inw(addr1));
925145119Speter		}
926146734Snyan	} else {
927145119Speter		if (addr1 >= addr2) {
928145119Speter			/* src after dest: copy forward */
929145119Speter			for (; count != 0; count--, addr1 += 2, addr2 += 2)
930145119Speter				*(volatile u_int16_t *)(addr2) =
931145119Speter				    *(volatile u_int16_t *)(addr1);
932145119Speter		} else {
933145119Speter			/* dest after src: copy backwards */
934145119Speter			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
935145119Speter			    count != 0; count--, addr1 -= 2, addr2 -= 2)
936145119Speter				*(volatile u_int16_t *)(addr2) =
937145119Speter				    *(volatile u_int16_t *)(addr1);
938145119Speter		}
939145119Speter	}
940145119Speter}
941145119Speter
942145119Speterstatic __inline void
943145119Speterbus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
944145119Speter			bus_size_t off1, bus_space_handle_t bsh2,
945145119Speter			bus_size_t off2, size_t count)
946145119Speter{
947145119Speter	bus_space_handle_t addr1 = bsh1 + off1;
948145119Speter	bus_space_handle_t addr2 = bsh2 + off2;
949145119Speter
950146734Snyan	if (tag == AMD64_BUS_SPACE_IO) {
951145119Speter		if (addr1 >= addr2) {
952145119Speter			/* src after dest: copy forward */
953145119Speter			for (; count != 0; count--, addr1 += 4, addr2 += 4)
954145119Speter				outl(addr2, inl(addr1));
955145119Speter		} else {
956145119Speter			/* dest after src: copy backwards */
957145119Speter			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
958145119Speter			    count != 0; count--, addr1 -= 4, addr2 -= 4)
959145119Speter				outl(addr2, inl(addr1));
960145119Speter		}
961146734Snyan	} else {
962145119Speter		if (addr1 >= addr2) {
963145119Speter			/* src after dest: copy forward */
964145119Speter			for (; count != 0; count--, addr1 += 4, addr2 += 4)
965145119Speter				*(volatile u_int32_t *)(addr2) =
966145119Speter				    *(volatile u_int32_t *)(addr1);
967145119Speter		} else {
968145119Speter			/* dest after src: copy backwards */
969145119Speter			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
970145119Speter			    count != 0; count--, addr1 -= 4, addr2 -= 4)
971145119Speter				*(volatile u_int32_t *)(addr2) =
972145119Speter				    *(volatile u_int32_t *)(addr1);
973145119Speter		}
974145119Speter	}
975145119Speter}
976145119Speter
977145119Speter#if 0	/* Cause a link error for bus_space_copy_8 */
978145119Speter#define	bus_space_copy_region_8	!!! bus_space_copy_region_8 unimplemented !!!
979145119Speter#endif
980145119Speter
981145119Speter/*
982145119Speter * Bus read/write barrier methods.
983145119Speter *
984145119Speter *	void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
985145119Speter *			       bus_size_t offset, bus_size_t len, int flags);
986145119Speter *
987145119Speter *
988145119Speter * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
989145119Speter * prevent reordering by the compiler; all Intel x86 processors currently
990145119Speter * retire operations outside the CPU in program order.
991145119Speter */
992145119Speter#define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
993145119Speter#define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
994145119Speter
995145119Speterstatic __inline void
996145119Speterbus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
997145119Speter		  bus_size_t offset __unused, bus_size_t len __unused, int flags)
998145119Speter{
999145119Speter#ifdef __GNUCLIKE_ASM
1000145119Speter	if (flags & BUS_SPACE_BARRIER_READ)
1001145119Speter		__asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory");
1002145119Speter	else
1003145119Speter		__asm __volatile("" : : : "memory");
1004145119Speter#endif
1005145119Speter}
1006145119Speter
1007156699Speter#ifdef BUS_SPACE_NO_LEGACY
1008156699Speter#undef inb
1009156699Speter#undef outb
1010156699Speter#define inb(a) compiler_error
1011156699Speter#define inw(a) compiler_error
1012156699Speter#define inl(a) compiler_error
1013156699Speter#define outb(a, b) compiler_error
1014156699Speter#define outw(a, b) compiler_error
1015156699Speter#define outl(a, b) compiler_error
1016156699Speter#endif
1017156699Speter
101884593Snyan#include <machine/bus_dma.h>
101948527Simp
102091394Stmm/*
1021114930Speter * Stream accesses are the same as normal accesses on amd64; there are no
102291394Stmm * supported bus systems with an endianess different from the host one.
102391394Stmm */
102491394Stmm#define	bus_space_read_stream_1(t, h, o)	bus_space_read_1((t), (h), (o))
102591394Stmm#define	bus_space_read_stream_2(t, h, o)	bus_space_read_2((t), (h), (o))
102691394Stmm#define	bus_space_read_stream_4(t, h, o)	bus_space_read_4((t), (h), (o))
102791394Stmm
102891394Stmm#define	bus_space_read_multi_stream_1(t, h, o, a, c) \
102991394Stmm	bus_space_read_multi_1((t), (h), (o), (a), (c))
103091394Stmm#define	bus_space_read_multi_stream_2(t, h, o, a, c) \
103191394Stmm	bus_space_read_multi_2((t), (h), (o), (a), (c))
103291394Stmm#define	bus_space_read_multi_stream_4(t, h, o, a, c) \
103391394Stmm	bus_space_read_multi_4((t), (h), (o), (a), (c))
103491394Stmm
103591394Stmm#define	bus_space_write_stream_1(t, h, o, v) \
103691394Stmm	bus_space_write_1((t), (h), (o), (v))
103791394Stmm#define	bus_space_write_stream_2(t, h, o, v) \
103891394Stmm	bus_space_write_2((t), (h), (o), (v))
103991394Stmm#define	bus_space_write_stream_4(t, h, o, v) \
104091394Stmm	bus_space_write_4((t), (h), (o), (v))
104191394Stmm
104291394Stmm#define	bus_space_write_multi_stream_1(t, h, o, a, c) \
104391394Stmm	bus_space_write_multi_1((t), (h), (o), (a), (c))
104491394Stmm#define	bus_space_write_multi_stream_2(t, h, o, a, c) \
104591394Stmm	bus_space_write_multi_2((t), (h), (o), (a), (c))
104691394Stmm#define	bus_space_write_multi_stream_4(t, h, o, a, c) \
104791394Stmm	bus_space_write_multi_4((t), (h), (o), (a), (c))
104891394Stmm
104991394Stmm#define	bus_space_set_multi_stream_1(t, h, o, v, c) \
105091394Stmm	bus_space_set_multi_1((t), (h), (o), (v), (c))
105191394Stmm#define	bus_space_set_multi_stream_2(t, h, o, v, c) \
105291394Stmm	bus_space_set_multi_2((t), (h), (o), (v), (c))
105391394Stmm#define	bus_space_set_multi_stream_4(t, h, o, v, c) \
105491394Stmm	bus_space_set_multi_4((t), (h), (o), (v), (c))
105591394Stmm
105691394Stmm#define	bus_space_read_region_stream_1(t, h, o, a, c) \
105791394Stmm	bus_space_read_region_1((t), (h), (o), (a), (c))
105891394Stmm#define	bus_space_read_region_stream_2(t, h, o, a, c) \
105991394Stmm	bus_space_read_region_2((t), (h), (o), (a), (c))
106091394Stmm#define	bus_space_read_region_stream_4(t, h, o, a, c) \
106191394Stmm	bus_space_read_region_4((t), (h), (o), (a), (c))
106291394Stmm
106391394Stmm#define	bus_space_write_region_stream_1(t, h, o, a, c) \
106491394Stmm	bus_space_write_region_1((t), (h), (o), (a), (c))
106591394Stmm#define	bus_space_write_region_stream_2(t, h, o, a, c) \
106691394Stmm	bus_space_write_region_2((t), (h), (o), (a), (c))
106791394Stmm#define	bus_space_write_region_stream_4(t, h, o, a, c) \
106891394Stmm	bus_space_write_region_4((t), (h), (o), (a), (c))
106991394Stmm
107091394Stmm#define	bus_space_set_region_stream_1(t, h, o, v, c) \
107191394Stmm	bus_space_set_region_1((t), (h), (o), (v), (c))
107291394Stmm#define	bus_space_set_region_stream_2(t, h, o, v, c) \
107391394Stmm	bus_space_set_region_2((t), (h), (o), (v), (c))
107491394Stmm#define	bus_space_set_region_stream_4(t, h, o, v, c) \
107591394Stmm	bus_space_set_region_4((t), (h), (o), (v), (c))
107691394Stmm
107791394Stmm#define	bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
107891394Stmm	bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
107991394Stmm#define	bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
108091394Stmm	bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
108191394Stmm#define	bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
108291394Stmm	bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
108391394Stmm
1084114930Speter#endif /* _AMD64_BUS_H_ */
1085