Commit 84631fd79cd9c1c5ed21b9a574dd6bb9309de64c
1 parent
4f3baa4b
implement i440 instead of i450 ISA memory mappings to be compatible with Bochs
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2177 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
41 additions
and
54 deletions
hw/piix_pci.c
| ... | ... | @@ -55,63 +55,50 @@ static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) |
| 55 | 55 | static uint32_t isa_page_descs[384 / 4]; |
| 56 | 56 | static uint8_t smm_enabled; |
| 57 | 57 | |
| 58 | -static const uint32_t mar_addresses[15] = { | |
| 59 | - 0xa0000, | |
| 60 | - 0xc0000, | |
| 61 | - 0xc4000, | |
| 62 | - 0xc8000, | |
| 63 | - 0xcc000, | |
| 64 | - 0xd0000, | |
| 65 | - 0xd4000, | |
| 66 | - 0xd8000, | |
| 67 | - 0xdc000, | |
| 68 | - 0xe0000, | |
| 69 | - 0xe4000, | |
| 70 | - 0xe8000, | |
| 71 | - 0xec000, | |
| 72 | - 0xf0000, | |
| 73 | - 0x100000, | |
| 74 | -}; | |
| 58 | +static void update_pam(PCIDevice *d, uint32_t start, uint32_t end, int r) | |
| 59 | +{ | |
| 60 | + uint32_t addr; | |
| 61 | + | |
| 62 | + // printf("ISA mapping %08x-0x%08x: %d\n", start, end, r); | |
| 63 | + switch(r) { | |
| 64 | + case 3: | |
| 65 | + /* RAM */ | |
| 66 | + cpu_register_physical_memory(start, end - start, | |
| 67 | + start); | |
| 68 | + break; | |
| 69 | + case 1: | |
| 70 | + /* ROM (XXX: not quite correct) */ | |
| 71 | + cpu_register_physical_memory(start, end - start, | |
| 72 | + start | IO_MEM_ROM); | |
| 73 | + break; | |
| 74 | + case 2: | |
| 75 | + case 0: | |
| 76 | + /* XXX: should distinguish read/write cases */ | |
| 77 | + for(addr = start; addr < end; addr += 4096) { | |
| 78 | + cpu_register_physical_memory(addr, 4096, | |
| 79 | + isa_page_descs[(addr - 0xa0000) >> 12]); | |
| 80 | + } | |
| 81 | + break; | |
| 82 | + } | |
| 83 | +} | |
| 75 | 84 | |
| 76 | 85 | static void i440fx_update_memory_mappings(PCIDevice *d) |
| 77 | 86 | { |
| 78 | 87 | int i, r; |
| 79 | - uint32_t start, end, addr; | |
| 80 | - uint32_t smram, smbase, smsize; | |
| 81 | - | |
| 82 | - for(i = 0; i < 14; i++) { | |
| 83 | - r = (d->config[(i >> 1) + 0x61] >> ((i & 1) * 4)) & 3; | |
| 84 | - start = mar_addresses[i]; | |
| 85 | - end = mar_addresses[i + 1]; | |
| 86 | - // printf("ISA mapping %08x: %d\n", start, r); | |
| 87 | - switch(r) { | |
| 88 | - case 3: | |
| 89 | - /* RAM */ | |
| 90 | - cpu_register_physical_memory(start, end - start, | |
| 91 | - start); | |
| 92 | - break; | |
| 93 | - case 2: | |
| 94 | - /* ROM (XXX: not quite correct) */ | |
| 95 | - cpu_register_physical_memory(start, end - start, | |
| 96 | - start | IO_MEM_ROM); | |
| 97 | - break; | |
| 98 | - case 1: | |
| 99 | - case 0: | |
| 100 | - /* XXX: should distinguish read/write cases */ | |
| 101 | - for(addr = start; addr < end; addr += 4096) { | |
| 102 | - cpu_register_physical_memory(addr, 4096, | |
| 103 | - isa_page_descs[(addr - 0xa0000) >> 12]); | |
| 104 | - } | |
| 105 | - break; | |
| 106 | - } | |
| 88 | + uint32_t smram, addr; | |
| 89 | + | |
| 90 | + update_pam(d, 0xf0000, 0x100000, (d->config[0x59] >> 4) & 3); | |
| 91 | + for(i = 0; i < 12; i++) { | |
| 92 | + r = (d->config[(i >> 1) + 0x5a] >> ((i & 1) * 4)) & 3; | |
| 93 | + update_pam(d, 0xc0000 + 0x4000 * i, 0xc0000 + 0x4000 * (i + 1), r); | |
| 107 | 94 | } |
| 108 | - smram = le32_to_cpu(*(uint32_t *)(d->config + 0x6c)); | |
| 109 | - if ((smm_enabled && (smram & 0x80000000)) || (smram & (1 << 26))) { | |
| 110 | - /* Note: we assume the SMM area is in the 0xa0000-0x100000 range */ | |
| 111 | - smbase = (smram & 0xffff) << 16; | |
| 112 | - smsize = (((smram >> 20) & 0xf) + 1) << 16; | |
| 113 | - if (smbase >= 0xa0000 && (smbase + smsize) <= 0x100000) { | |
| 114 | - cpu_register_physical_memory(smbase, smsize, smbase); | |
| 95 | + smram = d->config[0x72]; | |
| 96 | + if ((smm_enabled && (smram & 0x08)) || (smram & 0x40)) { | |
| 97 | + cpu_register_physical_memory(0xa0000, 0x20000, 0xa0000); | |
| 98 | + } else { | |
| 99 | + for(addr = 0xa0000; addr < 0xc0000; addr += 4096) { | |
| 100 | + cpu_register_physical_memory(addr, 4096, | |
| 101 | + isa_page_descs[(addr - 0xa0000) >> 12]); | |
| 115 | 102 | } |
| 116 | 103 | } |
| 117 | 104 | } |
| ... | ... | @@ -142,7 +129,7 @@ static void i440fx_write_config(PCIDevice *d, |
| 142 | 129 | { |
| 143 | 130 | /* XXX: implement SMRAM.D_LOCK */ |
| 144 | 131 | pci_default_write_config(d, address, val, len); |
| 145 | - if ((address >= 0x61 && address <= 0x67) || address == 0x6c) | |
| 132 | + if ((address >= 0x59 && address <= 0x5f) || address == 0x72) | |
| 146 | 133 | i440fx_update_memory_mappings(d); |
| 147 | 134 | } |
| 148 | 135 | |
| ... | ... | @@ -200,7 +187,7 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state) |
| 200 | 187 | d->config[0x0b] = 0x06; // class_base = PCI_bridge |
| 201 | 188 | d->config[0x0e] = 0x00; // header_type |
| 202 | 189 | |
| 203 | - d->config[0x6c] = 0x0a; /* SMRAM */ | |
| 190 | + d->config[0x72] = 0x02; /* SMRAM */ | |
| 204 | 191 | |
| 205 | 192 | register_savevm("I440FX", 0, 1, i440fx_save, i440fx_load, d); |
| 206 | 193 | *pi440fx_state = d; | ... | ... |