Fix driver implementation

This commit is contained in:
EnderIce2
2024-07-07 03:14:54 +03:00
parent 3e5177d375
commit 51ea074b60
29 changed files with 3069 additions and 1510 deletions

View File

@ -20,16 +20,21 @@
#include <types.h>
#include <interface/driver.h>
#include <interface/input.h>
#include <filesystem.hpp>
#include <unordered_map>
#include <memory.hpp>
#include <ints.hpp>
#include <lock.hpp>
#include <task.hpp>
#include <ring.hpp>
#include <debug.h>
#include <cpu.hpp>
#include <pci.hpp>
#include <vector>
#include <bitset>
#include <elf.h>
#include <io.h>
#include <list>
@ -38,20 +43,32 @@ namespace Driver
char GetScanCode(uint8_t ScanCode, bool Upper);
bool IsValidChar(uint8_t ScanCode);
struct DriverHandlers
{
const InodeOperations *Ops = nullptr;
struct Inode *Node = nullptr;
RingBuffer<InputReport> *InputReports;
};
struct DriverObject
{
uintptr_t BaseAddress = 0;
uintptr_t EntryPoint = 0;
Memory::VirtualMemoryArea *vma = nullptr;
Memory::VirtualMemoryArea *vma;
/* Path has the same pointer as in the Node */
std::string Path;
std::unordered_map<uint8_t, void *> *InterruptHandlers;
std::unordered_map<dev_t, DriverHandlers> *DeviceOperations;
dev_t ID = 0;
char Name[32] = {'\0'};
char Description[64] = {'\0'};
char Author[32] = {'\0'};
char Version[16] = {'\0'};
struct
{
int Major, Minor, Patch;
} Version = {0, 0, 0};
char License[32] = {'\0'};
bool Initialized = false;
int ErrorCode = 0;
@ -67,27 +84,81 @@ namespace Driver
private:
NewLock(ModuleInitLock);
std::unordered_map<dev_t, DriverObject> Drivers;
dev_t DriverIDCounter = 0;
int LoadDriverFile(uintptr_t &EntryPoint,
uintptr_t &BaseAddress,
Memory::VirtualMemoryArea *dVma,
FileNode *rDrv);
/**
* 0 - generic null/zero/random/etc devices
* 1 - input/... devices
*/
dev_t DriverIDCounter = 2;
FileNode *devNode = nullptr;
FileNode *devInputNode = nullptr;
int LoadDriverFile(DriverObject &Drv, FileNode *File);
void InitializeDaemonFS();
dev_t RegisterInputDevice(std::unordered_map<dev_t, DriverHandlers> *, dev_t, size_t, const InodeOperations *);
dev_t RegisterBlockDevice(std::unordered_map<dev_t, DriverHandlers> *, dev_t, size_t, const InodeOperations *);
public:
RingBuffer<KeyboardReport> GlobalKeyboardInputReports;
RingBuffer<MouseReport> GlobalMouseInputReports;
struct DeviceInode
{
struct Inode Node;
FileNode *Parent;
Inode *ParentInode;
std::string Name;
std::vector<DeviceInode *> Children;
};
std::unordered_map<dev_t, DriverObject> &
GetDrivers() { return Drivers; }
void Daemon();
void PreloadDrivers();
void LoadAllDrivers();
void UnloadAllDrivers();
void Panic();
/** Prefixes:
* - dsk (any disk device)
* - dsk0p0 (disk 0, partition 0)
* - blk (block device)
* - eth (Ethernet device)
* - wlan (Wireless LAN device)
* - lo (Loopback device)
* - kb (Keyboard device)
* - ms (Mouse device)
* - js (Joystick device)
* - tp (Touchpad device)
* - tc (Touchscreen device)
* - cam (Camera device)
* - spk (Speaker device)
* - mic (Microphone device)
* - snd (Sound device)
* - tty (Serial device)
* - lp (Parallel device)
* - gpu (Graphics device)
* - fb (Framebuffer device)
* - usb (USB device)
* - usb0dsk0p0 (USB 0, disk 0, partition 0; for USB storage)
*/
dev_t CreateIncrementalDevice(dev_t DriverID, const std::string &Prefix, mode_t Mode, InodeOperations *Ops);
dev_t RegisterDevice(dev_t DriverID, DeviceType Type, const InodeOperations *Operations);
int ReportInputEvent(dev_t DriverID, InputReport *Report);
int UnregisterDevice(dev_t DriverID, dev_t Device);
Manager();
~Manager();
};
void PopulateDriverAPI(void *API);
void ManagerDaemonWrapper();
}
void *GetSymbolByName(const char *Name, int Version);
#endif // !__FENNIX_KERNEL_DRIVER_H__

View File

