* 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.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Note: mostly ripped from atapi.c
* Some of this code was based on knowledge and/or code developed
*
*/
-#include "freeldr.h"
-#include "debug.h"
-#include "hardware.h"
-#include "machine.h"
-#include "machxbox.h"
-#include "portio.h"
-#include "rtl.h"
+#include <freeldr.h>
+
+#define NDEBUG
+#include <debug.h>
#define XBOX_IDE_COMMAND_PORT 0x1f0
#define XBOX_IDE_CONTROL_PORT 0x170
static struct
{
- U32 SectorCountBeforePartition;
- U32 PartitionSectorCount;
- U8 SystemIndicator;
+ ULONG SectorCountBeforePartition;
+ ULONG PartitionSectorCount;
+ UCHAR SystemIndicator;
} XboxPartitions[] =
{
/* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */
#define IDEWriteDMAStatus(Address, Data) \
(WRITE_PORT_UCHAR((PUCHAR)((Address) + 2), (Data)))
#define IDEWritePRDTable(Address, Data) \
- (WRITE_PORT_ULONG((PULONG)((Address) + 4), (Data)))
+ (WRITE_PORT_ULONG((PULONG)((Address) + 4), (Data)))
/*
* Data block read and write commands
*/
#define IDEReadBlock(Address, Buffer, Count) \
- (READ_PORT_BUFFER_USHORT((PU16)((Address) + IDE_REG_DATA_PORT), (PU16)(Buffer), (Count) / 2))
+ (__inwordstring(((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
#define IDEWriteBlock(Address, Buffer, Count) \
- (WRITE_PORT_BUFFER_USHORT((PU16)((Address) + IDE_REG_DATA_PORT), (PU16)(Buffer), (Count) / 2))
+ (WRITE_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
#define IDEReadBlock32(Address, Buffer, Count) \
- (READ_PORT_BUFFER_ULONG((PU32)((Address) + IDE_REG_DATA_PORT), (PU32)(Buffer), (Count) / 4))
+ (READ_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
#define IDEWriteBlock32(Address, Buffer, Count) \
- (WRITE_PORT_BUFFER_ULONG((PU32)((Address) + IDE_REG_DATA_PORT), (PU32)(Buffer), (Count) / 4))
+ (WRITE_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
#define IDEReadWord(Address) \
- (READ_PORT_USHORT((PU16)((Address) + IDE_REG_DATA_PORT)))
+ (READ_PORT_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT)))
/*
* Access macros for control registers
typedef struct _IDE_DRIVE_IDENTIFY
{
- U16 ConfigBits; /*00*/
- U16 LogicalCyls; /*01*/
- U16 Reserved02; /*02*/
- U16 LogicalHeads; /*03*/
- U16 BytesPerTrack; /*04*/
- U16 BytesPerSector; /*05*/
- U16 SectorsPerTrack; /*06*/
- U8 InterSectorGap; /*07*/
- U8 InterSectorGapSize;
- U8 Reserved08H; /*08*/
- U8 BytesInPLO;
- U16 VendorUniqueCnt; /*09*/
+ USHORT ConfigBits; /*00*/
+ USHORT LogicalCyls; /*01*/
+ USHORT Reserved02; /*02*/
+ USHORT LogicalHeads; /*03*/
+ USHORT BytesPerTrack; /*04*/
+ USHORT BytesPerSector; /*05*/
+ USHORT SectorsPerTrack; /*06*/
+ UCHAR InterSectorGap; /*07*/
+ UCHAR InterSectorGapSize;
+ UCHAR Reserved08H; /*08*/
+ UCHAR BytesInPLO;
+ USHORT VendorUniqueCnt; /*09*/
char SerialNumber[20]; /*10*/
- U16 ControllerType; /*20*/
- U16 BufferSize; /*21*/
- U16 ECCByteCnt; /*22*/
+ USHORT ControllerType; /*20*/
+ USHORT BufferSize; /*21*/
+ USHORT ECCByteCnt; /*22*/
char FirmwareRev[8]; /*23*/
char ModelNumber[40]; /*27*/
- U16 RWMultImplemented; /*47*/
- U16 DWordIo; /*48*/
- U16 Capabilities; /*49*/
+ USHORT RWMultImplemented; /*47*/
+ USHORT DWordIo; /*48*/
+ USHORT Capabilities; /*49*/
#define IDE_DRID_STBY_SUPPORTED 0x2000
#define IDE_DRID_IORDY_SUPPORTED 0x0800
#define IDE_DRID_IORDY_DISABLE 0x0400
#define IDE_DRID_LBA_SUPPORTED 0x0200
#define IDE_DRID_DMA_SUPPORTED 0x0100
- U16 Reserved50; /*50*/
- U16 MinPIOTransTime; /*51*/
- U16 MinDMATransTime; /*52*/
- U16 TMFieldsValid; /*53*/
- U16 TMCylinders; /*54*/
- U16 TMHeads; /*55*/
- U16 TMSectorsPerTrk; /*56*/
- U16 TMCapacityLo; /*57*/
- U16 TMCapacityHi; /*58*/
- U16 RWMultCurrent; /*59*/
- U16 TMSectorCountLo; /*60*/
- U16 TMSectorCountHi; /*61*/
- U16 DmaModes; /*62*/
- U16 MultiDmaModes; /*63*/
- U16 Reserved64[5]; /*64*/
- U16 Reserved69[2]; /*69*/
- U16 Reserved71[4]; /*71*/
- U16 MaxQueueDepth; /*75*/
- U16 Reserved76[4]; /*76*/
- U16 MajorRevision; /*80*/
- U16 MinorRevision; /*81*/
- U16 SupportedFeatures82; /*82*/
- U16 SupportedFeatures83; /*83*/
- U16 SupportedFeatures84; /*84*/
- U16 EnabledFeatures85; /*85*/
- U16 EnabledFeatures86; /*86*/
- U16 EnabledFeatures87; /*87*/
- U16 UltraDmaModes; /*88*/
- U16 Reserved89[11]; /*89*/
- U16 Max48BitAddress[4]; /*100*/
- U16 Reserved104[151]; /*104*/
- U16 Checksum; /*255*/
+ USHORT Reserved50; /*50*/
+ USHORT MinPIOTransTime; /*51*/
+ USHORT MinDMATransTime; /*52*/
+ USHORT TMFieldsValid; /*53*/
+ USHORT TMCylinders; /*54*/
+ USHORT TMHeads; /*55*/
+ USHORT TMSectorsPerTrk; /*56*/
+ USHORT TMCapacityLo; /*57*/
+ USHORT TMCapacityHi; /*58*/
+ USHORT RWMultCurrent; /*59*/
+ USHORT TMSectorCountLo; /*60*/
+ USHORT TMSectorCountHi; /*61*/
+ USHORT DmaModes; /*62*/
+ USHORT MultiDmaModes; /*63*/
+ USHORT Reserved64[5]; /*64*/
+ USHORT Reserved69[2]; /*69*/
+ USHORT Reserved71[4]; /*71*/
+ USHORT MaxQueueDepth; /*75*/
+ USHORT Reserved76[4]; /*76*/
+ USHORT MajorRevision; /*80*/
+ USHORT MinorRevision; /*81*/
+ USHORT SupportedFeatures82; /*82*/
+ USHORT SupportedFeatures83; /*83*/
+ USHORT SupportedFeatures84; /*84*/
+ USHORT EnabledFeatures85; /*85*/
+ USHORT EnabledFeatures86; /*86*/
+ USHORT EnabledFeatures87; /*87*/
+ USHORT UltraDmaModes; /*88*/
+ USHORT Reserved89[11]; /*89*/
+ USHORT Max48BitAddress[4]; /*100*/
+ USHORT Reserved104[151]; /*104*/
+ USHORT Checksum; /*255*/
} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
/* XboxDiskPolledRead
* 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
+ * ULONG CommandPort Address of command port for drive
+ * ULONG ControlPort Address of control port for drive
+ * UCHAR PreComp Value to write to precomp register
+ * UCHAR SectorCnt Value to write to sectorCnt register
+ * UCHAR SectorNum Value to write to sectorNum register
+ * UCHAR CylinderLow Value to write to CylinderLow register
+ * UCHAR CylinderHigh Value to write to CylinderHigh register
+ * UCHAR DrvHead Value to write to Drive/Head register
+ * UCHAR Command Value to write to Command register
* PVOID Buffer Buffer for output data
*
* RETURNS:
- * BOOL: TRUE success, FALSE error
+ * BOOLEAN: 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,
+static BOOLEAN
+XboxDiskPolledRead(ULONG CommandPort,
+ ULONG ControlPort,
+ UCHAR PreComp,
+ UCHAR SectorCnt,
+ UCHAR SectorNum,
+ UCHAR CylinderLow,
+ UCHAR CylinderHigh,
+ UCHAR DrvHead,
+ UCHAR Command,
PVOID Buffer)
{
- U32 SectorCount = 0;
- U32 RetryCount;
- BOOL Junk = FALSE;
- U8 Status;
+ ULONG SectorCount = 0;
+ ULONG RetryCount;
+ BOOLEAN Junk = FALSE;
+ UCHAR Status;
/* Wait for BUSY to clear */
for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
{
break;
}
- KeStallExecutionProcessor(10);
+ StallExecutionProcessor(10);
}
- DbgPrint((DPRINT_DISK, "status=0x%x\n", Status));
- DbgPrint((DPRINT_DISK, "waited %d usecs for busy to clear\n", RetryCount * 10));
+ DPRINTM(DPRINT_DISK, "status=0x%x\n", Status);
+ DPRINTM(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"));
+ DPRINTM(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);
+ StallExecutionProcessor(500);
/* Disable interrupts */
IDEWriteDriveControl(ControlPort, IDE_DC_nIEN);
- KeStallExecutionProcessor(500);
+ StallExecutionProcessor(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",
+ DPRINTM(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));
+ 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",
+ DPRINTM(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));
+ Command);
}
/* Setup command parameters */
/* Issue the command */
IDEWriteCommand(CommandPort, Command);
- KeStallExecutionProcessor(50);
+ StallExecutionProcessor(50);
/* wait for DRQ or error */
for (RetryCount = 0; RetryCount < IDE_MAX_POLL_RETRIES; RetryCount++)
if (Status & IDE_SR_ERR)
{
IDEWriteDriveControl(ControlPort, 0);
- KeStallExecutionProcessor(50);
+ StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
else
{
IDEWriteDriveControl(ControlPort, 0);
- KeStallExecutionProcessor(50);
+ StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
}
}
- KeStallExecutionProcessor(10);
+ StallExecutionProcessor(10);
}
/* timed out */
if (RetryCount >= IDE_MAX_POLL_RETRIES)
{
IDEWriteDriveControl(ControlPort, 0);
- KeStallExecutionProcessor(50);
+ StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
if (Junk == FALSE)
{
IDEReadBlock(CommandPort, Buffer, IDE_SECTOR_BUF_SZ);
- Buffer += IDE_SECTOR_BUF_SZ;
+ Buffer = (PVOID)((ULONG_PTR)Buffer + IDE_SECTOR_BUF_SZ);
}
else
{
if (Status & IDE_SR_ERR)
{
IDEWriteDriveControl(ControlPort, 0);
- KeStallExecutionProcessor(50);
+ StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return FALSE;
{
if (SectorCount >= SectorCnt)
{
- DbgPrint((DPRINT_DISK, "Buffer size exceeded!\n"));
+ DPRINTM(DPRINT_DISK, "Buffer size exceeded!\n");
Junk = TRUE;
}
break;
{
if (SectorCount > SectorCnt)
{
- DbgPrint((DPRINT_DISK, "Read %lu sectors of junk!\n",
- SectorCount - SectorCnt));
+ DPRINTM(DPRINT_DISK, "Read %lu sectors of junk!\n",
+ SectorCount - SectorCnt);
}
IDEWriteDriveControl(ControlPort, 0);
- KeStallExecutionProcessor(50);
+ StallExecutionProcessor(50);
IDEReadStatus(CommandPort);
return TRUE;
}
}
-BOOL
-XboxDiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer)
+BOOLEAN
+XboxDiskReadLogicalSectors(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
- U32 StartSector;
- U8 Count;
+ ULONG StartSector;
+ UCHAR Count;
if (DriveNumber < 0x80 || 2 <= (DriveNumber & 0x0f))
{
/* Xbox has only 1 IDE controller and no floppy */
- DbgPrint((DPRINT_DISK, "Invalid drive number\n"));
+ DPRINTM(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"));
+ DPRINTM(DPRINT_DISK, "48bit LBA required but not implemented\n");
return FALSE;
}
- StartSector = (U32) SectorNumber;
+ StartSector = (ULONG) SectorNumber;
while (0 < SectorCount)
{
Count = (SectorCount <= 255 ? SectorCount : 255);
return TRUE;
}
-BOOL
-XboxDiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
+BOOLEAN
+XboxDiskGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
- U8 SectorData[IDE_SECTOR_BUF_SZ];
+ UCHAR SectorData[IDE_SECTOR_BUF_SZ];
/* This is the Xbox, chances are that there is a Xbox-standard partitionless
* disk in it so let's check that first */
if (1 <= PartitionNumber && PartitionNumber <= sizeof(XboxPartitions) / sizeof(XboxPartitions[0]) &&
MachDiskReadLogicalSectors(DriveNumber, XBOX_SIGNATURE_SECTOR, 1, SectorData))
{
- if (*((PU32) SectorData) == XBOX_SIGNATURE)
+ if (*((PULONG) SectorData) == XBOX_SIGNATURE)
{
memset(PartitionTableEntry, 0, sizeof(PARTITION_TABLE_ENTRY));
PartitionTableEntry->SystemIndicator = XboxPartitions[PartitionNumber - 1].SystemIndicator;
return DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
}
-BOOL
-XboxDiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY Geometry)
+BOOLEAN
+XboxDiskGetDriveGeometry(ULONG DriveNumber, PGEOMETRY Geometry)
{
IDE_DRIVE_IDENTIFY DrvParms;
- U32 i;
- BOOL Atapi;
+ ULONG i;
+ BOOLEAN Atapi;
Atapi = FALSE; /* FIXME */
/* Get the Drive Identify block from drive or die */
(Atapi ? IDE_CMD_IDENT_ATAPI_DRV : IDE_CMD_IDENT_ATA_DRV),
(PUCHAR) &DrvParms))
{
- DbgPrint((DPRINT_DISK, "XboxDiskPolledRead() failed\n"));
+ DPRINTM(DPRINT_DISK, "XboxDiskPolledRead() failed\n");
return FALSE;
}
}
else
{
- DbgPrint((DPRINT_DISK, "BytesPerSector %d\n", DrvParms.BytesPerSector));
+ DPRINTM(DPRINT_DISK, "BytesPerSector %d\n", DrvParms.BytesPerSector);
if (DrvParms.BytesPerSector == 0)
{
Geometry->BytesPerSector = 512;
}
else
{
- for (i = 15; i >= 0; i--)
+ for (i = 1 << 15; i; i /= 2)
{
- if (0 != (DrvParms.BytesPerSector & (1 << i)))
+ if (0 != (DrvParms.BytesPerSector & i))
{
- Geometry->BytesPerSector = 1 << i;
+ Geometry->BytesPerSector = i;
break;
}
}
}
}
- DbgPrint((DPRINT_DISK, "Cylinders %d\n", Geometry->Cylinders));
- DbgPrint((DPRINT_DISK, "Heads %d\n", Geometry->Heads));
- DbgPrint((DPRINT_DISK, "Sectors %d\n", Geometry->Sectors));
- DbgPrint((DPRINT_DISK, "BytesPerSector %d\n", Geometry->BytesPerSector));
+ DPRINTM(DPRINT_DISK, "Cylinders %d\n", Geometry->Cylinders);
+ DPRINTM(DPRINT_DISK, "Heads %d\n", Geometry->Heads);
+ DPRINTM(DPRINT_DISK, "Sectors %d\n", Geometry->Sectors);
+ DPRINTM(DPRINT_DISK, "BytesPerSector %d\n", Geometry->BytesPerSector);
return TRUE;
}
-U32
-XboxDiskGetCacheableBlockCount(U32 DriveNumber)
+ULONG
+XboxDiskGetCacheableBlockCount(ULONG DriveNumber)
{
/* 64 seems a nice number, it is used by the machpc code for LBA devices */
return 64;