| 312 | sum += ((uint8_t*)header)[i]; |
| 313 | return sum == 0; |
| 314 | } |
| 315 | |
| 316 | BAN::ErrorOr<void> ACPI::initialize_impl() |
| 317 | { |
| 318 | auto opt_rsdp = locate_rsdp(); |
| 319 | if (!opt_rsdp.has_value()) |
| 320 | return BAN::Error::from_errno(ENODEV); |
| 321 | const RSDP rsdp = opt_rsdp.release_value(); |
| 322 | |
| 323 | uint32_t root_entry_count = 0; |
| 324 | |
| 325 | if (rsdp.revision >= 2) |
| 326 | { |
| 327 | TRY(PageTable::with_fast_page(rsdp.xsdt_address & PAGE_ADDR_MASK, |
| 328 | [&]() -> BAN::ErrorOr<void> |
| 329 | { |
| 330 | auto& xsdt = PageTable::fast_page_as<const XSDT>(rsdp.xsdt_address % PAGE_SIZE); |
| 331 | if (memcmp(xsdt.signature, "XSDT", 4) != 0) |
| 332 | return BAN::Error::from_errno(ENODEV); |
| 333 | if (!is_valid_std_header(&xsdt)) |
| 334 | return BAN::Error::from_errno(ENODEV); |
| 335 | |
| 336 | m_header_table_paddr = rsdp.xsdt_address + offsetof(XSDT, entries); |
| 337 | m_entry_size = 8; |
| 338 | root_entry_count = (xsdt.length - sizeof(SDTHeader)) / 8; |
| 339 | return {}; |
| 340 | } |
| 341 | )); |
| 342 | } |
| 343 | else |
| 344 | { |
| 345 | TRY(PageTable::with_fast_page(rsdp.rsdt_address & PAGE_ADDR_MASK, |
| 346 | [&]() -> BAN::ErrorOr<void> |
| 347 | { |
| 348 | auto& rsdt = PageTable::fast_page_as<const RSDT>(rsdp.rsdt_address % PAGE_SIZE); |
| 349 | if (memcmp(rsdt.signature, "RSDT", 4) != 0) |
| 350 | return BAN::Error::from_errno(ENODEV); |
| 351 | if (!is_valid_std_header(&rsdt)) |
| 352 | return BAN::Error::from_errno(ENODEV); |
| 353 | |
| 354 | m_header_table_paddr = rsdp.rsdt_address + offsetof(RSDT, entries); |
| 355 | m_entry_size = 4; |
| 356 | root_entry_count = (rsdt.length - sizeof(SDTHeader)) / 4; |
| 357 | return {}; |
| 358 | } |
| 359 | )); |
| 360 | } |
| 361 | |
| 362 | size_t needed_pages = range_page_count(m_header_table_paddr, root_entry_count * m_entry_size); |
| 363 | m_header_table_vaddr = PageTable::kernel().reserve_free_contiguous_pages(needed_pages, KERNEL_OFFSET); |
| 364 | ASSERT(m_header_table_vaddr); |
| 365 | |
| 366 | m_header_table_vaddr += m_header_table_paddr % PAGE_SIZE; |
| 367 | |
| 368 | PageTable::kernel().map_range_at( |
| 369 | m_header_table_paddr & PAGE_ADDR_MASK, |
| 370 | m_header_table_vaddr & PAGE_ADDR_MASK, |
| 371 | needed_pages * PAGE_SIZE, |
no test coverage detected