/* * Init.cpp * Driver initialization orchestration * Copyright (c) 2025 Daniel Hammer */ #include "Init.hpp" #include #include #include #include #include #include #include #include #include #include #include #include namespace Drivers { // ------------------------------------------------------------------------- // Device ID whitelists // ------------------------------------------------------------------------- static constexpr uint16_t g_e1000Ids[] = { 0x100E, }; static constexpr uint16_t g_e1000eIds[] = { // I217 0x153A, 0x153B, // I218 0x155A, 0x1559, 0x15A0, 0x15A1, 0x15A2, 0x15A3, // I219-LM 0x156F, 0x15B7, 0x15BB, 0x15BD, 0x15DF, 0x15E1, 0x15E3, 0x15D7, 0x0D4C, 0x0D4E, 0x0D53, 0x0D55, 0x0DC5, 0x0DC7, 0x1A1C, 0x1A1E, // I219-V 0x1570, 0x15B8, 0x15BC, 0x15BE, 0x15E0, 0x15E2, 0x15D6, 0x15D8, 0x0D4D, 0x0D4F, 0x0D54, 0x0DC6, 0x0DC8, 0x1A1D, 0x1A1F, }; // ------------------------------------------------------------------------- // Probe wrappers (adapt namespace::Probe to PciProbeFunc signature) // ------------------------------------------------------------------------- static bool ProbeIntelGPU(const Pci::PciDevice& dev) { return Graphics::IntelGPU::Probe(dev); } static bool ProbeXhci(const Pci::PciDevice& dev) { return USB::Xhci::Probe(dev); } static bool ProbeE1000(const Pci::PciDevice& dev) { return Net::E1000::Probe(dev); } static bool ProbeE1000E(const Pci::PciDevice& dev) { return Net::E1000E::Probe(dev); } static bool ProbeAhci(const Pci::PciDevice& dev) { return Storage::Ahci::Probe(dev); } static bool ProbeNvme(const Pci::PciDevice& dev) { return Storage::Nvme::Probe(dev); } static bool ProbeIntelHda(const Pci::PciDevice& dev) { return Audio::IntelHda::Probe(dev); } // ------------------------------------------------------------------------- // Driver table // ------------------------------------------------------------------------- static constexpr Pci::PciDriverDesc g_driverTable[] = { // Order 1: Intel GPU — Early phase, match vendor=0x8086 + class=0x03 { "IntelGPU", 0x8086, // VendorId 0x03, // ClassCode (Display) 0xFF, // SubClass (any) 0xFF, // ProgIf (any) nullptr, // DeviceIds (internal gen lookup) 0, // DeviceIdCount Pci::ProbePhase::Early, ProbeIntelGPU, }, // Order 2: xHCI — Normal phase, match class=0x0C/0x03/0x30 { "xHCI", 0, // VendorId (any) 0x0C, // ClassCode (Serial Bus) 0x03, // SubClass (USB) 0x30, // ProgIf (xHCI) nullptr, 0, Pci::ProbePhase::Normal, ProbeXhci, }, // Order 3: E1000 — Normal phase, vendor=0x8086 + deviceId={0x100E} { "E1000", 0x8086, 0xFF, 0xFF, 0xFF, g_e1000Ids, sizeof(g_e1000Ids) / sizeof(g_e1000Ids[0]), Pci::ProbePhase::Normal, ProbeE1000, }, // Order 4: E1000E — Normal phase, vendor=0x8086 + deviceIds list { "E1000E", 0x8086, 0xFF, 0xFF, 0xFF, g_e1000eIds, sizeof(g_e1000eIds) / sizeof(g_e1000eIds[0]), Pci::ProbePhase::Normal, ProbeE1000E, }, // Order 5: AHCI — Normal phase, match class=0x01/0x06/0x01 (SATA AHCI) { "AHCI", 0, // VendorId (any) 0x01, // ClassCode (Mass Storage) 0x06, // SubClass (SATA) 0x01, // ProgIf (AHCI 1.0) nullptr, 0, Pci::ProbePhase::Normal, ProbeAhci, }, // Order 6: NVMe — Normal phase, match class=0x01/0x08/0x02 (NVM Express) { "NVMe", 0, // VendorId (any) 0x01, // ClassCode (Mass Storage) 0x08, // SubClass (Non-Volatile Memory) 0x02, // ProgIf (NVM Express) nullptr, 0, Pci::ProbePhase::Normal, ProbeNvme, }, // Order 7: Intel HDA — Normal phase, match vendor=0x8086 + class=0x04 (Multimedia) // SubClass 0x01 = "Multimedia audio controller" (most Intel HDA) // SubClass 0x03 = "Audio device" (HDA-compatible) { "IntelHDA", 0x8086, // VendorId (Intel) 0x04, // ClassCode (Multimedia) 0xFF, // SubClass (any — covers both 0x01 and 0x03) 0xFF, // ProgIf (any) nullptr, 0, Pci::ProbePhase::Normal, ProbeIntelHda, }, }; static constexpr uint16_t g_driverTableCount = sizeof(g_driverTable) / sizeof(g_driverTable[0]); // ------------------------------------------------------------------------- // Public API // ------------------------------------------------------------------------- void ProbeEarly() { Pci::ProbeAll(g_driverTable, g_driverTableCount, Pci::ProbePhase::Early); } void InitializeGraphics() { if (Graphics::IntelGPU::IsInitialized()) { ::Graphics::Framebuffer::Set( Graphics::IntelGPU::GetFramebufferBase(), Graphics::IntelGPU::GetWidth(), Graphics::IntelGPU::GetHeight(), Graphics::IntelGPU::GetPitch() ); } } void ProbeNormal() { Pci::ProbeAll(g_driverTable, g_driverTableCount, Pci::ProbePhase::Normal); } void InitializeNetwork() { ::Net::Initialize(); } void InitializeStorage() { // AHCI driver registered SATA devices as block devices during // ProbeNormal(). Now probe all block devices for GPT partitions. Storage::Gpt::ProbeAll(); } void InitializeAudio() { // HDA driver initializes during ProbeNormal(). // Bluetooth audio (A2DP) initializes automatically during USB enumeration // when a Bluetooth adapter is detected by the xHCI driver. } }