control.rs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. use super::{BitsIterator, GHC_IE};
  2. use crate::{kernel::mem::PhysAccess as _, sync::fence::memory_barrier};
  3. use core::ptr::NonNull;
  4. use eonix_mm::address::PAddr;
  5. /// An `AdapterControl` is an HBA device Global Host Control block
  6. ///
  7. /// # Access
  8. ///
  9. /// All reads and writes to this struct is volatile
  10. ///
  11. #[allow(dead_code)]
  12. #[repr(C)]
  13. struct AdapterControlData {
  14. capabilities: u32,
  15. global_host_control: u32,
  16. interrupt_status: u32,
  17. ports_implemented: u32,
  18. version: u32,
  19. command_completion_coalescing_control: u32,
  20. command_completion_coalescing_ports: u32,
  21. enclosure_management_location: u32,
  22. enclosure_management_control: u32,
  23. host_capabilities_extended: u32,
  24. bios_handoff_control_status: u32,
  25. _reserved: [u8; 116],
  26. vendor: [u8; 96],
  27. }
  28. #[allow(dead_code)]
  29. const CONTROL_CAP: usize = 0;
  30. const CONTROL_GHC: usize = 1;
  31. const CONTROL_IS: usize = 2;
  32. const CONTROL_PI: usize = 3;
  33. pub struct AdapterControl {
  34. control_data: NonNull<u32>,
  35. }
  36. /// # Safety
  37. /// At the same time, exactly one instance of this struct may exist.
  38. unsafe impl Send for AdapterControl {}
  39. impl AdapterControl {
  40. pub fn new(addr: PAddr) -> Self {
  41. Self {
  42. control_data: unsafe { addr.as_ptr() },
  43. }
  44. }
  45. }
  46. impl AdapterControl {
  47. fn read(&self, off: usize) -> u32 {
  48. unsafe { self.control_data.offset(off as isize).read_volatile() }
  49. }
  50. fn write(&self, off: usize, value: u32) {
  51. unsafe { self.control_data.offset(off as isize).write_volatile(value) }
  52. }
  53. pub fn enable_interrupts(&self) {
  54. let ghc = self.read(CONTROL_GHC);
  55. self.write(CONTROL_GHC, ghc | GHC_IE);
  56. memory_barrier();
  57. }
  58. pub fn implemented_ports(&self) -> BitsIterator {
  59. BitsIterator::new(self.read(CONTROL_PI))
  60. }
  61. pub fn pending_interrupts(&self) -> BitsIterator {
  62. BitsIterator::new(self.read(CONTROL_IS))
  63. }
  64. pub fn clear_interrupt(&self, no: u32) {
  65. self.write(CONTROL_IS, 1 << no);
  66. memory_barrier();
  67. }
  68. }