@@ -28,17 +28,16 @@
#include "usb-ehci.h"
#include "monitor.h"
-#define EHCI_DEBUG 1
-#if EHCI_DEBUG
-//#define DEBUG(x) timed_printf x
-#define DEBUG(x) printf x
+#define EHCI_DEBUG 1
+#define TDEBUG 0
+#define DEBUG_PACKET 1
+
+#if EHCI_DEBUG || TDEBUG || DEBUG_PACKET
+//#define DPRINTF printf
+#define DPRINTF timed_printf
#else
-#define DEBUG(x)
+#define DPRINTF(...)
#endif
-//static int timed_printf(const char *fmt, ...);
-
-// #define TDEBUG
-// #define DEBUG_PACKET
#define ASSERT(x) { if (!(x)) { printf("Assertion failed in usb-echi.c line %d\n", __LINE__); exit(1); } }
@@ -135,6 +134,7 @@
#else
#define FRAME_TIMER_FREQ 8000
#endif
+#define FRAME_TIMER_USEC (1000000 / FRAME_TIMER_FREQ)
#define NB_MAXINTRATE 8 // Max rate at which controller issues ints
#define NB_PORTS 4 // Number of downstream ports
@@ -376,6 +376,8 @@ typedef struct {
uint32_t frame_end_usec;
} EHCIState;
+#define SET_LAST_RUN_CLOCK(s) (s)->last_run_usec = qemu_get_clock(vm_clock) / 1000;
+
static inline uint32_t get_field(uint32_t data, uint32_t mask, int shift)
{
return((data & mask) >> shift);
@@ -388,23 +390,95 @@ static inline void set_field(uint32_t *data, uint32_t val,
*data |=(val << shift);
}
+#if EHCI_DEBUG
+static int timed_printf(const char *fmt, ...)
+{
+ int msec, usec;
+ static int usec_last;
+ va_list ap;
+
+ usec = qemu_get_clock(vm_clock) / 1000;
+
+ msec = usec - usec_last;
+ usec_last = usec;
+ usec = msec;
+
+ msec /= 1000;
+ msec %= 1000;
+
+ usec %= 1000;
+
+ va_start(ap, fmt);
+ printf("%03d.%03d ", msec, usec);
+ vprintf(fmt, ap);
+ va_end(ap);
+
+ return 0;
+}
+
+static const char *addr2str(unsigned addr)
+{
+ const char *r = " unknown";
+
+ switch(addr) {
+ case CAPLENGTH:
+ r = " CAPLENGTH";
+ break;
+
+ case HCIVERSION:
+ r = "HCIVERSION";
+ break;
+
+ case HCSPARAMS:
+ r = " HCSPARAMS";
+ break;
+
+ case HCCPARAMS:
+ r = " HCCPARAMS";
+ break;
+
+ case USBCMD:
+ r = " COMMAND";
+ break;
+
+ case USBSTS:
+ r = " STATUS";
+ break;
+
+ case USBINTR:
+ r = " INTERRUPT";
+ break;
+
+ case FRINDEX:
+ r = " FRAME IDX";
+ break;
+ }
+
+ return r;
+}
+
static void dump_ptr(const char *s, uint32_t ptr, int has_type)
{
int t = NLPTR_TYPE_GET(ptr);
-
- printf("%s%08X", s, NLPTR_GET(ptr));
+ DPRINTF("%s%08X", s, NLPTR_GET(ptr));
if (has_type) {
- printf("(PTR type is %s)",
+ DPRINTF("(PTR type is %s)",
t == NLPTR_TYPE_ITD ? "ITD" :
(t == NLPTR_TYPE_QH ? "QH" :
(t == NLPTR_TYPE_STITD ? "STITD" :
(t == NLPTR_TYPE_FSTN ? "FSTN" : "****"))));
}
- printf("%s\n", NLPTR_TBIT(ptr) ? " TBIT set" : "");
+ DPRINTF("%s\n", NLPTR_TBIT(ptr) ? " TBIT set" : "");
}
+#else
+static inline void dump_ptr(const char *s, uint32_t ptr, int has_type)
+{
+}
+#endif
+#if EHCI_DEBUG || DEBUG_PACKET
static void dump_qtd(EHCIqtd *qtd, uint32_t qtdaddr)
{
int pid;
@@ -445,7 +519,8 @@ static void dump_qtd(EHCIqtd *qtd, uint32_t qtdaddr)
qtd->bufptr[0] & BUFPTR_CURROFF_MASK);
printf(" === ======== ========\n");
}
-
+#endif
+#if EHCI_DEBUG
static void dump_qh(EHCIqh *qh, uint32_t qhaddr)
{
int speed =(qh->epchar & QH_EPCHAR_EPS_MASK) >> QH_EPCHAR_EPS_SH;
@@ -496,8 +571,13 @@ static void dump_qh(EHCIqh *qh, uint32_t qhaddr)
(qh->bufptr[2] & BUFPTR_SBYTES_MASK) >> BUFPTR_SBYTES_SH);
printf("== ======== ========\n");
}
+#else
+static inline void dump_qh(EHCIqh *qh, uint32_t qhaddr)
+{
+}
+#endif
-#ifdef DEBUG_PACKET
+#if DEBUG_PACKET
static void dump_itd(EHCIitd *itd, uint32_t addr)
{
@@ -554,49 +634,22 @@ static void dump_itd(EHCIitd *itd, uint32_t addr)
#endif
-#if 0
-static int timed_printf(const char *fmt, ...)
-{
- int msec, usec;
- static int usec_last;
- va_list ap;
-
- usec = qemu_get_clock(vm_clock) / 1000;
- msec = usec - usec_last;
- usec_last = usec;
- usec = msec;
-
- msec /= 1000;
- msec %= 1000;
-
- usec %= 1000;
-
- va_start(ap, fmt);
- printf("%03d.%03d ", msec, usec);
- vprintf(fmt, ap);
- va_end(ap);
-
- return 0;
-}
-#endif
-
-static inline void ehci_set_interrupt(EHCIState *ehci, int intr)
+static inline void ehci_set_interrupt(EHCIState *s, int intr)
{
int level = 0;
// TODO honour interrupt threshold requests
- ehci->usbsts |= intr;
+ s->usbsts |= intr;
- if ((ehci->usbsts & USBINTR_MASK) & ehci->usbintr)
+ if ((s->usbsts & USBINTR_MASK) & s->usbintr)
level = 1;
-#ifdef TDEBUG
- DEBUG(("ehci: setting interrupt level %d(st/en)=(%02X/%02X)\n", level,
- ehci->usbsts & USBINTR_MASK, ehci->usbintr));
-#endif
- qemu_set_irq(ehci->irq, level);
+ DPRINTF("ehci_set_interrupt: intr x%x, STS x%x, INTR x%x, level %d\n",
+ intr, s->usbsts & USBINTR_MASK, s->usbintr, level);
+
+ qemu_set_irq(s->irq, level);
}
/* Attach or detach a device on root hub */
@@ -606,8 +659,8 @@ static void ehci_attach(USBPort *port, USBDevice *dev)
EHCIState *s = port->opaque;
uint32_t *portsc = &s->portsc[port->index];
- DEBUG(("ehci_attach invoked for index %d, desc %s\n",
- port->index, dev ? dev->product_desc : "undefined"));
+ DPRINTF("ehci_attach invoked for index %d, portsc 0x%x, desc %s\n",
+ port->index, *portsc, dev ? dev->product_desc : "undefined");
if (dev) {
if (port->dev) {
@@ -647,7 +700,6 @@ static void ehci_reset(void *opaque)
uint8_t *pci_conf;
int i;
- DEBUG(("ehci_reset\n"));
pci_conf = s->dev.config;
memset(&s->mmio[OPREGBASE], 0x00, MMIO_SIZE - OPREGBASE);
@@ -676,7 +728,8 @@ static uint32_t ehci_mem_readb(void *ptr, target_phys_addr_t addr)
uint32_t val;
val = s->mmio[addr];
- DEBUG(("mem_readb : addr=0x%08X, val=%02X\n",(int)addr,(int)val));
+ DPRINTF("ehci_mem_readb: %s (addr 0x%08X), val 0x%02X\n",
+ addr2str((unsigned) addr), (unsigned) addr, val);
return val;
}
@@ -687,7 +740,8 @@ static uint32_t ehci_mem_readw(void *ptr, target_phys_addr_t addr)
uint32_t val;
val = s->mmio[addr] |(s->mmio[addr+1] << 8);
- DEBUG(("mem_readw : addr=0x%08X, val=0x%04X\n",(int)addr,(int)val));
+ DPRINTF("ehci_mem_readw: %s (addr 0x%08X), val 0x%04X\n",
+ addr2str((unsigned) addr), (unsigned) addr, val);
return val;
}
@@ -700,20 +754,22 @@ static uint32_t ehci_mem_readl(void *ptr, target_phys_addr_t addr)
val = s->mmio[addr] |(s->mmio[addr+1] << 8) |
(s->mmio[addr+2] << 16) |(s->mmio[addr+3] << 24);
- DEBUG(("ehci_mem_readl : addr=0x%08X, val=0x%08X\n",(unsigned) addr, val));
+ if (addr != USBSTS)
+ DPRINTF("ehci_mem_readl: %s (addr 0x%08X), val 0x%08X\n",
+ addr2str((unsigned) addr), (unsigned) addr, val);
return val;
}
static void ehci_mem_writeb(void *ptr, target_phys_addr_t addr, uint32_t val)
{
- printf("EHCI doesn't handle byte writes to MMIO\n");
+ fprintf(stderr, "EHCI doesn't handle byte writes to MMIO\n");
exit(1);
}
static void ehci_mem_writew(void *ptr, target_phys_addr_t addr, uint32_t val)
{
- printf("EHCI doesn't handle 16-bit writes to MMIO\n");
+ fprintf(stderr, "EHCI doesn't handle 16-bit writes to MMIO\n");
exit(1);
}
@@ -723,9 +779,9 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val)
int rwc;
USBDevice *dev = s->ports[port].dev;
- DEBUG(("PORTSC %08X->%08X rwc=%08X rw=%08X\n", *portsc, val,
- (val & PORTSC_RWC_MASK),
- val & PORTSC_RO_MASK));
+ DPRINTF("port_status_write: "
+ "PORTSC (port %d) curr %08X new %08X rw-clear %08X rw %08X\n",
+ port, *portsc, val, (val & PORTSC_RWC_MASK), val & PORTSC_RO_MASK);
rwc = val & PORTSC_RWC_MASK;
val &= PORTSC_RO_MASK;
@@ -734,14 +790,12 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val)
*portsc &= ~rwc;
- DEBUG(("PORTSC -> %08X\n", *portsc));
-
if ((val & PORTSC_PRESET) && !(*portsc & PORTSC_PRESET)) {
- DEBUG(("USBTRAN Port %d reset begin\n", port));
+ DPRINTF("port_status_write: USBTRAN Port %d reset begin\n", port);
}
if (!(val & PORTSC_PRESET) &&(*portsc & PORTSC_PRESET)) {
- DEBUG(("USBTRAN Port %d reset done\n", port));
+ DPRINTF("port_status_write: USBTRAN Port %d reset done\n", port);
ehci_attach(&s->ports[port], dev);
// TODO how to handle reset of ports with no device
@@ -749,7 +803,8 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val)
usb_send_msg(dev, USB_MSG_RESET);
if (s->ports[port].dev) {
- DEBUG(("Device was connected before reset, clearing CSC bit\n"));
+ DPRINTF("port_status_write: "
+ "Device was connected before reset, clearing CSC bit\n");
*portsc &= ~PORTSC_CSC;
}
@@ -764,7 +819,7 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val)
*portsc &= ~PORTSC_RO_MASK;
*portsc |= val;
- DEBUG(("Port status set to 0x%08x\n", *portsc));
+ DPRINTF("port_status_write: Port %d status set to 0x%08x\n", port, *portsc);
}
static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
@@ -774,13 +829,11 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
/* Only aligned reads are allowed on OHCI */
if (addr & 3) {
- printf("usb-ehci: Mis-aligned write\n");
+ fprintf(stderr, "usb-ehci: Mis-aligned write to addr 0x%lx\n", addr);
return;
}
if (addr >= PORTSC && addr < PORTSC + 4 * NB_PORTS) {
- DEBUG(("ehci_mem_writel : PORTSC%d->0x%08X \n",
- (int)(addr-PORTSC)/4, val));
handle_port_status_write(s, (addr-PORTSC)/4, val);
return;
}
@@ -790,28 +843,25 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
switch(addr)
{
case USBCMD:
+ DPRINTF("ehci_mem_writel: USBCMD val=0x%08X\n", val);
if ((val & USBCMD_RUNSTOP) && !(s->usbcmd & USBCMD_RUNSTOP)) {
- DEBUG(("ehci_mem_writel : USBCMD run, clear halt\n"));
- // printf("Call mod_timer for %p\n", s->frame_timer);
+ DPRINTF(" run, clear halt\n");
qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock));
- s->last_run_usec = qemu_get_clock(vm_clock) / 1000;
+ SET_LAST_RUN_CLOCK(s);
s->usbsts &= ~USBSTS_HALT;
}
- if (!(val & USBCMD_RUNSTOP) &&(s->usbcmd & USBCMD_RUNSTOP)) {
- DEBUG(("ehci_mem_writel : USBCMD ** STOP **\n"));
- // printf("Call del_timer for %p\n", s->frame_timer);
-#if 0
+ if (!(val & USBCMD_RUNSTOP) && (s->usbcmd & USBCMD_RUNSTOP)) {
+ DPRINTF(" ** STOP **\n");
qemu_del_timer(s->frame_timer);
-#endif
// TODO - should finish out some stuff before setting halt
s->usbsts |= USBSTS_HALT;
}
if (val & USBCMD_HCRESET) {
- DEBUG(("ehci_mem_writel : USBCMD resetting ...\n"));
+ DPRINTF(" resetting ...\n");
ehci_reset(s);
- DEBUG(("ehci_mem_writel: USBCMD reset done, clear reset request bit\n"));
+ DPRINTF(" reset done, clear reset request bit\n");
val &= ~USBCMD_HCRESET;
}
@@ -819,26 +869,26 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
case USBSTS:
val &= USBSTS_RO_MASK; // bits 6 thru 31 are RO
- DEBUG(("ehci_mem_writel : USBSTS RWC set to 0x%08X\n", val));
+ DPRINTF("mem_writel : USBSTS RWC set to 0x%08X\n", val);
val =(s->usbsts &= ~val); // bits 0 thru 5 are R/WC
- DEBUG(("ehci_mem_writel : USBSTS updating interrupt condition\n"));
+ DPRINTF("mem_writel : USBSTS updating interrupt condition\n");
ehci_set_interrupt(s, 0);
-
break;
case USBINTR:
val &= USBINTR_MASK;
- // DEBUG(("ehci_mem_writel : USBINTR set to 0x%08X\n", val));
+ DPRINTF("ehci_mem_writel: USBINTR set to 0x%08X\n", val);
break;
case FRINDEX:
s->sofv = val >> 3;
+ DPRINTF("ehci_mem_writel: FRAME index set to 0x%08X\n",(unsigned) addr, val);
break;
case CONFIGFLAG:
+ DPRINTF("ehci_mem_writel: CONFIGFLAG set to 0x%08X\n",(unsigned) addr, val);
val &= 0x1;
-
if (val) {
for(i = 0; i < NB_PORTS; i++)
s->portsc[i] &= ~PORTSC_POWNER;
@@ -847,10 +897,6 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
break;
}
- if (addr != 0x28) {
- DEBUG(("ehci_mem_writel : addr=0x%08X, val=0x%08X\n",(unsigned) addr, val));
- }
-
*(uint32_t *)(&s->mmio[addr]) = val;
}
@@ -896,15 +942,15 @@ static void ehci_qh_do_overlay(EHCIState *ehci, EHCIqh *qh, EHCIqtd *qtd)
dtoggle = qh->token & QTD_TOKEN_DTOGGLE;
ping = qh->token & QTD_TOKEN_PING;
- DEBUG(("setting qh.current from %08X to 0x%08X\n", qh->current,
- ehci->qtdaddr));
+ DPRINTF("setting qh.current from %08X to 0x%08X\n", qh->current,
+ ehci->qtdaddr);
qh->current = ehci->qtdaddr;
qh->qtdnext = qtd->next;
qh->altnext = qtd->altnext;
qh->token = qtd->token;
if (qh->current < 0x1000) {
-#ifdef DEBUG_PACKET
+#if DEBUG_PACKET
dump_qh(qh, qh->current);
#endif
ASSERT(1==2);
@@ -940,8 +986,8 @@ static void ehci_buffer_rw(EHCIState *ehci, EHCIqh *qh, int bytes, int rw)
cpage = get_field(qh->token, QTD_TOKEN_CPAGE_MASK, QTD_TOKEN_CPAGE_SH);
ASSERT(cpage == 0);
- DEBUG(("exec: %sing %d bytes to/from %08x\n",
- rw ? "writ" : "read", bytes, qh->bufptr[0]));
+ DPRINTF("exec: %sing %d bytes to/from %08x\n",
+ rw ? "writ" : "read", bytes, qh->bufptr[0]);
if (!bytes)
return;
@@ -953,8 +999,8 @@ static void ehci_buffer_rw(EHCIState *ehci, EHCIqh *qh, int bytes, int rw)
if (bytes <=(tail - head))
tail = head + bytes;
- DEBUG(("DATA %s cpage:%d head:%08X tail:%08X target:%08X\n",
- rw ? "WRITE" : "READ ", cpage, head, tail, bufpos));
+ DPRINTF("DATA %s cpage:%d head:%08X tail:%08X target:%08X\n",
+ rw ? "WRITE" : "READ ", cpage, head, tail, bufpos);
ASSERT(bufpos + tail - head <= BUFF_SIZE);
ASSERT(tail - head > 0);
@@ -977,19 +1023,23 @@ static void ehci_buffer_rw(EHCIState *ehci, EHCIqh *qh, int bytes, int rw)
static void ehci_async_complete_packet(USBPacket *packet, void *opaque)
{
EHCIState *ehci = opaque;
-#ifdef DEBUG_PACKET
- dprintf("Async packet complete\n");
+#if DEBUG_PACKET
+ DPRINTF("Async packet complete\n");
#endif
ehci->async_complete = 1;
ehci->exec_status = packet->len;
}
+#if TDEBUG
+static int transactid;
+#endif
+
static int ehci_execute_complete(EHCIState *ehci,
EHCIqh *qh,
int ret)
{
if (ret == USB_RET_ASYNC && !ehci->async_complete) {
- DEBUG(("not done yet\n"));
+ DPRINTF("not done yet\n");
return ret;
}
@@ -999,37 +1049,36 @@ static int ehci_execute_complete(EHCIState *ehci,
if (ret < 0) {
switch(ret) {
case USB_RET_NODEV:
- printf("USB no device\n");
+ fprintf(stderr, "USB no device\n");
break;
case USB_RET_STALL:
- printf("USB stall\n");
+ fprintf(stderr, "USB stall\n");
qh->token |= QTD_TOKEN_HALT;
break;
case USB_RET_NAK:
- DEBUG(("USBTRAN RSP NAK, returning without clear active\n"));
+ DPRINTF("USBTRAN RSP NAK, returning without clear active\n");
return USB_RET_NAK;
break;
case USB_RET_BABBLE:
- printf("USB babble TODO\n");
+ fprintf(stderr, "USB babble TODO\n");
ASSERT(ret >= 0);
break;
default:
- printf("USB invalid response %d to handle\n",
- ret);
+ fprintf(stderr, "USB invalid response %d to handle\n", ret);
ASSERT(ret >= 0);
break;
}
} else {
// if (ret < maxpkt)
// {
- // DEBUG(("Short packet condition\n"));
+ // DPRINTF("Short packet condition\n");
// // TODO check 4.12 for splits
// }
if (ehci->tbytes && ehci->pid == USB_TOKEN_IN) {
ASSERT(ret > 0);
ehci_buffer_rw(ehci, qh, ret, 1);
-#ifdef TDEBUG
+#if TDEBUG
printf("Data after execution:\n");
// dump_data(ehci->buffer, ehci->tbytes < 64 ? ehci->tbytes : 64);
// decode_data(ehci->pid, ehci->buffer, ret);
@@ -1051,23 +1100,23 @@ static int ehci_execute_complete(EHCIState *ehci,
// TODO should do this after writeback to memory
ehci_set_interrupt(ehci, USBSTS_INT);
}
-#ifdef DEBUG_PACKET
- DEBUG(("QH after execute:-\n"));
+#if DEBUG_PACKET
+ DPRINTF("QH after execute:-\n");
dump_qh(qh, NLPTR_GET(ehci->qhaddr));
#endif
-#ifdef TDEBUG
- printf("USBTRAN RSP %3d return:(%5d) ",
+#if TDEBUG
+ DPRINTF("USBTRAN RSP %3d return:(%5d) ",
transactid,
ret);
if (ehci->pid == USB_TOKEN_IN) {
- printf("[%02X %02X %02X %02X ...]\n",
+ DPRINTF("[%02X %02X %02X %02X ...]\n",
*ehci->buffer, *(ehci->buffer+1),
*(ehci->buffer+2), *(ehci->buffer+3));
}
else
- printf("\n");
+ DPRINTF("\n");
#endif
return ret;
}
@@ -1095,46 +1144,46 @@ static int ehci_execute(EHCIState *ehci,
devadr = get_field(qh->epchar, QH_EPCHAR_DEVADDR_MASK, 0);
if ( !(qh->token & QTD_TOKEN_ACTIVE)) {
- printf("Attempting to execute inactive QH\n");
+ fprintf(stderr, "Attempting to execute inactive QH\n");
exit(1);;
}
if (smask) {
- DEBUG(("active interrupt transfer frindex %d for dev %d EP %d\n",
- ehci->frindex, devadr, endp));
+ DPRINTF("active interrupt transfer frindex %d for dev %d EP %d\n",
+ ehci->frindex, devadr, endp);
// TODO are interrupt always IN ?
ehci->pid = USB_TOKEN_IN;
} else {
- DEBUG(("Active non-interrupt QH, executing\n"));
+ DPRINTF("Active non-interrupt QH, executing\n");
- DEBUG(("pid is %2X\n", ehci->pid));
+ DPRINTF("pid is %2X\n", ehci->pid);
switch(ehci->pid) {
case 0: ehci->pid = USB_TOKEN_OUT; break;
case 1: ehci->pid = USB_TOKEN_IN; break;
case 2: ehci->pid = USB_TOKEN_SETUP; break;
- default: printf("bad token\n"); break;
+ default: fprintf(stderr, "bad token\n"); break;
}
}
// TODO set reclam
-#ifdef DEBUG_PACKET
- DEBUG(("QH before execute:-\n"));
+#if DEBUG_PACKET
+ DPRINTF("QH before execute:-\n");
dump_qh(qh, NLPTR_GET(qhaddr));
#endif
if (ehci->tbytes && ehci->pid != USB_TOKEN_IN) {
ehci_buffer_rw(ehci, qh, ehci->tbytes, 0);
-#ifdef TDEBUG
- printf("Data before execution:\n");
+#if TDEBUG
+ DPRINTF("Data before execution:\n");
// dump_data(ehci->buffer, ehci->tbytes < 64 ? ehci->tbytes : 64);
// decode_data(ehci->pid, ehci->buffer, ehci->tbytes);
#endif
}
-#ifdef TDEBUG
- printf("\nUSBTRAN REQ %3d dev:%d ep:%d pid:%02X %s bytes:(%5d) ",
+#if TDEBUG
+ DPRINTF("\nUSBTRAN REQ %3d dev:%d ep:%d pid:%02X %s bytes:(%5d) ",
++transactid,
devadr,
endp,
@@ -1145,12 +1194,12 @@ static int ehci_execute(EHCIState *ehci,
ehci->tbytes);
if (ehci->pid != USB_TOKEN_IN) {
- printf("[%02X %02X %02X %02X ...]\n",
+ DPRINTF("[%02X %02X %02X %02X ...]\n",
*ehci->buffer, *(ehci->buffer+1),
*(ehci->buffer+2), *(ehci->buffer+3));
}
else
- printf("\n");
+ DPRINTF("\n");
#endif
ret = USB_RET_NODEV;
@@ -1162,8 +1211,8 @@ static int ehci_execute(EHCIState *ehci,
// TODO sometime we will also need to check if we are the port owner
if (!(ehci->portsc[i] &(PORTSC_CONNECT))) {
- DEBUG(("Port %d, no exec, not connected(%08X)\n",
- i, ehci->portsc[i]));
+ DPRINTF("Port %d, no exec, not connected(%08X)\n",
+ i, ehci->portsc[i]);
continue;
}
@@ -1175,17 +1224,17 @@ static int ehci_execute(EHCIState *ehci,
ehci->usb_packet.complete_cb = ehci_async_complete_packet;
ehci->usb_packet.complete_opaque = ehci;
- DEBUG(("calling dev->info->handle_packet\n"));
+ DPRINTF("calling dev->info->handle_packet\n");
ret = dev->info->handle_packet(dev, &ehci->usb_packet);
if (ret != USB_RET_NODEV)
break;
}
- DEBUG(("exit loop dev->info->handle_packet\n"));
+ DPRINTF("exit loop dev->info->handle_packet\n");
if (ret > BUFF_SIZE || ehci->tbytes > BUFF_SIZE) {
- printf("bogus QH byte count\n");
+ fprintf(stderr, "bogus QH byte count\n");
dump_qh(qh, NLPTR_GET(qhaddr));
ASSERT(ret <= BUFF_SIZE && ehci->tbytes <= BUFF_SIZE);
}
@@ -1231,8 +1280,8 @@ static void ehci_process_itd(EHCIState *ehci,
#endif
if (itd->transact[i] & ITD_XACT_ACTIVE) {
- DEBUG(("ISOCHRONOUS active for frame %d, interval %d\n",
- ehci->frindex >> 3, i));
+ DPRINTF("ISOCHRONOUS active for frame %d, interval %d\n",
+ ehci->frindex >> 3, i);
pg = get_field(itd->transact[i], ITD_XACT_PGSEL_MASK,
ITD_XACT_PGSEL_SH);
@@ -1243,7 +1292,7 @@ static void ehci_process_itd(EHCIState *ehci,
ASSERT(len <= BUFF_SIZE);
- DEBUG(("ISOCH: buffer %08X len %d\n", ptr, len));
+ DPRINTF("ISOCH: buffer %08X len %d\n", ptr, len);
if (!dir) {
cpu_physical_memory_rw(ptr, &ehci->buffer[0], len, 0);
@@ -1260,8 +1309,8 @@ static void ehci_process_itd(EHCIState *ehci,
// TODO sometime we will also need to check if we are the port owner
if (!(ehci->portsc[j] &(PORTSC_CONNECT))) {
- DEBUG(("Port %d, no exec, not connected(%08X)\n",
- j, ehci->portsc[j]));
+ DPRINTF("Port %d, no exec, not connected(%08X)\n",
+ j, ehci->portsc[j]);
continue;
}
@@ -1273,7 +1322,7 @@ static void ehci_process_itd(EHCIState *ehci,
ehci->usb_packet.complete_cb = ehci_async_complete_packet;
ehci->usb_packet.complete_opaque = ehci;
- DEBUG(("calling dev->info->handle_packet\n"));
+ DPRINTF("calling dev->info->handle_packet\n");
ret = dev->info->handle_packet(dev, &ehci->usb_packet);
if (ret != USB_RET_NODEV)
@@ -1287,21 +1336,21 @@ static void ehci_process_itd(EHCIState *ehci,
if (ret == USB_RET_NAK) {
if (ehci->isoch_pause > 0) {
- DEBUG(("ISOCH: received a NAK but paused so returning\n"));
+ DPRINTF("ISOCH: received a NAK but paused so returning\n");
ehci->isoch_pause--;
return;
} else if (ehci->isoch_pause == -1) {
- DEBUG(("ISOCH: recv NAK & isoch pause inactive, setting\n"));
+ DPRINTF("ISOCH: recv NAK & isoch pause inactive, setting\n");
// Pause frindex for up to 50 msec waiting for data from
// remote
ehci->isoch_pause = 50;
return;
} else {
- DEBUG(("ISOCH: isoch pause timeout! return 0\n"));
+ DPRINTF("ISOCH: isoch pause timeout! return 0\n");
ret = 0;
}
} else {
- DEBUG(("ISOCH: received ACK, clearing pause\n"));
+ DPRINTF("ISOCH: received ACK, clearing pause\n");
ehci->isoch_pause = -1;
}
@@ -1318,8 +1367,8 @@ static void ehci_process_itd(EHCIState *ehci,
cpu_physical_memory_rw(ptr, &ehci->buffer[0], len, 1);
if (ret != len) {
- DEBUG(("ISOCH IN expected %d, got %d\n",
- len, ret));
+ DPRINTF("ISOCH IN expected %d, got %d\n",
+ len, ret);
set_field(&itd->transact[i],
ret,
ITD_XACT_LENGTH_MASK,
@@ -1351,7 +1400,7 @@ static int ehci_advance_state(EHCIState *ehci,
int nakcnt;
do {
- DEBUG(("advance_state: again=%d\n", again));
+ DPRINTF("advance_state: again=%d\n", again);
again = 0;
// ASSERT(loopcount++ < MAX_ITERATIONS);
@@ -1360,7 +1409,7 @@ static int ehci_advance_state(EHCIState *ehci,
* processing. Entry here consitutes a EHCI start event state(4.8.5)
*/
case EST_WAITLISTHEAD:
- DEBUG(("WAITLISTHEAD\n"));
+ DPRINTF("WAITLISTHEAD\n");
if (async)
ehci->usbsts |= USBSTS_REC;
@@ -1373,11 +1422,11 @@ static int ehci_advance_state(EHCIState *ehci,
sizeof(EHCIqh) >> 2);
if (qh->epchar & QH_EPCHAR_H) {
- DEBUG(("QH %08X is the HEAD of the list\n", entry));
+ DPRINTF("QH %08X is the HEAD of the list\n", entry);
break;
}
- DEBUG(("QH %08X is NOT the HEAD of the list\n", entry));
+ DPRINTF("QH %08X is NOT the HEAD of the list\n", entry);
entry = qh->next;
}
@@ -1394,15 +1443,15 @@ static int ehci_advance_state(EHCIState *ehci,
* processing.
*/
case EST_FETCHENTRY:
- DEBUG(("FETCHENTRY\n"));
+ DPRINTF("FETCHENTRY\n");
if (qemu_get_clock(vm_clock) / 1000 > ehci->frame_end_usec) {
if (async) {
- DEBUG(("FRAME timer elapsed, exit state machine\n"));
+ DPRINTF("FRAME timer elapsed, exit state machine\n");
state = EST_ACTIVE;
break;
} else
- DEBUG(("WARNING - frame timer elapsed during periodic\n"));
+ DPRINTF("WARNING - frame timer elapsed during periodic\n");
}
if (NLPTR_TBIT(entry)) {
@@ -1431,11 +1480,11 @@ static int ehci_advance_state(EHCIState *ehci,
case EST_FETCHQH:
get_dwords(NLPTR_GET(ehci->qhaddr),(uint32_t *) qh,
sizeof(EHCIqh) >> 2);
- DEBUG(("FETCHQH: Fetched QH at address %08X "
+ DPRINTF("FETCHQH: Fetched QH at address %08X "
"(next is %08X, h-bit is %d)\n",
- ehci->qhaddr, qh->next, qh->epchar & QH_EPCHAR_H));
+ ehci->qhaddr, qh->next, qh->epchar & QH_EPCHAR_H);
-#ifdef DEBUG_PACKET
+#if DEBUG_PACKET
dump_qh(qh, NLPTR_GET(ehci->qhaddr));
#endif
@@ -1443,10 +1492,10 @@ static int ehci_advance_state(EHCIState *ehci,
/* EHCI spec version 1.0 Section 4.8.3
*/
if (qh->epchar & QH_EPCHAR_H) {
- DEBUG(("h-bit set\n"));
+ DPRINTF("h-bit set\n");
if (!(ehci->usbsts & USBSTS_REC)) {
- DEBUG(("h-bit and !reclam, done\n"));
+ DPRINTF("h-bit and !reclam, done\n");
state = EST_ACTIVE;
break;
}
@@ -1454,42 +1503,42 @@ static int ehci_advance_state(EHCIState *ehci,
/* EHCI spec version 1.0 Section 4.10.1
*/
if ( !(qh->epcap & QH_EPCAP_SMASK_MASK)) {
- DEBUG(("not intr, clear reclam\n"));
+ DPRINTF("not intr, clear reclam\n");
ehci->usbsts &= ~USBSTS_REC;
}
} else {
- DEBUG(("exec: qh check, frindex is %d,%d\n",
- (ehci->frindex >> 3),(ehci->frindex & 7)));
+ DPRINTF("exec: qh check, frindex is %d,%d\n",
+ (ehci->frindex >> 3),(ehci->frindex & 7));
}
reload = get_field(qh->epchar, QH_EPCHAR_RL_MASK, QH_EPCHAR_RL_SH);
if (reload) {
- DEBUG(("reloading nakcnt to %d\n",
- reload));
+ DPRINTF("reloading nakcnt to %d\n",
+ reload);
set_field(&qh->altnext, reload, QH_ALTNEXT_NAKCNT_MASK,
QH_ALTNEXT_NAKCNT_SH);
}
if (qh->token & QTD_TOKEN_ACTIVE) {
if ((qh->token & QTD_TOKEN_HALT)) {
- printf("Active, Halt, ** ILLEGAL **\n");
+ fprintf(stderr, "Active, Halt, ** ILLEGAL **\n");
state = EST_ACTIVE;
} else {
- DEBUG(("Active, !Halt, execute - fetchqtd\n"));
+ DPRINTF("Active, !Halt, execute - fetchqtd\n");
ehci->qtdaddr = qh->current;
state = EST_FETCHQTD;
again = 1;
}
} else {
if (qh->token & QTD_TOKEN_HALT) {
- DEBUG(("!Active, Halt, go horiz\n"));
+ DPRINTF("!Active, Halt, go horiz\n");
state = EST_HORIZONTALQH;
again = 1;
} else {
/* EHCI spec version 1.0 Section 4.10.2
*/
- DEBUG(("!Active, !Halt, adv q\n"));
+ DPRINTF("!Active, !Halt, adv q\n");
state = EST_ADVANCEQUEUE;
again = 1;
}
@@ -1500,16 +1549,16 @@ static int ehci_advance_state(EHCIState *ehci,
case EST_FETCHITD:
get_dwords(NLPTR_GET(ehci->itdaddr),(uint32_t *) &itd,
sizeof(EHCIitd) >> 2);
- DEBUG(("FETCHITD: Fetched ITD at address %08X "
+ DPRINTF("FETCHITD: Fetched ITD at address %08X "
"(next is %08X)\n",
- ehci->itdaddr, itd.next));
+ ehci->itdaddr, itd.next);
-#ifdef DEBUG_PACKET
+#if DEBUG_PACKET
dump_itd(&itd, NLPTR_GET(ehci->itdaddr));
#endif
ehci_process_itd(ehci, &itd);
-#ifdef DEBUG_PACKET
+#if DEBUG_PACKET
dump_itd(&itd, NLPTR_GET(ehci->itdaddr));
#endif
put_dwords(NLPTR_GET(ehci->itdaddr),(uint32_t *) &itd,
@@ -1520,11 +1569,11 @@ static int ehci_advance_state(EHCIState *ehci,
break;
case EST_ADVANCEQUEUE:
- DEBUG(("ADVANCEQUEUE\n"));
+ DPRINTF("ADVANCEQUEUE\n");
if ((qh->token & QTD_TOKEN_TBYTES_MASK) != 0 &&
NLPTR_TBIT(qh->altnext) == 0) {
ehci->qtdaddr = qh->altnext;
- DEBUG(("tbytes!=0 and tbit = 0, go with altnext\n"));
+ DPRINTF("tbytes!=0 and tbit = 0, go with altnext\n");
} else {
if (NLPTR_TBIT(qh->qtdnext)) {
state = EST_HORIZONTALQH;
@@ -1539,7 +1588,7 @@ static int ehci_advance_state(EHCIState *ehci,
break;
case EST_FETCHQTD:
- DEBUG(("FETCHQTD: Fetching QTD at address %08X\n", ehci->qtdaddr));
+ DPRINTF("FETCHQTD: Fetching QTD at address %08X\n", ehci->qtdaddr);
get_dwords(NLPTR_GET(ehci->qtdaddr),(uint32_t *) qtd,
sizeof(EHCIqtd) >> 2);
@@ -1548,7 +1597,7 @@ static int ehci_advance_state(EHCIState *ehci,
again = 1;
break;
} else {
- DEBUG(("abort advance, not active\n"));
+ DPRINTF("abort advance, not active\n");
state = EST_HORIZONTALQH;
again = 1;
break;
@@ -1564,12 +1613,12 @@ static int ehci_advance_state(EHCIState *ehci,
case EST_EXECUTE:
if (async) {
- DEBUG(("\n\n>>>>> ASYNC STATE MACHINE execute\n"));
+ DPRINTF("\n\n>>>>> ASYNC STATE MACHINE execute\n");
} else {
- DEBUG(("\n\n>>>>> PERIODIC STATE MACHINE execute\n"));
+ DPRINTF("\n\n>>>>> PERIODIC STATE MACHINE execute\n");
}
-#ifdef DEBUG_PACKET
+#if DEBUG_PACKET
dump_qh(qh, NLPTR_GET(ehci->qhaddr));
dump_qtd(qtd, NLPTR_GET(ehci->qtdaddr));
#endif
@@ -1578,11 +1627,11 @@ static int ehci_advance_state(EHCIState *ehci,
#ifndef EHCI_NOMICROFRAMES
if (smask &&(smask &(1 <<(ehci->frindex & 7))) == 0) {
- DEBUG(("PERIODIC active not interval: "
+ DPRINTF("PERIODIC active not interval: "
"mask is %d, "
"frindex is %d,%d\n",
smask,
- (ehci->frindex >> 3),(ehci->frindex & 7)));
+ (ehci->frindex >> 3),(ehci->frindex & 7));
state = EST_HORIZONTALQH;
again = 1;
@@ -1591,18 +1640,18 @@ static int ehci_advance_state(EHCIState *ehci,
#endif
if (smask) {
- DEBUG(("PERIODIC active !!! "
+ DPRINTF("PERIODIC active !!! "
"mask is %d, "
"frindex is %d,%d\n",
smask,
- (ehci->frindex >> 3),(ehci->frindex & 7)));
+ (ehci->frindex >> 3),(ehci->frindex & 7));
}
reload = get_field(qh->epchar, QH_EPCHAR_RL_MASK, QH_EPCHAR_RL_SH);
nakcnt = get_field(qh->altnext, QH_ALTNEXT_NAKCNT_MASK,
QH_ALTNEXT_NAKCNT_SH);
if (reload && !nakcnt) {
- DEBUG(("RL != 0 but NakCnt == 0, no execute\n"));
+ DPRINTF("RL != 0 but NakCnt == 0, no execute\n");
state = EST_HORIZONTALQH;
again = 1;
break;
@@ -1620,7 +1669,7 @@ static int ehci_advance_state(EHCIState *ehci,
#if 0
if (!transactCtr &&(qh->epcap & QH_EPCAP_SMASK_MASK) > 0)
{
- DEBUG(("ZERO transactctr for int qh, go HORIZ\n"));
+ DPRINTF("ZERO transactctr for int qh, go HORIZ\n");
*state = EST_HORIZONTALQH;
again = 1;
break;
@@ -1631,12 +1680,12 @@ static int ehci_advance_state(EHCIState *ehci,
transactCtr = 1; // TODO - check at what level do we repeat
if (qh->epcap & QH_EPCAP_SMASK_MASK)
- DEBUG(("WARN - ZERO transactctr force to 1 for intr\n"));
+ DPRINTF("WARN - ZERO transactctr force to 1 for intr\n");
}
- DEBUG(("exec: ctr is %d\n", transactCtr));
- DEBUG(("exec: frindex is %d,%d\n",
- (ehci->frindex >> 3),(ehci->frindex & 7)));
+ DPRINTF("exec: ctr is %d\n", transactCtr);
+ DPRINTF("exec: frindex is %d,%d\n",
+ (ehci->frindex >> 3),(ehci->frindex & 7));
ehci_qh_do_overlay(ehci, qh, qtd);
ehci->exec_status = ehci_execute(ehci, ehci->qhaddr, qh);
@@ -1648,14 +1697,14 @@ static int ehci_advance_state(EHCIState *ehci,
break;
case EST_EXECUTING:
- DEBUG(("Enter EXECUTING\n"));
+ DPRINTF("Enter EXECUTING\n");
ehci->exec_status = ehci_execute_complete(ehci, qh,
ehci->exec_status);
if (ehci->exec_status == USB_RET_ASYNC)
break;
- DEBUG(("finishing exec\n"));
+ DPRINTF("finishing exec\n");
transactCtr = get_field(qh->epcap,
QH_EPCAP_MULT_MASK, QH_EPCAP_MULT_SH);
@@ -1673,13 +1722,13 @@ static int ehci_advance_state(EHCIState *ehci,
if (ehci->exec_status == USB_RET_NAK) {
nakcnt--;
- DEBUG(("Nak occured and RL != 0, dec NakCnt to %d\n",
- nakcnt));
+ DPRINTF("Nak occured and RL != 0, dec NakCnt to %d\n",
+ nakcnt);
} else {
nakcnt = reload;
- DEBUG(("Nak didn't occur, reloading to %d\n",
- nakcnt));
+ DPRINTF("Nak didn't occur, reloading to %d\n",
+ nakcnt);
}
set_field(&qh->altnext, nakcnt, QH_ALTNEXT_NAKCNT_MASK,
@@ -1692,8 +1741,8 @@ static int ehci_advance_state(EHCIState *ehci,
* physical memory with our guest VM.
*/
- DEBUG(("write QH to VM memory\n"));
-#ifdef DEBUG_PACKET
+ DPRINTF("write QH to VM memory\n");
+#if DEBUG_PACKET
dump_qh(qh, NLPTR_GET(ehci->qhaddr));
#endif
put_dwords(NLPTR_GET(ehci->qhaddr),(uint32_t *) qh,
@@ -1711,7 +1760,7 @@ static int ehci_advance_state(EHCIState *ehci,
case EST_WRITEBACK:
/* Write back the QTD from the QH area */
- DEBUG(("write QTD to VM memory\n"));
+ DPRINTF("write QTD to VM memory\n");
put_dwords(NLPTR_GET(ehci->qtdaddr),(uint32_t *) &qh->qtdnext,
sizeof(EHCIqtd) >> 2);
/* TODO confirm next state. For now, keep going if async
@@ -1727,7 +1776,7 @@ static int ehci_advance_state(EHCIState *ehci,
break;
default:
- printf("Bad state!\n");
+ fprintf(stderr, "Bad state!\n");
break;
}
}
@@ -1741,7 +1790,7 @@ static void ehci_advance_async_state(EHCIState *ehci)
switch(ehci->astate) {
case EST_INACTIVE:
if (ehci->usbcmd & USBCMD_ASE) {
- DEBUG(("ASYNC going active\n"));
+ DPRINTF("ASYNC going active\n");
ehci->usbsts |= USBSTS_ASS;
ehci->astate = EST_ACTIVE;
// No break, fall through to ACTIVE
@@ -1750,13 +1799,13 @@ static void ehci_advance_async_state(EHCIState *ehci)
case EST_ACTIVE:
if ( !(ehci->usbcmd & USBCMD_ASE)) {
- DEBUG(("ASYNC going inactive\n"));
+ DPRINTF("ASYNC going inactive\n");
ehci->usbsts &= ~USBSTS_ASS;
ehci->astate = EST_INACTIVE;
break;
}
- DEBUG(("\n === === === === === ===\n\n"));
+ DPRINTF("\n === === === === === ===\n\n");
if (ehci->usbcmd & USBCMD_IAAD) {
/* Async advance doorbell interrupted requested
*/
@@ -1770,13 +1819,13 @@ static void ehci_advance_async_state(EHCIState *ehci)
break;
case EST_EXECUTING:
- DEBUG(("async state adv for executing\n"));
+ DPRINTF("async state adv for executing\n");
ehci->astate = ehci_advance_state(ehci, 1,
EST_EXECUTING, ehci->qhaddr);
break;
default:
- printf("Bad asynchronous state %d\n",
+ fprintf(stderr, "Bad asynchronous state %d\n",
ehci->astate);
ASSERT(1==2);
}
@@ -1792,7 +1841,7 @@ static void ehci_advance_periodic_state(EHCIState *ehci)
switch(ehci->pstate) {
case EST_INACTIVE:
if ( !(ehci->frindex & 7) &&(ehci->usbcmd & USBCMD_PSE)) {
- DEBUG(("PERIODIC going active\n"));
+ DPRINTF("PERIODIC going active\n");
ehci->usbsts |= USBSTS_PSS;
ehci->pstate = EST_ACTIVE;
// No break, fall through to ACTIVE
@@ -1801,7 +1850,7 @@ static void ehci_advance_periodic_state(EHCIState *ehci)
case EST_ACTIVE:
if ( !(ehci->frindex & 7) && !(ehci->usbcmd & USBCMD_PSE)) {
- DEBUG(("PERIODIC going inactive\n"));
+ DPRINTF("PERIODIC going inactive\n");
ehci->usbsts &= ~USBSTS_PSS;
ehci->pstate = EST_INACTIVE;
break;
@@ -1813,20 +1862,20 @@ static void ehci_advance_periodic_state(EHCIState *ehci)
cpu_physical_memory_rw(list,(uint8_t *) &entry, sizeof entry, 0);
entry = le32_to_cpu(entry);
- DEBUG(("periodic state adv fr=%d. [%08X] -> %08X\n",
- ehci->frindex / 8, list, entry));
+ DPRINTF("periodic state adv fr=%d. [%08X] -> %08X\n",
+ ehci->frindex / 8, list, entry);
ehci->pstate = ehci_advance_state(ehci, 0,
EST_FETCHENTRY, entry);
break;
case EST_EXECUTING:
- DEBUG(("periodic state adv for executing\n"));
+ DPRINTF("periodic state adv for executing\n");
ehci->pstate = ehci_advance_state(ehci, 0,
EST_EXECUTING, ehci->qhaddr);
break;
default:
- printf("Bad periodic state %d\n",
+ fprintf(stderr, "Bad periodic state %d\n",
ehci->pstate);
ASSERT(1==2);
}
@@ -1850,19 +1899,12 @@ static void ehci_frame_timer(void *opaque)
usec_now = t_now / 1000;
usec_elapsed = usec_now - ehci->last_run_usec;
- ehci->frame_end_usec = usec_now + 1000;
+ frames = usec_elapsed / FRAME_TIMER_USEC;
+ ehci->frame_end_usec = usec_now + FRAME_TIMER_USEC;
-#ifdef EHCI_NOMICROFRAMES
- frames = usec_elapsed / 1000;
- ehci->frame_end_usec = usec_now + 1000;
-#else
- frames = usec_elapsed / 125;
- ehci->frame_end_usec = usec_now + 125;
-#endif
-
-#ifdef TDEBUG
- DEBUG(("Frame timer, usec elapsed since last %d, frames %d\n",
- usec_elapsed, frames));
+#if TDEBUG
+ DPRINTF("Frame timer, usec elapsed since last %d, frames %d\n",
+ usec_elapsed, frames);
#endif
for(i = 0; i < frames; i++) {
@@ -1877,8 +1919,8 @@ static void ehci_frame_timer(void *opaque)
if (ehci->frindex > 0x00001fff) {
ehci->frindex = 0;
-#ifdef TDEBUG
- DEBUG(("PERIODIC frindex rollover\n"));
+#if TDEBUG
+ DPRINTF("PERIODIC frindex rollover\n");
#endif
ehci_set_interrupt(ehci, USBSTS_FLR);
}
@@ -1896,16 +1938,12 @@ static void ehci_frame_timer(void *opaque)
ehci_advance_periodic_state(ehci);
}
-#ifdef EHCI_NOMICROFRAMES
- ehci->last_run_usec += 1000;
-#else
- ehci->last_run_usec += 125;
-#endif
+ ehci->last_run_usec += FRAME_TIMER_USEC;
}
#if 0
if (skipped_frames)
- DEBUG(("WARNING - EHCI skipped %d frames\n", skipped_frames));
+ DPRINTF("WARNING - EHCI skipped %d frames\n", skipped_frames);
#endif
/* Async is not inside loop since it executes everything it can once
@@ -1916,10 +1954,9 @@ static void ehci_frame_timer(void *opaque)
qemu_mod_timer(ehci->frame_timer, expire_time);
+#if TDEBUG
usec_elapsed = qemu_get_clock(vm_clock) / 1000 - usec_now;
-
-#ifdef TDEBUG
- DEBUG(("TIMING: frame_timer used %d usec\n", usec_elapsed));
+ DPRINTF("TIMING: frame_timer used %d usec\n", usec_elapsed);
#endif
}
@@ -1940,8 +1977,8 @@ static void ehci_map(PCIDevice *pci_dev, int region_num,
{
EHCIState *s =(EHCIState *)pci_dev;
- DEBUG(("ehci_map: region %d, addr %08lX, size %ld, s->mem %08X\n",
- region_num, addr, size, s->mem));
+ DPRINTF("ehci_map: region %d, addr %08lX, size %ld, s->mem %08X\n",
+ region_num, addr, size, s->mem);
s->mem_base = addr;
cpu_register_physical_memory(addr, size, s->mem);
}
@@ -1987,26 +2024,26 @@ static int usb_ehci_initfn(PCIDevice *dev)
pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82801D);
- pci_conf[PCI_REVISION_ID] = 0x10;
- pci_conf[PCI_CLASS_PROG] = 0x20;
+ pci_set_byte(&pci_conf[PCI_REVISION_ID], 0x10);
+ pci_set_byte(&pci_conf[PCI_CLASS_PROG], 0x20);
pci_config_set_class(pci_conf, PCI_CLASS_SERIAL_USB);
+ pci_set_byte(&pci_conf[PCI_HEADER_TYPE], PCI_HEADER_TYPE_NORMAL);
- pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;
- pci_conf[PCI_CAPABILITY_LIST] = 0x00; // capabilities pointer
-
- // pci_conf[0x34] = 0x50; // capabilities pointer
+ /* capabilities pointer */
+ pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x00);
+ //pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x50);
- pci_conf[0x3d] = 4; // interrupt pin 3
- pci_conf[0x3e] = 0; // MaxLat
- pci_conf[0x3f] = 0; // MinGnt
+ pci_set_byte(&pci_conf[PCI_INTERRUPT_PIN], 4); // interrupt pin 3
+ pci_set_byte(&pci_conf[PCI_MIN_GNT], 0); // MaxLat
+ pci_set_byte(&pci_conf[PCI_MAX_LAT], 0); // MinGnt
// pci_conf[0x50] = 0x01; // power management caps
- pci_conf[0x60] = 0x20; // SBRN
- pci_conf[0x61] = 0x20; // FLADJ
- pci_conf[0x62] = 0x7f;
- pci_conf[0x63] = 0x00; // PORTWAKECAP
- pci_conf[0x64] = 0x00;
+ pci_set_byte(&pci_conf[0x60], 0x20); // spec release number (2.1.4)
+ pci_set_byte(&pci_conf[0x61], 0x20); // frame length adjustment (2.1.5)
+ pci_set_word(&pci_conf[0x62], 0x00); // port wake up capability (2.1.6)
+
+ pci_conf[0x64] = 0x00;
pci_conf[0x65] = 0x00;
pci_conf[0x66] = 0x00;
pci_conf[0x67] = 0x00;
@@ -2019,20 +2056,19 @@ static int usb_ehci_initfn(PCIDevice *dev)
pci_conf[0x6e] = 0x00;
pci_conf[0x6f] = 0xc0; // USBLEFCTLSTS
- s->mmio[0x00] = OPREGBASE;
- s->mmio[0x01] = 0x00;
- s->mmio[0x02] = 0x00;
- s->mmio[0x03] = 0x01; // HC version
- s->mmio[0x04] = NB_PORTS; // Number of downstream ports
- s->mmio[0x05] = 0x00; // No companion ports at present
- s->mmio[0x06] = 0x00;
- s->mmio[0x07] = 0x00;
- s->mmio[0x08] = 0x80; // We can cache whole frame, not 64-bit capable
- s->mmio[0x09] = 0x68; // EECP
- s->mmio[0x0a] = 0x00;
- s->mmio[0x0b] = 0x00;
-
- s->irq = s->dev.irq[0];
+ // 2.2.2 host controller interface version
+ pci_set_byte(&s->mmio[CAPLENGTH], OPREGBASE);
+ pci_set_word(&s->mmio[HCIVERSION], 0x0100);
+
+ // 2.2.3 host controller structural parameters
+ pci_set_word(&s->mmio[HCSPARAMS], NB_PORTS);
+
+ // 2.2.4 host controller capability parameters
+ // - 0x80 = can cache whole frame, not 64-bit capable
+ pci_set_word(&s->mmio[HCCPARAMS], 0x00000080);
+
+
+ s->irq = s->dev.irq[3];
// TODO - port registration is going to need an overhaul since ports
// can be low, full or high speed and are not tied to UHCI or EHCI.
@@ -2040,7 +2076,7 @@ static int usb_ehci_initfn(PCIDevice *dev)
// list but really all ports need to be owned by EHCI and it should
// hand off to companion controllers if device is full or low speed.
- DEBUG(("ehci init : registering USB ports with no device attached\n"));
+ DPRINTF("ehci_init : registering USB ports with no device attached\n");
// TODO come up with a better port allocation scheme
// added ehci->bus, need to find ehci->DeviceState
@@ -2052,15 +2088,16 @@ static int usb_ehci_initfn(PCIDevice *dev)
s->frame_timer = qemu_new_timer(vm_clock, ehci_frame_timer, s);
+ DPRINTF("ehci_init: calling ehci_reset\n");
qemu_register_reset(ehci_reset, s);
s->mem = cpu_register_io_memory(ehci_readfn, ehci_writefn, s);
- DEBUG(("ehci init : registering MMIO size %d\n", MMIO_SIZE));
+ DPRINTF("ehci_init: registering MMIO size %d\n", MMIO_SIZE);
pci_register_bar(&s->dev, 0, MMIO_SIZE, PCI_BASE_ADDRESS_SPACE_MEMORY,
ehci_map);
- DEBUG(("*** ehci init : under development 16-OCT-08 *** \n"));
+ fprintf(stderr, "\n\n*** EHCI support is under development *** \n\n");
return 0;
}