Lines Matching +full:dma +full:- +full:controller
5 * Copyright (c) 2024 Mark Cave-Ayland
15 #include "exec/cpu-interrupt.h"
19 #include "hw/m68k/next-cube.h"
28 #include "hw/qdev-properties.h"
30 #include "qemu/error-report.h"
48 #define TYPE_NEXT_RTC "next-rtc"
66 #define TYPE_NEXT_SCSI "next-scsi"
69 /* NeXT SCSI Controller */
82 #define TYPE_NEXT_PC "next-pc"
85 /* NeXT Peripheral Controller */
133 #define TYPE_NEXT_MACHINE MACHINE_TYPE_NAME("next-cube")
145 next_dma dma[10]; member
170 if (s->scr2 & 0x1) { in next_scr2_led_update()
172 s->led++; in next_scr2_led_update()
173 if (s->led == 10) { in next_scr2_led_update()
175 s->led = 0; in next_scr2_led_update()
184 old_scr2_rtc = extract32(s->old_scr2, 8, 8); in next_scr2_rtc_update()
185 scr2_rtc = extract32(s->scr2, 8, 8); in next_scr2_rtc_update()
188 /* DPRINTF("RTC %x phase %i\n", scr2_2, rtc->phase); */ in next_scr2_rtc_update()
193 qemu_irq_raise(s->rtc_data_irq); in next_scr2_rtc_update()
195 qemu_irq_lower(s->rtc_data_irq); in next_scr2_rtc_update()
200 qemu_irq_raise(s->rtc_cmd_reset_irq); in next_scr2_rtc_update()
211 /* DPRINTF("Read INT status: %x\n", s->int_status); */ in next_mmio_read()
212 val = s->int_status; in next_mmio_read()
216 DPRINTF("MMIO Read INT mask: %x\n", s->int_mask); in next_mmio_read()
217 val = s->int_mask; in next_mmio_read()
221 val = extract32(s->scr1, (4 - (addr - 0x7000) - size) << 3, in next_mmio_read()
226 val = extract32(s->scr2, (4 - (addr - 0x8000) - size) << 3, in next_mmio_read()
246 DPRINTF("INT Status old: %x new: %x\n", s->int_status, in next_mmio_write()
248 s->int_status = val; in next_mmio_write()
252 DPRINTF("INT Mask old: %x new: %x\n", s->int_mask, (unsigned int)val); in next_mmio_write()
253 s->int_mask = val; in next_mmio_write()
258 s->scr1 = deposit32(s->scr1, (4 - (addr - 0x7000) - size) << 3, in next_mmio_write()
263 s->scr2 = deposit32(s->scr2, (4 - (addr - 0x8000) - size) << 3, in next_mmio_write()
267 s->old_scr2 = s->scr2; in next_mmio_write()
285 #define SCSICSR_RESET 0x02 /* reset scsi dma */
288 #define SCSICSR_CPUDMA 0x10 /* if set, dma enabled */
311 next_state->dma[NEXTDMA_ENRX].csr |= DMA_DEV2M; in next_dma_write()
315 /* DPRINTF("SCSI DMA ENABLE\n"); */ in next_dma_write()
316 next_state->dma[NEXTDMA_ENRX].csr |= DMA_ENABLE; in next_dma_write()
319 next_state->dma[NEXTDMA_ENRX].csr |= DMA_SUPDATE; in next_dma_write()
322 next_state->dma[NEXTDMA_ENRX].csr &= ~DMA_COMPLETE; in next_dma_write()
326 next_state->dma[NEXTDMA_ENRX].csr &= ~(DMA_COMPLETE | DMA_SUPDATE | in next_dma_write()
333 next_state->dma[NEXTDMA_ENRX].next_initbuf = val; in next_dma_write()
337 next_state->dma[NEXTDMA_ENRX].next = val; in next_dma_write()
341 next_state->dma[NEXTDMA_ENRX].limit = val; in next_dma_write()
346 next_state->dma[NEXTDMA_SCSI].csr |= DMA_DEV2M; in next_dma_write()
349 /* DPRINTF("SCSI DMA ENABLE\n"); */ in next_dma_write()
350 next_state->dma[NEXTDMA_SCSI].csr |= DMA_ENABLE; in next_dma_write()
353 next_state->dma[NEXTDMA_SCSI].csr |= DMA_SUPDATE; in next_dma_write()
356 next_state->dma[NEXTDMA_SCSI].csr &= ~DMA_COMPLETE; in next_dma_write()
360 next_state->dma[NEXTDMA_SCSI].csr &= ~(DMA_COMPLETE | DMA_SUPDATE | in next_dma_write()
362 /* DPRINTF("SCSI DMA RESET\n"); */ in next_dma_write()
368 next_state->dma[NEXTDMA_SCSI].next = val; in next_dma_write()
372 next_state->dma[NEXTDMA_SCSI].limit = val; in next_dma_write()
376 next_state->dma[NEXTDMA_SCSI].start = val; in next_dma_write()
380 next_state->dma[NEXTDMA_SCSI].stop = val; in next_dma_write()
384 next_state->dma[NEXTDMA_SCSI].next_initbuf = val; in next_dma_write()
388 DPRINTF("DMA write @ %x w/ %x\n", (unsigned)addr, (unsigned)val); in next_dma_write()
399 DPRINTF("SCSI DMA CSR READ\n"); in next_dma_read()
400 val = next_state->dma[NEXTDMA_SCSI].csr; in next_dma_read()
404 val = next_state->dma[NEXTDMA_ENRX].csr; in next_dma_read()
408 val = next_state->dma[NEXTDMA_ENRX].next_initbuf; in next_dma_read()
412 val = next_state->dma[NEXTDMA_ENRX].next; in next_dma_read()
416 val = next_state->dma[NEXTDMA_ENRX].limit; in next_dma_read()
420 val = next_state->dma[NEXTDMA_SCSI].next; in next_dma_read()
424 val = next_state->dma[NEXTDMA_SCSI].next_initbuf; in next_dma_read()
428 val = next_state->dma[NEXTDMA_SCSI].limit; in next_dma_read()
432 val = next_state->dma[NEXTDMA_SCSI].start; in next_dma_read()
436 val = next_state->dma[NEXTDMA_SCSI].stop; in next_dma_read()
440 DPRINTF("DMA read @ %x\n", (unsigned int)addr); in next_dma_read()
464 M68kCPU *cpu = s->cpu; in next_irq()
470 /* level 3 - floppy, kbd/mouse, power, ether rx/tx, scsi, clock */ in next_irq()
493 /* level 5 - scc (serial) */ in next_irq()
498 /* level 6 - audio etherrx/tx dma */ in next_irq()
520 if (s->int_mask & (1 << shift)) { in next_irq()
521 DPRINTF("%x interrupt masked @ %x\n", 1 << shift, cpu->env.pc); in next_irq()
527 s->int_status |= 1 << shift; in next_irq()
530 /* level 3 - floppy, kbd/mouse, power, ether rx/tx, scsi, clock */ in next_irq()
541 /* level 5 - scc (serial) */ in next_irq()
546 /* level 6 - audio etherrx/tx dma */ in next_irq()
556 s->int_status &= ~(1 << shift); in next_irq()
571 /* Most DMA is supposedly 16 byte aligned */ in nextdma_write()
573 size -= size % align; in nextdma_write()
578 * prom sets the dma start using initbuf while the bootloader uses next in nextdma_write()
581 if (next_state->dma[type].next_initbuf == 0) { in nextdma_write()
582 base_addr = next_state->dma[type].next; in nextdma_write()
584 base_addr = next_state->dma[type].next_initbuf; in nextdma_write()
589 next_state->dma[type].next_initbuf = 0; in nextdma_write()
592 next_state->dma[type].saved_limit = (next_state->dma[type].next + size); in nextdma_write()
593 next_state->dma[type].saved_next = (next_state->dma[type].next); in nextdma_write()
599 /* stl_phys(s->rx_dma.base-32,0xFFFFFFFF); */ in nextdma_write()
601 if (!(next_state->dma[type].csr & DMA_SUPDATE)) { in nextdma_write()
602 next_state->dma[type].next = next_state->dma[type].start; in nextdma_write()
603 next_state->dma[type].limit = next_state->dma[type].stop; in nextdma_write()
606 /* Set dma registers and raise an irq */ in nextdma_write()
607 next_state->dma[type].csr |= DMA_COMPLETE; /* DON'T CHANGE THIS! */ in nextdma_write()
648 * qemu_irq_raise(s->scsi_dma); in next_scsi_csr_write()
649 * s->scsi_csr_1 = 0xc0; in next_scsi_csr_write()
650 * s->scsi_csr_1 |= 0x1; in next_scsi_csr_write()
651 * qemu_irq_pulse(s->scsi_dma); in next_scsi_csr_write()
656 * s->scsi_csr_1 &= ~SCSICSR_ENABLE; in next_scsi_csr_write()
662 qemu_irq_raise(pc->scsi_reset); in next_scsi_csr_write()
663 s->scsi_csr_1 &= ~(SCSICSR_INTMASK | 0x80 | 0x1); in next_scsi_csr_write()
664 qemu_irq_lower(pc->scsi_reset); in next_scsi_csr_write()
671 /* qemu_irq_raise(s->scsi_dma); */ in next_scsi_csr_write()
672 pc->int_status |= 0x4000000; in next_scsi_csr_write()
675 pc->int_status &= ~(0x4000000); in next_scsi_csr_write()
676 /* qemu_irq_lower(s->scsi_dma); */ in next_scsi_csr_write()
682 * s->scsi_csr_1 |= val; in next_scsi_csr_write()
683 * s->scsi_csr_1 &= ~SCSICSR_INTMASK; in next_scsi_csr_write()
684 * if (s->scsi_queued) { in next_scsi_csr_write()
685 * s->scsi_queued = 0; in next_scsi_csr_write()
694 /* s->scsi_csr_1 |= 0x80; */ in next_scsi_csr_write()
697 s->scsi_csr_1 = val; in next_scsi_csr_write()
702 s->scsi_csr_2 = val; in next_scsi_csr_write()
717 DPRINTF("SCSI 4020 STATUS READ %X\n", s->scsi_csr_1); in next_scsi_csr_read()
718 val = s->scsi_csr_1; in next_scsi_csr_read()
722 DPRINTF("SCSI 4021 STATUS READ %X\n", s->scsi_csr_2); in next_scsi_csr_read()
723 val = s->scsi_csr_2; in next_scsi_csr_read()
746 object_initialize_child(obj, "esp", &s->sysbus_esp, TYPE_SYSBUS_ESP); in next_scsi_init()
748 memory_region_init_io(&s->scsi_csr_mem, obj, &next_scsi_csr_ops, in next_scsi_init()
751 memory_region_init(&s->scsi_mem, obj, "next.scsi", 0x40); in next_scsi_init()
752 sysbus_init_mmio(sbd, &s->scsi_mem); in next_scsi_init()
766 sysbus_esp = SYSBUS_ESP(&s->sysbus_esp); in next_scsi_realize()
767 esp = &sysbus_esp->esp; in next_scsi_realize()
768 esp->dma_memory_read = nextscsi_read; in next_scsi_realize()
769 esp->dma_memory_write = nextscsi_write; in next_scsi_realize()
770 esp->dma_opaque = pcdev; in next_scsi_realize()
771 sysbus_esp->it_shift = 0; in next_scsi_realize()
772 esp->dma_enabled = 1; in next_scsi_realize()
777 memory_region_add_subregion(&s->scsi_mem, 0x0, in next_scsi_realize()
781 memory_region_add_subregion(&s->scsi_mem, 0x20, &s->scsi_csr_mem); in next_scsi_realize()
783 scsi_bus_legacy_handle_cmdline(&s->sysbus_esp.esp.bus); in next_scsi_realize()
787 .name = "next-scsi",
801 dc->desc = "NeXT SCSI Controller"; in next_scsi_class_init()
802 dc->realize = next_scsi_realize; in next_scsi_class_init()
803 dc->vmsd = &next_scsi_vmstate; in next_scsi_class_init()
821 /* qemu_irq_raise(s->fd_irq[0]); */ in next_floppy_write()
860 /* Hardware timer latch - not implemented yet */ in next_timer_write()
880 val = extract32(clock(), (4 - addr - size) << 3, in next_timer_read()
940 if (rtc->phase < 8) { in next_rtc_data_in_irq()
941 rtc->command = (rtc->command << 1) | level; in next_rtc_data_in_irq()
943 if (rtc->phase == 7 && !next_rtc_cmd_is_write(rtc->command)) { in next_rtc_data_in_irq()
944 if (rtc->command <= 0x1f) { in next_rtc_data_in_irq()
946 rtc->retval = rtc->ram[rtc->command]; in next_rtc_data_in_irq()
948 if ((rtc->command >= 0x20) && (rtc->command <= 0x2f)) { in next_rtc_data_in_irq()
952 rtc->retval = 0; in next_rtc_data_in_irq()
954 switch (rtc->command) { in next_rtc_data_in_irq()
956 rtc->retval = SCR2_TOBCD(info->tm_sec); in next_rtc_data_in_irq()
959 rtc->retval = SCR2_TOBCD(info->tm_min); in next_rtc_data_in_irq()
962 rtc->retval = SCR2_TOBCD(info->tm_hour); in next_rtc_data_in_irq()
965 rtc->retval = SCR2_TOBCD(info->tm_mday); in next_rtc_data_in_irq()
968 rtc->retval = SCR2_TOBCD((info->tm_mon + 1)); in next_rtc_data_in_irq()
971 rtc->retval = SCR2_TOBCD((info->tm_year - 100)); in next_rtc_data_in_irq()
975 if (rtc->command == 0x30) { in next_rtc_data_in_irq()
977 rtc->retval = rtc->status; in next_rtc_data_in_irq()
979 if (rtc->command == 0x31) { in next_rtc_data_in_irq()
981 rtc->retval = rtc->control; in next_rtc_data_in_irq()
985 if (rtc->phase >= 8 && rtc->phase < 16) { in next_rtc_data_in_irq()
986 if (next_rtc_cmd_is_write(rtc->command)) { in next_rtc_data_in_irq()
988 rtc->value = (rtc->value << 1) | level; in next_rtc_data_in_irq()
991 if (rtc->retval & (0x80 >> (rtc->phase - 8))) { in next_rtc_data_in_irq()
992 qemu_irq_raise(rtc->data_out_irq); in next_rtc_data_in_irq()
994 qemu_irq_lower(rtc->data_out_irq); in next_rtc_data_in_irq()
999 rtc->phase++; in next_rtc_data_in_irq()
1000 if (rtc->phase == 16 && next_rtc_cmd_is_write(rtc->command)) { in next_rtc_data_in_irq()
1001 if (rtc->command >= 0x80 && rtc->command <= 0x9f) { in next_rtc_data_in_irq()
1003 rtc->ram[rtc->command - 0x80] = rtc->value; in next_rtc_data_in_irq()
1005 if (rtc->command == 0xb1) { in next_rtc_data_in_irq()
1007 if (rtc->value & 0x04) { in next_rtc_data_in_irq()
1009 rtc->status = rtc->status & (~0x18); in next_rtc_data_in_irq()
1010 qemu_irq_lower(rtc->power_irq); in next_rtc_data_in_irq()
1021 rtc->phase = 0; in next_rtc_cmd_reset_irq()
1022 rtc->command = 0; in next_rtc_cmd_reset_irq()
1023 rtc->value = 0; in next_rtc_cmd_reset_irq()
1031 rtc->status = 0x90; in next_rtc_reset_hold()
1033 /* Load RTC RAM - TODO: provide possibility to load contents from file */ in next_rtc_reset_hold()
1034 memcpy(rtc->ram, rtc_ram2, 32); in next_rtc_reset_hold()
1042 "rtc-data-in", 1); in next_rtc_init()
1043 qdev_init_gpio_out_named(DEVICE(obj), &rtc->data_out_irq, in next_rtc_init()
1044 "rtc-data-out", 1); in next_rtc_init()
1046 "rtc-cmd-reset", 1); in next_rtc_init()
1047 qdev_init_gpio_out_named(DEVICE(obj), &rtc->power_irq, in next_rtc_init()
1048 "rtc-power-out", 1); in next_rtc_init()
1052 .name = "next-rtc",
1072 dc->desc = "NeXT RTC"; in next_rtc_class_init()
1073 dc->vmsd = &next_rtc_vmstate; in next_rtc_class_init()
1074 rc->phases.hold = next_rtc_reset_hold; in next_rtc_class_init()
1088 uint8_t scr2_2 = extract32(s->scr2, 8, 8); in next_pc_rtc_data_in_irq()
1096 s->scr2 = deposit32(s->scr2, 8, 8, scr2_2); in next_pc_rtc_data_in_irq()
1105 s->scr1 = 0x00011102; in next_pc_reset_hold()
1106 s->scr2 = 0x00ff0c80; in next_pc_reset_hold()
1107 s->old_scr2 = s->scr2; in next_pc_reset_hold()
1117 sbd = SYS_BUS_DEVICE(&s->next_scsi); in next_pc_realize()
1122 d = DEVICE(object_resolve_path_component(OBJECT(&s->next_scsi), "esp")); in next_pc_realize()
1126 s->scsi_reset = qdev_get_gpio_in(d, 0); in next_pc_realize()
1127 s->scsi_dma = qdev_get_gpio_in(d, 1); in next_pc_realize()
1130 d = DEVICE(&s->escc); in next_pc_realize()
1148 d = DEVICE(&s->rtc); in next_pc_realize()
1153 qdev_connect_gpio_out_named(dev, "rtc-data-out", 0, in next_pc_realize()
1154 qdev_get_gpio_in_named(d, "rtc-data-in", 0)); in next_pc_realize()
1156 qdev_connect_gpio_out_named(d, "rtc-data-out", 0, in next_pc_realize()
1158 "rtc-data-in", 0)); in next_pc_realize()
1159 qdev_connect_gpio_out_named(dev, "rtc-cmd-reset", 0, in next_pc_realize()
1160 qdev_get_gpio_in_named(d, "rtc-cmd-reset", 0)); in next_pc_realize()
1161 qdev_connect_gpio_out_named(d, "rtc-power-out", 0, in next_pc_realize()
1172 memory_region_init_io(&s->mmiomem, OBJECT(s), &next_mmio_ops, s, in next_pc_init()
1174 sysbus_init_mmio(sbd, &s->mmiomem); in next_pc_init()
1176 memory_region_init_io(&s->dummyen_mem, OBJECT(s), &next_dummy_en_ops, s, in next_pc_init()
1178 sysbus_init_mmio(sbd, &s->dummyen_mem); in next_pc_init()
1180 object_initialize_child(obj, "next-scsi", &s->next_scsi, TYPE_NEXT_SCSI); in next_pc_init()
1182 sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->next_scsi), 0)); in next_pc_init()
1184 memory_region_init_io(&s->floppy_mem, OBJECT(s), &next_floppy_ops, s, in next_pc_init()
1186 sysbus_init_mmio(sbd, &s->floppy_mem); in next_pc_init()
1188 object_initialize_child(obj, "escc", &s->escc, TYPE_ESCC); in next_pc_init()
1190 sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->escc), 0)); in next_pc_init()
1192 memory_region_init_io(&s->timer_mem, OBJECT(s), &next_timer_ops, s, in next_pc_init()
1194 sysbus_init_mmio(sbd, &s->timer_mem); in next_pc_init()
1196 object_initialize_child(obj, "rtc", &s->rtc, TYPE_NEXT_RTC); in next_pc_init()
1199 "rtc-data-in", 1); in next_pc_init()
1200 qdev_init_gpio_out_named(DEVICE(obj), &s->rtc_data_irq, in next_pc_init()
1201 "rtc-data-out", 1); in next_pc_init()
1202 qdev_init_gpio_out_named(DEVICE(obj), &s->rtc_cmd_reset_irq, in next_pc_init()
1203 "rtc-cmd-reset", 1); in next_pc_init()
1217 .name = "next-pc",
1236 dc->desc = "NeXT Peripheral Controller"; in next_pc_class_init()
1237 dc->realize = next_pc_realize; in next_pc_class_init()
1239 dc->vmsd = &next_pc_vmstate; in next_pc_class_init()
1240 rc->phases.hold = next_pc_reset_hold; in next_pc_class_init()
1257 const char *bios_name = machine->firmware ?: ROM_FILE; in next_cube_init()
1261 cpu = M68K_CPU(cpu_create(machine->cpu_type)); in next_cube_init()
1266 env = &cpu->env; in next_cube_init()
1269 env->vbr = 0; in next_cube_init()
1270 env->sr = 0x2700; in next_cube_init()
1272 /* Peripheral Controller */ in next_cube_init()
1278 memory_region_add_subregion(sysmem, 0x04000000, machine->ram); in next_cube_init()
1286 /* BMAP IO - acts as a catch-all for now */ in next_cube_init()
1294 /* unknown: Magneto-Optical drive controller? */ in next_cube_init()
1311 memory_region_init_ram_flags_nomigrate(&m->bmapm1, NULL, "next.bmapmem", in next_cube_init()
1313 memory_region_add_subregion(sysmem, 0x020c0000, &m->bmapm1); in next_cube_init()
1315 memory_region_init_alias(&m->bmapm2, NULL, "next.bmapmem2", &m->bmapm1, in next_cube_init()
1317 memory_region_add_subregion(sysmem, 0x820c0000, &m->bmapm2); in next_cube_init()
1323 memory_region_init_rom(&m->rom, NULL, "next.rom", 0x20000, &error_fatal); in next_cube_init()
1324 memory_region_add_subregion(sysmem, 0x01000000, &m->rom); in next_cube_init()
1325 memory_region_init_alias(&m->rom2, NULL, "next.rom2", &m->rom, 0x0, in next_cube_init()
1327 memory_region_add_subregion(sysmem, 0x0, &m->rom2); in next_cube_init()
1337 env->pc = ldl_be_p(ptr); in next_cube_init()
1338 if (env->pc >= 0x01020000) { in next_cube_init()
1345 /* DMA */ in next_cube_init()
1346 memory_region_init_io(&m->dmamem, NULL, &next_dma_ops, machine, in next_cube_init()
1347 "next.dma", 0x5000); in next_cube_init()
1348 memory_region_add_subregion(sysmem, 0x02000000, &m->dmamem); in next_cube_init()
1355 mc->desc = "NeXT Cube"; in next_machine_class_init()
1356 mc->init = next_cube_init; in next_machine_class_init()
1357 mc->block_default_type = IF_SCSI; in next_machine_class_init()
1358 mc->default_ram_size = RAM_SIZE; in next_machine_class_init()
1359 mc->default_ram_id = "next.ram"; in next_machine_class_init()
1360 mc->default_cpu_type = M68K_CPU_TYPE_NAME("m68040"); in next_machine_class_init()
1361 mc->no_cdrom = true; in next_machine_class_init()