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