~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to hw/misc/macio/mac_dbdma.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
/*
55
55
 */
56
56
 
57
 
/*
58
 
 * DBDMA control/status registers.  All little-endian.
59
 
 */
60
 
 
61
 
#define DBDMA_CONTROL         0x00
62
 
#define DBDMA_STATUS          0x01
63
 
#define DBDMA_CMDPTR_HI       0x02
64
 
#define DBDMA_CMDPTR_LO       0x03
65
 
#define DBDMA_INTR_SEL        0x04
66
 
#define DBDMA_BRANCH_SEL      0x05
67
 
#define DBDMA_WAIT_SEL        0x06
68
 
#define DBDMA_XFER_MODE       0x07
69
 
#define DBDMA_DATA2PTR_HI     0x08
70
 
#define DBDMA_DATA2PTR_LO     0x09
71
 
#define DBDMA_RES1            0x0A
72
 
#define DBDMA_ADDRESS_HI      0x0B
73
 
#define DBDMA_BRANCH_ADDR_HI  0x0C
74
 
#define DBDMA_RES2            0x0D
75
 
#define DBDMA_RES3            0x0E
76
 
#define DBDMA_RES4            0x0F
77
 
 
78
 
#define DBDMA_REGS            16
79
 
#define DBDMA_SIZE            (DBDMA_REGS * sizeof(uint32_t))
80
 
 
81
 
#define DBDMA_CHANNEL_SHIFT   7
82
 
#define DBDMA_CHANNEL_SIZE    (1 << DBDMA_CHANNEL_SHIFT)
83
 
 
84
 
#define DBDMA_CHANNELS        (0x1000 >> DBDMA_CHANNEL_SHIFT)
85
 
 
86
 
/* Bits in control and status registers */
87
 
 
88
 
#define RUN     0x8000
89
 
#define PAUSE   0x4000
90
 
#define FLUSH   0x2000
91
 
#define WAKE    0x1000
92
 
#define DEAD    0x0800
93
 
#define ACTIVE  0x0400
94
 
#define BT      0x0100
95
 
#define DEVSTAT 0x00ff
96
 
 
97
 
/*
98
 
 * DBDMA command structure.  These fields are all little-endian!
99
 
 */
100
 
 
101
 
typedef struct dbdma_cmd {
102
 
    uint16_t req_count;   /* requested byte transfer count */
103
 
    uint16_t command;     /* command word (has bit-fields) */
104
 
    uint32_t phy_addr;    /* physical data address */
105
 
    uint32_t cmd_dep;     /* command-dependent field */
106
 
    uint16_t res_count;   /* residual count after completion */
107
 
    uint16_t xfer_status; /* transfer status */
108
 
} dbdma_cmd;
109
 
 
110
 
/* DBDMA command values in command field */
111
 
 
112
 
#define COMMAND_MASK    0xf000
113
 
#define OUTPUT_MORE     0x0000  /* transfer memory data to stream */
114
 
#define OUTPUT_LAST     0x1000  /* ditto followed by end marker */
115
 
#define INPUT_MORE      0x2000  /* transfer stream data to memory */
116
 
#define INPUT_LAST      0x3000  /* ditto, expect end marker */
117
 
#define STORE_WORD      0x4000  /* write word (4 bytes) to device reg */
118
 
#define LOAD_WORD       0x5000  /* read word (4 bytes) from device reg */
119
 
#define DBDMA_NOP       0x6000  /* do nothing */
120
 
#define DBDMA_STOP      0x7000  /* suspend processing */
121
 
 
122
 
/* Key values in command field */
123
 
 
124
 
#define KEY_MASK        0x0700
125
 
#define KEY_STREAM0     0x0000  /* usual data stream */
126
 
#define KEY_STREAM1     0x0100  /* control/status stream */
127
 
#define KEY_STREAM2     0x0200  /* device-dependent stream */
128
 
#define KEY_STREAM3     0x0300  /* device-dependent stream */
129
 
#define KEY_STREAM4     0x0400  /* reserved */
130
 
#define KEY_REGS        0x0500  /* device register space */
131
 
#define KEY_SYSTEM      0x0600  /* system memory-mapped space */
132
 
#define KEY_DEVICE      0x0700  /* device memory-mapped space */
133
 
 
134
 
/* Interrupt control values in command field */
135
 
 
136
 
#define INTR_MASK       0x0030
137
 
#define INTR_NEVER      0x0000  /* don't interrupt */
138
 
#define INTR_IFSET      0x0010  /* intr if condition bit is 1 */
139
 
#define INTR_IFCLR      0x0020  /* intr if condition bit is 0 */
140
 
#define INTR_ALWAYS     0x0030  /* always interrupt */
141
 
 
142
 
/* Branch control values in command field */
143
 
 
144
 
#define BR_MASK         0x000c
145
 
#define BR_NEVER        0x0000  /* don't branch */
146
 
#define BR_IFSET        0x0004  /* branch if condition bit is 1 */
147
 
#define BR_IFCLR        0x0008  /* branch if condition bit is 0 */
148
 
#define BR_ALWAYS       0x000c  /* always branch */
149
 
 
150
 
