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