aboutsummaryrefslogtreecommitdiff
path: root/hw/spapr_hcall.c
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2011-04-01 15:15:20 +1100
committerAlexander Graf <agraf@suse.de>2011-04-01 18:34:55 +0200
commit9fdf0c2995d04a74a22ea4609b2931eef209e53d (patch)
tree827b30000a29039442a233eac421805e5b598097 /hw/spapr_hcall.c
parent9d52e9079da4f28abd788faf39e64fbf4b305561 (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.c41
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;
+}