139 lines
3.9 KiB
C++
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();
|
||
|
}
|