Patchwork [2/3] s390: Move IPL code into a separate device

login
register
mail settings
Submitter Jens Freimann
Date Dec. 7, 2012, 1:55 p.m.
Message ID <1354888531-47836-3-git-send-email-jfrei@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/204513/
State New
Headers show

Comments

Jens Freimann - Dec. 7, 2012, 1:55 p.m.
From: Christian Borntraeger <borntraeger@de.ibm.com>

Lets move the code to setup IPL for external kernel
or via the zipl rom into a separate file. This allows to

- define a reboot handler, setting up the PSW appropriately
- enhance the boot code to IPL disks that contain a bootmap that
  was created with zipl under LPAR or z/VM (see additional patch)
  and thus disabling the bios code that only works for specifically
  prepared disks.
- reuse that code for several machines (e.g. virtio-ccw and virtio-s390)

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
---
 hw/s390-virtio.c       |   30 ++---------------
 hw/s390x/Makefile.objs |    1 +
 hw/s390x/ipl.c         |   80 ++++++++++++++++++++++++++++++++++++++++++++++++
 hw/s390x/ipl.h         |   34 ++++++++++++++++++++
 4 files changed, 119 insertions(+), 26 deletions(-)
 create mode 100644 hw/s390x/ipl.c
 create mode 100644 hw/s390x/ipl.h
Christian Borntraeger - Dec. 7, 2012, 3:14 p.m.
Alex,

here is were the IPL device code would move into. Some rough edges are still 
there, but it can ipl almost anything that was zipled under LPAR/VM.

Christian Borntraeger (2):
  s390: Add bootmap parsing to ipl device
  s390: enable ipl device for virtio-ccw

 hw/s390x/Makefile.objs |    2 +-
 hw/s390x/ipl-disk.c    |  504 ++++++++++++++++++++++++++++++++++++++++++++++++
 hw/s390x/ipl-disk.h    |  104 ++++++++++
 hw/s390x/ipl.c         |   51 ++++-
 4 files changed, 659 insertions(+), 2 deletions(-)
 create mode 100644 hw/s390x/ipl-disk.c
 create mode 100644 hw/s390x/ipl-disk.h
Alexander Graf - Dec. 11, 2012, 10:36 a.m.
On 07.12.2012, at 16:14, Christian Borntraeger wrote:

> Alex,
> 
> here is were the IPL device code would move into. Some rough edges are still 
> there, but it can ipl almost anything that was zipled under LPAR/VM.

Please try and check how nicely this can be done if we would map a firmware blob into the guest address space. I still believe that we can handle all boot strapping cases from within guest context.

The great advantage would be that we get user interaction and consistent device state. And less code that runs under host privileges.


Alex
Alexander Graf - Dec. 11, 2012, 10:38 a.m.
On 07.12.2012, at 14:55, Jens Freimann wrote:

> From: Christian Borntraeger <borntraeger@de.ibm.com>
> 
> Lets move the code to setup IPL for external kernel
> or via the zipl rom into a separate file. This allows to
> 
> - define a reboot handler, setting up the PSW appropriately
> - enhance the boot code to IPL disks that contain a bootmap that
>  was created with zipl under LPAR or z/VM (see additional patch)
>  and thus disabling the bios code that only works for specifically
>  prepared disks.
> - reuse that code for several machines (e.g. virtio-ccw and virtio-s390)
> 
> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
> Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>

Creating a separate device sounds like a good idea, but please do so consistently. Please move everything that relates to booting into the device, including -kernel.

Also, I don't think we need a "-default" ipl device. Just create a generic ipl device that controls booting.


Alex

