Blue Swirl | ae0bfb7 | 2010-10-13 18:38:07 +0000 | [diff] [blame] | 1 | |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 2 | /* |
aurel32 | 4d7ca41 | 2009-01-07 23:38:59 +0000 | [diff] [blame] | 3 | * QEMU OldWorld PowerMac (currently ~G3 Beige) hardware System Emulator |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 4 | * |
| 5 | * Copyright (c) 2004-2007 Fabrice Bellard |
| 6 | * Copyright (c) 2007 Jocelyn Mayer |
| 7 | * |
| 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
| 9 | * of this software and associated documentation files (the "Software"), to deal |
| 10 | * in the Software without restriction, including without limitation the rights |
| 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 12 | * copies of the Software, and to permit persons to whom the Software is |
| 13 | * furnished to do so, subject to the following conditions: |
| 14 | * |
| 15 | * The above copyright notice and this permission notice shall be included in |
| 16 | * all copies or substantial portions of the Software. |
| 17 | * |
| 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 21 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 24 | * THE SOFTWARE. |
| 25 | */ |
Peter Maydell | 0d75590 | 2016-01-26 18:16:58 +0000 | [diff] [blame] | 26 | #include "qemu/osdep.h" |
Markus Armbruster | da34e65 | 2016-03-14 09:01:28 +0100 | [diff] [blame] | 27 | #include "qapi/error.h" |
Andreas Färber | baec191 | 2013-01-23 23:03:54 +0000 | [diff] [blame] | 28 | #include "hw/hw.h" |
Paolo Bonzini | 0d09e41 | 2013-02-05 17:06:20 +0100 | [diff] [blame] | 29 | #include "hw/ppc/ppc.h" |
Andreas Färber | baec191 | 2013-01-23 23:03:54 +0000 | [diff] [blame] | 30 | #include "mac.h" |
Paolo Bonzini | 0d09e41 | 2013-02-05 17:06:20 +0100 | [diff] [blame] | 31 | #include "hw/input/adb.h" |
| 32 | #include "hw/timer/m48t59.h" |
Paolo Bonzini | 9c17d61 | 2012-12-17 18:20:04 +0100 | [diff] [blame] | 33 | #include "sysemu/sysemu.h" |
Paolo Bonzini | 1422e32 | 2012-10-24 08:43:34 +0200 | [diff] [blame] | 34 | #include "net/net.h" |
Paolo Bonzini | 0d09e41 | 2013-02-05 17:06:20 +0100 | [diff] [blame] | 35 | #include "hw/isa/isa.h" |
Andreas Färber | baec191 | 2013-01-23 23:03:54 +0000 | [diff] [blame] | 36 | #include "hw/pci/pci.h" |
| 37 | #include "hw/boards.h" |
Paolo Bonzini | 0d09e41 | 2013-02-05 17:06:20 +0100 | [diff] [blame] | 38 | #include "hw/nvram/fw_cfg.h" |
| 39 | #include "hw/char/escc.h" |
Andreas Färber | baec191 | 2013-01-23 23:03:54 +0000 | [diff] [blame] | 40 | #include "hw/ide.h" |
| 41 | #include "hw/loader.h" |
Blue Swirl | ca20cf3 | 2009-09-20 14:58:02 +0000 | [diff] [blame] | 42 | #include "elf.h" |
Markus Armbruster | c525436 | 2015-12-17 17:35:09 +0100 | [diff] [blame] | 43 | #include "qemu/error-report.h" |
Paolo Bonzini | 9c17d61 | 2012-12-17 18:20:04 +0100 | [diff] [blame] | 44 | #include "sysemu/kvm.h" |
Alexander Graf | dc333cd | 2010-02-09 17:37:05 +0100 | [diff] [blame] | 45 | #include "kvm_ppc.h" |
Markus Armbruster | 4be7463 | 2014-10-07 13:59:18 +0200 | [diff] [blame] | 46 | #include "sysemu/block-backend.h" |
Paolo Bonzini | 022c62c | 2012-12-17 18:19:49 +0100 | [diff] [blame] | 47 | #include "exec/address-spaces.h" |
Veronia Bahaa | f348b6d | 2016-03-20 19:16:19 +0200 | [diff] [blame] | 48 | #include "qemu/cutils.h" |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 49 | |
ths | e4bcb14 | 2007-12-02 04:51:10 +0000 | [diff] [blame] | 50 | #define MAX_IDE_BUS 2 |
blueswir1 | 271dd5e | 2008-12-24 20:29:16 +0000 | [diff] [blame] | 51 | #define CFG_ADDR 0xf0000510 |
Alexander Graf | 536d8cd | 2013-06-29 17:34:58 +0200 | [diff] [blame] | 52 | #define TBFREQ 16600000UL |
BALATON Zoltan | 9d1c128 | 2014-04-17 19:04:44 +0200 | [diff] [blame] | 53 | #define CLOCKFREQ 266000000UL |
| 54 | #define BUSFREQ 66000000UL |
blueswir1 | 271dd5e | 2008-12-24 20:29:16 +0000 | [diff] [blame] | 55 | |
Mark Cave-Ayland | b50de5c | 2017-05-01 14:43:32 +0100 | [diff] [blame] | 56 | #define NDRV_VGA_FILENAME "qemu_vga.ndrv" |
| 57 | |
Gonglei | ddcd553 | 2014-12-03 19:04:02 +0000 | [diff] [blame] | 58 | static void fw_cfg_boot_set(void *opaque, const char *boot_device, |
| 59 | Error **errp) |
blueswir1 | 513f789 | 2009-03-08 09:51:29 +0000 | [diff] [blame] | 60 | { |
Gabriel L. Somlo | 48779e5 | 2015-06-08 14:10:45 -0400 | [diff] [blame] | 61 | fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); |
blueswir1 | 513f789 | 2009-03-08 09:51:29 +0000 | [diff] [blame] | 62 | } |
| 63 | |
Aurelien Jarno | 409dbce | 2010-03-14 21:20:59 +0100 | [diff] [blame] | 64 | static uint64_t translate_kernel_address(void *opaque, uint64_t addr) |
| 65 | { |
| 66 | return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR; |
| 67 | } |
| 68 | |
Avi Kivity | a8170e5 | 2012-10-23 12:30:10 +0200 | [diff] [blame] | 69 | static hwaddr round_page(hwaddr addr) |
Alexander Graf | b9e17a3 | 2011-06-15 23:27:19 +0200 | [diff] [blame] | 70 | { |
| 71 | return (addr + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK; |
| 72 | } |
| 73 | |
Andreas Färber | 1bba0dc | 2012-02-08 03:03:33 +0100 | [diff] [blame] | 74 | static void ppc_heathrow_reset(void *opaque) |
| 75 | { |
Andreas Färber | cd79664 | 2012-05-04 17:42:23 +0200 | [diff] [blame] | 76 | PowerPCCPU *cpu = opaque; |
Andreas Färber | 1bba0dc | 2012-02-08 03:03:33 +0100 | [diff] [blame] | 77 | |
Andreas Färber | cd79664 | 2012-05-04 17:42:23 +0200 | [diff] [blame] | 78 | cpu_reset(CPU(cpu)); |
Andreas Färber | 1bba0dc | 2012-02-08 03:03:33 +0100 | [diff] [blame] | 79 | } |
| 80 | |
Marcel Apfelbaum | 3ef9622 | 2014-05-07 17:42:57 +0300 | [diff] [blame] | 81 | static void ppc_heathrow_init(MachineState *machine) |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 82 | { |
Marcel Apfelbaum | 3ef9622 | 2014-05-07 17:42:57 +0300 | [diff] [blame] | 83 | ram_addr_t ram_size = machine->ram_size; |
Marcel Apfelbaum | 3ef9622 | 2014-05-07 17:42:57 +0300 | [diff] [blame] | 84 | const char *kernel_filename = machine->kernel_filename; |
| 85 | const char *kernel_cmdline = machine->kernel_cmdline; |
| 86 | const char *initrd_filename = machine->initrd_filename; |
| 87 | const char *boot_device = machine->boot_order; |
Avi Kivity | c92bb2c | 2011-09-25 16:27:52 +0300 | [diff] [blame] | 88 | MemoryRegion *sysmem = get_system_memory(); |
Andreas Färber | 72c33dd | 2012-05-04 17:38:41 +0200 | [diff] [blame] | 89 | PowerPCCPU *cpu = NULL; |
Andreas Färber | e2684c0 | 2012-03-14 01:38:23 +0100 | [diff] [blame] | 90 | CPUPPCState *env = NULL; |
Paul Brook | 5cea859 | 2009-05-30 00:52:44 +0100 | [diff] [blame] | 91 | char *filename; |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 92 | qemu_irq *pic, **heathrow_irqs; |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 93 | int linux_boot, i; |
Avi Kivity | c92bb2c | 2011-09-25 16:27:52 +0300 | [diff] [blame] | 94 | MemoryRegion *ram = g_new(MemoryRegion, 1); |
| 95 | MemoryRegion *bios = g_new(MemoryRegion, 1); |
Paolo Bonzini | 7d52857 | 2013-07-22 15:54:12 +0200 | [diff] [blame] | 96 | MemoryRegion *isa = g_new(MemoryRegion, 1); |
Alexander Graf | b9e17a3 | 2011-06-15 23:27:19 +0200 | [diff] [blame] | 97 | uint32_t kernel_base, initrd_base, cmdline_base = 0; |
blueswir1 | 7373048 | 2009-01-24 12:00:23 +0000 | [diff] [blame] | 98 | int32_t kernel_size, initrd_size; |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 99 | PCIBus *pci_bus; |
Andreas Färber | d037834 | 2013-01-23 23:03:57 +0000 | [diff] [blame] | 100 | PCIDevice *macio; |
Andreas Färber | 07a7484 | 2013-01-23 23:04:01 +0000 | [diff] [blame] | 101 | MACIOIDEState *macio_ide; |
| 102 | DeviceState *dev; |
Andreas Färber | 293c867 | 2013-01-23 23:04:05 +0000 | [diff] [blame] | 103 | BusState *adb_bus; |
Mark Cave-Ayland | b50de5c | 2017-05-01 14:43:32 +0100 | [diff] [blame] | 104 | int bios_size, ndrv_size; |
| 105 | uint8_t *ndrv_file; |
Andreas Färber | 45fa67f | 2013-01-23 23:04:02 +0000 | [diff] [blame] | 106 | MemoryRegion *pic_mem; |
Andreas Färber | 07a7484 | 2013-01-23 23:04:01 +0000 | [diff] [blame] | 107 | MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1); |
blueswir1 | 513f789 | 2009-03-08 09:51:29 +0000 | [diff] [blame] | 108 | uint16_t ppc_boot_device; |
Gerd Hoffmann | f455e98 | 2009-08-28 15:47:03 +0200 | [diff] [blame] | 109 | DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; |
blueswir1 | 271dd5e | 2008-12-24 20:29:16 +0000 | [diff] [blame] | 110 | void *fw_cfg; |
Alexander Graf | caae6c9 | 2014-07-13 22:29:02 +0200 | [diff] [blame] | 111 | uint64_t tbfreq; |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 112 | |
| 113 | linux_boot = (kernel_filename != NULL); |
| 114 | |
| 115 | /* init CPUs */ |
Bharata B Rao | 19fb2c3 | 2015-07-02 16:23:19 +1000 | [diff] [blame] | 116 | if (machine->cpu_model == NULL) |
| 117 | machine->cpu_model = "G3"; |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 118 | for (i = 0; i < smp_cpus; i++) { |
Bharata B Rao | 19fb2c3 | 2015-07-02 16:23:19 +1000 | [diff] [blame] | 119 | cpu = cpu_ppc_init(machine->cpu_model); |
Andreas Färber | 72c33dd | 2012-05-04 17:38:41 +0200 | [diff] [blame] | 120 | if (cpu == NULL) { |
bellard | aaed909 | 2007-11-10 15:15:54 +0000 | [diff] [blame] | 121 | fprintf(stderr, "Unable to find PowerPC CPU definition\n"); |
| 122 | exit(1); |
| 123 | } |
Andreas Färber | 72c33dd | 2012-05-04 17:38:41 +0200 | [diff] [blame] | 124 | env = &cpu->env; |
| 125 | |
aurel32 | b0fb43d | 2009-01-14 14:48:04 +0000 | [diff] [blame] | 126 | /* Set time-base frequency to 16.6 Mhz */ |
Alexander Graf | 536d8cd | 2013-06-29 17:34:58 +0200 | [diff] [blame] | 127 | cpu_ppc_tb_init(env, TBFREQ); |
Andreas Färber | cd79664 | 2012-05-04 17:42:23 +0200 | [diff] [blame] | 128 | qemu_register_reset(ppc_heathrow_reset, cpu); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 129 | } |
| 130 | |
| 131 | /* allocate RAM */ |
aurel32 | 6b4079f | 2009-01-13 19:08:10 +0000 | [diff] [blame] | 132 | if (ram_size > (2047 << 20)) { |
| 133 | fprintf(stderr, |
| 134 | "qemu: Too much memory for this machine: %d MB, maximum 2047 MB\n", |
| 135 | ((unsigned int)ram_size / (1 << 20))); |
| 136 | exit(1); |
| 137 | } |
| 138 | |
Shreyas B. Prabhu | e938ba0 | 2014-07-10 17:31:03 +0530 | [diff] [blame] | 139 | memory_region_allocate_system_memory(ram, NULL, "ppc_heathrow.ram", |
| 140 | ram_size); |
Avi Kivity | c92bb2c | 2011-09-25 16:27:52 +0300 | [diff] [blame] | 141 | memory_region_add_subregion(sysmem, 0, ram); |
aurel32 | a748ab6 | 2008-12-20 23:40:35 +0000 | [diff] [blame] | 142 | |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 143 | /* allocate and load BIOS */ |
Peter Maydell | 98a99ce | 2017-07-07 15:42:53 +0100 | [diff] [blame] | 144 | memory_region_init_ram(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE, |
Markus Armbruster | f8ed85a | 2015-09-11 16:51:43 +0200 | [diff] [blame] | 145 | &error_fatal); |
Hu Tao | e206ad4 | 2014-07-21 17:30:17 +0800 | [diff] [blame] | 146 | |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 147 | if (bios_name == NULL) |
blueswir1 | 992e5ac | 2008-12-24 20:23:51 +0000 | [diff] [blame] | 148 | bios_name = PROM_FILENAME; |
Paul Brook | 5cea859 | 2009-05-30 00:52:44 +0100 | [diff] [blame] | 149 | filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); |
Avi Kivity | c92bb2c | 2011-09-25 16:27:52 +0300 | [diff] [blame] | 150 | memory_region_set_readonly(bios, true); |
| 151 | memory_region_add_subregion(sysmem, PROM_ADDR, bios); |
blueswir1 | 992e5ac | 2008-12-24 20:23:51 +0000 | [diff] [blame] | 152 | |
| 153 | /* Load OpenBIOS (ELF) */ |
Paul Brook | 5cea859 | 2009-05-30 00:52:44 +0100 | [diff] [blame] | 154 | if (filename) { |
Aurelien Jarno | 409dbce | 2010-03-14 21:20:59 +0100 | [diff] [blame] | 155 | bios_size = load_elf(filename, 0, NULL, NULL, NULL, NULL, |
Peter Crosthwaite | 7ef295e | 2016-03-04 11:30:21 +0000 | [diff] [blame] | 156 | 1, PPC_ELF_MACHINE, 0, 0); |
Anthony Liguori | 7267c09 | 2011-08-20 22:09:37 -0500 | [diff] [blame] | 157 | g_free(filename); |
Paul Brook | 5cea859 | 2009-05-30 00:52:44 +0100 | [diff] [blame] | 158 | } else { |
| 159 | bios_size = -1; |
| 160 | } |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 161 | if (bios_size < 0 || bios_size > BIOS_SIZE) { |
Markus Armbruster | c525436 | 2015-12-17 17:35:09 +0100 | [diff] [blame] | 162 | error_report("could not load PowerPC bios '%s'", bios_name); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 163 | exit(1); |
| 164 | } |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 165 | |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 166 | if (linux_boot) { |
aurel32 | 36bee1e | 2009-01-26 10:22:15 +0000 | [diff] [blame] | 167 | uint64_t lowaddr = 0; |
Blue Swirl | ca20cf3 | 2009-09-20 14:58:02 +0000 | [diff] [blame] | 168 | int bswap_needed; |
| 169 | |
| 170 | #ifdef BSWAP_NEEDED |
| 171 | bswap_needed = 1; |
| 172 | #else |
| 173 | bswap_needed = 0; |
| 174 | #endif |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 175 | kernel_base = KERNEL_LOAD_ADDR; |
Aurelien Jarno | 409dbce | 2010-03-14 21:20:59 +0100 | [diff] [blame] | 176 | kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, |
Peter Crosthwaite | 7ef295e | 2016-03-04 11:30:21 +0000 | [diff] [blame] | 177 | NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, |
| 178 | 0, 0); |
blueswir1 | 52f163b | 2008-12-24 20:30:01 +0000 | [diff] [blame] | 179 | if (kernel_size < 0) |
| 180 | kernel_size = load_aout(kernel_filename, kernel_base, |
Blue Swirl | ca20cf3 | 2009-09-20 14:58:02 +0000 | [diff] [blame] | 181 | ram_size - kernel_base, bswap_needed, |
| 182 | TARGET_PAGE_SIZE); |
blueswir1 | 52f163b | 2008-12-24 20:30:01 +0000 | [diff] [blame] | 183 | if (kernel_size < 0) |
| 184 | kernel_size = load_image_targphys(kernel_filename, |
| 185 | kernel_base, |
| 186 | ram_size - kernel_base); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 187 | if (kernel_size < 0) { |
Markus Armbruster | c525436 | 2015-12-17 17:35:09 +0100 | [diff] [blame] | 188 | error_report("could not load kernel '%s'", kernel_filename); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 189 | exit(1); |
| 190 | } |
| 191 | /* load initrd */ |
| 192 | if (initrd_filename) { |
Alexander Graf | b9e17a3 | 2011-06-15 23:27:19 +0200 | [diff] [blame] | 193 | initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP); |
pbrook | dcac967 | 2009-04-09 20:05:49 +0000 | [diff] [blame] | 194 | initrd_size = load_image_targphys(initrd_filename, initrd_base, |
| 195 | ram_size - initrd_base); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 196 | if (initrd_size < 0) { |
Markus Armbruster | c525436 | 2015-12-17 17:35:09 +0100 | [diff] [blame] | 197 | error_report("could not load initial ram disk '%s'", |
| 198 | initrd_filename); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 199 | exit(1); |
| 200 | } |
Alexander Graf | b9e17a3 | 2011-06-15 23:27:19 +0200 | [diff] [blame] | 201 | cmdline_base = round_page(initrd_base + initrd_size); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 202 | } else { |
| 203 | initrd_base = 0; |
| 204 | initrd_size = 0; |
Alexander Graf | b9e17a3 | 2011-06-15 23:27:19 +0200 | [diff] [blame] | 205 | cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 206 | } |
balrog | 6ac0e82 | 2007-10-31 01:54:04 +0000 | [diff] [blame] | 207 | ppc_boot_device = 'm'; |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 208 | } else { |
| 209 | kernel_base = 0; |
| 210 | kernel_size = 0; |
| 211 | initrd_base = 0; |
| 212 | initrd_size = 0; |
j_mayer | 28c5af5 | 2007-11-11 01:50:45 +0000 | [diff] [blame] | 213 | ppc_boot_device = '\0'; |
j_mayer | 0d913fd | 2007-11-11 14:44:28 +0000 | [diff] [blame] | 214 | for (i = 0; boot_device[i] != '\0'; i++) { |
j_mayer | 28c5af5 | 2007-11-11 01:50:45 +0000 | [diff] [blame] | 215 | /* TOFIX: for now, the second IDE channel is not properly |
j_mayer | 0d913fd | 2007-11-11 14:44:28 +0000 | [diff] [blame] | 216 | * used by OHW. The Mac floppy disk are not emulated. |
j_mayer | 28c5af5 | 2007-11-11 01:50:45 +0000 | [diff] [blame] | 217 | * For now, OHW cannot boot from the network. |
| 218 | */ |
| 219 | #if 0 |
j_mayer | 0d913fd | 2007-11-11 14:44:28 +0000 | [diff] [blame] | 220 | if (boot_device[i] >= 'a' && boot_device[i] <= 'f') { |
| 221 | ppc_boot_device = boot_device[i]; |
j_mayer | 28c5af5 | 2007-11-11 01:50:45 +0000 | [diff] [blame] | 222 | break; |
j_mayer | 0d913fd | 2007-11-11 14:44:28 +0000 | [diff] [blame] | 223 | } |
j_mayer | 28c5af5 | 2007-11-11 01:50:45 +0000 | [diff] [blame] | 224 | #else |
j_mayer | 0d913fd | 2007-11-11 14:44:28 +0000 | [diff] [blame] | 225 | if (boot_device[i] >= 'c' && boot_device[i] <= 'd') { |
| 226 | ppc_boot_device = boot_device[i]; |
j_mayer | 28c5af5 | 2007-11-11 01:50:45 +0000 | [diff] [blame] | 227 | break; |
j_mayer | 0d913fd | 2007-11-11 14:44:28 +0000 | [diff] [blame] | 228 | } |
j_mayer | 28c5af5 | 2007-11-11 01:50:45 +0000 | [diff] [blame] | 229 | #endif |
| 230 | } |
| 231 | if (ppc_boot_device == '\0') { |
aurel32 | 8a901de | 2009-01-13 19:07:59 +0000 | [diff] [blame] | 232 | fprintf(stderr, "No valid boot device for G3 Beige machine\n"); |
j_mayer | 28c5af5 | 2007-11-11 01:50:45 +0000 | [diff] [blame] | 233 | exit(1); |
| 234 | } |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 235 | } |
| 236 | |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 237 | /* Register 2 MB of ISA IO space */ |
Paolo Bonzini | 7d52857 | 2013-07-22 15:54:12 +0200 | [diff] [blame] | 238 | memory_region_init_alias(isa, NULL, "isa_mmio", |
| 239 | get_system_io(), 0, 0x00200000); |
| 240 | memory_region_add_subregion(sysmem, 0xfe000000, isa); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 241 | |
| 242 | /* XXX: we register only 1 output pin for heathrow PIC */ |
Anthony Liguori | 7267c09 | 2011-08-20 22:09:37 -0500 | [diff] [blame] | 243 | heathrow_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 244 | heathrow_irqs[0] = |
Anthony Liguori | 7267c09 | 2011-08-20 22:09:37 -0500 | [diff] [blame] | 245 | g_malloc0(smp_cpus * sizeof(qemu_irq) * 1); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 246 | /* Connect the heathrow PIC outputs to the 6xx bus */ |
| 247 | for (i = 0; i < smp_cpus; i++) { |
| 248 | switch (PPC_INPUT(env)) { |
| 249 | case PPC_FLAGS_INPUT_6xx: |
| 250 | heathrow_irqs[i] = heathrow_irqs[0] + (i * 1); |
| 251 | heathrow_irqs[i][0] = |
| 252 | ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; |
| 253 | break; |
| 254 | default: |
Markus Armbruster | c525436 | 2015-12-17 17:35:09 +0100 | [diff] [blame] | 255 | error_report("Bus model not supported on OldWorld Mac machine"); |
| 256 | exit(1); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 257 | } |
| 258 | } |
| 259 | |
Alexander Graf | caae6c9 | 2014-07-13 22:29:02 +0200 | [diff] [blame] | 260 | /* Timebase Frequency */ |
| 261 | if (kvm_enabled()) { |
| 262 | tbfreq = kvmppc_get_tbfreq(); |
| 263 | } else { |
| 264 | tbfreq = TBFREQ; |
| 265 | } |
| 266 | |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 267 | /* init basic PC hardware */ |
| 268 | if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { |
Markus Armbruster | c525436 | 2015-12-17 17:35:09 +0100 | [diff] [blame] | 269 | error_report("Only 6xx bus is supported on heathrow machine"); |
| 270 | exit(1); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 271 | } |
Avi Kivity | 23c5e4c | 2011-08-08 16:09:17 +0300 | [diff] [blame] | 272 | pic = heathrow_pic_init(&pic_mem, 1, heathrow_irqs); |
Avi Kivity | aee97b8 | 2011-08-08 16:09:04 +0300 | [diff] [blame] | 273 | pci_bus = pci_grackle_init(0xfec00000, pic, |
| 274 | get_system_memory(), |
| 275 | get_system_io()); |
Aurelien Jarno | 3e20ad3 | 2012-09-08 12:21:20 +0200 | [diff] [blame] | 276 | pci_vga_init(pci_bus); |
j_mayer | aae9366 | 2007-11-24 02:56:36 +0000 | [diff] [blame] | 277 | |
Alexander Graf | b39491a | 2011-09-30 15:29:12 +0200 | [diff] [blame] | 278 | escc_mem = escc_init(0, pic[0x0f], pic[0x10], serial_hds[0], |
blueswir1 | 7fa9ae1 | 2009-01-12 17:40:23 +0000 | [diff] [blame] | 279 | serial_hds[1], ESCC_CLOCK, 4); |
Paolo Bonzini | 2c9b15c | 2013-06-06 05:41:28 -0400 | [diff] [blame] | 280 | memory_region_init_alias(escc_bar, NULL, "escc-bar", |
Avi Kivity | 5b15f27 | 2011-08-24 21:37:05 +0300 | [diff] [blame] | 281 | escc_mem, 0, memory_region_size(escc_mem)); |
j_mayer | aae9366 | 2007-11-24 02:56:36 +0000 | [diff] [blame] | 282 | |
aliguori | cb457d7 | 2009-01-13 19:47:10 +0000 | [diff] [blame] | 283 | for(i = 0; i < nb_nics; i++) |
David Gibson | 29b358f | 2013-06-06 18:48:51 +1000 | [diff] [blame] | 284 | pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL); |
j_mayer | 0d913fd | 2007-11-11 14:44:28 +0000 | [diff] [blame] | 285 | |
ths | e4bcb14 | 2007-12-02 04:51:10 +0000 | [diff] [blame] | 286 | |
John Snow | d8f94e1 | 2014-10-01 14:19:27 -0400 | [diff] [blame] | 287 | ide_drive_get(hd, ARRAY_SIZE(hd)); |
aurel32 | bd4524e | 2009-03-07 21:35:21 +0000 | [diff] [blame] | 288 | |
Andreas Färber | d037834 | 2013-01-23 23:03:57 +0000 | [diff] [blame] | 289 | macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO); |
Andreas Färber | 07a7484 | 2013-01-23 23:04:01 +0000 | [diff] [blame] | 290 | dev = DEVICE(macio); |
Andreas Färber | 45fa67f | 2013-01-23 23:04:02 +0000 | [diff] [blame] | 291 | qdev_connect_gpio_out(dev, 0, pic[0x12]); /* CUDA */ |
Alexander Graf | 14eefd0 | 2013-06-24 21:40:50 +0200 | [diff] [blame] | 292 | qdev_connect_gpio_out(dev, 1, pic[0x0D]); /* IDE-0 */ |
| 293 | qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE-0 DMA */ |
| 294 | qdev_connect_gpio_out(dev, 3, pic[0x0E]); /* IDE-1 */ |
| 295 | qdev_connect_gpio_out(dev, 4, pic[0x03]); /* IDE-1 DMA */ |
Alexander Graf | b981289 | 2014-07-13 22:31:53 +0200 | [diff] [blame] | 296 | qdev_prop_set_uint64(dev, "frequency", tbfreq); |
Andreas Färber | 45fa67f | 2013-01-23 23:04:02 +0000 | [diff] [blame] | 297 | macio_init(macio, pic_mem, escc_bar); |
Andreas Färber | 07a7484 | 2013-01-23 23:04:01 +0000 | [diff] [blame] | 298 | |
Andreas Färber | 07a7484 | 2013-01-23 23:04:01 +0000 | [diff] [blame] | 299 | macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), |
Alexander Graf | 14eefd0 | 2013-06-24 21:40:50 +0200 | [diff] [blame] | 300 | "ide[0]")); |
Andreas Färber | 07a7484 | 2013-01-23 23:04:01 +0000 | [diff] [blame] | 301 | macio_ide_init_drives(macio_ide, hd); |
| 302 | |
Alexander Graf | 14eefd0 | 2013-06-24 21:40:50 +0200 | [diff] [blame] | 303 | macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), |
| 304 | "ide[1]")); |
| 305 | macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 306 | |
Andreas Färber | 293c867 | 2013-01-23 23:04:05 +0000 | [diff] [blame] | 307 | dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda")); |
| 308 | adb_bus = qdev_get_child_bus(dev, "adb.0"); |
| 309 | dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD); |
Andreas Färber | 2e4a7c9 | 2013-01-23 23:04:04 +0000 | [diff] [blame] | 310 | qdev_init_nofail(dev); |
Andreas Färber | 293c867 | 2013-01-23 23:04:05 +0000 | [diff] [blame] | 311 | dev = qdev_create(adb_bus, TYPE_ADB_MOUSE); |
Andreas Färber | 2e4a7c9 | 2013-01-23 23:04:04 +0000 | [diff] [blame] | 312 | qdev_init_nofail(dev); |
Andreas Färber | 45fa67f | 2013-01-23 23:04:02 +0000 | [diff] [blame] | 313 | |
Eduardo Habkost | 4bcbe0b | 2016-06-08 17:50:25 -0300 | [diff] [blame] | 314 | if (machine_usb(machine)) { |
Gerd Hoffmann | afb9a60 | 2012-03-07 15:06:32 +0100 | [diff] [blame] | 315 | pci_create_simple(pci_bus, -1, "pci-ohci"); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 316 | } |
| 317 | |
| 318 | if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) |
| 319 | graphic_depth = 15; |
| 320 | |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 321 | /* No PCI init: the BIOS will do it */ |
| 322 | |
Laszlo Ersek | 6670882 | 2014-12-22 13:11:36 +0100 | [diff] [blame] | 323 | fw_cfg = fw_cfg_init_mem(CFG_ADDR, CFG_ADDR + 2); |
Igor Mammedov | 5836d16 | 2016-11-15 13:17:15 +0100 | [diff] [blame] | 324 | fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); |
Eduardo Habkost | 70db922 | 2013-01-22 18:25:03 -0200 | [diff] [blame] | 325 | fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); |
blueswir1 | 271dd5e | 2008-12-24 20:29:16 +0000 | [diff] [blame] | 326 | fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); |
| 327 | fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW); |
blueswir1 | 513f789 | 2009-03-08 09:51:29 +0000 | [diff] [blame] | 328 | fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); |
| 329 | fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); |
| 330 | if (kernel_cmdline) { |
Alexander Graf | b9e17a3 | 2011-06-15 23:27:19 +0200 | [diff] [blame] | 331 | fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base); |
| 332 | pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); |
blueswir1 | 513f789 | 2009-03-08 09:51:29 +0000 | [diff] [blame] | 333 | } else { |
| 334 | fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); |
| 335 | } |
| 336 | fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base); |
| 337 | fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); |
| 338 | fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device); |
Laurent Vivier | 7f1aec5 | 2009-08-08 10:19:24 +0000 | [diff] [blame] | 339 | |
| 340 | fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width); |
| 341 | fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height); |
| 342 | fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth); |
| 343 | |
Alexander Graf | 45024f0 | 2010-08-03 15:22:42 +0200 | [diff] [blame] | 344 | fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled()); |
Alexander Graf | dc333cd | 2010-02-09 17:37:05 +0100 | [diff] [blame] | 345 | if (kvm_enabled()) { |
| 346 | #ifdef CONFIG_KVM |
Alexander Graf | 45024f0 | 2010-08-03 15:22:42 +0200 | [diff] [blame] | 347 | uint8_t *hypercall; |
| 348 | |
Anthony Liguori | 7267c09 | 2011-08-20 22:09:37 -0500 | [diff] [blame] | 349 | hypercall = g_malloc(16); |
Alexander Graf | 45024f0 | 2010-08-03 15:22:42 +0200 | [diff] [blame] | 350 | kvmppc_get_hypercall(env, hypercall, 16); |
| 351 | fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16); |
| 352 | fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); |
Alexander Graf | dc333cd | 2010-02-09 17:37:05 +0100 | [diff] [blame] | 353 | #endif |
Alexander Graf | dc333cd | 2010-02-09 17:37:05 +0100 | [diff] [blame] | 354 | } |
Alexander Graf | caae6c9 | 2014-07-13 22:29:02 +0200 | [diff] [blame] | 355 | fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, tbfreq); |
Alexander Graf | a1014f2 | 2013-06-23 00:22:50 +0200 | [diff] [blame] | 356 | /* Mac OS X requires a "known good" clock-frequency value; pass it one. */ |
BALATON Zoltan | 9d1c128 | 2014-04-17 19:04:44 +0200 | [diff] [blame] | 357 | fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, CLOCKFREQ); |
| 358 | fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_BUSFREQ, BUSFREQ); |
Alexander Graf | dc333cd | 2010-02-09 17:37:05 +0100 | [diff] [blame] | 359 | |
Mark Cave-Ayland | b50de5c | 2017-05-01 14:43:32 +0100 | [diff] [blame] | 360 | /* MacOS NDRV VGA driver */ |
| 361 | filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, NDRV_VGA_FILENAME); |
| 362 | if (filename) { |
| 363 | ndrv_size = get_image_size(filename); |
| 364 | if (ndrv_size != -1) { |
| 365 | ndrv_file = g_malloc(ndrv_size); |
| 366 | ndrv_size = load_image(filename, ndrv_file); |
| 367 | |
| 368 | fw_cfg_add_file(fw_cfg, "ndrv/qemu_vga.ndrv", ndrv_file, ndrv_size); |
| 369 | } |
| 370 | g_free(filename); |
| 371 | } |
| 372 | |
blueswir1 | 513f789 | 2009-03-08 09:51:29 +0000 | [diff] [blame] | 373 | qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); |
j_mayer | 3cbee15 | 2007-10-28 23:42:18 +0000 | [diff] [blame] | 374 | } |
| 375 | |
Alexander Graf | 277c7a4 | 2014-07-24 10:46:47 +0200 | [diff] [blame] | 376 | static int heathrow_kvm_type(const char *arg) |
| 377 | { |
| 378 | /* Always force PR KVM */ |
| 379 | return 2; |
| 380 | } |
| 381 | |
Eduardo Habkost | e264d29 | 2015-09-04 15:37:08 -0300 | [diff] [blame] | 382 | static void heathrow_machine_init(MachineClass *mc) |
| 383 | { |
| 384 | mc->desc = "Heathrow based PowerMAC"; |
| 385 | mc->init = ppc_heathrow_init; |
Markus Armbruster | 2059839 | 2017-02-15 11:05:40 +0100 | [diff] [blame] | 386 | mc->block_default_type = IF_IDE; |
Eduardo Habkost | e264d29 | 2015-09-04 15:37:08 -0300 | [diff] [blame] | 387 | mc->max_cpus = MAX_CPUS; |
Andreas Färber | 46214a2 | 2009-12-20 00:22:26 +0100 | [diff] [blame] | 388 | #ifndef TARGET_PPC64 |
Eduardo Habkost | e264d29 | 2015-09-04 15:37:08 -0300 | [diff] [blame] | 389 | mc->is_default = 1; |
Andreas Färber | 46214a2 | 2009-12-20 00:22:26 +0100 | [diff] [blame] | 390 | #endif |
Eduardo Habkost | f309ae8 | 2015-09-04 15:37:07 -0300 | [diff] [blame] | 391 | /* TOFIX "cad" when Mac floppy is implemented */ |
Eduardo Habkost | e264d29 | 2015-09-04 15:37:08 -0300 | [diff] [blame] | 392 | mc->default_boot_order = "cd"; |
| 393 | mc->kvm_type = heathrow_kvm_type; |
Anthony Liguori | f80f9ec | 2009-05-20 18:38:09 -0500 | [diff] [blame] | 394 | } |
| 395 | |
Eduardo Habkost | e264d29 | 2015-09-04 15:37:08 -0300 | [diff] [blame] | 396 | DEFINE_MACHINE("g3beige", heathrow_machine_init) |