1baec1910SAndreas Färber /*
2baec1910SAndreas Färber * QEMU PowerPC CHRP (currently NewWorld PowerMac) hardware System Emulator
3baec1910SAndreas Färber *
4baec1910SAndreas Färber * Copyright (c) 2004-2007 Fabrice Bellard
5baec1910SAndreas Färber * Copyright (c) 2007 Jocelyn Mayer
6baec1910SAndreas Färber *
7baec1910SAndreas Färber * Permission is hereby granted, free of charge, to any person obtaining a copy
8baec1910SAndreas Färber * of this software and associated documentation files (the "Software"), to deal
9baec1910SAndreas Färber * in the Software without restriction, including without limitation the rights
10baec1910SAndreas Färber * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11baec1910SAndreas Färber * copies of the Software, and to permit persons to whom the Software is
12baec1910SAndreas Färber * furnished to do so, subject to the following conditions:
13baec1910SAndreas Färber *
14baec1910SAndreas Färber * The above copyright notice and this permission notice shall be included in
15baec1910SAndreas Färber * all copies or substantial portions of the Software.
16baec1910SAndreas Färber *
17baec1910SAndreas Färber * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18baec1910SAndreas Färber * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19baec1910SAndreas Färber * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20baec1910SAndreas Färber * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21baec1910SAndreas Färber * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22baec1910SAndreas Färber * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23baec1910SAndreas Färber * THE SOFTWARE.
24baec1910SAndreas Färber *
25baec1910SAndreas Färber * PCI bus layout on a real G5 (U3 based):
26baec1910SAndreas Färber *
27baec1910SAndreas Färber * 0000:f0:0b.0 Host bridge [0600]: Apple Computer Inc. U3 AGP [106b:004b]
28baec1910SAndreas Färber * 0000:f0:10.0 VGA compatible controller [0300]: ATI Technologies Inc RV350 AP [Radeon 9600] [1002:4150]
29baec1910SAndreas Färber * 0001:00:00.0 Host bridge [0600]: Apple Computer Inc. CPC945 HT Bridge [106b:004a]
30baec1910SAndreas Färber * 0001:00:01.0 PCI bridge [0604]: Advanced Micro Devices [AMD] AMD-8131 PCI-X Bridge [1022:7450] (rev 12)
31baec1910SAndreas Färber * 0001:00:02.0 PCI bridge [0604]: Advanced Micro Devices [AMD] AMD-8131 PCI-X Bridge [1022:7450] (rev 12)
32baec1910SAndreas Färber * 0001:00:03.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0045]
33baec1910SAndreas Färber * 0001:00:04.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0046]
34baec1910SAndreas Färber * 0001:00:05.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0047]
35baec1910SAndreas Färber * 0001:00:06.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0048]
36baec1910SAndreas Färber * 0001:00:07.0 PCI bridge [0604]: Apple Computer Inc. K2 HT-PCI Bridge [106b:0049]
37baec1910SAndreas Färber * 0001:01:07.0 Class [ff00]: Apple Computer Inc. K2 KeyLargo Mac/IO [106b:0041] (rev 20)
38baec1910SAndreas Färber * 0001:01:08.0 USB Controller [0c03]: Apple Computer Inc. K2 KeyLargo USB [106b:0040]
39baec1910SAndreas Färber * 0001:01:09.0 USB Controller [0c03]: Apple Computer Inc. K2 KeyLargo USB [106b:0040]
40baec1910SAndreas Färber * 0001:02:0b.0 USB Controller [0c03]: NEC Corporation USB [1033:0035] (rev 43)
41baec1910SAndreas Färber * 0001:02:0b.1 USB Controller [0c03]: NEC Corporation USB [1033:0035] (rev 43)
42baec1910SAndreas Färber * 0001:02:0b.2 USB Controller [0c03]: NEC Corporation USB 2.0 [1033:00e0] (rev 04)
43baec1910SAndreas Färber * 0001:03:0d.0 Class [ff00]: Apple Computer Inc. K2 ATA/100 [106b:0043]
44baec1910SAndreas Färber * 0001:03:0e.0 FireWire (IEEE 1394) [0c00]: Apple Computer Inc. K2 FireWire [106b:0042]
45baec1910SAndreas Färber * 0001:04:0f.0 Ethernet controller [0200]: Apple Computer Inc. K2 GMAC (Sun GEM) [106b:004c]
46baec1910SAndreas Färber * 0001:05:0c.0 IDE interface [0101]: Broadcom K2 SATA [1166:0240]
47baec1910SAndreas Färber */
48a8d25326SMarkus Armbruster
490d75590dSPeter Maydell #include "qemu/osdep.h"
502c65db5eSPaolo Bonzini #include "qemu/datadir.h"
51cfb47bfaSBALATON Zoltan #include "qemu/units.h"
52da34e65cSMarkus Armbruster #include "qapi/error.h"
530d09e41aSPaolo Bonzini #include "hw/ppc/ppc.h"
54a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
55443f07b7SBALATON Zoltan #include "hw/nvram/mac_nvram.h"
56cfb47bfaSBALATON Zoltan #include "hw/boards.h"
57cfb47bfaSBALATON Zoltan #include "hw/pci-host/uninorth.h"
580d09e41aSPaolo Bonzini #include "hw/input/adb.h"
590d09e41aSPaolo Bonzini #include "hw/ppc/mac_dbdma.h"
60baec1910SAndreas Färber #include "hw/pci/pci.h"
61baec1910SAndreas Färber #include "net/net.h"
62baec1910SAndreas Färber #include "sysemu/sysemu.h"
630d09e41aSPaolo Bonzini #include "hw/nvram/fw_cfg.h"
640d09e41aSPaolo Bonzini #include "hw/char/escc.h"
65e1218e48SMark Cave-Ayland #include "hw/misc/macio/macio.h"
660d09e41aSPaolo Bonzini #include "hw/ppc/openpic.h"
67baec1910SAndreas Färber #include "hw/loader.h"
685d19be6cSMark Cave-Ayland #include "hw/fw-path-provider.h"
69baec1910SAndreas Färber #include "elf.h"
70c525436eSMarkus Armbruster #include "qemu/error-report.h"
71baec1910SAndreas Färber #include "sysemu/kvm.h"
7271e8a915SMarkus Armbruster #include "sysemu/reset.h"
73baec1910SAndreas Färber #include "kvm_ppc.h"
74baec1910SAndreas Färber #include "hw/usb.h"
75baec1910SAndreas Färber #include "hw/sysbus.h"
765283c27fSLaurent Vivier #include "trace.h"
77baec1910SAndreas Färber
78baec1910SAndreas Färber #define MAX_IDE_BUS 2
79baec1910SAndreas Färber #define CFG_ADDR 0xf0000510
8078abf93cSMark Cave-Ayland #define TBFREQ (25UL * 1000UL * 1000UL)
813c062289SBenjamin Herrenschmidt #define CLOCKFREQ (900UL * 1000UL * 1000UL)
829d1c1283SBALATON Zoltan #define BUSFREQ (100UL * 1000UL * 1000UL)
83baec1910SAndreas Färber
8453ecf09dSMark Cave-Ayland #define NDRV_VGA_FILENAME "qemu_vga.ndrv"
8553ecf09dSMark Cave-Ayland
863d0031c1SBALATON Zoltan #define PROM_FILENAME "openbios-ppc"
8731a6f353SBALATON Zoltan #define PROM_BASE 0xfff00000
8831a6f353SBALATON Zoltan #define PROM_SIZE (1 * MiB)
89baec1910SAndreas Färber
903d0031c1SBALATON Zoltan #define KERNEL_LOAD_ADDR 0x01000000
913d0031c1SBALATON Zoltan #define KERNEL_GAP 0x00100000
923d0031c1SBALATON Zoltan
93cfb47bfaSBALATON Zoltan #define TYPE_CORE99_MACHINE MACHINE_TYPE_NAME("mac99")
94cfb47bfaSBALATON Zoltan typedef struct Core99MachineState Core99MachineState;
95cfb47bfaSBALATON Zoltan DECLARE_INSTANCE_CHECKER(Core99MachineState, CORE99_MACHINE,
96cfb47bfaSBALATON Zoltan TYPE_CORE99_MACHINE)
97cfb47bfaSBALATON Zoltan
9853cb552dSBALATON Zoltan typedef enum {
9953cb552dSBALATON Zoltan CORE99_VIA_CONFIG_CUDA = 0,
10053cb552dSBALATON Zoltan CORE99_VIA_CONFIG_PMU,
10153cb552dSBALATON Zoltan CORE99_VIA_CONFIG_PMU_ADB
10253cb552dSBALATON Zoltan } Core99ViaConfig;
103cfb47bfaSBALATON Zoltan
104cfb47bfaSBALATON Zoltan struct Core99MachineState {
105cfb47bfaSBALATON Zoltan /*< private >*/
106cfb47bfaSBALATON Zoltan MachineState parent;
107cfb47bfaSBALATON Zoltan
10853cb552dSBALATON Zoltan Core99ViaConfig via_config;
109cfb47bfaSBALATON Zoltan };
110cfb47bfaSBALATON Zoltan
fw_cfg_boot_set(void * opaque,const char * boot_device,Error ** errp)111ddcd5531SGonglei static void fw_cfg_boot_set(void *opaque, const char *boot_device,
112ddcd5531SGonglei Error **errp)
113baec1910SAndreas Färber {
11448779e50SGabriel L. Somlo fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
115baec1910SAndreas Färber }
116baec1910SAndreas Färber
translate_kernel_address(void * opaque,uint64_t addr)117baec1910SAndreas Färber static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
118baec1910SAndreas Färber {
119baec1910SAndreas Färber return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR;
120baec1910SAndreas Färber }
121baec1910SAndreas Färber
ppc_core99_reset(void * opaque)122baec1910SAndreas Färber static void ppc_core99_reset(void *opaque)
123baec1910SAndreas Färber {
124baec1910SAndreas Färber PowerPCCPU *cpu = opaque;
125baec1910SAndreas Färber
126baec1910SAndreas Färber cpu_reset(CPU(cpu));
12720f649ddSAlexander Graf /* 970 CPUs want to get their initial IP as part of their boot protocol */
12831a6f353SBALATON Zoltan cpu->env.nip = PROM_BASE + 0x100;
129baec1910SAndreas Färber }
130baec1910SAndreas Färber
131baec1910SAndreas Färber /* PowerPC Mac99 hardware initialisation */
ppc_core99_init(MachineState * machine)1323ef96221SMarcel Apfelbaum static void ppc_core99_init(MachineState *machine)
133baec1910SAndreas Färber {
134f1114c17SMark Cave-Ayland Core99MachineState *core99_machine = CORE99_MACHINE(machine);
135053b7086SThomas Huth MachineClass *mc = MACHINE_GET_CLASS(machine);
136baec1910SAndreas Färber PowerPCCPU *cpu = NULL;
137baec1910SAndreas Färber CPUPPCState *env = NULL;
138baec1910SAndreas Färber char *filename;
1399929301eSGreg Kurz IrqLines *openpic_irqs;
1406120dc8dSBALATON Zoltan int i, j, k, ppc_boot_device, machine_arch, bios_size = -1;
141cc4a140aSBALATON Zoltan const char *bios_name = machine->firmware ?: PROM_FILENAME;
142a5b5de02SIgor Mammedov MemoryRegion *bios = g_new(MemoryRegion, 1);
1436120dc8dSBALATON Zoltan hwaddr kernel_base = 0, initrd_base = 0, cmdline_base = 0;
1446120dc8dSBALATON Zoltan long kernel_size = 0, initrd_size = 0;
145baec1910SAndreas Färber PCIBus *pci_bus;
146f1114c17SMark Cave-Ayland bool has_pmu, has_adb;
14718e0383bSBALATON Zoltan Object *macio;
14807a7484eSAndreas Färber MACIOIDEState *macio_ide;
149293c867dSAndreas Färber BusState *adb_bus;
150baec1910SAndreas Färber MacIONVRAMState *nvr;
151baec1910SAndreas Färber DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
152baec1910SAndreas Färber void *fw_cfg;
153baec1910SAndreas Färber SysBusDevice *s;
15418e0383bSBALATON Zoltan DeviceState *dev, *pic_dev, *uninorth_pci_dev;
1556ce97b22SMark Cave-Ayland DeviceState *uninorth_internal_dev = NULL, *uninorth_agp_dev = NULL;
156261265ccSAlexander Graf hwaddr nvram_addr = 0xFFF04000;
1576b924abeSBALATON Zoltan uint64_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TBFREQ;
158baec1910SAndreas Färber
159baec1910SAndreas Färber /* init CPUs */
160cc4a140aSBALATON Zoltan for (i = 0; i < machine->smp.cpus; i++) {
1619dff4c07SIgor Mammedov cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
162baec1910SAndreas Färber env = &cpu->env;
163baec1910SAndreas Färber
164baec1910SAndreas Färber /* Set time-base frequency to 100 Mhz */
165536d8cdaSAlexander Graf cpu_ppc_tb_init(env, TBFREQ);
166baec1910SAndreas Färber qemu_register_reset(ppc_core99_reset, cpu);
167baec1910SAndreas Färber }
168baec1910SAndreas Färber
169baec1910SAndreas Färber /* allocate RAM */
17003b3542aSPhilippe Mathieu-Daudé if (machine->ram_size > 2 * GiB) {
17103b3542aSPhilippe Mathieu-Daudé error_report("RAM size more than 2 GiB is not supported");
17203b3542aSPhilippe Mathieu-Daudé exit(1);
17303b3542aSPhilippe Mathieu-Daudé }
174a5b5de02SIgor Mammedov memory_region_add_subregion(get_system_memory(), 0, machine->ram);
175baec1910SAndreas Färber
17631a6f353SBALATON Zoltan /* allocate and load firmware ROM */
17731a6f353SBALATON Zoltan memory_region_init_rom(bios, NULL, "ppc_core99.bios", PROM_SIZE,
178f8ed85acSMarkus Armbruster &error_fatal);
17931a6f353SBALATON Zoltan memory_region_add_subregion(get_system_memory(), PROM_BASE, bios);
180e206ad48SHu Tao
181baec1910SAndreas Färber filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
182baec1910SAndreas Färber if (filename) {
18331a6f353SBALATON Zoltan /* Load OpenBIOS (ELF) */
1844366e1dbSLiam Merwick bios_size = load_elf(filename, NULL, NULL, NULL, NULL,
1856cdda0ffSAleksandar Markovic NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);
186baec1910SAndreas Färber
18731a6f353SBALATON Zoltan if (bios_size <= 0) {
18831a6f353SBALATON Zoltan /* or load binary ROM image */
18931a6f353SBALATON Zoltan bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE);
19031a6f353SBALATON Zoltan }
191baec1910SAndreas Färber g_free(filename);
192baec1910SAndreas Färber }
19331a6f353SBALATON Zoltan if (bios_size < 0 || bios_size > PROM_SIZE) {
194c525436eSMarkus Armbruster error_report("could not load PowerPC bios '%s'", bios_name);
195baec1910SAndreas Färber exit(1);
196baec1910SAndreas Färber }
197baec1910SAndreas Färber
198cc4a140aSBALATON Zoltan if (machine->kernel_filename) {
1996120dc8dSBALATON Zoltan int bswap_needed = 0;
200baec1910SAndreas Färber
201baec1910SAndreas Färber #ifdef BSWAP_NEEDED
202baec1910SAndreas Färber bswap_needed = 1;
203baec1910SAndreas Färber #endif
204baec1910SAndreas Färber kernel_base = KERNEL_LOAD_ADDR;
205cc4a140aSBALATON Zoltan kernel_size = load_elf(machine->kernel_filename, NULL,
206617160c9SBALATON Zoltan translate_kernel_address, NULL, NULL, NULL,
207617160c9SBALATON Zoltan NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0);
208cc537e13SBALATON Zoltan if (kernel_size < 0) {
209cc4a140aSBALATON Zoltan kernel_size = load_aout(machine->kernel_filename, kernel_base,
210cc4a140aSBALATON Zoltan machine->ram_size - kernel_base,
211cc4a140aSBALATON Zoltan bswap_needed, TARGET_PAGE_SIZE);
212cc537e13SBALATON Zoltan }
213cc537e13SBALATON Zoltan if (kernel_size < 0) {
214cc4a140aSBALATON Zoltan kernel_size = load_image_targphys(machine->kernel_filename,
215baec1910SAndreas Färber kernel_base,
216cc4a140aSBALATON Zoltan machine->ram_size - kernel_base);
217cc537e13SBALATON Zoltan }
218baec1910SAndreas Färber if (kernel_size < 0) {
219cc4a140aSBALATON Zoltan error_report("could not load kernel '%s'",
220cc4a140aSBALATON Zoltan machine->kernel_filename);
221baec1910SAndreas Färber exit(1);
222baec1910SAndreas Färber }
223baec1910SAndreas Färber /* load initrd */
224cc4a140aSBALATON Zoltan if (machine->initrd_filename) {
22539d96847SKamil Rytarowski initrd_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP);
226cc4a140aSBALATON Zoltan initrd_size = load_image_targphys(machine->initrd_filename,
227cc4a140aSBALATON Zoltan initrd_base,
228cc4a140aSBALATON Zoltan machine->ram_size - initrd_base);
229baec1910SAndreas Färber if (initrd_size < 0) {
230c525436eSMarkus Armbruster error_report("could not load initial ram disk '%s'",
231cc4a140aSBALATON Zoltan machine->initrd_filename);
232baec1910SAndreas Färber exit(1);
233baec1910SAndreas Färber }
23439d96847SKamil Rytarowski cmdline_base = TARGET_PAGE_ALIGN(initrd_base + initrd_size);
235baec1910SAndreas Färber } else {
23639d96847SKamil Rytarowski cmdline_base = TARGET_PAGE_ALIGN(kernel_base + kernel_size + KERNEL_GAP);
237baec1910SAndreas Färber }
238baec1910SAndreas Färber ppc_boot_device = 'm';
239baec1910SAndreas Färber } else {
240baec1910SAndreas Färber ppc_boot_device = '\0';
241baec1910SAndreas Färber /* We consider that NewWorld PowerMac never have any floppy drive
242baec1910SAndreas Färber * For now, OHW cannot boot from the network.
243baec1910SAndreas Färber */
244cc4a140aSBALATON Zoltan for (i = 0; machine->boot_config.order[i] != '\0'; i++) {
245cc4a140aSBALATON Zoltan if (machine->boot_config.order[i] >= 'c' &&
246cc4a140aSBALATON Zoltan machine->boot_config.order[i] <= 'f') {
247cc4a140aSBALATON Zoltan ppc_boot_device = machine->boot_config.order[i];
248baec1910SAndreas Färber break;
249baec1910SAndreas Färber }
250baec1910SAndreas Färber }
251baec1910SAndreas Färber if (ppc_boot_device == '\0') {
2526f76b817SAlistair Francis error_report("No valid boot device for Mac99 machine");
253baec1910SAndreas Färber exit(1);
254baec1910SAndreas Färber }
255baec1910SAndreas Färber }
256baec1910SAndreas Färber
257cc4a140aSBALATON Zoltan openpic_irqs = g_new0(IrqLines, machine->smp.cpus);
25818e0383bSBALATON Zoltan dev = DEVICE(cpu);
259cc4a140aSBALATON Zoltan for (i = 0; i < machine->smp.cpus; i++) {
260baec1910SAndreas Färber /* Mac99 IRQ connection between OpenPIC outputs pins
261baec1910SAndreas Färber * and PowerPC input pins
262baec1910SAndreas Färber */
263baec1910SAndreas Färber switch (PPC_INPUT(env)) {
264baec1910SAndreas Färber case PPC_FLAGS_INPUT_6xx:
2659929301eSGreg Kurz openpic_irqs[i].irq[OPENPIC_OUTPUT_INT] =
26618e0383bSBALATON Zoltan qdev_get_gpio_in(dev, PPC6xx_INPUT_INT);
2679929301eSGreg Kurz openpic_irqs[i].irq[OPENPIC_OUTPUT_CINT] =
26818e0383bSBALATON Zoltan qdev_get_gpio_in(dev, PPC6xx_INPUT_INT);
2699929301eSGreg Kurz openpic_irqs[i].irq[OPENPIC_OUTPUT_MCK] =
27018e0383bSBALATON Zoltan qdev_get_gpio_in(dev, PPC6xx_INPUT_MCP);
271baec1910SAndreas Färber /* Not connected ? */
2729929301eSGreg Kurz openpic_irqs[i].irq[OPENPIC_OUTPUT_DEBUG] = NULL;
273baec1910SAndreas Färber /* Check this */
2749929301eSGreg Kurz openpic_irqs[i].irq[OPENPIC_OUTPUT_RESET] =
27518e0383bSBALATON Zoltan qdev_get_gpio_in(dev, PPC6xx_INPUT_HRESET);
276baec1910SAndreas Färber break;
277baec1910SAndreas Färber #if defined(TARGET_PPC64)
278baec1910SAndreas Färber case PPC_FLAGS_INPUT_970:
2799929301eSGreg Kurz openpic_irqs[i].irq[OPENPIC_OUTPUT_INT] =
28018e0383bSBALATON Zoltan qdev_get_gpio_in(dev, PPC970_INPUT_INT);
2819929301eSGreg Kurz openpic_irqs[i].irq[OPENPIC_OUTPUT_CINT] =
28218e0383bSBALATON Zoltan qdev_get_gpio_in(dev, PPC970_INPUT_INT);
2839929301eSGreg Kurz openpic_irqs[i].irq[OPENPIC_OUTPUT_MCK] =
28418e0383bSBALATON Zoltan qdev_get_gpio_in(dev, PPC970_INPUT_MCP);
285baec1910SAndreas Färber /* Not connected ? */
2869929301eSGreg Kurz openpic_irqs[i].irq[OPENPIC_OUTPUT_DEBUG] = NULL;
287baec1910SAndreas Färber /* Check this */
2889929301eSGreg Kurz openpic_irqs[i].irq[OPENPIC_OUTPUT_RESET] =
28918e0383bSBALATON Zoltan qdev_get_gpio_in(dev, PPC970_INPUT_HRESET);
290baec1910SAndreas Färber break;
291baec1910SAndreas Färber #endif /* defined(TARGET_PPC64) */
292baec1910SAndreas Färber default:
293c525436eSMarkus Armbruster error_report("Bus model not supported on mac99 machine");
294baec1910SAndreas Färber exit(1);
295baec1910SAndreas Färber }
296baec1910SAndreas Färber }
297baec1910SAndreas Färber
29850c496d2SBALATON Zoltan /* UniN init */
29950c496d2SBALATON Zoltan s = SYS_BUS_DEVICE(qdev_new(TYPE_UNI_NORTH));
30050c496d2SBALATON Zoltan sysbus_realize_and_unref(s, &error_fatal);
30150c496d2SBALATON Zoltan memory_region_add_subregion(get_system_memory(), 0xf8000000,
30250c496d2SBALATON Zoltan sysbus_mmio_get_region(s, 0));
30350c496d2SBALATON Zoltan
304baec1910SAndreas Färber if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
30550c496d2SBALATON Zoltan machine_arch = ARCH_MAC99_U3;
306baec1910SAndreas Färber /* 970 gets a U3 bus */
3078ce3f743SMark Cave-Ayland /* Uninorth AGP bus */
30818e0383bSBALATON Zoltan uninorth_pci_dev = qdev_new(TYPE_U3_AGP_HOST_BRIDGE);
30918e0383bSBALATON Zoltan s = SYS_BUS_DEVICE(uninorth_pci_dev);
31050c496d2SBALATON Zoltan sysbus_realize_and_unref(s, &error_fatal);
31150c496d2SBALATON Zoltan sysbus_mmio_map(s, 0, 0xf0800000);
31250c496d2SBALATON Zoltan sysbus_mmio_map(s, 1, 0xf0c00000);
3138ce3f743SMark Cave-Ayland /* PCI hole */
31450c496d2SBALATON Zoltan memory_region_add_subregion(get_system_memory(), 0x80000000,
3158ce3f743SMark Cave-Ayland sysbus_mmio_get_region(s, 2));
316e226efbbSMark Cave-Ayland /* Register 8 MB of ISA IO space */
317e226efbbSMark Cave-Ayland memory_region_add_subregion(get_system_memory(), 0xf2000000,
318e226efbbSMark Cave-Ayland sysbus_mmio_get_region(s, 3));
319baec1910SAndreas Färber } else {
32050c496d2SBALATON Zoltan machine_arch = ARCH_MAC99;
3217b19318bSMark Cave-Ayland /* Use values found on a real PowerMac */
3227b19318bSMark Cave-Ayland /* Uninorth AGP bus */
3236ce97b22SMark Cave-Ayland uninorth_agp_dev = qdev_new(TYPE_UNI_NORTH_AGP_HOST_BRIDGE);
3246ce97b22SMark Cave-Ayland s = SYS_BUS_DEVICE(uninorth_agp_dev);
3253c6ef471SMarkus Armbruster sysbus_realize_and_unref(s, &error_fatal);
3267b19318bSMark Cave-Ayland sysbus_mmio_map(s, 0, 0xf0800000);
3277b19318bSMark Cave-Ayland sysbus_mmio_map(s, 1, 0xf0c00000);
3287b19318bSMark Cave-Ayland
3297b19318bSMark Cave-Ayland /* Uninorth internal bus */
3306ce97b22SMark Cave-Ayland uninorth_internal_dev = qdev_new(
3316ce97b22SMark Cave-Ayland TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE);
3326ce97b22SMark Cave-Ayland s = SYS_BUS_DEVICE(uninorth_internal_dev);
3333c6ef471SMarkus Armbruster sysbus_realize_and_unref(s, &error_fatal);
3347b19318bSMark Cave-Ayland sysbus_mmio_map(s, 0, 0xf4800000);
3357b19318bSMark Cave-Ayland sysbus_mmio_map(s, 1, 0xf4c00000);
3367b19318bSMark Cave-Ayland
33750c496d2SBALATON Zoltan /* Uninorth main bus - this must be last to make it the default */
33818e0383bSBALATON Zoltan uninorth_pci_dev = qdev_new(TYPE_UNI_NORTH_PCI_HOST_BRIDGE);
33918e0383bSBALATON Zoltan qdev_prop_set_uint32(uninorth_pci_dev, "ofw-addr", 0xf2000000);
34018e0383bSBALATON Zoltan s = SYS_BUS_DEVICE(uninorth_pci_dev);
34150c496d2SBALATON Zoltan sysbus_realize_and_unref(s, &error_fatal);
34250c496d2SBALATON Zoltan sysbus_mmio_map(s, 0, 0xf2800000);
34350c496d2SBALATON Zoltan sysbus_mmio_map(s, 1, 0xf2c00000);
3447b19318bSMark Cave-Ayland /* PCI hole */
34550c496d2SBALATON Zoltan memory_region_add_subregion(get_system_memory(), 0x80000000,
3467b19318bSMark Cave-Ayland sysbus_mmio_get_region(s, 2));
347e226efbbSMark Cave-Ayland /* Register 8 MB of ISA IO space */
348e226efbbSMark Cave-Ayland memory_region_add_subregion(get_system_memory(), 0xf2000000,
349e226efbbSMark Cave-Ayland sysbus_mmio_get_region(s, 3));
350baec1910SAndreas Färber }
351caae6c96SAlexander Graf
35272f1f97dSAlexander Graf machine->usb |= defaults_enabled() && !machine->usb_disabled;
353f1114c17SMark Cave-Ayland has_pmu = (core99_machine->via_config != CORE99_VIA_CONFIG_CUDA);
354f1114c17SMark Cave-Ayland has_adb = (core99_machine->via_config == CORE99_VIA_CONFIG_CUDA ||
355f1114c17SMark Cave-Ayland core99_machine->via_config == CORE99_VIA_CONFIG_PMU_ADB);
35672f1f97dSAlexander Graf
3570f4b5415SMark Cave-Ayland /* init basic PC hardware */
35818e0383bSBALATON Zoltan pci_bus = PCI_HOST_BRIDGE(uninorth_pci_dev)->bus;
3590f4b5415SMark Cave-Ayland
360343bd85aSMark Cave-Ayland /* MacIO */
36118e0383bSBALATON Zoltan macio = OBJECT(pci_new(-1, TYPE_NEWWORLD_MACIO));
36207a7484eSAndreas Färber dev = DEVICE(macio);
363b981289cSAlexander Graf qdev_prop_set_uint64(dev, "frequency", tbfreq);
364f1114c17SMark Cave-Ayland qdev_prop_set_bit(dev, "has-pmu", has_pmu);
365f1114c17SMark Cave-Ayland qdev_prop_set_bit(dev, "has-adb", has_adb);
366348b8d1aSMark Cave-Ayland
36718e0383bSBALATON Zoltan dev = DEVICE(object_resolve_path_component(macio, "escc"));
36818e0383bSBALATON Zoltan qdev_prop_set_chr(dev, "chrA", serial_hd(0));
36918e0383bSBALATON Zoltan qdev_prop_set_chr(dev, "chrB", serial_hd(1));
370348b8d1aSMark Cave-Ayland
37118e0383bSBALATON Zoltan pci_realize_and_unref(PCI_DEVICE(macio), pci_bus, &error_fatal);
37207a7484eSAndreas Färber
37318e0383bSBALATON Zoltan pic_dev = DEVICE(object_resolve_path_component(macio, "pic"));
3746ce97b22SMark Cave-Ayland for (i = 0; i < 4; i++) {
37518e0383bSBALATON Zoltan qdev_connect_gpio_out(uninorth_pci_dev, i,
3766ce97b22SMark Cave-Ayland qdev_get_gpio_in(pic_dev, 0x1b + i));
3776ce97b22SMark Cave-Ayland }
3786ce97b22SMark Cave-Ayland
3796ce97b22SMark Cave-Ayland /* TODO: additional PCI buses only wired up for 32-bit machines */
3806ce97b22SMark Cave-Ayland if (PPC_INPUT(env) != PPC_FLAGS_INPUT_970) {
3816ce97b22SMark Cave-Ayland /* Uninorth AGP bus */
3826ce97b22SMark Cave-Ayland for (i = 0; i < 4; i++) {
3836ce97b22SMark Cave-Ayland qdev_connect_gpio_out(uninorth_agp_dev, i,
3846ce97b22SMark Cave-Ayland qdev_get_gpio_in(pic_dev, 0x1b + i));
3856ce97b22SMark Cave-Ayland }
3866ce97b22SMark Cave-Ayland
3876ce97b22SMark Cave-Ayland /* Uninorth internal bus */
3886ce97b22SMark Cave-Ayland for (i = 0; i < 4; i++) {
3896ce97b22SMark Cave-Ayland qdev_connect_gpio_out(uninorth_internal_dev, i,
3906ce97b22SMark Cave-Ayland qdev_get_gpio_in(pic_dev, 0x1b + i));
3916ce97b22SMark Cave-Ayland }
3926ce97b22SMark Cave-Ayland }
3936ce97b22SMark Cave-Ayland
3947e4d62dfSMark Cave-Ayland /* OpenPIC */
3957e4d62dfSMark Cave-Ayland s = SYS_BUS_DEVICE(pic_dev);
3967e4d62dfSMark Cave-Ayland k = 0;
397cc4a140aSBALATON Zoltan for (i = 0; i < machine->smp.cpus; i++) {
3987e4d62dfSMark Cave-Ayland for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
3997e4d62dfSMark Cave-Ayland sysbus_connect_irq(s, k++, openpic_irqs[i].irq[j]);
4007e4d62dfSMark Cave-Ayland }
4017e4d62dfSMark Cave-Ayland }
4027e4d62dfSMark Cave-Ayland g_free(openpic_irqs);
4037e4d62dfSMark Cave-Ayland
40407a7484eSAndreas Färber /* We only emulate 2 out of 3 IDE controllers for now */
405d8f94e1bSJohn Snow ide_drive_get(hd, ARRAY_SIZE(hd));
406a0bb2a5fSBALATON Zoltan
40718e0383bSBALATON Zoltan macio_ide = MACIO_IDE(object_resolve_path_component(macio, "ide[0]"));
40807a7484eSAndreas Färber macio_ide_init_drives(macio_ide, hd);
40907a7484eSAndreas Färber
41018e0383bSBALATON Zoltan macio_ide = MACIO_IDE(object_resolve_path_component(macio, "ide[1]"));
41107a7484eSAndreas Färber macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);
412baec1910SAndreas Färber
413f1114c17SMark Cave-Ayland if (has_adb) {
414d811d61fSMark Cave-Ayland if (has_pmu) {
41518e0383bSBALATON Zoltan dev = DEVICE(object_resolve_path_component(macio, "pmu"));
416d811d61fSMark Cave-Ayland } else {
41718e0383bSBALATON Zoltan dev = DEVICE(object_resolve_path_component(macio, "cuda"));
418d811d61fSMark Cave-Ayland }
419d811d61fSMark Cave-Ayland
420293c867dSAndreas Färber adb_bus = qdev_get_child_bus(dev, "adb.0");
4213e80f690SMarkus Armbruster dev = qdev_new(TYPE_ADB_KEYBOARD);
4223e80f690SMarkus Armbruster qdev_realize_and_unref(dev, adb_bus, &error_fatal);
423d811d61fSMark Cave-Ayland
4243e80f690SMarkus Armbruster dev = qdev_new(TYPE_ADB_MOUSE);
4253e80f690SMarkus Armbruster qdev_realize_and_unref(dev, adb_bus, &error_fatal);
426f1114c17SMark Cave-Ayland }
42745fa67fbSAndreas Färber
42859a04198SMarcel Apfelbaum if (machine->usb) {
429baec1910SAndreas Färber pci_create_simple(pci_bus, -1, "pci-ohci");
430c86580b8SMarkus Armbruster
431baec1910SAndreas Färber /* U3 needs to use USB for input because Linux doesn't support via-cuda
432baec1910SAndreas Färber on PPC64 */
433f1114c17SMark Cave-Ayland if (!has_adb || machine_arch == ARCH_MAC99_U3) {
4342dd2f2e0SPaolo Bonzini USBBus *usb_bus;
435c86580b8SMarkus Armbruster
4362dd2f2e0SPaolo Bonzini usb_bus = USB_BUS(object_resolve_type_unambiguous(TYPE_USB_BUS,
4372dd2f2e0SPaolo Bonzini &error_abort));
438c86580b8SMarkus Armbruster usb_create_simple(usb_bus, "usb-kbd");
439c86580b8SMarkus Armbruster usb_create_simple(usb_bus, "usb-mouse");
440baec1910SAndreas Färber }
441baec1910SAndreas Färber }
442baec1910SAndreas Färber
443a0bb2a5fSBALATON Zoltan pci_vga_init(pci_bus);
444a0bb2a5fSBALATON Zoltan
445a0bb2a5fSBALATON Zoltan if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) {
446baec1910SAndreas Färber graphic_depth = 15;
447a0bb2a5fSBALATON Zoltan }
448a0bb2a5fSBALATON Zoltan
44936b6968dSDavid Woodhouse pci_init_nic_devices(pci_bus, mc->default_nic);
450baec1910SAndreas Färber
451baec1910SAndreas Färber /* The NewWorld NVRAM is not located in the MacIO device */
4528e3b0cbbSMarc-André Lureau if (kvm_enabled() && qemu_real_host_page_size() > 4096) {
453261265ccSAlexander Graf /* We can't combine read-write and read-only in a single page, so
454261265ccSAlexander Graf move the NVRAM out of ROM again for KVM */
455261265ccSAlexander Graf nvram_addr = 0xFFE00000;
456261265ccSAlexander Graf }
4573e80f690SMarkus Armbruster dev = qdev_new(TYPE_MACIO_NVRAM);
458458586feSBALATON Zoltan qdev_prop_set_uint32(dev, "size", MACIO_NVRAM_SIZE);
45995ed3b7cSAndreas Färber qdev_prop_set_uint32(dev, "it_shift", 1);
4603c6ef471SMarkus Armbruster sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
461261265ccSAlexander Graf sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, nvram_addr);
46295ed3b7cSAndreas Färber nvr = MACIO_NVRAM(dev);
463458586feSBALATON Zoltan pmac_format_nvram_partition(nvr, MACIO_NVRAM_SIZE);
464baec1910SAndreas Färber /* No PCI init: the BIOS will do it */
465baec1910SAndreas Färber
4663e80f690SMarkus Armbruster dev = qdev_new(TYPE_FW_CFG_MEM);
46774887ed9SMark Cave-Ayland fw_cfg = FW_CFG(dev);
46874887ed9SMark Cave-Ayland qdev_prop_set_uint32(dev, "data_width", 1);
46974887ed9SMark Cave-Ayland qdev_prop_set_bit(dev, "dma_enabled", false);
4704db4847dSBALATON Zoltan object_property_add_child(OBJECT(machine), TYPE_FW_CFG, OBJECT(fw_cfg));
47174887ed9SMark Cave-Ayland s = SYS_BUS_DEVICE(dev);
4723c6ef471SMarkus Armbruster sysbus_realize_and_unref(s, &error_fatal);
47374887ed9SMark Cave-Ayland sysbus_mmio_map(s, 0, CFG_ADDR);
47474887ed9SMark Cave-Ayland sysbus_mmio_map(s, 1, CFG_ADDR + 2);
47574887ed9SMark Cave-Ayland
476cc4a140aSBALATON Zoltan fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)machine->smp.cpus);
477fe6b6346SLike Xu fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)machine->smp.max_cpus);
478cc4a140aSBALATON Zoltan fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)machine->ram_size);
479baec1910SAndreas Färber fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch);
480baec1910SAndreas Färber fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base);
481baec1910SAndreas Färber fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
482cc4a140aSBALATON Zoltan if (machine->kernel_cmdline) {
483baec1910SAndreas Färber fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base);
484cc4a140aSBALATON Zoltan pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE,
485cc4a140aSBALATON Zoltan machine->kernel_cmdline);
486baec1910SAndreas Färber } else {
487baec1910SAndreas Färber fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
488baec1910SAndreas Färber }
489baec1910SAndreas Färber fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base);
490baec1910SAndreas Färber fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
491baec1910SAndreas Färber fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device);
492baec1910SAndreas Färber
493baec1910SAndreas Färber fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width);
494baec1910SAndreas Färber fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height);
495baec1910SAndreas Färber fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth);
496baec1910SAndreas Färber
497f1114c17SMark Cave-Ayland fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_VIACONFIG, core99_machine->via_config);
498f1114c17SMark Cave-Ayland
499baec1910SAndreas Färber fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
500baec1910SAndreas Färber if (kvm_enabled()) {
501baec1910SAndreas Färber uint8_t *hypercall;
502baec1910SAndreas Färber
503baec1910SAndreas Färber hypercall = g_malloc(16);
504baec1910SAndreas Färber kvmppc_get_hypercall(env, hypercall, 16);
505baec1910SAndreas Färber fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
506baec1910SAndreas Färber fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
507baec1910SAndreas Färber }
508caae6c96SAlexander Graf fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, tbfreq);
509a1014f25SAlexander Graf /* Mac OS X requires a "known good" clock-frequency value; pass it one. */
5109d1c1283SBALATON Zoltan fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, CLOCKFREQ);
5119d1c1283SBALATON Zoltan fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_BUSFREQ, BUSFREQ);
512261265ccSAlexander Graf fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_NVRAM_ADDR, nvram_addr);
513baec1910SAndreas Färber
51453ecf09dSMark Cave-Ayland /* MacOS NDRV VGA driver */
51553ecf09dSMark Cave-Ayland filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, NDRV_VGA_FILENAME);
51653ecf09dSMark Cave-Ayland if (filename) {
5179776874fSPeter Maydell gchar *ndrv_file;
5189776874fSPeter Maydell gsize ndrv_size;
51953ecf09dSMark Cave-Ayland
5209776874fSPeter Maydell if (g_file_get_contents(filename, &ndrv_file, &ndrv_size, NULL)) {
52153ecf09dSMark Cave-Ayland fw_cfg_add_file(fw_cfg, "ndrv/qemu_vga.ndrv", ndrv_file, ndrv_size);
52253ecf09dSMark Cave-Ayland }
52353ecf09dSMark Cave-Ayland g_free(filename);
52453ecf09dSMark Cave-Ayland }
52553ecf09dSMark Cave-Ayland
526baec1910SAndreas Färber qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
527baec1910SAndreas Färber }
528baec1910SAndreas Färber
5295d19be6cSMark Cave-Ayland /*
5305d19be6cSMark Cave-Ayland * Implementation of an interface to adjust firmware path
5315d19be6cSMark Cave-Ayland * for the bootindex property handling.
5325d19be6cSMark Cave-Ayland */
core99_fw_dev_path(FWPathProvider * p,BusState * bus,DeviceState * dev)5335d19be6cSMark Cave-Ayland static char *core99_fw_dev_path(FWPathProvider *p, BusState *bus,
5345d19be6cSMark Cave-Ayland DeviceState *dev)
5355d19be6cSMark Cave-Ayland {
5365d19be6cSMark Cave-Ayland PCIDevice *pci;
5375d19be6cSMark Cave-Ayland MACIOIDEState *macio_ide;
5385d19be6cSMark Cave-Ayland
5395d19be6cSMark Cave-Ayland if (!strcmp(object_get_typename(OBJECT(dev)), "macio-newworld")) {
5405d19be6cSMark Cave-Ayland pci = PCI_DEVICE(dev);
5415d19be6cSMark Cave-Ayland return g_strdup_printf("mac-io@%x", PCI_SLOT(pci->devfn));
5425d19be6cSMark Cave-Ayland }
5435d19be6cSMark Cave-Ayland
5445d19be6cSMark Cave-Ayland if (!strcmp(object_get_typename(OBJECT(dev)), "macio-ide")) {
5455d19be6cSMark Cave-Ayland macio_ide = MACIO_IDE(dev);
5465d19be6cSMark Cave-Ayland return g_strdup_printf("ata-3@%x", macio_ide->addr);
5475d19be6cSMark Cave-Ayland }
5485d19be6cSMark Cave-Ayland
5495d19be6cSMark Cave-Ayland if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) {
55031bc6fa7SMark Cave-Ayland return g_strdup("disk");
5515d19be6cSMark Cave-Ayland }
5525d19be6cSMark Cave-Ayland
5535d19be6cSMark Cave-Ayland if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) {
5545d19be6cSMark Cave-Ayland return g_strdup("cdrom");
5555d19be6cSMark Cave-Ayland }
5565d19be6cSMark Cave-Ayland
5575d19be6cSMark Cave-Ayland if (!strcmp(object_get_typename(OBJECT(dev)), "virtio-blk-device")) {
5585d19be6cSMark Cave-Ayland return g_strdup("disk");
5595d19be6cSMark Cave-Ayland }
5605d19be6cSMark Cave-Ayland
5615d19be6cSMark Cave-Ayland return NULL;
5625d19be6cSMark Cave-Ayland }
core99_kvm_type(MachineState * machine,const char * arg)563dc0ca80eSEric Auger static int core99_kvm_type(MachineState *machine, const char *arg)
564277c7a4dSAlexander Graf {
565277c7a4dSAlexander Graf /* Always force PR KVM */
566277c7a4dSAlexander Graf return 2;
567277c7a4dSAlexander Graf }
568277c7a4dSAlexander Graf
core99_machine_class_init(ObjectClass * oc,void * data)569b1c2fb9bSMarcel Apfelbaum static void core99_machine_class_init(ObjectClass *oc, void *data)
570baec1910SAndreas Färber {
571b1c2fb9bSMarcel Apfelbaum MachineClass *mc = MACHINE_CLASS(oc);
5725d19be6cSMark Cave-Ayland FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
573b1c2fb9bSMarcel Apfelbaum
574*9d906ad1STejas Vipin mc->desc = "Mac99 based PowerMac";
575b1c2fb9bSMarcel Apfelbaum mc->init = ppc_core99_init;
5762059839bSMarkus Armbruster mc->block_default_type = IF_IDE;
57783234b82SPeter Maydell /* SMP is not supported currently */
57883234b82SPeter Maydell mc->max_cpus = 1;
579b1c2fb9bSMarcel Apfelbaum mc->default_boot_order = "cd";
5803232794bSMark Cave-Ayland mc->default_display = "std";
581053b7086SThomas Huth mc->default_nic = "sungem";
582b1c2fb9bSMarcel Apfelbaum mc->kvm_type = core99_kvm_type;
5839dff4c07SIgor Mammedov #ifdef TARGET_PPC64
5849dff4c07SIgor Mammedov mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("970fx_v3.1");
5859dff4c07SIgor Mammedov #else
5869dff4c07SIgor Mammedov mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7400_v2.9");
5879dff4c07SIgor Mammedov #endif
588a5b5de02SIgor Mammedov mc->default_ram_id = "ppc_core99.ram";
5895d19be6cSMark Cave-Ayland mc->ignore_boot_device_suffixes = true;
5905d19be6cSMark Cave-Ayland fwc->get_dev_path = core99_fw_dev_path;
591baec1910SAndreas Färber }
592baec1910SAndreas Färber
core99_get_via_config(Object * obj,Error ** errp)593f1114c17SMark Cave-Ayland static char *core99_get_via_config(Object *obj, Error **errp)
594f1114c17SMark Cave-Ayland {
595f1114c17SMark Cave-Ayland Core99MachineState *cms = CORE99_MACHINE(obj);
596f1114c17SMark Cave-Ayland
597f1114c17SMark Cave-Ayland switch (cms->via_config) {
598f1114c17SMark Cave-Ayland default:
599f1114c17SMark Cave-Ayland case CORE99_VIA_CONFIG_CUDA:
600f1114c17SMark Cave-Ayland return g_strdup("cuda");
601f1114c17SMark Cave-Ayland
602f1114c17SMark Cave-Ayland case CORE99_VIA_CONFIG_PMU:
603f1114c17SMark Cave-Ayland return g_strdup("pmu");
604f1114c17SMark Cave-Ayland
605f1114c17SMark Cave-Ayland case CORE99_VIA_CONFIG_PMU_ADB:
606f1114c17SMark Cave-Ayland return g_strdup("pmu-adb");
607f1114c17SMark Cave-Ayland }
608f1114c17SMark Cave-Ayland }
609f1114c17SMark Cave-Ayland
core99_set_via_config(Object * obj,const char * value,Error ** errp)610f1114c17SMark Cave-Ayland static void core99_set_via_config(Object *obj, const char *value, Error **errp)
611f1114c17SMark Cave-Ayland {
612f1114c17SMark Cave-Ayland Core99MachineState *cms = CORE99_MACHINE(obj);
613f1114c17SMark Cave-Ayland
614f1114c17SMark Cave-Ayland if (!strcmp(value, "cuda")) {
615f1114c17SMark Cave-Ayland cms->via_config = CORE99_VIA_CONFIG_CUDA;
616f1114c17SMark Cave-Ayland } else if (!strcmp(value, "pmu")) {
617f1114c17SMark Cave-Ayland cms->via_config = CORE99_VIA_CONFIG_PMU;
618f1114c17SMark Cave-Ayland } else if (!strcmp(value, "pmu-adb")) {
619f1114c17SMark Cave-Ayland cms->via_config = CORE99_VIA_CONFIG_PMU_ADB;
620f1114c17SMark Cave-Ayland } else {
621f1114c17SMark Cave-Ayland error_setg(errp, "Invalid via value");
622f1114c17SMark Cave-Ayland error_append_hint(errp, "Valid values are cuda, pmu, pmu-adb.\n");
623f1114c17SMark Cave-Ayland }
624f1114c17SMark Cave-Ayland }
625f1114c17SMark Cave-Ayland
core99_instance_init(Object * obj)62606fe3a5bSMark Cave-Ayland static void core99_instance_init(Object *obj)
62706fe3a5bSMark Cave-Ayland {
628f1114c17SMark Cave-Ayland Core99MachineState *cms = CORE99_MACHINE(obj);
629f1114c17SMark Cave-Ayland
630f1114c17SMark Cave-Ayland /* Default via_config is CORE99_VIA_CONFIG_CUDA */
631f1114c17SMark Cave-Ayland cms->via_config = CORE99_VIA_CONFIG_CUDA;
632f1114c17SMark Cave-Ayland object_property_add_str(obj, "via", core99_get_via_config,
633d2623129SMarkus Armbruster core99_set_via_config);
634f1114c17SMark Cave-Ayland object_property_set_description(obj, "via",
635f1114c17SMark Cave-Ayland "Set VIA configuration. "
6367eecec7dSMarkus Armbruster "Valid values are cuda, pmu and pmu-adb");
637f1114c17SMark Cave-Ayland
63806fe3a5bSMark Cave-Ayland return;
63906fe3a5bSMark Cave-Ayland }
64006fe3a5bSMark Cave-Ayland
641b1c2fb9bSMarcel Apfelbaum static const TypeInfo core99_machine_info = {
642c0f36518SEduardo Habkost .name = MACHINE_TYPE_NAME("mac99"),
643b1c2fb9bSMarcel Apfelbaum .parent = TYPE_MACHINE,
644b1c2fb9bSMarcel Apfelbaum .class_init = core99_machine_class_init,
64506fe3a5bSMark Cave-Ayland .instance_init = core99_instance_init,
6465d19be6cSMark Cave-Ayland .instance_size = sizeof(Core99MachineState),
6475d19be6cSMark Cave-Ayland .interfaces = (InterfaceInfo[]) {
6485d19be6cSMark Cave-Ayland { TYPE_FW_PATH_PROVIDER },
6495d19be6cSMark Cave-Ayland { }
6505d19be6cSMark Cave-Ayland },
651b1c2fb9bSMarcel Apfelbaum };
652b1c2fb9bSMarcel Apfelbaum
mac_machine_register_types(void)653b1c2fb9bSMarcel Apfelbaum static void mac_machine_register_types(void)
654b1c2fb9bSMarcel Apfelbaum {
655b1c2fb9bSMarcel Apfelbaum type_register_static(&core99_machine_info);
656b1c2fb9bSMarcel Apfelbaum }
657b1c2fb9bSMarcel Apfelbaum
658b1c2fb9bSMarcel Apfelbaum type_init(mac_machine_register_types)
659