~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/esp.c

  • Committer: Blue Swirl
  • Date: 2009-08-31 15:14:40 UTC
  • Revision ID: git-v1:528e93a9787ccfc59582a44035f5f342caf5b84f
Fix breakage due to __thread

Thread-local storage is not supported on all hosts.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 * THE SOFTWARE.
23
23
 */
24
24
 
25
 
#include "hw.h"
 
25
#include "sysbus.h"
26
26
#include "scsi-disk.h"
27
27
#include "scsi.h"
28
28
 
38
38
 */
39
39
 
40
40
#ifdef DEBUG_ESP
41
 
#define DPRINTF(fmt, args...) \
42
 
do { printf("ESP: " fmt , ##args); } while (0)
 
41
#define DPRINTF(fmt, ...)                                       \
 
42
    do { printf("ESP: " fmt , ## __VA_ARGS__); } while (0)
43
43
#else
44
 
#define DPRINTF(fmt, args...) do {} while (0)
 
44
#define DPRINTF(fmt, ...) do {} while (0)
45
45
#endif
46
46
 
 
47
#define ESP_ERROR(fmt, ...)                                             \
 
48
    do { printf("ESP ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0)
 
49
 
47
50
#define ESP_REGS 16
48
 
#define TI_BUFSZ 32
 
51
#define TI_BUFSZ 16
49
52
 
50
53
typedef struct ESPState ESPState;
51
54
 
52
55
struct ESPState {
 
56
    SysBusDevice busdev;
53
57
    uint32_t it_shift;
54
58
    qemu_irq irq;
55
59
    uint8_t rregs[ESP_REGS];
111
115
#define CMD_TI       0x10
112
116
#define CMD_ICCS     0x11
113
117
#define CMD_MSGACC   0x12
 
118
#define CMD_PAD      0x18
114
119
#define CMD_SATN     0x1a
 
120
#define CMD_SEL      0x41
115
121
#define CMD_SELATN   0x42
116
122
#define CMD_SELATNS  0x43
117
123
#define CMD_ENSEL    0x44
120
126
#define STAT_DI 0x01
121
127
#define STAT_CD 0x02
122
128
#define STAT_ST 0x03
123
 
#define STAT_MI 0x06
124
 
#define STAT_MO 0x07
 
129
#define STAT_MO 0x06
 
130
#define STAT_MI 0x07
125
131
#define STAT_PIO_MASK 0x06
126
132
 
127
133
#define STAT_TC 0x10
129
135
#define STAT_GE 0x40
130
136
#define STAT_INT 0x80
131
137
 
 
138
#define BUSID_DID 0x07
 
139
 
132
140
#define INTR_FC 0x08
133
141
#define INTR_BS 0x10
134
142
#define INTR_DC 0x20
139
147
 
140
148
#define CFG1_RESREPT 0x40
141
149
 
142
 
#define CFG2_MASK 0x15
143
 
 
144
150
#define TCHI_FAS100A 0x4
145
151
 
146
152
static void esp_raise_irq(ESPState *s)
164
170
    uint32_t dmalen;
165
171
    int target;
166
172
 
167
 
    dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
168
 
    target = s->wregs[ESP_WBUSID] & 7;
169
 
    DPRINTF("get_cmd: len %d target %d\n", dmalen, target);
 
173
    target = s->wregs[ESP_WBUSID] & BUSID_DID;
170
174
    if (s->dma) {
 
175
        dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
171
176
        s->dma_memory_read(s->dma_opaque, buf, dmalen);
172
177
    } else {
 
178
        dmalen = s->ti_size;
 
179
        memcpy(buf, s->ti_buf, dmalen);
173
180
        buf[0] = 0;
174
 
        memcpy(&buf[1], s->ti_buf, dmalen);
175
 
        dmalen++;
176
181
    }
 
182
    DPRINTF("get_cmd: len %d target %d\n", dmalen, target);
177
183
 
178
184
    s->ti_size = 0;
179
185
    s->ti_rptr = 0;
318
324
        } else {
319
325
            s->current_dev->read_data(s->current_dev, 0);
320
326
            /* If there is still data to be read from the device then
321
 
               complete the DMA operation immeriately.  Otherwise defer
 
327
               complete the DMA operation immediately.  Otherwise defer
322
328
               until the scsi layer has completed.  */
323
329
            if (s->dma_left == 0 && s->ti_size > 0) {
324
330
                esp_dma_done(s);
397
403
{
398
404
    ESPState *s = opaque;
399
405
 
400
 
    esp_lower_irq(s);
401
 
 
402
406
    memset(s->rregs, 0, ESP_REGS);
403
407
    memset(s->wregs, 0, ESP_REGS);
404
408
    s->rregs[ESP_TCHI] = TCHI_FAS100A; // Indicate fas100a
407
411
    s->ti_wptr = 0;
408
412
    s->dma = 0;
409
413
    s->do_cmd = 0;
 
414
 
 
415
    s->rregs[ESP_CFG1] = 7;
410
416
}
411
417
 
412
418
static void parent_esp_reset(void *opaque, int irq, int level)
418
424
static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
419
425
{
420
426
    ESPState *s = opaque;
421
 
    uint32_t saddr;
 
427
    uint32_t saddr, old_val;
422
428
 
423
 
    saddr = (addr >> s->it_shift) & (ESP_REGS - 1);
 
429
    saddr = addr >> s->it_shift;
424
430
    DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);
425
431
    switch (saddr) {
426
432
    case ESP_FIFO:
427
433
        if (s->ti_size > 0) {
428
434
            s->ti_size--;
429
435
            if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
430
 
                /* Data in/out.  */
431
 
                fprintf(stderr, "esp: PIO data read not implemented\n");
 
436
                /* Data out.  */
 
437
                ESP_ERROR("PIO data read not implemented\n");
432
438
                s->rregs[ESP_FIFO] = 0;
433
439
            } else {
434
440
                s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
441
447
        }
442
448
        break;
443
449
    case ESP_RINTR:
444
 
        // Clear interrupt/error status bits
445
 
        s->rregs[ESP_RSTAT] &= ~(STAT_GE | STAT_PE);
 
450
        /* Clear sequence step, interrupt register and all status bits
 
451
           except TC */
 
452
        old_val = s->rregs[ESP_RINTR];
 
453
        s->rregs[ESP_RINTR] = 0;
 
454
        s->rregs[ESP_RSTAT] &= ~STAT_TC;
 
455
        s->rregs[ESP_RSEQ] = SEQ_CD;
446
456
        esp_lower_irq(s);
447
 
        break;
 
457
 
 
458
        return old_val;
448
459
    default:
449
460
        break;
450
461
    }
456
467
    ESPState *s = opaque;
457
468
    uint32_t saddr;
458
469
 
459
 
    saddr = (addr >> s->it_shift) & (ESP_REGS - 1);
 
470
    saddr = addr >> s->it_shift;
460
471
    DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr],
461
472
            val);
462
473
    switch (saddr) {
467
478
    case ESP_FIFO:
468
479
        if (s->do_cmd) {
469
480
            s->cmdbuf[s->cmdlen++] = val & 0xff;
470
 
        } else if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
471
 
            uint8_t buf;
472
 
            buf = val & 0xff;
473
 
            s->ti_size--;
474
 
            fprintf(stderr, "esp: PIO data write not implemented\n");
 
481
        } else if (s->ti_size == TI_BUFSZ - 1) {
 
482
            ESP_ERROR("fifo overrun\n");
475
483
        } else {
476
484
            s->ti_size++;
477
485
            s->ti_buf[s->ti_wptr++] = val & 0xff;
496
504
            //s->ti_size = 0;
497
505
            s->rregs[ESP_RINTR] = INTR_FC;
498
506
            s->rregs[ESP_RSEQ] = 0;
 
507
            s->rregs[ESP_RFLAGS] = 0;
499
508
            break;
500
509
        case CMD_RESET:
501
510
            DPRINTF("Chip reset (%2.2x)\n", val);
514
523
        case CMD_ICCS:
515
524
            DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
516
525
            write_response(s);
 
526
            s->rregs[ESP_RINTR] = INTR_FC;
 
527
            s->rregs[ESP_RSTAT] |= STAT_MI;
517
528
            break;
518
529
        case CMD_MSGACC:
519
530
            DPRINTF("Message Accepted (%2.2x)\n", val);
521
532
            s->rregs[ESP_RINTR] = INTR_DC;
522
533
            s->rregs[ESP_RSEQ] = 0;
523
534
            break;
 
535
        case CMD_PAD:
 
536
            DPRINTF("Transfer padding (%2.2x)\n", val);
 
537
            s->rregs[ESP_RSTAT] = STAT_TC;
 
538
            s->rregs[ESP_RINTR] = INTR_FC;
 
539
            s->rregs[ESP_RSEQ] = 0;
 
540
            break;
524
541
        case CMD_SATN:
525
542
            DPRINTF("Set ATN (%2.2x)\n", val);
526
543
            break;
 
544
        case CMD_SEL:
 
545
            DPRINTF("Select without ATN (%2.2x)\n", val);
 
546
            handle_satn(s);
 
547
            break;
527
548
        case CMD_SELATN:
528
 
            DPRINTF("Set ATN (%2.2x)\n", val);
 
549
            DPRINTF("Select with ATN (%2.2x)\n", val);
529
550
            handle_satn(s);
530
551
            break;
531
552
        case CMD_SELATNS:
532
 
            DPRINTF("Set ATN & stop (%2.2x)\n", val);
 
553
            DPRINTF("Select with ATN & stop (%2.2x)\n", val);
533
554
            handle_satn_stop(s);
534
555
            break;
535
556
        case CMD_ENSEL:
536
557
            DPRINTF("Enable selection (%2.2x)\n", val);
 
558
            s->rregs[ESP_RINTR] = 0;
537
559
            break;
538
560
        default:
539
 
            DPRINTF("Unhandled ESP command (%2.2x)\n", val);
 
561
            ESP_ERROR("Unhandled ESP command (%2.2x)\n", val);
540
562
            break;
541
563
        }
542
564
        break;
547
569
        break;
548
570
    case ESP_WCCF ... ESP_WTEST:
549
571
        break;
550
 
    case ESP_CFG2:
551
 
        s->rregs[saddr] = val & CFG2_MASK;
552
 
        break;
553
 
    case ESP_CFG3 ... ESP_RES4:
 
572
    case ESP_CFG2 ... ESP_RES4:
554
573
        s->rregs[saddr] = val;
555
574
        break;
556
575
    default:
557
 
        break;
 
576
        ESP_ERROR("invalid write of 0x%02x at [0x%x]\n", val, saddr);
 
577
        return;
558
578
    }
559
579
    s->wregs[saddr] = val;
560
580
}
561
581
 
562
 
static CPUReadMemoryFunc *esp_mem_read[3] = {
 
582
static CPUReadMemoryFunc * const esp_mem_read[3] = {
563
583
    esp_mem_readb,
564
584
    NULL,
565
585
    NULL,
566
586
};
567
587
 
568
 
static CPUWriteMemoryFunc *esp_mem_write[3] = {
569
 
    esp_mem_writeb,
570
 
    NULL,
571
 
    NULL,
 
588
static CPUWriteMemoryFunc * const esp_mem_write[3] = {
 
589
    esp_mem_writeb,
 
590
    NULL,
 
591
    esp_mem_writeb,
572
592
};
573
593
 
574
594
static void esp_save(QEMUFile *f, void *opaque)
577
597
 
578
598
    qemu_put_buffer(f, s->rregs, ESP_REGS);
579
599
    qemu_put_buffer(f, s->wregs, ESP_REGS);
580
 
    qemu_put_be32s(f, (uint32_t *)&s->ti_size);
 
600
    qemu_put_sbe32s(f, &s->ti_size);
581
601
    qemu_put_be32s(f, &s->ti_rptr);
582
602
    qemu_put_be32s(f, &s->ti_wptr);
583
603
    qemu_put_buffer(f, s->ti_buf, TI_BUFSZ);
599
619
 
600
620
    qemu_get_buffer(f, s->rregs, ESP_REGS);
601
621
    qemu_get_buffer(f, s->wregs, ESP_REGS);
602
 
    qemu_get_be32s(f, (uint32_t *)&s->ti_size);
 
622
    qemu_get_sbe32s(f, &s->ti_size);
603
623
    qemu_get_be32s(f, &s->ti_rptr);
604
624
    qemu_get_be32s(f, &s->ti_wptr);
605
625
    qemu_get_buffer(f, s->ti_buf, TI_BUFSZ);
613
633
    return 0;
614
634
}
615
635
 
616
 
void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id)
 
636
static void esp_scsi_attach(DeviceState *host, BlockDriverState *bd, int id)
617
637
{
618
 
    ESPState *s = (ESPState *)opaque;
 
638
    ESPState *s = FROM_SYSBUS(ESPState, sysbus_from_qdev(host));
619
639
 
620
640
    if (id < 0) {
621
641
        for (id = 0; id < ESP_MAX_DEVS; id++) {
 
642
            if (id == (s->rregs[ESP_CFG1] & 0x7))
 
643
                continue;
622
644
            if (s->scsi_dev[id] == NULL)
623
645
                break;
624
646
        }
638
660
        s->scsi_dev[id] = scsi_disk_init(bd, 0, esp_command_complete, s);
639
661
}
640
662
 
641
 
void *esp_init(target_phys_addr_t espaddr, int it_shift,
642
 
               espdma_memory_read_write dma_memory_read,
643
 
               espdma_memory_read_write dma_memory_write,
644
 
               void *dma_opaque, qemu_irq irq, qemu_irq *reset)
645
 
{
646
 
    ESPState *s;
 
663
void esp_init(target_phys_addr_t espaddr, int it_shift,
 
664
              espdma_memory_read_write dma_memory_read,
 
665
              espdma_memory_read_write dma_memory_write,
 
666
              void *dma_opaque, qemu_irq irq, qemu_irq *reset)
 
667
{
 
668
    DeviceState *dev;
 
669
    SysBusDevice *s;
 
670
    ESPState *esp;
 
671
 
 
672
    dev = qdev_create(NULL, "esp");
 
673
    esp = DO_UPCAST(ESPState, busdev.qdev, dev);
 
674
    esp->dma_memory_read = dma_memory_read;
 
675
    esp->dma_memory_write = dma_memory_write;
 
676
    esp->dma_opaque = dma_opaque;
 
677
    esp->it_shift = it_shift;
 
678
    qdev_init(dev);
 
679
    s = sysbus_from_qdev(dev);
 
680
    sysbus_connect_irq(s, 0, irq);
 
681
    sysbus_mmio_map(s, 0, espaddr);
 
682
    *reset = qdev_get_gpio_in(dev, 0);
 
683
}
 
684
 
 
685
static int esp_init1(SysBusDevice *dev)
 
686
{
 
687
    ESPState *s = FROM_SYSBUS(ESPState, dev);
647
688
    int esp_io_memory;
648
689
 
649
 
    s = qemu_mallocz(sizeof(ESPState));
650
 
    if (!s)
651
 
        return NULL;
652
 
 
653
 
    s->irq = irq;
654
 
    s->it_shift = it_shift;
655
 
    s->dma_memory_read = dma_memory_read;
656
 
    s->dma_memory_write = dma_memory_write;
657
 
    s->dma_opaque = dma_opaque;
658
 
 
659
 
    esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s);
660
 
    cpu_register_physical_memory(espaddr, ESP_REGS << it_shift, esp_io_memory);
 
690
    sysbus_init_irq(dev, &s->irq);
 
691
    assert(s->it_shift != -1);
 
692
 
 
693
    esp_io_memory = cpu_register_io_memory(esp_mem_read, esp_mem_write, s);
 
694
    sysbus_init_mmio(dev, ESP_REGS << s->it_shift, esp_io_memory);
661
695
 
662
696
    esp_reset(s);
663
697
 
664
 
    register_savevm("esp", espaddr, 3, esp_save, esp_load, s);
 
698
    register_savevm("esp", -1, 3, esp_save, esp_load, s);
665
699
    qemu_register_reset(esp_reset, s);
666
700
 
667
 
    *reset = *qemu_allocate_irqs(parent_esp_reset, s, 1);
668
 
 
669
 
    return s;
670
 
}
 
701
    qdev_init_gpio_in(&dev->qdev, parent_esp_reset, 1);
 
702
 
 
703
    scsi_bus_new(&dev->qdev, esp_scsi_attach);
 
704
    return 0;
 
705
}
 
706
 
 
707
static void esp_register_devices(void)
 
708
{
 
709
    sysbus_register_dev("esp", sizeof(ESPState), esp_init1);
 
710
}
 
711
 
 
712
device_init(esp_register_devices)