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