Expand the VIRT_DEBUG memory map entry from 0x100 to RISCV_DM_SIZE (0x1000 = 4 KiB) to accommodate the full Debug Module address space: DMI registers, work area, and ROM entry vector.
Create the Debug Module device via riscv_dm_create() and wire each hart's halt-request GPIO to it. Set dm_halt_addr so the CPU enters the DM ROM entry point on debug-mode entry. Signed-off-by: Chao Liu <[email protected]> --- hw/riscv/virt.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index bbce2fb667..0a7e29a743 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -58,6 +58,7 @@ #include "qapi/qapi-visit-common.h" #include "hw/virtio/virtio-iommu.h" #include "hw/uefi/var-service-api.h" +#include "hw/riscv/dm.h" /* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */ static bool virt_use_kvm_aia_aplic_imsic(RISCVVirtAIAType aia_type) @@ -80,7 +81,7 @@ static bool virt_aclint_allowed(void) } static const MemMapEntry virt_memmap[] = { - [VIRT_DEBUG] = { 0x0, 0x100 }, + [VIRT_DEBUG] = { 0x0, RISCV_DM_SIZE }, [VIRT_MROM] = { 0x1000, 0xf000 }, [VIRT_TEST] = { 0x100000, 0x1000 }, [VIRT_RTC] = { 0x101000, 0x1000 }, @@ -1702,6 +1703,24 @@ static void virt_machine_init(MachineState *machine) create_platform_bus(s, mmio_irqchip); + /* Create Debug Module and connect each hart's halt-request IRQ */ + int total_harts = machine->smp.cpus; + DeviceState *dm = riscv_dm_create(system_memory, + s->memmap[VIRT_DEBUG].base, + total_harts); + + for (int h = 0; h < total_harts; h++) { + CPUState *cs = qemu_get_cpu(h); + RISCVCPU *rcpu = RISCV_CPU(cs); + + qdev_connect_gpio_out(dm, h, + qdev_get_gpio_in_named(DEVICE(cs), + "dm-halt-req", 0)); + rcpu->env.dm_rom_present = true; + rcpu->env.dm_halt_addr = s->memmap[VIRT_DEBUG].base + + RISCV_DM_ROM_ENTRY; + } + serial_mm_init(system_memory, s->memmap[VIRT_UART0].base, 0, qdev_get_gpio_in(mmio_irqchip, UART0_IRQ), 399193, serial_hd(0), DEVICE_LITTLE_ENDIAN); -- 2.53.0