@ -37,6 +37,8 @@ static_assert(IFTODT(S_IFCHR) == DT_CHR);
else \
return fsi->Ops.op(this->Node, ##__VA_ARGS__)
#define FSROOT(num) "\002root-" #num "\003"
class FileNode
{
public:
@ -83,6 +85,7 @@ namespace vfs
{
Inode Node;
std::string Name;
std::string FriendlyName;
std::vector<Inode *> Children;
};
@ -106,7 +109,8 @@ namespace vfs
std::unordered_map<dev_t, FSMountInfo> DeviceMap;
std::atomic_bool RegisterLock = false;
FileNode *__CacheRecursiveSearch(FileNode *, const char *, bool);
FileNode *CacheSearchReturnLast(FileNode *Parent, const char **Path);
FileNode *CacheRecursiveSearch(FileNode *Root, const char *NameOrPath, bool IsName);
FileNode *CacheLookup(const char *Path);
FileNode *CreateCacheNode(FileNode *Parent, Inode *Node, const char *Name, mode_t Mode);
@ -114,6 +118,7 @@ namespace vfs
public:
vfsInode *FileSystemRoots = nullptr;
std::unordered_map<ino_t, FileNode *> FileRoots;
bool PathIsRelative(const char *Path);
bool PathIsAbsolute(const char *Path) { return !PathIsRelative(Path); }
@ -140,7 +145,11 @@ namespace vfs
FileNode *Create(FileNode *Parent, const char *Name, mode_t Mode);
FileNode *ForceCreate(FileNode *Parent, const char *Name, mode_t Mode);
FileNode *Mount(FileNode *Parent, Inode *Node, const char *Path);
int Unmount(const char *Path);
FileNode *GetByPath(const char *Path, FileNode *Parent);
std::string GetByNode(FileNode *Node);
FileNode *CreateLink(const char *Path, FileNode *Parent, const char *Target);
FileNode *CreateLink(const char *Path, FileNode *Parent, FileNode *Target);
bool PathExists(const char *Path, FileNode *Parent);

259
include/interface/aip.h Normal file
View File

@ -0,0 +1,259 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_API_AIP_H__
#define __FENNIX_API_AIP_H__
#include <types.h>
#define PIC1_CMD 0x20
#define PIC1_DATA (PIC1_CMD + 1)
#define PIC2_CMD 0xA0
#define PIC2_DATA (PIC2_CMD + 1)
#define _PIC_EOI 0x20
#define PS2_DATA 0x60
#define PS2_STATUS 0x64
#define PS2_CMD PS2_STATUS
#define PS2_ACK 0xFA
#define PS2_TEST_PASSED 0x55
#define PS2_TEST_FAILED 0xFC
#define PS2_CMD_READ_CONFIG 0x20
#define PS2_CMD_READ_CONFIG_N(n) (PS2_CMD_READ_CONFIG + n)
#define PS2_CMD_WRITE_CONFIG 0x60
#define PS2_CMD_WRITE_CONFIG_N(n) (PS2_CMD_WRITE_CONFIG + n)
#define PS2_CMD_DISABLE_PORT_2 0xA7
#define PS2_CMD_ENABLE_PORT_2 0xA8
#define PS2_CMD_TEST_PORT_2 0xA9
#define PS2_CMD_TEST_CONTROLLER 0xAA
#define PS2_CMD_TEST_PORT_1 0xAB
#define PS2_CMD_DIAGNOSTIC_DUMP 0xAC
#define PS2_CMD_DISABLE_PORT_1 0xAD
#define PS2_CMD_ENABLE_PORT_1 0xAE
#define PS2_CMD_READ_INPUT_PORT 0xC0
#define PS2_CMD_COPY_INPUT_0_3_TO_4_7_STATUS 0xC1
#define PS2_CMD_COPY_INPUT_4_7_TO_4_7_STATUS 0xC2
#define PS2_CMD_READ_OUTPUT_PORT 0xD0
#define PS2_CMD_WRITE_NEXT_BYTE_TO_OUTPUT_PORT 0xD1
#define PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_1_OUTPUT 0xD2
#define PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_OUTPUT 0xD3
#define PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT 0xD4
#define PS2_CMD_PULSE_OUTPUT_LINE(n) (0xF0 + n)
typedef union
{
struct
{
uint8_t OutputBufferFull : 1;
uint8_t InputBufferFull : 1;
uint8_t SystemFlag : 1;
uint8_t CommandData : 1;
uint8_t Unknown1 : 1;
uint8_t Unknown2 : 1;
uint8_t TimeoutError : 1;
uint8_t ParityError : 1;
};
uint8_t Raw;
} PS2_STATUSES;
typedef union
{
struct
{
uint8_t Port1Interrupt : 1;
uint8_t Port2Interrupt : 1;
uint8_t SystemFlag : 1;
uint8_t Zero0 : 1;
uint8_t Port1Clock : 1;
uint8_t Port2Clock : 1;
uint8_t Port1Translation : 1;
uint8_t Zero1 : 1;
};
uint8_t Raw;
} PS2_CONFIGURATION;
typedef union
{
struct
{
uint8_t SystemReset : 1;
uint8_t A20Gate : 1;
uint8_t Port2Clock : 1;
uint8_t Port2Data : 1;
uint8_t Port1OutputBufferFull : 1;
uint8_t Port2OutputBufferFull : 1;
uint8_t Port1InputBufferFull : 1;
uint8_t Port2InputBufferFull : 1;
};
uint8_t Raw;
} PS2_OUTPUT_PORT;
void PIC_EOI(uint8_t IRQ);
void IRQ_MASK(uint8_t IRQ);
void IRQ_UNMASK(uint8_t IRQ);
void PS2Wait(const bool Output);
void PS2WriteCommand(uint8_t Command);
void PS2WriteData(uint8_t Data);
uint8_t PS2ReadData();
uint8_t PS2ReadStatus();
uint8_t PS2ReadAfterACK();
void PS2ClearOutputBuffer();
int PS2ACKTimeout();
#define WaitOutput PS2Wait(DriverID, true)
#define WaitInput PS2Wait(DriverID, false)
#define PS2_KBD_CMD_SET_LEDS 0xED
#define PS2_KBD_CMD_ECHO 0xEE
#define PS2_KBD_CMD_SCAN_CODE_SET 0xF0
#define PS2_KBD_CMD_IDENTIFY 0xF2
#define PS2_KBD_CMD_TYPEMATIC 0xF3
#define PS2_KBD_CMD_ENABLE_SCANNING 0xF4
#define PS2_KBD_CMD_DISABLE_SCANNING 0xF5
#define PS2_KBD_CMD_DEFAULTS 0xF6
#define PS2_KBD_CMD_ALL_TYPEMATIC 0xF7
#define PS2_KBD_CMD_ALL_MAKE_RELEASE 0xF8
#define PS2_KBD_CMD_ALL_MAKE 0xF9
#define PS2_KBD_CMD_ALL_TYPEMATIC_MAKE_RELEASE 0xFA
#define PS2_KBD_CMD_SPECIFIC_TYPEMATIC 0xFB
#define PS2_KBD_CMD_SPECIFIC_MAKE_RELEASE 0xFC
#define PS2_KBD_CMD_SPECIFIC_MAKE 0xFD
#define PS2_KBD_CMD_RESEND 0xFE
#define PS2_KBD_CMD_RESET 0xFF
#define PS2_KBD_RESP_ACK 0xFA
#define PS2_KBD_RESP_ECHO 0xEE
#define PS2_KBD_RESP_RESEND 0xFE
#define PS2_KBD_RESP_TEST_PASSED 0xAA
#define PS2_KBD_RESP_TEST_FAILED 0xFC
#define PS2_KBD_RESP_TEST_FAILED_2 0xFD
typedef enum
{
PS2_KBD_LED_SCROLL_LOCK = 1,
PS2_KBD_LED_NUM_LOCK = 2,
PS2_KBD_LED_CAPS_LOCK = 4
} PS2_KBD_LEDS;
typedef enum
{
PS2_KBD_SCAN_CODE_GET_CURRENT = 0,
PS2_KBD_SCAN_CODE_SET_1 = 1,
PS2_KBD_SCAN_CODE_SET_2 = 2,
PS2_KBD_SCAN_CODE_SET_3 = 3,
PS2_KBD_SC_SET_1 = 0x43,
PS2_KBD_SC_SET_2 = 0x41,
PS2_KBD_SC_SET_3 = 0x3F
} PS2_KBD_SCAN_CODE_SET;
typedef union
{
struct
{
/**
* 00000b - 30Hz
* 11111b - 2Hz
*/
uint8_t RepeatRate : 5;
/**
* 00b - 250ms
* 01b - 500ms
* 10b - 750ms
* 11b - 1000ms
*/
uint8_t Delay : 2;
/**
* Must be zero
*/
uint8_t Zero : 1;
};
uint8_t Raw;
} PS2_KBD_TYPEMATIC;
#define PS2_MOUSE_CMD_SET_SCALING_1_1 0xE6
#define PS2_MOUSE_CMD_SET_SCALING_2_1 0xE7
#define PS2_MOUSE_CMD_SET_RESOLUTION 0xE8
#define PS2_MOUSE_CMD_GET_STATUS 0xE9
#define PS2_MOUSE_CMD_SET_STREAM_MODE 0xEA
#define PS2_MOUSE_CMD_READ_DATA 0xEB
#define PS2_MOUSE_CMD_RESET_WRAP_MODE 0xEC
#define PS2_MOUSE_CMD_SET_WRAP_MODE 0xEE
#define PS2_MOUSE_CMD_SET_REMOTE_MODE 0xF0
#define PS2_MOUSE_CMD_READ_ID 0xF2
/** Values: 10, 20, 40, 60, 80, 100, 200 */
#define PS2_MOUSE_CMD_SET_SAMPLE_RATE 0xF3
#define PS2_MOUSE_CMD_ENABLE_DATA_REPORTING 0xF4
#define PS2_MOUSE_CMD_DISABLE_DATA_REPORTING 0xF5
#define PS2_MOUSE_CMD_SET_DEFAULTS 0xF6
#define PS2_MOUSE_CMD_RESEND 0xFE
#define PS2_MOUSE_CMD_RESET 0xFF
#define PS2_MOUSE_RESP_ACK 0xFA
#define PS2_MOUSE_RESP_RESEND 0xFE
#define PS2_MOUSE_RESP_TEST_PASSED 0xAA
#define PS2_MOUSE_RESP_TEST_FAILED 0xFC
typedef enum
{
PS2_MOUSE_RES_1 = 0,
PS2_MOUSE_RES_2 = 1,
PS2_MOUSE_RES_4 = 2,
PS2_MOUSE_RES_8 = 3
} PS2_MOUSE_RESOLUTION;
typedef struct
{
union
{
struct
{
uint8_t LeftButton : 1;
uint8_t RightButton : 1;
uint8_t MiddleButton : 1;
uint8_t Always1 : 1;
uint8_t XSign : 1;
uint8_t YSign : 1;
uint8_t XOverflow : 1;
uint8_t YOverflow : 1;
} __attribute__((packed));
uint8_t Raw;
} Base;
uint8_t XMovement;
uint8_t YMovement;
union
{
struct
{
uint8_t Z : 4;
uint8_t Button4 : 1;
uint8_t Button5 : 1;
uint8_t Always0 : 1;
uint8_t Always0_2 : 1;
} __attribute__((packed));
uint8_t Raw;
} ZMovement;
} PS2_MOUSE_PACKET;
#endif // !__FENNIX_API_AIP_H__

View File

@ -15,31 +15,15 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_CIRCULAR_BUFFER_H__
#define __FENNIX_KERNEL_CIRCULAR_BUFFER_H__
#ifndef __FENNIX_API_AUDIO_H__
#define __FENNIX_API_AUDIO_H__
#include <types.h>
#include <lock.hpp>
class CircularBuffer
{
private:
spin_lock Lock;
uint8_t *Buffer;
size_t BufferSize;
size_t BufferCount;
#if __has_include(<interface/device.h>)
#include <interface/device.h>
#else
#include <device.h>
#endif
size_t Head;
size_t Tail;
public:
CircularBuffer(size_t Size);
~CircularBuffer();
size_t Write(const uint8_t *Data, size_t Size);
size_t Read(uint8_t *Data, size_t Size);
size_t Peek(uint8_t *Data, size_t Size);
size_t Count();
size_t Free();
};
#endif // !__FENNIX_KERNEL_CIRCULAR_BUFFER_H__
#endif // !__FENNIX_API_AUDIO_H__

View File

@ -0,0 +1,74 @@
/*
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/>.
*/
#ifndef __FENNIX_API_DEVICE_H__
#define __FENNIX_API_DEVICE_H__
#include <types.h>
#ifndef __FENNIX_API_FILESYSTEM_H__
#if __has_include(<interface/fs.h>)
#include <interface/fs.h>
#else
#include <fs.h>
#endif
#endif // !__FENNIX_API_FILESYSTEM_H__
typedef enum
{
DEVICE_TYPE_MASK = 0b1111111100000000000000000000000000000000,
DEVICE_TYPE_NONE = 0b0000000000000000000000000000000000000000,
DEVICE_TYPE_INPUT = 0b0000000100000000000000000000000000000000,
DEVICE_TYPE_AUDIO = 0b0000001000000000000000000000000000000000,
DEVICE_TYPE_NETWORK = 0b0000010000000000000000000000000000000000,
DEVICE_TYPE_BLOCK = 0b0000100000000000000000000000000000000000,
INPUT_TYPE_NONE = DEVICE_TYPE_INPUT + 0,
INPUT_TYPE_KEYBOARD = DEVICE_TYPE_INPUT + 2,
INPUT_TYPE_MOUSE = DEVICE_TYPE_INPUT + 4,
INPUT_TYPE_JOYSTICK = DEVICE_TYPE_INPUT + 8,
INPUT_TYPE_TOUCHSCREEN = DEVICE_TYPE_INPUT + 16,
INPUT_TYPE_GAMEPAD = DEVICE_TYPE_INPUT + 32,
INPUT_TYPE_ACCELEROMETER = DEVICE_TYPE_INPUT + 64,
INPUT_TYPE_GYROSCOPE = DEVICE_TYPE_INPUT + 128,
INPUT_TYPE_MAGNETOMETER = DEVICE_TYPE_INPUT + 256,
AUDIO_TYPE_NONE = DEVICE_TYPE_AUDIO + 0,
AUDIO_TYPE_PWM = DEVICE_TYPE_AUDIO + 2,
AUDIO_TYPE_DSP = DEVICE_TYPE_AUDIO + 4,
AUDIO_TYPE_PCM = DEVICE_TYPE_AUDIO + 8,
AUDIO_TYPE_MIDI = DEVICE_TYPE_AUDIO + 16,
NETWORK_TYPE_NONE = DEVICE_TYPE_NETWORK + 0,
NETWORK_TYPE_ETHERNET = DEVICE_TYPE_NETWORK + 2,
NETWORK_TYPE_WIFI = DEVICE_TYPE_NETWORK + 4,
NETWORK_TYPE_BLUETOOTH = DEVICE_TYPE_NETWORK + 8,
BLOCK_TYPE_NONE = DEVICE_TYPE_BLOCK + 0,
BLOCK_TYPE_SDCARD = DEVICE_TYPE_BLOCK + 2,
BLOCK_TYPE_HDD = DEVICE_TYPE_BLOCK + 4,
BLOCK_TYPE_SSD = DEVICE_TYPE_BLOCK + 8,
BLOCK_TYPE_USB = DEVICE_TYPE_BLOCK + 16,
BLOCK_TYPE_NVME = DEVICE_TYPE_BLOCK + 32,
BLOCK_TYPE_CDROM = DEVICE_TYPE_BLOCK + 64,
BLOCK_TYPE_FLOPPY = DEVICE_TYPE_BLOCK + 128,
} DeviceType;
EXTERNC dev_t RegisterDevice(DeviceType Type, const struct InodeOperations *Operations);
EXTERNC int UnregisterDevice(dev_t Device);
#endif // !__FENNIX_API_DEVICE_H__

View File

@ -20,30 +20,6 @@
#include <types.h>
typedef enum
{
_drf_Entry,
_drf_Final,
_drf_Panic,
_drf_Probe,
} __driverRegFunc;
typedef union
{
struct
{
uint8_t LeftButton : 1;
uint8_t RightButton : 1;
uint8_t MiddleButton : 1;
uint8_t Button4 : 1;
uint8_t Button5 : 1;
uint8_t Button6 : 1;
uint8_t Button7 : 1;
uint8_t Button8 : 1;
};
uint8_t Value;
} __MouseButtons;
typedef struct
{
/* PCIDevice */ void *Device;
@ -55,143 +31,6 @@ typedef struct
#define PCI_END 0x0000
#define KEY_NULL 0x00
typedef enum
{
KEY_1,
KEY_2,
KEY_3,
KEY_4,
KEY_5,
KEY_6,
KEY_7,
KEY_8,
KEY_9,
KEY_0,
KEY_Q,
KEY_W,
KEY_E,
KEY_R,
KEY_T,
KEY_Y,
KEY_U,
KEY_I,
KEY_O,
KEY_P,
KEY_A,
KEY_S,
KEY_D,
KEY_F,
KEY_G,
KEY_H,
KEY_J,
KEY_K,
KEY_L,
KEY_Z,
KEY_X,
KEY_C,
KEY_V,
KEY_B,
KEY_N,
KEY_M,
KEY_F1,
KEY_F2,
KEY_F3,
KEY_F4,
KEY_F5,
KEY_F6,
KEY_F7,
KEY_F8,
KEY_F9,
KEY_F10,
KEY_F11,
KEY_F12,
KEYPAD_7,
KEYPAD_8,
KEYPAD_9,
KEYPAD_MINUS,
KEYPAD_4,
KEYPAD_5,
KEYPAD_6,
KEYPAD_PLUS,
KEYPAD_1,
KEYPAD_2,
KEYPAD_3,
KEYPAD_0,
KEYPAD_PERIOD,
KEYPAD_RETURN,
KEYPAD_ASTERISK,
KEYPAD_SLASH,
KEY_LEFT_CTRL,
KEY_RIGHT_CTRL,
KEY_LEFT_SHIFT,
KEY_RIGHT_SHIFT,
KEY_LEFT_ALT,
KEY_RIGHT_ALT,
KEY_ESCAPE,
KEY_MINUS,
KEY_EQUAL,
KEY_BACKSPACE,
KEY_TAB,
KEY_LEFT_BRACKET,
KEY_RIGHT_BRACKET,
KEY_RETURN,
KEY_SEMICOLON,
KEY_APOSTROPHE,
KEY_BACK_TICK,
KEY_BACKSLASH,
KEY_COMMA,
KEY_PERIOD,
KEY_SLASH,
KEY_SPACE,
KEY_CAPS_LOCK,
KEY_NUM_LOCK,
KEY_SCROLL_LOCK,
KEY_PRINT_SCREEN,
KEY_HOME,
KEY_UP_ARROW,
KEY_LEFT_ARROW,
KEY_RIGHT_ARROW,
KEY_DOWN_ARROW,
KEY_PAGE_UP,
KEY_PAGE_DOWN,
KEY_END,
KEY_INSERT,
KEY_DELETE,
KEY_LEFT_GUI,
KEY_RIGHT_GUI,
KEY_APPS,
KEY_MULTIMEDIA_PREV_TRACK,
KEY_MULTIMEDIA_NEXT_TRACK,
KEY_MULTIMEDIA_MUTE,
KEY_MULTIMEDIA_CALCULATOR,
KEY_MULTIMEDIA_PLAY,
KEY_MULTIMEDIA_STOP,
KEY_MULTIMEDIA_VOL_DOWN,
KEY_MULTIMEDIA_VOL_UP,
KEY_MULTIMEDIA_WWW_HOME,
KEY_MULTIMEDIA_WWW_SEARCH,
KEY_MULTIMEDIA_WWW_FAVORITES,
KEY_MULTIMEDIA_WWW_REFRESH,
KEY_MULTIMEDIA_WWW_STOP,
KEY_MULTIMEDIA_WWW_FORWARD,
KEY_MULTIMEDIA_WWW_BACK,
KEY_MULTIMEDIA_MY_COMPUTER,
KEY_MULTIMEDIA_EMAIL,
KEY_MULTIMEDIA_MEDIA_SELECT,
KEY_ACPI_POWER,
KEY_ACPI_SLEEP,
KEY_ACPI_WAKE,
KEY_PRESSED = 0x80,
} KeyScanCodes;
typedef enum
{
IOCTL_AUDIO_GET_VOLUME = 0,
@ -221,73 +60,17 @@ typedef enum
MAP_CACHE_DISABLE = 1 << 4,
} PageMapFlags;
typedef struct
struct __DriverInfo
{
struct
const char *Name;
const char *Description;
const char *Author;
struct __DriverVersion
{
uint8_t Major;
uint8_t Minor;
uint8_t Patch;
} APIVersion;
dev_t MajorID;
uintptr_t Base;
/* Internal */
int (*RegisterFunction)(dev_t MajorID, void *Function, __driverRegFunc Type);
int (*GetDriverInfo)(dev_t MajorID, const char *Name, const char *Description, const char *Author, const char *Version, const char *License);
/* Interrupts */
int (*RegisterInterruptHandler)(dev_t MajorID, uint8_t IRQ, void *Handler);
int (*OverrideInterruptHandler)(dev_t MajorID, uint8_t IRQ, void *Handler);
int (*UnregisterInterruptHandler)(dev_t MajorID, uint8_t IRQ, void *Handler);
int (*UnregisterAllInterruptHandlers)(dev_t MajorID, void *Handler);
/* /dev/... */
dev_t (*RegisterDevice)(dev_t MajorID, char Prefix[8], void *Open, void *Close, void *Read, void *Write, void *Ioctl);
int (*UnregisterDevice)(dev_t MajorID, dev_t MinorID);
/* Logging */
void (*KPrint)(dev_t MajorID, const char *Format, va_list args);
void (*KernelLog)(dev_t MajorID, const char *Format, va_list args);
/* Memory */
void *(*RequestPages)(dev_t MajorID, size_t Pages);
void (*FreePages)(dev_t MajorID, void *Pointer, size_t Pages);
/* Mapping */
void (*AppendMapFlag)(dev_t MajorID, void *Address, PageMapFlags Flag);
void (*RemoveMapFlag)(dev_t MajorID, void *Address, PageMapFlags Flag);
void (*MapPages)(dev_t MajorID, void *PhysicalAddress, void *VirtualAddress, size_t Pages, uint32_t Flags);
void (*UnmapPages)(dev_t MajorID, void *VirtualAddress, size_t Pages);
/* Scheduling */
pid_t (*CreateKernelProcess)(dev_t MajorID, const char *Name);
pid_t (*CreateKernelThread)(dev_t MajorID, pid_t pId, const char *Name, void *EntryPoint, void *Argument);
pid_t (*GetCurrentProcess)(dev_t MajorID);
int (*KillProcess)(dev_t MajorID, pid_t pId, int ExitCode);
int (*KillThread)(dev_t MajorID, pid_t tId, pid_t pId, int ExitCode);
void (*Yield)(dev_t MajorID);
void (*Sleep)(dev_t MajorID, uint64_t Milliseconds);
/* PCI */
__PCIArray *(*GetPCIDevices)(dev_t MajorID, uint16_t Vendors[], uint16_t Devices[]);
void (*InitializePCI)(dev_t MajorID, void *Header);
uint32_t (*GetBAR)(dev_t MajorID, uint8_t Index, void *Header);
/* Kernel std API */
void *(*memcpy)(dev_t MajorID, void *Destination, const void *Source, size_t Length);
void *(*memset)(dev_t MajorID, void *Destination, int Value, size_t Length);
void *(*memmove)(dev_t MajorID, void *Destination, const void *Source, size_t Length);
int (*memcmp)(dev_t MajorID, const void *Left, const void *Right, size_t Length);
size_t (*strlen)(dev_t MajorID, const char *String);
char *(*strcpy)(dev_t MajorID, char *Destination, const char *Source);
char *(*strcat)(dev_t MajorID, char *Destination, const char *Source);
int (*strcmp)(dev_t MajorID, const char *Left, const char *Right);
int (*strncmp)(dev_t MajorID, const char *Left, const char *Right, size_t Length);
char *(*strchr)(dev_t MajorID, const char *String, int Character);
char *(*strrchr)(dev_t MajorID, const char *String, int Character);
char *(*strstr)(dev_t MajorID, const char *Haystack, const char *Needle);
} __driverAPI;
int APIVersion;
int Major, Minor, Patch;
} Version;
const char *License;
};
#endif // !__FENNIX_API_DRIVER_FUNCTIONS_H__

View File

@ -18,9 +18,7 @@
#ifndef __FENNIX_API_FILESYSTEM_H__
#define __FENNIX_API_FILESYSTEM_H__
#ifdef __kernel__
#include <types.h>
#endif
#define SEEK_SET 0
#define SEEK_CUR 1
@ -253,30 +251,6 @@ struct kdirent
char d_name[];
};
struct InodeOperations
{
int (*Lookup)(struct Inode *Parent, const char *Name, struct Inode **Result);
int (*Create)(struct Inode *Parent, const char *Name, mode_t Mode, struct Inode **Result);
int (*Remove)(struct Inode *Parent, const char *Name);
int (*Rename)(struct Inode *Parent, const char *OldName, const char *NewName);
ssize_t (*Read)(struct Inode *Node, void *Buffer, size_t Size, off_t Offset);
ssize_t (*Write)(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset);
int (*Truncate)(struct Inode *Node, off_t Size);
int (*Open)(struct Inode *Node, int Flags, mode_t Mode);
int (*Close)(struct Inode *Node);
int (*Ioctl)(struct Inode *Node, unsigned long Request, void *Argp);
ssize_t (*ReadDir)(struct Inode *Node, struct kdirent *Buffer, size_t Size, off_t Offset, off_t Entries);
int (*MkDir)(struct Inode *Parent, const char *Name, mode_t Mode, struct Inode **Result);
int (*RmDir)(struct Inode *Parent, const char *Name);
int (*SymLink)(struct Inode *Parent, const char *Name, const char *Target, struct Inode **Result);
ssize_t (*ReadLink)(struct Inode *Node, char *Buffer, size_t Size);
off_t (*Seek)(struct Inode *Node, off_t Offset);
int (*Stat)(struct Inode *Node, struct kstat *Stat);
} __attribute__((packed));
#define I_FLAG_MOUNTPOINT 0x1
#define I_FLAG_CACHE_KEEP 0x2
struct Inode
{
dev_t Device, RawDevice;
@ -335,6 +309,32 @@ struct Inode
#endif // __cplusplus
};
struct InodeOperations
{
int (*Lookup)(struct Inode *Parent, const char *Name, struct Inode **Result);
int (*Create)(struct Inode *Parent, const char *Name, mode_t Mode, struct Inode **Result);
int (*Remove)(struct Inode *Parent, const char *Name);
int (*Rename)(struct Inode *Parent, const char *OldName, const char *NewName);
ssize_t (*Read)(struct Inode *Node, void *Buffer, size_t Size, off_t Offset);
ssize_t (*Write)(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset);
int (*Truncate)(struct Inode *Node, off_t Size);
int (*Open)(struct Inode *Node, int Flags, mode_t Mode);
int (*Close)(struct Inode *Node);
int (*Ioctl)(struct Inode *Node, unsigned long Request, void *Argp);
ssize_t (*ReadDir)(struct Inode *Node, struct kdirent *Buffer, size_t Size, off_t Offset, off_t Entries);
int (*MkDir)(struct Inode *Parent, const char *Name, mode_t Mode, struct Inode **Result);
int (*RmDir)(struct Inode *Parent, const char *Name);
int (*SymLink)(struct Inode *Parent, const char *Name, const char *Target, struct Inode **Result);
ssize_t (*ReadLink)(struct Inode *Node, char *Buffer, size_t Size);
off_t (*Seek)(struct Inode *Node, off_t Offset);
int (*Stat)(struct Inode *Node, struct kstat *Stat);
} __attribute__((packed));
#define I_FLAG_ROOT 0x1
#define I_FLAG_MOUNTPOINT 0x2
#define I_FLAG_CACHE_KEEP 0x4
struct FileSystemInfo;
struct SuperBlockOperations
{
int (*AllocateInode)(struct FileSystemInfo *Info, struct Inode **Result);
@ -360,12 +360,13 @@ struct SuperBlockOperations
*
* @return Zero on success, otherwise an error code.
*/
int (*Destroy)(FileSystemInfo *Info);
int (*Destroy)(struct FileSystemInfo *Info);
} __attribute__((packed));
struct FileSystemInfo
{
const char *Name;
const char *RootName;
int Flags;
struct SuperBlockOperations SuperOps;
struct InodeOperations Ops;
@ -373,7 +374,7 @@ struct FileSystemInfo
void *PrivateData;
} __attribute__((packed));
dev_t RegisterFileSystem(FileSystemInfo *Info, struct Inode *Root);
dev_t RegisterFileSystem(struct FileSystemInfo *Info, struct Inode *Root);
int UnregisterFileSystem(dev_t Device);
#endif // !__FENNIX_API_FILESYSTEM_H__

