Revision a8303d18 hw/etraxfs_dma.c
b/hw/etraxfs_dma.c | ||
---|---|---|
267 | 267 |
target_phys_addr_t addr = channel_reg(ctrl, c, RW_SAVED_DATA); |
268 | 268 |
|
269 | 269 |
/* Load and decode. FIXME: handle endianness. */ |
270 |
D(printf("%s addr=%x\n", __func__, addr));
|
|
270 |
D(printf("%s ch=%d addr=%x\n", __func__, c, addr));
|
|
271 | 271 |
cpu_physical_memory_read (addr, |
272 | 272 |
(void *) &ctrl->channels[c].current_d, |
273 | 273 |
sizeof ctrl->channels[c].current_d); |
274 | 274 |
|
275 | 275 |
D(dump_d(c, &ctrl->channels[c].current_d)); |
276 | 276 |
ctrl->channels[c].regs[RW_DATA] = addr; |
277 |
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = |
|
278 |
(uint32_t)ctrl->channels[c].current_d.buf; |
|
277 |
} |
|
278 |
|
|
279 |
static void channel_store_c(struct fs_dma_ctrl *ctrl, int c) |
|
280 |
{ |
|
281 |
target_phys_addr_t addr = channel_reg(ctrl, c, RW_GROUP_DOWN); |
|
282 |
|
|
283 |
/* Encode and store. FIXME: handle endianness. */ |
|
284 |
D(printf("%s ch=%d addr=%x\n", __func__, c, addr)); |
|
285 |
D(dump_d(c, &ctrl->channels[c].current_d)); |
|
286 |
cpu_physical_memory_write (addr, |
|
287 |
(void *) &ctrl->channels[c].current_c, |
|
288 |
sizeof ctrl->channels[c].current_c); |
|
279 | 289 |
} |
280 | 290 |
|
281 | 291 |
static void channel_store_d(struct fs_dma_ctrl *ctrl, int c) |
282 | 292 |
{ |
283 | 293 |
target_phys_addr_t addr = channel_reg(ctrl, c, RW_SAVED_DATA); |
284 | 294 |
|
285 |
/* Load and decode. FIXME: handle endianness. */
|
|
286 |
D(printf("%s addr=%x\n", __func__, addr));
|
|
295 |
/* Encode and store. FIXME: handle endianness. */
|
|
296 |
D(printf("%s ch=%d addr=%x\n", __func__, c, addr));
|
|
287 | 297 |
cpu_physical_memory_write (addr, |
288 | 298 |
(void *) &ctrl->channels[c].current_d, |
289 | 299 |
sizeof ctrl->channels[c].current_d); |
... | ... | |
326 | 336 |
/* If the current descriptor cleared the eol flag and we had already |
327 | 337 |
reached eol state, do the continue. */ |
328 | 338 |
if (!ctrl->channels[c].current_d.eol && ctrl->channels[c].eol) { |
329 |
D(printf("continue %d ok %x\n", c,
|
|
339 |
D(printf("continue %d ok %p\n", c,
|
|
330 | 340 |
ctrl->channels[c].current_d.next)); |
331 | 341 |
ctrl->channels[c].regs[RW_SAVED_DATA] = |
332 | 342 |
(uint32_t) ctrl->channels[c].current_d.next; |
333 | 343 |
channel_load_d(ctrl, c); |
334 | 344 |
channel_start(ctrl, c); |
335 | 345 |
} |
346 |
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = |
|
347 |
(uint32_t) ctrl->channels[c].current_d.buf; |
|
336 | 348 |
} |
337 | 349 |
|
338 | 350 |
static void channel_stream_cmd(struct fs_dma_ctrl *ctrl, int c, uint32_t v) |
339 | 351 |
{ |
340 | 352 |
unsigned int cmd = v & ((1 << 10) - 1); |
341 | 353 |
|
342 |
D(printf("%s cmd=%x\n", __func__, cmd)); |
|
354 |
D(printf("%s ch=%d cmd=%x pc=%x\n", |
|
355 |
__func__, c, cmd, ctrl->env->pc)); |
|
343 | 356 |
if (cmd & regk_dma_load_d) { |
344 | 357 |
channel_load_d(ctrl, c); |
345 | 358 |
if (cmd & regk_dma_burst) |
... | ... | |
348 | 361 |
|
349 | 362 |
if (cmd & regk_dma_load_c) { |
350 | 363 |
channel_load_c(ctrl, c); |
364 |
channel_start(ctrl, c); |
|
351 | 365 |
} |
352 | 366 |
} |
353 | 367 |
|
... | ... | |
382 | 396 |
|
383 | 397 |
saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF); |
384 | 398 |
|
385 |
D(printf("buf=%x after=%x saved_data_buf=%x\n", |
|
399 |
D(fprintf(logfile, "ch=%d buf=%x after=%x saved_data_buf=%x\n", |
|
400 |
c, |
|
386 | 401 |
(uint32_t)ctrl->channels[c].current_d.buf, |
387 | 402 |
(uint32_t)ctrl->channels[c].current_d.after, |
388 | 403 |
saved_data_buf)); |
389 | 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, buf, len); |
|
418 |
else |
|
419 |
printf("WARNING: DMA ch%d dataloss, no attached client.\n", c); |
|
420 |
|
|
421 |
saved_data_buf += len; |
|
422 |
|
|
390 | 423 |
if (saved_data_buf == (uint32_t)ctrl->channels[c].current_d.after) { |
391 | 424 |
/* Done. Step to next. */ |
392 | 425 |
if (ctrl->channels[c].current_d.out_eop) { |
... | ... | |
403 | 436 |
if (ctrl->channels[c].current_d.eol) { |
404 | 437 |
D(printf("channel %d EOL\n", c)); |
405 | 438 |
ctrl->channels[c].eol = 1; |
439 |
|
|
440 |
/* Mark the context as disabled. */ |
|
441 |
ctrl->channels[c].current_c.dis = 1; |
|
442 |
channel_store_c(ctrl, c); |
|
443 |
|
|
406 | 444 |
channel_stop(ctrl, c); |
407 | 445 |
} else { |
408 | 446 |
ctrl->channels[c].regs[RW_SAVED_DATA] = |
409 | 447 |
(uint32_t) ctrl->channels[c].current_d.next; |
410 | 448 |
/* Load new descriptor. */ |
411 | 449 |
channel_load_d(ctrl, c); |
450 |
saved_data_buf = (uint32_t) |
|
451 |
ctrl->channels[c].current_d.buf; |
|
412 | 452 |
} |
413 | 453 |
|
414 | 454 |
channel_store_d(ctrl, c); |
455 |
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf; |
|
415 | 456 |
D(dump_d(c, &ctrl->channels[c].current_d)); |
416 |
return; |
|
417 | 457 |
} |
418 |
|
|
419 |
len = (uint32_t) ctrl->channels[c].current_d.after; |
|
420 |
len -= saved_data_buf; |
|
421 |
|
|
422 |
if (len > sizeof buf) |
|
423 |
len = sizeof buf; |
|
424 |
cpu_physical_memory_read (saved_data_buf, buf, len); |
|
425 |
|
|
426 |
D(printf("channel %d pushes %x %u bytes\n", c, |
|
427 |
saved_data_buf, len)); |
|
428 |
/* TODO: Push content. */ |
|
429 |
if (ctrl->channels[c].client->client.push) |
|
430 |
ctrl->channels[c].client->client.push( |
|
431 |
ctrl->channels[c].client->client.opaque, buf, len); |
|
432 |
else |
|
433 |
printf("WARNING: DMA ch%d dataloss, no attached client.\n", c); |
|
434 |
|
|
435 |
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] += len; |
|
458 |
ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf; |
|
436 | 459 |
} |
437 | 460 |
|
438 | 461 |
static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, |
... | ... | |
483 | 506 |
if (ctrl->channels[c].current_d.eol) { |
484 | 507 |
D(printf("channel %d EOL\n", c)); |
485 | 508 |
ctrl->channels[c].eol = 1; |
509 |
|
|
510 |
/* Mark the context as disabled. */ |
|
511 |
ctrl->channels[c].current_c.dis = 1; |
|
512 |
channel_store_c(ctrl, c); |
|
513 |
|
|
486 | 514 |
channel_stop(ctrl, c); |
487 | 515 |
} else { |
488 | 516 |
ctrl->channels[c].regs[RW_SAVED_DATA] = |
489 | 517 |
(uint32_t) ctrl->channels[c].current_d.next; |
490 | 518 |
/* Load new descriptor. */ |
491 | 519 |
channel_load_d(ctrl, c); |
492 |
saved_data_buf = |
|
493 |
ctrl->channels[c].regs[RW_SAVED_DATA_BUF];
|
|
520 |
saved_data_buf = (uint32_t)
|
|
521 |
ctrl->channels[c].current_d.buf;
|
|
494 | 522 |
} |
495 | 523 |
} |
496 | 524 |
|
... | ... | |
523 | 551 |
|
524 | 552 |
/* Make addr relative to this instances base. */ |
525 | 553 |
c = fs_channel(ctrl->base, addr); |
526 |
addr &= 0x1fff;
|
|
554 |
addr &= 0x1fff;
|
|
527 | 555 |
switch (addr) |
528 |
{
|
|
556 |
{
|
|
529 | 557 |
case RW_STAT: |
530 | 558 |
r = ctrl->channels[c].state & 7; |
531 | 559 |
r |= ctrl->channels[c].eol << 5; |
532 | 560 |
r |= ctrl->channels[c].stream_cmd_src << 8; |
533 | 561 |
break; |
534 | 562 |
|
535 |
default:
|
|
563 |
default:
|
|
536 | 564 |
r = ctrl->channels[c].regs[addr]; |
537 | 565 |
D(printf ("%s c=%d addr=%x pc=%x\n", |
538 |
__func__, c, addr, env->pc));
|
|
539 |
break;
|
|
540 |
}
|
|
566 |
__func__, c, addr, ctrl->env->pc));
|
|
567 |
break;
|
|
568 |
}
|
|
541 | 569 |
return r; |
542 | 570 |
} |
543 | 571 |
|
... | ... | |
560 | 588 |
c = fs_channel(ctrl->base, addr); |
561 | 589 |
addr &= 0x1fff; |
562 | 590 |
switch (addr) |
563 |
{
|
|
591 |
{
|
|
564 | 592 |
case RW_DATA: |
565 | 593 |
ctrl->channels[c].regs[addr] = value; |
566 | 594 |
break; |
... | ... | |
591 | 619 |
|
592 | 620 |
case RW_STREAM_CMD: |
593 | 621 |
ctrl->channels[c].regs[addr] = value; |
622 |
D(printf("stream_cmd ch=%d pc=%x\n", |
|
623 |
c, ctrl->env->pc)); |
|
594 | 624 |
channel_stream_cmd(ctrl, c, value); |
595 | 625 |
break; |
596 | 626 |
|
597 |
default:
|
|
598 |
D(printf ("%s c=%d %x %x pc=%x\n",
|
|
599 |
__func__, c, addr, value, env->pc)); |
|
600 |
break;
|
|
627 |
default:
|
|
628 |
D(printf ("%s c=%d %x %x pc=%x\n",
|
|
629 |
__func__, c, addr, value, ctrl->env->pc));
|
|
630 |
break;
|
|
601 | 631 |
} |
602 | 632 |
} |
603 | 633 |
|
Also available in: Unified diff