diff options
author | Pankaj Raghav <dev@pankajraghav.com> | 2023-05-05 14:37:26 +0200 |
---|---|---|
committer | Jelle Raaijmakers <jelle@gmta.nl> | 2023-05-07 21:16:41 +0200 |
commit | f0b6eb6932e21010ae83bfcddd2d58880c4bbd19 (patch) | |
tree | 6205c99b57a01ed0233de8c336c0caf8440cfc61 /Kernel/Arch | |
parent | bf7ac06d7b3a0b5618e54e6acf4d2cfcbed1ca9b (diff) | |
download | serenity-f0b6eb6932e21010ae83bfcddd2d58880c4bbd19.zip |
Kernel: Implement helpers to manipulate MSI(x) data structures
MSIx table entry is used to program interrupt vectors and it is
architecture specific. Add helper functions declaration in
Arch/PCIMSI.h. The definition of the function is placed in the
respective arch specific code.
Diffstat (limited to 'Kernel/Arch')
-rw-r--r-- | Kernel/Arch/PCIMSI.h | 42 | ||||
-rw-r--r-- | Kernel/Arch/x86_64/PCI/MSI.cpp | 50 | ||||
-rw-r--r-- | Kernel/Arch/x86_64/PCI/MSI.h | 22 |
3 files changed, 114 insertions, 0 deletions
diff --git a/Kernel/Arch/PCIMSI.h b/Kernel/Arch/PCIMSI.h new file mode 100644 index 0000000000..fa5b3f4988 --- /dev/null +++ b/Kernel/Arch/PCIMSI.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023, Pankaj R <dev@pankajraghav.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/Types.h> + +namespace Kernel { +#if ARCH(X86_64) +u64 msi_address_register(u8 destination_id, bool redirection_hint, bool destination_mode); +u32 msi_data_register(u8 vector, bool level_trigger, bool assert); +u32 msix_vector_control_register(u32 vector_control, bool mask); +void msi_signal_eoi(); +#elif ARCH(AARCH64) +[[maybe_unused]] static u64 msi_address_register([[maybe_unused]] u8 destination_id, [[maybe_unused]] bool redirection_hint, [[maybe_unused]] bool destination_mode) +{ + TODO_AARCH64(); + return 0; +} + +[[maybe_unused]] static u32 msi_data_register([[maybe_unused]] u8 vector, [[maybe_unused]] bool level_trigger, [[maybe_unused]] bool assert) +{ + TODO_AARCH64(); + return 0; +} + +[[maybe_unused]] static u32 msix_vector_control_register([[maybe_unused]] u32 vector_control, [[maybe_unused]] bool mask) +{ + TODO_AARCH64(); + return 0; +} + +[[maybe_unused]] static void msi_signal_eoi() +{ + TODO_AARCH64(); + return; +} +#endif +} diff --git a/Kernel/Arch/x86_64/PCI/MSI.cpp b/Kernel/Arch/x86_64/PCI/MSI.cpp new file mode 100644 index 0000000000..874f9aae94 --- /dev/null +++ b/Kernel/Arch/x86_64/PCI/MSI.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023, Pankaj R <dev@pankajraghav.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <Kernel/Arch/Interrupts.h> +#include <Kernel/Arch/PCIMSI.h> +#include <Kernel/Arch/x86_64/Interrupts/APIC.h> +#include <Kernel/Arch/x86_64/PCI/MSI.h> +#include <Kernel/InterruptDisabler.h> + +namespace Kernel { +u64 msi_address_register(u8 destination_id, bool redirection_hint, bool destination_mode) +{ + u64 flags = 0; + if (redirection_hint) { + flags |= msi_redirection_hint; + if (destination_mode) + flags |= msi_destination_mode_logical; + } + return (msi_address_base | (destination_id << msi_destination_shift) | flags); +} + +u32 msi_data_register(u8 vector, bool level_trigger, bool assert) +{ + u32 flags = 0; + + if (level_trigger) { + flags |= msi_trigger_mode_level; + if (assert) + flags |= msi_level_assert; + } + return ((vector + IRQ_VECTOR_BASE) & msi_data_vector_mask) | flags; +} + +u32 msix_vector_control_register(u32 vector_control, bool mask) +{ + if (!mask) + return (vector_control & msi_vector_control_unmask); + return (vector_control | msi_vector_control_mask); +} + +void msi_signal_eoi() +{ + InterruptDisabler disabler; + APIC::the().eoi(); +} + +} diff --git a/Kernel/Arch/x86_64/PCI/MSI.h b/Kernel/Arch/x86_64/PCI/MSI.h new file mode 100644 index 0000000000..efe38c2888 --- /dev/null +++ b/Kernel/Arch/x86_64/PCI/MSI.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023, Pankaj R <dev@pankajraghav.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +// Address register +static constexpr u32 msi_address_base = 0xfee00000; +static constexpr u8 msi_destination_shift = 12; +static constexpr u32 msi_redirection_hint = 0x00000008; +static constexpr u32 msi_destination_mode_logical = 0x00000004; + +// Data register +static constexpr u8 msi_data_vector_mask = 0xff; +static constexpr u32 msi_trigger_mode_level = 0x00008000; +static constexpr u32 msi_level_assert = 0x00004000; + +// Vector control +static constexpr u32 msi_vector_control_mask = 0x1; +static constexpr u32 msi_vector_control_unmask = ~(0x1); |