xref: /openbmc/qemu/pc-bios/s390-ccw/s390-arch.h (revision 0d5fae3e)
1 /*
2  * S390 Basic Architecture
3  *
4  * Copyright (c) 2019 Jason J. Herne <jjherne@us.ibm.com>
5  *
6  * This work is licensed under the terms of the GNU GPL, version 2 or (at
7  * your option) any later version. See the COPYING file in the top-level
8  * directory.
9  */
10 
11 #ifndef S390_ARCH_H
12 #define S390_ARCH_H
13 
14 typedef struct PSW {
15     uint64_t mask;
16     uint64_t addr;
17 } __attribute__ ((aligned(8))) PSW;
18 _Static_assert(sizeof(struct PSW) == 16, "PSW size incorrect");
19 
20 /* Older PSW format used by LPSW instruction */
21 typedef struct PSWLegacy {
22     uint32_t mask;
23     uint32_t addr;
24 } __attribute__ ((aligned(8))) PSWLegacy;
25 _Static_assert(sizeof(struct PSWLegacy) == 8, "PSWLegacy size incorrect");
26 
27 /* s390 psw bit masks */
28 #define PSW_MASK_IOINT      0x0200000000000000ULL
29 #define PSW_MASK_WAIT       0x0002000000000000ULL
30 #define PSW_MASK_EAMODE     0x0000000100000000ULL
31 #define PSW_MASK_BAMODE     0x0000000080000000ULL
32 #define PSW_MASK_ZMODE      (PSW_MASK_EAMODE | PSW_MASK_BAMODE)
33 
34 /* Low core mapping */
35 typedef struct LowCore {
36     /* prefix area: defined by architecture */
37     PSWLegacy       ipl_psw;                  /* 0x000 */
38     uint32_t        ccw1[2];                  /* 0x008 */
39     uint32_t        ccw2[2];                  /* 0x010 */
40     uint8_t         pad1[0x80 - 0x18];        /* 0x018 */
41     uint32_t        ext_params;               /* 0x080 */
42     uint16_t        cpu_addr;                 /* 0x084 */
43     uint16_t        ext_int_code;             /* 0x086 */
44     uint16_t        svc_ilen;                 /* 0x088 */
45     uint16_t        svc_code;                 /* 0x08a */
46     uint16_t        pgm_ilen;                 /* 0x08c */
47     uint16_t        pgm_code;                 /* 0x08e */
48     uint32_t        data_exc_code;            /* 0x090 */
49     uint16_t        mon_class_num;            /* 0x094 */
50     uint16_t        per_perc_atmid;           /* 0x096 */
51     uint64_t        per_address;              /* 0x098 */
52     uint8_t         exc_access_id;            /* 0x0a0 */
53     uint8_t         per_access_id;            /* 0x0a1 */
54     uint8_t         op_access_id;             /* 0x0a2 */
55     uint8_t         ar_access_id;             /* 0x0a3 */
56     uint8_t         pad2[0xA8 - 0xA4];        /* 0x0a4 */
57     uint64_t        trans_exc_code;           /* 0x0a8 */
58     uint64_t        monitor_code;             /* 0x0b0 */
59     uint16_t        subchannel_id;            /* 0x0b8 */
60     uint16_t        subchannel_nr;            /* 0x0ba */
61     uint32_t        io_int_parm;              /* 0x0bc */
62     uint32_t        io_int_word;              /* 0x0c0 */
63     uint8_t         pad3[0xc8 - 0xc4];        /* 0x0c4 */
64     uint32_t        stfl_fac_list;            /* 0x0c8 */
65     uint8_t         pad4[0xe8 - 0xcc];        /* 0x0cc */
66     uint64_t        mcic;                     /* 0x0e8 */
67     uint8_t         pad5[0xf4 - 0xf0];        /* 0x0f0 */
68     uint32_t        external_damage_code;     /* 0x0f4 */
69     uint64_t        failing_storage_address;  /* 0x0f8 */
70     uint8_t         pad6[0x110 - 0x100];      /* 0x100 */
71     uint64_t        per_breaking_event_addr;  /* 0x110 */
72     uint8_t         pad7[0x120 - 0x118];      /* 0x118 */
73     PSW             restart_old_psw;          /* 0x120 */
74     PSW             external_old_psw;         /* 0x130 */
75     PSW             svc_old_psw;              /* 0x140 */
76     PSW             program_old_psw;          /* 0x150 */
77     PSW             mcck_old_psw;             /* 0x160 */
78     PSW             io_old_psw;               /* 0x170 */
79     uint8_t         pad8[0x1a0 - 0x180];      /* 0x180 */
80     PSW             restart_new_psw;          /* 0x1a0 */
81     PSW             external_new_psw;         /* 0x1b0 */
82     PSW             svc_new_psw;              /* 0x1c0 */
83     PSW             program_new_psw;          /* 0x1d0 */
84     PSW             mcck_new_psw;             /* 0x1e0 */
85     PSW             io_new_psw;               /* 0x1f0 */
86 } __attribute__((packed, aligned(8192))) LowCore;
87 
88 extern LowCore const *lowcore;
89 
90 static inline void set_prefix(uint32_t address)
91 {
92     asm volatile("spx %0" : : "m" (address) : "memory");
93 }
94 
95 static inline uint32_t store_prefix(void)
96 {
97     uint32_t address;
98 
99     asm volatile("stpx %0" : "=m" (address));
100     return address;
101 }
102 
103 #endif
104