- Move the HW detection code specific to the PC architecture from hardware.c to machpc.c, keeping in hardware.c the code that is shared between PC and XBOX.
- Move what remained of i386disk.c into pcdisk.c (specific to PC architecture) + code formatting.
- Move what remained of xboxhw.c into machxbox.c (specific to XBOX architecture); we discover that some code related to disk management is actually shared with PC architecture (in hwdisk.c): hwdisk.c therefore contains disk-management routines common to both PC & XBOX.
- xboxdisk.c: Code formatting only.
- Cleanup in disk.c/disk.h
svn path=/trunk/; revision=73616
arch/i386/hwdisk.c
arch/i386/hwpci.c
arch/i386/i386bug.c
- arch/i386/i386disk.c
arch/i386/i386idt.c
arch/i386/i386rtl.c
arch/i386/i386vid.c
arch/i386/xboxcons.c
arch/i386/xboxdisk.c
arch/i386/xboxfont.c
- arch/i386/xboxhw.c
arch/i386/xboxi2c.c
arch/i386/xboxmem.c
arch/i386/xboxrtc.c
arch/i386/hwpci.c
arch/i386/i386bug.c
arch/i386/i386rtl.c
- arch/i386/i386disk.c
arch/i386/i386vid.c
arch/i386/machpc.c
arch/i386/pccons.c
*/
#include <freeldr.h>
-#include <cportlib/cportlib.h>
#define NDEBUG
#include <debug.h>
+DBG_DEFAULT_CHANNEL(HWDETECT);
+
+
#define MILLISEC (10)
#define PRECISION (8)
#define CLOCK_TICK_RATE (1193182)
#define LATCH (CLOCK_TICK_RATE / HZ)
-
-/* Maximum number of COM and LPT ports */
-#define MAX_COM_PORTS 4
-#define MAX_LPT_PORTS 3
-
-/* No Mouse */
-#define MOUSE_TYPE_NONE 0
-/* Microsoft Mouse with 2 buttons */
-#define MOUSE_TYPE_MICROSOFT 1
-/* Logitech Mouse with 3 buttons */
-#define MOUSE_TYPE_LOGITECH 2
-/* Microsoft Wheel Mouse (aka Z Mouse) */
-#define MOUSE_TYPE_WHEELZ 3
-/* Mouse Systems Mouse */
-#define MOUSE_TYPE_MOUSESYSTEMS 4
-
-
-/* PS2 stuff */
-
-/* Controller registers. */
-#define CONTROLLER_REGISTER_STATUS 0x64
-#define CONTROLLER_REGISTER_CONTROL 0x64
-#define CONTROLLER_REGISTER_DATA 0x60
-
-/* Controller commands. */
-#define CONTROLLER_COMMAND_READ_MODE 0x20
-#define CONTROLLER_COMMAND_WRITE_MODE 0x60
-#define CONTROLLER_COMMAND_GET_VERSION 0xA1
-#define CONTROLLER_COMMAND_MOUSE_DISABLE 0xA7
-#define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8
-#define CONTROLLER_COMMAND_TEST_MOUSE 0xA9
-#define CONTROLLER_COMMAND_SELF_TEST 0xAA
-#define CONTROLLER_COMMAND_KEYBOARD_TEST 0xAB
-#define CONTROLLER_COMMAND_KEYBOARD_DISABLE 0xAD
-#define CONTROLLER_COMMAND_KEYBOARD_ENABLE 0xAE
-#define CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER 0xD3
-#define CONTROLLER_COMMAND_WRITE_MOUSE 0xD4
-
-/* Controller status */
-#define CONTROLLER_STATUS_OUTPUT_BUFFER_FULL 0x01
-#define CONTROLLER_STATUS_INPUT_BUFFER_FULL 0x02
-#define CONTROLLER_STATUS_SELF_TEST 0x04
-#define CONTROLLER_STATUS_COMMAND 0x08
-#define CONTROLLER_STATUS_UNLOCKED 0x10
-#define CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL 0x20
-#define CONTROLLER_STATUS_GENERAL_TIMEOUT 0x40
-#define CONTROLLER_STATUS_PARITY_ERROR 0x80
-#define AUX_STATUS_OUTPUT_BUFFER_FULL (CONTROLLER_STATUS_OUTPUT_BUFFER_FULL | \
- CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL)
-
-/* Timeout in ms for sending to keyboard controller. */
-#define CONTROLLER_TIMEOUT 250
-
-DBG_DEFAULT_CHANNEL(HWDETECT);
-
static unsigned int delay_count = 1;
-
extern UCHAR PcBiosDiskCount;
PCHAR
UCHAR DriveNumber);
BOOLEAN
-HwInitializeBiosDisks(VOID);
-
-/* FUNCTIONS ****************************************************************/
+InitializeBiosDisks(VOID);
+/* FUNCTIONS *****************************************************************/
static
VOID
for (i = 0; i < Loops; i++);
}
-
VOID StallExecutionProcessor(ULONG Microseconds)
{
ULONGLONG LoopCount = ((ULONGLONG)delay_count * (ULONGLONG)Microseconds) / 1000ULL;
__StallExecutionProcessor((ULONG)LoopCount);
}
-
static
ULONG
Read8254Timer(VOID)
return Count;
}
-
static
VOID
WaitFor8254Wraparound(VOID)
while (Delta < 300);
}
-
VOID
HalpCalibrateStallExecution(VOID)
{
delay_count /= (MILLISEC / 2);
}
-static
-VOID
-DetectPnpBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
-{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- PCM_PNP_BIOS_DEVICE_NODE DeviceNode;
- PCM_PNP_BIOS_INSTALLATION_CHECK InstData;
- PCONFIGURATION_COMPONENT_DATA BusKey;
- ULONG x;
- ULONG NodeSize = 0;
- ULONG NodeCount = 0;
- UCHAR NodeNumber;
- ULONG FoundNodeCount;
- int i;
- ULONG PnpBufferSize;
- ULONG Size;
- char *Ptr;
-
- InstData = (PCM_PNP_BIOS_INSTALLATION_CHECK)PnpBiosSupported();
- if (InstData == NULL || strncmp((CHAR*)InstData->Signature, "$PnP", 4))
- {
- TRACE("PnP-BIOS not supported\n");
- return;
- }
-
- TRACE("PnP-BIOS supported\n");
- TRACE("Signature '%c%c%c%c'\n",
- InstData->Signature[0], InstData->Signature[1],
- InstData->Signature[2], InstData->Signature[3]);
-
- x = PnpBiosGetDeviceNodeCount(&NodeSize, &NodeCount);
- if (x == 0x82)
- {
- TRACE("PnP-BIOS function 'Get Number of System Device Nodes' not supported\n");
- return;
- }
-
- NodeCount &= 0xFF; // needed since some fscked up BIOSes return
- // wrong info (e.g. Mac Virtual PC)
- // e.g. look: http://my.execpc.com/~geezer/osd/pnp/pnp16.c
- if (x != 0 || NodeSize == 0 || NodeCount == 0)
- {
- ERR("PnP-BIOS failed to enumerate device nodes\n");
- return;
- }
- TRACE("MaxNodeSize %u NodeCount %u\n", NodeSize, NodeCount);
- TRACE("Estimated buffer size %u\n", NodeSize * NodeCount);
-
- /* Set 'Configuration Data' value */
- Size = sizeof(CM_PARTIAL_RESOURCE_LIST)
- + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK) + (NodeSize * NodeCount);
- PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
- if (PartialResourceList == NULL)
- {
- ERR("Failed to allocate resource descriptor\n");
- return;
- }
- memset(PartialResourceList, 0, Size);
-
- /* Initialize resource descriptor */
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 1;
- PartialResourceList->PartialDescriptors[0].Type =
- CmResourceTypeDeviceSpecific;
- PartialResourceList->PartialDescriptors[0].ShareDisposition =
- CmResourceShareUndetermined;
-
- /* The buffer starts after PartialResourceList->PartialDescriptors[0] */
- Ptr = (char *)(PartialResourceList + 1);
-
- /* Set installation check data */
- memcpy (Ptr, InstData, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
- Ptr += sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
-
- /* Copy device nodes */
- FoundNodeCount = 0;
- PnpBufferSize = sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
- for (i = 0; i < 0xFF; i++)
- {
- NodeNumber = (UCHAR)i;
-
- x = PnpBiosGetDeviceNode(&NodeNumber, DiskReadBuffer);
- if (x == 0)
- {
- DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DiskReadBuffer;
-
- TRACE("Node: %u Size %u (0x%x)\n",
- DeviceNode->Node,
- DeviceNode->Size,
- DeviceNode->Size);
-
- if (PnpBufferSize + DeviceNode->Size > Size)
- {
- ERR("Buffer too small!\n");
- break;
- }
-
- memcpy(Ptr, DeviceNode, DeviceNode->Size);
-
- Ptr += DeviceNode->Size;
- PnpBufferSize += DeviceNode->Size;
-
- FoundNodeCount++;
- if (FoundNodeCount >= NodeCount)
- break;
- }
- }
-
- /* Set real data size */
- PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
- PnpBufferSize;
- Size = sizeof(CM_PARTIAL_RESOURCE_LIST) + PnpBufferSize;
-
- TRACE("Real buffer size: %u\n", PnpBufferSize);
- TRACE("Resource size: %u\n", Size);
-
- /* Create component key */
- FldrCreateComponentKey(SystemKey,
- AdapterClass,
- MultiFunctionAdapter,
- 0x0,
- 0x0,
- 0xFFFFFFFF,
- "PNP BIOS",
- PartialResourceList,
- Size,
- &BusKey);
-
- (*BusNumber)++;
-}
-
-
-
-static PCM_PARTIAL_RESOURCE_LIST
-GetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
-{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
- EXTENDED_GEOMETRY ExtGeometry;
- GEOMETRY Geometry;
- ULONG Size;
-
- //
- // Initialize returned size
- //
- *pSize = 0;
-
- /* Set 'Configuration Data' value */
- Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
- sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
- PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
- if (PartialResourceList == NULL)
- {
- ERR("Failed to allocate a full resource descriptor\n");
- return NULL;
- }
-
- memset(PartialResourceList, 0, Size);
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 1;
- PartialResourceList->PartialDescriptors[0].Type =
- CmResourceTypeDeviceSpecific;
-// PartialResourceList->PartialDescriptors[0].ShareDisposition =
-// PartialResourceList->PartialDescriptors[0].Flags =
- PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
- sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
-
- /* Get pointer to geometry data */
- DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
-
- /* Get the disk geometry */
- ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
- if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
- {
- DiskGeometry->BytesPerSector = ExtGeometry.BytesPerSector;
- DiskGeometry->NumberOfCylinders = ExtGeometry.Cylinders;
- DiskGeometry->SectorsPerTrack = ExtGeometry.SectorsPerTrack;
- DiskGeometry->NumberOfHeads = ExtGeometry.Heads;
- }
- else if(MachDiskGetDriveGeometry(DriveNumber, &Geometry))
- {
- DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
- DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
- DiskGeometry->SectorsPerTrack = Geometry.Sectors;
- DiskGeometry->NumberOfHeads = Geometry.Heads;
- }
- else
- {
- TRACE("Reading disk geometry failed\n");
- FrLdrHeapFree(PartialResourceList, TAG_HW_RESOURCE_LIST);
- return NULL;
- }
- TRACE("Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
- DriveNumber,
- DiskGeometry->NumberOfCylinders,
- DiskGeometry->NumberOfHeads,
- DiskGeometry->SectorsPerTrack,
- DiskGeometry->BytesPerSector);
-
- //
- // Return configuration data
- //
- *pSize = Size;
- return PartialResourceList;
-}
static
UCHAR
return ((Data & 0xF0) ? 1 : 0) + ((Data & 0x0F) ? 1 : 0);
}
-
static
UCHAR
GetFloppyType(UCHAR DriveNumber)
return 0;
}
-
static
PVOID
GetInt1eTable(VOID)
return (PVOID)((ULONG_PTR)(((ULONG)(*SegPtr)) << 4) + (ULONG)(*OfsPtr));
}
-
static
VOID
DetectBiosFloppyPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey)
}
}
-
static
-VOID
+PCONFIGURATION_COMPONENT_DATA
DetectBiosFloppyController(PCONFIGURATION_COMPONENT_DATA BusKey)
{
PCONFIGURATION_COMPONENT_DATA ControllerKey;
ULONG FloppyCount;
FloppyCount = GetFloppyCount();
- TRACE("Floppy count: %u\n",
- FloppyCount);
+ TRACE("Floppy count: %u\n", FloppyCount);
+ /* Always create a BIOS disk controller, no matter if we have floppy drives or not */
Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
if (PartialResourceList == NULL)
{
ERR("Failed to allocate resource descriptor\n");
- return;
+ return NULL;
}
memset(PartialResourceList, 0, Size);
&ControllerKey);
TRACE("Created key: DiskController\\0\n");
- if (FloppyCount) DetectBiosFloppyPeripheral(ControllerKey);
+ if (FloppyCount)
+ DetectBiosFloppyPeripheral(ControllerKey);
+
+ return ControllerKey;
}
-static
PCONFIGURATION_COMPONENT_DATA
DetectSystem(VOID)
{
return SystemKey;
}
-static
+extern PCM_PARTIAL_RESOURCE_LIST
+PcGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize);
+
+#define GetHarddiskConfigurationData PcGetHarddiskConfigurationData
+
+// static
VOID
DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA BusKey)
{
- PCONFIGURATION_COMPONENT_DATA DiskKey, ControllerKey;
+ PCONFIGURATION_COMPONENT_DATA ControllerKey, DiskKey;
ULONG i;
- FldrCreateComponentKey(BusKey,
- ControllerClass,
- DiskController,
- Output | Input,
- 0x0,
- 0xFFFFFFFF,
- NULL,
- NULL,
- 0,
- &ControllerKey);
- TRACE("Created key: DiskController\\0\n");
+ /* Use the floppy disk controller as our controller */
+ ControllerKey = DetectBiosFloppyController(BusKey);
+ if (!ControllerKey)
+ {
+ ERR("Failed to detect BIOS disk controller\n");
+ return;
+ }
/* Create and fill subkey for each harddisk */
for (i = 0; i < PcBiosDiskCount; i++)
}
}
-static
VOID
-InitializeSerialPort(PUCHAR Port,
- UCHAR LineControl)
-{
- WRITE_PORT_UCHAR(Port + 3, 0x80); /* set DLAB on */
- WRITE_PORT_UCHAR(Port, 0x60); /* speed LO byte */
- WRITE_PORT_UCHAR(Port + 1, 0); /* speed HI byte */
- WRITE_PORT_UCHAR(Port + 3, LineControl);
- WRITE_PORT_UCHAR(Port + 1, 0); /* set comm and DLAB to 0 */
- WRITE_PORT_UCHAR(Port + 4, 0x09); /* DR int enable */
- READ_PORT_UCHAR(Port + 5); /* clear error bits */
-}
-
-
-static
-ULONG
-DetectSerialMouse(PUCHAR Port)
-{
- CHAR Buffer[4];
- ULONG i;
- ULONG TimeOut;
- UCHAR LineControl;
-
- /* Shutdown mouse or something like that */
- LineControl = READ_PORT_UCHAR(Port + 4);
- WRITE_PORT_UCHAR(Port + 4, (LineControl & ~0x02) | 0x01);
- StallExecutionProcessor(100000);
-
- /*
- * Clear buffer
- * Maybe there is no serial port although BIOS reported one (this
- * is the case on Apple hardware), or the serial port is misbehaving,
- * therefore we must give up after some time.
- */
- TimeOut = 200;
- while (READ_PORT_UCHAR(Port + 5) & 0x01)
- {
- if (--TimeOut == 0)
- return MOUSE_TYPE_NONE;
- READ_PORT_UCHAR(Port);
- }
-
- /*
- * Send modem control with 'Data Terminal Ready', 'Request To Send' and
- * 'Output Line 2' message. This enables mouse to identify.
- */
- WRITE_PORT_UCHAR(Port + 4, 0x0b);
-
- /* Wait 10 milliseconds for the mouse getting ready */
- StallExecutionProcessor(10000);
-
- /* Read first four bytes, which contains Microsoft Mouse signs */
- TimeOut = 200;
- for (i = 0; i < 4; i++)
- {
- while (((READ_PORT_UCHAR(Port + 5) & 1) == 0) && (TimeOut > 0))
- {
- StallExecutionProcessor(1000);
- --TimeOut;
- if (TimeOut == 0)
- return MOUSE_TYPE_NONE;
- }
- Buffer[i] = READ_PORT_UCHAR(Port);
- }
-
- TRACE("Mouse data: %x %x %x %x\n",
- Buffer[0], Buffer[1], Buffer[2], Buffer[3]);
-
- /* Check that four bytes for signs */
- for (i = 0; i < 4; ++i)
- {
- if (Buffer[i] == 'B')
- {
- /* Sign for Microsoft Ballpoint */
-// DbgPrint("Microsoft Ballpoint device detected\n");
-// DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
- return MOUSE_TYPE_NONE;
- }
- else if (Buffer[i] == 'M')
- {
- /* Sign for Microsoft Mouse protocol followed by button specifier */
- if (i == 3)
- {
- /* Overflow Error */
- return MOUSE_TYPE_NONE;
- }
-
- switch (Buffer[i + 1])
- {
- case '3':
- TRACE("Microsoft Mouse with 3-buttons detected\n");
- return MOUSE_TYPE_LOGITECH;
-
- case 'Z':
- TRACE("Microsoft Wheel Mouse detected\n");
- return MOUSE_TYPE_WHEELZ;
-
- /* case '2': */
- default:
- TRACE("Microsoft Mouse with 2-buttons detected\n");
- return MOUSE_TYPE_MICROSOFT;
- }
- }
- }
-
- return MOUSE_TYPE_NONE;
-}
-
-
-static ULONG
-GetSerialMousePnpId(PUCHAR Port, char *Buffer)
+FrLdrCheckCpuCompatibility(VOID)
{
- ULONG TimeOut;
- ULONG i = 0;
- char c;
- char x;
-
- WRITE_PORT_UCHAR(Port + 4, 0x09);
-
- /* Wait 10 milliseconds for the mouse getting ready */
- StallExecutionProcessor(10000);
-
- WRITE_PORT_UCHAR(Port + 4, 0x0b);
-
- StallExecutionProcessor(10000);
-
- for (;;)
- {
- TimeOut = 200;
- while (((READ_PORT_UCHAR(Port + 5) & 1) == 0) && (TimeOut > 0))
- {
- StallExecutionProcessor(1000);
- --TimeOut;
- if (TimeOut == 0)
- {
- return 0;
- }
- }
+ INT CpuInformation[4] = {-1};
+ ULONG NumberOfIds;
- c = READ_PORT_UCHAR(Port);
- if (c == 0x08 || c == 0x28)
- break;
- }
+ /* Check if the processor first supports ID 1 */
+ __cpuid(CpuInformation, 0);
- Buffer[i++] = c;
- x = c + 1;
+ NumberOfIds = CpuInformation[0];
- for (;;)
+ if (NumberOfIds == 0)
{
- TimeOut = 200;
- while (((READ_PORT_UCHAR(Port + 5) & 1) == 0) && (TimeOut > 0))
- {
- StallExecutionProcessor(1000);
- --TimeOut;
- if (TimeOut == 0)
- return 0;
- }
- c = READ_PORT_UCHAR(Port);
- Buffer[i++] = c;
- if (c == x)
- break;
- if (i >= 256)
- break;
+ FrLdrBugCheckWithMessage(MISSING_HARDWARE_REQUIREMENTS,
+ __FILE__,
+ __LINE__,
+ "ReactOS requires the CPUID instruction to return "
+ "more than one supported ID.\n\n");
}
- return i;
-}
-
-
-static
-VOID
-DetectSerialPointerPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey,
- PUCHAR Base)
-{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- char Buffer[256];
- CHAR Identifier[256];
- PCONFIGURATION_COMPONENT_DATA PeripheralKey;
- ULONG MouseType;
- ULONG Size, Length;
- ULONG i;
- ULONG j;
- ULONG k;
-
- TRACE("DetectSerialPointerPeripheral()\n");
-
- Identifier[0] = 0;
-
- InitializeSerialPort(Base, 2);
- MouseType = DetectSerialMouse(Base);
-
- if (MouseType != MOUSE_TYPE_NONE)
+ /* NumberOfIds will be greater than 1 if the processor is new enough */
+ if (NumberOfIds == 1)
{
- Length = GetSerialMousePnpId(Base, Buffer);
- TRACE( "PnP ID length: %u\n", Length);
+ INT ProcessorFamily;
- if (Length != 0)
- {
- /* Convert PnP sting to ASCII */
- if (Buffer[0] == 0x08)
- {
- for (i = 0; i < Length; i++)
- Buffer[i] += 0x20;
- }
- Buffer[Length] = 0;
-
- TRACE("PnP ID string: %s\n", Buffer);
-
- /* Copy PnpId string */
- for (i = 0; i < 7; i++)
- {
- Identifier[i] = Buffer[3 + i];
- }
- memcpy(&Identifier[7],
- L" - ",
- 3 * sizeof(WCHAR));
-
- /* Skip device serial number */
- i = 10;
- if (Buffer[i] == '\\')
- {
- for (j = ++i; i < Length; ++i)
- {
- if (Buffer[i] == '\\')
- break;
- }
- if (i >= Length)
- i -= 3;
- }
-
- /* Skip PnP class */
- if (Buffer[i] == '\\')
- {
- for (j = ++i; i < Length; ++i)
- {
- if (Buffer[i] == '\\')
- break;
- }
-
- if (i >= Length)
- i -= 3;
- }
-
- /* Skip compatible PnP Id */
- if (Buffer[i] == '\\')
- {
- for (j = ++i; i < Length; ++i)
- {
- if (Buffer[i] == '\\')
- break;
- }
- if (Buffer[j] == '*')
- ++j;
- if (i >= Length)
- i -= 3;
- }
-
- /* Get product description */
- if (Buffer[i] == '\\')
- {
- for (j = ++i; i < Length; ++i)
- {
- if (Buffer[i] == ';')
- break;
- }
- if (i >= Length)
- i -= 3;
- if (i > j + 1)
- {
- for (k = 0; k < i - j; k++)
- {
- Identifier[k + 10] = Buffer[k + j];
- }
- Identifier[10 + (i - j)] = 0;
- }
- }
-
- TRACE("Identifier string: %s\n", Identifier);
- }
+ /* Get information */
+ __cpuid(CpuInformation, 1);
- if (Length == 0 || strlen(Identifier) < 11)
- {
- switch (MouseType)
- {
- case MOUSE_TYPE_LOGITECH:
- strcpy(Identifier, "LOGITECH SERIAL MOUSE");
- break;
-
- case MOUSE_TYPE_WHEELZ:
- strcpy(Identifier, "MICROSOFT SERIAL MOUSE WITH WHEEL");
- break;
-
- case MOUSE_TYPE_MICROSOFT:
- default:
- strcpy(Identifier, "MICROSOFT SERIAL MOUSE");
- break;
- }
- }
+ ProcessorFamily = (CpuInformation[0] >> 8) & 0xF;
- /* Set 'Configuration Data' value */
- Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
- sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
- PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
- if (PartialResourceList == NULL)
+ /* If it's Family 4 or lower, bugcheck */
+ if (ProcessorFamily < 5)
{
- ERR("Failed to allocate resource descriptor\n");
- return;
+ FrLdrBugCheckWithMessage(MISSING_HARDWARE_REQUIREMENTS,
+ __FILE__,
+ __LINE__,
+ "Processor is too old (family %u < 5)\n"
+ "ReactOS requires a Pentium-level processor or newer.",
+ ProcessorFamily);
}
- memset(PartialResourceList, 0, Size);
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 0;
-
- /* Create 'PointerPeripheral' key */
- FldrCreateComponentKey(ControllerKey,
- PeripheralClass,
- PointerPeripheral,
- Input,
- 0x0,
- 0xFFFFFFFF,
- Identifier,
- PartialResourceList,
- Size,
- &PeripheralKey);
-
- TRACE("Created key: PointerPeripheral\\0\n");
}
}
-
-static
-VOID
-DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
-{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
- PCM_SERIAL_DEVICE_DATA SerialDeviceData;
- ULONG Irq[MAX_COM_PORTS] = {4, 3, 4, 3};
- ULONG Base;
- CHAR Buffer[80];
- PUSHORT BasePtr;
- ULONG ControllerNumber = 0;
- PCONFIGURATION_COMPONENT_DATA ControllerKey;
- ULONG i;
- ULONG Size;
-
- TRACE("DetectSerialPorts()\n");
-
- /*
- * The BIOS data area 0x400 holds the address of the first valid COM port.
- * Each COM port address is stored in a 2-byte field.
- * Infos at: http://www.bioscentral.com/misc/bda.htm
- */
- BasePtr = (PUSHORT)0x400;
-
- for (i = 0; i < MAX_COM_PORTS; i++, BasePtr++)
- {
- Base = (ULONG) * BasePtr;
- if (Base == 0 || !CpDoesPortExist((PUCHAR)Base))
- continue;
-
- TRACE("Found COM%u port at 0x%x\n", i + 1, Base);
-
- /* Set 'Identifier' value */
- sprintf(Buffer, "COM%ld", i + 1);
-
- /* Build full device descriptor */
- Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
- 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) +
- sizeof(CM_SERIAL_DEVICE_DATA);
- PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
- if (PartialResourceList == NULL)
- {
- ERR("Failed to allocate resource descriptor\n");
- continue;
- }
- memset(PartialResourceList, 0, Size);
-
- /* Initialize resource descriptor */
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 3;
-
- /* Set IO Port */
- PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
- PartialDescriptor->Type = CmResourceTypePort;
- PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
- PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
- PartialDescriptor->u.Port.Start.LowPart = Base;
- PartialDescriptor->u.Port.Start.HighPart = 0x0;
- PartialDescriptor->u.Port.Length = 7;
-
- /* Set Interrupt */
- PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
- PartialDescriptor->Type = CmResourceTypeInterrupt;
- PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
- PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
- PartialDescriptor->u.Interrupt.Level = Irq[i];
- PartialDescriptor->u.Interrupt.Vector = Irq[i];
- PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
-
- /* Set serial data (device specific) */
- PartialDescriptor = &PartialResourceList->PartialDescriptors[2];
- PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
- PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
- PartialDescriptor->Flags = 0;
- PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_SERIAL_DEVICE_DATA);
-
- SerialDeviceData =
- (PCM_SERIAL_DEVICE_DATA)&PartialResourceList->PartialDescriptors[3];
- SerialDeviceData->BaudClock = 1843200; /* UART Clock frequency (Hertz) */
-
- /* Create controller key */
- FldrCreateComponentKey(BusKey,
- ControllerClass,
- SerialController,
- Output | Input | ConsoleIn | ConsoleOut,
- ControllerNumber,
- 0xFFFFFFFF,
- Buffer,
- PartialResourceList,
- Size,
- &ControllerKey);
-
- if (!Rs232PortInUse(UlongToPtr(Base)))
- {
- /* Detect serial mouse */
- DetectSerialPointerPeripheral(ControllerKey, UlongToPtr(Base));
- }
-
- ControllerNumber++;
- }
-}
-
-
-static VOID
-DetectParallelPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
-{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
- ULONG Irq[MAX_LPT_PORTS] = {7, 5, (ULONG) - 1};
- CHAR Buffer[80];
- PCONFIGURATION_COMPONENT_DATA ControllerKey;
- PUSHORT BasePtr;
- ULONG Base;
- ULONG ControllerNumber = 0;
- ULONG i;
- ULONG Size;
-
- TRACE("DetectParallelPorts() called\n");
-
- /*
- * The BIOS data area 0x408 holds the address of the first valid LPT port.
- * Each LPT port address is stored in a 2-byte field.
- * Infos at: http://www.bioscentral.com/misc/bda.htm
- */
- BasePtr = (PUSHORT)0x408;
-
- for (i = 0; i < MAX_LPT_PORTS; i++, BasePtr++)
- {
- Base = (ULONG) * BasePtr;
- if (Base == 0)
- continue;
-
- TRACE("Parallel port %u: %x\n", ControllerNumber, Base);
-
- /* Set 'Identifier' value */
- sprintf(Buffer, "PARALLEL%ld", i + 1);
-
- /* Build full device descriptor */
- Size = sizeof(CM_PARTIAL_RESOURCE_LIST);
- if (Irq[i] != (ULONG) - 1)
- Size += sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
-
- PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
- if (PartialResourceList == NULL)
- {
- ERR("Failed to allocate resource descriptor\n");
- continue;
- }
- memset(PartialResourceList, 0, Size);
-
- /* Initialize resource descriptor */
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = (Irq[i] != (ULONG) - 1) ? 2 : 1;
-
- /* Set IO Port */
- PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
- PartialDescriptor->Type = CmResourceTypePort;
- PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
- PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
- PartialDescriptor->u.Port.Start.LowPart = Base;
- PartialDescriptor->u.Port.Start.HighPart = 0x0;
- PartialDescriptor->u.Port.Length = 3;
-
- /* Set Interrupt */
- if (Irq[i] != (ULONG) - 1)
- {
- PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
- PartialDescriptor->Type = CmResourceTypeInterrupt;
- PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
- PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
- PartialDescriptor->u.Interrupt.Level = Irq[i];
- PartialDescriptor->u.Interrupt.Vector = Irq[i];
- PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
- }
-
- /* Create controller key */
- FldrCreateComponentKey(BusKey,
- ControllerClass,
- ParallelController,
- Output,
- ControllerNumber,
- 0xFFFFFFFF,
- Buffer,
- PartialResourceList,
- Size,
- &ControllerKey);
-
- ControllerNumber++;
- }
-
- TRACE("DetectParallelPorts() done\n");
-}
-
-
-//static
-BOOLEAN
-DetectKeyboardDevice(VOID)
-{
- UCHAR Status;
- UCHAR Scancode;
- ULONG Loops;
- BOOLEAN Result = TRUE;
-
- /* Identify device */
- WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA, 0xF2);
-
- /* Wait for reply */
- for (Loops = 0; Loops < 100; Loops++)
- {
- StallExecutionProcessor(10000);
- Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
- if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
- break;
- }
-
- if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) == 0)
- {
- /* PC/XT keyboard or no keyboard */
- Result = FALSE;
- }
-
- Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
- if (Scancode != 0xFA)
- {
- /* No ACK received */
- Result = FALSE;
- }
-
- StallExecutionProcessor(10000);
-
- Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
- if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) == 0)
- {
- /* Found AT keyboard */
- return Result;
- }
-
- Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
- if (Scancode != 0xAB)
- {
- /* No 0xAB received */
- Result = FALSE;
- }
-
- StallExecutionProcessor(10000);
-
- Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
- if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) == 0)
- {
- /* No byte in buffer */
- Result = FALSE;
- }
-
- Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
- if (Scancode != 0x41)
- {
- /* No 0x41 received */
- Result = FALSE;
- }
-
- /* Found MF-II keyboard */
- return Result;
-}
-
-
-static VOID
-DetectKeyboardPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey)
-{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
- PCM_KEYBOARD_DEVICE_DATA KeyboardData;
- PCONFIGURATION_COMPONENT_DATA PeripheralKey;
- ULONG Size;
-
- /* HACK: don't call DetectKeyboardDevice() as it fails in Qemu 0.8.2
- if (DetectKeyboardDevice()) */
- {
- /* Set 'Configuration Data' value */
- Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
- sizeof(CM_KEYBOARD_DEVICE_DATA);
- PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
- if (PartialResourceList == NULL)
- {
- ERR("Failed to allocate resource descriptor\n");
- return;
- }
-
- /* Initialize resource descriptor */
- memset(PartialResourceList, 0, Size);
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 1;
-
- PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
- PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
- PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
- PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_KEYBOARD_DEVICE_DATA);
-
- KeyboardData = (PCM_KEYBOARD_DEVICE_DATA)(PartialDescriptor + 1);
- KeyboardData->Version = 1;
- KeyboardData->Revision = 1;
- KeyboardData->Type = 4;
- KeyboardData->Subtype = 0;
- KeyboardData->KeyboardFlags = 0x20;
-
- /* Create controller key */
- FldrCreateComponentKey(ControllerKey,
- PeripheralClass,
- KeyboardPeripheral,
- Input | ConsoleIn,
- 0x0,
- 0xFFFFFFFF,
- "PCAT_ENHANCED",
- PartialResourceList,
- Size,
- &PeripheralKey);
- TRACE("Created key: KeyboardPeripheral\\0\n");
- }
-}
-
-
-static
-VOID
-DetectKeyboardController(PCONFIGURATION_COMPONENT_DATA BusKey)
-{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
- PCONFIGURATION_COMPONENT_DATA ControllerKey;
- ULONG Size;
-
- /* Set 'Configuration Data' value */
- Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
- 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
- PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
- if (PartialResourceList == NULL)
- {
- ERR("Failed to allocate resource descriptor\n");
- return;
- }
-
- /* Initialize resource descriptor */
- memset(PartialResourceList, 0, Size);
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 3;
-
- /* Set Interrupt */
- PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
- PartialDescriptor->Type = CmResourceTypeInterrupt;
- PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
- PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
- PartialDescriptor->u.Interrupt.Level = 1;
- PartialDescriptor->u.Interrupt.Vector = 1;
- PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
-
- /* Set IO Port 0x60 */
- PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
- PartialDescriptor->Type = CmResourceTypePort;
- PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
- PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
- PartialDescriptor->u.Port.Start.LowPart = 0x60;
- PartialDescriptor->u.Port.Start.HighPart = 0x0;
- PartialDescriptor->u.Port.Length = 1;
-
- /* Set IO Port 0x64 */
- PartialDescriptor = &PartialResourceList->PartialDescriptors[2];
- PartialDescriptor->Type = CmResourceTypePort;
- PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
- PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
- PartialDescriptor->u.Port.Start.LowPart = 0x64;
- PartialDescriptor->u.Port.Start.HighPart = 0x0;
- PartialDescriptor->u.Port.Length = 1;
-
- /* Create controller key */
- FldrCreateComponentKey(BusKey,
- ControllerClass,
- KeyboardController,
- Input | ConsoleIn,
- 0x0,
- 0xFFFFFFFF,
- NULL,
- PartialResourceList,
- Size,
- &ControllerKey);
- TRACE("Created key: KeyboardController\\0\n");
-
- DetectKeyboardPeripheral(ControllerKey);
-}
-
-
-static
-VOID
-PS2ControllerWait(VOID)
-{
- ULONG Timeout;
- UCHAR Status;
-
- for (Timeout = 0; Timeout < CONTROLLER_TIMEOUT; Timeout++)
- {
- Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
- if ((Status & CONTROLLER_STATUS_INPUT_BUFFER_FULL) == 0)
- return;
-
- /* Sleep for one millisecond */
- StallExecutionProcessor(1000);
- }
-}
-
-
-static
-BOOLEAN
-DetectPS2AuxPort(VOID)
-{
-#if 1
- /* Current detection is too unreliable. Just do as if
- * the PS/2 aux port is always present
- */
- return TRUE;
-#else
- ULONG Loops;
- UCHAR Status;
-
- /* Put the value 0x5A in the output buffer using the
- * "WriteAuxiliary Device Output Buffer" command (0xD3).
- * Poll the Status Register for a while to see if the value really turns up
- * in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
- * to 1 in the Status Register, we assume this controller has an
- * Auxiliary Port (a.k.a. Mouse Port).
- */
- PS2ControllerWait();
- WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
- CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER);
- PS2ControllerWait();
-
- /* 0x5A is a random dummy value */
- WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
- 0x5A);
-
- for (Loops = 0; Loops < 10; Loops++)
- {
- StallExecutionProcessor(10000);
- Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
- if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
- break;
- }
-
- READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
-
- return (Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL);
-#endif
-}
-
-
-static
-BOOLEAN
-DetectPS2AuxDevice(VOID)
-{
- UCHAR Scancode;
- UCHAR Status;
- ULONG Loops;
- BOOLEAN Result = TRUE;
-
- PS2ControllerWait();
- WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
- CONTROLLER_COMMAND_WRITE_MOUSE);
- PS2ControllerWait();
-
- /* Identify device */
- WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA, 0xF2);
-
- /* Wait for reply */
- for (Loops = 0; Loops < 100; Loops++)
- {
- StallExecutionProcessor(10000);
- Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
- if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
- break;
- }
-
- Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
- if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
- Result = FALSE;
-
- Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
- if (Scancode != 0xFA)
- Result = FALSE;
-
- StallExecutionProcessor(10000);
-
- Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
- if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
- Result = FALSE;
-
- Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
- if (Scancode != 0x00)
- Result = FALSE;
-
- return Result;
-}
-
-
-static
-VOID
-DetectPS2Mouse(PCONFIGURATION_COMPONENT_DATA BusKey)
-{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- PCONFIGURATION_COMPONENT_DATA ControllerKey;
- PCONFIGURATION_COMPONENT_DATA PeripheralKey;
- ULONG Size;
-
- if (DetectPS2AuxPort())
- {
- TRACE("Detected PS2 port\n");
-
- PartialResourceList = FrLdrHeapAlloc(sizeof(CM_PARTIAL_RESOURCE_LIST), TAG_HW_RESOURCE_LIST);
- if (PartialResourceList == NULL)
- {
- ERR("Failed to allocate resource descriptor\n");
- return;
- }
- memset(PartialResourceList, 0, sizeof(CM_PARTIAL_RESOURCE_LIST));
-
- /* Initialize resource descriptor */
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 1;
-
- /* Set Interrupt */
- PartialResourceList->PartialDescriptors[0].Type = CmResourceTypeInterrupt;
- PartialResourceList->PartialDescriptors[0].ShareDisposition = CmResourceShareUndetermined;
- PartialResourceList->PartialDescriptors[0].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
- PartialResourceList->PartialDescriptors[0].u.Interrupt.Level = 12;
- PartialResourceList->PartialDescriptors[0].u.Interrupt.Vector = 12;
- PartialResourceList->PartialDescriptors[0].u.Interrupt.Affinity = 0xFFFFFFFF;
-
- /* Create controller key */
- FldrCreateComponentKey(BusKey,
- ControllerClass,
- PointerController,
- Input,
- 0x0,
- 0xFFFFFFFF,
- NULL,
- PartialResourceList,
- sizeof(CM_PARTIAL_RESOURCE_LIST),
- &ControllerKey);
- TRACE("Created key: PointerController\\0\n");
-
- if (DetectPS2AuxDevice())
- {
- TRACE("Detected PS2 mouse\n");
-
- /* Initialize resource descriptor */
- Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
- sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
- PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
- if (PartialResourceList == NULL)
- {
- ERR("Failed to allocate resource descriptor\n");
- return;
- }
- memset(PartialResourceList, 0, Size);
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 0;
-
- /* Create peripheral key */
- FldrCreateComponentKey(ControllerKey,
- ControllerClass,
- PointerPeripheral,
- Input,
- 0x0,
- 0xFFFFFFFF,
- "MICROSOFT PS2 MOUSE",
- PartialResourceList,
- Size,
- &PeripheralKey);
- TRACE("Created key: PointerPeripheral\\0\n");
- }
- }
-}
-
-
-static VOID
-DetectDisplayController(PCONFIGURATION_COMPONENT_DATA BusKey)
-{
- CHAR Buffer[80];
- PCONFIGURATION_COMPONENT_DATA ControllerKey;
- USHORT VesaVersion;
-
- /* FIXME: Set 'ComponentInformation' value */
-
- VesaVersion = BiosIsVesaSupported();
- if (VesaVersion != 0)
- {
- TRACE("VESA version %c.%c\n",
- (VesaVersion >> 8) + '0',
- (VesaVersion & 0xFF) + '0');
- }
- else
- {
- TRACE("VESA not supported\n");
- }
-
- if (VesaVersion >= 0x0200)
- {
- strcpy(Buffer, "VBE Display");
- }
- else
- {
- strcpy(Buffer, "VGA Display");
- }
-
- FldrCreateComponentKey(BusKey,
- ControllerClass,
- DisplayController,
- 0x0,
- 0x0,
- 0xFFFFFFFF,
- Buffer,
- NULL,
- 0,
- &ControllerKey);
- TRACE("Created key: DisplayController\\0\n");
-
- /* FIXME: Add display peripheral (monitor) data */
- if (VesaVersion != 0)
- {
- if (BiosIsVesaDdcSupported())
- {
- TRACE("VESA/DDC supported!\n");
- if (BiosVesaReadEdid())
- {
- TRACE("EDID data read successfully!\n");
-
- }
- }
- }
-}
-
-
-static
-VOID
-DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
-{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- PCONFIGURATION_COMPONENT_DATA BusKey;
- ULONG Size;
-
- /* Increment bus number */
- (*BusNumber)++;
-
- /* Set 'Configuration Data' value */
- Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
- sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
- PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
- if (PartialResourceList == NULL)
- {
- ERR("Failed to allocate resource descriptor\n");
- return;
- }
-
- /* Initialize resource descriptor */
- memset(PartialResourceList, 0, Size);
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 0;
-
- /* Create new bus key */
- FldrCreateComponentKey(SystemKey,
- AdapterClass,
- MultiFunctionAdapter,
- 0x0,
- 0x0,
- 0xFFFFFFFF,
- "ISA",
- PartialResourceList,
- Size,
- &BusKey);
-
- /* Detect ISA/BIOS devices */
- DetectBiosDisks(BusKey);
-
- DetectBiosFloppyController(BusKey);
-
- DetectSerialPorts(BusKey);
-
- DetectParallelPorts(BusKey);
-
- DetectKeyboardController(BusKey);
-
- DetectPS2Mouse(BusKey);
-
- DetectDisplayController(BusKey);
-
- /* FIXME: Detect more ISA devices */
-}
-
-BOOLEAN
-PcInitializeBootDevices(VOID)
-{
- return HwInitializeBiosDisks();
-}
-
-PCONFIGURATION_COMPONENT_DATA
-PcHwDetect(VOID)
-{
- PCONFIGURATION_COMPONENT_DATA SystemKey;
- ULONG BusNumber = 0;
-
- TRACE("DetectHardware()\n");
-
- /* Create the 'System' key */
- SystemKey = DetectSystem();
-
- /* Detect buses */
- DetectPciBios(SystemKey, &BusNumber);
- DetectApmBios(SystemKey, &BusNumber);
- DetectPnpBios(SystemKey, &BusNumber);
- DetectIsaBios(SystemKey, &BusNumber);
- DetectAcpiBios(SystemKey, &BusNumber);
-
- TRACE("DetectHardware() Done\n");
-
- return SystemKey;
-}
-
-VOID
-PcHwIdle(VOID)
-{
- REGS Regs;
-
- /* Select APM 1.0+ function */
- Regs.b.ah = 0x53;
-
- /* Function 05h: CPU idle */
- Regs.b.al = 0x05;
-
- /* Call INT 15h */
- Int386(0x15, &Regs, &Regs);
-
- /* Check if successfull (CF set on error) */
- if (INT386_SUCCESS(Regs))
- return;
-
- /*
- * No futher processing here.
- * Optionally implement HLT instruction handling.
- */
-}
-
-VOID
-FrLdrCheckCpuCompatibility(VOID)
-{
- INT CpuInformation[4] = {-1};
- ULONG NumberOfIds;
-
- /* Check if the processor first supports ID 1 */
- __cpuid(CpuInformation, 0);
-
- NumberOfIds = CpuInformation[0];
-
- if (NumberOfIds == 0)
- {
- FrLdrBugCheckWithMessage(MISSING_HARDWARE_REQUIREMENTS,
- __FILE__,
- __LINE__,
- "ReactOS requires the CPUID instruction to return "
- "more than one supported ID.\n\n");
- }
-
- /* NumberOfIds will be greater than 1 if the processor is new enough. */
- if (NumberOfIds == 1)
- {
- INT ProcessorFamily;
-
- /* Get information. */
- __cpuid(CpuInformation, 1);
-
- ProcessorFamily = (CpuInformation[0] >> 8) & 0xF;
-
- /* If it's Family 4 or lower, bugcheck. */
- if(ProcessorFamily < 5)
- {
- FrLdrBugCheckWithMessage(MISSING_HARDWARE_REQUIREMENTS,
- __FILE__,
- __LINE__,
- "Processor is too old (family %u < 5)\n"
- "ReactOS requires a Pentium-level processor or newer.",
- ProcessorFamily);
- }
- }
-}
-
-
/* EOF */
extern ARC_DISK_SIGNATURE_EX reactos_arc_disk_info[];
static CHAR Hex[] = "0123456789abcdef";
+
UCHAR PcBiosDiskCount = 0;
-CHAR PcDiskIdentifier[32][20];
+static CHAR PcDiskIdentifier[32][20];
+
PVOID DiskReadBuffer;
SIZE_T DiskReadBufferSize;
-static ARC_STATUS DiskClose(ULONG FileId)
+/* FUNCTIONS *****************************************************************/
+
+// static
+ARC_STATUS
+DiskClose(ULONG FileId)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
return ESUCCESS;
}
-static ARC_STATUS DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
+// static
+ARC_STATUS
+DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
return ESUCCESS;
}
-static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
+static ARC_STATUS
+DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
{
DISKCONTEXT* Context;
UCHAR DriveNumber;
}
else
{
- /* This is either a floppy disk device (DrivePartition == 0) or
- * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but
- * it doesn't matter which one because they both have 512 bytes per sector */
+ /*
+ * This is either a floppy disk device (DrivePartition == 0) or
+ * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF)
+ * but it doesn't matter which one because they both have 512 bytes
+ * per sector.
+ */
SectorSize = 512;
}
{
if (!DiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
return EINVAL;
+
SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
SectorCount = PartitionTableEntry.PartitionSectorCount;
}
+#if 0 // FIXME: Investigate
+ else
+ {
+ SectorCount = 0; /* FIXME */
+ }
+#endif
Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
if (!Context)
return ENOMEM;
+
Context->DriveNumber = DriveNumber;
Context->SectorSize = SectorSize;
Context->SectorOffset = SectorOffset;
return ESUCCESS;
}
-static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
+// static
+ARC_STATUS
+DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
UCHAR* Ptr = (UCHAR*)Buffer;
MaxSectors = DiskReadBufferSize / Context->SectorSize;
SectorOffset = Context->SectorNumber + Context->SectorOffset;
- ret = 1;
+ ret = TRUE;
while (TotalSectors)
{
if (ReadSectors > MaxSectors)
ReadSectors = MaxSectors;
- ret = MachDiskReadLogicalSectors(
- Context->DriveNumber,
- SectorOffset,
- ReadSectors,
- DiskReadBuffer);
+ ret = MachDiskReadLogicalSectors(Context->DriveNumber,
+ SectorOffset,
+ ReadSectors,
+ DiskReadBuffer);
if (!ret)
break;
return (!ret) ? EIO : ESUCCESS;
}
-static ARC_STATUS DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
+// static
+ARC_STATUS
+DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
return ESUCCESS;
}
-static const DEVVTBL DiskVtbl = {
+static const DEVVTBL DiskVtbl =
+{
DiskClose,
DiskGetFileInformation,
DiskOpen,
DiskSeek,
};
+
PCHAR
GetHarddiskIdentifier(
UCHAR DriveNumber)
Identifier[15] = Hex[(Signature >> 4) & 0x0F];
Identifier[16] = Hex[Signature & 0x0F];
Identifier[17] = '-';
- Identifier[18] = 'A';
+ Identifier[18] = 'A'; // FIXME: Not always 'A' ...
Identifier[19] = 0;
TRACE("Identifier: %s\n", Identifier);
}
-
BOOLEAN
-HwInitializeBiosDisks(VOID)
+PcInitializeBootDevices(VOID)
{
UCHAR DiskCount, DriveNumber;
ULONG i;
DiskCount++;
DriveNumber++;
- memset(DiskReadBuffer, 0xcd, 512);
+ memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
}
DiskReportError(TRUE);
+ TRACE("BIOS reports %d harddisk%s\n",
+ (int)DiskCount, (DiskCount == 1) ? "" : "s");
/* Get the drive we're booting from */
MachDiskGetBootPath(BootPath, sizeof(BootPath));
TRACE("BIOS reports %d harddisk%s\n",
(int)DiskCount, (DiskCount == 1) ? "": "s");
- return DiskCount != 0;
+ return (DiskCount != 0);
}
+++ /dev/null
-/*
- * FreeLoader
- * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <freeldr.h>
-
-#define NDEBUG
-#include <debug.h>
-
-DBG_DEFAULT_CHANNEL(DISK);
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-// FUNCTIONS
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-BOOLEAN DiskResetController(UCHAR DriveNumber)
-{
- REGS RegsIn;
- REGS RegsOut;
-
- WARN("DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
-
- // BIOS Int 13h, function 0 - Reset disk system
- // AH = 00h
- // DL = drive (if bit 7 is set both hard disks and floppy disks reset)
- // Return:
- // AH = status
- // CF clear if successful
- // CF set on error
- RegsIn.b.ah = 0x00;
- RegsIn.b.dl = DriveNumber;
-
- // Reset the disk controller
- Int386(0x13, &RegsIn, &RegsOut);
-
- return INT386_SUCCESS(RegsOut);
-}
-
-BOOLEAN DiskInt13ExtensionsSupported(UCHAR DriveNumber)
-{
- static UCHAR LastDriveNumber = 0xff;
- static BOOLEAN LastSupported;
- REGS RegsIn;
- REGS RegsOut;
-
- TRACE("PcDiskInt13ExtensionsSupported()\n");
-
- if (DriveNumber == LastDriveNumber)
- {
- TRACE("Using cached value %s for drive 0x%x\n", LastSupported ? "TRUE" : "FALSE", DriveNumber);
- return LastSupported;
- }
-
- // Some BIOSes report that extended disk access functions are not supported
- // when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping
- // with Intel Macs). Therefore we just return TRUE if we're booting from a CD -
- // we can assume that all El Torito capable BIOSes support INT 13 extensions.
- // We simply detect whether we're booting from CD by checking whether the drive
- // number is >= 0x8A. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes.
- if (DriveNumber >= 0x8A)
- {
- LastSupported = TRUE;
- return TRUE;
- }
-
- LastDriveNumber = DriveNumber;
-
- // IBM/MS INT 13 Extensions - INSTALLATION CHECK
- // AH = 41h
- // BX = 55AAh
- // DL = drive (80h-FFh)
- // Return:
- // CF set on error (extensions not supported)
- // AH = 01h (invalid function)
- // CF clear if successful
- // BX = AA55h if installed
- // AH = major version of extensions
- // 01h = 1.x
- // 20h = 2.0 / EDD-1.0
- // 21h = 2.1 / EDD-1.1
- // 30h = EDD-3.0
- // AL = internal use
- // CX = API subset support bitmap
- // DH = extension version (v2.0+ ??? -- not present in 1.x)
- //
- // Bitfields for IBM/MS INT 13 Extensions API support bitmap
- // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
- // Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
- // Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
- // extended drive parameter table is valid
- // Bits 3-15 reserved
- RegsIn.b.ah = 0x41;
- RegsIn.w.bx = 0x55AA;
- RegsIn.b.dl = DriveNumber;
-
- // Reset the disk controller
- Int386(0x13, &RegsIn, &RegsOut);
-
- if (!INT386_SUCCESS(RegsOut))
- {
- // CF set on error (extensions not supported)
- LastSupported = FALSE;
- return FALSE;
- }
-
- if (RegsOut.w.bx != 0xAA55)
- {
- // BX = AA55h if installed
- LastSupported = FALSE;
- return FALSE;
- }
-
- if (!(RegsOut.w.cx & 0x0001))
- {
- // CX = API subset support bitmap
- // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
- DbgPrint("Suspicious API subset support bitmap 0x%x on device 0x%lx\n", RegsOut.w.cx, DriveNumber);
- LastSupported = FALSE;
- return FALSE;
- }
-
- LastSupported = TRUE;
- return TRUE;
-}
-
-VOID DiskStopFloppyMotor(VOID)
-{
- WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0);
-}
-
-BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize)
-{
- REGS RegsIn;
- REGS RegsOut;
- PUSHORT Ptr = (PUSHORT)(BIOSCALLBUFFER);
-
- TRACE("DiskGetExtendedDriveParameters()\n");
-
- if (!DiskInt13ExtensionsSupported(DriveNumber))
- return FALSE;
-
- // Initialize transfer buffer
- *Ptr = BufferSize;
-
- // BIOS Int 13h, function 48h - Get drive parameters
- // AH = 48h
- // DL = drive (bit 7 set for hard disk)
- // DS:SI = result buffer
- // Return:
- // CF set on error
- // AH = status (07h)
- // CF clear if successful
- // AH = 00h
- // DS:SI -> result buffer
- RegsIn.b.ah = 0x48;
- RegsIn.b.dl = DriveNumber;
- RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> result buffer
- RegsIn.w.si = BIOSCALLBUFOFFSET;
-
- // Get drive parameters
- Int386(0x13, &RegsIn, &RegsOut);
-
- if (!INT386_SUCCESS(RegsOut))
- {
- return FALSE;
- }
-
- memcpy(Buffer, Ptr, BufferSize);
-
-#if DBG
- TRACE("size of buffer: %x\n", Ptr[0]);
- TRACE("information flags: %x\n", Ptr[1]);
- TRACE("number of physical cylinders on drive: %u\n", *(PULONG)&Ptr[2]);
- TRACE("number of physical heads on drive: %u\n", *(PULONG)&Ptr[4]);
- TRACE("number of physical sectors per track: %u\n", *(PULONG)&Ptr[6]);
- TRACE("total number of sectors on drive: %I64u\n", *(unsigned long long*)&Ptr[8]);
- TRACE("bytes per sector: %u\n", Ptr[12]);
- if (Ptr[0] >= 0x1e)
- {
- TRACE("EED configuration parameters: %x:%x\n", Ptr[13], Ptr[14]);
- if (Ptr[13] != 0xffff && Ptr[14] != 0xffff)
- {
- PUCHAR SpecPtr = (PUCHAR)(ULONG_PTR)((Ptr[13] << 4) + Ptr[14]);
- TRACE("SpecPtr: %x\n", SpecPtr);
- TRACE("physical I/O port base address: %x\n", *(PUSHORT)&SpecPtr[0]);
- TRACE("disk-drive control port address: %x\n", *(PUSHORT)&SpecPtr[2]);
- TRACE("drive flags: %x\n", SpecPtr[4]);
- TRACE("proprietary information: %x\n", SpecPtr[5]);
- TRACE("IRQ for drive: %u\n", SpecPtr[6]);
- TRACE("sector count for multi-sector transfers: %u\n", SpecPtr[7]);
- TRACE("DMA control: %x\n", SpecPtr[8]);
- TRACE("programmed I/O control: %x\n", SpecPtr[9]);
- TRACE("drive options: %x\n", *(PUSHORT)&SpecPtr[10]);
- }
- }
- if (Ptr[0] >= 0x42)
- {
- TRACE("signature: %x\n", Ptr[15]);
- }
-#endif
-
- return TRUE;
-}
-
-/* EOF */
*/
#include <freeldr.h>
+#include <cportlib/cportlib.h>
+
+#define NDEBUG
+#include <debug.h>
+
+DBG_DEFAULT_CHANNEL(HWDETECT);
+
+
+/* Maximum number of COM and LPT ports */
+#define MAX_COM_PORTS 4
+#define MAX_LPT_PORTS 3
+
+/* No Mouse */
+#define MOUSE_TYPE_NONE 0
+/* Microsoft Mouse with 2 buttons */
+#define MOUSE_TYPE_MICROSOFT 1
+/* Logitech Mouse with 3 buttons */
+#define MOUSE_TYPE_LOGITECH 2
+/* Microsoft Wheel Mouse (aka Z Mouse) */
+#define MOUSE_TYPE_WHEELZ 3
+/* Mouse Systems Mouse */
+#define MOUSE_TYPE_MOUSESYSTEMS 4
+
+
+/* PS2 stuff */
+
+/* Controller registers. */
+#define CONTROLLER_REGISTER_STATUS 0x64
+#define CONTROLLER_REGISTER_CONTROL 0x64
+#define CONTROLLER_REGISTER_DATA 0x60
+
+/* Controller commands. */
+#define CONTROLLER_COMMAND_READ_MODE 0x20
+#define CONTROLLER_COMMAND_WRITE_MODE 0x60
+#define CONTROLLER_COMMAND_GET_VERSION 0xA1
+#define CONTROLLER_COMMAND_MOUSE_DISABLE 0xA7
+#define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8
+#define CONTROLLER_COMMAND_TEST_MOUSE 0xA9
+#define CONTROLLER_COMMAND_SELF_TEST 0xAA
+#define CONTROLLER_COMMAND_KEYBOARD_TEST 0xAB
+#define CONTROLLER_COMMAND_KEYBOARD_DISABLE 0xAD
+#define CONTROLLER_COMMAND_KEYBOARD_ENABLE 0xAE
+#define CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER 0xD3
+#define CONTROLLER_COMMAND_WRITE_MOUSE 0xD4
+
+/* Controller status */
+#define CONTROLLER_STATUS_OUTPUT_BUFFER_FULL 0x01
+#define CONTROLLER_STATUS_INPUT_BUFFER_FULL 0x02
+#define CONTROLLER_STATUS_SELF_TEST 0x04
+#define CONTROLLER_STATUS_COMMAND 0x08
+#define CONTROLLER_STATUS_UNLOCKED 0x10
+#define CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL 0x20
+#define CONTROLLER_STATUS_GENERAL_TIMEOUT 0x40
+#define CONTROLLER_STATUS_PARITY_ERROR 0x80
+#define AUX_STATUS_OUTPUT_BUFFER_FULL (CONTROLLER_STATUS_OUTPUT_BUFFER_FULL | \
+ CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL)
+
+/* Timeout in ms for sending to keyboard controller. */
+#define CONTROLLER_TIMEOUT 250
+
+
+// NOTE: Similar to xboxhw.c!XboxGetHarddiskConfigurationData(),
+// but with extended geometry support.
+// static
+PCM_PARTIAL_RESOURCE_LIST
+PcGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
+{
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
+ EXTENDED_GEOMETRY ExtGeometry;
+ GEOMETRY Geometry;
+ ULONG Size;
+
+ //
+ // Initialize returned size
+ //
+ *pSize = 0;
+
+ /* Set 'Configuration Data' value */
+ Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
+ sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate a full resource descriptor\n");
+ return NULL;
+ }
+
+ memset(PartialResourceList, 0, Size);
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 1;
+ PartialResourceList->PartialDescriptors[0].Type =
+ CmResourceTypeDeviceSpecific;
+// PartialResourceList->PartialDescriptors[0].ShareDisposition =
+// PartialResourceList->PartialDescriptors[0].Flags =
+ PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
+ sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
+
+ /* Get pointer to geometry data */
+ DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
+
+ /* Get the disk geometry */
+ ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
+ if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
+ {
+ DiskGeometry->BytesPerSector = ExtGeometry.BytesPerSector;
+ DiskGeometry->NumberOfCylinders = ExtGeometry.Cylinders;
+ DiskGeometry->SectorsPerTrack = ExtGeometry.SectorsPerTrack;
+ DiskGeometry->NumberOfHeads = ExtGeometry.Heads;
+ }
+ else if (MachDiskGetDriveGeometry(DriveNumber, &Geometry))
+ {
+ DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
+ DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
+ DiskGeometry->SectorsPerTrack = Geometry.Sectors;
+ DiskGeometry->NumberOfHeads = Geometry.Heads;
+ }
+ else
+ {
+ TRACE("Reading disk geometry failed\n");
+ FrLdrHeapFree(PartialResourceList, TAG_HW_RESOURCE_LIST);
+ return NULL;
+ }
+ TRACE("Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
+ DriveNumber,
+ DiskGeometry->NumberOfCylinders,
+ DiskGeometry->NumberOfHeads,
+ DiskGeometry->SectorsPerTrack,
+ DiskGeometry->BytesPerSector);
+
+ //
+ // Return configuration data
+ //
+ *pSize = Size;
+ return PartialResourceList;
+}
+
+static
+VOID
+DetectPnpBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
+{
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCM_PNP_BIOS_DEVICE_NODE DeviceNode;
+ PCM_PNP_BIOS_INSTALLATION_CHECK InstData;
+ PCONFIGURATION_COMPONENT_DATA BusKey;
+ ULONG x;
+ ULONG NodeSize = 0;
+ ULONG NodeCount = 0;
+ UCHAR NodeNumber;
+ ULONG FoundNodeCount;
+ int i;
+ ULONG PnpBufferSize;
+ ULONG Size;
+ char *Ptr;
+
+ InstData = (PCM_PNP_BIOS_INSTALLATION_CHECK)PnpBiosSupported();
+ if (InstData == NULL || strncmp((CHAR*)InstData->Signature, "$PnP", 4))
+ {
+ TRACE("PnP-BIOS not supported\n");
+ return;
+ }
+
+ TRACE("PnP-BIOS supported\n");
+ TRACE("Signature '%c%c%c%c'\n",
+ InstData->Signature[0], InstData->Signature[1],
+ InstData->Signature[2], InstData->Signature[3]);
+
+ x = PnpBiosGetDeviceNodeCount(&NodeSize, &NodeCount);
+ if (x == 0x82)
+ {
+ TRACE("PnP-BIOS function 'Get Number of System Device Nodes' not supported\n");
+ return;
+ }
+
+ NodeCount &= 0xFF; // needed since some fscked up BIOSes return
+ // wrong info (e.g. Mac Virtual PC)
+ // e.g. look: http://my.execpc.com/~geezer/osd/pnp/pnp16.c
+ if (x != 0 || NodeSize == 0 || NodeCount == 0)
+ {
+ ERR("PnP-BIOS failed to enumerate device nodes\n");
+ return;
+ }
+ TRACE("MaxNodeSize %u NodeCount %u\n", NodeSize, NodeCount);
+ TRACE("Estimated buffer size %u\n", NodeSize * NodeCount);
+
+ /* Set 'Configuration Data' value */
+ Size = sizeof(CM_PARTIAL_RESOURCE_LIST)
+ + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK) + (NodeSize * NodeCount);
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ return;
+ }
+ memset(PartialResourceList, 0, Size);
+
+ /* Initialize resource descriptor */
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 1;
+ PartialResourceList->PartialDescriptors[0].Type =
+ CmResourceTypeDeviceSpecific;
+ PartialResourceList->PartialDescriptors[0].ShareDisposition =
+ CmResourceShareUndetermined;
+
+ /* The buffer starts after PartialResourceList->PartialDescriptors[0] */
+ Ptr = (char *)(PartialResourceList + 1);
+
+ /* Set installation check data */
+ memcpy (Ptr, InstData, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK));
+ Ptr += sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
+
+ /* Copy device nodes */
+ FoundNodeCount = 0;
+ PnpBufferSize = sizeof(CM_PNP_BIOS_INSTALLATION_CHECK);
+ for (i = 0; i < 0xFF; i++)
+ {
+ NodeNumber = (UCHAR)i;
+
+ x = PnpBiosGetDeviceNode(&NodeNumber, DiskReadBuffer);
+ if (x == 0)
+ {
+ DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DiskReadBuffer;
+
+ TRACE("Node: %u Size %u (0x%x)\n",
+ DeviceNode->Node,
+ DeviceNode->Size,
+ DeviceNode->Size);
+
+ if (PnpBufferSize + DeviceNode->Size > Size)
+ {
+ ERR("Buffer too small!\n");
+ break;
+ }
+
+ memcpy(Ptr, DeviceNode, DeviceNode->Size);
+
+ Ptr += DeviceNode->Size;
+ PnpBufferSize += DeviceNode->Size;
+
+ FoundNodeCount++;
+ if (FoundNodeCount >= NodeCount)
+ break;
+ }
+ }
+
+ /* Set real data size */
+ PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
+ PnpBufferSize;
+ Size = sizeof(CM_PARTIAL_RESOURCE_LIST) + PnpBufferSize;
+
+ TRACE("Real buffer size: %u\n", PnpBufferSize);
+ TRACE("Resource size: %u\n", Size);
+
+ /* Create component key */
+ FldrCreateComponentKey(SystemKey,
+ AdapterClass,
+ MultiFunctionAdapter,
+ 0x0,
+ 0x0,
+ 0xFFFFFFFF,
+ "PNP BIOS",
+ PartialResourceList,
+ Size,
+ &BusKey);
+
+ (*BusNumber)++;
+}
+
+static
+VOID
+InitializeSerialPort(PUCHAR Port,
+ UCHAR LineControl)
+{
+ WRITE_PORT_UCHAR(Port + 3, 0x80); /* set DLAB on */
+ WRITE_PORT_UCHAR(Port, 0x60); /* speed LO byte */
+ WRITE_PORT_UCHAR(Port + 1, 0); /* speed HI byte */
+ WRITE_PORT_UCHAR(Port + 3, LineControl);
+ WRITE_PORT_UCHAR(Port + 1, 0); /* set comm and DLAB to 0 */
+ WRITE_PORT_UCHAR(Port + 4, 0x09); /* DR int enable */
+ READ_PORT_UCHAR(Port + 5); /* clear error bits */
+}
+
+static
+ULONG
+DetectSerialMouse(PUCHAR Port)
+{
+ CHAR Buffer[4];
+ ULONG i;
+ ULONG TimeOut;
+ UCHAR LineControl;
+
+ /* Shutdown mouse or something like that */
+ LineControl = READ_PORT_UCHAR(Port + 4);
+ WRITE_PORT_UCHAR(Port + 4, (LineControl & ~0x02) | 0x01);
+ StallExecutionProcessor(100000);
+
+ /*
+ * Clear buffer
+ * Maybe there is no serial port although BIOS reported one (this
+ * is the case on Apple hardware), or the serial port is misbehaving,
+ * therefore we must give up after some time.
+ */
+ TimeOut = 200;
+ while (READ_PORT_UCHAR(Port + 5) & 0x01)
+ {
+ if (--TimeOut == 0)
+ return MOUSE_TYPE_NONE;
+ READ_PORT_UCHAR(Port);
+ }
+
+ /*
+ * Send modem control with 'Data Terminal Ready', 'Request To Send' and
+ * 'Output Line 2' message. This enables mouse to identify.
+ */
+ WRITE_PORT_UCHAR(Port + 4, 0x0b);
+
+ /* Wait 10 milliseconds for the mouse getting ready */
+ StallExecutionProcessor(10000);
+
+ /* Read first four bytes, which contains Microsoft Mouse signs */
+ TimeOut = 200;
+ for (i = 0; i < 4; i++)
+ {
+ while (((READ_PORT_UCHAR(Port + 5) & 1) == 0) && (TimeOut > 0))
+ {
+ StallExecutionProcessor(1000);
+ --TimeOut;
+ if (TimeOut == 0)
+ return MOUSE_TYPE_NONE;
+ }
+ Buffer[i] = READ_PORT_UCHAR(Port);
+ }
+
+ TRACE("Mouse data: %x %x %x %x\n",
+ Buffer[0], Buffer[1], Buffer[2], Buffer[3]);
+
+ /* Check that four bytes for signs */
+ for (i = 0; i < 4; ++i)
+ {
+ if (Buffer[i] == 'B')
+ {
+ /* Sign for Microsoft Ballpoint */
+// DbgPrint("Microsoft Ballpoint device detected\n");
+// DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
+ return MOUSE_TYPE_NONE;
+ }
+ else if (Buffer[i] == 'M')
+ {
+ /* Sign for Microsoft Mouse protocol followed by button specifier */
+ if (i == 3)
+ {
+ /* Overflow Error */
+ return MOUSE_TYPE_NONE;
+ }
+
+ switch (Buffer[i + 1])
+ {
+ case '3':
+ TRACE("Microsoft Mouse with 3-buttons detected\n");
+ return MOUSE_TYPE_LOGITECH;
+
+ case 'Z':
+ TRACE("Microsoft Wheel Mouse detected\n");
+ return MOUSE_TYPE_WHEELZ;
+
+ /* case '2': */
+ default:
+ TRACE("Microsoft Mouse with 2-buttons detected\n");
+ return MOUSE_TYPE_MICROSOFT;
+ }
+ }
+ }
+
+ return MOUSE_TYPE_NONE;
+}
+
+static ULONG
+GetSerialMousePnpId(PUCHAR Port, char *Buffer)
+{
+ ULONG TimeOut;
+ ULONG i = 0;
+ char c;
+ char x;
+
+ WRITE_PORT_UCHAR(Port + 4, 0x09);
+
+ /* Wait 10 milliseconds for the mouse getting ready */
+ StallExecutionProcessor(10000);
+
+ WRITE_PORT_UCHAR(Port + 4, 0x0b);
+
+ StallExecutionProcessor(10000);
+
+ for (;;)
+ {
+ TimeOut = 200;
+ while (((READ_PORT_UCHAR(Port + 5) & 1) == 0) && (TimeOut > 0))
+ {
+ StallExecutionProcessor(1000);
+ --TimeOut;
+ if (TimeOut == 0)
+ {
+ return 0;
+ }
+ }
+
+ c = READ_PORT_UCHAR(Port);
+ if (c == 0x08 || c == 0x28)
+ break;
+ }
+
+ Buffer[i++] = c;
+ x = c + 1;
+
+ for (;;)
+ {
+ TimeOut = 200;
+ while (((READ_PORT_UCHAR(Port + 5) & 1) == 0) && (TimeOut > 0))
+ {
+ StallExecutionProcessor(1000);
+ --TimeOut;
+ if (TimeOut == 0)
+ return 0;
+ }
+ c = READ_PORT_UCHAR(Port);
+ Buffer[i++] = c;
+ if (c == x)
+ break;
+ if (i >= 256)
+ break;
+ }
+
+ return i;
+}
+
+static
+VOID
+DetectSerialPointerPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey,
+ PUCHAR Base)
+{
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ char Buffer[256];
+ CHAR Identifier[256];
+ PCONFIGURATION_COMPONENT_DATA PeripheralKey;
+ ULONG MouseType;
+ ULONG Size, Length;
+ ULONG i;
+ ULONG j;
+ ULONG k;
+
+ TRACE("DetectSerialPointerPeripheral()\n");
+
+ Identifier[0] = 0;
+
+ InitializeSerialPort(Base, 2);
+ MouseType = DetectSerialMouse(Base);
+
+ if (MouseType != MOUSE_TYPE_NONE)
+ {
+ Length = GetSerialMousePnpId(Base, Buffer);
+ TRACE( "PnP ID length: %u\n", Length);
+
+ if (Length != 0)
+ {
+ /* Convert PnP sting to ASCII */
+ if (Buffer[0] == 0x08)
+ {
+ for (i = 0; i < Length; i++)
+ Buffer[i] += 0x20;
+ }
+ Buffer[Length] = 0;
+
+ TRACE("PnP ID string: %s\n", Buffer);
+
+ /* Copy PnpId string */
+ for (i = 0; i < 7; i++)
+ {
+ Identifier[i] = Buffer[3 + i];
+ }
+ memcpy(&Identifier[7],
+ L" - ",
+ 3 * sizeof(WCHAR));
+
+ /* Skip device serial number */
+ i = 10;
+ if (Buffer[i] == '\\')
+ {
+ for (j = ++i; i < Length; ++i)
+ {
+ if (Buffer[i] == '\\')
+ break;
+ }
+ if (i >= Length)
+ i -= 3;
+ }
+
+ /* Skip PnP class */
+ if (Buffer[i] == '\\')
+ {
+ for (j = ++i; i < Length; ++i)
+ {
+ if (Buffer[i] == '\\')
+ break;
+ }
+
+ if (i >= Length)
+ i -= 3;
+ }
+
+ /* Skip compatible PnP Id */
+ if (Buffer[i] == '\\')
+ {
+ for (j = ++i; i < Length; ++i)
+ {
+ if (Buffer[i] == '\\')
+ break;
+ }
+ if (Buffer[j] == '*')
+ ++j;
+ if (i >= Length)
+ i -= 3;
+ }
+
+ /* Get product description */
+ if (Buffer[i] == '\\')
+ {
+ for (j = ++i; i < Length; ++i)
+ {
+ if (Buffer[i] == ';')
+ break;
+ }
+ if (i >= Length)
+ i -= 3;
+ if (i > j + 1)
+ {
+ for (k = 0; k < i - j; k++)
+ {
+ Identifier[k + 10] = Buffer[k + j];
+ }
+ Identifier[10 + (i - j)] = 0;
+ }
+ }
+
+ TRACE("Identifier string: %s\n", Identifier);
+ }
+
+ if (Length == 0 || strlen(Identifier) < 11)
+ {
+ switch (MouseType)
+ {
+ case MOUSE_TYPE_LOGITECH:
+ strcpy(Identifier, "LOGITECH SERIAL MOUSE");
+ break;
+
+ case MOUSE_TYPE_WHEELZ:
+ strcpy(Identifier, "MICROSOFT SERIAL MOUSE WITH WHEEL");
+ break;
+
+ case MOUSE_TYPE_MICROSOFT:
+ default:
+ strcpy(Identifier, "MICROSOFT SERIAL MOUSE");
+ break;
+ }
+ }
+
+ /* Set 'Configuration Data' value */
+ Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
+ sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ return;
+ }
+ memset(PartialResourceList, 0, Size);
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 0;
+
+ /* Create 'PointerPeripheral' key */
+ FldrCreateComponentKey(ControllerKey,
+ PeripheralClass,
+ PointerPeripheral,
+ Input,
+ 0x0,
+ 0xFFFFFFFF,
+ Identifier,
+ PartialResourceList,
+ Size,
+ &PeripheralKey);
+
+ TRACE("Created key: PointerPeripheral\\0\n");
+ }
+}
+
+static
+VOID
+DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
+{
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+ PCM_SERIAL_DEVICE_DATA SerialDeviceData;
+ ULONG Irq[MAX_COM_PORTS] = {4, 3, 4, 3};
+ ULONG Base;
+ CHAR Buffer[80];
+ PUSHORT BasePtr;
+ ULONG ControllerNumber = 0;
+ PCONFIGURATION_COMPONENT_DATA ControllerKey;
+ ULONG i;
+ ULONG Size;
+
+ TRACE("DetectSerialPorts()\n");
+
+ /*
+ * The BIOS data area 0x400 holds the address of the first valid COM port.
+ * Each COM port address is stored in a 2-byte field.
+ * Infos at: http://www.bioscentral.com/misc/bda.htm
+ */
+ BasePtr = (PUSHORT)0x400;
+
+ for (i = 0; i < MAX_COM_PORTS; i++, BasePtr++)
+ {
+ Base = (ULONG) * BasePtr;
+ if (Base == 0 || !CpDoesPortExist((PUCHAR)Base))
+ continue;
+
+ TRACE("Found COM%u port at 0x%x\n", i + 1, Base);
+
+ /* Set 'Identifier' value */
+ sprintf(Buffer, "COM%ld", i + 1);
+
+ /* Build full device descriptor */
+ Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
+ 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) +
+ sizeof(CM_SERIAL_DEVICE_DATA);
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ continue;
+ }
+ memset(PartialResourceList, 0, Size);
+
+ /* Initialize resource descriptor */
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 3;
+
+ /* Set IO Port */
+ PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
+ PartialDescriptor->Type = CmResourceTypePort;
+ PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
+ PartialDescriptor->u.Port.Start.LowPart = Base;
+ PartialDescriptor->u.Port.Start.HighPart = 0x0;
+ PartialDescriptor->u.Port.Length = 7;
+
+ /* Set Interrupt */
+ PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
+ PartialDescriptor->Type = CmResourceTypeInterrupt;
+ PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+ PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
+ PartialDescriptor->u.Interrupt.Level = Irq[i];
+ PartialDescriptor->u.Interrupt.Vector = Irq[i];
+ PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
+
+ /* Set serial data (device specific) */
+ PartialDescriptor = &PartialResourceList->PartialDescriptors[2];
+ PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
+ PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+ PartialDescriptor->Flags = 0;
+ PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_SERIAL_DEVICE_DATA);
+
+ SerialDeviceData =
+ (PCM_SERIAL_DEVICE_DATA)&PartialResourceList->PartialDescriptors[3];
+ SerialDeviceData->BaudClock = 1843200; /* UART Clock frequency (Hertz) */
+
+ /* Create controller key */
+ FldrCreateComponentKey(BusKey,
+ ControllerClass,
+ SerialController,
+ Output | Input | ConsoleIn | ConsoleOut,
+ ControllerNumber,
+ 0xFFFFFFFF,
+ Buffer,
+ PartialResourceList,
+ Size,
+ &ControllerKey);
+
+ if (!Rs232PortInUse(UlongToPtr(Base)))
+ {
+ /* Detect serial mouse */
+ DetectSerialPointerPeripheral(ControllerKey, UlongToPtr(Base));
+ }
+
+ ControllerNumber++;
+ }
+}
+
+static VOID
+DetectParallelPorts(PCONFIGURATION_COMPONENT_DATA BusKey)
+{
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+ ULONG Irq[MAX_LPT_PORTS] = {7, 5, (ULONG) - 1};
+ CHAR Buffer[80];
+ PCONFIGURATION_COMPONENT_DATA ControllerKey;
+ PUSHORT BasePtr;
+ ULONG Base;
+ ULONG ControllerNumber = 0;
+ ULONG i;
+ ULONG Size;
+
+ TRACE("DetectParallelPorts() called\n");
+
+ /*
+ * The BIOS data area 0x408 holds the address of the first valid LPT port.
+ * Each LPT port address is stored in a 2-byte field.
+ * Infos at: http://www.bioscentral.com/misc/bda.htm
+ */
+ BasePtr = (PUSHORT)0x408;
+
+ for (i = 0; i < MAX_LPT_PORTS; i++, BasePtr++)
+ {
+ Base = (ULONG) * BasePtr;
+ if (Base == 0)
+ continue;
+
+ TRACE("Parallel port %u: %x\n", ControllerNumber, Base);
+
+ /* Set 'Identifier' value */
+ sprintf(Buffer, "PARALLEL%ld", i + 1);
+
+ /* Build full device descriptor */
+ Size = sizeof(CM_PARTIAL_RESOURCE_LIST);
+ if (Irq[i] != (ULONG) - 1)
+ Size += sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ continue;
+ }
+ memset(PartialResourceList, 0, Size);
+
+ /* Initialize resource descriptor */
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = (Irq[i] != (ULONG) - 1) ? 2 : 1;
+
+ /* Set IO Port */
+ PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
+ PartialDescriptor->Type = CmResourceTypePort;
+ PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
+ PartialDescriptor->u.Port.Start.LowPart = Base;
+ PartialDescriptor->u.Port.Start.HighPart = 0x0;
+ PartialDescriptor->u.Port.Length = 3;
+
+ /* Set Interrupt */
+ if (Irq[i] != (ULONG) - 1)
+ {
+ PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
+ PartialDescriptor->Type = CmResourceTypeInterrupt;
+ PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+ PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
+ PartialDescriptor->u.Interrupt.Level = Irq[i];
+ PartialDescriptor->u.Interrupt.Vector = Irq[i];
+ PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
+ }
+
+ /* Create controller key */
+ FldrCreateComponentKey(BusKey,
+ ControllerClass,
+ ParallelController,
+ Output,
+ ControllerNumber,
+ 0xFFFFFFFF,
+ Buffer,
+ PartialResourceList,
+ Size,
+ &ControllerKey);
+
+ ControllerNumber++;
+ }
+
+ TRACE("DetectParallelPorts() done\n");
+}
+
+//static
+BOOLEAN
+DetectKeyboardDevice(VOID)
+{
+ UCHAR Status;
+ UCHAR Scancode;
+ ULONG Loops;
+ BOOLEAN Result = TRUE;
+
+ /* Identify device */
+ WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA, 0xF2);
+
+ /* Wait for reply */
+ for (Loops = 0; Loops < 100; Loops++)
+ {
+ StallExecutionProcessor(10000);
+ Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+ if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
+ break;
+ }
+
+ if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) == 0)
+ {
+ /* PC/XT keyboard or no keyboard */
+ Result = FALSE;
+ }
+
+ Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
+ if (Scancode != 0xFA)
+ {
+ /* No ACK received */
+ Result = FALSE;
+ }
+
+ StallExecutionProcessor(10000);
+
+ Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+ if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) == 0)
+ {
+ /* Found AT keyboard */
+ return Result;
+ }
+
+ Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
+ if (Scancode != 0xAB)
+ {
+ /* No 0xAB received */
+ Result = FALSE;
+ }
+
+ StallExecutionProcessor(10000);
+
+ Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+ if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) == 0)
+ {
+ /* No byte in buffer */
+ Result = FALSE;
+ }
+
+ Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
+ if (Scancode != 0x41)
+ {
+ /* No 0x41 received */
+ Result = FALSE;
+ }
+
+ /* Found MF-II keyboard */
+ return Result;
+}
+
+static VOID
+DetectKeyboardPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey)
+{
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+ PCM_KEYBOARD_DEVICE_DATA KeyboardData;
+ PCONFIGURATION_COMPONENT_DATA PeripheralKey;
+ ULONG Size;
+
+ /* HACK: don't call DetectKeyboardDevice() as it fails in Qemu 0.8.2
+ if (DetectKeyboardDevice()) */
+ {
+ /* Set 'Configuration Data' value */
+ Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
+ sizeof(CM_KEYBOARD_DEVICE_DATA);
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ return;
+ }
+
+ /* Initialize resource descriptor */
+ memset(PartialResourceList, 0, Size);
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 1;
+
+ PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
+ PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
+ PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+ PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_KEYBOARD_DEVICE_DATA);
+
+ KeyboardData = (PCM_KEYBOARD_DEVICE_DATA)(PartialDescriptor + 1);
+ KeyboardData->Version = 1;
+ KeyboardData->Revision = 1;
+ KeyboardData->Type = 4;
+ KeyboardData->Subtype = 0;
+ KeyboardData->KeyboardFlags = 0x20;
+
+ /* Create controller key */
+ FldrCreateComponentKey(ControllerKey,
+ PeripheralClass,
+ KeyboardPeripheral,
+ Input | ConsoleIn,
+ 0x0,
+ 0xFFFFFFFF,
+ "PCAT_ENHANCED",
+ PartialResourceList,
+ Size,
+ &PeripheralKey);
+ TRACE("Created key: KeyboardPeripheral\\0\n");
+ }
+}
+
+static
+VOID
+DetectKeyboardController(PCONFIGURATION_COMPONENT_DATA BusKey)
+{
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+ PCONFIGURATION_COMPONENT_DATA ControllerKey;
+ ULONG Size;
+
+ /* Set 'Configuration Data' value */
+ Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
+ 2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ return;
+ }
+
+ /* Initialize resource descriptor */
+ memset(PartialResourceList, 0, Size);
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 3;
+
+ /* Set Interrupt */
+ PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
+ PartialDescriptor->Type = CmResourceTypeInterrupt;
+ PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+ PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
+ PartialDescriptor->u.Interrupt.Level = 1;
+ PartialDescriptor->u.Interrupt.Vector = 1;
+ PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
+
+ /* Set IO Port 0x60 */
+ PartialDescriptor = &PartialResourceList->PartialDescriptors[1];
+ PartialDescriptor->Type = CmResourceTypePort;
+ PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
+ PartialDescriptor->u.Port.Start.LowPart = 0x60;
+ PartialDescriptor->u.Port.Start.HighPart = 0x0;
+ PartialDescriptor->u.Port.Length = 1;
+
+ /* Set IO Port 0x64 */
+ PartialDescriptor = &PartialResourceList->PartialDescriptors[2];
+ PartialDescriptor->Type = CmResourceTypePort;
+ PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
+ PartialDescriptor->u.Port.Start.LowPart = 0x64;
+ PartialDescriptor->u.Port.Start.HighPart = 0x0;
+ PartialDescriptor->u.Port.Length = 1;
+
+ /* Create controller key */
+ FldrCreateComponentKey(BusKey,
+ ControllerClass,
+ KeyboardController,
+ Input | ConsoleIn,
+ 0x0,
+ 0xFFFFFFFF,
+ NULL,
+ PartialResourceList,
+ Size,
+ &ControllerKey);
+ TRACE("Created key: KeyboardController\\0\n");
+
+ DetectKeyboardPeripheral(ControllerKey);
+}
+
+static
+VOID
+PS2ControllerWait(VOID)
+{
+ ULONG Timeout;
+ UCHAR Status;
+
+ for (Timeout = 0; Timeout < CONTROLLER_TIMEOUT; Timeout++)
+ {
+ Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+ if ((Status & CONTROLLER_STATUS_INPUT_BUFFER_FULL) == 0)
+ return;
+
+ /* Sleep for one millisecond */
+ StallExecutionProcessor(1000);
+ }
+}
+
+static
+BOOLEAN
+DetectPS2AuxPort(VOID)
+{
+#if 1
+ /* Current detection is too unreliable. Just do as if
+ * the PS/2 aux port is always present
+ */
+ return TRUE;
+#else
+ ULONG Loops;
+ UCHAR Status;
+
+ /* Put the value 0x5A in the output buffer using the
+ * "WriteAuxiliary Device Output Buffer" command (0xD3).
+ * Poll the Status Register for a while to see if the value really turns up
+ * in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
+ * to 1 in the Status Register, we assume this controller has an
+ * Auxiliary Port (a.k.a. Mouse Port).
+ */
+ PS2ControllerWait();
+ WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
+ CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER);
+ PS2ControllerWait();
+
+ /* 0x5A is a random dummy value */
+ WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
+ 0x5A);
+
+ for (Loops = 0; Loops < 10; Loops++)
+ {
+ StallExecutionProcessor(10000);
+ Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+ if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
+ break;
+ }
+
+ READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
+
+ return (Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL);
+#endif
+}
+
+static
+BOOLEAN
+DetectPS2AuxDevice(VOID)
+{
+ UCHAR Scancode;
+ UCHAR Status;
+ ULONG Loops;
+ BOOLEAN Result = TRUE;
+
+ PS2ControllerWait();
+ WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
+ CONTROLLER_COMMAND_WRITE_MOUSE);
+ PS2ControllerWait();
+
+ /* Identify device */
+ WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA, 0xF2);
+
+ /* Wait for reply */
+ for (Loops = 0; Loops < 100; Loops++)
+ {
+ StallExecutionProcessor(10000);
+ Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+ if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
+ break;
+ }
+
+ Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+ if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
+ Result = FALSE;
+
+ Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
+ if (Scancode != 0xFA)
+ Result = FALSE;
+
+ StallExecutionProcessor(10000);
+
+ Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
+ if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
+ Result = FALSE;
+
+ Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
+ if (Scancode != 0x00)
+ Result = FALSE;
+
+ return Result;
+}
+
+// FIXME: Missing: DetectPS2Peripheral!! (for corresponding 'PointerPeripheral')
+
+static
+VOID
+DetectPS2Mouse(PCONFIGURATION_COMPONENT_DATA BusKey)
+{
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCONFIGURATION_COMPONENT_DATA ControllerKey;
+ PCONFIGURATION_COMPONENT_DATA PeripheralKey;
+ ULONG Size;
+
+ if (DetectPS2AuxPort())
+ {
+ TRACE("Detected PS2 port\n");
+
+ PartialResourceList = FrLdrHeapAlloc(sizeof(CM_PARTIAL_RESOURCE_LIST), TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ return;
+ }
+ memset(PartialResourceList, 0, sizeof(CM_PARTIAL_RESOURCE_LIST));
+
+ /* Initialize resource descriptor */
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 1;
+
+ /* Set Interrupt */
+ PartialResourceList->PartialDescriptors[0].Type = CmResourceTypeInterrupt;
+ PartialResourceList->PartialDescriptors[0].ShareDisposition = CmResourceShareUndetermined;
+ PartialResourceList->PartialDescriptors[0].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
+ PartialResourceList->PartialDescriptors[0].u.Interrupt.Level = 12;
+ PartialResourceList->PartialDescriptors[0].u.Interrupt.Vector = 12;
+ PartialResourceList->PartialDescriptors[0].u.Interrupt.Affinity = 0xFFFFFFFF;
+
+ /* Create controller key */
+ FldrCreateComponentKey(BusKey,
+ ControllerClass,
+ PointerController,
+ Input,
+ 0x0,
+ 0xFFFFFFFF,
+ NULL,
+ PartialResourceList,
+ sizeof(CM_PARTIAL_RESOURCE_LIST),
+ &ControllerKey);
+ TRACE("Created key: PointerController\\0\n");
+
+ if (DetectPS2AuxDevice())
+ {
+ TRACE("Detected PS2 mouse\n");
+
+ /* Initialize resource descriptor */
+ Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
+ sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ return;
+ }
+ memset(PartialResourceList, 0, Size);
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 0;
+
+ /* Create peripheral key */
+ FldrCreateComponentKey(ControllerKey,
+ ControllerClass,
+ PointerPeripheral,
+ Input,
+ 0x0,
+ 0xFFFFFFFF,
+ "MICROSOFT PS2 MOUSE",
+ PartialResourceList,
+ Size,
+ &PeripheralKey);
+ TRACE("Created key: PointerPeripheral\\0\n");
+ }
+ }
+}
+
+static VOID
+DetectDisplayController(PCONFIGURATION_COMPONENT_DATA BusKey)
+{
+ CHAR Buffer[80];
+ PCONFIGURATION_COMPONENT_DATA ControllerKey;
+ USHORT VesaVersion;
+
+ /* FIXME: Set 'ComponentInformation' value */
+
+ VesaVersion = BiosIsVesaSupported();
+ if (VesaVersion != 0)
+ {
+ TRACE("VESA version %c.%c\n",
+ (VesaVersion >> 8) + '0',
+ (VesaVersion & 0xFF) + '0');
+ }
+ else
+ {
+ TRACE("VESA not supported\n");
+ }
+
+ if (VesaVersion >= 0x0200)
+ {
+ strcpy(Buffer, "VBE Display");
+ }
+ else
+ {
+ strcpy(Buffer, "VGA Display");
+ }
+
+ FldrCreateComponentKey(BusKey,
+ ControllerClass,
+ DisplayController,
+ 0x0,
+ 0x0,
+ 0xFFFFFFFF,
+ Buffer,
+ NULL,
+ 0,
+ &ControllerKey);
+ TRACE("Created key: DisplayController\\0\n");
+
+ /* FIXME: Add display peripheral (monitor) data */
+ if (VesaVersion != 0)
+ {
+ if (BiosIsVesaDdcSupported())
+ {
+ TRACE("VESA/DDC supported!\n");
+ if (BiosVesaReadEdid())
+ {
+ TRACE("EDID data read successfully!\n");
+
+ }
+ }
+ }
+}
+
+extern VOID
+DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA BusKey);
+
+static
+VOID
+DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
+{
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCONFIGURATION_COMPONENT_DATA BusKey;
+ ULONG Size;
+
+ /* Set 'Configuration Data' value */
+ Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
+ sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ return;
+ }
+
+ /* Initialize resource descriptor */
+ memset(PartialResourceList, 0, Size);
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 0;
+
+ /* Create new bus key */
+ FldrCreateComponentKey(SystemKey,
+ AdapterClass,
+ MultiFunctionAdapter,
+ 0x0,
+ 0x0,
+ 0xFFFFFFFF,
+ "ISA",
+ PartialResourceList,
+ Size,
+ &BusKey);
+
+ /* Increment bus number */
+ (*BusNumber)++;
+
+ /* Detect ISA/BIOS devices */
+ DetectBiosDisks(BusKey);
+ DetectSerialPorts(BusKey);
+ DetectParallelPorts(BusKey);
+ DetectKeyboardController(BusKey);
+ DetectPS2Mouse(BusKey);
+ DetectDisplayController(BusKey);
+
+ /* FIXME: Detect more ISA devices */
+}
+
+extern PCONFIGURATION_COMPONENT_DATA
+DetectSystem(VOID);
+
+PCONFIGURATION_COMPONENT_DATA
+PcHwDetect(VOID)
+{
+ PCONFIGURATION_COMPONENT_DATA SystemKey;
+ ULONG BusNumber = 0;
+
+ TRACE("DetectHardware()\n");
+
+ /* Create the 'System' key */
+ SystemKey = DetectSystem();
+
+ /* Detect buses */
+ DetectPciBios(SystemKey, &BusNumber);
+ DetectApmBios(SystemKey, &BusNumber);
+ DetectPnpBios(SystemKey, &BusNumber);
+ DetectIsaBios(SystemKey, &BusNumber); // TODO: Detect first EISA or MCA, before ISA
+ DetectAcpiBios(SystemKey, &BusNumber);
+
+ TRACE("DetectHardware() Done\n");
+ return SystemKey;
+}
+
+VOID
+PcHwIdle(VOID)
+{
+ REGS Regs;
+
+ /* Select APM 1.0+ function */
+ Regs.b.ah = 0x53;
+
+ /* Function 05h: CPU idle */
+ Regs.b.al = 0x05;
+
+ /* Call INT 15h */
+ Int386(0x15, &Regs, &Regs);
+
+ /* Check if successfull (CF set on error) */
+ if (INT386_SUCCESS(Regs))
+ return;
+
+ /*
+ * No futher processing here.
+ * Optionally implement HLT instruction handling.
+ */
+}
+
+
+/******************************************************************************/
VOID
PcMachInit(const char *CmdLine)
VOID
PcPrepareForReactOS(IN BOOLEAN Setup)
{
- //
- // On PC, prepare video and turn off the floppy motor
- //
+ /* On PC, prepare video and turn off the floppy motor */
PcVideoPrepareForReactOS(Setup);
DiskStopFloppyMotor();
}
+
/* EOF */
#include <freeldr.h>
+#define NDEBUG
+#include <debug.h>
+
+DBG_DEFAULT_CHANNEL(HWDETECT);
+
+
+static CHAR Hex[] = "0123456789ABCDEF";
+
+extern ULONG reactos_disk_count;
+extern ARC_DISK_SIGNATURE_EX reactos_arc_disk_info[];
+
+typedef struct tagDISKCONTEXT
+{
+ UCHAR DriveNumber;
+ ULONG SectorSize;
+ ULONGLONG SectorOffset;
+ ULONGLONG SectorCount;
+ ULONGLONG SectorNumber;
+} DISKCONTEXT;
+
+
+
+// NOTE: Similar to hardware.c!PcGetHarddiskConfigurationData(),
+// but without extended geometry support.
+static
+PCM_PARTIAL_RESOURCE_LIST
+XboxGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
+{
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
+ //EXTENDED_GEOMETRY ExtGeometry;
+ GEOMETRY Geometry;
+ ULONG Size;
+
+ //
+ // Initialize returned size
+ //
+ *pSize = 0;
+
+ /* Set 'Configuration Data' value */
+ Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
+ sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate a full resource descriptor\n");
+ return NULL;
+ }
+
+ memset(PartialResourceList, 0, Size);
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 1;
+ PartialResourceList->PartialDescriptors[0].Type =
+ CmResourceTypeDeviceSpecific;
+// PartialResourceList->PartialDescriptors[0].ShareDisposition =
+// PartialResourceList->PartialDescriptors[0].Flags =
+ PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
+ sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
+
+ /* Get pointer to geometry data */
+ DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
+
+ /* Get the disk geometry */
+ //ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
+
+ if (MachDiskGetDriveGeometry(DriveNumber, &Geometry))
+ {
+ DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
+ DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
+ DiskGeometry->SectorsPerTrack = Geometry.Sectors;
+ DiskGeometry->NumberOfHeads = Geometry.Heads;
+ }
+ else
+ {
+ ERR("Reading disk geometry failed\n");
+ FrLdrHeapFree(PartialResourceList, TAG_HW_RESOURCE_LIST);
+ return NULL;
+ }
+ TRACE("Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
+ DriveNumber,
+ DiskGeometry->NumberOfCylinders,
+ DiskGeometry->NumberOfHeads,
+ DiskGeometry->SectorsPerTrack,
+ DiskGeometry->BytesPerSector);
+
+ //
+ // Return configuration data
+ //
+ *pSize = Size;
+ return PartialResourceList;
+}
+
+#define GetHarddiskConfigurationData XboxGetHarddiskConfigurationData
+
+
+extern ARC_STATUS
+DiskClose(ULONG FileId);
+
+extern ARC_STATUS
+DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information);
+
+static
+ARC_STATUS
+DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
+{
+ DISKCONTEXT* Context;
+ ULONG DrivePartition, SectorSize;
+ UCHAR DriveNumber;
+ ULONGLONG SectorOffset = 0;
+ ULONGLONG SectorCount = 0;
+ PARTITION_TABLE_ENTRY PartitionTableEntry;
+ CHAR FileName[1];
+
+ if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition))
+ return EINVAL;
+
+ if (DrivePartition == 0xff)
+ {
+ /* This is a CD-ROM device */
+ SectorSize = 2048;
+ }
+ else
+ {
+ /* This is either a floppy disk device (DrivePartition == 0) or
+ * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but
+ * it doesn't matter which one because they both have 512 bytes per sector */
+ SectorSize = 512;
+ }
+
+ if (DrivePartition != 0xff && DrivePartition != 0)
+ {
+ if (!XboxDiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
+ return EINVAL;
+ SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
+ SectorCount = PartitionTableEntry.PartitionSectorCount;
+ }
+ else
+ {
+ SectorCount = 0; /* FIXME */
+ }
+
+ Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
+ if (!Context)
+ return ENOMEM;
+ Context->DriveNumber = DriveNumber;
+ Context->SectorSize = SectorSize;
+ Context->SectorOffset = SectorOffset;
+ Context->SectorCount = SectorCount;
+ Context->SectorNumber = 0;
+ FsSetDeviceSpecific(*FileId, Context);
+
+ return ESUCCESS;
+}
+
+extern ARC_STATUS
+DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count);
+
+extern ARC_STATUS
+DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode);
+
+static const DEVVTBL DiskVtbl =
+{
+ DiskClose,
+ DiskGetFileInformation,
+ DiskOpen,
+ DiskRead,
+ DiskSeek,
+};
+
+static
+VOID
+GetHarddiskIdentifier(PCHAR Identifier,
+ UCHAR DriveNumber)
+{
+ PMASTER_BOOT_RECORD Mbr;
+ PULONG Buffer;
+ ULONG i;
+ ULONG Checksum;
+ ULONG Signature;
+ CHAR ArcName[MAX_PATH];
+ PARTITION_TABLE_ENTRY PartitionTableEntry;
+
+ /* Read the MBR */
+ if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
+ {
+ ERR("Reading MBR failed\n");
+ return;
+ }
+
+ Buffer = (ULONG*)DiskReadBuffer;
+ Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
+
+ Signature = Mbr->Signature;
+ TRACE("Signature: %x\n", Signature);
+
+ /* Calculate the MBR checksum */
+ Checksum = 0;
+ for (i = 0; i < 512 / sizeof(ULONG); i++)
+ {
+ Checksum += Buffer[i];
+ }
+ Checksum = ~Checksum + 1;
+ TRACE("Checksum: %x\n", Checksum);
+
+ /* Fill out the ARC disk block */
+ reactos_arc_disk_info[reactos_disk_count].DiskSignature.Signature = Signature;
+ reactos_arc_disk_info[reactos_disk_count].DiskSignature.CheckSum = Checksum;
+ sprintf(ArcName, "multi(0)disk(0)rdisk(%lu)", reactos_disk_count);
+ strcpy(reactos_arc_disk_info[reactos_disk_count].ArcName, ArcName);
+ reactos_arc_disk_info[reactos_disk_count].DiskSignature.ArcName =
+ reactos_arc_disk_info[reactos_disk_count].ArcName;
+ reactos_disk_count++;
+
+ sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(0)", DriveNumber - 0x80);
+ FsRegisterDevice(ArcName, &DiskVtbl);
+
+ /* Add partitions */
+ i = 1;
+ DiskReportError(FALSE);
+ while (XboxDiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry))
+ {
+ if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED)
+ {
+ sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(%lu)", DriveNumber - 0x80, i);
+ FsRegisterDevice(ArcName, &DiskVtbl);
+ }
+ i++;
+ }
+ DiskReportError(TRUE);
+
+ /* Convert checksum and signature to identifier string */
+ Identifier[0] = Hex[(Checksum >> 28) & 0x0F];
+ Identifier[1] = Hex[(Checksum >> 24) & 0x0F];
+ Identifier[2] = Hex[(Checksum >> 20) & 0x0F];
+ Identifier[3] = Hex[(Checksum >> 16) & 0x0F];
+ Identifier[4] = Hex[(Checksum >> 12) & 0x0F];
+ Identifier[5] = Hex[(Checksum >> 8) & 0x0F];
+ Identifier[6] = Hex[(Checksum >> 4) & 0x0F];
+ Identifier[7] = Hex[Checksum & 0x0F];
+ Identifier[8] = '-';
+ Identifier[9] = Hex[(Signature >> 28) & 0x0F];
+ Identifier[10] = Hex[(Signature >> 24) & 0x0F];
+ Identifier[11] = Hex[(Signature >> 20) & 0x0F];
+ Identifier[12] = Hex[(Signature >> 16) & 0x0F];
+ Identifier[13] = Hex[(Signature >> 12) & 0x0F];
+ Identifier[14] = Hex[(Signature >> 8) & 0x0F];
+ Identifier[15] = Hex[(Signature >> 4) & 0x0F];
+ Identifier[16] = Hex[Signature & 0x0F];
+ Identifier[17] = '-';
+ Identifier[18] = 'A';
+ Identifier[19] = 0;
+ TRACE("Identifier: %s\n", Identifier);
+}
+
+static
+VOID
+DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
+ PCONFIGURATION_COMPONENT_DATA BusKey)
+{
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCM_INT13_DRIVE_PARAMETER Int13Drives;
+ GEOMETRY Geometry;
+ PCONFIGURATION_COMPONENT_DATA DiskKey, ControllerKey;
+ UCHAR DiskCount;
+ ULONG i;
+ ULONG Size;
+ BOOLEAN Changed;
+
+ /* Count the number of visible drives */
+ DiskReportError(FALSE);
+ DiskCount = 0;
+
+ /* There are some really broken BIOSes out there. There are even BIOSes
+ * that happily report success when you ask them to read from non-existent
+ * harddisks. So, we set the buffer to known contents first, then try to
+ * read. If the BIOS reports success but the buffer contents haven't
+ * changed then we fail anyway */
+ memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
+ while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, DiskReadBuffer))
+ {
+ Changed = FALSE;
+ for (i = 0; ! Changed && i < DiskReadBufferSize; i++)
+ {
+ Changed = ((PUCHAR)DiskReadBuffer)[i] != 0xcd;
+ }
+ if (! Changed)
+ {
+ TRACE("BIOS reports success for disk %d but data didn't change\n",
+ (int)DiskCount);
+ break;
+ }
+ DiskCount++;
+ memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
+ }
+ DiskReportError(TRUE);
+ TRACE("BIOS reports %d harddisk%s\n",
+ (int)DiskCount, (DiskCount == 1) ? "" : "s");
+
+ //DetectBiosFloppyController(BusKey);
+
+ /* Allocate resource descriptor */
+ Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
+ sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ ERR("Failed to allocate resource descriptor\n");
+ return;
+ }
+
+ /* Initialize resource descriptor */
+ memset(PartialResourceList, 0, Size);
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 1;
+ PartialResourceList->PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific;
+ PartialResourceList->PartialDescriptors[0].ShareDisposition = 0;
+ PartialResourceList->PartialDescriptors[0].Flags = 0;
+ PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
+ sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
+
+ /* Get harddisk Int13 geometry data */
+ Int13Drives = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
+ for (i = 0; i < DiskCount; i++)
+ {
+ if (MachDiskGetDriveGeometry(0x80 + i, &Geometry))
+ {
+ Int13Drives[i].DriveSelect = 0x80 + i;
+ Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
+ Int13Drives[i].SectorsPerTrack = (USHORT)Geometry.Sectors;
+ Int13Drives[i].MaxHeads = (USHORT)Geometry.Heads - 1;
+ Int13Drives[i].NumberDrives = DiskCount;
+
+ TRACE(
+ "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
+ 0x80 + i,
+ Geometry.Cylinders - 1,
+ Geometry.Heads - 1,
+ Geometry.Sectors,
+ Geometry.BytesPerSector);
+ }
+ }
+
+ FldrCreateComponentKey(BusKey,
+ ControllerClass,
+ DiskController,
+ Output | Input,
+ 0,
+ 0xFFFFFFFF,
+ NULL,
+ PartialResourceList,
+ Size,
+ &ControllerKey);
+ TRACE("Created key: DiskController\\0\n");
+
+ /* Create and fill subkey for each harddisk */
+ for (i = 0; i < DiskCount; i++)
+ {
+ CHAR Identifier[20];
+
+ /* Get disk values */
+ PartialResourceList = GetHarddiskConfigurationData(0x80 + i, &Size);
+ GetHarddiskIdentifier(Identifier, 0x80 + i);
+
+ /* Create disk key */
+ FldrCreateComponentKey(ControllerKey,
+ PeripheralClass,
+ DiskPeripheral,
+ Output | Input,
+ 0,
+ 0xFFFFFFFF,
+ Identifier,
+ PartialResourceList,
+ Size,
+ &DiskKey);
+ }
+}
+
+BOOLEAN
+XboxInitializeBootDevices(VOID)
+{
+ // Emulate old behavior
+ return XboxHwDetect() != NULL;
+}
+
+
+
+
+static
+VOID
+DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
+{
+ PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+ PCONFIGURATION_COMPONENT_DATA BusKey;
+ ULONG Size;
+
+ /* Set 'Configuration Data' value */
+ Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
+ sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+ PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+ if (PartialResourceList == NULL)
+ {
+ TRACE("Failed to allocate resource descriptor\n");
+ return;
+ }
+
+ /* Initialize resource descriptor */
+ memset(PartialResourceList, 0, Size);
+ PartialResourceList->Version = 1;
+ PartialResourceList->Revision = 1;
+ PartialResourceList->Count = 0;
+
+ /* Create new bus key */
+ FldrCreateComponentKey(SystemKey,
+ AdapterClass,
+ MultiFunctionAdapter,
+ 0x0,
+ 0x0,
+ 0xFFFFFFFF,
+ "ISA",
+ PartialResourceList,
+ Size,
+ &BusKey);
+
+ /* Increment bus number */
+ (*BusNumber)++;
+
+ /* Detect ISA/BIOS devices */
+ DetectBiosDisks(SystemKey, BusKey);
+
+ /* FIXME: Detect more ISA devices */
+}
+
+PCONFIGURATION_COMPONENT_DATA
+XboxHwDetect(VOID)
+{
+ PCONFIGURATION_COMPONENT_DATA SystemKey;
+ ULONG BusNumber = 0;
+
+ TRACE("DetectHardware()\n");
+
+ /* Create the 'System' key */
+ FldrCreateSystemKey(&SystemKey);
+
+ /* TODO: Build actual xbox's hardware configuration tree */
+ DetectIsaBios(SystemKey, &BusNumber);
+
+ TRACE("DetectHardware() Done\n");
+ return SystemKey;
+}
+
+VOID XboxHwIdle(VOID)
+{
+ /* UNIMPLEMENTED */
+}
+
+
+/******************************************************************************/
+
VOID
XboxMachInit(const char *CmdLine)
{
- /* Set LEDs to red before anything is initialized */
- XboxSetLED("rrrr");
-
- /* Initialize our stuff */
- XboxMemInit();
- XboxVideoInit();
-
- /* Setup vtbl */
- MachVtbl.ConsPutChar = XboxConsPutChar;
- MachVtbl.ConsKbHit = XboxConsKbHit;
- MachVtbl.ConsGetCh = XboxConsGetCh;
- MachVtbl.VideoClearScreen = XboxVideoClearScreen;
- MachVtbl.VideoSetDisplayMode = XboxVideoSetDisplayMode;
- MachVtbl.VideoGetDisplaySize = XboxVideoGetDisplaySize;
- MachVtbl.VideoGetBufferSize = XboxVideoGetBufferSize;
- MachVtbl.VideoHideShowTextCursor = XboxVideoHideShowTextCursor;
- MachVtbl.VideoPutChar = XboxVideoPutChar;
- MachVtbl.VideoCopyOffScreenBufferToVRAM = XboxVideoCopyOffScreenBufferToVRAM;
- MachVtbl.VideoIsPaletteFixed = XboxVideoIsPaletteFixed;
- MachVtbl.VideoSetPaletteColor = XboxVideoSetPaletteColor;
- MachVtbl.VideoGetPaletteColor = XboxVideoGetPaletteColor;
- MachVtbl.VideoSync = XboxVideoSync;
- MachVtbl.Beep = PcBeep;
- MachVtbl.PrepareForReactOS = XboxPrepareForReactOS;
- MachVtbl.GetMemoryMap = XboxMemGetMemoryMap;
- MachVtbl.DiskGetBootPath = DiskGetBootPath;
- MachVtbl.DiskReadLogicalSectors = XboxDiskReadLogicalSectors;
- MachVtbl.DiskGetDriveGeometry = XboxDiskGetDriveGeometry;
- MachVtbl.DiskGetCacheableBlockCount = XboxDiskGetCacheableBlockCount;
- MachVtbl.GetTime = XboxGetTime;
- MachVtbl.InitializeBootDevices = XboxInitializeBootDevices;
- MachVtbl.HwDetect = XboxHwDetect;
- MachVtbl.HwIdle = XboxHwIdle;
-
- /* Set LEDs to orange after init */
- XboxSetLED("oooo");
+ /* Set LEDs to red before anything is initialized */
+ XboxSetLED("rrrr");
+
+ /* Initialize our stuff */
+ XboxMemInit();
+ XboxVideoInit();
+
+ /* Setup vtbl */
+ MachVtbl.ConsPutChar = XboxConsPutChar;
+ MachVtbl.ConsKbHit = XboxConsKbHit;
+ MachVtbl.ConsGetCh = XboxConsGetCh;
+ MachVtbl.VideoClearScreen = XboxVideoClearScreen;
+ MachVtbl.VideoSetDisplayMode = XboxVideoSetDisplayMode;
+ MachVtbl.VideoGetDisplaySize = XboxVideoGetDisplaySize;
+ MachVtbl.VideoGetBufferSize = XboxVideoGetBufferSize;
+ MachVtbl.VideoHideShowTextCursor = XboxVideoHideShowTextCursor;
+ MachVtbl.VideoPutChar = XboxVideoPutChar;
+ MachVtbl.VideoCopyOffScreenBufferToVRAM = XboxVideoCopyOffScreenBufferToVRAM;
+ MachVtbl.VideoIsPaletteFixed = XboxVideoIsPaletteFixed;
+ MachVtbl.VideoSetPaletteColor = XboxVideoSetPaletteColor;
+ MachVtbl.VideoGetPaletteColor = XboxVideoGetPaletteColor;
+ MachVtbl.VideoSync = XboxVideoSync;
+ MachVtbl.Beep = PcBeep;
+ MachVtbl.PrepareForReactOS = XboxPrepareForReactOS;
+ MachVtbl.GetMemoryMap = XboxMemGetMemoryMap;
+ MachVtbl.DiskGetBootPath = DiskGetBootPath;
+ MachVtbl.DiskReadLogicalSectors = XboxDiskReadLogicalSectors;
+ MachVtbl.DiskGetDriveGeometry = XboxDiskGetDriveGeometry;
+ MachVtbl.DiskGetCacheableBlockCount = XboxDiskGetCacheableBlockCount;
+ MachVtbl.GetTime = XboxGetTime;
+ MachVtbl.InitializeBootDevices = PcInitializeBootDevices;
+ MachVtbl.HwDetect = XboxHwDetect;
+ MachVtbl.HwIdle = XboxHwIdle;
+
+ /* Set LEDs to orange after init */
+ XboxSetLED("oooo");
}
VOID
XboxPrepareForReactOS(IN BOOLEAN Setup)
{
- //
- // On XBOX, prepare video and turn off the floppy motor
- //
+ /* On XBOX, prepare video and turn off the floppy motor */
XboxVideoPrepareForReactOS(Setup);
DiskStopFloppyMotor();
}
+
+/* EOF */
*/
#include <freeldr.h>
+
+#define NDEBUG
#include <debug.h>
DBG_DEFAULT_CHANNEL(DISK);
#include <pshpack2.h>
typedef struct
{
- UCHAR PacketSize; // 00h - Size of packet (10h or 18h)
- UCHAR Reserved; // 01h - Reserved (0)
- USHORT LBABlockCount; // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
- USHORT TransferBufferOffset; // 04h - Transfer buffer offset (seg:off)
- USHORT TransferBufferSegment; // Transfer buffer segment (seg:off)
- ULONGLONG LBAStartBlock; // 08h - Starting absolute block number
- //ULONGLONG TransferBuffer64; // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
- // used if DWORD at 04h is FFFFh:FFFFh
- // Commented since some earlier BIOSes refuse to work with
- // such extended structure
+ UCHAR PacketSize; // 00h - Size of packet (10h or 18h)
+ UCHAR Reserved; // 01h - Reserved (0)
+ USHORT LBABlockCount; // 02h - Number of blocks to transfer (max 007Fh for Phoenix EDD)
+ USHORT TransferBufferOffset; // 04h - Transfer buffer offset (seg:off)
+ USHORT TransferBufferSegment; // Transfer buffer segment (seg:off)
+ ULONGLONG LBAStartBlock; // 08h - Starting absolute block number
+// ULONGLONG TransferBuffer64; // 10h - (EDD-3.0, optional) 64-bit flat address of transfer buffer
+ // used if DWORD at 04h is FFFFh:FFFFh
+ // Commented since some earlier BIOSes refuse to work with
+ // such extended structure
} I386_DISK_ADDRESS_PACKET, *PI386_DISK_ADDRESS_PACKET;
#include <poppack.h>
-/////////////////////////////////////////////////////////////////////////////////////////////
-// FUNCTIONS
-/////////////////////////////////////////////////////////////////////////////////////////////
+/* FUNCTIONS *****************************************************************/
-static BOOLEAN PcDiskResetController(UCHAR DriveNumber)
+BOOLEAN DiskResetController(UCHAR DriveNumber)
{
- REGS RegsIn;
- REGS RegsOut;
-
- WARN("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
+ REGS RegsIn, RegsOut;
+
+ WARN("DiskResetController(0x%x) DISK OPERATION FAILED -- RESETTING CONTROLLER\n", DriveNumber);
+
+ /*
+ * BIOS Int 13h, function 0 - Reset disk system
+ * AH = 00h
+ * DL = drive (if bit 7 is set both hard disks and floppy disks reset)
+ * Return:
+ * AH = status
+ * CF clear if successful
+ * CF set on error
+ */
RegsIn.b.ah = 0x00;
RegsIn.b.dl = DriveNumber;
- // Reset the disk controller
+ /* Reset the disk controller */
Int386(0x13, &RegsIn, &RegsOut);
return INT386_SUCCESS(RegsOut);
static BOOLEAN PcDiskReadLogicalSectorsLBA(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
- REGS RegsIn;
- REGS RegsOut;
- ULONG RetryCount;
- PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
+ REGS RegsIn, RegsOut;
+ ULONG RetryCount;
+ PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER);
TRACE("PcDiskReadLogicalSectorsLBA() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer);
ASSERT(((ULONG_PTR)Buffer) <= 0xFFFFF);
- // BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
- RegsIn.b.ah = 0x42; // Subfunction 42h
- RegsIn.b.dl = DriveNumber; // Drive number in DL (0 - floppy, 0x80 - harddisk)
- RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> disk address packet
- RegsIn.w.si = BIOSCALLBUFOFFSET;
-
- // Setup disk address packet
- RtlZeroMemory(Packet, sizeof(I386_DISK_ADDRESS_PACKET));
- Packet->PacketSize = sizeof(I386_DISK_ADDRESS_PACKET);
+ /* Setup disk address packet */
+ RtlZeroMemory(Packet, sizeof(*Packet));
+ Packet->PacketSize = sizeof(*Packet);
Packet->Reserved = 0;
Packet->LBABlockCount = (USHORT)SectorCount;
ASSERT(Packet->LBABlockCount == SectorCount);
Packet->TransferBufferSegment = (USHORT)(((ULONG_PTR)Buffer) >> 4);
Packet->LBAStartBlock = SectorNumber;
- // BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
- // Return:
- // CF clear if successful
- // AH = 00h
- // CF set on error
- // AH = error code
- // disk address packet's block count field set to the
- // number of blocks successfully transferred
+ /*
+ * BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ
+ * Return:
+ * CF clear if successful
+ * AH = 00h
+ * CF set on error
+ * AH = error code
+ * Disk address packet's block count field set to the
+ * number of blocks successfully transferred.
+ */
+ RegsIn.b.ah = 0x42; // Subfunction 42h
+ RegsIn.b.dl = DriveNumber; // Drive number in DL (0 - floppy, 0x80 - harddisk)
+ RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> disk address packet
+ RegsIn.w.si = BIOSCALLBUFOFFSET;
- // Retry 3 times
+ /* Retry 3 times */
for (RetryCount=0; RetryCount<3; RetryCount++)
{
Int386(0x13, &RegsIn, &RegsOut);
- // If it worked return TRUE
+ /* If it worked return TRUE */
if (INT386_SUCCESS(RegsOut))
{
return TRUE;
}
- // If it was a corrected ECC error then the data is still good
+ /* If it was a corrected ECC error then the data is still good */
else if (RegsOut.b.ah == 0x11)
{
return TRUE;
}
- // If it failed then do the next retry
+ /* If it failed then do the next retry */
else
{
- PcDiskResetController(DriveNumber);
+ DiskResetController(DriveNumber);
continue;
}
}
- // If we get here then the read failed
+ /* If we get here then the read failed */
ERR("Disk Read Failed in LBA mode: %x (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n", RegsOut.b.ah, DriveNumber, SectorNumber, SectorCount);
return FALSE;
static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
- UCHAR PhysicalSector;
- UCHAR PhysicalHead;
- ULONG PhysicalTrack;
- GEOMETRY DriveGeometry;
- ULONG NumberOfSectorsToRead;
- REGS RegsIn;
- REGS RegsOut;
- ULONG RetryCount;
+ UCHAR PhysicalSector;
+ UCHAR PhysicalHead;
+ ULONG PhysicalTrack;
+ GEOMETRY DriveGeometry;
+ ULONG NumberOfSectorsToRead;
+ REGS RegsIn, RegsOut;
+ ULONG RetryCount;
TRACE("PcDiskReadLogicalSectorsCHS()\n");
- //
- // Get the drive geometry
- //
+ /* Get the drive geometry */
if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry) ||
DriveGeometry.Sectors == 0 ||
DriveGeometry.Heads == 0)
while (SectorCount)
{
-
- //
- // Calculate the physical disk offsets
- // Note: DriveGeometry.Sectors < 64
- //
+ /*
+ * Calculate the physical disk offsets.
+ * Note: DriveGeometry.Sectors < 64
+ */
PhysicalSector = 1 + (UCHAR)(SectorNumber % DriveGeometry.Sectors);
PhysicalHead = (UCHAR)((SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads);
PhysicalTrack = (ULONG)((SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads);
- //
- // Calculate how many sectors we need to read this round
- //
+ /* Calculate how many sectors we need to read this round */
if (PhysicalSector > 1)
{
if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
NumberOfSectorsToRead = SectorCount;
}
- //
- // Make sure the read is within the geometry boundaries
- //
+ /* Make sure the read is within the geometry boundaries */
if ((PhysicalHead >= DriveGeometry.Heads) ||
(PhysicalTrack >= DriveGeometry.Cylinders) ||
((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
return FALSE;
}
- // BIOS Int 13h, function 2 - Read Disk Sectors
- // AH = 02h
- // AL = number of sectors to read (must be nonzero)
- // CH = low eight bits of cylinder number
- // CL = sector number 1-63 (bits 0-5)
- // high two bits of cylinder (bits 6-7, hard disk only)
- // DH = head number
- // DL = drive number (bit 7 set for hard disk)
- // ES:BX -> data buffer
- // Return:
- // CF set on error
- // if AH = 11h (corrected ECC error), AL = burst length
- // CF clear if successful
- // AH = status
- // AL = number of sectors transferred
- // (only valid if CF set for some BIOSes)
+ /*
+ * BIOS Int 13h, function 2 - Read Disk Sectors
+ * AH = 02h
+ * AL = number of sectors to read (must be nonzero)
+ * CH = low eight bits of cylinder number
+ * CL = sector number 1-63 (bits 0-5)
+ * high two bits of cylinder (bits 6-7, hard disk only)
+ * DH = head number
+ * DL = drive number (bit 7 set for hard disk)
+ * ES:BX -> data buffer
+ * Return:
+ * CF set on error
+ * if AH = 11h (corrected ECC error), AL = burst length
+ * CF clear if successful
+ * AH = status
+ * AL = number of sectors transferred
+ * (only valid if CF set for some BIOSes)
+ */
RegsIn.b.ah = 0x02;
RegsIn.b.al = (UCHAR)NumberOfSectorsToRead;
RegsIn.b.ch = (PhysicalTrack & 0xFF);
RegsIn.w.es = (USHORT)(((ULONG_PTR)Buffer) >> 4);
RegsIn.w.bx = ((ULONG_PTR)Buffer) & 0x0F;
- //
- // Perform the read
- // Retry 3 times
- //
+ /* Perform the read. Retry 3 times. */
for (RetryCount=0; RetryCount<3; RetryCount++)
{
Int386(0x13, &RegsIn, &RegsOut);
- // If it worked break out
+ /* If it worked break out */
if (INT386_SUCCESS(RegsOut))
{
break;
}
- // If it was a corrected ECC error then the data is still good
+ /* If it was a corrected ECC error then the data is still good */
else if (RegsOut.b.ah == 0x11)
{
break;
}
- // If it failed the do the next retry
+ /* If it failed the do the next retry */
else
{
- PcDiskResetController(DriveNumber);
-
+ DiskResetController(DriveNumber);
continue;
}
}
- // If we retried 3 times then fail
+ /* If we retried 3 times then fail */
if (RetryCount >= 3)
{
ERR("Disk Read Failed in CHS mode, after retrying 3 times: %x\n", RegsOut.b.ah);
return FALSE;
}
- // I have learned that not all bioses return
+ // I have learned that not all BIOSes return
// the sector read count in the AL register (at least mine doesn't)
// even if the sectors were read correctly. So instead
// of checking the sector read count we will rely solely
return TRUE;
}
+static BOOLEAN DiskInt13ExtensionsSupported(UCHAR DriveNumber)
+{
+ static UCHAR LastDriveNumber = 0xff;
+ static BOOLEAN LastSupported;
+ REGS RegsIn, RegsOut;
+
+ TRACE("DiskInt13ExtensionsSupported()\n");
+
+ if (DriveNumber == LastDriveNumber)
+ {
+ TRACE("Using cached value %s for drive 0x%x\n",
+ LastSupported ? "TRUE" : "FALSE", DriveNumber);
+ return LastSupported;
+ }
+
+ /*
+ * Some BIOSes report that extended disk access functions are not supported
+ * when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping
+ * with Intel Macs). Therefore we just return TRUE if we're booting from a CD -
+ * we can assume that all El Torito capable BIOSes support INT 13 extensions.
+ * We simply detect whether we're booting from CD by checking whether the drive
+ * number is >= 0x8A. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes.
+ */
+ if (DriveNumber >= 0x8A)
+ {
+ LastSupported = TRUE;
+ return TRUE;
+ }
+
+ LastDriveNumber = DriveNumber;
+
+ /*
+ * IBM/MS INT 13 Extensions - INSTALLATION CHECK
+ * AH = 41h
+ * BX = 55AAh
+ * DL = drive (80h-FFh)
+ * Return:
+ * CF set on error (extensions not supported)
+ * AH = 01h (invalid function)
+ * CF clear if successful
+ * BX = AA55h if installed
+ * AH = major version of extensions
+ * 01h = 1.x
+ * 20h = 2.0 / EDD-1.0
+ * 21h = 2.1 / EDD-1.1
+ * 30h = EDD-3.0
+ * AL = internal use
+ * CX = API subset support bitmap
+ * DH = extension version (v2.0+ ??? -- not present in 1.x)
+ *
+ * Bitfields for IBM/MS INT 13 Extensions API support bitmap
+ * Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported
+ * Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported
+ * Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
+ * extended drive parameter table is valid
+ * Bits 3-15 reserved
+ */
+ RegsIn.b.ah = 0x41;
+ RegsIn.w.bx = 0x55AA;
+ RegsIn.b.dl = DriveNumber;
+
+ /* Reset the disk controller */
+ Int386(0x13, &RegsIn, &RegsOut);
+
+ if (!INT386_SUCCESS(RegsOut))
+ {
+ /* CF set on error (extensions not supported) */
+ LastSupported = FALSE;
+ return FALSE;
+ }
+
+ if (RegsOut.w.bx != 0xAA55)
+ {
+ /* BX = AA55h if installed */
+ LastSupported = FALSE;
+ return FALSE;
+ }
+
+ if (!(RegsOut.w.cx & 0x0001))
+ {
+ /*
+ * CX = API subset support bitmap.
+ * Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported.
+ */
+ DbgPrint("Suspicious API subset support bitmap 0x%x on device 0x%lx\n",
+ RegsOut.w.cx, DriveNumber);
+ LastSupported = FALSE;
+ return FALSE;
+ }
+
+ LastSupported = TRUE;
+ return TRUE;
+}
+
BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
BOOLEAN ExtensionsSupported;
- TRACE("PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer);
+ TRACE("PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n",
+ DriveNumber, SectorNumber, SectorCount, Buffer);
- //
- // Check to see if it is a fixed disk drive
- // If so then check to see if Int13 extensions work
- // If they do then use them, otherwise default back to BIOS calls
- //
+ /*
+ * Check to see if it is a fixed disk drive.
+ * If so then check to see if Int13 extensions work.
+ * If they do then use them, otherwise default back to BIOS calls.
+ */
ExtensionsSupported = DiskInt13ExtensionsSupported(DriveNumber);
if ((DriveNumber >= 0x80) && ExtensionsSupported)
{
TRACE("Using Int 13 Extensions for read. DiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, ExtensionsSupported ? "TRUE" : "FALSE");
- //
- // LBA is easy, nothing to calculate
- // Just do the read
- //
+ /* LBA is easy, nothing to calculate. Just do the read. */
return PcDiskReadLogicalSectorsLBA(DriveNumber, SectorNumber, SectorCount, Buffer);
}
else
{
- // LBA is not supported default to the CHS calls
+ /* LBA is not supported default to the CHS calls */
return PcDiskReadLogicalSectorsCHS(DriveNumber, SectorNumber, SectorCount, Buffer);
}
return TRUE;
}
+VOID DiskStopFloppyMotor(VOID)
+{
+ WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0);
+}
+
+BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize)
+{
+ REGS RegsIn, RegsOut;
+ PUSHORT Ptr = (PUSHORT)(BIOSCALLBUFFER);
+
+ TRACE("DiskGetExtendedDriveParameters()\n");
+
+ if (!DiskInt13ExtensionsSupported(DriveNumber))
+ return FALSE;
+
+ /* Initialize transfer buffer */
+ *Ptr = BufferSize;
+
+ /*
+ * BIOS Int 13h, function 48h - Get drive parameters
+ * AH = 48h
+ * DL = drive (bit 7 set for hard disk)
+ * DS:SI = result buffer
+ * Return:
+ * CF set on error
+ * AH = status (07h)
+ * CF clear if successful
+ * AH = 00h
+ * DS:SI -> result buffer
+ */
+ RegsIn.b.ah = 0x48;
+ RegsIn.b.dl = DriveNumber;
+ RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> result buffer
+ RegsIn.w.si = BIOSCALLBUFOFFSET;
+
+ /* Get drive parameters */
+ Int386(0x13, &RegsIn, &RegsOut);
+ if (!INT386_SUCCESS(RegsOut))
+ return FALSE;
+
+ memcpy(Buffer, Ptr, BufferSize);
+
+#if DBG
+ TRACE("size of buffer: %x\n", Ptr[0]);
+ TRACE("information flags: %x\n", Ptr[1]);
+ TRACE("number of physical cylinders on drive: %u\n", *(PULONG)&Ptr[2]);
+ TRACE("number of physical heads on drive: %u\n", *(PULONG)&Ptr[4]);
+ TRACE("number of physical sectors per track: %u\n", *(PULONG)&Ptr[6]);
+ TRACE("total number of sectors on drive: %I64u\n", *(unsigned long long*)&Ptr[8]);
+ TRACE("bytes per sector: %u\n", Ptr[12]);
+ if (Ptr[0] >= 0x1e)
+ {
+ TRACE("EED configuration parameters: %x:%x\n", Ptr[13], Ptr[14]);
+ if (Ptr[13] != 0xffff && Ptr[14] != 0xffff)
+ {
+ PUCHAR SpecPtr = (PUCHAR)(ULONG_PTR)((Ptr[13] << 4) + Ptr[14]);
+ TRACE("SpecPtr: %x\n", SpecPtr);
+ TRACE("physical I/O port base address: %x\n", *(PUSHORT)&SpecPtr[0]);
+ TRACE("disk-drive control port address: %x\n", *(PUSHORT)&SpecPtr[2]);
+ TRACE("drive flags: %x\n", SpecPtr[4]);
+ TRACE("proprietary information: %x\n", SpecPtr[5]);
+ TRACE("IRQ for drive: %u\n", SpecPtr[6]);
+ TRACE("sector count for multi-sector transfers: %u\n", SpecPtr[7]);
+ TRACE("DMA control: %x\n", SpecPtr[8]);
+ TRACE("programmed I/O control: %x\n", SpecPtr[9]);
+ TRACE("drive options: %x\n", *(PUSHORT)&SpecPtr[10]);
+ }
+ }
+ if (Ptr[0] >= 0x42)
+ {
+ TRACE("signature: %x\n", Ptr[15]);
+ }
+#endif
+
+ return TRUE;
+}
+
BOOLEAN
PcDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
{
- EXTENDED_GEOMETRY ExtGeometry;
- REGS RegsIn;
- REGS RegsOut;
- ULONG Cylinders;
-
- TRACE("DiskGetDriveGeometry()\n");
-
- /* Try to get the extended geometry first */
- ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
- if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
- {
- Geometry->Cylinders = ExtGeometry.Cylinders;
- Geometry->Heads = ExtGeometry.Heads;
- Geometry->Sectors = ExtGeometry.SectorsPerTrack;
- Geometry->BytesPerSector = ExtGeometry.BytesPerSector;
+ EXTENDED_GEOMETRY ExtGeometry;
+ REGS RegsIn, RegsOut;
+ ULONG Cylinders;
- return TRUE;
- }
-
- /* BIOS Int 13h, function 08h - Get drive parameters
- * AH = 08h
- * DL = drive (bit 7 set for hard disk)
- * ES:DI = 0000h:0000h to guard against BIOS bugs
- * Return:
- * CF set on error
- * AH = status (07h)
- * CF clear if successful
- * AH = 00h
- * AL = 00h on at least some BIOSes
- * BL = drive type (AT/PS2 floppies only)
- * CH = low eight bits of maximum cylinder number
- * CL = maximum sector number (bits 5-0)
- * high two bits of maximum cylinder number (bits 7-6)
- * DH = maximum head number
- * DL = number of drives
- * ES:DI -> drive parameter table (floppies only)
- */
- RegsIn.b.ah = 0x08;
- RegsIn.b.dl = DriveNumber;
- RegsIn.w.es = 0x0000;
- RegsIn.w.di = 0x0000;
-
- /* Get drive parameters */
- Int386(0x13, &RegsIn, &RegsOut);
-
- if (! INT386_SUCCESS(RegsOut))
+ TRACE("DiskGetDriveGeometry()\n");
+
+ /* Try to get the extended geometry first */
+ ExtGeometry.Size = sizeof(ExtGeometry);
+ if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
{
- return FALSE;
+ Geometry->Cylinders = ExtGeometry.Cylinders;
+ Geometry->Heads = ExtGeometry.Heads;
+ Geometry->Sectors = ExtGeometry.SectorsPerTrack;
+ Geometry->BytesPerSector = ExtGeometry.BytesPerSector;
+ return TRUE;
}
- Cylinders = (RegsOut.b.cl & 0xC0) << 2;
- Cylinders += RegsOut.b.ch;
- Cylinders++;
- Geometry->Cylinders = Cylinders;
- Geometry->Heads = RegsOut.b.dh + 1;
- Geometry->Sectors = RegsOut.b.cl & 0x3F;
- Geometry->BytesPerSector = 512; /* Just assume 512 bytes per sector */
+ /*
+ * BIOS Int 13h, function 08h - Get drive parameters
+ * AH = 08h
+ * DL = drive (bit 7 set for hard disk)
+ * ES:DI = 0000h:0000h to guard against BIOS bugs
+ * Return:
+ * CF set on error
+ * AH = status (07h)
+ * CF clear if successful
+ * AH = 00h
+ * AL = 00h on at least some BIOSes
+ * BL = drive type (AT/PS2 floppies only)
+ * CH = low eight bits of maximum cylinder number
+ * CL = maximum sector number (bits 5-0)
+ * high two bits of maximum cylinder number (bits 7-6)
+ * DH = maximum head number
+ * DL = number of drives
+ * ES:DI -> drive parameter table (floppies only)
+ */
+ RegsIn.b.ah = 0x08;
+ RegsIn.b.dl = DriveNumber;
+ RegsIn.w.es = 0x0000;
+ RegsIn.w.di = 0x0000;
- return TRUE;
+ /* Get drive parameters */
+ Int386(0x13, &RegsIn, &RegsOut);
+ if (!INT386_SUCCESS(RegsOut))
+ return FALSE;
+
+ Cylinders = (RegsOut.b.cl & 0xC0) << 2;
+ Cylinders += RegsOut.b.ch;
+ Cylinders++;
+ Geometry->Cylinders = Cylinders;
+ Geometry->Heads = RegsOut.b.dh + 1;
+ Geometry->Sectors = RegsOut.b.cl & 0x3F;
+ Geometry->BytesPerSector = 512; /* Just assume 512 bytes per sector */
+
+ return TRUE;
}
ULONG
PcDiskGetCacheableBlockCount(UCHAR DriveNumber)
{
- GEOMETRY Geometry;
+ GEOMETRY Geometry;
- /* If LBA is supported then the block size will be 64 sectors (32k)
- * If not then the block size is the size of one track */
- if (DiskInt13ExtensionsSupported(DriveNumber))
+ /* If LBA is supported then the block size will be 64 sectors (32k)
+ * If not then the block size is the size of one track. */
+ if (DiskInt13ExtensionsSupported(DriveNumber))
{
- return 64;
+ return 64;
}
- /* Get the disk geometry
- * If this fails then we will just return 1 sector to be safe */
- else if (! PcDiskGetDriveGeometry(DriveNumber, &Geometry))
+ /* Get the disk geometry. If this fails then we will
+ * just return 1 sector to be safe. */
+ else if (! PcDiskGetDriveGeometry(DriveNumber, &Geometry))
{
- return 1;
+ return 1;
}
- else
+ else
{
- return Geometry.Sectors;
+ return Geometry.Sectors;
}
}
static struct
{
- ULONG SectorCountBeforePartition;
- ULONG PartitionSectorCount;
- UCHAR SystemIndicator;
+ ULONG SectorCountBeforePartition;
+ ULONG PartitionSectorCount;
+ UCHAR SystemIndicator;
} XboxPartitions[] =
{
- /* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */
- { 0x0055F400, 0x0098f800, PARTITION_FAT32 }, /* Store, E: */
- { 0x00465400, 0x000FA000, PARTITION_FAT_16 }, /* System, C: */
- { 0x00000400, 0x00177000, PARTITION_FAT_16 }, /* Cache1, X: */
- { 0x00177400, 0x00177000, PARTITION_FAT_16 }, /* Cache2, Y: */
- { 0x002EE400, 0x00177000, PARTITION_FAT_16 } /* Cache3, Z: */
+ /* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */
+ { 0x0055F400, 0x0098f800, PARTITION_FAT32 }, /* Store , E: */
+ { 0x00465400, 0x000FA000, PARTITION_FAT_16 }, /* System, C: */
+ { 0x00000400, 0x00177000, PARTITION_FAT_16 }, /* Cache1, X: */
+ { 0x00177400, 0x00177000, PARTITION_FAT_16 }, /* Cache2, Y: */
+ { 0x002EE400, 0x00177000, PARTITION_FAT_16 } /* Cache3, Z: */
};
-#define IDE_SECTOR_BUF_SZ 512
-#define IDE_MAX_POLL_RETRIES 100000
-#define IDE_MAX_BUSY_RETRIES 50000
+#define IDE_SECTOR_BUF_SZ 512
+#define IDE_MAX_POLL_RETRIES 100000
+#define IDE_MAX_BUSY_RETRIES 50000
/* Control Block offsets and masks */
#define IDE_REG_ALT_STATUS 0x0000
* Each macro takes an address of the command port block, and data
*/
#define IDEReadError(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ERROR)))
+ (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ERROR)))
#define IDEWritePrecomp(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_PRECOMP), (Data)))
+ (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_PRECOMP), (Data)))
#define IDEReadSectorCount(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT)))
+ (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT)))
#define IDEWriteSectorCount(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT), (Data)))
+ (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT), (Data)))
#define IDEReadSectorNum(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM)))
+ (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM)))
#define IDEWriteSectorNum(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM), (Data)))
+ (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM), (Data)))
#define IDEReadCylinderLow(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW)))
+ (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW)))
#define IDEWriteCylinderLow(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW), (Data)))
+ (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW), (Data)))
#define IDEReadCylinderHigh(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH)))
+ (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH)))
#define IDEWriteCylinderHigh(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH), (Data)))
+ (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH), (Data)))
#define IDEReadDriveHead(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD)))
+ (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD)))
#define IDEWriteDriveHead(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD), (Data)))
+ (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD), (Data)))
#define IDEReadStatus(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_STATUS)))
+ (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_STATUS)))
#define IDEWriteCommand(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_COMMAND), (Data)))
+ (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_COMMAND), (Data)))
#define IDEReadDMACommand(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address))))
+ (READ_PORT_UCHAR((PUCHAR)((Address))))
#define IDEWriteDMACommand(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address)), (Data)))
+ (WRITE_PORT_UCHAR((PUCHAR)((Address)), (Data)))
#define IDEReadDMAStatus(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + 2)))
+ (READ_PORT_UCHAR((PUCHAR)((Address) + 2)))
#define IDEWriteDMAStatus(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + 2), (Data)))
+ (WRITE_PORT_UCHAR((PUCHAR)((Address) + 2), (Data)))
#define IDEWritePRDTable(Address, Data) \
- (WRITE_PORT_ULONG((PULONG)((Address) + 4), (Data)))
+ (WRITE_PORT_ULONG((PULONG)((Address) + 4), (Data)))
/*
* Data block read and write commands
*/
#define IDEReadBlock(Address, Buffer, Count) \
- (READ_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
+ (READ_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
#define IDEWriteBlock(Address, Buffer, Count) \
- (WRITE_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
+ (WRITE_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
#define IDEReadBlock32(Address, Buffer, Count) \
- (READ_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
+ (READ_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
#define IDEWriteBlock32(Address, Buffer, Count) \
- (WRITE_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
+ (WRITE_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
#define IDEReadWord(Address) \
- (READ_PORT_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT)))
+ (READ_PORT_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT)))
/*
* Access macros for control registers
* Each macro takes an address of the control port blank and data
*/
#define IDEReadAltStatus(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ALT_STATUS)))
+ (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ALT_STATUS)))
#define IDEWriteDriveControl(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data)))
+ (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data)))
/* IDE_DRIVE_IDENTIFY */
typedef struct _IDE_DRIVE_IDENTIFY
{
- USHORT ConfigBits; /*00*/
- USHORT LogicalCyls; /*01*/
- USHORT Reserved02; /*02*/
- USHORT LogicalHeads; /*03*/
- USHORT BytesPerTrack; /*04*/
- USHORT BytesPerSector; /*05*/
- USHORT SectorsPerTrack; /*06*/
- UCHAR InterSectorGap; /*07*/
- UCHAR InterSectorGapSize;
- UCHAR Reserved08H; /*08*/
- UCHAR BytesInPLO;
- USHORT VendorUniqueCnt; /*09*/
- char SerialNumber[20]; /*10*/
- USHORT ControllerType; /*20*/
- USHORT BufferSize; /*21*/
- USHORT ECCByteCnt; /*22*/
- char FirmwareRev[8]; /*23*/
- char ModelNumber[40]; /*27*/
- USHORT RWMultImplemented; /*47*/
- USHORT DWordIo; /*48*/
- USHORT Capabilities; /*49*/
+ USHORT ConfigBits; /*00*/
+ USHORT LogicalCyls; /*01*/
+ USHORT Reserved02; /*02*/
+ USHORT LogicalHeads; /*03*/
+ USHORT BytesPerTrack; /*04*/
+ USHORT BytesPerSector; /*05*/
+ USHORT SectorsPerTrack; /*06*/
+ UCHAR InterSectorGap; /*07*/
+ UCHAR InterSectorGapSize;
+ UCHAR Reserved08H; /*08*/
+ UCHAR BytesInPLO;
+ USHORT VendorUniqueCnt; /*09*/
+ UCHAR SerialNumber[20]; /*10*/
+ USHORT ControllerType; /*20*/
+ USHORT BufferSize; /*21*/
+ USHORT ECCByteCnt; /*22*/
+ UCHAR FirmwareRev[8]; /*23*/
+ UCHAR ModelNumber[40]; /*27*/
+ USHORT RWMultImplemented; /*47*/
+ USHORT DWordIo; /*48*/
+ USHORT Capabilities; /*49*/
#define IDE_DRID_STBY_SUPPORTED 0x2000
#define IDE_DRID_IORDY_SUPPORTED 0x0800
#define IDE_DRID_IORDY_DISABLE 0x0400
#define IDE_DRID_LBA_SUPPORTED 0x0200
#define IDE_DRID_DMA_SUPPORTED 0x0100
- USHORT Reserved50; /*50*/
- USHORT MinPIOTransTime; /*51*/
- USHORT MinDMATransTime; /*52*/
- USHORT TMFieldsValid; /*53*/
- USHORT TMCylinders; /*54*/
- USHORT TMHeads; /*55*/
- USHORT TMSectorsPerTrk; /*56*/
- USHORT TMCapacityLo; /*57*/
- USHORT TMCapacityHi; /*58*/
- USHORT RWMultCurrent; /*59*/
- USHORT TMSectorCountLo; /*60*/
- USHORT TMSectorCountHi; /*61*/
- USHORT DmaModes; /*62*/
- USHORT MultiDmaModes; /*63*/
- USHORT Reserved64[5]; /*64*/
- USHORT Reserved69[2]; /*69*/
- USHORT Reserved71[4]; /*71*/
- USHORT MaxQueueDepth; /*75*/
- USHORT Reserved76[4]; /*76*/
- USHORT MajorRevision; /*80*/
- USHORT MinorRevision; /*81*/
- USHORT SupportedFeatures82; /*82*/
- USHORT SupportedFeatures83; /*83*/
- USHORT SupportedFeatures84; /*84*/
- USHORT EnabledFeatures85; /*85*/
- USHORT EnabledFeatures86; /*86*/
- USHORT EnabledFeatures87; /*87*/
- USHORT UltraDmaModes; /*88*/
- USHORT Reserved89[11]; /*89*/
- USHORT Max48BitAddress[4]; /*100*/
- USHORT Reserved104[151]; /*104*/
- USHORT Checksum; /*255*/
+ USHORT Reserved50; /*50*/
+ USHORT MinPIOTransTime; /*51*/
+ USHORT MinDMATransTime; /*52*/
+ USHORT TMFieldsValid; /*53*/
+ USHORT TMCylinders; /*54*/
+ USHORT TMHeads; /*55*/
+ USHORT TMSectorsPerTrk; /*56*/
+ USHORT TMCapacityLo; /*57*/
+ USHORT TMCapacityHi; /*58*/
+ USHORT RWMultCurrent; /*59*/
+ USHORT TMSectorCountLo; /*60*/
+ USHORT TMSectorCountHi; /*61*/
+ USHORT DmaModes; /*62*/
+ USHORT MultiDmaModes; /*63*/
+ USHORT Reserved64[5]; /*64*/
+ USHORT Reserved69[2]; /*69*/
+ USHORT Reserved71[4]; /*71*/
+ USHORT MaxQueueDepth; /*75*/
+ USHORT Reserved76[4]; /*76*/
+ USHORT MajorRevision; /*80*/
+ USHORT MinorRevision; /*81*/
+ USHORT SupportedFeatures82; /*82*/
+ USHORT SupportedFeatures83; /*83*/
+ USHORT SupportedFeatures84; /*84*/
+ USHORT EnabledFeatures85; /*85*/
+ USHORT EnabledFeatures86; /*86*/
+ USHORT EnabledFeatures87; /*87*/
+ USHORT UltraDmaModes; /*88*/
+ USHORT Reserved89[11]; /*89*/
+ USHORT Max48BitAddress[4]; /*100*/
+ USHORT Reserved104[151]; /*104*/
+ USHORT Checksum; /*255*/
} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
/* XboxDiskPolledRead
* PASSIVE_LEVEL
*
* ARGUMENTS:
- * ULONG CommandPort Address of command port for drive
- * ULONG ControlPort Address of control port for drive
- * UCHAR PreComp Value to write to precomp register
- * UCHAR SectorCnt Value to write to sectorCnt register
- * UCHAR SectorNum Value to write to sectorNum register
- * UCHAR CylinderLow Value to write to CylinderLow register
- * UCHAR CylinderHigh Value to write to CylinderHigh register
- * UCHAR DrvHead Value to write to Drive/Head register
- * UCHAR Command Value to write to Command register
- * PVOID Buffer Buffer for output data
+ * ULONG CommandPort Address of command port for drive
+ * ULONG ControlPort Address of control port for drive
+ * UCHAR PreComp Value to write to precomp register
+ * UCHAR SectorCnt Value to write to sectorCnt register
+ * UCHAR SectorNum Value to write to sectorNum register
+ * UCHAR CylinderLow Value to write to CylinderLow register
+ * UCHAR CylinderHigh Value to write to CylinderHigh register
+ * UCHAR DrvHead Value to write to Drive/Head register
+ * UCHAR Command Value to write to Command register
+ * PVOID Buffer Buffer for output data
*
* RETURNS:
* BOOLEAN: TRUE success, FALSE error
*/
-
static BOOLEAN
XboxDiskPolledRead(ULONG CommandPort,
ULONG ControlPort,
UCHAR Command,
PVOID Buffer)
{
- ULONG SectorCount = 0;
- ULONG RetryCount;
- BOOLEAN Junk = FALSE;
- UCHAR Status;
+ ULONG SectorCount = 0;
+ ULONG RetryCount;
+ BOOLEAN Junk = FALSE;
+ UCHAR Status;
- /* Wait for BUSY to clear */
- for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
+ /* Wait for BUSY to clear */
+ for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
{
- Status = IDEReadStatus(CommandPort);
- if (!(Status & IDE_SR_BUSY))
- {
- break;
- }
- StallExecutionProcessor(10);
+ Status = IDEReadStatus(CommandPort);
+ if (!(Status & IDE_SR_BUSY))
+ break;
+
+ StallExecutionProcessor(10);
}
- TRACE("status=0x%x\n", Status);
- TRACE("waited %d usecs for busy to clear\n", RetryCount * 10);
- if (RetryCount >= IDE_MAX_BUSY_RETRIES)
+ TRACE("status=0x%x\n", Status);
+ TRACE("waited %d usecs for busy to clear\n", RetryCount * 10);
+ if (RetryCount >= IDE_MAX_BUSY_RETRIES)
{
- WARN("Drive is BUSY for too long\n");
- return FALSE;
+ WARN("Drive is BUSY for too long\n");
+ return FALSE;
}
- /* Write Drive/Head to select drive */
- IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
- StallExecutionProcessor(500);
+ /* Write Drive/Head to select drive */
+ IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
+ StallExecutionProcessor(500);
- /* Disable interrupts */
- IDEWriteDriveControl(ControlPort, IDE_DC_nIEN);
- StallExecutionProcessor(500);
+ /* Disable interrupts */
+ IDEWriteDriveControl(ControlPort, IDE_DC_nIEN);
+ StallExecutionProcessor(500);
- /* Issue command to drive */
- if (DrvHead & IDE_DH_LBA)
+ /* Issue command to drive */
+ if (DrvHead & IDE_DH_LBA)
{
- TRACE("READ:DRV=%d:LBA=1:BLK=%d:SC=0x%x:CM=0x%x\n",
- DrvHead & IDE_DH_DRV1 ? 1 : 0,
- ((DrvHead & 0x0f) << 24) + (CylinderHigh << 16) + (CylinderLow << 8) + SectorNum,
- SectorCnt,
- Command);
+ TRACE("READ:DRV=%d:LBA=1:BLK=%d:SC=0x%x:CM=0x%x\n",
+ DrvHead & IDE_DH_DRV1 ? 1 : 0,
+ ((DrvHead & 0x0f) << 24) + (CylinderHigh << 16) + (CylinderLow << 8) + SectorNum,
+ SectorCnt,
+ Command);
}
- else
+ else
{
- TRACE("READ:DRV=%d:LBA=0:CH=0x%x:CL=0x%x:HD=0x%x:SN=0x%x:SC=0x%x:CM=0x%x\n",
- DrvHead & IDE_DH_DRV1 ? 1 : 0,
- CylinderHigh,
- CylinderLow,
- DrvHead & 0x0f,
- SectorNum,
- SectorCnt,
- Command);
+ TRACE("READ:DRV=%d:LBA=0:CH=0x%x:CL=0x%x:HD=0x%x:SN=0x%x:SC=0x%x:CM=0x%x\n",
+ DrvHead & IDE_DH_DRV1 ? 1 : 0,
+ CylinderHigh,
+ CylinderLow,
+ DrvHead & 0x0f,
+ SectorNum,
+ SectorCnt,
+ Command);
}
- /* Setup command parameters */
- IDEWritePrecomp(CommandPort, PreComp);
- IDEWriteSectorCount(CommandPort, SectorCnt);
- IDEWriteSectorNum(CommandPort, SectorNum);
- IDEWriteCylinderHigh(CommandPort, CylinderHigh);
- IDEWriteCylinderLow(CommandPort, CylinderLow);
- IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
+ /* Setup command parameters */
+ IDEWritePrecomp(CommandPort, PreComp);
+ IDEWriteSectorCount(CommandPort, SectorCnt);
+ IDEWriteSectorNum(CommandPort, SectorNum);
+ IDEWriteCylinderHigh(CommandPort, CylinderHigh);
+ IDEWriteCylinderLow(CommandPort, CylinderLow);
+ IDEWriteDriveHead(CommandPort, IDE_DH_FIXED | DrvHead);
- /* Issue the command */
- IDEWriteCommand(CommandPort, Command);
- StallExecutionProcessor(50);
+ /* Issue the command */
+ IDEWriteCommand(CommandPort, Command);
+ StallExecutionProcessor(50);
- /* wait for DRQ or error */
- for (RetryCount = 0; RetryCount < IDE_MAX_POLL_RETRIES; RetryCount++)
- {
- Status = IDEReadStatus(CommandPort);
- if (!(Status & IDE_SR_BUSY))
+ /* Wait for DRQ or error */
+ for (RetryCount = 0; RetryCount < IDE_MAX_POLL_RETRIES; RetryCount++)
{
- if (Status & IDE_SR_ERR)
- {
- IDEWriteDriveControl(ControlPort, 0);
- StallExecutionProcessor(50);
- IDEReadStatus(CommandPort);
-
- return FALSE;
- }
-
- if (Status & IDE_SR_DRQ)
- {
- break;
- }
- else
+ Status = IDEReadStatus(CommandPort);
+ if (!(Status & IDE_SR_BUSY))
{
- IDEWriteDriveControl(ControlPort, 0);
- StallExecutionProcessor(50);
- IDEReadStatus(CommandPort);
+ if (Status & IDE_SR_ERR)
+ {
+ IDEWriteDriveControl(ControlPort, 0);
+ StallExecutionProcessor(50);
+ IDEReadStatus(CommandPort);
+ return FALSE;
+ }
- return FALSE;
+ if (Status & IDE_SR_DRQ)
+ {
+ break;
+ }
+ else
+ {
+ IDEWriteDriveControl(ControlPort, 0);
+ StallExecutionProcessor(50);
+ IDEReadStatus(CommandPort);
+ return FALSE;
+ }
}
- }
- StallExecutionProcessor(10);
+ StallExecutionProcessor(10);
}
- /* timed out */
- if (RetryCount >= IDE_MAX_POLL_RETRIES)
+ /* Timed out */
+ if (RetryCount >= IDE_MAX_POLL_RETRIES)
{
- IDEWriteDriveControl(ControlPort, 0);
- StallExecutionProcessor(50);
- IDEReadStatus(CommandPort);
-
- return FALSE;
+ IDEWriteDriveControl(ControlPort, 0);
+ StallExecutionProcessor(50);
+ IDEReadStatus(CommandPort);
+ return FALSE;
}
- while (1)
+ while (1)
{
- /* Read data into buffer */
- if (Junk == FALSE)
- {
- IDEReadBlock(CommandPort, Buffer, IDE_SECTOR_BUF_SZ);
- Buffer = (PVOID)((ULONG_PTR)Buffer + IDE_SECTOR_BUF_SZ);
- }
- else
- {
- UCHAR JunkBuffer[IDE_SECTOR_BUF_SZ];
- IDEReadBlock(CommandPort, JunkBuffer, IDE_SECTOR_BUF_SZ);
- }
- SectorCount++;
-
- /* Check for error or more sectors to read */
- for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
- {
- Status = IDEReadStatus(CommandPort);
- if (!(Status & IDE_SR_BUSY))
- {
- if (Status & IDE_SR_ERR)
+ /* Read data into buffer */
+ if (Junk == FALSE)
{
- IDEWriteDriveControl(ControlPort, 0);
- StallExecutionProcessor(50);
- IDEReadStatus(CommandPort);
-
- return FALSE;
+ IDEReadBlock(CommandPort, Buffer, IDE_SECTOR_BUF_SZ);
+ Buffer = (PVOID)((ULONG_PTR)Buffer + IDE_SECTOR_BUF_SZ);
}
- if (Status & IDE_SR_DRQ)
+ else
{
- if (SectorCount >= SectorCnt)
- {
- TRACE("Buffer size exceeded!\n");
- Junk = TRUE;
- }
- break;
+ UCHAR JunkBuffer[IDE_SECTOR_BUF_SZ];
+ IDEReadBlock(CommandPort, JunkBuffer, IDE_SECTOR_BUF_SZ);
}
- else
+ SectorCount++;
+
+ /* Check for error or more sectors to read */
+ for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++)
{
- if (SectorCount > SectorCnt)
+ Status = IDEReadStatus(CommandPort);
+ if (!(Status & IDE_SR_BUSY))
{
- TRACE("Read %lu sectors of junk!\n",
- SectorCount - SectorCnt);
+ if (Status & IDE_SR_ERR)
+ {
+ IDEWriteDriveControl(ControlPort, 0);
+ StallExecutionProcessor(50);
+ IDEReadStatus(CommandPort);
+ return FALSE;
+ }
+ if (Status & IDE_SR_DRQ)
+ {
+ if (SectorCount >= SectorCnt)
+ {
+ TRACE("Buffer size exceeded!\n");
+ Junk = TRUE;
+ }
+ break;
+ }
+ else
+ {
+ if (SectorCount > SectorCnt)
+ {
+ TRACE("Read %lu sectors of junk!\n",
+ SectorCount - SectorCnt);
+ }
+
+ IDEWriteDriveControl(ControlPort, 0);
+ StallExecutionProcessor(50);
+ IDEReadStatus(CommandPort);
+ return TRUE;
+ }
}
- IDEWriteDriveControl(ControlPort, 0);
- StallExecutionProcessor(50);
- IDEReadStatus(CommandPort);
-
- return TRUE;
- }
}
}
- }
}
BOOLEAN
XboxDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
{
- ULONG StartSector;
- UCHAR Count;
+ ULONG StartSector;
+ UCHAR Count;
- if (DriveNumber < 0x80 || 2 <= (DriveNumber & 0x0f))
+ if (DriveNumber < 0x80 || 2 <= (DriveNumber & 0x0f))
{
- /* Xbox has only 1 IDE controller and no floppy */
- WARN("Invalid drive number\n");
- return FALSE;
+ /* Xbox has only 1 IDE controller and no floppy */
+ WARN("Invalid drive number\n");
+ return FALSE;
}
- if (UINT64_C(0) != ((SectorNumber + SectorCount) & UINT64_C(0xfffffffff0000000)))
+ if (UINT64_C(0) != ((SectorNumber + SectorCount) & UINT64_C(0xfffffffff0000000)))
{
- FIXME("48bit LBA required but not implemented\n");
- return FALSE;
+ FIXME("48bit LBA required but not implemented\n");
+ return FALSE;
}
- StartSector = (ULONG) SectorNumber;
- while (0 < SectorCount)
+ StartSector = (ULONG) SectorNumber;
+ while (0 < SectorCount)
{
- Count = (SectorCount <= 255 ? (UCHAR)SectorCount : 255);
- if (! XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
- XBOX_IDE_CONTROL_PORT,
- 0, Count,
- StartSector & 0xff,
- (StartSector >> 8) & 0xff,
- (StartSector >> 16) & 0xff,
- ((StartSector >> 24) & 0x0f) | IDE_DH_LBA |
- (0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
- IDE_CMD_READ,
+ Count = (SectorCount <= 255 ? (UCHAR)SectorCount : 255);
+ if (!XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
+ XBOX_IDE_CONTROL_PORT,
+ 0, Count,
+ StartSector & 0xff,
+ (StartSector >> 8) & 0xff,
+ (StartSector >> 16) & 0xff,
+ ((StartSector >> 24) & 0x0f) | IDE_DH_LBA |
+ (0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
+ IDE_CMD_READ,
Buffer))
{
- return FALSE;
+ return FALSE;
}
- SectorCount -= Count;
- Buffer = (PVOID) ((PCHAR) Buffer + Count * IDE_SECTOR_BUF_SZ);
+ SectorCount -= Count;
+ Buffer = (PVOID) ((PCHAR) Buffer + Count * IDE_SECTOR_BUF_SZ);
}
- return TRUE;
+ return TRUE;
}
BOOLEAN
XboxDiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
{
- UCHAR SectorData[IDE_SECTOR_BUF_SZ];
-
- /* 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))
+ 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 (*((PULONG) SectorData) == XBOX_SIGNATURE)
+ if (*((PULONG) SectorData) == XBOX_SIGNATURE)
{
- memset(PartitionTableEntry, 0, sizeof(PARTITION_TABLE_ENTRY));
- PartitionTableEntry->SystemIndicator = XboxPartitions[PartitionNumber - 1].SystemIndicator;
- PartitionTableEntry->SectorCountBeforePartition = XboxPartitions[PartitionNumber - 1].SectorCountBeforePartition;
- PartitionTableEntry->PartitionSectorCount = XboxPartitions[PartitionNumber - 1].PartitionSectorCount;
- return TRUE;
+ memset(PartitionTableEntry, 0, sizeof(PARTITION_TABLE_ENTRY));
+ PartitionTableEntry->SystemIndicator = XboxPartitions[PartitionNumber - 1].SystemIndicator;
+ PartitionTableEntry->SectorCountBeforePartition = XboxPartitions[PartitionNumber - 1].SectorCountBeforePartition;
+ PartitionTableEntry->PartitionSectorCount = XboxPartitions[PartitionNumber - 1].PartitionSectorCount;
+ return TRUE;
}
}
- /* No magic Xbox partitions. Maybe there's a MBR */
- return DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
+ /* No magic Xbox partitions. Maybe there's a MBR */
+ return DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
}
BOOLEAN
XboxDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
{
- IDE_DRIVE_IDENTIFY DrvParms;
- ULONG i;
- BOOLEAN Atapi;
-
- Atapi = FALSE; /* FIXME */
- /* Get the Drive Identify block from drive or die */
- if (! XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
- XBOX_IDE_CONTROL_PORT,
- 0,
- 1,
- 0,
- 0,
- 0,
- (0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
- (Atapi ? IDE_CMD_IDENT_ATAPI_DRV : IDE_CMD_IDENT_ATA_DRV),
- (PUCHAR) &DrvParms))
+ IDE_DRIVE_IDENTIFY DrvParms;
+ ULONG i;
+ BOOLEAN Atapi;
+
+ Atapi = FALSE; /* FIXME */
+ /* Get the Drive Identify block from drive or die */
+ if (!XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT,
+ XBOX_IDE_CONTROL_PORT,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ (0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1),
+ (Atapi ? IDE_CMD_IDENT_ATAPI_DRV : IDE_CMD_IDENT_ATA_DRV),
+ (PUCHAR) &DrvParms))
{
- ERR("XboxDiskPolledRead() failed\n");
- return FALSE;
+ ERR("XboxDiskPolledRead() failed\n");
+ return FALSE;
}
- Geometry->Cylinders = DrvParms.LogicalCyls;
- Geometry->Heads = DrvParms.LogicalHeads;
- Geometry->Sectors = DrvParms.SectorsPerTrack;
+ Geometry->Cylinders = DrvParms.LogicalCyls;
+ Geometry->Heads = DrvParms.LogicalHeads;
+ Geometry->Sectors = DrvParms.SectorsPerTrack;
- if (! Atapi && 0 != (DrvParms.Capabilities & IDE_DRID_LBA_SUPPORTED))
+ if (! Atapi && 0 != (DrvParms.Capabilities & IDE_DRID_LBA_SUPPORTED))
{
- /* LBA ATA drives always have a sector size of 512 */
- Geometry->BytesPerSector = 512;
+ /* LBA ATA drives always have a sector size of 512 */
+ Geometry->BytesPerSector = 512;
}
- else
+ else
{
- TRACE("BytesPerSector %d\n", DrvParms.BytesPerSector);
- if (DrvParms.BytesPerSector == 0)
+ TRACE("BytesPerSector %d\n", DrvParms.BytesPerSector);
+ if (DrvParms.BytesPerSector == 0)
{
- Geometry->BytesPerSector = 512;
+ Geometry->BytesPerSector = 512;
}
- else
+ else
{
- for (i = 1 << 15; i; i /= 2)
+ for (i = 1 << 15; i; i /= 2)
{
- if (0 != (DrvParms.BytesPerSector & i))
+ if ((DrvParms.BytesPerSector & i) != 0)
{
- Geometry->BytesPerSector = i;
- break;
+ Geometry->BytesPerSector = i;
+ break;
}
}
}
}
- TRACE("Cylinders %d\n", Geometry->Cylinders);
- TRACE("Heads %d\n", Geometry->Heads);
- TRACE("Sectors %d\n", Geometry->Sectors);
- TRACE("BytesPerSector %d\n", Geometry->BytesPerSector);
+ TRACE("Cylinders %d\n", Geometry->Cylinders);
+ TRACE("Heads %d\n", Geometry->Heads);
+ TRACE("Sectors %d\n", Geometry->Sectors);
+ TRACE("BytesPerSector %d\n", Geometry->BytesPerSector);
- return TRUE;
+ return TRUE;
}
ULONG
XboxDiskGetCacheableBlockCount(UCHAR DriveNumber)
{
- /* 64 seems a nice number, it is used by the machpc code for LBA devices */
- return 64;
+ /* 64 seems a nice number, it is used by the machpc code for LBA devices */
+ return 64;
}
/* EOF */
+++ /dev/null
-/*
- * FreeLoader
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <freeldr.h>
-
-#define NDEBUG
-#include <debug.h>
-
-DBG_DEFAULT_CHANNEL(HWDETECT);
-
-static CHAR Hex[] = "0123456789ABCDEF";
-//static unsigned int delay_count = 1;
-
-extern ULONG reactos_disk_count;
-extern ARC_DISK_SIGNATURE_EX reactos_arc_disk_info[];
-
-static
-PCM_PARTIAL_RESOURCE_LIST
-GetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
-{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
- //EXTENDED_GEOMETRY ExtGeometry;
- GEOMETRY Geometry;
- ULONG Size;
-
- //
- // Initialize returned size
- //
- *pSize = 0;
-
- /* Set 'Configuration Data' value */
- Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
- sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
- PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
- if (PartialResourceList == NULL)
- {
- ERR("Failed to allocate a full resource descriptor\n");
- return NULL;
- }
-
- memset(PartialResourceList, 0, Size);
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 1;
- PartialResourceList->PartialDescriptors[0].Type =
- CmResourceTypeDeviceSpecific;
-// PartialResourceList->PartialDescriptors[0].ShareDisposition =
-// PartialResourceList->PartialDescriptors[0].Flags =
- PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
- sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
-
- /* Get pointer to geometry data */
- DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
-
- /* Get the disk geometry */
- //ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
-
- if (MachDiskGetDriveGeometry(DriveNumber, &Geometry))
- {
- DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
- DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
- DiskGeometry->SectorsPerTrack = Geometry.Sectors;
- DiskGeometry->NumberOfHeads = Geometry.Heads;
- }
- else
- {
- ERR("Reading disk geometry failed\n");
- FrLdrHeapFree(PartialResourceList, TAG_HW_RESOURCE_LIST);
- return NULL;
- }
- TRACE("Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
- DriveNumber,
- DiskGeometry->NumberOfCylinders,
- DiskGeometry->NumberOfHeads,
- DiskGeometry->SectorsPerTrack,
- DiskGeometry->BytesPerSector);
-
- //
- // Return configuration data
- //
- *pSize = Size;
- return PartialResourceList;
-}
-
-typedef struct tagDISKCONTEXT
-{
- UCHAR DriveNumber;
- ULONG SectorSize;
- ULONGLONG SectorOffset;
- ULONGLONG SectorCount;
- ULONGLONG SectorNumber;
-} DISKCONTEXT;
-
-static
-ARC_STATUS
-DiskClose(ULONG FileId)
-{
- DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
-
- FrLdrTempFree(Context, TAG_HW_DISK_CONTEXT);
- return ESUCCESS;
-}
-
-static
-ARC_STATUS
-DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
-{
- DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
-
- RtlZeroMemory(Information, sizeof(FILEINFORMATION));
- Information->EndingAddress.QuadPart = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize;
- Information->CurrentAddress.QuadPart = (Context->SectorOffset + Context->SectorNumber) * Context->SectorSize;
-
- return ESUCCESS;
-}
-
-static
-ARC_STATUS
-DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
-{
- DISKCONTEXT* Context;
- ULONG DrivePartition, SectorSize;
- UCHAR DriveNumber;
- ULONGLONG SectorOffset = 0;
- ULONGLONG SectorCount = 0;
- PARTITION_TABLE_ENTRY PartitionTableEntry;
- CHAR FileName[1];
-
- if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition))
- return EINVAL;
-
- if (DrivePartition == 0xff)
- {
- /* This is a CD-ROM device */
- SectorSize = 2048;
- }
- else
- {
- /* This is either a floppy disk device (DrivePartition == 0) or
- * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but
- * it doesn't matter which one because they both have 512 bytes per sector */
- SectorSize = 512;
- }
-
- if (DrivePartition != 0xff && DrivePartition != 0)
- {
- if (!XboxDiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
- return EINVAL;
- SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
- SectorCount = PartitionTableEntry.PartitionSectorCount;
- }
- else
- {
- SectorCount = 0; /* FIXME */
- }
-
- Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
- if (!Context)
- return ENOMEM;
- Context->DriveNumber = DriveNumber;
- Context->SectorSize = SectorSize;
- Context->SectorOffset = SectorOffset;
- Context->SectorCount = SectorCount;
- Context->SectorNumber = 0;
- FsSetDeviceSpecific(*FileId, Context);
-
- return ESUCCESS;
-}
-
-static
-ARC_STATUS
-DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
-{
- DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
- UCHAR* Ptr = (UCHAR*)Buffer;
- ULONG i, Length, Sectors;
- BOOLEAN ret;
-
- *Count = 0;
- i = 0;
- while (N > 0)
- {
- Length = N;
- if (Length > DiskReadBufferSize)
- Length = DiskReadBufferSize;
- Sectors = (Length + Context->SectorSize - 1) / Context->SectorSize;
- ret = MachDiskReadLogicalSectors(
- Context->DriveNumber,
- Context->SectorNumber + Context->SectorOffset + i,
- Sectors,
- DiskReadBuffer);
- if (!ret)
- return EIO;
- RtlCopyMemory(Ptr, DiskReadBuffer, Length);
- Ptr += Length;
- *Count += Length;
- N -= Length;
- i += Sectors;
- }
-
- return ESUCCESS;
-}
-
-static
-ARC_STATUS
-DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
-{
- DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
-
- if (SeekMode != SeekAbsolute)
- return EINVAL;
- if (Position->LowPart & (Context->SectorSize - 1))
- return EINVAL;
-
- /* FIXME: take HighPart into account */
- Context->SectorNumber = Position->LowPart / Context->SectorSize;
- return ESUCCESS;
-}
-
-static const DEVVTBL DiskVtbl =
-{
- DiskClose,
- DiskGetFileInformation,
- DiskOpen,
- DiskRead,
- DiskSeek,
-};
-
-static
-VOID
-GetHarddiskIdentifier(PCHAR Identifier,
- UCHAR DriveNumber)
-{
- PMASTER_BOOT_RECORD Mbr;
- PULONG Buffer;
- ULONG i;
- ULONG Checksum;
- ULONG Signature;
- CHAR ArcName[MAX_PATH];
- PARTITION_TABLE_ENTRY PartitionTableEntry;
-
- /* Read the MBR */
- if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
- {
- ERR("Reading MBR failed\n");
- return;
- }
-
- Buffer = (ULONG*)DiskReadBuffer;
- Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
-
- Signature = Mbr->Signature;
- TRACE("Signature: %x\n", Signature);
-
- /* Calculate the MBR checksum */
- Checksum = 0;
- for (i = 0; i < 512 / sizeof(ULONG); i++)
- {
- Checksum += Buffer[i];
- }
- Checksum = ~Checksum + 1;
- TRACE("Checksum: %x\n", Checksum);
-
- /* Fill out the ARC disk block */
- reactos_arc_disk_info[reactos_disk_count].DiskSignature.Signature = Signature;
- reactos_arc_disk_info[reactos_disk_count].DiskSignature.CheckSum = Checksum;
- sprintf(ArcName, "multi(0)disk(0)rdisk(%lu)", reactos_disk_count);
- strcpy(reactos_arc_disk_info[reactos_disk_count].ArcName, ArcName);
- reactos_arc_disk_info[reactos_disk_count].DiskSignature.ArcName =
- reactos_arc_disk_info[reactos_disk_count].ArcName;
- reactos_disk_count++;
-
- sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(0)", DriveNumber - 0x80);
- FsRegisterDevice(ArcName, &DiskVtbl);
-
- /* Add partitions */
- i = 1;
- DiskReportError(FALSE);
- while (XboxDiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry))
- {
- if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED)
- {
- sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(%lu)", DriveNumber - 0x80, i);
- FsRegisterDevice(ArcName, &DiskVtbl);
- }
- i++;
- }
- DiskReportError(TRUE);
-
- /* Convert checksum and signature to identifier string */
- Identifier[0] = Hex[(Checksum >> 28) & 0x0F];
- Identifier[1] = Hex[(Checksum >> 24) & 0x0F];
- Identifier[2] = Hex[(Checksum >> 20) & 0x0F];
- Identifier[3] = Hex[(Checksum >> 16) & 0x0F];
- Identifier[4] = Hex[(Checksum >> 12) & 0x0F];
- Identifier[5] = Hex[(Checksum >> 8) & 0x0F];
- Identifier[6] = Hex[(Checksum >> 4) & 0x0F];
- Identifier[7] = Hex[Checksum & 0x0F];
- Identifier[8] = '-';
- Identifier[9] = Hex[(Signature >> 28) & 0x0F];
- Identifier[10] = Hex[(Signature >> 24) & 0x0F];
- Identifier[11] = Hex[(Signature >> 20) & 0x0F];
- Identifier[12] = Hex[(Signature >> 16) & 0x0F];
- Identifier[13] = Hex[(Signature >> 12) & 0x0F];
- Identifier[14] = Hex[(Signature >> 8) & 0x0F];
- Identifier[15] = Hex[(Signature >> 4) & 0x0F];
- Identifier[16] = Hex[Signature & 0x0F];
- Identifier[17] = '-';
- Identifier[18] = 'A';
- Identifier[19] = 0;
- TRACE("Identifier: %s\n", Identifier);
-}
-
-static
-VOID
-DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
- PCONFIGURATION_COMPONENT_DATA BusKey)
-{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- PCM_INT13_DRIVE_PARAMETER Int13Drives;
- GEOMETRY Geometry;
- PCONFIGURATION_COMPONENT_DATA DiskKey, ControllerKey;
- UCHAR DiskCount;
- ULONG i;
- ULONG Size;
- BOOLEAN Changed;
-
- /* Count the number of visible drives */
- DiskReportError(FALSE);
- DiskCount = 0;
-
- /* There are some really broken BIOSes out there. There are even BIOSes
- * that happily report success when you ask them to read from non-existent
- * harddisks. So, we set the buffer to known contents first, then try to
- * read. If the BIOS reports success but the buffer contents haven't
- * changed then we fail anyway */
- memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
- while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, DiskReadBuffer))
- {
- Changed = FALSE;
- for (i = 0; ! Changed && i < DiskReadBufferSize; i++)
- {
- Changed = ((PUCHAR)DiskReadBuffer)[i] != 0xcd;
- }
- if (! Changed)
- {
- TRACE("BIOS reports success for disk %d but data didn't change\n",
- (int)DiskCount);
- break;
- }
- DiskCount++;
- memset(DiskReadBuffer, 0xcd, DiskReadBufferSize);
- }
- DiskReportError(TRUE);
- TRACE("BIOS reports %d harddisk%s\n",
- (int)DiskCount, (DiskCount == 1) ? "" : "s");
-
- //DetectBiosFloppyController(BusKey);
-
- /* Allocate resource descriptor */
- Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
- sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
- PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
- if (PartialResourceList == NULL)
- {
- ERR("Failed to allocate resource descriptor\n");
- return;
- }
-
- /* Initialize resource descriptor */
- memset(PartialResourceList, 0, Size);
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 1;
- PartialResourceList->PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific;
- PartialResourceList->PartialDescriptors[0].ShareDisposition = 0;
- PartialResourceList->PartialDescriptors[0].Flags = 0;
- PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
- sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
-
- /* Get harddisk Int13 geometry data */
- Int13Drives = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
- for (i = 0; i < DiskCount; i++)
- {
- if (MachDiskGetDriveGeometry(0x80 + i, &Geometry))
- {
- Int13Drives[i].DriveSelect = 0x80 + i;
- Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
- Int13Drives[i].SectorsPerTrack = (USHORT)Geometry.Sectors;
- Int13Drives[i].MaxHeads = (USHORT)Geometry.Heads - 1;
- Int13Drives[i].NumberDrives = DiskCount;
-
- TRACE(
- "Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
- 0x80 + i,
- Geometry.Cylinders - 1,
- Geometry.Heads - 1,
- Geometry.Sectors,
- Geometry.BytesPerSector);
- }
- }
-
- FldrCreateComponentKey(BusKey,
- ControllerClass,
- DiskController,
- Output | Input,
- 0,
- 0xFFFFFFFF,
- NULL,
- PartialResourceList,
- Size,
- &ControllerKey);
- TRACE("Created key: DiskController\\0\n");
-
- /* Create and fill subkey for each harddisk */
- for (i = 0; i < DiskCount; i++)
- {
- CHAR Identifier[20];
-
- /* Get disk values */
- PartialResourceList = GetHarddiskConfigurationData(0x80 + i, &Size);
- GetHarddiskIdentifier(Identifier, 0x80 + i);
-
- /* Create disk key */
- FldrCreateComponentKey(ControllerKey,
- PeripheralClass,
- DiskPeripheral,
- Output | Input,
- 0,
- 0xFFFFFFFF,
- Identifier,
- PartialResourceList,
- Size,
- &DiskKey);
- }
-}
-
-static
-VOID
-DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
-{
- PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
- PCONFIGURATION_COMPONENT_DATA BusKey;
- ULONG Size;
-
- /* Set 'Configuration Data' value */
- Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
- sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
- PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
- if (PartialResourceList == NULL)
- {
- TRACE(
- "Failed to allocate resource descriptor\n");
- return;
- }
-
- /* Initialize resource descriptor */
- memset(PartialResourceList, 0, Size);
- PartialResourceList->Version = 1;
- PartialResourceList->Revision = 1;
- PartialResourceList->Count = 0;
-
- /* Create new bus key */
- FldrCreateComponentKey(SystemKey,
- AdapterClass,
- MultiFunctionAdapter,
- 0x0,
- 0x0,
- 0xFFFFFFFF,
- "ISA",
- PartialResourceList,
- Size,
- &BusKey);
-
- /* Increment bus number */
- (*BusNumber)++;
-
- /* Detect ISA/BIOS devices */
- DetectBiosDisks(SystemKey, BusKey);
-
-
- /* FIXME: Detect more ISA devices */
-}
-
-PCONFIGURATION_COMPONENT_DATA
-XboxHwDetect(VOID)
-{
- PCONFIGURATION_COMPONENT_DATA SystemKey;
- ULONG BusNumber = 0;
-
- TRACE("DetectHardware()\n");
-
- /* Create the 'System' key */
- FldrCreateSystemKey(&SystemKey);
-
- /* TODO: Build actual xbox's hardware configuration tree */
- DetectIsaBios(SystemKey, &BusNumber);
-
- TRACE("DetectHardware() Done\n");
- return SystemKey;
-}
-
-BOOLEAN
-XboxInitializeBootDevices(VOID)
-{
- // Emulate old behavior
- return XboxHwDetect() != NULL;
-}
-
-VOID XboxHwIdle(VOID)
-{
- /* UNIMPLEMENTED */
-}
-
-/* EOF */
#ifndef _M_ARM
#include <freeldr.h>
+
+#define NDEBUG
#include <debug.h>
DBG_DEFAULT_CHANNEL(DISK);
static BOOLEAN bReportError = TRUE;
-/////////////////////////////////////////////////////////////////////////////////////////////
-// FUNCTIONS
-/////////////////////////////////////////////////////////////////////////////////////////////
+/* FUNCTIONS *****************************************************************/
-VOID DiskReportError (BOOLEAN bError)
+VOID DiskReportError(BOOLEAN bError)
{
bReportError = bError;
}
VOID DiskError(PCSTR ErrorString, ULONG ErrorCode)
{
- CHAR ErrorCodeString[200];
+ CHAR ErrorCodeString[200];
if (bReportError == FALSE)
return;
- sprintf(ErrorCodeString, "%s\n\nError Code: 0x%lx\nError: %s", ErrorString, ErrorCode, DiskGetErrorCodeString(ErrorCode));
+ sprintf(ErrorCodeString, "%s\n\nError Code: 0x%lx\nError: %s",
+ ErrorString, ErrorCode, DiskGetErrorCodeString(ErrorCode));
TRACE("%s\n", ErrorCodeString);
}
}
-// This function is in arch/i386/i386disk.c
-//BOOLEAN DiskReadLogicalSectors(ULONG DriveNumber, U64 SectorNumber, ULONG SectorCount, PVOID Buffer)
-
BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber)
{
- // Hard disks use drive numbers >= 0x80
- // So if the drive number indicates a hard disk
- // then return FALSE
- // 0x49 is our magic ramdisk drive, so return FALSE for that too
+ /*
+ * Hard disks use drive numbers >= 0x80 . So if the drive number
+ * indicates a hard disk then return FALSE.
+ * 0x49 is our magic ramdisk drive, so return FALSE for that too.
+ */
if ((DriveNumber >= 0x80) || (DriveNumber == 0x49))
- {
return FALSE;
- }
- // Drive is a floppy diskette so return TRUE
+ /* The drive is a floppy diskette so return TRUE */
return TRUE;
}
return TRUE;
}
-// This function is in arch/i386/i386disk.c
-//VOID DiskStopFloppyMotor(VOID)
-
-// This function is in arch/i386/i386disk.c
-//ULONG DiskGetCacheableBlockCount(UCHAR DriveNumber)
-
#endif
PFREELDR_MEMORY_DESCRIPTOR PcMemGetMemoryMap(ULONG *MemoryMapSize);
+BOOLEAN DiskResetController(UCHAR DriveNumber);
+BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize);
+
BOOLEAN PcDiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size);
BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer);
BOOLEAN PcDiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
typedef struct _GEOMETRY
{
- ULONG Cylinders; // Number of cylinders on the disk
- ULONG Heads; // Number of heads on the disk
- ULONG Sectors; // Number of sectors per track
- ULONG BytesPerSector; // Number of bytes per sector
+ ULONG Cylinders; // Number of cylinders on the disk
+ ULONG Heads; // Number of heads on the disk
+ ULONG Sectors; // Number of sectors per track
+ ULONG BytesPerSector; // Number of bytes per sector
} GEOMETRY, *PGEOMETRY;
#include <pshpack1.h>
typedef struct _EXTENDED_GEOMETRY
{
- USHORT Size;
- USHORT Flags;
- ULONG Cylinders;
- ULONG Heads;
- ULONG SectorsPerTrack;
- ULONGLONG Sectors;
- USHORT BytesPerSector;
- ULONG PDPTE;
+ USHORT Size;
+ USHORT Flags;
+ ULONG Cylinders;
+ ULONG Heads;
+ ULONG SectorsPerTrack;
+ ULONGLONG Sectors;
+ USHORT BytesPerSector;
+ ULONG PDPTE;
+
} EXTENDED_GEOMETRY, *PEXTENDED_GEOMETRY;
//
//
typedef struct _PARTITION_TABLE_ENTRY
{
- UCHAR BootIndicator; // 0x00 - non-bootable partition, 0x80 - bootable partition (one partition only)
- UCHAR StartHead; // Beginning head number
- UCHAR StartSector; // Beginning sector (2 high bits of cylinder #)
- UCHAR StartCylinder; // Beginning cylinder# (low order bits of cylinder #)
- UCHAR SystemIndicator; // System indicator
- UCHAR EndHead; // Ending head number
- UCHAR EndSector; // Ending sector (2 high bits of cylinder #)
- UCHAR EndCylinder; // Ending cylinder# (low order bits of cylinder #)
- ULONG SectorCountBeforePartition; // Number of sectors preceding the partition
- ULONG PartitionSectorCount; // Number of sectors in the partition
+ UCHAR BootIndicator; // 0x00 - non-bootable partition,
+ // 0x80 - bootable partition (one partition only)
+ UCHAR StartHead; // Beginning head number
+ UCHAR StartSector; // Beginning sector (2 high bits of cylinder #)
+ UCHAR StartCylinder; // Beginning cylinder# (low order bits of cylinder #)
+ UCHAR SystemIndicator; // System indicator
+ UCHAR EndHead; // Ending head number
+ UCHAR EndSector; // Ending sector (2 high bits of cylinder #)
+ UCHAR EndCylinder; // Ending cylinder# (low order bits of cylinder #)
+ ULONG SectorCountBeforePartition; // Number of sectors preceding the partition
+ ULONG PartitionSectorCount; // Number of sectors in the partition
} PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY;
//
typedef struct _MASTER_BOOT_RECORD
{
- UCHAR MasterBootRecordCodeAndData[0x1b8]; /* 0x000 */
- ULONG Signature; /* 0x1B8 */
- USHORT Reserved; /* 0x1BC */
- PARTITION_TABLE_ENTRY PartitionTable[4]; /* 0x1BE */
- USHORT MasterBootRecordMagic; /* 0x1FE */
+ UCHAR MasterBootRecordCodeAndData[0x1b8]; /* 0x000 */
+ ULONG Signature; /* 0x1B8 */
+ USHORT Reserved; /* 0x1BC */
+ PARTITION_TABLE_ENTRY PartitionTable[4]; /* 0x1BE */
+ USHORT MasterBootRecordMagic; /* 0x1FE */
} MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD;
#include <poppack.h>
///////////////////////////////////////////////////////////////////////////////////////
//
-// i386 BIOS Disk Functions (i386disk.c)
+// PC x86/64 BIOS Disk Functions (pcdisk.c)
//
///////////////////////////////////////////////////////////////////////////////////////
#if defined(__i386__) || defined(_M_AMD64)
-
-BOOLEAN DiskResetController(UCHAR DriveNumber);
-BOOLEAN DiskInt13ExtensionsSupported(UCHAR DriveNumber);
-//VOID DiskStopFloppyMotor(VOID);
-BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize);
-
+VOID DiskStopFloppyMotor(VOID);
#endif // defined __i386__ || defined(_M_AMD64)
///////////////////////////////////////////////////////////////////////////////////////
// FreeLoader Disk Functions
//
///////////////////////////////////////////////////////////////////////////////////////
-VOID DiskReportError (BOOLEAN bError);
-VOID DiskError(PCSTR ErrorString, ULONG ErrorCode);
-PCSTR DiskGetErrorCodeString(ULONG ErrorCode);
-BOOLEAN DiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); // Implemented in i386disk.c
-BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber);
-VOID DiskStopFloppyMotor(VOID); // Implemented in i386disk.c
+VOID DiskReportError (BOOLEAN bError);
+VOID DiskError(PCSTR ErrorString, ULONG ErrorCode);
+PCSTR DiskGetErrorCodeString(ULONG ErrorCode);
+BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber);
extern UCHAR FrldrBootDrive;
extern ULONG FrldrBootPartition;
extern PVOID DiskReadBuffer;
// Fixed Disk Partition Management Functions
//
///////////////////////////////////////////////////////////////////////////////////////
-BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry, ULONG *ActivePartition);
-BOOLEAN DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
-BOOLEAN DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
-BOOLEAN DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
-BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord);
+BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry, ULONG *ActivePartition);
+BOOLEAN DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
+BOOLEAN DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
+BOOLEAN DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
+BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord);
+/*
+ * SCSI support (disk/scsiport.c)
+ */
ULONG LoadBootDeviceDriver(VOID);