📄 cuda.c
字号:
s->b = val; cuda_update(s); break; case 1: s->a = val; break; case 2: s->dirb = val; break; case 3: s->dira = val; break; case 4: s->timers[0].latch = (s->timers[0].latch & 0xff00) | val; cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock)); break; case 5: s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8); s->ifr &= ~T1_INT; set_counter(s, &s->timers[0], s->timers[0].latch); break; case 6: s->timers[0].latch = (s->timers[0].latch & 0xff00) | val; cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock)); break; case 7: s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8); s->ifr &= ~T1_INT; cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock)); break; case 8: s->timers[1].latch = val; set_counter(s, &s->timers[1], val); break; case 9: set_counter(s, &s->timers[1], (val << 8) | s->timers[1].latch); break; case 10: s->sr = val; break; case 11: s->acr = val; cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock)); cuda_update(s); break; case 12: s->pcr = val; break; case 13: /* reset bits */ s->ifr &= ~val; cuda_update_irq(s); break; case 14: if (val & IER_SET) { /* set bits */ s->ier |= val & 0x7f; } else { /* reset bits */ s->ier &= ~val; } cuda_update_irq(s); break; default: case 15: s->anh = val; break; }}/* NOTE: TIP and TREQ are negated */static void cuda_update(CUDAState *s){ int packet_received, len; packet_received = 0; if (!(s->b & TIP)) { /* transfer requested from host */ if (s->acr & SR_OUT) { /* data output */ if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) { if (s->data_out_index < sizeof(s->data_out)) {#ifdef DEBUG_CUDA printf("cuda: send: %02x\n", s->sr);#endif s->data_out[s->data_out_index++] = s->sr; s->ifr |= SR_INT; cuda_update_irq(s); } } } else { if (s->data_in_index < s->data_in_size) { /* data input */ if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) { s->sr = s->data_in[s->data_in_index++];#ifdef DEBUG_CUDA printf("cuda: recv: %02x\n", s->sr);#endif /* indicate end of transfer */ if (s->data_in_index >= s->data_in_size) { s->b = (s->b | TREQ); } s->ifr |= SR_INT; cuda_update_irq(s); } } } } else { /* no transfer requested: handle sync case */ if ((s->last_b & TIP) && (s->b & TACK) != (s->last_b & TACK)) { /* update TREQ state each time TACK change state */ if (s->b & TACK) s->b = (s->b | TREQ); else s->b = (s->b & ~TREQ); s->ifr |= SR_INT; cuda_update_irq(s); } else { if (!(s->last_b & TIP)) { /* handle end of host to cuda transfert */ packet_received = (s->data_out_index > 0); /* always an IRQ at the end of transfert */ s->ifr |= SR_INT; cuda_update_irq(s); } /* signal if there is data to read */ if (s->data_in_index < s->data_in_size) { s->b = (s->b & ~TREQ); } } } s->last_acr = s->acr; s->last_b = s->b; /* NOTE: cuda_receive_packet_from_host() can call cuda_update() recursively */ if (packet_received) { len = s->data_out_index; s->data_out_index = 0; cuda_receive_packet_from_host(s, s->data_out, len); }}static void cuda_send_packet_to_host(CUDAState *s, const uint8_t *data, int len){#ifdef DEBUG_CUDA_PACKET { int i; printf("cuda_send_packet_to_host:\n"); for(i = 0; i < len; i++) printf(" %02x", data[i]); printf("\n"); }#endif memcpy(s->data_in, data, len); s->data_in_size = len; s->data_in_index = 0; cuda_update(s); s->ifr |= SR_INT; cuda_update_irq(s);}static void cuda_adb_poll(void *opaque){ CUDAState *s = opaque; uint8_t obuf[ADB_MAX_OUT_LEN + 2]; int olen; olen = adb_poll(&adb_bus, obuf + 2); if (olen > 0) { obuf[0] = ADB_PACKET; obuf[1] = 0x40; /* polled data */ cuda_send_packet_to_host(s, obuf, olen + 2); } qemu_mod_timer(s->adb_poll_timer, qemu_get_clock(vm_clock) + (ticks_per_sec / CUDA_ADB_POLL_FREQ));}static void cuda_receive_packet(CUDAState *s, const uint8_t *data, int len){ uint8_t obuf[16]; int ti, autopoll; switch(data[0]) { case CUDA_AUTOPOLL: autopoll = (data[1] != 0); if (autopoll != s->autopoll) { s->autopoll = autopoll; if (autopoll) { qemu_mod_timer(s->adb_poll_timer, qemu_get_clock(vm_clock) + (ticks_per_sec / CUDA_ADB_POLL_FREQ)); } else { qemu_del_timer(s->adb_poll_timer); } } obuf[0] = CUDA_PACKET; obuf[1] = data[1]; cuda_send_packet_to_host(s, obuf, 2); break; case CUDA_GET_TIME: case CUDA_SET_TIME: /* XXX: add time support ? */ ti = time(NULL) + RTC_OFFSET; obuf[0] = CUDA_PACKET; obuf[1] = 0; obuf[2] = 0; obuf[3] = ti >> 24; obuf[4] = ti >> 16; obuf[5] = ti >> 8; obuf[6] = ti; cuda_send_packet_to_host(s, obuf, 7); break; case CUDA_FILE_SERVER_FLAG: case CUDA_SET_DEVICE_LIST: case CUDA_SET_AUTO_RATE: case CUDA_SET_POWER_MESSAGES: obuf[0] = CUDA_PACKET; obuf[1] = 0; cuda_send_packet_to_host(s, obuf, 2); break; case CUDA_POWERDOWN: obuf[0] = CUDA_PACKET; obuf[1] = 0; cuda_send_packet_to_host(s, obuf, 2); qemu_system_shutdown_request(); break; default: break; }}static void cuda_receive_packet_from_host(CUDAState *s, const uint8_t *data, int len){#ifdef DEBUG_CUDA_PACKET { int i; printf("cuda_receive_packet_from_host:\n"); for(i = 0; i < len; i++) printf(" %02x", data[i]); printf("\n"); }#endif switch(data[0]) { case ADB_PACKET: { uint8_t obuf[ADB_MAX_OUT_LEN + 2]; int olen; olen = adb_request(&adb_bus, obuf + 2, data + 1, len - 1); if (olen > 0) { obuf[0] = ADB_PACKET; obuf[1] = 0x00; } else { /* error */ obuf[0] = ADB_PACKET; obuf[1] = -olen; olen = 0; } cuda_send_packet_to_host(s, obuf, olen + 2); } break; case CUDA_PACKET: cuda_receive_packet(s, data + 1, len - 1); break; }}static void cuda_writew (void *opaque, target_phys_addr_t addr, uint32_t value){}static void cuda_writel (void *opaque, target_phys_addr_t addr, uint32_t value){}static uint32_t cuda_readw (void *opaque, target_phys_addr_t addr){ return 0;}static uint32_t cuda_readl (void *opaque, target_phys_addr_t addr){ return 0;}static CPUWriteMemoryFunc *cuda_write[] = { &cuda_writeb, &cuda_writew, &cuda_writel,};static CPUReadMemoryFunc *cuda_read[] = { &cuda_readb, &cuda_readw, &cuda_readl,};int cuda_init(SetIRQFunc *set_irq, void *irq_opaque, int irq){ CUDAState *s = &cuda_state; int cuda_mem_index; s->set_irq = set_irq; s->irq_opaque = irq_opaque; s->irq = irq; s->timers[0].index = 0; s->timers[0].timer = qemu_new_timer(vm_clock, cuda_timer1, s); s->timers[0].latch = 0xffff; set_counter(s, &s->timers[0], 0xffff); s->timers[1].index = 1; s->timers[1].latch = 0; // s->ier = T1_INT | SR_INT; s->ier = 0; set_counter(s, &s->timers[1], 0xffff); s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s); cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s); return cuda_mem_index;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -