Serenity Operating System
at master 171 lines 3.6 kB view raw
1/* 2 * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/Types.h> 10#include <AK/Vector.h> 11#include <Kernel/Memory/Region.h> 12#include <Kernel/PhysicalAddress.h> 13#include <Kernel/VirtualAddress.h> 14 15namespace Kernel { 16namespace MultiProcessor { 17 18struct [[gnu::packed]] FloatingPointer { 19 char sig[4]; 20 u32 physical_address_ptr; 21 u8 length; 22 u8 specification_revision; 23 u8 checksum; 24 u8 feature_info[5]; 25}; 26 27struct [[gnu::packed]] EntryHeader { 28 u8 entry_type; 29}; 30 31struct [[gnu::packed]] ConfigurationTableHeader { 32 char sig[4]; 33 u16 length; 34 u8 specification_revision; 35 u8 checksum; 36 char oem_id[8]; 37 char product_id[12]; 38 u32 oem_table_ptr; 39 u16 oem_table_size; 40 u16 entry_count; 41 u32 local_apic_address; 42 u16 ext_table_length; 43 u8 ext_table_checksum; 44 u8 reserved; 45 EntryHeader entries[]; 46}; 47 48enum class ConfigurationTableEntryType { 49 Processor = 0, 50 Bus = 1, 51 IOAPIC = 2, 52 IO_Interrupt_Assignment = 3, 53 Local_Interrupt_Assignment = 4, 54 SystemAddressSpaceMapping = 128, 55 BusHierarchyDescriptor = 129, 56 CompatibilityBusAddressSpaceModifier = 130 57}; 58 59struct [[gnu::packed]] ExtEntryHeader { 60 u8 entry_type; 61 u8 entry_length; 62}; 63 64struct [[gnu::packed]] ProcessorEntry { 65 EntryHeader h; 66 u8 local_apic_id; 67 u8 local_apic_version; 68 u8 cpu_flags; 69 u32 cpu_signature; 70 u32 feature_flags; 71 u8 reserved[8]; 72}; 73 74struct [[gnu::packed]] BusEntry { 75 EntryHeader h; 76 u8 bus_id; 77 char bus_type[6]; 78}; 79 80struct [[gnu::packed]] IOAPICEntry { 81 EntryHeader h; 82 u8 ioapic_id; 83 u8 ioapic_version; 84 u8 ioapic_flags; 85 u32 ioapic_address; 86}; 87 88enum class InterruptType { 89 INT = 0, 90 NMI = 1, 91 SMI = 2, 92 ExtINT = 3, 93}; 94 95struct [[gnu::packed]] IOInterruptAssignmentEntry { 96 EntryHeader h; 97 u8 interrupt_type; 98 u8 polarity; 99 u8 trigger_mode; 100 u8 source_bus_id; 101 u8 source_bus_irq; 102 u8 destination_ioapic_id; 103 u8 destination_ioapic_intin_pin; 104}; 105 106struct [[gnu::packed]] LocalInterruptAssignmentEntry { 107 EntryHeader h; 108 u8 interrupt_type; 109 u8 polarity; 110 u8 trigger_mode; 111 u8 source_bus_id; 112 u8 source_bus_irq; 113 u8 destination_lapic_id; 114 u8 destination_lapic_lintin_pin; 115}; 116 117enum class SystemAddressType { 118 IO = 0, 119 Memory = 1, 120 Prefetch = 2, 121}; 122 123struct [[gnu::packed]] SystemAddressSpaceMappingEntry { 124 ExtEntryHeader h; 125 u8 bus_id; 126 u8 address_type; 127 u64 address_base; 128 u64 length; 129}; 130 131struct [[gnu::packed]] BusHierarchyDescriptorEntry { 132 ExtEntryHeader h; 133 u8 bus_id; 134 u8 bus_info; 135 u8 parent_bus; 136 u8 reserved[3]; 137}; 138 139struct [[gnu::packed]] CompatibilityBusAddressSpaceModifierEntry { 140 ExtEntryHeader h; 141 u8 bus_id; 142 u8 address_modifier; 143 u32 predefined_range_list; 144}; 145 146} 147 148class PCIInterruptOverrideMetadata; 149 150class MultiProcessorParser final { 151public: 152 static OwnPtr<MultiProcessorParser> autodetect(); 153 154 Vector<PCIInterruptOverrideMetadata> get_pci_interrupt_redirections(); 155 156private: 157 explicit MultiProcessorParser(PhysicalAddress floating_pointer); 158 159 void parse_configuration_table(); 160 void parse_floating_pointer_data(); 161 162 Vector<u8> get_pci_bus_ids() const; 163 164 static Optional<PhysicalAddress> find_floating_pointer(); 165 166 PhysicalAddress m_floating_pointer; 167 PhysicalAddress m_configuration_table; 168 Vector<MultiProcessor::IOInterruptAssignmentEntry> m_io_interrupt_assignment_entries; 169 Vector<MultiProcessor::BusEntry> m_bus_entries; 170}; 171}