]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/MAI/bios_emulator/scitech/src/v86bios/v86bios.c
* Patch by Thomas Frieden, 13 Nov 2002:
[karo-tx-uboot.git] / board / MAI / bios_emulator / scitech / src / v86bios / v86bios.c
1 /*
2  * Copyright 1999 Egbert Eich
3  *
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.
13  *
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.
21  */
22 #define DELETE
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <stdio.h>
26 #include <sys/mman.h>
27 #include <sys/types.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <signal.h>
31 #include <sys/stat.h>
32 #include <readline/readline.h>
33 #include <readline/history.h>
34 #if defined(__alpha__) || defined (__ia64__)
35 #include <sys/io.h>
36 #elif defined(HAVE_SYS_PERM)
37 #include <sys/perm.h>
38 #endif
39 #include "debug.h"
40 #include "v86bios.h"
41 #include "pci.h"
42 #include "AsmMacros.h"
43
44 #define SIZE 0x100000
45 #define VRAM_START 0xA0000
46 #define VRAM_SIZE 0x1FFFF
47 #define V_BIOS_SIZE 0x1FFFF
48 #define BIOS_START 0x7C00            /* default BIOS entry */
49 #define BIOS_MEM 0x600
50
51 //CARD8 code[] = { 0xb8 , 0xf0 , 0xf0, 0xf4 };
52 #define VB_X(x) (V_BIOS >> x) & 0xFF
53 CARD8 code[] = { 6, 0x9a, 0x03, 0x00, 0x00, VB_X(12), 0xf4 };
54 //CARD8 code[] = { 0x9a, 0x03, 0x00, 0x00, VB_X(12), 0xb8, 0x03, 0x00,
55 //0xcd, 0x10, 0xf4 };
56 //CARD8 code[] = {  0xb8 , 0xf0 , 0xf0 ,0xf4 };
57
58 int ioperm_list[IOPERM_BITS] = {0,};
59
60 static void sig_handler(int);
61 static int map(void);
62 static void unmap(void);
63 static void bootBIOS(CARD16 ax);
64 static int map_vram(void);
65 static void unmap_vram(void);
66 static int copy_vbios(memType v_base);
67 static int copy_sys_bios(void);
68 static void save_bios_to_file(void);
69 static int setup_system_bios(void);
70 static CARD32 setup_int_vect(void);
71 #ifdef __ia32__
72 static CARD32 setup_primary_int_vect(void);
73 #endif
74 static int chksum(CARD8 *start);
75 static void setup_bios_regs(i86biosRegsPtr regs, CARD32 ax);
76 static void print_regs(i86biosRegsPtr regs);
77 static void print_usage(void);
78 static void set_hlt(Bool set);
79 static void set_ioperm(void);
80
81 extern void yyparse();
82
83 void loadCodeToMem(unsigned char *ptr, CARD8 *code);
84 void dprint(unsigned long start, unsigned long size);
85
86 static int vram_mapped = 0;
87 static char* bios_var = NULL;
88 static CARD8 save_msr;
89 static CARD8 save_pos102;
90 static CARD8 save_vse;
91 static CARD8 save_46e8;
92 static haltpoints hltp[20] = { {0, 0}, };
93
94 console Console = {-1,-1};
95 struct config Config;
96
97 int main(int argc,char **argv)
98 {
99     int c;
100     
101     Config.PrintPort = PRINT_PORT;
102     Config.IoStatistics = IO_STATISTICS;
103     Config.PrintIrq = PRINT_IRQ;
104     Config.PrintPci = PRINT_PCI;
105     Config.ShowAllDev = SHOW_ALL_DEV;        
106     Config.PrintIp = PRINT_IP;           
107     Config.SaveBios = SAVE_BIOS;          
108     Config.Trace = TRACE;             
109     Config.ConfigActiveOnly = CONFIG_ACTIVE_ONLY;  /* boot */
110     Config.ConfigActiveDevice = CONFIG_ACTIVE_DEVICE; /* boot */
111     Config.MapSysBios = MAP_SYS_BIOS;        
112     Config.Resort = RESORT;  /* boot */          
113     Config.FixRom = FIX_ROM;            
114     Config.NoConsole = NO_CONSOLE;
115     Config.BootOnly = FALSE;
116     Config.Verbose = VERBOSE;
117     
118     opterr = 0;    
119     while ((c = getopt(argc,argv,"psicaPStAdbrfnv:?")) != EOF) {
120     switch(c) {
121     case 'p':
122         Config.PrintPort = TRUE;
123         break;
124     case 's':
125         Config.IoStatistics = TRUE;
126         break;
127     case 'i':
128         Config.PrintIrq = TRUE;
129         break;
130     case 'c':
131         Config.PrintPci = TRUE;
132         break;
133     case 'a':
134         Config.ShowAllDev = TRUE;
135         break;
136     case 'P':
137         Config.PrintIp = TRUE;
138         break;
139     case 'S':
140         Config.SaveBios = TRUE;
141         break;
142     case 't':
143         Config.Trace = TRUE;
144         break;
145     case 'A':
146         Config.ConfigActiveOnly = TRUE;
147         break;
148     case 'd':
149         Config.ConfigActiveDevice = TRUE;
150         break;
151     case 'b':
152         Config.MapSysBios = TRUE;
153         break;
154     case 'r':
155         Config.Resort = TRUE;
156         break;
157     case 'f':
158         Config.FixRom = TRUE;
159         break;
160     case 'n':
161         Config.NoConsole = TRUE;
162         break;
163     case 'v':
164         Config.Verbose = strtol(optarg,NULL,0);
165         break;
166     case '?':
167         print_usage();
168         break;
169     default:
170         break;
171     }
172     }
173     
174     
175     if (!map())
176     exit(1);
177     
178     if (!setup_system_bios())
179     exit(1);
180     
181     iopl(3);
182
183     scan_pci();
184
185     save_msr = inb(0x3CC);
186     save_vse = inb(0x3C3);
187     save_46e8 = inb(0x46e8);
188     save_pos102 = inb(0x102);
189
190     if (Config.BootOnly) {
191     
192     if (!CurrentPci && !Config.ConfigActiveDevice
193         && !Config.ConfigActiveOnly) {
194         iopl(0);
195         unmap();
196         exit (1);
197     }
198     call_boot(NULL);
199     } else {
200     using_history();
201     yyparse();
202     }
203     
204     unmap();
205
206     pciVideoRestore();
207     
208     outb(0x102, save_pos102);
209     outb(0x46e8, save_46e8);
210     outb(0x3C3, save_vse);
211     outb(0x3C2, save_msr);
212
213     iopl(0);
214
215     close_console(Console);
216
217     exit(0);
218 }
219
220
221 void
222 call_boot(struct device *dev)
223 {
224     int Active_is_Pci = 0;
225     CARD32 vbios_base;
226     
227     CurrentPci = PciList;
228     Console = open_console();
229     
230     set_ioperm();
231
232     
233     signal(2,sig_handler);
234     signal(11,sig_handler);
235     
236     /* disable primary card */
237     pciVideoRestore(); /* reset PCI state to see primary card */
238     outb(0x3C2,~(CARD8)0x03 & save_msr);
239     outb(0x3C3,~(CARD8)0x01 & save_vse);
240     outb(0x46e8, ~(CARD8)0x08 & save_46e8);
241     outb(0x102, ~(CARD8)0x01 & save_pos102);
242     
243     pciVideoDisable();
244     
245     while (CurrentPci) {
246     CARD16 ax;
247     
248     if (CurrentPci->active) {
249         Active_is_Pci = 1;
250         if (!Config.ConfigActiveDevice && !dev) {
251         CurrentPci = CurrentPci->next;
252         continue;
253         }
254     } else if (Config.ConfigActiveOnly && !dev) {
255         CurrentPci = CurrentPci->next;
256         continue;
257     }
258     if (dev && ((dev->type != PCI)
259             || (dev->type == PCI
260             && (dev->loc.pci.dev != CurrentPci->dev
261                 || dev->loc.pci.bus != CurrentPci->bus
262                 || dev->loc.pci.func != CurrentPci->func)))) {
263         CurrentPci = CurrentPci->next;
264         continue;
265     }
266     
267     EnableCurrent();
268     
269     if (CurrentPci->active) {
270         outb(0x102, save_pos102);
271         outb(0x46e8, save_46e8);
272         outb(0x3C3, save_vse);
273         outb(0x3C2, save_msr);
274     }
275     
276     /* clear interrupt vectors */
277 #ifdef __ia32__
278     vbios_base = CurrentPci->active ? setup_primary_int_vect()
279         : setup_int_vect();
280 #else
281     vbios_base = setup_int_vect();
282 #endif
283     ax = ((CARD16)(CurrentPci->bus) << 8)
284         | (CurrentPci->dev << 3) | (CurrentPci->func & 0x7);
285     if (Config.Verbose > 1) P_printf("ax: 0x%x\n",ax);
286     
287     BootBios = findPciByIDs(CurrentPci->bus,CurrentPci->dev,
288                    CurrentPci->func);
289     if (!((mapPciRom(BootBios) && chksum((CARD8*)V_BIOS))
290           || (CurrentPci->active && copy_vbios(vbios_base)))) {
291         CurrentPci = CurrentPci->next;
292         continue;
293     }
294     if (!map_vram()) {
295         CurrentPci = CurrentPci->next;
296         continue;
297     }
298     if (Config.SaveBios) save_bios_to_file();
299     printf("initializing PCI bus: %i dev: %i func: %i\n",CurrentPci->bus,
300            CurrentPci->dev,CurrentPci->func);
301     bootBIOS(ax);
302     unmap_vram();
303
304     if (CurrentPci->active)
305         close_console(Console);
306
307     if (dev) return;
308     
309     CurrentPci = CurrentPci->next;
310     }
311     
312     /* We have an ISA device - configure if requested */
313     if (!Active_is_Pci /* no isa card in system! */
314     && ((!dev && (Config.ConfigActiveDevice || Config.ConfigActiveOnly))
315         || (dev && dev->type == ISA))) {
316
317     pciVideoDisable();
318
319     if (!dev || dev->type == ISA) {
320         outb(0x102, save_pos102);
321         outb(0x46e8, save_46e8);
322         outb(0x3C3, save_vse);
323         outb(0x3C2, save_msr);
324         
325 #ifdef __ia32__
326         vbios_base = setup_primary_int_vect();
327 #else
328         vbios_base = setup_int_vect();
329 #endif
330         if (copy_vbios(vbios_base)) {
331         
332         if (Config.SaveBios) save_bios_to_file();
333         if  (map_vram()) {
334             printf("initializing ISA bus\n");
335             bootBIOS(0);
336         }
337         }
338     
339         unmap_vram();
340         sleep(1);
341         close_console(Console);
342     }
343     }
344     
345     
346 }
347
348 int  
349 map(void)
350 {
351     void* mem;
352     mem = mmap(0, (size_t)SIZE,
353                PROT_EXEC | PROT_READ | PROT_WRITE,
354                MAP_FIXED | MAP_PRIVATE | MAP_ANON,
355                -1, 0 ); 
356     if (mem != 0) {
357         perror("anonymous map");
358         return (0);
359     }
360     memset(mem,0,SIZE);
361
362     return (1);
363 }
364
365 static void
366 unmap(void)
367 {
368     munmap(0,SIZE);
369 }
370
371 static void
372 bootBIOS(CARD16 ax)
373 {
374     i86biosRegs bRegs;
375 #ifdef V86BIOS_DEBUG
376     printf("starting BIOS\n");
377 #endif
378     setup_io();
379     setup_bios_regs(&bRegs, ax);
380     loadCodeToMem((unsigned char *) BIOS_START, code);
381     do_x86(BIOS_START,&bRegs);
382 #ifdef V86BIOS_DEBUG
383     printf("done\n");
384 #endif
385 }
386
387 static int
388 map_vram(void)
389 {
390     int mem_fd;
391
392 #ifdef __ia64__
393     if ((mem_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0) 
394 #else
395     if ((mem_fd = open(MEM_FILE,O_RDWR))<0) 
396 #endif
397         {
398         perror("opening memory");
399         return 0;
400     }
401
402 #ifdef __alpha__
403        if (!_bus_base()) sparse_shift = 7; /* Uh, oh, JENSEN... */
404          if (!_bus_base_sparse()) sparse_shift = 0;
405          if ((vram_map = mmap(0,(size_t) (VRAM_SIZE << sparse_shift),
406                                                  PROT_READ | PROT_WRITE,
407                                                  MAP_SHARED,
408                                                  mem_fd, (VRAM_START << sparse_shift)
409                                                  | _bus_base_sparse())) == (void *) -1)
410 #else
411       if (mmap((void *) VRAM_START, (size_t) VRAM_SIZE,
412                          PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
413                          mem_fd, VRAM_START) == (void *) -1) 
414 #endif
415       {
416         perror("mmap error in map_hardware_ram (1)");
417             close(mem_fd);
418             return (0);
419         }
420     vram_mapped = 1;
421     close(mem_fd);
422     return (1);
423 }
424
425 static void
426 unmap_vram(void)
427 {
428     if (!vram_mapped) return;
429     
430     munmap((void*)VRAM_START,VRAM_SIZE);
431     vram_mapped = 0;
432 }
433
434 static int
435 copy_vbios(memType v_base)
436 {
437     int mem_fd;
438     unsigned char *tmp;
439     int size;
440
441     if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
442         perror("opening memory");
443         return (0);
444     }
445
446     if (lseek(mem_fd,(off_t) v_base, SEEK_SET) != (off_t) v_base) { 
447           fprintf(stderr,"Cannot lseek\n");
448           goto Error;
449       }
450     tmp = (unsigned char *)malloc(3);
451     if (read(mem_fd, (char *)tmp, (size_t) 3) != (size_t) 3) {
452             fprintf(stderr,"Cannot read\n");
453         goto Error;
454     }
455     if (lseek(mem_fd,(off_t) v_base,SEEK_SET) != (off_t) v_base) 
456         goto Error;
457
458     if (*tmp != 0x55 || *(tmp+1) != 0xAA ) {
459         fprintf(stderr,"No bios found at: 0x%lx\n",v_base);
460         goto Error;
461     }
462 #ifdef DEBUG
463         dprint((unsigned long)tmp,0x100);
464 #endif
465     size = *(tmp+2) * 512;
466
467     if (read(mem_fd, (char *)v_base, (size_t) size) != (size_t) size) {
468             fprintf(stderr,"Cannot read\n");
469         goto Error;
470     }
471     free(tmp);
472     close(mem_fd);
473     if (!chksum((CARD8*)v_base))
474         return (0);
475
476     return (1);
477
478 Error:
479     perror("v_bios");
480     close(mem_fd);
481     return (0);
482 }
483
484 static int
485 copy_sys_bios(void)
486 {
487 #define SYS_BIOS 0xF0000
488     int mem_fd;
489
490     if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
491         perror("opening memory");
492         return (0);
493     }
494   
495     if (lseek(mem_fd,(off_t) SYS_BIOS,SEEK_SET) != (off_t) SYS_BIOS) 
496         goto Error;
497     if (read(mem_fd, (char *)SYS_BIOS, (size_t) 0xFFFF) != (size_t) 0xFFFF) 
498         goto Error;
499
500     close(mem_fd);
501     return (1);
502
503 Error:
504     perror("sys_bios");
505     close(mem_fd);
506     return (0);
507 }
508
509 void
510 loadCodeToMem(unsigned char *ptr, CARD8 code[])
511 {
512     int i;
513     CARD8 val;
514     int size = code[0];
515     
516     for ( i=1;i<=size;i++) {
517         val = code[i];
518         *ptr++ = val;
519     }
520     return;
521 }
522         
523 void 
524 dprint(unsigned long start, unsigned long size)
525 {
526     int i,j;
527     char *c = (char *)start;
528
529     for (j = 0; j < (size >> 4); j++) {
530     char *d = c;
531     printf("\n0x%lx:  ",(unsigned long)c);
532     for (i = 0; i<16; i++) 
533         printf("%2.2x ",(unsigned char) (*(c++)));
534     c = d;
535     for (i = 0; i<16; i++) {
536         printf("%c",((((CARD8)(*c)) > 32) && (((CARD8)(*c)) < 128)) ?
537            (unsigned char) (*(c)): '.');
538         c++;
539     }
540     }
541     printf("\n");
542 }
543
544 static void
545 save_bios_to_file(void)
546 {
547     static int num = 0;
548     int size, count;
549     char file_name[256];
550     int fd;
551     
552     sprintf(file_name,"bios_%i.fil",num);
553     if ((fd =  open(file_name,O_WRONLY | O_CREAT | O_TRUNC,00644)) == -1)
554         return;
555     size = (*(unsigned char*)(V_BIOS + 2)) * 512;
556 #ifdef V86BIOS_DEBUG
557     dprint(V_BIOS,20);
558 #endif
559     if ((count = write(fd,(void *)(V_BIOS),size)) != size)
560         fprintf(stderr,"only saved %i of %i bytes\n",size,count);
561     num++;
562 }
563
564 static void
565 sig_handler(int unused)
566 {
567     fflush(stdout);
568     fflush(stderr);
569
570     /* put system back in a save state */
571     unmap_vram();
572     pciVideoRestore();
573     outb(0x102, save_pos102);
574     outb(0x46e8, save_46e8);
575     outb(0x3C3, save_vse);
576     outb(0x3C2, save_msr);
577
578     close_console(Console);
579     iopl(0);
580     unmap();
581
582     exit(1);
583 }
584
585 /*
586  * For initialization we just pass ax to the BIOS.
587  * PCI BIOSes need this. All other register are set 0.
588  */
589 static void setup_bios_regs(i86biosRegsPtr regs, CARD32 ax)
590 {
591     regs->ax = ax;
592     regs->bx = 0;
593     regs->cx = 0;
594     regs->dx = 0;
595     regs->es = 0;
596     regs->ds = 0x40;               /* standard pc ds */
597     regs->si = 0;
598     regs->di = 0;
599 }
600
601 /*
602  * here we are really paranoid about faking a "real"
603  * BIOS. Most of this information was pulled from
604  * dosem.
605  */
606
607 #ifdef __ia32__
608 static CARD32
609 setup_primary_int_vect(void)
610 {
611     int mem_fd;
612     CARD32 vbase;
613     void *map;
614
615     if ((mem_fd = open(MEM_FILE,O_RDWR))<0) 
616             {
617     perror("opening memory");
618     return (0);
619     }
620   
621     if ((map = mmap((void *) 0, (size_t) 0x2000,
622          PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
623          mem_fd, 0)) == (void *)-1)   {
624     perror("mmap error in map_hardware_ram (2)");
625     close(mem_fd);
626     return (0);
627     }
628
629     close(mem_fd);
630     memcpy(0,map,BIOS_MEM);
631     munmap(map,0x2000);
632     /*
633      * create a backup copy of the bios variables to write back the
634      * modified values
635      */
636     if (!bios_var)
637     bios_var = (char *)malloc(BIOS_MEM);
638     memcpy(bios_var,0,BIOS_MEM);
639     
640     vbase = (*((CARD16*)(0x10 << 2) + 1)) << 4;
641     if (Config.Verbose > 0) printf("vbase: 0x%x\n",vbase);
642     return vbase;
643 }
644 #endif
645
646 static CARD32
647 setup_int_vect(void)
648 {
649     const CARD16 cs = 0x0;
650     const CARD16 ip = 0x0;
651     int i;
652     
653     /* let the int vects point to the SYS_BIOS seg */
654     for (i=0; i<0x80; i++) {
655         ((CARD16*)0)[i<<1] = ip;
656         ((CARD16*)0)[(i<<1)+1] = cs;
657     }
658     /* video interrupts default location */
659     ((CARD16*)0)[(0x42<<1)+1] = 0xf000;
660     ((CARD16*)0)[0x42<<1] = 0xf065;
661     ((CARD16*)0)[(0x10<<1)+1] = 0xf000;
662     ((CARD16*)0)[0x10<<1] = 0xf065;
663     /* video param table default location (int 1d) */
664     ((CARD16*)0)[(0x1d<<1)+1] = 0xf000;
665     ((CARD16*)0)[0x1d<<1] = 0xf0A4;
666     /* font tables default location (int 1F) */
667     ((CARD16*)0)[(0x1f<<1)+1] = 0xf000;
668     ((CARD16*)0)[0x1f<<1] = 0xfa6e;
669
670     /* int 11 default location */
671     ((CARD16*)0)[(0x11<<1)+1] = 0xf000;
672     ((CARD16*)0)[0x11<<1] = 0xf84d;
673     /* int 12 default location */
674     ((CARD16*)0)[(0x12<<1)+1] = 0xf000;
675     ((CARD16*)0)[0x12<<1] = 0xf841;
676     /* int 15 default location */
677     ((CARD16*)0)[(0x15<<1)+1] = 0xf000;
678     ((CARD16*)0)[0x15<<1] = 0xf859;
679     /* int 1A default location */
680     ((CARD16*)0)[(0x1a<<1)+1] = 0xf000;
681     ((CARD16*)0)[0x1a<<1] = 0xff6e;
682     /* int 05 default location */
683     ((CARD16*)0)[(0x05<<1)+1] = 0xf000;
684     ((CARD16*)0)[0x05<<1] = 0xff54;
685     /* int 08 default location */
686     ((CARD16*)0)[(0x8<<1)+1] = 0xf000;
687     ((CARD16*)0)[0x8<<1] = 0xfea5;
688     /* int 13 default location (fdd) */
689     ((CARD16*)0)[(0x13<<1)+1] = 0xf000;
690     ((CARD16*)0)[0x13<<1] = 0xec59;
691     /* int 0E default location */
692     ((CARD16*)0)[(0xe<<1)+1] = 0xf000;
693     ((CARD16*)0)[0xe<<1] = 0xef57;
694     /* int 17 default location */
695     ((CARD16*)0)[(0x17<<1)+1] = 0xf000;
696     ((CARD16*)0)[0x17<<1] = 0xefd2;
697     /* fdd table default location (int 1e) */
698     ((CARD16*)0)[(0x1e<<1)+1] = 0xf000;
699     ((CARD16*)0)[0x1e<<1] = 0xefc7;
700     return V_BIOS;
701 }
702
703 static int
704 setup_system_bios(void)
705 {
706     char *date = "06/01/99";
707     char *eisa_ident = "PCI/ISA";
708     
709     if (Config.MapSysBios) {
710
711         if (!copy_sys_bios()) return 0;
712         return 1;
713
714     } else {
715
716 //    memset((void *)0xF0000,0xf4,0xfff7);
717     
718         /*
719          * we trap the "industry standard entry points" to the BIOS
720          * and all other locations by filling them with "hlt"
721          * TODO: implement hlt-handler for these
722          */
723         memset((void *)0xF0000,0xf4,0x10000);
724         
725         /*
726          * TODO: we should copy the fdd table (0xfec59-0xfec5b)
727          * the video parameter table (0xf0ac-0xf0fb)
728          * and the font tables (0xfa6e-0xfe6d)
729          * from the original bios here
730          */
731     
732         /* set bios date */
733         strcpy((char *)0xFFFF5,date);
734         /* set up eisa ident string */
735         strcpy((char *)0xFFFD9,eisa_ident);
736         /* write system model id for IBM-AT */
737         ((char *)0)[0xFFFFE] = 0xfc;
738
739         return 1;
740     }
741     
742 }
743
744 static void
745 update_bios_vars(void)
746 {
747     int mem_fd;
748     void *map;
749     memType i;
750     
751 #ifdef __ia64__
752     if ((mem_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0) 
753 #else
754     if ((mem_fd = open(MEM_FILE,O_RDWR))<0) 
755 #endif
756             {
757     perror("opening memory");
758     return;
759     }
760   
761     if ((map = mmap((void *) 0, (size_t) 0x2000,
762          PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
763          mem_fd, 0)) == (void *)-1)   {
764     perror("mmap error in map_hardware_ram (3)");
765     close(mem_fd);
766     return;
767     }
768
769     for (i = 0; i < BIOS_MEM; i++) {
770     if (bios_var[i] != *(CARD8*)i) 
771         *((CARD8*)map + i) = *(CARD8*)i;
772     }
773
774     munmap(map,0x2000);
775     close(mem_fd);
776 }
777
778 static int
779 chksum(CARD8 *start)
780 {
781   CARD16 size;
782   CARD8 val = 0;
783   int i;
784
785   size = *(start+2) * 512;  
786   for (i = 0; i<size; i++)
787     val += *(start + i);
788     
789   if (!val)
790     return 1;
791
792     fprintf(stderr,"BIOS cksum wrong!\n");
793   return 0;
794 }
795
796 void
797 runINT(int num, i86biosRegsPtr Regs)
798 {
799     Bool isVideo = FALSE;
800     CARD8 code_int[] = { 3, 0xcd, 0x00, 0xf4 };
801
802     code_int[2] = (CARD8) num;
803     
804     if (num == 0x10)
805     isVideo = TRUE;
806     
807     if (!setup_system_bios())
808     return;
809
810     if ((isVideo && (!CurrentPci || CurrentPci->active)) || !isVideo) {
811     CARD32 vbios_base;
812
813 #ifdef __ia32__
814     if (!(vbios_base = setup_primary_int_vect()))
815 #else
816     if (!(vbios_base = setup_int_vect()))
817 #endif
818         return;
819     if (!copy_vbios(vbios_base))
820         return;
821     }
822     
823     if (!map_vram())
824     return;
825     
826 #ifdef V86BIOS_DEBUG
827         printf("starting BIOS\n");
828 #endif
829     loadCodeToMem((unsigned char *) BIOS_START, code_int);
830     setup_io();
831     print_regs(Regs);
832     set_ioperm();
833     set_hlt(TRUE);
834     do_x86(BIOS_START,Regs);
835     set_hlt(FALSE);
836     print_regs(Regs);
837     
838 #ifdef V86BIOS_DEBUG
839     printf("done\n");
840 #endif
841
842     if ((isVideo && (!CurrentPci || CurrentPci->active)) || !isVideo) 
843     update_bios_vars();
844 }
845
846 static void
847 print_regs(i86biosRegsPtr regs)
848 {
849     printf("ax=%x bx=%x cx=%x dx=%x ds=%x es=%x di=%x si=%x\n",
850        (CARD16)regs->ax,(CARD16)regs->bx,(CARD16)regs->cx,(CARD16)regs->dx,
851        (CARD16)regs->ds,(CARD16)regs->es,(CARD16)regs->di,
852        (CARD16)regs->si);
853 }
854
855 static void
856 print_usage(void)
857 {
858 }
859
860 void
861 add_hlt(unsigned long val)
862 {
863     int i;
864
865     if (val < BIOS_MEM || (val > VRAM_START && val < (VRAM_START + VRAM_SIZE))
866     || val >= SIZE) {
867     printf("address out of range\n");
868     return;
869     }
870     
871     for (i=0; i<20; i++) {
872     if (hltp[i].address == 0) {
873         hltp[i].address = (void*)val;
874         break;
875     }
876     }
877     if (i == 20) printf("no more hltpoints available\n");
878 }
879
880 void
881 del_hlt(int val)
882 {
883     if (val == 21) { /* delete all */
884     int i;
885     printf("clearing all hltpoints\n");
886     for (i=0; i <20; i++)
887         hltp[i].address = NULL;
888     } else if (val >= 0 &&  val <20)
889     hltp[val].address = NULL;
890     else printf("hltpoint %i out of range: valid range 0-19\n",val);
891 }
892
893 void
894 list_hlt()
895 {
896     int i;
897     for (i=0; i<20; i++) 
898     if (hltp[i].address)
899         printf("hltpoint[%i]: 0x%lx\n",i,(unsigned long)hltp[i].address);
900 }
901
902 static void
903 set_hlt(Bool set)
904 {
905     int i;
906     for (i=0; i<20; i++) 
907     if (hltp[i].address) {
908         if (set) {
909         hltp[i].orgval = *(CARD8*)hltp[i].address;
910         *(CARD8*)hltp[i].address = 0xf4;
911         } else 
912         *(CARD8*)hltp[i].address = hltp[i].orgval;
913     }
914 }
915
916 static void
917 set_ioperm(void)
918 {
919     int i, start;
920
921     ioperm(0,IOPERM_BITS,0);
922
923     for (i = 0; i < IOPERM_BITS;i++)
924     if (ioperm_list[i]) {
925         start = i;
926         for (;i < IOPERM_BITS; i++) {
927         if (!ioperm_list[i]) {
928             ioperm(start,i - start, 1);
929             break;
930         }
931         }
932     }
933 }