Serenity Operating System
1/*
2 * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <AK/IntrusiveList.h>
10#include <AK/Types.h>
11#include <Kernel/Arch/RegisterState.h>
12
13namespace Kernel {
14
15enum class HandlerType : u8 {
16 IRQHandler = 1,
17 SharedIRQHandler = 2,
18 UnhandledInterruptHandler = 3,
19 SpuriousInterruptHandler = 4
20};
21
22class GenericInterruptHandler {
23public:
24 static GenericInterruptHandler& from(u8 interrupt_number);
25 virtual ~GenericInterruptHandler()
26 {
27 VERIFY(!m_registered);
28 }
29 // Note: this method returns boolean value, to indicate if the handler handled
30 // the interrupt or not. This is useful for shared handlers mostly.
31 virtual bool handle_interrupt(RegisterState const& regs) = 0;
32
33 void will_be_destroyed();
34 bool is_registered() const { return m_registered; }
35 void register_interrupt_handler();
36 void unregister_interrupt_handler();
37
38 u8 interrupt_number() const { return m_interrupt_number; }
39
40 ReadonlySpan<u32> per_cpu_call_counts() const;
41
42 virtual size_t sharing_devices_count() const = 0;
43 virtual bool is_shared_handler() const = 0;
44 virtual bool is_sharing_with_others() const = 0;
45
46 virtual HandlerType type() const = 0;
47 virtual StringView purpose() const = 0;
48 virtual StringView controller() const = 0;
49
50 virtual bool eoi() = 0;
51 void increment_call_count();
52
53protected:
54 void change_interrupt_number(u8 number);
55 GenericInterruptHandler(u8 interrupt_number, bool disable_remap = false);
56
57 void disable_remap() { m_disable_remap = true; }
58
59private:
60 Array<u32, MAX_CPU_COUNT> m_per_cpu_call_counts {};
61
62 u8 m_interrupt_number { 0 };
63 bool m_disable_remap { false };
64 bool m_registered { false };
65
66 IntrusiveListNode<GenericInterruptHandler> m_list_node;
67
68public:
69 using List = IntrusiveList<&GenericInterruptHandler::m_list_node>;
70};
71}