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>
32 #if defined(__alpha__) || defined (__ia64__)
34 #elif defined(HAVE_SYS_PERM)
40 #include "AsmMacros.h"
43 #define VRAM_START 0xA0000
44 #define VRAM_SIZE 0x1FFFF
45 #define V_BIOS_SIZE 0x1FFFF
46 #define BIOS_START 0x7C00 /* default BIOS entry */
48 /*CARD8 code[] = { 0xb8 , 0xf0 , 0xf0, 0xf4 }; */
49 #define VB_X(x) (V_BIOS >> x) & 0xFF
50 CARD8 code[] = { 0x9a, 0x03, 0x00, 0x00, VB_X(12), 0xf4 };
51 /*CARD8 code[] = { 0x9a, 0x03, 0x00, 0x00, VB_X(12), 0xb8, 0x03, 0x00, */
52 /*0xcd, 0x10, 0xf4 }; */
53 /*CARD8 code[] = { 0xb8 , 0xf0 , 0xf0 ,0xf4 }; */
55 static void sig_handler(int);
57 static void unmap(void);
58 static void bootBIOS(CARD16 ax);
59 static int map_vram(void);
60 static void unmap_vram(void);
61 static int copy_vbios(void);
62 static int copy_sys_bios(void);
63 static void save_bios_to_file(void);
64 static int setup_system_bios(void);
65 static void setup_int_vect(void);
66 static int chksum(CARD8 *start);
67 static void setup_bios_regs(i86biosRegsPtr regs, CARD32 ax);
69 void loadCodeToMem(unsigned char *ptr, CARD8 *code);
70 void dprint(unsigned long start, unsigned long size);
72 static int vram_mapped = 0;
73 static CARD8 save_msr;
74 static CARD8 save_pos102;
75 static CARD8 save_vse;
76 static CARD8 save_46e8;
84 int Active_is_Pci = 0;
86 Config.PrintPort = PRINT_PORT;
87 Config.IoStatistics = IO_STATISTICS;
88 Config.PrintIrq = PRINT_IRQ;
89 Config.PrintPci = PRINT_PCI;
90 Config.ShowAllDev = SHOW_ALL_DEV;
91 Config.PrintIp = PRINT_IP;
92 Config.SaveBios = SAVE_BIOS;
94 Config.ConfigActiveOnly = CONFIG_ACTIVE_ONLY;
95 Config.ConfigActiveDevice = CONFIG_ACTIVE_DEVICE;
96 Config.MapSysBios = MAP_SYS_BIOS;
97 Config.Resort = RESORT;
98 Config.FixRom = FIX_ROM;
99 Config.NoConsole = NO_CONSOLE;
100 Config.Verbose = VERBOSE;
105 if (!setup_system_bios())
112 if (!CurrentPci && !Config.ConfigActiveDevice && !Config.ConfigActiveOnly)
115 Console = open_console();
117 if (Config.ConfigActiveOnly) {
123 if (CurrentPci->active) {
125 if (!(mapPciRom(NULL) && chksum((CARD8*)V_BIOS)))
129 CurrentPci = CurrentPci->next;
131 ax = ((CARD16)(CurrentPci->bus) << 8)
132 | (CurrentPci->dev << 3) | (CurrentPci->func & 0x7);
133 P_printf("ax: 0x%x\n",ax);
135 if (!error && (activePci || copy_vbios())) {
137 if (Config.SaveBios) save_bios_to_file();
139 printf("initializing ISA\n");
146 /* disable primary card */
147 save_msr = inb(0x3CC);
148 save_vse = inb(0x3C3);
149 save_46e8 = inb(0x46e8);
150 save_pos102 = inb(0x102);
152 signal(2,sig_handler);
153 signal(11,sig_handler);
155 outb(0x3C2,~(CARD8)0x03 & save_msr);
156 outb(0x3C3,~(CARD8)0x01 & save_vse);
157 outb(0x46e8, ~(CARD8)0x08 & save_46e8);
158 outb(0x102, ~(CARD8)0x01 & save_pos102);
165 if (CurrentPci->active) {
167 if (!Config.ConfigActiveDevice) {
168 CurrentPci = CurrentPci->next;
175 if (CurrentPci->active) {
176 outb(0x102, save_pos102);
177 outb(0x46e8, save_46e8);
178 outb(0x3C3, save_vse);
179 outb(0x3C2, save_msr);
182 /* clear interrupt vectors */
185 ax = ((CARD16)(CurrentPci->bus) << 8)
186 | (CurrentPci->dev << 3) | (CurrentPci->func & 0x7);
187 P_printf("ax: 0x%x\n",ax);
189 if (!((mapPciRom(NULL) && chksum((CARD8*)V_BIOS))
190 || (CurrentPci->active && copy_vbios()))) {
191 CurrentPci = CurrentPci->next;
195 CurrentPci = CurrentPci->next;
198 if (Config.SaveBios) save_bios_to_file();
199 printf("initializing PCI bus: %i dev: %i func: %i\n",CurrentPci->bus,
200 CurrentPci->dev,CurrentPci->func);
204 CurrentPci = CurrentPci->next;
207 /* We have an ISA device - configure if requested */
208 if (!Active_is_Pci && Config.ConfigActiveDevice) {
211 outb(0x102, save_pos102);
212 outb(0x46e8, save_46e8);
213 outb(0x3C3, save_vse);
214 outb(0x3C2, save_msr);
219 if (Config.SaveBios) save_bios_to_file();
221 printf("initializing ISA\n");
232 outb(0x102, save_pos102);
233 outb(0x46e8, save_46e8);
234 outb(0x3C3, save_vse);
235 outb(0x3C2, save_msr);
238 close_console(Console);
245 if (Config.IoStatistics)
257 mem = mmap(0, (size_t)SIZE,
258 PROT_EXEC | PROT_READ | PROT_WRITE,
259 MAP_FIXED | MAP_PRIVATE | MAP_ANON,
262 perror("anonymous map");
267 loadCodeToMem((unsigned char *) BIOS_START, code);
282 printf("starting BIOS\n");
284 setup_bios_regs(&bRegs, ax);
285 do_x86(BIOS_START,&bRegs);
297 if ((mem_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0)
299 if ((mem_fd = open(MEM_FILE,O_RDWR))<0)
302 perror("opening memory");
307 if (mmap((void *) VRAM_START, (size_t) VRAM_SIZE,
308 PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
309 mem_fd, VRAM_START) == (void *) -1)
311 if (!_bus_base()) sparse_shift = 7; /* Uh, oh, JENSEN... */
312 if (!_bus_base_sparse()) sparse_shift = 0;
313 if ((vram_map = mmap(0,(size_t) (VRAM_SIZE << sparse_shift),
314 PROT_READ | PROT_WRITE,
316 mem_fd, (VRAM_START << sparse_shift)
317 | _bus_base_sparse())) == (void *) -1)
320 perror("mmap error in map_hardware_ram");
332 if (!vram_mapped) return;
334 munmap((void*)VRAM_START,VRAM_SIZE);
345 if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
346 perror("opening memory");
350 if (lseek(mem_fd,(off_t) V_BIOS, SEEK_SET) != (off_t) V_BIOS) {
351 fprintf(stderr,"Cannot lseek\n");
354 tmp = (unsigned char *)malloc(3);
355 if (read(mem_fd, (char *)tmp, (size_t) 3) != (size_t) 3) {
356 fprintf(stderr,"Cannot read\n");
359 if (lseek(mem_fd,(off_t) V_BIOS,SEEK_SET) != (off_t) V_BIOS)
362 if (*tmp != 0x55 || *(tmp+1) != 0xAA ) {
364 dprint((unsigned long)tmp,0x100);
366 fprintf(stderr,"No bios found at: 0x%x\n",V_BIOS);
369 size = *(tmp+2) * 512;
371 if (read(mem_fd, (char *)V_BIOS, (size_t) size) != (size_t) size) {
372 fprintf(stderr,"Cannot read\n");
377 if (!chksum((CARD8)V_BIOS))
391 #define SYS_BIOS 0xF0000
394 if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
395 perror("opening memory");
399 if (lseek(mem_fd,(off_t) SYS_BIOS,SEEK_SET) != (off_t) SYS_BIOS)
401 if (read(mem_fd, (char *)SYS_BIOS, (size_t) 0xFFFF) != (size_t) 0xFFFF)
414 loadCodeToMem(unsigned char *ptr, CARD8 code[])
422 if (val == 0xf4) break;
428 dprint(unsigned long start, unsigned long size)
431 char *c = (char *)start;
433 for (j = 0; j < (size >> 4); j++) {
435 printf("\n0x%lx: ",(unsigned long)c);
436 for (i = 0; i<16; i++)
437 printf("%2.2x ",(unsigned char) (*(c++)));
439 for (i = 0; i<16; i++) {
440 printf("%c",((((CARD8)(*c)) > 32) && (((CARD8)(*c)) < 128)) ?
441 (unsigned char) (*(c)): '.');
449 save_bios_to_file(void)
456 sprintf(file_name,"bios_%i.fil",num);
457 if ((fd = open(file_name,O_WRONLY | O_CREAT | O_TRUNC,00644)) == -1)
459 size = (*(unsigned char*)(V_BIOS + 2)) * 512;
463 if ((count = write(fd,(void *)(V_BIOS),size)) != size)
464 fprintf(stderr,"only saved %i of %i bytes\n",size,count);
469 sig_handler(int unused)
474 /* put system back in a save state */
477 outb(0x102, save_pos102);
478 outb(0x46e8, save_46e8);
479 outb(0x3C3, save_vse);
480 outb(0x3C2, save_msr);
482 close_console(Console);
490 * For initialization we just pass ax to the BIOS.
491 * PCI BIOSes need this. All other register are set 0.
493 static void setup_bios_regs(i86biosRegsPtr regs, CARD32 ax)
504 * here we are really paranoid about faking a "real"
505 * BIOS. Most of this information was pulled from
511 const CARD16 cs = 0x0000;
512 const CARD16 ip = 0x0;
515 /* let the int vects point to the SYS_BIOS seg */
516 for (i=0; i<0x80; i++) {
517 ((CARD16*)0)[i<<1] = ip;
518 ((CARD16*)0)[(i<<1)+1] = cs;
520 /* video interrupts default location */
521 ((CARD16*)0)[(0x42<<1)+1] = 0xf000;
522 ((CARD16*)0)[0x42<<1] = 0xf065;
523 ((CARD16*)0)[(0x10<<1)+1] = 0xf000;
524 ((CARD16*)0)[0x10<<1] = 0xf065;
525 /* video param table default location (int 1d) */
526 ((CARD16*)0)[(0x1d<<1)+1] = 0xf000;
527 ((CARD16*)0)[0x1d<<1] = 0xf0A4;
528 /* font tables default location (int 1F) */
529 ((CARD16*)0)[(0x1f<<1)+1] = 0xf000;
530 ((CARD16*)0)[0x1f<<1] = 0xfa6e;
532 /* int 11 default location */
533 ((CARD16*)0)[(0x11<1)+1] = 0xf000;
534 ((CARD16*)0)[0x11<<1] = 0xf84d;
535 /* int 12 default location */
536 ((CARD16*)0)[(0x12<<1)+1] = 0xf000;
537 ((CARD16*)0)[0x12<<1] = 0xf841;
538 /* int 15 default location */
539 ((CARD16*)0)[(0x15<<1)+1] = 0xf000;
540 ((CARD16*)0)[0x15<<1] = 0xf859;
541 /* int 1A default location */
542 ((CARD16*)0)[(0x1a<<1)+1] = 0xf000;
543 ((CARD16*)0)[0x1a<<1] = 0xff6e;
544 /* int 05 default location */
545 ((CARD16*)0)[(0x05<<1)+1] = 0xf000;
546 ((CARD16*)0)[0x05<<1] = 0xff54;
547 /* int 08 default location */
548 ((CARD16*)0)[(0x8<<1)+1] = 0xf000;
549 ((CARD16*)0)[0x8<<1] = 0xfea5;
550 /* int 13 default location (fdd) */
551 ((CARD16*)0)[(0x13<<1)+1] = 0xf000;
552 ((CARD16*)0)[0x13<<1] = 0xec59;
553 /* int 0E default location */
554 ((CARD16*)0)[(0xe<<1)+1] = 0xf000;
555 ((CARD16*)0)[0xe<<1] = 0xef57;
556 /* int 17 default location */
557 ((CARD16*)0)[(0x17<<1)+1] = 0xf000;
558 ((CARD16*)0)[0x17<<1] = 0xefd2;
559 /* fdd table default location (int 1e) */
560 ((CARD16*)0)[(0x1e<<1)+1] = 0xf000;
561 ((CARD16*)0)[0x1e<<1] = 0xefc7;
565 setup_system_bios(void)
567 char *date = "06/01/99";
568 char *eisa_ident = "PCI/ISA";
571 if (!copy_sys_bios()) return 0;
574 /* memset((void *)0xF0000,0xf4,0xfff7); */
577 * we trap the "industry standard entry points" to the BIOS
578 * and all other locations by filling them with "hlt"
579 * TODO: implement hlt-handler for these
581 memset((void *)0xF0000,0xf4,0x10000);
584 * TODO: we should copy the fdd table (0xfec59-0xfec5b)
585 * the video parameter table (0xf0ac-0xf0fb)
586 * and the font tables (0xfa6e-0xfe6d)
587 * from the original bios here
591 strcpy((char *)0xFFFF5,date);
592 /* set up eisa ident string */
593 strcpy((char *)0xFFFD9,eisa_ident);
594 /* write system model id for IBM-AT */
595 ((char *)0)[0xFFFFE] = 0xfc;
607 size = *(start+2) * 512;
608 for (i = 0; i<size; i++)
614 fprintf(stderr,"BIOS cksum wrong!\n");