Coding style cleanup
[platform/kernel/u-boot.git] / board / MAI / bios_emulator / scitech / src / v86bios / cbios.c
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
28 CARD8 code[] = { 0xcd, 0x10, 0xf4 };
29 struct config Config;
30
31 static int map(void);
32 static void unmap(void);
33 static void runBIOS(int argc, char **argv);
34 static int map_vram(void);
35 static void unmap_vram(void);
36 static int copy_vbios(memType base);
37 static int copy_sys_bios(void);
38 static CARD32 setup_int_vect(void);
39 static void update_bios_vars(void);
40 static int chksum(CARD8 *start);
41 static void setup_bios_regs(i86biosRegsPtr regs, int argc, char **argv);
42 static void print_regs(i86biosRegsPtr regs);
43 void dprint(unsigned long start, unsigned long size);
44
45 void loadCodeToMem(unsigned char *ptr, CARD8 *code);
46
47 static int vram_mapped = 0;
48 static char* bios_var;
49
50
51 int
52 main(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;
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;
65     Config.ConfigActiveDevice = CONFIG_ACTIVE_DEVICE;
66     Config.MapSysBios = MAP_SYS_BIOS;
67     Config.Resort = RESORT;
68     Config.FixRom = FIX_ROM;
69     Config.NoConsole = NO_CONSOLE;
70     Config.Verbose = VERBOSE;
71
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);
82
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
94 int
95 map(void)
96 {
97     void* mem;
98
99     mem = mmap(0, (size_t)SIZE,
100                PROT_EXEC | PROT_READ | PROT_WRITE,
101                MAP_FIXED | MAP_PRIVATE | MAP_ANON,
102                -1, 0 );
103     if (mem != 0) {
104         perror("anonymous map");
105         return (0);
106     }
107     memset(mem,0,SIZE);
108
109     loadCodeToMem((unsigned char *) BIOS_START, code);
110     return (1);
111 }
112
113 static int
114 copy_sys_bios(void)
115 {
116 #define SYS_BIOS 0xF0000
117     int mem_fd;
118
119     if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
120         perror("opening memory");
121         return (0);
122     }
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;
128
129     close(mem_fd);
130     return (1);
131
132 Error:
133     perror("sys_bios");
134     close(mem_fd);
135     return (0);
136 }
137
138 static int
139 map_vram(void)
140 {
141     int mem_fd;
142
143 #ifdef __ia64__
144     if ((mem_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0)
145 #else
146     if ((mem_fd = open(MEM_FILE,O_RDWR))<0)
147 #endif
148       {
149         perror("opening memory");
150         return 0;
151     }
152
153 #ifndef __alpha__
154     if (mmap((void *) VRAM_START, (size_t) VRAM_SIZE,
155                      PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
156                      mem_fd, VRAM_START) == (void *) -1)
157 #else
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)
165 #endif
166       {
167         perror("mmap error in map_hardware_ram");
168             close(mem_fd);
169             return (0);
170         }
171     vram_mapped = 1;
172     close(mem_fd);
173     return (1);
174 }
175
176 static int
177 copy_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) {
184         perror("opening memory");
185         return (0);
186     }
187
188     if (lseek(mem_fd,(off_t) v_base, SEEK_SET) != (off_t) v_base) {
189           fprintf(stderr,"Cannot lseek\n");
190           goto Error;
191       }
192     tmp = (unsigned char *)malloc(3);
193     if (read(mem_fd, (char *)tmp, (size_t) 3) != (size_t) 3) {
194             fprintf(stderr,"Cannot read\n");
195         goto Error;
196     }
197     if (lseek(mem_fd,(off_t) v_base,SEEK_SET) != (off_t) v_base)
198         goto Error;
199
200     if (*tmp != 0x55 || *(tmp+1) != 0xAA ) {
201         fprintf(stderr,"No bios found at: 0x%lx\n",v_base);
202         goto Error;
203     }
204 #ifdef DEBUG
205         dprint((unsigned long)tmp,0x100);
206 #endif
207     size = *(tmp+2) * 512;
208
209     if (read(mem_fd, (char *)v_base, (size_t) size) != (size_t) size) {
210             fprintf(stderr,"Cannot read\n");
211         goto Error;
212     }
213     free(tmp);
214     close(mem_fd);
215     if (!chksum((CARD8*)v_base))
216         return (0);
217
218     return (1);
219
220 Error:
221     perror("v_bios");
222     close(mem_fd);
223     return (0);
224 }
225
226 static void
227 unmap(void)
228 {
229     munmap(0,SIZE);
230 }
231
232 static void
233 unmap_vram(void)
234 {
235     if (!vram_mapped) return;
236
237     munmap((void*)VRAM_START,VRAM_SIZE);
238     vram_mapped = 0;
239 }
240
241 static void
242 runBIOS(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
256 static CARD32
257 setup_int_vect(void)
258 {
259     int mem_fd;
260     CARD32 vbase;
261     void *map;
262
263     if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
264     perror("opening memory");
265     return (0);
266     }
267
268     if ((map = mmap((void *) 0, (size_t) 0x2000,
269          PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
270          mem_fd, 0)) == (void *)-1)   {
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);
285
286     vbase = (*((CARD16*)(0x10 << 2) + 1)) << 4;
287     fprintf(stderr,"vbase: 0x%x\n",vbase);
288     return vbase;
289 }
290
291 static void
292 update_bios_vars(void)
293 {
294     int mem_fd;
295     void *map;
296     memType i;
297
298 #ifdef __ia64__
299     if ((mem_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0)
300 #else
301     if ((mem_fd = open(MEM_FILE,O_RDWR))<0)
302 #endif
303       {
304         perror("opening memory");
305         return;
306       }
307
308     if ((map = mmap((void *) 0, (size_t) 0x2000,
309          PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
310          mem_fd, 0)) == (void *)-1)   {
311     perror("mmap error in map_hardware_ram");
312     close(mem_fd);
313     return;
314     }
315
316     for (i = 0; i < BIOS_MEM; i++) {
317     if (bios_var[i] != *(CARD8*)i)
318         *((CARD8*)map + i) = *(CARD8*)i;
319     }
320
321     munmap(map,0x2000);
322     close(mem_fd);
323 }
324
325
326 static void
327 setup_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':
341         regs->ax = strtol(optarg,NULL,0);
342         break;
343     case 'b':
344         regs->bx = strtol(optarg,NULL,0);
345         break;
346     case 'c':
347         regs->cx = strtol(optarg,NULL,0);
348         break;
349     case 'd':
350         regs->dx = strtol(optarg,NULL,0);
351         break;
352     case 'e':
353         regs->es = strtol(optarg,NULL,0);
354         break;
355     case 'i':
356         regs->di = strtol(optarg,NULL,0);
357         break;
358     }
359     }
360 }
361
362
363 static int
364 chksum(CARD8 *start)
365 {
366   CARD16 size;
367   CARD8 val = 0;
368   int i;
369
370   size = *(start+2) * 512;
371   for (i = 0; i<size; i++)
372     val += *(start + i);
373
374   if (!val)
375     return 1;
376
377     fprintf(stderr,"BIOS cksum wrong!\n");
378   return 0;
379 }
380
381 static void
382 print_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
389 void
390 loadCodeToMem(unsigned char *ptr, CARD8 code[])
391 {
392     int i;
393     CARD8 val;
394
395     for ( i=0;;i++) {
396         val = code[i];
397         *ptr++ = val;
398         if (val == 0xf4) break;
399     }
400     return;
401 }
402
403 void
404 dprint(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++) {
410         printf ("\n0x%lx:  ",(unsigned long)c);
411         for (i = 0; i<16; i++)
412             printf("%x ",(unsigned char) (*(c++)));
413     }
414     printf("\n");
415 }