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,72 +393,74 @@ static void channel_out_run(struct fs_dma_ctrl *ctrl, int c) | ||
| 393 | uint32_t saved_data_buf; | 393 | uint32_t saved_data_buf; |
| 394 | unsigned char buf[2 * 1024]; | 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 | ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf; | 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 | static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, | 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,7 +473,7 @@ static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, | ||
| 471 | return 0; | 473 | return 0; |
| 472 | 474 | ||
| 473 | saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF); | 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 | len -= saved_data_buf; | 477 | len -= saved_data_buf; |
| 476 | 478 | ||
| 477 | if (len > buflen) | 479 | if (len > buflen) |
| @@ -481,7 +483,7 @@ static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, | @@ -481,7 +483,7 @@ static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, | ||
| 481 | saved_data_buf += len; | 483 | saved_data_buf += len; |
| 482 | 484 | ||
| 483 | if (saved_data_buf == | 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 | || eop) { | 487 | || eop) { |
| 486 | uint32_t r_intr = ctrl->channels[c].regs[R_INTR]; | 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,10 +520,10 @@ static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, | ||
| 518 | channel_stop(ctrl, c); | 520 | channel_stop(ctrl, c); |
| 519 | } else { | 521 | } else { |
| 520 | ctrl->channels[c].regs[RW_SAVED_DATA] = | 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 | /* Load new descriptor. */ | 524 | /* Load new descriptor. */ |
| 523 | channel_load_d(ctrl, c); | 525 | channel_load_d(ctrl, c); |
| 524 | - saved_data_buf = (uint32_t)(unsigned long) | 526 | + saved_data_buf = (uint32_t) |
| 525 | ctrl->channels[c].current_d.buf; | 527 | ctrl->channels[c].current_d.buf; |
| 526 | } | 528 | } |
| 527 | } | 529 | } |