253 lines
5.2 KiB
C
253 lines
5.2 KiB
C
/*++
|
||
|
||
Copyright (c) 1997 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
debug.c
|
||
|
||
Abstract:
|
||
|
||
This module contains support routines for the Pnp resource arbiters.
|
||
|
||
Author:
|
||
|
||
Andrew Thornton (andrewth) 19-June-1998
|
||
|
||
|
||
Environment:
|
||
|
||
Kernel mode
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "arbp.h"
|
||
|
||
|
||
//
|
||
// Debugging support
|
||
//
|
||
|
||
//
|
||
// Debug print level:
|
||
// -1 = no messages
|
||
// 0 = vital messages only
|
||
// 1 = call trace
|
||
// 2 = verbose messages
|
||
//
|
||
|
||
//Present in retail builds
|
||
LONG ArbDebugLevel = -1;
|
||
|
||
#if ARB_DBG
|
||
|
||
//
|
||
// ArbStopOnError works just like a debug level variable except
|
||
// instead of controlling whether a message is printed, it controls
|
||
// whether we breakpoint on an error or not. Likewise ArbReplayOnError
|
||
// controls if we replay fail arbitrations so we can debug them.
|
||
//
|
||
|
||
ULONG ArbStopOnError;
|
||
ULONG ArbReplayOnError;
|
||
|
||
const CHAR* ArbpActionStrings[] = {
|
||
"ArbiterActionTestAllocation",
|
||
"ArbiterActionRetestAllocation",
|
||
"ArbiterActionCommitAllocation",
|
||
"ArbiterActionRollbackAllocation",
|
||
"ArbiterActionQueryAllocatedResources",
|
||
"ArbiterActionWriteReservedResources",
|
||
"ArbiterActionQueryConflict",
|
||
"ArbiterActionQueryArbitrate",
|
||
"ArbiterActionAddReserved",
|
||
"ArbiterActionBootAllocation"
|
||
};
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(PAGE, ArbDumpArbiterRange)
|
||
#pragma alloc_text(PAGE, ArbDumpArbiterInstance)
|
||
#pragma alloc_text(PAGE, ArbDumpArbitrationList)
|
||
#endif
|
||
|
||
VOID
|
||
ArbDumpArbiterRange(
|
||
LONG Level,
|
||
PRTL_RANGE_LIST List,
|
||
PUCHAR RangeText
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This dumps the contents of a range list to the debugger.
|
||
|
||
Parameters:
|
||
|
||
Level - The debug level at or above which the data should be displayed.
|
||
List - The range list to be displayed.
|
||
RangeText - Informative text to go with the display.
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
{
|
||
PRTL_RANGE current;
|
||
RTL_RANGE_LIST_ITERATOR iterator;
|
||
BOOLEAN headerDisplayed = FALSE;
|
||
|
||
PAGED_CODE();
|
||
|
||
FOR_ALL_RANGES(List, &iterator, current) {
|
||
|
||
if (headerDisplayed == FALSE) {
|
||
headerDisplayed = TRUE;
|
||
ARB_PRINT(Level, (" %s:\n", RangeText));
|
||
}
|
||
|
||
ARB_PRINT(Level,
|
||
(" %I64x-%I64x %s%s O=0x%08x U=0x%08x\n",
|
||
current->Start,
|
||
current->End,
|
||
current->Flags & RTL_RANGE_SHARED ? "S" : " ",
|
||
current->Flags & RTL_RANGE_CONFLICT ? "C" : " ",
|
||
current->Owner,
|
||
current->UserData
|
||
));
|
||
}
|
||
if (headerDisplayed == FALSE) {
|
||
ARB_PRINT(Level, (" %s: <None>\n", RangeText));
|
||
}
|
||
}
|
||
|
||
VOID
|
||
ArbDumpArbiterInstance(
|
||
LONG Level,
|
||
PARBITER_INSTANCE Arbiter
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This dumps the state of the arbiter to the debugger.
|
||
|
||
Parameters:
|
||
|
||
Level - The debug level at or above which the data should be displayed.
|
||
|
||
Arbiter - The arbiter instance to display
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
PAGED_CODE();
|
||
|
||
ARB_PRINT(Level,
|
||
("---%S Arbiter State---\n",
|
||
Arbiter->Name
|
||
));
|
||
|
||
ArbDumpArbiterRange(
|
||
Level,
|
||
Arbiter->Allocation,
|
||
"Allocation"
|
||
);
|
||
|
||
ArbDumpArbiterRange(
|
||
Level,
|
||
Arbiter->PossibleAllocation,
|
||
"PossibleAllocation"
|
||
);
|
||
}
|
||
|
||
VOID
|
||
ArbDumpArbitrationList(
|
||
LONG Level,
|
||
PLIST_ENTRY ArbitrationList
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Display the contents of an arbitration list. That is, the
|
||
set of resources (possibilities) we are trying to get.
|
||
|
||
Parameters:
|
||
|
||
Level - The debug level at or above which the data
|
||
should be displayed.
|
||
ArbitrationList - The arbitration list to be displayed.
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
|
||
{
|
||
PARBITER_LIST_ENTRY current;
|
||
PIO_RESOURCE_DESCRIPTOR alternative;
|
||
PDEVICE_OBJECT previousOwner = NULL;
|
||
UCHAR andOr = ' ';
|
||
|
||
PAGED_CODE();
|
||
|
||
ARB_PRINT(Level, ("Arbitration List\n"));
|
||
|
||
FOR_ALL_IN_LIST(ARBITER_LIST_ENTRY, ArbitrationList, current) {
|
||
|
||
if (previousOwner != current->PhysicalDeviceObject) {
|
||
|
||
previousOwner = current->PhysicalDeviceObject;
|
||
|
||
ARB_PRINT(
|
||
Level,
|
||
(" Owning object 0x%08x\n",
|
||
current->PhysicalDeviceObject
|
||
));
|
||
ARB_PRINT(
|
||
Level,
|
||
(" Length Alignment Minimum Address - Maximum Address\n"
|
||
));
|
||
|
||
}
|
||
|
||
FOR_ALL_IN_ARRAY(current->Alternatives,
|
||
current->AlternativeCount,
|
||
alternative) {
|
||
|
||
ARB_PRINT(
|
||
Level,
|
||
("%c %8x %8x %08x%08x - %08x%08x %s\n",
|
||
andOr,
|
||
alternative->u.Generic.Length,
|
||
alternative->u.Generic.Alignment,
|
||
alternative->u.Generic.MinimumAddress.HighPart,
|
||
alternative->u.Generic.MinimumAddress.LowPart,
|
||
alternative->u.Generic.MaximumAddress.HighPart,
|
||
alternative->u.Generic.MaximumAddress.LowPart,
|
||
alternative->Type == CmResourceTypeMemory ?
|
||
"Memory"
|
||
: "Port"
|
||
));
|
||
andOr = '|';
|
||
}
|
||
andOr = '&';
|
||
}
|
||
}
|
||
|
||
#endif // ARB_DBG
|