234
include/interface/input.h Normal file
View File

@ -0,0 +1,234 @@
/*
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/>.
*/
#ifndef __FENNIX_API_INPUT_H__
#define __FENNIX_API_INPUT_H__
#include <types.h>
#if __has_include(<interface/device.h>)
#include <interface/device.h>
#else
#include <device.h>
#endif
struct InodeOperations;
typedef enum
{
KEY_1,
KEY_2,
KEY_3,
KEY_4,
KEY_5,
KEY_6,
KEY_7,
KEY_8,
KEY_9,
KEY_0,
KEY_Q,
KEY_W,
KEY_E,
KEY_R,
KEY_T,
KEY_Y,
KEY_U,
KEY_I,
KEY_O,
KEY_P,
KEY_A,
KEY_S,
KEY_D,
KEY_F,
KEY_G,
KEY_H,
KEY_J,
KEY_K,
KEY_L,
KEY_Z,
KEY_X,
KEY_C,
KEY_V,
KEY_B,
KEY_N,
KEY_M,
KEY_F1,
KEY_F2,
KEY_F3,
KEY_F4,
KEY_F5,
KEY_F6,
KEY_F7,
KEY_F8,
KEY_F9,
KEY_F10,
KEY_F11,
KEY_F12,
KEYPAD_7,
KEYPAD_8,
KEYPAD_9,
KEYPAD_MINUS,
KEYPAD_4,
KEYPAD_5,
KEYPAD_6,
KEYPAD_PLUS,
KEYPAD_1,
KEYPAD_2,
KEYPAD_3,
KEYPAD_0,
KEYPAD_PERIOD,
KEYPAD_RETURN,
KEYPAD_ASTERISK,
KEYPAD_SLASH,
KEY_LEFT_CTRL,
KEY_RIGHT_CTRL,
KEY_LEFT_SHIFT,
KEY_RIGHT_SHIFT,
KEY_LEFT_ALT,
KEY_RIGHT_ALT,
KEY_ESCAPE,
KEY_MINUS,
KEY_EQUAL,
KEY_BACKSPACE,
KEY_TAB,
KEY_LEFT_BRACKET,
KEY_RIGHT_BRACKET,
KEY_RETURN,
KEY_SEMICOLON,
KEY_APOSTROPHE,
KEY_BACK_TICK,
KEY_BACKSLASH,
KEY_COMMA,
KEY_PERIOD,
KEY_SLASH,
KEY_SPACE,
KEY_CAPS_LOCK,
KEY_NUM_LOCK,
KEY_SCROLL_LOCK,
KEY_PRINT_SCREEN,
KEY_HOME,
KEY_UP_ARROW,
KEY_LEFT_ARROW,
KEY_RIGHT_ARROW,
KEY_DOWN_ARROW,
KEY_PAGE_UP,
KEY_PAGE_DOWN,
KEY_END,
KEY_INSERT,
KEY_DELETE,
KEY_LEFT_GUI,
KEY_RIGHT_GUI,
KEY_APPS,
KEY_MULTIMEDIA_PREV_TRACK,
KEY_MULTIMEDIA_NEXT_TRACK,
KEY_MULTIMEDIA_MUTE,
KEY_MULTIMEDIA_CALCULATOR,
KEY_MULTIMEDIA_PLAY,
KEY_MULTIMEDIA_STOP,
KEY_MULTIMEDIA_VOL_DOWN,
KEY_MULTIMEDIA_VOL_UP,
KEY_MULTIMEDIA_WWW_HOME,
KEY_MULTIMEDIA_WWW_SEARCH,
KEY_MULTIMEDIA_WWW_FAVORITES,
KEY_MULTIMEDIA_WWW_REFRESH,
KEY_MULTIMEDIA_WWW_STOP,
KEY_MULTIMEDIA_WWW_FORWARD,
KEY_MULTIMEDIA_WWW_BACK,
KEY_MULTIMEDIA_MY_COMPUTER,
KEY_MULTIMEDIA_EMAIL,
KEY_MULTIMEDIA_MEDIA_SELECT,
KEY_ACPI_POWER,
KEY_ACPI_SLEEP,
KEY_ACPI_WAKE,
KEY_PRESSED = 0x80,
} KeyScanCodes;
typedef struct
{
KeyScanCodes Key;
} KeyboardReport;
typedef struct
{
long X, Y;
int8_t Z;
uint8_t Absolute : 1;
uint8_t LeftButton : 1;
uint8_t RightButton : 1;
uint8_t MiddleButton : 1;
uint8_t Button4 : 1;
uint8_t Button5 : 1;
uint8_t Button6 : 1;
uint8_t Button7 : 1;
uint8_t Button8 : 1;
} MouseReport;
typedef struct
{
} JoystickReport;
typedef struct
{
uint16_t X, Y;
uint8_t Pressure;
} TouchScreenReport;
typedef struct
{
} GamepadReport;
typedef struct
{
} AccelerometerReport;
typedef struct
{
} GyroscopeReport;
typedef struct
{
} MagnetometerReport;
typedef struct
{
DeviceType Type;
dev_t Device;
union
{
KeyboardReport Keyboard;
MouseReport Mouse;
JoystickReport Joystick;
TouchScreenReport TouchScreen;
GamepadReport Gamepad;
AccelerometerReport Accelerometer;
GyroscopeReport Gyroscope;
MagnetometerReport Magnetometer;
/* ... */
};
} InputReport;
EXTERNC int ReportInputEvent(InputReport *Report);
#endif // !__FENNIX_API_INPUT_H__

