Revision 819e712b

b/hw/adb.c
63 63
    int devaddr, cmd, i;
64 64
    uint8_t obuf[4];
65 65

  
66
    cmd = buf[1] & 0xf;
67
    devaddr = buf[1] >> 4;
66
    cmd = buf[0] & 0xf;
67
    devaddr = buf[0] >> 4;
68 68
    if (buf[1] == ADB_BUSRESET) {
69 69
        obuf[0] = 0x00;
70 70
        obuf[1] = 0x00;
b/hw/cuda.c
23 23
 */
24 24
#include "vl.h"
25 25

  
26
//#define DEBUG_CUDA
27
//#define DEBUG_CUDA_PACKET
28

  
26 29
/* Bits in B data register: all active low */
27 30
#define TREQ		0x08		/* Transfer request (input) */
28 31
#define TACK		0x10		/* Transfer acknowledge (output) */
......
114 117
    int data_out_index;
115 118

  
116 119
    int irq;
120
    openpic_t *openpic;
117 121
    uint8_t autopoll;
118 122
    uint8_t data_in[128];
119 123
    uint8_t data_out[16];
......
125 129
static void cuda_update(CUDAState *s);
126 130
static void cuda_receive_packet_from_host(CUDAState *s, 
127 131
                                          const uint8_t *data, int len);
132
static void cuda_timer_update(CUDAState *s, CUDATimer *ti, 
133
                              int64_t current_time);
128 134

  
129 135
static void cuda_update_irq(CUDAState *s)
130 136
{
131
    if (s->ifr & s->ier & SR_INT) {
132
        pic_set_irq(s->irq, 1);
137
    if (s->ifr & s->ier & (SR_INT | T1_INT)) {
138
        openpic_set_irq(s->openpic, s->irq, 1);
133 139
    } else {
134
        pic_set_irq(s->irq, 0);
140
        openpic_set_irq(s->openpic, s->irq, 0);
135 141
    }
136 142
}
137 143

  
......
150 156
    return counter;
151 157
}
152 158

  
153
static void set_counter(CUDATimer *s, unsigned int val)
159
static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val)
154 160
{
155
    s->load_time = qemu_get_clock(vm_clock);
156
    s->counter_value = val;
161
#ifdef DEBUG_CUDA
162
    printf("cuda: T%d.counter=%d\n",
163
           1 + (ti->timer == NULL), val);
164
#endif
165
    ti->load_time = qemu_get_clock(vm_clock);
166
    ti->counter_value = val;
167
    cuda_timer_update(s, ti, ti->load_time);
157 168
}
158 169

  
159 170
static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time)
......
165 176
    if (d <= s->counter_value) {
166 177
        next_time = s->counter_value + 1;
167 178
    } else {
168
        base = ((d - s->counter_value) % s->latch);
179
        base = ((d - s->counter_value) / s->latch);
169 180
        base = (base * s->latch) + s->counter_value;
170 181
        next_time = base + s->latch;
171 182
    }
183
#ifdef DEBUG_CUDA
184
    printf("latch=%d counter=%lld delta_next=%lld\n", 
185
           s->latch, d, next_time - d);
186
#endif
172 187
    next_time = muldiv64(next_time, ticks_per_sec, CUDA_TIMER_FREQ) + 
173 188
        s->load_time;
174 189
    if (next_time <= current_time)
......
176 191
    return next_time;
177 192
}
178 193

  
194
static void cuda_timer_update(CUDAState *s, CUDATimer *ti, 
195
                              int64_t current_time)
196
{
197
    if (!ti->timer)
198
        return;
199
    if ((s->acr & T1MODE) != T1MODE_CONT) {
200
        qemu_del_timer(ti->timer);
201
    } else {
202
        ti->next_irq_time = get_next_irq_time(ti, current_time);
203
        qemu_mod_timer(ti->timer, ti->next_irq_time);
204
    }
205
}
206

  
179 207
static void cuda_timer1(void *opaque)
180 208
{
181 209
    CUDAState *s = opaque;
182 210
    CUDATimer *ti = &s->timers[0];
183 211

  
184
    ti->next_irq_time = get_next_irq_time(ti, ti->next_irq_time);
185
    qemu_mod_timer(ti->timer, ti->next_irq_time);
212
    cuda_timer_update(s, ti, ti->next_irq_time);
186 213
    s->ifr |= T1_INT;
187 214
    cuda_update_irq(s);
188 215
}
......
229 256
        val = get_counter(&s->timers[1]) >> 8;
230 257
        break;
231 258
    case 10:
