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" 24d9656f86SBALATON Zoltan #include "sysemu/qtest.h" 25d9656f86SBALATON Zoltan #include "sysemu/reset.h" 26d9656f86SBALATON Zoltan #include "kvm_ppc.h" 27d9656f86SBALATON Zoltan 28d9656f86SBALATON Zoltan #define BUS_FREQ_HZ 100000000 29d9656f86SBALATON Zoltan 30d9656f86SBALATON Zoltan /* 31d9656f86SBALATON Zoltan * Firmware binary available at 32d9656f86SBALATON Zoltan * https://www.hyperion-entertainment.com/index.php/downloads?view=files&parent=28 33d9656f86SBALATON Zoltan * then "tail -c 524288 updater.image >u-boot-amigaone.bin" 34d9656f86SBALATON Zoltan * 35d9656f86SBALATON Zoltan * BIOS emulator in firmware cannot run QEMU vgabios and hangs on it, use 36d9656f86SBALATON Zoltan * -device VGA,romfile=VGABIOS-lgpl-latest.bin 37d9656f86SBALATON Zoltan * from http://www.nongnu.org/vgabios/ instead. 38d9656f86SBALATON Zoltan */ 39d9656f86SBALATON Zoltan #define PROM_ADDR 0xfff00000 40d9656f86SBALATON Zoltan #define PROM_SIZE (512 * KiB) 41d9656f86SBALATON Zoltan 42e25acd61SBALATON Zoltan /* AmigaOS calls this routine from ROM, use this if no firmware loaded */ 43e25acd61SBALATON Zoltan static const char dummy_fw[] = { 44e25acd61SBALATON Zoltan 0x38, 0x00, 0x00, 0x08, /* li r0,8 */ 45e25acd61SBALATON Zoltan 0x7c, 0x09, 0x03, 0xa6, /* mtctr r0 */ 46e25acd61SBALATON Zoltan 0x54, 0x63, 0xf8, 0x7e, /* srwi r3,r3,1 */ 47e25acd61SBALATON Zoltan 0x42, 0x00, 0xff, 0xfc, /* bdnz 0x8 */ 48e25acd61SBALATON Zoltan 0x7c, 0x63, 0x18, 0xf8, /* not r3,r3 */ 49e25acd61SBALATON Zoltan 0x4e, 0x80, 0x00, 0x20, /* blr */ 50e25acd61SBALATON Zoltan }; 51e25acd61SBALATON Zoltan 52d9656f86SBALATON Zoltan static void amigaone_cpu_reset(void *opaque) 53d9656f86SBALATON Zoltan { 54d9656f86SBALATON Zoltan PowerPCCPU *cpu = opaque; 55d9656f86SBALATON Zoltan 56d9656f86SBALATON Zoltan cpu_reset(CPU(cpu)); 57d9656f86SBALATON Zoltan cpu_ppc_tb_reset(&cpu->env); 58d9656f86SBALATON Zoltan } 59d9656f86SBALATON Zoltan 60d9656f86SBALATON Zoltan static void fix_spd_data(uint8_t *spd) 61d9656f86SBALATON Zoltan { 62d9656f86SBALATON Zoltan uint32_t bank_size = 4 * MiB * spd[31]; 63d9656f86SBALATON Zoltan uint32_t rows = bank_size / spd[13] / spd[17]; 64d9656f86SBALATON Zoltan spd[3] = ctz32(rows) - spd[4]; 65d9656f86SBALATON Zoltan } 66d9656f86SBALATON Zoltan 67d9656f86SBALATON Zoltan static void amigaone_init(MachineState *machine) 68d9656f86SBALATON Zoltan { 69d9656f86SBALATON Zoltan PowerPCCPU *cpu; 70d9656f86SBALATON Zoltan CPUPPCState *env; 71d9656f86SBALATON Zoltan MemoryRegion *rom, *pci_mem, *mr; 72d9656f86SBALATON Zoltan ssize_t sz; 73d9656f86SBALATON Zoltan PCIBus *pci_bus; 74d9656f86SBALATON Zoltan Object *via; 75d9656f86SBALATON Zoltan DeviceState *dev; 76d9656f86SBALATON Zoltan I2CBus *i2c_bus; 77d9656f86SBALATON Zoltan uint8_t *spd_data; 78d9656f86SBALATON Zoltan int i; 79d9656f86SBALATON Zoltan 80d9656f86SBALATON Zoltan /* init CPU */ 81d9656f86SBALATON Zoltan cpu = POWERPC_CPU(cpu_create(machine->cpu_type)); 82d9656f86SBALATON Zoltan env = &cpu->env; 83d9656f86SBALATON Zoltan if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { 84d9656f86SBALATON Zoltan error_report("Incompatible CPU, only 6xx bus supported"); 85d9656f86SBALATON Zoltan exit(1); 86d9656f86SBALATON Zoltan } 87d9656f86SBALATON Zoltan cpu_ppc_tb_init(env, BUS_FREQ_HZ / 4); 88d9656f86SBALATON Zoltan qemu_register_reset(amigaone_cpu_reset, cpu); 89d9656f86SBALATON Zoltan 90d9656f86SBALATON Zoltan /* RAM */ 91d9656f86SBALATON Zoltan if (machine->ram_size > 2 * GiB) { 92d9656f86SBALATON Zoltan error_report("RAM size more than 2 GiB is not supported"); 93d9656f86SBALATON Zoltan exit(1); 94d9656f86SBALATON Zoltan } 95d9656f86SBALATON Zoltan memory_region_add_subregion(get_system_memory(), 0, machine->ram); 96d9656f86SBALATON Zoltan if (machine->ram_size < 1 * GiB + 32 * KiB) { 97d9656f86SBALATON Zoltan /* Firmware uses this area for startup */ 98d9656f86SBALATON Zoltan mr = g_new(MemoryRegion, 1); 99d9656f86SBALATON Zoltan memory_region_init_ram(mr, NULL, "init-cache", 32 * KiB, &error_fatal); 100d9656f86SBALATON Zoltan memory_region_add_subregion(get_system_memory(), 0x40000000, mr); 101d9656f86SBALATON Zoltan } 102d9656f86SBALATON Zoltan 103d9656f86SBALATON Zoltan /* allocate and load firmware */ 104d9656f86SBALATON Zoltan rom = g_new(MemoryRegion, 1); 105d9656f86SBALATON Zoltan memory_region_init_rom(rom, NULL, "rom", PROM_SIZE, &error_fatal); 106d9656f86SBALATON Zoltan memory_region_add_subregion(get_system_memory(), PROM_ADDR, rom); 107e25acd61SBALATON Zoltan if (!machine->firmware) { 108e25acd61SBALATON Zoltan rom_add_blob_fixed("dummy-fw", dummy_fw, sizeof(dummy_fw), 109e25acd61SBALATON Zoltan PROM_ADDR + PROM_SIZE - 0x80); 110e25acd61SBALATON Zoltan } else { 111e25acd61SBALATON Zoltan g_autofree char *filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, 112e25acd61SBALATON Zoltan machine->firmware); 113e25acd61SBALATON Zoltan if (!filename) { 114e25acd61SBALATON Zoltan error_report("Could not find firmware '%s'", machine->firmware); 115e25acd61SBALATON Zoltan exit(1); 116e25acd61SBALATON Zoltan } 117d9656f86SBALATON Zoltan sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE); 118d9656f86SBALATON Zoltan if (sz <= 0 || sz > PROM_SIZE) { 119d9656f86SBALATON Zoltan error_report("Could not load firmware '%s'", filename); 120d9656f86SBALATON Zoltan exit(1); 121d9656f86SBALATON Zoltan } 122d9656f86SBALATON Zoltan } 123d9656f86SBALATON Zoltan 124d9656f86SBALATON Zoltan /* Articia S */ 125d9656f86SBALATON Zoltan dev = sysbus_create_simple(TYPE_ARTICIA, 0xfe000000, NULL); 126d9656f86SBALATON Zoltan 127d9656f86SBALATON Zoltan i2c_bus = I2C_BUS(qdev_get_child_bus(dev, "smbus")); 128d9656f86SBALATON Zoltan if (machine->ram_size > 512 * MiB) { 129d9656f86SBALATON Zoltan spd_data = spd_data_generate(SDR, machine->ram_size / 2); 130d9656f86SBALATON Zoltan } else { 131d9656f86SBALATON Zoltan spd_data = spd_data_generate(SDR, machine->ram_size); 132d9656f86SBALATON Zoltan } 133d9656f86SBALATON Zoltan fix_spd_data(spd_data); 134d9656f86SBALATON Zoltan smbus_eeprom_init_one(i2c_bus, 0x51, spd_data); 135d9656f86SBALATON Zoltan if (machine->ram_size > 512 * MiB) { 136d9656f86SBALATON Zoltan smbus_eeprom_init_one(i2c_bus, 0x52, spd_data); 137d9656f86SBALATON Zoltan } 138d9656f86SBALATON Zoltan 139d9656f86SBALATON Zoltan pci_mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); 140d9656f86SBALATON Zoltan mr = g_new(MemoryRegion, 1); 141d9656f86SBALATON Zoltan memory_region_init_alias(mr, OBJECT(dev), "pci-mem-low", pci_mem, 142d9656f86SBALATON Zoltan 0, 0x1000000); 143d9656f86SBALATON Zoltan memory_region_add_subregion(get_system_memory(), 0xfd000000, mr); 144d9656f86SBALATON Zoltan mr = g_new(MemoryRegion, 1); 145d9656f86SBALATON Zoltan memory_region_init_alias(mr, OBJECT(dev), "pci-mem-high", pci_mem, 146d9656f86SBALATON Zoltan 0x80000000, 0x7d000000); 147d9656f86SBALATON Zoltan memory_region_add_subregion(get_system_memory(), 0x80000000, mr); 148d9656f86SBALATON Zoltan pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci.0")); 149d9656f86SBALATON Zoltan 150d9656f86SBALATON Zoltan /* VIA VT82c686B South Bridge (multifunction PCI device) */ 151d9656f86SBALATON Zoltan via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(7, 0), 152d9656f86SBALATON Zoltan TYPE_VT82C686B_ISA)); 153d9656f86SBALATON Zoltan object_property_add_alias(OBJECT(machine), "rtc-time", 154d9656f86SBALATON Zoltan object_resolve_path_component(via, "rtc"), 155d9656f86SBALATON Zoltan "date"); 156*9a365c25SBernhard Beschow qdev_connect_gpio_out_named(DEVICE(via), "intr", 0, 157*9a365c25SBernhard Beschow qdev_get_gpio_in(DEVICE(cpu), 158*9a365c25SBernhard Beschow PPC6xx_INPUT_INT)); 159d9656f86SBALATON Zoltan for (i = 0; i < PCI_NUM_PINS; i++) { 160d9656f86SBALATON Zoltan qdev_connect_gpio_out(dev, i, qdev_get_gpio_in_named(DEVICE(via), 161d9656f86SBALATON Zoltan "pirq", i)); 162d9656f86SBALATON Zoltan } 163d9656f86SBALATON Zoltan pci_ide_create_devs(PCI_DEVICE(object_resolve_path_component(via, "ide"))); 164d9656f86SBALATON Zoltan pci_vga_init(pci_bus); 165d9656f86SBALATON Zoltan } 166d9656f86SBALATON Zoltan 167d9656f86SBALATON Zoltan static void amigaone_machine_init(MachineClass *mc) 168d9656f86SBALATON Zoltan { 169d9656f86SBALATON Zoltan mc->desc = "Eyetech AmigaOne/Mai Logic Teron"; 170d9656f86SBALATON Zoltan mc->init = amigaone_init; 171d9656f86SBALATON Zoltan mc->block_default_type = IF_IDE; 172d9656f86SBALATON Zoltan mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7457_v1.2"); 173d9656f86SBALATON Zoltan mc->default_display = "std"; 174d9656f86SBALATON Zoltan mc->default_ram_id = "ram"; 175d9656f86SBALATON Zoltan mc->default_ram_size = 512 * MiB; 176d9656f86SBALATON Zoltan } 177d9656f86SBALATON Zoltan 178d9656f86SBALATON Zoltan DEFINE_MACHINE("amigaone", amigaone_machine_init) 179