- Query BIOS for supported disk drives

svn path=/trunk/; revision=4604
This commit is contained in:
Casper Hornstrup 2003-04-27 18:18:51 +00:00
parent 3f270ca3d4
commit 371b0fd87e
4 changed files with 269 additions and 24 deletions

View file

@ -1,3 +1,7 @@
Changes in v1.8.10 (4/27/2003) (chorns)
- Query BIOS for supported disk drives
Changes in v1.8.9 (4/25/2003) (chorns)
- Detect PCI busses

View file

@ -22,7 +22,7 @@
/* just some stuff */
#define VERSION "FreeLoader v1.8.9"
#define VERSION "FreeLoader v1.8.10"
#define COPYRIGHT "Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>"
#define AUTHOR_EMAIL "<brianp@sginet.com>"
#define BY_AUTHOR "by Brian Palmer"
@ -36,7 +36,7 @@
//
#define FREELOADER_MAJOR_VERSION 1
#define FREELOADER_MINOR_VERSION 8
#define FREELOADER_PATCH_VERSION 9
#define FREELOADER_PATCH_VERSION 10
PUCHAR GetFreeLoaderVersionString(VOID);

View file

@ -2,6 +2,7 @@
* 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
@ -21,6 +22,7 @@
#include <freeldr.h>
#include <rtl.h>
#include <mm.h>
#include <arch.h>
#include <portio.h>
#include "registry.h"
#include "hwdetect.h"
@ -444,7 +446,7 @@ RegisterBusKey(HKEY Key, INTERFACE_TYPE BusType, U32 BusNumber)
InsertTailList(&BusKeyListHead, &BusKey->ListEntry);
}
#if 0
static HKEY
GetBusKey(INTERFACE_TYPE BusType, U32 BusNumber)
{
@ -470,7 +472,7 @@ GetBusKey(INTERFACE_TYPE BusType, U32 BusNumber)
BusType, BusNumber));
return NULL;
}
#endif
static HKEY
CreateOrOpenKey(HKEY RelativeKey, PCHAR KeyName)
@ -501,7 +503,7 @@ CreateOrOpenKey(HKEY RelativeKey, PCHAR KeyName)
/* ***** END Helper functions ***** */
#if 0
/* ***** BEGIN ATA ***** */
typedef struct _PCI_NATIVE_CONTROLLER
@ -1285,6 +1287,7 @@ AtapiFindIsaBusController(U32 SystemIoBusNumber,
return(FALSE);
}
#if 0
static VOID
FindIDEControllers(PDETECTED_STORAGE DetectedStorage)
{
@ -1442,31 +1445,178 @@ FindIDEControllers(PDETECTED_STORAGE DetectedStorage)
}
}
}
#endif
/* ***** END ATA ***** */
#endif
VOID
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_STORAGE_CONTROLLER Controller;
PDETECTED_DISK DetectedDisk;
PLIST_ENTRY ListEntry;
CHAR buf[200];
// CHAR buf[200];
S32 Error;
U32 ScsiPortNumber;
HKEY ScsiPortKey;
HKEY SystemKey;
U32 i;
/* U32 i;
HKEY BusKey;
HKEY DiskControllerKey;
HKEY DiskPeripheralKey;
HKEY DriveKey;
CM_INT13_DRIVE_PARAMETER Int13;
HKEY DriveKey;*/
U32 Size;
U32 Count;
U32 DriveCount;
PCM_INT13_DRIVE_PARAMETER Int13Array;
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
InitializeListHead(&DetectedStorage.StorageControllers);
InitializeListHead(&DetectedStorage.Disks);
FindIDEControllers(&DetectedStorage);
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)
@ -1549,9 +1699,10 @@ DetectStorage(VOID)
}
DbgPrint((DPRINT_HWDETECT, "%d controllers found\n", ScsiPortNumber));
#endif
}
VOID
static VOID
PrepareRegistry()
{
HKEY HardwareKey;
@ -1611,7 +1762,7 @@ PrepareRegistry()
}
}
VOID
static VOID
FindPciBusses(PDETECTED_BUSSES DetectedBusses)
{
PDETECTED_BUS DetectedBus;
@ -1663,7 +1814,7 @@ FindPciBusses(PDETECTED_BUSSES DetectedBusses)
}
}
VOID
static VOID
FindIsaBus(PDETECTED_BUSSES DetectedBusses)
{
PDETECTED_BUS DetectedBus;
@ -1681,7 +1832,33 @@ FindIsaBus(PDETECTED_BUSSES DetectedBusses)
InsertHeadList(&DetectedBusses->Busses, &DetectedBus->ListEntry);
}
VOID
#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];
@ -1726,7 +1903,7 @@ DetectBusses()
ListEntry);
/* Create DESCRIPTION/System/MultifunctionAdapter/X key */
sprintf(buf, "%d", (int) BusNumber);
sprintf(buf, "%d", GetBusKeyName(Bus->BusType, Bus->BusNumber));
Error = RegCreateKey(MultifunctionAdapterKey,
buf,
&BusKey);
@ -1759,7 +1936,7 @@ DetectBusses()
VOID
DetectHardware(VOID)
{
DbgPrint((DPRINT_REACTOS, "DetectHardware()\n"));
DbgPrint((DPRINT_HWDETECT, "DetectHardware()\n"));
InitializeListHead(&BusKeyListHead);

View file

@ -2,6 +2,7 @@
* 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
@ -21,6 +22,8 @@
#ifndef __HWDETECT_H
#define __HWDETECT_H
typedef U64 PHYSICAL_ADDRESS;
typedef enum _INTERFACE_TYPE
{
InterfaceTypeUndefined = -1,
@ -67,6 +70,57 @@ typedef struct _CM_INT13_DRIVE_PARAMETER {
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
@ -388,7 +442,7 @@ typedef struct _DETECTED_BUSSES
LIST_ENTRY Busses; /* DETECTED_BUS */
} DETECTED_BUSSES, *PDETECTED_BUSSES;
#if 0
typedef struct _DETECTED_STORAGE_CONTROLLER
{
LIST_ENTRY ListEntry;
@ -397,10 +451,20 @@ typedef struct _DETECTED_STORAGE_CONTROLLER
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 StorageControllers; /* DETECTED_STORAGE_CONTROLLER */
LIST_ENTRY Disks; /* DETECTED_DISK */
} DETECTED_STORAGE, *PDETECTED_STORAGE;