GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / pccons / x86mem.c
blob28d4b77d2eaecf8cbff47e93a34f729302bde0e2
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * X86 simulator sparse memory File: X86MEM.C
5 *
6 * This module implements X86 memory for the X86 emulator
7 * used by the BIOS simulator. To avoid allocating the
8 * entire 1MB of PC's addressable memory, this is a "sparse"
9 * memory model, allocating chunks of storage as needed.
10 * VGA BIOSes seem to do all sorts of bizarre things to memory
11 * so this helps reduce the total amount we need to allocate
12 * significantly.
14 * In addition, this module lets the simulator "hook"
15 * ranges of memory to be handled by a callback
16 * routine. This is used so that we can redirect
17 * accesses to VGA memory space to the PCI bus handler.
19 * Author: Mitch Lichtenberg (mpl@broadcom.com)
21 *********************************************************************
23 * Copyright 2000,2001,2002,2003
24 * Broadcom Corporation. All rights reserved.
26 * This software is furnished under license and may be used and
27 * copied only in accordance with the following terms and
28 * conditions. Subject to these conditions, you may download,
29 * copy, install, use, modify and distribute modified or unmodified
30 * copies of this software in source and/or binary form. No title
31 * or ownership is transferred hereby.
33 * 1) Any source code used, modified or distributed must reproduce
34 * and retain this copyright notice and list of conditions
35 * as they appear in the source file.
37 * 2) No right is granted to use any trade name, trademark, or
38 * logo of Broadcom Corporation. The "Broadcom Corporation"
39 * name may not be used to endorse or promote products derived
40 * from this software without the prior written permission of
41 * Broadcom Corporation.
43 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
44 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
45 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
46 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
47 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
48 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
51 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
52 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
53 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
54 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
55 * THE POSSIBILITY OF SUCH DAMAGE.
56 ********************************************************************* */
59 #include "lib_types.h"
60 #include "lib_string.h"
61 #include "lib_malloc.h"
62 #include "lib_printf.h"
63 #include "x86mem.h"
65 /* *********************************************************************
66 * Macros
67 ********************************************************************* */
69 #define BSWAP_SHORT(s) ((((s) >> 8) & 0xFF) | (((s)&0xFF) << 8))
70 #define BSWAP_LONG(s) ((((s) & 0xFF000000) >> 24) | \
71 (((s) & 0x00FF0000) >> 8) | \
72 (((s) & 0x0000FF00) << 8) | \
73 (((s) & 0x000000FF) << 24))
76 /* *********************************************************************
77 * X86MEM_INIT()
79 * Initialize an X86mem object
81 * Input parameters:
82 * mem - X86mem object
84 * Return value:
85 * nothing
86 ********************************************************************* */
88 void x86mem_init(x86mem_t *mem)
90 memset(mem,0,sizeof(mem));
93 /* *********************************************************************
94 * X86MEM_UNINIT(mem)
96 * Uninitialize an X86mem object, freeing any storage
97 * associated with it.
99 * Input parameters:
100 * mem - x86mem object
102 * Return value:
103 * nothing
104 ********************************************************************* */
106 void x86mem_uninit(x86mem_t *mem)
108 int idx;
110 for (idx = 0; idx < X86MEM_CHUNKS; idx++) {
111 if (mem->data[idx]) {
112 KFREE(mem->data[idx]);
113 mem->data[idx] = NULL;
118 /* *********************************************************************
119 * X86MEM_READB(mem,addr)
121 * Read a byte of memory from the X86mem object.
123 * Input parameters:
124 * mem - x86mem object
125 * addr - address of byte to read
127 * Return value:
128 * byte read
129 ********************************************************************* */
131 uint8_t x86mem_readb(x86mem_t *mem,uint32_t addr)
133 uint8_t *p;
135 if (mem->read[X86MEM_REGION(addr)]) {
136 return (uint8_t) (*(mem->read[X86MEM_REGION(addr)]))(mem,addr,1);
139 p = (mem->data[X86MEM_REGION(addr)]);
141 if (p) {
142 return *(p + X86MEM_OFFSET(addr));
144 else {
145 return 0;
149 /* *********************************************************************
150 * X86MEM_READW(mem,addr)
152 * Read a 16-bit word of memory from the X86mem object.
154 * Input parameters:
155 * mem - x86mem object
156 * addr - address of word to read
158 * Return value:
159 * word read
160 ********************************************************************* */
162 uint16_t x86mem_readw(x86mem_t *mem,uint32_t addr)
164 uint8_t *p;
165 uint16_t ret;
167 if (mem->read[X86MEM_REGION(addr)]) {
168 return (uint8_t) (*(mem->read[X86MEM_REGION(addr)]))(mem,addr,2);
171 p = (mem->data[X86MEM_REGION(addr)]);
172 if (!p) return 0;
174 if ((addr & 1) || (X86MEM_OFFSET(addr) == X86MEM_CHUNKSIZE-1)) {
176 ret = ((uint16_t) x86mem_readb(mem,addr+0)) |
177 (((uint16_t) x86mem_readb(mem,addr+1)) << 8);
178 return ret;
180 else {
181 ret = *((uint16_t *) (p+X86MEM_OFFSET(addr)));
182 #ifdef __MIPSEB
183 ret = BSWAP_SHORT(ret);
184 #endif
187 return ret;
190 /* *********************************************************************
191 * X86MEM_READL(mem,addr)
193 * Read a 32-bit dword of memory from the X86mem object.
195 * Input parameters:
196 * mem - x86mem object
197 * addr - address of dword to read
199 * Return value:
200 * dword read
201 ********************************************************************* */
203 uint32_t x86mem_readl(x86mem_t *mem,uint32_t addr)
205 uint8_t *p;
206 uint32_t ret;
208 if (mem->read[X86MEM_REGION(addr)]) {
209 return (uint8_t) (*(mem->read[X86MEM_REGION(addr)]))(mem,addr,4);
212 p = (mem->data[X86MEM_REGION(addr)]);
213 if (!p) return 0;
215 if ((addr & 3) || (X86MEM_OFFSET(addr) >= X86MEM_CHUNKSIZE-3)) {
216 ret = ((uint32_t) x86mem_readb(mem,addr+0)) |
217 (((uint32_t) x86mem_readb(mem,addr+1)) << 8) |
218 (((uint32_t) x86mem_readb(mem,addr+2)) << 16) |
219 (((uint32_t) x86mem_readb(mem,addr+3)) << 24);
221 else {
222 ret = *((uint32_t *) (p+X86MEM_OFFSET(addr)));
223 #ifdef __MIPSEB
224 ret = BSWAP_LONG(ret);
225 #endif
228 return ret;
231 /* *********************************************************************
232 * X86MEM_WRITEB(mem,addr,data)
234 * Write a byte to the X86mem object
236 * Input parameters:
237 * mem - x86mem object
238 * addr - address of byte to write
239 * data - data to write
241 * Return value:
242 * nothing
243 ********************************************************************* */
244 void x86mem_writeb(x86mem_t *mem,uint32_t addr,uint8_t data)
246 uint8_t *p;
248 if (mem->write[X86MEM_REGION(addr)]) {
249 (*(mem->write[X86MEM_REGION(addr)]))(mem,addr,data,1);
250 return;
253 p = (mem->data[X86MEM_REGION(addr)]);
255 if (p) {
256 *(p + X86MEM_OFFSET(addr)) = data;
258 else {
259 p = mem->data[X86MEM_REGION(addr)] = KMALLOC(X86MEM_CHUNKSIZE,sizeof(uint32_t));
260 if (p) {
261 memset(p,0,X86MEM_CHUNKSIZE);
262 *(p + X86MEM_OFFSET(addr)) = data;
267 /* *********************************************************************
268 * X86MEM_WRITEW(mem,addr,data)
270 * Write a 16-bit word to the X86mem object
272 * Input parameters:
273 * mem - x86mem object
274 * addr - address of word to write
275 * data - data to write
277 * Return value:
278 * nothing
279 ********************************************************************* */
280 void x86mem_writew(x86mem_t *mem,uint32_t addr,uint16_t data)
282 uint8_t *p;
284 if (mem->write[X86MEM_REGION(addr)]) {
285 (*(mem->write[X86MEM_REGION(addr)]))(mem,addr,data,2);
286 return;
289 p = (mem->data[X86MEM_REGION(addr)]);
291 if (!p || (addr & 1) || (X86MEM_OFFSET(addr) == X86MEM_CHUNKSIZE-1)) {
292 x86mem_writeb(mem,addr+0,(data & 0xFF));
293 x86mem_writeb(mem,addr+1,((data >> 8) & 0xFF));
295 else {
296 #ifdef __MIPSEB
297 data = BSWAP_SHORT(data);
298 #endif
299 *((uint16_t *) (p+X86MEM_OFFSET(addr))) = data;
303 /* *********************************************************************
304 * X86MEM_WRITEL(mem,addr,data)
306 * Write a 32-bit dword to the X86mem object
308 * Input parameters:
309 * mem - x86mem object
310 * addr - address of dword to write
311 * data - data to write
313 * Return value:
314 * nothing
315 ********************************************************************* */
316 void x86mem_writel(x86mem_t *mem,uint32_t addr,uint32_t data)
318 uint8_t *p;
320 if (mem->write[X86MEM_REGION(addr)]) {
321 (*(mem->write[X86MEM_REGION(addr)]))(mem,addr,data,4);
322 return;
325 p = (mem->data[X86MEM_REGION(addr)]);
327 if (!p || (addr & 3) || (X86MEM_OFFSET(addr) >= X86MEM_CHUNKSIZE-3)) {
328 x86mem_writeb(mem,addr+0,(data & 0xFF));
329 x86mem_writeb(mem,addr+1,((data >> 8) & 0xFF));
330 x86mem_writeb(mem,addr+2,((data >> 16) & 0xFF));
331 x86mem_writeb(mem,addr+3,((data >> 24) & 0xFF));
333 else {
334 #ifdef __MIPSEB
335 data = BSWAP_LONG(data);
336 #endif
337 *((uint32_t *) (p+X86MEM_OFFSET(addr))) = data;
341 /* *********************************************************************
342 * X86MEM_MEMCPY(mem,dest,src,cnt)
344 * memcpy data into the X86mem object
346 * Input parameters:
347 * mem - x86mem object
348 * destaddr - destination x86mem address
349 * src - source local address
350 * cnt - number of bytes to copy
352 * Return value:
353 * nothing
354 ********************************************************************* */
356 void x86mem_memcpy(x86mem_t *mem,uint32_t destaddr,uint8_t *src,int count)
358 while (count) {
359 x86mem_writeb(mem,destaddr,*src);
360 destaddr++;
361 src++;
362 count--;
367 /* *********************************************************************
368 * X86MEM_HOOK(mem,addr,readf,writef)
370 * Establish a hook for a block of simulated memory
372 * Input parameters:
373 * mem - x86mem object
374 * addr - address in memory, should be aligned on a "chunk"
375 * boundary.
376 * readf - function to call on READ accesses
377 * writef - function to call on WRITE accesses
379 * Return value:
380 * nothing
381 ********************************************************************* */
383 void x86mem_hook(x86mem_t *mem,uint32_t chunkaddr,
384 uint32_t (*readf)(x86mem_t *mem,uint32_t addr,int size),
385 void (*writef)(x86mem_t *mem,uint32_t addr,uint32_t val,int size))
387 if (mem->data[X86MEM_REGION(chunkaddr)]) {
388 KFREE(mem->data[X86MEM_REGION(chunkaddr)]);
389 mem->data[X86MEM_REGION(chunkaddr)] = NULL;
391 mem->read[X86MEM_REGION(chunkaddr)] = readf;
392 mem->write[X86MEM_REGION(chunkaddr)] = writef;
395 /* *********************************************************************
396 * X86MEM_HOOK_RANGE(mem,addr,size,readf,writef)
398 * Establish a hook for a block of simulated memory
400 * Input parameters:
401 * mem - x86mem object
402 * addr - address in memory, should be aligned on a "chunk"
403 * boundary.
404 * size - size of region to hook. Should be a multiple
405 * of the chunk size
406 * readf - function to call on READ accesses
407 * writef - function to call on WRITE accesses
409 * Return value:
410 * nothing
411 ********************************************************************* */
413 void x86mem_hook_range(x86mem_t *mem,uint32_t chunkaddr,int size,
414 uint32_t (*readf)(x86mem_t *mem,uint32_t addr,int size),
415 void (*writef)(x86mem_t *mem,uint32_t addr,uint32_t val,int size))
417 while (size > 0) {
418 x86mem_hook(mem,chunkaddr,readf,writef);
419 size -= X86MEM_CHUNKSIZE;
420 chunkaddr += X86MEM_CHUNKSIZE;