1*0bbb2f3dSGerd Hoffmann /* 2*0bbb2f3dSGerd Hoffmann * USB xHCI controller emulation 3*0bbb2f3dSGerd Hoffmann * 4*0bbb2f3dSGerd Hoffmann * Copyright (c) 2011 Securiforest 5*0bbb2f3dSGerd Hoffmann * Date: 2011-05-11 ; Author: Hector Martin <hector@marcansoft.com> 6*0bbb2f3dSGerd Hoffmann * Based on usb-ohci.c, emulates Renesas NEC USB 3.0 7*0bbb2f3dSGerd Hoffmann * 8*0bbb2f3dSGerd Hoffmann * This library is free software; you can redistribute it and/or 9*0bbb2f3dSGerd Hoffmann * modify it under the terms of the GNU Lesser General Public 10*0bbb2f3dSGerd Hoffmann * License as published by the Free Software Foundation; either 11*0bbb2f3dSGerd Hoffmann * version 2 of the License, or (at your option) any later version. 12*0bbb2f3dSGerd Hoffmann * 13*0bbb2f3dSGerd Hoffmann * This library is distributed in the hope that it will be useful, 14*0bbb2f3dSGerd Hoffmann * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*0bbb2f3dSGerd Hoffmann * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16*0bbb2f3dSGerd Hoffmann * Lesser General Public License for more details. 17*0bbb2f3dSGerd Hoffmann * 18*0bbb2f3dSGerd Hoffmann * You should have received a copy of the GNU Lesser General Public 19*0bbb2f3dSGerd Hoffmann * License along with this library; if not, see <http://www.gnu.org/licenses/>. 20*0bbb2f3dSGerd Hoffmann */ 21*0bbb2f3dSGerd Hoffmann 22*0bbb2f3dSGerd Hoffmann #define TYPE_XHCI "base-xhci" 23*0bbb2f3dSGerd Hoffmann #define TYPE_NEC_XHCI "nec-usb-xhci" 24*0bbb2f3dSGerd Hoffmann #define TYPE_QEMU_XHCI "qemu-xhci" 25*0bbb2f3dSGerd Hoffmann 26*0bbb2f3dSGerd Hoffmann #define XHCI(obj) \ 27*0bbb2f3dSGerd Hoffmann OBJECT_CHECK(XHCIState, (obj), TYPE_XHCI) 28*0bbb2f3dSGerd Hoffmann 29*0bbb2f3dSGerd Hoffmann #define MAXPORTS_2 15 30*0bbb2f3dSGerd Hoffmann #define MAXPORTS_3 15 31*0bbb2f3dSGerd Hoffmann 32*0bbb2f3dSGerd Hoffmann #define MAXPORTS (MAXPORTS_2 + MAXPORTS_3) 33*0bbb2f3dSGerd Hoffmann #define MAXSLOTS 64 34*0bbb2f3dSGerd Hoffmann #define MAXINTRS 16 35*0bbb2f3dSGerd Hoffmann 36*0bbb2f3dSGerd Hoffmann /* Very pessimistic, let's hope it's enough for all cases */ 37*0bbb2f3dSGerd Hoffmann #define EV_QUEUE (((3 * 24) + 16) * MAXSLOTS) 38*0bbb2f3dSGerd Hoffmann 39*0bbb2f3dSGerd Hoffmann typedef struct XHCIState XHCIState; 40*0bbb2f3dSGerd Hoffmann typedef struct XHCIStreamContext XHCIStreamContext; 41*0bbb2f3dSGerd Hoffmann typedef struct XHCIEPContext XHCIEPContext; 42*0bbb2f3dSGerd Hoffmann 43*0bbb2f3dSGerd Hoffmann enum xhci_flags { 44*0bbb2f3dSGerd Hoffmann XHCI_FLAG_SS_FIRST = 1, 45*0bbb2f3dSGerd Hoffmann XHCI_FLAG_FORCE_PCIE_ENDCAP, 46*0bbb2f3dSGerd Hoffmann XHCI_FLAG_ENABLE_STREAMS, 47*0bbb2f3dSGerd Hoffmann }; 48*0bbb2f3dSGerd Hoffmann 49*0bbb2f3dSGerd Hoffmann typedef enum TRBType { 50*0bbb2f3dSGerd Hoffmann TRB_RESERVED = 0, 51*0bbb2f3dSGerd Hoffmann TR_NORMAL, 52*0bbb2f3dSGerd Hoffmann TR_SETUP, 53*0bbb2f3dSGerd Hoffmann TR_DATA, 54*0bbb2f3dSGerd Hoffmann TR_STATUS, 55*0bbb2f3dSGerd Hoffmann TR_ISOCH, 56*0bbb2f3dSGerd Hoffmann TR_LINK, 57*0bbb2f3dSGerd Hoffmann TR_EVDATA, 58*0bbb2f3dSGerd Hoffmann TR_NOOP, 59*0bbb2f3dSGerd Hoffmann CR_ENABLE_SLOT, 60*0bbb2f3dSGerd Hoffmann CR_DISABLE_SLOT, 61*0bbb2f3dSGerd Hoffmann CR_ADDRESS_DEVICE, 62*0bbb2f3dSGerd Hoffmann CR_CONFIGURE_ENDPOINT, 63*0bbb2f3dSGerd Hoffmann CR_EVALUATE_CONTEXT, 64*0bbb2f3dSGerd Hoffmann CR_RESET_ENDPOINT, 65*0bbb2f3dSGerd Hoffmann CR_STOP_ENDPOINT, 66*0bbb2f3dSGerd Hoffmann CR_SET_TR_DEQUEUE, 67*0bbb2f3dSGerd Hoffmann CR_RESET_DEVICE, 68*0bbb2f3dSGerd Hoffmann CR_FORCE_EVENT, 69*0bbb2f3dSGerd Hoffmann CR_NEGOTIATE_BW, 70*0bbb2f3dSGerd Hoffmann CR_SET_LATENCY_TOLERANCE, 71*0bbb2f3dSGerd Hoffmann CR_GET_PORT_BANDWIDTH, 72*0bbb2f3dSGerd Hoffmann CR_FORCE_HEADER, 73*0bbb2f3dSGerd Hoffmann CR_NOOP, 74*0bbb2f3dSGerd Hoffmann ER_TRANSFER = 32, 75*0bbb2f3dSGerd Hoffmann ER_COMMAND_COMPLETE, 76*0bbb2f3dSGerd Hoffmann ER_PORT_STATUS_CHANGE, 77*0bbb2f3dSGerd Hoffmann ER_BANDWIDTH_REQUEST, 78*0bbb2f3dSGerd Hoffmann ER_DOORBELL, 79*0bbb2f3dSGerd Hoffmann ER_HOST_CONTROLLER, 80*0bbb2f3dSGerd Hoffmann ER_DEVICE_NOTIFICATION, 81*0bbb2f3dSGerd Hoffmann ER_MFINDEX_WRAP, 82*0bbb2f3dSGerd Hoffmann /* vendor specific bits */ 83*0bbb2f3dSGerd Hoffmann CR_VENDOR_NEC_FIRMWARE_REVISION = 49, 84*0bbb2f3dSGerd Hoffmann CR_VENDOR_NEC_CHALLENGE_RESPONSE = 50, 85*0bbb2f3dSGerd Hoffmann } TRBType; 86*0bbb2f3dSGerd Hoffmann 87*0bbb2f3dSGerd Hoffmann typedef enum TRBCCode { 88*0bbb2f3dSGerd Hoffmann CC_INVALID = 0, 89*0bbb2f3dSGerd Hoffmann CC_SUCCESS, 90*0bbb2f3dSGerd Hoffmann CC_DATA_BUFFER_ERROR, 91*0bbb2f3dSGerd Hoffmann CC_BABBLE_DETECTED, 92*0bbb2f3dSGerd Hoffmann CC_USB_TRANSACTION_ERROR, 93*0bbb2f3dSGerd Hoffmann CC_TRB_ERROR, 94*0bbb2f3dSGerd Hoffmann CC_STALL_ERROR, 95*0bbb2f3dSGerd Hoffmann CC_RESOURCE_ERROR, 96*0bbb2f3dSGerd Hoffmann CC_BANDWIDTH_ERROR, 97*0bbb2f3dSGerd Hoffmann CC_NO_SLOTS_ERROR, 98*0bbb2f3dSGerd Hoffmann CC_INVALID_STREAM_TYPE_ERROR, 99*0bbb2f3dSGerd Hoffmann CC_SLOT_NOT_ENABLED_ERROR, 100*0bbb2f3dSGerd Hoffmann CC_EP_NOT_ENABLED_ERROR, 101*0bbb2f3dSGerd Hoffmann CC_SHORT_PACKET, 102*0bbb2f3dSGerd Hoffmann CC_RING_UNDERRUN, 103*0bbb2f3dSGerd Hoffmann CC_RING_OVERRUN, 104*0bbb2f3dSGerd Hoffmann CC_VF_ER_FULL, 105*0bbb2f3dSGerd Hoffmann CC_PARAMETER_ERROR, 106*0bbb2f3dSGerd Hoffmann CC_BANDWIDTH_OVERRUN, 107*0bbb2f3dSGerd Hoffmann CC_CONTEXT_STATE_ERROR, 108*0bbb2f3dSGerd Hoffmann CC_NO_PING_RESPONSE_ERROR, 109*0bbb2f3dSGerd Hoffmann CC_EVENT_RING_FULL_ERROR, 110*0bbb2f3dSGerd Hoffmann CC_INCOMPATIBLE_DEVICE_ERROR, 111*0bbb2f3dSGerd Hoffmann CC_MISSED_SERVICE_ERROR, 112*0bbb2f3dSGerd Hoffmann CC_COMMAND_RING_STOPPED, 113*0bbb2f3dSGerd Hoffmann CC_COMMAND_ABORTED, 114*0bbb2f3dSGerd Hoffmann CC_STOPPED, 115*0bbb2f3dSGerd Hoffmann CC_STOPPED_LENGTH_INVALID, 116*0bbb2f3dSGerd Hoffmann CC_MAX_EXIT_LATENCY_TOO_LARGE_ERROR = 29, 117*0bbb2f3dSGerd Hoffmann CC_ISOCH_BUFFER_OVERRUN = 31, 118*0bbb2f3dSGerd Hoffmann CC_EVENT_LOST_ERROR, 119*0bbb2f3dSGerd Hoffmann CC_UNDEFINED_ERROR, 120*0bbb2f3dSGerd Hoffmann CC_INVALID_STREAM_ID_ERROR, 121*0bbb2f3dSGerd Hoffmann CC_SECONDARY_BANDWIDTH_ERROR, 122*0bbb2f3dSGerd Hoffmann CC_SPLIT_TRANSACTION_ERROR 123*0bbb2f3dSGerd Hoffmann } TRBCCode; 124*0bbb2f3dSGerd Hoffmann 125*0bbb2f3dSGerd Hoffmann typedef struct XHCIRing { 126*0bbb2f3dSGerd Hoffmann dma_addr_t dequeue; 127*0bbb2f3dSGerd Hoffmann bool ccs; 128*0bbb2f3dSGerd Hoffmann } XHCIRing; 129*0bbb2f3dSGerd Hoffmann 130*0bbb2f3dSGerd Hoffmann typedef struct XHCIPort { 131*0bbb2f3dSGerd Hoffmann XHCIState *xhci; 132*0bbb2f3dSGerd Hoffmann uint32_t portsc; 133*0bbb2f3dSGerd Hoffmann uint32_t portnr; 134*0bbb2f3dSGerd Hoffmann USBPort *uport; 135*0bbb2f3dSGerd Hoffmann uint32_t speedmask; 136*0bbb2f3dSGerd Hoffmann char name[16]; 137*0bbb2f3dSGerd Hoffmann MemoryRegion mem; 138*0bbb2f3dSGerd Hoffmann } XHCIPort; 139*0bbb2f3dSGerd Hoffmann 140*0bbb2f3dSGerd Hoffmann typedef struct XHCISlot { 141*0bbb2f3dSGerd Hoffmann bool enabled; 142*0bbb2f3dSGerd Hoffmann bool addressed; 143*0bbb2f3dSGerd Hoffmann dma_addr_t ctx; 144*0bbb2f3dSGerd Hoffmann USBPort *uport; 145*0bbb2f3dSGerd Hoffmann XHCIEPContext *eps[31]; 146*0bbb2f3dSGerd Hoffmann } XHCISlot; 147*0bbb2f3dSGerd Hoffmann 148*0bbb2f3dSGerd Hoffmann typedef struct XHCIEvent { 149*0bbb2f3dSGerd Hoffmann TRBType type; 150*0bbb2f3dSGerd Hoffmann TRBCCode ccode; 151*0bbb2f3dSGerd Hoffmann uint64_t ptr; 152*0bbb2f3dSGerd Hoffmann uint32_t length; 153*0bbb2f3dSGerd Hoffmann uint32_t flags; 154*0bbb2f3dSGerd Hoffmann uint8_t slotid; 155*0bbb2f3dSGerd Hoffmann uint8_t epid; 156*0bbb2f3dSGerd Hoffmann } XHCIEvent; 157*0bbb2f3dSGerd Hoffmann 158*0bbb2f3dSGerd Hoffmann typedef struct XHCIInterrupter { 159*0bbb2f3dSGerd Hoffmann uint32_t iman; 160*0bbb2f3dSGerd Hoffmann uint32_t imod; 161*0bbb2f3dSGerd Hoffmann uint32_t erstsz; 162*0bbb2f3dSGerd Hoffmann uint32_t erstba_low; 163*0bbb2f3dSGerd Hoffmann uint32_t erstba_high; 164*0bbb2f3dSGerd Hoffmann uint32_t erdp_low; 165*0bbb2f3dSGerd Hoffmann uint32_t erdp_high; 166*0bbb2f3dSGerd Hoffmann 167*0bbb2f3dSGerd Hoffmann bool msix_used, er_pcs; 168*0bbb2f3dSGerd Hoffmann 169*0bbb2f3dSGerd Hoffmann dma_addr_t er_start; 170*0bbb2f3dSGerd Hoffmann uint32_t er_size; 171*0bbb2f3dSGerd Hoffmann unsigned int er_ep_idx; 172*0bbb2f3dSGerd Hoffmann 173*0bbb2f3dSGerd Hoffmann /* kept for live migration compat only */ 174*0bbb2f3dSGerd Hoffmann bool er_full_unused; 175*0bbb2f3dSGerd Hoffmann XHCIEvent ev_buffer[EV_QUEUE]; 176*0bbb2f3dSGerd Hoffmann unsigned int ev_buffer_put; 177*0bbb2f3dSGerd Hoffmann unsigned int ev_buffer_get; 178*0bbb2f3dSGerd Hoffmann 179*0bbb2f3dSGerd Hoffmann } XHCIInterrupter; 180*0bbb2f3dSGerd Hoffmann 181*0bbb2f3dSGerd Hoffmann struct XHCIState { 182*0bbb2f3dSGerd Hoffmann /*< private >*/ 183*0bbb2f3dSGerd Hoffmann PCIDevice parent_obj; 184*0bbb2f3dSGerd Hoffmann /*< public >*/ 185*0bbb2f3dSGerd Hoffmann 186*0bbb2f3dSGerd Hoffmann USBBus bus; 187*0bbb2f3dSGerd Hoffmann MemoryRegion mem; 188*0bbb2f3dSGerd Hoffmann MemoryRegion mem_cap; 189*0bbb2f3dSGerd Hoffmann MemoryRegion mem_oper; 190*0bbb2f3dSGerd Hoffmann MemoryRegion mem_runtime; 191*0bbb2f3dSGerd Hoffmann MemoryRegion mem_doorbell; 192*0bbb2f3dSGerd Hoffmann 193*0bbb2f3dSGerd Hoffmann /* properties */ 194*0bbb2f3dSGerd Hoffmann uint32_t numports_2; 195*0bbb2f3dSGerd Hoffmann uint32_t numports_3; 196*0bbb2f3dSGerd Hoffmann uint32_t numintrs; 197*0bbb2f3dSGerd Hoffmann uint32_t numslots; 198*0bbb2f3dSGerd Hoffmann uint32_t flags; 199*0bbb2f3dSGerd Hoffmann uint32_t max_pstreams_mask; 200*0bbb2f3dSGerd Hoffmann OnOffAuto msi; 201*0bbb2f3dSGerd Hoffmann OnOffAuto msix; 202*0bbb2f3dSGerd Hoffmann 203*0bbb2f3dSGerd Hoffmann /* Operational Registers */ 204*0bbb2f3dSGerd Hoffmann uint32_t usbcmd; 205*0bbb2f3dSGerd Hoffmann uint32_t usbsts; 206*0bbb2f3dSGerd Hoffmann uint32_t dnctrl; 207*0bbb2f3dSGerd Hoffmann uint32_t crcr_low; 208*0bbb2f3dSGerd Hoffmann uint32_t crcr_high; 209*0bbb2f3dSGerd Hoffmann uint32_t dcbaap_low; 210*0bbb2f3dSGerd Hoffmann uint32_t dcbaap_high; 211*0bbb2f3dSGerd Hoffmann uint32_t config; 212*0bbb2f3dSGerd Hoffmann 213*0bbb2f3dSGerd Hoffmann USBPort uports[MAX(MAXPORTS_2, MAXPORTS_3)]; 214*0bbb2f3dSGerd Hoffmann XHCIPort ports[MAXPORTS]; 215*0bbb2f3dSGerd Hoffmann XHCISlot slots[MAXSLOTS]; 216*0bbb2f3dSGerd Hoffmann uint32_t numports; 217*0bbb2f3dSGerd Hoffmann 218*0bbb2f3dSGerd Hoffmann /* Runtime Registers */ 219*0bbb2f3dSGerd Hoffmann int64_t mfindex_start; 220*0bbb2f3dSGerd Hoffmann QEMUTimer *mfwrap_timer; 221*0bbb2f3dSGerd Hoffmann XHCIInterrupter intr[MAXINTRS]; 222*0bbb2f3dSGerd Hoffmann 223*0bbb2f3dSGerd Hoffmann XHCIRing cmd_ring; 224*0bbb2f3dSGerd Hoffmann 225*0bbb2f3dSGerd Hoffmann bool nec_quirks; 226*0bbb2f3dSGerd Hoffmann }; 227