#include <freeldr.h>
+#include <debug.h>
+DBG_DEFAULT_CHANNEL(HWDETECT);
+
+
+BOOLEAN
+XboxFindPciBios(PPCI_REGISTRY_INFO BusData)
+{
+ /* We emulate PCI BIOS here, there are 2 known working PCI buses on an original Xbox */
+
+ BusData->NoBuses = 2;
+ BusData->MajorRevision = 1;
+ BusData->MinorRevision = 0;
+ BusData->HardwareMechanism = 1;
+ return TRUE;
+}
+
+extern
VOID
-XboxMachInit(const char *CmdLine)
+DetectSerialPointerPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey, PUCHAR Base);
+
+static
+ULONG
+XboxGetSerialPort(ULONG Index, PULONG Irq)
{
- /* 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");
+ /*
+ * Xbox may have maximum two Serial COM ports
+ * if the Super I/O chip is connected via LPC
+ */
+ static const UCHAR Device[MAX_XBOX_COM_PORTS] = {LPC_DEVICE_SERIAL_PORT_1, LPC_DEVICE_SERIAL_PORT_2};
+ ULONG ComBase = 0;
+
+ // Enter Configuration
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_ENTER_CONFIG_KEY);
+
+ // Select serial device
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_NUMBER);
+ WRITE_PORT_UCHAR(LPC_IO_BASE + 1, Device[Index]);
+
+ // Check if selected device is active
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_ACTIVATE);
+ if (READ_PORT_UCHAR(LPC_IO_BASE + 1) == 1)
+ {
+ // Read LSB
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_BASE_ADDRESS_LOW);
+ ComBase = READ_PORT_UCHAR(LPC_IO_BASE + 1);
+ // Read MSB
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_BASE_ADDRESS_HIGH);
+ ComBase |= (READ_PORT_UCHAR(LPC_IO_BASE + 1) << 8);
+ // Read IRQ
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_INTERRUPT);
+ *Irq = READ_PORT_UCHAR(LPC_IO_BASE + 1);
+ }
+
+ // Exit Configuration
+ WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_EXIT_CONFIG_KEY);
+
+ return ComBase;
}
+extern
VOID
-XboxPrepareForReactOS(IN BOOLEAN Setup)
+DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey, GET_SERIAL_PORT MachGetSerialPort, ULONG Count);
+
+VOID
+XboxGetExtendedBIOSData(PULONG ExtendedBIOSDataArea, PULONG ExtendedBIOSDataSize)
+{
+ TRACE("XboxGetExtendedBIOSData(): UNIMPLEMENTED\n");
+ *ExtendedBIOSDataArea = 0;
+ *ExtendedBIOSDataSize = 0;
+}
+
+// NOTE: Similar to machpc.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
//
- // On XBOX, prepare video and turn off the floppy motor
+ *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);
+
//
- XboxVideoPrepareForReactOS(Setup);
+ // Return configuration data
+ //
+ *pSize = Size;
+ return PartialResourceList;
+}
+
+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);
+ DetectSerialPorts(BusKey, XboxGetSerialPort, MAX_XBOX_COM_PORTS);
+
+ /* FIXME: Detect more ISA devices */
+}
+
+static
+UCHAR
+XboxGetFloppyCount(VOID)
+{
+ /* On a PC we use CMOS/RTC I/O ports 0x70 and 0x71 to detect floppies.
+ * However an Xbox CMOS memory range [0x10, 0x70) and [0x80, 0x100)
+ * is filled with 0x55 0xAA 0x55 0xAA ... byte pattern which is used
+ * to validate the date/time settings by Xbox OS.
+ *
+ * Technically it's possible to connect a floppy drive to Xbox, but
+ * CMOS detection method should not be used here. */
+
+ WARN("XboxGetFloppyCount() is UNIMPLEMENTED, returning 0\n");
+ return 0;
+}
+
+PCONFIGURATION_COMPONENT_DATA
+XboxHwDetect(VOID)
+{
+ PCONFIGURATION_COMPONENT_DATA SystemKey;
+ ULONG BusNumber = 0;
+
+ TRACE("DetectHardware()\n");
+
+ /* Create the 'System' key */
+ FldrCreateSystemKey(&SystemKey);
+
+ GetHarddiskConfigurationData = XboxGetHarddiskConfigurationData;
+ FindPciBios = XboxFindPciBios;
+
+ /* TODO: Build actual xbox's hardware configuration tree */
+ DetectPciBios(SystemKey, &BusNumber);
+ 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.VideoGetFontsFromFirmware = XboxVideoGetFontsFromFirmware;
+ MachVtbl.VideoSetTextCursorPosition = XboxVideoSetTextCursorPosition;
+ 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.GetExtendedBIOSData = XboxGetExtendedBIOSData;
+ MachVtbl.GetFloppyCount = XboxGetFloppyCount;
+ 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(VOID)
+{
+ /* On XBOX, prepare video and turn off the floppy motor */
+ XboxVideoPrepareForReactOS();
DiskStopFloppyMotor();
}
+
+/* EOF */