Revision c45886db
b/vl.c | ||
---|---|---|
25 | 25 |
#include <stdio.h> |
26 | 26 |
#include <stdarg.h> |
27 | 27 |
#include <string.h> |
28 |
#include <ctype.h> |
|
28 | 29 |
#include <getopt.h> |
29 | 30 |
#include <inttypes.h> |
30 | 31 |
#include <unistd.h> |
... | ... | |
80 | 81 |
#define PHYS_RAM_BASE 0xac000000 |
81 | 82 |
#define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024) |
82 | 83 |
|
84 |
#if defined (TARGET_I386) |
|
83 | 85 |
#define KERNEL_LOAD_ADDR 0x00100000 |
86 |
#elif defined (TARGET_PPC) |
|
87 |
//#define USE_OPEN_FIRMWARE |
|
88 |
#if defined (USE_OPEN_FIRMWARE) |
|
89 |
#define KERNEL_LOAD_ADDR 0x01000000 |
|
90 |
#define KERNEL_STACK_ADDR 0x01200000 |
|
91 |
#else |
|
92 |
#define KERNEL_LOAD_ADDR 0x00000000 |
|
93 |
#define KERNEL_STACK_ADDR 0x00400000 |
|
94 |
#endif |
|
95 |
#endif |
|
84 | 96 |
#define INITRD_LOAD_ADDR 0x00400000 |
85 | 97 |
#define KERNEL_PARAMS_ADDR 0x00090000 |
86 | 98 |
|
... | ... | |
206 | 218 |
|
207 | 219 |
static const char *bios_dir = CONFIG_QEMU_SHAREDIR; |
208 | 220 |
char phys_ram_file[1024]; |
209 |
CPUX86State *global_env;
|
|
210 |
CPUX86State *cpu_single_env;
|
|
221 |
CPUState *global_env; |
|
222 |
CPUState *cpu_single_env; |
|
211 | 223 |
IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; |
212 | 224 |
IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; |
213 |
BlockDriverState *bs_table[MAX_DISKS]; |
|
225 |
BlockDriverState *bs_table[MAX_DISKS], *fd_table[MAX_FD];
|
|
214 | 226 |
int vga_ram_size; |
215 | 227 |
static DisplayState display_state; |
216 | 228 |
int nographic; |
... | ... | |
221 | 233 |
/***********************************************************/ |
222 | 234 |
/* x86 io ports */ |
223 | 235 |
|
224 |
uint32_t default_ioport_readb(CPUX86State *env, uint32_t address)
|
|
236 |
uint32_t default_ioport_readb(CPUState *env, uint32_t address) |
|
225 | 237 |
{ |
226 | 238 |
#ifdef DEBUG_UNUSED_IOPORT |
227 | 239 |
fprintf(stderr, "inb: port=0x%04x\n", address); |
... | ... | |
229 | 241 |
return 0xff; |
230 | 242 |
} |
231 | 243 |
|
232 |
void default_ioport_writeb(CPUX86State *env, uint32_t address, uint32_t data)
|
|
244 |
void default_ioport_writeb(CPUState *env, uint32_t address, uint32_t data) |
|
233 | 245 |
{ |
234 | 246 |
#ifdef DEBUG_UNUSED_IOPORT |
235 | 247 |
fprintf(stderr, "outb: port=0x%04x data=0x%02x\n", address, data); |
... | ... | |
237 | 249 |
} |
238 | 250 |
|
239 | 251 |
/* default is to make two byte accesses */ |
240 |
uint32_t default_ioport_readw(CPUX86State *env, uint32_t address)
|
|
252 |
uint32_t default_ioport_readw(CPUState *env, uint32_t address) |
|
241 | 253 |
{ |
242 | 254 |
uint32_t data; |
243 | 255 |
data = ioport_read_table[0][address & (MAX_IOPORTS - 1)](env, address); |
... | ... | |
245 | 257 |
return data; |
246 | 258 |
} |
247 | 259 |
|
248 |
void default_ioport_writew(CPUX86State *env, uint32_t address, uint32_t data)
|
|
260 |
void default_ioport_writew(CPUState *env, uint32_t address, uint32_t data) |
|
249 | 261 |
{ |
250 | 262 |
ioport_write_table[0][address & (MAX_IOPORTS - 1)](env, address, data & 0xff); |
251 | 263 |
ioport_write_table[0][(address + 1) & (MAX_IOPORTS - 1)](env, address + 1, (data >> 8) & 0xff); |
252 | 264 |
} |
253 | 265 |
|
254 |
uint32_t default_ioport_readl(CPUX86State *env, uint32_t address)
|
|
266 |
uint32_t default_ioport_readl(CPUState *env, uint32_t address) |
|
255 | 267 |
{ |
256 | 268 |
#ifdef DEBUG_UNUSED_IOPORT |
257 | 269 |
fprintf(stderr, "inl: port=0x%04x\n", address); |
... | ... | |
259 | 271 |
return 0xffffffff; |
260 | 272 |
} |
261 | 273 |
|
262 |
void default_ioport_writel(CPUX86State *env, uint32_t address, uint32_t data)
|
|
274 |
void default_ioport_writel(CPUState *env, uint32_t address, uint32_t data) |
|
263 | 275 |
{ |
264 | 276 |
#ifdef DEBUG_UNUSED_IOPORT |
265 | 277 |
fprintf(stderr, "outl: port=0x%04x data=0x%02x\n", address, data); |
... | ... | |
345 | 357 |
|
346 | 358 |
int load_kernel(const char *filename, uint8_t *addr) |
347 | 359 |
{ |
348 |
int fd, size, setup_sects; |
|
360 |
int fd, size; |
|
361 |
#if defined (TARGET_I386) |
|
362 |
int setup_sects; |
|
349 | 363 |
uint8_t bootsect[512]; |
364 |
#endif |
|
350 | 365 |
|
366 |
printf("Load kernel at %p (0x%08x)\n", addr, |
|
367 |
(uint32_t)addr - (uint32_t)phys_ram_base); |
|
351 | 368 |
fd = open(filename, O_RDONLY); |
352 | 369 |
if (fd < 0) |
353 | 370 |
return -1; |
371 |
#if defined (TARGET_I386) |
|
354 | 372 |
if (read(fd, bootsect, 512) != 512) |
355 | 373 |
goto fail; |
356 | 374 |
setup_sects = bootsect[0x1F1]; |
... | ... | |
358 | 376 |
setup_sects = 4; |
359 | 377 |
/* skip 16 bit setup code */ |
360 | 378 |
lseek(fd, (setup_sects + 1) * 512, SEEK_SET); |
379 |
#endif |
|
361 | 380 |
size = read(fd, addr, 16 * 1024 * 1024); |
362 | 381 |
if (size < 0) |
363 | 382 |
goto fail; |
... | ... | |
385 | 404 |
return size; |
386 | 405 |
} |
387 | 406 |
|
388 |
void cpu_x86_outb(CPUX86State *env, int addr, int val)
|
|
407 |
void cpu_outb(CPUState *env, int addr, int val)
|
|
389 | 408 |
{ |
390 | 409 |
ioport_write_table[0][addr & (MAX_IOPORTS - 1)](env, addr, val); |
391 | 410 |
} |
392 | 411 |
|
393 |
void cpu_x86_outw(CPUX86State *env, int addr, int val)
|
|
412 |
void cpu_outw(CPUState *env, int addr, int val)
|
|
394 | 413 |
{ |
395 | 414 |
ioport_write_table[1][addr & (MAX_IOPORTS - 1)](env, addr, val); |
396 | 415 |
} |
397 | 416 |
|
398 |
void cpu_x86_outl(CPUX86State *env, int addr, int val)
|
|
417 |
void cpu_outl(CPUState *env, int addr, int val)
|
|
399 | 418 |
{ |
400 | 419 |
ioport_write_table[2][addr & (MAX_IOPORTS - 1)](env, addr, val); |
401 | 420 |
} |
402 | 421 |
|
403 |
int cpu_x86_inb(CPUX86State *env, int addr)
|
|
422 |
int cpu_inb(CPUState *env, int addr)
|
|
404 | 423 |
{ |
405 | 424 |
return ioport_read_table[0][addr & (MAX_IOPORTS - 1)](env, addr); |
406 | 425 |
} |
407 | 426 |
|
408 |
int cpu_x86_inw(CPUX86State *env, int addr)
|
|
427 |
int cpu_inw(CPUState *env, int addr)
|
|
409 | 428 |
{ |
410 | 429 |
return ioport_read_table[1][addr & (MAX_IOPORTS - 1)](env, addr); |
411 | 430 |
} |
412 | 431 |
|
413 |
int cpu_x86_inl(CPUX86State *env, int addr)
|
|
432 |
int cpu_inl(CPUState *env, int addr)
|
|
414 | 433 |
{ |
415 | 434 |
return ioport_read_table[2][addr & (MAX_IOPORTS - 1)](env, addr); |
416 | 435 |
} |
417 | 436 |
|
418 | 437 |
/***********************************************************/ |
419 |
void ioport80_write(CPUX86State *env, uint32_t addr, uint32_t data)
|
|
438 |
void ioport80_write(CPUState *env, uint32_t addr, uint32_t data) |
|
420 | 439 |
{ |
421 | 440 |
} |
422 | 441 |
|
... | ... | |
430 | 449 |
fprintf(stderr, "\n"); |
431 | 450 |
#ifdef TARGET_I386 |
432 | 451 |
cpu_x86_dump_state(global_env, stderr, X86_DUMP_FPU | X86_DUMP_CCOP); |
452 |
#else |
|
453 |
cpu_dump_state(global_env, stderr, 0); |
|
433 | 454 |
#endif |
434 | 455 |
va_end(ap); |
435 | 456 |
abort(); |
... | ... | |
438 | 459 |
/***********************************************************/ |
439 | 460 |
/* cmos emulation */ |
440 | 461 |
|
462 |
#if defined (TARGET_I386) |
|
441 | 463 |
#define RTC_SECONDS 0 |
442 | 464 |
#define RTC_SECONDS_ALARM 1 |
443 | 465 |
#define RTC_MINUTES 2 |
... | ... | |
463 | 485 |
uint8_t cmos_data[128]; |
464 | 486 |
uint8_t cmos_index; |
465 | 487 |
|
466 |
void cmos_ioport_write(CPUX86State *env, uint32_t addr, uint32_t data)
|
|
488 |
void cmos_ioport_write(CPUState *env, uint32_t addr, uint32_t data) |
|
467 | 489 |
{ |
468 | 490 |
if (addr == 0x70) { |
469 | 491 |
cmos_index = data & 0x7f; |
... | ... | |
503 | 525 |
} |
504 | 526 |
} |
505 | 527 |
|
506 |
uint32_t cmos_ioport_read(CPUX86State *env, uint32_t addr)
|
|
528 |
uint32_t cmos_ioport_read(CPUState *env, uint32_t addr) |
|
507 | 529 |
{ |
508 | 530 |
int ret; |
509 | 531 |
|
... | ... | |
580 | 602 |
|
581 | 603 |
switch(boot_device) { |
582 | 604 |
case 'a': |
605 |
case 'b': |
|
583 | 606 |
cmos_data[0x3d] = 0x01; /* floppy boot */ |
584 | 607 |
break; |
585 | 608 |
default: |
... | ... | |
595 | 618 |
register_ioport_read(0x70, 2, cmos_ioport_read, 1); |
596 | 619 |
} |
597 | 620 |
|
621 |
void cmos_register_fd (uint8_t fd0, uint8_t fd1) |
|
622 |
{ |
|
623 |
int nb = 0; |
|
624 |
|
|
625 |
cmos_data[0x10] = 0; |
|
626 |
switch (fd0) { |
|
627 |
case 0: |
|
628 |
/* 1.44 Mb 3"5 drive */ |
|
629 |
cmos_data[0x10] |= 0x40; |
|
630 |
break; |
|
631 |
case 1: |
|
632 |
/* 2.88 Mb 3"5 drive */ |
|
633 |
cmos_data[0x10] |= 0x60; |
|
634 |
break; |
|
635 |
case 2: |
|
636 |
/* 1.2 Mb 5"5 drive */ |
|
637 |
cmos_data[0x10] |= 0x20; |
|
638 |
break; |
|
639 |
} |
|
640 |
switch (fd1) { |
|
641 |
case 0: |
|
642 |
/* 1.44 Mb 3"5 drive */ |
|
643 |
cmos_data[0x10] |= 0x04; |
|
644 |
break; |
|
645 |
case 1: |
|
646 |
/* 2.88 Mb 3"5 drive */ |
|
647 |
cmos_data[0x10] |= 0x06; |
|
648 |
break; |
|
649 |
case 2: |
|
650 |
/* 1.2 Mb 5"5 drive */ |
|
651 |
cmos_data[0x10] |= 0x02; |
|
652 |
break; |
|
653 |
} |
|
654 |
if (fd0 < 3) |
|
655 |
nb++; |
|
656 |
if (fd1 < 3) |
|
657 |
nb++; |
|
658 |
switch (nb) { |
|
659 |
case 0: |
|
660 |
break; |
|
661 |
case 1: |
|
662 |
cmos_data[REG_EQUIPMENT_BYTE] |= 0x01; /* 1 drive, ready for boot */ |
|
663 |
break; |
|
664 |
case 2: |
|
665 |
cmos_data[REG_EQUIPMENT_BYTE] |= 0x41; /* 2 drives, ready for boot */ |
|
666 |
break; |
|
667 |
} |
|
668 |
} |
|
669 |
#endif /* TARGET_I386 */ |
|
670 |
|
|
598 | 671 |
/***********************************************************/ |
599 | 672 |
/* 8259 pic emulation */ |
600 | 673 |
|
... | ... | |
606 | 679 |
uint8_t priority_add; /* used to compute irq priority */ |
607 | 680 |
uint8_t irq_base; |
608 | 681 |
uint8_t read_reg_select; |
682 |
uint8_t poll; |
|
609 | 683 |
uint8_t special_mask; |
610 | 684 |
uint8_t init_state; |
611 | 685 |
uint8_t auto_eoi; |
... | ... | |
663 | 737 |
|
664 | 738 |
/* raise irq to CPU if necessary. must be called every time the active |
665 | 739 |
irq may change */ |
666 |
static void pic_update_irq(void)
|
|
740 |
void pic_update_irq(void) |
|
667 | 741 |
{ |
668 | 742 |
int irq2, irq; |
669 | 743 |
|
... | ... | |
684 | 758 |
/* from master pic */ |
685 | 759 |
pic_irq_requested = irq; |
686 | 760 |
} |
687 |
cpu_x86_interrupt(global_env, CPU_INTERRUPT_HARD);
|
|
761 |
cpu_interrupt(global_env, CPU_INTERRUPT_HARD); |
|
688 | 762 |
} |
689 | 763 |
} |
690 | 764 |
|
... | ... | |
713 | 787 |
pic_update_irq(); |
714 | 788 |
} |
715 | 789 |
|
716 |
int cpu_x86_get_pic_interrupt(CPUX86State *env)
|
|
790 |
int cpu_x86_get_pic_interrupt(CPUState *env) |
|
717 | 791 |
{ |
718 | 792 |
int irq, irq2, intno; |
719 | 793 |
|
... | ... | |
742 | 816 |
return intno; |
743 | 817 |
} |
744 | 818 |
|
745 |
void pic_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
|
|
819 |
void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
|
746 | 820 |
{ |
747 | 821 |
PicState *s; |
748 | 822 |
int priority; |
... | ... | |
763 | 837 |
if (val & 0x08) |
764 | 838 |
hw_error("level sensitive irq not supported"); |
765 | 839 |
} else if (val & 0x08) { |
840 |
if (val & 0x04) { |
|
841 |
s->poll = 1; |
|
842 |
} else { |
|
766 | 843 |
if (val & 0x02) |
767 | 844 |
s->read_reg_select = val & 1; |
768 | 845 |
if (val & 0x40) |
769 | 846 |
s->special_mask = (val >> 5) & 1; |
847 |
} |
|
770 | 848 |
} else { |
771 | 849 |
switch(val) { |
772 | 850 |
case 0x00: |
... | ... | |
826 | 904 |
} |
827 | 905 |
} |
828 | 906 |
|
829 |
uint32_t pic_ioport_read(CPUX86State *env, uint32_t addr1) |
|
907 |
static uint32_t pic_poll_read (PicState *s, uint32_t addr1) |
|
908 |
{ |
|
909 |
int ret; |
|
910 |
|
|
911 |
ret = pic_get_irq(s); |
|
912 |
if (ret >= 0) { |
|
913 |
if (addr1 >> 7) { |
|
914 |
pics[0].isr &= ~(1 << 2); |
|
915 |
pics[0].irr &= ~(1 << 2); |
|
916 |
} |
|
917 |
s->irr &= ~(1 << ret); |
|
918 |
s->isr &= ~(1 << ret); |
|
919 |
if (addr1 >> 7 || ret != 2) |
|
920 |
pic_update_irq(); |
|
921 |
} else { |
|
922 |
ret = 0x07; |
|
923 |
pic_update_irq(); |
|
924 |
} |
|
925 |
|
|
926 |
return ret; |
|
927 |
} |
|
928 |
|
|
929 |
uint32_t pic_ioport_read(CPUState *env, uint32_t addr1) |
|
830 | 930 |
{ |
831 | 931 |
PicState *s; |
832 | 932 |
unsigned int addr; |
... | ... | |
835 | 935 |
addr = addr1; |
836 | 936 |
s = &pics[addr >> 7]; |
837 | 937 |
addr &= 1; |
938 |
if (s->poll == 1) { |
|
939 |
ret = pic_poll_read(s, addr1); |
|
940 |
s->poll = 0; |
|
941 |
} else { |
|
838 | 942 |
if (addr == 0) { |
839 | 943 |
if (s->read_reg_select) |
840 | 944 |
ret = s->isr; |
... | ... | |
843 | 947 |
} else { |
844 | 948 |
ret = s->imr; |
845 | 949 |
} |
950 |
} |
|
846 | 951 |
#ifdef DEBUG_PIC |
847 | 952 |
printf("pic_read: addr=0x%02x val=0x%02x\n", addr1, ret); |
848 | 953 |
#endif |
849 | 954 |
return ret; |
850 | 955 |
} |
851 | 956 |
|
957 |
/* memory mapped interrupt status */ |
|
958 |
uint32_t pic_intack_read(CPUState *env) |
|
959 |
{ |
|
960 |
int ret; |
|
961 |
|
|
962 |
ret = pic_poll_read(&pics[0], 0x00); |
|
963 |
if (ret == 2) |
|
964 |
ret = pic_poll_read(&pics[1], 0x80) + 8; |
|
965 |
/* Prepare for ISR read */ |
|
966 |
pics[0].read_reg_select = 1; |
|
967 |
|
|
968 |
return ret; |
|
969 |
} |
|
970 |
|
|
852 | 971 |
void pic_init(void) |
853 | 972 |
{ |
973 |
#if defined (TARGET_I386) || defined (TARGET_PPC) |
|
854 | 974 |
register_ioport_write(0x20, 2, pic_ioport_write, 1); |
855 | 975 |
register_ioport_read(0x20, 2, pic_ioport_read, 1); |
856 | 976 |
register_ioport_write(0xa0, 2, pic_ioport_write, 1); |
857 | 977 |
register_ioport_read(0xa0, 2, pic_ioport_read, 1); |
978 |
#endif |
|
858 | 979 |
} |
859 | 980 |
|
860 | 981 |
/***********************************************************/ |
... | ... | |
1140 | 1261 |
} |
1141 | 1262 |
} |
1142 | 1263 |
|
1143 |
void pit_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
|
|
1264 |
void pit_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
|
1144 | 1265 |
{ |
1145 | 1266 |
int channel, access; |
1146 | 1267 |
PITChannelState *s; |
... | ... | |
1185 | 1306 |
} |
1186 | 1307 |
} |
1187 | 1308 |
|
1188 |
uint32_t pit_ioport_read(CPUX86State *env, uint32_t addr)
|
|
1309 |
uint32_t pit_ioport_read(CPUState *env, uint32_t addr) |
|
1189 | 1310 |
{ |
1190 | 1311 |
int ret, count; |
1191 | 1312 |
PITChannelState *s; |
... | ... | |
1218 | 1339 |
return ret; |
1219 | 1340 |
} |
1220 | 1341 |
|
1221 |
void speaker_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) |
|
1342 |
#if defined (TARGET_I386) |
|
1343 |
void speaker_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
|
1222 | 1344 |
{ |
1223 | 1345 |
speaker_data_on = (val >> 1) & 1; |
1224 | 1346 |
pit_set_gate(&pit_channels[2], val & 1); |
1225 | 1347 |
} |
1226 | 1348 |
|
1227 |
uint32_t speaker_ioport_read(CPUX86State *env, uint32_t addr)
|
|
1349 |
uint32_t speaker_ioport_read(CPUState *env, uint32_t addr) |
|
1228 | 1350 |
{ |
1229 | 1351 |
int out; |
1230 | 1352 |
out = pit_get_out(&pit_channels[2]); |
... | ... | |
1232 | 1354 |
return (speaker_data_on << 1) | pit_channels[2].gate | (out << 5) | |
1233 | 1355 |
(dummy_refresh_clock << 4); |
1234 | 1356 |
} |
1357 |
#endif |
|
1235 | 1358 |
|
1236 | 1359 |
void pit_init(void) |
1237 | 1360 |
{ |
... | ... | |
1250 | 1373 |
register_ioport_write(0x40, 4, pit_ioport_write, 1); |
1251 | 1374 |
register_ioport_read(0x40, 3, pit_ioport_read, 1); |
1252 | 1375 |
|
1376 |
#if defined (TARGET_I386) |
|
1253 | 1377 |
register_ioport_read(0x61, 1, speaker_ioport_read, 1); |
1254 | 1378 |
register_ioport_write(0x61, 1, speaker_ioport_write, 1); |
1379 |
#endif |
|
1255 | 1380 |
} |
1256 | 1381 |
|
1257 | 1382 |
/***********************************************************/ |
... | ... | |
1339 | 1464 |
} |
1340 | 1465 |
} |
1341 | 1466 |
|
1342 |
void serial_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
|
|
1467 |
void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
|
1343 | 1468 |
{ |
1344 | 1469 |
SerialState *s = &serial_ports[0]; |
1345 | 1470 |
unsigned char ch; |
... | ... | |
1396 | 1521 |
} |
1397 | 1522 |
} |
1398 | 1523 |
|
1399 |
uint32_t serial_ioport_read(CPUX86State *env, uint32_t addr)
|
|
1524 |
uint32_t serial_ioport_read(CPUState *env, uint32_t addr) |
|
1400 | 1525 |
{ |
1401 | 1526 |
SerialState *s = &serial_ports[0]; |
1402 | 1527 |
uint32_t ret; |
... | ... | |
1458 | 1583 |
} |
1459 | 1584 |
|
1460 | 1585 |
#define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */ |
1461 |
static int term_got_escape; |
|
1586 |
static int term_got_escape, term_command; |
|
1587 |
static unsigned char term_cmd_buf[128]; |
|
1588 |
|
|
1589 |
typedef struct term_cmd_t { |
|
1590 |
const unsigned char *name; |
|
1591 |
void (*handler)(unsigned char *params); |
|
1592 |
} term_cmd_t; |
|
1593 |
|
|
1594 |
static void do_change_cdrom (unsigned char *params); |
|
1595 |
static void do_change_fd0 (unsigned char *params); |
|
1596 |
static void do_change_fd1 (unsigned char *params); |
|
1597 |
|
|
1598 |
static term_cmd_t term_cmds[] = { |
|
1599 |
{ "changecd", &do_change_cdrom, }, |
|
1600 |
{ "changefd0", &do_change_fd0, }, |
|
1601 |
{ "changefd1", &do_change_fd1, }, |
|
1602 |
{ NULL, NULL, }, |
|
1603 |
}; |
|
1462 | 1604 |
|
1463 | 1605 |
void term_print_help(void) |
1464 | 1606 |
{ |
1465 | 1607 |
printf("\n" |
1466 | 1608 |
"C-a h print this help\n" |
1467 | 1609 |
"C-a x exit emulatior\n" |
1610 |
"C-a d switch on/off debug log\n" |
|
1468 | 1611 |
"C-a s save disk data back to file (if -snapshot)\n" |
1469 | 1612 |
"C-a b send break (magic sysrq)\n" |
1613 |
"C-a c send qemu internal command\n" |
|
1470 | 1614 |
"C-a C-a send C-a\n" |
1471 | 1615 |
); |
1472 | 1616 |
} |
1473 | 1617 |
|
1618 |
static void do_change_cdrom (unsigned char *params) |
|
1619 |
{ |
|
1620 |
/* Dunno how to do it... */ |
|
1621 |
} |
|
1622 |
|
|
1623 |
static void do_change_fd (int fd, unsigned char *params) |
|
1624 |
{ |
|
1625 |
unsigned char *name_start, *name_end, *ros; |
|
1626 |
int ro; |
|
1627 |
|
|
1628 |
for (name_start = params; |
|
1629 |
isspace(*name_start); name_start++) |
|
1630 |
continue; |
|
1631 |
if (*name_start == '\0') |
|
1632 |
return; |
|
1633 |
for (name_end = name_start; |
|
1634 |
!isspace(*name_end) && *name_end != '\0'; name_end++) |
|
1635 |
continue; |
|
1636 |
for (ros = name_end + 1; isspace(*ros); ros++) |
|
1637 |
continue; |
|
1638 |
if (ros[0] == 'r' && ros[1] == 'o') |
|
1639 |
ro = 1; |
|
1640 |
else |
|
1641 |
ro = 0; |
|
1642 |
*name_end = '\0'; |
|
1643 |
printf("Change fd %d to %s (%s)\n", fd, name_start, params); |
|
1644 |
fdctrl_disk_change(fd, name_start, ro); |
|
1645 |
} |
|
1646 |
|
|
1647 |
static void do_change_fd0 (unsigned char *params) |
|
1648 |
{ |
|
1649 |
do_change_fd(0, params); |
|
1650 |
} |
|
1651 |
|
|
1652 |
static void do_change_fd1 (unsigned char *params) |
|
1653 |
{ |
|
1654 |
do_change_fd(1, params); |
|
1655 |
} |
|
1656 |
|
|
1657 |
static void serial_treat_command () |
|
1658 |
{ |
|
1659 |
unsigned char *cmd_start, *cmd_end; |
|
1660 |
int i; |
|
1661 |
|
|
1662 |
for (cmd_start = term_cmd_buf; isspace(*cmd_start); cmd_start++) |
|
1663 |
continue; |
|
1664 |
for (cmd_end = cmd_start; |
|
1665 |
!isspace(*cmd_end) && *cmd_end != '\0'; cmd_end++) |
|
1666 |
continue; |
|
1667 |
for (i = 0; term_cmds[i].name != NULL; i++) { |
|
1668 |
if (strlen(term_cmds[i].name) == (cmd_end - cmd_start) && |
|
1669 |
memcmp(term_cmds[i].name, cmd_start, cmd_end - cmd_start) == 0) { |
|
1670 |
(*term_cmds[i].handler)(cmd_end + 1); |
|
1671 |
return; |
|
1672 |
} |
|
1673 |
} |
|
1674 |
*cmd_end = '\0'; |
|
1675 |
printf("Unknown term command: %s\n", cmd_start); |
|
1676 |
} |
|
1677 |
|
|
1678 |
extern FILE *logfile; |
|
1679 |
|
|
1474 | 1680 |
/* called when a char is received */ |
1475 | 1681 |
void serial_received_byte(SerialState *s, int ch) |
1476 | 1682 |
{ |
1477 |
if (term_got_escape) { |
|
1683 |
if (term_command) { |
|
1684 |
if (ch == '\n' || ch == '\r' || term_command == 127) { |
|
1685 |
printf("\n"); |
|
1686 |
serial_treat_command(); |
|
1687 |
term_command = 0; |
|
1688 |
} else { |
|
1689 |
if (ch == 0x7F || ch == 0x08) { |
|
1690 |
if (term_command > 1) { |
|
1691 |
term_cmd_buf[--term_command - 1] = '\0'; |
|
1692 |
printf("\r " |
|
1693 |
" "); |
|
1694 |
printf("\r> %s", term_cmd_buf); |
|
1695 |
} |
|
1696 |
} else if (ch > 0x1f) { |
|
1697 |
term_cmd_buf[term_command++ - 1] = ch; |
|
1698 |
term_cmd_buf[term_command - 1] = '\0'; |
|
1699 |
printf("\r> %s", term_cmd_buf); |
|
1700 |
} |
|
1701 |
fflush(stdout); |
|
1702 |
} |
|
1703 |
} else if (term_got_escape) { |
|
1478 | 1704 |
term_got_escape = 0; |
1479 | 1705 |
switch(ch) { |
1480 | 1706 |
case 'h': |
... | ... | |
1498 | 1724 |
s->lsr |= UART_LSR_BI | UART_LSR_DR; |
1499 | 1725 |
serial_update_irq(); |
1500 | 1726 |
break; |
1501 |
case 'd': |
|
1502 |
cpu_set_log(CPU_LOG_ALL); |
|
1727 |
case 'c': |
|
1728 |
printf("> "); |
|
1729 |
fflush(stdout); |
|
1730 |
term_command = 1; |
|
1503 | 1731 |
break; |
1504 | 1732 |
case TERM_ESCAPE: |
1505 | 1733 |
goto send_char; |
... | ... | |
1521 | 1749 |
s->lsr = UART_LSR_TEMT | UART_LSR_THRE; |
1522 | 1750 |
s->iir = UART_IIR_NO_INT; |
1523 | 1751 |
|
1752 |
#if defined(TARGET_I386) || defined (TARGET_PPC) |
|
1524 | 1753 |
register_ioport_write(0x3f8, 8, serial_ioport_write, 1); |
1525 | 1754 |
register_ioport_read(0x3f8, 8, serial_ioport_read, 1); |
1755 |
#endif |
|
1526 | 1756 |
} |
1527 | 1757 |
|
1528 | 1758 |
/***********************************************************/ |
1529 | 1759 |
/* ne2000 emulation */ |
1530 | 1760 |
|
1761 |
#if defined (TARGET_I386) |
|
1531 | 1762 |
#define NE2000_IOPORT 0x300 |
1532 | 1763 |
#define NE2000_IRQ 9 |
1533 | 1764 |
|
... | ... | |
1775 | 2006 |
ne2000_update_irq(s); |
1776 | 2007 |
} |
1777 | 2008 |
|
1778 |
void ne2000_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
|
|
2009 |
void ne2000_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
|
1779 | 2010 |
{ |
1780 | 2011 |
NE2000State *s = &ne2000_state; |
1781 | 2012 |
int offset, page; |
... | ... | |
1860 | 2091 |
} |
1861 | 2092 |
} |
1862 | 2093 |
|
1863 |
uint32_t ne2000_ioport_read(CPUX86State *env, uint32_t addr)
|
|
2094 |
uint32_t ne2000_ioport_read(CPUState *env, uint32_t addr) |
|
1864 | 2095 |
{ |
1865 | 2096 |
NE2000State *s = &ne2000_state; |
1866 | 2097 |
int offset, page, ret; |
... | ... | |
1901 | 2132 |
return ret; |
1902 | 2133 |
} |
1903 | 2134 |
|
1904 |
void ne2000_asic_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
|
|
2135 |
void ne2000_asic_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
|
1905 | 2136 |
{ |
1906 | 2137 |
NE2000State *s = &ne2000_state; |
1907 | 2138 |
uint8_t *p; |
... | ... | |
1932 | 2163 |
} |
1933 | 2164 |
} |
1934 | 2165 |
|
1935 |
uint32_t ne2000_asic_ioport_read(CPUX86State *env, uint32_t addr)
|
|
2166 |
uint32_t ne2000_asic_ioport_read(CPUState *env, uint32_t addr) |
|
1936 | 2167 |
{ |
1937 | 2168 |
NE2000State *s = &ne2000_state; |
1938 | 2169 |
uint8_t *p; |
... | ... | |
1964 | 2195 |
return ret; |
1965 | 2196 |
} |
1966 | 2197 |
|
1967 |
void ne2000_reset_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
|
|
2198 |
void ne2000_reset_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
|
1968 | 2199 |
{ |
1969 | 2200 |
/* nothing to do (end of reset pulse) */ |
1970 | 2201 |
} |
1971 | 2202 |
|
1972 |
uint32_t ne2000_reset_ioport_read(CPUX86State *env, uint32_t addr)
|
|
2203 |
uint32_t ne2000_reset_ioport_read(CPUState *env, uint32_t addr) |
|
1973 | 2204 |
{ |
1974 | 2205 |
ne2000_reset(); |
1975 | 2206 |
return 0; |
... | ... | |
1989 | 2220 |
register_ioport_read(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_read, 1); |
1990 | 2221 |
ne2000_reset(); |
1991 | 2222 |
} |
2223 |
#endif |
|
2224 |
|
|
2225 |
/***********************************************************/ |
|
2226 |
/* PC floppy disk controler emulation glue */ |
|
2227 |
#define PC_FDC_DMA 0x2 |
|
2228 |
#define PC_FDC_IRQ 0x6 |
|
2229 |
#define PC_FDC_BASE 0x3F0 |
|
2230 |
|
|
2231 |
static void fdctrl_register (unsigned char **disknames, int ro, |
|
2232 |
char boot_device) |
|
2233 |
{ |
|
2234 |
int i; |
|
2235 |
|
|
2236 |
fdctrl_init(PC_FDC_IRQ, PC_FDC_DMA, 0, PC_FDC_BASE, boot_device); |
|
2237 |
for (i = 0; i < MAX_FD; i++) { |
|
2238 |
if (disknames[i] != NULL) |
|
2239 |
fdctrl_disk_change(i, disknames[i], ro); |
|
2240 |
} |
|
2241 |
} |
|
1992 | 2242 |
|
1993 | 2243 |
/***********************************************************/ |
1994 | 2244 |
/* keyboard emulation */ |
... | ... | |
2158 | 2408 |
kbd_queue(s, keycode, 0); |
2159 | 2409 |
} |
2160 | 2410 |
|
2161 |
uint32_t kbd_read_status(CPUX86State *env, uint32_t addr)
|
|
2411 |
uint32_t kbd_read_status(CPUState *env, uint32_t addr) |
|
2162 | 2412 |
{ |
2163 | 2413 |
KBDState *s = &kbd_state; |
2164 | 2414 |
int val; |
2165 | 2415 |
val = s->status; |
2166 |
#if defined(DEBUG_KBD) && 0
|
|
2416 |
#if defined(DEBUG_KBD) |
|
2167 | 2417 |
printf("kbd: read status=0x%02x\n", val); |
2168 | 2418 |
#endif |
2169 | 2419 |
return val; |
2170 | 2420 |
} |
2171 | 2421 |
|
2172 |
void kbd_write_command(CPUX86State *env, uint32_t addr, uint32_t val)
|
|
2422 |
void kbd_write_command(CPUState *env, uint32_t addr, uint32_t val) |
|
2173 | 2423 |
{ |
2174 | 2424 |
KBDState *s = &kbd_state; |
2175 | 2425 |
|
... | ... | |
2216 | 2466 |
break; |
2217 | 2467 |
case KBD_CCMD_READ_OUTPORT: |
2218 | 2468 |
/* XXX: check that */ |
2469 |
#ifdef TARGET_I386 |
|
2219 | 2470 |
val = 0x01 | (a20_enabled << 1); |
2471 |
#else |
|
2472 |
val = 0x01; |
|
2473 |
#endif |
|
2220 | 2474 |
if (s->status & KBD_STAT_OBF) |
2221 | 2475 |
val |= 0x10; |
2222 | 2476 |
if (s->status & KBD_STAT_MOUSE_OBF) |
2223 | 2477 |
val |= 0x20; |
2224 | 2478 |
kbd_queue(s, val, 0); |
2225 | 2479 |
break; |
2480 |
#ifdef TARGET_I386 |
|
2226 | 2481 |
case KBD_CCMD_ENABLE_A20: |
2227 | 2482 |
cpu_x86_set_a20(env, 1); |
2228 | 2483 |
break; |
2229 | 2484 |
case KBD_CCMD_DISABLE_A20: |
2230 | 2485 |
cpu_x86_set_a20(env, 0); |
2231 | 2486 |
break; |
2487 |
#endif |
|
2232 | 2488 |
case KBD_CCMD_RESET: |
2233 | 2489 |
reset_requested = 1; |
2234 |
cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT);
|
|
2490 |
cpu_interrupt(global_env, CPU_INTERRUPT_EXIT); |
|
2235 | 2491 |
break; |
2236 | 2492 |
case 0xff: |
2237 | 2493 |
/* ignore that - I don't know what is its use */ |
... | ... | |
2242 | 2498 |
} |
2243 | 2499 |
} |
2244 | 2500 |
|
2245 |
uint32_t kbd_read_data(CPUX86State *env, uint32_t addr)
|
|
2501 |
uint32_t kbd_read_data(CPUState *env, uint32_t addr) |
|
2246 | 2502 |
{ |
2247 | 2503 |
KBDState *s = &kbd_state; |
2248 | 2504 |
KBDQueue *q; |
... | ... | |
2543 | 2799 |
} |
2544 | 2800 |
} |
2545 | 2801 |
|
2546 |
void kbd_write_data(CPUX86State *env, uint32_t addr, uint32_t val)
|
|
2802 |
void kbd_write_data(CPUState *env, uint32_t addr, uint32_t val) |
|
2547 | 2803 |
{ |
2548 | 2804 |
KBDState *s = &kbd_state; |
2549 | 2805 |
|
... | ... | |
2566 | 2822 |
kbd_queue(s, val, 1); |
2567 | 2823 |
break; |
2568 | 2824 |
case KBD_CCMD_WRITE_OUTPORT: |
2825 |
#ifdef TARGET_I386 |
|
2569 | 2826 |
cpu_x86_set_a20(env, (val >> 1) & 1); |
2827 |
#endif |
|
2570 | 2828 |
if (!(val & 1)) { |
2571 | 2829 |
reset_requested = 1; |
2572 |
cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT);
|
|
2830 |
cpu_interrupt(global_env, CPU_INTERRUPT_EXIT); |
|
2573 | 2831 |
} |
2574 | 2832 |
break; |
2575 | 2833 |
case KBD_CCMD_WRITE_MOUSE: |
... | ... | |
2601 | 2859 |
void kbd_init(void) |
2602 | 2860 |
{ |
2603 | 2861 |
kbd_reset(&kbd_state); |
2862 |
#if defined (TARGET_I386) || defined (TARGET_PPC) |
|
2604 | 2863 |
register_ioport_read(0x60, 1, kbd_read_data, 1); |
2605 | 2864 |
register_ioport_write(0x60, 1, kbd_write_data, 1); |
2606 | 2865 |
register_ioport_read(0x64, 1, kbd_read_status, 1); |
2607 | 2866 |
register_ioport_write(0x64, 1, kbd_write_command, 1); |
2867 |
#endif |
|
2608 | 2868 |
} |
2609 | 2869 |
|
2610 | 2870 |
/***********************************************************/ |
2611 | 2871 |
/* Bochs BIOS debug ports */ |
2612 |
|
|
2872 |
#ifdef TARGET_I386 |
|
2613 | 2873 |
void bochs_bios_write(CPUX86State *env, uint32_t addr, uint32_t val) |
2614 | 2874 |
{ |
2615 | 2875 |
switch(addr) { |
... | ... | |
2651 | 2911 |
register_ioport_write(0x500, 1, bochs_bios_write, 1); |
2652 | 2912 |
register_ioport_write(0x503, 1, bochs_bios_write, 1); |
2653 | 2913 |
} |
2914 |
#endif |
|
2654 | 2915 |
|
2655 | 2916 |
/***********************************************************/ |
2656 | 2917 |
/* dumb display */ |
... | ... | |
2756 | 3017 |
|
2757 | 3018 |
if (gui_refresh_pending || timer_irq_pending) { |
2758 | 3019 |
/* just exit from the cpu to have a chance to handle timers */ |
2759 |
cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT);
|
|
3020 |
cpu_interrupt(global_env, CPU_INTERRUPT_EXIT); |
|
2760 | 3021 |
} |
2761 | 3022 |
} |
2762 | 3023 |
|
... | ... | |
2786 | 3047 |
|
2787 | 3048 |
int main_loop(void *opaque) |
2788 | 3049 |
{ |
2789 |
struct pollfd ufds[3], *pf, *serial_ufd, *net_ufd, *gdb_ufd; |
|
3050 |
struct pollfd ufds[3], *pf, *serial_ufd, *gdb_ufd; |
|
3051 |
#if defined (TARGET_I386) |
|
3052 |
struct pollfd *net_ufd; |
|
3053 |
#endif |
|
2790 | 3054 |
int ret, n, timeout, serial_ok; |
2791 | 3055 |
uint8_t ch; |
2792 | 3056 |
CPUState *env = global_env; |
... | ... | |
2802 | 3066 |
serial_ok = 1; |
2803 | 3067 |
cpu_enable_ticks(); |
2804 | 3068 |
for(;;) { |
2805 |
ret = cpu_x86_exec(env); |
|
3069 |
#if defined (DO_TB_FLUSH) |
|
3070 |
tb_flush(); |
|
3071 |
#endif |
|
3072 |
ret = cpu_exec(env); |
|
2806 | 3073 |
if (reset_requested) { |
2807 | 3074 |
ret = EXCP_INTERRUPT; |
2808 | 3075 |
break; |
... | ... | |
2825 | 3092 |
pf->events = POLLIN; |
2826 | 3093 |
pf++; |
2827 | 3094 |
} |
3095 |
#if defined (TARGET_I386) |
|
2828 | 3096 |
net_ufd = NULL; |
2829 | 3097 |
if (net_fd > 0 && ne2000_can_receive(&ne2000_state)) { |
2830 | 3098 |
net_ufd = pf; |
... | ... | |
2832 | 3100 |
pf->events = POLLIN; |
2833 | 3101 |
pf++; |
2834 | 3102 |
} |
3103 |
#endif |
|
2835 | 3104 |
gdb_ufd = NULL; |
2836 | 3105 |
if (gdbstub_fd > 0) { |
2837 | 3106 |
gdb_ufd = pf; |
... | ... | |
2851 | 3120 |
serial_ok = 0; |
2852 | 3121 |
} |
2853 | 3122 |
} |
3123 |
#if defined (TARGET_I386) |
|
2854 | 3124 |
if (net_ufd && (net_ufd->revents & POLLIN)) { |
2855 | 3125 |
uint8_t buf[MAX_ETH_FRAME_SIZE]; |
2856 | 3126 |
|
... | ... | |
2863 | 3133 |
ne2000_receive(&ne2000_state, buf, n); |
2864 | 3134 |
} |
2865 | 3135 |
} |
3136 |
#endif |
|
2866 | 3137 |
if (gdb_ufd && (gdb_ufd->revents & POLLIN)) { |
2867 | 3138 |
uint8_t buf[1]; |
2868 | 3139 |
/* stop emulation if requested by gdb */ |
... | ... | |
2876 | 3147 |
|
2877 | 3148 |
/* timer IRQ */ |
2878 | 3149 |
if (timer_irq_pending) { |
3150 |
#if defined (TARGET_I386) |
|
2879 | 3151 |
pic_set_irq(0, 1); |
2880 | 3152 |
pic_set_irq(0, 0); |
2881 | 3153 |
timer_irq_pending = 0; |
... | ... | |
2883 | 3155 |
if (cmos_data[RTC_REG_B] & 0x50) { |
2884 | 3156 |
pic_set_irq(8, 1); |
2885 | 3157 |
} |
3158 |
#endif |
|
2886 | 3159 |
} |
2887 | 3160 |
|
2888 | 3161 |
/* VGA */ |
... | ... | |
2903 | 3176 |
"'disk_image' is a raw hard image image for IDE hard disk 0\n" |
2904 | 3177 |
"\n" |
2905 | 3178 |
"Standard options:\n" |
3179 |
"-fda/-fdb file use 'file' as floppy disk 0/1 image\n" |
|
2906 | 3180 |
"-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n" |
2907 | 3181 |
"-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n" |
2908 | 3182 |
"-cdrom file use 'file' as IDE cdrom 2 image\n" |
... | ... | |
2957 | 3231 |
{ "hdd", 1, NULL, 0, }, |
2958 | 3232 |
{ "cdrom", 1, NULL, 0, }, |
2959 | 3233 |
{ "boot", 1, NULL, 0, }, |
3234 |
{ "fda", 1, NULL, 0, }, |
|
3235 |
{ "fdb", 1, NULL, 0, }, |
|
2960 | 3236 |
{ NULL, 0, NULL, 0 }, |
2961 | 3237 |
}; |
2962 | 3238 |
|
... | ... | |
2976 | 3252 |
{ |
2977 | 3253 |
int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index; |
2978 | 3254 |
int snapshot, linux_boot, total_ram_size; |
3255 |
#if defined (TARGET_I386) |
|
2979 | 3256 |
struct linux_params *params; |
3257 |
#endif |
|
2980 | 3258 |
struct sigaction act; |
2981 | 3259 |
struct itimerval itv; |
2982 |
CPUX86State *env;
|
|
3260 |
CPUState *env; |
|
2983 | 3261 |
const char *initrd_filename; |
2984 |
const char *hd_filename[MAX_DISKS]; |
|
3262 |
const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
|
|
2985 | 3263 |
const char *kernel_filename, *kernel_cmdline; |
2986 | 3264 |
DisplayState *ds = &display_state; |
2987 | 3265 |
|
2988 | 3266 |
/* we never want that malloc() uses mmap() */ |
2989 | 3267 |
mallopt(M_MMAP_THRESHOLD, 4096 * 1024); |
2990 | 3268 |
initrd_filename = NULL; |
3269 |
for(i = 0; i < MAX_FD; i++) |
|
3270 |
fd_filename[i] = NULL; |
|
2991 | 3271 |
for(i = 0; i < MAX_DISKS; i++) |
2992 | 3272 |
hd_filename[i] = NULL; |
2993 | 3273 |
phys_ram_size = 32 * 1024 * 1024; |
2994 | 3274 |
vga_ram_size = VGA_RAM_SIZE; |
3275 |
#if defined (TARGET_I386) |
|
2995 | 3276 |
pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT); |
3277 |
#endif |
|
2996 | 3278 |
use_gdbstub = 0; |
2997 | 3279 |
gdbstub_port = DEFAULT_GDBSTUB_PORT; |
2998 | 3280 |
snapshot = 0; |
... | ... | |
3047 | 3329 |
case 7: |
3048 | 3330 |
kernel_cmdline = optarg; |
3049 | 3331 |
break; |
3332 |
#if defined (TARGET_I386) |
|
3050 | 3333 |
case 8: |
3051 | 3334 |
net_fd = atoi(optarg); |
3052 | 3335 |
break; |
3336 |
#endif |
|
3053 | 3337 |
case 9: |
3054 | 3338 |
hd_filename[2] = optarg; |
3055 | 3339 |
break; |
... | ... | |
3062 | 3346 |
break; |
3063 | 3347 |
case 12: |
3064 | 3348 |
boot_device = optarg[0]; |
3065 |
if (boot_device != 'c' && boot_device != 'd') { |
|
3349 |
if (boot_device != 'a' && boot_device != 'b' && |
|
3350 |
boot_device != 'c' && boot_device != 'd') { |
|
3066 | 3351 |
fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device); |
3067 | 3352 |
exit(1); |
3068 | 3353 |
} |
3069 | 3354 |
break; |
3355 |
case 13: |
|
3356 |
fd_filename[0] = optarg; |
|
3357 |
break; |
|
3358 |
case 14: |
|
3359 |
fd_filename[1] = optarg; |
|
3360 |
break; |
|
3070 | 3361 |
} |
3071 | 3362 |
break; |
3072 | 3363 |
case 'h': |
... | ... | |
3085 | 3376 |
case 'd': |
3086 | 3377 |
cpu_set_log(CPU_LOG_ALL); |
3087 | 3378 |
break; |
3379 |
#if defined (TARGET_I386) |
|
3088 | 3380 |
case 'n': |
3089 | 3381 |
pstrcpy(network_script, sizeof(network_script), optarg); |
3090 | 3382 |
break; |
3383 |
#endif |
|
3091 | 3384 |
case 's': |
3092 | 3385 |
use_gdbstub = 1; |
3093 | 3386 |
break; |
... | ... | |
3106 | 3399 |
|
3107 | 3400 |
linux_boot = (kernel_filename != NULL); |
3108 | 3401 |
|
3109 |
if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0') |
|
3402 |
if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0' && |
|
3403 |
fd_filename[0] == '\0') |
|
3110 | 3404 |
help(); |
3111 | 3405 |
|
3112 | 3406 |
/* boot to cd by default if no hard disk */ |
... | ... | |
3124 | 3418 |
#endif |
3125 | 3419 |
|
3126 | 3420 |
/* init network tun interface */ |
3421 |
#if defined (TARGET_I386) |
|
3127 | 3422 |
if (net_fd < 0) |
3128 | 3423 |
net_init(); |
3424 |
#endif |
|
3129 | 3425 |
|
3130 | 3426 |
/* init the memory */ |
3131 | 3427 |
total_ram_size = phys_ram_size + vga_ram_size; |
... | ... | |
3213 | 3509 |
} |
3214 | 3510 |
|
3215 | 3511 |
/* init kernel params */ |
3512 |
#ifdef TARGET_I386 |
|
3216 | 3513 |
params = (void *)(phys_ram_base + KERNEL_PARAMS_ADDR); |
3217 | 3514 |
memset(params, 0, sizeof(struct linux_params)); |
3218 | 3515 |
params->mount_root_rdonly = 0; |
... | ... | |
3256 | 3553 |
env->eip = KERNEL_LOAD_ADDR; |
3257 | 3554 |
env->regs[R_ESI] = KERNEL_PARAMS_ADDR; |
3258 | 3555 |
env->eflags = 0x2; |
3259 |
|
|
3556 |
#elif defined (TARGET_PPC) |
|
3557 |
cpu_x86_init_mmu(env); |
|
3558 |
PPC_init_hw(env, phys_ram_size, KERNEL_LOAD_ADDR, ret, |
|
3559 |
KERNEL_STACK_ADDR, boot_device); |
|
3560 |
#endif |
|
3260 | 3561 |
} else { |
3261 | 3562 |
char buf[1024]; |
3262 | 3563 |
|
3263 | 3564 |
/* RAW PC boot */ |
3264 |
|
|
3565 |
#if defined(TARGET_I386) |
|
3265 | 3566 |
/* BIOS load */ |
3266 | 3567 |
snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME); |
3267 | 3568 |
ret = load_image(buf, phys_ram_base + 0x000f0000); |
... | ... | |
3302 | 3603 |
env->eflags = 0x2; |
3303 | 3604 |
|
3304 | 3605 |
bochs_bios_init(); |
3606 |
#elif defined(TARGET_PPC) |
|
3607 |
cpu_x86_init_mmu(env); |
|
3608 |
/* allocate ROM */ |
|
3609 |
// snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME); |
|
3610 |
snprintf(buf, sizeof(buf), "%s", BIOS_FILENAME); |
|
3611 |
printf("load BIOS at %p\n", phys_ram_base + 0x000f0000); |
|
3612 |
ret = load_image(buf, phys_ram_base + 0x000f0000); |
|
3613 |
if (ret != 0x10000) { |
|
3614 |
fprintf(stderr, "qemu: could not load PPC bios '%s' (%d)\n%m\n", |
|
3615 |
buf, ret); |
|
3616 |
exit(1); |
|
3617 |
} |
|
3618 |
#endif |
|
3305 | 3619 |
} |
3306 | 3620 |
|
3307 | 3621 |
/* terminal init */ |
... | ... | |
3317 | 3631 |
/* init basic PC hardware */ |
3318 | 3632 |
register_ioport_write(0x80, 1, ioport80_write, 1); |
3319 | 3633 |
|
3320 |
vga_init(ds, phys_ram_base + phys_ram_size, phys_ram_size, |
|
3634 |
vga_initialize(ds, phys_ram_base + phys_ram_size, phys_ram_size,
|
|
3321 | 3635 |
vga_ram_size); |
3636 |
#if defined (TARGET_I386) |
|
3322 | 3637 |
cmos_init(); |
3638 |
#endif |
|
3323 | 3639 |
pic_init(); |
3324 | 3640 |
pit_init(); |
3325 | 3641 |
serial_init(); |
3642 |
#if defined (TARGET_I386) |
|
3326 | 3643 |
ne2000_init(); |
3644 |
#endif |
|
3327 | 3645 |
ide_init(); |
3328 | 3646 |
kbd_init(); |
3329 | 3647 |
AUD_init(); |
3330 | 3648 |
DMA_init(); |
3649 |
#if defined (TARGET_I386) |
|
3331 | 3650 |
SB16_init(); |
3332 |
|
|
3651 |
#endif |
|
3652 |
#if defined (TARGET_PPC) |
|
3653 |
PPC_end_init(); |
|
3654 |
#endif |
|
3655 |
fdctrl_register((unsigned char **)fd_filename, snapshot, boot_device); |
|
3333 | 3656 |
/* setup cpu signal handlers for MMU / self modifying code handling */ |
3334 | 3657 |
sigfillset(&act.sa_mask); |
3335 | 3658 |
act.sa_flags = SA_SIGINFO; |
Also available in: Unified diff