[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 1/8] hw/usb/xhci: Move HCD constants to a header and add regis
From: |
Nicholas Piggin |
Subject: |
[PATCH v2 1/8] hw/usb/xhci: Move HCD constants to a header and add register constants |
Date: |
Sat, 18 Jan 2025 17:08:46 +1000 |
Prepare to use some of these constants in xhci qtest code.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
hw/usb/hcd-xhci.h | 214 ++++++++++++++++++++++
hw/usb/hcd-xhci.c | 450 +++++++++++++++-------------------------------
2 files changed, 360 insertions(+), 304 deletions(-)
diff --git a/hw/usb/hcd-xhci.h b/hw/usb/hcd-xhci.h
index 9609b835141..bd1d8e8e81a 100644
--- a/hw/usb/hcd-xhci.h
+++ b/hw/usb/hcd-xhci.h
@@ -115,6 +115,220 @@ typedef enum TRBCCode {
CC_SPLIT_TRANSACTION_ERROR
} TRBCCode;
+/* Register definitions */
+#define XHCI_HCCAP_REG_CAPLENGTH 0x00
+#define XHCI_HCCAP_REG_HCIVERSION 0x02
+#define XHCI_HCCAP_REG_HCSPARAMS1 0x04
+#define XHCI_HCCAP_REG_HCSPARAMS2 0x08
+#define XHCI_HCCAP_REG_HCSPARAMS3 0x0C
+#define XHCI_HCCAP_REG_HCCPARAMS1 0x10
+#define XHCI_HCCPARAMS1_AC64 0x00000001
+#define XHCI_HCCPARAMS1_XECP_SHIFT 16
+#define XHCI_HCCPARAMS1_MAXPSASIZE_SHIFT 12
+#define XHCI_HCCAP_REG_DBOFF 0x14
+#define XHCI_HCCAP_REG_RTSOFF 0x18
+#define XHCI_HCCAP_REG_HCCPARAMS2 0x1C
+#define XHCI_HCCAP_EXTCAP_START 0x20 /* SW-defined */
+
+#define XHCI_PORT_PR_SZ 0x10
+#define XHCI_PORT_REG_PORTSC 0x00
+#define XHCI_PORTSC_CCS (1 << 0)
+#define XHCI_PORTSC_PED (1 << 1)
+#define XHCI_PORTSC_OCA (1 << 3)
+#define XHCI_PORTSC_PR (1 << 4)
+#define XHCI_PORTSC_PLS_SHIFT 5
+#define XHCI_PORTSC_PLS_MASK 0xf
+#define XHCI_PORTSC_PP (1 << 9)
+#define XHCI_PORTSC_SPEED_SHIFT 10
+#define XHCI_PORTSC_SPEED_MASK 0xf
+#define XHCI_PORTSC_SPEED_FULL (1 << 10)
+#define XHCI_PORTSC_SPEED_LOW (2 << 10)
+#define XHCI_PORTSC_SPEED_HIGH (3 << 10)
+#define XHCI_PORTSC_SPEED_SUPER (4 << 10)
+#define XHCI_PORTSC_PIC_SHIFT 14
+#define XHCI_PORTSC_PIC_MASK 0x3
+#define XHCI_PORTSC_LWS (1 << 16)
+#define XHCI_PORTSC_CSC (1 << 17)
+#define XHCI_PORTSC_PEC (1 << 18)
+#define XHCI_PORTSC_WRC (1 << 19)
+#define XHCI_PORTSC_OCC (1 << 20)
+#define XHCI_PORTSC_PRC (1 << 21)
+#define XHCI_PORTSC_PLC (1 << 22)
+#define XHCI_PORTSC_CEC (1 << 23)
+#define XHCI_PORTSC_CAS (1 << 24)
+#define XHCI_PORTSC_WCE (1 << 25)
+#define XHCI_PORTSC_WDE (1 << 26)
+#define XHCI_PORTSC_WOE (1 << 27)
+#define XHCI_PORTSC_DR (1 << 30)
+#define XHCI_PORTSC_WPR (1 << 31)
+/* read/write bits */
+#define XHCI_PORTSC_RW_MASK (XHCI_PORTSC_PP | \
+ XHCI_PORTSC_WCE | \
+ XHCI_PORTSC_WDE | \
+ XHCI_PORTSC_WOE)
+/* write-1-to-clear bits*/
+#define XHCI_PORTSC_W1C_MASK (XHCI_PORTSC_CSC | \
+ XHCI_PORTSC_PEC | \
+ XHCI_PORTSC_WRC | \
+ XHCI_PORTSC_OCC | \
+ XHCI_PORTSC_PRC | \
+ XHCI_PORTSC_PLC | \
+ XHCI_PORTSC_CEC)
+#define XHCI_PORT_REG_PORTPMSC 0x04
+#define XHCI_PORT_REG_PORTLI 0x08
+#define XHCI_PORT_REG_PORTHLPMC 0x0C
+
+#define XHCI_OPER_REG_USBCMD 0x00
+#define XHCI_USBCMD_RS (1 << 0)
+#define XHCI_USBCMD_HCRST (1 << 1)
+#define XHCI_USBCMD_INTE (1 << 2)
+#define XHCI_USBCMD_HSEE (1 << 3)
+#define XHCI_USBCMD_LHCRST (1 << 7)
+#define XHCI_USBCMD_CSS (1 << 8)
+#define XHCI_USBCMD_CRS (1 << 9)
+#define XHCI_USBCMD_EWE (1 << 10)
+#define XHCI_USBCMD_EU3S (1 << 11)
+#define XHCI_OPER_REG_USBSTS 0x04
+#define XHCI_USBSTS_HCH (1 << 0)
+#define XHCI_USBSTS_HSE (1 << 2)
+#define XHCI_USBSTS_EINT (1 << 3)
+#define XHCI_USBSTS_PCD (1 << 4)
+#define XHCI_USBSTS_SSS (1 << 8)
+#define XHCI_USBSTS_RSS (1 << 9)
+#define XHCI_USBSTS_SRE (1 << 10)
+#define XHCI_USBSTS_CNR (1 << 11)
+#define XHCI_USBSTS_HCE (1 << 12)
+/* these bits are write-1-to-clear */
+#define XHCI_USBSTS_W1C_MASK (XHCI_USBSTS_HSE | \
+ XHCI_USBSTS_EINT | \
+ XHCI_USBSTS_PCD | \
+ XHCI_USBSTS_SRE)
+#define XHCI_OPER_REG_PAGESIZE 0x08
+#define XHCI_OPER_REG_DNCTRL 0x14
+#define XHCI_OPER_REG_CRCR_LO 0x18
+#define XHCI_CRCR_RCS (1 << 0)
+#define XHCI_CRCR_CS (1 << 1)
+#define XHCI_CRCR_CA (1 << 2)
+#define XHCI_CRCR_CRR (1 << 3)
+#define XHCI_OPER_REG_CRCR_HI 0x1C
+#define XHCI_OPER_REG_DCBAAP_LO 0x30
+#define XHCI_OPER_REG_DCBAAP_HI 0x34
+#define XHCI_OPER_REG_CONFIG 0x38
+
+#define XHCI_DBELL_DB_SZ 0x4
+
+#define XHCI_INTR_REG_MFINDEX 0x00
+#define XHCI_INTR_REG_IR0 0x20
+#define XHCI_INTR_IR_SZ 0x20
+
+#define XHCI_INTR_REG_IMAN 0x00
+#define XHCI_IMAN_IP (1 << 0)
+#define XHCI_IMAN_IE (1 << 1)
+#define XHCI_INTR_REG_IMOD 0x04
+#define XHCI_INTR_REG_ERSTSZ 0x08
+#define XHCI_INTR_REG_ERSTBA_LO 0x10
+#define XHCI_INTR_REG_ERSTBA_HI 0x14
+#define XHCI_INTR_REG_ERDP_LO 0x18
+#define XHCI_ERDP_EHB (1 << 3)
+#define XHCI_INTR_REG_ERDP_HI 0x1C
+
+#define TRB_SIZE 16
+typedef struct XHCITRB {
+ uint64_t parameter;
+ uint32_t status;
+ uint32_t control;
+ dma_addr_t addr;
+ bool ccs;
+} XHCITRB;
+
+enum {
+ PLS_U0 = 0,
+ PLS_U1 = 1,
+ PLS_U2 = 2,
+ PLS_U3 = 3,
+ PLS_DISABLED = 4,
+ PLS_RX_DETECT = 5,
+ PLS_INACTIVE = 6,
+ PLS_POLLING = 7,
+ PLS_RECOVERY = 8,
+ PLS_HOT_RESET = 9,
+ PLS_COMPILANCE_MODE = 10,
+ PLS_TEST_MODE = 11,
+ PLS_RESUME = 15,
+};
+
+#define CR_LINK TR_LINK
+
+#define TRB_C (1 << 0)
+#define TRB_TYPE_SHIFT 10
+#define TRB_TYPE_MASK 0x3f
+#define TRB_TYPE(t) (((t).control >> TRB_TYPE_SHIFT) & TRB_TYPE_MASK)
+
+#define TRB_EV_ED (1 << 2)
+
+#define TRB_TR_ENT (1 << 1)
+#define TRB_TR_ISP (1 << 2)
+#define TRB_TR_NS (1 << 3)
+#define TRB_TR_CH (1 << 4)
+#define TRB_TR_IOC (1 << 5)
+#define TRB_TR_IDT (1 << 6)
+#define TRB_TR_TBC_SHIFT 7
+#define TRB_TR_TBC_MASK 0x3
+#define TRB_TR_BEI (1 << 9)
+#define TRB_TR_TLBPC_SHIFT 16
+#define TRB_TR_TLBPC_MASK 0xf
+#define TRB_TR_FRAMEID_SHIFT 20
+#define TRB_TR_FRAMEID_MASK 0x7ff
+#define TRB_TR_SIA (1 << 31)
+
+#define TRB_TR_DIR (1 << 16)
+
+#define TRB_CR_SLOTID_SHIFT 24
+#define TRB_CR_SLOTID_MASK 0xff
+#define TRB_CR_EPID_SHIFT 16
+#define TRB_CR_EPID_MASK 0x1f
+
+#define TRB_CR_BSR (1 << 9)
+#define TRB_CR_DC (1 << 9)
+
+#define TRB_LK_TC (1 << 1)
+
+#define TRB_INTR_SHIFT 22
+#define TRB_INTR_MASK 0x3ff
+#define TRB_INTR(t) (((t).status >> TRB_INTR_SHIFT) & TRB_INTR_MASK)
+
+#define EP_TYPE_MASK 0x7
+#define EP_TYPE_SHIFT 3
+
+#define EP_STATE_MASK 0x7
+#define EP_DISABLED (0 << 0)
+#define EP_RUNNING (1 << 0)
+#define EP_HALTED (2 << 0)
+#define EP_STOPPED (3 << 0)
+#define EP_ERROR (4 << 0)
+
+#define SLOT_STATE_MASK 0x1f
+#define SLOT_STATE_SHIFT 27
+#define SLOT_STATE(s) (((s) >> SLOT_STATE_SHIFT) & SLOT_STATE_MASK)
+#define SLOT_ENABLED 0
+#define SLOT_DEFAULT 1
+#define SLOT_ADDRESSED 2
+#define SLOT_CONFIGURED 3
+
+#define SLOT_CONTEXT_ENTRIES_MASK 0x1f
+#define SLOT_CONTEXT_ENTRIES_SHIFT 27
+
+typedef enum EPType {
+ ET_INVALID = 0,
+ ET_ISO_OUT,
+ ET_BULK_OUT,
+ ET_INTR_OUT,
+ ET_CONTROL,
+ ET_ISO_IN,
+ ET_BULK_IN,
+ ET_INTR_IN,
+} EPType;
+
typedef struct XHCIRing {
dma_addr_t dequeue;
bool ccs;
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 00d5bc37792..d21b0543957 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -47,8 +47,8 @@
#define TRANSFER_LIMIT 256
#define LEN_CAP 0x40
-#define LEN_OPER (0x400 + 0x10 * XHCI_MAXPORTS)
-#define LEN_RUNTIME ((XHCI_MAXINTRS + 1) * 0x20)
+#define LEN_OPER (0x400 + XHCI_PORT_PR_SZ * XHCI_MAXPORTS)
+#define LEN_RUNTIME ((XHCI_MAXINTRS + 1) * XHCI_INTR_IR_SZ)
#define LEN_DOORBELL ((XHCI_MAXSLOTS + 1) * 0x20)
#define OFF_OPER LEN_CAP
@@ -65,154 +65,6 @@
# error Increase XHCI_LEN_REGS
#endif
-/* bit definitions */
-#define USBCMD_RS (1<<0)
-#define USBCMD_HCRST (1<<1)
-#define USBCMD_INTE (1<<2)
-#define USBCMD_HSEE (1<<3)
-#define USBCMD_LHCRST (1<<7)
-#define USBCMD_CSS (1<<8)
-#define USBCMD_CRS (1<<9)
-#define USBCMD_EWE (1<<10)
-#define USBCMD_EU3S (1<<11)
-
-#define USBSTS_HCH (1<<0)
-#define USBSTS_HSE (1<<2)
-#define USBSTS_EINT (1<<3)
-#define USBSTS_PCD (1<<4)
-#define USBSTS_SSS (1<<8)
-#define USBSTS_RSS (1<<9)
-#define USBSTS_SRE (1<<10)
-#define USBSTS_CNR (1<<11)
-#define USBSTS_HCE (1<<12)
-
-
-#define PORTSC_CCS (1<<0)
-#define PORTSC_PED (1<<1)
-#define PORTSC_OCA (1<<3)
-#define PORTSC_PR (1<<4)
-#define PORTSC_PLS_SHIFT 5
-#define PORTSC_PLS_MASK 0xf
-#define PORTSC_PP (1<<9)
-#define PORTSC_SPEED_SHIFT 10
-#define PORTSC_SPEED_MASK 0xf
-#define PORTSC_SPEED_FULL (1<<10)
-#define PORTSC_SPEED_LOW (2<<10)
-#define PORTSC_SPEED_HIGH (3<<10)
-#define PORTSC_SPEED_SUPER (4<<10)
-#define PORTSC_PIC_SHIFT 14
-#define PORTSC_PIC_MASK 0x3
-#define PORTSC_LWS (1<<16)
-#define PORTSC_CSC (1<<17)
-#define PORTSC_PEC (1<<18)
-#define PORTSC_WRC (1<<19)
-#define PORTSC_OCC (1<<20)
-#define PORTSC_PRC (1<<21)
-#define PORTSC_PLC (1<<22)
-#define PORTSC_CEC (1<<23)
-#define PORTSC_CAS (1<<24)
-#define PORTSC_WCE (1<<25)
-#define PORTSC_WDE (1<<26)
-#define PORTSC_WOE (1<<27)
-#define PORTSC_DR (1<<30)
-#define PORTSC_WPR (1<<31)
-
-#define CRCR_RCS (1<<0)
-#define CRCR_CS (1<<1)
-#define CRCR_CA (1<<2)
-#define CRCR_CRR (1<<3)
-
-#define IMAN_IP (1<<0)
-#define IMAN_IE (1<<1)
-
-#define ERDP_EHB (1<<3)
-
-#define TRB_SIZE 16
-typedef struct XHCITRB {
- uint64_t parameter;
- uint32_t status;
- uint32_t control;
- dma_addr_t addr;
- bool ccs;
-} XHCITRB;
-
-enum {
- PLS_U0 = 0,
- PLS_U1 = 1,
- PLS_U2 = 2,
- PLS_U3 = 3,
- PLS_DISABLED = 4,
- PLS_RX_DETECT = 5,
- PLS_INACTIVE = 6,
- PLS_POLLING = 7,
- PLS_RECOVERY = 8,
- PLS_HOT_RESET = 9,
- PLS_COMPILANCE_MODE = 10,
- PLS_TEST_MODE = 11,
- PLS_RESUME = 15,
-};
-
-#define CR_LINK TR_LINK
-
-#define TRB_C (1<<0)
-#define TRB_TYPE_SHIFT 10
-#define TRB_TYPE_MASK 0x3f
-#define TRB_TYPE(t) (((t).control >> TRB_TYPE_SHIFT) & TRB_TYPE_MASK)
-
-#define TRB_EV_ED (1<<2)
-
-#define TRB_TR_ENT (1<<1)
-#define TRB_TR_ISP (1<<2)
-#define TRB_TR_NS (1<<3)
-#define TRB_TR_CH (1<<4)
-#define TRB_TR_IOC (1<<5)
-#define TRB_TR_IDT (1<<6)
-#define TRB_TR_TBC_SHIFT 7
-#define TRB_TR_TBC_MASK 0x3
-#define TRB_TR_BEI (1<<9)
-#define TRB_TR_TLBPC_SHIFT 16
-#define TRB_TR_TLBPC_MASK 0xf
-#define TRB_TR_FRAMEID_SHIFT 20
-#define TRB_TR_FRAMEID_MASK 0x7ff
-#define TRB_TR_SIA (1<<31)
-
-#define TRB_TR_DIR (1<<16)
-
-#define TRB_CR_SLOTID_SHIFT 24
-#define TRB_CR_SLOTID_MASK 0xff
-#define TRB_CR_EPID_SHIFT 16
-#define TRB_CR_EPID_MASK 0x1f
-
-#define TRB_CR_BSR (1<<9)
-#define TRB_CR_DC (1<<9)
-
-#define TRB_LK_TC (1<<1)
-
-#define TRB_INTR_SHIFT 22
-#define TRB_INTR_MASK 0x3ff
-#define TRB_INTR(t) (((t).status >> TRB_INTR_SHIFT) & TRB_INTR_MASK)
-
-#define EP_TYPE_MASK 0x7
-#define EP_TYPE_SHIFT 3
-
-#define EP_STATE_MASK 0x7
-#define EP_DISABLED (0<<0)
-#define EP_RUNNING (1<<0)
-#define EP_HALTED (2<<0)
-#define EP_STOPPED (3<<0)
-#define EP_ERROR (4<<0)
-
-#define SLOT_STATE_MASK 0x1f
-#define SLOT_STATE_SHIFT 27
-#define SLOT_STATE(s) (((s)>>SLOT_STATE_SHIFT)&SLOT_STATE_MASK)
-#define SLOT_ENABLED 0
-#define SLOT_DEFAULT 1
-#define SLOT_ADDRESSED 2
-#define SLOT_CONFIGURED 3
-
-#define SLOT_CONTEXT_ENTRIES_MASK 0x1f
-#define SLOT_CONTEXT_ENTRIES_SHIFT 27
-
#define get_field(data, field) \
(((data) >> field##_SHIFT) & field##_MASK)
@@ -223,17 +75,6 @@ enum {
*data = val_; \
} while (0)
-typedef enum EPType {
- ET_INVALID = 0,
- ET_ISO_OUT,
- ET_BULK_OUT,
- ET_INTR_OUT,
- ET_CONTROL,
- ET_ISO_IN,
- ET_BULK_IN,
- ET_INTR_IN,
-} EPType;
-
typedef struct XHCITransfer {
XHCIEPContext *epctx;
USBPacket packet;
@@ -440,7 +281,7 @@ static uint64_t xhci_mfindex_get(XHCIState *xhci)
static void xhci_mfwrap_update(XHCIState *xhci)
{
- const uint32_t bits = USBCMD_RS | USBCMD_EWE;
+ const uint32_t bits = XHCI_USBCMD_RS | XHCI_USBCMD_EWE;
uint32_t mfindex, left;
int64_t now;
@@ -465,7 +306,7 @@ static void xhci_mfwrap_timer(void *opaque)
static void xhci_die(XHCIState *xhci)
{
- xhci->usbsts |= USBSTS_HCE;
+ xhci->usbsts |= XHCI_USBSTS_HCE;
DPRINTF("xhci: asserted controller error\n");
}
@@ -557,51 +398,51 @@ static void xhci_intr_update(XHCIState *xhci, int v)
int level = 0;
if (v == 0) {
- if (xhci->intr[0].iman & IMAN_IP &&
- xhci->intr[0].iman & IMAN_IE &&
- xhci->usbcmd & USBCMD_INTE) {
+ if (xhci->intr[0].iman & XHCI_IMAN_IP &&
+ xhci->intr[0].iman & XHCI_IMAN_IE &&
+ xhci->usbcmd & XHCI_USBCMD_INTE) {
level = 1;
}
if (xhci->intr_raise) {
if (xhci->intr_raise(xhci, 0, level)) {
- xhci->intr[0].iman &= ~IMAN_IP;
+ xhci->intr[0].iman &= ~XHCI_IMAN_IP;
}
}
}
if (xhci->intr_update) {
xhci->intr_update(xhci, v,
- xhci->intr[v].iman & IMAN_IE);
+ xhci->intr[v].iman & XHCI_IMAN_IE);
}
}
static void xhci_intr_raise(XHCIState *xhci, int v)
{
- bool pending = (xhci->intr[v].erdp_low & ERDP_EHB);
+ bool pending = (xhci->intr[v].erdp_low & XHCI_ERDP_EHB);
- xhci->intr[v].erdp_low |= ERDP_EHB;
- xhci->intr[v].iman |= IMAN_IP;
- xhci->usbsts |= USBSTS_EINT;
+ xhci->intr[v].erdp_low |= XHCI_ERDP_EHB;
+ xhci->intr[v].iman |= XHCI_IMAN_IP;
+ xhci->usbsts |= XHCI_USBSTS_EINT;
if (pending) {
return;
}
- if (!(xhci->intr[v].iman & IMAN_IE)) {
+ if (!(xhci->intr[v].iman & XHCI_IMAN_IE)) {
return;
}
- if (!(xhci->usbcmd & USBCMD_INTE)) {
+ if (!(xhci->usbcmd & XHCI_USBCMD_INTE)) {
return;
}
if (xhci->intr_raise) {
if (xhci->intr_raise(xhci, v, true)) {
- xhci->intr[v].iman &= ~IMAN_IP;
+ xhci->intr[v].iman &= ~XHCI_IMAN_IP;
}
}
}
static inline int xhci_running(XHCIState *xhci)
{
- return !(xhci->usbsts & USBSTS_HCH);
+ return !(xhci->usbsts & XHCI_USBSTS_HCH);
}
static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v)
@@ -845,15 +686,15 @@ static void xhci_er_reset(XHCIState *xhci, int v)
static void xhci_run(XHCIState *xhci)
{
trace_usb_xhci_run();
- xhci->usbsts &= ~USBSTS_HCH;
+ xhci->usbsts &= ~XHCI_USBSTS_HCH;
xhci->mfindex_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
static void xhci_stop(XHCIState *xhci)
{
trace_usb_xhci_stop();
- xhci->usbsts |= USBSTS_HCH;
- xhci->crcr_low &= ~CRCR_CRR;
+ xhci->usbsts |= XHCI_USBSTS_HCH;
+ xhci->crcr_low &= ~XHCI_CRCR_CRR;
}
static XHCIStreamContext *xhci_alloc_stream_contexts(unsigned count,
@@ -2479,7 +2320,7 @@ static void xhci_process_commands(XHCIState *xhci)
return;
}
- xhci->crcr_low |= CRCR_CRR;
+ xhci->crcr_low |= XHCI_CRCR_CRR;
while ((type = xhci_ring_fetch(xhci, &xhci->cmd_ring, &trb, &addr))) {
event.ptr = addr;
@@ -2631,32 +2472,32 @@ static void xhci_port_update(XHCIPort *port, int
is_detach)
uint32_t pls = PLS_RX_DETECT;
assert(port);
- port->portsc = PORTSC_PP;
+ port->portsc = XHCI_PORTSC_PP;
if (!is_detach && xhci_port_have_device(port)) {
- port->portsc |= PORTSC_CCS;
+ port->portsc |= XHCI_PORTSC_CCS;
switch (port->uport->dev->speed) {
case USB_SPEED_LOW:
- port->portsc |= PORTSC_SPEED_LOW;
+ port->portsc |= XHCI_PORTSC_SPEED_LOW;
pls = PLS_POLLING;
break;
case USB_SPEED_FULL:
- port->portsc |= PORTSC_SPEED_FULL;
+ port->portsc |= XHCI_PORTSC_SPEED_FULL;
pls = PLS_POLLING;
break;
case USB_SPEED_HIGH:
- port->portsc |= PORTSC_SPEED_HIGH;
+ port->portsc |= XHCI_PORTSC_SPEED_HIGH;
pls = PLS_POLLING;
break;
case USB_SPEED_SUPER:
- port->portsc |= PORTSC_SPEED_SUPER;
- port->portsc |= PORTSC_PED;
+ port->portsc |= XHCI_PORTSC_SPEED_SUPER;
+ port->portsc |= XHCI_PORTSC_PED;
pls = PLS_U0;
break;
}
}
- set_field(&port->portsc, pls, PORTSC_PLS);
+ set_field(&port->portsc, pls, XHCI_PORTSC_PLS);
trace_usb_xhci_port_link(port->portnr, pls);
- xhci_port_notify(port, PORTSC_CSC);
+ xhci_port_notify(port, XHCI_PORTSC_CSC);
}
static void xhci_port_reset(XHCIPort *port, bool warm_reset)
@@ -2672,20 +2513,20 @@ static void xhci_port_reset(XHCIPort *port, bool
warm_reset)
switch (port->uport->dev->speed) {
case USB_SPEED_SUPER:
if (warm_reset) {
- port->portsc |= PORTSC_WRC;
+ port->portsc |= XHCI_PORTSC_WRC;
}
/* fall through */
case USB_SPEED_LOW:
case USB_SPEED_FULL:
case USB_SPEED_HIGH:
- set_field(&port->portsc, PLS_U0, PORTSC_PLS);
+ set_field(&port->portsc, PLS_U0, XHCI_PORTSC_PLS);
trace_usb_xhci_port_link(port->portnr, PLS_U0);
- port->portsc |= PORTSC_PED;
+ port->portsc |= XHCI_PORTSC_PED;
break;
}
- port->portsc &= ~PORTSC_PR;
- xhci_port_notify(port, PORTSC_PRC);
+ port->portsc &= ~XHCI_PORTSC_PR;
+ xhci_port_notify(port, XHCI_PORTSC_PRC);
}
static void xhci_reset(DeviceState *dev)
@@ -2694,12 +2535,12 @@ static void xhci_reset(DeviceState *dev)
int i;
trace_usb_xhci_reset();
- if (!(xhci->usbsts & USBSTS_HCH)) {
+ if (!(xhci->usbsts & XHCI_USBSTS_HCH)) {
DPRINTF("xhci: reset while running!\n");
}
xhci->usbcmd = 0;
- xhci->usbsts = USBSTS_HCH;
+ xhci->usbsts = XHCI_USBSTS_HCH;
xhci->dnctrl = 0;
xhci->crcr_low = 0;
xhci->crcr_high = 0;
@@ -2740,56 +2581,56 @@ static uint64_t xhci_cap_read(void *ptr, hwaddr reg,
unsigned size)
uint32_t ret;
switch (reg) {
- case 0x00: /* HCIVERSION, CAPLENGTH */
+ case XHCI_HCCAP_REG_CAPLENGTH: /* Covers HCIVERSION and CAPLENGTH */
ret = 0x01000000 | LEN_CAP;
break;
- case 0x04: /* HCSPARAMS 1 */
+ case XHCI_HCCAP_REG_HCSPARAMS1:
ret = ((xhci->numports_2+xhci->numports_3)<<24)
| (xhci->numintrs<<8) | xhci->numslots;
break;
- case 0x08: /* HCSPARAMS 2 */
+ case XHCI_HCCAP_REG_HCSPARAMS2:
ret = 0x0000000f;
break;
- case 0x0c: /* HCSPARAMS 3 */
+ case XHCI_HCCAP_REG_HCSPARAMS3:
ret = 0x00000000;
break;
- case 0x10: /* HCCPARAMS */
- if (sizeof(dma_addr_t) == 4) {
- ret = 0x00080000 | (xhci->max_pstreams_mask << 12);
- } else {
- ret = 0x00080001 | (xhci->max_pstreams_mask << 12);
+ case XHCI_HCCAP_REG_HCCPARAMS1:
+ ret = (XHCI_HCCAP_EXTCAP_START / 4) << XHCI_HCCPARAMS1_XECP_SHIFT;
+ ret |= xhci->max_pstreams_mask << XHCI_HCCPARAMS1_MAXPSASIZE_SHIFT;
+ if (sizeof(dma_addr_t) == 8) {
+ ret |= XHCI_HCCPARAMS1_AC64;
}
break;
- case 0x14: /* DBOFF */
+ case XHCI_HCCAP_REG_DBOFF:
ret = OFF_DOORBELL;
break;
- case 0x18: /* RTSOFF */
+ case XHCI_HCCAP_REG_RTSOFF:
ret = OFF_RUNTIME;
break;
/* extended capabilities */
- case 0x20: /* Supported Protocol:00 */
+ case XHCI_HCCAP_EXTCAP_START + 0x00: /* Supported Protocol:00 */
ret = 0x02000402; /* USB 2.0 */
break;
- case 0x24: /* Supported Protocol:04 */
+ case XHCI_HCCAP_EXTCAP_START + 0x04: /* Supported Protocol:04 */
ret = 0x20425355; /* "USB " */
break;
- case 0x28: /* Supported Protocol:08 */
+ case XHCI_HCCAP_EXTCAP_START + 0x08: /* Supported Protocol:08 */
ret = (xhci->numports_2 << 8) | (xhci->numports_3 + 1);
break;
- case 0x2c: /* Supported Protocol:0c */
+ case XHCI_HCCAP_EXTCAP_START + 0x0c: /* Supported Protocol:0c */
ret = 0x00000000; /* reserved */
break;
- case 0x30: /* Supported Protocol:00 */
+ case XHCI_HCCAP_EXTCAP_START + 0x10: /* Supported Protocol:00 */
ret = 0x03000002; /* USB 3.0 */
break;
- case 0x34: /* Supported Protocol:04 */
+ case XHCI_HCCAP_EXTCAP_START + 0x14: /* Supported Protocol:04 */
ret = 0x20425355; /* "USB " */
break;
- case 0x38: /* Supported Protocol:08 */
+ case XHCI_HCCAP_EXTCAP_START + 0x18: /* Supported Protocol:08 */
ret = (xhci->numports_3 << 8) | 1;
break;
- case 0x3c: /* Supported Protocol:0c */
+ case XHCI_HCCAP_EXTCAP_START + 0x1c: /* Supported Protocol:0c */
ret = 0x00000000; /* reserved */
break;
default:
@@ -2807,14 +2648,18 @@ static uint64_t xhci_port_read(void *ptr, hwaddr reg,
unsigned size)
uint32_t ret;
switch (reg) {
- case 0x00: /* PORTSC */
+ case XHCI_PORT_REG_PORTSC:
ret = port->portsc;
break;
- case 0x04: /* PORTPMSC */
- case 0x08: /* PORTLI */
+ case XHCI_PORT_REG_PORTLI:
ret = 0;
break;
- case 0x0c: /* PORTHLPMC */
+ case XHCI_PORT_REG_PORTPMSC:
+ ret = 0;
+ qemu_log_mask(LOG_UNIMP, "%s: read from port register PORTHPMSC",
+ __func__);
+ break;
+ case XHCI_PORT_REG_PORTHLPMC:
ret = 0;
qemu_log_mask(LOG_UNIMP, "%s: read from port register PORTHLPMC",
__func__);
@@ -2839,37 +2684,35 @@ static void xhci_port_write(void *ptr, hwaddr reg,
trace_usb_xhci_port_write(port->portnr, reg, val);
switch (reg) {
- case 0x00: /* PORTSC */
+ case XHCI_PORT_REG_PORTSC:
/* write-1-to-start bits */
- if (val & PORTSC_WPR) {
+ if (val & XHCI_PORTSC_WPR) {
xhci_port_reset(port, true);
break;
}
- if (val & PORTSC_PR) {
+ if (val & XHCI_PORTSC_PR) {
xhci_port_reset(port, false);
break;
}
portsc = port->portsc;
notify = 0;
- /* write-1-to-clear bits*/
- portsc &= ~(val & (PORTSC_CSC|PORTSC_PEC|PORTSC_WRC|PORTSC_OCC|
- PORTSC_PRC|PORTSC_PLC|PORTSC_CEC));
- if (val & PORTSC_LWS) {
+ portsc &= ~(val & XHCI_PORTSC_W1C_MASK);
+ if (val & XHCI_PORTSC_LWS) {
/* overwrite PLS only when LWS=1 */
- uint32_t old_pls = get_field(port->portsc, PORTSC_PLS);
- uint32_t new_pls = get_field(val, PORTSC_PLS);
+ uint32_t old_pls = get_field(port->portsc, XHCI_PORTSC_PLS);
+ uint32_t new_pls = get_field(val, XHCI_PORTSC_PLS);
switch (new_pls) {
case PLS_U0:
if (old_pls != PLS_U0) {
- set_field(&portsc, new_pls, PORTSC_PLS);
+ set_field(&portsc, new_pls, XHCI_PORTSC_PLS);
trace_usb_xhci_port_link(port->portnr, new_pls);
- notify = PORTSC_PLC;
+ notify = XHCI_PORTSC_PLC;
}
break;
case PLS_U3:
if (old_pls < PLS_U3) {
- set_field(&portsc, new_pls, PORTSC_PLS);
+ set_field(&portsc, new_pls, XHCI_PORTSC_PLS);
trace_usb_xhci_port_link(port->portnr, new_pls);
}
break;
@@ -2882,22 +2725,21 @@ static void xhci_port_write(void *ptr, hwaddr reg,
break;
}
}
- /* read/write bits */
- portsc &= ~(PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE);
- portsc |= (val & (PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE));
+ portsc &= ~XHCI_PORTSC_RW_MASK;
+ portsc |= val & XHCI_PORTSC_RW_MASK;
port->portsc = portsc;
if (notify) {
xhci_port_notify(port, notify);
}
break;
- case 0x04: /* PORTPMSC */
- case 0x0c: /* PORTHLPMC */
+ case XHCI_PORT_REG_PORTPMSC:
+ case XHCI_PORT_REG_PORTHLPMC:
qemu_log_mask(LOG_UNIMP,
"%s: write 0x%" PRIx64
" (%u bytes) to port register at offset 0x%" HWADDR_PRIx,
__func__, val, size, reg);
break;
- case 0x08: /* PORTLI */
+ case XHCI_PORT_REG_PORTLI:
qemu_log_mask(LOG_GUEST_ERROR, "%s: Write to read-only PORTLI
register",
__func__);
break;
@@ -2916,31 +2758,31 @@ static uint64_t xhci_oper_read(void *ptr, hwaddr reg,
unsigned size)
uint32_t ret;
switch (reg) {
- case 0x00: /* USBCMD */
+ case XHCI_OPER_REG_USBCMD:
ret = xhci->usbcmd;
break;
- case 0x04: /* USBSTS */
+ case XHCI_OPER_REG_USBSTS:
ret = xhci->usbsts;
break;
- case 0x08: /* PAGESIZE */
+ case XHCI_OPER_REG_PAGESIZE:
ret = 1; /* 4KiB */
break;
- case 0x14: /* DNCTRL */
+ case XHCI_OPER_REG_DNCTRL:
ret = xhci->dnctrl;
break;
- case 0x18: /* CRCR low */
+ case XHCI_OPER_REG_CRCR_LO:
ret = xhci->crcr_low & ~0xe;
break;
- case 0x1c: /* CRCR high */
+ case XHCI_OPER_REG_CRCR_HI:
ret = xhci->crcr_high;
break;
- case 0x30: /* DCBAAP low */
+ case XHCI_OPER_REG_DCBAAP_LO:
ret = xhci->dcbaap_low;
break;
- case 0x34: /* DCBAAP high */
+ case XHCI_OPER_REG_DCBAAP_HI:
ret = xhci->dcbaap_high;
break;
- case 0x38: /* CONFIG */
+ case XHCI_OPER_REG_CONFIG:
ret = xhci->config;
break;
default:
@@ -2960,60 +2802,60 @@ static void xhci_oper_write(void *ptr, hwaddr reg,
trace_usb_xhci_oper_write(reg, val);
switch (reg) {
- case 0x00: /* USBCMD */
- if ((val & USBCMD_RS) && !(xhci->usbcmd & USBCMD_RS)) {
+ case XHCI_OPER_REG_USBCMD:
+ if ((val & XHCI_USBCMD_RS) && !(xhci->usbcmd & XHCI_USBCMD_RS)) {
xhci_run(xhci);
- } else if (!(val & USBCMD_RS) && (xhci->usbcmd & USBCMD_RS)) {
+ } else if (!(val & XHCI_USBCMD_RS) && (xhci->usbcmd & XHCI_USBCMD_RS))
{
xhci_stop(xhci);
}
- if (val & USBCMD_CSS) {
+ if (val & XHCI_USBCMD_CSS) {
/* save state */
- xhci->usbsts &= ~USBSTS_SRE;
+ xhci->usbsts &= ~XHCI_USBSTS_SRE;
}
- if (val & USBCMD_CRS) {
+ if (val & XHCI_USBCMD_CRS) {
/* restore state */
- xhci->usbsts |= USBSTS_SRE;
+ xhci->usbsts |= XHCI_USBSTS_SRE;
}
xhci->usbcmd = val & 0xc0f;
xhci_mfwrap_update(xhci);
- if (val & USBCMD_HCRST) {
+ if (val & XHCI_USBCMD_HCRST) {
xhci_reset(DEVICE(xhci));
}
xhci_intr_update(xhci, 0);
break;
- case 0x04: /* USBSTS */
- /* these bits are write-1-to-clear */
- xhci->usbsts &= ~(val &
(USBSTS_HSE|USBSTS_EINT|USBSTS_PCD|USBSTS_SRE));
+ case XHCI_OPER_REG_USBSTS:
+ xhci->usbsts &= ~(val & XHCI_USBSTS_W1C_MASK);
xhci_intr_update(xhci, 0);
break;
- case 0x14: /* DNCTRL */
+ case XHCI_OPER_REG_DNCTRL:
xhci->dnctrl = val & 0xffff;
break;
- case 0x18: /* CRCR low */
- xhci->crcr_low = (val & 0xffffffcf) | (xhci->crcr_low & CRCR_CRR);
+ case XHCI_OPER_REG_CRCR_LO:
+ xhci->crcr_low = (val & 0xffffffcf) | (xhci->crcr_low & XHCI_CRCR_CRR);
break;
- case 0x1c: /* CRCR high */
+ case XHCI_OPER_REG_CRCR_HI:
xhci->crcr_high = val;
- if (xhci->crcr_low & (CRCR_CA|CRCR_CS) && (xhci->crcr_low & CRCR_CRR))
{
+ if (xhci->crcr_low & (XHCI_CRCR_CA | XHCI_CRCR_CS) &&
+ (xhci->crcr_low & XHCI_CRCR_CRR)) {
XHCIEvent event = {ER_COMMAND_COMPLETE, CC_COMMAND_RING_STOPPED};
- xhci->crcr_low &= ~CRCR_CRR;
+ xhci->crcr_low &= ~XHCI_CRCR_CRR;
xhci_event(xhci, &event, 0);
DPRINTF("xhci: command ring stopped (CRCR=%08x)\n",
xhci->crcr_low);
} else {
dma_addr_t base = xhci_addr64(xhci->crcr_low & ~0x3f, val);
xhci_ring_init(xhci, &xhci->cmd_ring, base);
}
- xhci->crcr_low &= ~(CRCR_CA | CRCR_CS);
+ xhci->crcr_low &= ~(XHCI_CRCR_CA | XHCI_CRCR_CS);
break;
- case 0x30: /* DCBAAP low */
+ case XHCI_OPER_REG_DCBAAP_LO:
xhci->dcbaap_low = val & 0xffffffc0;
break;
- case 0x34: /* DCBAAP high */
+ case XHCI_OPER_REG_DCBAAP_HI:
xhci->dcbaap_high = val;
break;
- case 0x38: /* CONFIG */
+ case XHCI_OPER_REG_CONFIG:
xhci->config = val & 0xff;
break;
default:
@@ -3027,9 +2869,9 @@ static uint64_t xhci_runtime_read(void *ptr, hwaddr reg,
XHCIState *xhci = ptr;
uint32_t ret = 0;
- if (reg < 0x20) {
+ if (reg < XHCI_INTR_REG_IR0) {
switch (reg) {
- case 0x00: /* MFINDEX */
+ case XHCI_INTR_REG_MFINDEX:
ret = xhci_mfindex_get(xhci) & 0x3fff;
break;
default:
@@ -3037,28 +2879,28 @@ static uint64_t xhci_runtime_read(void *ptr, hwaddr reg,
break;
}
} else {
- int v = (reg - 0x20) / 0x20;
+ int v = (reg - XHCI_INTR_REG_IR0) / XHCI_INTR_IR_SZ;
XHCIInterrupter *intr = &xhci->intr[v];
- switch (reg & 0x1f) {
- case 0x00: /* IMAN */
+ switch (reg & (XHCI_INTR_IR_SZ - 1)) {
+ case XHCI_INTR_REG_IMAN:
ret = intr->iman;
break;
- case 0x04: /* IMOD */
+ case XHCI_INTR_REG_IMOD:
ret = intr->imod;
break;
- case 0x08: /* ERSTSZ */
+ case XHCI_INTR_REG_ERSTSZ:
ret = intr->erstsz;
break;
- case 0x10: /* ERSTBA low */
+ case XHCI_INTR_REG_ERSTBA_LO:
ret = intr->erstba_low;
break;
- case 0x14: /* ERSTBA high */
+ case XHCI_INTR_REG_ERSTBA_HI:
ret = intr->erstba_high;
break;
- case 0x18: /* ERDP low */
+ case XHCI_INTR_REG_ERDP_LO:
ret = intr->erdp_low;
break;
- case 0x1c: /* ERDP high */
+ case XHCI_INTR_REG_ERDP_HI:
ret = intr->erdp_high;
break;
}
@@ -3077,29 +2919,29 @@ static void xhci_runtime_write(void *ptr, hwaddr reg,
trace_usb_xhci_runtime_write(reg, val);
- if (reg < 0x20) {
+ if (reg < XHCI_INTR_REG_IR0) {
trace_usb_xhci_unimplemented("runtime write", reg);
return;
}
- v = (reg - 0x20) / 0x20;
+ v = (reg - XHCI_INTR_REG_IR0) / XHCI_INTR_IR_SZ;
intr = &xhci->intr[v];
- switch (reg & 0x1f) {
- case 0x00: /* IMAN */
- if (val & IMAN_IP) {
- intr->iman &= ~IMAN_IP;
+ switch (reg & (XHCI_INTR_IR_SZ - 1)) {
+ case XHCI_INTR_REG_IMAN:
+ if (val & XHCI_IMAN_IP) {
+ intr->iman &= ~XHCI_IMAN_IP;
}
- intr->iman &= ~IMAN_IE;
- intr->iman |= val & IMAN_IE;
+ intr->iman &= ~XHCI_IMAN_IE;
+ intr->iman |= val & XHCI_IMAN_IE;
xhci_intr_update(xhci, v);
break;
- case 0x04: /* IMOD */
+ case XHCI_INTR_REG_IMOD:
intr->imod = val;
break;
- case 0x08: /* ERSTSZ */
+ case XHCI_INTR_REG_ERSTSZ:
intr->erstsz = val & 0xffff;
break;
- case 0x10: /* ERSTBA low */
+ case XHCI_INTR_REG_ERSTBA_LO:
if (xhci->nec_quirks) {
/* NEC driver bug: it doesn't align this to 64 bytes */
intr->erstba_low = val & 0xfffffff0;
@@ -3107,16 +2949,17 @@ static void xhci_runtime_write(void *ptr, hwaddr reg,
intr->erstba_low = val & 0xffffffc0;
}
break;
- case 0x14: /* ERSTBA high */
+ case XHCI_INTR_REG_ERSTBA_HI:
intr->erstba_high = val;
xhci_er_reset(xhci, v);
break;
- case 0x18: /* ERDP low */
- if (val & ERDP_EHB) {
- intr->erdp_low &= ~ERDP_EHB;
+ case XHCI_INTR_REG_ERDP_LO:
+ if (val & XHCI_ERDP_EHB) {
+ intr->erdp_low &= ~XHCI_ERDP_EHB;
}
- intr->erdp_low = (val & ~ERDP_EHB) | (intr->erdp_low & ERDP_EHB);
- if (val & ERDP_EHB) {
+ intr->erdp_low = (val & ~XHCI_ERDP_EHB) |
+ (intr->erdp_low & XHCI_ERDP_EHB);
+ if (val & XHCI_ERDP_EHB) {
dma_addr_t erdp = xhci_addr64(intr->erdp_low, intr->erdp_high);
unsigned int dp_idx = (erdp - intr->er_start) / TRB_SIZE;
if (erdp >= intr->er_start &&
@@ -3126,7 +2969,7 @@ static void xhci_runtime_write(void *ptr, hwaddr reg,
}
}
break;
- case 0x1c: /* ERDP high */
+ case XHCI_INTR_REG_ERDP_HI:
intr->erdp_high = val;
break;
default:
@@ -3155,8 +2998,7 @@ static void xhci_doorbell_write(void *ptr, hwaddr reg,
return;
}
- reg >>= 2;
-
+ reg /= XHCI_DBELL_DB_SZ;
if (reg == 0) {
if (val == 0) {
xhci_process_commands(xhci);
@@ -3249,11 +3091,11 @@ static void xhci_wakeup(USBPort *usbport)
XHCIPort *port = xhci_lookup_port(xhci, usbport);
assert(port);
- if (get_field(port->portsc, PORTSC_PLS) != PLS_U3) {
+ if (get_field(port->portsc, XHCI_PORTSC_PLS) != PLS_U3) {
return;
}
- set_field(&port->portsc, PLS_RESUME, PORTSC_PLS);
- xhci_port_notify(port, PORTSC_PLC);
+ set_field(&port->portsc, PLS_RESUME, XHCI_PORTSC_PLS);
+ xhci_port_notify(port, XHCI_PORTSC_PLC);
}
static void xhci_complete(USBPort *port, USBPacket *packet)
@@ -3340,7 +3182,7 @@ static void usb_xhci_init(XHCIState *xhci)
XHCIPort *port;
unsigned int i, usbports, speedmask;
- xhci->usbsts = USBSTS_HCH;
+ xhci->usbsts = XHCI_USBSTS_HCH;
if (xhci->numports_2 > XHCI_MAXPORTS_2) {
xhci->numports_2 = XHCI_MAXPORTS_2;
@@ -3428,10 +3270,10 @@ static void usb_xhci_realize(DeviceState *dev, Error
**errp)
for (i = 0; i < xhci->numports; i++) {
XHCIPort *port = &xhci->ports[i];
- uint32_t offset = OFF_OPER + 0x400 + 0x10 * i;
+ uint32_t offset = OFF_OPER + 0x400 + XHCI_PORT_PR_SZ * i;
port->xhci = xhci;
memory_region_init_io(&port->mem, OBJECT(dev), &xhci_port_ops, port,
- port->name, 0x10);
+ port->name, XHCI_PORT_PR_SZ);
memory_region_add_subregion(&xhci->mem, offset, &port->mem);
}
}
--
2.45.2
- [PATCH v2 0/8] usb/xhci: TR NOOP, TI HCD device, more qtests, Nicholas Piggin, 2025/01/18
- [PATCH v2 1/8] hw/usb/xhci: Move HCD constants to a header and add register constants,
Nicholas Piggin <=
- [PATCH v2 2/8] hw/usb/xhci: Rename and move HCD register region constants to header, Nicholas Piggin, 2025/01/18
- [PATCH v2 3/8] tests/qtest/xhci: Add controller and device setup and ring tests, Nicholas Piggin, 2025/01/18
- [PATCH v2 4/8] hw/usb/xhci: Support TR NOOP commands, Nicholas Piggin, 2025/01/18
- [PATCH v2 5/8] tests/qtest/xhci: add a test for TR NOOP commands, Nicholas Piggin, 2025/01/18
- [PATCH v2 6/8] tests/qtest/xhci: test the qemu-xhci device, Nicholas Piggin, 2025/01/18
- [PATCH v2 7/8] hw/usb/hcd-xhci-pci: Make PCI device more configurable, Nicholas Piggin, 2025/01/18
- [PATCH v2 8/8] hw/usb/hcd-xhci-pci: Add TI TUSB73X0 XHCI controller model, Nicholas Piggin, 2025/01/18