Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

352 lines
7.5 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
apic.c
Abstract:
WinDbg Extension Api
Author:
Ken Reneris (kenr) 06-June-1994
Environment:
User Mode.
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#define LU_SIZE 0x400
#define LU_ID_REGISTER 0x00000020
#define LU_VERS_REGISTER 0x00000030
#define LU_TPR 0x00000080
#define LU_APR 0x00000090
#define LU_PPR 0x000000A0
#define LU_EOI 0x000000B0
#define LU_REMOTE_REGISTER 0x000000C0
#define LU_DEST 0x000000D0
#define LU_DEST_FORMAT 0x000000E0
#define LU_SPURIOUS_VECTOR 0x000000F0
#define LU_FAULT_VECTOR 0x00000370
#define LU_ISR_0 0x00000100
#define LU_TMR_0 0x00000180
#define LU_IRR_0 0x00000200
#define LU_ERROR_STATUS 0x00000280
#define LU_INT_CMD_LOW 0x00000300
#define LU_INT_CMD_HIGH 0x00000310
#define LU_TIMER_VECTOR 0x00000320
#define LU_INT_VECTOR_0 0x00000350
#define LU_INT_VECTOR_1 0x00000360
#define LU_INITIAL_COUNT 0x00000380
#define LU_CURRENT_COUNT 0x00000390
#define LU_DIVIDER_CONFIG 0x000003E0
#define IO_REGISTER_SELECT 0x00000000
#define IO_REGISTER_WINDOW 0x00000010
#define IO_ID_REGISTER 0x00000000
#define IO_VERS_REGISTER 0x00000001
#define IO_ARB_ID_REGISTER 0x00000002
#define IO_REDIR_BASE 0x00000010
ApicRead (
ULONG Address,
ULONG Offset
)
{
ULONG Data, result;
ReadMemory((DWORD)Address + Offset, &Data, sizeof (ULONG), &result);
return Data;
}
IoApicRead (
PHYSICAL_ADDRESS PhysAddress,
ULONG Offset
)
{
ULONG Data, result;
PhysAddress.LowPart += IO_REGISTER_SELECT;
WritePhysical(PhysAddress, &Offset, sizeof(ULONG), &result);
PhysAddress.LowPart += IO_REGISTER_WINDOW - IO_REGISTER_SELECT;
ReadPhysical (PhysAddress, &Data, sizeof (ULONG), &result);
return Data;
}
ULONG
ApicDumpSetBits (
PUCHAR Desc,
ULONG Address,
ULONG Offset
)
{
ULONG Bits [0x80 / sizeof (ULONG)];
PULONG p;
ULONG i, result;
BOOLEAN FoundOne;
ReadMemory((DWORD)Address + Offset, Bits, 0x80, &result);
dprintf (Desc);
i = 0;
p = Bits;
FoundOne = FALSE;
for (; ;) {
if (*p & 1) {
if (FoundOne) {
dprintf (", %x", i);
} else {
FoundOne = TRUE;
dprintf ("%x", i);
}
}
*p >>= 1;
i++;
if (i >= 0x100) {
break;
}
if ((i % 32) == 0) {
p += 4;
}
}
dprintf ("\n");
return 0;
}
ULONG
ApicDumpRedir (
PUCHAR Desc,
BOOLEAN CommandReg,
BOOLEAN DestSelf,
ULONG lh,
ULONG ll
)
{
static PUCHAR DelMode[] = {
"FixedDel",
"LowestDl",
"res010 ",
"remoterd",
"NMI ",
"RESET ",
"res110 ",
"ExtINTA "
};
static PUCHAR DesShDesc[] = { "",
" Dest=Self",
" Dest=ALL",
" Dest=Othrs"
};
ULONG del, dest, delstat, rirr, trig, masked, destsh;
del = (ll >> 8) & 0x7;
dest = (ll >> 11) & 0x1;
delstat = (ll >> 12) & 0x1;
rirr = (ll >> 14) & 0x1;
trig = (ll >> 15) & 0x1;
masked = (ll >> 16) & 0x1;
destsh = (ll >> 18) & 0x3;
if (CommandReg) {
// command reg's don't have a mask
masked = 0;
}
dprintf ("%s: %08x Vec:%02X %s ",
Desc,
ll,
ll & 0xff,
DelMode [ del ]
);
if (DestSelf) {
dprintf (DesShDesc[1]);
} else if (CommandReg && destsh) {
dprintf (DesShDesc[destsh]);
} else {
if (dest) {
dprintf ("Lg:%08x", lh);
} else {
dprintf ("PhysDest:%02X", (lh >> 56) & 0xFF);
}
}
dprintf ("%s %s %s %s\n",
delstat ? "-Pend" : " ",
trig ? "lvl" : "edg",
rirr ? "rirr" : " ",
masked ? "masked" : " "
);
return 0;
}
DECLARE_API( apic )
/*++
Routine Description:
Dumps local apic
Arguments:
args - Supplies the address in hex.
Return Value:
None
--*/
{
static PUCHAR divbase[] = { "2", "4", "8", "f" };
static PUCHAR clktype[] = { "clk", "tmbase", "%s/%s", "??%s/%s" };
ULONG Address;
ULONG result, junk, l, ll, lh, clkvec;
UCHAR s[40];
sscanf(args,"%lX",&Address);
if ( !ReadMemory(
(DWORD)Address,
(PVOID)&junk,
1,
&result
) ) {
dprintf("Unable to read lapic\n");
return;
}
if ( !ReadMemory(
(DWORD)Address + LU_SIZE - 1,
(PVOID)&junk,
1,
&result
) ) {
dprintf("Unable to read lapic\n");
return;
}
dprintf ("Apic @ %08x ID:%x (%x) LogDesc:%08x DestFmt:%08x TPR %02X\n",
Address,
ApicRead (Address, LU_ID_REGISTER) >> 24,
ApicRead (Address, LU_VERS_REGISTER),
ApicRead (Address, LU_DEST),
ApicRead (Address, LU_DEST_FORMAT),
ApicRead (Address, LU_TPR)
);
l = ApicRead (Address, LU_SPURIOUS_VECTOR);
ll = ApicRead (Address, LU_DIVIDER_CONFIG);
clkvec = ApicRead (Address, LU_TIMER_VECTOR);
sprintf (s, clktype[ (clkvec >> 18) & 0x3 ],
clktype [ (ll >> 2) & 0x1 ],
divbase [ ll & 0x3]
);
dprintf ("TimeCnt: %08x%s%s SpurVec:%02x FaultVec:%02x error:%x%s\n",
ApicRead (Address, LU_INITIAL_COUNT),
s,
((clkvec >> 17) & 1) ? "" : "-oneshot",
l & 0xff,
ApicRead (Address, LU_FAULT_VECTOR),
ApicRead (Address, LU_ERROR_STATUS),
l & 0x100 ? "" : " DISABLED"
);
ll = ApicRead (Address, LU_INT_CMD_LOW);
lh = ApicRead (Address, LU_INT_CMD_HIGH);
ApicDumpRedir ("Ipi Cmd", TRUE, FALSE, lh, ll);
ApicDumpRedir ("Timer..", FALSE, TRUE, 0, clkvec);
ApicDumpRedir ("Linti0.", FALSE, TRUE, 0, ApicRead (Address, LU_INT_VECTOR_0));
ApicDumpRedir ("Linti1.", FALSE, TRUE, 0, ApicRead (Address, LU_INT_VECTOR_1));
ApicDumpSetBits ("TMR: ", Address, LU_TMR_0);
ApicDumpSetBits ("IRR: ", Address, LU_IRR_0);
ApicDumpSetBits ("ISR: ", Address, LU_ISR_0);
}
DECLARE_API( ioapic )
/*++
Routine Description:
Dumps io apic
Arguments:
args - Supplies the address in hex.
Return Value:
None
--*/
{
PHYSICAL_ADDRESS PhysAddress;
ULONG Address;
ULONG i, ll, lh, max;
UCHAR s[40];
BOOLEAN Converted;
sscanf(args,"%lX",&Address);
Converted = MiGetPhysicalAddress ((PVOID) Address, &PhysAddress);
if (!Converted) {
dprintf("Unable to read ioapic\n");
return;
}
ll = IoApicRead (PhysAddress, IO_VERS_REGISTER),
max = (ll >> 16) & 0xff;
dprintf ("IoApic @ %08x ID:%x (%x) Arb:%x\n",
Address,
IoApicRead (PhysAddress, IO_ID_REGISTER) >> 24,
ll & 0xFF,
IoApicRead (PhysAddress, IO_ARB_ID_REGISTER)
);
//
// Dump inti table
//
max *= 2;
for (i=0; i <= max; i += 2) {
ll = IoApicRead (PhysAddress, IO_REDIR_BASE+i+0);
lh = IoApicRead (PhysAddress, IO_REDIR_BASE+i+1);
sprintf (s, "Inti%02X.", i/2);
ApicDumpRedir (s, FALSE, FALSE, lh, ll);
}
}