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