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