Commit 0aa6a4a2500627d8824a536d4ea45176de273761
1 parent
938828a2
added Heathrow PowerMAC machine - added UniN memory fake controller for Mac99 - …
…added temporary frame buffer OSI calls to keep Mac OS X happy git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1448 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
246 additions
and
51 deletions
hw/ppc_chrp.c
| ... | ... | @@ -34,9 +34,10 @@ |
| 34 | 34 | |
| 35 | 35 | static int dbdma_mem_index; |
| 36 | 36 | static int cuda_mem_index; |
| 37 | -static int ide0_mem_index; | |
| 38 | -static int ide1_mem_index; | |
| 39 | -static int openpic_mem_index; | |
| 37 | +static int ide0_mem_index = -1; | |
| 38 | +static int ide1_mem_index = -1; | |
| 39 | +static int openpic_mem_index = -1; | |
| 40 | +static int heathrow_pic_mem_index = -1; | |
| 40 | 41 | |
| 41 | 42 | /* DBDMA: currently no op - should suffice right now */ |
| 42 | 43 | |
| ... | ... | @@ -84,11 +85,20 @@ static CPUReadMemoryFunc *dbdma_read[] = { |
| 84 | 85 | static void macio_map(PCIDevice *pci_dev, int region_num, |
| 85 | 86 | uint32_t addr, uint32_t size, int type) |
| 86 | 87 | { |
| 88 | + if (heathrow_pic_mem_index >= 0) { | |
| 89 | + cpu_register_physical_memory(addr + 0x00000, 0x1000, | |
| 90 | + heathrow_pic_mem_index); | |
| 91 | + } | |
| 87 | 92 | cpu_register_physical_memory(addr + 0x08000, 0x1000, dbdma_mem_index); |
| 88 | 93 | cpu_register_physical_memory(addr + 0x16000, 0x2000, cuda_mem_index); |
| 89 | - cpu_register_physical_memory(addr + 0x1f000, 0x1000, ide0_mem_index); | |
| 90 | - cpu_register_physical_memory(addr + 0x20000, 0x1000, ide1_mem_index); | |
| 91 | - cpu_register_physical_memory(addr + 0x40000, 0x40000, openpic_mem_index); | |
| 94 | + if (ide0_mem_index >= 0) | |
| 95 | + cpu_register_physical_memory(addr + 0x1f000, 0x1000, ide0_mem_index); | |
| 96 | + if (ide1_mem_index >= 0) | |
| 97 | + cpu_register_physical_memory(addr + 0x20000, 0x1000, ide1_mem_index); | |
| 98 | + if (openpic_mem_index >= 0) { | |
| 99 | + cpu_register_physical_memory(addr + 0x40000, 0x40000, | |
| 100 | + openpic_mem_index); | |
| 101 | + } | |
| 92 | 102 | } |
| 93 | 103 | |
| 94 | 104 | static void macio_init(PCIBus *bus) |
| ... | ... | @@ -116,20 +126,112 @@ static void macio_init(PCIBus *bus) |
| 116 | 126 | PCI_ADDRESS_SPACE_MEM, macio_map); |
| 117 | 127 | } |
| 118 | 128 | |
| 119 | -/* PowerPC PREP hardware initialisation */ | |
| 120 | -void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, | |
| 121 | - DisplayState *ds, const char **fd_filename, int snapshot, | |
| 122 | - const char *kernel_filename, const char *kernel_cmdline, | |
| 123 | - const char *initrd_filename) | |
| 129 | +/* UniN device */ | |
| 130 | +static void unin_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | |
| 131 | +{ | |
| 132 | +} | |
| 133 | + | |
| 134 | +static uint32_t unin_readl (void *opaque, target_phys_addr_t addr) | |
| 135 | +{ | |
| 136 | + return 0; | |
| 137 | +} | |
| 138 | + | |
| 139 | +static CPUWriteMemoryFunc *unin_write[] = { | |
| 140 | + &unin_writel, | |
| 141 | + &unin_writel, | |
| 142 | + &unin_writel, | |
| 143 | +}; | |
| 144 | + | |
| 145 | +static CPUReadMemoryFunc *unin_read[] = { | |
| 146 | + &unin_readl, | |
| 147 | + &unin_readl, | |
| 148 | + &unin_readl, | |
| 149 | +}; | |
| 150 | + | |
| 151 | +/* temporary frame buffer OSI calls for the video.x driver. The right | |
| 152 | + solution is to modify the driver to use VGA PCI I/Os */ | |
| 153 | +static int vga_osi_call(CPUState *env) | |
| 154 | +{ | |
| 155 | + static int vga_vbl_enabled; | |
| 156 | + int linesize; | |
| 157 | + | |
| 158 | + // printf("osi_call R5=%d\n", env->gpr[5]); | |
| 159 | + | |
| 160 | + /* same handler as PearPC, coming from the original MOL video | |
| 161 | + driver. */ | |
| 162 | + switch(env->gpr[5]) { | |
| 163 | + case 4: | |
| 164 | + break; | |
| 165 | + case 28: /* set_vmode */ | |
| 166 | + if (env->gpr[6] != 1 || env->gpr[7] != 0) | |
| 167 | + env->gpr[3] = 1; | |
| 168 | + else | |
| 169 | + env->gpr[3] = 0; | |
| 170 | + break; | |
| 171 | + case 29: /* get_vmode_info */ | |
| 172 | + if (env->gpr[6] != 0) { | |
| 173 | + if (env->gpr[6] != 1 || env->gpr[7] != 0) { | |
| 174 | + env->gpr[3] = 1; | |
| 175 | + break; | |
| 176 | + } | |
| 177 | + } | |
| 178 | + env->gpr[3] = 0; | |
| 179 | + env->gpr[4] = (1 << 16) | 1; /* num_vmodes, cur_vmode */ | |
| 180 | + env->gpr[5] = (1 << 16) | 0; /* num_depths, cur_depth_mode */ | |
| 181 | + env->gpr[6] = (graphic_width << 16) | graphic_height; /* w, h */ | |
| 182 | + env->gpr[7] = 85 << 16; /* refresh rate */ | |
| 183 | + env->gpr[8] = (graphic_depth + 7) & ~7; /* depth (round to byte) */ | |
| 184 | + linesize = ((graphic_depth + 7) >> 3) * graphic_width; | |
| 185 | + linesize = (linesize + 3) & ~3; | |
| 186 | + env->gpr[9] = (linesize << 16) | 0; /* row_bytes, offset */ | |
| 187 | + break; | |
| 188 | + case 31: /* set_video power */ | |
| 189 | + env->gpr[3] = 0; | |
| 190 | + break; | |
| 191 | + case 39: /* video_ctrl */ | |
| 192 | + if (env->gpr[6] == 0 || env->gpr[6] == 1) | |
| 193 | + vga_vbl_enabled = env->gpr[6]; | |
| 194 | + env->gpr[3] = 0; | |
| 195 | + break; | |
| 196 | + case 47: | |
| 197 | + break; | |
| 198 | + case 59: /* set_color */ | |
| 199 | + /* R6 = index, R7 = RGB */ | |
| 200 | + env->gpr[3] = 0; | |
| 201 | + break; | |
| 202 | + case 64: /* get color */ | |
| 203 | + /* R6 = index */ | |
| 204 | + env->gpr[3] = 0; | |
| 205 | + break; | |
| 206 | + case 116: /* set hwcursor */ | |
| 207 | + /* R6 = x, R7 = y, R8 = visible, R9 = data */ | |
| 208 | + break; | |
| 209 | + default: | |
| 210 | + fprintf(stderr, "unsupported OSI call R5=%08x\n", env->gpr[5]); | |
| 211 | + break; | |
| 212 | + } | |
| 213 | + return 1; /* osi_call handled */ | |
| 214 | +} | |
| 215 | + | |
| 216 | +/* PowerPC CHRP hardware initialisation */ | |
| 217 | +static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, | |
| 218 | + DisplayState *ds, const char **fd_filename, | |
| 219 | + int snapshot, | |
| 220 | + const char *kernel_filename, | |
| 221 | + const char *kernel_cmdline, | |
| 222 | + const char *initrd_filename, | |
| 223 | + int is_heathrow) | |
| 124 | 224 | { |
| 125 | 225 | char buf[1024]; |
| 126 | - openpic_t *openpic; | |
| 226 | + SetIRQFunc *set_irq; | |
| 227 | + void *pic; | |
| 127 | 228 | m48t59_t *nvram; |
| 128 | - int PPC_io_memory; | |
| 229 | + int PPC_io_memory, unin_memory; | |
| 129 | 230 | int ret, linux_boot, i; |
| 130 | 231 | unsigned long bios_offset; |
| 131 | 232 | uint32_t kernel_base, kernel_size, initrd_base, initrd_size; |
| 132 | 233 | PCIBus *pci_bus; |
| 234 | + const char *arch_name; | |
| 133 | 235 | |
| 134 | 236 | linux_boot = (kernel_filename != NULL); |
| 135 | 237 | |
| ... | ... | @@ -180,49 +282,101 @@ void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, |
| 180 | 282 | } |
| 181 | 283 | /* Register CPU as a 74x/75x */ |
| 182 | 284 | cpu_ppc_register(cpu_single_env, 0x00080000); |
| 183 | - /* Set time-base frequency to 100 Mhz */ | |
| 184 | - cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL); | |
| 185 | - | |
| 186 | - isa_mem_base = 0x80000000; | |
| 187 | - pci_bus = pci_pmac_init(); | |
| 188 | - | |
| 189 | - /* Register 8 MB of ISA IO space */ | |
| 190 | - PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL); | |
| 191 | - cpu_register_physical_memory(0xF2000000, 0x00800000, PPC_io_memory); | |
| 192 | - | |
| 193 | - /* init basic PC hardware */ | |
| 194 | - vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, | |
| 195 | - vga_ram_size); | |
| 196 | - openpic = openpic_init(NULL, &openpic_mem_index, 1); | |
| 197 | - pci_pmac_set_openpic(pci_bus, openpic); | |
| 198 | - | |
| 199 | - /* XXX: suppress that */ | |
| 200 | - pic_init(); | |
| 201 | - | |
| 202 | - /* XXX: use Mac Serial port */ | |
| 203 | - serial_init(0x3f8, 4, serial_hds[0]); | |
| 204 | - | |
| 205 | - for(i = 0; i < nb_nics; i++) { | |
| 206 | - pci_ne2000_init(pci_bus, &nd_table[i]); | |
| 285 | + /* Set time-base frequency to 10 Mhz */ | |
| 286 | + cpu_ppc_tb_init(cpu_single_env, 10UL * 1000UL * 1000UL); | |
| 287 | + | |
| 288 | + cpu_single_env->osi_call = vga_osi_call; | |
| 289 | + | |
| 290 | + if (is_heathrow) { | |
| 291 | + isa_mem_base = 0x80000000; | |
| 292 | + pci_bus = pci_grackle_init(0xfec00000); | |
| 293 | + | |
| 294 | + /* Register 2 MB of ISA IO space */ | |
| 295 | + PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL); | |
| 296 | + cpu_register_physical_memory(0xfe000000, 0x00200000, PPC_io_memory); | |
| 297 | + | |
| 298 | + /* init basic PC hardware */ | |
| 299 | + vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, | |
| 300 | + vga_ram_size); | |
| 301 | + pic = heathrow_pic_init(&heathrow_pic_mem_index); | |
| 302 | + set_irq = heathrow_pic_set_irq; | |
| 303 | + pci_set_pic(pci_bus, set_irq, pic); | |
| 304 | + | |
| 305 | + /* XXX: suppress that */ | |
| 306 | + pic_init(); | |
| 307 | + | |
| 308 | + /* XXX: use Mac Serial port */ | |
| 309 | + serial_init(0x3f8, 4, serial_hds[0]); | |
| 310 | + | |
| 311 | + for(i = 0; i < nb_nics; i++) { | |
| 312 | + pci_ne2000_init(pci_bus, &nd_table[i]); | |
| 313 | + } | |
| 314 | + | |
| 315 | + pci_cmd646_ide_init(pci_bus, &bs_table[0], 0); | |
| 316 | + | |
| 317 | + /* cuda also initialize ADB */ | |
| 318 | + cuda_mem_index = cuda_init(set_irq, pic, 0x12); | |
| 319 | + | |
| 320 | + adb_kbd_init(&adb_bus); | |
| 321 | + adb_mouse_init(&adb_bus); | |
| 322 | + | |
| 323 | + macio_init(pci_bus); | |
| 324 | + | |
| 325 | + nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE); | |
| 326 | + | |
| 327 | + arch_name = "HEATHROW"; | |
| 328 | + } else { | |
| 329 | + isa_mem_base = 0x80000000; | |
| 330 | + pci_bus = pci_pmac_init(); | |
| 331 | + | |
| 332 | + /* Register 8 MB of ISA IO space */ | |
| 333 | + PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL); | |
| 334 | + cpu_register_physical_memory(0xF2000000, 0x00800000, PPC_io_memory); | |
| 335 | + | |
| 336 | + /* UniN init */ | |
| 337 | + unin_memory = cpu_register_io_memory(0, unin_read, unin_write, NULL); | |
| 338 | + cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory); | |
| 339 | + | |
| 340 | + /* init basic PC hardware */ | |
| 341 | + vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, | |
| 342 | + vga_ram_size); | |
| 343 | + pic = openpic_init(NULL, &openpic_mem_index, 1); | |
| 344 | + set_irq = openpic_set_irq; | |
| 345 | + pci_set_pic(pci_bus, set_irq, pic); | |
| 346 | + | |
| 347 | + /* XXX: suppress that */ | |
| 348 | + pic_init(); | |
| 349 | + | |
| 350 | + /* XXX: use Mac Serial port */ | |
| 351 | + serial_init(0x3f8, 4, serial_hds[0]); | |
| 352 | + | |
| 353 | + for(i = 0; i < nb_nics; i++) { | |
| 354 | + pci_ne2000_init(pci_bus, &nd_table[i]); | |
| 355 | + } | |
| 356 | + | |
| 357 | +#if 1 | |
| 358 | + ide0_mem_index = pmac_ide_init(&bs_table[0], set_irq, pic, 0x13); | |
| 359 | + ide1_mem_index = pmac_ide_init(&bs_table[2], set_irq, pic, 0x14); | |
| 360 | +#else | |
| 361 | + pci_cmd646_ide_init(pci_bus, &bs_table[0], 0); | |
| 362 | +#endif | |
| 363 | + /* cuda also initialize ADB */ | |
| 364 | + cuda_mem_index = cuda_init(set_irq, pic, 0x19); | |
| 365 | + | |
| 366 | + adb_kbd_init(&adb_bus); | |
| 367 | + adb_mouse_init(&adb_bus); | |
| 368 | + | |
| 369 | + macio_init(pci_bus); | |
| 370 | + | |
| 371 | + nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE); | |
| 372 | + | |
| 373 | + arch_name = "MAC99"; | |
| 207 | 374 | } |
| 208 | - | |
| 209 | - ide0_mem_index = pmac_ide_init(&bs_table[0], openpic, 0x13); | |
| 210 | - ide1_mem_index = pmac_ide_init(&bs_table[2], openpic, 0x14); | |
| 211 | - | |
| 212 | - /* cuda also initialize ADB */ | |
| 213 | - cuda_mem_index = cuda_init(openpic, 0x19); | |
| 214 | - | |
| 215 | - adb_kbd_init(&adb_bus); | |
| 216 | - adb_mouse_init(&adb_bus); | |
| 217 | - | |
| 218 | - macio_init(pci_bus); | |
| 219 | - | |
| 220 | - nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE); | |
| 221 | 375 | |
| 222 | 376 | if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) |
| 223 | 377 | graphic_depth = 15; |
| 224 | 378 | |
| 225 | - PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "CHRP", ram_size, boot_device, | |
| 379 | + PPC_NVRAM_set_params(nvram, NVRAM_SIZE, arch_name, ram_size, boot_device, | |
| 226 | 380 | kernel_base, kernel_size, |
| 227 | 381 | kernel_cmdline, |
| 228 | 382 | initrd_base, initrd_size, |
| ... | ... | @@ -230,4 +384,45 @@ void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, |
| 230 | 384 | 0, |
| 231 | 385 | graphic_width, graphic_height, graphic_depth); |
| 232 | 386 | /* No PCI init: the BIOS will do it */ |
| 387 | + | |
| 388 | + /* Special port to get debug messages from Open-Firmware */ | |
| 389 | + register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL); | |
| 390 | +} | |
| 391 | + | |
| 392 | +static void ppc_core99_init(int ram_size, int vga_ram_size, int boot_device, | |
| 393 | + DisplayState *ds, const char **fd_filename, | |
| 394 | + int snapshot, | |
| 395 | + const char *kernel_filename, | |
| 396 | + const char *kernel_cmdline, | |
| 397 | + const char *initrd_filename) | |
| 398 | +{ | |
| 399 | + ppc_chrp_init(ram_size, vga_ram_size, boot_device, | |
| 400 | + ds, fd_filename, snapshot, | |
| 401 | + kernel_filename, kernel_cmdline, | |
| 402 | + initrd_filename, 0); | |
| 233 | 403 | } |
| 404 | + | |
| 405 | +static void ppc_heathrow_init(int ram_size, int vga_ram_size, int boot_device, | |
| 406 | + DisplayState *ds, const char **fd_filename, | |
| 407 | + int snapshot, | |
| 408 | + const char *kernel_filename, | |
| 409 | + const char *kernel_cmdline, | |
| 410 | + const char *initrd_filename) | |
| 411 | +{ | |
| 412 | + ppc_chrp_init(ram_size, vga_ram_size, boot_device, | |
| 413 | + ds, fd_filename, snapshot, | |
| 414 | + kernel_filename, kernel_cmdline, | |
| 415 | + initrd_filename, 1); | |
| 416 | +} | |
| 417 | + | |
| 418 | +QEMUMachine core99_machine = { | |
| 419 | + "core99", | |
| 420 | + "Core99 based PowerMAC", | |
| 421 | + ppc_core99_init, | |
| 422 | +}; | |
| 423 | + | |
| 424 | +QEMUMachine heathrow_machine = { | |
| 425 | + "heathrow", | |
| 426 | + "Heathrow based PowerMAC", | |
| 427 | + ppc_heathrow_init, | |
| 428 | +}; | ... | ... |