5export module arch.s390x.init.zxfl.protocol;
6import arch.s390x.cpu.features;
7import zxfoundation.base.types;
8import zxfoundation.base.config;
9import crypto.sha256.core;
14namespace arch::s390x::init::zxfl {
16 constexpr auto ZXFL_MAGIC = 0x5A58464CU;
17 constexpr auto ZXFL_VERSION_4 = 0x00000004U;
18 constexpr auto ZXFL_LOADER_MAJOR = 1U;
19 constexpr auto ZXFL_LOADER_MINOR = 0U;
20 constexpr auto ZXFL_SEED = 0xA5F0C3E1B2D49687UL;
21 constexpr auto ZXFL_OFFSET_KERNEL_STACK_TOP = 400U;
23 constexpr auto ZXFL_FLAG_SMP = 1U << 0;
24 constexpr auto ZXFL_FLAG_MEM_MAP = 1U << 1;
25 constexpr auto ZXFL_FLAG_CMDLINE = 1U << 2;
26 constexpr auto ZXFL_FLAG_LOWCORE = 1U << 3;
27 constexpr auto ZXFL_FLAG_STFLE = 1U << 4;
28 constexpr auto ZXFL_FLAG_SYSINFO = 1U << 5;
29 constexpr auto ZXFL_FLAG_TOD = 1U << 6;
30 constexpr auto ZXFL_FLAG_SCLP = 1U << 8;
31 constexpr auto ZXFL_FLAG_ECAG = 1U << 12;
33 constexpr auto ZXFL_MEM_MAP_MAX = 16U;
34 constexpr auto ZXFL_CPU_MAP_MAX = zxfoundation::base::config::CONFIG_ZX_MAX_CPUS;
36 constexpr auto ZXFL_MEM_USABLE = 0x01U;
37 constexpr auto ZXFL_MEM_RESERVED = 0x02U;
38 constexpr auto ZXFL_MEM_LOADER = 0x03U;
39 constexpr auto ZXFL_MEM_KERNEL = 0x04U;
41 constexpr auto ZXFL_MEMPROBE_UNKNOWN = 0;
42 constexpr auto ZXFL_MEMPROBE_SCLP = 1;
43 constexpr auto ZXFL_MEMPROBE_DIAG = 2;
44 constexpr auto ZXFL_MEMPROBE_TPROT = 3;
46 constexpr auto ZXFL_CPU_ONLINE = 0x01U;
47 constexpr auto ZXFL_CPU_STOPPED = 0x02U;
48 constexpr auto ZXFL_CPU_UNKNOWN = 0x00U;
51 constexpr auto ZXFL_CPU_TYPE_CP = 1U;
52 constexpr auto ZXFL_CPU_TYPE_IFL = 2U;
53 constexpr auto ZXFL_CPU_TYPE_ICF = 3U;
54 constexpr auto ZXFL_CPU_TYPE_ZIIP = 4U;
55 constexpr auto ZXFL_CPU_TYPE_ZAAP = 5U;
56 constexpr auto ZXFL_CPU_TYPE_UNKNOWN = 0xFFU;
58 constexpr auto ZXFL_CPU_EVIDENCE_NONE = 0x00U;
59 constexpr auto ZXFL_CPU_EVIDENCE_SIGP = 0x01U;
60 constexpr auto ZXFL_CPU_EVIDENCE_STSI = 0x02U;
61 constexpr auto ZXFL_CPU_EVIDENCE_FALLBACK = 0x04U;
63 constexpr auto ZXFL_LOWCORE_PHYS = 0x0ULL;
85 u8 topology_evidence{};
90 constexpr auto IPL_TYPE_CCW = 0U;
91 constexpr auto IPL_TYPE_FCP = 1U;
92 constexpr auto IPL_TYPE_ECKD = 2U;
93 constexpr auto IPL_TYPE_NVME = 3U;
94 constexpr auto IPL_TYPE_UNKNOWN = 0xFFU;
97 constexpr auto SCLP_FEAT_SIEF2 = 0U;
98 constexpr auto SCLP_FEAT_SIIF = 1U;
99 constexpr auto SCLP_FEAT_SIGPIF = 2U;
100 constexpr auto SCLP_FEAT_GPERF = 3U;
101 constexpr auto SCLP_FEAT_IB = 4U;
102 constexpr auto SCLP_FEAT_CEI = 5U;
103 constexpr auto SCLP_FEAT_SKEY = 6U;
108 char manufacturer[16]{};
113 char model_capacity[16]{};
114 char model_perm_cap[16]{};
115 char model_temp_cap[16]{};
116 char model_var_cap[16]{};
117 u32 model_cap_rating{};
118 u32 model_perm_cap_rating{};
119 u32 model_temp_cap_rating{};
120 u32 model_var_cap_rating{};
121 u32 ncr{}, npr{}, ntr{}, nvr{};
127 u8 lpar_characteristics{};
128 u16 lpar_cpus_dedicated{};
129 u16 lpar_cpus_shared{};
131 u8 lpar_mt_installed{};
139 u16 cpus_configured{};
164 u32 cache_line_size{};
165 u32 cache_total_size{};
166 u32 cache_associativity{};
193 u32 loader_timestamp{};
194 u64 loader_build_id{};
202 u64 kernel_phys_start{};
203 u64 kernel_phys_end{};
206 u64 mem_total_bytes{};
209 u8 mem_detect_source{};
211 u64 hhdm_phys_coverage_end{};
213 u64 stfle_fac[cpu::features::STFLE_MAX_DWORDS]{};
224 u64 kernel_stack_top{};
232 u64 pgtbl_pool_end{};
234 cpu_info cpu_map[ZXFL_CPU_MAP_MAX]{};
245 sysmodule modules[16];
253 u8 loader_digest[32]{};
256 u64 sclp_info_addr{};
259 u64 ecag_info_addr{};
263 [[nodiscard]]
auto mem_type_str(u32 type)
noexcept -> std::string_view {
265 case ZXFL_MEM_USABLE:
return "usable";
266 case ZXFL_MEM_RESERVED:
return "reserved";
267 case ZXFL_MEM_LOADER:
return "loader";
268 case ZXFL_MEM_KERNEL:
return "kernel";
269 default:
return "unknown";
274 [[nodiscard]]
auto cpu_state_str(u8 state)
noexcept -> std::string_view {
276 case ZXFL_CPU_ONLINE:
return "online";
277 case ZXFL_CPU_STOPPED:
return "stopped";
278 default:
return "unknown";
283 [[nodiscard]]
auto cpu_type_str(u8 type)
noexcept -> std::string_view {
285 case ZXFL_CPU_TYPE_CP:
return "CP";
286 case ZXFL_CPU_TYPE_IFL:
return "IFL";
287 case ZXFL_CPU_TYPE_ICF:
return "ICF";
288 case ZXFL_CPU_TYPE_ZIIP:
return "zIIP";
289 case ZXFL_CPU_TYPE_ZAAP:
return "zAAP";
290 case ZXFL_CPU_TYPE_UNKNOWN:
return "unknown";
297namespace arch::s390x::init::zxvl {
299 constexpr auto ZXVL_SEED = 0xA5F0C3E1B2D49687UL;
300 constexpr auto ZXVL_SEED_HI = 0xA5F0C3E1U;
301 constexpr auto ZXVL_SEED_LO = 0xB2D49687U;
303 constexpr auto ZXVL_HS_CHALLENGE = 0xFEEDFACECAFEBABEUL;
304 constexpr auto ZXVL_HS_RESPONSE = 0xDEADBEEF0BADF00DUL;
305 constexpr auto ZXVL_HS_RESPONSE_HI = 0xDEADBEEFU;
306 constexpr auto ZXVL_HS_RESPONSE_LO = 0x0BADF00DU;
307 constexpr auto ZXVL_PFLAGS_HS = 0x00400005U;
308 constexpr auto ZXVL_PFLAGS_ENTRY = 0x00800005U;
310 constexpr auto ZXVL_FRAME_MAGIC_A = 0xC0FFEE00FACADE42UL;
311 constexpr auto ZXVL_FRAME_MAGIC_B = 0x1337BABE0DDBA115UL;
312 constexpr auto ZXVL_FRAME_SIZE = 64U;
314 constexpr auto ZXVL_LOCK_MASK = 0x3C1E0F8704B2D596UL;
315 constexpr auto ZXVL_LOCK_EXPECTED = 0xF0A5C3B2E1D49687UL;
316 constexpr auto ZXVL_LOCK_EMBED_HI = 0xCCBBCC35U;
317 constexpr auto ZXVL_LOCK_EMBED_LO = 0xE5664311U;
318 constexpr auto ZXVL_LOCK_SENTINEL = 0x5A58464CU;
319 constexpr auto ZXVL_PFLAGS_LOCK = 0x00100006U;
321 constexpr auto ZXVL_CKSUM_MAGIC = 0x5A58564CU;
322 constexpr auto ZXVL_CKSUM_VERSION = 0x00000001U;
323 constexpr auto ZXVL_CKSUM_ALGO_SHA256 = 0x00000001U;
324 constexpr auto ZXVL_CKSUM_MAX_ENTRIES = 16U;
325 constexpr auto ZXVL_PFLAGS_CKSUM = 0x00200004U;
328 inline constexpr u8 ZXFL_EXPECTED_DIGEST[crypto::sha256::SHA256_DIGEST_SIZE]{};
329 static_assert(
sizeof(ZXFL_EXPECTED_DIGEST) == 32U,
330 "ZXFL_EXPECTED_DIGEST must be exactly 32 bytes");
332 [[nodiscard]]
constexpr auto compute_token(u64 stfle0, u64 schid)
noexcept -> u64 {
333 return ZXVL_SEED ^ stfle0 ^ schid;
336 struct [[gnu::packed]] checksum_entry {
339 u8 digest[crypto::sha256::SHA256_DIGEST_SIZE]{};
342 struct [[gnu::packed]] checksum_table {
343 u32 magic{}, version{}, algo{}, count{};
344 checksum_entry entries[ZXVL_CKSUM_MAX_ENTRIES]{};
347 static_assert(
sizeof(checksum_entry) == 48U,
348 "checksum_entry size mismatch vs zxvl_cksum_entry_t");
349 static_assert(
sizeof(checksum_table) == 784U,
350 "checksum_table size mismatch vs zxvl_checksum_table_t");