mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:57:35 +00:00
Kernel: Don't use references or pointers to physical addresses
Now the ACPI & PCI code is more safer, because we don't use raw pointers or references to objects or data that are located in the physical address space, so an accidental dereference cannot happen easily. Instead, we use the PhysicalAddress class to represent those addresses.
This commit is contained in:
parent
43d570a1e3
commit
85307dd26e
13 changed files with 91 additions and 102 deletions
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
void ACPIDynamicParser::initialize(ACPI_RAW::RSDPDescriptor20& rsdp)
|
void ACPIDynamicParser::initialize(PhysicalAddress rsdp)
|
||||||
{
|
{
|
||||||
if (!ACPIStaticParser::is_initialized()) {
|
if (!ACPIStaticParser::is_initialized()) {
|
||||||
new ACPIDynamicParser(rsdp);
|
new ACPIDynamicParser(rsdp);
|
||||||
|
@ -49,7 +49,7 @@ ACPIDynamicParser::ACPIDynamicParser()
|
||||||
{
|
{
|
||||||
kprintf("ACPI: Dynamic Parsing Enabled, Can parse AML\n");
|
kprintf("ACPI: Dynamic Parsing Enabled, Can parse AML\n");
|
||||||
}
|
}
|
||||||
ACPIDynamicParser::ACPIDynamicParser(ACPI_RAW::RSDPDescriptor20& rsdp)
|
ACPIDynamicParser::ACPIDynamicParser(PhysicalAddress rsdp)
|
||||||
: IRQHandler(9)
|
: IRQHandler(9)
|
||||||
, ACPIStaticParser(rsdp)
|
, ACPIStaticParser(rsdp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace Kernel {
|
||||||
class ACPIDynamicParser final : public IRQHandler
|
class ACPIDynamicParser final : public IRQHandler
|
||||||
, ACPIStaticParser {
|
, ACPIStaticParser {
|
||||||
public:
|
public:
|
||||||
static void initialize(ACPI_RAW::RSDPDescriptor20& rsdp);
|
static void initialize(PhysicalAddress rsdp);
|
||||||
static void initialize_without_rsdp();
|
static void initialize_without_rsdp();
|
||||||
|
|
||||||
virtual void enable_aml_interpretation() override;
|
virtual void enable_aml_interpretation() override;
|
||||||
|
@ -49,7 +49,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ACPIDynamicParser();
|
ACPIDynamicParser();
|
||||||
explicit ACPIDynamicParser(ACPI_RAW::RSDPDescriptor20&);
|
explicit ACPIDynamicParser(PhysicalAddress);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void build_namespace();
|
void build_namespace();
|
||||||
|
|
|
@ -58,10 +58,10 @@ ACPIParser::ACPIParser(bool usable)
|
||||||
s_acpi_parser = this;
|
s_acpi_parser = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ACPI_RAW::SDTHeader* ACPIParser::find_table(const char*)
|
PhysicalAddress ACPIParser::find_table(const char*)
|
||||||
{
|
{
|
||||||
kprintf("ACPI: Requested to search for a table, Abort!\n");
|
kprintf("ACPI: Requested to search for a table, Abort!\n");
|
||||||
return nullptr;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ACPIParser::do_acpi_reboot()
|
void ACPIParser::do_acpi_reboot()
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
|
|
||||||
static bool is_initialized();
|
static bool is_initialized();
|
||||||
static void initialize_limited();
|
static void initialize_limited();
|
||||||
virtual ACPI_RAW::SDTHeader* find_table(const char* sig);
|
virtual PhysicalAddress find_table(const char* sig);
|
||||||
|
|
||||||
virtual void do_acpi_reboot();
|
virtual void do_acpi_reboot();
|
||||||
virtual void do_acpi_shutdown();
|
virtual void do_acpi_shutdown();
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
void ACPIStaticParser::initialize(ACPI_RAW::RSDPDescriptor20& rsdp)
|
void ACPIStaticParser::initialize(PhysicalAddress rsdp)
|
||||||
{
|
{
|
||||||
if (!ACPIParser::is_initialized()) {
|
if (!ACPIParser::is_initialized()) {
|
||||||
new ACPIStaticParser(rsdp);
|
new ACPIStaticParser(rsdp);
|
||||||
|
@ -59,7 +59,7 @@ void ACPIStaticParser::locate_static_data()
|
||||||
locate_all_aml_tables();
|
locate_all_aml_tables();
|
||||||
}
|
}
|
||||||
|
|
||||||
ACPI_RAW::SDTHeader* ACPIStaticParser::find_table(const char* sig)
|
PhysicalAddress ACPIStaticParser::find_table(const char* sig)
|
||||||
{
|
{
|
||||||
#ifdef ACPI_DEBUG
|
#ifdef ACPI_DEBUG
|
||||||
dbgprintf("ACPI: Calling Find Table method!\n");
|
dbgprintf("ACPI: Calling Find Table method!\n");
|
||||||
|
@ -74,33 +74,34 @@ ACPI_RAW::SDTHeader* ACPIStaticParser::find_table(const char* sig)
|
||||||
#ifdef ACPI_DEBUG
|
#ifdef ACPI_DEBUG
|
||||||
dbgprintf("ACPI: Found Table @ P 0x%x\n", physical_sdt_ptr);
|
dbgprintf("ACPI: Found Table @ P 0x%x\n", physical_sdt_ptr);
|
||||||
#endif
|
#endif
|
||||||
return physical_sdt_ptr;
|
return PhysicalAddress((uintptr_t)physical_sdt_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ACPIStaticParser::init_fadt()
|
void ACPIStaticParser::init_fadt()
|
||||||
{
|
{
|
||||||
kprintf("ACPI: Initializing Fixed ACPI data\n");
|
kprintf("ACPI: Initializing Fixed ACPI data\n");
|
||||||
kprintf("ACPI: Searching for the Fixed ACPI Data Table\n");
|
kprintf("ACPI: Searching for the Fixed ACPI Data Table\n");
|
||||||
ASSERT(find_table("FACP") != nullptr);
|
|
||||||
auto* fadt_ptr = find_table("FACP");
|
|
||||||
|
|
||||||
auto checkup_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((fadt_ptr))), (PAGE_SIZE * 2), "ACPI Static Parser", Region::Access::Read);
|
auto fadt = find_table("FACP");
|
||||||
|
ASSERT(!fadt.is_null());
|
||||||
|
|
||||||
|
auto checkup_region = MM.allocate_kernel_region(fadt.page_base(), (PAGE_SIZE * 2), "ACPI Static Parser", Region::Access::Read);
|
||||||
#ifdef ACPI_DEBUG
|
#ifdef ACPI_DEBUG
|
||||||
dbgprintf("ACPI: Checking FADT Length to choose the correct mapping size\n");
|
dbgprintf("ACPI: Checking FADT Length to choose the correct mapping size\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto* sdt = (const ACPI_RAW::SDTHeader*)checkup_region->vaddr().offset(offset_in_page((fadt_ptr))).as_ptr();
|
auto* sdt = (const ACPI_RAW::SDTHeader*)checkup_region->vaddr().offset(fadt.offset_in_page().get()).as_ptr();
|
||||||
#ifdef ACPI_DEBUG
|
#ifdef ACPI_DEBUG
|
||||||
dbgprintf("ACPI: FADT @ V 0x%x, P 0x%x\n", sdt, fadt_ptr);
|
dbgprintf("ACPI: FADT @ V 0x%x, P 0x%x\n", sdt, fadt_ptr);
|
||||||
#endif
|
#endif
|
||||||
u32 length = sdt->length;
|
u32 length = sdt->length;
|
||||||
kprintf("ACPI: Fixed ACPI data, Revision %u\n", sdt->revision);
|
kprintf("ACPI: Fixed ACPI data, Revision %u\n", sdt->revision);
|
||||||
|
|
||||||
auto fadt_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((fadt_ptr))), PAGE_ROUND_UP(length) + PAGE_SIZE, "ACPI Static Parser", Region::Access::Read);
|
auto fadt_region = MM.allocate_kernel_region(fadt.page_base(), PAGE_ROUND_UP(length) + PAGE_SIZE, "ACPI Static Parser", Region::Access::Read);
|
||||||
m_fadt = make<ACPI::FixedACPIData>(*(ACPI_RAW::FADT*)fadt_region->vaddr().offset(offset_in_page((fadt_ptr))).as_ptr());
|
m_fadt = make<ACPI::FixedACPIData>(*(ACPI_RAW::FADT*)fadt_region->vaddr().offset(fadt.offset_in_page().get()).as_ptr());
|
||||||
#ifdef ACPI_DEBUG
|
#ifdef ACPI_DEBUG
|
||||||
dbgprintf("ACPI: Finished to initialize Fixed ACPI data\n");
|
dbgprintf("ACPI: Finished to initialize Fixed ACPI data\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -139,25 +140,25 @@ inline bool validate_acpi_table(ACPI_RAW::SDTHeader& v_header, size_t length)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ACPIStaticParser::get_table_size(ACPI_RAW::SDTHeader& p_header)
|
size_t ACPIStaticParser::get_table_size(PhysicalAddress table_header)
|
||||||
{
|
{
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
#ifdef ACPI_DEBUG
|
#ifdef ACPI_DEBUG
|
||||||
dbgprintf("ACPI: Checking SDT Length\n");
|
dbgprintf("ACPI: Checking SDT Length\n");
|
||||||
#endif
|
#endif
|
||||||
auto region = MM.allocate_kernel_region(PhysicalAddress((uintptr_t)&p_header).page_base(), (PAGE_SIZE * 2), "ACPI get_table_size()", Region::Access::Read);
|
auto region = MM.allocate_kernel_region(table_header.page_base(), (PAGE_SIZE * 2), "ACPI get_table_size()", Region::Access::Read);
|
||||||
auto* sdt = (volatile ACPI_RAW::SDTHeader*)region->vaddr().offset(offset_in_page(&p_header)).as_ptr();
|
auto* sdt = (volatile ACPI_RAW::SDTHeader*)region->vaddr().offset(table_header.offset_in_page().get()).as_ptr();
|
||||||
return sdt->length;
|
return sdt->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 ACPIStaticParser::get_table_revision(ACPI_RAW::SDTHeader& p_header)
|
u8 ACPIStaticParser::get_table_revision(PhysicalAddress table_header)
|
||||||
{
|
{
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
#ifdef ACPI_DEBUG
|
#ifdef ACPI_DEBUG
|
||||||
dbgprintf("ACPI: Checking SDT Revision\n");
|
dbgprintf("ACPI: Checking SDT Revision\n");
|
||||||
#endif
|
#endif
|
||||||
auto region = MM.allocate_kernel_region(PhysicalAddress((uintptr_t)&p_header).page_base(), (PAGE_SIZE * 2), "ACPI get_table_revision()", Region::Access::Read);
|
auto region = MM.allocate_kernel_region(table_header.page_base(), (PAGE_SIZE * 2), "ACPI get_table_revision()", Region::Access::Read);
|
||||||
auto* sdt = (volatile ACPI_RAW::SDTHeader*)region->vaddr().offset(offset_in_page(&p_header)).as_ptr();
|
auto* sdt = (volatile ACPI_RAW::SDTHeader*)region->vaddr().offset(table_header.offset_in_page().get()).as_ptr();
|
||||||
return sdt->revision;
|
return sdt->revision;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,25 +167,18 @@ void ACPIStaticParser::initialize_main_system_description_table()
|
||||||
#ifdef ACPI_DEBUG
|
#ifdef ACPI_DEBUG
|
||||||
dbgprintf("ACPI: Checking Main SDT Length to choose the correct mapping size\n");
|
dbgprintf("ACPI: Checking Main SDT Length to choose the correct mapping size\n");
|
||||||
#endif
|
#endif
|
||||||
ASSERT(m_main_system_description_table != nullptr);
|
ASSERT(!m_main_system_description_table.is_null());
|
||||||
u32 length;
|
auto length = get_table_size(m_main_system_description_table);
|
||||||
u8 revision;
|
auto revision = get_table_revision(m_main_system_description_table);
|
||||||
if (m_xsdt_supported) {
|
|
||||||
length = get_table_size(*m_main_system_description_table);
|
|
||||||
revision = get_table_revision(*m_main_system_description_table);
|
|
||||||
} else {
|
|
||||||
length = get_table_size(*m_main_system_description_table);
|
|
||||||
revision = get_table_revision(*m_main_system_description_table);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto main_sdt_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of(m_main_system_description_table)), PAGE_ROUND_UP(length) + PAGE_SIZE, "ACPI Static Parser Initialization", Region::Access::Read, false, true);
|
auto main_sdt_region = MM.allocate_kernel_region(m_main_system_description_table.page_base(), PAGE_ROUND_UP(length) + PAGE_SIZE, "ACPI Static Parser Initialization", Region::Access::Read, false, true);
|
||||||
auto* sdt = (volatile ACPI_RAW::SDTHeader*)main_sdt_region->vaddr().offset(offset_in_page(m_main_system_description_table)).as_ptr();
|
auto* sdt = (volatile ACPI_RAW::SDTHeader*)main_sdt_region->vaddr().offset(m_main_system_description_table.offset_in_page().get()).as_ptr();
|
||||||
kprintf("ACPI: Main Description Table valid? 0x%x\n", validate_acpi_table(const_cast<ACPI_RAW::SDTHeader&>(*sdt), length));
|
kprintf("ACPI: Main Description Table valid? 0x%x\n", validate_acpi_table(const_cast<ACPI_RAW::SDTHeader&>(*sdt), length));
|
||||||
|
|
||||||
Vector<ACPI_RAW::SDTHeader*> sdt_pointers;
|
Vector<ACPI_RAW::SDTHeader*> sdt_pointers;
|
||||||
if (m_xsdt_supported) {
|
if (m_xsdt_supported) {
|
||||||
volatile auto* xsdt = (volatile ACPI_RAW::XSDT*)sdt;
|
volatile auto* xsdt = (volatile ACPI_RAW::XSDT*)sdt;
|
||||||
kprintf("ACPI: Using XSDT, Enumerating tables @ P 0x%x\n", m_main_system_description_table);
|
kprintf("ACPI: Using XSDT, Enumerating tables @ P 0x%x\n", m_main_system_description_table.get());
|
||||||
kprintf("ACPI: XSDT Revision %d, Total length - %u\n", revision, length);
|
kprintf("ACPI: XSDT Revision %d, Total length - %u\n", revision, length);
|
||||||
#ifdef ACPI_DEBUG
|
#ifdef ACPI_DEBUG
|
||||||
dbgprintf("ACPI: XSDT pointer @ V 0x%x\n", xsdt);
|
dbgprintf("ACPI: XSDT pointer @ V 0x%x\n", xsdt);
|
||||||
|
@ -197,7 +191,7 @@ void ACPIStaticParser::initialize_main_system_description_table()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
volatile auto* rsdt = (volatile ACPI_RAW::RSDT*)sdt;
|
volatile auto* rsdt = (volatile ACPI_RAW::RSDT*)sdt;
|
||||||
kprintf("ACPI: Using RSDT, Enumerating tables @ P 0x%x\n", m_main_system_description_table);
|
kprintf("ACPI: Using RSDT, Enumerating tables @ P 0x%x\n", m_main_system_description_table.get());
|
||||||
kprintf("ACPI: RSDT Revision %d, Total length - %u\n", revision, length);
|
kprintf("ACPI: RSDT Revision %d, Total length - %u\n", revision, length);
|
||||||
#ifdef ACPI_DEBUG
|
#ifdef ACPI_DEBUG
|
||||||
dbgprintf("ACPI: RSDT pointer @ V 0x%x\n", rsdt);
|
dbgprintf("ACPI: RSDT pointer @ V 0x%x\n", rsdt);
|
||||||
|
@ -214,8 +208,8 @@ void ACPIStaticParser::initialize_main_system_description_table()
|
||||||
|
|
||||||
void ACPIStaticParser::locate_main_system_description_table()
|
void ACPIStaticParser::locate_main_system_description_table()
|
||||||
{
|
{
|
||||||
auto rsdp_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)m_rsdp)), (PAGE_SIZE * 2), "ACPI Static Parser Initialization", Region::Access::Read, false, true);
|
auto rsdp_region = MM.allocate_kernel_region(m_rsdp.page_base(), (PAGE_SIZE * 2), "ACPI Static Parser Initialization", Region::Access::Read, false, true);
|
||||||
volatile auto* rsdp = (ACPI_RAW::RSDPDescriptor20*)rsdp_region->vaddr().offset(offset_in_page((u32)m_rsdp)).as_ptr();
|
volatile auto* rsdp = (ACPI_RAW::RSDPDescriptor20*)rsdp_region->vaddr().offset(m_rsdp.offset_in_page().get()).as_ptr();
|
||||||
if (rsdp->base.revision == 0) {
|
if (rsdp->base.revision == 0) {
|
||||||
m_xsdt_supported = false;
|
m_xsdt_supported = false;
|
||||||
} else if (rsdp->base.revision >= 2) {
|
} else if (rsdp->base.revision >= 2) {
|
||||||
|
@ -226,9 +220,9 @@ void ACPIStaticParser::locate_main_system_description_table()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!m_xsdt_supported) {
|
if (!m_xsdt_supported) {
|
||||||
m_main_system_description_table = (ACPI_RAW::SDTHeader*)rsdp->base.rsdt_ptr;
|
m_main_system_description_table = PhysicalAddress(rsdp->base.rsdt_ptr);
|
||||||
} else {
|
} else {
|
||||||
m_main_system_description_table = (ACPI_RAW::SDTHeader*)rsdp->xsdt_ptr;
|
m_main_system_description_table = PhysicalAddress(rsdp->xsdt_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,12 +248,11 @@ void ACPIStaticParser::locate_all_aml_tables()
|
||||||
|
|
||||||
ACPIStaticParser::ACPIStaticParser()
|
ACPIStaticParser::ACPIStaticParser()
|
||||||
: ACPIParser(true)
|
: ACPIParser(true)
|
||||||
, m_rsdp(nullptr)
|
, m_rsdp(search_rsdp())
|
||||||
, m_main_sdt(nullptr)
|
, m_main_sdt(nullptr)
|
||||||
, m_fadt(nullptr)
|
, m_fadt(nullptr)
|
||||||
{
|
{
|
||||||
m_rsdp = search_rsdp();
|
if (!m_rsdp.is_null()) {
|
||||||
if (m_rsdp != nullptr) {
|
|
||||||
kprintf("ACPI: Using RSDP @ P 0x%x\n", m_rsdp);
|
kprintf("ACPI: Using RSDP @ P 0x%x\n", m_rsdp);
|
||||||
m_operable = true;
|
m_operable = true;
|
||||||
locate_static_data();
|
locate_static_data();
|
||||||
|
@ -269,7 +262,7 @@ ACPIStaticParser::ACPIStaticParser()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ACPI_RAW::RSDPDescriptor20* ACPIStaticParser::search_rsdp_in_ebda(u16 ebda_segment)
|
PhysicalAddress ACPIStaticParser::search_rsdp_in_ebda(u16 ebda_segment)
|
||||||
{
|
{
|
||||||
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);
|
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());
|
char* p_rsdp_str = (char*)(PhysicalAddress(ebda_segment << 4).as_ptr());
|
||||||
|
@ -278,13 +271,13 @@ ACPI_RAW::RSDPDescriptor20* ACPIStaticParser::search_rsdp_in_ebda(u16 ebda_segme
|
||||||
dbgprintf("ACPI: Looking for RSDP in EBDA @ V0x%x, P0x%x\n", rsdp_str, p_rsdp_str);
|
dbgprintf("ACPI: Looking for RSDP in EBDA @ V0x%x, P0x%x\n", rsdp_str, p_rsdp_str);
|
||||||
#endif
|
#endif
|
||||||
if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR ")))
|
if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR ")))
|
||||||
return (ACPI_RAW::RSDPDescriptor20*)p_rsdp_str;
|
return PhysicalAddress((uintptr_t)p_rsdp_str);
|
||||||
p_rsdp_str += 16;
|
p_rsdp_str += 16;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ACPI_RAW::RSDPDescriptor20* ACPIStaticParser::search_rsdp_in_bios_area()
|
PhysicalAddress ACPIStaticParser::search_rsdp_in_bios_area()
|
||||||
{
|
{
|
||||||
auto rsdp_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)0xE0000)), PAGE_ROUND_UP(0xFFFFF - 0xE0000), "ACPI Static Parser RSDP Finding #2", Region::Access::Read, false, true);
|
auto rsdp_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)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());
|
char* p_rsdp_str = (char*)(PhysicalAddress(0xE0000).as_ptr());
|
||||||
|
@ -293,32 +286,32 @@ ACPI_RAW::RSDPDescriptor20* ACPIStaticParser::search_rsdp_in_bios_area()
|
||||||
dbgprintf("ACPI: Looking for RSDP in BIOS area @ V0x%x, P0x%x\n", rsdp_str, p_rsdp_str);
|
dbgprintf("ACPI: Looking for RSDP in BIOS area @ V0x%x, P0x%x\n", rsdp_str, p_rsdp_str);
|
||||||
#endif
|
#endif
|
||||||
if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR ")))
|
if (!strncmp("RSD PTR ", rsdp_str, strlen("RSD PTR ")))
|
||||||
return (ACPI_RAW::RSDPDescriptor20*)p_rsdp_str;
|
return PhysicalAddress((uintptr_t)p_rsdp_str);
|
||||||
p_rsdp_str += 16;
|
p_rsdp_str += 16;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ACPI_RAW::RSDPDescriptor20* ACPIStaticParser::search_rsdp()
|
PhysicalAddress ACPIStaticParser::search_rsdp()
|
||||||
{
|
{
|
||||||
ACPI_RAW::RSDPDescriptor20* rsdp = nullptr;
|
PhysicalAddress rsdp;
|
||||||
auto region = MM.allocate_kernel_region(PhysicalAddress(0), PAGE_SIZE, "ACPI Static Parser RSDP Finding", Region::Access::Read);
|
auto region = MM.allocate_kernel_region(PhysicalAddress(0), PAGE_SIZE, "ACPI Static Parser RSDP Finding", Region::Access::Read);
|
||||||
u16 ebda_seg = (u16) * ((uint16_t*)((region->vaddr().get() & PAGE_MASK) + 0x40e));
|
u16 ebda_seg = (u16) * ((uint16_t*)((region->vaddr().get() & PAGE_MASK) + 0x40e));
|
||||||
kprintf("ACPI: Probing EBDA, Segment 0x%x\n", ebda_seg);
|
kprintf("ACPI: Probing EBDA, Segment 0x%x\n", ebda_seg);
|
||||||
|
|
||||||
rsdp = search_rsdp_in_ebda(ebda_seg);
|
rsdp = search_rsdp_in_ebda(ebda_seg);
|
||||||
if (rsdp != nullptr)
|
if (!rsdp.is_null())
|
||||||
return rsdp;
|
return rsdp;
|
||||||
return search_rsdp_in_bios_area();
|
return search_rsdp_in_bios_area();
|
||||||
}
|
}
|
||||||
|
|
||||||
ACPIStaticParser::ACPIStaticParser(ACPI_RAW::RSDPDescriptor20& rsdp)
|
ACPIStaticParser::ACPIStaticParser(PhysicalAddress rsdp)
|
||||||
: ACPIParser(true)
|
: ACPIParser(true)
|
||||||
, m_rsdp(&rsdp)
|
, m_rsdp(rsdp)
|
||||||
, m_main_sdt(nullptr)
|
, m_main_sdt(nullptr)
|
||||||
, m_fadt(nullptr)
|
, m_fadt(nullptr)
|
||||||
{
|
{
|
||||||
kprintf("ACPI: Using RSDP @ Px%x\n", &rsdp);
|
kprintf("ACPI: Using RSDP @ Px%x\n", rsdp.get());
|
||||||
m_operable = true;
|
m_operable = true;
|
||||||
locate_static_data();
|
locate_static_data();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,34 +33,33 @@ namespace Kernel {
|
||||||
|
|
||||||
class ACPIStaticParser : ACPIParser {
|
class ACPIStaticParser : ACPIParser {
|
||||||
public:
|
public:
|
||||||
static void initialize(ACPI_RAW::RSDPDescriptor20& rsdp);
|
static void initialize(PhysicalAddress rsdp);
|
||||||
static void initialize_without_rsdp();
|
static void initialize_without_rsdp();
|
||||||
static bool is_initialized();
|
static bool is_initialized();
|
||||||
|
|
||||||
virtual ACPI_RAW::SDTHeader* find_table(const char* sig) override;
|
virtual PhysicalAddress find_table(const char* sig) override;
|
||||||
virtual void do_acpi_reboot() override;
|
virtual void do_acpi_reboot() override;
|
||||||
virtual void do_acpi_shutdown() override;
|
virtual void do_acpi_shutdown() override;
|
||||||
virtual bool is_operable() override { return m_operable; }
|
virtual bool is_operable() override { return m_operable; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ACPIStaticParser();
|
ACPIStaticParser();
|
||||||
explicit ACPIStaticParser(ACPI_RAW::RSDPDescriptor20&);
|
explicit ACPIStaticParser(PhysicalAddress);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void locate_static_data();
|
void locate_static_data();
|
||||||
void locate_all_aml_tables();
|
void locate_all_aml_tables();
|
||||||
void locate_main_system_description_table();
|
void locate_main_system_description_table();
|
||||||
void initialize_main_system_description_table();
|
void initialize_main_system_description_table();
|
||||||
size_t get_table_size(ACPI_RAW::SDTHeader&);
|
size_t get_table_size(PhysicalAddress);
|
||||||
u8 get_table_revision(ACPI_RAW::SDTHeader&);
|
u8 get_table_revision(PhysicalAddress);
|
||||||
void init_fadt();
|
void init_fadt();
|
||||||
ACPI_RAW::RSDPDescriptor20* search_rsdp_in_ebda(u16 ebda_segment);
|
PhysicalAddress search_rsdp_in_ebda(u16 ebda_segment);
|
||||||
ACPI_RAW::RSDPDescriptor20* search_rsdp_in_bios_area();
|
PhysicalAddress search_rsdp_in_bios_area();
|
||||||
ACPI_RAW::RSDPDescriptor20* search_rsdp();
|
PhysicalAddress search_rsdp();
|
||||||
|
|
||||||
// Early pointers that are needed really for initializtion only...
|
PhysicalAddress m_rsdp;
|
||||||
ACPI_RAW::RSDPDescriptor20* m_rsdp;
|
PhysicalAddress m_main_system_description_table;
|
||||||
ACPI_RAW::SDTHeader* m_main_system_description_table;
|
|
||||||
|
|
||||||
OwnPtr<ACPI::MainSystemDescriptionTable> m_main_sdt;
|
OwnPtr<ACPI::MainSystemDescriptionTable> m_main_sdt;
|
||||||
OwnPtr<ACPI::FixedACPIData> m_fadt;
|
OwnPtr<ACPI::FixedACPIData> m_fadt;
|
||||||
|
|
|
@ -116,18 +116,18 @@ void InterruptManagement::switch_to_ioapic_mode()
|
||||||
kprintf("Interrupts: Switch to IOAPIC mode failed, Reverting to PIC mode\n");
|
kprintf("Interrupts: Switch to IOAPIC mode failed, Reverting to PIC mode\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvancedInterruptManagement::initialize(ACPI_RAW::MADT& p_madt)
|
void AdvancedInterruptManagement::initialize(PhysicalAddress p_madt)
|
||||||
{
|
{
|
||||||
ASSERT(!InterruptManagement::initialized());
|
ASSERT(!InterruptManagement::initialized());
|
||||||
s_interrupt_management = new AdvancedInterruptManagement(p_madt);
|
s_interrupt_management = new AdvancedInterruptManagement(p_madt);
|
||||||
}
|
}
|
||||||
|
|
||||||
AdvancedInterruptManagement::AdvancedInterruptManagement(ACPI_RAW::MADT& p_madt)
|
AdvancedInterruptManagement::AdvancedInterruptManagement(PhysicalAddress p_madt)
|
||||||
: InterruptManagement(false)
|
: InterruptManagement(false)
|
||||||
, m_madt(p_madt)
|
, m_madt(p_madt)
|
||||||
{
|
{
|
||||||
// FIXME: Check what is the actual data size then map accordingly
|
// FIXME: Check what is the actual data size then map accordingly
|
||||||
dbg() << "Interrupts: MADT @ P " << &p_madt;
|
dbg() << "Interrupts: MADT @ P " << p_madt.as_ptr();
|
||||||
locate_isa_interrupt_overrides(p_madt);
|
locate_isa_interrupt_overrides(p_madt);
|
||||||
locate_ioapics(p_madt);
|
locate_ioapics(p_madt);
|
||||||
}
|
}
|
||||||
|
@ -166,10 +166,10 @@ void AdvancedInterruptManagement::switch_to_ioapic_mode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvancedInterruptManagement::locate_ioapics(ACPI_RAW::MADT& p_madt)
|
void AdvancedInterruptManagement::locate_ioapics(PhysicalAddress p_madt)
|
||||||
{
|
{
|
||||||
auto region = MM.allocate_kernel_region(PhysicalAddress(page_base_of(&p_madt)), (PAGE_SIZE * 2), "Initializing Interrupts", Region::Access::Read);
|
auto region = MM.allocate_kernel_region(p_madt.page_base(), (PAGE_SIZE * 2), "Initializing Interrupts", Region::Access::Read);
|
||||||
auto& madt = *(const ACPI_RAW::MADT*)region->vaddr().offset(offset_in_page(&p_madt)).as_ptr();
|
auto& madt = *(const ACPI_RAW::MADT*)region->vaddr().offset(p_madt.offset_in_page().get()).as_ptr();
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (madt.flags & PCAT_COMPAT_FLAG) {
|
if (madt.flags & PCAT_COMPAT_FLAG) {
|
||||||
|
@ -200,10 +200,10 @@ void AdvancedInterruptManagement::locate_pci_interrupt_overrides()
|
||||||
m_pci_interrupt_overrides = MultiProcessorParser::the().get_pci_interrupt_redirections();
|
m_pci_interrupt_overrides = MultiProcessorParser::the().get_pci_interrupt_redirections();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdvancedInterruptManagement::locate_isa_interrupt_overrides(ACPI_RAW::MADT& p_madt)
|
void AdvancedInterruptManagement::locate_isa_interrupt_overrides(PhysicalAddress p_madt)
|
||||||
{
|
{
|
||||||
auto region = MM.allocate_kernel_region(PhysicalAddress(page_base_of(&p_madt)), (PAGE_SIZE * 2), "Initializing Interrupts", Region::Access::Read);
|
auto region = MM.allocate_kernel_region(p_madt.page_base(), (PAGE_SIZE * 2), "Initializing Interrupts", Region::Access::Read);
|
||||||
auto& madt = *(const ACPI_RAW::MADT*)region->vaddr().offset(offset_in_page(&p_madt)).as_ptr();
|
auto& madt = *(const ACPI_RAW::MADT*)region->vaddr().offset(p_madt.offset_in_page().get()).as_ptr();
|
||||||
|
|
||||||
size_t entry_index = 0;
|
size_t entry_index = 0;
|
||||||
size_t entries_length = madt.h.length - sizeof(ACPI_RAW::MADT);
|
size_t entries_length = madt.h.length - sizeof(ACPI_RAW::MADT);
|
||||||
|
|
|
@ -65,18 +65,18 @@ class AdvancedInterruptManagement : public InterruptManagement {
|
||||||
friend class IOAPIC;
|
friend class IOAPIC;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void initialize(ACPI_RAW::MADT& madt);
|
static void initialize(PhysicalAddress madt);
|
||||||
virtual void switch_to_ioapic_mode() override;
|
virtual void switch_to_ioapic_mode() override;
|
||||||
virtual void switch_to_pic_mode() override;
|
virtual void switch_to_pic_mode() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit AdvancedInterruptManagement(ACPI_RAW::MADT& madt);
|
explicit AdvancedInterruptManagement(PhysicalAddress madt);
|
||||||
void locate_ioapics(ACPI_RAW::MADT& madt);
|
void locate_ioapics(PhysicalAddress madt);
|
||||||
void locate_isa_interrupt_overrides(ACPI_RAW::MADT& madt);
|
void locate_isa_interrupt_overrides(PhysicalAddress madt);
|
||||||
void locate_pci_interrupt_overrides();
|
void locate_pci_interrupt_overrides();
|
||||||
Vector<RefPtr<ISAInterruptOverrideMetadata>> m_isa_interrupt_overrides;
|
Vector<RefPtr<ISAInterruptOverrideMetadata>> m_isa_interrupt_overrides;
|
||||||
Vector<RefPtr<PCIInterruptOverrideMetadata>> m_pci_interrupt_overrides;
|
Vector<RefPtr<PCIInterruptOverrideMetadata>> m_pci_interrupt_overrides;
|
||||||
ACPI_RAW::MADT& m_madt;
|
PhysicalAddress m_madt;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ISAInterruptOverrideMetadata : public RefCounted<ISAInterruptOverrideMetadata> {
|
class ISAInterruptOverrideMetadata : public RefCounted<ISAInterruptOverrideMetadata> {
|
||||||
|
|
|
@ -44,7 +44,7 @@ PCI::Initializer& PCI::Initializer::the()
|
||||||
}
|
}
|
||||||
return *s_pci_initializer;
|
return *s_pci_initializer;
|
||||||
}
|
}
|
||||||
void PCI::Initializer::initialize_pci_mmio_access(ACPI_RAW::MCFG& mcfg)
|
void PCI::Initializer::initialize_pci_mmio_access(PhysicalAddress mcfg)
|
||||||
{
|
{
|
||||||
PCI::MMIOAccess::initialize(mcfg);
|
PCI::MMIOAccess::initialize(mcfg);
|
||||||
detect_devices();
|
detect_devices();
|
||||||
|
@ -129,15 +129,12 @@ bool PCI::Initializer::test_pci_io()
|
||||||
|
|
||||||
bool PCI::Initializer::test_pci_mmio()
|
bool PCI::Initializer::test_pci_mmio()
|
||||||
{
|
{
|
||||||
if (ACPIParser::the().find_table("MCFG") != nullptr)
|
return !ACPIParser::the().find_table("MCFG").is_null();
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCI::Initializer::initialize_pci_mmio_access_after_test()
|
void PCI::Initializer::initialize_pci_mmio_access_after_test()
|
||||||
{
|
{
|
||||||
initialize_pci_mmio_access(*(ACPI_RAW::MCFG*)(ACPIParser::the().find_table("MCFG")));
|
initialize_pci_mmio_access(ACPIParser::the().find_table("MCFG"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCI::Initializer::dismiss()
|
void PCI::Initializer::dismiss()
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace Kernel {
|
||||||
class PCI::Initializer {
|
class PCI::Initializer {
|
||||||
public:
|
public:
|
||||||
static PCI::Initializer& the();
|
static PCI::Initializer& the();
|
||||||
void initialize_pci_mmio_access(ACPI_RAW::MCFG& mcfg);
|
void initialize_pci_mmio_access(PhysicalAddress mcfg);
|
||||||
void initialize_pci_io_access();
|
void initialize_pci_io_access();
|
||||||
void test_and_initialize(bool disable_pci_mmio);
|
void test_and_initialize(bool disable_pci_mmio);
|
||||||
static void dismiss();
|
static void dismiss();
|
||||||
|
|
|
@ -47,35 +47,35 @@ uint8_t PCI::MMIOAccess::get_segment_end_bus(u32 seg)
|
||||||
return m_segments.get(seg).value()->get_end_bus();
|
return m_segments.get(seg).value()->get_end_bus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCI::MMIOAccess::initialize(ACPI_RAW::MCFG& mcfg)
|
void PCI::MMIOAccess::initialize(PhysicalAddress mcfg)
|
||||||
{
|
{
|
||||||
if (!PCI::Access::is_initialized())
|
if (!PCI::Access::is_initialized())
|
||||||
new PCI::MMIOAccess(mcfg);
|
new PCI::MMIOAccess(mcfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
PCI::MMIOAccess::MMIOAccess(ACPI_RAW::MCFG& raw_mcfg)
|
PCI::MMIOAccess::MMIOAccess(PhysicalAddress p_mcfg)
|
||||||
: m_mcfg(raw_mcfg)
|
: m_mcfg(p_mcfg)
|
||||||
, m_segments(*new HashMap<u16, MMIOSegment*>())
|
, m_segments(*new HashMap<u16, MMIOSegment*>())
|
||||||
, m_mapped_address(ChangeableAddress(0xFFFF, 0xFF, 0xFF, 0xFF))
|
, m_mapped_address(ChangeableAddress(0xFFFF, 0xFF, 0xFF, 0xFF))
|
||||||
{
|
{
|
||||||
kprintf("PCI: Using MMIO Mechanism for PCI Configuartion Space Access\n");
|
kprintf("PCI: Using MMIO Mechanism for PCI Configuartion Space Access\n");
|
||||||
m_mmio_window_region = MM.allocate_kernel_region(PAGE_ROUND_UP(PCI_MMIO_CONFIG_SPACE_SIZE), "PCI MMIO", Region::Access::Read | Region::Access::Write);
|
m_mmio_window_region = MM.allocate_kernel_region(PAGE_ROUND_UP(PCI_MMIO_CONFIG_SPACE_SIZE), "PCI MMIO", Region::Access::Read | Region::Access::Write);
|
||||||
|
|
||||||
auto checkup_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)&raw_mcfg)), (PAGE_SIZE * 2), "PCI MCFG Checkup", Region::Access::Read | Region::Access::Write);
|
auto checkup_region = MM.allocate_kernel_region(p_mcfg.page_base(), (PAGE_SIZE * 2), "PCI MCFG Checkup", Region::Access::Read | Region::Access::Write);
|
||||||
#ifdef PCI_DEBUG
|
#ifdef PCI_DEBUG
|
||||||
dbgprintf("PCI: Checking MCFG Table length to choose the correct mapping size\n");
|
dbgprintf("PCI: Checking MCFG Table length to choose the correct mapping size\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ACPI_RAW::SDTHeader* sdt = (ACPI_RAW::SDTHeader*)checkup_region->vaddr().offset(offset_in_page((u32)&raw_mcfg)).as_ptr();
|
ACPI_RAW::SDTHeader* sdt = (ACPI_RAW::SDTHeader*)checkup_region->vaddr().offset(p_mcfg.offset_in_page().get()).as_ptr();
|
||||||
u32 length = sdt->length;
|
u32 length = sdt->length;
|
||||||
u8 revision = sdt->revision;
|
u8 revision = sdt->revision;
|
||||||
|
|
||||||
kprintf("PCI: MCFG, length - %u, revision %d\n", length, revision);
|
kprintf("PCI: MCFG, length - %u, revision %d\n", length, revision);
|
||||||
checkup_region->unmap();
|
checkup_region->unmap();
|
||||||
|
|
||||||
auto mcfg_region = MM.allocate_kernel_region(PhysicalAddress(page_base_of((u32)&raw_mcfg)), PAGE_ROUND_UP(length) + PAGE_SIZE, "PCI Parsing MCFG", Region::Access::Read | Region::Access::Write);
|
auto mcfg_region = MM.allocate_kernel_region(p_mcfg.page_base(), PAGE_ROUND_UP(length) + PAGE_SIZE, "PCI Parsing MCFG", Region::Access::Read | Region::Access::Write);
|
||||||
|
|
||||||
auto& mcfg = *(ACPI_RAW::MCFG*)mcfg_region->vaddr().offset(offset_in_page((u32)&raw_mcfg)).as_ptr();
|
auto& mcfg = *(ACPI_RAW::MCFG*)mcfg_region->vaddr().offset(p_mcfg.offset_in_page().get()).as_ptr();
|
||||||
#ifdef PCI_DEBUG
|
#ifdef PCI_DEBUG
|
||||||
dbgprintf("PCI: Checking MCFG @ V 0x%x, P 0x%x\n", &mcfg, &raw_mcfg);
|
dbgprintf("PCI: Checking MCFG @ V 0x%x, P 0x%x\n", &mcfg, &raw_mcfg);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,14 +39,14 @@ namespace Kernel {
|
||||||
|
|
||||||
class PCI::MMIOAccess final : public PCI::Access {
|
class PCI::MMIOAccess final : public PCI::Access {
|
||||||
public:
|
public:
|
||||||
static void initialize(ACPI_RAW::MCFG&);
|
static void initialize(PhysicalAddress mcfg);
|
||||||
virtual void enumerate_all(Function<void(Address, ID)>&) override final;
|
virtual void enumerate_all(Function<void(Address, ID)>&) override final;
|
||||||
|
|
||||||
virtual String get_access_type() override final { return "MMIO-Access"; };
|
virtual String get_access_type() override final { return "MMIO-Access"; };
|
||||||
virtual u32 get_segments_count();
|
virtual u32 get_segments_count();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit MMIOAccess(ACPI_RAW::MCFG&);
|
explicit MMIOAccess(PhysicalAddress mcfg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual u8 read8_field(Address address, u32) override final;
|
virtual u8 read8_field(Address address, u32) override final;
|
||||||
|
@ -60,7 +60,7 @@ private:
|
||||||
virtual u8 get_segment_start_bus(u32);
|
virtual u8 get_segment_start_bus(u32);
|
||||||
virtual u8 get_segment_end_bus(u32);
|
virtual u8 get_segment_end_bus(u32);
|
||||||
|
|
||||||
ACPI_RAW::MCFG& m_mcfg;
|
PhysicalAddress m_mcfg;
|
||||||
HashMap<u16, MMIOSegment*>& m_segments;
|
HashMap<u16, MMIOSegment*>& m_segments;
|
||||||
OwnPtr<Region> m_mmio_window_region;
|
OwnPtr<Region> m_mmio_window_region;
|
||||||
PCI::ChangeableAddress m_mapped_address;
|
PCI::ChangeableAddress m_mapped_address;
|
||||||
|
|
|
@ -146,7 +146,7 @@ extern "C" [[noreturn]] void init()
|
||||||
VirtualConsole::switch_to(0);
|
VirtualConsole::switch_to(0);
|
||||||
|
|
||||||
// Sample test to see if the ACPI parser is working...
|
// Sample test to see if the ACPI parser is working...
|
||||||
kprintf("ACPI: HPET table @ P 0x%x\n", ACPIParser::the().find_table("HPET"));
|
kprintf("ACPI: HPET table @ P 0x%x\n", ACPIParser::the().find_table("HPET").get());
|
||||||
|
|
||||||
setup_pci();
|
setup_pci();
|
||||||
|
|
||||||
|
@ -463,12 +463,12 @@ void setup_pci()
|
||||||
|
|
||||||
static void setup_interrupt_management()
|
static void setup_interrupt_management()
|
||||||
{
|
{
|
||||||
auto* madt = (ACPI_RAW::MADT*)ACPIParser::the().find_table("APIC");
|
auto madt = ACPIParser::the().find_table("APIC");
|
||||||
if (!madt) {
|
if (madt.is_null()) {
|
||||||
InterruptManagement::initialize();
|
InterruptManagement::initialize();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AdvancedInterruptManagement::initialize(*madt);
|
AdvancedInterruptManagement::initialize(madt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_interrupts()
|
void setup_interrupts()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue