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