--- /dev/null
+/*
+ * FreeLoader
+ *
+ * Copyright (C) 2003 Eric Kohl
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <freeldr.h>
+#include <arch.h>
+#include <rtl.h>
+#include <debug.h>
+#include <disk.h>
+#include <mm.h>
+#include <portio.h>
+
+#include "../../reactos/registry.h"
+
+
+#define MILLISEC (10)
+#define PRECISION (8)
+
+#define HZ (100)
+#define CLOCK_TICK_RATE (1193182)
+#define LATCH (CLOCK_TICK_RATE / HZ)
+
+
+typedef enum
+{
+ InterfaceTypeUndefined = -1,
+ Internal,
+ Isa,
+ Eisa,
+ MicroChannel,
+ TurboChannel,
+ PCIBus,
+ VMEBus,
+ NuBus,
+ PCMCIABus,
+ CBus,
+ MPIBus,
+ MPSABus,
+ ProcessorInternal,
+ InternalPowerBus,
+ PNPISABus,
+ MaximumInterfaceType
+} INTERFACE_TYPE, *PINTERFACE_TYPE;
+
+
+typedef U64 PHYSICAL_ADDRESS;
+
+
+typedef struct _CM_INT13_DRIVE_PARAMETER
+{
+ U16 DriveSelect;
+ U32 MaxCylinders;
+ U16 SectorsPerTrack;
+ U16 MaxHeads;
+ U16 NumberDrives;
+} CM_INT13_DRIVE_PARAMETER, *PCM_INT13_DRIVE_PARAMETER;
+
+
+typedef struct _CM_DISK_GEOMETRY_DEVICE_DATA
+{
+ U32 BytesPerSector;
+ U32 NumberOfCylinders;
+ U32 SectorsPerTrack;
+ U32 NumberOfHeads;
+} CM_DISK_GEOMETRY_DEVICE_DATA, *PCM_DISK_GEOMETRY_DEVICE_DATA;
+
+
+typedef struct
+{
+ U8 Type;
+ U8 ShareDisposition;
+ U16 Flags;
+ union
+ {
+ struct
+ {
+ PHYSICAL_ADDRESS Start;
+ U32 Length;
+ } __attribute__((packed)) Port;
+ struct
+ {
+ U32 Level;
+ U32 Vector;
+ U32 Affinity;
+ } __attribute__((packed)) Interrupt;
+ struct
+ {
+ PHYSICAL_ADDRESS Start;
+ U32 Length;
+ } __attribute__((packed)) Memory;
+ struct
+ {
+ U32 Channel;
+ U32 Port;
+ U32 Reserved1;
+ } __attribute__((packed)) Dma;
+ struct
+ {
+ U32 DataSize;
+ U32 Reserved1;
+ U32 Reserved2;
+ } __attribute__((packed)) DeviceSpecificData;
+ } __attribute__((packed)) u;
+} __attribute__((packed)) CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
+
+
+typedef struct
+{
+ U16 Version;
+ U16 Revision;
+ U32 Count;
+ CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];
+} __attribute__((packed))CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
+
+
+typedef struct
+{
+ INTERFACE_TYPE InterfaceType;
+ U32 BusNumber;
+ CM_PARTIAL_RESOURCE_LIST PartialResourceList;
+} __attribute__((packed)) CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;
+
+
+typedef struct _DEVICE_NODE
+{
+ U16 Size;
+ U8 Node;
+ U8 ProductId[4];
+ U8 DeviceType[3];
+ U16 DeviceAttributes;
+} PACKED DEVICE_NODE, *PDEVICE_NODE;
+
+typedef struct _MPS_CONFIG_TABLE_HEADER
+{
+ U32 Signature;
+ U16 BaseTableLength;
+ U8 SpecRev;
+ U8 Checksum;
+ CHAR OemIdString[8];
+ CHAR ProductIdString[12];
+ U32 OemTablePointer;
+ U16 OemTableLength;
+ U16 EntryCount;
+ U32 AddressOfLocalAPIC;
+ U16 ExtendedTableLength;
+ U8 ExtendedTableChecksum;
+ U8 Reserved;
+} PACKED MPS_CONFIG_TABLE_HEADER, *PMPS_CONFIG_TABLE_HEADER;
+
+typedef struct _MPS_PROCESSOR_ENTRY
+{
+ U8 EntryType;
+ U8 LocalApicId;
+ U8 LocalApicVersion;
+ U8 CpuFlags;
+ U32 CpuSignature;
+ U32 FeatureFlags;
+ U32 Reserved1;
+ U32 Reserved2;
+} PACKED MPS_PROCESSOR_ENTRY, *PMPS_PROCESSOR_ENTRY;
+
+static char Hex[] = "0123456789ABCDEF";
+static unsigned int delay_count = 1;
+
+/* PROTOTYPES ***************************************************************/
+
+/* i386cpu.S */
+
+U32 CpuidSupported(VOID);
+VOID GetCpuid(U32 Level, U32 *eax, U32 *ebx, U32 *ecx, U32 *edx);
+
+U32 MpsSupported(VOID);
+U32 MpsGetDefaultConfiguration(VOID);
+U32 MpsGetConfigurationTable(PVOID ConfigTable);
+
+
+/* FUNCTIONS ****************************************************************/
+
+
+static VOID
+__KeStallExecutionProcessor(U32 Loops)
+{
+ register unsigned int i;
+ for (i = 0; i < Loops; i++);
+}
+
+VOID KeStallExecutionProcessor(U32 Microseconds)
+{
+ __KeStallExecutionProcessor((delay_count * Microseconds) / 1000);
+}
+
+
+static U32
+Read8254Timer(VOID)
+{
+ U32 Count;
+
+ WRITE_PORT_UCHAR((PU8)0x43, 0x00);
+ Count = READ_PORT_UCHAR((PU8)0x40);
+ Count |= READ_PORT_UCHAR((PU8)0x40) << 8;
+
+ return Count;
+}
+
+
+static VOID
+WaitFor8254Wraparound(VOID)
+{
+ U32 CurCount;
+ U32 PrevCount = ~0;
+ S32 Delta;
+
+ CurCount = Read8254Timer();
+
+ do
+ {
+ PrevCount = CurCount;
+ CurCount = Read8254Timer();
+ Delta = CurCount - PrevCount;
+
+ /*
+ * This limit for delta seems arbitrary, but it isn't, it's
+ * slightly above the level of error a buggy Mercury/Neptune
+ * chipset timer can cause.
+ */
+ }
+ while (Delta < 300);
+}
+
+
+VOID
+HalpCalibrateStallExecution(VOID)
+{
+ U32 i;
+ U32 calib_bit;
+ U32 CurCount;
+
+ /* Initialise timer interrupt with MILLISECOND ms interval */
+ WRITE_PORT_UCHAR((PU8)0x43, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
+ WRITE_PORT_UCHAR((PU8)0x40, LATCH & 0xff); /* LSB */
+ WRITE_PORT_UCHAR((PU8)0x40, LATCH >> 8); /* MSB */
+
+ /* Stage 1: Coarse calibration */
+
+ WaitFor8254Wraparound();
+
+ delay_count = 1;
+
+ do {
+ delay_count <<= 1; /* Next delay count to try */
+
+ WaitFor8254Wraparound();
+
+ __KeStallExecutionProcessor(delay_count); /* Do the delay */
+
+ CurCount = Read8254Timer();
+ } while (CurCount > LATCH / 2);
+
+ delay_count >>= 1; /* Get bottom value for delay */
+
+ /* Stage 2: Fine calibration */
+
+ calib_bit = delay_count; /* Which bit are we going to test */
+
+ for(i=0;i<PRECISION;i++) {
+ calib_bit >>= 1; /* Next bit to calibrate */
+ if(!calib_bit) break; /* If we have done all bits, stop */
+
+ delay_count |= calib_bit; /* Set the bit in delay_count */
+
+ WaitFor8254Wraparound();
+
+ __KeStallExecutionProcessor(delay_count); /* Do the delay */
+
+ CurCount = Read8254Timer();
+ if (CurCount <= LATCH / 2) /* If a tick has passed, turn the */
+ delay_count &= ~calib_bit; /* calibrated bit back off */
+ }
+
+ /* We're finished: Do the finishing touches */
+
+ delay_count /= (MILLISEC / 2); /* Calculate delay_count for 1ms */
+}
+
+
+static VOID
+DetectCPU(VOID)
+{
+ char VendorIdentifier[13];
+// char Buffer[64];
+ U32 eax = 0;
+ U32 ebx = 0;
+ U32 ecx = 0;
+ U32 edx = 0;
+ U32 *Ptr;
+
+ eax = CpuidSupported();
+ if (eax & 1)
+ {
+ printf(" CPUID supported\n");
+
+ GetCpuid(0, &eax, &ebx, &ecx, &edx);
+// printf(" Level 0: %x %x %x %x\n", (int)eax, (int)ebx, (int)ecx, (int)edx);
+
+ VendorIdentifier[12] = 0;
+ Ptr = (U32*)&VendorIdentifier[0];
+ *Ptr = ebx;
+ Ptr++;
+ *Ptr = edx;
+ Ptr++;
+ *Ptr = ecx;
+
+ printf(" Vendor Identifier: %s\n",
+ VendorIdentifier);
+
+ GetCpuid(1, &eax, &ebx, &ecx, &edx);
+// printf(" Level 1: %x %x %x %x\n", (int)eax, (int)ebx, (int)ecx, (int)edx);
+
+ printf(" Identifier: x86 Family %u Model %u Stepping %u\n",
+ (unsigned int)((eax >> 8) & 0x0F),
+ (unsigned int)((eax >> 4) & 0x0F),
+ (unsigned int)(eax & 0x0F));
+
+ printf(" FeatureSet: %x\n",
+ (unsigned int)edx);
+ }
+ else
+ {
+ edx = 0; /* No feature set */
+
+ printf(" CPUID not supported\n");
+ printf(" Vendor Identifier: Unknown\n");
+ printf(" Identifier: x86 Family %u Model %u Stepping %u\n",
+ (unsigned int)((eax >> 8) & 0x0F),
+ (unsigned int)((eax >> 4) & 0x0F),
+ (unsigned int)(eax & 0x0F));
+ printf(" FeatureSet: %x\n",
+ (unsigned int)edx);
+ }
+
+ /* FIXME: add more checks */
+
+
+ /* FIXME: store cpu info in the registry (CPU 0 only) */
+
+ printf("\n");
+}
+
+
+static BOOL
+DetectMps(VOID)
+{
+ U32 DefaultConfig;
+ char *Buffer;
+// char Signature[5];
+ PMPS_CONFIG_TABLE_HEADER ConfigTable;
+ PMPS_PROCESSOR_ENTRY CpuEntry;
+ char *Ptr;
+ unsigned long Offset;
+
+
+ DefaultConfig = MpsGetDefaultConfiguration();
+ if (DefaultConfig == 0)
+ {
+ /* Read configuration table */
+ MpsGetConfigurationTable((PVOID)DISKREADBUFFER);
+ Buffer = (char *)DISKREADBUFFER;
+
+// Signature[0] = Buffer[0];
+// Signature[1] = Buffer[1];
+// Signature[2] = Buffer[2];
+// Signature[3] = Buffer[3];
+// Signature[4] = 0;
+
+// printf(" Signature: %s\n",
+// Signature);
+
+ ConfigTable = (PMPS_CONFIG_TABLE_HEADER)DISKREADBUFFER;
+ Offset = 0x2C;
+ while (Offset < ConfigTable->BaseTableLength)
+ {
+ Ptr = Buffer + Offset;
+
+ switch (*Ptr)
+ {
+ case 0:
+ CpuEntry = (PMPS_PROCESSOR_ENTRY)Ptr;
+ printf (" Processor %u: x86 Family %u Model %u Stepping %u\n",
+ CpuEntry->LocalApicId,
+ (unsigned int)((CpuEntry->CpuSignature >> 8) & 0x0F),
+ (unsigned int)((CpuEntry->CpuSignature >> 4) & 0x0F),
+ (unsigned int)(CpuEntry->CpuSignature & 0x0F));
+
+// printf(" Processor Entry\n");
+// printf(" APIC Id %u APIC Version %u Flags %x Signature %x Feature %x\n",
+// CpuEntry->LocalApicId,
+// CpuEntry->LocalApicVersion,
+// CpuEntry->CpuFlags,
+// CpuEntry->CpuSignature,
+// CpuEntry->FeatureFlags);
+
+ Offset += 0x14;
+ break;
+
+ case 1:
+// printf(" Bus Entry\n");
+ Offset += 0x08;
+ break;
+
+ case 2:
+// printf(" I/0 APIC Entry\n");
+ Offset += 0x08;
+ break;
+
+ case 3:
+// printf(" I/0 Interrupt Assignment Entry\n");
+ Offset += 0x08;
+ break;
+
+ case 4:
+// printf(" Local Interrupt Assignment Entry\n");
+ Offset += 0x08;
+ break;
+
+ default:
+// printf(" Unknown Entry %u\n",(unsigned int)*Ptr);
+ return FALSE;
+ }
+
+ }
+ }
+ else
+ {
+// printf(" Unsupported MPS configuration: %x\n", (unsigned int)DefaultConfig);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static VOID
+DetectCPUs(VOID)
+{
+ if (MpsSupported ())
+ DetectMps ();
+ else
+ DetectCPU ();
+}
+
+
+static VOID
+SetHarddiskConfigurationData(HKEY DiskKey,
+ U32 DriveNumber)
+{
+ PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
+ PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
+ EXTENDED_GEOMETRY ExtGeometry;
+ GEOMETRY Geometry;
+ U32 Size;
+ S32 Error;
+
+ /* Set 'Configuration Data' value */
+ Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
+ sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
+ FullResourceDescriptor = MmAllocateMemory(Size);
+ if (FullResourceDescriptor == NULL)
+ {
+ DbgPrint((DPRINT_HWDETECT,
+ "Failed to allocate a full resource descriptor\n"));
+ return;
+ }
+
+ memset(FullResourceDescriptor, 0, Size);
+ FullResourceDescriptor->InterfaceType = InterfaceTypeUndefined;
+ FullResourceDescriptor->BusNumber = 0;
+ FullResourceDescriptor->PartialResourceList.Count = 1;
+ FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize =
+ sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
+
+ /* Get pointer to geometry data */
+ DiskGeometry = ((PVOID)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
+
+ /* Get the disk geometry */
+ ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
+ if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
+ {
+ DiskGeometry->BytesPerSector = ExtGeometry.BytesPerSector;
+ DiskGeometry->NumberOfCylinders = ExtGeometry.Cylinders;
+ DiskGeometry->SectorsPerTrack = ExtGeometry.SectorsPerTrack;
+ DiskGeometry->NumberOfHeads = ExtGeometry.Heads;
+ }
+ else if(DiskGetDriveParameters(DriveNumber, &Geometry))
+ {
+ DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
+ DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
+ DiskGeometry->SectorsPerTrack = Geometry.Sectors;
+ DiskGeometry->NumberOfHeads = Geometry.Heads;
+ }
+ else
+ {
+ DbgPrint((DPRINT_HWDETECT, "Reading disk geometry failed\n"));
+ MmFreeMemory(FullResourceDescriptor);
+ return;
+ }
+ DbgPrint((DPRINT_HWDETECT,
+ "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
+ DriveNumber,
+ DiskGeometry->NumberOfCylinders,
+ DiskGeometry->NumberOfHeads,
+ DiskGeometry->SectorsPerTrack,
+ DiskGeometry->BytesPerSector));
+
+ Error = RegSetValue(DiskKey,
+ "Configuration Data",
+ REG_FULL_RESOURCE_DESCRIPTOR,
+ (PU8) FullResourceDescriptor,
+ Size);
+ MmFreeMemory(FullResourceDescriptor);
+ if (Error != ERROR_SUCCESS)
+ {
+ DbgPrint((DPRINT_HWDETECT,
+ "RegSetValue(Configuration Data) failed (Error %u)\n",
+ (int)Error));
+ }
+}
+
+
+static VOID
+SetHarddiskIdentifier(HKEY DiskKey,
+ U32 DriveNumber)
+{
+ PMASTER_BOOT_RECORD Mbr;
+ U32 *Buffer;
+ U32 i;
+ U32 Checksum;
+ U32 Signature;
+ char Identifier[20];
+ S32 Error;
+
+ /* Read the MBR */
+ if (!DiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
+ {
+ DbgPrint((DPRINT_HWDETECT, "Reading MBR failed\n"));
+ return;
+ }
+
+ Buffer = (U32*)DISKREADBUFFER;
+ Mbr = (PMASTER_BOOT_RECORD)DISKREADBUFFER;
+
+ Signature = Mbr->Signature;
+ DbgPrint((DPRINT_HWDETECT, "Signature: %x\n", Signature));
+
+ /* Calculate the MBR checksum */
+ Checksum = 0;
+ for (i = 0; i < 128; i++)
+ {
+ Checksum += Buffer[i];
+ }
+ Checksum = ~Checksum + 1;
+ DbgPrint((DPRINT_HWDETECT, "Checksum: %x\n", Checksum));
+
+ /* Convert checksum and signature to identifier string */
+ Identifier[0] = Hex[(Checksum >> 28) & 0x0F];
+ Identifier[1] = Hex[(Checksum >> 24) & 0x0F];
+ Identifier[2] = Hex[(Checksum >> 20) & 0x0F];
+ Identifier[3] = Hex[(Checksum >> 16) & 0x0F];
+ Identifier[4] = Hex[(Checksum >> 12) & 0x0F];
+ Identifier[5] = Hex[(Checksum >> 8) & 0x0F];
+ Identifier[6] = Hex[(Checksum >> 4) & 0x0F];
+ Identifier[7] = Hex[Checksum & 0x0F];
+ Identifier[8] = '-';
+ Identifier[9] = Hex[(Signature >> 28) & 0x0F];
+ Identifier[10] = Hex[(Signature >> 24) & 0x0F];
+ Identifier[11] = Hex[(Signature >> 20) & 0x0F];
+ Identifier[12] = Hex[(Signature >> 16) & 0x0F];
+ Identifier[13] = Hex[(Signature >> 12) & 0x0F];
+ Identifier[14] = Hex[(Signature >> 8) & 0x0F];
+ Identifier[15] = Hex[(Signature >> 4) & 0x0F];
+ Identifier[16] = Hex[Signature & 0x0F];
+ Identifier[17] = '-';
+ Identifier[18] = 'A';
+ Identifier[19] = 0;
+ DbgPrint((DPRINT_HWDETECT, "Identifier: %xsn", Identifier));
+
+ /* Set identifier */
+ Error = RegSetValue(DiskKey,
+ "Identifier",
+ REG_SZ,
+ (PU8) Identifier,
+ 20);
+ if (Error != ERROR_SUCCESS)
+ {
+ DbgPrint((DPRINT_HWDETECT,
+ "RegSetValue(Identifier) failed (Error %u)\n",
+ (int)Error));
+ }
+}
+
+
+static VOID
+DetectBiosDisks(HKEY SystemKey,
+ HKEY BusKey)
+{
+ PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
+ PCM_INT13_DRIVE_PARAMETER Int13Drives;
+ GEOMETRY Geometry;
+ char Buffer[80];
+ HKEY DiskKey;
+ U32 DiskCount;
+ U32 Size;
+ U32 i;
+ S32 Error;
+
+ /* Count the number of visible drives */
+ DiskCount = 0;
+ while (DiskGetDriveParameters(0x80 + DiskCount, &Geometry))
+ {
+ DiskCount++;
+ }
+ DbgPrint((DPRINT_HWDETECT, "BIOS reports %d harddisk%s\n",
+ (int)DiskCount, (DiskCount == 1) ? "": "s"));
+
+ /* Allocate resource descriptor */
+ Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
+ sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
+ FullResourceDescriptor = MmAllocateMemory(Size);
+ if (FullResourceDescriptor == NULL)
+ {
+ DbgPrint((DPRINT_HWDETECT,
+ "Failed to allocate resource descriptor\n"));
+ return;
+ }
+
+ /* Initialize resource descriptor */
+ memset(FullResourceDescriptor, 0, Size);
+ FullResourceDescriptor->InterfaceType = InterfaceTypeUndefined;
+ FullResourceDescriptor->BusNumber = -1;
+ FullResourceDescriptor->PartialResourceList.Count = 1;
+ FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize =
+ sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
+
+ /* Get harddisk Int13 geometry data */
+ Int13Drives = ((PVOID)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
+ for (i = 0; i < DiskCount; i++)
+ {
+ if (DiskGetDriveParameters(0x80 + DiskCount, &Geometry))
+ {
+ Int13Drives[i].DriveSelect = 0x80 + 1;
+ Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
+ Int13Drives[i].SectorsPerTrack = Geometry.Sectors;
+ Int13Drives[i].MaxHeads = Geometry.Heads - 1;
+ Int13Drives[i].NumberDrives = DiskCount;
+ }
+ }
+
+ /* Set 'Configuration Data' value */
+ Error = RegSetValue(SystemKey,
+ "Configuration Data",
+ REG_FULL_RESOURCE_DESCRIPTOR,
+ (PU8) FullResourceDescriptor,
+ Size);
+ MmFreeMemory(FullResourceDescriptor);
+ if (Error != ERROR_SUCCESS)
+ {
+ DbgPrint((DPRINT_HWDETECT,
+ "RegSetValue(Configuration Data) failed (Error %u)\n",
+ (int)Error));
+ return;
+ }
+
+ /* Create and fill subkey for each harddisk */
+ for (i = 0; i < DiskCount; i++)
+ {
+ /* Create disk key */
+ sprintf (Buffer,
+ "DiskController\\0\\DiskPeripheral\\%u",
+ i);
+
+ Error = RegCreateKey(BusKey,
+ Buffer,
+ &DiskKey);
+ if (Error != ERROR_SUCCESS)
+ {
+ DbgPrint((DPRINT_HWDETECT, "Failed to create drive key\n"));
+ continue;
+ }
+ DbgPrint((DPRINT_HWDETECT, "Created key: %s\n", Buffer));
+
+ /* Set disk values */
+ SetHarddiskConfigurationData(DiskKey, 0x80 + i);
+ SetHarddiskIdentifier(DiskKey, 0x80 + i);
+ }
+}
+
+
+static VOID
+DetectIsaBus(U32 *BusNumber)
+{
+ char Buffer[80];
+ HKEY SystemKey;
+ HKEY BusKey;
+ S32 Error;
+
+ /* Create or open the 'System' key */
+ Error = RegCreateKey(NULL,
+ "\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
+ &SystemKey);
+ if (Error != ERROR_SUCCESS)
+ {
+ DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
+ return;
+ }
+
+ /* Create new bus key */
+ sprintf(Buffer,
+ "MultifunctionAdapter\\%u", *BusNumber);
+ Error = RegCreateKey(SystemKey,
+ Buffer,
+ &BusKey);
+ if (Error != ERROR_SUCCESS)
+ {
+ DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
+ return;
+ }
+
+ /* Increment bus number */
+ (*BusNumber)++;
+
+ /* Set bus identifier */
+ Error = RegSetValue(BusKey,
+ "Identifier",
+ REG_SZ,
+ (PU8)"ISA",
+ 4);
+ if (Error != ERROR_SUCCESS)
+ {
+ DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
+ return;
+ }
+
+ /* Detect ISA/BIOS devices */
+// DetectBiosFloppys(SystemKey, BusKey);
+ DetectBiosDisks(SystemKey, BusKey);
+
+// DetectBiosSerialPorts
+// DetectBiosParallelPorts
+
+// DetectBiosKeyboard
+// DetectBiosMouse
+
+ /* FIXME: Detect more ISA devices */
+}
+
+
+VOID
+DetectHardware(VOID)
+{
+ U32 BusNumber = 0;
+
+ DbgPrint((DPRINT_HWDETECT, "DetectHardware()\n"));
+
+ HalpCalibrateStallExecution ();
+
+// DetectBiosData();
+ DetectCPUs ();
+
+ /* Detect buses */
+// DetectPciBios (&BusNumber);
+// DetectPci (&BusNumber);
+// DetectApm (&BusNumber);
+// DetectPnpBios (&BusNumber);
+
+ DetectIsaBus (&BusNumber);
+
+
+ DbgPrint ((DPRINT_HWDETECT, "DetectHardware() Done\n"));
+
+// printf ("*** System stopped ***\n");
+// for (;;);
+}
+
+/* EOF */
+++ /dev/null
-/*
- * FreeLoader
- *
- * Copyright (C) 2001 Eric Kohl
- * Copyright (C) 2003 Casper S. Hornstrup
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <freeldr.h>
-#include <rtl.h>
-#include <mm.h>
-#include <arch.h>
-#include <portio.h>
-#include "registry.h"
-#include "hwdetect.h"
-#include <debug.h>
-
-/* ***** BEGIN I/O ***** */
-
-#define MILLISEC (10)
-#define PRECISION (8)
-
-static unsigned int delay_count = 1;
-
-static VOID
-__KeStallExecutionProcessor(U32 Loops)
-{
- register unsigned int i;
- for (i = 0; i < Loops; i++);
-}
-
-VOID KeStallExecutionProcessor(U32 Microseconds)
-{
- __KeStallExecutionProcessor((delay_count * Microseconds) / 1000);
-}
-
-#define HZ (100)
-#define CLOCK_TICK_RATE (1193182)
-#define LATCH (CLOCK_TICK_RATE / HZ)
-
-static U32
-Read8254Timer(VOID)
-{
- U32 Count;
-
- WRITE_PORT_UCHAR((PU8)0x43, 0x00);
- Count = READ_PORT_UCHAR((PU8)0x40);
- Count |= READ_PORT_UCHAR((PU8)0x40) << 8;
- return Count;
-}
-
-static VOID
-WaitFor8254Wraparound(VOID)
-{
- U32 CurCount;
- U32 PrevCount = ~0;
- S32 Delta;
-
- CurCount = Read8254Timer();
-
- do {
- PrevCount = CurCount;
- CurCount = Read8254Timer();
- Delta = CurCount - PrevCount;
-
- /*
- * This limit for delta seems arbitrary, but it isn't, it's
- * slightly above the level of error a buggy Mercury/Neptune
- * chipset timer can cause.
- */
- } while (Delta < 300);
-}
-
-VOID
-HalpCalibrateStallExecution(VOID)
-{
- U32 i;
- U32 calib_bit;
- U32 CurCount;
-
- /* Initialise timer interrupt with MILLISECOND ms interval */
- WRITE_PORT_UCHAR((PU8)0x43, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
- WRITE_PORT_UCHAR((PU8)0x40, LATCH & 0xff); /* LSB */
- WRITE_PORT_UCHAR((PU8)0x40, LATCH >> 8); /* MSB */
-
- /* Stage 1: Coarse calibration */
-
- WaitFor8254Wraparound();
-
- delay_count = 1;
-
- do {
- delay_count <<= 1; /* Next delay count to try */
-
- WaitFor8254Wraparound();
-
- __KeStallExecutionProcessor(delay_count); /* Do the delay */
-
- CurCount = Read8254Timer();
- } while (CurCount > LATCH / 2);
-
- delay_count >>= 1; /* Get bottom value for delay */
-
- /* Stage 2: Fine calibration */
-
- calib_bit = delay_count; /* Which bit are we going to test */
-
- for(i=0;i<PRECISION;i++) {
- calib_bit >>= 1; /* Next bit to calibrate */
- if(!calib_bit) break; /* If we have done all bits, stop */
-
- delay_count |= calib_bit; /* Set the bit in delay_count */
-
- WaitFor8254Wraparound();
-
- __KeStallExecutionProcessor(delay_count); /* Do the delay */
-
- CurCount = Read8254Timer();
- if (CurCount <= LATCH / 2) /* If a tick has passed, turn the */
- delay_count &= ~calib_bit; /* calibrated bit back off */
- }
-
- /* We're finished: Do the finishing touches */
-
- delay_count /= (MILLISEC / 2); /* Calculate delay_count for 1ms */
-}
-
-
-
-/* ***** BEGIN Bus ***** */
-
-/* access type 1 macros */
-#define CONFIG_CMD(bus, dev_fn, where) \
- (0x80000000 | (((U32)(bus)) << 16) | (((dev_fn) & 0x1F) << 11) | (((dev_fn) & 0xE0) << 3) | ((where) & ~3))
-
-/* access type 2 macros */
-#define IOADDR(dev_fn, where) \
- (0xC000 | (((dev_fn) & 0x1F) << 8) | (where))
-#define FUNC(dev_fn) \
- ((((dev_fn) & 0xE0) >> 4) | 0xf0)
-
-static U32 PciBusConfigType = 0; /* undetermined config type */
-
-static BOOLEAN
-ReadPciConfigUchar(U8 Bus,
- U8 Slot,
- U8 Offset,
- PU8 Value)
-{
- switch (PciBusConfigType)
- {
- case 1:
- WRITE_PORT_ULONG((PU32)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- *Value = READ_PORT_UCHAR((PU8)0xCFC + (Offset & 3));
- return TRUE;
-
- case 2:
- WRITE_PORT_UCHAR((PU8)0xCF8, FUNC(Slot));
- WRITE_PORT_UCHAR((PU8)0xCFA, Bus);
- *Value = READ_PORT_UCHAR((PU8)(IOADDR(Slot, Offset)));
- WRITE_PORT_UCHAR((PU8)0xCF8, 0);
- return TRUE;
- }
- return FALSE;
-}
-
-static BOOLEAN
-ReadPciConfigUshort(U8 Bus,
- U8 Slot,
- U8 Offset,
- PU16 Value)
-{
- if ((Offset & 1) != 0)
- {
- return FALSE;
- }
-
- switch (PciBusConfigType)
- {
- case 1:
- WRITE_PORT_ULONG((PU32)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- *Value = READ_PORT_USHORT((PU16)0xCFC + (Offset & 2));
- return TRUE;
-
- case 2:
- WRITE_PORT_UCHAR((PU8)0xCF8, FUNC(Slot));
- WRITE_PORT_UCHAR((PU8)0xCFA, Bus);
- *Value = READ_PORT_USHORT((PU16)(IOADDR(Slot, Offset)));
- WRITE_PORT_UCHAR((PU8)0xCF8, 0);
- return TRUE;
- }
- return FALSE;
-}
-
-static BOOLEAN
-ReadPciConfigUlong(U8 Bus,
- U8 Slot,
- U8 Offset,
- PU32 Value)
-{
- if ((Offset & 3) != 0)
- {
- return FALSE;
- }
-
- switch (PciBusConfigType)
- {
- case 1:
- WRITE_PORT_ULONG((PU32)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
- *Value = READ_PORT_ULONG((PU32)0xCFC);
- return TRUE;
-
- case 2:
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
- WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
- *Value = READ_PORT_ULONG((PU32)(IOADDR(Slot, Offset)));
- WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
- return TRUE;
- }
- return FALSE;
-}
-
-static U32
-GetPciBusConfigType(VOID)
-{
- U32 Value;
-
- WRITE_PORT_UCHAR((PU8)0xCFB, 0x01);
- Value = READ_PORT_ULONG((PU32)0xCF8);
- WRITE_PORT_ULONG((PU32)0xCF8, 0x80000000);
- if (READ_PORT_ULONG((PU32)0xCF8) == 0x80000000)
- {
- WRITE_PORT_ULONG((PU32)0xCF8, Value);
- DbgPrint((DPRINT_HWDETECT, "Pci bus type 1 found\n"));
- return 1;
- }
- WRITE_PORT_ULONG((PU32)0xCF8, Value);
-
- WRITE_PORT_UCHAR((PU8)0xCFB, 0x00);
- WRITE_PORT_UCHAR((PU8)0xCF8, 0x00);
- WRITE_PORT_UCHAR((PU8)0xCFA, 0x00);
- if (READ_PORT_UCHAR((PU8)0xCF8) == 0x00 &&
- READ_PORT_UCHAR((PU8)0xCFB) == 0x00)
- {
- DbgPrint((DPRINT_HWDETECT, "Pci bus type 2 found\n"));
- return 2;
- }
-
- DbgPrint((DPRINT_HWDETECT, "No pci bus found\n"));
- return 0;
-}
-
-static U32
-HalpGetPciData(U32 BusNumber,
- U32 SlotNumber,
- PVOID Buffer,
- U32 Offset,
- U32 Length)
-{
- PVOID Ptr = Buffer;
- U32 Address = Offset;
- U32 Len = Length;
- U32 Vendor;
- UCHAR HeaderType;
-
- if ((Length == 0) || (PciBusConfigType == 0))
- return 0;
-
- ReadPciConfigUlong(BusNumber,
- SlotNumber & 0x1F,
- 0x00,
- &Vendor);
- /* some broken boards return 0 if a slot is empty: */
- if (Vendor == 0xFFFFFFFF || Vendor == 0)
- {
- if (BusNumber == 0 && Offset == 0 && Length >= 2)
- {
- *(PU16)Buffer = PCI_INVALID_VENDORID;
- return 2;
- }
- return 0;
- }
-
- /* 0E=PCI_HEADER_TYPE */
- ReadPciConfigUchar(BusNumber,
- SlotNumber & 0x1F,
- 0x0E,
- &HeaderType);
- if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0))
- {
- if (Offset == 0 && Length >= 2)
- {
- *(PU16)Buffer = PCI_INVALID_VENDORID;
- return 2;
- }
- return 0;
- }
- ReadPciConfigUlong(BusNumber,
- SlotNumber,
- 0x00,
- &Vendor);
-
- /* some broken boards return 0 if a slot is empty: */
- if (Vendor == 0xFFFFFFFF || Vendor == 0)
- {
- if (BusNumber == 0 && Offset == 0 && Length >= 2)
- {
- *(PU16)Buffer = PCI_INVALID_VENDORID;
- return 2;
- }
- return 0;
- }
-
- if ((Address & 1) && (Len >= 1))
- {
- ReadPciConfigUchar(BusNumber,
- SlotNumber,
- Address,
- Ptr);
- Ptr = Ptr + 1;
- Address++;
- Len--;
- }
-
- if ((Address & 2) && (Len >= 2))
- {
- ReadPciConfigUshort(BusNumber,
- SlotNumber,
- Address,
- Ptr);
- Ptr = Ptr + 2;
- Address += 2;
- Len -= 2;
- }
-
- while (Len >= 4)
- {
- ReadPciConfigUlong(BusNumber,
- SlotNumber,
- Address,
- Ptr);
- Ptr = Ptr + 4;
- Address += 4;
- Len -= 4;
- }
-
- if (Len >= 2)
- {
- ReadPciConfigUshort(BusNumber,
- SlotNumber,
- Address,
- Ptr);
- Ptr = Ptr + 2;
- Address += 2;
- Len -= 2;
- }
-
- if (Len >= 1)
- {
- ReadPciConfigUchar(BusNumber,
- SlotNumber,
- Address,
- Ptr);
- Ptr = Ptr + 1;
- Address++;
- Len--;
- }
-
- return Length - Len;
-}
-
-U32
-HalGetBusDataByOffset(BUS_DATA_TYPE BusDataType,
- U32 BusNumber,
- U32 SlotNumber,
- PVOID Buffer,
- U32 Offset,
- U32 Length)
-{
- U32 Result;
-
- if (BusDataType == PCIConfiguration)
- {
- Result = HalpGetPciData(BusNumber,
- SlotNumber,
- Buffer,
- Offset,
- Length);
- }
- else
- {
- DbgPrint((DPRINT_WARNING, "Unknown bus data type %d", (U32) BusDataType));
- Result = 0;
- }
-
- return Result;
-}
-
-U32
-HalGetBusData(BUS_DATA_TYPE BusDataType,
- U32 BusNumber,
- U32 SlotNumber,
- PVOID Buffer,
- U32 Length)
-{
- return (HalGetBusDataByOffset(BusDataType,
- BusNumber,
- SlotNumber,
- Buffer,
- 0,
- Length));
-}
-
-/* ***** END Bus ***** */
-
-
-
-/* ***** BEGIN Helper functions ***** */
-
-static LIST_ENTRY BusKeyListHead; /* REGISTRY_BUS_INFORMATION */
-
-static VOID
-RegisterBusKey(HKEY Key, INTERFACE_TYPE BusType, U32 BusNumber)
-{
- PREGISTRY_BUS_INFORMATION BusKey;
-
- BusKey = MmAllocateMemory(sizeof(REGISTRY_BUS_INFORMATION));
- if (BusKey == NULL)
- return;
-
- BusKey->BusType = BusType;
- BusKey->BusNumber = BusNumber;
- InsertTailList(&BusKeyListHead, &BusKey->ListEntry);
-}
-
-#if 0
-static HKEY
-GetBusKey(INTERFACE_TYPE BusType, U32 BusNumber)
-{
- PREGISTRY_BUS_INFORMATION BusKey;
- PLIST_ENTRY ListEntry;
-
- ListEntry = BusKeyListHead.Flink;
- while (ListEntry != &BusKeyListHead)
- {
- BusKey = CONTAINING_RECORD(ListEntry,
- REGISTRY_BUS_INFORMATION,
- ListEntry);
-
- if ((BusKey->BusType == BusType) && (BusKey->BusNumber == BusNumber))
- {
- return BusKey->BusKey;
- }
-
- ListEntry = ListEntry->Flink;
- }
-
- DbgPrint((DPRINT_WARNING, "Key not found for BysType %d and BusNumber %d\n",
- BusType, BusNumber));
- return NULL;
-}
-#endif
-
-static HKEY
-CreateOrOpenKey(HKEY RelativeKey, PCHAR KeyName)
-{
- HKEY Key;
- S32 Error;
-
- Error = RegOpenKey(RelativeKey,
- KeyName,
- &Key);
- if (Error == ERROR_SUCCESS)
- {
- return Key;
- }
-
- Error = RegCreateKey(RelativeKey,
- KeyName,
- &Key);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
- return NULL;
- }
-
- return Key;
-}
-
-/* ***** END Helper functions ***** */
-
-
-#if 0
-/* ***** BEGIN ATA ***** */
-
-typedef struct _PCI_NATIVE_CONTROLLER
-{
- U16 VendorID;
- U16 DeviceID;
-} PCI_NATIVE_CONTROLLER, *PPCI_NATIVE_CONTROLLER;
-
-PCI_NATIVE_CONTROLLER const PciNativeController[] =
-{
- {
- 0x105A, // Promise
- 0x4D68, // PDC20268, Ultra100TX2
- },
- {
- 0x105A, // Promise
- 0x4D30, // PDC20267, Ultra100
- }
-};
-
-static PCI_SLOT_NUMBER LastSlotNumber;
-
-static BOOLEAN AtdiskPrimaryClaimed = FALSE;
-static BOOLEAN AtdiskSecondaryClaimed = FALSE;
-
-inline void
-IDESwapBytePairs(char *Buf,
- int Cnt)
-{
- char t;
- int i;
-
- for (i = 0; i < Cnt; i += 2)
- {
- t = Buf[i];
- Buf[i] = Buf[i+1];
- Buf[i+1] = t;
- }
-}
-
-/*
- * AtapiPolledRead
- *
- * DESCRIPTION:
- * Read a sector of data from the drive in a polled fashion.
- * ARGUMENTS:
- * CommandPort
- * Address of command port for drive
- * ControlPort
- * Address of control port for drive
- * PreComp
- * Value to write to precomp register
- * SectorCnt
- * Value to write to sectorCnt register
- * SectorNum
- * Value to write to sectorNum register
- * CylinderLow
- * Value to write to CylinderLow register
- * CylinderHigh
- * Value to write to CylinderHigh register
- * DrvHead
- * Value to write to Drive/Head register
- * Command
- * Value to write to Command register
- * Buffer
- * Buffer for output data
- * RETURNS:
- * 0 is success, non 0 is an error code
- */
-static S32
-AtapiPolledRead(U32 CommandPort,
- U32 ControlPort,
- U8 PreComp,
- U8 SectorCnt,
- U8 SectorNum,
- U8 CylinderLow,
- U8 CylinderHigh,
- U8 DrvHead,
- U8 Command,
- U8 *Buffer)
-{
- U32 SectorCount = 0;
- U32 RetryCount;
- BOOLEAN Junk = FALSE;
- U8 Status;
-
- /* Wait for BUSY to clear */
- for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
- {
- Status = IDEReadStatus(CommandPort);
- if (!(Status & IDE_SR_BUSY))
- {
- break;
- }
- KeStallExecutionProcessor(10);
- }
- if (RetryCount >= IDE_MAX_BUSY_RETRIES)
- {
- DbgPrint((DPRINT_HWDETECT, "Drive is BUSY for too long\n"));
- return(IDE_ER_ABRT);
- }
-
- /* Write Drive/Head to select drive */
- IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
- KeStallExecutionProcessor(500);
-
- /* Disable interrupts */
- IDEWriteDriveControl(ControlPort, IDE_DC_nIEN);
- KeStallExecutionProcessor(500);
-
- /* Issue command to drive */
- if (DrvHead & IDE_DH_LBA)
- {
- DbgPrint((DPRINT_HWDETECT, "READ:DRV=%d:LBA=1:BLK=%d:SC=%x:CM=%x\n",
- DrvHead & IDE_DH_DRV1 ? 1 : 0,
- ((DrvHead & 0x0f) << 24) + (CylinderHigh << 16) + (CylinderLow << 8) + SectorNum,
- SectorCnt,
- Command));
- }
- else
- {
- DbgPrint((DPRINT_HWDETECT, "READ:DRV=%d:LBA=0:CH=%x:CL=%x:HD=%x:SN=%x:SC=%x:CM=%x\n",
- DrvHead & IDE_DH_DRV1 ? 1 : 0,
- CylinderHigh,
- CylinderLow,
- DrvHead & 0x0f,
- SectorNum,
- SectorCnt,
- Command));
- }
-
- /* Setup command parameters */
- IDEWritePrecomp(CommandPort, PreComp);
- IDEWriteSectorCount(CommandPort, SectorCnt);
- IDEWriteSectorNum(CommandPort, SectorNum);
- IDEWriteCylinderHigh(CommandPort, CylinderHigh);
- IDEWriteCylinderLow(CommandPort, CylinderLow);
- IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
-
- /* Issue the command */
- IDEWriteCommand(CommandPort, Command);
- KeStallExecutionProcessor(50);
-
- /* wait for DRQ or error */
- for (RetryCount = 0; RetryCount < IDE_MAX_POLL_RETRIES; RetryCount++)
- {
- Status = IDEReadStatus(CommandPort);
- if (!(Status & IDE_SR_BUSY))
- {
- if (Status & IDE_SR_ERR)
- {
- IDEWriteDriveControl(ControlPort, 0);
- KeStallExecutionProcessor(50);
- IDEReadStatus(CommandPort);
-
- return(IDE_ER_ABRT);
- }
- if (Status & IDE_SR_DRQ)
- {
- break;
- }
- else
- {
- IDEWriteDriveControl(ControlPort, 0);
- KeStallExecutionProcessor(50);
- IDEReadStatus(CommandPort);
-
- return(IDE_ER_ABRT);
- }
- }
- KeStallExecutionProcessor(10);
- }
-
- /* timed out */
- if (RetryCount >= IDE_MAX_POLL_RETRIES)
- {
- IDEWriteDriveControl(ControlPort, 0);
- KeStallExecutionProcessor(50);
- IDEReadStatus(CommandPort);
-
- return(IDE_ER_ABRT);
- }
-
- while (1)
- {
- /* Read data into buffer */
- if (Junk == FALSE)
- {
- IDEReadBlock(CommandPort, Buffer, IDE_SECTOR_BUF_SZ);
- Buffer += IDE_SECTOR_BUF_SZ;
- }
- else
- {
- U8 JunkBuffer[IDE_SECTOR_BUF_SZ];
- IDEReadBlock(CommandPort, JunkBuffer, IDE_SECTOR_BUF_SZ);
- }
- SectorCount++;
-
- /* Check for error or more sectors to read */
- for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
- {
- Status = IDEReadStatus(CommandPort);
- if (!(Status & IDE_SR_BUSY))
- {
- if (Status & IDE_SR_ERR)
- {
- IDEWriteDriveControl(ControlPort, 0);
- KeStallExecutionProcessor(50);
- IDEReadStatus(CommandPort);
-
- return(IDE_ER_ABRT);
- }
- if (Status & IDE_SR_DRQ)
- {
- if (SectorCount >= SectorCnt)
- {
- DbgPrint((DPRINT_HWDETECT, "Buffer size exceeded\n"));
- Junk = TRUE;
- }
- break;
- }
- else
- {
- if (SectorCount > SectorCnt)
- {
- DbgPrint((DPRINT_HWDETECT, "Read %d sectors of junk\n",
- SectorCount - SectorCnt));
- }
- IDEWriteDriveControl(ControlPort, 0);
- KeStallExecutionProcessor(50);
- IDEReadStatus(CommandPort);
-
- return(0);
- }
- }
- }
- }
-}
-
-/*
- * AtapiIdentifyDevice
- *
- * DESCRIPTION:
- * Get the identification block from the drive
- *
- * ARGUMENTS:
- * CommandPort
- * Address of the command port
- * ControlPort
- * Address of the control port
- * DriveNum
- * The drive index (0,1)
- * Atapi
- * Send an ATA(FALSE) or an ATAPI(TRUE) identify comand
- * DrvParms
- * Address to write drive identication block
- *
- * RETURNS:
- * TRUE: The drive identification block was retrieved successfully
- * FALSE: an error ocurred
- */
-static BOOLEAN
-AtapiIdentifyDevice(U32 CommandPort,
- U32 ControlPort,
- U32 DriveNum,
- BOOLEAN Atapi,
- PIDE_DRIVE_IDENTIFY DrvParms)
-{
- S32 i;
-
- /* Get the Drive Identify block from drive or die */
- if (AtapiPolledRead(CommandPort,
- ControlPort,
- 0,
- 1,
- 0,
- 0,
- 0,
- (DriveNum ? IDE_DH_DRV1 : 0),
- (Atapi ? IDE_CMD_IDENT_ATAPI_DRV : IDE_CMD_IDENT_ATA_DRV),
- (PU8)DrvParms) != 0)
- {
- DbgPrint((DPRINT_HWDETECT, "IDEPolledRead() failed\n"));
- return(FALSE);
- }
-
- /* Report on drive parameters if debug mode */
- IDESwapBytePairs(DrvParms->SerialNumber, 20);
- IDESwapBytePairs(DrvParms->FirmwareRev, 8);
- IDESwapBytePairs(DrvParms->ModelNumber, 40);
- DbgPrint((DPRINT_HWDETECT, "Config:%x Cyls:%d Heads:%d Sectors/Track:%d Gaps:%d %d\n",
- DrvParms->ConfigBits,
- DrvParms->LogicalCyls,
- DrvParms->LogicalHeads,
- DrvParms->SectorsPerTrack,
- DrvParms->InterSectorGap,
- DrvParms->InterSectorGapSize));
- DbgPrint((DPRINT_HWDETECT, "Bytes/PLO:%d Vendor Cnt:%d Serial number:[%s]\n",
- DrvParms->BytesInPLO,
- DrvParms->VendorUniqueCnt,
- DrvParms->SerialNumber));
- DbgPrint((DPRINT_HWDETECT, "Cntlr type:%d BufSiz:%d ECC bytes:%d Firmware Rev:[%s]\n",
- DrvParms->ControllerType,
- DrvParms->BufferSize * IDE_SECTOR_BUF_SZ,
- DrvParms->ECCByteCnt,
- DrvParms->FirmwareRev));
- DbgPrint((DPRINT_HWDETECT, "Model:[%s]\n", DrvParms->ModelNumber));
- DbgPrint((DPRINT_HWDETECT, "RWMultMax?:%x RWMult?:%x LBA:%d DMA:%d MinPIO:%d ns MinDMA:%d ns\n",
- (DrvParms->RWMultImplemented),
- (DrvParms->RWMultCurrent) & 0xff,
- (DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED) ? 1 : 0,
- (DrvParms->Capabilities & IDE_DRID_DMA_SUPPORTED) ? 1 : 0,
- DrvParms->MinPIOTransTime,
- DrvParms->MinDMATransTime));
- DbgPrint((DPRINT_HWDETECT, "TM:Cyls:%d Heads:%d Sectors/Trk:%d Capacity:%d\n",
- DrvParms->TMCylinders,
- DrvParms->TMHeads,
- DrvParms->TMSectorsPerTrk,
- (U32)(DrvParms->TMCapacityLo + (DrvParms->TMCapacityHi << 16))));
-
- DbgPrint((DPRINT_HWDETECT, "TM:SectorCount: 0x%x%x = %d\n",
- DrvParms->TMSectorCountHi,
- DrvParms->TMSectorCountLo,
- (U32)((DrvParms->TMSectorCountHi << 16) + DrvParms->TMSectorCountLo)));
-
- if (!Atapi && 0 != (DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED))
- {
- /* LBA ATA drives always have a sector size of 512 */
- DrvParms->BytesPerSector = 512;
- }
- else
- {
- if (DrvParms->BytesPerSector == 0)
- {
- DbgPrint((DPRINT_HWDETECT, "BytesPerSector is 0. Defaulting to 512\n"));
- DrvParms->BytesPerSector = 512;
- }
- else
- {
- DbgPrint((DPRINT_HWDETECT, "BytesPerSector %d\n", DrvParms->BytesPerSector));
- for (i = 15; i >= 0; i--)
- {
- if (DrvParms->BytesPerSector & (1 << i))
- {
- DrvParms->BytesPerSector = 1 << i;
- break;
- }
- }
- }
- }
- DbgPrint((DPRINT_HWDETECT, "BytesPerSector %d\n", DrvParms->BytesPerSector));
-
- return(TRUE);
-}
-
-/*
- * AtapiFindDevices
- *
- * DESCRIPTION:
- * Find all devices on a controller
- *
- * ARGUMENTS:
- * CommandPort
- * Address of the command port
- * ControlPort
- * Address of the control port
- * DeviceParams
- * Buffer for drive parameters
- *
- * RETURNS:
- * Number of devices found
- */
-static U32
-AtapiFindDevices(U32 CommandPortBase,
- U32 ControlPortBase,
- PIDE_DRIVE_IDENTIFY DeviceParams)
-{
- U32 DevicesFound = 0;
- U32 UnitNumber;
- U32 Retries;
- U8 High, Low;
-
- DbgPrint((DPRINT_HWDETECT, "AtapiFindDevices(CommandPortBase: %x, ControlPortBase %x)\n",
- CommandPortBase, ControlPortBase));
-
- for (UnitNumber = 0; UnitNumber < 2; UnitNumber++)
- {
- /* Select drive */
- IDEWriteDriveHead(CommandPortBase,
- IDE_DH_FIXED | (UnitNumber ? IDE_DH_DRV1 : 0));
- KeStallExecutionProcessor(500);
-
- /* Disable interrupts */
- IDEWriteDriveControl(ControlPortBase,
- IDE_DC_nIEN);
- KeStallExecutionProcessor(500);
-
- /* Check if a device is attached to the interface */
- IDEWriteCylinderHigh(CommandPortBase, 0xaa);
- IDEWriteCylinderLow(CommandPortBase, 0x55);
-
- High = IDEReadCylinderHigh(CommandPortBase);
- Low = IDEReadCylinderLow(CommandPortBase);
-
- IDEWriteCylinderHigh(CommandPortBase, 0);
- IDEWriteCylinderLow(CommandPortBase, 0);
-
- if (Low != 0x55 || High != 0xaa)
- {
- DbgPrint((DPRINT_HWDETECT, "No Drive found. UnitNumber %d CommandPortBase %x\n",
- UnitNumber, CommandPortBase));
- continue;
- }
-
- IDEWriteCommand(CommandPortBase, IDE_CMD_RESET);
-
- for (Retries = 0; Retries < 20000; Retries++)
- {
- if (!(IDEReadStatus(CommandPortBase) & IDE_SR_BUSY))
- {
- break;
- }
- KeStallExecutionProcessor(150);
- }
-
- if (Retries >= 20000)
- {
- DbgPrint((DPRINT_HWDETECT, "Timeout on drive %d\n", UnitNumber));
- continue;
- }
-
- High = IDEReadCylinderHigh(CommandPortBase);
- Low = IDEReadCylinderLow(CommandPortBase);
-
- DbgPrint((DPRINT_HWDETECT, "Check drive %d: High 0x%x Low 0x%x\n",
- UnitNumber,
- High,
- Low));
-
- if (High == 0xEB && Low == 0x14)
- {
- if (AtapiIdentifyDevice(CommandPortBase,
- ControlPortBase,
- UnitNumber,
- TRUE,
- &DeviceParams[UnitNumber]))
- {
- DbgPrint((DPRINT_HWDETECT, "ATAPI drive found\n"));
- DevicesFound++;
- }
- else
- {
- DbgPrint((DPRINT_HWDETECT, "No ATAPI drive found\n"));
- }
- }
- else
- {
- if (AtapiIdentifyDevice(CommandPortBase,
- ControlPortBase,
- UnitNumber,
- FALSE,
- &DeviceParams[UnitNumber]))
- {
- DbgPrint((DPRINT_HWDETECT, "IDE drive found\n"));
- DevicesFound++;
- }
- else
- {
- DbgPrint((DPRINT_HWDETECT, "No IDE drive found\n"));
- }
- }
- }
-
- /* Reset pending interrupts */
- IDEReadStatus(CommandPortBase);
- /* Reenable interrupts */
- IDEWriteDriveControl(ControlPortBase, 0);
- KeStallExecutionProcessor(500);
- /* Return with drive 0 selected */
- IDEWriteDriveHead(CommandPortBase, IDE_DH_FIXED);
- KeStallExecutionProcessor(500);
-
- DbgPrint((DPRINT_HWDETECT, "AtapiFindDevices() Done (DevicesFound %d)\n", DevicesFound));
-
- return(DevicesFound);
-}
-
-// TRUE if a controller was found, FALSE if not
-static BOOLEAN
-AtapiFindCompatiblePciController(U32 SystemIoBusNumber,
- PU32 SystemSlotNumber,
- PU32 CommandPortBase,
- PU32 ControlPortBase,
- PU32 BusMasterPortBase,
- PU32 InterruptVector,
- PU32 DevicesFound,
- PIDE_DRIVE_IDENTIFY DeviceParams,
- PBOOLEAN Again)
-{
- PCI_SLOT_NUMBER SlotNumber;
- PCI_COMMON_CONFIG PciConfig;
- U32 DataSize;
- U32 StartDeviceNumber;
- U32 DeviceNumber;
- U32 StartFunctionNumber;
- U32 FunctionNumber;
- BOOLEAN ChannelFound;
- U32 BusMasterBasePort = 0;
-
- *Again = FALSE;
-
- /* both channels were claimed: exit */
- if (AtdiskPrimaryClaimed == TRUE &&
- AtdiskSecondaryClaimed == TRUE)
- return FALSE;
-
- SlotNumber.u.AsULONG = *SystemSlotNumber;
- StartDeviceNumber = SlotNumber.u.bits.DeviceNumber;
- StartFunctionNumber = SlotNumber.u.bits.FunctionNumber;
- for (DeviceNumber = StartDeviceNumber; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
- {
- SlotNumber.u.bits.DeviceNumber = DeviceNumber;
- for (FunctionNumber = StartFunctionNumber; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
- {
- SlotNumber.u.bits.FunctionNumber = FunctionNumber;
- ChannelFound = FALSE;
-
- DataSize = HalGetBusData(PCIConfiguration,
- SystemIoBusNumber,
- SlotNumber.u.AsULONG,
- &PciConfig,
- PCI_COMMON_HDR_LENGTH);
- if (DataSize != PCI_COMMON_HDR_LENGTH)
- {
- if (FunctionNumber == 0)
- {
- break;
- }
- else
- {
- continue;
- }
- }
-
- DbgPrint((DPRINT_HWDETECT, "BaseClass %x SubClass %x\n", PciConfig.BaseClass, PciConfig.SubClass));
- if (PciConfig.BaseClass == 0x01 &&
- PciConfig.SubClass == 0x01)
- {
- /* both channels are in compatibility mode */
- DbgPrint((DPRINT_HWDETECT, "Bus %d Device %d Func %d VenID 0x%x DevID 0x%x\n",
- SystemIoBusNumber,
- SlotNumber.u.bits.DeviceNumber,
- SlotNumber.u.bits.FunctionNumber,
- PciConfig.VendorID,
- PciConfig.DeviceID));
-
- DbgPrint((DPRINT_HWDETECT, "Found IDE controller in compatibility mode\n"));
-
- if (PciConfig.ProgIf & 0x80)
- {
- DbgPrint((DPRINT_HWDETECT, "Found IDE Bus Master controller!\n"));
- if (PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_SPACE)
- {
- BusMasterBasePort = PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_ADDRESS_MASK;
- DbgPrint((DPRINT_HWDETECT, "IDE Bus Master Registers at IO %x\n", BusMasterBasePort));
- }
- }
- if (AtdiskPrimaryClaimed == FALSE)
- {
- /* Both channels unclaimed: Claim primary channel */
- DbgPrint((DPRINT_HWDETECT, "Primary channel\n"));
- AtdiskPrimaryClaimed = TRUE;
- *CommandPortBase = 0x1F0;
- *ControlPortBase = 0x3F4;
- *BusMasterPortBase = BusMasterBasePort;
- *InterruptVector = 14;
- *Again = TRUE;
-
- }
- else if (AtdiskSecondaryClaimed == FALSE)
- {
- /* Primary channel already claimed: claim secondary channel */
- DbgPrint((DPRINT_HWDETECT, "Secondary channel\n"));
- AtdiskSecondaryClaimed = TRUE;
- *CommandPortBase = 0x170;
- *ControlPortBase = 0x374;
- *BusMasterPortBase = BusMasterBasePort ? BusMasterBasePort + 8 : 0;
- *InterruptVector = 15;
- *Again = FALSE;
- }
-
- /* Find attached devices */
- *DevicesFound = AtapiFindDevices(*CommandPortBase, *ControlPortBase, DeviceParams);
- *SystemSlotNumber = SlotNumber.u.AsULONG;
- return TRUE;
- }
-
- if (FunctionNumber == 0 && !(PciConfig.HeaderType & PCI_MULTIFUNCTION))
- {
- break;
- }
- }
- StartFunctionNumber = 0;
- }
- return FALSE;
-}
-
-// TRUE if a controller was found, FALSE if not
-static BOOLEAN
-AtapiFindNativePciController(U32 SystemIoBusNumber,
- PU32 SystemSlotNumber,
- PU32 CommandPortBase,
- PU32 ControlPortBase,
- PU32 BusMasterPortBase,
- PU32 InterruptVector,
- PU32 DevicesFound,
- PIDE_DRIVE_IDENTIFY DeviceParams,
- PBOOLEAN Again)
-{
- PCI_COMMON_CONFIG PciConfig;
- PCI_SLOT_NUMBER SlotNumber;
- U32 DataSize;
- U32 DeviceNumber;
- U32 StartDeviceNumber;
- U32 FunctionNumber;
- U32 StartFunctionNumber;
- U32 BusMasterBasePort;
- U32 Count;
- BOOLEAN ChannelFound;
-
- SlotNumber.u.AsULONG = *SystemSlotNumber;
- StartDeviceNumber = SlotNumber.u.bits.DeviceNumber;
- StartFunctionNumber = SlotNumber.u.bits.FunctionNumber;
- for (DeviceNumber = StartDeviceNumber; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
- {
- SlotNumber.u.bits.DeviceNumber = DeviceNumber;
- for (FunctionNumber = StartFunctionNumber; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
- {
- SlotNumber.u.bits.FunctionNumber = FunctionNumber;
- DataSize = HalGetBusData(PCIConfiguration,
- SystemIoBusNumber,
- SlotNumber.u.AsULONG,
- &PciConfig,
- PCI_COMMON_HDR_LENGTH);
- if (DataSize != PCI_COMMON_HDR_LENGTH)
- {
- break;
- }
- for (Count = 0; Count < sizeof(PciNativeController)/sizeof(PCI_NATIVE_CONTROLLER); Count++)
- {
- if (PciConfig.VendorID == PciNativeController[Count].VendorID &&
- PciConfig.DeviceID == PciNativeController[Count].DeviceID)
- {
- break;
- }
- }
- if (Count < sizeof(PciNativeController)/sizeof(PCI_NATIVE_CONTROLLER))
- {
- /* We have found a known native pci ide controller */
- if ((PciConfig.ProgIf & 0x80) && (PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_SPACE))
- {
- DbgPrint((DPRINT_HWDETECT, "Found IDE Bus Master controller\n"));
- BusMasterBasePort = PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_ADDRESS_MASK;
- DbgPrint((DPRINT_HWDETECT, "IDE Bus Master Registers at IO %x\n", BusMasterBasePort));
- }
- else
- {
- BusMasterBasePort = 0;
- }
-
- DbgPrint((DPRINT_HWDETECT, "VendorID: %04x, DeviceID: %04x\n",
- PciConfig.VendorID, PciConfig.DeviceID));
- ChannelFound = FALSE;
- if (LastSlotNumber.u.AsULONG != SlotNumber.u.AsULONG)
- {
- /* primary channel */
- if ((PciConfig.u.type0.BaseAddresses[0] & PCI_ADDRESS_IO_SPACE) &&
- (PciConfig.u.type0.BaseAddresses[1] & PCI_ADDRESS_IO_SPACE))
- {
- /* primary channel is enabled */
- ChannelFound = TRUE;
- *CommandPortBase = PciConfig.u.type0.BaseAddresses[0] & PCI_ADDRESS_IO_ADDRESS_MASK;
- *ControlPortBase = PciConfig.u.type0.BaseAddresses[1] & PCI_ADDRESS_IO_ADDRESS_MASK;
- *BusMasterPortBase = BusMasterBasePort;
- *InterruptVector = PciConfig.u.type0.InterruptLine;
-
- if (ChannelFound)
- {
- *DevicesFound = AtapiFindDevices(*CommandPortBase, *ControlPortBase, DeviceParams);
- *Again = TRUE;
- *SystemSlotNumber = LastSlotNumber.u.AsULONG = SlotNumber.u.AsULONG;
- return(TRUE);
- }
- }
- }
- if (!ChannelFound)
- {
- /* secondary channel */
- if ((PciConfig.u.type0.BaseAddresses[2] & PCI_ADDRESS_IO_SPACE) &&
- (PciConfig.u.type0.BaseAddresses[3] & PCI_ADDRESS_IO_SPACE))
- {
- /* secondary channel is enabled */
- *CommandPortBase = PciConfig.u.type0.BaseAddresses[2] & PCI_ADDRESS_IO_ADDRESS_MASK;
- *ControlPortBase = PciConfig.u.type0.BaseAddresses[3] & PCI_ADDRESS_IO_ADDRESS_MASK;
- *BusMasterPortBase = BusMasterBasePort ? BusMasterBasePort + 8 : 0;
- *InterruptVector = PciConfig.u.type0.InterruptLine;
-
- if (ChannelFound)
- {
- *DevicesFound = AtapiFindDevices(*CommandPortBase, *ControlPortBase, DeviceParams);
- *Again = FALSE;
- LastSlotNumber.u.AsULONG = 0xFFFFFFFF;
- return(TRUE);
- }
- }
- }
- }
- }
- StartFunctionNumber = 0;
- }
- *Again = FALSE;
- LastSlotNumber.u.AsULONG = 0xFFFFFFFF;
-
- return(FALSE);
-}
-
-// TRUE if a controller was found, FALSE if not
-static BOOLEAN
-AtapiFindIsaBusController(U32 SystemIoBusNumber,
- PU32 SystemSlotNumber,
- PU32 CommandPortBase,
- PU32 ControlPortBase,
- PU32 BusMasterPortBase,
- PU32 InterruptVector,
- PU32 DevicesFound,
- PIDE_DRIVE_IDENTIFY DeviceParams,
- PBOOLEAN Again)
-{
- BOOLEAN ChannelFound = FALSE;
-
- *Again = FALSE;
-
- if (AtdiskPrimaryClaimed == FALSE)
- {
- /* Both channels unclaimed: Claim primary channel */
- DbgPrint((DPRINT_HWDETECT, "Primary channel\n"));
- AtdiskPrimaryClaimed = TRUE;
- ChannelFound = TRUE;
- *CommandPortBase = 0x1F0;
- *ControlPortBase = 0x3F4;
- *BusMasterPortBase = 0;
- *InterruptVector = 14;
- *Again = TRUE;
- }
- else if (AtdiskSecondaryClaimed == FALSE)
- {
- /* Primary channel already claimed: claim secondary channel */
- DbgPrint((DPRINT_HWDETECT, "Secondary channel\n"));
- AtdiskSecondaryClaimed = TRUE;
- ChannelFound = TRUE;
- *CommandPortBase = 0x170;
- *ControlPortBase = 0x374;
- *BusMasterPortBase = 0;
- *InterruptVector = 15;
- *Again = FALSE;
- }
- else
- {
- DbgPrint((DPRINT_HWDETECT, "AtapiFindIsaBusController() both channels claimed\n"));
- *Again = FALSE;
- return(FALSE);
- }
-
- /* Find attached devices */
- if (ChannelFound)
- {
- *DevicesFound = AtapiFindDevices(*CommandPortBase, *ControlPortBase, DeviceParams);
- return(TRUE);
- }
- *Again = FALSE;
- return(FALSE);
-}
-
-#if 0
-static VOID
-FindIDEControllers(PDETECTED_STORAGE DetectedStorage)
-{
- U32 SystemIoBusNumber;
- U32 SystemSlotNumber;
- U32 CommandPortBase;
- U32 ControlPortBase;
- U32 BusMasterPortBase;
- U32 InterruptVector;
- U32 DevicesFound;
- PDETECTED_STORAGE_CONTROLLER StorageController;
- BOOLEAN Again;
- BOOLEAN Found;
- U32 MaxBus;
-
- AtdiskPrimaryClaimed = FALSE;
- AtdiskSecondaryClaimed = FALSE;
-
-/* Search the PCI bus for all IDE controllers */
-
- MaxBus = 8; /* Max 8 PCI busses */
-
- SystemIoBusNumber = 0;
- SystemSlotNumber = 0;
-
- while (TRUE)
- {
- /* Search the PCI bus for compatibility mode IDE controllers */
- StorageController = MmAllocateMemory(sizeof(DETECTED_STORAGE_CONTROLLER));
- Found = AtapiFindCompatiblePciController(SystemIoBusNumber,
- &SystemSlotNumber,
- &CommandPortBase,
- &ControlPortBase,
- &BusMasterPortBase,
- &InterruptVector,
- &DevicesFound,
- &StorageController->IdeDriveIdentify[0],
- &Again);
-
- if (Found)
- {
- DbgPrint((DPRINT_HWDETECT, "Found compatible IDE controller\n"));
-
- StorageController->DriveCount = DevicesFound;
- StorageController->BusType = PCIBus;
- StorageController->BusNumber = SystemIoBusNumber;
- InsertTailList(&DetectedStorage->StorageControllers,
- &StorageController->ListEntry);
- }
- else
- {
- MmFreeMemory(StorageController);
- }
-
- if (Again == FALSE)
- {
- SystemIoBusNumber++;
- SystemSlotNumber = 0;
- }
-
- if (SystemIoBusNumber >= MaxBus)
- {
- DbgPrint((DPRINT_HWDETECT, "Scanned all PCI buses\n"));
- break;
- }
- }
-
- /* Search the PCI bus for all IDE controllers */
-
- SystemIoBusNumber = 0;
- SystemSlotNumber = 0;
-
- LastSlotNumber.u.AsULONG = 0;
-
- while (TRUE)
- {
- /* Search the PCI bus for native PCI IDE controllers */
- StorageController = MmAllocateMemory(sizeof(DETECTED_STORAGE_CONTROLLER));
- Found = AtapiFindNativePciController(SystemIoBusNumber,
- &SystemSlotNumber,
- &CommandPortBase,
- &ControlPortBase,
- &BusMasterPortBase,
- &InterruptVector,
- &DevicesFound,
- &StorageController->IdeDriveIdentify[0],
- &Again);
-
- if (Found)
- {
- DbgPrint((DPRINT_HWDETECT, "Found native PCI IDE controller\n"));
-
- StorageController->DriveCount = DevicesFound;
- StorageController->BusType = PCIBus;
- StorageController->BusNumber = SystemIoBusNumber;
- InsertTailList(&DetectedStorage->StorageControllers,
- &StorageController->ListEntry);
- }
-
- if (Again == FALSE)
- {
- SystemIoBusNumber++;
- SystemSlotNumber = 0;
- }
- else
- {
- MmFreeMemory(StorageController);
- }
-
- if (SystemIoBusNumber >= MaxBus)
- {
- DbgPrint((DPRINT_HWDETECT, "Scanned all PCI buses\n"));
- break;
- }
- }
-
- LastSlotNumber.u.AsULONG = 0xFFFFFFFF;
-
- SystemIoBusNumber = 0;
- SystemSlotNumber = 0;
-
- LastSlotNumber.u.AsULONG = 0;
-
- while (TRUE)
- {
- /* Search the ISA bus for an IDE controller */
- Found = AtapiFindIsaBusController(SystemIoBusNumber,
- &SystemSlotNumber,
- &CommandPortBase,
- &ControlPortBase,
- &BusMasterPortBase,
- &InterruptVector,
- &DevicesFound,
- &StorageController->IdeDriveIdentify[0],
- &Again);
-
- if (Found)
- {
- DbgPrint((DPRINT_HWDETECT, "Found ISA IDE controller\n"));
-
- StorageController->DriveCount = DevicesFound;
- StorageController->BusType = Isa;
- StorageController->BusNumber = SystemIoBusNumber;
- InsertTailList(&DetectedStorage->StorageControllers,
- &StorageController->ListEntry);
- }
- else
- {
- MmFreeMemory(StorageController);
- }
-
- if (Again == FALSE)
- {
- break;
- }
- }
-}
-#endif
-
-/* ***** END ATA ***** */
-#endif
-
-static VOID
-QueryBiosForDisks(PDETECTED_STORAGE DetectedStorage)
-{
- REGS RegsIn;
- REGS RegsOut;
- U32 Count;
- U32 DriveCount;
- U32 BiosDriveNumber;
- PDETECTED_DISK DetectedDisk;
-
- DriveCount = 1; /* Will set this on first successful query */
- for (Count = 0; Count < DriveCount; Count++)
- {
- // BIOS int 0x13, function 08h - Get Drive Parameters
- BiosDriveNumber = 0x80 + Count;
- RegsIn.b.ah = 0x08; // Subfunction 08h
- RegsIn.b.dl = BiosDriveNumber; // Drive number in DL (0 - floppy, 0x80 - harddisk)
- RegsIn.x.es = 0; // ES:DI -> 0000h:0000h to guard against BIOS bugs
- RegsIn.w.di = 0;
-
- // BIOS int 0x13, function 08h - Get Drive Parameters
- // AH = 08h
- // DL = drive (bit 7 set for hard disk)
- // ES:DI = 0000h:0000h to guard against BIOS bugs
- // Return:
- // CF clear if successful
- // AH = 00h
- // AL = 00h (on at least some BIOSes)
- // BL = drive type (AT/PS2 floppies only)
- // CH = low eight bits of maximum cylinder number
- // CL = maximum sector number (bits 5-0)
- // high two bits of maximum cylinder number (bits 7-6)
- // DH = maximum head number
- // DL = number of drives
- // ES:DI -> drive parameter table (floppies only)
- // CF set on error
- // AH = error code
- // See http://www.ctyme.com/intr/rb-0621.htm for notes about how to deal with
- // different hardware.
-
- Int386(0x13, &RegsIn, &RegsOut);
- if (!INT386_SUCCESS(RegsOut))
- {
- // Failed - assume no more disks
- return;
- }
-
- // Success
- DriveCount = RegsOut.b.dl;
- if (Count == 0)
- {
- DbgPrint((DPRINT_HWDETECT, "BIOS reports %d drives\n", (int) DriveCount));
- }
-
- DbgPrint((DPRINT_HWDETECT, "Checking BIOS drive 0x%x\n", (int) BiosDriveNumber));
- DbgPrint((DPRINT_HWDETECT, "Max. cylinder = %d\n", (int) (((RegsOut.b.cl & 0xc0) << 2) + RegsOut.b.ch)));
- DbgPrint((DPRINT_HWDETECT, "Max. sector number = %d\n", (int) RegsOut.b.cl & 0x3f));
- DbgPrint((DPRINT_HWDETECT, "Max. head number = %d\n", (int) RegsOut.b.dh));
-
- DetectedDisk = MmAllocateMemory(sizeof(DETECTED_DISK));
- DetectedDisk->BusType = Isa;
- DetectedDisk->BusNumber = 0;
- DetectedDisk->Int13DriveParameter.DriveSelect = BiosDriveNumber;
- DetectedDisk->Int13DriveParameter.MaxCylinders = ((RegsOut.b.cl & 0xc0) << 2) + RegsOut.b.ch;
- DetectedDisk->Int13DriveParameter.SectorsPerTrack = RegsOut.b.cl & 0x3f;
- DetectedDisk->Int13DriveParameter.MaxHeads = RegsOut.b.dh;
- DetectedDisk->Int13DriveParameter.NumberDrives = 0; /* Fill in later */
-
- InsertTailList(&DetectedStorage->Disks,
- &DetectedDisk->ListEntry);
- }
-}
-
-
-static VOID
-DetectStorage(VOID)
-{
- DETECTED_STORAGE DetectedStorage;
- PDETECTED_DISK DetectedDisk;
- PLIST_ENTRY ListEntry;
-// CHAR buf[200];
- S32 Error;
- HKEY SystemKey;
-
-/* U32 i;
- HKEY BusKey;
- HKEY DiskControllerKey;
- HKEY DiskPeripheralKey;
- HKEY DriveKey;*/
- U32 Size;
- U32 Count;
- U32 DriveCount;
- PCM_INT13_DRIVE_PARAMETER Int13Array;
- PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
-
- InitializeListHead(&DetectedStorage.Disks);
-
- QueryBiosForDisks(&DetectedStorage);
-
- /* Calculate number of drives */
- DriveCount = 0;
- ListEntry = DetectedStorage.Disks.Flink;
- while (ListEntry != &DetectedStorage.Disks)
- {
- DetectedDisk = CONTAINING_RECORD(ListEntry,
- DETECTED_DISK,
- ListEntry);
- DriveCount++;
- ListEntry = ListEntry->Flink;
- }
-
- if (DriveCount > 0)
- {
- Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + sizeof(CM_INT13_DRIVE_PARAMETER) * DriveCount;
- FullResourceDescriptor = MmAllocateMemory(Size);
- if (FullResourceDescriptor == NULL)
- {
- return;
- }
- memset(FullResourceDescriptor, 0, Size);
- FullResourceDescriptor->InterfaceType = InterfaceTypeUndefined;
- FullResourceDescriptor->BusNumber = -1;
- FullResourceDescriptor->PartialResourceList.Count = 1;
- FullResourceDescriptor->PartialResourceList.PartialDescriptors[0]
- .u.DeviceSpecificData.DataSize = sizeof(CM_INT13_DRIVE_PARAMETER) * DriveCount;
- Int13Array = ((PVOID) FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
- Count = 0;
- ListEntry = DetectedStorage.Disks.Flink;
- while (ListEntry != &DetectedStorage.Disks)
- {
- DetectedDisk = CONTAINING_RECORD(ListEntry,
- DETECTED_DISK,
- ListEntry);
- DetectedDisk->Int13DriveParameter.NumberDrives = DriveCount;
- memcpy(&Int13Array[Count], &DetectedDisk->Int13DriveParameter, sizeof(CM_INT13_DRIVE_PARAMETER));
-
- Count++;
- ListEntry = ListEntry->Flink;
- }
-
- /* Create or open System key */
- SystemKey = CreateOrOpenKey(NULL,
- "\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System");
- if (SystemKey == NULL)
- {
- DbgPrint((DPRINT_HWDETECT, "CreateOrOpenKey(System) failed\n"));
- MmFreeMemory(FullResourceDescriptor);
- return;
- }
-
- Error = RegSetValue(SystemKey,
- "Configuration Data",
- REG_FULL_RESOURCE_DESCRIPTOR,
- (PU8) FullResourceDescriptor,
- Size);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegSetValue(Configuration Data) failed (Error %u)\n", (int)Error));
- MmFreeMemory(FullResourceDescriptor);
- return;
- }
- MmFreeMemory(FullResourceDescriptor);
- }
-
-
-#if 0
- /* Write information to registry */
- ScsiPortNumber = 0;
- ListEntry = DetectedStorage.StorageControllers.Flink;
- while (ListEntry != &DetectedStorage.StorageControllers)
- {
- Controller = CONTAINING_RECORD(ListEntry,
- DETECTED_STORAGE_CONTROLLER,
- ListEntry);
-
- BusKey = GetBusKey(Controller->BusType, Controller->BusNumber);
-
- /* Create or open DiskController key */
- DiskControllerKey = CreateOrOpenKey(BusKey,
- "DiskController");
- if (DiskControllerKey == NULL)
- {
- DbgPrint((DPRINT_HWDETECT, "CreateOrOpenKey() failed\n"));
- return;
- }
-
- /* Create X key */
- sprintf(buf, "%d", (int) ScsiPortNumber);
- Error = RegCreateKey(DiskControllerKey,
- buf,
- &ScsiPortKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegCreateKey(X) failed (Error %u)\n", (int)Error));
- return;
- }
-
- /* FIXME: Create value: 'Component information' */
-
- /* FIXME: Create value: 'Configuration data' */
-
- /* Create DiskPeripheral key */
- sprintf(buf, "%d", (int) ScsiPortNumber);
- Error = RegCreateKey(ScsiPortKey,
- "DiskPeripheral",
- &DiskPeripheralKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegCreateKey(DiskPeripheral) failed (Error %u)\n", (int)Error));
- return;
- }
-
- for (i = 0; i < Controller->DriveCount; i++)
- {
- /* Create DiskPeripheral/X key */
- sprintf(buf, "%d", (int) i);
- Error = RegCreateKey(DiskPeripheralKey,
- buf,
- &DriveKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegCreateKey(DiskPeripheral/X) failed (Error %u)\n", (int)Error));
- return;
- }
-
- Int13.DriveSelect = 0; /* FIXME: What is this? */
- Int13.MaxCylinders = Controller->IdeDriveIdentify[i].TMCylinders;
- Int13.SectorsPerTrack = Controller->IdeDriveIdentify[i].TMSectorsPerTrk;
- Int13.MaxHeads = Controller->IdeDriveIdentify[i].TMHeads;
- Int13.NumberDrives = Controller->DriveCount; /* FIXME: This does not make sense */
- Error = RegSetValue(DriveKey,
- "Component information",
- REG_BINARY,
- (PU8) &Int13,
- sizeof(CM_INT13_DRIVE_PARAMETER));
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegSetValue(Component information) failed (Error %u)\n", (int)Error));
- return;
- }
-
- /* FIXME: Create value: 'Configuration data' */
- }
-
- ScsiPortNumber++;
- ListEntry = ListEntry->Flink;
- }
-
- DbgPrint((DPRINT_HWDETECT, "%d controllers found\n", ScsiPortNumber));
-#endif
-}
-
-static VOID
-PrepareRegistry()
-{
- HKEY HardwareKey;
- HKEY DescriptionKey;
- HKEY SystemKey;
- HKEY DeviceMapKey;
- HKEY ResourceMapKey;
- S32 Error;
-
- Error = RegOpenKey(NULL,
- "\\Registry\\Machine\\HARDWARE",
- &HardwareKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegOpenKey(HARDWARE) failed (Error %u)\n", (int)Error));
- return;
- }
-
- /* Create DESCRIPTION key */
- Error = RegCreateKey(HardwareKey,
- "DESCRIPTION",
- &DescriptionKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegCreateKey(DESCRIPTION) failed (Error %u)\n", (int)Error));
- return;
- }
-
- /* Create DESCRIPTION/System key */
- Error = RegCreateKey(DescriptionKey,
- "System",
- &SystemKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegCreateKey(System) failed (Error %u)\n", (int)Error));
- return;
- }
-
- /* Create DEVICEMAP key */
- Error = RegCreateKey(HardwareKey,
- "DEVICEMAP",
- &DeviceMapKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegCreateKey(DEVICEMAP) failed (Error %u)\n", (int)Error));
- return;
- }
-
- /* Create RESOURCEMAP key */
- Error = RegCreateKey(HardwareKey,
- "RESOURCEMAP",
- &ResourceMapKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegCreateKey(RESOURCEMAP) failed (Error %u)\n", (int)Error));
- return;
- }
-}
-
-static VOID
-FindPciBusses(PDETECTED_BUSSES DetectedBusses)
-{
- PDETECTED_BUS DetectedBus;
-
- PciBusConfigType = GetPciBusConfigType();
-
- if (PciBusConfigType == 0)
- {
- /* No PCI bus present */
- }
- else if (PciBusConfigType == 1)
- {
- /* 1 PCI bus present */
- DetectedBus = MmAllocateMemory(sizeof(DETECTED_BUS));
- if (DetectedBus == NULL)
- return;
-
- DetectedBus->BusType = PCIBus;
- DetectedBus->BusNumber = 0;
- strcpy(DetectedBus->Identifier, "PCI");
- InsertHeadList(&DetectedBusses->Busses, &DetectedBus->ListEntry);
- }
- else if (PciBusConfigType == 2)
- {
- /* PCI and AGP bus present */
- DetectedBus = MmAllocateMemory(sizeof(DETECTED_BUS));
- if (DetectedBus == NULL)
- return;
-
- DetectedBus->BusType = PCIBus;
- DetectedBus->BusNumber = 0;
- strcpy(DetectedBus->Identifier, "PCI");
- InsertHeadList(&DetectedBusses->Busses, &DetectedBus->ListEntry);
-
-
- DetectedBus = MmAllocateMemory(sizeof(DETECTED_BUS));
- if (DetectedBus == NULL)
- return;
-
- DetectedBus->BusType = PCIBus;
- DetectedBus->BusNumber = 1;
- strcpy(DetectedBus->Identifier, "PCI");
- InsertHeadList(&DetectedBusses->Busses, &DetectedBus->ListEntry);
- }
- else
- {
- /* Unknown PCI bus configuration */
- DbgPrint((DPRINT_WARNING, "Unknown PCI bus configuration %d\n", PciBusConfigType));
- }
-}
-
-static VOID
-FindIsaBus(PDETECTED_BUSSES DetectedBusses)
-{
- PDETECTED_BUS DetectedBus;
-
- /* Assume an ISA bus is present */
-
- DetectedBus = MmAllocateMemory(sizeof(DETECTED_BUS));
- if (DetectedBus == NULL)
- return;
-
- DetectedBus->BusType = Isa;
- DetectedBus->BusNumber = 0;
- strcpy(DetectedBus->Identifier, "ISA");
-
- InsertHeadList(&DetectedBusses->Busses, &DetectedBus->ListEntry);
-}
-
-#define APM_BUSKEY 0
-#define PNPBIOS_BUSKEY 1
-#define PCIBIOS_BUSKEY 2
-#define ACPIBIOS_BUSKEY 3
-#define ISA_BUSKEY 4
-#define FIRST_PCI_BUSKEY 5
-
-static int
-GetBusKeyName(INTERFACE_TYPE BusType, U32 BusNumber)
-{
- if (BusType == Isa)
- {
- return ISA_BUSKEY;
- }
- else if (BusType == PCIBus)
- {
- return FIRST_PCI_BUSKEY + BusNumber;
- }
- else
- {
- DbgPrint((DPRINT_WARNING, "GetBusKeyName(). Unknown BusType %u\n", (int)BusType));
- return -1;
- }
-}
-
-
-static VOID
-DetectBusses()
-{
- CHAR buf[200];
- DETECTED_BUSSES DetectedBusses;
- PDETECTED_BUS Bus;
- S32 Error;
- U32 BusNumber;
- PLIST_ENTRY ListEntry;
- HKEY SystemKey;
- HKEY MultifunctionAdapterKey;
- HKEY BusKey;
-
- InitializeListHead(&DetectedBusses.Busses);
- FindPciBusses(&DetectedBusses);
- FindIsaBus(&DetectedBusses);
-
- Error = RegOpenKey(NULL,
- "\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
- &SystemKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegOpenKey(System) failed (Error %u)\n", (int)Error));
- return;
- }
-
- /* Create DESCRIPTION/System/MultifunctionAdapter key */
- Error = RegCreateKey(SystemKey,
- "MultifunctionAdapter",
- &MultifunctionAdapterKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegCreateKey(MultifunctionAdapter) failed (Error %u)\n", (int)Error));
- return;
- }
-
- BusNumber = 0;
- ListEntry = DetectedBusses.Busses.Flink;
- while (ListEntry != &DetectedBusses.Busses)
- {
- Bus = CONTAINING_RECORD(ListEntry,
- DETECTED_BUS,
- ListEntry);
-
- /* Create DESCRIPTION/System/MultifunctionAdapter/X key */
- sprintf(buf, "%d", GetBusKeyName(Bus->BusType, Bus->BusNumber));
- Error = RegCreateKey(MultifunctionAdapterKey,
- buf,
- &BusKey);
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegCreateKey(X) failed (Error %u)\n", (int)Error));
- return;
- }
-
- RegisterBusKey(BusKey, Bus->BusType, Bus->BusNumber);
-
- Error = RegSetValue(BusKey,
- "Identifier",
- REG_SZ,
- (PU8) Bus->Identifier,
- strlen(Bus->Identifier));
- if (Error != ERROR_SUCCESS)
- {
- DbgPrint((DPRINT_HWDETECT, "RegSetValue(Identifier) failed (Error %u)\n", (int)Error));
- return;
- }
-
- BusNumber++;
- ListEntry = ListEntry->Flink;
- }
-
- DbgPrint((DPRINT_HWDETECT, "%d busses found\n", BusNumber));
-}
-
-VOID
-DetectHardware(VOID)
-{
- DbgPrint((DPRINT_HWDETECT, "DetectHardware()\n"));
-
- InitializeListHead(&BusKeyListHead);
-
- HalpCalibrateStallExecution();
-
- PrepareRegistry();
-
- DetectBusses();
-
- DetectStorage();
-
- DbgPrint((DPRINT_HWDETECT, "DetectHardware() Done\n"));
-}
+++ /dev/null
-/*
- * FreeLoader
- *
- * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
- * Copyright (C) 2003 Casper S. Hornstrup <chorns@users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __HWDETECT_H
-#define __HWDETECT_H
-
-typedef U64 PHYSICAL_ADDRESS;
-
-typedef enum _INTERFACE_TYPE
-{
- InterfaceTypeUndefined = -1,
- Internal,
- Isa,
- Eisa,
- MicroChannel,
- TurboChannel,
- PCIBus,
- VMEBus,
- NuBus,
- PCMCIABus,
- CBus,
- MPIBus,
- MPSABus,
- ProcessorInternal,
- InternalPowerBus,
- PNPISABus,
- MaximumInterfaceType
-} INTERFACE_TYPE, *PINTERFACE_TYPE;
-
-typedef enum _BUS_DATA_TYPE
-{
- ConfigurationSpaceUndefined = -1,
- Cmos,
- EisaConfiguration,
- Pos,
- CbusConfiguration,
- PCIConfiguration,
- VMEConfiguration,
- NuBusConfiguration,
- PCMCIAConfiguration,
- MPIConfiguration,
- MPSAConfiguration,
- PNPISAConfiguration,
- MaximumBusDataType,
-} BUS_DATA_TYPE, *PBUS_DATA_TYPE;
-
-typedef struct _CM_INT13_DRIVE_PARAMETER {
- U16 DriveSelect;
- U32 MaxCylinders;
- U16 SectorsPerTrack;
- U16 MaxHeads;
- U16 NumberDrives;
-} CM_INT13_DRIVE_PARAMETER, *PCM_INT13_DRIVE_PARAMETER;
-
-typedef struct _CM_DISK_GEOMETRY_DEVICE_DATA {
- U32 BytesPerSector;
- U32 NumberOfCylinders;
- U32 SectorsPerTrack;
- U32 NumberOfHeads;
-} CM_DISK_GEOMETRY_DEVICE_DATA, *PCM_DISK_GEOMETRY_DEVICE_DATA;
-
-typedef struct {
- U8 Type;
- U8 ShareDisposition;
- U16 Flags;
- union {
- struct {
- PHYSICAL_ADDRESS Start;
- U32 Length;
- } __attribute__((packed)) Port;
- struct {
- U32 Level;
- U32 Vector;
- U32 Affinity;
- } __attribute__((packed)) Interrupt;
- struct {
- PHYSICAL_ADDRESS Start;
- U32 Length;
- } __attribute__((packed)) Memory;
- struct {
- U32 Channel;
- U32 Port;
- U32 Reserved1;
- } __attribute__((packed)) Dma;
- struct {
- U32 DataSize;
- U32 Reserved1;
- U32 Reserved2;
- } __attribute__((packed)) DeviceSpecificData;
- } __attribute__((packed)) u;
-} __attribute__((packed)) CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
-
-typedef struct {
- U16 Version;
- U16 Revision;
- U32 Count;
- CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];
-} __attribute__((packed))CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
-
-typedef struct {
- INTERFACE_TYPE InterfaceType;
- U32 BusNumber;
- CM_PARTIAL_RESOURCE_LIST PartialResourceList;
-} __attribute__((packed)) CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;
-
-/* PCI bus definitions */
-
-#define PCI_TYPE0_ADDRESSES 6
-#define PCI_TYPE1_ADDRESSES 2
-#define PCI_TYPE2_ADDRESSES 5
-
-typedef struct _PCI_COMMON_CONFIG
-{
- U16 VendorID; /* read-only */
- U16 DeviceID; /* read-only */
- U16 Command;
- U16 Status;
- U8 RevisionID; /* read-only */
- U8 ProgIf; /* read-only */
- U8 SubClass; /* read-only */
- U8 BaseClass; /* read-only */
- U8 CacheLineSize; /* read-only */
- U8 LatencyTimer; /* read-only */
- U8 HeaderType; /* read-only */
- U8 BIST;
- union
- {
- struct _PCI_HEADER_TYPE_0
- {
- U32 BaseAddresses[PCI_TYPE0_ADDRESSES];
- U32 CIS;
- U16 SubVendorID;
- U16 SubSystemID;
- U32 ROMBaseAddress;
- U32 Reserved2[2];
-
- U8 InterruptLine;
- U8 InterruptPin; /* read-only */
- U8 MinimumGrant; /* read-only */
- U8 MaximumLatency; /* read-only */
- } type0;
-
- /* PCI to PCI Bridge */
- struct _PCI_HEADER_TYPE_1
- {
- U32 BaseAddresses[PCI_TYPE1_ADDRESSES];
- U8 PrimaryBus;
- U8 SecondaryBus;
- U8 SubordinateBus;
- U8 SecondaryLatency;
- U8 IOBase;
- U8 IOLimit;
- U16 SecondaryStatus;
- U16 MemoryBase;
- U16 MemoryLimit;
- U16 PrefetchBase;
- U16 PrefetchLimit;
- U32 PrefetchBaseUpper32;
- U32 PrefetchLimitUpper32;
- U16 IOBaseUpper16;
- U16 IOLimitUpper16;
- U8 CapabilitiesPtr;
- U8 Reserved1[3];
- U32 ROMBaseAddress;
- U8 InterruptLine;
- U8 InterruptPin;
- U16 BridgeControl;
- } type1;
-
- /* PCI to CARDBUS Bridge */
- struct _PCI_HEADER_TYPE_2
- {
- U32 SocketRegistersBaseAddress;
- U8 CapabilitiesPtr;
- U8 Reserved;
- U16 SecondaryStatus;
- U8 PrimaryBus;
- U8 SecondaryBus;
- U8 SubordinateBus;
- U8 SecondaryLatency;
- struct
- {
- U32 Base;
- U32 Limit;
- } Range[PCI_TYPE2_ADDRESSES-1];
- U8 InterruptLine;
- U8 InterruptPin;
- U16 BridgeControl;
- } type2;
- } u;
- U8 DeviceSpecific[192];
-} PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
-
-#define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET (PCI_COMMON_CONFIG, DeviceSpecific))
-
-#define PCI_MAX_DEVICES 32
-#define PCI_MAX_FUNCTION 8
-
-#define PCI_INVALID_VENDORID 0xFFFF
-
-/* Bit encodings for PCI_COMMON_CONFIG.HeaderType */
-
-#define PCI_MULTIFUNCTION 0x80
-#define PCI_DEVICE_TYPE 0x00
-#define PCI_BRIDGE_TYPE 0x01
-
-
-/* Bit encodings for PCI_COMMON_CONFIG.Command */
-
-#define PCI_ENABLE_IO_SPACE 0x0001
-#define PCI_ENABLE_MEMORY_SPACE 0x0002
-#define PCI_ENABLE_BUS_MASTER 0x0004
-#define PCI_ENABLE_SPECIAL_CYCLES 0x0008
-#define PCI_ENABLE_WRITE_AND_INVALIDATE 0x0010
-#define PCI_ENABLE_VGA_COMPATIBLE_PALETTE 0x0020
-#define PCI_ENABLE_PARITY 0x0040
-#define PCI_ENABLE_WAIT_CYCLE 0x0080
-#define PCI_ENABLE_SERR 0x0100
-#define PCI_ENABLE_FAST_BACK_TO_BACK 0x0200
-
-
-/* Bit encodings for PCI_COMMON_CONFIG.Status */
-
-#define PCI_STATUS_FAST_BACK_TO_BACK 0x0080
-#define PCI_STATUS_DATA_PARITY_DETECTED 0x0100
-#define PCI_STATUS_DEVSEL 0x0600 /* 2 bits wide */
-#define PCI_STATUS_SIGNALED_TARGET_ABORT 0x0800
-#define PCI_STATUS_RECEIVED_TARGET_ABORT 0x1000
-#define PCI_STATUS_RECEIVED_MASTER_ABORT 0x2000
-#define PCI_STATUS_SIGNALED_SYSTEM_ERROR 0x4000
-#define PCI_STATUS_DETECTED_PARITY_ERROR 0x8000
-
-
-/* PCI device classes */
-
-#define PCI_CLASS_PRE_20 0x00
-#define PCI_CLASS_MASS_STORAGE_CTLR 0x01
-#define PCI_CLASS_NETWORK_CTLR 0x02
-#define PCI_CLASS_DISPLAY_CTLR 0x03
-#define PCI_CLASS_MULTIMEDIA_DEV 0x04
-#define PCI_CLASS_MEMORY_CTLR 0x05
-#define PCI_CLASS_BRIDGE_DEV 0x06
-#define PCI_CLASS_SIMPLE_COMMS_CTLR 0x07
-#define PCI_CLASS_BASE_SYSTEM_DEV 0x08
-#define PCI_CLASS_INPUT_DEV 0x09
-#define PCI_CLASS_DOCKING_STATION 0x0a
-#define PCI_CLASS_PROCESSOR 0x0b
-#define PCI_CLASS_SERIAL_BUS_CTLR 0x0c
-
-
-/* PCI device subclasses for class 1 (mass storage controllers)*/
-
-#define PCI_SUBCLASS_MSC_SCSI_BUS_CTLR 0x00
-#define PCI_SUBCLASS_MSC_IDE_CTLR 0x01
-#define PCI_SUBCLASS_MSC_FLOPPY_CTLR 0x02
-#define PCI_SUBCLASS_MSC_IPI_CTLR 0x03
-#define PCI_SUBCLASS_MSC_RAID_CTLR 0x04
-#define PCI_SUBCLASS_MSC_OTHER 0x80
-
-
-/* Bit encodes for PCI_COMMON_CONFIG.u.type0.BaseAddresses */
-
-#define PCI_ADDRESS_IO_SPACE 0x00000001
-#define PCI_ADDRESS_MEMORY_TYPE_MASK 0x00000006
-#define PCI_ADDRESS_MEMORY_PREFETCHABLE 0x00000008
-
-#define PCI_ADDRESS_IO_ADDRESS_MASK 0xfffffffc
-#define PCI_ADDRESS_MEMORY_ADDRESS_MASK 0xfffffff0
-#define PCI_ADDRESS_ROM_ADDRESS_MASK 0xfffff800
-
-#define PCI_TYPE_32BIT 0
-#define PCI_TYPE_20BIT 2
-#define PCI_TYPE_64BIT 4
-
-
-/* Bit encodes for PCI_COMMON_CONFIG.u.type0.ROMBaseAddresses */
-
-#define PCI_ROMADDRESS_ENABLED 0x00000001
-
-typedef struct _PCI_SLOT_NUMBER
-{
- union
- {
- struct
- {
- U32 DeviceNumber:5;
- U32 FunctionNumber:3;
- U32 Reserved:24;
- } bits;
- U32 AsULONG;
- } u;
-} PCI_SLOT_NUMBER, *PPCI_SLOT_NUMBER;
-
-
-
-/* ***** BEGIN ATA ***** */
-
-#define IDE_SECTOR_BUF_SZ 512
-#define IDE_MAX_POLL_RETRIES 100000
-#define IDE_MAX_BUSY_RETRIES 50000
-
-// Control Block offsets and masks
-#define IDE_REG_DEV_CNTRL 0x0000 /* device control register */
-#define IDE_DC_nIEN 0x02 /* IRQ enable (active low) */
-
-// Command Block offsets and masks
-#define IDE_REG_DATA_PORT 0x0000
-#define IDE_REG_ERROR 0x0001 /* error register */
-#define IDE_ER_AMNF 0x01 /* address mark not found */
-#define IDE_ER_TK0NF 0x02 /* Track 0 not found */
-#define IDE_ER_ABRT 0x04 /* Command aborted */
-#define IDE_ER_MCR 0x08 /* Media change requested */
-#define IDE_ER_IDNF 0x10 /* ID not found */
-#define IDE_ER_MC 0x20 /* Media changed */
-#define IDE_ER_UNC 0x40 /* Uncorrectable data error */
-#define IDE_REG_PRECOMP 0x0001
-#define IDE_REG_SECTOR_CNT 0x0002
-#define IDE_REG_SECTOR_NUM 0x0003
-#define IDE_REG_CYL_LOW 0x0004
-#define IDE_REG_CYL_HIGH 0x0005
-#define IDE_REG_DRV_HEAD 0x0006
-#define IDE_DH_FIXED 0xA0
-#define IDE_DH_LBA 0x40
-#define IDE_DH_HDMASK 0x0F
-#define IDE_DH_DRV0 0x00
-#define IDE_DH_DRV1 0x10
-#define IDE_REG_STATUS 0x0007
-#define IDE_SR_BUSY 0x80
-#define IDE_SR_DRQ 0x08
-#define IDE_SR_ERR 0x01
-#define IDE_REG_COMMAND 0x0007
-
-/* IDE/ATA commands */
-#define IDE_CMD_RESET 0x08
-#define IDE_CMD_IDENT_ATA_DRV 0xEC
-#define IDE_CMD_IDENT_ATAPI_DRV 0xA1
-
-/* Access macros for command registers
- Each macro takes an address of the command port block, and data */
-#define IDEWritePrecomp(Address, Data) \
- (WRITE_PORT_UCHAR((PU8)((Address) + IDE_REG_PRECOMP), (Data)))
-#define IDEWriteSectorCount(Address, Data) \
- (WRITE_PORT_UCHAR((PU8)((Address) + IDE_REG_SECTOR_CNT), (Data)))
-#define IDEWriteSectorNum(Address, Data) \
- (WRITE_PORT_UCHAR((PU8)((Address) + IDE_REG_SECTOR_NUM), (Data)))
-#define IDEReadCylinderLow(Address) \
- (READ_PORT_UCHAR((PU8)((Address) + IDE_REG_CYL_LOW)))
-#define IDEWriteCylinderLow(Address, Data) \
- (WRITE_PORT_UCHAR((PU8)((Address) + IDE_REG_CYL_LOW), (Data)))
-#define IDEReadCylinderHigh(Address) \
- (READ_PORT_UCHAR((PU8)((Address) + IDE_REG_CYL_HIGH)))
-#define IDEWriteCylinderHigh(Address, Data) \
- (WRITE_PORT_UCHAR((PU8)((Address) + IDE_REG_CYL_HIGH), (Data)))
-#define IDEWriteDriveHead(Address, Data) \
- (WRITE_PORT_UCHAR((PU8)((Address) + IDE_REG_DRV_HEAD), (Data)))
-#define IDEWriteDriveControl(Address, Data) \
- (WRITE_PORT_UCHAR((PU8)((Address) + IDE_REG_DEV_CNTRL), (Data)))
-#define IDEReadStatus(Address) \
- (READ_PORT_UCHAR((PU8)((Address) + IDE_REG_STATUS)))
-#define IDEWriteCommand(Address, Data) \
- (WRITE_PORT_UCHAR((PU8)((Address) + IDE_REG_COMMAND), (Data)))
-
-/* Data block read and write commands */
-#define IDEReadBlock(Address, Buffer, Count) \
- (READ_PORT_BUFFER_USHORT((PU16)((Address) + IDE_REG_DATA_PORT), \
- (PU16)(Buffer), (Count) / 2))
-
-typedef struct _IDE_DRIVE_IDENTIFY
-{
- U16 ConfigBits; /*00*/
- U16 LogicalCyls; /*01*/
- U16 Reserved02; /*02*/
- U16 LogicalHeads; /*03*/
- U16 BytesPerTrack; /*04*/
- U16 BytesPerSector; /*05*/
- U16 SectorsPerTrack; /*06*/
- U8 InterSectorGap; /*07*/
- U8 InterSectorGapSize;
- U8 Reserved08H; /*08*/
- U8 BytesInPLO;
- U16 VendorUniqueCnt; /*09*/
- CHAR SerialNumber[20]; /*10*/
- U16 ControllerType; /*20*/
- U16 BufferSize; /*21*/
- U16 ECCByteCnt; /*22*/
- CHAR FirmwareRev[8]; /*23*/
- CHAR ModelNumber[40]; /*27*/
- U16 RWMultImplemented; /*47*/
- U16 DWordIo; /*48*/
- U16 Capabilities; /*49*/
-#define IDE_DRID_STBY_SUPPORTED 0x2000
-#define IDE_DRID_IORDY_SUPPORTED 0x0800
-#define IDE_DRID_IORDY_DISABLE 0x0400
-#define IDE_DRID_LBA_SUPPORTED 0x0200
-#define IDE_DRID_DMA_SUPPORTED 0x0100
- U16 Reserved50; /*50*/
- U16 MinPIOTransTime; /*51*/
- U16 MinDMATransTime; /*52*/
- U16 TMFieldsValid; /*53*/
- U16 TMCylinders; /*54*/
- U16 TMHeads; /*55*/
- U16 TMSectorsPerTrk; /*56*/
- U16 TMCapacityLo; /*57*/
- U16 TMCapacityHi; /*58*/
- U16 RWMultCurrent; /*59*/
- U16 TMSectorCountLo; /*60*/
- U16 TMSectorCountHi; /*61*/
- U16 Reserved62[193]; /*62*/
- U16 Checksum; /*255*/
-} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
-
-/* ***** END ATA ***** */
-
-typedef struct _DETECTED_BUS
-{
- LIST_ENTRY ListEntry;
- INTERFACE_TYPE BusType;
- U32 BusNumber;
- CHAR Identifier[20];
-} DETECTED_BUS, *PDETECTED_BUS;
-
-typedef struct _DETECTED_BUSSES
-{
- LIST_ENTRY Busses; /* DETECTED_BUS */
-} DETECTED_BUSSES, *PDETECTED_BUSSES;
-
-#if 0
-typedef struct _DETECTED_STORAGE_CONTROLLER
-{
- LIST_ENTRY ListEntry;
- INTERFACE_TYPE BusType;
- U32 BusNumber;
- U32 DriveCount;
- IDE_DRIVE_IDENTIFY IdeDriveIdentify[2];
-} DETECTED_STORAGE_CONTROLLER, *PDETECTED_STORAGE_CONTROLLER;
-#endif
-
-typedef struct _DETECTED_DISK
-{
- LIST_ENTRY ListEntry;
- INTERFACE_TYPE BusType;
- U32 BusNumber;
- CM_INT13_DRIVE_PARAMETER Int13DriveParameter;
- CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometryDeviceData;
-} DETECTED_DISK, *PDETECTED_DISK;
-
-typedef struct _DETECTED_STORAGE
-{
- LIST_ENTRY Disks; /* DETECTED_DISK */
-} DETECTED_STORAGE, *PDETECTED_STORAGE;
-
-
-typedef struct _REGISTRY_BUS_INFORMATION
-{
- LIST_ENTRY ListEntry;
- HKEY BusKey;
- INTERFACE_TYPE BusType;
- U32 BusNumber;
-} REGISTRY_BUS_INFORMATION, *PREGISTRY_BUS_INFORMATION;
-
-VOID DetectHardware(VOID);
-
-#endif /* __HWDETECT_H */