master
h 73 lines 1.64 KB
Raw
1 /*
2 * QEMU S390 IPL Block
3 *
4 * Copyright 2015 IBM Corp.
5 * Author(s): Alexander Yarygin <yarygin@linux.vnet.ibm.com>
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2 or (at
8 * your option) any later version. See the COPYING file in the top-level
9 * directory.
10 */
11
12 #ifndef IPLB_H
13 #define IPLB_H
14
15 #ifndef QEMU_PACKED
16 #define QEMU_PACKED __attribute__((packed))
17 #endif
18
19 #include <qipl.h>
20 #include <string.h>
21
22 extern QemuIplParameters qipl;
23 extern IplParameterBlock *iplb;
24 extern bool have_iplb;
25 extern IplBlocks ipl_blocks;
26
27 static inline bool manage_iplb(IplParameterBlock *iplb, bool store)
28 {
29 register unsigned long addr asm("0") = (unsigned long) iplb;
30 register unsigned long rc asm("1") = 0;
31 unsigned long subcode = store ? 6 : 5;
32
33 asm volatile ("diag %0,%2,0x308\n"
34 : "+d" (addr), "+d" (rc)
35 : "d" (subcode)
36 : "memory", "cc");
37 return rc == 0x01;
38 }
39
40
41 static inline bool store_iplb(IplParameterBlock *iplb)
42 {
43 return manage_iplb(iplb, true);
44 }
45
46 static inline bool set_iplb(IplParameterBlock *iplb)
47 {
48 return manage_iplb(iplb, false);
49 }
50
51 /*
52 * The IPL started on the device, but failed in some way. If the IPLB chain
53 * still has more devices left to try, use the next device in order.
54 */
55 static inline bool load_next_iplb(void)
56 {
57 IplParameterBlock *next_iplb;
58
59 if (qipl.chain_len < 1) {
60 return false;
61 }
62
63 qipl.index++;
64 next_iplb = (IplParameterBlock *) qipl.ipl_data;
65 memcpy(iplb, next_iplb, sizeof(IplParameterBlock));
66
67 qipl.chain_len--;
68 qipl.ipl_data = qipl.ipl_data + sizeof(IplParameterBlock);
69
70 return true;
71 }
72
73 #endif /* IPLB_H */