#define IOREGSELECTPHYADDR 0xfec00000
#define IOREGWINPHYADDR 0xfec00010
#include "ntddk.h"
#include "APIC.h"
ULONG GetAPICVersion()
{
KIRQL OldKIRQL;
ULONG ulAPICVersion;
PHYSICAL_ADDRESS PhysicalAddress;
PVOID pRegSelect,pRegWin = NULL;
RtlZeroMemory( &PhysicalAddress, sizeof(PHYSICAL_ADDRESS) );
PhysicalAddress.u.LowPart = IOREGSELECTPHYADDR;
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
KeRaiseIrql( DISPATCH_LEVEL, &OldKIRQL );
KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "OldKIRQL=%d\n", OldKIRQL ));
pRegSelect = MmMapIoSpace( PhysicalAddress, 0x14, MmNonCached );
if( !MmIsAddressValid( pRegSelect ) )
{
if( pRegSelect )
MmUnmapIoSpace( pRegSelect, 0x14 );
KeLowerIrql(OldKIRQL);
return 1;
}
pRegWin = (UCHAR*)pRegSelect+0x10;
*((UCHAR*)pRegSelect) = 0x01; //低8位,选择版本寄存器
ulAPICVersion = *((ULONG*)pRegWin);
KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Current APIC version: 0x%08x\n", ulAPICVersion ));
if( pRegSelect )
MmUnmapIoSpace( pRegSelect, 0x14 );
KeLowerIrql(OldKIRQL);
return 0;
}
ULONG ListIRQNumber()
{
ULONG i;
KIRQL OldKIRQL;
ULONG ulData;
PHYSICAL_ADDRESS PhysicalAddress;
PVOID pRegSelect,pRegWin = NULL;
RtlZeroMemory( &PhysicalAddress, sizeof(PHYSICAL_ADDRESS) );
PhysicalAddress.u.LowPart = IOREGSELECTPHYADDR;
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
KeRaiseIrql( DISPATCH_LEVEL, &OldKIRQL );
KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "OldKIRQL=%d\n", OldKIRQL ));
pRegSelect = MmMapIoSpace( PhysicalAddress, 0x14, MmNonCached );
if( !MmIsAddressValid( pRegSelect ) )
{
if( pRegSelect )
MmUnmapIoSpace( pRegSelect, 0x14 );
KeLowerIrql(OldKIRQL);
return 1;
}
pRegWin = (UCHAR*)pRegSelect+0x10;
KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "IOAPIC Redirection Table:\n" ));
for( i=0x10; i<0x3f+1; i++ )
{
*((UCHAR*)pRegSelect) = i; //低8位,选择重定位表寄存器
ulData = *((ULONG*)pRegWin);
if( !(i%2) )
KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "IRQ Number:%02x\n",(UCHAR)(ulData & 0xff) ));
KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Offset:%02x,Data:0x%08x\n",i,ulData ));
}
if( pRegSelect )
MmUnmapIoSpace( pRegSelect, 0x14 );
KeLowerIrql(OldKIRQL);
return 0;
}