]> git.ipfire.org Git - people/ms/u-boot.git/blame - board/MAI/bios_emulator/scitech/src/v86bios/cbios.c
* Code cleanup:
[people/ms/u-boot.git] / board / MAI / bios_emulator / scitech / src / v86bios / cbios.c
CommitLineData
c7de829c
WD
1#include <unistd.h>
2#include <fcntl.h>
3#include <stdio.h>
4#include <sys/mman.h>
5#include <sys/types.h>
6#include <string.h>
7#include <stdlib.h>
8#include <signal.h>
9#include <sys/stat.h>
10#include <getopt.h>
11#if defined(__alpha__) || defined (__ia64__)
12#include <sys/io.h>
13#elif defined(HAVE_SYS_PERM)
14#include <sys/perm.h>
15#endif
16#include "debug.h"
17#include "v86bios.h"
18#include "pci.h"
19#include "AsmMacros.h"
20
21#define SIZE 0x100000
22#define VRAM_START 0xA0000
23#define VRAM_SIZE 0x1FFFF
24#define V_BIOS_SIZE 0x1FFFF
25#define BIOS_START 0x7C00 /* default BIOS entry */
26#define BIOS_MEM 0x600
27
28CARD8 code[] = { 0xcd, 0x10, 0xf4 };
29struct config Config;
30
31static int map(void);
32static void unmap(void);
33static void runBIOS(int argc, char **argv);
34static int map_vram(void);
35static void unmap_vram(void);
36static int copy_vbios(memType base);
37static int copy_sys_bios(void);
38static CARD32 setup_int_vect(void);
39static void update_bios_vars(void);
40static int chksum(CARD8 *start);
41static void setup_bios_regs(i86biosRegsPtr regs, int argc, char **argv);
42static void print_regs(i86biosRegsPtr regs);
43void dprint(unsigned long start, unsigned long size);
44
45void loadCodeToMem(unsigned char *ptr, CARD8 *code);
46
47static int vram_mapped = 0;
48static char* bios_var;
49
50
51int
52main(int argc,char **argv)
53{
54 CARD32 vbios_base;
55
56 Config.PrintPort = PRINT_PORT;
57 Config.IoStatistics = IO_STATISTICS;
58 Config.PrintIrq = PRINT_IRQ;
59 Config.PrintPci = PRINT_PCI;
8bde7f77
WD
60 Config.ShowAllDev = SHOW_ALL_DEV;
61 Config.PrintIp = PRINT_IP;
62 Config.SaveBios = SAVE_BIOS;
63 Config.Trace = TRACE;
64 Config.ConfigActiveOnly = CONFIG_ACTIVE_ONLY;
c7de829c 65 Config.ConfigActiveDevice = CONFIG_ACTIVE_DEVICE;
8bde7f77
WD
66 Config.MapSysBios = MAP_SYS_BIOS;
67 Config.Resort = RESORT;
68 Config.FixRom = FIX_ROM;
69 Config.NoConsole = NO_CONSOLE;
c7de829c 70 Config.Verbose = VERBOSE;
8bde7f77 71
c7de829c
WD
72 if (!map())
73 exit(1);
74 if (!copy_sys_bios())
75 exit(1);
76 if (!(vbios_base = setup_int_vect()))
77 exit(1);
78 if (!map_vram())
79 exit(1);
80 if (!copy_vbios(vbios_base))
81 exit(1);
8bde7f77 82
c7de829c
WD
83 iopl(3);
84 setup_io();
85 runBIOS(argc,argv);
86 update_bios_vars();
87 unmap_vram();
88 iopl(0);
89 unmap();
90 printf("done !\n");
91 exit (1);
92}
93
8bde7f77 94int
c7de829c
WD
95map(void)
96{
97 void* mem;
98
99 mem = mmap(0, (size_t)SIZE,
8bde7f77
WD
100 PROT_EXEC | PROT_READ | PROT_WRITE,
101 MAP_FIXED | MAP_PRIVATE | MAP_ANON,
102 -1, 0 );
c7de829c 103 if (mem != 0) {
8bde7f77
WD
104 perror("anonymous map");
105 return (0);
c7de829c
WD
106 }
107 memset(mem,0,SIZE);
108
109 loadCodeToMem((unsigned char *) BIOS_START, code);
110 return (1);
111}
112
113static int
114copy_sys_bios(void)
115{
116#define SYS_BIOS 0xF0000
117 int mem_fd;
118
119 if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
8bde7f77
WD
120 perror("opening memory");
121 return (0);
c7de829c 122 }
8bde7f77
WD
123
124 if (lseek(mem_fd,(off_t) SYS_BIOS,SEEK_SET) != (off_t) SYS_BIOS)
125 goto Error;
126 if (read(mem_fd, (char *)SYS_BIOS, (size_t) 0xFFFF) != (size_t) 0xFFFF)
127 goto Error;
c7de829c
WD
128
129 close(mem_fd);
130 return (1);
131
132Error:
133 perror("sys_bios");
134 close(mem_fd);
135 return (0);
136}
137
138static int
139map_vram(void)
140{
141 int mem_fd;
142
143#ifdef __ia64__
8bde7f77 144 if ((mem_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0)
c7de829c 145#else
8bde7f77 146 if ((mem_fd = open(MEM_FILE,O_RDWR))<0)
c7de829c
WD
147#endif
148 {
8bde7f77
WD
149 perror("opening memory");
150 return 0;
c7de829c
WD
151 }
152
153#ifndef __alpha__
154 if (mmap((void *) VRAM_START, (size_t) VRAM_SIZE,
8bde7f77
WD
155 PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
156 mem_fd, VRAM_START) == (void *) -1)
c7de829c 157#else
8bde7f77
WD
158 if (!_bus_base()) sparse_shift = 7; /* Uh, oh, JENSEN... */
159 if (!_bus_base_sparse()) sparse_shift = 0;
160 if ((vram_map = mmap(0,(size_t) (VRAM_SIZE << sparse_shift),
161 PROT_READ | PROT_WRITE,
162 MAP_SHARED,
163 mem_fd, (VRAM_START << sparse_shift)
164 | _bus_base_sparse())) == (void *) -1)
c7de829c
WD
165#endif
166 {
8bde7f77
WD
167 perror("mmap error in map_hardware_ram");
168 close(mem_fd);
169 return (0);
170 }
c7de829c
WD
171 vram_mapped = 1;
172 close(mem_fd);
173 return (1);
174}
175
176static int
177copy_vbios(memType v_base)
178{
179 int mem_fd;
180 unsigned char *tmp;
181 int size;
182
183 if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
8bde7f77
WD
184 perror("opening memory");
185 return (0);
c7de829c
WD
186 }
187
8bde7f77
WD
188 if (lseek(mem_fd,(off_t) v_base, SEEK_SET) != (off_t) v_base) {
189 fprintf(stderr,"Cannot lseek\n");
190 goto Error;
c7de829c
WD
191 }
192 tmp = (unsigned char *)malloc(3);
193 if (read(mem_fd, (char *)tmp, (size_t) 3) != (size_t) 3) {
8bde7f77
WD
194 fprintf(stderr,"Cannot read\n");
195 goto Error;
c7de829c 196 }
8bde7f77
WD
197 if (lseek(mem_fd,(off_t) v_base,SEEK_SET) != (off_t) v_base)
198 goto Error;
c7de829c
WD
199
200 if (*tmp != 0x55 || *(tmp+1) != 0xAA ) {
8bde7f77
WD
201 fprintf(stderr,"No bios found at: 0x%lx\n",v_base);
202 goto Error;
c7de829c
WD
203 }
204#ifdef DEBUG
8bde7f77 205 dprint((unsigned long)tmp,0x100);
c7de829c
WD
206#endif
207 size = *(tmp+2) * 512;
208
209 if (read(mem_fd, (char *)v_base, (size_t) size) != (size_t) size) {
8bde7f77
WD
210 fprintf(stderr,"Cannot read\n");
211 goto Error;
c7de829c
WD
212 }
213 free(tmp);
214 close(mem_fd);
215 if (!chksum((CARD8*)v_base))
8bde7f77 216 return (0);
c7de829c
WD
217
218 return (1);
219
220Error:
221 perror("v_bios");
222 close(mem_fd);
223 return (0);
224}
225
226static void
227unmap(void)
228{
229 munmap(0,SIZE);
230}
231
232static void
233unmap_vram(void)
234{
235 if (!vram_mapped) return;
8bde7f77 236
c7de829c
WD
237 munmap((void*)VRAM_START,VRAM_SIZE);
238 vram_mapped = 0;
239}
240
241static void
242runBIOS(int argc, char ** argv)
243{
244 i86biosRegs bRegs;
245#ifdef V86BIOS_DEBUG
246 printf("starting BIOS\n");
247#endif
248 setup_bios_regs(&bRegs, argc, argv);
249 do_x86(BIOS_START,&bRegs);
250 print_regs(&bRegs);
251#ifdef V86BIOS_DEBUG
252 printf("done\n");
253#endif
254}
255
256static CARD32
257setup_int_vect(void)
258{
259 int mem_fd;
260 CARD32 vbase;
261 void *map;
8bde7f77 262
c7de829c
WD
263 if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
264 perror("opening memory");
265 return (0);
266 }
8bde7f77 267
c7de829c 268 if ((map = mmap((void *) 0, (size_t) 0x2000,
8bde7f77
WD
269 PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
270 mem_fd, 0)) == (void *)-1) {
c7de829c
WD
271 perror("mmap error in map_hardware_ram");
272 close(mem_fd);
273 return (0);
274 }
275
276 close(mem_fd);
277 memcpy(0,map,BIOS_MEM);
278 munmap(map,0x2000);
279 /*
280 * create a backup copy of the bios variables to write back the
281 * modified values
282 */
283 bios_var = (char *)malloc(BIOS_MEM);
284 memcpy(bios_var,0,BIOS_MEM);
8bde7f77 285
c7de829c
WD
286 vbase = (*((CARD16*)(0x10 << 2) + 1)) << 4;
287 fprintf(stderr,"vbase: 0x%x\n",vbase);
288 return vbase;
289}
290
291static void
292update_bios_vars(void)
293{
294 int mem_fd;
295 void *map;
296 memType i;
8bde7f77 297
c7de829c 298#ifdef __ia64__
8bde7f77 299 if ((mem_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0)
c7de829c 300#else
8bde7f77 301 if ((mem_fd = open(MEM_FILE,O_RDWR))<0)
c7de829c
WD
302#endif
303 {
8bde7f77
WD
304 perror("opening memory");
305 return;
c7de829c 306 }
8bde7f77 307
c7de829c 308 if ((map = mmap((void *) 0, (size_t) 0x2000,
8bde7f77
WD
309 PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
310 mem_fd, 0)) == (void *)-1) {
c7de829c
WD
311 perror("mmap error in map_hardware_ram");
312 close(mem_fd);
313 return;
314 }
315
316 for (i = 0; i < BIOS_MEM; i++) {
8bde7f77
WD
317 if (bios_var[i] != *(CARD8*)i)
318 *((CARD8*)map + i) = *(CARD8*)i;
c7de829c
WD
319 }
320
321 munmap(map,0x2000);
322 close(mem_fd);
323}
324
325
326static void
327setup_bios_regs(i86biosRegsPtr regs, int argc, char **argv)
328{
329 int c;
330
331 regs->ax = 0;
332 regs->bx = 0;
333 regs->cx = 0;
334 regs->dx = 0;
335 regs->es = 0;
336 regs->di = 0;
337 opterr = 0;
338 while ((c = getopt(argc,argv,"a:b:c:d:e:i:")) != EOF) {
339 switch (c) {
340 case 'a':
8bde7f77
WD
341 regs->ax = strtol(optarg,NULL,0);
342 break;
c7de829c 343 case 'b':
8bde7f77
WD
344 regs->bx = strtol(optarg,NULL,0);
345 break;
c7de829c 346 case 'c':
8bde7f77
WD
347 regs->cx = strtol(optarg,NULL,0);
348 break;
c7de829c 349 case 'd':
8bde7f77
WD
350 regs->dx = strtol(optarg,NULL,0);
351 break;
c7de829c 352 case 'e':
8bde7f77
WD
353 regs->es = strtol(optarg,NULL,0);
354 break;
c7de829c 355 case 'i':
8bde7f77
WD
356 regs->di = strtol(optarg,NULL,0);
357 break;
c7de829c
WD
358 }
359 }
360}
361
362
363static int
364chksum(CARD8 *start)
365{
366 CARD16 size;
367 CARD8 val = 0;
368 int i;
369
8bde7f77 370 size = *(start+2) * 512;
c7de829c
WD
371 for (i = 0; i<size; i++)
372 val += *(start + i);
8bde7f77 373
c7de829c
WD
374 if (!val)
375 return 1;
376
377 fprintf(stderr,"BIOS cksum wrong!\n");
378 return 0;
379}
380
381static void
382print_regs(i86biosRegsPtr regs)
383{
384 printf("ax=%x bx=%x cx=%x dx=%x es=%x di=%x\n",(CARD16)regs->ax,
385 (CARD16)regs->bx,(CARD16)regs->cx,(CARD16)regs->dx,
386 (CARD16)regs->es,(CARD16)regs->di);
387}
388
389void
390loadCodeToMem(unsigned char *ptr, CARD8 code[])
391{
392 int i;
393 CARD8 val;
8bde7f77 394
c7de829c 395 for ( i=0;;i++) {
8bde7f77
WD
396 val = code[i];
397 *ptr++ = val;
398 if (val == 0xf4) break;
c7de829c
WD
399 }
400 return;
401}
402
8bde7f77 403void
c7de829c
WD
404dprint(unsigned long start, unsigned long size)
405{
406 int i,j;
407 char *c = (char *)start;
408
409 for (j = 0; j < (size >> 4); j++) {
8bde7f77
WD
410 printf ("\n0x%lx: ",(unsigned long)c);
411 for (i = 0; i<16; i++)
412 printf("%x ",(unsigned char) (*(c++)));
c7de829c
WD
413 }
414 printf("\n");
415}