[FREELDR] Formatting only.
[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 DBG_DEFAULT_CHANNEL(HWDETECT);
23
24
25 BOOLEAN
26 XboxFindPciBios(PPCI_REGISTRY_INFO BusData)
27 {
28 /* We emulate PCI BIOS here, there are 2 known working PCI buses on an original Xbox */
29
30 BusData->NoBuses = 2;
31 BusData->MajorRevision = 1;
32 BusData->MinorRevision = 0;
33 BusData->HardwareMechanism = 1;
34 return TRUE;
35 }
36
37 extern
38 VOID
39 DetectSerialPointerPeripheral(PCONFIGURATION_COMPONENT_DATA ControllerKey, PUCHAR Base);
40
41 static
42 ULONG
43 XboxGetSerialPort(ULONG Index, PULONG Irq)
44 {
45 /*
46 * Xbox may have maximum two Serial COM ports
47 * if the Super I/O chip is connected via LPC
48 */
49 static const UCHAR Device[MAX_XBOX_COM_PORTS] = {LPC_DEVICE_SERIAL_PORT_1, LPC_DEVICE_SERIAL_PORT_2};
50 ULONG ComBase = 0;
51
52 // Enter Configuration
53 WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_ENTER_CONFIG_KEY);
54
55 // Select serial device
56 WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_NUMBER);
57 WRITE_PORT_UCHAR(LPC_IO_BASE + 1, Device[Index]);
58
59 // Check if selected device is active
60 WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_ACTIVATE);
61 if (READ_PORT_UCHAR(LPC_IO_BASE + 1) == 1)
62 {
63 // Read LSB
64 WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_BASE_ADDRESS_LOW);
65 ComBase = READ_PORT_UCHAR(LPC_IO_BASE + 1);
66 // Read MSB
67 WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_BASE_ADDRESS_HIGH);
68 ComBase |= (READ_PORT_UCHAR(LPC_IO_BASE + 1) << 8);
69 // Read IRQ
70 WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_CONFIG_DEVICE_INTERRUPT);
71 *Irq = READ_PORT_UCHAR(LPC_IO_BASE + 1);
72 }
73
74 // Exit Configuration
75 WRITE_PORT_UCHAR(LPC_IO_BASE, LPC_EXIT_CONFIG_KEY);
76
77 return ComBase;
78 }
79
80 extern
81 VOID
82 DetectSerialPorts(PCONFIGURATION_COMPONENT_DATA BusKey, GET_SERIAL_PORT MachGetSerialPort, ULONG Count);
83
84 VOID
85 XboxGetExtendedBIOSData(PULONG ExtendedBIOSDataArea, PULONG ExtendedBIOSDataSize)
86 {
87 TRACE("XboxGetExtendedBIOSData(): UNIMPLEMENTED\n");
88 *ExtendedBIOSDataArea = 0;
89 *ExtendedBIOSDataSize = 0;
90 }
91
92 // NOTE: Similar to machpc.c!PcGetHarddiskConfigurationData(),
93 // but without extended geometry support.
94 static
95 PCM_PARTIAL_RESOURCE_LIST
96 XboxGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
97 {
98 PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
99 PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
100 //EXTENDED_GEOMETRY ExtGeometry;
101 GEOMETRY Geometry;
102 ULONG Size;
103
104 //
105 // Initialize returned size
106 //
107 *pSize = 0;
108
109 /* Set 'Configuration Data' value */
110 Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
111 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
112 PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
113 if (PartialResourceList == NULL)
114 {
115 ERR("Failed to allocate a full resource descriptor\n");
116 return NULL;
117 }
118
119 memset(PartialResourceList, 0, Size);
120 PartialResourceList->Version = 1;
121 PartialResourceList->Revision = 1;
122 PartialResourceList->Count = 1;
123 PartialResourceList->PartialDescriptors[0].Type =
124 CmResourceTypeDeviceSpecific;
125 // PartialResourceList->PartialDescriptors[0].ShareDisposition =
126 // PartialResourceList->PartialDescriptors[0].Flags =
127 PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
128 sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
129
130 /* Get pointer to geometry data */
131 DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
132
133 /* Get the disk geometry */
134 //ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
135
136 if (MachDiskGetDriveGeometry(DriveNumber, &Geometry))
137 {
138 DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
139 DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
140 DiskGeometry->SectorsPerTrack = Geometry.Sectors;
141 DiskGeometry->NumberOfHeads = Geometry.Heads;
142 }
143 else
144 {
145 ERR("Reading disk geometry failed\n");
146 FrLdrHeapFree(PartialResourceList, TAG_HW_RESOURCE_LIST);
147 return NULL;
148 }
149 TRACE("Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
150 DriveNumber,
151 DiskGeometry->NumberOfCylinders,
152 DiskGeometry->NumberOfHeads,
153 DiskGeometry->SectorsPerTrack,
154 DiskGeometry->BytesPerSector);
155
156 //
157 // Return configuration data
158 //
159 *pSize = Size;
160 return PartialResourceList;
161 }
162
163 static
164 VOID
165 DetectIsaBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
166 {
167 PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
168 PCONFIGURATION_COMPONENT_DATA BusKey;
169 ULONG Size;
170
171 /* Set 'Configuration Data' value */
172 Size = sizeof(CM_PARTIAL_RESOURCE_LIST) -
173 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
174 PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
175 if (PartialResourceList == NULL)
176 {
177 TRACE("Failed to allocate resource descriptor\n");
178 return;
179 }
180
181 /* Initialize resource descriptor */
182 memset(PartialResourceList, 0, Size);
183 PartialResourceList->Version = 1;
184 PartialResourceList->Revision = 1;
185 PartialResourceList->Count = 0;
186
187 /* Create new bus key */
188 FldrCreateComponentKey(SystemKey,
189 AdapterClass,
190 MultiFunctionAdapter,
191 0x0,
192 0x0,
193 0xFFFFFFFF,
194 "ISA",
195 PartialResourceList,
196 Size,
197 &BusKey);
198
199 /* Increment bus number */
200 (*BusNumber)++;
201
202 /* Detect ISA/BIOS devices */
203 DetectBiosDisks(SystemKey, BusKey);
204 DetectSerialPorts(BusKey, XboxGetSerialPort, MAX_XBOX_COM_PORTS);
205
206 /* FIXME: Detect more ISA devices */
207 }
208
209 static
210 UCHAR
211 XboxGetFloppyCount(VOID)
212 {
213 /* On a PC we use CMOS/RTC I/O ports 0x70 and 0x71 to detect floppies.
214 * However an Xbox CMOS memory range [0x10, 0x70) and [0x80, 0x100)
215 * is filled with 0x55 0xAA 0x55 0xAA ... byte pattern which is used
216 * to validate the date/time settings by Xbox OS.
217 *
218 * Technically it's possible to connect a floppy drive to Xbox, but
219 * CMOS detection method should not be used here. */
220
221 WARN("XboxGetFloppyCount() is UNIMPLEMENTED, returning 0\n");
222 return 0;
223 }
224
225 PCONFIGURATION_COMPONENT_DATA
226 XboxHwDetect(VOID)
227 {
228 PCONFIGURATION_COMPONENT_DATA SystemKey;
229 ULONG BusNumber = 0;
230
231 TRACE("DetectHardware()\n");
232
233 /* Create the 'System' key */
234 FldrCreateSystemKey(&SystemKey);
235
236 GetHarddiskConfigurationData = XboxGetHarddiskConfigurationData;
237 FindPciBios = XboxFindPciBios;
238
239 /* TODO: Build actual xbox's hardware configuration tree */
240 DetectPciBios(SystemKey, &BusNumber);
241 DetectIsaBios(SystemKey, &BusNumber);
242
243 TRACE("DetectHardware() Done\n");
244 return SystemKey;
245 }
246
247 VOID XboxHwIdle(VOID)
248 {
249 /* UNIMPLEMENTED */
250 }
251
252
253 /******************************************************************************/
254
255 VOID
256 XboxMachInit(const char *CmdLine)
257 {
258 /* Set LEDs to red before anything is initialized */
259 XboxSetLED("rrrr");
260
261 /* Initialize our stuff */
262 XboxMemInit();
263 XboxVideoInit();
264
265 /* Setup vtbl */
266 MachVtbl.ConsPutChar = XboxConsPutChar;
267 MachVtbl.ConsKbHit = XboxConsKbHit;
268 MachVtbl.ConsGetCh = XboxConsGetCh;
269 MachVtbl.VideoClearScreen = XboxVideoClearScreen;
270 MachVtbl.VideoSetDisplayMode = XboxVideoSetDisplayMode;
271 MachVtbl.VideoGetDisplaySize = XboxVideoGetDisplaySize;
272 MachVtbl.VideoGetBufferSize = XboxVideoGetBufferSize;
273 MachVtbl.VideoGetFontsFromFirmware = XboxVideoGetFontsFromFirmware;
274 MachVtbl.VideoSetTextCursorPosition = XboxVideoSetTextCursorPosition;
275 MachVtbl.VideoHideShowTextCursor = XboxVideoHideShowTextCursor;
276 MachVtbl.VideoPutChar = XboxVideoPutChar;
277 MachVtbl.VideoCopyOffScreenBufferToVRAM = XboxVideoCopyOffScreenBufferToVRAM;
278 MachVtbl.VideoIsPaletteFixed = XboxVideoIsPaletteFixed;
279 MachVtbl.VideoSetPaletteColor = XboxVideoSetPaletteColor;
280 MachVtbl.VideoGetPaletteColor = XboxVideoGetPaletteColor;
281 MachVtbl.VideoSync = XboxVideoSync;
282 MachVtbl.Beep = PcBeep;
283 MachVtbl.PrepareForReactOS = XboxPrepareForReactOS;
284 MachVtbl.GetMemoryMap = XboxMemGetMemoryMap;
285 MachVtbl.GetExtendedBIOSData = XboxGetExtendedBIOSData;
286 MachVtbl.GetFloppyCount = XboxGetFloppyCount;
287 MachVtbl.DiskGetBootPath = DiskGetBootPath;
288 MachVtbl.DiskReadLogicalSectors = XboxDiskReadLogicalSectors;
289 MachVtbl.DiskGetDriveGeometry = XboxDiskGetDriveGeometry;
290 MachVtbl.DiskGetCacheableBlockCount = XboxDiskGetCacheableBlockCount;
291 MachVtbl.GetTime = XboxGetTime;
292 MachVtbl.InitializeBootDevices = PcInitializeBootDevices;
293 MachVtbl.HwDetect = XboxHwDetect;
294 MachVtbl.HwIdle = XboxHwIdle;
295
296 /* Set LEDs to orange after init */
297 XboxSetLED("oooo");
298 }
299
300 VOID
301 XboxPrepareForReactOS(VOID)
302 {
303 /* On XBOX, prepare video and turn off the floppy motor */
304 XboxVideoPrepareForReactOS();
305 DiskStopFloppyMotor();
306 }
307
308 /* EOF */