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

« back to all changes in this revision

Viewing changes to debian/patches/ubuntu/linaro/0008-omap_dma-add-scatter-gather-list-support.patch

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-02-04 12:13:08 UTC
  • mfrom: (10.1.45 sid)
  • Revision ID: package-import@ubuntu.com-20140204121308-1xq92lrfs75agw2g
Tags: 1.7.0+dfsg-3ubuntu1~ppa1
* Merge 1.7.0+dfsg-3 from debian.  Remaining changes:
  - debian/patches/ubuntu:
    * expose-vmx_qemu64cpu.patch
    * linaro (omap3) and arm64 patches
    * ubuntu/target-ppc-add-stubs-for-kvm-breakpoints: fix FTBFS
      on ppc
    * ubuntu/CVE-2013-4377.patch: fix denial of service via virtio
  - debian/qemu-system-x86.modprobe: set kvm_intel nested=1 options
  - debian/control:
    * add arm64 to Architectures
    * add qemu-common and qemu-system-aarch64 packages
  - debian/qemu-system-common.install: add debian/tmp/usr/lib
  - debian/qemu-system-common.preinst: add kvm group
  - debian/qemu-system-common.postinst: remove acl placed by udev,
    and add udevadm trigger.
  - qemu-system-x86.links: add eepro100.rom, remove pxe-virtio,
    pxe-e1000 and pxe-rtl8139.
  - add qemu-system-x86.qemu-kvm.upstart and .default
  - qemu-user-static.postinst-in: remove arm64 binfmt
  - debian/rules:
    * allow parallel build
    * add aarch64 to system_targets and sys_systems
    * add qemu-kvm-spice links
    * install qemu-system-x86.modprobe
  - add debian/qemu-system-common.links for OVMF.fd link
* Remove kvm-img, kvm-nbd, kvm-ifup and kvm-ifdown symlinks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
From 56674d9155f939b950f5f7813cc3ede205560aad Mon Sep 17 00:00:00 2001
 
2
From: =?UTF-8?q?Juha=20Riihim=C3=A4ki?= <juha.riihimaki@nokia.com>
 
3
Date: Mon, 18 Feb 2013 16:58:24 +0000
 
4
Subject: [PATCH 08/70] omap_dma: add scatter gather list support
 
5
MIME-Version: 1.0
 
6
Content-Type: text/plain; charset=UTF-8
 
7
Content-Transfer-Encoding: 8bit
 
8
 
 
9
Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com>
 
10
---
 
11
 hw/dma/omap_dma.c | 411 +++++++++++++++++++++++++++++++++++-------------------
 
12
 1 file changed, 268 insertions(+), 143 deletions(-)
 
13
 
 
14
diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c
 
15
index 7d365bb..c3971a7 100644
 
16
--- a/hw/dma/omap_dma.c
 
17
+++ b/hw/dma/omap_dma.c
 
18
@@ -98,6 +98,12 @@ struct omap_dma_channel_s {
 
19
     int type;
 
20
     int suspend;
 
21
     int buf_disable;
 
22
+
 
23
+    struct omap_dma_desc_linked_list_s {
 
24
+        uint32_t ptr;
 
25
+        uint32_t next;
 
26
+        uint32_t number;
 
27
+    } sgl;
 
28
 };
 
