aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/riscv/virt.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index c4b8f455f8..4f0c2fbca0 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -59,6 +59,15 @@ static const MemMapEntry virt_memmap[] = {
[VIRT_DRAM] = { 0x80000000, 0x0 },
};
+/* PCIe high mmio is fixed for RV32 */
+#define VIRT32_HIGH_PCIE_MMIO_BASE 0x300000000ULL
+#define VIRT32_HIGH_PCIE_MMIO_SIZE (4 * GiB)
+
+/* PCIe high mmio for RV64, size is fixed but base depends on top of RAM */
+#define VIRT64_HIGH_PCIE_MMIO_SIZE (16 * GiB)
+
+static MemMapEntry virt_high_pcie_memmap;
+
#define VIRT_FLASH_SECTOR_SIZE (256 * KiB)
static PFlashCFI01 *virt_flash_create1(RISCVVirtState *s,
@@ -371,7 +380,11 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
2, memmap[VIRT_PCIE_PIO].base, 2, memmap[VIRT_PCIE_PIO].size,
1, FDT_PCI_RANGE_MMIO,
2, memmap[VIRT_PCIE_MMIO].base,
- 2, memmap[VIRT_PCIE_MMIO].base, 2, memmap[VIRT_PCIE_MMIO].size);
+ 2, memmap[VIRT_PCIE_MMIO].base, 2, memmap[VIRT_PCIE_MMIO].size,
+ 1, FDT_PCI_RANGE_MMIO_64BIT,
+ 2, virt_high_pcie_memmap.base,
+ 2, virt_high_pcie_memmap.base, 2, virt_high_pcie_memmap.size);
+
create_pcie_irq_map(fdt, name, plic_pcie_phandle);
g_free(name);
@@ -448,12 +461,14 @@ update_bootargs:
static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
hwaddr ecam_base, hwaddr ecam_size,
hwaddr mmio_base, hwaddr mmio_size,
+ hwaddr high_mmio_base,
+ hwaddr high_mmio_size,
hwaddr pio_base,
DeviceState *plic)
{
DeviceState *dev;
MemoryRegion *ecam_alias, *ecam_reg;
- MemoryRegion *mmio_alias, *mmio_reg;
+ MemoryRegion *mmio_alias, *high_mmio_alias, *mmio_reg;
qemu_irq irq;
int i;
@@ -473,6 +488,13 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
mmio_reg, mmio_base, mmio_size);
memory_region_add_subregion(get_system_memory(), mmio_base, mmio_alias);
+ /* Map high MMIO space */
+ high_mmio_alias = g_new0(MemoryRegion, 1);
+ memory_region_init_alias(high_mmio_alias, OBJECT(dev), "pcie-mmio-high",
+ mmio_reg, high_mmio_base, high_mmio_size);
+ memory_region_add_subregion(get_system_memory(), high_mmio_base,
+ high_mmio_alias);
+
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, pio_base);
for (i = 0; i < GPEX_NUM_IRQS; i++) {
@@ -598,6 +620,13 @@ static void virt_machine_init(MachineState *machine)
error_report("Limiting RAM size to 10 GiB");
}
#endif
+ virt_high_pcie_memmap.base = VIRT32_HIGH_PCIE_MMIO_BASE;
+ virt_high_pcie_memmap.size = VIRT32_HIGH_PCIE_MMIO_SIZE;
+ } else {
+ virt_high_pcie_memmap.size = VIRT64_HIGH_PCIE_MMIO_SIZE;
+ virt_high_pcie_memmap.base = memmap[VIRT_DRAM].base + machine->ram_size;
+ virt_high_pcie_memmap.base =
+ ROUND_UP(virt_high_pcie_memmap.base, virt_high_pcie_memmap.size);
}
/* register system main memory (actual RAM) */
@@ -683,6 +712,8 @@ static void virt_machine_init(MachineState *machine)
memmap[VIRT_PCIE_ECAM].size,
memmap[VIRT_PCIE_MMIO].base,
memmap[VIRT_PCIE_MMIO].size,
+ virt_high_pcie_memmap.base,
+ virt_high_pcie_memmap.size,
memmap[VIRT_PCIE_PIO].base,
DEVICE(pcie_plic));