[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,11 +153,10 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
if (ReadSectors > MaxSectors)
ReadSectors = MaxSectors;
ret = MachDiskReadLogicalSectors(
Context->DriveNumber,
SectorOffset,
ReadSectors,
DiskReadBuffer);
ret = MachDiskReadLogicalSectors(Context->DriveNumber,
SectorOffset,
ReadSectors,
DiskReadBuffer);
if (!ret)
break;
@ -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,53 +18,513 @@
#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)
{
/* Set LEDs to red before anything is initialized */
XboxSetLED("rrrr");
/* Set LEDs to red before anything is initialized */
XboxSetLED("rrrr");
/* Initialize our stuff */
XboxMemInit();
XboxVideoInit();
/* Initialize our stuff */
XboxMemInit();
XboxVideoInit();
/* Setup vtbl */
MachVtbl.ConsPutChar = XboxConsPutChar;
MachVtbl.ConsKbHit = XboxConsKbHit;
MachVtbl.ConsGetCh = XboxConsGetCh;
MachVtbl.VideoClearScreen = XboxVideoClearScreen;
MachVtbl.VideoSetDisplayMode = XboxVideoSetDisplayMode;
MachVtbl.VideoGetDisplaySize = XboxVideoGetDisplaySize;
MachVtbl.VideoGetBufferSize = XboxVideoGetBufferSize;
MachVtbl.VideoHideShowTextCursor = XboxVideoHideShowTextCursor;
MachVtbl.VideoPutChar = XboxVideoPutChar;
MachVtbl.VideoCopyOffScreenBufferToVRAM = XboxVideoCopyOffScreenBufferToVRAM;
MachVtbl.VideoIsPaletteFixed = XboxVideoIsPaletteFixed;
MachVtbl.VideoSetPaletteColor = XboxVideoSetPaletteColor;
MachVtbl.VideoGetPaletteColor = XboxVideoGetPaletteColor;
MachVtbl.VideoSync = XboxVideoSync;
MachVtbl.Beep = PcBeep;
MachVtbl.PrepareForReactOS = XboxPrepareForReactOS;
MachVtbl.GetMemoryMap = XboxMemGetMemoryMap;
MachVtbl.DiskGetBootPath = DiskGetBootPath;
MachVtbl.DiskReadLogicalSectors = XboxDiskReadLogicalSectors;
MachVtbl.DiskGetDriveGeometry = XboxDiskGetDriveGeometry;
MachVtbl.DiskGetCacheableBlockCount = XboxDiskGetCacheableBlockCount;
MachVtbl.GetTime = XboxGetTime;
MachVtbl.InitializeBootDevices = XboxInitializeBootDevices;
MachVtbl.HwDetect = XboxHwDetect;
MachVtbl.HwIdle = XboxHwIdle;
/* Setup vtbl */
MachVtbl.ConsPutChar = XboxConsPutChar;
MachVtbl.ConsKbHit = XboxConsKbHit;
MachVtbl.ConsGetCh = XboxConsGetCh;
MachVtbl.VideoClearScreen = XboxVideoClearScreen;
MachVtbl.VideoSetDisplayMode = XboxVideoSetDisplayMode;
MachVtbl.VideoGetDisplaySize = XboxVideoGetDisplaySize;
MachVtbl.VideoGetBufferSize = XboxVideoGetBufferSize;
MachVtbl.VideoHideShowTextCursor = XboxVideoHideShowTextCursor;
MachVtbl.VideoPutChar = XboxVideoPutChar;
MachVtbl.VideoCopyOffScreenBufferToVRAM = XboxVideoCopyOffScreenBufferToVRAM;
MachVtbl.VideoIsPaletteFixed = XboxVideoIsPaletteFixed;
MachVtbl.VideoSetPaletteColor = XboxVideoSetPaletteColor;
MachVtbl.VideoGetPaletteColor = XboxVideoGetPaletteColor;
MachVtbl.VideoSync = XboxVideoSync;
MachVtbl.Beep = PcBeep;
MachVtbl.PrepareForReactOS = XboxPrepareForReactOS;
MachVtbl.GetMemoryMap = XboxMemGetMemoryMap;
MachVtbl.DiskGetBootPath = DiskGetBootPath;
MachVtbl.DiskReadLogicalSectors = XboxDiskReadLogicalSectors;
MachVtbl.DiskGetDriveGeometry = XboxDiskGetDriveGeometry;
MachVtbl.DiskGetCacheableBlockCount = XboxDiskGetCacheableBlockCount;
MachVtbl.GetTime = XboxGetTime;
MachVtbl.InitializeBootDevices = PcInitializeBootDevices;
MachVtbl.HwDetect = XboxHwDetect;
MachVtbl.HwIdle = XboxHwIdle;
/* Set LEDs to orange after init */
XboxSetLED("oooo");
/* Set LEDs to orange after init */
XboxSetLED("oooo");
}
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);
@ -25,41 +27,40 @@ DBG_DEFAULT_CHANNEL(DISK);
#include <pshpack2.h>
typedef struct
{
UCHAR PacketSize; // 00h - Size of packet (10h or 18h)
UCHAR Reserved; // 01h - Reserved (0)
USHORT LBABlockCount; // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
USHORT TransferBufferOffset; // 04h - Transfer buffer offset (seg:off)
USHORT TransferBufferSegment; // Transfer buffer segment (seg:off)
ULONGLONG LBAStartBlock; // 08h - Starting absolute block number
//ULONGLONG TransferBuffer64; // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
// used if DWORD at 04h is FFFFh:FFFFh
// Commented since some earlier BIOSes refuse to work with
// such extended structure
UCHAR PacketSize; // 00h - Size of packet (10h or 18h)
UCHAR Reserved; // 01h - Reserved (0)
USHORT LBABlockCount; // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
USHORT TransferBufferOffset; // 04h - Transfer buffer offset (seg:off)
USHORT TransferBufferSegment; // Transfer buffer segment (seg:off)
ULONGLONG LBAStartBlock; // 08h - Starting absolute block number
// ULONGLONG TransferBuffer64; // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
// used if DWORD at 04h is FFFFh:FFFFh
// Commented since some earlier BIOSes refuse to work with
// such extended structure
} 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;
ULONG RetryCount;
PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
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;
@ -131,20 +131,17 @@ static BOOLEAN PcDiskReadLogicalSectorsLBA(UCHAR DriveNumber, ULONGLONG SectorNu
static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
UCHAR PhysicalSector;
UCHAR PhysicalHead;
ULONG PhysicalTrack;
GEOMETRY DriveGeometry;
ULONG NumberOfSectorsToRead;
REGS RegsIn;
REGS RegsOut;
ULONG RetryCount;
UCHAR PhysicalSector;
UCHAR PhysicalHead;
ULONG PhysicalTrack;
GEOMETRY DriveGeometry;
ULONG NumberOfSectorsToRead;
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,122 +256,287 @@ 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;
ULONG Cylinders;
EXTENDED_GEOMETRY ExtGeometry;
REGS RegsIn, RegsOut;
ULONG Cylinders;
TRACE("DiskGetDriveGeometry()\n");
TRACE("DiskGetDriveGeometry()\n");
/* Try to get the extended geometry first */
ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
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
* AH = 08h
* DL = drive (bit 7 set for hard disk)
* ES:DI = 0000h:0000h to guard against BIOS bugs
* Return:
* CF set on error
* AH = status (07h)
* 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)
*/
RegsIn.b.ah = 0x08;
RegsIn.b.dl = DriveNumber;
RegsIn.w.es = 0x0000;
RegsIn.w.di = 0x0000;
/* Get drive parameters */
Int386(0x13, &RegsIn, &RegsOut);
if (! INT386_SUCCESS(RegsOut))
/* Try to get the extended geometry first */
ExtGeometry.Size = sizeof(ExtGeometry);
if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
{
return FALSE;
Geometry->Cylinders = ExtGeometry.Cylinders;
Geometry->Heads = ExtGeometry.Heads;
Geometry->Sectors = ExtGeometry.SectorsPerTrack;
Geometry->BytesPerSector = ExtGeometry.BytesPerSector;
return TRUE;
}
Cylinders = (RegsOut.b.cl & 0xC0) << 2;
Cylinders += RegsOut.b.ch;
Cylinders++;
Geometry->Cylinders = Cylinders;
Geometry->Heads = RegsOut.b.dh + 1;
Geometry->Sectors = RegsOut.b.cl & 0x3F;
Geometry->BytesPerSector = 512; /* Just assume 512 bytes per sector */
/*
* 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
* Return:
* CF set on error
* AH = status (07h)
* 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)
*/
RegsIn.b.ah = 0x08;
RegsIn.b.dl = DriveNumber;
RegsIn.w.es = 0x0000;
RegsIn.w.di = 0x0000;
return TRUE;
/* Get drive parameters */
Int386(0x13, &RegsIn, &RegsOut);
if (!INT386_SUCCESS(RegsOut))
return FALSE;
Cylinders = (RegsOut.b.cl & 0xC0) << 2;
Cylinders += RegsOut.b.ch;
Cylinders++;
Geometry->Cylinders = Cylinders;
Geometry->Heads = RegsOut.b.dh + 1;
Geometry->Sectors = RegsOut.b.cl & 0x3F;
Geometry->BytesPerSector = 512; /* Just assume 512 bytes per sector */
return TRUE;
}
ULONG
PcDiskGetCacheableBlockCount(UCHAR DriveNumber)
{
GEOMETRY Geometry;
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 (DiskInt13ExtensionsSupported(DriveNumber))
/* 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 (DiskInt13ExtensionsSupported(DriveNumber))
{
return 64;
return 64;
}
/* Get the disk geometry
* If this fails then we will just return 1 sector to be safe */
else if (! PcDiskGetDriveGeometry(DriveNumber, &Geometry))
/* Get the disk geometry. If this fails then we will
* just return 1 sector to be safe. */
else if (! PcDiskGetDriveGeometry(DriveNumber, &Geometry))
{
return 1;
return 1;
}
else
else
{
return Geometry.Sectors;
return Geometry.Sectors;
}
}

