301 lines
5 KiB
C
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;
|
||
|
}
|