summaryrefslogtreecommitdiff
path: root/Kernel/Firmware/MultiProcessor/Parser.h
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel/Firmware/MultiProcessor/Parser.h')
-rw-r--r--Kernel/Firmware/MultiProcessor/Parser.h171
1 files changed, 171 insertions, 0 deletions
diff --git a/Kernel/Firmware/MultiProcessor/Parser.h b/Kernel/Firmware/MultiProcessor/Parser.h
new file mode 100644
index 0000000000..26094c8ab4
--- /dev/null
+++ b/Kernel/Firmware/MultiProcessor/Parser.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Types.h>
+#include <AK/Vector.h>
+#include <Kernel/Memory/Region.h>
+#include <Kernel/PhysicalAddress.h>
+#include <Kernel/VirtualAddress.h>
+
+namespace Kernel {
+namespace MultiProcessor {
+
+struct [[gnu::packed]] FloatingPointer {
+ char sig[4];
+ u32 physical_address_ptr;
+ u8 length;
+ u8 specification_revision;
+ u8 checksum;
+ u8 feature_info[5];
+};
+
+struct [[gnu::packed]] EntryHeader {
+ u8 entry_type;
+};
+
+struct [[gnu::packed]] ConfigurationTableHeader {
+ char sig[4];
+ u16 length;
+ u8 specification_revision;
+ u8 checksum;
+ char oem_id[8];
+ char product_id[12];
+ u32 oem_table_ptr;
+ u16 oem_table_size;
+ u16 entry_count;
+ u32 local_apic_address;
+ u16 ext_table_length;
+ u8 ext_table_checksum;
+ u8 reserved;
+ EntryHeader entries[];
+};
+
+enum class ConfigurationTableEntryType {
+ Processor = 0,
+ Bus = 1,
+ IOAPIC = 2,
+ IO_Interrupt_Assignment = 3,
+ Local_Interrupt_Assignment = 4,
+ SystemAddressSpaceMapping = 128,
+ BusHierarchyDescriptor = 129,
+ CompatibilityBusAddressSpaceModifier = 130
+};
+
+struct [[gnu::packed]] ExtEntryHeader {
+ u8 entry_type;
+ u8 entry_length;
+};
+
+struct [[gnu::packed]] ProcessorEntry {
+ EntryHeader h;
+ u8 local_apic_id;
+ u8 local_apic_version;
+ u8 cpu_flags;
+ u32 cpu_signature;
+ u32 feature_flags;
+ u8 reserved[8];
+};
+
+struct [[gnu::packed]] BusEntry {
+ EntryHeader h;
+ u8 bus_id;
+ char bus_type[6];
+};
+
+struct [[gnu::packed]] IOAPICEntry {
+ EntryHeader h;
+ u8 ioapic_id;
+ u8 ioapic_version;
+ u8 ioapic_flags;
+ u32 ioapic_address;
+};
+
+enum class InterruptType {
+ INT = 0,
+ NMI = 1,
+ SMI = 2,
+ ExtINT = 3,
+};
+
+struct [[gnu::packed]] IOInterruptAssignmentEntry {
+ EntryHeader h;
+ u8 interrupt_type;
+ u8 polarity;
+ u8 trigger_mode;
+ u8 source_bus_id;
+ u8 source_bus_irq;
+ u8 destination_ioapic_id;
+ u8 destination_ioapic_intin_pin;
+};
+
+struct [[gnu::packed]] LocalInterruptAssignmentEntry {
+ EntryHeader h;
+ u8 interrupt_type;
+ u8 polarity;
+ u8 trigger_mode;
+ u8 source_bus_id;
+ u8 source_bus_irq;
+ u8 destination_lapic_id;
+ u8 destination_lapic_lintin_pin;
+};
+
+enum class SystemAddressType {
+ IO = 0,
+ Memory = 1,
+ Prefetch = 2,
+};
+
+struct [[gnu::packed]] SystemAddressSpaceMappingEntry {
+ ExtEntryHeader h;
+ u8 bus_id;
+ u8 address_type;
+ u64 address_base;
+ u64 length;
+};
+
+struct [[gnu::packed]] BusHierarchyDescriptorEntry {
+ ExtEntryHeader h;
+ u8 bus_id;
+ u8 bus_info;
+ u8 parent_bus;
+ u8 reserved[3];
+};
+
+struct [[gnu::packed]] CompatibilityBusAddressSpaceModifierEntry {
+ ExtEntryHeader h;
+ u8 bus_id;
+ u8 address_modifier;
+ u32 predefined_range_list;
+};
+
+}
+
+class PCIInterruptOverrideMetadata;
+
+class MultiProcessorParser final {
+public:
+ static OwnPtr<MultiProcessorParser> autodetect();
+
+ Vector<PCIInterruptOverrideMetadata> get_pci_interrupt_redirections();
+
+private:
+ explicit MultiProcessorParser(PhysicalAddress floating_pointer);
+
+ void parse_configuration_table();
+ void parse_floating_pointer_data();
+
+ Vector<u8> get_pci_bus_ids() const;
+
+ static Optional<PhysicalAddress> find_floating_pointer();
+
+ PhysicalAddress m_floating_pointer;
+ PhysicalAddress m_configuration_table;
+ Vector<MultiProcessor::IOInterruptAssignmentEntry> m_io_interrupt_assignment_entries;
+ Vector<MultiProcessor::BusEntry> m_bus_entries;
+};
+}