Annotation of sys/arch/sparc/include/bus.h, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: bus.h,v 1.6 2006/01/01 00:41:02 millert Exp $ */
! 2: /*
! 3: * Copyright (c) 2003, Miodrag Vallat.
! 4: *
! 5: * Redistribution and use in source and binary forms, with or without
! 6: * modification, are permitted provided that the following conditions
! 7: * are met:
! 8: * 1. Redistributions of source code must retain the above copyright
! 9: * notice, this list of conditions and the following disclaimer.
! 10: * 2. Redistributions in binary form must reproduce the above copyright
! 11: * notice, this list of conditions and the following disclaimer in the
! 12: * documentation and/or other materials provided with the distribution.
! 13: *
! 14: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 15: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 16: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
! 17: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
! 18: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 19: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 20: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 21: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
! 22: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
! 23: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 24: * POSSIBILITY OF SUCH DAMAGE.
! 25: */
! 26:
! 27: /*
! 28: * ``No-nonsense'' sparc bus_space implementation.
! 29: *
! 30: * This is a stripped down bus_space implementation for sparc, providing
! 31: * simple enough functions, suitable for inlining.
! 32: * To achieve this goal, it relies upon the following assumptions:
! 33: * - everything is memory-mapped. Hence, tags are basically not used,
! 34: * and most operation are just simple pointer arithmetic with the handle.
! 35: * - interrupt functions are not implemented; callers will provide their
! 36: * own wrappers on a need-to-do basis.
! 37: */
! 38:
! 39: #ifndef _SPARC_BUS_H_
! 40: #define _SPARC_BUS_H_
! 41:
! 42: #include <machine/autoconf.h>
! 43:
! 44: #include <uvm/uvm_extern.h>
! 45:
! 46: #include <machine/pmap.h>
! 47:
! 48: typedef u_int32_t bus_space_handle_t;
! 49:
! 50: /*
! 51: * bus_space_tag_t are pointer to *modified* rom_reg structures.
! 52: * rr_iospace is used to also carry bus endianness information.
! 53: */
! 54: typedef struct rom_reg *bus_space_tag_t;
! 55:
! 56: #define TAG_LITTLE_ENDIAN 0x80000000
! 57:
! 58: #define SET_TAG_BIG_ENDIAN(t) ((t))->rr_iospace &= ~TAG_LITTLE_ENDIAN
! 59: #define SET_TAG_LITTLE_ENDIAN(t) ((t))->rr_iospace |= TAG_LITTLE_ENDIAN
! 60:
! 61: #define IS_TAG_LITTLE_ENDIAN(t) ((t)->rr_iospace & TAG_LITTLE_ENDIAN)
! 62:
! 63: typedef u_int32_t bus_addr_t;
! 64: typedef u_int32_t bus_size_t;
! 65:
! 66: /*
! 67: * General bus_space function set
! 68: */
! 69:
! 70: static int bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
! 71: bus_space_handle_t *);
! 72: static int bus_space_unmap(bus_space_tag_t, bus_space_handle_t,
! 73: bus_size_t);
! 74:
! 75: #define BUS_SPACE_BARRIER_READ 0
! 76: #define BUS_SPACE_BARRIER_WRITE 1
! 77:
! 78: static void bus_space_barrier(bus_space_tag_t, bus_space_handle_t,
! 79: bus_addr_t, bus_size_t, int);
! 80:
! 81: static void* bus_space_vaddr(bus_space_tag_t, bus_space_handle_t);
! 82: static int bus_space_subregion(bus_space_tag_t, bus_space_handle_t,
! 83: bus_addr_t, bus_size_t, bus_space_handle_t *);
! 84:
! 85: static __inline__ int
! 86: bus_space_map(bus_space_tag_t tag, bus_addr_t addr, bus_size_t size, int flags,
! 87: bus_space_handle_t *handle)
! 88: {
! 89: if ((*handle = (bus_space_handle_t)mapiodev(tag,
! 90: addr, size)) != NULL)
! 91: return (0);
! 92:
! 93: return (ENOMEM);
! 94: }
! 95:
! 96: static __inline__ int
! 97: bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t size)
! 98: {
! 99: /*
! 100: * The mapiodev() call eventually ended up as a set of pmap_kenter_pa()
! 101: * calls. Although the iospace va will not be reclaimed, at least
! 102: * relinquish the wiring.
! 103: */
! 104: pmap_kremove((vaddr_t)handle, size);
! 105: pmap_update(pmap_kernel());
! 106: return (0);
! 107: }
! 108:
! 109: static __inline__ void
! 110: bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t handle,
! 111: bus_addr_t offset, bus_size_t size, int flags)
! 112: {
! 113: /* no membar is necessary for sparc so far */
! 114: }
! 115:
! 116: static __inline__ void *
! 117: bus_space_vaddr(bus_space_tag_t tag, bus_space_handle_t handle)
! 118: {
! 119: u_int32_t iospace = tag->rr_iospace;
! 120: void *rc;
! 121:
! 122: tag->rr_iospace &= ~TAG_LITTLE_ENDIAN;
! 123: rc = (void *)(REG2PHYS(tag, 0) | PMAP_NC);
! 124: tag->rr_iospace = iospace;
! 125: return (rc);
! 126: }
! 127:
! 128: static __inline__ int
! 129: bus_space_subregion(bus_space_tag_t tag, bus_space_handle_t handle,
! 130: bus_addr_t offset, bus_size_t size, bus_space_handle_t *newh)
! 131: {
! 132: *newh = handle + offset;
! 133: return (0);
! 134: }
! 135:
! 136: /*
! 137: * Read/Write/Region functions
! 138: * Most of these are straightforward and assume that everything is properly
! 139: * aligned.
! 140: */
! 141:
! 142: #define bus_space_read_1(tag, handle, offset) \
! 143: ((void)(tag), *(volatile u_int8_t *)((handle) + (offset)))
! 144: #define __bus_space_read_2(tag, handle, offset) \
! 145: *(volatile u_int16_t *)((handle) + (offset))
! 146: #define __bus_space_read_4(tag, handle, offset) \
! 147: *(volatile u_int32_t *)((handle) + (offset))
! 148: #define bus_space_read_2(tag, handle, offset) \
! 149: ((IS_TAG_LITTLE_ENDIAN(tag)) ? \
! 150: letoh16(__bus_space_read_2(tag, handle, offset)) : \
! 151: __bus_space_read_2(tag, handle, offset))
! 152: #define bus_space_read_4(tag, handle, offset) \
! 153: ((IS_TAG_LITTLE_ENDIAN(tag)) ? \
! 154: letoh32(__bus_space_read_4(tag, handle, offset)) : \
! 155: __bus_space_read_4(tag, handle, offset))
! 156:
! 157: static void bus_space_read_multi_1(bus_space_tag_t, bus_space_handle_t,
! 158: bus_addr_t, u_int8_t *, size_t);
! 159:
! 160: static __inline__ void
! 161: bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t handle,
! 162: bus_addr_t offset, u_int8_t *dest, size_t count)
! 163: {
! 164: while ((int)--count >= 0)
! 165: *dest++ = bus_space_read_1(tag, handle, offset);
! 166: }
! 167:
! 168: static void bus_space_read_multi_2(bus_space_tag_t, bus_space_handle_t,
! 169: bus_addr_t, u_int16_t *, size_t);
! 170:
! 171: static __inline__ void
! 172: bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
! 173: bus_addr_t offset, u_int16_t *dest, size_t count)
! 174: {
! 175: while ((int)--count >= 0)
! 176: *dest++ = bus_space_read_2(tag, handle, offset);
! 177: }
! 178:
! 179: static void bus_space_read_multi_4(bus_space_tag_t, bus_space_handle_t,
! 180: bus_addr_t, u_int32_t *, size_t);
! 181:
! 182: static __inline__ void
! 183: bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
! 184: bus_addr_t offset, u_int32_t *dest, size_t count)
! 185: {
! 186: while ((int)--count >= 0)
! 187: *dest++ = bus_space_read_4(tag, handle, offset);
! 188: }
! 189:
! 190: static void bus_space_read_raw_multi_2(bus_space_tag_t, bus_space_handle_t,
! 191: bus_addr_t, u_int8_t *, size_t);
! 192:
! 193: static __inline__ void
! 194: bus_space_read_raw_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
! 195: bus_addr_t offset, u_int8_t *dest, size_t size)
! 196: {
! 197: size >>= 1;
! 198: while ((int)--size >= 0) {
! 199: *(u_int16_t *)dest =
! 200: __bus_space_read_2(tag, handle, offset);
! 201: dest += 2;
! 202: }
! 203: }
! 204:
! 205: static void bus_space_read_raw_multi_4(bus_space_tag_t, bus_space_handle_t,
! 206: bus_addr_t, u_int8_t *, size_t);
! 207:
! 208: static __inline__ void
! 209: bus_space_read_raw_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
! 210: bus_addr_t offset, u_int8_t *dest, size_t size)
! 211: {
! 212: size >>= 2;
! 213: while ((int)--size >= 0) {
! 214: *(u_int32_t *)dest =
! 215: __bus_space_read_4(tag, handle, offset);
! 216: dest += 4;
! 217: }
! 218: }
! 219:
! 220: #define bus_space_write_1(tag, handle, offset, value) \
! 221: ((void)(tag), *(volatile u_int8_t *)((handle) + (offset)) = (value))
! 222: #define __bus_space_write_2(tag, handle, offset, value) \
! 223: *(volatile u_int16_t *)((handle) + (offset)) = (value)
! 224: #define __bus_space_write_4(tag, handle, offset, value) \
! 225: *(volatile u_int32_t *)((handle) + (offset)) = (value)
! 226: #define bus_space_write_2(tag, handle, offset, value) \
! 227: __bus_space_write_2(tag, handle, offset, \
! 228: (IS_TAG_LITTLE_ENDIAN(tag)) ? htole16(value) : (value))
! 229: #define bus_space_write_4(tag, handle, offset, value) \
! 230: __bus_space_write_4(tag, handle, offset, \
! 231: (IS_TAG_LITTLE_ENDIAN(tag)) ? htole32(value) : (value))
! 232:
! 233: static void bus_space_write_multi_1(bus_space_tag_t, bus_space_handle_t,
! 234: bus_addr_t, u_int8_t *, size_t);
! 235:
! 236: static __inline__ void
! 237: bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t handle,
! 238: bus_addr_t offset, u_int8_t *dest, size_t count)
! 239: {
! 240: while ((int)--count >= 0)
! 241: bus_space_write_1(tag, handle, offset, *dest++);
! 242: }
! 243:
! 244: static void bus_space_write_multi_2(bus_space_tag_t, bus_space_handle_t,
! 245: bus_addr_t, u_int16_t *, size_t);
! 246:
! 247: static __inline__ void
! 248: bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
! 249: bus_addr_t offset, u_int16_t *dest, size_t count)
! 250: {
! 251: while ((int)--count >= 0)
! 252: bus_space_write_2(tag, handle, offset, *dest++);
! 253: }
! 254:
! 255: static void bus_space_write_multi_4(bus_space_tag_t, bus_space_handle_t,
! 256: bus_addr_t, u_int32_t *, size_t);
! 257:
! 258: static __inline__ void
! 259: bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
! 260: bus_addr_t offset, u_int32_t *dest, size_t count)
! 261: {
! 262: while ((int)--count >= 0)
! 263: bus_space_write_4(tag, handle, offset, *dest);
! 264: }
! 265:
! 266: static void bus_space_write_raw_multi_2(bus_space_tag_t, bus_space_handle_t,
! 267: bus_addr_t, u_int8_t *, size_t);
! 268:
! 269: static __inline__ void
! 270: bus_space_write_raw_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
! 271: bus_addr_t offset, u_int8_t *dest, size_t size)
! 272: {
! 273: size >>= 1;
! 274: while ((int)--size >= 0) {
! 275: __bus_space_write_2(tag, handle, offset,
! 276: *(u_int16_t *)dest);
! 277: dest += 2;
! 278: }
! 279: }
! 280:
! 281: static void bus_space_write_raw_multi_4(bus_space_tag_t, bus_space_handle_t,
! 282: bus_addr_t, u_int8_t *, size_t);
! 283:
! 284: static __inline__ void
! 285: bus_space_write_raw_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
! 286: bus_addr_t offset, u_int8_t *dest, size_t size)
! 287: {
! 288: size >>= 2;
! 289: while ((int)--size >= 0) {
! 290: __bus_space_write_4(tag, handle, offset,
! 291: *(u_int32_t *)dest);
! 292: dest += 4;
! 293: }
! 294: }
! 295:
! 296: static void bus_space_set_multi_1(bus_space_tag_t, bus_space_handle_t,
! 297: bus_addr_t, u_int8_t, size_t);
! 298:
! 299: static __inline__ void
! 300: bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t handle,
! 301: bus_addr_t offset, u_int8_t value, size_t count)
! 302: {
! 303: while ((int)--count >= 0)
! 304: bus_space_write_1(tag, handle, offset, value);
! 305: }
! 306:
! 307: static void bus_space_set_multi_2(bus_space_tag_t, bus_space_handle_t,
! 308: bus_addr_t, u_int16_t, size_t);
! 309:
! 310: static __inline__ void
! 311: bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
! 312: bus_addr_t offset, u_int16_t value, size_t count)
! 313: {
! 314: while ((int)--count >= 0)
! 315: bus_space_write_2(tag, handle, offset, value);
! 316: }
! 317:
! 318: static void bus_space_set_multi_4(bus_space_tag_t, bus_space_handle_t,
! 319: bus_addr_t, u_int32_t, size_t);
! 320:
! 321: static __inline__ void
! 322: bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
! 323: bus_addr_t offset, u_int32_t value, size_t count)
! 324: {
! 325: while ((int)--count >= 0)
! 326: bus_space_write_4(tag, handle, offset, value);
! 327: }
! 328:
! 329: static void bus_space_write_region_1(bus_space_tag_t, bus_space_handle_t,
! 330: bus_addr_t, u_int8_t *, size_t);
! 331:
! 332: static __inline__ void
! 333: bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t handle,
! 334: bus_addr_t offset, u_int8_t *dest, size_t count)
! 335: {
! 336: while ((int)--count >= 0)
! 337: bus_space_write_1(tag, handle, offset++, *dest++);
! 338: }
! 339:
! 340: static void bus_space_write_region_2(bus_space_tag_t, bus_space_handle_t,
! 341: bus_addr_t, u_int16_t *, size_t);
! 342:
! 343: static __inline__ void
! 344: bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t handle,
! 345: bus_addr_t offset, u_int16_t *dest, size_t count)
! 346: {
! 347: while ((int)--count >= 0) {
! 348: bus_space_write_2(tag, handle, offset, *dest++);
! 349: offset += 2;
! 350: }
! 351: }
! 352:
! 353: static void bus_space_write_region_4(bus_space_tag_t, bus_space_handle_t,
! 354: bus_addr_t, u_int32_t *, size_t);
! 355:
! 356: static __inline__ void
! 357: bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
! 358: bus_addr_t offset, u_int32_t *dest, size_t count)
! 359: {
! 360: while ((int)--count >= 0) {
! 361: bus_space_write_4(tag, handle, offset, *dest++);
! 362: offset +=4;
! 363: }
! 364: }
! 365:
! 366: static void bus_space_write_raw_region_2(bus_space_tag_t, bus_space_handle_t,
! 367: bus_addr_t, u_int8_t *, size_t);
! 368:
! 369: static __inline__ void
! 370: bus_space_write_raw_region_2(bus_space_tag_t tag, bus_space_handle_t handle,
! 371: bus_addr_t offset, u_int8_t *dest, size_t size)
! 372: {
! 373: size >>= 1;
! 374: while ((int)--size >= 0) {
! 375: __bus_space_write_2(tag, handle, offset, *(u_int16_t *)dest);
! 376: offset += 2;
! 377: dest += 2;
! 378: }
! 379: }
! 380:
! 381: static void bus_space_write_raw_region_4(bus_space_tag_t, bus_space_handle_t,
! 382: bus_addr_t, u_int8_t *, size_t);
! 383:
! 384: static __inline__ void
! 385: bus_space_write_raw_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
! 386: bus_addr_t offset, u_int8_t *dest, size_t size)
! 387: {
! 388: size >>= 2;
! 389: while ((int)--size >= 0) {
! 390: __bus_space_write_4(tag, handle, offset, *(u_int32_t *)dest);
! 391: offset += 4;
! 392: dest += 4;
! 393: }
! 394: }
! 395:
! 396: static void bus_space_read_region_1(bus_space_tag_t, bus_space_handle_t,
! 397: bus_addr_t, u_int8_t *, size_t);
! 398:
! 399: static __inline__ void
! 400: bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t handle,
! 401: bus_addr_t offset, u_int8_t *dest, size_t count)
! 402: {
! 403: while ((int)--count >= 0)
! 404: *dest++ = bus_space_read_1(tag, handle, offset++);
! 405: }
! 406:
! 407: static void bus_space_read_region_2(bus_space_tag_t, bus_space_handle_t,
! 408: bus_addr_t, u_int16_t *, size_t);
! 409:
! 410: static __inline__ void
! 411: bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t handle,
! 412: bus_addr_t offset, u_int16_t *dest, size_t count)
! 413: {
! 414: while ((int)--count >= 0) {
! 415: *dest++ = bus_space_read_2(tag, handle, offset);
! 416: offset += 2;
! 417: }
! 418: }
! 419:
! 420: static void bus_space_read_region_4(bus_space_tag_t, bus_space_handle_t,
! 421: bus_addr_t, u_int32_t *, size_t);
! 422:
! 423: static __inline__ void
! 424: bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
! 425: bus_addr_t offset, u_int32_t *dest, size_t count)
! 426: {
! 427: while ((int)--count >= 0) {
! 428: *dest++ = bus_space_read_4(tag, handle, offset);
! 429: offset += 4;
! 430: }
! 431: }
! 432:
! 433: static void bus_space_set_region_1(bus_space_tag_t, bus_space_handle_t,
! 434: bus_addr_t, u_int8_t, size_t);
! 435:
! 436: static __inline__ void
! 437: bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t handle,
! 438: bus_addr_t offset, u_int8_t value, size_t count)
! 439: {
! 440: while ((int)--count >= 0)
! 441: bus_space_write_1(tag, handle, offset++, value);
! 442: }
! 443:
! 444: static void bus_space_set_region_2(bus_space_tag_t, bus_space_handle_t,
! 445: bus_addr_t, u_int16_t, size_t);
! 446:
! 447: static __inline__ void
! 448: bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t handle,
! 449: bus_addr_t offset, u_int16_t value, size_t count)
! 450: {
! 451: while ((int)--count >= 0) {
! 452: bus_space_write_2(tag, handle, offset, value);
! 453: offset += 2;
! 454: }
! 455: }
! 456:
! 457: static void bus_space_set_region_4(bus_space_tag_t, bus_space_handle_t,
! 458: bus_addr_t, u_int32_t, size_t);
! 459:
! 460: static __inline__ void
! 461: bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
! 462: bus_addr_t offset, u_int32_t value, size_t count)
! 463: {
! 464: while ((int)--count >= 0) {
! 465: bus_space_write_4(tag, handle, offset, value);
! 466: offset += 4;
! 467: }
! 468: }
! 469:
! 470: static void bus_space_read_raw_region_2(bus_space_tag_t, bus_space_handle_t,
! 471: bus_addr_t, u_int8_t *, size_t);
! 472:
! 473: static __inline__ void
! 474: bus_space_read_raw_region_2(bus_space_tag_t tag, bus_space_handle_t handle,
! 475: bus_addr_t offset, u_int8_t *dest, size_t size)
! 476: {
! 477: size >>= 1;
! 478: while ((int)--size >= 0) {
! 479: *(u_int16_t *)dest = __bus_space_read_2(tag, handle, offset);
! 480: offset += 2;
! 481: dest += 2;
! 482: }
! 483: }
! 484:
! 485: static void bus_space_read_raw_region_4(bus_space_tag_t, bus_space_handle_t,
! 486: bus_addr_t, u_int8_t *, size_t);
! 487:
! 488: static __inline__ void
! 489: bus_space_read_raw_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
! 490: bus_addr_t offset, u_int8_t *dest, size_t size)
! 491: {
! 492: size >>= 2;
! 493: while ((int)--size >= 0) {
! 494: *(u_int32_t *)dest = __bus_space_read_4(tag, handle, offset);
! 495: offset += 4;
! 496: dest += 4;
! 497: }
! 498: }
! 499:
! 500: #endif /* _SPARC_BUS_H_ */
CVSweb