mirror of https://gitlab.com/qemu-project/qemu
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
1.8 KiB
C
77 lines
1.8 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
|
|
|
|
#ifndef QEMU_PACKED
|
|
#define QEMU_PACKED __attribute__((packed))
|
|
#endif
|
|
|
|
#include <qipl.h>
|
|
#include <string.h>
|
|
|
|
extern QemuIplParameters qipl;
|
|
extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
|
|
extern bool have_iplb;
|
|
|
|
#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);
|
|
}
|
|
|
|
/*
|
|
* The IPL started on the device, but failed in some way. If the IPLB chain
|
|
* still has more devices left to try, use the next device in order.
|
|
*/
|
|
static inline bool load_next_iplb(void)
|
|
{
|
|
IplParameterBlock *next_iplb;
|
|
|
|
if (qipl.chain_len < 1) {
|
|
return false;
|
|
}
|
|
|
|
qipl.index++;
|
|
next_iplb = (IplParameterBlock *) qipl.next_iplb;
|
|
memcpy(&iplb, next_iplb, sizeof(IplParameterBlock));
|
|
|
|
qipl.chain_len--;
|
|
qipl.next_iplb = qipl.next_iplb + sizeof(IplParameterBlock);
|
|
|
|
return true;
|
|
}
|
|
|
|
#endif /* IPLB_H */
|