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; | ... | ... |