232
        if (s->data_in_index < s->data_in_size) {
233
            val = s->data_in[s->data_in_index];
234
        } else {
235
            val = 0;
236
        }
259
        val = s->sr;
260
        s->ifr &= ~SR_INT;
261
        cuda_update_irq(s);
237 262
        break;
238 263
    case 11:
239 264
        val = s->acr;
......
253 278
        break;
254 279
    }
255 280
#ifdef DEBUG_CUDA
256
    printf("cuda: read: reg=0x%x val=%02x\n", addr, val);
281
    if (addr != 13 || val != 0)
282
        printf("cuda: read: reg=0x%x val=%02x\n", addr, val);
257 283
#endif
258 284
    return val;
259 285
}
......
283 309
        break;
284 310
    case 4:
285 311
        val = val | (get_counter(&s->timers[0]) & 0xff00);
286
        set_counter(&s->timers[0], val);
312
        set_counter(s, &s->timers[0], val);
287 313
        break;
288 314
    case 5:
289 315
        val = (val << 8) |  (get_counter(&s->timers[0]) & 0xff);
290
        set_counter(&s->timers[0], val);
316
        set_counter(s, &s->timers[0], val);
291 317
        break;
292 318
    case 6:
293 319
        s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
320
        cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
294 321
        break;
295 322
    case 7:
296 323
        s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
324
        cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
297 325
        break;
298 326
    case 8:
299 327
        val = val | (get_counter(&s->timers[1]) & 0xff00);
300
        set_counter(&s->timers[1], val);
328
        set_counter(s, &s->timers[1], val);
301 329
        break;
302 330
    case 9:
303 331
        val = (val << 8) |  (get_counter(&s->timers[1]) & 0xff);
304
        set_counter(&s->timers[1], val);
332
        set_counter(s, &s->timers[1], val);
305 333
        break;
306 334
    case 10:
307 335
        s->sr = val;
308 336
        break;
309 337
    case 11:
310 338
        s->acr = val;
311
        if ((s->acr & T1MODE) == T1MODE_CONT) {
312
            if ((s->last_acr & T1MODE) != T1MODE_CONT) {
313
                CUDATimer *ti = &s->timers[0];
314
                /* activate timer interrupt */
315
                ti->next_irq_time = get_next_irq_time(ti, qemu_get_clock(vm_clock));
316
                qemu_mod_timer(ti->timer, ti->next_irq_time);
317
            }
318
        } else {
319
            if ((s->last_acr & T1MODE) == T1MODE_CONT) {
320
                CUDATimer *ti = &s->timers[0];
321
                qemu_del_timer(ti->timer);
322
            }
323
        }
339
        cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
324 340
        cuda_update(s);
325 341
        break;
326 342
    case 12:
