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 {
44 u32 nucleus_nesting{};
46 irq_class current_irq_class{};
47 u8 _pad_irq_class[3]{};
48 std::atomic<u64> ec_bits{};
50 zxfoundation::sync::qspinlock::mcs_node qnodes[zxfoundation::sync::qspinlock::MCS_MAX_LOCK_DEPTH]{};
54 u8 in_rcu_read_side{};
57 void* rcu_pending_cbs{
nullptr};
58 u64 rcu_pending_gp{0};
59 u32 rcu_pending_count{0};
62 u32 ipi_pending_count{};
73 u8 topology_evidence{0};
78 u32 attached_domain_id{0};
79 u8 attached_dgp_state{0};
82 u64 watchdog_heartbeat{0};
84 u32 pgm_fixup_applied{0};
85 u64 pgm_fixup_addr{0};
88 u64 ipd_window_deadline{0};
91 std::atomic<u32> deferred_pending{};
98 static_assert(
__builtin_offsetof(percpu_data, self_phys) == 0,
99 "self_phys must be at offset 0 within percpu_data");
100 static_assert(
__builtin_offsetof(percpu_data, cpu_id) == 8,
101 "cpu_id must be at offset 8 within percpu_data");
102 static_assert(
__builtin_offsetof(percpu_data, preempt_count) == 48,
103 "preempt_count offset must match PCP_PREEMPT_COUNT in lowcore.h");
104 static_assert(
__builtin_offsetof(percpu_data, irq_nesting) == 52,
105 "irq_nesting offset must match PCP_IRQ_NESTING in lowcore.h");
106 static_assert(
__builtin_offsetof(percpu_data, nucleus_nesting) == 56,
107 "nucleus_nesting offset must match PCP_NUCLEUS_NESTING in lowcore.h");
108 static_assert(
__builtin_offsetof(percpu_data, current_irq_class) == 64,
109 "current_irq_class offset must match PCP_IRQ_CLASS in lowcore.h");
112 auto init_bsp()
noexcept ->
void;
116 auto init_ap(percpu_data& pcp)
noexcept ->
void;
119 [[nodiscard]]
auto this_cpu()
noexcept -> percpu_data&;
123 [[nodiscard]]
auto at(u16 cpu_id)
noexcept -> percpu_data&;
126 [[nodiscard]]
auto cpu_percpu(u16 cpu_id)
noexcept -> percpu::percpu_data*;
129 [[nodiscard]]
auto cpu_id()
noexcept -> u16;
132 [[nodiscard]]
auto cpu_type()
noexcept -> u8;
135 [[nodiscard]]
auto cpu_type_prefix()
noexcept -> std::string_view;