diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2023-11-02 18:21:21 +0800 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2023-11-02 18:21:21 +0800 |
commit | 4a6a6cb60de80e9e90d9915abfec8d3d9fcc157c (patch) | |
tree | 7b05f6fffddfeb302255c96119bf0b5507a03d29 /hw/m68k/next-cube.c | |
parent | 6c9ae1ce82b65faa3f266fd103729878cf11e07e (diff) | |
parent | a35c20961bb776ed8a4a7377f946b0f3149d3fe7 (diff) |
Merge tag 'm68k-pull-2023-11-02' of https://gitlab.com/huth/qemu into staging
* Avoid qemu_get_cpu() and first_cpu, and use properties instead
* Mirror next-cube bios to address 0
* Instantiate ESP SCSI controller in the next-cube machine
* Fix URL in the next-cube avocado test
# -----BEGIN PGP SIGNATURE-----
#
# iQJHBAABCAAxFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmVDbcETHGh1dGhAdHV4
# ZmFtaWx5Lm9yZwAKCRAu2dd0/nAttY1UEACfU8+L6ySkA6X0gtHKyMCQTna+RgGw
# TCQM3eUcL+/ZhcKrBBj397ea80h+VWrniixEpB2VSnQJsHraaIWtLTiOQFPRfVF9
# 4K5Nx/yuNq/6LX+jB5rvntKBeiU97E2XFZ7MKWQRhnjyUKeu6wAXtv4mhiLpj5wN
# PwbREVb0dqI7km/RAfUPJ4cAClokTIHUiUWRcaFR646weH6SU8JIOAyaGpeOhdYY
# QtWRIUThHjuGt2jfXzgOcX+kkc63BuxOn1OOVJpx5j39PhbXeIoPDQoY+EMgEztt
# HS7LYNqh7K8H2nmcgX7pzMEEZlJbDp5R8nLsK7G2a3/s3eAFc1ssAUQV8ZRmncNp
# gup6PDlNjoAb1qr8cu8vfdDMQzlGAIlH68YckSDHSa2H+bFF5LDWMsK1CKUz04x8
# XYub9uA2lH9j34B63Jbnk1grJsB/6gCFl3CTGgljL3kMZZncvmHSUi0TliX9v8pv
# xo7CH/SlG+Xp3XG72E2O01GZ4fZqaStDySr/xCc1hySurR2Ylw7qlu5e40nh8+CT
# CPjY9eWx/4mv7sNTCC/TndawKOBBfQpV3m+mWB2gNnLIuZmdnigcY+GuQaTwpTma
# PteoEMNgqE+H0FAC88n5SL9+tiAoEQ/Xu6HuBDqwJJC1d/+KqvJrkFH6BxzyFrH4
# nSBXNb8y1+qpkA==
# =MOWk
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 02 Nov 2023 17:37:05 HKT
# gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5
# gpg: issuer "huth@tuxfamily.org"
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full]
# gpg: aka "Thomas Huth <thuth@redhat.com>" [full]
# gpg: aka "Thomas Huth <huth@tuxfamily.org>" [full]
# gpg: aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5
* tag 'm68k-pull-2023-11-02' of https://gitlab.com/huth/qemu:
tests/avocado/machine_m68k_nextcube: Fix the download URL for the ROM image
m68k: Instantiate the ESP SCSI controller for the NeXTcube machine
hw/m68k/next-cube: Mirror BIOS to address 0
hw/char/mcf_uart: Have mcf_uart_create() return DeviceState
hw/m68k/virt: Do not open-code sysbus_create_simple()
hw/m68k/next-cube: Do not open-code sysbus_create_simple()
hw/m68k/mcf_intc: Pass CPU using QOM link property
hw/m68k/mcf_intc: Expose MMIO region via SysBus API
hw/m68k/mcf5206: Pass CPU using QOM link property
hw/m68k/irqc: Pass CPU using QOM link property
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw/m68k/next-cube.c')
-rw-r--r-- | hw/m68k/next-cube.c | 130 |
1 files changed, 115 insertions, 15 deletions
diff --git a/hw/m68k/next-cube.c b/hw/m68k/next-cube.c index 5d244b3b95..fabd861941 100644 --- a/hw/m68k/next-cube.c +++ b/hw/m68k/next-cube.c @@ -90,10 +90,13 @@ struct NeXTPC { uint32_t scr1; uint32_t scr2; - uint8_t scsi_csr_1; - uint8_t scsi_csr_2; uint32_t int_mask; uint32_t int_status; + uint8_t scsi_csr_1; + uint8_t scsi_csr_2; + + qemu_irq scsi_reset; + qemu_irq scsi_dma; NextRtc rtc; }; @@ -466,7 +469,7 @@ static void scr_writeb(NeXTPC *s, hwaddr addr, uint32_t value) DPRINTF("SCSICSR FIFO Flush\n"); /* will have to add another irq to the esp if this is needed */ /* esp_puflush_fifo(esp_g); */ - /* qemu_irq_pulse(s->scsi_dma); */ + qemu_irq_pulse(s->scsi_dma); } if (value & SCSICSR_ENABLE) { @@ -486,9 +489,9 @@ static void scr_writeb(NeXTPC *s, hwaddr addr, uint32_t value) if (value & SCSICSR_RESET) { DPRINTF("SCSICSR Reset\n"); /* I think this should set DMADIR. CPUDMA and INTMASK to 0 */ - /* qemu_irq_raise(s->scsi_reset); */ - /* s->scsi_csr_1 &= ~(SCSICSR_INTMASK |0x80|0x1); */ - + qemu_irq_raise(s->scsi_reset); + s->scsi_csr_1 &= ~(SCSICSR_INTMASK | 0x80 | 0x1); + qemu_irq_lower(s->scsi_reset); } if (value & SCSICSR_DMADIR) { DPRINTF("SCSICSR DMAdir\n"); @@ -496,10 +499,11 @@ static void scr_writeb(NeXTPC *s, hwaddr addr, uint32_t value) if (value & SCSICSR_CPUDMA) { DPRINTF("SCSICSR CPUDMA\n"); /* qemu_irq_raise(s->scsi_dma); */ - s->int_status |= 0x4000000; } else { + /* fprintf(stderr,"SCSICSR CPUDMA disabled\n"); */ s->int_status &= ~(0x4000000); + /* qemu_irq_lower(s->scsi_dma); */ } if (value & SCSICSR_INTMASK) { DPRINTF("SCSICSR INTMASK\n"); @@ -828,6 +832,103 @@ static void next_irq(void *opaque, int number, int level) } } +static void nextdma_write(void *opaque, uint8_t *buf, int size, int type) +{ + uint32_t base_addr; + int irq = 0; + uint8_t align = 16; + NeXTState *next_state = NEXT_MACHINE(qdev_get_machine()); + + if (type == NEXTDMA_ENRX || type == NEXTDMA_ENTX) { + align = 32; + } + /* Most DMA is supposedly 16 byte aligned */ + if ((size % align) != 0) { + size -= size % align; + size += align; + } + + /* + * prom sets the dma start using initbuf while the bootloader uses next + * so we check to see if initbuf is 0 + */ + if (next_state->dma[type].next_initbuf == 0) { + base_addr = next_state->dma[type].next; + } else { + base_addr = next_state->dma[type].next_initbuf; + } + + cpu_physical_memory_write(base_addr, buf, size); + + next_state->dma[type].next_initbuf = 0; + + /* saved limit is checked to calculate packet size by both, rom and netbsd */ + next_state->dma[type].saved_limit = (next_state->dma[type].next + size); + next_state->dma[type].saved_next = (next_state->dma[type].next); + + /* + * 32 bytes under savedbase seems to be some kind of register + * of which the purpose is unknown as of yet + */ + /* stl_phys(s->rx_dma.base-32,0xFFFFFFFF); */ + + if (!(next_state->dma[type].csr & DMA_SUPDATE)) { + next_state->dma[type].next = next_state->dma[type].start; + next_state->dma[type].limit = next_state->dma[type].stop; + } + + /* Set dma registers and raise an irq */ + next_state->dma[type].csr |= DMA_COMPLETE; /* DON'T CHANGE THIS! */ + + switch (type) { + case NEXTDMA_SCSI: + irq = NEXT_SCSI_DMA_I; + break; + } + + next_irq(opaque, irq, 1); + next_irq(opaque, irq, 0); +} + +static void nextscsi_read(void *opaque, uint8_t *buf, int len) +{ + DPRINTF("SCSI READ: %x\n", len); + abort(); +} + +static void nextscsi_write(void *opaque, uint8_t *buf, int size) +{ + DPRINTF("SCSI WRITE: %i\n", size); + nextdma_write(opaque, buf, size, NEXTDMA_SCSI); +} + +static void next_scsi_init(DeviceState *pcdev, M68kCPU *cpu) +{ + struct NeXTPC *next_pc = NEXT_PC(pcdev); + DeviceState *dev; + SysBusDevice *sysbusdev; + SysBusESPState *sysbus_esp; + ESPState *esp; + + dev = qdev_new(TYPE_SYSBUS_ESP); + sysbus_esp = SYSBUS_ESP(dev); + esp = &sysbus_esp->esp; + esp->dma_memory_read = nextscsi_read; + esp->dma_memory_write = nextscsi_write; + esp->dma_opaque = pcdev; + sysbus_esp->it_shift = 0; + esp->dma_enabled = 1; + sysbusdev = SYS_BUS_DEVICE(dev); + sysbus_realize_and_unref(sysbusdev, &error_fatal); + sysbus_connect_irq(sysbusdev, 0, qdev_get_gpio_in(pcdev, NEXT_SCSI_I)); + sysbus_mmio_map(sysbusdev, 0, 0x2114000); + + next_pc->scsi_reset = qdev_get_gpio_in(dev, 0); + next_pc->scsi_dma = qdev_get_gpio_in(dev, 1); + + scsi_bus_legacy_handle_cmdline(&esp->bus); +} + static void next_escc_init(DeviceState *pcdev) { DeviceState *dev; @@ -945,12 +1046,12 @@ static void next_cube_init(MachineState *machine) M68kCPU *cpu; CPUM68KState *env; MemoryRegion *rom = g_new(MemoryRegion, 1); + MemoryRegion *rom2 = g_new(MemoryRegion, 1); MemoryRegion *dmamem = g_new(MemoryRegion, 1); MemoryRegion *bmapm1 = g_new(MemoryRegion, 1); MemoryRegion *bmapm2 = g_new(MemoryRegion, 1); MemoryRegion *sysmem = get_system_memory(); const char *bios_name = machine->firmware ?: ROM_FILE; - DeviceState *dev; DeviceState *pcdev; /* Initialize the cpu core */ @@ -974,9 +1075,7 @@ static void next_cube_init(MachineState *machine) memory_region_add_subregion(sysmem, 0x04000000, machine->ram); /* Framebuffer */ - dev = qdev_new(TYPE_NEXTFB); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x0B000000); + sysbus_create_simple(TYPE_NEXTFB, 0x0B000000, NULL); /* MMIO */ sysbus_mmio_map(SYS_BUS_DEVICE(pcdev), 0, 0x02000000); @@ -993,14 +1092,13 @@ static void next_cube_init(MachineState *machine) memory_region_add_subregion(sysmem, 0x820c0000, bmapm2); /* KBD */ - dev = qdev_new(TYPE_NEXTKBD); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x0200e000); + sysbus_create_simple(TYPE_NEXTKBD, 0x0200e000, NULL); /* Load ROM here */ - /* still not sure if the rom should also be mapped at 0x0*/ memory_region_init_rom(rom, NULL, "next.rom", 0x20000, &error_fatal); memory_region_add_subregion(sysmem, 0x01000000, rom); + memory_region_init_alias(rom2, NULL, "next.rom2", rom, 0x0, 0x20000); + memory_region_add_subregion(sysmem, 0x0, rom2); if (load_image_targphys(bios_name, 0x01000000, 0x20000) < 8) { if (!qtest_enabled()) { error_report("Failed to load firmware '%s'.", bios_name); @@ -1024,6 +1122,7 @@ static void next_cube_init(MachineState *machine) /* TODO: */ /* Network */ /* SCSI */ + next_scsi_init(pcdev, cpu); /* DMA */ memory_region_init_io(dmamem, NULL, &dma_ops, machine, "next.dma", 0x5000); @@ -1036,6 +1135,7 @@ static void next_machine_class_init(ObjectClass *oc, void *data) mc->desc = "NeXT Cube"; mc->init = next_cube_init; + mc->block_default_type = IF_SCSI; mc->default_ram_size = RAM_SIZE; mc->default_ram_id = "next.ram"; mc->default_cpu_type = M68K_CPU_TYPE_NAME("m68040"); |