View File

@ -0,0 +1,29 @@
/*
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/>.
*/
#ifndef __FENNIX_API_NETWORK_H__
#define __FENNIX_API_NETWORK_H__
#include <types.h>
#if __has_include(<interface/device.h>)
#include <interface/device.h>
#else
#include <device.h>
#endif
#endif // !__FENNIX_API_NETWORK_H__

184
include/interface/pci.h Normal file
View File

@ -0,0 +1,184 @@
/*
This file is part of Fennix Drivers.
Fennix Drivers 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 Drivers 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 Drivers. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_API_PCI_H__
#define __FENNIX_API_PCI_H__
#include <types.h>
/* https://sites.uclouvain.be/SystInfo/usr/include/linux/pci_regs.h.html */
typedef enum
{
/** @brief Enable response in I/O space */
PCI_COMMAND_IO = 0x1,
/** @brief Enable response in Memory space */
PCI_COMMAND_MEMORY = 0x2,
/** @brief Enable bus mastering */
PCI_COMMAND_MASTER = 0x4,
/** @brief Enable response to special cycles */
PCI_COMMAND_SPECIAL = 0x8,
/** @brief Use memory write and invalidate */
PCI_COMMAND_INVALIDATE = 0x10,
/** @brief Enable palette snooping */
PCI_COMMAND_VGA_PALETTE = 0x20,
/** @brief Enable parity checking */
PCI_COMMAND_PARITY = 0x40,
/** @brief Enable address/data stepping */
PCI_COMMAND_WAIT = 0x80,
/** @brief Enable SERR */
PCI_COMMAND_SERR = 0x100,
/** @brief Enable back-to-back writes */
PCI_COMMAND_FAST_BACK = 0x200,
/** @brief INTx Emulation Disable */
PCI_COMMAND_INTX_DISABLE = 0x400
} PCI_COMMANDS;
typedef struct
{
uint16_t VendorID;
uint16_t DeviceID;
uint16_t Command;
uint16_t Status;
uint8_t RevisionID;
uint8_t ProgIF;
uint8_t Subclass;
uint8_t Class;
uint8_t CacheLineSize;
uint8_t LatencyTimer;
uint8_t HeaderType;
uint8_t BIST;
} __attribute__((packed)) PCIDeviceHeader;
typedef struct
{
PCIDeviceHeader Header;
uint32_t BAR0;
uint32_t BAR1;
uint32_t BAR2;
uint32_t BAR3;
uint32_t BAR4;
uint32_t BAR5;
uint32_t CardbusCISPointer;
uint16_t SubsystemVendorID;
uint16_t SubsystemID;
uint32_t ExpansionROMBaseAddress;
uint8_t CapabilitiesPointer;
uint8_t Reserved0;
uint16_t Reserved1;
uint32_t Reserved2;
uint8_t InterruptLine;
uint8_t InterruptPin;
uint8_t MinGrant;
uint8_t MaxLatency;
} __attribute__((packed)) PCIHeader0;
typedef struct
{
PCIDeviceHeader Header;
uint32_t BAR0;
uint32_t BAR1;
uint8_t PrimaryBusNumber;
uint8_t SecondaryBusNumber;
uint8_t SubordinateBusNumber;
uint8_t SecondaryLatencyTimer;
uint8_t IOBase;
uint8_t IOLimit;
uint16_t SecondaryStatus;
uint16_t MemoryBase;
uint16_t MemoryLimit;
uint16_t PrefetchableMemoryBase;
uint16_t PrefetchableMemoryLimit;
uint32_t PrefetchableMemoryBaseUpper32;
uint32_t PrefetchableMemoryLimitUpper32;
uint16_t IOBaseUpper16;
uint16_t IOLimitUpper16;
uint8_t CapabilitiesPointer;
uint8_t Reserved0;
uint16_t Reserved1;
uint32_t ExpansionROMBaseAddress;
uint8_t InterruptLine;
uint8_t InterruptPin;
uint16_t BridgeControl;
} __attribute__((packed)) PCIHeader1;
typedef struct
{
PCIDeviceHeader Header;
uint32_t CardbusSocketRegistersBaseAddress;
uint8_t CapabilitiesPointer;
uint8_t Reserved0;
uint16_t SecondaryStatus;
uint8_t PCIbusNumber;
uint8_t CardbusBusNumber;
uint8_t SubordinateBusNumber;
uint8_t CardbusLatencyTimer;
uint32_t MemoryBase0;
uint32_t MemoryLimit0;
uint32_t MemoryBase1;
uint32_t MemoryLimit1;
uint32_t IOBase0;
uint32_t IOLimit0;
uint32_t IOBase1;
uint32_t IOLimit1;
uint8_t InterruptLine;
uint8_t InterruptPin;
uint16_t BridgeControl;
uint16_t SubsystemVendorID;
uint16_t SubsystemID;
uint32_t LegacyBaseAddress;
} __attribute__((packed)) PCIHeader2;
typedef struct
{
uint64_t BaseAddress;
uint16_t PCISegGroup;
uint8_t StartBus;
uint8_t EndBus;
uint32_t Reserved;
} __attribute__((packed)) DeviceConfig;
typedef struct
{
PCIDeviceHeader *Header;
DeviceConfig *Config;
uint32_t Bus;
uint32_t Device;
uint32_t Function;
} __attribute__((packed)) PCIDevice;
typedef struct
{
PCIDevice *Device;
/* PCIArray */ void *Next;
} __attribute__((packed)) PCIArray;
#ifdef __cplusplus
extern "C"
{
#endif
PCIArray *GetPCIDevices(uint16_t Vendors[], uint16_t Devices[]);
void InitializePCI(PCIDevice *Device);
uint32_t GetBAR(uint8_t Index, PCIDevice *Device);
uint8_t iLine(PCIDevice *Device);
uint8_t iPin(PCIDevice *Device);
#ifdef __cplusplus
}
#endif
#endif // !__FENNIX_API_PCI_H__

