mirror of https://github.com/lianthony/NT4.0
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.
1305 lines
43 KiB
1305 lines
43 KiB
/*++
|
|
|
|
Copyright (C) 1991-1995 Microsoft Corporation
|
|
All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
fxerrlog.c
|
|
|
|
Abstract:
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
--*/
|
|
|
|
#include "halp.h"
|
|
|
|
WCHAR rgzNeTpowerKey[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries";
|
|
|
|
//
|
|
// Registry paths and keys for
|
|
// memory error logging
|
|
//
|
|
|
|
#define MEMORY_ERROR_LOG_KEY_MEMORY 0
|
|
#define MEMORY_ERROR_LOG_KEY_CE 1
|
|
#define MEMORY_ERROR_LOG_KEY_UE 2
|
|
#define MEMORY_ERROR_LOG_KEY_MCE 3
|
|
#define MEMORY_ERROR_LOG_KEY_MUE 4
|
|
#define MEMORY_ERROR_LOG_KEY_MAX 5
|
|
|
|
PWCHAR rgzMemoryErrorLogKeys[] = {
|
|
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Memory",
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Memory\\CorrectableError",
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Memory\\UncorrectableError",
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Memory\\MultipleCorrError",
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Memory\\MultipleCorrError"
|
|
|
|
};
|
|
|
|
#define MEMORY_ERROR_LOG_VALUEKEY_INDEX0 0
|
|
#define MEMORY_ERROR_LOG_VALUEKEY_INDEX1 1
|
|
#define MEMORY_ERROR_LOG_VALUEKEY_INDEX2 2
|
|
#define MEMORY_ERROR_LOG_VALUEKEY_INDEX3 3
|
|
#define MEMORY_ERROR_LOG_VALUEKEY_INDEX4 4
|
|
#define MEMORY_ERROR_LOG_VALUEKEY_MAX 5
|
|
|
|
PWCHAR rgzMemoryErrorLogValueKeys[] = {
|
|
|
|
L"TotalAccumulatedErrors",
|
|
L"TotalErrorsSinceLastReboot",
|
|
L"LastMemoryErrorAddressReg",
|
|
L"LastMemoryStatusReg",
|
|
L"LastMemoryDiagReg"
|
|
|
|
};
|
|
|
|
ULONG HalpMemoryUeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_MAX];
|
|
ULONG HalpMemoryCeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_MAX];
|
|
ULONG HalpMemoryMceLogVariable[MEMORY_ERROR_LOG_VALUEKEY_MAX];
|
|
ULONG HalpMemoryMueLogVariable[MEMORY_ERROR_LOG_VALUEKEY_MAX];
|
|
|
|
//
|
|
// Registry paths and keys for
|
|
// pci error logging
|
|
//
|
|
|
|
#define PCI_ERROR_LOG_KEY_PCI 0
|
|
#define PCI_ERROR_LOG_KEY_RMA 1
|
|
#define PCI_ERROR_LOG_KEY_MPE 2
|
|
#define PCI_ERROR_LOG_KEY_RER 3
|
|
#define PCI_ERROR_LOG_KEY_RTA 4
|
|
#define PCI_ERROR_LOG_KEY_IAE 5
|
|
#define PCI_ERROR_LOG_KEY_RSE 6
|
|
#define PCI_ERROR_LOG_KEY_ME 7
|
|
|
|
#define PCI_ERROR_LOG_KEY_MAX 8
|
|
|
|
PWCHAR rgzPciErrorLogKeys[] = {
|
|
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Pci",
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Pci\\MasterAbortError",
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Pci\\ParityError",
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Pci\\ExcessiveRetryError",
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Pci\\TargetAbortError",
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Pci\\AccessError",
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Pci\\SystemError",
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Pci\\MultipleError"
|
|
|
|
};
|
|
|
|
#define PCI_ERROR_LOG_VALUEKEY_INDEX0 0
|
|
#define PCI_ERROR_LOG_VALUEKEY_INDEX1 1
|
|
#define PCI_ERROR_LOG_VALUEKEY_INDEX2 2
|
|
#define PCI_ERROR_LOG_VALUEKEY_INDEX3 3
|
|
#define PCI_ERROR_LOG_VALUEKEY_INDEX4 4
|
|
#define PCI_ERROR_LOG_VALUEKEY_MAX 5
|
|
|
|
PWCHAR rgzPciErrorLogValueKeys[] = {
|
|
|
|
L"TotalAccumulatedErrors",
|
|
L"TotalErrorsSinceLastReboot",
|
|
L"LastPciErrorAddressReg",
|
|
L"LastPciStatusReg",
|
|
L"LastPciRetryReg"
|
|
|
|
};
|
|
|
|
ULONG HalpPciRmaLogVariable[PCI_ERROR_LOG_VALUEKEY_MAX];
|
|
ULONG HalpPciMpeLogVariable[PCI_ERROR_LOG_VALUEKEY_MAX];
|
|
ULONG HalpPciRerLogVariable[PCI_ERROR_LOG_VALUEKEY_MAX];
|
|
ULONG HalpPciRtaLogVariable[PCI_ERROR_LOG_VALUEKEY_MAX];
|
|
ULONG HalpPciIaeLogVariable[PCI_ERROR_LOG_VALUEKEY_MAX];
|
|
ULONG HalpPciRseLogVariable[PCI_ERROR_LOG_VALUEKEY_MAX];
|
|
ULONG HalpPciMeLogVariable[PCI_ERROR_LOG_VALUEKEY_MAX];
|
|
|
|
//
|
|
// Registry paths and keys for
|
|
// processor error logging
|
|
//
|
|
|
|
#define PROC_ERROR_LOG_KEY_MAX 1
|
|
|
|
PWCHAR rgzProcErrorLogKeys[] = {
|
|
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\FASTseries\\Processor"
|
|
|
|
};
|
|
|
|
#define PROC_ERROR_LOG_VALUEKEY_MAX 2
|
|
|
|
PWCHAR rgzProcErrorLogValueKeys[] = {
|
|
|
|
L"TotalAccumulatedErrors",
|
|
L"TotalErrorsSinceLastReboot"
|
|
|
|
};
|
|
|
|
ULONG HalpProcErrorLogVariable[PROC_ERROR_LOG_VALUEKEY_MAX];
|
|
|
|
|
|
VOID
|
|
HalpCreateLogKeys(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
|
|
UNICODE_STRING unicodeString;
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
HANDLE hErrKey;
|
|
NTSTATUS status;
|
|
ULONG disposition, i, j;
|
|
|
|
PKEY_VALUE_FULL_INFORMATION ValueInfo;
|
|
UCHAR buffer [sizeof(PPCI_REGISTRY_INFO) + 99];
|
|
|
|
//
|
|
// Now we can add subkeys to the registry at
|
|
//
|
|
// \\Registry\\Machine\\System\\CurrentControlSet\\Services\\EventLog\\System\\*
|
|
//
|
|
// which will allow our bus and interrupt handlers
|
|
// to log errors as they occur. All of these keys
|
|
// have the REG_OPTION_NON_VOLATILE attribute so
|
|
// that the key and its values are preserved across
|
|
// reboots. If the keys already exist, then they
|
|
// are just opened and then closed without affecting
|
|
// their values.
|
|
//
|
|
// The subkeys created here are
|
|
//
|
|
// - FASTseries
|
|
// - Memory
|
|
// - Pci
|
|
// - Processor
|
|
//
|
|
// Refer to the individual bus and interrupt handlers
|
|
// for details about additional subkeys and values
|
|
// logged.
|
|
//
|
|
|
|
//
|
|
// FASTseries key
|
|
//
|
|
|
|
RtlInitUnicodeString (&unicodeString, rgzNeTpowerKey);
|
|
InitializeObjectAttributes (
|
|
&objectAttributes,
|
|
&unicodeString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL);
|
|
|
|
|
|
status = ZwCreateKey (&hErrKey,
|
|
KEY_WRITE,
|
|
&objectAttributes,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
&disposition);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
return ;
|
|
}
|
|
|
|
ZwClose(hErrKey);
|
|
|
|
//
|
|
// MEMORY:
|
|
//
|
|
// Create (or open) the registry
|
|
// keys used for error logging and
|
|
// get the values (if any) and save
|
|
// them in the appropriate variable
|
|
// that will be referenced by the
|
|
// bus and interrupt handlers.
|
|
//
|
|
|
|
for (i = 0; i < MEMORY_ERROR_LOG_KEY_MAX; i++) {
|
|
|
|
RtlInitUnicodeString(&unicodeString, rgzMemoryErrorLogKeys[i]);
|
|
InitializeObjectAttributes (&objectAttributes,
|
|
&unicodeString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL);
|
|
|
|
status = ZwCreateKey (&hErrKey,
|
|
KEY_WRITE,
|
|
&objectAttributes,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
&disposition);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
return ;
|
|
}
|
|
|
|
if (i) {
|
|
|
|
ValueInfo = (PKEY_VALUE_FULL_INFORMATION) buffer;
|
|
|
|
for (j = 0; j < MEMORY_ERROR_LOG_VALUEKEY_MAX; j++) {
|
|
|
|
RtlInitUnicodeString(&unicodeString, rgzMemoryErrorLogValueKeys[j]);
|
|
status = ZwQueryValueKey(hErrKey,
|
|
&unicodeString,
|
|
KeyValueFullInformation,
|
|
ValueInfo,
|
|
sizeof(buffer),
|
|
&disposition);
|
|
|
|
//
|
|
// If we are not successful, then
|
|
// the value key must not exist so
|
|
// let's create and initialize it
|
|
// and then go to the next valuekey
|
|
//
|
|
// If the value key is the errors
|
|
// since last reboot, we should clear
|
|
// the registry value and start from
|
|
// 0.
|
|
//
|
|
|
|
if (!NT_SUCCESS(status) || (j == MEMORY_ERROR_LOG_VALUEKEY_INDEX1) ) {
|
|
|
|
switch (i) {
|
|
|
|
case MEMORY_ERROR_LOG_KEY_CE:
|
|
|
|
HalpMemoryCeLogVariable[j] = 0;
|
|
|
|
ZwSetValueKey(hErrKey,
|
|
&unicodeString,
|
|
0,
|
|
REG_DWORD,
|
|
&HalpMemoryCeLogVariable[j],
|
|
sizeof(HalpMemoryCeLogVariable[j]));
|
|
break;
|
|
|
|
case MEMORY_ERROR_LOG_KEY_UE:
|
|
|
|
HalpMemoryUeLogVariable[j] = 0;
|
|
|
|
ZwSetValueKey(hErrKey,
|
|
&unicodeString,
|
|
0,
|
|
REG_DWORD,
|
|
&HalpMemoryUeLogVariable[j],
|
|
sizeof(HalpMemoryUeLogVariable[j]));
|
|
break;
|
|
|
|
case MEMORY_ERROR_LOG_KEY_MCE:
|
|
|
|
HalpMemoryMceLogVariable[j] = 0;
|
|
|
|
ZwSetValueKey(hErrKey,
|
|
&unicodeString,
|
|
0,
|
|
REG_DWORD,
|
|
&HalpMemoryMceLogVariable[j],
|
|
sizeof(HalpMemoryMceLogVariable[j]));
|
|
break;
|
|
|
|
case MEMORY_ERROR_LOG_KEY_MUE:
|
|
|
|
HalpMemoryMueLogVariable[j] = 0;
|
|
|
|
ZwSetValueKey(hErrKey,
|
|
&unicodeString,
|
|
0,
|
|
REG_DWORD,
|
|
&HalpMemoryMueLogVariable[j],
|
|
sizeof(HalpMemoryMueLogVariable[j]));
|
|
break;
|
|
|
|
}
|
|
|
|
continue ;
|
|
}
|
|
|
|
//
|
|
// Otherwise, let's initialize the
|
|
// appropriate variable that the bus
|
|
// and interrupt handlers will reference
|
|
// and update
|
|
//
|
|
|
|
switch (i) {
|
|
|
|
case MEMORY_ERROR_LOG_KEY_CE:
|
|
|
|
HalpMemoryCeLogVariable[j] = *((PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset));
|
|
break;
|
|
|
|
case MEMORY_ERROR_LOG_KEY_UE:
|
|
|
|
HalpMemoryUeLogVariable[j] = *((PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset));
|
|
break;
|
|
|
|
case MEMORY_ERROR_LOG_KEY_MCE:
|
|
|
|
HalpMemoryMceLogVariable[j] = *((PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset));
|
|
break;
|
|
|
|
case MEMORY_ERROR_LOG_KEY_MUE:
|
|
|
|
HalpMemoryMueLogVariable[j] = *((PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset));
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ZwClose(hErrKey);
|
|
|
|
}
|
|
|
|
//
|
|
// PCI:
|
|
//
|
|
// Create (or open) the registry
|
|
// keys used for error logging and
|
|
// get the values (if any) and save
|
|
// them in the appropriate variable
|
|
// that will be referenced by the
|
|
// bus and interrupt handlers.
|
|
//
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_KEY_MAX; i++) {
|
|
|
|
RtlInitUnicodeString(&unicodeString, rgzPciErrorLogKeys[i]);
|
|
InitializeObjectAttributes (&objectAttributes,
|
|
&unicodeString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL);
|
|
|
|
status = ZwCreateKey (&hErrKey,
|
|
KEY_WRITE,
|
|
&objectAttributes,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
&disposition);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
return ;
|
|
}
|
|
|
|
if (i) {
|
|
|
|
ValueInfo = (PKEY_VALUE_FULL_INFORMATION) buffer;
|
|
|
|
for (j = 0; j < PCI_ERROR_LOG_VALUEKEY_MAX; j++) {
|
|
|
|
RtlInitUnicodeString(&unicodeString, rgzPciErrorLogValueKeys[j]);
|
|
status = ZwQueryValueKey(hErrKey,
|
|
&unicodeString,
|
|
KeyValueFullInformation,
|
|
ValueInfo,
|
|
sizeof(buffer),
|
|
&disposition);
|
|
|
|
//
|
|
// If we are not successful, then
|
|
// the value key must not exist so
|
|
// let's create and initialize it
|
|
// and then go to the next valuekey
|
|
//
|
|
|
|
if (!NT_SUCCESS(status) || (j == PCI_ERROR_LOG_VALUEKEY_INDEX1) ) {
|
|
|
|
switch(i) {
|
|
|
|
case PCI_ERROR_LOG_KEY_RMA:
|
|
|
|
HalpPciRmaLogVariable[j] = 0;
|
|
|
|
ZwSetValueKey(hErrKey,
|
|
&unicodeString,
|
|
0,
|
|
REG_DWORD,
|
|
&HalpPciRmaLogVariable[j],
|
|
sizeof(HalpPciRmaLogVariable[j]));
|
|
|
|
break;
|
|
|
|
case PCI_ERROR_LOG_KEY_MPE:
|
|
|
|
HalpPciMpeLogVariable[j] = 0;
|
|
|
|
ZwSetValueKey(hErrKey,
|
|
&unicodeString,
|
|
0,
|
|
REG_DWORD,
|
|
&HalpPciMpeLogVariable[j],
|
|
sizeof(HalpPciMpeLogVariable[j]));
|
|
|
|
break;
|
|
|
|
case PCI_ERROR_LOG_KEY_RER:
|
|
|
|
HalpPciRerLogVariable[j] = 0;
|
|
|
|
ZwSetValueKey(hErrKey,
|
|
&unicodeString,
|
|
0,
|
|
REG_DWORD,
|
|
&HalpPciRerLogVariable[j],
|
|
sizeof(HalpPciRerLogVariable[j]));
|
|
|
|
break;
|
|
|
|
case PCI_ERROR_LOG_KEY_RTA:
|
|
|
|
HalpPciRtaLogVariable[j] = 0;
|
|
|
|
ZwSetValueKey(hErrKey,
|
|
&unicodeString,
|
|
0,
|
|
REG_DWORD,
|
|
&HalpPciRtaLogVariable[j],
|
|
sizeof(HalpPciRtaLogVariable[j]));
|
|
|
|
break;
|
|
|
|
case PCI_ERROR_LOG_KEY_IAE:
|
|
|
|
HalpPciIaeLogVariable[j] = 0;
|
|
|
|
ZwSetValueKey(hErrKey,
|
|
&unicodeString,
|
|
0,
|
|
REG_DWORD,
|
|
&HalpPciIaeLogVariable[j],
|
|
sizeof(HalpPciIaeLogVariable[j]));
|
|
|
|
break;
|
|
|
|
case PCI_ERROR_LOG_KEY_RSE:
|
|
|
|
HalpPciRseLogVariable[j] = 0;
|
|
|
|
ZwSetValueKey(hErrKey,
|
|
&unicodeString,
|
|
0,
|
|
REG_DWORD,
|
|
&HalpPciRseLogVariable[j],
|
|
sizeof(HalpPciRseLogVariable[j]));
|
|
|
|
break;
|
|
|
|
case PCI_ERROR_LOG_KEY_ME:
|
|
|
|
HalpPciMeLogVariable[j] = 0;
|
|
|
|
ZwSetValueKey(hErrKey,
|
|
&unicodeString,
|
|
0,
|
|
REG_DWORD,
|
|
&HalpPciMeLogVariable[j],
|
|
sizeof(HalpPciMeLogVariable[j]));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
continue ;
|
|
}
|
|
|
|
//
|
|
// Otherwise, let's initialize the
|
|
// appropriate variable that the bus
|
|
// and interrupt handlers will reference
|
|
// and update
|
|
//
|
|
|
|
switch (i) {
|
|
|
|
case PCI_ERROR_LOG_KEY_RMA:
|
|
|
|
HalpPciRmaLogVariable[j] = *((PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset));
|
|
break;
|
|
|
|
case PCI_ERROR_LOG_KEY_MPE:
|
|
|
|
HalpPciMpeLogVariable[j] = *((PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset));
|
|
break;
|
|
|
|
case PCI_ERROR_LOG_KEY_RER:
|
|
|
|
HalpPciRerLogVariable[j] = *((PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset));
|
|
break;
|
|
|
|
case PCI_ERROR_LOG_KEY_RTA:
|
|
|
|
HalpPciRtaLogVariable[j] = *((PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset));
|
|
break;
|
|
|
|
case PCI_ERROR_LOG_KEY_IAE:
|
|
|
|
HalpPciIaeLogVariable[j] = *((PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset));
|
|
break;
|
|
|
|
case PCI_ERROR_LOG_KEY_RSE:
|
|
|
|
HalpPciRseLogVariable[j] = *((PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset));
|
|
break;
|
|
|
|
case PCI_ERROR_LOG_KEY_ME:
|
|
|
|
HalpPciMeLogVariable[j] = *((PULONG)((PUCHAR)ValueInfo + ValueInfo->DataOffset));
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ZwClose(hErrKey);
|
|
|
|
}
|
|
|
|
//
|
|
// Processor keys
|
|
//
|
|
|
|
for (i = 0; i < PROC_ERROR_LOG_KEY_MAX; i++) {
|
|
|
|
RtlInitUnicodeString(&unicodeString, rgzProcErrorLogKeys[i]);
|
|
InitializeObjectAttributes (&objectAttributes,
|
|
&unicodeString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL);
|
|
|
|
status = ZwCreateKey (&hErrKey,
|
|
KEY_WRITE,
|
|
&objectAttributes,
|
|
0,
|
|
NULL,
|
|
REG_OPTION_NON_VOLATILE,
|
|
&disposition);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
return ;
|
|
}
|
|
|
|
ZwClose(hErrKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
VOID
|
|
HalpLogErrorInfo(
|
|
IN PCWSTR RegistryKey,
|
|
IN PCWSTR ValueName,
|
|
IN ULONG Type,
|
|
IN PVOID Data,
|
|
IN ULONG Size
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function ?
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
UNICODE_STRING unicodeString;
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
HANDLE hMFunc;
|
|
NTSTATUS status;
|
|
|
|
RtlInitUnicodeString(&unicodeString, RegistryKey);
|
|
InitializeObjectAttributes (
|
|
&objectAttributes,
|
|
&unicodeString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL);
|
|
|
|
status = ZwOpenKey (&hMFunc,
|
|
KEY_WRITE,
|
|
&objectAttributes);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
return ;
|
|
}
|
|
|
|
RtlInitUnicodeString(&unicodeString, ValueName);
|
|
ZwSetValueKey(hMFunc,
|
|
&unicodeString,
|
|
0,
|
|
Type,
|
|
Data,
|
|
Size);
|
|
|
|
ZwClose(hMFunc);
|
|
|
|
}
|
|
|
|
BOOLEAN
|
|
HalpDataBusErrorHandler (
|
|
IN PEXCEPTION_RECORD ExceptionRecord,
|
|
IN PKEXCEPTION_FRAME ExceptionFrame,
|
|
IN PKTRAP_FRAME TrapFrame,
|
|
IN PVOID VirtualAddress,
|
|
IN PHYSICAL_ADDRESS PhysicalAddress
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function provides the FASTseries bus error
|
|
|
|
Arguments:
|
|
|
|
ExceptionRecord - Supplies a pointer to an exception record.
|
|
|
|
ExceptionFrame - Supplies a pointer to an exception frame.
|
|
|
|
TrapFrame - Supplies a pointer to a trap frame.
|
|
|
|
VirtualAddress - Supplies the virtual address of the bus error.
|
|
|
|
PhysicalAddress - Supplies the physical address of the bus error.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG BadStatus, i;
|
|
|
|
|
|
//
|
|
// MEMORY:
|
|
// 1. Uncorrectable memory error
|
|
// 2. Multiple UE
|
|
// 3. Mutiple CE
|
|
//
|
|
|
|
BadStatus = READ_REGISTER_ULONG(HalpPmpMemStatus);
|
|
|
|
if ( BadStatus & MEM_STATUS_MUE ) {
|
|
|
|
//
|
|
// Read the address, status, and diag registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpMemoryMueLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpMemoryMueLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpMemoryMueLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpMemErrAddr);
|
|
HalpMemoryMueLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpMemErrAck);
|
|
HalpMemoryMueLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpMemDiag);
|
|
|
|
for (i = 0; i < MEMORY_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzMemoryErrorLogKeys[MEMORY_ERROR_LOG_KEY_MUE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpMemoryMueLogVariable[i],
|
|
sizeof(HalpMemoryMueLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & (MEM_STATUS_EUE | MEM_STATUS_OUE) ) {
|
|
|
|
//
|
|
// Read the address, status, and diag registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpMemoryUeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpMemoryUeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpMemoryUeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpMemErrAddr);
|
|
HalpMemoryUeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpMemErrAck);
|
|
HalpMemoryUeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpMemDiag);
|
|
|
|
for (i = 0; i < MEMORY_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzMemoryErrorLogKeys[MEMORY_ERROR_LOG_KEY_UE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpMemoryUeLogVariable[i],
|
|
sizeof(HalpMemoryUeLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & MEM_STATUS_MCE ) {
|
|
|
|
HalpMemoryMceLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpMemoryMceLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpMemoryMceLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpMemErrAddr);
|
|
HalpMemoryMceLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpMemErrAck);
|
|
HalpMemoryMceLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpMemDiag);
|
|
|
|
for (i = 0; i < MEMORY_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzMemoryErrorLogKeys[MEMORY_ERROR_LOG_KEY_MCE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpMemoryMceLogVariable[i],
|
|
sizeof(HalpMemoryMceLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & (MEM_STATUS_ECE | MEM_STATUS_OCE) ) {
|
|
|
|
HalpMemoryCeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpMemoryCeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpMemoryCeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpMemErrAddr);
|
|
HalpMemoryCeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpMemErrAck);
|
|
HalpMemoryCeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpMemDiag);
|
|
|
|
for (i = 0; i < MEMORY_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzMemoryErrorLogKeys[MEMORY_ERROR_LOG_KEY_CE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpMemoryCeLogVariable[i],
|
|
sizeof(HalpMemoryCeLogVariable[i]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// PCI:
|
|
// 1. Parity (SERR#)
|
|
// 2. Master Abort
|
|
// 3. Target Abort
|
|
// 4. Access Error
|
|
// 5. System Error
|
|
// 6. Retry Error
|
|
//
|
|
|
|
BadStatus = READ_REGISTER_ULONG(HalpPmpPciStatus);
|
|
|
|
if ( BadStatus & PCI_STATUS_ME) {
|
|
|
|
HalpPciMeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciMeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciMeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciMeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciMeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_ME],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciMeLogVariable[i],
|
|
sizeof(HalpPciMeLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & PCI_STATUS_RMA) {
|
|
|
|
//
|
|
// Read the address and status registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpPciRmaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciRmaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciRmaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciRmaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciRmaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_RMA],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciRmaLogVariable[i],
|
|
sizeof(HalpPciRmaLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & PCI_STATUS_RSE) {
|
|
|
|
//
|
|
// Read the address and status registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpPciRseLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciRseLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciRseLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciRseLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciRseLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_RSE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciRseLogVariable[i],
|
|
sizeof(HalpPciRseLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & PCI_STATUS_RER) {
|
|
|
|
//
|
|
// Read the address and status registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpPciRerLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciRerLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciRerLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciRerLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciRerLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_RER],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciRerLogVariable[i],
|
|
sizeof(HalpPciRerLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & PCI_STATUS_IAE) {
|
|
|
|
//
|
|
// Read the address and status registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpPciIaeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciIaeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciIaeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciIaeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciIaeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_IAE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciIaeLogVariable[i],
|
|
sizeof(HalpPciIaeLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & PCI_STATUS_MPE) {
|
|
|
|
//
|
|
// Read the address and status registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpPciMpeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciMpeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciMpeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciMpeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciMpeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_MPE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciMpeLogVariable[i],
|
|
sizeof(HalpPciMpeLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & PCI_STATUS_RTA) {
|
|
|
|
HalpPciRtaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciRtaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciRtaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciRtaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciRtaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_RTA],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciRtaLogVariable[i],
|
|
sizeof(HalpPciRtaLogVariable[i]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
KeBugCheckEx(ExceptionRecord->ExceptionCode & 0xffff,
|
|
(ULONG)VirtualAddress,
|
|
PhysicalAddress.HighPart,
|
|
PhysicalAddress.LowPart,
|
|
0);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function handles PCI interrupts on a FASTseries.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
VOID
|
|
HalpPciInterrupt(
|
|
VOID
|
|
)
|
|
|
|
{
|
|
ULONG BadStatus, i;
|
|
|
|
//
|
|
// PCI:
|
|
// 1. Parity (SERR#)
|
|
// 2. Master Abort
|
|
// 3. Target Abort
|
|
// 4. Access Error
|
|
// 5. System Error
|
|
// 6. Retry Error
|
|
//
|
|
|
|
BadStatus = READ_REGISTER_ULONG(HalpPmpPciStatus);
|
|
|
|
if ( BadStatus & PCI_STATUS_RMA) {
|
|
|
|
//
|
|
// Determine if this is expected (from
|
|
// pci config probe) or unexpected
|
|
//
|
|
|
|
if (HalpPciRmaConfigErrorOccurred == 0) {
|
|
|
|
//
|
|
// Clear the error source
|
|
//
|
|
|
|
READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
|
|
HalpPciRmaConfigErrorOccurred = 1;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Read the address and status registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpPciRmaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciRmaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciRmaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciRmaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciRmaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_RMA],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciRmaLogVariable[i],
|
|
sizeof(HalpPciRmaLogVariable[i]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & PCI_STATUS_RSE) {
|
|
|
|
//
|
|
// Read the address and status registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpPciRseLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciRseLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciRseLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciRseLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciRseLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_RSE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciRseLogVariable[i],
|
|
sizeof(HalpPciRseLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & PCI_STATUS_RER) {
|
|
|
|
//
|
|
// Read the address and status registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpPciRerLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciRerLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciRerLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciRerLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciRerLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_RER],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciRerLogVariable[i],
|
|
sizeof(HalpPciRerLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & PCI_STATUS_IAE) {
|
|
|
|
//
|
|
// Read the address and status registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpPciIaeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciIaeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciIaeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciIaeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciIaeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_IAE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciIaeLogVariable[i],
|
|
sizeof(HalpPciIaeLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & PCI_STATUS_MPE) {
|
|
|
|
//
|
|
// Read the address and status registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpPciMpeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciMpeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciMpeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciMpeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciMpeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_MPE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciMpeLogVariable[i],
|
|
sizeof(HalpPciMpeLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & PCI_STATUS_RTA) {
|
|
|
|
HalpPciRtaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciRtaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciRtaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciRtaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciRtaLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_RTA],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciRtaLogVariable[i],
|
|
sizeof(HalpPciRtaLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & PCI_STATUS_ME) {
|
|
|
|
HalpPciMeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpPciMeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpPciMeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpPciErrAddr);
|
|
HalpPciMeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpPciErrAck);
|
|
HalpPciMeLogVariable[PCI_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpPciRetry);
|
|
|
|
for (i = 0; i < PCI_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzPciErrorLogKeys[PCI_ERROR_LOG_KEY_ME],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpPciMeLogVariable[i],
|
|
sizeof(HalpPciMeLogVariable[i]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function handles Memory interrupts on a FASTseries.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
VOID
|
|
HalpMemoryInterrupt(
|
|
VOID
|
|
)
|
|
|
|
{
|
|
ULONG BadStatus, i;
|
|
|
|
|
|
//
|
|
// MEMORY:
|
|
// 1. Uncorrectable memory error
|
|
// 2. Multiple UE
|
|
// 3. Mutiple CE
|
|
//
|
|
|
|
BadStatus = READ_REGISTER_ULONG(HalpPmpMemStatus);
|
|
|
|
if ( BadStatus & MEM_STATUS_MUE ) {
|
|
|
|
//
|
|
// Read the address, status, and diag registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpMemoryMueLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpMemoryMueLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpMemoryMueLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpMemErrAddr);
|
|
HalpMemoryMueLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpMemErrAck);
|
|
HalpMemoryMueLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpMemDiag);
|
|
|
|
for (i = 0; i < MEMORY_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzMemoryErrorLogKeys[MEMORY_ERROR_LOG_KEY_MUE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpMemoryMueLogVariable[i],
|
|
sizeof(HalpMemoryMueLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & (MEM_STATUS_EUE | MEM_STATUS_OUE) ) {
|
|
|
|
//
|
|
// Read the address, status, and diag registers
|
|
// and update the appropriate variables
|
|
//
|
|
|
|
HalpMemoryUeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpMemoryUeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpMemoryUeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpMemErrAddr);
|
|
HalpMemoryUeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpMemErrAck);
|
|
HalpMemoryUeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpMemDiag);
|
|
|
|
for (i = 0; i < MEMORY_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzMemoryErrorLogKeys[MEMORY_ERROR_LOG_KEY_UE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpMemoryUeLogVariable[i],
|
|
sizeof(HalpMemoryUeLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & MEM_STATUS_MCE ) {
|
|
|
|
HalpMemoryMceLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpMemoryMceLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpMemoryMceLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpMemErrAddr);
|
|
HalpMemoryMceLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpMemErrAck);
|
|
HalpMemoryMceLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpMemDiag);
|
|
|
|
for (i = 0; i < MEMORY_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzMemoryErrorLogKeys[MEMORY_ERROR_LOG_KEY_MCE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpMemoryMceLogVariable[i],
|
|
sizeof(HalpMemoryMceLogVariable[i]));
|
|
|
|
}
|
|
|
|
} else if ( BadStatus & (MEM_STATUS_ECE | MEM_STATUS_OCE) ) {
|
|
|
|
HalpMemoryCeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX0]++;
|
|
HalpMemoryCeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX1]++;
|
|
HalpMemoryCeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX2] = READ_REGISTER_ULONG(HalpPmpMemErrAddr);
|
|
HalpMemoryCeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX3] = READ_REGISTER_ULONG(HalpPmpMemErrAck);
|
|
HalpMemoryCeLogVariable[MEMORY_ERROR_LOG_VALUEKEY_INDEX4] = READ_REGISTER_ULONG(HalpPmpMemDiag);
|
|
|
|
for (i = 0; i < MEMORY_ERROR_LOG_VALUEKEY_MAX; i++) {
|
|
|
|
HalpLogErrorInfo(rgzMemoryErrorLogKeys[MEMORY_ERROR_LOG_KEY_CE],
|
|
rgzMemoryErrorLogValueKeys[i],
|
|
REG_DWORD,
|
|
&HalpMemoryCeLogVariable[i],
|
|
sizeof(HalpMemoryCeLogVariable[i]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|