Merge remote-tracking branch 'agraf/tags/signed-ppc-for-upstream' into staging

Patch queue for ppc - 2013-12-20

Alexander Graf (3):
      PPC: Use default pci bus name for grackle and heathrow
      roms: Flush icache when writing roms to guest memory
      PPC: Add VSX to hflags

Alexey Kardashevskiy (5):
      powerpc: add PVR mask support
      target-ppc: move POWER7+ to a separate family
      spapr-rtas: replace return code constants with macros
      spapr-rtas: add ibm, (get|set)-system-parameter
      spapr: make sure RMA is in first mode of first memory node

Greg Kurz (1):
      target-ppc: add stubs for KVM breakpoints

Paolo Bonzini (1):
      spapr: tie spapr-nvram to -pflash

Paul Mackerras (1):
      spapr: limit numa memory regions by ram size

Peter Crosthwaite (2):
      device_tree: s/qemu_devtree/qemu_fdt globally
      device_tree: qemu_fdt_setprop: Rename val_array arg

Tom Musta (19):
      Declare and Enable VSX
      Add MSR VSX and Associated Exception
      Add VSX Instruction Decoders
      Add VSR to Global Registers
      Add lxvd2x
      Add stxvd2x
      Add xxpermdi
      Add lxsdx
      Add lxvdsx
      Add lxvw4x
      Add stxsdx
      Add stxvw4x
      Add VSX Scalar Move Instructions
      Add VSX Vector Move Instructions
      Add Power7 VSX Logical Instructions
      Add xxmrgh/xxmrgl
      Add xxsel
      Add xxspltw
      Add xxsldwi

* agraf/tags/signed-ppc-for-upstream: (32 commits)
  spapr: limit numa memory regions by ram size
  spapr: make sure RMA is in first mode of first memory node
  device_tree: qemu_fdt_setprop: Rename val_array arg
  device_tree: s/qemu_devtree/qemu_fdt globally
  PPC: Add VSX to hflags
  Add xxsldwi
  Add xxspltw
  Add xxsel
  Add xxmrgh/xxmrgl
  Add Power7 VSX Logical Instructions
  Add VSX Vector Move Instructions
  Add VSX Scalar Move Instructions
  roms: Flush icache when writing roms to guest memory
  spapr: tie spapr-nvram to -pflash
  PPC: Use default pci bus name for grackle and heathrow
  spapr-rtas: add ibm, (get|set)-system-parameter
  spapr-rtas: replace return code constants with macros
  target-ppc: move POWER7+ to a separate family
  Add stxvw4x
  Add stxsdx
  ...
