1 /* 2 * QEMU PowerPC 405 evaluation boards emulation 3 * 4 * Copyright (c) 2007 Jocelyn Mayer 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 #include "qemu/osdep.h" 25 #include "qemu/units.h" 26 #include "qapi/error.h" 27 #include "qemu-common.h" 28 #include "cpu.h" 29 #include "hw/hw.h" 30 #include "hw/ppc/ppc.h" 31 #include "ppc405.h" 32 #include "hw/timer/m48t59.h" 33 #include "hw/block/flash.h" 34 #include "sysemu/sysemu.h" 35 #include "sysemu/qtest.h" 36 #include "sysemu/block-backend.h" 37 #include "hw/boards.h" 38 #include "qemu/log.h" 39 #include "qemu/error-report.h" 40 #include "hw/loader.h" 41 #include "exec/address-spaces.h" 42 43 #define BIOS_FILENAME "ppc405_rom.bin" 44 #define BIOS_SIZE (2 * MiB) 45 46 #define KERNEL_LOAD_ADDR 0x00000000 47 #define INITRD_LOAD_ADDR 0x01800000 48 49 #define USE_FLASH_BIOS 50 51 /*****************************************************************************/ 52 /* PPC405EP reference board (IBM) */ 53 /* Standalone board with: 54 * - PowerPC 405EP CPU 55 * - SDRAM (0x00000000) 56 * - Flash (0xFFF80000) 57 * - SRAM (0xFFF00000) 58 * - NVRAM (0xF0000000) 59 * - FPGA (0xF0300000) 60 */ 61 typedef struct ref405ep_fpga_t ref405ep_fpga_t; 62 struct ref405ep_fpga_t { 63 uint8_t reg0; 64 uint8_t reg1; 65 }; 66 67 static uint64_t ref405ep_fpga_readb(void *opaque, hwaddr addr, unsigned size) 68 { 69 ref405ep_fpga_t *fpga; 70 uint32_t ret; 71 72 fpga = opaque; 73 switch (addr) { 74 case 0x0: 75 ret = fpga->reg0; 76 break; 77 case 0x1: 78 ret = fpga->reg1; 79 break; 80 default: 81 ret = 0; 82 break; 83 } 84 85 return ret; 86 } 87 88 static void ref405ep_fpga_writeb(void *opaque, hwaddr addr, uint64_t value, 89 unsigned size) 90 { 91 ref405ep_fpga_t *fpga; 92 93 fpga = opaque; 94 switch (addr) { 95 case 0x0: 96 /* Read only */ 97 break; 98 case 0x1: 99 fpga->reg1 = value; 100 break; 101 default: 102 break; 103 } 104 } 105 106 static const MemoryRegionOps ref405ep_fpga_ops = { 107 .read = ref405ep_fpga_readb, 108 .write = ref405ep_fpga_writeb, 109 .impl.min_access_size = 1, 110 .impl.max_access_size = 1, 111 .valid.min_access_size = 1, 112 .valid.max_access_size = 4, 113 .endianness = DEVICE_BIG_ENDIAN, 114 }; 115 116 static void ref405ep_fpga_reset (void *opaque) 117 { 118 ref405ep_fpga_t *fpga; 119 120 fpga = opaque; 121 fpga->reg0 = 0x00; 122 fpga->reg1 = 0x0F; 123 } 124 125 static void ref405ep_fpga_init(MemoryRegion *sysmem, uint32_t base) 126 { 127 ref405ep_fpga_t *fpga; 128 MemoryRegion *fpga_memory = g_new(MemoryRegion, 1); 129 130 fpga = g_malloc0(sizeof(ref405ep_fpga_t)); 131 memory_region_init_io(fpga_memory, NULL, &ref405ep_fpga_ops, fpga, 132 "fpga", 0x00000100); 133 memory_region_add_subregion(sysmem, base, fpga_memory); 134 qemu_register_reset(&ref405ep_fpga_reset, fpga); 135 } 136 137 static void ref405ep_init(MachineState *machine) 138 { 139 ram_addr_t ram_size = machine->ram_size; 140 const char *kernel_filename = machine->kernel_filename; 141 const char *kernel_cmdline = machine->kernel_cmdline; 142 const char *initrd_filename = machine->initrd_filename; 143 char *filename; 144 ppc4xx_bd_info_t bd; 145 CPUPPCState *env; 146 qemu_irq *pic; 147 MemoryRegion *bios; 148 MemoryRegion *sram = g_new(MemoryRegion, 1); 149 ram_addr_t bdloc; 150 MemoryRegion *ram_memories = g_new(MemoryRegion, 2); 151 hwaddr ram_bases[2], ram_sizes[2]; 152 target_ulong sram_size; 153 long bios_size; 154 //int phy_addr = 0; 155 //static int phy_addr = 1; 156 target_ulong kernel_base, initrd_base; 157 long kernel_size, initrd_size; 158 int linux_boot; 159 int len; 160 DriveInfo *dinfo; 161 MemoryRegion *sysmem = get_system_memory(); 162 163 /* XXX: fix this */ 164 memory_region_allocate_system_memory(&ram_memories[0], NULL, "ef405ep.ram", 165 0x08000000); 166 ram_bases[0] = 0; 167 ram_sizes[0] = 0x08000000; 168 memory_region_init(&ram_memories[1], NULL, "ef405ep.ram1", 0); 169 ram_bases[1] = 0x00000000; 170 ram_sizes[1] = 0x00000000; 171 ram_size = 128 * MiB; 172 env = ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes, 173 33333333, &pic, kernel_filename == NULL ? 0 : 1); 174 /* allocate SRAM */ 175 sram_size = 512 * KiB; 176 memory_region_init_ram(sram, NULL, "ef405ep.sram", sram_size, 177 &error_fatal); 178 memory_region_add_subregion(sysmem, 0xFFF00000, sram); 179 /* allocate and load BIOS */ 180 #ifdef USE_FLASH_BIOS 181 dinfo = drive_get(IF_PFLASH, 0, 0); 182 if (dinfo) { 183 bios_size = 8 * MiB; 184 pflash_cfi02_register((uint32_t)(-bios_size), 185 "ef405ep.bios", bios_size, 186 dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, 187 64 * KiB, 1, 188 2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, 189 1); 190 } else 191 #endif 192 { 193 bios = g_new(MemoryRegion, 1); 194 memory_region_init_ram(bios, NULL, "ef405ep.bios", BIOS_SIZE, 195 &error_fatal); 196 197 if (bios_name == NULL) 198 bios_name = BIOS_FILENAME; 199 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); 200 if (filename) { 201 bios_size = load_image_size(filename, 202 memory_region_get_ram_ptr(bios), 203 BIOS_SIZE); 204 g_free(filename); 205 if (bios_size < 0) { 206 error_report("Could not load PowerPC BIOS '%s'", bios_name); 207 exit(1); 208 } 209 bios_size = (bios_size + 0xfff) & ~0xfff; 210 memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios); 211 } else if (!qtest_enabled() || kernel_filename != NULL) { 212 error_report("Could not load PowerPC BIOS '%s'", bios_name); 213 exit(1); 214 } else { 215 /* Avoid an uninitialized variable warning */ 216 bios_size = -1; 217 } 218 memory_region_set_readonly(bios, true); 219 } 220 /* Register FPGA */ 221 ref405ep_fpga_init(sysmem, 0xF0300000); 222 /* Register NVRAM */ 223 m48t59_init(NULL, 0xF0000000, 0, 8192, 1968, 8); 224 /* Load kernel */ 225 linux_boot = (kernel_filename != NULL); 226 if (linux_boot) { 227 memset(&bd, 0, sizeof(bd)); 228 bd.bi_memstart = 0x00000000; 229 bd.bi_memsize = ram_size; 230 bd.bi_flashstart = -bios_size; 231 bd.bi_flashsize = -bios_size; 232 bd.bi_flashoffset = 0; 233 bd.bi_sramstart = 0xFFF00000; 234 bd.bi_sramsize = sram_size; 235 bd.bi_bootflags = 0; 236 bd.bi_intfreq = 133333333; 237 bd.bi_busfreq = 33333333; 238 bd.bi_baudrate = 115200; 239 bd.bi_s_version[0] = 'Q'; 240 bd.bi_s_version[1] = 'M'; 241 bd.bi_s_version[2] = 'U'; 242 bd.bi_s_version[3] = '\0'; 243 bd.bi_r_version[0] = 'Q'; 244 bd.bi_r_version[1] = 'E'; 245 bd.bi_r_version[2] = 'M'; 246 bd.bi_r_version[3] = 'U'; 247 bd.bi_r_version[4] = '\0'; 248 bd.bi_procfreq = 133333333; 249 bd.bi_plb_busfreq = 33333333; 250 bd.bi_pci_busfreq = 33333333; 251 bd.bi_opbfreq = 33333333; 252 bdloc = ppc405_set_bootinfo(env, &bd, 0x00000001); 253 env->gpr[3] = bdloc; 254 kernel_base = KERNEL_LOAD_ADDR; 255 /* now we can load the kernel */ 256 kernel_size = load_image_targphys(kernel_filename, kernel_base, 257 ram_size - kernel_base); 258 if (kernel_size < 0) { 259 error_report("could not load kernel '%s'", kernel_filename); 260 exit(1); 261 } 262 printf("Load kernel size %ld at " TARGET_FMT_lx, 263 kernel_size, kernel_base); 264 /* load initrd */ 265 if (initrd_filename) { 266 initrd_base = INITRD_LOAD_ADDR; 267 initrd_size = load_image_targphys(initrd_filename, initrd_base, 268 ram_size - initrd_base); 269 if (initrd_size < 0) { 270 error_report("could not load initial ram disk '%s'", 271 initrd_filename); 272 exit(1); 273 } 274 } else { 275 initrd_base = 0; 276 initrd_size = 0; 277 } 278 env->gpr[4] = initrd_base; 279 env->gpr[5] = initrd_size; 280 if (kernel_cmdline != NULL) { 281 len = strlen(kernel_cmdline); 282 bdloc -= ((len + 255) & ~255); 283 cpu_physical_memory_write(bdloc, kernel_cmdline, len + 1); 284 env->gpr[6] = bdloc; 285 env->gpr[7] = bdloc + len; 286 } else { 287 env->gpr[6] = 0; 288 env->gpr[7] = 0; 289 } 290 env->nip = KERNEL_LOAD_ADDR; 291 } else { 292 kernel_base = 0; 293 kernel_size = 0; 294 initrd_base = 0; 295 initrd_size = 0; 296 bdloc = 0; 297 } 298 } 299 300 static void ref405ep_class_init(ObjectClass *oc, void *data) 301 { 302 MachineClass *mc = MACHINE_CLASS(oc); 303 304 mc->desc = "ref405ep"; 305 mc->init = ref405ep_init; 306 } 307 308 static const TypeInfo ref405ep_type = { 309 .name = MACHINE_TYPE_NAME("ref405ep"), 310 .parent = TYPE_MACHINE, 311 .class_init = ref405ep_class_init, 312 }; 313 314 /*****************************************************************************/ 315 /* AMCC Taihu evaluation board */ 316 /* - PowerPC 405EP processor 317 * - SDRAM 128 MB at 0x00000000 318 * - Boot flash 2 MB at 0xFFE00000 319 * - Application flash 32 MB at 0xFC000000 320 * - 2 serial ports 321 * - 2 ethernet PHY 322 * - 1 USB 1.1 device 0x50000000 323 * - 1 LCD display 0x50100000 324 * - 1 CPLD 0x50100000 325 * - 1 I2C EEPROM 326 * - 1 I2C thermal sensor 327 * - a set of LEDs 328 * - bit-bang SPI port using GPIOs 329 * - 1 EBC interface connector 0 0x50200000 330 * - 1 cardbus controller + expansion slot. 331 * - 1 PCI expansion slot. 332 */ 333 typedef struct taihu_cpld_t taihu_cpld_t; 334 struct taihu_cpld_t { 335 uint8_t reg0; 336 uint8_t reg1; 337 }; 338 339 static uint64_t taihu_cpld_read(void *opaque, hwaddr addr, unsigned size) 340 { 341 taihu_cpld_t *cpld; 342 uint32_t ret; 343 344 cpld = opaque; 345 switch (addr) { 346 case 0x0: 347 ret = cpld->reg0; 348 break; 349 case 0x1: 350 ret = cpld->reg1; 351 break; 352 default: 353 ret = 0; 354 break; 355 } 356 357 return ret; 358 } 359 360 static void taihu_cpld_write(void *opaque, hwaddr addr, 361 uint64_t value, unsigned size) 362 { 363 taihu_cpld_t *cpld; 364 365 cpld = opaque; 366 switch (addr) { 367 case 0x0: 368 /* Read only */ 369 break; 370 case 0x1: 371 cpld->reg1 = value; 372 break; 373 default: 374 break; 375 } 376 } 377 378 static const MemoryRegionOps taihu_cpld_ops = { 379 .read = taihu_cpld_read, 380 .write = taihu_cpld_write, 381 .impl = { 382 .min_access_size = 1, 383 .max_access_size = 1, 384 }, 385 .endianness = DEVICE_NATIVE_ENDIAN, 386 }; 387 388 static void taihu_cpld_reset (void *opaque) 389 { 390 taihu_cpld_t *cpld; 391 392 cpld = opaque; 393 cpld->reg0 = 0x01; 394 cpld->reg1 = 0x80; 395 } 396 397 static void taihu_cpld_init(MemoryRegion *sysmem, uint32_t base) 398 { 399 taihu_cpld_t *cpld; 400 MemoryRegion *cpld_memory = g_new(MemoryRegion, 1); 401 402 cpld = g_malloc0(sizeof(taihu_cpld_t)); 403 memory_region_init_io(cpld_memory, NULL, &taihu_cpld_ops, cpld, "cpld", 0x100); 404 memory_region_add_subregion(sysmem, base, cpld_memory); 405 qemu_register_reset(&taihu_cpld_reset, cpld); 406 } 407 408 static void taihu_405ep_init(MachineState *machine) 409 { 410 ram_addr_t ram_size = machine->ram_size; 411 const char *kernel_filename = machine->kernel_filename; 412 const char *initrd_filename = machine->initrd_filename; 413 char *filename; 414 qemu_irq *pic; 415 MemoryRegion *sysmem = get_system_memory(); 416 MemoryRegion *bios; 417 MemoryRegion *ram_memories = g_new(MemoryRegion, 2); 418 MemoryRegion *ram = g_malloc0(sizeof(*ram)); 419 hwaddr ram_bases[2], ram_sizes[2]; 420 long bios_size; 421 target_ulong kernel_base, initrd_base; 422 long kernel_size, initrd_size; 423 int linux_boot; 424 int fl_idx; 425 DriveInfo *dinfo; 426 427 /* RAM is soldered to the board so the size cannot be changed */ 428 ram_size = 0x08000000; 429 memory_region_allocate_system_memory(ram, NULL, "taihu_405ep.ram", 430 ram_size); 431 432 ram_bases[0] = 0; 433 ram_sizes[0] = 0x04000000; 434 memory_region_init_alias(&ram_memories[0], NULL, 435 "taihu_405ep.ram-0", ram, ram_bases[0], 436 ram_sizes[0]); 437 ram_bases[1] = 0x04000000; 438 ram_sizes[1] = 0x04000000; 439 memory_region_init_alias(&ram_memories[1], NULL, 440 "taihu_405ep.ram-1", ram, ram_bases[1], 441 ram_sizes[1]); 442 ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes, 443 33333333, &pic, kernel_filename == NULL ? 0 : 1); 444 /* allocate and load BIOS */ 445 fl_idx = 0; 446 #if defined(USE_FLASH_BIOS) 447 dinfo = drive_get(IF_PFLASH, 0, fl_idx); 448 if (dinfo) { 449 bios_size = 2 * MiB; 450 pflash_cfi02_register(0xFFE00000, 451 "taihu_405ep.bios", bios_size, 452 dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, 453 64 * KiB, 1, 454 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, 455 1); 456 fl_idx++; 457 } else 458 #endif 459 { 460 if (bios_name == NULL) 461 bios_name = BIOS_FILENAME; 462 bios = g_new(MemoryRegion, 1); 463 memory_region_init_ram(bios, NULL, "taihu_405ep.bios", BIOS_SIZE, 464 &error_fatal); 465 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); 466 if (filename) { 467 bios_size = load_image_size(filename, 468 memory_region_get_ram_ptr(bios), 469 BIOS_SIZE); 470 g_free(filename); 471 if (bios_size < 0) { 472 error_report("Could not load PowerPC BIOS '%s'", bios_name); 473 exit(1); 474 } 475 bios_size = (bios_size + 0xfff) & ~0xfff; 476 memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios); 477 } else if (!qtest_enabled()) { 478 error_report("Could not load PowerPC BIOS '%s'", bios_name); 479 exit(1); 480 } 481 memory_region_set_readonly(bios, true); 482 } 483 /* Register Linux flash */ 484 dinfo = drive_get(IF_PFLASH, 0, fl_idx); 485 if (dinfo) { 486 bios_size = 32 * MiB; 487 pflash_cfi02_register(0xfc000000, "taihu_405ep.flash", bios_size, 488 dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, 489 64 * KiB, 1, 490 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA, 491 1); 492 fl_idx++; 493 } 494 /* Register CLPD & LCD display */ 495 taihu_cpld_init(sysmem, 0x50100000); 496 /* Load kernel */ 497 linux_boot = (kernel_filename != NULL); 498 if (linux_boot) { 499 kernel_base = KERNEL_LOAD_ADDR; 500 /* now we can load the kernel */ 501 kernel_size = load_image_targphys(kernel_filename, kernel_base, 502 ram_size - kernel_base); 503 if (kernel_size < 0) { 504 error_report("could not load kernel '%s'", kernel_filename); 505 exit(1); 506 } 507 /* load initrd */ 508 if (initrd_filename) { 509 initrd_base = INITRD_LOAD_ADDR; 510 initrd_size = load_image_targphys(initrd_filename, initrd_base, 511 ram_size - initrd_base); 512 if (initrd_size < 0) { 513 error_report("could not load initial ram disk '%s'", 514 initrd_filename); 515 exit(1); 516 } 517 } else { 518 initrd_base = 0; 519 initrd_size = 0; 520 } 521 } else { 522 kernel_base = 0; 523 kernel_size = 0; 524 initrd_base = 0; 525 initrd_size = 0; 526 } 527 } 528 529 static void taihu_class_init(ObjectClass *oc, void *data) 530 { 531 MachineClass *mc = MACHINE_CLASS(oc); 532 533 mc->desc = "taihu"; 534 mc->init = taihu_405ep_init; 535 } 536 537 static const TypeInfo taihu_type = { 538 .name = MACHINE_TYPE_NAME("taihu"), 539 .parent = TYPE_MACHINE, 540 .class_init = taihu_class_init, 541 }; 542 543 static void ppc405_machine_init(void) 544 { 545 type_register_static(&ref405ep_type); 546 type_register_static(&taihu_type); 547 } 548 549 type_init(ppc405_machine_init) 550