windows-nt/Source/XPSP1/NT/base/tools/kdexts2/pic.c
2020-09-26 16:20:57 +08:00

301 lines
5 KiB
C

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
pic.c
Abstract:
WinDbg Extension Api
Author:
Santosh Jodh (santoshj) 29-June-1998
Environment:
User Mode.
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#define PIC_MASTER_PORT0 0x20
#define PIC_MASTER_PORT1 0x21
#define PIC_SLAVE_PORT0 0xA0
#define PIC_SLAVE_PORT1 0xA1
#define ELCR_PORT0 0x4D0
#define ELCR_PORT1 0x4D1
VOID
ShowMask (
ULONG Mask
)
{
ULONG interrupt;
for ( interrupt = 0;
interrupt <= 0x0F;
interrupt++)
{
if (Mask & (1 << interrupt))
dprintf(" Y");
else
dprintf(" .");
}
dprintf("\n");
}
BOOLEAN
GetPICStatus (
UCHAR Type,
PULONG Status
)
{
ULONG size;
ULONG data;
ULONG mask;
//
// Send OCW3 to master.
//
size = 1;
WriteIoSpace64(PIC_MASTER_PORT0, Type, &size);
//
// Read master's status.
//
data = 0;
size = 1;
ReadIoSpace64(PIC_MASTER_PORT0, &data, &size);
if (size == 1)
{
//
// Send OCW3 to slave.
//
mask = data;
size = 1;
WriteIoSpace64(PIC_SLAVE_PORT0, Type, &size);
//
// Get the slave's status.
//
data = 0;
size = 1;
ReadIoSpace64(PIC_SLAVE_PORT0, &data, &size);
if (size == 1)
{
mask |= (data << 8);
*Status = mask;
return (TRUE);
}
}
*Status = 0;
return (FALSE);
}
BOOLEAN
GetELCRStatus(
OUT PULONG Status
)
{
ULONG data = 0;
ULONG size = 1;
ULONG mask = 0;
*Status = 0;
ReadIoSpace64(ELCR_PORT0, &data, &size);
if (size == 1) {
mask = data;
ReadIoSpace64(ELCR_PORT1, &data, &size);
if (size == 1) {
mask |= (data << 8);
*Status = mask;
return TRUE;
}
}
return FALSE;
}
DECLARE_API(pic)
/*++
Routine Description:
Dumps PIC information.
Input Parameters:
args - Supplies the options.
Return Value:
None
--*/
{
ULONG data;
ULONG size;
ULONG mask;
ULONG64 addr;
UCHAR halName[32];
BOOL dumpElcr=FALSE;
// X86_ONLY_API
if (TargetMachine != IMAGE_FILE_MACHINE_I386) {
dprintf("!pic is for X86 targets only.\n");
return E_INVALIDARG;
}
if (strcmp(args, "-e")==0) {
//
// Here we trust that the user knows this machine architecture
// such that the ELCR exists at these ports.
//
dumpElcr = TRUE;
}else{
//
// Now lets see what HAL we are running. Currently
// we can only dump the ELCR mask safely on ACPI (non-apic) machines
// as ACPI has defined static ports for this.
//
addr = GetExpression("hal!HalName");
if (addr == 0) {
dprintf("Unable to use HAL symbols (hal!HalName), please verify symbols.\n");
return E_INVALIDARG;
}
if (!xReadMemory(addr, &halName, sizeof(halName))) {
dprintf("Failed to read HalName from host memory, quitting.\n");
return E_INVALIDARG;
}
halName[sizeof(halName)-1] = '\0';
if (strcmp(halName, "ACPI Compatible Eisa/Isa HAL")==0) {
dumpElcr = TRUE;
}
}
//
// Display the title.
//
dprintf("----- IRQ Number ----- 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
//
// Dump the Interrupt Service Register information.
//
dprintf("Physically in service:");
if (GetPICStatus(0x0B, &mask))
{
ShowMask(mask);
}
else
{
dprintf("Error reading PIC!\n");
}
//
// Dump the Interrupt Mask Register information.
//
dprintf("Physically masked: ");
data = 0;
size = 1;
ReadIoSpace64(PIC_MASTER_PORT1, &data, &size);
if (size == 1)
{
mask = data;
data = 0;
size = 1;
ReadIoSpace64(PIC_SLAVE_PORT1, &data, &size);
if (size == 1)
{
mask |= (data << 8);
ShowMask(mask);
}
else
{
dprintf("Error reading PIC!\n");
}
}
else
{
dprintf("Error reading PIC!\n");
}
//
// Dump the Interrupt Request Register information.
//
dprintf("Physically requested: ");
if (GetPICStatus(0x0A, &mask))
{
ShowMask(mask);
}
else
{
dprintf("Error reading PIC!\n");
}
if (dumpElcr) {
//
// Dump the Edge/Level Control Register information.
//
dprintf("Level Triggered: ");
if (GetELCRStatus(&mask)) {
ShowMask(mask);
}else{
dprintf("Error reading ELCR!\n");
}
}
return S_OK;
}