106
106
*/
107
107
#define XHCI_PADDR_SZ 4096 /* paddr_guest2host max size */
108
108
#define XHCI_ERST_MAX 0 /* max 2^entries event ring seg tbl */
109
- #define XHCI_CAPLEN (4 *8) /* offset of op register space */
109
+ #define XHCI_CAPLEN (8 *8) /* offset of op register space */
110
110
#define XHCI_HCCPRAMS2 0x1C /* offset of HCCPARAMS2 register */
111
111
#define XHCI_PORTREGS_START 0x400
112
112
#define XHCI_DOORBELL_MAX 256
@@ -377,6 +377,7 @@ struct pci_xhci_vdev {
377
377
uint32_t hccparams1 ; /* capability parameters 1 */
378
378
uint32_t dboff ; /* doorbell offset */
379
379
uint32_t rtsoff ; /* runtime register space offset */
380
+ uint32_t rtsend ;
380
381
uint32_t hccparams2 ; /* capability parameters 2 */
381
382
382
383
uint32_t excapoff ; /* ext-capability registers offset */
@@ -3332,7 +3333,7 @@ pci_xhci_write(struct vmctx *ctx,
3332
3333
pci_xhci_hostop_write (xdev , offset , value );
3333
3334
else if (offset < xdev -> rtsoff )
3334
3335
pci_xhci_dbregs_write (xdev , offset , value );
3335
- else if (offset < xdev -> excapoff )
3336
+ else if (offset < xdev -> rtsend )
3336
3337
pci_xhci_rtsregs_write (xdev , offset , value );
3337
3338
else if (offset < xdev -> regsend )
3338
3339
pci_xhci_excap_write (xdev , offset , value );
@@ -3376,8 +3377,36 @@ pci_xhci_hostcap_read(struct pci_xhci_vdev *xdev, uint64_t offset)
3376
3377
value = xdev -> rtsoff ;
3377
3378
break ;
3378
3379
3379
- case XHCI_HCCPRAMS2 : /* 0x1C */
3380
- value = xdev -> hccparams2 ;
3380
+ case ACRN_XHCI_EXCAP1 :
3381
+ value = 0x02000402 ; /* USB 2.0 */
3382
+ break ;
3383
+
3384
+ case ACRN_XHCI_EXCAP1 + 4 :
3385
+ value = 0x20425355 ; /* "USB " */
3386
+ break ;
3387
+
3388
+ case ACRN_XHCI_EXCAP1 + 8 :
3389
+ value = (((XHCI_MAX_DEVS /2 ) << 8 ) | (XHCI_MAX_DEVS /2 + 1 ));
3390
+ break ;
3391
+
3392
+ case ACRN_XHCI_EXCAP1 + 12 :
3393
+ value = 0 ;
3394
+ break ;
3395
+
3396
+ case ACRN_XHCI_EXCAP2 :
3397
+ value = 0x03000002 ; /* USB 3.0 */
3398
+ break ;
3399
+
3400
+ case ACRN_XHCI_EXCAP2 + 4 :
3401
+ value = 0x20425355 ; /* "USB " */
3402
+ break ;
3403
+
3404
+ case ACRN_XHCI_EXCAP2 + 8 :
3405
+ value = (((XHCI_MAX_DEVS /2 ) << 8 ) | 1 );
3406
+ break ;
3407
+
3408
+ case ACRN_XHCI_EXCAP2 + 12 :
3409
+ value = 0 ;
3381
3410
break ;
3382
3411
3383
3412
default :
@@ -3477,11 +3506,11 @@ pci_xhci_rtsregs_read(struct pci_xhci_vdev *xdev, uint64_t offset)
3477
3506
3478
3507
if (value >= 1 )
3479
3508
xdev -> rtsregs .mfindex += value ;
3480
- } else if (offset >= 0x20 ) {
3509
+ } else if (offset >= XHCI_RT_IR_BASE ) {
3481
3510
int item ;
3482
3511
uint32_t * p ;
3483
3512
3484
- offset -= 0x20 ;
3513
+ offset -= XHCI_RT_IR_BASE ;
3485
3514
item = offset % 32 ;
3486
3515
3487
3516
assert (offset < sizeof (xdev -> rtsregs .intrreg ));
@@ -3551,7 +3580,7 @@ pci_xhci_read(struct vmctx *ctx,
3551
3580
value = pci_xhci_hostop_read (xdev , offset );
3552
3581
else if (offset < xdev -> rtsoff )
3553
3582
value = pci_xhci_dbregs_read (xdev , offset );
3554
- else if (offset < xdev -> excapoff )
3583
+ else if (offset < xdev -> rtsend )
3555
3584
value = pci_xhci_rtsregs_read (xdev , offset );
3556
3585
else if (offset < xdev -> regsend )
3557
3586
value = pci_xhci_excap_read (xdev , offset );
@@ -3897,19 +3926,18 @@ pci_xhci_parse_extcap(struct pci_xhci_vdev *xdev, char *opts)
3897
3926
if (!strncmp (cap , "apl" , 3 )) {
3898
3927
xdev -> excap_write = pci_xhci_apl_drdregs_write ;
3899
3928
xdev -> excap_ptr = excap_group_apl ;
3900
- xdev -> vid = XHCI_PCI_VENDOR_ID_INTEL ;
3901
- xdev -> pid = XHCI_PCI_DEVICE_ID_INTEL_APL ;
3929
+ xdev -> vid = PCI_INTEL_APL_XHCI_VID ;
3930
+ xdev -> pid = PCI_INTEL_APL_XHCI_PID ;
3902
3931
} else
3903
3932
rc = -2 ;
3904
3933
3905
3934
if (((struct pci_xhci_excap * )(xdev -> excap_ptr ))-> start
3906
3935
== EXCAP_GROUP_END ) {
3907
3936
xdev -> excap_write = NULL ;
3908
- xdev -> excap_ptr = excap_group_dft ;
3909
- xdev -> vid = XHCI_PCI_VENDOR_ID_DFLT ;
3910
- xdev -> pid = XHCI_PCI_DEVICE_ID_DFLT ;
3911
- UPRINTF (LWRN , "Invalid xhci excap, force set "
3912
- "default excap\r\n" );
3937
+ xdev -> excap_ptr = NULL ;
3938
+ xdev -> vid = PCI_ACRN_XHCI_VID ;
3939
+ xdev -> pid = PCI_ACRN_XHCI_PID ;
3940
+ UPRINTF (LWRN , "Invalid excap, set to ACRN excap\r\n" );
3913
3941
}
3914
3942
3915
3943
errout :
@@ -4034,10 +4062,10 @@ pci_xhci_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
4034
4062
xdev -> usb2_port_start = (XHCI_MAX_DEVS /2 ) + 1 ;
4035
4063
xdev -> usb3_port_start = 1 ;
4036
4064
4037
- xdev -> excap_ptr = excap_group_dft ;
4038
-
4039
- xdev -> vid = XHCI_PCI_VENDOR_ID_DFLT ;
4040
- xdev -> pid = XHCI_PCI_DEVICE_ID_DFLT ;
4065
+ xdev -> vid = PCI_ACRN_XHCI_VID ;
4066
+ xdev -> pid = PCI_ACRN_XHCI_PID ;
4067
+ xdev -> excapoff = ACRN_XHCI_EXCAP1 ;
4068
+ xdev -> excap_ptr = NULL ;
4041
4069
4042
4070
xdev -> rtsregs .mfindex = 0 ;
4043
4071
clock_gettime (CLOCK_MONOTONIC , & xdev -> mf_prev_time );
@@ -4083,6 +4111,7 @@ pci_xhci_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
4083
4111
(XHCI_MAX_SLOTS + 1 ) * 32 );
4084
4112
if (xdev -> rtsoff & 0x1F )
4085
4113
xdev -> rtsoff = (xdev -> rtsoff + 0x1F ) & ~0x1F ;
4114
+ xdev -> rtsend = xdev -> rtsoff + XHCI_RT_IR_BASE + sizeof (xdev -> rtsregs );
4086
4115
4087
4116
UPRINTF (LDBG , "dboff: 0x%x, rtsoff: 0x%x\r\n" , xdev -> dboff ,
4088
4117
xdev -> rtsoff );
@@ -4092,28 +4121,24 @@ pci_xhci_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
4092
4121
4093
4122
pci_xhci_reset (xdev );
4094
4123
4095
- /* xdev->excap_ptr should be assigned to global array in which
4096
- * it need include two items at least and field start must be
4097
- * ended by EXCAP_GROUP_END at last item.
4098
- */
4099
4124
excap = xdev -> excap_ptr ;
4100
- if (!excap ) {
4101
- error = -1 ;
4102
- goto done ;
4125
+ if (excap == NULL ) {
4126
+ xdev -> regsend = xdev -> rtsend ;
4127
+ xdev -> excapoff = ACRN_XHCI_EXCAP1 ;
4128
+ } else {
4129
+ xdev -> excapoff = excap -> start ;
4130
+ while (excap && excap -> start != EXCAP_GROUP_END ) {
4131
+ xdev -> regsend = excap -> end ;
4132
+ excap ++ ;
4133
+ }
4103
4134
}
4104
4135
4105
- xdev -> excapoff = excap -> start ;
4106
-
4107
- do {
4108
- xdev -> regsend = excap -> end ;
4109
- excap ++ ;
4110
- } while (excap && excap -> start != EXCAP_GROUP_END );
4111
-
4112
4136
/*
4113
4137
* Set extended capabilities pointer to be after regsend;
4114
4138
* value of excap field is 32-bit offset.
4115
4139
*/
4116
- xdev -> hccparams1 |= XHCI_SET_HCCP1_XECP (XHCI_EXCAP_PTR );
4140
+ xdev -> hccparams1 |=
4141
+ XHCI_SET_HCCP1_XECP (XHCI_XECP_OFF_SHIFT (xdev -> excapoff ));
4117
4142
4118
4143
pci_set_cfgdata16 (dev , PCIR_DEVICE , xdev -> pid );
4119
4144
pci_set_cfgdata16 (dev , PCIR_VENDOR , xdev -> vid );
0 commit comments