qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

hcd-dwc2.c (43317B)


      1 /*
      2  * dwc-hsotg (dwc2) USB host controller emulation
      3  *
      4  * Based on hw/usb/hcd-ehci.c and hw/usb/hcd-ohci.c
      5  *
      6  * Note that to use this emulation with the dwc-otg driver in the
      7  * Raspbian kernel, you must pass the option "dwc_otg.fiq_fsm_enable=0"
      8  * on the kernel command line.
      9  *
     10  * Some useful documentation used to develop this emulation can be
     11  * found online (as of April 2020) at:
     12  *
     13  * http://www.capital-micro.com/PDF/CME-M7_Family_User_Guide_EN.pdf
     14  * which has a pretty complete description of the controller starting
     15  * on page 370.
     16  *
     17  * https://sourceforge.net/p/wive-ng/wive-ng-mt/ci/master/tree/docs/DataSheets/RT3050_5x_V2.0_081408_0902.pdf
     18  * which has a description of the controller registers starting on
     19  * page 130.
     20  *
     21  * Copyright (c) 2020 Paul Zimmerman <pauldzim@gmail.com>
     22  *
     23  * This program is free software; you can redistribute it and/or modify
     24  * it under the terms of the GNU General Public License as published by
     25  * the Free Software Foundation; either version 2 of the License, or
     26  * (at your option) any later version.
     27  *
     28  * This program is distributed in the hope that it will be useful,
     29  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     31  * GNU General Public License for more details.
     32  */
     33 
     34 #include "qemu/osdep.h"
     35 #include "qemu/units.h"
     36 #include "qapi/error.h"
     37 #include "hw/usb/dwc2-regs.h"
     38 #include "hw/usb/hcd-dwc2.h"
     39 #include "migration/vmstate.h"
     40 #include "trace.h"
     41 #include "qemu/log.h"
     42 #include "qemu/error-report.h"
     43 #include "qemu/main-loop.h"
     44 #include "hw/qdev-properties.h"
     45 
     46 #define USB_HZ_FS       12000000
     47 #define USB_HZ_HS       96000000
     48 #define USB_FRMINTVL    12000
     49 
     50 /* nifty macros from Arnon's EHCI version  */
     51 #define get_field(data, field) \
     52     (((data) & field##_MASK) >> field##_SHIFT)
     53 
     54 #define set_field(data, newval, field) do { \
     55     uint32_t val = *(data); \
     56     val &= ~field##_MASK; \
     57     val |= ((newval) << field##_SHIFT) & field##_MASK; \
     58     *(data) = val; \
     59 } while (0)
     60 
     61 #define get_bit(data, bitmask) \
     62     (!!((data) & (bitmask)))
     63 
     64 /* update irq line */
     65 static inline void dwc2_update_irq(DWC2State *s)
     66 {
     67     static int oldlevel;
     68     int level = 0;
     69 
     70     if ((s->gintsts & s->gintmsk) && (s->gahbcfg & GAHBCFG_GLBL_INTR_EN)) {
     71         level = 1;
     72     }
     73     if (level != oldlevel) {
     74         oldlevel = level;
     75         trace_usb_dwc2_update_irq(level);
     76         qemu_set_irq(s->irq, level);
     77     }
     78 }
     79 
     80 /* flag interrupt condition */
     81 static inline void dwc2_raise_global_irq(DWC2State *s, uint32_t intr)
     82 {
     83     if (!(s->gintsts & intr)) {
     84         s->gintsts |= intr;
     85         trace_usb_dwc2_raise_global_irq(intr);
     86         dwc2_update_irq(s);
     87     }
     88 }
     89 
     90 static inline void dwc2_lower_global_irq(DWC2State *s, uint32_t intr)
     91 {
     92     if (s->gintsts & intr) {
     93         s->gintsts &= ~intr;
     94         trace_usb_dwc2_lower_global_irq(intr);
     95         dwc2_update_irq(s);
     96     }
     97 }
     98 
     99 static inline void dwc2_raise_host_irq(DWC2State *s, uint32_t host_intr)
    100 {
    101     if (!(s->haint & host_intr)) {
    102         s->haint |= host_intr;
    103         s->haint &= 0xffff;
    104         trace_usb_dwc2_raise_host_irq(host_intr);
    105         if (s->haint & s->haintmsk) {
    106             dwc2_raise_global_irq(s, GINTSTS_HCHINT);
    107         }
    108     }
    109 }
    110 
    111 static inline void dwc2_lower_host_irq(DWC2State *s, uint32_t host_intr)
    112 {
    113     if (s->haint & host_intr) {
    114         s->haint &= ~host_intr;
    115         trace_usb_dwc2_lower_host_irq(host_intr);
    116         if (!(s->haint & s->haintmsk)) {
    117             dwc2_lower_global_irq(s, GINTSTS_HCHINT);
    118         }
    119     }
    120 }
    121 
    122 static inline void dwc2_update_hc_irq(DWC2State *s, int index)
    123 {
    124     uint32_t host_intr = 1 << (index >> 3);
    125 
    126     if (s->hreg1[index + 2] & s->hreg1[index + 3]) {
    127         dwc2_raise_host_irq(s, host_intr);
    128     } else {
    129         dwc2_lower_host_irq(s, host_intr);
    130     }
    131 }
    132 
    133 /* set a timer for EOF */
    134 static void dwc2_eof_timer(DWC2State *s)
    135 {
    136     timer_mod(s->eof_timer, s->sof_time + s->usb_frame_time);
    137 }
    138 
    139 /* Set a timer for EOF and generate SOF event */
    140 static void dwc2_sof(DWC2State *s)
    141 {
    142     s->sof_time += s->usb_frame_time;
    143     trace_usb_dwc2_sof(s->sof_time);
    144     dwc2_eof_timer(s);
    145     dwc2_raise_global_irq(s, GINTSTS_SOF);
    146 }
    147 
    148 /* Do frame processing on frame boundary */
    149 static void dwc2_frame_boundary(void *opaque)
    150 {
    151     DWC2State *s = opaque;
    152     int64_t now;
    153     uint16_t frcnt;
    154 
    155     now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    156 
    157     /* Frame boundary, so do EOF stuff here */
    158 
    159     /* Increment frame number */
    160     frcnt = (uint16_t)((now - s->sof_time) / s->fi);
    161     s->frame_number = (s->frame_number + frcnt) & 0xffff;
    162     s->hfnum = s->frame_number & HFNUM_MAX_FRNUM;
    163 
    164     /* Do SOF stuff here */
    165     dwc2_sof(s);
    166 }
    167 
    168 /* Start sending SOF tokens on the USB bus */
    169 static void dwc2_bus_start(DWC2State *s)
    170 {
    171     trace_usb_dwc2_bus_start();
    172     s->sof_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    173     dwc2_eof_timer(s);
    174 }
    175 
    176 /* Stop sending SOF tokens on the USB bus */
    177 static void dwc2_bus_stop(DWC2State *s)
    178 {
    179     trace_usb_dwc2_bus_stop();
    180     timer_del(s->eof_timer);
    181 }
    182 
    183 static USBDevice *dwc2_find_device(DWC2State *s, uint8_t addr)
    184 {
    185     USBDevice *dev;
    186 
    187     trace_usb_dwc2_find_device(addr);
    188 
    189     if (!(s->hprt0 & HPRT0_ENA)) {
    190         trace_usb_dwc2_port_disabled(0);
    191     } else {
    192         dev = usb_find_device(&s->uport, addr);
    193         if (dev != NULL) {
    194             trace_usb_dwc2_device_found(0);
    195             return dev;
    196         }
    197     }
    198 
    199     trace_usb_dwc2_device_not_found();
    200     return NULL;
    201 }
    202 
    203 static const char *pstatus[] = {
    204     "USB_RET_SUCCESS", "USB_RET_NODEV", "USB_RET_NAK", "USB_RET_STALL",
    205     "USB_RET_BABBLE", "USB_RET_IOERROR", "USB_RET_ASYNC",
    206     "USB_RET_ADD_TO_QUEUE", "USB_RET_REMOVE_FROM_QUEUE"
    207 };
    208 
    209 static uint32_t pintr[] = {
    210     HCINTMSK_XFERCOMPL, HCINTMSK_XACTERR, HCINTMSK_NAK, HCINTMSK_STALL,
    211     HCINTMSK_BBLERR, HCINTMSK_XACTERR, HCINTMSK_XACTERR, HCINTMSK_XACTERR,
    212     HCINTMSK_XACTERR
    213 };
    214 
    215 static const char *types[] = {
    216     "Ctrl", "Isoc", "Bulk", "Intr"
    217 };
    218 
    219 static const char *dirs[] = {
    220     "Out", "In"
    221 };
    222 
    223 static void dwc2_handle_packet(DWC2State *s, uint32_t devadr, USBDevice *dev,
    224                                USBEndpoint *ep, uint32_t index, bool send)
    225 {
    226     DWC2Packet *p;
    227     uint32_t hcchar = s->hreg1[index];
    228     uint32_t hctsiz = s->hreg1[index + 4];
    229     uint32_t hcdma = s->hreg1[index + 5];
    230     uint32_t chan, epnum, epdir, eptype, mps, pid, pcnt, len, tlen, intr = 0;
    231     uint32_t tpcnt, stsidx, actual = 0;
    232     bool do_intr = false, done = false;
    233 
    234     epnum = get_field(hcchar, HCCHAR_EPNUM);
    235     epdir = get_bit(hcchar, HCCHAR_EPDIR);
    236     eptype = get_field(hcchar, HCCHAR_EPTYPE);
    237     mps = get_field(hcchar, HCCHAR_MPS);
    238     pid = get_field(hctsiz, TSIZ_SC_MC_PID);
    239     pcnt = get_field(hctsiz, TSIZ_PKTCNT);
    240     len = get_field(hctsiz, TSIZ_XFERSIZE);
    241     if (len > DWC2_MAX_XFER_SIZE) {
    242         qemu_log_mask(LOG_GUEST_ERROR,
    243                       "%s: HCTSIZ transfer size too large\n", __func__);
    244         return;
    245     }
    246 
    247     chan = index >> 3;
    248     p = &s->packet[chan];
    249 
    250     trace_usb_dwc2_handle_packet(chan, dev, &p->packet, epnum, types[eptype],
    251                                  dirs[epdir], mps, len, pcnt);
    252 
    253     if (mps == 0) {
    254         qemu_log_mask(LOG_GUEST_ERROR,
    255                 "%s: Bad HCCHAR_MPS set to zero\n", __func__);
    256         return;
    257     }
    258 
    259     if (eptype == USB_ENDPOINT_XFER_CONTROL && pid == TSIZ_SC_MC_PID_SETUP) {
    260         pid = USB_TOKEN_SETUP;
    261     } else {
    262         pid = epdir ? USB_TOKEN_IN : USB_TOKEN_OUT;
    263     }
    264 
    265     if (send) {
    266         tlen = len;
    267         if (p->small) {
    268             if (tlen > mps) {
    269                 tlen = mps;
    270             }
    271         }
    272 
    273         if (pid != USB_TOKEN_IN) {
    274             trace_usb_dwc2_memory_read(hcdma, tlen);
    275             if (dma_memory_read(&s->dma_as, hcdma, s->usb_buf[chan], tlen,
    276                                 MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
    277                 qemu_log_mask(LOG_GUEST_ERROR, "%s: dma_memory_read failed\n",
    278                               __func__);
    279             }
    280         }
    281 
    282         usb_packet_init(&p->packet);
    283         usb_packet_setup(&p->packet, pid, ep, 0, hcdma,
    284                          pid != USB_TOKEN_IN, true);
    285         usb_packet_addbuf(&p->packet, s->usb_buf[chan], tlen);
    286         p->async = DWC2_ASYNC_NONE;
    287         usb_handle_packet(dev, &p->packet);
    288     } else {
    289         tlen = p->len;
    290     }
    291 
    292     stsidx = -p->packet.status;
    293     assert(stsidx < sizeof(pstatus) / sizeof(*pstatus));
    294     actual = p->packet.actual_length;
    295     trace_usb_dwc2_packet_status(pstatus[stsidx], actual);
    296 
    297 babble:
    298     if (p->packet.status != USB_RET_SUCCESS &&
    299             p->packet.status != USB_RET_NAK &&
    300             p->packet.status != USB_RET_STALL &&
    301             p->packet.status != USB_RET_ASYNC) {
    302         trace_usb_dwc2_packet_error(pstatus[stsidx]);
    303     }
    304 
    305     if (p->packet.status == USB_RET_ASYNC) {
    306         trace_usb_dwc2_async_packet(&p->packet, chan, dev, epnum,
    307                                     dirs[epdir], tlen);
    308         usb_device_flush_ep_queue(dev, ep);
    309         assert(p->async != DWC2_ASYNC_INFLIGHT);
    310         p->devadr = devadr;
    311         p->epnum = epnum;
    312         p->epdir = epdir;
    313         p->mps = mps;
    314         p->pid = pid;
    315         p->index = index;
    316         p->pcnt = pcnt;
    317         p->len = tlen;
    318         p->async = DWC2_ASYNC_INFLIGHT;
    319         p->needs_service = false;
    320         return;
    321     }
    322 
    323     if (p->packet.status == USB_RET_SUCCESS) {
    324         if (actual > tlen) {
    325             p->packet.status = USB_RET_BABBLE;
    326             goto babble;
    327         }
    328 
    329         if (pid == USB_TOKEN_IN) {
    330             trace_usb_dwc2_memory_write(hcdma, actual);
    331             if (dma_memory_write(&s->dma_as, hcdma, s->usb_buf[chan], actual,
    332                                  MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
    333                 qemu_log_mask(LOG_GUEST_ERROR, "%s: dma_memory_write failed\n",
    334                               __func__);
    335             }
    336         }
    337 
    338         tpcnt = actual / mps;
    339         if (actual % mps) {
    340             tpcnt++;
    341             if (pid == USB_TOKEN_IN) {
    342                 done = true;
    343             }
    344         }
    345 
    346         pcnt -= tpcnt < pcnt ? tpcnt : pcnt;
    347         set_field(&hctsiz, pcnt, TSIZ_PKTCNT);
    348         len -= actual < len ? actual : len;
    349         set_field(&hctsiz, len, TSIZ_XFERSIZE);
    350         s->hreg1[index + 4] = hctsiz;
    351         hcdma += actual;
    352         s->hreg1[index + 5] = hcdma;
    353 
    354         if (!pcnt || len == 0 || actual == 0) {
    355             done = true;
    356         }
    357     } else {
    358         intr |= pintr[stsidx];
    359         if (p->packet.status == USB_RET_NAK &&
    360             (eptype == USB_ENDPOINT_XFER_CONTROL ||
    361              eptype == USB_ENDPOINT_XFER_BULK)) {
    362             /*
    363              * for ctrl/bulk, automatically retry on NAK,
    364              * but send the interrupt anyway
    365              */
    366             intr &= ~HCINTMSK_RESERVED14_31;
    367             s->hreg1[index + 2] |= intr;
    368             do_intr = true;
    369         } else {
    370             intr |= HCINTMSK_CHHLTD;
    371             done = true;
    372         }
    373     }
    374 
    375     usb_packet_cleanup(&p->packet);
    376 
    377     if (done) {
    378         hcchar &= ~HCCHAR_CHENA;
    379         s->hreg1[index] = hcchar;
    380         if (!(intr & HCINTMSK_CHHLTD)) {
    381             intr |= HCINTMSK_CHHLTD | HCINTMSK_XFERCOMPL;
    382         }
    383         intr &= ~HCINTMSK_RESERVED14_31;
    384         s->hreg1[index + 2] |= intr;
    385         p->needs_service = false;
    386         trace_usb_dwc2_packet_done(pstatus[stsidx], actual, len, pcnt);
    387         dwc2_update_hc_irq(s, index);
    388         return;
    389     }
    390 
    391     p->devadr = devadr;
    392     p->epnum = epnum;
    393     p->epdir = epdir;
    394     p->mps = mps;
    395     p->pid = pid;
    396     p->index = index;
    397     p->pcnt = pcnt;
    398     p->len = len;
    399     p->needs_service = true;
    400     trace_usb_dwc2_packet_next(pstatus[stsidx], len, pcnt);
    401     if (do_intr) {
    402         dwc2_update_hc_irq(s, index);
    403     }
    404 }
    405 
    406 /* Attach or detach a device on root hub */
    407 
    408 static const char *speeds[] = {
    409     "low", "full", "high"
    410 };
    411 
    412 static void dwc2_attach(USBPort *port)
    413 {
    414     DWC2State *s = port->opaque;
    415     int hispd = 0;
    416 
    417     trace_usb_dwc2_attach(port);
    418     assert(port->index == 0);
    419 
    420     if (!port->dev || !port->dev->attached) {
    421         return;
    422     }
    423 
    424     assert(port->dev->speed <= USB_SPEED_HIGH);
    425     trace_usb_dwc2_attach_speed(speeds[port->dev->speed]);
    426     s->hprt0 &= ~HPRT0_SPD_MASK;
    427 
    428     switch (port->dev->speed) {
    429     case USB_SPEED_LOW:
    430         s->hprt0 |= HPRT0_SPD_LOW_SPEED << HPRT0_SPD_SHIFT;
    431         break;
    432     case USB_SPEED_FULL:
    433         s->hprt0 |= HPRT0_SPD_FULL_SPEED << HPRT0_SPD_SHIFT;
    434         break;
    435     case USB_SPEED_HIGH:
    436         s->hprt0 |= HPRT0_SPD_HIGH_SPEED << HPRT0_SPD_SHIFT;
    437         hispd = 1;
    438         break;
    439     }
    440 
    441     if (hispd) {
    442         s->usb_frame_time = NANOSECONDS_PER_SECOND / 8000;        /* 125000 */
    443         if (NANOSECONDS_PER_SECOND >= USB_HZ_HS) {
    444             s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_HS; /* 10.4 */
    445         } else {
    446             s->usb_bit_time = 1;
    447         }
    448     } else {
    449         s->usb_frame_time = NANOSECONDS_PER_SECOND / 1000;        /* 1000000 */
    450         if (NANOSECONDS_PER_SECOND >= USB_HZ_FS) {
    451             s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_FS; /* 83.3 */
    452         } else {
    453             s->usb_bit_time = 1;
    454         }
    455     }
    456 
    457     s->fi = USB_FRMINTVL - 1;
    458     s->hprt0 |= HPRT0_CONNDET | HPRT0_CONNSTS;
    459 
    460     dwc2_bus_start(s);
    461     dwc2_raise_global_irq(s, GINTSTS_PRTINT);
    462 }
    463 
    464 static void dwc2_detach(USBPort *port)
    465 {
    466     DWC2State *s = port->opaque;
    467 
    468     trace_usb_dwc2_detach(port);
    469     assert(port->index == 0);
    470 
    471     dwc2_bus_stop(s);
    472 
    473     s->hprt0 &= ~(HPRT0_SPD_MASK | HPRT0_SUSP | HPRT0_ENA | HPRT0_CONNSTS);
    474     s->hprt0 |= HPRT0_CONNDET | HPRT0_ENACHG;
    475 
    476     dwc2_raise_global_irq(s, GINTSTS_PRTINT);
    477 }
    478 
    479 static void dwc2_child_detach(USBPort *port, USBDevice *child)
    480 {
    481     trace_usb_dwc2_child_detach(port, child);
    482     assert(port->index == 0);
    483 }
    484 
    485 static void dwc2_wakeup(USBPort *port)
    486 {
    487     DWC2State *s = port->opaque;
    488 
    489     trace_usb_dwc2_wakeup(port);
    490     assert(port->index == 0);
    491 
    492     if (s->hprt0 & HPRT0_SUSP) {
    493         s->hprt0 |= HPRT0_RES;
    494         dwc2_raise_global_irq(s, GINTSTS_PRTINT);
    495     }
    496 
    497     qemu_bh_schedule(s->async_bh);
    498 }
    499 
    500 static void dwc2_async_packet_complete(USBPort *port, USBPacket *packet)
    501 {
    502     DWC2State *s = port->opaque;
    503     DWC2Packet *p;
    504     USBDevice *dev;
    505     USBEndpoint *ep;
    506 
    507     assert(port->index == 0);
    508     p = container_of(packet, DWC2Packet, packet);
    509     dev = dwc2_find_device(s, p->devadr);
    510     ep = usb_ep_get(dev, p->pid, p->epnum);
    511     trace_usb_dwc2_async_packet_complete(port, packet, p->index >> 3, dev,
    512                                          p->epnum, dirs[p->epdir], p->len);
    513     assert(p->async == DWC2_ASYNC_INFLIGHT);
    514 
    515     if (packet->status == USB_RET_REMOVE_FROM_QUEUE) {
    516         usb_cancel_packet(packet);
    517         usb_packet_cleanup(packet);
    518         return;
    519     }
    520 
    521     dwc2_handle_packet(s, p->devadr, dev, ep, p->index, false);
    522 
    523     p->async = DWC2_ASYNC_FINISHED;
    524     qemu_bh_schedule(s->async_bh);
    525 }
    526 
    527 static USBPortOps dwc2_port_ops = {
    528     .attach = dwc2_attach,
    529     .detach = dwc2_detach,
    530     .child_detach = dwc2_child_detach,
    531     .wakeup = dwc2_wakeup,
    532     .complete = dwc2_async_packet_complete,
    533 };
    534 
    535 static uint32_t dwc2_get_frame_remaining(DWC2State *s)
    536 {
    537     uint32_t fr = 0;
    538     int64_t tks;
    539 
    540     tks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->sof_time;
    541     if (tks < 0) {
    542         tks = 0;
    543     }
    544 
    545     /* avoid muldiv if possible */
    546     if (tks >= s->usb_frame_time) {
    547         goto out;
    548     }
    549     if (tks < s->usb_bit_time) {
    550         fr = s->fi;
    551         goto out;
    552     }
    553 
    554     /* tks = number of ns since SOF, divided by 83 (fs) or 10 (hs) */
    555     tks = tks / s->usb_bit_time;
    556     if (tks >= (int64_t)s->fi) {
    557         goto out;
    558     }
    559 
    560     /* remaining = frame interval minus tks */
    561     fr = (uint32_t)((int64_t)s->fi - tks);
    562 
    563 out:
    564     return fr;
    565 }
    566 
    567 static void dwc2_work_bh(void *opaque)
    568 {
    569     DWC2State *s = opaque;
    570     DWC2Packet *p;
    571     USBDevice *dev;
    572     USBEndpoint *ep;
    573     int64_t t_now, expire_time;
    574     int chan;
    575     bool found = false;
    576 
    577     trace_usb_dwc2_work_bh();
    578     if (s->working) {
    579         return;
    580     }
    581     s->working = true;
    582 
    583     t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    584     chan = s->next_chan;
    585 
    586     do {
    587         p = &s->packet[chan];
    588         if (p->needs_service) {
    589             dev = dwc2_find_device(s, p->devadr);
    590             ep = usb_ep_get(dev, p->pid, p->epnum);
    591             trace_usb_dwc2_work_bh_service(s->next_chan, chan, dev, p->epnum);
    592             dwc2_handle_packet(s, p->devadr, dev, ep, p->index, true);
    593             found = true;
    594         }
    595         if (++chan == DWC2_NB_CHAN) {
    596             chan = 0;
    597         }
    598         if (found) {
    599             s->next_chan = chan;
    600             trace_usb_dwc2_work_bh_next(chan);
    601         }
    602     } while (chan != s->next_chan);
    603 
    604     if (found) {
    605         expire_time = t_now + NANOSECONDS_PER_SECOND / 4000;
    606         timer_mod(s->frame_timer, expire_time);
    607     }
    608     s->working = false;
    609 }
    610 
    611 static void dwc2_enable_chan(DWC2State *s,  uint32_t index)
    612 {
    613     USBDevice *dev;
    614     USBEndpoint *ep;
    615     uint32_t hcchar;
    616     uint32_t hctsiz;
    617     uint32_t devadr, epnum, epdir, eptype, pid, len;
    618     DWC2Packet *p;
    619 
    620     assert((index >> 3) < DWC2_NB_CHAN);
    621     p = &s->packet[index >> 3];
    622     hcchar = s->hreg1[index];
    623     hctsiz = s->hreg1[index + 4];
    624     devadr = get_field(hcchar, HCCHAR_DEVADDR);
    625     epnum = get_field(hcchar, HCCHAR_EPNUM);
    626     epdir = get_bit(hcchar, HCCHAR_EPDIR);
    627     eptype = get_field(hcchar, HCCHAR_EPTYPE);
    628     pid = get_field(hctsiz, TSIZ_SC_MC_PID);
    629     len = get_field(hctsiz, TSIZ_XFERSIZE);
    630 
    631     dev = dwc2_find_device(s, devadr);
    632 
    633     trace_usb_dwc2_enable_chan(index >> 3, dev, &p->packet, epnum);
    634     if (dev == NULL) {
    635         return;
    636     }
    637 
    638     if (eptype == USB_ENDPOINT_XFER_CONTROL && pid == TSIZ_SC_MC_PID_SETUP) {
    639         pid = USB_TOKEN_SETUP;
    640     } else {
    641         pid = epdir ? USB_TOKEN_IN : USB_TOKEN_OUT;
    642     }
    643 
    644     ep = usb_ep_get(dev, pid, epnum);
    645 
    646     /*
    647      * Hack: Networking doesn't like us delivering large transfers, it kind
    648      * of works but the latency is horrible. So if the transfer is <= the mtu
    649      * size, we take that as a hint that this might be a network transfer,
    650      * and do the transfer packet-by-packet.
    651      */
    652     if (len > 1536) {
    653         p->small = false;
    654     } else {
    655         p->small = true;
    656     }
    657 
    658     dwc2_handle_packet(s, devadr, dev, ep, index, true);
    659     qemu_bh_schedule(s->async_bh);
    660 }
    661 
    662 static const char *glbregnm[] = {
    663     "GOTGCTL  ", "GOTGINT  ", "GAHBCFG  ", "GUSBCFG  ", "GRSTCTL  ",
    664     "GINTSTS  ", "GINTMSK  ", "GRXSTSR  ", "GRXSTSP  ", "GRXFSIZ  ",
    665     "GNPTXFSIZ", "GNPTXSTS ", "GI2CCTL  ", "GPVNDCTL ", "GGPIO    ",
    666     "GUID     ", "GSNPSID  ", "GHWCFG1  ", "GHWCFG2  ", "GHWCFG3  ",
    667     "GHWCFG4  ", "GLPMCFG  ", "GPWRDN   ", "GDFIFOCFG", "GADPCTL  ",
    668     "GREFCLK  ", "GINTMSK2 ", "GINTSTS2 "
    669 };
    670 
    671 static uint64_t dwc2_glbreg_read(void *ptr, hwaddr addr, int index,
    672                                  unsigned size)
    673 {
    674     DWC2State *s = ptr;
    675     uint32_t val;
    676 
    677     if (addr > GINTSTS2) {
    678         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
    679                       __func__, addr);
    680         return 0;
    681     }
    682 
    683     val = s->glbreg[index];
    684 
    685     switch (addr) {
    686     case GRSTCTL:
    687         /* clear any self-clearing bits that were set */
    688         val &= ~(GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH | GRSTCTL_IN_TKNQ_FLSH |
    689                  GRSTCTL_FRMCNTRRST | GRSTCTL_HSFTRST | GRSTCTL_CSFTRST);
    690         s->glbreg[index] = val;
    691         break;
    692     default:
    693         break;
    694     }
    695 
    696     trace_usb_dwc2_glbreg_read(addr, glbregnm[index], val);
    697     return val;
    698 }
    699 
    700 static void dwc2_glbreg_write(void *ptr, hwaddr addr, int index, uint64_t val,
    701                               unsigned size)
    702 {
    703     DWC2State *s = ptr;
    704     uint64_t orig = val;
    705     uint32_t *mmio;
    706     uint32_t old;
    707     int iflg = 0;
    708 
    709     if (addr > GINTSTS2) {
    710         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
    711                       __func__, addr);
    712         return;
    713     }
    714 
    715     mmio = &s->glbreg[index];
    716     old = *mmio;
    717 
    718     switch (addr) {
    719     case GOTGCTL:
    720         /* don't allow setting of read-only bits */
    721         val &= ~(GOTGCTL_MULT_VALID_BC_MASK | GOTGCTL_BSESVLD |
    722                  GOTGCTL_ASESVLD | GOTGCTL_DBNC_SHORT | GOTGCTL_CONID_B |
    723                  GOTGCTL_HSTNEGSCS | GOTGCTL_SESREQSCS);
    724         /* don't allow clearing of read-only bits */
    725         val |= old & (GOTGCTL_MULT_VALID_BC_MASK | GOTGCTL_BSESVLD |
    726                       GOTGCTL_ASESVLD | GOTGCTL_DBNC_SHORT | GOTGCTL_CONID_B |
    727                       GOTGCTL_HSTNEGSCS | GOTGCTL_SESREQSCS);
    728         break;
    729     case GAHBCFG:
    730         if ((val & GAHBCFG_GLBL_INTR_EN) && !(old & GAHBCFG_GLBL_INTR_EN)) {
    731             iflg = 1;
    732         }
    733         break;
    734     case GRSTCTL:
    735         val |= GRSTCTL_AHBIDLE;
    736         val &= ~GRSTCTL_DMAREQ;
    737         if (!(old & GRSTCTL_TXFFLSH) && (val & GRSTCTL_TXFFLSH)) {
    738                 /* TODO - TX fifo flush */
    739             qemu_log_mask(LOG_UNIMP, "%s: Tx FIFO flush not implemented\n",
    740                           __func__);
    741         }
    742         if (!(old & GRSTCTL_RXFFLSH) && (val & GRSTCTL_RXFFLSH)) {
    743                 /* TODO - RX fifo flush */
    744             qemu_log_mask(LOG_UNIMP, "%s: Rx FIFO flush not implemented\n",
    745                           __func__);
    746         }
    747         if (!(old & GRSTCTL_IN_TKNQ_FLSH) && (val & GRSTCTL_IN_TKNQ_FLSH)) {
    748                 /* TODO - device IN token queue flush */
    749             qemu_log_mask(LOG_UNIMP, "%s: Token queue flush not implemented\n",
    750                           __func__);
    751         }
    752         if (!(old & GRSTCTL_FRMCNTRRST) && (val & GRSTCTL_FRMCNTRRST)) {
    753                 /* TODO - host frame counter reset */
    754             qemu_log_mask(LOG_UNIMP,
    755                           "%s: Frame counter reset not implemented\n",
    756                           __func__);
    757         }
    758         if (!(old & GRSTCTL_HSFTRST) && (val & GRSTCTL_HSFTRST)) {
    759                 /* TODO - host soft reset */
    760             qemu_log_mask(LOG_UNIMP, "%s: Host soft reset not implemented\n",
    761                           __func__);
    762         }
    763         if (!(old & GRSTCTL_CSFTRST) && (val & GRSTCTL_CSFTRST)) {
    764                 /* TODO - core soft reset */
    765             qemu_log_mask(LOG_UNIMP, "%s: Core soft reset not implemented\n",
    766                           __func__);
    767         }
    768         /* don't allow clearing of self-clearing bits */
    769         val |= old & (GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH |
    770                       GRSTCTL_IN_TKNQ_FLSH | GRSTCTL_FRMCNTRRST |
    771                       GRSTCTL_HSFTRST | GRSTCTL_CSFTRST);
    772         break;
    773     case GINTSTS:
    774         /* clear the write-1-to-clear bits */
    775         val |= ~old;
    776         val = ~val;
    777         /* don't allow clearing of read-only bits */
    778         val |= old & (GINTSTS_PTXFEMP | GINTSTS_HCHINT | GINTSTS_PRTINT |
    779                       GINTSTS_OEPINT | GINTSTS_IEPINT | GINTSTS_GOUTNAKEFF |
    780                       GINTSTS_GINNAKEFF | GINTSTS_NPTXFEMP | GINTSTS_RXFLVL |
    781                       GINTSTS_OTGINT | GINTSTS_CURMODE_HOST);
    782         iflg = 1;
    783         break;
    784     case GINTMSK:
    785         iflg = 1;
    786         break;
    787     default:
    788         break;
    789     }
    790 
    791     trace_usb_dwc2_glbreg_write(addr, glbregnm[index], orig, old, val);
    792     *mmio = val;
    793 
    794     if (iflg) {
    795         dwc2_update_irq(s);
    796     }
    797 }
    798 
    799 static uint64_t dwc2_fszreg_read(void *ptr, hwaddr addr, int index,
    800                                  unsigned size)
    801 {
    802     DWC2State *s = ptr;
    803     uint32_t val;
    804 
    805     if (addr != HPTXFSIZ) {
    806         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
    807                       __func__, addr);
    808         return 0;
    809     }
    810 
    811     val = s->fszreg[index];
    812 
    813     trace_usb_dwc2_fszreg_read(addr, val);
    814     return val;
    815 }
    816 
    817 static void dwc2_fszreg_write(void *ptr, hwaddr addr, int index, uint64_t val,
    818                               unsigned size)
    819 {
    820     DWC2State *s = ptr;
    821     uint64_t orig = val;
    822     uint32_t *mmio;
    823     uint32_t old;
    824 
    825     if (addr != HPTXFSIZ) {
    826         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
    827                       __func__, addr);
    828         return;
    829     }
    830 
    831     mmio = &s->fszreg[index];
    832     old = *mmio;
    833 
    834     trace_usb_dwc2_fszreg_write(addr, orig, old, val);
    835     *mmio = val;
    836 }
    837 
    838 static const char *hreg0nm[] = {
    839     "HCFG     ", "HFIR     ", "HFNUM    ", "<rsvd>   ", "HPTXSTS  ",
    840     "HAINT    ", "HAINTMSK ", "HFLBADDR ", "<rsvd>   ", "<rsvd>   ",
    841     "<rsvd>   ", "<rsvd>   ", "<rsvd>   ", "<rsvd>   ", "<rsvd>   ",
    842     "<rsvd>   ", "HPRT0    "
    843 };
    844 
    845 static uint64_t dwc2_hreg0_read(void *ptr, hwaddr addr, int index,
    846                                 unsigned size)
    847 {
    848     DWC2State *s = ptr;
    849     uint32_t val;
    850 
    851     if (addr < HCFG || addr > HPRT0) {
    852         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
    853                       __func__, addr);
    854         return 0;
    855     }
    856 
    857     val = s->hreg0[index];
    858 
    859     switch (addr) {
    860     case HFNUM:
    861         val = (dwc2_get_frame_remaining(s) << HFNUM_FRREM_SHIFT) |
    862               (s->hfnum << HFNUM_FRNUM_SHIFT);
    863         break;
    864     default:
    865         break;
    866     }
    867 
    868     trace_usb_dwc2_hreg0_read(addr, hreg0nm[index], val);
    869     return val;
    870 }
    871 
    872 static void dwc2_hreg0_write(void *ptr, hwaddr addr, int index, uint64_t val,
    873                              unsigned size)
    874 {
    875     DWC2State *s = ptr;
    876     USBDevice *dev = s->uport.dev;
    877     uint64_t orig = val;
    878     uint32_t *mmio;
    879     uint32_t tval, told, old;
    880     int prst = 0;
    881     int iflg = 0;
    882 
    883     if (addr < HCFG || addr > HPRT0) {
    884         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
    885                       __func__, addr);
    886         return;
    887     }
    888 
    889     mmio = &s->hreg0[index];
    890     old = *mmio;
    891 
    892     switch (addr) {
    893     case HFIR:
    894         break;
    895     case HFNUM:
    896     case HPTXSTS:
    897     case HAINT:
    898         qemu_log_mask(LOG_GUEST_ERROR, "%s: write to read-only register\n",
    899                       __func__);
    900         return;
    901     case HAINTMSK:
    902         val &= 0xffff;
    903         break;
    904     case HPRT0:
    905         /* don't allow clearing of read-only bits */
    906         val |= old & (HPRT0_SPD_MASK | HPRT0_LNSTS_MASK | HPRT0_OVRCURRACT |
    907                       HPRT0_CONNSTS);
    908         /* don't allow clearing of self-clearing bits */
    909         val |= old & (HPRT0_SUSP | HPRT0_RES);
    910         /* don't allow setting of self-setting bits */
    911         if (!(old & HPRT0_ENA) && (val & HPRT0_ENA)) {
    912             val &= ~HPRT0_ENA;
    913         }
    914         /* clear the write-1-to-clear bits */
    915         tval = val & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
    916                       HPRT0_CONNDET);
    917         told = old & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
    918                       HPRT0_CONNDET);
    919         tval |= ~told;
    920         tval = ~tval;
    921         tval &= (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
    922                  HPRT0_CONNDET);
    923         val &= ~(HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_ENA |
    924                  HPRT0_CONNDET);
    925         val |= tval;
    926         if (!(val & HPRT0_RST) && (old & HPRT0_RST)) {
    927             if (dev && dev->attached) {
    928                 val |= HPRT0_ENA | HPRT0_ENACHG;
    929                 prst = 1;
    930             }
    931         }
    932         if (val & (HPRT0_OVRCURRCHG | HPRT0_ENACHG | HPRT0_CONNDET)) {
    933             iflg = 1;
    934         } else {
    935             iflg = -1;
    936         }
    937         break;
    938     default:
    939         break;
    940     }
    941 
    942     if (prst) {
    943         trace_usb_dwc2_hreg0_write(addr, hreg0nm[index], orig, old,
    944                                    val & ~HPRT0_CONNDET);
    945         trace_usb_dwc2_hreg0_action("call usb_port_reset");
    946         usb_port_reset(&s->uport);
    947         val &= ~HPRT0_CONNDET;
    948     } else {
    949         trace_usb_dwc2_hreg0_write(addr, hreg0nm[index], orig, old, val);
    950     }
    951 
    952     *mmio = val;
    953 
    954     if (iflg > 0) {
    955         trace_usb_dwc2_hreg0_action("enable PRTINT");
    956         dwc2_raise_global_irq(s, GINTSTS_PRTINT);
    957     } else if (iflg < 0) {
    958         trace_usb_dwc2_hreg0_action("disable PRTINT");
    959         dwc2_lower_global_irq(s, GINTSTS_PRTINT);
    960     }
    961 }
    962 
    963 static const char *hreg1nm[] = {
    964     "HCCHAR  ", "HCSPLT  ", "HCINT   ", "HCINTMSK", "HCTSIZ  ", "HCDMA   ",
    965     "<rsvd>  ", "HCDMAB  "
    966 };
    967 
    968 static uint64_t dwc2_hreg1_read(void *ptr, hwaddr addr, int index,
    969                                 unsigned size)
    970 {
    971     DWC2State *s = ptr;
    972     uint32_t val;
    973 
    974     if (addr < HCCHAR(0) || addr > HCDMAB(DWC2_NB_CHAN - 1)) {
    975         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
    976                       __func__, addr);
    977         return 0;
    978     }
    979 
    980     val = s->hreg1[index];
    981 
    982     trace_usb_dwc2_hreg1_read(addr, hreg1nm[index & 7], addr >> 5, val);
    983     return val;
    984 }
    985 
    986 static void dwc2_hreg1_write(void *ptr, hwaddr addr, int index, uint64_t val,
    987                              unsigned size)
    988 {
    989     DWC2State *s = ptr;
    990     uint64_t orig = val;
    991     uint32_t *mmio;
    992     uint32_t old;
    993     int iflg = 0;
    994     int enflg = 0;
    995     int disflg = 0;
    996 
    997     if (addr < HCCHAR(0) || addr > HCDMAB(DWC2_NB_CHAN - 1)) {
    998         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
    999                       __func__, addr);
   1000         return;
   1001     }
   1002 
   1003     mmio = &s->hreg1[index];
   1004     old = *mmio;
   1005 
   1006     switch (HSOTG_REG(0x500) + (addr & 0x1c)) {
   1007     case HCCHAR(0):
   1008         if ((val & HCCHAR_CHDIS) && !(old & HCCHAR_CHDIS)) {
   1009             val &= ~(HCCHAR_CHENA | HCCHAR_CHDIS);
   1010             disflg = 1;
   1011         } else {
   1012             val |= old & HCCHAR_CHDIS;
   1013             if ((val & HCCHAR_CHENA) && !(old & HCCHAR_CHENA)) {
   1014                 val &= ~HCCHAR_CHDIS;
   1015                 enflg = 1;
   1016             } else {
   1017                 val |= old & HCCHAR_CHENA;
   1018             }
   1019         }
   1020         break;
   1021     case HCINT(0):
   1022         /* clear the write-1-to-clear bits */
   1023         val |= ~old;
   1024         val = ~val;
   1025         val &= ~HCINTMSK_RESERVED14_31;
   1026         iflg = 1;
   1027         break;
   1028     case HCINTMSK(0):
   1029         val &= ~HCINTMSK_RESERVED14_31;
   1030         iflg = 1;
   1031         break;
   1032     case HCDMAB(0):
   1033         qemu_log_mask(LOG_GUEST_ERROR, "%s: write to read-only register\n",
   1034                       __func__);
   1035         return;
   1036     default:
   1037         break;
   1038     }
   1039 
   1040     trace_usb_dwc2_hreg1_write(addr, hreg1nm[index & 7], index >> 3, orig,
   1041                                old, val);
   1042     *mmio = val;
   1043 
   1044     if (disflg) {
   1045         /* set ChHltd in HCINT */
   1046         s->hreg1[(index & ~7) + 2] |= HCINTMSK_CHHLTD;
   1047         iflg = 1;
   1048     }
   1049 
   1050     if (enflg) {
   1051         dwc2_enable_chan(s, index & ~7);
   1052     }
   1053 
   1054     if (iflg) {
   1055         dwc2_update_hc_irq(s, index & ~7);
   1056     }
   1057 }
   1058 
   1059 static const char *pcgregnm[] = {
   1060         "PCGCTL   ", "PCGCCTL1 "
   1061 };
   1062 
   1063 static uint64_t dwc2_pcgreg_read(void *ptr, hwaddr addr, int index,
   1064                                  unsigned size)
   1065 {
   1066     DWC2State *s = ptr;
   1067     uint32_t val;
   1068 
   1069     if (addr < PCGCTL || addr > PCGCCTL1) {
   1070         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
   1071                       __func__, addr);
   1072         return 0;
   1073     }
   1074 
   1075     val = s->pcgreg[index];
   1076 
   1077     trace_usb_dwc2_pcgreg_read(addr, pcgregnm[index], val);
   1078     return val;
   1079 }
   1080 
   1081 static void dwc2_pcgreg_write(void *ptr, hwaddr addr, int index,
   1082                               uint64_t val, unsigned size)
   1083 {
   1084     DWC2State *s = ptr;
   1085     uint64_t orig = val;
   1086     uint32_t *mmio;
   1087     uint32_t old;
   1088 
   1089     if (addr < PCGCTL || addr > PCGCCTL1) {
   1090         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n",
   1091                       __func__, addr);
   1092         return;
   1093     }
   1094 
   1095     mmio = &s->pcgreg[index];
   1096     old = *mmio;
   1097 
   1098     trace_usb_dwc2_pcgreg_write(addr, pcgregnm[index], orig, old, val);
   1099     *mmio = val;
   1100 }
   1101 
   1102 static uint64_t dwc2_hsotg_read(void *ptr, hwaddr addr, unsigned size)
   1103 {
   1104     uint64_t val;
   1105 
   1106     switch (addr) {
   1107     case HSOTG_REG(0x000) ... HSOTG_REG(0x0fc):
   1108         val = dwc2_glbreg_read(ptr, addr, (addr - HSOTG_REG(0x000)) >> 2, size);
   1109         break;
   1110     case HSOTG_REG(0x100):
   1111         val = dwc2_fszreg_read(ptr, addr, (addr - HSOTG_REG(0x100)) >> 2, size);
   1112         break;
   1113     case HSOTG_REG(0x104) ... HSOTG_REG(0x3fc):
   1114         /* Gadget-mode registers, just return 0 for now */
   1115         val = 0;
   1116         break;
   1117     case HSOTG_REG(0x400) ... HSOTG_REG(0x4fc):
   1118         val = dwc2_hreg0_read(ptr, addr, (addr - HSOTG_REG(0x400)) >> 2, size);
   1119         break;
   1120     case HSOTG_REG(0x500) ... HSOTG_REG(0x7fc):
   1121         val = dwc2_hreg1_read(ptr, addr, (addr - HSOTG_REG(0x500)) >> 2, size);
   1122         break;
   1123     case HSOTG_REG(0x800) ... HSOTG_REG(0xdfc):
   1124         /* Gadget-mode registers, just return 0 for now */
   1125         val = 0;
   1126         break;
   1127     case HSOTG_REG(0xe00) ... HSOTG_REG(0xffc):
   1128         val = dwc2_pcgreg_read(ptr, addr, (addr - HSOTG_REG(0xe00)) >> 2, size);
   1129         break;
   1130     default:
   1131         g_assert_not_reached();
   1132     }
   1133 
   1134     return val;
   1135 }
   1136 
   1137 static void dwc2_hsotg_write(void *ptr, hwaddr addr, uint64_t val,
   1138                              unsigned size)
   1139 {
   1140     switch (addr) {
   1141     case HSOTG_REG(0x000) ... HSOTG_REG(0x0fc):
   1142         dwc2_glbreg_write(ptr, addr, (addr - HSOTG_REG(0x000)) >> 2, val, size);
   1143         break;
   1144     case HSOTG_REG(0x100):
   1145         dwc2_fszreg_write(ptr, addr, (addr - HSOTG_REG(0x100)) >> 2, val, size);
   1146         break;
   1147     case HSOTG_REG(0x104) ... HSOTG_REG(0x3fc):
   1148         /* Gadget-mode registers, do nothing for now */
   1149         break;
   1150     case HSOTG_REG(0x400) ... HSOTG_REG(0x4fc):
   1151         dwc2_hreg0_write(ptr, addr, (addr - HSOTG_REG(0x400)) >> 2, val, size);
   1152         break;
   1153     case HSOTG_REG(0x500) ... HSOTG_REG(0x7fc):
   1154         dwc2_hreg1_write(ptr, addr, (addr - HSOTG_REG(0x500)) >> 2, val, size);
   1155         break;
   1156     case HSOTG_REG(0x800) ... HSOTG_REG(0xdfc):
   1157         /* Gadget-mode registers, do nothing for now */
   1158         break;
   1159     case HSOTG_REG(0xe00) ... HSOTG_REG(0xffc):
   1160         dwc2_pcgreg_write(ptr, addr, (addr - HSOTG_REG(0xe00)) >> 2, val, size);
   1161         break;
   1162     default:
   1163         g_assert_not_reached();
   1164     }
   1165 }
   1166 
   1167 static const MemoryRegionOps dwc2_mmio_hsotg_ops = {
   1168     .read = dwc2_hsotg_read,
   1169     .write = dwc2_hsotg_write,
   1170     .impl.min_access_size = 4,
   1171     .impl.max_access_size = 4,
   1172     .endianness = DEVICE_LITTLE_ENDIAN,
   1173 };
   1174 
   1175 static uint64_t dwc2_hreg2_read(void *ptr, hwaddr addr, unsigned size)
   1176 {
   1177     /* TODO - implement FIFOs to support slave mode */
   1178     trace_usb_dwc2_hreg2_read(addr, addr >> 12, 0);
   1179     qemu_log_mask(LOG_UNIMP, "%s: FIFO read not implemented\n", __func__);
   1180     return 0;
   1181 }
   1182 
   1183 static void dwc2_hreg2_write(void *ptr, hwaddr addr, uint64_t val,
   1184                              unsigned size)
   1185 {
   1186     uint64_t orig = val;
   1187 
   1188     /* TODO - implement FIFOs to support slave mode */
   1189     trace_usb_dwc2_hreg2_write(addr, addr >> 12, orig, 0, val);
   1190     qemu_log_mask(LOG_UNIMP, "%s: FIFO write not implemented\n", __func__);
   1191 }
   1192 
   1193 static const MemoryRegionOps dwc2_mmio_hreg2_ops = {
   1194     .read = dwc2_hreg2_read,
   1195     .write = dwc2_hreg2_write,
   1196     .impl.min_access_size = 4,
   1197     .impl.max_access_size = 4,
   1198     .endianness = DEVICE_LITTLE_ENDIAN,
   1199 };
   1200 
   1201 static void dwc2_wakeup_endpoint(USBBus *bus, USBEndpoint *ep,
   1202                                  unsigned int stream)
   1203 {
   1204     DWC2State *s = container_of(bus, DWC2State, bus);
   1205 
   1206     trace_usb_dwc2_wakeup_endpoint(ep, stream);
   1207 
   1208     /* TODO - do something here? */
   1209     qemu_bh_schedule(s->async_bh);
   1210 }
   1211 
   1212 static USBBusOps dwc2_bus_ops = {
   1213     .wakeup_endpoint = dwc2_wakeup_endpoint,
   1214 };
   1215 
   1216 static void dwc2_work_timer(void *opaque)
   1217 {
   1218     DWC2State *s = opaque;
   1219 
   1220     trace_usb_dwc2_work_timer();
   1221     qemu_bh_schedule(s->async_bh);
   1222 }
   1223 
   1224 static void dwc2_reset_enter(Object *obj, ResetType type)
   1225 {
   1226     DWC2Class *c = DWC2_USB_GET_CLASS(obj);
   1227     DWC2State *s = DWC2_USB(obj);
   1228     int i;
   1229 
   1230     trace_usb_dwc2_reset_enter();
   1231 
   1232     if (c->parent_phases.enter) {
   1233         c->parent_phases.enter(obj, type);
   1234     }
   1235 
   1236     timer_del(s->frame_timer);
   1237     qemu_bh_cancel(s->async_bh);
   1238 
   1239     if (s->uport.dev && s->uport.dev->attached) {
   1240         usb_detach(&s->uport);
   1241     }
   1242 
   1243     dwc2_bus_stop(s);
   1244 
   1245     s->gotgctl = GOTGCTL_BSESVLD | GOTGCTL_ASESVLD | GOTGCTL_CONID_B;
   1246     s->gotgint = 0;
   1247     s->gahbcfg = 0;
   1248     s->gusbcfg = 5 << GUSBCFG_USBTRDTIM_SHIFT;
   1249     s->grstctl = GRSTCTL_AHBIDLE;
   1250     s->gintsts = GINTSTS_CONIDSTSCHNG | GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP |
   1251                  GINTSTS_CURMODE_HOST;
   1252     s->gintmsk = 0;
   1253     s->grxstsr = 0;
   1254     s->grxstsp = 0;
   1255     s->grxfsiz = 1024;
   1256     s->gnptxfsiz = 1024 << FIFOSIZE_DEPTH_SHIFT;
   1257     s->gnptxsts = (4 << FIFOSIZE_DEPTH_SHIFT) | 1024;
   1258     s->gi2cctl = GI2CCTL_I2CDATSE0 | GI2CCTL_ACK;
   1259     s->gpvndctl = 0;
   1260     s->ggpio = 0;
   1261     s->guid = 0;
   1262     s->gsnpsid = 0x4f54294a;
   1263     s->ghwcfg1 = 0;
   1264     s->ghwcfg2 = (8 << GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT) |
   1265                  (4 << GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT) |
   1266                  (4 << GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT) |
   1267                  GHWCFG2_DYNAMIC_FIFO |
   1268                  GHWCFG2_PERIO_EP_SUPPORTED |
   1269                  ((DWC2_NB_CHAN - 1) << GHWCFG2_NUM_HOST_CHAN_SHIFT) |
   1270                  (GHWCFG2_INT_DMA_ARCH << GHWCFG2_ARCHITECTURE_SHIFT) |
   1271                  (GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST << GHWCFG2_OP_MODE_SHIFT);
   1272     s->ghwcfg3 = (4096 << GHWCFG3_DFIFO_DEPTH_SHIFT) |
   1273                  (4 << GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT) |
   1274                  (4 << GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT);
   1275     s->ghwcfg4 = 0;
   1276     s->glpmcfg = 0;
   1277     s->gpwrdn = GPWRDN_PWRDNRSTN;
   1278     s->gdfifocfg = 0;
   1279     s->gadpctl = 0;
   1280     s->grefclk = 0;
   1281     s->gintmsk2 = 0;
   1282     s->gintsts2 = 0;
   1283 
   1284     s->hptxfsiz = 500 << FIFOSIZE_DEPTH_SHIFT;
   1285 
   1286     s->hcfg = 2 << HCFG_RESVALID_SHIFT;
   1287     s->hfir = 60000;
   1288     s->hfnum = 0x3fff;
   1289     s->hptxsts = (16 << TXSTS_QSPCAVAIL_SHIFT) | 32768;
   1290     s->haint = 0;
   1291     s->haintmsk = 0;
   1292     s->hprt0 = 0;
   1293 
   1294     memset(s->hreg1, 0, sizeof(s->hreg1));
   1295     memset(s->pcgreg, 0, sizeof(s->pcgreg));
   1296 
   1297     s->sof_time = 0;
   1298     s->frame_number = 0;
   1299     s->fi = USB_FRMINTVL - 1;
   1300     s->next_chan = 0;
   1301     s->working = false;
   1302 
   1303     for (i = 0; i < DWC2_NB_CHAN; i++) {
   1304         s->packet[i].needs_service = false;
   1305     }
   1306 }
   1307 
   1308 static void dwc2_reset_hold(Object *obj)
   1309 {
   1310     DWC2Class *c = DWC2_USB_GET_CLASS(obj);
   1311     DWC2State *s = DWC2_USB(obj);
   1312 
   1313     trace_usb_dwc2_reset_hold();
   1314 
   1315     if (c->parent_phases.hold) {
   1316         c->parent_phases.hold(obj);
   1317     }
   1318 
   1319     dwc2_update_irq(s);
   1320 }
   1321 
   1322 static void dwc2_reset_exit(Object *obj)
   1323 {
   1324     DWC2Class *c = DWC2_USB_GET_CLASS(obj);
   1325     DWC2State *s = DWC2_USB(obj);
   1326 
   1327     trace_usb_dwc2_reset_exit();
   1328 
   1329     if (c->parent_phases.exit) {
   1330         c->parent_phases.exit(obj);
   1331     }
   1332 
   1333     s->hprt0 = HPRT0_PWR;
   1334     if (s->uport.dev && s->uport.dev->attached) {
   1335         usb_attach(&s->uport);
   1336         usb_device_reset(s->uport.dev);
   1337     }
   1338 }
   1339 
   1340 static void dwc2_realize(DeviceState *dev, Error **errp)
   1341 {
   1342     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
   1343     DWC2State *s = DWC2_USB(dev);
   1344     Object *obj;
   1345 
   1346     obj = object_property_get_link(OBJECT(dev), "dma-mr", &error_abort);
   1347 
   1348     s->dma_mr = MEMORY_REGION(obj);
   1349     address_space_init(&s->dma_as, s->dma_mr, "dwc2");
   1350 
   1351     usb_bus_new(&s->bus, sizeof(s->bus), &dwc2_bus_ops, dev);
   1352     usb_register_port(&s->bus, &s->uport, s, 0, &dwc2_port_ops,
   1353                       USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL |
   1354                       (s->usb_version == 2 ? USB_SPEED_MASK_HIGH : 0));
   1355     s->uport.dev = 0;
   1356 
   1357     s->usb_frame_time = NANOSECONDS_PER_SECOND / 1000;          /* 1000000 */
   1358     if (NANOSECONDS_PER_SECOND >= USB_HZ_FS) {
   1359         s->usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ_FS;   /* 83.3 */
   1360     } else {
   1361         s->usb_bit_time = 1;
   1362     }
   1363 
   1364     s->fi = USB_FRMINTVL - 1;
   1365     s->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_frame_boundary, s);
   1366     s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_work_timer, s);
   1367     s->async_bh = qemu_bh_new(dwc2_work_bh, s);
   1368 
   1369     sysbus_init_irq(sbd, &s->irq);
   1370 }
   1371 
   1372 static void dwc2_init(Object *obj)
   1373 {
   1374     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
   1375     DWC2State *s = DWC2_USB(obj);
   1376 
   1377     memory_region_init(&s->container, obj, "dwc2", DWC2_MMIO_SIZE);
   1378     sysbus_init_mmio(sbd, &s->container);
   1379 
   1380     memory_region_init_io(&s->hsotg, obj, &dwc2_mmio_hsotg_ops, s,
   1381                           "dwc2-io", 4 * KiB);
   1382     memory_region_add_subregion(&s->container, 0x0000, &s->hsotg);
   1383 
   1384     memory_region_init_io(&s->fifos, obj, &dwc2_mmio_hreg2_ops, s,
   1385                           "dwc2-fifo", 64 * KiB);
   1386     memory_region_add_subregion(&s->container, 0x1000, &s->fifos);
   1387 }
   1388 
   1389 static const VMStateDescription vmstate_dwc2_state_packet = {
   1390     .name = "dwc2/packet",
   1391     .version_id = 1,
   1392     .minimum_version_id = 1,
   1393     .fields = (VMStateField[]) {
   1394         VMSTATE_UINT32(devadr, DWC2Packet),
   1395         VMSTATE_UINT32(epnum, DWC2Packet),
   1396         VMSTATE_UINT32(epdir, DWC2Packet),
   1397         VMSTATE_UINT32(mps, DWC2Packet),
   1398         VMSTATE_UINT32(pid, DWC2Packet),
   1399         VMSTATE_UINT32(index, DWC2Packet),
   1400         VMSTATE_UINT32(pcnt, DWC2Packet),
   1401         VMSTATE_UINT32(len, DWC2Packet),
   1402         VMSTATE_INT32(async, DWC2Packet),
   1403         VMSTATE_BOOL(small, DWC2Packet),
   1404         VMSTATE_BOOL(needs_service, DWC2Packet),
   1405         VMSTATE_END_OF_LIST()
   1406     },
   1407 };
   1408 
   1409 const VMStateDescription vmstate_dwc2_state = {
   1410     .name = "dwc2",
   1411     .version_id = 1,
   1412     .minimum_version_id = 1,
   1413     .fields = (VMStateField[]) {
   1414         VMSTATE_UINT32_ARRAY(glbreg, DWC2State,
   1415                              DWC2_GLBREG_SIZE / sizeof(uint32_t)),
   1416         VMSTATE_UINT32_ARRAY(fszreg, DWC2State,
   1417                              DWC2_FSZREG_SIZE / sizeof(uint32_t)),
   1418         VMSTATE_UINT32_ARRAY(hreg0, DWC2State,
   1419                              DWC2_HREG0_SIZE / sizeof(uint32_t)),
   1420         VMSTATE_UINT32_ARRAY(hreg1, DWC2State,
   1421                              DWC2_HREG1_SIZE / sizeof(uint32_t)),
   1422         VMSTATE_UINT32_ARRAY(pcgreg, DWC2State,
   1423                              DWC2_PCGREG_SIZE / sizeof(uint32_t)),
   1424 
   1425         VMSTATE_TIMER_PTR(eof_timer, DWC2State),
   1426         VMSTATE_TIMER_PTR(frame_timer, DWC2State),
   1427         VMSTATE_INT64(sof_time, DWC2State),
   1428         VMSTATE_INT64(usb_frame_time, DWC2State),
   1429         VMSTATE_INT64(usb_bit_time, DWC2State),
   1430         VMSTATE_UINT32(usb_version, DWC2State),
   1431         VMSTATE_UINT16(frame_number, DWC2State),
   1432         VMSTATE_UINT16(fi, DWC2State),
   1433         VMSTATE_UINT16(next_chan, DWC2State),
   1434         VMSTATE_BOOL(working, DWC2State),
   1435 
   1436         VMSTATE_STRUCT_ARRAY(packet, DWC2State, DWC2_NB_CHAN, 1,
   1437                              vmstate_dwc2_state_packet, DWC2Packet),
   1438         VMSTATE_UINT8_2DARRAY(usb_buf, DWC2State, DWC2_NB_CHAN,
   1439                               DWC2_MAX_XFER_SIZE),
   1440 
   1441         VMSTATE_END_OF_LIST()
   1442     }
   1443 };
   1444 
   1445 static Property dwc2_usb_properties[] = {
   1446     DEFINE_PROP_UINT32("usb_version", DWC2State, usb_version, 2),
   1447     DEFINE_PROP_END_OF_LIST(),
   1448 };
   1449 
   1450 static void dwc2_class_init(ObjectClass *klass, void *data)
   1451 {
   1452     DeviceClass *dc = DEVICE_CLASS(klass);
   1453     DWC2Class *c = DWC2_USB_CLASS(klass);
   1454     ResettableClass *rc = RESETTABLE_CLASS(klass);
   1455 
   1456     dc->realize = dwc2_realize;
   1457     dc->vmsd = &vmstate_dwc2_state;
   1458     set_bit(DEVICE_CATEGORY_USB, dc->categories);
   1459     device_class_set_props(dc, dwc2_usb_properties);
   1460     resettable_class_set_parent_phases(rc, dwc2_reset_enter, dwc2_reset_hold,
   1461                                        dwc2_reset_exit, &c->parent_phases);
   1462 }
   1463 
   1464 static const TypeInfo dwc2_usb_type_info = {
   1465     .name          = TYPE_DWC2_USB,
   1466     .parent        = TYPE_SYS_BUS_DEVICE,
   1467     .instance_size = sizeof(DWC2State),
   1468     .instance_init = dwc2_init,
   1469     .class_size    = sizeof(DWC2Class),
   1470     .class_init    = dwc2_class_init,
   1471 };
   1472 
   1473 static void dwc2_usb_register_types(void)
   1474 {
   1475     type_register_static(&dwc2_usb_type_info);
   1476 }
   1477 
   1478 type_init(dwc2_usb_register_types)