]> git.ipfire.org Git - u-boot.git/blame - board/MAI/bios_emulator/scitech/src/v86bios/v86bios.c
* Code cleanup:
[u-boot.git] / board / MAI / bios_emulator / scitech / src / v86bios / v86bios.c
CommitLineData
c7de829c
WD
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
8bde7f77 51/*CARD8 code[] = { 0xb8 , 0xf0 , 0xf0, 0xf4 }; */
c7de829c
WD
52#define VB_X(x) (V_BIOS >> x) & 0xFF
53CARD8 code[] = { 6, 0x9a, 0x03, 0x00, 0x00, VB_X(12), 0xf4 };
8bde7f77
WD
54/*CARD8 code[] = { 0x9a, 0x03, 0x00, 0x00, VB_X(12), 0xb8, 0x03, 0x00, */
55/*0xcd, 0x10, 0xf4 }; */
56/*CARD8 code[] = { 0xb8 , 0xf0 , 0xf0 ,0xf4 }; */
c7de829c
WD
57
58int ioperm_list[IOPERM_BITS] = {0,};
59
60static void sig_handler(int);
61static int map(void);
62static void unmap(void);
63static void bootBIOS(CARD16 ax);
64static int map_vram(void);
65static void unmap_vram(void);
66static int copy_vbios(memType v_base);
67static int copy_sys_bios(void);
68static void save_bios_to_file(void);
69static int setup_system_bios(void);
70static CARD32 setup_int_vect(void);
71#ifdef __ia32__
72static CARD32 setup_primary_int_vect(void);
73#endif
74static int chksum(CARD8 *start);
75static void setup_bios_regs(i86biosRegsPtr regs, CARD32 ax);
76static void print_regs(i86biosRegsPtr regs);
77static void print_usage(void);
78static void set_hlt(Bool set);
79static void set_ioperm(void);
80
81extern void yyparse();
82
83void loadCodeToMem(unsigned char *ptr, CARD8 *code);
84void dprint(unsigned long start, unsigned long size);
85
86static int vram_mapped = 0;
87static char* bios_var = NULL;
88static CARD8 save_msr;
89static CARD8 save_pos102;
90static CARD8 save_vse;
91static CARD8 save_46e8;
92static haltpoints hltp[20] = { {0, 0}, };
93
94console Console = {-1,-1};
95struct config Config;
96
97int main(int argc,char **argv)
98{
99 int c;
8bde7f77 100
c7de829c
WD
101 Config.PrintPort = PRINT_PORT;
102 Config.IoStatistics = IO_STATISTICS;
103 Config.PrintIrq = PRINT_IRQ;
104 Config.PrintPci = PRINT_PCI;
8bde7f77
WD
105 Config.ShowAllDev = SHOW_ALL_DEV;
106 Config.PrintIp = PRINT_IP;
107 Config.SaveBios = SAVE_BIOS;
108 Config.Trace = TRACE;
c7de829c
WD
109 Config.ConfigActiveOnly = CONFIG_ACTIVE_ONLY; /* boot */
110 Config.ConfigActiveDevice = CONFIG_ACTIVE_DEVICE; /* boot */
8bde7f77
WD
111 Config.MapSysBios = MAP_SYS_BIOS;
112 Config.Resort = RESORT; /* boot */
113 Config.FixRom = FIX_ROM;
c7de829c
WD
114 Config.NoConsole = NO_CONSOLE;
115 Config.BootOnly = FALSE;
116 Config.Verbose = VERBOSE;
8bde7f77
WD
117
118 opterr = 0;
c7de829c
WD
119 while ((c = getopt(argc,argv,"psicaPStAdbrfnv:?")) != EOF) {
120 switch(c) {
121 case 'p':
8bde7f77
WD
122 Config.PrintPort = TRUE;
123 break;
c7de829c 124 case 's':
8bde7f77
WD
125 Config.IoStatistics = TRUE;
126 break;
c7de829c 127 case 'i':
8bde7f77
WD
128 Config.PrintIrq = TRUE;
129 break;
c7de829c 130 case 'c':
8bde7f77
WD
131 Config.PrintPci = TRUE;
132 break;
c7de829c 133 case 'a':
8bde7f77
WD
134 Config.ShowAllDev = TRUE;
135 break;
c7de829c 136 case 'P':
8bde7f77
WD
137 Config.PrintIp = TRUE;
138 break;
c7de829c 139 case 'S':
8bde7f77
WD
140 Config.SaveBios = TRUE;
141 break;
c7de829c 142 case 't':
8bde7f77
WD
143 Config.Trace = TRUE;
144 break;
c7de829c 145 case 'A':
8bde7f77
WD
146 Config.ConfigActiveOnly = TRUE;
147 break;
c7de829c 148 case 'd':
8bde7f77
WD
149 Config.ConfigActiveDevice = TRUE;
150 break;
c7de829c 151 case 'b':
8bde7f77
WD
152 Config.MapSysBios = TRUE;
153 break;
c7de829c 154 case 'r':
8bde7f77
WD
155 Config.Resort = TRUE;
156 break;
c7de829c 157 case 'f':
8bde7f77
WD
158 Config.FixRom = TRUE;
159 break;
c7de829c 160 case 'n':
8bde7f77
WD
161 Config.NoConsole = TRUE;
162 break;
c7de829c 163 case 'v':
8bde7f77
WD
164 Config.Verbose = strtol(optarg,NULL,0);
165 break;
c7de829c 166 case '?':
8bde7f77
WD
167 print_usage();
168 break;
c7de829c 169 default:
8bde7f77 170 break;
c7de829c
WD
171 }
172 }
8bde7f77
WD
173
174
c7de829c
WD
175 if (!map())
176 exit(1);
8bde7f77 177
c7de829c
WD
178 if (!setup_system_bios())
179 exit(1);
8bde7f77 180
c7de829c
WD
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) {
8bde7f77 191
c7de829c 192 if (!CurrentPci && !Config.ConfigActiveDevice
8bde7f77
WD
193 && !Config.ConfigActiveOnly) {
194 iopl(0);
195 unmap();
196 exit (1);
c7de829c
WD
197 }
198 call_boot(NULL);
199 } else {
200 using_history();
201 yyparse();
202 }
8bde7f77 203
c7de829c
WD
204 unmap();
205
206 pciVideoRestore();
8bde7f77 207
c7de829c
WD
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
221void
222call_boot(struct device *dev)
223{
224 int Active_is_Pci = 0;
225 CARD32 vbios_base;
8bde7f77 226
c7de829c
WD
227 CurrentPci = PciList;
228 Console = open_console();
8bde7f77 229
c7de829c
WD
230 set_ioperm();
231
8bde7f77 232
c7de829c
WD
233 signal(2,sig_handler);
234 signal(11,sig_handler);
8bde7f77 235
c7de829c
WD
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);
8bde7f77 242
c7de829c 243 pciVideoDisable();
8bde7f77 244
c7de829c
WD
245 while (CurrentPci) {
246 CARD16 ax;
8bde7f77 247
c7de829c 248 if (CurrentPci->active) {
8bde7f77
WD
249 Active_is_Pci = 1;
250 if (!Config.ConfigActiveDevice && !dev) {
251 CurrentPci = CurrentPci->next;
252 continue;
253 }
c7de829c 254 } else if (Config.ConfigActiveOnly && !dev) {
8bde7f77
WD
255 CurrentPci = CurrentPci->next;
256 continue;
c7de829c
WD
257 }
258 if (dev && ((dev->type != PCI)
8bde7f77
WD
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
c7de829c 267 EnableCurrent();
8bde7f77 268
c7de829c 269 if (CurrentPci->active) {
8bde7f77
WD
270 outb(0x102, save_pos102);
271 outb(0x46e8, save_46e8);
272 outb(0x3C3, save_vse);
273 outb(0x3C2, save_msr);
c7de829c 274 }
8bde7f77 275
c7de829c
WD
276 /* clear interrupt vectors */
277#ifdef __ia32__
278 vbios_base = CurrentPci->active ? setup_primary_int_vect()
8bde7f77 279 : setup_int_vect();
c7de829c
WD
280#else
281 vbios_base = setup_int_vect();
282#endif
283 ax = ((CARD16)(CurrentPci->bus) << 8)
8bde7f77 284 | (CurrentPci->dev << 3) | (CurrentPci->func & 0x7);
c7de829c 285 if (Config.Verbose > 1) P_printf("ax: 0x%x\n",ax);
8bde7f77 286
c7de829c 287 BootBios = findPciByIDs(CurrentPci->bus,CurrentPci->dev,
8bde7f77 288 CurrentPci->func);
c7de829c 289 if (!((mapPciRom(BootBios) && chksum((CARD8*)V_BIOS))
8bde7f77
WD
290 || (CurrentPci->active && copy_vbios(vbios_base)))) {
291 CurrentPci = CurrentPci->next;
292 continue;
c7de829c
WD
293 }
294 if (!map_vram()) {
8bde7f77
WD
295 CurrentPci = CurrentPci->next;
296 continue;
c7de829c
WD
297 }
298 if (Config.SaveBios) save_bios_to_file();
299 printf("initializing PCI bus: %i dev: %i func: %i\n",CurrentPci->bus,
8bde7f77 300 CurrentPci->dev,CurrentPci->func);
c7de829c
WD
301 bootBIOS(ax);
302 unmap_vram();
303
304 if (CurrentPci->active)
8bde7f77 305 close_console(Console);
c7de829c
WD
306
307 if (dev) return;
8bde7f77 308
c7de829c
WD
309 CurrentPci = CurrentPci->next;
310 }
8bde7f77 311
c7de829c
WD
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))
8bde7f77 315 || (dev && dev->type == ISA))) {
c7de829c
WD
316
317 pciVideoDisable();
318
319 if (!dev || dev->type == ISA) {
8bde7f77
WD
320 outb(0x102, save_pos102);
321 outb(0x46e8, save_46e8);
322 outb(0x3C3, save_vse);
323 outb(0x3C2, save_msr);
324
c7de829c 325#ifdef __ia32__
8bde7f77 326 vbios_base = setup_primary_int_vect();
c7de829c 327#else
8bde7f77 328 vbios_base = setup_int_vect();
c7de829c 329#endif
8bde7f77
WD
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
c7de829c
WD
346}
347
8bde7f77 348int
c7de829c
WD
349map(void)
350{
351 void* mem;
352 mem = mmap(0, (size_t)SIZE,
8bde7f77
WD
353 PROT_EXEC | PROT_READ | PROT_WRITE,
354 MAP_FIXED | MAP_PRIVATE | MAP_ANON,
355 -1, 0 );
c7de829c 356 if (mem != 0) {
8bde7f77
WD
357 perror("anonymous map");
358 return (0);
c7de829c
WD
359 }
360 memset(mem,0,SIZE);
361
362 return (1);
363}
364
365static void
366unmap(void)
367{
368 munmap(0,SIZE);
369}
370
371static void
372bootBIOS(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
387static int
388map_vram(void)
389{
390 int mem_fd;
391
392#ifdef __ia64__
8bde7f77 393 if ((mem_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0)
c7de829c 394#else
8bde7f77 395 if ((mem_fd = open(MEM_FILE,O_RDWR))<0)
c7de829c 396#endif
8bde7f77
WD
397 {
398 perror("opening memory");
399 return 0;
c7de829c
WD
400 }
401
402#ifdef __alpha__
403 if (!_bus_base()) sparse_shift = 7; /* Uh, oh, JENSEN... */
8bde7f77
WD
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)
c7de829c
WD
410#else
411 if (mmap((void *) VRAM_START, (size_t) VRAM_SIZE,
8bde7f77
WD
412 PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
413 mem_fd, VRAM_START) == (void *) -1)
c7de829c
WD
414#endif
415 {
8bde7f77
WD
416 perror("mmap error in map_hardware_ram (1)");
417 close(mem_fd);
418 return (0);
419 }
c7de829c
WD
420 vram_mapped = 1;
421 close(mem_fd);
422 return (1);
423}
424
425static void
426unmap_vram(void)
427{
428 if (!vram_mapped) return;
8bde7f77 429
c7de829c
WD
430 munmap((void*)VRAM_START,VRAM_SIZE);
431 vram_mapped = 0;
432}
433
434static int
435copy_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) {
8bde7f77
WD
442 perror("opening memory");
443 return (0);
c7de829c
WD
444 }
445
8bde7f77
WD
446 if (lseek(mem_fd,(off_t) v_base, SEEK_SET) != (off_t) v_base) {
447 fprintf(stderr,"Cannot lseek\n");
448 goto Error;
c7de829c
WD
449 }
450 tmp = (unsigned char *)malloc(3);
451 if (read(mem_fd, (char *)tmp, (size_t) 3) != (size_t) 3) {
8bde7f77
WD
452 fprintf(stderr,"Cannot read\n");
453 goto Error;
c7de829c 454 }
8bde7f77
WD
455 if (lseek(mem_fd,(off_t) v_base,SEEK_SET) != (off_t) v_base)
456 goto Error;
c7de829c
WD
457
458 if (*tmp != 0x55 || *(tmp+1) != 0xAA ) {
8bde7f77
WD
459 fprintf(stderr,"No bios found at: 0x%lx\n",v_base);
460 goto Error;
c7de829c
WD
461 }
462#ifdef DEBUG
8bde7f77 463 dprint((unsigned long)tmp,0x100);
c7de829c
WD
464#endif
465 size = *(tmp+2) * 512;
466
467 if (read(mem_fd, (char *)v_base, (size_t) size) != (size_t) size) {
8bde7f77
WD
468 fprintf(stderr,"Cannot read\n");
469 goto Error;
c7de829c
WD
470 }
471 free(tmp);
472 close(mem_fd);
473 if (!chksum((CARD8*)v_base))
8bde7f77 474 return (0);
c7de829c
WD
475
476 return (1);
477
478Error:
479 perror("v_bios");
480 close(mem_fd);
481 return (0);
482}
483
484static int
485copy_sys_bios(void)
486{
487#define SYS_BIOS 0xF0000
488 int mem_fd;
489
490 if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
8bde7f77
WD
491 perror("opening memory");
492 return (0);
c7de829c 493 }
8bde7f77
WD
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;
c7de829c
WD
499
500 close(mem_fd);
501 return (1);
502
503Error:
504 perror("sys_bios");
505 close(mem_fd);
506 return (0);
507}
508
509void
510loadCodeToMem(unsigned char *ptr, CARD8 code[])
511{
512 int i;
513 CARD8 val;
514 int size = code[0];
8bde7f77 515
c7de829c 516 for ( i=1;i<=size;i++) {
8bde7f77
WD
517 val = code[i];
518 *ptr++ = val;
c7de829c
WD
519 }
520 return;
521}
8bde7f77
WD
522
523void
c7de829c
WD
524dprint(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);
8bde7f77
WD
532 for (i = 0; i<16; i++)
533 printf("%2.2x ",(unsigned char) (*(c++)));
c7de829c
WD
534 c = d;
535 for (i = 0; i<16; i++) {
8bde7f77
WD
536 printf("%c",((((CARD8)(*c)) > 32) && (((CARD8)(*c)) < 128)) ?
537 (unsigned char) (*(c)): '.');
538 c++;
c7de829c
WD
539 }
540 }
541 printf("\n");
542}
543
544static void
545save_bios_to_file(void)
546{
547 static int num = 0;
548 int size, count;
549 char file_name[256];
550 int fd;
8bde7f77 551
c7de829c
WD
552 sprintf(file_name,"bios_%i.fil",num);
553 if ((fd = open(file_name,O_WRONLY | O_CREAT | O_TRUNC,00644)) == -1)
8bde7f77 554 return;
c7de829c
WD
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)
8bde7f77 560 fprintf(stderr,"only saved %i of %i bytes\n",size,count);
c7de829c
WD
561 num++;
562}
563
564static void
565sig_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 */
589static 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__
608static CARD32
609setup_primary_int_vect(void)
610{
611 int mem_fd;
612 CARD32 vbase;
613 void *map;
614
8bde7f77
WD
615 if ((mem_fd = open(MEM_FILE,O_RDWR))<0)
616 {
c7de829c
WD
617 perror("opening memory");
618 return (0);
619 }
8bde7f77 620
c7de829c 621 if ((map = mmap((void *) 0, (size_t) 0x2000,
8bde7f77
WD
622 PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
623 mem_fd, 0)) == (void *)-1) {
c7de829c
WD
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);
8bde7f77 639
c7de829c
WD
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
646static CARD32
647setup_int_vect(void)
648{
649 const CARD16 cs = 0x0;
650 const CARD16 ip = 0x0;
651 int i;
8bde7f77 652
c7de829c
WD
653 /* let the int vects point to the SYS_BIOS seg */
654 for (i=0; i<0x80; i++) {
8bde7f77
WD
655 ((CARD16*)0)[i<<1] = ip;
656 ((CARD16*)0)[(i<<1)+1] = cs;
c7de829c
WD
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
703static int
704setup_system_bios(void)
705{
706 char *date = "06/01/99";
707 char *eisa_ident = "PCI/ISA";
8bde7f77 708
c7de829c
WD
709 if (Config.MapSysBios) {
710
8bde7f77
WD
711 if (!copy_sys_bios()) return 0;
712 return 1;
c7de829c
WD
713
714 } else {
715
8bde7f77
WD
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
c7de829c
WD
742}
743
744static void
745update_bios_vars(void)
746{
747 int mem_fd;
748 void *map;
749 memType i;
8bde7f77 750
c7de829c 751#ifdef __ia64__
8bde7f77 752 if ((mem_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0)
c7de829c 753#else
8bde7f77 754 if ((mem_fd = open(MEM_FILE,O_RDWR))<0)
c7de829c 755#endif
8bde7f77 756 {
c7de829c
WD
757 perror("opening memory");
758 return;
759 }
8bde7f77 760
c7de829c 761 if ((map = mmap((void *) 0, (size_t) 0x2000,
8bde7f77
WD
762 PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
763 mem_fd, 0)) == (void *)-1) {
c7de829c
WD
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++) {
8bde7f77
WD
770 if (bios_var[i] != *(CARD8*)i)
771 *((CARD8*)map + i) = *(CARD8*)i;
c7de829c
WD
772 }
773
774 munmap(map,0x2000);
775 close(mem_fd);
776}
777
778static int
779chksum(CARD8 *start)
780{
781 CARD16 size;
782 CARD8 val = 0;
783 int i;
784
8bde7f77 785 size = *(start+2) * 512;
c7de829c
WD
786 for (i = 0; i<size; i++)
787 val += *(start + i);
8bde7f77 788
c7de829c
WD
789 if (!val)
790 return 1;
791
792 fprintf(stderr,"BIOS cksum wrong!\n");
793 return 0;
794}
795
796void
797runINT(int num, i86biosRegsPtr Regs)
798{
799 Bool isVideo = FALSE;
800 CARD8 code_int[] = { 3, 0xcd, 0x00, 0xf4 };
801
802 code_int[2] = (CARD8) num;
8bde7f77 803
c7de829c
WD
804 if (num == 0x10)
805 isVideo = TRUE;
8bde7f77 806
c7de829c
WD
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
8bde7f77 818 return;
c7de829c 819 if (!copy_vbios(vbios_base))
8bde7f77 820 return;
c7de829c 821 }
8bde7f77 822
c7de829c
WD
823 if (!map_vram())
824 return;
8bde7f77 825
c7de829c 826#ifdef V86BIOS_DEBUG
8bde7f77 827 printf("starting BIOS\n");
c7de829c
WD
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);
8bde7f77 837
c7de829c
WD
838#ifdef V86BIOS_DEBUG
839 printf("done\n");
840#endif
841
8bde7f77 842 if ((isVideo && (!CurrentPci || CurrentPci->active)) || !isVideo)
c7de829c
WD
843 update_bios_vars();
844}
845
846static void
847print_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
855static void
856print_usage(void)
857{
858}
859
860void
861add_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 }
8bde7f77 870
c7de829c
WD
871 for (i=0; i<20; i++) {
872 if (hltp[i].address == 0) {
8bde7f77
WD
873 hltp[i].address = (void*)val;
874 break;
c7de829c
WD
875 }
876 }
877 if (i == 20) printf("no more hltpoints available\n");
878}
879
880void
881del_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++)
8bde7f77 887 hltp[i].address = NULL;
c7de829c
WD
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
893void
894list_hlt()
895{
896 int i;
8bde7f77 897 for (i=0; i<20; i++)
c7de829c 898 if (hltp[i].address)
8bde7f77 899 printf("hltpoint[%i]: 0x%lx\n",i,(unsigned long)hltp[i].address);
c7de829c
WD
900}
901
902static void
903set_hlt(Bool set)
904{
905 int i;
8bde7f77 906 for (i=0; i<20; i++)
c7de829c 907 if (hltp[i].address) {
8bde7f77
WD
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;
c7de829c
WD
913 }
914}
915
916static void
917set_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]) {
8bde7f77
WD
925 start = i;
926 for (;i < IOPERM_BITS; i++) {
927 if (!ioperm_list[i]) {
928 ioperm(start,i - start, 1);
929 break;
930 }
931 }
c7de829c
WD
932 }
933}