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 { 39*b9599519SPhilippe Mathieu-Daudé XHCI_FLAG_ENABLE_STREAMS = 1, 400bbb2f3dSGerd Hoffmann }; 410bbb2f3dSGerd Hoffmann 420bbb2f3dSGerd Hoffmann typedef enum TRBType { 430bbb2f3dSGerd Hoffmann TRB_RESERVED = 0, 440bbb2f3dSGerd Hoffmann TR_NORMAL, 450bbb2f3dSGerd Hoffmann TR_SETUP, 460bbb2f3dSGerd Hoffmann TR_DATA, 470bbb2f3dSGerd Hoffmann TR_STATUS, 480bbb2f3dSGerd Hoffmann TR_ISOCH, 490bbb2f3dSGerd Hoffmann TR_LINK, 500bbb2f3dSGerd Hoffmann TR_EVDATA, 510bbb2f3dSGerd Hoffmann TR_NOOP, 520bbb2f3dSGerd Hoffmann CR_ENABLE_SLOT, 530bbb2f3dSGerd Hoffmann CR_DISABLE_SLOT, 540bbb2f3dSGerd Hoffmann CR_ADDRESS_DEVICE, 550bbb2f3dSGerd Hoffmann CR_CONFIGURE_ENDPOINT, 560bbb2f3dSGerd Hoffmann CR_EVALUATE_CONTEXT, 570bbb2f3dSGerd Hoffmann CR_RESET_ENDPOINT, 580bbb2f3dSGerd Hoffmann CR_STOP_ENDPOINT, 590bbb2f3dSGerd Hoffmann CR_SET_TR_DEQUEUE, 600bbb2f3dSGerd Hoffmann CR_RESET_DEVICE, 610bbb2f3dSGerd Hoffmann CR_FORCE_EVENT, 620bbb2f3dSGerd Hoffmann CR_NEGOTIATE_BW, 630bbb2f3dSGerd Hoffmann CR_SET_LATENCY_TOLERANCE, 640bbb2f3dSGerd Hoffmann CR_GET_PORT_BANDWIDTH, 650bbb2f3dSGerd Hoffmann CR_FORCE_HEADER, 660bbb2f3dSGerd Hoffmann CR_NOOP, 670bbb2f3dSGerd Hoffmann ER_TRANSFER = 32, 680bbb2f3dSGerd Hoffmann ER_COMMAND_COMPLETE, 690bbb2f3dSGerd Hoffmann ER_PORT_STATUS_CHANGE, 700bbb2f3dSGerd Hoffmann ER_BANDWIDTH_REQUEST, 710bbb2f3dSGerd Hoffmann ER_DOORBELL, 720bbb2f3dSGerd Hoffmann ER_HOST_CONTROLLER, 730bbb2f3dSGerd Hoffmann ER_DEVICE_NOTIFICATION, 740bbb2f3dSGerd Hoffmann ER_MFINDEX_WRAP, 750bbb2f3dSGerd Hoffmann /* vendor specific bits */ 760bbb2f3dSGerd Hoffmann CR_VENDOR_NEC_FIRMWARE_REVISION = 49, 770bbb2f3dSGerd Hoffmann CR_VENDOR_NEC_CHALLENGE_RESPONSE = 50, 780bbb2f3dSGerd Hoffmann } TRBType; 790bbb2f3dSGerd Hoffmann 800bbb2f3dSGerd Hoffmann typedef enum TRBCCode { 810bbb2f3dSGerd Hoffmann CC_INVALID = 0, 820bbb2f3dSGerd Hoffmann CC_SUCCESS, 830bbb2f3dSGerd Hoffmann CC_DATA_BUFFER_ERROR, 840bbb2f3dSGerd Hoffmann CC_BABBLE_DETECTED, 850bbb2f3dSGerd Hoffmann CC_USB_TRANSACTION_ERROR, 860bbb2f3dSGerd Hoffmann CC_TRB_ERROR, 870bbb2f3dSGerd Hoffmann CC_STALL_ERROR, 880bbb2f3dSGerd Hoffmann CC_RESOURCE_ERROR, 890bbb2f3dSGerd Hoffmann CC_BANDWIDTH_ERROR, 900bbb2f3dSGerd Hoffmann CC_NO_SLOTS_ERROR, 910bbb2f3dSGerd Hoffmann CC_INVALID_STREAM_TYPE_ERROR, 920bbb2f3dSGerd Hoffmann CC_SLOT_NOT_ENABLED_ERROR, 930bbb2f3dSGerd Hoffmann CC_EP_NOT_ENABLED_ERROR, 940bbb2f3dSGerd Hoffmann CC_SHORT_PACKET, 950bbb2f3dSGerd Hoffmann CC_RING_UNDERRUN, 960bbb2f3dSGerd Hoffmann CC_RING_OVERRUN, 970bbb2f3dSGerd Hoffmann CC_VF_ER_FULL, 980bbb2f3dSGerd Hoffmann CC_PARAMETER_ERROR, 990bbb2f3dSGerd Hoffmann CC_BANDWIDTH_OVERRUN, 1000bbb2f3dSGerd Hoffmann CC_CONTEXT_STATE_ERROR, 1010bbb2f3dSGerd Hoffmann CC_NO_PING_RESPONSE_ERROR, 1020bbb2f3dSGerd Hoffmann CC_EVENT_RING_FULL_ERROR, 1030bbb2f3dSGerd Hoffmann CC_INCOMPATIBLE_DEVICE_ERROR, 1040bbb2f3dSGerd Hoffmann CC_MISSED_SERVICE_ERROR, 1050bbb2f3dSGerd Hoffmann CC_COMMAND_RING_STOPPED, 1060bbb2f3dSGerd Hoffmann CC_COMMAND_ABORTED, 1070bbb2f3dSGerd Hoffmann CC_STOPPED, 1080bbb2f3dSGerd Hoffmann CC_STOPPED_LENGTH_INVALID, 1090bbb2f3dSGerd Hoffmann CC_MAX_EXIT_LATENCY_TOO_LARGE_ERROR = 29, 1100bbb2f3dSGerd Hoffmann CC_ISOCH_BUFFER_OVERRUN = 31, 1110bbb2f3dSGerd Hoffmann CC_EVENT_LOST_ERROR, 1120bbb2f3dSGerd Hoffmann CC_UNDEFINED_ERROR, 1130bbb2f3dSGerd Hoffmann CC_INVALID_STREAM_ID_ERROR, 1140bbb2f3dSGerd Hoffmann CC_SECONDARY_BANDWIDTH_ERROR, 1150bbb2f3dSGerd Hoffmann CC_SPLIT_TRANSACTION_ERROR 1160bbb2f3dSGerd Hoffmann } TRBCCode; 1170bbb2f3dSGerd Hoffmann 1180bbb2f3dSGerd Hoffmann typedef struct XHCIRing { 1190bbb2f3dSGerd Hoffmann dma_addr_t dequeue; 1200bbb2f3dSGerd Hoffmann bool ccs; 1210bbb2f3dSGerd Hoffmann } XHCIRing; 1220bbb2f3dSGerd Hoffmann 1230bbb2f3dSGerd Hoffmann typedef struct XHCIPort { 1240bbb2f3dSGerd Hoffmann XHCIState *xhci; 1250bbb2f3dSGerd Hoffmann uint32_t portsc; 1260bbb2f3dSGerd Hoffmann uint32_t portnr; 1270bbb2f3dSGerd Hoffmann USBPort *uport; 1280bbb2f3dSGerd Hoffmann uint32_t speedmask; 12996b66e55SPhilippe Mathieu-Daudé char name[20]; 1300bbb2f3dSGerd Hoffmann MemoryRegion mem; 1310bbb2f3dSGerd Hoffmann } XHCIPort; 1320bbb2f3dSGerd Hoffmann 1330bbb2f3dSGerd Hoffmann typedef struct XHCISlot { 1340bbb2f3dSGerd Hoffmann bool enabled; 1350bbb2f3dSGerd Hoffmann bool addressed; 136b4329d1aSYuri Benditovich uint16_t intr; 1370bbb2f3dSGerd Hoffmann dma_addr_t ctx; 1380bbb2f3dSGerd Hoffmann USBPort *uport; 1390bbb2f3dSGerd Hoffmann XHCIEPContext *eps[31]; 1400bbb2f3dSGerd Hoffmann } XHCISlot; 1410bbb2f3dSGerd Hoffmann 1420bbb2f3dSGerd Hoffmann typedef struct XHCIEvent { 1430bbb2f3dSGerd Hoffmann TRBType type; 1440bbb2f3dSGerd Hoffmann TRBCCode ccode; 1450bbb2f3dSGerd Hoffmann uint64_t ptr; 1460bbb2f3dSGerd Hoffmann uint32_t length; 1470bbb2f3dSGerd Hoffmann uint32_t flags; 1480bbb2f3dSGerd Hoffmann uint8_t slotid; 1490bbb2f3dSGerd Hoffmann uint8_t epid; 1500bbb2f3dSGerd Hoffmann } XHCIEvent; 1510bbb2f3dSGerd Hoffmann 1520bbb2f3dSGerd Hoffmann typedef struct XHCIInterrupter { 1530bbb2f3dSGerd Hoffmann uint32_t iman; 1540bbb2f3dSGerd Hoffmann uint32_t imod; 1550bbb2f3dSGerd Hoffmann uint32_t erstsz; 1560bbb2f3dSGerd Hoffmann uint32_t erstba_low; 1570bbb2f3dSGerd Hoffmann uint32_t erstba_high; 1580bbb2f3dSGerd Hoffmann uint32_t erdp_low; 1590bbb2f3dSGerd Hoffmann uint32_t erdp_high; 1600bbb2f3dSGerd Hoffmann 1610bbb2f3dSGerd Hoffmann bool msix_used, er_pcs; 1620bbb2f3dSGerd Hoffmann 1630bbb2f3dSGerd Hoffmann dma_addr_t er_start; 1640bbb2f3dSGerd Hoffmann uint32_t er_size; 1650bbb2f3dSGerd Hoffmann unsigned int er_ep_idx; 1660bbb2f3dSGerd Hoffmann 1670bbb2f3dSGerd Hoffmann /* kept for live migration compat only */ 1680bbb2f3dSGerd Hoffmann bool er_full_unused; 1690bbb2f3dSGerd Hoffmann XHCIEvent ev_buffer[EV_QUEUE]; 1700bbb2f3dSGerd Hoffmann unsigned int ev_buffer_put; 1710bbb2f3dSGerd Hoffmann unsigned int ev_buffer_get; 1720bbb2f3dSGerd Hoffmann 1730bbb2f3dSGerd Hoffmann } XHCIInterrupter; 1740bbb2f3dSGerd Hoffmann 1758ddab8ddSSai Pavan Boddu typedef struct XHCIState { 1768ddab8ddSSai Pavan Boddu DeviceState parent; 1770bbb2f3dSGerd Hoffmann 1780bbb2f3dSGerd Hoffmann USBBus bus; 1790bbb2f3dSGerd Hoffmann MemoryRegion mem; 180f00ff136SSai Pavan Boddu MemoryRegion *dma_mr; 181a5317074SSai Pavan Boddu AddressSpace *as; 1820bbb2f3dSGerd Hoffmann MemoryRegion mem_cap; 1830bbb2f3dSGerd Hoffmann MemoryRegion mem_oper; 1840bbb2f3dSGerd Hoffmann MemoryRegion mem_runtime; 1850bbb2f3dSGerd Hoffmann MemoryRegion mem_doorbell; 1860bbb2f3dSGerd Hoffmann 1870bbb2f3dSGerd Hoffmann /* properties */ 1880bbb2f3dSGerd Hoffmann uint32_t numports_2; 1890bbb2f3dSGerd Hoffmann uint32_t numports_3; 1900bbb2f3dSGerd Hoffmann uint32_t numintrs; 1910bbb2f3dSGerd Hoffmann uint32_t numslots; 1920bbb2f3dSGerd Hoffmann uint32_t flags; 1930bbb2f3dSGerd Hoffmann uint32_t max_pstreams_mask; 1948ddab8ddSSai Pavan Boddu void (*intr_update)(XHCIState *s, int n, bool enable); 195fc967aadSRuimei Yan bool (*intr_raise)(XHCIState *s, int n, bool level); 1968ddab8ddSSai Pavan Boddu DeviceState *hostOpaque; 1970bbb2f3dSGerd Hoffmann 1980bbb2f3dSGerd Hoffmann /* Operational Registers */ 1990bbb2f3dSGerd Hoffmann uint32_t usbcmd; 2000bbb2f3dSGerd Hoffmann uint32_t usbsts; 2010bbb2f3dSGerd Hoffmann uint32_t dnctrl; 2020bbb2f3dSGerd Hoffmann uint32_t crcr_low; 2030bbb2f3dSGerd Hoffmann uint32_t crcr_high; 2040bbb2f3dSGerd Hoffmann uint32_t dcbaap_low; 2050bbb2f3dSGerd Hoffmann uint32_t dcbaap_high; 2060bbb2f3dSGerd Hoffmann uint32_t config; 2070bbb2f3dSGerd Hoffmann 208848db525SGerd Hoffmann USBPort uports[MAX_CONST(XHCI_MAXPORTS_2, XHCI_MAXPORTS_3)]; 209848db525SGerd Hoffmann XHCIPort ports[XHCI_MAXPORTS]; 210848db525SGerd Hoffmann XHCISlot slots[XHCI_MAXSLOTS]; 2110bbb2f3dSGerd Hoffmann uint32_t numports; 2120bbb2f3dSGerd Hoffmann 2130bbb2f3dSGerd Hoffmann /* Runtime Registers */ 2140bbb2f3dSGerd Hoffmann int64_t mfindex_start; 2150bbb2f3dSGerd Hoffmann QEMUTimer *mfwrap_timer; 216848db525SGerd Hoffmann XHCIInterrupter intr[XHCI_MAXINTRS]; 2170bbb2f3dSGerd Hoffmann 2180bbb2f3dSGerd Hoffmann XHCIRing cmd_ring; 2190bbb2f3dSGerd Hoffmann 2200bbb2f3dSGerd Hoffmann bool nec_quirks; 2218ddab8ddSSai Pavan Boddu } XHCIState; 222f91005e1SMarkus Armbruster 2238ddab8ddSSai Pavan Boddu extern const VMStateDescription vmstate_xhci; 224755fba11SSai Pavan Boddu bool xhci_get_flag(XHCIState *xhci, enum xhci_flags bit); 225755fba11SSai Pavan Boddu void xhci_set_flag(XHCIState *xhci, enum xhci_flags bit); 226f91005e1SMarkus Armbruster #endif 227