constructed_tables_test.rs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. use super::{fadt::Fadt, parse_rsdp, rsdp::Rsdp, sdt::SdtHeader, AcpiHandler, PhysicalMapping};
  2. use std::boxed::Box;
  3. /// These tests cover ideal sets of ACPI tables, which we construct on the fly. Eventually, this
  4. /// should cover all compliant implementations, but does not guarantee we'll be able to parse a
  5. /// particular hardware's tables, obviously.
  6. use std::mem;
  7. use std::ptr::NonNull;
  8. const OEM_ID: &[u8; 6] = b"RUST ";
  9. /*
  10. * We use fake physical addresses to track what is being requested. When a particular table or
  11. * resource is requested, we just allocate it on the heap and return the "virtual address"
  12. * (a pointer onto the heap).
  13. */
  14. const RSDP_ADDRESS: usize = 0x0;
  15. const RSDT_ADDRESS: usize = 0x1;
  16. const FADT_ADDRESS: usize = 0x2;
  17. #[repr(C, packed)]
  18. struct TestRsdt {
  19. header: SdtHeader,
  20. fadt: u32,
  21. // TODO: We should probably actually add some SDTs
  22. }
  23. struct TestHandler;
  24. impl AcpiHandler for TestHandler {
  25. fn map_physical_region<T>(&mut self, physical_address: usize) -> PhysicalMapping<T> {
  26. match physical_address {
  27. RSDP_ADDRESS => {
  28. let rsdp = Box::new(Rsdp::make_testcase(
  29. *b"RSD PTR ",
  30. None,
  31. *OEM_ID,
  32. 0,
  33. RSDT_ADDRESS as u32,
  34. 0,
  35. 0x0,
  36. None,
  37. [0, 0, 0],
  38. ));
  39. PhysicalMapping {
  40. physical_start: RSDP_ADDRESS,
  41. virtual_start: unsafe {
  42. NonNull::<T>::new_unchecked(Box::into_raw(rsdp) as *mut T)
  43. },
  44. region_length: mem::size_of::<Rsdp>(),
  45. mapped_length: mem::size_of::<Rsdp>(),
  46. }
  47. }
  48. RSDT_ADDRESS => {
  49. let checksum = 0; // TODO: calculate real checksum
  50. let rsdt = Box::new(TestRsdt {
  51. header: SdtHeader::make_testcase(
  52. *b"RSDT",
  53. mem::size_of::<TestRsdt>() as u32,
  54. 0,
  55. checksum,
  56. *OEM_ID,
  57. *b"OEMRSDT ",
  58. 0xDEADBEEF,
  59. 0xDEADBEEF,
  60. 0xDEADBEEF,
  61. ),
  62. fadt: FADT_ADDRESS as u32,
  63. });
  64. PhysicalMapping {
  65. physical_start: RSDT_ADDRESS,
  66. virtual_start: unsafe {
  67. NonNull::<T>::new_unchecked(Box::into_raw(rsdt) as *mut T)
  68. },
  69. region_length: mem::size_of::<TestRsdt>(),
  70. mapped_length: mem::size_of::<TestRsdt>(),
  71. }
  72. }
  73. FADT_ADDRESS => {
  74. let fadt = Box::new(Fadt::make_testcase(
  75. *OEM_ID,
  76. *b"OEMFADT ",
  77. 0xDEADBEEF,
  78. 0xDEADBEEF,
  79. 0xDEADBEEF,
  80. ));
  81. PhysicalMapping {
  82. physical_start: FADT_ADDRESS,
  83. virtual_start: unsafe {
  84. NonNull::<T>::new_unchecked(Box::into_raw(fadt) as *mut T)
  85. },
  86. region_length: mem::size_of::<Fadt>(),
  87. mapped_length: mem::size_of::<Fadt>(),
  88. }
  89. }
  90. _ => panic!(
  91. "ACPI requested invalid physical address: {:#x}",
  92. physical_address
  93. ),
  94. }
  95. }
  96. fn unmap_physical_region<T>(&mut self, region: PhysicalMapping<T>) {
  97. match region.physical_start {
  98. RSDP_ADDRESS | RSDT_ADDRESS | FADT_ADDRESS => {
  99. let _ = unsafe { Box::from_raw(region.virtual_start.as_ptr()) };
  100. }
  101. address => panic!(
  102. "ACPI tried to unmap a region not created by test harness: {:#x}",
  103. address
  104. ),
  105. }
  106. }
  107. }
  108. #[test]
  109. fn test_constructed_tables() {
  110. let mut test_handler = TestHandler;
  111. match parse_rsdp(&mut test_handler, RSDP_ADDRESS) {
  112. Ok(_) => {}
  113. Err(err) => {}
  114. }
  115. }