From: Alexander Graf <agraf@suse.de>
To: David Gibson <david@gibson.dropbear.id.au>
Cc: paulus@samba.org, qemu-devel@nongnu.org, anton@samba.org
Subject: [Qemu-devel] Re: [PATCH 16/26] Implement hcall based RTAS for pSeries machines
Date: Wed, 16 Mar 2011 16:08:30 +0100 [thread overview]
Message-ID: <4D80D26E.1030206@suse.de> (raw)
In-Reply-To: <1300251423-6715-17-git-send-email-david@gibson.dropbear.id.au>
On 03/16/2011 05:56 AM, David Gibson wrote:
> 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>
> ---
> Makefile | 3 +-
> Makefile.target | 2 +-
> hw/spapr.c | 27 +++++++++++--
> hw/spapr.h | 21 ++++++++++
> hw/spapr_hcall.c | 15 +++++++
> hw/spapr_rtas.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++
> pc-bios/spapr-rtas.bin | Bin 0 -> 20 bytes
> 7 files changed, 166 insertions(+), 6 deletions(-)
> create mode 100644 hw/spapr_rtas.c
> create mode 100644 pc-bios/spapr-rtas.bin
>
> diff --git a/Makefile b/Makefile
> index eca4c76..fc4bd24 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -213,7 +213,8 @@ pxe-ne2k_pci.bin pxe-pcnet.bin \
> pxe-rtl8139.bin pxe-virtio.bin \
> bamboo.dtb petalogix-s3adsp1800.dtb \
> multiboot.bin linuxboot.bin \
> -s390-zipl.rom
> +s390-zipl.rom \
> +spapr-rtas.bin
> else
> BLOBS=
> endif
> diff --git a/Makefile.target b/Makefile.target
> index 3f2b235..e333225 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -232,7 +232,7 @@ obj-ppc-y += ppc_oldworld.o
> # NewWorld PowerMac
> obj-ppc-y += ppc_newworld.o
> # IBM pSeries (sPAPR)
> -obj-ppc-y += spapr.o spapr_hcall.o spapr_vio.o
> +obj-ppc-y += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o
> obj-ppc-y += spapr_vty.o
> # PowerPC 4xx boards
> obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
> diff --git a/hw/spapr.c b/hw/spapr.c
> index c3d9286..f41451b 100644
> --- a/hw/spapr.c
> +++ b/hw/spapr.c
> @@ -40,6 +40,7 @@
> #define KERNEL_LOAD_ADDR 0x00000000
> #define INITRD_LOAD_ADDR 0x02800000
> #define FDT_MAX_SIZE 0x10000
> +#define RTAS_MAX_SIZE 0x10000
>
> #define TIMEBASE_FREQ 512000000ULL
>
> @@ -51,6 +52,8 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
> target_phys_addr_t initrd_base,
> target_phys_addr_t initrd_size,
> const char *kernel_cmdline,
> + target_phys_addr_t rtas_addr,
> + target_phys_addr_t rtas_size,
> long hash_shift)
> {
> void *fdt;
> @@ -162,7 +165,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
>
> _FDT((fdt_property(fdt, "ibm,hypertas-functions", hypertas_prop,
> sizeof(hypertas_prop))));
> -
> +
Ahem...
> _FDT((fdt_end_node(fdt)));
>
> /* vdevice */
> @@ -186,6 +189,11 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t ramsize,
> fprintf(stderr, "couldn't setup vio devices in fdt\n");
> }
>
> + /* RTAS */
> + ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);
> + if (ret< 0)
Braces
> + fprintf(stderr, "Couldn't set up RTAS device tree properties\n");
> +
> _FDT((fdt_pack(fdt)));
>
> if (fdt_size) {
> @@ -218,12 +226,13 @@ static void ppc_spapr_init(ram_addr_t ram_size,
> void *fdt, *htab;
> int i;
> ram_addr_t ram_offset;
> - target_phys_addr_t fdt_addr;
> + target_phys_addr_t fdt_addr, rtas_addr;
> uint32_t kernel_base, initrd_base;
> - long kernel_size, initrd_size, htab_size;
> + long kernel_size, initrd_size, htab_size, rtas_size;
> long pteg_shift = 17;
> int fdt_size;
> sPAPREnvironment *spapr;
> + char *filename;
>
> spapr = qemu_malloc(sizeof(*spapr));
>
> @@ -231,6 +240,8 @@ static void ppc_spapr_init(ram_addr_t ram_size,
> * 2GB, so that it can be processed with 32-bit code if
> * necessary */
> fdt_addr = MIN(ram_size, 0x80000000) - FDT_MAX_SIZE;
> + /* RTAS goes just below that */
> + rtas_addr = fdt_addr - RTAS_MAX_SIZE;
>
> /* init CPUs */
> if (cpu_model == NULL) {
> @@ -271,6 +282,14 @@ static void ppc_spapr_init(ram_addr_t ram_size,
> envs[i]->htab_mask = htab_size - 1;
> }
>
> + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
> + rtas_size = load_image_targphys(filename, rtas_addr, ram_size - rtas_addr);
> + if (rtas_size< 0) {
> + hw_error("qemu: could not load LPAR rtas '%s'\n", filename);
> + exit(1);
> + }
> + qemu_free(filename);
> +
> spapr->vio_bus = spapr_vio_bus_init();
>
> for (i = 0; i< MAX_SERIAL_PORTS; i++) {
> @@ -317,7 +336,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
> /* Prepare the device tree */
> fdt = spapr_create_fdt(&fdt_size, ram_size, cpu_model, envs, spapr,
> initrd_base, initrd_size, kernel_cmdline,
> - pteg_shift + 7);
> + rtas_addr, rtas_size, pteg_shift + 7);
> if (!fdt) {
> hw_error("Couldn't create pSeries device tree\n");
> exit(1);
> diff --git a/hw/spapr.h b/hw/spapr.h
> index 47bf2ef..7a7c319 100644
> --- a/hw/spapr.h
> +++ b/hw/spapr.h
> @@ -237,6 +237,8 @@ typedef struct sPAPREnvironment {
> #define H_GET_MPP 0x2D4
> #define MAX_HCALL_OPCODE H_GET_MPP
>
> +#define H_RTAS 0x72746173
> +
> typedef target_ulong (*spapr_hcall_fn)(CPUState *env, sPAPREnvironment *spapr,
> target_ulong opcode,
> target_ulong *args);
> @@ -245,5 +247,24 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn);
> target_ulong spapr_hypercall(CPUState *env, sPAPREnvironment *spapr,
> 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__) */
> diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
> index 2b14000..7b8e17c 100644
> --- a/hw/spapr_hcall.c
> +++ b/hw/spapr_hcall.c
> @@ -241,6 +241,16 @@ static target_ulong h_protect(CPUState *env, sPAPREnvironment *spapr,
> return H_SUCCESS;
> }
>
> +static target_ulong h_rtas(sPAPREnvironment *spapr, target_ulong rtas_r3)
> +{
> + uint32_t token = ldl_phys(rtas_r3);
> + uint32_t nargs = ldl_phys(rtas_r3 + 4);
> + uint32_t nret = ldl_phys(rtas_r3 + 8);
> +
> + return spapr_rtas_call(spapr, token, nargs, rtas_r3 + 12,
> + nret, rtas_r3 + 12 + 4*nargs);
> +}
> +
> struct hypercall {
> spapr_hcall_fn fn;
> } hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
> @@ -276,6 +286,11 @@ target_ulong spapr_hypercall(CPUState *env, sPAPREnvironment *spapr,
> return hc->fn(env, spapr, opcode, args);
> }
>
> + if (opcode == H_RTAS) {
> + /* H_RTAS is a special case outside the normal range */
> + return h_rtas(spapr, args[0]);
> + }
> +
> fprintf(stderr, "Unimplemented hcall 0x" TARGET_FMT_lx "\n", opcode);
> return H_FUNCTION;
> }
> diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
> new file mode 100644
> index 0000000..c606018
> --- /dev/null
> +++ b/hw/spapr_rtas.c
> @@ -0,0 +1,104 @@
> +#include "cpu.h"
> +#include "sysemu.h"
> +#include "qemu-char.h"
> +#include "hw/qdev.h"
> +#include "device_tree.h"
> +
> +#include "hw/spapr.h"
> +#include "hw/spapr_vio.h"
> +
> +#include<libfdt.h>
> +
> +#define TOKEN_BASE 0x2000
> +#define TOKEN_MAX 0x100
> +
> +static struct rtas_call {
> + const char *name;
> + spapr_rtas_fn fn;
> +} rtas_table[TOKEN_MAX];
> +
> +struct rtas_call *rtas_next = rtas_table;
> +
> +target_ulong spapr_rtas_call(sPAPREnvironment *spapr,
> + uint32_t token, uint32_t nargs, target_ulong args,
> + uint32_t nret, target_ulong rets)
> +{
> + if ((token>= TOKEN_BASE)
> +&& ((token - TOKEN_BASE)< TOKEN_MAX)) {
> + struct rtas_call *call = rtas_table + (token - TOKEN_BASE);
> +
> + if (call->fn) {
> + call->fn(spapr, token, nargs, args, nret, rets);
> + return H_SUCCESS;
> + }
> + }
> +
> + fprintf(stderr, "Unknown RTAS token 0x%x\n", token);
> + rtas_st(rets, 0, -3);
> + return H_PARAMETER;
> +}
> +
> +void spapr_rtas_register(const char *name, spapr_rtas_fn fn)
> +{
> + assert(rtas_next< (rtas_table + TOKEN_MAX));
> +
> + rtas_next->name = name;
> + rtas_next->fn = fn;
> +
> + rtas_next++;
> +}
> +
> +int spapr_rtas_device_tree_setup(void *fdt, target_phys_addr_t rtas_addr,
> + target_phys_addr_t rtas_size)
> +{
> + int ret;
> + int i;
> +
> + ret = fdt_add_mem_rsv(fdt, rtas_addr, rtas_size);
> + if (ret< 0) {
> + fprintf(stderr, "Couldn't add RTAS reserve entry: %s\n",
> + fdt_strerror(ret));
> + return ret;
> + }
> +
> + ret = qemu_devtree_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);
> + 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);
> + if (ret< 0) {
> + fprintf(stderr, "Couldn't add rtas-size property: %s\n",
> + fdt_strerror(ret));
> + return ret;
> + }
> +
> + for (i = 0; i< TOKEN_MAX; i++) {
> + struct rtas_call *call =&rtas_table[i];
> +
> + if (!call->fn) {
> + continue;
> + }
> +
> + ret = qemu_devtree_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));
> + return ret;
> + }
> +
> + }
> + return 0;
> +}
> diff --git a/pc-bios/spapr-rtas.bin b/pc-bios/spapr-rtas.bin
> new file mode 100644
> index 0000000000000000000000000000000000000000..eade9c0e8ff0fd3071e3a6638a11c1a2e9a47152
> GIT binary patch
> literal 20
> bcmb<Pk*=^wC@M)vPAqm|U{LaFU{C-6M#cr<
>
> literal 0
> HcmV?d00001
Despite being very simple, this is missing source code. There needs to
at least be a reference on where to find it in some text file in pc-bios.
Alex
next prev parent reply other threads:[~2011-03-16 15:08 UTC|newest]
Thread overview: 82+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-16 4:56 [Qemu-devel] Implement emulation of pSeries logical partitions (v3) David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 01/26] Clean up PowerPC SLB handling code David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 02/26] Allow qemu_devtree_setprop() to take arbitrary values David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 03/26] Add a hook to allow hypercalls to be emulated on PowerPC David Gibson
2011-03-16 13:46 ` [Qemu-devel] " Alexander Graf
2011-03-16 16:58 ` Stefan Hajnoczi
2011-03-17 2:26 ` David Gibson
2011-03-16 20:44 ` [Qemu-devel] " Anthony Liguori
2011-03-17 4:55 ` David Gibson
2011-03-17 13:20 ` Anthony Liguori
2011-03-18 4:03 ` David Gibson
2011-03-18 6:57 ` Alexander Graf
2011-03-16 4:56 ` [Qemu-devel] [PATCH 04/26] Implement PowerPC slbmfee and slbmfev instructions David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 05/26] Implement missing parts of the logic for the POWER PURR David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 06/26] Correct ppc popcntb logic, implement popcntw and popcntd David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 07/26] Clean up slb_lookup() function David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 08/26] Parse SDR1 on mtspr instead of at translate time David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 09/26] Use "hash" more consistently in ppc mmu code David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 10/26] Better factor the ppc hash translation path David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 11/26] Support 1T segments on ppc David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 12/26] Add POWER7 support for ppc David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 13/26] Start implementing pSeries logical partition machine David Gibson
2011-03-16 14:30 ` [Qemu-devel] " Alexander Graf
2011-03-16 21:59 ` [Qemu-devel] " Anthony Liguori
2011-03-16 23:46 ` Alexander Graf
2011-03-17 3:08 ` David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 14/26] Implement the bus structure for PAPR virtual IO David Gibson
2011-03-16 14:43 ` [Qemu-devel] " Alexander Graf
2011-03-16 22:04 ` [Qemu-devel] " Anthony Liguori
2011-03-17 3:19 ` David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 15/26] Virtual hash page table handling on pSeries machine David Gibson
2011-03-16 15:03 ` [Qemu-devel] " Alexander Graf
2011-03-17 1:03 ` [Qemu-devel] Re: [PATCH 15/26] Virtual hash page table handling on pSeries machine' David Gibson
2011-03-17 7:35 ` Alexander Graf
2011-03-16 4:56 ` [Qemu-devel] [PATCH 16/26] Implement hcall based RTAS for pSeries machines David Gibson
2011-03-16 15:08 ` Alexander Graf [this message]
2011-03-17 1:22 ` [Qemu-devel] " David Gibson
2011-03-17 7:36 ` Alexander Graf
2011-03-16 22:08 ` [Qemu-devel] " Anthony Liguori
2011-03-16 4:56 ` [Qemu-devel] [PATCH 17/26] Implement assorted pSeries hcalls and RTAS methods David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 18/26] Implement the PAPR (pSeries) virtualized interrupt controller (xics) David Gibson
2011-03-16 15:47 ` [Qemu-devel] " Alexander Graf
2011-03-17 1:29 ` David Gibson
2011-03-17 7:37 ` Alexander Graf
2011-03-16 22:16 ` [Qemu-devel] " Anthony Liguori
2011-03-17 1:34 ` David Gibson
2011-03-17 13:13 ` Anthony Liguori
2011-03-23 3:48 ` David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 19/26] Add PAPR H_VIO_SIGNAL hypercall and infrastructure for VIO interrupts David Gibson
2011-03-16 15:49 ` [Qemu-devel] " Alexander Graf
2011-03-17 1:38 ` David Gibson
2011-03-17 7:38 ` Alexander Graf
2011-03-16 4:56 ` [Qemu-devel] [PATCH 20/26] Add (virtual) interrupt to PAPR virtual tty device David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 21/26] Implement TCE translation for sPAPR VIO David Gibson
2011-03-16 16:03 ` [Qemu-devel] " Alexander Graf
2011-03-16 20:05 ` Benjamin Herrenschmidt
2011-03-16 20:21 ` Anthony Liguori
2011-03-16 20:22 ` Anthony Liguori
2011-03-16 20:36 ` Benjamin Herrenschmidt
2011-03-17 1:43 ` David Gibson
2011-03-16 22:20 ` [Qemu-devel] " Anthony Liguori
2011-03-18 1:58 ` David Gibson
2011-03-16 4:56 ` [Qemu-devel] [PATCH 22/26] Implement sPAPR Virtual LAN (ibmveth) David Gibson
2011-03-16 16:12 ` [Qemu-devel] " Alexander Graf
2011-03-17 2:04 ` David Gibson
2011-03-16 22:29 ` [Qemu-devel] " Anthony Liguori
2011-03-17 2:09 ` David Gibson
2011-03-16 4:57 ` [Qemu-devel] [PATCH 23/26] Implement PAPR CRQ hypercalls David Gibson
2011-03-16 16:15 ` [Qemu-devel] " Alexander Graf
2011-03-16 4:57 ` [Qemu-devel] [PATCH 24/26] Implement PAPR virtual SCSI interface (ibmvscsi) David Gibson
2011-03-16 16:41 ` [Qemu-devel] " Alexander Graf
2011-03-16 16:51 ` Anthony Liguori
2011-03-16 20:08 ` Benjamin Herrenschmidt
2011-03-16 20:19 ` Anthony Liguori
2011-03-16 4:57 ` [Qemu-devel] [PATCH 25/26] Add a PAPR TCE-bypass mechanism for the pSeries machine David Gibson
2011-03-16 16:43 ` [Qemu-devel] " Alexander Graf
2011-03-17 2:21 ` David Gibson
2011-03-17 3:25 ` Benjamin Herrenschmidt
2011-03-17 7:44 ` Alexander Graf
2011-03-17 8:44 ` Benjamin Herrenschmidt
2011-03-17 9:37 ` Alexander Graf
2011-03-16 4:57 ` [Qemu-devel] [PATCH 26/26] Implement PAPR VPA functions for pSeries shared processor partitions David Gibson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D80D26E.1030206@suse.de \
--to=agraf@suse.de \
--cc=anton@samba.org \
--cc=david@gibson.dropbear.id.au \
--cc=paulus@samba.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).