]>
git.ipfire.org Git - ipfire-2.x.git/blob - src/hwinfo/src/int10/i10_vbios.c
2 * Copyright 1999 Egbert Eich
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the authors not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. The authors makes no representations
11 * about the suitability of this software for any purpose. It is provided
12 * "as is" without express or implied warranty.
14 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
27 #include <sys/types.h>
33 #if defined(__alpha__) || defined (__ia64__)
35 //#elif defined(HAVE_SYS_PERM)
41 #include "AsmMacros.h"
44 void log_err(char *format
, ...) __attribute__ ((format (printf
, 1, 2)));
47 #define VRAM_START 0xA0000
48 #define VRAM_SIZE 0x1FFFF
49 #define V_BIOS_SIZE 0x1FFFF
50 #define BIOS_START 0x7C00 /* default BIOS entry */
52 static CARD8 code
[] = { 0xcd, 0x10, 0xf4 }; /* int 0x10, hlt */
53 // static CARD8 code13[] = { 0xcd, 0x13, 0xf4 }; /* int 0x13, hlt */
55 static int int10_bios_ok(void);
57 static void unmap(void);
58 static int map_vram(void);
59 static void unmap_vram(void);
60 static int copy_vbios(hd_data_t
*hd_data
);
61 // static int copy_sbios(void);
63 static int copy_sys_bios(hd_data_t
*hd_data
);
65 static int copy_bios_ram(hd_data_t
*hd_data
);
66 static int setup_system_bios(hd_data_t
*hd_data
);
67 static void setup_int_vect(void);
68 static int chksum(CARD8
*start
);
70 void loadCodeToMem(unsigned char *ptr
, CARD8
*code
);
72 static int vram_mapped
= 0;
73 static int int10inited
= 0;
75 static sigjmp_buf longjmp_buf
;
77 static void sigsegv_handler(int);
79 int InitInt10(hd_data_t
*hd_data
, int pci_cfg_method
)
81 if(geteuid()) return -1;
85 if(!setup_system_bios(hd_data
)) {
97 scan_pci(pci_cfg_method
);
99 for(; CurrentPci
; CurrentPci
= CurrentPci
->next
) {
100 if(CurrentPci
->active
) break;
107 if(!copy_vbios(hd_data
)) {
112 if(!map_vram() || !copy_bios_ram(hd_data
)) {
117 if(!int10_bios_ok()) {
130 if(!int10inited
) return;
140 * Check whether int 0x10 points to some useful code.
147 ip
= ((uint16_t *) 0)[0x10 * 2];
148 cs
= ((uint16_t *) 0)[0x10 * 2 + 1];
150 p
= (unsigned char *) ((cs
<< 4) + ip
);
153 " vbe: int 10h points to %04x:%04x: %02x %02x %02x %02x %02x %02x %02x %02x\n",
155 p
[0], p
[1], p
[2], p
[3], p
[4], p
[5], p
[6], p
[7]
158 /* It can't possibly start with all zeros. */
159 if(!*(uint32_t *) p
) {
160 log_err(" vbe: oops, int 10h points into nirvana!\n");
169 void sigsegv_handler(int num
)
171 siglongjmp(longjmp_buf
, num
+ 1000);
175 int CallInt10(int *ax
, int *bx
, int *cx
, unsigned char *buf
, int len
, int cpuemu
)
178 void (*old_sigsegv_handler
)(int) = SIG_DFL
;
179 void (*old_sigill_handler
)(int) = SIG_DFL
;
180 void (*old_sigtrap_handler
)(int) = SIG_DFL
;
183 if(!int10inited
) return -1;
184 memset(&bRegs
, 0, sizeof bRegs
);
191 if(buf
) memcpy((unsigned char *) 0x7e00, buf
, len
);
195 jmp
= sigsetjmp(longjmp_buf
, 1);
198 old_sigsegv_handler
= signal(SIGSEGV
, sigsegv_handler
);
199 old_sigill_handler
= signal(SIGILL
, sigsegv_handler
);
200 old_sigtrap_handler
= signal(SIGTRAP
, sigsegv_handler
);
202 loadCodeToMem((unsigned char *) BIOS_START
, code
);
203 do_x86(BIOS_START
, &bRegs
, cpuemu
);
207 log_err("oops: got signal %d in vm86() code\n", jmp
- 1000);
210 signal(SIGTRAP
, old_sigtrap_handler
);
211 signal(SIGILL
, old_sigill_handler
);
212 signal(SIGSEGV
, old_sigsegv_handler
);
216 if(buf
) memcpy(buf
, (unsigned char *) 0x7e00, len
);
227 int CallInt13(int *ax
, int *bx
, int *cx
, int *dx
, unsigned char *buf
, int len
, int cpuemu
)
231 if(!int10inited
) return -1;
232 memset(&bRegs
, 0, sizeof bRegs
);
241 if(buf
) memcpy((unsigned char *) 0x7e00, buf
, len
);
245 loadCodeToMem((unsigned char *) BIOS_START
, code13
);
246 do_x86(BIOS_START
, &bRegs
, cpuemu
);
250 if(buf
) memcpy(buf
, (unsigned char *) 0x7e00, len
);
266 mem
= mmap(0, (size_t) SIZE
, PROT_EXEC
| PROT_READ
| PROT_WRITE
, MAP_FIXED
| MAP_PRIVATE
| MAP_ANON
, -1, 0);
269 perror("anonymous map");
273 memset(mem
, 0, SIZE
);
275 loadCodeToMem((unsigned char *) BIOS_START
, code
);
293 if ((mem_fd
= open(MEM_FILE
,O_RDWR
| O_SYNC
))<0)
295 if ((mem_fd
= open(MEM_FILE
,O_RDWR
))<0)
298 perror("opening memory");
303 if (mmap((void *) VRAM_START
, (size_t) VRAM_SIZE
,
304 PROT_EXEC
| PROT_READ
| PROT_WRITE
, MAP_SHARED
| MAP_FIXED
,
305 mem_fd
, VRAM_START
) == (void *) -1)
307 if (!_bus_base()) sparse_shift
= 7; /* Uh, oh, JENSEN... */
308 if (!_bus_base_sparse()) sparse_shift
= 0;
309 if ((vram_map
= mmap(0,(size_t) (VRAM_SIZE
<< sparse_shift
),
310 PROT_READ
| PROT_WRITE
,
312 mem_fd
, (VRAM_START
<< sparse_shift
)
313 | _bus_base_sparse())) == (void *) -1)
316 perror("mmap error in map_hardware_ram");
328 if(!vram_mapped
) return;
330 munmap((void*) VRAM_START
, VRAM_SIZE
);
337 * Read video BIOS from /dev/mem.
343 int copy_vbios(hd_data_t
*hd_data
)
346 unsigned char tmp
[3];
348 if(!hd_read_mmap(hd_data
, MEM_FILE
, tmp
, V_BIOS
, sizeof tmp
)) {
349 log_err("vbe: failed to read %u bytes at 0x%x\n", (unsigned) sizeof tmp
, V_BIOS
);
353 if(tmp
[0] != 0x55 || tmp
[1] != 0xAA ) {
354 log_err("vbe: no bios found at: 0x%x\n", V_BIOS
);
358 size
= tmp
[2] * 0x200;
360 if(!hd_read_mmap(hd_data
, MEM_FILE
, (unsigned char *) V_BIOS
, V_BIOS
, size
)) {
361 log_err("vbe: failed to read %d bytes at 0x%x\n", size
, V_BIOS
);
365 return chksum((CARD8
*) V_BIOS
) ? 1 : 0;
371 copy_sys_bios(hd_data_t
*hd_data
)
373 return hd_read_mmap(hd_data
, MEM_FILE
, (unsigned char *) 0xf0000, 0xf0000, 0xffff);
378 static int copy_bios_ram(hd_data_t
*hd_data
)
380 return hd_read_mmap(hd_data
, MEM_FILE
, (unsigned char *) 0, 0, 0x1000);
383 void loadCodeToMem(unsigned char *ptr
, CARD8
*code
)
385 while((*ptr
++ = *code
++) != 0xf4 /* hlt */);
392 * here we are really paranoid about faking a "real"
393 * BIOS. Most of this information was pulled from
399 const CARD16 cs
= 0x0000;
400 const CARD16 ip
= 0x0;
403 /* let the int vects point to the SYS_BIOS seg */
404 for (i
=0; i
<0x80; i
++) {
405 ((CARD16
*)0)[i
<<1] = ip
;
406 ((CARD16
*)0)[(i
<<1)+1] = cs
;
408 /* video interrupts default location */
409 ((CARD16
*)0)[(0x42<<1)+1] = 0xf000;
410 ((CARD16
*)0)[0x42<<1] = 0xf065;
411 ((CARD16
*)0)[(0x10<<1)+1] = 0xf000;
412 ((CARD16
*)0)[0x10<<1] = 0xf065;
413 /* video param table default location (int 1d) */
414 ((CARD16
*)0)[(0x1d<<1)+1] = 0xf000;
415 ((CARD16
*)0)[0x1d<<1] = 0xf0A4;
416 /* font tables default location (int 1F) */
417 ((CARD16
*)0)[(0x1f<<1)+1] = 0xf000;
418 ((CARD16
*)0)[0x1f<<1] = 0xfa6e;
420 /* int 11 default location */
421 ((CARD16
*)0)[(0x11<1)+1] = 0xf000;
422 ((CARD16
*)0)[0x11<<1] = 0xf84d;
423 /* int 12 default location */
424 ((CARD16
*)0)[(0x12<<1)+1] = 0xf000;
425 ((CARD16
*)0)[0x12<<1] = 0xf841;
426 /* int 15 default location */
427 ((CARD16
*)0)[(0x15<<1)+1] = 0xf000;
428 ((CARD16
*)0)[0x15<<1] = 0xf859;
429 /* int 1A default location */
430 ((CARD16
*)0)[(0x1a<<1)+1] = 0xf000;
431 ((CARD16
*)0)[0x1a<<1] = 0xff6e;
432 /* int 05 default location */
433 ((CARD16
*)0)[(0x05<<1)+1] = 0xf000;
434 ((CARD16
*)0)[0x05<<1] = 0xff54;
435 /* int 08 default location */
436 ((CARD16
*)0)[(0x8<<1)+1] = 0xf000;
437 ((CARD16
*)0)[0x8<<1] = 0xfea5;
438 /* int 13 default location (fdd) */
439 ((CARD16
*)0)[(0x13<<1)+1] = 0xf000;
440 ((CARD16
*)0)[0x13<<1] = 0xec59;
441 /* int 0E default location */
442 ((CARD16
*)0)[(0xe<<1)+1] = 0xf000;
443 ((CARD16
*)0)[0xe<<1] = 0xef57;
444 /* int 17 default location */
445 ((CARD16
*)0)[(0x17<<1)+1] = 0xf000;
446 ((CARD16
*)0)[0x17<<1] = 0xefd2;
447 /* fdd table default location (int 1e) */
448 ((CARD16
*)0)[(0x1e<<1)+1] = 0xf000;
449 ((CARD16
*)0)[0x1e<<1] = 0xefc7;
453 setup_system_bios(hd_data_t
*hd_data
)
455 char *date
= "06/01/99";
456 char *eisa_ident
= "PCI/ISA";
459 if (!copy_sys_bios(hd_data
)) return 0;
462 // memset((void *)0xF0000,0xf4,0xfff7);
465 * we trap the "industry standard entry points" to the BIOS
466 * and all other locations by filling them with "hlt"
467 * TODO: implement hlt-handler for these
469 memset((void *)0xF0000,0xf4,0x10000);
472 * TODO: we should copy the fdd table (0xfec59-0xfec5b)
473 * the video parameter table (0xf0ac-0xf0fb)
474 * and the font tables (0xfa6e-0xfe6d)
475 * from the original bios here
479 strcpy((char *)0xFFFF5,date
);
480 /* set up eisa ident string */
481 strcpy((char *)0xFFFD9,eisa_ident
);
482 /* write system model id for IBM-AT */
483 ((char *)0)[0xFFFFE] = 0xfc;
496 int chksum(CARD8
*start
)
502 size
= start
[2] * 0x200;
503 for(i
= 0; i
< size
; i
++) val
+= start
[i
];
507 log_err("vbe: BIOS chksum wrong\n");