xref: /aosp_15_r20/external/crosvm/devices/src/usb/xhci/xhci_abi.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2018 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::fmt;
6 use std::fmt::Display;
7 
8 use bit_field::Error as BitFieldError;
9 use bit_field::*;
10 use remain::sorted;
11 use thiserror::Error;
12 use vm_memory::GuestAddress;
13 use zerocopy::AsBytes;
14 use zerocopy::FromBytes;
15 use zerocopy::FromZeroes;
16 
17 #[sorted]
18 #[derive(Error, Debug)]
19 pub enum Error {
20     #[error("cannot cast trb from raw memory")]
21     CannotCastTrb,
22     #[error("we got an unknown trb type value: {0}")]
23     UnknownTrbType(BitFieldError),
24 }
25 
26 type Result<T> = std::result::Result<T, Error>;
27 
28 // Fixed size of all TRB types.
29 const TRB_SIZE: usize = 16;
30 
31 // Size of segment table.
32 const SEGMENT_TABLE_SIZE: usize = 16;
33 
34 /// All kinds of trb.
35 #[bitfield]
36 #[bits = 6]
37 #[derive(PartialEq, Eq, Debug, Clone, Copy)]
38 pub enum TrbType {
39     Reserved = 0,
40     Normal = 1,
41     SetupStage = 2,
42     DataStage = 3,
43     StatusStage = 4,
44     Isoch = 5,
45     Link = 6,
46     EventData = 7,
47     Noop = 8,
48     EnableSlotCommand = 9,
49     DisableSlotCommand = 10,
50     AddressDeviceCommand = 11,
51     ConfigureEndpointCommand = 12,
52     EvaluateContextCommand = 13,
53     ResetEndpointCommand = 14,
54     StopEndpointCommand = 15,
55     SetTRDequeuePointerCommand = 16,
56     ResetDeviceCommand = 17,
57     NoopCommand = 23,
58     TransferEvent = 32,
59     CommandCompletionEvent = 33,
60     PortStatusChangeEvent = 34,
61 }
62 
63 /// Completion code of trb types.
64 #[bitfield]
65 #[bits = 8]
66 #[derive(PartialEq, Eq, Debug)]
67 pub enum TrbCompletionCode {
68     Success = 1,
69     TransactionError = 4,
70     TrbError = 5,
71     StallError = 6,
72     NoSlotsAvailableError = 9,
73     SlotNotEnabledError = 11,
74     ShortPacket = 13,
75     ContextStateError = 19,
76 }
77 
78 /// State of device slot.
79 #[bitfield]
80 #[bits = 5]
81 #[derive(PartialEq, Eq, Debug)]
82 pub enum DeviceSlotState {
83     // The same value (0) is used for both the enabled and disabled states. See
84     // xhci spec table 60.
85     DisabledOrEnabled = 0,
86     Default = 1,
87     Addressed = 2,
88     Configured = 3,
89 }
90 
91 /// State of endpoint.
92 #[bitfield]
93 #[bits = 3]
94 #[derive(PartialEq, Eq, Debug)]
95 pub enum EndpointState {
96     Disabled = 0,
97     Running = 1,
98     Halted = 2,
99     Stopped = 3,
100     Error = 4,
101 }
102 
103 #[bitfield]
104 #[bits = 60]
105 #[derive(PartialEq, Eq, Debug)]
106 pub struct DequeuePtr(u64);
107 
108 impl DequeuePtr {
new(addr: GuestAddress) -> Self109     pub fn new(addr: GuestAddress) -> Self {
110         DequeuePtr(addr.0 >> 4)
111     }
112 
113     // Get the guest physical address.
get_gpa(&self) -> GuestAddress114     pub fn get_gpa(&self) -> GuestAddress {
115         GuestAddress(self.0 << 4)
116     }
117 }
118 
119 // Generic TRB struct containing only fields common to all types.
120 #[bitfield]
121 #[derive(Clone, Copy, PartialEq, Eq, FromZeroes, FromBytes, AsBytes)]
122 pub struct Trb {
123     parameter: B64,
124     status: B32,
125     cycle: bool,
126     flags: B9,
127     trb_type: TrbType,
128     control: B16,
129 }
130 
131 impl Trb {
fmt_helper(&self, f: &mut fmt::Formatter) -> Result<fmt::Result>132     fn fmt_helper(&self, f: &mut fmt::Formatter) -> Result<fmt::Result> {
133         match self.get_trb_type().map_err(Error::UnknownTrbType)? {
134             TrbType::Reserved => Ok(write!(f, "reserved trb type")),
135             TrbType::Normal => {
136                 let t = self.cast::<NormalTrb>()?;
137                 Ok(write!(f, "trb: {:?}", t))
138             }
139             TrbType::SetupStage => {
140                 let t = self.cast::<SetupStageTrb>()?;
141                 Ok(write!(f, "trb: {:?}", t))
142             }
143             TrbType::DataStage => {
144                 let t = self.cast::<DataStageTrb>()?;
145                 Ok(write!(f, "trb: {:?}", t))
146             }
147             TrbType::StatusStage => {
148                 let t = self.cast::<StatusStageTrb>()?;
149                 Ok(write!(f, "trb: {:?}", t))
150             }
151             TrbType::Isoch => {
152                 let t = self.cast::<IsochTrb>()?;
153                 Ok(write!(f, "trb: {:?}", t))
154             }
155             TrbType::Link => {
156                 let t = self.cast::<LinkTrb>()?;
157                 Ok(write!(f, "trb: {:?}", t))
158             }
159             TrbType::EventData => {
160                 let t = self.cast::<EventDataTrb>()?;
161                 Ok(write!(f, "trb: {:?}", t))
162             }
163             TrbType::Noop => {
164                 let t = self.cast::<NoopTrb>()?;
165                 Ok(write!(f, "trb: {:?}", t))
166             }
167             TrbType::EnableSlotCommand => Ok(write!(f, "trb: enable slot command {:?}", self)),
168             TrbType::DisableSlotCommand => {
169                 let t = self.cast::<DisableSlotCommandTrb>()?;
170                 Ok(write!(f, "trb: {:?}", t))
171             }
172             TrbType::AddressDeviceCommand => {
173                 let t = self.cast::<AddressDeviceCommandTrb>()?;
174                 Ok(write!(f, "trb: {:?}", t))
175             }
176             TrbType::ConfigureEndpointCommand => {
177                 let t = self.cast::<ConfigureEndpointCommandTrb>()?;
178                 Ok(write!(f, "trb: {:?}", t))
179             }
180             TrbType::EvaluateContextCommand => {
181                 let t = self.cast::<EvaluateContextCommandTrb>()?;
182                 Ok(write!(f, "trb: {:?}", t))
183             }
184             TrbType::ResetEndpointCommand => {
185                 let t = self.cast::<ResetEndpointCommandTrb>()?;
186                 Ok(write!(f, "trb: {:?}", t))
187             }
188             TrbType::StopEndpointCommand => {
189                 let t = self.cast::<StopEndpointCommandTrb>()?;
190                 Ok(write!(f, "trb: {:?}", t))
191             }
192             TrbType::SetTRDequeuePointerCommand => {
193                 let t = self.cast::<SetTRDequeuePointerCommandTrb>()?;
194                 Ok(write!(f, "trb: {:?}", t))
195             }
196             TrbType::ResetDeviceCommand => {
197                 let t = self.cast::<ResetDeviceCommandTrb>()?;
198                 Ok(write!(f, "trb: {:?}", t))
199             }
200             TrbType::NoopCommand => Ok(write!(f, "trb: noop command {:?}", self)),
201             TrbType::TransferEvent => {
202                 let t = self.cast::<TransferEventTrb>()?;
203                 Ok(write!(f, "trb: {:?}", t))
204             }
205             TrbType::CommandCompletionEvent => {
206                 let t = self.cast::<CommandCompletionEventTrb>()?;
207                 Ok(write!(f, "trb: {:?}", t))
208             }
209             TrbType::PortStatusChangeEvent => {
210                 let t = self.cast::<PortStatusChangeEventTrb>()?;
211                 Ok(write!(f, "trb: {:?}", t))
212             }
213         }
214     }
215 }
216 
217 impl Display for Trb {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result218     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
219         match self.fmt_helper(f) {
220             Ok(f) => f,
221             Err(e) => write!(f, "fail to format trb {}", e),
222         }
223     }
224 }
225 
226 impl Trb {
227     /// Get chain bit.
get_chain_bit(&self) -> Result<bool>228     pub fn get_chain_bit(&self) -> Result<bool> {
229         Ok(match self.get_trb_type() {
230             Ok(TrbType::Normal) => self.cast::<NormalTrb>()?.get_chain(),
231             Ok(TrbType::DataStage) => self.cast::<DataStageTrb>()?.get_chain(),
232             Ok(TrbType::StatusStage) => self.cast::<StatusStageTrb>()?.get_chain(),
233             Ok(TrbType::Isoch) => self.cast::<IsochTrb>()?.get_chain(),
234             Ok(TrbType::Noop) => self.cast::<NoopTrb>()?.get_chain(),
235             Ok(TrbType::Link) => self.cast::<LinkTrb>()?.get_chain(),
236             Ok(TrbType::EventData) => self.cast::<EventDataTrb>()?.get_chain(),
237             _ => false,
238         })
239     }
240 
241     /// Get interrupt target.
interrupter_target(&self) -> u8242     pub fn interrupter_target(&self) -> u8 {
243         const STATUS_INTERRUPTER_TARGET_OFFSET: u8 = 22;
244         (self.get_status() >> STATUS_INTERRUPTER_TARGET_OFFSET) as u8
245     }
246 
247     /// Only some of trb types could appear in transfer ring.
can_be_in_transfer_ring(&self) -> Result<bool>248     pub fn can_be_in_transfer_ring(&self) -> Result<bool> {
249         match self.get_trb_type().map_err(Error::UnknownTrbType)? {
250             TrbType::Normal
251             | TrbType::SetupStage
252             | TrbType::DataStage
253             | TrbType::StatusStage
254             | TrbType::Isoch
255             | TrbType::Link
256             | TrbType::EventData
257             | TrbType::Noop => Ok(true),
258             _ => Ok(false),
259         }
260     }
261 
262     /// Length of this transfer.
transfer_length(&self) -> Result<u32>263     pub fn transfer_length(&self) -> Result<u32> {
264         const STATUS_TRANSFER_LENGTH_MASK: u32 = 0x1ffff;
265         match self.get_trb_type().map_err(Error::UnknownTrbType)? {
266             TrbType::Normal | TrbType::SetupStage | TrbType::DataStage | TrbType::Isoch => {
267                 Ok(self.get_status() & STATUS_TRANSFER_LENGTH_MASK)
268             }
269             _ => Ok(0),
270         }
271     }
272 
273     /// Returns true if interrupt is required on completion.
interrupt_on_completion(&self) -> bool274     pub fn interrupt_on_completion(&self) -> bool {
275         const FLAGS_INTERRUPT_ON_COMPLETION_MASK: u16 = 0x10;
276         (self.get_flags() & FLAGS_INTERRUPT_ON_COMPLETION_MASK) > 0
277     }
278 
279     /// Returns true if interrupt is required on transfer of short packet.
interrupt_on_short_packet(&self) -> bool280     pub fn interrupt_on_short_packet(&self) -> bool {
281         const FLAGS_INTERRUPT_ON_SHORT_PACKET: u16 = 0x2;
282         (self.get_flags() & FLAGS_INTERRUPT_ON_SHORT_PACKET) > 0
283     }
284 
285     /// Returns true if this trb is immediate data.
immediate_data(&self) -> Result<bool>286     pub fn immediate_data(&self) -> Result<bool> {
287         const FLAGS_IMMEDIATE_DATA_MASK: u16 = 0x20;
288         match self.get_trb_type().map_err(Error::UnknownTrbType)? {
289             TrbType::Normal | TrbType::SetupStage | TrbType::DataStage | TrbType::Isoch => {
290                 Ok((self.get_flags() & FLAGS_IMMEDIATE_DATA_MASK) != 0)
291             }
292             _ => Ok(false),
293         }
294     }
295 }
296 
297 #[bitfield]
298 #[derive(Clone, Copy, AsBytes, FromZeroes, FromBytes)]
299 pub struct NormalTrb {
300     data_buffer: B64,
301     trb_transfer_length: B17,
302     td_size: B5,
303     interrupter_target: B10,
304     cycle: bool,
305     evaluate_next_trb: B1,
306     interrupt_on_short_packet: B1,
307     no_snoop: B1,
308     chain: bool,
309     interrupt_on_completion: B1,
310     immediate_data: B1,
311     reserved: B2,
312     block_event_interrupt: B1,
313     trb_type: TrbType,
314     reserved1: B16,
315 }
316 
317 #[bitfield]
318 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
319 pub struct SetupStageTrb {
320     request_type: B8,
321     request: B8,
322     value: B16,
323     index: B16,
324     length: B16,
325     trb_transfer_length: B17,
326     reserved0: B5,
327     interrupter_target: B10,
328     cycle: bool,
329     reserved1: B4,
330     interrupt_on_completion: B1,
331     immediate_data: B1,
332     reserved2: B3,
333     trb_type: TrbType,
334     transfer_type: B2,
335     reserved3: B14,
336 }
337 
338 #[bitfield]
339 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
340 pub struct DataStageTrb {
341     data_buffer_pointer: B64,
342     trb_transfer_length: B17,
343     td_size: B5,
344     interrupter_target: B10,
345     cycle: bool,
346     evaluate_next_trb: B1,
347     interrupt_on_short_packet: B1,
348     no_snoop: B1,
349     chain: bool,
350     interrupt_on_completion: B1,
351     immediate_data: B1,
352     reserved0: B3,
353     trb_type: TrbType,
354     direction: B1,
355     reserved1: B15,
356 }
357 
358 #[bitfield]
359 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
360 pub struct StatusStageTrb {
361     reserved0: B64,
362     reserved1: B22,
363     interrupter_target: B10,
364     cycle: bool,
365     evaluate_next_trb: B1,
366     reserved2: B2,
367     chain: bool,
368     interrupt_on_completion: B1,
369     reserved3: B4,
370     trb_type: TrbType,
371     direction: B1,
372     reserved4: B15,
373 }
374 
375 #[bitfield]
376 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
377 pub struct IsochTrb {
378     data_buffer_pointer: B64,
379     trb_transfer_length: B17,
380     td_size: B5,
381     interrupter_target: B10,
382     cycle: bool,
383     evaulate_nex_trb: B1,
384     interrupt_on_short_packet: B1,
385     no_snoop: B1,
386     chain: bool,
387     interrupt_on_completion: B1,
388     immediate_data: B1,
389     transfer_burst_count: B2,
390     block_event_interrupt: B1,
391     trb_type: TrbType,
392     tlbpc: B4,
393     frame_id: B11,
394     sia: B1,
395 }
396 
397 #[bitfield]
398 #[derive(Clone, Copy, AsBytes, FromZeroes, FromBytes)]
399 pub struct LinkTrb {
400     ring_segment_pointer: B64,
401     reserved0: B22,
402     interrupter_target: B10,
403     cycle: bool,
404     toggle_cycle: bool,
405     reserved1: B2,
406     chain: bool,
407     interrupt_on_completion: bool,
408     reserved2: B4,
409     trb_type: TrbType,
410     reserved3: B16,
411 }
412 
413 #[bitfield]
414 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
415 pub struct EventDataTrb {
416     event_data: B64,
417     reserved0: B22,
418     interrupter_target: B10,
419     cycle: bool,
420     evaluate_next_trb: B1,
421     reserved1: B2,
422     chain: bool,
423     interrupt_on_completion: B1,
424     reserved2: B3,
425     block_event_interrupt: B1,
426     trb_type: TrbType,
427     reserved3: B16,
428 }
429 
430 #[bitfield]
431 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
432 pub struct NoopTrb {
433     reserved0: B64,
434     reserved1: B22,
435     interrupter_target: B10,
436     cycle: bool,
437     evaluate_next_trb: B1,
438     reserved2: B2,
439     chain: bool,
440     interrupt_on_completion: B1,
441     reserved3: B4,
442     trb_type: TrbType,
443     reserved4: B16,
444 }
445 
446 #[bitfield]
447 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
448 pub struct DisableSlotCommandTrb {
449     reserved0: B32,
450     reserved1: B32,
451     reserved2: B32,
452     cycle: bool,
453     reserved3: B9,
454     trb_type: TrbType,
455     reserved4: B8,
456     slot_id: B8,
457 }
458 
459 #[bitfield]
460 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
461 pub struct AddressDeviceCommandTrb {
462     input_context_pointer: B64,
463     reserved: B32,
464     cycle: bool,
465     reserved2: B8,
466     block_set_address_request: bool,
467     trb_type: TrbType,
468     reserved3: B8,
469     slot_id: B8,
470 }
471 
472 #[bitfield]
473 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
474 pub struct ConfigureEndpointCommandTrb {
475     input_context_pointer: B64,
476     reserved0: B32,
477     cycle: bool,
478     reserved1: B8,
479     deconfigure: bool,
480     trb_type: TrbType,
481     reserved2: B8,
482     slot_id: B8,
483 }
484 
485 #[bitfield]
486 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
487 pub struct EvaluateContextCommandTrb {
488     input_context_pointer: B64,
489     reserved0: B32,
490     cycle: bool,
491     reserved1: B9,
492     trb_type: TrbType,
493     reserved2: B8,
494     slot_id: B8,
495 }
496 
497 #[bitfield]
498 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
499 pub struct ResetEndpointCommandTrb {
500     reserved0: B32,
501     reserved1: B32,
502     reserved2: B32,
503     cycle: bool,
504     reserved3: B8,
505     transfer_state_preserve: B1,
506     trb_type: TrbType,
507     endpoint_id: B5,
508     reserved4: B3,
509     slot_id: B8,
510 }
511 
512 #[bitfield]
513 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
514 pub struct StopEndpointCommandTrb {
515     reserved0: B32,
516     reserved1: B32,
517     reserved2: B32,
518     cycle: bool,
519     reserved3: B9,
520     trb_type: TrbType,
521     endpoint_id: B5,
522     reserved4: B2,
523     suspend: B1,
524     slot_id: B8,
525 }
526 
527 #[bitfield]
528 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
529 pub struct SetTRDequeuePointerCommandTrb {
530     dequeue_cycle_state: bool,
531     stream_context_type: B3,
532     dequeue_ptr: DequeuePtr,
533     reserved0: B16,
534     stream_id: B16,
535     cycle: bool,
536     reserved1: B9,
537     trb_type: TrbType,
538     endpoint_id: B5,
539     reserved3: B2,
540     suspend: B1,
541     slot_id: B8,
542 }
543 
544 #[bitfield]
545 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
546 pub struct ResetDeviceCommandTrb {
547     reserved0: B32,
548     reserved1: B32,
549     reserved2: B32,
550     cycle: bool,
551     reserved3: B9,
552     trb_type: TrbType,
553     reserved4: B8,
554     slot_id: B8,
555 }
556 
557 #[bitfield]
558 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
559 pub struct TransferEventTrb {
560     trb_pointer: B64,
561     trb_transfer_length: B24,
562     completion_code: TrbCompletionCode,
563     cycle: bool,
564     reserved0: B1,
565     event_data: B1,
566     reserved1: B7,
567     trb_type: TrbType,
568     endpoint_id: B5,
569     reserved2: B3,
570     slot_id: B8,
571 }
572 
573 #[bitfield]
574 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
575 pub struct CommandCompletionEventTrb {
576     trb_pointer: B64,
577     command_completion_parameter: B24,
578     completion_code: TrbCompletionCode,
579     cycle: bool,
580     reserved: B9,
581     trb_type: TrbType,
582     vf_id: B8,
583     slot_id: B8,
584 }
585 
586 #[bitfield]
587 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
588 pub struct PortStatusChangeEventTrb {
589     reserved0: B24,
590     port_id: B8,
591     reserved1: B32,
592     reserved2: B24,
593     completion_code: TrbCompletionCode,
594     cycle: bool,
595     reserved3: B9,
596     trb_type: TrbType,
597     reserved4: B16,
598 }
599 
600 /// Associate real type of trb.
601 pub trait TypedTrb {
602     const TY: TrbType;
603 }
604 
605 impl TypedTrb for Trb {
606     const TY: TrbType = TrbType::Reserved;
607 }
608 
609 impl TypedTrb for NormalTrb {
610     const TY: TrbType = TrbType::Normal;
611 }
612 
613 impl TypedTrb for SetupStageTrb {
614     const TY: TrbType = TrbType::SetupStage;
615 }
616 
617 impl TypedTrb for DataStageTrb {
618     const TY: TrbType = TrbType::DataStage;
619 }
620 
621 impl TypedTrb for StatusStageTrb {
622     const TY: TrbType = TrbType::StatusStage;
623 }
624 
625 impl TypedTrb for IsochTrb {
626     const TY: TrbType = TrbType::Isoch;
627 }
628 
629 impl TypedTrb for LinkTrb {
630     const TY: TrbType = TrbType::Link;
631 }
632 
633 impl TypedTrb for EventDataTrb {
634     const TY: TrbType = TrbType::EventData;
635 }
636 
637 impl TypedTrb for NoopTrb {
638     const TY: TrbType = TrbType::Noop;
639 }
640 
641 impl TypedTrb for DisableSlotCommandTrb {
642     const TY: TrbType = TrbType::DisableSlotCommand;
643 }
644 
645 impl TypedTrb for AddressDeviceCommandTrb {
646     const TY: TrbType = TrbType::AddressDeviceCommand;
647 }
648 
649 impl TypedTrb for ConfigureEndpointCommandTrb {
650     const TY: TrbType = TrbType::ConfigureEndpointCommand;
651 }
652 
653 impl TypedTrb for EvaluateContextCommandTrb {
654     const TY: TrbType = TrbType::EvaluateContextCommand;
655 }
656 
657 impl TypedTrb for ResetEndpointCommandTrb {
658     const TY: TrbType = TrbType::ResetEndpointCommand;
659 }
660 
661 impl TypedTrb for StopEndpointCommandTrb {
662     const TY: TrbType = TrbType::StopEndpointCommand;
663 }
664 
665 impl TypedTrb for SetTRDequeuePointerCommandTrb {
666     const TY: TrbType = TrbType::SetTRDequeuePointerCommand;
667 }
668 
669 impl TypedTrb for ResetDeviceCommandTrb {
670     const TY: TrbType = TrbType::ResetDeviceCommand;
671 }
672 
673 impl TypedTrb for TransferEventTrb {
674     const TY: TrbType = TrbType::TransferEvent;
675 }
676 
677 impl TypedTrb for CommandCompletionEventTrb {
678     const TY: TrbType = TrbType::CommandCompletionEvent;
679 }
680 
681 impl TypedTrb for PortStatusChangeEventTrb {
682     const TY: TrbType = TrbType::PortStatusChangeEvent;
683 }
684 
685 /// # Safety
686 ///
687 /// All trb structs have the same size. One trb could be safely casted to another, though the
688 /// values might be invalid.
689 pub unsafe trait TrbCast: FromBytes + AsBytes + TypedTrb {
cast<T: TrbCast>(&self) -> Result<&T>690     fn cast<T: TrbCast>(&self) -> Result<&T> {
691         zerocopy::Ref::<_, T>::new(self.as_bytes())
692             .ok_or(Error::CannotCastTrb)
693             .map(zerocopy::Ref::into_ref)
694     }
695 
cast_mut<T: TrbCast>(&mut self) -> Result<&mut T>696     fn cast_mut<T: TrbCast>(&mut self) -> Result<&mut T> {
697         zerocopy::Ref::<_, T>::new(self.as_bytes_mut())
698             .ok_or(Error::CannotCastTrb)
699             .map(zerocopy::Ref::into_mut)
700     }
701 
checked_cast<T: TrbCast>(&self) -> Result<&T>702     fn checked_cast<T: TrbCast>(&self) -> Result<&T> {
703         if self
704             .cast::<Trb>()?
705             .get_trb_type()
706             .map_err(Error::UnknownTrbType)?
707             != T::TY
708         {
709             return Err(Error::CannotCastTrb);
710         }
711         self.cast::<T>()
712     }
713 
checked_mut_cast<T: TrbCast>(&mut self) -> Result<&mut T>714     fn checked_mut_cast<T: TrbCast>(&mut self) -> Result<&mut T> {
715         if self
716             .cast::<Trb>()?
717             .get_trb_type()
718             .map_err(Error::UnknownTrbType)?
719             != T::TY
720         {
721             return Err(Error::CannotCastTrb);
722         }
723         self.cast_mut::<T>()
724     }
725 }
726 
727 // SAFETY: see safety comments for TrbCast
728 unsafe impl TrbCast for Trb {}
729 // SAFETY: see safety comments for TrbCast
730 unsafe impl TrbCast for NormalTrb {}
731 // SAFETY: see safety comments for TrbCast
732 unsafe impl TrbCast for SetupStageTrb {}
733 // SAFETY: see safety comments for TrbCast
734 unsafe impl TrbCast for DataStageTrb {}
735 // SAFETY: see safety comments for TrbCast
736 unsafe impl TrbCast for StatusStageTrb {}
737 // SAFETY: see safety comments for TrbCast
738 unsafe impl TrbCast for IsochTrb {}
739 // SAFETY: see safety comments for TrbCast
740 unsafe impl TrbCast for LinkTrb {}
741 // SAFETY: see safety comments for TrbCast
742 unsafe impl TrbCast for EventDataTrb {}
743 // SAFETY: see safety comments for TrbCast
744 unsafe impl TrbCast for NoopTrb {}
745 // SAFETY: see safety comments for TrbCast
746 unsafe impl TrbCast for DisableSlotCommandTrb {}
747 // SAFETY: see safety comments for TrbCast
748 unsafe impl TrbCast for AddressDeviceCommandTrb {}
749 // SAFETY: see safety comments for TrbCast
750 unsafe impl TrbCast for ConfigureEndpointCommandTrb {}
751 // SAFETY: see safety comments for TrbCast
752 unsafe impl TrbCast for EvaluateContextCommandTrb {}
753 // SAFETY: see safety comments for TrbCast
754 unsafe impl TrbCast for ResetEndpointCommandTrb {}
755 // SAFETY: see safety comments for TrbCast
756 unsafe impl TrbCast for StopEndpointCommandTrb {}
757 // SAFETY: see safety comments for TrbCast
758 unsafe impl TrbCast for SetTRDequeuePointerCommandTrb {}
759 // SAFETY: see safety comments for TrbCast
760 unsafe impl TrbCast for ResetDeviceCommandTrb {}
761 // SAFETY: see safety comments for TrbCast
762 unsafe impl TrbCast for TransferEventTrb {}
763 // SAFETY: see safety comments for TrbCast
764 unsafe impl TrbCast for CommandCompletionEventTrb {}
765 // SAFETY: see safety comments for TrbCast
766 unsafe impl TrbCast for PortStatusChangeEventTrb {}
767 
768 #[bitfield]
769 #[derive(Clone, Copy, AsBytes, FromZeroes, FromBytes)]
770 pub struct EventRingSegmentTableEntry {
771     ring_segment_base_address: B64,
772     ring_segment_size: B16,
773     reserved2: B48,
774 }
775 
776 #[bitfield]
777 #[derive(Clone, Copy, AsBytes, FromZeroes, FromBytes)]
778 pub struct InputControlContext {
779     // Xhci spec 6.2.5.1.
780     drop_context_flags: B32,
781     add_context_flags: B32,
782     reserved0: B32,
783     reserved1: B32,
784     reserved2: B32,
785     reserved3: B32,
786     reserved4: B32,
787     configuration_value: B8,
788     interface_number: B8,
789     alternate_setting: B8,
790     reserved5: B8,
791 }
792 
793 impl InputControlContext {
794     /// Get drop context flag.
drop_context_flag(&self, idx: u8) -> bool795     pub fn drop_context_flag(&self, idx: u8) -> bool {
796         (self.get_drop_context_flags() & (1 << idx)) != 0
797     }
798 
799     /// Get add context flag.
add_context_flag(&self, idx: u8) -> bool800     pub fn add_context_flag(&self, idx: u8) -> bool {
801         (self.get_add_context_flags() & (1 << idx)) != 0
802     }
803 }
804 
805 // Size of device context entries (SlotContext and EndpointContext).
806 pub const DEVICE_CONTEXT_ENTRY_SIZE: usize = 32usize;
807 
808 #[bitfield]
809 #[derive(Clone, Copy, FromZeroes, FromBytes, AsBytes)]
810 pub struct SlotContext {
811     route_string: B20,
812     speed: B4,
813     reserved1: B1,
814     mtt: B1,
815     hub: B1,
816     context_entries: B5,
817     max_exit_latency: B16,
818     root_hub_port_number: B8,
819     num_ports: B8,
820     tt_hub_slot_id: B8,
821     tt_port_number: B8,
822     tt_think_time: B2,
823     reserved2: B4,
824     interrupter_target: B10,
825     usb_device_address: B8,
826     reserved3: B19,
827     slot_state: DeviceSlotState,
828     reserved4: B32,
829     reserved5: B32,
830     reserved6: B32,
831     reserved7: B32,
832 }
833 
834 #[bitfield]
835 #[derive(Clone, Copy, AsBytes, FromZeroes, FromBytes)]
836 pub struct EndpointContext {
837     endpoint_state: EndpointState,
838     reserved1: B5,
839     mult: B2,
840     max_primary_streams: B5,
841     linear_stream_array: B1,
842     interval: B8,
843     max_esit_payload_hi: B8,
844     reserved2: B1,
845     error_count: B2,
846     endpoint_type: B3,
847     reserved3: B1,
848     host_initiate_disable: B1,
849     max_burst_size: B8,
850     max_packet_size: B16,
851     dequeue_cycle_state: bool,
852     reserved4: B3,
853     tr_dequeue_pointer: DequeuePtr,
854     average_trb_length: B16,
855     max_esit_payload_lo: B16,
856     reserved5: B32,
857     reserved6: B32,
858     reserved7: B32,
859 }
860 
861 #[bitfield]
862 #[derive(Clone, Copy, AsBytes, FromZeroes, FromBytes)]
863 pub struct StreamContext {
864     dequeue_cycle_state: bool,
865     stream_context_type: B3,
866     tr_dequeue_pointer: DequeuePtr,
867     stopped_edtla: B24,
868     reserved1: B8,
869     reserved2: B32,
870 }
871 
872 #[repr(C)]
873 #[derive(Clone, Copy, Debug, FromZeroes, FromBytes, AsBytes)]
874 pub struct StreamContextArray {
875     pub stream_contexts: [StreamContext; 16],
876 }
877 
878 /// Device context.
879 #[repr(C)]
880 #[derive(Clone, Copy, Debug, FromZeroes, FromBytes, AsBytes)]
881 pub struct DeviceContext {
882     pub slot_context: SlotContext,
883     pub endpoint_context: [EndpointContext; 31],
884 }
885 
886 /// POD struct associates a TRB with its address in guest memory.  This is
887 /// useful because transfer and command completion event TRBs must contain
888 /// pointers to the original TRB that generated the event.
889 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
890 pub struct AddressedTrb {
891     pub trb: Trb,
892     pub gpa: u64,
893 }
894 
895 pub type TransferDescriptor = Vec<AddressedTrb>;
896 
897 #[cfg(test)]
898 mod tests {
899     use super::*;
900 
901     #[test]
check_struct_sizes()902     fn check_struct_sizes() {
903         assert_eq!(std::mem::size_of::<Trb>(), TRB_SIZE);
904         assert_eq!(std::mem::size_of::<NormalTrb>(), TRB_SIZE);
905         assert_eq!(std::mem::size_of::<SetupStageTrb>(), TRB_SIZE);
906         assert_eq!(std::mem::size_of::<DataStageTrb>(), TRB_SIZE);
907         assert_eq!(std::mem::size_of::<StatusStageTrb>(), TRB_SIZE);
908         assert_eq!(std::mem::size_of::<IsochTrb>(), TRB_SIZE);
909         assert_eq!(std::mem::size_of::<LinkTrb>(), TRB_SIZE);
910         assert_eq!(std::mem::size_of::<EventDataTrb>(), TRB_SIZE);
911         assert_eq!(std::mem::size_of::<NoopTrb>(), TRB_SIZE);
912         assert_eq!(std::mem::size_of::<DisableSlotCommandTrb>(), TRB_SIZE);
913         assert_eq!(std::mem::size_of::<AddressDeviceCommandTrb>(), TRB_SIZE);
914         assert_eq!(std::mem::size_of::<ConfigureEndpointCommandTrb>(), TRB_SIZE);
915         assert_eq!(std::mem::size_of::<EvaluateContextCommandTrb>(), TRB_SIZE);
916         assert_eq!(std::mem::size_of::<ResetEndpointCommandTrb>(), TRB_SIZE);
917         assert_eq!(std::mem::size_of::<StopEndpointCommandTrb>(), TRB_SIZE);
918         assert_eq!(
919             std::mem::size_of::<SetTRDequeuePointerCommandTrb>(),
920             TRB_SIZE
921         );
922         assert_eq!(std::mem::size_of::<ResetDeviceCommandTrb>(), TRB_SIZE);
923         assert_eq!(std::mem::size_of::<TransferEventTrb>(), TRB_SIZE);
924         assert_eq!(std::mem::size_of::<CommandCompletionEventTrb>(), TRB_SIZE);
925         assert_eq!(std::mem::size_of::<PortStatusChangeEventTrb>(), TRB_SIZE);
926 
927         assert_eq!(
928             std::mem::size_of::<EventRingSegmentTableEntry>(),
929             SEGMENT_TABLE_SIZE
930         );
931         assert_eq!(std::mem::size_of::<InputControlContext>(), 32);
932         assert_eq!(
933             std::mem::size_of::<SlotContext>(),
934             DEVICE_CONTEXT_ENTRY_SIZE
935         );
936         assert_eq!(
937             std::mem::size_of::<EndpointContext>(),
938             DEVICE_CONTEXT_ENTRY_SIZE
939         );
940         assert_eq!(
941             std::mem::size_of::<DeviceContext>(),
942             32 * DEVICE_CONTEXT_ENTRY_SIZE
943         );
944     }
945 }
946