xref: /openbmc/qemu/pc-bios/s390-ccw/iplb.h (revision e17e57e862faf6e1f372385c18dcf6d3fd31158e)
1d046c51dSAlexander Yarygin /*
2d046c51dSAlexander Yarygin  * QEMU S390 IPL Block
3d046c51dSAlexander Yarygin  *
4d046c51dSAlexander Yarygin  * Copyright 2015 IBM Corp.
5d046c51dSAlexander Yarygin  * Author(s): Alexander Yarygin <yarygin@linux.vnet.ibm.com>
6d046c51dSAlexander Yarygin  *
7d046c51dSAlexander Yarygin  * This work is licensed under the terms of the GNU GPL, version 2 or (at
8d046c51dSAlexander Yarygin  * your option) any later version. See the COPYING file in the top-level
9d046c51dSAlexander Yarygin  * directory.
10d046c51dSAlexander Yarygin  */
11d046c51dSAlexander Yarygin 
12d046c51dSAlexander Yarygin #ifndef IPLB_H
13d046c51dSAlexander Yarygin #define IPLB_H
14d046c51dSAlexander Yarygin 
15ba3658adSJared Rossi #ifndef QEMU_PACKED
16ba3658adSJared Rossi #define QEMU_PACKED __attribute__((packed))
17ba3658adSJared Rossi #endif
18a0e11b61SCollin Walling 
19ba3658adSJared Rossi #include <qipl.h>
20*f697bed2SJared Rossi #include <string.h>
21118ee80fSCollin L. Walling 
22118ee80fSCollin L. Walling extern QemuIplParameters qipl;
23ba3658adSJared Rossi extern IplParameterBlock iplb __attribute__((__aligned__(PAGE_SIZE)));
24*f697bed2SJared Rossi extern bool have_iplb;
25118ee80fSCollin L. Walling 
26d046c51dSAlexander Yarygin #define S390_IPL_TYPE_FCP 0x00
27d046c51dSAlexander Yarygin #define S390_IPL_TYPE_CCW 0x02
28b39b7718SEugene (jno) Dvurechenski #define S390_IPL_TYPE_QEMU_SCSI 0xff
29d046c51dSAlexander Yarygin 
manage_iplb(IplParameterBlock * iplb,bool store)30e8c7ef28SViktor Mihajlovski static inline bool manage_iplb(IplParameterBlock *iplb, bool store)
31d046c51dSAlexander Yarygin {
32d046c51dSAlexander Yarygin     register unsigned long addr asm("0") = (unsigned long) iplb;
33d046c51dSAlexander Yarygin     register unsigned long rc asm("1") = 0;
3463d8b5acSCornelia Huck     unsigned long subcode = store ? 6 : 5;
35d046c51dSAlexander Yarygin 
36d046c51dSAlexander Yarygin     asm volatile ("diag %0,%2,0x308\n"
37d046c51dSAlexander Yarygin                   : "+d" (addr), "+d" (rc)
3863d8b5acSCornelia Huck                   : "d" (subcode)
39d046c51dSAlexander Yarygin                   : "memory", "cc");
40d046c51dSAlexander Yarygin     return rc == 0x01;
41d046c51dSAlexander Yarygin }
42d046c51dSAlexander Yarygin 
43e8c7ef28SViktor Mihajlovski 
store_iplb(IplParameterBlock * iplb)44e8c7ef28SViktor Mihajlovski static inline bool store_iplb(IplParameterBlock *iplb)
45e8c7ef28SViktor Mihajlovski {
46e8c7ef28SViktor Mihajlovski     return manage_iplb(iplb, true);
47e8c7ef28SViktor Mihajlovski }
48e8c7ef28SViktor Mihajlovski 
set_iplb(IplParameterBlock * iplb)49e8c7ef28SViktor Mihajlovski static inline bool set_iplb(IplParameterBlock *iplb)
50e8c7ef28SViktor Mihajlovski {
51e8c7ef28SViktor Mihajlovski     return manage_iplb(iplb, false);
52e8c7ef28SViktor Mihajlovski }
53e8c7ef28SViktor Mihajlovski 
54*f697bed2SJared Rossi /*
55*f697bed2SJared Rossi  * The IPL started on the device, but failed in some way.  If the IPLB chain
56*f697bed2SJared Rossi  * still has more devices left to try, use the next device in order.
57*f697bed2SJared Rossi  */
load_next_iplb(void)58*f697bed2SJared Rossi static inline bool load_next_iplb(void)
59*f697bed2SJared Rossi {
60*f697bed2SJared Rossi     IplParameterBlock *next_iplb;
61*f697bed2SJared Rossi 
62*f697bed2SJared Rossi     if (qipl.chain_len < 1) {
63*f697bed2SJared Rossi         return false;
64*f697bed2SJared Rossi     }
65*f697bed2SJared Rossi 
66*f697bed2SJared Rossi     qipl.index++;
67*f697bed2SJared Rossi     next_iplb = (IplParameterBlock *) qipl.next_iplb;
68*f697bed2SJared Rossi     memcpy(&iplb, next_iplb, sizeof(IplParameterBlock));
69*f697bed2SJared Rossi 
70*f697bed2SJared Rossi     qipl.chain_len--;
71*f697bed2SJared Rossi     qipl.next_iplb = qipl.next_iplb + sizeof(IplParameterBlock);
72*f697bed2SJared Rossi 
73*f697bed2SJared Rossi     return true;
74*f697bed2SJared Rossi }
75*f697bed2SJared Rossi 
76d046c51dSAlexander Yarygin #endif /* IPLB_H */
77