1/* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */ 2/*- 3 * $Id: bus.h,v 1.6 2007/08/09 11:23:32 katta Exp $ 4 * 5 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10 * NASA Ames Research Center. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34/* 35 * Copyright (c) 1996 Charles M. Hannum. All rights reserved. 36 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. All advertising materials mentioning features or use of this software 47 * must display the following acknowledgement: 48 * This product includes software developed by Christopher G. Demetriou 49 * for the NetBSD Project. 50 * 4. The name of the author may not be used to endorse or promote products 51 * derived from this software without specific prior written permission 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 54 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 55 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 56 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 57 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 58 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 59 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 60 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 61 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 62 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 63 * 64 * from: src/sys/alpha/include/bus.h,v 1.5 1999/08/28 00:38:40 peter 65 * $FreeBSD$ 66 */ 67#include <sys/cdefs.h> 68__FBSDID("$FreeBSD$"); 69 70#include <sys/param.h> 71#include <sys/systm.h> 72#include <sys/bus.h> 73#include <sys/kernel.h> 74#include <sys/malloc.h> 75#include <sys/ktr.h> 76 77#include <vm/vm.h> 78#include <vm/pmap.h> 79#include <vm/vm_kern.h> 80#include <vm/vm_extern.h> 81 82#include <machine/bus.h> 83#include <machine/cache.h> 84 85static struct bus_space generic_space = { 86 /* cookie */ 87 (void *) 0, 88 89 /* mapping/unmapping */ 90 generic_bs_map, 91 generic_bs_unmap, 92 generic_bs_subregion, 93 94 /* allocation/deallocation */ 95 NULL, 96 NULL, 97 98 /* barrier */ 99 generic_bs_barrier, 100 101 /* read (single) */ 102 generic_bs_r_1, 103 generic_bs_r_2, 104 generic_bs_r_4, 105 NULL, 106 107 /* read multiple */ 108 generic_bs_rm_1, 109 generic_bs_rm_2, 110 generic_bs_rm_4, 111 NULL, 112 113 /* read region */ 114 generic_bs_rr_1, 115 generic_bs_rr_2, 116 generic_bs_rr_4, 117 NULL, 118 119 /* write (single) */ 120 generic_bs_w_1, 121 generic_bs_w_2, 122 generic_bs_w_4, 123 NULL, 124 125 /* write multiple */ 126 generic_bs_wm_1, 127 generic_bs_wm_2, 128 generic_bs_wm_4, 129 NULL, 130 131 /* write region */ 132 NULL, 133 generic_bs_wr_2, 134 generic_bs_wr_4, 135 NULL, 136 137 /* set multiple */ 138 NULL, 139 NULL, 140 NULL, 141 NULL, 142 143 /* set region */ 144 NULL, 145 generic_bs_sr_2, 146 generic_bs_sr_4, 147 NULL, 148 149 /* copy */ 150 NULL, 151 generic_bs_c_2, 152 NULL, 153 NULL, 154 155 /* read (single) stream */ 156 generic_bs_r_1, 157 generic_bs_r_2, 158 generic_bs_r_4, 159 NULL, 160 161 /* read multiple stream */ 162 generic_bs_rm_1, 163 generic_bs_rm_2, 164 generic_bs_rm_4, 165 NULL, 166 167 /* read region stream */ 168 generic_bs_rr_1, 169 generic_bs_rr_2, 170 generic_bs_rr_4, 171 NULL, 172 173 /* write (single) stream */ 174 generic_bs_w_1, 175 generic_bs_w_2, 176 generic_bs_w_4, 177 NULL, 178 179 /* write multiple stream */ 180 generic_bs_wm_1, 181 generic_bs_wm_2, 182 generic_bs_wm_4, 183 NULL, 184 185 /* write region stream */ 186 NULL, 187 generic_bs_wr_2, 188 generic_bs_wr_4, 189 NULL, 190}; 191 192/* Ultra-gross kludge */ 193#include "opt_cputype.h" 194#if defined(CPU_CNMIPS) && (defined(__mips_n32) || defined(__mips_o32)) 195#include <contrib/octeon-sdk/cvmx.h> 196#define rd8(a) cvmx_read64_uint8(a) 197#define rd16(a) cvmx_read64_uint16(a) 198#define rd32(a) cvmx_read64_uint32(a) 199#define wr8(a, v) cvmx_write64_uint8(a, v) 200#define wr16(a, v) cvmx_write64_uint16(a, v) 201#define wr32(a, v) cvmx_write64_uint32(a, v) 202#elif defined(CPU_SB1) && _BYTE_ORDER == _BIG_ENDIAN 203#include <mips/sibyte/sb_bus_space.h> 204#define rd8(a) sb_big_endian_read8(a) 205#define rd16(a) sb_big_endian_read16(a) 206#define rd32(a) sb_big_endian_read32(a) 207#define wr8(a, v) sb_big_endian_write8(a, v) 208#define wr16(a, v) sb_big_endian_write16(a, v) 209#define wr32(a, v) sb_big_endian_write32(a, v) 210#else 211#define rd8(a) readb(a) 212#define rd16(a) readw(a) 213#define rd32(a) readl(a) 214#define wr8(a, v) writeb(a, v) 215#define wr16(a, v) writew(a, v) 216#define wr32(a, v) writel(a, v) 217#endif 218 219/* generic bus_space tag */ 220bus_space_tag_t mips_bus_space_generic = &generic_space; 221 222int 223generic_bs_map(void *t __unused, bus_addr_t addr, 224 bus_size_t size __unused, int flags __unused, 225 bus_space_handle_t *bshp) 226{ 227 228 *bshp = addr; 229 return (0); 230} 231 232void 233generic_bs_unmap(void *t __unused, bus_space_handle_t bh __unused, 234 bus_size_t size __unused) 235{ 236 237 /* Do nothing */ 238} 239 240int 241generic_bs_subregion(void *t __unused, bus_space_handle_t handle __unused, 242 bus_size_t offset __unused, bus_size_t size __unused, 243 bus_space_handle_t *nhandle __unused) 244{ 245 246 printf("SUBREGION?!?!?!\n"); 247 /* Do nothing */ 248 return (0); 249} 250 251uint8_t 252generic_bs_r_1(void *t, bus_space_handle_t handle, 253 bus_size_t offset) 254{ 255 256 return (rd8(handle + offset)); 257} 258 259uint16_t 260generic_bs_r_2(void *t, bus_space_handle_t handle, 261 bus_size_t offset) 262{ 263 264 return (rd16(handle + offset)); 265} 266 267uint32_t 268generic_bs_r_4(void *t, bus_space_handle_t handle, 269 bus_size_t offset) 270{ 271 272 return (rd32(handle + offset)); 273} 274 275 276void 277generic_bs_rm_1(void *t, bus_space_handle_t bsh, 278 bus_size_t offset, uint8_t *addr, size_t count) 279{ 280 281 while (count--) 282 *addr++ = rd8(bsh + offset); 283} 284 285void 286generic_bs_rm_2(void *t, bus_space_handle_t bsh, 287 bus_size_t offset, uint16_t *addr, size_t count) 288{ 289 bus_addr_t baddr = bsh + offset; 290 291 while (count--) 292 *addr++ = rd16(baddr); 293} 294 295void 296generic_bs_rm_4(void *t, bus_space_handle_t bsh, 297 bus_size_t offset, uint32_t *addr, size_t count) 298{ 299 bus_addr_t baddr = bsh + offset; 300 301 while (count--) 302 *addr++ = rd32(baddr); 303} 304 305 306/* 307 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 308 * described by tag/handle and starting at `offset' and copy into 309 * buffer provided. 310 */ 311void 312generic_bs_rr_1(void *t, bus_space_handle_t bsh, 313 bus_size_t offset, uint8_t *addr, size_t count) 314{ 315 bus_addr_t baddr = bsh + offset; 316 317 while (count--) { 318 *addr++ = rd8(baddr); 319 baddr += 1; 320 } 321} 322 323void 324generic_bs_rr_2(void *t, bus_space_handle_t bsh, 325 bus_size_t offset, uint16_t *addr, size_t count) 326{ 327 bus_addr_t baddr = bsh + offset; 328 329 while (count--) { 330 *addr++ = rd16(baddr); 331 baddr += 2; 332 } 333} 334 335void 336generic_bs_rr_4(void *t, bus_space_handle_t bsh, 337 bus_size_t offset, uint32_t *addr, size_t count) 338{ 339 bus_addr_t baddr = bsh + offset; 340 341 while (count--) { 342 *addr++ = rd32(baddr); 343 baddr += 4; 344 } 345} 346 347/* 348 * Write the 1, 2, 4, or 8 byte value `value' to bus space 349 * described by tag/handle/offset. 350 */ 351void 352generic_bs_w_1(void *t, bus_space_handle_t bsh, 353 bus_size_t offset, uint8_t value) 354{ 355 356 wr8(bsh + offset, value); 357} 358 359void 360generic_bs_w_2(void *t, bus_space_handle_t bsh, 361 bus_size_t offset, uint16_t value) 362{ 363 364 wr16(bsh + offset, value); 365} 366 367void 368generic_bs_w_4(void *t, bus_space_handle_t bsh, 369 bus_size_t offset, uint32_t value) 370{ 371 372 wr32(bsh + offset, value); 373} 374 375/* 376 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 377 * provided to bus space described by tag/handle/offset. 378 */ 379void 380generic_bs_wm_1(void *t, bus_space_handle_t bsh, 381 bus_size_t offset, const uint8_t *addr, size_t count) 382{ 383 bus_addr_t baddr = bsh + offset; 384 385 while (count--) 386 wr8(baddr, *addr++); 387} 388 389void 390generic_bs_wm_2(void *t, bus_space_handle_t bsh, 391 bus_size_t offset, const uint16_t *addr, size_t count) 392{ 393 bus_addr_t baddr = bsh + offset; 394 395 while (count--) 396 wr16(baddr, *addr++); 397} 398 399void 400generic_bs_wm_4(void *t, bus_space_handle_t bsh, 401 bus_size_t offset, const uint32_t *addr, size_t count) 402{ 403 bus_addr_t baddr = bsh + offset; 404 405 while (count--) 406 wr32(baddr, *addr++); 407} 408 409/* 410 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 411 * to bus space described by tag/handle starting at `offset'. 412 */ 413void 414generic_bs_wr_1(void *t, bus_space_handle_t bsh, 415 bus_size_t offset, const uint8_t *addr, size_t count) 416{ 417 bus_addr_t baddr = bsh + offset; 418 419 while (count--) { 420 wr8(baddr, *addr++); 421 baddr += 1; 422 } 423} 424 425void 426generic_bs_wr_2(void *t, bus_space_handle_t bsh, 427 bus_size_t offset, const uint16_t *addr, size_t count) 428{ 429 bus_addr_t baddr = bsh + offset; 430 431 while (count--) { 432 wr16(baddr, *addr++); 433 baddr += 2; 434 } 435} 436 437void 438generic_bs_wr_4(void *t, bus_space_handle_t bsh, 439 bus_size_t offset, const uint32_t *addr, size_t count) 440{ 441 bus_addr_t baddr = bsh + offset; 442 443 while (count--) { 444 wr32(baddr, *addr++); 445 baddr += 4; 446 } 447} 448 449/* 450 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 451 * by tag/handle/offset `count' times. 452 */ 453void 454generic_bs_sm_1(void *t, bus_space_handle_t bsh, 455 bus_size_t offset, uint8_t value, size_t count) 456{ 457 bus_addr_t addr = bsh + offset; 458 459 while (count--) 460 wr8(addr, value); 461} 462 463void 464generic_bs_sm_2(void *t, bus_space_handle_t bsh, 465 bus_size_t offset, uint16_t value, size_t count) 466{ 467 bus_addr_t addr = bsh + offset; 468 469 while (count--) 470 wr16(addr, value); 471} 472 473void 474generic_bs_sm_4(void *t, bus_space_handle_t bsh, 475 bus_size_t offset, uint32_t value, size_t count) 476{ 477 bus_addr_t addr = bsh + offset; 478 479 while (count--) 480 wr32(addr, value); 481} 482 483/* 484 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 485 * by tag/handle starting at `offset'. 486 */ 487void 488generic_bs_sr_1(void *t, bus_space_handle_t bsh, 489 bus_size_t offset, uint8_t value, size_t count) 490{ 491 bus_addr_t addr = bsh + offset; 492 493 for (; count != 0; count--, addr++) 494 wr8(addr, value); 495} 496 497void 498generic_bs_sr_2(void *t, bus_space_handle_t bsh, 499 bus_size_t offset, uint16_t value, size_t count) 500{ 501 bus_addr_t addr = bsh + offset; 502 503 for (; count != 0; count--, addr += 2) 504 wr16(addr, value); 505} 506 507void 508generic_bs_sr_4(void *t, bus_space_handle_t bsh, 509 bus_size_t offset, uint32_t value, size_t count) 510{ 511 bus_addr_t addr = bsh + offset; 512 513 for (; count != 0; count--, addr += 4) 514 wr32(addr, value); 515} 516 517/* 518 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 519 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 520 */ 521void 522generic_bs_c_1(void *t, bus_space_handle_t bsh1, 523 bus_size_t off1, bus_space_handle_t bsh2, 524 bus_size_t off2, size_t count) 525{ 526 bus_addr_t addr1 = bsh1 + off1; 527 bus_addr_t addr2 = bsh2 + off2; 528 529 if (addr1 >= addr2) { 530 /* src after dest: copy forward */ 531 for (; count != 0; count--, addr1++, addr2++) 532 wr8(addr2, rd8(addr1)); 533 } else { 534 /* dest after src: copy backwards */ 535 for (addr1 += (count - 1), addr2 += (count - 1); 536 count != 0; count--, addr1--, addr2--) 537 wr8(addr2, rd8(addr1)); 538 } 539} 540 541void 542generic_bs_c_2(void *t, bus_space_handle_t bsh1, 543 bus_size_t off1, bus_space_handle_t bsh2, 544 bus_size_t off2, size_t count) 545{ 546 bus_addr_t addr1 = bsh1 + off1; 547 bus_addr_t addr2 = bsh2 + off2; 548 549 if (addr1 >= addr2) { 550 /* src after dest: copy forward */ 551 for (; count != 0; count--, addr1 += 2, addr2 += 2) 552 wr16(addr2, rd16(addr1)); 553 } else { 554 /* dest after src: copy backwards */ 555 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); 556 count != 0; count--, addr1 -= 2, addr2 -= 2) 557 wr16(addr2, rd16(addr1)); 558 } 559} 560 561void 562generic_bs_c_4(void *t, bus_space_handle_t bsh1, 563 bus_size_t off1, bus_space_handle_t bsh2, 564 bus_size_t off2, size_t count) 565{ 566 bus_addr_t addr1 = bsh1 + off1; 567 bus_addr_t addr2 = bsh2 + off2; 568 569 if (addr1 >= addr2) { 570 /* src after dest: copy forward */ 571 for (; count != 0; count--, addr1 += 4, addr2 += 4) 572 wr32(addr2, rd32(addr1)); 573 } else { 574 /* dest after src: copy backwards */ 575 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); 576 count != 0; count--, addr1 -= 4, addr2 -= 4) 577 wr32(addr2, rd32(addr1)); 578 } 579} 580 581void 582generic_bs_barrier(void *t __unused, 583 bus_space_handle_t bsh __unused, 584 bus_size_t offset __unused, bus_size_t len __unused, 585 int flags) 586{ 587#if 0 588 if (flags & BUS_SPACE_BARRIER_WRITE) 589 mips_dcache_wbinv_all(); 590#endif 591} 592