1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150 |
- #ifndef _IPXE_XHCI_H
- #define _IPXE_XHCI_H
-
- /** @file
- *
- * USB eXtensible Host Controller Interface (xHCI) driver
- *
- */
-
- FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
- #include <assert.h>
- #include <ipxe/pci.h>
- #include <ipxe/uaccess.h>
- #include <ipxe/usb.h>
-
- /** Minimum alignment required for data structures
- *
- * With the exception of the scratchpad buffer pages (which are
- * page-aligned), data structures used by xHCI generally require from
- * 16 to 64 byte alignment and must not cross an (xHCI) page boundary.
- * We simplify this requirement by aligning each structure on its own
- * size, with a minimum of a 64 byte alignment.
- */
- #define XHCI_MIN_ALIGN 64
-
- /** Maximum transfer size */
- #define XHCI_MTU 65536
-
- /** xHCI PCI BAR */
- #define XHCI_BAR PCI_BASE_ADDRESS_0
-
- /** Capability register length */
- #define XHCI_CAP_CAPLENGTH 0x00
-
- /** Host controller interface version number */
- #define XHCI_CAP_HCIVERSION 0x02
-
- /** Structural parameters 1 */
- #define XHCI_CAP_HCSPARAMS1 0x04
-
- /** Number of device slots */
- #define XHCI_HCSPARAMS1_SLOTS(params) ( ( (params) >> 0 ) & 0xff )
-
- /** Number of interrupters */
- #define XHCI_HCSPARAMS1_INTRS(params) ( ( (params) >> 8 ) & 0x3ff )
-
- /** Number of ports */
- #define XHCI_HCSPARAMS1_PORTS(params) ( ( (params) >> 24 ) & 0xff )
-
- /** Structural parameters 2 */
- #define XHCI_CAP_HCSPARAMS2 0x08
-
- /** Number of page-sized scratchpad buffers */
- #define XHCI_HCSPARAMS2_SCRATCHPADS(params) \
- ( ( ( (params) >> 16 ) & 0x3e0 ) | ( ( (params) >> 27 ) & 0x1f ) )
-
- /** Capability parameters */
- #define XHCI_CAP_HCCPARAMS1 0x10
-
- /** 64-bit addressing capability */
- #define XHCI_HCCPARAMS1_ADDR64(params) ( ( (params) >> 0 ) & 0x1 )
-
- /** Context size shift */
- #define XHCI_HCCPARAMS1_CSZ_SHIFT(params) ( 5 + ( ( (params) >> 2 ) & 0x1 ) )
-
- /** xHCI extended capabilities pointer */
- #define XHCI_HCCPARAMS1_XECP(params) ( ( ( (params) >> 16 ) & 0xffff ) << 2 )
-
- /** Doorbell offset */
- #define XHCI_CAP_DBOFF 0x14
-
- /** Runtime register space offset */
- #define XHCI_CAP_RTSOFF 0x18
-
- /** xHCI extended capability ID */
- #define XHCI_XECP_ID(xecp) ( ( (xecp) >> 0 ) & 0xff )
-
- /** Next xHCI extended capability pointer */
- #define XHCI_XECP_NEXT(xecp) ( ( ( (xecp) >> 8 ) & 0xff ) << 2 )
-
- /** USB legacy support extended capability */
- #define XHCI_XECP_ID_LEGACY 1
-
- /** USB legacy support BIOS owned semaphore */
- #define XHCI_USBLEGSUP_BIOS 0x02
-
- /** USB legacy support BIOS ownership flag */
- #define XHCI_USBLEGSUP_BIOS_OWNED 0x01
-
- /** USB legacy support OS owned semaphore */
- #define XHCI_USBLEGSUP_OS 0x03
-
- /** USB legacy support OS ownership flag */
- #define XHCI_USBLEGSUP_OS_OWNED 0x01
-
- /** USB legacy support control/status */
- #define XHCI_USBLEGSUP_CTLSTS 0x04
-
- /** Supported protocol extended capability */
- #define XHCI_XECP_ID_SUPPORTED 2
-
- /** Supported protocol revision */
- #define XHCI_SUPPORTED_REVISION 0x00
-
- /** Supported protocol minor revision */
- #define XHCI_SUPPORTED_REVISION_VER(revision) ( ( (revision) >> 16 ) & 0xffff )
-
- /** Supported protocol name */
- #define XHCI_SUPPORTED_NAME 0x04
-
- /** Supported protocol ports */
- #define XHCI_SUPPORTED_PORTS 0x08
-
- /** Supported protocol port offset */
- #define XHCI_SUPPORTED_PORTS_OFFSET(ports) ( ( (ports) >> 0 ) & 0xff )
-
- /** Supported protocol port count */
- #define XHCI_SUPPORTED_PORTS_COUNT(ports) ( ( (ports) >> 8 ) & 0xff )
-
- /** Supported protocol PSI count */
- #define XHCI_SUPPORTED_PORTS_PSIC(ports) ( ( (ports) >> 28 ) & 0x0f )
-
- /** Supported protocol slot */
- #define XHCI_SUPPORTED_SLOT 0x0c
-
- /** Supported protocol slot type */
- #define XHCI_SUPPORTED_SLOT_TYPE(slot) ( ( (slot) >> 0 ) & 0x1f )
-
- /** Supported protocol PSI */
- #define XHCI_SUPPORTED_PSI(index) ( 0x10 + ( (index) * 4 ) )
-
- /** Supported protocol PSI value */
- #define XHCI_SUPPORTED_PSI_VALUE(psi) ( ( (psi) >> 0 ) & 0x0f )
-
- /** Supported protocol PSI mantissa */
- #define XHCI_SUPPORTED_PSI_MANTISSA(psi) ( ( (psi) >> 16 ) & 0xffff )
-
- /** Supported protocol PSI exponent */
- #define XHCI_SUPPORTED_PSI_EXPONENT(psi) ( ( (psi) >> 4 ) & 0x03 )
-
- /** Default PSI values */
- enum xhci_default_psi_value {
- /** Full speed (12Mbps) */
- XHCI_SPEED_FULL = 1,
- /** Low speed (1.5Mbps) */
- XHCI_SPEED_LOW = 2,
- /** High speed (480Mbps) */
- XHCI_SPEED_HIGH = 3,
- /** Super speed */
- XHCI_SPEED_SUPER = 4,
- };
-
- /** USB command register */
- #define XHCI_OP_USBCMD 0x00
-
- /** Run/stop */
- #define XHCI_USBCMD_RUN 0x00000001UL
-
- /** Host controller reset */
- #define XHCI_USBCMD_HCRST 0x00000002UL
-
- /** USB status register */
- #define XHCI_OP_USBSTS 0x04
-
- /** Host controller halted */
- #define XHCI_USBSTS_HCH 0x00000001UL
-
- /** Page size register */
- #define XHCI_OP_PAGESIZE 0x08
-
- /** Page size */
- #define XHCI_PAGESIZE(pagesize) ( (pagesize) << 12 )
-
- /** Device notifcation control register */
- #define XHCI_OP_DNCTRL 0x14
-
- /** Command ring control register */
- #define XHCI_OP_CRCR 0x18
-
- /** Command ring cycle state */
- #define XHCI_CRCR_RCS 0x00000001UL
-
- /** Command abort */
- #define XHCI_CRCR_CA 0x00000004UL
-
- /** Command ring running */
- #define XHCI_CRCR_CRR 0x00000008UL
-
- /** Device context base address array pointer */
- #define XHCI_OP_DCBAAP 0x30
-
- /** Configure register */
- #define XHCI_OP_CONFIG 0x38
-
- /** Maximum device slots enabled */
- #define XHCI_CONFIG_MAX_SLOTS_EN(slots) ( (slots) << 0 )
-
- /** Maximum device slots enabled mask */
- #define XHCI_CONFIG_MAX_SLOTS_EN_MASK \
- XHCI_CONFIG_MAX_SLOTS_EN ( 0xff )
-
- /** Port status and control register */
- #define XHCI_OP_PORTSC(port) ( 0x400 - 0x10 + ( (port) << 4 ) )
-
- /** Current connect status */
- #define XHCI_PORTSC_CCS 0x00000001UL
-
- /** Port enabled */
- #define XHCI_PORTSC_PED 0x00000002UL
-
- /** Port reset */
- #define XHCI_PORTSC_PR 0x00000010UL
-
- /** Port link state */
- #define XHCI_PORTSC_PLS(pls) ( (pls) << 5 )
-
- /** Disabled port link state */
- #define XHCI_PORTSC_PLS_DISABLED XHCI_PORTSC_PLS ( 4 )
-
- /** RxDetect port link state */
- #define XHCI_PORTSC_PLS_RXDETECT XHCI_PORTSC_PLS ( 5 )
-
- /** Port link state mask */
- #define XHCI_PORTSC_PLS_MASK XHCI_PORTSC_PLS ( 0xf )
-
- /** Port power */
- #define XHCI_PORTSC_PP 0x00000200UL
-
- /** Time to delay after enabling power to a port */
- #define XHCI_PORT_POWER_DELAY_MS 20
-
- /** Port speed ID value */
- #define XHCI_PORTSC_PSIV(portsc) ( ( (portsc) >> 10 ) & 0xf )
-
- /** Port indicator control */
- #define XHCI_PORTSC_PIC(indicators) ( (indicators) << 14 )
-
- /** Port indicator control mask */
- #define XHCI_PORTSC_PIC_MASK XHCI_PORTSC_PIC ( 3 )
-
- /** Port link state write strobe */
- #define XHCI_PORTSC_LWS 0x00010000UL
-
- /** Time to delay after writing the port link state */
- #define XHCI_LINK_STATE_DELAY_MS 20
-
- /** Connect status change */
- #define XHCI_PORTSC_CSC 0x00020000UL
-
- /** Port enabled/disabled change */
- #define XHCI_PORTSC_PEC 0x00040000UL
-
- /** Warm port reset change */
- #define XHCI_PORTSC_WRC 0x00080000UL
-
- /** Over-current change */
- #define XHCI_PORTSC_OCC 0x00100000UL
-
- /** Port reset change */
- #define XHCI_PORTSC_PRC 0x00200000UL
-
- /** Port link state change */
- #define XHCI_PORTSC_PLC 0x00400000UL
-
- /** Port config error change */
- #define XHCI_PORTSC_CEC 0x00800000UL
-
- /** Port status change mask */
- #define XHCI_PORTSC_CHANGE \
- ( XHCI_PORTSC_CSC | XHCI_PORTSC_PEC | XHCI_PORTSC_WRC | \
- XHCI_PORTSC_OCC | XHCI_PORTSC_PRC | XHCI_PORTSC_PLC | \
- XHCI_PORTSC_CEC )
-
- /** Port status and control bits which should be preserved
- *
- * The port status and control register is a horrendous mix of
- * differing semantics. Some bits are written to only when a separate
- * write strobe bit is set. Some bits should be preserved when
- * modifying other bits. Some bits will be cleared if written back as
- * a one. Most excitingly, the "port enabled" bit has the semantics
- * that 1=enabled, 0=disabled, yet writing a 1 will disable the port.
- */
- #define XHCI_PORTSC_PRESERVE ( XHCI_PORTSC_PP | XHCI_PORTSC_PIC_MASK )
-
- /** Port power management status and control register */
- #define XHCI_OP_PORTPMSC(port) ( 0x404 - 0x10 + ( (port) << 4 ) )
-
- /** Port link info register */
- #define XHCI_OP_PORTLI(port) ( 0x408 - 0x10 + ( (port) << 4 ) )
-
- /** Port hardware link power management control register */
- #define XHCI_OP_PORTHLPMC(port) ( 0x40c - 0x10 + ( (port) << 4 ) )
-
- /** Event ring segment table size register */
- #define XHCI_RUN_ERSTSZ(intr) ( 0x28 + ( (intr) << 5 ) )
-
- /** Event ring segment table base address register */
- #define XHCI_RUN_ERSTBA(intr) ( 0x30 + ( (intr) << 5 ) )
-
- /** Event ring dequeue pointer register */
- #define XHCI_RUN_ERDP(intr) ( 0x38 + ( (intr) << 5 ) )
-
- /** A transfer request block template */
- struct xhci_trb_template {
- /** Parameter */
- uint64_t parameter;
- /** Status */
- uint32_t status;
- /** Control */
- uint32_t control;
- };
-
- /** A transfer request block */
- struct xhci_trb_common {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint32_t reserved_b;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint16_t reserved_c;
- } __attribute__ (( packed ));
-
- /** Transfer request block cycle bit flag */
- #define XHCI_TRB_C 0x01
-
- /** Transfer request block toggle cycle bit flag */
- #define XHCI_TRB_TC 0x02
-
- /** Transfer request block chain flag */
- #define XHCI_TRB_CH 0x10
-
- /** Transfer request block interrupt on completion flag */
- #define XHCI_TRB_IOC 0x20
-
- /** Transfer request block immediate data flag */
- #define XHCI_TRB_IDT 0x40
-
- /** Transfer request block type */
- #define XHCI_TRB_TYPE(type) ( (type) << 2 )
-
- /** Transfer request block type mask */
- #define XHCI_TRB_TYPE_MASK XHCI_TRB_TYPE ( 0x3f )
-
- /** A normal transfer request block */
- struct xhci_trb_normal {
- /** Data buffer */
- uint64_t data;
- /** Length */
- uint32_t len;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint16_t reserved;
- } __attribute__ (( packed ));
-
- /** A normal transfer request block */
- #define XHCI_TRB_NORMAL XHCI_TRB_TYPE ( 1 )
-
- /** Construct TD size field */
- #define XHCI_TD_SIZE(remaining) \
- ( ( ( (remaining) <= 0xf ) ? remaining : 0xf ) << 17 )
-
- /** A setup stage transfer request block */
- struct xhci_trb_setup {
- /** Setup packet */
- struct usb_setup_packet packet;
- /** Length */
- uint32_t len;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Transfer direction */
- uint8_t direction;
- /** Reserved */
- uint8_t reserved;
- } __attribute__ (( packed ));
-
- /** A setup stage transfer request block */
- #define XHCI_TRB_SETUP XHCI_TRB_TYPE ( 2 )
-
- /** Setup stage input data direction */
- #define XHCI_SETUP_IN 3
-
- /** Setup stage output data direction */
- #define XHCI_SETUP_OUT 2
-
- /** A data stage transfer request block */
- struct xhci_trb_data {
- /** Data buffer */
- uint64_t data;
- /** Length */
- uint32_t len;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Transfer direction */
- uint8_t direction;
- /** Reserved */
- uint8_t reserved;
- } __attribute__ (( packed ));
-
- /** A data stage transfer request block */
- #define XHCI_TRB_DATA XHCI_TRB_TYPE ( 3 )
-
- /** Input data direction */
- #define XHCI_DATA_IN 0x01
-
- /** Output data direction */
- #define XHCI_DATA_OUT 0x00
-
- /** A status stage transfer request block */
- struct xhci_trb_status {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint32_t reserved_b;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Direction */
- uint8_t direction;
- /** Reserved */
- uint8_t reserved_c;
- } __attribute__ (( packed ));
-
- /** A status stage transfer request block */
- #define XHCI_TRB_STATUS XHCI_TRB_TYPE ( 4 )
-
- /** Input status direction */
- #define XHCI_STATUS_IN 0x01
-
- /** Output status direction */
- #define XHCI_STATUS_OUT 0x00
-
- /** A link transfer request block */
- struct xhci_trb_link {
- /** Next ring segment */
- uint64_t next;
- /** Reserved */
- uint32_t reserved_a;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint16_t reserved_c;
- } __attribute__ (( packed ));
-
- /** A link transfer request block */
- #define XHCI_TRB_LINK XHCI_TRB_TYPE ( 6 )
-
- /** A no-op transfer request block */
- #define XHCI_TRB_NOP XHCI_TRB_TYPE ( 8 )
-
- /** An enable slot transfer request block */
- struct xhci_trb_enable_slot {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint32_t reserved_b;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Slot type */
- uint8_t slot;
- /** Reserved */
- uint8_t reserved_c;
- } __attribute__ (( packed ));
-
- /** An enable slot transfer request block */
- #define XHCI_TRB_ENABLE_SLOT XHCI_TRB_TYPE ( 9 )
-
- /** A disable slot transfer request block */
- struct xhci_trb_disable_slot {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint32_t reserved_b;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint8_t reserved_c;
- /** Slot ID */
- uint8_t slot;
- } __attribute__ (( packed ));
-
- /** A disable slot transfer request block */
- #define XHCI_TRB_DISABLE_SLOT XHCI_TRB_TYPE ( 10 )
-
- /** A context transfer request block */
- struct xhci_trb_context {
- /** Input context */
- uint64_t input;
- /** Reserved */
- uint32_t reserved_a;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint8_t reserved_b;
- /** Slot ID */
- uint8_t slot;
- } __attribute__ (( packed ));
-
- /** An address device transfer request block */
- #define XHCI_TRB_ADDRESS_DEVICE XHCI_TRB_TYPE ( 11 )
-
- /** A configure endpoint transfer request block */
- #define XHCI_TRB_CONFIGURE_ENDPOINT XHCI_TRB_TYPE ( 12 )
-
- /** An evaluate context transfer request block */
- #define XHCI_TRB_EVALUATE_CONTEXT XHCI_TRB_TYPE ( 13 )
-
- /** A reset endpoint transfer request block */
- struct xhci_trb_reset_endpoint {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint32_t reserved_b;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Endpoint ID */
- uint8_t endpoint;
- /** Slot ID */
- uint8_t slot;
- } __attribute__ (( packed ));
-
- /** A reset endpoint transfer request block */
- #define XHCI_TRB_RESET_ENDPOINT XHCI_TRB_TYPE ( 14 )
-
- /** A stop endpoint transfer request block */
- struct xhci_trb_stop_endpoint {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint32_t reserved_b;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Endpoint ID */
- uint8_t endpoint;
- /** Slot ID */
- uint8_t slot;
- } __attribute__ (( packed ));
-
- /** A stop endpoint transfer request block */
- #define XHCI_TRB_STOP_ENDPOINT XHCI_TRB_TYPE ( 15 )
-
- /** A set transfer ring dequeue pointer transfer request block */
- struct xhci_trb_set_tr_dequeue_pointer {
- /** Dequeue pointer */
- uint64_t dequeue;
- /** Reserved */
- uint32_t reserved;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Endpoint ID */
- uint8_t endpoint;
- /** Slot ID */
- uint8_t slot;
- } __attribute__ (( packed ));
-
- /** A set transfer ring dequeue pointer transfer request block */
- #define XHCI_TRB_SET_TR_DEQUEUE_POINTER XHCI_TRB_TYPE ( 16 )
-
- /** A no-op command transfer request block */
- #define XHCI_TRB_NOP_CMD XHCI_TRB_TYPE ( 23 )
-
- /** A transfer event transfer request block */
- struct xhci_trb_transfer {
- /** Transfer TRB pointer */
- uint64_t transfer;
- /** Residual transfer length */
- uint16_t residual;
- /** Reserved */
- uint8_t reserved;
- /** Completion code */
- uint8_t code;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Endpoint ID */
- uint8_t endpoint;
- /** Slot ID */
- uint8_t slot;
- } __attribute__ (( packed ));
-
- /** A transfer event transfer request block */
- #define XHCI_TRB_TRANSFER XHCI_TRB_TYPE ( 32 )
-
- /** A command completion event transfer request block */
- struct xhci_trb_complete {
- /** Command TRB pointer */
- uint64_t command;
- /** Parameter */
- uint8_t parameter[3];
- /** Completion code */
- uint8_t code;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Virtual function ID */
- uint8_t vf;
- /** Slot ID */
- uint8_t slot;
- } __attribute__ (( packed ));
-
- /** A command completion event transfer request block */
- #define XHCI_TRB_COMPLETE XHCI_TRB_TYPE ( 33 )
-
- /** xHCI completion codes */
- enum xhci_completion_code {
- /** Success */
- XHCI_CMPLT_SUCCESS = 1,
- /** Short packet */
- XHCI_CMPLT_SHORT = 13,
- /** Command ring stopped */
- XHCI_CMPLT_CMD_STOPPED = 24,
- };
-
- /** A port status change transfer request block */
- struct xhci_trb_port_status {
- /** Reserved */
- uint8_t reserved_a[3];
- /** Port ID */
- uint8_t port;
- /** Reserved */
- uint8_t reserved_b[7];
- /** Completion code */
- uint8_t code;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint16_t reserved_c;
- } __attribute__ (( packed ));
-
- /** A port status change transfer request block */
- #define XHCI_TRB_PORT_STATUS XHCI_TRB_TYPE ( 34 )
-
- /** A port status change transfer request block */
- struct xhci_trb_host_controller {
- /** Reserved */
- uint64_t reserved_a;
- /** Reserved */
- uint8_t reserved_b[3];
- /** Completion code */
- uint8_t code;
- /** Flags */
- uint8_t flags;
- /** Type */
- uint8_t type;
- /** Reserved */
- uint16_t reserved_c;
- } __attribute__ (( packed ));
-
- /** A port status change transfer request block */
- #define XHCI_TRB_HOST_CONTROLLER XHCI_TRB_TYPE ( 37 )
-
- /** A transfer request block */
- union xhci_trb {
- /** Template */
- struct xhci_trb_template template;
- /** Common fields */
- struct xhci_trb_common common;
- /** Normal TRB */
- struct xhci_trb_normal normal;
- /** Setup stage TRB */
- struct xhci_trb_setup setup;
- /** Data stage TRB */
- struct xhci_trb_data data;
- /** Status stage TRB */
- struct xhci_trb_status status;
- /** Link TRB */
- struct xhci_trb_link link;
- /** Enable slot TRB */
- struct xhci_trb_enable_slot enable;
- /** Disable slot TRB */
- struct xhci_trb_disable_slot disable;
- /** Input context TRB */
- struct xhci_trb_context context;
- /** Reset endpoint TRB */
- struct xhci_trb_reset_endpoint reset;
- /** Stop endpoint TRB */
- struct xhci_trb_stop_endpoint stop;
- /** Set transfer ring dequeue pointer TRB */
- struct xhci_trb_set_tr_dequeue_pointer dequeue;
- /** Transfer event */
- struct xhci_trb_transfer transfer;
- /** Command completion event */
- struct xhci_trb_complete complete;
- /** Port status changed event */
- struct xhci_trb_port_status port;
- /** Host controller event */
- struct xhci_trb_host_controller host;
- } __attribute__ (( packed ));
-
- /** An input control context */
- struct xhci_control_context {
- /** Drop context flags */
- uint32_t drop;
- /** Add context flags */
- uint32_t add;
- /** Reserved */
- uint32_t reserved_a[5];
- /** Configuration value */
- uint8_t config;
- /** Interface number */
- uint8_t intf;
- /** Alternate setting */
- uint8_t alt;
- /** Reserved */
- uint8_t reserved_b;
- } __attribute__ (( packed ));
-
- /** A slot context */
- struct xhci_slot_context {
- /** Device info */
- uint32_t info;
- /** Maximum exit latency */
- uint16_t latency;
- /** Root hub port number */
- uint8_t port;
- /** Number of downstream ports */
- uint8_t ports;
- /** TT hub slot ID */
- uint8_t tt_id;
- /** TT port number */
- uint8_t tt_port;
- /** Interrupter target */
- uint16_t intr;
- /** USB address */
- uint8_t address;
- /** Reserved */
- uint16_t reserved_a;
- /** Slot state */
- uint8_t state;
- /** Reserved */
- uint32_t reserved_b[4];
- } __attribute__ (( packed ));
-
- /** Construct slot context device info */
- #define XHCI_SLOT_INFO( entries, hub, speed, route ) \
- ( ( (entries) << 27 ) | ( (hub) << 26 ) | ( (speed) << 20 ) | (route) )
-
- /** An endpoint context */
- struct xhci_endpoint_context {
- /** Endpoint state */
- uint8_t state;
- /** Stream configuration */
- uint8_t stream;
- /** Polling interval */
- uint8_t interval;
- /** Max ESIT payload high */
- uint8_t esit_high;
- /** Endpoint type */
- uint8_t type;
- /** Maximum burst size */
- uint8_t burst;
- /** Maximum packet size */
- uint16_t mtu;
- /** Transfer ring dequeue pointer */
- uint64_t dequeue;
- /** Average TRB length */
- uint16_t trb_len;
- /** Max ESIT payload low */
- uint16_t esit_low;
- /** Reserved */
- uint32_t reserved[3];
- } __attribute__ (( packed ));
-
- /** Endpoint states */
- enum xhci_endpoint_state {
- /** Endpoint is disabled */
- XHCI_ENDPOINT_DISABLED = 0,
- /** Endpoint is running */
- XHCI_ENDPOINT_RUNNING = 1,
- /** Endpoint is halted due to a USB Halt condition */
- XHCI_ENDPOINT_HALTED = 2,
- /** Endpoint is stopped */
- XHCI_ENDPOINT_STOPPED = 3,
- /** Endpoint is halted due to a TRB error */
- XHCI_ENDPOINT_ERROR = 4,
- };
-
- /** Endpoint state mask */
- #define XHCI_ENDPOINT_STATE_MASK 0x07
-
- /** Endpoint type */
- #define XHCI_EP_TYPE(type) ( (type) << 3 )
-
- /** Control endpoint type */
- #define XHCI_EP_TYPE_CONTROL XHCI_EP_TYPE ( 4 )
-
- /** Input endpoint type */
- #define XHCI_EP_TYPE_IN XHCI_EP_TYPE ( 4 )
-
- /** Periodic endpoint type */
- #define XHCI_EP_TYPE_PERIODIC XHCI_EP_TYPE ( 1 )
-
- /** Endpoint dequeue cycle state */
- #define XHCI_EP_DCS 0x00000001UL
-
- /** Control endpoint average TRB length */
- #define XHCI_EP0_TRB_LEN 8
-
- /** An event ring segment */
- struct xhci_event_ring_segment {
- /** Base address */
- uint64_t base;
- /** Number of TRBs */
- uint32_t count;
- /** Reserved */
- uint32_t reserved;
- } __attribute__ (( packed ));
-
- /** A transfer request block command/transfer ring */
- struct xhci_trb_ring {
- /** Producer counter */
- unsigned int prod;
- /** Consumer counter */
- unsigned int cons;
- /** Ring size (log2) */
- unsigned int shift;
- /** Ring counter mask */
- unsigned int mask;
-
- /** I/O buffers */
- struct io_buffer **iobuf;
-
- /** Transfer request blocks */
- union xhci_trb *trb;
- /** Length of transfer request blocks */
- size_t len;
- /** Link TRB (if applicable) */
- struct xhci_trb_link *link;
-
- /** Doorbell register */
- void *db;
- /** Doorbell register value */
- uint32_t dbval;
- };
-
- /** An event ring */
- struct xhci_event_ring {
- /** Consumer counter */
- unsigned int cons;
- /** Event ring segment table */
- struct xhci_event_ring_segment *segment;
- /** Transfer request blocks */
- union xhci_trb *trb;
- };
-
- /**
- * Calculate doorbell register value
- *
- * @v target Doorbell target
- * @v stream Doorbell stream ID
- * @ret dbval Doorbell register value
- */
- #define XHCI_DBVAL( target, stream ) ( (target) | ( (stream) << 16 ) )
-
- /**
- * Calculate space used in TRB ring
- *
- * @v ring TRB ring
- * @ret fill Number of entries used
- */
- static inline __attribute__ (( always_inline )) unsigned int
- xhci_ring_fill ( struct xhci_trb_ring *ring ) {
-
- return ( ring->prod - ring->cons );
- }
-
- /**
- * Calculate space remaining in TRB ring
- *
- * @v ring TRB ring
- * @ret remaining Number of entries remaining
- *
- * xHCI does not allow us to completely fill a ring; there must be at
- * least one free entry (excluding the Link TRB).
- */
- static inline __attribute__ (( always_inline )) unsigned int
- xhci_ring_remaining ( struct xhci_trb_ring *ring ) {
- unsigned int fill = xhci_ring_fill ( ring );
-
- /* We choose to utilise rings with ( 2^n + 1 ) entries, with
- * the final entry being a Link TRB. The maximum fill level
- * is therefore
- *
- * ( ( 2^n + 1 ) - 1 (Link TRB) - 1 (one slot always empty)
- * == ( 2^n - 1 )
- *
- * which is therefore equal to the ring mask.
- */
- assert ( fill <= ring->mask );
- return ( ring->mask - fill );
- }
-
- /**
- * Calculate physical address of most recently consumed TRB
- *
- * @v ring TRB ring
- * @ret trb TRB physical address
- */
- static inline __attribute__ (( always_inline )) physaddr_t
- xhci_ring_consumed ( struct xhci_trb_ring *ring ) {
- unsigned int index = ( ( ring->cons - 1 ) & ring->mask );
-
- return virt_to_phys ( &ring->trb[index] );
- }
-
- /** Slot context index */
- #define XHCI_CTX_SLOT 0
-
- /** Calculate context index from USB endpoint address */
- #define XHCI_CTX(address) \
- ( (address) ? ( ( ( (address) & 0x0f ) << 1 ) | \
- ( ( (address) & 0x80 ) >> 7 ) ) : 1 )
-
- /** Endpoint zero context index */
- #define XHCI_CTX_EP0 XHCI_CTX ( 0x00 )
-
- /** End of contexts */
- #define XHCI_CTX_END 32
-
- /** Device context index */
- #define XHCI_DCI(ctx) ( (ctx) + 0 )
-
- /** Input context index */
- #define XHCI_ICI(ctx) ( (ctx) + 1 )
-
- /** Number of TRBs (excluding Link TRB) in the command ring
- *
- * This is a policy decision.
- */
- #define XHCI_CMD_TRBS_LOG2 2
-
- /** Number of TRBs in the event ring
- *
- * This is a policy decision.
- */
- #define XHCI_EVENT_TRBS_LOG2 6
-
- /** Number of TRBs in a transfer ring
- *
- * This is a policy decision.
- */
- #define XHCI_TRANSFER_TRBS_LOG2 6
-
- /** Maximum time to wait for BIOS to release ownership
- *
- * This is a policy decision.
- */
- #define XHCI_USBLEGSUP_MAX_WAIT_MS 100
-
- /** Maximum time to wait for host controller to stop
- *
- * This is a policy decision.
- */
- #define XHCI_STOP_MAX_WAIT_MS 100
-
- /** Maximum time to wait for reset to complete
- *
- * This is a policy decision.
- */
- #define XHCI_RESET_MAX_WAIT_MS 500
-
- /** Maximum time to wait for a command to complete
- *
- * The "address device" command involves waiting for a response to a
- * USB control transaction, and so we must wait for up to the 5000ms
- * that USB allows for devices to respond to control transactions.
- */
- #define XHCI_COMMAND_MAX_WAIT_MS USB_CONTROL_MAX_WAIT_MS
-
- /** Time to delay after aborting a command
- *
- * This is a policy decision
- */
- #define XHCI_COMMAND_ABORT_DELAY_MS 500
-
- /** Maximum time to wait for a port reset to complete
- *
- * This is a policy decision.
- */
- #define XHCI_PORT_RESET_MAX_WAIT_MS 500
-
- /** Intel PCH quirk */
- struct xhci_pch {
- /** USB2 port routing register original value */
- uint32_t xusb2pr;
- /** USB3 port SuperSpeed enable register original value */
- uint32_t usb3pssen;
- };
-
- /** Intel PCH quirk flag */
- #define XHCI_PCH 0x0001
-
- /** Intel PCH USB2 port routing register */
- #define XHCI_PCH_XUSB2PR 0xd0
-
- /** Intel PCH USB2 port routing mask register */
- #define XHCI_PCH_XUSB2PRM 0xd4
-
- /** Intel PCH SuperSpeed enable register */
- #define XHCI_PCH_USB3PSSEN 0xd8
-
- /** Intel PCH USB3 port routing mask register */
- #define XHCI_PCH_USB3PRM 0xdc
-
- /** Invalid protocol speed ID values quirk */
- #define XHCI_BAD_PSIV 0x0002
-
- /** An xHCI device */
- struct xhci_device {
- /** Registers */
- void *regs;
- /** Name */
- const char *name;
- /** Quirks */
- unsigned int quirks;
-
- /** Capability registers */
- void *cap;
- /** Operational registers */
- void *op;
- /** Runtime registers */
- void *run;
- /** Doorbell registers */
- void *db;
-
- /** Number of device slots */
- unsigned int slots;
- /** Number of interrupters */
- unsigned int intrs;
- /** Number of ports */
- unsigned int ports;
-
- /** Number of page-sized scratchpad buffers */
- unsigned int scratchpads;
-
- /** 64-bit addressing capability */
- int addr64;
- /** Context size shift */
- unsigned int csz_shift;
- /** xHCI extended capabilities offset */
- unsigned int xecp;
-
- /** Page size */
- size_t pagesize;
-
- /** USB legacy support capability (if present and enabled) */
- unsigned int legacy;
-
- /** Device context base address array */
- uint64_t *dcbaa;
-
- /** Scratchpad buffer area */
- userptr_t scratchpad;
- /** Scratchpad buffer array */
- uint64_t *scratchpad_array;
-
- /** Command ring */
- struct xhci_trb_ring command;
- /** Event ring */
- struct xhci_event_ring event;
- /** Current command (if any) */
- union xhci_trb *pending;
-
- /** Device slots, indexed by slot ID */
- struct xhci_slot **slot;
-
- /** USB bus */
- struct usb_bus *bus;
-
- /** Intel PCH quirk */
- struct xhci_pch pch;
- };
-
- /** An xHCI device slot */
- struct xhci_slot {
- /** xHCI device */
- struct xhci_device *xhci;
- /** USB device */
- struct usb_device *usb;
- /** Slot ID */
- unsigned int id;
- /** Slot context */
- struct xhci_slot_context *context;
- /** Route string */
- unsigned int route;
- /** Root hub port number */
- unsigned int port;
- /** Protocol speed ID */
- unsigned int psiv;
- /** Number of ports (if this device is a hub) */
- unsigned int ports;
- /** Transaction translator slot ID */
- unsigned int tt_id;
- /** Transaction translator port */
- unsigned int tt_port;
- /** Endpoints, indexed by context ID */
- struct xhci_endpoint *endpoint[XHCI_CTX_END];
- };
-
- /** An xHCI endpoint */
- struct xhci_endpoint {
- /** xHCI device */
- struct xhci_device *xhci;
- /** xHCI slot */
- struct xhci_slot *slot;
- /** USB endpoint */
- struct usb_endpoint *ep;
- /** Context index */
- unsigned int ctx;
- /** Endpoint type */
- unsigned int type;
- /** Endpoint interval */
- unsigned int interval;
- /** Endpoint context */
- struct xhci_endpoint_context *context;
- /** Transfer ring */
- struct xhci_trb_ring ring;
- };
-
- #endif /* _IPXE_XHCI_H */
|