Serenity Operating System
at master 80 lines 2.6 kB view raw
1/* 2 * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <Kernel/Arch/InterruptManagement.h> 8#include <Kernel/Arch/Interrupts.h> 9#include <Kernel/Assertions.h> 10#include <Kernel/Interrupts/GenericInterruptHandler.h> 11 12namespace Kernel { 13GenericInterruptHandler& GenericInterruptHandler::from(u8 interrupt_number) 14{ 15 return get_interrupt_handler(interrupt_number); 16} 17 18GenericInterruptHandler::GenericInterruptHandler(u8 interrupt_number, bool disable_remap) 19 : m_interrupt_number(interrupt_number) 20 , m_disable_remap(disable_remap) 21{ 22 // NOTE: We cannot register or unregister the handler while the object 23 // is being constructed or deconstructed! 24} 25 26void GenericInterruptHandler::will_be_destroyed() 27{ 28 // This will be called for RefCounted interrupt handlers before the 29 // object is being destroyed. As soon as the destructor is invoked 30 // it is no longer advisable to unregister the handler (which causes 31 // calls to virtual functions), so let's do this right before 32 // invoking it 33 unregister_interrupt_handler(); 34} 35 36void GenericInterruptHandler::register_interrupt_handler() 37{ 38 if (m_registered) 39 return; 40 if (m_disable_remap) 41 register_generic_interrupt_handler(m_interrupt_number, *this); 42 else 43 register_generic_interrupt_handler(InterruptManagement::acquire_mapped_interrupt_number(m_interrupt_number), *this); 44 m_registered = true; 45} 46 47void GenericInterruptHandler::unregister_interrupt_handler() 48{ 49 if (!m_registered) 50 return; 51 if (m_disable_remap) 52 unregister_generic_interrupt_handler(m_interrupt_number, *this); 53 else 54 unregister_generic_interrupt_handler(InterruptManagement::acquire_mapped_interrupt_number(m_interrupt_number), *this); 55 m_registered = false; 56} 57 58void GenericInterruptHandler::change_interrupt_number(u8 number) 59{ 60 VERIFY_INTERRUPTS_DISABLED(); 61 VERIFY(!m_disable_remap); 62 if (m_registered) { 63 unregister_generic_interrupt_handler(InterruptManagement::acquire_mapped_interrupt_number(interrupt_number()), *this); 64 m_registered = false; 65 } 66 m_interrupt_number = number; 67 register_generic_interrupt_handler(InterruptManagement::acquire_mapped_interrupt_number(interrupt_number()), *this); 68} 69 70ReadonlySpan<u32> GenericInterruptHandler::per_cpu_call_counts() const 71{ 72 return m_per_cpu_call_counts.span().slice(0, Processor::count()); 73} 74 75void GenericInterruptHandler::increment_call_count() 76{ 77 ++m_per_cpu_call_counts[Processor::current_id()]; 78} 79 80}