/* 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 #include "../../kernel.h" #include "../../driver.h" // #define DEBUG_API #ifdef DEBUG_API #define dbg_api(Format, ...) function(Format, ##__VA_ARGS__) #else #define dbg_api(Format, ...) #endif using enum PCI::PCICommands; #define VMWARE_MAGIC 0x564D5868 /* hXMV */ #define VMWARE_PORT 0x5658 #define CMD_GETVERSION 0xA namespace Driver { int RegisterFunction(dev_t MajorID, void *Function, __driverRegFunc Type) { dbg_api("%d, %#lx, %d", MajorID, (uintptr_t)Function, Type); std::unordered_map &Drivers = DriverManager->GetDrivers(); auto itr = Drivers.find(MajorID); if (itr == Drivers.end()) return -EINVAL; DriverObject *drv = &itr->second; switch (Type) { case _drf_Entry: drv->Entry = (int (*)())Function; debug("Entry %#lx for %s", (uintptr_t)Function, drv->Path); break; case _drf_Final: drv->Final = (int (*)())Function; debug("Finalize %#lx for %s", (uintptr_t)Function, drv->Path); break; case _drf_Panic: drv->Panic = (int (*)())Function; debug("Panic %#lx for %s", (uintptr_t)Function, drv->Path); break; case _drf_Probe: drv->Probe = (int (*)())Function; debug("Probe %#lx for %s", (uintptr_t)Function, drv->Path); break; default: assert(!"Invalid driver function type"); } return 0; } int GetDriverInfo(dev_t MajorID, const char *Name, const char *Description, const char *Author, const char *Version, const char *License) { dbg_api("%d, %s, %s, %s, %s, %s", MajorID, Name, Description, Author, Version, License); std::unordered_map &Drivers = DriverManager->GetDrivers(); auto itr = Drivers.find(MajorID); if (itr == Drivers.end()) return -EINVAL; DriverObject *drv = &itr->second; strncpy(drv->Name, Name, sizeof(drv->Name)); strncpy(drv->Description, Description, sizeof(drv->Description)); strncpy(drv->Author, Author, sizeof(drv->Author)); strncpy(drv->Version, Version, sizeof(drv->Version)); strncpy(drv->License, License, sizeof(drv->License)); return 0; } /* --------- */ int RegisterInterruptHandler(dev_t MajorID, uint8_t IRQ, void *Handler) { dbg_api("%d, %d, %#lx", MajorID, IRQ, Handler); std::unordered_map &Drivers = DriverManager->GetDrivers(); auto itr = Drivers.find(MajorID); if (itr == Drivers.end()) return -EINVAL; DriverObject *drv = &itr->second; if (drv->InterruptHandlers->contains(IRQ)) return -EEXIST; Interrupts::AddHandler((void (*)(CPU::TrapFrame *))Handler, IRQ); drv->InterruptHandlers->insert(std::pair(IRQ, Handler)); return 0; } int OverrideInterruptHandler(dev_t MajorID, uint8_t IRQ, void *Handler) { dbg_api("%d, %d, %#lx", MajorID, IRQ, Handler); debug("Overriding IRQ %d with %#lx", IRQ, Handler); std::unordered_map &Drivers = DriverManager->GetDrivers(); foreach (auto &var in Drivers) { DriverObject *drv = &var.second; foreach (auto &ih in * drv->InterruptHandlers) { if (ih.first == IRQ) { debug("Removing IRQ %d: %#lx for %s", IRQ, (uintptr_t)ih.second, drv->Path); Interrupts::RemoveHandler((void (*)(CPU::TrapFrame *))ih.second, IRQ); drv->InterruptHandlers->erase(IRQ); break; } } } return RegisterInterruptHandler(MajorID, IRQ, Handler); } int UnregisterInterruptHandler(dev_t MajorID, uint8_t IRQ, void *Handler) { dbg_api("%d, %d, %#lx", MajorID, IRQ, Handler); std::unordered_map &Drivers = DriverManager->GetDrivers(); auto itr = Drivers.find(MajorID); if (itr == Drivers.end()) return -EINVAL; DriverObject *drv = &itr->second; Interrupts::RemoveHandler((void (*)(CPU::TrapFrame *))Handler, IRQ); drv->InterruptHandlers->erase(IRQ); return 0; } int UnregisterAllInterruptHandlers(dev_t MajorID, void *Handler) { dbg_api("%d, %#lx", MajorID, Handler); std::unordered_map &Drivers = DriverManager->GetDrivers(); auto itr = Drivers.find(MajorID); if (itr == Drivers.end()) return -EINVAL; DriverObject *drv = &itr->second; foreach (auto &i in * drv->InterruptHandlers) { Interrupts::RemoveHandler((void (*)(CPU::TrapFrame *))Handler, i.first); debug("Removed IRQ %d: %#lx for %s", i.first, (uintptr_t)Handler, drv->Path); } drv->InterruptHandlers->clear(); return 0; } /* --------- */ dev_t RegisterInputDevice(dev_t MajorID, DeviceDriverType Type) { dbg_api("%d, %d", MajorID, Type); switch (Type) { case ddt_Keyboard: return DriverManager->InputKeyboardDev->Register(MajorID); case ddt_Mouse: return DriverManager->InputMouseDev->Register(MajorID); /* ... */ default: assert(!"Invalid input device type"); } } int UnregisterInputDevice(dev_t MajorID, dev_t MinorID, DeviceDriverType Type) { dbg_api("%d, %d, %d", MajorID, MinorID, Type); switch (Type) { case ddt_Keyboard: return DriverManager->InputKeyboardDev->Unregister(MajorID, MinorID); case ddt_Mouse: return DriverManager->InputMouseDev->Unregister(MajorID, MinorID); /* ... */ default: assert(!"Invalid input device type"); } } int ReportKeyboardEvent(dev_t MajorID, dev_t MinorID, uint8_t ScanCode) { dbg_api("%d, %d, %d", MajorID, MinorID, ScanCode); return DriverManager->InputKeyboardDev->ReportKeyEvent(MajorID, MinorID, ScanCode); } int ReportRelativeMouseEvent(dev_t MajorID, dev_t MinorID, __MouseButtons Button, int X, int Y, int8_t Z) { dbg_api("%d, %d, %d, %d, %d, %d", MajorID, MinorID, Button, X, Y, Z); return DriverManager->InputMouseDev->ReportMouseEvent(MajorID, MinorID, Button.LeftButton, Button.RightButton, Button.MiddleButton, Button.Button4, Button.Button5, Button.Button6, Button.Button7, Button.Button8, X, Y, Z, true); } int ReportAbsoluteMouseEvent(dev_t MajorID, dev_t MinorID, __MouseButtons Button, uintptr_t X, uintptr_t Y, int8_t Z) { dbg_api("%d, %d, %d, %d, %d, %d", MajorID, MinorID, Button, X, Y, Z); return DriverManager->InputMouseDev->ReportMouseEvent(MajorID, MinorID, Button.LeftButton, Button.RightButton, Button.MiddleButton, Button.Button4, Button.Button5, Button.Button6, Button.Button7, Button.Button8, X, Y, Z, false); } /* --------- */ dev_t RegisterBlockDevice(dev_t MajorID, DeviceDriverType Type, void *Open, void *Close, void *Read, void *Write, void *Ioctl) { dbg_api("%d, %d, %#lx, %#lx, %#lx, %#lx, %#lx", MajorID, Type, Open, Close, Read, Write, Ioctl); switch (Type) { case ddt_SATA: { dev_t ret = DriverManager->BlockSATADev->Register(MajorID); DriverManager->BlockSATADev->NewBlock(MajorID, ret, (SlaveDeviceFile::drvOpen_t)Open, (SlaveDeviceFile::drvClose_t)Close, (SlaveDeviceFile::drvRead_t)Read, (SlaveDeviceFile::drvWrite_t)Write, (SlaveDeviceFile::drvIoctl_t)Ioctl); return ret; } case ddt_ATA: { dev_t ret = DriverManager->BlockHDDev->Register(MajorID); DriverManager->BlockHDDev->NewBlock(MajorID, ret, (SlaveDeviceFile::drvOpen_t)Open, (SlaveDeviceFile::drvClose_t)Close, (SlaveDeviceFile::drvRead_t)Read, (SlaveDeviceFile::drvWrite_t)Write, (SlaveDeviceFile::drvIoctl_t)Ioctl); return ret; } case ddt_NVMe: { dev_t ret = DriverManager->BlockNVMeDev->Register(MajorID); DriverManager->BlockNVMeDev->NewBlock(MajorID, ret, (SlaveDeviceFile::drvOpen_t)Open, (SlaveDeviceFile::drvClose_t)Close, (SlaveDeviceFile::drvRead_t)Read, (SlaveDeviceFile::drvWrite_t)Write, (SlaveDeviceFile::drvIoctl_t)Ioctl); return ret; } /* ... */ default: assert(!"Invalid storage device type"); } } int UnregisterBlockDevice(dev_t MajorID, dev_t MinorID, DeviceDriverType Type) { dbg_api("%d, %d, %d", MajorID, MinorID, Type); switch (Type) { case ddt_SATA: return DriverManager->BlockSATADev->Unregister(MajorID, MinorID); case ddt_ATA: return DriverManager->BlockHDDev->Unregister(MajorID, MinorID); case ddt_NVMe: return DriverManager->BlockNVMeDev->Unregister(MajorID, MinorID); /* ... */ default: assert(!"Invalid storage device type"); } } /* --------- */ dev_t RegisterAudioDevice(dev_t MajorID, DeviceDriverType Type, void *Open, void *Close, void *Read, void *Write, void *Ioctl) { dbg_api("%d, %d, %#lx, %#lx, %#lx, %#lx, %#lx", MajorID, Type, Open, Close, Read, Write, Ioctl); switch (Type) { case ddt_Audio: { dev_t ret = DriverManager->AudioDev->Register(MajorID); DriverManager->AudioDev->NewAudio(MajorID, ret, (SlaveDeviceFile::drvOpen_t)Open, (SlaveDeviceFile::drvClose_t)Close, (SlaveDeviceFile::drvRead_t)Read, (SlaveDeviceFile::drvWrite_t)Write, (SlaveDeviceFile::drvIoctl_t)Ioctl); return ret; } /* ... */ default: assert(!"Invalid audio device type"); } } int UnregisterAudioDevice(dev_t MajorID, dev_t MinorID, DeviceDriverType Type) { dbg_api("%d, %d, %d", MajorID, MinorID, Type); switch (Type) { case ddt_Audio: return DriverManager->AudioDev->Unregister(MajorID, MinorID); /* ... */ default: assert(!"Invalid audio device type"); } } /* --------- */ dev_t RegisterNetDevice(dev_t MajorID, DeviceDriverType Type, void *Open, void *Close, void *Read, void *Write, void *Ioctl) { dbg_api("%d, %d, %#lx, %#lx, %#lx, %#lx, %#lx", MajorID, Type, Open, Close, Read, Write, Ioctl); switch (Type) { case ddt_Network: { dev_t ret = DriverManager->NetDev->Register(MajorID); DriverManager->NetDev->NewNet(MajorID, ret, (SlaveDeviceFile::drvOpen_t)Open, (SlaveDeviceFile::drvClose_t)Close, (SlaveDeviceFile::drvRead_t)Read, (SlaveDeviceFile::drvWrite_t)Write, (SlaveDeviceFile::drvIoctl_t)Ioctl); return ret; } /* ... */ default: assert(!"Invalid audio device type"); } } int UnregisterNetDevice(dev_t MajorID, dev_t MinorID, DeviceDriverType Type) { dbg_api("%d, %d, %d", MajorID, MinorID, Type); switch (Type) { case ddt_Network: return DriverManager->NetDev->Unregister(MajorID, MinorID); /* ... */ default: assert(!"Invalid audio device type"); } } int ReportNetworkPacket(dev_t MajorID, dev_t MinorID, void *Buffer, size_t Size) { dbg_api("%d, %d, %#lx, %d", MajorID, MinorID, Buffer, Size); return DriverManager->NetDev->ReportNetworkPacket(MajorID, MinorID, Buffer, Size); } /* --------- */ void d_KPrint(dev_t MajorID, const char *Format, va_list args) { dbg_api("%d %s, %#lx", MajorID, Format, args); _KPrint(Format, args); } void KernelLog(dev_t MajorID, const char *Format, va_list args) { dbg_api("%d, %s, %#lx", MajorID, Format, args); fctprintf(uart_wrapper, nullptr, "DRVER| %ld: ", MajorID); vfctprintf(uart_wrapper, nullptr, Format, args); uart_wrapper('\n', nullptr); } /* --------- */ void *RequestPages(dev_t MajorID, size_t Pages) { dbg_api("%d, %d", MajorID, Pages); std::unordered_map &Drivers = DriverManager->GetDrivers(); auto itr = Drivers.find(MajorID); assert(itr != Drivers.end()); return itr->second.vma->RequestPages(Pages); } void FreePages(dev_t MajorID, void *Pointer, size_t Pages) { dbg_api("%d, %#lx, %d", MajorID, Pointer, Pages); std::unordered_map &Drivers = DriverManager->GetDrivers(); auto itr = Drivers.find(MajorID); assert(itr != Drivers.end()); itr->second.vma->FreePages(Pointer, Pages); } /* --------- */ void AppendMapFlag(dev_t MajorID, void *Address, PageMapFlags Flag) { dbg_api("%d, %#lx, %d", MajorID, Address, Flag); Memory::Virtual vmm(KernelPageTable); vmm.GetPTE(Address)->raw |= Flag; } void RemoveMapFlag(dev_t MajorID, void *Address, PageMapFlags Flag) { dbg_api("%d, %#lx, %d", MajorID, Address, Flag); Memory::Virtual vmm(KernelPageTable); vmm.GetPTE(Address)->raw &= ~Flag; } void MapPages(dev_t MajorID, void *PhysicalAddress, void *VirtualAddress, size_t Pages, uint32_t Flags) { dbg_api("%d, %#lx, %#lx, %d, %d", MajorID, PhysicalAddress, VirtualAddress, Pages, Flags); Memory::Virtual vmm(KernelPageTable); vmm.Map(VirtualAddress, PhysicalAddress, Pages, Flags); } void UnmapPages(dev_t MajorID, void *VirtualAddress, size_t Pages) { dbg_api("%d, %#lx, %d", MajorID, VirtualAddress, Pages); Memory::Virtual vmm(KernelPageTable); vmm.Unmap(VirtualAddress, Pages); } /* --------- */ pid_t CreateKernelProcess(dev_t MajorID, const char *Name) { dbg_api("%d, %s", MajorID, Name); Tasking::PCB *pcb = TaskManager->CreateProcess(nullptr, Name, Tasking::System, nullptr, true, 0, 0); return pcb->ID; } pid_t CreateKernelThread(dev_t MajorID, pid_t pId, const char *Name, void *EntryPoint, void *Argument) { dbg_api("%d, %d, %s, %#lx, %#lx", MajorID, pId, Name, EntryPoint, Argument); Tasking::PCB *parent = TaskManager->GetProcessByID(pId); if (!parent) return -EINVAL; CriticalSection cs; Tasking::TCB *tcb = TaskManager->CreateThread(parent, (Tasking::IP)EntryPoint); if (Argument) tcb->SYSV_ABI_Call((uintptr_t)Argument); tcb->Rename(Name); return tcb->ID; } int KillProcess(dev_t MajorID, pid_t pId, int ExitCode) { dbg_api("%d, %d, %d", MajorID, pId, ExitCode); Tasking::PCB *pcb = TaskManager->GetProcessByID(pId); if (!pcb) return -EINVAL; TaskManager->KillProcess(pcb, (Tasking::KillCode)ExitCode); return 0; } int KillThread(dev_t MajorID, pid_t tId, int ExitCode) { dbg_api("%d, %d, %d", MajorID, tId, ExitCode); Tasking::TCB *tcb = TaskManager->GetThreadByID(tId); if (!tcb) return -EINVAL; TaskManager->KillThread(tcb, (Tasking::KillCode)ExitCode); return 0; } void Yield(dev_t MajorID) { dbg_api("%d", MajorID); TaskManager->Yield(); } void Sleep(dev_t MajorID, uint64_t Milliseconds) { dbg_api("%d, %d", MajorID, Milliseconds); TaskManager->Sleep(Milliseconds); } /* --------- */ __PCIArray *GetPCIDevices(dev_t MajorID, uint16_t _Vendors[], uint16_t _Devices[]) { dbg_api("%d, %#lx, %#lx", MajorID, _Vendors, _Devices); std::unordered_map &Drivers = DriverManager->GetDrivers(); auto itr = Drivers.find(MajorID); if (itr == Drivers.end()) return nullptr; std::list VendorIDs; for (int i = 0; _Vendors[i] != 0x0; i++) VendorIDs.push_back(_Vendors[i]); std::list DeviceIDs; for (int i = 0; _Devices[i] != 0x0; i++) DeviceIDs.push_back(_Devices[i]); std::list Devices = PCIManager->FindPCIDevice(VendorIDs, DeviceIDs); if (Devices.empty()) return nullptr; Memory::VirtualMemoryArea *vma = itr->second.vma; __PCIArray *head = nullptr; __PCIArray *array = nullptr; foreach (auto &dev in Devices) { /* TODO: optimize memory allocation */ PCI::PCIDevice *dptr = (PCI::PCIDevice *)vma->RequestPages(TO_PAGES(sizeof(PCI::PCIDevice))); memcpy(dptr, &dev, sizeof(PCI::PCIDevice)); __PCIArray *newArray = (__PCIArray *)vma->RequestPages(TO_PAGES(sizeof(__PCIArray))); if (unlikely(head == nullptr)) { head = newArray; array = head; } else { array->Next = newArray; array = newArray; } array->Device = dptr; array->Next = nullptr; debug("Found %02x.%02x.%02x: %04x:%04x", dev.Bus, dev.Device, dev.Function, dev.Header->VendorID, dev.Header->DeviceID); } return head; } void InitializePCI(dev_t MajorID, void *_Header) { dbg_api("%d, %#lx", MajorID, _Header); PCI::PCIDeviceHeader *Header = (PCI::PCIDeviceHeader *)_Header; debug("Header Type: %d", Header->HeaderType); switch (Header->HeaderType) { case 128: warn("Unknown header type %d! Guessing PCI Header 0", Header->HeaderType); [[fallthrough]]; case 0: /* PCI Header 0 */ { PCI::PCIHeader0 *hdr0 = (PCI::PCIHeader0 *)Header; uint32_t BAR[6]; size_t BARsSize[6]; BAR[0] = hdr0->BAR0; BAR[1] = hdr0->BAR1; BAR[2] = hdr0->BAR2; BAR[3] = hdr0->BAR3; BAR[4] = hdr0->BAR4; BAR[5] = hdr0->BAR5; debug("Type: %d; IOBase: %#lx; MemoryBase: %#lx", BAR[0] & 1, BAR[1] & (~3), BAR[0] & (~15)); /* BARs Size */ for (short i = 0; i < 6; i++) { if (BAR[i] == 0) continue; size_t size; if ((BAR[i] & 1) == 0) /* Memory Base */ { hdr0->BAR0 = 0xFFFFFFFF; size = hdr0->BAR0; hdr0->BAR0 = BAR[i]; BARsSize[i] = size & (~15); BARsSize[i] = ~BARsSize[i] + 1; BARsSize[i] = BARsSize[i] & 0xFFFFFFFF; debug("BAR%d %#lx size: %d", i, BAR[i], BARsSize[i]); } else if ((BAR[i] & 1) == 1) /* I/O Base */ { hdr0->BAR1 = 0xFFFFFFFF; size = hdr0->BAR1; hdr0->BAR1 = BAR[i]; BARsSize[i] = size & (~3); BARsSize[i] = ~BARsSize[i] + 1; BARsSize[i] = BARsSize[i] & 0xFFFF; debug("BAR%d %#lx size: %d", i, BAR[i], BARsSize[i]); } } Memory::Virtual vmm(KernelPageTable); /* Mapping the BARs */ for (short i = 0; i < 6; i++) { if (BAR[i] == 0) continue; if ((BAR[i] & 1) == 0) /* Memory Base */ { uintptr_t BARBase = BAR[i] & (~15); size_t BARSize = BARsSize[i]; debug("Mapping BAR%d %#lx-%#lx", i, BARBase, BARBase + BARSize); if (BARSize == 0) { warn("BAR%d size is zero!", i); BARSize++; } vmm.Map((void *)BARBase, (void *)BARBase, BARSize, Memory::RW | Memory::PWT | Memory::PCD); } else if ((BAR[i] & 1) == 1) /* I/O Base */ { uintptr_t BARBase = BAR[i] & (~3); size_t BARSize = BARsSize[i]; debug("Mapping BAR%d %#x-%#x", i, BARBase, BARBase + BARSize); if (BARSize == 0) { warn("BAR%d size is zero!", i); BARSize++; } vmm.Map((void *)BARBase, (void *)BARBase, BARSize, Memory::RW | Memory::PWT | Memory::PCD); } } break; } case 1: /* PCI Header 1 (PCI-to-PCI Bridge) */ { fixme("PCI Header 1 (PCI-to-PCI Bridge) not implemented yet"); break; } case 2: /* PCI Header 2 (PCI-to-CardBus Bridge) */ { fixme("PCI Header 2 (PCI-to-CardBus Bridge) not implemented yet"); break; } default: { error("Unknown header type %d", Header->HeaderType); break; } } Header->Command |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; Header->Command &= ~PCI_COMMAND_INTX_DISABLE; } uint32_t GetBAR(dev_t MajorID, uint8_t i, void *_Header) { dbg_api("%d, %d, %#lx", MajorID, i, _Header); PCI::PCIDeviceHeader *Header = (PCI::PCIDeviceHeader *)_Header; switch (Header->HeaderType) { case 128: warn("Unknown header type %d! Guessing PCI Header 0", Header->HeaderType); [[fallthrough]]; case 0: /* PCI Header 0 */ { PCI::PCIHeader0 *hdr0 = (PCI::PCIHeader0 *)Header; switch (i) { case 0: return hdr0->BAR0; case 1: return hdr0->BAR1; case 2: return hdr0->BAR2; case 3: return hdr0->BAR3; case 4: return hdr0->BAR4; case 5: return hdr0->BAR5; default: assert(!"Invalid BAR index"); } } case 1: /* PCI Header 1 (PCI-to-PCI Bridge) */ { PCI::PCIHeader1 *hdr1 = (PCI::PCIHeader1 *)Header; switch (i) { case 0: return hdr1->BAR0; case 1: return hdr1->BAR1; default: assert(!"Invalid BAR index"); } } case 2: /* PCI Header 2 (PCI-to-CardBus Bridge) */ { assert(!"PCI-to-CardBus Bridge not supported"); } default: assert(!"Invalid PCI header type"); } } /* --------- */ void *api__memcpy(dev_t MajorID, void *Destination, const void *Source, size_t Length) { dbg_api("%d, %#lx, %#lx, %d", MajorID, Destination, Source, Length); return memcpy(Destination, Source, Length); } void *api__memset(dev_t MajorID, void *Destination, int Value, size_t Length) { dbg_api("%d, %#lx, %d, %d", MajorID, Destination, Value, Length); return memset(Destination, Value, Length); } void *api__memmove(dev_t MajorID, void *Destination, const void *Source, size_t Length) { dbg_api("%d, %#lx, %#lx, %d", MajorID, Destination, Source, Length); return memmove(Destination, Source, Length); } int api__memcmp(dev_t MajorID, const void *Left, const void *Right, size_t Length) { dbg_api("%d, %#lx, %#lx, %d", MajorID, Left, Right, Length); return memcmp(Left, Right, Length); } size_t api__strlen(dev_t MajorID, const char *String) { dbg_api("%d, %s", MajorID, String); return strlen(String); } char *api__strcpy(dev_t MajorID, char *Destination, const char *Source) { dbg_api("%d, %#lx, %s", MajorID, Destination, Source); return strcpy(Destination, Source); } char *api__strcat(dev_t MajorID, char *Destination, const char *Source) { dbg_api("%d, %#lx, %s", MajorID, Destination, Source); return strcat(Destination, Source); } int api__strcmp(dev_t MajorID, const char *Left, const char *Right) { dbg_api("%d, %s, %s", MajorID, Left, Right); return strcmp(Left, Right); } int api__strncmp(dev_t MajorID, const char *Left, const char *Right, size_t Length) { dbg_api("%d, %s, %s, %d", MajorID, Left, Right, Length); return strncmp(Left, Right, Length); } char *api__strchr(dev_t MajorID, const char *String, int Character) { dbg_api("%d, %s, %d", MajorID, String, Character); return strchr(String, Character); } char *api__strrchr(dev_t MajorID, const char *String, int Character) { dbg_api("%d, %s, %d", MajorID, String, Character); stub; return nullptr; // return strrchr(String, Character); } char *api__strstr(dev_t MajorID, const char *Haystack, const char *Needle) { dbg_api("%d, %s, %s", MajorID, Haystack, Needle); return strstr(Haystack, Needle); } /* --------- */ void PopulateDriverAPI(void *API) { __driverAPI *api = (__driverAPI *)API; api->RegisterFunction = RegisterFunction; api->GetDriverInfo = GetDriverInfo; api->RegisterInterruptHandler = RegisterInterruptHandler; api->OverrideInterruptHandler = OverrideInterruptHandler; api->UnregisterInterruptHandler = UnregisterInterruptHandler; api->UnregisterAllInterruptHandlers = UnregisterAllInterruptHandlers; api->RegisterInputDevice = RegisterInputDevice; api->UnregisterInputDevice = UnregisterInputDevice; api->ReportKeyboardEvent = ReportKeyboardEvent; api->ReportRelativeMouseEvent = ReportRelativeMouseEvent; api->ReportAbsoluteMouseEvent = ReportAbsoluteMouseEvent; api->RegisterBlockDevice = RegisterBlockDevice; api->UnregisterBlockDevice = UnregisterBlockDevice; api->RegisterAudioDevice = RegisterAudioDevice; api->UnregisterAudioDevice = UnregisterAudioDevice; api->RegisterNetDevice = RegisterNetDevice; api->UnregisterNetDevice = UnregisterNetDevice; api->ReportNetworkPacket = ReportNetworkPacket; api->KPrint = d_KPrint; api->KernelLog = KernelLog; api->RequestPages = RequestPages; api->FreePages = FreePages; api->AppendMapFlag = AppendMapFlag; api->RemoveMapFlag = RemoveMapFlag; api->MapPages = MapPages; api->UnmapPages = UnmapPages; api->CreateKernelProcess = CreateKernelProcess; api->CreateKernelThread = CreateKernelThread; api->KillProcess = KillProcess; api->KillThread = KillThread; api->Yield = Yield; api->Sleep = Sleep; api->GetPCIDevices = GetPCIDevices; api->InitializePCI = InitializePCI; api->GetBAR = GetBAR; api->memcpy = api__memcpy; api->memset = api__memset; api->memmove = api__memmove; api->memcmp = api__memcmp; api->strlen = api__strlen; api->strcpy = api__strcpy; api->strcat = api__strcat; api->strcmp = api__strcmp; api->strncmp = api__strncmp; api->strchr = api__strchr; api->strrchr = api__strrchr; api->strstr = api__strstr; } }