diff options
| -rw-r--r-- | arch/x86_64/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/bus/isa.hpp | 31 | ||||
| -rw-r--r-- | arch/x86_64/kapi/devices.cpp | 22 | ||||
| -rw-r--r-- | arch/x86_64/src/bus/isa.cpp | 56 | ||||
| -rw-r--r-- | kapi/include/kapi/devices.hpp | 8 | ||||
| -rw-r--r-- | kernel/include/kernel/devices/root_bus.hpp | 4 | ||||
| -rw-r--r-- | kernel/src/devices/root_bus.cpp | 4 | ||||
| -rw-r--r-- | kernel/src/main.cpp | 3 | ||||
| -rw-r--r-- | libs/kstd/include/kstd/bits/unique_ptr.hpp | 11 |
9 files changed, 140 insertions, 3 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index 4427e4c..21dceef 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -15,6 +15,7 @@ target_sources("x86_64" PRIVATE "kapi/boot_modules.cpp" "kapi/cio.cpp" "kapi/cpu.cpp" + "kapi/devices.cpp" "kapi/interrupts.cpp" "kapi/memory.cpp" "kapi/system.cpp" @@ -24,6 +25,9 @@ target_sources("x86_64" PRIVATE "src/cpu/interrupts.cpp" "src/cpu/interrupt_stubs.S" + # Bus Initialization + "src/bus/isa.cpp" + # Low-level bootstrap "src/boot/boot32.S" "src/boot/entry64.s" diff --git a/arch/x86_64/include/arch/bus/isa.hpp b/arch/x86_64/include/arch/bus/isa.hpp new file mode 100644 index 0000000..41dda93 --- /dev/null +++ b/arch/x86_64/include/arch/bus/isa.hpp @@ -0,0 +1,31 @@ +#ifndef TEACHOS_X86_64_BUS_ISA_HPP +#define TEACHOS_X86_64_BUS_ISA_HPP + +#include "kapi/devices/bus.hpp" +#include "kapi/devices/device.hpp" + +#include <kstd/memory> +#include <kstd/vector> + +namespace arch::bus +{ + + struct isa final : public kapi::devices::bus + { + isa(); + + auto add_child(kstd::unique_ptr<device> child) -> void override; + + [[nodiscard]] auto children() const -> kstd::vector<kstd::observer_ptr<device>> const & override; + + auto init() -> bool override; + + private: + kstd::vector<kstd::unique_ptr<device>> m_devices{}; + kstd::vector<kstd::observer_ptr<device>> m_observers{}; + bool m_initialized{}; + }; + +} // namespace arch::bus + +#endif // TEACHOS_X86_64_BUS_ISA_HPP diff --git a/arch/x86_64/kapi/devices.cpp b/arch/x86_64/kapi/devices.cpp new file mode 100644 index 0000000..25185d6 --- /dev/null +++ b/arch/x86_64/kapi/devices.cpp @@ -0,0 +1,22 @@ +#include "kapi/devices.hpp" + +#include "arch/bus/isa.hpp" + +#include <kstd/memory> +#include <kstd/print> + +#include <utility> + +namespace kapi::devices +{ + + auto init_platform_devices() -> void + { + kstd::println("[x86_64:devices] Initializing ISA bus..."); + auto isa_bus = kstd::make_unique<arch::bus::isa>(); + + auto & root_bus = get_root_bus(); + root_bus.add_child(std::move(isa_bus)); + } + +} // namespace kapi::devices
\ No newline at end of file diff --git a/arch/x86_64/src/bus/isa.cpp b/arch/x86_64/src/bus/isa.cpp new file mode 100644 index 0000000..3fe4f6f --- /dev/null +++ b/arch/x86_64/src/bus/isa.cpp @@ -0,0 +1,56 @@ +#include "arch/bus/isa.hpp" + +#include "kapi/devices.hpp" +#include "kapi/devices/device.hpp" +#include "kapi/system.hpp" + +#include <kstd/memory> +#include <kstd/print> +#include <kstd/vector> + +#include <algorithm> +#include <utility> + +namespace arch::bus +{ + + isa::isa() + : kapi::devices::bus(kapi::devices::allocate_major_number(), 0, "isa") + {} + + auto isa::add_child(kstd::unique_ptr<device> child) -> void + { + auto observer = m_observers.emplace_back(child.get()); + m_devices.push_back(std::move(child)); + + if (m_initialized) + { + kstd::println("[bus:{}} Initializing child device '{}'", name(), observer->name()); + if (!observer->init()) + { + kapi::system::panic("[x86_64:devices] Failed to initialize child device"); + } + } + } + + auto isa::children() const -> kstd::vector<kstd::observer_ptr<device>> const & + { + return m_observers; + } + + auto isa::init() -> bool + { + if (m_initialized) + { + kapi::system::panic("[x86_64:devices] ISA bus already initialized!"); + } + + m_initialized = std::ranges::fold_left(m_devices, true, [](bool acc, auto & child) -> bool { + kstd::println("[x86_64:devices] Initializing child device '{}'", child->name()); + return acc && child->init(); + }); + + return m_initialized; + } + +} // namespace arch::bus
\ No newline at end of file diff --git a/kapi/include/kapi/devices.hpp b/kapi/include/kapi/devices.hpp index 60a39bd..2028a64 100644 --- a/kapi/include/kapi/devices.hpp +++ b/kapi/include/kapi/devices.hpp @@ -41,6 +41,14 @@ namespace kapi::devices //! @} + //! @addtogroup platform-defined + //! @{ + + //! Initialize the platform's device tree. + auto init_platform_devices() -> void; + + //! @} + } // namespace kapi::devices #endif
\ No newline at end of file diff --git a/kernel/include/kernel/devices/root_bus.hpp b/kernel/include/kernel/devices/root_bus.hpp index f7bfbfb..d92914d 100644 --- a/kernel/include/kernel/devices/root_bus.hpp +++ b/kernel/include/kernel/devices/root_bus.hpp @@ -8,6 +8,8 @@ #include <kstd/print> #include <kstd/vector> +#include <atomic> + namespace kernel::devices { @@ -24,7 +26,7 @@ namespace kernel::devices private: kstd::vector<kstd::unique_ptr<device>> m_children{}; kstd::vector<kstd::observer_ptr<device>> m_observers{}; - bool m_initialized{}; + std::atomic_flag m_initialized{}; }; } // namespace kernel::devices diff --git a/kernel/src/devices/root_bus.cpp b/kernel/src/devices/root_bus.cpp index a7f3c1a..75b5b80 100644 --- a/kernel/src/devices/root_bus.cpp +++ b/kernel/src/devices/root_bus.cpp @@ -24,7 +24,7 @@ namespace kernel::devices auto observer = m_observers.emplace_back(child.get()); m_children.push_back(std::move(child)); - if (m_initialized) + if (m_initialized.test()) { kstd::println("Initializing child device '{}'", observer->name()); if (!observer->init()) @@ -41,7 +41,7 @@ namespace kernel::devices auto root_bus::init() -> bool { - if (m_initialized) + if (m_initialized.test_and_set()) { kapi::system::panic("[kernel:devices] Root bus already initialized!"); } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 9d6028d..eaaf87f 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -183,6 +183,9 @@ auto main() -> int kapi::devices::init(); kstd::println("[OS] System root bus initialized."); + kapi::devices::init_platform_devices(); + kstd::println("[OS] Platform devices initialized."); + kapi::boot_modules::init(); kstd::println("[OS] Boot module registry initialized."); diff --git a/libs/kstd/include/kstd/bits/unique_ptr.hpp b/libs/kstd/include/kstd/bits/unique_ptr.hpp index e0870b1..f50335c 100644 --- a/libs/kstd/include/kstd/bits/unique_ptr.hpp +++ b/libs/kstd/include/kstd/bits/unique_ptr.hpp @@ -16,6 +16,9 @@ namespace kstd template<typename T> struct unique_ptr { + template<typename U> + friend struct unique_ptr; + /** * @brief Constructor. * @@ -40,6 +43,14 @@ namespace kstd */ unique_ptr(unique_ptr const &) = delete; + template<typename U> + requires(std::is_convertible_v<U *, T *>) + unique_ptr(unique_ptr<U> && other) noexcept + : pointer(other.pointer) + { + other.pointer = nullptr; + } + /** * @brief Deleted copy assignment operator to enforce unique ownership. */ |
