Commit c968ef8df5052100683a4bb375078e46d96203a7

Authored by edgar_igl
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 }