ZXFoundation™ 26h2
Loading...
Searching...
No Matches
core.cxxm
1/// SPDX-License-Identifier: Apache-2.0
2/// @file arch/s390x/trap/mcck.cxxm
3/// @brief Centralized Machine-Check (MCCK) dispatcher.
4
5export module arch.s390x.trap.mcck.core;
6import arch.s390x.cpu.irq;
7import arch.s390x.cpu.features;
8import zxfoundation.base.types;
9import lib.structure;
10import lib.bitfield;
11import lib.stl;
12
13#define __zxmacro_want_assert
14#define __zxmacro_want_bits
15#include macro_extensions
16
17export {
18
19namespace arch::s390x::trap::mcck {
20
21 /// @brief Machine-Check Interruption Code bits
22 /// @{
23 constexpr u64 MCIC_SD = 1ULL << 63; // bit 0 — system damage
24 constexpr u64 MCIC_PD = 1ULL << 62; // bit 1 — instruction-processing damage
25 constexpr u64 MCIC_SR = 1ULL << 61; // bit 2 — system recovery
26 constexpr u64 MCIC_CD = 1ULL << 59; // bit 4 — timing-facility damage
27 constexpr u64 MCIC_ED = 1ULL << 58; // bit 5 — external damage
28 constexpr u64 MCIC_BACKLOG = 1ULL << 57; // bit 6 — stacked machine check (MCIC not cleared)
29 constexpr u64 MCIC_DG = 1ULL << 56; // bit 7 — degradation
30 constexpr u64 MCIC_W = 1ULL << 55; // bit 8 — warning
31 constexpr u64 MCIC_CP = 1ULL << 54; // bit 9 — channel-report pending
32 constexpr u64 MCIC_SP = 1ULL << 53; // bit 10 — service-processor damage
33 constexpr u64 MCIC_CK = 1ULL << 52; // bit 11 — channel-subsystem damage
34 constexpr u64 MCIC_B = 1ULL << 49; // bit 14 — backed-up (nullifying IPD survived)
35 constexpr u64 MCIC_SE = 1ULL << 47; // bit 16 — storage error uncorrected
36 constexpr u64 MCIC_SC = 1ULL << 46; // bit 17 — storage error corrected
37 constexpr u64 MCIC_KE = 1ULL << 45; // bit 18 — storage-key error uncorrected
38 constexpr u64 MCIC_DS = 1ULL << 44; // bit 19 — storage degradation
39 constexpr u64 MCIC_WP = 1ULL << 43; // bit 20 — PSW-MWP validity
40 constexpr u64 MCIC_MS = 1ULL << 42; // bit 21 — PSW mask and key validity
41 constexpr u64 MCIC_PM = 1ULL << 41; // bit 22 — PSW program-mask and CC validity
42 constexpr u64 MCIC_IA = 1ULL << 40; // bit 23 — PSW-instruction-address validity
43 constexpr u64 MCIC_FA = 1ULL << 39; // bit 24 — failing-storage-address validity
44 constexpr u64 MCIC_VR = 1ULL << 38; // bit 25 — vector-register validity
45 constexpr u64 MCIC_EC = 1ULL << 37; // bit 26 — external-damage-code validity
46 constexpr u64 MCIC_FP = 1ULL << 36; // bit 27 — floating-point-register validity
47 constexpr u64 MCIC_GR = 1ULL << 35; // bit 28 — general-register validity
48 constexpr u64 MCIC_CR = 1ULL << 34; // bit 29 — control-register validity
49 constexpr u64 MCIC_ST = 1ULL << 32; // bit 31 — storage logical validity
50 constexpr u64 MCIC_IE = 1ULL << 31; // bit 32 — indirect storage error
51 constexpr u64 MCIC_AR = 1ULL << 30; // bit 33 — access-register validity
52 constexpr u64 MCIC_DA = 1ULL << 29; // bit 34 — delayed-access exception
53 constexpr u64 MCIC_GS = 1ULL << 27; // bit 36 — guarded-storage-registers validity
54 constexpr u64 MCIC_PR = 1ULL << 21; // bit 42 — TOD-programmable-register validity
55 constexpr u64 MCIC_FC = 1ULL << 20; // bit 43 — FP-control-register validity
56 constexpr u64 MCIC_AP = 1ULL << 19; // bit 44 — ancillary report
57 constexpr u64 MCIC_CT = 1ULL << 17; // bit 46 — CPU-timer validity
58 constexpr u64 MCIC_CC = 1ULL << 16; // bit 47 — clock-comparator validity
59 /// @}
60
61 /// @brief IPD damage-window constants
62 /// @{
63 constexpr u32 MAX_IPD_COUNT = 29;
64 constexpr u64 MAX_IPD_WINDOW_TOD = 5ULL * 60ULL * 4'096'000'000ULL;
65 /// @}
66
67 struct [[gnu::packed]] mcesa10 {
68 u64 vector_register[32][2]{};
69 bytersvd(tobytes(dw, 64)){};
70 };
71 assert_size(mcesa10, 1024);
72
73 struct [[gnu::packed]] mcesa11 {
74 u64 vector_register[32][2]{};
75 bytersvd(tobytes(dw, 65)){};
76 u64 gsd_register{};
77 u64 gssm_register{};
78 u64 gsepla_register{};
79 bytersvd(tobytes(dw, 124)){};
80 };
81 assert_size(mcesa11, 2048);
82
83 struct [[gnu::packed]] mcesa12 {
84 u64 vector_register[32][2]{};
85 bytersvd(tobytes(dw, 65)){};
86 u64 gsd_register{};
87 u64 gssm_register{};
88 u64 gsepla_register{};
89 bytersvd(tobytes(dw, 380)){};
90 };
91 assert_size(mcesa12, 4096);
92
93 using mcesa = std::variant<mcesa10 const*, mcesa11 const*, mcesa12 const*>;
94
95 template <class Derived>
96 struct mcesad_ops {
97
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>());
103 }
104
105 [[nodiscard]] auto save_area_characteristic(this const Derived& self) noexcept -> std::pair<u64, usize> {
106 const auto da = self.template get<"designation_area">();
107 switch (self.lc()) {
108 case 0:
109 case 10:
110 return { da.template extract_aligned<0, 53, 1024>(), 1024 };
111 case 11:
112 return { da.template extract_aligned<0, 52, 2048>(), 2048 };
113 case 12:
114 return { da.template extract_aligned<0, 51, 4096>(), 4096 };
115 default:
116 return { 0, 0 };
117 }
118 }
119
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;
123
124 switch (self.lc()) {
125 case 0:
126 case 10:
127 return reinterpret_cast<mcesa10 const*>(address);
128 case 11:
129 return reinterpret_cast<mcesa11 const*>(address);
130 case 12:
131 return reinterpret_cast<mcesa12 const*>(address);
132 default:
133 return std::nullopt;
134 }
135 }
136
137 };
138
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>
142 >;
143 assert_size(mcesad, 8);
144
145 /// @brief Centralized machine-check dispatcher
146 /// @param[in] frame Saved interrupt frame from entry.S SAVE_FRAME on the
147 /// MCCK stack
148 auto handle(cpu::irq::irq_frame* frame) noexcept -> void;
149
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>>
156 >;
157
158} // namespace arch::s390x::trap::mcck
159
160} // end export