/* 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 #include #include "../../kernel.h" #include "../../Fex.hpp" #include "api.hpp" // show debug messages // #define DEBUG_DRIVER_API 1 #ifdef DEBUG_DRIVER_API #define drvdbg(m, ...) debug(m, ##__VA_ARGS__) #else #define drvdbg(m, ...) #endif NewLock(DriverDisplayPrintLock); void DriverDebugPrint(char *String, __UINT64_TYPE__ DriverUID) { trace("[%ld] %s", DriverUID, String); } void DriverDisplayPrint(char *String) { SmartLock(DriverDisplayPrintLock); for (__UINT64_TYPE__ i = 0; i < strlen(String); i++) Display->Print(String[i], 0, true); } void *RequestPage(__UINT64_TYPE__ Size) { void *ret = KernelAllocator.RequestPages(size_t(Size + 1)); drvdbg("Allocated %ld pages (%#lx-%#lx)", Size, (__UINT64_TYPE__)ret, (__UINT64_TYPE__)ret + FROM_PAGES(Size)); return ret; } void FreePage(void *Page, __UINT64_TYPE__ Size) { drvdbg("Freeing %ld pages (%#lx-%#lx)", Size, (__UINT64_TYPE__)Page, (__UINT64_TYPE__)Page + FROM_PAGES(Size)); KernelAllocator.FreePages(Page, size_t(Size + 1)); } void MapMemory(void *VirtualAddress, void *PhysicalAddress, __UINT64_TYPE__ Flags) { SmartLock(DriverDisplayPrintLock); drvdbg("Mapping %#lx to %#lx with flags %#lx...", (__UINT64_TYPE__)VirtualAddress, (__UINT64_TYPE__)PhysicalAddress, Flags); Memory::Virtual(KernelPageTable).Map(VirtualAddress, PhysicalAddress, Flags); } void UnmapMemory(void *VirtualAddress) { SmartLock(DriverDisplayPrintLock); drvdbg("Unmapping %#lx...", (__UINT64_TYPE__)VirtualAddress); Memory::Virtual(KernelPageTable).Unmap(VirtualAddress); } void *Drivermemcpy(void *Destination, void *Source, __UINT64_TYPE__ Size) { SmartLock(DriverDisplayPrintLock); drvdbg("Copying %ld bytes from %#lx-%#lx to %#lx-%#lx...", Size, (__UINT64_TYPE__)Source, (__UINT64_TYPE__)Source + Size, (__UINT64_TYPE__)Destination, (__UINT64_TYPE__)Destination + Size); return memcpy(Destination, Source, size_t(Size)); } void *Drivermemset(void *Destination, int Value, __UINT64_TYPE__ Size) { SmartLock(DriverDisplayPrintLock); drvdbg("Setting value %#x at %#lx-%#lx (%ld bytes)...", Value, (__UINT64_TYPE__)Destination, (__UINT64_TYPE__)Destination + Size, Size); return memset(Destination, Value, size_t(Size)); } void DriverNetSend(__UINT32_TYPE__ DriverID, __UINT8_TYPE__ *Data, __UINT16_TYPE__ Size) { // This is useless I guess... if (NIManager) NIManager->DrvSend(DriverID, Data, Size); } void DriverNetReceive(__UINT32_TYPE__ DriverID, __UINT8_TYPE__ *Data, __UINT16_TYPE__ Size) { if (NIManager) NIManager->DrvReceive(DriverID, Data, Size); } void DriverAHCIDiskRead(__UINT32_TYPE__ DriverID, __UINT64_TYPE__ Sector, __UINT8_TYPE__ *Data, __UINT32_TYPE__ SectorCount, __UINT8_TYPE__ Port) { DumpData("DriverDiskRead", Data, SectorCount * 512); UNUSED(DriverID); UNUSED(Sector); UNUSED(Port); } void DriverAHCIDiskWrite(__UINT32_TYPE__ DriverID, __UINT64_TYPE__ Sector, __UINT8_TYPE__ *Data, __UINT32_TYPE__ SectorCount, __UINT8_TYPE__ Port) { DumpData("DriverDiskWrite", Data, SectorCount * 512); UNUSED(DriverID); UNUSED(Sector); UNUSED(Port); } char *DriverPCIGetDeviceName(__UINT32_TYPE__ VendorID, __UINT32_TYPE__ DeviceID) { UNUSED(VendorID); UNUSED(DeviceID); return (char *)"Unknown"; } __UINT32_TYPE__ DriverGetWidth() { /* TODO: We won't rely only on display buffers, what about graphics drivers and changing resolutions? */ return Display->GetBuffer(0)->Width; } __UINT32_TYPE__ DriverGetHeight() { /* TODO: We won't rely only on display buffers, what about graphics drivers and changing resolutions? */ return Display->GetBuffer(0)->Height; } void DriverSleep(__UINT64_TYPE__ Milliseconds) { SmartLock(DriverDisplayPrintLock); drvdbg("Sleeping for %ld milliseconds...", Milliseconds); if (TaskManager) TaskManager->Sleep(Milliseconds); else TimeManager->Sleep(size_t(Milliseconds), Time::Units::Milliseconds); } int Driversprintf(char *Buffer, const char *Format, ...) { va_list args; va_start(args, Format); int ret = vsprintf(Buffer, Format, args); va_end(args); return ret; } KernelAPI KernelAPITemplate = { .Version = { .Major = 0, .Minor = 0, .Patch = 1}, .Info = { .Offset = 0, .DriverUID = 0, .KernelDebug = false, }, .Memory = { .PageSize = PAGE_SIZE, .RequestPage = RequestPage, .FreePage = FreePage, .Map = MapMemory, .Unmap = UnmapMemory, }, .PCI = { .GetDeviceName = DriverPCIGetDeviceName, }, .Util = { .DebugPrint = DriverDebugPrint, .DisplayPrint = DriverDisplayPrint, .memcpy = Drivermemcpy, .memset = Drivermemset, .Sleep = DriverSleep, .sprintf = Driversprintf, }, .Command = { .Network = { .SendPacket = DriverNetSend, .ReceivePacket = DriverNetReceive, }, .Disk = { .AHCI = { .ReadSector = DriverAHCIDiskRead, .WriteSector = DriverAHCIDiskWrite, }, }, }, .Display = { .GetWidth = DriverGetWidth, .GetHeight = DriverGetHeight, }, };