]> git.ipfire.org Git - people/ms/u-boot.git/blame - board/MAI/bios_emulator/scitech/src/biosemu/besys.c
* Patch by Thomas Frieden, 13 Nov 2002:
[people/ms/u-boot.git] / board / MAI / bios_emulator / scitech / src / biosemu / besys.c
CommitLineData
c7de829c
WD
1/****************************************************************************
2*
3* BIOS emulator and interface
4* to Realmode X86 Emulator Library
5*
6* Copyright (C) 1996-1999 SciTech Software, Inc.
7*
8* ========================================================================
9*
10* Permission to use, copy, modify, distribute, and sell this software and
11* its documentation for any purpose is hereby granted without fee,
12* provided that the above copyright notice appear in all copies and that
13* both that copyright notice and this permission notice appear in
14* supporting documentation, and that the name of the authors not be used
15* in advertising or publicity pertaining to distribution of the software
16* without specific, written prior permission. The authors makes no
17* representations about the suitability of this software for any purpose.
18* It is provided "as is" without express or implied warranty.
19*
20* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
22* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
23* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
24* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
25* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
26* PERFORMANCE OF THIS SOFTWARE.
27*
28* ========================================================================
29*
30* Language: ANSI C
31* Environment: Any
32* Developer: Kendall Bennett
33*
34* Description: This file includes BIOS emulator I/O and memory access
35* functions.
36*
37****************************************************************************/
38
39#include "biosemui.h"
40
41/*------------------------------- Macros ----------------------------------*/
42
43/* Macros to read and write values to x86 bus memory. Replace these as
44 * necessary if you need to do something special to access memory over
45 * the bus on a particular processor family.
46 */
47
48#define readb(base,off) *((u8*)((u32)(base) + (off)))
49#define readw(base,off) *((u16*)((u32)(base) + (off)))
50#define readl(base,off) *((u32*)((u32)(base) + (off)))
51#define writeb(v,base,off) *((u8*)((u32)(base) + (off))) = (v)
52#define writew(v,base,off) *((u16*)((u32)(base) + (off))) = (v)
53#define writel(v,base,off) *((u32*)((u32)(base) + (off))) = (v)
54
55/*----------------------------- Implementation ----------------------------*/
56
57#ifdef DEBUG
58# define DEBUG_MEM() (M.x86.debug & DEBUG_MEM_TRACE_F)
59#else
60# define DEBUG_MEM()
61#endif
62
63/****************************************************************************
64PARAMETERS:
65addr - Emulator memory address to read
66
67RETURNS:
68Byte value read from emulator memory.
69
70REMARKS:
71Reads a byte value from the emulator memory. We have three distinct memory
72regions that are handled differently, which this function handles.
73****************************************************************************/
74u8 X86API BE_rdb(
75 u32 addr)
76{
77 u8 val = 0;
78
79 if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
80 val = *(u8*)(_BE_env.biosmem_base + addr - 0xC0000);
81 }
82 else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
83 val = readb(_BE_env.busmem_base, addr - 0xA0000);
84 }
85 else if (addr > M.mem_size - 1) {
86DB( printk("mem_read: address %#lx out of range!\n", addr);)
87 HALT_SYS();
88 }
89 else {
90 val = *(u8*)(M.mem_base + addr);
91 }
92DB( if (DEBUG_MEM())
93 printk("%#08x 1 -> %#x\n", addr, val);)
94 return val;
95}
96
97/****************************************************************************
98PARAMETERS:
99addr - Emulator memory address to read
100
101RETURNS:
102Word value read from emulator memory.
103
104REMARKS:
105Reads a word value from the emulator memory. We have three distinct memory
106regions that are handled differently, which this function handles.
107****************************************************************************/
108u16 X86API BE_rdw(
109 u32 addr)
110{
111 u16 val = 0;
112
113 if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
114#ifdef __BIG_ENDIAN__
115 if (addr & 0x1) {
116 addr -= 0xC0000;
117 val = ( *(u8*)(_BE_env.biosmem_base + addr) |
118 (*(u8*)(_BE_env.biosmem_base + addr + 1) << 8));
119 }
120 else
121#endif
122 val = *(u16*)(_BE_env.biosmem_base + addr - 0xC0000);
123 }
124 else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
125#ifdef __BIG_ENDIAN__
126 if (addr & 0x1) {
127 addr -= 0xA0000;
128 val = ( readb(_BE_env.busmem_base, addr) |
129 (readb(_BE_env.busmem_base, addr + 1) << 8));
130 }
131 else
132#endif
133 val = readw(_BE_env.busmem_base, addr - 0xA0000);
134 }
135 else if (addr > M.mem_size - 2) {
136DB( printk("mem_read: address %#lx out of range!\n", addr);)
137 HALT_SYS();
138 }
139 else {
140#ifdef __BIG_ENDIAN__
141 if (addr & 0x1) {
142 val = ( *(u8*)(M.mem_base + addr) |
143 (*(u8*)(M.mem_base + addr + 1) << 8));
144 }
145 else
146#endif
147 val = *(u16*)(M.mem_base + addr);
148 }
149DB( if (DEBUG_MEM())
150 printk("%#08x 2 -> %#x\n", addr, val);)
151 return val;
152}
153
154/****************************************************************************
155PARAMETERS:
156addr - Emulator memory address to read
157
158RETURNS:
159Long value read from emulator memory.
160
161REMARKS:
162Reads a long value from the emulator memory. We have three distinct memory
163regions that are handled differently, which this function handles.
164****************************************************************************/
165u32 X86API BE_rdl(
166 u32 addr)
167{
168 u32 val = 0;
169
170 if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
171#ifdef __BIG_ENDIAN__
172 if (addr & 0x3) {
173 addr -= 0xC0000;
174 val = ( *(u8*)(_BE_env.biosmem_base + addr + 0) |
175 (*(u8*)(_BE_env.biosmem_base + addr + 1) << 8) |
176 (*(u8*)(_BE_env.biosmem_base + addr + 2) << 16) |
177 (*(u8*)(_BE_env.biosmem_base + addr + 3) << 24));
178 }
179 else
180#endif
181 val = *(u32*)(_BE_env.biosmem_base + addr - 0xC0000);
182 }
183 else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
184#ifdef __BIG_ENDIAN__
185 if (addr & 0x3) {
186 addr -= 0xA0000;
187 val = ( readb(_BE_env.busmem_base, addr) |
188 (readb(_BE_env.busmem_base, addr + 1) << 8) |
189 (readb(_BE_env.busmem_base, addr + 2) << 16) |
190 (readb(_BE_env.busmem_base, addr + 3) << 24));
191 }
192 else
193#endif
194 val = readl(_BE_env.busmem_base, addr - 0xA0000);
195 }
196 else if (addr > M.mem_size - 4) {
197DB( printk("mem_read: address %#lx out of range!\n", addr);)
198 HALT_SYS();
199 }
200 else {
201#ifdef __BIG_ENDIAN__
202 if (addr & 0x3) {
203 val = ( *(u8*)(M.mem_base + addr + 0) |
204 (*(u8*)(M.mem_base + addr + 1) << 8) |
205 (*(u8*)(M.mem_base + addr + 2) << 16) |
206 (*(u8*)(M.mem_base + addr + 3) << 24));
207 }
208 else
209#endif
210 val = *(u32*)(M.mem_base + addr);
211 }
212DB( if (DEBUG_MEM())
213 printk("%#08x 4 -> %#x\n", addr, val);)
214 return val;
215}
216
217/****************************************************************************
218PARAMETERS:
219addr - Emulator memory address to read
220val - Value to store
221
222REMARKS:
223Writes a byte value to emulator memory. We have three distinct memory
224regions that are handled differently, which this function handles.
225****************************************************************************/
226void X86API BE_wrb(
227 u32 addr,
228 u8 val)
229{
230DB( if (DEBUG_MEM())
231 printk("%#08x 1 <- %#x\n", addr, val);)
232 if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
233 *(u8*)(_BE_env.biosmem_base + addr - 0xC0000) = val;
234 }
235 else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
236 writeb(val, _BE_env.busmem_base, addr - 0xA0000);
237 }
238 else if (addr > M.mem_size-1) {
239DB( printk("mem_write: address %#lx out of range!\n", addr);)
240 HALT_SYS();
241 }
242 else {
243 *(u8*)(M.mem_base + addr) = val;
244 }
245}
246
247/****************************************************************************
248PARAMETERS:
249addr - Emulator memory address to read
250val - Value to store
251
252REMARKS:
253Writes a word value to emulator memory. We have three distinct memory
254regions that are handled differently, which this function handles.
255****************************************************************************/
256void X86API BE_wrw(
257 u32 addr,
258 u16 val)
259{
260DB( if (DEBUG_MEM())
261 printk("%#08x 2 <- %#x\n", addr, val);)
262 if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
263#ifdef __BIG_ENDIAN__
264 if (addr & 0x1) {
265 addr -= 0xC0000;
266 *(u8*)(_BE_env.biosmem_base + addr + 0) = (val >> 0) & 0xff;
267 *(u8*)(_BE_env.biosmem_base + addr + 1) = (val >> 8) & 0xff;
268 }
269 else
270#endif
271 *(u16*)(_BE_env.biosmem_base + addr - 0xC0000) = val;
272 }
273 else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
274#ifdef __BIG_ENDIAN__
275 if (addr & 0x1) {
276 addr -= 0xA0000;
277 writeb(val >> 0, _BE_env.busmem_base, addr);
278 writeb(val >> 8, _BE_env.busmem_base, addr + 1);
279 }
280 else
281#endif
282 writew(val, _BE_env.busmem_base, addr - 0xA0000);
283 }
284 else if (addr > M.mem_size-2) {
285DB( printk("mem_write: address %#lx out of range!\n", addr);)
286 HALT_SYS();
287 }
288 else {
289#ifdef __BIG_ENDIAN__
290 if (addr & 0x1) {
291 *(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff;
292 *(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff;
293 }
294 else
295#endif
296 *(u16*)(M.mem_base + addr) = val;
297 }
298}
299
300/****************************************************************************
301PARAMETERS:
302addr - Emulator memory address to read
303val - Value to store
304
305REMARKS:
306Writes a long value to emulator memory. We have three distinct memory
307regions that are handled differently, which this function handles.
308****************************************************************************/
309void X86API BE_wrl(
310 u32 addr,
311 u32 val)
312{
313DB( if (DEBUG_MEM())
314 printk("%#08x 4 <- %#x\n", addr, val);)
315 if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
316#ifdef __BIG_ENDIAN__
317 if (addr & 0x1) {
318 addr -= 0xC0000;
319 *(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff;
320 *(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff;
321 *(u8*)(M.mem_base + addr + 2) = (val >> 16) & 0xff;
322 *(u8*)(M.mem_base + addr + 3) = (val >> 24) & 0xff;
323 }
324 else
325#endif
326 *(u32*)(M.mem_base + addr - 0xC0000) = val;
327 }
328 else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
329#ifdef __BIG_ENDIAN__
330 if (addr & 0x3) {
331 addr -= 0xA0000;
332 writeb(val >> 0, _BE_env.busmem_base, addr);
333 writeb(val >> 8, _BE_env.busmem_base, addr + 1);
334 writeb(val >> 16, _BE_env.busmem_base, addr + 1);
335 writeb(val >> 24, _BE_env.busmem_base, addr + 1);
336 }
337 else
338#endif
339 writel(val, _BE_env.busmem_base, addr - 0xA0000);
340 }
341 else if (addr > M.mem_size-4) {
342DB( printk("mem_write: address %#lx out of range!\n", addr);)
343 HALT_SYS();
344 }
345 else {
346#ifdef __BIG_ENDIAN__
347 if (addr & 0x1) {
348 *(u8*)(M.mem_base + addr + 0) = (val >> 0) & 0xff;
349 *(u8*)(M.mem_base + addr + 1) = (val >> 8) & 0xff;
350 *(u8*)(M.mem_base + addr + 2) = (val >> 16) & 0xff;
351 *(u8*)(M.mem_base + addr + 3) = (val >> 24) & 0xff;
352 }
353 else
354#endif
355 *(u32*)(M.mem_base + addr) = val;
356 }
357}
358
359/* Debug functions to do ISA/PCI bus port I/O */
360
361#ifdef DEBUG
362#define DEBUG_IO() (M.x86.debug & DEBUG_IO_TRACE_F)
363
364u8 X86API BE_inb(int port)
365{
366 u8 val = PM_inpb(port);
367 if (DEBUG_IO())
368 printk("%04X:%04X: inb.%04X -> %02X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
369 return val;
370}
371
372u16 X86API BE_inw(int port)
373{
374 u16 val = PM_inpw(port);
375 if (DEBUG_IO())
376 printk("%04X:%04X: inw.%04X -> %04X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
377 return val;
378}
379
380u32 X86API BE_inl(int port)
381{
382 u32 val = PM_inpd(port);
383 if (DEBUG_IO())
384 printk("%04X:%04X: inl.%04X -> %08X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
385 return val;
386}
387
388void X86API BE_outb(int port, u8 val)
389{
390 if (DEBUG_IO())
391 printk("%04X:%04X: outb.%04X <- %02X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
392 PM_outpb(port,val);
393}
394
395void X86API BE_outw(int port, u16 val)
396{
397 if (DEBUG_IO())
398 printk("%04X:%04X: outw.%04X <- %04X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
399 PM_outpw(port,val);
400}
401
402void X86API BE_outl(int port, u32 val)
403{
404 if (DEBUG_IO())
405 printk("%04X:%04X: outl.%04X <- %08X\n",M.x86.saved_cs, M.x86.saved_ip, (ushort)port, val);
406 PM_outpd(port,val);
407}
408#endif