5export module arch.s390x.trap.mcck.core;
6import arch.s390x.cpu.irq;
7import arch.s390x.cpu.features;
8import zxfoundation.base.types;
13#define __zxmacro_want_assert
14#define __zxmacro_want_bits
15#include macro_extensions
19namespace arch::s390x::trap::mcck {
23 constexpr u64 MCIC_SD = 1ULL << 63;
24 constexpr u64 MCIC_PD = 1ULL << 62;
25 constexpr u64 MCIC_SR = 1ULL << 61;
26 constexpr u64 MCIC_CD = 1ULL << 59;
27 constexpr u64 MCIC_ED = 1ULL << 58;
28 constexpr u64 MCIC_BACKLOG = 1ULL << 57;
29 constexpr u64 MCIC_DG = 1ULL << 56;
30 constexpr u64 MCIC_W = 1ULL << 55;
31 constexpr u64 MCIC_CP = 1ULL << 54;
32 constexpr u64 MCIC_SP = 1ULL << 53;
33 constexpr u64 MCIC_CK = 1ULL << 52;
34 constexpr u64 MCIC_B = 1ULL << 49;
35 constexpr u64 MCIC_SE = 1ULL << 47;
36 constexpr u64 MCIC_SC = 1ULL << 46;
37 constexpr u64 MCIC_KE = 1ULL << 45;
38 constexpr u64 MCIC_DS = 1ULL << 44;
39 constexpr u64 MCIC_WP = 1ULL << 43;
40 constexpr u64 MCIC_MS = 1ULL << 42;
41 constexpr u64 MCIC_PM = 1ULL << 41;
42 constexpr u64 MCIC_IA = 1ULL << 40;
43 constexpr u64 MCIC_FA = 1ULL << 39;
44 constexpr u64 MCIC_VR = 1ULL << 38;
45 constexpr u64 MCIC_EC = 1ULL << 37;
46 constexpr u64 MCIC_FP = 1ULL << 36;
47 constexpr u64 MCIC_GR = 1ULL << 35;
48 constexpr u64 MCIC_CR = 1ULL << 34;
49 constexpr u64 MCIC_ST = 1ULL << 32;
50 constexpr u64 MCIC_IE = 1ULL << 31;
51 constexpr u64 MCIC_AR = 1ULL << 30;
52 constexpr u64 MCIC_DA = 1ULL << 29;
53 constexpr u64 MCIC_GS = 1ULL << 27;
54 constexpr u64 MCIC_PR = 1ULL << 21;
55 constexpr u64 MCIC_FC = 1ULL << 20;
56 constexpr u64 MCIC_AP = 1ULL << 19;
57 constexpr u64 MCIC_CT = 1ULL << 17;
58 constexpr u64 MCIC_CC = 1ULL << 16;
63 constexpr u32 MAX_IPD_COUNT = 29;
64 constexpr u64 MAX_IPD_WINDOW_TOD = 5ULL * 60ULL * 4'096'000'000ULL;
67 struct [[gnu::packed]] mcesa10 {
68 u64 vector_register[32][2]{};
69 bytersvd(tobytes(dw, 64)){};
71 assert_size(mcesa10, 1024);
73 struct [[gnu::packed]] mcesa11 {
74 u64 vector_register[32][2]{};
75 bytersvd(tobytes(dw, 65)){};
78 u64 gsepla_register{};
79 bytersvd(tobytes(dw, 124)){};
81 assert_size(mcesa11, 2048);
83 struct [[gnu::packed]] mcesa12 {
84 u64 vector_register[32][2]{};
85 bytersvd(tobytes(dw, 65)){};
88 u64 gsepla_register{};
89 bytersvd(tobytes(dw, 380)){};
91 assert_size(mcesa12, 4096);
93 using mcesa = std::variant<mcesa10
const*, mcesa11
const*, mcesa12
const*>;
95 template <
class Derived>
98 [[nodiscard]]
auto lc(
this const Derived& self)
noexcept -> u8 {
99 if (!cpu::features::has(cpu::features::facility::guarded_storage))
return 0;
100 return static_cast<u8>(self
101 .
template get<
"designation_area">()
102 .
template extract<60, 63>());
105 [[nodiscard]]
auto save_area_characteristic(
this const Derived& self)
noexcept -> std::pair<u64, usize> {
106 const auto da = self.
template get<
"designation_area">();
110 return { da.
template extract_aligned<0, 53, 1024>(), 1024 };
112 return { da.
template extract_aligned<0, 52, 2048>(), 2048 };
114 return { da.
template extract_aligned<0, 51, 4096>(), 4096 };
120 [[nodiscard]]
auto save_area(
this const Derived& self)
noexcept -> std::optional<mcesa> {
121 auto [address, size] = self.save_area_characteristic();
122 if (address == 0)
return std::nullopt;
127 return reinterpret_cast<mcesa10
const*>(address);
129 return reinterpret_cast<mcesa11
const*>(address);
131 return reinterpret_cast<mcesa12
const*>(address);
139 using mcesad = lib::structure<8, 8, lib::endian::big,
140 lib::extensions<mcesad_ops>,
141 lib::rw<
"designation_area", lib::auto_layout, lib::bf64>
143 assert_size(mcesad, 8);
148 auto handle(cpu::irq::irq_frame* frame)
noexcept ->
void;
150 using external_damage_code = lib::record<u32, lib::msb0_t,
151 lib::rw<
"etr_sync_check", lib::bits<19, 19>>,
152 lib::rw<
"stp_sync_check", lib::bits<24, 24>>,
153 lib::rw<
"island_condition", lib::bits<25, 25>>,
154 lib::rw<
"ctn_config_change", lib::bits<26, 26>>,
155 lib::rw<
"stp_clock_source_err", lib::bits<27, 27>>