29
 
 
30
 struct omap_dma_s {
 
31
@@ -132,7 +138,10 @@ struct omap_dma_s {
 
32
 #define SYNC            (1 << 6)
 
33
 #define END_PKT_INTR   (1 << 7)
 
34
 #define TRANS_ERR_INTR (1 << 8)
 
35
+#define SV_ERR_INTR     (1 << 10)
 
36
 #define MISALIGN_INTR  (1 << 11)
 
37
+#define END_DRAIN_INTR  (1 << 12)
 
38
+#define END_SBLOCK_INTR (1 << 14)
 
39
 
 
40
 static inline void omap_dma_interrupts_update(struct omap_dma_s *s)
 
41
 {
 
42
@@ -259,6 +268,100 @@ static void omap_dma_deactivate_channel(struct omap_dma_s *s,
 
43
     }
 
44
 }
 
45
 
 
46
+static void omap_dma4_write_ch(struct omap_dma_s *s,
 
47
+                               struct omap_dma_channel_s *ch,
 
48
+                               uint32_t offset, uint32_t value);
 
49
+
 
50
+static int omap_dma_sgl_next(struct omap_dma_s *s,
 
51
+                             struct omap_dma_channel_s *ch)
 
52
+{
 
53
+    if ((ch->sgl.next >> 2) == 0x3fffffff) {
 
54
+        ch->status |= END_SBLOCK_INTR;
 
55
+        return 0;
 
56
+    }
 
57
+    int type = (ch->sgl.ptr >> 4) & 7;      /* NEXT_DESCRIPTOR_TYPE */
 
58
+    int src_valid = (ch->sgl.ptr >> 2) & 3; /* SRC_VALID */
 
59
+    int dst_valid = ch->sgl.ptr & 3;        /* DEST_VALID */
 
60
+    if (type < 1 || type > 3) {
 
61
+        hw_error("%s: unknown descriptor type %d\n", __func__, type);
 
62
+    }
 
63
+    hwaddr addr = (hwaddr)ch->sgl.next;
 
64
+    ch->sgl.ptr &= ~0xff;
 
65
+    uint8_t data[4];
 
66
+    cpu_physical_memory_read(addr, data, 4);
 
67
+    uint32_t word = ldl_p(data);
 
68
+    ch->sgl.next = word & ~3;
 
69
+    ch->sgl.ptr |= (word & 1) << 7;     /* PAUSE_LINK_LIST */
 
70
+    cpu_physical_memory_read(addr + 4, data, 4);
 
71
+    word = ldl_p(data);
 
72
+    ch->sgl.ptr |= (word >> 25) & 0x70; /* NEXT_DESCRIPTOR_TYPE */
 
73
+    ch->sgl.ptr |= (word >> 26) & 3;    /* DEST_VALID */
 
74
+    ch->sgl.ptr |= (word >> 22) & 0x0c; /* SRC_VALID */
 
75
+    ch->sgl.number = word & 0xffffff;
 
76
+    if (type == 3) {
 
77
+        ch->interrupts &= ~0x20;               /* BLOCK_IE */
 
78
+        ch->interrupts |= (word >> 23) & 0x20; /* BLOCK_IE */
 
79
+    }
 
80
+    addr += 8;
 
81
+    switch (src_valid) {
 
82
+    case 0:
 
83
+        ch->addr[0] = ch->active_set.src;
 
84
+        break;
 
85
+    case 1:
 
86
+        cpu_physical_memory_read(addr, data, 4);
 
87
+        ch->addr[0] = ldl_p(data);
 
88
+        addr += 4;
 
89
+        break;
 
90
+    case 2:
 
91
+        break;
 
92
+    default:
 
93
+        hw_error("%s: unknown src addressing mode %d\n",
 
94
+                 __func__, src_valid);
 
95
+        break;
 
96
+    }
 
97
+    switch (dst_valid) {
 
98
+    case 0:
 
99
+        ch->addr[1] = ch->active_set.dest;
 
100
+        break;
 
101
+    case 1:
 
102
+        cpu_physical_memory_read(addr, data, 4);
 
103
+        ch->addr[1] = ldl_p(data);
 
104
+        addr += 4;
 
105
+        break;
 
106
+    case 2:
 
107
+        break;
 
108
+    default:
 
109
+        hw_error("%s: unknown dest addressing mode %d\n",
 
110
+                 __func__, dst_valid);
 
111
+        break;
 
112
+    }
 
113
+    if (type == 1 || type == 2) {
 
114
+        cpu_physical_memory_read(addr, data, 4);
 
115
+        word = ldl_p(data);
 
116
+        ch->interrupts = word >> 16;
 
117
+        ch->frames = word & 0xffff;
 
118
+        cpu_physical_memory_read(addr + 4, data, 4);
 
119
+        word = ldl_p(data);
 
120
+        ch->element_index[0] = (int16_t)(word >> 16);
 
121
+        ch->element_index[1] = (int16_t)(word & 0xffff);
 
122
+        cpu_physical_memory_read(addr + 8, data, 4);
 
123
+        ch->frame_index[1] = ldl_p(data);
 
124
+        cpu_physical_memory_read(addr + 12, data, 4);
 
125
+        ch->frame_index[0] = ldl_p(data);
 
126
+        if (type == 1) {
 
127
+            cpu_physical_memory_read(addr + 16, data, 4);
 
128
+            ch->color = ldl_p(data);
 
129
+            cpu_physical_memory_read(addr + 20, data, 4);
 
130
+            omap_dma4_write_ch(s, ch, 0x10, ldl_p(data)); /* CSDP */
 
131
+            cpu_physical_memory_read(addr + 24, data, 4);
 
132
+            omap_dma4_write_ch(s, ch, 0x04, ldl_p(data)); /* CLNK_CTRL */
 
133
+            cpu_physical_memory_read(addr + 28, data, 4);
 
134
+            omap_dma4_write_ch(s, ch, 0x00, ldl_p(data)); /* CCR */
 
135
+        }
 
136
+    }
 
137
+    return 1;
 
138
+}
 
139
+
 
140
 static void omap_dma_enable_channel(struct omap_dma_s *s,
 
141
                 struct omap_dma_channel_s *ch)
 
142
 {
 
143
@@ -366,6 +469,34 @@ static void omap_dma_process_request(struct omap_dma_s *s, int request)
 
144
         omap_dma_interrupts_update(s);
 
145
 }
 
146
 
 
147
+static void omap_dma_end_of_block(struct omap_dma_s *s,
 
148
+                                  struct omap_dma_channel_s *ch)
 
149
+{
 
150
+    if (ch->omap_3_1_compatible_disable) {
 
151
+        omap_dma_disable_channel(s, ch);
 
152
+        if (ch->link_enabled) {
 
153
+            omap_dma_enable_channel(s, &s->ch[ch->link_next_ch]);
 
154
+        }
 
155
+    } else {
 
156
+        int sgl_pause = (ch->sgl.ptr >> 7) & 1; /* PAUSE_LINK_LIST */
 
157
+        if (((ch->sgl.ptr >> 8) & 3) != 1 || /* TRANSFER_MODE != linked list */
 
158
+            !omap_dma_sgl_next(s, ch) ||     /* end of list */
 
159
+            sgl_pause) {
 
160
+            if (!ch->auto_init) {
 
161
+                omap_dma_disable_channel(s, ch);
 
162
+            } else if (ch->repeat || ch->end_prog) {
 
163
+                omap_dma_channel_load(ch);
 
164
+            } else {
 
165
+                ch->waiting_end_prog = 1;
 
166
+                omap_dma_deactivate_channel(s, ch);
 
167
+            }
 
168
+        }
 
169
+    }
 
170
+
 
171
+    if (ch->interrupts & END_BLOCK_INTR)
 
172
+        ch->status |= END_BLOCK_INTR;
 
173
+}
 
174
+
 
175
 static void omap_dma_transfer_generic(struct soc_dma_ch_s *dma)
 
176
 {
 
177
     uint8_t value[4];
 
178
@@ -458,25 +589,7 @@ static void omap_dma_transfer_generic(struct soc_dma_ch_s *dma)
 
179
             if (a->frame == a->frames) {
 
180
                 /* End of Block */
 
181
                 /* Disable the channel */
 
182
-
 
183
-                if (ch->omap_3_1_compatible_disable) {
 
184
-                    omap_dma_disable_channel(s, ch);
 
185
-                    if (ch->link_enabled)
 
186
-                        omap_dma_enable_channel(s,
 
187
-                                        &s->ch[ch->link_next_ch]);
 
188
-                } else {
 
189
-                    if (!ch->auto_init)
 
190
-                        omap_dma_disable_channel(s, ch);
 
191
-                    else if (ch->repeat || ch->end_prog)
 
192
-                        omap_dma_channel_load(ch);
 
193
-                    else {
 
194
-                        ch->waiting_end_prog = 1;
 
195
-                        omap_dma_deactivate_channel(s, ch);
 
196
-                    }
 
197
-                }
 
198
-
 
199
-                if (ch->interrupts & END_BLOCK_INTR)
 
200
-                    ch->status |= END_BLOCK_INTR;
 
201
+                omap_dma_end_of_block(s, ch);
 
202
             }
 
203
         }
 
204
     } while (status == ch->status && ch->active);
 
205
@@ -507,6 +620,11 @@ static void omap_dma_transfer_setup(struct soc_dma_ch_s *dma)
 
206
 
 
207
     a = &ch->active_set;
 
208
 
 
209
+    if (((ch->sgl.ptr >> 8) & 3) == 1 && /* TRANSFER_MODE == linked list */
 
210
+        a->frame >= a->frames) {
 
211
+        omap_dma_channel_load(ch);
 
212
+    }
 
213
+
 
214
     src_p = &s->mpu->port[ch->port[0]];
 
215
     dest_p = &s->mpu->port[ch->port[1]];
 
216
     if ((!ch->constant_fill && !src_p->addr_valid(s->mpu, a->src)) ||
 
217
@@ -626,24 +744,7 @@ static void omap_dma_transfer_setup(struct soc_dma_ch_s *dma)
 
218
         if (min_elems == elements[omap_dma_intr_block]) {
 
219
             /* End of Block */
 
220
             /* Disable the channel */
 
221
-
 
222
-            if (ch->omap_3_1_compatible_disable) {
 
223
-                omap_dma_disable_channel(s, ch);
 
224
-                if (ch->link_enabled)
 
225
-                    omap_dma_enable_channel(s, &s->ch[ch->link_next_ch]);
 
226
-            } else {
 
227
-                if (!ch->auto_init)
 
228
-                    omap_dma_disable_channel(s, ch);
 
229
-                else if (ch->repeat || ch->end_prog)
 
230
-                    omap_dma_channel_load(ch);
 
231
-                else {
 
232
-                    ch->waiting_end_prog = 1;
 
233
-                    omap_dma_deactivate_channel(s, ch);
 
234
-                }
 
235
-            }
 
236
-
 
237
-            if (ch->interrupts & END_BLOCK_INTR)
 
238
-                ch->status |= END_BLOCK_INTR;
 
239
+            omap_dma_end_of_block(s, ch);
 
240
         }
 
241
 
 
242
         /* Update packet number */
 
243
@@ -747,6 +848,9 @@ void omap_dma_reset(struct soc_dma_s *dma)
 
244
         s->ch[i].priority = 0;
 
245
         s->ch[i].interleave_disabled = 0;
 
246
         s->ch[i].type = 0;
 
247
+        s->ch[i].sgl.ptr = 0;
 
248
+        s->ch[i].sgl.next = 0xfffffffc;
 
249
+        s->ch[i].sgl.number = 0;
 
250
     }
 
251
 }
 
