a0e11b617b
Loadparm is defined by the s390 architecture to be 8 bytes in length. Let's define this size in the s390-ccw bios. Suggested-by: Laszlo Ersek <lersek@redhat.com> Signed-off-by: Collin Walling <walling@linux.ibm.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
127 lines
2.9 KiB
C
127 lines
2.9 KiB
C
/*
|
|
* QEMU S390 IPL Block
|
|
*
|
|
* Copyright 2015 IBM Corp.
|
|
* Author(s): Alexander Yarygin <yarygin@linux.vnet.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 IPLB_H
|
|
#define IPLB_H
|
|
|
|
#define LOADPARM_LEN 8
|
|
|
|
struct IplBlockCcw {
|
|
uint8_t reserved0[85];
|
|
uint8_t ssid;
|
|
uint16_t devno;
|
|
uint8_t vm_flags;
|
|
uint8_t reserved3[3];
|
|
uint32_t vm_parm_len;
|
|
uint8_t nss_name[8];
|
|
uint8_t vm_parm[64];
|
|
uint8_t reserved4[8];
|
|
} __attribute__ ((packed));
|
|
typedef struct IplBlockCcw IplBlockCcw;
|
|
|
|
struct IplBlockFcp {
|
|
uint8_t reserved1[305 - 1];
|
|
uint8_t opt;
|
|
uint8_t reserved2[3];
|
|
uint16_t reserved3;
|
|
uint16_t devno;
|
|
uint8_t reserved4[4];
|
|
uint64_t wwpn;
|
|
uint64_t lun;
|
|
uint32_t bootprog;
|
|
uint8_t reserved5[12];
|
|
uint64_t br_lba;
|
|
uint32_t scp_data_len;
|
|
uint8_t reserved6[260];
|
|
uint8_t scp_data[];
|
|
} __attribute__ ((packed));
|
|
typedef struct IplBlockFcp IplBlockFcp;
|
|
|
|
struct IplBlockQemuScsi {
|
|
uint32_t lun;
|
|
uint16_t target;
|
|
uint16_t channel;
|
|
uint8_t reserved0[77];
|
|
uint8_t ssid;
|
|
uint16_t devno;
|
|
} __attribute__ ((packed));
|
|
typedef struct IplBlockQemuScsi IplBlockQemuScsi;
|
|
|
|
struct IplParameterBlock {
|
|
uint32_t len;
|
|
uint8_t reserved0[3];
|
|
uint8_t version;
|
|
uint32_t blk0_len;
|
|
uint8_t pbt;
|
|
uint8_t flags;
|
|
uint16_t reserved01;
|
|
uint8_t loadparm[LOADPARM_LEN];
|
|
union {
|
|
IplBlockCcw ccw;
|
|
IplBlockFcp fcp;
|
|
IplBlockQemuScsi scsi;
|
|
};
|
|
} __attribute__ ((packed));
|
|
typedef struct IplParameterBlock IplParameterBlock;
|
|
|
|
extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
|
|
|
|
#define QIPL_ADDRESS 0xcc
|
|
|
|
/* Boot Menu flags */
|
|
#define QIPL_FLAG_BM_OPTS_CMD 0x80
|
|
#define QIPL_FLAG_BM_OPTS_ZIPL 0x40
|
|
|
|
/*
|
|
* This definition must be kept in sync with the defininition
|
|
* in hw/s390x/ipl.h
|
|
*/
|
|
struct QemuIplParameters {
|
|
uint8_t qipl_flags;
|
|
uint8_t reserved1[3];
|
|
uint64_t netboot_start_addr;
|
|
uint32_t boot_menu_timeout;
|
|
uint8_t reserved2[12];
|
|
} __attribute__ ((packed));
|
|
typedef struct QemuIplParameters QemuIplParameters;
|
|
|
|
extern QemuIplParameters qipl;
|
|
|
|
#define S390_IPL_TYPE_FCP 0x00
|
|
#define S390_IPL_TYPE_CCW 0x02
|
|
#define S390_IPL_TYPE_QEMU_SCSI 0xff
|
|
|
|
static inline bool manage_iplb(IplParameterBlock *iplb, bool store)
|
|
{
|
|
register unsigned long addr asm("0") = (unsigned long) iplb;
|
|
register unsigned long rc asm("1") = 0;
|
|
unsigned long subcode = store ? 6 : 5;
|
|
|
|
asm volatile ("diag %0,%2,0x308\n"
|
|
: "+d" (addr), "+d" (rc)
|
|
: "d" (subcode)
|
|
: "memory", "cc");
|
|
return rc == 0x01;
|
|
}
|
|
|
|
|
|
static inline bool store_iplb(IplParameterBlock *iplb)
|
|
{
|
|
return manage_iplb(iplb, true);
|
|
}
|
|
|
|
static inline bool set_iplb(IplParameterBlock *iplb)
|
|
{
|
|
return manage_iplb(iplb, false);
|
|
}
|
|
|
|
#endif /* IPLB_H */
|