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
This commit is contained in:
bellard 2006-09-24 19:31:43 +00:00
parent 4f3baa4b36
commit 84631fd79c
1 changed files with 40 additions and 53 deletions

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