252
 
 
253
@@ -1531,6 +1635,7 @@ static void omap_dma_write(void *opaque, hwaddr addr,
 
254
     case 0x404 ... 0x4fe:
 
255
         if (s->model <= omap_dma_3_1)
 
256
             break;
 
257
+        /* fall through */
 
258
     case 0x400:
 
259
         /* Fall through. */
 
260
         if (omap_dma_sys_write(s, addr, value))
 
261
@@ -1699,9 +1804,9 @@ static void omap_dma_interrupts_4_update(struct omap_dma_s *s)
 
262
     uint32_t bmp, bit;
 
263
 
 
264
     for (bmp = 0, bit = 1; bit; ch ++, bit <<= 1)
 
265
-        if ((ch->status &= ch->interrupts)) {
 
266
+        if ((ch->status & ch->interrupts)) {
 
267
             bmp |= bit;
 
268
-            ch->cstatus |= ch->status;
 
269
+            ch->cstatus |= ch->status & ch->interrupts;
 
270
             ch->status = 0;
 
271
         }
 
272
     if ((s->irqstat[0] |= s->irqen[0] & bmp))
 
273
@@ -1868,96 +1973,36 @@ static uint64_t omap_dma4_read(void *opaque, hwaddr addr,
 
274
         return ch->color;
 
275
 
 
276
     case 0x50: /* DMA4_CDP */
 
277
-    case 0x54: /* DMA4_CNDP */
 
278
-    case 0x58: /* DMA4_CCDN */
 
279
-        return 0;
 
280
-
 
281
-    default:
 
282
-        OMAP_BAD_REG(0x80 + chnum * 0x60 + addr);
 
283
-        return 0;
 
284
-    }
 
285
-}
 
286
-
 
287
-static void omap_dma4_write(void *opaque, hwaddr addr,
 
288
-                            uint64_t value, unsigned size)
 
289
-{
 
290
-    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
 
291
-    int chnum, irqn = 0;
 
292
-    struct omap_dma_channel_s *ch;
 
293
-
 
294
-    if (size == 1) {
 
295
-        return omap_badwidth_write16(opaque, addr, value);
 
296
-    }
 
297
-
 
298
-    switch (addr) {
 
299
-    case 0x14: /* DMA4_IRQSTATUS_L3 */
 
300
-        irqn ++;
 
301
-        /* fall through */
 
302
-    case 0x10: /* DMA4_IRQSTATUS_L2 */
 
303
-        irqn ++;
 
304
-        /* fall through */
 
305
-    case 0x0c: /* DMA4_IRQSTATUS_L1 */
 
306
-        irqn ++;
 
307
-        /* fall through */
 
308
-    case 0x08: /* DMA4_IRQSTATUS_L0 */
 
309
-        s->irqstat[irqn] &= ~value;
 
310
-        if (!s->irqstat[irqn])
 
311
-            qemu_irq_lower(s->irq[irqn]);
 
312
-        return;
 
313
-
 
314
-    case 0x24: /* DMA4_IRQENABLE_L3 */
 
315
-        irqn ++;
 
316
-        /* fall through */
 
317
-    case 0x20: /* DMA4_IRQENABLE_L2 */
 
318
-        irqn ++;
 
319
-        /* fall through */
 
320
-    case 0x1c: /* DMA4_IRQENABLE_L1 */
 
321
-        irqn ++;
 
322
-        /* fall through */
 
323
-    case 0x18: /* DMA4_IRQENABLE_L0 */
 
324
-        s->irqen[irqn] = value;
 
325
-        return;
 
326
-
 
327
-    case 0x2c: /* DMA4_OCP_SYSCONFIG */
 
328
-        if (value & 2) { /* SOFTRESET */
 
329
-            if (!cpu_is_omap3630(s->mpu)) { /* N/A on 3630GP */
 
330
-                omap_dma_reset(s->dma);
 
331
-            }
 
332
+        if (cpu_is_omap3630(s->mpu)) {
 
333
+            return ch->sgl.ptr;
 
334
         }
 
335
-        s->ocp = value & 0x3321;
 
336
-        if (((s->ocp >> 12) & 3) == 3)                         /* MIDLEMODE */
 
337
-            fprintf(stderr, "%s: invalid DMA power mode\n", __FUNCTION__);
 
338
-        return;
 
339
-
 
340
-    case 0x78: /* DMA4_GCR */
 
341
-        s->gcr = value & 0x00ff00ff;
 
342
-       if ((value & 0xff) == 0x00)             /* MAX_CHANNEL_FIFO_DEPTH */
 
343
-            fprintf(stderr, "%s: wrong FIFO depth in GCR\n", __FUNCTION__);
 
344
-        return;
 
345
+        break;
 
346
 
 
347
-    case 0x80 ... 0xfff:
 
348
-        addr -= 0x80;
 
349
-        chnum = addr / 0x60;
 
350
-        ch = s->ch + chnum;
 
351
-        addr -= chnum * 0x60;
 
352
+    case 0x54: /* DMA4_CNDP */
 
353
+        if (cpu_is_omap3630(s->mpu)) {
 
354
+            return ch->sgl.next;
 
355
+        }
 
356
         break;
 
357
 
 
358
-    case 0x00: /* DMA4_REVISION */
 
359
-    case 0x28: /* DMA4_SYSSTATUS */
 
360
-    case 0x64: /* DMA4_CAPS_0 */
 
361
-    case 0x6c: /* DMA4_CAPS_2 */
 
362
-    case 0x70: /* DMA4_CAPS_3 */
 
363
-    case 0x74: /* DMA4_CAPS_4 */
 
364
-        OMAP_RO_REG(addr);
 
365
-        return;
 
366
+    case 0x58: /* DMA4_CCDN */
 
367
+        if (cpu_is_omap3630(s->mpu)) {
 
368
+            return ch->sgl.number;
 
369
+        }
 
370
+        break;
 
371
 
 
372
     default:
 
373
-        OMAP_BAD_REG(addr);
 
374
-        return;
 
375
+        break;
 
376
     }
 
377
 
 
378
-    /* Per-channel registers */
 
379
-    switch (addr) {
 
380
+    OMAP_BAD_REG(0x80 + chnum * 0x60 + addr);
 
381
+    return 0;
 
382
+}
 
383
+
 
384
+static void omap_dma4_write_ch(struct omap_dma_s *s,
 
385
+                               struct omap_dma_channel_s *ch,
 
386
+                               uint32_t offset, uint32_t value)
 
387
+{
 
388
+    switch (offset) {
 
389
     case 0x00: /* DMA4_CCR */
 
390
         ch->buf_disable = (value >> 25) & 1;
 
391
         ch->src_sync = (value >> 24) & 1;      /* XXX For CamDMA must be 1 */
 
392
@@ -1979,11 +2024,15 @@ static void omap_dma4_write(void *opaque, hwaddr addr,
 
393
         ch->sync = (value & 0x001f) | ((value >> 14) & 0x0060);
 
394
         /* XXX must be 0x01 for CamDMA */
 
395
 
 
396
-        if (value & 0x0080)
 
397
-            omap_dma_enable_channel(s, ch);
 
398
-        else
 
399
+        if (value & 0x0080) {
 
400
+            if (((ch->sgl.ptr >> 8) & 3) != 1 || /* TRANSFER_MODE */
 
401
+                !(ch->sgl.ptr & (1 << 10)) ||    /* FAST */
 
402
+                omap_dma_sgl_next(s, ch)) {
 
403
+                omap_dma_enable_channel(s, ch);
 
404
+            }
 
405
+        } else {
 
406
             omap_dma_disable_channel(s, ch);
 
407
-
 
408
+        }
 
409
         break;
 
410
 
 
411
     case 0x04: /* DMA4_CLNK_CTRL */
 
412
@@ -2068,41 +2117,117 @@ static void omap_dma4_write(void *opaque, hwaddr addr,
 
413
         ch->set_update = 1;
 
414
         break;
 
415
 
 
416
-    case 0x44: /* DMA4_COLOR */
 
417
-        /* XXX only in sDMA */
 
418
-        ch->color = value;
 
419
-        break;
 
420
-
 
421
     case 0x34: /* DMA4_CSAC */
 
422
     case 0x38: /* DMA4_CDAC */
 
423
     case 0x3c: /* DMA4_CCEN */
 
424
     case 0x40: /* DMA4_CCFN */
 
425
-        /* f.ex. linux kernel writes zeroes to these registers as well
 
426
-           when performing a DMA channel reset. let's just ignore the
 
427
-           writes instead of reporting "dummy" errors */
 
428
-        /*OMAP_RO_REG(0x80 + chnum * 0x60 + addr);*/
 
429
+        /* ignore */
 
430
+        break;
 
431
+
 
432
+    case 0x44: /* DMA4_COLOR */
 
433
+        /* XXX only in sDMA */
 
434
+        ch->color = value;
 
435
         break;
 
436
 
 
437
     case 0x50: /* DMA4_CDP */
 
438
         if (cpu_is_omap3630(s->mpu)) {
 
439
-            if ((value >> 8) & 3) { /* TRANSFER_MODE */
 
440
-                hw_error("%s: linked list transfer mode not supported",
 
441
-                         __FUNCTION__);
 
442
-            }
 
443
-        } else {
 
444
-            OMAP_BAD_REG(0x80 + chnum * 0x60 + addr);
 
445
+            ch->sgl.ptr = value & 0x7ff;
 
446
         }
 
447
         break;
 
448
 
 
449
     case 0x54: /* DMA4_CNDP */
 
450
+        if (cpu_is_omap3630(s->mpu)) {
 
451
+            ch->sgl.next = value & ~3;
 
452
+        }
 
453
+        break;
 
454
+
 
455
     case 0x58: /* DMA4_CCDN */
 
456
-        if (!cpu_is_omap3630(s->mpu)) {
 
457
-            OMAP_BAD_REG(0x80 + chnum * 0x60 + addr);
 
458
+        if (cpu_is_omap3630(s->mpu)) {
 
459
+            ch->sgl.number = value & 0xffff;
 
460
         }
 
461
         break;
 
462
 
 
463
     default:
 
464
-        OMAP_BAD_REG(0x80 + chnum * 0x60 + addr);
 
465
+        fprintf(stderr, "%s: unknown register 0x%x\n",
 
466
+                __func__, offset + 0x80);
 
467
+        break;
 
468
+    }
 
469
+}
 
470
+
 
471
+static void omap_dma4_write(void *opaque, hwaddr addr,
 
472
+                            uint64_t value, unsigned size)
 
473
+{
 
474
+    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
 
475
+    int chnum, irqn = 0;
 
476
+
 
477
+    if (size == 1) {
 
478
+        return omap_badwidth_write16(opaque, addr, value);
 
479
+    }
 
480
+
 
481
+    switch (addr) {
 
482
+    case 0x14: /* DMA4_IRQSTATUS_L3 */
 
483
+        irqn++;
 
484
+        /* fall through */
 
485
+    case 0x10: /* DMA4_IRQSTATUS_L2 */
 
486
+        irqn++;
 
487
+        /* fall through */
 
488
+    case 0x0c: /* DMA4_IRQSTATUS_L1 */
 
489
+        irqn++;
 
490
+        /* fall through */
 
491
+    case 0x08: /* DMA4_IRQSTATUS_L0 */
 
492
+        s->irqstat[irqn] &= ~value;
 
493
+        if (!s->irqstat[irqn]) {
 
494
+            qemu_irq_lower(s->irq[irqn]);
 
495
+        }
 
496
+        break;
 
497
+
 
498
+    case 0x24: /* DMA4_IRQENABLE_L3 */
 
499
+        irqn++;
 
500
+    case 0x20: /* DMA4_IRQENABLE_L2 */
 
501
+        irqn++;
 
502
+    case 0x1c: /* DMA4_IRQENABLE_L1 */
 
503
+        irqn++;
 
504
+    case 0x18: /* DMA4_IRQENABLE_L0 */
 
505
+        s->irqen[irqn] = value;
 
506
+        break;
 
507
+
 
508
+    case 0x2c: /* DMA4_OCP_SYSCONFIG */
 
509
+        if (value & 2) { /* SOFTRESET */
 
510
+            /* N/A on 3630GP?? */
 
511
+            omap_dma_reset(s->dma);
 
512
+        }
 
513
+        s->ocp = value & 0x3321;
 
514
+        if (((s->ocp >> 12) & 3) == 3) { /* MIDLEMODE */
 
515
+            fprintf(stderr, "%s: invalid DMA power mode\n", __func__);
 
516
+        }
 
517
+        break;
 
518
+
 
519
+    case 0x78: /* DMA4_GCR */
 
520
+        s->gcr = value & 0x00ff00ff;
 
521
+        if ((value & 0xff) == 0x00) { /* MAX_CHANNEL_FIFO_DEPTH */
 
522
+            fprintf(stderr, "%s: wrong FIFO depth in GCR\n", __func__);
 
523
+        }
 
524
+        break;
 
525
+
 
526
+    case 0x80 ... 0xfff:
 
527
+        addr -= 0x80;
 
528
+        chnum = addr / 0x60;
 
529
+        addr -= chnum * 0x60;
 
530
+        omap_dma4_write_ch(s, s->ch + chnum, (uint32_t)addr, value);
 
531
+        break;
 
532
+
 
533
+    case 0x00: /* DMA4_REVISION */
 
534
+    case 0x28: /* DMA4_SYSSTATUS */
 
535
+    case 0x64: /* DMA4_CAPS_0 */
 
536
+    case 0x6c: /* DMA4_CAPS_2 */
 
537
+    case 0x70: /* DMA4_CAPS_3 */
 
538
+    case 0x74: /* DMA4_CAPS_4 */
 
539
+        OMAP_RO_REG(addr);
 
540
+        break;
 
541
+
 
542
+    default:
 
543
+        OMAP_BAD_REG(addr);
 
544
+        break;
 
545
     }
 
546
 }
 
547
 
 
548
-- 
 
549
1.8.5.2
 
550