[FREELDR]: More local changes merging, part 2/x:

- Move the HW detection code specific to the PC architecture from hardware.c to machpc.c, keeping in hardware.c the code that is shared between PC and XBOX.
- Move what remained of i386disk.c into pcdisk.c (specific to PC architecture) + code formatting.
- Move what remained of xboxhw.c into machxbox.c (specific to XBOX architecture); we discover that some code related to disk management is actually shared with PC architecture (in hwdisk.c): hwdisk.c therefore contains disk-management routines common to both PC & XBOX.
- xboxdisk.c: Code formatting only.
- Cleanup in disk.c/disk.h

svn path=/trunk/; revision=73616
This commit is contained in:
Hermès Bélusca-Maïto 2017-01-28 23:47:35 +00:00
parent 8c8c4f495c
commit dde1f97a02
12 changed files with 2628 additions and 2771 deletions

View file

@ -123,7 +123,6 @@ if(ARCH STREQUAL "i386")
arch/i386/hwdisk.c
arch/i386/hwpci.c
arch/i386/i386bug.c
arch/i386/i386disk.c
arch/i386/i386idt.c
arch/i386/i386rtl.c
arch/i386/i386vid.c
@ -137,7 +136,6 @@ if(ARCH STREQUAL "i386")
arch/i386/xboxcons.c
arch/i386/xboxdisk.c
arch/i386/xboxfont.c
arch/i386/xboxhw.c
arch/i386/xboxi2c.c
arch/i386/xboxmem.c
arch/i386/xboxrtc.c
@ -170,7 +168,6 @@ elseif(ARCH STREQUAL "amd64")
arch/i386/hwpci.c
arch/i386/i386bug.c
arch/i386/i386rtl.c
arch/i386/i386disk.c
arch/i386/i386vid.c
arch/i386/machpc.c
arch/i386/pccons.c

File diff suppressed because it is too large Load diff

View file

