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