diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 36daa67..960ba71 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -77,6 +77,10 @@ static void s390_ipl_from_disk(VirtIOBlkCcw *dev, uint64_t pswaddr)
     env->psw.addr = pswaddr;
     env->psw.mask = IPL_PSW_MASK;
     env->regs[7] = ccw_dev->sch->devno;
+    env->regs[7] = (env->regs[7] << 16) | (ccw_dev->sch->schid);
+    env->regs[7] = (env->regs[7] << 8) | (ccw_dev->sch->cssid);
+    env->regs[7] = (env->regs[7] << 8) | (ccw_dev->sch->ssid);
+    env->regs[8] = ccw_dev->loadparm;
     s390_add_running_cpu(cpu);
 }
 
diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img
index b549a86e55194bbf54e25f839e52b490ac308260..fe8d2c6b9f5d937ea156084f7eb248b17e1fa89c 100644
GIT binary patch
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index 53a460d..9cd3edf 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -173,7 +173,7 @@ fail:
     return -1;
 }
 
-int zipl_load(void)
+int zipl_load(uint64_t load_parm)
 {
     struct mbr *mbr = (void*)sec;
     uint8_t *ns, *ns_end;
@@ -223,7 +223,7 @@ int zipl_load(void)
 
     /* Run the default entry */
 
-    prog_table_entry = (struct scsi_blockptr *)(sec + pte_len);
+    prog_table_entry = (struct scsi_blockptr *)(sec + (pte_len *(1+load_parm)));
 
     return zipl_run(prog_table_entry);
 
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index fd40fa5..0c1c11c 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -20,7 +20,7 @@ void virtio_panic(const char *string)
     while (1) { }
 }
 
-static void virtio_setup(void)
+static void virtio_setup(uint16_t dev_no)
 {
     struct schib schib;
     int i;
@@ -35,7 +35,7 @@ static void virtio_setup(void)
         if (r == 3) {
             break;
         }
-        if (schib.pmcw.dnv) {
+        if (schib.pmcw.dnv && (schib.pmcw.dev == dev_no)) {
             if (virtio_is_blk(blk_schid)) {
                 found = true;
                 break;
@@ -52,10 +52,24 @@ static void virtio_setup(void)
 
 int main(void)
 {
+    uint64_t boot_value;
+    uint64_t load_parm;
+    register uint64_t reg7 asm("7");
+    register uint64_t reg8 asm("8");
+    
+    asm volatile(
+            "   stg     %2, %0\n"
+            "   stg     %3, %1\n"
+            : "=m" (boot_value), "=m" (load_parm)
+            : "d" (reg7), "d" (reg8)
+            : "cc");
+    
     sclp_setup();
-    virtio_setup();
-    if (zipl_load() < 0)
+    virtio_setup(boot_value >> 32);
+
+    if (zipl_load(load_parm) < 0) {
         sclp_print("Failed to load OS from hard disk\n");
+    }
     disabled_wait();
     while (1) { }
 }
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 8241b0a..2851995 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -63,7 +63,7 @@ void virtio_setup_block(struct subchannel_id schid);
 int virtio_read(ulong sector, void *load_addr);
 
 /* bootmap.c */
-int zipl_load(void);
+int zipl_load(uint64_t load_parm);
 
 static inline void *memset(void *s, int c, size_t n)
 {
