10bbb2f3dSGerd Hoffmann /* 20bbb2f3dSGerd Hoffmann * USB xHCI controller emulation 30bbb2f3dSGerd Hoffmann * 40bbb2f3dSGerd Hoffmann * Copyright (c) 2011 Securiforest 50bbb2f3dSGerd Hoffmann * Date: 2011-05-11 ; Author: Hector Martin <hector@marcansoft.com> 60bbb2f3dSGerd Hoffmann * Based on usb-ohci.c, emulates Renesas NEC USB 3.0 70bbb2f3dSGerd Hoffmann * 80bbb2f3dSGerd Hoffmann * This library is free software; you can redistribute it and/or 90bbb2f3dSGerd Hoffmann * modify it under the terms of the GNU Lesser General Public 100bbb2f3dSGerd Hoffmann * License as published by the Free Software Foundation; either 11bee41971SChetan Pant * version 2.1 of the License, or (at your option) any later version. 120bbb2f3dSGerd Hoffmann * 130bbb2f3dSGerd Hoffmann * This library is distributed in the hope that it will be useful, 140bbb2f3dSGerd Hoffmann * but WITHOUT ANY WARRANTY; without even the implied warranty of 150bbb2f3dSGerd Hoffmann * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 160bbb2f3dSGerd Hoffmann * Lesser General Public License for more details. 170bbb2f3dSGerd Hoffmann * 180bbb2f3dSGerd Hoffmann * You should have received a copy of the GNU Lesser General Public 190bbb2f3dSGerd Hoffmann * License along with this library; if not, see <http://www.gnu.org/licenses/>. 200bbb2f3dSGerd Hoffmann */ 210bbb2f3dSGerd Hoffmann 22f91005e1SMarkus Armbruster #ifndef HW_USB_HCD_XHCI_H 23f91005e1SMarkus Armbruster #define HW_USB_HCD_XHCI_H 24db1015e9SEduardo Habkost #include "qom/object.h" 25f91005e1SMarkus Armbruster 26755fba11SSai Pavan Boddu #include "hw/usb.h" 27848db525SGerd Hoffmann #include "hw/usb/xhci.h" 288ddab8ddSSai Pavan Boddu #include "sysemu/dma.h" 29755fba11SSai Pavan Boddu 308063396bSEduardo Habkost OBJECT_DECLARE_SIMPLE_TYPE(XHCIState, XHCI) 310bbb2f3dSGerd Hoffmann 320bbb2f3dSGerd Hoffmann /* Very pessimistic, let's hope it's enough for all cases */ 33848db525SGerd Hoffmann #define EV_QUEUE (((3 * 24) + 16) * XHCI_MAXSLOTS) 340bbb2f3dSGerd Hoffmann 350bbb2f3dSGerd Hoffmann typedef struct XHCIStreamContext XHCIStreamContext; 360bbb2f3dSGerd Hoffmann typedef struct XHCIEPContext XHCIEPContext; 370bbb2f3dSGerd Hoffmann 380bbb2f3dSGerd Hoffmann enum xhci_flags { 390bbb2f3dSGerd Hoffmann XHCI_FLAG_SS_FIRST = 1, 400bbb2f3dSGerd Hoffmann XHCI_FLAG_FORCE_PCIE_ENDCAP, 410bbb2f3dSGerd Hoffmann XHCI_FLAG_ENABLE_STREAMS, 420bbb2f3dSGerd Hoffmann }; 430bbb2f3dSGerd Hoffmann 440bbb2f3dSGerd Hoffmann typedef enum TRBType { 450bbb2f3dSGerd Hoffmann TRB_RESERVED = 0, 460bbb2f3dSGerd Hoffmann TR_NORMAL, 470bbb2f3dSGerd Hoffmann TR_SETUP, 480bbb2f3dSGerd Hoffmann TR_DATA, 490bbb2f3dSGerd Hoffmann TR_STATUS, 500bbb2f3dSGerd Hoffmann TR_ISOCH, 510bbb2f3dSGerd Hoffmann TR_LINK, 520bbb2f3dSGerd Hoffmann TR_EVDATA, 530bbb2f3dSGerd Hoffmann TR_NOOP, 540bbb2f3dSGerd Hoffmann CR_ENABLE_SLOT, 550bbb2f3dSGerd Hoffmann CR_DISABLE_SLOT, 560bbb2f3dSGerd Hoffmann CR_ADDRESS_DEVICE, 570bbb2f3dSGerd Hoffmann CR_CONFIGURE_ENDPOINT, 580bbb2f3dSGerd Hoffmann CR_EVALUATE_CONTEXT, 590bbb2f3dSGerd Hoffmann CR_RESET_ENDPOINT, 600bbb2f3dSGerd Hoffmann CR_STOP_ENDPOINT, 610bbb2f3dSGerd Hoffmann CR_SET_TR_DEQUEUE, 620bbb2f3dSGerd Hoffmann CR_RESET_DEVICE, 630bbb2f3dSGerd Hoffmann CR_FORCE_EVENT, 640bbb2f3dSGerd Hoffmann CR_NEGOTIATE_BW, 650bbb2f3dSGerd Hoffmann CR_SET_LATENCY_TOLERANCE, 660bbb2f3dSGerd Hoffmann CR_GET_PORT_BANDWIDTH, 670bbb2f3dSGerd Hoffmann CR_FORCE_HEADER, 680bbb2f3dSGerd Hoffmann CR_NOOP, 690bbb2f3dSGerd Hoffmann ER_TRANSFER = 32, 700bbb2f3dSGerd Hoffmann ER_COMMAND_COMPLETE, 710bbb2f3dSGerd Hoffmann ER_PORT_STATUS_CHANGE, 720bbb2f3dSGerd Hoffmann ER_BANDWIDTH_REQUEST, 730bbb2f3dSGerd Hoffmann ER_DOORBELL, 740bbb2f3dSGerd Hoffmann ER_HOST_CONTROLLER, 750bbb2f3dSGerd Hoffmann ER_DEVICE_NOTIFICATION, 760bbb2f3dSGerd Hoffmann ER_MFINDEX_WRAP, 770bbb2f3dSGerd Hoffmann /* vendor specific bits */ 780bbb2f3dSGerd Hoffmann CR_VENDOR_NEC_FIRMWARE_REVISION = 49, 790bbb2f3dSGerd Hoffmann CR_VENDOR_NEC_CHALLENGE_RESPONSE = 50, 800bbb2f3dSGerd Hoffmann } TRBType; 810bbb2f3dSGerd Hoffmann 820bbb2f3dSGerd Hoffmann typedef enum TRBCCode { 830bbb2f3dSGerd Hoffmann CC_INVALID = 0, 840bbb2f3dSGerd Hoffmann CC_SUCCESS, 850bbb2f3dSGerd Hoffmann CC_DATA_BUFFER_ERROR, 860bbb2f3dSGerd Hoffmann CC_BABBLE_DETECTED, 870bbb2f3dSGerd Hoffmann CC_USB_TRANSACTION_ERROR, 880bbb2f3dSGerd Hoffmann CC_TRB_ERROR, 890bbb2f3dSGerd Hoffmann CC_STALL_ERROR, 900bbb2f3dSGerd Hoffmann CC_RESOURCE_ERROR, 910bbb2f3dSGerd Hoffmann CC_BANDWIDTH_ERROR, 920bbb2f3dSGerd Hoffmann CC_NO_SLOTS_ERROR, 930bbb2f3dSGerd Hoffmann CC_INVALID_STREAM_TYPE_ERROR, 940bbb2f3dSGerd Hoffmann CC_SLOT_NOT_ENABLED_ERROR, 950bbb2f3dSGerd Hoffmann CC_EP_NOT_ENABLED_ERROR, 960bbb2f3dSGerd Hoffmann CC_SHORT_PACKET, 970bbb2f3dSGerd Hoffmann CC_RING_UNDERRUN, 980bbb2f3dSGerd Hoffmann CC_RING_OVERRUN, 990bbb2f3dSGerd Hoffmann CC_VF_ER_FULL, 1000bbb2f3dSGerd Hoffmann CC_PARAMETER_ERROR, 1010bbb2f3dSGerd Hoffmann CC_BANDWIDTH_OVERRUN, 1020bbb2f3dSGerd Hoffmann CC_CONTEXT_STATE_ERROR, 1030bbb2f3dSGerd Hoffmann CC_NO_PING_RESPONSE_ERROR, 1040bbb2f3dSGerd Hoffmann CC_EVENT_RING_FULL_ERROR, 1050bbb2f3dSGerd Hoffmann CC_INCOMPATIBLE_DEVICE_ERROR, 1060bbb2f3dSGerd Hoffmann CC_MISSED_SERVICE_ERROR, 1070bbb2f3dSGerd Hoffmann CC_COMMAND_RING_STOPPED, 1080bbb2f3dSGerd Hoffmann CC_COMMAND_ABORTED, 1090bbb2f3dSGerd Hoffmann CC_STOPPED, 1100bbb2f3dSGerd Hoffmann CC_STOPPED_LENGTH_INVALID, 1110bbb2f3dSGerd Hoffmann CC_MAX_EXIT_LATENCY_TOO_LARGE_ERROR = 29, 1120bbb2f3dSGerd Hoffmann CC_ISOCH_BUFFER_OVERRUN = 31, 1130bbb2f3dSGerd Hoffmann CC_EVENT_LOST_ERROR, 1140bbb2f3dSGerd Hoffmann CC_UNDEFINED_ERROR, 1150bbb2f3dSGerd Hoffmann CC_INVALID_STREAM_ID_ERROR, 1160bbb2f3dSGerd Hoffmann CC_SECONDARY_BANDWIDTH_ERROR, 1170bbb2f3dSGerd Hoffmann CC_SPLIT_TRANSACTION_ERROR 1180bbb2f3dSGerd Hoffmann } TRBCCode; 1190bbb2f3dSGerd Hoffmann 1200bbb2f3dSGerd Hoffmann typedef struct XHCIRing { 1210bbb2f3dSGerd Hoffmann dma_addr_t dequeue; 1220bbb2f3dSGerd Hoffmann bool ccs; 1230bbb2f3dSGerd Hoffmann } XHCIRing; 1240bbb2f3dSGerd Hoffmann 1250bbb2f3dSGerd Hoffmann typedef struct XHCIPort { 1260bbb2f3dSGerd Hoffmann XHCIState *xhci; 1270bbb2f3dSGerd Hoffmann uint32_t portsc; 1280bbb2f3dSGerd Hoffmann uint32_t portnr; 1290bbb2f3dSGerd Hoffmann USBPort *uport; 1300bbb2f3dSGerd Hoffmann uint32_t speedmask; 13196b66e55SPhilippe Mathieu-Daudé char name[20]; 1320bbb2f3dSGerd Hoffmann MemoryRegion mem; 1330bbb2f3dSGerd Hoffmann } XHCIPort; 1340bbb2f3dSGerd Hoffmann 1350bbb2f3dSGerd Hoffmann typedef struct XHCISlot { 1360bbb2f3dSGerd Hoffmann bool enabled; 1370bbb2f3dSGerd Hoffmann bool addressed; 138b4329d1aSYuri Benditovich uint16_t intr; 1390bbb2f3dSGerd Hoffmann dma_addr_t ctx; 1400bbb2f3dSGerd Hoffmann USBPort *uport; 1410bbb2f3dSGerd Hoffmann XHCIEPContext *eps[31]; 1420bbb2f3dSGerd Hoffmann } XHCISlot; 1430bbb2f3dSGerd Hoffmann 1440bbb2f3dSGerd Hoffmann typedef struct XHCIEvent { 1450bbb2f3dSGerd Hoffmann TRBType type; 1460bbb2f3dSGerd Hoffmann TRBCCode ccode; 1470bbb2f3dSGerd Hoffmann uint64_t ptr; 1480bbb2f3dSGerd Hoffmann uint32_t length; 1490bbb2f3dSGerd Hoffmann uint32_t flags; 1500bbb2f3dSGerd Hoffmann uint8_t slotid; 1510bbb2f3dSGerd Hoffmann uint8_t epid; 1520bbb2f3dSGerd Hoffmann } XHCIEvent; 1530bbb2f3dSGerd Hoffmann 1540bbb2f3dSGerd Hoffmann typedef struct XHCIInterrupter { 1550bbb2f3dSGerd Hoffmann uint32_t iman; 1560bbb2f3dSGerd Hoffmann uint32_t imod; 1570bbb2f3dSGerd Hoffmann uint32_t erstsz; 1580bbb2f3dSGerd Hoffmann uint32_t erstba_low; 1590bbb2f3dSGerd Hoffmann uint32_t erstba_high; 1600bbb2f3dSGerd Hoffmann uint32_t erdp_low; 1610bbb2f3dSGerd Hoffmann uint32_t erdp_high; 1620bbb2f3dSGerd Hoffmann 1630bbb2f3dSGerd Hoffmann bool msix_used, er_pcs; 1640bbb2f3dSGerd Hoffmann 1650bbb2f3dSGerd Hoffmann dma_addr_t er_start; 1660bbb2f3dSGerd Hoffmann uint32_t er_size; 1670bbb2f3dSGerd Hoffmann unsigned int er_ep_idx; 1680bbb2f3dSGerd Hoffmann 1690bbb2f3dSGerd Hoffmann /* kept for live migration compat only */ 1700bbb2f3dSGerd Hoffmann bool er_full_unused; 1710bbb2f3dSGerd Hoffmann XHCIEvent ev_buffer[EV_QUEUE]; 1720bbb2f3dSGerd Hoffmann unsigned int ev_buffer_put; 1730bbb2f3dSGerd Hoffmann unsigned int ev_buffer_get; 1740bbb2f3dSGerd Hoffmann 1750bbb2f3dSGerd Hoffmann } XHCIInterrupter; 1760bbb2f3dSGerd Hoffmann 1778ddab8ddSSai Pavan Boddu typedef struct XHCIState { 1788ddab8ddSSai Pavan Boddu DeviceState parent; 1790bbb2f3dSGerd Hoffmann 1800bbb2f3dSGerd Hoffmann USBBus bus; 1810bbb2f3dSGerd Hoffmann MemoryRegion mem; 182f00ff136SSai Pavan Boddu MemoryRegion *dma_mr; 183a5317074SSai Pavan Boddu AddressSpace *as; 1840bbb2f3dSGerd Hoffmann MemoryRegion mem_cap; 1850bbb2f3dSGerd Hoffmann MemoryRegion mem_oper; 1860bbb2f3dSGerd Hoffmann MemoryRegion mem_runtime; 1870bbb2f3dSGerd Hoffmann MemoryRegion mem_doorbell; 1880bbb2f3dSGerd Hoffmann 1890bbb2f3dSGerd Hoffmann /* properties */ 1900bbb2f3dSGerd Hoffmann uint32_t numports_2; 1910bbb2f3dSGerd Hoffmann uint32_t numports_3; 1920bbb2f3dSGerd Hoffmann uint32_t numintrs; 1930bbb2f3dSGerd Hoffmann uint32_t numslots; 1940bbb2f3dSGerd Hoffmann uint32_t flags; 1950bbb2f3dSGerd Hoffmann uint32_t max_pstreams_mask; 1968ddab8ddSSai Pavan Boddu void (*intr_update)(XHCIState *s, int n, bool enable); 197*fc967aadSRuimei Yan bool (*intr_raise)(XHCIState *s, int n, bool level); 1988ddab8ddSSai Pavan Boddu DeviceState *hostOpaque; 1990bbb2f3dSGerd Hoffmann 2000bbb2f3dSGerd Hoffmann /* Operational Registers */ 2010bbb2f3dSGerd Hoffmann uint32_t usbcmd; 2020bbb2f3dSGerd Hoffmann uint32_t usbsts; 2030bbb2f3dSGerd Hoffmann uint32_t dnctrl; 2040bbb2f3dSGerd Hoffmann uint32_t crcr_low; 2050bbb2f3dSGerd Hoffmann uint32_t crcr_high; 2060bbb2f3dSGerd Hoffmann uint32_t dcbaap_low; 2070bbb2f3dSGerd Hoffmann uint32_t dcbaap_high; 2080bbb2f3dSGerd Hoffmann uint32_t config; 2090bbb2f3dSGerd Hoffmann 210848db525SGerd Hoffmann USBPort uports[MAX_CONST(XHCI_MAXPORTS_2, XHCI_MAXPORTS_3)]; 211848db525SGerd Hoffmann XHCIPort ports[XHCI_MAXPORTS]; 212848db525SGerd Hoffmann XHCISlot slots[XHCI_MAXSLOTS]; 2130bbb2f3dSGerd Hoffmann uint32_t numports; 2140bbb2f3dSGerd Hoffmann 2150bbb2f3dSGerd Hoffmann /* Runtime Registers */ 2160bbb2f3dSGerd Hoffmann int64_t mfindex_start; 2170bbb2f3dSGerd Hoffmann QEMUTimer *mfwrap_timer; 218848db525SGerd Hoffmann XHCIInterrupter intr[XHCI_MAXINTRS]; 2190bbb2f3dSGerd Hoffmann 2200bbb2f3dSGerd Hoffmann XHCIRing cmd_ring; 2210bbb2f3dSGerd Hoffmann 2220bbb2f3dSGerd Hoffmann bool nec_quirks; 2238ddab8ddSSai Pavan Boddu } XHCIState; 224f91005e1SMarkus Armbruster 2258ddab8ddSSai Pavan Boddu extern const VMStateDescription vmstate_xhci; 226755fba11SSai Pavan Boddu bool xhci_get_flag(XHCIState *xhci, enum xhci_flags bit); 227755fba11SSai Pavan Boddu void xhci_set_flag(XHCIState *xhci, enum xhci_flags bit); 228f91005e1SMarkus Armbruster #endif 229