32
32
#include "sysemu.h"
33
33
#include "devices.h"
34
34
#include "boards.h"
35
#include "device_tree.h"
36
35
#include "xilinx.h"
39
36
#include "blockdev.h"
41
38
#include "exec-memory.h"
40
#include "microblaze_boot.h"
43
41
#include "microblaze_pic_cpu.h"
44
42
#include "xilinx_axidma.h"
46
44
#define LMB_BRAM_SIZE (128 * 1024)
47
45
#define FLASH_SIZE (32 * 1024 * 1024)
51
uint32_t bootstrap_pc;
56
static void main_cpu_reset(void *opaque)
58
CPUState *env = opaque;
61
env->regs[5] = boot_info.cmdline;
62
env->regs[7] = boot_info.fdt;
63
env->sregs[SR_PC] = boot_info.bootstrap_pc;
47
#define BINARY_DEVICE_TREE_FILE "petalogix-ml605.dtb"
49
#define MEMORY_BASEADDR 0x50000000
50
#define FLASH_BASEADDR 0x86000000
51
#define INTC_BASEADDR 0x81800000
52
#define TIMER_BASEADDR 0x83c00000
53
#define UART16550_BASEADDR 0x83e00000
54
#define AXIENET_BASEADDR 0x82780000
55
#define AXIDMA_BASEADDR 0x84600000
57
static void machine_cpu_reset(MicroBlazeCPU *cpu)
59
CPUMBState *env = &cpu->env;
64
61
env->pvr.regs[10] = 0x0e000000; /* virtex 6 */
65
62
/* setup pvr to match kernel setting */
66
63
env->pvr.regs[5] |= PVR5_DCACHE_WRITEBACK_MASK;
71
68
env->pvr.regs[5] = 0xc56be000;
74
#define BINARY_DEVICE_TREE_FILE "petalogix-ml605.dtb"
75
static int petalogix_load_device_tree(target_phys_addr_t addr,
77
target_phys_addr_t initrd_base,
78
target_phys_addr_t initrd_size,
79
const char *kernel_cmdline)
87
/* Try the local "mb.dtb" override. */
88
fdt = load_device_tree("mb.dtb", &fdt_size);
90
path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
92
fdt = load_device_tree(path, &fdt_size);
100
r = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs", kernel_cmdline);
102
fprintf(stderr, "couldn't set /chosen/bootargs\n");
104
cpu_physical_memory_write(addr, (void *)fdt, fdt_size);
106
/* We lack libfdt so we cannot manipulate the fdt. Just pass on the blob
108
fdt_size = load_image_targphys("mb.dtb", addr, 0x10000);
110
path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
112
fdt_size = load_image_targphys(path, addr, 0x10000);
117
if (kernel_cmdline) {
119
"Warning: missing libfdt, cannot pass cmdline to kernel!\n");
125
static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
127
return addr - 0x30000000LL;
130
#define MEMORY_BASEADDR 0x50000000
131
#define FLASH_BASEADDR 0x86000000
132
#define INTC_BASEADDR 0x81800000
133
#define TIMER_BASEADDR 0x83c00000
134
#define UART16550_BASEADDR 0x83e00000
135
#define AXIENET_BASEADDR 0x82780000
136
#define AXIDMA_BASEADDR 0x84600000
139
72
petalogix_ml605_init(ram_addr_t ram_size,
140
73
const char *boot_device,
157
90
if (cpu_model == NULL) {
158
91
cpu_model = "microblaze";
160
env = cpu_init(cpu_model);
162
qemu_register_reset(main_cpu_reset, env);
93
cpu = cpu_mb_init(cpu_model);
164
96
/* Attach emulated BRAM through the LMB. */
165
97
memory_region_init_ram(phys_lmb_bram, "petalogix_ml605.lmb_bram",
191
123
irq[5], 115200, serial_hds[0], DEVICE_LITTLE_ENDIAN);
193
125
/* 2 timers at irq 2 @ 100 Mhz. */
194
xilinx_timer_create(TIMER_BASEADDR, irq[2], 2, 100 * 1000000);
126
xilinx_timer_create(TIMER_BASEADDR, irq[2], 0, 100 * 1000000);
196
128
/* axi ethernet and dma initialization. TODO: Dynamically connect them. */
203
135
irq[1], irq[0], 100 * 1000000);
206
if (kernel_filename) {
207
uint64_t entry, low, high;
211
#ifdef TARGET_WORDS_BIGENDIAN
215
/* Boots a kernel elf binary. */
216
kernel_size = load_elf(kernel_filename, NULL, NULL,
218
big_endian, ELF_MACHINE, 0);
220
if (base32 == 0xc0000000) {
221
kernel_size = load_elf(kernel_filename, translate_kernel_address,
222
NULL, &entry, NULL, NULL,
223
big_endian, ELF_MACHINE, 0);
225
/* Always boot into physical ram. */
226
boot_info.bootstrap_pc = ddr_base + (entry & 0x0fffffff);
228
/* If it wasn't an ELF image, try an u-boot image. */
229
if (kernel_size < 0) {
230
target_phys_addr_t uentry, loadaddr;
232
kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0);
233
boot_info.bootstrap_pc = uentry;
234
high = (loadaddr + kernel_size + 3) & ~3;
237
/* Not an ELF image nor an u-boot image, try a RAW image. */
238
if (kernel_size < 0) {
239
kernel_size = load_image_targphys(kernel_filename, ddr_base,
241
boot_info.bootstrap_pc = ddr_base;
242
high = (ddr_base + kernel_size + 3) & ~3;
245
boot_info.cmdline = high + 4096;
246
if (kernel_cmdline && strlen(kernel_cmdline)) {
247
pstrcpy_targphys("cmdline", boot_info.cmdline, 256, kernel_cmdline);
249
/* Provide a device-tree. */
250
boot_info.fdt = boot_info.cmdline + 4096;
251
petalogix_load_device_tree(boot_info.fdt, ram_size,
138
microblaze_load_kernel(cpu, ddr_base, ram_size, BINARY_DEVICE_TREE_FILE,
257
143
static QEMUMachine petalogix_ml605_machine = {