|
|
1.1 ! root 1: /* $Id: sun2-bwtwo.c,v 1.2 2003/07/29 18:25:17 fredette Exp $ */ ! 2: ! 3: /* machine/sun2/sun2-bwtwo.c - Sun2 bwtwo emulation implementation: */ ! 4: ! 5: /* ! 6: * Copyright (c) 2003 Matt Fredette ! 7: * All rights reserved. ! 8: * ! 9: * Redistribution and use in source and binary forms, with or without ! 10: * modification, are permitted provided that the following conditions ! 11: * are met: ! 12: * 1. Redistributions of source code must retain the above copyright ! 13: * notice, this list of conditions and the following disclaimer. ! 14: * 2. Redistributions in binary form must reproduce the above copyright ! 15: * notice, this list of conditions and the following disclaimer in the ! 16: * documentation and/or other materials provided with the distribution. ! 17: * 3. All advertising materials mentioning features or use of this software ! 18: * must display the following acknowledgement: ! 19: * This product includes software developed by Matt Fredette. ! 20: * 4. The name of the author may not be used to endorse or promote products ! 21: * derived from this software without specific prior written permission. ! 22: * ! 23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ! 24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ! 25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ! 26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, ! 27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ! 28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ! 29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ! 31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ! 32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ! 33: * POSSIBILITY OF SUCH DAMAGE. ! 34: */ ! 35: ! 36: #include <tme/common.h> ! 37: _TME_RCSID("$Id: sun2-bwtwo.c,v 1.2 2003/07/29 18:25:17 fredette Exp $"); ! 38: ! 39: /* includes: */ ! 40: #include <tme/machine/sun.h> ! 41: #include <tme/generic/bus-device.h> ! 42: #include <tme/generic/fb.h> ! 43: ! 44: /* macros: */ ! 45: ! 46: /* screen dimensions: */ ! 47: #define TME_SUN2BW2_LO_WIDTH (1152) ! 48: #define TME_SUN2BW2_LO_HEIGHT (900) ! 49: #define TME_SUN2BW2_HI_WIDTH (1024) ! 50: #define TME_SUN2BW2_HI_HEIGHT (1024) ! 51: ! 52: /* register offsets and sizes: */ ! 53: #define TME_SUN2BW2_REG_MEM (0) ! 54: #define TME_SUN2BW2_SIZ_MEM (0x20000) ! 55: #define TME_SUN2BW2_REG_CSR_OBMEM (0x81800) ! 56: #define TME_SUN2BW2_REG_CSR_OBIO (0x20000) ! 57: #define TME_SUN2BW2_SIZ_CSR (0x00002) ! 58: #define TME_SUN2BW2_SIZ_CSR_PAGE (0x00800) ! 59: ! 60: /* the bits in the Control/Status register: */ ! 61: #define TME_SUN2BW2_CSR_ENABLE_VIDEO (0x8000) /* enable video */ ! 62: #define TME_SUN2BW2_CSR_ENABLE_COPY (0x4000) /* enable copy mode */ ! 63: #define TME_SUN2BW2_CSR_ENABLE_INT (0x2000) /* interrupt enable */ ! 64: #define TME_SUN2BW2_CSR_INT_ACTIVE (0x1000) /* interrupt is active */ ! 65: #define TME_SUN2BW2_CSR_JUMPER_B (0x0800) /* jumper B */ ! 66: #define TME_SUN2BW2_CSR_JUMPER_A (0x0400) /* jumper A */ ! 67: #define TME_SUN2BW2_CSR_JUMPER_COLOR (0x0200) /* jumper color */ ! 68: #define TME_SUN2BW2_CSR_JUMPER_HIRES (0x0100) /* jumper hires */ ! 69: #define TME_SUN2BW2_CSR_COPYBASE_MASK (0x007E) /* copybase mask */ ! 70: ! 71: #if 0 ! 72: #define TME_SUN2BW2_DEBUG ! 73: #endif ! 74: ! 75: /* structures: */ ! 76: ! 77: /* the card: */ ! 78: struct tme_sun2bw2 { ! 79: ! 80: /* our simple bus device header: */ ! 81: struct tme_bus_device tme_sun2bw2_device; ! 82: #define tme_sun2bw2_element tme_sun2bw2_device.tme_bus_device_element ! 83: ! 84: /* the mutex protecting the card: */ ! 85: tme_mutex_t tme_sun2bw2_mutex; ! 86: ! 87: /* the rwlock protecting the card: */ ! 88: tme_rwlock_t tme_sun2bw2_rwlock; ! 89: ! 90: /* the framebuffer connection: */ ! 91: struct tme_fb_connection *tme_sun2bw2_fb_connection; ! 92: ! 93: /* if our interrupt line is currently asserted: */ ! 94: int tme_sun2bw2_int_asserted; ! 95: ! 96: /* the (relative) bus address of our csr register: */ ! 97: tme_bus_addr_t tme_sun2bw2_csr_address; ! 98: ! 99: /* the (relative) bus address of the first byte after displayed ! 100: framebuffer memory: */ ! 101: tme_bus_addr_t tme_sun2bw2_end_address; ! 102: ! 103: /* the framebuffer memory: */ ! 104: tme_uint8_t *tme_sun2bw2_fb_memory; ! 105: ! 106: /* any pad memory: */ ! 107: tme_uint8_t *tme_sun2bw2_pad_memory; ! 108: ! 109: /* our csr: */ ! 110: tme_uint16_t tme_sun2bw2_csr; ! 111: }; ! 112: ! 113: /* globals: */ ! 114: ! 115: static const struct tme_bus_subregion _tme_sun2bw2_subregion_csr_obmem = { ! 116: TME_SUN2BW2_REG_CSR_OBMEM, ! 117: TME_SUN2BW2_REG_CSR_OBMEM ! 118: + TME_SUN2BW2_SIZ_CSR_PAGE ! 119: - 1, ! 120: NULL }; ! 121: static const struct tme_bus_subregion _tme_sun2bw2_subregion_csr_obio = { ! 122: TME_SUN2BW2_REG_CSR_OBIO, ! 123: TME_SUN2BW2_REG_CSR_OBIO ! 124: + TME_SUN2BW2_SIZ_CSR_PAGE ! 125: - 1, ! 126: NULL }; ! 127: ! 128: #ifdef TME_SUN2BW2_DEBUG ! 129: static int ! 130: _tme_sun2bw2_update_debug(struct tme_fb_connection *conn_fb) ! 131: { ! 132: struct tme_sun2bw2 *sun2bw2; ! 133: static int y = -1; ! 134: static int x; ! 135: unsigned long pixel; ! 136: unsigned int pixel_byte; ! 137: tme_uint8_t pixel_bit; ! 138: int box, box_y, box_x; ! 139: ! 140: sun2bw2 = conn_fb->tme_fb_connection.tme_connection_element->tme_element_private; ! 141: ! 142: for (box = 0; box < 2; box++) { ! 143: if (y < 0) { ! 144: y = 16; ! 145: x = 0; ! 146: continue; ! 147: } ! 148: for (box_y = 0; box_y < 2; box_y++) { ! 149: for (box_x = 0; box_x < 2; box_x++) { ! 150: pixel = (((y + box_y) ! 151: * TME_SUN2BW2_LO_WIDTH) ! 152: + x ! 153: + box_x); ! 154: pixel_byte = (pixel / 8); ! 155: pixel_bit = (0x80 >> (pixel % 8)); ! 156: sun2bw2->tme_sun2bw2_fb_memory[pixel_byte] ^= pixel_bit; ! 157: } ! 158: } ! 159: if (box == 0) { ! 160: x += 2; ! 161: if (x == TME_SUN2BW2_LO_WIDTH) { ! 162: x = 0; ! 163: y += 2; ! 164: if (y == TME_SUN2BW2_LO_HEIGHT) { ! 165: y = 0; ! 166: } ! 167: } ! 168: } ! 169: } ! 170: ! 171: return (TME_OK); ! 172: } ! 173: #endif /* TME_SUN2BW2_DEBUG */ ! 174: ! 175: /* the sun2bw2 framebuffer bus cycle handler: */ ! 176: static int ! 177: _tme_sun2bw2_bus_cycle_fb(void *_sun2bw2, struct tme_bus_cycle *cycle_init) ! 178: { ! 179: struct tme_sun2bw2 *sun2bw2; ! 180: ! 181: /* recover our data structure: */ ! 182: sun2bw2 = (struct tme_sun2bw2 *) _sun2bw2; ! 183: ! 184: /* lock the mutex: */ ! 185: tme_mutex_lock(&sun2bw2->tme_sun2bw2_mutex); ! 186: ! 187: /* run the cycle: */ ! 188: assert (cycle_init->tme_bus_cycle_address ! 189: >= TME_SUN2BW2_REG_MEM); ! 190: tme_bus_cycle_xfer_memory(cycle_init, ! 191: (sun2bw2->tme_sun2bw2_fb_memory ! 192: - TME_SUN2BW2_REG_MEM), ! 193: sun2bw2->tme_sun2bw2_end_address - 1); ! 194: ! 195: /* unlock the mutex: */ ! 196: tme_mutex_unlock(&sun2bw2->tme_sun2bw2_mutex); ! 197: ! 198: /* no faults: */ ! 199: return (TME_OK); ! 200: } ! 201: ! 202: /* the sun2bw2 pad bus cycle handler: */ ! 203: static int ! 204: _tme_sun2bw2_bus_cycle_pad(void *_sun2bw2, struct tme_bus_cycle *cycle_init) ! 205: { ! 206: struct tme_sun2bw2 *sun2bw2; ! 207: ! 208: /* recover our data structure: */ ! 209: sun2bw2 = (struct tme_sun2bw2 *) _sun2bw2; ! 210: ! 211: /* lock the mutex: */ ! 212: tme_mutex_lock(&sun2bw2->tme_sun2bw2_mutex); ! 213: ! 214: /* run the cycle: */ ! 215: assert (cycle_init->tme_bus_cycle_address ! 216: >= sun2bw2->tme_sun2bw2_end_address); ! 217: assert (sun2bw2->tme_sun2bw2_end_address ! 218: < TME_SUN2BW2_SIZ_MEM); ! 219: tme_bus_cycle_xfer_memory(cycle_init, ! 220: (sun2bw2->tme_sun2bw2_pad_memory ! 221: - sun2bw2->tme_sun2bw2_end_address), ! 222: ((TME_SUN2BW2_SIZ_MEM ! 223: - sun2bw2->tme_sun2bw2_end_address) ! 224: - 1)); ! 225: ! 226: /* unlock the mutex: */ ! 227: tme_mutex_unlock(&sun2bw2->tme_sun2bw2_mutex); ! 228: ! 229: /* no faults: */ ! 230: return (TME_OK); ! 231: } ! 232: ! 233: /* the sun2bw2 CSR bus cycle handler: */ ! 234: static int ! 235: _tme_sun2bw2_bus_cycle_csr(void *_sun2bw2, struct tme_bus_cycle *cycle_init) ! 236: { ! 237: struct tme_sun2bw2 *sun2bw2; ! 238: tme_uint16_t csr_old, csr_new; ! 239: tme_bus_addr_t undecoded; ! 240: ! 241: /* recover our data structure: */ ! 242: sun2bw2 = (struct tme_sun2bw2 *) _sun2bw2; ! 243: ! 244: /* lock the mutex: */ ! 245: tme_mutex_lock(&sun2bw2->tme_sun2bw2_mutex); ! 246: ! 247: /* get the old CSR value: */ ! 248: csr_old = tme_betoh_u16(sun2bw2->tme_sun2bw2_csr); ! 249: ! 250: /* the entire 2KB (one page's) worth of addresses at ! 251: tme_sun2bw2_csr_address are all decoded (or, rather, not decoded) ! 252: as the CSR: */ ! 253: undecoded ! 254: = (cycle_init->tme_bus_cycle_address ! 255: & (TME_SUN2BW2_SIZ_CSR_PAGE - 2)); ! 256: cycle_init->tme_bus_cycle_address ! 257: -= undecoded; ! 258: ! 259: /* run the cycle: */ ! 260: assert (cycle_init->tme_bus_cycle_address ! 261: >= sun2bw2->tme_sun2bw2_csr_address); ! 262: tme_bus_cycle_xfer_memory(cycle_init, ! 263: (((tme_uint8_t *) &sun2bw2->tme_sun2bw2_csr) ! 264: - sun2bw2->tme_sun2bw2_csr_address), ! 265: (sun2bw2->tme_sun2bw2_csr_address ! 266: + sizeof(sun2bw2->tme_sun2bw2_csr) ! 267: - 1)); ! 268: cycle_init->tme_bus_cycle_address ! 269: += undecoded; ! 270: ! 271: /* get the new CSR value: */ ! 272: csr_new = tme_betoh_u16(sun2bw2->tme_sun2bw2_csr); ! 273: ! 274: /* put back the unchanging bits: */ ! 275: csr_new ! 276: = ((csr_new ! 277: & ~(TME_SUN2BW2_CSR_INT_ACTIVE ! 278: | TME_SUN2BW2_CSR_JUMPER_B ! 279: | TME_SUN2BW2_CSR_JUMPER_A ! 280: | TME_SUN2BW2_CSR_JUMPER_COLOR ! 281: | TME_SUN2BW2_CSR_JUMPER_HIRES)) ! 282: | (csr_old ! 283: & (TME_SUN2BW2_CSR_INT_ACTIVE ! 284: | TME_SUN2BW2_CSR_JUMPER_B ! 285: | TME_SUN2BW2_CSR_JUMPER_A ! 286: | TME_SUN2BW2_CSR_JUMPER_COLOR ! 287: | TME_SUN2BW2_CSR_JUMPER_HIRES))); ! 288: ! 289: /* we do not support these bits: */ ! 290: if (csr_new ! 291: & (TME_SUN2BW2_CSR_ENABLE_COPY ! 292: | TME_SUN2BW2_CSR_ENABLE_INT)) { ! 293: abort(); ! 294: } ! 295: ! 296: /* set the new CSR value: */ ! 297: sun2bw2->tme_sun2bw2_csr = tme_htobe_u16(csr_new); ! 298: ! 299: /* unlock the mutex: */ ! 300: tme_mutex_unlock(&sun2bw2->tme_sun2bw2_mutex); ! 301: ! 302: /* no faults: */ ! 303: return (TME_OK); ! 304: } ! 305: ! 306: /* the sun2bw2 TLB filler: */ ! 307: static int ! 308: _tme_sun2bw2_tlb_fill(void *_sun2bw2, struct tme_bus_tlb *tlb, ! 309: tme_bus_addr_t address, unsigned int cycles) ! 310: { ! 311: struct tme_sun2bw2 *sun2bw2; ! 312: ! 313: /* recover our data structure: */ ! 314: sun2bw2 = (struct tme_sun2bw2 *) _sun2bw2; ! 315: ! 316: /* initialize the TLB entry: */ ! 317: tme_bus_tlb_initialize(tlb); ! 318: ! 319: /* if the address falls in the CSR: */ ! 320: if ((sun2bw2->tme_sun2bw2_csr_address ! 321: <= address) ! 322: && (address ! 323: < (sun2bw2->tme_sun2bw2_csr_address ! 324: + TME_SUN2BW2_SIZ_CSR_PAGE))) { ! 325: ! 326: tlb->tme_bus_tlb_cycle = _tme_sun2bw2_bus_cycle_csr; ! 327: ! 328: /* this TLB entry covers this range: */ ! 329: TME_ATOMIC_WRITE(tme_bus_addr_t, ! 330: tlb->tme_bus_tlb_addr_first, ! 331: sun2bw2->tme_sun2bw2_csr_address); ! 332: TME_ATOMIC_WRITE(tme_bus_addr_t, ! 333: tlb->tme_bus_tlb_addr_last, ! 334: (sun2bw2->tme_sun2bw2_csr_address ! 335: + TME_SUN2BW2_SIZ_CSR ! 336: - 1)); ! 337: ! 338: /* this TLB entry cannot allow fast reading, since the page the ! 339: CSR is on isn't fully decoded - all words on the 2KB page are ! 340: the CSR: */ ! 341: } ! 342: ! 343: /* if this address falls in the displayed framebuffer memory: */ ! 344: else if ((TME_SUN2BW2_REG_MEM ! 345: <= address) ! 346: && (address ! 347: < sun2bw2->tme_sun2bw2_end_address)) { ! 348: ! 349: assert (sun2bw2->tme_sun2bw2_fb_connection != NULL); ! 350: ! 351: tlb->tme_bus_tlb_cycle = _tme_sun2bw2_bus_cycle_fb; ! 352: ! 353: /* this TLB entry covers this range: */ ! 354: TME_ATOMIC_WRITE(tme_bus_addr_t, ! 355: tlb->tme_bus_tlb_addr_first, ! 356: TME_SUN2BW2_REG_MEM); ! 357: TME_ATOMIC_WRITE(tme_bus_addr_t, ! 358: tlb->tme_bus_tlb_addr_last, ! 359: sun2bw2->tme_sun2bw2_end_address); ! 360: ! 361: /* this TLB entry allows fast reading and writing: */ ! 362: tlb->tme_bus_tlb_emulator_off_read ! 363: = (sun2bw2->tme_sun2bw2_fb_memory ! 364: - TME_SUN2BW2_REG_MEM); ! 365: tlb->tme_bus_tlb_emulator_off_write ! 366: = (sun2bw2->tme_sun2bw2_fb_memory ! 367: - TME_SUN2BW2_REG_MEM); ! 368: } ! 369: ! 370: /* if this address falls in the pad memory: */ ! 371: else if ((sun2bw2->tme_sun2bw2_end_address ! 372: <= address) ! 373: && (address ! 374: < (TME_SUN2BW2_REG_MEM ! 375: + TME_SUN2BW2_SIZ_MEM))) { ! 376: ! 377: tlb->tme_bus_tlb_cycle = _tme_sun2bw2_bus_cycle_pad; ! 378: ! 379: /* this TLB entry covers this range: */ ! 380: TME_ATOMIC_WRITE(tme_bus_addr_t, ! 381: tlb->tme_bus_tlb_addr_first, ! 382: sun2bw2->tme_sun2bw2_end_address); ! 383: TME_ATOMIC_WRITE(tme_bus_addr_t, ! 384: tlb->tme_bus_tlb_addr_last, ! 385: (TME_SUN2BW2_REG_MEM ! 386: + TME_SUN2BW2_SIZ_MEM)); ! 387: ! 388: /* this TLB entry allows fast reading and writing: */ ! 389: tlb->tme_bus_tlb_emulator_off_read ! 390: = (sun2bw2->tme_sun2bw2_pad_memory ! 391: - sun2bw2->tme_sun2bw2_end_address); ! 392: tlb->tme_bus_tlb_emulator_off_write ! 393: = (sun2bw2->tme_sun2bw2_pad_memory ! 394: - sun2bw2->tme_sun2bw2_end_address); ! 395: } ! 396: ! 397: /* the fast reading and writing rwlock: */ ! 398: tlb->tme_bus_tlb_rwlock = &sun2bw2->tme_sun2bw2_rwlock; ! 399: ! 400: /* allow reading and writing: */ ! 401: tlb->tme_bus_tlb_cycles_ok = TME_BUS_CYCLE_READ | TME_BUS_CYCLE_WRITE; ! 402: ! 403: /* our bus cycle handler private data: */ ! 404: tlb->tme_bus_tlb_cycle_private = _sun2bw2; ! 405: ! 406: return (TME_OK); ! 407: } ! 408: ! 409: /* this makes a new framebuffer connection: */ ! 410: static int ! 411: _tme_sun2bw2_connection_make(struct tme_connection *conn, unsigned int state) ! 412: { ! 413: struct tme_sun2bw2 *sun2bw2; ! 414: struct tme_fb_connection *conn_fb; ! 415: struct tme_fb_connection *conn_fb_other; ! 416: int rc; ! 417: ! 418: /* recover our data structures: */ ! 419: sun2bw2 = conn->tme_connection_element->tme_element_private; ! 420: conn_fb = (struct tme_fb_connection *) conn; ! 421: conn_fb_other = (struct tme_fb_connection *) conn->tme_connection_other; ! 422: ! 423: /* both sides must be framebuffer connections: */ ! 424: assert(conn->tme_connection_type == TME_CONNECTION_FRAMEBUFFER); ! 425: assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_FRAMEBUFFER); ! 426: ! 427: /* lock our mutex: */ ! 428: tme_mutex_lock(&sun2bw2->tme_sun2bw2_mutex); ! 429: ! 430: /* once the connection is made, we know whether or not the other ! 431: side of the connection is supplying specific memory that it wants ! 432: us to use, or if we should allocate memory ourselves: */ ! 433: if (conn_fb->tme_fb_connection_buffer == NULL) { ! 434: rc = tme_fb_xlat_alloc_src(conn_fb); ! 435: assert (rc == TME_OK); ! 436: sun2bw2->tme_sun2bw2_fb_memory = conn_fb->tme_fb_connection_buffer; ! 437: } ! 438: ! 439: /* we're always set up to answer calls across the connection, so we ! 440: only have to do work when the connection has gone full, namely ! 441: taking the other side of the connection: */ ! 442: if (state == TME_CONNECTION_FULL) { ! 443: ! 444: /* save our connection: */ ! 445: sun2bw2->tme_sun2bw2_fb_connection = conn_fb_other; ! 446: } ! 447: ! 448: /* unlock our mutex: */ ! 449: tme_mutex_unlock(&sun2bw2->tme_sun2bw2_mutex); ! 450: ! 451: return (TME_OK); ! 452: } ! 453: ! 454: /* this breaks a connection: */ ! 455: static int ! 456: _tme_sun2bw2_connection_break(struct tme_connection *conn, unsigned int state) ! 457: { ! 458: abort(); ! 459: } ! 460: ! 461: /* this makes a new connection side for a sun2bw2: */ ! 462: static int ! 463: _tme_sun2bw2_connections_new(struct tme_element *element, ! 464: const char * const *args, ! 465: struct tme_connection **_conns, ! 466: char **_output) ! 467: { ! 468: struct tme_sun2bw2 *sun2bw2; ! 469: struct tme_fb_connection *conn_fb; ! 470: struct tme_connection *conn; ! 471: int rc; ! 472: ! 473: /* recover our data structure: */ ! 474: sun2bw2 = (struct tme_sun2bw2 *) element->tme_element_private; ! 475: ! 476: /* make the generic bus device connection side: */ ! 477: rc = tme_bus_device_connections_new(element, args, _conns, _output); ! 478: if (rc != TME_OK) { ! 479: return (rc); ! 480: } ! 481: ! 482: /* if we don't have a framebuffer connection, make one: */ ! 483: if (sun2bw2->tme_sun2bw2_fb_connection == NULL) { ! 484: ! 485: /* allocate the new framebuffer connection: */ ! 486: conn_fb = tme_new0(struct tme_fb_connection, 1); ! 487: conn = &conn_fb->tme_fb_connection; ! 488: ! 489: /* fill in the generic connection: */ ! 490: conn->tme_connection_next = *_conns; ! 491: conn->tme_connection_type = TME_CONNECTION_FRAMEBUFFER; ! 492: conn->tme_connection_score = tme_fb_connection_score; ! 493: conn->tme_connection_make = _tme_sun2bw2_connection_make; ! 494: conn->tme_connection_break = _tme_sun2bw2_connection_break; ! 495: ! 496: /* fill in the framebuffer connection: */ ! 497: conn_fb->tme_fb_connection_mode_change = NULL; ! 498: #ifdef TME_SUN2BW2_DEBUG ! 499: conn_fb->tme_fb_connection_update = _tme_sun2bw2_update_debug; ! 500: #else /* !TME_SUN2BW2_DEBUG */ ! 501: conn_fb->tme_fb_connection_update = NULL; ! 502: #endif /* !TME_SUN2BW2_DEBUG */ ! 503: ! 504: /* height and width depend on the hires jumper: */ ! 505: if (sun2bw2->tme_sun2bw2_csr ! 506: & TME_SUN2BW2_CSR_JUMPER_HIRES) { ! 507: conn_fb->tme_fb_connection_width = TME_SUN2BW2_HI_WIDTH; ! 508: conn_fb->tme_fb_connection_height = TME_SUN2BW2_HI_HEIGHT; ! 509: } ! 510: else { ! 511: conn_fb->tme_fb_connection_width = TME_SUN2BW2_LO_WIDTH; ! 512: conn_fb->tme_fb_connection_height = TME_SUN2BW2_LO_HEIGHT; ! 513: } ! 514: ! 515: /* we are monochrome: */ ! 516: conn_fb->tme_fb_connection_depth = 1; ! 517: conn_fb->tme_fb_connection_bits_per_pixel = 1; ! 518: ! 519: /* we skip no pixels at the start of the scanline: */ ! 520: conn_fb->tme_fb_connection_skipx = 0; ! 521: ! 522: /* we pad to 32-bit boundaries: */ ! 523: conn_fb->tme_fb_connection_scanline_pad = 32; ! 524: ! 525: /* we are big-endian: */ ! 526: conn_fb->tme_fb_connection_order = TME_ENDIAN_BIG; ! 527: ! 528: /* we don't allocate memory until the connection is made, in case ! 529: the other side of the connection wants to provide us with a ! 530: specific memory region to use (maybe we're on a system with a ! 531: real bwtwo and we can write directly to its buffer): */ ! 532: conn_fb->tme_fb_connection_buffer = NULL; ! 533: ! 534: /* return the connection side possibility: */ ! 535: *_conns = conn; ! 536: } ! 537: ! 538: /* done: */ ! 539: return (TME_OK); ! 540: } ! 541: ! 542: /* the new _sun2bw2 function: */ ! 543: TME_ELEMENT_SUB_NEW_DECL(tme_machine_sun2,bwtwo) { ! 544: struct tme_sun2bw2 *sun2bw2; ! 545: struct tme_bus_subregion *subregion; ! 546: const char *bw2_type; ! 547: int arg_i; ! 548: int usage; ! 549: ! 550: /* check our arguments: */ ! 551: usage = 0; ! 552: bw2_type = NULL; ! 553: arg_i = 1; ! 554: for (;;) { ! 555: ! 556: /* the framebuffer type: */ ! 557: if (TME_ARG_IS(args[arg_i + 0], "type")) { ! 558: bw2_type = args[arg_i + 1]; ! 559: if (bw2_type == NULL ! 560: || (strcmp(bw2_type, "obmem") ! 561: && strcmp(bw2_type, "obio"))) { ! 562: usage = TRUE; ! 563: break; ! 564: } ! 565: arg_i += 2; ! 566: } ! 567: ! 568: /* if we ran out of arguments: */ ! 569: else if (args[arg_i] == NULL) { ! 570: ! 571: break; ! 572: } ! 573: ! 574: /* otherwise this is a bad argument: */ ! 575: else { ! 576: tme_output_append_error(_output, ! 577: "%s %s, ", ! 578: args[arg_i], ! 579: _("unexpected")); ! 580: usage = TRUE; ! 581: break; ! 582: } ! 583: } ! 584: ! 585: if (usage) { ! 586: tme_output_append_error(_output, ! 587: "%s %s type { obmem | obio }", ! 588: _("usage:"), ! 589: args[0]); ! 590: return (EINVAL); ! 591: } ! 592: ! 593: /* start the sun2bw2 structure: */ ! 594: sun2bw2 = tme_new0(struct tme_sun2bw2, 1); ! 595: sun2bw2->tme_sun2bw2_element = element; ! 596: tme_mutex_init(&sun2bw2->tme_sun2bw2_mutex); ! 597: tme_rwlock_init(&sun2bw2->tme_sun2bw2_rwlock); ! 598: ! 599: /* set our initial CSR: */ ! 600: sun2bw2->tme_sun2bw2_csr ! 601: = tme_htobe_u16(TME_SUN2BW2_CSR_ENABLE_VIDEO); ! 602: ! 603: /* if we're high-resolution: */ ! 604: if (sun2bw2->tme_sun2bw2_csr ! 605: & TME_SUN2BW2_CSR_JUMPER_HIRES) { ! 606: ! 607: /* set the address after the end of displayed framebuffer memory: */ ! 608: sun2bw2->tme_sun2bw2_end_address ! 609: = (TME_SUN2BW2_REG_MEM ! 610: + (TME_SUN2BW2_HI_WIDTH ! 611: * TME_SUN2BW2_HI_HEIGHT ! 612: / 8)); ! 613: ! 614: /* we don't need any pad memory: */ ! 615: sun2bw2->tme_sun2bw2_pad_memory = NULL; ! 616: } ! 617: ! 618: /* otherwise, we're low-resolution: */ ! 619: else { ! 620: ! 621: /* set the address after the end of displayed framebuffer memory: */ ! 622: sun2bw2->tme_sun2bw2_end_address ! 623: = (TME_SUN2BW2_REG_MEM ! 624: + (TME_SUN2BW2_LO_WIDTH ! 625: * TME_SUN2BW2_LO_HEIGHT ! 626: / 8)); ! 627: ! 628: /* allocate the pad memory: */ ! 629: sun2bw2->tme_sun2bw2_pad_memory ! 630: = tme_new0(tme_uint8_t, ! 631: (TME_SUN2BW2_REG_MEM ! 632: + TME_SUN2BW2_SIZ_MEM ! 633: - sun2bw2->tme_sun2bw2_end_address)); ! 634: } ! 635: ! 636: /* initialize our simple bus device descriptor: */ ! 637: sun2bw2->tme_sun2bw2_device.tme_bus_device_element = element; ! 638: sun2bw2->tme_sun2bw2_device.tme_bus_device_tlb_fill = _tme_sun2bw2_tlb_fill; ! 639: subregion = &sun2bw2->tme_sun2bw2_device.tme_bus_device_subregions; ! 640: subregion->tme_bus_subregion_address_first ! 641: = TME_SUN2BW2_REG_MEM; ! 642: subregion->tme_bus_subregion_address_last ! 643: = TME_SUN2BW2_SIZ_MEM; ! 644: subregion->tme_bus_subregion_next ! 645: = (!strcmp(bw2_type, "obmem") ! 646: ? &_tme_sun2bw2_subregion_csr_obmem ! 647: : &_tme_sun2bw2_subregion_csr_obio); ! 648: sun2bw2->tme_sun2bw2_csr_address ! 649: = subregion->tme_bus_subregion_next->tme_bus_subregion_address_first; ! 650: ! 651: /* fill the element: */ ! 652: element->tme_element_private = sun2bw2; ! 653: element->tme_element_connections_new = _tme_sun2bw2_connections_new; ! 654: ! 655: return (TME_OK); ! 656: } ! 657:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.