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