aboutsummaryrefslogtreecommitdiff
path: root/hw/m68k/next-cube.c
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2023-11-02 18:21:21 +0800
committerStefan Hajnoczi <stefanha@redhat.com>2023-11-02 18:21:21 +0800
commit4a6a6cb60de80e9e90d9915abfec8d3d9fcc157c (patch)
tree7b05f6fffddfeb302255c96119bf0b5507a03d29 /hw/m68k/next-cube.c
parent6c9ae1ce82b65faa3f266fd103729878cf11e07e (diff)
parenta35c20961bb776ed8a4a7377f946b0f3149d3fe7 (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.c130
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");