Commit c968ef8df5052100683a4bb375078e46d96203a7
1 parent
31c18d87
ETRAX-FS: Process outgoing DMA channels until EOL.
For outgoing DMA channels, keep processing descriptors until hitting end of list. Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5553 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
69 additions
and
67 deletions
hw/etraxfs_dma.c
... | ... | @@ -393,72 +393,74 @@ static void channel_out_run(struct fs_dma_ctrl *ctrl, int c) |
393 | 393 | uint32_t saved_data_buf; |
394 | 394 | unsigned char buf[2 * 1024]; |
395 | 395 | |
396 | - if (ctrl->channels[c].eol == 1) | |
397 | - return; | |
398 | - | |
399 | - saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF); | |
400 | - | |
401 | - D(printf("ch=%d buf=%x after=%x saved_data_buf=%x\n", | |
402 | - c, | |
403 | - (uint32_t)ctrl->channels[c].current_d.buf, | |
404 | - (uint32_t)ctrl->channels[c].current_d.after, | |
405 | - saved_data_buf)); | |
406 | - | |
407 | - len = (uint32_t)(unsigned long) ctrl->channels[c].current_d.after; | |
408 | - len -= saved_data_buf; | |
409 | - | |
410 | - if (len > sizeof buf) | |
411 | - len = sizeof buf; | |
412 | - cpu_physical_memory_read (saved_data_buf, buf, len); | |
413 | - | |
414 | - D(printf("channel %d pushes %x %u bytes\n", c, | |
415 | - saved_data_buf, len)); | |
416 | - | |
417 | - if (ctrl->channels[c].client->client.push) | |
418 | - ctrl->channels[c].client->client.push( | |
419 | - ctrl->channels[c].client->client.opaque, buf, len); | |
420 | - else | |
421 | - printf("WARNING: DMA ch%d dataloss, no attached client.\n", c); | |
422 | - | |
423 | - saved_data_buf += len; | |
424 | - | |
425 | - if (saved_data_buf == | |
426 | - (uint32_t)(unsigned long)ctrl->channels[c].current_d.after) { | |
427 | - /* Done. Step to next. */ | |
428 | - if (ctrl->channels[c].current_d.out_eop) { | |
429 | - /* TODO: signal eop to the client. */ | |
430 | - D(printf("signal eop\n")); | |
396 | + while (ctrl->channels[c].eol != 1) { | |
397 | + saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF); | |
398 | + | |
399 | + D(printf("ch=%d buf=%x after=%x saved_data_buf=%x\n", | |
400 | + c, | |
401 | + (uint32_t)ctrl->channels[c].current_d.buf, | |
402 | + (uint32_t)ctrl->channels[c].current_d.after, | |
403 | + saved_data_buf)); | |
404 | + | |
405 | + len = (uint32_t)ctrl->channels[c].current_d.after; | |
406 | + len -= saved_data_buf; | |
407 | + | |
408 | + if (len > sizeof buf) | |
409 | + len = sizeof buf; | |
410 | + cpu_physical_memory_read (saved_data_buf, buf, len); | |
411 | + | |
412 | + D(printf("channel %d pushes %x %u bytes\n", c, | |
413 | + saved_data_buf, len)); | |
414 | + | |
415 | + if (ctrl->channels[c].client->client.push) | |
416 | + ctrl->channels[c].client->client.push( | |
417 | + ctrl->channels[c].client->client.opaque, | |
418 | + buf, len); | |
419 | + else | |
420 | + printf("WARNING: DMA ch%d dataloss," | |
421 | + " no attached client.\n", c); | |
422 | + | |
423 | + saved_data_buf += len; | |
424 | + | |
425 | + if (saved_data_buf == | |
426 | + (uint32_t)ctrl->channels[c].current_d.after) { | |
427 | + /* Done. Step to next. */ | |
428 | + if (ctrl->channels[c].current_d.out_eop) { | |
429 | + /* TODO: signal eop to the client. */ | |
430 | + D(printf("signal eop\n")); | |
431 | + } | |
432 | + if (ctrl->channels[c].current_d.intr) { | |
433 | + /* TODO: signal eop to the client. */ | |
434 | + /* data intr. */ | |
435 | + D(printf("signal intr\n")); | |
436 | + ctrl->channels[c].regs[R_INTR] |= (1 << 2); | |
437 | + channel_update_irq(ctrl, c); | |
438 | + } | |
439 | + if (ctrl->channels[c].current_d.eol) { | |
440 | + D(printf("channel %d EOL\n", c)); | |
441 | + ctrl->channels[c].eol = 1; | |
442 | + | |
443 | + /* Mark the context as disabled. */ | |
444 | + ctrl->channels[c].current_c.dis = 1; | |
445 | + channel_store_c(ctrl, c); | |
446 | + | |
447 | + channel_stop(ctrl, c); | |
448 | + } else { | |
449 | + ctrl->channels[c].regs[RW_SAVED_DATA] = | |
450 | + (uint32_t)ctrl->channels[c].current_d.next; | |
451 | + /* Load new descriptor. */ | |
452 | + channel_load_d(ctrl, c); | |
453 | + saved_data_buf = (uint32_t)(unsigned long) | |
454 | + ctrl->channels[c].current_d.buf; | |
455 | + } | |
456 | + | |
457 | + channel_store_d(ctrl, c); | |
458 | + ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = | |
459 | + saved_data_buf; | |
460 | + D(dump_d(c, &ctrl->channels[c].current_d)); | |
431 | 461 | } |
432 | - if (ctrl->channels[c].current_d.intr) { | |
433 | - /* TODO: signal eop to the client. */ | |
434 | - /* data intr. */ | |
435 | - D(printf("signal intr\n")); | |
436 | - ctrl->channels[c].regs[R_INTR] |= (1 << 2); | |
437 | - channel_update_irq(ctrl, c); | |
438 | - } | |
439 | - if (ctrl->channels[c].current_d.eol) { | |
440 | - D(printf("channel %d EOL\n", c)); | |
441 | - ctrl->channels[c].eol = 1; | |
442 | - | |
443 | - /* Mark the context as disabled. */ | |
444 | - ctrl->channels[c].current_c.dis = 1; | |
445 | - channel_store_c(ctrl, c); | |
446 | - | |
447 | - channel_stop(ctrl, c); | |
448 | - } else { | |
449 | - ctrl->channels[c].regs[RW_SAVED_DATA] = | |
450 | - (uint32_t)(unsigned long) ctrl->channels[c].current_d.next; | |
451 | - /* Load new descriptor. */ | |
452 | - channel_load_d(ctrl, c); | |
453 | - saved_data_buf = (uint32_t)(unsigned long) | |
454 | - ctrl->channels[c].current_d.buf; | |
455 | - } | |
456 | - | |
457 | - channel_store_d(ctrl, c); | |
458 | 462 | ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf; |
459 | - D(dump_d(c, &ctrl->channels[c].current_d)); | |
460 | 463 | } |
461 | - ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf; | |
462 | 464 | } |
463 | 465 | |
464 | 466 | static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, |
... | ... | @@ -471,7 +473,7 @@ static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, |
471 | 473 | return 0; |
472 | 474 | |
473 | 475 | saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF); |
474 | - len = (uint32_t)(unsigned long) ctrl->channels[c].current_d.after; | |
476 | + len = (uint32_t)ctrl->channels[c].current_d.after; | |
475 | 477 | len -= saved_data_buf; |
476 | 478 | |
477 | 479 | if (len > buflen) |
... | ... | @@ -481,7 +483,7 @@ static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, |
481 | 483 | saved_data_buf += len; |
482 | 484 | |
483 | 485 | if (saved_data_buf == |
484 | - (uint32_t)(unsigned long)ctrl->channels[c].current_d.after | |
486 | + (uint32_t)ctrl->channels[c].current_d.after | |
485 | 487 | || eop) { |
486 | 488 | uint32_t r_intr = ctrl->channels[c].regs[R_INTR]; |
487 | 489 | |
... | ... | @@ -518,10 +520,10 @@ static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, |
518 | 520 | channel_stop(ctrl, c); |
519 | 521 | } else { |
520 | 522 | ctrl->channels[c].regs[RW_SAVED_DATA] = |
521 | - (uint32_t)(unsigned long) ctrl->channels[c].current_d.next; | |
523 | + (uint32_t)ctrl->channels[c].current_d.next; | |
522 | 524 | /* Load new descriptor. */ |
523 | 525 | channel_load_d(ctrl, c); |
524 | - saved_data_buf = (uint32_t)(unsigned long) | |
526 | + saved_data_buf = (uint32_t) | |
525 | 527 | ctrl->channels[c].current_d.buf; |
526 | 528 | } |
527 | 529 | } | ... | ... |