i know there high_level irql to disable all interrupts i want to know if its possible to do so on apic
// I’ve discovered that the APIC base address must be mapped to virtual memory to ensure proper access
is this approach correct?
#include <intrin.h>
#include <wdm.h>
#define IA32_APIC_BASE_MSR 0x1B
#define APIC_TPR_OFFSET 0x80
uintptr_t cpu_get_apic_base() {
uint64_t msrValue = __readmsr(IA32_APIC_BASE_MSR);
#ifdef __PHYSICAL_MEMORY_EXTENSION__
return msrValue & 0xFFFFFFFFFFFFF000ULL;
#else
return msrValue & 0xFFFFF000;
#endif
}
uintptr_t map_physical_to_virtual(uint64_t phys_addr, SIZE_T size) {
PHYSICAL_ADDRESS PhysicalAddress;
PhysicalAddress.QuadPart = phys_addr;
return (uintptr_t)MmMapIoSpace(PhysicalAddress, size, MmNonCached);
}
void unmap_virtual_address(void* virt_addr) {
MmUnmapIoSpace(virt_addr, sizeof(uint32_t));
}
static inline uint32_t read_tpr(uintptr_t apicBaseVirt) {
return *((volatile uint32_t*)(apicBaseVirt + APIC_TPR_OFFSET));
}
static inline void write_tpr(uintptr_t apicBaseVirt, uint32_t value) {
*((volatile uint32_t*)(apicBaseVirt + APIC_TPR_OFFSET)) = value;
}
void DisableAndEnableApicInterrupts() {
uint64_t apicBasePhys = cpu_get_apic_base();
uintptr_t apicBaseVirt = map_physical_to_virtual(apicBasePhys, sizeof(uint32_t));
if (!apicBaseVirt) {
DbgPrint("Couldn't map physical memory.\n");
return;
}
uint32_t original_tpr = read_tpr(apicBaseVirt);
// Raise the APIC's task priority to effectively mask off all interrupts
write_tpr(apicBaseVirt, 0xFF);
// ... Your code that needs to run without external interrupts ...
// Restore the original TPR value to re-enable interrupts
write_tpr(apicBaseVirt, original_tpr);
unmap_virtual_address((void*)apicBaseVirt);
}