|
|
1.1.1.3 ! root 1: /* $Id: sun-bwtwo.c,v 1.6 2009/11/08 17:03:58 fredette Exp $ */ 1.1 root 2: 3: /* machine/sun/sun-bwtwo.c - Sun bwtwo emulation: */ 4: 5: /* 1.1.1.2 root 6: * Copyright (c) 2003, 2004, 2006 Matt Fredette 1.1 root 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> 1.1.1.3 ! root 37: _TME_RCSID("$Id: sun-bwtwo.c,v 1.6 2009/11/08 17:03:58 fredette Exp $"); 1.1 root 38: 39: /* includes: */ 40: #include <tme/machine/sun.h> 41: #include <tme/generic/bus-device.h> 42: #include <tme/generic/fb.h> 43: #include "sun-fb.h" 44: 45: /* macros: */ 46: 47: /* bwtwo types: */ 48: #define TME_SUNBW2_TYPE_NULL (0) 49: #define TME_SUNBW2_TYPE_MULTIBUS (1) 50: #define TME_SUNBW2_TYPE_OLD_ONBOARD (2) 51: #define TME_SUNBW2_TYPE_ONBOARD (3) 52: #define TME_SUNBW2_TYPE_P4 (4) 1.1.1.2 root 53: #define TME_SUNBW2_TYPE_SBUS (5) 1.1 root 54: 55: /* register offsets and sizes: */ 56: #define TME_SUNBW2_REG_CSR_MULTIBUS (0x81800) 57: #define TME_SUNBW2_REG_CSR_OLD_ONBOARD (0x20000) 58: #define TME_SUNBW2_SIZ_CSR (0x00002) 59: #define TME_SUNBW2_SIZ_CSR_PAGE (0x00800) 60: 61: /* the bits in the Multibus and old-onboard Control/Status register: */ 62: #define TME_SUNBW2_CSR_ENABLE_VIDEO (0x8000) /* enable video */ 63: #define TME_SUNBW2_CSR_ENABLE_COPY (0x4000) /* enable copy mode */ 64: #define TME_SUNBW2_CSR_ENABLE_INT (0x2000) /* interrupt enable */ 65: #define TME_SUNBW2_CSR_INT_ACTIVE (0x1000) /* interrupt is active */ 66: #define TME_SUNBW2_CSR_JUMPER_B (0x0800) /* jumper B */ 67: #define TME_SUNBW2_CSR_JUMPER_A (0x0400) /* jumper A */ 68: #define TME_SUNBW2_CSR_JUMPER_COLOR (0x0200) /* jumper color */ 69: #define TME_SUNBW2_CSR_JUMPER_HIRES (0x0100) /* jumper hires */ 70: #define TME_SUNBW2_CSR_COPYBASE_MASK (0x007E) /* copybase mask */ 71: 72: #if 0 73: #define TME_SUNBW2_DEBUG 74: #endif 75: 76: /* structures: */ 77: 78: /* the card: */ 79: struct tme_sunbw2 { 80: 1.1.1.2 root 81: /* our generic Sun framebuffer: */ 82: struct tme_sunfb tme_sunbw2_sunfb; 83: #define tme_sunbw2_mutex tme_sunbw2_sunfb.tme_sunfb_mutex 84: #define tme_sunbw2_bus_subregion_memory tme_sunbw2_sunfb.tme_sunfb_bus_subregion_memory 85: #define tme_sunbw2_bus_subregion_regs tme_sunbw2_sunfb.tme_sunfb_bus_subregion_regs 86: #define tme_sunbw2_csr_address tme_sunbw2_bus_subregion_regs.tme_bus_subregion_address_first 1.1 root 87: 88: /* the type of the bwtwo: */ 89: tme_uint32_t tme_sunbw2_type; 90: 91: /* our csr: */ 92: tme_uint16_t tme_sunbw2_csr; 93: }; 94: 95: #ifdef TME_SUNBW2_DEBUG 96: #define TME_SUNBW2_LO_WIDTH (1152) 97: #define TME_SUNBW2_LO_HEIGHT (900) 98: static int 99: _tme_sunbw2_update_debug(struct tme_fb_connection *conn_fb) 100: { 101: struct tme_sunbw2 *sunbw2; 102: static int y = -1; 103: static int x; 104: unsigned long pixel; 105: unsigned int pixel_byte; 106: tme_uint8_t pixel_bit; 107: int box, box_y, box_x; 108: 109: sunbw2 = conn_fb->tme_fb_connection.tme_connection_element->tme_element_private; 110: 111: for (box = 0; box < 2; box++) { 112: if (y < 0) { 113: y = 16; 114: x = 0; 115: continue; 116: } 117: for (box_y = 0; box_y < 2; box_y++) { 118: for (box_x = 0; box_x < 2; box_x++) { 119: pixel = (((y + box_y) 120: * TME_SUNBW2_LO_WIDTH) 121: + x 122: + box_x); 123: pixel_byte = (pixel / 8); 124: pixel_bit = (0x80 >> (pixel % 8)); 125: sunbw2->tme_sunbw2_fb_memory[pixel_byte] ^= pixel_bit; 126: } 127: } 128: if (box == 0) { 129: x += 2; 130: if (x == TME_SUNBW2_LO_WIDTH) { 131: x = 0; 132: y += 2; 133: if (y == TME_SUNBW2_LO_HEIGHT) { 134: y = 0; 135: } 136: } 137: } 138: } 139: 140: return (TME_OK); 141: } 142: #undef TME_SUNBW2_LO_WIDTH 143: #undef TME_SUNBW2_LO_HEIGHT 144: #endif /* TME_SUNBW2_DEBUG */ 145: 146: /* the sunbw2 CSR bus cycle handler: */ 147: static int 148: _tme_sunbw2_bus_cycle_csr(void *_sunbw2, struct tme_bus_cycle *cycle_init) 149: { 150: struct tme_sunbw2 *sunbw2; 151: tme_uint16_t csr_old, csr_new; 1.1.1.3 ! root 152: tme_bus_addr32_t undecoded; 1.1 root 153: 154: /* recover our data structure: */ 155: sunbw2 = (struct tme_sunbw2 *) _sunbw2; 156: 157: /* lock the mutex: */ 158: tme_mutex_lock(&sunbw2->tme_sunbw2_mutex); 159: 160: /* get the old CSR value: */ 161: csr_old = tme_betoh_u16(sunbw2->tme_sunbw2_csr); 162: 163: /* the entire 2KB (one page's) worth of addresses at 164: tme_sunbw2_csr_address are all decoded (or, rather, not decoded) 165: as the CSR: */ 166: undecoded 167: = (cycle_init->tme_bus_cycle_address 168: & (TME_SUNBW2_SIZ_CSR_PAGE - sizeof(sunbw2->tme_sunbw2_csr))); 169: cycle_init->tme_bus_cycle_address 170: -= undecoded; 171: 172: /* run the cycle: */ 173: assert (cycle_init->tme_bus_cycle_address 174: >= sunbw2->tme_sunbw2_csr_address); 175: tme_bus_cycle_xfer_memory(cycle_init, 176: (((tme_uint8_t *) &sunbw2->tme_sunbw2_csr) 177: - sunbw2->tme_sunbw2_csr_address), 178: (sunbw2->tme_sunbw2_csr_address 179: + sizeof(sunbw2->tme_sunbw2_csr) 180: - 1)); 181: cycle_init->tme_bus_cycle_address 182: += undecoded; 183: 184: /* get the new CSR value: */ 185: csr_new = tme_betoh_u16(sunbw2->tme_sunbw2_csr); 186: 187: /* put back the unchanging bits: */ 188: csr_new 189: = ((csr_new 190: & ~(TME_SUNBW2_CSR_INT_ACTIVE 191: | TME_SUNBW2_CSR_JUMPER_B 192: | TME_SUNBW2_CSR_JUMPER_A 193: | TME_SUNBW2_CSR_JUMPER_COLOR 194: | TME_SUNBW2_CSR_JUMPER_HIRES)) 195: | (csr_old 196: & (TME_SUNBW2_CSR_INT_ACTIVE 197: | TME_SUNBW2_CSR_JUMPER_B 198: | TME_SUNBW2_CSR_JUMPER_A 199: | TME_SUNBW2_CSR_JUMPER_COLOR 200: | TME_SUNBW2_CSR_JUMPER_HIRES))); 201: 202: /* we do not support these bits: */ 203: if (csr_new 204: & (TME_SUNBW2_CSR_ENABLE_COPY 205: | TME_SUNBW2_CSR_ENABLE_INT)) { 206: abort(); 207: } 208: 209: /* set the new CSR value: */ 210: sunbw2->tme_sunbw2_csr = tme_htobe_u16(csr_new); 211: 212: /* unlock the mutex: */ 213: tme_mutex_unlock(&sunbw2->tme_sunbw2_mutex); 214: 215: /* no faults: */ 216: return (TME_OK); 217: } 218: 1.1.1.2 root 219: /* this sets the bwtwo type: */ 220: static const char * 221: _tme_sunbw2_type_set(struct tme_sunfb *sunfb, const char *bw2_type_string) 1.1 root 222: { 223: struct tme_sunbw2 *sunbw2; 1.1.1.2 root 224: tme_uint32_t bw2_type; 1.1 root 225: 226: /* recover our data structure: */ 1.1.1.2 root 227: sunbw2 = (struct tme_sunbw2 *) sunfb; 1.1 root 228: 1.1.1.2 root 229: /* see if this is a good type: */ 230: bw2_type = TME_SUNBW2_TYPE_NULL; 231: if (TME_ARG_IS(bw2_type_string, "multibus")) { 232: bw2_type = TME_SUNBW2_TYPE_MULTIBUS; 1.1 root 233: } 1.1.1.2 root 234: else if (TME_ARG_IS(bw2_type_string, "old-onboard")) { 235: bw2_type = TME_SUNBW2_TYPE_OLD_ONBOARD; 1.1 root 236: } 1.1.1.2 root 237: else if (TME_ARG_IS(bw2_type_string, "onboard")) { 238: bw2_type = TME_SUNBW2_TYPE_ONBOARD; 1.1 root 239: } 1.1.1.2 root 240: else if (TME_ARG_IS(bw2_type_string, "P4")) { 241: bw2_type = TME_SUNBW2_TYPE_P4; 1.1 root 242: } 1.1.1.2 root 243: else if (TME_ARG_IS(bw2_type_string, "sbus")) { 244: bw2_type = TME_SUNBW2_TYPE_SBUS; 1.1 root 245: } 246: 1.1.1.2 root 247: /* set the new type: */ 248: sunbw2->tme_sunbw2_type = bw2_type; 1.1 root 249: 1.1.1.2 root 250: /* assume the (relative) bus address of the first byte of displayed 251: framebuffer memory is zero: */ 252: sunbw2->tme_sunbw2_bus_subregion_memory.tme_bus_subregion_address_first = 0; 1.1 root 253: 1.1.1.3 ! root 254: /* assume that we can use the unspecified interrupt: */ ! 255: sunfb->tme_sunfb_bus_signal_int = TME_BUS_SIGNAL_INT_UNSPEC; ! 256: 1.1.1.2 root 257: /* dispatch on the new type: */ 258: switch (bw2_type) { 1.1 root 259: 1.1.1.2 root 260: /* if this was a bad type, return a string of types: */ 261: default: assert(FALSE); 262: case TME_SUNBW2_TYPE_NULL: 263: return ("multibus | old-onboard | onboard | P4 | sbus"); 1.1 root 264: 1.1.1.2 root 265: case TME_SUNBW2_TYPE_MULTIBUS: 266: case TME_SUNBW2_TYPE_OLD_ONBOARD: 267: 268: /* set the addresses of the CSR bus subregion: */ 269: sunbw2->tme_sunbw2_csr_address 270: = (bw2_type == TME_SUNBW2_TYPE_MULTIBUS 271: ? TME_SUNBW2_REG_CSR_MULTIBUS 272: : TME_SUNBW2_REG_CSR_OLD_ONBOARD); 273: sunbw2->tme_sunbw2_bus_subregion_regs.tme_bus_subregion_address_last 274: = (sunbw2->tme_sunbw2_csr_address 275: + TME_SUNBW2_SIZ_CSR_PAGE 276: - 1); 1.1 root 277: 1.1.1.2 root 278: /* set the CSR bus cycle handler: */ 279: sunfb->tme_sunfb_bus_handler_regs = _tme_sunbw2_bus_cycle_csr; 1.1 root 280: 1.1.1.2 root 281: /* the original Multibus bwtwo and onboard bwtwo only support 282: 1152x900 and 1024x1024: */ 283: sunfb->tme_sunfb_size 284: = (TME_SUNFB_SIZE_1152_900 285: | TME_SUNFB_SIZE_1024_1024); 286: break; 1.1 root 287: 1.1.1.2 root 288: case TME_SUNBW2_TYPE_ONBOARD: 1.1 root 289: 1.1.1.2 root 290: /* the onboard bwtwo doesn't have any CSR: */ 291: sunfb->tme_sunfb_bus_handler_regs = NULL; 292: 293: /* the sizes supported by a CSR-less bwtwo appear to depend on the 294: actual model; we assume the user knows what he is doing: */ 295: sunfb->tme_sunfb_size = (TME_SUNFB_SIZE_NULL - 1); 296: break; 1.1 root 297: 1.1.1.2 root 298: case TME_SUNBW2_TYPE_P4: 1.1 root 299: 1.1.1.2 root 300: /* set our initial P4 register: */ 301: sunfb->tme_sunfb_p4 = tme_htobe_u32(TME_SUNFB_P4_ID_BWTWO); 1.1 root 302: 1.1.1.2 root 303: /* set the P4 register bus cycle handler: */ 304: sunfb->tme_sunfb_bus_handler_regs = tme_sunfb_bus_cycle_p4; 1.1 root 305: 1.1.1.2 root 306: /* we support the default P4 framebuffer sizes: */ 307: sunfb->tme_sunfb_size = 0; 1.1 root 308: 1.1.1.2 root 309: /* the framebuffer memory begins at a fixed offset after the P4 register: */ 310: sunbw2->tme_sunbw2_bus_subregion_memory.tme_bus_subregion_address_first 311: = TME_SUNFB_P4_OFFSET_BITMAP; 1.1 root 312: 1.1.1.2 root 313: break; 1.1 root 314: 1.1.1.2 root 315: case TME_SUNBW2_TYPE_SBUS: 1.1 root 316: 1.1.1.2 root 317: /* set the S4 register bus cycle handler: */ 318: sunfb->tme_sunfb_bus_handler_regs = tme_sunfb_bus_cycle_s4; 1.1 root 319: 1.1.1.2 root 320: /* we support the default S4 framebuffer sizes: */ 321: sunfb->tme_sunfb_size = 0; 1.1 root 322: 1.1.1.2 root 323: /* we use the default S4 memory address: */ 324: sunbw2->tme_sunbw2_bus_subregion_memory.tme_bus_subregion_address_first = 0; 1.1 root 325: 1.1.1.3 ! root 326: /* the SBus bwtwo uses priority seven interrupts: */ ! 327: sunfb->tme_sunfb_bus_signal_int = TME_BUS_SIGNAL_INT(7); ! 328: 1.1.1.2 root 329: break; 1.1 root 330: } 331: 1.1.1.2 root 332: /* success: */ 333: return (NULL); 1.1 root 334: } 335: 336: /* the new sun bwtwo function: */ 337: int 338: tme_sun_bwtwo(struct tme_element *element, const char * const *args, char **_output) 339: { 340: struct tme_sunbw2 *sunbw2; 1.1.1.2 root 341: int rc; 1.1 root 342: 343: /* start the sunbw2 structure: */ 344: sunbw2 = tme_new0(struct tme_sunbw2, 1); 1.1.1.2 root 345: sunbw2->tme_sunbw2_sunfb.tme_sunfb_element = element; 1.1 root 346: 1.1.1.2 root 347: /* initialize the sunfb structure: */ 348: sunbw2->tme_sunbw2_sunfb.tme_sunfb_class = TME_FB_XLAT_CLASS_MONOCHROME; 349: sunbw2->tme_sunbw2_sunfb.tme_sunfb_depth = 1; 350: sunbw2->tme_sunbw2_sunfb.tme_sunfb_type_set = _tme_sunbw2_type_set; 351: 352: /* if the generic initialization fails: */ 353: rc = tme_sunfb_new(&sunbw2->tme_sunbw2_sunfb, args, _output); 354: if (rc) { 1.1 root 355: 1.1.1.2 root 356: /* free the sunfb structure and return the error: */ 357: tme_free(sunbw2); 358: return (rc); 1.1 root 359: } 360: 361: /* dispatch on the bwtwo type: */ 1.1.1.2 root 362: switch (sunbw2->tme_sunbw2_type) { 363: default: break; 1.1 root 364: case TME_SUNBW2_TYPE_MULTIBUS: 365: case TME_SUNBW2_TYPE_OLD_ONBOARD: 366: 367: /* set our initial CSR: */ 368: sunbw2->tme_sunbw2_csr 369: = tme_htobe_u16(TME_SUNBW2_CSR_ENABLE_VIDEO 1.1.1.2 root 370: | (sunbw2->tme_sunbw2_sunfb.tme_sunfb_size == TME_SUNFB_SIZE_1024_1024 1.1 root 371: ? TME_SUNBW2_CSR_JUMPER_HIRES 372: : 0)); 373: 374: break; 375: } 376: 377: return (TME_OK); 378: } 379:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.