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