/* Wait control values in command field */
151
 
 
152
 
#define WAIT_MASK       0x0003
153
 
#define WAIT_NEVER      0x0000  /* don't wait */
154
 
#define WAIT_IFSET      0x0001  /* wait if condition bit is 1 */
155
 
#define WAIT_IFCLR      0x0002  /* wait if condition bit is 0 */
156
 
#define WAIT_ALWAYS     0x0003  /* always wait */
157
 
 
158
 
typedef struct DBDMA_channel {
159
 
    int channel;
160
 
    uint32_t regs[DBDMA_REGS];
161
 
    qemu_irq irq;
162
 
    DBDMA_io io;
163
 
    DBDMA_rw rw;
164
 
    DBDMA_flush flush;
165
 
    dbdma_cmd current;
166
 
    int processing;
167
 
} DBDMA_channel;
168
 
 
169
 
typedef struct {
170
 
    MemoryRegion mem;
171
 
    DBDMA_channel channels[DBDMA_CHANNELS];
172
 
} DBDMAState;
 
57
static DBDMAState *dbdma_from_ch(DBDMA_channel *ch)
 
58
{
 
59
    return container_of(ch, DBDMAState, channels[ch->channel]);
 
60
}
173
61
 
174
62
#ifdef DEBUG_DBDMA
175
63
static void dump_dbdma_cmd(dbdma_cmd *cmd)
224
112
    uint32_t status;
225
113
    int cond;
226
114
 
227
 
    DBDMA_DPRINTF("conditional_interrupt\n");
 
115
    DBDMA_DPRINTF("%s\n", __func__);
228
116
 
229
117
    intr = le16_to_cpu(current->command) & INTR_MASK;
230
118
 
233
121
        return;
234
122
    case INTR_ALWAYS: /* always interrupt */
235
123
        qemu_irq_raise(ch->irq);
 
124
        DBDMA_DPRINTF("%s: raise\n", __func__);
236
125
        return;
237
126
    }
238
127
 
245
134
 
246
135
    switch(intr) {
247
136
    case INTR_IFSET:  /* intr if condition bit is 1 */
248
 
        if (cond)
 
137
        if (cond) {
249
138
            qemu_irq_raise(ch->irq);
 
139
            DBDMA_DPRINTF("%s: raise\n", __func__);
 
140
        }
250
141
        return;
251
142
    case INTR_IFCLR:  /* intr if condition bit is 0 */
252
 
        if (!cond)
 
143
        if (!cond) {
253
144
            qemu_irq_raise(ch->irq);
 
145
            DBDMA_DPRINTF("%s: raise\n", __func__);
 
146
        }
254
147
        return;
255
148
    }
256
149
}
360
253
    }
361
254
}
362
255
 
363
 
static QEMUBH *dbdma_bh;
364
256
static void channel_run(DBDMA_channel *ch);
365
257
 
366
258
static void dbdma_end(DBDMA_io *io)
368
260
    DBDMA_channel *ch = io->channel;
369
261
    dbdma_cmd *current = &ch->current;
370
262
 
 
263
    DBDMA_DPRINTF("%s\n", __func__);
 
264
 
371
265
    if (conditional_wait(ch))
372
266
        goto wait;
373
267
 
381
275
    conditional_branch(ch);
382
276
 
383
277
wait:
384
 
    ch->processing = 0;
 
278
    /* Indicate that we're ready for a new DMA round */
 
279
    ch->io.processing = false;
 
280
 
385
281
    if ((ch->regs[DBDMA_STATUS] & RUN) &&
386
282
        (ch->regs[DBDMA_STATUS] & ACTIVE))
387
283
        channel_run(ch);
407
303
    ch->io.is_last = is_last;
408
304
    ch->io.dma_end = dbdma_end;
409
305
    ch->io.is_dma_out = 1;
410
 
    ch->processing = 1;
 
306
    ch->io.processing = true;
411
307
    if (ch->rw) {
412
308
        ch->rw(&ch->io);
413
309
    }
422
318
     * are not implemented in the mac-io chip
423
319
     */
424
320
 
 
321
    DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key);
425
322
    if (!addr || key > KEY_STREAM3) {
426
323
        kill_channel(ch);
427
324
        return;
432
329
    ch->io.is_last = is_last;
433
330
    ch->io.dma_end = dbdma_end;
434
331
    ch->io.is_dma_out = 0;
435
 
    ch->processing = 1;
 
332
    ch->io.processing = true;
436
333
    if (ch->rw) {
437
334
        ch->rw(&ch->io);
438
335
    }
474
371
    next(ch);
475
372
 
476
373
wait:
477
 
    qemu_bh_schedule(dbdma_bh);
 
374
    DBDMA_kick(dbdma_from_ch(ch));
478
375
}
479
376
 
480
377
static void store_word(DBDMA_channel *ch, int key, uint32_t addr,
512
409
    next(ch);
513
410
 
514
411
wait:
515
 
    qemu_bh_schedule(dbdma_bh);
 
412
    DBDMA_kick(dbdma_from_ch(ch));
516
413
}
517
414
 
