handler.rs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. use core::{ops::Deref, ptr::NonNull};
  2. /// Describes a physical mapping created by `AcpiHandler::map_physical_region` and unmapped by
  3. /// `AcpiHandler::unmap_physical_region`. The region mapped must be at least `size_of::<T>()`
  4. /// bytes, but may be bigger.
  5. pub struct PhysicalMapping<H, T>
  6. where
  7. H: AcpiHandler,
  8. {
  9. pub physical_start: usize,
  10. pub virtual_start: NonNull<T>,
  11. pub region_length: usize, // Can be equal or larger than size_of::<T>()
  12. pub mapped_length: usize, // Differs from `region_length` if padding is added for alignment
  13. pub handler: H,
  14. }
  15. impl<H, T> Deref for PhysicalMapping<H, T>
  16. where
  17. H: AcpiHandler,
  18. {
  19. type Target = T;
  20. fn deref(&self) -> &T {
  21. unsafe { self.virtual_start.as_ref() }
  22. }
  23. }
  24. impl<H, T> Drop for PhysicalMapping<H, T>
  25. where
  26. H: AcpiHandler,
  27. {
  28. fn drop(&mut self) {
  29. self.handler.unmap_physical_region(self)
  30. }
  31. }
  32. /// An implementation of this trait must be provided to allow `acpi` to access platform-specific
  33. /// functionality, such as mapping regions of physical memory. You are free to implement these
  34. /// however you please, as long as they conform to the documentation of each function. The handler is stored in
  35. /// every `PhysicalMapping` so it's able to unmap itself when dropped, so this type needs to be something you can
  36. /// clone/move about freely (e.g. a reference, wrapper over `Rc`, marker struct, etc.).
  37. pub trait AcpiHandler: Clone + Sized {
  38. /// Given a physical address and a size, map a region of physical memory that contains `T` (note: the passed
  39. /// size may be larger than `size_of::<T>()`). The address is not neccessarily page-aligned, so the
  40. /// implementation may need to map more than `size` bytes. The virtual address the region is mapped to does not
  41. /// matter, as long as it is accessible to `acpi`.
  42. unsafe fn map_physical_region<T>(&self, physical_address: usize, size: usize) -> PhysicalMapping<Self, T>;
  43. /// Unmap the given physical mapping. This is called when a `PhysicalMapping` is dropped.
  44. fn unmap_physical_region<T>(&self, region: &PhysicalMapping<Self, T>);
  45. }