Commit c01c07bbf971296be84b72341ede37b1f700022e
1 parent
70ea255d
ETRAX: Process out channels immediately when the channel is started.
* Process out channels immediately when the channel is started. * Context descriptor load does not start a channel. * Store updated descriptors after processing them regardless of eol state. * Correct control-register area size. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6208 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
31 additions
and
20 deletions
hw/etraxfs_dma.c
... | ... | @@ -31,21 +31,21 @@ |
31 | 31 | |
32 | 32 | #define D(x) |
33 | 33 | |
34 | -#define RW_DATA 0x0 | |
35 | -#define RW_SAVED_DATA 0x58 | |
36 | -#define RW_SAVED_DATA_BUF 0x5c | |
37 | -#define RW_GROUP 0x60 | |
38 | -#define RW_GROUP_DOWN 0x7c | |
39 | -#define RW_CMD 0x80 | |
40 | -#define RW_CFG 0x84 | |
41 | -#define RW_STAT 0x88 | |
42 | -#define RW_INTR_MASK 0x8c | |
43 | -#define RW_ACK_INTR 0x90 | |
44 | -#define R_INTR 0x94 | |
45 | -#define R_MASKED_INTR 0x98 | |
46 | -#define RW_STREAM_CMD 0x9c | |
47 | - | |
48 | -#define DMA_REG_MAX 0x100 | |
34 | +#define RW_DATA (0x0 / 4) | |
35 | +#define RW_SAVED_DATA (0x58 / 4) | |
36 | +#define RW_SAVED_DATA_BUF (0x5c / 4) | |
37 | +#define RW_GROUP (0x60 / 4) | |
38 | +#define RW_GROUP_DOWN (0x7c / 4) | |
39 | +#define RW_CMD (0x80 / 4) | |
40 | +#define RW_CFG (0x84 / 4) | |
41 | +#define RW_STAT (0x88 / 4) | |
42 | +#define RW_INTR_MASK (0x8c / 4) | |
43 | +#define RW_ACK_INTR (0x90 / 4) | |
44 | +#define R_INTR (0x94 / 4) | |
45 | +#define R_MASKED_INTR (0x98 / 4) | |
46 | +#define RW_STREAM_CMD (0x9c / 4) | |
47 | + | |
48 | +#define DMA_REG_MAX (0x100 / 4) | |
49 | 49 | |
50 | 50 | /* descriptors */ |
51 | 51 | |
... | ... | @@ -194,6 +194,9 @@ struct fs_dma_ctrl |
194 | 194 | QEMUBH *bh; |
195 | 195 | }; |
196 | 196 | |
197 | +static void DMA_run(void *opaque); | |
198 | +static int channel_out_run(struct fs_dma_ctrl *ctrl, int c); | |
199 | + | |
197 | 200 | static inline uint32_t channel_reg(struct fs_dma_ctrl *ctrl, int c, int reg) |
198 | 201 | { |
199 | 202 | return ctrl->channels[c].regs[reg]; |
... | ... | @@ -314,6 +317,8 @@ static inline void channel_start(struct fs_dma_ctrl *ctrl, int c) |
314 | 317 | { |
315 | 318 | ctrl->channels[c].eol = 0; |
316 | 319 | ctrl->channels[c].state = RUNNING; |
320 | + if (!ctrl->channels[c].input) | |
321 | + channel_out_run(ctrl, c); | |
317 | 322 | } else |
318 | 323 | printf("WARNING: starting DMA ch %d with no client\n", c); |
319 | 324 | |
... | ... | @@ -347,6 +352,9 @@ static void channel_continue(struct fs_dma_ctrl *ctrl, int c) |
347 | 352 | ctrl->channels[c].regs[RW_SAVED_DATA] = |
348 | 353 | (uint32_t)(unsigned long)ctrl->channels[c].current_d.next; |
349 | 354 | channel_load_d(ctrl, c); |
355 | + ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = | |
356 | + (uint32_t)(unsigned long)ctrl->channels[c].current_d.buf; | |
357 | + | |
350 | 358 | channel_start(ctrl, c); |
351 | 359 | } |
352 | 360 | ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = |
... | ... | @@ -367,7 +375,6 @@ static void channel_stream_cmd(struct fs_dma_ctrl *ctrl, int c, uint32_t v) |
367 | 375 | |
368 | 376 | if (cmd & regk_dma_load_c) { |
369 | 377 | channel_load_c(ctrl, c); |
370 | - channel_start(ctrl, c); | |
371 | 378 | } |
372 | 379 | } |
373 | 380 | |
... | ... | @@ -401,14 +408,14 @@ static int channel_out_run(struct fs_dma_ctrl *ctrl, int c) |
401 | 408 | return 0; |
402 | 409 | |
403 | 410 | do { |
404 | - saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF); | |
405 | - | |
406 | 411 | D(printf("ch=%d buf=%x after=%x saved_data_buf=%x\n", |
407 | 412 | c, |
408 | 413 | (uint32_t)ctrl->channels[c].current_d.buf, |
409 | 414 | (uint32_t)ctrl->channels[c].current_d.after, |
410 | 415 | saved_data_buf)); |
411 | 416 | |
417 | + channel_load_d(ctrl, c); | |
418 | + saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF); | |
412 | 419 | len = (uint32_t)(unsigned long) |
413 | 420 | ctrl->channels[c].current_d.after; |
414 | 421 | len -= saved_data_buf; |
... | ... | @@ -440,10 +447,12 @@ static int channel_out_run(struct fs_dma_ctrl *ctrl, int c) |
440 | 447 | if (ctrl->channels[c].current_d.intr) { |
441 | 448 | /* TODO: signal eop to the client. */ |
442 | 449 | /* data intr. */ |
443 | - D(printf("signal intr\n")); | |
450 | + D(printf("signal intr %d eol=%d\n", | |
451 | + len, ctrl->channels[c].current_d.eol)); | |
444 | 452 | ctrl->channels[c].regs[R_INTR] |= (1 << 2); |
445 | 453 | channel_update_irq(ctrl, c); |
446 | 454 | } |
455 | + channel_store_d(ctrl, c); | |
447 | 456 | if (ctrl->channels[c].current_d.eol) { |
448 | 457 | D(printf("channel %d EOL\n", c)); |
449 | 458 | ctrl->channels[c].eol = 1; |
... | ... | @@ -463,7 +472,6 @@ static int channel_out_run(struct fs_dma_ctrl *ctrl, int c) |
463 | 472 | ctrl->channels[c].current_d.buf; |
464 | 473 | } |
465 | 474 | |
466 | - channel_store_d(ctrl, c); | |
467 | 475 | ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = |
468 | 476 | saved_data_buf; |
469 | 477 | D(dump_d(c, &ctrl->channels[c].current_d)); |
... | ... | @@ -482,6 +490,7 @@ static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, |
482 | 490 | if (ctrl->channels[c].eol == 1) |
483 | 491 | return 0; |
484 | 492 | |
493 | + channel_load_d(ctrl, c); | |
485 | 494 | saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF); |
486 | 495 | len = (uint32_t)(unsigned long)ctrl->channels[c].current_d.after; |
487 | 496 | len -= saved_data_buf; |
... | ... | @@ -572,6 +581,7 @@ dma_readl (void *opaque, target_phys_addr_t addr) |
572 | 581 | /* Make addr relative to this channel and bounded to nr regs. */ |
573 | 582 | c = fs_channel(addr); |
574 | 583 | addr &= 0xff; |
584 | + addr >>= 2; | |
575 | 585 | switch (addr) |
576 | 586 | { |
577 | 587 | case RW_STAT: |
... | ... | @@ -618,6 +628,7 @@ dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
618 | 628 | /* Make addr relative to this channel and bounded to nr regs. */ |
619 | 629 | c = fs_channel(addr); |
620 | 630 | addr &= 0xff; |
631 | + addr >>= 2; | |
621 | 632 | switch (addr) |
622 | 633 | { |
623 | 634 | case RW_DATA: | ... | ... |