[FREELDR] Add PCI BIOS emulation and PCI bus enumeration for Xbox (#1830)
[reactos.git] / boot / freeldr / freeldr / arch / i386 / machxbox.c
1 /*
2 * FreeLoader
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include <freeldr.h>
20
21 #include <debug.h>
22
23 DBG_DEFAULT_CHANNEL(HWDETECT);
24
25
26 BOOLEAN
27 XboxFindPciBios(PPCI_REGISTRY_INFO BusData)
28 {
29 /* We emulate PCI BIOS here, there are 2 known working PCI buses on an original Xbox */
30
31 BusData->NoBuses = 2;
32 BusData->MajorRevision = 1;
33 BusData->MinorRevision = 0;
34 BusData->HardwareMechanism = 1;
35 return TRUE;
36 }
37
38 VOID
39 XboxGetExtendedBIOSData(PULONG ExtendedBIOSDataArea, PULONG ExtendedBIOSDataSize)
40 {
41 TRACE("XboxGetExtendedBIOSData(): UNIMPLEMENTED\n");
42 *ExtendedBIOSDataArea = 0;
43 *ExtendedBIOSDataSize = 0;
44 }
45
46 // NOTE: Similar to machpc.c!PcGetHarddiskConfigurationData(),
47 // but without extended geometry support.
48 static
49 PCM_PARTIAL_RESOURCE_LIST
50 XboxGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
51 {
52 PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
53 PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
54 //EXTENDED_GEOMETRY ExtGeometry;
55 GEOMETRY Geometry;
56 ULONG Size;
57
58 //
59 // Initialize returned size
60 //
61 *pSize = 0;
62
63 /* Set 'Configuration Data' value */
64 Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
65 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
66 PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
67 if (PartialResourceList == NULL)
68 {
69 ERR("Failed to allocate a full resource descriptor\n");
70 return NULL;
71 }
72
73 memset(PartialResourceList, 0, Size);
74 PartialResourceList->Version = 1;
75 PartialResourceList->Revision = 1;
76 PartialResourceList->Count = 1;
77 PartialResourceList->PartialDescriptors[0].Type =
78 CmResourceTypeDeviceSpecific;
79 // PartialResourceList->PartialDescriptors[0].ShareDisposition =
80 // PartialResourceList->PartialDescriptors[0].Flags =
81 PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
82 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
83
84 /* Get pointer to geometry data */
85 DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
86
87 /* Get the disk geometry */
88 //ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
89
90 if (MachDiskGetDriveGeometry(DriveNumber, &Geometry))
91 {
92 DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
93 DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
94 DiskGeometry->SectorsPerTrack = Geometry.Sectors;
95 DiskGeometry->NumberOfHeads = Geometry.Heads;
96 }
97 else
98 {
99 ERR("Reading disk geometry failed\n");
100 FrLdrHeapFree(PartialResourceList, TAG_HW_RESOURCE_LIST);
101 return NULL;
102 }
103 TRACE("Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
104 DriveNumber,
105 DiskGeometry->NumberOfCylinders,
106 DiskGeometry->NumberOfHeads,
107 DiskGeometry->SectorsPerTrack,
108 DiskGeometry->BytesPerSector);
109
110 //
111 // Return configuration data
112 //
113 *pSize = Size;
114 return PartialResourceList;
115 }
116
117 static
118 VOID
119 DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
120 {
121 PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
122 PCONFIGURATION_COMPONENT_DATA BusKey;
123 ULONG Size;
124
125 /* Set 'Configuration Data' value */
126 Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
127 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
128 PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
129 if (PartialResourceList == NULL)
130 {
131 TRACE("Failed to allocate resource descriptor\n");
132 return;
133 }
134
135 /* Initialize resource descriptor */
136 memset(PartialResourceList, 0, Size);
137 PartialResourceList->Version = 1;
138 PartialResourceList->Revision = 1;
139 PartialResourceList->Count = 0;
140
141 /* Create new bus key */
142 FldrCreateComponentKey(SystemKey,
143 AdapterClass,
144 MultiFunctionAdapter,
145 0x0,
146 0x0,
147 0xFFFFFFFF,
148 "ISA",
149 PartialResourceList,
150 Size,
151 &BusKey);
152
153 /* Increment bus number */
154 (*BusNumber)++;
155
156 /* Detect ISA/BIOS devices */
157 DetectBiosDisks(SystemKey, BusKey);
158
159 /* FIXME: Detect more ISA devices */
160 }
161
162 static
163 UCHAR
164 XboxGetFloppyCount(VOID)
165 {
166 /* On a PC we use CMOS/RTC I/O ports 0x70 and 0x71 to detect floppies.
167 * However an Xbox CMOS memory range [0x10, 0x70) and [0x80, 0x100)
168 * is filled with 0x55 0xAA 0x55 0xAA ... byte pattern which is used
169 * to validate the date/time settings by Xbox OS.
170 *
171 * Technically it's possible to connect a floppy drive to Xbox, but
172 * CMOS detection method should not be used here. */
173
174 WARN("XboxGetFloppyCount() is UNIMPLEMENTED, returning 0\n");
175 return 0;
176 }
177
178 PCONFIGURATION_COMPONENT_DATA
179 XboxHwDetect(VOID)
180 {
181 PCONFIGURATION_COMPONENT_DATA SystemKey;
182 ULONG BusNumber = 0;
183
184 TRACE("DetectHardware()\n");
185
186 /* Create the 'System' key */
187 FldrCreateSystemKey(&SystemKey);
188
189 GetHarddiskConfigurationData = XboxGetHarddiskConfigurationData;
190 FindPciBios = XboxFindPciBios;
191
192 /* TODO: Build actual xbox's hardware configuration tree */
193 DetectPciBios(SystemKey, &BusNumber);
194 DetectIsaBios(SystemKey, &BusNumber);
195
196 TRACE("DetectHardware() Done\n");
197 return SystemKey;
198 }
199
200 VOID XboxHwIdle(VOID)
201 {
202 /* UNIMPLEMENTED */
203 }
204
205
206 /******************************************************************************/
207
208 VOID
209 XboxMachInit(const char *CmdLine)
210 {
211 /* Set LEDs to red before anything is initialized */
212 XboxSetLED("rrrr");
213
214 /* Initialize our stuff */
215 XboxMemInit();
216 XboxVideoInit();
217
218 /* Setup vtbl */
219 MachVtbl.ConsPutChar = XboxConsPutChar;
220 MachVtbl.ConsKbHit = XboxConsKbHit;
221 MachVtbl.ConsGetCh = XboxConsGetCh;
222 MachVtbl.VideoClearScreen = XboxVideoClearScreen;
223 MachVtbl.VideoSetDisplayMode = XboxVideoSetDisplayMode;
224 MachVtbl.VideoGetDisplaySize = XboxVideoGetDisplaySize;
225 MachVtbl.VideoGetBufferSize = XboxVideoGetBufferSize;
226 MachVtbl.VideoGetFontsFromFirmware = XboxVideoGetFontsFromFirmware;
227 MachVtbl.VideoHideShowTextCursor = XboxVideoHideShowTextCursor;
228 MachVtbl.VideoPutChar = XboxVideoPutChar;
229 MachVtbl.VideoCopyOffScreenBufferToVRAM = XboxVideoCopyOffScreenBufferToVRAM;
230 MachVtbl.VideoIsPaletteFixed = XboxVideoIsPaletteFixed;
231 MachVtbl.VideoSetPaletteColor = XboxVideoSetPaletteColor;
232 MachVtbl.VideoGetPaletteColor = XboxVideoGetPaletteColor;
233 MachVtbl.VideoSync = XboxVideoSync;
234 MachVtbl.Beep = PcBeep;
235 MachVtbl.PrepareForReactOS = XboxPrepareForReactOS;
236 MachVtbl.GetMemoryMap = XboxMemGetMemoryMap;
237 MachVtbl.GetExtendedBIOSData = XboxGetExtendedBIOSData;
238 MachVtbl.GetFloppyCount = XboxGetFloppyCount;
239 MachVtbl.DiskGetBootPath = DiskGetBootPath;
240 MachVtbl.DiskReadLogicalSectors = XboxDiskReadLogicalSectors;
241 MachVtbl.DiskGetDriveGeometry = XboxDiskGetDriveGeometry;
242 MachVtbl.DiskGetCacheableBlockCount = XboxDiskGetCacheableBlockCount;
243 MachVtbl.GetTime = XboxGetTime;
244 MachVtbl.InitializeBootDevices = PcInitializeBootDevices;
245 MachVtbl.HwDetect = XboxHwDetect;
246 MachVtbl.HwIdle = XboxHwIdle;
247
248 /* Set LEDs to orange after init */
249 XboxSetLED("oooo");
250 }
251
252 VOID
253 XboxPrepareForReactOS(VOID)
254 {
255 /* On XBOX, prepare video and turn off the floppy motor */
256 XboxVideoPrepareForReactOS();
257 DiskStopFloppyMotor();
258 }
259
260 /* EOF */