| 
									
										
										
										
											2017-05-17 12:33:12 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * USB xHCI controller emulation | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (c) 2011 Securiforest | 
					
						
							|  |  |  |  * Date: 2011-05-11 ;  Author: Hector Martin <hector@marcansoft.com> | 
					
						
							|  |  |  |  * Based on usb-ohci.c, emulates Renesas NEC USB 3.0 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							| 
									
										
										
										
											2020-10-23 12:23:32 +00:00
										 |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2017-05-17 12:33:12 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-04 20:16:18 +02:00
										 |  |  | #ifndef HW_USB_HCD_XHCI_H
 | 
					
						
							|  |  |  | #define HW_USB_HCD_XHCI_H
 | 
					
						
							| 
									
										
										
										
											2020-09-03 16:43:22 -04:00
										 |  |  | #include "qom/object.h"
 | 
					
						
							| 
									
										
										
										
											2019-06-04 20:16:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-24 19:50:51 +05:30
										 |  |  | #include "hw/usb.h"
 | 
					
						
							| 
									
										
										
										
											2020-10-20 09:48:36 +02:00
										 |  |  | #include "hw/usb/xhci.h"
 | 
					
						
							| 
									
										
										
										
											2020-09-24 19:50:52 +05:30
										 |  |  | #include "sysemu/dma.h"
 | 
					
						
							| 
									
										
										
										
											2020-09-24 19:50:51 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-16 14:25:19 -04:00
										 |  |  | OBJECT_DECLARE_SIMPLE_TYPE(XHCIState, XHCI) | 
					
						
							| 
									
										
										
										
											2017-05-17 12:33:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Very pessimistic, let's hope it's enough for all cases */ | 
					
						
							| 
									
										
										
										
											2020-10-20 09:48:36 +02:00
										 |  |  | #define EV_QUEUE (((3 * 24) + 16) * XHCI_MAXSLOTS)
 | 
					
						
							| 
									
										
										
										
											2017-05-17 12:33:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef struct XHCIStreamContext XHCIStreamContext; | 
					
						
							|  |  |  | typedef struct XHCIEPContext XHCIEPContext; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum xhci_flags { | 
					
						
							|  |  |  |     XHCI_FLAG_SS_FIRST = 1, | 
					
						
							|  |  |  |     XHCI_FLAG_FORCE_PCIE_ENDCAP, | 
					
						
							|  |  |  |     XHCI_FLAG_ENABLE_STREAMS, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef enum TRBType { | 
					
						
							|  |  |  |     TRB_RESERVED = 0, | 
					
						
							|  |  |  |     TR_NORMAL, | 
					
						
							|  |  |  |     TR_SETUP, | 
					
						
							|  |  |  |     TR_DATA, | 
					
						
							|  |  |  |     TR_STATUS, | 
					
						
							|  |  |  |     TR_ISOCH, | 
					
						
							|  |  |  |     TR_LINK, | 
					
						
							|  |  |  |     TR_EVDATA, | 
					
						
							|  |  |  |     TR_NOOP, | 
					
						
							|  |  |  |     CR_ENABLE_SLOT, | 
					
						
							|  |  |  |     CR_DISABLE_SLOT, | 
					
						
							|  |  |  |     CR_ADDRESS_DEVICE, | 
					
						
							|  |  |  |     CR_CONFIGURE_ENDPOINT, | 
					
						
							|  |  |  |     CR_EVALUATE_CONTEXT, | 
					
						
							|  |  |  |     CR_RESET_ENDPOINT, | 
					
						
							|  |  |  |     CR_STOP_ENDPOINT, | 
					
						
							|  |  |  |     CR_SET_TR_DEQUEUE, | 
					
						
							|  |  |  |     CR_RESET_DEVICE, | 
					
						
							|  |  |  |     CR_FORCE_EVENT, | 
					
						
							|  |  |  |     CR_NEGOTIATE_BW, | 
					
						
							|  |  |  |     CR_SET_LATENCY_TOLERANCE, | 
					
						
							|  |  |  |     CR_GET_PORT_BANDWIDTH, | 
					
						
							|  |  |  |     CR_FORCE_HEADER, | 
					
						
							|  |  |  |     CR_NOOP, | 
					
						
							|  |  |  |     ER_TRANSFER = 32, | 
					
						
							|  |  |  |     ER_COMMAND_COMPLETE, | 
					
						
							|  |  |  |     ER_PORT_STATUS_CHANGE, | 
					
						
							|  |  |  |     ER_BANDWIDTH_REQUEST, | 
					
						
							|  |  |  |     ER_DOORBELL, | 
					
						
							|  |  |  |     ER_HOST_CONTROLLER, | 
					
						
							|  |  |  |     ER_DEVICE_NOTIFICATION, | 
					
						
							|  |  |  |     ER_MFINDEX_WRAP, | 
					
						
							|  |  |  |     /* vendor specific bits */ | 
					
						
							|  |  |  |     CR_VENDOR_NEC_FIRMWARE_REVISION  = 49, | 
					
						
							|  |  |  |     CR_VENDOR_NEC_CHALLENGE_RESPONSE = 50, | 
					
						
							|  |  |  | } TRBType; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef enum TRBCCode { | 
					
						
							|  |  |  |     CC_INVALID = 0, | 
					
						
							|  |  |  |     CC_SUCCESS, | 
					
						
							|  |  |  |     CC_DATA_BUFFER_ERROR, | 
					
						
							|  |  |  |     CC_BABBLE_DETECTED, | 
					
						
							|  |  |  |     CC_USB_TRANSACTION_ERROR, | 
					
						
							|  |  |  |     CC_TRB_ERROR, | 
					
						
							|  |  |  |     CC_STALL_ERROR, | 
					
						
							|  |  |  |     CC_RESOURCE_ERROR, | 
					
						
							|  |  |  |     CC_BANDWIDTH_ERROR, | 
					
						
							|  |  |  |     CC_NO_SLOTS_ERROR, | 
					
						
							|  |  |  |     CC_INVALID_STREAM_TYPE_ERROR, | 
					
						
							|  |  |  |     CC_SLOT_NOT_ENABLED_ERROR, | 
					
						
							|  |  |  |     CC_EP_NOT_ENABLED_ERROR, | 
					
						
							|  |  |  |     CC_SHORT_PACKET, | 
					
						
							|  |  |  |     CC_RING_UNDERRUN, | 
					
						
							|  |  |  |     CC_RING_OVERRUN, | 
					
						
							|  |  |  |     CC_VF_ER_FULL, | 
					
						
							|  |  |  |     CC_PARAMETER_ERROR, | 
					
						
							|  |  |  |     CC_BANDWIDTH_OVERRUN, | 
					
						
							|  |  |  |     CC_CONTEXT_STATE_ERROR, | 
					
						
							|  |  |  |     CC_NO_PING_RESPONSE_ERROR, | 
					
						
							|  |  |  |     CC_EVENT_RING_FULL_ERROR, | 
					
						
							|  |  |  |     CC_INCOMPATIBLE_DEVICE_ERROR, | 
					
						
							|  |  |  |     CC_MISSED_SERVICE_ERROR, | 
					
						
							|  |  |  |     CC_COMMAND_RING_STOPPED, | 
					
						
							|  |  |  |     CC_COMMAND_ABORTED, | 
					
						
							|  |  |  |     CC_STOPPED, | 
					
						
							|  |  |  |     CC_STOPPED_LENGTH_INVALID, | 
					
						
							|  |  |  |     CC_MAX_EXIT_LATENCY_TOO_LARGE_ERROR = 29, | 
					
						
							|  |  |  |     CC_ISOCH_BUFFER_OVERRUN = 31, | 
					
						
							|  |  |  |     CC_EVENT_LOST_ERROR, | 
					
						
							|  |  |  |     CC_UNDEFINED_ERROR, | 
					
						
							|  |  |  |     CC_INVALID_STREAM_ID_ERROR, | 
					
						
							|  |  |  |     CC_SECONDARY_BANDWIDTH_ERROR, | 
					
						
							|  |  |  |     CC_SPLIT_TRANSACTION_ERROR | 
					
						
							|  |  |  | } TRBCCode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct XHCIRing { | 
					
						
							|  |  |  |     dma_addr_t dequeue; | 
					
						
							|  |  |  |     bool ccs; | 
					
						
							|  |  |  | } XHCIRing; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct XHCIPort { | 
					
						
							|  |  |  |     XHCIState *xhci; | 
					
						
							|  |  |  |     uint32_t portsc; | 
					
						
							|  |  |  |     uint32_t portnr; | 
					
						
							|  |  |  |     USBPort  *uport; | 
					
						
							|  |  |  |     uint32_t speedmask; | 
					
						
							| 
									
										
											  
											
												hw/usb/hcd-xhci: Fix extraneous format-truncation error on 32-bit hosts
For some reason the assert() added in commit ccb799313a5
("hw/usb: avoid format truncation warning when formatting
port name") does not fix when building with GCC 10.
KISS and expand the buffer by 4 bytes to silent the following
error when using GCC 10.2.1 on Fedora 33:
  hw/usb/hcd-xhci.c: In function 'usb_xhci_realize':
  hw/usb/hcd-xhci.c:3309:54: error: '%d' directive output may be truncated writing between 1 and 8 bytes into a region of size 5 [-Werror=format-truncation=]
   3309 |             snprintf(port->name, sizeof(port->name), "usb2 port #%d", i+1);
        |                                                      ^~~~~~~~~~~~~~~
  hw/usb/hcd-xhci.c:3309:54: note: directive argument in the range [1, 89478486]
  In file included from /usr/include/stdio.h:866,
                   from include/qemu/osdep.h:85,
                   from hw/usb/hcd-xhci.c:22:
  /usr/include/bits/stdio2.h:70:10: note: '__builtin___snprintf_chk' output between 13 and 20 bytes into a destination of size 16
     70 |   return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
        |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     71 |        __bos (__s), __fmt, __va_arg_pack ());
        |        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  hw/usb/hcd-xhci.c:3323:54: error: '%d' directive output may be truncated writing between 1 and 8 bytes into a region of size 5 [-Werror=format-truncation=]
   3323 |             snprintf(port->name, sizeof(port->name), "usb3 port #%d", i+1);
        |                                                      ^~~~~~~~~~~~~~~
  hw/usb/hcd-xhci.c:3323:54: note: directive argument in the range [1, 89478486]
  In file included from /usr/include/stdio.h:866,
                   from include/qemu/osdep.h:85,
                   from hw/usb/hcd-xhci.c:22:
  /usr/include/bits/stdio2.h:70:10: note: '__builtin___snprintf_chk' output between 13 and 20 bytes into a destination of size 16
     70 |   return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
        |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     71 |        __bos (__s), __fmt, __va_arg_pack ());
        |        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  cc1: all warnings being treated as errors
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20210118181115.313742-1-philmd@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
											
										 
											2021-01-18 19:11:15 +01:00
										 |  |  |     char name[20]; | 
					
						
							| 
									
										
										
										
											2017-05-17 12:33:12 +02:00
										 |  |  |     MemoryRegion mem; | 
					
						
							|  |  |  | } XHCIPort; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct XHCISlot { | 
					
						
							|  |  |  |     bool enabled; | 
					
						
							|  |  |  |     bool addressed; | 
					
						
							| 
									
										
										
										
											2019-01-28 20:05:09 +00:00
										 |  |  |     uint16_t intr; | 
					
						
							| 
									
										
										
										
											2017-05-17 12:33:12 +02:00
										 |  |  |     dma_addr_t ctx; | 
					
						
							|  |  |  |     USBPort *uport; | 
					
						
							|  |  |  |     XHCIEPContext *eps[31]; | 
					
						
							|  |  |  | } XHCISlot; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct XHCIEvent { | 
					
						
							|  |  |  |     TRBType type; | 
					
						
							|  |  |  |     TRBCCode ccode; | 
					
						
							|  |  |  |     uint64_t ptr; | 
					
						
							|  |  |  |     uint32_t length; | 
					
						
							|  |  |  |     uint32_t flags; | 
					
						
							|  |  |  |     uint8_t slotid; | 
					
						
							|  |  |  |     uint8_t epid; | 
					
						
							|  |  |  | } XHCIEvent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct XHCIInterrupter { | 
					
						
							|  |  |  |     uint32_t iman; | 
					
						
							|  |  |  |     uint32_t imod; | 
					
						
							|  |  |  |     uint32_t erstsz; | 
					
						
							|  |  |  |     uint32_t erstba_low; | 
					
						
							|  |  |  |     uint32_t erstba_high; | 
					
						
							|  |  |  |     uint32_t erdp_low; | 
					
						
							|  |  |  |     uint32_t erdp_high; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool msix_used, er_pcs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dma_addr_t er_start; | 
					
						
							|  |  |  |     uint32_t er_size; | 
					
						
							|  |  |  |     unsigned int er_ep_idx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* kept for live migration compat only */ | 
					
						
							|  |  |  |     bool er_full_unused; | 
					
						
							|  |  |  |     XHCIEvent ev_buffer[EV_QUEUE]; | 
					
						
							|  |  |  |     unsigned int ev_buffer_put; | 
					
						
							|  |  |  |     unsigned int ev_buffer_get; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } XHCIInterrupter; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-24 19:50:52 +05:30
										 |  |  | typedef struct XHCIState { | 
					
						
							|  |  |  |     DeviceState parent; | 
					
						
							| 
									
										
										
										
											2017-05-17 12:33:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     USBBus bus; | 
					
						
							|  |  |  |     MemoryRegion mem; | 
					
						
							| 
									
										
										
										
											2020-09-24 19:50:53 +05:30
										 |  |  |     MemoryRegion *dma_mr; | 
					
						
							| 
									
										
										
										
											2020-09-24 19:50:50 +05:30
										 |  |  |     AddressSpace *as; | 
					
						
							| 
									
										
										
										
											2017-05-17 12:33:12 +02:00
										 |  |  |     MemoryRegion mem_cap; | 
					
						
							|  |  |  |     MemoryRegion mem_oper; | 
					
						
							|  |  |  |     MemoryRegion mem_runtime; | 
					
						
							|  |  |  |     MemoryRegion mem_doorbell; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* properties */ | 
					
						
							|  |  |  |     uint32_t numports_2; | 
					
						
							|  |  |  |     uint32_t numports_3; | 
					
						
							|  |  |  |     uint32_t numintrs; | 
					
						
							|  |  |  |     uint32_t numslots; | 
					
						
							|  |  |  |     uint32_t flags; | 
					
						
							|  |  |  |     uint32_t max_pstreams_mask; | 
					
						
							| 
									
										
										
										
											2020-09-24 19:50:52 +05:30
										 |  |  |     void (*intr_update)(XHCIState *s, int n, bool enable); | 
					
						
							|  |  |  |     void (*intr_raise)(XHCIState *s, int n, bool level); | 
					
						
							|  |  |  |     DeviceState *hostOpaque; | 
					
						
							| 
									
										
										
										
											2017-05-17 12:33:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Operational Registers */ | 
					
						
							|  |  |  |     uint32_t usbcmd; | 
					
						
							|  |  |  |     uint32_t usbsts; | 
					
						
							|  |  |  |     uint32_t dnctrl; | 
					
						
							|  |  |  |     uint32_t crcr_low; | 
					
						
							|  |  |  |     uint32_t crcr_high; | 
					
						
							|  |  |  |     uint32_t dcbaap_low; | 
					
						
							|  |  |  |     uint32_t dcbaap_high; | 
					
						
							|  |  |  |     uint32_t config; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-20 09:48:36 +02:00
										 |  |  |     USBPort  uports[MAX_CONST(XHCI_MAXPORTS_2, XHCI_MAXPORTS_3)]; | 
					
						
							|  |  |  |     XHCIPort ports[XHCI_MAXPORTS]; | 
					
						
							|  |  |  |     XHCISlot slots[XHCI_MAXSLOTS]; | 
					
						
							| 
									
										
										
										
											2017-05-17 12:33:12 +02:00
										 |  |  |     uint32_t numports; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Runtime Registers */ | 
					
						
							|  |  |  |     int64_t mfindex_start; | 
					
						
							|  |  |  |     QEMUTimer *mfwrap_timer; | 
					
						
							| 
									
										
										
										
											2020-10-20 09:48:36 +02:00
										 |  |  |     XHCIInterrupter intr[XHCI_MAXINTRS]; | 
					
						
							| 
									
										
										
										
											2017-05-17 12:33:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     XHCIRing cmd_ring; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool nec_quirks; | 
					
						
							| 
									
										
										
										
											2020-09-24 19:50:52 +05:30
										 |  |  | } XHCIState; | 
					
						
							| 
									
										
										
										
											2019-06-04 20:16:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-24 19:50:52 +05:30
										 |  |  | extern const VMStateDescription vmstate_xhci; | 
					
						
							| 
									
										
										
										
											2020-09-24 19:50:51 +05:30
										 |  |  | bool xhci_get_flag(XHCIState *xhci, enum xhci_flags bit); | 
					
						
							|  |  |  | void xhci_set_flag(XHCIState *xhci, enum xhci_flags bit); | 
					
						
							| 
									
										
										
										
											2019-06-04 20:16:18 +02:00
										 |  |  | #endif
 |