HelenOS sources
This source file includes following definitions.
- xhci_get_max_spbuf
- xhci_extcap_next
- xhci_extcap_psi
#ifndef XHCI_REGS_H
#define XHCI_REGS_H
#include <macros.h>
#include <ddi.h>
#include "common.h"
#define XHCI_PIO_CHANGE_UDELAY 5
#define XHCI_REG_RD(reg_set, reg_spec) XHCI_REG_RD_INNER(reg_set, reg_spec)
#define XHCI_REG_WR(reg_set, reg_spec, value) XHCI_REG_WR_INNER(reg_set, value, reg_spec)
#define XHCI_REG_SET(reg_set, reg_spec, value) XHCI_REG_SET_INNER(reg_set, value, reg_spec)
#define XHCI_REG_CLR(reg_set, reg_spec, value) XHCI_REG_CLR_INNER(reg_set, value, reg_spec)
#define XHCI_REG_MASK(reg_spec) XHCI_REG_MASK_INNER(reg_spec)
#define XHCI_REG_SHIFT(reg_spec) XHCI_REG_SHIFT_INNER(reg_spec)
#define XHCI_REG_RD_INNER(reg_set, field, size, type, ...) \
XHCI_REG_RD_##type(&((reg_set)->field), size, ##__VA_ARGS__)
#define XHCI_REG_WR_INNER(reg_set, value, field, size, type, ...) \
XHCI_REG_WR_##type(&(reg_set)->field, value, size, ##__VA_ARGS__)
#define XHCI_REG_SET_INNER(reg_set, value, field, size, type, ...) \
XHCI_REG_SET_##type(&(reg_set)->field, value, size, ##__VA_ARGS__)
#define XHCI_REG_CLR_INNER(reg_set, value, field, size, type, ...) \
XHCI_REG_CLR_##type(&(reg_set)->field, value, size, ##__VA_ARGS__)
#define XHCI_REG_MASK_INNER(field, size, type, ...) \
XHCI_REG_MASK_##type(size, ##__VA_ARGS__)
#define XHCI_REG_SHIFT_INNER(field, size, type, ...) \
XHCI_REG_SHIFT_##type(size, ##__VA_ARGS__)
#define XHCI_REG_RD_FIELD(ptr, size) \
xhci2host(size, pio_read_##size((ptr)))
#define XHCI_REG_WR_FIELD(ptr, value, size) \
pio_write_##size((ptr), host2xhci(size, value))
#define XHCI_REG_SET_FIELD(ptr, value, size) \
pio_set_##size((ptr), host2xhci(size, value), XHCI_PIO_CHANGE_UDELAY);
#define XHCI_REG_CLR_FIELD(ptr, value, size) \
pio_clear_##size((ptr), host2xhci(size, value), XHCI_PIO_CHANGE_UDELAY);
#define XHCI_REG_MASK_FIELD(size) (~((uint##size##_t) 0))
#define XHCI_REG_SHIFT_FIELD(size) (0)
#define XHCI_REG_RD_FLAG(ptr, size, offset) \
XHCI_REG_RD_RANGE((ptr), size, (offset), (offset))
#define XHCI_REG_WR_FLAG(ptr, value, size, offset) \
XHCI_REG_WR_RANGE((ptr), (value), size, (offset), (offset))
#define XHCI_REG_SET_FLAG(ptr, value, size, offset) \
XHCI_REG_SET_RANGE((ptr), (value), size, (offset), (offset))
#define XHCI_REG_CLR_FLAG(ptr, value, size, offset) \
XHCI_REG_CLR_RANGE((ptr), (value), size, (offset), (offset))
#define XHCI_REG_MASK_FLAG(size, offset) BIT_V(uint##size##_t, offset)
#define XHCI_REG_SHIFT_FLAG(size, offset) (offset)
#define XHCI_REG_RD_RANGE(ptr, size, hi, lo) \
BIT_RANGE_EXTRACT(uint##size##_t, (hi), (lo), XHCI_REG_RD_FIELD((ptr), size))
#define XHCI_REG_WR_RANGE(ptr, value, size, hi, lo) \
pio_change_##size((ptr), host2xhci(size, BIT_RANGE_INSERT(uint##size##_t, \
(hi), (lo), (value))), \
host2xhci(size, BIT_RANGE(uint##size##_t, (hi), (lo))), \
XHCI_PIO_CHANGE_UDELAY);
#define XHCI_REG_SET_RANGE(ptr, value, size, hi, lo) \
pio_set_##size((ptr), host2xhci(size, BIT_RANGE_INSERT(uint##size##_t, \
(hi), (lo), (value))), \
XHCI_PIO_CHANGE_UDELAY);
#define XHCI_REG_CLR_RANGE(ptr, value, size, hi, lo) \
pio_clear_##size((ptr), host2xhci(size, BIT_RANGE_INSERT(uint##size##_t, \
(hi), (lo), (value))), \
XHCI_PIO_CHANGE_UDELAY);
#define XHCI_REG_MASK_RANGE(size, hi, lo) BIT_RANGE(uint##size##_t, hi, lo)
#define XHCI_REG_SHIFT_RANGE(size, hi, lo) (lo)
typedef const struct xhci_cap_regs {
const ioport8_t caplength;
const PADD8(1);
const ioport16_t hciversion;
const ioport32_t hcsparams1;
const ioport32_t hcsparams2;
const ioport32_t hcsparams3;
const ioport32_t hccparams1;
const ioport32_t dboff;
const ioport32_t rtsoff;
const ioport32_t hccparams2;
} xhci_cap_regs_t;
#define XHCI_CAP_LENGTH caplength, 8, FIELD
#define XHCI_CAP_VERSION hciversion, 16, FIELD
#define XHCI_CAP_MAX_SLOTS hcsparams1, 32, RANGE, 7, 0
#define XHCI_CAP_MAX_INTRS hcsparams1, 32, RANGE, 18, 8
#define XHCI_CAP_MAX_PORTS hcsparams1, 32, RANGE, 31, 24
#define XHCI_CAP_IST hcsparams2, 32, RANGE, 3, 0
#define XHCI_CAP_ERST_MAX hcsparams2, 32, RANGE, 7, 4
#define XHCI_CAP_MAX_SPBUF_HI hcsparams2, 32, RANGE, 25, 21
#define XHCI_CAP_SPR hcsparams2, 32, FLAG, 26
#define XHCI_CAP_MAX_SPBUF_LO hcsparams2, 32, RANGE, 31, 27
#define XHCI_CAP_U1EL hcsparams3, 32, RANGE, 7, 0
#define XHCI_CAP_U2EL hcsparams3, 32, RANGE, 31, 16
#define XHCI_CAP_AC64 hccparams1, 32, FLAG, 0
#define XHCI_CAP_BNC hccparams1, 32, FLAG, 1
#define XHCI_CAP_CSZ hccparams1, 32, FLAG, 2
#define XHCI_CAP_PPC hccparams1, 32, FLAG, 3
#define XHCI_CAP_PIND hccparams1, 32, FLAG, 4
#define XHCI_CAP_C hccparams1, 32, FLAG, 5
#define XHCI_CAP_LTC hccparams1, 32, FLAG, 6
#define XHCI_CAP_NSS hccparams1, 32, FLAG, 7
#define XHCI_CAP_PAE hccparams1, 32, FLAG, 8
#define XHCI_CAP_SPC hccparams1, 32, FLAG, 9
#define XHCI_CAP_SEC hccparams1, 32, FLAG, 10
#define XHCI_CAP_CFC hccparams1, 32, FLAG, 11
#define XHCI_CAP_MAX_PSA_SIZE hccparams1, 32, RANGE, 15, 12
#define XHCI_CAP_XECP hccparams1, 32, RANGE, 31, 16
#define XHCI_CAP_DBOFF dboff, 32, FIELD
#define XHCI_CAP_RTSOFF rtsoff, 32, FIELD
#define XHCI_CAP_U3C hccparams2, 32, FLAG, 0
#define XHCI_CAP_CMC hccparams2, 32, FLAG, 1
#define XHCI_CAP_FSC hccparams2, 32, FLAG, 2
#define XHCI_CAP_CTC hccparams2, 32, FLAG, 3
#define XHCI_CAP_LEC hccparams2, 32, FLAG, 4
#define XHCI_CAP_CIC hccparams2, 32, FLAG, 5
static inline unsigned xhci_get_max_spbuf(xhci_cap_regs_t *cap_regs)
{
return XHCI_REG_RD(cap_regs, XHCI_CAP_MAX_SPBUF_HI) << 5 |
XHCI_REG_RD(cap_regs, XHCI_CAP_MAX_SPBUF_LO);
}
typedef struct xhci_port_regs {
ioport32_t portsc;
ioport32_t portpmsc;
ioport32_t portli;
ioport32_t porthlpmc;
} xhci_port_regs_t;
#define XHCI_PORT_CCS portsc, 32, FLAG, 0
#define XHCI_PORT_PED portsc, 32, FLAG, 1
#define XHCI_PORT_OCA portsc, 32, FLAG, 3
#define XHCI_PORT_PR portsc, 32, FLAG, 4
#define XHCI_PORT_PLS portsc, 32, RANGE, 8, 5
#define XHCI_PORT_PP portsc, 32, FLAG, 9
#define XHCI_PORT_PS portsc, 32, RANGE, 13, 10
#define XHCI_PORT_PIC portsc, 32, RANGE, 15, 14
#define XHCI_PORT_LWS portsc, 32, FLAG, 16
#define XHCI_PORT_CSC portsc, 32, FLAG, 17
#define XHCI_PORT_PEC portsc, 32, FLAG, 18
#define XHCI_PORT_WRC portsc, 32, FLAG, 19
#define XHCI_PORT_OCC portsc, 32, FLAG, 20
#define XHCI_PORT_PRC portsc, 32, FLAG, 21
#define XHCI_PORT_PLC portsc, 32, FLAG, 22
#define XHCI_PORT_CEC portsc, 32, FLAG, 23
#define XHCI_PORT_CAS portsc, 32, FLAG, 24
#define XHCI_PORT_WCE portsc, 32, FLAG, 25
#define XHCI_PORT_WDE portsc, 32, FLAG, 26
#define XHCI_PORT_WOE portsc, 32, FLAG, 27
#define XHCI_PORT_DR portsc, 32, FLAG, 30
#define XHCI_PORT_WPR portsc, 32, FLAG, 31
#define XHCI_PORT_USB3_U1TO portpmsc, 32, RANGE, 7, 0
#define XHCI_PORT_USB3_U2TO portpmsc, 32, RANGE, 15, 8
#define XHCI_PORT_USB3_FLPMA portpmsc, 32, FLAG, 16
#define XHCI_PORT_USB3_LEC portli, 32, RANGE, 15, 0
#define XHCI_PORT_USB3_RLC portli, 32, RANGE, 19, 16
#define XHCI_PORT_USB3_TLC portli, 32, RANGE, 23, 20
#define XHCI_PORT_USB2_L1S portpmsc, 32, RANGE, 2, 0
#define XHCI_PORT_USB2_RWE portpmsc, 32, FLAG, 3
#define XHCI_PORT_USB2_BESL portpmsc, 32, RANGE, 7, 4
#define XHCI_PORT_USB2_L1DS portpmsc, 32, RANGE, 15, 8
#define XHCI_PORT_USB2_HLE portpmsc, 32, FLAG, 16
#define XHCI_PORT_USB2_TM portpmsc, 32, RANGE, 31, 28
#define XHCI_PORT_USB2_HIRDM porthlpmc, 32, RANGE, 1, 0
#define XHCI_PORT_USB2_L1TO porthlpmc, 32, RANGE, 9, 2
#define XHCI_PORT_USB2_BESLD porthlpmc, 32, RANGE, 13, 10
typedef struct xhci_op_regs {
ioport32_t usbcmd;
ioport32_t usbsts;
ioport32_t pagesize;
PADD32(2);
ioport32_t dnctrl;
ioport64_t crcr;
PADD32(4);
ioport64_t dcbaap;
ioport32_t config;
PADD32(241);
xhci_port_regs_t portrs[256];
} xhci_op_regs_t;
#define XHCI_OP_RS usbcmd, 32, FLAG, 0
#define XHCI_OP_HCRST usbcmd, 32, FLAG, 1
#define XHCI_OP_INTE usbcmd, 32, FLAG, 2
#define XHCI_OP_HSEE usbcmd, 32, FLAG, 3
#define XHCI_OP_LHCRST usbcmd, 32, FLAG, 7
#define XHCI_OP_CSS usbcmd, 32, FLAG, 8
#define XHCI_OP_CRS usbcmd, 32, FLAG, 9
#define XHCI_OP_EWE usbcmd, 32, FLAG, 10
#define XHCI_OP_EU3S usbcmd, 32, FLAG, 11
#define XHCI_OP_CME usbcmd, 32, FLAG, 13
#define XHCI_OP_HCH usbsts, 32, FLAG, 0
#define XHCI_OP_HSE usbsts, 32, FLAG, 2
#define XHCI_OP_EINT usbsts, 32, FLAG, 3
#define XHCI_OP_PCD usbsts, 32, FLAG, 4
#define XHCI_OP_SSS usbsts, 32, FLAG, 8
#define XHCI_OP_RSS usbsts, 32, FLAG, 9
#define XHCI_OP_SRE usbsts, 32, FLAG, 10
#define XHCI_OP_CNR usbsts, 32, FLAG, 11
#define XHCI_OP_HCE usbsts, 32, FLAG, 12
#define XHCI_OP_PAGESIZE pagesize, 32, FIELD
#define XHCI_OP_NOTIFICATION dnctrl, 32, RANGE, 15, 0
#define XHCI_OP_RCS crcr, 64, FLAG, 0
#define XHCI_OP_CS crcr, 64, FLAG, 1
#define XHCI_OP_CA crcr, 64, FLAG, 2
#define XHCI_OP_CRR crcr, 64, FLAG, 3
#define XHCI_OP_CRCR crcr, 64, FIELD
#define XHCI_OP_DCBAAP dcbaap, 64, FIELD
#define XHCI_OP_MAX_SLOTS_EN config, 32, RANGE, 7, 0
#define XHCI_OP_U3E config, 32, FLAG, 8
#define XHCI_OP_CIE config, 32, FLAG, 9
#define XHCI_OP_STATUS usbsts, 32, RANGE, 12, 0
#define XHCI_STATUS_ACK_MASK 0x41C
typedef struct xhci_interrupter_regs {
ioport32_t iman;
ioport32_t imod;
ioport32_t erstsz;
PADD32(1);
ioport64_t erstba;
ioport64_t erdp;
} xhci_interrupter_regs_t;
#define XHCI_INTR_IP iman, 32, FLAG, 0
#define XHCI_INTR_IE iman, 32, FLAG, 1
#define XHCI_INTR_IMI imod, 32, RANGE, 15, 0
#define XHCI_INTR_IMC imod, 32, RANGE, 31, 16
#define XHCI_INTR_ERSTSZ erstsz, 32, FIELD
#define XHCI_INTR_ERSTBA erstba, 64, FIELD
#define XHCI_INTR_ERDP_ESI erdp, 64, RANGE, 2, 0
#define XHCI_INTR_ERDP_EHB erdp, 64, FLAG, 3
#define XHCI_INTR_ERDP erdp, 64, FIELD
typedef struct xhci_rt_regs {
ioport32_t mfindex;
PADD32(7);
xhci_interrupter_regs_t ir [];
} xhci_rt_regs_t;
#define XHCI_RT_MFINDEX mfindex, 32, RANGE, 13, 0
#define XHCI_MFINDEX_MAX (1 << 14)
typedef ioport32_t xhci_doorbell_t;
enum xhci_plt {
XHCI_PSI_PLT_SYMM,
XHCI_PSI_PLT_RSVD,
XHCI_PSI_PLT_RX,
XHCI_PSI_PLT_TX
};
typedef struct xhci_psi {
xhci_dword_t psi;
} xhci_psi_t;
#define XHCI_PSI_PSIV psi, 32, RANGE, 3, 0
#define XHCI_PSI_PSIE psi, 32, RANGE, 5, 4
#define XHCI_PSI_PLT psi, 32, RANGE, 7, 6
#define XHCI_PSI_PFD psi, 32, FLAG, 8
#define XHCI_PSI_PSIM psi, 32, RANGE, 31, 16
enum xhci_extcap_type {
XHCI_EC_RESERVED = 0,
XHCI_EC_USB_LEGACY,
XHCI_EC_SUPPORTED_PROTOCOL,
XHCI_EC_EXTENDED_POWER_MANAGEMENT,
XHCI_EC_IOV,
XHCI_EC_MSI,
XHCI_EC_LOCALMEM,
XHCI_EC_DEBUG = 10,
XHCI_EC_MSIX = 17,
XHCI_EC_MAX = 255
};
typedef struct xhci_extcap {
xhci_dword_t header;
xhci_dword_t cap_specific[];
} xhci_extcap_t;
#define XHCI_EC_CAP_ID header, 32, RANGE, 7, 0
#define XHCI_EC_SIZE header, 32, RANGE, 15, 8
#define XHCI_EC_SP_MINOR header, 32, RANGE, 23, 16
#define XHCI_EC_SP_MAJOR header, 32, RANGE, 31, 24
#define XHCI_EC_SP_NAME cap_specific[0], 32, FIELD
#define XHCI_EC_SP_CP_OFF cap_specific[1], 32, RANGE, 7, 0
#define XHCI_EC_SP_CP_COUNT cap_specific[1], 32, RANGE, 15, 8
#define XHCI_EC_SP_PSIC cap_specific[1], 32, RANGE, 31, 28
#define XHCI_EC_SP_SLOT_TYPE cap_specific[2], 32, RANGE, 4, 0
typedef union {
char str [4];
uint32_t packed;
} xhci_sp_name_t;
static const xhci_sp_name_t xhci_name_usb = {
.str = "USB "
};
static inline xhci_extcap_t *xhci_extcap_next(const xhci_extcap_t *cur)
{
unsigned dword_offset = XHCI_REG_RD(cur, XHCI_EC_SIZE);
if (!dword_offset)
return NULL;
return (xhci_extcap_t *) (((xhci_dword_t *) cur) + dword_offset);
}
static inline xhci_psi_t *xhci_extcap_psi(const xhci_extcap_t *ec, unsigned psid)
{
assert(XHCI_REG_RD(ec, XHCI_EC_CAP_ID) == XHCI_EC_SUPPORTED_PROTOCOL);
assert(XHCI_REG_RD(ec, XHCI_EC_SP_PSIC) > psid);
unsigned dword_offset = 4 + psid;
return (xhci_psi_t *) (((xhci_dword_t *) ec) + dword_offset);
}
typedef struct xhci_extcap_legsup {
ioport8_t cap_id;
ioport8_t size;
ioport8_t sem_bios;
ioport8_t sem_os;
xhci_dword_t usblegctlsts;
} xhci_legsup_t;
#define XHCI_LEGSUP_SEM_BIOS sem_bios, 8, FLAG, 0
#define XHCI_LEGSUP_SEM_OS sem_os, 8, FLAG, 0
#define XHCI_LEGSUP_BIOS_TIMEOUT_US 1000000
#define XHCI_LEGSUP_POLLING_DELAY_1MS 1000
#endif
HelenOS homepage, sources at GitHub