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