summary refs log tree commit diff stats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/s390x/ipl.c41
-rw-r--r--hw/s390x/s390-virtio-bus.c8
-rw-r--r--hw/s390x/s390-virtio-ccw.c2
-rw-r--r--hw/s390x/s390-virtio.c7
-rw-r--r--hw/s390x/s390-virtio.h3
5 files changed, 39 insertions, 22 deletions
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 206d552e16..ace5ff50d1 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -23,7 +23,6 @@
 #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                    (PSW_MASK_32 | PSW_MASK_64)
 
@@ -48,11 +47,13 @@ typedef struct S390IPLClass {
 typedef struct S390IPLState {
     /*< private >*/
     SysBusDevice parent_obj;
-    /*< public >*/
+    uint64_t start_addr;
 
+    /*< public >*/
     char *kernel;
     char *initrd;
     char *cmdline;
+    char *firmware;
 } S390IPLState;
 
 
@@ -77,20 +78,25 @@ static int s390_ipl_init(SysBusDevice *dev)
 
         /* Load zipl bootloader */
         if (bios_name == NULL) {
-            bios_name = ZIPL_FILENAME;
+            bios_name = ipl->firmware;
         }
 
         bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-        bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START, 4096);
+        bios_size = load_elf(bios_filename, NULL, NULL, &ipl->start_addr, NULL,
+                             NULL, 1, ELF_MACHINE, 0);
+        if (bios_size == -1UL) {
+            bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START,
+                                            4096);
+            ipl->start_addr = ZIPL_IMAGE_START;
+            if (bios_size > 4096) {
+                hw_error("stage1 bootloader is > 4k\n");
+            }
+        }
         g_free(bios_filename);
 
         if ((long)bios_size < 0) {
             hw_error("could not load bootloader '%s'\n", bios_name);
         }
-
-        if (bios_size > 4096) {
-            hw_error("stage1 bootloader is > 4k\n");
-        }
         return 0;
     } else {
         kernel_size = load_elf(ipl->kernel, NULL, NULL, NULL, NULL,
@@ -104,6 +110,13 @@ static int s390_ipl_init(SysBusDevice *dev)
         }
         /* we have to overwrite values in the kernel image, which are "rom" */
         strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline);
+
+        /*
+         * 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.
+         */
+        ipl->start_addr = KERN_IMAGE_START;
     }
     if (ipl->initrd) {
         ram_addr_t initrd_offset, initrd_size;
@@ -131,6 +144,7 @@ static Property s390_ipl_properties[] = {
     DEFINE_PROP_STRING("kernel", S390IPLState, kernel),
     DEFINE_PROP_STRING("initrd", S390IPLState, initrd),
     DEFINE_PROP_STRING("cmdline", S390IPLState, cmdline),
+    DEFINE_PROP_STRING("firmware", S390IPLState, firmware),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -138,16 +152,7 @@ static void s390_ipl_reset(DeviceState *dev)
 {
     S390IPLState *ipl = S390_IPL(dev);
 
-    if (ipl->kernel) {
-        /*
-         * 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);
-    } else {
-        return s390_ipl_cpu(ZIPL_IMAGE_START);
-    }
+    s390_ipl_cpu(ipl->start_addr);
 }
 
 static void s390_ipl_class_init(ObjectClass *klass, void *data)
diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index a7e81d159f..2cff6b794d 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -531,11 +531,19 @@ static const TypeInfo s390_virtio_serial = {
     .class_init    = s390_virtio_serial_class_init,
 };
 
+static Property s390_virtio_rng_properties[] = {
+    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOS390Device, host_features),
+    DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGS390, vdev.conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void s390_virtio_rng_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 
     k->init = s390_virtio_rng_init;
+    dc->props = s390_virtio_rng_properties;
 }
 
 static const TypeInfo s390_virtio_rng = {
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index a49e4401cd..eb774d90e0 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -83,7 +83,7 @@ static void ccw_init(QEMUMachineInitArgs *args)
     css_bus = virtual_css_bus_init();
     s390_sclp_init();
     s390_init_ipl_dev(args->kernel_filename, args->kernel_cmdline,
-                      args->initrd_filename);
+                      args->initrd_filename, "s390-ccw.img");
 
     /* register hypercalls */
     virtio_ccw_register_hcalls();
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 46aec999a6..30d1118cdc 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -49,6 +49,7 @@
 #endif
 
 #define MAX_BLK_DEVS                    10
+#define ZIPL_FILENAME                   "s390-zipl.rom"
 
 static VirtIOS390Bus *s390_bus;
 static S390CPU **ipi_states;
@@ -158,7 +159,8 @@ unsigned s390_del_running_cpu(S390CPU *cpu)
 
 void s390_init_ipl_dev(const char *kernel_filename,
                        const char *kernel_cmdline,
-                       const char *initrd_filename)
+                       const char *initrd_filename,
+                       const char *firmware)
 {
     DeviceState *dev;
 
@@ -170,6 +172,7 @@ void s390_init_ipl_dev(const char *kernel_filename,
         qdev_prop_set_string(dev, "initrd", initrd_filename);
     }
     qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
+    qdev_prop_set_string(dev, "firmware", firmware);
     qdev_init_nofail(dev);
 }
 
@@ -247,7 +250,7 @@ static void s390_init(QEMUMachineInitArgs *args)
     s390_bus = s390_virtio_bus_init(&my_ram_size);
     s390_sclp_init();
     s390_init_ipl_dev(args->kernel_filename, args->kernel_cmdline,
-                      args->initrd_filename);
+                      args->initrd_filename, ZIPL_FILENAME);
 
     /* register hypercalls */
     s390_virtio_register_hcalls();
diff --git a/hw/s390x/s390-virtio.h b/hw/s390x/s390-virtio.h
index a6c4c19895..5c405e7755 100644
--- a/hw/s390x/s390-virtio.h
+++ b/hw/s390x/s390-virtio.h
@@ -23,6 +23,7 @@ void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn);
 void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys);
 void s390_init_ipl_dev(const char *kernel_filename,
                        const char *kernel_cmdline,
-                       const char *initrd_filename);
+                       const char *initrd_filename,
+                       const char *firmware);
 void s390_create_virtio_net(BusState *bus, const char *name);
 #endif