From dde1f97a0269d4bab36e4dcc140d17683273dc49 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 28 Jan 2017 23:47:35 +0000 Subject: [PATCH] [FREELDR]: More local changes merging, part 2/x: - Move the HW detection code specific to the PC architecture from hardware.c to machpc.c, keeping in hardware.c the code that is shared between PC and XBOX. - Move what remained of i386disk.c into pcdisk.c (specific to PC architecture) + code formatting. - Move what remained of xboxhw.c into machxbox.c (specific to XBOX architecture); we discover that some code related to disk management is actually shared with PC architecture (in hwdisk.c): hwdisk.c therefore contains disk-management routines common to both PC & XBOX. - xboxdisk.c: Code formatting only. - Cleanup in disk.c/disk.h svn path=/trunk/; revision=73616 --- reactos/boot/freeldr/freeldr/CMakeLists.txt | 3 - .../boot/freeldr/freeldr/arch/i386/hardware.c | 1459 +---------------- .../boot/freeldr/freeldr/arch/i386/hwdisk.c | 68 +- .../boot/freeldr/freeldr/arch/i386/i386disk.c | 220 --- .../boot/freeldr/freeldr/arch/i386/machpc.c | 1342 ++++++++++++++- .../boot/freeldr/freeldr/arch/i386/machxbox.c | 538 +++++- .../boot/freeldr/freeldr/arch/i386/pcdisk.c | 513 ++++-- .../boot/freeldr/freeldr/arch/i386/xboxdisk.c | 609 ++++--- .../boot/freeldr/freeldr/arch/i386/xboxhw.c | 531 ------ reactos/boot/freeldr/freeldr/disk/disk.c | 35 +- .../freeldr/freeldr/include/arch/pc/machpc.h | 3 + reactos/boot/freeldr/freeldr/include/disk.h | 88 +- 12 files changed, 2633 insertions(+), 2776 deletions(-) delete mode 100644 reactos/boot/freeldr/freeldr/arch/i386/i386disk.c delete mode 100644 reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c diff --git a/reactos/boot/freeldr/freeldr/CMakeLists.txt b/reactos/boot/freeldr/freeldr/CMakeLists.txt index 970c725abd1..c4ca5b4a33f 100644 --- a/reactos/boot/freeldr/freeldr/CMakeLists.txt +++ b/reactos/boot/freeldr/freeldr/CMakeLists.txt @@ -123,7 +123,6 @@ if(ARCH STREQUAL "i386") arch/i386/hwdisk.c arch/i386/hwpci.c arch/i386/i386bug.c - arch/i386/i386disk.c arch/i386/i386idt.c arch/i386/i386rtl.c arch/i386/i386vid.c @@ -137,7 +136,6 @@ if(ARCH STREQUAL "i386") arch/i386/xboxcons.c arch/i386/xboxdisk.c arch/i386/xboxfont.c - arch/i386/xboxhw.c arch/i386/xboxi2c.c arch/i386/xboxmem.c arch/i386/xboxrtc.c @@ -170,7 +168,6 @@ elseif(ARCH STREQUAL "amd64") arch/i386/hwpci.c arch/i386/i386bug.c arch/i386/i386rtl.c - arch/i386/i386disk.c arch/i386/i386vid.c arch/i386/machpc.c arch/i386/pccons.c diff --git a/reactos/boot/freeldr/freeldr/arch/i386/hardware.c b/reactos/boot/freeldr/freeldr/arch/i386/hardware.c index eb24cb19421..414f27dd115 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/hardware.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/hardware.c @@ -20,11 +20,13 @@ */ #include -#include #define NDEBUG #include +DBG_DEFAULT_CHANNEL(HWDETECT); + + #define MILLISEC (10) #define PRECISION (8) @@ -32,63 +34,7 @@ #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 @@ -96,10 +42,9 @@ GetHarddiskIdentifier( UCHAR DriveNumber); BOOLEAN -HwInitializeBiosDisks(VOID); - -/* FUNCTIONS ****************************************************************/ +InitializeBiosDisks(VOID); +/* FUNCTIONS *****************************************************************/ static VOID @@ -109,14 +54,12 @@ __StallExecutionProcessor(ULONG Loops) 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) @@ -130,7 +73,6 @@ Read8254Timer(VOID) return Count; } - static VOID WaitFor8254Wraparound(VOID) @@ -156,7 +98,6 @@ WaitFor8254Wraparound(VOID) while (Delta < 300); } - VOID HalpCalibrateStallExecution(VOID) { @@ -225,213 +166,6 @@ 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 @@ -445,7 +179,6 @@ GetFloppyCount(VOID) return ((Data & 0xF0) ? 1 : 0) + ((Data & 0x0F) ? 1 : 0); } - static UCHAR GetFloppyType(UCHAR DriveNumber) @@ -463,7 +196,6 @@ GetFloppyType(UCHAR DriveNumber) return 0; } - static PVOID GetInt1eTable(VOID) @@ -474,7 +206,6 @@ GetInt1eTable(VOID) return (PVOID)((ULONG_PTR)(((ULONG)(*SegPtr)) << 4) + (ULONG)(*OfsPtr)); } - static VOID DetectBiosFloppyPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey) @@ -546,9 +277,8 @@ DetectBiosFloppyPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey) } } - static -VOID +PCONFIGURATION_COMPONENT_DATA DetectBiosFloppyController(PCONFIGURATION_COMPONENT_DATA BusKey) { PCONFIGURATION_COMPONENT_DATA ControllerKey; @@ -558,16 +288,16 @@ DetectBiosFloppyController(PCONFIGURATION_COMPONENT_DATA BusKey) 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); @@ -615,10 +345,12 @@ DetectBiosFloppyController(PCONFIGURATION_COMPONENT_DATA BusKey) &ControllerKey); TRACE("Created key: DiskController\\0\n"); - if (FloppyCount) DetectBiosFloppyPeripheral(ControllerKey); + if (FloppyCount) + DetectBiosFloppyPeripheral(ControllerKey); + + return ControllerKey; } -static PCONFIGURATION_COMPONENT_DATA DetectSystem(VOID) { @@ -688,24 +420,25 @@ 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++) @@ -733,1133 +466,47 @@ DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA BusKey) } } -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 */ diff --git a/reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c b/reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c index a5889e3f9bf..e251d4d1af5 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/hwdisk.c @@ -39,13 +39,19 @@ extern ULONG reactos_disk_count; extern ARC_DISK_SIGNATURE_EX reactos_arc_disk_info[]; static CHAR Hex[] = "0123456789abcdef"; + UCHAR PcBiosDiskCount = 0; -CHAR PcDiskIdentifier[32][20]; +static CHAR PcDiskIdentifier[32][20]; + PVOID DiskReadBuffer; SIZE_T DiskReadBufferSize; -static ARC_STATUS DiskClose(ULONG FileId) +/* FUNCTIONS *****************************************************************/ + +// static +ARC_STATUS +DiskClose(ULONG FileId) { DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); @@ -53,7 +59,9 @@ static ARC_STATUS DiskClose(ULONG FileId) return ESUCCESS; } -static ARC_STATUS DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information) +// static +ARC_STATUS +DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information) { DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); @@ -64,7 +72,8 @@ static ARC_STATUS DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Informat return ESUCCESS; } -static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) +static ARC_STATUS +DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) { DISKCONTEXT* Context; UCHAR DriveNumber; @@ -84,9 +93,12 @@ static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) } else { - /* This is either a floppy disk device (DrivePartition == 0) or - * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but - * it doesn't matter which one because they both have 512 bytes per sector */ + /* + * This is either a floppy disk device (DrivePartition == 0) or + * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) + * but it doesn't matter which one because they both have 512 bytes + * per sector. + */ SectorSize = 512; } @@ -94,13 +106,21 @@ static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) { if (!DiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry)) return EINVAL; + SectorOffset = PartitionTableEntry.SectorCountBeforePartition; SectorCount = PartitionTableEntry.PartitionSectorCount; } +#if 0 // FIXME: Investigate + else + { + SectorCount = 0; /* FIXME */ + } +#endif Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT); if (!Context) return ENOMEM; + Context->DriveNumber = DriveNumber; Context->SectorSize = SectorSize; Context->SectorOffset = SectorOffset; @@ -111,7 +131,9 @@ static ARC_STATUS DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) return ESUCCESS; } -static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) +// static +ARC_STATUS +DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) { DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); UCHAR* Ptr = (UCHAR*)Buffer; @@ -123,7 +145,7 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) MaxSectors = DiskReadBufferSize / Context->SectorSize; SectorOffset = Context->SectorNumber + Context->SectorOffset; - ret = 1; + ret = TRUE; while (TotalSectors) { @@ -131,11 +153,10 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) if (ReadSectors > MaxSectors) ReadSectors = MaxSectors; - ret = MachDiskReadLogicalSectors( - Context->DriveNumber, - SectorOffset, - ReadSectors, - DiskReadBuffer); + ret = MachDiskReadLogicalSectors(Context->DriveNumber, + SectorOffset, + ReadSectors, + DiskReadBuffer); if (!ret) break; @@ -156,7 +177,9 @@ static ARC_STATUS DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) return (!ret) ? EIO : ESUCCESS; } -static ARC_STATUS DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode) +// static +ARC_STATUS +DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode) { DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); @@ -169,7 +192,8 @@ static ARC_STATUS DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekM return ESUCCESS; } -static const DEVVTBL DiskVtbl = { +static const DEVVTBL DiskVtbl = +{ DiskClose, DiskGetFileInformation, DiskOpen, @@ -177,6 +201,7 @@ static const DEVVTBL DiskVtbl = { DiskSeek, }; + PCHAR GetHarddiskIdentifier( UCHAR DriveNumber) @@ -264,14 +289,13 @@ GetHarddiskInformation( Identifier[15] = Hex[(Signature >> 4) & 0x0F]; Identifier[16] = Hex[Signature & 0x0F]; Identifier[17] = '-'; - Identifier[18] = 'A'; + Identifier[18] = 'A'; // FIXME: Not always 'A' ... Identifier[19] = 0; TRACE("Identifier: %s\n", Identifier); } - BOOLEAN -HwInitializeBiosDisks(VOID) +PcInitializeBootDevices(VOID) { UCHAR DiskCount, DriveNumber; ULONG i; @@ -314,9 +338,11 @@ HwInitializeBiosDisks(VOID) DiskCount++; DriveNumber++; - memset(DiskReadBuffer, 0xcd, 512); + memset(DiskReadBuffer, 0xcd, DiskReadBufferSize); } DiskReportError(TRUE); + TRACE("BIOS reports %d harddisk%s\n", + (int)DiskCount, (DiskCount == 1) ? "" : "s"); /* Get the drive we're booting from */ MachDiskGetBootPath(BootPath, sizeof(BootPath)); @@ -366,5 +392,5 @@ HwInitializeBiosDisks(VOID) TRACE("BIOS reports %d harddisk%s\n", (int)DiskCount, (DiskCount == 1) ? "": "s"); - return DiskCount != 0; + return (DiskCount != 0); } diff --git a/reactos/boot/freeldr/freeldr/arch/i386/i386disk.c b/reactos/boot/freeldr/freeldr/arch/i386/i386disk.c deleted file mode 100644 index 07062e99ee4..00000000000 --- a/reactos/boot/freeldr/freeldr/arch/i386/i386disk.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * FreeLoader - * Copyright (C) 1998-2003 Brian Palmer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include - -#define NDEBUG -#include - -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 */ diff --git a/reactos/boot/freeldr/freeldr/arch/i386/machpc.c b/reactos/boot/freeldr/freeldr/arch/i386/machpc.c index 07083f03c88..e08e7e08f52 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/machpc.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/machpc.c @@ -17,6 +17,1343 @@ */ #include +#include + +#define NDEBUG +#include + +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) @@ -53,10 +1390,9 @@ 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 */ diff --git a/reactos/boot/freeldr/freeldr/arch/i386/machxbox.c b/reactos/boot/freeldr/freeldr/arch/i386/machxbox.c index 627a84819b1..c66ba87cb1d 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/machxbox.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/machxbox.c @@ -18,53 +18,513 @@ #include +#define NDEBUG +#include + +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 */ diff --git a/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c b/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c index f6055cca3a9..fd85af705fe 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/pcdisk.c @@ -18,6 +18,8 @@ */ #include + +#define NDEBUG #include DBG_DEFAULT_CHANNEL(DISK); @@ -25,41 +27,40 @@ DBG_DEFAULT_CHANNEL(DISK); #include 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 -///////////////////////////////////////////////////////////////////////////////////////////// -// 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); @@ -67,23 +68,16 @@ static BOOLEAN PcDiskResetController(UCHAR DriveNumber) static BOOLEAN PcDiskReadLogicalSectorsLBA(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer) { - REGS RegsIn; - REGS RegsOut; - ULONG RetryCount; - PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER); + REGS RegsIn, RegsOut; + ULONG RetryCount; + PI386_DISK_ADDRESS_PACKET Packet = (PI386_DISK_ADDRESS_PACKET)(BIOSCALLBUFFER); TRACE("PcDiskReadLogicalSectorsLBA() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer); ASSERT(((ULONG_PTR)Buffer) <= 0xFFFFF); - // BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ - RegsIn.b.ah = 0x42; // Subfunction 42h - RegsIn.b.dl = DriveNumber; // Drive number in DL (0 - floppy, 0x80 - harddisk) - RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> disk address packet - RegsIn.w.si = BIOSCALLBUFOFFSET; - - // Setup disk address packet - RtlZeroMemory(Packet, sizeof(I386_DISK_ADDRESS_PACKET)); - Packet->PacketSize = sizeof(I386_DISK_ADDRESS_PACKET); + /* Setup disk address packet */ + RtlZeroMemory(Packet, sizeof(*Packet)); + Packet->PacketSize = sizeof(*Packet); Packet->Reserved = 0; Packet->LBABlockCount = (USHORT)SectorCount; ASSERT(Packet->LBABlockCount == SectorCount); @@ -91,39 +85,45 @@ static BOOLEAN PcDiskReadLogicalSectorsLBA(UCHAR DriveNumber, ULONGLONG SectorNu Packet->TransferBufferSegment = (USHORT)(((ULONG_PTR)Buffer) >> 4); Packet->LBAStartBlock = SectorNumber; - // BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ - // Return: - // CF clear if successful - // AH = 00h - // CF set on error - // AH = error code - // disk address packet's block count field set to the - // number of blocks successfully transferred + /* + * BIOS int 0x13, function 42h - IBM/MS INT 13 Extensions - EXTENDED READ + * Return: + * CF clear if successful + * AH = 00h + * CF set on error + * AH = error code + * Disk address packet's block count field set to the + * number of blocks successfully transferred. + */ + RegsIn.b.ah = 0x42; // Subfunction 42h + RegsIn.b.dl = DriveNumber; // Drive number in DL (0 - floppy, 0x80 - harddisk) + RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> disk address packet + RegsIn.w.si = BIOSCALLBUFOFFSET; - // Retry 3 times + /* Retry 3 times */ for (RetryCount=0; RetryCount<3; RetryCount++) { Int386(0x13, &RegsIn, &RegsOut); - // If it worked return TRUE + /* If it worked return TRUE */ if (INT386_SUCCESS(RegsOut)) { return TRUE; } - // If it was a corrected ECC error then the data is still good + /* If it was a corrected ECC error then the data is still good */ else if (RegsOut.b.ah == 0x11) { return TRUE; } - // If it failed then do the next retry + /* If it failed then do the next retry */ else { - PcDiskResetController(DriveNumber); + DiskResetController(DriveNumber); continue; } } - // If we get here then the read failed + /* If we get here then the read failed */ ERR("Disk Read Failed in LBA mode: %x (DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d)\n", RegsOut.b.ah, DriveNumber, SectorNumber, SectorCount); return FALSE; @@ -131,20 +131,17 @@ static BOOLEAN PcDiskReadLogicalSectorsLBA(UCHAR DriveNumber, ULONGLONG SectorNu static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer) { - UCHAR PhysicalSector; - UCHAR PhysicalHead; - ULONG PhysicalTrack; - GEOMETRY DriveGeometry; - ULONG NumberOfSectorsToRead; - REGS RegsIn; - REGS RegsOut; - ULONG RetryCount; + UCHAR PhysicalSector; + UCHAR PhysicalHead; + ULONG PhysicalTrack; + GEOMETRY DriveGeometry; + ULONG NumberOfSectorsToRead; + REGS RegsIn, RegsOut; + ULONG RetryCount; TRACE("PcDiskReadLogicalSectorsCHS()\n"); - // - // Get the drive geometry - // + /* Get the drive geometry */ if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry) || DriveGeometry.Sectors == 0 || DriveGeometry.Heads == 0) @@ -154,18 +151,15 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu while (SectorCount) { - - // - // Calculate the physical disk offsets - // Note: DriveGeometry.Sectors < 64 - // + /* + * Calculate the physical disk offsets. + * Note: DriveGeometry.Sectors < 64 + */ PhysicalSector = 1 + (UCHAR)(SectorNumber % DriveGeometry.Sectors); PhysicalHead = (UCHAR)((SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads); PhysicalTrack = (ULONG)((SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads); - // - // Calculate how many sectors we need to read this round - // + /* Calculate how many sectors we need to read this round */ if (PhysicalSector > 1) { if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1))) @@ -181,9 +175,7 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu NumberOfSectorsToRead = SectorCount; } - // - // Make sure the read is within the geometry boundaries - // + /* Make sure the read is within the geometry boundaries */ if ((PhysicalHead >= DriveGeometry.Heads) || (PhysicalTrack >= DriveGeometry.Cylinders) || ((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) || @@ -193,22 +185,24 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu return FALSE; } - // BIOS Int 13h, function 2 - Read Disk Sectors - // AH = 02h - // AL = number of sectors to read (must be nonzero) - // CH = low eight bits of cylinder number - // CL = sector number 1-63 (bits 0-5) - // high two bits of cylinder (bits 6-7, hard disk only) - // DH = head number - // DL = drive number (bit 7 set for hard disk) - // ES:BX -> data buffer - // Return: - // CF set on error - // if AH = 11h (corrected ECC error), AL = burst length - // CF clear if successful - // AH = status - // AL = number of sectors transferred - // (only valid if CF set for some BIOSes) + /* + * BIOS Int 13h, function 2 - Read Disk Sectors + * AH = 02h + * AL = number of sectors to read (must be nonzero) + * CH = low eight bits of cylinder number + * CL = sector number 1-63 (bits 0-5) + * high two bits of cylinder (bits 6-7, hard disk only) + * DH = head number + * DL = drive number (bit 7 set for hard disk) + * ES:BX -> data buffer + * Return: + * CF set on error + * if AH = 11h (corrected ECC error), AL = burst length + * CF clear if successful + * AH = status + * AL = number of sectors transferred + * (only valid if CF set for some BIOSes) + */ RegsIn.b.ah = 0x02; RegsIn.b.al = (UCHAR)NumberOfSectorsToRead; RegsIn.b.ch = (PhysicalTrack & 0xFF); @@ -218,41 +212,37 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu RegsIn.w.es = (USHORT)(((ULONG_PTR)Buffer) >> 4); RegsIn.w.bx = ((ULONG_PTR)Buffer) & 0x0F; - // - // Perform the read - // Retry 3 times - // + /* Perform the read. Retry 3 times. */ for (RetryCount=0; RetryCount<3; RetryCount++) { Int386(0x13, &RegsIn, &RegsOut); - // If it worked break out + /* If it worked break out */ if (INT386_SUCCESS(RegsOut)) { break; } - // If it was a corrected ECC error then the data is still good + /* If it was a corrected ECC error then the data is still good */ else if (RegsOut.b.ah == 0x11) { break; } - // If it failed the do the next retry + /* If it failed the do the next retry */ else { - PcDiskResetController(DriveNumber); - + DiskResetController(DriveNumber); continue; } } - // If we retried 3 times then fail + /* If we retried 3 times then fail */ if (RetryCount >= 3) { ERR("Disk Read Failed in CHS mode, after retrying 3 times: %x\n", RegsOut.b.ah); return FALSE; } - // I have learned that not all bioses return + // I have learned that not all BIOSes return // the sector read count in the AL register (at least mine doesn't) // even if the sectors were read correctly. So instead // of checking the sector read count we will rely solely @@ -266,122 +256,287 @@ static BOOLEAN PcDiskReadLogicalSectorsCHS(UCHAR DriveNumber, ULONGLONG SectorNu return TRUE; } +static BOOLEAN DiskInt13ExtensionsSupported(UCHAR DriveNumber) +{ + static UCHAR LastDriveNumber = 0xff; + static BOOLEAN LastSupported; + REGS RegsIn, RegsOut; + + TRACE("DiskInt13ExtensionsSupported()\n"); + + if (DriveNumber == LastDriveNumber) + { + TRACE("Using cached value %s for drive 0x%x\n", + LastSupported ? "TRUE" : "FALSE", DriveNumber); + return LastSupported; + } + + /* + * Some BIOSes report that extended disk access functions are not supported + * when booting from a CD (e.g. Phoenix BIOS v6.00PG and Insyde BIOS shipping + * with Intel Macs). Therefore we just return TRUE if we're booting from a CD - + * we can assume that all El Torito capable BIOSes support INT 13 extensions. + * We simply detect whether we're booting from CD by checking whether the drive + * number is >= 0x8A. It's 0x90 on the Insyde BIOS, and 0x9F on most other BIOSes. + */ + if (DriveNumber >= 0x8A) + { + LastSupported = TRUE; + return TRUE; + } + + LastDriveNumber = DriveNumber; + + /* + * IBM/MS INT 13 Extensions - INSTALLATION CHECK + * AH = 41h + * BX = 55AAh + * DL = drive (80h-FFh) + * Return: + * CF set on error (extensions not supported) + * AH = 01h (invalid function) + * CF clear if successful + * BX = AA55h if installed + * AH = major version of extensions + * 01h = 1.x + * 20h = 2.0 / EDD-1.0 + * 21h = 2.1 / EDD-1.1 + * 30h = EDD-3.0 + * AL = internal use + * CX = API subset support bitmap + * DH = extension version (v2.0+ ??? -- not present in 1.x) + * + * Bitfields for IBM/MS INT 13 Extensions API support bitmap + * Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported + * Bit 1, removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h) supported + * Bit 2, enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported + * extended drive parameter table is valid + * Bits 3-15 reserved + */ + RegsIn.b.ah = 0x41; + RegsIn.w.bx = 0x55AA; + RegsIn.b.dl = DriveNumber; + + /* Reset the disk controller */ + Int386(0x13, &RegsIn, &RegsOut); + + if (!INT386_SUCCESS(RegsOut)) + { + /* CF set on error (extensions not supported) */ + LastSupported = FALSE; + return FALSE; + } + + if (RegsOut.w.bx != 0xAA55) + { + /* BX = AA55h if installed */ + LastSupported = FALSE; + return FALSE; + } + + if (!(RegsOut.w.cx & 0x0001)) + { + /* + * CX = API subset support bitmap. + * Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported. + */ + DbgPrint("Suspicious API subset support bitmap 0x%x on device 0x%lx\n", + RegsOut.w.cx, DriveNumber); + LastSupported = FALSE; + return FALSE; + } + + LastSupported = TRUE; + return TRUE; +} + BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer) { BOOLEAN ExtensionsSupported; - TRACE("PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, SectorCount, Buffer); + TRACE("PcDiskReadLogicalSectors() DriveNumber: 0x%x SectorNumber: %I64d SectorCount: %d Buffer: 0x%x\n", + DriveNumber, SectorNumber, SectorCount, Buffer); - // - // Check to see if it is a fixed disk drive - // If so then check to see if Int13 extensions work - // If they do then use them, otherwise default back to BIOS calls - // + /* + * Check to see if it is a fixed disk drive. + * If so then check to see if Int13 extensions work. + * If they do then use them, otherwise default back to BIOS calls. + */ ExtensionsSupported = DiskInt13ExtensionsSupported(DriveNumber); if ((DriveNumber >= 0x80) && ExtensionsSupported) { TRACE("Using Int 13 Extensions for read. DiskInt13ExtensionsSupported(%d) = %s\n", DriveNumber, ExtensionsSupported ? "TRUE" : "FALSE"); - // - // LBA is easy, nothing to calculate - // Just do the read - // + /* LBA is easy, nothing to calculate. Just do the read. */ return PcDiskReadLogicalSectorsLBA(DriveNumber, SectorNumber, SectorCount, Buffer); } else { - // LBA is not supported default to the CHS calls + /* LBA is not supported default to the CHS calls */ return PcDiskReadLogicalSectorsCHS(DriveNumber, SectorNumber, SectorCount, Buffer); } return TRUE; } +VOID DiskStopFloppyMotor(VOID) +{ + WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0); +} + +BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize) +{ + REGS RegsIn, RegsOut; + PUSHORT Ptr = (PUSHORT)(BIOSCALLBUFFER); + + TRACE("DiskGetExtendedDriveParameters()\n"); + + if (!DiskInt13ExtensionsSupported(DriveNumber)) + return FALSE; + + /* Initialize transfer buffer */ + *Ptr = BufferSize; + + /* + * BIOS Int 13h, function 48h - Get drive parameters + * AH = 48h + * DL = drive (bit 7 set for hard disk) + * DS:SI = result buffer + * Return: + * CF set on error + * AH = status (07h) + * CF clear if successful + * AH = 00h + * DS:SI -> result buffer + */ + RegsIn.b.ah = 0x48; + RegsIn.b.dl = DriveNumber; + RegsIn.x.ds = BIOSCALLBUFSEGMENT; // DS:SI -> result buffer + RegsIn.w.si = BIOSCALLBUFOFFSET; + + /* Get drive parameters */ + Int386(0x13, &RegsIn, &RegsOut); + if (!INT386_SUCCESS(RegsOut)) + return FALSE; + + memcpy(Buffer, Ptr, BufferSize); + +#if DBG + TRACE("size of buffer: %x\n", Ptr[0]); + TRACE("information flags: %x\n", Ptr[1]); + TRACE("number of physical cylinders on drive: %u\n", *(PULONG)&Ptr[2]); + TRACE("number of physical heads on drive: %u\n", *(PULONG)&Ptr[4]); + TRACE("number of physical sectors per track: %u\n", *(PULONG)&Ptr[6]); + TRACE("total number of sectors on drive: %I64u\n", *(unsigned long long*)&Ptr[8]); + TRACE("bytes per sector: %u\n", Ptr[12]); + if (Ptr[0] >= 0x1e) + { + TRACE("EED configuration parameters: %x:%x\n", Ptr[13], Ptr[14]); + if (Ptr[13] != 0xffff && Ptr[14] != 0xffff) + { + PUCHAR SpecPtr = (PUCHAR)(ULONG_PTR)((Ptr[13] << 4) + Ptr[14]); + TRACE("SpecPtr: %x\n", SpecPtr); + TRACE("physical I/O port base address: %x\n", *(PUSHORT)&SpecPtr[0]); + TRACE("disk-drive control port address: %x\n", *(PUSHORT)&SpecPtr[2]); + TRACE("drive flags: %x\n", SpecPtr[4]); + TRACE("proprietary information: %x\n", SpecPtr[5]); + TRACE("IRQ for drive: %u\n", SpecPtr[6]); + TRACE("sector count for multi-sector transfers: %u\n", SpecPtr[7]); + TRACE("DMA control: %x\n", SpecPtr[8]); + TRACE("programmed I/O control: %x\n", SpecPtr[9]); + TRACE("drive options: %x\n", *(PUSHORT)&SpecPtr[10]); + } + } + if (Ptr[0] >= 0x42) + { + TRACE("signature: %x\n", Ptr[15]); + } +#endif + + return TRUE; +} + BOOLEAN PcDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry) { - EXTENDED_GEOMETRY ExtGeometry; - REGS RegsIn; - REGS RegsOut; - ULONG Cylinders; - - 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; } } diff --git a/reactos/boot/freeldr/freeldr/arch/i386/xboxdisk.c b/reactos/boot/freeldr/freeldr/arch/i386/xboxdisk.c index 1a28eda00f4..fa3e0a1deaa 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/xboxdisk.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/xboxdisk.c @@ -36,22 +36,22 @@ DBG_DEFAULT_CHANNEL(DISK); static struct { - ULONG SectorCountBeforePartition; - ULONG PartitionSectorCount; - UCHAR SystemIndicator; + ULONG SectorCountBeforePartition; + ULONG PartitionSectorCount; + UCHAR SystemIndicator; } XboxPartitions[] = { - /* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */ - { 0x0055F400, 0x0098f800, PARTITION_FAT32 }, /* Store, E: */ - { 0x00465400, 0x000FA000, PARTITION_FAT_16 }, /* System, C: */ - { 0x00000400, 0x00177000, PARTITION_FAT_16 }, /* Cache1, X: */ - { 0x00177400, 0x00177000, PARTITION_FAT_16 }, /* Cache2, Y: */ - { 0x002EE400, 0x00177000, PARTITION_FAT_16 } /* Cache3, Z: */ + /* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */ + { 0x0055F400, 0x0098f800, PARTITION_FAT32 }, /* Store , E: */ + { 0x00465400, 0x000FA000, PARTITION_FAT_16 }, /* System, C: */ + { 0x00000400, 0x00177000, PARTITION_FAT_16 }, /* Cache1, X: */ + { 0x00177400, 0x00177000, PARTITION_FAT_16 }, /* Cache2, Y: */ + { 0x002EE400, 0x00177000, PARTITION_FAT_16 } /* Cache3, Z: */ }; -#define IDE_SECTOR_BUF_SZ 512 -#define IDE_MAX_POLL_RETRIES 100000 -#define IDE_MAX_BUSY_RETRIES 50000 +#define IDE_SECTOR_BUF_SZ 512 +#define IDE_MAX_POLL_RETRIES 100000 +#define IDE_MAX_BUSY_RETRIES 50000 /* Control Block offsets and masks */ #define IDE_REG_ALT_STATUS 0x0000 @@ -111,131 +111,131 @@ static struct * Each macro takes an address of the command port block, and data */ #define IDEReadError(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ERROR))) + (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ERROR))) #define IDEWritePrecomp(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_PRECOMP), (Data))) + (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_PRECOMP), (Data))) #define IDEReadSectorCount(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT))) + (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT))) #define IDEWriteSectorCount(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT), (Data))) + (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT), (Data))) #define IDEReadSectorNum(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM))) + (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM))) #define IDEWriteSectorNum(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM), (Data))) + (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM), (Data))) #define IDEReadCylinderLow(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW))) + (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW))) #define IDEWriteCylinderLow(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW), (Data))) + (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW), (Data))) #define IDEReadCylinderHigh(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH))) + (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH))) #define IDEWriteCylinderHigh(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH), (Data))) + (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH), (Data))) #define IDEReadDriveHead(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD))) + (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD))) #define IDEWriteDriveHead(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD), (Data))) + (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD), (Data))) #define IDEReadStatus(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_STATUS))) + (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_STATUS))) #define IDEWriteCommand(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_COMMAND), (Data))) + (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_COMMAND), (Data))) #define IDEReadDMACommand(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address)))) + (READ_PORT_UCHAR((PUCHAR)((Address)))) #define IDEWriteDMACommand(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address)), (Data))) + (WRITE_PORT_UCHAR((PUCHAR)((Address)), (Data))) #define IDEReadDMAStatus(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + 2))) + (READ_PORT_UCHAR((PUCHAR)((Address) + 2))) #define IDEWriteDMAStatus(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + 2), (Data))) + (WRITE_PORT_UCHAR((PUCHAR)((Address) + 2), (Data))) #define IDEWritePRDTable(Address, Data) \ - (WRITE_PORT_ULONG((PULONG)((Address) + 4), (Data))) + (WRITE_PORT_ULONG((PULONG)((Address) + 4), (Data))) /* * Data block read and write commands */ #define IDEReadBlock(Address, Buffer, Count) \ - (READ_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2)) + (READ_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2)) #define IDEWriteBlock(Address, Buffer, Count) \ - (WRITE_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2)) + (WRITE_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2)) #define IDEReadBlock32(Address, Buffer, Count) \ - (READ_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4)) + (READ_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4)) #define IDEWriteBlock32(Address, Buffer, Count) \ - (WRITE_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4)) + (WRITE_PORT_BUFFER_ULONG((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4)) #define IDEReadWord(Address) \ - (READ_PORT_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT))) + (READ_PORT_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT))) /* * Access macros for control registers * Each macro takes an address of the control port blank and data */ #define IDEReadAltStatus(Address) \ - (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ALT_STATUS))) + (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ALT_STATUS))) #define IDEWriteDriveControl(Address, Data) \ - (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data))) + (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data))) /* IDE_DRIVE_IDENTIFY */ typedef struct _IDE_DRIVE_IDENTIFY { - USHORT ConfigBits; /*00*/ - USHORT LogicalCyls; /*01*/ - USHORT Reserved02; /*02*/ - USHORT LogicalHeads; /*03*/ - USHORT BytesPerTrack; /*04*/ - USHORT BytesPerSector; /*05*/ - USHORT SectorsPerTrack; /*06*/ - UCHAR InterSectorGap; /*07*/ - UCHAR InterSectorGapSize; - UCHAR Reserved08H; /*08*/ - UCHAR BytesInPLO; - USHORT VendorUniqueCnt; /*09*/ - char SerialNumber[20]; /*10*/ - USHORT ControllerType; /*20*/ - USHORT BufferSize; /*21*/ - USHORT ECCByteCnt; /*22*/ - char FirmwareRev[8]; /*23*/ - char ModelNumber[40]; /*27*/ - USHORT RWMultImplemented; /*47*/ - USHORT DWordIo; /*48*/ - USHORT Capabilities; /*49*/ + USHORT ConfigBits; /*00*/ + USHORT LogicalCyls; /*01*/ + USHORT Reserved02; /*02*/ + USHORT LogicalHeads; /*03*/ + USHORT BytesPerTrack; /*04*/ + USHORT BytesPerSector; /*05*/ + USHORT SectorsPerTrack; /*06*/ + UCHAR InterSectorGap; /*07*/ + UCHAR InterSectorGapSize; + UCHAR Reserved08H; /*08*/ + UCHAR BytesInPLO; + USHORT VendorUniqueCnt; /*09*/ + UCHAR SerialNumber[20]; /*10*/ + USHORT ControllerType; /*20*/ + USHORT BufferSize; /*21*/ + USHORT ECCByteCnt; /*22*/ + UCHAR FirmwareRev[8]; /*23*/ + UCHAR ModelNumber[40]; /*27*/ + USHORT RWMultImplemented; /*47*/ + USHORT DWordIo; /*48*/ + USHORT Capabilities; /*49*/ #define IDE_DRID_STBY_SUPPORTED 0x2000 #define IDE_DRID_IORDY_SUPPORTED 0x0800 #define IDE_DRID_IORDY_DISABLE 0x0400 #define IDE_DRID_LBA_SUPPORTED 0x0200 #define IDE_DRID_DMA_SUPPORTED 0x0100 - USHORT Reserved50; /*50*/ - USHORT MinPIOTransTime; /*51*/ - USHORT MinDMATransTime; /*52*/ - USHORT TMFieldsValid; /*53*/ - USHORT TMCylinders; /*54*/ - USHORT TMHeads; /*55*/ - USHORT TMSectorsPerTrk; /*56*/ - USHORT TMCapacityLo; /*57*/ - USHORT TMCapacityHi; /*58*/ - USHORT RWMultCurrent; /*59*/ - USHORT TMSectorCountLo; /*60*/ - USHORT TMSectorCountHi; /*61*/ - USHORT DmaModes; /*62*/ - USHORT MultiDmaModes; /*63*/ - USHORT Reserved64[5]; /*64*/ - USHORT Reserved69[2]; /*69*/ - USHORT Reserved71[4]; /*71*/ - USHORT MaxQueueDepth; /*75*/ - USHORT Reserved76[4]; /*76*/ - USHORT MajorRevision; /*80*/ - USHORT MinorRevision; /*81*/ - USHORT SupportedFeatures82; /*82*/ - USHORT SupportedFeatures83; /*83*/ - USHORT SupportedFeatures84; /*84*/ - USHORT EnabledFeatures85; /*85*/ - USHORT EnabledFeatures86; /*86*/ - USHORT EnabledFeatures87; /*87*/ - USHORT UltraDmaModes; /*88*/ - USHORT Reserved89[11]; /*89*/ - USHORT Max48BitAddress[4]; /*100*/ - USHORT Reserved104[151]; /*104*/ - USHORT Checksum; /*255*/ + USHORT Reserved50; /*50*/ + USHORT MinPIOTransTime; /*51*/ + USHORT MinDMATransTime; /*52*/ + USHORT TMFieldsValid; /*53*/ + USHORT TMCylinders; /*54*/ + USHORT TMHeads; /*55*/ + USHORT TMSectorsPerTrk; /*56*/ + USHORT TMCapacityLo; /*57*/ + USHORT TMCapacityHi; /*58*/ + USHORT RWMultCurrent; /*59*/ + USHORT TMSectorCountLo; /*60*/ + USHORT TMSectorCountHi; /*61*/ + USHORT DmaModes; /*62*/ + USHORT MultiDmaModes; /*63*/ + USHORT Reserved64[5]; /*64*/ + USHORT Reserved69[2]; /*69*/ + USHORT Reserved71[4]; /*71*/ + USHORT MaxQueueDepth; /*75*/ + USHORT Reserved76[4]; /*76*/ + USHORT MajorRevision; /*80*/ + USHORT MinorRevision; /*81*/ + USHORT SupportedFeatures82; /*82*/ + USHORT SupportedFeatures83; /*83*/ + USHORT SupportedFeatures84; /*84*/ + USHORT EnabledFeatures85; /*85*/ + USHORT EnabledFeatures86; /*86*/ + USHORT EnabledFeatures87; /*87*/ + USHORT UltraDmaModes; /*88*/ + USHORT Reserved89[11]; /*89*/ + USHORT Max48BitAddress[4]; /*100*/ + USHORT Reserved104[151]; /*104*/ + USHORT Checksum; /*255*/ } IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY; /* XboxDiskPolledRead @@ -247,21 +247,20 @@ typedef struct _IDE_DRIVE_IDENTIFY * PASSIVE_LEVEL * * ARGUMENTS: - * ULONG CommandPort Address of command port for drive - * ULONG ControlPort Address of control port for drive - * UCHAR PreComp Value to write to precomp register - * UCHAR SectorCnt Value to write to sectorCnt register - * UCHAR SectorNum Value to write to sectorNum register - * UCHAR CylinderLow Value to write to CylinderLow register - * UCHAR CylinderHigh Value to write to CylinderHigh register - * UCHAR DrvHead Value to write to Drive/Head register - * UCHAR Command Value to write to Command register - * PVOID Buffer Buffer for output data + * ULONG CommandPort Address of command port for drive + * ULONG ControlPort Address of control port for drive + * UCHAR PreComp Value to write to precomp register + * UCHAR SectorCnt Value to write to sectorCnt register + * UCHAR SectorNum Value to write to sectorNum register + * UCHAR CylinderLow Value to write to CylinderLow register + * UCHAR CylinderHigh Value to write to CylinderHigh register + * UCHAR DrvHead Value to write to Drive/Head register + * UCHAR Command Value to write to Command register + * PVOID Buffer Buffer for output data * * RETURNS: * BOOLEAN: TRUE success, FALSE error */ - static BOOLEAN XboxDiskPolledRead(ULONG CommandPort, ULONG ControlPort, @@ -274,300 +273,296 @@ XboxDiskPolledRead(ULONG CommandPort, UCHAR Command, PVOID Buffer) { - ULONG SectorCount = 0; - ULONG RetryCount; - BOOLEAN Junk = FALSE; - UCHAR Status; + ULONG SectorCount = 0; + ULONG RetryCount; + BOOLEAN Junk = FALSE; + UCHAR Status; - /* Wait for BUSY to clear */ - for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++) + /* Wait for BUSY to clear */ + for (RetryCount = 0; RetryCount < IDE_MAX_BUSY_RETRIES; RetryCount++) { - Status = IDEReadStatus(CommandPort); - if (!(Status & IDE_SR_BUSY)) - { - 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 */ diff --git a/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c b/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c deleted file mode 100644 index d5a68811e9c..00000000000 --- a/reactos/boot/freeldr/freeldr/arch/i386/xboxhw.c +++ /dev/null @@ -1,531 +0,0 @@ -/* - * FreeLoader - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include - -#define NDEBUG -#include - -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 */ diff --git a/reactos/boot/freeldr/freeldr/disk/disk.c b/reactos/boot/freeldr/freeldr/disk/disk.c index 4cdf12f7f5a..68218cfd018 100644 --- a/reactos/boot/freeldr/freeldr/disk/disk.c +++ b/reactos/boot/freeldr/freeldr/disk/disk.c @@ -19,29 +19,30 @@ #ifndef _M_ARM #include + +#define NDEBUG #include DBG_DEFAULT_CHANNEL(DISK); static BOOLEAN bReportError = TRUE; -///////////////////////////////////////////////////////////////////////////////////////////// -// FUNCTIONS -///////////////////////////////////////////////////////////////////////////////////////////// +/* FUNCTIONS *****************************************************************/ -VOID DiskReportError (BOOLEAN bError) +VOID DiskReportError(BOOLEAN bError) { bReportError = bError; } VOID DiskError(PCSTR ErrorString, ULONG ErrorCode) { - CHAR ErrorCodeString[200]; + CHAR ErrorCodeString[200]; if (bReportError == FALSE) return; - sprintf(ErrorCodeString, "%s\n\nError Code: 0x%lx\nError: %s", ErrorString, ErrorCode, DiskGetErrorCodeString(ErrorCode)); + sprintf(ErrorCodeString, "%s\n\nError Code: 0x%lx\nError: %s", + ErrorString, ErrorCode, DiskGetErrorCodeString(ErrorCode)); TRACE("%s\n", ErrorCodeString); @@ -83,21 +84,17 @@ PCSTR DiskGetErrorCodeString(ULONG ErrorCode) } } -// This function is in arch/i386/i386disk.c -//BOOLEAN DiskReadLogicalSectors(ULONG DriveNumber, U64 SectorNumber, ULONG SectorCount, PVOID Buffer) - BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber) { - // Hard disks use drive numbers >= 0x80 - // So if the drive number indicates a hard disk - // then return FALSE - // 0x49 is our magic ramdisk drive, so return FALSE for that too + /* + * Hard disks use drive numbers >= 0x80 . So if the drive number + * indicates a hard disk then return FALSE. + * 0x49 is our magic ramdisk drive, so return FALSE for that too. + */ if ((DriveNumber >= 0x80) || (DriveNumber == 0x49)) - { return FALSE; - } - // Drive is a floppy diskette so return TRUE + /* The drive is a floppy diskette so return TRUE */ return TRUE; } @@ -191,10 +188,4 @@ DiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size) return TRUE; } -// This function is in arch/i386/i386disk.c -//VOID DiskStopFloppyMotor(VOID) - -// This function is in arch/i386/i386disk.c -//ULONG DiskGetCacheableBlockCount(UCHAR DriveNumber) - #endif diff --git a/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h b/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h index 0ce2dbd94d3..1df325b7700 100644 --- a/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h +++ b/reactos/boot/freeldr/freeldr/include/arch/pc/machpc.h @@ -49,6 +49,9 @@ VOID PcPrepareForReactOS(IN BOOLEAN Setup); PFREELDR_MEMORY_DESCRIPTOR PcMemGetMemoryMap(ULONG *MemoryMapSize); +BOOLEAN DiskResetController(UCHAR DriveNumber); +BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize); + BOOLEAN PcDiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size); BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); BOOLEAN PcDiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry); diff --git a/reactos/boot/freeldr/freeldr/include/disk.h b/reactos/boot/freeldr/freeldr/include/disk.h index 330fc21e1fe..7431755940b 100644 --- a/reactos/boot/freeldr/freeldr/include/disk.h +++ b/reactos/boot/freeldr/freeldr/include/disk.h @@ -23,10 +23,10 @@ typedef struct _GEOMETRY { - ULONG Cylinders; // Number of cylinders on the disk - ULONG Heads; // Number of heads on the disk - ULONG Sectors; // Number of sectors per track - ULONG BytesPerSector; // Number of bytes per sector + ULONG Cylinders; // Number of cylinders on the disk + ULONG Heads; // Number of heads on the disk + ULONG Sectors; // Number of sectors per track + ULONG BytesPerSector; // Number of bytes per sector } GEOMETRY, *PGEOMETRY; @@ -36,14 +36,15 @@ typedef struct _GEOMETRY #include typedef struct _EXTENDED_GEOMETRY { - USHORT Size; - USHORT Flags; - ULONG Cylinders; - ULONG Heads; - ULONG SectorsPerTrack; - ULONGLONG Sectors; - USHORT BytesPerSector; - ULONG PDPTE; + USHORT Size; + USHORT Flags; + ULONG Cylinders; + ULONG Heads; + ULONG SectorsPerTrack; + ULONGLONG Sectors; + USHORT BytesPerSector; + ULONG PDPTE; + } EXTENDED_GEOMETRY, *PEXTENDED_GEOMETRY; // @@ -51,16 +52,17 @@ typedef struct _EXTENDED_GEOMETRY // typedef struct _PARTITION_TABLE_ENTRY { - UCHAR BootIndicator; // 0x00 - non-bootable partition, 0x80 - bootable partition (one partition only) - UCHAR StartHead; // Beginning head number - UCHAR StartSector; // Beginning sector (2 high bits of cylinder #) - UCHAR StartCylinder; // Beginning cylinder# (low order bits of cylinder #) - UCHAR SystemIndicator; // System indicator - UCHAR EndHead; // Ending head number - UCHAR EndSector; // Ending sector (2 high bits of cylinder #) - UCHAR EndCylinder; // Ending cylinder# (low order bits of cylinder #) - ULONG SectorCountBeforePartition; // Number of sectors preceding the partition - ULONG PartitionSectorCount; // Number of sectors in the partition + UCHAR BootIndicator; // 0x00 - non-bootable partition, + // 0x80 - bootable partition (one partition only) + UCHAR StartHead; // Beginning head number + UCHAR StartSector; // Beginning sector (2 high bits of cylinder #) + UCHAR StartCylinder; // Beginning cylinder# (low order bits of cylinder #) + UCHAR SystemIndicator; // System indicator + UCHAR EndHead; // Ending head number + UCHAR EndSector; // Ending sector (2 high bits of cylinder #) + UCHAR EndCylinder; // Ending cylinder# (low order bits of cylinder #) + ULONG SectorCountBeforePartition; // Number of sectors preceding the partition + ULONG PartitionSectorCount; // Number of sectors in the partition } PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY; @@ -69,11 +71,11 @@ typedef struct _PARTITION_TABLE_ENTRY // typedef struct _MASTER_BOOT_RECORD { - UCHAR MasterBootRecordCodeAndData[0x1b8]; /* 0x000 */ - ULONG Signature; /* 0x1B8 */ - USHORT Reserved; /* 0x1BC */ - PARTITION_TABLE_ENTRY PartitionTable[4]; /* 0x1BE */ - USHORT MasterBootRecordMagic; /* 0x1FE */ + UCHAR MasterBootRecordCodeAndData[0x1b8]; /* 0x000 */ + ULONG Signature; /* 0x1B8 */ + USHORT Reserved; /* 0x1BC */ + PARTITION_TABLE_ENTRY PartitionTable[4]; /* 0x1BE */ + USHORT MasterBootRecordMagic; /* 0x1FE */ } MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD; #include @@ -107,16 +109,11 @@ typedef struct _MASTER_BOOT_RECORD /////////////////////////////////////////////////////////////////////////////////////// // -// i386 BIOS Disk Functions (i386disk.c) +// PC x86/64 BIOS Disk Functions (pcdisk.c) // /////////////////////////////////////////////////////////////////////////////////////// #if defined(__i386__) || defined(_M_AMD64) - -BOOLEAN DiskResetController(UCHAR DriveNumber); -BOOLEAN DiskInt13ExtensionsSupported(UCHAR DriveNumber); -//VOID DiskStopFloppyMotor(VOID); -BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize); - +VOID DiskStopFloppyMotor(VOID); #endif // defined __i386__ || defined(_M_AMD64) /////////////////////////////////////////////////////////////////////////////////////// @@ -124,12 +121,10 @@ BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHOR // FreeLoader Disk Functions // /////////////////////////////////////////////////////////////////////////////////////// -VOID DiskReportError (BOOLEAN bError); -VOID DiskError(PCSTR ErrorString, ULONG ErrorCode); -PCSTR DiskGetErrorCodeString(ULONG ErrorCode); -BOOLEAN DiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer); // Implemented in i386disk.c -BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber); -VOID DiskStopFloppyMotor(VOID); // Implemented in i386disk.c +VOID DiskReportError (BOOLEAN bError); +VOID DiskError(PCSTR ErrorString, ULONG ErrorCode); +PCSTR DiskGetErrorCodeString(ULONG ErrorCode); +BOOLEAN DiskIsDriveRemovable(UCHAR DriveNumber); extern UCHAR FrldrBootDrive; extern ULONG FrldrBootPartition; extern PVOID DiskReadBuffer; @@ -143,10 +138,13 @@ BOOLEAN DiskGetBootPath(OUT PCHAR BootPath, IN ULONG Size); // Fixed Disk Partition Management Functions // /////////////////////////////////////////////////////////////////////////////////////// -BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry, ULONG *ActivePartition); -BOOLEAN DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry); -BOOLEAN DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry); -BOOLEAN DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry); -BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord); +BOOLEAN DiskGetActivePartitionEntry(UCHAR DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry, ULONG *ActivePartition); +BOOLEAN DiskGetPartitionEntry(UCHAR DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry); +BOOLEAN DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry); +BOOLEAN DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry); +BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord); +/* + * SCSI support (disk/scsiport.c) + */ ULONG LoadBootDeviceDriver(VOID); -- 2.17.1