Commit 1a6c0886203689bd522d814d3c698328d35aaf91

Authored by j_mayer
1 parent 6b80055d

Evaluation boards for PowerPC 405EP.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2722 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -426,7 +426,7 @@ ifeq ($(TARGET_BASE_ARCH), ppc)
426 426 VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
427 427 VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o pflash_cfi02.o
428 428 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o
429   -VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o ppc405_uc.o
  429 +VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o ppc405_uc.o ppc405_boards.o
430 430 CPPFLAGS += -DHAS_AUDIO
431 431 endif
432 432 ifeq ($(TARGET_BASE_ARCH), mips)
... ...
hw/ppc405_boards.c 0 → 100644
  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 "vl.h"
  25 +#include "ppc405.h"
  26 +
  27 +extern int loglevel;
  28 +extern FILE *logfile;
  29 +
  30 +#define BIOS_FILENAME "ppc405_rom.bin"
  31 +#undef BIOS_SIZE
  32 +#define BIOS_SIZE (2048 * 1024)
  33 +
  34 +#define KERNEL_LOAD_ADDR 0x00000000
  35 +#define INITRD_LOAD_ADDR 0x01800000
  36 +
  37 +#define USE_FLASH_BIOS
  38 +
  39 +#define DEBUG_BOARD_INIT
  40 +
  41 +/*****************************************************************************/
  42 +/* PPC405EP reference board (IBM) */
  43 +/* Standalone board with:
  44 + * - PowerPC 405EP CPU
  45 + * - SDRAM (0x00000000)
  46 + * - Flash (0xFFF80000)
  47 + * - SRAM (0xFFF00000)
  48 + * - NVRAM (0xF0000000)
  49 + * - FPGA (0xF0300000)
  50 + */
  51 +typedef struct ref405ep_fpga_t ref405ep_fpga_t;
  52 +struct ref405ep_fpga_t {
  53 + uint32_t base;
  54 + uint8_t reg0;
  55 + uint8_t reg1;
  56 +};
  57 +
  58 +static uint32_t ref405ep_fpga_readb (void *opaque, target_phys_addr_t addr)
  59 +{
  60 + ref405ep_fpga_t *fpga;
  61 + uint32_t ret;
  62 +
  63 + fpga = opaque;
  64 + addr -= fpga->base;
  65 + switch (addr) {
  66 + case 0x0:
  67 + ret = fpga->reg0;
  68 + break;
  69 + case 0x1:
  70 + ret = fpga->reg1;
  71 + break;
  72 + default:
  73 + ret = 0;
  74 + break;
  75 + }
  76 +
  77 + return ret;
  78 +}
  79 +
  80 +static void ref405ep_fpga_writeb (void *opaque,
  81 + target_phys_addr_t addr, uint32_t value)
  82 +{
  83 + ref405ep_fpga_t *fpga;
  84 +
  85 + fpga = opaque;
  86 + addr -= fpga->base;
  87 + switch (addr) {
  88 + case 0x0:
  89 + /* Read only */
  90 + break;
  91 + case 0x1:
  92 + fpga->reg1 = value;
  93 + break;
  94 + default:
  95 + break;
  96 + }
  97 +}
  98 +
  99 +static uint32_t ref405ep_fpga_readw (void *opaque, target_phys_addr_t addr)
  100 +{
  101 + uint32_t ret;
  102 +
  103 + ret = ref405ep_fpga_readb(opaque, addr) << 8;
  104 + ret |= ref405ep_fpga_readb(opaque, addr + 1);
  105 +
  106 + return ret;
  107 +}
  108 +
  109 +static void ref405ep_fpga_writew (void *opaque,
  110 + target_phys_addr_t addr, uint32_t value)
  111 +{
  112 + ref405ep_fpga_writeb(opaque, addr, (value >> 8) & 0xFF);
  113 + ref405ep_fpga_writeb(opaque, addr + 1, value & 0xFF);
  114 +}
  115 +
  116 +static uint32_t ref405ep_fpga_readl (void *opaque, target_phys_addr_t addr)
  117 +{
  118 + uint32_t ret;
  119 +
  120 + ret = ref405ep_fpga_readb(opaque, addr) << 24;
  121 + ret |= ref405ep_fpga_readb(opaque, addr + 1) << 16;
  122 + ret |= ref405ep_fpga_readb(opaque, addr + 2) << 8;
  123 + ret |= ref405ep_fpga_readb(opaque, addr + 3);
  124 +
  125 + return ret;
  126 +}
  127 +
  128 +static void ref405ep_fpga_writel (void *opaque,
  129 + target_phys_addr_t addr, uint32_t value)
  130 +{
  131 + ref405ep_fpga_writel(opaque, addr, (value >> 24) & 0xFF);
  132 + ref405ep_fpga_writel(opaque, addr + 1, (value >> 16) & 0xFF);
  133 + ref405ep_fpga_writel(opaque, addr + 2, (value >> 8) & 0xFF);
  134 + ref405ep_fpga_writeb(opaque, addr + 3, value & 0xFF);
  135 +}
  136 +
  137 +static CPUReadMemoryFunc *ref405ep_fpga_read[] = {
  138 + &ref405ep_fpga_readb,
  139 + &ref405ep_fpga_readw,
  140 + &ref405ep_fpga_readl,
  141 +};
  142 +
  143 +static CPUWriteMemoryFunc *ref405ep_fpga_write[] = {
  144 + &ref405ep_fpga_writeb,
  145 + &ref405ep_fpga_writew,
  146 + &ref405ep_fpga_writel,
  147 +};
  148 +
  149 +static void ref405ep_fpga_reset (void *opaque)
  150 +{
  151 + ref405ep_fpga_t *fpga;
  152 +
  153 + fpga = opaque;
  154 + fpga->reg0 = 0x00;
  155 + fpga->reg1 = 0x0F;
  156 +}
  157 +
  158 +static void ref405ep_fpga_init (uint32_t base)
  159 +{
  160 + ref405ep_fpga_t *fpga;
  161 + int fpga_memory;
  162 +
  163 + fpga = qemu_mallocz(sizeof(ref405ep_fpga_t));
  164 + if (fpga != NULL) {
  165 + fpga->base = base;
  166 + fpga_memory = cpu_register_io_memory(0, ref405ep_fpga_read,
  167 + ref405ep_fpga_write, fpga);
  168 + cpu_register_physical_memory(base, 0x00000100, fpga_memory);
  169 + ref405ep_fpga_reset(fpga);
  170 + qemu_register_reset(&ref405ep_fpga_reset, fpga);
  171 + }
  172 +}
  173 +
  174 +static void ref405ep_init (int ram_size, int vga_ram_size, int boot_device,
  175 + DisplayState *ds, const char **fd_filename,
  176 + int snapshot,
  177 + const char *kernel_filename,
  178 + const char *kernel_cmdline,
  179 + const char *initrd_filename,
  180 + const char *cpu_model)
  181 +{
  182 + char buf[1024];
  183 + ppc4xx_bd_info_t bd;
  184 + CPUPPCState *env;
  185 + qemu_irq *pic;
  186 + ram_addr_t sram_offset, bios_offset, bdloc;
  187 + target_ulong ram_bases[2], ram_sizes[2];
  188 + target_ulong sram_size, bios_size;
  189 + //int phy_addr = 0;
  190 + //static int phy_addr = 1;
  191 + target_ulong kernel_base, kernel_size, initrd_base, initrd_size;
  192 + int linux_boot;
  193 + int fl_idx, fl_sectors, len;
  194 +
  195 + /* XXX: fix this */
  196 + ram_bases[0] = 0x00000000;
  197 + ram_sizes[0] = 0x08000000;
  198 + ram_bases[1] = 0x00000000;
  199 + ram_sizes[1] = 0x00000000;
  200 + ram_size = 128 * 1024 * 1024;
  201 +#ifdef DEBUG_BOARD_INIT
  202 + printf("%s: register cpu\n", __func__);
  203 +#endif
  204 + env = ppc405ep_init(ram_bases, ram_sizes, 33333333, &pic, &sram_offset,
  205 + kernel_filename == NULL ? 0 : 1);
  206 + /* allocate SRAM */
  207 +#ifdef DEBUG_BOARD_INIT
  208 + printf("%s: register SRAM at offset %08lx\n", __func__, sram_offset);
  209 +#endif
  210 + sram_size = 512 * 1024;
  211 + cpu_register_physical_memory(0xFFF00000, sram_size,
  212 + sram_offset | IO_MEM_RAM);
  213 + /* allocate and load BIOS */
  214 +#ifdef DEBUG_BOARD_INIT
  215 + printf("%s: register BIOS\n", __func__);
  216 +#endif
  217 + bios_offset = sram_offset + sram_size;
  218 + fl_idx = 0;
  219 +#ifdef USE_FLASH_BIOS
  220 + if (pflash_table[fl_idx] != NULL) {
  221 + bios_size = bdrv_getlength(pflash_table[fl_idx]);
  222 + fl_sectors = (bios_size + 65535) >> 16;
  223 +#ifdef DEBUG_BOARD_INIT
  224 + printf("Register parallel flash %d size " ADDRX " at offset %08lx "
  225 + " addr " ADDRX " '%s' %d\n",
  226 + fl_idx, bios_size, bios_offset, -bios_size,
  227 + bdrv_get_device_name(pflash_table[fl_idx]), fl_sectors);
  228 +#endif
  229 + pflash_register(-(bios_size), bios_offset, pflash_table[fl_idx],
  230 + 65536, fl_sectors, 2,
  231 + 0x0001, 0x22DA, 0x0000, 0x0000);
  232 + fl_idx++;
  233 + } else
  234 +#endif
  235 + {
  236 +#ifdef DEBUG_BOARD_INIT
  237 + printf("Load BIOS from file\n");
  238 +#endif
  239 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
  240 + bios_size = load_image(buf, phys_ram_base + bios_offset);
  241 + if (bios_size < 0 || bios_size > BIOS_SIZE) {
  242 + fprintf(stderr, "qemu: could not load PowerPC bios '%s'\n", buf);
  243 + exit(1);
  244 + }
  245 + bios_size = (bios_size + 0xfff) & ~0xfff;
  246 + cpu_register_physical_memory((uint32_t)(-bios_size),
  247 + bios_size, bios_offset | IO_MEM_ROM);
  248 + }
  249 + bios_offset += bios_size;
  250 + /* Register FPGA */
  251 +#ifdef DEBUG_BOARD_INIT
  252 + printf("%s: register FPGA\n", __func__);
  253 +#endif
  254 + ref405ep_fpga_init(0xF0300000);
  255 + /* Register NVRAM */
  256 +#ifdef DEBUG_BOARD_INIT
  257 + printf("%s: register NVRAM\n", __func__);
  258 +#endif
  259 + m48t59_init(NULL, 0xF0000000, 0, 8192, 8);
  260 + /* Load kernel */
  261 + linux_boot = (kernel_filename != NULL);
  262 + if (linux_boot) {
  263 +#ifdef DEBUG_BOARD_INIT
  264 + printf("%s: load kernel\n", __func__);
  265 +#endif
  266 + memset(&bd, 0, sizeof(bd));
  267 + bd.bi_memstart = 0x00000000;
  268 + bd.bi_memsize = ram_size;
  269 + bd.bi_flashstart = -(bios_size);
  270 + bd.bi_flashsize = -bios_size;
  271 + bd.bi_flashoffset = 0;
  272 + bd.bi_sramstart = 0xFFF00000;
  273 + bd.bi_sramsize = sram_size;
  274 + bd.bi_bootflags = 0;
  275 + bd.bi_intfreq = 133333333;
  276 + bd.bi_busfreq = 33333333;
  277 + bd.bi_baudrate = 115200;
  278 + bd.bi_s_version[0] = 'Q';
  279 + bd.bi_s_version[1] = 'M';
  280 + bd.bi_s_version[2] = 'U';
  281 + bd.bi_s_version[3] = '\0';
  282 + bd.bi_r_version[0] = 'Q';
  283 + bd.bi_r_version[1] = 'E';
  284 + bd.bi_r_version[2] = 'M';
  285 + bd.bi_r_version[3] = 'U';
  286 + bd.bi_r_version[4] = '\0';
  287 + bd.bi_procfreq = 133333333;
  288 + bd.bi_plb_busfreq = 33333333;
  289 + bd.bi_pci_busfreq = 33333333;
  290 + bd.bi_opbfreq = 33333333;
  291 + bdloc = ppc405_set_bootinfo(env, &bd);
  292 + env->gpr[3] = bdloc;
  293 + kernel_base = KERNEL_LOAD_ADDR;
  294 + /* now we can load the kernel */
  295 + kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
  296 + if (kernel_size < 0) {
  297 + fprintf(stderr, "qemu: could not load kernel '%s'\n",
  298 + kernel_filename);
  299 + exit(1);
  300 + }
  301 + printf("Load kernel size " TARGET_FMT_ld " at " TARGET_FMT_lx
  302 + " %02x %02x %02x %02x\n", kernel_size, kernel_base,
  303 + *(char *)(phys_ram_base + kernel_base),
  304 + *(char *)(phys_ram_base + kernel_base + 1),
  305 + *(char *)(phys_ram_base + kernel_base + 2),
  306 + *(char *)(phys_ram_base + kernel_base + 3));
  307 + /* load initrd */
  308 + if (initrd_filename) {
  309 + initrd_base = INITRD_LOAD_ADDR;
  310 + initrd_size = load_image(initrd_filename,
  311 + phys_ram_base + initrd_base);
  312 + if (initrd_size < 0) {
  313 + fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
  314 + initrd_filename);
  315 + exit(1);
  316 + }
  317 + } else {
  318 + initrd_base = 0;
  319 + initrd_size = 0;
  320 + }
  321 + env->gpr[4] = initrd_base;
  322 + env->gpr[5] = initrd_size;
  323 + boot_device = 'm';
  324 + if (kernel_cmdline != NULL) {
  325 + len = strlen(kernel_cmdline);
  326 + bdloc -= ((len + 255) & ~255);
  327 + memcpy(phys_ram_base + bdloc, kernel_cmdline, len + 1);
  328 + env->gpr[6] = bdloc;
  329 + env->gpr[7] = bdloc + len;
  330 + } else {
  331 + env->gpr[6] = 0;
  332 + env->gpr[7] = 0;
  333 + }
  334 + env->nip = KERNEL_LOAD_ADDR;
  335 + } else {
  336 + kernel_base = 0;
  337 + kernel_size = 0;
  338 + initrd_base = 0;
  339 + initrd_size = 0;
  340 + bdloc = 0;
  341 + }
  342 +#ifdef DEBUG_BOARD_INIT
  343 + printf("%s: Done\n", __func__);
  344 +#endif
  345 + printf("bdloc %016lx %s\n",
  346 + (unsigned long)bdloc, (char *)(phys_ram_base + bdloc));
  347 +}
  348 +
  349 +QEMUMachine ref405ep_machine = {
  350 + "ref405ep",
  351 + "ref405ep",
  352 + ref405ep_init,
  353 +};
  354 +
  355 +/*****************************************************************************/
  356 +/* AMCC Taihu evaluation board */
  357 +/* - PowerPC 405EP processor
  358 + * - SDRAM 128 MB at 0x00000000
  359 + * - Boot flash 2 MB at 0xFFE00000
  360 + * - Application flash 32 MB at 0xFC000000
  361 + * - 2 serial ports
  362 + * - 2 ethernet PHY
  363 + * - 1 USB 1.1 device 0x50000000
  364 + * - 1 LCD display 0x50100000
  365 + * - 1 CPLD 0x50100000
  366 + * - 1 I2C EEPROM
  367 + * - 1 I2C thermal sensor
  368 + * - a set of LEDs
  369 + * - bit-bang SPI port using GPIOs
  370 + * - 1 EBC interface connector 0 0x50200000
  371 + * - 1 cardbus controller + expansion slot.
  372 + * - 1 PCI expansion slot.
  373 + */
  374 +typedef struct taihu_cpld_t taihu_cpld_t;
  375 +struct taihu_cpld_t {
  376 + uint32_t base;
  377 + uint8_t reg0;
  378 + uint8_t reg1;
  379 +};
  380 +
  381 +static uint32_t taihu_cpld_readb (void *opaque, target_phys_addr_t addr)
  382 +{
  383 + taihu_cpld_t *cpld;
  384 + uint32_t ret;
  385 +
  386 + cpld = opaque;
  387 + addr -= cpld->base;
  388 + switch (addr) {
  389 + case 0x0:
  390 + ret = cpld->reg0;
  391 + break;
  392 + case 0x1:
  393 + ret = cpld->reg1;
  394 + break;
  395 + default:
  396 + ret = 0;
  397 + break;
  398 + }
  399 +
  400 + return ret;
  401 +}
  402 +
  403 +static void taihu_cpld_writeb (void *opaque,
  404 + target_phys_addr_t addr, uint32_t value)
  405 +{
  406 + taihu_cpld_t *cpld;
  407 +
  408 + cpld = opaque;
  409 + addr -= cpld->base;
  410 + switch (addr) {
  411 + case 0x0:
  412 + /* Read only */
  413 + break;
  414 + case 0x1:
  415 + cpld->reg1 = value;
  416 + break;
  417 + default:
  418 + break;
  419 + }
  420 +}
  421 +
  422 +static uint32_t taihu_cpld_readw (void *opaque, target_phys_addr_t addr)
  423 +{
  424 + uint32_t ret;
  425 +
  426 + ret = taihu_cpld_readb(opaque, addr) << 8;
  427 + ret |= taihu_cpld_readb(opaque, addr + 1);
  428 +
  429 + return ret;
  430 +}
  431 +
  432 +static void taihu_cpld_writew (void *opaque,
  433 + target_phys_addr_t addr, uint32_t value)
  434 +{
  435 + taihu_cpld_writeb(opaque, addr, (value >> 8) & 0xFF);
  436 + taihu_cpld_writeb(opaque, addr + 1, value & 0xFF);
  437 +}
  438 +
  439 +static uint32_t taihu_cpld_readl (void *opaque, target_phys_addr_t addr)
  440 +{
  441 + uint32_t ret;
  442 +
  443 + ret = taihu_cpld_readb(opaque, addr) << 24;
  444 + ret |= taihu_cpld_readb(opaque, addr + 1) << 16;
  445 + ret |= taihu_cpld_readb(opaque, addr + 2) << 8;
  446 + ret |= taihu_cpld_readb(opaque, addr + 3);
  447 +
  448 + return ret;
  449 +}
  450 +
  451 +static void taihu_cpld_writel (void *opaque,
  452 + target_phys_addr_t addr, uint32_t value)
  453 +{
  454 + taihu_cpld_writel(opaque, addr, (value >> 24) & 0xFF);
  455 + taihu_cpld_writel(opaque, addr + 1, (value >> 16) & 0xFF);
  456 + taihu_cpld_writel(opaque, addr + 2, (value >> 8) & 0xFF);
  457 + taihu_cpld_writeb(opaque, addr + 3, value & 0xFF);
  458 +}
  459 +
  460 +static CPUReadMemoryFunc *taihu_cpld_read[] = {
  461 + &taihu_cpld_readb,
  462 + &taihu_cpld_readw,
  463 + &taihu_cpld_readl,
  464 +};
  465 +
  466 +static CPUWriteMemoryFunc *taihu_cpld_write[] = {
  467 + &taihu_cpld_writeb,
  468 + &taihu_cpld_writew,
  469 + &taihu_cpld_writel,
  470 +};
  471 +
  472 +static void taihu_cpld_reset (void *opaque)
  473 +{
  474 + taihu_cpld_t *cpld;
  475 +
  476 + cpld = opaque;
  477 + cpld->reg0 = 0x01;
  478 + cpld->reg1 = 0x80;
  479 +}
  480 +
  481 +static void taihu_cpld_init (uint32_t base)
  482 +{
  483 + taihu_cpld_t *cpld;
  484 + int cpld_memory;
  485 +
  486 + cpld = qemu_mallocz(sizeof(taihu_cpld_t));
  487 + if (cpld != NULL) {
  488 + cpld->base = base;
  489 + cpld_memory = cpu_register_io_memory(0, taihu_cpld_read,
  490 + taihu_cpld_write, cpld);
  491 + cpu_register_physical_memory(base, 0x00000100, cpld_memory);
  492 + taihu_cpld_reset(cpld);
  493 + qemu_register_reset(&taihu_cpld_reset, cpld);
  494 + }
  495 +}
  496 +
  497 +static void taihu_405ep_init(int ram_size, int vga_ram_size, int boot_device,
  498 + DisplayState *ds, const char **fd_filename,
  499 + int snapshot,
  500 + const char *kernel_filename,
  501 + const char *kernel_cmdline,
  502 + const char *initrd_filename,
  503 + const char *cpu_model)
  504 +{
  505 + char buf[1024];
  506 + CPUPPCState *env;
  507 + qemu_irq *pic;
  508 + ram_addr_t bios_offset;
  509 + target_ulong ram_bases[2], ram_sizes[2];
  510 + target_ulong bios_size;
  511 + target_ulong kernel_base, kernel_size, initrd_base, initrd_size;
  512 + int linux_boot;
  513 + int fl_idx, fl_sectors;
  514 +
  515 + /* RAM is soldered to the board so the size cannot be changed */
  516 + ram_bases[0] = 0x00000000;
  517 + ram_sizes[0] = 0x04000000;
  518 + ram_bases[1] = 0x04000000;
  519 + ram_sizes[1] = 0x04000000;
  520 +#ifdef DEBUG_BOARD_INIT
  521 + printf("%s: register cpu\n", __func__);
  522 +#endif
  523 + env = ppc405ep_init(ram_bases, ram_sizes, 33333333, &pic, &bios_offset,
  524 + kernel_filename == NULL ? 0 : 1);
  525 + /* allocate and load BIOS */
  526 +#ifdef DEBUG_BOARD_INIT
  527 + printf("%s: register BIOS\n", __func__);
  528 +#endif
  529 + fl_idx = 0;
  530 +#if defined(USE_FLASH_BIOS)
  531 + if (pflash_table[fl_idx] != NULL) {
  532 + bios_size = bdrv_getlength(pflash_table[fl_idx]);
  533 + /* XXX: should check that size is 2MB */
  534 + // bios_size = 2 * 1024 * 1024;
  535 + fl_sectors = (bios_size + 65535) >> 16;
  536 +#ifdef DEBUG_BOARD_INIT
  537 + printf("Register parallel flash %d size " ADDRX " at offset %08lx "
  538 + " addr " ADDRX " '%s' %d\n",
  539 + fl_idx, bios_size, bios_offset, -bios_size,
  540 + bdrv_get_device_name(pflash_table[fl_idx]), fl_sectors);
  541 +#endif
  542 + pflash_register(-(bios_size), bios_offset, pflash_table[fl_idx],
  543 + 65536, fl_sectors, 4,
  544 + 0x0001, 0x22DA, 0x0000, 0x0000);
  545 + fl_idx++;
  546 + } else
  547 +#endif
  548 + {
  549 +#ifdef DEBUG_BOARD_INIT
  550 + printf("Load BIOS from file\n");
  551 +#endif
  552 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
  553 + bios_size = load_image(buf, phys_ram_base + bios_offset);
  554 + if (bios_size < 0 || bios_size > BIOS_SIZE) {
  555 + fprintf(stderr, "qemu: could not load PowerPC bios '%s'\n", buf);
  556 + exit(1);
  557 + }
  558 + bios_size = (bios_size + 0xfff) & ~0xfff;
  559 + cpu_register_physical_memory((uint32_t)(-bios_size),
  560 + bios_size, bios_offset | IO_MEM_ROM);
  561 + }
  562 + bios_offset += bios_size;
  563 + /* Register Linux flash */
  564 + if (pflash_table[fl_idx] != NULL) {
  565 + bios_size = bdrv_getlength(pflash_table[fl_idx]);
  566 + /* XXX: should check that size is 32MB */
  567 + bios_size = 32 * 1024 * 1024;
  568 + fl_sectors = (bios_size + 65535) >> 16;
  569 +#ifdef DEBUG_BOARD_INIT
  570 + printf("Register parallel flash %d size " ADDRX " at offset %08lx "
  571 + " addr " ADDRX " '%s'\n",
  572 + fl_idx, bios_size, bios_offset, (target_ulong)0xfc000000,
  573 + bdrv_get_device_name(pflash_table[fl_idx]));
  574 +#endif
  575 + pflash_register(0xfc000000, bios_offset, pflash_table[fl_idx],
  576 + 65536, fl_sectors, 4,
  577 + 0x0001, 0x22DA, 0x0000, 0x0000);
  578 + fl_idx++;
  579 + }
  580 + /* Register CLPD & LCD display */
  581 +#ifdef DEBUG_BOARD_INIT
  582 + printf("%s: register CPLD\n", __func__);
  583 +#endif
  584 + taihu_cpld_init(0x50100000);
  585 + /* Load kernel */
  586 + linux_boot = (kernel_filename != NULL);
  587 + if (linux_boot) {
  588 +#ifdef DEBUG_BOARD_INIT
  589 + printf("%s: load kernel\n", __func__);
  590 +#endif
  591 + kernel_base = KERNEL_LOAD_ADDR;
  592 + /* now we can load the kernel */
  593 + kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
  594 + if (kernel_size < 0) {
  595 + fprintf(stderr, "qemu: could not load kernel '%s'\n",
  596 + kernel_filename);
  597 + exit(1);
  598 + }
  599 + /* load initrd */
  600 + if (initrd_filename) {
  601 + initrd_base = INITRD_LOAD_ADDR;
  602 + initrd_size = load_image(initrd_filename,
  603 + phys_ram_base + initrd_base);
  604 + if (initrd_size < 0) {
  605 + fprintf(stderr,
  606 + "qemu: could not load initial ram disk '%s'\n",
  607 + initrd_filename);
  608 + exit(1);
  609 + }
  610 + } else {
  611 + initrd_base = 0;
  612 + initrd_size = 0;
  613 + }
  614 + boot_device = 'm';
  615 + } else {
  616 + kernel_base = 0;
  617 + kernel_size = 0;
  618 + initrd_base = 0;
  619 + initrd_size = 0;
  620 + }
  621 +#ifdef DEBUG_BOARD_INIT
  622 + printf("%s: Done\n", __func__);
  623 +#endif
  624 +}
  625 +
  626 +QEMUMachine taihu_machine = {
  627 + "taihu",
  628 + "taihu",
  629 + taihu_405ep_init,
  630 +};
... ...
... ... @@ -6717,6 +6717,8 @@ void register_machines(void)
6717 6717 qemu_register_machine(&heathrow_machine);
6718 6718 qemu_register_machine(&core99_machine);
6719 6719 qemu_register_machine(&prep_machine);
  6720 + qemu_register_machine(&ref405ep_machine);
  6721 + qemu_register_machine(&taihu_machine);
6720 6722 #elif defined(TARGET_MIPS)
6721 6723 qemu_register_machine(&mips_machine);
6722 6724 qemu_register_machine(&mips_malta_machine);
... ...
... ... @@ -1133,6 +1133,8 @@ int ioport_get_a20(void);
1133 1133 extern QEMUMachine prep_machine;
1134 1134 extern QEMUMachine core99_machine;
1135 1135 extern QEMUMachine heathrow_machine;
  1136 +extern QEMUMachine ref405ep_machine;
  1137 +extern QEMUMachine taihu_machine;
1136 1138  
1137 1139 /* mips_r4k.c */
1138 1140 extern QEMUMachine mips_machine;
... ...