/* This file is part of Fennix Kernel. Fennix Kernel is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix Kernel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix Kernel. If not, see . */ #include "../api.hpp" #include #include #include #include #include #include #include #include "../../../kernel.h" #include "../../../mapi.hpp" #include "../../../Fex.hpp" namespace Module { ModuleCode Module::ModuleLoadBindInterrupt(uintptr_t ModuleAddress, size_t Size, bool IsBuiltIn) { Memory::VirtualMemoryArea *vma = new Memory::VirtualMemoryArea(nullptr); BuiltInModuleInfo *bidi = (BuiltInModuleInfo *)ModuleAddress; Fex *fex = nullptr; if (!IsBuiltIn) { fex = (Fex *)vma->RequestPages(TO_PAGES(Size + 1)); memcpy(fex, (void *)ModuleAddress, Size); debug("Module allocated at %#lx-%#lx", fex, (uintptr_t)fex + Size); } else fex = (Fex *)bidi->EntryPoint; ModuleCode ret = CallModuleEntryPoint(fex, IsBuiltIn); if (ret != ModuleCode::OK) { delete vma; return ret; } if (IsBuiltIn) fex = 0x0; /* Addresses are absolute if built-in. */ FexExtended *fexE = IsBuiltIn ? (FexExtended *)bidi->ExtendedHeader : (FexExtended *)((uintptr_t)fex + EXTENDED_SECTION_ADDRESS); debug("Starting driver %s", fexE->Module.Name); switch (fexE->Module.Type) { case FexModuleType::FexModuleType_Generic: case FexModuleType::FexModuleType_Display: case FexModuleType::FexModuleType_Network: case FexModuleType::FexModuleType_Storage: case FexModuleType::FexModuleType_FileSystem: case FexModuleType::FexModuleType_Input: case FexModuleType::FexModuleType_Audio: { FexExtended *DriverExtendedHeader = (FexExtended *)vma->RequestPages(TO_PAGES(sizeof(FexExtended) + 1)); memcpy(DriverExtendedHeader, fexE, sizeof(FexExtended)); ModuleFile DrvFile = { .Enabled = true, .BuiltIn = IsBuiltIn, .modUniqueID = this->modUIDs - 1, .Address = (void *)fex, .ExtendedHeaderAddress = (void *)DriverExtendedHeader, .InterruptCallback = (void *)((uintptr_t)fex + (uintptr_t)fexE->Module.InterruptCallback), .vma = vma, }; if (fexE->Module.InterruptCallback) { for (uint16_t i = 0; i < sizeof(fexE->Module.Bind.Interrupt.Vector) / sizeof(fexE->Module.Bind.Interrupt.Vector[0]); i++) { if (fexE->Module.Bind.Interrupt.Vector[i] == 0) break; DrvFile.InterruptHook[i] = new ModuleInterruptHook(fexE->Module.Bind.Interrupt.Vector[i], DrvFile); } } KernelCallback KCallback{}; KCallback.RawPtr = nullptr; KCallback.Reason = CallbackReason::ConfigurationReason; ModuleCode CallbackRet = ((ModuleCode(*)(KernelCallback *))((uintptr_t)fexE->Module.Callback + (uintptr_t)fex))(&KCallback); if (CallbackRet != ModuleCode::OK) { error("Module %s returned error %d", fexE->Module.Name, CallbackRet); delete vma; return CallbackRet; } Modules.push_back(DrvFile); return ModuleCode::OK; } default: { warn("Unknown driver type: %d", fexE->Module.Type); delete vma; return ModuleCode::UNKNOWN_MODULE_TYPE; } } } }