5export module arch.s390x.trap.ext;
6import arch.s390x.cpu.lowcore;
7import arch.s390x.cpu.irq;
8import arch.s390x.cpu.cputimer;
9import arch.s390x.cpu.clock;
10import arch.s390x.cpu.cpumask;
11import arch.s390x.cpu.psw;
12import zxfoundation.sys.irq.consts;
13import zxfoundation.sys.irq.core;
14import zxfoundation.sched.core;
15import zxfoundation.sched.topology.core;
16import zxfoundation.dgp.domain.types;
17import zxfoundation.base.types;
18import zxfoundation.sys.syschk.core;
19import zxfoundation.sys.timer.core;
20import zxfoundation.sys.printk.core;
21import zxfoundation.sys.timer.types;
22import zxfoundation.smp.csd.core;
24import lib.softirq.core;
28namespace arch::s390x::trap::ext {
32 constexpr u16 EXT_INTERRUPT_KEY = 0x0040;
33 constexpr u16 EXT_CLOCK_COMPARATOR = 0x1004;
34 constexpr u16 EXT_CPU_TIMER = 0x1005;
35 constexpr u16 EXT_WARNING_TRACK = 0x1007;
36 constexpr u16 EXT_MALFUNCTION_ALERT = 0x1200;
37 constexpr u16 EXT_EMERGENCY_SIGNAL = 0x1201;
38 constexpr u16 EXT_EXTERNAL_CALL = 0x1202;
39 constexpr u16 EXT_TIMING_ALERT = 0x1406;
40 constexpr u16 EXT_MEASUREMENT_ALERT = 0x1407;
41 constexpr u16 EXT_SERVICE_SIGNAL = 0x2401;
42 constexpr u16 EXT_CP_SERVICE = 0x2603;
48 auto ack_lowcore()
noexcept ->
void {
49 auto* lc = arch::s390x::cpu::lowcore::get_current();
50 lc->ext_int_code = 0U;
57 auto handle(cpu::irq::irq_frame* frame)
noexcept ->
void {
58 auto* lc = cpu::lowcore::get_current();
59 const u16 ext_code = lc->ext_int_code;
61 detail::ack_lowcore();
63 const u16 irq_nr = zxfoundation::sys::irq::ext_code_to_irq(ext_code);
64 if (irq_nr == zxfoundation::sys::irq::IRQ_NR_MAX) {
65 zxfoundation::sys::printk::pverbose(
66 "ext: unrecognised ext_code {:#06x} — no IRQ slot\n",
71 zxfoundation::sys::irq::irq_dispatch(
72 irq_nr, frame, cpu::irq::ZX_IRQ_CLASS_EXT);
74 namespace irq = zxfoundation::sys::irq;
75 if (irq::deferred_test_clear(irq::DEFERRED_RESCHED_BIT)) {
76 zxfoundation::sched::sched_resched_current();
79 if (irq::deferred_test_clear(irq::DEFERRED_MCCK_PENDING_BIT)) {
85 zxfoundation::sys::printk::pverbose(
86 "ext: deferred MCCK work armed on cpu={}\n",
87 arch::s390x::cpu::lowcore::this_cpu_percpu().cpu_id);
90 if (irq::deferred_test_clear(irq::DEFERRED_CALL_FUNCTION_BIT)) {
91 zxfoundation::smp::csd::drain_cpu();
94 if (irq::deferred_test_clear(irq::DEFERRED_IRQ_WORK_BIT)) {
98 if (irq::deferred_test_clear(irq::DEFERRED_STOP_CPU_BIT)) {
100 arch::s390x::cpu::lowcore::this_cpu_percpu().cpu_id;
101 zxfoundation::sys::printk::pnotice(
102 "ext: stop-cpu deferred work on cpu={} — halting\n", cpu_id);
103 arch::s390x::cpu::cpumask::cpu_clear_online(cpu_id);
104 zxfoundation::sched::topology::topology_offline_cpu(cpu_id);
105 arch::s390x::cpu::psw::disabled_wait();