518
415
static void nop(DBDMA_channel *ch)
529
426
    conditional_branch(ch);
530
427
 
531
428
wait:
532
 
    qemu_bh_schedule(dbdma_bh);
 
429
    DBDMA_kick(dbdma_from_ch(ch));
533
430
}
534
431
 
535
432
static void stop(DBDMA_channel *ch)
558
455
    switch (cmd) {
559
456
    case DBDMA_NOP:
560
457
        nop(ch);
561
 
        return;
 
458
        return;
562
459
 
563
460
    case DBDMA_STOP:
564
461
        stop(ch);
565
 
        return;
 
462
        return;
566
463
    }
567
464
 
568
465
    key = le16_to_cpu(current->command) & 0x0700;
578
475
    switch (cmd) {
579
476
    case OUTPUT_MORE:
580
477
        start_output(ch, key, phy_addr, req_count, 0);
581
 
        return;
 
478
        return;
582
479
 
583
480
    case OUTPUT_LAST:
584
481
        start_output(ch, key, phy_addr, req_count, 1);
585
 
        return;
 
482
        return;
586
483
 
587
484
    case INPUT_MORE:
588
485
        start_input(ch, key, phy_addr, req_count, 0);
589
 
        return;
 
486
        return;
590
487
 
591
488
    case INPUT_LAST:
592
489
        start_input(ch, key, phy_addr, req_count, 1);
593
 
        return;
 
490
        return;
594
491
    }
595
492
 
596
493
    if (key < KEY_REGS) {
615
512
    switch (cmd) {
616
513
    case LOAD_WORD:
617
514
        load_word(ch, key, phy_addr, req_count);
618
 
        return;
 
515
        return;
619
516
 
620
517
    case STORE_WORD:
621
518
        store_word(ch, key, phy_addr, req_count);
622
 
        return;
 
519
        return;
623
520
    }
624
521
}
625
522
 
630
527
    for (channel = 0; channel < DBDMA_CHANNELS; channel++) {
631
528
        DBDMA_channel *ch = &s->channels[channel];
632
529
        uint32_t status = ch->regs[DBDMA_STATUS];
633
 
        if (!ch->processing && (status & RUN) && (status & ACTIVE)) {
 
530
        if (!ch->io.processing && (status & RUN) && (status & ACTIVE)) {
634
531
            channel_run(ch);
635
532
        }
636
533
    }
645
542
    DBDMA_run(s);
646
543
}
647
544
 
 
545
void DBDMA_kick(DBDMAState *dbdma)
 
546
{
 
547
    qemu_bh_schedule(dbdma->bh);
 
548
}
 
549
 
648
550
void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
649
551
                            DBDMA_rw rw, DBDMA_flush flush,
650
552
                            void *opaque)
698
600
 
699
601
    ch->regs[DBDMA_STATUS] = status;
700
602
 
701
 
    if (status & ACTIVE)
702
 
        qemu_bh_schedule(dbdma_bh);
703
 
    if ((status & FLUSH) && ch->flush)
 
603
    if (status & ACTIVE) {
 
604
        DBDMA_kick(dbdma_from_ch(ch));
 
605
    }
 
606
    if ((status & FLUSH) && ch->flush) {
704
607
        ch->flush(&ch->io);
 
608
    }
705
609
}
706
610
 
707
611
static void dbdma_write(void *opaque, hwaddr addr,
712
616
    DBDMA_channel *ch = &s->channels[channel];
713
617
    int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;
714
618
 
715
 
    DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08x\n", addr, value);
 
619
    DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08"PRIx64"\n",
 
620
                  addr, value);
716
621
    DBDMA_DPRINTF("channel 0x%x reg 0x%x\n",
717
622
                  (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);
718
623
 
719
 
    /* cmdptr cannot be modified if channel is RUN or ACTIVE */
 
624
    /* cmdptr cannot be modified if channel is ACTIVE */
720
625
 
721
 
    if (reg == DBDMA_CMDPTR_LO &&
722
 
        (ch->regs[DBDMA_STATUS] & (RUN | ACTIVE)))
723
 
        return;
 
626
    if (reg == DBDMA_CMDPTR_LO && (ch->regs[DBDMA_STATUS] & ACTIVE)) {
 
627
        return;
 
628
    }
724
629
 
725
630
    ch->regs[reg] = value;
726
631
 
848
753
 
849
754
    s = g_malloc0(sizeof(DBDMAState));
850
755
 
851
 
    memory_region_init_io(&s->mem, &dbdma_ops, s, "dbdma", 0x1000);
 
756
    memory_region_init_io(&s->mem, NULL, &dbdma_ops, s, "dbdma", 0x1000);
852
757
    *dbdma_mem = &s->mem;
853
758
    vmstate_register(NULL, -1, &vmstate_dbdma, s);
854
759
    qemu_register_reset(dbdma_reset, s);
855
760
 
856
 
    dbdma_bh = qemu_bh_new(DBDMA_run_bh, s);
 
761
    s->bh = qemu_bh_new(DBDMA_run_bh, s);
857
762
 
858
763
    return s;
859
764
}