ladybird/Kernel/Interrupts/IOAPIC.h
Liav A f86be46c98 Kernel: Abstract IRQ controller handling from Interrupt handlers
Now we don't send raw numbers, but we let the IRQController object to
figure out the correct IRQ number.
This helps in a situation when we have 2 or more IOAPICs, so if IOAPIC
1 is assigned for IRQs 0-23 and IOAPIC 2 is assigned for IRQs 24-47,
if an IRQHandler of IRQ 25 invokes disable() for example, it will call
his responsible IRQController (IOAPIC 2), and the IRQController will
subtract the IRQ number with his assigned offset, and the result is that
the second redirection entry in IOAPIC 2 will be masked.
2020-03-24 16:15:33 +01:00

88 lines
3.6 KiB
C++

/*
* Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <Kernel/Interrupts/IRQController.h>
namespace Kernel {
struct [[gnu::packed]] ioapic_mmio_regs
{
volatile u32 select;
u32 reserved[3];
volatile u32 window;
};
class ISAInterruptOverrideMetadata;
class PCIInterruptOverrideMetadata;
class IOAPIC final : public IRQController {
public:
IOAPIC(ioapic_mmio_regs& regs, u32 gsi_base);
virtual void enable(const GenericInterruptHandler&) override;
virtual void disable(const GenericInterruptHandler&) override;
virtual void hard_disable() override;
virtual void eoi(const GenericInterruptHandler&) const override;
virtual void spurious_eoi(const GenericInterruptHandler&) const override;
virtual bool is_vector_enabled(u8 number) const override;
virtual u16 get_isr() const override;
virtual u16 get_irr() const override;
virtual u32 gsi_base() const override { return m_gsi_base; }
virtual size_t interrupt_vectors_count() const { return m_redirection_entries_count; }
virtual const char* model() const override { return "IOAPIC"; };
virtual IRQControllerType type() const override { return IRQControllerType::i82093AA; }
private:
void configure_redirection_entry(int index, u8 interrupt_vector, u8 delivery_mode, bool logical_destination, bool active_low, bool trigger_level_mode, bool masked, u8 destination) const;
void reset_redirection_entry(int index) const;
void map_interrupt_redirection(u8 interrupt_vector);
void reset_all_redirection_entries() const;
void mask_all_redirection_entries() const;
void mask_redirection_entry(u8 index) const;
void unmask_redirection_entry(u8 index) const;
bool is_redirection_entry_masked(u8 index) const;
u8 read_redirection_entry_vector(u8 index) const;
int find_redirection_entry_by_vector(u8 vector) const;
void configure_redirections() const;
void write_register(u32 index, u32 value) const;
u32 read_register(u32 index) const;
virtual void initialize() override;
void map_isa_interrupts();
void map_pci_interrupts();
void isa_identity_map(int index);
ioapic_mmio_regs& m_physical_access_registers;
u32 m_gsi_base;
u8 m_id;
u8 m_version;
size_t m_redirection_entries_count;
};
}