24#include "pedigree/kernel/LockGuard.h"
25#include "pedigree/kernel/processor/PhysicalMemoryManager.h"
26#include "pedigree/kernel/processor/VirtualAddressSpace.h"
33constexpr uint32_t RedirectionStatus = (1U << 12) | (1U << 14);
36IoApic::IoApic() : m_IoSpace(
"I/O APIC"), m_Lock(false), m_GsiBase(0), m_Count(0) {}
40bool IoApic::initialise(physical_uintptr_t address, uint32_t gsiBase) {
53 m_IoSpace.write32(1, 0);
54 const uint32_t version = m_IoSpace.read32(0x10);
55 const uint32_t count = ((version >> 16) & 0xff) + 1;
56 if (count > UINT32_MAX - gsiBase) {
64bool IoApic::contains(uint32_t gsi)
const {
65 return m_Count && gsi >= m_GsiBase && gsi - m_GsiBase < m_Count;
68bool IoApic::route(uint32_t gsi, uint8_t vector, uint8_t destination,
bool activeLow) {
69 if (!contains(gsi) || vector < 0x20) {
72 const uint32_t registerNumber = 0x10 + 2 * (gsi - m_GsiBase);
73 const uint32_t low = vector | (1U << 15) | (1U << 16) | (activeLow ? 1U << 13 : 0);
74 const uint32_t high = uint32_t(destination) << 24;
76 m_IoSpace.write32(registerNumber, 0);
77 const uint32_t current = m_IoSpace.read32(0x10);
78 m_IoSpace.write32(current | (1U << 16), 0x10);
79 m_IoSpace.write32(registerNumber + 1, 0);
80 m_IoSpace.write32(high, 0x10);
81 const bool highWritten = m_IoSpace.read32(0x10) == high;
82 m_IoSpace.write32(registerNumber, 0);
83 m_IoSpace.write32(low, 0x10);
84 return highWritten && (m_IoSpace.read32(0x10) & ~RedirectionStatus) == low;
87bool IoApic::mask(uint32_t gsi,
bool masked) {
91 const uint32_t registerNumber = 0x10 + 2 * (gsi - m_GsiBase);
93 m_IoSpace.write32(registerNumber, 0);
94 uint32_t low = m_IoSpace.read32(0x10);
95 low = masked ? low | (1U << 16) : low & ~(1U << 16);
96 m_IoSpace.write32(low, 0x10);
97 return (m_IoSpace.read32(0x10) & ~RedirectionStatus) == (low & ~RedirectionStatus);
static const size_t continuous
static PhysicalMemoryManager & instance()
static constexpr size_t getPageSize() PURE
static const size_t force
static const size_t nonRamMemory
static const size_t CacheDisable
static const size_t KernelMode
static const size_t Write