mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-25 22:14:37 +00:00
231 lines
5.6 KiB
C++
231 lines
5.6 KiB
C++
/*
|
|
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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <driver.hpp>
|
|
|
|
#include <dumper.hpp>
|
|
#include <lock.hpp>
|
|
|
|
#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,
|
|
},
|
|
};
|