> ---
> hw/s390-virtio.c       |   30 ++---------------
> hw/s390x/Makefile.objs |    1 +
> hw/s390x/ipl.c         |   80 ++++++++++++++++++++++++++++++++++++++++++++++++
> hw/s390x/ipl.h         |   34 ++++++++++++++++++++
> 4 files changed, 119 insertions(+), 26 deletions(-)
> create mode 100644 hw/s390x/ipl.c
> create mode 100644 hw/s390x/ipl.h
> 
> diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
> index d77871a..10a5fd7 100644
> --- a/hw/s390-virtio.c
> +++ b/hw/s390-virtio.c
> @@ -33,6 +33,7 @@
> 
> #include "hw/s390-virtio-bus.h"
> #include "hw/s390x/sclp.h"
> +#include "hw/s390x/ipl.h"
> 
> //#define DEBUG_S390
> 
> @@ -48,17 +49,6 @@
> #define KVM_S390_VIRTIO_RESET           1
> #define KVM_S390_VIRTIO_SET_STATUS      2
> 
> -#define KERN_IMAGE_START                0x010000UL
> -#define KERN_PARM_AREA                  0x010480UL
> -#define INITRD_START                    0x800000UL
> -#define INITRD_PARM_START               0x010408UL
> -#define INITRD_PARM_SIZE                0x010410UL
> -#define PARMFILE_START                  0x001000UL
> -
> -#define ZIPL_START			0x009000UL
> -#define ZIPL_LOAD_ADDR			0x009000UL
> -#define ZIPL_FILENAME			"s390-zipl.rom"
> -
> #define MAX_BLK_DEVS                    10
> 
> static VirtIOS390Bus *s390_bus;
> @@ -185,6 +175,7 @@ static void s390_init(QEMUMachineInitArgs *args)
>     /* get a BUS */
>     s390_bus = s390_virtio_bus_init(&my_ram_size);
>     s390_sclp_init();
> +    s390_ipl_init();
> 
>     /* allocate RAM */
>     memory_region_init_ram(ram, "s390.ram", my_ram_size);
> @@ -225,11 +216,7 @@ static void s390_init(QEMUMachineInitArgs *args)
>         tmp_env->storage_keys = storage_keys;
>     }
> 
> -    /* One CPU has to run */
> -    s390_add_running_cpu(env);
> -
>     if (kernel_filename) {
> -
>         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, NULL,
>                                NULL, 1, ELF_MACHINE, 0);
>         if (kernel_size == -1UL) {
> @@ -240,13 +227,6 @@ static void s390_init(QEMUMachineInitArgs *args)
>                     kernel_filename);
>             exit(1);
>         }
> -        /*
> -         * we can not rely on the ELF entry point, since up to 3.2 this
> -         * value was 0x800 (the SALIPL loader) and it wont work. For
> -         * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine.
> -         */
> -        env->psw.addr = KERN_IMAGE_START;
> -        env->psw.mask = 0x0000000180000000ULL;
>     } else {
>         ram_addr_t bios_size = 0;
>         char *bios_filename;
> @@ -257,7 +237,7 @@ static void s390_init(QEMUMachineInitArgs *args)
>         }
> 
>         bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> -        bios_size = load_image_targphys(bios_filename, ZIPL_LOAD_ADDR, 4096);
> +        bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START, 4096);
>         g_free(bios_filename);
> 
>         if ((long)bios_size < 0) {
> @@ -267,9 +247,6 @@ static void s390_init(QEMUMachineInitArgs *args)
>         if (bios_size > 4096) {
>             hw_error("stage1 bootloader is > 4k\n");
>         }
> -
> -        env->psw.addr = ZIPL_START;
> -        env->psw.mask = 0x0000000180000000ULL;
>     }
> 
>     if (initrd_filename) {
> @@ -352,3 +329,4 @@ static void s390_machine_init(void)
> }
> 
> machine_init(s390_machine_init);
> +
> diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
> index 096dfcd..4a5a5d8 100644
> --- a/hw/s390x/Makefile.objs
> +++ b/hw/s390x/Makefile.objs
> @@ -4,3 +4,4 @@ obj-y := $(addprefix ../,$(obj-y))
> obj-y += sclp.o
> obj-y += event-facility.o
> obj-y += sclpquiesce.o sclpconsole.o
> +obj-y += ipl.o
> diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
> new file mode 100644
> index 0000000..1736fca
> --- /dev/null
> +++ b/hw/s390x/ipl.c
> @@ -0,0 +1,80 @@
> +/*
> + * bootloader support
> + *
> + * Copyright IBM, Corp. 2012
> + *
> + * Authors:
> + *  Christian Borntraeger <borntraeger@de.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or (at your
> + * option) any later version.  See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#include <sysemu.h>
> +#include "cpu.h"
> +#include "hw/loader.h"
> +#include "hw/sysbus.h"
> +#include "hw/s390x/ipl.h"
> +
> +void s390_ipl_cpu(uint64_t pswaddr)
> +{
> +    CPUS390XState *env = qemu_get_cpu(0);
> +    env->psw.addr = pswaddr;
> +    env->psw.mask = IPL_PSW_MASK;
> +    s390_add_running_cpu(env);
> +}
> +
> +static int s390_ipl_default_init(SysBusDevice *dev)
> +{
> +    return 0;
> +}
> +
> +static Property s390_ipl_properties[] = {
> +        DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void s390_ipl_reset(DeviceState *dev)
> +{
> +    if (rom_ptr(KERN_IMAGE_START)) {
> +        /*
> +         * we can not rely on the ELF entry point, since up to 3.2 this
> +         * value was 0x800 (the SALIPL loader) and it wont work. For
> +         * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine.
> +         */
> +        return s390_ipl_cpu(KERN_IMAGE_START);
> +    }
> +    return s390_ipl_cpu(ZIPL_IMAGE_START);
> +}
> +
> +static void s390_ipl_default_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
> +
> +    k->init = s390_ipl_default_init;
> +    dc->props = s390_ipl_properties;
> +    dc->reset = s390_ipl_reset;
> +    dc->no_user = 1;
> +}
> +
> +static TypeInfo s390_ipl_default_info = {
> +    .class_init = s390_ipl_default_class_init,
> +    .parent = TYPE_SYS_BUS_DEVICE,
> +    .name  = "s390-ipl-default",
> +};
> +
> +static void s390_register_ipl(void)
> +{
> +    type_register_static(&s390_ipl_default_info);
> +}
> +
> +type_init(s390_register_ipl)
> +
> +void s390_ipl_init(void)
> +{
> +    DeviceState *dev  = qdev_create(NULL, "s390-ipl-default");
> +    qdev_init_nofail(dev);
> +}
> +
> +
> diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
> new file mode 100644
> index 0000000..214abbc
> --- /dev/null
> +++ b/hw/s390x/ipl.h
> @@ -0,0 +1,34 @@
> +/*
> + * ipl support
> + *
> + * Copyright IBM, Corp. 2012
> + *
> + * Authors:
> + *  Christian Borntraeger <borntraeger@de.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or (at your
> + * option) any later version.  See the COPYING file in the top-level directory.
> + *
> + */
> +
> +
> +#ifndef S390_IPL_H
> +#define S390_IPL_H
> +
> +#define KERN_IMAGE_START                0x010000UL
> +#define KERN_PARM_AREA                  0x010480UL
> +#define INITRD_START                    0x800000UL
> +#define INITRD_PARM_START               0x010408UL
> +#define INITRD_PARM_SIZE                0x010410UL
> +#define PARMFILE_START                  0x001000UL
> +#define ZIPL_FILENAME                   "s390-zipl.rom"
> +#define ZIPL_IMAGE_START                0x009000UL
> +#define IPL_PSW_MASK                    0x0000000180000000ULL
> +
> +/* starts the first cpu with the given address and a default psw mask */
> +void s390_ipl_cpu(uint64_t pswaddr);
> +
> +/* Initialize the ipl code */
> +void s390_ipl_init(void);
> +
> +#endif //S390_IPL_H
> -- 
> 1.7.1
>

