summaryrefslogtreecommitdiff
path: root/Kernel/ACPI
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-05-22 12:55:23 +0200
committerAndreas Kling <kling@serenityos.org>2020-05-22 13:17:38 +0200
commit84b7bc5e14bcdaef0721143f8d99b40fde7e7c5e (patch)
tree5db8c1ac3eefc0fdcaad5303f511cf56d900b815 /Kernel/ACPI
parent6b5d2afd007ce5834aa9e816ac5db7d99b04d36f (diff)
downloadserenity-84b7bc5e14bcdaef0721143f8d99b40fde7e7c5e.zip
Kernel: Add convenient ways to map whole BIOS and EBDA into memory
This patch adds a MappedROM abstraction to the Kernel VM subsystem. It's basically the read-only byte buffer equivalent of a TypedMapping. We use this in the ACPI and MP table parsers to scan for interesting stuff in low memory instead of doing a bunch of address arithmetic.
Diffstat (limited to 'Kernel/ACPI')
-rw-r--r--Kernel/ACPI/MultiProcessorParser.cpp37
-rw-r--r--Kernel/ACPI/MultiProcessorParser.h2
-rw-r--r--Kernel/ACPI/Parser.cpp35
3 files changed, 27 insertions, 47 deletions
diff --git a/Kernel/ACPI/MultiProcessorParser.cpp b/Kernel/ACPI/MultiProcessorParser.cpp
index 450a62236c..2191d1194d 100644
--- a/Kernel/ACPI/MultiProcessorParser.cpp
+++ b/Kernel/ACPI/MultiProcessorParser.cpp
@@ -27,6 +27,7 @@
#include <AK/StringView.h>
#include <Kernel/ACPI/MultiProcessorParser.h>
+#include <Kernel/Arch/PC/BIOS.h>
#include <Kernel/Interrupts/IOAPIC.h>
#include <Kernel/StdLib.h>
#include <Kernel/VM/MemoryManager.h>
@@ -115,42 +116,28 @@ void MultiProcessorParser::parse_configuration_table()
PhysicalAddress MultiProcessorParser::search_floating_pointer()
{
- PhysicalAddress mp_floating_pointer;
- auto region = MM.allocate_kernel_region(PhysicalAddress(0), PAGE_SIZE, "MultiProcessor Parser Floating Pointer Structure Finding", Region::Access::Read);
- u16 ebda_seg = (u16) * ((uint16_t*)((region->vaddr().get() & PAGE_MASK) + 0x40e));
- klog() << "MultiProcessor: Probing EBDA, Segment 0x" << String::format("%x", ebda_seg);
-
- mp_floating_pointer = search_floating_pointer_in_ebda(ebda_seg);
+ auto mp_floating_pointer = search_floating_pointer_in_ebda();
if (!mp_floating_pointer.is_null())
return mp_floating_pointer;
return search_floating_pointer_in_bios_area();
}
-PhysicalAddress MultiProcessorParser::search_floating_pointer_in_ebda(u16 ebda_segment)
+PhysicalAddress MultiProcessorParser::search_floating_pointer_in_ebda()
{
- auto floating_pointer_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)(ebda_segment << 4))), PAGE_ROUND_UP(1024), "MultiProcessor Parser floating_pointer Finding #1", Region::Access::Read, false, true);
- char* p_floating_pointer_str = (char*)(PhysicalAddress(ebda_segment << 4).as_ptr());
- for (char* floating_pointer_str = (char*)floating_pointer_region->vaddr().offset(offset_in_page((u32)(ebda_segment << 4))).as_ptr(); floating_pointer_str < (char*)(floating_pointer_region->vaddr().offset(offset_in_page((u32)(ebda_segment << 4))).get() + 1024); floating_pointer_str += 16) {
-#ifdef MULTIPROCESSOR_DEBUG
- //dbg() << "MultiProcessor: Looking for floating pointer structure in EBDA @ V0x " << String::format("%x", floating_pointer_str) << ", P0x" << String::format("%x", p_floating_pointer_str);
-#endif
- if (!strncmp("_MP_", floating_pointer_str, strlen("_MP_")))
- return PhysicalAddress((FlatPtr)p_floating_pointer_str);
- p_floating_pointer_str += 16;
+ klog() << "MultiProcessor: Probing EBDA";
+ auto ebda = map_ebda();
+ for (auto* floating_pointer_str = ebda.base(); floating_pointer_str < ebda.end(); floating_pointer_str += 16) {
+ if (!strncmp("_MP_", (const char*)floating_pointer_str, strlen("_MP_")))
+ return ebda.paddr_of(floating_pointer_str);
}
return {};
}
PhysicalAddress MultiProcessorParser::search_floating_pointer_in_bios_area()
{
- auto floating_pointer_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)0xE0000)), PAGE_ROUND_UP(0xFFFFF - 0xE0000), "MultiProcessor Parser floating_pointer Finding #2", Region::Access::Read, false, true);
- char* p_floating_pointer_str = (char*)(PhysicalAddress(0xE0000).as_ptr());
- for (char* floating_pointer_str = (char*)floating_pointer_region->vaddr().offset(offset_in_page((u32)(0xE0000))).as_ptr(); floating_pointer_str < (char*)(floating_pointer_region->vaddr().offset(offset_in_page((u32)(0xE0000))).get() + (0xFFFFF - 0xE0000)); floating_pointer_str += 16) {
-#ifdef MULTIPROCESSOR_DEBUG
- //dbg() << "MultiProcessor: Looking for floating pointer structure in BIOS area @ V0x " << String::format("%x", floating_pointer_str) << ", P0x" << String::format("%x", p_floating_pointer_str);
-#endif
- if (!strncmp("_MP_", floating_pointer_str, strlen("_MP_")))
- return PhysicalAddress((FlatPtr)p_floating_pointer_str);
- p_floating_pointer_str += 16;
+ auto bios = map_bios();
+ for (auto* floating_pointer_str = bios.base(); floating_pointer_str < bios.end(); floating_pointer_str += 16) {
+ if (!strncmp("_MP_", (const char*)floating_pointer_str, strlen("_MP_")))
+ return bios.paddr_of(floating_pointer_str);
}
return {};
}
diff --git a/Kernel/ACPI/MultiProcessorParser.h b/Kernel/ACPI/MultiProcessorParser.h
index 18b2be6ad1..7aca917d0f 100644
--- a/Kernel/ACPI/MultiProcessorParser.h
+++ b/Kernel/ACPI/MultiProcessorParser.h
@@ -206,7 +206,7 @@ protected:
Vector<u8> get_pci_bus_ids() const;
PhysicalAddress search_floating_pointer();
- PhysicalAddress search_floating_pointer_in_ebda(u16 ebda_segment);
+ PhysicalAddress search_floating_pointer_in_ebda();
PhysicalAddress search_floating_pointer_in_bios_area();
PhysicalAddress m_floating_pointer;
diff --git a/Kernel/ACPI/Parser.cpp b/Kernel/ACPI/Parser.cpp
index 7b7817d7d4..54ece1a94d 100644
--- a/Kernel/ACPI/Parser.cpp
+++ b/Kernel/ACPI/Parser.cpp
@@ -27,11 +27,12 @@
#include <AK/StringView.h>
#include <Kernel/ACPI/Parser.h>
+#include <Kernel/Arch/PC/BIOS.h>
+#include <Kernel/IO.h>
#include <Kernel/PCI/Access.h>
+#include <Kernel/StdLib.h>
#include <Kernel/VM/MemoryManager.h>
#include <Kernel/VM/TypedMapping.h>
-#include <Kernel/IO.h>
-#include <Kernel/StdLib.h>
namespace Kernel {
namespace ACPI {
@@ -321,32 +322,25 @@ Parser::Parser(PhysicalAddress rsdp)
locate_static_data();
}
-static PhysicalAddress find_rsdp_in_ebda(u16 ebda_segment)
+static PhysicalAddress find_rsdp_in_ebda()
{
- auto rsdp_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)(ebda_segment << 4))), PAGE_ROUND_UP(1024), "ACPI Static Parser RSDP Finding #1", Region::Access::Read, false, true);
- char* p_rsdp_str = (char*)(PhysicalAddress(ebda_segment << 4).as_ptr());
- for (char* rsdp_str = (char*)rsdp_region->vaddr().offset(offset_in_page((u32)(ebda_segment << 4))).as_ptr(); rsdp_str < (char*)(rsdp_region->vaddr().offset(offset_in_page((u32)(ebda_segment << 4))).get() + 1024); rsdp_str += 16) {
+ auto ebda = map_ebda();
+ for (auto* rsdp_str = ebda.base(); rsdp_str < ebda.end(); rsdp_str += 16) {
#ifdef ACPI_DEBUG
dbg() << "ACPI: Looking for RSDP in EBDA @ V " << (void*)rsdp_str << ", P " << (void*)p_rsdp_str;
#endif
- if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR ")))
- return PhysicalAddress((FlatPtr)p_rsdp_str);
- p_rsdp_str += 16;
+ if (!strncmp("RSD PTR ", (const char*)rsdp_str, strlen("RSD PTR ")))
+ return ebda.paddr_of(rsdp_str);
}
return {};
}
static PhysicalAddress find_rsdp_in_bios_area()
{
- auto rsdp_region = MM.allocate_kernel_region(PhysicalAddress(0xE0000), PAGE_ROUND_UP(0xFFFFF - 0xE0000), "ACPI Static Parser RSDP Finding #2", Region::Access::Read, false, true);
- char* p_rsdp_str = (char*)(PhysicalAddress(0xE0000).as_ptr());
- for (char* rsdp_str = (char*)rsdp_region->vaddr().offset(offset_in_page((u32)(0xE0000))).as_ptr(); rsdp_str < (char*)(rsdp_region->vaddr().offset(offset_in_page((u32)(0xE0000))).get() + (0xFFFFF - 0xE0000)); rsdp_str += 16) {
-#ifdef ACPI_DEBUG
- dbg() << "ACPI: Looking for RSDP in BIOS ROM area @ V " << (void*)rsdp_str << ", P " << (void*)p_rsdp_str;
-#endif
- if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR ")))
- return PhysicalAddress((FlatPtr)p_rsdp_str);
- p_rsdp_str += 16;
+ auto bios = map_bios();
+ for (auto* rsdp_str = bios.base(); rsdp_str < bios.end(); rsdp_str += 16) {
+ if (!strncmp("RSD PTR ", (const char*)rsdp_str, strlen("RSD PTR ")))
+ return bios.paddr_of(rsdp_str);
}
return {};
}
@@ -364,9 +358,8 @@ static bool validate_table(const Structures::SDTHeader& v_header, size_t length)
PhysicalAddress StaticParsing::find_rsdp()
{
- auto ebda_seg_ptr = map_typed<u16>(PhysicalAddress(0x40e));
- klog() << "ACPI: Probing EBDA, Segment 0x" << String::format("%x", *ebda_seg_ptr);
- auto rsdp = find_rsdp_in_ebda(*ebda_seg_ptr);
+ klog() << "ACPI: Probing EBDA";
+ auto rsdp = find_rsdp_in_ebda();
if (!rsdp.is_null())
return rsdp;
return find_rsdp_in_bios_area();