Annotation of qemu/hw/cuda.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  * QEMU CUDA support
                      3:  * 
                      4:  * Copyright (c) 2004 Fabrice Bellard
                      5:  * 
                      6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
                     24: #include "vl.h"
                     25: 
                     26: /* XXX: implement all timer modes */
                     27: 
                     28: //#define DEBUG_CUDA
                     29: //#define DEBUG_CUDA_PACKET
                     30: 
                     31: /* Bits in B data register: all active low */
                     32: #define TREQ           0x08            /* Transfer request (input) */
                     33: #define TACK           0x10            /* Transfer acknowledge (output) */
                     34: #define TIP            0x20            /* Transfer in progress (output) */
                     35: 
                     36: /* Bits in ACR */
                     37: #define SR_CTRL                0x1c            /* Shift register control bits */
                     38: #define SR_EXT         0x0c            /* Shift on external clock */
                     39: #define SR_OUT         0x10            /* Shift out if 1 */
                     40: 
                     41: /* Bits in IFR and IER */
                     42: #define IER_SET                0x80            /* set bits in IER */
                     43: #define IER_CLR                0               /* clear bits in IER */
                     44: #define SR_INT         0x04            /* Shift register full/empty */
                     45: #define T1_INT          0x40            /* Timer 1 interrupt */
                     46: #define T2_INT          0x20            /* Timer 2 interrupt */
                     47: 
                     48: /* Bits in ACR */
                     49: #define T1MODE          0xc0            /* Timer 1 mode */
                     50: #define T1MODE_CONT     0x40            /*  continuous interrupts */
                     51: 
                     52: /* commands (1st byte) */
                     53: #define ADB_PACKET     0
                     54: #define CUDA_PACKET    1
                     55: #define ERROR_PACKET   2
                     56: #define TIMER_PACKET   3
                     57: #define POWER_PACKET   4
                     58: #define MACIIC_PACKET  5
                     59: #define PMU_PACKET     6
                     60: 
                     61: 
                     62: /* CUDA commands (2nd byte) */
                     63: #define CUDA_WARM_START                        0x0
                     64: #define CUDA_AUTOPOLL                  0x1
                     65: #define CUDA_GET_6805_ADDR             0x2
                     66: #define CUDA_GET_TIME                  0x3
                     67: #define CUDA_GET_PRAM                  0x7
                     68: #define CUDA_SET_6805_ADDR             0x8
                     69: #define CUDA_SET_TIME                  0x9
                     70: #define CUDA_POWERDOWN                 0xa
                     71: #define CUDA_POWERUP_TIME              0xb
                     72: #define CUDA_SET_PRAM                  0xc
                     73: #define CUDA_MS_RESET                  0xd
                     74: #define CUDA_SEND_DFAC                 0xe
                     75: #define CUDA_BATTERY_SWAP_SENSE                0x10
                     76: #define CUDA_RESET_SYSTEM              0x11
                     77: #define CUDA_SET_IPL                   0x12
                     78: #define CUDA_FILE_SERVER_FLAG          0x13
                     79: #define CUDA_SET_AUTO_RATE             0x14
                     80: #define CUDA_GET_AUTO_RATE             0x16
                     81: #define CUDA_SET_DEVICE_LIST           0x19
                     82: #define CUDA_GET_DEVICE_LIST           0x1a
                     83: #define CUDA_SET_ONE_SECOND_MODE       0x1b
                     84: #define CUDA_SET_POWER_MESSAGES                0x21
                     85: #define CUDA_GET_SET_IIC               0x22
                     86: #define CUDA_WAKEUP                    0x23
                     87: #define CUDA_TIMER_TICKLE              0x24
                     88: #define CUDA_COMBINED_FORMAT_IIC       0x25
                     89: 
                     90: #define CUDA_TIMER_FREQ (4700000 / 6)
                     91: #define CUDA_ADB_POLL_FREQ 50
                     92: 
                     93: /* CUDA returns time_t's offset from Jan 1, 1904, not 1970 */
                     94: #define RTC_OFFSET                      2082844800
                     95: 
                     96: typedef struct CUDATimer {
                     97:     int index; 
                     98:     uint16_t latch;
                     99:     uint16_t counter_value; /* counter value at load time */
                    100:     int64_t load_time;
                    101:     int64_t next_irq_time;
                    102:     QEMUTimer *timer;
                    103: } CUDATimer;
                    104: 
                    105: typedef struct CUDAState {
                    106:     /* cuda registers */
                    107:     uint8_t b;      /* B-side data */
                    108:     uint8_t a;      /* A-side data */
                    109:     uint8_t dirb;   /* B-side direction (1=output) */
                    110:     uint8_t dira;   /* A-side direction (1=output) */
                    111:     uint8_t sr;     /* Shift register */
                    112:     uint8_t acr;    /* Auxiliary control register */
                    113:     uint8_t pcr;    /* Peripheral control register */
                    114:     uint8_t ifr;    /* Interrupt flag register */
                    115:     uint8_t ier;    /* Interrupt enable register */
                    116:     uint8_t anh;    /* A-side data, no handshake */
                    117: 
                    118:     CUDATimer timers[2];
                    119:     
                    120:     uint8_t last_b; /* last value of B register */
                    121:     uint8_t last_acr; /* last value of B register */
                    122:     
                    123:     int data_in_size;
                    124:     int data_in_index;
                    125:     int data_out_index;
                    126: 
                    127:     SetIRQFunc *set_irq;
                    128:     int irq;
                    129:     void *irq_opaque;
                    130:     uint8_t autopoll;
                    131:     uint8_t data_in[128];
                    132:     uint8_t data_out[16];
                    133:     QEMUTimer *adb_poll_timer;
                    134: } CUDAState;
                    135: 
                    136: static CUDAState cuda_state;
                    137: ADBBusState adb_bus;
                    138: 
                    139: static void cuda_update(CUDAState *s);
                    140: static void cuda_receive_packet_from_host(CUDAState *s, 
                    141:                                           const uint8_t *data, int len);
                    142: static void cuda_timer_update(CUDAState *s, CUDATimer *ti, 
                    143:                               int64_t current_time);
                    144: 
                    145: static void cuda_update_irq(CUDAState *s)
                    146: {
                    147:     if (s->ifr & s->ier & (SR_INT | T1_INT)) {
                    148:         s->set_irq(s->irq_opaque, s->irq, 1);
                    149:     } else {
                    150:         s->set_irq(s->irq_opaque, s->irq, 0);
                    151:     }
                    152: }
                    153: 
                    154: static unsigned int get_counter(CUDATimer *s)
                    155: {
                    156:     int64_t d;
                    157:     unsigned int counter;
                    158: 
                    159:     d = muldiv64(qemu_get_clock(vm_clock) - s->load_time, 
                    160:                  CUDA_TIMER_FREQ, ticks_per_sec);
                    161:     if (s->index == 0) {
                    162:         /* the timer goes down from latch to -1 (period of latch + 2) */
                    163:         if (d <= (s->counter_value + 1)) {
                    164:             counter = (s->counter_value - d) & 0xffff;
                    165:         } else {
                    166:             counter = (d - (s->counter_value + 1)) % (s->latch + 2);
                    167:             counter = (s->latch - counter) & 0xffff; 
                    168:         }
                    169:     } else {
                    170:         counter = (s->counter_value - d) & 0xffff;
                    171:     }
                    172:     return counter;
                    173: }
                    174: 
                    175: static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val)
                    176: {
                    177: #ifdef DEBUG_CUDA
                    178:     printf("cuda: T%d.counter=%d\n",
                    179:            1 + (ti->timer == NULL), val);
                    180: #endif
                    181:     ti->load_time = qemu_get_clock(vm_clock);
                    182:     ti->counter_value = val;
                    183:     cuda_timer_update(s, ti, ti->load_time);
                    184: }
                    185: 
                    186: static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time)
                    187: {
                    188:     int64_t d, next_time;
                    189:     unsigned int counter;
                    190: 
                    191:     /* current counter value */
                    192:     d = muldiv64(current_time - s->load_time, 
                    193:                  CUDA_TIMER_FREQ, ticks_per_sec);
                    194:     /* the timer goes down from latch to -1 (period of latch + 2) */
                    195:     if (d <= (s->counter_value + 1)) {
                    196:         counter = (s->counter_value - d) & 0xffff;
                    197:     } else {
                    198:         counter = (d - (s->counter_value + 1)) % (s->latch + 2);
                    199:         counter = (s->latch - counter) & 0xffff; 
                    200:     }
                    201:     
                    202:     /* Note: we consider the irq is raised on 0 */
                    203:     if (counter == 0xffff) {
                    204:         next_time = d + s->latch + 1;
                    205:     } else if (counter == 0) {
                    206:         next_time = d + s->latch + 2;
                    207:     } else {
                    208:         next_time = d + counter;
                    209:     }
                    210: #if 0
                    211: #ifdef DEBUG_CUDA
1.1.1.2 ! root      212:     printf("latch=%d counter=%" PRId64 " delta_next=%" PRId64 "\n", 
1.1       root      213:            s->latch, d, next_time - d);
                    214: #endif
                    215: #endif
                    216:     next_time = muldiv64(next_time, ticks_per_sec, CUDA_TIMER_FREQ) + 
                    217:         s->load_time;
                    218:     if (next_time <= current_time)
                    219:         next_time = current_time + 1;
                    220:     return next_time;
                    221: }
                    222: 
                    223: static void cuda_timer_update(CUDAState *s, CUDATimer *ti, 
                    224:                               int64_t current_time)
                    225: {
                    226:     if (!ti->timer)
                    227:         return;
                    228:     if ((s->acr & T1MODE) != T1MODE_CONT) {
                    229:         qemu_del_timer(ti->timer);
                    230:     } else {
                    231:         ti->next_irq_time = get_next_irq_time(ti, current_time);
                    232:         qemu_mod_timer(ti->timer, ti->next_irq_time);
                    233:     }
                    234: }
                    235: 
                    236: static void cuda_timer1(void *opaque)
                    237: {
                    238:     CUDAState *s = opaque;
                    239:     CUDATimer *ti = &s->timers[0];
                    240: 
                    241:     cuda_timer_update(s, ti, ti->next_irq_time);
                    242:     s->ifr |= T1_INT;
                    243:     cuda_update_irq(s);
                    244: }
                    245: 
                    246: static uint32_t cuda_readb(void *opaque, target_phys_addr_t addr)
                    247: {
                    248:     CUDAState *s = opaque;
                    249:     uint32_t val;
                    250: 
                    251:     addr = (addr >> 9) & 0xf;
                    252:     switch(addr) {
                    253:     case 0:
                    254:         val = s->b;
                    255:         break;
                    256:     case 1:
                    257:         val = s->a;
                    258:         break;
                    259:     case 2:
                    260:         val = s->dirb;
                    261:         break;
                    262:     case 3:
                    263:         val = s->dira;
                    264:         break;
                    265:     case 4:
                    266:         val = get_counter(&s->timers[0]) & 0xff;
                    267:         s->ifr &= ~T1_INT;
                    268:         cuda_update_irq(s);
                    269:         break;
                    270:     case 5:
                    271:         val = get_counter(&s->timers[0]) >> 8;
                    272:         cuda_update_irq(s);
                    273:         break;
                    274:     case 6:
                    275:         val = s->timers[0].latch & 0xff;
                    276:         break;
                    277:     case 7:
                    278:         /* XXX: check this */
                    279:         val = (s->timers[0].latch >> 8) & 0xff;
                    280:         break;
                    281:     case 8:
                    282:         val = get_counter(&s->timers[1]) & 0xff;
                    283:         s->ifr &= ~T2_INT;
                    284:         break;
                    285:     case 9:
                    286:         val = get_counter(&s->timers[1]) >> 8;
                    287:         break;
                    288:     case 10:
                    289:         val = s->sr;
                    290:         s->ifr &= ~SR_INT;
                    291:         cuda_update_irq(s);
                    292:         break;
                    293:     case 11:
                    294:         val = s->acr;
                    295:         break;
                    296:     case 12:
                    297:         val = s->pcr;
                    298:         break;
                    299:     case 13:
                    300:         val = s->ifr;
                    301:         if (s->ifr & s->ier) 
                    302:             val |= 0x80;
                    303:         break;
                    304:     case 14:
                    305:         val = s->ier | 0x80;
                    306:         break;
                    307:     default:
                    308:     case 15:
                    309:         val = s->anh;
                    310:         break;
                    311:     }
                    312: #ifdef DEBUG_CUDA
                    313:     if (addr != 13 || val != 0)
                    314:         printf("cuda: read: reg=0x%x val=%02x\n", addr, val);
                    315: #endif
                    316:     return val;
                    317: }
                    318: 
                    319: static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
                    320: {
                    321:     CUDAState *s = opaque;
                    322:     
                    323:     addr = (addr >> 9) & 0xf;
                    324: #ifdef DEBUG_CUDA
                    325:     printf("cuda: write: reg=0x%x val=%02x\n", addr, val);
                    326: #endif
                    327: 
                    328:     switch(addr) {
                    329:     case 0:
                    330:         s->b = val;
                    331:         cuda_update(s);
                    332:         break;
                    333:     case 1:
                    334:         s->a = val;
                    335:         break;
                    336:     case 2:
                    337:         s->dirb = val;
                    338:         break;
                    339:     case 3:
                    340:         s->dira = val;
                    341:         break;
                    342:     case 4:
                    343:         s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
                    344:         cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
                    345:         break;
                    346:     case 5:
                    347:         s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
                    348:         s->ifr &= ~T1_INT;
                    349:         set_counter(s, &s->timers[0], s->timers[0].latch);
                    350:         break;
                    351:     case 6:
                    352:         s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
                    353:         cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
                    354:         break;
                    355:     case 7:
                    356:         s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
                    357:         s->ifr &= ~T1_INT;
                    358:         cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
                    359:         break;
                    360:     case 8:
                    361:         s->timers[1].latch = val;
                    362:         set_counter(s, &s->timers[1], val);
                    363:         break;
                    364:     case 9:
                    365:         set_counter(s, &s->timers[1], (val << 8) | s->timers[1].latch);
                    366:         break;
                    367:     case 10:
                    368:         s->sr = val;
                    369:         break;
                    370:     case 11:
                    371:         s->acr = val;
                    372:         cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
                    373:         cuda_update(s);
                    374:         break;
                    375:     case 12:
                    376:         s->pcr = val;
                    377:         break;
                    378:     case 13:
                    379:         /* reset bits */
                    380:         s->ifr &= ~val;
                    381:         cuda_update_irq(s);
                    382:         break;
                    383:     case 14:
                    384:         if (val & IER_SET) {
                    385:             /* set bits */
                    386:             s->ier |= val & 0x7f;
                    387:         } else {
                    388:             /* reset bits */
                    389:             s->ier &= ~val;
                    390:         }
                    391:         cuda_update_irq(s);
                    392:         break;
                    393:     default:
                    394:     case 15:
                    395:         s->anh = val;
                    396:         break;
                    397:     }
                    398: }
                    399: 
                    400: /* NOTE: TIP and TREQ are negated */
                    401: static void cuda_update(CUDAState *s)
                    402: {
                    403:     int packet_received, len;
                    404: 
                    405:     packet_received = 0;
                    406:     if (!(s->b & TIP)) {
                    407:         /* transfer requested from host */
                    408: 
                    409:         if (s->acr & SR_OUT) {
                    410:             /* data output */
                    411:             if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
                    412:                 if (s->data_out_index < sizeof(s->data_out)) {
                    413: #ifdef DEBUG_CUDA
                    414:                     printf("cuda: send: %02x\n", s->sr);
                    415: #endif
                    416:                     s->data_out[s->data_out_index++] = s->sr;
                    417:                     s->ifr |= SR_INT;
                    418:                     cuda_update_irq(s);
                    419:                 }
                    420:             }
                    421:         } else {
                    422:             if (s->data_in_index < s->data_in_size) {
                    423:                 /* data input */
                    424:                 if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
                    425:                     s->sr = s->data_in[s->data_in_index++];
                    426: #ifdef DEBUG_CUDA
                    427:                     printf("cuda: recv: %02x\n", s->sr);
                    428: #endif
                    429:                     /* indicate end of transfer */
                    430:                     if (s->data_in_index >= s->data_in_size) {
                    431:                         s->b = (s->b | TREQ);
                    432:                     }
                    433:                     s->ifr |= SR_INT;
                    434:                     cuda_update_irq(s);
                    435:                 }
                    436:             }
                    437:         }
                    438:     } else {
                    439:         /* no transfer requested: handle sync case */
                    440:         if ((s->last_b & TIP) && (s->b & TACK) != (s->last_b & TACK)) {
                    441:             /* update TREQ state each time TACK change state */
                    442:             if (s->b & TACK)
                    443:                 s->b = (s->b | TREQ);
                    444:             else
                    445:                 s->b = (s->b & ~TREQ);
                    446:             s->ifr |= SR_INT;
                    447:             cuda_update_irq(s);
                    448:         } else {
                    449:             if (!(s->last_b & TIP)) {
                    450:                 /* handle end of host to cuda transfert */
                    451:                 packet_received = (s->data_out_index > 0);
                    452:                 /* always an IRQ at the end of transfert */
                    453:                 s->ifr |= SR_INT;
                    454:                 cuda_update_irq(s);
                    455:             }
                    456:             /* signal if there is data to read */
                    457:             if (s->data_in_index < s->data_in_size) {
                    458:                 s->b = (s->b & ~TREQ);
                    459:             }
                    460:         }
                    461:     }
                    462: 
                    463:     s->last_acr = s->acr;
                    464:     s->last_b = s->b;
                    465: 
                    466:     /* NOTE: cuda_receive_packet_from_host() can call cuda_update()
                    467:        recursively */
                    468:     if (packet_received) {
                    469:         len = s->data_out_index;
                    470:         s->data_out_index = 0;
                    471:         cuda_receive_packet_from_host(s, s->data_out, len);
                    472:     }
                    473: }
                    474: 
                    475: static void cuda_send_packet_to_host(CUDAState *s, 
                    476:                                      const uint8_t *data, int len)
                    477: {
                    478: #ifdef DEBUG_CUDA_PACKET
                    479:     {
                    480:         int i;
                    481:         printf("cuda_send_packet_to_host:\n");
                    482:         for(i = 0; i < len; i++)
                    483:             printf(" %02x", data[i]);
                    484:         printf("\n");
                    485:     }
                    486: #endif
                    487:     memcpy(s->data_in, data, len);
                    488:     s->data_in_size = len;
                    489:     s->data_in_index = 0;
                    490:     cuda_update(s);
                    491:     s->ifr |= SR_INT;
                    492:     cuda_update_irq(s);
                    493: }
                    494: 
                    495: static void cuda_adb_poll(void *opaque)
                    496: {
                    497:     CUDAState *s = opaque;
                    498:     uint8_t obuf[ADB_MAX_OUT_LEN + 2];
                    499:     int olen;
                    500: 
                    501:     olen = adb_poll(&adb_bus, obuf + 2);
                    502:     if (olen > 0) {
                    503:         obuf[0] = ADB_PACKET;
                    504:         obuf[1] = 0x40; /* polled data */
                    505:         cuda_send_packet_to_host(s, obuf, olen + 2);
                    506:     }
                    507:     qemu_mod_timer(s->adb_poll_timer, 
                    508:                    qemu_get_clock(vm_clock) + 
                    509:                    (ticks_per_sec / CUDA_ADB_POLL_FREQ));
                    510: }
                    511: 
                    512: static void cuda_receive_packet(CUDAState *s, 
                    513:                                 const uint8_t *data, int len)
                    514: {
                    515:     uint8_t obuf[16];
                    516:     int ti, autopoll;
                    517: 
                    518:     switch(data[0]) {
                    519:     case CUDA_AUTOPOLL:
                    520:         autopoll = (data[1] != 0);
                    521:         if (autopoll != s->autopoll) {
                    522:             s->autopoll = autopoll;
                    523:             if (autopoll) {
                    524:                 qemu_mod_timer(s->adb_poll_timer, 
                    525:                                qemu_get_clock(vm_clock) + 
                    526:                                (ticks_per_sec / CUDA_ADB_POLL_FREQ));
                    527:             } else {
                    528:                 qemu_del_timer(s->adb_poll_timer);
                    529:             }
                    530:         }
                    531:         obuf[0] = CUDA_PACKET;
                    532:         obuf[1] = data[1];
                    533:         cuda_send_packet_to_host(s, obuf, 2);
                    534:         break;
                    535:     case CUDA_GET_TIME:
                    536:     case CUDA_SET_TIME:
                    537:         /* XXX: add time support ? */
                    538:         ti = time(NULL) + RTC_OFFSET;
                    539:         obuf[0] = CUDA_PACKET;
                    540:         obuf[1] = 0;
                    541:         obuf[2] = 0;
                    542:         obuf[3] = ti >> 24;
                    543:         obuf[4] = ti >> 16;
                    544:         obuf[5] = ti >> 8;
                    545:         obuf[6] = ti;
                    546:         cuda_send_packet_to_host(s, obuf, 7);
                    547:         break;
                    548:     case CUDA_FILE_SERVER_FLAG:
                    549:     case CUDA_SET_DEVICE_LIST:
                    550:     case CUDA_SET_AUTO_RATE:
                    551:     case CUDA_SET_POWER_MESSAGES:
                    552:         obuf[0] = CUDA_PACKET;
                    553:         obuf[1] = 0;
                    554:         cuda_send_packet_to_host(s, obuf, 2);
                    555:         break;
                    556:     case CUDA_POWERDOWN:
                    557:         obuf[0] = CUDA_PACKET;
                    558:         obuf[1] = 0;
                    559:         cuda_send_packet_to_host(s, obuf, 2);
                    560:        qemu_system_shutdown_request();
                    561:        break;
                    562:     default:
                    563:         break;
                    564:     }
                    565: }
                    566: 
                    567: static void cuda_receive_packet_from_host(CUDAState *s, 
                    568:                                           const uint8_t *data, int len)
                    569: {
                    570: #ifdef DEBUG_CUDA_PACKET
                    571:     {
                    572:         int i;
                    573:         printf("cuda_receive_packet_from_host:\n");
                    574:         for(i = 0; i < len; i++)
                    575:             printf(" %02x", data[i]);
                    576:         printf("\n");
                    577:     }
                    578: #endif
                    579:     switch(data[0]) {
                    580:     case ADB_PACKET:
                    581:         {
                    582:             uint8_t obuf[ADB_MAX_OUT_LEN + 2];
                    583:             int olen;
                    584:             olen = adb_request(&adb_bus, obuf + 2, data + 1, len - 1);
                    585:             if (olen > 0) {
                    586:                 obuf[0] = ADB_PACKET;
                    587:                 obuf[1] = 0x00;
                    588:             } else {
                    589:                 /* error */
                    590:                 obuf[0] = ADB_PACKET;
                    591:                 obuf[1] = -olen;
                    592:                 olen = 0;
                    593:             }
                    594:             cuda_send_packet_to_host(s, obuf, olen + 2);
                    595:         }
                    596:         break;
                    597:     case CUDA_PACKET:
                    598:         cuda_receive_packet(s, data + 1, len - 1);
                    599:         break;
                    600:     }
                    601: }
                    602: 
                    603: static void cuda_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
                    604: {
                    605: }
                    606: 
                    607: static void cuda_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
                    608: {
                    609: }
                    610: 
                    611: static uint32_t cuda_readw (void *opaque, target_phys_addr_t addr)
                    612: {
                    613:     return 0;
                    614: }
                    615: 
                    616: static uint32_t cuda_readl (void *opaque, target_phys_addr_t addr)
                    617: {
                    618:     return 0;
                    619: }
                    620: 
                    621: static CPUWriteMemoryFunc *cuda_write[] = {
                    622:     &cuda_writeb,
                    623:     &cuda_writew,
                    624:     &cuda_writel,
                    625: };
                    626: 
                    627: static CPUReadMemoryFunc *cuda_read[] = {
                    628:     &cuda_readb,
                    629:     &cuda_readw,
                    630:     &cuda_readl,
                    631: };
                    632: 
                    633: int cuda_init(SetIRQFunc *set_irq, void *irq_opaque, int irq)
                    634: {
                    635:     CUDAState *s = &cuda_state;
                    636:     int cuda_mem_index;
                    637: 
                    638:     s->set_irq = set_irq;
                    639:     s->irq_opaque = irq_opaque;
                    640:     s->irq = irq;
                    641: 
                    642:     s->timers[0].index = 0;
                    643:     s->timers[0].timer = qemu_new_timer(vm_clock, cuda_timer1, s);
                    644:     s->timers[0].latch = 0xffff;
                    645:     set_counter(s, &s->timers[0], 0xffff);
                    646: 
                    647:     s->timers[1].index = 1;
                    648:     s->timers[1].latch = 0;
                    649:     //    s->ier = T1_INT | SR_INT;
                    650:     s->ier = 0;
                    651:     set_counter(s, &s->timers[1], 0xffff);
                    652: 
                    653:     s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s);
                    654:     cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s);
                    655:     return cuda_mem_index;
                    656: }

unix.superglobalmegacorp.com

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