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 std::fmt::{self, Display}; 9 use sys_util::GuestAddress; 10 11 use std; 12 13 #[derive(Debug)] 14 pub enum Error { 15 UnknownTrbType(BitFieldError), 16 CannotCastTrb, 17 } 18 19 type Result<T> = std::result::Result<T, Error>; 20 21 impl Display for Error { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result22 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 23 use self::Error::*; 24 25 match self { 26 UnknownTrbType(e) => write!(f, "we got an unknown trb type value: {}", e), 27 CannotCastTrb => write!(f, "cannot cast trb from raw memory"), 28 } 29 } 30 } 31 32 // Fixed size of all TRB types. 33 const TRB_SIZE: usize = 16; 34 35 // Size of segment table. 36 const SEGMENT_TABLE_SIZE: usize = 16; 37 38 /// All kinds of trb. 39 #[bitfield] 40 #[bits = 6] 41 #[derive(PartialEq, Debug, Clone, Copy)] 42 pub enum TrbType { 43 Reserved = 0, 44 Normal = 1, 45 SetupStage = 2, 46 DataStage = 3, 47 StatusStage = 4, 48 Isoch = 5, 49 Link = 6, 50 EventData = 7, 51 Noop = 8, 52 EnableSlotCommand = 9, 53 DisableSlotCommand = 10, 54 AddressDeviceCommand = 11, 55 ConfigureEndpointCommand = 12, 56 EvaluateContextCommand = 13, 57 ResetEndpointCommand = 14, 58 StopEndpointCommand = 15, 59 SetTRDequeuePointerCommand = 16, 60 ResetDeviceCommand = 17, 61 NoopCommand = 23, 62 TransferEvent = 32, 63 CommandCompletionEvent = 33, 64 PortStatusChangeEvent = 34, 65 } 66 67 /// Completion code of trb types. 68 #[bitfield] 69 #[bits = 8] 70 #[derive(PartialEq, Debug)] 71 pub enum TrbCompletionCode { 72 Success = 1, 73 TransactionError = 4, 74 TrbError = 5, 75 NoSlotsAvailableError = 9, 76 SlotNotEnabledError = 11, 77 ShortPacket = 13, 78 ContextStateError = 19, 79 } 80 81 /// State of device slot. 82 #[bitfield] 83 #[bits = 5] 84 #[derive(PartialEq, Debug)] 85 pub enum DeviceSlotState { 86 // The same value (0) is used for both the enabled and disabled states. See 87 // xhci spec table 60. 88 DisabledOrEnabled = 0, 89 Default = 1, 90 Addressed = 2, 91 Configured = 3, 92 } 93 94 /// State of endpoint. 95 #[bitfield] 96 #[bits = 3] 97 #[derive(PartialEq, Debug)] 98 pub enum EndpointState { 99 Disabled = 0, 100 Running = 1, 101 } 102 103 #[bitfield] 104 #[bits = 60] 105 #[derive(PartialEq, 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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)] 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 /// All trb structs have the same size. One trb could be safely casted to another, though the 686 /// values might be invalid. 687 pub unsafe trait TrbCast: DataInit + TypedTrb { cast<T: TrbCast>(&self) -> Result<&T>688 fn cast<T: TrbCast>(&self) -> Result<&T> { 689 T::from_slice(self.as_slice()).ok_or(Error::CannotCastTrb) 690 } 691 cast_mut<T: TrbCast>(&mut self) -> Result<&mut T>692 fn cast_mut<T: TrbCast>(&mut self) -> Result<&mut T> { 693 T::from_mut_slice(self.as_mut_slice()).ok_or(Error::CannotCastTrb) 694 } 695 checked_cast<T: TrbCast>(&self) -> Result<&T>696 fn checked_cast<T: TrbCast>(&self) -> Result<&T> { 697 if Trb::from_slice(self.as_slice()) 698 .ok_or(Error::CannotCastTrb)? 699 .get_trb_type() 700 .map_err(Error::UnknownTrbType)? 701 != T::TY 702 { 703 return Err(Error::CannotCastTrb); 704 } 705 T::from_slice(self.as_slice()).ok_or(Error::CannotCastTrb) 706 } 707 checked_mut_cast<T: TrbCast>(&mut self) -> Result<&mut T>708 fn checked_mut_cast<T: TrbCast>(&mut self) -> Result<&mut T> { 709 if Trb::from_slice(self.as_slice()) 710 .ok_or(Error::CannotCastTrb)? 711 .get_trb_type() 712 .map_err(Error::UnknownTrbType)? 713 != T::TY 714 { 715 return Err(Error::CannotCastTrb); 716 } 717 T::from_mut_slice(self.as_mut_slice()).ok_or(Error::CannotCastTrb) 718 } 719 } 720 721 unsafe impl DataInit for Trb {} 722 unsafe impl DataInit for NormalTrb {} 723 unsafe impl DataInit for SetupStageTrb {} 724 unsafe impl DataInit for DataStageTrb {} 725 unsafe impl DataInit for StatusStageTrb {} 726 unsafe impl DataInit for IsochTrb {} 727 unsafe impl DataInit for LinkTrb {} 728 unsafe impl DataInit for EventDataTrb {} 729 unsafe impl DataInit for NoopTrb {} 730 unsafe impl DataInit for DisableSlotCommandTrb {} 731 unsafe impl DataInit for AddressDeviceCommandTrb {} 732 unsafe impl DataInit for ConfigureEndpointCommandTrb {} 733 unsafe impl DataInit for EvaluateContextCommandTrb {} 734 unsafe impl DataInit for ResetEndpointCommandTrb {} 735 unsafe impl DataInit for StopEndpointCommandTrb {} 736 unsafe impl DataInit for SetTRDequeuePointerCommandTrb {} 737 unsafe impl DataInit for ResetDeviceCommandTrb {} 738 unsafe impl DataInit for TransferEventTrb {} 739 unsafe impl DataInit for CommandCompletionEventTrb {} 740 unsafe impl DataInit for PortStatusChangeEventTrb {} 741 unsafe impl DataInit for EventRingSegmentTableEntry {} 742 unsafe impl DataInit for InputControlContext {} 743 unsafe impl DataInit for SlotContext {} 744 unsafe impl DataInit for EndpointContext {} 745 746 unsafe impl DataInit for DeviceContext {} 747 unsafe impl DataInit for AddressedTrb {} 748 749 unsafe impl TrbCast for Trb {} 750 unsafe impl TrbCast for NormalTrb {} 751 unsafe impl TrbCast for SetupStageTrb {} 752 unsafe impl TrbCast for DataStageTrb {} 753 unsafe impl TrbCast for StatusStageTrb {} 754 unsafe impl TrbCast for IsochTrb {} 755 unsafe impl TrbCast for LinkTrb {} 756 unsafe impl TrbCast for EventDataTrb {} 757 unsafe impl TrbCast for NoopTrb {} 758 unsafe impl TrbCast for DisableSlotCommandTrb {} 759 unsafe impl TrbCast for AddressDeviceCommandTrb {} 760 unsafe impl TrbCast for ConfigureEndpointCommandTrb {} 761 unsafe impl TrbCast for EvaluateContextCommandTrb {} 762 unsafe impl TrbCast for ResetEndpointCommandTrb {} 763 unsafe impl TrbCast for StopEndpointCommandTrb {} 764 unsafe impl TrbCast for SetTRDequeuePointerCommandTrb {} 765 unsafe impl TrbCast for ResetDeviceCommandTrb {} 766 unsafe impl TrbCast for TransferEventTrb {} 767 unsafe impl TrbCast for CommandCompletionEventTrb {} 768 unsafe impl TrbCast for PortStatusChangeEventTrb {} 769 770 #[bitfield] 771 #[derive(Clone, Copy)] 772 pub struct EventRingSegmentTableEntry { 773 ring_segment_base_address: B64, 774 ring_segment_size: B16, 775 reserved2: B48, 776 } 777 778 #[bitfield] 779 #[derive(Clone, Copy)] 780 pub struct InputControlContext { 781 // Xhci spec 6.2.5.1. 782 drop_context_flags: B32, 783 add_context_flags: B32, 784 reserved0: B32, 785 reserved1: B32, 786 reserved2: B32, 787 reserved3: B32, 788 reserved4: B32, 789 configuration_value: B8, 790 interface_number: B8, 791 alternate_setting: B8, 792 reserved5: B8, 793 } 794 795 impl InputControlContext { 796 /// Get drop context flag. drop_context_flag(&self, idx: u8) -> bool797 pub fn drop_context_flag(&self, idx: u8) -> bool { 798 (self.get_drop_context_flags() & (1 << idx)) != 0 799 } 800 801 /// Get add context flag. add_context_flag(&self, idx: u8) -> bool802 pub fn add_context_flag(&self, idx: u8) -> bool { 803 (self.get_add_context_flags() & (1 << idx)) != 0 804 } 805 } 806 807 // Size of device context entries (SlotContext and EndpointContext). 808 pub const DEVICE_CONTEXT_ENTRY_SIZE: usize = 32usize; 809 810 #[bitfield] 811 #[derive(Clone, Copy)] 812 pub struct SlotContext { 813 route_string: B20, 814 speed: B4, 815 reserved1: B1, 816 mtt: B1, 817 hub: B1, 818 context_entries: B5, 819 max_exit_latency: B16, 820 root_hub_port_number: B8, 821 num_ports: B8, 822 tt_hub_slot_id: B8, 823 tt_port_number: B8, 824 tt_think_time: B2, 825 reserved2: B4, 826 interrupter_target: B10, 827 usb_device_address: B8, 828 reserved3: B19, 829 slot_state: DeviceSlotState, 830 reserved4: B32, 831 reserved5: B32, 832 reserved6: B32, 833 reserved7: B32, 834 } 835 836 #[bitfield] 837 #[derive(Clone, Copy)] 838 pub struct EndpointContext { 839 endpoint_state: EndpointState, 840 reserved1: B5, 841 mult: B2, 842 max_primary_streams: B5, 843 linear_stream_array: B1, 844 interval: B8, 845 max_esit_payload_hi: B8, 846 reserved2: B1, 847 error_count: B2, 848 endpoint_type: B3, 849 reserved3: B1, 850 host_initiate_disable: B1, 851 max_burst_size: B8, 852 max_packet_size: B16, 853 dequeue_cycle_state: bool, 854 reserved4: B3, 855 tr_dequeue_pointer: DequeuePtr, 856 average_trb_length: B16, 857 max_esit_payload_lo: B16, 858 reserved5: B32, 859 reserved6: B32, 860 reserved7: B32, 861 } 862 863 /// Device context. 864 #[derive(Clone, Copy, Debug)] 865 pub struct DeviceContext { 866 pub slot_context: SlotContext, 867 pub endpoint_context: [EndpointContext; 31], 868 } 869 870 /// POD struct associates a TRB with its address in guest memory. This is 871 /// useful because transfer and command completion event TRBs must contain 872 /// pointers to the original TRB that generated the event. 873 #[derive(Clone, Copy, Debug, PartialEq)] 874 pub struct AddressedTrb { 875 pub trb: Trb, 876 pub gpa: u64, 877 } 878 879 pub type TransferDescriptor = Vec<AddressedTrb>; 880 881 #[cfg(test)] 882 mod tests { 883 use super::*; 884 885 #[test] check_struct_sizes()886 fn check_struct_sizes() { 887 assert_eq!(std::mem::size_of::<Trb>(), TRB_SIZE); 888 assert_eq!(std::mem::size_of::<NormalTrb>(), TRB_SIZE); 889 assert_eq!(std::mem::size_of::<SetupStageTrb>(), TRB_SIZE); 890 assert_eq!(std::mem::size_of::<DataStageTrb>(), TRB_SIZE); 891 assert_eq!(std::mem::size_of::<StatusStageTrb>(), TRB_SIZE); 892 assert_eq!(std::mem::size_of::<IsochTrb>(), TRB_SIZE); 893 assert_eq!(std::mem::size_of::<LinkTrb>(), TRB_SIZE); 894 assert_eq!(std::mem::size_of::<EventDataTrb>(), TRB_SIZE); 895 assert_eq!(std::mem::size_of::<NoopTrb>(), TRB_SIZE); 896 assert_eq!(std::mem::size_of::<DisableSlotCommandTrb>(), TRB_SIZE); 897 assert_eq!(std::mem::size_of::<AddressDeviceCommandTrb>(), TRB_SIZE); 898 assert_eq!(std::mem::size_of::<ConfigureEndpointCommandTrb>(), TRB_SIZE); 899 assert_eq!(std::mem::size_of::<EvaluateContextCommandTrb>(), TRB_SIZE); 900 assert_eq!(std::mem::size_of::<ResetEndpointCommandTrb>(), TRB_SIZE); 901 assert_eq!(std::mem::size_of::<StopEndpointCommandTrb>(), TRB_SIZE); 902 assert_eq!( 903 std::mem::size_of::<SetTRDequeuePointerCommandTrb>(), 904 TRB_SIZE 905 ); 906 assert_eq!(std::mem::size_of::<ResetDeviceCommandTrb>(), TRB_SIZE); 907 assert_eq!(std::mem::size_of::<TransferEventTrb>(), TRB_SIZE); 908 assert_eq!(std::mem::size_of::<CommandCompletionEventTrb>(), TRB_SIZE); 909 assert_eq!(std::mem::size_of::<PortStatusChangeEventTrb>(), TRB_SIZE); 910 911 assert_eq!( 912 std::mem::size_of::<EventRingSegmentTableEntry>(), 913 SEGMENT_TABLE_SIZE 914 ); 915 assert_eq!(std::mem::size_of::<InputControlContext>(), 32); 916 assert_eq!( 917 std::mem::size_of::<SlotContext>(), 918 DEVICE_CONTEXT_ENTRY_SIZE 919 ); 920 assert_eq!( 921 std::mem::size_of::<EndpointContext>(), 922 DEVICE_CONTEXT_ENTRY_SIZE 923 ); 924 assert_eq!( 925 std::mem::size_of::<DeviceContext>(), 926 32 * DEVICE_CONTEXT_ENTRY_SIZE 927 ); 928 } 929 } 930