control.rs 2.0 KB

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