5export module arch.s390x.cpu.percpu;
6import arch.s390x.cpu.types;
7import zxfoundation.base.types;
8import zxfoundation.sync.qspinlock.mcs;
9import zxfoundation.memory.pmm.types;
14namespace arch::s390x::cpu::percpu {
16 using zxfoundation::memory::pmm::pcp_pool;
19 enum class irq_class : u8 {
30 struct alignas(processor::CACHE_LINE_SIZE) percpu_data {
43 u32 softirq_pending{};
45 u32 nucleus_nesting{};
47 irq_class current_irq_class{};
48 u8 _pad_irq_class[3]{};
49 std::atomic<u64> ec_bits{};
51 zxfoundation::sync::qspinlock::mcs_node qnodes[zxfoundation::sync::qspinlock::MCS_MAX_LOCK_DEPTH]{};
55 u8 in_rcu_read_side{};
58 void* rcu_pending_cbs{
nullptr};
59 u64 rcu_pending_gp{0};
60 u32 rcu_pending_count{0};
63 u32 ipi_pending_count{};
74 u8 topology_evidence{0};
79 u32 attached_domain_id{0};
80 u8 attached_dgp_state{0};
83 u64 watchdog_heartbeat{0};
85 u32 pgm_fixup_applied{0};
86 u64 pgm_fixup_addr{0};
89 u64 ipd_window_deadline{0};
92 std::atomic<u32> deferred_pending{};
97 static_assert(
__builtin_offsetof(percpu_data, cpu_id) == 8,
98 "cpu_id must be at offset 8 within s390x_percpu_data "
99 "(required by LC_CPU_ID_OFFSET = 0x0408)");
101 static_assert(
__builtin_offsetof(percpu_data, prefix_phys) == 0,
102 "prefix_phys must be at offset 0 within s390x_percpu_data");
104 static_assert(
sizeof(percpu_data) <= 0x0E00,
105 "s390x_percpu_data exceeds available lowcore space (0x0400–0x11FF = 0x0E00 bytes)");
108 auto init_bsp()
noexcept ->
void;
112 auto init_ap(percpu_data& pcp)
noexcept ->
void;
115 [[nodiscard]]
auto this_cpu()
noexcept -> percpu_data&;
118 [[nodiscard]]
auto cpu_id()
noexcept -> u16;
121 [[nodiscard]]
auto cpu_type()
noexcept -> u8;
125 [[nodiscard]]
auto cpu_type_prefix()
noexcept -> std::string_view;