blob: fa6959e0e41f17db976730c73790c1ec4e2dd1fb [file] [log] [blame]
Stefan Reinauer38cd29e2009-08-11 21:28:25 +00001/******************************************************************************
2 * Copyright (c) 2004, 2008 IBM Corporation
3 * Copyright (c) 2009 Pattrick Hueper <phueper@hueper.net>
Martin Rotha9e1a222016-01-14 14:15:24 -07004 *
Stefan Reinauer38cd29e2009-08-11 21:28:25 +00005 * All rights reserved.
Martin Rotha9e1a222016-01-14 14:15:24 -07006 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer
16 * in the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Stefan Reinauer38cd29e2009-08-11 21:28:25 +000030 *
31 * Contributors:
32 * IBM Corporation - initial implementation
33 *****************************************************************************/
34
35#include <types.h>
Stefan Reinauer38cd29e2009-08-11 21:28:25 +000036#include "debug.h"
37#include "device.h"
38#include "x86emu/x86emu.h"
39#include "biosemu.h"
Uwe Hermann01ce6012010-03-05 10:03:50 +000040#include "mem.h"
Stefan Reinauer38cd29e2009-08-11 21:28:25 +000041#include "compat/time.h"
Edward O'Callaghana173a622014-06-17 17:05:36 +100042#include <device/resource.h>
Stefan Reinauer38cd29e2009-08-11 21:28:25 +000043
Julius Wernercd49cce2019-03-05 16:53:33 -080044#if !CONFIG(YABEL_DIRECTHW) || !CONFIG(YABEL_DIRECTHW)
Myles Watson8f8a51c2010-09-09 16:00:20 +000045
Stefan Reinauer38cd29e2009-08-11 21:28:25 +000046// define a check for access to certain (virtual) memory regions (interrupt handlers, BIOS Data Area, ...)
Julius Wernercd49cce2019-03-05 16:53:33 -080047#if CONFIG(X86EMU_DEBUG)
Stefan Reinauer38cd29e2009-08-11 21:28:25 +000048static u8 in_check = 0; // to avoid recursion...
Stefan Reinauer38cd29e2009-08-11 21:28:25 +000049
Myles Watson8f8a51c2010-09-09 16:00:20 +000050static inline void DEBUG_CHECK_VMEM_READ(u32 _addr, u32 _rval)
51{
52 u16 ebda_segment;
53 u32 ebda_size;
54 if (!((debug_flags & DEBUG_CHECK_VMEM_ACCESS) && (in_check == 0)))
55 return;
56 in_check = 1;
57 /* determine ebda_segment and size
58 * since we are using my_rdx calls, make sure, this is after setting in_check! */
59 /* offset 03 in BDA is EBDA segment */
60 ebda_segment = my_rdw(0x40e);
61 /* first value in ebda is size in KB */
62 ebda_size = my_rdb(ebda_segment << 4) * 1024;
63 /* check Interrupt Vector Access (0000:0000h - 0000:0400h) */
64 if (_addr < 0x400) {
65 DEBUG_PRINTF_CS_IP("%s: read from Interrupt Vector %x --> %x\n",
66 __func__, _addr / 4, _rval);
67 }
68 /* access to BIOS Data Area (0000:0400h - 0000:0500h)*/
69 else if ((_addr >= 0x400) && (_addr < 0x500)) {
70 DEBUG_PRINTF_CS_IP("%s: read from BIOS Data Area: addr: %x --> %x\n",
71 __func__, _addr, _rval);
72 /* dump registers */
73 /* x86emu_dump_xregs(); */
74 }
75 /* access to first 64k of memory... */
76 else if (_addr < 0x10000) {
77 DEBUG_PRINTF_CS_IP("%s: read from segment 0000h: addr: %x --> %x\n",
78 __func__, _addr, _rval);
79 /* dump registers */
80 /* x86emu_dump_xregs(); */
81 }
82 /* read from PMM_CONV_SEGMENT */
83 else if ((_addr <= ((PMM_CONV_SEGMENT << 4) | 0xffff)) && (_addr >= (PMM_CONV_SEGMENT << 4))) {
84 DEBUG_PRINTF_CS_IP("%s: read from PMM Segment %04xh: addr: %x --> %x\n",
85 __func__, PMM_CONV_SEGMENT, _addr, _rval);
86 /* HALT_SYS(); */
87 /* dump registers */
88 /* x86emu_dump_xregs(); */
89 }
90 /* read from PNP_DATA_SEGMENT */
91 else if ((_addr <= ((PNP_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (PNP_DATA_SEGMENT << 4))) {
92 DEBUG_PRINTF_CS_IP("%s: read from PnP Data Segment %04xh: addr: %x --> %x\n",
93 __func__, PNP_DATA_SEGMENT, _addr, _rval);
94 /* HALT_SYS(); */
95 /* dump registers */
96 /* x86emu_dump_xregs(); */
97 }
98 /* read from EBDA Segment */
99 else if ((_addr <= ((ebda_segment << 4) | (ebda_size - 1))) && (_addr >= (ebda_segment << 4))) {
100 DEBUG_PRINTF_CS_IP("%s: read from Extended BIOS Data Area %04xh, size: %04x: addr: %x --> %x\n",
101 __func__, ebda_segment, ebda_size, _addr, _rval);
102 }
103 /* read from BIOS_DATA_SEGMENT */
104 else if ((_addr <= ((BIOS_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (BIOS_DATA_SEGMENT << 4))) {
105 DEBUG_PRINTF_CS_IP("%s: read from BIOS Data Segment %04xh: addr: %x --> %x\n",
106 __func__, BIOS_DATA_SEGMENT, _addr, _rval);
107 /* for PMM debugging */
108 /*if (_addr == BIOS_DATA_SEGMENT << 4) {
109 X86EMU_trace_on();
110 M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
111 }*/
112 /* dump registers */
113 /* x86emu_dump_xregs(); */
114 }
115 in_check = 0;
116}
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000117
Myles Watson8f8a51c2010-09-09 16:00:20 +0000118static inline void DEBUG_CHECK_VMEM_WRITE(u32 _addr, u32 _val)
119{
120 u16 ebda_segment;
121 u32 ebda_size;
122 if (!((debug_flags & DEBUG_CHECK_VMEM_ACCESS) && (in_check == 0)))
123 return;
124 in_check = 1;
125 /* determine ebda_segment and size
126 * since we are using my_rdx calls, make sure that this is after
127 * setting in_check! */
128 /* offset 03 in BDA is EBDA segment */
129 ebda_segment = my_rdw(0x40e);
130 /* first value in ebda is size in KB */
131 ebda_size = my_rdb(ebda_segment << 4) * 1024;
132 /* check Interrupt Vector Access (0000:0000h - 0000:0400h) */
133 if (_addr < 0x400) {
134 DEBUG_PRINTF_CS_IP("%s: write to Interrupt Vector %x <-- %x\n",
135 __func__, _addr / 4, _val);
136 }
137 /* access to BIOS Data Area (0000:0400h - 0000:0500h)*/
138 else if ((_addr >= 0x400) && (_addr < 0x500)) {
139 DEBUG_PRINTF_CS_IP("%s: write to BIOS Data Area: addr: %x <-- %x\n",
140 __func__, _addr, _val);
141 /* dump registers */
142 /* x86emu_dump_xregs(); */
143 }
144 /* access to first 64k of memory...*/
145 else if (_addr < 0x10000) {
146 DEBUG_PRINTF_CS_IP("%s: write to segment 0000h: addr: %x <-- %x\n",
147 __func__, _addr, _val);
148 /* dump registers */
149 /* x86emu_dump_xregs(); */
150 }
151 /* write to PMM_CONV_SEGMENT... */
152 else if ((_addr <= ((PMM_CONV_SEGMENT << 4) | 0xffff)) && (_addr >= (PMM_CONV_SEGMENT << 4))) {
153 DEBUG_PRINTF_CS_IP("%s: write to PMM Segment %04xh: addr: %x <-- %x\n",
154 __func__, PMM_CONV_SEGMENT, _addr, _val);
155 /* dump registers */
156 /* x86emu_dump_xregs(); */
157 }
158 /* write to PNP_DATA_SEGMENT... */
159 else if ((_addr <= ((PNP_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (PNP_DATA_SEGMENT << 4))) {
160 DEBUG_PRINTF_CS_IP("%s: write to PnP Data Segment %04xh: addr: %x <-- %x\n",
161 __func__, PNP_DATA_SEGMENT, _addr, _val);
162 /* dump registers */
163 /* x86emu_dump_xregs(); */
164 }
165 /* write to EBDA Segment... */
166 else if ((_addr <= ((ebda_segment << 4) | (ebda_size - 1))) && (_addr >= (ebda_segment << 4))) {
167 DEBUG_PRINTF_CS_IP("%s: write to Extended BIOS Data Area %04xh, size: %04x: addr: %x <-- %x\n",
168 __func__, ebda_segment, ebda_size, _addr, _val);
169 }
170 /* write to BIOS_DATA_SEGMENT... */
171 else if ((_addr <= ((BIOS_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (BIOS_DATA_SEGMENT << 4))) {
172 DEBUG_PRINTF_CS_IP("%s: write to BIOS Data Segment %04xh: addr: %x <-- %x\n",
173 __func__, BIOS_DATA_SEGMENT, _addr, _val);
174 /* dump registers */
175 /* x86emu_dump_xregs(); */
176 }
177 /* write to current CS segment... */
178 else if ((_addr < ((M.x86.R_CS << 4) | 0xffff)) && (_addr > (M.x86.R_CS << 4))) {
179 DEBUG_PRINTF_CS_IP("%s: write to CS segment %04xh: addr: %x <-- %x\n",
180 __func__, M.x86.R_CS, _addr, _val);
181 /* dump registers */
182 /* x86emu_dump_xregs(); */
183 }
184 in_check = 0;
185}
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000186#else
Myles Watson8f8a51c2010-09-09 16:00:20 +0000187static inline void DEBUG_CHECK_VMEM_READ(u32 _addr, u32 _rval) {};
188static inline void DEBUG_CHECK_VMEM_WRITE(u32 _addr, u32 _val) {};
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000189#endif
190
Myles Watson8f8a51c2010-09-09 16:00:20 +0000191//update time in BIOS Data Area
192//DWord at offset 0x6c is the timer ticks since midnight, timer is running at 18Hz
193//byte at 0x70 is timer overflow (set if midnight passed since last call to interrupt 1a function 00
194//cur_val is the current value, of offset 6c...
195static void
196update_time(u32 cur_val)
197{
Martin Roth63373ed2013-07-08 16:24:19 -0600198 //for convenience, we let the start of timebase be at midnight, we currently don't support
Myles Watson8f8a51c2010-09-09 16:00:20 +0000199 //real daytime anyway...
200 u64 ticks_per_day = tb_freq * 60 * 24;
201 // at 18Hz a period is ~55ms, converted to ticks (tb_freq is ticks/second)
202 u32 period_ticks = (55 * tb_freq) / 1000;
203 u64 curr_time = get_time();
204 u64 ticks_since_midnight = curr_time % ticks_per_day;
205 u32 periods_since_midnight = ticks_since_midnight / period_ticks;
206 // if periods since midnight is smaller than last value, set overflow
207 // at BDA Offset 0x70
208 if (periods_since_midnight < cur_val) {
209 my_wrb(0x470, 1);
210 }
211 // store periods since midnight at BDA offset 0x6c
212 my_wrl(0x46c, periods_since_midnight);
213}
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000214
215// read byte from memory
216u8
217my_rdb(u32 addr)
218{
219 unsigned long translated_addr = addr;
Patrick Georgi91443042011-01-13 11:38:46 +0000220 u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000221 u8 rval;
222 if (translated != 0) {
Martin Roth63373ed2013-07-08 16:24:19 -0600223 //translation successful, access VGA Memory (BAR or Legacy...)
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000224 DEBUG_PRINTF_MEM("%s(%08x): access to VGA Memory\n",
225 __func__, addr);
226 //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __func__, addr, translated_addr);
227 set_ci();
228 rval = *((u8 *) translated_addr);
229 clr_ci();
230 DEBUG_PRINTF_MEM("%s(%08x) VGA --> %02x\n", __func__, addr,
231 rval);
232 return rval;
233 } else if (addr > M.mem_size) {
234 DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n",
235 __func__, addr);
236 //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1);
237 HALT_SYS();
238 } else {
239 /* read from virtual memory */
240 rval = *((u8 *) (M.mem_base + addr));
241 DEBUG_CHECK_VMEM_READ(addr, rval);
242 return rval;
243 }
244 return -1;
245}
246
247//read word from memory
248u16
249my_rdw(u32 addr)
250{
251 unsigned long translated_addr = addr;
Patrick Georgi91443042011-01-13 11:38:46 +0000252 u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000253 u16 rval;
254 if (translated != 0) {
Martin Roth63373ed2013-07-08 16:24:19 -0600255 //translation successful, access VGA Memory (BAR or Legacy...)
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000256 DEBUG_PRINTF_MEM("%s(%08x): access to VGA Memory\n",
257 __func__, addr);
258 //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __func__, addr, translated_addr);
259 // check for legacy memory, because of the remapping to BARs, the reads must
260 // be byte reads...
261 if ((addr >= 0xa0000) && (addr < 0xc0000)) {
262 //read bytes a using my_rdb, because of the remapping to BARs
263 //words may not be contiguous in memory, so we need to translate
264 //every address...
265 rval = ((u8) my_rdb(addr)) |
266 (((u8) my_rdb(addr + 1)) << 8);
267 } else {
268 if ((translated_addr & (u64) 0x1) == 0) {
269 // 16 bit aligned access...
270 set_ci();
271 rval = in16le((void *) translated_addr);
272 clr_ci();
273 } else {
274 // unaligned access, read single bytes
275 set_ci();
276 rval = (*((u8 *) translated_addr)) |
277 (*((u8 *) translated_addr + 1) << 8);
278 clr_ci();
279 }
280 }
281 DEBUG_PRINTF_MEM("%s(%08x) VGA --> %04x\n", __func__, addr,
282 rval);
283 return rval;
284 } else if (addr > M.mem_size) {
285 DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n",
286 __func__, addr);
287 //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1);
288 HALT_SYS();
289 } else {
290 /* read from virtual memory */
291 rval = in16le((void *) (M.mem_base + addr));
292 DEBUG_CHECK_VMEM_READ(addr, rval);
293 return rval;
294 }
295 return -1;
296}
297
298//read long from memory
299u32
300my_rdl(u32 addr)
301{
302 unsigned long translated_addr = addr;
Patrick Georgi91443042011-01-13 11:38:46 +0000303 u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000304 u32 rval;
305 if (translated != 0) {
Martin Roth63373ed2013-07-08 16:24:19 -0600306 //translation successful, access VGA Memory (BAR or Legacy...)
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000307 DEBUG_PRINTF_MEM("%s(%x): access to VGA Memory\n",
308 __func__, addr);
309 //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __func__, addr, translated_addr);
310 // check for legacy memory, because of the remapping to BARs, the reads must
311 // be byte reads...
312 if ((addr >= 0xa0000) && (addr < 0xc0000)) {
313 //read bytes a using my_rdb, because of the remapping to BARs
314 //dwords may not be contiguous in memory, so we need to translate
315 //every address...
316 rval = ((u8) my_rdb(addr)) |
317 (((u8) my_rdb(addr + 1)) << 8) |
318 (((u8) my_rdb(addr + 2)) << 16) |
319 (((u8) my_rdb(addr + 3)) << 24);
320 } else {
321 if ((translated_addr & (u64) 0x3) == 0) {
322 // 32 bit aligned access...
323 set_ci();
324 rval = in32le((void *) translated_addr);
325 clr_ci();
326 } else {
327 // unaligned access, read single bytes
328 set_ci();
329 rval = (*((u8 *) translated_addr)) |
330 (*((u8 *) translated_addr + 1) << 8) |
331 (*((u8 *) translated_addr + 2) << 16) |
332 (*((u8 *) translated_addr + 3) << 24);
333 clr_ci();
334 }
335 }
336 DEBUG_PRINTF_MEM("%s(%08x) VGA --> %08x\n", __func__, addr,
337 rval);
338 //HALT_SYS();
339 return rval;
340 } else if (addr > M.mem_size) {
341 DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n",
342 __func__, addr);
343 //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1);
344 HALT_SYS();
345 } else {
346 /* read from virtual memory */
347 rval = in32le((void *) (M.mem_base + addr));
348 switch (addr) {
349 case 0x46c:
350 //BDA Time Data, update it, before reading
351 update_time(rval);
352 rval = in32le((void *) (M.mem_base + addr));
353 break;
354 }
355 DEBUG_CHECK_VMEM_READ(addr, rval);
356 return rval;
357 }
358 return -1;
359}
360
361//write byte to memory
362void
363my_wrb(u32 addr, u8 val)
364{
365 unsigned long translated_addr = addr;
Patrick Georgi91443042011-01-13 11:38:46 +0000366 u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000367 if (translated != 0) {
Elyes HAOUAS394ec022018-08-07 12:23:43 +0200368 //translation successful, access VGA Memory (BAR or Legacy...)
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000369 DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n",
370 __func__, addr, val);
371 //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __func__, addr, translated_addr);
372 set_ci();
373 *((u8 *) translated_addr) = val;
374 clr_ci();
375 } else if (addr > M.mem_size) {
376 DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n",
377 __func__, addr);
378 //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1);
379 HALT_SYS();
380 } else {
381 /* write to virtual memory */
382 DEBUG_CHECK_VMEM_WRITE(addr, val);
383 *((u8 *) (M.mem_base + addr)) = val;
384 }
385}
386
387void
388my_wrw(u32 addr, u16 val)
389{
390 unsigned long translated_addr = addr;
Patrick Georgi91443042011-01-13 11:38:46 +0000391 u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000392 if (translated != 0) {
Elyes HAOUAS394ec022018-08-07 12:23:43 +0200393 //translation successful, access VGA Memory (BAR or Legacy...)
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000394 DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n",
395 __func__, addr, val);
396 //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __func__, addr, translated_addr);
397 // check for legacy memory, because of the remapping to BARs, the reads must
398 // be byte reads...
399 if ((addr >= 0xa0000) && (addr < 0xc0000)) {
400 //read bytes a using my_rdb, because of the remapping to BARs
401 //words may not be contiguous in memory, so we need to translate
402 //every address...
403 my_wrb(addr, (u8) (val & 0x00FF));
404 my_wrb(addr + 1, (u8) ((val & 0xFF00) >> 8));
405 } else {
406 if ((translated_addr & (u64) 0x1) == 0) {
407 // 16 bit aligned access...
408 set_ci();
409 out16le((void *) translated_addr, val);
410 clr_ci();
411 } else {
412 // unaligned access, write single bytes
413 set_ci();
414 *((u8 *) translated_addr) =
415 (u8) (val & 0x00FF);
416 *((u8 *) translated_addr + 1) =
417 (u8) ((val & 0xFF00) >> 8);
418 clr_ci();
419 }
420 }
421 } else if (addr > M.mem_size) {
422 DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n",
423 __func__, addr);
424 //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1);
425 HALT_SYS();
426 } else {
427 /* write to virtual memory */
428 DEBUG_CHECK_VMEM_WRITE(addr, val);
429 out16le((void *) (M.mem_base + addr), val);
430 }
431}
432void
433my_wrl(u32 addr, u32 val)
434{
435 unsigned long translated_addr = addr;
Patrick Georgi91443042011-01-13 11:38:46 +0000436 u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000437 if (translated != 0) {
Elyes HAOUAS394ec022018-08-07 12:23:43 +0200438 //translation successful, access VGA Memory (BAR or Legacy...)
Stefan Reinauer38cd29e2009-08-11 21:28:25 +0000439 DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n",
440 __func__, addr, val);
441 //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __func__, addr, translated_addr);
442 // check for legacy memory, because of the remapping to BARs, the reads must
443 // be byte reads...
444 if ((addr >= 0xa0000) && (addr < 0xc0000)) {
445 //read bytes a using my_rdb, because of the remapping to BARs
446 //words may not be contiguous in memory, so we need to translate
447 //every address...
448 my_wrb(addr, (u8) (val & 0x000000FF));
449 my_wrb(addr + 1, (u8) ((val & 0x0000FF00) >> 8));
450 my_wrb(addr + 2, (u8) ((val & 0x00FF0000) >> 16));
451 my_wrb(addr + 3, (u8) ((val & 0xFF000000) >> 24));
452 } else {
453 if ((translated_addr & (u64) 0x3) == 0) {
454 // 32 bit aligned access...
455 set_ci();
456 out32le((void *) translated_addr, val);
457 clr_ci();
458 } else {
459 // unaligned access, write single bytes
460 set_ci();
461 *((u8 *) translated_addr) =
462 (u8) (val & 0x000000FF);
463 *((u8 *) translated_addr + 1) =
464 (u8) ((val & 0x0000FF00) >> 8);
465 *((u8 *) translated_addr + 2) =
466 (u8) ((val & 0x00FF0000) >> 16);
467 *((u8 *) translated_addr + 3) =
468 (u8) ((val & 0xFF000000) >> 24);
469 clr_ci();
470 }
471 }
472 } else if (addr > M.mem_size) {
473 DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n",
474 __func__, addr);
475 //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1);
476 HALT_SYS();
477 } else {
478 /* write to virtual memory */
479 DEBUG_CHECK_VMEM_WRITE(addr, val);
480 out32le((void *) (M.mem_base + addr), val);
481 }
482}
Stefan Reinauerd650e992010-02-22 04:33:13 +0000483#else
484u8
485my_rdb(u32 addr)
486{
487 return rdb(addr);
488}
489
490u16
491my_rdw(u32 addr)
492{
493 return rdw(addr);
494}
495
496u32
497my_rdl(u32 addr)
498{
499 return rdl(addr);
500}
501
502void
503my_wrb(u32 addr, u8 val)
504{
505 wrb(addr, val);
506}
507
508void
509my_wrw(u32 addr, u16 val)
510{
511 wrw(addr, val);
512}
513
514void
515my_wrl(u32 addr, u32 val)
516{
517 wrl(addr, val);
518}
519#endif