implement i440 instead of i450 ISA memory mappings to be compatible with Bochs
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 24 Sep 2006 19:31:43 +0000 (19:31 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 24 Sep 2006 19:31:43 +0000 (19:31 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2177 c046a42c-6fe2-441c-8c8c-71466251a162

hw/piix_pci.c

index 43f2da2..1557694 100644 (file)
@@ -55,63 +55,50 @@ static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
 static uint32_t isa_page_descs[384 / 4];
 static uint8_t smm_enabled;
 
-static const uint32_t mar_addresses[15] = {
-    0xa0000,
-    0xc0000,
-    0xc4000,
-    0xc8000,
-    0xcc000,
-    0xd0000,
-    0xd4000,
-    0xd8000,
-    0xdc000,
-    0xe0000,
-    0xe4000,
-    0xe8000,
-    0xec000,
-    0xf0000,
-    0x100000,
-};
+static void update_pam(PCIDevice *d, uint32_t start, uint32_t end, int r)
+{
+    uint32_t addr;
+
+    //    printf("ISA mapping %08x-0x%08x: %d\n", start, end, r);
+    switch(r) {
+    case 3:
+        /* RAM */
+        cpu_register_physical_memory(start, end - start, 
+                                     start);
+        break;
+    case 1:
+        /* ROM (XXX: not quite correct) */
+        cpu_register_physical_memory(start, end - start, 
+                                     start | IO_MEM_ROM);
+        break;
+    case 2:
+    case 0:
+        /* XXX: should distinguish read/write cases */
+        for(addr = start; addr < end; addr += 4096) {
+            cpu_register_physical_memory(addr, 4096, 
+                                         isa_page_descs[(addr - 0xa0000) >> 12]);
+        }
+        break;
+    }
+}
 
 static void i440fx_update_memory_mappings(PCIDevice *d)
 {
     int i, r;
-    uint32_t start, end, addr;
-    uint32_t smram, smbase, smsize;
-
-    for(i = 0; i < 14; i++) {
-        r = (d->config[(i >> 1) + 0x61] >> ((i & 1) * 4)) & 3;
-        start = mar_addresses[i];
-        end = mar_addresses[i + 1];
-        //        printf("ISA mapping %08x: %d\n", start, r);
-        switch(r) {
-        case 3:
-            /* RAM */
-            cpu_register_physical_memory(start, end - start, 
-                                         start);
-            break;
-        case 2:
-            /* ROM (XXX: not quite correct) */
-            cpu_register_physical_memory(start, end - start, 
-                                         start | IO_MEM_ROM);
-            break;
-        case 1:
-        case 0:
-            /* XXX: should distinguish read/write cases */
-            for(addr = start; addr < end; addr += 4096) {
-                cpu_register_physical_memory(addr, 4096, 
-                                             isa_page_descs[(addr - 0xa0000) >> 12]);
-            }
-            break;
-        }
+    uint32_t smram, addr;
+
+    update_pam(d, 0xf0000, 0x100000, (d->config[0x59] >> 4) & 3);
+    for(i = 0; i < 12; i++) {
+        r = (d->config[(i >> 1) + 0x5a] >> ((i & 1) * 4)) & 3;
+        update_pam(d, 0xc0000 + 0x4000 * i, 0xc0000 + 0x4000 * (i + 1), r);
     }
-    smram = le32_to_cpu(*(uint32_t *)(d->config + 0x6c));
-    if ((smm_enabled && (smram & 0x80000000)) || (smram & (1 << 26))) {
-        /* Note: we assume the SMM area is in the 0xa0000-0x100000 range */
-        smbase = (smram & 0xffff) << 16;
-        smsize = (((smram >> 20) & 0xf) + 1) << 16;
-        if (smbase >= 0xa0000 && (smbase + smsize) <= 0x100000) {
-            cpu_register_physical_memory(smbase, smsize, smbase);
+    smram = d->config[0x72];
+    if ((smm_enabled && (smram & 0x08)) || (smram & 0x40)) {
+        cpu_register_physical_memory(0xa0000, 0x20000, 0xa0000);
+    } else {
+        for(addr = 0xa0000; addr < 0xc0000; addr += 4096) {
+            cpu_register_physical_memory(addr, 4096, 
+                                         isa_page_descs[(addr - 0xa0000) >> 12]);
         }
     }
 }
@@ -142,7 +129,7 @@ static void i440fx_write_config(PCIDevice *d,
 {
     /* XXX: implement SMRAM.D_LOCK */
     pci_default_write_config(d, address, val, len);
-    if ((address >= 0x61 && address <= 0x67) || address == 0x6c)
+    if ((address >= 0x59 && address <= 0x5f) || address == 0x72)
         i440fx_update_memory_mappings(d);
 }
 
@@ -200,7 +187,7 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state)
     d->config[0x0b] = 0x06; // class_base = PCI_bridge
     d->config[0x0e] = 0x00; // header_type
 
-    d->config[0x6c] = 0x0a; /* SMRAM */
+    d->config[0x72] = 0x02; /* SMRAM */
 
     register_savevm("I440FX", 0, 1, i440fx_save, i440fx_load, d);
     *pi440fx_state = d;