1 /* $NetBSD: isa_io.c,v 1.12 2018/03/16 17:56:33 ryo Exp $ */ 2 3 /* 4 * Copyright 1997 5 * Digital Equipment Corporation. All rights reserved. 6 * 7 * This software is furnished under license and may be used and 8 * copied only in accordance with the following terms and conditions. 9 * Subject to these conditions, you may download, copy, install, 10 * use, modify and distribute this software in source and/or binary 11 * form. No title or ownership is transferred hereby. 12 * 13 * 1) Any source code used, modified or distributed must reproduce 14 * and retain this copyright notice and list of conditions as 15 * they appear in the source file. 16 * 17 * 2) No right is granted to use any trade name, trademark, or logo of 18 * Digital Equipment Corporation. Neither the "Digital Equipment 19 * Corporation" name nor any trademark or logo of Digital Equipment 20 * Corporation may be used to endorse or promote products derived 21 * from this software without the prior written permission of 22 * Digital Equipment Corporation. 23 * 24 * 3) This software is provided "AS-IS" and any express or implied 25 * warranties, including but not limited to, any implied warranties 26 * of merchantability, fitness for a particular purpose, or 27 * non-infringement are disclaimed. In no event shall DIGITAL be 28 * liable for any damages whatsoever, and in particular, DIGITAL 29 * shall not be liable for special, indirect, consequential, or 30 * incidental damages or damages for lost profits, loss of 31 * revenue or loss of use, whether such damages arise in contract, 32 * negligence, tort, under statute, in equity, at law or otherwise, 33 * even if advised of the possibility of such damage. 34 */ 35 36 /* 37 * bus_space I/O functions for isa 38 */ 39 40 #include <sys/cdefs.h> 41 __KERNEL_RCSID(0, "$NetBSD: isa_io.c,v 1.12 2018/03/16 17:56:33 ryo Exp $"); 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/malloc.h> 46 #include <sys/extent.h> 47 #include <sys/bus.h> 48 #include <machine/pio.h> 49 #include <machine/isa_machdep.h> 50 51 /* Proto types for all the bus_space structure functions */ 52 53 bs_protos(isa); 54 bs_protos(bs_notimpl); 55 void isa_bs_mallocok(void); 56 57 /* 58 * Declare the isa bus space tags 59 * The IO and MEM structs are identical, except for the cookies, 60 * which contain the address space bases. 61 */ 62 63 /* 64 * NOTE: ASSEMBLY LANGUAGE RELIES ON THE COOKIE -- THE FIRST MEMBER OF 65 * THIS STRUCTURE -- TO BE THE VIRTUAL ADDRESS OF 16 BIT ISA/IO! 66 */ 67 struct bus_space isa_io_bs_tag = { 68 /* cookie */ 69 .bs_cookie = NULL, /* initialized below */ 70 71 /* mapping/unmapping */ 72 .bs_map = isa_bs_map, 73 .bs_unmap = isa_bs_unmap, 74 .bs_subregion = isa_bs_subregion, 75 76 /* allocation/deallocation */ 77 .bs_alloc = isa_bs_alloc, 78 .bs_free = isa_bs_free, 79 80 /* get kernel virtual address */ 81 .bs_vaddr = isa_bs_vaddr, 82 83 /* mmap bus space for userland */ 84 .bs_mmap = bs_notimpl_bs_mmap, /* XXX possible even? XXX */ 85 86 /* barrier */ 87 .bs_barrier = isa_bs_barrier, 88 89 /* read (single) */ 90 .bs_r_1 = isa_bs_r_1, 91 .bs_r_2 = isa_bs_r_2, 92 .bs_r_4 = isa_bs_r_4, 93 .bs_r_8 = bs_notimpl_bs_r_8, 94 95 /* read multiple */ 96 .bs_rm_1 = isa_bs_rm_1, 97 .bs_rm_2 = isa_bs_rm_2, 98 .bs_rm_4 = isa_bs_rm_4, 99 .bs_rm_8 = bs_notimpl_bs_rm_8, 100 101 /* read region */ 102 .bs_rr_1 = isa_bs_rr_1, 103 .bs_rr_2 = isa_bs_rr_2, 104 .bs_rr_4 = isa_bs_rr_4, 105 .bs_rr_8 = bs_notimpl_bs_rr_8, 106 107 /* write (single) */ 108 .bs_w_1 = isa_bs_w_1, 109 .bs_w_2 = isa_bs_w_2, 110 .bs_w_4 = isa_bs_w_4, 111 .bs_w_8 = bs_notimpl_bs_w_8, 112 113 /* write multiple */ 114 .bs_wm_1 = isa_bs_wm_1, 115 .bs_wm_2 = isa_bs_wm_2, 116 .bs_wm_4 = isa_bs_wm_4, 117 .bs_wm_8 = bs_notimpl_bs_wm_8, 118 119 /* write region */ 120 .bs_wr_1 = isa_bs_wr_1, 121 .bs_wr_2 = isa_bs_wr_2, 122 .bs_wr_4 = isa_bs_wr_4, 123 .bs_wr_8 = bs_notimpl_bs_wr_8, 124 125 /* set multiple */ 126 .bs_sm_1 = bs_notimpl_bs_sm_1, 127 .bs_sm_2 = bs_notimpl_bs_sm_2, 128 .bs_sm_4 = bs_notimpl_bs_sm_4, 129 .bs_sm_8 = bs_notimpl_bs_sm_8, 130 131 /* set region */ 132 .bs_sr_1 = bs_notimpl_bs_sr_1, 133 .bs_sr_2 = isa_bs_sr_2, 134 .bs_sr_4 = bs_notimpl_bs_sr_4, 135 .bs_sr_8 = bs_notimpl_bs_sr_8, 136 137 /* copy */ 138 .bs_c_1 = bs_notimpl_bs_c_1, 139 .bs_c_2 = bs_notimpl_bs_c_2, 140 .bs_c_4 = bs_notimpl_bs_c_4, 141 .bs_c_8 = bs_notimpl_bs_c_8, 142 }; 143 144 /* 145 * NOTE: ASSEMBLY LANGUAGE RELIES ON THE COOKIE -- THE FIRST MEMBER OF 146 * THIS STRUCTURE -- TO BE THE VIRTUAL ADDRESS OF ISA/MEMORY! 147 */ 148 struct bus_space isa_mem_bs_tag = { 149 /* cookie */ 150 .bs_cookie = NULL, /* initialized below */ 151 152 /* mapping/unmapping */ 153 .bs_map = isa_bs_map, 154 .bs_unmap = isa_bs_unmap, 155 .bs_subregion = isa_bs_subregion, 156 157 /* allocation/deallocation */ 158 .bs_alloc = isa_bs_alloc, 159 .bs_free = isa_bs_free, 160 161 /* get kernel virtual address */ 162 .bs_vaddr = isa_bs_vaddr, 163 164 /* mmap bus space for userland */ 165 .bs_mmap = bs_notimpl_bs_mmap, /* XXX open for now ... XXX */ 166 167 /* barrier */ 168 .bs_barrier = isa_bs_barrier, 169 170 /* read (single) */ 171 .bs_r_1 = isa_bs_r_1, 172 .bs_r_2 = isa_bs_r_2, 173 .bs_r_4 = isa_bs_r_4, 174 .bs_r_8 = bs_notimpl_bs_r_8, 175 176 /* read multiple */ 177 .bs_rm_1 = isa_bs_rm_1, 178 .bs_rm_2 = isa_bs_rm_2, 179 .bs_rm_4 = isa_bs_rm_4, 180 .bs_rm_8 = bs_notimpl_bs_rm_8, 181 182 /* read region */ 183 .bs_rr_1 = isa_bs_rr_1, 184 .bs_rr_2 = isa_bs_rr_2, 185 .bs_rr_4 = isa_bs_rr_4, 186 .bs_rr_8 = bs_notimpl_bs_rr_8, 187 188 /* write (single) */ 189 .bs_w_1 = isa_bs_w_1, 190 .bs_w_2 = isa_bs_w_2, 191 .bs_w_4 = isa_bs_w_4, 192 .bs_w_8 = bs_notimpl_bs_w_8, 193 194 /* write multiple */ 195 .bs_wm_1 = isa_bs_wm_1, 196 .bs_wm_2 = isa_bs_wm_2, 197 .bs_wm_4 = isa_bs_wm_4, 198 .bs_wm_8 = bs_notimpl_bs_wm_8, 199 200 /* write region */ 201 .bs_wr_1 = isa_bs_wr_1, 202 .bs_wr_2 = isa_bs_wr_2, 203 .bs_wr_4 = isa_bs_wr_4, 204 .bs_wr_8 = bs_notimpl_bs_wr_8, 205 206 /* set multiple */ 207 .bs_sm_1 = bs_notimpl_bs_sm_1, 208 .bs_sm_2 = bs_notimpl_bs_sm_2, 209 .bs_sm_4 = bs_notimpl_bs_sm_4, 210 .bs_sm_8 = bs_notimpl_bs_sm_8, 211 212 /* set region */ 213 .bs_sr_1 = bs_notimpl_bs_sr_1, 214 .bs_sr_2 = isa_bs_sr_2, 215 .bs_sr_4 = bs_notimpl_bs_sr_4, 216 .bs_sr_8 = bs_notimpl_bs_sr_8, 217 218 /* copy */ 219 .bs_c_1 = bs_notimpl_bs_c_1, 220 .bs_c_2 = bs_notimpl_bs_c_2, 221 .bs_c_4 = bs_notimpl_bs_c_4, 222 .bs_c_8 = bs_notimpl_bs_c_8, 223 }; 224 225 static long isaio_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 226 static long isamem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)]; 227 static int malloc_safe = 0; 228 struct extent *isaio_ex; 229 struct extent *isamem_ex; 230 231 void 232 isa_bs_mallocok(void) 233 { 234 malloc_safe = 1; 235 } 236 237 /* bus space functions */ 238 239 void 240 isa_io_init(vaddr_t isa_io_addr, vaddr_t isa_mem_addr) 241 { 242 isa_io_bs_tag.bs_cookie = (void *)isa_io_addr; 243 isa_mem_bs_tag.bs_cookie = (void *)isa_mem_addr; 244 245 isaio_ex = extent_create("isaio", 0x0, 0xffff, 246 (void *)isaio_ex_storage, sizeof(isaio_ex_storage), 247 EX_NOWAIT|EX_NOCOALESCE); 248 isamem_ex = extent_create("isamem", 0x0, 0xfffff, 249 (void *)isamem_ex_storage, sizeof(isamem_ex_storage), 250 EX_NOWAIT|EX_NOCOALESCE); 251 if (isaio_ex == NULL || isamem_ex == NULL) 252 panic("isa_io_init(): can't alloc extent maps"); 253 } 254 255 /* 256 * break the abstraction: sometimes, other parts of the system 257 * (e.g. X servers) need to map ISA space directly. use these 258 * functions sparingly! 259 */ 260 vaddr_t 261 isa_io_data_vaddr(void) 262 { 263 return (vaddr_t)isa_io_bs_tag.bs_cookie; 264 } 265 266 vaddr_t 267 isa_mem_data_vaddr(void) 268 { 269 return (vaddr_t)isa_mem_bs_tag.bs_cookie; 270 } 271 272 int 273 isa_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int cacheable, bus_space_handle_t *bshp) 274 { 275 struct extent *ex; 276 int err; 277 278 if (t == isa_io_bs_tag.bs_cookie) 279 ex = isaio_ex; 280 else 281 ex = isamem_ex; 282 283 err = extent_alloc_region(ex, bpa, size, 284 EX_NOWAIT|(malloc_safe ? EX_MALLOCOK : 0)); 285 if (err) 286 return err; 287 288 *bshp = bpa + (bus_addr_t)t; 289 return(0); 290 } 291 292 void 293 isa_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size) 294 { 295 isa_bs_free(t, bsh, size); 296 } 297 298 int 299 isa_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp) 300 { 301 *nbshp = bsh + offset; 302 return(0); 303 } 304 305 int 306 isa_bs_alloc( 307 void *t, 308 bus_addr_t rstart, 309 bus_addr_t rend, 310 bus_size_t size, 311 bus_size_t alignment, 312 bus_size_t boundary, 313 int cacheable, 314 bus_addr_t *bpap, 315 bus_space_handle_t *bshp) 316 { 317 struct extent *ex; 318 u_long bpa; 319 int err; 320 321 if (t == isa_io_bs_tag.bs_cookie) 322 ex = isaio_ex; 323 else 324 ex = isamem_ex; 325 326 err = extent_alloc_subregion(ex, rstart, rend, size, alignment, 327 boundary, (EX_FAST|EX_NOWAIT|(malloc_safe ? EX_MALLOCOK : 0)), 328 &bpa); 329 330 if (err) 331 return err; 332 333 *bshp = *bpap = bpa + (bus_addr_t)t; 334 return 0; 335 } 336 337 void 338 isa_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size) 339 { 340 struct extent *ex; 341 342 if (t == isa_io_bs_tag.bs_cookie) 343 ex = isaio_ex; 344 else 345 ex = isamem_ex; 346 347 extent_free(ex, bsh - (bus_addr_t)t, size, 348 EX_NOWAIT|(malloc_safe ? EX_MALLOCOK : 0)); 349 } 350 351 void * 352 isa_bs_vaddr(void *t, bus_space_handle_t bsh) 353 { 354 355 return ((void *)bsh); 356 } 357 358 void 359 isa_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset, bus_size_t len, int flags) 360 { 361 /* just return */ 362 } 363