Add disk I/O (well, input only, no output) for the Xbox

svn path=/trunk/; revision=11608
This commit is contained in:
Gé van Geldorp 2004-11-09 23:36:20 +00:00
parent d5b047feae
commit 2950511d3e
25 changed files with 834 additions and 292 deletions

View file

@ -213,7 +213,9 @@ ARCH_OBJS = fathelp.o \
machpc.o \
machxbox.o \
pccons.o \
pcdisk.o \
pcmem.o \
xboxdisk.o \
xboxfont.o \
xboxmem.o \
xboxvideo.o \

View file

@ -1,4 +1,4 @@
/* $Id: archmach.c,v 1.1 2004/11/08 22:02:47 gvg Exp $
/* $Id: archmach.c,v 1.2 2004/11/09 23:36:19 gvg Exp $
*
* FreeLoader
*
@ -45,6 +45,8 @@ MachInit(VOID)
{
PcMachInit();
}
HalpCalibrateStallExecution();
}
/* EOF */

View file

@ -24,6 +24,7 @@
#include <debug.h>
#include <disk.h>
#include <mm.h>
#include <machine.h>
#include <portio.h>
#include <video.h>
@ -569,7 +570,7 @@ SetHarddiskIdentifier(HKEY DiskKey,
S32 Error;
/* Read the MBR */
if (!DiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
{
DbgPrint((DPRINT_HWDETECT, "Reading MBR failed\n"));
return;
@ -645,7 +646,7 @@ DetectBiosDisks(HKEY SystemKey,
/* Count the number of visible drives */
DiskReportError(FALSE);
DiskCount = 0;
while (DiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, (PVOID)DISKREADBUFFER))
while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, (PVOID)DISKREADBUFFER))
{
DiskCount++;
}
@ -2238,8 +2239,6 @@ DetectHardware(VOID)
DbgPrint((DPRINT_HWDETECT, "DetectHardware()\n"));
HalpCalibrateStallExecution ();
/* Create the 'System' key */
Error = RegCreateKey(NULL,
"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",

View file

@ -159,6 +159,7 @@ typedef struct _CM_COMPONENT_INFORMATION
/* PROTOTYPES ***************************************************************/
/* hardware.c */
VOID HalpCalibrateStallExecution(VOID);
VOID KeStallExecutionProcessor(U32 Microseconds);
VOID SetComponentInformation(HKEY ComponentKey,

View file

@ -25,251 +25,12 @@
#include <portio.h>
typedef struct
{
U8 PacketSize; // 00h - Size of packet (10h or 18h)
U8 Reserved; // 01h - Reserved (0)
U16 LBABlockCount; // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
U16 TransferBufferOffset; // 04h - Transfer buffer offset (seg:off)
U16 TransferBufferSegment; // Transfer buffer segment (seg:off)
U64 LBAStartBlock; // 08h - Starting absolute block number
U64 TransferBuffer64; // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
// used if DWORD at 04h is FFFFh:FFFFh
} PACKED I386_DISK_ADDRESS_PACKET, *PI386_DISK_ADDRESS_PACKET;
/////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////////////
#ifdef __i386__
BOOL DiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
{
DbgPrint((DPRINT_DISK, "DiskReadLogicalSectors() 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
//
if ((DriveNumber >= 0x80) && DiskInt13ExtensionsSupported(DriveNumber))
{
DbgPrint((DPRINT_DISK, "Using Int 13 Extensions for read. DiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, DiskInt13ExtensionsSupported(DriveNumber) ? "TRUE" : "FALSE"));
//
// LBA is easy, nothing to calculate
// Just do the read
//
return DiskReadLogicalSectorsLBA(DriveNumber, SectorNumber, SectorCount, Buffer);
}
else
{
// LBA is not supported default to the CHS calls
return DiskReadLogicalSectorsCHS(DriveNumber, SectorNumber, SectorCount, Buffer);
}
return TRUE;
}
BOOL DiskReadLogicalSectorsLBA(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
{
REGS RegsIn;
REGS RegsOut;
U32 RetryCount;
PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
DbgPrint((DPRINT_DISK, "DiskReadLogicalSectorsLBA() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer));
// 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);
Packet->Reserved = 0;
Packet->LBABlockCount = SectorCount;
Packet->TransferBufferOffset = ((U32)Buffer) & 0x0F;
Packet->TransferBufferSegment = ((U32)Buffer) >> 4;
Packet->LBAStartBlock = SectorNumber;
Packet->TransferBuffer64 = 0;
// 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
// Retry 3 times
for (RetryCount=0; RetryCount<3; RetryCount++)
{
Int386(0x13, &RegsIn, &RegsOut);
// If it worked return TRUE
if (INT386_SUCCESS(RegsOut))
{
return TRUE;
}
// If it was a corrected ECC error then the data is still good
else if (RegsOut.b.ah == 0x11)
{
return TRUE;
}
// If it failed the do the next retry
else
{
DiskResetController(DriveNumber);
continue;
}
}
// If we get here then the read failed
DiskError("Disk Read Failed", RegsOut.b.ah);
return FALSE;
}
BOOL DiskReadLogicalSectorsCHS(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
{
U32 PhysicalSector;
U32 PhysicalHead;
U32 PhysicalTrack;
GEOMETRY DriveGeometry;
U32 NumberOfSectorsToRead;
REGS RegsIn;
REGS RegsOut;
U32 RetryCount;
DbgPrint((DPRINT_DISK, "DiskReadLogicalSectorsCHS()\n"));
//
// Get the drive geometry
//
if (!DiskGetDriveGeometry(DriveNumber, &DriveGeometry))
{
return FALSE;
}
while (SectorCount)
{
//
// Calculate the physical disk offsets
//
PhysicalSector = 1 + (SectorNumber % DriveGeometry.Sectors);
PhysicalHead = (SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads;
PhysicalTrack = (SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads;
//
// Calculate how many sectors we need to read this round
//
if (PhysicalSector > 1)
{
if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
NumberOfSectorsToRead = (DriveGeometry.Sectors - (PhysicalSector - 1));
else
NumberOfSectorsToRead = SectorCount;
}
else
{
if (SectorCount >= DriveGeometry.Sectors)
NumberOfSectorsToRead = DriveGeometry.Sectors;
else
NumberOfSectorsToRead = SectorCount;
}
//
// Make sure the read is within the geometry boundaries
//
if ((PhysicalHead >= DriveGeometry.Heads) ||
(PhysicalTrack >= DriveGeometry.Cylinders) ||
((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
(PhysicalSector > DriveGeometry.Sectors))
{
DiskError("Disk read exceeds drive geometry limits.", 0);
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)
RegsIn.b.ah = 0x02;
RegsIn.b.al = NumberOfSectorsToRead;
RegsIn.b.ch = (PhysicalTrack & 0xFF);
RegsIn.b.cl = (PhysicalSector + ((PhysicalTrack & 0x300) >> 2));
RegsIn.b.dh = PhysicalHead;
RegsIn.b.dl = DriveNumber;
RegsIn.w.es = ((U32)Buffer) >> 4;
RegsIn.w.bx = ((U32)Buffer) & 0x0F;
//
// Perform the read
// Retry 3 times
//
for (RetryCount=0; RetryCount<3; RetryCount++)
{
Int386(0x13, &RegsIn, &RegsOut);
// If it worked break out
if (INT386_SUCCESS(RegsOut))
{
break;
}
// 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
else
{
DiskResetController(DriveNumber);
continue;
}
}
// If we retried 3 times then fail
if (RetryCount >= 3)
{
DiskError("Disk Read Failed", RegsOut.b.ah);
return FALSE;
}
// 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
// on the carry flag being set on error
Buffer += (NumberOfSectorsToRead * DriveGeometry.BytesPerSector);
SectorCount -= NumberOfSectorsToRead;
SectorNumber += NumberOfSectorsToRead;
}
return TRUE;
}
BOOL DiskResetController(U32 DriveNumber)
{
REGS RegsIn;

View file

@ -1,4 +1,4 @@
/* $Id: machpc.c,v 1.1 2004/11/08 22:02:47 gvg Exp $
/* $Id: machpc.c,v 1.2 2004/11/09 23:36:19 gvg Exp $
*
* FreeLoader
*
@ -34,6 +34,7 @@ PcMachInit(VOID)
MachVtbl.PutChar = PcConsPutChar;
MachVtbl.PutCharAttrAtLoc = PcConsPutCharAttrAtLoc;
MachVtbl.GetMemoryMap = PcMemGetMemoryMap;
MachVtbl.DiskReadLogicalSectors = PcDiskReadLogicalSectors;
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: machpc.h,v 1.1 2004/11/08 22:02:47 gvg Exp $
/* $Id: machpc.h,v 1.2 2004/11/09 23:36:19 gvg Exp $
*
* FreeLoader
*
@ -34,6 +34,8 @@ VOID PcConsPutCharAttrAtLoc(int Ch, U8 Attr, unsigned X, unsigned Y);
U32 PcMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize);
BOOL PcDiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer);
#endif /* __I386_MACHPC_H_ */
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: machxbox.c,v 1.1 2004/11/08 22:02:47 gvg Exp $
/* $Id: machxbox.c,v 1.2 2004/11/09 23:36:19 gvg Exp $
*
* FreeLoader
*
@ -34,4 +34,5 @@ XboxMachInit(VOID)
MachVtbl.PutChar = XboxVideoPutChar;
MachVtbl.PutCharAttrAtLoc = XboxVideoPutCharAttrAtLoc;
MachVtbl.GetMemoryMap = XboxMemGetMemoryMap;
MachVtbl.DiskReadLogicalSectors = XboxDiskReadLogicalSectors;
}

View file

@ -1,4 +1,4 @@
/* $Id: machxbox.h,v 1.1 2004/11/08 22:02:47 gvg Exp $
/* $Id: machxbox.h,v 1.2 2004/11/09 23:36:19 gvg Exp $
*
* FreeLoader
*
@ -37,6 +37,8 @@ VOID XboxMemInit(VOID);
PVOID XboxMemReserveMemory(U32 MbToReserve);
U32 XboxMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize);
BOOL XboxDiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer);
#endif /* __I386_HWXBOX_H_ */
/* EOF */

View file

@ -0,0 +1,365 @@
/*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <freeldr.h>
#include <disk.h>
#include <rtl.h>
#include <arch.h>
#include <debug.h>
#include <portio.h>
typedef struct
{
U8 PacketSize; // 00h - Size of packet (10h or 18h)
U8 Reserved; // 01h - Reserved (0)
U16 LBABlockCount; // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
U16 TransferBufferOffset; // 04h - Transfer buffer offset (seg:off)
U16 TransferBufferSegment; // Transfer buffer segment (seg:off)
U64 LBAStartBlock; // 08h - Starting absolute block number
U64 TransferBuffer64; // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
// used if DWORD at 04h is FFFFh:FFFFh
} PACKED I386_DISK_ADDRESS_PACKET, *PI386_DISK_ADDRESS_PACKET;
/////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////////////
static BOOL PcDiskResetController(U32 DriveNumber)
{
REGS RegsIn;
REGS RegsOut;
DbgPrint((DPRINT_DISK, "PcDiskResetController(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);
}
static BOOL PcDiskReadLogicalSectorsLBA(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
{
REGS RegsIn;
REGS RegsOut;
U32 RetryCount;
PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
DbgPrint((DPRINT_DISK, "PcDiskReadLogicalSectorsLBA() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer));
// 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);
Packet->Reserved = 0;
Packet->LBABlockCount = SectorCount;
Packet->TransferBufferOffset = ((U32)Buffer) & 0x0F;
Packet->TransferBufferSegment = ((U32)Buffer) >> 4;
Packet->LBAStartBlock = SectorNumber;
Packet->TransferBuffer64 = 0;
// 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
// Retry 3 times
for (RetryCount=0; RetryCount<3; RetryCount++)
{
Int386(0x13, &RegsIn, &RegsOut);
// If it worked return TRUE
if (INT386_SUCCESS(RegsOut))
{
return TRUE;
}
// If it was a corrected ECC error then the data is still good
else if (RegsOut.b.ah == 0x11)
{
return TRUE;
}
// If it failed the do the next retry
else
{
PcDiskResetController(DriveNumber);
continue;
}
}
// If we get here then the read failed
DiskError("Disk Read Failed", RegsOut.b.ah);
return FALSE;
}
static BOOL PcDiskReadLogicalSectorsCHS(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
{
U32 PhysicalSector;
U32 PhysicalHead;
U32 PhysicalTrack;
GEOMETRY DriveGeometry;
U32 NumberOfSectorsToRead;
REGS RegsIn;
REGS RegsOut;
U32 RetryCount;
DbgPrint((DPRINT_DISK, "PcDiskReadLogicalSectorsCHS()\n"));
//
// Get the drive geometry
//
if (!DiskGetDriveGeometry(DriveNumber, &DriveGeometry))
{
return FALSE;
}
while (SectorCount)
{
//
// Calculate the physical disk offsets
//
PhysicalSector = 1 + (SectorNumber % DriveGeometry.Sectors);
PhysicalHead = (SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads;
PhysicalTrack = (SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads;
//
// Calculate how many sectors we need to read this round
//
if (PhysicalSector > 1)
{
if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
NumberOfSectorsToRead = (DriveGeometry.Sectors - (PhysicalSector - 1));
else
NumberOfSectorsToRead = SectorCount;
}
else
{
if (SectorCount >= DriveGeometry.Sectors)
NumberOfSectorsToRead = DriveGeometry.Sectors;
else
NumberOfSectorsToRead = SectorCount;
}
//
// Make sure the read is within the geometry boundaries
//
if ((PhysicalHead >= DriveGeometry.Heads) ||
(PhysicalTrack >= DriveGeometry.Cylinders) ||
((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
(PhysicalSector > DriveGeometry.Sectors))
{
DiskError("Disk read exceeds drive geometry limits.", 0);
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)
RegsIn.b.ah = 0x02;
RegsIn.b.al = NumberOfSectorsToRead;
RegsIn.b.ch = (PhysicalTrack & 0xFF);
RegsIn.b.cl = (PhysicalSector + ((PhysicalTrack & 0x300) >> 2));
RegsIn.b.dh = PhysicalHead;
RegsIn.b.dl = DriveNumber;
RegsIn.w.es = ((U32)Buffer) >> 4;
RegsIn.w.bx = ((U32)Buffer) & 0x0F;
//
// Perform the read
// Retry 3 times
//
for (RetryCount=0; RetryCount<3; RetryCount++)
{
Int386(0x13, &RegsIn, &RegsOut);
// If it worked break out
if (INT386_SUCCESS(RegsOut))
{
break;
}
// 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
else
{
PcDiskResetController(DriveNumber);
continue;
}
}
// If we retried 3 times then fail
if (RetryCount >= 3)
{
DiskError("Disk Read Failed", RegsOut.b.ah);
return FALSE;
}
// 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
// on the carry flag being set on error
Buffer += (NumberOfSectorsToRead * DriveGeometry.BytesPerSector);
SectorCount -= NumberOfSectorsToRead;
SectorNumber += NumberOfSectorsToRead;
}
return TRUE;
}
static BOOL PcDiskInt13ExtensionsSupported(U32 DriveNumber)
{
REGS RegsIn;
REGS RegsOut;
DbgPrint((DPRINT_DISK, "PcDiskInt13ExtensionsSupported()\n"));
// 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)
return FALSE;
}
if (RegsOut.w.bx != 0xAA55)
{
// BX = AA55h if installed
return FALSE;
}
// Note:
// The original check is too strict because some BIOSes report that
// extended disk access functions are not suported when booting
// from a CD (e.g. Phoenix BIOS v6.00PG). Argh!
#if 0
if (!(RegsOut.w.cx & 0x0001))
{
// CX = API subset support bitmap
// Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
return FALSE;
}
#endif
// Use this relaxed check instead
if (RegsOut.w.cx == 0x0000)
{
// CX = API subset support bitmap
return FALSE;
}
return TRUE;
}
BOOL PcDiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
{
DbgPrint((DPRINT_DISK, "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
//
if ((DriveNumber >= 0x80) && PcDiskInt13ExtensionsSupported(DriveNumber))
{
DbgPrint((DPRINT_DISK, "Using Int 13 Extensions for read. PcDiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, PcDiskInt13ExtensionsSupported(DriveNumber) ? "TRUE" : "FALSE"));
//
// 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
return PcDiskReadLogicalSectorsCHS(DriveNumber, SectorNumber, SectorCount, Buffer);
}
return TRUE;
}

View file

@ -0,0 +1,398 @@
/* $Id: xboxdisk.c,v 1.1 2004/11/09 23:36:19 gvg Exp $
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Note: mostly ripped from atapi.c
*
*/
#include "freeldr.h"
#include "debug.h"
#include "hardware.h"
#include "machxbox.h"
#include "portio.h"
#include "rtl.h"
#define XBOX_IDE_COMMAND_PORT 0x1f0
#define XBOX_IDE_CONTROL_PORT 0x170
#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
#define IDE_REG_DEV_CNTRL 0x0000 /* device control register */
#define IDE_DC_SRST 0x04 /* drive reset (both drives) */
#define IDE_DC_nIEN 0x02 /* IRQ enable (active low) */
#define IDE_REG_DRV_ADDR 0x0001
/* Command Block offsets and masks */
#define IDE_REG_DATA_PORT 0x0000
#define IDE_REG_ERROR 0x0001 /* error register */
#define IDE_ER_AMNF 0x01 /* addr mark not found */
#define IDE_ER_TK0NF 0x02 /* track 0 not found */
#define IDE_ER_ABRT 0x04 /* command aborted */
#define IDE_ER_MCR 0x08 /* media change requested */
#define IDE_ER_IDNF 0x10 /* ID not found */
#define IDE_ER_MC 0x20 /* Media changed */
#define IDE_ER_UNC 0x40 /* Uncorrectable data error */
#define IDE_REG_PRECOMP 0x0001
#define IDE_REG_SECTOR_CNT 0x0002
#define IDE_REG_SECTOR_NUM 0x0003
#define IDE_REG_CYL_LOW 0x0004
#define IDE_REG_CYL_HIGH 0x0005
#define IDE_REG_DRV_HEAD 0x0006
#define IDE_DH_FIXED 0xA0
#define IDE_DH_LBA 0x40
#define IDE_DH_HDMASK 0x0F
#define IDE_DH_DRV0 0x00
#define IDE_DH_DRV1 0x10
#define IDE_REG_STATUS 0x0007
#define IDE_SR_BUSY 0x80
#define IDE_SR_DRDY 0x40
#define IDE_SR_WERR 0x20
#define IDE_SR_DRQ 0x08
#define IDE_SR_ERR 0x01
#define IDE_REG_COMMAND 0x0007
/* IDE/ATA commands */
#define IDE_CMD_RESET 0x08
#define IDE_CMD_READ 0x20
#define IDE_CMD_READ_RETRY 0x21
#define IDE_CMD_WRITE 0x30
#define IDE_CMD_WRITE_RETRY 0x31
#define IDE_CMD_PACKET 0xA0
#define IDE_CMD_READ_MULTIPLE 0xC4
#define IDE_CMD_WRITE_MULTIPLE 0xC5
#define IDE_CMD_READ_DMA 0xC8
#define IDE_CMD_WRITE_DMA 0xCA
#define IDE_CMD_FLUSH_CACHE 0xE7
#define IDE_CMD_FLUSH_CACHE_EXT 0xEA
#define IDE_CMD_IDENT_ATA_DRV 0xEC
#define IDE_CMD_IDENT_ATAPI_DRV 0xA1
#define IDE_CMD_GET_MEDIA_STATUS 0xDA
/*
* Access macros for command registers
* Each macro takes an address of the command port block, and data
*/
#define IDEReadError(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ERROR)))
#define IDEWritePrecomp(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_PRECOMP), (Data)))
#define IDEReadSectorCount(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT)))
#define IDEWriteSectorCount(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT), (Data)))
#define IDEReadSectorNum(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM)))
#define IDEWriteSectorNum(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM), (Data)))
#define IDEReadCylinderLow(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW)))
#define IDEWriteCylinderLow(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW), (Data)))
#define IDEReadCylinderHigh(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH)))
#define IDEWriteCylinderHigh(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH), (Data)))
#define IDEReadDriveHead(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD)))
#define IDEWriteDriveHead(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD), (Data)))
#define IDEReadStatus(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_STATUS)))
#define IDEWriteCommand(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_COMMAND), (Data)))
#define IDEReadDMACommand(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address))))
#define IDEWriteDMACommand(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address)), (Data)))
#define IDEReadDMAStatus(Address) \
(READ_PORT_UCHAR((PUCHAR)((Address) + 2)))
#define IDEWriteDMAStatus(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + 2), (Data)))
#define IDEWritePRDTable(Address, Data) \
(WRITE_PORT_ULONG((PULONG)((Address) + 4), (Data)))
/*
* Data block read and write commands
*/
#define IDEReadBlock(Address, Buffer, Count) \
(READ_PORT_BUFFER_USHORT((PU16)((Address) + IDE_REG_DATA_PORT), (PU16)(Buffer), (Count) / 2))
#define IDEWriteBlock(Address, Buffer, Count) \
(WRITE_PORT_BUFFER_USHORT((PU16)((Address) + IDE_REG_DATA_PORT), (PU16)(Buffer), (Count) / 2))
#define IDEReadBlock32(Address, Buffer, Count) \
(READ_PORT_BUFFER_ULONG((PU32)((Address) + IDE_REG_DATA_PORT), (PU32)(Buffer), (Count) / 4))
#define IDEWriteBlock32(Address, Buffer, Count) \
(WRITE_PORT_BUFFER_ULONG((PU32)((Address) + IDE_REG_DATA_PORT), (PU32)(Buffer), (Count) / 4))
#define IDEReadWord(Address) \
(READ_PORT_USHORT((PU16)((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)))
#define IDEWriteDriveControl(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data)))
/* XboxDiskPolledRead
*
* DESCRIPTION:
* Read a sector of data from the drive in a polled fashion.
*
* RUN LEVEL:
* PASSIVE_LEVEL
*
* ARGUMENTS:
* U32 CommandPort Address of command port for drive
* U32 ControlPort Address of control port for drive
* U8 PreComp Value to write to precomp register
* U8 SectorCnt Value to write to sectorCnt register
* U8 SectorNum Value to write to sectorNum register
* U8 CylinderLow Value to write to CylinderLow register
* U8 CylinderHigh Value to write to CylinderHigh register
* U8 DrvHead Value to write to Drive/Head register
* U8 Command Value to write to Command register
* PVOID Buffer Buffer for output data
*
* RETURNS:
* BOOL: TRUE success, FALSE error
*/
static BOOL
XboxDiskPolledRead(U32 CommandPort,
U32 ControlPort,
U8 PreComp,
U8 SectorCnt,
U8 SectorNum,
U8 CylinderLow,
U8 CylinderHigh,
U8 DrvHead,
U8 Command,
PVOID Buffer)
{
U32 SectorCount = 0;
U32 RetryCount;
BOOL Junk = FALSE;
U8 Status;
/* Wait for BUSY to clear */
for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
{
Status = IDEReadStatus(CommandPort);
if (!(Status & IDE_SR_BUSY))
{
break;
}
KeStallExecutionProcessor(10);
}
DbgPrint((DPRINT_DISK, "status=0x%x\n", Status));
DbgPrint((DPRINT_DISK, "waited %d usecs for busy to clear\n", RetryCount * 10));
if (RetryCount >= IDE_MAX_BUSY_RETRIES)
{
DbgPrint((DPRINT_DISK, "Drive is BUSY for too long\n"));
return FALSE;
}
/* Write Drive/Head to select drive */
IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
KeStallExecutionProcessor(500);
/* Disable interrupts */
IDEWriteDriveControl(ControlPort, IDE_DC_nIEN);
KeStallExecutionProcessor(500);
/* Issue command to drive */
if (DrvHead & IDE_DH_LBA)
{
DbgPrint((DPRINT_DISK, "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
{
DbgPrint((DPRINT_DISK, "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);
KeStallExecutionProcessor(50);
/* wait for DRQ or error */
for (RetryCount = 0; RetryCount < IDE_MAX_POLL_RETRIES; RetryCount++)
{
Status = IDEReadStatus(CommandPort);
if (!(Status & IDE_SR_BUSY))
{
if (Status & IDE_SR_ERR)
{
IDEWriteDriveControl(ControlPort, 0);
KeStallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
if (Status & IDE_SR_DRQ)
{
break;
}
else
{
IDEWriteDriveControl(ControlPort, 0);
KeStallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
}
KeStallExecutionProcessor(10);
}
/* timed out */
if (RetryCount >= IDE_MAX_POLL_RETRIES)
{
IDEWriteDriveControl(ControlPort, 0);
KeStallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
while (1)
{
/* Read data into buffer */
if (Junk == FALSE)
{
IDEReadBlock(CommandPort, Buffer, IDE_SECTOR_BUF_SZ);
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);
KeStallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
if (Status & IDE_SR_DRQ)
{
if (SectorCount >= SectorCnt)
{
DbgPrint((DPRINT_DISK, "Buffer size exceeded!\n"));
Junk = TRUE;
}
break;
}
else
{
if (SectorCount > SectorCnt)
{
DbgPrint((DPRINT_DISK, "Read %lu sectors of junk!\n",
SectorCount - SectorCnt));
}
IDEWriteDriveControl(ControlPort, 0);
KeStallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return TRUE;
}
}
}
}
}
BOOL
XboxDiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
{
U32 StartSector;
U8 Count;
if (DriveNumber < 0x80 || 2 <= (DriveNumber & 0x0f))
{
/* Xbox has only 1 IDE controller and no floppy */
DbgPrint((DPRINT_DISK, "Invalid drive number\n"));
return FALSE;
}
if (UINT64_C(0) != ((SectorNumber + SectorCount) & UINT64_C(0xfffffffff0000000)))
{
DbgPrint((DPRINT_DISK, "48bit LBA required but not implemented\n"));
return FALSE;
}
StartSector = (U32) SectorNumber;
while (0 < SectorCount)
{
Count = (SectorCount <= 255 ? 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;
}
SectorCount -= Count;
Buffer = (PVOID) ((PCHAR) Buffer + Count * IDE_SECTOR_BUF_SZ);
}
return TRUE;
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: xboxmem.c,v 1.1 2004/11/08 22:02:47 gvg Exp $
/* $Id: xboxmem.c,v 1.2 2004/11/09 23:36:19 gvg Exp $
*
* FreeLoader
*
@ -108,18 +108,6 @@ XboxMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize)
return EntryCount;
}
unsigned
XboxMemGetInstalledMemoryMb(VOID)
{
if (0 == InstalledMemoryMb)
{
/* Hmm, seems we're not initialized yet */
XboxMemInit();
}
return InstalledMemoryMb;
}
PVOID
XboxMemReserveMemory(U32 MbToReserve)
{

View file

@ -25,6 +25,7 @@
#include <rtl.h>
#include <debug.h>
#include <arch.h>
#include <machine.h>
// Returns a pointer to a CACHE_BLOCK structure
// Adds the block to the cache manager block list
@ -122,7 +123,7 @@ PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, U32 BlockNumb
}
// Now try to read in the block
if (!DiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, (PVOID)DISKREADBUFFER))
if (!MachDiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, (PVOID)DISKREADBUFFER))
{
MmFreeMemory(CacheBlock->BlockData);
MmFreeMemory(CacheBlock);

View file

@ -76,7 +76,6 @@ VOID DebugInit(VOID)
VOID DebugPrintChar(UCHAR Character)
{
extern VOID XboxVideoPutChar(char c);
if (Character == '\n')
{
DebugStartOfLine = TRUE;

View file

@ -23,6 +23,7 @@
#include <mm.h>
#include <debug.h>
#include <arch.h>
#include <machine.h>
BOOL DiskGetActivePartitionEntry(U32 DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
@ -201,7 +202,7 @@ BOOL DiskReadBootRecord(U32 DriveNumber, U64 LogicalSectorNumber, PMASTER_BOOT_R
#endif
// Read master boot record
if (!DiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, (PVOID)DISKREADBUFFER))
if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, (PVOID)DISKREADBUFFER))
{
return FALSE;
}

View file

@ -27,6 +27,7 @@
#include <mm.h>
#include <debug.h>
#include <cache.h>
#include <machine.h>
GEOMETRY Ext2DiskGeometry; // Ext2 file system disk geometry
@ -563,7 +564,7 @@ BOOL Ext2ReadVolumeSectors(U8 DriveNumber, U64 SectorNumber, U64 SectorCount, PV
//{
// return FALSE;
//}
//ReturnValue = DiskReadLogicalSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, (PVOID)DISKREADBUFFER);
//ReturnValue = MachDiskReadLogicalSectors(DriveNumber, SectorNumber + Ext2VolumeStartSector, SectorCount, (PVOID)DISKREADBUFFER);
//RtlCopyMemory(Buffer, (PVOID)DISKREADBUFFER, SectorCount * DiskGeometry.BytesPerSector);
//return ReturnValue;
@ -601,7 +602,7 @@ BOOL Ext2ReadSuperBlock(VOID)
// Now try to read the super block
// If this fails then abort
if (!DiskReadLogicalSectors(Ext2DriveNumber, Ext2VolumeStartSector, 8, (PVOID)DISKREADBUFFER))
if (!MachDiskReadLogicalSectors(Ext2DriveNumber, Ext2VolumeStartSector, 8, (PVOID)DISKREADBUFFER))
{
return FALSE;
}

View file

@ -27,6 +27,7 @@
#include <mm.h>
#include <debug.h>
#include <cache.h>
#include <machine.h>
PFAT_BOOTSECTOR FatVolumeBootSector = NULL;
@ -76,7 +77,7 @@ BOOL FatOpenVolume(U32 DriveNumber, U32 VolumeStartSector)
// Now try to read the boot sector
// If this fails then abort
if (!DiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, (PVOID)DISKREADBUFFER))
if (!MachDiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, (PVOID)DISKREADBUFFER))
{
return FALSE;
}
@ -1206,7 +1207,7 @@ BOOL FatReadVolumeSectors(U32 DriveNumber, U32 SectorNumber, U32 SectorCount, PV
//{
// return FALSE;
//}
//ReturnValue = DiskReadLogicalSectors(DriveNumber, SectorNumber + FatVolumeBootSector->HiddenSectors, SectorCount, (PVOID)DISKREADBUFFER);
//ReturnValue = MachDiskReadLogicalSectors(DriveNumber, SectorNumber + FatVolumeBootSector->HiddenSectors, SectorCount, (PVOID)DISKREADBUFFER);
//RtlCopyMemory(Buffer, (PVOID)DISKREADBUFFER, SectorCount * DiskGeometry.BytesPerSector);
//return ReturnValue;

View file

@ -28,6 +28,7 @@
#include <rtl.h>
#include <arch.h>
#include <debug.h>
#include <machine.h>
@ -69,7 +70,7 @@ BOOL FsRecIsIso9660(U32 DriveNumber)
{
PUCHAR Sector = (PUCHAR)DISKREADBUFFER;
if (!DiskReadLogicalSectors(DriveNumber, 16, 1, Sector))
if (!MachDiskReadLogicalSectors(DriveNumber, 16, 1, Sector))
{
FileSystemError("Failed to read the PVD.");
return FALSE;
@ -87,7 +88,7 @@ BOOL FsRecIsExt2(U32 DriveNumber, U32 VolumeStartSector)
{
PEXT2_SUPER_BLOCK SuperBlock = (PEXT2_SUPER_BLOCK)DISKREADBUFFER;
if (!DiskReadLogicalSectors(DriveNumber, VolumeStartSector + 2, 2, SuperBlock))
if (!MachDiskReadLogicalSectors(DriveNumber, VolumeStartSector + 2, 2, SuperBlock))
{
FileSystemError("Failed to read the super block.");
return FALSE;
@ -105,7 +106,7 @@ BOOL FsRecIsFat(U32 DriveNumber, U32 VolumeStartSector)
{
PFAT_BOOTSECTOR BootSector = (PFAT_BOOTSECTOR)DISKREADBUFFER;
PFAT32_BOOTSECTOR BootSector32 = (PFAT32_BOOTSECTOR)DISKREADBUFFER;
if (!DiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, BootSector))
if (!MachDiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, BootSector))
{
FileSystemError("Failed to read the boot sector.");
return FALSE;
@ -124,7 +125,7 @@ BOOL FsRecIsFat(U32 DriveNumber, U32 VolumeStartSector)
BOOL FsRecIsNtfs(U32 DriveNumber, U32 VolumeStartSector)
{
PNTFS_BOOTSECTOR BootSector = (PNTFS_BOOTSECTOR)DISKREADBUFFER;
if (!DiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, BootSector))
if (!MachDiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, BootSector))
{
FileSystemError("Failed to read the boot sector.");
return FALSE;

View file

@ -25,6 +25,7 @@
#include <mm.h>
#include <debug.h>
#include <cache.h>
#include <machine.h>
#include "iso.h"
@ -49,7 +50,7 @@ BOOL IsoOpenVolume(U32 DriveNumber)
IsoRootSector = 0;
IsoRootLength = 0;
if (!DiskReadLogicalSectors(DriveNumber, 16, 1, Pvd))
if (!MachDiskReadLogicalSectors(DriveNumber, 16, 1, Pvd))
{
FileSystemError("Failed to read the PVD.");
return FALSE;
@ -160,7 +161,7 @@ static PVOID IsoBufferDirectory(U32 DirectoryStartSector, U32 DirectoryLength)
//
for (i = 0, Ptr = DirectoryBuffer; i < SectorCount; i++, Ptr += SECTORSIZE)
{
if (!DiskReadLogicalSectors(IsoDriveNumber, DirectoryStartSector + i, 1, (PVOID)DISKREADBUFFER))
if (!MachDiskReadLogicalSectors(IsoDriveNumber, DirectoryStartSector + i, 1, (PVOID)DISKREADBUFFER))
{
MmFreeMemory(DirectoryBuffer);
return NULL;
@ -372,7 +373,7 @@ BOOL IsoReadFile(FILE *FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer
//
// Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
//
if (!DiskReadLogicalSectors(IsoDriveNumber, SectorNumber, 1, (PVOID)DISKREADBUFFER))
if (!MachDiskReadLogicalSectors(IsoDriveNumber, SectorNumber, 1, (PVOID)DISKREADBUFFER))
{
return FALSE;
}
@ -403,7 +404,7 @@ BOOL IsoReadFile(FILE *FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer
//
// Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
//
if (!DiskReadLogicalSectorsLBA(IsoDriveNumber, SectorNumber, 1, (PVOID)DISKREADBUFFER))
if (!MachDiskReadLogicalSectors(IsoDriveNumber, SectorNumber, 1, (PVOID)DISKREADBUFFER))
{
return FALSE;
}
@ -430,7 +431,7 @@ BOOL IsoReadFile(FILE *FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer
//
// Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
//
if (!DiskReadLogicalSectorsLBA(IsoDriveNumber, SectorNumber, 1, (PVOID)DISKREADBUFFER))
if (!MachDiskReadLogicalSectors(IsoDriveNumber, SectorNumber, 1, (PVOID)DISKREADBUFFER))
{
return FALSE;
}

View file

@ -32,6 +32,7 @@
#include <mm.h>
#include <debug.h>
#include <cache.h>
#include <machine.h>
#include "ntfs.h"
@ -157,7 +158,7 @@ BOOL NtfsDiskRead(U64 Offset, U64 Length, PCHAR Buffer)
/* I. Read partial first sector if needed */
if (Offset % NtfsBootSector->BytesPerSector)
{
if (!DiskReadLogicalSectors(NtfsDriveNumber, NtfsSectorOfClusterZero + (Offset / NtfsBootSector->BytesPerSector), 1, (PCHAR)DISKREADBUFFER))
if (!MachDiskReadLogicalSectors(NtfsDriveNumber, NtfsSectorOfClusterZero + (Offset / NtfsBootSector->BytesPerSector), 1, (PCHAR)DISKREADBUFFER))
return FALSE;
ReadLength = min(Length, NtfsBootSector->BytesPerSector - (Offset % NtfsBootSector->BytesPerSector));
RtlCopyMemory(Buffer, (PCHAR)DISKREADBUFFER + (Offset % NtfsBootSector->BytesPerSector), ReadLength);
@ -169,7 +170,7 @@ BOOL NtfsDiskRead(U64 Offset, U64 Length, PCHAR Buffer)
/* II. Read all complete 64-sector blocks. */
while (Length >= 64 * NtfsBootSector->BytesPerSector)
{
if (!DiskReadLogicalSectors(NtfsDriveNumber, NtfsSectorOfClusterZero + (Offset / NtfsBootSector->BytesPerSector), 64, (PCHAR)DISKREADBUFFER))
if (!MachDiskReadLogicalSectors(NtfsDriveNumber, NtfsSectorOfClusterZero + (Offset / NtfsBootSector->BytesPerSector), 64, (PCHAR)DISKREADBUFFER))
return FALSE;
RtlCopyMemory(Buffer, (PCHAR)DISKREADBUFFER, 64 * NtfsBootSector->BytesPerSector);
Buffer += 64 * NtfsBootSector->BytesPerSector;
@ -181,7 +182,7 @@ BOOL NtfsDiskRead(U64 Offset, U64 Length, PCHAR Buffer)
if (Length)
{
ReadLength = ((Length + NtfsBootSector->BytesPerSector - 1) / NtfsBootSector->BytesPerSector);
if (!DiskReadLogicalSectors(NtfsDriveNumber, NtfsSectorOfClusterZero + (Offset / NtfsBootSector->BytesPerSector), ReadLength, (PCHAR)DISKREADBUFFER))
if (!MachDiskReadLogicalSectors(NtfsDriveNumber, NtfsSectorOfClusterZero + (Offset / NtfsBootSector->BytesPerSector), ReadLength, (PCHAR)DISKREADBUFFER))
return FALSE;
RtlCopyMemory(Buffer, (PCHAR)DISKREADBUFFER, Length);
}
@ -611,7 +612,7 @@ BOOL NtfsOpenVolume(U32 DriveNumber, U32 VolumeStartSector)
DbgPrint((DPRINT_FILESYSTEM, "NtfsOpenVolume() DriveNumber = 0x%x VolumeStartSector = 0x%x\n", DriveNumber, VolumeStartSector));
if (!DiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, (PCHAR)DISKREADBUFFER))
if (!MachDiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, (PCHAR)DISKREADBUFFER))
{
FileSystemError("Failed to read the boot sector.");
return FALSE;
@ -651,7 +652,7 @@ BOOL NtfsOpenVolume(U32 DriveNumber, U32 VolumeStartSector)
NtfsSectorOfClusterZero = VolumeStartSector;
DbgPrint((DPRINT_FILESYSTEM, "Reading MFT index...\n"));
if (!DiskReadLogicalSectors(DriveNumber,
if (!MachDiskReadLogicalSectors(DriveNumber,
NtfsSectorOfClusterZero +
(NtfsBootSector->MftLocation * NtfsBootSector->SectorsPerCluster),
NtfsMftRecordSize / NtfsBootSector->BytesPerSector, (PCHAR)DISKREADBUFFER))

View file

@ -106,9 +106,6 @@ typedef struct _MASTER_BOOT_RECORD
///////////////////////////////////////////////////////////////////////////////////////
#ifdef __i386__
//BOOL DiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer);
BOOL DiskReadLogicalSectorsLBA(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer);
BOOL DiskReadLogicalSectorsCHS(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer);
BOOL DiskResetController(U32 DriveNumber);
BOOL DiskInt13ExtensionsSupported(U32 DriveNumber);
//VOID DiskStopFloppyMotor(VOID);

View file

@ -1,4 +1,4 @@
/* $Id: machine.h,v 1.1 2004/11/08 22:02:48 gvg Exp $
/* $Id: machine.h,v 1.2 2004/11/09 23:36:20 gvg Exp $
*
* FreeLoader
*
@ -31,6 +31,8 @@ typedef struct tagMACHVTBL
VOID (*PutCharAttrAtLoc)(int Ch, U8 Attr, unsigned X, unsigned Y);
U32 (*GetMemoryMap)(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize);
BOOL (*DiskReadLogicalSectors)(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer);
} MACHVTBL, *PMACHVTBL;
VOID MachInit(VOID);
@ -41,6 +43,7 @@ extern MACHVTBL MachVtbl;
#define MachPutChar(Ch) MachVtbl.PutChar(Ch)
#define MachPutCharAttrAtLoc(Ch, Attr, X, Y) MachVtbl.PutCharAttrAtLoc((Ch), (Attr), (X), (Y))
#define MachGetMemoryMap(MMap, Size) MachVtbl.GetMemoryMap((MMap), (Size))
#define MachDiskReadLogicalSectors(Drive, Start, Count, Buf) MachVtbl.DiskReadLogicalSectors((Drive), (Start), (Count), (Buf))
#endif /* __MACHINE_H_ */

View file

@ -93,6 +93,9 @@ void sound(int freq);
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define UINT64_C(val) val##ULL
///////////////////////////////////////////////////////////////////////////////////////
//
// Screen Output Functions

View file

@ -1,4 +1,4 @@
/* $Id: machine.c,v 1.1 2004/11/08 22:02:47 gvg Exp $
/* $Id: machine.c,v 1.2 2004/11/09 23:36:19 gvg Exp $
*
* FreeLoader
*
@ -24,6 +24,7 @@
#undef MachPutChar
#undef MachPutCharAttrAtLoc
#undef MachGetMemoryMap
#undef MachDiskReadLogicalSectors
MACHVTBL MachVtbl;
@ -33,19 +34,28 @@ MachClearScreenAttr(U8 Attr)
MachVtbl.ClearScreenAttr(Attr);
}
void MachPutChar(int Ch)
void
MachPutChar(int Ch)
{
MachVtbl.PutChar(Ch);
}
void MachPutCharAttrAtLoc(int Ch, U8 Attr, unsigned X, unsigned Y)
void
MachPutCharAttrAtLoc(int Ch, U8 Attr, unsigned X, unsigned Y)
{
MachVtbl.PutCharAttrAtLoc(Ch, Attr, X, Y);
}
U32 MachGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize)
U32
MachGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize)
{
return MachVtbl.GetMemoryMap(BiosMemoryMap, MaxMemoryMapSize);
}
BOOL
MachDiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
{
return MachVtbl.DiskReadLogicalSectors(DriveNumber, SectorNumber, SectorCount, Buffer);
}
/* EOF */

View file

@ -27,6 +27,7 @@
#include <inifile.h>
#include <disk.h>
#include <drivemap.h>
#include <machine.h>
VOID LoadAndBootBootSector(PUCHAR OperatingSystemName)
{
@ -152,7 +153,7 @@ VOID LoadAndBootPartition(PUCHAR OperatingSystemName)
// Now try to read the partition boot sector
// If this fails then abort
if (!DiskReadLogicalSectors(BootDrive, PartitionTableEntry.SectorCountBeforePartition, 1, (PVOID)0x7C00))
if (!MachDiskReadLogicalSectors(BootDrive, PartitionTableEntry.SectorCountBeforePartition, 1, (PVOID)0x7C00))
{
return;
}
@ -204,7 +205,7 @@ VOID LoadAndBootDrive(PUCHAR OperatingSystemName)
// Now try to read the boot sector (or mbr)
// If this fails then abort
if (!DiskReadLogicalSectors(BootDrive, 0, 1, (PVOID)0x7C00))
if (!MachDiskReadLogicalSectors(BootDrive, 0, 1, (PVOID)0x7C00))
{
return;
}