This commit is contained in:
Anthony Liguori
2013-12-19 17:03:17 -08:00
33 changed files with 1237 additions and 387 deletions
+32 -32
View File
@@ -131,12 +131,12 @@ static int findnode_nofail(void *fdt, const char *node_path)
return offset;
}
int qemu_devtree_setprop(void *fdt, const char *node_path,
const char *property, const void *val_array, int size)
int qemu_fdt_setprop(void *fdt, const char *node_path,
const char *property, const void *val, int size)
{
int r;
r = fdt_setprop(fdt, findnode_nofail(fdt, node_path), property, val_array, size);
r = fdt_setprop(fdt, findnode_nofail(fdt, node_path), property, val, size);
if (r < 0) {
fprintf(stderr, "%s: Couldn't set %s/%s: %s\n", __func__, node_path,
property, fdt_strerror(r));
@@ -146,8 +146,8 @@ int qemu_devtree_setprop(void *fdt, const char *node_path,
return r;
}
int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
const char *property, uint32_t val)
int qemu_fdt_setprop_cell(void *fdt, const char *node_path,
const char *property, uint32_t val)
{
int r;
@@ -161,15 +161,15 @@ int qemu_devtree_setprop_cell(void *fdt, const char *node_path,
return r;
}
int qemu_devtree_setprop_u64(void *fdt, const char *node_path,
const char *property, uint64_t val)
int qemu_fdt_setprop_u64(void *fdt, const char *node_path,
const char *property, uint64_t val)
{
val = cpu_to_be64(val);
return qemu_devtree_setprop(fdt, node_path, property, &val, sizeof(val));
return qemu_fdt_setprop(fdt, node_path, property, &val, sizeof(val));
}
int qemu_devtree_setprop_string(void *fdt, const char *node_path,
const char *property, const char *string)
int qemu_fdt_setprop_string(void *fdt, const char *node_path,
const char *property, const char *string)
{
int r;
@@ -183,8 +183,8 @@ int qemu_devtree_setprop_string(void *fdt, const char *node_path,
return r;
}
const void *qemu_devtree_getprop(void *fdt, const char *node_path,
const char *property, int *lenp)
const void *qemu_fdt_getprop(void *fdt, const char *node_path,
const char *property, int *lenp)
{
int len;
const void *r;
@@ -200,11 +200,11 @@ const void *qemu_devtree_getprop(void *fdt, const char *node_path,
return r;
}
uint32_t qemu_devtree_getprop_cell(void *fdt, const char *node_path,
const char *property)
uint32_t qemu_fdt_getprop_cell(void *fdt, const char *node_path,
const char *property)
{
int len;
const uint32_t *p = qemu_devtree_getprop(fdt, node_path, property, &len);
const uint32_t *p = qemu_fdt_getprop(fdt, node_path, property, &len);
if (len != 4) {
fprintf(stderr, "%s: %s/%s not 4 bytes long (not a cell?)\n",
__func__, node_path, property);
@@ -213,7 +213,7 @@ uint32_t qemu_devtree_getprop_cell(void *fdt, const char *node_path,
return be32_to_cpu(*p);
}
uint32_t qemu_devtree_get_phandle(void *fdt, const char *path)
uint32_t qemu_fdt_get_phandle(void *fdt, const char *path)
{
uint32_t r;
@@ -227,15 +227,15 @@ uint32_t qemu_devtree_get_phandle(void *fdt, const char *path)
return r;
}
int qemu_devtree_setprop_phandle(void *fdt, const char *node_path,
const char *property,
const char *target_node_path)
int qemu_fdt_setprop_phandle(void *fdt, const char *node_path,
const char *property,
const char *target_node_path)
{
uint32_t phandle = qemu_devtree_get_phandle(fdt, target_node_path);
return qemu_devtree_setprop_cell(fdt, node_path, property, phandle);
uint32_t phandle = qemu_fdt_get_phandle(fdt, target_node_path);
return qemu_fdt_setprop_cell(fdt, node_path, property, phandle);
}
uint32_t qemu_devtree_alloc_phandle(void *fdt)
uint32_t qemu_fdt_alloc_phandle(void *fdt)
{
static int phandle = 0x0;
@@ -259,7 +259,7 @@ uint32_t qemu_devtree_alloc_phandle(void *fdt)
return phandle++;
}
int qemu_devtree_nop_node(void *fdt, const char *node_path)
int qemu_fdt_nop_node(void *fdt, const char *node_path)
{
int r;
@@ -273,7 +273,7 @@ int qemu_devtree_nop_node(void *fdt, const char *node_path)
return r;
}
int qemu_devtree_add_subnode(void *fdt, const char *name)
int qemu_fdt_add_subnode(void *fdt, const char *name)
{
char *dupname = g_strdup(name);
char *basename = strrchr(dupname, '/');
@@ -303,7 +303,7 @@ int qemu_devtree_add_subnode(void *fdt, const char *name)
return retval;
}
void qemu_devtree_dumpdtb(void *fdt, int size)
void qemu_fdt_dumpdtb(void *fdt, int size)
{
const char *dumpdtb = qemu_opt_get(qemu_get_machine_opts(), "dumpdtb");
@@ -313,11 +313,11 @@ void qemu_devtree_dumpdtb(void *fdt, int size)
}
}
int qemu_devtree_setprop_sized_cells_from_array(void *fdt,
const char *node_path,
const char *property,
int numvalues,
uint64_t *values)
int qemu_fdt_setprop_sized_cells_from_array(void *fdt,
const char *node_path,
const char *property,
int numvalues,
uint64_t *values)
{
uint32_t *propcells;
uint64_t value;
@@ -342,6 +342,6 @@ int qemu_devtree_setprop_sized_cells_from_array(void *fdt,
propcells[cellnum++] = cpu_to_be32(value);
}
return qemu_devtree_setprop(fdt, node_path, property, propcells,
cellnum * sizeof(uint32_t));
return qemu_fdt_setprop(fdt, node_path, property, propcells,
cellnum * sizeof(uint32_t));
}
+39 -5
View File
@@ -50,6 +50,7 @@
#include "translate-all.h"
#include "exec/memory-internal.h"
#include "qemu/cache-utils.h"
#include "qemu/range.h"
@@ -2070,9 +2071,13 @@ void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
address_space_rw(&address_space_memory, addr, buf, len, is_write);
}
/* used for ROM loading : can write in RAM and ROM */
void cpu_physical_memory_write_rom(hwaddr addr,
const uint8_t *buf, int len)
enum write_rom_type {
WRITE_DATA,
FLUSH_CACHE,
};
static inline void cpu_physical_memory_write_rom_internal(
hwaddr addr, const uint8_t *buf, int len, enum write_rom_type type)
{
hwaddr l;
uint8_t *ptr;
@@ -2091,8 +2096,15 @@ void cpu_physical_memory_write_rom(hwaddr addr,
addr1 += memory_region_get_ram_addr(mr);
/* ROM/RAM case */
ptr = qemu_get_ram_ptr(addr1);
memcpy(ptr, buf, l);
invalidate_and_set_dirty(addr1, l);
switch (type) {
case WRITE_DATA:
memcpy(ptr, buf, l);
invalidate_and_set_dirty(addr1, l);
break;
case FLUSH_CACHE:
flush_icache_range((uintptr_t)ptr, (uintptr_t)ptr + l);
break;
}
}
len -= l;
buf += l;
@@ -2100,6 +2112,28 @@ void cpu_physical_memory_write_rom(hwaddr addr,
}
}
/* used for ROM loading : can write in RAM and ROM */
void cpu_physical_memory_write_rom(hwaddr addr,
const uint8_t *buf, int len)
{
cpu_physical_memory_write_rom_internal(addr, buf, len, WRITE_DATA);
}
void cpu_flush_icache_range(hwaddr start, int len)
{
/*
* This function should do the same thing as an icache flush that was
* triggered from within the guest. For TCG we are always cache coherent,
* so there is no need to flush anything. For KVM / Xen we need to flush
* the host's instruction cache at least.
*/
if (tcg_enabled()) {
return;
}
cpu_physical_memory_write_rom_internal(start, NULL, len, FLUSH_CACHE);
}
typedef struct {
MemoryRegion *mr;
void *buffer;
+12 -12
View File
@@ -335,8 +335,8 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
}
}
acells = qemu_devtree_getprop_cell(fdt, "/", "#address-cells");
scells = qemu_devtree_getprop_cell(fdt, "/", "#size-cells");
acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells");
scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells");
if (acells == 0 || scells == 0) {
fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 0)\n");
goto fail;
@@ -351,17 +351,17 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
goto fail;
}
rc = qemu_devtree_setprop_sized_cells(fdt, "/memory", "reg",
acells, binfo->loader_start,
scells, binfo->ram_size);
rc = qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg",
acells, binfo->loader_start,
scells, binfo->ram_size);
if (rc < 0) {
fprintf(stderr, "couldn't set /memory/reg\n");
goto fail;
}
if (binfo->kernel_cmdline && *binfo->kernel_cmdline) {
rc = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
binfo->kernel_cmdline);
rc = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
binfo->kernel_cmdline);
if (rc < 0) {
fprintf(stderr, "couldn't set /chosen/bootargs\n");
goto fail;
@@ -369,15 +369,15 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
}
if (binfo->initrd_size) {
rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
binfo->initrd_start);
rc = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
binfo->initrd_start);
if (rc < 0) {
fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
goto fail;
}
rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
binfo->initrd_start + binfo->initrd_size);
rc = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
binfo->initrd_start + binfo->initrd_size);
if (rc < 0) {
fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
goto fail;
@@ -388,7 +388,7 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo)
binfo->modify_dtb(binfo, fdt);
}
qemu_devtree_dumpdtb(fdt, size);
qemu_fdt_dumpdtb(fdt, size);
cpu_physical_memory_write(addr, fdt, size);
+9 -9
View File
@@ -419,13 +419,13 @@ static int add_virtio_mmio_node(void *fdt, uint32_t acells, uint32_t scells,
int rc;
char *nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, addr);
rc = qemu_devtree_add_subnode(fdt, nodename);
rc |= qemu_devtree_setprop_string(fdt, nodename,
"compatible", "virtio,mmio");
rc |= qemu_devtree_setprop_sized_cells(fdt, nodename, "reg",
acells, addr, scells, size);
qemu_devtree_setprop_cells(fdt, nodename, "interrupt-parent", intc);
qemu_devtree_setprop_cells(fdt, nodename, "interrupts", 0, irq, 1);
rc = qemu_fdt_add_subnode(fdt, nodename);
rc |= qemu_fdt_setprop_string(fdt, nodename,
"compatible", "virtio,mmio");
rc |= qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
acells, addr, scells, size);
qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", intc);
qemu_fdt_setprop_cells(fdt, nodename, "interrupts", 0, irq, 1);
g_free(nodename);
if (rc) {
return -1;
@@ -456,8 +456,8 @@ static void vexpress_modify_dtb(const struct arm_boot_info *info, void *fdt)
uint32_t acells, scells, intc;
const VEDBoardInfo *daughterboard = (const VEDBoardInfo *)info;
acells = qemu_devtree_getprop_cell(fdt, "/", "#address-cells");
scells = qemu_devtree_getprop_cell(fdt, "/", "#size-cells");
acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells");
scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells");
intc = find_int_controller(fdt);
if (!intc) {
/* Not fatal, we just won't provide virtio. This will
+53 -53
View File
@@ -156,42 +156,42 @@ static void create_fdt(VirtBoardInfo *vbi)
vbi->fdt = fdt;
/* Header */
qemu_devtree_setprop_string(fdt, "/", "compatible", "linux,dummy-virt");
qemu_devtree_setprop_cell(fdt, "/", "#address-cells", 0x2);
qemu_devtree_setprop_cell(fdt, "/", "#size-cells", 0x2);
qemu_fdt_setprop_string(fdt, "/", "compatible", "linux,dummy-virt");
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
/*
* /chosen and /memory nodes must exist for load_dtb
* to fill in necessary properties later
*/
qemu_devtree_add_subnode(fdt, "/chosen");
qemu_devtree_add_subnode(fdt, "/memory");
qemu_devtree_setprop_string(fdt, "/memory", "device_type", "memory");
qemu_fdt_add_subnode(fdt, "/chosen");
qemu_fdt_add_subnode(fdt, "/memory");
qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
/* Clock node, for the benefit of the UART. The kernel device tree
* binding documentation claims the PL011 node clock properties are
* optional but in practice if you omit them the kernel refuses to
* probe for the device.
*/
vbi->clock_phandle = qemu_devtree_alloc_phandle(fdt);
qemu_devtree_add_subnode(fdt, "/apb-pclk");
qemu_devtree_setprop_string(fdt, "/apb-pclk", "compatible", "fixed-clock");
qemu_devtree_setprop_cell(fdt, "/apb-pclk", "#clock-cells", 0x0);
qemu_devtree_setprop_cell(fdt, "/apb-pclk", "clock-frequency", 24000000);
qemu_devtree_setprop_string(fdt, "/apb-pclk", "clock-output-names",
vbi->clock_phandle = qemu_fdt_alloc_phandle(fdt);
qemu_fdt_add_subnode(fdt, "/apb-pclk");
qemu_fdt_setprop_string(fdt, "/apb-pclk", "compatible", "fixed-clock");
qemu_fdt_setprop_cell(fdt, "/apb-pclk", "#clock-cells", 0x0);
qemu_fdt_setprop_cell(fdt, "/apb-pclk", "clock-frequency", 24000000);
qemu_fdt_setprop_string(fdt, "/apb-pclk", "clock-output-names",
"clk24mhz");
qemu_devtree_setprop_cell(fdt, "/apb-pclk", "phandle", vbi->clock_phandle);
qemu_fdt_setprop_cell(fdt, "/apb-pclk", "phandle", vbi->clock_phandle);
/* No PSCI for TCG yet */
if (kvm_enabled()) {
qemu_devtree_add_subnode(fdt, "/psci");
qemu_devtree_setprop_string(fdt, "/psci", "compatible", "arm,psci");
qemu_devtree_setprop_string(fdt, "/psci", "method", "hvc");
qemu_devtree_setprop_cell(fdt, "/psci", "cpu_suspend",
qemu_fdt_add_subnode(fdt, "/psci");
qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
qemu_fdt_setprop_string(fdt, "/psci", "method", "hvc");
qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend",
PSCI_FN_CPU_SUSPEND);
qemu_devtree_setprop_cell(fdt, "/psci", "cpu_off", PSCI_FN_CPU_OFF);
qemu_devtree_setprop_cell(fdt, "/psci", "cpu_on", PSCI_FN_CPU_ON);
qemu_devtree_setprop_cell(fdt, "/psci", "migrate", PSCI_FN_MIGRATE);
qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", PSCI_FN_CPU_OFF);
qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", PSCI_FN_CPU_ON);
qemu_fdt_setprop_cell(fdt, "/psci", "migrate", PSCI_FN_MIGRATE);
}
}
@@ -206,10 +206,10 @@ static void fdt_add_timer_nodes(const VirtBoardInfo *vbi)
irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
GIC_FDT_IRQ_PPI_CPU_WIDTH, (1 << vbi->smp_cpus) - 1);
qemu_devtree_add_subnode(vbi->fdt, "/timer");
qemu_devtree_setprop_string(vbi->fdt, "/timer",
qemu_fdt_add_subnode(vbi->fdt, "/timer");
qemu_fdt_setprop_string(vbi->fdt, "/timer",
"compatible", "arm,armv7-timer");
qemu_devtree_setprop_cells(vbi->fdt, "/timer", "interrupts",
qemu_fdt_setprop_cells(vbi->fdt, "/timer", "interrupts",
GIC_FDT_IRQ_TYPE_PPI, 13, irqflags,
GIC_FDT_IRQ_TYPE_PPI, 14, irqflags,
GIC_FDT_IRQ_TYPE_PPI, 11, irqflags,
@@ -220,25 +220,25 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
{
int cpu;
qemu_devtree_add_subnode(vbi->fdt, "/cpus");
qemu_devtree_setprop_cell(vbi->fdt, "/cpus", "#address-cells", 0x1);
qemu_devtree_setprop_cell(vbi->fdt, "/cpus", "#size-cells", 0x0);
qemu_fdt_add_subnode(vbi->fdt, "/cpus");
qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#address-cells", 0x1);
qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#size-cells", 0x0);
for (cpu = vbi->smp_cpus - 1; cpu >= 0; cpu--) {
char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
qemu_devtree_add_subnode(vbi->fdt, nodename);
qemu_devtree_setprop_string(vbi->fdt, nodename, "device_type", "cpu");
qemu_devtree_setprop_string(vbi->fdt, nodename, "compatible",
qemu_fdt_add_subnode(vbi->fdt, nodename);
qemu_fdt_setprop_string(vbi->fdt, nodename, "device_type", "cpu");
qemu_fdt_setprop_string(vbi->fdt, nodename, "compatible",
armcpu->dtb_compatible);
if (vbi->smp_cpus > 1) {
qemu_devtree_setprop_string(vbi->fdt, nodename,
qemu_fdt_setprop_string(vbi->fdt, nodename,
"enable-method", "psci");
}
qemu_devtree_setprop_cell(vbi->fdt, nodename, "reg", cpu);
qemu_fdt_setprop_cell(vbi->fdt, nodename, "reg", cpu);
g_free(nodename);
}
}
@@ -247,20 +247,20 @@ static void fdt_add_gic_node(const VirtBoardInfo *vbi)
{
uint32_t gic_phandle;
gic_phandle = qemu_devtree_alloc_phandle(vbi->fdt);
qemu_devtree_setprop_cell(vbi->fdt, "/", "interrupt-parent", gic_phandle);
gic_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
qemu_fdt_setprop_cell(vbi->fdt, "/", "interrupt-parent", gic_phandle);
qemu_devtree_add_subnode(vbi->fdt, "/intc");
qemu_devtree_setprop_string(vbi->fdt, "/intc", "compatible",
qemu_fdt_add_subnode(vbi->fdt, "/intc");
qemu_fdt_setprop_string(vbi->fdt, "/intc", "compatible",
vbi->gic_compatible);
qemu_devtree_setprop_cell(vbi->fdt, "/intc", "#interrupt-cells", 3);
qemu_devtree_setprop(vbi->fdt, "/intc", "interrupt-controller", NULL, 0);
qemu_devtree_setprop_sized_cells(vbi->fdt, "/intc", "reg",
qemu_fdt_setprop_cell(vbi->fdt, "/intc", "#interrupt-cells", 3);
qemu_fdt_setprop(vbi->fdt, "/intc", "interrupt-controller", NULL, 0);
qemu_fdt_setprop_sized_cells(vbi->fdt, "/intc", "reg",
2, vbi->memmap[VIRT_GIC_DIST].base,
2, vbi->memmap[VIRT_GIC_DIST].size,
2, vbi->memmap[VIRT_GIC_CPU].base,
2, vbi->memmap[VIRT_GIC_CPU].size);
qemu_devtree_setprop_cell(vbi->fdt, "/intc", "phandle", gic_phandle);
qemu_fdt_setprop_cell(vbi->fdt, "/intc", "phandle", gic_phandle);
}
static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
@@ -275,18 +275,18 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic)
sysbus_create_simple("pl011", base, pic[irq]);
nodename = g_strdup_printf("/pl011@%" PRIx64, base);
qemu_devtree_add_subnode(vbi->fdt, nodename);
qemu_fdt_add_subnode(vbi->fdt, nodename);
/* Note that we can't use setprop_string because of the embedded NUL */
qemu_devtree_setprop(vbi->fdt, nodename, "compatible",
qemu_fdt_setprop(vbi->fdt, nodename, "compatible",
compat, sizeof(compat));
qemu_devtree_setprop_sized_cells(vbi->fdt, nodename, "reg",
qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
2, base, 2, size);
qemu_devtree_setprop_cells(vbi->fdt, nodename, "interrupts",
qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
GIC_FDT_IRQ_TYPE_SPI, irq,
GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
qemu_devtree_setprop_cells(vbi->fdt, nodename, "clocks",
qemu_fdt_setprop_cells(vbi->fdt, nodename, "clocks",
vbi->clock_phandle, vbi->clock_phandle);
qemu_devtree_setprop(vbi->fdt, nodename, "clock-names",
qemu_fdt_setprop(vbi->fdt, nodename, "clock-names",
clocknames, sizeof(clocknames));
g_free(nodename);
}
@@ -314,14 +314,14 @@ static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic)
hwaddr base = vbi->memmap[VIRT_MMIO].base + i * size;
nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, base);
qemu_devtree_add_subnode(vbi->fdt, nodename);
qemu_devtree_setprop_string(vbi->fdt, nodename,
"compatible", "virtio,mmio");
qemu_devtree_setprop_sized_cells(vbi->fdt, nodename, "reg",
2, base, 2, size);
qemu_devtree_setprop_cells(vbi->fdt, nodename, "interrupts",
GIC_FDT_IRQ_TYPE_SPI, irq,
GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
qemu_fdt_add_subnode(vbi->fdt, nodename);
qemu_fdt_setprop_string(vbi->fdt, nodename,
"compatible", "virtio,mmio");
qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
2, base, 2, size);
qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
GIC_FDT_IRQ_TYPE_SPI, irq,
GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
g_free(nodename);
}
}
+7
View File
@@ -785,6 +785,13 @@ static void rom_reset(void *unused)
g_free(rom->data);
rom->data = NULL;
}
/*
* The rom loader is really on the same level as firmware in the guest
* shadowing a ROM into RAM. Such a shadowing mechanism needs to ensure
* that the instruction cache for that new region is clear, so that the
* CPU definitely fetches its instructions from the just written data.
*/
cpu_flush_icache_range(rom->addr, rom->datasize);
}
}
+12 -12
View File
@@ -723,7 +723,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t nr, server, priority;
if ((nargs != 3) || (nret != 1)) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
@@ -733,13 +733,13 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
if (!ics_valid_irq(ics, nr) || (server >= ics->icp->nr_servers)
|| (priority > 0xff)) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
ics_write_xive(ics, nr, server, priority, priority);
rtas_st(rets, 0, 0); /* Success */
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
static void rtas_get_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
@@ -751,18 +751,18 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t nr;
if ((nargs != 1) || (nret != 3)) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
nr = rtas_ld(args, 0);
if (!ics_valid_irq(ics, nr)) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
rtas_st(rets, 0, 0); /* Success */
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
rtas_st(rets, 1, ics->irqs[nr - ics->offset].server);
rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
}
@@ -776,21 +776,21 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t nr;
if ((nargs != 1) || (nret != 1)) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
nr = rtas_ld(args, 0);
if (!ics_valid_irq(ics, nr)) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server, 0xff,
ics->irqs[nr - ics->offset].priority);
rtas_st(rets, 0, 0); /* Success */
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
static void rtas_int_on(PowerPCCPU *cpu, sPAPREnvironment *spapr,
@@ -802,14 +802,14 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t nr;
if ((nargs != 1) || (nret != 1)) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
nr = rtas_ld(args, 0);
if (!ics_valid_irq(ics, nr)) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
@@ -817,7 +817,7 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPREnvironment *spapr,
ics->irqs[nr - ics->offset].saved_priority,
ics->irqs[nr - ics->offset].saved_priority);
rtas_st(rets, 0, 0); /* Success */
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
/*
+6 -6
View File
@@ -79,19 +79,19 @@ static int microblaze_load_dtb(hwaddr addr,
}
if (kernel_cmdline) {
r = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
kernel_cmdline);
r = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
kernel_cmdline);
if (r < 0) {
fprintf(stderr, "couldn't set /chosen/bootargs\n");
}
}
if (initrd_start) {
qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
initrd_start);
qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
initrd_start);
qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
initrd_end);
qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
initrd_end);
}
cpu_physical_memory_write(addr, fdt, fdt_size);
+8 -8
View File
@@ -55,12 +55,12 @@ static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr,
void *membuf;
if ((nargs != 3) || (nret != 2)) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
if (!nvram) {
rtas_st(rets, 0, -1);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
rtas_st(rets, 1, 0);
return;
}
@@ -71,7 +71,7 @@ static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr,
if (((offset + len) < offset)
|| ((offset + len) > nvram->size)) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
rtas_st(rets, 1, 0);
return;
}
@@ -87,7 +87,7 @@ static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr,
}
cpu_physical_memory_unmap(membuf, len, 1, len);
rtas_st(rets, 0, (alen < len) ? -1 : 0);
rtas_st(rets, 0, (alen < len) ? RTAS_OUT_HW_ERROR : RTAS_OUT_SUCCESS);
rtas_st(rets, 1, (alen < 0) ? 0 : alen);
}
@@ -102,12 +102,12 @@ static void rtas_nvram_store(PowerPCCPU *cpu, sPAPREnvironment *spapr,
void *membuf;
if ((nargs != 3) || (nret != 2)) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
if (!nvram) {
rtas_st(rets, 0, -1);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
@@ -117,7 +117,7 @@ static void rtas_nvram_store(PowerPCCPU *cpu, sPAPREnvironment *spapr,
if (((offset + len) < offset)
|| ((offset + len) > nvram->size)) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
@@ -132,7 +132,7 @@ static void rtas_nvram_store(PowerPCCPU *cpu, sPAPREnvironment *spapr,
}
cpu_physical_memory_unmap(membuf, len, 0, len);
rtas_st(rets, 0, (alen < len) ? -1 : 0);
rtas_st(rets, 0, (alen < len) ? RTAS_OUT_HW_ERROR : RTAS_OUT_SUCCESS);
rtas_st(rets, 1, (alen < 0) ? 0 : alen);
}
+1 -1
View File
@@ -82,7 +82,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
phb->bus = pci_register_bus(dev, "pci",
phb->bus = pci_register_bus(dev, NULL,
pci_grackle_set_irq,
pci_grackle_map_irq,
pic,
+2 -2
View File
@@ -234,7 +234,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
h->bus = pci_register_bus(dev, "pci",
h->bus = pci_register_bus(dev, NULL,
pci_unin_set_irq, pci_unin_map_irq,
pic,
&d->pci_mmio,
@@ -300,7 +300,7 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
h->bus = pci_register_bus(dev, "pci",
h->bus = pci_register_bus(dev, NULL,
pci_unin_set_irq, pci_unin_map_irq,
pic,
&d->pci_mmio,
+107 -106
View File
@@ -108,18 +108,18 @@ static void dt_serial_create(void *fdt, unsigned long long offset,
char ser[128];
snprintf(ser, sizeof(ser), "%s/serial@%llx", soc, offset);
qemu_devtree_add_subnode(fdt, ser);
qemu_devtree_setprop_string(fdt, ser, "device_type", "serial");
qemu_devtree_setprop_string(fdt, ser, "compatible", "ns16550");
qemu_devtree_setprop_cells(fdt, ser, "reg", offset, 0x100);
qemu_devtree_setprop_cell(fdt, ser, "cell-index", idx);
qemu_devtree_setprop_cell(fdt, ser, "clock-frequency", 0);
qemu_devtree_setprop_cells(fdt, ser, "interrupts", 42, 2);
qemu_devtree_setprop_phandle(fdt, ser, "interrupt-parent", mpic);
qemu_devtree_setprop_string(fdt, "/aliases", alias, ser);
qemu_fdt_add_subnode(fdt, ser);
qemu_fdt_setprop_string(fdt, ser, "device_type", "serial");
qemu_fdt_setprop_string(fdt, ser, "compatible", "ns16550");
qemu_fdt_setprop_cells(fdt, ser, "reg", offset, 0x100);
qemu_fdt_setprop_cell(fdt, ser, "cell-index", idx);
qemu_fdt_setprop_cell(fdt, ser, "clock-frequency", 0);
qemu_fdt_setprop_cells(fdt, ser, "interrupts", 42, 2);
qemu_fdt_setprop_phandle(fdt, ser, "interrupt-parent", mpic);
qemu_fdt_setprop_string(fdt, "/aliases", alias, ser);
if (defcon) {
qemu_devtree_setprop_string(fdt, "/chosen", "linux,stdout-path", ser);
qemu_fdt_setprop_string(fdt, "/chosen", "linux,stdout-path", ser);
}
}
@@ -183,30 +183,30 @@ static int ppce500_load_device_tree(QEMUMachineInitArgs *args,
}
/* Manipulate device tree in memory. */
qemu_devtree_setprop_cell(fdt, "/", "#address-cells", 2);
qemu_devtree_setprop_cell(fdt, "/", "#size-cells", 2);
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 2);
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 2);
qemu_devtree_add_subnode(fdt, "/memory");
qemu_devtree_setprop_string(fdt, "/memory", "device_type", "memory");
qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
sizeof(mem_reg_property));
qemu_fdt_add_subnode(fdt, "/memory");
qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
qemu_fdt_setprop(fdt, "/memory", "reg", mem_reg_property,
sizeof(mem_reg_property));
qemu_devtree_add_subnode(fdt, "/chosen");
qemu_fdt_add_subnode(fdt, "/chosen");
if (initrd_size) {
ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
initrd_base);
ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
initrd_base);
if (ret < 0) {
fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
}
ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
(initrd_base + initrd_size));
ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
(initrd_base + initrd_size));
if (ret < 0) {
fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
}
}
ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
ret = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
args->kernel_cmdline);
if (ret < 0)
fprintf(stderr, "couldn't set /chosen/bootargs\n");
@@ -217,22 +217,22 @@ static int ppce500_load_device_tree(QEMUMachineInitArgs *args,
tb_freq = kvmppc_get_tbfreq();
/* indicate KVM hypercall interface */
qemu_devtree_add_subnode(fdt, "/hypervisor");
qemu_devtree_setprop_string(fdt, "/hypervisor", "compatible",
"linux,kvm");
qemu_fdt_add_subnode(fdt, "/hypervisor");
qemu_fdt_setprop_string(fdt, "/hypervisor", "compatible",
"linux,kvm");
kvmppc_get_hypercall(env, hypercall, sizeof(hypercall));
qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions",
hypercall, sizeof(hypercall));
qemu_fdt_setprop(fdt, "/hypervisor", "hcall-instructions",
hypercall, sizeof(hypercall));
/* if KVM supports the idle hcall, set property indicating this */
if (kvmppc_get_hasidle(env)) {
qemu_devtree_setprop(fdt, "/hypervisor", "has-idle", NULL, 0);
qemu_fdt_setprop(fdt, "/hypervisor", "has-idle", NULL, 0);
}
}
/* Create CPU nodes */
qemu_devtree_add_subnode(fdt, "/cpus");
qemu_devtree_setprop_cell(fdt, "/cpus", "#address-cells", 1);
qemu_devtree_setprop_cell(fdt, "/cpus", "#size-cells", 0);
qemu_fdt_add_subnode(fdt, "/cpus");
qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 1);
qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0);
/* We need to generate the cpu nodes in reverse order, so Linux can pick
the first node as boot node and be happy */
@@ -249,55 +249,56 @@ static int ppce500_load_device_tree(QEMUMachineInitArgs *args,
snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x",
cpu->cpu_index);
qemu_devtree_add_subnode(fdt, cpu_name);
qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
qemu_devtree_setprop_string(fdt, cpu_name, "device_type", "cpu");
qemu_devtree_setprop_cell(fdt, cpu_name, "reg", cpu->cpu_index);
qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-line-size",
env->dcache_line_size);
qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-line-size",
env->icache_line_size);
qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-size", 0x8000);
qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-size", 0x8000);
qemu_devtree_setprop_cell(fdt, cpu_name, "bus-frequency", 0);
qemu_fdt_add_subnode(fdt, cpu_name);
qemu_fdt_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
qemu_fdt_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
qemu_fdt_setprop_cell(fdt, cpu_name, "reg", cpu->cpu_index);
qemu_fdt_setprop_cell(fdt, cpu_name, "d-cache-line-size",
env->dcache_line_size);
qemu_fdt_setprop_cell(fdt, cpu_name, "i-cache-line-size",
env->icache_line_size);
qemu_fdt_setprop_cell(fdt, cpu_name, "d-cache-size", 0x8000);
qemu_fdt_setprop_cell(fdt, cpu_name, "i-cache-size", 0x8000);
qemu_fdt_setprop_cell(fdt, cpu_name, "bus-frequency", 0);
if (cpu->cpu_index) {
qemu_devtree_setprop_string(fdt, cpu_name, "status", "disabled");
qemu_devtree_setprop_string(fdt, cpu_name, "enable-method", "spin-table");
qemu_devtree_setprop_u64(fdt, cpu_name, "cpu-release-addr",
cpu_release_addr);
qemu_fdt_setprop_string(fdt, cpu_name, "status", "disabled");
qemu_fdt_setprop_string(fdt, cpu_name, "enable-method",
"spin-table");
qemu_fdt_setprop_u64(fdt, cpu_name, "cpu-release-addr",
cpu_release_addr);
} else {
qemu_devtree_setprop_string(fdt, cpu_name, "status", "okay");
qemu_fdt_setprop_string(fdt, cpu_name, "status", "okay");
}
}
qemu_devtree_add_subnode(fdt, "/aliases");
qemu_fdt_add_subnode(fdt, "/aliases");
/* XXX These should go into their respective devices' code */
snprintf(soc, sizeof(soc), "/soc@%llx", MPC8544_CCSRBAR_BASE);
qemu_devtree_add_subnode(fdt, soc);
qemu_devtree_setprop_string(fdt, soc, "device_type", "soc");
qemu_devtree_setprop(fdt, soc, "compatible", compatible_sb,
sizeof(compatible_sb));
qemu_devtree_setprop_cell(fdt, soc, "#address-cells", 1);
qemu_devtree_setprop_cell(fdt, soc, "#size-cells", 1);
qemu_devtree_setprop_cells(fdt, soc, "ranges", 0x0,
MPC8544_CCSRBAR_BASE >> 32, MPC8544_CCSRBAR_BASE,
MPC8544_CCSRBAR_SIZE);
qemu_fdt_add_subnode(fdt, soc);
qemu_fdt_setprop_string(fdt, soc, "device_type", "soc");
qemu_fdt_setprop(fdt, soc, "compatible", compatible_sb,
sizeof(compatible_sb));
qemu_fdt_setprop_cell(fdt, soc, "#address-cells", 1);
qemu_fdt_setprop_cell(fdt, soc, "#size-cells", 1);
qemu_fdt_setprop_cells(fdt, soc, "ranges", 0x0,
MPC8544_CCSRBAR_BASE >> 32, MPC8544_CCSRBAR_BASE,
MPC8544_CCSRBAR_SIZE);
/* XXX should contain a reasonable value */
qemu_devtree_setprop_cell(fdt, soc, "bus-frequency", 0);
qemu_fdt_setprop_cell(fdt, soc, "bus-frequency", 0);
snprintf(mpic, sizeof(mpic), "%s/pic@%llx", soc, MPC8544_MPIC_REGS_OFFSET);
qemu_devtree_add_subnode(fdt, mpic);
qemu_devtree_setprop_string(fdt, mpic, "device_type", "open-pic");
qemu_devtree_setprop_string(fdt, mpic, "compatible", "fsl,mpic");
qemu_devtree_setprop_cells(fdt, mpic, "reg", MPC8544_MPIC_REGS_OFFSET,
0x40000);
qemu_devtree_setprop_cell(fdt, mpic, "#address-cells", 0);
qemu_devtree_setprop_cell(fdt, mpic, "#interrupt-cells", 2);
mpic_ph = qemu_devtree_alloc_phandle(fdt);
qemu_devtree_setprop_cell(fdt, mpic, "phandle", mpic_ph);
qemu_devtree_setprop_cell(fdt, mpic, "linux,phandle", mpic_ph);
qemu_devtree_setprop(fdt, mpic, "interrupt-controller", NULL, 0);
qemu_fdt_add_subnode(fdt, mpic);
qemu_fdt_setprop_string(fdt, mpic, "device_type", "open-pic");
qemu_fdt_setprop_string(fdt, mpic, "compatible", "fsl,mpic");
qemu_fdt_setprop_cells(fdt, mpic, "reg", MPC8544_MPIC_REGS_OFFSET,
0x40000);
qemu_fdt_setprop_cell(fdt, mpic, "#address-cells", 0);
qemu_fdt_setprop_cell(fdt, mpic, "#interrupt-cells", 2);
mpic_ph = qemu_fdt_alloc_phandle(fdt);
qemu_fdt_setprop_cell(fdt, mpic, "phandle", mpic_ph);
qemu_fdt_setprop_cell(fdt, mpic, "linux,phandle", mpic_ph);
qemu_fdt_setprop(fdt, mpic, "interrupt-controller", NULL, 0);
/*
* We have to generate ser1 first, because Linux takes the first
@@ -311,19 +312,19 @@ static int ppce500_load_device_tree(QEMUMachineInitArgs *args,
snprintf(gutil, sizeof(gutil), "%s/global-utilities@%llx", soc,
MPC8544_UTIL_OFFSET);
qemu_devtree_add_subnode(fdt, gutil);
qemu_devtree_setprop_string(fdt, gutil, "compatible", "fsl,mpc8544-guts");
qemu_devtree_setprop_cells(fdt, gutil, "reg", MPC8544_UTIL_OFFSET, 0x1000);
qemu_devtree_setprop(fdt, gutil, "fsl,has-rstcr", NULL, 0);
qemu_fdt_add_subnode(fdt, gutil);
qemu_fdt_setprop_string(fdt, gutil, "compatible", "fsl,mpc8544-guts");
qemu_fdt_setprop_cells(fdt, gutil, "reg", MPC8544_UTIL_OFFSET, 0x1000);
qemu_fdt_setprop(fdt, gutil, "fsl,has-rstcr", NULL, 0);
snprintf(msi, sizeof(msi), "/%s/msi@%llx", soc, MPC8544_MSI_REGS_OFFSET);
qemu_devtree_add_subnode(fdt, msi);
qemu_devtree_setprop_string(fdt, msi, "compatible", "fsl,mpic-msi");
qemu_devtree_setprop_cells(fdt, msi, "reg", MPC8544_MSI_REGS_OFFSET, 0x200);
msi_ph = qemu_devtree_alloc_phandle(fdt);
qemu_devtree_setprop_cells(fdt, msi, "msi-available-ranges", 0x0, 0x100);
qemu_devtree_setprop_phandle(fdt, msi, "interrupt-parent", mpic);
qemu_devtree_setprop_cells(fdt, msi, "interrupts",
qemu_fdt_add_subnode(fdt, msi);
qemu_fdt_setprop_string(fdt, msi, "compatible", "fsl,mpic-msi");
qemu_fdt_setprop_cells(fdt, msi, "reg", MPC8544_MSI_REGS_OFFSET, 0x200);
msi_ph = qemu_fdt_alloc_phandle(fdt);
qemu_fdt_setprop_cells(fdt, msi, "msi-available-ranges", 0x0, 0x100);
qemu_fdt_setprop_phandle(fdt, msi, "interrupt-parent", mpic);
qemu_fdt_setprop_cells(fdt, msi, "interrupts",
0xe0, 0x0,
0xe1, 0x0,
0xe2, 0x0,
@@ -332,46 +333,46 @@ static int ppce500_load_device_tree(QEMUMachineInitArgs *args,
0xe5, 0x0,
0xe6, 0x0,
0xe7, 0x0);
qemu_devtree_setprop_cell(fdt, msi, "phandle", msi_ph);
qemu_devtree_setprop_cell(fdt, msi, "linux,phandle", msi_ph);
qemu_fdt_setprop_cell(fdt, msi, "phandle", msi_ph);
qemu_fdt_setprop_cell(fdt, msi, "linux,phandle", msi_ph);
snprintf(pci, sizeof(pci), "/pci@%llx", MPC8544_PCI_REGS_BASE);
qemu_devtree_add_subnode(fdt, pci);
qemu_devtree_setprop_cell(fdt, pci, "cell-index", 0);
qemu_devtree_setprop_string(fdt, pci, "compatible", "fsl,mpc8540-pci");
qemu_devtree_setprop_string(fdt, pci, "device_type", "pci");
qemu_devtree_setprop_cells(fdt, pci, "interrupt-map-mask", 0xf800, 0x0,
0x0, 0x7);
pci_map = pci_map_create(fdt, qemu_devtree_get_phandle(fdt, mpic),
qemu_fdt_add_subnode(fdt, pci);
qemu_fdt_setprop_cell(fdt, pci, "cell-index", 0);
qemu_fdt_setprop_string(fdt, pci, "compatible", "fsl,mpc8540-pci");
qemu_fdt_setprop_string(fdt, pci, "device_type", "pci");
qemu_fdt_setprop_cells(fdt, pci, "interrupt-map-mask", 0xf800, 0x0,
0x0, 0x7);
pci_map = pci_map_create(fdt, qemu_fdt_get_phandle(fdt, mpic),
params->pci_first_slot, params->pci_nr_slots,
&len);
qemu_devtree_setprop(fdt, pci, "interrupt-map", pci_map, len);
qemu_devtree_setprop_phandle(fdt, pci, "interrupt-parent", mpic);
qemu_devtree_setprop_cells(fdt, pci, "interrupts", 24, 2);
qemu_devtree_setprop_cells(fdt, pci, "bus-range", 0, 255);
qemu_fdt_setprop(fdt, pci, "interrupt-map", pci_map, len);
qemu_fdt_setprop_phandle(fdt, pci, "interrupt-parent", mpic);
qemu_fdt_setprop_cells(fdt, pci, "interrupts", 24, 2);
qemu_fdt_setprop_cells(fdt, pci, "bus-range", 0, 255);
for (i = 0; i < 14; i++) {
pci_ranges[i] = cpu_to_be32(pci_ranges[i]);
}
qemu_devtree_setprop_cell(fdt, pci, "fsl,msi", msi_ph);
qemu_devtree_setprop(fdt, pci, "ranges", pci_ranges, sizeof(pci_ranges));
qemu_devtree_setprop_cells(fdt, pci, "reg", MPC8544_PCI_REGS_BASE >> 32,
MPC8544_PCI_REGS_BASE, 0, 0x1000);
qemu_devtree_setprop_cell(fdt, pci, "clock-frequency", 66666666);
qemu_devtree_setprop_cell(fdt, pci, "#interrupt-cells", 1);
qemu_devtree_setprop_cell(fdt, pci, "#size-cells", 2);
qemu_devtree_setprop_cell(fdt, pci, "#address-cells", 3);
qemu_devtree_setprop_string(fdt, "/aliases", "pci0", pci);
qemu_fdt_setprop_cell(fdt, pci, "fsl,msi", msi_ph);
qemu_fdt_setprop(fdt, pci, "ranges", pci_ranges, sizeof(pci_ranges));
qemu_fdt_setprop_cells(fdt, pci, "reg", MPC8544_PCI_REGS_BASE >> 32,
MPC8544_PCI_REGS_BASE, 0, 0x1000);
qemu_fdt_setprop_cell(fdt, pci, "clock-frequency", 66666666);
qemu_fdt_setprop_cell(fdt, pci, "#interrupt-cells", 1);
qemu_fdt_setprop_cell(fdt, pci, "#size-cells", 2);
qemu_fdt_setprop_cell(fdt, pci, "#address-cells", 3);
qemu_fdt_setprop_string(fdt, "/aliases", "pci0", pci);
params->fixup_devtree(params, fdt);
if (toplevel_compat) {
qemu_devtree_setprop(fdt, "/", "compatible", toplevel_compat,
strlen(toplevel_compat) + 1);
qemu_fdt_setprop(fdt, "/", "compatible", toplevel_compat,
strlen(toplevel_compat) + 1);
}
done:
if (!dry_run) {
qemu_devtree_dumpdtb(fdt, fdt_size);
qemu_fdt_dumpdtb(fdt, fdt_size);
cpu_physical_memory_write(addr, fdt, fdt_size);
}
ret = fdt_size;
+3 -3
View File
@@ -23,9 +23,9 @@ static void e500plat_fixup_devtree(PPCE500Params *params, void *fdt)
const char model[] = "QEMU ppce500";
const char compatible[] = "fsl,qemu-e500";
qemu_devtree_setprop(fdt, "/", "model", model, sizeof(model));
qemu_devtree_setprop(fdt, "/", "compatible", compatible,
sizeof(compatible));
qemu_fdt_setprop(fdt, "/", "model", model, sizeof(model));
qemu_fdt_setprop(fdt, "/", "compatible", compatible,
sizeof(compatible));
}
static void e500plat_init(QEMUMachineInitArgs *args)
+3 -3
View File
@@ -21,9 +21,9 @@ static void mpc8544ds_fixup_devtree(PPCE500Params *params, void *fdt)
const char model[] = "MPC8544DS";
const char compatible[] = "MPC8544DS\0MPC85xxDS";
qemu_devtree_setprop(fdt, "/", "model", model, sizeof(model));
qemu_devtree_setprop(fdt, "/", "compatible", compatible,
sizeof(compatible));
qemu_fdt_setprop(fdt, "/", "model", model, sizeof(model));
qemu_fdt_setprop(fdt, "/", "compatible", compatible,
sizeof(compatible));
}
static void mpc8544ds_init(QEMUMachineInitArgs *args)
+12 -12
View File
@@ -77,23 +77,23 @@ static int bamboo_load_device_tree(hwaddr addr,
/* Manipulate device tree in memory. */
ret = qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
sizeof(mem_reg_property));
ret = qemu_fdt_setprop(fdt, "/memory", "reg", mem_reg_property,
sizeof(mem_reg_property));
if (ret < 0)
fprintf(stderr, "couldn't set /memory/reg\n");
ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
initrd_base);
ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
initrd_base);
if (ret < 0)
fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
(initrd_base + initrd_size));
ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
(initrd_base + initrd_size));
if (ret < 0)
fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
kernel_cmdline);
ret = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
kernel_cmdline);
if (ret < 0)
fprintf(stderr, "couldn't set /chosen/bootargs\n");
@@ -105,10 +105,10 @@ static int bamboo_load_device_tree(hwaddr addr,
clock_freq = kvmppc_get_clockfreq();
}
qemu_devtree_setprop_cell(fdt, "/cpus/cpu@0", "clock-frequency",
clock_freq);
qemu_devtree_setprop_cell(fdt, "/cpus/cpu@0", "timebase-frequency",
tb_freq);
qemu_fdt_setprop_cell(fdt, "/cpus/cpu@0", "clock-frequency",
clock_freq);
qemu_fdt_setprop_cell(fdt, "/cpus/cpu@0", "timebase-frequency",
tb_freq);
rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
g_free(fdt);
+29 -20
View File
@@ -526,14 +526,15 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
cpu_to_be32(0x0), cpu_to_be32(0x0),
cpu_to_be32(0x0)};
char mem_name[32];
hwaddr node0_size, mem_start;
hwaddr node0_size, mem_start, node_size;
uint64_t mem_reg_property[2];
int i, off;
/* memory node(s) */
node0_size = (nb_numa_nodes > 1) ? node_mem[0] : ram_size;
if (spapr->rma_size > node0_size) {
spapr->rma_size = node0_size;
if (nb_numa_nodes > 1 && node_mem[0] < ram_size) {
node0_size = node_mem[0];
} else {
node0_size = ram_size;
}
/* RMA */
@@ -566,7 +567,15 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
mem_start = node0_size;
for (i = 1; i < nb_numa_nodes; i++) {
mem_reg_property[0] = cpu_to_be64(mem_start);
mem_reg_property[1] = cpu_to_be64(node_mem[i]);
if (mem_start >= ram_size) {
node_size = 0;
} else {
node_size = node_mem[i];
if (node_size > ram_size - mem_start) {
node_size = ram_size - mem_start;
}
}
mem_reg_property[1] = cpu_to_be64(node_size);
associativity[3] = associativity[4] = cpu_to_be32(i);
sprintf(mem_name, "memory@" TARGET_FMT_lx, mem_start);
off = fdt_add_subnode(fdt, 0, mem_name);
@@ -576,7 +585,7 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt)
sizeof(mem_reg_property))));
_FDT((fdt_setprop(fdt, off, "ibm,associativity", associativity,
sizeof(associativity))));
mem_start += node_mem[i];
mem_start += node_size;
}
return 0;
@@ -688,7 +697,8 @@ static void spapr_reset_htab(sPAPREnvironment *spapr)
/* Update the RMA size if necessary */
if (spapr->vrma_adjust) {
spapr->rma_size = kvmppc_rma_size(ram_size, spapr->htab_shift);
hwaddr node0_size = (nb_numa_nodes > 1) ? node_mem[0] : ram_size;
spapr->rma_size = kvmppc_rma_size(node0_size, spapr->htab_shift);
}
}
@@ -739,18 +749,10 @@ static void spapr_cpu_reset(void *opaque)
static void spapr_create_nvram(sPAPREnvironment *spapr)
{
DeviceState *dev = qdev_create(&spapr->vio_bus->bus, "spapr-nvram");
const char *drivename = qemu_opt_get(qemu_get_machine_opts(), "nvram");
DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0);
if (drivename) {
BlockDriverState *bs;
bs = bdrv_find(drivename);
if (!bs) {
fprintf(stderr, "No such block device \"%s\" for nvram\n",
drivename);
exit(1);
}
qdev_prop_set_drive_nofail(dev, "drive", bs);
if (dinfo) {
qdev_prop_set_drive_nofail(dev, "drive", dinfo->bdrv);
}
qdev_init_nofail(dev);
@@ -1113,6 +1115,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);
hwaddr rma_alloc_size;
hwaddr node0_size = (nb_numa_nodes > 1) ? node_mem[0] : ram_size;
uint32_t initrd_base = 0;
long kernel_size = 0, initrd_size = 0;
long load_limit, rtas_limit, fw_size;
@@ -1134,10 +1137,10 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
exit(1);
}
if (rma_alloc_size && (rma_alloc_size < ram_size)) {
if (rma_alloc_size && (rma_alloc_size < node0_size)) {
spapr->rma_size = rma_alloc_size;
} else {
spapr->rma_size = ram_size;
spapr->rma_size = node0_size;
/* With KVM, we don't actually know whether KVM supports an
* unbounded RMA (PR KVM) or is limited by the hash table size
@@ -1154,6 +1157,12 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
}
}
if (spapr->rma_size > node0_size) {
fprintf(stderr, "Error: Numa node 0 has to span the RMA (%#08"HWADDR_PRIx")\n",
spapr->rma_size);
exit(1);
}
/* We place the device tree and RTAS just below either the top of the RMA,
* or just below 2GB, whichever is lowere, so that it can be
* processed with 32-bit real mode code if necessary */
+3 -3
View File
@@ -286,7 +286,7 @@ static void check_exception(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint64_t xinfo;
if ((nargs < 6) || (nargs > 7) || nret != 1) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
@@ -306,9 +306,9 @@ static void check_exception(PowerPCCPU *cpu, sPAPREnvironment *spapr,
cpu_physical_memory_write(buf, pending_epow, len);
g_free(pending_epow);
pending_epow = NULL;
rtas_st(rets, 0, 0);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
} else {
rtas_st(rets, 0, 1);
rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
}
}
+21 -21
View File
@@ -90,7 +90,7 @@ static void finish_read_pci_config(sPAPREnvironment *spapr, uint64_t buid,
if ((size != 1) && (size != 2) && (size != 4)) {
/* access must be 1, 2 or 4 bytes */
rtas_st(rets, 0, -1);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
@@ -100,14 +100,14 @@ static void finish_read_pci_config(sPAPREnvironment *spapr, uint64_t buid,
if (!pci_dev || (addr % size) || (addr >= pci_config_size(pci_dev))) {
/* Access must be to a valid device, within bounds and
* naturally aligned */
rtas_st(rets, 0, -1);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
val = pci_host_config_read_common(pci_dev, addr,
pci_config_size(pci_dev), size);
rtas_st(rets, 0, 0);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
rtas_st(rets, 1, val);
}
@@ -120,7 +120,7 @@ static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t size, addr;
if ((nargs != 4) || (nret != 2)) {
rtas_st(rets, 0, -1);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
@@ -139,7 +139,7 @@ static void rtas_read_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t size, addr;
if ((nargs != 2) || (nret != 2)) {
rtas_st(rets, 0, -1);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
@@ -157,7 +157,7 @@ static void finish_write_pci_config(sPAPREnvironment *spapr, uint64_t buid,
if ((size != 1) && (size != 2) && (size != 4)) {
/* access must be 1, 2 or 4 bytes */
rtas_st(rets, 0, -1);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
@@ -167,14 +167,14 @@ static void finish_write_pci_config(sPAPREnvironment *spapr, uint64_t buid,
if (!pci_dev || (addr % size) || (addr >= pci_config_size(pci_dev))) {
/* Access must be to a valid device, within bounds and
* naturally aligned */
rtas_st(rets, 0, -1);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
pci_host_config_write_common(pci_dev, addr, pci_config_size(pci_dev),
val, size);
rtas_st(rets, 0, 0);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
@@ -186,7 +186,7 @@ static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t val, size, addr;
if ((nargs != 5) || (nret != 1)) {
rtas_st(rets, 0, -1);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
@@ -206,7 +206,7 @@ static void rtas_write_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t val, size, addr;
if ((nargs != 3) || (nret != 1)) {
rtas_st(rets, 0, -1);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
@@ -293,7 +293,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
break;
default:
fprintf(stderr, "rtas_ibm_change_msi(%u) is not implemented\n", func);
rtas_st(rets, 0, -3); /* Parameter error */
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
@@ -303,7 +303,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
pdev = find_dev(spapr, buid, config_addr);
}
if (!phb || !pdev) {
rtas_st(rets, 0, -3); /* Parameter error */
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
@@ -312,11 +312,11 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
ndev = spapr_msicfg_find(phb, config_addr, false);
if (ndev < 0) {
trace_spapr_pci_msi("MSI has not been enabled", -1, config_addr);
rtas_st(rets, 0, -1); /* Hardware error */
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
trace_spapr_pci_msi("Released MSIs", ndev, config_addr);
rtas_st(rets, 0, 0);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
rtas_st(rets, 1, 0);
return;
}
@@ -327,7 +327,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
ndev = spapr_msicfg_find(phb, config_addr, true);
if (ndev >= SPAPR_MSIX_MAX_DEVS || ndev < 0) {
fprintf(stderr, "No free entry for a new MSI device\n");
rtas_st(rets, 0, -1); /* Hardware error */
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
trace_spapr_pci_msi("Configuring MSI", ndev, config_addr);
@@ -336,7 +336,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
if (phb->msi_table[ndev].nvec && (req_num != phb->msi_table[ndev].nvec)) {
/* Unexpected behaviour */
fprintf(stderr, "Cannot reuse MSI config for device#%d", ndev);
rtas_st(rets, 0, -1); /* Hardware error */
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
@@ -346,7 +346,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
ret_intr_type == RTAS_TYPE_MSI);
if (irq < 0) {
fprintf(stderr, "Cannot allocate MSIs for device#%d", ndev);
rtas_st(rets, 0, -1); /* Hardware error */
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
phb->msi_table[ndev].irq = irq;
@@ -358,7 +358,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
spapr_msi_setmsg(pdev, spapr->msi_win_addr, ret_intr_type == RTAS_TYPE_MSIX,
phb->msi_table[ndev].irq, req_num);
rtas_st(rets, 0, 0);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
rtas_st(rets, 1, req_num);
rtas_st(rets, 2, ++seq_num);
rtas_st(rets, 3, ret_intr_type);
@@ -383,7 +383,7 @@ static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
/* Fins sPAPRPHBState */
phb = find_phb(spapr, buid);
if (!phb) {
rtas_st(rets, 0, -3); /* Parameter error */
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
@@ -391,7 +391,7 @@ static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
ndev = spapr_msicfg_find(phb, config_addr, false);
if (ndev < 0) {
trace_spapr_pci_msi("MSI has not been enabled", -1, config_addr);
rtas_st(rets, 0, -1); /* Hardware error */
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
@@ -399,7 +399,7 @@ static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
trace_spapr_pci_rtas_ibm_query_interrupt_source_number(ioa_intr_num,
intr_src_num);
rtas_st(rets, 0, 0);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
rtas_st(rets, 1, intr_src_num);
rtas_st(rets, 2, 1);/* 0 == level; 1 == edge */
}
+72 -25
View File
@@ -47,10 +47,10 @@ static void rtas_display_character(PowerPCCPU *cpu, sPAPREnvironment *spapr,
VIOsPAPRDevice *sdev = vty_lookup(spapr, 0);
if (!sdev) {
rtas_st(rets, 0, -1);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
} else {
vty_putchars(sdev, &c, sizeof(c));
rtas_st(rets, 0, 0);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
}
@@ -62,13 +62,13 @@ static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
struct tm tm;
if (nret != 8) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
qemu_get_timedate(&tm, spapr->rtc_offset);
rtas_st(rets, 0, 0); /* Success */
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
rtas_st(rets, 1, tm.tm_year + 1900);
rtas_st(rets, 2, tm.tm_mon + 1);
rtas_st(rets, 3, tm.tm_mday);
@@ -96,7 +96,7 @@ static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
rtc_change_mon_event(&tm);
spapr->rtc_offset = qemu_timedate_diff(&tm);
rtas_st(rets, 0, 0); /* Success */
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
static void rtas_power_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
@@ -104,11 +104,11 @@ static void rtas_power_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t nret, target_ulong rets)
{
if (nargs != 2 || nret != 1) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
qemu_system_shutdown_request();
rtas_st(rets, 0, 0);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
static void rtas_system_reboot(PowerPCCPU *cpu, sPAPREnvironment *spapr,
@@ -117,11 +117,11 @@ static void rtas_system_reboot(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t nret, target_ulong rets)
{
if (nargs != 0 || nret != 1) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
qemu_system_reset_request();
rtas_st(rets, 0, 0);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
@@ -134,7 +134,7 @@ static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
CPUState *cpu;
if (nargs != 1 || nret != 2) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
@@ -147,12 +147,12 @@ static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
rtas_st(rets, 1, 2);
}
rtas_st(rets, 0, 0);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
return;
}
/* Didn't find a matching cpu */
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}
static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPREnvironment *spapr,
@@ -164,7 +164,7 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPREnvironment *spapr,
CPUState *cs;
if (nargs != 3 || nret != 1) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
@@ -178,7 +178,7 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPREnvironment *spapr,
CPUPPCState *env = &cpu->env;
if (!cs->halted) {
rtas_st(rets, 0, -1);
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
@@ -194,12 +194,12 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPREnvironment *spapr,
qemu_cpu_kick(cs);
rtas_st(rets, 0, 0);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
return;
}
/* Didn't find a matching cpu */
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}
static void rtas_stop_self(PowerPCCPU *cpu, sPAPREnvironment *spapr,
@@ -224,6 +224,49 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPREnvironment *spapr,
env->msr = 0;
}
#define DIAGNOSTICS_RUN_MODE 42
static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
sPAPREnvironment *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
{
target_ulong parameter = rtas_ld(args, 0);
target_ulong buffer = rtas_ld(args, 1);
target_ulong length = rtas_ld(args, 2);
target_ulong ret = RTAS_OUT_NOT_SUPPORTED;
switch (parameter) {
case DIAGNOSTICS_RUN_MODE:
if (length == 1) {
rtas_st(buffer, 0, 0);
ret = RTAS_OUT_SUCCESS;
}
break;
}
rtas_st(rets, 0, ret);
}
static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu,
sPAPREnvironment *spapr,
uint32_t token, uint32_t nargs,
target_ulong args,
uint32_t nret, target_ulong rets)
{
target_ulong parameter = rtas_ld(args, 0);
target_ulong ret = RTAS_OUT_NOT_SUPPORTED;
switch (parameter) {
case DIAGNOSTICS_RUN_MODE:
ret = RTAS_OUT_NOT_AUTHORIZED;
break;
}
rtas_st(rets, 0, ret);
}
static struct rtas_call {
const char *name;
spapr_rtas_fn fn;
@@ -255,7 +298,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
}
hcall_dprintf("Unknown RTAS token 0x%x\n", token);
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return H_PARAMETER;
}
@@ -291,24 +334,24 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
return ret;
}
ret = qemu_devtree_setprop_cell(fdt, "/rtas", "linux,rtas-base",
rtas_addr);
ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-base",
rtas_addr);
if (ret < 0) {
fprintf(stderr, "Couldn't add linux,rtas-base property: %s\n",
fdt_strerror(ret));
return ret;
}
ret = qemu_devtree_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
rtas_addr);
ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
rtas_addr);
if (ret < 0) {
fprintf(stderr, "Couldn't add linux,rtas-entry property: %s\n",
fdt_strerror(ret));
return ret;
}
ret = qemu_devtree_setprop_cell(fdt, "/rtas", "rtas-size",
rtas_size);
ret = qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-size",
rtas_size);
if (ret < 0) {
fprintf(stderr, "Couldn't add rtas-size property: %s\n",
fdt_strerror(ret));
@@ -322,8 +365,8 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
continue;
}
ret = qemu_devtree_setprop_cell(fdt, "/rtas", call->name,
i + TOKEN_BASE);
ret = qemu_fdt_setprop_cell(fdt, "/rtas", call->name,
i + TOKEN_BASE);
if (ret < 0) {
fprintf(stderr, "Couldn't add rtas token for %s: %s\n",
call->name, fdt_strerror(ret));
@@ -345,6 +388,10 @@ static void core_rtas_register_types(void)
rtas_query_cpu_stopped_state);
spapr_rtas_register("start-cpu", rtas_start_cpu);
spapr_rtas_register("stop-self", rtas_stop_self);
spapr_rtas_register("ibm,get-system-parameter",
rtas_ibm_get_system_parameter);
spapr_rtas_register("ibm,set-system-parameter",
rtas_ibm_set_system_parameter);
}
type_init(core_rtas_register_types)
+6 -6
View File
@@ -331,25 +331,25 @@ static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t unit, enable;
if (nargs != 2) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
unit = rtas_ld(args, 0);
enable = rtas_ld(args, 1);
dev = spapr_vio_find_by_reg(bus, unit);
if (!dev) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
if (!dev->tcet) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
spapr_tce_set_bypass(dev->tcet, !!enable);
rtas_st(rets, 0, 0);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
static void rtas_quiesce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
@@ -362,7 +362,7 @@ static void rtas_quiesce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
VIOsPAPRDevice *dev = NULL;
if (nargs != 0) {
rtas_st(rets, 0, -3);
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
@@ -371,7 +371,7 @@ static void rtas_quiesce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
spapr_vio_quiesce_one(dev);
}
rtas_st(rets, 0, 0);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
static VIOsPAPRDevice *reg_conflict(VIOsPAPRDevice *dev)

Some files were not shown because too many files have changed in this diff Show More