bus.h revision 32517
132517Sgibbs/* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */ 232517Sgibbs 332517Sgibbs/*- 432517Sgibbs * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. 532517Sgibbs * All rights reserved. 632517Sgibbs * 732517Sgibbs * This code is derived from software contributed to The NetBSD Foundation 832517Sgibbs * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 932517Sgibbs * NASA Ames Research Center. 1032517Sgibbs * 1132517Sgibbs * Redistribution and use in source and binary forms, with or without 1232517Sgibbs * modification, are permitted provided that the following conditions 1332517Sgibbs * are met: 1432517Sgibbs * 1. Redistributions of source code must retain the above copyright 1532517Sgibbs * notice, this list of conditions and the following disclaimer. 1632517Sgibbs * 2. Redistributions in binary form must reproduce the above copyright 1732517Sgibbs * notice, this list of conditions and the following disclaimer in the 1832517Sgibbs * documentation and/or other materials provided with the distribution. 1932517Sgibbs * 3. All advertising materials mentioning features or use of this software 2032517Sgibbs * must display the following acknowledgement: 2132517Sgibbs * This product includes software developed by the NetBSD 2232517Sgibbs * Foundation, Inc. and its contributors. 2332517Sgibbs * 4. Neither the name of The NetBSD Foundation nor the names of its 2432517Sgibbs * contributors may be used to endorse or promote products derived 2532517Sgibbs * from this software without specific prior written permission. 2632517Sgibbs * 2732517Sgibbs * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 2832517Sgibbs * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2932517Sgibbs * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 3032517Sgibbs * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 3132517Sgibbs * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3232517Sgibbs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3332517Sgibbs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3432517Sgibbs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3532517Sgibbs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3632517Sgibbs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3732517Sgibbs * POSSIBILITY OF SUCH DAMAGE. 3832517Sgibbs */ 3932517Sgibbs 4032517Sgibbs/* 4132517Sgibbs * Copyright (c) 1996 Charles M. Hannum. All rights reserved. 4232517Sgibbs * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 4332517Sgibbs * 4432517Sgibbs * Redistribution and use in source and binary forms, with or without 4532517Sgibbs * modification, are permitted provided that the following conditions 4632517Sgibbs * are met: 4732517Sgibbs * 1. Redistributions of source code must retain the above copyright 4832517Sgibbs * notice, this list of conditions and the following disclaimer. 4932517Sgibbs * 2. Redistributions in binary form must reproduce the above copyright 5032517Sgibbs * notice, this list of conditions and the following disclaimer in the 5132517Sgibbs * documentation and/or other materials provided with the distribution. 5232517Sgibbs * 3. All advertising materials mentioning features or use of this software 5332517Sgibbs * must display the following acknowledgement: 5432517Sgibbs * This product includes software developed by Christopher G. Demetriou 5532517Sgibbs * for the NetBSD Project. 5632517Sgibbs * 4. The name of the author may not be used to endorse or promote products 5732517Sgibbs * derived from this software without specific prior written permission 5832517Sgibbs * 5932517Sgibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 6032517Sgibbs * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 6132517Sgibbs * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 6232517Sgibbs * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 6332517Sgibbs * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 6432517Sgibbs * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 6532517Sgibbs * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 6632517Sgibbs * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 6732517Sgibbs * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 6832517Sgibbs * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 6932517Sgibbs */ 7032517Sgibbs/* $Id$ */ 7132517Sgibbs 7232517Sgibbs#ifndef _I386_BUS_H_ 7332517Sgibbs#define _I386_BUS_H_ 7432517Sgibbs 7532517Sgibbs#include <machine/cpufunc.h> 7632517Sgibbs 7732517Sgibbs/* 7832517Sgibbs * Values for the i386 bus space tag, not to be used directly by MI code. 7932517Sgibbs */ 8032517Sgibbs#define I386_BUS_SPACE_IO 0 /* space is i/o space */ 8132517Sgibbs#define I386_BUS_SPACE_MEM 1 /* space is mem space */ 8232517Sgibbs 8332517Sgibbs/* 8432517Sgibbs * Bus address and size types 8532517Sgibbs */ 8632517Sgibbstypedef u_long bus_addr_t; 8732517Sgibbstypedef u_long bus_size_t; 8832517Sgibbs 8932517Sgibbs#define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF 9032517Sgibbs#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF 9132517Sgibbs#define BUS_SPACE_MAXSIZE (64 * 1024) /* Maximum supported size */ 9232517Sgibbs#define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF 9332517Sgibbs#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF 9432517Sgibbs#define BUS_SPACE_MAXADDR 0xFFFFFFFF 9532517Sgibbs 9632517Sgibbs/* 9732517Sgibbs * Access methods for bus resources and address space. 9832517Sgibbs */ 9932517Sgibbstypedef int bus_space_tag_t; 10032517Sgibbstypedef u_long bus_space_handle_t; 10132517Sgibbs 10232517Sgibbs/* 10332517Sgibbs * Map a region of device bus space into CPU virtual address space. 10432517Sgibbs */ 10532517Sgibbs 10632517Sgibbs#define BUS_SPACE_MAP_CACHEABLE 0x01 10732517Sgibbs#define BUS_SPACE_MAP_LINEAR 0x02 10832517Sgibbs 10932517Sgibbsint bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, 11032517Sgibbs int flags, bus_space_handle_t *bshp); 11132517Sgibbs 11232517Sgibbs/* 11332517Sgibbs * Unmap a region of device bus space. 11432517Sgibbs */ 11532517Sgibbs 11632517Sgibbsvoid bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, 11732517Sgibbs bus_size_t size); 11832517Sgibbs 11932517Sgibbs/* 12032517Sgibbs * Get a new handle for a subregion of an already-mapped area of bus space. 12132517Sgibbs */ 12232517Sgibbs 12332517Sgibbsint bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, 12432517Sgibbs bus_size_t offset, bus_size_t size, 12532517Sgibbs bus_space_handle_t *nbshp); 12632517Sgibbs 12732517Sgibbs/* 12832517Sgibbs * Allocate a region of memory that is accessible to devices in bus space. 12932517Sgibbs */ 13032517Sgibbs 13132517Sgibbsint bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, 13232517Sgibbs bus_addr_t rend, bus_size_t size, bus_size_t align, 13332517Sgibbs bus_size_t boundary, int flags, bus_addr_t *addrp, 13432517Sgibbs bus_space_handle_t *bshp); 13532517Sgibbs 13632517Sgibbs/* 13732517Sgibbs * Free a region of bus space accessible memory. 13832517Sgibbs */ 13932517Sgibbs 14032517Sgibbsvoid bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, 14132517Sgibbs bus_size_t size); 14232517Sgibbs 14332517Sgibbs#if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_) 14432517Sgibbs 14532517Sgibbs/* 14632517Sgibbs * Read a 1, 2, 4, or 8 byte quantity from bus space 14732517Sgibbs * described by tag/handle/offset. 14832517Sgibbs */ 14932517Sgibbsstatic __inline u_int8_t bus_space_read_1(bus_space_tag_t tag, 15032517Sgibbs bus_space_handle_t handle, 15132517Sgibbs bus_size_t offset); 15232517Sgibbs 15332517Sgibbsstatic __inline u_int16_t bus_space_read_2(bus_space_tag_t tag, 15432517Sgibbs bus_space_handle_t handle, 15532517Sgibbs bus_size_t offset); 15632517Sgibbs 15732517Sgibbsstatic __inline u_int32_t bus_space_read_4(bus_space_tag_t tag, 15832517Sgibbs bus_space_handle_t handle, 15932517Sgibbs bus_size_t offset); 16032517Sgibbs 16132517Sgibbsstatic __inline u_int8_t 16232517Sgibbsbus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle, 16332517Sgibbs bus_size_t offset) 16432517Sgibbs{ 16532517Sgibbs#if defined (_I386_BUS_PIO_H_) 16632517Sgibbs#if defined (_I386_BUS_MEMIO_H_) 16732517Sgibbs if (tag == I386_BUS_SPACE_IO) 16832517Sgibbs#endif 16932517Sgibbs return (inb(handle + offset)); 17032517Sgibbs#endif 17132517Sgibbs#if defined (_I386_BUS_MEMIO_H_) 17232517Sgibbs return (*(volatile u_int8_t *)(handle + offset)); 17332517Sgibbs#endif 17432517Sgibbs} 17532517Sgibbs 17632517Sgibbsstatic __inline u_int16_t 17732517Sgibbsbus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle, 17832517Sgibbs bus_size_t offset) 17932517Sgibbs{ 18032517Sgibbs#if defined(_I386_BUS_PIO_H_) 18132517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 18232517Sgibbs if (tag == I386_BUS_SPACE_IO) 18332517Sgibbs#endif 18432517Sgibbs return (inw(handle + offset)); 18532517Sgibbs#endif 18632517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 18732517Sgibbs return (*(volatile u_int16_t *)(handle + offset)); 18832517Sgibbs#endif 18932517Sgibbs} 19032517Sgibbs 19132517Sgibbsstatic __inline u_int32_t 19232517Sgibbsbus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle, 19332517Sgibbs bus_size_t offset) 19432517Sgibbs{ 19532517Sgibbs#if defined(_I386_BUS_PIO_H_) 19632517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 19732517Sgibbs if (tag == I386_BUS_SPACE_IO) 19832517Sgibbs#endif 19932517Sgibbs return (inl(handle + offset)); 20032517Sgibbs#endif 20132517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 20232517Sgibbs return (*(volatile u_int32_t *)(handle + offset)); 20332517Sgibbs#endif 20432517Sgibbs} 20532517Sgibbs 20632517Sgibbs#if 0 /* Cause a link error for bus_space_read_8 */ 20732517Sgibbs#define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!! 20832517Sgibbs#endif 20932517Sgibbs 21032517Sgibbs/* 21132517Sgibbs * Read `count' 1, 2, 4, or 8 byte quantities from bus space 21232517Sgibbs * described by tag/handle/offset and copy into buffer provided. 21332517Sgibbs */ 21432517Sgibbsstatic __inline void bus_space_read_multi_1(bus_space_tag_t tag, 21532517Sgibbs bus_space_handle_t bsh, 21632517Sgibbs bus_size_t offset, u_int8_t *addr, 21732517Sgibbs size_t count); 21832517Sgibbs 21932517Sgibbsstatic __inline void bus_space_read_multi_2(bus_space_tag_t tag, 22032517Sgibbs bus_space_handle_t bsh, 22132517Sgibbs bus_size_t offset, u_int16_t *addr, 22232517Sgibbs size_t count); 22332517Sgibbs 22432517Sgibbsstatic __inline void bus_space_read_multi_4(bus_space_tag_t tag, 22532517Sgibbs bus_space_handle_t bsh, 22632517Sgibbs bus_size_t offset, u_int32_t *addr, 22732517Sgibbs size_t count); 22832517Sgibbs 22932517Sgibbsstatic __inline void 23032517Sgibbsbus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 23132517Sgibbs bus_size_t offset, u_int8_t *addr, size_t count) 23232517Sgibbs{ 23332517Sgibbs#if defined(_I386_BUS_PIO_H_) 23432517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 23532517Sgibbs if (tag == I386_BUS_SPACE_IO) 23632517Sgibbs#endif 23732517Sgibbs insb(bsh + offset, addr, count); 23832517Sgibbs#endif 23932517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 24032517Sgibbs#if defined(_I386_BUS_PIO_H_) 24132517Sgibbs else 24232517Sgibbs#endif 24332517Sgibbs { 24432517Sgibbs int __x __asm__("%eax"); 24532517Sgibbs __asm __volatile(" 24632517Sgibbs cld ; 24732517Sgibbs 1: movb (%1),%%al ; 24832517Sgibbs stosb ; 24932517Sgibbs loop 1b" : 25032517Sgibbs "=&a" (__x) : 25132517Sgibbs "r" (bsh + offset), "D" (addr), "c" (count) : 25232517Sgibbs "%edi", "%ecx", "memory"); 25332517Sgibbs } 25432517Sgibbs#endif 25532517Sgibbs} 25632517Sgibbs 25732517Sgibbsstatic __inline void 25832517Sgibbsbus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 25932517Sgibbs bus_size_t offset, u_int16_t *addr, size_t count) 26032517Sgibbs{ 26132517Sgibbs#if defined(_I386_BUS_PIO_H_) 26232517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 26332517Sgibbs if (tag == I386_BUS_SPACE_IO) 26432517Sgibbs#endif 26532517Sgibbs insw(bsh + offset, addr, count); 26632517Sgibbs#endif 26732517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 26832517Sgibbs#if defined(_I386_BUS_PIO_H_) 26932517Sgibbs else 27032517Sgibbs#endif 27132517Sgibbs { 27232517Sgibbs int __x __asm__("%eax"); 27332517Sgibbs __asm __volatile(" 27432517Sgibbs cld ; 27532517Sgibbs 1: movw (%1),%%ax ; 27632517Sgibbs stosw ; 27732517Sgibbs loop 1b" : 27832517Sgibbs "=&a" (__x) : 27932517Sgibbs "r" (bsh + offset), "D" (addr), "c" (count) : 28032517Sgibbs "%edi", "%ecx", "memory"); 28132517Sgibbs } 28232517Sgibbs#endif 28332517Sgibbs} 28432517Sgibbs 28532517Sgibbsstatic __inline void 28632517Sgibbsbus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 28732517Sgibbs bus_size_t offset, u_int32_t *addr, size_t count) 28832517Sgibbs{ 28932517Sgibbs#if defined(_I386_BUS_PIO_H_) 29032517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 29132517Sgibbs if (tag == I386_BUS_SPACE_IO) 29232517Sgibbs#endif 29332517Sgibbs insl(bsh + offset, addr, count); 29432517Sgibbs#endif 29532517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 29632517Sgibbs#if defined(_I386_BUS_PIO_H_) 29732517Sgibbs else 29832517Sgibbs#endif 29932517Sgibbs { 30032517Sgibbs int __x __asm__("%eax"); 30132517Sgibbs __asm __volatile(" 30232517Sgibbs cld ; 30332517Sgibbs 1: movl (%1),%%eax ; 30432517Sgibbs stosl ; 30532517Sgibbs loop 1b" : 30632517Sgibbs "=&a" (__x) : 30732517Sgibbs "r" (bsh + offset), "D" (addr), "c" (count) : 30832517Sgibbs "%edi", "%ecx", "memory"); 30932517Sgibbs } 31032517Sgibbs#endif 31132517Sgibbs} 31232517Sgibbs 31332517Sgibbs#if 0 /* Cause a link error for bus_space_read_multi_8 */ 31432517Sgibbs#define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!! 31532517Sgibbs#endif 31632517Sgibbs 31732517Sgibbs/* 31832517Sgibbs * Read `count' 1, 2, 4, or 8 byte quantities from bus space 31932517Sgibbs * described by tag/handle and starting at `offset' and copy into 32032517Sgibbs * buffer provided. 32132517Sgibbs */ 32232517Sgibbsstatic __inline void bus_space_read_region_1(bus_space_tag_t tag, 32332517Sgibbs bus_space_handle_t bsh, 32432517Sgibbs bus_size_t offset, u_int8_t *addr, 32532517Sgibbs size_t count); 32632517Sgibbs 32732517Sgibbsstatic __inline void bus_space_read_region_2(bus_space_tag_t tag, 32832517Sgibbs bus_space_handle_t bsh, 32932517Sgibbs bus_size_t offset, u_int16_t *addr, 33032517Sgibbs size_t count); 33132517Sgibbs 33232517Sgibbsstatic __inline void bus_space_read_region_4(bus_space_tag_t tag, 33332517Sgibbs bus_space_handle_t bsh, 33432517Sgibbs bus_size_t offset, u_int32_t *addr, 33532517Sgibbs size_t count); 33632517Sgibbs 33732517Sgibbs 33832517Sgibbsstatic __inline void 33932517Sgibbsbus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 34032517Sgibbs bus_size_t offset, u_int8_t *addr, size_t count) 34132517Sgibbs{ 34232517Sgibbs#if defined(_I386_BUS_PIO_H_) 34332517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 34432517Sgibbs if (tag == I386_BUS_SPACE_IO) 34532517Sgibbs#endif 34632517Sgibbs { 34732517Sgibbs int __x __asm__("%eax"); 34832517Sgibbs __asm __volatile(" 34932517Sgibbs cld ; 35032517Sgibbs 1: inb %w1,%%al ; 35132517Sgibbs stosb ; 35232517Sgibbs incl %1 ; 35332517Sgibbs loop 1b" : 35432517Sgibbs "=&a" (__x) : 35532517Sgibbs "d" (bsh + offset), "D" (addr), "c" (count) : 35632517Sgibbs "%edx", "%edi", "%ecx", "memory"); 35732517Sgibbs } 35832517Sgibbs#endif 35932517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 36032517Sgibbs#if defined(_I386_BUS_PIO_H_) 36132517Sgibbs else 36232517Sgibbs#endif 36332517Sgibbs { 36432517Sgibbs __asm __volatile(" 36532517Sgibbs cld ; 36632517Sgibbs repne ; 36732517Sgibbs movsb" : 36832517Sgibbs : 36932517Sgibbs "S" (bsh + offset), "D" (addr), "c" (count) : 37032517Sgibbs "%esi", "%edi", "%ecx", "memory"); 37132517Sgibbs } 37232517Sgibbs#endif 37332517Sgibbs} 37432517Sgibbs 37532517Sgibbsstatic __inline void 37632517Sgibbsbus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 37732517Sgibbs bus_size_t offset, u_int16_t *addr, size_t count) 37832517Sgibbs{ 37932517Sgibbs#if defined(_I386_BUS_PIO_H_) 38032517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 38132517Sgibbs if (tag == I386_BUS_SPACE_IO) 38232517Sgibbs#endif 38332517Sgibbs { 38432517Sgibbs int __x __asm__("%eax"); 38532517Sgibbs __asm __volatile(" 38632517Sgibbs cld ; 38732517Sgibbs 1: inw %w1,%%ax ; 38832517Sgibbs stosw ; 38932517Sgibbs addl $2,%1 ; 39032517Sgibbs loop 1b" : 39132517Sgibbs "=&a" (__x) : 39232517Sgibbs "d" (bsh + offset), "D" (addr), "c" (count) : 39332517Sgibbs "%edx", "%edi", "%ecx", "memory"); 39432517Sgibbs } 39532517Sgibbs#endif 39632517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 39732517Sgibbs#if defined(_I386_BUS_PIO_H_) 39832517Sgibbs else 39932517Sgibbs#endif 40032517Sgibbs { 40132517Sgibbs __asm __volatile(" 40232517Sgibbs cld ; 40332517Sgibbs repne ; 40432517Sgibbs movsw" : 40532517Sgibbs : 40632517Sgibbs "S" (bsh + offset), "D" (addr), "c" (count) : 40732517Sgibbs "%esi", "%edi", "%ecx", "memory"); 40832517Sgibbs } 40932517Sgibbs#endif 41032517Sgibbs} 41132517Sgibbs 41232517Sgibbsstatic __inline void 41332517Sgibbsbus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 41432517Sgibbs bus_size_t offset, u_int32_t *addr, size_t count) 41532517Sgibbs{ 41632517Sgibbs#if defined(_I386_BUS_PIO_H_) 41732517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 41832517Sgibbs if (tag == I386_BUS_SPACE_IO) 41932517Sgibbs#endif 42032517Sgibbs { 42132517Sgibbs int __x __asm__("%eax"); 42232517Sgibbs __asm __volatile(" 42332517Sgibbs cld ; 42432517Sgibbs 1: inl %w1,%%eax ; 42532517Sgibbs stosl ; 42632517Sgibbs addl $4,%1 ; 42732517Sgibbs loop 1b" : 42832517Sgibbs "=&a" (__x) : 42932517Sgibbs "d" (bsh + offset), "D" (addr), "c" (count) : 43032517Sgibbs "%edx", "%edi", "%ecx", "memory"); 43132517Sgibbs } 43232517Sgibbs#endif 43332517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 43432517Sgibbs#if defined(_I386_BUS_PIO_H_) 43532517Sgibbs else 43632517Sgibbs#endif 43732517Sgibbs { 43832517Sgibbs __asm __volatile(" 43932517Sgibbs cld ; 44032517Sgibbs repne ; 44132517Sgibbs movsl" : 44232517Sgibbs : 44332517Sgibbs "S" (bsh + offset), "D" (addr), "c" (count) : 44432517Sgibbs "%esi", "%edi", "%ecx", "memory"); 44532517Sgibbs } 44632517Sgibbs#endif 44732517Sgibbs} 44832517Sgibbs 44932517Sgibbs#if 0 /* Cause a link error for bus_space_read_region_8 */ 45032517Sgibbs#define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!! 45132517Sgibbs#endif 45232517Sgibbs 45332517Sgibbs/* 45432517Sgibbs * Write the 1, 2, 4, or 8 byte value `value' to bus space 45532517Sgibbs * described by tag/handle/offset. 45632517Sgibbs */ 45732517Sgibbs 45832517Sgibbsstatic __inline void bus_space_write_1(bus_space_tag_t tag, 45932517Sgibbs bus_space_handle_t bsh, 46032517Sgibbs bus_size_t offset, u_int8_t value); 46132517Sgibbs 46232517Sgibbsstatic __inline void bus_space_write_2(bus_space_tag_t tag, 46332517Sgibbs bus_space_handle_t bsh, 46432517Sgibbs bus_size_t offset, u_int16_t value); 46532517Sgibbs 46632517Sgibbsstatic __inline void bus_space_write_4(bus_space_tag_t tag, 46732517Sgibbs bus_space_handle_t bsh, 46832517Sgibbs bus_size_t offset, u_int32_t value); 46932517Sgibbs 47032517Sgibbsstatic __inline void 47132517Sgibbsbus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh, 47232517Sgibbs bus_size_t offset, u_int8_t value) 47332517Sgibbs{ 47432517Sgibbs#if defined(_I386_BUS_PIO_H_) 47532517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 47632517Sgibbs if (tag == I386_BUS_SPACE_IO) 47732517Sgibbs#endif 47832517Sgibbs outb(bsh + offset, value); 47932517Sgibbs#endif 48032517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 48132517Sgibbs#if defined(_I386_BUS_PIO_H_) 48232517Sgibbs else 48332517Sgibbs#endif 48432517Sgibbs *(volatile u_int8_t *)(bsh + offset) = value; 48532517Sgibbs#endif 48632517Sgibbs} 48732517Sgibbs 48832517Sgibbsstatic __inline void 48932517Sgibbsbus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh, 49032517Sgibbs bus_size_t offset, u_int16_t value) 49132517Sgibbs{ 49232517Sgibbs#if defined(_I386_BUS_PIO_H_) 49332517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 49432517Sgibbs if (tag == I386_BUS_SPACE_IO) 49532517Sgibbs#endif 49632517Sgibbs outw(bsh + offset, value); 49732517Sgibbs#endif 49832517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 49932517Sgibbs#if defined(_I386_BUS_PIO_H_) 50032517Sgibbs else 50132517Sgibbs#endif 50232517Sgibbs *(volatile u_int16_t *)(bsh + offset) = value; 50332517Sgibbs#endif 50432517Sgibbs} 50532517Sgibbs 50632517Sgibbsstatic __inline void 50732517Sgibbsbus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh, 50832517Sgibbs bus_size_t offset, u_int32_t value) 50932517Sgibbs{ 51032517Sgibbs#if defined(_I386_BUS_PIO_H_) 51132517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 51232517Sgibbs if (tag == I386_BUS_SPACE_IO) 51332517Sgibbs#endif 51432517Sgibbs outl(bsh + offset, value); 51532517Sgibbs#endif 51632517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 51732517Sgibbs#if defined(_I386_BUS_PIO_H_) 51832517Sgibbs else 51932517Sgibbs#endif 52032517Sgibbs *(volatile u_int32_t *)(bsh + offset) = value; 52132517Sgibbs#endif 52232517Sgibbs} 52332517Sgibbs 52432517Sgibbs#if 0 /* Cause a link error for bus_space_write_8 */ 52532517Sgibbs#define bus_space_write_8 !!! bus_space_write_8 not implemented !!! 52632517Sgibbs#endif 52732517Sgibbs 52832517Sgibbs/* 52932517Sgibbs * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 53032517Sgibbs * provided to bus space described by tag/handle/offset. 53132517Sgibbs */ 53232517Sgibbs 53332517Sgibbsstatic __inline void bus_space_write_multi_1(bus_space_tag_t tag, 53432517Sgibbs bus_space_handle_t bsh, 53532517Sgibbs bus_size_t offset, 53632517Sgibbs const u_int8_t *addr, 53732517Sgibbs size_t count); 53832517Sgibbsstatic __inline void bus_space_write_multi_2(bus_space_tag_t tag, 53932517Sgibbs bus_space_handle_t bsh, 54032517Sgibbs bus_size_t offset, 54132517Sgibbs const u_int16_t *addr, 54232517Sgibbs size_t count); 54332517Sgibbs 54432517Sgibbsstatic __inline void bus_space_write_multi_4(bus_space_tag_t tag, 54532517Sgibbs bus_space_handle_t bsh, 54632517Sgibbs bus_size_t offset, 54732517Sgibbs const u_int32_t *addr, 54832517Sgibbs size_t count); 54932517Sgibbs 55032517Sgibbsstatic __inline void 55132517Sgibbsbus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 55232517Sgibbs bus_size_t offset, const u_int8_t *addr, size_t count) 55332517Sgibbs{ 55432517Sgibbs#if defined(_I386_BUS_PIO_H_) 55532517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 55632517Sgibbs if (tag == I386_BUS_SPACE_IO) 55732517Sgibbs#endif 55832517Sgibbs outsb(bsh + offset, addr, count); 55932517Sgibbs#endif 56032517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 56132517Sgibbs#if defined(_I386_BUS_PIO_H_) 56232517Sgibbs else 56332517Sgibbs#endif 56432517Sgibbs { 56532517Sgibbs int __x __asm__("%eax"); 56632517Sgibbs __asm __volatile(" 56732517Sgibbs cld ; 56832517Sgibbs 1: lodsb ; 56932517Sgibbs movb %%al,(%1) ; 57032517Sgibbs loop 1b" : 57132517Sgibbs "=&a" (__x) : 57232517Sgibbs "r" (bsh + offset), "S" (addr), "c" (count) : 57332517Sgibbs "%esi", "%ecx"); 57432517Sgibbs } 57532517Sgibbs#endif 57632517Sgibbs} 57732517Sgibbs 57832517Sgibbsstatic __inline void 57932517Sgibbsbus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 58032517Sgibbs bus_size_t offset, const u_int16_t *addr, size_t count) 58132517Sgibbs{ 58232517Sgibbs#if defined(_I386_BUS_PIO_H_) 58332517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 58432517Sgibbs if (tag == I386_BUS_SPACE_IO) 58532517Sgibbs#endif 58632517Sgibbs outsw(bsh + offset, addr, count); 58732517Sgibbs#endif 58832517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 58932517Sgibbs#if defined(_I386_BUS_PIO_H_) 59032517Sgibbs else 59132517Sgibbs#endif 59232517Sgibbs { 59332517Sgibbs int __x __asm__("%eax"); 59432517Sgibbs __asm __volatile(" 59532517Sgibbs cld ; 59632517Sgibbs 1: lodsw ; 59732517Sgibbs movw %%ax,(%1) ; 59832517Sgibbs loop 1b" : 59932517Sgibbs "=&a" (__x) : 60032517Sgibbs "r" (bsh + offset), "S" (addr), "c" (count) : 60132517Sgibbs "%esi", "%ecx"); 60232517Sgibbs } 60332517Sgibbs#endif 60432517Sgibbs} 60532517Sgibbs 60632517Sgibbsstatic __inline void 60732517Sgibbsbus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 60832517Sgibbs bus_size_t offset, const u_int32_t *addr, size_t count) 60932517Sgibbs{ 61032517Sgibbs#if defined(_I386_BUS_PIO_H_) 61132517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 61232517Sgibbs if (tag == I386_BUS_SPACE_IO) 61332517Sgibbs#endif 61432517Sgibbs outsl(bsh + offset, addr, count); 61532517Sgibbs#endif 61632517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 61732517Sgibbs#if defined(_I386_BUS_PIO_H_) 61832517Sgibbs else 61932517Sgibbs#endif 62032517Sgibbs { 62132517Sgibbs int __x __asm__("%eax"); 62232517Sgibbs __asm __volatile(" 62332517Sgibbs cld ; 62432517Sgibbs 1: lodsl ; 62532517Sgibbs movl %%eax,(%1) ; 62632517Sgibbs loop 1b" : 62732517Sgibbs "=&a" (__x) : 62832517Sgibbs "r" (bsh + offset), "S" (addr), "c" (count) : 62932517Sgibbs "%esi", "%ecx"); 63032517Sgibbs } 63132517Sgibbs#endif 63232517Sgibbs} 63332517Sgibbs 63432517Sgibbs#if 0 /* Cause a link error for bus_space_write_multi_8 */ 63532517Sgibbs#define bus_space_write_multi_8(t, h, o, a, c) \ 63632517Sgibbs !!! bus_space_write_multi_8 unimplemented !!! 63732517Sgibbs#endif 63832517Sgibbs 63932517Sgibbs/* 64032517Sgibbs * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 64132517Sgibbs * to bus space described by tag/handle starting at `offset'. 64232517Sgibbs */ 64332517Sgibbs 64432517Sgibbsstatic __inline void bus_space_write_region_1(bus_space_tag_t tag, 64532517Sgibbs bus_space_handle_t bsh, 64632517Sgibbs bus_size_t offset, 64732517Sgibbs const u_int8_t *addr, 64832517Sgibbs size_t count); 64932517Sgibbsstatic __inline void bus_space_write_region_2(bus_space_tag_t tag, 65032517Sgibbs bus_space_handle_t bsh, 65132517Sgibbs bus_size_t offset, 65232517Sgibbs const u_int16_t *addr, 65332517Sgibbs size_t count); 65432517Sgibbsstatic __inline void bus_space_write_region_4(bus_space_tag_t tag, 65532517Sgibbs bus_space_handle_t bsh, 65632517Sgibbs bus_size_t offset, 65732517Sgibbs const u_int32_t *addr, 65832517Sgibbs size_t count); 65932517Sgibbs 66032517Sgibbsstatic __inline void 66132517Sgibbsbus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 66232517Sgibbs bus_size_t offset, const u_int8_t *addr, size_t count) 66332517Sgibbs{ 66432517Sgibbs#if defined(_I386_BUS_PIO_H_) 66532517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 66632517Sgibbs if (tag == I386_BUS_SPACE_IO) 66732517Sgibbs#endif 66832517Sgibbs { 66932517Sgibbs int __x __asm__("%eax"); 67032517Sgibbs __asm __volatile(" 67132517Sgibbs cld ; 67232517Sgibbs 1: lodsb ; 67332517Sgibbs outb %%al,%w1 ; 67432517Sgibbs incl %1 ; 67532517Sgibbs loop 1b" : 67632517Sgibbs "=&a" (__x) : 67732517Sgibbs "d" (bsh + offset), "S" (addr), "c" (count) : 67832517Sgibbs "%edx", "%esi", "%ecx", "memory"); 67932517Sgibbs } 68032517Sgibbs#endif 68132517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 68232517Sgibbs#if defined(_I386_BUS_PIO_H_) 68332517Sgibbs else 68432517Sgibbs#endif 68532517Sgibbs { 68632517Sgibbs __asm __volatile(" 68732517Sgibbs cld ; 68832517Sgibbs repne ; 68932517Sgibbs movsb" : 69032517Sgibbs : 69132517Sgibbs "D" (bsh + offset), "S" (addr), "c" (count) : 69232517Sgibbs "%edi", "%esi", "%ecx", "memory"); 69332517Sgibbs } 69432517Sgibbs#endif 69532517Sgibbs} 69632517Sgibbs 69732517Sgibbsstatic __inline void 69832517Sgibbsbus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 69932517Sgibbs bus_size_t offset, const u_int16_t *addr, size_t count) 70032517Sgibbs{ 70132517Sgibbs#if defined(_I386_BUS_PIO_H_) 70232517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 70332517Sgibbs if (tag == I386_BUS_SPACE_IO) 70432517Sgibbs#endif 70532517Sgibbs { 70632517Sgibbs int __x __asm__("%eax"); 70732517Sgibbs __asm __volatile(" 70832517Sgibbs cld ; 70932517Sgibbs 1: lodsw ; 71032517Sgibbs outw %%ax,%w1 ; 71132517Sgibbs addl $2,%1 ; 71232517Sgibbs loop 1b" : 71332517Sgibbs "=&a" (__x) : 71432517Sgibbs "d" (bsh + offset), "S" (addr), "c" (count) : 71532517Sgibbs "%edx", "%esi", "%ecx", "memory"); 71632517Sgibbs } 71732517Sgibbs#endif 71832517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 71932517Sgibbs#if defined(_I386_BUS_PIO_H_) 72032517Sgibbs else 72132517Sgibbs#endif 72232517Sgibbs { 72332517Sgibbs __asm __volatile(" 72432517Sgibbs cld ; 72532517Sgibbs repne ; 72632517Sgibbs movsw" : 72732517Sgibbs : 72832517Sgibbs "D" (bsh + offset), "S" (addr), "c" (count) : 72932517Sgibbs "%edi", "%esi", "%ecx", "memory"); 73032517Sgibbs } 73132517Sgibbs#endif 73232517Sgibbs} 73332517Sgibbs 73432517Sgibbsstatic __inline void 73532517Sgibbsbus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 73632517Sgibbs bus_size_t offset, const u_int32_t *addr, size_t count) 73732517Sgibbs{ 73832517Sgibbs#if defined(_I386_BUS_PIO_H_) 73932517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 74032517Sgibbs if (tag == I386_BUS_SPACE_IO) 74132517Sgibbs#endif 74232517Sgibbs { 74332517Sgibbs int __x __asm__("%eax"); 74432517Sgibbs __asm __volatile(" 74532517Sgibbs cld ; 74632517Sgibbs 1: lodsl ; 74732517Sgibbs outl %%eax,%w1 ; 74832517Sgibbs addl $4,%1 ; 74932517Sgibbs loop 1b" : 75032517Sgibbs "=&a" (__x) : 75132517Sgibbs "d" (bsh + offset), "S" (addr), "c" (count) : 75232517Sgibbs "%edx", "%esi", "%ecx", "memory"); 75332517Sgibbs } 75432517Sgibbs#endif 75532517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 75632517Sgibbs#if defined(_I386_BUS_PIO_H_) 75732517Sgibbs else 75832517Sgibbs#endif 75932517Sgibbs { 76032517Sgibbs __asm __volatile(" 76132517Sgibbs cld ; 76232517Sgibbs repne ; 76332517Sgibbs movsl" : 76432517Sgibbs : 76532517Sgibbs "D" (bsh + offset), "S" (addr), "c" (count) : 76632517Sgibbs "%edi", "%esi", "%ecx", "memory"); 76732517Sgibbs } 76832517Sgibbs#endif 76932517Sgibbs} 77032517Sgibbs 77132517Sgibbs#if 0 /* Cause a link error for bus_space_write_region_8 */ 77232517Sgibbs#define bus_space_write_region_8 \ 77332517Sgibbs !!! bus_space_write_region_8 unimplemented !!! 77432517Sgibbs#endif 77532517Sgibbs 77632517Sgibbs/* 77732517Sgibbs * Write the 1, 2, 4, or 8 byte value `val' to bus space described 77832517Sgibbs * by tag/handle/offset `count' times. 77932517Sgibbs */ 78032517Sgibbs 78132517Sgibbsstatic __inline void bus_space_set_multi_1(bus_space_tag_t tag, 78232517Sgibbs bus_space_handle_t bsh, 78332517Sgibbs bus_size_t offset, 78432517Sgibbs u_int8_t value, size_t count); 78532517Sgibbsstatic __inline void bus_space_set_multi_2(bus_space_tag_t tag, 78632517Sgibbs bus_space_handle_t bsh, 78732517Sgibbs bus_size_t offset, 78832517Sgibbs u_int16_t value, size_t count); 78932517Sgibbsstatic __inline void bus_space_set_multi_4(bus_space_tag_t tag, 79032517Sgibbs bus_space_handle_t bsh, 79132517Sgibbs bus_size_t offset, 79232517Sgibbs u_int32_t value, size_t count); 79332517Sgibbs 79432517Sgibbsstatic __inline void 79532517Sgibbsbus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh, 79632517Sgibbs bus_size_t offset, u_int8_t value, size_t count) 79732517Sgibbs{ 79832517Sgibbs bus_addr_t addr = bsh + offset; 79932517Sgibbs 80032517Sgibbs#if defined(_I386_BUS_PIO_H_) 80132517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 80232517Sgibbs if (tag == I386_BUS_SPACE_IO) 80332517Sgibbs#endif 80432517Sgibbs while (count--) 80532517Sgibbs outb(addr, value); 80632517Sgibbs#endif 80732517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 80832517Sgibbs#if defined(_I386_BUS_PIO_H_) 80932517Sgibbs else 81032517Sgibbs#endif 81132517Sgibbs while (count--) 81232517Sgibbs *(volatile u_int8_t *)(addr) = value; 81332517Sgibbs#endif 81432517Sgibbs} 81532517Sgibbs 81632517Sgibbsstatic __inline void 81732517Sgibbsbus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh, 81832517Sgibbs bus_size_t offset, u_int16_t value, size_t count) 81932517Sgibbs{ 82032517Sgibbs bus_addr_t addr = bsh + offset; 82132517Sgibbs 82232517Sgibbs#if defined(_I386_BUS_PIO_H_) 82332517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 82432517Sgibbs if (tag == I386_BUS_SPACE_IO) 82532517Sgibbs#endif 82632517Sgibbs while (count--) 82732517Sgibbs outw(addr, value); 82832517Sgibbs#endif 82932517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 83032517Sgibbs#if defined(_I386_BUS_PIO_H_) 83132517Sgibbs else 83232517Sgibbs#endif 83332517Sgibbs while (count--) 83432517Sgibbs *(volatile u_int16_t *)(addr) = value; 83532517Sgibbs#endif 83632517Sgibbs} 83732517Sgibbs 83832517Sgibbsstatic __inline void 83932517Sgibbsbus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh, 84032517Sgibbs bus_size_t offset, u_int32_t value, size_t count) 84132517Sgibbs{ 84232517Sgibbs bus_addr_t addr = bsh + offset; 84332517Sgibbs 84432517Sgibbs#if defined(_I386_BUS_PIO_H_) 84532517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 84632517Sgibbs if (tag == I386_BUS_SPACE_IO) 84732517Sgibbs#endif 84832517Sgibbs while (count--) 84932517Sgibbs outl(addr, value); 85032517Sgibbs#endif 85132517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 85232517Sgibbs#if defined(_I386_BUS_PIO_H_) 85332517Sgibbs else 85432517Sgibbs#endif 85532517Sgibbs while (count--) 85632517Sgibbs *(volatile u_int32_t *)(addr) = value; 85732517Sgibbs#endif 85832517Sgibbs} 85932517Sgibbs 86032517Sgibbs#if 0 /* Cause a link error for bus_space_set_multi_8 */ 86132517Sgibbs#define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!! 86232517Sgibbs#endif 86332517Sgibbs 86432517Sgibbs/* 86532517Sgibbs * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 86632517Sgibbs * by tag/handle starting at `offset'. 86732517Sgibbs */ 86832517Sgibbs 86932517Sgibbsstatic __inline void bus_space_set_region_1(bus_space_tag_t tag, 87032517Sgibbs bus_space_handle_t bsh, 87132517Sgibbs bus_size_t offset, u_int8_t value, 87232517Sgibbs size_t count); 87332517Sgibbsstatic __inline void bus_space_set_region_2(bus_space_tag_t tag, 87432517Sgibbs bus_space_handle_t bsh, 87532517Sgibbs bus_size_t offset, u_int16_t value, 87632517Sgibbs size_t count); 87732517Sgibbsstatic __inline void bus_space_set_region_4(bus_space_tag_t tag, 87832517Sgibbs bus_space_handle_t bsh, 87932517Sgibbs bus_size_t offset, u_int32_t value, 88032517Sgibbs size_t count); 88132517Sgibbs 88232517Sgibbsstatic __inline void 88332517Sgibbsbus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh, 88432517Sgibbs bus_size_t offset, u_int8_t value, size_t count) 88532517Sgibbs{ 88632517Sgibbs bus_addr_t addr = bsh + offset; 88732517Sgibbs 88832517Sgibbs#if defined(_I386_BUS_PIO_H_) 88932517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 89032517Sgibbs if (tag == I386_BUS_SPACE_IO) 89132517Sgibbs#endif 89232517Sgibbs for (; count != 0; count--, addr++) 89332517Sgibbs outb(addr, value); 89432517Sgibbs#endif 89532517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 89632517Sgibbs#if defined(_I386_BUS_PIO_H_) 89732517Sgibbs else 89832517Sgibbs#endif 89932517Sgibbs for (; count != 0; count--, addr++) 90032517Sgibbs *(volatile u_int8_t *)(addr) = value; 90132517Sgibbs#endif 90232517Sgibbs} 90332517Sgibbs 90432517Sgibbsstatic __inline void 90532517Sgibbsbus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh, 90632517Sgibbs bus_size_t offset, u_int16_t value, size_t count) 90732517Sgibbs{ 90832517Sgibbs bus_addr_t addr = bsh + offset; 90932517Sgibbs 91032517Sgibbs#if defined(_I386_BUS_PIO_H_) 91132517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 91232517Sgibbs if (tag == I386_BUS_SPACE_IO) 91332517Sgibbs#endif 91432517Sgibbs for (; count != 0; count--, addr += 2) 91532517Sgibbs outw(addr, value); 91632517Sgibbs#endif 91732517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 91832517Sgibbs#if defined(_I386_BUS_PIO_H_) 91932517Sgibbs else 92032517Sgibbs#endif 92132517Sgibbs for (; count != 0; count--, addr += 2) 92232517Sgibbs *(volatile u_int16_t *)(addr) = value; 92332517Sgibbs#endif 92432517Sgibbs} 92532517Sgibbs 92632517Sgibbsstatic __inline void 92732517Sgibbsbus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh, 92832517Sgibbs bus_size_t offset, u_int32_t value, size_t count) 92932517Sgibbs{ 93032517Sgibbs bus_addr_t addr = bsh + offset; 93132517Sgibbs 93232517Sgibbs#if defined(_I386_BUS_PIO_H_) 93332517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 93432517Sgibbs if (tag == I386_BUS_SPACE_IO) 93532517Sgibbs#endif 93632517Sgibbs for (; count != 0; count--, addr += 4) 93732517Sgibbs outl(addr, value); 93832517Sgibbs#endif 93932517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 94032517Sgibbs#if defined(_I386_BUS_PIO_H_) 94132517Sgibbs else 94232517Sgibbs#endif 94332517Sgibbs for (; count != 0; count--, addr += 4) 94432517Sgibbs *(volatile u_int32_t *)(addr) = value; 94532517Sgibbs#endif 94632517Sgibbs} 94732517Sgibbs 94832517Sgibbs#if 0 /* Cause a link error for bus_space_set_region_8 */ 94932517Sgibbs#define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!! 95032517Sgibbs#endif 95132517Sgibbs 95232517Sgibbs/* 95332517Sgibbs * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 95432517Sgibbs * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 95532517Sgibbs */ 95632517Sgibbs 95732517Sgibbsstatic __inline void bus_space_copy_region_1(bus_space_tag_t tag, 95832517Sgibbs bus_space_handle_t bsh1, 95932517Sgibbs bus_size_t off1, 96032517Sgibbs bus_space_handle_t bsh2, 96132517Sgibbs bus_size_t off2, size_t count); 96232517Sgibbs 96332517Sgibbsstatic __inline void bus_space_copy_region_2(bus_space_tag_t tag, 96432517Sgibbs bus_space_handle_t bsh1, 96532517Sgibbs bus_size_t off1, 96632517Sgibbs bus_space_handle_t bsh2, 96732517Sgibbs bus_size_t off2, size_t count); 96832517Sgibbs 96932517Sgibbsstatic __inline void bus_space_copy_region_4(bus_space_tag_t tag, 97032517Sgibbs bus_space_handle_t bsh1, 97132517Sgibbs bus_size_t off1, 97232517Sgibbs bus_space_handle_t bsh2, 97332517Sgibbs bus_size_t off2, size_t count); 97432517Sgibbs 97532517Sgibbsstatic __inline void 97632517Sgibbsbus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1, 97732517Sgibbs bus_size_t off1, bus_space_handle_t bsh2, 97832517Sgibbs bus_size_t off2, size_t count) 97932517Sgibbs{ 98032517Sgibbs bus_addr_t addr1 = bsh1 + off1; 98132517Sgibbs bus_addr_t addr2 = bsh2 + off2; 98232517Sgibbs 98332517Sgibbs#if defined(_I386_BUS_PIO_H_) 98432517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 98532517Sgibbs if (tag == I386_BUS_SPACE_IO) 98632517Sgibbs#endif 98732517Sgibbs { 98832517Sgibbs if (addr1 >= addr2) { 98932517Sgibbs /* src after dest: copy forward */ 99032517Sgibbs for (; count != 0; count--, addr1++, addr2++) 99132517Sgibbs outb(addr2, inb(addr1)); 99232517Sgibbs } else { 99332517Sgibbs /* dest after src: copy backwards */ 99432517Sgibbs for (addr1 += (count - 1), addr2 += (count - 1); 99532517Sgibbs count != 0; count--, addr1--, addr2--) 99632517Sgibbs outb(addr2, inb(addr1)); 99732517Sgibbs } 99832517Sgibbs } 99932517Sgibbs#endif 100032517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 100132517Sgibbs#if defined(_I386_BUS_PIO_H_) 100232517Sgibbs else 100332517Sgibbs#endif 100432517Sgibbs { 100532517Sgibbs if (addr1 >= addr2) { 100632517Sgibbs /* src after dest: copy forward */ 100732517Sgibbs for (; count != 0; count--, addr1++, addr2++) 100832517Sgibbs *(volatile u_int8_t *)(addr2) = 100932517Sgibbs *(volatile u_int8_t *)(addr1); 101032517Sgibbs } else { 101132517Sgibbs /* dest after src: copy backwards */ 101232517Sgibbs for (addr1 += (count - 1), addr2 += (count - 1); 101332517Sgibbs count != 0; count--, addr1--, addr2--) 101432517Sgibbs *(volatile u_int8_t *)(addr2) = 101532517Sgibbs *(volatile u_int8_t *)(addr1); 101632517Sgibbs } 101732517Sgibbs } 101832517Sgibbs#endif 101932517Sgibbs} 102032517Sgibbs 102132517Sgibbsstatic __inline void 102232517Sgibbsbus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1, 102332517Sgibbs bus_size_t off1, bus_space_handle_t bsh2, 102432517Sgibbs bus_size_t off2, size_t count) 102532517Sgibbs{ 102632517Sgibbs bus_addr_t addr1 = bsh1 + off1; 102732517Sgibbs bus_addr_t addr2 = bsh2 + off2; 102832517Sgibbs 102932517Sgibbs#if defined(_I386_BUS_PIO_H_) 103032517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 103132517Sgibbs if (tag == I386_BUS_SPACE_IO) 103232517Sgibbs#endif 103332517Sgibbs { 103432517Sgibbs if (addr1 >= addr2) { 103532517Sgibbs /* src after dest: copy forward */ 103632517Sgibbs for (; count != 0; count--, addr1 += 2, addr2 += 2) 103732517Sgibbs outw(addr2, inw(addr1)); 103832517Sgibbs } else { 103932517Sgibbs /* dest after src: copy backwards */ 104032517Sgibbs for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); 104132517Sgibbs count != 0; count--, addr1 -= 2, addr2 -= 2) 104232517Sgibbs outw(addr2, inw(addr1)); 104332517Sgibbs } 104432517Sgibbs } 104532517Sgibbs#endif 104632517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 104732517Sgibbs#if defined(_I386_BUS_PIO_H_) 104832517Sgibbs else 104932517Sgibbs#endif 105032517Sgibbs { 105132517Sgibbs if (addr1 >= addr2) { 105232517Sgibbs /* src after dest: copy forward */ 105332517Sgibbs for (; count != 0; count--, addr1 += 2, addr2 += 2) 105432517Sgibbs *(volatile u_int16_t *)(addr2) = 105532517Sgibbs *(volatile u_int16_t *)(addr1); 105632517Sgibbs } else { 105732517Sgibbs /* dest after src: copy backwards */ 105832517Sgibbs for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); 105932517Sgibbs count != 0; count--, addr1 -= 2, addr2 -= 2) 106032517Sgibbs *(volatile u_int16_t *)(addr2) = 106132517Sgibbs *(volatile u_int16_t *)(addr1); 106232517Sgibbs } 106332517Sgibbs } 106432517Sgibbs#endif 106532517Sgibbs} 106632517Sgibbs 106732517Sgibbsstatic __inline void 106832517Sgibbsbus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1, 106932517Sgibbs bus_size_t off1, bus_space_handle_t bsh2, 107032517Sgibbs bus_size_t off2, size_t count) 107132517Sgibbs{ 107232517Sgibbs bus_addr_t addr1 = bsh1 + off1; 107332517Sgibbs bus_addr_t addr2 = bsh2 + off2; 107432517Sgibbs 107532517Sgibbs#if defined(_I386_BUS_PIO_H_) 107632517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 107732517Sgibbs if (tag == I386_BUS_SPACE_IO) 107832517Sgibbs#endif 107932517Sgibbs { 108032517Sgibbs if (addr1 >= addr2) { 108132517Sgibbs /* src after dest: copy forward */ 108232517Sgibbs for (; count != 0; count--, addr1 += 4, addr2 += 4) 108332517Sgibbs outl(addr2, inl(addr1)); 108432517Sgibbs } else { 108532517Sgibbs /* dest after src: copy backwards */ 108632517Sgibbs for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); 108732517Sgibbs count != 0; count--, addr1 -= 4, addr2 -= 4) 108832517Sgibbs outl(addr2, inl(addr1)); 108932517Sgibbs } 109032517Sgibbs } 109132517Sgibbs#endif 109232517Sgibbs#if defined(_I386_BUS_MEMIO_H_) 109332517Sgibbs#if defined(_I386_BUS_PIO_H_) 109432517Sgibbs else 109532517Sgibbs#endif 109632517Sgibbs { 109732517Sgibbs if (addr1 >= addr2) { 109832517Sgibbs /* src after dest: copy forward */ 109932517Sgibbs for (; count != 0; count--, addr1 += 4, addr2 += 4) 110032517Sgibbs *(volatile u_int32_t *)(addr2) = 110132517Sgibbs *(volatile u_int32_t *)(addr1); 110232517Sgibbs } else { 110332517Sgibbs /* dest after src: copy backwards */ 110432517Sgibbs for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); 110532517Sgibbs count != 0; count--, addr1 -= 4, addr2 -= 4) 110632517Sgibbs *(volatile u_int32_t *)(addr2) = 110732517Sgibbs *(volatile u_int32_t *)(addr1); 110832517Sgibbs } 110932517Sgibbs } 111032517Sgibbs#endif 111132517Sgibbs} 111232517Sgibbs 111332517Sgibbs#endif /* defined(_I386_BUS_PIO_H_) || defined(_I386_MEM_IO_H_) */ 111432517Sgibbs 111532517Sgibbs#if 0 /* Cause a link error for bus_space_copy_8 */ 111632517Sgibbs#define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!! 111732517Sgibbs#endif 111832517Sgibbs 111932517Sgibbs/* 112032517Sgibbs * Bus read/write barrier methods. 112132517Sgibbs * 112232517Sgibbs * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, 112332517Sgibbs * bus_size_t offset, bus_size_t len, int flags); 112432517Sgibbs * 112532517Sgibbs * Note: the i386 does not currently require barriers, but we must 112632517Sgibbs * provide the flags to MI code. 112732517Sgibbs */ 112832517Sgibbs#define bus_space_barrier(t, h, o, l, f) \ 112932517Sgibbs ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f))) 113032517Sgibbs#define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */ 113132517Sgibbs#define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */ 113232517Sgibbs 113332517Sgibbs/* 113432517Sgibbs * Flags used in various bus DMA methods. 113532517Sgibbs */ 113632517Sgibbs#define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */ 113732517Sgibbs#define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */ 113832517Sgibbs#define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */ 113932517Sgibbs#define BUS_DMAMEM_NOSYNC 0x04 /* map memory to not require sync */ 114032517Sgibbs#define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */ 114132517Sgibbs#define BUS_DMA_BUS2 0x20 114232517Sgibbs#define BUS_DMA_BUS3 0x40 114332517Sgibbs#define BUS_DMA_BUS4 0x80 114432517Sgibbs 114532517Sgibbs/* Forwards needed by prototypes below. */ 114632517Sgibbsstruct mbuf; 114732517Sgibbsstruct uio; 114832517Sgibbs 114932517Sgibbs/* 115032517Sgibbs * bus_dmasync_op_t 115132517Sgibbs * 115232517Sgibbs * Operations performed by bus_dmamap_sync(). 115332517Sgibbs */ 115432517Sgibbstypedef enum { 115532517Sgibbs BUS_DMASYNC_PREREAD, 115632517Sgibbs BUS_DMASYNC_POSTREAD, 115732517Sgibbs BUS_DMASYNC_PREWRITE, 115832517Sgibbs BUS_DMASYNC_POSTWRITE, 115932517Sgibbs} bus_dmasync_op_t; 116032517Sgibbs 116132517Sgibbs/* 116232517Sgibbs * bus_dma_tag_t 116332517Sgibbs * 116432517Sgibbs * A machine-dependent opaque type describing the characteristics 116532517Sgibbs * of how to perform DMA mappings. This structure encapsultes 116632517Sgibbs * information concerning address and alignment restrictions, number 116732517Sgibbs * of S/G segments, amount of data per S/G segment, etc. 116832517Sgibbs */ 116932517Sgibbstypedef struct bus_dma_tag *bus_dma_tag_t; 117032517Sgibbs 117132517Sgibbs/* 117232517Sgibbs * bus_dmamap_t 117332517Sgibbs * 117432517Sgibbs * DMA mapping instance information. 117532517Sgibbs */ 117632517Sgibbstypedef struct bus_dmamap *bus_dmamap_t; 117732517Sgibbs 117832517Sgibbs/* 117932517Sgibbs * bus_dma_segment_t 118032517Sgibbs * 118132517Sgibbs * Describes a single contiguous DMA transaction. Values 118232517Sgibbs * are suitable for programming into DMA registers. 118332517Sgibbs */ 118432517Sgibbstypedef struct bus_dma_segment { 118532517Sgibbs bus_addr_t ds_addr; /* DMA address */ 118632517Sgibbs bus_size_t ds_len; /* length of transfer */ 118732517Sgibbs} bus_dma_segment_t; 118832517Sgibbs 118932517Sgibbs/* 119032517Sgibbs * A function that returns 1 if the address cannot be accessed by 119132517Sgibbs * a device and 0 if it can be. 119232517Sgibbs */ 119332517Sgibbstypedef int bus_dma_filter_t(void *, bus_addr_t); 119432517Sgibbs 119532517Sgibbs/* 119632517Sgibbs * Allocate a device specific dma_tag encapsulating the constraints of 119732517Sgibbs * the parent tag in addition to other restrictions specified: 119832517Sgibbs * 119932517Sgibbs * boundary: Boundary that segments cannot cross. 120032517Sgibbs * lowaddr: Low restricted address that cannot appear in a mapping. 120132517Sgibbs * highaddr: High restricted address that cannot appear in a mapping. 120232517Sgibbs * filtfunc: An optional function to further test if an address 120332517Sgibbs * within the range of lowaddr and highaddr cannot appear 120432517Sgibbs * in a mapping. 120532517Sgibbs * filtfuncarg: An argument that will be passed to filtfunc in addition 120632517Sgibbs * to the address to test. 120732517Sgibbs * flags: Bus DMA flags. 120832517Sgibbs * dmat: A pointer to set to a valid dma tag should the return 120932517Sgibbs * value of this function indicate success. 121032517Sgibbs */ 121132517Sgibbsint bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t boundary, 121232517Sgibbs bus_addr_t lowaddr, bus_addr_t highaddr, 121332517Sgibbs bus_dma_filter_t *filtfunc, void *filtfuncarg, 121432517Sgibbs bus_size_t maxsize, int nsegments, bus_size_t maxsegsz, 121532517Sgibbs int flags, bus_dma_tag_t *dmat); 121632517Sgibbs 121732517Sgibbsint bus_dma_tag_destroy(bus_dma_tag_t dmat); 121832517Sgibbs 121932517Sgibbs/* 122032517Sgibbs * Allocate a handle for mapping from kva/uva/physical 122132517Sgibbs * address space into bus device space. 122232517Sgibbs * 122332517Sgibbs * maxsize: Maximum mapping size supported by this handle. 122432517Sgibbs * nsegments: Number of discontinuities allowed in the map. 122532517Sgibbs * maxsegsz: Maximum size of a segment in the map. 122632517Sgibbs */ 122732517Sgibbsint bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp); 122832517Sgibbs 122932517Sgibbs/* 123032517Sgibbs * Destroy a handle for mapping from kva/uva/physical 123132517Sgibbs * address space into bus device space. 123232517Sgibbs */ 123332517Sgibbsint bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map); 123432517Sgibbs 123532517Sgibbs/* 123632517Sgibbs * A function that processes a successfully loaded dma map or an error 123732517Sgibbs * from a delayed load map. 123832517Sgibbs */ 123932517Sgibbstypedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); 124032517Sgibbs 124132517Sgibbs/* 124232517Sgibbs * Map the buffer buf into bus space using the dmamap map. 124332517Sgibbs */ 124432517Sgibbsint bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 124532517Sgibbs bus_size_t buflen, bus_dmamap_callback_t *callback, 124632517Sgibbs void *callback_arg, int flags); 124732517Sgibbs 124832517Sgibbs/* 124932517Sgibbs * Perform a syncronization operation on the given map. 125032517Sgibbs */ 125132517Sgibbsvoid _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t); 125232517Sgibbs#define bus_dmamap_sync(dmat, dmamap, op) \ 125332517Sgibbs if ((dmamap) != NULL) \ 125432517Sgibbs _bus_dmamap_sync(dmat, dmamap, op) 125532517Sgibbs 125632517Sgibbs/* 125732517Sgibbs * Release the mapping held by map. 125832517Sgibbs */ 125932517Sgibbsvoid _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map); 126032517Sgibbs#define bus_dmamap_unload(dmat, dmamap) \ 126132517Sgibbs if ((dmamap) != NULL) \ 126232517Sgibbs _bus_dmamap_unload(dmat, dmamap) 126332517Sgibbs 126432517Sgibbs#endif /* _I386_BUS_H_ */ 1265