1d9656f86SBALATON Zoltan /* 2d9656f86SBALATON Zoltan * QEMU Eyetech AmigaOne/Mai Logic Teron emulation 3d9656f86SBALATON Zoltan * 4d9656f86SBALATON Zoltan * Copyright (c) 2023 BALATON Zoltan 5d9656f86SBALATON Zoltan * 6d9656f86SBALATON Zoltan * This work is licensed under the GNU GPL license version 2 or later. 7d9656f86SBALATON Zoltan * 8d9656f86SBALATON Zoltan */ 9d9656f86SBALATON Zoltan 10d9656f86SBALATON Zoltan #include "qemu/osdep.h" 11d9656f86SBALATON Zoltan #include "qemu/units.h" 12d9656f86SBALATON Zoltan #include "qemu/datadir.h" 13d9656f86SBALATON Zoltan #include "qemu/log.h" 14d9656f86SBALATON Zoltan #include "qemu/error-report.h" 15d9656f86SBALATON Zoltan #include "qapi/error.h" 16d9656f86SBALATON Zoltan #include "hw/ppc/ppc.h" 17d9656f86SBALATON Zoltan #include "hw/boards.h" 18d9656f86SBALATON Zoltan #include "hw/loader.h" 19d9656f86SBALATON Zoltan #include "hw/pci-host/articia.h" 20d9656f86SBALATON Zoltan #include "hw/isa/vt82c686.h" 21d9656f86SBALATON Zoltan #include "hw/ide/pci.h" 22d9656f86SBALATON Zoltan #include "hw/i2c/smbus_eeprom.h" 23d9656f86SBALATON Zoltan #include "hw/ppc/ppc.h" 24*addff513SBALATON Zoltan #include "system/block-backend.h" 2532cad1ffSPhilippe Mathieu-Daudé #include "system/qtest.h" 2632cad1ffSPhilippe Mathieu-Daudé #include "system/reset.h" 27d9656f86SBALATON Zoltan #include "kvm_ppc.h" 28d9656f86SBALATON Zoltan 29*addff513SBALATON Zoltan #include <zlib.h> /* for crc32 */ 30*addff513SBALATON Zoltan 31d9656f86SBALATON Zoltan #define BUS_FREQ_HZ 100000000 32d9656f86SBALATON Zoltan 33d9656f86SBALATON Zoltan /* 34d9656f86SBALATON Zoltan * Firmware binary available at 35d9656f86SBALATON Zoltan * https://www.hyperion-entertainment.com/index.php/downloads?view=files&parent=28 36d9656f86SBALATON Zoltan * then "tail -c 524288 updater.image >u-boot-amigaone.bin" 37d9656f86SBALATON Zoltan * 38d9656f86SBALATON Zoltan * BIOS emulator in firmware cannot run QEMU vgabios and hangs on it, use 39d9656f86SBALATON Zoltan * -device VGA,romfile=VGABIOS-lgpl-latest.bin 40d9656f86SBALATON Zoltan * from http://www.nongnu.org/vgabios/ instead. 41d9656f86SBALATON Zoltan */ 42d9656f86SBALATON Zoltan #define PROM_ADDR 0xfff00000 43d9656f86SBALATON Zoltan #define PROM_SIZE (512 * KiB) 44d9656f86SBALATON Zoltan 45e25acd61SBALATON Zoltan /* AmigaOS calls this routine from ROM, use this if no firmware loaded */ 46e25acd61SBALATON Zoltan static const char dummy_fw[] = { 47222d37d3SBALATON Zoltan 0x54, 0x63, 0xc2, 0x3e, /* srwi r3,r3,8 */ 48e25acd61SBALATON Zoltan 0x7c, 0x63, 0x18, 0xf8, /* not r3,r3 */ 49e25acd61SBALATON Zoltan 0x4e, 0x80, 0x00, 0x20, /* blr */ 50e25acd61SBALATON Zoltan }; 51e25acd61SBALATON Zoltan 52*addff513SBALATON Zoltan #define NVRAM_ADDR 0xfd0e0000 53*addff513SBALATON Zoltan #define NVRAM_SIZE (4 * KiB) 54*addff513SBALATON Zoltan 55*addff513SBALATON Zoltan #define TYPE_A1_NVRAM "a1-nvram" 56*addff513SBALATON Zoltan OBJECT_DECLARE_SIMPLE_TYPE(A1NVRAMState, A1_NVRAM) 57*addff513SBALATON Zoltan 58*addff513SBALATON Zoltan struct A1NVRAMState { 59*addff513SBALATON Zoltan SysBusDevice parent_obj; 60*addff513SBALATON Zoltan 61*addff513SBALATON Zoltan MemoryRegion mr; 62*addff513SBALATON Zoltan BlockBackend *blk; 63*addff513SBALATON Zoltan }; 64*addff513SBALATON Zoltan 65*addff513SBALATON Zoltan static uint64_t nvram_read(void *opaque, hwaddr addr, unsigned int size) 66*addff513SBALATON Zoltan { 67*addff513SBALATON Zoltan /* read callback not used because of romd mode */ 68*addff513SBALATON Zoltan g_assert_not_reached(); 69*addff513SBALATON Zoltan } 70*addff513SBALATON Zoltan 71*addff513SBALATON Zoltan static void nvram_write(void *opaque, hwaddr addr, uint64_t val, 72*addff513SBALATON Zoltan unsigned int size) 73*addff513SBALATON Zoltan { 74*addff513SBALATON Zoltan A1NVRAMState *s = opaque; 75*addff513SBALATON Zoltan uint8_t *p = memory_region_get_ram_ptr(&s->mr); 76*addff513SBALATON Zoltan 77*addff513SBALATON Zoltan p[addr] = val; 78*addff513SBALATON Zoltan if (s->blk) { 79*addff513SBALATON Zoltan blk_pwrite(s->blk, addr, 1, &val, 0); 80*addff513SBALATON Zoltan } 81*addff513SBALATON Zoltan } 82*addff513SBALATON Zoltan 83*addff513SBALATON Zoltan static const MemoryRegionOps nvram_ops = { 84*addff513SBALATON Zoltan .read = nvram_read, 85*addff513SBALATON Zoltan .write = nvram_write, 86*addff513SBALATON Zoltan .endianness = DEVICE_BIG_ENDIAN, 87*addff513SBALATON Zoltan .impl = { 88*addff513SBALATON Zoltan .min_access_size = 1, 89*addff513SBALATON Zoltan .max_access_size = 1, 90*addff513SBALATON Zoltan }, 91*addff513SBALATON Zoltan }; 92*addff513SBALATON Zoltan 93*addff513SBALATON Zoltan static void nvram_realize(DeviceState *dev, Error **errp) 94*addff513SBALATON Zoltan { 95*addff513SBALATON Zoltan A1NVRAMState *s = A1_NVRAM(dev); 96*addff513SBALATON Zoltan void *p; 97*addff513SBALATON Zoltan uint32_t *c; 98*addff513SBALATON Zoltan 99*addff513SBALATON Zoltan memory_region_init_rom_device(&s->mr, NULL, &nvram_ops, s, "nvram", 100*addff513SBALATON Zoltan NVRAM_SIZE, &error_fatal); 101*addff513SBALATON Zoltan sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mr); 102*addff513SBALATON Zoltan c = p = memory_region_get_ram_ptr(&s->mr); 103*addff513SBALATON Zoltan if (s->blk) { 104*addff513SBALATON Zoltan if (blk_getlength(s->blk) != NVRAM_SIZE) { 105*addff513SBALATON Zoltan error_setg(errp, "NVRAM backing file size must be %" PRId64 "bytes", 106*addff513SBALATON Zoltan NVRAM_SIZE); 107*addff513SBALATON Zoltan return; 108*addff513SBALATON Zoltan } 109*addff513SBALATON Zoltan blk_set_perm(s->blk, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE, 110*addff513SBALATON Zoltan BLK_PERM_ALL, &error_fatal); 111*addff513SBALATON Zoltan if (blk_pread(s->blk, 0, NVRAM_SIZE, p, 0) < 0) { 112*addff513SBALATON Zoltan error_setg(errp, "Cannot read NVRAM contents from backing file"); 113*addff513SBALATON Zoltan return; 114*addff513SBALATON Zoltan } 115*addff513SBALATON Zoltan } 116*addff513SBALATON Zoltan if (*c == 0) { 117*addff513SBALATON Zoltan *c = cpu_to_be32(crc32(0, p + 4, NVRAM_SIZE - 4)); 118*addff513SBALATON Zoltan if (s->blk) { 119*addff513SBALATON Zoltan blk_pwrite(s->blk, 0, 4, p, 0); 120*addff513SBALATON Zoltan } 121*addff513SBALATON Zoltan } 122*addff513SBALATON Zoltan } 123*addff513SBALATON Zoltan 124*addff513SBALATON Zoltan static const Property nvram_properties[] = { 125*addff513SBALATON Zoltan DEFINE_PROP_DRIVE("drive", A1NVRAMState, blk), 126*addff513SBALATON Zoltan }; 127*addff513SBALATON Zoltan 128*addff513SBALATON Zoltan static void nvram_class_init(ObjectClass *oc, void *data) 129*addff513SBALATON Zoltan { 130*addff513SBALATON Zoltan DeviceClass *dc = DEVICE_CLASS(oc); 131*addff513SBALATON Zoltan 132*addff513SBALATON Zoltan dc->realize = nvram_realize; 133*addff513SBALATON Zoltan device_class_set_props(dc, nvram_properties); 134*addff513SBALATON Zoltan } 135*addff513SBALATON Zoltan 136*addff513SBALATON Zoltan static const TypeInfo nvram_types[] = { 137*addff513SBALATON Zoltan { 138*addff513SBALATON Zoltan .name = TYPE_A1_NVRAM, 139*addff513SBALATON Zoltan .parent = TYPE_SYS_BUS_DEVICE, 140*addff513SBALATON Zoltan .instance_size = sizeof(A1NVRAMState), 141*addff513SBALATON Zoltan .class_init = nvram_class_init, 142*addff513SBALATON Zoltan }, 143*addff513SBALATON Zoltan }; 144*addff513SBALATON Zoltan DEFINE_TYPES(nvram_types) 145*addff513SBALATON Zoltan 146d9656f86SBALATON Zoltan static void amigaone_cpu_reset(void *opaque) 147d9656f86SBALATON Zoltan { 148d9656f86SBALATON Zoltan PowerPCCPU *cpu = opaque; 149d9656f86SBALATON Zoltan 150d9656f86SBALATON Zoltan cpu_reset(CPU(cpu)); 151d9656f86SBALATON Zoltan cpu_ppc_tb_reset(&cpu->env); 152d9656f86SBALATON Zoltan } 153d9656f86SBALATON Zoltan 154d9656f86SBALATON Zoltan static void fix_spd_data(uint8_t *spd) 155d9656f86SBALATON Zoltan { 156d9656f86SBALATON Zoltan uint32_t bank_size = 4 * MiB * spd[31]; 157d9656f86SBALATON Zoltan uint32_t rows = bank_size / spd[13] / spd[17]; 158d9656f86SBALATON Zoltan spd[3] = ctz32(rows) - spd[4]; 159d9656f86SBALATON Zoltan } 160d9656f86SBALATON Zoltan 161d9656f86SBALATON Zoltan static void amigaone_init(MachineState *machine) 162d9656f86SBALATON Zoltan { 163d9656f86SBALATON Zoltan PowerPCCPU *cpu; 164d9656f86SBALATON Zoltan CPUPPCState *env; 165d9656f86SBALATON Zoltan MemoryRegion *rom, *pci_mem, *mr; 166d9656f86SBALATON Zoltan ssize_t sz; 167d9656f86SBALATON Zoltan PCIBus *pci_bus; 168d9656f86SBALATON Zoltan Object *via; 169d9656f86SBALATON Zoltan DeviceState *dev; 170d9656f86SBALATON Zoltan I2CBus *i2c_bus; 171d9656f86SBALATON Zoltan uint8_t *spd_data; 172*addff513SBALATON Zoltan DriveInfo *di; 173d9656f86SBALATON Zoltan 174d9656f86SBALATON Zoltan /* init CPU */ 175d9656f86SBALATON Zoltan cpu = POWERPC_CPU(cpu_create(machine->cpu_type)); 176d9656f86SBALATON Zoltan env = &cpu->env; 177d9656f86SBALATON Zoltan if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { 178d9656f86SBALATON Zoltan error_report("Incompatible CPU, only 6xx bus supported"); 179d9656f86SBALATON Zoltan exit(1); 180d9656f86SBALATON Zoltan } 181d9656f86SBALATON Zoltan cpu_ppc_tb_init(env, BUS_FREQ_HZ / 4); 182d9656f86SBALATON Zoltan qemu_register_reset(amigaone_cpu_reset, cpu); 183d9656f86SBALATON Zoltan 184d9656f86SBALATON Zoltan /* RAM */ 185d9656f86SBALATON Zoltan if (machine->ram_size > 2 * GiB) { 186d9656f86SBALATON Zoltan error_report("RAM size more than 2 GiB is not supported"); 187d9656f86SBALATON Zoltan exit(1); 188d9656f86SBALATON Zoltan } 189d9656f86SBALATON Zoltan memory_region_add_subregion(get_system_memory(), 0, machine->ram); 190d9656f86SBALATON Zoltan if (machine->ram_size < 1 * GiB + 32 * KiB) { 191d9656f86SBALATON Zoltan /* Firmware uses this area for startup */ 192d9656f86SBALATON Zoltan mr = g_new(MemoryRegion, 1); 193d9656f86SBALATON Zoltan memory_region_init_ram(mr, NULL, "init-cache", 32 * KiB, &error_fatal); 194d9656f86SBALATON Zoltan memory_region_add_subregion(get_system_memory(), 0x40000000, mr); 195d9656f86SBALATON Zoltan } 196d9656f86SBALATON Zoltan 197*addff513SBALATON Zoltan /* nvram */ 198*addff513SBALATON Zoltan dev = qdev_new(TYPE_A1_NVRAM); 199*addff513SBALATON Zoltan di = drive_get(IF_MTD, 0, 0); 200*addff513SBALATON Zoltan if (di) { 201*addff513SBALATON Zoltan qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(di)); 202*addff513SBALATON Zoltan } 203*addff513SBALATON Zoltan sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 204*addff513SBALATON Zoltan memory_region_add_subregion(get_system_memory(), NVRAM_ADDR, 205*addff513SBALATON Zoltan sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0)); 206*addff513SBALATON Zoltan 207d9656f86SBALATON Zoltan /* allocate and load firmware */ 208d9656f86SBALATON Zoltan rom = g_new(MemoryRegion, 1); 209d9656f86SBALATON Zoltan memory_region_init_rom(rom, NULL, "rom", PROM_SIZE, &error_fatal); 210d9656f86SBALATON Zoltan memory_region_add_subregion(get_system_memory(), PROM_ADDR, rom); 211e25acd61SBALATON Zoltan if (!machine->firmware) { 212e25acd61SBALATON Zoltan rom_add_blob_fixed("dummy-fw", dummy_fw, sizeof(dummy_fw), 213e25acd61SBALATON Zoltan PROM_ADDR + PROM_SIZE - 0x80); 214e25acd61SBALATON Zoltan } else { 215e25acd61SBALATON Zoltan g_autofree char *filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, 216e25acd61SBALATON Zoltan machine->firmware); 217e25acd61SBALATON Zoltan if (!filename) { 218e25acd61SBALATON Zoltan error_report("Could not find firmware '%s'", machine->firmware); 219e25acd61SBALATON Zoltan exit(1); 220e25acd61SBALATON Zoltan } 221d9656f86SBALATON Zoltan sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE); 222d9656f86SBALATON Zoltan if (sz <= 0 || sz > PROM_SIZE) { 223d9656f86SBALATON Zoltan error_report("Could not load firmware '%s'", filename); 224d9656f86SBALATON Zoltan exit(1); 225d9656f86SBALATON Zoltan } 226d9656f86SBALATON Zoltan } 227d9656f86SBALATON Zoltan 228d9656f86SBALATON Zoltan /* Articia S */ 229d9656f86SBALATON Zoltan dev = sysbus_create_simple(TYPE_ARTICIA, 0xfe000000, NULL); 230d9656f86SBALATON Zoltan 231d9656f86SBALATON Zoltan i2c_bus = I2C_BUS(qdev_get_child_bus(dev, "smbus")); 232d9656f86SBALATON Zoltan if (machine->ram_size > 512 * MiB) { 233d9656f86SBALATON Zoltan spd_data = spd_data_generate(SDR, machine->ram_size / 2); 234d9656f86SBALATON Zoltan } else { 235d9656f86SBALATON Zoltan spd_data = spd_data_generate(SDR, machine->ram_size); 236d9656f86SBALATON Zoltan } 237d9656f86SBALATON Zoltan fix_spd_data(spd_data); 238d9656f86SBALATON Zoltan smbus_eeprom_init_one(i2c_bus, 0x51, spd_data); 239d9656f86SBALATON Zoltan if (machine->ram_size > 512 * MiB) { 240d9656f86SBALATON Zoltan smbus_eeprom_init_one(i2c_bus, 0x52, spd_data); 241d9656f86SBALATON Zoltan } 242d9656f86SBALATON Zoltan 243d9656f86SBALATON Zoltan pci_mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); 244d9656f86SBALATON Zoltan mr = g_new(MemoryRegion, 1); 245d9656f86SBALATON Zoltan memory_region_init_alias(mr, OBJECT(dev), "pci-mem-low", pci_mem, 246*addff513SBALATON Zoltan 0, 0xe0000); 247d9656f86SBALATON Zoltan memory_region_add_subregion(get_system_memory(), 0xfd000000, mr); 248d9656f86SBALATON Zoltan mr = g_new(MemoryRegion, 1); 249d9656f86SBALATON Zoltan memory_region_init_alias(mr, OBJECT(dev), "pci-mem-high", pci_mem, 250d9656f86SBALATON Zoltan 0x80000000, 0x7d000000); 251d9656f86SBALATON Zoltan memory_region_add_subregion(get_system_memory(), 0x80000000, mr); 252d9656f86SBALATON Zoltan pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci.0")); 253d9656f86SBALATON Zoltan 254d9656f86SBALATON Zoltan /* VIA VT82c686B South Bridge (multifunction PCI device) */ 255d9656f86SBALATON Zoltan via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(7, 0), 256d9656f86SBALATON Zoltan TYPE_VT82C686B_ISA)); 257d9656f86SBALATON Zoltan object_property_add_alias(OBJECT(machine), "rtc-time", 258d9656f86SBALATON Zoltan object_resolve_path_component(via, "rtc"), 259d9656f86SBALATON Zoltan "date"); 2609a365c25SBernhard Beschow qdev_connect_gpio_out_named(DEVICE(via), "intr", 0, 2619a365c25SBernhard Beschow qdev_get_gpio_in(DEVICE(cpu), 2629a365c25SBernhard Beschow PPC6xx_INPUT_INT)); 263*addff513SBALATON Zoltan for (int i = 0; i < PCI_NUM_PINS; i++) { 264d9656f86SBALATON Zoltan qdev_connect_gpio_out(dev, i, qdev_get_gpio_in_named(DEVICE(via), 265d9656f86SBALATON Zoltan "pirq", i)); 266d9656f86SBALATON Zoltan } 267d9656f86SBALATON Zoltan pci_ide_create_devs(PCI_DEVICE(object_resolve_path_component(via, "ide"))); 268d9656f86SBALATON Zoltan pci_vga_init(pci_bus); 269d9656f86SBALATON Zoltan } 270d9656f86SBALATON Zoltan 271d9656f86SBALATON Zoltan static void amigaone_machine_init(MachineClass *mc) 272d9656f86SBALATON Zoltan { 273d9656f86SBALATON Zoltan mc->desc = "Eyetech AmigaOne/Mai Logic Teron"; 274d9656f86SBALATON Zoltan mc->init = amigaone_init; 275d9656f86SBALATON Zoltan mc->block_default_type = IF_IDE; 276d9656f86SBALATON Zoltan mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7457_v1.2"); 277d9656f86SBALATON Zoltan mc->default_display = "std"; 278d9656f86SBALATON Zoltan mc->default_ram_id = "ram"; 279d9656f86SBALATON Zoltan mc->default_ram_size = 512 * MiB; 280d9656f86SBALATON Zoltan } 281d9656f86SBALATON Zoltan 282d9656f86SBALATON Zoltan DEFINE_MACHINE("amigaone", amigaone_machine_init) 283