124
include/ring.hpp Normal file
View File

@ -0,0 +1,124 @@
/*
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/>.
*/
#ifndef __FENNIX_KERNEL_RING_BUFFER_H__
#define __FENNIX_KERNEL_RING_BUFFER_H__
#include <types.h>
#include <lock.hpp>
template <typename T>
class RingBuffer
{
private:
spin_lock *Lock;
T *Buffer;
size_t BufferSize;
size_t BufferCount;
size_t Head;
size_t Tail;
public:
RingBuffer(size_t Size = 16)
: Lock(new spin_lock()),
Buffer(new T[Size]),
BufferSize(Size),
BufferCount(0),
Head(0),
Tail(0) {}
~RingBuffer()
{
delete Lock;
delete[] Buffer;
}
size_t Write(const T *Data, size_t Size)
{
sl_guard(*Lock);
size_t written = 0;
while (Size > 0)
{
if (BufferCount == BufferSize)
break;
Buffer[Head] = *Data++;
Head = (Head + 1) % BufferSize;
BufferCount++;
written++;
Size--;
}
return written;
}
size_t Read(T *Data, size_t Size)
{
sl_guard(*Lock);
size_t read = 0;
while (Size > 0)
{
if (BufferCount == 0)
break;
*Data++ = Buffer[Tail];
Tail = (Tail + 1) % BufferSize;
BufferCount--;
read++;
Size--;
}
return read;
}
size_t Peek(T *Data, size_t Size)
{
sl_guard(*Lock);
size_t read = 0;
size_t tail = Tail;
while (Size > 0)
{
if (BufferCount == 0)
break;
*Data++ = Buffer[tail];
tail = (tail + 1) % BufferSize;
read++;
Size--;
}
return read;
}
size_t Count()
{
sl_guard(*Lock);
return BufferCount;
}
size_t Free()
{
sl_guard(*Lock);
return BufferSize - BufferCount;
}
};
#endif // !__FENNIX_KERNEL_RING_BUFFER_H__

