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