@ -39,13 +39,19 @@ extern ULONG reactos_disk_count;
extern ARC_DISK_SIGNATURE_EX reactos_arc_disk_info[];
static CHAR Hex[] = "0123456789abcdef";
UCHAR PcBiosDiskCount = 0;
CHAR PcDiskIdentifier[32][20];
static CHAR PcDiskIdentifier[32][20];
PVOID DiskReadBuffer;
SIZE_T DiskReadBufferSize;
static ARC_STATUS DiskClose(ULONG FileId)
/* FUNCTIONS *****************************************************************/
// static
ARC_STATUS
DiskClose(ULONG FileId)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
@ -53,7 +59,9 @@ static ARC_STATUS DiskClose(ULONG FileId)
return ESUCCESS;
}
static ARC_STATUS DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
// static
ARC_STATUS
DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
@ -64,7 +72,8 @@ static ARC_STATUS DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Informat
return ESUCCESS;
}
static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
static ARC_STATUS
DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
{
DISKCONTEXT* Context;
UCHAR DriveNumber;
@ -84,9 +93,12 @@ static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
}
else
{
/* This is either a floppy disk device (DrivePartition == 0) or
* a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but
* it doesn't matter which one because they both have 512 bytes per sector */
/*
* This is either a floppy disk device (DrivePartition == 0) or
* a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF)
* but it doesn't matter which one because they both have 512 bytes
* per sector.
*/
SectorSize = 512;
}
@ -94,13 +106,21 @@ static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
{
if (!DiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
return EINVAL;
SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
SectorCount = PartitionTableEntry.PartitionSectorCount;
}
#if 0 // FIXME: Investigate
else
{
SectorCount = 0; /* FIXME */
}
#endif
Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
if (!Context)
return ENOMEM;
Context->DriveNumber = DriveNumber;
Context->SectorSize = SectorSize;
Context->SectorOffset = SectorOffset;
@ -111,7 +131,9 @@ static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
return ESUCCESS;
}
static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
// static
ARC_STATUS
DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
UCHAR* Ptr = (UCHAR*)Buffer;
@ -123,7 +145,7 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
MaxSectors = DiskReadBufferSize / Context->SectorSize;
SectorOffset = Context->SectorNumber + Context->SectorOffset;
ret = 1;
ret = TRUE;
while (TotalSectors)
{
@ -131,8 +153,7 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
if (ReadSectors > MaxSectors)
ReadSectors = MaxSectors;
ret = MachDiskReadLogicalSectors(
Context->DriveNumber,
ret = MachDiskReadLogicalSectors(Context->DriveNumber,
SectorOffset,
ReadSectors,
DiskReadBuffer);
@ -156,7 +177,9 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
return (!ret) ? EIO : ESUCCESS;
}
static ARC_STATUS DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
// static
ARC_STATUS
DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
@ -169,7 +192,8 @@ static ARC_STATUS DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekM
return ESUCCESS;
}
static const DEVVTBL DiskVtbl = {
static const DEVVTBL DiskVtbl =
{
DiskClose,
DiskGetFileInformation,
DiskOpen,
@ -177,6 +201,7 @@ static const DEVVTBL DiskVtbl = {
DiskSeek,
};
PCHAR
GetHarddiskIdentifier(
UCHAR DriveNumber)
@ -264,14 +289,13 @@ GetHarddiskInformation(
Identifier[15] = Hex[(Signature >> 4) & 0x0F];
Identifier[16] = Hex[Signature & 0x0F];
Identifier[17] = '-';
Identifier[18] = 'A';
Identifier[18] = 'A'; // FIXME: Not always 'A' ...
Identifier[19] = 0;
TRACE("Identifier: %s\n", Identifier);
}
BOOLEAN
HwInitializeBiosDisks(VOID)
PcInitializeBootDevices(VOID)
{
UCHAR DiskCount, DriveNumber;
ULONG i;
@ -314,9 +338,11 @@ HwInitializeBiosDisks(VOID)
DiskCount++;
DriveNumber++;
memset(DiskReadBuffer, 0xcd, 512);
memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
}
DiskReportError(TRUE);
TRACE("BIOS reports %d harddisk%s\n",
(int)DiskCount, (DiskCount == 1) ? "" : "s");
/* Get the drive we're booting from */
MachDiskGetBootPath(BootPath, sizeof(BootPath));
@ -366,5 +392,5 @@ HwInitializeBiosDisks(VOID)
TRACE("BIOS reports %d harddisk%s\n",
(int)DiskCount, (DiskCount == 1) ? "": "s");
return DiskCount != 0;
return (DiskCount != 0);
}

View file

@ -1,220 +0,0 @@
/*
* FreeLoader
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <freeldr.h>
#define NDEBUG
#include <debug.h>
DBG_DEFAULT_CHANNEL(DISK);
/////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////////////
BOOLEAN DiskResetController(UCHAR DriveNumber)
{
REGS RegsIn;
REGS RegsOut;
WARN("DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
// BIOS Int 13h, function 0 - Reset disk system
// AH = 00h
// DL = drive (if bit 7 is set both hard disks and floppy disks reset)
// Return:
// AH = status
// CF clear if successful
// CF set on error
RegsIn.b.ah = 0x00;
RegsIn.b.dl = DriveNumber;
// Reset the disk controller
Int386(0x13, &RegsIn, &RegsOut);
return INT386_SUCCESS(RegsOut);
}
BOOLEAN DiskInt13ExtensionsSupported(UCHAR DriveNumber)
{
static UCHAR LastDriveNumber = 0xff;
static BOOLEAN LastSupported;
REGS RegsIn;
REGS RegsOut;
TRACE("PcDiskInt13ExtensionsSupported()\n");
if (DriveNumber == LastDriveNumber)
{
TRACE("Using cached value %s for drive 0x%x\n", LastSupported ? "TRUE" : "FALSE", DriveNumber);
return LastSupported;
}
// Some BIOSes report that extended disk access functions are not supported
// when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping
// with Intel Macs). Therefore we just return TRUE if we're booting from a CD -
// we can assume that all El Torito capable BIOSes support INT 13 extensions.
// We simply detect whether we're booting from CD by checking whether the drive
// number is >= 0x8A. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes.
if (DriveNumber >= 0x8A)
{
LastSupported = TRUE;
return TRUE;
}
LastDriveNumber = DriveNumber;
// IBM/MS INT 13 Extensions - INSTALLATION CHECK
// AH = 41h
// BX = 55AAh
// DL = drive (80h-FFh)
// Return:
// CF set on error (extensions not supported)
// AH = 01h (invalid function)
// CF clear if successful
// BX = AA55h if installed
// AH = major version of extensions
// 01h = 1.x
// 20h = 2.0 / EDD-1.0
// 21h = 2.1 / EDD-1.1
// 30h = EDD-3.0
// AL = internal use
// CX = API subset support bitmap
// DH = extension version (v2.0+ ??? -- not present in 1.x)
//
// Bitfields for IBM/MS INT 13 Extensions API support bitmap
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
// Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
// Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
// extended drive parameter table is valid
// Bits 3-15 reserved
RegsIn.b.ah = 0x41;
RegsIn.w.bx = 0x55AA;
RegsIn.b.dl = DriveNumber;
// Reset the disk controller
Int386(0x13, &RegsIn, &RegsOut);
if (!INT386_SUCCESS(RegsOut))
{
// CF set on error (extensions not supported)
LastSupported = FALSE;
return FALSE;
}
if (RegsOut.w.bx != 0xAA55)
{
// BX = AA55h if installed
LastSupported = FALSE;
return FALSE;
}
if (!(RegsOut.w.cx & 0x0001))
{
// CX = API subset support bitmap
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
DbgPrint("Suspicious API subset support bitmap 0x%x on device 0x%lx\n", RegsOut.w.cx, DriveNumber);
LastSupported = FALSE;
return FALSE;
}
LastSupported = TRUE;
return TRUE;
}
VOID DiskStopFloppyMotor(VOID)
{
WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0);
}
BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize)
{
REGS RegsIn;
REGS RegsOut;
PUSHORT Ptr = (PUSHORT)(BIOSCALLBUFFER);
TRACE("DiskGetExtendedDriveParameters()\n");
if (!DiskInt13ExtensionsSupported(DriveNumber))
return FALSE;
// 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);
#if DBG
TRACE("size of buffer: %x\n", Ptr[0]);
TRACE("information flags: %x\n", Ptr[1]);
TRACE("number of physical cylinders on drive: %u\n", *(PULONG)&Ptr[2]);
TRACE("number of physical heads on drive: %u\n", *(PULONG)&Ptr[4]);
TRACE("number of physical sectors per track: %u\n", *(PULONG)&Ptr[6]);
TRACE("total number of sectors on drive: %I64u\n", *(unsigned long long*)&Ptr[8]);
TRACE("bytes per sector: %u\n", Ptr[12]);
if (Ptr[0] >= 0x1e)
{
TRACE("EED configuration parameters: %x:%x\n", Ptr[13], Ptr[14]);
if (Ptr[13] != 0xffff && Ptr[14] != 0xffff)
{
PUCHAR SpecPtr = (PUCHAR)(ULONG_PTR)((Ptr[13] << 4) + Ptr[14]);
TRACE("SpecPtr: %x\n", SpecPtr);
TRACE("physical I/O port base address: %x\n", *(PUSHORT)&SpecPtr[0]);
TRACE("disk-drive control port address: %x\n", *(PUSHORT)&SpecPtr[2]);
TRACE("drive flags: %x\n", SpecPtr[4]);
TRACE("proprietary information: %x\n", SpecPtr[5]);
TRACE("IRQ for drive: %u\n", SpecPtr[6]);
TRACE("sector count for multi-sector transfers: %u\n", SpecPtr[7]);
TRACE("DMA control: %x\n", SpecPtr[8]);
TRACE("programmed I/O control: %x\n", SpecPtr[9]);
TRACE("drive options: %x\n", *(PUSHORT)&SpecPtr[10]);
}
}
if (Ptr[0] >= 0x42)
{
TRACE("signature: %x\n", Ptr[15]);
}
#endif
return TRUE;
}
/* EOF */

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,466 @@
#include <freeldr.h>
#define NDEBUG
#include <debug.h>
DBG_DEFAULT_CHANNEL(HWDETECT);
static CHAR Hex[] = "0123456789ABCDEF";
extern ULONG reactos_disk_count;
extern ARC_DISK_SIGNATURE_EX reactos_arc_disk_info[];
typedef struct tagDISKCONTEXT
{
UCHAR DriveNumber;
ULONG SectorSize;
ULONGLONG SectorOffset;
ULONGLONG SectorCount;
ULONGLONG SectorNumber;
} DISKCONTEXT;
// NOTE: Similar to hardware.c!PcGetHarddiskConfigurationData(),
// but without extended geometry support.
static
PCM_PARTIAL_RESOURCE_LIST
XboxGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
{
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
//EXTENDED_GEOMETRY ExtGeometry;
GEOMETRY Geometry;
ULONG Size;
//
// Initialize returned size
//
*pSize = 0;
/* Set 'Configuration Data' value */
Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
if (PartialResourceList == NULL)
{
ERR("Failed to allocate a full resource descriptor\n");
return NULL;
}
memset(PartialResourceList, 0, Size);
PartialResourceList->Version = 1;
PartialResourceList->Revision = 1;
PartialResourceList->Count = 1;
PartialResourceList->PartialDescriptors[0].Type =
CmResourceTypeDeviceSpecific;
// PartialResourceList->PartialDescriptors[0].ShareDisposition =
// PartialResourceList->PartialDescriptors[0].Flags =
PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
/* Get pointer to geometry data */
DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
/* Get the disk geometry */
//ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
if (MachDiskGetDriveGeometry(DriveNumber, &Geometry))
{
DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
DiskGeometry->SectorsPerTrack = Geometry.Sectors;
DiskGeometry->NumberOfHeads = Geometry.Heads;
}
else
{
ERR("Reading disk geometry failed\n");
FrLdrHeapFree(PartialResourceList, TAG_HW_RESOURCE_LIST);
return NULL;
}
TRACE("Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
DriveNumber,
DiskGeometry->NumberOfCylinders,
DiskGeometry->NumberOfHeads,
DiskGeometry->SectorsPerTrack,
DiskGeometry->BytesPerSector);
//
// Return configuration data
//
*pSize = Size;
return PartialResourceList;
}
#define GetHarddiskConfigurationData XboxGetHarddiskConfigurationData
extern ARC_STATUS
DiskClose(ULONG FileId);
extern ARC_STATUS
DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information);
static
ARC_STATUS
DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
{
DISKCONTEXT* Context;
ULONG DrivePartition, SectorSize;
UCHAR DriveNumber;
ULONGLONG SectorOffset = 0;
ULONGLONG SectorCount = 0;
PARTITION_TABLE_ENTRY PartitionTableEntry;
CHAR FileName[1];
if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition))
return EINVAL;
if (DrivePartition == 0xff)
{
/* This is a CD-ROM device */
SectorSize = 2048;
}
else
{
/* This is either a floppy disk device (DrivePartition == 0) or
* a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but
* it doesn't matter which one because they both have 512 bytes per sector */
SectorSize = 512;
}
if (DrivePartition != 0xff && DrivePartition != 0)
{
if (!XboxDiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
return EINVAL;
SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
SectorCount = PartitionTableEntry.PartitionSectorCount;
}
else
{
SectorCount = 0; /* FIXME */
}
Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
if (!Context)
return ENOMEM;
Context->DriveNumber = DriveNumber;
Context->SectorSize = SectorSize;
Context->SectorOffset = SectorOffset;
Context->SectorCount = SectorCount;
Context->SectorNumber = 0;
FsSetDeviceSpecific(*FileId, Context);
return ESUCCESS;
}
extern ARC_STATUS
DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count);
extern ARC_STATUS
DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode);
static const DEVVTBL DiskVtbl =
{
DiskClose,
DiskGetFileInformation,
DiskOpen,
DiskRead,
DiskSeek,
};
static
VOID
GetHarddiskIdentifier(PCHAR Identifier,
UCHAR DriveNumber)
{
PMASTER_BOOT_RECORD Mbr;
PULONG Buffer;
ULONG i;
ULONG Checksum;
ULONG Signature;
CHAR ArcName[MAX_PATH];
PARTITION_TABLE_ENTRY PartitionTableEntry;
/* Read the MBR */
if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
{
ERR("Reading MBR failed\n");
return;
}
Buffer = (ULONG*)DiskReadBuffer;
Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
Signature = Mbr->Signature;
TRACE("Signature: %x\n", Signature);
/* Calculate the MBR checksum */
Checksum = 0;
for (i = 0; i < 512 / sizeof(ULONG); i++)
{
Checksum += Buffer[i];
}
Checksum = ~Checksum + 1;
TRACE("Checksum: %x\n", Checksum);
/* Fill out the ARC disk block */
reactos_arc_disk_info[reactos_disk_count].DiskSignature.Signature = Signature;
reactos_arc_disk_info[reactos_disk_count].DiskSignature.CheckSum = Checksum;
sprintf(ArcName, "multi(0)disk(0)rdisk(%lu)", reactos_disk_count);
strcpy(reactos_arc_disk_info[reactos_disk_count].ArcName, ArcName);
reactos_arc_disk_info[reactos_disk_count].DiskSignature.ArcName =
reactos_arc_disk_info[reactos_disk_count].ArcName;
reactos_disk_count++;
sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(0)", DriveNumber - 0x80);
FsRegisterDevice(ArcName, &DiskVtbl);
/* Add partitions */
i = 1;
DiskReportError(FALSE);
while (XboxDiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry))
{
if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED)
{
sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(%lu)", DriveNumber - 0x80, i);
FsRegisterDevice(ArcName, &DiskVtbl);
}
i++;
}
DiskReportError(TRUE);
/* 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;
TRACE("Identifier: %s\n", Identifier);
}
static
VOID
DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
PCONFIGURATION_COMPONENT_DATA BusKey)
{
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_INT13_DRIVE_PARAMETER Int13Drives;
GEOMETRY Geometry;
PCONFIGURATION_COMPONENT_DATA DiskKey, ControllerKey;
UCHAR DiskCount;
ULONG i;
ULONG Size;
BOOLEAN Changed;
/* Count the number of visible drives */
DiskReportError(FALSE);
DiskCount = 0;
/* There are some really broken BIOSes out there. There are even BIOSes
* that happily report success when you ask them to read from non-existent
* harddisks. So, we set the buffer to known contents first, then try to
* read. If the BIOS reports success but the buffer contents haven't
* changed then we fail anyway */
memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, DiskReadBuffer))
{
Changed = FALSE;
for (i = 0; ! Changed && i < DiskReadBufferSize; i++)
{
Changed = ((PUCHAR)DiskReadBuffer)[i] != 0xcd;
}
if (! Changed)
{
TRACE("BIOS reports success for disk %d but data didn't change\n",
(int)DiskCount);
break;
}
DiskCount++;
memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
}
DiskReportError(TRUE);
TRACE("BIOS reports %d harddisk%s\n",
(int)DiskCount, (DiskCount == 1) ? "" : "s");
//DetectBiosFloppyController(BusKey);
/* Allocate resource descriptor */
Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
if (PartialResourceList == NULL)
{
ERR("Failed to allocate resource descriptor\n");
return;
}
/* Initialize resource descriptor */
memset(PartialResourceList, 0, Size);
PartialResourceList->Version = 1;
PartialResourceList->Revision = 1;
PartialResourceList->Count = 1;
PartialResourceList->PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific;
PartialResourceList->PartialDescriptors[0].ShareDisposition = 0;
PartialResourceList->PartialDescriptors[0].Flags = 0;
PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
/* Get harddisk Int13 geometry data */
Int13Drives = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
for (i = 0; i < DiskCount; i++)
{
if (MachDiskGetDriveGeometry(0x80 + i, &Geometry))
{
Int13Drives[i].DriveSelect = 0x80 + i;
Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
Int13Drives[i].SectorsPerTrack = (USHORT)Geometry.Sectors;
Int13Drives[i].MaxHeads = (USHORT)Geometry.Heads - 1;
Int13Drives[i].NumberDrives = DiskCount;
TRACE(
"Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
0x80 + i,
Geometry.Cylinders - 1,
Geometry.Heads - 1,
Geometry.Sectors,
Geometry.BytesPerSector);
}
}
FldrCreateComponentKey(BusKey,
ControllerClass,
DiskController,
Output | Input,
0,
0xFFFFFFFF,
NULL,
PartialResourceList,
Size,
&ControllerKey);
TRACE("Created key: DiskController\\0\n");
/* Create and fill subkey for each harddisk */
for (i = 0; i < DiskCount; i++)
{
CHAR Identifier[20];
/* Get disk values */
PartialResourceList = GetHarddiskConfigurationData(0x80 + i, &Size);
GetHarddiskIdentifier(Identifier, 0x80 + i);
/* Create disk key */
FldrCreateComponentKey(ControllerKey,
PeripheralClass,
DiskPeripheral,
Output | Input,
0,
0xFFFFFFFF,
Identifier,
PartialResourceList,
Size,
&DiskKey);
}
}
BOOLEAN
XboxInitializeBootDevices(VOID)
{
// Emulate old behavior
return XboxHwDetect() != NULL;
}
static
VOID
DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
{
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCONFIGURATION_COMPONENT_DATA BusKey;
ULONG Size;
/* Set 'Configuration Data' value */
Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
if (PartialResourceList == NULL)
{
TRACE("Failed to allocate resource descriptor\n");
return;
}
/* Initialize resource descriptor */
memset(PartialResourceList, 0, Size);
PartialResourceList->Version = 1;
PartialResourceList->Revision = 1;
PartialResourceList->Count = 0;
/* Create new bus key */
FldrCreateComponentKey(SystemKey,
AdapterClass,
MultiFunctionAdapter,
0x0,
0x0,
0xFFFFFFFF,
"ISA",
PartialResourceList,
Size,
&BusKey);
/* Increment bus number */
(*BusNumber)++;
/* Detect ISA/BIOS devices */
DetectBiosDisks(SystemKey, BusKey);
/* FIXME: Detect more ISA devices */
}
PCONFIGURATION_COMPONENT_DATA
XboxHwDetect(VOID)
{
PCONFIGURATION_COMPONENT_DATA SystemKey;
ULONG BusNumber = 0;
TRACE("DetectHardware()\n");
/* Create the 'System' key */
FldrCreateSystemKey(&SystemKey);
/* TODO: Build actual xbox's hardware configuration tree */
DetectIsaBios(SystemKey, &BusNumber);
TRACE("DetectHardware() Done\n");
return SystemKey;
}
VOID XboxHwIdle(VOID)
{
/* UNIMPLEMENTED */
}
/******************************************************************************/
VOID
XboxMachInit(const char *CmdLine)
{
@ -51,7 +511,7 @@ XboxMachInit(const char *CmdLine)
MachVtbl.DiskGetDriveGeometry = XboxDiskGetDriveGeometry;
MachVtbl.DiskGetCacheableBlockCount = XboxDiskGetCacheableBlockCount;
MachVtbl.GetTime = XboxGetTime;
MachVtbl.InitializeBootDevices = XboxInitializeBootDevices;
MachVtbl.InitializeBootDevices = PcInitializeBootDevices;
MachVtbl.HwDetect = XboxHwDetect;
MachVtbl.HwIdle = XboxHwIdle;
@ -62,9 +522,9 @@ XboxMachInit(const char *CmdLine)
VOID
XboxPrepareForReactOS(IN BOOLEAN Setup)
{
//
// On XBOX, prepare video and turn off the floppy motor
//
/* On XBOX, prepare video and turn off the floppy motor */
XboxVideoPrepareForReactOS(Setup);
DiskStopFloppyMotor();
}
/* EOF */

View file

@ -18,6 +18,8 @@
*/
#include <freeldr.h>
#define NDEBUG
#include <debug.h>
DBG_DEFAULT_CHANNEL(DISK);
@ -38,28 +40,27 @@ typedef struct
} I386_DISK_ADDRESS_PACKET, *PI386_DISK_ADDRESS_PACKET;
#include <poppack.h>
/////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////////////
/* FUNCTIONS *****************************************************************/
static BOOLEAN PcDiskResetController(UCHAR DriveNumber)
BOOLEAN DiskResetController(UCHAR DriveNumber)
{
REGS RegsIn;
REGS RegsOut;
REGS RegsIn, RegsOut;
WARN("PcDiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
WARN("DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
// BIOS Int 13h, function 0 - Reset disk system
// AH = 00h
// DL = drive (if bit 7 is set both hard disks and floppy disks reset)
// Return:
// AH = status
// CF clear if successful
// CF set on error
/*
* BIOS Int 13h, function 0 - Reset disk system
* AH = 00h
* DL = drive (if bit 7 is set both hard disks and floppy disks reset)
* Return:
* AH = status
* CF clear if successful
* CF set on error
*/
RegsIn.b.ah = 0x00;
RegsIn.b.dl = DriveNumber;
// Reset the disk controller
/* Reset the disk controller */
Int386(0x13, &RegsIn, &RegsOut);
return INT386_SUCCESS(RegsOut);
@ -67,23 +68,16 @@ static BOOLEAN PcDiskResetController(UCHAR DriveNumber)
static BOOLEAN PcDiskReadLogicalSectorsLBA(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
REGS RegsIn;
REGS RegsOut;
REGS RegsIn, RegsOut;
ULONG RetryCount;
PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
TRACE("PcDiskReadLogicalSectorsLBA() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer);
ASSERT(((ULONG_PTR)Buffer) <= 0xFFFFF);
// BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
RegsIn.b.ah = 0x42; // Subfunction 42h
RegsIn.b.dl = DriveNumber; // Drive number in DL (0 - floppy, 0x80 - harddisk)
RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> disk address packet
RegsIn.w.si = BIOSCALLBUFOFFSET;
// Setup disk address packet
RtlZeroMemory(Packet, sizeof(I386_DISK_ADDRESS_PACKET));
Packet->PacketSize = sizeof(I386_DISK_ADDRESS_PACKET);
/* Setup disk address packet */
RtlZeroMemory(Packet, sizeof(*Packet));
Packet->PacketSize = sizeof(*Packet);
Packet->Reserved = 0;
Packet->LBABlockCount = (USHORT)SectorCount;
ASSERT(Packet->LBABlockCount == SectorCount);
@ -91,39 +85,45 @@ static BOOLEAN PcDiskReadLogicalSectorsLBA(UCHAR DriveNumber, ULONGLONG SectorNu
Packet->TransferBufferSegment = (USHORT)(((ULONG_PTR)Buffer) >> 4);
Packet->LBAStartBlock = SectorNumber;
// BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
// Return:
// CF clear if successful
// AH = 00h
// CF set on error
// AH = error code
// disk address packet's block count field set to the
// number of blocks successfully transferred
/*
* BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
* Return:
* CF clear if successful
* AH = 00h
* CF set on error
* AH = error code
* Disk address packet's block count field set to the
* number of blocks successfully transferred.
*/
RegsIn.b.ah = 0x42; // Subfunction 42h
RegsIn.b.dl = DriveNumber; // Drive number in DL (0 - floppy, 0x80 - harddisk)
RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> disk address packet
RegsIn.w.si = BIOSCALLBUFOFFSET;
// Retry 3 times
/* Retry 3 times */
for (RetryCount=0; RetryCount<3; RetryCount++)
{
Int386(0x13, &RegsIn, &RegsOut);
// If it worked return TRUE
/* If it worked return TRUE */
if (INT386_SUCCESS(RegsOut))
{
return TRUE;
}
// If it was a corrected ECC error then the data is still good
/* If it was a corrected ECC error then the data is still good */
else if (RegsOut.b.ah == 0x11)
{
return TRUE;
}
// If it failed then do the next retry
/* If it failed then do the next retry */
else
{
PcDiskResetController(DriveNumber);
DiskResetController(DriveNumber);
continue;
}
}
// If we get here then the read failed
/* If we get here then the read failed */
ERR("Disk Read Failed in LBA mode: %x (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n", RegsOut.b.ah, DriveNumber, SectorNumber, SectorCount);
return FALSE;
@ -136,15 +136,12 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu
ULONG PhysicalTrack;
GEOMETRY DriveGeometry;
ULONG NumberOfSectorsToRead;
REGS RegsIn;
REGS RegsOut;
REGS RegsIn, RegsOut;
ULONG RetryCount;
TRACE("PcDiskReadLogicalSectorsCHS()\n");
//
// Get the drive geometry
//
/* Get the drive geometry */
if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry) ||
DriveGeometry.Sectors == 0 ||
DriveGeometry.Heads == 0)
@ -154,18 +151,15 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu
while (SectorCount)
{
//
// Calculate the physical disk offsets
// Note: DriveGeometry.Sectors < 64
//
/*
* Calculate the physical disk offsets.
* Note: DriveGeometry.Sectors < 64
*/
PhysicalSector = 1 + (UCHAR)(SectorNumber % DriveGeometry.Sectors);
PhysicalHead = (UCHAR)((SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads);
PhysicalTrack = (ULONG)((SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads);
//
// Calculate how many sectors we need to read this round
//
/* Calculate how many sectors we need to read this round */
if (PhysicalSector > 1)
{
if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
@ -181,9 +175,7 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu
NumberOfSectorsToRead = SectorCount;
}
//
// Make sure the read is within the geometry boundaries
//
/* Make sure the read is within the geometry boundaries */
if ((PhysicalHead >= DriveGeometry.Heads) ||
(PhysicalTrack >= DriveGeometry.Cylinders) ||
((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
@ -193,22 +185,24 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu
return FALSE;
}
// BIOS Int 13h, function 2 - Read Disk Sectors
// AH = 02h
// AL = number of sectors to read (must be nonzero)
// CH = low eight bits of cylinder number
// CL = sector number 1-63 (bits 0-5)
// high two bits of cylinder (bits 6-7, hard disk only)
// DH = head number
// DL = drive number (bit 7 set for hard disk)
// ES:BX -> data buffer
// Return:
// CF set on error
// if AH = 11h (corrected ECC error), AL = burst length
// CF clear if successful
// AH = status
// AL = number of sectors transferred
// (only valid if CF set for some BIOSes)
/*
* BIOS Int 13h, function 2 - Read Disk Sectors
* AH = 02h
* AL = number of sectors to read (must be nonzero)
* CH = low eight bits of cylinder number
* CL = sector number 1-63 (bits 0-5)
* high two bits of cylinder (bits 6-7, hard disk only)
* DH = head number
* DL = drive number (bit 7 set for hard disk)
* ES:BX -> data buffer
* Return:
* CF set on error
* if AH = 11h (corrected ECC error), AL = burst length
* CF clear if successful
* AH = status
* AL = number of sectors transferred
* (only valid if CF set for some BIOSes)
*/
RegsIn.b.ah = 0x02;
RegsIn.b.al = (UCHAR)NumberOfSectorsToRead;
RegsIn.b.ch = (PhysicalTrack & 0xFF);
@ -218,41 +212,37 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu
RegsIn.w.es = (USHORT)(((ULONG_PTR)Buffer) >> 4);
RegsIn.w.bx = ((ULONG_PTR)Buffer) & 0x0F;
//
// Perform the read
// Retry 3 times
//
/* Perform the read. Retry 3 times. */
for (RetryCount=0; RetryCount<3; RetryCount++)
{
Int386(0x13, &RegsIn, &RegsOut);
// If it worked break out
/* If it worked break out */
if (INT386_SUCCESS(RegsOut))
{
break;
}
// If it was a corrected ECC error then the data is still good
/* If it was a corrected ECC error then the data is still good */
else if (RegsOut.b.ah == 0x11)
{
break;
}
// If it failed the do the next retry
/* If it failed the do the next retry */
else
{
PcDiskResetController(DriveNumber);
DiskResetController(DriveNumber);
continue;
}
}
// If we retried 3 times then fail
/* If we retried 3 times then fail */
if (RetryCount >= 3)
{
ERR("Disk Read Failed in CHS mode, after retrying 3 times: %x\n", RegsOut.b.ah);
return FALSE;
}
// I have learned that not all bioses return
// I have learned that not all BIOSes return
// the sector read count in the AL register (at least mine doesn't)
// even if the sectors were read correctly. So instead
// of checking the sector read count we will rely solely
@ -266,61 +256,229 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu
return TRUE;
}
static BOOLEAN DiskInt13ExtensionsSupported(UCHAR DriveNumber)
{
static UCHAR LastDriveNumber = 0xff;
static BOOLEAN LastSupported;
REGS RegsIn, RegsOut;
TRACE("DiskInt13ExtensionsSupported()\n");
if (DriveNumber == LastDriveNumber)
{
TRACE("Using cached value %s for drive 0x%x\n",
LastSupported ? "TRUE" : "FALSE", DriveNumber);
return LastSupported;
}
/*
* Some BIOSes report that extended disk access functions are not supported
* when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping
* with Intel Macs). Therefore we just return TRUE if we're booting from a CD -
* we can assume that all El Torito capable BIOSes support INT 13 extensions.
* We simply detect whether we're booting from CD by checking whether the drive
* number is >= 0x8A. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes.
*/
if (DriveNumber >= 0x8A)
{
LastSupported = TRUE;
return TRUE;
}
LastDriveNumber = DriveNumber;
/*
* IBM/MS INT 13 Extensions - INSTALLATION CHECK
* AH = 41h
* BX = 55AAh
* DL = drive (80h-FFh)
* Return:
* CF set on error (extensions not supported)
* AH = 01h (invalid function)
* CF clear if successful
* BX = AA55h if installed
* AH = major version of extensions
* 01h = 1.x
* 20h = 2.0 / EDD-1.0
* 21h = 2.1 / EDD-1.1
* 30h = EDD-3.0
* AL = internal use
* CX = API subset support bitmap
* DH = extension version (v2.0+ ??? -- not present in 1.x)
*
* Bitfields for IBM/MS INT 13 Extensions API support bitmap
* Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
* Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
* Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
* extended drive parameter table is valid
* Bits 3-15 reserved
*/
RegsIn.b.ah = 0x41;
RegsIn.w.bx = 0x55AA;
RegsIn.b.dl = DriveNumber;
/* Reset the disk controller */
Int386(0x13, &RegsIn, &RegsOut);
if (!INT386_SUCCESS(RegsOut))
{
/* CF set on error (extensions not supported) */
LastSupported = FALSE;
return FALSE;
}
if (RegsOut.w.bx != 0xAA55)
{
/* BX = AA55h if installed */
LastSupported = FALSE;
return FALSE;
}
if (!(RegsOut.w.cx & 0x0001))
{
/*
* CX = API subset support bitmap.
* Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported.
*/
DbgPrint("Suspicious API subset support bitmap 0x%x on device 0x%lx\n",
RegsOut.w.cx, DriveNumber);
LastSupported = FALSE;
return FALSE;
}
LastSupported = TRUE;
return TRUE;
}
BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
BOOLEAN ExtensionsSupported;
TRACE("PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer);
TRACE("PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n",
DriveNumber, SectorNumber, SectorCount, Buffer);
//
// Check to see if it is a fixed disk drive
// If so then check to see if Int13 extensions work
// If they do then use them, otherwise default back to BIOS calls
//
/*
* Check to see if it is a fixed disk drive.
* If so then check to see if Int13 extensions work.
* If they do then use them, otherwise default back to BIOS calls.
*/
ExtensionsSupported = DiskInt13ExtensionsSupported(DriveNumber);
if ((DriveNumber >= 0x80) && ExtensionsSupported)
{
TRACE("Using Int 13 Extensions for read. DiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, ExtensionsSupported ? "TRUE" : "FALSE");
//
// LBA is easy, nothing to calculate
// Just do the read
//
/* LBA is easy, nothing to calculate. Just do the read. */
return PcDiskReadLogicalSectorsLBA(DriveNumber, SectorNumber, SectorCount, Buffer);
}
else
{
// LBA is not supported default to the CHS calls
/* LBA is not supported default to the CHS calls */
return PcDiskReadLogicalSectorsCHS(DriveNumber, SectorNumber, SectorCount, Buffer);
}
return TRUE;
}
VOID DiskStopFloppyMotor(VOID)
{
WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0);
}
BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize)
{
REGS RegsIn, RegsOut;
PUSHORT Ptr = (PUSHORT)(BIOSCALLBUFFER);
TRACE("DiskGetExtendedDriveParameters()\n");
if (!DiskInt13ExtensionsSupported(DriveNumber))
return FALSE;
/* 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);
#if DBG
TRACE("size of buffer: %x\n", Ptr[0]);
TRACE("information flags: %x\n", Ptr[1]);
TRACE("number of physical cylinders on drive: %u\n", *(PULONG)&Ptr[2]);
TRACE("number of physical heads on drive: %u\n", *(PULONG)&Ptr[4]);
TRACE("number of physical sectors per track: %u\n", *(PULONG)&Ptr[6]);
TRACE("total number of sectors on drive: %I64u\n", *(unsigned long long*)&Ptr[8]);
TRACE("bytes per sector: %u\n", Ptr[12]);
if (Ptr[0] >= 0x1e)
{
TRACE("EED configuration parameters: %x:%x\n", Ptr[13], Ptr[14]);
if (Ptr[13] != 0xffff && Ptr[14] != 0xffff)
{
PUCHAR SpecPtr = (PUCHAR)(ULONG_PTR)((Ptr[13] << 4) + Ptr[14]);
TRACE("SpecPtr: %x\n", SpecPtr);
TRACE("physical I/O port base address: %x\n", *(PUSHORT)&SpecPtr[0]);
TRACE("disk-drive control port address: %x\n", *(PUSHORT)&SpecPtr[2]);
TRACE("drive flags: %x\n", SpecPtr[4]);
TRACE("proprietary information: %x\n", SpecPtr[5]);
TRACE("IRQ for drive: %u\n", SpecPtr[6]);
TRACE("sector count for multi-sector transfers: %u\n", SpecPtr[7]);
TRACE("DMA control: %x\n", SpecPtr[8]);
TRACE("programmed I/O control: %x\n", SpecPtr[9]);
TRACE("drive options: %x\n", *(PUSHORT)&SpecPtr[10]);
}
}
if (Ptr[0] >= 0x42)
{
TRACE("signature: %x\n", Ptr[15]);
}
#endif
return TRUE;
}
BOOLEAN
PcDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
{
EXTENDED_GEOMETRY ExtGeometry;
REGS RegsIn;
REGS RegsOut;
REGS RegsIn, RegsOut;
ULONG Cylinders;
TRACE("DiskGetDriveGeometry()\n");
/* Try to get the extended geometry first */
ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
ExtGeometry.Size = sizeof(ExtGeometry);
if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
{
Geometry->Cylinders = ExtGeometry.Cylinders;
Geometry->Heads = ExtGeometry.Heads;
Geometry->Sectors = ExtGeometry.SectorsPerTrack;
Geometry->BytesPerSector = ExtGeometry.BytesPerSector;
return TRUE;
}
/* BIOS Int 13h, function 08h - Get drive parameters
/*
* BIOS Int 13h, function 08h - Get drive parameters
* AH = 08h
* DL = drive (bit 7 set for hard disk)
* ES:DI = 0000h:0000h to guard against BIOS bugs
@ -345,11 +503,8 @@ PcDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
/* Get drive parameters */
Int386(0x13, &RegsIn, &RegsOut);
if (!INT386_SUCCESS(RegsOut))
{
return FALSE;
}
Cylinders = (RegsOut.b.cl & 0xC0) << 2;
Cylinders += RegsOut.b.ch;
@ -368,13 +523,13 @@ PcDiskGetCacheableBlockCount(UCHAR DriveNumber)
GEOMETRY Geometry;
/* If LBA is supported then the block size will be 64 sectors (32k)
* If not then the block size is the size of one track */
* If not then the block size is the size of one track. */
if (DiskInt13ExtensionsSupported(DriveNumber))
{
return 64;
}
/* Get the disk geometry
* If this fails then we will just return 1 sector to be safe */
/* Get the disk geometry. If this fails then we will
* just return 1 sector to be safe. */
else if (! PcDiskGetDriveGeometry(DriveNumber, &Geometry))
{
return 1;

View file

@ -190,12 +190,12 @@ typedef struct _IDE_DRIVE_IDENTIFY
UCHAR Reserved08H; /*08*/
UCHAR BytesInPLO;
USHORT VendorUniqueCnt; /*09*/
char SerialNumber[20]; /*10*/
UCHAR SerialNumber[20]; /*10*/
USHORT ControllerType; /*20*/
USHORT BufferSize; /*21*/
USHORT ECCByteCnt; /*22*/
char FirmwareRev[8]; /*23*/
char ModelNumber[40]; /*27*/
UCHAR FirmwareRev[8]; /*23*/
UCHAR ModelNumber[40]; /*27*/
USHORT RWMultImplemented; /*47*/
USHORT DWordIo; /*48*/
USHORT Capabilities; /*49*/
@ -261,7 +261,6 @@ typedef struct _IDE_DRIVE_IDENTIFY
* RETURNS:
* BOOLEAN: TRUE success, FALSE error
*/
static BOOLEAN
XboxDiskPolledRead(ULONG CommandPort,
ULONG ControlPort,
@ -284,9 +283,8 @@ XboxDiskPolledRead(ULONG CommandPort,
{
Status = IDEReadStatus(CommandPort);
if (!(Status & IDE_SR_BUSY))
{
break;
}
StallExecutionProcessor(10);
}
TRACE("status=0x%x\n", Status);
@ -338,7 +336,7 @@ XboxDiskPolledRead(ULONG CommandPort,
IDEWriteCommand(CommandPort, Command);
StallExecutionProcessor(50);
/* wait for DRQ or error */
/* Wait for DRQ or error */
for (RetryCount = 0; RetryCount < IDE_MAX_POLL_RETRIES; RetryCount++)
{
Status = IDEReadStatus(CommandPort);
@ -349,7 +347,6 @@ XboxDiskPolledRead(ULONG CommandPort,
IDEWriteDriveControl(ControlPort, 0);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
@ -362,20 +359,18 @@ XboxDiskPolledRead(ULONG CommandPort,
IDEWriteDriveControl(ControlPort, 0);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
}
StallExecutionProcessor(10);
}
/* timed out */
/* Timed out */
if (RetryCount >= IDE_MAX_POLL_RETRIES)
{
IDEWriteDriveControl(ControlPort, 0);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
@ -405,7 +400,6 @@ XboxDiskPolledRead(ULONG CommandPort,
IDEWriteDriveControl(ControlPort, 0);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
if (Status & IDE_SR_DRQ)
@ -424,10 +418,10 @@ XboxDiskPolledRead(ULONG CommandPort,
TRACE("Read %lu sectors of junk!\n",
SectorCount - SectorCnt);
}
IDEWriteDriveControl(ControlPort, 0);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return TRUE;
}
}
@ -483,9 +477,10 @@ XboxDiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_T
{
UCHAR SectorData[IDE_SECTOR_BUF_SZ];
/* This is the Xbox, chances are that there is a Xbox-standard partitionless
* disk in it so let's check that first */
/*
* This is the Xbox, chances are that there is a Xbox-standard
* partitionless disk in it so let's check that first.
*/
if (1 <= PartitionNumber && PartitionNumber <= sizeof(XboxPartitions) / sizeof(XboxPartitions[0]) &&
MachDiskReadLogicalSectors(DriveNumber, XBOX_SIGNATURE_SECTOR, 1, SectorData))
{
@ -547,7 +542,7 @@ XboxDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
{
for (i = 1 << 15; i; i /= 2)
{
if (0 != (DrvParms.BytesPerSector & i))
if ((DrvParms.BytesPerSector & i) != 0)
{
Geometry->BytesPerSector = i;
break;

View file

@ -1,531 +0,0 @@
/*
* FreeLoader
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <freeldr.h>
#define NDEBUG
#include <debug.h>
DBG_DEFAULT_CHANNEL(HWDETECT);
static CHAR Hex[] = "0123456789ABCDEF";
//static unsigned int delay_count = 1;
extern ULONG reactos_disk_count;
extern ARC_DISK_SIGNATURE_EX reactos_arc_disk_info[];
static
PCM_PARTIAL_RESOURCE_LIST
GetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
{
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
//EXTENDED_GEOMETRY ExtGeometry;
GEOMETRY Geometry;
ULONG Size;
//
// Initialize returned size
//
*pSize = 0;
/* Set 'Configuration Data' value */
Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
if (PartialResourceList == NULL)
{
ERR("Failed to allocate a full resource descriptor\n");
return NULL;
}
memset(PartialResourceList, 0, Size);
PartialResourceList->Version = 1;
PartialResourceList->Revision = 1;
PartialResourceList->Count = 1;
PartialResourceList->PartialDescriptors[0].Type =
CmResourceTypeDeviceSpecific;
// PartialResourceList->PartialDescriptors[0].ShareDisposition =
// PartialResourceList->PartialDescriptors[0].Flags =
PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
/* Get pointer to geometry data */
DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
/* Get the disk geometry */
//ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
if (MachDiskGetDriveGeometry(DriveNumber, &Geometry))
{
DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
DiskGeometry->SectorsPerTrack = Geometry.Sectors;
DiskGeometry->NumberOfHeads = Geometry.Heads;
}
else
{
ERR("Reading disk geometry failed\n");
FrLdrHeapFree(PartialResourceList, TAG_HW_RESOURCE_LIST);
return NULL;
}
TRACE("Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
DriveNumber,
DiskGeometry->NumberOfCylinders,
DiskGeometry->NumberOfHeads,
DiskGeometry->SectorsPerTrack,
DiskGeometry->BytesPerSector);
//
// Return configuration data
//
*pSize = Size;
return PartialResourceList;
}
typedef struct tagDISKCONTEXT
{
UCHAR DriveNumber;
ULONG SectorSize;
ULONGLONG SectorOffset;
ULONGLONG SectorCount;
ULONGLONG SectorNumber;
} DISKCONTEXT;
static
ARC_STATUS
DiskClose(ULONG FileId)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
FrLdrTempFree(Context, TAG_HW_DISK_CONTEXT);
return ESUCCESS;
}
static
ARC_STATUS
DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
RtlZeroMemory(Information, sizeof(FILEINFORMATION));
Information->EndingAddress.QuadPart = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize;
Information->CurrentAddress.QuadPart = (Context->SectorOffset + Context->SectorNumber) * Context->SectorSize;
return ESUCCESS;
}
static
ARC_STATUS
DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
{
DISKCONTEXT* Context;
ULONG DrivePartition, SectorSize;
UCHAR DriveNumber;
ULONGLONG SectorOffset = 0;
ULONGLONG SectorCount = 0;
PARTITION_TABLE_ENTRY PartitionTableEntry;
CHAR FileName[1];
if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition))
return EINVAL;
if (DrivePartition == 0xff)
{
/* This is a CD-ROM device */
SectorSize = 2048;
}
else
{
/* This is either a floppy disk device (DrivePartition == 0) or
* a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but
* it doesn't matter which one because they both have 512 bytes per sector */
SectorSize = 512;
}
if (DrivePartition != 0xff && DrivePartition != 0)
{
if (!XboxDiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
return EINVAL;
SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
SectorCount = PartitionTableEntry.PartitionSectorCount;
}
else
{
SectorCount = 0; /* FIXME */
}
Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
if (!Context)
return ENOMEM;
Context->DriveNumber = DriveNumber;
Context->SectorSize = SectorSize;
Context->SectorOffset = SectorOffset;
Context->SectorCount = SectorCount;
Context->SectorNumber = 0;
FsSetDeviceSpecific(*FileId, Context);
return ESUCCESS;
}
static
ARC_STATUS
DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
UCHAR* Ptr = (UCHAR*)Buffer;
ULONG i, Length, Sectors;
BOOLEAN ret;
*Count = 0;
i = 0;
while (N > 0)
{
Length = N;
if (Length > DiskReadBufferSize)
Length = DiskReadBufferSize;
Sectors = (Length + Context->SectorSize - 1) / Context->SectorSize;
ret = MachDiskReadLogicalSectors(
Context->DriveNumber,
Context->SectorNumber + Context->SectorOffset + i,
Sectors,
DiskReadBuffer);
if (!ret)
return EIO;
RtlCopyMemory(Ptr, DiskReadBuffer, Length);
Ptr += Length;
*Count += Length;
N -= Length;
i += Sectors;
}
return ESUCCESS;
}
static
ARC_STATUS
DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
if (SeekMode != SeekAbsolute)
return EINVAL;
if (Position->LowPart & (Context->SectorSize - 1))
return EINVAL;
/* FIXME: take HighPart into account */
Context->SectorNumber = Position->LowPart / Context->SectorSize;
return ESUCCESS;
}
static const DEVVTBL DiskVtbl =
{
DiskClose,
DiskGetFileInformation,
DiskOpen,
DiskRead,
DiskSeek,
};
static
VOID
GetHarddiskIdentifier(PCHAR Identifier,
UCHAR DriveNumber)
{
PMASTER_BOOT_RECORD Mbr;
PULONG Buffer;
ULONG i;
ULONG Checksum;
ULONG Signature;
CHAR ArcName[MAX_PATH];
PARTITION_TABLE_ENTRY PartitionTableEntry;
/* Read the MBR */
if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
{
ERR("Reading MBR failed\n");
return;
}
Buffer = (ULONG*)DiskReadBuffer;
Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
Signature = Mbr->Signature;
TRACE("Signature: %x\n", Signature);
/* Calculate the MBR checksum */
Checksum = 0;
for (i = 0; i < 512 / sizeof(ULONG); i++)
{
Checksum += Buffer[i];
}
Checksum = ~Checksum + 1;
TRACE("Checksum: %x\n", Checksum);
/* Fill out the ARC disk block */
reactos_arc_disk_info[reactos_disk_count].DiskSignature.Signature = Signature;
reactos_arc_disk_info[reactos_disk_count].DiskSignature.CheckSum = Checksum;
sprintf(ArcName, "multi(0)disk(0)rdisk(%lu)", reactos_disk_count);
strcpy(reactos_arc_disk_info[reactos_disk_count].ArcName, ArcName);
reactos_arc_disk_info[reactos_disk_count].DiskSignature.ArcName =
reactos_arc_disk_info[reactos_disk_count].ArcName;
reactos_disk_count++;
sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(0)", DriveNumber - 0x80);
FsRegisterDevice(ArcName, &DiskVtbl);
/* Add partitions */
i = 1;
DiskReportError(FALSE);
while (XboxDiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry))
{
if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED)
{
sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(%lu)", DriveNumber - 0x80, i);
FsRegisterDevice(ArcName, &DiskVtbl);
}
i++;
}
DiskReportError(TRUE);
/* 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;
TRACE("Identifier: %s\n", Identifier);
}
static
VOID
DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
PCONFIGURATION_COMPONENT_DATA BusKey)
{
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCM_INT13_DRIVE_PARAMETER Int13Drives;
GEOMETRY Geometry;
PCONFIGURATION_COMPONENT_DATA DiskKey, ControllerKey;
UCHAR DiskCount;
ULONG i;
ULONG Size;
BOOLEAN Changed;
/* Count the number of visible drives */
DiskReportError(FALSE);
DiskCount = 0;
/* There are some really broken BIOSes out there. There are even BIOSes
* that happily report success when you ask them to read from non-existent
* harddisks. So, we set the buffer to known contents first, then try to
* read. If the BIOS reports success but the buffer contents haven't
* changed then we fail anyway */
memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, DiskReadBuffer))
{
Changed = FALSE;
for (i = 0; ! Changed && i < DiskReadBufferSize; i++)
{
Changed = ((PUCHAR)DiskReadBuffer)[i] != 0xcd;
}
if (! Changed)
{
TRACE("BIOS reports success for disk %d but data didn't change\n",
(int)DiskCount);
break;
}
DiskCount++;
memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
}
DiskReportError(TRUE);
TRACE("BIOS reports %d harddisk%s\n",
(int)DiskCount, (DiskCount == 1) ? "" : "s");
//DetectBiosFloppyController(BusKey);
/* Allocate resource descriptor */
Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
if (PartialResourceList == NULL)
{
ERR("Failed to allocate resource descriptor\n");
return;
}
/* Initialize resource descriptor */
memset(PartialResourceList, 0, Size);
PartialResourceList->Version = 1;
PartialResourceList->Revision = 1;
PartialResourceList->Count = 1;
PartialResourceList->PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific;
PartialResourceList->PartialDescriptors[0].ShareDisposition = 0;
PartialResourceList->PartialDescriptors[0].Flags = 0;
PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
/* Get harddisk Int13 geometry data */
Int13Drives = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
for (i = 0; i < DiskCount; i++)
{
if (MachDiskGetDriveGeometry(0x80 + i, &Geometry))
{
Int13Drives[i].DriveSelect = 0x80 + i;
Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
Int13Drives[i].SectorsPerTrack = (USHORT)Geometry.Sectors;
Int13Drives[i].MaxHeads = (USHORT)Geometry.Heads - 1;
Int13Drives[i].NumberDrives = DiskCount;
TRACE(
"Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
0x80 + i,
Geometry.Cylinders - 1,
Geometry.Heads - 1,
Geometry.Sectors,
Geometry.BytesPerSector);
}
}
FldrCreateComponentKey(BusKey,
ControllerClass,
DiskController,
Output | Input,
0,
0xFFFFFFFF,
NULL,
PartialResourceList,
Size,
&ControllerKey);
TRACE("Created key: DiskController\\0\n");
/* Create and fill subkey for each harddisk */
for (i = 0; i < DiskCount; i++)
{
CHAR Identifier[20];
/* Get disk values */
PartialResourceList = GetHarddiskConfigurationData(0x80 + i, &Size);
GetHarddiskIdentifier(Identifier, 0x80 + i);
/* Create disk key */
FldrCreateComponentKey(ControllerKey,
PeripheralClass,
DiskPeripheral,
Output | Input,
0,
0xFFFFFFFF,
Identifier,
PartialResourceList,
Size,
&DiskKey);
}
}
static
VOID
DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
{
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
PCONFIGURATION_COMPONENT_DATA BusKey;
ULONG Size;
/* Set 'Configuration Data' value */
Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
if (PartialResourceList == NULL)
{
TRACE(
"Failed to allocate resource descriptor\n");
return;
}
/* Initialize resource descriptor */
memset(PartialResourceList, 0, Size);
PartialResourceList->Version = 1;
PartialResourceList->Revision = 1;
PartialResourceList->Count = 0;
/* Create new bus key */
FldrCreateComponentKey(SystemKey,
AdapterClass,
MultiFunctionAdapter,
0x0,
0x0,
0xFFFFFFFF,
"ISA",
PartialResourceList,
Size,
&BusKey);
/* Increment bus number */
(*BusNumber)++;
/* Detect ISA/BIOS devices */
DetectBiosDisks(SystemKey, BusKey);
/* FIXME: Detect more ISA devices */
}
PCONFIGURATION_COMPONENT_DATA
XboxHwDetect(VOID)
{
PCONFIGURATION_COMPONENT_DATA SystemKey;
ULONG BusNumber = 0;
TRACE("DetectHardware()\n");
/* Create the 'System' key */
FldrCreateSystemKey(&SystemKey);
/* TODO: Build actual xbox's hardware configuration tree */
DetectIsaBios(SystemKey, &BusNumber);
TRACE("DetectHardware() Done\n");
return SystemKey;
}
BOOLEAN
XboxInitializeBootDevices(VOID)
{
// Emulate old behavior
return XboxHwDetect() != NULL;
}
VOID XboxHwIdle(VOID)
{
/* UNIMPLEMENTED */
}
/* EOF */

View file

@ -19,15 +19,15 @@
#ifndef _M_ARM
#include <freeldr.h>
#define NDEBUG
#include <debug.h>
DBG_DEFAULT_CHANNEL(DISK);
static BOOLEAN bReportError = TRUE;
/////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////////////
/* FUNCTIONS *****************************************************************/
VOID DiskReportError(BOOLEAN bError)
{
@ -41,7 +41,8 @@ VOID DiskError(PCSTR ErrorString, ULONG ErrorCode)
if (bReportError == FALSE)
return;
sprintf(ErrorCodeString, "%s\n\nError Code: 0x%lx\nError: %s", ErrorString, ErrorCode, DiskGetErrorCodeString(ErrorCode));
sprintf(ErrorCodeString, "%s\n\nError Code: 0x%lx\nError: %s",
ErrorString, ErrorCode, DiskGetErrorCodeString(ErrorCode));
TRACE("%s\n", ErrorCodeString);
@ -83,21 +84,17 @@ PCSTR DiskGetErrorCodeString(ULONG ErrorCode)
}
}
// This function is in arch/i386/i386disk.c
//BOOLEAN DiskReadLogicalSectors(ULONG DriveNumber, U64 SectorNumber, ULONG SectorCount, PVOID Buffer)
BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber)
{
// Hard disks use drive numbers >= 0x80
// So if the drive number indicates a hard disk
// then return FALSE
// 0x49 is our magic ramdisk drive, so return FALSE for that too
/*
* Hard disks use drive numbers >= 0x80 . So if the drive number
* indicates a hard disk then return FALSE.
* 0x49 is our magic ramdisk drive, so return FALSE for that too.
*/
if ((DriveNumber >= 0x80) || (DriveNumber == 0x49))
{
return FALSE;
}
// Drive is a floppy diskette so return TRUE
/* The drive is a floppy diskette so return TRUE */
return TRUE;
}
@ -191,10 +188,4 @@ DiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size)
return TRUE;
}
// This function is in arch/i386/i386disk.c
//VOID DiskStopFloppyMotor(VOID)
// This function is in arch/i386/i386disk.c
//ULONG DiskGetCacheableBlockCount(UCHAR DriveNumber)
#endif

View file

@ -49,6 +49,9 @@ VOID PcPrepareForReactOS(IN BOOLEAN Setup);
PFREELDR_MEMORY_DESCRIPTOR PcMemGetMemoryMap(ULONG *MemoryMapSize);
BOOLEAN DiskResetController(UCHAR DriveNumber);
BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize);
BOOLEAN PcDiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size);
BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer);
BOOLEAN PcDiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);