View file

@ -36,22 +36,22 @@ DBG_DEFAULT_CHANNEL(DISK);
static struct
{
ULONG SectorCountBeforePartition;
ULONG PartitionSectorCount;
UCHAR SystemIndicator;
ULONG SectorCountBeforePartition;
ULONG PartitionSectorCount;
UCHAR SystemIndicator;
} XboxPartitions[] =
{
/* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */
{ 0x0055F400, 0x0098f800, PARTITION_FAT32 }, /* Store, E: */
{ 0x00465400, 0x000FA000, PARTITION_FAT_16 }, /* System, C: */
{ 0x00000400, 0x00177000, PARTITION_FAT_16 }, /* Cache1, X: */
{ 0x00177400, 0x00177000, PARTITION_FAT_16 }, /* Cache2, Y: */
{ 0x002EE400, 0x00177000, PARTITION_FAT_16 } /* Cache3, Z: */
/* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */
{ 0x0055F400, 0x0098f800, PARTITION_FAT32 }, /* Store , E: */
{ 0x00465400, 0x000FA000, PARTITION_FAT_16 }, /* System, C: */
{ 0x00000400, 0x00177000, PARTITION_FAT_16 }, /* Cache1, X: */
{ 0x00177400, 0x00177000, PARTITION_FAT_16 }, /* Cache2, Y: */
{ 0x002EE400, 0x00177000, PARTITION_FAT_16 } /* Cache3, Z: */
};
#define IDE_SECTOR_BUF_SZ 512
#define IDE_MAX_POLL_RETRIES 100000
#define IDE_MAX_BUSY_RETRIES 50000
#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_ALT_STATUS 0x0000
@ -111,131 +111,131 @@ static struct
* Each macro takes an address of the command port block, and data
*/
#define IDEReadError(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ERROR)))
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ERROR)))
#define IDEWritePrecomp(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_PRECOMP), (Data)))
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_PRECOMP), (Data)))
#define IDEReadSectorCount(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT)))
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT)))
#define IDEWriteSectorCount(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT), (Data)))
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT), (Data)))
#define IDEReadSectorNum(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM)))
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM)))
#define IDEWriteSectorNum(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM), (Data)))
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM), (Data)))
#define IDEReadCylinderLow(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW)))
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW)))
#define IDEWriteCylinderLow(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW), (Data)))
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW), (Data)))
#define IDEReadCylinderHigh(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH)))
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH)))
#define IDEWriteCylinderHigh(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH), (Data)))
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH), (Data)))
#define IDEReadDriveHead(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD)))
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD)))
#define IDEWriteDriveHead(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD), (Data)))
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD), (Data)))
#define IDEReadStatus(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_STATUS)))
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_STATUS)))
#define IDEWriteCommand(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_COMMAND), (Data)))
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_COMMAND), (Data)))
#define IDEReadDMACommand(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address))))
(READ_PORT_UCHAR((PUCHAR)((Address))))
#define IDEWriteDMACommand(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address)), (Data)))
(WRITE_PORT_UCHAR((PUCHAR)((Address)), (Data)))
#define IDEReadDMAStatus(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + 2)))
(READ_PORT_UCHAR((PUCHAR)((Address) + 2)))
#define IDEWriteDMAStatus(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + 2), (Data)))
(WRITE_PORT_UCHAR((PUCHAR)((Address) + 2), (Data)))
#define IDEWritePRDTable(Address, Data) \
(WRITE_PORT_ULONG((PULONG)((Address) + 4), (Data)))
(WRITE_PORT_ULONG((PULONG)((Address) + 4), (Data)))
/*
* Data block read and write commands
*/
#define IDEReadBlock(Address, Buffer, Count) \
(READ_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
(READ_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
#define IDEWriteBlock(Address, Buffer, Count) \
(WRITE_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
(WRITE_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
#define IDEReadBlock32(Address, Buffer, Count) \
(READ_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
(READ_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
#define IDEWriteBlock32(Address, Buffer, Count) \
(WRITE_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
(WRITE_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
#define IDEReadWord(Address) \
(READ_PORT_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT)))
(READ_PORT_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT)))
/*
* Access macros for control registers
* Each macro takes an address of the control port blank and data
*/
#define IDEReadAltStatus(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ALT_STATUS)))
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ALT_STATUS)))
#define IDEWriteDriveControl(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data)))
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data)))
/* IDE_DRIVE_IDENTIFY */
typedef struct _IDE_DRIVE_IDENTIFY
{
USHORT ConfigBits; /*00*/
USHORT LogicalCyls; /*01*/
USHORT Reserved02; /*02*/
USHORT LogicalHeads; /*03*/
USHORT BytesPerTrack; /*04*/
USHORT BytesPerSector; /*05*/
USHORT SectorsPerTrack; /*06*/
UCHAR InterSectorGap; /*07*/
UCHAR InterSectorGapSize;
UCHAR Reserved08H; /*08*/
UCHAR BytesInPLO;
USHORT VendorUniqueCnt; /*09*/
char SerialNumber[20]; /*10*/
USHORT ControllerType; /*20*/
USHORT BufferSize; /*21*/
USHORT ECCByteCnt; /*22*/
char FirmwareRev[8]; /*23*/
char ModelNumber[40]; /*27*/
USHORT RWMultImplemented; /*47*/
USHORT DWordIo; /*48*/
USHORT Capabilities; /*49*/
USHORT ConfigBits; /*00*/
USHORT LogicalCyls; /*01*/
USHORT Reserved02; /*02*/
USHORT LogicalHeads; /*03*/
USHORT BytesPerTrack; /*04*/
USHORT BytesPerSector; /*05*/
USHORT SectorsPerTrack; /*06*/
UCHAR InterSectorGap; /*07*/
UCHAR InterSectorGapSize;
UCHAR Reserved08H; /*08*/
UCHAR BytesInPLO;
USHORT VendorUniqueCnt; /*09*/
UCHAR SerialNumber[20]; /*10*/
USHORT ControllerType; /*20*/
USHORT BufferSize; /*21*/
USHORT ECCByteCnt; /*22*/
UCHAR FirmwareRev[8]; /*23*/
UCHAR ModelNumber[40]; /*27*/
USHORT RWMultImplemented; /*47*/
USHORT DWordIo; /*48*/
USHORT 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
USHORT Reserved50; /*50*/
USHORT MinPIOTransTime; /*51*/
USHORT MinDMATransTime; /*52*/
USHORT TMFieldsValid; /*53*/
USHORT TMCylinders; /*54*/
USHORT TMHeads; /*55*/
USHORT TMSectorsPerTrk; /*56*/
USHORT TMCapacityLo; /*57*/
USHORT TMCapacityHi; /*58*/
USHORT RWMultCurrent; /*59*/
USHORT TMSectorCountLo; /*60*/
USHORT TMSectorCountHi; /*61*/
USHORT DmaModes; /*62*/
USHORT MultiDmaModes; /*63*/
USHORT Reserved64[5]; /*64*/
USHORT Reserved69[2]; /*69*/
USHORT Reserved71[4]; /*71*/
USHORT MaxQueueDepth; /*75*/
USHORT Reserved76[4]; /*76*/
USHORT MajorRevision; /*80*/
USHORT MinorRevision; /*81*/
USHORT SupportedFeatures82; /*82*/
USHORT SupportedFeatures83; /*83*/
USHORT SupportedFeatures84; /*84*/
USHORT EnabledFeatures85; /*85*/
USHORT EnabledFeatures86; /*86*/
USHORT EnabledFeatures87; /*87*/
USHORT UltraDmaModes; /*88*/
USHORT Reserved89[11]; /*89*/
USHORT Max48BitAddress[4]; /*100*/
USHORT Reserved104[151]; /*104*/
USHORT Checksum; /*255*/
USHORT Reserved50; /*50*/
USHORT MinPIOTransTime; /*51*/
USHORT MinDMATransTime; /*52*/
USHORT TMFieldsValid; /*53*/
USHORT TMCylinders; /*54*/
USHORT TMHeads; /*55*/
USHORT TMSectorsPerTrk; /*56*/
USHORT TMCapacityLo; /*57*/
USHORT TMCapacityHi; /*58*/
USHORT RWMultCurrent; /*59*/
USHORT TMSectorCountLo; /*60*/
USHORT TMSectorCountHi; /*61*/
USHORT DmaModes; /*62*/
USHORT MultiDmaModes; /*63*/
USHORT Reserved64[5]; /*64*/
USHORT Reserved69[2]; /*69*/
USHORT Reserved71[4]; /*71*/
USHORT MaxQueueDepth; /*75*/
USHORT Reserved76[4]; /*76*/
USHORT MajorRevision; /*80*/
USHORT MinorRevision; /*81*/
USHORT SupportedFeatures82; /*82*/
USHORT SupportedFeatures83; /*83*/
USHORT SupportedFeatures84; /*84*/
USHORT EnabledFeatures85; /*85*/
USHORT EnabledFeatures86; /*86*/
USHORT EnabledFeatures87; /*87*/
USHORT UltraDmaModes; /*88*/
USHORT Reserved89[11]; /*89*/
USHORT Max48BitAddress[4]; /*100*/
USHORT Reserved104[151]; /*104*/
USHORT Checksum; /*255*/
} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
/* XboxDiskPolledRead
@ -247,21 +247,20 @@ typedef struct _IDE_DRIVE_IDENTIFY
* PASSIVE_LEVEL
*
* ARGUMENTS:
* ULONG CommandPort Address of command port for drive
* ULONG ControlPort Address of control port for drive
* UCHAR PreComp Value to write to precomp register
* UCHAR SectorCnt Value to write to sectorCnt register
* UCHAR SectorNum Value to write to sectorNum register
* UCHAR CylinderLow Value to write to CylinderLow register
* UCHAR CylinderHigh Value to write to CylinderHigh register
* UCHAR DrvHead Value to write to Drive/Head register
* UCHAR Command Value to write to Command register
* PVOID Buffer Buffer for output data
* ULONG CommandPort Address of command port for drive
* ULONG ControlPort Address of control port for drive
* UCHAR PreComp Value to write to precomp register
* UCHAR SectorCnt Value to write to sectorCnt register
* UCHAR SectorNum Value to write to sectorNum register
* UCHAR CylinderLow Value to write to CylinderLow register
* UCHAR CylinderHigh Value to write to CylinderHigh register
* UCHAR DrvHead Value to write to Drive/Head register
* UCHAR Command Value to write to Command register
* PVOID Buffer Buffer for output data
*
* RETURNS:
* BOOLEAN: TRUE success, FALSE error
*/
static BOOLEAN
XboxDiskPolledRead(ULONG CommandPort,
ULONG ControlPort,
@ -274,300 +273,296 @@ XboxDiskPolledRead(ULONG CommandPort,
UCHAR Command,
PVOID Buffer)
{
ULONG SectorCount = 0;
ULONG RetryCount;
BOOLEAN Junk = FALSE;
UCHAR Status;
ULONG SectorCount = 0;
ULONG RetryCount;
BOOLEAN Junk = FALSE;
UCHAR Status;
/* Wait for BUSY to clear */
for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
/* Wait for BUSY to clear */
for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
{
Status = IDEReadStatus(CommandPort);
if (!(Status & IDE_SR_BUSY))
Status = IDEReadStatus(CommandPort);
if (!(Status & IDE_SR_BUSY))
break;
StallExecutionProcessor(10);
}
TRACE("status=0x%x\n", Status);
TRACE("waited %d usecs for busy to clear\n", RetryCount * 10);
if (RetryCount >= IDE_MAX_BUSY_RETRIES)
{
WARN("Drive is BUSY for too long\n");
return FALSE;
}
/* Write Drive/Head to select drive */
IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
StallExecutionProcessor(500);
/* Disable interrupts */
IDEWriteDriveControl(ControlPort, IDE_DC_nIEN);
StallExecutionProcessor(500);
/* Issue command to drive */
if (DrvHead & IDE_DH_LBA)
{
TRACE("READ:DRV=%d:LBA=1:BLK=%d:SC=0x%x:CM=0x%x\n",
DrvHead & IDE_DH_DRV1 ? 1 : 0,
((DrvHead & 0x0f) << 24) + (CylinderHigh << 16) + (CylinderLow << 8) + SectorNum,
SectorCnt,
Command);
}
else
{
TRACE("READ:DRV=%d:LBA=0:CH=0x%x:CL=0x%x:HD=0x%x:SN=0x%x:SC=0x%x:CM=0x%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);
StallExecutionProcessor(50);
/* Wait for DRQ or error */
for (RetryCount = 0; RetryCount < IDE_MAX_POLL_RETRIES; RetryCount++)
{
Status = IDEReadStatus(CommandPort);
if (!(Status & IDE_SR_BUSY))
{
break;
}
StallExecutionProcessor(10);
}
TRACE("status=0x%x\n", Status);
TRACE("waited %d usecs for busy to clear\n", RetryCount * 10);
if (RetryCount >= IDE_MAX_BUSY_RETRIES)
{
WARN("Drive is BUSY for too long\n");
return FALSE;
}
/* Write Drive/Head to select drive */
IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
StallExecutionProcessor(500);
/* Disable interrupts */
IDEWriteDriveControl(ControlPort, IDE_DC_nIEN);
StallExecutionProcessor(500);
/* Issue command to drive */
if (DrvHead & IDE_DH_LBA)
{
TRACE("READ:DRV=%d:LBA=1:BLK=%d:SC=0x%x:CM=0x%x\n",
DrvHead & IDE_DH_DRV1 ? 1 : 0,
((DrvHead & 0x0f) << 24) + (CylinderHigh << 16) + (CylinderLow << 8) + SectorNum,
SectorCnt,
Command);
}
else
{
TRACE("READ:DRV=%d:LBA=0:CH=0x%x:CL=0x%x:HD=0x%x:SN=0x%x:SC=0x%x:CM=0x%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);
StallExecutionProcessor(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);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
if (Status & IDE_SR_DRQ)
{
break;
}
else
{
IDEWriteDriveControl(ControlPort, 0);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
}
StallExecutionProcessor(10);
}
/* timed out */
if (RetryCount >= IDE_MAX_POLL_RETRIES)
{
IDEWriteDriveControl(ControlPort, 0);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
while (1)
{
/* Read data into buffer */
if (Junk == FALSE)
{
IDEReadBlock(CommandPort, Buffer, IDE_SECTOR_BUF_SZ);
Buffer = (PVOID)((ULONG_PTR)Buffer + IDE_SECTOR_BUF_SZ);
}
else
{
UCHAR 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);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
if (Status & IDE_SR_DRQ)
{
if (SectorCount >= SectorCnt)
if (Status & IDE_SR_ERR)
{
TRACE("Buffer size exceeded!\n");
Junk = TRUE;
IDEWriteDriveControl(ControlPort, 0);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
break;
}
else
{
if (SectorCount > SectorCnt)
{
TRACE("Read %lu sectors of junk!\n",
SectorCount - SectorCnt);
}
IDEWriteDriveControl(ControlPort, 0);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return TRUE;
}
if (Status & IDE_SR_DRQ)
{
break;
}
else
{
IDEWriteDriveControl(ControlPort, 0);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
}
StallExecutionProcessor(10);
}
/* Timed out */
if (RetryCount >= IDE_MAX_POLL_RETRIES)
{
IDEWriteDriveControl(ControlPort, 0);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
while (1)
{
/* Read data into buffer */
if (Junk == FALSE)
{
IDEReadBlock(CommandPort, Buffer, IDE_SECTOR_BUF_SZ);
Buffer = (PVOID)((ULONG_PTR)Buffer + IDE_SECTOR_BUF_SZ);
}
else
{
UCHAR 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);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
if (Status & IDE_SR_DRQ)
{
if (SectorCount >= SectorCnt)
{
TRACE("Buffer size exceeded!\n");
Junk = TRUE;
}
break;
}
else
{
if (SectorCount > SectorCnt)
{
TRACE("Read %lu sectors of junk!\n",
SectorCount - SectorCnt);
}
IDEWriteDriveControl(ControlPort, 0);
StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return TRUE;
}
}
}
}
}
BOOLEAN
XboxDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
ULONG StartSector;
UCHAR Count;
ULONG StartSector;
UCHAR Count;
if (DriveNumber < 0x80 || 2 <= (DriveNumber & 0x0f))
if (DriveNumber < 0x80 || 2 <= (DriveNumber & 0x0f))
{
/* Xbox has only 1 IDE controller and no floppy */
WARN("Invalid drive number\n");
return FALSE;
/* Xbox has only 1 IDE controller and no floppy */
WARN("Invalid drive number\n");
return FALSE;
}
if (UINT64_C(0) != ((SectorNumber + SectorCount) & UINT64_C(0xfffffffff0000000)))
if (UINT64_C(0) != ((SectorNumber + SectorCount) & UINT64_C(0xfffffffff0000000)))
{
FIXME("48bit LBA required but not implemented\n");
return FALSE;
FIXME("48bit LBA required but not implemented\n");
return FALSE;
}
StartSector = (ULONG) SectorNumber;
while (0 < SectorCount)
StartSector = (ULONG) SectorNumber;
while (0 < SectorCount)
{
Count = (SectorCount <= 255 ? (UCHAR)SectorCount : 255);
if (! XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
XBOX_IDE_CONTROL_PORT,
0, Count,
StartSector & 0xff,
(StartSector >> 8) & 0xff,
(StartSector >> 16) & 0xff,
((StartSector >> 24) & 0x0f) | IDE_DH_LBA |
(0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
IDE_CMD_READ,
Count = (SectorCount <= 255 ? (UCHAR)SectorCount : 255);
if (!XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
XBOX_IDE_CONTROL_PORT,
0, Count,
StartSector & 0xff,
(StartSector >> 8) & 0xff,
(StartSector >> 16) & 0xff,
((StartSector >> 24) & 0x0f) | IDE_DH_LBA |
(0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
IDE_CMD_READ,
Buffer))
{
return FALSE;
return FALSE;
}
SectorCount -= Count;
Buffer = (PVOID) ((PCHAR) Buffer + Count * IDE_SECTOR_BUF_SZ);
SectorCount -= Count;
Buffer = (PVOID) ((PCHAR) Buffer + Count * IDE_SECTOR_BUF_SZ);
}
return TRUE;
return TRUE;
}
BOOLEAN
XboxDiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
UCHAR SectorData[IDE_SECTOR_BUF_SZ];
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 */
if (1 <= PartitionNumber && PartitionNumber <= sizeof(XboxPartitions) / sizeof(XboxPartitions[0]) &&
MachDiskReadLogicalSectors(DriveNumber, XBOX_SIGNATURE_SECTOR, 1, SectorData))
/*
* 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))
{
if (*((PULONG) SectorData) == XBOX_SIGNATURE)
if (*((PULONG) SectorData) == XBOX_SIGNATURE)
{
memset(PartitionTableEntry, 0, sizeof(PARTITION_TABLE_ENTRY));
PartitionTableEntry->SystemIndicator = XboxPartitions[PartitionNumber - 1].SystemIndicator;
PartitionTableEntry->SectorCountBeforePartition = XboxPartitions[PartitionNumber - 1].SectorCountBeforePartition;
PartitionTableEntry->PartitionSectorCount = XboxPartitions[PartitionNumber - 1].PartitionSectorCount;
return TRUE;
memset(PartitionTableEntry, 0, sizeof(PARTITION_TABLE_ENTRY));
PartitionTableEntry->SystemIndicator = XboxPartitions[PartitionNumber - 1].SystemIndicator;
PartitionTableEntry->SectorCountBeforePartition = XboxPartitions[PartitionNumber - 1].SectorCountBeforePartition;
PartitionTableEntry->PartitionSectorCount = XboxPartitions[PartitionNumber - 1].PartitionSectorCount;
return TRUE;
}
}
/* No magic Xbox partitions. Maybe there's a MBR */
return DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
/* No magic Xbox partitions. Maybe there's a MBR */
return DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
}
BOOLEAN
XboxDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
{
IDE_DRIVE_IDENTIFY DrvParms;
ULONG i;
BOOLEAN Atapi;
IDE_DRIVE_IDENTIFY DrvParms;
ULONG i;
BOOLEAN Atapi;
Atapi = FALSE; /* FIXME */
/* Get the Drive Identify block from drive or die */
if (! XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
XBOX_IDE_CONTROL_PORT,
0,
1,
0,
0,
0,
(0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
(Atapi ? IDE_CMD_IDENT_ATAPI_DRV : IDE_CMD_IDENT_ATA_DRV),
(PUCHAR) &DrvParms))
Atapi = FALSE; /* FIXME */
/* Get the Drive Identify block from drive or die */
if (!XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
XBOX_IDE_CONTROL_PORT,
0,
1,
0,
0,
0,
(0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
(Atapi ? IDE_CMD_IDENT_ATAPI_DRV : IDE_CMD_IDENT_ATA_DRV),
(PUCHAR) &DrvParms))
{
ERR("XboxDiskPolledRead() failed\n");
return FALSE;
ERR("XboxDiskPolledRead() failed\n");
return FALSE;
}
Geometry->Cylinders = DrvParms.LogicalCyls;
Geometry->Heads = DrvParms.LogicalHeads;
Geometry->Sectors = DrvParms.SectorsPerTrack;
Geometry->Cylinders = DrvParms.LogicalCyls;
Geometry->Heads = DrvParms.LogicalHeads;
Geometry->Sectors = DrvParms.SectorsPerTrack;
if (! Atapi && 0 != (DrvParms.Capabilities & IDE_DRID_LBA_SUPPORTED))
if (! Atapi && 0 != (DrvParms.Capabilities & IDE_DRID_LBA_SUPPORTED))
{
/* LBA ATA drives always have a sector size of 512 */
Geometry->BytesPerSector = 512;
/* LBA ATA drives always have a sector size of 512 */
Geometry->BytesPerSector = 512;
}
else
else
{
TRACE("BytesPerSector %d\n", DrvParms.BytesPerSector);
if (DrvParms.BytesPerSector == 0)
TRACE("BytesPerSector %d\n", DrvParms.BytesPerSector);
if (DrvParms.BytesPerSector == 0)
{
Geometry->BytesPerSector = 512;
Geometry->BytesPerSector = 512;
}
else
else
{
for (i = 1 << 15; i; i /= 2)
for (i = 1 << 15; i; i /= 2)
{
if (0 != (DrvParms.BytesPerSector & i))
if ((DrvParms.BytesPerSector & i) != 0)
{
Geometry->BytesPerSector = i;
break;
Geometry->BytesPerSector = i;
break;
}
}
}
}
TRACE("Cylinders %d\n", Geometry->Cylinders);
TRACE("Heads %d\n", Geometry->Heads);
TRACE("Sectors %d\n", Geometry->Sectors);
TRACE("BytesPerSector %d\n", Geometry->BytesPerSector);
TRACE("Cylinders %d\n", Geometry->Cylinders);
TRACE("Heads %d\n", Geometry->Heads);
TRACE("Sectors %d\n", Geometry->Sectors);
TRACE("BytesPerSector %d\n", Geometry->BytesPerSector);
return TRUE;
return TRUE;
}
ULONG
XboxDiskGetCacheableBlockCount(UCHAR DriveNumber)
{
/* 64 seems a nice number, it is used by the machpc code for LBA devices */
return 64;
/* 64 seems a nice number, it is used by the machpc code for LBA devices */
return 64;
}
/* EOF */

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,29 +19,30 @@
#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)
VOID DiskReportError(BOOLEAN bError)
{
bReportError = bError;
}
VOID DiskError(PCSTR ErrorString, ULONG ErrorCode)
{
CHAR ErrorCodeString[200];
CHAR ErrorCodeString[200];
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

@ -23,10 +23,10 @@
typedef struct _GEOMETRY
{
ULONG Cylinders; // Number of cylinders on the disk
ULONG Heads; // Number of heads on the disk
ULONG Sectors; // Number of sectors per track
ULONG BytesPerSector; // Number of bytes per sector
ULONG Cylinders; // Number of cylinders on the disk
ULONG Heads; // Number of heads on the disk
ULONG Sectors; // Number of sectors per track
ULONG BytesPerSector; // Number of bytes per sector
} GEOMETRY, *PGEOMETRY;
@ -36,14 +36,15 @@ typedef struct _GEOMETRY
#include <pshpack1.h>
typedef struct _EXTENDED_GEOMETRY
{
USHORT Size;
USHORT Flags;
ULONG Cylinders;
ULONG Heads;
ULONG SectorsPerTrack;
ULONGLONG Sectors;
USHORT BytesPerSector;
ULONG PDPTE;
USHORT Size;
USHORT Flags;
ULONG Cylinders;
ULONG Heads;
ULONG SectorsPerTrack;
ULONGLONG Sectors;
USHORT BytesPerSector;
ULONG PDPTE;
} EXTENDED_GEOMETRY, *PEXTENDED_GEOMETRY;
//
@ -51,16 +52,17 @@ typedef struct _EXTENDED_GEOMETRY
//
typedef struct _PARTITION_TABLE_ENTRY
{
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 #)
UCHAR SystemIndicator; // System indicator
UCHAR EndHead; // Ending head number
UCHAR EndSector; // Ending sector (2 high bits of cylinder #)
UCHAR EndCylinder; // Ending cylinder# (low order bits of cylinder #)
ULONG SectorCountBeforePartition; // Number of sectors preceding the partition
ULONG PartitionSectorCount; // Number of sectors in the partition
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 #)
UCHAR SystemIndicator; // System indicator
UCHAR EndHead; // Ending head number
UCHAR EndSector; // Ending sector (2 high bits of cylinder #)
UCHAR EndCylinder; // Ending cylinder# (low order bits of cylinder #)
ULONG SectorCountBeforePartition; // Number of sectors preceding the partition
ULONG PartitionSectorCount; // Number of sectors in the partition
} PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY;
@ -69,11 +71,11 @@ typedef struct _PARTITION_TABLE_ENTRY
//
typedef struct _MASTER_BOOT_RECORD
{
UCHAR MasterBootRecordCodeAndData[0x1b8]; /* 0x000 */
ULONG Signature; /* 0x1B8 */
USHORT Reserved; /* 0x1BC */
PARTITION_TABLE_ENTRY PartitionTable[4]; /* 0x1BE */
USHORT MasterBootRecordMagic; /* 0x1FE */
UCHAR MasterBootRecordCodeAndData[0x1b8]; /* 0x000 */
ULONG Signature; /* 0x1B8 */
USHORT Reserved; /* 0x1BC */
PARTITION_TABLE_ENTRY PartitionTable[4]; /* 0x1BE */
USHORT MasterBootRecordMagic; /* 0x1FE */
} MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD;
#include <poppack.h>
@ -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)
///////////////////////////////////////////////////////////////////////////////////////
@ -124,12 +121,10 @@ BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHOR
// FreeLoader Disk Functions
//
///////////////////////////////////////////////////////////////////////////////////////
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
VOID DiskReportError (BOOLEAN bError);
VOID DiskError(PCSTR ErrorString, ULONG ErrorCode);
PCSTR DiskGetErrorCodeString(ULONG ErrorCode);
BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber);
extern UCHAR FrldrBootDrive;
extern ULONG FrldrBootPartition;
extern PVOID DiskReadBuffer;
@ -143,10 +138,13 @@ BOOLEAN DiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size);
// Fixed Disk Partition Management Functions
//
///////////////////////////////////////////////////////////////////////////////////////
BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry, ULONG *ActivePartition);
BOOLEAN DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOLEAN DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOLEAN DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord);
BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry, ULONG *ActivePartition);
BOOLEAN DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOLEAN DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
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);