blob: 3ec2c2362b354bc7c3ecc385777cba0813f6156e [file] [log] [blame]
Li-Ta Lo81521262004-07-08 17:18:27 +00001/* $XFree86: xc/programs/Xserver/hw/xfree86/int10/helper_exec.c,v 1.16 2001/04/30 14:34:57 tsi Exp $ */
2/*
3 * XFree86 int10 module
4 * execute BIOS int 10h calls in x86 real mode environment
5 * Copyright 1999 Egbert Eich
6 *
7 * Part of this is based on code taken from DOSEMU
8 * (C) Copyright 1992, ..., 1999 the "DOSEMU-Development-Team"
9 */
10
11/*
12 * To debug port accesses define PRINT_PORT.
13 * Note! You also have to comment out ioperm()
14 * in xf86EnableIO(). Otherwise we won't trap
15 * on PIO.
16 */
17#include <x86emu.h>
Luc Verhaegene6e899d2009-05-27 11:39:16 +000018#include "helper_exec.h"
Li-Ta Lo81521262004-07-08 17:18:27 +000019#include "test.h"
Luc Verhaegene6e899d2009-05-27 11:39:16 +000020#include <sys/io.h>
Li-Ta Lo81521262004-07-08 17:18:27 +000021#include <sys/time.h>
Luc Verhaegene6e899d2009-05-27 11:39:16 +000022#include <stdio.h>
23
Li-Ta Lo81521262004-07-08 17:18:27 +000024
25int port_rep_inb(u16 port, u32 base, int d_f, u32 count);
26u8 x_inb(u16 port);
27u16 x_inw(u16 port);
28void x_outb(u16 port, u8 val);
29void x_outw(u16 port, u16 val);
30u32 x_inl(u16 port);
31void x_outl(u16 port, u32 val);
32
33/* general software interrupt handler */
34u32 getIntVect(int num)
35{
36 return MEM_RW(num << 2) + (MEM_RW((num << 2) + 2) << 4);
37}
38
39void pushw(u16 val)
40{
41 X86_ESP -= 2;
42 MEM_WW(((u32) X86_SS << 4) + X86_SP, val);
43}
44
45int run_bios_int(int num)
46{
47 u32 eflags;
48
49 eflags = X86_EFLAGS;
50 pushw(eflags);
51 pushw(X86_CS);
52 pushw(X86_IP);
53 X86_CS = MEM_RW((num << 2) + 2);
54 X86_IP = MEM_RW(num << 2);
55
Li-Ta Lo8b0356c2005-01-11 03:18:39 +000056 printf("%s: INT %x CS:IP = %x:%x\n", __FUNCTION__,
57 num, MEM_RW((num << 2) + 2), MEM_RW(num << 2));
Li-Ta Lo81521262004-07-08 17:18:27 +000058
59 return 1;
60}
61
62int port_rep_inb(u16 port, u32 base, int d_f, u32 count)
63{
64 register int inc = d_f ? -1 : 1;
65 u32 dst = base;
66 while (count--) {
67 MEM_WB(dst, x_inb(port));
68 dst += inc;
69 }
70 return dst - base;
71}
72
73int port_rep_inw(u16 port, u32 base, int d_f, u32 count)
74{
75 register int inc = d_f ? -2 : 2;
76 u32 dst = base;
77 while (count--) {
78 MEM_WW(dst, x_inw(port));
79 dst += inc;
80 }
81 return dst - base;
82}
83
84int port_rep_inl(u16 port, u32 base, int d_f, u32 count)
85{
86 register int inc = d_f ? -4 : 4;
87 u32 dst = base;
88 while (count--) {
89 MEM_WL(dst, x_inl(port));
90 dst += inc;
91 }
92 return dst - base;
93}
94
95int port_rep_outb(u16 port, u32 base, int d_f, u32 count)
96{
97 register int inc = d_f ? -1 : 1;
98 u32 dst = base;
99 while (count--) {
100 x_outb(port, MEM_RB(dst));
101 dst += inc;
102 }
103 return dst - base;
104}
105
106int port_rep_outw(u16 port, u32 base, int d_f, u32 count)
107{
108 register int inc = d_f ? -2 : 2;
109 u32 dst = base;
110 while (count--) {
111 x_outw(port, MEM_RW(dst));
112 dst += inc;
113 }
114 return dst - base;
115}
116
117int port_rep_outl(u16 port, u32 base, int d_f, u32 count)
118{
119 register int inc = d_f ? -4 : 4;
120 u32 dst = base;
121 while (count--) {
122 x_outl(port, MEM_RL(dst));
123 dst += inc;
124 }
125 return dst - base;
126}
127
128u8 x_inb(u16 port)
129{
130 u8 val;
131
132 val = inb(port);
133
Li-Ta Lo8b0356c2005-01-11 03:18:39 +0000134 printf("inb(0x%04x) = 0x%02x\n", port, val);
Li-Ta Lo81521262004-07-08 17:18:27 +0000135
136 return val;
137}
138
139u16 x_inw(u16 port)
140{
141 u16 val;
142
143 val = inw(port);
144
Li-Ta Lo8b0356c2005-01-11 03:18:39 +0000145 printf("inw(0x%04x) = 0x%04x\n", port, val);
Li-Ta Lo81521262004-07-08 17:18:27 +0000146 return val;
147}
148
149u32 x_inl(u16 port)
150{
151 u32 val;
152
153 val = inl(port);
154
Li-Ta Lo8b0356c2005-01-11 03:18:39 +0000155 printf("inl(0x%04x) = 0x%08x\n", port, val);
Li-Ta Lo81521262004-07-08 17:18:27 +0000156 return val;
157}
158
159void x_outb(u16 port, u8 val)
160{
Li-Ta Lo8b0356c2005-01-11 03:18:39 +0000161 printf("outb(0x%02x, 0x%04x)\n",
162 val, port);
Li-Ta Lo81521262004-07-08 17:18:27 +0000163 outb(val, port);
164}
165
166void x_outw(u16 port, u16 val)
167{
Li-Ta Lo8b0356c2005-01-11 03:18:39 +0000168 printf("outw(0x%04x, 0x%04x)\n", val, port);
Li-Ta Lo81521262004-07-08 17:18:27 +0000169 outw(val, port);
170}
171
172void x_outl(u16 port, u32 val)
173{
Li-Ta Lo8b0356c2005-01-11 03:18:39 +0000174 printf("outl(0x%08x, 0x%04x)\n", val, port);
Li-Ta Lo81521262004-07-08 17:18:27 +0000175 outl(val, port);
176}
177
178u8 Mem_rb(int addr)
179{
180 return (*current->mem->rb) (current, addr);
181}
182
183u16 Mem_rw(int addr)
184{
185 return (*current->mem->rw) (current, addr);
186}
187
188u32 Mem_rl(int addr)
189{
190 return (*current->mem->rl) (current, addr);
191}
192
193void Mem_wb(int addr, u8 val)
194{
195 (*current->mem->wb) (current, addr, val);
196}
197
198void Mem_ww(int addr, u16 val)
199{
200 (*current->mem->ww) (current, addr, val);
201}
202
203void Mem_wl(int addr, u32 val)
204{
205 (*current->mem->wl) (current, addr, val);
206}
207
208void getsecs(unsigned long *sec, unsigned long *usec)
209{
210 struct timeval tv;
211 gettimeofday(&tv, 0);
212 *sec = tv.tv_sec;
213 *usec = tv.tv_usec;
214}
215
216#define TAG(Cfg1Addr) (Cfg1Addr & 0xffff00)
217#define OFFSET(Cfg1Addr) (Cfg1Addr & 0xff)
218
219u8 bios_checksum(u8 * start, int size)
220{
221 u8 sum = 0;
222
223 while (size-- > 0)
224 sum += *start++;
225 return sum;
226}
227
228/*
229 * Lock/Unlock legacy VGA. Some Bioses try to be very clever and make
230 * an attempt to detect a legacy ISA card. If they find one they might
231 * act very strange: for example they might configure the card as a
232 * monochrome card. This might cause some drivers to choke.
233 * To avoid this we attempt legacy VGA by writing to all know VGA
234 * disable registers before we call the BIOS initialization and
235 * restore the original values afterwards. In beween we hold our
236 * breath. To get to a (possibly exising) ISA card need to disable
237 * our current PCI card.
238 */
239/*
240 * This is just for booting: we just want to catch pure
241 * legacy vga therefore we don't worry about mmio etc.
242 * This stuff should really go into vgaHW.c. However then
243 * the driver would have to load the vga-module prior to
244 * doing int10.
245 */
246/*void
247LockLegacyVGA(int screenIndex,legacyVGAPtr vga)
248{
249 xf86SetCurrentAccess(FALSE, xf86Screens[screenIndex]);
250 vga->save_msr = inb(0x3CC);
251 vga->save_vse = inb(0x3C3);
252 vga->save_46e8 = inb(0x46e8);
253 vga->save_pos102 = inb(0x102);
254 outb(0x3C2, ~(u8)0x03 & vga->save_msr);
255 outb(0x3C3, ~(u8)0x01 & vga->save_vse);
256 outb(0x46e8, ~(u8)0x08 & vga->save_46e8);
257 outb(0x102, ~(u8)0x01 & vga->save_pos102);
258 xf86SetCurrentAccess(TRUE, xf86Screens[screenIndex]);
259}
260
261void
262UnlockLegacyVGA(int screenIndex, legacyVGAPtr vga)
263{
264 xf86SetCurrentAccess(FALSE, xf86Screens[screenIndex]);
265 outb(0x102, vga->save_pos102);
266 outb(0x46e8, vga->save_46e8);
267 outb(0x3C3, vga->save_vse);
268 outb(0x3C2, vga->save_msr);
269 xf86SetCurrentAccess(TRUE, xf86Screens[screenIndex]);
270}
271*/