]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/MAI/bios_emulator/scitech/src/biosemu/besys.c
* Patch by Thomas Frieden, 13 Nov 2002:
[karo-tx-uboot.git] / board / MAI / bios_emulator / scitech / src / biosemu / besys.c
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 /****************************************************************************
64 PARAMETERS:
65 addr    - Emulator memory address to read
66
67 RETURNS:
68 Byte value read from emulator memory.
69
70 REMARKS:
71 Reads a byte value from the emulator memory. We have three distinct memory
72 regions that are handled differently, which this function handles.
73 ****************************************************************************/
74 u8 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) {
86 DB(     printk("mem_read: address %#lx out of range!\n", addr);)
87         HALT_SYS();
88         }
89     else {
90         val = *(u8*)(M.mem_base + addr);
91         }
92 DB( if (DEBUG_MEM())
93         printk("%#08x 1 -> %#x\n", addr, val);)
94     return val;
95 }
96
97 /****************************************************************************
98 PARAMETERS:
99 addr    - Emulator memory address to read
100
101 RETURNS:
102 Word value read from emulator memory.
103
104 REMARKS:
105 Reads a word value from the emulator memory. We have three distinct memory
106 regions that are handled differently, which this function handles.
107 ****************************************************************************/
108 u16 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) {
136 DB(     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         }
149 DB( if (DEBUG_MEM())
150         printk("%#08x 2 -> %#x\n", addr, val);)
151     return val;
152 }
153
154 /****************************************************************************
155 PARAMETERS:
156 addr    - Emulator memory address to read
157
158 RETURNS:
159 Long value read from emulator memory.
160
161 REMARKS:
162 Reads a long value from the emulator memory. We have three distinct memory
163 regions that are handled differently, which this function handles.
164 ****************************************************************************/
165 u32 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) {
197 DB(     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         }
212 DB( if (DEBUG_MEM())
213         printk("%#08x 4 -> %#x\n", addr, val);)
214     return val;
215 }
216
217 /****************************************************************************
218 PARAMETERS:
219 addr    - Emulator memory address to read
220 val     - Value to store
221
222 REMARKS:
223 Writes a byte value to emulator memory. We have three distinct memory
224 regions that are handled differently, which this function handles.
225 ****************************************************************************/
226 void X86API BE_wrb(
227     u32 addr,
228     u8 val)
229 {
230 DB( 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) {
239 DB(     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 /****************************************************************************
248 PARAMETERS:
249 addr    - Emulator memory address to read
250 val     - Value to store
251
252 REMARKS:
253 Writes a word value to emulator memory. We have three distinct memory
254 regions that are handled differently, which this function handles.
255 ****************************************************************************/
256 void X86API BE_wrw(
257     u32 addr,
258     u16 val)
259 {
260 DB( 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) {
285 DB(     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 /****************************************************************************
301 PARAMETERS:
302 addr    - Emulator memory address to read
303 val     - Value to store
304
305 REMARKS:
306 Writes a long value to emulator memory. We have three distinct memory
307 regions that are handled differently, which this function handles.
308 ****************************************************************************/
309 void X86API BE_wrl(
310     u32 addr,
311     u32 val)
312 {
313 DB( 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) {
342 DB(     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
364 u8 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
372 u16 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
380 u32 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
388 void 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
395 void 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
402 void 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