aboutsummaryrefslogtreecommitdiff
path: root/hw/riscv/virt.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/riscv/virt.c')
-rw-r--r--hw/riscv/virt.c68
1 files changed, 53 insertions, 15 deletions
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 2299b3a6be..4f0c2fbca0 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -43,10 +43,7 @@
#include "hw/pci/pci.h"
#include "hw/pci-host/gpex.h"
-static const struct MemmapEntry {
- hwaddr base;
- hwaddr size;
-} virt_memmap[] = {
+static const MemMapEntry virt_memmap[] = {
[VIRT_DEBUG] = { 0x0, 0x100 },
[VIRT_MROM] = { 0x1000, 0xf000 },
[VIRT_TEST] = { 0x100000, 0x1000 },
@@ -62,6 +59,15 @@ static const struct MemmapEntry {
[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,
@@ -170,7 +176,7 @@ static void create_pcie_irq_map(void *fdt, char *nodename,
0x1800, 0, 0, 0x7);
}
-static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
+static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
uint64_t mem_size, const char *cmdline, bool is_32_bit)
{
void *fdt;
@@ -374,7 +380,11 @@ static void create_fdt(RISCVVirtState *s, const struct 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);
@@ -451,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, bool link_up)
+ 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;
@@ -476,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++) {
@@ -490,7 +509,7 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
static void virt_machine_init(MachineState *machine)
{
- const struct MemmapEntry *memmap = virt_memmap;
+ const MemMapEntry *memmap = virt_memmap;
RISCVVirtState *s = RISCV_VIRT_MACHINE(machine);
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
@@ -593,6 +612,23 @@ static void virt_machine_init(MachineState *machine)
}
}
+ if (riscv_is_32bit(&s->soc[0])) {
+#if HOST_LONG_BITS == 64
+ /* limit RAM size in a 32-bit system */
+ if (machine->ram_size > 10 * GiB) {
+ machine->ram_size = 10 * GiB;
+ 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) */
memory_region_init_ram(main_mem, NULL, "riscv_virt_board.ram",
machine->ram_size, &error_fatal);
@@ -672,12 +708,14 @@ static void virt_machine_init(MachineState *machine)
}
gpex_pcie_init(system_memory,
- memmap[VIRT_PCIE_ECAM].base,
- memmap[VIRT_PCIE_ECAM].size,
- memmap[VIRT_PCIE_MMIO].base,
- memmap[VIRT_PCIE_MMIO].size,
- memmap[VIRT_PCIE_PIO].base,
- DEVICE(pcie_plic), true);
+ memmap[VIRT_PCIE_ECAM].base,
+ 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));
serial_mm_init(system_memory, memmap[VIRT_UART0].base,
0, qdev_get_gpio_in(DEVICE(mmio_plic), UART0_IRQ), 399193,