diff --git a/freeldr/freeldr/CHANGELOG b/freeldr/freeldr/CHANGELOG index 91ae4387ef5..b1ec4b223a2 100644 --- a/freeldr/freeldr/CHANGELOG +++ b/freeldr/freeldr/CHANGELOG @@ -1,3 +1,11 @@ +Changes in v1.8.11 (4/30/2003) (ekohl) + +- Added DiskGetExtendedDriveParameters() +- Moved hardware detection into the arch directory +- Rewrote/completed harddisk detection +- Removed PCI and IDE detection +- Added basic CPU detection + Changes in v1.8.10 (4/27/2003) (chorns) - Query BIOS for supported disk drives diff --git a/freeldr/freeldr/Makefile b/freeldr/freeldr/Makefile index 18890ca370b..54372157f63 100644 --- a/freeldr/freeldr/Makefile +++ b/freeldr/freeldr/Makefile @@ -206,6 +206,8 @@ ARCH_OBJS = fathelp.o \ int386.o \ i386disk.o \ portio.o \ + hardware.o \ + i386cpu.o \ _alloca.o # For Mingw32 builds RTL_OBJS = print.o \ @@ -230,7 +232,6 @@ UI_OBJS = tui.o \ REACTOS_OBJS= reactos.o \ arcname.o \ - hwdetect.o \ reghive.o \ binhive.o \ registry.o diff --git a/freeldr/freeldr/arch/i386/hardware.c b/freeldr/freeldr/arch/i386/hardware.c new file mode 100644 index 00000000000..5c17baca5d5 --- /dev/null +++ b/freeldr/freeldr/arch/i386/hardware.c @@ -0,0 +1,799 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#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>= 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 */ diff --git a/freeldr/freeldr/arch/i386/i386cpu.S b/freeldr/freeldr/arch/i386/i386cpu.S new file mode 100644 index 00000000000..77a3ada9661 --- /dev/null +++ b/freeldr/freeldr/arch/i386/i386cpu.S @@ -0,0 +1,337 @@ +/* + * 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. + */ + + .text + .code16 + +#define ASM + +#include + +/* + * U32 CpuidSupported(VOID); + * + * RETURNS: + * 0x00000001: CPU supports the CPUID instruction + * 0x00000300: Found 80386 CPU + * 0x00000400: Found 80486 CPU without CPUID support + */ + +EXTERN(_CpuidSupported) + .code32 + + pushl %ecx /* save ECX */ + + pushfl /* push original EFLAGS */ + popl %eax /* get original EFLAGS */ + movl %eax,%ecx /* save original EFLAGS */ + xorl $0x40000,%eax /* flip AC bit in EFLAGS */ + pushl %eax /* save new EFLAGS value on stack */ + popfl /* replace current EFLAGS value */ + + pushfl /* get new EFLAGS */ + popl %eax /* store new EFLAGS in EAX */ + xorl %ecx, %eax /* can't toggle AC bit, processor=80386 */ + + movl $0x300,%eax /* return processor id */ + jz NoCpuid /* jump if 80386 processor */ + + pushl %ecx + popfl /* restore AC bit in EFLAGS first */ + + movl %ecx,%eax /* get original EFLAGS */ + xorl $0x200000,%eax /* flip ID bit in EFLAGS */ + pushl %eax /* save new EFLAGS value on stack */ + popfl /* replace current EFLAGS value */ + pushfl /* get new EFLAGS */ + popl %eax /* store new EFLAGS in EAX */ + xorl %ecx,%eax /* can't toggle ID bit, */ + + movl $0x400,%eax /* return processor id */ + je NoCpuid /* processor=80486 */ + + movl $1,%eax /* CPUID supported */ + +NoCpuid: + pushl %ecx + popfl /* restore EFLAGS */ + popl %ecx /* retore ECX */ + + ret + + +/* + * VOID GetCpuid(U32 Level, U32 *eax, U32 *ebx, U32 *ecx, U32 *edx); + */ + +EXTERN(_GetCpuid) + .code32 + + pushl %ebp + movl %esp,%ebp + + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + pushl %esi + + movl 0x08(%ebp),%eax + cpuid + + movl 0x0C(%ebp),%esi + movl %eax, (%esi) + + movl 0x10(%ebp),%esi + movl %ebx, (%esi) + + movl 0x14(%ebp),%esi + movl %ecx, (%esi) + + movl 0x18(%ebp),%esi + movl %edx, (%esi) + + popl %esi + popl %edx + popl %ecx + popl %ebx + popl %eax + + movl %ebp,%esp + popl %ebp + ret + +/* + * U32 MpsSupported(VOID); + * + * RETURNS: + */ +_mps_supported: + .long 0 +_mps_fp_table_offset: + .word 0 + +EXTERN(_MpsSupported) + .code32 + + pushl %ebp + movl %esp,%ebp + pushal + push %es + + call switch_to_real + + .code16 + + /* init ES */ + pushw $0xF000 + popw %es + + /* init SI */ + movw $0xFFF0,%si + +mps_again: + movw %es:(%si),%ax + cmp $0x4D5F,%ax /* "_M" */ + jne mps_next + + push %si + add $2,%si + movw %es:(%si),%ax + cmp $0x5F50,%ax /* "P_" */ + pop %si + je mps_found + +mps_next: + cmp $0,%si + je mps_not_found + + sub $0x10,%si + jmp mps_again + +mps_found: + movw %si,_mps_fp_table_offset + movzwl %si,%eax + movl %eax,_mps_supported + +mps_not_found: + call switch_to_prot + + .code32 + + pop %es + popal + movl %ebp,%esp + popl %ebp + + movl _mps_supported,%eax + + ret + + +/* + * U32 MpsGetDefaultConfiguration(VOID); + * + * RETURNS: + */ +_mps_default_configuration: + .long 0 + +EXTERN(_MpsGetDefaultConfiguration) + .code32 + + pushl %ebp + movl %esp,%ebp + pushal + push %es + + call switch_to_real + + .code16 + + /* init ES */ + pushw $0xF000 + popw %es + + /* init SI */ + movw _mps_fp_table_offset,%si + + /* read default configuration (feature byte 1) */ + addw $0x0B,%si + movb %es:(%si),%al + + /* save configuration */ + movzbl %al,%ecx + movl %ecx,_mps_default_configuration + + call switch_to_prot + + .code32 + + pop %es + popal + movl %ebp,%esp + popl %ebp + + movl _mps_default_configuration,%eax + + ret + + +/* + * U32 MpsGetConfigurationTable(PVOID ConfigTable); + * + * RETURNS: + */ +_mps_buffer_segment: + .word 0 +_mps_buffer_offset: + .word 0 + +_mps_config_segment: + .word 0 +_mps_config_offset: + .word 0 +_mps_config_length: + .word 0 + +EXTERN(_MpsGetConfigurationTable) + .code32 + + pushl %ebp + movl %esp,%ebp + pushal + push %es + + /* convert pointer to node buffer to segment/offset */ + movl 0x08(%ebp),%eax + shrl $4,%eax + andl $0xf000,%eax + movw %ax,_mps_buffer_segment + movl 0x08(%ebp),%eax + andl $0xffff,%eax + movw %ax,_mps_buffer_offset + + call switch_to_real + + .code16 + + /* init ES */ + pushw $0xF000 + popw %es + + /* init SI */ + movw _mps_fp_table_offset,%si + + /* read pointer to configuration table */ + addw $0x04,%si + movl %es:(%si),%eax + + /* save table offset */ + movw %ax,_mps_config_offset + + /* save table segment */ + shrl $0x4,%eax + andw $0xf000,%ax + movw %ax,_mps_config_segment + + /* init ES */ + pushw _mps_config_segment + popw %es + + /* init CX (read table lenght) */ + movw _mps_config_offset,%si + addw $0x04,%si + movw %es:(%si),%cx + + /* init ES */ + pushw _mps_buffer_segment + popw %es + + /* init DI */ + movw _mps_buffer_offset,%di + + /* init SI */ + movw _mps_config_offset,%si + + /* init DS */ + movw _mps_config_segment,%ax + pushw %ds + pushw %ax + popw %ds + + /* copy table */ +// cld + rep movsb + + /* restore DS */ + pop %ds + + call switch_to_prot + + .code32 + + pop %es + popal + movl %ebp,%esp + popl %ebp + + ret + +/* EOF */ diff --git a/freeldr/freeldr/arch/i386/i386disk.c b/freeldr/freeldr/arch/i386/i386disk.c index 3408082194e..b2a819ce1f2 100644 --- a/freeldr/freeldr/arch/i386/i386disk.c +++ b/freeldr/freeldr/arch/i386/i386disk.c @@ -420,6 +420,47 @@ BOOL DiskGetDriveParameters(U32 DriveNumber, PGEOMETRY Geometry) return TRUE; } +BOOL DiskGetExtendedDriveParameters(U32 DriveNumber, PVOID Buffer, U16 BufferSize) +{ + REGS RegsIn; + REGS RegsOut; + PU16 Ptr = (PU16)(BIOSCALLBUFFER); + + DbgPrint((DPRINT_DISK, "DiskGetExtendedDriveParameters()\n")); + + // Initialize transfer buffer + *Ptr = BufferSize; + + // BIOS Int 13h, function 48h - Get drive parameters + // AH = 48h + // DL = drive (bit 7 set for hard disk) + // DS:SI = result buffer + // Return: + // CF set on error + // AH = status (07h) + // CF clear if successful + // AH = 00h + // DS:SI -> result buffer + RegsIn.b.ah = 0x48; + RegsIn.b.dl = DriveNumber; + RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> result buffer + RegsIn.w.si = BIOSCALLBUFOFFSET; + + // Get drive parameters + Int386(0x13, &RegsIn, &RegsOut); + + if (!INT386_SUCCESS(RegsOut)) + { + return FALSE; + } + + memcpy(Buffer, Ptr, BufferSize); + + return TRUE; +} + + + U32 DiskGetCacheableBlockCount(U32 DriveNumber) { GEOMETRY Geometry; diff --git a/freeldr/freeldr/fs/fs.c b/freeldr/freeldr/fs/fs.c index 6e44cb7c094..544189eaff8 100644 --- a/freeldr/freeldr/fs/fs.c +++ b/freeldr/freeldr/fs/fs.c @@ -122,8 +122,8 @@ BOOL FsOpenVolume(U32 DriveNumber, U32 PartitionNumber) // Try to recognize the file system if (!FsRecognizeVolume(DriveNumber, PartitionTableEntry.SectorCountBeforePartition, &VolumeType)) { - sprintf(ErrorText, "Unrecognized file system. Type: 0x%x", PartitionTableEntry.SystemIndicator); - FileSystemError(ErrorText); + FileSystemError("Unrecognized file system."); + return FALSE; } //switch (PartitionTableEntry.SystemIndicator) @@ -142,7 +142,7 @@ BOOL FsOpenVolume(U32 DriveNumber, U32 PartitionNumber) return Ext2OpenVolume(DriveNumber, PartitionTableEntry.SectorCountBeforePartition); default: FileSystemType = 0; - sprintf(ErrorText, "Unsupported file system. Type: 0x%x", PartitionTableEntry.SystemIndicator); + sprintf(ErrorText, "Unsupported file system. Type: 0x%x", VolumeType); FileSystemError(ErrorText); return FALSE; } diff --git a/freeldr/freeldr/include/arch.h b/freeldr/freeldr/include/arch.h index b316af73abf..20d3557f8bf 100644 --- a/freeldr/freeldr/include/arch.h +++ b/freeldr/freeldr/include/arch.h @@ -163,6 +163,8 @@ void EnableA20(void); VOID ChainLoadBiosBootSectorCode(VOID); // Implemented in boot.S VOID SoftReboot(VOID); // Implemented in boot.S +VOID DetectHardware(VOID); // Implemented in hardware.c + #endif /* ! ASM */ diff --git a/freeldr/freeldr/include/disk.h b/freeldr/freeldr/include/disk.h index 7f104f50a69..e29172fe204 100644 --- a/freeldr/freeldr/include/disk.h +++ b/freeldr/freeldr/include/disk.h @@ -30,6 +30,21 @@ typedef struct _GEOMETRY } GEOMETRY, *PGEOMETRY; +// +// Extended disk geometry (Int13 / ah=48h) +// +typedef struct _EXTENDED_GEOMETRY +{ + U16 Size; + U16 Flags; + U32 Cylinders; + U32 Heads; + U32 SectorsPerTrack; + U64 Sectors; + U16 BytesPerSector; + U32 PDPTE; +} __attribute__((packed)) EXTENDED_GEOMETRY, *PEXTENDED_GEOMETRY; + // // Define the structure of a partition table entry // @@ -53,9 +68,11 @@ typedef struct _PARTITION_TABLE_ENTRY // typedef struct _MASTER_BOOT_RECORD { - U8 MasterBootRecordCodeAndData[0x1be]; - PARTITION_TABLE_ENTRY PartitionTable[4]; - U16 MasterBootRecordMagic; + U8 MasterBootRecordCodeAndData[0x1b8]; /* 0x000 */ + U32 Signature; /* 0x1B8 */ + U16 Reserved; /* 0x1BC */ + PARTITION_TABLE_ENTRY PartitionTable[4]; /* 0x1BE */ + U16 MasterBootRecordMagic; /* 0x1FE */ } PACKED MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD; @@ -95,6 +112,8 @@ BOOL DiskResetController(U32 DriveNumber); BOOL DiskInt13ExtensionsSupported(U32 DriveNumber); //VOID DiskStopFloppyMotor(VOID); BOOL DiskGetDriveParameters(U32 DriveNumber, PGEOMETRY Geometry); +BOOL DiskGetExtendedDriveParameters(U32 DriveNumber, PVOID Buffer, U16 BufferSize); + //U32 DiskGetCacheableBlockCount(U32 DriveNumber); #endif // defined __i386__ diff --git a/freeldr/freeldr/include/version.h b/freeldr/freeldr/include/version.h index 7740d7f07fd..0b942e9a08b 100644 --- a/freeldr/freeldr/include/version.h +++ b/freeldr/freeldr/include/version.h @@ -22,7 +22,7 @@ /* just some stuff */ -#define VERSION "FreeLoader v1.8.10" +#define VERSION "FreeLoader v1.8.11" #define COPYRIGHT "Copyright (C) 1998-2003 Brian Palmer " #define AUTHOR_EMAIL "" #define BY_AUTHOR "by Brian Palmer" @@ -36,7 +36,7 @@ // #define FREELOADER_MAJOR_VERSION 1 #define FREELOADER_MINOR_VERSION 8 -#define FREELOADER_PATCH_VERSION 10 +#define FREELOADER_PATCH_VERSION 11 PUCHAR GetFreeLoaderVersionString(VOID); diff --git a/freeldr/freeldr/reactos/hwdetect.c b/freeldr/freeldr/reactos/hwdetect.c deleted file mode 100644 index b8841fe28dd..00000000000 --- a/freeldr/freeldr/reactos/hwdetect.c +++ /dev/null @@ -1,1952 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include "registry.h" -#include "hwdetect.h" -#include - -/* ***** 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>= 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")); -} diff --git a/freeldr/freeldr/reactos/hwdetect.h b/freeldr/freeldr/reactos/hwdetect.h deleted file mode 100644 index 39498d814ea..00000000000 --- a/freeldr/freeldr/reactos/hwdetect.h +++ /dev/null @@ -1,481 +0,0 @@ -/* - * FreeLoader - * - * Copyright (C) 1998-2003 Brian Palmer - * 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. - */ - -#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 */ diff --git a/freeldr/freeldr/reactos/reactos.c b/freeldr/freeldr/reactos/reactos.c index 310ef385743..90696a5a369 100644 --- a/freeldr/freeldr/reactos/reactos.c +++ b/freeldr/freeldr/reactos/reactos.c @@ -31,7 +31,6 @@ #include #include "registry.h" -#include "hwdetect.h" #define NDEBUG diff --git a/freeldr/freeldr/reactos/setupldr.c b/freeldr/freeldr/reactos/setupldr.c index 0fe380f7c56..44ebf82f1ef 100644 --- a/freeldr/freeldr/reactos/setupldr.c +++ b/freeldr/freeldr/reactos/setupldr.c @@ -29,7 +29,6 @@ #include #include "registry.h" -#include "hwdetect.h" static BOOL @@ -151,7 +150,8 @@ VOID RunLoader(VOID) /* Copy ARC path into kernel command line */ sprintf(multiboot_kernel_cmdline, - "multi(0)disk(0)cdrom(%u)\\reactos /DEBUGPORT=COM1", +// "multi(0)disk(0)cdrom(%u)\\reactos /DEBUGPORT=COM1", + "multi(0)disk(0)cdrom(%u)\\reactos /DEBUGPORT=SCREEN", (unsigned int)BootDrive); /* Open boot drive */