2 * QEMU PowerPC 405 evaluation boards emulation
4 * Copyright (c) 2007 Jocelyn Mayer
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
25 #include "qemu/osdep.h"
26 #include "qemu/units.h"
27 #include "qapi/error.h"
28 #include "qemu/datadir.h"
30 #include "hw/ppc/ppc.h"
31 #include "hw/qdev-properties.h"
32 #include "hw/sysbus.h"
34 #include "hw/rtc/m48t59.h"
35 #include "hw/block/flash.h"
36 #include "sysemu/qtest.h"
37 #include "sysemu/reset.h"
38 #include "sysemu/block-backend.h"
39 #include "hw/boards.h"
40 #include "qemu/error-report.h"
41 #include "hw/loader.h"
42 #include "qemu/cutils.h"
45 #define BIOS_FILENAME "ppc405_rom.bin"
46 #define BIOS_SIZE (2 * MiB)
48 #define KERNEL_LOAD_ADDR 0x01000000
49 #define INITRD_LOAD_ADDR 0x01800000
51 #define PPC405EP_SDRAM_BASE 0x00000000
52 #define PPC405EP_SRAM_BASE 0xFFF00000
53 #define PPC405EP_SRAM_SIZE (512 * KiB)
55 #define USE_FLASH_BIOS
57 #define TYPE_PPC405_MACHINE MACHINE_TYPE_NAME("ppc405")
58 OBJECT_DECLARE_SIMPLE_TYPE(Ppc405MachineState
, PPC405_MACHINE
);
60 struct Ppc405MachineState
{
62 MachineState parent_obj
;
68 /* CPU reset handler when booting directly from a loaded kernel */
69 static struct boot_info
{
74 uint32_t cmdline_base
;
75 uint32_t cmdline_size
;
78 static void main_cpu_reset(void *opaque
)
80 PowerPCCPU
*cpu
= opaque
;
81 CPUPPCState
*env
= &cpu
->env
;
82 struct boot_info
*bi
= env
->load_info
;
86 /* stack: top of sram */
87 env
->gpr
[1] = PPC405EP_SRAM_BASE
+ PPC405EP_SRAM_SIZE
- 8;
89 /* Tune our boot state */
90 env
->gpr
[3] = bi
->bdloc
;
91 env
->gpr
[4] = bi
->initrd_base
;
92 env
->gpr
[5] = bi
->initrd_base
+ bi
->initrd_size
;
93 env
->gpr
[6] = bi
->cmdline_base
;
94 env
->gpr
[7] = bi
->cmdline_size
;
99 /* Bootinfo as set-up by u-boot */
101 uint32_t bi_memstart
;
103 uint32_t bi_flashstart
;
104 uint32_t bi_flashsize
;
105 uint32_t bi_flashoffset
; /* 0x10 */
106 uint32_t bi_sramstart
;
107 uint32_t bi_sramsize
;
108 uint32_t bi_bootflags
;
109 uint32_t bi_ipaddr
; /* 0x20 */
110 uint8_t bi_enetaddr
[6];
111 uint16_t bi_ethspeed
;
113 uint32_t bi_busfreq
; /* 0x30 */
114 uint32_t bi_baudrate
;
115 uint8_t bi_s_version
[4];
116 uint8_t bi_r_version
[32];
117 uint32_t bi_procfreq
;
118 uint32_t bi_plb_busfreq
;
119 uint32_t bi_pci_busfreq
;
120 uint8_t bi_pci_enetaddr
[6];
121 uint8_t bi_pci_enetaddr2
[6]; /* PPC405EP specific */
123 uint32_t bi_iic_fast
[2];
126 static void ppc405_set_default_bootinfo(ppc4xx_bd_info_t
*bd
,
129 memset(bd
, 0, sizeof(*bd
));
131 bd
->bi_memstart
= PPC405EP_SDRAM_BASE
;
132 bd
->bi_memsize
= ram_size
;
133 bd
->bi_sramstart
= PPC405EP_SRAM_BASE
;
134 bd
->bi_sramsize
= PPC405EP_SRAM_SIZE
;
135 bd
->bi_bootflags
= 0;
136 bd
->bi_intfreq
= 133333333;
137 bd
->bi_busfreq
= 33333333;
138 bd
->bi_baudrate
= 115200;
139 bd
->bi_s_version
[0] = 'Q';
140 bd
->bi_s_version
[1] = 'M';
141 bd
->bi_s_version
[2] = 'U';
142 bd
->bi_s_version
[3] = '\0';
143 bd
->bi_r_version
[0] = 'Q';
144 bd
->bi_r_version
[1] = 'E';
145 bd
->bi_r_version
[2] = 'M';
146 bd
->bi_r_version
[3] = 'U';
147 bd
->bi_r_version
[4] = '\0';
148 bd
->bi_procfreq
= 133333333;
149 bd
->bi_plb_busfreq
= 33333333;
150 bd
->bi_pci_busfreq
= 33333333;
151 bd
->bi_opbfreq
= 33333333;
154 static ram_addr_t
__ppc405_set_bootinfo(CPUPPCState
*env
, ppc4xx_bd_info_t
*bd
)
156 CPUState
*cs
= env_cpu(env
);
160 /* We put the bd structure at the top of memory */
161 if (bd
->bi_memsize
>= 0x01000000UL
) {
162 bdloc
= 0x01000000UL
- sizeof(ppc4xx_bd_info_t
);
164 bdloc
= bd
->bi_memsize
- sizeof(ppc4xx_bd_info_t
);
166 stl_be_phys(cs
->as
, bdloc
+ 0x00, bd
->bi_memstart
);
167 stl_be_phys(cs
->as
, bdloc
+ 0x04, bd
->bi_memsize
);
168 stl_be_phys(cs
->as
, bdloc
+ 0x08, bd
->bi_flashstart
);
169 stl_be_phys(cs
->as
, bdloc
+ 0x0C, bd
->bi_flashsize
);
170 stl_be_phys(cs
->as
, bdloc
+ 0x10, bd
->bi_flashoffset
);
171 stl_be_phys(cs
->as
, bdloc
+ 0x14, bd
->bi_sramstart
);
172 stl_be_phys(cs
->as
, bdloc
+ 0x18, bd
->bi_sramsize
);
173 stl_be_phys(cs
->as
, bdloc
+ 0x1C, bd
->bi_bootflags
);
174 stl_be_phys(cs
->as
, bdloc
+ 0x20, bd
->bi_ipaddr
);
175 for (i
= 0; i
< 6; i
++) {
176 stb_phys(cs
->as
, bdloc
+ 0x24 + i
, bd
->bi_enetaddr
[i
]);
178 stw_be_phys(cs
->as
, bdloc
+ 0x2A, bd
->bi_ethspeed
);
179 stl_be_phys(cs
->as
, bdloc
+ 0x2C, bd
->bi_intfreq
);
180 stl_be_phys(cs
->as
, bdloc
+ 0x30, bd
->bi_busfreq
);
181 stl_be_phys(cs
->as
, bdloc
+ 0x34, bd
->bi_baudrate
);
182 for (i
= 0; i
< 4; i
++) {
183 stb_phys(cs
->as
, bdloc
+ 0x38 + i
, bd
->bi_s_version
[i
]);
185 for (i
= 0; i
< 32; i
++) {
186 stb_phys(cs
->as
, bdloc
+ 0x3C + i
, bd
->bi_r_version
[i
]);
188 stl_be_phys(cs
->as
, bdloc
+ 0x5C, bd
->bi_procfreq
);
189 stl_be_phys(cs
->as
, bdloc
+ 0x60, bd
->bi_plb_busfreq
);
190 stl_be_phys(cs
->as
, bdloc
+ 0x64, bd
->bi_pci_busfreq
);
191 for (i
= 0; i
< 6; i
++) {
192 stb_phys(cs
->as
, bdloc
+ 0x68 + i
, bd
->bi_pci_enetaddr
[i
]);
194 n
= 0x70; /* includes 2 bytes hole */
195 for (i
= 0; i
< 6; i
++) {
196 stb_phys(cs
->as
, bdloc
+ n
++, bd
->bi_pci_enetaddr2
[i
]);
198 stl_be_phys(cs
->as
, bdloc
+ n
, bd
->bi_opbfreq
);
200 for (i
= 0; i
< 2; i
++) {
201 stl_be_phys(cs
->as
, bdloc
+ n
, bd
->bi_iic_fast
[i
]);
208 static ram_addr_t
ppc405_set_bootinfo(CPUPPCState
*env
, ram_addr_t ram_size
)
212 memset(&bd
, 0, sizeof(bd
));
214 ppc405_set_default_bootinfo(&bd
, ram_size
);
216 return __ppc405_set_bootinfo(env
, &bd
);
219 static void boot_from_kernel(MachineState
*machine
, PowerPCCPU
*cpu
)
221 CPUPPCState
*env
= &cpu
->env
;
230 bdloc
= ppc405_set_bootinfo(env
, machine
->ram_size
);
231 boot_info
.bdloc
= bdloc
;
233 kernel_size
= load_elf(machine
->kernel_filename
, NULL
, NULL
, NULL
,
234 &boot_entry
, &kernel_base
, NULL
, NULL
,
235 1, PPC_ELF_MACHINE
, 0, 0);
236 if (kernel_size
< 0) {
237 error_report("Could not load kernel '%s' : %s",
238 machine
->kernel_filename
, load_elf_strerror(kernel_size
));
241 boot_info
.entry
= boot_entry
;
244 if (machine
->initrd_filename
) {
245 initrd_base
= INITRD_LOAD_ADDR
;
246 initrd_size
= load_image_targphys(machine
->initrd_filename
, initrd_base
,
247 machine
->ram_size
- initrd_base
);
248 if (initrd_size
< 0) {
249 error_report("could not load initial ram disk '%s'",
250 machine
->initrd_filename
);
254 boot_info
.initrd_base
= initrd_base
;
255 boot_info
.initrd_size
= initrd_size
;
258 if (machine
->kernel_cmdline
) {
259 len
= strlen(machine
->kernel_cmdline
);
260 bdloc
-= ((len
+ 255) & ~255);
261 cpu_physical_memory_write(bdloc
, machine
->kernel_cmdline
, len
+ 1);
262 boot_info
.cmdline_base
= bdloc
;
263 boot_info
.cmdline_size
= bdloc
+ len
;
266 /* Install our custom reset handler to start from Linux */
267 qemu_register_reset(main_cpu_reset
, cpu
);
268 env
->load_info
= &boot_info
;
271 static void ppc405_init(MachineState
*machine
)
273 Ppc405MachineState
*ppc405
= PPC405_MACHINE(machine
);
274 const char *kernel_filename
= machine
->kernel_filename
;
275 MemoryRegion
*sysmem
= get_system_memory();
277 object_initialize_child(OBJECT(machine
), "soc", &ppc405
->soc
,
279 object_property_set_link(OBJECT(&ppc405
->soc
), "dram",
280 OBJECT(machine
->ram
), &error_abort
);
281 object_property_set_uint(OBJECT(&ppc405
->soc
), "sys-clk", 33333333,
283 qdev_realize(DEVICE(&ppc405
->soc
), NULL
, &error_fatal
);
285 /* allocate and load BIOS */
286 if (machine
->firmware
) {
287 MemoryRegion
*bios
= g_new(MemoryRegion
, 1);
288 g_autofree
char *filename
= qemu_find_file(QEMU_FILE_TYPE_BIOS
,
292 memory_region_init_rom(bios
, NULL
, "ef405ep.bios", BIOS_SIZE
,
296 error_report("Could not find firmware '%s'", machine
->firmware
);
300 bios_size
= load_image_size(filename
,
301 memory_region_get_ram_ptr(bios
),
304 error_report("Could not load PowerPC BIOS '%s'", machine
->firmware
);
308 bios_size
= (bios_size
+ 0xfff) & ~0xfff;
309 memory_region_add_subregion(sysmem
, (uint32_t)(-bios_size
), bios
);
312 /* Load kernel and initrd using U-Boot images */
313 if (kernel_filename
&& machine
->firmware
) {
314 target_ulong kernel_base
, initrd_base
;
315 long kernel_size
, initrd_size
;
317 kernel_base
= KERNEL_LOAD_ADDR
;
318 kernel_size
= load_image_targphys(kernel_filename
, kernel_base
,
319 machine
->ram_size
- kernel_base
);
320 if (kernel_size
< 0) {
321 error_report("could not load kernel '%s'", kernel_filename
);
326 if (machine
->initrd_filename
) {
327 initrd_base
= INITRD_LOAD_ADDR
;
328 initrd_size
= load_image_targphys(machine
->initrd_filename
,
330 machine
->ram_size
- initrd_base
);
331 if (initrd_size
< 0) {
332 error_report("could not load initial ram disk '%s'",
333 machine
->initrd_filename
);
338 /* Load ELF kernel and rootfs.cpio */
339 } else if (kernel_filename
&& !machine
->firmware
) {
340 ppc4xx_sdram_ddr_enable(&ppc405
->soc
.sdram
);
341 boot_from_kernel(machine
, &ppc405
->soc
.cpu
);
345 static void ppc405_machine_class_init(ObjectClass
*oc
, void *data
)
347 MachineClass
*mc
= MACHINE_CLASS(oc
);
349 mc
->desc
= "PPC405 generic machine";
350 mc
->init
= ppc405_init
;
351 mc
->default_ram_size
= 128 * MiB
;
352 mc
->default_ram_id
= "ppc405.ram";
353 mc
->deprecation_reason
= "machine is old and unmaintained";
356 static const TypeInfo ppc405_machine_type
= {
357 .name
= TYPE_PPC405_MACHINE
,
358 .parent
= TYPE_MACHINE
,
359 .instance_size
= sizeof(Ppc405MachineState
),
360 .class_init
= ppc405_machine_class_init
,
364 /*****************************************************************************/
365 /* PPC405EP reference board (IBM) */
367 * Standalone board with:
368 * - PowerPC 405EP CPU
369 * - SDRAM (0x00000000)
370 * - Flash (0xFFF80000)
371 * - SRAM (0xFFF00000)
372 * - NVRAM (0xF0000000)
373 * - FPGA (0xF0300000)
376 #define PPC405EP_NVRAM_BASE 0xF0000000
377 #define PPC405EP_FPGA_BASE 0xF0300000
378 #define PPC405EP_FLASH_BASE 0xFFF80000
380 #define TYPE_REF405EP_FPGA "ref405ep-fpga"
381 OBJECT_DECLARE_SIMPLE_TYPE(Ref405epFpgaState
, REF405EP_FPGA
);
382 struct Ref405epFpgaState
{
383 SysBusDevice parent_obj
;
391 static uint64_t ref405ep_fpga_readb(void *opaque
, hwaddr addr
, unsigned size
)
393 Ref405epFpgaState
*fpga
= opaque
;
411 static void ref405ep_fpga_writeb(void *opaque
, hwaddr addr
, uint64_t value
,
414 Ref405epFpgaState
*fpga
= opaque
;
428 static const MemoryRegionOps ref405ep_fpga_ops
= {
429 .read
= ref405ep_fpga_readb
,
430 .write
= ref405ep_fpga_writeb
,
431 .impl
.min_access_size
= 1,
432 .impl
.max_access_size
= 1,
433 .valid
.min_access_size
= 1,
434 .valid
.max_access_size
= 4,
435 .endianness
= DEVICE_BIG_ENDIAN
,
438 static void ref405ep_fpga_reset(DeviceState
*dev
)
440 Ref405epFpgaState
*fpga
= REF405EP_FPGA(dev
);
446 static void ref405ep_fpga_realize(DeviceState
*dev
, Error
**errp
)
448 Ref405epFpgaState
*s
= REF405EP_FPGA(dev
);
450 memory_region_init_io(&s
->iomem
, OBJECT(s
), &ref405ep_fpga_ops
, s
,
452 sysbus_init_mmio(SYS_BUS_DEVICE(s
), &s
->iomem
);
455 static void ref405ep_fpga_class_init(ObjectClass
*oc
, void *data
)
457 DeviceClass
*dc
= DEVICE_CLASS(oc
);
459 dc
->realize
= ref405ep_fpga_realize
;
460 device_class_set_legacy_reset(dc
, ref405ep_fpga_reset
);
461 /* Reason: only works as part of a ppc405 board */
462 dc
->user_creatable
= false;
465 static const TypeInfo ref405ep_fpga_type
= {
466 .name
= TYPE_REF405EP_FPGA
,
467 .parent
= TYPE_SYS_BUS_DEVICE
,
468 .instance_size
= sizeof(Ref405epFpgaState
),
469 .class_init
= ref405ep_fpga_class_init
,
472 static void ref405ep_init(MachineState
*machine
)
476 MemoryRegion
*sram
= g_new(MemoryRegion
, 1);
478 ppc405_init(machine
);
481 memory_region_init_ram(sram
, NULL
, "ref405ep.sram", PPC405EP_SRAM_SIZE
,
483 memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE
, sram
);
486 dev
= qdev_new(TYPE_REF405EP_FPGA
);
487 object_property_add_child(OBJECT(machine
), "fpga", OBJECT(dev
));
488 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev
), &error_fatal
);
489 sysbus_mmio_map(SYS_BUS_DEVICE(dev
), 0, PPC405EP_FPGA_BASE
);
492 dev
= qdev_new("sysbus-m48t08");
493 qdev_prop_set_int32(dev
, "base-year", 1968);
494 s
= SYS_BUS_DEVICE(dev
);
495 sysbus_realize_and_unref(s
, &error_fatal
);
496 sysbus_mmio_map(s
, 0, PPC405EP_NVRAM_BASE
);
499 static void ref405ep_class_init(ObjectClass
*oc
, void *data
)
501 MachineClass
*mc
= MACHINE_CLASS(oc
);
503 mc
->desc
= "ref405ep";
504 mc
->init
= ref405ep_init
;
507 static const TypeInfo ref405ep_type
= {
508 .name
= MACHINE_TYPE_NAME("ref405ep"),
509 .parent
= TYPE_PPC405_MACHINE
,
510 .class_init
= ref405ep_class_init
,
513 static void ppc405_machine_init(void)
515 type_register_static(&ppc405_machine_type
);
516 type_register_static(&ref405ep_type
);
517 type_register_static(&ref405ep_fpga_type
);
520 type_init(ppc405_machine_init
)