5export module arch.s390x.cpu.lowcore;
6import arch.s390x.cpu.psw;
7import arch.s390x.io.types;
8import arch.s390x.trap.ext.core;
9import arch.s390x.trap.pgm.core;
10import arch.s390x.trap.mcck.core;
11import arch.s390x.cpu.teid;
12import arch.s390x.init.zxfl.protocol;
13import arch.s390x.cpu.clock;
14import arch.s390x.cpu.tx;
15import zxfoundation.sys.syschk.types;
16import zxfoundation.base.types;
22namespace arch::s390x::cpu::lowcore {
24 constexpr u64 LC_EXT_OLD_PSW = 0x0130UL;
25 constexpr u64 LC_SVC_OLD_PSW = 0x0140UL;
26 constexpr u64 LC_PGM_OLD_PSW = 0x0150UL;
27 constexpr u64 LC_MCCK_OLD_PSW = 0x0160UL;
28 constexpr u64 LC_IO_OLD_PSW = 0x0170UL;
30 constexpr u64 LC_PSW_TEMP = 0x0248UL;
31 constexpr u64 LC_RETURN_PSW = 0x0290UL;
32 constexpr u64 LC_KERNEL_STACK = 0x0348UL;
33 constexpr u64 LC_ASYNC_STACK = 0x0350UL;
34 constexpr u64 LC_NODAT_STACK = 0x0358UL;
35 constexpr u64 LC_RESTART_STACK = 0x0360UL;
36 constexpr u64 LC_MCCK_STACK = 0x0368UL;
37 constexpr u64 LC_AP_CR0 = 0x0330UL;
38 constexpr u64 LC_AP_CR13 = 0x0338UL;
39 constexpr u64 LC_CURRENT_DOMAIN = 0x0340UL;
40 constexpr u64 LC_KERNEL_ASCE = 0x0388UL;
42 constexpr u64 LC_CPU_ID_OFFSET = 0x03a0UL;
43 constexpr u64 LC_PERCPU_PTR = 0x0400UL;
46 constexpr u64 LC_SIZE = 8192UL;
47 constexpr u64 LC_ALIGN = 8192UL;
49 enum class architectural_mode : u8 {
54 using restart_fn =
auto(*)(
void*)
noexcept ->
void;
57 using zlowcore = lib::structure<LC_SIZE, LC_ALIGN, lib::endian::big,
58 lib::overlay_rw<
"esa390_psw", lib::bytes<0, 7>, psw::esa390_psw>,
59 lib::overlay_rw<
"short_psw", lib::bytes<0, 7>, psw::short_psw>,
61 lib::rw<
"ipl_ccw1", lib::bytes<8, 15>, io::ccw0>,
63 lib::overlay_rw<
"ipl_ccw2", lib::bytes<16, 23>, io::ccw0>,
64 lib::rw<
"ipl_machine_loader_space_sz", lib::bytes<16, 19>, u32>,
65 lib::rw<
"ipl_sysparm_block_addr", lib::bytes<20, 23>, u32>,
67 lib::rw<
"external_int_parameter", lib::bytes<128, 131>, trap::ext::ext_parameter>,
68 lib::rw<
"cpu_addr", lib::bytes<132, 133>, u16>,
69 lib::rw<
"external_interruption_code", lib::bytes<134, 135>, u16>,
71 lib::rw<
"svc_interruption_id", lib::bytes<136, 139>, lib::record<u32, lib::msb0_t,
72 lib::rw<
"instruction_length_code", lib::bits<13, 14>>,
73 lib::rw<
"instruction_code", lib::bits<16, 31>>
76 lib::rw<
"pgm_interruption_id", lib::bytes<140, 143>, lib::record<u32, lib::msb0_t,
77 lib::rw<
"instruction_length_code", lib::bits<13, 14>>,
78 lib::rw<
"instruction_code", lib::bits<16, 31>>
81 lib::rw<
"exception_code", lib::bytes<144, 147>, lib::record<u32, lib::msb0_t,
82 lib::overlay_rw<
"vector_exception_code", lib::bits<24, 31>, trap::pgm::vector_exception_code>,
83 lib::overlay_rw<
"data_exception_code", lib::bits<24, 31>, trap::pgm::data_exception_code>
86 lib::rw<
"monitor_class_number", lib::bytes<148, 149>, lib::record<u16, lib::msb0_t,
87 lib::rw<
"number", lib::bits<8, 15>>
90 lib::rw<
"per_code", lib::bytes<150, 151>, trap::pgm::per_code>,
91 lib::rw<
"per_address", lib::bytes<152, 159>, u64>,
92 lib::rw<
"exception_address_id", lib::bytes<160, 160>, trap::pgm::eaid>,
93 lib::rw<
"per_access_id", lib::bytes<161, 161>, trap::pgm::per_access_id>,
94 lib::rw<
"operation_access_id", lib::bytes<162, 162>, lib::record<u8, lib::msb0_t,
95 lib::rw<
"move_page_r1", lib::bits<0, 3>>,
96 lib::rw<
"move_page_r2", lib::bits<4, 7>>
99 lib::overlay_rw<
"status_arch_mode_id", lib::bytes<163, 163>, lib::record<u8, lib::msb0_t,
100 lib::rw<
"architectural_mode", lib::bits<7, 7>, architectural_mode>
102 lib::overlay_rw<
"mcck_arch_mode_id", lib::bytes<163, 163>, lib::record<u8, lib::msb0_t,
103 lib::rw<
"architectural_mode", lib::bits<7, 7>, architectural_mode>
106 lib::rw<
"translation_except_id", lib::bytes<168, 175>, teid::teid>,
107 lib::rw<
"monitor_code", lib::bytes<176, 183>, u64>,
109 lib::rw<
"io_interruption_code", lib::bytes<184, 195>, io::io_interruption_code>,
111 lib::rw<
"facility_list", lib::bytes<200, 203>, lib::bf32>,
113 lib::rw<
"mcck_interruption_code", lib::bytes<232, 239>, u64>,
114 lib::rw<
"external_damage_code", lib::bytes<244, 247>, trap::mcck::external_damage_code>,
115 lib::rw<
"failing_storage_address", lib::bytes<248, 255>, u64>,
116 lib::rw<
"monitor_counter_array_origin", lib::bytes<256, 263>, u64>,
117 lib::rw<
"monitor_ctr_array_size", lib::bytes<264, 267>, u32>,
118 lib::rw<
"monitor_exception_count", lib::bytes<268, 271>, u32>,
119 lib::rw<
"breaking_event_address", lib::bytes<272, 279>, u64>,
121 lib::rw<
"restart_old_psw", lib::bytes<288, 303>, psw::zpsw>,
122 lib::rw<
"external_old_psw", lib::bytes<304, 319>, psw::zpsw>,
123 lib::rw<
"supervisor_call_old_psw", lib::bytes<320, 335>, psw::zpsw>,
124 lib::rw<
"program_old_psw", lib::bytes<336, 351>, psw::zpsw>,
125 lib::rw<
"mcck_old_psw", lib::bytes<352, 367>, psw::zpsw>,
126 lib::rw<
"io_old_psw", lib::bytes<368, 383>, psw::zpsw>,
128 lib::rw<
"restart_new_psw", lib::bytes<416, 431>, psw::zpsw>,
129 lib::rw<
"external_new_psw", lib::bytes<432, 447>, psw::zpsw>,
130 lib::rw<
"supervisor_call_new_psw", lib::bytes<448, 463>, psw::zpsw>,
131 lib::rw<
"program_new_psw", lib::bytes<464, 479>, psw::zpsw>,
132 lib::rw<
"mcck_new_psw", lib::bytes<480, 495>, psw::zpsw>,
133 lib::rw<
"io_new_psw", lib::bytes<496, 511>, psw::zpsw>,
135 lib::rw<
"save_area_sync", lib::bytes<512, 575>, u64[8]>,
136 lib::rw<
"stack_canary", lib::bytes<576, 583>, u64>,
137 lib::rw<
"return_psw_temp", lib::bytes<584, 599>, psw::zpsw>,
139 lib::rw<
"save_area_restart", lib::bytes<640, 647>, u64[1]>,
140 lib::rw<
"pcpu", lib::bytes<648, 655>, u64>,
141 lib::rw<
"return_psw", lib::bytes<656, 671>, psw::zpsw>,
142 lib::rw<
"return_mcck_psw", lib::bytes<672, 687>, psw::zpsw>,
143 lib::rw<
"last_break", lib::bytes<688, 695>, u64>,
144 lib::rw<
"sys_enter_timer", lib::bytes<696, 703>, u64>,
145 lib::rw<
"mcck_enter_timer", lib::bytes<704, 711>, u64>,
146 lib::rw<
"exit_timer", lib::bytes<712, 719>, u64>,
147 lib::rw<
"user_timer", lib::bytes<720, 727>, u64>,
148 lib::rw<
"guest_timer", lib::bytes<728, 735>, u64>,
149 lib::rw<
"system_timer", lib::bytes<736, 743>, u64>,
150 lib::rw<
"hardirq_timer", lib::bytes<744, 751>, u64>,
151 lib::rw<
"softirq_timer", lib::bytes<752, 759>, u64>,
152 lib::rw<
"steal_timer", lib::bytes<760, 767>, u64>,
153 lib::rw<
"avg_steal_timer", lib::bytes<768, 775>, u64>,
154 lib::rw<
"last_update_timer", lib::bytes<776, 783>, u64>,
155 lib::rw<
"last_update_clock", lib::bytes<784, 791>, u64>,
156 lib::rw<
"int_clock", lib::bytes<792, 807>, clock::tod_clock>,
158 lib::rw<
"clock_comparator", lib::bytes<808, 815>, u64>,
159 lib::rw<
"ap_cr0", lib::bytes<816, 823>, u64>,
160 lib::rw<
"ap_cr13", lib::bytes<824, 831>, u64>,
161 lib::rw<
"current_domain", lib::bytes<832, 839>, u64>,
162 lib::rw<
"kernel_stack", lib::bytes<840, 847>, u64>,
163 lib::rw<
"async_stack", lib::bytes<848, 855>, u64>,
164 lib::rw<
"nodat_stack", lib::bytes<856, 863>, u64>,
165 lib::rw<
"restart_stack", lib::bytes<864, 871>, u64>,
166 lib::rw<
"mcck_stack", lib::bytes<872, 879>, u64>,
167 lib::rw<
"restart_fn", lib::bytes<880, 887>, restart_fn>,
168 lib::rw<
"restart_data", lib::bytes<888, 895>, u64>,
169 lib::rw<
"restart_source", lib::bytes<896, 899>, u32>,
170 lib::rw<
"restart_flags", lib::bytes<900, 903>, u32>,
171 lib::rw<
"kernel_asce", lib::bytes<904, 911>, u64>,
172 lib::rw<
"user_asce", lib::bytes<912, 919>, u64>,
173 lib::rw<
"lpp", lib::bytes<920, 923>, u32>,
174 lib::rw<
"current_pid", lib::bytes<924, 927>, u32>,
175 lib::rw<
"cpu_id", lib::bytes<928, 929>, u16>,
177 lib::rw<
"spinlock_lockval", lib::bytes<940, 943>, u32>,
178 lib::rw<
"spinlock_index", lib::bytes<944, 947>, u32>,
179 lib::rw<
"percpu_ptr", lib::bytes<1024, 1031>, u64>,
181 lib::rw<
"mcck_save_area_designation", lib::bytes<4528, 4535>, trap::mcck::mcesad>,
182 lib::rw<
"floating_pt_save_area", lib::bytes<4608, 4735>, u64[16]>,
183 lib::rw<
"gpregs_save_area", lib::bytes<4736, 4863>, u64[16]>,
185 lib::overlay_rw<
"psw_save_area", lib::bytes<4864, 4879>, psw::zpsw>,
186 lib::overlay_rw<
"fixed_logout_area", lib::bytes<4864, 4879>, u8[16]>,
188 lib::rw<
"prefixreg_save_area", lib::bytes<4888, 4891>, u32>,
189 lib::rw<
"fpt_creg_save_area", lib::bytes<4892, 4895>, u32>,
190 lib::rw<
"tod_progreg_save_area", lib::bytes<4900, 4903>, u32>,
191 lib::rw<
"cpu_timer_save_area", lib::bytes<4904, 4911>, u32[2]>,
192 lib::rw<
"clock_comp_save_area", lib::bytes<4912, 4919>, u32[2]>,
193 lib::rw<
"last_break_save_area", lib::bytes<4920, 4927>, u64>,
194 lib::rw<
"access_regs_save_area", lib::bytes<4928, 4991>, u32[16]>,
195 lib::rw<
"cregs_save_area", lib::bytes<4992, 5119>, u64[16]>,
197 lib::rw<
"crash_record", lib::bytes<5120, 5375>, zxfoundation::sys::syschk::zx_crash_record>,
199 lib::rw<
"crypto_counter_designation", lib::bytes<5376, 5383>, lib::record<u64, lib::msb0_t,
200 lib::rw<
"real_location", lib::bits<0, 52>>
203 lib::rw<
"aic_designation", lib::bytes<5384, 5391>, lib::record<u64, lib::msb0_t,
204 lib::rw<
"real_location", lib::bits<0, 54>>
207 lib::rw<
"transactional_diagnostic_block", lib::bytes<6144, 6399>, tx::tdb>
210 [[nodiscard]]
auto get_current()
noexcept -> zlowcore*;
211 [[nodiscard]]
auto get_current_phys()
noexcept -> zlowcore*;
216 [[nodiscard]]
auto get_for_cpu(u16 cpu_id)
noexcept -> zlowcore*;
218 auto register_cpu_lowcore(u16 cpu_id, u64 phys_lc)
noexcept ->
void;
221 auto init_bsp(
const init::zxfl::protocol& proto)
noexcept ->
void;
224 [[nodiscard]]
auto current_domain_ptr()
noexcept ->
void*;
227 [[nodiscard]]
auto current_strand_ptr()
noexcept ->
void*;
232 auto register_restart_handler(
233 void(*fn)(
void*)
noexcept,
238 struct ap_init_params {
251 auto init_ap(zlowcore& lc,
const ap_init_params& p)
noexcept ->
void;