From 645578894e0ec81a8a23458aad2661f89e931ded Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 2 Mar 2023 02:32:55 +0200 Subject: [PATCH] Updated driver loading code --- Core/Driver/Driver.cpp | 21 +- Core/Driver/DriverLoading/BindInput.cpp | 98 +++-- Core/Driver/DriverLoading/BindInterrupt.cpp | 416 ++++++++++++++------ Core/Driver/DriverLoading/BindPCI.cpp | 379 ++++++++++++++---- Core/Driver/DriverLoading/BindProcess.cpp | 35 ++ include/driver.hpp | 40 +- 6 files changed, 751 insertions(+), 238 deletions(-) diff --git a/Core/Driver/Driver.cpp b/Core/Driver/Driver.cpp index 16f79c7..10c466a 100644 --- a/Core/Driver/Driver.cpp +++ b/Core/Driver/Driver.cpp @@ -30,13 +30,12 @@ namespace Driver void Driver::UnloadAllDrivers() { - KernelCallback callback; debug("%ld drivers loaded, [DUIDs: %ld]", Drivers.size(), DriverUIDs); debug("driver size %ld", Drivers.size()); for (size_t i = 0; i < Drivers.size(); i++) { DriverFile *drv = Drivers[i]; - memset(&callback, 0, sizeof(KernelCallback)); + KernelCallback callback; callback.Reason = StopReason; debug("Stopping & unloading driver %ld [%#lx]", drv->DriverUID, drv->Address); DriverManager->IOCB(drv->DriverUID, (void *)&callback); @@ -54,16 +53,16 @@ namespace Driver bool Driver::UnloadDriver(unsigned long DUID) { + debug("Searching for driver %ld", DUID); for (size_t i = 0; i < Drivers.size(); i++) { DriverFile *drv = Drivers[i]; if (drv->DriverUID == DUID) { KernelCallback callback; - memset(&callback, 0, sizeof(KernelCallback)); callback.Reason = StopReason; - debug("Stopping & unloading driver %ld [%#lx]", drv->DriverUID, drv->Address); - DriverManager->IOCB(drv->DriverUID, (void *)&callback); + debug("Stopping and unloading driver %ld [%#lx]", drv->DriverUID, drv->Address); + this->IOCB(drv->DriverUID, (void *)&callback); delete drv->MemTrk; for (size_t i = 0; i < sizeof(drv->InterruptHook) / sizeof(drv->InterruptHook[0]); i++) @@ -81,12 +80,16 @@ namespace Driver int Driver::IOCB(unsigned long DUID, void *KCB) { - foreach (auto var in Drivers) - if (var->DriverUID == DUID) + foreach (auto Drv in Drivers) + { + if (Drv->DriverUID == DUID) { - FexExtended *DrvExtHdr = (FexExtended *)((uintptr_t)var->Address + EXTENDED_SECTION_ADDRESS); - return ((int (*)(void *))((uintptr_t)DrvExtHdr->Driver.Callback + (uintptr_t)var->Address))(KCB); + FexExtended *DrvExtHdr = (FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS); + int ret = ((int (*)(void *))((uintptr_t)DrvExtHdr->Driver.Callback + (uintptr_t)Drv->Address))(KCB); + __sync; + return ret; } + } return -1; } diff --git a/Core/Driver/DriverLoading/BindInput.cpp b/Core/Driver/DriverLoading/BindInput.cpp index b013f9c..bcce8c7 100644 --- a/Core/Driver/DriverLoading/BindInput.cpp +++ b/Core/Driver/DriverLoading/BindInput.cpp @@ -14,6 +14,70 @@ namespace Driver { + DriverCode Driver::BindInputGeneric(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindInputDisplay(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindInputNetwork(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindInputStorage(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindInputFileSystem(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindInputInput(Memory::MemMgr *mem, void *fex) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + KernelCallback *KCallback = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback))); + + fixme("Input driver: %s", fexExtended->Driver.Name); + KCallback->RawPtr = nullptr; + KCallback->Reason = CallbackReason::ConfigurationReason; + int CallbackRet = ((int (*)(KernelCallback *))((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex))(KCallback); + if (CallbackRet == DriverReturnCode::NOT_IMPLEMENTED) + { + delete mem; + error("Driver %s is not implemented", fexExtended->Driver.Name); + return DriverCode::NOT_IMPLEMENTED; + } + else if (CallbackRet != DriverReturnCode::OK) + { + delete mem; + error("Driver %s returned error %d", fexExtended->Driver.Name, CallbackRet); + return DriverCode::DRIVER_RETURNED_ERROR; + } + + fixme("Input driver: %s", fexExtended->Driver.Name); + + DriverFile *DrvFile = new DriverFile; + DrvFile->Enabled = true; + DrvFile->DriverUID = this->DriverUIDs - 1; + DrvFile->Address = (void *)fex; + DrvFile->MemTrk = mem; + DrvFile->InterruptHook[0] = nullptr; + Drivers.push_back(DrvFile); + return DriverCode::OK; + } + + DriverCode Driver::BindInputAudio(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; + } + DriverCode Driver::DriverLoadBindInput(void *DrvExtHdr, uintptr_t DriverAddress, size_t Size, bool IsElf) { UNUSED(DrvExtHdr); @@ -39,45 +103,15 @@ namespace Driver } debug("Starting driver %s (offset: %#lx)", fexExtended->Driver.Name, fex); - KernelCallback *KCallback = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback))); - switch (fexExtended->Driver.Type) { case FexDriverType::FexDriverType_Input: - { - fixme("Input driver: %s", fexExtended->Driver.Name); - KCallback->RawPtr = nullptr; - break; - KCallback->Reason = CallbackReason::ConfigurationReason; - int CallbackRet = ((int (*)(KernelCallback *))((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex))(KCallback); - if (CallbackRet == DriverReturnCode::NOT_IMPLEMENTED) - { - delete mem; - error("Driver %s is not implemented", fexExtended->Driver.Name); - break; - } - else if (CallbackRet != DriverReturnCode::OK) - { - delete mem; - error("Driver %s returned error %d", fexExtended->Driver.Name, CallbackRet); - break; - } - - fixme("Input driver: %s", fexExtended->Driver.Name); - - DriverFile *DrvFile = new DriverFile; - DrvFile->DriverUID = this->DriverUIDs - 1; - DrvFile->Address = (void *)fex; - DrvFile->MemTrk = mem; - DrvFile->InterruptHook[0] = nullptr; - Drivers.push_back(DrvFile); - break; - } + return BindInputInput(mem, fex); default: { warn("Unknown driver type: %d", fexExtended->Driver.Type); delete mem; - break; + return DriverCode::UNKNOWN_DRIVER_TYPE; } } diff --git a/Core/Driver/DriverLoading/BindInterrupt.cpp b/Core/Driver/DriverLoading/BindInterrupt.cpp index f6ddbc1..0ffcee9 100644 --- a/Core/Driver/DriverLoading/BindInterrupt.cpp +++ b/Core/Driver/DriverLoading/BindInterrupt.cpp @@ -14,6 +14,300 @@ namespace Driver { + DriverCode Driver::BindInterruptGeneric(Memory::MemMgr *mem, void *fex) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + fixme("Generic driver: %s", fexExtended->Driver.Name); + DriverFile *DrvFile = new DriverFile; + DrvFile->Enabled = true; + DrvFile->DriverUID = this->DriverUIDs - 1; + DrvFile->Address = (void *)fex; + DrvFile->MemTrk = mem; + Drivers.push_back(DrvFile); + return DriverCode::OK; + } + + DriverCode Driver::BindInterruptDisplay(Memory::MemMgr *mem, void *fex) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + fixme("Display driver: %s", fexExtended->Driver.Name); + delete mem; + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindInterruptNetwork(Memory::MemMgr *mem, void *fex) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + fixme("Network driver: %s", fexExtended->Driver.Name); + delete mem; + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindInterruptStorage(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; // FIXME + + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + KernelCallback *KCallback = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback))); + UNUSED(KCallback); // Shut up clang + for (unsigned long i = 0; i < sizeof(fexExtended->Driver.Bind.Interrupt.Vector) / sizeof(fexExtended->Driver.Bind.Interrupt.Vector[0]); i++) + { + if (fexExtended->Driver.Bind.Interrupt.Vector[i] == 0) + break; + + fixme("TODO: MULTIPLE BIND INTERRUPT VECTORS %d", fexExtended->Driver.Bind.Interrupt.Vector[i]); + } + + KCallback->RawPtr = nullptr; + KCallback->Reason = CallbackReason::ConfigurationReason; + int CallbackRet = ((int (*)(KernelCallback *))((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex))(KCallback); + if (CallbackRet == DriverReturnCode::NOT_IMPLEMENTED) + { + error("Driver %s is not implemented", fexExtended->Driver.Name); + delete mem; + return DriverCode::NOT_IMPLEMENTED; + } + else if (CallbackRet != DriverReturnCode::OK) + { + error("Driver %s returned error %d", fexExtended->Driver.Name, CallbackRet); + delete mem; + return DriverCode::DRIVER_RETURNED_ERROR; + } + + DriverFile *DrvFile = new DriverFile; + DrvFile->Enabled = true; + DrvFile->DriverUID = this->DriverUIDs - 1; + DrvFile->Address = (void *)fex; + DrvFile->MemTrk = mem; + Drivers.push_back(DrvFile); + return DriverCode::OK; + } + + DriverCode Driver::BindInterruptFileSystem(Memory::MemMgr *mem, void *fex) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + fixme("Filesystem driver: %s", fexExtended->Driver.Name); + delete mem; + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindInterruptInput(Memory::MemMgr *mem, void *fex) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + debug("Searching for conflicting drivers..."); + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + + if ((fe->Driver.TypeFlags & FexDriverInputTypes_Mouse && + fexExtended->Driver.TypeFlags & FexDriverInputTypes_Mouse) || + (fe->Driver.TypeFlags & FexDriverInputTypes_Keyboard && + fexExtended->Driver.TypeFlags & FexDriverInputTypes_Keyboard)) + { + DriversToRemove.push_back(Drv->DriverUID); + debug("Driver %s is conflicting with %s", fe->Driver.Name, fexExtended->Driver.Name); + } + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + KernelCallback *KCallback = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback))); + + DriverInterruptHook *InterruptHook = nullptr; + if (fexExtended->Driver.Bind.Interrupt.Vector[0] != 0) + InterruptHook = new DriverInterruptHook(fexExtended->Driver.Bind.Interrupt.Vector[0] + 32, // x86 + (void *)((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex), + KCallback); + + for (unsigned long i = 0; i < sizeof(fexExtended->Driver.Bind.Interrupt.Vector) / sizeof(fexExtended->Driver.Bind.Interrupt.Vector[0]); i++) + { + if (fexExtended->Driver.Bind.Interrupt.Vector[i] == 0) + break; + // InterruptHook = new DriverInterruptHook((fexExtended->Driver.Bind.Interrupt.Vector[i] + 32, // x86 + // (void *)((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex), + // KCallback); + fixme("TODO: MULTIPLE BIND INTERRUPT VECTORS %d", fexExtended->Driver.Bind.Interrupt.Vector[i]); + } + + KCallback->RawPtr = nullptr; + KCallback->Reason = CallbackReason::ConfigurationReason; + int CallbackRet = ((int (*)(KernelCallback *))((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex))(KCallback); + if (CallbackRet == DriverReturnCode::NOT_IMPLEMENTED) + { + error("Driver %s is not implemented", fexExtended->Driver.Name); + delete InterruptHook; + delete mem; + return DriverCode::NOT_IMPLEMENTED; + } + else if (CallbackRet != DriverReturnCode::OK) + { + error("Driver %s returned error %d", fexExtended->Driver.Name, CallbackRet); + delete InterruptHook; + delete mem; + return DriverCode::DRIVER_RETURNED_ERROR; + } + + memset(KCallback, 0, sizeof(KernelCallback)); + KCallback->Reason = CallbackReason::InterruptReason; + + DriverFile *DrvFile = new DriverFile; + DrvFile->Enabled = true; + DrvFile->DriverUID = this->DriverUIDs - 1; + DrvFile->Address = (void *)fex; + DrvFile->MemTrk = mem; + DrvFile->InterruptHook[0] = InterruptHook; + Drivers.push_back(DrvFile); + return DriverCode::OK; + } + + DriverCode Driver::BindInterruptAudio(Memory::MemMgr *mem, void *fex) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + fixme("Audio driver: %s", fexExtended->Driver.Name); + delete mem; + return DriverCode::NOT_IMPLEMENTED; + } + DriverCode Driver::DriverLoadBindInterrupt(void *DrvExtHdr, uintptr_t DriverAddress, size_t Size, bool IsElf) { UNUSED(IsElf); @@ -38,133 +332,27 @@ namespace Driver } debug("Starting driver %s (offset: %#lx)", fexExtended->Driver.Name, fex); - KernelCallback *KCallback = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback))); - switch (fexExtended->Driver.Type) { case FexDriverType::FexDriverType_Generic: - { - fixme("Generic driver: %s", fexExtended->Driver.Name); - DriverFile *DrvFile = new DriverFile; - DrvFile->DriverUID = this->DriverUIDs - 1; - DrvFile->Address = (void *)fex; - DrvFile->MemTrk = mem; - Drivers.push_back(DrvFile); - break; - } + return BindInterruptGeneric(mem, fex); case FexDriverType::FexDriverType_Display: - { - fixme("Display driver: %s", fexExtended->Driver.Name); - delete mem; - break; - } + return BindInterruptDisplay(mem, fex); case FexDriverType::FexDriverType_Network: - { - fixme("Network driver: %s", fexExtended->Driver.Name); - delete mem; - break; - } + return BindInterruptNetwork(mem, fex); case FexDriverType::FexDriverType_Storage: - { - for (unsigned long i = 0; i < sizeof(((FexExtended *)DrvExtHdr)->Driver.Bind.Interrupt.Vector) / sizeof(((FexExtended *)DrvExtHdr)->Driver.Bind.Interrupt.Vector[0]); i++) - { - if (((FexExtended *)DrvExtHdr)->Driver.Bind.Interrupt.Vector[i] == 0) - break; - - fixme("TODO: MULTIPLE BIND INTERRUPT VECTORS %d", ((FexExtended *)DrvExtHdr)->Driver.Bind.Interrupt.Vector[i]); - } - - fixme("Not implemented"); - delete mem; - break; - - KCallback->RawPtr = nullptr; - KCallback->Reason = CallbackReason::ConfigurationReason; - int CallbackRet = ((int (*)(KernelCallback *))((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex))(KCallback); - if (CallbackRet == DriverReturnCode::NOT_IMPLEMENTED) - { - error("Driver %s is not implemented", fexExtended->Driver.Name); - delete mem; - break; - } - else if (CallbackRet != DriverReturnCode::OK) - { - error("Driver %s returned error %d", fexExtended->Driver.Name, CallbackRet); - delete mem; - break; - } - - DriverFile *DrvFile = new DriverFile; - DrvFile->DriverUID = this->DriverUIDs - 1; - DrvFile->Address = (void *)fex; - DrvFile->MemTrk = mem; - Drivers.push_back(DrvFile); - break; - } + return BindInterruptStorage(mem, fex); case FexDriverType::FexDriverType_FileSystem: - { - fixme("Filesystem driver: %s", fexExtended->Driver.Name); - delete mem; - break; - } + return BindInterruptFileSystem(mem, fex); case FexDriverType::FexDriverType_Input: - { - DriverInterruptHook *InterruptHook = nullptr; - if (((FexExtended *)DrvExtHdr)->Driver.Bind.Interrupt.Vector[0] != 0) - InterruptHook = new DriverInterruptHook(((FexExtended *)DrvExtHdr)->Driver.Bind.Interrupt.Vector[0] + 32, // x86 - (void *)((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex), - KCallback); - - for (unsigned long i = 0; i < sizeof(((FexExtended *)DrvExtHdr)->Driver.Bind.Interrupt.Vector) / sizeof(((FexExtended *)DrvExtHdr)->Driver.Bind.Interrupt.Vector[0]); i++) - { - if (((FexExtended *)DrvExtHdr)->Driver.Bind.Interrupt.Vector[i] == 0) - break; - // InterruptHook = new DriverInterruptHook(((FexExtended *)DrvExtHdr)->Driver.Bind.Interrupt.Vector[i] + 32, // x86 - // (void *)((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex), - // KCallback); - fixme("TODO: MULTIPLE BIND INTERRUPT VECTORS %d", ((FexExtended *)DrvExtHdr)->Driver.Bind.Interrupt.Vector[i]); - } - - KCallback->RawPtr = nullptr; - KCallback->Reason = CallbackReason::ConfigurationReason; - int CallbackRet = ((int (*)(KernelCallback *))((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex))(KCallback); - if (CallbackRet == DriverReturnCode::NOT_IMPLEMENTED) - { - error("Driver %s is not implemented", fexExtended->Driver.Name); - delete InterruptHook; - delete mem; - break; - } - else if (CallbackRet != DriverReturnCode::OK) - { - error("Driver %s returned error %d", fexExtended->Driver.Name, CallbackRet); - delete InterruptHook; - delete mem; - break; - } - - memset(KCallback, 0, sizeof(KernelCallback)); - KCallback->Reason = CallbackReason::InterruptReason; - - DriverFile *DrvFile = new DriverFile; - DrvFile->DriverUID = this->DriverUIDs - 1; - DrvFile->Address = (void *)fex; - DrvFile->MemTrk = mem; - DrvFile->InterruptHook[0] = InterruptHook; - Drivers.push_back(DrvFile); - break; - } + return BindInterruptInput(mem, fex); case FexDriverType::FexDriverType_Audio: - { - fixme("Audio driver: %s", fexExtended->Driver.Name); - delete mem; - break; - } + return BindInterruptAudio(mem, fex); default: { warn("Unknown driver type: %d", fexExtended->Driver.Type); delete mem; - break; + return DriverCode::UNKNOWN_DRIVER_TYPE; } } diff --git a/Core/Driver/DriverLoading/BindPCI.cpp b/Core/Driver/DriverLoading/BindPCI.cpp index e747459..f670307 100644 --- a/Core/Driver/DriverLoading/BindPCI.cpp +++ b/Core/Driver/DriverLoading/BindPCI.cpp @@ -14,11 +14,273 @@ namespace Driver { + DriverCode Driver::BindPCIGeneric(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + fixme("Generic driver: %s", fexExtended->Driver.Name); + delete mem; + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindPCIDisplay(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + fixme("Display driver: %s", fexExtended->Driver.Name); + delete mem; + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindPCINetwork(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + KernelCallback *KCallback = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback))); + + DriverInterruptHook *InterruptHook = new DriverInterruptHook(((int)((PCI::PCIHeader0 *)PCIDevice)->InterruptLine) + 32, // x86 + (void *)((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex), + KCallback); + + KCallback->RawPtr = PCIDevice; + KCallback->Reason = CallbackReason::ConfigurationReason; + int CallbackRet = ((int (*)(KernelCallback *))((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex))(KCallback); + if (CallbackRet == DriverReturnCode::NOT_IMPLEMENTED) + { + error("Driver %s is not implemented", fexExtended->Driver.Name); + delete mem; + delete InterruptHook; + return DriverCode::NOT_IMPLEMENTED; + } + else if (CallbackRet == DriverReturnCode::OK) + trace("Device found for driver: %s", fexExtended->Driver.Name); + else + { + error("Driver %s returned error %d", fexExtended->Driver.Name, CallbackRet); + delete mem; + delete InterruptHook; + return DriverCode::DRIVER_RETURNED_ERROR; + } + + memset(KCallback, 0, sizeof(KernelCallback)); + KCallback->Reason = CallbackReason::InterruptReason; + + DriverFile *DrvFile = new DriverFile; + DrvFile->Enabled = true; + DrvFile->DriverUID = this->DriverUIDs - 1; + DrvFile->Address = (void *)fex; + DrvFile->MemTrk = mem; + DrvFile->InterruptHook[0] = InterruptHook; + Drivers.push_back(DrvFile); + return DriverCode::OK; + } + + DriverCode Driver::BindPCIStorage(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + KernelCallback *KCallback = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback))); + + KCallback->RawPtr = PCIDevice; + KCallback->Reason = CallbackReason::ConfigurationReason; + int CallbackRet = ((int (*)(KernelCallback *))((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex))(KCallback); + if (CallbackRet == DriverReturnCode::NOT_IMPLEMENTED) + { + error("Driver %s is not implemented", fexExtended->Driver.Name); + delete mem; + return DriverCode::NOT_IMPLEMENTED; + } + else if (CallbackRet == DriverReturnCode::OK) + trace("Device found for driver: %s", fexExtended->Driver.Name); + else + { + error("Driver %s returned error %d", fexExtended->Driver.Name, CallbackRet); + delete mem; + return DriverCode::DRIVER_RETURNED_ERROR; + } + + DriverFile *DrvFile = new DriverFile; + DrvFile->Enabled = true; + DrvFile->DriverUID = this->DriverUIDs - 1; + DrvFile->Address = (void *)fex; + DrvFile->MemTrk = mem; + DrvFile->InterruptHook[0] = nullptr; + Drivers.push_back(DrvFile); + return DriverCode::OK; + } + + DriverCode Driver::BindPCIFileSystem(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + fixme("Filesystem driver: %s", fexExtended->Driver.Name); + delete mem; + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindPCIInput(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + fixme("Input driver: %s", fexExtended->Driver.Name); + delete mem; + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindPCIAudio(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice) + { + FexExtended *fexExtended = (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); + + if (fexExtended->Driver.OverrideOnConflict) + { + Vector DriversToRemove = Vector(); + foreach (auto Drv in Drivers) + { + FexExtended *fe = ((FexExtended *)((uintptr_t)Drv->Address + EXTENDED_SECTION_ADDRESS)); + if (fe->Driver.OverrideOnConflict) + return DriverCode::DRIVER_CONFLICT; + } + + foreach (auto DrvID in DriversToRemove) + { + if (!this->UnloadDriver(DrvID)) + { + error("Failed to unload conflicting driver %d", DrvID); + return DriverCode::DRIVER_CONFLICT; + } + } + } + + fixme("Audio driver: %s", fexExtended->Driver.Name); + delete mem; + return DriverCode::NOT_IMPLEMENTED; + } + DriverCode Driver::DriverLoadBindPCI(void *DrvExtHdr, uintptr_t DriverAddress, size_t Size, bool IsElf) { UNUSED(IsElf); - bool IsDriverLoaded = false; for (unsigned long Vidx = 0; Vidx < sizeof(((FexExtended *)DrvExtHdr)->Driver.Bind.PCI.VendorID) / sizeof(((FexExtended *)DrvExtHdr)->Driver.Bind.PCI.VendorID[0]); Vidx++) + { for (unsigned long Didx = 0; Didx < sizeof(((FexExtended *)DrvExtHdr)->Driver.Bind.PCI.DeviceID) / sizeof(((FexExtended *)DrvExtHdr)->Driver.Bind.PCI.DeviceID[0]); Didx++) { if (Vidx >= sizeof(((FexExtended *)DrvExtHdr)->Driver.Bind.PCI.VendorID) && Didx >= sizeof(((FexExtended *)DrvExtHdr)->Driver.Bind.PCI.DeviceID)) @@ -55,8 +317,6 @@ namespace Driver } debug("Starting driver %s", fexExtended->Driver.Name); - KernelCallback *KCallback = (KernelCallback *)mem->RequestPages(TO_PAGES(sizeof(KernelCallback))); - debug("Type: %d; IOBase: %#x; MemoryBase: %#x", ((PCI::PCIHeader0 *)PCIDevice)->BAR0 & 1, ((PCI::PCIHeader0 *)PCIDevice)->BAR1 & (~3), @@ -87,111 +347,70 @@ namespace Driver { case FexDriverType::FexDriverType_Generic: { - fixme("Generic driver: %s", fexExtended->Driver.Name); - delete mem; - break; + DriverCode ret = BindPCIGeneric(mem, fex, PCIDevice); + if (ret != DriverCode::OK && + ret != DriverCode::DRIVER_CONFLICT) + continue; + return DriverCode::OK; } case FexDriverType::FexDriverType_Display: { - fixme("Display driver: %s", fexExtended->Driver.Name); - delete mem; - break; + DriverCode ret = BindPCIDisplay(mem, fex, PCIDevice); + if (ret != DriverCode::OK && + ret != DriverCode::DRIVER_CONFLICT) + continue; + return DriverCode::OK; } case FexDriverType::FexDriverType_Network: { - DriverInterruptHook *InterruptHook = new DriverInterruptHook(((int)((PCI::PCIHeader0 *)devices[0])->InterruptLine) + 32, // x86 - (void *)((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex), - KCallback); - - KCallback->RawPtr = PCIDevice; - KCallback->Reason = CallbackReason::ConfigurationReason; - int CallbackRet = ((int (*)(KernelCallback *))((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex))(KCallback); - if (CallbackRet == DriverReturnCode::NOT_IMPLEMENTED) - { - error("Driver %s is not implemented", fexExtended->Driver.Name); - delete mem; - delete InterruptHook; + DriverCode ret = BindPCINetwork(mem, fex, PCIDevice); + if (ret != DriverCode::OK && + ret != DriverCode::DRIVER_CONFLICT) continue; - } - else if (CallbackRet == DriverReturnCode::OK) - trace("Device found for driver: %s", fexExtended->Driver.Name); - else - { - error("Driver %s returned error %d", fexExtended->Driver.Name, CallbackRet); - delete mem; - delete InterruptHook; - continue; - } - - memset(KCallback, 0, sizeof(KernelCallback)); - KCallback->Reason = CallbackReason::InterruptReason; - - DriverFile *DrvFile = new DriverFile; - DrvFile->DriverUID = this->DriverUIDs - 1; - DrvFile->Address = (void *)fex; - DrvFile->InterruptHook[0] = InterruptHook; - Drivers.push_back(DrvFile); - break; + return DriverCode::OK; } case FexDriverType::FexDriverType_Storage: { - KCallback->RawPtr = PCIDevice; - KCallback->Reason = CallbackReason::ConfigurationReason; - int CallbackRet = ((int (*)(KernelCallback *))((uintptr_t)fexExtended->Driver.Callback + (uintptr_t)fex))(KCallback); - if (CallbackRet == DriverReturnCode::NOT_IMPLEMENTED) - { - error("Driver %s is not implemented", fexExtended->Driver.Name); - delete mem; + DriverCode ret = BindPCIStorage(mem, fex, PCIDevice); + if (ret != DriverCode::OK && + ret != DriverCode::DRIVER_CONFLICT) continue; - } - else if (CallbackRet == DriverReturnCode::OK) - trace("Device found for driver: %s", fexExtended->Driver.Name); - else - { - error("Driver %s returned error %d", fexExtended->Driver.Name, CallbackRet); - delete mem; - continue; - } - - DriverFile *DrvFile = new DriverFile; - DrvFile->DriverUID = this->DriverUIDs - 1; - DrvFile->Address = (void *)fex; - DrvFile->InterruptHook[0] = nullptr; - Drivers.push_back(DrvFile); - break; + return DriverCode::OK; } case FexDriverType::FexDriverType_FileSystem: { - fixme("Filesystem driver: %s", fexExtended->Driver.Name); - delete mem; - break; + DriverCode ret = BindPCIFileSystem(mem, fex, PCIDevice); + if (ret != DriverCode::OK && + ret != DriverCode::DRIVER_CONFLICT) + continue; + return DriverCode::OK; } case FexDriverType::FexDriverType_Input: { - fixme("Input driver: %s", fexExtended->Driver.Name); - delete mem; - break; + DriverCode ret = BindPCIInput(mem, fex, PCIDevice); + if (ret != DriverCode::OK && + ret != DriverCode::DRIVER_CONFLICT) + continue; + return DriverCode::OK; } case FexDriverType::FexDriverType_Audio: { - fixme("Audio driver: %s", fexExtended->Driver.Name); - delete mem; - break; + DriverCode ret = BindPCIAudio(mem, fex, PCIDevice); + if (ret != DriverCode::OK && + ret != DriverCode::DRIVER_CONFLICT) + continue; + return DriverCode::OK; } default: { warn("Unknown driver type: %d", fexExtended->Driver.Type); delete mem; - break; + return DriverCode::UNKNOWN_DRIVER_TYPE; } } - IsDriverLoaded = true; } } - - if (IsDriverLoaded) - return DriverCode::OK; - else - return DriverCode::NOT_AVAILABLE; + } + return DriverCode::PCI_DEVICE_NOT_FOUND; } } diff --git a/Core/Driver/DriverLoading/BindProcess.cpp b/Core/Driver/DriverLoading/BindProcess.cpp index 2287bbb..011f4e9 100644 --- a/Core/Driver/DriverLoading/BindProcess.cpp +++ b/Core/Driver/DriverLoading/BindProcess.cpp @@ -14,6 +14,41 @@ namespace Driver { + DriverCode Driver::BindProcessGeneric(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindProcessDisplay(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindProcessNetwork(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindProcessStorage(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindProcessFileSystem(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindProcessInput(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; + } + + DriverCode Driver::BindProcessAudio(Memory::MemMgr *mem, void *fex) + { + return DriverCode::NOT_IMPLEMENTED; + } + DriverCode Driver::DriverLoadBindProcess(void *DrvExtHdr, uintptr_t DriverAddress, size_t Size, bool IsElf) { fixme("Process driver: %s", ((FexExtended *)DrvExtHdr)->Driver.Name); diff --git a/include/driver.hpp b/include/driver.hpp index b9a84a5..f50aaa3 100644 --- a/include/driver.hpp +++ b/include/driver.hpp @@ -3,11 +3,12 @@ #include -#include #include #include +#include #include #include +#include namespace Driver { @@ -22,7 +23,8 @@ namespace Driver NOT_IMPLEMENTED, DRIVER_RETURNED_ERROR, UNKNOWN_DRIVER_TYPE, - PCI_DEVICE_NOT_FOUND + PCI_DEVICE_NOT_FOUND, + DRIVER_CONFLICT }; class DriverInterruptHook : public Interrupts::Handler @@ -46,6 +48,7 @@ namespace Driver struct DriverFile { + bool Enabled; unsigned long DriverUID; void *Address; Memory::MemMgr *MemTrk; @@ -57,11 +60,42 @@ namespace Driver private: Vector Drivers; unsigned long DriverUIDs = 0; - DriverCode CallDriverEntryPoint(void *fex, void *KAPIAddress); + + DriverCode BindPCIGeneric(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice); + DriverCode BindPCIDisplay(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice); + DriverCode BindPCINetwork(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice); + DriverCode BindPCIStorage(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice); + DriverCode BindPCIFileSystem(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice); + DriverCode BindPCIInput(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice); + DriverCode BindPCIAudio(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice); DriverCode DriverLoadBindPCI(void *DrvExtHdr, uintptr_t DriverAddress, size_t Size, bool IsElf = false); + + DriverCode BindInterruptGeneric(Memory::MemMgr *mem, void *fex); + DriverCode BindInterruptDisplay(Memory::MemMgr *mem, void *fex); + DriverCode BindInterruptNetwork(Memory::MemMgr *mem, void *fex); + DriverCode BindInterruptStorage(Memory::MemMgr *mem, void *fex); + DriverCode BindInterruptFileSystem(Memory::MemMgr *mem, void *fex); + DriverCode BindInterruptInput(Memory::MemMgr *mem, void *fex); + DriverCode BindInterruptAudio(Memory::MemMgr *mem, void *fex); DriverCode DriverLoadBindInterrupt(void *DrvExtHdr, uintptr_t DriverAddress, size_t Size, bool IsElf = false); + + DriverCode BindInputGeneric(Memory::MemMgr *mem, void *fex); + DriverCode BindInputDisplay(Memory::MemMgr *mem, void *fex); + DriverCode BindInputNetwork(Memory::MemMgr *mem, void *fex); + DriverCode BindInputStorage(Memory::MemMgr *mem, void *fex); + DriverCode BindInputFileSystem(Memory::MemMgr *mem, void *fex); + DriverCode BindInputInput(Memory::MemMgr *mem, void *fex); + DriverCode BindInputAudio(Memory::MemMgr *mem, void *fex); DriverCode DriverLoadBindInput(void *DrvExtHdr, uintptr_t DriverAddress, size_t Size, bool IsElf = false); + + DriverCode BindProcessGeneric(Memory::MemMgr *mem, void *fex); + DriverCode BindProcessDisplay(Memory::MemMgr *mem, void *fex); + DriverCode BindProcessNetwork(Memory::MemMgr *mem, void *fex); + DriverCode BindProcessStorage(Memory::MemMgr *mem, void *fex); + DriverCode BindProcessFileSystem(Memory::MemMgr *mem, void *fex); + DriverCode BindProcessInput(Memory::MemMgr *mem, void *fex); + DriverCode BindProcessAudio(Memory::MemMgr *mem, void *fex); DriverCode DriverLoadBindProcess(void *DrvExtHdr, uintptr_t DriverAddress, size_t Size, bool IsElf = false); public: