Revision 5a4348d1
b/device_tree.c | ||
---|---|---|
131 | 131 |
return offset; |
132 | 132 |
} |
133 | 133 |
|
134 |
int qemu_devtree_setprop(void *fdt, const char *node_path,
|
|
135 |
const char *property, const void *val_array, int size)
|
|
134 |
int qemu_fdt_setprop(void *fdt, const char *node_path,
|
|
135 |
const char *property, const void *val_array, int size) |
|
136 | 136 |
{ |
137 | 137 |
int r; |
138 | 138 |
|
... | ... | |
146 | 146 |
return r; |
147 | 147 |
} |
148 | 148 |
|
149 |
int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
|
|
150 |
const char *property, uint32_t val)
|
|
149 |
int qemu_fdt_setprop_cell(void *fdt, const char *node_path,
|
|
150 |
const char *property, uint32_t val) |
|
151 | 151 |
{ |
152 | 152 |
int r; |
153 | 153 |
|
... | ... | |
161 | 161 |
return r; |
162 | 162 |
} |
163 | 163 |
|
164 |
int qemu_devtree_setprop_u64(void *fdt, const char *node_path,
|
|
165 |
const char *property, uint64_t val)
|
|
164 |
int qemu_fdt_setprop_u64(void *fdt, const char *node_path,
|
|
165 |
const char *property, uint64_t val) |
|
166 | 166 |
{ |
167 | 167 |
val = cpu_to_be64(val); |
168 |
return qemu_devtree_setprop(fdt, node_path, property, &val, sizeof(val));
|
|
168 |
return qemu_fdt_setprop(fdt, node_path, property, &val, sizeof(val));
|
|
169 | 169 |
} |
170 | 170 |
|
171 |
int qemu_devtree_setprop_string(void *fdt, const char *node_path,
|
|
172 |
const char *property, const char *string)
|
|
171 |
int qemu_fdt_setprop_string(void *fdt, const char *node_path,
|
|
172 |
const char *property, const char *string) |
|
173 | 173 |
{ |
174 | 174 |
int r; |
175 | 175 |
|
... | ... | |
183 | 183 |
return r; |
184 | 184 |
} |
185 | 185 |
|
186 |
const void *qemu_devtree_getprop(void *fdt, const char *node_path,
|
|
187 |
const char *property, int *lenp)
|
|
186 |
const void *qemu_fdt_getprop(void *fdt, const char *node_path,
|
|
187 |
const char *property, int *lenp) |
|
188 | 188 |
{ |
189 | 189 |
int len; |
190 | 190 |
const void *r; |
... | ... | |
200 | 200 |
return r; |
201 | 201 |
} |
202 | 202 |
|
203 |
uint32_t qemu_devtree_getprop_cell(void *fdt, const char *node_path,
|
|
204 |
const char *property)
|
|
203 |
uint32_t qemu_fdt_getprop_cell(void *fdt, const char *node_path,
|
|
204 |
const char *property) |
|
205 | 205 |
{ |
206 | 206 |
int len; |
207 |
const uint32_t *p = qemu_devtree_getprop(fdt, node_path, property, &len);
|
|
207 |
const uint32_t *p = qemu_fdt_getprop(fdt, node_path, property, &len);
|
|
208 | 208 |
if (len != 4) { |
209 | 209 |
fprintf(stderr, "%s: %s/%s not 4 bytes long (not a cell?)\n", |
210 | 210 |
__func__, node_path, property); |
... | ... | |
213 | 213 |
return be32_to_cpu(*p); |
214 | 214 |
} |
215 | 215 |
|
216 |
uint32_t qemu_devtree_get_phandle(void *fdt, const char *path)
|
|
216 |
uint32_t qemu_fdt_get_phandle(void *fdt, const char *path)
|
|
217 | 217 |
{ |
218 | 218 |
uint32_t r; |
219 | 219 |
|
... | ... | |
227 | 227 |
return r; |
228 | 228 |
} |
229 | 229 |
|
230 |
int qemu_devtree_setprop_phandle(void *fdt, const char *node_path,
|
|
231 |
const char *property,
|
|
232 |
const char *target_node_path)
|
|
230 |
int qemu_fdt_setprop_phandle(void *fdt, const char *node_path,
|
|
231 |
const char *property, |
|
232 |
const char *target_node_path) |
|
233 | 233 |
{ |
234 |
uint32_t phandle = qemu_devtree_get_phandle(fdt, target_node_path);
|
|
235 |
return qemu_devtree_setprop_cell(fdt, node_path, property, phandle);
|
|
234 |
uint32_t phandle = qemu_fdt_get_phandle(fdt, target_node_path);
|
|
235 |
return qemu_fdt_setprop_cell(fdt, node_path, property, phandle);
|
|
236 | 236 |
} |
237 | 237 |
|
238 |
uint32_t qemu_devtree_alloc_phandle(void *fdt)
|
|
238 |
uint32_t qemu_fdt_alloc_phandle(void *fdt)
|
|
239 | 239 |
{ |
240 | 240 |
static int phandle = 0x0; |
241 | 241 |
|
... | ... | |
259 | 259 |
return phandle++; |
260 | 260 |
} |
261 | 261 |
|
262 |
int qemu_devtree_nop_node(void *fdt, const char *node_path)
|
|
262 |
int qemu_fdt_nop_node(void *fdt, const char *node_path)
|
|
263 | 263 |
{ |
264 | 264 |
int r; |
265 | 265 |
|
... | ... | |
273 | 273 |
return r; |
274 | 274 |
} |
275 | 275 |
|
276 |
int qemu_devtree_add_subnode(void *fdt, const char *name)
|
|
276 |
int qemu_fdt_add_subnode(void *fdt, const char *name)
|
|
277 | 277 |
{ |
278 | 278 |
char *dupname = g_strdup(name); |
279 | 279 |
char *basename = strrchr(dupname, '/'); |
... | ... | |
303 | 303 |
return retval; |
304 | 304 |
} |
305 | 305 |
|
306 |
void qemu_devtree_dumpdtb(void *fdt, int size)
|
|
306 |
void qemu_fdt_dumpdtb(void *fdt, int size)
|
|
307 | 307 |
{ |
308 | 308 |
const char *dumpdtb = qemu_opt_get(qemu_get_machine_opts(), "dumpdtb"); |
309 | 309 |
|
... | ... | |
313 | 313 |
} |
314 | 314 |
} |
315 | 315 |
|
316 |
int qemu_devtree_setprop_sized_cells_from_array(void *fdt,
|
|
317 |
const char *node_path,
|
|
318 |
const char *property,
|
|
319 |
int numvalues,
|
|
320 |
uint64_t *values)
|
|
316 |
int qemu_fdt_setprop_sized_cells_from_array(void *fdt,
|
|
317 |
const char *node_path, |
|
318 |
const char *property, |
|
319 |
int numvalues, |
|
320 |
uint64_t *values) |
|
321 | 321 |
{ |
322 | 322 |
uint32_t *propcells; |
323 | 323 |
uint64_t value; |
... | ... | |
342 | 342 |
propcells[cellnum++] = cpu_to_be32(value); |
343 | 343 |
} |
344 | 344 |
|
345 |
return qemu_devtree_setprop(fdt, node_path, property, propcells,
|
|
346 |
cellnum * sizeof(uint32_t));
|
|
345 |
return qemu_fdt_setprop(fdt, node_path, property, propcells,
|
|
346 |
cellnum * sizeof(uint32_t)); |
|
347 | 347 |
} |
b/hw/arm/boot.c | ||
---|---|---|
335 | 335 |
} |
336 | 336 |
} |
337 | 337 |
|
338 |
acells = qemu_devtree_getprop_cell(fdt, "/", "#address-cells");
|
|
339 |
scells = qemu_devtree_getprop_cell(fdt, "/", "#size-cells");
|
|
338 |
acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells");
|
|
339 |
scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells");
|
|
340 | 340 |
if (acells == 0 || scells == 0) { |
341 | 341 |
fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 0)\n"); |
342 | 342 |
goto fail; |
... | ... | |
351 | 351 |
goto fail; |
352 | 352 |
} |
353 | 353 |
|
354 |
rc = qemu_devtree_setprop_sized_cells(fdt, "/memory", "reg",
|
|
355 |
acells, binfo->loader_start,
|
|
356 |
scells, binfo->ram_size);
|
|
354 |
rc = qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg",
|
|
355 |
acells, binfo->loader_start, |
|
356 |
scells, binfo->ram_size); |
|
357 | 357 |
if (rc < 0) { |
358 | 358 |
fprintf(stderr, "couldn't set /memory/reg\n"); |
359 | 359 |
goto fail; |
360 | 360 |
} |
361 | 361 |
|
362 | 362 |
if (binfo->kernel_cmdline && *binfo->kernel_cmdline) { |
363 |
rc = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
|
|
364 |
binfo->kernel_cmdline);
|
|
363 |
rc = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
|
|
364 |
binfo->kernel_cmdline); |
|
365 | 365 |
if (rc < 0) { |
366 | 366 |
fprintf(stderr, "couldn't set /chosen/bootargs\n"); |
367 | 367 |
goto fail; |
... | ... | |
369 | 369 |
} |
370 | 370 |
|
371 | 371 |
if (binfo->initrd_size) { |
372 |
rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
|
|
373 |
binfo->initrd_start); |
|
372 |
rc = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
|
|
373 |
binfo->initrd_start);
|
|
374 | 374 |
if (rc < 0) { |
375 | 375 |
fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n"); |
376 | 376 |
goto fail; |
377 | 377 |
} |
378 | 378 |
|
379 |
rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
|
|
380 |
binfo->initrd_start + binfo->initrd_size); |
|
379 |
rc = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
|
|
380 |
binfo->initrd_start + binfo->initrd_size);
|
|
381 | 381 |
if (rc < 0) { |
382 | 382 |
fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n"); |
383 | 383 |
goto fail; |
... | ... | |
388 | 388 |
binfo->modify_dtb(binfo, fdt); |
389 | 389 |
} |
390 | 390 |
|
391 |
qemu_devtree_dumpdtb(fdt, size);
|
|
391 |
qemu_fdt_dumpdtb(fdt, size);
|
|
392 | 392 |
|
393 | 393 |
cpu_physical_memory_write(addr, fdt, size); |
394 | 394 |
|
b/hw/arm/vexpress.c | ||
---|---|---|
419 | 419 |
int rc; |
420 | 420 |
char *nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, addr); |
421 | 421 |
|
422 |
rc = qemu_devtree_add_subnode(fdt, nodename);
|
|
423 |
rc |= qemu_devtree_setprop_string(fdt, nodename,
|
|
424 |
"compatible", "virtio,mmio");
|
|
425 |
rc |= qemu_devtree_setprop_sized_cells(fdt, nodename, "reg",
|
|
426 |
acells, addr, scells, size);
|
|
427 |
qemu_devtree_setprop_cells(fdt, nodename, "interrupt-parent", intc);
|
|
428 |
qemu_devtree_setprop_cells(fdt, nodename, "interrupts", 0, irq, 1);
|
|
422 |
rc = qemu_fdt_add_subnode(fdt, nodename);
|
|
423 |
rc |= qemu_fdt_setprop_string(fdt, nodename,
|
|
424 |
"compatible", "virtio,mmio"); |
|
425 |
rc |= qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
|
|
426 |
acells, addr, scells, size); |
|
427 |
qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", intc);
|
|
428 |
qemu_fdt_setprop_cells(fdt, nodename, "interrupts", 0, irq, 1);
|
|
429 | 429 |
g_free(nodename); |
430 | 430 |
if (rc) { |
431 | 431 |
return -1; |
... | ... | |
456 | 456 |
uint32_t acells, scells, intc; |
457 | 457 |
const VEDBoardInfo *daughterboard = (const VEDBoardInfo *)info; |
458 | 458 |
|
459 |
acells = qemu_devtree_getprop_cell(fdt, "/", "#address-cells");
|
|
460 |
scells = qemu_devtree_getprop_cell(fdt, "/", "#size-cells");
|
|
459 |
acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells");
|
|
460 |
scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells");
|
|
461 | 461 |
intc = find_int_controller(fdt); |
462 | 462 |
if (!intc) { |
463 | 463 |
/* Not fatal, we just won't provide virtio. This will |
b/hw/arm/virt.c | ||
---|---|---|
156 | 156 |
vbi->fdt = fdt; |
157 | 157 |
|
158 | 158 |
/* Header */ |
159 |
qemu_devtree_setprop_string(fdt, "/", "compatible", "linux,dummy-virt");
|
|
160 |
qemu_devtree_setprop_cell(fdt, "/", "#address-cells", 0x2);
|
|
161 |
qemu_devtree_setprop_cell(fdt, "/", "#size-cells", 0x2);
|
|
159 |
qemu_fdt_setprop_string(fdt, "/", "compatible", "linux,dummy-virt");
|
|
160 |
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
|
|
161 |
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
|
|
162 | 162 |
|
163 | 163 |
/* |
164 | 164 |
* /chosen and /memory nodes must exist for load_dtb |
165 | 165 |
* to fill in necessary properties later |
166 | 166 |
*/ |
167 |
qemu_devtree_add_subnode(fdt, "/chosen");
|
|
168 |
qemu_devtree_add_subnode(fdt, "/memory");
|
|
169 |
qemu_devtree_setprop_string(fdt, "/memory", "device_type", "memory");
|
|
167 |
qemu_fdt_add_subnode(fdt, "/chosen");
|
|
168 |
qemu_fdt_add_subnode(fdt, "/memory");
|
|
169 |
qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
|
|
170 | 170 |
|
171 | 171 |
/* Clock node, for the benefit of the UART. The kernel device tree |
172 | 172 |
* binding documentation claims the PL011 node clock properties are |
173 | 173 |
* optional but in practice if you omit them the kernel refuses to |
174 | 174 |
* probe for the device. |
175 | 175 |
*/ |
176 |
vbi->clock_phandle = qemu_devtree_alloc_phandle(fdt);
|
|
177 |
qemu_devtree_add_subnode(fdt, "/apb-pclk");
|
|
178 |
qemu_devtree_setprop_string(fdt, "/apb-pclk", "compatible", "fixed-clock");
|
|
179 |
qemu_devtree_setprop_cell(fdt, "/apb-pclk", "#clock-cells", 0x0);
|
|
180 |
qemu_devtree_setprop_cell(fdt, "/apb-pclk", "clock-frequency", 24000000);
|
|
181 |
qemu_devtree_setprop_string(fdt, "/apb-pclk", "clock-output-names",
|
|
176 |
vbi->clock_phandle = qemu_fdt_alloc_phandle(fdt);
|
|
177 |
qemu_fdt_add_subnode(fdt, "/apb-pclk");
|
|
178 |
qemu_fdt_setprop_string(fdt, "/apb-pclk", "compatible", "fixed-clock");
|
|
179 |
qemu_fdt_setprop_cell(fdt, "/apb-pclk", "#clock-cells", 0x0);
|
|
180 |
qemu_fdt_setprop_cell(fdt, "/apb-pclk", "clock-frequency", 24000000);
|
|
181 |
qemu_fdt_setprop_string(fdt, "/apb-pclk", "clock-output-names",
|
|
182 | 182 |
"clk24mhz"); |
183 |
qemu_devtree_setprop_cell(fdt, "/apb-pclk", "phandle", vbi->clock_phandle);
|
|
183 |
qemu_fdt_setprop_cell(fdt, "/apb-pclk", "phandle", vbi->clock_phandle);
|
|
184 | 184 |
|
185 | 185 |
/* No PSCI for TCG yet */ |
186 | 186 |
if (kvm_enabled()) { |
187 |
qemu_devtree_add_subnode(fdt, "/psci");
|
|
188 |
qemu_devtree_setprop_string(fdt, "/psci", "compatible", "arm,psci");
|
|
189 |
qemu_devtree_setprop_string(fdt, "/psci", "method", "hvc");
|
|
190 |
qemu_devtree_setprop_cell(fdt, "/psci", "cpu_suspend",
|
|
187 |
qemu_fdt_add_subnode(fdt, "/psci");
|
|
188 |
qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
|
|
189 |
qemu_fdt_setprop_string(fdt, "/psci", "method", "hvc");
|
|
190 |
qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend",
|
|
191 | 191 |
PSCI_FN_CPU_SUSPEND); |
192 |
qemu_devtree_setprop_cell(fdt, "/psci", "cpu_off", PSCI_FN_CPU_OFF);
|
|
193 |
qemu_devtree_setprop_cell(fdt, "/psci", "cpu_on", PSCI_FN_CPU_ON);
|
|
194 |
qemu_devtree_setprop_cell(fdt, "/psci", "migrate", PSCI_FN_MIGRATE);
|
|
192 |
qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", PSCI_FN_CPU_OFF);
|
|
193 |
qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", PSCI_FN_CPU_ON);
|
|
194 |
qemu_fdt_setprop_cell(fdt, "/psci", "migrate", PSCI_FN_MIGRATE);
|
|
195 | 195 |
} |
196 | 196 |
} |
197 | 197 |
|
... | ... | |
206 | 206 |
irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START, |
207 | 207 |
GIC_FDT_IRQ_PPI_CPU_WIDTH, (1 << vbi->smp_cpus) - 1); |
208 | 208 |
|
209 |
qemu_devtree_add_subnode(vbi->fdt, "/timer");
|
|
210 |
qemu_devtree_setprop_string(vbi->fdt, "/timer",
|
|
209 |
qemu_fdt_add_subnode(vbi->fdt, "/timer");
|
|
210 |
qemu_fdt_setprop_string(vbi->fdt, "/timer",
|
|
211 | 211 |
"compatible", "arm,armv7-timer"); |
212 |
qemu_devtree_setprop_cells(vbi->fdt, "/timer", "interrupts",
|
|
212 |
qemu_fdt_setprop_cells(vbi->fdt, "/timer", "interrupts",
|
|
213 | 213 |
GIC_FDT_IRQ_TYPE_PPI, 13, irqflags, |
214 | 214 |
GIC_FDT_IRQ_TYPE_PPI, 14, irqflags, |
215 | 215 |
GIC_FDT_IRQ_TYPE_PPI, 11, irqflags, |
... | ... | |
220 | 220 |
{ |
221 | 221 |
int cpu; |
222 | 222 |
|
223 |
qemu_devtree_add_subnode(vbi->fdt, "/cpus");
|
|
224 |
qemu_devtree_setprop_cell(vbi->fdt, "/cpus", "#address-cells", 0x1);
|
|
225 |
qemu_devtree_setprop_cell(vbi->fdt, "/cpus", "#size-cells", 0x0);
|
|
223 |
qemu_fdt_add_subnode(vbi->fdt, "/cpus");
|
|
224 |
qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#address-cells", 0x1);
|
|
225 |
qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#size-cells", 0x0);
|
|
226 | 226 |
|
227 | 227 |
for (cpu = vbi->smp_cpus - 1; cpu >= 0; cpu--) { |
228 | 228 |
char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu); |
229 | 229 |
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu)); |
230 | 230 |
|
231 |
qemu_devtree_add_subnode(vbi->fdt, nodename);
|
|
232 |
qemu_devtree_setprop_string(vbi->fdt, nodename, "device_type", "cpu");
|
|
233 |
qemu_devtree_setprop_string(vbi->fdt, nodename, "compatible",
|
|
231 |
qemu_fdt_add_subnode(vbi->fdt, nodename);
|
|
232 |
qemu_fdt_setprop_string(vbi->fdt, nodename, "device_type", "cpu");
|
|
233 |
qemu_fdt_setprop_string(vbi->fdt, nodename, "compatible",
|
|
234 | 234 |
armcpu->dtb_compatible); |
235 | 235 |
|
236 | 236 |
if (vbi->smp_cpus > 1) { |
237 |
qemu_devtree_setprop_string(vbi->fdt, nodename,
|
|
237 |
qemu_fdt_setprop_string(vbi->fdt, nodename,
|
|
238 | 238 |
"enable-method", "psci"); |
239 | 239 |
} |
240 | 240 |
|
241 |
qemu_devtree_setprop_cell(vbi->fdt, nodename, "reg", cpu);
|
|
241 |
qemu_fdt_setprop_cell(vbi->fdt, nodename, "reg", cpu);
|
|
242 | 242 |
g_free(nodename); |
243 | 243 |
} |
244 | 244 |
} |
... | ... | |
247 | 247 |
{ |
248 | 248 |
uint32_t gic_phandle; |
249 | 249 |
|
250 |
gic_phandle = qemu_devtree_alloc_phandle(vbi->fdt);
|
|
251 |
qemu_devtree_setprop_cell(vbi->fdt, "/", "interrupt-parent", gic_phandle);
|
|
250 |
gic_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
|
|
251 |
qemu_fdt_setprop_cell(vbi->fdt, "/", "interrupt-parent", gic_phandle);
|
|
252 | 252 |
|
253 |
qemu_devtree_add_subnode(vbi->fdt, "/intc");
|
|
254 |
qemu_devtree_setprop_string(vbi->fdt, "/intc", "compatible",
|
|
253 |
qemu_fdt_add_subnode(vbi->fdt, "/intc");
|
|
254 |
qemu_fdt_setprop_string(vbi->fdt, "/intc", "compatible",
|
|
255 | 255 |
vbi->gic_compatible); |
256 |
qemu_devtree_setprop_cell(vbi->fdt, "/intc", "#interrupt-cells", 3);
|
|
257 |
qemu_devtree_setprop(vbi->fdt, "/intc", "interrupt-controller", NULL, 0);
|
|
258 |
qemu_devtree_setprop_sized_cells(vbi->fdt, "/intc", "reg",
|
|
256 |
qemu_fdt_setprop_cell(vbi->fdt, "/intc", "#interrupt-cells", 3);
|
|
257 |
qemu_fdt_setprop(vbi->fdt, "/intc", "interrupt-controller", NULL, 0);
|
|
258 |
qemu_fdt_setprop_sized_cells(vbi->fdt, "/intc", "reg",
|
|
259 | 259 |
2, vbi->memmap[VIRT_GIC_DIST].base, |
260 | 260 |
2, vbi->memmap[VIRT_GIC_DIST].size, |
261 | 261 |
2, vbi->memmap[VIRT_GIC_CPU].base, |
262 | 262 |
2, vbi->memmap[VIRT_GIC_CPU].size); |
263 |
qemu_devtree_setprop_cell(vbi->fdt, "/intc", "phandle", gic_phandle);
|
|
263 |
qemu_fdt_setprop_cell(vbi->fdt, "/intc", "phandle", gic_phandle);
|
|
264 | 264 |
} |
265 | 265 |
|
266 | 266 |
static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic) |
... | ... | |
275 | 275 |
sysbus_create_simple("pl011", base, pic[irq]); |
276 | 276 |
|
277 | 277 |
nodename = g_strdup_printf("/pl011@%" PRIx64, base); |
278 |
qemu_devtree_add_subnode(vbi->fdt, nodename);
|
|
278 |
qemu_fdt_add_subnode(vbi->fdt, nodename);
|
|
279 | 279 |
/* Note that we can't use setprop_string because of the embedded NUL */ |
280 |
qemu_devtree_setprop(vbi->fdt, nodename, "compatible",
|
|
280 |
qemu_fdt_setprop(vbi->fdt, nodename, "compatible",
|
|
281 | 281 |
compat, sizeof(compat)); |
282 |
qemu_devtree_setprop_sized_cells(vbi->fdt, nodename, "reg",
|
|
282 |
qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
|
|
283 | 283 |
2, base, 2, size); |
284 |
qemu_devtree_setprop_cells(vbi->fdt, nodename, "interrupts",
|
|
284 |
qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
|
|
285 | 285 |
GIC_FDT_IRQ_TYPE_SPI, irq, |
286 | 286 |
GIC_FDT_IRQ_FLAGS_EDGE_LO_HI); |
287 |
qemu_devtree_setprop_cells(vbi->fdt, nodename, "clocks",
|
|
287 |
qemu_fdt_setprop_cells(vbi->fdt, nodename, "clocks",
|
|
288 | 288 |
vbi->clock_phandle, vbi->clock_phandle); |
289 |
qemu_devtree_setprop(vbi->fdt, nodename, "clock-names",
|
|
289 |
qemu_fdt_setprop(vbi->fdt, nodename, "clock-names",
|
|
290 | 290 |
clocknames, sizeof(clocknames)); |
291 | 291 |
g_free(nodename); |
292 | 292 |
} |
... | ... | |
314 | 314 |
hwaddr base = vbi->memmap[VIRT_MMIO].base + i * size; |
315 | 315 |
|
316 | 316 |
nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, base); |
317 |
qemu_devtree_add_subnode(vbi->fdt, nodename);
|
|
318 |
qemu_devtree_setprop_string(vbi->fdt, nodename,
|
|
319 |
"compatible", "virtio,mmio");
|
|
320 |
qemu_devtree_setprop_sized_cells(vbi->fdt, nodename, "reg",
|
|
321 |
2, base, 2, size);
|
|
322 |
qemu_devtree_setprop_cells(vbi->fdt, nodename, "interrupts",
|
|
323 |
GIC_FDT_IRQ_TYPE_SPI, irq,
|
|
324 |
GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
|
|
317 |
qemu_fdt_add_subnode(vbi->fdt, nodename);
|
|
318 |
qemu_fdt_setprop_string(vbi->fdt, nodename,
|
|
319 |
"compatible", "virtio,mmio"); |
|
320 |
qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
|
|
321 |
2, base, 2, size); |
|
322 |
qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
|
|
323 |
GIC_FDT_IRQ_TYPE_SPI, irq, |
|
324 |
GIC_FDT_IRQ_FLAGS_EDGE_LO_HI); |
|
325 | 325 |
g_free(nodename); |
326 | 326 |
} |
327 | 327 |
} |
b/hw/microblaze/boot.c | ||
---|---|---|
79 | 79 |
} |
80 | 80 |
|
81 | 81 |
if (kernel_cmdline) { |
82 |
r = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
|
|
83 |
kernel_cmdline);
|
|
82 |
r = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
|
|
83 |
kernel_cmdline); |
|
84 | 84 |
if (r < 0) { |
85 | 85 |
fprintf(stderr, "couldn't set /chosen/bootargs\n"); |
86 | 86 |
} |
87 | 87 |
} |
88 | 88 |
|
89 | 89 |
if (initrd_start) { |
90 |
qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
|
|
91 |
initrd_start);
|
|
90 |
qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
|
|
91 |
initrd_start); |
|
92 | 92 |
|
93 |
qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
|
|
94 |
initrd_end);
|
|
93 |
qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
|
|
94 |
initrd_end); |
|
95 | 95 |
} |
96 | 96 |
|
97 | 97 |
cpu_physical_memory_write(addr, fdt, fdt_size); |
b/hw/ppc/e500.c | ||
---|---|---|
108 | 108 |
char ser[128]; |
109 | 109 |
|
110 | 110 |
snprintf(ser, sizeof(ser), "%s/serial@%llx", soc, offset); |
111 |
qemu_devtree_add_subnode(fdt, ser);
|
|
112 |
qemu_devtree_setprop_string(fdt, ser, "device_type", "serial");
|
|
113 |
qemu_devtree_setprop_string(fdt, ser, "compatible", "ns16550");
|
|
114 |
qemu_devtree_setprop_cells(fdt, ser, "reg", offset, 0x100);
|
|
115 |
qemu_devtree_setprop_cell(fdt, ser, "cell-index", idx);
|
|
116 |
qemu_devtree_setprop_cell(fdt, ser, "clock-frequency", 0);
|
|
117 |
qemu_devtree_setprop_cells(fdt, ser, "interrupts", 42, 2);
|
|
118 |
qemu_devtree_setprop_phandle(fdt, ser, "interrupt-parent", mpic);
|
|
119 |
qemu_devtree_setprop_string(fdt, "/aliases", alias, ser);
|
|
111 |
qemu_fdt_add_subnode(fdt, ser);
|
|
112 |
qemu_fdt_setprop_string(fdt, ser, "device_type", "serial");
|
|
113 |
qemu_fdt_setprop_string(fdt, ser, "compatible", "ns16550");
|
|
114 |
qemu_fdt_setprop_cells(fdt, ser, "reg", offset, 0x100);
|
|
115 |
qemu_fdt_setprop_cell(fdt, ser, "cell-index", idx);
|
|
116 |
qemu_fdt_setprop_cell(fdt, ser, "clock-frequency", 0);
|
|
117 |
qemu_fdt_setprop_cells(fdt, ser, "interrupts", 42, 2);
|
|
118 |
qemu_fdt_setprop_phandle(fdt, ser, "interrupt-parent", mpic);
|
|
119 |
qemu_fdt_setprop_string(fdt, "/aliases", alias, ser);
|
|
120 | 120 |
|
121 | 121 |
if (defcon) { |
122 |
qemu_devtree_setprop_string(fdt, "/chosen", "linux,stdout-path", ser);
|
|
122 |
qemu_fdt_setprop_string(fdt, "/chosen", "linux,stdout-path", ser);
|
|
123 | 123 |
} |
124 | 124 |
} |
125 | 125 |
|
... | ... | |
183 | 183 |
} |
184 | 184 |
|
185 | 185 |
/* Manipulate device tree in memory. */ |
186 |
qemu_devtree_setprop_cell(fdt, "/", "#address-cells", 2);
|
|
187 |
qemu_devtree_setprop_cell(fdt, "/", "#size-cells", 2);
|
|
186 |
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 2);
|
|
187 |
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 2);
|
|
188 | 188 |
|
189 |
qemu_devtree_add_subnode(fdt, "/memory");
|
|
190 |
qemu_devtree_setprop_string(fdt, "/memory", "device_type", "memory");
|
|
191 |
qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
|
|
192 |
sizeof(mem_reg_property));
|
|
189 |
qemu_fdt_add_subnode(fdt, "/memory");
|
|
190 |
qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
|
|
191 |
qemu_fdt_setprop(fdt, "/memory", "reg", mem_reg_property,
|
|
192 |
sizeof(mem_reg_property)); |
|
193 | 193 |
|
194 |
qemu_devtree_add_subnode(fdt, "/chosen");
|
|
194 |
qemu_fdt_add_subnode(fdt, "/chosen");
|
|
195 | 195 |
if (initrd_size) { |
196 |
ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
|
|
197 |
initrd_base);
|
|
196 |
ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
|
|
197 |
initrd_base); |
|
198 | 198 |
if (ret < 0) { |
199 | 199 |
fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n"); |
200 | 200 |
} |
201 | 201 |
|
202 |
ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
|
|
203 |
(initrd_base + initrd_size));
|
|
202 |
ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
|
|
203 |
(initrd_base + initrd_size)); |
|
204 | 204 |
if (ret < 0) { |
205 | 205 |
fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n"); |
206 | 206 |
} |
207 | 207 |
} |
208 | 208 |
|
209 |
ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
|
|
209 |
ret = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
|
|
210 | 210 |
args->kernel_cmdline); |
211 | 211 |
if (ret < 0) |
212 | 212 |
fprintf(stderr, "couldn't set /chosen/bootargs\n"); |
... | ... | |
217 | 217 |
tb_freq = kvmppc_get_tbfreq(); |
218 | 218 |
|
219 | 219 |
/* indicate KVM hypercall interface */ |
220 |
qemu_devtree_add_subnode(fdt, "/hypervisor");
|
|
221 |
qemu_devtree_setprop_string(fdt, "/hypervisor", "compatible",
|
|
222 |
"linux,kvm");
|
|
220 |
qemu_fdt_add_subnode(fdt, "/hypervisor");
|
|
221 |
qemu_fdt_setprop_string(fdt, "/hypervisor", "compatible",
|
|
222 |
"linux,kvm"); |
|
223 | 223 |
kvmppc_get_hypercall(env, hypercall, sizeof(hypercall)); |
224 |
qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions",
|
|
225 |
hypercall, sizeof(hypercall));
|
|
224 |
qemu_fdt_setprop(fdt, "/hypervisor", "hcall-instructions",
|
|
225 |
hypercall, sizeof(hypercall)); |
|
226 | 226 |
/* if KVM supports the idle hcall, set property indicating this */ |
227 | 227 |
if (kvmppc_get_hasidle(env)) { |
228 |
qemu_devtree_setprop(fdt, "/hypervisor", "has-idle", NULL, 0);
|
|
228 |
qemu_fdt_setprop(fdt, "/hypervisor", "has-idle", NULL, 0);
|
|
229 | 229 |
} |
230 | 230 |
} |
231 | 231 |
|
232 | 232 |
/* Create CPU nodes */ |
233 |
qemu_devtree_add_subnode(fdt, "/cpus");
|
|
234 |
qemu_devtree_setprop_cell(fdt, "/cpus", "#address-cells", 1);
|
|
235 |
qemu_devtree_setprop_cell(fdt, "/cpus", "#size-cells", 0);
|
|
233 |
qemu_fdt_add_subnode(fdt, "/cpus");
|
|
234 |
qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 1);
|
|
235 |
qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0);
|
|
236 | 236 |
|
237 | 237 |
/* We need to generate the cpu nodes in reverse order, so Linux can pick |
238 | 238 |
the first node as boot node and be happy */ |
... | ... | |
249 | 249 |
|
250 | 250 |
snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", |
251 | 251 |
cpu->cpu_index); |
252 |
qemu_devtree_add_subnode(fdt, cpu_name);
|
|
253 |
qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
|
|
254 |
qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
|
|
255 |
qemu_devtree_setprop_string(fdt, cpu_name, "device_type", "cpu");
|
|
256 |
qemu_devtree_setprop_cell(fdt, cpu_name, "reg", cpu->cpu_index);
|
|
257 |
qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-line-size",
|
|
258 |
env->dcache_line_size);
|
|
259 |
qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-line-size",
|
|
260 |
env->icache_line_size);
|
|
261 |
qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-size", 0x8000);
|
|
262 |
qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-size", 0x8000);
|
|
263 |
qemu_devtree_setprop_cell(fdt, cpu_name, "bus-frequency", 0);
|
|
252 |
qemu_fdt_add_subnode(fdt, cpu_name);
|
|
253 |
qemu_fdt_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
|
|
254 |
qemu_fdt_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
|
|
255 |
qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
|
|
256 |
qemu_fdt_setprop_cell(fdt, cpu_name, "reg", cpu->cpu_index);
|
|
257 |
qemu_fdt_setprop_cell(fdt, cpu_name, "d-cache-line-size",
|
|
258 |
env->dcache_line_size); |
|
259 |
qemu_fdt_setprop_cell(fdt, cpu_name, "i-cache-line-size",
|
|
260 |
env->icache_line_size); |
|
261 |
qemu_fdt_setprop_cell(fdt, cpu_name, "d-cache-size", 0x8000);
|
|
262 |
qemu_fdt_setprop_cell(fdt, cpu_name, "i-cache-size", 0x8000);
|
|
263 |
qemu_fdt_setprop_cell(fdt, cpu_name, "bus-frequency", 0);
|
|
264 | 264 |
if (cpu->cpu_index) { |
265 |
qemu_devtree_setprop_string(fdt, cpu_name, "status", "disabled"); |
|
266 |
qemu_devtree_setprop_string(fdt, cpu_name, "enable-method", "spin-table"); |
|
267 |
qemu_devtree_setprop_u64(fdt, cpu_name, "cpu-release-addr", |
|
268 |
cpu_release_addr); |
|
265 |
qemu_fdt_setprop_string(fdt, cpu_name, "status", "disabled"); |
|
266 |
qemu_fdt_setprop_string(fdt, cpu_name, "enable-method", |
|
267 |
"spin-table"); |
|
268 |
qemu_fdt_setprop_u64(fdt, cpu_name, "cpu-release-addr", |
|
269 |
cpu_release_addr); |
|
269 | 270 |
} else { |
270 |
qemu_devtree_setprop_string(fdt, cpu_name, "status", "okay");
|
|
271 |
qemu_fdt_setprop_string(fdt, cpu_name, "status", "okay");
|
|
271 | 272 |
} |
272 | 273 |
} |
273 | 274 |
|
274 |
qemu_devtree_add_subnode(fdt, "/aliases");
|
|
275 |
qemu_fdt_add_subnode(fdt, "/aliases");
|
|
275 | 276 |
/* XXX These should go into their respective devices' code */ |
276 | 277 |
snprintf(soc, sizeof(soc), "/soc@%llx", MPC8544_CCSRBAR_BASE); |
277 |
qemu_devtree_add_subnode(fdt, soc);
|
|
278 |
qemu_devtree_setprop_string(fdt, soc, "device_type", "soc");
|
|
279 |
qemu_devtree_setprop(fdt, soc, "compatible", compatible_sb,
|
|
280 |
sizeof(compatible_sb));
|
|
281 |
qemu_devtree_setprop_cell(fdt, soc, "#address-cells", 1);
|
|
282 |
qemu_devtree_setprop_cell(fdt, soc, "#size-cells", 1);
|
|
283 |
qemu_devtree_setprop_cells(fdt, soc, "ranges", 0x0,
|
|
284 |
MPC8544_CCSRBAR_BASE >> 32, MPC8544_CCSRBAR_BASE,
|
|
285 |
MPC8544_CCSRBAR_SIZE);
|
|
278 |
qemu_fdt_add_subnode(fdt, soc);
|
|
279 |
qemu_fdt_setprop_string(fdt, soc, "device_type", "soc");
|
|
280 |
qemu_fdt_setprop(fdt, soc, "compatible", compatible_sb,
|
|
281 |
sizeof(compatible_sb)); |
|
282 |
qemu_fdt_setprop_cell(fdt, soc, "#address-cells", 1);
|
|
283 |
qemu_fdt_setprop_cell(fdt, soc, "#size-cells", 1);
|
|
284 |
qemu_fdt_setprop_cells(fdt, soc, "ranges", 0x0,
|
|
285 |
MPC8544_CCSRBAR_BASE >> 32, MPC8544_CCSRBAR_BASE, |
|
286 |
MPC8544_CCSRBAR_SIZE); |
|
286 | 287 |
/* XXX should contain a reasonable value */ |
287 |
qemu_devtree_setprop_cell(fdt, soc, "bus-frequency", 0);
|
|
288 |
qemu_fdt_setprop_cell(fdt, soc, "bus-frequency", 0);
|
|
288 | 289 |
|
289 | 290 |
snprintf(mpic, sizeof(mpic), "%s/pic@%llx", soc, MPC8544_MPIC_REGS_OFFSET); |
290 |
qemu_devtree_add_subnode(fdt, mpic);
|
|
291 |
qemu_devtree_setprop_string(fdt, mpic, "device_type", "open-pic");
|
|
292 |
qemu_devtree_setprop_string(fdt, mpic, "compatible", "fsl,mpic");
|
|
293 |
qemu_devtree_setprop_cells(fdt, mpic, "reg", MPC8544_MPIC_REGS_OFFSET,
|
|
294 |
0x40000);
|
|
295 |
qemu_devtree_setprop_cell(fdt, mpic, "#address-cells", 0);
|
|
296 |
qemu_devtree_setprop_cell(fdt, mpic, "#interrupt-cells", 2);
|
|
297 |
mpic_ph = qemu_devtree_alloc_phandle(fdt);
|
|
298 |
qemu_devtree_setprop_cell(fdt, mpic, "phandle", mpic_ph);
|
|
299 |
qemu_devtree_setprop_cell(fdt, mpic, "linux,phandle", mpic_ph);
|
|
300 |
qemu_devtree_setprop(fdt, mpic, "interrupt-controller", NULL, 0);
|
|
291 |
qemu_fdt_add_subnode(fdt, mpic);
|
|
292 |
qemu_fdt_setprop_string(fdt, mpic, "device_type", "open-pic");
|
|
293 |
qemu_fdt_setprop_string(fdt, mpic, "compatible", "fsl,mpic");
|
|
294 |
qemu_fdt_setprop_cells(fdt, mpic, "reg", MPC8544_MPIC_REGS_OFFSET,
|
|
295 |
0x40000); |
|
296 |
qemu_fdt_setprop_cell(fdt, mpic, "#address-cells", 0);
|
|
297 |
qemu_fdt_setprop_cell(fdt, mpic, "#interrupt-cells", 2);
|
|
298 |
mpic_ph = qemu_fdt_alloc_phandle(fdt);
|
|
299 |
qemu_fdt_setprop_cell(fdt, mpic, "phandle", mpic_ph);
|
|
300 |
qemu_fdt_setprop_cell(fdt, mpic, "linux,phandle", mpic_ph);
|
|
301 |
qemu_fdt_setprop(fdt, mpic, "interrupt-controller", NULL, 0);
|
|
301 | 302 |
|
302 | 303 |
/* |
303 | 304 |
* We have to generate ser1 first, because Linux takes the first |
... | ... | |
311 | 312 |
|
312 | 313 |
snprintf(gutil, sizeof(gutil), "%s/global-utilities@%llx", soc, |
313 | 314 |
MPC8544_UTIL_OFFSET); |
314 |
qemu_devtree_add_subnode(fdt, gutil);
|
|
315 |
qemu_devtree_setprop_string(fdt, gutil, "compatible", "fsl,mpc8544-guts");
|
|
316 |
qemu_devtree_setprop_cells(fdt, gutil, "reg", MPC8544_UTIL_OFFSET, 0x1000);
|
|
317 |
qemu_devtree_setprop(fdt, gutil, "fsl,has-rstcr", NULL, 0);
|
|
315 |
qemu_fdt_add_subnode(fdt, gutil);
|
|
316 |
qemu_fdt_setprop_string(fdt, gutil, "compatible", "fsl,mpc8544-guts");
|
|
317 |
qemu_fdt_setprop_cells(fdt, gutil, "reg", MPC8544_UTIL_OFFSET, 0x1000);
|
|
318 |
qemu_fdt_setprop(fdt, gutil, "fsl,has-rstcr", NULL, 0);
|
|
318 | 319 |
|
319 | 320 |
snprintf(msi, sizeof(msi), "/%s/msi@%llx", soc, MPC8544_MSI_REGS_OFFSET); |
320 |
qemu_devtree_add_subnode(fdt, msi);
|
|
321 |
qemu_devtree_setprop_string(fdt, msi, "compatible", "fsl,mpic-msi");
|
|
322 |
qemu_devtree_setprop_cells(fdt, msi, "reg", MPC8544_MSI_REGS_OFFSET, 0x200);
|
|
323 |
msi_ph = qemu_devtree_alloc_phandle(fdt);
|
|
324 |
qemu_devtree_setprop_cells(fdt, msi, "msi-available-ranges", 0x0, 0x100);
|
|
325 |
qemu_devtree_setprop_phandle(fdt, msi, "interrupt-parent", mpic);
|
|
326 |
qemu_devtree_setprop_cells(fdt, msi, "interrupts",
|
|
321 |
qemu_fdt_add_subnode(fdt, msi);
|
|
322 |
qemu_fdt_setprop_string(fdt, msi, "compatible", "fsl,mpic-msi");
|
|
323 |
qemu_fdt_setprop_cells(fdt, msi, "reg", MPC8544_MSI_REGS_OFFSET, 0x200);
|
|
324 |
msi_ph = qemu_fdt_alloc_phandle(fdt);
|
|
325 |
qemu_fdt_setprop_cells(fdt, msi, "msi-available-ranges", 0x0, 0x100);
|
|
326 |
qemu_fdt_setprop_phandle(fdt, msi, "interrupt-parent", mpic);
|
|
327 |
qemu_fdt_setprop_cells(fdt, msi, "interrupts",
|
|
327 | 328 |
0xe0, 0x0, |
328 | 329 |
0xe1, 0x0, |
329 | 330 |
0xe2, 0x0, |
... | ... | |
332 | 333 |
0xe5, 0x0, |
333 | 334 |
0xe6, 0x0, |
334 | 335 |
0xe7, 0x0); |
335 |
qemu_devtree_setprop_cell(fdt, msi, "phandle", msi_ph);
|
|
336 |
qemu_devtree_setprop_cell(fdt, msi, "linux,phandle", msi_ph);
|
|
336 |
qemu_fdt_setprop_cell(fdt, msi, "phandle", msi_ph);
|
|
337 |
qemu_fdt_setprop_cell(fdt, msi, "linux,phandle", msi_ph);
|
|
337 | 338 |
|
338 | 339 |
snprintf(pci, sizeof(pci), "/pci@%llx", MPC8544_PCI_REGS_BASE); |
339 |
qemu_devtree_add_subnode(fdt, pci);
|
|
340 |
qemu_devtree_setprop_cell(fdt, pci, "cell-index", 0);
|
|
341 |
qemu_devtree_setprop_string(fdt, pci, "compatible", "fsl,mpc8540-pci");
|
|
342 |
qemu_devtree_setprop_string(fdt, pci, "device_type", "pci");
|
|
343 |
qemu_devtree_setprop_cells(fdt, pci, "interrupt-map-mask", 0xf800, 0x0,
|
|
344 |
0x0, 0x7);
|
|
345 |
pci_map = pci_map_create(fdt, qemu_devtree_get_phandle(fdt, mpic),
|
|
340 |
qemu_fdt_add_subnode(fdt, pci);
|
|
341 |
qemu_fdt_setprop_cell(fdt, pci, "cell-index", 0);
|
|
342 |
qemu_fdt_setprop_string(fdt, pci, "compatible", "fsl,mpc8540-pci");
|
|
343 |
qemu_fdt_setprop_string(fdt, pci, "device_type", "pci");
|
|
344 |
qemu_fdt_setprop_cells(fdt, pci, "interrupt-map-mask", 0xf800, 0x0,
|
|
345 |
0x0, 0x7); |
|
346 |
pci_map = pci_map_create(fdt, qemu_fdt_get_phandle(fdt, mpic),
|
|
346 | 347 |
params->pci_first_slot, params->pci_nr_slots, |
347 | 348 |
&len); |
348 |
qemu_devtree_setprop(fdt, pci, "interrupt-map", pci_map, len);
|
|
349 |
qemu_devtree_setprop_phandle(fdt, pci, "interrupt-parent", mpic);
|
|
350 |
qemu_devtree_setprop_cells(fdt, pci, "interrupts", 24, 2);
|
|
351 |
qemu_devtree_setprop_cells(fdt, pci, "bus-range", 0, 255);
|
|
349 |
qemu_fdt_setprop(fdt, pci, "interrupt-map", pci_map, len);
|
|
350 |
qemu_fdt_setprop_phandle(fdt, pci, "interrupt-parent", mpic);
|
|
351 |
qemu_fdt_setprop_cells(fdt, pci, "interrupts", 24, 2);
|
|
352 |
qemu_fdt_setprop_cells(fdt, pci, "bus-range", 0, 255);
|
|
352 | 353 |
for (i = 0; i < 14; i++) { |
353 | 354 |
pci_ranges[i] = cpu_to_be32(pci_ranges[i]); |
354 | 355 |
} |
355 |
qemu_devtree_setprop_cell(fdt, pci, "fsl,msi", msi_ph);
|
|
356 |
qemu_devtree_setprop(fdt, pci, "ranges", pci_ranges, sizeof(pci_ranges));
|
|
357 |
qemu_devtree_setprop_cells(fdt, pci, "reg", MPC8544_PCI_REGS_BASE >> 32,
|
|
358 |
MPC8544_PCI_REGS_BASE, 0, 0x1000);
|
|
359 |
qemu_devtree_setprop_cell(fdt, pci, "clock-frequency", 66666666);
|
|
360 |
qemu_devtree_setprop_cell(fdt, pci, "#interrupt-cells", 1);
|
|
361 |
qemu_devtree_setprop_cell(fdt, pci, "#size-cells", 2);
|
|
362 |
qemu_devtree_setprop_cell(fdt, pci, "#address-cells", 3);
|
|
363 |
qemu_devtree_setprop_string(fdt, "/aliases", "pci0", pci);
|
|
356 |
qemu_fdt_setprop_cell(fdt, pci, "fsl,msi", msi_ph);
|
|
357 |
qemu_fdt_setprop(fdt, pci, "ranges", pci_ranges, sizeof(pci_ranges));
|
|
358 |
qemu_fdt_setprop_cells(fdt, pci, "reg", MPC8544_PCI_REGS_BASE >> 32,
|
|
359 |
MPC8544_PCI_REGS_BASE, 0, 0x1000); |
|
360 |
qemu_fdt_setprop_cell(fdt, pci, "clock-frequency", 66666666);
|
|
361 |
qemu_fdt_setprop_cell(fdt, pci, "#interrupt-cells", 1);
|
|
362 |
qemu_fdt_setprop_cell(fdt, pci, "#size-cells", 2);
|
|
363 |
qemu_fdt_setprop_cell(fdt, pci, "#address-cells", 3);
|
|
364 |
qemu_fdt_setprop_string(fdt, "/aliases", "pci0", pci);
|
|
364 | 365 |
|
365 | 366 |
params->fixup_devtree(params, fdt); |
366 | 367 |
|
367 | 368 |
if (toplevel_compat) { |
368 |
qemu_devtree_setprop(fdt, "/", "compatible", toplevel_compat,
|
|
369 |
strlen(toplevel_compat) + 1);
|
|
369 |
qemu_fdt_setprop(fdt, "/", "compatible", toplevel_compat,
|
|
370 |
strlen(toplevel_compat) + 1); |
|
370 | 371 |
} |
371 | 372 |
|
372 | 373 |
done: |
373 | 374 |
if (!dry_run) { |
374 |
qemu_devtree_dumpdtb(fdt, fdt_size);
|
|
375 |
qemu_fdt_dumpdtb(fdt, fdt_size);
|
|
375 | 376 |
cpu_physical_memory_write(addr, fdt, fdt_size); |
376 | 377 |
} |
377 | 378 |
ret = fdt_size; |
b/hw/ppc/e500plat.c | ||
---|---|---|
23 | 23 |
const char model[] = "QEMU ppce500"; |
24 | 24 |
const char compatible[] = "fsl,qemu-e500"; |
25 | 25 |
|
26 |
qemu_devtree_setprop(fdt, "/", "model", model, sizeof(model));
|
|
27 |
qemu_devtree_setprop(fdt, "/", "compatible", compatible,
|
|
28 |
sizeof(compatible));
|
|
26 |
qemu_fdt_setprop(fdt, "/", "model", model, sizeof(model));
|
|
27 |
qemu_fdt_setprop(fdt, "/", "compatible", compatible,
|
|
28 |
sizeof(compatible)); |
|
29 | 29 |
} |
30 | 30 |
|
31 | 31 |
static void e500plat_init(QEMUMachineInitArgs *args) |
b/hw/ppc/mpc8544ds.c | ||
---|---|---|
21 | 21 |
const char model[] = "MPC8544DS"; |
22 | 22 |
const char compatible[] = "MPC8544DS\0MPC85xxDS"; |
23 | 23 |
|
24 |
qemu_devtree_setprop(fdt, "/", "model", model, sizeof(model));
|
|
25 |
qemu_devtree_setprop(fdt, "/", "compatible", compatible,
|
|
26 |
sizeof(compatible));
|
|
24 |
qemu_fdt_setprop(fdt, "/", "model", model, sizeof(model));
|
|
25 |
qemu_fdt_setprop(fdt, "/", "compatible", compatible,
|
|
26 |
sizeof(compatible)); |
|
27 | 27 |
} |
28 | 28 |
|
29 | 29 |
static void mpc8544ds_init(QEMUMachineInitArgs *args) |
b/hw/ppc/ppc440_bamboo.c | ||
---|---|---|
77 | 77 |
|
78 | 78 |
/* Manipulate device tree in memory. */ |
79 | 79 |
|
80 |
ret = qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
|
|
81 |
sizeof(mem_reg_property));
|
|
80 |
ret = qemu_fdt_setprop(fdt, "/memory", "reg", mem_reg_property,
|
|
81 |
sizeof(mem_reg_property)); |
|
82 | 82 |
if (ret < 0) |
83 | 83 |
fprintf(stderr, "couldn't set /memory/reg\n"); |
84 | 84 |
|
85 |
ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
|
|
86 |
initrd_base);
|
|
85 |
ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
|
|
86 |
initrd_base); |
|
87 | 87 |
if (ret < 0) |
88 | 88 |
fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n"); |
89 | 89 |
|
90 |
ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
|
|
91 |
(initrd_base + initrd_size));
|
|
90 |
ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
|
|
91 |
(initrd_base + initrd_size)); |
|
92 | 92 |
if (ret < 0) |
93 | 93 |
fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n"); |
94 | 94 |
|
95 |
ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
|
|
96 |
kernel_cmdline);
|
|
95 |
ret = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
|
|
96 |
kernel_cmdline); |
|
97 | 97 |
if (ret < 0) |
98 | 98 |
fprintf(stderr, "couldn't set /chosen/bootargs\n"); |
99 | 99 |
|
... | ... | |
105 | 105 |
clock_freq = kvmppc_get_clockfreq(); |
106 | 106 |
} |
107 | 107 |
|
108 |
qemu_devtree_setprop_cell(fdt, "/cpus/cpu@0", "clock-frequency",
|
|
109 |
clock_freq);
|
|
110 |
qemu_devtree_setprop_cell(fdt, "/cpus/cpu@0", "timebase-frequency",
|
|
111 |
tb_freq);
|
|
108 |
qemu_fdt_setprop_cell(fdt, "/cpus/cpu@0", "clock-frequency",
|
|
109 |
clock_freq); |
|
110 |
qemu_fdt_setprop_cell(fdt, "/cpus/cpu@0", "timebase-frequency",
|
|
111 |
tb_freq); |
|
112 | 112 |
|
113 | 113 |
rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr); |
114 | 114 |
g_free(fdt); |
b/hw/ppc/spapr_rtas.c | ||
---|---|---|
334 | 334 |
return ret; |
335 | 335 |
} |
336 | 336 |
|
337 |
ret = qemu_devtree_setprop_cell(fdt, "/rtas", "linux,rtas-base",
|
|
338 |
rtas_addr);
|
|
337 |
ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-base",
|
|
338 |
rtas_addr); |
|
339 | 339 |
if (ret < 0) { |
340 | 340 |
fprintf(stderr, "Couldn't add linux,rtas-base property: %s\n", |
341 | 341 |
fdt_strerror(ret)); |
342 | 342 |
return ret; |
343 | 343 |
} |
344 | 344 |
|
345 |
ret = qemu_devtree_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
|
|
346 |
rtas_addr);
|
|
345 |
ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
|
|
346 |
rtas_addr); |
|
347 | 347 |
if (ret < 0) { |
348 | 348 |
fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n", |
349 | 349 |
fdt_strerror(ret)); |
350 | 350 |
return ret; |
351 | 351 |
} |
352 | 352 |
|
353 |
ret = qemu_devtree_setprop_cell(fdt, "/rtas", "rtas-size",
|
|
354 |
rtas_size);
|
|
353 |
ret = qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-size",
|
|
354 |
rtas_size); |
|
355 | 355 |
if (ret < 0) { |
356 | 356 |
fprintf(stderr, "Couldn't add rtas-size property: %s\n", |
357 | 357 |
fdt_strerror(ret)); |
... | ... | |
365 | 365 |
continue; |
366 | 366 |
} |
367 | 367 |
|
368 |
ret = qemu_devtree_setprop_cell(fdt, "/rtas", call->name,
|
|
369 |
i + TOKEN_BASE);
|
|
368 |
ret = qemu_fdt_setprop_cell(fdt, "/rtas", call->name,
|
|
369 |
i + TOKEN_BASE); |
|
370 | 370 |
if (ret < 0) { |
371 | 371 |
fprintf(stderr, "Couldn't add rtas token for %s: %s\n", |
372 | 372 |
call->name, fdt_strerror(ret)); |
b/hw/ppc/virtex_ml507.c | ||
---|---|---|
166 | 166 |
if (!fdt) { |
167 | 167 |
return 0; |
168 | 168 |
} |
169 |
r = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs", kernel_cmdline);
|
|
169 |
r = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", kernel_cmdline);
|
|
170 | 170 |
if (r < 0) |
171 | 171 |
fprintf(stderr, "couldn't set /chosen/bootargs\n"); |
172 | 172 |
cpu_physical_memory_write(addr, fdt, fdt_size); |
b/include/sysemu/device_tree.h | ||
---|---|---|
17 | 17 |
void *create_device_tree(int *sizep); |
18 | 18 |
void *load_device_tree(const char *filename_path, int *sizep); |
19 | 19 |
|
20 |
int qemu_devtree_setprop(void *fdt, const char *node_path,
|
|
21 |
const char *property, const void *val_array, int size);
|
|
22 |
int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
|
|
23 |
const char *property, uint32_t val);
|
|
24 |
int qemu_devtree_setprop_u64(void *fdt, const char *node_path,
|
|
25 |
const char *property, uint64_t val);
|
|
26 |
int qemu_devtree_setprop_string(void *fdt, const char *node_path,
|
|
27 |
const char *property, const char *string);
|
|
28 |
int qemu_devtree_setprop_phandle(void *fdt, const char *node_path,
|
|
29 |
const char *property,
|
|
30 |
const char *target_node_path);
|
|
31 |
const void *qemu_devtree_getprop(void *fdt, const char *node_path,
|
|
32 |
const char *property, int *lenp);
|
|
33 |
uint32_t qemu_devtree_getprop_cell(void *fdt, const char *node_path,
|
|
34 |
const char *property);
|
|
35 |
uint32_t qemu_devtree_get_phandle(void *fdt, const char *path);
|
|
36 |
uint32_t qemu_devtree_alloc_phandle(void *fdt);
|
|
37 |
int qemu_devtree_nop_node(void *fdt, const char *node_path);
|
|
38 |
int qemu_devtree_add_subnode(void *fdt, const char *name);
|
|
20 |
int qemu_fdt_setprop(void *fdt, const char *node_path,
|
|
21 |
const char *property, const void *val_array, int size); |
|
22 |
int qemu_fdt_setprop_cell(void *fdt, const char *node_path,
|
|
23 |
const char *property, uint32_t val); |
|
24 |
int qemu_fdt_setprop_u64(void *fdt, const char *node_path,
|
|
25 |
const char *property, uint64_t val); |
|
26 |
int qemu_fdt_setprop_string(void *fdt, const char *node_path,
|
|
27 |
const char *property, const char *string); |
|
28 |
int qemu_fdt_setprop_phandle(void *fdt, const char *node_path,
|
|
29 |
const char *property, |
|
30 |
const char *target_node_path); |
|
31 |
const void *qemu_fdt_getprop(void *fdt, const char *node_path,
|
|
32 |
const char *property, int *lenp); |
|
33 |
uint32_t qemu_fdt_getprop_cell(void *fdt, const char *node_path,
|
|
34 |
const char *property); |
|
35 |
uint32_t qemu_fdt_get_phandle(void *fdt, const char *path);
|
|
36 |
uint32_t qemu_fdt_alloc_phandle(void *fdt);
|
|
37 |
int qemu_fdt_nop_node(void *fdt, const char *node_path);
|
|
38 |
int qemu_fdt_add_subnode(void *fdt, const char *name);
|
|
39 | 39 |
|
40 |
#define qemu_devtree_setprop_cells(fdt, node_path, property, ...) \
|
|
40 |
#define qemu_fdt_setprop_cells(fdt, node_path, property, ...) \
|
|
41 | 41 |
do { \ |
42 | 42 |
uint32_t qdt_tmp[] = { __VA_ARGS__ }; \ |
43 | 43 |
int i; \ |
... | ... | |
45 | 45 |
for (i = 0; i < ARRAY_SIZE(qdt_tmp); i++) { \ |
46 | 46 |
qdt_tmp[i] = cpu_to_be32(qdt_tmp[i]); \ |
47 | 47 |
} \ |
48 |
qemu_devtree_setprop(fdt, node_path, property, qdt_tmp, \
|
|
49 |
sizeof(qdt_tmp)); \
|
|
48 |
qemu_fdt_setprop(fdt, node_path, property, qdt_tmp, \
|
|
49 |
sizeof(qdt_tmp)); \
|
|
50 | 50 |
} while (0) |
51 | 51 |
|
52 |
void qemu_devtree_dumpdtb(void *fdt, int size);
|
|
52 |
void qemu_fdt_dumpdtb(void *fdt, int size);
|
|
53 | 53 |
|
54 | 54 |
/** |
55 |
* qemu_devtree_setprop_sized_cells_from_array:
|
|
55 |
* qemu_fdt_setprop_sized_cells_from_array:
|
|
56 | 56 |
* @fdt: device tree blob |
57 | 57 |
* @node_path: node to set property on |
58 | 58 |
* @property: property to set |
... | ... | |
72 | 72 |
* the number of cells used for each element vary depending on the |
73 | 73 |
* #address-cells and #size-cells properties of their parent node. |
74 | 74 |
* If you know all your cell elements are one cell wide you can use the |
75 |
* simpler qemu_devtree_setprop_cells(). If you're not setting up the
|
|
76 |
* array programmatically, qemu_devtree_setprop_sized_cells may be more
|
|
75 |
* simpler qemu_fdt_setprop_cells(). If you're not setting up the
|
|
76 |
* array programmatically, qemu_fdt_setprop_sized_cells may be more
|
|
77 | 77 |
* convenient. |
78 | 78 |
* |
79 | 79 |
* Return value: 0 on success, <0 on error. |
80 | 80 |
*/ |
81 |
int qemu_devtree_setprop_sized_cells_from_array(void *fdt,
|
|
82 |
const char *node_path,
|
|
83 |
const char *property,
|
|
84 |
int numvalues,
|
|
85 |
uint64_t *values);
|
|
81 |
int qemu_fdt_setprop_sized_cells_from_array(void *fdt,
|
|
82 |
const char *node_path, |
|
83 |
const char *property, |
|
84 |
int numvalues, |
|
85 |
uint64_t *values); |
|
86 | 86 |
|
87 | 87 |
/** |
88 |
* qemu_devtree_setprop_sized_cells:
|
|
88 |
* qemu_fdt_setprop_sized_cells:
|
|
89 | 89 |
* @fdt: device tree blob |
90 | 90 |
* @node_path: node to set property on |
91 | 91 |
* @property: property to set |
... | ... | |
97 | 97 |
* used by this value" and "value". |
98 | 98 |
* |
99 | 99 |
* This is a convenience wrapper for the function |
100 |
* qemu_devtree_setprop_sized_cells_from_array().
|
|
100 |
* qemu_fdt_setprop_sized_cells_from_array().
|
|
101 | 101 |
* |
102 | 102 |
* Return value: 0 on success, <0 on error. |
103 | 103 |
*/ |
104 |
#define qemu_devtree_setprop_sized_cells(fdt, node_path, property, ...) \
|
|
105 |
({ \
|
|
106 |
uint64_t qdt_tmp[] = { __VA_ARGS__ }; \
|
|
107 |
qemu_devtree_setprop_sized_cells_from_array(fdt, node_path, \
|
|
108 |
property, \
|
|
109 |
ARRAY_SIZE(qdt_tmp) / 2, \
|
|
110 |
qdt_tmp); \
|
|
104 |
#define qemu_fdt_setprop_sized_cells(fdt, node_path, property, ...) \
|
|
105 |
({ \ |
|
106 |
uint64_t qdt_tmp[] = { __VA_ARGS__ }; \ |
|
107 |
qemu_fdt_setprop_sized_cells_from_array(fdt, node_path, \
|
|
108 |
property, \ |
|
109 |
ARRAY_SIZE(qdt_tmp) / 2, \ |
|
110 |
qdt_tmp); \ |
|
111 | 111 |
}) |
112 | 112 |
|
113 | 113 |
#endif /* __DEVICE_TREE_H__ */ |
Also available in: Unified diff