Commit a09db21f711237d01375b64e6a4da676e88d4f37
1 parent
b671f9ed
Windows 2000 install disk full hack (original idea from Vladimir N. Oleynik)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1428 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
43 additions
and
3 deletions
Changelog
hw/ide.c
| @@ -332,6 +332,7 @@ typedef struct IDEState { | @@ -332,6 +332,7 @@ typedef struct IDEState { | ||
| 332 | uint8_t *data_ptr; | 332 | uint8_t *data_ptr; |
| 333 | uint8_t *data_end; | 333 | uint8_t *data_end; |
| 334 | uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; | 334 | uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; |
| 335 | + QEMUTimer *sector_write_timer; /* only used for win2k instal hack */ | ||
| 335 | } IDEState; | 336 | } IDEState; |
| 336 | 337 | ||
| 337 | #define BM_STATUS_DMAING 0x01 | 338 | #define BM_STATUS_DMAING 0x01 |
| @@ -645,6 +646,12 @@ static void ide_sector_read_dma(IDEState *s) | @@ -645,6 +646,12 @@ static void ide_sector_read_dma(IDEState *s) | ||
| 645 | ide_dma_start(s, ide_read_dma_cb); | 646 | ide_dma_start(s, ide_read_dma_cb); |
| 646 | } | 647 | } |
| 647 | 648 | ||
| 649 | +static void ide_sector_write_timer_cb(void *opaque) | ||
| 650 | +{ | ||
| 651 | + IDEState *s = opaque; | ||
| 652 | + ide_set_irq(s); | ||
| 653 | +} | ||
| 654 | + | ||
| 648 | static void ide_sector_write(IDEState *s) | 655 | static void ide_sector_write(IDEState *s) |
| 649 | { | 656 | { |
| 650 | int64_t sector_num; | 657 | int64_t sector_num; |
| @@ -670,7 +677,22 @@ static void ide_sector_write(IDEState *s) | @@ -670,7 +677,22 @@ static void ide_sector_write(IDEState *s) | ||
| 670 | ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write); | 677 | ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write); |
| 671 | } | 678 | } |
| 672 | ide_set_sector(s, sector_num + n); | 679 | ide_set_sector(s, sector_num + n); |
| 673 | - ide_set_irq(s); | 680 | + |
| 681 | +#ifdef TARGET_I386 | ||
| 682 | + if (win2k_install_hack) { | ||
| 683 | + /* It seems there is a bug in the Windows 2000 installer HDD | ||
| 684 | + IDE driver which fills the disk with empty logs when the | ||
| 685 | + IDE write IRQ comes too early. This hack tries to correct | ||
| 686 | + that at the expense of slower write performances. Use this | ||
| 687 | + option _only_ to install Windows 2000. You must disable it | ||
| 688 | + for normal use. */ | ||
| 689 | + qemu_mod_timer(s->sector_write_timer, | ||
| 690 | + qemu_get_clock(vm_clock) + (ticks_per_sec / 1000)); | ||
| 691 | + } else | ||
| 692 | +#endif | ||
| 693 | + { | ||
| 694 | + ide_set_irq(s); | ||
| 695 | + } | ||
| 674 | } | 696 | } |
| 675 | 697 | ||
| 676 | static int ide_write_dma_cb(IDEState *s, | 698 | static int ide_write_dma_cb(IDEState *s, |
| @@ -1939,6 +1961,8 @@ static void ide_init2(IDEState *ide_state, int irq, | @@ -1939,6 +1961,8 @@ static void ide_init2(IDEState *ide_state, int irq, | ||
| 1939 | } | 1961 | } |
| 1940 | s->drive_serial = drive_serial++; | 1962 | s->drive_serial = drive_serial++; |
| 1941 | s->irq = irq; | 1963 | s->irq = irq; |
| 1964 | + s->sector_write_timer = qemu_new_timer(vm_clock, | ||
| 1965 | + ide_sector_write_timer_cb, s); | ||
| 1942 | ide_reset(s); | 1966 | ide_reset(s); |
| 1943 | } | 1967 | } |
| 1944 | } | 1968 | } |
vl.c
| @@ -147,6 +147,9 @@ int full_screen = 0; | @@ -147,6 +147,9 @@ int full_screen = 0; | ||
| 147 | TextConsole *vga_console; | 147 | TextConsole *vga_console; |
| 148 | CharDriverState *serial_hds[MAX_SERIAL_PORTS]; | 148 | CharDriverState *serial_hds[MAX_SERIAL_PORTS]; |
| 149 | CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; | 149 | CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; |
| 150 | +#ifdef TARGET_I386 | ||
| 151 | +int win2k_install_hack = 0; | ||
| 152 | +#endif | ||
| 150 | 153 | ||
| 151 | /***********************************************************/ | 154 | /***********************************************************/ |
| 152 | /* x86 ISA bus support */ | 155 | /* x86 ISA bus support */ |
| @@ -933,7 +936,7 @@ static void init_timers(void) | @@ -933,7 +936,7 @@ static void init_timers(void) | ||
| 933 | 936 | ||
| 934 | /* timer signal */ | 937 | /* timer signal */ |
| 935 | sigfillset(&act.sa_mask); | 938 | sigfillset(&act.sa_mask); |
| 936 | - act.sa_flags = 0; | 939 | + act.sa_flags = 0; |
| 937 | #if defined (TARGET_I386) && defined(USE_CODE_COPY) | 940 | #if defined (TARGET_I386) && defined(USE_CODE_COPY) |
| 938 | act.sa_flags |= SA_ONSTACK; | 941 | act.sa_flags |= SA_ONSTACK; |
| 939 | #endif | 942 | #endif |
| @@ -2746,6 +2749,9 @@ void help(void) | @@ -2746,6 +2749,9 @@ void help(void) | ||
| 2746 | "-enable-audio enable audio support\n" | 2749 | "-enable-audio enable audio support\n" |
| 2747 | "-localtime set the real time clock to local time [default=utc]\n" | 2750 | "-localtime set the real time clock to local time [default=utc]\n" |
| 2748 | "-full-screen start in full screen\n" | 2751 | "-full-screen start in full screen\n" |
| 2752 | +#ifdef TARGET_I386 | ||
| 2753 | + "-win2k-hack use it when installing Windows 2000 to avoid a disk full bug\n" | ||
| 2754 | +#endif | ||
| 2749 | #ifdef TARGET_PPC | 2755 | #ifdef TARGET_PPC |
| 2750 | "-prep Simulate a PREP system (default is PowerMAC)\n" | 2756 | "-prep Simulate a PREP system (default is PowerMAC)\n" |
| 2751 | #endif | 2757 | #endif |
| @@ -2878,6 +2884,7 @@ enum { | @@ -2878,6 +2884,7 @@ enum { | ||
| 2878 | QEMU_OPTION_full_screen, | 2884 | QEMU_OPTION_full_screen, |
| 2879 | QEMU_OPTION_pidfile, | 2885 | QEMU_OPTION_pidfile, |
| 2880 | QEMU_OPTION_no_kqemu, | 2886 | QEMU_OPTION_no_kqemu, |
| 2887 | + QEMU_OPTION_win2k_hack, | ||
| 2881 | }; | 2888 | }; |
| 2882 | 2889 | ||
| 2883 | typedef struct QEMUOption { | 2890 | typedef struct QEMUOption { |
| @@ -2946,7 +2953,8 @@ const QEMUOption qemu_options[] = { | @@ -2946,7 +2953,8 @@ const QEMUOption qemu_options[] = { | ||
| 2946 | { "loadvm", HAS_ARG, QEMU_OPTION_loadvm }, | 2953 | { "loadvm", HAS_ARG, QEMU_OPTION_loadvm }, |
| 2947 | { "full-screen", 0, QEMU_OPTION_full_screen }, | 2954 | { "full-screen", 0, QEMU_OPTION_full_screen }, |
| 2948 | { "pidfile", HAS_ARG, QEMU_OPTION_pidfile }, | 2955 | { "pidfile", HAS_ARG, QEMU_OPTION_pidfile }, |
| 2949 | - | 2956 | + { "win2k-hack", 0, QEMU_OPTION_win2k_hack }, |
| 2957 | + | ||
| 2950 | /* temporary options */ | 2958 | /* temporary options */ |
| 2951 | { "pci", 0, QEMU_OPTION_pci }, | 2959 | { "pci", 0, QEMU_OPTION_pci }, |
| 2952 | { "cirrusvga", 0, QEMU_OPTION_cirrusvga }, | 2960 | { "cirrusvga", 0, QEMU_OPTION_cirrusvga }, |
| @@ -3397,6 +3405,11 @@ int main(int argc, char **argv) | @@ -3397,6 +3405,11 @@ int main(int argc, char **argv) | ||
| 3397 | case QEMU_OPTION_pidfile: | 3405 | case QEMU_OPTION_pidfile: |
| 3398 | create_pidfile(optarg); | 3406 | create_pidfile(optarg); |
| 3399 | break; | 3407 | break; |
| 3408 | +#ifdef TARGET_I386 | ||
| 3409 | + case QEMU_OPTION_win2k_hack: | ||
| 3410 | + win2k_install_hack = 1; | ||
| 3411 | + break; | ||
| 3412 | +#endif | ||
| 3400 | #ifdef USE_KQEMU | 3413 | #ifdef USE_KQEMU |
| 3401 | case QEMU_OPTION_no_kqemu: | 3414 | case QEMU_OPTION_no_kqemu: |
| 3402 | kqemu_allowed = 0; | 3415 | kqemu_allowed = 0; |
vl.h
| @@ -126,6 +126,7 @@ extern int graphic_height; | @@ -126,6 +126,7 @@ extern int graphic_height; | ||
| 126 | extern int graphic_depth; | 126 | extern int graphic_depth; |
| 127 | extern const char *keyboard_layout; | 127 | extern const char *keyboard_layout; |
| 128 | extern int kqemu_allowed; | 128 | extern int kqemu_allowed; |
| 129 | +extern int win2k_install_hack; | ||
| 129 | 130 | ||
| 130 | /* XXX: make it dynamic */ | 131 | /* XXX: make it dynamic */ |
| 131 | #if defined (TARGET_PPC) | 132 | #if defined (TARGET_PPC) |