|
|
1.1 root 1: /*
2: * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
3: *
4: * Copyright (c) 2004-2007 Fabrice Bellard
5: * Copyright (c) 2007 Jocelyn Mayer
6: * Copyright (c) 2010 David Gibson, IBM Corporation.
7: *
8: * Permission is hereby granted, free of charge, to any person obtaining a copy
9: * of this software and associated documentation files (the "Software"), to deal
10: * in the Software without restriction, including without limitation the rights
11: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12: * copies of the Software, and to permit persons to whom the Software is
13: * furnished to do so, subject to the following conditions:
14: *
15: * The above copyright notice and this permission notice shall be included in
16: * all copies or substantial portions of the Software.
17: *
18: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24: * THE SOFTWARE.
25: *
26: */
27: #include "sysemu.h"
28: #include "hw.h"
29: #include "elf.h"
30: #include "net.h"
31: #include "blockdev.h"
1.1.1.2 ! root 32: #include "cpus.h"
! 33: #include "kvm.h"
! 34: #include "kvm_ppc.h"
1.1 root 35:
36: #include "hw/boards.h"
37: #include "hw/ppc.h"
38: #include "hw/loader.h"
39:
40: #include "hw/spapr.h"
41: #include "hw/spapr_vio.h"
1.1.1.2 ! root 42: #include "hw/spapr_pci.h"
1.1 root 43: #include "hw/xics.h"
44:
1.1.1.2 ! root 45: #include "kvm.h"
! 46: #include "kvm_ppc.h"
! 47: #include "pci.h"
! 48:
! 49: #include "exec-memory.h"
! 50:
1.1 root 51: #include <libfdt.h>
52:
53: #define KERNEL_LOAD_ADDR 0x00000000
54: #define INITRD_LOAD_ADDR 0x02800000
55: #define FDT_MAX_SIZE 0x10000
56: #define RTAS_MAX_SIZE 0x10000
57: #define FW_MAX_SIZE 0x400000
58: #define FW_FILE_NAME "slof.bin"
59:
1.1.1.2 ! root 60: #define MIN_RMA_SLOF 128UL
1.1 root 61:
62: #define TIMEBASE_FREQ 512000000ULL
63:
64: #define MAX_CPUS 256
65: #define XICS_IRQS 1024
66:
1.1.1.2 ! root 67: #define SPAPR_PCI_BUID 0x800000020000001ULL
! 68: #define SPAPR_PCI_MEM_WIN_ADDR (0x10000000000ULL + 0xA0000000)
! 69: #define SPAPR_PCI_MEM_WIN_SIZE 0x20000000
! 70: #define SPAPR_PCI_IO_WIN_ADDR (0x10000000000ULL + 0x80000000)
! 71:
! 72: #define PHANDLE_XICP 0x00001111
! 73:
1.1 root 74: sPAPREnvironment *spapr;
75:
1.1.1.2 ! root 76: qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num)
! 77: {
! 78: uint32_t irq;
! 79: qemu_irq qirq;
! 80:
! 81: if (hint) {
! 82: irq = hint;
! 83: /* FIXME: we should probably check for collisions somehow */
! 84: } else {
! 85: irq = spapr->next_irq++;
! 86: }
! 87:
! 88: qirq = xics_find_qirq(spapr->icp, irq);
! 89: if (!qirq) {
! 90: return NULL;
! 91: }
! 92:
! 93: if (irq_num) {
! 94: *irq_num = irq;
! 95: }
! 96:
! 97: return qirq;
! 98: }
! 99:
1.1 root 100: static void *spapr_create_fdt_skel(const char *cpu_model,
1.1.1.2 ! root 101: target_phys_addr_t rma_size,
1.1 root 102: target_phys_addr_t initrd_base,
103: target_phys_addr_t initrd_size,
104: const char *boot_device,
105: const char *kernel_cmdline,
106: long hash_shift)
107: {
108: void *fdt;
109: CPUState *env;
1.1.1.2 ! root 110: uint64_t mem_reg_property_rma[] = { 0, cpu_to_be64(rma_size) };
! 111: uint64_t mem_reg_property_nonrma[] = { cpu_to_be64(rma_size),
! 112: cpu_to_be64(ram_size - rma_size) };
1.1 root 113: uint32_t start_prop = cpu_to_be32(initrd_base);
114: uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
115: uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
116: char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
1.1.1.2 ! root 117: "\0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk";
1.1 root 118: uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
119: int i;
120: char *modelname;
1.1.1.2 ! root 121: int smt = kvmppc_smt_threads();
1.1 root 122:
123: #define _FDT(exp) \
124: do { \
125: int ret = (exp); \
126: if (ret < 0) { \
127: fprintf(stderr, "qemu: error creating device tree: %s: %s\n", \
128: #exp, fdt_strerror(ret)); \
129: exit(1); \
130: } \
131: } while (0)
132:
1.1.1.2 ! root 133: fdt = g_malloc0(FDT_MAX_SIZE);
1.1 root 134: _FDT((fdt_create(fdt, FDT_MAX_SIZE)));
135:
136: _FDT((fdt_finish_reservemap(fdt)));
137:
138: /* Root node */
139: _FDT((fdt_begin_node(fdt, "")));
140: _FDT((fdt_property_string(fdt, "device_type", "chrp")));
141: _FDT((fdt_property_string(fdt, "model", "IBM pSeries (emulated by qemu)")));
142:
143: _FDT((fdt_property_cell(fdt, "#address-cells", 0x2)));
144: _FDT((fdt_property_cell(fdt, "#size-cells", 0x2)));
145:
146: /* /chosen */
147: _FDT((fdt_begin_node(fdt, "chosen")));
148:
149: _FDT((fdt_property_string(fdt, "bootargs", kernel_cmdline)));
150: _FDT((fdt_property(fdt, "linux,initrd-start",
151: &start_prop, sizeof(start_prop))));
152: _FDT((fdt_property(fdt, "linux,initrd-end",
153: &end_prop, sizeof(end_prop))));
154: _FDT((fdt_property_string(fdt, "qemu,boot-device", boot_device)));
155:
1.1.1.2 ! root 156: /*
! 157: * Because we don't always invoke any firmware, we can't rely on
! 158: * that to do BAR allocation. Long term, we should probably do
! 159: * that ourselves, but for now, this setting (plus advertising the
! 160: * current BARs as 0) causes sufficiently recent kernels to to the
! 161: * BAR assignment themselves */
! 162: _FDT((fdt_property_cell(fdt, "linux,pci-probe-only", 0)));
! 163:
1.1 root 164: _FDT((fdt_end_node(fdt)));
165:
1.1.1.2 ! root 166: /* memory node(s) */
1.1 root 167: _FDT((fdt_begin_node(fdt, "memory@0")));
168:
169: _FDT((fdt_property_string(fdt, "device_type", "memory")));
1.1.1.2 ! root 170: _FDT((fdt_property(fdt, "reg", mem_reg_property_rma,
! 171: sizeof(mem_reg_property_rma))));
1.1 root 172: _FDT((fdt_end_node(fdt)));
173:
1.1.1.2 ! root 174: if (ram_size > rma_size) {
! 175: char mem_name[32];
! 176:
! 177: sprintf(mem_name, "memory@%" PRIx64, (uint64_t)rma_size);
! 178: _FDT((fdt_begin_node(fdt, mem_name)));
! 179: _FDT((fdt_property_string(fdt, "device_type", "memory")));
! 180: _FDT((fdt_property(fdt, "reg", mem_reg_property_nonrma,
! 181: sizeof(mem_reg_property_nonrma))));
! 182: _FDT((fdt_end_node(fdt)));
! 183: }
! 184:
1.1 root 185: /* cpus */
186: _FDT((fdt_begin_node(fdt, "cpus")));
187:
188: _FDT((fdt_property_cell(fdt, "#address-cells", 0x1)));
189: _FDT((fdt_property_cell(fdt, "#size-cells", 0x0)));
190:
1.1.1.2 ! root 191: modelname = g_strdup(cpu_model);
1.1 root 192:
193: for (i = 0; i < strlen(modelname); i++) {
194: modelname[i] = toupper(modelname[i]);
195: }
196:
197: for (env = first_cpu; env != NULL; env = env->next_cpu) {
198: int index = env->cpu_index;
1.1.1.2 ! root 199: uint32_t servers_prop[smp_threads];
! 200: uint32_t gservers_prop[smp_threads * 2];
1.1 root 201: char *nodename;
202: uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
203: 0xffffffff, 0xffffffff};
1.1.1.2 ! root 204: uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ;
! 205: uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;
! 206:
! 207: if ((index % smt) != 0) {
! 208: continue;
! 209: }
1.1 root 210:
211: if (asprintf(&nodename, "%s@%x", modelname, index) < 0) {
212: fprintf(stderr, "Allocation failure\n");
213: exit(1);
214: }
215:
216: _FDT((fdt_begin_node(fdt, nodename)));
217:
218: free(nodename);
219:
220: _FDT((fdt_property_cell(fdt, "reg", index)));
221: _FDT((fdt_property_string(fdt, "device_type", "cpu")));
222:
223: _FDT((fdt_property_cell(fdt, "cpu-version", env->spr[SPR_PVR])));
224: _FDT((fdt_property_cell(fdt, "dcache-block-size",
225: env->dcache_line_size)));
226: _FDT((fdt_property_cell(fdt, "icache-block-size",
227: env->icache_line_size)));
1.1.1.2 ! root 228: _FDT((fdt_property_cell(fdt, "timebase-frequency", tbfreq)));
! 229: _FDT((fdt_property_cell(fdt, "clock-frequency", cpufreq)));
1.1 root 230: _FDT((fdt_property_cell(fdt, "ibm,slb-size", env->slb_nr)));
231: _FDT((fdt_property(fdt, "ibm,pft-size",
232: pft_size_prop, sizeof(pft_size_prop))));
233: _FDT((fdt_property_string(fdt, "status", "okay")));
234: _FDT((fdt_property(fdt, "64-bit", NULL, 0)));
1.1.1.2 ! root 235:
! 236: /* Build interrupt servers and gservers properties */
! 237: for (i = 0; i < smp_threads; i++) {
! 238: servers_prop[i] = cpu_to_be32(index + i);
! 239: /* Hack, direct the group queues back to cpu 0 */
! 240: gservers_prop[i*2] = cpu_to_be32(index + i);
! 241: gservers_prop[i*2 + 1] = 0;
! 242: }
! 243: _FDT((fdt_property(fdt, "ibm,ppc-interrupt-server#s",
! 244: servers_prop, sizeof(servers_prop))));
1.1 root 245: _FDT((fdt_property(fdt, "ibm,ppc-interrupt-gserver#s",
1.1.1.2 ! root 246: gservers_prop, sizeof(gservers_prop))));
1.1 root 247:
248: if (env->mmu_model & POWERPC_MMU_1TSEG) {
249: _FDT((fdt_property(fdt, "ibm,processor-segment-sizes",
250: segs, sizeof(segs))));
251: }
252:
1.1.1.2 ! root 253: /* Advertise VMX/VSX (vector extensions) if available
! 254: * 0 / no property == no vector extensions
! 255: * 1 == VMX / Altivec available
! 256: * 2 == VSX available */
! 257: if (env->insns_flags & PPC_ALTIVEC) {
! 258: uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1;
! 259:
! 260: _FDT((fdt_property_cell(fdt, "ibm,vmx", vmx)));
! 261: }
! 262:
! 263: /* Advertise DFP (Decimal Floating Point) if available
! 264: * 0 / no property == no DFP
! 265: * 1 == DFP available */
! 266: if (env->insns_flags2 & PPC2_DFP) {
! 267: _FDT((fdt_property_cell(fdt, "ibm,dfp", 1)));
! 268: }
! 269:
1.1 root 270: _FDT((fdt_end_node(fdt)));
271: }
272:
1.1.1.2 ! root 273: g_free(modelname);
1.1 root 274:
275: _FDT((fdt_end_node(fdt)));
276:
277: /* RTAS */
278: _FDT((fdt_begin_node(fdt, "rtas")));
279:
280: _FDT((fdt_property(fdt, "ibm,hypertas-functions", hypertas_prop,
281: sizeof(hypertas_prop))));
282:
283: _FDT((fdt_end_node(fdt)));
284:
285: /* interrupt controller */
1.1.1.2 ! root 286: _FDT((fdt_begin_node(fdt, "interrupt-controller")));
1.1 root 287:
288: _FDT((fdt_property_string(fdt, "device_type",
289: "PowerPC-External-Interrupt-Presentation")));
290: _FDT((fdt_property_string(fdt, "compatible", "IBM,ppc-xicp")));
291: _FDT((fdt_property(fdt, "interrupt-controller", NULL, 0)));
292: _FDT((fdt_property(fdt, "ibm,interrupt-server-ranges",
293: interrupt_server_ranges_prop,
294: sizeof(interrupt_server_ranges_prop))));
1.1.1.2 ! root 295: _FDT((fdt_property_cell(fdt, "#interrupt-cells", 2)));
! 296: _FDT((fdt_property_cell(fdt, "linux,phandle", PHANDLE_XICP)));
! 297: _FDT((fdt_property_cell(fdt, "phandle", PHANDLE_XICP)));
1.1 root 298:
299: _FDT((fdt_end_node(fdt)));
300:
301: /* vdevice */
302: _FDT((fdt_begin_node(fdt, "vdevice")));
303:
304: _FDT((fdt_property_string(fdt, "device_type", "vdevice")));
305: _FDT((fdt_property_string(fdt, "compatible", "IBM,vdevice")));
306: _FDT((fdt_property_cell(fdt, "#address-cells", 0x1)));
307: _FDT((fdt_property_cell(fdt, "#size-cells", 0x0)));
308: _FDT((fdt_property_cell(fdt, "#interrupt-cells", 0x2)));
309: _FDT((fdt_property(fdt, "interrupt-controller", NULL, 0)));
310:
311: _FDT((fdt_end_node(fdt)));
312:
313: _FDT((fdt_end_node(fdt))); /* close root node */
314: _FDT((fdt_finish(fdt)));
315:
316: return fdt;
317: }
318:
319: static void spapr_finalize_fdt(sPAPREnvironment *spapr,
320: target_phys_addr_t fdt_addr,
321: target_phys_addr_t rtas_addr,
322: target_phys_addr_t rtas_size)
323: {
324: int ret;
325: void *fdt;
1.1.1.2 ! root 326: sPAPRPHBState *phb;
1.1 root 327:
1.1.1.2 ! root 328: fdt = g_malloc(FDT_MAX_SIZE);
1.1 root 329:
330: /* open out the base tree into a temp buffer for the final tweaks */
331: _FDT((fdt_open_into(spapr->fdt_skel, fdt, FDT_MAX_SIZE)));
332:
333: ret = spapr_populate_vdevice(spapr->vio_bus, fdt);
334: if (ret < 0) {
335: fprintf(stderr, "couldn't setup vio devices in fdt\n");
336: exit(1);
337: }
338:
1.1.1.2 ! root 339: QLIST_FOREACH(phb, &spapr->phbs, list) {
! 340: ret = spapr_populate_pci_devices(phb, PHANDLE_XICP, fdt);
! 341: }
! 342:
! 343: if (ret < 0) {
! 344: fprintf(stderr, "couldn't setup PCI devices in fdt\n");
! 345: exit(1);
! 346: }
! 347:
1.1 root 348: /* RTAS */
349: ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
350: if (ret < 0) {
351: fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
352: }
353:
1.1.1.2 ! root 354: spapr_populate_chosen_stdout(fdt, spapr->vio_bus);
! 355:
1.1 root 356: _FDT((fdt_pack(fdt)));
357:
358: cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
359:
1.1.1.2 ! root 360: g_free(fdt);
1.1 root 361: }
362:
363: static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
364: {
365: return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR;
366: }
367:
368: static void emulate_spapr_hypercall(CPUState *env)
369: {
370: env->gpr[3] = spapr_hypercall(env, env->gpr[3], &env->gpr[4]);
371: }
372:
373: static void spapr_reset(void *opaque)
374: {
375: sPAPREnvironment *spapr = (sPAPREnvironment *)opaque;
376:
377: fprintf(stderr, "sPAPR reset\n");
378:
379: /* flush out the hash table */
380: memset(spapr->htab, 0, spapr->htab_size);
381:
382: /* Load the fdt */
383: spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
384: spapr->rtas_size);
385:
386: /* Set up the entry state */
387: first_cpu->gpr[3] = spapr->fdt_addr;
388: first_cpu->gpr[5] = 0;
389: first_cpu->halted = 0;
390: first_cpu->nip = spapr->entry_point;
391:
392: }
393:
394: /* pSeries LPAR / sPAPR hardware init */
395: static void ppc_spapr_init(ram_addr_t ram_size,
396: const char *boot_device,
397: const char *kernel_filename,
398: const char *kernel_cmdline,
399: const char *initrd_filename,
400: const char *cpu_model)
401: {
402: CPUState *env;
403: int i;
1.1.1.2 ! root 404: MemoryRegion *sysmem = get_system_memory();
! 405: MemoryRegion *ram = g_new(MemoryRegion, 1);
! 406: target_phys_addr_t rma_alloc_size, rma_size;
1.1 root 407: uint32_t initrd_base;
408: long kernel_size, initrd_size, fw_size;
409: long pteg_shift = 17;
410: char *filename;
411:
1.1.1.2 ! root 412: spapr = g_malloc0(sizeof(*spapr));
! 413: QLIST_INIT(&spapr->phbs);
! 414:
1.1 root 415: cpu_ppc_hypercall = emulate_spapr_hypercall;
416:
1.1.1.2 ! root 417: /* Allocate RMA if necessary */
! 418: rma_alloc_size = kvmppc_alloc_rma("ppc_spapr.rma", sysmem);
! 419:
! 420: if (rma_alloc_size == -1) {
! 421: hw_error("qemu: Unable to create RMA\n");
! 422: exit(1);
! 423: }
! 424: if (rma_alloc_size && (rma_alloc_size < ram_size)) {
! 425: rma_size = rma_alloc_size;
! 426: } else {
! 427: rma_size = ram_size;
! 428: }
! 429:
! 430: /* We place the device tree just below either the top of the RMA,
! 431: * or just below 2GB, whichever is lowere, so that it can be
! 432: * processed with 32-bit real mode code if necessary */
! 433: spapr->fdt_addr = MIN(rma_size, 0x80000000) - FDT_MAX_SIZE;
1.1 root 434: spapr->rtas_addr = spapr->fdt_addr - RTAS_MAX_SIZE;
435:
436: /* init CPUs */
437: if (cpu_model == NULL) {
1.1.1.2 ! root 438: cpu_model = kvm_enabled() ? "host" : "POWER7";
1.1 root 439: }
440: for (i = 0; i < smp_cpus; i++) {
441: env = cpu_init(cpu_model);
442:
443: if (!env) {
444: fprintf(stderr, "Unable to find PowerPC CPU definition\n");
445: exit(1);
446: }
447: /* Set time-base frequency to 512 MHz */
448: cpu_ppc_tb_init(env, TIMEBASE_FREQ);
449: qemu_register_reset((QEMUResetHandler *)&cpu_reset, env);
450:
451: env->hreset_vector = 0x60;
452: env->hreset_excp_prefix = 0;
453: env->gpr[3] = env->cpu_index;
454: }
455:
456: /* allocate RAM */
1.1.1.2 ! root 457: spapr->ram_limit = ram_size;
! 458: if (spapr->ram_limit > rma_alloc_size) {
! 459: ram_addr_t nonrma_base = rma_alloc_size;
! 460: ram_addr_t nonrma_size = spapr->ram_limit - rma_alloc_size;
! 461:
! 462: memory_region_init_ram(ram, NULL, "ppc_spapr.ram", nonrma_size);
! 463: memory_region_add_subregion(sysmem, nonrma_base, ram);
! 464: }
1.1 root 465:
466: /* allocate hash page table. For now we always make this 16mb,
467: * later we should probably make it scale to the size of guest
468: * RAM */
469: spapr->htab_size = 1ULL << (pteg_shift + 7);
1.1.1.2 ! root 470: spapr->htab = qemu_memalign(spapr->htab_size, spapr->htab_size);
1.1 root 471:
472: for (env = first_cpu; env != NULL; env = env->next_cpu) {
473: env->external_htab = spapr->htab;
474: env->htab_base = -1;
475: env->htab_mask = spapr->htab_size - 1;
1.1.1.2 ! root 476:
! 477: /* Tell KVM that we're in PAPR mode */
! 478: env->spr[SPR_SDR1] = (unsigned long)spapr->htab |
! 479: ((pteg_shift + 7) - 18);
! 480: env->spr[SPR_HIOR] = 0;
! 481:
! 482: if (kvm_enabled()) {
! 483: kvmppc_set_papr(env);
! 484: }
1.1 root 485: }
486:
487: filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
488: spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr,
489: ram_size - spapr->rtas_addr);
490: if (spapr->rtas_size < 0) {
491: hw_error("qemu: could not load LPAR rtas '%s'\n", filename);
492: exit(1);
493: }
1.1.1.2 ! root 494: g_free(filename);
1.1 root 495:
496: /* Set up Interrupt Controller */
497: spapr->icp = xics_system_init(XICS_IRQS);
1.1.1.2 ! root 498: spapr->next_irq = 16;
1.1 root 499:
500: /* Set up VIO bus */
501: spapr->vio_bus = spapr_vio_bus_init();
502:
1.1.1.2 ! root 503: for (i = 0; i < MAX_SERIAL_PORTS; i++) {
1.1 root 504: if (serial_hds[i]) {
505: spapr_vty_create(spapr->vio_bus, SPAPR_VTY_BASE_ADDRESS + i,
1.1.1.2 ! root 506: serial_hds[i]);
1.1 root 507: }
508: }
509:
1.1.1.2 ! root 510: /* Set up PCI */
! 511: spapr_create_phb(spapr, "pci", SPAPR_PCI_BUID,
! 512: SPAPR_PCI_MEM_WIN_ADDR,
! 513: SPAPR_PCI_MEM_WIN_SIZE,
! 514: SPAPR_PCI_IO_WIN_ADDR);
! 515:
! 516: for (i = 0; i < nb_nics; i++) {
1.1 root 517: NICInfo *nd = &nd_table[i];
518:
519: if (!nd->model) {
1.1.1.2 ! root 520: nd->model = g_strdup("ibmveth");
1.1 root 521: }
522:
523: if (strcmp(nd->model, "ibmveth") == 0) {
1.1.1.2 ! root 524: spapr_vlan_create(spapr->vio_bus, 0x1000 + i, nd);
1.1 root 525: } else {
1.1.1.2 ! root 526: pci_nic_init_nofail(&nd_table[i], nd->model, NULL);
1.1 root 527: }
528: }
529:
530: for (i = 0; i <= drive_get_max_bus(IF_SCSI); i++) {
1.1.1.2 ! root 531: spapr_vscsi_create(spapr->vio_bus, 0x2000 + i);
1.1 root 532: }
533:
534: if (kernel_filename) {
535: uint64_t lowaddr = 0;
536:
537: kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
538: NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);
539: if (kernel_size < 0) {
540: kernel_size = load_image_targphys(kernel_filename,
541: KERNEL_LOAD_ADDR,
542: ram_size - KERNEL_LOAD_ADDR);
543: }
544: if (kernel_size < 0) {
545: fprintf(stderr, "qemu: could not load kernel '%s'\n",
546: kernel_filename);
547: exit(1);
548: }
549:
550: /* load initrd */
551: if (initrd_filename) {
552: initrd_base = INITRD_LOAD_ADDR;
553: initrd_size = load_image_targphys(initrd_filename, initrd_base,
554: ram_size - initrd_base);
555: if (initrd_size < 0) {
556: fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
557: initrd_filename);
558: exit(1);
559: }
560: } else {
561: initrd_base = 0;
562: initrd_size = 0;
563: }
564:
565: spapr->entry_point = KERNEL_LOAD_ADDR;
566: } else {
1.1.1.2 ! root 567: if (rma_size < (MIN_RMA_SLOF << 20)) {
1.1 root 568: fprintf(stderr, "qemu: pSeries SLOF firmware requires >= "
1.1.1.2 ! root 569: "%ldM guest RMA (Real Mode Area memory)\n", MIN_RMA_SLOF);
1.1 root 570: exit(1);
571: }
1.1.1.2 ! root 572: filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, FW_FILE_NAME);
1.1 root 573: fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
574: if (fw_size < 0) {
575: hw_error("qemu: could not load LPAR rtas '%s'\n", filename);
576: exit(1);
577: }
1.1.1.2 ! root 578: g_free(filename);
1.1 root 579: spapr->entry_point = 0x100;
580: initrd_base = 0;
581: initrd_size = 0;
582:
583: /* SLOF will startup the secondary CPUs using RTAS,
584: rather than expecting a kexec() style entry */
585: for (env = first_cpu; env != NULL; env = env->next_cpu) {
586: env->halted = 1;
587: }
588: }
589:
590: /* Prepare the device tree */
1.1.1.2 ! root 591: spapr->fdt_skel = spapr_create_fdt_skel(cpu_model, rma_size,
1.1 root 592: initrd_base, initrd_size,
593: boot_device, kernel_cmdline,
594: pteg_shift + 7);
595: assert(spapr->fdt_skel != NULL);
596:
597: qemu_register_reset(spapr_reset, spapr);
598: }
599:
600: static QEMUMachine spapr_machine = {
601: .name = "pseries",
602: .desc = "pSeries Logical Partition (PAPR compliant)",
603: .init = ppc_spapr_init,
604: .max_cpus = MAX_CPUS,
605: .no_vga = 1,
606: .no_parallel = 1,
607: .use_scsi = 1,
608: };
609:
610: static void spapr_machine_init(void)
611: {
612: qemu_register_machine(&spapr_machine);
613: }
614:
615: machine_init(spapr_machine_init);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.