1 /* This file is part of the coreboot project. */
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; version 2 of the License.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
23 #define die(x) { perror(x); exit(1); }
24 #define warn(x) { perror(x); }
26 #include <x86emu/x86emu.h>
27 #include <console/console.h>
28 #include <arch/byteorder.h>
32 #include "pci-userspace.h"
33 int X86EMU_set_debug(int debug
);
35 biosemu_device_t bios_device
;
37 extern int teststart
, testend
;
39 #define BIOSMEM_SIZE (1024 * 1024)
40 unsigned char biosmem
[BIOSMEM_SIZE
];
44 static unsigned char *mapitin(char *file
, off_t where
, size_t size
)
48 int fd
= open(file
, O_RDWR
, 0);
52 z
= mmap(0, size
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, fd
, where
);
60 static unsigned short get_device(char *arg_val
)
62 unsigned short devfn
=0;
63 long bus
=0,dev
=0,fn
=0,need_pack
=0;
66 tok
= strsep(&arg_val
,":");
67 if (arg_val
!= NULL
) {
68 bus
= strtol(tok
,0,16);
75 tok
= strsep(&arg_val
,".");
76 if (arg_val
!= NULL
) {
77 dev
= strtol(tok
,0,16);
78 fn
= strtol(arg_val
,0,16);
82 if (need_pack
==1 && (strlen(tok
))) {
83 dev
= strtol(tok
,0,16);
87 if ( need_pack
== 1) {
88 devfn
= bus
<<8 | (dev
<<3) | fn
;
91 devfn
= strtol(tok
, 0, 0);
97 int printk(int msg_level
, const char *fmt
, ...)
103 putchar('0' + msg_level
);
107 i
= vprintf(fmt
, args
);
113 static void usage(char *name
)
116 ("Usage: %s [-c codesegment] [-s size] [-b base] [-i ip] [-t] "
117 "<filename> ...\n", name
);
120 /* main entry into YABEL biosemu, arguments are:
121 * *biosmem = pointer to virtual memory
122 * biosmem_size = size of the virtual memory
123 * *dev = pointer to the device to be initialised
124 * rom_addr = address of the OptionROM to be executed, if this is = 0, YABEL
125 * will look for an ExpansionROM BAR and use the code from there.
128 biosemu(u8
*biosmem
, u32 biosmem_size
, struct device
* dev
, unsigned long
132 int main(int argc
, char **argv
)
135 char *absegname
= NULL
;
142 int have_size
= 0, have_base
= 0, have_ip
= 0, have_cs
= 0;
145 //char *fsegname = 0;
146 //unsigned char *fsegptr;
147 unsigned short initialip
= 0, initialcs
= 0, devfn
= 0;
148 //X86EMU_intrFuncs intFuncs[256];
152 //const char *optstring = "vh?b:i:c:s:tpd:";
153 const char *optstring
= "vh?b:i:c:s:tpd:";
155 int option_index
= 0;
156 static struct option long_options
[] = {
157 {"verbose", 0, 0, 'v'},
159 {"trace", 0, 0, 't'},
161 //{"fseg", 1, 0, 'f'},
162 {"instructionpointer", 1, 0, 'i'},
163 {"codesegment", 1, 0, 'c'},
164 {"absegment", 1, 0, 'a'},
166 {"parserom", 0, 0, 'p'},
167 {"device", 1, 0, 'd'},
168 {"debug", 1, 0, 'D'},
171 c
= getopt_long(argc
, argv
, optstring
, long_options
, &option_index
);
186 // base = strtol(optarg, 0, 0);
190 initialip
= strtol(optarg
, 0, 0);
194 initialcs
= strtol(optarg
, 0, 0);
198 size
= strtol(optarg
, 0, 0);
205 // fsegname = optarg;
211 devfn
= get_device(optarg
);
215 debugflag
= strtol(optarg
, 0, 0);
218 printf("Unknown option\n");
224 if (optind
>= argc
) {
225 printf("Filename missing.\n");
230 while (optind
< argc
) {
231 printf("running file %s\n", argv
[optind
]);
232 filename
= argv
[optind
];
234 /* normally we would do continue, but for
235 * now only one filename is supported.
242 printf("No size specified. defaulting to 32k\n");
246 printf("No base specified. defaulting to 0xc0000\n");
250 // printf("No initial code segment specified. defaulting to 0xc000\n");
251 // initialcs = 0xc000;
255 ("No initial instruction pointer specified. defaulting to 0x0003\n");
260 printf("Parsing rom images not implemented.\n");
262 //printf("Point 1 int%x vector at %x\n", 0x42, getIntVect(0x42));
264 if (initialip
== 0x0003) {
265 if ((devfn
== 0) || (have_devfn
== 0)) {
266 printf("WARNING! It appears you are trying to run an option ROM.\n");
267 printf(" (initial ip = 0x0003)\n");
269 printf(" However, the device you have specified is 0x00\n");
270 printf(" It is very unlikely that your device is at this address\n");
271 printf(" Please check your -d option\n");
274 printf(" Please specify a device with -d\n");
275 printf(" The default is not likely to work\n");
282 abseg
= mapitin(absegname
, (off_t
) 0xa0000, 0x20000);
290 warn("iopl failed, continuing anyway");
293 /* Emergency sync ;-) */
297 /* Setting up interrupt environment.
298 * basically this means initializing PCI and
304 for (i
= 0; i
< 256; i
++)
305 intFuncs
[i
] = do_int
;
306 X86EMU_setupIntrFuncs(intFuncs
);
308 cp
= mapitin(filename
, (off_t
) 0, size
);
311 printf("Loading ax with BusDevFn = %x\n",devfn
);
315 current
->ax
= devfn
? devfn
: 0xff;
318 for (i
= 0; i
< size
; i
++)
319 wrb(base
+ i
, cp
[i
]);
322 fsegptr
= mapitin(fsegname
, (off_t
) 0, 0x10000);
323 for (i
= 0; i
< 0x10000; i
++)
324 wrb(0xf0000 + i
, fsegptr
[i
]);
326 const char *date
= "01/01/99";
327 for (i
= i
; date
[i
]; i
++)
328 wrb(0xffff5 + i
, date
[i
]);
333 X86_AX
= devfn
? devfn
: 0xff;
338 /* Initialize stack and data segment */
342 /* We need a sane way to return from bios
343 * execution. A hlt instruction and a pointer
344 * to it, both kept on the stack, will do.
346 pushw(0xf4f4); /* hlt; hlt */
354 printf("Switching to single step mode.\n");
358 printf("Enable Debug = %x.\n",debugflag
);
359 //X86EMU_set_debug(debugflag);
365 ret
= biosemu(biosmem
, BIOSMEM_SIZE
, dev
, base
);
369 X86EMU_setMemBase(biosmem
, sizeof(biosmem
));
370 M
.abseg
= (unsigned long)abseg
;
371 X86EMU_setupPioFuncs(&myfuncs
);