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,63 +55,50 @@ static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) | ||
55 | static uint32_t isa_page_descs[384 / 4]; | 55 | static uint32_t isa_page_descs[384 / 4]; |
56 | static uint8_t smm_enabled; | 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 | static void i440fx_update_memory_mappings(PCIDevice *d) | 85 | static void i440fx_update_memory_mappings(PCIDevice *d) |
77 | { | 86 | { |
78 | int i, r; | 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,7 +129,7 @@ static void i440fx_write_config(PCIDevice *d, | ||
142 | { | 129 | { |
143 | /* XXX: implement SMRAM.D_LOCK */ | 130 | /* XXX: implement SMRAM.D_LOCK */ |
144 | pci_default_write_config(d, address, val, len); | 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 | i440fx_update_memory_mappings(d); | 133 | i440fx_update_memory_mappings(d); |
147 | } | 134 | } |
148 | 135 | ||
@@ -200,7 +187,7 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state) | @@ -200,7 +187,7 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state) | ||
200 | d->config[0x0b] = 0x06; // class_base = PCI_bridge | 187 | d->config[0x0b] = 0x06; // class_base = PCI_bridge |
201 | d->config[0x0e] = 0x00; // header_type | 188 | d->config[0x0e] = 0x00; // header_type |
202 | 189 | ||
203 | - d->config[0x6c] = 0x0a; /* SMRAM */ | 190 | + d->config[0x72] = 0x02; /* SMRAM */ |
204 | 191 | ||
205 | register_savevm("I440FX", 0, 1, i440fx_save, i440fx_load, d); | 192 | register_savevm("I440FX", 0, 1, i440fx_save, i440fx_load, d); |
206 | *pi440fx_state = d; | 193 | *pi440fx_state = d; |