xref: /qemu/hw/misc/macio/cuda.c (revision d271ae36dc1e292ae140f5bbf23e0fc1392dd325)
1 /*
2  * QEMU PowerMac CUDA device support
3  *
4  * Copyright (c) 2004-2007 Fabrice Bellard
5  * Copyright (c) 2007 Jocelyn Mayer
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 #include "hw/hw.h"
26 #include "hw/ppc/mac.h"
27 #include "hw/input/adb.h"
28 #include "qemu/timer.h"
29 #include "sysemu/sysemu.h"
30 
31 /* XXX: implement all timer modes */
32 
33 /* debug CUDA */
34 //#define DEBUG_CUDA
35 
36 /* debug CUDA packets */
37 //#define DEBUG_CUDA_PACKET
38 
39 #ifdef DEBUG_CUDA
40 #define CUDA_DPRINTF(fmt, ...)                                  \
41     do { printf("CUDA: " fmt , ## __VA_ARGS__); } while (0)
42 #else
43 #define CUDA_DPRINTF(fmt, ...)
44 #endif
45 
46 /* Bits in B data register: all active low */
47 #define TREQ		0x08		/* Transfer request (input) */
48 #define TACK		0x10		/* Transfer acknowledge (output) */
49 #define TIP		0x20		/* Transfer in progress (output) */
50 
51 /* Bits in ACR */
52 #define SR_CTRL		0x1c		/* Shift register control bits */
53 #define SR_EXT		0x0c		/* Shift on external clock */
54 #define SR_OUT		0x10		/* Shift out if 1 */
55 
56 /* Bits in IFR and IER */
57 #define IER_SET		0x80		/* set bits in IER */
58 #define IER_CLR		0		/* clear bits in IER */
59 #define SR_INT		0x04		/* Shift register full/empty */
60 #define SR_DATA_INT	0x08
61 #define SR_CLOCK_INT	0x10
62 #define T1_INT          0x40            /* Timer 1 interrupt */
63 #define T2_INT          0x20            /* Timer 2 interrupt */
64 
65 /* Bits in ACR */
66 #define T1MODE          0xc0            /* Timer 1 mode */
67 #define T1MODE_CONT     0x40            /*  continuous interrupts */
68 
69 /* commands (1st byte) */
70 #define ADB_PACKET	0
71 #define CUDA_PACKET	1
72 #define ERROR_PACKET	2
73 #define TIMER_PACKET	3
74 #define POWER_PACKET	4
75 #define MACIIC_PACKET	5
76 #define PMU_PACKET	6
77 
78 
79 /* CUDA commands (2nd byte) */
80 #define CUDA_WARM_START			0x0
81 #define CUDA_AUTOPOLL			0x1
82 #define CUDA_GET_6805_ADDR		0x2
83 #define CUDA_GET_TIME			0x3
84 #define CUDA_GET_PRAM			0x7
85 #define CUDA_SET_6805_ADDR		0x8
86 #define CUDA_SET_TIME			0x9
87 #define CUDA_POWERDOWN			0xa
88 #define CUDA_POWERUP_TIME		0xb
89 #define CUDA_SET_PRAM			0xc
90 #define CUDA_MS_RESET			0xd
91 #define CUDA_SEND_DFAC			0xe
92 #define CUDA_BATTERY_SWAP_SENSE		0x10
93 #define CUDA_RESET_SYSTEM		0x11
94 #define CUDA_SET_IPL			0x12
95 #define CUDA_FILE_SERVER_FLAG		0x13
96 #define CUDA_SET_AUTO_RATE		0x14
97 #define CUDA_GET_AUTO_RATE		0x16
98 #define CUDA_SET_DEVICE_LIST		0x19
99 #define CUDA_GET_DEVICE_LIST		0x1a
100 #define CUDA_SET_ONE_SECOND_MODE	0x1b
101 #define CUDA_SET_POWER_MESSAGES		0x21
102 #define CUDA_GET_SET_IIC		0x22
103 #define CUDA_WAKEUP			0x23
104 #define CUDA_TIMER_TICKLE		0x24
105 #define CUDA_COMBINED_FORMAT_IIC	0x25
106 
107 #define CUDA_TIMER_FREQ (4700000 / 6)
108 #define CUDA_ADB_POLL_FREQ 50
109 
110 /* CUDA returns time_t's offset from Jan 1, 1904, not 1970 */
111 #define RTC_OFFSET                      2082844800
112 
113 static void cuda_update(CUDAState *s);
114 static void cuda_receive_packet_from_host(CUDAState *s,
115                                           const uint8_t *data, int len);
116 static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
117                               int64_t current_time);
118 
119 static void cuda_update_irq(CUDAState *s)
120 {
121     if (s->ifr & s->ier & (SR_INT | T1_INT)) {
122         qemu_irq_raise(s->irq);
123     } else {
124         qemu_irq_lower(s->irq);
125     }
126 }
127 
128 static uint64_t get_tb(uint64_t freq)
129 {
130     return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
131                     freq, get_ticks_per_sec());
132 }
133 
134 static unsigned int get_counter(CUDATimer *s)
135 {
136     int64_t d;
137     unsigned int counter;
138     uint64_t tb_diff;
139 
140     /* Reverse of the tb calculation algorithm that Mac OS X uses on bootup. */
141     tb_diff = get_tb(s->frequency) - s->load_time;
142     d = (tb_diff * 0xBF401675E5DULL) / (s->frequency << 24);
143 
144     if (s->index == 0) {
145         /* the timer goes down from latch to -1 (period of latch + 2) */
146         if (d <= (s->counter_value + 1)) {
147             counter = (s->counter_value - d) & 0xffff;
148         } else {
149             counter = (d - (s->counter_value + 1)) % (s->latch + 2);
150             counter = (s->latch - counter) & 0xffff;
151         }
152     } else {
153         counter = (s->counter_value - d) & 0xffff;
154     }
155     return counter;
156 }
157 
158 static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val)
159 {
160     CUDA_DPRINTF("T%d.counter=%d\n", 1 + (ti->timer == NULL), val);
161     ti->load_time = get_tb(s->frequency);
162     ti->counter_value = val;
163     cuda_timer_update(s, ti, ti->load_time);
164 }
165 
166 static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time)
167 {
168     int64_t d, next_time;
169     unsigned int counter;
170 
171     /* current counter value */
172     d = muldiv64(current_time - s->load_time,
173                  CUDA_TIMER_FREQ, get_ticks_per_sec());
174     /* the timer goes down from latch to -1 (period of latch + 2) */
175     if (d <= (s->counter_value + 1)) {
176         counter = (s->counter_value - d) & 0xffff;
177     } else {
178         counter = (d - (s->counter_value + 1)) % (s->latch + 2);
179         counter = (s->latch - counter) & 0xffff;
180     }
181 
182     /* Note: we consider the irq is raised on 0 */
183     if (counter == 0xffff) {
184         next_time = d + s->latch + 1;
185     } else if (counter == 0) {
186         next_time = d + s->latch + 2;
187     } else {
188         next_time = d + counter;
189     }
190     CUDA_DPRINTF("latch=%d counter=%" PRId64 " delta_next=%" PRId64 "\n",
191                  s->latch, d, next_time - d);
192     next_time = muldiv64(next_time, get_ticks_per_sec(), CUDA_TIMER_FREQ) +
193         s->load_time;
194     if (next_time <= current_time)
195         next_time = current_time + 1;
196     return next_time;
197 }
198 
199 static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
200                               int64_t current_time)
201 {
202     if (!ti->timer)
203         return;
204     if ((s->acr & T1MODE) != T1MODE_CONT) {
205         timer_del(ti->timer);
206     } else {
207         ti->next_irq_time = get_next_irq_time(ti, current_time);
208         timer_mod(ti->timer, ti->next_irq_time);
209     }
210 }
211 
212 static void cuda_timer1(void *opaque)
213 {
214     CUDAState *s = opaque;
215     CUDATimer *ti = &s->timers[0];
216 
217     cuda_timer_update(s, ti, ti->next_irq_time);
218     s->ifr |= T1_INT;
219     cuda_update_irq(s);
220 }
221 
222 static uint32_t cuda_readb(void *opaque, hwaddr addr)
223 {
224     CUDAState *s = opaque;
225     uint32_t val;
226 
227     addr = (addr >> 9) & 0xf;
228     switch(addr) {
229     case 0:
230         val = s->b;
231         break;
232     case 1:
233         val = s->a;
234         break;
235     case 2:
236         val = s->dirb;
237         break;
238     case 3:
239         val = s->dira;
240         break;
241     case 4:
242         val = get_counter(&s->timers[0]) & 0xff;
243         s->ifr &= ~T1_INT;
244         cuda_update_irq(s);
245         break;
246     case 5:
247         val = get_counter(&s->timers[0]) >> 8;
248         cuda_update_irq(s);
249         break;
250     case 6:
251         val = s->timers[0].latch & 0xff;
252         break;
253     case 7:
254         /* XXX: check this */
255         val = (s->timers[0].latch >> 8) & 0xff;
256         break;
257     case 8:
258         val = get_counter(&s->timers[1]) & 0xff;
259         s->ifr &= ~T2_INT;
260         break;
261     case 9:
262         val = get_counter(&s->timers[1]) >> 8;
263         break;
264     case 10:
265         val = s->sr;
266         s->ifr &= ~(SR_INT | SR_CLOCK_INT | SR_DATA_INT);
267         cuda_update_irq(s);
268         break;
269     case 11:
270         val = s->acr;
271         break;
272     case 12:
273         val = s->pcr;
274         break;
275     case 13:
276         val = s->ifr;
277         if (s->ifr & s->ier)
278             val |= 0x80;
279         break;
280     case 14:
281         val = s->ier | 0x80;
282         break;
283     default:
284     case 15:
285         val = s->anh;
286         break;
287     }
288     if (addr != 13 || val != 0) {
289         CUDA_DPRINTF("read: reg=0x%x val=%02x\n", (int)addr, val);
290     }
291 
292     return val;
293 }
294 
295 static void cuda_writeb(void *opaque, hwaddr addr, uint32_t val)
296 {
297     CUDAState *s = opaque;
298 
299     addr = (addr >> 9) & 0xf;
300     CUDA_DPRINTF("write: reg=0x%x val=%02x\n", (int)addr, val);
301 
302     switch(addr) {
303     case 0:
304         s->b = val;
305         cuda_update(s);
306         break;
307     case 1:
308         s->a = val;
309         break;
310     case 2:
311         s->dirb = val;
312         break;
313     case 3:
314         s->dira = val;
315         break;
316     case 4:
317         s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
318         cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
319         break;
320     case 5:
321         s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
322         s->ifr &= ~T1_INT;
323         set_counter(s, &s->timers[0], s->timers[0].latch);
324         break;
325     case 6:
326         s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
327         cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
328         break;
329     case 7:
330         s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
331         s->ifr &= ~T1_INT;
332         cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
333         break;
334     case 8:
335         s->timers[1].latch = val;
336         set_counter(s, &s->timers[1], val);
337         break;
338     case 9:
339         set_counter(s, &s->timers[1], (val << 8) | s->timers[1].latch);
340         break;
341     case 10:
342         s->sr = val;
343         break;
344     case 11:
345         s->acr = val;
346         cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
347         cuda_update(s);
348         break;
349     case 12:
350         s->pcr = val;
351         break;
352     case 13:
353         /* reset bits */
354         s->ifr &= ~val;
355         cuda_update_irq(s);
356         break;
357     case 14:
358         if (val & IER_SET) {
359             /* set bits */
360             s->ier |= val & 0x7f;
361         } else {
362             /* reset bits */
363             s->ier &= ~val;
364         }
365         cuda_update_irq(s);
366         break;
367     default:
368     case 15:
369         s->anh = val;
370         break;
371     }
372 }
373 
374 /* NOTE: TIP and TREQ are negated */
375 static void cuda_update(CUDAState *s)
376 {
377     int packet_received, len;
378 
379     packet_received = 0;
380     if (!(s->b & TIP)) {
381         /* transfer requested from host */
382 
383         if (s->acr & SR_OUT) {
384             /* data output */
385             if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
386                 if (s->data_out_index < sizeof(s->data_out)) {
387                     CUDA_DPRINTF("send: %02x\n", s->sr);
388                     s->data_out[s->data_out_index++] = s->sr;
389                     s->ifr |= SR_INT;
390                     cuda_update_irq(s);
391                 }
392             }
393         } else {
394             if (s->data_in_index < s->data_in_size) {
395                 /* data input */
396                 if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
397                     s->sr = s->data_in[s->data_in_index++];
398                     CUDA_DPRINTF("recv: %02x\n", s->sr);
399                     /* indicate end of transfer */
400                     if (s->data_in_index >= s->data_in_size) {
401                         s->b = (s->b | TREQ);
402                     }
403                     s->ifr |= SR_INT;
404                     cuda_update_irq(s);
405                 }
406             }
407         }
408     } else {
409         /* no transfer requested: handle sync case */
410         if ((s->last_b & TIP) && (s->b & TACK) != (s->last_b & TACK)) {
411             /* update TREQ state each time TACK change state */
412             if (s->b & TACK)
413                 s->b = (s->b | TREQ);
414             else
415                 s->b = (s->b & ~TREQ);
416             s->ifr |= SR_INT;
417             cuda_update_irq(s);
418         } else {
419             if (!(s->last_b & TIP)) {
420                 /* handle end of host to cuda transfer */
421                 packet_received = (s->data_out_index > 0);
422                 /* always an IRQ at the end of transfer */
423                 s->ifr |= SR_INT;
424                 cuda_update_irq(s);
425             }
426             /* signal if there is data to read */
427             if (s->data_in_index < s->data_in_size) {
428                 s->b = (s->b & ~TREQ);
429             }
430         }
431     }
432 
433     s->last_acr = s->acr;
434     s->last_b = s->b;
435 
436     /* NOTE: cuda_receive_packet_from_host() can call cuda_update()
437        recursively */
438     if (packet_received) {
439         len = s->data_out_index;
440         s->data_out_index = 0;
441         cuda_receive_packet_from_host(s, s->data_out, len);
442     }
443 }
444 
445 static void cuda_send_packet_to_host(CUDAState *s,
446                                      const uint8_t *data, int len)
447 {
448 #ifdef DEBUG_CUDA_PACKET
449     {
450         int i;
451         printf("cuda_send_packet_to_host:\n");
452         for(i = 0; i < len; i++)
453             printf(" %02x", data[i]);
454         printf("\n");
455     }
456 #endif
457     memcpy(s->data_in, data, len);
458     s->data_in_size = len;
459     s->data_in_index = 0;
460     cuda_update(s);
461     s->ifr |= SR_INT;
462     cuda_update_irq(s);
463 }
464 
465 static void cuda_adb_poll(void *opaque)
466 {
467     CUDAState *s = opaque;
468     uint8_t obuf[ADB_MAX_OUT_LEN + 2];
469     int olen;
470 
471     olen = adb_poll(&s->adb_bus, obuf + 2);
472     if (olen > 0) {
473         obuf[0] = ADB_PACKET;
474         obuf[1] = 0x40; /* polled data */
475         cuda_send_packet_to_host(s, obuf, olen + 2);
476     }
477     timer_mod(s->adb_poll_timer,
478                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
479                    (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ));
480 }
481 
482 static void cuda_receive_packet(CUDAState *s,
483                                 const uint8_t *data, int len)
484 {
485     uint8_t obuf[16] = { CUDA_PACKET, 0, data[0] };
486     int autopoll;
487     uint32_t ti;
488 
489     switch(data[0]) {
490     case CUDA_AUTOPOLL:
491         autopoll = (data[1] != 0);
492         if (autopoll != s->autopoll) {
493             s->autopoll = autopoll;
494             if (autopoll) {
495                 timer_mod(s->adb_poll_timer,
496                                qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
497                                (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ));
498             } else {
499                 timer_del(s->adb_poll_timer);
500             }
501         }
502         cuda_send_packet_to_host(s, obuf, 3);
503         break;
504     case CUDA_GET_6805_ADDR:
505         cuda_send_packet_to_host(s, obuf, 3);
506         break;
507     case CUDA_SET_TIME:
508         ti = (((uint32_t)data[1]) << 24) + (((uint32_t)data[2]) << 16) + (((uint32_t)data[3]) << 8) + data[4];
509         s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec());
510         cuda_send_packet_to_host(s, obuf, 3);
511         break;
512     case CUDA_GET_TIME:
513         ti = s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec());
514         obuf[3] = ti >> 24;
515         obuf[4] = ti >> 16;
516         obuf[5] = ti >> 8;
517         obuf[6] = ti;
518         cuda_send_packet_to_host(s, obuf, 7);
519         break;
520     case CUDA_FILE_SERVER_FLAG:
521     case CUDA_SET_DEVICE_LIST:
522     case CUDA_SET_AUTO_RATE:
523     case CUDA_SET_POWER_MESSAGES:
524         cuda_send_packet_to_host(s, obuf, 3);
525         break;
526     case CUDA_POWERDOWN:
527         cuda_send_packet_to_host(s, obuf, 3);
528         qemu_system_shutdown_request();
529         break;
530     case CUDA_RESET_SYSTEM:
531         cuda_send_packet_to_host(s, obuf, 3);
532         qemu_system_reset_request();
533         break;
534     case CUDA_COMBINED_FORMAT_IIC:
535         obuf[0] = ERROR_PACKET;
536         obuf[1] = 0x5;
537         obuf[2] = CUDA_PACKET;
538         obuf[3] = data[0];
539         cuda_send_packet_to_host(s, obuf, 4);
540         break;
541     case CUDA_GET_SET_IIC:
542         if (len == 4) {
543             cuda_send_packet_to_host(s, obuf, 3);
544         } else {
545             obuf[0] = ERROR_PACKET;
546             obuf[1] = 0x2;
547             obuf[2] = CUDA_PACKET;
548             obuf[3] = data[0];
549             cuda_send_packet_to_host(s, obuf, 4);
550         }
551         break;
552     default:
553         break;
554     }
555 }
556 
557 static void cuda_receive_packet_from_host(CUDAState *s,
558                                           const uint8_t *data, int len)
559 {
560 #ifdef DEBUG_CUDA_PACKET
561     {
562         int i;
563         printf("cuda_receive_packet_from_host:\n");
564         for(i = 0; i < len; i++)
565             printf(" %02x", data[i]);
566         printf("\n");
567     }
568 #endif
569     switch(data[0]) {
570     case ADB_PACKET:
571         {
572             uint8_t obuf[ADB_MAX_OUT_LEN + 3];
573             int olen;
574             olen = adb_request(&s->adb_bus, obuf + 2, data + 1, len - 1);
575             if (olen > 0) {
576                 obuf[0] = ADB_PACKET;
577                 obuf[1] = 0x00;
578                 cuda_send_packet_to_host(s, obuf, olen + 2);
579             } else {
580                 /* error */
581                 obuf[0] = ADB_PACKET;
582                 obuf[1] = -olen;
583                 obuf[2] = data[1];
584                 olen = 0;
585                 cuda_send_packet_to_host(s, obuf, olen + 3);
586             }
587         }
588         break;
589     case CUDA_PACKET:
590         cuda_receive_packet(s, data + 1, len - 1);
591         break;
592     }
593 }
594 
595 static void cuda_writew (void *opaque, hwaddr addr, uint32_t value)
596 {
597 }
598 
599 static void cuda_writel (void *opaque, hwaddr addr, uint32_t value)
600 {
601 }
602 
603 static uint32_t cuda_readw (void *opaque, hwaddr addr)
604 {
605     return 0;
606 }
607 
608 static uint32_t cuda_readl (void *opaque, hwaddr addr)
609 {
610     return 0;
611 }
612 
613 static const MemoryRegionOps cuda_ops = {
614     .old_mmio = {
615         .write = {
616             cuda_writeb,
617             cuda_writew,
618             cuda_writel,
619         },
620         .read = {
621             cuda_readb,
622             cuda_readw,
623             cuda_readl,
624         },
625     },
626     .endianness = DEVICE_NATIVE_ENDIAN,
627 };
628 
629 static bool cuda_timer_exist(void *opaque, int version_id)
630 {
631     CUDATimer *s = opaque;
632 
633     return s->timer != NULL;
634 }
635 
636 static const VMStateDescription vmstate_cuda_timer = {
637     .name = "cuda_timer",
638     .version_id = 0,
639     .minimum_version_id = 0,
640     .fields = (VMStateField[]) {
641         VMSTATE_UINT16(latch, CUDATimer),
642         VMSTATE_UINT16(counter_value, CUDATimer),
643         VMSTATE_INT64(load_time, CUDATimer),
644         VMSTATE_INT64(next_irq_time, CUDATimer),
645         VMSTATE_TIMER_PTR_TEST(timer, CUDATimer, cuda_timer_exist),
646         VMSTATE_END_OF_LIST()
647     }
648 };
649 
650 static const VMStateDescription vmstate_cuda = {
651     .name = "cuda",
652     .version_id = 2,
653     .minimum_version_id = 2,
654     .fields = (VMStateField[]) {
655         VMSTATE_UINT8(a, CUDAState),
656         VMSTATE_UINT8(b, CUDAState),
657         VMSTATE_UINT8(dira, CUDAState),
658         VMSTATE_UINT8(dirb, CUDAState),
659         VMSTATE_UINT8(sr, CUDAState),
660         VMSTATE_UINT8(acr, CUDAState),
661         VMSTATE_UINT8(pcr, CUDAState),
662         VMSTATE_UINT8(ifr, CUDAState),
663         VMSTATE_UINT8(ier, CUDAState),
664         VMSTATE_UINT8(anh, CUDAState),
665         VMSTATE_INT32(data_in_size, CUDAState),
666         VMSTATE_INT32(data_in_index, CUDAState),
667         VMSTATE_INT32(data_out_index, CUDAState),
668         VMSTATE_UINT8(autopoll, CUDAState),
669         VMSTATE_BUFFER(data_in, CUDAState),
670         VMSTATE_BUFFER(data_out, CUDAState),
671         VMSTATE_UINT32(tick_offset, CUDAState),
672         VMSTATE_STRUCT_ARRAY(timers, CUDAState, 2, 1,
673                              vmstate_cuda_timer, CUDATimer),
674         VMSTATE_TIMER_PTR(adb_poll_timer, CUDAState),
675         VMSTATE_END_OF_LIST()
676     }
677 };
678 
679 static void cuda_reset(DeviceState *dev)
680 {
681     CUDAState *s = CUDA(dev);
682 
683     s->b = 0;
684     s->a = 0;
685     s->dirb = 0;
686     s->dira = 0;
687     s->sr = 0;
688     s->acr = 0;
689     s->pcr = 0;
690     s->ifr = 0;
691     s->ier = 0;
692     //    s->ier = T1_INT | SR_INT;
693     s->anh = 0;
694     s->data_in_size = 0;
695     s->data_in_index = 0;
696     s->data_out_index = 0;
697     s->autopoll = 0;
698 
699     s->timers[0].latch = 0xffff;
700     set_counter(s, &s->timers[0], 0xffff);
701 
702     s->timers[1].latch = 0;
703     set_counter(s, &s->timers[1], 0xffff);
704 }
705 
706 static void cuda_realizefn(DeviceState *dev, Error **errp)
707 {
708     CUDAState *s = CUDA(dev);
709     struct tm tm;
710 
711     s->timers[0].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_timer1, s);
712     s->timers[0].frequency = s->frequency;
713     s->timers[1].frequency = s->frequency;
714 
715     qemu_get_timedate(&tm, 0);
716     s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
717 
718     s->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_adb_poll, s);
719 }
720 
721 static void cuda_initfn(Object *obj)
722 {
723     SysBusDevice *d = SYS_BUS_DEVICE(obj);
724     CUDAState *s = CUDA(obj);
725     int i;
726 
727     memory_region_init_io(&s->mem, obj, &cuda_ops, s, "cuda", 0x2000);
728     sysbus_init_mmio(d, &s->mem);
729     sysbus_init_irq(d, &s->irq);
730 
731     for (i = 0; i < ARRAY_SIZE(s->timers); i++) {
732         s->timers[i].index = i;
733     }
734 
735     qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
736                         DEVICE(obj), "adb.0");
737 }
738 
739 static Property cuda_properties[] = {
740     DEFINE_PROP_UINT64("frequency", CUDAState, frequency, 0),
741     DEFINE_PROP_END_OF_LIST()
742 };
743 
744 static void cuda_class_init(ObjectClass *oc, void *data)
745 {
746     DeviceClass *dc = DEVICE_CLASS(oc);
747 
748     dc->realize = cuda_realizefn;
749     dc->reset = cuda_reset;
750     dc->vmsd = &vmstate_cuda;
751     dc->props = cuda_properties;
752     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
753 }
754 
755 static const TypeInfo cuda_type_info = {
756     .name = TYPE_CUDA,
757     .parent = TYPE_SYS_BUS_DEVICE,
758     .instance_size = sizeof(CUDAState),
759     .instance_init = cuda_initfn,
760     .class_init = cuda_class_init,
761 };
762 
763 static void cuda_register_types(void)
764 {
765     type_register_static(&cuda_type_info);
766 }
767 
768 type_init(cuda_register_types)
769