|
|
/*++
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; }
|