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#include <sys/endian.h> 77 78#include <vm/vm.h> 79#include <vm/pmap.h> 80#include <vm/vm_kern.h> 81#include <vm/vm_extern.h> 82 83#include <machine/bus.h> 84#include <machine/cache.h> 85 86#include <mips/cavium/octopcivar.h> 87 88#include <contrib/octeon-sdk/cvmx.h> 89 90static struct bus_space octopci_space = { 91 /* cookie */ 92 (void *) 0, 93 94 /* mapping/unmapping */ 95 octopci_bs_map, 96 octopci_bs_unmap, 97 octopci_bs_subregion, 98 99 /* allocation/deallocation */ 100 NULL, 101 NULL, 102 103 /* barrier */ 104 octopci_bs_barrier, 105 106 /* read (single) */ 107 octopci_bs_r_1, 108 octopci_bs_r_2, 109 octopci_bs_r_4, 110 NULL, 111 112 /* read multiple */ 113 octopci_bs_rm_1, 114 octopci_bs_rm_2, 115 octopci_bs_rm_4, 116 NULL, 117 118 /* read region */ 119 octopci_bs_rr_1, 120 octopci_bs_rr_2, 121 octopci_bs_rr_4, 122 NULL, 123 124 /* write (single) */ 125 octopci_bs_w_1, 126 octopci_bs_w_2, 127 octopci_bs_w_4, 128 NULL, 129 130 /* write multiple */ 131 octopci_bs_wm_1, 132 octopci_bs_wm_2, 133 octopci_bs_wm_4, 134 NULL, 135 136 /* write region */ 137 NULL, 138 octopci_bs_wr_2, 139 octopci_bs_wr_4, 140 NULL, 141 142 /* set multiple */ 143 NULL, 144 NULL, 145 NULL, 146 NULL, 147 148 /* set region */ 149 NULL, 150 octopci_bs_sr_2, 151 octopci_bs_sr_4, 152 NULL, 153 154 /* copy */ 155 NULL, 156 octopci_bs_c_2, 157 NULL, 158 NULL, 159 160 /* read (single) stream */ 161 octopci_bs_r_1, 162 octopci_bs_r_2, 163 octopci_bs_r_4, 164 NULL, 165 166 /* read multiple stream */ 167 octopci_bs_rm_1, 168 octopci_bs_rm_2, 169 octopci_bs_rm_4, 170 NULL, 171 172 /* read region stream */ 173 octopci_bs_rr_1, 174 octopci_bs_rr_2, 175 octopci_bs_rr_4, 176 NULL, 177 178 /* write (single) stream */ 179 octopci_bs_w_1, 180 octopci_bs_w_2, 181 octopci_bs_w_4, 182 NULL, 183 184 /* write multiple stream */ 185 octopci_bs_wm_1, 186 octopci_bs_wm_2, 187 octopci_bs_wm_4, 188 NULL, 189 190 /* write region stream */ 191 NULL, 192 octopci_bs_wr_2, 193 octopci_bs_wr_4, 194 NULL, 195}; 196 197#define rd8(a) cvmx_read64_uint8(a) 198#define rd16(a) le16toh(cvmx_read64_uint16(a)) 199#define rd32(a) le32toh(cvmx_read64_uint32(a)) 200#define wr8(a, v) cvmx_write64_uint8(a, v) 201#define wr16(a, v) cvmx_write64_uint16(a, htole16(v)) 202#define wr32(a, v) cvmx_write64_uint32(a, htole32(v)) 203 204/* octopci bus_space tag */ 205bus_space_tag_t octopci_bus_space = &octopci_space; 206 207int 208octopci_bs_map(void *t __unused, bus_addr_t addr, 209 bus_size_t size __unused, int flags __unused, 210 bus_space_handle_t *bshp) 211{ 212 213 *bshp = addr; 214 return (0); 215} 216 217void 218octopci_bs_unmap(void *t __unused, bus_space_handle_t bh __unused, 219 bus_size_t size __unused) 220{ 221 222 /* Do nothing */ 223} 224 225int 226octopci_bs_subregion(void *t __unused, bus_space_handle_t handle, 227 bus_size_t offset, bus_size_t size __unused, 228 bus_space_handle_t *bshp) 229{ 230 231 *bshp = handle + offset; 232 return (0); 233} 234 235uint8_t 236octopci_bs_r_1(void *t, bus_space_handle_t handle, 237 bus_size_t offset) 238{ 239 240 return (rd8(handle + offset)); 241} 242 243uint16_t 244octopci_bs_r_2(void *t, bus_space_handle_t handle, 245 bus_size_t offset) 246{ 247 248 return (rd16(handle + offset)); 249} 250 251uint32_t 252octopci_bs_r_4(void *t, bus_space_handle_t handle, 253 bus_size_t offset) 254{ 255 256 return (rd32(handle + offset)); 257} 258 259 260void 261octopci_bs_rm_1(void *t, bus_space_handle_t bsh, 262 bus_size_t offset, uint8_t *addr, size_t count) 263{ 264 265 while (count--) 266 *addr++ = rd8(bsh + offset); 267} 268 269void 270octopci_bs_rm_2(void *t, bus_space_handle_t bsh, 271 bus_size_t offset, uint16_t *addr, size_t count) 272{ 273 bus_addr_t baddr = bsh + offset; 274 275 while (count--) 276 *addr++ = rd16(baddr); 277} 278 279void 280octopci_bs_rm_4(void *t, bus_space_handle_t bsh, 281 bus_size_t offset, uint32_t *addr, size_t count) 282{ 283 bus_addr_t baddr = bsh + offset; 284 285 while (count--) 286 *addr++ = rd32(baddr); 287} 288 289 290/* 291 * Read `count' 1, 2, 4, or 8 byte quantities from bus space 292 * described by tag/handle and starting at `offset' and copy into 293 * buffer provided. 294 */ 295void 296octopci_bs_rr_1(void *t, bus_space_handle_t bsh, 297 bus_size_t offset, uint8_t *addr, size_t count) 298{ 299 bus_addr_t baddr = bsh + offset; 300 301 while (count--) { 302 *addr++ = rd8(baddr); 303 baddr += 1; 304 } 305} 306 307void 308octopci_bs_rr_2(void *t, bus_space_handle_t bsh, 309 bus_size_t offset, uint16_t *addr, size_t count) 310{ 311 bus_addr_t baddr = bsh + offset; 312 313 while (count--) { 314 *addr++ = rd16(baddr); 315 baddr += 2; 316 } 317} 318 319void 320octopci_bs_rr_4(void *t, bus_space_handle_t bsh, 321 bus_size_t offset, uint32_t *addr, size_t count) 322{ 323 bus_addr_t baddr = bsh + offset; 324 325 while (count--) { 326 *addr++ = rd32(baddr); 327 baddr += 4; 328 } 329} 330 331/* 332 * Write the 1, 2, 4, or 8 byte value `value' to bus space 333 * described by tag/handle/offset. 334 */ 335void 336octopci_bs_w_1(void *t, bus_space_handle_t bsh, 337 bus_size_t offset, uint8_t value) 338{ 339 340 wr8(bsh + offset, value); 341} 342 343void 344octopci_bs_w_2(void *t, bus_space_handle_t bsh, 345 bus_size_t offset, uint16_t value) 346{ 347 348 wr16(bsh + offset, value); 349} 350 351void 352octopci_bs_w_4(void *t, bus_space_handle_t bsh, 353 bus_size_t offset, uint32_t value) 354{ 355 356 wr32(bsh + offset, value); 357} 358 359/* 360 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer 361 * provided to bus space described by tag/handle/offset. 362 */ 363void 364octopci_bs_wm_1(void *t, bus_space_handle_t bsh, 365 bus_size_t offset, const uint8_t *addr, size_t count) 366{ 367 bus_addr_t baddr = bsh + offset; 368 369 while (count--) 370 wr8(baddr, *addr++); 371} 372 373void 374octopci_bs_wm_2(void *t, bus_space_handle_t bsh, 375 bus_size_t offset, const uint16_t *addr, size_t count) 376{ 377 bus_addr_t baddr = bsh + offset; 378 379 while (count--) 380 wr16(baddr, *addr++); 381} 382 383void 384octopci_bs_wm_4(void *t, bus_space_handle_t bsh, 385 bus_size_t offset, const uint32_t *addr, size_t count) 386{ 387 bus_addr_t baddr = bsh + offset; 388 389 while (count--) 390 wr32(baddr, *addr++); 391} 392 393/* 394 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided 395 * to bus space described by tag/handle starting at `offset'. 396 */ 397void 398octopci_bs_wr_1(void *t, bus_space_handle_t bsh, 399 bus_size_t offset, const uint8_t *addr, size_t count) 400{ 401 bus_addr_t baddr = bsh + offset; 402 403 while (count--) { 404 wr8(baddr, *addr++); 405 baddr += 1; 406 } 407} 408 409void 410octopci_bs_wr_2(void *t, bus_space_handle_t bsh, 411 bus_size_t offset, const uint16_t *addr, size_t count) 412{ 413 bus_addr_t baddr = bsh + offset; 414 415 while (count--) { 416 wr16(baddr, *addr++); 417 baddr += 2; 418 } 419} 420 421void 422octopci_bs_wr_4(void *t, bus_space_handle_t bsh, 423 bus_size_t offset, const uint32_t *addr, size_t count) 424{ 425 bus_addr_t baddr = bsh + offset; 426 427 while (count--) { 428 wr32(baddr, *addr++); 429 baddr += 4; 430 } 431} 432 433/* 434 * Write the 1, 2, 4, or 8 byte value `val' to bus space described 435 * by tag/handle/offset `count' times. 436 */ 437void 438octopci_bs_sm_1(void *t, bus_space_handle_t bsh, 439 bus_size_t offset, uint8_t value, size_t count) 440{ 441 bus_addr_t addr = bsh + offset; 442 443 while (count--) 444 wr8(addr, value); 445} 446 447void 448octopci_bs_sm_2(void *t, bus_space_handle_t bsh, 449 bus_size_t offset, uint16_t value, size_t count) 450{ 451 bus_addr_t addr = bsh + offset; 452 453 while (count--) 454 wr16(addr, value); 455} 456 457void 458octopci_bs_sm_4(void *t, bus_space_handle_t bsh, 459 bus_size_t offset, uint32_t value, size_t count) 460{ 461 bus_addr_t addr = bsh + offset; 462 463 while (count--) 464 wr32(addr, value); 465} 466 467/* 468 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described 469 * by tag/handle starting at `offset'. 470 */ 471void 472octopci_bs_sr_1(void *t, bus_space_handle_t bsh, 473 bus_size_t offset, uint8_t value, size_t count) 474{ 475 bus_addr_t addr = bsh + offset; 476 477 for (; count != 0; count--, addr++) 478 wr8(addr, value); 479} 480 481void 482octopci_bs_sr_2(void *t, bus_space_handle_t bsh, 483 bus_size_t offset, uint16_t value, size_t count) 484{ 485 bus_addr_t addr = bsh + offset; 486 487 for (; count != 0; count--, addr += 2) 488 wr16(addr, value); 489} 490 491void 492octopci_bs_sr_4(void *t, bus_space_handle_t bsh, 493 bus_size_t offset, uint32_t value, size_t count) 494{ 495 bus_addr_t addr = bsh + offset; 496 497 for (; count != 0; count--, addr += 4) 498 wr32(addr, value); 499} 500 501/* 502 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting 503 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2. 504 */ 505void 506octopci_bs_c_1(void *t, bus_space_handle_t bsh1, 507 bus_size_t off1, bus_space_handle_t bsh2, 508 bus_size_t off2, size_t count) 509{ 510 bus_addr_t addr1 = bsh1 + off1; 511 bus_addr_t addr2 = bsh2 + off2; 512 513 if (addr1 >= addr2) { 514 /* src after dest: copy forward */ 515 for (; count != 0; count--, addr1++, addr2++) 516 wr8(addr2, rd8(addr1)); 517 } else { 518 /* dest after src: copy backwards */ 519 for (addr1 += (count - 1), addr2 += (count - 1); 520 count != 0; count--, addr1--, addr2--) 521 wr8(addr2, rd8(addr1)); 522 } 523} 524 525void 526octopci_bs_c_2(void *t, bus_space_handle_t bsh1, 527 bus_size_t off1, bus_space_handle_t bsh2, 528 bus_size_t off2, size_t count) 529{ 530 bus_addr_t addr1 = bsh1 + off1; 531 bus_addr_t addr2 = bsh2 + off2; 532 533 if (addr1 >= addr2) { 534 /* src after dest: copy forward */ 535 for (; count != 0; count--, addr1 += 2, addr2 += 2) 536 wr16(addr2, rd16(addr1)); 537 } else { 538 /* dest after src: copy backwards */ 539 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1); 540 count != 0; count--, addr1 -= 2, addr2 -= 2) 541 wr16(addr2, rd16(addr1)); 542 } 543} 544 545void 546octopci_bs_c_4(void *t, bus_space_handle_t bsh1, 547 bus_size_t off1, bus_space_handle_t bsh2, 548 bus_size_t off2, size_t count) 549{ 550 bus_addr_t addr1 = bsh1 + off1; 551 bus_addr_t addr2 = bsh2 + off2; 552 553 if (addr1 >= addr2) { 554 /* src after dest: copy forward */ 555 for (; count != 0; count--, addr1 += 4, addr2 += 4) 556 wr32(addr2, rd32(addr1)); 557 } else { 558 /* dest after src: copy backwards */ 559 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1); 560 count != 0; count--, addr1 -= 4, addr2 -= 4) 561 wr32(addr2, rd32(addr1)); 562 } 563} 564 565void 566octopci_bs_barrier(void *t __unused, 567 bus_space_handle_t bsh __unused, 568 bus_size_t offset __unused, bus_size_t len __unused, 569 int flags) 570{ 571#if 0 572 if (flags & BUS_SPACE_BARRIER_WRITE) 573 mips_dcache_wbinv_all(); 574#endif 575} 576