mirror of https://gitee.com/openkylin/qemu.git
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:
parent
4f3baa4b36
commit
84631fd79c
|
@ -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;
|
||||
uint32_t smram, addr;
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue