singrdk/base/Windows/singx86/apic.cpp

139 lines
3.9 KiB
C++

/////////////////////////////////////////////////////////////////////////////
//
// apic.cpp - Extension to inspect APIC
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include "singx86.h"
inline static ULONG ApicRead32(const BYTE* apic, int offsetInBytes)
{
return ((ULONG*) apic)[offsetInBytes / sizeof(ULONG)];
}
inline static BYTE ApicRead8(const BYTE* apic, int offsetInBytes)
{
return apic[offsetInBytes];
}
inline static const char* TimerMode(ULONG flag)
{
return (flag == 0) ? "One-shot" : "Periodic";
}
inline static const char* Mask(ULONG flag)
{
return (flag == 0) ? "Unmasked" : "Masked ";
}
inline static const char* TriggerMode(ULONG pmask, ULONG flag)
{
if ((pmask & (1 << 15)) == 0)
return "-----";
return (flag == 0) ? "Edge " : "Level";
}
inline static const char* RemoteIRR(ULONG pmask, ULONG flag)
{
if ((pmask & (1 << 14)) == 0)
return "------";
return (flag == 0) ? "No IRR" : "IRR ";
}
inline static const char* PinPolarity(ULONG pmask, ULONG flag)
{
if ((pmask & (1 << 13)) == 0)
return "---------";
return (flag == 0) ? "Active-Hi" : "Active-Lo";
}
inline static const char* DeliveryStatus(ULONG flag)
{
return (flag == 0) ? "Idle" : "Pend";
}
inline static const char* DeliveryMode(ULONG pmask, ULONG value)
{
if ((pmask & 0x700) == 0)
return "---";
const char * dm[8] = {
"Fix", "Res", "SMI", "Res", "NMI", "INI", "Res", "Ext"
};
value = (value & 0x700u) >> 8;
return dm[value];
}
static void DumpTimer(ULONG t)
{
ExtOut("Timer: %08x => Vector %02x ", t & 0x310ff, t & 0xff);
ExtOut("%s %s %s\n", Mask(t & 0x10000), TimerMode(t & 0x20000),
DeliveryStatus(t & 0x1000));
}
static void DumpLvt(const char* name, ULONG pmask, ULONG value)
{
ExtOut("%s: %08x => Vector %02x ", name, value & pmask, value & 0xff);
ExtOut("%s %s %s %s %s %s\n",
Mask(value), TriggerMode(pmask, value),
RemoteIRR(pmask, value), PinPolarity(pmask, value),
DeliveryStatus(value), DeliveryMode(pmask, value));
}
static void DumpBits(const char* name, const BYTE* apic, int startOffset)
{
ExtOut("%s: ", name);
for (int w = 0; w < 8; w++)
{
ULONG bits = ApicRead32(apic, startOffset + w * 16);
for (int i = 0; i < 32; i++)
{
if ((bits & (1 << i)) != 0)
{
ExtOut("0x%02x ", w * 32 + i);
}
}
}
ExtOut("\n");
}
EXT_DECL(apic) // Defines: PDEBUG_CLIENT Client, PCSTR args
{
EXT_ENTER(); // Defines: HRESULT status = S_OK;
UNREFERENCED_PARAMETER(args);
static const ULONG64 ApicBase = 0x00000000fee00000;
BYTE apic[0x400];
EXT_CHECK(g_ExtData->ReadPhysical(ApicBase, &apic, sizeof(apic), NULL));
int maxLvt = ApicRead8(apic, 0x32);
ExtOut("Apic Id %u Version %02x Max LVT %u\n",
ApicRead8(apic, 0x23), ApicRead8(apic, 0x30), maxLvt);
ExtOut("TPR %08x APR %08x PPR %08x\n",
ApicRead32(apic, 0x80), ApicRead32(apic, 0x90),
ApicRead32(apic, 0xa0));
ExtOut("Logical Destination %08x Destination Format %08x\n",
ApicRead32(apic, 0xd0), ApicRead32(apic, 0xe0));
ExtOut("Spurious Interrupt Vector %08x\n", ApicRead32(apic, 0xf0));
ExtOut("Fault Status %02x\n", ApicRead8(apic, 0x280));
DumpTimer(ApicRead32(apic, 0x320));
DumpLvt("LINT0", 0x1f7ff, ApicRead32(apic, 0x350));
DumpLvt("LINT1", 0x1f7ff, ApicRead32(apic, 0x360));
DumpLvt("Fault", 0x110ff, ApicRead32(apic, 0x370));
if (maxLvt >= 4)
DumpLvt("Perf ", 0x117ff, ApicRead32(apic, 0x340));
if (maxLvt >= 5)
DumpLvt("Therm", 0x117ff, ApicRead32(apic, 0x343));
DumpBits("ISR", apic, 0x100);
DumpBits("IRR", apic, 0x200);
DumpBits("TMR", apic, 0x180);
EXT_LEAVE();
}