MultiProcessorParser.h 3.5 KB

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