Prechádzať zdrojové kódy

Kernel/Devices: Use try_create_device helper for ConsoleDevice

Liav A 3 rokov pred
rodič
commit
fd4397a430

+ 5 - 15
Kernel/Devices/ConsoleDevice.cpp

@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
-#include <AK/Singleton.h>
 #include <Kernel/Devices/ConsoleDevice.h>
+#include <Kernel/Devices/DeviceManagement.h>
 #include <Kernel/IO.h>
 #include <Kernel/Locking/Spinlock.h>
 #include <Kernel/Sections.h>
@@ -14,23 +14,13 @@
 // Output bytes to kernel debug port 0xE9 (Bochs console). It's very handy.
 #define CONSOLE_OUT_TO_BOCHS_DEBUG_PORT
 
-static Singleton<ConsoleDevice> s_the;
 static Kernel::Spinlock g_console_lock;
 
-UNMAP_AFTER_INIT void ConsoleDevice::initialize()
+UNMAP_AFTER_INIT NonnullRefPtr<ConsoleDevice> ConsoleDevice::must_create()
 {
-    s_the.ensure_instance();
-    s_the->after_inserting();
-}
-
-ConsoleDevice& ConsoleDevice::the()
-{
-    return *s_the;
-}
-
-bool ConsoleDevice::is_initialized()
-{
-    return s_the.is_initialized();
+    auto device_or_error = DeviceManagement::try_create_device<ConsoleDevice>();
+    VERIFY(!device_or_error.is_error());
+    return device_or_error.release_value();
 }
 
 UNMAP_AFTER_INIT ConsoleDevice::ConsoleDevice()

+ 4 - 4
Kernel/Devices/ConsoleDevice.h

@@ -14,12 +14,11 @@ namespace Kernel {
 
 class ConsoleDevice final : public CharacterDevice {
     AK_MAKE_ETERNAL
+    friend class DeviceManagement;
+
 public:
-    static ConsoleDevice& the();
-    static void initialize();
-    static bool is_initialized();
+    static NonnullRefPtr<ConsoleDevice> must_create();
 
-    ConsoleDevice();
     virtual ~ConsoleDevice() override;
 
     // ^CharacterDevice
@@ -34,6 +33,7 @@ public:
     const CircularQueue<char, 16384>& logbuffer() const { return m_logbuffer; }
 
 private:
+    ConsoleDevice();
     CircularQueue<char, 16384> m_logbuffer;
 };
 

+ 15 - 0
Kernel/Devices/DeviceManagement.cpp

@@ -22,6 +22,12 @@ UNMAP_AFTER_INIT void DeviceManagement::initialize()
     s_the.ensure_instance();
 }
 
+
+UNMAP_AFTER_INIT void DeviceManagement::attach_console_device(ConsoleDevice const& device)
+{
+    m_console_device = device;
+}
+
 UNMAP_AFTER_INIT void DeviceManagement::attach_null_device(NullDevice const& device)
 {
     m_null_device = device;
@@ -85,4 +91,13 @@ NullDevice const& DeviceManagement::null_device() const
     return *m_null_device;
 }
 
+ConsoleDevice const& DeviceManagement::console_device() const
+{
+    return *m_console_device;
+}
+ConsoleDevice& DeviceManagement::console_device()
+{
+    return *m_console_device;
+}
+
 }

+ 9 - 0
Kernel/Devices/DeviceManagement.h

@@ -15,6 +15,7 @@
 #include <Kernel/API/KResult.h>
 #include <Kernel/API/TimePage.h>
 #include <Kernel/Arch/x86/RegisterState.h>
+#include <Kernel/Devices/ConsoleDevice.h>
 #include <Kernel/Devices/Device.h>
 #include <Kernel/Devices/NullDevice.h>
 #include <Kernel/UnixTypes.h>
@@ -30,14 +31,21 @@ public:
     static DeviceManagement& the();
     void attach_null_device(NullDevice const&);
 
