提交 c8cda874 编写于 作者: D Dominik Dingel 提交者: Alexander Graf

s390/IPL: Allow boot from other ssid than 0

We now take the subchannel set id also into account to find the boot device.
If we want to use a subchannel set other than the default set 0, we first
need to enable the mss facility.
Signed-off-by: NDominik Dingel <dingel@linux.vnet.ibm.com>
Signed-off-by: NChristian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: NAlexander Graf <agraf@suse.de>
上级 461bdb34
......@@ -93,6 +93,26 @@ struct subchannel_id {
__u32 sch_no : 16;
} __attribute__ ((packed, aligned(4)));
struct chsc_header {
__u16 length;
__u16 code;
} __attribute__((packed));
struct chsc_area_sda {
struct chsc_header request;
__u8 reserved1:4;
__u8 format:4;
__u8 reserved2;
__u16 operation_code;
__u32 reserved3;
__u32 reserved4;
__u32 operation_data_area[252];
struct chsc_header response;
__u32 reserved5:4;
__u32 format2:4;
__u32 reserved6:24;
} __attribute__((packed));
/*
* TPI info structure
*/
......
......@@ -35,6 +35,13 @@ static void virtio_setup(uint64_t dev_info)
check_devno = true;
dev_no = dev_info & 0xffff;
debug_print_int("device no. ", dev_no);
blk_schid.ssid = (dev_info >> 16) & 0x3;
if (blk_schid.ssid != 0) {
debug_print_int("ssid ", blk_schid.ssid);
if (enable_mss_facility() != 0) {
virtio_panic("Failed to enable mss facility\n");
}
}
}
for (i = 0; i < 0x10000; i++) {
......
......@@ -61,6 +61,7 @@ unsigned long virtio_load_direct(ulong rec_list1, ulong rec_list2,
bool virtio_is_blk(struct subchannel_id schid);
void virtio_setup_block(struct subchannel_id schid);
int virtio_read(ulong sector, void *load_addr);
int enable_mss_facility(void);
/* bootmap.c */
int zipl_load(void);
......
......@@ -13,6 +13,8 @@
struct vring block;
static char chsc_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
static long kvm_hypercall(unsigned long nr, unsigned long param1,
unsigned long param2)
{
......@@ -301,3 +303,19 @@ bool virtio_is_blk(struct subchannel_id schid)
return true;
}
int enable_mss_facility(void)
{
int ret;
struct chsc_area_sda *sda_area = (struct chsc_area_sda *) chsc_page;
memset(sda_area, 0, PAGE_SIZE);
sda_area->request.length = 0x0400;
sda_area->request.code = 0x0031;
sda_area->operation_code = 0x2;
ret = chsc(sda_area);
if ((ret == 0) && (sda_area->response.code == 0x0001)) {
return 0;
}
return -EIO;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册