diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2011-04-01 15:15:23 +1100 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2011-04-01 18:34:56 +0200 |
commit | 39ac8455106af1ed669b8e10223420cf1ac5b190 (patch) | |
tree | 48c935a56286ff50f76982c9d7aab1a0eb835e03 /hw/spapr.h | |
parent | f43e35255cffb6ac6230dd09d308f7909f823f96 (diff) |
Implement hcall based RTAS for pSeries machines
On pSeries machines, operating systems can instantiate "RTAS" (Run-Time
Abstraction Services), a runtime component of the firmware which implements
a number of low-level, infrequently used operations. On logical partitions
under a hypervisor, many of the RTAS functions require hypervisor
privilege. For simplicity, therefore, hypervisor systems typically
implement the in-partition RTAS as just a tiny wrapper around a hypercall
which actually implements the various RTAS functions.
This patch implements such a hypercall based RTAS for our emulated pSeries
machine. A tiny in-partition "firmware" calls a new hypercall, which
looks up available RTAS services in a table.
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'hw/spapr.h')
-rw-r--r-- | hw/spapr.h | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/hw/spapr.h b/hw/spapr.h index 06cca15b94..0dcb83a5ae 100644 --- a/hw/spapr.h +++ b/hw/spapr.h @@ -237,6 +237,18 @@ typedef struct sPAPREnvironment { #define H_GET_MPP 0x2D4 #define MAX_HCALL_OPCODE H_GET_MPP +/* The hcalls above are standardized in PAPR and implemented by pHyp + * as well. + * + * We also need some hcalls which are specific to qemu / KVM-on-POWER. + * So far we just need one for H_RTAS, but in future we'll need more + * for extensions like virtio. We put those into the 0xf000-0xfffc + * range which is reserved by PAPR for "platform-specific" hcalls. + */ +#define KVMPPC_HCALL_BASE 0xf000 +#define KVMPPC_H_RTAS (KVMPPC_HCALL_BASE + 0x0) +#define KVMPPC_HCALL_MAX KVMPPC_H_RTAS + extern sPAPREnvironment *spapr; /*#define DEBUG_SPAPR_HCALLS*/ @@ -257,4 +269,24 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn); target_ulong spapr_hypercall(CPUState *env, target_ulong opcode, target_ulong *args); +static inline uint32_t rtas_ld(target_ulong phys, int n) +{ + return ldl_phys(phys + 4*n); +} + +static inline void rtas_st(target_ulong phys, int n, uint32_t val) +{ + stl_phys(phys + 4*n, val); +} + +typedef void (*spapr_rtas_fn)(sPAPREnvironment *spapr, uint32_t token, + uint32_t nargs, target_ulong args, + uint32_t nret, target_ulong rets); +void spapr_rtas_register(const char *name, spapr_rtas_fn fn); +target_ulong spapr_rtas_call(sPAPREnvironment *spapr, + uint32_t token, uint32_t nargs, target_ulong args, + uint32_t nret, target_ulong rets); +int spapr_rtas_device_tree_setup(void *fdt, target_phys_addr_t rtas_addr, + target_phys_addr_t rtas_size); + #endif /* !defined (__HW_SPAPR_H__) */ |