32 |
32 |
#include "usb.h"
|
33 |
33 |
#include "pci.h"
|
34 |
34 |
#include "pxa.h"
|
|
35 |
#include "devices.h"
|
35 |
36 |
|
36 |
37 |
//#define DEBUG_OHCI
|
37 |
38 |
/* Dump packet contents. */
|
... | ... | |
60 |
61 |
|
61 |
62 |
enum ohci_type {
|
62 |
63 |
OHCI_TYPE_PCI,
|
63 |
|
OHCI_TYPE_PXA
|
|
64 |
OHCI_TYPE_PXA,
|
|
65 |
OHCI_TYPE_SM501,
|
64 |
66 |
};
|
65 |
67 |
|
66 |
68 |
typedef struct {
|
... | ... | |
108 |
110 |
uint32_t hreset;
|
109 |
111 |
uint32_t htest;
|
110 |
112 |
|
|
113 |
/* SM501 local memory offset */
|
|
114 |
target_phys_addr_t localmem_base;
|
|
115 |
|
111 |
116 |
/* Active packets. */
|
112 |
117 |
uint32_t old_ctl;
|
113 |
118 |
USBPacket usb_packet;
|
... | ... | |
425 |
430 |
}
|
426 |
431 |
|
427 |
432 |
/* Get an array of dwords from main memory */
|
428 |
|
static inline int get_dwords(uint32_t addr, uint32_t *buf, int num)
|
|
433 |
static inline int get_dwords(OHCIState *ohci,
|
|
434 |
uint32_t addr, uint32_t *buf, int num)
|
429 |
435 |
{
|
430 |
436 |
int i;
|
431 |
437 |
|
|
438 |
addr += ohci->localmem_base;
|
|
439 |
|
432 |
440 |
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
|
433 |
441 |
cpu_physical_memory_rw(addr, (uint8_t *)buf, sizeof(*buf), 0);
|
434 |
442 |
*buf = le32_to_cpu(*buf);
|
... | ... | |
438 |
446 |
}
|
439 |
447 |
|
440 |
448 |
/* Put an array of dwords in to main memory */
|
441 |
|
static inline int put_dwords(uint32_t addr, uint32_t *buf, int num)
|
|
449 |
static inline int put_dwords(OHCIState *ohci,
|
|
450 |
uint32_t addr, uint32_t *buf, int num)
|
442 |
451 |
{
|
443 |
452 |
int i;
|
444 |
453 |
|
|
454 |
addr += ohci->localmem_base;
|
|
455 |
|
445 |
456 |
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
|
446 |
457 |
uint32_t tmp = cpu_to_le32(*buf);
|
447 |
458 |
cpu_physical_memory_rw(addr, (uint8_t *)&tmp, sizeof(tmp), 1);
|
... | ... | |
451 |
462 |
}
|
452 |
463 |
|
453 |
464 |
/* Get an array of words from main memory */
|
454 |
|
static inline int get_words(uint32_t addr, uint16_t *buf, int num)
|
|
465 |
static inline int get_words(OHCIState *ohci,
|
|
466 |
uint32_t addr, uint16_t *buf, int num)
|
455 |
467 |
{
|
456 |
468 |
int i;
|
457 |
469 |
|
|
470 |
addr += ohci->localmem_base;
|
|
471 |
|
458 |
472 |
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
|
459 |
473 |
cpu_physical_memory_rw(addr, (uint8_t *)buf, sizeof(*buf), 0);
|
460 |
474 |
*buf = le16_to_cpu(*buf);
|
... | ... | |
464 |
478 |
}
|
465 |
479 |
|
466 |
480 |
/* Put an array of words in to main memory */
|
467 |
|
static inline int put_words(uint32_t addr, uint16_t *buf, int num)
|
|
481 |
static inline int put_words(OHCIState *ohci,
|
|
482 |
uint32_t addr, uint16_t *buf, int num)
|
468 |
483 |
{
|
469 |
484 |
int i;
|
470 |
485 |
|
|
486 |
addr += ohci->localmem_base;
|
|
487 |
|
471 |
488 |
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
|
472 |
489 |
uint16_t tmp = cpu_to_le16(*buf);
|
473 |
490 |
cpu_physical_memory_rw(addr, (uint8_t *)&tmp, sizeof(tmp), 1);
|
... | ... | |
476 |
493 |
return 1;
|
477 |
494 |
}
|
478 |
495 |
|
479 |
|
static inline int ohci_read_ed(uint32_t addr, struct ohci_ed *ed)
|
|
496 |
static inline int ohci_read_ed(OHCIState *ohci,
|
|
497 |
uint32_t addr, struct ohci_ed *ed)
|
480 |
498 |
{
|
481 |
|
return get_dwords(addr, (uint32_t *)ed, sizeof(*ed) >> 2);
|
|
499 |
return get_dwords(ohci, addr, (uint32_t *)ed, sizeof(*ed) >> 2);
|
482 |
500 |
}
|
483 |
501 |
|
484 |
|
static inline int ohci_read_td(uint32_t addr, struct ohci_td *td)
|
|
502 |
static inline int ohci_read_td(OHCIState *ohci,
|
|
503 |
uint32_t addr, struct ohci_td *td)
|
485 |
504 |
{
|
486 |
|
return get_dwords(addr, (uint32_t *)td, sizeof(*td) >> 2);
|
|
505 |
return get_dwords(ohci, addr, (uint32_t *)td, sizeof(*td) >> 2);
|
487 |
506 |
}
|
488 |
507 |
|
489 |
|
static inline int ohci_read_iso_td(uint32_t addr, struct ohci_iso_td *td)
|
|
508 |
static inline int ohci_read_iso_td(OHCIState *ohci,
|
|
509 |
uint32_t addr, struct ohci_iso_td *td)
|
490 |
510 |
{
|
491 |
|
return (get_dwords(addr, (uint32_t *)td, 4) &&
|
492 |
|
get_words(addr + 16, td->offset, 8));
|
|
511 |
return (get_dwords(ohci, addr, (uint32_t *)td, 4) &&
|
|
512 |
get_words(ohci, addr + 16, td->offset, 8));
|
493 |
513 |
}
|
494 |
514 |
|
495 |
|
static inline int ohci_put_ed(uint32_t addr, struct ohci_ed *ed)
|
|
515 |
static inline int ohci_read_hcca(OHCIState *ohci,
|
|
516 |
uint32_t addr, struct ohci_hcca *hcca)
|
496 |
517 |
{
|
497 |
|
return put_dwords(addr, (uint32_t *)ed, sizeof(*ed) >> 2);
|
|
518 |
cpu_physical_memory_rw(addr + ohci->localmem_base,
|
|
519 |
(uint8_t *)hcca, sizeof(*hcca), 0);
|
|
520 |
return 1;
|
498 |
521 |
}
|
499 |
522 |
|
500 |
|
static inline int ohci_put_td(uint32_t addr, struct ohci_td *td)
|
|
523 |
static inline int ohci_put_ed(OHCIState *ohci,
|
|
524 |
uint32_t addr, struct ohci_ed *ed)
|
501 |
525 |
{
|
502 |
|
return put_dwords(addr, (uint32_t *)td, sizeof(*td) >> 2);
|
|
526 |
return put_dwords(ohci, addr, (uint32_t *)ed, sizeof(*ed) >> 2);
|
503 |
527 |
}
|
504 |
528 |
|
505 |
|
static inline int ohci_put_iso_td(uint32_t addr, struct ohci_iso_td *td)
|
|
529 |
static inline int ohci_put_td(OHCIState *ohci,
|
|
530 |
uint32_t addr, struct ohci_td *td)
|
506 |
531 |
{
|
507 |
|
return (put_dwords(addr, (uint32_t *)td, 4) &&
|
508 |
|
put_words(addr + 16, td->offset, 8));
|
|
532 |
return put_dwords(ohci, addr, (uint32_t *)td, sizeof(*td) >> 2);
|
|
533 |
}
|
|
534 |
|
|
535 |
static inline int ohci_put_iso_td(OHCIState *ohci,
|
|
536 |
uint32_t addr, struct ohci_iso_td *td)
|
|
537 |
{
|
|
538 |
return (put_dwords(ohci, addr, (uint32_t *)td, 4) &&
|
|
539 |
put_words(ohci, addr + 16, td->offset, 8));
|
|
540 |
}
|
|
541 |
|
|
542 |
static inline int ohci_put_hcca(OHCIState *ohci,
|
|
543 |
uint32_t addr, struct ohci_hcca *hcca)
|
|
544 |
{
|
|
545 |
cpu_physical_memory_rw(addr + ohci->localmem_base,
|
|
546 |
(uint8_t *)hcca, sizeof(*hcca), 1);
|
|
547 |
return 1;
|
509 |
548 |
}
|
510 |
549 |
|
511 |
550 |
/* Read/Write the contents of a TD from/to main memory. */
|
512 |
|
static void ohci_copy_td(struct ohci_td *td, uint8_t *buf, int len, int write)
|
|
551 |
static void ohci_copy_td(OHCIState *ohci, struct ohci_td *td,
|
|
552 |
uint8_t *buf, int len, int write)
|
513 |
553 |
{
|
514 |
554 |
uint32_t ptr;
|
515 |
555 |
uint32_t n;
|
... | ... | |
518 |
558 |
n = 0x1000 - (ptr & 0xfff);
|
519 |
559 |
if (n > len)
|
520 |
560 |
n = len;
|
521 |
|
cpu_physical_memory_rw(ptr, buf, n, write);
|
|
561 |
cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write);
|
522 |
562 |
if (n == len)
|
523 |
563 |
return;
|
524 |
564 |
ptr = td->be & ~0xfffu;
|
525 |
565 |
buf += n;
|
526 |
|
cpu_physical_memory_rw(ptr, buf, len - n, write);
|
|
566 |
cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write);
|
527 |
567 |
}
|
528 |
568 |
|
529 |
569 |
/* Read/Write the contents of an ISO TD from/to main memory. */
|
530 |
|
static void ohci_copy_iso_td(uint32_t start_addr, uint32_t end_addr,
|
|
570 |
static void ohci_copy_iso_td(OHCIState *ohci,
|
|
571 |
uint32_t start_addr, uint32_t end_addr,
|
531 |
572 |
uint8_t *buf, int len, int write)
|
532 |
573 |
{
|
533 |
574 |
uint32_t ptr;
|
... | ... | |
537 |
578 |
n = 0x1000 - (ptr & 0xfff);
|
538 |
579 |
if (n > len)
|
539 |
580 |
n = len;
|
540 |
|
cpu_physical_memory_rw(ptr, buf, n, write);
|
|
581 |
cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write);
|
541 |
582 |
if (n == len)
|
542 |
583 |
return;
|
543 |
584 |
ptr = end_addr & ~0xfffu;
|
544 |
585 |
buf += n;
|
545 |
|
cpu_physical_memory_rw(ptr, buf, len - n, write);
|
|
586 |
cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write);
|
546 |
587 |
}
|
547 |
588 |
|
548 |
589 |
static void ohci_process_lists(OHCIState *ohci, int completion);
|
... | ... | |
579 |
620 |
|
580 |
621 |
addr = ed->head & OHCI_DPTR_MASK;
|
581 |
622 |
|
582 |
|
if (!ohci_read_iso_td(addr, &iso_td)) {
|
|
623 |
if (!ohci_read_iso_td(ohci, addr, &iso_td)) {
|
583 |
624 |
printf("usb-ohci: ISO_TD read error at %x\n", addr);
|
584 |
625 |
return 0;
|
585 |
626 |
}
|
... | ... | |
621 |
662 |
i = OHCI_BM(iso_td.flags, TD_DI);
|
622 |
663 |
if (i < ohci->done_count)
|
623 |
664 |
ohci->done_count = i;
|
624 |
|
ohci_put_iso_td(addr, &iso_td);
|
|
665 |
ohci_put_iso_td(ohci, addr, &iso_td);
|
625 |
666 |
return 0;
|
626 |
667 |
}
|
627 |
668 |
|
... | ... | |
696 |
737 |
}
|
697 |
738 |
|
698 |
739 |
if (len && dir != OHCI_TD_DIR_IN) {
|
699 |
|
ohci_copy_iso_td(start_addr, end_addr, ohci->usb_buf, len, 0);
|
|
740 |
ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, len, 0);
|
700 |
741 |
}
|
701 |
742 |
|
702 |
743 |
if (completion) {
|
... | ... | |
732 |
773 |
/* Writeback */
|
733 |
774 |
if (dir == OHCI_TD_DIR_IN && ret >= 0 && ret <= len) {
|
734 |
775 |
/* IN transfer succeeded */
|
735 |
|
ohci_copy_iso_td(start_addr, end_addr, ohci->usb_buf, ret, 1);
|
|
776 |
ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, ret, 1);
|
736 |
777 |
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
|
737 |
778 |
OHCI_CC_NOERROR);
|
738 |
779 |
OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, ret);
|
... | ... | |
788 |
829 |
if (i < ohci->done_count)
|
789 |
830 |
ohci->done_count = i;
|
790 |
831 |
}
|
791 |
|
ohci_put_iso_td(addr, &iso_td);
|
|
832 |
ohci_put_iso_td(ohci, addr, &iso_td);
|
792 |
833 |
return 1;
|
793 |
834 |
}
|
794 |
835 |
|
... | ... | |
818 |
859 |
#endif
|
819 |
860 |
return 1;
|
820 |
861 |
}
|
821 |
|
if (!ohci_read_td(addr, &td)) {
|
|
862 |
if (!ohci_read_td(ohci, addr, &td)) {
|
822 |
863 |
fprintf(stderr, "usb-ohci: TD read error at %x\n", addr);
|
823 |
864 |
return 0;
|
824 |
865 |
}
|
... | ... | |
859 |
900 |
}
|
860 |
901 |
|
861 |
902 |
if (len && dir != OHCI_TD_DIR_IN && !completion) {
|
862 |
|
ohci_copy_td(&td, ohci->usb_buf, len, 0);
|
|
903 |
ohci_copy_td(ohci, &td, ohci->usb_buf, len, 0);
|
863 |
904 |
}
|
864 |
905 |
}
|
865 |
906 |
|
... | ... | |
918 |
959 |
}
|
919 |
960 |
if (ret >= 0) {
|
920 |
961 |
if (dir == OHCI_TD_DIR_IN) {
|
921 |
|
ohci_copy_td(&td, ohci->usb_buf, ret, 1);
|
|
962 |
ohci_copy_td(ohci, &td, ohci->usb_buf, ret, 1);
|
922 |
963 |
#ifdef DEBUG_PACKET
|
923 |
964 |
dprintf(" data:");
|
924 |
965 |
for (i = 0; i < ret; i++)
|
... | ... | |
987 |
1028 |
i = OHCI_BM(td.flags, TD_DI);
|
988 |
1029 |
if (i < ohci->done_count)
|
989 |
1030 |
ohci->done_count = i;
|
990 |
|
ohci_put_td(addr, &td);
|
|
1031 |
ohci_put_td(ohci, addr, &td);
|
991 |
1032 |
return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR;
|
992 |
1033 |
}
|
993 |
1034 |
|
... | ... | |
1005 |
1046 |
return 0;
|
1006 |
1047 |
|
1007 |
1048 |
for (cur = head; cur; cur = next_ed) {
|
1008 |
|
if (!ohci_read_ed(cur, &ed)) {
|
|
1049 |
if (!ohci_read_ed(ohci, cur, &ed)) {
|
1009 |
1050 |
fprintf(stderr, "usb-ohci: ED read error at %x\n", cur);
|
1010 |
1051 |
return 0;
|
1011 |
1052 |
}
|
... | ... | |
1046 |
1087 |
}
|
1047 |
1088 |
}
|
1048 |
1089 |
|
1049 |
|
ohci_put_ed(cur, &ed);
|
|
1090 |
ohci_put_ed(ohci, cur, &ed);
|
1050 |
1091 |
}
|
1051 |
1092 |
|
1052 |
1093 |
return active;
|
... | ... | |
1087 |
1128 |
OHCIState *ohci = opaque;
|
1088 |
1129 |
struct ohci_hcca hcca;
|
1089 |
1130 |
|
1090 |
|
cpu_physical_memory_rw(ohci->hcca, (uint8_t *)&hcca, sizeof(hcca), 0);
|
|
1131 |
ohci_read_hcca(ohci, ohci->hcca, &hcca);
|
1091 |
1132 |
|
1092 |
1133 |
/* Process all the lists at the end of the frame */
|
1093 |
1134 |
if (ohci->ctl & OHCI_CTL_PLE) {
|
... | ... | |
1131 |
1172 |
ohci_sof(ohci);
|
1132 |
1173 |
|
1133 |
1174 |
/* Writeback HCCA */
|
1134 |
|
cpu_physical_memory_rw(ohci->hcca, (uint8_t *)&hcca, sizeof(hcca), 1);
|
|
1175 |
ohci_put_hcca(ohci, ohci->hcca, &hcca);
|
1135 |
1176 |
}
|
1136 |
1177 |
|
1137 |
1178 |
/* Start sending SOF tokens across the USB bus, lists are processed in
|
... | ... | |
1620 |
1661 |
};
|
1621 |
1662 |
|
1622 |
1663 |
static void usb_ohci_init(OHCIState *ohci, int num_ports, int devfn,
|
1623 |
|
qemu_irq irq, enum ohci_type type, const char *name)
|
|
1664 |
qemu_irq irq, enum ohci_type type,
|
|
1665 |
const char *name, uint32_t localmem_base)
|
1624 |
1666 |
{
|
1625 |
1667 |
int i;
|
1626 |
1668 |
|
... | ... | |
1641 |
1683 |
}
|
1642 |
1684 |
|
1643 |
1685 |
ohci->mem = cpu_register_io_memory(0, ohci_readfn, ohci_writefn, ohci);
|
|
1686 |
ohci->localmem_base = localmem_base;
|
1644 |
1687 |
ohci->name = name;
|
1645 |
1688 |
|
1646 |
1689 |
ohci->irq = irq;
|
... | ... | |
1687 |
1730 |
ohci->pci_dev.config[0x3d] = 0x01; /* interrupt pin 1 */
|
1688 |
1731 |
|
1689 |
1732 |
usb_ohci_init(&ohci->state, num_ports, devfn, ohci->pci_dev.irq[0],
|
1690 |
|
OHCI_TYPE_PCI, ohci->pci_dev.name);
|
|
1733 |
OHCI_TYPE_PCI, ohci->pci_dev.name, 0);
|
1691 |
1734 |
|
1692 |
1735 |
pci_register_io_region((struct PCIDevice *)ohci, 0, 256,
|
1693 |
1736 |
PCI_ADDRESS_SPACE_MEM, ohci_mapfunc);
|
... | ... | |
1699 |
1742 |
OHCIState *ohci = (OHCIState *)qemu_mallocz(sizeof(OHCIState));
|
1700 |
1743 |
|
1701 |
1744 |
usb_ohci_init(ohci, num_ports, devfn, irq,
|
1702 |
|
OHCI_TYPE_PXA, "OHCI USB");
|
|
1745 |
OHCI_TYPE_PXA, "OHCI USB", 0);
|
1703 |
1746 |
|
1704 |
1747 |
cpu_register_physical_memory(base, 0x1000, ohci->mem);
|
1705 |
1748 |
}
|
|
1749 |
|
|
1750 |
void usb_ohci_init_sm501(uint32_t mmio_base, uint32_t localmem_base,
|
|
1751 |
int num_ports, int devfn, qemu_irq irq)
|
|
1752 |
{
|
|
1753 |
OHCIState *ohci = (OHCIState *)qemu_mallocz(sizeof(OHCIState));
|
|
1754 |
|
|
1755 |
usb_ohci_init(ohci, num_ports, devfn, irq,
|
|
1756 |
OHCI_TYPE_SM501, "OHCI USB", localmem_base);
|
|
1757 |
|
|
1758 |
cpu_register_physical_memory(mmio_base, 0x1000, ohci->mem);
|
|
1759 |
}
|
|
1760 |
|