f813d2aa9bd4f78fab3e95e80b41b4e5bebf0709
[reactos.git] / reactos / boot / freeldr / freeldr / machine.c
1 /* $Id$
2 *
3 * FreeLoader
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <freeldr.h>
21
22 #undef MachConsPutChar
23 #undef MachConsKbHit
24 #undef MachConsGetCh
25 #undef MachVideoClearScreen
26 #undef MachVideoSetDisplayMode
27 #undef MachVideoGetDisplaySize
28 #undef MachVideoGetBufferSize
29 #undef MachVideoSetTextCursorPosition
30 #undef MachVideoHideShowTextCursor
31 #undef MachVideoPutChar
32 #undef MachVideoCopyOffScreenBufferToVRAM
33 #undef MachVideoIsPaletteFixed
34 #undef MachVideoSetPaletteColor
35 #undef MachVideoGetPaletteColor
36 #undef MachVideoSync
37 #undef MachBeep
38 #undef MachPrepareForReactOS
39 #undef MachDiskGetBootVolume
40 #undef MachDiskGetSystemVolume
41 #undef MachDiskGetBootPath
42 #undef MachDiskGetBootDevice
43 #undef MachDiskBootingFromFloppy
44 #undef MachDiskNormalizeSystemPath
45 #undef MachDiskReadLogicalSectors
46 #undef MachDiskGetPartitionEntry
47 #undef MachDiskGetDriveGeometry
48 #undef MachDiskGetCacheableBlockCount
49 #undef MachHwDetect
50
51 MACHVTBL MachVtbl;
52
53 VOID
54 MachConsPutChar(int Ch)
55 {
56 MachVtbl.ConsPutChar(Ch);
57 }
58
59 BOOLEAN
60 MachConsKbHit()
61 {
62 return MachVtbl.ConsKbHit();
63 }
64
65 int
66 MachConsGetCh()
67 {
68 return MachVtbl.ConsGetCh();
69 }
70
71 VOID
72 MachVideoClearScreen(UCHAR Attr)
73 {
74 MachVtbl.VideoClearScreen(Attr);
75 }
76
77 VIDEODISPLAYMODE
78 MachVideoSetDisplayMode(char *DisplayMode, BOOLEAN Init)
79 {
80 return MachVtbl.VideoSetDisplayMode(DisplayMode, Init);
81 }
82
83 VOID
84 MachVideoGetDisplaySize(PULONG Width, PULONG Height, PULONG Depth)
85 {
86 return MachVtbl.VideoGetDisplaySize(Width, Height, Depth);
87 }
88
89 ULONG
90 MachVideoGetBufferSize(VOID)
91 {
92 return MachVtbl.VideoGetBufferSize();
93 }
94
95 VOID
96 MachVideoSetTextCursorPosition(ULONG X, ULONG Y)
97 {
98 return MachVtbl.VideoSetTextCursorPosition(X, Y);
99 }
100
101 VOID
102 MachVideoHideShowTextCursor(BOOLEAN Show)
103 {
104 MachVtbl.VideoHideShowTextCursor(Show);
105 }
106
107 VOID
108 MachVideoPutChar(int Ch, UCHAR Attr, unsigned X, unsigned Y)
109 {
110 MachVtbl.VideoPutChar(Ch, Attr, X, Y);
111 }
112
113 VOID
114 MachVideoCopyOffScreenBufferToVRAM(PVOID Buffer)
115 {
116 MachVtbl.VideoCopyOffScreenBufferToVRAM(Buffer);
117 }
118
119 BOOLEAN
120 MachVideoIsPaletteFixed(VOID)
121 {
122 return MachVtbl.VideoIsPaletteFixed();
123 }
124
125 VOID
126 MachVideoSetPaletteColor(UCHAR Color, UCHAR Red, UCHAR Green, UCHAR Blue)
127 {
128 return MachVtbl.VideoSetPaletteColor(Color, Red, Green, Blue);
129 }
130
131 VOID
132 MachVideoGetPaletteColor(UCHAR Color, UCHAR *Red, UCHAR *Green, UCHAR *Blue)
133 {
134 return MachVtbl.VideoGetPaletteColor(Color, Red, Green, Blue);
135 }
136
137 VOID
138 MachVideoSync(VOID)
139 {
140 MachVtbl.VideoSync();
141 }
142
143 VOID
144 MachBeep(VOID)
145 {
146 MachVtbl.Beep();
147 }
148
149 VOID
150 MachPrepareForReactOS(IN BOOLEAN Setup)
151 {
152 MachVtbl.PrepareForReactOS(Setup);
153 }
154
155 typedef struct
156 {
157 MEMORY_DESCRIPTOR m;
158 ULONG Index;
159 BOOLEAN GeneratedDescriptor;
160 } MEMORY_DESCRIPTOR_INT;
161 static const MEMORY_DESCRIPTOR_INT MemoryDescriptors[] =
162 {
163 #if defined (__i386__) || defined (_M_AMD64)
164 { { MemoryFirmwarePermanent, 0x00, 1 }, 0, }, // realmode int vectors
165 { { MemoryFirmwareTemporary, 0x01, 7 }, 1, }, // freeldr stack + cmdline
166 { { MemoryLoadedProgram, 0x08, 0x70 }, 2, }, // freeldr image (roughly max. 0x64 pages)
167 { { MemorySpecialMemory, 0x78, 8 }, 3, }, // prot mode stack. BIOSCALLBUFFER
168 { { MemoryFirmwareTemporary, 0x80, 0x10 }, 4, }, // File system read buffer. FILESYSBUFFER
169 { { MemoryFirmwareTemporary, 0x90, 0x10 }, 5, }, // Disk read buffer for int 13h. DISKREADBUFFER
170 { { MemoryFirmwarePermanent, 0xA0, 0x60 }, 6, }, // ROM / Video
171 { { MemorySpecialMemory, 0xFFF, 1 }, 7, }, // unusable memory
172 #elif __arm__
173 { { MemoryFirmwarePermanent, 0x00, 1 }, 0, }, // arm exception handlers
174 { { MemoryFirmwareTemporary, 0x01, 7 }, 1, }, // arm board block + freeldr stack + cmdline
175 { { MemoryLoadedProgram, 0x08, 0x70 }, 2, }, // freeldr image (roughly max. 0x64 pages)
176 #endif
177 };
178 MEMORY_DESCRIPTOR*
179 ArcGetMemoryDescriptor(MEMORY_DESCRIPTOR* Current)
180 {
181 MEMORY_DESCRIPTOR_INT* CurrentDescriptor;
182 BIOS_MEMORY_MAP BiosMemoryMap[32];
183 static ULONG BiosMemoryMapEntryCount;
184 static MEMORY_DESCRIPTOR_INT BiosMemoryDescriptors[32];
185 static BOOLEAN MemoryMapInitialized = FALSE;
186 ULONG i, j;
187
188 //
189 // Does machine provide an override for this function?
190 //
191 if (MachVtbl.GetMemoryDescriptor)
192 {
193 //
194 // Yes. Use it instead
195 //
196 return MachVtbl.GetMemoryDescriptor(Current);
197 }
198
199 //
200 // Check if it is the first time we're called
201 //
202 if (!MemoryMapInitialized)
203 {
204 //
205 // Get the machine generated memory map
206 //
207 RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
208 BiosMemoryMapEntryCount = MachVtbl.GetMemoryMap(BiosMemoryMap,
209 sizeof(BiosMemoryMap) / sizeof(BIOS_MEMORY_MAP));
210
211 //
212 // Copy the entries to our structure
213 //
214 for (i = 0, j = 0; i < BiosMemoryMapEntryCount; i++)
215 {
216 //
217 // Is it suitable memory?
218 //
219 if (BiosMemoryMap[i].Type != BiosMemoryUsable)
220 {
221 //
222 // No. Process next descriptor
223 //
224 continue;
225 }
226
227 //
228 // Copy this memory descriptor
229 //
230 BiosMemoryDescriptors[j].m.MemoryType = MemoryFree;
231 BiosMemoryDescriptors[j].m.BasePage = BiosMemoryMap[i].BaseAddress / MM_PAGE_SIZE;
232 BiosMemoryDescriptors[j].m.PageCount = BiosMemoryMap[i].Length / MM_PAGE_SIZE;
233 BiosMemoryDescriptors[j].Index = j;
234 BiosMemoryDescriptors[j].GeneratedDescriptor = TRUE;
235 j++;
236 }
237
238 //
239 // Remember how much descriptors we found
240 //
241 BiosMemoryMapEntryCount = j;
242
243 //
244 // Mark memory map as already retrieved and initialized
245 //
246 MemoryMapInitialized = TRUE;
247 }
248
249 CurrentDescriptor = CONTAINING_RECORD(Current, MEMORY_DESCRIPTOR_INT, m);
250
251 if (Current == NULL)
252 {
253 //
254 // First descriptor requested
255 //
256 if (BiosMemoryMapEntryCount > 0)
257 {
258 //
259 // Return first generated memory descriptor
260 //
261 return &BiosMemoryDescriptors[0].m;
262 }
263 else if (sizeof(MemoryDescriptors) > 0)
264 {
265 //
266 // Return first fixed memory descriptor
267 //
268 return (MEMORY_DESCRIPTOR*)&MemoryDescriptors[0].m;
269 }
270 else
271 {
272 //
273 // Strange case, we have no memory descriptor
274 //
275 return NULL;
276 }
277 }
278 else if (CurrentDescriptor->GeneratedDescriptor)
279 {
280 //
281 // Current entry is a generated descriptor
282 //
283 if (CurrentDescriptor->Index + 1 < BiosMemoryMapEntryCount)
284 {
285 //
286 // Return next generated descriptor
287 //
288 return &BiosMemoryDescriptors[CurrentDescriptor->Index + 1].m;
289 }
290 else if (sizeof(MemoryDescriptors) > 0)
291 {
292 //
293 // Return first fixed memory descriptor
294 //
295 return (MEMORY_DESCRIPTOR*)&MemoryDescriptors[0].m;
296 }
297 else
298 {
299 //
300 // No fixed memory descriptor; end of memory map
301 //
302 return NULL;
303 }
304 }
305 else
306 {
307 //
308 // Current entry is a fixed descriptor
309 //
310 if (CurrentDescriptor->Index + 1 < sizeof(MemoryDescriptors) / sizeof(MemoryDescriptors[0]))
311 {
312 //
313 // Return next fixed descriptor
314 //
315 return (MEMORY_DESCRIPTOR*)&MemoryDescriptors[CurrentDescriptor->Index + 1].m;
316 }
317 else
318 {
319 //
320 // No more fixed memory descriptor; end of memory map
321 //
322 return NULL;
323 }
324 }
325 }
326
327 BOOLEAN
328 MachDiskGetBootVolume(PULONG DriveNumber, PULONGLONG StartSector, PULONGLONG SectorCount, int *FsType)
329 {
330 return MachVtbl.DiskGetBootVolume(DriveNumber, StartSector, SectorCount, FsType);
331 }
332
333 BOOLEAN
334 MachDiskGetSystemVolume(char *SystemPath,
335 char *RemainingPath,
336 PULONG Device,
337 PULONG DriveNumber,
338 PULONGLONG StartSector,
339 PULONGLONG SectorCount,
340 int *FsType)
341 {
342 return MachVtbl.DiskGetSystemVolume(SystemPath, RemainingPath, Device,
343 DriveNumber, StartSector, SectorCount,
344 FsType);
345 }
346
347 BOOLEAN
348 MachDiskGetBootPath(char *BootPath, unsigned Size)
349 {
350 return MachVtbl.DiskGetBootPath(BootPath, Size);
351 }
352
353 VOID
354 MachDiskGetBootDevice(PULONG BootDevice)
355 {
356 MachVtbl.DiskGetBootDevice(BootDevice);
357 }
358
359 BOOLEAN
360 MachDiskBootingFromFloppy()
361 {
362 return MachVtbl.DiskBootingFromFloppy();
363 }
364
365 BOOLEAN
366 MachDiskNormalizeSystemPath(char *SystemPath, unsigned Size)
367 {
368 return MachVtbl.DiskNormalizeSystemPath(SystemPath, Size);
369 }
370
371 BOOLEAN
372 MachDiskReadLogicalSectors(ULONG DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer)
373 {
374 return MachVtbl.DiskReadLogicalSectors(DriveNumber, SectorNumber, SectorCount, Buffer);
375 }
376
377 BOOLEAN
378 MachDiskGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
379 {
380 return MachVtbl.DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry);
381 }
382
383 BOOLEAN
384 MachDiskGetDriveGeometry(ULONG DriveNumber, PGEOMETRY DriveGeometry)
385 {
386 return MachVtbl.DiskGetDriveGeometry(DriveNumber, DriveGeometry);
387 }
388
389 ULONG
390 MachDiskGetCacheableBlockCount(ULONG DriveNumber)
391 {
392 return MachVtbl.DiskGetCacheableBlockCount(DriveNumber);
393 }
394
395 TIMEINFO*
396 ArcGetTime(VOID)
397 {
398 return MachVtbl.GetTime();
399 }
400
401 ULONG
402 ArcGetRelativeTime(VOID)
403 {
404 TIMEINFO* TimeInfo;
405 ULONG ret;
406
407 if (MachVtbl.GetRelativeTime)
408 return MachVtbl.GetRelativeTime();
409
410 TimeInfo = ArcGetTime();
411 ret = ((TimeInfo->Hour * 24) + TimeInfo->Minute) * 60 + TimeInfo->Second;
412 return ret;
413 }
414
415 VOID
416 MachHwDetect(VOID)
417 {
418 MachVtbl.HwDetect();
419 }
420
421 /* EOF */