View File

@ -95,52 +95,6 @@ typedef __builtin_va_list va_list;
#define VPOKE(type, address) (*((volatile type *)(address)))
#define POKE(type, address) (*((type *)(address)))
#ifndef __cplusplus
#ifdef __STDC__
#ifdef __STDC_VERSION__
#if (__STDC_VERSION__ >= 201710L)
#define C_LANGUAGE_STANDARD 2018
#elif (__STDC_VERSION__ >= 201112L)
#define C_LANGUAGE_STANDARD 2011
#elif (__STDC_VERSION__ >= 199901L)
#define C_LANGUAGE_STANDARD 1999
#elif (__STDC_VERSION__ >= 199409L)
#define C_LANGUAGE_STANDARD 1995
#endif
#else
#define C_LANGUAGE_STANDARD 1990
#endif
#else
#define C_LANGUAGE_STANDARD 1972
#endif
#else
#ifdef __STDC__
#ifdef __cplusplus
#if (__cplusplus >= 202100L)
#define CPP_LANGUAGE_STANDARD 2023
#elif (__cplusplus >= 202002L)
#define CPP_LANGUAGE_STANDARD 2020
#elif (__cplusplus >= 201703L)
#define CPP_LANGUAGE_STANDARD 2017
#elif (__cplusplus >= 201402L)
#define CPP_LANGUAGE_STANDARD 2014
#elif (__cplusplus >= 201103L)
#define CPP_LANGUAGE_STANDARD 2011
#elif (__cplusplus >= 199711L)
#define CPP_LANGUAGE_STANDARD 1998
#endif
#else
#define CPP_LANGUAGE_STANDARD __cplusplus
#endif
#else
#define CPP_LANGUAGE_STANDARD __cplusplus
#endif
#endif // __cplusplus
#ifndef __SIG_ATOMIC_TYPE__
#define __SIG_ATOMIC_TYPE__ int
#endif
@ -511,11 +465,22 @@ typedef uint48_t uint_fast48_t;
#define StackPop(stack, type) \
*((type *)stack++)
#define ReturnLogError(ret, Format, ...) \
#define ReturnLogError(ret, format, ...) \
{ \
trace(Format, ##__VA_ARGS__); \
trace(format, ##__VA_ARGS__); \
return ret; \
} \
while (0)
while (0) \
__builtin_unreachable()
#define AssertReturnError(condition, ret) \
do \
{ \
if (__builtin_expect(!!(!(condition)), 0)) \
{ \
error("\"%s\" failed!", #condition); \
return ret; \
} \
} while (0)
#endif // !__FENNIX_KERNEL_TYPES_H__