Annotation of tme/machine/sun2/sun2-bwtwo.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.