Browse Source

Kernel: Encapsulate APIC initialization inside InterruptManagement

Currently the APIC class is constructed irrespective of whether it
is used or not.

So, move APIC initialization from init to the InterruptManagement
class and construct the APIC class only when it is needed.
Pankaj Raghav 3 years ago
parent
commit
1a27220bca
3 changed files with 10 additions and 8 deletions
  1. 1 0
      Kernel/Interrupts/InterruptManagement.cpp
  2. 9 7
      Kernel/Time/TimeManagement.cpp
  3. 0 1
      Kernel/init.cpp

+ 1 - 0
Kernel/Interrupts/InterruptManagement.cpp

@@ -182,6 +182,7 @@ UNMAP_AFTER_INIT void InterruptManagement::switch_to_ioapic_mode()
         m_pci_interrupt_overrides = mp_parser->get_pci_interrupt_redirections();
     }
 
+    APIC::initialize();
     APIC::the().init_bsp();
 }
 

+ 9 - 7
Kernel/Time/TimeManagement.cpp

@@ -142,13 +142,15 @@ UNMAP_AFTER_INIT void TimeManagement::initialize(u32 cpu)
         VERIFY(!s_the.is_initialized());
         s_the.ensure_instance();
 
-        // Initialize the APIC timers after the other timers as the
-        // initialization needs to briefly enable interrupts, which then
-        // would trigger a deadlock trying to get the s_the instance while
-        // creating it.
-        if (auto* apic_timer = APIC::the().initialize_timers(*s_the->m_system_timer)) {
-            dmesgln("Time: Using APIC timer as system timer");
-            s_the->set_system_timer(*apic_timer);
+        if (APIC::initialized()) {
+            // Initialize the APIC timers after the other timers as the
+            // initialization needs to briefly enable interrupts, which then
+            // would trigger a deadlock trying to get the s_the instance while
+            // creating it.
+            if (auto* apic_timer = APIC::the().initialize_timers(*s_the->m_system_timer)) {
+                dmesgln("Time: Using APIC timer as system timer");
+                s_the->set_system_timer(*apic_timer);
+            }
         }
 
         s_the->m_time_page_region = MM.allocate_kernel_region(PAGE_SIZE, "Time page"sv, Memory::Region::Access::ReadWrite, AllocationStrategy::AllocateNow).release_value();

+ 0 - 1
Kernel/init.cpp

@@ -203,7 +203,6 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init(BootInfo const& boot_info)
     for (ctor_func_t* ctor = start_ctors; ctor < end_ctors; ctor++)
         (*ctor)();
 
-    APIC::initialize();
     InterruptManagement::initialize();
     ACPI::initialize();