1
2
3
4
5
6
7
8
9
10
11
12
13
14#include "qemu/osdep.h"
15#include "qemu/units.h"
16#include "qemu-common.h"
17#include "qemu/error-report.h"
18#include "qapi/error.h"
19#include "hw/hw.h"
20#include "hw/boards.h"
21#include "sysemu/kvm.h"
22#include "kvm_ppc.h"
23#include "sysemu/device_tree.h"
24#include "sysemu/block-backend.h"
25#include "hw/loader.h"
26#include "elf.h"
27#include "exec/address-spaces.h"
28#include "exec/memory.h"
29#include "ppc440.h"
30#include "ppc405.h"
31#include "hw/block/flash.h"
32#include "sysemu/sysemu.h"
33#include "sysemu/qtest.h"
34#include "hw/sysbus.h"
35#include "hw/char/serial.h"
36#include "hw/i2c/ppc4xx_i2c.h"
37#include "hw/i2c/smbus.h"
38#include "hw/usb/hcd-ehci.h"
39#include "hw/ppc/fdt.h"
40
41#include <libfdt.h>
42
43#define BINARY_DEVICE_TREE_FILE "canyonlands.dtb"
44#define UBOOT_FILENAME "u-boot-sam460-20100605.bin"
45
46
47
48
49
50#define FLASH_BASE 0xfff00000
51#define FLASH_BASE_H 0x4
52#define FLASH_SIZE (1 * MiB)
53#define UBOOT_LOAD_BASE 0xfff80000
54#define UBOOT_SIZE 0x00080000
55#define UBOOT_ENTRY 0xfffffffc
56
57
58#define EPAPR_MAGIC (0x45504150)
59#define KERNEL_ADDR 0x1000000
60#define FDT_ADDR 0x1800000
61#define RAMDISK_ADDR 0x1900000
62
63
64
65
66
67
68
69
70
71
72#define CPU_FREQ 1150000000
73#define PLB_FREQ 230000000
74#define OPB_FREQ 115000000
75#define EBC_FREQ 115000000
76#define UART_FREQ 11059200
77#define SDRAM_NR_BANKS 4
78
79
80static const unsigned int ppc460ex_sdram_bank_sizes[] = {
81 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 0
82};
83
84struct boot_info {
85 uint32_t dt_base;
86 uint32_t dt_size;
87 uint32_t entry;
88};
89
90
91
92
93struct _eeprom24c0x_t {
94 uint8_t tick;
95 uint8_t address;
96 uint8_t command;
97 uint8_t ack;
98 uint8_t scl;
99 uint8_t sda;
100 uint8_t data;
101 uint8_t contents[256];
102};
103
104typedef struct _eeprom24c0x_t eeprom24c0x_t;
105
106static eeprom24c0x_t spd_eeprom = {
107 .contents = {
108 0x80, 0x08, 0xFF, 0x0D, 0x0A, 0xFF, 0x40, 0x00,
109 0x04, 0x75, 0x54, 0x00, 0x82, 0x08, 0x00, 0x01,
110 0x8F, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x14, 0x0F, 0x14, 0x2D, 0xFF,
112 0x15, 0x08, 0x15, 0x08, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xD0,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xF4,
124 },
125};
126
127static void generate_eeprom_spd(uint8_t *eeprom, ram_addr_t ram_size)
128{
129 enum { SDR = 0x4, DDR1 = 0x7, DDR2 = 0x8 } type;
130 uint8_t *spd = spd_eeprom.contents;
131 uint8_t nbanks = 0;
132 uint16_t density = 0;
133 int i;
134
135
136 ram_size /= MiB;
137
138 while ((ram_size >= 4) && (nbanks <= 2)) {
139 int sz_log2 = MIN(31 - clz32(ram_size), 14);
140 nbanks++;
141 density |= 1 << (sz_log2 - 2);
142 ram_size -= 1 << sz_log2;
143 }
144
145
146 if ((nbanks == 1) && (density > 1)) {
147 nbanks++;
148 density >>= 1;
149 }
150
151 if (density & 0xff00) {
152 density = (density & 0xe0) | ((density >> 8) & 0x1f);
153 type = DDR2;
154 } else if (!(density & 0x1f)) {
155 type = DDR2;
156 } else {
157 type = SDR;
158 }
159
160 if (ram_size) {
161 warn_report("SPD cannot represent final " RAM_ADDR_FMT "MB"
162 " of SDRAM", ram_size);
163 }
164
165
166 spd[2] = type;
167 spd[5] = nbanks;
168 spd[31] = density;
169
170
171 spd[9] = 0x10;
172 spd[18] = 0x20;
173 spd[23] = 0x10;
174 spd[25] = 0x10;
175
176
177 spd[63] = 0;
178 for (i = 0; i < 63; i++) {
179 spd[63] += spd[i];
180 }
181
182
183 memcpy(eeprom, spd, sizeof(spd_eeprom.contents));
184}
185
186static void generate_eeprom_serial(uint8_t *eeprom)
187{
188 int i, pos = 0;
189 uint8_t mac[6] = { 0x00 };
190 uint8_t sn[5] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
191
192
193 eeprom[pos++] = 0x01;
194
195
196 eeprom[pos++] = 0x02;
197
198
199 eeprom[pos++] = 0x01;
200 eeprom[pos++] = 0x06;
201 memcpy(&eeprom[pos], mac, sizeof(mac));
202 pos += sizeof(mac);
203
204
205 eeprom[pos++] = 0x02;
206 eeprom[pos++] = 0x05;
207 memcpy(&eeprom[pos], sn, sizeof(sn));
208 pos += sizeof(sn);
209
210
211 eeprom[pos] = 0;
212 for (i = 0; i < pos; i++) {
213 eeprom[pos] += eeprom[i];
214 }
215}
216
217
218
219static int sam460ex_load_uboot(void)
220{
221 DriveInfo *dinfo;
222 BlockBackend *blk = NULL;
223 hwaddr base = FLASH_BASE | ((hwaddr)FLASH_BASE_H << 32);
224 long bios_size = FLASH_SIZE;
225 int fl_sectors;
226
227 dinfo = drive_get(IF_PFLASH, 0, 0);
228 if (dinfo) {
229 blk = blk_by_legacy_dinfo(dinfo);
230 bios_size = blk_getlength(blk);
231 }
232 fl_sectors = (bios_size + 65535) >> 16;
233
234 if (!pflash_cfi01_register(base, NULL, "sam460ex.flash", bios_size,
235 blk, 64 * KiB, fl_sectors,
236 1, 0x89, 0x18, 0x0000, 0x0, 1)) {
237 error_report("Error registering flash memory");
238
239 exit(1);
240 }
241
242 if (!blk) {
243
244
245 base = UBOOT_LOAD_BASE | ((hwaddr)FLASH_BASE_H << 32);
246 rom_add_file_fixed(UBOOT_FILENAME, base, -1);
247 }
248
249 return 0;
250}
251
252static int sam460ex_load_device_tree(hwaddr addr,
253 uint32_t ramsize,
254 hwaddr initrd_base,
255 hwaddr initrd_size,
256 const char *kernel_cmdline)
257{
258 uint32_t mem_reg_property[] = { 0, 0, cpu_to_be32(ramsize) };
259 char *filename;
260 int fdt_size;
261 void *fdt;
262 uint32_t tb_freq = CPU_FREQ;
263 uint32_t clock_freq = CPU_FREQ;
264 int offset;
265
266 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
267 if (!filename) {
268 error_report("Couldn't find dtb file `%s'", BINARY_DEVICE_TREE_FILE);
269 exit(1);
270 }
271 fdt = load_device_tree(filename, &fdt_size);
272 if (!fdt) {
273 error_report("Couldn't load dtb file `%s'", filename);
274 g_free(filename);
275 exit(1);
276 }
277 g_free(filename);
278
279
280
281 qemu_fdt_setprop(fdt, "/memory", "reg", mem_reg_property,
282 sizeof(mem_reg_property));
283
284
285 qemu_fdt_add_subnode(fdt, "/chosen");
286
287 qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", initrd_base);
288
289 qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
290 (initrd_base + initrd_size));
291
292 qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", kernel_cmdline);
293
294
295
296
297 if (kvm_enabled()) {
298 tb_freq = kvmppc_get_tbfreq();
299 clock_freq = kvmppc_get_clockfreq();
300 }
301
302 qemu_fdt_setprop_cell(fdt, "/cpus/cpu@0", "clock-frequency",
303 clock_freq);
304 qemu_fdt_setprop_cell(fdt, "/cpus/cpu@0", "timebase-frequency",
305 tb_freq);
306
307
308 offset = fdt_path_offset(fdt, "/cpm");
309 if (offset >= 0) {
310 _FDT(fdt_nop_node(fdt, offset));
311 }
312
313
314 offset = fdt_node_offset_by_compatible(fdt, -1, "ns16550");
315 while (offset >= 0) {
316 _FDT(fdt_setprop_cell(fdt, offset, "clock-frequency", UART_FREQ));
317 offset = fdt_node_offset_by_compatible(fdt, offset, "ns16550");
318 }
319
320
321 qemu_fdt_setprop_cell(fdt, "/plb", "clock-frequency",
322 PLB_FREQ);
323 qemu_fdt_setprop_cell(fdt, "/plb/opb", "clock-frequency",
324 OPB_FREQ);
325 qemu_fdt_setprop_cell(fdt, "/plb/opb/ebc", "clock-frequency",
326 EBC_FREQ);
327
328 rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
329 g_free(fdt);
330
331 return fdt_size;
332}
333
334
335static void mmubooke_create_initial_mapping_uboot(CPUPPCState *env)
336{
337 ppcemb_tlb_t *tlb = &env->tlb.tlbe[0];
338
339
340
341
342
343 tlb->attr = 0;
344 tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4);
345 tlb->size = 0x10000000;
346 tlb->EPN = 0xf0000000 & TARGET_PAGE_MASK;
347 tlb->RPN = (0xf0000000 & TARGET_PAGE_MASK) | 0x4;
348 tlb->PID = 0;
349}
350
351
352static void mmubooke_create_initial_mapping(CPUPPCState *env,
353 target_ulong va,
354 hwaddr pa)
355{
356 ppcemb_tlb_t *tlb = &env->tlb.tlbe[0];
357
358 tlb->attr = 0;
359 tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4);
360 tlb->size = 1 << 31;
361 tlb->EPN = va & TARGET_PAGE_MASK;
362 tlb->RPN = pa & TARGET_PAGE_MASK;
363 tlb->PID = 0;
364}
365
366static void main_cpu_reset(void *opaque)
367{
368 PowerPCCPU *cpu = opaque;
369 CPUPPCState *env = &cpu->env;
370 struct boot_info *bi = env->load_info;
371
372 cpu_reset(CPU(cpu));
373
374
375 if (bi->entry != UBOOT_ENTRY) {
376 env->gpr[1] = (16 * MiB) - 8;
377 env->gpr[3] = FDT_ADDR;
378 env->nip = bi->entry;
379
380
381 mmubooke_create_initial_mapping(env, 0, 0);
382 env->gpr[6] = tswap32(EPAPR_MAGIC);
383 env->gpr[7] = (16 * MiB) - 8;
384
385 } else {
386 env->nip = UBOOT_ENTRY;
387 mmubooke_create_initial_mapping_uboot(env);
388 }
389}
390
391static void sam460ex_init(MachineState *machine)
392{
393 MemoryRegion *address_space_mem = get_system_memory();
394 MemoryRegion *isa = g_new(MemoryRegion, 1);
395 MemoryRegion *ram_memories = g_new(MemoryRegion, SDRAM_NR_BANKS);
396 hwaddr ram_bases[SDRAM_NR_BANKS];
397 hwaddr ram_sizes[SDRAM_NR_BANKS];
398 MemoryRegion *l2cache_ram = g_new(MemoryRegion, 1);
399 qemu_irq *irqs, *uic[4];
400 PCIBus *pci_bus;
401 PowerPCCPU *cpu;
402 CPUPPCState *env;
403 PPC4xxI2CState *i2c[2];
404 hwaddr entry = UBOOT_ENTRY;
405 hwaddr loadaddr = 0;
406 target_long initrd_size = 0;
407 DeviceState *dev;
408 SysBusDevice *sbdev;
409 int success;
410 int i;
411 struct boot_info *boot_info;
412 const size_t smbus_eeprom_size = 8 * 256;
413 uint8_t *smbus_eeprom_buf = g_malloc0(smbus_eeprom_size);
414
415 cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
416 env = &cpu->env;
417 if (env->mmu_model != POWERPC_MMU_BOOKE) {
418 error_report("Only MMU model BookE is supported by this machine.");
419 exit(1);
420 }
421
422 qemu_register_reset(main_cpu_reset, cpu);
423 boot_info = g_malloc0(sizeof(*boot_info));
424 env->load_info = boot_info;
425
426 ppc_booke_timers_init(cpu, CPU_FREQ, 0);
427 ppc_dcr_init(env, NULL, NULL);
428
429
430 ppc4xx_plb_init(env);
431
432
433 irqs = g_malloc0(sizeof(*irqs) * PPCUIC_OUTPUT_NB);
434 irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
435 irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];
436 uic[0] = ppcuic_init(env, irqs, 0xc0, 0, 1);
437 uic[1] = ppcuic_init(env, &uic[0][30], 0xd0, 0, 1);
438 uic[2] = ppcuic_init(env, &uic[0][10], 0xe0, 0, 1);
439 uic[3] = ppcuic_init(env, &uic[0][16], 0xf0, 0, 1);
440
441
442 memset(ram_bases, 0, sizeof(ram_bases));
443 memset(ram_sizes, 0, sizeof(ram_sizes));
444
445
446 machine->ram_size = ppc4xx_sdram_adjust(machine->ram_size, 1,
447 ram_memories, ram_bases, ram_sizes,
448 ppc460ex_sdram_bank_sizes);
449
450
451 ppc440_sdram_init(env, SDRAM_NR_BANKS, ram_memories,
452 ram_bases, ram_sizes, 1);
453
454
455 for (i = 0; i < SDRAM_NR_BANKS; i++) {
456 generate_eeprom_spd(&smbus_eeprom_buf[i * 256], ram_sizes[i]);
457 }
458 generate_eeprom_serial(&smbus_eeprom_buf[4 * 256]);
459 generate_eeprom_serial(&smbus_eeprom_buf[6 * 256]);
460
461
462 dev = sysbus_create_simple(TYPE_PPC4xx_I2C, 0x4ef600700, uic[0][2]);
463 i2c[0] = PPC4xx_I2C(dev);
464 object_property_set_bool(OBJECT(dev), true, "realized", NULL);
465 smbus_eeprom_init(i2c[0]->bus, 8, smbus_eeprom_buf, smbus_eeprom_size);
466 g_free(smbus_eeprom_buf);
467 i2c_create_slave(i2c[0]->bus, "m41t80", 0x68);
468
469 dev = sysbus_create_simple(TYPE_PPC4xx_I2C, 0x4ef600800, uic[0][3]);
470 i2c[1] = PPC4xx_I2C(dev);
471
472
473 ppc405_ebc_init(env);
474
475
476 ppc4xx_cpr_init(env);
477
478
479 ppc4xx_ahb_init(env);
480
481
482 ppc4xx_sdr_init(env);
483
484
485 ppc4xx_mal_init(env, 4, 16, &uic[2][3]);
486
487
488 ppc4xx_dma_init(env, 0x200);
489
490
491 ppc4xx_l2sram_init(env);
492
493 memory_region_init_ram(l2cache_ram, NULL, "ppc440.l2cache_ram", 256 * KiB,
494 &error_abort);
495 memory_region_add_subregion(address_space_mem, 0x400000000LL, l2cache_ram);
496
497
498 sysbus_create_simple(TYPE_PPC4xx_EHCI, 0x4bffd0400, uic[2][29]);
499 dev = qdev_create(NULL, "sysbus-ohci");
500 qdev_prop_set_string(dev, "masterbus", "usb-bus.0");
501 qdev_prop_set_uint32(dev, "num-ports", 6);
502 qdev_init_nofail(dev);
503 sbdev = SYS_BUS_DEVICE(dev);
504 sysbus_mmio_map(sbdev, 0, 0x4bffd0000);
505 sysbus_connect_irq(sbdev, 0, uic[2][30]);
506 usb_create_simple(usb_bus_find(-1), "usb-kbd");
507 usb_create_simple(usb_bus_find(-1), "usb-mouse");
508
509
510 ppc460ex_pcie_init(env);
511
512 dev = sysbus_create_simple("ppc440-pcix-host", 0xc0ec00000, uic[1][0]);
513 pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
514 if (!pci_bus) {
515 error_report("couldn't create PCI controller!");
516 exit(1);
517 }
518 memory_region_init_alias(isa, NULL, "isa_mmio", get_system_io(),
519 0, 0x10000);
520 memory_region_add_subregion(get_system_memory(), 0xc08000000, isa);
521
522
523 pci_create_simple(pci_bus, PCI_DEVFN(6, 0), "sm501");
524
525
526
527 if (defaults_enabled()) {
528 pci_create_simple(pci_bus, -1, "sii3112");
529 }
530
531
532
533 if (serial_hd(0) != NULL) {
534 serial_mm_init(address_space_mem, 0x4ef600300, 0, uic[1][1],
535 PPC_SERIAL_MM_BAUDBASE, serial_hd(0),
536 DEVICE_BIG_ENDIAN);
537 }
538 if (serial_hd(1) != NULL) {
539 serial_mm_init(address_space_mem, 0x4ef600400, 0, uic[0][1],
540 PPC_SERIAL_MM_BAUDBASE, serial_hd(1),
541 DEVICE_BIG_ENDIAN);
542 }
543
544
545 if (!machine->kernel_filename) {
546 success = sam460ex_load_uboot();
547 if (success < 0) {
548 error_report("could not load firmware");
549 exit(1);
550 }
551 }
552
553
554 if (machine->kernel_filename) {
555 success = load_uimage(machine->kernel_filename, &entry, &loadaddr,
556 NULL, NULL, NULL);
557 if (success < 0) {
558 uint64_t elf_entry, elf_lowaddr;
559
560 success = load_elf(machine->kernel_filename, NULL, NULL, &elf_entry,
561 &elf_lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0);
562 entry = elf_entry;
563 loadaddr = elf_lowaddr;
564 }
565
566 if (success < 0) {
567 error_report("could not load kernel '%s'",
568 machine->kernel_filename);
569 exit(1);
570 }
571 }
572
573
574 if (machine->initrd_filename) {
575 initrd_size = load_image_targphys(machine->initrd_filename,
576 RAMDISK_ADDR,
577 machine->ram_size - RAMDISK_ADDR);
578 if (initrd_size < 0) {
579 error_report("could not load ram disk '%s' at %x",
580 machine->initrd_filename, RAMDISK_ADDR);
581 exit(1);
582 }
583 }
584
585
586 if (machine->kernel_filename) {
587 int dt_size;
588
589 dt_size = sam460ex_load_device_tree(FDT_ADDR, machine->ram_size,
590 RAMDISK_ADDR, initrd_size,
591 machine->kernel_cmdline);
592
593 boot_info->dt_base = FDT_ADDR;
594 boot_info->dt_size = dt_size;
595 }
596
597 boot_info->entry = entry;
598}
599
600static void sam460ex_machine_init(MachineClass *mc)
601{
602 mc->desc = "aCube Sam460ex";
603 mc->init = sam460ex_init;
604 mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("460exb");
605 mc->default_ram_size = 512 * MiB;
606}
607
608DEFINE_MACHINE("sam460ex", sam460ex_machine_init)
609