Revision a9f8ad8f

b/.gitmodules
4 4
[submodule "roms/seabios"]
5 5
	path = roms/seabios
6 6
	url = git://git.qemu.org/seabios.git/
7
[submodule "roms/SLOF"]
8
	path = roms/SLOF
9
	url = git://git.qemu.org/SLOF.git
b/Makefile
214 214
bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
215 215
multiboot.bin linuxboot.bin \
216 216
s390-zipl.rom \
217
spapr-rtas.bin
217
spapr-rtas.bin slof.bin
218 218
else
219 219
BLOBS=
220 220
endif
b/hw/spapr.c
44 44
#define INITRD_LOAD_ADDR        0x02800000
45 45
#define FDT_MAX_SIZE            0x10000
46 46
#define RTAS_MAX_SIZE           0x10000
47
#define FW_MAX_SIZE             0x400000
48
#define FW_FILE_NAME            "slof.bin"
49

  
50
#define MIN_RAM_SLOF		512UL
47 51

  
48 52
#define TIMEBASE_FREQ           512000000ULL
49 53

  
......
57 61
                              sPAPREnvironment *spapr,
58 62
                              target_phys_addr_t initrd_base,
59 63
                              target_phys_addr_t initrd_size,
64
                              const char *boot_device,
60 65
                              const char *kernel_cmdline,
61 66
                              target_phys_addr_t rtas_addr,
62 67
                              target_phys_addr_t rtas_size,
......
105 110
                       &start_prop, sizeof(start_prop))));
106 111
    _FDT((fdt_property(fdt, "linux,initrd-end",
107 112
                       &end_prop, sizeof(end_prop))));
113
    _FDT((fdt_property_string(fdt, "qemu,boot-device", boot_device)));
108 114

  
109 115
    _FDT((fdt_end_node(fdt)));
110 116

  
......
261 267
    ram_addr_t ram_offset;
262 268
    target_phys_addr_t fdt_addr, rtas_addr;
263 269
    uint32_t kernel_base, initrd_base;
264
    long kernel_size, initrd_size, htab_size, rtas_size;
270
    long kernel_size, initrd_size, htab_size, rtas_size, fw_size;
265 271
    long pteg_shift = 17;
266 272
    int fdt_size;
267 273
    char *filename;
......
392 398
            initrd_size = 0;
393 399
        }
394 400
    } else {
395
        fprintf(stderr, "pSeries machine needs -kernel for now");
396
        exit(1);
401
        if (ram_size < (MIN_RAM_SLOF << 20)) {
402
            fprintf(stderr, "qemu: pSeries SLOF firmware requires >= "
403
                    "%ldM guest RAM\n", MIN_RAM_SLOF);
404
            exit(1);
405
        }
406
        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "slof.bin");
407
        fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
408
        if (fw_size < 0) {
409
            hw_error("qemu: could not load LPAR rtas '%s'\n", filename);
410
            exit(1);
411
        }
412
        qemu_free(filename);
413
        kernel_base = 0x100;
414
        initrd_base = 0;
415
        initrd_size = 0;
416

  
417
        /* SLOF will startup the secondary CPUs using RTAS,
418
           rather than expecting a kexec() style entry */
419
        for (i = 0; i < smp_cpus; i++) {
420
            envs[i]->halted = 1;
421
        }
397 422
    }
398 423

  
399 424
    /* Prepare the device tree */
400 425
    fdt = spapr_create_fdt(&fdt_size, ram_size, cpu_model, envs, spapr,
401
                           initrd_base, initrd_size, kernel_cmdline,
426
                           initrd_base, initrd_size,
427
                           boot_device, kernel_cmdline,
402 428
                           rtas_addr, rtas_size, pteg_shift + 7);
403 429
    assert(fdt != NULL);
404 430

  
......
409 435
    envs[0]->gpr[3] = fdt_addr;
410 436
    envs[0]->gpr[5] = 0;
411 437
    envs[0]->hreset_vector = kernel_base;
438
    envs[0]->halted = 0;
412 439
}
413 440

  
414 441
static QEMUMachine spapr_machine = {
b/hw/spapr_rtas.c
90 90
    rtas_st(rets, 0, 0);
91 91
}
92 92

  
93
static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
94
                                         uint32_t token, uint32_t nargs,
95
                                         target_ulong args,
96
                                         uint32_t nret, target_ulong rets)
97
{
98
    target_ulong id;
99
    CPUState *env;
100

  
101
    if (nargs != 1 || nret != 2) {
102
        rtas_st(rets, 0, -3);
103
        return;
104
    }
105

  
106
    id = rtas_ld(args, 0);
107
    for (env = first_cpu; env; env = env->next_cpu) {
108
        if (env->cpu_index != id) {
109
            continue;
110
        }
111

  
112
        if (env->halted) {
113
            rtas_st(rets, 1, 0);
114
        } else {
115
            rtas_st(rets, 1, 2);
116
        }
117

  
118
        rtas_st(rets, 0, 0);
119
        return;
120
    }
121

  
122
    /* Didn't find a matching cpu */
123
    rtas_st(rets, 0, -3);
124
}
125

  
126
static void rtas_start_cpu(sPAPREnvironment *spapr,
127
                           uint32_t token, uint32_t nargs,
128
                           target_ulong args,
129
                           uint32_t nret, target_ulong rets)
130
{
131
    target_ulong id, start, r3;
132
    CPUState *env;
133

  
134
    if (nargs != 3 || nret != 1) {
135
        rtas_st(rets, 0, -3);
136
        return;
137
    }
138

  
139
    id = rtas_ld(args, 0);
140
    start = rtas_ld(args, 1);
141
    r3 = rtas_ld(args, 2);
142

  
143
    for (env = first_cpu; env; env = env->next_cpu) {
144
        if (env->cpu_index != id) {
145
            continue;
146
        }
147

  
148
        if (!env->halted) {
149
            rtas_st(rets, 0, -1);
150
            return;
151
        }
152

  
153
        env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
154
        env->nip = start;
155
        env->gpr[3] = r3;
156
        env->halted = 0;
157

  
158
        qemu_cpu_kick(env);
159

  
160
        rtas_st(rets, 0, 0);
161
        return;
162
    }
163

  
164
    /* Didn't find a matching cpu */
165
    rtas_st(rets, 0, -3);
166
}
167

  
93 168
static struct rtas_call {
94 169
    const char *name;
95 170
    spapr_rtas_fn fn;
......
196 271
    spapr_rtas_register("display-character", rtas_display_character);
197 272
    spapr_rtas_register("get-time-of-day", rtas_get_time_of_day);
198 273
    spapr_rtas_register("power-off", rtas_power_off);
274
    spapr_rtas_register("query-cpu-stopped-state",
275
                        rtas_query_cpu_stopped_state);
276
    spapr_rtas_register("start-cpu", rtas_start_cpu);
199 277
}
200 278
device_init(register_core_rtas);
b/pc-bios/README
13 13
  The included image for PowerPC (for 32 and 64 bit PPC CPUs), Sparc32
14 14
  and Sparc64 are built from OpenBIOS SVN revision 1018.
15 15

  
16
- SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware
17
  implementation for certain IBM POWER hardware.  The sources are at
18
  https://github.com/dgibson/SLOF, and the image currently in qemu is
19
  built from git tag qemu-slof-20110323.
20

  
16 21
- The PXE roms come from Rom-o-Matic gPXE 0.9.9 with BANNER_TIMEOUT=0
17 22

  
18 23
  e1000 8086:100E
b/roms/SLOF
1
Subproject commit d1d6b53b713a2b7c2c25685268fa932d28a4b4c0

Also available in: Unified diff