......
351 367
/* NOTE: TIP and TREQ are negated */
352 368
static void cuda_update(CUDAState *s)
353 369
{
354
    if (s->data_in_index < s->data_in_size) {
355
        /* data input */
356
        if (!(s->b & TIP) && 
357
            (s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
358
            s->sr = s->data_in[s->data_in_index++];
359
            s->ifr |= SR_INT;
360
            cuda_update_irq(s);
361
        }
362
    }
363
    if (s->data_in_index < s->data_in_size) {
364
        /* there is some data to read */
365
        s->b = (s->b & ~TREQ);
366
    } else {
367
        s->b = (s->b | TREQ);
368
    }
370
    int packet_received, len;
371

  
372
    packet_received = 0;
373
    if (!(s->b & TIP)) {
374
        /* transfer requested from host */
369 375

  
370
    if (s->acr & SR_OUT) {
371
        /* data output */
372
        if (!(s->b & TIP) && 
373
            (s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
374
            if (s->data_out_index < sizeof(s->data_out)) {
375
                s->data_out[s->data_out_index++] = s->sr;
376
        if (s->acr & SR_OUT) {
377
            /* data output */
378
            if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
379
                if (s->data_out_index < sizeof(s->data_out)) {
380
#ifdef DEBUG_CUDA
381
                    printf("cuda: send: %02x\n", s->sr);
382
#endif
383
                    s->data_out[s->data_out_index++] = s->sr;
384
                    s->ifr |= SR_INT;
385
                    cuda_update_irq(s);
386
                }
387
            }
388
        } else {
389
            if (s->data_in_index < s->data_in_size) {
390
                /* data input */
391
                if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
392
                    s->sr = s->data_in[s->data_in_index++];
393
#ifdef DEBUG_CUDA
394
                    printf("cuda: recv: %02x\n", s->sr);
395
#endif
396
                    /* indicate end of transfer */
397
                    if (s->data_in_index >= s->data_in_size) {
398
                        s->b = (s->b | TREQ);
399
                    }
400
                    s->ifr |= SR_INT;
401
                    cuda_update_irq(s);
402
                }
376 403
            }
404
        }
405
    } else {
406
        /* no transfer requested: handle sync case */
407
        if ((s->last_b & TIP) && (s->b & TACK) != (s->last_b & TACK)) {
408
            /* update TREQ state each time TACK change state */
409
            if (s->b & TACK)
410
                s->b = (s->b | TREQ);
411
            else
412
                s->b = (s->b & ~TREQ);
377 413
            s->ifr |= SR_INT;
378 414
            cuda_update_irq(s);
415
        } else {
416
            if (!(s->last_b & TIP)) {
417
                /* handle end of host to cuda transfert */
418
                packet_received = (s->data_out_index > 0);
419
                /* always an IRQ at the end of transfert */
420
                s->ifr |= SR_INT;
421
                cuda_update_irq(s);
422
            }
423
            /* signal if there is data to read */
424
            if (s->data_in_index < s->data_in_size) {
425
                s->b = (s->b & ~TREQ);
426
            }
379 427
        }
380 428
    }
381 429

  
382
    /* check end of data output */
383
    if (!(s->acr & SR_OUT) && (s->last_acr & SR_OUT)) {
384
        if (s->data_out_index > 0)
385
            cuda_receive_packet_from_host(s, s->data_out, s->data_out_index);
386
        s->data_out_index = 0;
387
    }
388 430
    s->last_acr = s->acr;
389 431
    s->last_b = s->b;
432

  
433
    /* NOTE: cuda_receive_packet_from_host() can call cuda_update()
434
       recursively */
435
    if (packet_received) {
436
        len = s->data_out_index;
437
        s->data_out_index = 0;
438
        cuda_receive_packet_from_host(s, s->data_out, len);
439
    }
390 440
}
391 441

  
392 442
static void cuda_send_packet_to_host(CUDAState *s, 
393 443
                                     const uint8_t *data, int len)
394 444
{
445
#ifdef DEBUG_CUDA_PACKET
446
    {
447
        int i;
448
        printf("cuda_send_packet_to_host:\n");
449
        for(i = 0; i < len; i++)
450
            printf(" %02x", data[i]);
451
        printf("\n");
452
    }
453
#endif
395 454
    memcpy(s->data_in, data, len);
396 455
    s->data_in_size = len;
397 456
    s->data_in_index = 0;
......
425 484
        break;
426 485
    case CUDA_GET_TIME:
427 486
        /* XXX: add time support ? */
428
        ti = 0;
487
        ti = time(NULL);
429 488
        obuf[0] = CUDA_PACKET;
430 489
        obuf[1] = 0;
431 490
        obuf[2] = 0;
......
452 511
static void cuda_receive_packet_from_host(CUDAState *s, 
453 512
                                          const uint8_t *data, int len)
454 513
{
514
#ifdef DEBUG_CUDA_PACKET
515
    {
516
        int i;
517
        printf("cuda_receive_packet_to_host:\n");
518
        for(i = 0; i < len; i++)
519
            printf(" %02x", data[i]);
520
        printf("\n");
521
    }
522
#endif
455 523
    switch(data[0]) {
456 524
    case ADB_PACKET:
457 525
        adb_receive_packet(&adb_bus, data + 1, len - 1);
......
492 560
    &cuda_readl,
493 561
};
494 562

  
495
int cuda_init(void)
563
int cuda_init(openpic_t *openpic, int irq)
496 564
{
497 565
    CUDAState *s = &cuda_state;
498 566
    int cuda_mem_index;
499 567

  
500
    s->timers[0].latch = 0x10000;
501
    set_counter(&s->timers[0], 0xffff);
568
    s->openpic = openpic;
569
    s->irq = irq;
570

  
502 571
    s->timers[0].timer = qemu_new_timer(vm_clock, cuda_timer1, s);
572
    s->timers[0].latch = 0x10000;
573
    set_counter(s, &s->timers[0], 0xffff);
503 574
    s->timers[1].latch = 0x10000;
504
    set_counter(&s->timers[1], 0xffff);
575
    s->ier = T1_INT | SR_INT;
576
    set_counter(s, &s->timers[1], 0xffff);
505 577
    cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s);
506 578
    return cuda_mem_index;
507 579
}

Also available in: Unified diff