aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/s390x/ipl.c25
-rw-r--r--hw/s390x/ipl.h18
-rw-r--r--pc-bios/s390-ccw.imgbin42608 -> 42608 bytes
-rw-r--r--pc-bios/s390-ccw/jump2ipl.c1
-rw-r--r--pc-bios/s390-ccw/main.c8
-rw-r--r--pc-bios/s390-ccw/netmain.c1
-rw-r--r--pc-bios/s390-ccw/s390-arch.h10
-rw-r--r--pc-bios/s390-ccw/s390-ccw.h1
-rw-r--r--target/s390x/diag.c2
9 files changed, 53 insertions, 13 deletions
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 9c1ecd423c..b81942e1e6 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -538,6 +538,30 @@ static bool is_virtio_scsi_device(IplParameterBlock *iplb)
return is_virtio_ccw_device_of_type(iplb, VIRTIO_ID_SCSI);
}
+static void update_machine_ipl_properties(IplParameterBlock *iplb)
+{
+ Object *machine = qdev_get_machine();
+ Error *err = NULL;
+
+ /* Sync loadparm */
+ if (iplb->flags & DIAG308_FLAGS_LP_VALID) {
+ uint8_t *ebcdic_loadparm = iplb->loadparm;
+ char ascii_loadparm[8];
+ int i;
+
+ for (i = 0; i < 8 && ebcdic_loadparm[i]; i++) {
+ ascii_loadparm[i] = ebcdic2ascii[(uint8_t) ebcdic_loadparm[i]];
+ }
+ ascii_loadparm[i] = 0;
+ object_property_set_str(machine, ascii_loadparm, "loadparm", &err);
+ } else {
+ object_property_set_str(machine, "", "loadparm", &err);
+ }
+ if (err) {
+ warn_report_err(err);
+ }
+}
+
void s390_ipl_update_diag308(IplParameterBlock *iplb)
{
S390IPLState *ipl = get_ipl_device();
@@ -545,6 +569,7 @@ void s390_ipl_update_diag308(IplParameterBlock *iplb)
ipl->iplb = *iplb;
ipl->iplb_valid = true;
ipl->netboot = is_virtio_net_device(iplb);
+ update_machine_ipl_properties(iplb);
}
IplParameterBlock *s390_ipl_get_iplb(void)
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index d4813105db..3e44abe1c6 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -173,16 +173,16 @@ static inline bool iplb_valid_len(IplParameterBlock *iplb)
return be32_to_cpu(iplb->len) <= sizeof(IplParameterBlock);
}
-static inline bool iplb_valid_ccw(IplParameterBlock *iplb)
+static inline bool iplb_valid(IplParameterBlock *iplb)
{
- return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN &&
- iplb->pbt == S390_IPL_TYPE_CCW;
-}
-
-static inline bool iplb_valid_fcp(IplParameterBlock *iplb)
-{
- return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN &&
- iplb->pbt == S390_IPL_TYPE_FCP;
+ switch (iplb->pbt) {
+ case S390_IPL_TYPE_FCP:
+ return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_FCP_LEN;
+ case S390_IPL_TYPE_CCW:
+ return be32_to_cpu(iplb->len) >= S390_IPLB_MIN_CCW_LEN;
+ default:
+ return false;
+ }
}
#endif
diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img
index 91cdee4436..b9da9d8ecb 100644
--- a/pc-bios/s390-ccw.img
+++ b/pc-bios/s390-ccw.img
Binary files differ
diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
index da13c43cc0..4eba2510b0 100644
--- a/pc-bios/s390-ccw/jump2ipl.c
+++ b/pc-bios/s390-ccw/jump2ipl.c
@@ -35,6 +35,7 @@ void jump_to_IPL_code(uint64_t address)
{
/* store the subsystem information _after_ the bootmap was loaded */
write_subsystem_identification();
+ write_iplb_location();
/* prevent unknown IPL types in the guest */
if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index a21b386280..4e65b411e1 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -9,6 +9,7 @@
*/
#include "libc.h"
+#include "helper.h"
#include "s390-arch.h"
#include "s390-ccw.h"
#include "cio.h"
@@ -22,7 +23,7 @@ QemuIplParameters qipl;
IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
static bool have_iplb;
static uint16_t cutype;
-LowCore const *lowcore; /* Yes, this *is* a pointer to address 0 */
+LowCore *lowcore; /* Yes, this *is* a pointer to address 0 */
#define LOADPARM_PROMPT "PROMPT "
#define LOADPARM_EMPTY " "
@@ -42,6 +43,11 @@ void write_subsystem_identification(void)
*zeroes = 0;
}
+void write_iplb_location(void)
+{
+ lowcore->ptr_iplb = ptr2u32(&iplb);
+}
+
void panic(const char *string)
{
sclp_print(string);
diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index f2dcc01e27..309ffa30d9 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -40,6 +40,7 @@
#define DEFAULT_TFTP_RETRIES 20
extern char _start[];
+void write_iplb_location(void) {}
#define KERNEL_ADDR ((void *)0L)
#define KERNEL_MAX_SIZE ((long)_start)
diff --git a/pc-bios/s390-ccw/s390-arch.h b/pc-bios/s390-ccw/s390-arch.h
index 504fc7c2f0..5f36361c02 100644
--- a/pc-bios/s390-ccw/s390-arch.h
+++ b/pc-bios/s390-ccw/s390-arch.h
@@ -36,7 +36,13 @@ typedef struct LowCore {
/* prefix area: defined by architecture */
PSWLegacy ipl_psw; /* 0x000 */
uint32_t ccw1[2]; /* 0x008 */
- uint32_t ccw2[2]; /* 0x010 */
+ union {
+ uint32_t ccw2[2]; /* 0x010 */
+ struct {
+ uint32_t reserved10;
+ uint32_t ptr_iplb;
+ };
+ };
uint8_t pad1[0x80 - 0x18]; /* 0x018 */
uint32_t ext_params; /* 0x080 */
uint16_t cpu_addr; /* 0x084 */
@@ -85,7 +91,7 @@ typedef struct LowCore {
PSW io_new_psw; /* 0x1f0 */
} __attribute__((packed, aligned(8192))) LowCore;
-extern LowCore const *lowcore;
+extern LowCore *lowcore;
static inline void set_prefix(uint32_t address)
{
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 11bce7d73c..21f27e7990 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -57,6 +57,7 @@ void consume_io_int(void);
/* main.c */
void panic(const char *string);
void write_subsystem_identification(void);
+void write_iplb_location(void);
extern char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
unsigned int get_loadparm_index(void);
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
index b5aec06d6b..54e5670b3f 100644
--- a/target/s390x/diag.c
+++ b/target/s390x/diag.c
@@ -117,7 +117,7 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
cpu_physical_memory_read(addr, iplb, be32_to_cpu(iplb->len));
- if (!iplb_valid_ccw(iplb) && !iplb_valid_fcp(iplb)) {
+ if (!iplb_valid(iplb)) {
env->regs[r1 + 1] = DIAG_308_RC_INVALID;
goto out;
}