busiosubr.c revision 120375
1240135Skib/* $FreeBSD: head/sys/pc98/pc98/busiosubr.c 120375 2003-09-23 08:22:34Z nyan $ */ 2257491Skib/* $NecBSD: busiosubr.c,v 1.30.4.4 1999/08/28 02:25:35 honda Exp $ */ 3254147Sobrien/* $NetBSD$ */ 4240135Skib 5240135Skib/* 6240135Skib * [NetBSD for NEC PC-98 series] 7257491Skib * Copyright (c) 1996, 1997, 1998 8257491Skib * NetBSD/pc98 porting staff. All rights reserved. 9257491Skib * 10240135Skib * [Ported for FreeBSD] 11240135Skib * Copyright (c) 2001 12240135Skib * TAKAHASHI Yoshihiro. All rights reserved. 13240135Skib * 14240135Skib * Redistribution and use in source and binary forms, with or without 15240135Skib * modification, are permitted provided that the following conditions 16240135Skib * are met: 17240135Skib * 1. Redistributions of source code must retain the above copyright 18240135Skib * notice, this list of conditions and the following disclaimer. 19240135Skib * 2. Redistributions in binary form must reproduce the above copyright 20240135Skib * notice, this list of conditions and the following disclaimer in the 21240135Skib * documentation and/or other materials provided with the distribution. 22240135Skib * 3. The name of the author may not be used to endorse or promote products 23240135Skib * derived from this software without specific prior written permission. 24240135Skib * 25240135Skib * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 26240135Skib * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27240135Skib * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28240135Skib * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 29240135Skib * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30240135Skib * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31240135Skib * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32240135Skib * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33240135Skib * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34240135Skib * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35240135Skib * POSSIBILITY OF SUCH DAMAGE. 36240135Skib */ 37254147Sobrien 38240135Skib/* 39256381Smarkm * Copyright (c) 1997, 1998 40254147Sobrien * Naofumi HONDA. All rights reserved. 41256381Smarkm */ 42240135Skib 43240135Skib#include <sys/param.h> 44254147Sobrien#include <sys/systm.h> 45254147Sobrien#include <sys/kernel.h> 46254147Sobrien#include <sys/malloc.h> 47254147Sobrien#include <machine/bus.h> 48256381Smarkm 49256381Smarkmstatic MALLOC_DEFINE(M_BUSSPACEHANDLE, "busspacehandle", "Bus space handle"); 50256381Smarkm 51256381Smarkm_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int8_t,1) 52254147Sobrien_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int16_t,2) 53240135Skib_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_io,u_int32_t,4) 54240135Skib_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int8_t,1) 55240135Skib_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int16_t,2) 56240135Skib_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_DA_mem,u_int32_t,4) 57240135Skib 58256381Smarkm_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int8_t,1) 59268519Sdelphij_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int16_t,2) 60256381Smarkm_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_io,u_int32_t,4) 61256381Smarkm_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int8_t,1) 62240135Skib_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int16_t,2) 63240135Skib_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int32_t,4) 64240135Skib 65257491Skibstruct bus_space_tag SBUS_io_space_tag = { 66240135Skib BUS_SPACE_IO, 67240135Skib 68257491Skib /* direct bus access methods */ 69257491Skib { 70240135Skib _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int8_t,1), 71257491Skib _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int16_t,2), 72240135Skib _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int32_t,4), 73257491Skib }, 74257491Skib 75257491Skib /* relocate bus access methods */ 76257491Skib { 77257491Skib _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int8_t,1), 78257491Skib _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int16_t,2), 79257491Skib _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int32_t,4), 80257491Skib } 81257491Skib}; 82257491Skib 83257491Skibstruct bus_space_tag SBUS_mem_space_tag = { 84240135Skib BUS_SPACE_MEM, 85240135Skib 86240135Skib /* direct bus access methods */ 87240135Skib { 88240135Skib _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int8_t,1), 89240135Skib _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int16_t,2), 90240135Skib _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int32_t,4), 91240135Skib }, 92257491Skib 93257491Skib /* relocate bus access methods */ 94240135Skib { 95257491Skib _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int8_t,1), 96257491Skib _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int16_t,2), 97257491Skib _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int32_t,4), 98240135Skib } 99240135Skib}; 100240135Skib 101240135Skib 102240135Skib#include "opt_mecia.h" 103254147Sobrien#ifdef DEV_MECIA 104254147Sobrien 105254147Sobrien_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_DA_io,u_int16_t,2) 106256381Smarkm_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_DA_io,u_int32_t,4) 107254147Sobrien 108254147Sobrien_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_RA_io,u_int16_t,2) 109254147Sobrien_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_RA_io,u_int32_t,4) 110256381Smarkm 111256381Smarkmstruct bus_space_tag NEPC_io_space_tag = { 112256381Smarkm BUS_SPACE_IO, 113254147Sobrien 114254147Sobrien /* direct bus access methods */ 115240135Skib { 116256381Smarkm _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_io,u_int8_t,1), 117254147Sobrien _BUS_SPACE_CALL_FUNCS_TAB(NEPC_DA_io,u_int16_t,2), 118256381Smarkm _BUS_SPACE_CALL_FUNCS_TAB(NEPC_DA_io,u_int32_t,4), 119256381Smarkm }, 120256381Smarkm 121256381Smarkm /* relocate bus access methods */ 122256381Smarkm { 123256381Smarkm _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_io,u_int8_t,1), 124256381Smarkm _BUS_SPACE_CALL_FUNCS_TAB(NEPC_RA_io,u_int16_t,2), 125256381Smarkm _BUS_SPACE_CALL_FUNCS_TAB(NEPC_RA_io,u_int32_t,4), 126256381Smarkm } 127256381Smarkm}; 128256381Smarkm 129256381Smarkmstruct bus_space_tag NEPC_mem_space_tag = { 130256381Smarkm BUS_SPACE_MEM, 131256381Smarkm 132254147Sobrien /* direct bus access methods */ 133254147Sobrien { 134256381Smarkm _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int8_t,1), 135254147Sobrien _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int16_t,2), 136254147Sobrien _BUS_SPACE_CALL_FUNCS_TAB(SBUS_DA_mem,u_int32_t,4), 137256381Smarkm }, 138 139 /* relocate bus access methods */ 140 { 141 _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int8_t,1), 142 _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int16_t,2), 143 _BUS_SPACE_CALL_FUNCS_TAB(SBUS_RA_mem,u_int32_t,4), 144 } 145}; 146 147#endif /* DEV_MECIA */ 148 149/************************************************************************* 150 * map init 151 *************************************************************************/ 152static __inline void 153bus_space_iat_init(bus_space_handle_t bsh) 154{ 155 int i; 156 157 for (i = 0; i < bsh->bsh_maxiatsz; i++) 158 bsh->bsh_iat[i] = bsh->bsh_base + i; 159} 160 161/************************************************************************* 162 * handle allocation 163 *************************************************************************/ 164int 165i386_bus_space_handle_alloc(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, 166 bus_space_handle_t *bshp) 167{ 168 bus_space_handle_t bsh; 169 170 bsh = (bus_space_handle_t) malloc(sizeof (*bsh), M_BUSSPACEHANDLE, 171 M_NOWAIT | M_ZERO); 172 if (bsh == NULL) 173 return ENOMEM; 174 175 bsh->bsh_maxiatsz = BUS_SPACE_IAT_MAXSIZE; 176 bsh->bsh_iatsz = 0; 177 bsh->bsh_base = bpa; 178 bsh->bsh_sz = size; 179 bsh->bsh_res = NULL; 180 bsh->bsh_ressz = 0; 181 bus_space_iat_init(bsh); 182 183 bsh->bsh_bam = t->bs_da; /* default: direct access */ 184 185 *bshp = bsh; 186 return 0; 187} 188 189void 190i386_bus_space_handle_free(bus_space_tag_t t, bus_space_handle_t bsh, 191 size_t size) 192{ 193 194 free(bsh, M_BUSSPACEHANDLE); 195} 196 197/************************************************************************* 198 * map 199 *************************************************************************/ 200int 201i386_memio_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags, 202 bus_space_handle_t *bshp) 203{ 204 205 return i386_bus_space_handle_alloc(t, bpa, size, bshp); 206} 207 208void 209i386_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size) 210{ 211 212 i386_bus_space_handle_free(t, bsh, bsh->bsh_sz); 213} 214 215void 216i386_memio_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size) 217{ 218 219 /* i386_memio_unmap() does all that we need to do. */ 220 i386_memio_unmap(t, bsh, bsh->bsh_sz); 221} 222 223int 224i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t pbsh, 225 bus_size_t offset, bus_size_t size, 226 bus_space_handle_t *tbshp) 227{ 228 int i, error = 0; 229 bus_space_handle_t bsh; 230 bus_addr_t pbase; 231 232 pbase = pbsh->bsh_base + offset; 233 switch (t->bs_tag) { 234 case BUS_SPACE_IO: 235 if (pbsh->bsh_iatsz > 0) { 236 if (offset >= pbsh->bsh_iatsz || 237 offset + size > pbsh->bsh_iatsz) 238 return EINVAL; 239 pbase = pbsh->bsh_base; 240 } 241 break; 242 243 case BUS_SPACE_MEM: 244 if (pbsh->bsh_iatsz > 0) 245 return EINVAL; 246 if (offset > pbsh->bsh_sz || offset + size > pbsh->bsh_sz) 247 return EINVAL; 248 break; 249 250 default: 251 panic("i386_memio_subregion: bad bus space tag"); 252 break; 253 } 254 255 error = i386_bus_space_handle_alloc(t, pbase, size, &bsh); 256 if (error != 0) 257 return error; 258 259 switch (t->bs_tag) { 260 case BUS_SPACE_IO: 261 if (pbsh->bsh_iatsz > 0) { 262 for (i = 0; i < size; i ++) 263 bsh->bsh_iat[i] = pbsh->bsh_iat[i + offset]; 264 bsh->bsh_iatsz = size; 265 } else if (pbsh->bsh_base > bsh->bsh_base || 266 pbsh->bsh_base + pbsh->bsh_sz < 267 bsh->bsh_base + bsh->bsh_sz) { 268 i386_bus_space_handle_free(t, bsh, size); 269 return EINVAL; 270 } 271 break; 272 273 case BUS_SPACE_MEM: 274 break; 275 } 276 277 if (pbsh->bsh_iatsz > 0) 278 bsh->bsh_bam = t->bs_ra; /* relocate access */ 279 *tbshp = bsh; 280 return error; 281} 282