summaryrefslogtreecommitdiff
path: root/Kernel/Arch/x86/Interrupts.h
blob: f97b82c43fc85ae23a142636fea852ccf68b59fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*
 * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
 * Copyright (c) 2021, Leon Albrecht <leon2002.la@gmail.com>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include <AK/Types.h>
#include <Kernel/Interrupts/GenericInterruptHandler.h>

namespace Kernel {

class GenericInterruptHandeler;

extern "C" void interrupt_common_asm_entry();

#if ARCH(I386)
#    define INTERRUPT_HANDLER_PUSH_PADDING
#else
#    define INTERRUPT_HANDLER_PUSH_PADDING "pushw $0\npushw $0\n"
#endif

// clang-format off
#define GENERATE_GENERIC_INTERRUPT_HANDLER_ASM_ENTRY(isr_number)                  \
    extern "C" void interrupt_##isr_number##_asm_entry();                         \
    static void interrupt_##isr_number##_asm_entry_dummy() __attribute__((used)); \
    NEVER_INLINE void interrupt_##isr_number##_asm_entry_dummy()                  \
    {                                                                             \
        asm(".globl interrupt_" #isr_number "_asm_entry\n"                        \
            "interrupt_" #isr_number "_asm_entry:\n"                              \
            INTERRUPT_HANDLER_PUSH_PADDING                                        \
            "    pushw $" #isr_number "\n"                                        \
            "    pushw $0\n"                                                      \
            "    jmp interrupt_common_asm_entry\n");                              \
    }
// clang-format on

void register_interrupt_handler(u8 number, void (*handler)());
void register_user_callable_interrupt_handler(u8 number, void (*handler)());
GenericInterruptHandler& get_interrupt_handler(u8 interrupt_number);
void register_generic_interrupt_handler(u8 number, GenericInterruptHandler&);
void unregister_generic_interrupt_handler(u8 number, GenericInterruptHandler&);

void idt_init();

}