ACPI!PnpiBiosAddressDoubleToIoDescriptor函数分析用了2个描述符rangeDescriptor和privateDescriptor
//
// Handle the hints that are given to us
//
if (buffer->GFlag & PNP_ADDRESS_FLAG_MINIMUM_FIXED &&
buffer->GFlag & PNP_ADDRESS_FLAG_MAXIMUM_FIXED) {
if (Descriptor->Type == CmResourceTypeBusNumber) {
oldValue = Descriptor->u.BusNumber.Length;
newValue = Descriptor->u.BusNumber.Length =
Descriptor->u.BusNumber.MaxBusNumber -
Descriptor->u.BusNumber.MinBusNumber + 1;
}
//
// Move to the next descriptor
//
buffer += increment;
tagName = *buffer;
}
switch(tagName) {
case TAG_DOUBLE_ADDRESS: {
status = PnpiBiosAddressDoubleToIoDescriptor(
buffer,
Array,
ArrayIndex,
Flags
);
ACPIPrint( (
ACPI_PRINT_RESOURCES_2,
"PnpBiosResourcesToNtResources: TAG_DOUBLE_ADDRESS = 0x%8lx\n",
status
) );
break;
}
0: kd> kc
#
00 ACPI!PnpiBiosAddressDoubleToIoDescriptor
01 ACPI!PnpBiosResourcesToNtResources
02 ACPI!ACPIBusIrpQueryResourceRequirements
03 ACPI!ACPIDispatchIrp
04 nt!IofCallDriver
05 nt!IopSynchronousCall
06 nt!PpIrpQueryResourceRequirements
07 nt!PiQueryResourceRequirements
08 nt!PiProcessNewDeviceNode
09 nt!PipProcessDevNodeTree
0a nt!PipDeviceActionWorker
0b nt!PipRequestDeviceAction
0c nt!IopInitializeBootDrivers
0d nt!IoInitSystem
0e nt!Phase1Initialization
0f nt!PspSystemThreadStartup
10 nt!KiThreadStartup
0: kd> dv
Data = 0xe129e381 "???"
Array = 0xe1278800
ArrayIndex = 0
Flags = 1
0: kd> db 0xe129e381
e129e381 87 18 00 00 0c 03 00 00-00 00 00 00 0a 00 ff ff ................
e129e391 0b 00 00 00 00 00 00 00-02 00 00 87 18 00 00 0c ................
0: kd> dt PNP_DWORD_ADDRESS_DESCRIPTOR 0xe129e381
ACPI!PNP_DWORD_ADDRESS_DESCRIPTOR
+0x000 Tag : 0x87 ''
+0x001 Length : 0x18
+0x003 RFlag : 0 '' PNP_ADDRESS_MEMORY_TYPE 0x0
+0x004 GFlag : 0xc ''
+0x005 TFlag : 0x3 ''
+0x006 Granularity : 0
+0x00a MinimumAddress : 0xa0000
+0x00e MaximumAddress : 0xbffff
+0x012 TranslationAddress : 0
+0x016 AddressLength : 0x20000
DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x00000000, // Granularity
0x000A0000, // Range Minimum
0x000BFFFF, // Range Maximum
0x00000000, // Translation Offset
0x00020000, // Length
0x00,, , AddressRangeMemory, TypeStatic)
//
// These are the possible values for RFlag Means
//
#define PNP_ADDRESS_MEMORY_TYPE 0x0
#define PNP_ADDRESS_IO_TYPE 0x1
#define PNP_ADDRESS_BUS_NUMBER_TYPE 0x2
//
// The Global flags
//
#define PNP_ADDRESS_FLAG_CONSUMED_ONLY 0x1
#define PNP_ADDRESS_FLAG_SUBTRACTIVE_DECODE 0x2
#define PNP_ADDRESS_FLAG_MINIMUM_FIXED 0x4
#define PNP_ADDRESS_FLAG_MAXIMUM_FIXED 0x8
//
// Ensure that there is enough space within the chosen list to add the
// resource
//
status = PnpiUpdateResourceList( & (Array[ArrayIndex]), &rangeDescriptor );
if (!NT_SUCCESS(status)) {
return status;
}
0: kd> t
eax=f789a164 ebx=80ae2bca ecx=80ae0dfa edx=80b18958 esi=e1278800 edi=e129e381
eip=f744a2d2 esp=f789a138 ebp=f789a158 iopl=0 nv up ei pl nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000206
ACPI!PnpiUpdateResourceList:
f744a2d2 55 push ebp
0: kd> dv
ResourceList = 0xe1278800
ResourceDesc = 0xf789a164
0: kd> dx -r1 ((ACPI!_IO_RESOURCE_LIST * *)0xe1278800)
((ACPI!_IO_RESOURCE_LIST * *)0xe1278800) : 0xe1278800 [Type: _IO_RESOURCE_LIST * *]
0xe12a7908 [Type: _IO_RESOURCE_LIST *]
//
// Find the next descriptor to use
//
*ResourceDesc = & ( (*ResourceList)->Descriptors[ (*ResourceList)->Count ] );
0: kd> dv ResourceDesc
ResourceDesc = 0xf789a164
0: kd> dx -r1 ((ACPI!_IO_RESOURCE_DESCRIPTOR * *)0xf789a164)
((ACPI!_IO_RESOURCE_DESCRIPTOR * *)0xf789a164) : 0xf789a164 [Type: _IO_RESOURCE_DESCRIPTOR * *]
0xe12a7930 : No Resource [Type: _IO_RESOURCE_DESCRIPTOR *]
0: kd> dt ACPI!_IO_RESOURCE_LIST 0xe12a7908
+0x000 Version : 1
+0x002 Revision : 1
+0x004 Count : 1
+0x008 Descriptors : [1] _IO_RESOURCE_DESCRIPTOR
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910
+0x000 Option : 0 ''
+0x001 Type : 0x6 ''
+0x002 ShareDisposition : 0x3 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR -v
struct _IO_RESOURCE_DESCRIPTOR, 7 elements, 0x20 bytes
+0x000 Option : UChar
+0x001 Type : UChar
+0x002 ShareDisposition : UChar
+0x003 Spare1 : UChar
+0x004 Flags : Uint2B
+0x006 Spare2 : Uint2B
+0x008 u : union __unnamed, 8 elements, 0x18 bytes
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*2
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*3
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*4
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*5
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*6
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*7
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*8
+0x000 Option : 0x22 '"'
+0x001 Type : 0x8 ''
+0x002 ShareDisposition : 0x2c ','
+0x003 Spare1 : 0x4 ''
+0x004 Flags : 0x624f
+0x006 Spare2 : 0x7153
+0x008 u : __unnamed
//
// Update the count of in-use descriptors
//
(*ResourceList)->Count += 1;
0: kd> dt ACPI!_IO_RESOURCE_LIST 0xe12a7908
+0x000 Version : 1
+0x002 Revision : 1
+0x004 Count : 2
+0x008 Descriptors : [1] _IO_RESOURCE_DESCRIPTOR
//
// Ensure that there is enough space within the chosen list to add the
// resource
//
status = PnpiUpdateResourceList( & (Array[ArrayIndex]), &rangeDescriptor );
if (!NT_SUCCESS(status)) {
return status;
}
0: kd> dv rangeDescriptor
rangeDescriptor = 0xe12a7930 No Resource
//
// If this is I/O or Memory, then we will need to make enough space for
// a device private resource too.
//
if ((buffer->RFlag == PNP_ADDRESS_MEMORY_TYPE) ||
(buffer->RFlag == PNP_ADDRESS_IO_TYPE)) {
status = PnpiUpdateResourceList( & (Array[ArrayIndex]), &privateDescriptor );
if (!NT_SUCCESS(status)) {
return status;
}
0: kd> kc
#
00 ACPI!PnpiUpdateResourceList
01 ACPI!PnpiBiosAddressDoubleToIoDescriptor
02 ACPI!PnpBiosResourcesToNtResources
03 ACPI!ACPIBusIrpQueryResourceRequirements
04 ACPI!ACPIDispatchIrp
05 nt!IofCallDriver
06 nt!IopSynchronousCall
07 nt!PpIrpQueryResourceRequirements
08 nt!PiQueryResourceRequirements
09 nt!PiProcessNewDeviceNode
0a nt!PipProcessDevNodeTree
0b nt!PipDeviceActionWorker
0c nt!PipRequestDeviceAction
0d nt!IopInitializeBootDrivers
0e nt!IoInitSystem
0f nt!Phase1Initialization
10 nt!PspSystemThreadStartup
11 nt!KiThreadStartup
0: kd> dv
ResourceList = 0xe1278800
ResourceDesc = 0xf789a160
0: kd> dx -r1 ((ACPI!_IO_RESOURCE_LIST * *)0xe1278800)
((ACPI!_IO_RESOURCE_LIST * *)0xe1278800) : 0xe1278800 [Type: _IO_RESOURCE_LIST * *]
0xe12a7908 [Type: _IO_RESOURCE_LIST *]
0: kd> gu
eax=00000000 ebx=80ae2bca ecx=f789a160 edx=80b18958 esi=e1278800 edi=e129e381
eip=f744ac0c esp=f789a144 ebp=f789a158 iopl=0 nv up ei pl nz na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000206
ACPI!PnpiBiosAddressDoubleToIoDescriptor+0xa8:
f744ac0c 85c0 test eax,eax
0: kd> dt ACPI!_IO_RESOURCE_LIST 0xe12a7908
+0x000 Version : 1
+0x002 Revision : 1
+0x004 Count : 3
+0x008 Descriptors : [1] _IO_RESOURCE_DESCRIPTOR
0: kd> dv privateDescriptor
privateDescriptor = 0xe12a7950 No Resource
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7950
+0x000 Option : 0 ''
+0x001 Type : 0 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
privateDescriptor->Type = CmResourceTypeDevicePrivate;
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7950
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
#define CmResourceTypeNonArbitrated 128 // Not arbitrated if 0x80 bit set
#define CmResourceTypeConfigData 128 // ResType_Reserved (0x8000)
#define CmResourceTypeDevicePrivate 129 // ResType_DevicePrivate (0x8001)
#define CmResourceTypePcCardConfig 130 // ResType_PcCardConfig (0x8002)
#define CmResourceTypeMfCardConfig 131 // ResType_MfCardConfig (0x8003)
privateDescriptor->Flags = TRANSLATION_DATA_PARENT_ADDRESS;
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7950
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x6000
+0x006 Spare2 : 0
+0x008 u : __unnamed
#define TRANSLATION_RANGE_SPARSE 0x0001
#define TRANSLATION_DATA_PARENT_ADDRESS 0x6000
//
// Fill in the top 32 bits of the start address.
//
privateDescriptor->u.DevicePrivate.Data[2] = 0;
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7950 -r
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x6000
+0x006 Spare2 : 0
+0x008 u : __unnamed
+0x000 Port : __unnamed
+0x000 Length : 0
+0x004 Alignment : 0
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 Memory : __unnamed
+0x000 Length : 0
+0x004 Alignment : 0
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 Interrupt : __unnamed
+0x000 MinimumVector : 0
+0x004 MaximumVector : 0
+0x000 Dma : __unnamed
+0x000 MinimumChannel : 0
+0x004 MaximumChannel : 0
+0x000 Generic : __unnamed
+0x000 Length : 0
+0x004 Alignment : 0
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 DevicePrivate : __unnamed
+0x000 Data : [3] 0
+0x000 BusNumber : __unnamed
+0x000 Length : 0
+0x004 MinBusNumber : 0
+0x008 MaxBusNumber : 0
+0x00c Reserved : 0
+0x000 ConfigData : __unnamed
+0x000 Priority : 0
+0x004 Reserved1 : 0
+0x008 Reserved2 : 0
length = buffer->AddressLength;
alignment = buffer->Granularity + 1;
//
// Calculate the bounds of both the parent and child sides of
// the bridge.
//
// The translation field applies to the parent address i.e.
// the child address is the address in the buffer and the
// parent address is the addition of the child address and
// the translation field.
//
parentMin = buffer->MinimumAddress + buffer->TranslationAddress;
childMin = buffer->MinimumAddress;
childMax = buffer->MaximumAddress;
switch (buffer->RFlag) {
case PNP_ADDRESS_MEMORY_TYPE:
//
// Set the proper ranges
//
rangeDescriptor->u.Memory.Alignment = alignment;
rangeDescriptor->u.Memory.Length = length;
rangeDescriptor->u.Memory.MinimumAddress.LowPart = childMin;
rangeDescriptor->u.Memory.MaximumAddress.LowPart = childMax;
rangeDescriptor->u.Memory.MinimumAddress.HighPart =
rangeDescriptor->u.Memory.MaximumAddress.HighPart = 0;
rangeDescriptor->Type = CmResourceTypeMemory;
typedef enum _CM_RESOURCE_TYPE {
CmResourceTypeNull = 0, // Reserved
CmResourceTypePort, 1
CmResourceTypeInterrupt, 2
CmResourceTypeMemory, 3
CmResourceTypeDma, 4
CmResourceTypeDeviceSpecific
} CM_RESOURCE_TYPE;
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20 -r
+0x000 Option : 0 ''
+0x001 Type : 0x3 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : __unnamed
+0x000 Port : __unnamed
+0x000 Length : 0x20000
+0x004 Alignment : 1
+0x008 MinimumAddress : _LARGE_INTEGER 0xa0000
+0x010 MaximumAddress : _LARGE_INTEGER 0xbffff
+0x000 Memory : __unnamed
+0x000 Length : 0x20000
+0x004 Alignment : 1
+0x008 MinimumAddress : _LARGE_INTEGER 0xa0000
+0x010 MaximumAddress : _LARGE_INTEGER 0xbffff
+0x000 Interrupt : __unnamed
+0x000 MinimumVector : 0x20000
+0x004 MaximumVector : 1
+0x000 Dma : __unnamed
+0x000 MinimumChannel : 0x20000
+0x004 MaximumChannel : 1
+0x000 Generic : __unnamed
+0x000 Length : 0x20000
+0x004 Alignment : 1
+0x008 MinimumAddress : _LARGE_INTEGER 0xa0000
+0x010 MaximumAddress : _LARGE_INTEGER 0xbffff
+0x000 DevicePrivate : __unnamed
+0x000 Data : [3] 0x20000
+0x000 BusNumber : __unnamed
+0x000 Length : 0x20000
+0x004 MinBusNumber : 1
+0x008 MaxBusNumber : 0xa0000
+0x00c Reserved : 0
+0x000 ConfigData : __unnamed
+0x000 Priority : 0x20000
+0x004 Reserved1 : 1
+0x008 Reserved2 : 0xa0000
if (buffer->TFlag & TRANSLATION_MEM_TO_IO) {
//
// The device private describes the parent. With this
// flag set, the descriptor type of the parent will
// changed from Memory to IO.
//
privateDescriptor->u.DevicePrivate.Data[0] =
CmResourceTypePort;
} else {
//
// The parent descriptor type will not change.
//
privateDescriptor->u.DevicePrivate.Data[0] =
CmResourceTypeMemory;
}
0: kd> dd 0xe12a7910+20*2
e12a7950 00008100 00006000 00000003 000a0000
e12a7960 00000000 00000000 00000000 00000000
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*2 -r
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x6000
+0x006 Spare2 : 0
+0x008 u : __unnamed
+0x000 Port : __unnamed
+0x000 Length : 3
+0x004 Alignment : 0xa0000
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 Memory : __unnamed
+0x000 Length : 3
+0x004 Alignment : 0xa0000
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 Interrupt : __unnamed
+0x000 MinimumVector : 3
+0x004 MaximumVector : 0xa0000
+0x000 Dma : __unnamed
+0x000 MinimumChannel : 3
+0x004 MaximumChannel : 0xa0000
+0x000 Generic : __unnamed
+0x000 Length : 3
+0x004 Alignment : 0xa0000
+0x008 MinimumAddress : _LARGE_INTEGER 0x0
+0x010 MaximumAddress : _LARGE_INTEGER 0x0
+0x000 DevicePrivate : __unnamed
+0x000 Data : [3] 3
+0x000 BusNumber : __unnamed
+0x000 Length : 3
+0x004 MinBusNumber : 0xa0000
+0x008 MaxBusNumber : 0
+0x00c Reserved : 0
+0x000 ConfigData : __unnamed
+0x000 Priority : 3
+0x004 Reserved1 : 0xa0000
+0x008 Reserved2 : 0
0: kd> dx -id 0,0,899a2278 -r1 (*((ACPI!unsigned long (*)[3])0xe12a7958))
(*((ACPI!unsigned long (*)[3])0xe12a7958)) [Type: unsigned long [3]]
[0] : 0x3 [Type: unsigned long]
[1] : 0xa0000 [Type: unsigned long]
[2] : 0x0 [Type: unsigned long]
回顾:parentMin
parentMin = buffer->MinimumAddress + buffer->TranslationAddress;
childMin = buffer->MinimumAddress;
childMax = buffer->MaximumAddress;
回顾结束:
//
// Handle global flags
//
PnpiBiosAddressHandleGlobalFlags( buffer, rangeDescriptor );
return STATUS_SUCCESS;
}
VOID
PnpiBiosAddressHandleGlobalFlags(
IN PVOID Buffer,
IN PIO_RESOURCE_DESCRIPTOR Descriptor
)
{
} else {
Descriptor->ShareDisposition = CmResourceShareShared;
}
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20
+0x000 Option : 0 ''
+0x001 Type : 0x3 ''
+0x002 ShareDisposition : 0x3 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x20
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dt ACPI!_IO_RESOURCE_DESCRIPTOR 0xe12a7910+20*2
+0x000 Option : 0 ''
+0x001 Type : 0x81 ''
+0x002 ShareDisposition : 0 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0x6000
+0x006 Spare2 : 0
+0x008 u : __unnamed
0: kd> dx -id 0,0,899a2278 -r1 (*((ACPI!unsigned long (*)[3])0xe12a7958))
(*((ACPI!unsigned long (*)[3])0xe12a7958)) [Type: unsigned long [3]]
[0] : 0x3 [Type: unsigned long]
[1] : 0xa0000 [Type: unsigned long]
[2] : 0x0 [Type: unsigned long]