Patch

diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index d77871a..10a5fd7 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -33,6 +33,7 @@ 
 
 #include "hw/s390-virtio-bus.h"
 #include "hw/s390x/sclp.h"
+#include "hw/s390x/ipl.h"
 
 //#define DEBUG_S390
 
@@ -48,17 +49,6 @@ 
 #define KVM_S390_VIRTIO_RESET           1
 #define KVM_S390_VIRTIO_SET_STATUS      2
 
-#define KERN_IMAGE_START                0x010000UL
-#define KERN_PARM_AREA                  0x010480UL
-#define INITRD_START                    0x800000UL
-#define INITRD_PARM_START               0x010408UL
-#define INITRD_PARM_SIZE                0x010410UL
-#define PARMFILE_START                  0x001000UL
-
-#define ZIPL_START			0x009000UL
-#define ZIPL_LOAD_ADDR			0x009000UL
-#define ZIPL_FILENAME			"s390-zipl.rom"
-
 #define MAX_BLK_DEVS                    10
 
 static VirtIOS390Bus *s390_bus;
@@ -185,6 +175,7 @@  static void s390_init(QEMUMachineInitArgs *args)
     /* get a BUS */
     s390_bus = s390_virtio_bus_init(&my_ram_size);
     s390_sclp_init();
+    s390_ipl_init();
 
     /* allocate RAM */
     memory_region_init_ram(ram, "s390.ram", my_ram_size);
@@ -225,11 +216,7 @@  static void s390_init(QEMUMachineInitArgs *args)
         tmp_env->storage_keys = storage_keys;
     }
 
-    /* One CPU has to run */
-    s390_add_running_cpu(env);
-
     if (kernel_filename) {
-
         kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, NULL,
                                NULL, 1, ELF_MACHINE, 0);
         if (kernel_size == -1UL) {
@@ -240,13 +227,6 @@  static void s390_init(QEMUMachineInitArgs *args)
                     kernel_filename);
             exit(1);
         }
