[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] Re: [PATCH 27/27] Add SLOF-based partition firmware for pSe
From: |
Alexander Graf |
Subject: |
[Qemu-devel] Re: [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options |
Date: |
Mon, 28 Mar 2011 12:30:58 +0200 |
On 25.03.2011, at 04:21, David Gibson wrote:
> Currently, the emulated pSeries machine requires the use of the
> -kernel parameter in order to explicitly load a guest kernel. This
> means booting from the virtual disk, cdrom or network is not possible.
>
> This patch addresses this limitation by inserting a within-partition
> firmware image (derived from the "SLOF" free Open Firmware project).
> If -kernel is not specified, qemu will now load the SLOF image, which
> has access to the qemu boot device list through the device tree, and
> can boot from any of the usual virtual devices.
>
> In order to support the new firmware, an extension to the emulated
> machine/hypervisor is necessary. Unlike Linux, which expects
> multi-CPU entry to be handled kexec() style, the SLOF firmware expects
> only one CPU to be active at entry, and to use a hypervisor RTAS
> method to enable the other CPUs one by one.
>
> This patch also implements this 'start-cpu' method, so that SLOF can
> start the secondary CPUs and marshal them into the kexec() holding
> pattern ready for entry into the guest OS. Linux should, and in the
> future might directly use the start-cpu method to enable initially
> disabled CPUs, but for now it does require kexec() entry.
>
> Signed-off-by: Benjamin Herrenschmidt <address@hidden>
> Signed-off-by: Paul Mackerras <address@hidden>
> Signed-off-by: David Gibson <address@hidden>
> ---
> Makefile | 2 +-
> hw/spapr.c | 35 +++++++++++++++++++++---
> hw/spapr_rtas.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> pc-bios/README | 5 +++
> pc-bios/slof.bin | Bin 0 -> 579072 bytes
> 5 files changed, 115 insertions(+), 5 deletions(-)
> create mode 100644 pc-bios/slof.bin
>
> diff --git a/Makefile b/Makefile
> index e0b3fea..989622b 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -214,7 +214,7 @@ pxe-rtl8139.bin pxe-virtio.bin \
> bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
> multiboot.bin linuxboot.bin \
> s390-zipl.rom \
> -spapr-rtas.bin
> +spapr-rtas.bin slof.bin
> else
> BLOBS=
> endif
> diff --git a/hw/spapr.c b/hw/spapr.c
> index 9d611a7..c6454e6 100644
> --- a/hw/spapr.c
> +++ b/hw/spapr.c
> @@ -44,6 +44,10 @@
> #define INITRD_LOAD_ADDR 0x02800000
> #define FDT_MAX_SIZE 0x10000
> #define RTAS_MAX_SIZE 0x10000
> +#define FW_MAX_SIZE 0x400000
> +#define FW_FILE_NAME "slof.bin"
> +
> +#define MIN_RAM_SLOF 512UL
>
> #define TIMEBASE_FREQ 512000000ULL
>
> @@ -56,6 +60,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t
> ramsize,
> sPAPREnvironment *spapr,
> target_phys_addr_t initrd_base,
> target_phys_addr_t initrd_size,
> + const char *boot_device,
> const char *kernel_cmdline,
> target_phys_addr_t rtas_addr,
> target_phys_addr_t rtas_size,
> @@ -104,6 +109,7 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t
> ramsize,
> &start_prop, sizeof(start_prop))));
> _FDT((fdt_property(fdt, "linux,initrd-end",
> &end_prop, sizeof(end_prop))));
> + _FDT((fdt_property_string(fdt, "qemu,boot-device", boot_device)));
>
> _FDT((fdt_end_node(fdt)));
>
> @@ -260,7 +266,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
> ram_addr_t ram_offset;
> target_phys_addr_t fdt_addr, rtas_addr;
> uint32_t kernel_base, initrd_base;
> - long kernel_size, initrd_size, htab_size, rtas_size;
> + long kernel_size, initrd_size, htab_size, rtas_size, fw_size;
> long pteg_shift = 17;
> int fdt_size;
> char *filename;
> @@ -392,13 +398,33 @@ static void ppc_spapr_init(ram_addr_t ram_size,
> initrd_size = 0;
> }
> } else {
> - fprintf(stderr, "pSeries machine needs -kernel for now");
> - exit(1);
> + if (ram_size < (MIN_RAM_SLOF << 20)) {
> + fprintf(stderr, "qemu: pSeries SLOF firmware requires >= "
> + "%ldM guest RAM\n", MIN_RAM_SLOF);
> + exit(1);
> + }
> + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "slof.bin");
> + fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
> + if (fw_size < 0) {
> + hw_error("qemu: could not load LPAR rtas '%s'\n", filename);
> + exit(1);
> + }
> + qemu_free(filename);
> + kernel_base = 0x100;
> + initrd_base = 0;
> + initrd_size = 0;
> +
> + /* SLOF will startup the secondary CPUs using RTAS,
> + rather than expecting a kexec() style entry */
> + for (i = 0; i < smp_cpus; i++) {
> + envs[i]->halted = 1;
> + }
> }
>
> /* Prepare the device tree */
> fdt = spapr_create_fdt(&fdt_size, ram_size, cpu_model, envs, spapr,
> - initrd_base, initrd_size, kernel_cmdline,
> + initrd_base, initrd_size,
> + boot_device, kernel_cmdline,
> rtas_addr, rtas_size, pteg_shift + 7);
> assert(fdt != NULL);
>
> @@ -409,6 +435,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
> envs[0]->gpr[3] = fdt_addr;
> envs[0]->gpr[5] = 0;
> envs[0]->hreset_vector = kernel_base;
> + envs[0]->halted = 0;
> }
>
> static QEMUMachine spapr_machine = {
> diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
> index 7226853..16b6542 100644
> --- a/hw/spapr_rtas.c
> +++ b/hw/spapr_rtas.c
> @@ -90,6 +90,81 @@ static void rtas_power_off(sPAPREnvironment *spapr,
> rtas_st(rets, 0, 0);
> }
>
> +static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
> + uint32_t token, uint32_t nargs,
> + target_ulong args,
> + uint32_t nret, target_ulong rets)
> +{
> + target_ulong id;
> + CPUState *env;
> +
> + if (nargs != 1 || nret != 2) {
> + rtas_st(rets, 0, -3);
> + return;
> + }
> +
> + id = rtas_ld(args, 0);
> + for (env = first_cpu; env; env = env->next_cpu) {
> + if (env->cpu_index != id) {
> + continue;
> + }
> +
> + if (env->halted) {
> + rtas_st(rets, 1, 0);
> + } else {
> + rtas_st(rets, 1, 2);
> + }
> +
> + rtas_st(rets, 0, 0);
> + return;
> + }
> +
> + /* Didn't find a matching cpu */
> + rtas_st(rets, 0, -3);
> +}
> +
> +static void rtas_start_cpu(sPAPREnvironment *spapr,
> + uint32_t token, uint32_t nargs,
> + target_ulong args,
> + uint32_t nret, target_ulong rets)
> +{
> + target_ulong id, start, r3;
> + CPUState *env;
> +
> + if (nargs != 3 || nret != 1) {
> + rtas_st(rets, 0, -3);
> + return;
> + }
> +
> + id = rtas_ld(args, 0);
> + start = rtas_ld(args, 1);
> + r3 = rtas_ld(args, 2);
> +
> + for (env = first_cpu; env; env = env->next_cpu) {
> + if (env->cpu_index != id) {
> + continue;
> + }
> +
> + if (!env->halted) {
> + rtas_st(rets, 0, -1);
> + return;
> + }
> +
> + env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
> + env->nip = start;
> + env->gpr[3] = r3;
> + env->halted = 0;
> +
> + qemu_cpu_kick(env);
> +
> + rtas_st(rets, 0, 0);
> + return;
> + }
> +
> + /* Didn't find a matching cpu */
> + rtas_st(rets, 0, -3);
> +}
> +
> static struct rtas_call {
> const char *name;
> spapr_rtas_fn fn;
> @@ -196,5 +271,8 @@ static void register_core_rtas(void)
> spapr_rtas_register("display-character", rtas_display_character);
> spapr_rtas_register("get-time-of-day", rtas_get_time_of_day);
> spapr_rtas_register("power-off", rtas_power_off);
> + spapr_rtas_register("query-cpu-stopped-state",
> + rtas_query_cpu_stopped_state);
> + spapr_rtas_register("start-cpu", rtas_start_cpu);
> }
> device_init(register_core_rtas);
> diff --git a/pc-bios/README b/pc-bios/README
> index 3fc0944..646a31a 100644
> --- a/pc-bios/README
> +++ b/pc-bios/README
> @@ -13,6 +13,11 @@
> The included image for PowerPC (for 32 and 64 bit PPC CPUs), Sparc32
> and Sparc64 are built from OpenBIOS SVN revision 1018.
>
> +- SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware
> + implementation for certain IBM POWER hardware. The sources are at
> + https://github.com/dgibson/SLOF, and the image currently in qemu is
> + built from git tag qemu-slof-20110323.
> +
> - The PXE roms come from Rom-o-Matic gPXE 0.9.9 with BANNER_TIMEOUT=0
Is this a line removal?
Alex
- Re: [Qemu-devel] [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options, (continued)
- Re: [Qemu-devel] [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options, David Gibson, 2011/03/28
- Re: [Qemu-devel] [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options, Blue Swirl, 2011/03/28
- Re: [Qemu-devel] [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options, Anthony Liguori, 2011/03/28
- Re: [Qemu-devel] [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options, Aurelien Jarno, 2011/03/28
- Re: [Qemu-devel] [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options, Anthony Liguori, 2011/03/28
- Re: [Qemu-devel] [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options, Aurelien Jarno, 2011/03/28
- Re: [Qemu-devel] [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options, Alexander Graf, 2011/03/29
- Re: [Qemu-devel] [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options, Alexander Graf, 2011/03/29
- Re: [Qemu-devel] [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options, Anthony Liguori, 2011/03/28
- Re: [Qemu-devel] [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options, David Gibson, 2011/03/29
[Qemu-devel] Re: [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options,
Alexander Graf <=
[Qemu-devel] Re: [PATCH 27/27] Add SLOF-based partition firmware for pSeries machine, allowing more boot options, Paolo Bonzini, 2011/03/28
[Qemu-devel] Re: [0/27] Implement emulation of pSeries logical partitions (v5), Alexander Graf, 2011/03/28