ReactOS 0.4.15-dev-8408-g466a198
rom.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: subsystems/mvdm/ntvdm/bios/rom.c
5 * PURPOSE: ROM Support Functions
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include "ntvdm.h"
12
13#define NDEBUG
14#include <debug.h>
15
16#include "emulator.h"
17#include "memory.h"
18#include "cpu/callback.h"
19#include "rom.h"
20
21#include "utils.h"
22
23/* PRIVATE FUNCTIONS **********************************************************/
24
26{
27 /* Prevent writing to ROM */
28 return FALSE;
29}
30
31static HANDLE
32OpenRomFile(IN PCSTR RomFileName,
33 OUT PULONG RomSize OPTIONAL)
34{
35 HANDLE hRomFile;
36 ULONG ulRomSize = 0;
37
38 /* Open the ROM image file */
39 hRomFile = FileOpen(RomFileName, &ulRomSize);
40
41 /* If we failed, bail out */
42 if (hRomFile == NULL) return NULL;
43
44 /*
45 * The size of the ROM image file is at most 256kB. For instance,
46 * the SeaBIOS image, which includes also expansion ROMs inside it,
47 * covers the range C000:0000 to F000:FFFF .
48 */
49 if (ulRomSize > 0x40000)
50 {
51 /* We failed, bail out */
52 DPRINT1("ROM image size 0x%lx too large, expected at most 0x40000 (256kB)\n", ulRomSize);
53 FileClose(hRomFile);
54 return NULL;
55 }
56
57 /* Success, return file handle and size if needed */
58 if (RomSize) *RomSize = ulRomSize;
59 return hRomFile;
60}
61
62static BOOLEAN
64 IN PVOID RomLocation,
65 IN ULONG RomSize,
67{
68 /*
69 * The size of the ROM image file is at most 256kB. For instance,
70 * the SeaBIOS image, which includes also expansion ROMs inside it,
71 * covers the range C000:0000 to F000:FFFF .
72 */
73 if (RomSize > 0x40000)
74 {
75 DPRINT1("ROM image size 0x%lx too large, expected at most 0x40000 (256kB)\n", RomSize);
76 return FALSE;
77 }
78
79 /* Attempt to load the ROM image file into memory */
80 return FileLoadByHandle(RomFileHandle,
81 REAL_TO_PHYS(RomLocation),
82 RomSize,
83 BytesRead);
84}
85
86static VOID
89 IN ULONG End,
91{
92 ULONG Address, EntryPoint;
93 ULONG RomSize;
94 UCHAR Checksum;
95
96 for (Address = Start; Address < End; Address += Increment)
97 {
98 /* Does the ROM have a valid signature? */
100 {
101 /* Check the control sum of the ROM */
102
103 /*
104 * If this is an adapter ROM (Start: C8000, End: E0000),
105 * its reported size is stored in byte 2 of the ROM.
106 *
107 * If this is an expansion ROM (Start: E0000, End: F0000),
108 * its real length is 64kB.
109 */
110 RomSize = *(PUCHAR)REAL_TO_PHYS(Address + 2) * 512; // Size in blocks of 512 bytes
111 if (Address >= 0xE0000) RomSize = 0x10000;
112
113 Checksum = CalcRomChecksum(Address, RomSize);
114 if (Checksum == 0x00)
115 {
116 EntryPoint = Address + 3;
117 DPRINT1("Going to run @ address 0x%p\n", EntryPoint);
118
119 EntryPoint = MAKELONG((EntryPoint & 0xFFFF), (EntryPoint & 0xF0000) >> 4);
120 // setDS((Address & 0xF0000) >> 4);
121 setDS((Address & 0xFF000) >> 4);
122 RunCallback16(Context, EntryPoint);
123 // Call16((EntryPoint & 0xF0000) >> 4, (EntryPoint & 0xFFFF));
124
125 DPRINT1("ROM @ address 0x%p initialized\n", Address);
126 }
127 else
128 {
129 DPRINT1("ROM @ address 0x%p has invalid checksum of 0x%02x\n", Address, Checksum);
130 }
131 }
132 }
133}
134
135/* PUBLIC FUNCTIONS ***********************************************************/
136
139 IN ULONG RomSize)
140{
141 return MemInstallFastMemoryHook(RomLocation, RomSize,
143}
144
147 IN ULONG RomSize)
148{
149 return MemRemoveFastMemoryHook(RomLocation, RomSize);
150}
151
152UCHAR
154 IN ULONG RomSize)
155{
156 ULONG RomLastAddress = RomLocation + RomSize;
157 UCHAR Sum = 0x00; // Using a UCHAR guarantees that we wrap at 0xFF i.e. we do a sum modulo 0x100.
158
159 while (RomLocation < RomLastAddress)
160 {
161 Sum += *(PUCHAR)REAL_TO_PHYS(RomLocation);
162 ++RomLocation;
163 }
164
165 return Sum;
166}
167
169LoadBios(IN PCSTR BiosFileName,
170 OUT PVOID* BiosLocation OPTIONAL,
171 OUT PULONG BiosSize OPTIONAL)
172{
174 HANDLE hBiosFile;
175 ULONG ulBiosSize = 0;
176 PVOID pBiosLocation;
177
178 /* Open the BIOS image file */
179 hBiosFile = OpenRomFile(BiosFileName, &ulBiosSize);
180
181 /* If we failed, bail out */
182 if (hBiosFile == NULL) return FALSE;
183
184 /* BIOS location needs to be aligned on 32-bit boundary */
185 // (PVOID)((ULONG_PTR)BaseAddress + ROM_AREA_END + 1 - ulBiosSize)
186 pBiosLocation = MEM_ALIGN_DOWN(TO_LINEAR(0xF000, 0xFFFF) + 1 - ulBiosSize, sizeof(ULONG));
187
188 /* Attempt to load the BIOS image file into memory */
189 Success = LoadRomFileByHandle(hBiosFile,
190 pBiosLocation,
191 ulBiosSize,
192 &ulBiosSize);
193 DPRINT1("BIOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
194
195 /* Close the BIOS image file */
196 FileClose(hBiosFile);
197
198 /*
199 * In case of success, write-protect the BIOS location
200 * and return the BIOS location and its size if needed.
201 */
202 if (Success)
203 {
204 WriteProtectRom(pBiosLocation, ulBiosSize);
205
206 if (BiosLocation) *BiosLocation = pBiosLocation;
207 if (BiosSize) *BiosSize = ulBiosSize;
208 }
209
210 return Success;
211}
212
214LoadRom(IN PCSTR RomFileName,
215 IN PVOID RomLocation,
216 OUT PULONG RomSize OPTIONAL)
217{
219 HANDLE hRomFile;
220 ULONG ulRomSize = 0;
221
222 /* Open the ROM image file */
223 hRomFile = OpenRomFile(RomFileName, &ulRomSize);
224
225 /* If we failed, bail out */
226 if (hRomFile == NULL) return FALSE;
227
228 /* Attempt to load the ROM image file into memory */
229 Success = LoadRomFileByHandle(hRomFile,
230 RomLocation,
231 ulRomSize,
232 &ulRomSize);
233 DPRINT1("ROM loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
234
235 /* Close the ROM image file and return */
236 FileClose(hRomFile);
237
238 /*
239 * In case of success, write-protect the ROM location
240 * and return the ROM size if needed.
241 */
242 if (Success)
243 {
244 WriteProtectRom(RomLocation, ulRomSize);
245 if (RomSize) *RomSize = ulRomSize;
246 }
247
248 return Success;
249}
250
251VOID
253{
254 /* Video ROMs -- Start: C0000, End: C8000, 2kB blocks */
255 InitRomRange(Context, 0xC0000, 0xC8000, 0x0800);
256
257 /* Adapters ROMs -- Start: C8000, End: E0000, 2kB blocks */
258 InitRomRange(Context, 0xC8000, 0xE0000, 0x0800);
259
260 /* Expansion ROM -- Start: E0000, End: F0000, 64kB block */
261 InitRomRange(Context, 0xE0000, 0xEFFFF, 0x10000);
262}
263
264/* EOF */
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define TO_LINEAR(seg, off)
Definition: emulator.h:26
#define REAL_TO_PHYS(ptr)
Definition: emulator.h:37
#define MEM_ALIGN_DOWN(ptr, align)
Definition: emulator.h:23
@ Success
Definition: eventcreate.c:712
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:46
return pTarget Start()
#define FASTCALL
Definition: nt_native.h:50
static WCHAR Address[46]
Definition: ping.c:68
UCHAR CalcRomChecksum(IN ULONG RomLocation, IN ULONG RomSize)
Definition: rom.c:153
BOOLEAN LoadBios(IN PCSTR BiosFileName, OUT PVOID *BiosLocation OPTIONAL, OUT PULONG BiosSize OPTIONAL)
Definition: rom.c:169
VOID SearchAndInitRoms(IN PCALLBACK16 Context)
Definition: rom.c:252
static BOOLEAN FASTCALL ShadowRomWrite(ULONG Address, PVOID Buffer, ULONG Size)
Definition: rom.c:25
static VOID InitRomRange(IN PCALLBACK16 Context, IN ULONG Start, IN ULONG End, IN ULONG Increment)
Definition: rom.c:87
BOOLEAN LoadRom(IN PCSTR RomFileName, IN PVOID RomLocation, OUT PULONG RomSize OPTIONAL)
Definition: rom.c:214
BOOLEAN WriteUnProtectRom(IN PVOID RomLocation, IN ULONG RomSize)
Definition: rom.c:146
static HANDLE OpenRomFile(IN PCSTR RomFileName, OUT PULONG RomSize OPTIONAL)
Definition: rom.c:32
BOOLEAN WriteProtectRom(IN PVOID RomLocation, IN ULONG RomSize)
Definition: rom.c:138
static BOOLEAN LoadRomFileByHandle(IN HANDLE RomFileHandle, IN PVOID RomLocation, IN ULONG RomSize, OUT PULONG BytesRead)
Definition: rom.c:63
#define OPTION_ROM_SIGNATURE
Definition: rom.h:17
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
VOID RunCallback16(IN PCALLBACK16 Context, IN ULONG FarPtr)
Definition: callback.c:93
BOOL MemRemoveFastMemoryHook(PVOID Address, ULONG Size)
Definition: memory.c:353
BOOL MemInstallFastMemoryHook(PVOID Address, ULONG Size, PMEMORY_READ_HANDLER ReadHandler, PMEMORY_WRITE_HANDLER WriteHandler)
Definition: memory.c:299
HANDLE FileOpen(IN PCSTR FileName, OUT PULONG FileSize OPTIONAL)
Definition: utils.c:27
VOID FileClose(IN HANDLE FileHandle)
Definition: utils.c:21
BOOLEAN FileLoadByHandle(IN HANDLE FileHandle, IN PVOID Location, IN ULONG FileSize, OUT PULONG BytesRead)
Definition: utils.c:69
uint32_t * PULONG
Definition: typedefs.h:59
uint16_t * PUSHORT
Definition: typedefs.h:56
const char * PCSTR
Definition: typedefs.h:52
#define IN
Definition: typedefs.h:39
#define MAKELONG(a, b)
Definition: typedefs.h:249
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
VOID WINAPI setDS(USHORT)
Definition: registers.c:515
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
unsigned char UCHAR
Definition: xmlstorage.h:181