diff --git a/freeldr/freeldr/Makefile b/freeldr/freeldr/Makefile index d1de3c83d0e..4b1b6a86f51 100644 --- a/freeldr/freeldr/Makefile +++ b/freeldr/freeldr/Makefile @@ -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 \ diff --git a/freeldr/freeldr/arch/i386/archmach.c b/freeldr/freeldr/arch/i386/archmach.c index ef25e1124c8..a8d858e9c87 100644 --- a/freeldr/freeldr/arch/i386/archmach.c +++ b/freeldr/freeldr/arch/i386/archmach.c @@ -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 */ diff --git a/freeldr/freeldr/arch/i386/hardware.c b/freeldr/freeldr/arch/i386/hardware.c index 5d63374b1af..80b85a38da4 100644 --- a/freeldr/freeldr/arch/i386/hardware.c +++ b/freeldr/freeldr/arch/i386/hardware.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -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", diff --git a/freeldr/freeldr/arch/i386/hardware.h b/freeldr/freeldr/arch/i386/hardware.h index a65e11862b0..40d46ead39e 100644 --- a/freeldr/freeldr/arch/i386/hardware.h +++ b/freeldr/freeldr/arch/i386/hardware.h @@ -159,6 +159,7 @@ typedef struct _CM_COMPONENT_INFORMATION /* PROTOTYPES ***************************************************************/ /* hardware.c */ +VOID HalpCalibrateStallExecution(VOID); VOID KeStallExecutionProcessor(U32 Microseconds); VOID SetComponentInformation(HKEY ComponentKey, diff --git a/freeldr/freeldr/arch/i386/i386disk.c b/freeldr/freeldr/arch/i386/i386disk.c index a47e98ef10c..a2e4b0a25fe 100644 --- a/freeldr/freeldr/arch/i386/i386disk.c +++ b/freeldr/freeldr/arch/i386/i386disk.c @@ -25,251 +25,12 @@ #include -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; diff --git a/freeldr/freeldr/arch/i386/machpc.c b/freeldr/freeldr/arch/i386/machpc.c index 24f89c607e9..3c4b8198546 100644 --- a/freeldr/freeldr/arch/i386/machpc.c +++ b/freeldr/freeldr/arch/i386/machpc.c @@ -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 */ diff --git a/freeldr/freeldr/arch/i386/machpc.h b/freeldr/freeldr/arch/i386/machpc.h index 39b1fdc8b4b..0917ab29048 100644 --- a/freeldr/freeldr/arch/i386/machpc.h +++ b/freeldr/freeldr/arch/i386/machpc.h @@ -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 */ diff --git a/freeldr/freeldr/arch/i386/machxbox.c b/freeldr/freeldr/arch/i386/machxbox.c index 698bf2e1c38..bbd585fccb1 100644 --- a/freeldr/freeldr/arch/i386/machxbox.c +++ b/freeldr/freeldr/arch/i386/machxbox.c @@ -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; } diff --git a/freeldr/freeldr/arch/i386/machxbox.h b/freeldr/freeldr/arch/i386/machxbox.h index 3eddac5e48d..40552159d56 100644 --- a/freeldr/freeldr/arch/i386/machxbox.h +++ b/freeldr/freeldr/arch/i386/machxbox.h @@ -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 */ diff --git a/freeldr/freeldr/arch/i386/pcdisk.c b/freeldr/freeldr/arch/i386/pcdisk.c new file mode 100644 index 00000000000..21c86ff628e --- /dev/null +++ b/freeldr/freeldr/arch/i386/pcdisk.c @@ -0,0 +1,365 @@ +/* + * FreeLoader + * Copyright (C) 1998-2003 Brian Palmer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + + +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; +} diff --git a/freeldr/freeldr/arch/i386/xboxdisk.c b/freeldr/freeldr/arch/i386/xboxdisk.c new file mode 100644 index 00000000000..8a290bd0851 --- /dev/null +++ b/freeldr/freeldr/arch/i386/xboxdisk.c @@ -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 */ diff --git a/freeldr/freeldr/arch/i386/xboxmem.c b/freeldr/freeldr/arch/i386/xboxmem.c index 7d4539a7f56..a2624b44c0b 100644 --- a/freeldr/freeldr/arch/i386/xboxmem.c +++ b/freeldr/freeldr/arch/i386/xboxmem.c @@ -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) { diff --git a/freeldr/freeldr/cache/blocklist.c b/freeldr/freeldr/cache/blocklist.c index 35ee9e2d5bd..29b5fdaca7f 100644 --- a/freeldr/freeldr/cache/blocklist.c +++ b/freeldr/freeldr/cache/blocklist.c @@ -25,6 +25,7 @@ #include #include #include +#include // 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); diff --git a/freeldr/freeldr/debug.c b/freeldr/freeldr/debug.c index d5021675658..88017ab79d9 100644 --- a/freeldr/freeldr/debug.c +++ b/freeldr/freeldr/debug.c @@ -76,7 +76,6 @@ VOID DebugInit(VOID) VOID DebugPrintChar(UCHAR Character) { -extern VOID XboxVideoPutChar(char c); if (Character == '\n') { DebugStartOfLine = TRUE; diff --git a/freeldr/freeldr/disk/partition.c b/freeldr/freeldr/disk/partition.c index ea20c11bd9f..01b498f0e29 100644 --- a/freeldr/freeldr/disk/partition.c +++ b/freeldr/freeldr/disk/partition.c @@ -23,6 +23,7 @@ #include #include #include +#include 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; } diff --git a/freeldr/freeldr/fs/ext2.c b/freeldr/freeldr/fs/ext2.c index 483d8c01590..d2a2758a0e8 100644 --- a/freeldr/freeldr/fs/ext2.c +++ b/freeldr/freeldr/fs/ext2.c @@ -27,6 +27,7 @@ #include #include #include +#include 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; } diff --git a/freeldr/freeldr/fs/fat.c b/freeldr/freeldr/fs/fat.c index 52edcdfbe9a..b3c130ade44 100644 --- a/freeldr/freeldr/fs/fat.c +++ b/freeldr/freeldr/fs/fat.c @@ -27,6 +27,7 @@ #include #include #include +#include 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; diff --git a/freeldr/freeldr/fs/fsrec.c b/freeldr/freeldr/fs/fsrec.c index 0de3708c7bf..affba0bc533 100644 --- a/freeldr/freeldr/fs/fsrec.c +++ b/freeldr/freeldr/fs/fsrec.c @@ -28,6 +28,7 @@ #include #include #include +#include @@ -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; diff --git a/freeldr/freeldr/fs/iso.c b/freeldr/freeldr/fs/iso.c index 073ef450d3b..54e7aa38c88 100644 --- a/freeldr/freeldr/fs/iso.c +++ b/freeldr/freeldr/fs/iso.c @@ -25,6 +25,7 @@ #include #include #include +#include #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; } diff --git a/freeldr/freeldr/fs/ntfs.c b/freeldr/freeldr/fs/ntfs.c index f02437dd281..6f6aebf86c9 100644 --- a/freeldr/freeldr/fs/ntfs.c +++ b/freeldr/freeldr/fs/ntfs.c @@ -32,6 +32,7 @@ #include #include #include +#include #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)) diff --git a/freeldr/freeldr/include/disk.h b/freeldr/freeldr/include/disk.h index 780409e22f8..cc511aa5829 100644 --- a/freeldr/freeldr/include/disk.h +++ b/freeldr/freeldr/include/disk.h @@ -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); diff --git a/freeldr/freeldr/include/machine.h b/freeldr/freeldr/include/machine.h index 5e7c9b46e8b..cbf7c84c064 100644 --- a/freeldr/freeldr/include/machine.h +++ b/freeldr/freeldr/include/machine.h @@ -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_ */ diff --git a/freeldr/freeldr/include/rtl.h b/freeldr/freeldr/include/rtl.h index ec434cbc460..4c23daf1259 100644 --- a/freeldr/freeldr/include/rtl.h +++ b/freeldr/freeldr/include/rtl.h @@ -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 diff --git a/freeldr/freeldr/machine.c b/freeldr/freeldr/machine.c index 1ab96bb2949..97a83653ad7 100644 --- a/freeldr/freeldr/machine.c +++ b/freeldr/freeldr/machine.c @@ -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 */ diff --git a/freeldr/freeldr/miscboot.c b/freeldr/freeldr/miscboot.c index 6feee0572d5..5b4828cfbc8 100644 --- a/freeldr/freeldr/miscboot.c +++ b/freeldr/freeldr/miscboot.c @@ -27,6 +27,7 @@ #include #include #include +#include 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; }