qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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

  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).