1 /* $NetBSD: isa_io.c,v 1.15 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.15 2018/03/16 17:56:33 ryo Exp $"); 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/bus.h> 46 #include <uvm/uvm.h> 47 #include <machine/pio.h> 48 #include <machine/isa_machdep.h> 49 #include <machine/ofw.h> 50 #include <machine/pmap.h> 51 #include "igsfb_ofbus.h" 52 #include "chipsfb_ofbus.h" 53 54 #if NIGSFB_OFBUS > 0 55 extern vaddr_t igsfb_mem_vaddr, igsfb_mmio_vaddr; 56 extern paddr_t igsfb_mem_paddr; 57 #endif 58 59 #if NCHIPSFB_OFBUS > 0 60 extern vaddr_t chipsfb_mem_vaddr, chipsfb_mmio_vaddr; 61 extern paddr_t chipsfb_mem_paddr; 62 #endif 63 64 /* Proto types for all the bus_space structure functions */ 65 66 bs_protos(isa); 67 bs_protos(bs_notimpl); 68 69 /* 70 * Declare the isa bus space tags 71 * The IO and MEM structs are identical, except for the cookies, 72 * which contain the address space bases. 73 */ 74 75 /* 76 * NOTE: ASSEMBLY LANGUAGE RELIES ON THE COOKIE -- THE FIRST MEMBER OF 77 * THIS STRUCTURE -- TO BE THE VIRTUAL ADDRESS OF ISA/IO! 78 */ 79 struct bus_space isa_io_bs_tag = { 80 /* cookie */ 81 .bs_cookie = NULL, /* initialized below */ 82 83 /* mapping/unmapping */ 84 .bs_map = isa_bs_map, 85 .bs_unmap = isa_bs_unmap, 86 .bs_subregion = isa_bs_subregion, 87 88 /* allocation/deallocation */ 89 .bs_alloc = isa_bs_alloc, 90 .bs_free = isa_bs_free, 91 92 /* get kernel virtual address */ 93 .bs_vaddr = isa_bs_vaddr, 94 95 /* mmap bus space for userland */ 96 .bs_mmap = isa_bs_mmap, 97 98 /* barrier */ 99 .bs_barrier = isa_bs_barrier, 100 101 /* read (single) */ 102 .bs_r_1 = isa_bs_r_1, 103 .bs_r_2 = isa_bs_r_2, 104 .bs_r_4 = isa_bs_r_4, 105 .bs_r_8 = bs_notimpl_bs_r_8, 106 107 /* read multiple */ 108 .bs_rm_1 = isa_bs_rm_1, 109 .bs_rm_2 = isa_bs_rm_2, 110 .bs_rm_4 = isa_bs_rm_4, 111 .bs_rm_8 = bs_notimpl_bs_rm_8, 112 113 /* read region */ 114 .bs_rr_1 = isa_bs_rr_1, 115 .bs_rr_2 = isa_bs_rr_2, 116 .bs_rr_4 = isa_bs_rr_4, 117 .bs_rr_8 = bs_notimpl_bs_rr_8, 118 119 /* write (single) */ 120 .bs_w_1 = isa_bs_w_1, 121 .bs_w_2 = isa_bs_w_2, 122 .bs_w_4 = isa_bs_w_4, 123 .bs_w_8 = bs_notimpl_bs_w_8, 124 125 /* write multiple */ 126 .bs_wm_1 = isa_bs_wm_1, 127 .bs_wm_2 = isa_bs_wm_2, 128 .bs_wm_4 = isa_bs_wm_4, 129 .bs_wm_8 = bs_notimpl_bs_wm_8, 130 131 /* write region */ 132 .bs_wr_1 = isa_bs_wr_1, 133 .bs_wr_2 = isa_bs_wr_2, 134 .bs_wr_4 = isa_bs_wr_4, 135 .bs_wr_8 = bs_notimpl_bs_wr_8, 136 137 /* set multiple */ 138 .bs_sm_1 = bs_notimpl_bs_sm_1, 139 .bs_sm_2 = bs_notimpl_bs_sm_2, 140 .bs_sm_4 = bs_notimpl_bs_sm_4, 141 .bs_sm_8 = bs_notimpl_bs_sm_8, 142 143 /* set region */ 144 .bs_sr_1 = bs_notimpl_bs_sr_1, 145 .bs_sr_2 = isa_bs_sr_2, 146 .bs_sr_4 = bs_notimpl_bs_sr_4, 147 .bs_sr_8 = bs_notimpl_bs_sr_8, 148 149 /* copy */ 150 .bs_c_1 = bs_notimpl_bs_c_1, 151 .bs_c_2 = isa_bs_c_2, 152 .bs_c_4 = bs_notimpl_bs_c_4, 153 .bs_c_8 = bs_notimpl_bs_c_8, 154 155 /* stream methods are identical to regular read/write here */ 156 /* read stream single */ 157 .bs_r_1_s = isa_bs_r_1, 158 .bs_r_2_s = isa_bs_r_2, 159 .bs_r_4_s = isa_bs_r_4, 160 .bs_r_8_s = bs_notimpl_bs_r_8, 161 162 /* read stream multiple */ 163 .bs_rm_1_s = isa_bs_rm_1, 164 .bs_rm_2_s = isa_bs_rm_2, 165 .bs_rm_4_s = isa_bs_rm_4, 166 .bs_rm_8_s = bs_notimpl_bs_rm_8, 167 168 /* read region stream */ 169 .bs_rr_1_s = isa_bs_rr_1, 170 .bs_rr_2_s = isa_bs_rr_2, 171 .bs_rr_4_s = isa_bs_rr_4, 172 .bs_rr_8_s = bs_notimpl_bs_rr_8, 173 174 /* write stream single */ 175 .bs_w_1_s = isa_bs_w_1, 176 .bs_w_2_s = isa_bs_w_2, 177 .bs_w_4_s = isa_bs_w_4, 178 .bs_w_8_s = bs_notimpl_bs_w_8, 179 180 /* write stream multiple */ 181 .bs_wm_1_s = isa_bs_wm_1, 182 .bs_wm_2_s = isa_bs_wm_2, 183 .bs_wm_4_s = isa_bs_wm_4, 184 .bs_wm_8_s = bs_notimpl_bs_wm_8, 185 186 /* write region stream */ 187 .bs_wr_1_s = isa_bs_wr_1, 188 .bs_wr_2_s = isa_bs_wr_2, 189 .bs_wr_4_s = isa_bs_wr_4, 190 .bs_wr_8_s = bs_notimpl_bs_wr_8, 191 192 }; 193 194 /* 195 * NOTE: ASSEMBLY LANGUAGE RELIES ON THE COOKIE -- THE FIRST MEMBER OF 196 * THIS STRUCTURE -- TO BE THE VIRTUAL ADDRESS OF ISA/MEMORY! 197 */ 198 struct bus_space isa_mem_bs_tag = { 199 /* cookie */ 200 .bs_cookie = NULL, /* initialized below */ 201 202 /* mapping/unmapping */ 203 .bs_map = isa_bs_map, 204 .bs_unmap = isa_bs_unmap, 205 .bs_subregion = isa_bs_subregion, 206 207 /* allocation/deallocation */ 208 .bs_alloc = isa_bs_alloc, 209 .bs_free = isa_bs_free, 210 211 /* get kernel virtual address */ 212 .bs_vaddr = isa_bs_vaddr, 213 214 /* mmap bus space for userland */ 215 .bs_mmap = isa_bs_mmap, 216 217 /* barrier */ 218 .bs_barrier = isa_bs_barrier, 219 220 /* read (single) */ 221 .bs_r_1 = isa_bs_r_1, 222 .bs_r_2 = isa_bs_r_2, 223 .bs_r_4 = isa_bs_r_4, 224 .bs_r_8 = bs_notimpl_bs_r_8, 225 226 /* read multiple */ 227 .bs_rm_1 = isa_bs_rm_1, 228 .bs_rm_2 = isa_bs_rm_2, 229 .bs_rm_4 = isa_bs_rm_4, 230 .bs_rm_8 = bs_notimpl_bs_rm_8, 231 232 /* read region */ 233 .bs_rr_1 = isa_bs_rr_1, 234 .bs_rr_2 = isa_bs_rr_2, 235 .bs_rr_4 = isa_bs_rr_4, 236 .bs_rr_8 = bs_notimpl_bs_rr_8, 237 238 /* write (single) */ 239 .bs_w_1 = isa_bs_w_1, 240 .bs_w_2 = isa_bs_w_2, 241 .bs_w_4 = isa_bs_w_4, 242 .bs_w_8 = bs_notimpl_bs_w_8, 243 244 /* write multiple */ 245 .bs_wm_1 = isa_bs_wm_1, 246 .bs_wm_2 = isa_bs_wm_2, 247 .bs_wm_4 = isa_bs_wm_4, 248 .bs_wm_8 = bs_notimpl_bs_wm_8, 249 250 /* write region */ 251 .bs_wr_1 = isa_bs_wr_1, 252 .bs_wr_2 = isa_bs_wr_2, 253 .bs_wr_4 = isa_bs_wr_4, 254 .bs_wr_8 = bs_notimpl_bs_wr_8, 255 256 /* set multiple */ 257 .bs_sm_1 = bs_notimpl_bs_sm_1, 258 .bs_sm_2 = bs_notimpl_bs_sm_2, 259 .bs_sm_4 = bs_notimpl_bs_sm_4, 260 .bs_sm_8 = bs_notimpl_bs_sm_8, 261 262 /* set region */ 263 .bs_sr_1 = bs_notimpl_bs_sr_1, 264 .bs_sr_2 = isa_bs_sr_2, 265 .bs_sr_4 = bs_notimpl_bs_sr_4, 266 .bs_sr_8 = bs_notimpl_bs_sr_8, 267 268 /* copy */ 269 .bs_c_1 = bs_notimpl_bs_c_1, 270 .bs_c_2 = isa_bs_c_2, 271 .bs_c_4 = bs_notimpl_bs_c_4, 272 .bs_c_8 = bs_notimpl_bs_c_8, 273 274 /* stream methods are identical to regular read/write here */ 275 /* read stream single */ 276 .bs_r_1_s = isa_bs_r_1, 277 .bs_r_2_s = isa_bs_r_2, 278 .bs_r_4_s = isa_bs_r_4, 279 .bs_r_8_s = bs_notimpl_bs_r_8, 280 281 /* read stream multiple */ 282 .bs_rm_1_s = isa_bs_rm_1, 283 .bs_rm_2_s = isa_bs_rm_2, 284 .bs_rm_4_s = isa_bs_rm_4, 285 .bs_rm_8_s = bs_notimpl_bs_rm_8, 286 287 /* read region stream */ 288 .bs_rr_1_s = isa_bs_rr_1, 289 .bs_rr_2_s = isa_bs_rr_2, 290 .bs_rr_4_s = isa_bs_rr_4, 291 .bs_rr_8_s = bs_notimpl_bs_rr_8, 292 293 /* write stream single */ 294 .bs_w_1_s = isa_bs_w_1, 295 .bs_w_2_s = isa_bs_w_2, 296 .bs_w_4_s = isa_bs_w_4, 297 .bs_w_8_s = bs_notimpl_bs_w_8, 298 299 /* write stream multiple */ 300 .bs_wm_1_s = isa_bs_wm_1, 301 .bs_wm_2_s = isa_bs_wm_2, 302 .bs_wm_4_s = isa_bs_wm_4, 303 .bs_wm_8_s = bs_notimpl_bs_wm_8, 304 305 /* write region stream */ 306 .bs_wr_1_s = isa_bs_wr_1, 307 .bs_wr_2_s = isa_bs_wr_2, 308 .bs_wr_4_s = isa_bs_wr_4, 309 .bs_wr_8_s = bs_notimpl_bs_wr_8, 310 }; 311 312 /* bus space functions */ 313 314 void 315 isa_io_init(vaddr_t isa_io_addr, vaddr_t isa_mem_addr) 316 { 317 isa_io_bs_tag.bs_cookie = (void *)isa_io_addr; 318 isa_mem_bs_tag.bs_cookie = (void *)isa_mem_addr; 319 } 320 321 /* 322 * break the abstraction: sometimes, other parts of the system 323 * (e.g. X servers) need to map ISA space directly. use these 324 * functions sparingly! 325 */ 326 vaddr_t 327 isa_io_data_vaddr(void) 328 { 329 return (vaddr_t)isa_io_bs_tag.bs_cookie; 330 } 331 332 vaddr_t 333 isa_mem_data_vaddr(void) 334 { 335 return (vaddr_t)isa_mem_bs_tag.bs_cookie; 336 } 337 338 int 339 isa_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int cacheable, bus_space_handle_t *bshp) 340 { 341 *bshp = bpa + (bus_addr_t)t; 342 return(0); 343 } 344 345 void 346 isa_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size) 347 { 348 /* Nothing to do. */ 349 } 350 351 paddr_t 352 isa_bs_mmap(void *cookie, bus_addr_t addr, off_t off, int prot, 353 int flags) 354 { 355 paddr_t paddr, ret; 356 357 #ifdef OFISA_DEBUG 358 printf("mmap %08x %08x %08x", (uint32_t)cookie, (uint32_t)addr, (uint32_t)off); 359 #endif 360 #if NIGSFB_OFBUS > 0 361 if ((vaddr_t)cookie == igsfb_mem_vaddr) { 362 paddr = igsfb_mem_paddr; 363 } else 364 #endif 365 #if NCHIPSFB_OFBUS > 0 366 if ((vaddr_t)cookie == chipsfb_mem_vaddr) { 367 paddr = 0; 368 } else 369 #endif 370 paddr = ofw_gettranslation((vaddr_t)cookie); 371 372 if (paddr == -1) { 373 #ifdef OFISA_DEBUG 374 printf(" no translation\n"); 375 #endif 376 return -1; 377 } 378 ret = paddr + addr + off; 379 #ifdef OFISA_DEBUG 380 printf(" -> %08x %08x\n", (uint32_t)paddr, (uint32_t)ret); 381 #endif 382 if (flags & BUS_SPACE_MAP_PREFETCHABLE) { 383 return (arm_btop(ret) | ARM32_MMAP_WRITECOMBINE); 384 } else 385 return arm_btop(ret); 386 } 387 388 int 389 isa_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp) 390 { 391 /* printf("isa_subregion(tag=%p, bsh=%lx, off=%lx, sz=%lx)\n", 392 t, bsh, offset, size);*/ 393 *nbshp = bsh + offset; 394 return(0); 395 } 396 397 int 398 isa_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, 399 bus_size_t alignment, bus_size_t boundary, int cacheable, 400 bus_addr_t *bpap, bus_space_handle_t *bshp) 401 { 402 panic("isa_alloc(): Help!"); 403 } 404 405 void 406 isa_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size) 407 { 408 panic("isa_free(): Help!"); 409 } 410 411 void * 412 isa_bs_vaddr(void *t, bus_space_handle_t bsh) 413 { 414 415 return ((void *)bsh); 416 } 417 418 void 419 isa_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset, bus_size_t len, int flags) 420 { 421 /* just return */ 422 } 423