qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] Re: Windows 2000 SP4 (was Re: APM bug)


From: Leonardo E. Reiter
Subject: Re: [Qemu-devel] Re: Windows 2000 SP4 (was Re: APM bug)
Date: Tue, 05 Apr 2005 19:03:08 -0400
User-agent: Debian Thunderbird 1.0 (X11/20050116)

Yes, we did replace the IDE driver with our own implementation. But you can apply this patch that was posted long ago on the list that takes care of it on regular QEMU. It will slow things down a bit, so you may want to disable it, so you may want to optimize it or disable it after you get Windows 2000 installed, but it works. The issue seems to be the fact that the install-time Windows 2000 IDE driver doesn't like write operations generating an interrupt too quickly (i.e. before the "out" or DMA transfer returns). It doesn't seem to have this issue after the base OS is installed and booted however, but your experience may vary. Attached is the patch that we found on the list. It applies both to 0.6.1 and 0.6.2, albeit with some possible hunks.

Best regards,

Leo Reiter

Hetz Ben Hamo wrote:
Hi Leonardo,

I have tried to install win2k from various CD's I have here around and
I stumbled on one really weird thing..

Disk space issues. I have tried with 1GB, 2GB and 4GB virtual disks,
and all of them seems to be quickly filled by the win2k installer and
then the install fails..

Do you also have the same problem there at win4lin? or is it only
happening with QEMU's internal IDE drive emulation? (since I recall
that win4lin replaced the IDE driver with their own's one)..

Thanks,
Hetz

--
Leonardo E. Reiter
Vice President of Engineering

Win4Lin, Inc.
Virtual Computing from Desktop to Data Center
Main: +1 512 339 7979
Fax: +1 512 532 6501
http://www.win4lin.com
diff -rbu qemu.orig/hw/ide.c qemu/hw/ide.c
--- qemu.orig/hw/ide.c  2004-12-02 23:20:21.000000000 +0300
+++ qemu/hw/ide.c       2004-12-17 14:06:15.000000000 +0300
@@ -332,8 +332,12 @@
     uint8_t *data_ptr;
     uint8_t *data_end;
     uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
+    int ide_set_irq_from_timer;
 } IDEState;
 
+volatile int ide_set_irq_from_timer;
+static IDEState *IDEStates[4];
+
 #define BM_STATUS_DMAING 0x01
 #define BM_STATUS_ERROR  0x02
 #define BM_STATUS_INT    0x04
@@ -512,6 +516,21 @@
     }
 }
 
+void make_ide_set_irq(void)
+{
+       int i;
+       IDEState *s;
+
+       ide_set_irq_from_timer--;
+       for(i = 0; (s=IDEStates[i]) != NULL; i++) {
+               if(s->ide_set_irq_from_timer) {
+                       s->ide_set_irq_from_timer--;
+                       ide_set_irq(s);
+                       break;
+               }
+       }
+}
+
 /* prepare data transfer and tell what to do after */
 static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, 
                                EndTransferFunc *end_transfer_func)
@@ -667,7 +686,11 @@
         ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
     }
     ide_set_sector(s, sector_num + n);
+    if(s->ide_set_irq_from_timer) {
+       ide_set_irq_from_timer++;
+    } else {
     ide_set_irq(s);
+    }
 }
 
 static int ide_write_dma_cb(IDEState *s, 
@@ -1511,6 +1534,7 @@
             s->error = 0;
             s->status = SEEK_STAT | READY_STAT;
             s->req_nb_sectors = 1;
+           s->ide_set_irq_from_timer = 1;
             ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
             break;
         case WIN_MULTREAD:
@@ -1528,6 +1552,7 @@
             n = s->nsector;
             if (n > s->req_nb_sectors)
                 n = s->req_nb_sectors;
+           s->ide_set_irq_from_timer = 1;
             ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
             break;
         case WIN_READDMA:
@@ -1883,6 +1908,7 @@
 
     for(i = 0; i < 2; i++) {
         s = ide_state + i;
+       IDEStates[drive_serial-1] = s;
         if (i == 0)
             s->bs = hd0;
         else
diff -rbu qemu.orig/vl.c qemu/vl.c
--- qemu.orig/vl.c      2004-12-13 01:20:04.000000000 +0300
+++ qemu/vl.c   2004-12-17 12:41:16.000000000 +0300
@@ -911,7 +911,7 @@
         
         /* timer signal */
         sigfillset(&act.sa_mask);
-        act.sa_flags = 0;
+       act.sa_flags = SA_RESTART;
 #if defined (TARGET_I386) && defined(USE_CODE_COPY)
         act.sa_flags |= SA_ONSTACK;
 #endif
@@ -2403,7 +2403,12 @@
     int n, max_size;
 #endif
     int ret;
+    /* ide.c hack */
+    extern volatile int ide_set_irq_from_timer;
+    extern void make_ide_set_irq(void);
 
+       if(ide_set_irq_from_timer)
+               make_ide_set_irq();
 #ifdef _WIN32
         if (timeout > 0)
             Sleep(timeout);
@@ -2449,8 +2454,6 @@
                             n = read(ioh->fd, buf, ioh->max_size);
                             if (n >= 0) {
                                 ioh->fd_read(ioh->opaque, buf, n);
-                            } else if (errno != EAGAIN) {
-                                ioh->fd_read(ioh->opaque, NULL, -errno);
                             }
                         }
                     }

reply via email to

[Prev in Thread] Current Thread [Next in Thread]