Serenity Operating System
1/*
2 * Copyright (c) 2018-2021, James Mintram <me@jamesrm.com>
3 * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#pragma once
9
10#include <AK/Function.h>
11#include <Kernel/Arch/DeferredCallEntry.h>
12
13namespace Kernel {
14
15// FIXME: Move the InterruptsState enum and related functions inside the Processor class.
16enum class InterruptsState {
17 Enabled,
18 Disabled
19};
20
21InterruptsState processor_interrupts_state();
22void restore_processor_interrupts_state(InterruptsState);
23
24}
25
26#if ARCH(X86_64)
27# include <Kernel/Arch/x86_64/Processor.h>
28#elif ARCH(AARCH64)
29# include <Kernel/Arch/aarch64/Processor.h>
30#else
31# error "Unknown architecture"
32#endif
33
34namespace Kernel {
35
36namespace Memory {
37class PageDirectory;
38}
39
40struct ProcessorMessageEntry;
41struct ProcessorMessage {
42 using CallbackFunction = Function<void()>;
43
44 enum Type {
45 FlushTlb,
46 Callback,
47 };
48 Type type;
49 Atomic<u32> refs;
50 union {
51 ProcessorMessage* next; // only valid while in the pool
52 alignas(CallbackFunction) u8 callback_storage[sizeof(CallbackFunction)];
53 struct {
54 Memory::PageDirectory const* page_directory;
55 u8* ptr;
56 size_t page_count;
57 } flush_tlb;
58 };
59
60 bool volatile async;
61
62 ProcessorMessageEntry* per_proc_entries;
63
64 CallbackFunction& callback_value()
65 {
66 return *bit_cast<CallbackFunction*>(&callback_storage);
67 }
68
69 void invoke_callback()
70 {
71 VERIFY(type == Type::Callback);
72 callback_value()();
73 }
74};
75
76struct ProcessorMessageEntry {
77 ProcessorMessageEntry* next;
78 ProcessorMessage* msg;
79};
80
81template<typename T>
82class ProcessorSpecific {
83public:
84 static void initialize()
85 {
86 Processor::current().set_specific(T::processor_specific_data_id(), new T);
87 }
88 static T& get()
89 {
90 return *Processor::current().get_specific<T>();
91 }
92};
93}