5export module arch.s390x.cpu.psw;
6import zxfoundation.base.types;
12namespace arch::s390x::cpu::psw {
15 constexpr u64 PSW_BIT_DAT = 0x0400000000000000ULL;
18 constexpr u64 PSW_BIT_IO = 0x0200000000000000ULL;
21 constexpr u64 PSW_BIT_EXT = 0x0100000000000000ULL;
24 constexpr u64 PSW_BIT_MCCK = 0x0004000000000000ULL;
27 constexpr u64 PSW_BIT_WAIT = 0x0002000000000000ULL;
30 constexpr u64 PSW_BIT_PSTATE = 0x0001000000000000ULL;
33 constexpr u64 PSW_BIT_EA = 0x0000000100000000ULL;
36 constexpr u64 PSW_BIT_BA = 0x0000000080000000ULL;
39 constexpr u64 PSW_ASC_PRIMARY = 0x0000000000000000ULL;
42 constexpr u64 PSW_ASC_SECONDARY = 0x0000800000000000ULL;
45 constexpr u64 PSW_ASC_ACCREG = 0x0000400000000000ULL;
48 constexpr u64 PSW_ASC_HOME = 0x0000C00000000000ULL;
51 constexpr u64 PSW_DEFAULT_KEY = 0ULL;
54 constexpr u64 PSW_ARCH_BITS = PSW_BIT_EA | PSW_BIT_BA;
57 constexpr u64 PSW_MASK_KERNEL = PSW_DEFAULT_KEY | PSW_ARCH_BITS | PSW_ASC_PRIMARY;
60 constexpr u64 PSW_MASK_KERNEL_DAT = PSW_DEFAULT_KEY | PSW_BIT_DAT | PSW_ARCH_BITS | PSW_ASC_HOME;
63 constexpr u64 PSW_MASK_KERNEL_ENABLED =
64 PSW_DEFAULT_KEY | PSW_BIT_DAT | PSW_BIT_IO | PSW_BIT_EXT | PSW_BIT_MCCK |
65 PSW_ARCH_BITS | PSW_ASC_HOME;
68 constexpr u64 PSW_MASK_USER =
79 constexpr u32 PSW_KEY_SHIFT = 52;
82 constexpr u64 PSW_MASK_DISABLED_WAIT = PSW_DEFAULT_KEY | PSW_BIT_WAIT | PSW_ARCH_BITS;
85 constexpr u64 PSW_MASK_ENABLED_WAIT =
86 PSW_DEFAULT_KEY | PSW_BIT_DAT | PSW_BIT_IO | PSW_BIT_EXT | PSW_BIT_MCCK |
87 PSW_BIT_WAIT | PSW_ARCH_BITS | PSW_ASC_HOME;
90 constexpr u64 PSW_STD_HALT_ADDR = 0x0000000000DEAD00ULL;
92 constexpr u64 PSW_LC_RESTART = 0x01A0ULL;
93 constexpr u64 PSW_LC_EXTERNAL = 0x01B0ULL;
94 constexpr u64 PSW_LC_SVC = 0x01C0ULL;
95 constexpr u64 PSW_LC_PROGRAM = 0x01D0ULL;
96 constexpr u64 PSW_LC_MCCK = 0x01E0ULL;
97 constexpr u64 PSW_LC_IO = 0x01F0ULL;
99 enum class psw_basic_addressing_modes : u64 {
105 using psw_mask = lib::record<u64, lib::msb0_t,
106 lib::rw<
"per_mask", lib::bits<1, 1>>,
107 lib::rw<
"dat_mode", lib::bits<5, 5>>,
108 lib::rw<
"io_mask", lib::bits<6, 6>>,
109 lib::rw<
"external_mask", lib::bits<7, 7>>,
110 lib::rw<
"psw_key", lib::bits<8, 11>>,
111 lib::rw<
"machine_check_mask", lib::bits<13, 13>>,
112 lib::rw<
"wait_state", lib::bits<14, 14>>,
113 lib::rw<
"problem_state", lib::bits<15, 15>>,
114 lib::rw<
"address_space_control", lib::bits<16, 17>>,
115 lib::rw<
"condition_code", lib::bits<18, 19>>,
116 lib::overlay_rw<
"pgm_mask", lib::bits<20, 23>>,
117 lib::rw<R"(pgm_mask\fixed_point_overflow)", lib::bits<20, 20>>,
118 lib::rw<R"(pgm_mask\decimal_overflow)", lib::bits<21, 21>>,
119 lib::rw<R"(pgm_mask\hfp_exponent_underflow)", lib::bits<22, 22>>,
120 lib::rw<R"(pgm_mask\hfp_significance)", lib::bits<23, 23>>,
121 lib::overlay_rw<
"addressing_mode", lib::bits<31, 32>, psw_basic_addressing_modes>,
122 lib::rw<
"extended_addressing_mode", lib::bits<31, 31>>,
123 lib::rw<
"basic_addressing_mode", lib::bits<32, 32>>
126 using psw_mask_view = lib::record_ref<u64, lib::msb0_t,
127 lib::rw<
"per_mask", lib::bits<1, 1>>,
128 lib::rw<
"dat_mode", lib::bits<5, 5>>,
129 lib::rw<
"io_mask", lib::bits<6, 6>>,
130 lib::rw<
"external_mask", lib::bits<7, 7>>,
131 lib::rw<
"psw_key", lib::bits<8, 11>>,
132 lib::rw<
"machine_check_mask", lib::bits<13, 13>>,
133 lib::rw<
"wait_state", lib::bits<14, 14>>,
134 lib::rw<
"problem_state", lib::bits<15, 15>>,
135 lib::rw<
"address_space_control", lib::bits<16, 17>>,
136 lib::rw<
"condition_code", lib::bits<18, 19>>,
137 lib::overlay_rw<
"pgm_mask", lib::bits<20, 23>>,
138 lib::rw<R"(pgm_mask\fixed_point_overflow)", lib::bits<20, 20>>,
139 lib::rw<R"(pgm_mask\decimal_overflow)", lib::bits<21, 21>>,
140 lib::rw<R"(pgm_mask\hfp_exponent_underflow)", lib::bits<22, 22>>,
141 lib::rw<R"(pgm_mask\hfp_significance)", lib::bits<23, 23>>,
142 lib::overlay_rw<
"addressing_mode", lib::bits<31, 32>, psw_basic_addressing_modes>,
143 lib::rw<
"extended_addressing_mode", lib::bits<31, 31>>,
144 lib::rw<
"basic_addressing_mode", lib::bits<32, 32>>
147 using zpsw = lib::structure<16, 8, lib::endian::big,
148 lib::rw<
"mask", lib::auto_layout, psw_mask>,
149 lib::rw<
"address", lib::auto_layout, u64>
152 using zpsw_view = lib::structure_ref<16, 8, lib::endian::big,
153 lib::rw<
"mask", lib::auto_layout, psw_mask>,
154 lib::rw<
"address", lib::auto_layout, u64>
157 using short_psw = lib::record<u64, lib::msb0_t,
158 lib::rw<
"per_mask", lib::bits<1, 1>>,
159 lib::rw<
"dat_mode", lib::bits<5, 5>>,
160 lib::rw<
"io_mask", lib::bits<6, 6>>,
161 lib::rw<
"external_mask", lib::bits<7, 7>>,
162 lib::rw<
"psw_key", lib::bits<8, 11>>,
163 lib::rw<
"machine_check_mask", lib::bits<13, 13>>,
164 lib::rw<
"wait_state", lib::bits<14, 14>>,
165 lib::rw<
"problem_state", lib::bits<15, 15>>,
166 lib::rw<
"address_space_control", lib::bits<16, 17>>,
167 lib::rw<
"condition_code", lib::bits<18, 19>>,
168 lib::overlay_rw<
"pgm_mask", lib::bits<20, 23>>,
169 lib::rw<R"(pgm_mask\fixed_point_overflow)", lib::bits<20, 20>>,
170 lib::rw<R"(pgm_mask\decimal_overflow)", lib::bits<21, 21>>,
171 lib::rw<R"(pgm_mask\hfp_exponent_underflow)", lib::bits<22, 22>>,
172 lib::rw<R"(pgm_mask\hfp_significance)", lib::bits<23, 23>>,
173 lib::overlay_rw<
"addressing_mode", lib::bits<31, 32>, psw_basic_addressing_modes>,
174 lib::rw<
"extended_addressing_mode", lib::bits<31, 31>>,
175 lib::rw<
"basic_addressing_mode", lib::bits<32, 32>>,
176 lib::rw<
"instruction_address", lib::bits<33, 63>>
179 using short_psw_view = lib::record_ref<u64, lib::msb0_t,
180 lib::rw<
"per_mask", lib::bits<1, 1>>,
181 lib::rw<
"dat_mode", lib::bits<5, 5>>,
182 lib::rw<
"io_mask", lib::bits<6, 6>>,
183 lib::rw<
"external_mask", lib::bits<7, 7>>,
184 lib::rw<
"psw_key", lib::bits<8, 11>>,
185 lib::rw<
"machine_check_mask", lib::bits<13, 13>>,
186 lib::rw<
"wait_state", lib::bits<14, 14>>,
187 lib::rw<
"problem_state", lib::bits<15, 15>>,
188 lib::rw<
"address_space_control", lib::bits<16, 17>>,
189 lib::rw<
"condition_code", lib::bits<18, 19>>,
190 lib::overlay_rw<
"pgm_mask", lib::bits<20, 23>>,
191 lib::rw<R"(pgm_mask\fixed_point_overflow)", lib::bits<20, 20>>,
192 lib::rw<R"(pgm_mask\decimal_overflow)", lib::bits<21, 21>>,
193 lib::rw<R"(pgm_mask\hfp_exponent_underflow)", lib::bits<22, 22>>,
194 lib::rw<R"(pgm_mask\hfp_significance)", lib::bits<23, 23>>,
195 lib::overlay_rw<
"addressing_mode", lib::bits<31, 32>, psw_basic_addressing_modes>,
196 lib::rw<
"extended_addressing_mode", lib::bits<31, 31>>,
197 lib::rw<
"basic_addressing_mode", lib::bits<32, 32>>,
198 lib::rw<
"instruction_address", lib::bits<33, 63>>
201 using esa390_psw = lib::record<u64, lib::msb0_t,
202 lib::rw<
"per_mask", lib::bits<1, 1>>,
203 lib::rw<
"dat_mode", lib::bits<5, 5>>,
204 lib::rw<
"io_mask", lib::bits<6, 6>>,
205 lib::rw<
"external_mask", lib::bits<7, 7>>,
206 lib::rw<
"psw_key", lib::bits<8, 11>>,
207 lib::rw<
"machine_check_mask", lib::bits<13, 13>>,
208 lib::rw<
"wait_state", lib::bits<14, 14>>,
209 lib::rw<
"problem_state", lib::bits<15, 15>>,
210 lib::rw<
"address_space_control", lib::bits<16, 17>>,
211 lib::rw<
"condition_code", lib::bits<18, 19>>,
212 lib::overlay_rw<
"pgm_mask", lib::bits<20, 23>>,
213 lib::rw<R"(pgm_mask\fixed_point_overflow)", lib::bits<20, 20>>,
214 lib::rw<R"(pgm_mask\decimal_overflow)", lib::bits<21, 21>>,
215 lib::rw<R"(pgm_mask\hfp_exponent_underflow)", lib::bits<22, 22>>,
216 lib::rw<R"(pgm_mask\hfp_significance)", lib::bits<23, 23>>,
217 lib::rw<
"addressing_mode", lib::bits<32, 32>>,
218 lib::rw<
"instruction_address", lib::bits<33, 63>>
221 using esa390_psw_view = lib::record_ref<u64, lib::msb0_t,
222 lib::rw<
"per_mask", lib::bits<1, 1>>,
223 lib::rw<
"dat_mode", lib::bits<5, 5>>,
224 lib::rw<
"io_mask", lib::bits<6, 6>>,
225 lib::rw<
"external_mask", lib::bits<7, 7>>,
226 lib::rw<
"psw_key", lib::bits<8, 11>>,
227 lib::rw<
"machine_check_mask", lib::bits<13, 13>>,
228 lib::rw<
"wait_state", lib::bits<14, 14>>,
229 lib::rw<
"problem_state", lib::bits<15, 15>>,
230 lib::rw<
"address_space_control", lib::bits<16, 17>>,
231 lib::rw<
"condition_code", lib::bits<18, 19>>,
232 lib::overlay_rw<
"pgm_mask", lib::bits<20, 23>>,
233 lib::rw<R"(pgm_mask\fixed_point_overflow)", lib::bits<20, 20>>,
234 lib::rw<R"(pgm_mask\decimal_overflow)", lib::bits<21, 21>>,
235 lib::rw<R"(pgm_mask\hfp_exponent_underflow)", lib::bits<22, 22>>,
236 lib::rw<R"(pgm_mask\hfp_significance)", lib::bits<23, 23>>,
237 lib::rw<
"addressing_mode", lib::bits<32, 32>>,
238 lib::rw<
"instruction_address", lib::bits<33, 63>>
241 struct [[gnu::packed]]
alignas(u64) epsw_words {
246 static_assert(
sizeof(zpsw) == 16,
"zx_psw must be exactly 16 bytes");
247 static_assert(
alignof(zpsw) == 8,
"zx_psw must be 8-byte aligned");
250 [[nodiscard]]
auto extract_psw()
noexcept -> zpsw;
252 [[noreturn]]
auto load_psw(
const zpsw& psw)
noexcept ->
void;
254 [[noreturn]]
auto disabled_wait()
noexcept ->
void;
257 auto enabled_wait()
noexcept ->
void;
259 auto write_psw_to_lowcore(u64 lc_offset, zpsw psw)
noexcept ->
void;
261 [[nodiscard]]
auto make_handler_psw(u64 entry_virt)
noexcept -> zpsw;
262 [[nodiscard]]
auto make_ap_restart_psw(u64 entry_phys)
noexcept -> zpsw;