diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2011-04-01 15:15:20 +1100 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2011-04-01 18:34:55 +0200 |
commit | 9fdf0c2995d04a74a22ea4609b2931eef209e53d (patch) | |
tree | 827b30000a29039442a233eac421805e5b598097 /hw/spapr_hcall.c | |
parent | 9d52e9079da4f28abd788faf39e64fbf4b305561 (diff) |
Start implementing pSeries logical partition machine
This patch adds a "pseries" machine to qemu. This aims to emulate a
logical partition on an IBM pSeries machine, compliant to the
"PowerPC Architecture Platform Requirements" (PAPR) document.
This initial version is quite limited, it implements a basic machine
and PAPR hypercall emulation. So far only one hypercall is present -
H_PUT_TERM_CHAR - so that a (write-only) console is available.
Multiple CPUs are permitted, with SMP entry handled kexec() style.
The machine so far more resembles an old POWER4 style "full system
partition" rather than a modern LPAR, in that the guest manages the
page tables directly, rather than via hypercalls.
The machine requires qemu to be configured with --enable-fdt. The
machine can (so far) only be booted with -kernel - i.e. no partition
firmware is provided.
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'hw/spapr_hcall.c')
-rw-r--r-- | hw/spapr_hcall.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c new file mode 100644 index 0000000000..e3919d01c2 --- /dev/null +++ b/hw/spapr_hcall.c @@ -0,0 +1,41 @@ +#include "sysemu.h" +#include "cpu.h" +#include "qemu-char.h" +#include "hw/spapr.h" + +spapr_hcall_fn hypercall_table[(MAX_HCALL_OPCODE / 4) + 1]; + +void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn) +{ + spapr_hcall_fn old_fn; + + assert(opcode <= MAX_HCALL_OPCODE); + assert((opcode & 0x3) == 0); + + old_fn = hypercall_table[opcode / 4]; + + assert(!old_fn || (fn == old_fn)); + + hypercall_table[opcode / 4] = fn; +} + +target_ulong spapr_hypercall(CPUState *env, target_ulong opcode, + target_ulong *args) +{ + if (msr_pr) { + hcall_dprintf("Hypercall made with MSR[PR]=1\n"); + return H_PRIVILEGE; + } + + if ((opcode <= MAX_HCALL_OPCODE) + && ((opcode & 0x3) == 0)) { + spapr_hcall_fn fn = hypercall_table[opcode / 4]; + + if (fn) { + return fn(env, spapr, opcode, args); + } + } + + hcall_dprintf("Unimplemented hcall 0x" TARGET_FMT_lx "\n", opcode); + return H_FUNCTION; +} |