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

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
        !           212:     printf("latch=%d counter=%lld delta_next=%lld\n", 
        !           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.