mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-12-17 21:26:13 -07:00
440fx: fix PAM, PCI holes
The current implementation of PAM and the PCI holes is broken in several
ways:
- PCI BARs are not restricted to the PCI hole (a BAR may hide memory)
- PCI devices do not respect PAM (if a PCI device maps a region while
PAM maps the region to RAM, the request will be honored)
This patch fixes things by introducing a pci address space, and using
memory region aliases to represent PAM regions, SMRAM, and PCI holes.
The memory hierarchy looks something like
system_memory
|
+--- low memory alias (0-0xe0000000)
| |
| +-- ram@0
|
+--- high memory alias (0x100000000-EOM)
| |
| +-- ram@0xe0000000
|
+--- pci hole alias (end of low memory-0x100000000)
| |
| +-- pci@end-of-low-memory
|
|
+--- pam[n] (0xc0000-0xc3fff etc) (when set to pci, priority 1)
| |
| +-- pci@0xc4000 etc
|
+--- smram (0xa0000-0xbffff) (when set to pci/vga, priority 1)
|
+-- pci@0xa0000 etc
ram (simple ram region)
pci
|
+--- BARn
|
+--- VGA 0xa0000-0xbffff
|
+--- ROMs
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
be20f9e902
commit
ae0a54664c
4 changed files with 115 additions and 46 deletions
23
hw/pc_piix.c
23
hw/pc_piix.c
|
|
@ -22,6 +22,8 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "hw.h"
|
||||
#include "pc.h"
|
||||
#include "apic.h"
|
||||
|
|
@ -93,6 +95,8 @@ static void pc_init1(MemoryRegion *system_memory,
|
|||
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
|
||||
BusState *idebus[MAX_IDE_BUS];
|
||||
ISADevice *rtc_state;
|
||||
MemoryRegion *ram_memory;
|
||||
MemoryRegion *pci_memory;
|
||||
|
||||
pc_cpus_init(cpu_model);
|
||||
|
||||
|
|
@ -108,11 +112,15 @@ static void pc_init1(MemoryRegion *system_memory,
|
|||
below_4g_mem_size = ram_size;
|
||||
}
|
||||
|
||||
pci_memory = g_new(MemoryRegion, 1);
|
||||
memory_region_init(pci_memory, "pci", INT64_MAX);
|
||||
|
||||
/* allocate ram and load rom/bios */
|
||||
if (!xen_enabled()) {
|
||||
pc_memory_init(system_memory,
|
||||
kernel_filename, kernel_cmdline, initrd_filename,
|
||||
below_4g_mem_size, above_4g_mem_size);
|
||||
below_4g_mem_size, above_4g_mem_size,
|
||||
pci_memory, &ram_memory);
|
||||
}
|
||||
|
||||
if (!xen_enabled()) {
|
||||
|
|
@ -130,7 +138,14 @@ static void pc_init1(MemoryRegion *system_memory,
|
|||
|
||||
if (pci_enabled) {
|
||||
pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq,
|
||||
system_memory, system_io, ram_size);
|
||||
system_memory, system_io, ram_size,
|
||||
below_4g_mem_size,
|
||||
0x100000000ULL - below_4g_mem_size,
|
||||
0x100000000ULL + above_4g_mem_size,
|
||||
(sizeof(target_phys_addr_t) == 4
|
||||
? 0
|
||||
: ((uint64_t)1 << 62)),
|
||||
pci_memory, ram_memory);
|
||||
} else {
|
||||
pci_bus = NULL;
|
||||
i440fx_state = NULL;
|
||||
|
|
@ -202,10 +217,6 @@ static void pc_init1(MemoryRegion *system_memory,
|
|||
smbus_eeprom_init(smbus, 8, NULL, 0);
|
||||
}
|
||||
|
||||
if (i440fx_state) {
|
||||
i440fx_init_memory_mappings(i440fx_state);
|
||||
}
|
||||
|
||||
if (pci_enabled) {
|
||||
pc_pci_device_init(pci_bus);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue