cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

hcd-dwc2.c (43269B)


      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 */
     65static 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 */
     81static 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
     90static 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
     99static 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
    111static 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
    122static 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 */
    134static 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 */
    140static 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 */
    149static 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 */
    169static 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 */
    177static void dwc2_bus_stop(DWC2State *s)
    178{
    179    trace_usb_dwc2_bus_stop();
    180    timer_del(s->eof_timer);
    181}
    182
    183static 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
    203static 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
    209static 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
    215static const char *types[] = {
    216    "Ctrl", "Isoc", "Bulk", "Intr"
    217};
    218
    219static const char *dirs[] = {
    220    "Out", "In"
    221};
    222
    223static 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,
    276                                s->usb_buf[chan], tlen) != 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
    297babble:
    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],
    332                                 actual) != 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
    408static const char *speeds[] = {
    409    "low", "full", "high"
    410};
    411
    412static 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
    464static 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
    479static void dwc2_child_detach(USBPort *port, USBDevice *child)
    480{
    481    trace_usb_dwc2_child_detach(port, child);
    482    assert(port->index == 0);
    483}
    484
    485static 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
    500static 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
    527static 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
    535static 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
    563out:
    564    return fr;
    565}
    566
    567static 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
    611static 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
    662static 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
    671static 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
    700static 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
    799static 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
    817static 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
    838static 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
    845static 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
    872static 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
    963static const char *hreg1nm[] = {
    964    "HCCHAR  ", "HCSPLT  ", "HCINT   ", "HCINTMSK", "HCTSIZ  ", "HCDMA   ",
    965    "<rsvd>  ", "HCDMAB  "
    966};
    967
    968static 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
    986static 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
   1059static const char *pcgregnm[] = {
   1060        "PCGCTL   ", "PCGCCTL1 "
   1061};
   1062
   1063static 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
   1081static 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
   1102static 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
   1137static 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
   1167static 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
   1175static 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
   1183static 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
   1193static 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
   1201static 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
   1212static USBBusOps dwc2_bus_ops = {
   1213    .wakeup_endpoint = dwc2_wakeup_endpoint,
   1214};
   1215
   1216static 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
   1224static 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
   1308static 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
   1322static 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
   1340static 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
   1372static 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
   1389static 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
   1409const 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
   1445static Property dwc2_usb_properties[] = {
   1446    DEFINE_PROP_UINT32("usb_version", DWC2State, usb_version, 2),
   1447    DEFINE_PROP_END_OF_LIST(),
   1448};
   1449
   1450static 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
   1464static 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
   1473static void dwc2_usb_register_types(void)
   1474{
   1475    type_register_static(&dwc2_usb_type_info);
   1476}
   1477
   1478type_init(dwc2_usb_register_types)