View file

@ -44,6 +44,7 @@ typedef struct _EXTENDED_GEOMETRY
ULONGLONG Sectors;
USHORT BytesPerSector;
ULONG PDPTE;
} EXTENDED_GEOMETRY, *PEXTENDED_GEOMETRY;
//
@ -51,7 +52,8 @@ typedef struct _EXTENDED_GEOMETRY
//
typedef struct _PARTITION_TABLE_ENTRY
{
UCHAR BootIndicator; // 0x00 - non-bootable partition, 0x80 - bootable partition (one partition only)
UCHAR BootIndicator; // 0x00 - non-bootable partition,
// 0x80 - bootable partition (one partition only)
UCHAR StartHead; // Beginning head number
UCHAR StartSector; // Beginning sector (2 high bits of cylinder #)
UCHAR StartCylinder; // Beginning cylinder# (low order bits of cylinder #)
@ -107,16 +109,11 @@ typedef struct _MASTER_BOOT_RECORD
///////////////////////////////////////////////////////////////////////////////////////
//
// i386 BIOS Disk Functions (i386disk.c)
// PC x86/64 BIOS Disk Functions (pcdisk.c)
//
///////////////////////////////////////////////////////////////////////////////////////
#if defined(__i386__) || defined(_M_AMD64)
BOOLEAN DiskResetController(UCHAR DriveNumber);
BOOLEAN DiskInt13ExtensionsSupported(UCHAR DriveNumber);
//VOID DiskStopFloppyMotor(VOID);
BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize);
VOID DiskStopFloppyMotor(VOID);
#endif // defined __i386__ || defined(_M_AMD64)
///////////////////////////////////////////////////////////////////////////////////////
@ -127,9 +124,7 @@ BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHOR
VOID DiskReportError (BOOLEAN bError);
VOID DiskError(PCSTR ErrorString, ULONG ErrorCode);
PCSTR DiskGetErrorCodeString(ULONG ErrorCode);
BOOLEAN DiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); // Implemented in i386disk.c
BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber);
VOID DiskStopFloppyMotor(VOID); // Implemented in i386disk.c
extern UCHAR FrldrBootDrive;
extern ULONG FrldrBootPartition;
extern PVOID DiskReadBuffer;
@ -149,4 +144,7 @@ BOOLEAN DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPAR
BOOLEAN DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord);
/*
* SCSI support (disk/scsiport.c)
*/
ULONG LoadBootDeviceDriver(VOID);