+    bool is_console_device_attached() const { return !m_console_device.is_null(); }
+    void attach_console_device(ConsoleDevice const&);
+
     void after_inserting_device(Badge<Device>, Device&);
     void before_device_removal(Badge<Device>, Device&);
 
     void for_each(Function<void(Device&)>);
     Device* get_device(unsigned major, unsigned minor);
+
     NullDevice const& null_device() const;
     NullDevice& null_device();
 
+    ConsoleDevice const& console_device() const;
+    ConsoleDevice& console_device();
+
     template<typename DeviceType, typename... Args>
     static inline KResultOr<NonnullRefPtr<DeviceType>> try_create_device(Args&&... args)
     {
@@ -48,6 +56,7 @@ public:
 
 private:
     RefPtr<NullDevice> m_null_device;
+    RefPtr<ConsoleDevice> m_console_device;
     MutexProtected<HashMap<u32, Device*>> m_devices;
 };
 

+ 2 - 1
Kernel/GlobalProcessExposed.cpp

@@ -559,8 +559,9 @@ private:
     ProcFSDmesg();
     virtual KResult try_generate(KBufferBuilder& builder) override
     {
+        VERIFY(DeviceManagement::the().is_console_device_attached());
         InterruptDisabler disabler;
-        for (char ch : ConsoleDevice::the().logbuffer()) {
+        for (char ch : DeviceManagement::the().console_device().logbuffer()) {
             TRY(builder.append(ch));
         }
         return KSuccess;

+ 3 - 1
Kernel/TTY/ConsoleManagement.cpp

@@ -7,6 +7,7 @@
 #include <AK/Singleton.h>
 #include <Kernel/CommandLine.h>
 #include <Kernel/Debug.h>
+#include <Kernel/Devices/DeviceManagement.h>
 #include <Kernel/Graphics/GraphicsManagement.h>
 #include <Kernel/Panic.h>
 #include <Kernel/Sections.h>
@@ -48,7 +49,8 @@ UNMAP_AFTER_INIT void ConsoleManagement::initialize()
     for (size_t index = 0; index < s_max_virtual_consoles; index++) {
         // FIXME: Better determine the debug TTY we chose...
         if (index == 1) {
-            m_consoles.append(VirtualConsole::create_with_preset_log(index, ConsoleDevice::the().logbuffer()));
+            VERIFY(DeviceManagement::the().is_console_device_attached());
+            m_consoles.append(VirtualConsole::create_with_preset_log(index, DeviceManagement::the().console_device().logbuffer()));
             continue;
         }
         m_consoles.append(VirtualConsole::create(index));

+ 1 - 2
Kernel/init.cpp

@@ -186,8 +186,7 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init(BootInfo const& boot_info)
     DeviceManagement::initialize();
     SysFSComponentRegistry::initialize();
     DeviceManagement::the().attach_null_device(*NullDevice::must_initialize());
-
-    ConsoleDevice::initialize();
+    DeviceManagement::the().attach_console_device(*ConsoleDevice::must_create());
     s_bsp_processor.initialize(0);
 
     CommandLine::initialize();

+ 3 - 2
Kernel/kprintf.cpp

@@ -8,6 +8,7 @@
 #include <AK/StringView.h>
 #include <AK/Types.h>
 #include <Kernel/Devices/ConsoleDevice.h>
+#include <Kernel/Devices/DeviceManagement.h>
 #include <Kernel/Devices/PCISerialDevice.h>
 #include <Kernel/Graphics/GraphicsManagement.h>
 #include <Kernel/IO.h>
@@ -87,8 +88,8 @@ static void console_out(char ch)
 
     // It would be bad to reach the assert in ConsoleDevice()::the() and do a stack overflow
 
-    if (ConsoleDevice::is_initialized()) {
-        ConsoleDevice::the().put_char(ch);
+    if (DeviceManagement::the().is_console_device_attached()) {
+        DeviceManagement::the().console_device().put_char(ch);
     } else {
         IO::out8(IO::BOCHS_DEBUG_PORT, ch);
     }