1394 lines
40 KiB
C
1394 lines
40 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1990, 1991 Microsoft Corporation
|
|||
|
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
hwdetect.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This is the main hardware detection module. Its main function is
|
|||
|
to detect various system hardware and build a configuration tree.
|
|||
|
|
|||
|
N.B. The configuration built in the detection module will needs to
|
|||
|
be adjusted later before we switch to FLAT mode. The is because
|
|||
|
all the "POINTER" is a far pointer instead of a flat pointer.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Shie-Lin Tzong (shielint) 16-Jan-92
|
|||
|
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Real mode.
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "hwdetect.h"
|
|||
|
#include "pci.h"
|
|||
|
#include <string.h>
|
|||
|
#include "apm.h"
|
|||
|
|
|||
|
|
|||
|
#if DBG
|
|||
|
|
|||
|
PUCHAR TypeName[] = {
|
|||
|
"ArcSystem",
|
|||
|
"CentralProcessor",
|
|||
|
"FloatingPointProcessor",
|
|||
|
"PrimaryICache",
|
|||
|
"PrimaryDCache",
|
|||
|
"SecondaryICache",
|
|||
|
"SecondaryDCache",
|
|||
|
"SecondaryCache",
|
|||
|
"EisaAdapter",
|
|||
|
"TcaAdapter",
|
|||
|
"ScsiAdapter",
|
|||
|
"DtiAdapter",
|
|||
|
"MultifunctionAapter",
|
|||
|
"DiskController",
|
|||
|
"TapeController",
|
|||
|
"CdRomController",
|
|||
|
"WormController",
|
|||
|
"SerialController",
|
|||
|
"NetworkController",
|
|||
|
"DisplayController",
|
|||
|
"ParallelController",
|
|||
|
"PointerController",
|
|||
|
"KeyboardController",
|
|||
|
"AudioController",
|
|||
|
"OtherController",
|
|||
|
"DiskPeripheral",
|
|||
|
"FloppyDiskPeripheral",
|
|||
|
"TapePeripheral",
|
|||
|
"ModemPeripheral",
|
|||
|
"MonitorPeripheral",
|
|||
|
"PrinterPeraipheral",
|
|||
|
"PointerPeripheral",
|
|||
|
"KeyboardPeripheral",
|
|||
|
"TerminalPeripheral",
|
|||
|
"OtherPeripheral",
|
|||
|
"LinePeripheral",
|
|||
|
"NetworkPeripheral",
|
|||
|
"SystemMemory",
|
|||
|
"MaximumType"
|
|||
|
};
|
|||
|
|
|||
|
VOID
|
|||
|
CheckConfigurationTree(
|
|||
|
FPFWCONFIGURATION_COMPONENT_DATA CurrentEntry
|
|||
|
);
|
|||
|
|
|||
|
extern
|
|||
|
USHORT
|
|||
|
HwGetKey(
|
|||
|
VOID
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
VOID
|
|||
|
GetIrqFromEisaData(
|
|||
|
FPFWCONFIGURATION_COMPONENT_DATA ControllerList,
|
|||
|
CONFIGURATION_TYPE ControllerType
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// HwBusType - defines the BUS type of the machine.
|
|||
|
// This variable is used by detection code only.
|
|||
|
//
|
|||
|
|
|||
|
USHORT HwBusType = 0;
|
|||
|
|
|||
|
//
|
|||
|
// AdapterEntry is the Configuration_Component_data for the bus adapter
|
|||
|
//
|
|||
|
|
|||
|
FPFWCONFIGURATION_COMPONENT_DATA AdapterEntry = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// FpRomBlock - A far pointer to our Rom Block
|
|||
|
//
|
|||
|
|
|||
|
FPUCHAR FpRomBlock = NULL;
|
|||
|
USHORT RomBlockLength = 0;
|
|||
|
|
|||
|
//
|
|||
|
// HwMcaPosData - A far pointer to the POS data block of MCA machine
|
|||
|
//
|
|||
|
|
|||
|
FPMCA_POS_DATA HwMcaPosData;
|
|||
|
|
|||
|
//
|
|||
|
// HwEisaConfigurationData - A far pointer to the EISA configuration
|
|||
|
// data on EISA machine.
|
|||
|
//
|
|||
|
|
|||
|
FPUCHAR HwEisaConfigurationData = NULL;
|
|||
|
ULONG HwEisaConfigurationSize = 0L;
|
|||
|
|
|||
|
//
|
|||
|
// DisableSerialMice - A bit flags to indicate the comports whose serial
|
|||
|
// mouse detection should be skipped.
|
|||
|
//
|
|||
|
|
|||
|
USHORT DisableSerialMice = 0x0;
|
|||
|
|
|||
|
//
|
|||
|
// Internal references and definitions.
|
|||
|
//
|
|||
|
|
|||
|
typedef enum _RELATIONSHIP_FLAGS {
|
|||
|
Child,
|
|||
|
Sibling,
|
|||
|
Parent
|
|||
|
} RELATIONSHIP_FLAGS;
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
HardwareDetection(
|
|||
|
ULONG HeapStart,
|
|||
|
ULONG HeapSize,
|
|||
|
ULONG ConfigurationTree,
|
|||
|
ULONG HeapUsed,
|
|||
|
ULONG OptionString,
|
|||
|
ULONG OptionStringLength
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Main entrypoint of the HW recognizer test. The routine builds
|
|||
|
a configuration tree and leaves it in the hardware heap.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HeapStart - Supplies the starting address of the configuaration heap.
|
|||
|
|
|||
|
HeapSize - Supplies the size of the heap in byte.
|
|||
|
|
|||
|
ConfigurationTree - Supplies a 32 bit FLAT address of the variable to
|
|||
|
receive the hardware configuration tree.
|
|||
|
|
|||
|
HeapUsed - Supplies a 32 bit FLAT address of the variable to receive
|
|||
|
the actual heap size in used.
|
|||
|
|
|||
|
OptionString - Supplies a 32 bit FLAT address of load option string.
|
|||
|
|
|||
|
OptionStringLength - Supplies the length of the OptionString
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
FPFWCONFIGURATION_COMPONENT_DATA ConfigurationRoot;
|
|||
|
FPFWCONFIGURATION_COMPONENT_DATA FirstCom = NULL, FirstLpt = NULL;
|
|||
|
FPFWCONFIGURATION_COMPONENT_DATA CurrentEntry, PreviousEntry;
|
|||
|
FPFWCONFIGURATION_COMPONENT Component;
|
|||
|
RELATIONSHIP_FLAGS NextRelationship;
|
|||
|
CHAR Identifier[256];
|
|||
|
USHORT BiosYear, BiosMonth, BiosDay;
|
|||
|
PUCHAR MachineId;
|
|||
|
USHORT Length, InitialLength, i, Count = 0;
|
|||
|
FPCHAR IdentifierString;
|
|||
|
PMOUSE_INFORMATION MouseInfo = 0;
|
|||
|
USHORT KeyboardId = 0;
|
|||
|
ULONG VideoAdapterType = 0;
|
|||
|
FPULONG BlConfigurationTree = NULL;
|
|||
|
FPULONG BlHeapUsed = NULL;
|
|||
|
FPCHAR BlOptions, EndOptions;
|
|||
|
PUCHAR RomChain;
|
|||
|
FPUCHAR FpRomChain = NULL, ConfigurationData, EndConfigurationData;
|
|||
|
SHORT FreeSize;
|
|||
|
FPHWPARTIAL_RESOURCE_DESCRIPTOR Descriptor;
|
|||
|
FPHWRESOURCE_DESCRIPTOR_LIST DescriptorList;
|
|||
|
PCI_REGISTRY_INFO PciEntry;
|
|||
|
APM_REGISTRY_INFO ApmEntry;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// First initialize our hardware heap.
|
|||
|
//
|
|||
|
|
|||
|
HwInitializeHeap(HeapStart, HeapSize);
|
|||
|
|
|||
|
MAKE_FP(BlConfigurationTree, ConfigurationTree);
|
|||
|
MAKE_FP(BlHeapUsed, HeapUsed);
|
|||
|
MAKE_FP(BlOptions, OptionString);
|
|||
|
|
|||
|
//
|
|||
|
// Parse OptionString and see if we need to disable serial mice detection.
|
|||
|
//
|
|||
|
|
|||
|
if (BlOptions && OptionStringLength <= 0x1000L && OptionStringLength > 0L) {
|
|||
|
EndOptions = BlOptions + OptionStringLength;
|
|||
|
if (*EndOptions == '\0') {
|
|||
|
do {
|
|||
|
if (BlOptions = _fstrstr(BlOptions, "NOSERIALMICE")) {
|
|||
|
BlOptions += strlen("NOSERIALMICE");
|
|||
|
while ((*BlOptions == ' ') || (*BlOptions == ':') ||
|
|||
|
(*BlOptions == '=')) {
|
|||
|
BlOptions++;
|
|||
|
}
|
|||
|
if (*BlOptions == 'C' && BlOptions[1] == 'O' &&
|
|||
|
BlOptions[2] == 'M') {
|
|||
|
BlOptions += 3;
|
|||
|
while (TRUE) {
|
|||
|
while (*BlOptions != '\0' && (*BlOptions == ' ' ||
|
|||
|
*BlOptions == ',' || *BlOptions == ';' ||
|
|||
|
*BlOptions == '0')) {
|
|||
|
BlOptions++;
|
|||
|
}
|
|||
|
if (*BlOptions >= '0' && *BlOptions <= '9') {
|
|||
|
if (BlOptions[1] < '0' || BlOptions[1] > '9') {
|
|||
|
DisableSerialMice |= 1 << (*BlOptions - '0');
|
|||
|
BlOptions++;
|
|||
|
} else {
|
|||
|
BlOptions++;
|
|||
|
while (*BlOptions && *BlOptions <= '9' &&
|
|||
|
*BlOptions >= '0') {
|
|||
|
BlOptions++;
|
|||
|
}
|
|||
|
}
|
|||
|
}else {
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
DisableSerialMice = 0xffff;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
} while (BlOptions && *BlOptions && (BlOptions < EndOptions)); // double checking
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Determine bus type
|
|||
|
//
|
|||
|
|
|||
|
if (HwIsEisaSystem()) {
|
|||
|
HwBusType = MACHINE_TYPE_EISA;
|
|||
|
} else if (HwIsMcaSystem()) {
|
|||
|
HwBusType = MACHINE_TYPE_MCA;
|
|||
|
} else {
|
|||
|
HwBusType = MACHINE_TYPE_ISA;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Allocate heap space for System component and initialize it.
|
|||
|
// Also make the System component the root of configuration tree.
|
|||
|
//
|
|||
|
|
|||
|
#if DBG
|
|||
|
clrscrn ();
|
|||
|
BlPrint("Detecting System Component ...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
ConfigurationRoot = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
|
|||
|
sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
|
|||
|
Component = &ConfigurationRoot->ComponentEntry;
|
|||
|
|
|||
|
Component->Class = SystemClass;
|
|||
|
Component->Type = MaximumType; // NOTE should be IsaCompatible
|
|||
|
Component->Version = 0;
|
|||
|
Component->Key = 0;
|
|||
|
Component->AffinityMask = 0;
|
|||
|
Component->ConfigurationDataLength = 0;
|
|||
|
MachineId = GetMachineId();
|
|||
|
if (MachineId) {
|
|||
|
Length = strlen(MachineId) + 1;
|
|||
|
IdentifierString = (FPCHAR)HwAllocateHeap(Length, FALSE);
|
|||
|
_fstrcpy(IdentifierString, MachineId);
|
|||
|
Component->Identifier = IdentifierString;
|
|||
|
Component->IdentifierLength = Length;
|
|||
|
} else {
|
|||
|
Component->Identifier = 0;
|
|||
|
Component->IdentifierLength = 0;
|
|||
|
}
|
|||
|
NextRelationship = Child;
|
|||
|
PreviousEntry = ConfigurationRoot;
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Reading BIOS date ...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
HwGetBiosDate (0xF0000, 0xFFFF, &BiosYear, &BiosMonth, &BiosDay);
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Done reading BIOS date (%d/%d/%d)\n",
|
|||
|
BiosMonth, BiosDay, BiosYear);
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Detecting PCI Bus Component ...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
if (BiosYear > 1992 || (BiosYear == 1992 && BiosMonth >= 11) ) {
|
|||
|
|
|||
|
// Bios date valid for pci presence check..
|
|||
|
HwGetPciSystemData((PVOID) &PciEntry, TRUE);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
// Bios date not confirmed...
|
|||
|
HwGetPciSystemData((PVOID) &PciEntry, FALSE);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Add a registry entry for each PCI bus
|
|||
|
//
|
|||
|
|
|||
|
for (i=0; i < PciEntry.NoBuses; i++) {
|
|||
|
|
|||
|
AdapterEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
|
|||
|
sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
|
|||
|
|
|||
|
Component = &AdapterEntry->ComponentEntry;
|
|||
|
Component->Class = AdapterClass;
|
|||
|
Component->Type = MultiFunctionAdapter;
|
|||
|
|
|||
|
strcpy (Identifier, "PCI");
|
|||
|
Length = strlen(Identifier) + 1;
|
|||
|
IdentifierString = (FPCHAR)HwAllocateHeap(Length, FALSE);
|
|||
|
_fstrcpy(IdentifierString, Identifier);
|
|||
|
|
|||
|
Component->Version = 0;
|
|||
|
Component->Key = 0;
|
|||
|
Component->AffinityMask = 0xffffffff;
|
|||
|
Component->IdentifierLength = Length;
|
|||
|
Component->Identifier = IdentifierString;
|
|||
|
|
|||
|
AdapterEntry->ConfigurationData = NULL;
|
|||
|
Component->ConfigurationDataLength = 0;
|
|||
|
|
|||
|
if (i == 0) {
|
|||
|
//
|
|||
|
// For the first PCI bus include the PCI_REGISTRY_INFO
|
|||
|
//
|
|||
|
|
|||
|
Length = sizeof(PCI_REGISTRY_INFO) + DATA_HEADER_SIZE;
|
|||
|
ConfigurationData = (FPUCHAR) HwAllocateHeap(Length, TRUE);
|
|||
|
|
|||
|
Component->ConfigurationDataLength = Length;
|
|||
|
AdapterEntry->ConfigurationData = ConfigurationData;
|
|||
|
|
|||
|
_fmemcpy ( ((FPUCHAR) ConfigurationData+DATA_HEADER_SIZE),
|
|||
|
(FPVOID) &PciEntry, sizeof (PCI_REGISTRY_INFO));
|
|||
|
|
|||
|
HwSetUpFreeFormDataHeader(
|
|||
|
(FPHWRESOURCE_DESCRIPTOR_LIST) ConfigurationData,
|
|||
|
0,
|
|||
|
0,
|
|||
|
0,
|
|||
|
Length - DATA_HEADER_SIZE
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Add it to tree
|
|||
|
//
|
|||
|
|
|||
|
if (NextRelationship == Sibling) {
|
|||
|
PreviousEntry->Sibling = AdapterEntry;
|
|||
|
AdapterEntry->Parent = PreviousEntry->Parent;
|
|||
|
} else {
|
|||
|
PreviousEntry->Child = AdapterEntry;
|
|||
|
AdapterEntry->Parent = PreviousEntry;
|
|||
|
}
|
|||
|
|
|||
|
NextRelationship = Sibling;
|
|||
|
PreviousEntry = AdapterEntry;
|
|||
|
}
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Detecting PCI Bus Component completes ...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
#if _PNP_POWER_
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Detecting APM Bus Component ...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
if (HwGetApmSystemData((PVOID) &ApmEntry)) {
|
|||
|
AdapterEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
|
|||
|
sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
|
|||
|
|
|||
|
Component = &AdapterEntry->ComponentEntry;
|
|||
|
Component->Class = AdapterClass;
|
|||
|
Component->Type = MultiFunctionAdapter;
|
|||
|
|
|||
|
strcpy (Identifier, "APM");
|
|||
|
Length = strlen(Identifier) + 1;
|
|||
|
IdentifierString = (FPCHAR)HwAllocateHeap(Length, FALSE);
|
|||
|
_fstrcpy(IdentifierString, Identifier);
|
|||
|
|
|||
|
Component->Version = 0;
|
|||
|
Component->Key = 0;
|
|||
|
Component->AffinityMask = 0xffffffff;
|
|||
|
Component->IdentifierLength = Length;
|
|||
|
Component->Identifier = IdentifierString;
|
|||
|
|
|||
|
AdapterEntry->ConfigurationData = NULL;
|
|||
|
Component->ConfigurationDataLength = 0;
|
|||
|
|
|||
|
//
|
|||
|
|
|||
|
Length = sizeof(APM_REGISTRY_INFO) + DATA_HEADER_SIZE;
|
|||
|
ConfigurationData = (FPUCHAR) HwAllocateHeap(Length, TRUE);
|
|||
|
|
|||
|
Component->ConfigurationDataLength = Length;
|
|||
|
AdapterEntry->ConfigurationData = ConfigurationData;
|
|||
|
|
|||
|
_fmemcpy ( ((FPUCHAR) ConfigurationData+DATA_HEADER_SIZE),
|
|||
|
(FPVOID) &ApmEntry, sizeof (APM_REGISTRY_INFO));
|
|||
|
|
|||
|
HwSetUpFreeFormDataHeader(
|
|||
|
(FPHWRESOURCE_DESCRIPTOR_LIST) ConfigurationData,
|
|||
|
0,
|
|||
|
0,
|
|||
|
0,
|
|||
|
Length - DATA_HEADER_SIZE
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// Add it to tree
|
|||
|
//
|
|||
|
|
|||
|
if (NextRelationship == Sibling) {
|
|||
|
PreviousEntry->Sibling = AdapterEntry;
|
|||
|
AdapterEntry->Parent = PreviousEntry->Parent;
|
|||
|
} else {
|
|||
|
PreviousEntry->Child = AdapterEntry;
|
|||
|
AdapterEntry->Parent = PreviousEntry;
|
|||
|
}
|
|||
|
|
|||
|
NextRelationship = Sibling;
|
|||
|
PreviousEntry = AdapterEntry;
|
|||
|
}
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("APM Data collection complete...\n");
|
|||
|
#endif // DBG
|
|||
|
|
|||
|
#endif // _PNP_POWER_
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Detecting PnP BIOS Bus Component ...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
if (HwGetPnpBiosSystemData(&ConfigurationData, &Length)) {
|
|||
|
AdapterEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
|
|||
|
sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
|
|||
|
|
|||
|
AdapterEntry->ConfigurationData = ConfigurationData;
|
|||
|
Component = &AdapterEntry->ComponentEntry;
|
|||
|
Component->ConfigurationDataLength = Length;
|
|||
|
|
|||
|
Component->Class = AdapterClass;
|
|||
|
Component->Type = MultiFunctionAdapter;
|
|||
|
|
|||
|
strcpy (Identifier, "PNP BIOS");
|
|||
|
i = strlen(Identifier) + 1;
|
|||
|
IdentifierString = (FPCHAR)HwAllocateHeap(i, FALSE);
|
|||
|
_fstrcpy(IdentifierString, Identifier);
|
|||
|
|
|||
|
Component->Version = 0;
|
|||
|
Component->Key = 0;
|
|||
|
Component->AffinityMask = 0xffffffff;
|
|||
|
Component->IdentifierLength = i;
|
|||
|
Component->Identifier = IdentifierString;
|
|||
|
|
|||
|
HwSetUpFreeFormDataHeader(
|
|||
|
(FPHWRESOURCE_DESCRIPTOR_LIST) ConfigurationData,
|
|||
|
0,
|
|||
|
0,
|
|||
|
0,
|
|||
|
Length - DATA_HEADER_SIZE
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// Add it to tree
|
|||
|
//
|
|||
|
|
|||
|
if (NextRelationship == Sibling) {
|
|||
|
PreviousEntry->Sibling = AdapterEntry;
|
|||
|
AdapterEntry->Parent = PreviousEntry->Parent;
|
|||
|
} else {
|
|||
|
PreviousEntry->Child = AdapterEntry;
|
|||
|
AdapterEntry->Parent = PreviousEntry;
|
|||
|
}
|
|||
|
|
|||
|
NextRelationship = Sibling;
|
|||
|
PreviousEntry = AdapterEntry;
|
|||
|
}
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("PnP BIOS Data collection complete...\n");
|
|||
|
#endif // DBG
|
|||
|
|
|||
|
//
|
|||
|
// Allocate heap space for Bus component and initialize it.
|
|||
|
//
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Detecting Bus/Adapter Component ...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
AdapterEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap (
|
|||
|
sizeof(FWCONFIGURATION_COMPONENT_DATA), TRUE);
|
|||
|
|
|||
|
Component = &AdapterEntry->ComponentEntry;
|
|||
|
|
|||
|
Component->Class = AdapterClass;
|
|||
|
|
|||
|
//
|
|||
|
// The assumption here is that the machine has only one
|
|||
|
// type of IO bus. If a machine has more than one types of
|
|||
|
// IO buses, it will not use this detection code anyway.
|
|||
|
//
|
|||
|
|
|||
|
if (HwBusType == MACHINE_TYPE_EISA) {
|
|||
|
|
|||
|
//
|
|||
|
// Note We don't collect EISA config data here. Because we may
|
|||
|
// exhaust the heap space. We will collect the data after all
|
|||
|
// the other components are detected.
|
|||
|
//
|
|||
|
|
|||
|
Component->Type = EisaAdapter;
|
|||
|
strcpy(Identifier, "EISA");
|
|||
|
AdapterEntry->ConfigurationData = NULL;
|
|||
|
Component->ConfigurationDataLength = 0;
|
|||
|
|
|||
|
} else if (HwBusType == MACHINE_TYPE_MCA) {
|
|||
|
|
|||
|
Component->Type = MultiFunctionAdapter;
|
|||
|
strcpy(Identifier, "MCA");
|
|||
|
GetMcaPosData(&AdapterEntry->ConfigurationData,
|
|||
|
&Component->ConfigurationDataLength);
|
|||
|
HwMcaPosData = (FPMCA_POS_DATA)
|
|||
|
((FPUCHAR)AdapterEntry->ConfigurationData + DATA_HEADER_SIZE);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// If not EISA or MCA, it must be ISA
|
|||
|
//
|
|||
|
|
|||
|
Component->Type = MultiFunctionAdapter;
|
|||
|
strcpy(Identifier, "ISA");
|
|||
|
}
|
|||
|
Length = strlen(Identifier) + 1;
|
|||
|
IdentifierString = (FPCHAR)HwAllocateHeap(Length, FALSE);
|
|||
|
_fstrcpy(IdentifierString, Identifier);
|
|||
|
Component->Version = 0;
|
|||
|
Component->Key = 0;
|
|||
|
Component->AffinityMask = 0xffffffff;
|
|||
|
Component->IdentifierLength = Length;
|
|||
|
Component->Identifier = IdentifierString;
|
|||
|
|
|||
|
//
|
|||
|
// Make Adapter component System's child
|
|||
|
//
|
|||
|
|
|||
|
if (NextRelationship == Sibling) {
|
|||
|
PreviousEntry->Sibling = AdapterEntry;
|
|||
|
AdapterEntry->Parent = PreviousEntry->Parent;
|
|||
|
} else {
|
|||
|
PreviousEntry->Child = AdapterEntry;
|
|||
|
AdapterEntry->Parent = PreviousEntry;
|
|||
|
}
|
|||
|
NextRelationship = Child;
|
|||
|
PreviousEntry = AdapterEntry;
|
|||
|
|
|||
|
//
|
|||
|
// Collect BIOS information for ConfigurationRoot component.
|
|||
|
// This step is done here because we need data collected in
|
|||
|
// adapter component. The ConfigurationData is:
|
|||
|
// HWRESOURCE_DESCRIPTOR_LIST header
|
|||
|
// HWPARTIAL_RESOURCE_DESCRIPTOR for Parameter Table
|
|||
|
// HWPARTIAL_RESOURCE_DESCRIPTOR for Rom Blocks.
|
|||
|
// (Note DATA_HEADER_SIZE contains the size of the first partial
|
|||
|
// descriptor already.)
|
|||
|
//
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Collecting Disk Geometry...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
GetInt13DriveParameters((PVOID)&RomChain, &Length);
|
|||
|
InitialLength = (USHORT)(Length + RESERVED_ROM_BLOCK_LIST_SIZE + DATA_HEADER_SIZE +
|
|||
|
sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR));
|
|||
|
ConfigurationData = (FPUCHAR)HwAllocateHeap(InitialLength, FALSE);
|
|||
|
EndConfigurationData = ConfigurationData + DATA_HEADER_SIZE;
|
|||
|
if (Length != 0) {
|
|||
|
FpRomChain = EndConfigurationData;
|
|||
|
_fmemcpy(FpRomChain, (FPVOID)RomChain, Length);
|
|||
|
}
|
|||
|
EndConfigurationData += (sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR) +
|
|||
|
Length);
|
|||
|
HwSetUpFreeFormDataHeader((FPHWRESOURCE_DESCRIPTOR_LIST)ConfigurationData,
|
|||
|
0,
|
|||
|
0,
|
|||
|
0,
|
|||
|
Length
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// Scan ROM to collect all the ROM blocks, if possible.
|
|||
|
//
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Detecting ROM Blocks...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
FpRomBlock = EndConfigurationData;
|
|||
|
GetRomBlocks(FpRomBlock, &Length);
|
|||
|
RomBlockLength = Length;
|
|||
|
if (Length != 0) {
|
|||
|
EndConfigurationData += Length;
|
|||
|
} else {
|
|||
|
FpRomBlock = NULL;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// We have both RomChain and RomBlock information/Headers.
|
|||
|
//
|
|||
|
|
|||
|
DescriptorList = (FPHWRESOURCE_DESCRIPTOR_LIST)ConfigurationData;
|
|||
|
DescriptorList->Count = 2;
|
|||
|
Descriptor = (FPHWPARTIAL_RESOURCE_DESCRIPTOR)(
|
|||
|
EndConfigurationData - Length -
|
|||
|
sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR));
|
|||
|
Descriptor->Type = RESOURCE_DEVICE_DATA;
|
|||
|
Descriptor->ShareDisposition = 0;
|
|||
|
Descriptor->Flags = 0;
|
|||
|
Descriptor->u.DeviceSpecificData.DataSize = (ULONG)Length;
|
|||
|
Descriptor->u.DeviceSpecificData.Reserved1 = 0;
|
|||
|
Descriptor->u.DeviceSpecificData.Reserved2 = 0;
|
|||
|
|
|||
|
Length = (USHORT)(MAKE_FLAT_ADDRESS(EndConfigurationData) -
|
|||
|
MAKE_FLAT_ADDRESS(ConfigurationData));
|
|||
|
ConfigurationRoot->ComponentEntry.ConfigurationDataLength = Length;
|
|||
|
ConfigurationRoot->ConfigurationData = ConfigurationData;
|
|||
|
FreeSize = InitialLength - Length;
|
|||
|
|
|||
|
HwFreeHeap((ULONG)FreeSize);
|
|||
|
|
|||
|
//
|
|||
|
// Set up device information structure for Keyboard.
|
|||
|
//
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Detecting Keyboard Component ...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
KeyboardId = GetKeyboardId();
|
|||
|
|
|||
|
CurrentEntry = SetKeyboardConfigurationData(KeyboardId);
|
|||
|
|
|||
|
//
|
|||
|
// Make display component the child of Adapter component.
|
|||
|
//
|
|||
|
|
|||
|
if (NextRelationship == Sibling) {
|
|||
|
PreviousEntry->Sibling = CurrentEntry;
|
|||
|
CurrentEntry->Parent = PreviousEntry->Parent;
|
|||
|
} else {
|
|||
|
PreviousEntry->Child = CurrentEntry;
|
|||
|
CurrentEntry->Parent = PreviousEntry;
|
|||
|
}
|
|||
|
NextRelationship = Sibling;
|
|||
|
PreviousEntry = CurrentEntry;
|
|||
|
|
|||
|
//
|
|||
|
// Set up device information for com port (Each COM component
|
|||
|
// is treated as a controller class.)
|
|||
|
//
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Detecting ComPort Component ...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
if (CurrentEntry = GetComportInformation()) {
|
|||
|
|
|||
|
FirstCom = CurrentEntry;
|
|||
|
|
|||
|
//
|
|||
|
// Make current component the child of Adapter component.
|
|||
|
//
|
|||
|
|
|||
|
if (NextRelationship == Sibling) {
|
|||
|
PreviousEntry->Sibling = CurrentEntry;
|
|||
|
} else {
|
|||
|
PreviousEntry->Child = CurrentEntry;
|
|||
|
}
|
|||
|
while (CurrentEntry) {
|
|||
|
CurrentEntry->Parent = AdapterEntry;
|
|||
|
PreviousEntry = CurrentEntry;
|
|||
|
CurrentEntry = CurrentEntry->Sibling;
|
|||
|
}
|
|||
|
NextRelationship = Sibling;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set up device information for parallel port. (Each parallel
|
|||
|
// is treated as a controller class.)
|
|||
|
//
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Detecting Parallel Component ...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
if (CurrentEntry = GetLptInformation()) {
|
|||
|
|
|||
|
FirstLpt = CurrentEntry;
|
|||
|
|
|||
|
//
|
|||
|
// Make current component the child of Adapter component.
|
|||
|
//
|
|||
|
|
|||
|
if (NextRelationship == Sibling) {
|
|||
|
PreviousEntry->Sibling = CurrentEntry;
|
|||
|
CurrentEntry->Parent = PreviousEntry->Parent;
|
|||
|
} else {
|
|||
|
PreviousEntry->Child = CurrentEntry;
|
|||
|
CurrentEntry->Parent = PreviousEntry;
|
|||
|
}
|
|||
|
PreviousEntry = CurrentEntry;
|
|||
|
CurrentEntry = CurrentEntry->Sibling;
|
|||
|
while (CurrentEntry) {
|
|||
|
CurrentEntry->Parent = PreviousEntry->Parent;
|
|||
|
PreviousEntry = CurrentEntry;
|
|||
|
CurrentEntry = CurrentEntry->Sibling;
|
|||
|
}
|
|||
|
NextRelationship = Sibling;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set up device information structure for Mouse.
|
|||
|
//
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Detecting Mouse Component ...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
if (CurrentEntry = GetMouseInformation()) {
|
|||
|
|
|||
|
//
|
|||
|
// Make current component the child of Adapter component.
|
|||
|
//
|
|||
|
|
|||
|
if (NextRelationship == Sibling) {
|
|||
|
PreviousEntry->Sibling = CurrentEntry;
|
|||
|
CurrentEntry->Parent = PreviousEntry->Parent;
|
|||
|
} else {
|
|||
|
PreviousEntry->Child = CurrentEntry;
|
|||
|
CurrentEntry->Parent = PreviousEntry;
|
|||
|
}
|
|||
|
PreviousEntry = CurrentEntry;
|
|||
|
CurrentEntry = CurrentEntry->Sibling;
|
|||
|
while (CurrentEntry) {
|
|||
|
CurrentEntry->Parent = PreviousEntry->Parent;
|
|||
|
PreviousEntry = CurrentEntry;
|
|||
|
CurrentEntry = CurrentEntry->Sibling;
|
|||
|
}
|
|||
|
NextRelationship = Sibling;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set up device information for floppy drives. (The returned information
|
|||
|
// is a tree structure.)
|
|||
|
//
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Detecting Floppy Component ...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
if (CurrentEntry = GetFloppyInformation()) {
|
|||
|
|
|||
|
//
|
|||
|
// Make current component the child of Adapter component.
|
|||
|
//
|
|||
|
|
|||
|
if (NextRelationship == Sibling) {
|
|||
|
PreviousEntry->Sibling = CurrentEntry;
|
|||
|
} else {
|
|||
|
PreviousEntry->Child = CurrentEntry;
|
|||
|
}
|
|||
|
while (CurrentEntry) {
|
|||
|
CurrentEntry->Parent = AdapterEntry;
|
|||
|
PreviousEntry = CurrentEntry;
|
|||
|
CurrentEntry = CurrentEntry->Sibling;
|
|||
|
}
|
|||
|
NextRelationship = Sibling;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set up device information structure for Video Display Adapter.
|
|||
|
//
|
|||
|
|
|||
|
#if DBG
|
|||
|
BlPrint("Detection done. Press a key to display hardware info ...\n");
|
|||
|
while ( ! HwGetKey ());
|
|||
|
clrscrn ();
|
|||
|
// BlPrint("Detecting Video Component ...\n");
|
|||
|
#endif
|
|||
|
|
|||
|
#if 0 // Remove video detection
|
|||
|
if (VideoAdapterType = GetVideoAdapterType()) {
|
|||
|
|
|||
|
CurrentEntry = SetVideoConfigurationData(VideoAdapterType);
|
|||
|
|
|||
|
//
|
|||
|
// Make display component the child of Adapter component.
|
|||
|
//
|
|||
|
|
|||
|
if (NextRelationship == Sibling) {
|
|||
|
PreviousEntry->Sibling = CurrentEntry;
|
|||
|
CurrentEntry->Parent = PreviousEntry->Parent;
|
|||
|
} else {
|
|||
|
PreviousEntry->Child = CurrentEntry;
|
|||
|
CurrentEntry->Parent = PreviousEntry;
|
|||
|
}
|
|||
|
NextRelationship = Sibling;
|
|||
|
PreviousEntry = CurrentEntry;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// Misc. supports. Note, the information collected here will NOT be
|
|||
|
// written to hardware registry.
|
|||
|
//
|
|||
|
// 1. Collect video font information for vdm
|
|||
|
//
|
|||
|
|
|||
|
GetVideoFontInformation();
|
|||
|
|
|||
|
//
|
|||
|
// After all the components are detected, we collect EISA config data.
|
|||
|
//
|
|||
|
|
|||
|
if (HwBusType == MACHINE_TYPE_EISA) {
|
|||
|
|
|||
|
Component = &AdapterEntry->ComponentEntry;
|
|||
|
GetEisaConfigurationData(&AdapterEntry->ConfigurationData,
|
|||
|
&Component->ConfigurationDataLength);
|
|||
|
if (Component->ConfigurationDataLength) {
|
|||
|
HwEisaConfigurationData = (FPUCHAR)AdapterEntry->ConfigurationData +
|
|||
|
DATA_HEADER_SIZE;
|
|||
|
HwEisaConfigurationSize = Component->ConfigurationDataLength -
|
|||
|
DATA_HEADER_SIZE;
|
|||
|
|
|||
|
//
|
|||
|
// Misc. detections based on Eisa config data
|
|||
|
//
|
|||
|
// Update Lpt and com controllers' irq information by examining
|
|||
|
// the EISA configuration data.
|
|||
|
//
|
|||
|
|
|||
|
GetIrqFromEisaData(FirstLpt, ParallelController);
|
|||
|
GetIrqFromEisaData(FirstCom, SerialController);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if DBG
|
|||
|
CheckConfigurationTree(ConfigurationRoot);
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// Update all the far pointers in the tree to flat 32 bit pointers
|
|||
|
//
|
|||
|
|
|||
|
UpdateConfigurationTree(ConfigurationRoot);
|
|||
|
|
|||
|
//
|
|||
|
// Set up returned values:
|
|||
|
// Size of Heap space which should be preserved for configuration tree
|
|||
|
// Pointer to the root of the configuration tree.
|
|||
|
//
|
|||
|
|
|||
|
CurrentEntry = (FPFWCONFIGURATION_COMPONENT_DATA)HwAllocateHeap(0, FALSE);
|
|||
|
*BlHeapUsed = MAKE_FLAT_ADDRESS(CurrentEntry) -
|
|||
|
MAKE_FLAT_ADDRESS(ConfigurationRoot);
|
|||
|
*BlConfigurationTree = (ULONG)MAKE_FLAT_ADDRESS(ConfigurationRoot);
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
GetIrqFromEisaData(
|
|||
|
FPFWCONFIGURATION_COMPONENT_DATA ControllerList,
|
|||
|
CONFIGURATION_TYPE ControllerType
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine updates all irq information for ControllerType components
|
|||
|
in the controllerList by examinine the eisa configuration data.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ControllerList - Supplies a pointer to a component entry whoes irq will
|
|||
|
be updated.
|
|||
|
|
|||
|
ControllerType - Supplies the controller type whoes irq will be searched
|
|||
|
for.
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
FPFWCONFIGURATION_COMPONENT_DATA CurrentEntry;
|
|||
|
FPHWPARTIAL_RESOURCE_DESCRIPTOR Descriptor;
|
|||
|
FPHWRESOURCE_DESCRIPTOR_LIST DescriptorList;
|
|||
|
USHORT i, Port;
|
|||
|
UCHAR Irq, Trigger;
|
|||
|
|
|||
|
CurrentEntry = ControllerList;
|
|||
|
while (CurrentEntry &&
|
|||
|
CurrentEntry->ComponentEntry.Type == ControllerType) {
|
|||
|
if (CurrentEntry->ConfigurationData) {
|
|||
|
DescriptorList = (FPHWRESOURCE_DESCRIPTOR_LIST)
|
|||
|
CurrentEntry->ConfigurationData;
|
|||
|
Port = 0;
|
|||
|
for (i = 0; i < (USHORT)DescriptorList->Count; i++) {
|
|||
|
Descriptor = &DescriptorList->PartialDescriptors[i];
|
|||
|
if (Descriptor->Type == CmResourceTypePort) {
|
|||
|
Port = (USHORT)Descriptor->u.Port.Start.LowPart;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if (Port != 0) {
|
|||
|
for (i = 0; i < (USHORT)DescriptorList->Count; i++) {
|
|||
|
Descriptor = &DescriptorList->PartialDescriptors[i];
|
|||
|
if (Descriptor->Type == CmResourceTypeInterrupt) {
|
|||
|
if (HwEisaGetIrqFromPort(Port, &Irq, &Trigger)) {
|
|||
|
if (Trigger == 0) { // EISA EDGE_TRIGGER
|
|||
|
Descriptor->Flags = EDGE_TRIGGERED;
|
|||
|
} else {
|
|||
|
Descriptor->Flags = LEVEL_SENSITIVE;
|
|||
|
}
|
|||
|
Descriptor->u.Interrupt.Level = Irq;
|
|||
|
Descriptor->u.Interrupt.Vector = Irq;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
CurrentEntry = CurrentEntry->Sibling;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
UpdateComponentPointers(
|
|||
|
FPFWCONFIGURATION_COMPONENT_DATA CurrentEntry
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine updates all the "far" pointer to 32 bit flat addresses
|
|||
|
for a component entry.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
CurrentEntry - Supplies a pointer to a component entry which will
|
|||
|
be updated.
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
FPULONG UpdatePointer;
|
|||
|
FPVOID NextEntry;
|
|||
|
ULONG FlatAddress;
|
|||
|
|
|||
|
//
|
|||
|
// Update the child, parent, sibling and ConfigurationData
|
|||
|
// far pointers to 32 bit flat addresses.
|
|||
|
// N.B. After we update the pointers to flat addresses, they
|
|||
|
// can no longer be accessed in real mode.
|
|||
|
//
|
|||
|
|
|||
|
UpdatePointer = (FPULONG)&CurrentEntry->Child;
|
|||
|
NextEntry = (FPVOID)CurrentEntry->Child;
|
|||
|
FlatAddress = MAKE_FLAT_ADDRESS(NextEntry);
|
|||
|
*UpdatePointer = FlatAddress;
|
|||
|
|
|||
|
UpdatePointer = (FPULONG)&CurrentEntry->Parent;
|
|||
|
NextEntry = (FPVOID)CurrentEntry->Parent;
|
|||
|
FlatAddress = MAKE_FLAT_ADDRESS(NextEntry);
|
|||
|
*UpdatePointer = FlatAddress;
|
|||
|
|
|||
|
UpdatePointer = (FPULONG)&CurrentEntry->Sibling;
|
|||
|
NextEntry = (FPVOID)CurrentEntry->Sibling;
|
|||
|
FlatAddress = MAKE_FLAT_ADDRESS(NextEntry);
|
|||
|
*UpdatePointer = FlatAddress;
|
|||
|
|
|||
|
UpdatePointer = (FPULONG)&CurrentEntry->ComponentEntry.Identifier;
|
|||
|
NextEntry = (FPVOID)CurrentEntry->ComponentEntry.Identifier;
|
|||
|
FlatAddress = MAKE_FLAT_ADDRESS(NextEntry);
|
|||
|
*UpdatePointer = FlatAddress;
|
|||
|
|
|||
|
UpdatePointer = (FPULONG)&CurrentEntry->ConfigurationData;
|
|||
|
NextEntry = (FPVOID)CurrentEntry->ConfigurationData;
|
|||
|
FlatAddress = MAKE_FLAT_ADDRESS(NextEntry);
|
|||
|
*UpdatePointer = FlatAddress;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
UpdateConfigurationTree(
|
|||
|
FPFWCONFIGURATION_COMPONENT_DATA CurrentEntry
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine traverses loader configuration tree and changes
|
|||
|
all the "far" pointer to 32 bit flat addresses.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
CurrentEntry - Supplies a pointer to a loader configuration
|
|||
|
tree or subtree.
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
if (CurrentEntry) {
|
|||
|
UpdateConfigurationTree(CurrentEntry->Child);
|
|||
|
UpdateConfigurationTree(CurrentEntry->Sibling);
|
|||
|
UpdateComponentPointers(CurrentEntry);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
FPVOID
|
|||
|
HwSetUpResourceDescriptor (
|
|||
|
FPFWCONFIGURATION_COMPONENT Component,
|
|||
|
PUCHAR Identifier,
|
|||
|
PHWCONTROLLER_DATA ControlData,
|
|||
|
USHORT SpecificDataLength,
|
|||
|
PUCHAR SpecificData
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine allocates space from far heap , puts the caller's controller
|
|||
|
information to the space and sets up CONFIGURATION_COMPONENT
|
|||
|
structure for the caller.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Component - Supplies the address the component whose configuration data
|
|||
|
should be set up.
|
|||
|
|
|||
|
Identifier - Suppies a pointer to the identifier to identify the controller
|
|||
|
|
|||
|
ControlData - Supplies a point to a structure which describes
|
|||
|
controller information.
|
|||
|
|
|||
|
SpecificDataLength - size of the device specific data. Device specific
|
|||
|
data is the information not defined in the standard format.
|
|||
|
|
|||
|
SpecificData - Supplies a pointer to the device specific data.
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Returns a far pointer to the Configuration data.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
FPCHAR fpIdentifier;
|
|||
|
FPHWRESOURCE_DESCRIPTOR_LIST fpDescriptor = NULL;
|
|||
|
USHORT Length;
|
|||
|
SHORT Count, i;
|
|||
|
FPUCHAR fpSpecificData;
|
|||
|
|
|||
|
//
|
|||
|
// Set up Identifier string for hardware component, if necessary.
|
|||
|
//
|
|||
|
|
|||
|
if (Identifier) {
|
|||
|
Length = strlen(Identifier) + 1;
|
|||
|
Component->IdentifierLength = Length;
|
|||
|
fpIdentifier = (FPUCHAR)HwAllocateHeap(Length, FALSE);
|
|||
|
Component->Identifier = fpIdentifier;
|
|||
|
_fstrcpy(fpIdentifier, Identifier);
|
|||
|
} else {
|
|||
|
Component->IdentifierLength = 0;
|
|||
|
Component->Identifier = NULL;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set up configuration data for hardware component, if necessary
|
|||
|
//
|
|||
|
|
|||
|
Count = ControlData->NumberPortEntries + ControlData->NumberIrqEntries +
|
|||
|
ControlData->NumberMemoryEntries + ControlData->NumberDmaEntries;
|
|||
|
|
|||
|
if (SpecificDataLength) {
|
|||
|
|
|||
|
//
|
|||
|
// if we have device specific data, we need to increment the count
|
|||
|
// by one.
|
|||
|
//
|
|||
|
|
|||
|
Count++;
|
|||
|
}
|
|||
|
|
|||
|
if (Count >0) {
|
|||
|
Length = (USHORT)(Count * sizeof(HWPARTIAL_RESOURCE_DESCRIPTOR) +
|
|||
|
FIELD_OFFSET(HWRESOURCE_DESCRIPTOR_LIST, PartialDescriptors) +
|
|||
|
SpecificDataLength);
|
|||
|
fpDescriptor = (FPHWRESOURCE_DESCRIPTOR_LIST)HwAllocateHeap(Length, TRUE);
|
|||
|
fpDescriptor->Count = Count;
|
|||
|
|
|||
|
//
|
|||
|
// Copy all the partial descriptors to the destination descriptors
|
|||
|
// except the last one. (The last partial descriptor may be a device
|
|||
|
// specific data. It requires special handling.)
|
|||
|
//
|
|||
|
|
|||
|
for (i = 0; i < (Count - 1); i++) {
|
|||
|
fpDescriptor->PartialDescriptors[i] =
|
|||
|
ControlData->DescriptorList[i];
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Set up the last partial descriptor. If it is a port, memory, irq or
|
|||
|
// dma entry, we simply copy it. If the last one is for device specific
|
|||
|
// data, we set up the length and copy the device spcific data to the end
|
|||
|
// of the decriptor.
|
|||
|
//
|
|||
|
|
|||
|
if (SpecificData) {
|
|||
|
fpDescriptor->PartialDescriptors[Count - 1].Type =
|
|||
|
RESOURCE_DEVICE_DATA;
|
|||
|
fpDescriptor->PartialDescriptors[Count - 1].Flags = 0;
|
|||
|
fpDescriptor->PartialDescriptors[Count - 1].u.DeviceSpecificData.DataSize =
|
|||
|
SpecificDataLength;
|
|||
|
fpSpecificData = (FPUCHAR)&(fpDescriptor->PartialDescriptors[Count]);
|
|||
|
_fmemcpy(fpSpecificData, SpecificData, SpecificDataLength);
|
|||
|
} else {
|
|||
|
fpDescriptor->PartialDescriptors[Count - 1] =
|
|||
|
ControlData->DescriptorList[Count - 1];
|
|||
|
}
|
|||
|
Component->ConfigurationDataLength = Length;
|
|||
|
}
|
|||
|
return(fpDescriptor);
|
|||
|
}
|
|||
|
VOID
|
|||
|
HwSetUpFreeFormDataHeader (
|
|||
|
FPHWRESOURCE_DESCRIPTOR_LIST Header,
|
|||
|
USHORT Version,
|
|||
|
USHORT Revision,
|
|||
|
USHORT Flags,
|
|||
|
ULONG DataSize
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine initialize free formed data header. Note this routine
|
|||
|
sets the the Header and initialize the FIRST PartialDescriptor only.
|
|||
|
If the header contains more than one descriptor, the caller must handle
|
|||
|
it itself.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Header - Supplies a pointer to the header to be initialized.
|
|||
|
|
|||
|
Version - Version number for the header.
|
|||
|
|
|||
|
Revision - Revision number for the header.
|
|||
|
|
|||
|
Flags - Free formed data flags. (Currently, it is undefined and
|
|||
|
should be zero.)
|
|||
|
|
|||
|
DataSize - Size of the free formed data.
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
Header->Version = Version;
|
|||
|
Header->Revision = Revision;
|
|||
|
Header->Count = 1;
|
|||
|
Header->PartialDescriptors[0].Type = RESOURCE_DEVICE_DATA;
|
|||
|
Header->PartialDescriptors[0].ShareDisposition = 0;
|
|||
|
Header->PartialDescriptors[0].Flags = Flags;
|
|||
|
Header->PartialDescriptors[0].u.DeviceSpecificData.DataSize = DataSize;
|
|||
|
Header->PartialDescriptors[0].u.DeviceSpecificData.Reserved1 = 0;
|
|||
|
Header->PartialDescriptors[0].u.DeviceSpecificData.Reserved2 = 0;
|
|||
|
}
|
|||
|
#if DBG
|
|||
|
|
|||
|
VOID
|
|||
|
CheckComponentNode(
|
|||
|
FPFWCONFIGURATION_COMPONENT_DATA CurrentEntry
|
|||
|
)
|
|||
|
{
|
|||
|
FPUCHAR NextEntry, DataPointer;
|
|||
|
ULONG FlatAddress;
|
|||
|
ULONG Length;
|
|||
|
UCHAR IdString[40];
|
|||
|
USHORT Count, i;
|
|||
|
UCHAR Type;
|
|||
|
FPHWRESOURCE_DESCRIPTOR_LIST DescriptorList;
|
|||
|
FPHWPARTIAL_RESOURCE_DESCRIPTOR Descriptor;
|
|||
|
|
|||
|
FlatAddress = MAKE_FLAT_ADDRESS(CurrentEntry);
|
|||
|
clrscrn ();
|
|||
|
BlPrint("\n");
|
|||
|
BlPrint("Current Node: %lx\n", FlatAddress);
|
|||
|
BlPrint(" Type = %s\n", TypeName[CurrentEntry->ComponentEntry.Type]);
|
|||
|
|
|||
|
//
|
|||
|
// Update the child, parent, sibling and ConfigurationData
|
|||
|
// far pointers to 32 bit flat addresses.
|
|||
|
// N.B. After we update the pointers to flat addresses, they
|
|||
|
// can no longer be accessed in real mode.
|
|||
|
//
|
|||
|
|
|||
|
NextEntry = (FPUCHAR)CurrentEntry->Child;
|
|||
|
FlatAddress = MAKE_FLAT_ADDRESS(NextEntry);
|
|||
|
if (FlatAddress > 0x60000 || (FlatAddress < 0x50000 && FlatAddress != 0)) {
|
|||
|
BlPrint("Invalid address: Child = %lx\n", FlatAddress);
|
|||
|
} else {
|
|||
|
BlPrint("\tChild = %lx\n", FlatAddress);
|
|||
|
}
|
|||
|
|
|||
|
NextEntry = (FPUCHAR)CurrentEntry->Parent;
|
|||
|
FlatAddress = MAKE_FLAT_ADDRESS(NextEntry);
|
|||
|
if (FlatAddress > 0x60000 || (FlatAddress < 0x50000 && FlatAddress != 0)) {
|
|||
|
BlPrint("Invalid address: Parent = %lx\n", FlatAddress);
|
|||
|
} else {
|
|||
|
BlPrint("\tParent = %lx\n", FlatAddress);
|
|||
|
}
|
|||
|
|
|||
|
NextEntry = (FPUCHAR)CurrentEntry->Sibling;
|
|||
|
FlatAddress = MAKE_FLAT_ADDRESS(NextEntry);
|
|||
|
if (FlatAddress > 0x60000 || (FlatAddress < 0x50000 && FlatAddress != 0)) {
|
|||
|
BlPrint("Invalid address: Sibling = %lx\n", FlatAddress);
|
|||
|
} else {
|
|||
|
BlPrint("\tSibling = %lx\n", FlatAddress);
|
|||
|
}
|
|||
|
|
|||
|
NextEntry = (FPUCHAR)CurrentEntry->ConfigurationData;
|
|||
|
FlatAddress = MAKE_FLAT_ADDRESS(NextEntry);
|
|||
|
if (FlatAddress > 0x60000 || (FlatAddress < 0x50000 && FlatAddress != 0)) {
|
|||
|
BlPrint("Invalid address: ConfigurationData = %lx\n", FlatAddress);
|
|||
|
} else {
|
|||
|
BlPrint("\tConfigurationData = %lx\n", FlatAddress);
|
|||
|
}
|
|||
|
|
|||
|
Length = CurrentEntry->ComponentEntry.IdentifierLength;
|
|||
|
BlPrint("IdentifierLength = %lx\n", CurrentEntry->ComponentEntry.IdentifierLength);
|
|||
|
if (Length > 0) {
|
|||
|
_fstrcpy(IdString, CurrentEntry->ComponentEntry.Identifier);
|
|||
|
BlPrint("Identifier = %s\n", IdString);
|
|||
|
}
|
|||
|
|
|||
|
Length = CurrentEntry->ComponentEntry.ConfigurationDataLength;
|
|||
|
BlPrint("ConfigdataLength = %lx\n", Length);
|
|||
|
|
|||
|
if (Length > 0) {
|
|||
|
|
|||
|
DescriptorList = (FPHWRESOURCE_DESCRIPTOR_LIST)CurrentEntry->ConfigurationData;
|
|||
|
BlPrint("Version = %x, Revision = %x\n", DescriptorList->Version,
|
|||
|
DescriptorList->Revision);
|
|||
|
Count = (USHORT)DescriptorList->Count;
|
|||
|
Descriptor = &DescriptorList->PartialDescriptors[0];
|
|||
|
BlPrint("Count = %x\n", Count);
|
|||
|
while (Count > 0) {
|
|||
|
Type = Descriptor->Type;
|
|||
|
if (Type == RESOURCE_PORT) {
|
|||
|
BlPrint("Type = Port");
|
|||
|
BlPrint("\tShareDisposition = %x\n", Descriptor->ShareDisposition);
|
|||
|
BlPrint("PortFlags = %x\n", Descriptor->Flags);
|
|||
|
BlPrint("PortStart = %x", Descriptor->u.Port.Start);
|
|||
|
BlPrint("\tPortLength = %x\n", Descriptor->u.Port.Length);
|
|||
|
} else if (Type == RESOURCE_DMA) {
|
|||
|
BlPrint("Type = Dma");
|
|||
|
BlPrint("\tShareDisposition = %x\n", Descriptor->ShareDisposition);
|
|||
|
BlPrint("DmaFlags = %x\n", Descriptor->Flags);
|
|||
|
BlPrint("DmaChannel = %x", Descriptor->u.Dma.Channel);
|
|||
|
BlPrint("\tDmaPort = %lx\n", Descriptor->u.Dma.Port);
|
|||
|
} else if (Type == RESOURCE_INTERRUPT) {
|
|||
|
BlPrint("Type = Interrupt");
|
|||
|
BlPrint("\tShareDisposition = %x\n", Descriptor->ShareDisposition);
|
|||
|
BlPrint("InterruptFlags = %x\n", Descriptor->Flags);
|
|||
|
BlPrint("Level = %x", Descriptor->u.Interrupt.Level);
|
|||
|
BlPrint("\tVector = %x\n", Descriptor->u.Interrupt.Vector);
|
|||
|
} else if (Type == RESOURCE_MEMORY) {
|
|||
|
BlPrint("Type = Memory");
|
|||
|
BlPrint("\tShareDisposition = %x\n", Descriptor->ShareDisposition);
|
|||
|
BlPrint("MemoryFlags = %x\n", Descriptor->Flags);
|
|||
|
BlPrint("Start1 = %lx", (ULONG)Descriptor->u.Memory.Start.LowPart);
|
|||
|
BlPrint("\tStart2 = %lx", (ULONG)Descriptor->u.Memory.Start.HighPart);
|
|||
|
BlPrint("\tLength = %lx\n", Descriptor->u.Memory.Length);
|
|||
|
} else {
|
|||
|
BlPrint("Type = Device Data\n");
|
|||
|
Length = Descriptor->u.DeviceSpecificData.DataSize;
|
|||
|
BlPrint("Size = %lx\n", Length);
|
|||
|
DataPointer = (FPUCHAR)(Descriptor+1);
|
|||
|
for (i = 0; i < Length && i < 64; i++) {
|
|||
|
BlPrint("%x ", *DataPointer);
|
|||
|
DataPointer++;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
Count--;
|
|||
|
Descriptor++;
|
|||
|
}
|
|||
|
}
|
|||
|
while (HwGetKey() == 0) {
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
CheckConfigurationTree(
|
|||
|
FPFWCONFIGURATION_COMPONENT_DATA CurrentEntry
|
|||
|
)
|
|||
|
{
|
|||
|
if (CurrentEntry) {
|
|||
|
CheckComponentNode(CurrentEntry);
|
|||
|
CheckConfigurationTree(CurrentEntry->Sibling);
|
|||
|
CheckConfigurationTree(CurrentEntry->Child);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endif
|