-        /*
-         * we can not rely on the ELF entry point, since up to 3.2 this
-         * value was 0x800 (the SALIPL loader) and it wont work. For
-         * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine.
-         */
-        env->psw.addr = KERN_IMAGE_START;
-        env->psw.mask = 0x0000000180000000ULL;
     } else {
         ram_addr_t bios_size = 0;
         char *bios_filename;
@@ -257,7 +237,7 @@  static void s390_init(QEMUMachineInitArgs *args)
         }
 
         bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-        bios_size = load_image_targphys(bios_filename, ZIPL_LOAD_ADDR, 4096);
+        bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START, 4096);
         g_free(bios_filename);
 
         if ((long)bios_size < 0) {
@@ -267,9 +247,6 @@  static void s390_init(QEMUMachineInitArgs *args)
         if (bios_size > 4096) {
             hw_error("stage1 bootloader is > 4k\n");
         }
-
-        env->psw.addr = ZIPL_START;
-        env->psw.mask = 0x0000000180000000ULL;
     }
 
     if (initrd_filename) {
@@ -352,3 +329,4 @@  static void s390_machine_init(void)
 }
 
 machine_init(s390_machine_init);
+
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 096dfcd..4a5a5d8 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -4,3 +4,4 @@  obj-y := $(addprefix ../,$(obj-y))
 obj-y += sclp.o
 obj-y += event-facility.o
 obj-y += sclpquiesce.o sclpconsole.o
+obj-y += ipl.o
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
new file mode 100644
index 0000000..1736fca
--- /dev/null
+++ b/hw/s390x/ipl.c
@@ -0,0 +1,80 @@ 
+/*
+ * bootloader support
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Christian Borntraeger <borntraeger@de.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at your
+ * option) any later version.  See the COPYING file in the top-level directory.
+ *
+ */
+
+#include <sysemu.h>
+#include "cpu.h"
+#include "hw/loader.h"
+#include "hw/sysbus.h"
+#include "hw/s390x/ipl.h"
+
+void s390_ipl_cpu(uint64_t pswaddr)
+{
+    CPUS390XState *env = qemu_get_cpu(0);
+    env->psw.addr = pswaddr;
+    env->psw.mask = IPL_PSW_MASK;
+    s390_add_running_cpu(env);
+}
+
+static int s390_ipl_default_init(SysBusDevice *dev)
+{
+    return 0;
+}
+
+static Property s390_ipl_properties[] = {
+        DEFINE_PROP_END_OF_LIST(),
+};
+
+static void s390_ipl_reset(DeviceState *dev)
+{
+    if (rom_ptr(KERN_IMAGE_START)) {
+        /*
+         * we can not rely on the ELF entry point, since up to 3.2 this
+         * value was 0x800 (the SALIPL loader) and it wont work. For
+         * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine.
+         */
+        return s390_ipl_cpu(KERN_IMAGE_START);
+    }
+    return s390_ipl_cpu(ZIPL_IMAGE_START);
+}
+
+static void s390_ipl_default_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = s390_ipl_default_init;
+    dc->props = s390_ipl_properties;
+    dc->reset = s390_ipl_reset;
+    dc->no_user = 1;
+}
+
+static TypeInfo s390_ipl_default_info = {
+    .class_init = s390_ipl_default_class_init,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .name  = "s390-ipl-default",
+};
+
+static void s390_register_ipl(void)
+{
+    type_register_static(&s390_ipl_default_info);
+}
+
+type_init(s390_register_ipl)
+
+void s390_ipl_init(void)
+{
+    DeviceState *dev  = qdev_create(NULL, "s390-ipl-default");
+    qdev_init_nofail(dev);
+}
+
+
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
new file mode 100644
index 0000000..214abbc
--- /dev/null
+++ b/hw/s390x/ipl.h
@@ -0,0 +1,34 @@ 
+/*
+ * ipl support
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Christian Borntraeger <borntraeger@de.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at your
+ * option) any later version.  See the COPYING file in the top-level directory.
+ *
+ */
+
+
+#ifndef S390_IPL_H
+#define S390_IPL_H
+
+#define KERN_IMAGE_START                0x010000UL
+#define KERN_PARM_AREA                  0x010480UL
+#define INITRD_START                    0x800000UL
+#define INITRD_PARM_START               0x010408UL
+#define INITRD_PARM_SIZE                0x010410UL
+#define PARMFILE_START                  0x001000UL
+#define ZIPL_FILENAME                   "s390-zipl.rom"
+#define ZIPL_IMAGE_START                0x009000UL
+#define IPL_PSW_MASK                    0x0000000180000000ULL
+
+/* starts the first cpu with the given address and a default psw mask */
+void s390_ipl_cpu(uint64_t pswaddr);
+
+/* Initialize the ipl code */
+void s390_ipl_init(void);
+
+#endif //S390_IPL_H