Commit c45886db19fb117a8ad8a5118572d23a957e5de5
1 parent
ffa65c3b
PowerPC system emulation (Jocelyn Mayer) - PIC poll mode (Jocelyn Mayer) - use C…
…PUState - Floppy support (Jocelyn Mayer) - command line debug (Jocelyn Mayer) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@539 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
382 additions
and
59 deletions
vl.c
... | ... | @@ -25,6 +25,7 @@ |
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,7 +81,18 @@ |
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,11 +218,11 @@ struct __attribute__ ((packed)) linux_params { |
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,7 +233,7 @@ int boot_device = 'c'; |
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,7 +241,7 @@ uint32_t default_ioport_readb(CPUX86State *env, uint32_t 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,7 +249,7 @@ void default_ioport_writeb(CPUX86State *env, uint32_t address, uint32_t 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,13 +257,13 @@ uint32_t default_ioport_readw(CPUX86State *env, uint32_t 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,7 +271,7 @@ uint32_t default_ioport_readl(CPUX86State *env, uint32_t 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,12 +357,18 @@ char *pstrcat(char *buf, int buf_size, const char *s) |
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,6 +376,7 @@ int load_kernel(const char *filename, uint8_t *addr) |
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,38 +404,38 @@ int load_image(const char *filename, uint8_t *addr) |
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,6 +449,8 @@ void hw_error(const char *fmt, ...) |
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,6 +459,7 @@ void hw_error(const char *fmt, ...) |
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,7 +485,7 @@ void hw_error(const char *fmt, ...) |
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,7 +525,7 @@ void cmos_ioport_write(CPUX86State *env, uint32_t addr, uint32_t data) |
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,6 +602,7 @@ void cmos_init(void) |
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,6 +618,56 @@ void cmos_init(void) |
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,6 +679,7 @@ typedef struct PicState { |
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,7 +737,7 @@ static int pic_get_irq(PicState *s) |
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,7 +758,7 @@ static void pic_update_irq(void) |
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,7 +787,7 @@ void pic_set_irq(int irq, int level) |
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,7 +816,7 @@ int cpu_x86_get_pic_interrupt(CPUX86State *env) |
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,10 +837,14 @@ void pic_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) |
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,7 +904,29 @@ void pic_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) |
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,6 +935,10 @@ uint32_t pic_ioport_read(CPUX86State *env, uint32_t addr1) |
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,18 +947,35 @@ uint32_t pic_ioport_read(CPUX86State *env, uint32_t addr1) |
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,7 +1261,7 @@ static inline void pit_load_count(PITChannelState *s, int val) |
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,7 +1306,7 @@ void pit_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) |
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,13 +1339,14 @@ uint32_t pit_ioport_read(CPUX86State *env, uint32_t addr) |
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,6 +1354,7 @@ uint32_t speaker_ioport_read(CPUX86State *env, uint32_t addr) |
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,8 +1373,10 @@ void pit_init(void) |
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,7 +1464,7 @@ void serial_update_irq(void) |
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,7 +1521,7 @@ void serial_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) |
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,23 +1583,124 @@ uint32_t serial_ioport_read(CPUX86State *env, uint32_t addr) |
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,8 +1724,10 @@ void serial_received_byte(SerialState *s, int ch) |
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,13 +1749,16 @@ void serial_init(void) |
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,7 +2006,7 @@ void ne2000_receive(NE2000State *s, uint8_t *buf, int size) |
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,7 +2091,7 @@ void ne2000_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) |
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,7 +2132,7 @@ uint32_t ne2000_ioport_read(CPUX86State *env, uint32_t addr) |
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,7 +2163,7 @@ void ne2000_asic_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) |
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,12 +2195,12 @@ uint32_t ne2000_asic_ioport_read(CPUX86State *env, uint32_t addr) |
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,6 +2220,25 @@ void ne2000_init(void) |
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,18 +2408,18 @@ void kbd_put_keycode(int keycode) |
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,22 +2466,28 @@ void kbd_write_command(CPUX86State *env, uint32_t addr, uint32_t val) |
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,7 +2498,7 @@ void kbd_write_command(CPUX86State *env, uint32_t addr, uint32_t val) |
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,7 +2799,7 @@ static void kbd_write_mouse(KBDState *s, int val) |
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,10 +2822,12 @@ void kbd_write_data(CPUX86State *env, uint32_t addr, uint32_t val) |
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,15 +2859,17 @@ void kbd_reset(KBDState *s) |
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,6 +2911,7 @@ void bochs_bios_init(void) |
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,7 +3017,7 @@ static void host_alarm_handler(int host_signum, siginfo_t *info, |
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,7 +3047,10 @@ CPUState *cpu_gdbstub_get_env(void *opaque) |
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,7 +3066,10 @@ int main_loop(void *opaque) |
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,6 +3092,7 @@ int main_loop(void *opaque) |
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,6 +3100,7 @@ int main_loop(void *opaque) |
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,6 +3120,7 @@ int main_loop(void *opaque) |
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,6 +3133,7 @@ int main_loop(void *opaque) |
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,6 +3147,7 @@ int main_loop(void *opaque) |
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,6 +3155,7 @@ int main_loop(void *opaque) |
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,6 +3176,7 @@ void help(void) |
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,6 +3231,8 @@ struct option long_options[] = { |
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,23 +3252,29 @@ int main(int argc, char **argv) |
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,9 +3329,11 @@ int main(int argc, char **argv) |
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,11 +3346,18 @@ int main(int argc, char **argv) |
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,9 +3376,11 @@ int main(int argc, char **argv) |
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,7 +3399,8 @@ int main(int argc, char **argv) |
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,8 +3418,10 @@ int main(int argc, char **argv) |
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,6 +3509,7 @@ int main(int argc, char **argv) |
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,12 +3553,16 @@ int main(int argc, char **argv) |
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,6 +3603,19 @@ int main(int argc, char **argv) |
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,19 +3631,28 @@ int main(int argc, char **argv) |
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; | ... | ... |