ReactOS  0.4.13-dev-982-g9853eab
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 
31 static HANDLE
32 OpenRomFile(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)", 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 
62 static 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)", 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 
86 static VOID
88  IN ULONG Start,
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 
137 BOOLEAN
139  IN ULONG RomSize)
140 {
141  return MemInstallFastMemoryHook(RomLocation, RomSize,
143 }
144 
145 BOOLEAN
147  IN ULONG RomSize)
148 {
149  return MemRemoveFastMemoryHook(RomLocation, RomSize);
150 }
151 
152 UCHAR
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 
168 BOOLEAN
169 LoadBios(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 
213 BOOLEAN
214 LoadRom(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 
251 VOID
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 */
#define IN
Definition: typedefs.h:38
BOOLEAN WriteProtectRom(IN PVOID RomLocation, IN ULONG RomSize)
Definition: rom.c:138
UCHAR CalcRomChecksum(IN ULONG RomLocation, IN ULONG RomSize)
Definition: rom.c:153
unsigned char * PUCHAR
Definition: retypes.h:3
VOID WINAPI setDS(USHORT)
Definition: registers.c:515
BOOL MemRemoveFastMemoryHook(PVOID Address, ULONG Size)
Definition: memory.c:350
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
VOID FileClose(IN HANDLE FileHandle)
Definition: utils.c:21
#define FASTCALL
Definition: nt_native.h:50
BOOLEAN LoadBios(IN PCSTR BiosFileName, OUT PVOID *BiosLocation OPTIONAL, OUT PULONG BiosSize OPTIONAL)
Definition: rom.c:169
BOOLEAN LoadRom(IN PCSTR RomFileName, IN PVOID RomLocation, OUT PULONG RomSize OPTIONAL)
Definition: rom.c:214
#define REAL_TO_PHYS(ptr)
Definition: emulator.h:33
#define MAKELONG(a, b)
Definition: typedefs.h:248
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
Definition: bufpool.h:45
static BOOLEAN FASTCALL ShadowRomWrite(ULONG Address, PVOID Buffer, ULONG Size)
Definition: rom.c:25
static HANDLE OpenRomFile(IN PCSTR RomFileName, OUT PULONG RomSize OPTIONAL)
Definition: rom.c:32
static VOID InitRomRange(IN PCALLBACK16 Context, IN ULONG Start, IN ULONG End, IN ULONG Increment)
Definition: rom.c:87
BOOLEAN WriteUnProtectRom(IN PVOID RomLocation, IN ULONG RomSize)
Definition: rom.c:146
BOOL MemInstallFastMemoryHook(PVOID Address, ULONG Size, PMEMORY_READ_HANDLER ReadHandler, PMEMORY_WRITE_HANDLER WriteHandler)
Definition: memory.c:296
Definition: partlist.h:33
#define TO_LINEAR(seg, off)
Definition: emulator.h:22
unsigned char UCHAR
Definition: xmlstorage.h:181
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
HANDLE FileOpen(IN PCSTR FileName, OUT PULONG FileSize OPTIONAL)
Definition: utils.c:27
static BOOLEAN LoadRomFileByHandle(IN HANDLE RomFileHandle, IN PVOID RomLocation, IN ULONG RomSize, OUT PULONG BytesRead)
Definition: rom.c:63
unsigned int * PULONG
Definition: retypes.h:1
#define MEM_ALIGN_DOWN(ptr, align)
Definition: emulator.h:19
#define DPRINT1
Definition: precomp.h:8
VOID RunCallback16(IN PCALLBACK16 Context, IN ULONG FarPtr)
Definition: callback.c:93
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN FileLoadByHandle(IN HANDLE FileHandle, IN PVOID Location, IN ULONG FileSize, OUT PULONG BytesRead)
Definition: utils.c:69
const char * PCSTR
Definition: typedefs.h:51
#define OPTION_ROM_SIGNATURE
Definition: rom.h:17
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG Increment
Definition: CrNtStubs.h:42
unsigned short * PUSHORT
Definition: retypes.h:2
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
VOID SearchAndInitRoms(IN PCALLBACK16 Context)
Definition: rom.c:252
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68