mirror of
https://github.com/Fennix-Project/Drivers.git
synced 2025-05-25 22:14:31 +00:00
Fix driver implementation
This commit is contained in:
parent
f85935f8f3
commit
4ecf37c44e
6
.vscode/c_boilerplates.code-snippets
vendored
6
.vscode/c_boilerplates.code-snippets
vendored
@ -4,14 +4,14 @@
|
|||||||
"head",
|
"head",
|
||||||
],
|
],
|
||||||
"body": [
|
"body": [
|
||||||
"#ifndef __FENNIX_API_${2:header}_H__",
|
"#ifndef __FENNIX_DRIVER_${2:header}_H__",
|
||||||
"#define __FENNIX_API_${2:header}_H__",
|
"#define __FENNIX_DRIVER_${2:header}_H__",
|
||||||
"",
|
"",
|
||||||
"#include <types.h>",
|
"#include <types.h>",
|
||||||
"",
|
"",
|
||||||
"$0",
|
"$0",
|
||||||
"",
|
"",
|
||||||
"#endif // !__FENNIX_API_${2:header}_H__",
|
"#endif // !__FENNIX_DRIVER_${2:header}_H__",
|
||||||
""
|
""
|
||||||
],
|
],
|
||||||
"description": "Create header."
|
"description": "Create header."
|
||||||
|
4
Makefile
4
Makefile
@ -1,5 +1,5 @@
|
|||||||
build:
|
build:
|
||||||
cp -f ../Kernel/driver.h include/driver.h
|
cp -rf ../Kernel/include/interface/* include/
|
||||||
mkdir -p out
|
mkdir -p out
|
||||||
make -C library build
|
make -C library build
|
||||||
make -C audio build
|
make -C audio build
|
||||||
@ -7,6 +7,7 @@ build:
|
|||||||
make -C misc build
|
make -C misc build
|
||||||
make -C network build
|
make -C network build
|
||||||
make -C storage build
|
make -C storage build
|
||||||
|
make -C filesystem build
|
||||||
|
|
||||||
prepare:
|
prepare:
|
||||||
$(info Nothing to prepare)
|
$(info Nothing to prepare)
|
||||||
@ -19,3 +20,4 @@ clean:
|
|||||||
make -C misc clean
|
make -C misc clean
|
||||||
make -C network clean
|
make -C network clean
|
||||||
make -C storage clean
|
make -C storage clean
|
||||||
|
make -C filesystem clean
|
||||||
|
@ -1,83 +1,22 @@
|
|||||||
# Config file
|
# Config files
|
||||||
include ../../../Makefile.conf
|
include ../../../Makefile.conf
|
||||||
|
include ../../config.mk
|
||||||
FILENAME = ac97.drv
|
|
||||||
|
|
||||||
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
|
||||||
CPP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
|
||||||
LD = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
|
||||||
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
|
||||||
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
|
||||||
|
|
||||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||||
INCLUDE_DIR = ../../include
|
|
||||||
|
|
||||||
LIBS := ../../out/dcrt0.o -L../../out -ldriver
|
FILENAME = ac97.drv
|
||||||
|
|
||||||
LDFLAGS := \
|
|
||||||
-fPIC -fPIE -pie \
|
|
||||||
-Wl,--no-dynamic-linker,-ztext,--no-warn-rwx-segment \
|
|
||||||
-nostdlib -nodefaultlibs -nolibc \
|
|
||||||
-zmax-page-size=0x1000 \
|
|
||||||
-Wl,-Map file.map -shared -fvisibility=hidden
|
|
||||||
|
|
||||||
WARNCFLAG = -Wall -Wextra
|
|
||||||
|
|
||||||
CFLAGS := -I$(INCLUDE_DIR) -fvisibility=hidden
|
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 \
|
|
||||||
-march=x86-64 -pipe -ffunction-sections \
|
|
||||||
-msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), i386)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
|
|
||||||
-march=i386 -pipe -msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), aarch64)
|
|
||||||
|
|
||||||
CFLAGS += -pipe -fno-builtin -fPIC
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(DEBUG), 1)
|
|
||||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
CFLAGS += -fverbose-asm
|
|
||||||
endif
|
|
||||||
ifneq ($(OSARCH), aarch64)
|
|
||||||
CFLAGS += -fstack-check
|
|
||||||
endif
|
|
||||||
LDFLAGS += -ggdb3 -O0
|
|
||||||
endif
|
|
||||||
|
|
||||||
build: $(FILENAME)
|
build: $(FILENAME)
|
||||||
mv $(FILENAME) ../../out/$(FILENAME)
|
mv $(FILENAME) ../../out/$(FILENAME)
|
||||||
|
|
||||||
$(FILENAME): $(OBJ)
|
$(FILENAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
$(CC) $(LDFLAGS) $(OBJ) $(LIBS) -o $@
|
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||||
|
|
||||||
%.o: %.c $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CC) $(CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.cpp $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CPP) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.S
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(AS) -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <base.h>
|
#include <base.h>
|
||||||
#include <pci.h>
|
#include <pci.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
#include <fs.h>
|
||||||
|
|
||||||
#define DescriptorListLength 0x20
|
#define DescriptorListLength 0x20
|
||||||
|
|
||||||
@ -370,13 +371,13 @@ public:
|
|||||||
{
|
{
|
||||||
if (Buffer == nullptr)
|
if (Buffer == nullptr)
|
||||||
{
|
{
|
||||||
Log("Invalid buffer.");
|
KernelLog("Invalid buffer.");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Size == 0) || (Size % (SampleSize * Channels)))
|
if ((Size == 0) || (Size % (SampleSize * Channels)))
|
||||||
{
|
{
|
||||||
Log("Invalid buffer length.");
|
KernelLog("Invalid buffer length.");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,7 +432,7 @@ public:
|
|||||||
|
|
||||||
if (Wrote == 0)
|
if (Wrote == 0)
|
||||||
{
|
{
|
||||||
Log("Wrote 0 bytes.");
|
KernelLog("Wrote 0 bytes.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,7 +564,7 @@ public:
|
|||||||
uint16_t CurrentBDL = inb(BusMasterAddress + PCMOUT_BufferDescriptorEntry);
|
uint16_t CurrentBDL = inb(BusMasterAddress + PCMOUT_BufferDescriptorEntry);
|
||||||
uint16_t LastBDL = (CurrentBDL + 2) & (DescriptorListLength - 1);
|
uint16_t LastBDL = (CurrentBDL + 2) & (DescriptorListLength - 1);
|
||||||
outb(BusMasterAddress + PCMOUT_DescriptorEntries, LastBDL);
|
outb(BusMasterAddress + PCMOUT_DescriptorEntries, LastBDL);
|
||||||
Log("FIXME: CurrentBDL: %d, LastBDL: %d", CurrentBDL, LastBDL);
|
KernelLog("FIXME: CurrentBDL: %d, LastBDL: %d", CurrentBDL, LastBDL);
|
||||||
}
|
}
|
||||||
else if (Status & TC_LastBufferEntryInterruptEnable)
|
else if (Status & TC_LastBufferEntryInterruptEnable)
|
||||||
{
|
{
|
||||||
@ -577,7 +578,7 @@ public:
|
|||||||
}
|
}
|
||||||
else if (Status & TC_FifoERRORInterruptEnable)
|
else if (Status & TC_FifoERRORInterruptEnable)
|
||||||
{
|
{
|
||||||
Log("FIFO error");
|
KernelLog("FIFO error");
|
||||||
outw(MixerAddress + PCMOUT_Status, TC_FifoERRORInterruptEnable);
|
outw(MixerAddress + PCMOUT_Status, TC_FifoERRORInterruptEnable);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -689,7 +690,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
AC97Device *Drivers[4] = {nullptr};
|
AC97Device *Drivers[4] = {nullptr};
|
||||||
dev_t AudioID[4] = {0};
|
dev_t AudioID[4] = {(dev_t)-1};
|
||||||
|
|
||||||
#define OIR(x) OIR_##x
|
#define OIR(x) OIR_##x
|
||||||
#define CREATE_OIR(x) \
|
#define CREATE_OIR(x) \
|
||||||
@ -700,20 +701,40 @@ CREATE_OIR(1);
|
|||||||
CREATE_OIR(2);
|
CREATE_OIR(2);
|
||||||
CREATE_OIR(3);
|
CREATE_OIR(3);
|
||||||
|
|
||||||
int drvOpen(dev_t, dev_t, int, mode_t) { return 0; }
|
int __fs_Open(struct Inode *, int, mode_t) { return 0; }
|
||||||
int drvClose(dev_t, dev_t) { return 0; }
|
int __fs_Close(struct Inode *) { return 0; }
|
||||||
size_t drvRead(dev_t, dev_t, uint8_t *, size_t, off_t) { return 0; }
|
ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; }
|
||||||
|
|
||||||
size_t drvWrite(dev_t, dev_t min, uint8_t *Buffer, size_t Size, off_t)
|
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t)
|
||||||
{
|
{
|
||||||
return Drivers[AudioID[min]]->write(Buffer, Size);
|
return Drivers[AudioID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int drvIoctl(dev_t, dev_t min, unsigned long Request, void *Argp)
|
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
|
||||||
{
|
{
|
||||||
return Drivers[AudioID[min]]->ioctl((AudioIoctl)Request, Argp);
|
return Drivers[AudioID[Node->GetMinor()]]->ioctl((AudioIoctl)Request, Argp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct InodeOperations AudioOps = {
|
||||||
|
.Lookup = nullptr,
|
||||||
|
.Create = nullptr,
|
||||||
|
.Remove = nullptr,
|
||||||
|
.Rename = nullptr,
|
||||||
|
.Read = __fs_Read,
|
||||||
|
.Write = __fs_Write,
|
||||||
|
.Truncate = nullptr,
|
||||||
|
.Open = __fs_Open,
|
||||||
|
.Close = __fs_Close,
|
||||||
|
.Ioctl = __fs_Ioctl,
|
||||||
|
.ReadDir = nullptr,
|
||||||
|
.MkDir = nullptr,
|
||||||
|
.RmDir = nullptr,
|
||||||
|
.SymLink = nullptr,
|
||||||
|
.ReadLink = nullptr,
|
||||||
|
.Seek = nullptr,
|
||||||
|
.Stat = nullptr,
|
||||||
|
};
|
||||||
|
|
||||||
PCIArray *Devices;
|
PCIArray *Devices;
|
||||||
EXTERNC int cxx_Panic()
|
EXTERNC int cxx_Panic()
|
||||||
{
|
{
|
||||||
@ -734,10 +755,10 @@ EXTERNC int cxx_Probe()
|
|||||||
{
|
{
|
||||||
uint16_t VendorIDs[] = {0x8086, PCI_END};
|
uint16_t VendorIDs[] = {0x8086, PCI_END};
|
||||||
uint16_t DeviceIDs[] = {0x2415, PCI_END};
|
uint16_t DeviceIDs[] = {0x2415, PCI_END};
|
||||||
Devices = FindPCIDevices(VendorIDs, DeviceIDs);
|
Devices = GetPCIDevices(VendorIDs, DeviceIDs);
|
||||||
if (Devices == nullptr)
|
if (Devices == nullptr)
|
||||||
{
|
{
|
||||||
Log("No AC'97 device found.");
|
KernelLog("No AC'97 device found.");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,10 +775,10 @@ EXTERNC int cxx_Probe()
|
|||||||
uint8_t Type = PCIBAR0 & 1;
|
uint8_t Type = PCIBAR0 & 1;
|
||||||
if (Type != 1)
|
if (Type != 1)
|
||||||
{
|
{
|
||||||
Log("Device %x:%x.%d BAR0 is not I/O.",
|
KernelLog("Device %x:%x.%d BAR0 is not I/O.",
|
||||||
PCIBaseAddress->Header.VendorID,
|
PCIBaseAddress->Header.VendorID,
|
||||||
PCIBaseAddress->Header.DeviceID,
|
PCIBaseAddress->Header.DeviceID,
|
||||||
PCIBaseAddress->Header.ProgIF);
|
PCIBaseAddress->Header.ProgIF);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,7 +788,7 @@ EXTERNC int cxx_Probe()
|
|||||||
|
|
||||||
if (!Found)
|
if (!Found)
|
||||||
{
|
{
|
||||||
Log("No valid AC'97 device found.");
|
KernelLog("No valid AC'97 device found.");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -787,10 +808,10 @@ EXTERNC int cxx_Initialize()
|
|||||||
uint8_t Type = PCIBAR0 & 1;
|
uint8_t Type = PCIBAR0 & 1;
|
||||||
if (Type != 1)
|
if (Type != 1)
|
||||||
{
|
{
|
||||||
Log("Device %x:%x.%d BAR0 is not I/O.",
|
KernelLog("Device %x:%x.%d BAR0 is not I/O.",
|
||||||
PCIBaseAddress->Header.VendorID,
|
PCIBaseAddress->Header.VendorID,
|
||||||
PCIBaseAddress->Header.DeviceID,
|
PCIBaseAddress->Header.DeviceID,
|
||||||
PCIBaseAddress->Header.ProgIF);
|
PCIBaseAddress->Header.ProgIF);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,10 +836,7 @@ EXTERNC int cxx_Initialize()
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dev_t ret = RegisterAudioDevice(ddt_Audio,
|
dev_t ret = RegisterDevice(AUDIO_TYPE_PCM, &AudioOps);
|
||||||
drvOpen, drvClose,
|
|
||||||
drvRead, drvWrite,
|
|
||||||
drvIoctl);
|
|
||||||
AudioID[Count] = ret;
|
AudioID[Count] = ret;
|
||||||
Count++;
|
Count++;
|
||||||
ctx = (PCIArray *)ctx->Next;
|
ctx = (PCIArray *)ctx->Next;
|
||||||
@ -841,10 +859,10 @@ EXTERNC int cxx_Finalize()
|
|||||||
uint8_t Type = PCIBAR0 & 1;
|
uint8_t Type = PCIBAR0 & 1;
|
||||||
if (Type != 1)
|
if (Type != 1)
|
||||||
{
|
{
|
||||||
Log("Device %x:%x.%d BAR0 is not I/O.",
|
KernelLog("Device %x:%x.%d BAR0 is not I/O.",
|
||||||
PCIBaseAddress->Header.VendorID,
|
PCIBaseAddress->Header.VendorID,
|
||||||
PCIBaseAddress->Header.DeviceID,
|
PCIBaseAddress->Header.DeviceID,
|
||||||
PCIBaseAddress->Header.ProgIF);
|
PCIBaseAddress->Header.ProgIF);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -853,5 +871,11 @@ EXTERNC int cxx_Finalize()
|
|||||||
ctx = (PCIArray *)ctx->Next;
|
ctx = (PCIArray *)ctx->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(AudioID) / sizeof(dev_t); i++)
|
||||||
|
{
|
||||||
|
if (AudioID[i] != (dev_t)-1)
|
||||||
|
UnregisterDevice(AudioID[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -27,5 +27,5 @@ int DriverProbe() { return cxx_Probe(); }
|
|||||||
DriverInfo("ac97",
|
DriverInfo("ac97",
|
||||||
"Audio Codec '97 Driver",
|
"Audio Codec '97 Driver",
|
||||||
"EnderIce2",
|
"EnderIce2",
|
||||||
"0.1",
|
0, 0, 1,
|
||||||
"GPLv3");
|
"GPLv3");
|
||||||
|
@ -1,83 +1,22 @@
|
|||||||
# Config file
|
# Config files
|
||||||
include ../../../Makefile.conf
|
include ../../../Makefile.conf
|
||||||
|
include ../../config.mk
|
||||||
FILENAME = hda.drv
|
|
||||||
|
|
||||||
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
|
||||||
CPP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
|
||||||
LD = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
|
||||||
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
|
||||||
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
|
||||||
|
|
||||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||||
INCLUDE_DIR = ../../include
|
|
||||||
|
|
||||||
LIBS := ../../out/dcrt0.o -L../../out -ldriver
|
FILENAME = hda.drv
|
||||||
|
|
||||||
LDFLAGS := \
|
|
||||||
-fPIC -fPIE -pie \
|
|
||||||
-Wl,--no-dynamic-linker,-ztext,--no-warn-rwx-segment \
|
|
||||||
-nostdlib -nodefaultlibs -nolibc \
|
|
||||||
-zmax-page-size=0x1000 \
|
|
||||||
-Wl,-Map file.map -shared -fvisibility=hidden
|
|
||||||
|
|
||||||
WARNCFLAG = -Wall -Wextra
|
|
||||||
|
|
||||||
CFLAGS := -I$(INCLUDE_DIR) -fvisibility=hidden
|
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 \
|
|
||||||
-march=x86-64 -pipe -ffunction-sections \
|
|
||||||
-msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), i386)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
|
|
||||||
-march=i386 -pipe -msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), aarch64)
|
|
||||||
|
|
||||||
CFLAGS += -pipe -fno-builtin -fPIC
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(DEBUG), 1)
|
|
||||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
CFLAGS += -fverbose-asm
|
|
||||||
endif
|
|
||||||
ifneq ($(OSARCH), aarch64)
|
|
||||||
CFLAGS += -fstack-check
|
|
||||||
endif
|
|
||||||
LDFLAGS += -ggdb3 -O0
|
|
||||||
endif
|
|
||||||
|
|
||||||
build: $(FILENAME)
|
build: $(FILENAME)
|
||||||
mv $(FILENAME) ../../out/$(FILENAME)
|
mv $(FILENAME) ../../out/$(FILENAME)
|
||||||
|
|
||||||
$(FILENAME): $(OBJ)
|
$(FILENAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
$(CC) $(LDFLAGS) $(OBJ) $(LIBS) -o $@
|
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||||
|
|
||||||
%.o: %.c $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CC) $(CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.cpp $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CPP) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.S
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(AS) -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <base.h>
|
#include <base.h>
|
||||||
#include <pci.h>
|
#include <pci.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
#include <fs.h>
|
||||||
|
|
||||||
#include "hda.hpp"
|
#include "hda.hpp"
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ public:
|
|||||||
RIRB((uint64_t *)AllocateMemory(1))
|
RIRB((uint64_t *)AllocateMemory(1))
|
||||||
{
|
{
|
||||||
CTL = (ControllerRegisters *)(uintptr_t)Header->BAR0;
|
CTL = (ControllerRegisters *)(uintptr_t)Header->BAR0;
|
||||||
Log("Unimplemented HDA driver");
|
KernelLog("Unimplemented HDA driver");
|
||||||
return;
|
return;
|
||||||
Initialized = true;
|
Initialized = true;
|
||||||
}
|
}
|
||||||
@ -75,7 +76,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
HDADevice *Drivers[4] = {nullptr};
|
HDADevice *Drivers[4] = {nullptr};
|
||||||
dev_t AudioID[4] = {0};
|
dev_t AudioID[4] = {(dev_t)-1};
|
||||||
|
|
||||||
#define OIR(x) OIR_##x
|
#define OIR(x) OIR_##x
|
||||||
#define CREATE_OIR(x) \
|
#define CREATE_OIR(x) \
|
||||||
@ -86,20 +87,40 @@ CREATE_OIR(1);
|
|||||||
CREATE_OIR(2);
|
CREATE_OIR(2);
|
||||||
CREATE_OIR(3);
|
CREATE_OIR(3);
|
||||||
|
|
||||||
int drvOpen(dev_t, dev_t, int, mode_t) { return 0; }
|
int __fs_Open(struct Inode *, int, mode_t) { return 0; }
|
||||||
int drvClose(dev_t, dev_t) { return 0; }
|
int __fs_Close(struct Inode *) { return 0; }
|
||||||
size_t drvRead(dev_t, dev_t, uint8_t *, size_t, off_t) { return 0; }
|
ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; }
|
||||||
|
|
||||||
size_t drvWrite(dev_t, dev_t min, uint8_t *Buffer, size_t Size, off_t)
|
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t)
|
||||||
{
|
{
|
||||||
return Drivers[AudioID[min]]->write(Buffer, Size);
|
return Drivers[AudioID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int drvIoctl(dev_t, dev_t min, unsigned long Request, void *Argp)
|
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
|
||||||
{
|
{
|
||||||
return Drivers[AudioID[min]]->ioctl((AudioIoctl)Request, Argp);
|
return Drivers[AudioID[Node->GetMinor()]]->ioctl((AudioIoctl)Request, Argp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct InodeOperations AudioOps = {
|
||||||
|
.Lookup = nullptr,
|
||||||
|
.Create = nullptr,
|
||||||
|
.Remove = nullptr,
|
||||||
|
.Rename = nullptr,
|
||||||
|
.Read = __fs_Read,
|
||||||
|
.Write = __fs_Write,
|
||||||
|
.Truncate = nullptr,
|
||||||
|
.Open = __fs_Open,
|
||||||
|
.Close = __fs_Close,
|
||||||
|
.Ioctl = __fs_Ioctl,
|
||||||
|
.ReadDir = nullptr,
|
||||||
|
.MkDir = nullptr,
|
||||||
|
.RmDir = nullptr,
|
||||||
|
.SymLink = nullptr,
|
||||||
|
.ReadLink = nullptr,
|
||||||
|
.Seek = nullptr,
|
||||||
|
.Stat = nullptr,
|
||||||
|
};
|
||||||
|
|
||||||
PCIArray *Devices;
|
PCIArray *Devices;
|
||||||
EXTERNC int cxx_Panic()
|
EXTERNC int cxx_Panic()
|
||||||
{
|
{
|
||||||
@ -125,10 +146,10 @@ EXTERNC int cxx_Probe()
|
|||||||
0x2668 /* ICH6 */,
|
0x2668 /* ICH6 */,
|
||||||
0x293E /* ICH9 */,
|
0x293E /* ICH9 */,
|
||||||
PCI_END};
|
PCI_END};
|
||||||
Devices = FindPCIDevices(VendorIDs, DeviceIDs);
|
Devices = GetPCIDevices(VendorIDs, DeviceIDs);
|
||||||
if (Devices == nullptr)
|
if (Devices == nullptr)
|
||||||
{
|
{
|
||||||
Log("No HDA device found.");
|
KernelLog("No HDA device found.");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,10 +166,10 @@ EXTERNC int cxx_Probe()
|
|||||||
uint8_t Type = PCIBAR0 & 1;
|
uint8_t Type = PCIBAR0 & 1;
|
||||||
if (Type == 1)
|
if (Type == 1)
|
||||||
{
|
{
|
||||||
Log("Device %x:%x.%d BAR0 is I/O.",
|
KernelLog("Device %x:%x.%d BAR0 is I/O.",
|
||||||
PCIBaseAddress->Header.VendorID,
|
PCIBaseAddress->Header.VendorID,
|
||||||
PCIBaseAddress->Header.DeviceID,
|
PCIBaseAddress->Header.DeviceID,
|
||||||
PCIBaseAddress->Header.ProgIF);
|
PCIBaseAddress->Header.ProgIF);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +179,7 @@ EXTERNC int cxx_Probe()
|
|||||||
|
|
||||||
if (!Found)
|
if (!Found)
|
||||||
{
|
{
|
||||||
Log("No valid HDA device found.");
|
KernelLog("No valid HDA device found.");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -178,10 +199,10 @@ EXTERNC int cxx_Initialize()
|
|||||||
uint8_t Type = PCIBAR0 & 1;
|
uint8_t Type = PCIBAR0 & 1;
|
||||||
if (Type == 1)
|
if (Type == 1)
|
||||||
{
|
{
|
||||||
Log("Device %x:%x.%d BAR0 is I/O.",
|
KernelLog("Device %x:%x.%d BAR0 is I/O.",
|
||||||
PCIBaseAddress->Header.VendorID,
|
PCIBaseAddress->Header.VendorID,
|
||||||
PCIBaseAddress->Header.DeviceID,
|
PCIBaseAddress->Header.DeviceID,
|
||||||
PCIBaseAddress->Header.ProgIF);
|
PCIBaseAddress->Header.ProgIF);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,10 +212,7 @@ EXTERNC int cxx_Initialize()
|
|||||||
|
|
||||||
if (Drivers[Count]->IsInitialized())
|
if (Drivers[Count]->IsInitialized())
|
||||||
{
|
{
|
||||||
dev_t ret = RegisterAudioDevice(ddt_Audio,
|
dev_t ret = RegisterDevice(AUDIO_TYPE_PCM, &AudioOps);
|
||||||
drvOpen, drvClose,
|
|
||||||
drvRead, drvWrite,
|
|
||||||
drvIoctl);
|
|
||||||
AudioID[Count] = ret;
|
AudioID[Count] = ret;
|
||||||
Count++;
|
Count++;
|
||||||
}
|
}
|
||||||
@ -203,7 +221,7 @@ EXTERNC int cxx_Initialize()
|
|||||||
|
|
||||||
if (Count == 0)
|
if (Count == 0)
|
||||||
{
|
{
|
||||||
Log("No valid HDA device found.");
|
KernelLog("No valid HDA device found.");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,10 +242,10 @@ EXTERNC int cxx_Finalize()
|
|||||||
uint8_t Type = PCIBAR0 & 1;
|
uint8_t Type = PCIBAR0 & 1;
|
||||||
if (Type == 1)
|
if (Type == 1)
|
||||||
{
|
{
|
||||||
Log("Device %x:%x.%d BAR0 is I/O.",
|
KernelLog("Device %x:%x.%d BAR0 is I/O.",
|
||||||
PCIBaseAddress->Header.VendorID,
|
PCIBaseAddress->Header.VendorID,
|
||||||
PCIBaseAddress->Header.DeviceID,
|
PCIBaseAddress->Header.DeviceID,
|
||||||
PCIBaseAddress->Header.ProgIF);
|
PCIBaseAddress->Header.ProgIF);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,5 +253,11 @@ EXTERNC int cxx_Finalize()
|
|||||||
ctx = (PCIArray *)ctx->Next;
|
ctx = (PCIArray *)ctx->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(AudioID) / sizeof(dev_t); i++)
|
||||||
|
{
|
||||||
|
if (AudioID[i] != (dev_t)-1)
|
||||||
|
UnregisterDevice(AudioID[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -27,5 +27,5 @@ int DriverProbe() { return cxx_Probe(); }
|
|||||||
DriverInfo("hda",
|
DriverInfo("hda",
|
||||||
"Intel High Definition Audio Driver",
|
"Intel High Definition Audio Driver",
|
||||||
"EnderIce2",
|
"EnderIce2",
|
||||||
"0.1",
|
0, 0, 1,
|
||||||
"GPLv3");
|
"GPLv3");
|
||||||
|
54
config.mk
Normal file
54
config.mk
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
||||||
|
CPP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
||||||
|
LD = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
||||||
|
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
||||||
|
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
||||||
|
|
||||||
|
DRIVER_LDFLAGS := -nostdlib -nodefaultlibs -nolibc -zmax-page-size=0x1000 \
|
||||||
|
-Wl,-Map file.map -fvisibility=hidden -Wl,--dynamic-linker=/boot/fennix.elf
|
||||||
|
|
||||||
|
ifeq ($(OSARCH), amd64)
|
||||||
|
|
||||||
|
DRIVER_CFLAGS := -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
||||||
|
-mno-red-zone -mno-sse -mno-sse2 \
|
||||||
|
-march=x86-64 -pipe -ffunction-sections \
|
||||||
|
-msoft-float -fno-builtin
|
||||||
|
|
||||||
|
else ifeq ($(OSARCH), i386)
|
||||||
|
|
||||||
|
DRIVER_CFLAGS := -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
||||||
|
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
|
||||||
|
-march=i386 -pipe -msoft-float -fno-builtin
|
||||||
|
|
||||||
|
else ifeq ($(OSARCH), aarch64)
|
||||||
|
|
||||||
|
DRIVER_CFLAGS += -pipe -fno-builtin -fPIC
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
DRIVER_CFLAGS += -I../../include
|
||||||
|
|
||||||
|
ifeq ($(DEBUG), 1)
|
||||||
|
DRIVER_CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
||||||
|
ifeq ($(OSARCH), amd64)
|
||||||
|
DRIVER_CFLAGS += -fverbose-asm
|
||||||
|
endif
|
||||||
|
ifneq ($(OSARCH), aarch64)
|
||||||
|
DRIVER_CFLAGS += -fstack-check
|
||||||
|
endif
|
||||||
|
DRIVER_LDFLAGS += -ggdb3 -O0
|
||||||
|
endif
|
||||||
|
|
||||||
|
WARNCFLAG = -Wall -Wextra
|
||||||
|
|
||||||
|
%.o: %.c $(HEADERS)
|
||||||
|
$(info Compiling $<)
|
||||||
|
$(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
|
||||||
|
|
||||||
|
%.o: %.cpp $(HEADERS)
|
||||||
|
$(info Compiling $<)
|
||||||
|
$(CPP) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
|
||||||
|
|
||||||
|
%.o: %.S
|
||||||
|
$(info Compiling $<)
|
||||||
|
$(AS) -o $@ $<
|
@ -46,5 +46,5 @@ int DriverProbe()
|
|||||||
DriverInfo("name",
|
DriverInfo("name",
|
||||||
"description",
|
"description",
|
||||||
"author",
|
"author",
|
||||||
"version",
|
0, 0, 0,
|
||||||
"license");
|
"license");
|
||||||
|
5
filesystem/Makefile
Normal file
5
filesystem/Makefile
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
build:
|
||||||
|
make -C fat build
|
||||||
|
|
||||||
|
clean:
|
||||||
|
make -C fat clean
|
22
filesystem/fat/Makefile
Normal file
22
filesystem/fat/Makefile
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Config files
|
||||||
|
include ../../../Makefile.conf
|
||||||
|
include ../../config.mk
|
||||||
|
|
||||||
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
|
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||||
|
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||||
|
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||||
|
|
||||||
|
FILENAME = fat.drv
|
||||||
|
|
||||||
|
build: $(FILENAME)
|
||||||
|
mv $(FILENAME) ../../out/$(FILENAME)
|
||||||
|
|
||||||
|
$(FILENAME): $(OBJ)
|
||||||
|
$(info Linking $@)
|
||||||
|
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
290
filesystem/fat/fat.h
Normal file
290
filesystem/fat/fat.h
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
/*
|
||||||
|
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_DRIVER_FAT_H__
|
||||||
|
#define __FENNIX_DRIVER_FAT_H__
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
/* Source: https://wiki.osdev.org/FAT */
|
||||||
|
|
||||||
|
struct BIOSParameterBlock
|
||||||
|
{
|
||||||
|
/** The first three bytes EB 3C 90 disassemble to JMP SHORT 3C NOP.
|
||||||
|
* (The 3C value may be different.) The reason for this is to jump
|
||||||
|
* over the disk format information (the BPB and EBPB). Since the
|
||||||
|
* first sector of the disk is loaded into ram at location
|
||||||
|
* 0x0000:0x7c00 and executed, without this jump, the processor
|
||||||
|
* would attempt to execute data that isn't code. Even for
|
||||||
|
* non-bootable volumes, code matching this pattern (or using the
|
||||||
|
* E9 jump opcode) is required to be present by both Windows and
|
||||||
|
* OS X. To fulfil this requirement, an infinite loop can be placed
|
||||||
|
* here with the bytes EB FE 90. */
|
||||||
|
uint8_t JumpBoot[3];
|
||||||
|
|
||||||
|
/** OEM identifier. The first 8 Bytes (3 - 10) is the version of DOS
|
||||||
|
* being used. The next eight Bytes 29 3A 63 7E 2D 49 48 and 43 read
|
||||||
|
* out the name of the version. The official FAT Specification from
|
||||||
|
* Microsoft says that this field is really meaningless and is ignored
|
||||||
|
* by MS FAT Modules, however it does recommend the value "MSWIN4.1"
|
||||||
|
* as some 3rd party drivers supposedly check it and expect it to
|
||||||
|
* have that value. Older versions of dos also report MSDOS5.1,
|
||||||
|
* linux-formatted floppy will likely to carry "mkdosfs" here, and
|
||||||
|
* FreeDOS formatted disks have been observed to have "FRDOS5.1" here.
|
||||||
|
* If the string is less than 8 bytes, it is padded with spaces. */
|
||||||
|
uint8_t OEM[8];
|
||||||
|
|
||||||
|
/** The number of Bytes per sector (remember, all numbers are in the
|
||||||
|
* little-endian format). */
|
||||||
|
uint16_t BytesPerSector;
|
||||||
|
|
||||||
|
/** Number of sectors per cluster. */
|
||||||
|
uint8_t SectorsPerCluster;
|
||||||
|
|
||||||
|
/** Number of reserved sectors. The boot record sectors are included
|
||||||
|
* in this value. */
|
||||||
|
uint16_t ReservedSectors;
|
||||||
|
|
||||||
|
/** Number of File Allocation Tables (FAT's) on the storage media.
|
||||||
|
* Often this value is 2. */
|
||||||
|
uint8_t NumberOfFATs;
|
||||||
|
|
||||||
|
/** Number of root directory entries (must be set so that the root
|
||||||
|
* directory occupies entire sectors). */
|
||||||
|
uint16_t RootDirectoryEntries;
|
||||||
|
|
||||||
|
/** The total sectors in the logical volume. If this value is 0, it
|
||||||
|
* means there are more than 65535 sectors in the volume, and the
|
||||||
|
* actual count is stored in the Large Sector Count entry at 0x20. */
|
||||||
|
uint16_t Sectors16;
|
||||||
|
|
||||||
|
/** This Byte indicates the media descriptor type. */
|
||||||
|
uint8_t Media;
|
||||||
|
|
||||||
|
/** Number of sectors per FAT. FAT12/FAT16 only. */
|
||||||
|
uint16_t SectorsPerFAT;
|
||||||
|
|
||||||
|
/** Number of sectors per track. */
|
||||||
|
uint16_t SectorsPerTrack;
|
||||||
|
|
||||||
|
/** Number of heads or sides on the storage media. */
|
||||||
|
uint16_t NumberOfHeads;
|
||||||
|
|
||||||
|
/** Number of hidden sectors. (i.e. the LBA of the beginning of
|
||||||
|
* the partition). */
|
||||||
|
uint32_t HiddenSectors;
|
||||||
|
|
||||||
|
/** Large sector count. This field is set if there are more than
|
||||||
|
* 65535 sectors in the volume, resulting in a value which does not
|
||||||
|
* fit in the Number of Sectors entry at 0x13. */
|
||||||
|
uint32_t Sectors32;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct ExtendedBootRecord_FAT12_16
|
||||||
|
{
|
||||||
|
/** Drive number. The value here should be identical to the value
|
||||||
|
* returned by BIOS interrupt 0x13, or passed in the DL register;
|
||||||
|
* i.e. 0x00 for a floppy disk and 0x80 for hard disks. This number
|
||||||
|
* is useless because the media is likely to be moved to another
|
||||||
|
* machine and inserted in a drive with a different drive number. */
|
||||||
|
uint8_t DriveNumber;
|
||||||
|
|
||||||
|
/** Flags in Windows NT. Reserved otherwise. */
|
||||||
|
uint8_t Flags;
|
||||||
|
|
||||||
|
/** Signature (must be 0x28 or 0x29). */
|
||||||
|
uint8_t Signature;
|
||||||
|
|
||||||
|
/** VolumeID 'Serial' number. Used for tracking volumes between
|
||||||
|
* computers. You can ignore this if you want. */
|
||||||
|
uint32_t VolumeID;
|
||||||
|
|
||||||
|
/** Volume label string. This field is padded with spaces. */
|
||||||
|
uint8_t VolumeLabel[11];
|
||||||
|
|
||||||
|
/** System identifier string. This field is a string representation
|
||||||
|
* of the FAT file system type. It is padded with spaces. The spec
|
||||||
|
* says never to trust the contents of this string for any use. */
|
||||||
|
uint8_t SystemIdentifier[8];
|
||||||
|
|
||||||
|
/** Boot code. */
|
||||||
|
uint8_t BootCode[448];
|
||||||
|
|
||||||
|
/** Bootable partition signature 0xAA55. */
|
||||||
|
uint16_t BootSignature;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct ExtendedBootRecord_FAT32
|
||||||
|
{
|
||||||
|
/** Sectors per FAT. The size of the FAT in sectors. */
|
||||||
|
uint32_t SectorsPerFAT;
|
||||||
|
|
||||||
|
/** Flags. */
|
||||||
|
uint16_t Flags;
|
||||||
|
|
||||||
|
/** FAT version number. The high byte is the major version and the
|
||||||
|
* low byte is the minor version. FAT drivers should respect this
|
||||||
|
* field. */
|
||||||
|
uint16_t FATVersion;
|
||||||
|
|
||||||
|
/** The cluster number of the root directory. Often this field is
|
||||||
|
* set to 2. */
|
||||||
|
uint32_t RootDirectoryCluster;
|
||||||
|
|
||||||
|
/** The sector number of the FSInfo structure. */
|
||||||
|
uint16_t FSInfoSector;
|
||||||
|
|
||||||
|
/** The sector number of the backup boot sector. */
|
||||||
|
uint16_t BackupBootSector;
|
||||||
|
|
||||||
|
/** Reserved. When the volume is formated these bytes should be zero. */
|
||||||
|
uint8_t Reserved[12];
|
||||||
|
|
||||||
|
/** Drive number. The values here are identical to the values returned
|
||||||
|
* by the BIOS interrupt 0x13. 0x00 for a floppy disk and 0x80 for
|
||||||
|
* hard disks. */
|
||||||
|
uint8_t DriveNumber;
|
||||||
|
|
||||||
|
/** Flags in Windows NT. Reserved otherwise. */
|
||||||
|
uint8_t Flags2;
|
||||||
|
|
||||||
|
/** Signature (must be 0x28 or 0x29). */
|
||||||
|
uint8_t Signature;
|
||||||
|
|
||||||
|
/** Volume ID 'Serial' number. Used for tracking volumes between
|
||||||
|
* computers. You can ignore this if you want. */
|
||||||
|
uint32_t VolumeID;
|
||||||
|
|
||||||
|
/** Volume label string. This field is padded with spaces. */
|
||||||
|
uint8_t VolumeLabel[11];
|
||||||
|
|
||||||
|
/** System identifier string. Always "FAT32 ". The spec says never
|
||||||
|
* to trust the contents of this string for any use. */
|
||||||
|
uint8_t SystemIdentifier[8];
|
||||||
|
|
||||||
|
/** Boot code. */
|
||||||
|
uint8_t BootCode[420];
|
||||||
|
|
||||||
|
/** Bootable partition signature 0xAA55. */
|
||||||
|
uint16_t BootSignature;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct FSInfo
|
||||||
|
{
|
||||||
|
/** Lead signature (must be 0x41615252 to indicate a valid FSInfo
|
||||||
|
* structure). */
|
||||||
|
uint32_t LeadSignature;
|
||||||
|
|
||||||
|
/** Reserved, these bytes should never be used. */
|
||||||
|
uint8_t Reserved1[480];
|
||||||
|
|
||||||
|
/** Another signature (must be 0x61417272). */
|
||||||
|
uint32_t AnotherSignature;
|
||||||
|
|
||||||
|
/** Contains the last known free cluster count on the volume. If the
|
||||||
|
* value is 0xFFFFFFFF, then the free count is unknown and must be
|
||||||
|
* computed. However, this value might be incorrect and should at
|
||||||
|
* least be range checked (<= volume cluster count). */
|
||||||
|
uint32_t FreeClusterCount;
|
||||||
|
|
||||||
|
/** Indicates the cluster number at which the filesystem driver should
|
||||||
|
* start looking for available clusters. If the value is 0xFFFFFFFF,
|
||||||
|
* then there is no hint and the driver should start searching at 2.
|
||||||
|
* Typically this value is set to the last allocated cluster number.
|
||||||
|
* As the previous field, this value should be range checked. */
|
||||||
|
uint32_t NextFreeCluster;
|
||||||
|
|
||||||
|
/** Reserved. */
|
||||||
|
uint8_t Reserved2[12];
|
||||||
|
|
||||||
|
/** Trail signature (0xAA550000). */
|
||||||
|
uint32_t TrailSignature;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
struct exFATBootRecord
|
||||||
|
{
|
||||||
|
/** The first three bytes EB 3C 90 disassemble to JMP SHORT 3C NOP.
|
||||||
|
* (The 3C value may be different.) The reason for this is to jump
|
||||||
|
* over the disk format information (the BPB and EBPB). Since the
|
||||||
|
* first sector of the disk is loaded into ram at location
|
||||||
|
* 0x0000:0x7c00 and executed, without this jump, the processor
|
||||||
|
* would attempt to execute data that isn't code. Even for
|
||||||
|
* non-bootable volumes, code matching this pattern (or using the
|
||||||
|
* E9 jump opcode) is required to be present by both Windows and
|
||||||
|
* OS X. To fulfil this requirement, an infinite loop can be placed
|
||||||
|
* here with the bytes EB FE 90. */
|
||||||
|
uint8_t JumpBoot[3];
|
||||||
|
|
||||||
|
/** OEM identifier. This contains the string "EXFAT ". Not to be
|
||||||
|
* used for filesystem determination, but it's a nice hint. */
|
||||||
|
uint8_t OEM[8];
|
||||||
|
|
||||||
|
/** Set to zero. This makes sure any FAT driver will not be able to
|
||||||
|
* load it. */
|
||||||
|
uint8_t Reserved1[53];
|
||||||
|
|
||||||
|
/** Partition offset. No idea why the partition itself would have
|
||||||
|
* this, but it's here. Might be wrong. Probably best to just ignore. */
|
||||||
|
uint64_t PartitionOffset;
|
||||||
|
|
||||||
|
/** Volume length. */
|
||||||
|
uint64_t VolumeLength;
|
||||||
|
|
||||||
|
/** FAT offset (in sectors) from start of partition. */
|
||||||
|
uint32_t FATOffset;
|
||||||
|
|
||||||
|
/** FAT length (in sectors). */
|
||||||
|
uint32_t FATLength;
|
||||||
|
|
||||||
|
/** Cluster heap offset (in sectors). */
|
||||||
|
uint32_t ClusterHeapOffset;
|
||||||
|
|
||||||
|
/** Cluster count. */
|
||||||
|
uint32_t ClusterCount;
|
||||||
|
|
||||||
|
/** Root directory cluster. Typically 4 (but just read this value). */
|
||||||
|
uint32_t RootDirectoryCluster;
|
||||||
|
|
||||||
|
/** Serial number of partition. */
|
||||||
|
uint32_t SerialNumber;
|
||||||
|
|
||||||
|
/** Filesystem revision. */
|
||||||
|
uint16_t FilesystemRevision;
|
||||||
|
|
||||||
|
/** Flags. */
|
||||||
|
uint16_t Flags;
|
||||||
|
|
||||||
|
/** Sector shift. */
|
||||||
|
uint8_t SectorShift;
|
||||||
|
|
||||||
|
/** Cluster shift. */
|
||||||
|
uint8_t ClusterShift;
|
||||||
|
|
||||||
|
/** Number of FATs. */
|
||||||
|
uint8_t NumberOfFATs;
|
||||||
|
|
||||||
|
/** Drive select. */
|
||||||
|
uint8_t DriveSelect;
|
||||||
|
|
||||||
|
/** Percentage in use. */
|
||||||
|
uint8_t PercentageInUse;
|
||||||
|
|
||||||
|
/** Reserved (set to 0). */
|
||||||
|
uint8_t Reserved2[7];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
#endif // !__FENNIX_DRIVER_FAT_H__
|
@ -15,11 +15,31 @@
|
|||||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __FENNIX_API_VM_H__
|
#include <base.h>
|
||||||
#define __FENNIX_API_VM_H__
|
|
||||||
|
|
||||||
#include <types.h>
|
int DriverEntry()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsVMwareBackdoorAvailable();
|
int DriverFinal()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // !__FENNIX_API_VM_H__
|
int DriverPanic()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DriverProbe()
|
||||||
|
{
|
||||||
|
/* Nothing to do */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DriverInfo("fat",
|
||||||
|
"File Allocation Table Driver",
|
||||||
|
"EnderIce2",
|
||||||
|
0, 0, 1,
|
||||||
|
"GPLv3");
|
144
include/aip.h
144
include/aip.h
@ -19,8 +19,6 @@
|
|||||||
#define __FENNIX_API_AIP_H__
|
#define __FENNIX_API_AIP_H__
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <aip/kbd.h>
|
|
||||||
#include <aip/mouse.h>
|
|
||||||
|
|
||||||
#define PIC1_CMD 0x20
|
#define PIC1_CMD 0x20
|
||||||
#define PIC1_DATA (PIC1_CMD + 1)
|
#define PIC1_DATA (PIC1_CMD + 1)
|
||||||
@ -117,7 +115,145 @@ uint8_t PS2ReadAfterACK();
|
|||||||
void PS2ClearOutputBuffer();
|
void PS2ClearOutputBuffer();
|
||||||
int PS2ACKTimeout();
|
int PS2ACKTimeout();
|
||||||
|
|
||||||
#define WaitOutput PS2Wait(true)
|
#define WaitOutput PS2Wait(DriverID, true)
|
||||||
#define WaitInput PS2Wait(false)
|
#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__
|
#endif // !__FENNIX_API_AIP_H__
|
||||||
|
@ -1,45 +1,29 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of Fennix Drivers.
|
This file is part of Fennix Kernel.
|
||||||
|
|
||||||
Fennix Drivers is free software: you can redistribute it and/or
|
Fennix Kernel is free software: you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License as
|
modify it under the terms of the GNU General Public License as
|
||||||
published by the Free Software Foundation, either version 3 of
|
published by the Free Software Foundation, either version 3 of
|
||||||
the License, or (at your option) any later version.
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
Fennix Drivers is distributed in the hope that it will be useful,
|
Fennix Kernel is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __FENNIX_API_AUDIO_H__
|
#ifndef __FENNIX_API_AUDIO_H__
|
||||||
#define __FENNIX_API_AUDIO_H__
|
#define __FENNIX_API_AUDIO_H__
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <driver.h>
|
|
||||||
|
|
||||||
typedef int (*drvOpen_t)(dev_t, dev_t, int, mode_t);
|
#if __has_include(<interface/device.h>)
|
||||||
typedef int (*drvClose_t)(dev_t, dev_t);
|
#include <interface/device.h>
|
||||||
typedef size_t (*drvRead_t)(dev_t, dev_t, uint8_t *, size_t, off_t);
|
#else
|
||||||
typedef size_t (*drvWrite_t)(dev_t, dev_t, uint8_t *, size_t, off_t);
|
#include <device.h>
|
||||||
typedef int (*drvIoctl_t)(dev_t, dev_t, unsigned long, void *);
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
dev_t RegisterAudioDevice(DeviceDriverType Type,
|
|
||||||
drvOpen_t Open, drvClose_t Close,
|
|
||||||
drvRead_t Read, drvWrite_t Write, drvIoctl_t Ioctl);
|
|
||||||
|
|
||||||
int UnregisterAudioDevice(dev_t DeviceID, DeviceDriverType Type);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#endif // !__FENNIX_API_AUDIO_H__
|
#endif // !__FENNIX_API_AUDIO_H__
|
||||||
|
@ -77,20 +77,20 @@ extern "C"
|
|||||||
void UnmapPages(void *VirtualAddress, size_t Pages);
|
void UnmapPages(void *VirtualAddress, size_t Pages);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Print to the screen
|
* @brief Print to the kernel terminal
|
||||||
* @param Format The format string
|
* @param Format The format string
|
||||||
* @param ... The arguments to the format string
|
* @param ... The arguments to the format string
|
||||||
*
|
*
|
||||||
* @note The newline character is automatically appended
|
* @note The newline character is automatically appended
|
||||||
*/
|
*/
|
||||||
void KPrint(const char *Format, ...);
|
void KernelPrint(const char *Format, ...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Print to the kernel logger
|
* @brief Print to the kernel logger
|
||||||
* @param Format The format string
|
* @param Format The format string
|
||||||
* @param ... The arguments to the format string
|
* @param ... The arguments to the format string
|
||||||
*/
|
*/
|
||||||
void Log(const char *Format, ...);
|
void KernelLog(const char *Format, ...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Register an interrupt handler
|
* @brief Register an interrupt handler
|
||||||
@ -241,17 +241,20 @@ extern "C"
|
|||||||
/** @copydoc LeaveCriticalSection */
|
/** @copydoc LeaveCriticalSection */
|
||||||
#define LCS LeaveCriticalSection(__ECS)
|
#define LCS LeaveCriticalSection(__ECS)
|
||||||
|
|
||||||
#define DriverInfo(Name, Description, Author, Version, License) \
|
#define DriverInfo(_Name, _Description, _Author, _MajorVersion, \
|
||||||
void __IdentifyDriver( \
|
_MinorVersion, _PathVersion, _License) \
|
||||||
dev_t ID, \
|
__attribute__((section(".driver.info"))) struct __DriverInfo \
|
||||||
int (*GetDriverInfo)(dev_t, const char *, const char *, \
|
__di = {.Name = _Name, \
|
||||||
const char *, const char *, const char *)) \
|
.Description = _Description, \
|
||||||
{ \
|
.Author = _Author, \
|
||||||
GetDriverInfo(ID, Name, Description, Author, Version, License); \
|
.Version = {.APIVersion = 0, \
|
||||||
}
|
.Major = _MajorVersion, \
|
||||||
|
.Minor = _MinorVersion, \
|
||||||
|
.Patch = _PathVersion}, \
|
||||||
|
.License = _License}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define DebugLog(m, ...) Log(m, ##__VA_ARGS__)
|
#define DebugLog(m, ...) KernelLog(m, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define DebugLog(m, ...)
|
#define DebugLog(m, ...)
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
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_BLOCK_H__
|
|
||||||
#define __FENNIX_API_BLOCK_H__
|
|
||||||
|
|
||||||
#include <types.h>
|
|
||||||
#include <driver.h>
|
|
||||||
|
|
||||||
typedef int (*drvOpen_t)(dev_t, dev_t, int, mode_t);
|
|
||||||
typedef int (*drvClose_t)(dev_t, dev_t);
|
|
||||||
typedef size_t (*drvRead_t)(dev_t, dev_t, uint8_t *, size_t, off_t);
|
|
||||||
typedef size_t (*drvWrite_t)(dev_t, dev_t, uint8_t *, size_t, off_t);
|
|
||||||
typedef int (*drvIoctl_t)(dev_t, dev_t, unsigned long, void *);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
dev_t RegisterBlockDevice(DeviceDriverType Type,
|
|
||||||
drvOpen_t Open, drvClose_t Close,
|
|
||||||
drvRead_t Read, drvWrite_t Write, drvIoctl_t Ioctl);
|
|
||||||
|
|
||||||
int UnregisterBlockDevice(dev_t DeviceID, DeviceDriverType Type);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#endif // !__FENNIX_API_BLOCK_H__
|
|
74
include/device.h
Normal file
74
include/device.h
Normal 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__
|
289
include/driver.h
289
include/driver.h
@ -20,30 +20,6 @@
|
|||||||
|
|
||||||
#include <types.h>
|
#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
|
typedef struct
|
||||||
{
|
{
|
||||||
/* PCIDevice */ void *Device;
|
/* PCIDevice */ void *Device;
|
||||||
@ -57,177 +33,22 @@ typedef struct
|
|||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
KEY_1,
|
IOCTL_AUDIO_GET_VOLUME = 0,
|
||||||
KEY_2,
|
IOCTL_AUDIO_SET_VOLUME = 1,
|
||||||
KEY_3,
|
|
||||||
KEY_4,
|
|
||||||
KEY_5,
|
|
||||||
KEY_6,
|
|
||||||
KEY_7,
|
|
||||||
KEY_8,
|
|
||||||
KEY_9,
|
|
||||||
KEY_0,
|
|
||||||
|
|
||||||
KEY_Q,
|
IOCTL_AUDIO_GET_MUTE = 2,
|
||||||
KEY_W,
|
IOCTL_AUDIO_SET_MUTE = 3,
|
||||||
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,
|
IOCTL_AUDIO_GET_SAMPLE_RATE = 4,
|
||||||
KEY_F2,
|
IOCTL_AUDIO_SET_SAMPLE_RATE = 5,
|
||||||
KEY_F3,
|
|
||||||
KEY_F4,
|
|
||||||
KEY_F5,
|
|
||||||
KEY_F6,
|
|
||||||
KEY_F7,
|
|
||||||
KEY_F8,
|
|
||||||
KEY_F9,
|
|
||||||
KEY_F10,
|
|
||||||
KEY_F11,
|
|
||||||
KEY_F12,
|
|
||||||
|
|
||||||
KEYPAD_7,
|
IOCTL_AUDIO_GET_CHANNELS = 6,
|
||||||
KEYPAD_8,
|
IOCTL_AUDIO_SET_CHANNELS = 7,
|
||||||
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
|
|
||||||
{
|
|
||||||
ddt_Keyboard,
|
|
||||||
ddt_Mouse,
|
|
||||||
ddt_Joystick,
|
|
||||||
ddt_Gamepad,
|
|
||||||
ddt_Touchpad,
|
|
||||||
ddt_Touchscreen,
|
|
||||||
|
|
||||||
ddt_SATA,
|
|
||||||
ddt_ATA,
|
|
||||||
ddt_NVMe,
|
|
||||||
|
|
||||||
ddt_Audio,
|
|
||||||
|
|
||||||
ddt_Network,
|
|
||||||
} DeviceDriverType;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
IOCTL_AUDIO_GET_VOLUME,
|
|
||||||
IOCTL_AUDIO_SET_VOLUME,
|
|
||||||
|
|
||||||
IOCTL_AUDIO_GET_MUTE,
|
|
||||||
IOCTL_AUDIO_SET_MUTE,
|
|
||||||
|
|
||||||
IOCTL_AUDIO_GET_SAMPLE_RATE,
|
|
||||||
IOCTL_AUDIO_SET_SAMPLE_RATE,
|
|
||||||
|
|
||||||
IOCTL_AUDIO_GET_CHANNELS,
|
|
||||||
IOCTL_AUDIO_SET_CHANNELS,
|
|
||||||
} AudioIoctl;
|
} AudioIoctl;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
IOCTL_NET_GET_MAC,
|
IOCTL_NET_GET_MAC = 0,
|
||||||
} NetIoctl;
|
} NetIoctl;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -239,89 +60,17 @@ typedef enum
|
|||||||
MAP_CACHE_DISABLE = 1 << 4,
|
MAP_CACHE_DISABLE = 1 << 4,
|
||||||
} PageMapFlags;
|
} PageMapFlags;
|
||||||
|
|
||||||
typedef struct
|
struct __DriverInfo
|
||||||
{
|
{
|
||||||
struct
|
const char *Name;
|
||||||
|
const char *Description;
|
||||||
|
const char *Author;
|
||||||
|
struct __DriverVersion
|
||||||
{
|
{
|
||||||
uint8_t Major;
|
int APIVersion;
|
||||||
uint8_t Minor;
|
int Major, Minor, Patch;
|
||||||
uint8_t Patch;
|
} Version;
|
||||||
} APIVersion;
|
const char *License;
|
||||||
|
};
|
||||||
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);
|
|
||||||
|
|
||||||
/* Input */
|
|
||||||
dev_t (*RegisterInputDevice)(dev_t MajorID, DeviceDriverType Type);
|
|
||||||
int (*UnregisterInputDevice)(dev_t MajorID, dev_t MinorID, DeviceDriverType Type);
|
|
||||||
int (*ReportKeyboardEvent)(dev_t MajorID, dev_t MinorID, uint8_t ScanCode);
|
|
||||||
int (*ReportRelativeMouseEvent)(dev_t MajorID, dev_t MinorID, __MouseButtons Button, int X, int Y, int8_t Z);
|
|
||||||
int (*ReportAbsoluteMouseEvent)(dev_t MajorID, dev_t MinorID, __MouseButtons Button, uintptr_t X, uintptr_t Y, int8_t Z);
|
|
||||||
|
|
||||||
/* Storage */
|
|
||||||
dev_t (*RegisterBlockDevice)(dev_t MajorID, DeviceDriverType Type, void *Open, void *Close, void *Read, void *Write, void *Ioctl);
|
|
||||||
int (*UnregisterBlockDevice)(dev_t MajorID, dev_t MinorID, DeviceDriverType Type);
|
|
||||||
|
|
||||||
/* Audio */
|
|
||||||
dev_t (*RegisterAudioDevice)(dev_t MajorID, DeviceDriverType Type, void *Open, void *Close, void *Read, void *Write, void *Ioctl);
|
|
||||||
int (*UnregisterAudioDevice)(dev_t MajorID, dev_t MinorID, DeviceDriverType Type);
|
|
||||||
|
|
||||||
/* Network */
|
|
||||||
dev_t (*RegisterNetDevice)(dev_t MajorID, DeviceDriverType Type, void *Open, void *Close, void *Read, void *Write, void *Ioctl);
|
|
||||||
int (*UnregisterNetDevice)(dev_t MajorID, dev_t MinorID, DeviceDriverType Type);
|
|
||||||
int (*ReportNetworkPacket)(dev_t MajorID, dev_t MinorID, void *Buffer, size_t Size);
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
#endif // !__FENNIX_API_DRIVER_FUNCTIONS_H__
|
#endif // !__FENNIX_API_DRIVER_FUNCTIONS_H__
|
||||||
|
986
include/errno.h
986
include/errno.h
@ -1,408 +1,604 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of Fennix Drivers.
|
This file is part of Fennix Kernel.
|
||||||
|
|
||||||
Fennix Drivers is free software: you can redistribute it and/or
|
Fennix Kernel is free software: you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License as
|
modify it under the terms of the GNU General Public License as
|
||||||
published by the Free Software Foundation, either version 3 of
|
published by the Free Software Foundation, either version 3 of
|
||||||
the License, or (at your option) any later version.
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
Fennix Drivers is distributed in the hope that it will be useful,
|
Fennix Kernel is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _ERRNO_H
|
#ifndef __FENNIX_KERNEL_ERRNO_H__
|
||||||
#define _ERRNO_H
|
#define __FENNIX_KERNEL_ERRNO_H__
|
||||||
|
|
||||||
/** Operation not permitted */
|
/**
|
||||||
#define EPERM 1
|
* The documentation for these error codes are from:
|
||||||
|
* https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html
|
||||||
/** No such file or directory */
|
*
|
||||||
#define ENOENT 2
|
* Full list:
|
||||||
|
* https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/errno.h.html
|
||||||
/** No such process */
|
*/
|
||||||
#define ESRCH 3
|
typedef enum
|
||||||
|
{
|
||||||
/** Interrupted system call */
|
/**
|
||||||
#define EINTR 4
|
* No Error
|
||||||
|
*/
|
||||||
/** I/O error */
|
EOK = 0,
|
||||||
#define EIO 5
|
|
||||||
|
/**
|
||||||
/** No such device or address */
|
* Argument list too long. The sum of the number of bytes used by the
|
||||||
#define ENXIO 6
|
* new process image's argument list and environment list is greater
|
||||||
|
* than the system-imposed limit of {ARG_MAX} bytes.
|
||||||
/** Argument list too long */
|
* or:
|
||||||
#define E2BIG 7
|
* Lack of space in an output buffer.
|
||||||
|
* or:
|
||||||
/** Exec format error */
|
* Argument is greater than the system-imposed maximum.
|
||||||
#define ENOEXEC 8
|
*/
|
||||||
|
E2BIG = 1,
|
||||||
/** Bad file number */
|
|
||||||
#define EBADF 9
|
/**
|
||||||
|
* Permission denied. An attempt was made to access a file in a way
|
||||||
/** No child processes */
|
* forbidden by its file access permissions.
|
||||||
#define ECHILD 10
|
*/
|
||||||
|
EACCES = 2,
|
||||||
/** Try again */
|
|
||||||
#define EAGAIN 11
|
/**
|
||||||
|
* Address in use. The specified address is in use.
|
||||||
/** Out of memory */
|
*/
|
||||||
#define ENOMEM 12
|
EADDRINUSE = 3,
|
||||||
|
|
||||||
/** Permission denied */
|
/**
|
||||||
#define EACCES 13
|
* Address not available. The specified address is not available from
|
||||||
|
* the local system.
|
||||||
/** Bad address */
|
*/
|
||||||
#define EFAULT 14
|
EADDRNOTAVAIL = 4,
|
||||||
|
|
||||||
/** Block device required */
|
/**
|
||||||
#define ENOTBLK 15
|
* Address family not supported. The implementation does not support
|
||||||
|
* the specified address family, or the specified address is not a
|
||||||
/** Device or resource busy */
|
* valid address for the address family of the specified socket.
|
||||||
#define EBUSY 16
|
*/
|
||||||
|
EAFNOSUPPORT = 5,
|
||||||
/** File exists */
|
|
||||||
#define EEXIST 17
|
/**
|
||||||
|
* Resource temporarily unavailable. This is a temporary condition
|
||||||
/** Cross-device link */
|
* and later calls to the same routine may complete normally.
|
||||||
#define EXDEV 18
|
*/
|
||||||
|
EAGAIN = 6,
|
||||||
/** No such device */
|
|
||||||
#define ENODEV 19
|
/**
|
||||||
|
* Connection already in progress. A connection request is already in
|
||||||
/** Not a directory */
|
* progress for the specified socket.
|
||||||
#define ENOTDIR 20
|
*/
|
||||||
|
EALREADY = 7,
|
||||||
/** Is a directory */
|
|
||||||
#define EISDIR 21
|
/**
|
||||||
|
* Bad file descriptor. A file descriptor argument is out of range,
|
||||||
/** Invalid argument */
|
* refers to no open file, or a read (write) request is made to a
|
||||||
#define EINVAL 22
|
* file that is only open for writing (reading).
|
||||||
|
*/
|
||||||
/** File table overflow */
|
EBADF = 8,
|
||||||
#define ENFILE 23
|
|
||||||
|
/**
|
||||||
/** Too many open files */
|
* Bad message. During a read(), getmsg(), getpmsg(), or ioctl()
|
||||||
#define EMFILE 24
|
* I_RECVFD request to a STREAMS device, a message arrived at the
|
||||||
|
* head of the STREAM that is inappropriate for the function
|
||||||
/** Not a typewriter */
|
* receiving the message.
|
||||||
#define ENOTTY 25
|
* read()
|
||||||
|
* Message waiting to be read on a STREAM is not a data message.
|
||||||
/** Text file busy */
|
* getmsg() or getpmsg()
|
||||||
#define ETXTBSY 26
|
* A file descriptor was received instead of a control message.
|
||||||
|
* ioctl()
|
||||||
/** File too large */
|
* Control or data information was received instead of a file
|
||||||
#define EFBIG 27
|
* descriptor when I_RECVFD was specified.
|
||||||
|
*/
|
||||||
/** No space left on device */
|
EBADMSG = 9,
|
||||||
#define ENOSPC 28
|
|
||||||
|
/**
|
||||||
/** Illegal seek */
|
* Resource busy. An attempt was made to make use of a system
|
||||||
#define ESPIPE 29
|
* resource that is not currently available, as it is being
|
||||||
|
* used by another process in a manner that would have
|
||||||
/** Read-only file system */
|
* conflicted with the request being made by this process.
|
||||||
#define EROFS 30
|
*/
|
||||||
|
EBUSY = 10,
|
||||||
/** Too many links */
|
|
||||||
#define EMLINK 31
|
/**
|
||||||
|
* Operation canceled. The associated asynchronous operation was
|
||||||
/** Broken pipe */
|
* canceled before completion.
|
||||||
#define EPIPE 32
|
*/
|
||||||
|
ECANCELED = 11,
|
||||||
/** Math argument out of domain of func */
|
|
||||||
#define EDOM 33
|
/**
|
||||||
|
* No child process. A wait(), waitid(), or waitpid() function was
|
||||||
/** Math result not representable */
|
* executed by a process that had no existing or unwaited-for
|
||||||
#define ERANGE 34
|
* child process.
|
||||||
|
*/
|
||||||
/** Resource deadlock would occur */
|
ECHILD = 12,
|
||||||
#define EDEADLK 35
|
|
||||||
|
/**
|
||||||
/** File name too long */
|
* Connection aborted. The connection has been aborted.
|
||||||
#define ENAMETOOLONG 36
|
*/
|
||||||
|
ECONNABORTED = 13,
|
||||||
/** No record locks available */
|
|
||||||
#define ENOLCK 37
|
/**
|
||||||
|
* Connection refused. An attempt to connect to a socket was refused
|
||||||
/** Function not implemented */
|
* because there was no process listening or because the queue of
|
||||||
#define ENOSYS 38
|
* connection requests was full and the underlying protocol does not
|
||||||
|
* support retransmissions.
|
||||||
/** Directory not empty */
|
*/
|
||||||
#define ENOTEMPTY 39
|
ECONNREFUSED = 14,
|
||||||
|
|
||||||
/** Too many symbolic links encountered */
|
/**
|
||||||
#define ELOOP 40
|
* Connection reset. The connection was forcibly closed by the peer.
|
||||||
|
*/
|
||||||
/** No message of desired type */
|
ECONNRESET = 15,
|
||||||
#define ENOMSG 42
|
|
||||||
|
/**
|
||||||
/** Identifier removed */
|
* Resource deadlock would occur. An attempt was made to lock a system
|
||||||
#define EIDRM 43
|
* resource that would have resulted in a deadlock situation.
|
||||||
|
*/
|
||||||
/** Channel number out of range */
|
EDEADLK = 16,
|
||||||
#define ECHRNG 44
|
|
||||||
|
/**
|
||||||
/** Level 2 not synchronized */
|
* Destination address required. No bind address was established.
|
||||||
#define EL2NSYNC 45
|
*/
|
||||||
|
EDESTADDRREQ = 17,
|
||||||
/** Level 3 halted */
|
|
||||||
#define EL3HLT 46
|
/**
|
||||||
|
* Domain error. An input argument is outside the defined domain of the
|
||||||
/** Level 3 reset */
|
* mathematical function (defined in the ISO C standard).
|
||||||
#define EL3RST 47
|
*/
|
||||||
|
EDOM = 18,
|
||||||
/** Link number out of range */
|
|
||||||
#define ELNRNG 48
|
/**
|
||||||
|
* Reserved.
|
||||||
/** Protocol driver not attached */
|
*/
|
||||||
#define EUNATCH 49
|
EDQUOT = 19,
|
||||||
|
|
||||||
/** No CSI structure available */
|
/**
|
||||||
#define ENOCSI 50
|
* File exists. An existing file was mentioned in an inappropriate
|
||||||
|
* context; for example, as a new link name in the link() function.
|
||||||
/** Level 2 halted */
|
*/
|
||||||
#define EL2HLT 51
|
EEXIST = 20,
|
||||||
|
|
||||||
/** Invalid exchange */
|
/**
|
||||||
#define EBADE 52
|
* Bad address. The system detected an invalid address in attempting
|
||||||
|
* to use an argument of a call. The reliable detection of this error
|
||||||
/** Invalid request descriptor */
|
* cannot be guaranteed, and when not detected may result in the
|
||||||
#define EBADR 53
|
* generation of a signal, indicating an address violation, which is
|
||||||
|
* sent to the process.
|
||||||
/** Exchange full */
|
*/
|
||||||
#define EXFULL 54
|
EFAULT = 21,
|
||||||
|
|
||||||
/** No anode */
|
/**
|
||||||
#define ENOANO 55
|
* File too large. The size of a file would exceed the maximum file
|
||||||
|
* size of an implementation or offset maximum established in the
|
||||||
/** Invalid request code */
|
* corresponding file description.
|
||||||
#define EBADRQC 56
|
*/
|
||||||
|
EFBIG = 22,
|
||||||
/** Invalid slot */
|
|
||||||
#define EBADSLT 57
|
/**
|
||||||
|
* Host is unreachable. The destination host cannot be reached
|
||||||
/** Bad font file format */
|
* (probably because the host is down or a remote router cannot
|
||||||
#define EBFONT 59
|
* reach it).
|
||||||
|
*/
|
||||||
/** Device not a stream */
|
EHOSTUNREACH = 23,
|
||||||
#define ENOSTR 60
|
|
||||||
|
/**
|
||||||
/** No data available */
|
* Identifier removed. Returned during XSI interprocess communication
|
||||||
#define ENODATA 61
|
* if an identifier has been removed from the system.
|
||||||
|
*/
|
||||||
/** Timer expired */
|
EIDRM = 24,
|
||||||
#define ETIME 62
|
|
||||||
|
/**
|
||||||
/** Out of streams resources */
|
* Illegal byte sequence. A wide-character code has been detected that
|
||||||
#define ENOSR 63
|
* does not correspond to a valid character, or a byte sequence does
|
||||||
|
* not form a valid wide-character code (defined in the ISO C standard).
|
||||||
/** Machine is not on the network */
|
*/
|
||||||
#define ENONET 64
|
EILSEQ = 25,
|
||||||
|
|
||||||
/** Package not installed */
|
/**
|
||||||
#define ENOPKG 65
|
* Operation in progress. This code is used to indicate that an
|
||||||
|
* asynchronous operation has not yet completed.
|
||||||
/** Object is remote */
|
* or:
|
||||||
#define EREMOTE 66
|
* O_NONBLOCK is set for the socket file descriptor and the connection
|
||||||
|
* cannot be immediately established.
|
||||||
/** Link has been severed */
|
*/
|
||||||
#define ENOLINK 67
|
EINPROGRESS = 26,
|
||||||
|
|
||||||
/** Advertise error */
|
/**
|
||||||
#define EADV 68
|
* Interrupted function call. An asynchronous signal was caught by the
|
||||||
|
* process during the execution of an interruptible function. If the
|
||||||
/** Srmount error */
|
* signal handler performs a normal return, the interrupted function
|
||||||
#define ESRMNT 69
|
* call may return this condition (see the Base Definitions volume
|
||||||
|
* of POSIX.1-2017, <signal.h>).
|
||||||
/** Communication error on send */
|
*/
|
||||||
#define ECOMM 70
|
EINTR = 27,
|
||||||
|
|
||||||
/** Protocol error */
|
/**
|
||||||
#define EPROTO 71
|
* Invalid argument. Some invalid argument was supplied; for example,
|
||||||
|
* specifying an undefined signal in a signal() function or a
|
||||||
/** Multihop attempted */
|
* kill() function.
|
||||||
#define EMULTIHOP 72
|
*/
|
||||||
|
EINVAL = 28,
|
||||||
/** RFS specific error */
|
|
||||||
#define EDOTDOT 73
|
/**
|
||||||
|
* Input/output error. Some physical input or output error has occurred.
|
||||||
/** Not a data message */
|
* This error may be reported on a subsequent operation on the same
|
||||||
#define EBADMSG 74
|
* file descriptor. Any other error-causing operation on the same file
|
||||||
|
* descriptor may cause the [EIO] error indication to be lost.
|
||||||
/** Value too large for defined data type */
|
*/
|
||||||
#define EOVERFLOW 75
|
EIO = 29,
|
||||||
|
|
||||||
/** Name not unique on network */
|
/**
|
||||||
#define ENOTUNIQ 76
|
* Socket is connected. The specified socket is already connected.
|
||||||
|
*/
|
||||||
/** File descriptor in bad state */
|
EISCONN = 30,
|
||||||
#define EBADFD 77
|
|
||||||
|
/**
|
||||||
/** Remote address changed */
|
* Is a directory. An attempt was made to open a directory with write
|
||||||
#define EREMCHG 78
|
* mode specified.
|
||||||
|
*/
|
||||||
/** Can not access a needed shared library */
|
EISDIR = 31,
|
||||||
#define ELIBACC 79
|
|
||||||
|
/**
|
||||||
/** Accessing a corrupted shared library */
|
* Symbolic link loop. A loop exists in symbolic links encountered
|
||||||
#define ELIBBAD 80
|
* during pathname resolution. This error may also be returned if
|
||||||
|
* more than {SYMLOOP_MAX} symbolic links are encountered during
|
||||||
/** .lib section in a.out corrupted */
|
* pathname resolution.
|
||||||
#define ELIBSCN 81
|
*/
|
||||||
|
ELOOP = 32,
|
||||||
/** Attempting to link in too many shared libraries */
|
|
||||||
#define ELIBMAX 82
|
/**
|
||||||
|
* File descriptor value too large or too many open streams. An
|
||||||
/** Cannot exec a shared library directly */
|
* attempt was made to open a file descriptor with a value greater
|
||||||
#define ELIBEXEC 83
|
* than or equal to {OPEN_MAX}, or an attempt was made to open more
|
||||||
|
* than the maximum number of streams allowed in the process.
|
||||||
/** Illegal byte sequence */
|
*/
|
||||||
#define EILSEQ 84
|
EMFILE = 33,
|
||||||
|
|
||||||
/** Interrupted system call should be restarted */
|
/**
|
||||||
#define ERESTART 85
|
* Too many links. An attempt was made to have the link count of a
|
||||||
|
* single file exceed {LINK_MAX}.
|
||||||
/** Streams pipe error */
|
*/
|
||||||
#define ESTRPIPE 86
|
EMLINK = 34,
|
||||||
|
|
||||||
/** Too many users */
|
/**
|
||||||
#define EUSERS 87
|
* Message too large. A message sent on a transport provider was
|
||||||
|
* larger than an internal message buffer or some other network limit.
|
||||||
/** Socket operation on non-socket */
|
* or:
|
||||||
#define ENOTSOCK 88
|
* Inappropriate message buffer length.
|
||||||
|
*/
|
||||||
/** Destination address required */
|
EMSGSIZE = 35,
|
||||||
#define EDESTADDRREQ 89
|
|
||||||
|
/**
|
||||||
/** Message too long */
|
* Reserved.
|
||||||
#define EMSGSIZE 90
|
*/
|
||||||
|
EMULTIHOP = 36,
|
||||||
/** Protocol wrong type for socket */
|
|
||||||
#define EPROTOTYPE 91
|
/**
|
||||||
|
* Filename too long. The length of a pathname exceeds {PATH_MAX} and
|
||||||
/** Protocol not available */
|
* the implementation considers this to be an error, or a pathname
|
||||||
#define ENOPROTOOPT 92
|
* component is longer than {NAME_MAX}. This error may also occur
|
||||||
|
* when pathname substitution, as a result of encountering a
|
||||||
/** Protocol not supported */
|
* symbolic link during pathname resolution, results in a pathname
|
||||||
#define EPROTONOSUPPORT 93
|
* string the size of which exceeds {PATH_MAX}.
|
||||||
|
*/
|
||||||
/** Socket type not supported */
|
ENAMETOOLONG = 37,
|
||||||
#define ESOCKTNOSUPPORT 94
|
|
||||||
|
/**
|
||||||
/** Operation not supported on transport endpoint */
|
* Network is down. The local network interface used to reach the
|
||||||
#define EOPNOTSUPP 95
|
* destination is down.
|
||||||
|
*/
|
||||||
/** Protocol family not supported */
|
ENETDOWN = 38,
|
||||||
#define EPFNOSUPPORT 96
|
|
||||||
|
/**
|
||||||
/** Address family not supported by protocol */
|
* The connection was aborted by the network.
|
||||||
#define EAFNOSUPPORT 97
|
*/
|
||||||
|
ENETRESET = 39,
|
||||||
/** Address already in use */
|
|
||||||
#define EADDRINUSE 98
|
/**
|
||||||
|
* Network unreachable. No route to the network is present.
|
||||||
/** Cannot assign requested address */
|
*/
|
||||||
#define EADDRNOTAVAIL 99
|
ENETUNREACH = 40,
|
||||||
|
|
||||||
/** Network is down */
|
/**
|
||||||
#define ENETDOWN 100
|
* Too many files open in system. Too many files are currently open
|
||||||
|
* in the system. The system has reached its predefined limit for
|
||||||
/** Network is unreachable */
|
* simultaneously open files and temporarily cannot accept requests
|
||||||
#define ENETUNREACH 101
|
* to open another one.
|
||||||
|
*/
|
||||||
/** Network dropped connection because of reset */
|
ENFILE = 41,
|
||||||
#define ENETRESET 102
|
|
||||||
|
/**
|
||||||
/** Software caused connection abort */
|
* No buffer space available. Insufficient buffer resources were
|
||||||
#define ECONNABORTED 103
|
* available in the system to perform the socket operation.
|
||||||
|
*/
|
||||||
/** Connection reset by peer */
|
ENOBUFS = 42,
|
||||||
#define ECONNRESET 104
|
|
||||||
|
/**
|
||||||
/** No buffer space available */
|
* No message available. No message is available on the STREAM head
|
||||||
#define ENOBUFS 105
|
* read queue.
|
||||||
|
*/
|
||||||
/** Transport endpoint is already connected */
|
ENODATA = 43,
|
||||||
#define EISCONN 106
|
|
||||||
|
/**
|
||||||
/** Transport endpoint is not connected */
|
* No such device. An attempt was made to apply an inappropriate
|
||||||
#define ENOTCONN 107
|
* function to a device; for example, trying to read a write-only
|
||||||
|
* device such as a printer.
|
||||||
/** Cannot send after transport endpoint shutdown */
|
*/
|
||||||
#define ESHUTDOWN 108
|
ENODEV = 44,
|
||||||
|
|
||||||
/** Too many references: cannot splice */
|
/**
|
||||||
#define ETOOMANYREFS 109
|
* No such file or directory. A component of a specified pathname
|
||||||
|
* does not exist, or the pathname is an empty string.
|
||||||
/** Connection timed out */
|
*/
|
||||||
#define ETIMEDOUT 110
|
ENOENT = 45,
|
||||||
|
|
||||||
/** Connection refused */
|
/**
|
||||||
#define ECONNREFUSED 111
|
* Executable file format error. A request is made to execute a file
|
||||||
|
* that, although it has appropriate privileges, is not in the
|
||||||
/** Host is down */
|
* format required by the implementation for executable files.
|
||||||
#define EHOSTDOWN 112
|
*/
|
||||||
|
ENOEXEC = 46,
|
||||||
/** No route to host */
|
|
||||||
#define EHOSTUNREACH 113
|
/**
|
||||||
|
* No locks available. A system-imposed limit on the number of
|
||||||
/** Operation already in progress */
|
* simultaneous file and record locks has been reached and no more
|
||||||
#define EALREADY 114
|
* are currently available.
|
||||||
|
*/
|
||||||
/** Operation now in progress */
|
ENOLCK = 47,
|
||||||
#define EINPROGRESS 115
|
|
||||||
|
/**
|
||||||
/** Stale NFS file handle */
|
* Reserved.
|
||||||
#define ESTALE 116
|
*/
|
||||||
|
ENOLINK = 48,
|
||||||
/** Structure needs cleaning */
|
|
||||||
#define EUCLEAN 117
|
/**
|
||||||
|
* Not enough space. The new process image requires more memory than
|
||||||
/** Not a XENIX named type file */
|
* is allowed by the hardware or system-imposed memory management
|
||||||
#define ENOTNAM 118
|
* constraints.
|
||||||
|
*/
|
||||||
/** No XENIX semaphores available */
|
ENOMEM = 49,
|
||||||
#define ENAVAIL 119
|
|
||||||
|
/**
|
||||||
/** Is a named type file */
|
* No message of the desired type. The message queue does not contain
|
||||||
#define EISNAM 120
|
* a message of the required type during XSI interprocess communication.
|
||||||
|
*/
|
||||||
/** Remote I/O error */
|
ENOMSG = 50,
|
||||||
#define EREMOTEIO 121
|
|
||||||
|
/**
|
||||||
/** Quota exceeded */
|
* Protocol not available. The protocol option specified to
|
||||||
#define EDQUOT 122
|
* setsockopt() is not supported by the implementation.
|
||||||
|
*/
|
||||||
/** No medium found */
|
ENOPROTOOPT = 51,
|
||||||
#define ENOMEDIUM 123
|
|
||||||
|
/**
|
||||||
/** Wrong medium type */
|
* No space left on a device. During the write() function on a
|
||||||
#define EMEDIUMTYPE 124
|
* regular file or when extending a directory, there is no free
|
||||||
|
* space left on the device.
|
||||||
/** Operation Canceled */
|
*/
|
||||||
#define ECANCELED 125
|
ENOSPC = 52,
|
||||||
|
|
||||||
/** Required key not available */
|
/**
|
||||||
#define ENOKEY 126
|
* No STREAM resources. Insufficient STREAMS memory resources are
|
||||||
|
* available to perform a STREAMS-related function. This is a
|
||||||
/** Key has expired */
|
* temporary condition; it may be recovered from if other
|
||||||
#define EKEYEXPIRED 127
|
* processes release resources.
|
||||||
|
*/
|
||||||
/** Key has been revoked */
|
ENOSR = 53,
|
||||||
#define EKEYREVOKED 128
|
|
||||||
|
/**
|
||||||
/** Key was rejected by service */
|
* Not a STREAM. A STREAM function was attempted on a file descriptor
|
||||||
#define EKEYREJECTED 129
|
* that was not associated with a STREAMS device.
|
||||||
|
*/
|
||||||
/** Owner died */
|
ENOSTR = 54,
|
||||||
#define EOWNERDEAD 130
|
|
||||||
|
/**
|
||||||
/** State not recoverable */
|
* Functionality not supported. An attempt was made to use optional
|
||||||
#define ENOTRECOVERABLE 131
|
* functionality that is not supported in this implementation.
|
||||||
|
*/
|
||||||
#endif // !_ERRNO_H
|
ENOSYS = 55,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Socket not connected. The socket is not connected.
|
||||||
|
*/
|
||||||
|
ENOTCONN = 56,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not a directory. A component of the specified pathname exists, but
|
||||||
|
* it is not a directory, when a directory was expected; or an
|
||||||
|
* attempt was made to create a non-directory file, and the specified
|
||||||
|
* pathname contains at least one non- <slash> character and ends
|
||||||
|
* with one or more trailing <slash> characters.
|
||||||
|
*/
|
||||||
|
ENOTDIR = 57,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directory not empty. A directory other than an empty directory
|
||||||
|
* was supplied when an empty directory was expected.
|
||||||
|
*/
|
||||||
|
ENOTEMPTY = 58,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State not recoverable. The state protected by a robust mutex
|
||||||
|
* is not recoverable.
|
||||||
|
*/
|
||||||
|
ENOTRECOVERABLE = 59,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not a socket. The file descriptor does not refer to a socket.
|
||||||
|
*/
|
||||||
|
ENOTSOCK = 60,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not supported. The implementation does not support the requested
|
||||||
|
* feature or value.
|
||||||
|
*/
|
||||||
|
ENOTSUP = 61,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inappropriate I/O control operation. A control function has been
|
||||||
|
* attempted for a file or special file for which the operation
|
||||||
|
* is inappropriate.
|
||||||
|
*/
|
||||||
|
ENOTTY = 62,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No such device or address. Input or output on a special file
|
||||||
|
* refers to a device that does not exist, or makes a request
|
||||||
|
* beyond the capabilities of the device. It may also occur when,
|
||||||
|
* for example, a tape drive is not on-line.
|
||||||
|
*/
|
||||||
|
ENXIO = 63,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operation not supported on socket. The type of socket (address
|
||||||
|
* family or protocol) does not support the requested operation.
|
||||||
|
*/
|
||||||
|
EOPNOTSUPP = 64,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value too large to be stored in data type. An operation was
|
||||||
|
* attempted which would generate a value that is outside the
|
||||||
|
* range of values that can be represented in the relevant data
|
||||||
|
* type or that are allowed for a given data item.
|
||||||
|
*/
|
||||||
|
EOVERFLOW = 65,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Previous owner died. The owner of a robust mutex terminated
|
||||||
|
* while holding the mutex lock.
|
||||||
|
*/
|
||||||
|
EOWNERDEAD = 66,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operation not permitted. An attempt was made to perform an
|
||||||
|
* operation limited to processes with appropriate privileges or
|
||||||
|
* to the owner of a file or other resource.
|
||||||
|
*/
|
||||||
|
EPERM = 67,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broken pipe. A write was attempted on a socket, pipe, or FIFO
|
||||||
|
* for which there is no process to read the data.
|
||||||
|
*/
|
||||||
|
EPIPE = 68,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protocol error. Some protocol error occurred. This error is
|
||||||
|
* device-specific, but is generally not related to a
|
||||||
|
* hardware failure.
|
||||||
|
*/
|
||||||
|
EPROTO = 69,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protocol not supported. The protocol is not supported by the
|
||||||
|
* address family, or the protocol is not supported by
|
||||||
|
* the implementation.
|
||||||
|
*/
|
||||||
|
EPROTONOSUPPORT = 70,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protocol wrong type for socket. The socket type is not
|
||||||
|
* supported by the protocol.
|
||||||
|
*/
|
||||||
|
EPROTOTYPE = 71,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result too large or too small. The result of the function
|
||||||
|
* is too large (overflow) or too small (underflow) to be
|
||||||
|
* represented in the available space.
|
||||||
|
*/
|
||||||
|
ERANGE = 72,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read-only file system. An attempt was made to modify a file
|
||||||
|
* or directory on a file system that is read-only.
|
||||||
|
*/
|
||||||
|
EROFS = 73,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalid seek. An attempt was made to access the file offset
|
||||||
|
* associated with a pipe or FIFO.
|
||||||
|
*/
|
||||||
|
ESPIPE = 74,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No such process. No process can be found corresponding to that
|
||||||
|
* specified by the given process ID.
|
||||||
|
*/
|
||||||
|
ESRCH = 75,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reserved.
|
||||||
|
*/
|
||||||
|
ESTALE = 76,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STREAM ioctl() timeout. The timer set for a STREAMS ioctl() call
|
||||||
|
* has expired. The cause of this error is device-specific and could
|
||||||
|
* indicate either a hardware or software failure, or a timeout
|
||||||
|
* value that is too short for the specific operation. The status
|
||||||
|
* of the ioctl() operation is unspecified.
|
||||||
|
*/
|
||||||
|
ETIME = 77,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection timed out. The connection to a remote machine has
|
||||||
|
* timed out.
|
||||||
|
* If the connection timed out during execution of the function that
|
||||||
|
* reported this error (as opposed to timing out prior to the
|
||||||
|
* function being called), it is unspecified whether the function
|
||||||
|
* has completed some or all of the documented behavior associated
|
||||||
|
* with a successful completion of the function.
|
||||||
|
* or:
|
||||||
|
* Operation timed out. The time limit associated with the operation
|
||||||
|
* was exceeded before the operation completed.
|
||||||
|
*/
|
||||||
|
ETIMEDOUT = 78,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Text file busy. An attempt was made to execute a pure-procedure
|
||||||
|
* program that is currently open for writing, or an attempt has
|
||||||
|
* been made to open for writing a pure-procedure program that
|
||||||
|
* is being executed.
|
||||||
|
*/
|
||||||
|
ETXTBSY = 79,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operation would block. An operation on a socket marked as
|
||||||
|
* non-blocking has encountered a situation such as no data available
|
||||||
|
* that otherwise would have caused the function to suspend execution.
|
||||||
|
*/
|
||||||
|
EWOULDBLOCK = 80,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Improper link. A link to a file on another file system was attempted.
|
||||||
|
*/
|
||||||
|
EXDEV = 81,
|
||||||
|
|
||||||
|
__ERRNO_MAX
|
||||||
|
} KernelErrors;
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
EXTERNC int *__errno_location(void) __attribute__((const));
|
||||||
|
#define errno (*__errno_location())
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
char *strerror(int errnum);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // !__FENNIX_KERNEL_ERRNO_H__
|
||||||
|
380
include/fs.h
Normal file
380
include/fs.h
Normal file
@ -0,0 +1,380 @@
|
|||||||
|
/*
|
||||||
|
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_FILESYSTEM_H__
|
||||||
|
#define __FENNIX_API_FILESYSTEM_H__
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
#define SEEK_SET 0
|
||||||
|
#define SEEK_CUR 1
|
||||||
|
#define SEEK_END 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File type mask for the upper 32 bits of mode_t.
|
||||||
|
*
|
||||||
|
* @note Maybe it will be used in the future.
|
||||||
|
*/
|
||||||
|
#define S_IFMT32 037777600000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File type mask.
|
||||||
|
*
|
||||||
|
* This mask is used to extract the file type
|
||||||
|
* from the mode field of a stat structure.
|
||||||
|
*
|
||||||
|
* Doing bitwise AND with this mask will return
|
||||||
|
* the file type.
|
||||||
|
* Example: st_mode & S_IFMT
|
||||||
|
*
|
||||||
|
* Doing bitwise negation and AND with this mask
|
||||||
|
* will return the permissions.
|
||||||
|
* Example: st_mode & ~S_IFMT
|
||||||
|
*/
|
||||||
|
#define S_IFMT 0170000
|
||||||
|
|
||||||
|
/* Whiteout */
|
||||||
|
#define S_IFWHT 0160000
|
||||||
|
/* Socket */
|
||||||
|
#define S_IFSOCK 0140000
|
||||||
|
/* Symbolic link */
|
||||||
|
#define S_IFLNK 0120000
|
||||||
|
/* Regular file */
|
||||||
|
#define S_IFREG 0100000
|
||||||
|
/* Block device */
|
||||||
|
#define S_IFBLK 0060000
|
||||||
|
/* Directory */
|
||||||
|
#define S_IFDIR 0040000
|
||||||
|
/* Character device */
|
||||||
|
#define S_IFCHR 0020000
|
||||||
|
/* FIFO */
|
||||||
|
#define S_IFIFO 0010000
|
||||||
|
|
||||||
|
#define S_ISUID 04000
|
||||||
|
#define S_ISGID 02000
|
||||||
|
#define S_ISVTX 01000
|
||||||
|
|
||||||
|
/** Owner: RWX */
|
||||||
|
#define S_IRWXU 0700
|
||||||
|
/** Owner: R */
|
||||||
|
#define S_IRUSR 0400
|
||||||
|
/** Owner: W */
|
||||||
|
#define S_IWUSR 0200
|
||||||
|
/** Owner: X */
|
||||||
|
#define S_IXUSR 0100
|
||||||
|
|
||||||
|
/** Group: RWX */
|
||||||
|
#define S_IRWXG 0070
|
||||||
|
/** Group: R */
|
||||||
|
#define S_IRGRP 0040
|
||||||
|
/** Group: W */
|
||||||
|
#define S_IWGRP 0020
|
||||||
|
/** Group: X */
|
||||||
|
#define S_IXGRP 0010
|
||||||
|
|
||||||
|
/** Other: RWX */
|
||||||
|
#define S_IRWXO 0007
|
||||||
|
/** Other: R */
|
||||||
|
#define S_IROTH 0004
|
||||||
|
/** Other: W */
|
||||||
|
#define S_IWOTH 0002
|
||||||
|
/** Other: X */
|
||||||
|
#define S_IXOTH 0001
|
||||||
|
|
||||||
|
#define O_RDONLY 00
|
||||||
|
#define O_WRONLY 01
|
||||||
|
#define O_RDWR 02
|
||||||
|
#define O_CREAT 0100
|
||||||
|
#define O_EXCL 0200
|
||||||
|
#define O_TRUNC 01000
|
||||||
|
#define O_APPEND 02000
|
||||||
|
#define O_NOFOLLOW 0400000
|
||||||
|
#define O_CLOEXEC 02000000
|
||||||
|
|
||||||
|
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||||
|
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
|
||||||
|
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
|
||||||
|
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
|
||||||
|
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
|
||||||
|
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
|
||||||
|
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
|
||||||
|
|
||||||
|
#define DT_UNKNOWN 0x0
|
||||||
|
#define DT_FIFO 0x1
|
||||||
|
#define DT_CHR 0x2
|
||||||
|
#define DT_DIR 0x4
|
||||||
|
#define DT_BLK 0x6
|
||||||
|
#define DT_REG 0x8
|
||||||
|
#define DT_LNK 0xA
|
||||||
|
#define DT_SOCK 0xC
|
||||||
|
#define DT_WHT 0xE
|
||||||
|
|
||||||
|
#define IFTODT(x) ((x) >> 12 & 0xF)
|
||||||
|
#define DTTOIF(x) ((x) << 12)
|
||||||
|
|
||||||
|
#define SYMLOOP_MAX 40
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#define static_assert _Static_assert
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __LP64__
|
||||||
|
static_assert(sizeof(dev_t) == 8, "dev_t must be 64 bits");
|
||||||
|
static_assert(sizeof(ino_t) == 8, "ino_t must be 64 bits");
|
||||||
|
static_assert(sizeof(mode_t) == 4, "mode_t must be 32 bits");
|
||||||
|
static_assert(sizeof(nlink_t) == 4, "nlink_t must be 32 bits");
|
||||||
|
static_assert(sizeof(uid_t) == 4, "uid_t must be 32 bits");
|
||||||
|
static_assert(sizeof(gid_t) == 4, "gid_t must be 32 bits");
|
||||||
|
static_assert(sizeof(off_t) == 8, "off_t must be 64 bits");
|
||||||
|
static_assert(sizeof(time_t) == 8, "time_t must be 64 bits");
|
||||||
|
static_assert(sizeof(blksize_t) == 8, "blksize_t must be 64 bits");
|
||||||
|
static_assert(sizeof(blkcnt_t) == 8, "blkcnt_t must be 64 bits");
|
||||||
|
#else
|
||||||
|
static_assert(sizeof(dev_t) == 4, "dev_t must be 32 bits");
|
||||||
|
static_assert(sizeof(ino_t) == 4, "ino_t must be 32 bits");
|
||||||
|
static_assert(sizeof(mode_t) == 2, "mode_t must be 16 bits");
|
||||||
|
static_assert(sizeof(nlink_t) == 2, "nlink_t must be 16 bits");
|
||||||
|
static_assert(sizeof(uid_t) == 2, "uid_t must be 16 bits");
|
||||||
|
static_assert(sizeof(gid_t) == 2, "gid_t must be 16 bits");
|
||||||
|
static_assert(sizeof(off_t) == 4, "off_t must be 32 bits");
|
||||||
|
static_assert(sizeof(time_t) == 4, "time_t must be 32 bits");
|
||||||
|
static_assert(sizeof(blksize_t) == 4, "blksize_t must be 32 bits");
|
||||||
|
static_assert(sizeof(blkcnt_t) == 4, "blkcnt_t must be 32 bits");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef static_assert
|
||||||
|
|
||||||
|
struct kstat
|
||||||
|
{
|
||||||
|
/** Device ID of the file. */
|
||||||
|
dev_t Device;
|
||||||
|
|
||||||
|
/** Inode number. */
|
||||||
|
ino_t Index;
|
||||||
|
|
||||||
|
/** File type and mode. */
|
||||||
|
mode_t Mode;
|
||||||
|
|
||||||
|
/** Number of hard links. */
|
||||||
|
nlink_t HardLinks;
|
||||||
|
|
||||||
|
/** User ID of the file's owner. */
|
||||||
|
uid_t UserID;
|
||||||
|
|
||||||
|
/** Group ID of the file's owner. */
|
||||||
|
gid_t GroupID;
|
||||||
|
|
||||||
|
/** Device ID for special files. */
|
||||||
|
dev_t RawDevice;
|
||||||
|
|
||||||
|
/** Size of the file in bytes. */
|
||||||
|
off_t Size;
|
||||||
|
|
||||||
|
/** Time of last access. */
|
||||||
|
time_t AccessTime;
|
||||||
|
|
||||||
|
/** Time of last modification. */
|
||||||
|
time_t ModifyTime;
|
||||||
|
|
||||||
|
/** Time of last status change. */
|
||||||
|
time_t ChangeTime;
|
||||||
|
|
||||||
|
/** Optimal I/O block size. */
|
||||||
|
blksize_t BlockSize;
|
||||||
|
|
||||||
|
/** Number of blocks allocated. */
|
||||||
|
blkcnt_t Blocks;
|
||||||
|
|
||||||
|
/** Additional file attributes. */
|
||||||
|
mode_t Attribute;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
dev_t MakeDevice(int Major, int Minor)
|
||||||
|
{
|
||||||
|
return ((Major & 0xFFF) << 8) |
|
||||||
|
(Minor & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetMajor()
|
||||||
|
{
|
||||||
|
return ((unsigned int)(Device) >> 8) & 0xFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetMinor()
|
||||||
|
{
|
||||||
|
return Device & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetFileType(mode_t Type)
|
||||||
|
{
|
||||||
|
Mode = (Mode & ~S_IFMT) |
|
||||||
|
(Type & S_IFMT);
|
||||||
|
}
|
||||||
|
|
||||||
|
mode_t GetFileType() { return Mode & S_IFMT; }
|
||||||
|
void ClearFileType() { Mode = Mode & ~S_IFMT; }
|
||||||
|
bool IsType(mode_t Type) { return (Mode & S_IFMT) == Type; }
|
||||||
|
|
||||||
|
void SetPermissions(mode_t Permissions)
|
||||||
|
{
|
||||||
|
Mode = (Mode & S_IFMT) |
|
||||||
|
(Permissions & ~S_IFMT);
|
||||||
|
}
|
||||||
|
|
||||||
|
mode_t GetPermissions() { return Mode & ~S_IFMT; }
|
||||||
|
void ClearPermissions() { Mode = Mode & S_IFMT; }
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kdirent
|
||||||
|
{
|
||||||
|
ino_t d_ino;
|
||||||
|
off_t d_off;
|
||||||
|
unsigned short d_reclen;
|
||||||
|
unsigned char d_type;
|
||||||
|
char d_name[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Inode
|
||||||
|
{
|
||||||
|
dev_t Device, RawDevice;
|
||||||
|
ino_t Index;
|
||||||
|
mode_t Mode;
|
||||||
|
uint32_t Flags;
|
||||||
|
off_t Offset;
|
||||||
|
|
||||||
|
void *PrivateData;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
/* ... */
|
||||||
|
|
||||||
|
void SetDevice(int Major, int Minor)
|
||||||
|
{
|
||||||
|
this->RawDevice = ((Major & 0xFFF) << 8) |
|
||||||
|
(Minor & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetMajor()
|
||||||
|
{
|
||||||
|
return ((unsigned int)(this->RawDevice) >> 8) & 0xFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetMinor()
|
||||||
|
{
|
||||||
|
return this->RawDevice & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
Inode()
|
||||||
|
{
|
||||||
|
Device = 0;
|
||||||
|
RawDevice = 0;
|
||||||
|
Index = 0;
|
||||||
|
Mode = 0;
|
||||||
|
Flags = 0;
|
||||||
|
Offset = 0;
|
||||||
|
PrivateData = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Inode() = default;
|
||||||
|
|
||||||
|
#else // __cplusplus
|
||||||
|
|
||||||
|
#define INODE_MAKEDEV(major, minor) \
|
||||||
|
((dev_t)(((major & 0xFFF) << 8) | \
|
||||||
|
(minor & 0xFF)))
|
||||||
|
|
||||||
|
#define INODE_MAJOR(rdev) \
|
||||||
|
((int)(((rdev) >> 8) & 0xFFF))
|
||||||
|
|
||||||
|
#define INODE_MINOR(rdev) \
|
||||||
|
((int)((rdev) & 0xFF))
|
||||||
|
|
||||||
|
#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);
|
||||||
|
int (*DeleteInode)(struct FileSystemInfo *Info, struct Inode *Node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronize the filesystem.
|
||||||
|
*
|
||||||
|
* Write all pending changes to the disk.
|
||||||
|
*
|
||||||
|
* @param Info Inode to synchronize. If NULL, synchronize all inodes.
|
||||||
|
*
|
||||||
|
* @return Zero on success, otherwise an error code.
|
||||||
|
*/
|
||||||
|
int (*Synchronize)(struct FileSystemInfo *Info, struct Inode *Node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the filesystem.
|
||||||
|
*
|
||||||
|
* Unregister the filesystem and free all resources.
|
||||||
|
*
|
||||||
|
* @param Info Filesystem to destroy.
|
||||||
|
*
|
||||||
|
* @return Zero on success, otherwise an error code.
|
||||||
|
*/
|
||||||
|
int (*Destroy)(struct FileSystemInfo *Info);
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct FileSystemInfo
|
||||||
|
{
|
||||||
|
const char *Name;
|
||||||
|
const char *RootName;
|
||||||
|
int Flags;
|
||||||
|
struct SuperBlockOperations SuperOps;
|
||||||
|
struct InodeOperations Ops;
|
||||||
|
|
||||||
|
void *PrivateData;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
dev_t RegisterFileSystem(struct FileSystemInfo *Info, struct Inode *Root);
|
||||||
|
int UnregisterFileSystem(dev_t Device);
|
||||||
|
|
||||||
|
#endif // !__FENNIX_API_FILESYSTEM_H__
|
242
include/input.h
242
include/input.h
@ -1,66 +1,234 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of Fennix Drivers.
|
This file is part of Fennix Kernel.
|
||||||
|
|
||||||
Fennix Drivers is free software: you can redistribute it and/or
|
Fennix Kernel is free software: you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License as
|
modify it under the terms of the GNU General Public License as
|
||||||
published by the Free Software Foundation, either version 3 of
|
published by the Free Software Foundation, either version 3 of
|
||||||
the License, or (at your option) any later version.
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
Fennix Drivers is distributed in the hope that it will be useful,
|
Fennix Kernel is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __FENNIX_API_INPUT_H__
|
#ifndef __FENNIX_API_INPUT_H__
|
||||||
#define __FENNIX_API_INPUT_H__
|
#define __FENNIX_API_INPUT_H__
|
||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <driver.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
|
typedef struct
|
||||||
{
|
{
|
||||||
union
|
KeyScanCodes Key;
|
||||||
{
|
} KeyboardReport;
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint8_t LeftButton : 1;
|
|
||||||
uint8_t RightButton : 1;
|
|
||||||
uint8_t MiddleButton : 1;
|
|
||||||
uint8_t Button4 : 1;
|
|
||||||
uint8_t Button5 : 1;
|
|
||||||
};
|
|
||||||
uint8_t Buttons;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
typedef struct
|
||||||
* @note Ignored if is absolute
|
{
|
||||||
*/
|
long X, Y;
|
||||||
int X;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @note Ignored if is absolute
|
|
||||||
*/
|
|
||||||
int Y;
|
|
||||||
int8_t Z;
|
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;
|
} MouseReport;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
typedef struct
|
||||||
extern "C"
|
|
||||||
{
|
{
|
||||||
#endif // __cplusplus
|
} JoystickReport;
|
||||||
|
|
||||||
dev_t RegisterInputDevice(DeviceDriverType Type);
|
typedef struct
|
||||||
int UnregisterInputDevice(dev_t DeviceID, DeviceDriverType Type);
|
{
|
||||||
int ReportKeyboardEvent(dev_t DeviceID, KeyScanCodes ScanCode, uint8_t Pressed);
|
uint16_t X, Y;
|
||||||
int ReportRelativeMouseEvent(dev_t DeviceID, MouseReport Report);
|
uint8_t Pressure;
|
||||||
int ReportAbsoluteMouseEvent(dev_t DeviceID, MouseReport Report, uintptr_t X, uintptr_t Y);
|
} TouchScreenReport;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
typedef struct
|
||||||
}
|
{
|
||||||
#endif // __cplusplus
|
} 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__
|
#endif // !__FENNIX_API_INPUT_H__
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
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_AUDIO_H__
|
|
||||||
#define __FENNIX_API_AUDIO_H__
|
|
||||||
|
|
||||||
#include <types.h>
|
|
||||||
#include <driver.h>
|
|
||||||
|
|
||||||
typedef int (*drvOpen_t)(dev_t, dev_t, int, mode_t);
|
|
||||||
typedef int (*drvClose_t)(dev_t, dev_t);
|
|
||||||
typedef size_t (*drvRead_t)(dev_t, dev_t, uint8_t *, size_t, off_t);
|
|
||||||
typedef size_t (*drvWrite_t)(dev_t, dev_t, uint8_t *, size_t, off_t);
|
|
||||||
typedef int (*drvIoctl_t)(dev_t, dev_t, unsigned long, void *);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
dev_t RegisterNetDevice(DeviceDriverType Type,
|
|
||||||
drvOpen_t Open, drvClose_t Close,
|
|
||||||
drvRead_t Read, drvWrite_t Write, drvIoctl_t Ioctl);
|
|
||||||
|
|
||||||
int UnregisterNetDevice(dev_t DeviceID, DeviceDriverType Type);
|
|
||||||
|
|
||||||
int ReportNetworkPacket(dev_t DeviceID, void *Buffer, size_t Size);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#endif // !__FENNIX_API_AUDIO_H__
|
|
29
include/network.h
Normal file
29
include/network.h
Normal 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__
|
@ -21,7 +21,7 @@
|
|||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
/* https://sites.uclouvain.be/SystInfo/usr/include/linux/pci_regs.h.html */
|
/* https://sites.uclouvain.be/SystInfo/usr/include/linux/pci_regs.h.html */
|
||||||
enum PCICommands
|
typedef enum
|
||||||
{
|
{
|
||||||
/** @brief Enable response in I/O space */
|
/** @brief Enable response in I/O space */
|
||||||
PCI_COMMAND_IO = 0x1,
|
PCI_COMMAND_IO = 0x1,
|
||||||
@ -45,7 +45,7 @@ enum PCICommands
|
|||||||
PCI_COMMAND_FAST_BACK = 0x200,
|
PCI_COMMAND_FAST_BACK = 0x200,
|
||||||
/** @brief INTx Emulation Disable */
|
/** @brief INTx Emulation Disable */
|
||||||
PCI_COMMAND_INTX_DISABLE = 0x400
|
PCI_COMMAND_INTX_DISABLE = 0x400
|
||||||
};
|
} PCI_COMMANDS;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -171,7 +171,7 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PCIArray *FindPCIDevices(uint16_t Vendors[], uint16_t Devices[]);
|
PCIArray *GetPCIDevices(uint16_t Vendors[], uint16_t Devices[]);
|
||||||
void InitializePCI(PCIDevice *Device);
|
void InitializePCI(PCIDevice *Device);
|
||||||
uint32_t GetBAR(uint8_t Index, PCIDevice *Device);
|
uint32_t GetBAR(uint8_t Index, PCIDevice *Device);
|
||||||
uint8_t iLine(PCIDevice *Device);
|
uint8_t iLine(PCIDevice *Device);
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint64_t r15; // General purpose
|
uint64_t r15; // General purpose
|
||||||
@ -49,8 +50,10 @@ typedef struct
|
|||||||
uint64_t rsp; // Stack Pointer
|
uint64_t rsp; // Stack Pointer
|
||||||
uint64_t ss; // Stack Segment
|
uint64_t ss; // Stack Segment
|
||||||
} TrapFrame;
|
} TrapFrame;
|
||||||
|
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
typedef struct TrapFrame
|
|
||||||
|
typedef struct
|
||||||
{
|
{
|
||||||
uint32_t edi; // Destination index for string operations
|
uint32_t edi; // Destination index for string operations
|
||||||
uint32_t esi; // Source index for string operations
|
uint32_t esi; // Source index for string operations
|
||||||
@ -71,8 +74,10 @@ typedef struct TrapFrame
|
|||||||
uint32_t r3_esp; // Stack Pointer
|
uint32_t r3_esp; // Stack Pointer
|
||||||
uint32_t r3_ss; // Stack Segment
|
uint32_t r3_ss; // Stack Segment
|
||||||
} TrapFrame;
|
} TrapFrame;
|
||||||
|
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
typedef struct TrapFrame
|
|
||||||
|
typedef struct
|
||||||
{
|
{
|
||||||
uint64_t x19; // General purpose
|
uint64_t x19; // General purpose
|
||||||
uint64_t x20; // General purpose
|
uint64_t x20; // General purpose
|
||||||
@ -95,6 +100,7 @@ typedef struct TrapFrame
|
|||||||
|
|
||||||
uint64_t InterruptNumber /* iar_el1 */; // Interrupt Acknowledge Register
|
uint64_t InterruptNumber /* iar_el1 */; // Interrupt Acknowledge Register
|
||||||
} TrapFrame;
|
} TrapFrame;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // !__FENNIX_API_REGISTERS_H__
|
#endif // !__FENNIX_API_REGISTERS_H__
|
||||||
|
@ -1,231 +0,0 @@
|
|||||||
/*
|
|
||||||
BSD 3-Clause License
|
|
||||||
|
|
||||||
Copyright (c) 2023, EnderIce2
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the copyright holder nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FENNIX_KERNEL_SYSCALLS_LIST_H__
|
|
||||||
#define __FENNIX_KERNEL_SYSCALLS_LIST_H__
|
|
||||||
|
|
||||||
/* mmap */
|
|
||||||
|
|
||||||
#define sc_PROT_NONE 0
|
|
||||||
#define sc_PROT_READ 1
|
|
||||||
#define sc_PROT_WRITE 2
|
|
||||||
#define sc_PROT_EXEC 4
|
|
||||||
|
|
||||||
#define sc_MAP_SHARED 1
|
|
||||||
#define sc_MAP_PRIVATE 2
|
|
||||||
#define sc_MAP_FIXED 4
|
|
||||||
#define sc_MAP_ANONYMOUS 8
|
|
||||||
|
|
||||||
/* lseek */
|
|
||||||
|
|
||||||
#define sc_SEEK_SET 0
|
|
||||||
#define sc_SEEK_CUR 1
|
|
||||||
#define sc_SEEK_END 2
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enumeration of all the native syscalls
|
|
||||||
* available in the kernel
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* This syscall is used to exit the current
|
|
||||||
* process with the provided exit code.
|
|
||||||
*
|
|
||||||
* @fn void exit(int status);
|
|
||||||
*
|
|
||||||
* @param Code The exit code
|
|
||||||
* @return This syscall does not return
|
|
||||||
*
|
|
||||||
* @note No permissions are required to call
|
|
||||||
* this syscall
|
|
||||||
*/
|
|
||||||
sc_exit = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map pages of memory
|
|
||||||
*
|
|
||||||
* @fn void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);
|
|
||||||
*/
|
|
||||||
sc_mmap,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unmap pages of memory
|
|
||||||
*
|
|
||||||
* @fn int munmap(void *addr, size_t len);
|
|
||||||
*/
|
|
||||||
sc_munmap,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the protection of a page of memory
|
|
||||||
*
|
|
||||||
* @fn int mprotect(void *addr, size_t len, int prot);
|
|
||||||
*/
|
|
||||||
sc_mprotect,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open a file
|
|
||||||
*
|
|
||||||
* @fn int open(const char *path, int oflag, ... );
|
|
||||||
*/
|
|
||||||
sc_open,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close a file descriptor
|
|
||||||
*
|
|
||||||
* @fn int close(int fildes);
|
|
||||||
*/
|
|
||||||
sc_close,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read from a file descriptor
|
|
||||||
*
|
|
||||||
* @fn ssize_t read(int fildes, void *buf, size_t nbyte);
|
|
||||||
*/
|
|
||||||
sc_read,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write to a file descriptor
|
|
||||||
*
|
|
||||||
* @fn ssize_t write(int fildes, const void *buf, size_t nbyte);
|
|
||||||
*/
|
|
||||||
sc_write,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Seek to a position in a file descriptor
|
|
||||||
*
|
|
||||||
* @fn off_t lseek(int fildes, off_t offset, int whence);
|
|
||||||
*/
|
|
||||||
sc_lseek,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new process
|
|
||||||
*
|
|
||||||
* @fn pid_t fork(void);
|
|
||||||
*/
|
|
||||||
sc_fork,
|
|
||||||
|
|
||||||
/** Not a real syscall */
|
|
||||||
sc_MaxSyscall
|
|
||||||
} NativeSyscalls;
|
|
||||||
|
|
||||||
#ifndef syscall0
|
|
||||||
static inline long syscall0(long syscall)
|
|
||||||
{
|
|
||||||
long ret;
|
|
||||||
__asm__ __volatile__("syscall"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "a"(syscall)
|
|
||||||
: "rcx", "r11", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef syscall1
|
|
||||||
static inline long syscall1(long syscall, long arg1)
|
|
||||||
{
|
|
||||||
long ret;
|
|
||||||
__asm__ __volatile__("syscall"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "a"(syscall), "D"(arg1)
|
|
||||||
: "rcx", "r11", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef syscall2
|
|
||||||
static inline long syscall2(long syscall, long arg1, long arg2)
|
|
||||||
{
|
|
||||||
long ret;
|
|
||||||
__asm__ __volatile__("syscall"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "a"(syscall), "D"(arg1), "S"(arg2)
|
|
||||||
: "rcx", "r11", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef syscall3
|
|
||||||
static inline long syscall3(long syscall, long arg1, long arg2, long arg3)
|
|
||||||
{
|
|
||||||
long ret;
|
|
||||||
__asm__ __volatile__("syscall"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3)
|
|
||||||
: "rcx", "r11", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef syscall4
|
|
||||||
static inline long syscall4(long syscall, long arg1, long arg2, long arg3, long arg4)
|
|
||||||
{
|
|
||||||
long ret;
|
|
||||||
register long r10 __asm__("r10") = arg4;
|
|
||||||
__asm__ __volatile__("syscall"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10)
|
|
||||||
: "rcx", "r11", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef syscall5
|
|
||||||
static inline long syscall5(long syscall, long arg1, long arg2, long arg3, long arg4, long arg5)
|
|
||||||
{
|
|
||||||
long ret;
|
|
||||||
register long r10 __asm__("r10") = arg4;
|
|
||||||
register long r8 __asm__("r8") = arg5;
|
|
||||||
__asm__ __volatile__("syscall"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8)
|
|
||||||
: "rcx", "r11", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef syscall6
|
|
||||||
static inline long syscall6(long syscall, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6)
|
|
||||||
{
|
|
||||||
long ret;
|
|
||||||
register long r10 __asm__("r10") = arg4;
|
|
||||||
register long r8 __asm__("r8") = arg5;
|
|
||||||
register long r9 __asm__("r9") = arg6;
|
|
||||||
__asm__ __volatile__("syscall"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8), "r"(r9)
|
|
||||||
: "rcx", "r11", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // !__FENNIX_KERNEL_SYSCALLS_LIST_H__
|
|
111
include/syscalls.h
Normal file
111
include/syscalls.h
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
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_SYSCALLS_LIST_H__
|
||||||
|
#define __FENNIX_API_SYSCALLS_LIST_H__
|
||||||
|
|
||||||
|
#ifndef syscall0
|
||||||
|
static inline long syscall0(long syscall)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
__asm__ __volatile__("syscall"
|
||||||
|
: "=a"(ret)
|
||||||
|
: "a"(syscall)
|
||||||
|
: "rcx", "r11", "memory");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef syscall1
|
||||||
|
static inline long syscall1(long syscall, long arg1)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
__asm__ __volatile__("syscall"
|
||||||
|
: "=a"(ret)
|
||||||
|
: "a"(syscall), "D"(arg1)
|
||||||
|
: "rcx", "r11", "memory");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef syscall2
|
||||||
|
static inline long syscall2(long syscall, long arg1, long arg2)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
__asm__ __volatile__("syscall"
|
||||||
|
: "=a"(ret)
|
||||||
|
: "a"(syscall), "D"(arg1), "S"(arg2)
|
||||||
|
: "rcx", "r11", "memory");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef syscall3
|
||||||
|
static inline long syscall3(long syscall, long arg1, long arg2, long arg3)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
__asm__ __volatile__("syscall"
|
||||||
|
: "=a"(ret)
|
||||||
|
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3)
|
||||||
|
: "rcx", "r11", "memory");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef syscall4
|
||||||
|
static inline long syscall4(long syscall, long arg1, long arg2, long arg3, long arg4)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
register long r10 __asm__("r10") = arg4;
|
||||||
|
__asm__ __volatile__("syscall"
|
||||||
|
: "=a"(ret)
|
||||||
|
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10)
|
||||||
|
: "rcx", "r11", "memory");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef syscall5
|
||||||
|
static inline long syscall5(long syscall, long arg1, long arg2, long arg3, long arg4, long arg5)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
register long r10 __asm__("r10") = arg4;
|
||||||
|
register long r8 __asm__("r8") = arg5;
|
||||||
|
__asm__ __volatile__("syscall"
|
||||||
|
: "=a"(ret)
|
||||||
|
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8)
|
||||||
|
: "rcx", "r11", "memory");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef syscall6
|
||||||
|
static inline long syscall6(long syscall, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6)
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
register long r10 __asm__("r10") = arg4;
|
||||||
|
register long r8 __asm__("r8") = arg5;
|
||||||
|
register long r9 __asm__("r9") = arg6;
|
||||||
|
__asm__ __volatile__("syscall"
|
||||||
|
: "=a"(ret)
|
||||||
|
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8), "r"(r9)
|
||||||
|
: "rcx", "r11", "memory");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // !__FENNIX_API_SYSCALLS_LIST_H__
|
@ -53,11 +53,41 @@ typedef __UINTMAX_TYPE__ uintmax_t;
|
|||||||
|
|
||||||
typedef __PTRDIFF_TYPE__ ptrdiff_t;
|
typedef __PTRDIFF_TYPE__ ptrdiff_t;
|
||||||
typedef __SIZE_TYPE__ size_t;
|
typedef __SIZE_TYPE__ size_t;
|
||||||
|
typedef intptr_t ssize_t;
|
||||||
|
|
||||||
typedef __SIZE_TYPE__ dev_t;
|
#if defined(__LP64__)
|
||||||
typedef __SIZE_TYPE__ off_t;
|
typedef int64_t off_t;
|
||||||
|
typedef int64_t off64_t;
|
||||||
|
typedef uint32_t mode_t;
|
||||||
|
typedef uint64_t dev_t;
|
||||||
|
typedef uint64_t ino64_t;
|
||||||
|
typedef uint64_t ino_t;
|
||||||
|
typedef uint32_t nlink_t;
|
||||||
|
typedef int64_t blksize_t;
|
||||||
|
typedef int64_t blkcnt_t;
|
||||||
|
typedef int64_t blkcnt64_t;
|
||||||
|
typedef int64_t time_t;
|
||||||
|
typedef uint32_t uid_t;
|
||||||
|
typedef uint32_t gid_t;
|
||||||
|
typedef int64_t clock_t;
|
||||||
|
typedef int32_t pid_t;
|
||||||
|
#elif defined(__LP32__)
|
||||||
|
typedef int32_t off_t;
|
||||||
|
typedef long long off64_t;
|
||||||
typedef __INT32_TYPE__ mode_t;
|
typedef __INT32_TYPE__ mode_t;
|
||||||
|
typedef int32_t dev_t;
|
||||||
|
typedef int32_t ino64_t;
|
||||||
|
typedef int32_t ino_t;
|
||||||
|
typedef unsigned int nlink_t;
|
||||||
|
typedef int blksize_t;
|
||||||
|
typedef int32_t blkcnt_t;
|
||||||
|
typedef int32_t blkcnt64_t;
|
||||||
|
typedef int32_t time_t;
|
||||||
|
typedef unsigned uid_t;
|
||||||
|
typedef unsigned gid_t;
|
||||||
|
typedef long clock_t;
|
||||||
typedef int pid_t;
|
typedef int pid_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define UNUSED(x) (void)(x)
|
#define UNUSED(x) (void)(x)
|
||||||
|
|
||||||
@ -108,4 +138,49 @@ typedef __builtin_va_list va_list;
|
|||||||
#define TO_PAGES(d) (((d) + PAGE_SIZE - 1) / PAGE_SIZE)
|
#define TO_PAGES(d) (((d) + PAGE_SIZE - 1) / PAGE_SIZE)
|
||||||
#define FROM_PAGES(d) ((d) * PAGE_SIZE)
|
#define FROM_PAGES(d) ((d) * PAGE_SIZE)
|
||||||
|
|
||||||
|
#define __unused __attribute__((unused))
|
||||||
|
#define __packed __attribute__((packed))
|
||||||
|
#define __naked __attribute__((naked))
|
||||||
|
#define __aligned(x) __attribute__((aligned(x)))
|
||||||
|
#define __section(x) __attribute__((section(x)))
|
||||||
|
#define __noreturn __attribute__((noreturn))
|
||||||
|
#define __weak __attribute__((weak))
|
||||||
|
#define __alias(x) __attribute__((alias(x)))
|
||||||
|
#define __always_inline __attribute__((always_inline))
|
||||||
|
#define __noinline __attribute__((noinline))
|
||||||
|
#define __pure __attribute__((pure))
|
||||||
|
#define __const __attribute__((const))
|
||||||
|
#define __malloc __attribute__((malloc))
|
||||||
|
#define __returns_twice __attribute__((returns_twice))
|
||||||
|
#define __used __attribute__((used))
|
||||||
|
#define __deprecated __attribute__((deprecated))
|
||||||
|
#define __deprecated_msg(x) __attribute__((deprecated(x)))
|
||||||
|
#define __weakref(x) __attribute__((weakref(x)))
|
||||||
|
#define __weakrefalias(x) __attribute__((weakref(#x)))
|
||||||
|
#define __visibility(x) __attribute__((visibility(x)))
|
||||||
|
#define __constructor __attribute__((constructor))
|
||||||
|
#define __destructor __attribute__((destructor))
|
||||||
|
#define __cleanup(x) __attribute__((cleanup(x)))
|
||||||
|
#define __fallthrough __attribute__((fallthrough))
|
||||||
|
#define __nonnull(x) __attribute__((nonnull x))
|
||||||
|
#define __nonnull_all __attribute__((nonnull))
|
||||||
|
#define __returns_nonnull __attribute__((returns_nonnull))
|
||||||
|
#define __sentinel __attribute__((sentinel))
|
||||||
|
#define __sentinel_all __attribute__((sentinel(0)))
|
||||||
|
#define __format(x, y, z) __attribute__((format(x, y, z)))
|
||||||
|
#define __format_arg(x) __attribute__((format_arg(x)))
|
||||||
|
#define __nonnull_params(x) __attribute__((nonnull x))
|
||||||
|
#define __nonnull_all __attribute__((nonnull))
|
||||||
|
#define __warn_unused_result __attribute__((warn_unused_result))
|
||||||
|
#define __no_stack_protector __attribute__((no_stack_protector))
|
||||||
|
#define __no_instrument_function __attribute__((no_instrument_function))
|
||||||
|
#define __no_debug __attribute__((no_debug))
|
||||||
|
#define __target(x) __attribute__((target(x)))
|
||||||
|
#define __min_vector_width(x) __attribute__((min_vector_width(x)))
|
||||||
|
|
||||||
|
#define __sync __sync_synchronize()
|
||||||
|
#define __unreachable __builtin_unreachable()
|
||||||
|
#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
|
||||||
#endif // !__FENNIX_API_TYPES_H__
|
#endif // !__FENNIX_API_TYPES_H__
|
||||||
|
@ -1,83 +1,22 @@
|
|||||||
# Config file
|
# Config files
|
||||||
include ../../../Makefile.conf
|
include ../../../Makefile.conf
|
||||||
|
include ../../config.mk
|
||||||
FILENAME = aip.drv
|
|
||||||
|
|
||||||
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
|
||||||
CPP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
|
||||||
LD = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
|
||||||
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
|
||||||
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
|
||||||
|
|
||||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||||
INCLUDE_DIR = ../../include
|
|
||||||
|
|
||||||
LIBS := ../../out/dcrt0.o -L../../out -ldriver
|
FILENAME = aip.drv
|
||||||
|
|
||||||
LDFLAGS := \
|
|
||||||
-fPIC -fPIE -pie \
|
|
||||||
-Wl,--no-dynamic-linker,-ztext,--no-warn-rwx-segment \
|
|
||||||
-nostdlib -nodefaultlibs -nolibc \
|
|
||||||
-zmax-page-size=0x1000 \
|
|
||||||
-Wl,-Map file.map -shared -fvisibility=hidden
|
|
||||||
|
|
||||||
WARNCFLAG = -Wall -Wextra
|
|
||||||
|
|
||||||
CFLAGS := -I$(INCLUDE_DIR) -fvisibility=hidden
|
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 \
|
|
||||||
-march=x86-64 -pipe -ffunction-sections \
|
|
||||||
-msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), i386)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
|
|
||||||
-march=i386 -pipe -msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), aarch64)
|
|
||||||
|
|
||||||
CFLAGS += -pipe -fno-builtin -fPIC
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(DEBUG), 1)
|
|
||||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
CFLAGS += -fverbose-asm
|
|
||||||
endif
|
|
||||||
ifneq ($(OSARCH), aarch64)
|
|
||||||
CFLAGS += -fstack-check
|
|
||||||
endif
|
|
||||||
LDFLAGS += -ggdb3 -O0
|
|
||||||
endif
|
|
||||||
|
|
||||||
build: $(FILENAME)
|
build: $(FILENAME)
|
||||||
mv $(FILENAME) ../../out/$(FILENAME)
|
mv $(FILENAME) ../../out/$(FILENAME)
|
||||||
|
|
||||||
$(FILENAME): $(OBJ)
|
$(FILENAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
$(CC) $(LDFLAGS) $(OBJ) $(LIBS) -o $@
|
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||||
|
|
||||||
%.o: %.c $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CC) $(CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.cpp $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CPP) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.S
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(AS) -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <driver.h>
|
#include <driver.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fs.h>
|
||||||
#include <input.h>
|
#include <input.h>
|
||||||
#include <base.h>
|
#include <base.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
@ -161,6 +162,17 @@ const unsigned short ScanCodeSet3[] = {
|
|||||||
[0x4B] = KEY_L,
|
[0x4B] = KEY_L,
|
||||||
[0x4D] = KEY_P};
|
[0x4D] = KEY_P};
|
||||||
|
|
||||||
|
InputReport kir = {0};
|
||||||
|
int ReportKeyboardEvent(dev_t Device, KeyScanCodes ScanCode, uint8_t Pressed)
|
||||||
|
{
|
||||||
|
kir.Type = INPUT_TYPE_KEYBOARD;
|
||||||
|
kir.Device = Device;
|
||||||
|
kir.Keyboard.Key = ScanCode;
|
||||||
|
kir.Keyboard.Key |= Pressed ? KEY_PRESSED : 0;
|
||||||
|
ReportInputEvent(&kir);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsE0 = false;
|
bool IsE0 = false;
|
||||||
bool IsE1 = false;
|
bool IsE1 = false;
|
||||||
void PS2KbdInterruptHandler(TrapFrame *)
|
void PS2KbdInterruptHandler(TrapFrame *)
|
||||||
@ -217,12 +229,21 @@ void PS2KbdInterruptHandler(TrapFrame *)
|
|||||||
{
|
{
|
||||||
if (IsE0)
|
if (IsE0)
|
||||||
IsE0 = false;
|
IsE0 = false;
|
||||||
Log("Unknown PS/2 Keyboard Scan Code Set: %#x", KeyboardScanCodeSet);
|
KernelLog("Unknown PS/2 Keyboard Scan Code Set: %#x", KeyboardScanCodeSet);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __fs_kb_Ioctl(struct Inode *, unsigned long, void *)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct InodeOperations KbdOps = {
|
||||||
|
.Ioctl = __fs_kb_Ioctl,
|
||||||
|
};
|
||||||
|
|
||||||
int InitializeKeyboard()
|
int InitializeKeyboard()
|
||||||
{
|
{
|
||||||
// PS2WriteData(PS2_KBD_CMD_RESET);
|
// PS2WriteData(PS2_KBD_CMD_RESET);
|
||||||
@ -230,45 +251,50 @@ int InitializeKeyboard()
|
|||||||
// if (test != PS2_KBD_RESP_TEST_PASSED &&
|
// if (test != PS2_KBD_RESP_TEST_PASSED &&
|
||||||
// test != PS2_KBD_RESP_ACK)
|
// test != PS2_KBD_RESP_ACK)
|
||||||
// {
|
// {
|
||||||
// Log("PS/2 keyboard reset failed (%#x)", test);
|
// KernelLog("PS/2 keyboard reset failed (%#x)", test);
|
||||||
// return -EFAULT;
|
// return -EFAULT;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
PS2WriteData(PS2_KBD_CMD_DEFAULTS);
|
PS2WriteData(PS2_KBD_CMD_DEFAULTS);
|
||||||
if (PS2ACKTimeout() != 0)
|
if (PS2ACKTimeout() != 0)
|
||||||
Log("PS/2 keyboard failed to set defaults");
|
KernelLog("PS/2 keyboard failed to set defaults");
|
||||||
|
|
||||||
PS2WriteData(PS2_KBD_CMD_SCAN_CODE_SET);
|
PS2WriteData(PS2_KBD_CMD_SCAN_CODE_SET);
|
||||||
if (PS2ACKTimeout() != 0)
|
if (PS2ACKTimeout() != 0)
|
||||||
Log("PS/2 keyboard failed to set scan code set");
|
KernelLog("PS/2 keyboard failed to set scan code set");
|
||||||
|
|
||||||
/* We want Scan Code Set 1 */
|
/* We want Scan Code Set 1 */
|
||||||
PS2WriteData(PS2_KBD_SCAN_CODE_SET_2); /* It will set to 1 but with translation? */
|
PS2WriteData(PS2_KBD_SCAN_CODE_SET_2); /* It will set to 1 but with translation? */
|
||||||
if (PS2ACKTimeout() != 0)
|
if (PS2ACKTimeout() != 0)
|
||||||
Log("PS/2 keyboard failed to set scan code set 2");
|
KernelLog("PS/2 keyboard failed to set scan code set 2");
|
||||||
|
|
||||||
PS2WriteData(PS2_KBD_CMD_SCAN_CODE_SET);
|
PS2WriteData(PS2_KBD_CMD_SCAN_CODE_SET);
|
||||||
if (PS2ACKTimeout() != 0)
|
if (PS2ACKTimeout() != 0)
|
||||||
Log("PS/2 keyboard failed to set scan code set");
|
KernelLog("PS/2 keyboard failed to set scan code set");
|
||||||
|
|
||||||
PS2WriteData(PS2_KBD_SCAN_CODE_GET_CURRENT);
|
PS2WriteData(PS2_KBD_SCAN_CODE_GET_CURRENT);
|
||||||
if (PS2ACKTimeout() != 0)
|
if (PS2ACKTimeout() != 0)
|
||||||
Log("PS/2 keyboard failed to get current scan code set");
|
KernelLog("PS/2 keyboard failed to get current scan code set");
|
||||||
|
|
||||||
KeyboardScanCodeSet = PS2ReadAfterACK();
|
KeyboardScanCodeSet = PS2ReadAfterACK();
|
||||||
Log("PS/2 Keyboard Scan Code Set: 0x%X", KeyboardScanCodeSet);
|
KernelLog("PS/2 Keyboard Scan Code Set: 0x%X", KeyboardScanCodeSet);
|
||||||
PS2ClearOutputBuffer();
|
PS2ClearOutputBuffer();
|
||||||
|
|
||||||
PS2WriteData(PS2_KBD_CMD_ENABLE_SCANNING);
|
PS2WriteData(PS2_KBD_CMD_ENABLE_SCANNING);
|
||||||
|
|
||||||
RegisterInterruptHandler(1, PS2KbdInterruptHandler);
|
RegisterInterruptHandler(1, PS2KbdInterruptHandler);
|
||||||
KeyboardDevID = RegisterInputDevice(ddt_Keyboard);
|
|
||||||
|
KeyboardDevID = RegisterDevice(INPUT_TYPE_KEYBOARD, &KbdOps);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FinalizeKeyboard()
|
int FinalizeKeyboard()
|
||||||
{
|
{
|
||||||
UnregisterInputDevice(KeyboardDevID, ddt_Keyboard);
|
PS2WriteData(PS2_KBD_CMD_DISABLE_SCANNING);
|
||||||
|
if (PS2ACKTimeout() != 0)
|
||||||
|
KernelLog("PS/2 keyboard failed to disable scanning");
|
||||||
|
|
||||||
|
UnregisterDevice(KeyboardDevID);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,11 +302,11 @@ int DetectPS2Keyboard()
|
|||||||
{
|
{
|
||||||
PS2WriteData(PS2_KBD_CMD_DISABLE_SCANNING);
|
PS2WriteData(PS2_KBD_CMD_DISABLE_SCANNING);
|
||||||
if (PS2ACKTimeout() != 0)
|
if (PS2ACKTimeout() != 0)
|
||||||
Log("PS/2 keyboard failed to disable scanning");
|
KernelLog("PS/2 keyboard failed to disable scanning");
|
||||||
|
|
||||||
PS2WriteData(PS2_KBD_CMD_IDENTIFY);
|
PS2WriteData(PS2_KBD_CMD_IDENTIFY);
|
||||||
if (PS2ACKTimeout() != 0)
|
if (PS2ACKTimeout() != 0)
|
||||||
Log("PS/2 keyboard failed to identify");
|
KernelLog("PS/2 keyboard failed to identify");
|
||||||
|
|
||||||
uint8_t recByte;
|
uint8_t recByte;
|
||||||
int timeout = 1000000;
|
int timeout = 1000000;
|
||||||
@ -300,10 +326,10 @@ int DetectPS2Keyboard()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (timeout == 0)
|
if (timeout == 0)
|
||||||
Log("PS/2 keyboard second byte timed out");
|
KernelLog("PS/2 keyboard second byte timed out");
|
||||||
else
|
else
|
||||||
Device1ID[1] = recByte;
|
Device1ID[1] = recByte;
|
||||||
|
|
||||||
Log("PS2 Keyboard Device: 0x%X 0x%X", Device1ID[0], Device1ID[1]);
|
KernelLog("PS2 Keyboard Device: 0x%X 0x%X", Device1ID[0], Device1ID[1]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ int DriverEntry()
|
|||||||
|
|
||||||
DualChannel = cfg.Port2Clock;
|
DualChannel = cfg.Port2Clock;
|
||||||
if (DualChannel)
|
if (DualChannel)
|
||||||
Log("Dual channel PS/2 controller detected");
|
KernelLog("Dual channel PS/2 controller detected");
|
||||||
cfg.Port1Interrupt = 1;
|
cfg.Port1Interrupt = 1;
|
||||||
cfg.Port2Interrupt = 1;
|
cfg.Port2Interrupt = 1;
|
||||||
cfg.Port1Translation = 1;
|
cfg.Port1Translation = 1;
|
||||||
@ -116,7 +116,7 @@ int DriverEntry()
|
|||||||
uint8_t test = PS2ReadData();
|
uint8_t test = PS2ReadData();
|
||||||
if (test != PS2_TEST_PASSED)
|
if (test != PS2_TEST_PASSED)
|
||||||
{
|
{
|
||||||
Log("PS/2 controller self test failed (%#x)", test);
|
KernelLog("PS/2 controller self test failed (%#x)", test);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ int DriverEntry()
|
|||||||
test = PS2ReadData();
|
test = PS2ReadData();
|
||||||
if (test != 0x00)
|
if (test != 0x00)
|
||||||
{
|
{
|
||||||
Log("PS/2 Port 1 self test failed (%#x)", test);
|
KernelLog("PS/2 Port 1 self test failed (%#x)", test);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ int DriverEntry()
|
|||||||
test = PS2ReadData();
|
test = PS2ReadData();
|
||||||
if (test != 0x00)
|
if (test != 0x00)
|
||||||
{
|
{
|
||||||
Log("PS/2 Port 2 self test failed (%#x)", test);
|
KernelLog("PS/2 Port 2 self test failed (%#x)", test);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ int DriverProbe()
|
|||||||
{
|
{
|
||||||
if (!IsKeyboard(Device1ID[0]))
|
if (!IsKeyboard(Device1ID[0]))
|
||||||
{
|
{
|
||||||
Log("PS/2 Port 1 is not a keyboard");
|
KernelLog("PS/2 Port 1 is not a keyboard");
|
||||||
// return -EINVAL;
|
// return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,15 +213,15 @@ int DriverProbe()
|
|||||||
{
|
{
|
||||||
if (!IsMouse(Device2ID[0]))
|
if (!IsMouse(Device2ID[0]))
|
||||||
{
|
{
|
||||||
Log("PS/2 Port 2 is not a mouse");
|
KernelLog("PS/2 Port 2 is not a mouse");
|
||||||
// return -EINVAL;
|
// return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KPrint("PS/2 Port 1: %s (0x%X 0x%X)",
|
KernelPrint("PS/2 Port 1: %s (0x%X 0x%X)",
|
||||||
GetPS2DeviceName(Device1ID[0], Device1ID[1]),
|
GetPS2DeviceName(Device1ID[0], Device1ID[1]),
|
||||||
Device1ID[0], Device1ID[1]);
|
Device1ID[0], Device1ID[1]);
|
||||||
KPrint("PS/2 Port 2: %s (0x%X 0x%X)",
|
KernelPrint("PS/2 Port 2: %s (0x%X 0x%X)",
|
||||||
GetPS2DeviceName(Device2ID[0], Device2ID[1]),
|
GetPS2DeviceName(Device2ID[0], Device2ID[1]),
|
||||||
Device2ID[0], Device2ID[1]);
|
Device2ID[0], Device2ID[1]);
|
||||||
return 0;
|
return 0;
|
||||||
@ -230,5 +230,5 @@ int DriverProbe()
|
|||||||
DriverInfo("aip",
|
DriverInfo("aip",
|
||||||
"Advanced Integrated Peripheral Driver",
|
"Advanced Integrated Peripheral Driver",
|
||||||
"EnderIce2",
|
"EnderIce2",
|
||||||
"0.1",
|
0, 0, 1,
|
||||||
"GPLv3");
|
"GPLv3");
|
||||||
|
@ -18,8 +18,9 @@
|
|||||||
#include "aip.h"
|
#include "aip.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <input.h>
|
|
||||||
#include <base.h>
|
#include <base.h>
|
||||||
|
#include <fs.h>
|
||||||
|
#include <input.h>
|
||||||
|
|
||||||
dev_t MouseDevID = -1;
|
dev_t MouseDevID = -1;
|
||||||
bool PacketReady = false;
|
bool PacketReady = false;
|
||||||
@ -28,6 +29,7 @@ bool MouseButton45 = false;
|
|||||||
uint8_t Cycle = 0;
|
uint8_t Cycle = 0;
|
||||||
PS2_MOUSE_PACKET Packet = {0};
|
PS2_MOUSE_PACKET Packet = {0};
|
||||||
|
|
||||||
|
InputReport mir = {0};
|
||||||
void PS2MouseInterruptHandler(TrapFrame *)
|
void PS2MouseInterruptHandler(TrapFrame *)
|
||||||
{
|
{
|
||||||
uint8_t data = PS2ReadData();
|
uint8_t data = PS2ReadData();
|
||||||
@ -114,18 +116,17 @@ void PS2MouseInterruptHandler(TrapFrame *)
|
|||||||
if (Packet.Base.YOverflow)
|
if (Packet.Base.YOverflow)
|
||||||
Y = 0;
|
Y = 0;
|
||||||
|
|
||||||
MouseReport mr = {
|
mir.Type = INPUT_TYPE_MOUSE;
|
||||||
.LeftButton = Packet.Base.LeftButton,
|
mir.Device = MouseDevID;
|
||||||
.RightButton = Packet.Base.RightButton,
|
mir.Mouse.LeftButton = Packet.Base.LeftButton;
|
||||||
.MiddleButton = Packet.Base.MiddleButton,
|
mir.Mouse.RightButton = Packet.Base.RightButton;
|
||||||
.Button4 = Packet.ZMovement.Button4,
|
mir.Mouse.MiddleButton = Packet.Base.MiddleButton;
|
||||||
.Button5 = Packet.ZMovement.Button5,
|
mir.Mouse.Button4 = Packet.ZMovement.Button4;
|
||||||
.X = X,
|
mir.Mouse.Button5 = Packet.ZMovement.Button5;
|
||||||
.Y = -Y,
|
mir.Mouse.X = X;
|
||||||
.Z = Packet.ZMovement.Z,
|
mir.Mouse.Y = -Y;
|
||||||
};
|
mir.Mouse.Z = Packet.ZMovement.Z;
|
||||||
ReportRelativeMouseEvent(MouseDevID, mr);
|
ReportInputEvent(&mir);
|
||||||
|
|
||||||
PacketReady = false;
|
PacketReady = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,6 +141,15 @@ void MouseSampleRate(uint8_t SampleRate)
|
|||||||
PS2ReadData();
|
PS2ReadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __fs_ms_Ioctl(struct Inode *, unsigned long, void *)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct InodeOperations MouseOps = {
|
||||||
|
.Ioctl = __fs_ms_Ioctl,
|
||||||
|
};
|
||||||
|
|
||||||
int InitializeMouse()
|
int InitializeMouse()
|
||||||
{
|
{
|
||||||
PS2WriteData(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
PS2WriteData(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||||
@ -148,12 +158,13 @@ int InitializeMouse()
|
|||||||
if (test != PS2_MOUSE_RESP_TEST_PASSED &&
|
if (test != PS2_MOUSE_RESP_TEST_PASSED &&
|
||||||
test != PS2_MOUSE_RESP_ACK)
|
test != PS2_MOUSE_RESP_ACK)
|
||||||
{
|
{
|
||||||
Log("PS/2 mouse reset failed! (%#x)", test);
|
KernelLog("PS/2 mouse reset failed! (%#x)", test);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterInterruptHandler(12, PS2MouseInterruptHandler);
|
RegisterInterruptHandler(12, PS2MouseInterruptHandler);
|
||||||
MouseDevID = RegisterInputDevice(ddt_Mouse);
|
|
||||||
|
MouseDevID = RegisterDevice(INPUT_TYPE_MOUSE, &MouseOps);
|
||||||
|
|
||||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||||
PS2WriteData(PS2_MOUSE_CMD_SET_DEFAULTS);
|
PS2WriteData(PS2_MOUSE_CMD_SET_DEFAULTS);
|
||||||
@ -169,7 +180,7 @@ int InitializeMouse()
|
|||||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||||
PS2WriteData(PS2_MOUSE_CMD_READ_ID);
|
PS2WriteData(PS2_MOUSE_CMD_READ_ID);
|
||||||
uint8_t Device2ID = PS2ReadData();
|
uint8_t Device2ID = PS2ReadData();
|
||||||
Log("PS/2 Mouse ID: %#x", Device2ID);
|
KernelLog("PS/2 Mouse ID: %#x", Device2ID);
|
||||||
|
|
||||||
MouseSampleRate(200);
|
MouseSampleRate(200);
|
||||||
MouseSampleRate(200);
|
MouseSampleRate(200);
|
||||||
@ -178,7 +189,7 @@ int InitializeMouse()
|
|||||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||||
PS2WriteData(PS2_MOUSE_CMD_READ_ID);
|
PS2WriteData(PS2_MOUSE_CMD_READ_ID);
|
||||||
Device2ID = PS2ReadData();
|
Device2ID = PS2ReadData();
|
||||||
Log("PS/2 Mouse ID: %#x", Device2ID);
|
KernelLog("PS/2 Mouse ID: %#x", Device2ID);
|
||||||
|
|
||||||
if (Device2ID >= 3 && Device2ID <= 4)
|
if (Device2ID >= 3 && Device2ID <= 4)
|
||||||
FourPackets = true;
|
FourPackets = true;
|
||||||
@ -190,10 +201,10 @@ int InitializeMouse()
|
|||||||
|
|
||||||
int FinalizeMouse()
|
int FinalizeMouse()
|
||||||
{
|
{
|
||||||
UnregisterInputDevice(MouseDevID, ddt_Mouse);
|
|
||||||
|
|
||||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||||
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
|
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
|
||||||
|
|
||||||
|
UnregisterDevice(MouseDevID);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,12 +213,12 @@ int DetectPS2Mouse()
|
|||||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||||
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
|
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
|
||||||
if (PS2ACKTimeout() != 0)
|
if (PS2ACKTimeout() != 0)
|
||||||
Log("PS/2 mouse failed to disable data reporting!");
|
KernelLog("PS/2 mouse failed to disable data reporting!");
|
||||||
|
|
||||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||||
PS2WriteData(PS2_MOUSE_CMD_READ_ID);
|
PS2WriteData(PS2_MOUSE_CMD_READ_ID);
|
||||||
if (PS2ACKTimeout() != 0)
|
if (PS2ACKTimeout() != 0)
|
||||||
Log("PS/2 mouse failed to read ID!");
|
KernelLog("PS/2 mouse failed to read ID!");
|
||||||
|
|
||||||
uint8_t recByte;
|
uint8_t recByte;
|
||||||
int timeout = 1000000;
|
int timeout = 1000000;
|
||||||
@ -228,6 +239,6 @@ int DetectPS2Mouse()
|
|||||||
}
|
}
|
||||||
Device2ID[1] = recByte;
|
Device2ID[1] = recByte;
|
||||||
|
|
||||||
Log("PS2 Mouse Device: 0x%X 0x%X", Device2ID[0], Device2ID[1]);
|
KernelLog("PS2 Mouse Device: 0x%X 0x%X", Device2ID[0], Device2ID[1]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Config file
|
# Config file
|
||||||
include ../../Makefile.conf
|
include ../../Makefile.conf
|
||||||
|
|
||||||
FILENAME = libdriver.a
|
FILENAME = libkernel.so
|
||||||
|
|
||||||
CC = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
CC = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
||||||
CPP = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
CPP = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
||||||
@ -17,15 +17,12 @@ OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURC
|
|||||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||||
INCLUDE_DIR = ../include
|
INCLUDE_DIR = ../include
|
||||||
|
|
||||||
LDFLAGS := \
|
LDFLAGS := -fPIC -fPIE -pie -nostdlib -nodefaultlibs -nolibc \
|
||||||
-fPIC -fPIE -pie \
|
-zmax-page-size=0x1000 -Wl,-Map libkernel.map -shared
|
||||||
-nostdlib -nodefaultlibs -nolibc \
|
|
||||||
-zmax-page-size=0x1000 \
|
|
||||||
-Wl,-Map driver.map -static -fvisibility=hidden
|
|
||||||
|
|
||||||
WARNCFLAG = -Wall -Wextra
|
WARNCFLAG = -Wall -Wextra
|
||||||
|
|
||||||
CFLAGS := -I$(INCLUDE_DIR) -fvisibility=hidden
|
CFLAGS := -I$(INCLUDE_DIR) -shared
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
ifeq ($(OSARCH), amd64)
|
||||||
|
|
||||||
@ -46,25 +43,29 @@ CFLAGS += -pipe -fno-builtin -fPIC
|
|||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
CRT_CFLAGS := -fPIC -fPIE -pie -mno-red-zone -std=c++20 -I../include
|
||||||
|
|
||||||
ifeq ($(DEBUG), 1)
|
ifeq ($(DEBUG), 1)
|
||||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
||||||
|
CRT_CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
||||||
ifeq ($(OSARCH), amd64)
|
ifeq ($(OSARCH), amd64)
|
||||||
CFLAGS += -fverbose-asm
|
CFLAGS += -fverbose-asm
|
||||||
|
CRT_CFLAGS += -fverbose-asm
|
||||||
endif
|
endif
|
||||||
ifneq ($(OSARCH), aarch64)
|
ifneq ($(OSARCH), aarch64)
|
||||||
CFLAGS += -fstack-check
|
CFLAGS += -fstack-check
|
||||||
|
CRT_CFLAGS += -fstack-check
|
||||||
endif
|
endif
|
||||||
LDFLAGS += -ggdb3 -O0
|
LDFLAGS += -ggdb3 -O0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
build: $(FILENAME)
|
build: $(FILENAME)
|
||||||
$(CC) $(CFLAGS) $(WARNCFLAG) -std=c17 -shared -c crt/crt0.c -o dcrt0.o
|
$(CPP) $(CRT_CFLAGS) -c crt/crt0.cpp -o dcrt0.o
|
||||||
mv dcrt0.o ../out/dcrt0.o
|
mv dcrt0.o ../out/dcrt0.o
|
||||||
|
|
||||||
$(FILENAME): $(OBJ)
|
$(FILENAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
$(AR) rcs $@ $(OBJ)
|
$(CC) $(LDFLAGS) $(OBJ) -o ../out/$(FILENAME)
|
||||||
mv $(FILENAME) ../out/$(FILENAME)
|
|
||||||
|
|
||||||
%.o: %.c $(HEADERS)
|
%.o: %.c $(HEADERS)
|
||||||
$(info Compiling $<)
|
$(info Compiling $<)
|
||||||
@ -79,4 +80,4 @@ $(FILENAME): $(OBJ)
|
|||||||
$(AS) -o $@ $<
|
$(AS) -o $@ $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f driver.map $(OBJ) $(FILENAME) $(STACK_USAGE_OBJ) dcrt0.su
|
rm -f libkernel.map $(OBJ) $(FILENAME) $(STACK_USAGE_OBJ) dcrt0.su
|
||||||
|
146
library/aip.c
146
library/aip.c
@ -1,146 +0,0 @@
|
|||||||
/*
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <aip.h>
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <io.h>
|
|
||||||
|
|
||||||
extern void Log(const char *Format, ...);
|
|
||||||
|
|
||||||
void PIC_EOI(uint8_t IRQ)
|
|
||||||
{
|
|
||||||
if (IRQ >= 8)
|
|
||||||
outb(PIC2_CMD, _PIC_EOI);
|
|
||||||
outb(PIC1_CMD, _PIC_EOI);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IRQ_MASK(uint8_t IRQ)
|
|
||||||
{
|
|
||||||
uint16_t port;
|
|
||||||
uint8_t value;
|
|
||||||
|
|
||||||
if (IRQ < 8)
|
|
||||||
port = PIC1_DATA;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
port = PIC2_DATA;
|
|
||||||
IRQ -= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = inb(port) | (1 << IRQ);
|
|
||||||
outb(port, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IRQ_UNMASK(uint8_t IRQ)
|
|
||||||
{
|
|
||||||
uint16_t port;
|
|
||||||
uint8_t value;
|
|
||||||
|
|
||||||
if (IRQ < 8)
|
|
||||||
port = PIC1_DATA;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
port = PIC2_DATA;
|
|
||||||
IRQ -= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = inb(port) & ~(1 << IRQ);
|
|
||||||
outb(port, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PS2Wait(const bool Output)
|
|
||||||
{
|
|
||||||
int Timeout = 100000;
|
|
||||||
PS2_STATUSES Status = {.Raw = inb(PS2_STATUS)};
|
|
||||||
while (Timeout--)
|
|
||||||
{
|
|
||||||
if (!Output) /* FIXME: Reverse? */
|
|
||||||
{
|
|
||||||
if (Status.OutputBufferFull == 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (Status.InputBufferFull == 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Status.Raw = inb(PS2_STATUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log("PS/2 controller timeout! (Status: %#x, %d)", Status, Output);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PS2WriteCommand(uint8_t Command)
|
|
||||||
{
|
|
||||||
WaitInput;
|
|
||||||
outb(PS2_CMD, Command);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PS2WriteData(uint8_t Data)
|
|
||||||
{
|
|
||||||
WaitInput;
|
|
||||||
outb(PS2_DATA, Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t PS2ReadData()
|
|
||||||
{
|
|
||||||
WaitOutput;
|
|
||||||
return inb(PS2_DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t PS2ReadStatus()
|
|
||||||
{
|
|
||||||
WaitOutput;
|
|
||||||
return inb(PS2_STATUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t PS2ReadAfterACK()
|
|
||||||
{
|
|
||||||
uint8_t ret = PS2ReadData();
|
|
||||||
while (ret == PS2_ACK)
|
|
||||||
{
|
|
||||||
WaitOutput;
|
|
||||||
ret = inb(PS2_DATA);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PS2ClearOutputBuffer()
|
|
||||||
{
|
|
||||||
PS2_STATUSES Status;
|
|
||||||
int timeout = 0x500;
|
|
||||||
while (timeout--)
|
|
||||||
{
|
|
||||||
Status.Raw = inb(PS2_STATUS);
|
|
||||||
if (Status.OutputBufferFull == 0)
|
|
||||||
return;
|
|
||||||
inb(PS2_DATA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int PS2ACKTimeout()
|
|
||||||
{
|
|
||||||
int timeout = 0x500;
|
|
||||||
while (timeout > 0)
|
|
||||||
{
|
|
||||||
if (PS2ReadData() == PS2_ACK)
|
|
||||||
return 0;
|
|
||||||
timeout--;
|
|
||||||
}
|
|
||||||
return -ETIMEDOUT;
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <audio.h>
|
|
||||||
|
|
||||||
extern __driverAPI *API;
|
|
||||||
|
|
||||||
dev_t RegisterAudioDevice(DeviceDriverType Type, drvOpen_t Open, drvClose_t Close,
|
|
||||||
drvRead_t Read, drvWrite_t Write, drvIoctl_t Ioctl)
|
|
||||||
{
|
|
||||||
return API->RegisterAudioDevice(API->MajorID, Type, Open, Close, Read, Write, Ioctl);
|
|
||||||
}
|
|
||||||
|
|
||||||
int UnregisterAudioDevice(dev_t DeviceID, DeviceDriverType Type)
|
|
||||||
{
|
|
||||||
return API->UnregisterAudioDevice(API->MajorID, DeviceID, Type);
|
|
||||||
}
|
|
182
library/base.c
182
library/base.c
@ -1,182 +0,0 @@
|
|||||||
/*
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <base.h>
|
|
||||||
|
|
||||||
#include <driver.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
__driverAPI *API = NULL;
|
|
||||||
|
|
||||||
int RegisterInterruptHandler(uint8_t IRQ, void *Handler)
|
|
||||||
{
|
|
||||||
if (Handler == NULL)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return API->RegisterInterruptHandler(API->MajorID,
|
|
||||||
IRQ,
|
|
||||||
Handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
int OverrideInterruptHandler(uint8_t IRQ, void *Handler)
|
|
||||||
{
|
|
||||||
if (Handler == NULL)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return API->OverrideInterruptHandler(API->MajorID,
|
|
||||||
IRQ,
|
|
||||||
Handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
int UnregisterInterruptHandler(uint8_t IRQ, void *Handler)
|
|
||||||
{
|
|
||||||
if (Handler == NULL)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return API->UnregisterInterruptHandler(API->MajorID,
|
|
||||||
IRQ,
|
|
||||||
Handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
int UnregisterAllInterruptHandlers(void *Handler)
|
|
||||||
{
|
|
||||||
if (Handler == NULL)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return API->UnregisterAllInterruptHandlers(API->MajorID,
|
|
||||||
Handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *AllocateMemory(size_t Pages)
|
|
||||||
{
|
|
||||||
if (Pages == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return API->RequestPages(API->MajorID,
|
|
||||||
Pages);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FreeMemory(void *Pointer, size_t Pages)
|
|
||||||
{
|
|
||||||
if (Pointer == NULL || Pages == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
API->FreePages(API->MajorID,
|
|
||||||
Pointer,
|
|
||||||
Pages);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppendMapFlag(void *Address, PageMapFlags Flag)
|
|
||||||
{
|
|
||||||
API->AppendMapFlag(API->MajorID,
|
|
||||||
Address,
|
|
||||||
Flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoveMapFlag(void *Address, PageMapFlags Flag)
|
|
||||||
{
|
|
||||||
API->RemoveMapFlag(API->MajorID,
|
|
||||||
Address,
|
|
||||||
Flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapPages(void *PhysicalAddress, void *VirtualAddress, size_t Pages, uint32_t Flags)
|
|
||||||
{
|
|
||||||
API->MapPages(API->MajorID,
|
|
||||||
PhysicalAddress,
|
|
||||||
VirtualAddress,
|
|
||||||
Pages,
|
|
||||||
Flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnmapPages(void *VirtualAddress, size_t Pages)
|
|
||||||
{
|
|
||||||
API->UnmapPages(API->MajorID,
|
|
||||||
VirtualAddress,
|
|
||||||
Pages);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KPrint(const char *Format, ...)
|
|
||||||
{
|
|
||||||
va_list Args;
|
|
||||||
va_start(Args, Format);
|
|
||||||
|
|
||||||
API->KPrint(API->MajorID,
|
|
||||||
Format,
|
|
||||||
Args);
|
|
||||||
|
|
||||||
va_end(Args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Log(const char *Format, ...)
|
|
||||||
{
|
|
||||||
va_list Args;
|
|
||||||
va_start(Args, Format);
|
|
||||||
|
|
||||||
API->KernelLog(API->MajorID,
|
|
||||||
Format,
|
|
||||||
Args);
|
|
||||||
|
|
||||||
va_end(Args);
|
|
||||||
}
|
|
||||||
|
|
||||||
CriticalState EnterCriticalSection()
|
|
||||||
{
|
|
||||||
CriticalState cs;
|
|
||||||
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
|
||||||
|
|
||||||
uintptr_t Flags;
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
asmv("pushfq");
|
|
||||||
asmv("popq %0"
|
|
||||||
: "=r"(Flags));
|
|
||||||
#else
|
|
||||||
asmv("pushfl");
|
|
||||||
asmv("popl %0"
|
|
||||||
: "=r"(Flags));
|
|
||||||
#endif
|
|
||||||
cs = Flags & (1 << 9);
|
|
||||||
asmv("cli");
|
|
||||||
|
|
||||||
#elif defined(__arm__) || defined(__aarch64__)
|
|
||||||
|
|
||||||
uintptr_t Flags;
|
|
||||||
asmv("mrs %0, cpsr"
|
|
||||||
: "=r"(Flags));
|
|
||||||
cs = Flags & (1 << 7);
|
|
||||||
asmv("cpsid i");
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return cs;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LeaveCriticalSection(CriticalState PreviousState)
|
|
||||||
{
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
|
||||||
|
|
||||||
if (PreviousState)
|
|
||||||
asmv("sti");
|
|
||||||
|
|
||||||
#elif defined(__arm__) || defined(__aarch64__)
|
|
||||||
|
|
||||||
if (PreviousState)
|
|
||||||
asmv("cpsie i");
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
94
library/base.cpp
Normal file
94
library/base.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <base.h>
|
||||||
|
|
||||||
|
#include <driver.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fs.h>
|
||||||
|
|
||||||
|
extern "C" dev_t DriverID;
|
||||||
|
|
||||||
|
#define KernelFunction(Name) \
|
||||||
|
extern "C" __attribute__((naked, used)) long \
|
||||||
|
__##Name(dev_t, long, long, long, \
|
||||||
|
long, long, long) { return 0; }
|
||||||
|
|
||||||
|
void *operator new(__SIZE_TYPE__) { return (void *)1; }
|
||||||
|
void *operator new[](__SIZE_TYPE__) { return (void *)1; }
|
||||||
|
void operator delete(void *) {}
|
||||||
|
void operator delete[](void *) {}
|
||||||
|
void operator delete(void *, __SIZE_TYPE__) {}
|
||||||
|
void operator delete[](void *, __SIZE_TYPE__) {}
|
||||||
|
|
||||||
|
KernelFunction(KernelPrint);
|
||||||
|
KernelFunction(KernelLog);
|
||||||
|
|
||||||
|
KernelFunction(RegisterInterruptHandler);
|
||||||
|
KernelFunction(OverrideInterruptHandler);
|
||||||
|
KernelFunction(UnregisterInterruptHandler);
|
||||||
|
KernelFunction(UnregisterAllInterruptHandlers);
|
||||||
|
|
||||||
|
KernelFunction(AllocateMemory);
|
||||||
|
KernelFunction(FreeMemory);
|
||||||
|
KernelFunction(AppendMapFlag);
|
||||||
|
KernelFunction(RemoveMapFlag);
|
||||||
|
KernelFunction(MapPages);
|
||||||
|
KernelFunction(UnmapPages);
|
||||||
|
|
||||||
|
KernelFunction(MemoryCopy);
|
||||||
|
KernelFunction(MemorySet);
|
||||||
|
KernelFunction(MemoryMove);
|
||||||
|
KernelFunction(StringLength);
|
||||||
|
KernelFunction(strstr);
|
||||||
|
|
||||||
|
KernelFunction(EnterCriticalSection);
|
||||||
|
KernelFunction(LeaveCriticalSection);
|
||||||
|
|
||||||
|
KernelFunction(CreateKernelProcess);
|
||||||
|
KernelFunction(CreateKernelThread);
|
||||||
|
KernelFunction(GetCurrentProcess);
|
||||||
|
KernelFunction(KillProcess);
|
||||||
|
KernelFunction(KillThread);
|
||||||
|
KernelFunction(Yield);
|
||||||
|
KernelFunction(Sleep);
|
||||||
|
|
||||||
|
KernelFunction(RegisterFileSystem);
|
||||||
|
KernelFunction(UnregisterFileSystem);
|
||||||
|
|
||||||
|
KernelFunction(PIC_EOI);
|
||||||
|
KernelFunction(IRQ_MASK);
|
||||||
|
KernelFunction(IRQ_UNMASK);
|
||||||
|
KernelFunction(PS2Wait);
|
||||||
|
KernelFunction(PS2WriteCommand);
|
||||||
|
KernelFunction(PS2WriteData);
|
||||||
|
KernelFunction(PS2ReadData);
|
||||||
|
KernelFunction(PS2ReadStatus);
|
||||||
|
KernelFunction(PS2ReadAfterACK);
|
||||||
|
KernelFunction(PS2ClearOutputBuffer);
|
||||||
|
KernelFunction(PS2ACKTimeout);
|
||||||
|
|
||||||
|
KernelFunction(RegisterDevice);
|
||||||
|
KernelFunction(UnregisterDevice);
|
||||||
|
|
||||||
|
KernelFunction(ReportInputEvent);
|
||||||
|
|
||||||
|
KernelFunction(InitializePCI);
|
||||||
|
KernelFunction(GetPCIDevices);
|
||||||
|
KernelFunction(GetBAR);
|
||||||
|
KernelFunction(iLine);
|
||||||
|
KernelFunction(iPin);
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <block.h>
|
|
||||||
|
|
||||||
extern __driverAPI *API;
|
|
||||||
|
|
||||||
dev_t RegisterBlockDevice(DeviceDriverType Type, drvOpen_t Open, drvClose_t Close,
|
|
||||||
drvRead_t Read, drvWrite_t Write, drvIoctl_t Ioctl)
|
|
||||||
{
|
|
||||||
return API->RegisterBlockDevice(API->MajorID, Type, Open, Close, Read, Write, Ioctl);
|
|
||||||
}
|
|
||||||
|
|
||||||
int UnregisterBlockDevice(dev_t DeviceID, DeviceDriverType Type)
|
|
||||||
{
|
|
||||||
return API->UnregisterBlockDevice(API->MajorID, DeviceID, Type);
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <driver.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
extern __driverAPI *API;
|
|
||||||
|
|
||||||
int DriverEntry();
|
|
||||||
int DriverFinal();
|
|
||||||
int DriverPanic();
|
|
||||||
int DriverProbe();
|
|
||||||
void __IdentifyDriver(
|
|
||||||
dev_t ID,
|
|
||||||
int (*GetDriverInfo)(dev_t, const char *, const char *,
|
|
||||||
const char *, const char *, const char *));
|
|
||||||
|
|
||||||
typedef void (*CallPtr)(void);
|
|
||||||
extern CallPtr __init_array_start[0], __init_array_end[0];
|
|
||||||
extern CallPtr __fini_array_start[0], __fini_array_end[0];
|
|
||||||
|
|
||||||
int _entry()
|
|
||||||
{
|
|
||||||
for (CallPtr *func = __init_array_start; func != __init_array_end; func++)
|
|
||||||
(*func)();
|
|
||||||
|
|
||||||
return DriverEntry();
|
|
||||||
}
|
|
||||||
|
|
||||||
int _final()
|
|
||||||
{
|
|
||||||
int err = DriverFinal();
|
|
||||||
|
|
||||||
for (CallPtr *func = __fini_array_start; func != __fini_array_end; func++)
|
|
||||||
(*func)();
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define API_MajorRequiredVersion 0
|
|
||||||
#define API_MinorRequiredVersion 0
|
|
||||||
#define API_PatchRequiredVersion 0
|
|
||||||
|
|
||||||
int _start(__driverAPI *__API)
|
|
||||||
{
|
|
||||||
if (unlikely(__API == NULL))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (unlikely(__API->APIVersion.Major != API_MajorRequiredVersion ||
|
|
||||||
__API->APIVersion.Minor != API_MinorRequiredVersion ||
|
|
||||||
__API->APIVersion.Patch != API_PatchRequiredVersion))
|
|
||||||
return -EPROTO;
|
|
||||||
|
|
||||||
if (unlikely(__API->RegisterFunction == NULL))
|
|
||||||
return -ENOSYS;
|
|
||||||
|
|
||||||
if (unlikely(DriverEntry == NULL ||
|
|
||||||
DriverFinal == NULL ||
|
|
||||||
DriverPanic == NULL ||
|
|
||||||
DriverProbe == NULL ||
|
|
||||||
__IdentifyDriver == NULL))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
API = __API;
|
|
||||||
__API->RegisterFunction(__API->MajorID, _entry, _drf_Entry);
|
|
||||||
__API->RegisterFunction(__API->MajorID, _final, _drf_Final);
|
|
||||||
__API->RegisterFunction(__API->MajorID, DriverPanic, _drf_Panic);
|
|
||||||
__API->RegisterFunction(__API->MajorID, DriverProbe, _drf_Probe);
|
|
||||||
__IdentifyDriver(__API->MajorID, __API->GetDriverInfo);
|
|
||||||
return 0;
|
|
||||||
}
|
|
144
library/crt/crt0.cpp
Normal file
144
library/crt/crt0.cpp
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <driver.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
dev_t DriverID = -1;
|
||||||
|
|
||||||
|
extern "C" int DriverEntry();
|
||||||
|
extern "C" int DriverFinal();
|
||||||
|
extern "C" int DriverPanic();
|
||||||
|
extern "C" int DriverProbe();
|
||||||
|
|
||||||
|
typedef void (*CallPtr)(void);
|
||||||
|
extern "C" CallPtr __init_array_start[0], __init_array_end[0];
|
||||||
|
extern "C" CallPtr __fini_array_start[0], __fini_array_end[0];
|
||||||
|
|
||||||
|
extern "C" int _start(dev_t id)
|
||||||
|
{
|
||||||
|
DriverID = id;
|
||||||
|
|
||||||
|
for (CallPtr *func = __init_array_start; func != __init_array_end; func++)
|
||||||
|
(*func)();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int _final()
|
||||||
|
{
|
||||||
|
int err = DriverFinal();
|
||||||
|
|
||||||
|
for (CallPtr *func = __fini_array_start; func != __fini_array_end; func++)
|
||||||
|
(*func)();
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------- */
|
||||||
|
|
||||||
|
#define KCALL extern "C" __attribute__((used))
|
||||||
|
|
||||||
|
#define KernelFunction(Name) \
|
||||||
|
KCALL long __##Name(dev_t id, \
|
||||||
|
long arg0 = 0, long arg1 = 0, long arg2 = 0, \
|
||||||
|
long arg3 = 0, long arg4 = 0, long arg5 = 0);
|
||||||
|
|
||||||
|
#define DefineFunction(ReturnType, Name, ...) \
|
||||||
|
KernelFunction(Name); \
|
||||||
|
KCALL ReturnType Name(__VA_ARGS__)
|
||||||
|
|
||||||
|
#define DefineWrapper(Name) \
|
||||||
|
KernelFunction(Name); \
|
||||||
|
KCALL long Name(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5) \
|
||||||
|
{ \
|
||||||
|
return __##Name(DriverID, arg0, arg1, arg2, arg3, arg4, arg5); \
|
||||||
|
}
|
||||||
|
|
||||||
|
DefineFunction(void, KernelPrint, const char *format, ...)
|
||||||
|
{
|
||||||
|
__builtin_va_list args;
|
||||||
|
__builtin_va_start(args, format);
|
||||||
|
__KernelPrint(DriverID, (long)format, (long)args);
|
||||||
|
__builtin_va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
DefineFunction(void, KernelLog, const char *format, ...)
|
||||||
|
{
|
||||||
|
__builtin_va_list args;
|
||||||
|
__builtin_va_start(args, format);
|
||||||
|
__KernelLog(DriverID, (long)format, (long)args);
|
||||||
|
__builtin_va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
DefineWrapper(RegisterInterruptHandler);
|
||||||
|
DefineWrapper(OverrideInterruptHandler);
|
||||||
|
DefineWrapper(UnregisterInterruptHandler);
|
||||||
|
DefineWrapper(UnregisterAllInterruptHandlers);
|
||||||
|
|
||||||
|
DefineWrapper(AllocateMemory);
|
||||||
|
DefineWrapper(FreeMemory);
|
||||||
|
DefineWrapper(AppendMapFlag);
|
||||||
|
DefineWrapper(RemoveMapFlag);
|
||||||
|
DefineWrapper(MapPages);
|
||||||
|
DefineWrapper(UnmapPages);
|
||||||
|
|
||||||
|
DefineWrapper(MemoryCopy);
|
||||||
|
DefineWrapper(MemorySet);
|
||||||
|
DefineWrapper(MemoryMove);
|
||||||
|
DefineWrapper(StringLength);
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch"
|
||||||
|
DefineWrapper(strstr);
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
DefineWrapper(EnterCriticalSection);
|
||||||
|
DefineWrapper(LeaveCriticalSection);
|
||||||
|
|
||||||
|
DefineWrapper(CreateKernelProcess);
|
||||||
|
DefineWrapper(CreateKernelThread);
|
||||||
|
DefineWrapper(GetCurrentProcess);
|
||||||
|
DefineWrapper(KillProcess);
|
||||||
|
DefineWrapper(KillThread);
|
||||||
|
DefineWrapper(Yield);
|
||||||
|
DefineWrapper(Sleep);
|
||||||
|
|
||||||
|
DefineWrapper(RegisterFileSystem);
|
||||||
|
DefineWrapper(UnregisterFileSystem);
|
||||||
|
|
||||||
|
DefineWrapper(PIC_EOI);
|
||||||
|
DefineWrapper(IRQ_MASK);
|
||||||
|
DefineWrapper(IRQ_UNMASK);
|
||||||
|
DefineWrapper(PS2Wait);
|
||||||
|
DefineWrapper(PS2WriteCommand);
|
||||||
|
DefineWrapper(PS2WriteData);
|
||||||
|
DefineWrapper(PS2ReadData);
|
||||||
|
DefineWrapper(PS2ReadStatus);
|
||||||
|
DefineWrapper(PS2ReadAfterACK);
|
||||||
|
DefineWrapper(PS2ClearOutputBuffer);
|
||||||
|
DefineWrapper(PS2ACKTimeout);
|
||||||
|
|
||||||
|
DefineWrapper(RegisterDevice);
|
||||||
|
DefineWrapper(UnregisterDevice);
|
||||||
|
|
||||||
|
DefineWrapper(ReportInputEvent);
|
||||||
|
|
||||||
|
DefineWrapper(InitializePCI);
|
||||||
|
DefineWrapper(GetPCIDevices);
|
||||||
|
DefineWrapper(GetBAR);
|
||||||
|
DefineWrapper(iLine);
|
||||||
|
DefineWrapper(iPin);
|
@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <input.h>
|
|
||||||
|
|
||||||
extern __driverAPI *API;
|
|
||||||
|
|
||||||
dev_t RegisterInputDevice(DeviceDriverType Type)
|
|
||||||
{
|
|
||||||
return API->RegisterInputDevice(API->MajorID, Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
int UnregisterInputDevice(dev_t DeviceID, DeviceDriverType Type)
|
|
||||||
{
|
|
||||||
return API->UnregisterInputDevice(API->MajorID, DeviceID, Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ReportKeyboardEvent(dev_t DeviceID, KeyScanCodes ScanCode, uint8_t Pressed)
|
|
||||||
{
|
|
||||||
if (Pressed)
|
|
||||||
ScanCode |= KEY_PRESSED;
|
|
||||||
return API->ReportKeyboardEvent(API->MajorID, DeviceID, ScanCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ReportRelativeMouseEvent(dev_t DeviceID, MouseReport Report)
|
|
||||||
{
|
|
||||||
__MouseButtons mb = {
|
|
||||||
.LeftButton = Report.LeftButton,
|
|
||||||
.RightButton = Report.RightButton,
|
|
||||||
.MiddleButton = Report.MiddleButton,
|
|
||||||
.Button4 = Report.Button4,
|
|
||||||
.Button5 = Report.Button5,
|
|
||||||
};
|
|
||||||
return API->ReportRelativeMouseEvent(API->MajorID, DeviceID, mb, Report.X, Report.Y, Report.Z);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ReportAbsoluteMouseEvent(dev_t DeviceID, MouseReport Report, uintptr_t X, uintptr_t Y)
|
|
||||||
{
|
|
||||||
__MouseButtons mb = {
|
|
||||||
.LeftButton = Report.LeftButton,
|
|
||||||
.RightButton = Report.RightButton,
|
|
||||||
.MiddleButton = Report.MiddleButton,
|
|
||||||
.Button4 = Report.Button4,
|
|
||||||
.Button5 = Report.Button5,
|
|
||||||
};
|
|
||||||
return API->ReportAbsoluteMouseEvent(API->MajorID, DeviceID, mb, X, Y, Report.Z);
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <net.h>
|
|
||||||
|
|
||||||
extern __driverAPI *API;
|
|
||||||
|
|
||||||
dev_t RegisterNetDevice(DeviceDriverType Type, drvOpen_t Open, drvClose_t Close,
|
|
||||||
drvRead_t Read, drvWrite_t Write, drvIoctl_t Ioctl)
|
|
||||||
{
|
|
||||||
return API->RegisterNetDevice(API->MajorID, Type, Open, Close, Read, Write, Ioctl);
|
|
||||||
}
|
|
||||||
|
|
||||||
int UnregisterNetDevice(dev_t DeviceID, DeviceDriverType Type)
|
|
||||||
{
|
|
||||||
return API->UnregisterNetDevice(API->MajorID, DeviceID, Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ReportNetworkPacket(dev_t DeviceID, void *Buffer, size_t Size)
|
|
||||||
{
|
|
||||||
return API->ReportNetworkPacket(API->MajorID, DeviceID, Buffer, Size);
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <pci.h>
|
|
||||||
|
|
||||||
#include <driver.h>
|
|
||||||
|
|
||||||
extern __driverAPI *API;
|
|
||||||
|
|
||||||
static_assert(sizeof(PCIArray) == sizeof(__PCIArray),
|
|
||||||
"PCIArray size mismatch");
|
|
||||||
|
|
||||||
PCIArray *FindPCIDevices(uint16_t Vendors[], uint16_t Devices[])
|
|
||||||
{
|
|
||||||
return (PCIArray *)API->GetPCIDevices(API->MajorID,
|
|
||||||
Vendors,
|
|
||||||
Devices);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitializePCI(PCIDevice *Device)
|
|
||||||
{
|
|
||||||
API->InitializePCI(API->MajorID,
|
|
||||||
(void *)Device->Header);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t GetBAR(uint8_t Index, PCIDevice *Device)
|
|
||||||
{
|
|
||||||
return API->GetBAR(API->MajorID,
|
|
||||||
Index,
|
|
||||||
(void *)Device->Header);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t iLine(PCIDevice *Device)
|
|
||||||
{
|
|
||||||
PCIHeader0 *Header = (PCIHeader0 *)Device->Header;
|
|
||||||
return Header->InterruptLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t iPin(PCIDevice *Device)
|
|
||||||
{
|
|
||||||
PCIHeader0 *Header = (PCIHeader0 *)Device->Header;
|
|
||||||
return Header->InterruptPin;
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <base.h>
|
|
||||||
#include <driver.h>
|
|
||||||
|
|
||||||
#undef memcpy
|
|
||||||
#undef memset
|
|
||||||
#undef memmove
|
|
||||||
#undef strlen
|
|
||||||
|
|
||||||
extern __driverAPI *API;
|
|
||||||
|
|
||||||
void *MemoryCopy(void *Destination, const void *Source, size_t Length)
|
|
||||||
{
|
|
||||||
return API->memcpy(API->MajorID, Destination, Source, Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *MemorySet(void *Destination, int Value, size_t Length)
|
|
||||||
{
|
|
||||||
return API->memset(API->MajorID, Destination, Value, Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *MemoryMove(void *Destination, const void *Source, size_t Length)
|
|
||||||
{
|
|
||||||
return API->memmove(API->MajorID, Destination, Source, Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t StringLength(const char String[])
|
|
||||||
{
|
|
||||||
return API->strlen(API->MajorID, String);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *strstr(const char *Haystack, const char *Needle)
|
|
||||||
{
|
|
||||||
return API->strstr(API->MajorID, Haystack, Needle);
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <base.h>
|
|
||||||
#include <driver.h>
|
|
||||||
|
|
||||||
extern __driverAPI *API;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: memory allocator
|
|
||||||
* we can't really call kernel's malloc because the
|
|
||||||
* kernel keep track of memory usage for each driver
|
|
||||||
*
|
|
||||||
* maybe implement the allocator in vma?
|
|
||||||
*/
|
|
||||||
|
|
||||||
void *__new_alloc_page(std::size_t Size)
|
|
||||||
{
|
|
||||||
/* Do not allow allocations larger than 4 KiB */
|
|
||||||
if (Size > PAGE_SIZE)
|
|
||||||
asmv("ud2");
|
|
||||||
|
|
||||||
return API->RequestPages(API->MajorID, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __delete_alloc_page(void *Pointer)
|
|
||||||
{
|
|
||||||
API->FreePages(API->MajorID, Pointer, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *operator new(std::size_t Size)
|
|
||||||
{
|
|
||||||
return __new_alloc_page(Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *operator new[](std::size_t Size)
|
|
||||||
{
|
|
||||||
return __new_alloc_page(Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator delete(void *Pointer)
|
|
||||||
{
|
|
||||||
__delete_alloc_page(Pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator delete[](void *Pointer)
|
|
||||||
{
|
|
||||||
__delete_alloc_page(Pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator delete(void *Pointer, std::size_t)
|
|
||||||
{
|
|
||||||
__delete_alloc_page(Pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator delete[](void *Pointer, std::size_t)
|
|
||||||
{
|
|
||||||
__delete_alloc_page(Pointer);
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <driver.h>
|
|
||||||
#include <base.h>
|
|
||||||
|
|
||||||
extern __driverAPI *API;
|
|
||||||
|
|
||||||
pid_t CreateKernelProcess(const char *Name)
|
|
||||||
{
|
|
||||||
return API->CreateKernelProcess(API->MajorID,
|
|
||||||
Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
pid_t CreateKernelThread(pid_t pId, const char *Name, void *EntryPoint, void *Argument)
|
|
||||||
{
|
|
||||||
return API->CreateKernelThread(API->MajorID,
|
|
||||||
pId,
|
|
||||||
Name,
|
|
||||||
EntryPoint,
|
|
||||||
Argument);
|
|
||||||
}
|
|
||||||
|
|
||||||
pid_t GetCurrentProcess()
|
|
||||||
{
|
|
||||||
return API->GetCurrentProcess(API->MajorID);
|
|
||||||
}
|
|
||||||
|
|
||||||
int KillProcess(pid_t pId, int ExitCode)
|
|
||||||
{
|
|
||||||
return API->KillProcess(API->MajorID,
|
|
||||||
pId, ExitCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
int KillThread(pid_t tId, pid_t pId, int ExitCode)
|
|
||||||
{
|
|
||||||
return API->KillThread(API->MajorID,
|
|
||||||
tId, pId, ExitCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Yield()
|
|
||||||
{
|
|
||||||
API->Yield(API->MajorID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sleep(uint64_t Milliseconds)
|
|
||||||
{
|
|
||||||
API->Sleep(API->MajorID,
|
|
||||||
Milliseconds);
|
|
||||||
}
|
|
114
library/vm.c
114
library/vm.c
@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <vm.h>
|
|
||||||
|
|
||||||
int __strcmp(const char *l, const char *r)
|
|
||||||
{
|
|
||||||
for (; *l == *r && *l; l++, r++)
|
|
||||||
;
|
|
||||||
|
|
||||||
return *(unsigned char *)l - *(unsigned char *)r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __cpuid(uint32_t Function,
|
|
||||||
uint32_t *eax, uint32_t *ebx,
|
|
||||||
uint32_t *ecx, uint32_t *edx)
|
|
||||||
{
|
|
||||||
asmv("cpuid"
|
|
||||||
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
|
||||||
: "a"(Function));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool __CheckHypervisorBit()
|
|
||||||
{
|
|
||||||
uint32_t eax, ebx, ecx, edx;
|
|
||||||
__cpuid(0x1, &eax, &ebx, &ecx, &edx);
|
|
||||||
if (!(ecx & (1 << 31)))
|
|
||||||
return false; /* Hypervisor not detected */
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool __VMwareBackdoorHypervisors()
|
|
||||||
{
|
|
||||||
const char hv[13] = {0};
|
|
||||||
uint32_t eax, ebx, ecx, edx;
|
|
||||||
__cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
|
|
||||||
|
|
||||||
*(uint32_t *)hv = ebx;
|
|
||||||
*(uint32_t *)(hv + 4) = ecx;
|
|
||||||
*(uint32_t *)(hv + 8) = edx;
|
|
||||||
|
|
||||||
if (__strcmp(hv, "VMwareVMware") != 0 &&
|
|
||||||
__strcmp(hv, "KVMKVMKVM") != 0 &&
|
|
||||||
__strcmp(hv, "TCGTCGTCGTCG") != 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsVMwareBackdoorAvailable()
|
|
||||||
{
|
|
||||||
if (!__CheckHypervisorBit())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!__VMwareBackdoorHypervisors())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
uint32_t ax;
|
|
||||||
uint32_t magic;
|
|
||||||
};
|
|
||||||
union
|
|
||||||
{
|
|
||||||
uint32_t bx;
|
|
||||||
size_t size;
|
|
||||||
};
|
|
||||||
union
|
|
||||||
{
|
|
||||||
uint32_t cx;
|
|
||||||
uint16_t command;
|
|
||||||
};
|
|
||||||
union
|
|
||||||
{
|
|
||||||
uint32_t dx;
|
|
||||||
uint16_t port;
|
|
||||||
};
|
|
||||||
uint32_t si;
|
|
||||||
uint32_t di;
|
|
||||||
} cmd;
|
|
||||||
|
|
||||||
cmd.si = cmd.di = 0;
|
|
||||||
cmd.bx = ~0x564D5868;
|
|
||||||
cmd.command = 0xA;
|
|
||||||
cmd.magic = 0x564D5868;
|
|
||||||
cmd.port = 0x5658;
|
|
||||||
|
|
||||||
asmv("in %%dx, %0"
|
|
||||||
: "+a"(cmd.ax), "+b"(cmd.bx),
|
|
||||||
"+c"(cmd.cx), "+d"(cmd.dx),
|
|
||||||
"+S"(cmd.si), "+D"(cmd.di));
|
|
||||||
|
|
||||||
if (cmd.bx != 0x564D5868 ||
|
|
||||||
cmd.ax == 0xFFFFFFFF)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,83 +1,22 @@
|
|||||||
# Config file
|
# Config files
|
||||||
include ../../../Makefile.conf
|
include ../../../Makefile.conf
|
||||||
|
include ../../config.mk
|
||||||
FILENAME = example.drv
|
|
||||||
|
|
||||||
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
|
||||||
CPP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
|
||||||
LD = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
|
||||||
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
|
||||||
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
|
||||||
|
|
||||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||||
INCLUDE_DIR = ../../include
|
|
||||||
|
|
||||||
LIBS := ../../out/dcrt0.o -L../../out -ldriver
|
FILENAME = example.drv
|
||||||
|
|
||||||
LDFLAGS := \
|
|
||||||
-fPIC -fPIE -pie \
|
|
||||||
-Wl,--no-dynamic-linker,-ztext,--no-warn-rwx-segment \
|
|
||||||
-nostdlib -nodefaultlibs -nolibc \
|
|
||||||
-zmax-page-size=0x1000 \
|
|
||||||
-Wl,-Map file.map -shared -fvisibility=hidden
|
|
||||||
|
|
||||||
WARNCFLAG = -Wall -Wextra
|
|
||||||
|
|
||||||
CFLAGS := -I$(INCLUDE_DIR) -fvisibility=hidden
|
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 \
|
|
||||||
-march=x86-64 -pipe -ffunction-sections \
|
|
||||||
-msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), i386)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
|
|
||||||
-march=i386 -pipe -msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), aarch64)
|
|
||||||
|
|
||||||
CFLAGS += -pipe -fno-builtin -fPIC
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(DEBUG), 1)
|
|
||||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
CFLAGS += -fverbose-asm
|
|
||||||
endif
|
|
||||||
ifneq ($(OSARCH), aarch64)
|
|
||||||
CFLAGS += -fstack-check
|
|
||||||
endif
|
|
||||||
LDFLAGS += -ggdb3 -O0
|
|
||||||
endif
|
|
||||||
|
|
||||||
build: $(FILENAME)
|
build: $(FILENAME)
|
||||||
mv $(FILENAME) ../../out/$(FILENAME)
|
mv $(FILENAME) ../../out/$(FILENAME)
|
||||||
|
|
||||||
$(FILENAME): $(OBJ)
|
$(FILENAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
$(CC) $(LDFLAGS) $(OBJ) $(LIBS) -o $@
|
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||||
|
|
||||||
%.o: %.c $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CC) $(CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.cpp $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CPP) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.S
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(AS) -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
||||||
|
@ -20,16 +20,15 @@
|
|||||||
int DriverEntry()
|
int DriverEntry()
|
||||||
{
|
{
|
||||||
/** This is the main function of the driver.
|
/** This is the main function of the driver.
|
||||||
* This function is called when the driver is loaded.
|
|
||||||
* This function should be used to initialize the PCI device
|
* This function should be used to initialize the PCI device
|
||||||
* and allocate resources.
|
* and allocate resources.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Print a message to the screen */
|
/* Print a message to the kernel terminal */
|
||||||
KPrint("Hello World from Example Driver!");
|
KernelPrint("Hello World from Example Driver!");
|
||||||
|
|
||||||
/* Print a message to the kernel log */
|
/* Print a message to the kernel log */
|
||||||
Log("Hello World from Example Driver!");
|
KernelLog("Hello World from Example Driver!");
|
||||||
|
|
||||||
/* Print a message only if DEBUG is set */
|
/* Print a message only if DEBUG is set */
|
||||||
DebugLog("Hello World from Example Driver!");
|
DebugLog("Hello World from Example Driver!");
|
||||||
@ -52,7 +51,7 @@ int DriverPanic()
|
|||||||
{
|
{
|
||||||
/** This function is called when the kernel panics.
|
/** This function is called when the kernel panics.
|
||||||
* This function should be used to stop the driver from
|
* This function should be used to stop the driver from
|
||||||
* receiving interrupts or anything else that is not
|
* sending interrupts or anything else that is not
|
||||||
* safe to do when the kernel panics.
|
* safe to do when the kernel panics.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -63,13 +62,14 @@ int DriverProbe()
|
|||||||
{
|
{
|
||||||
/** This is the first function that is called when the
|
/** This is the first function that is called when the
|
||||||
* driver is loaded.
|
* driver is loaded.
|
||||||
* We can use this function to test if the driver is
|
*
|
||||||
* compatible with the hardware.
|
* This function is to test if the driver is compatible
|
||||||
* Like if we have a specific PCI device or if we have
|
* with the hardware.
|
||||||
* a specific CPU feature.
|
* Example: Like if there is a PCI device that the driver
|
||||||
|
* is for, or a CPU feature that etc.
|
||||||
*
|
*
|
||||||
* Return 0 if the driver is compatible with the hardware.
|
* Return 0 if the driver is compatible with the hardware.
|
||||||
* Otherwise, we return a value from the errno.h header.
|
* Otherwise, return a value that is not 0.
|
||||||
*
|
*
|
||||||
* Note: In this function you cannot use variables that
|
* Note: In this function you cannot use variables that
|
||||||
* have constructors or destructors. Before DriverEntry,
|
* have constructors or destructors. Before DriverEntry,
|
||||||
@ -80,8 +80,18 @@ int DriverProbe()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DriverInfo() is a macro that is used to define the
|
||||||
|
* driver's information.
|
||||||
|
*
|
||||||
|
* The parameters are:
|
||||||
|
* - Name: Lowercase name
|
||||||
|
* - Description: A short description
|
||||||
|
* - Author: The author
|
||||||
|
* - Version: The version
|
||||||
|
* - License: The license
|
||||||
|
*/
|
||||||
DriverInfo("example",
|
DriverInfo("example",
|
||||||
"Example Driver",
|
"Example Driver",
|
||||||
"EnderIce2",
|
"EnderIce2",
|
||||||
"0.1",
|
0, 0, 1,
|
||||||
"GPLv3");
|
"GPLv3");
|
||||||
|
@ -1,83 +1,22 @@
|
|||||||
# Config file
|
# Config files
|
||||||
include ../../../Makefile.conf
|
include ../../../Makefile.conf
|
||||||
|
include ../../config.mk
|
||||||
FILENAME = vmware.drv
|
|
||||||
|
|
||||||
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
|
||||||
CPP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
|
||||||
LD = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
|
||||||
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
|
||||||
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
|
||||||
|
|
||||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||||
INCLUDE_DIR = ../../include
|
|
||||||
|
|
||||||
LIBS := ../../out/dcrt0.o -L../../out -ldriver
|
FILENAME = vmware.drv
|
||||||
|
|
||||||
LDFLAGS := \
|
|
||||||
-fPIC -fPIE -pie \
|
|
||||||
-Wl,--no-dynamic-linker,-ztext,--no-warn-rwx-segment \
|
|
||||||
-nostdlib -nodefaultlibs -nolibc \
|
|
||||||
-zmax-page-size=0x1000 \
|
|
||||||
-Wl,-Map file.map -shared -fvisibility=hidden
|
|
||||||
|
|
||||||
WARNCFLAG = -Wall -Wextra
|
|
||||||
|
|
||||||
CFLAGS := -I$(INCLUDE_DIR) -fvisibility=hidden
|
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 \
|
|
||||||
-march=x86-64 -pipe -ffunction-sections \
|
|
||||||
-msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), i386)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
|
|
||||||
-march=i386 -pipe -msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), aarch64)
|
|
||||||
|
|
||||||
CFLAGS += -pipe -fno-builtin -fPIC
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(DEBUG), 1)
|
|
||||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
CFLAGS += -fverbose-asm
|
|
||||||
endif
|
|
||||||
ifneq ($(OSARCH), aarch64)
|
|
||||||
CFLAGS += -fstack-check
|
|
||||||
endif
|
|
||||||
LDFLAGS += -ggdb3 -O0
|
|
||||||
endif
|
|
||||||
|
|
||||||
build: $(FILENAME)
|
build: $(FILENAME)
|
||||||
mv $(FILENAME) ../../out/$(FILENAME)
|
mv $(FILENAME) ../../out/$(FILENAME)
|
||||||
|
|
||||||
$(FILENAME): $(OBJ)
|
$(FILENAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
$(CC) $(LDFLAGS) $(OBJ) $(LIBS) -o $@
|
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||||
|
|
||||||
%.o: %.c $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CC) $(CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.cpp $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CPP) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.S
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(AS) -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
||||||
|
@ -17,11 +17,11 @@
|
|||||||
|
|
||||||
#include <driver.h>
|
#include <driver.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fs.h>
|
||||||
#include <input.h>
|
#include <input.h>
|
||||||
#include <regs.h>
|
#include <regs.h>
|
||||||
#include <base.h>
|
#include <base.h>
|
||||||
#include <aip.h>
|
#include <aip.h>
|
||||||
#include <vm.h>
|
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
|
||||||
enum RPCMessages
|
enum RPCMessages
|
||||||
@ -170,7 +170,7 @@ typedef struct
|
|||||||
"r"(bp) : "memory", "cc")
|
"r"(bp) : "memory", "cc")
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
- use vmcall or vmmcall instead of out or in if available
|
- use vmcall or vmmcall instead of "out" and "in" if available
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -183,6 +183,102 @@ typedef struct
|
|||||||
|
|
||||||
dev_t MouseDevID = -1;
|
dev_t MouseDevID = -1;
|
||||||
|
|
||||||
|
int __strcmp(const char *l, const char *r)
|
||||||
|
{
|
||||||
|
for (; *l == *r && *l; l++, r++)
|
||||||
|
;
|
||||||
|
|
||||||
|
return *(unsigned char *)l - *(unsigned char *)r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cpuid(uint32_t Function,
|
||||||
|
uint32_t *eax, uint32_t *ebx,
|
||||||
|
uint32_t *ecx, uint32_t *edx)
|
||||||
|
{
|
||||||
|
asmv("cpuid"
|
||||||
|
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
||||||
|
: "a"(Function));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool __CheckHypervisorBit()
|
||||||
|
{
|
||||||
|
uint32_t eax, ebx, ecx, edx;
|
||||||
|
__cpuid(0x1, &eax, &ebx, &ecx, &edx);
|
||||||
|
if (!(ecx & (1 << 31)))
|
||||||
|
return false; /* Hypervisor not detected */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool __VMwareBackdoorHypervisors()
|
||||||
|
{
|
||||||
|
const char hv[13] = {0};
|
||||||
|
uint32_t eax, ebx, ecx, edx;
|
||||||
|
__cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
|
||||||
|
|
||||||
|
*(uint32_t *)hv = ebx;
|
||||||
|
*(uint32_t *)(hv + 4) = ecx;
|
||||||
|
*(uint32_t *)(hv + 8) = edx;
|
||||||
|
|
||||||
|
if (__strcmp(hv, "VMwareVMware") != 0 &&
|
||||||
|
__strcmp(hv, "KVMKVMKVM") != 0 &&
|
||||||
|
__strcmp(hv, "TCGTCGTCGTCG") != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsVMwareBackdoorAvailable()
|
||||||
|
{
|
||||||
|
if (!__CheckHypervisorBit())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!__VMwareBackdoorHypervisors())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_t ax;
|
||||||
|
uint32_t magic;
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_t bx;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_t cx;
|
||||||
|
uint16_t command;
|
||||||
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_t dx;
|
||||||
|
uint16_t port;
|
||||||
|
};
|
||||||
|
uint32_t si;
|
||||||
|
uint32_t di;
|
||||||
|
} cmd;
|
||||||
|
|
||||||
|
cmd.si = cmd.di = 0;
|
||||||
|
cmd.bx = ~0x564D5868;
|
||||||
|
cmd.command = 0xA;
|
||||||
|
cmd.magic = 0x564D5868;
|
||||||
|
cmd.port = 0x5658;
|
||||||
|
|
||||||
|
asmv("in %%dx, %0"
|
||||||
|
: "+a"(cmd.ax), "+b"(cmd.bx),
|
||||||
|
"+c"(cmd.cx), "+d"(cmd.dx),
|
||||||
|
"+S"(cmd.si), "+D"(cmd.di));
|
||||||
|
|
||||||
|
if (cmd.bx != 0x564D5868 ||
|
||||||
|
cmd.ax == 0xFFFFFFFF)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int OpenMessageChannel(ToolboxContext *ctx, uint32_t Protocol)
|
static int OpenMessageChannel(ToolboxContext *ctx, uint32_t Protocol)
|
||||||
{
|
{
|
||||||
uintptr_t ax, bx, cx, dx, si = 0, di = 0;
|
uintptr_t ax, bx, cx, dx, si = 0, di = 0;
|
||||||
@ -194,7 +290,7 @@ static int OpenMessageChannel(ToolboxContext *ctx, uint32_t Protocol)
|
|||||||
|
|
||||||
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
|
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
|
||||||
{
|
{
|
||||||
Log("Failed to open message channel %#lx", Protocol);
|
KernelLog("Failed to open message channel %#lx", Protocol);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,8 +439,8 @@ static int MessageSend(ToolboxContext *ctx,
|
|||||||
|
|
||||||
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
|
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
|
||||||
{
|
{
|
||||||
Log("Failed to send message size for \"%s\": %d",
|
KernelLog("Failed to send message size for \"%s\": %d",
|
||||||
Message, cx);
|
Message, cx);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,14 +459,14 @@ static int MessageSend(ToolboxContext *ctx,
|
|||||||
}
|
}
|
||||||
else if ((status & STATUS_CPT) == 0)
|
else if ((status & STATUS_CPT) == 0)
|
||||||
{
|
{
|
||||||
Log("Checkpoint occurred for message \"%s\"", Message);
|
KernelLog("Checkpoint occurred for message \"%s\"", Message);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log("Failed to send message \"%s\": %#lx", Message, bx);
|
KernelLog("Failed to send message \"%s\": %#lx", Message, bx);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,12 +497,12 @@ static int MessageReceive(ToolboxContext *ctx,
|
|||||||
|
|
||||||
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
|
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
|
||||||
{
|
{
|
||||||
Log("Failed to receive message size: %d", cx);
|
KernelLog("Failed to receive message size: %d", cx);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
else if ((HighWord(cx) & STATUS_DORECV) == 0)
|
else if ((HighWord(cx) & STATUS_DORECV) == 0)
|
||||||
{
|
{
|
||||||
// Log("No message to receive");
|
DebugLog("No message to receive");
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,11 +523,11 @@ static int MessageReceive(ToolboxContext *ctx,
|
|||||||
{
|
{
|
||||||
if ((HighWord(bx) & STATUS_CPT) == 0)
|
if ((HighWord(bx) & STATUS_CPT) == 0)
|
||||||
{
|
{
|
||||||
Log("Checkpoint occurred for message payload");
|
KernelLog("Checkpoint occurred for message payload");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log("Failed to receive message payload: %d", HighWord(bx));
|
KernelLog("Failed to receive message payload: %d", HighWord(bx));
|
||||||
FreeMemory(ReplyBuf, ReplyBufPages);
|
FreeMemory(ReplyBuf, ReplyBufPages);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -451,11 +547,11 @@ static int MessageReceive(ToolboxContext *ctx,
|
|||||||
{
|
{
|
||||||
if ((HighWord(cx) & STATUS_CPT) == 0)
|
if ((HighWord(cx) & STATUS_CPT) == 0)
|
||||||
{
|
{
|
||||||
Log("Retrying message receive");
|
KernelLog("Retrying message receive");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log("Failed to receive message status: %d", HighWord(cx));
|
KernelLog("Failed to receive message status: %d", HighWord(cx));
|
||||||
FreeMemory(ReplyBuf, ReplyBufPages);
|
FreeMemory(ReplyBuf, ReplyBufPages);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -465,7 +561,7 @@ static int MessageReceive(ToolboxContext *ctx,
|
|||||||
|
|
||||||
if (ReplyBuf == NULL)
|
if (ReplyBuf == NULL)
|
||||||
{
|
{
|
||||||
Log("Failed to receive message");
|
KernelLog("Failed to receive message");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,14 +577,14 @@ static int SendRPCI(ToolboxContext *, const char *Request)
|
|||||||
int status = OpenMessageChannel(&rpci_ctx, MESSAGE_RPCI);
|
int status = OpenMessageChannel(&rpci_ctx, MESSAGE_RPCI);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
Log("Failed to open RPCI channel: %d", status);
|
KernelLog("Failed to open RPCI channel: %d", status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = MessageSend(&rpci_ctx, Request);
|
status = MessageSend(&rpci_ctx, Request);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
{
|
{
|
||||||
Log("Failed to send RPCI request: %d", status);
|
KernelLog("Failed to send RPCI request: %d", status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,7 +620,7 @@ static int DisplayGetSize(ToolboxContext *ctx)
|
|||||||
}
|
}
|
||||||
else if (status < 0)
|
else if (status < 0)
|
||||||
{
|
{
|
||||||
Log("Failed to receive message");
|
KernelLog("Failed to receive message");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,7 +675,7 @@ void DisplayScaleThread()
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (DisplayGetSize(tb_ctx) != 0)
|
if (DisplayGetSize(tb_ctx) != 0)
|
||||||
Log("Failed to scale display");
|
KernelLog("Failed to scale display");
|
||||||
Sleep(1000);
|
Sleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -627,6 +723,7 @@ void Relative()
|
|||||||
CommandSend(&cmd);
|
CommandSend(&cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InputReport ir = {0};
|
||||||
void InterruptHandler(TrapFrame *)
|
void InterruptHandler(TrapFrame *)
|
||||||
{
|
{
|
||||||
uint8_t Data = inb(0x60);
|
uint8_t Data = inb(0x60);
|
||||||
@ -639,7 +736,7 @@ void InterruptHandler(TrapFrame *)
|
|||||||
|
|
||||||
if (cmd.ax == 0xFFFF0000)
|
if (cmd.ax == 0xFFFF0000)
|
||||||
{
|
{
|
||||||
Log("VMware mouse is not connected?");
|
KernelLog("VMware mouse is not connected?");
|
||||||
Relative();
|
Relative();
|
||||||
Absolute();
|
Absolute();
|
||||||
return;
|
return;
|
||||||
@ -654,17 +751,6 @@ void InterruptHandler(TrapFrame *)
|
|||||||
|
|
||||||
int Buttons = (cmd.ax & 0xFFFF);
|
int Buttons = (cmd.ax & 0xFFFF);
|
||||||
|
|
||||||
MouseReport mr = {
|
|
||||||
.LeftButton = Buttons & 0x20,
|
|
||||||
.RightButton = Buttons & 0x10,
|
|
||||||
.MiddleButton = Buttons & 0x08,
|
|
||||||
.Button4 = 0x0,
|
|
||||||
.Button5 = 0x0,
|
|
||||||
.X = 0,
|
|
||||||
.Y = 0,
|
|
||||||
.Z = (int8_t)cmd.dx,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How should I handle this?
|
* How should I handle this?
|
||||||
* (cmd.[bx,cx] * Width) / 0xFFFF
|
* (cmd.[bx,cx] * Width) / 0xFFFF
|
||||||
@ -672,9 +758,44 @@ void InterruptHandler(TrapFrame *)
|
|||||||
*/
|
*/
|
||||||
uintptr_t AbsoluteX = cmd.bx;
|
uintptr_t AbsoluteX = cmd.bx;
|
||||||
uintptr_t AbsoluteY = cmd.cx;
|
uintptr_t AbsoluteY = cmd.cx;
|
||||||
ReportAbsoluteMouseEvent(MouseDevID, mr, AbsoluteX, AbsoluteY);
|
|
||||||
|
ir.Type = INPUT_TYPE_MOUSE;
|
||||||
|
ir.Device = MouseDevID;
|
||||||
|
ir.Mouse.X = AbsoluteX;
|
||||||
|
ir.Mouse.Y = AbsoluteY;
|
||||||
|
ir.Mouse.Z = (int8_t)cmd.dx;
|
||||||
|
ir.Mouse.Absolute = 1;
|
||||||
|
ir.Mouse.LeftButton = Buttons & 0x20;
|
||||||
|
ir.Mouse.RightButton = Buttons & 0x10;
|
||||||
|
ir.Mouse.MiddleButton = Buttons & 0x08;
|
||||||
|
// ir.Mouse.Button4 = 0x0;
|
||||||
|
// ir.Mouse.Button5 = 0x0;
|
||||||
|
// ir.Mouse.Button6 = 0x0;
|
||||||
|
// ir.Mouse.Button7 = 0x0;
|
||||||
|
// ir.Mouse.Button8 = 0x0;
|
||||||
|
ReportInputEvent(&ir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __fs_Ioctl(struct Inode *, unsigned long Request, void *)
|
||||||
|
{
|
||||||
|
switch (Request)
|
||||||
|
{
|
||||||
|
case 0x1:
|
||||||
|
Relative();
|
||||||
|
break;
|
||||||
|
case 0x2:
|
||||||
|
Absolute();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct InodeOperations MouseOps = {
|
||||||
|
.Ioctl = __fs_Ioctl,
|
||||||
|
};
|
||||||
|
|
||||||
bool ToolboxSupported = false;
|
bool ToolboxSupported = false;
|
||||||
int DriverEntry()
|
int DriverEntry()
|
||||||
{
|
{
|
||||||
@ -711,7 +832,8 @@ int DriverEntry()
|
|||||||
* override its interrupt handler.
|
* override its interrupt handler.
|
||||||
*/
|
*/
|
||||||
OverrideInterruptHandler(12, InterruptHandler);
|
OverrideInterruptHandler(12, InterruptHandler);
|
||||||
MouseDevID = RegisterInputDevice(ddt_Mouse);
|
|
||||||
|
MouseDevID = RegisterDevice(INPUT_TYPE_MOUSE, &MouseOps);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,7 +843,8 @@ int DriverFinal()
|
|||||||
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
|
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
|
||||||
|
|
||||||
Relative();
|
Relative();
|
||||||
UnregisterInputDevice(MouseDevID, ddt_Mouse);
|
|
||||||
|
UnregisterDevice(MouseDevID);
|
||||||
|
|
||||||
if (ToolboxSupported)
|
if (ToolboxSupported)
|
||||||
{
|
{
|
||||||
@ -751,5 +874,5 @@ int DriverProbe()
|
|||||||
DriverInfo("vmware",
|
DriverInfo("vmware",
|
||||||
"VMware Tools Driver",
|
"VMware Tools Driver",
|
||||||
"EnderIce2",
|
"EnderIce2",
|
||||||
"0.1",
|
0, 0, 1,
|
||||||
"GPLv3");
|
"GPLv3");
|
||||||
|
@ -1,83 +1,22 @@
|
|||||||
# Config file
|
# Config files
|
||||||
include ../../../Makefile.conf
|
include ../../../Makefile.conf
|
||||||
|
include ../../config.mk
|
||||||
FILENAME = e1000.drv
|
|
||||||
|
|
||||||
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
|
||||||
CPP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
|
||||||
LD = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
|
||||||
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
|
||||||
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
|
||||||
|
|
||||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||||
INCLUDE_DIR = ../../include
|
|
||||||
|
|
||||||
LIBS := ../../out/dcrt0.o -L../../out -ldriver
|
FILENAME = e1000.drv
|
||||||
|
|
||||||
LDFLAGS := \
|
|
||||||
-fPIC -fPIE -pie \
|
|
||||||
-Wl,--no-dynamic-linker,-ztext,--no-warn-rwx-segment \
|
|
||||||
-nostdlib -nodefaultlibs -nolibc \
|
|
||||||
-zmax-page-size=0x1000 \
|
|
||||||
-Wl,-Map file.map -shared -fvisibility=hidden
|
|
||||||
|
|
||||||
WARNCFLAG = -Wall -Wextra
|
|
||||||
|
|
||||||
CFLAGS := -I$(INCLUDE_DIR) -fvisibility=hidden
|
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 \
|
|
||||||
-march=x86-64 -pipe -ffunction-sections \
|
|
||||||
-msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), i386)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
|
|
||||||
-march=i386 -pipe -msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), aarch64)
|
|
||||||
|
|
||||||
CFLAGS += -pipe -fno-builtin -fPIC
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(DEBUG), 1)
|
|
||||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
CFLAGS += -fverbose-asm
|
|
||||||
endif
|
|
||||||
ifneq ($(OSARCH), aarch64)
|
|
||||||
CFLAGS += -fstack-check
|
|
||||||
endif
|
|
||||||
LDFLAGS += -ggdb3 -O0
|
|
||||||
endif
|
|
||||||
|
|
||||||
build: $(FILENAME)
|
build: $(FILENAME)
|
||||||
mv $(FILENAME) ../../out/$(FILENAME)
|
mv $(FILENAME) ../../out/$(FILENAME)
|
||||||
|
|
||||||
$(FILENAME): $(OBJ)
|
$(FILENAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
$(CC) $(LDFLAGS) $(OBJ) $(LIBS) -o $@
|
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||||
|
|
||||||
%.o: %.c $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CC) $(CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.cpp $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CPP) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.S
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(AS) -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include <regs.h>
|
#include <regs.h>
|
||||||
#include <base.h>
|
#include <base.h>
|
||||||
#include <pci.h>
|
#include <pci.h>
|
||||||
#include <net.h>
|
#include <network.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
|
||||||
#include "e1000.hpp"
|
#include "e1000.hpp"
|
||||||
@ -205,7 +205,7 @@ public:
|
|||||||
mac.Address[i] = BaseMac8[i];
|
mac.Address[i] = BaseMac8[i];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log("No MAC address found.");
|
KernelLog("No MAC address found.");
|
||||||
return MediaAccessControl();
|
return MediaAccessControl();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -240,7 +240,11 @@ public:
|
|||||||
uint8_t *data = (uint8_t *)RX[RXCurrent]->Address;
|
uint8_t *data = (uint8_t *)RX[RXCurrent]->Address;
|
||||||
uint16_t dataSz = RX[RXCurrent]->Length;
|
uint16_t dataSz = RX[RXCurrent]->Length;
|
||||||
|
|
||||||
ReportNetworkPacket(ID, data, dataSz);
|
// ReportNetworkPacket(ID, data, dataSz);
|
||||||
|
/* FIXME: Implement */
|
||||||
|
KernelLog("FIXME: Received packet");
|
||||||
|
(void)data;
|
||||||
|
(void)dataSz;
|
||||||
|
|
||||||
RX[RXCurrent]->Status = 0;
|
RX[RXCurrent]->Status = 0;
|
||||||
uint16_t OldRXCurrent = RXCurrent;
|
uint16_t OldRXCurrent = RXCurrent;
|
||||||
@ -270,7 +274,7 @@ public:
|
|||||||
{
|
{
|
||||||
case 0x100E:
|
case 0x100E:
|
||||||
{
|
{
|
||||||
Log("Found Intel 82540EM Gigabit Ethernet Controller.");
|
KernelLog("Found Intel 82540EM Gigabit Ethernet Controller.");
|
||||||
|
|
||||||
/* Detect EEPROM */
|
/* Detect EEPROM */
|
||||||
WriteCMD(REG::EEPROM, 0x1);
|
WriteCMD(REG::EEPROM, 0x1);
|
||||||
@ -282,7 +286,7 @@ public:
|
|||||||
|
|
||||||
if (!GetMAC().Valid())
|
if (!GetMAC().Valid())
|
||||||
{
|
{
|
||||||
Log("Failed to get MAC");
|
KernelLog("Failed to get MAC");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +307,7 @@ public:
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
Log("Unimplemented E1000 device.");
|
KernelLog("Unimplemented E1000 device.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -343,7 +347,7 @@ public:
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
Log("Unimplemented E1000 device.");
|
KernelLog("Unimplemented E1000 device.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -351,7 +355,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
E1000Device *Drivers[4] = {nullptr};
|
E1000Device *Drivers[4] = {nullptr};
|
||||||
dev_t AudioID[4] = {0};
|
dev_t NetID[4] = {(dev_t)-1};
|
||||||
|
|
||||||
#define OIR(x) OIR_##x
|
#define OIR(x) OIR_##x
|
||||||
#define CREATE_OIR(x) \
|
#define CREATE_OIR(x) \
|
||||||
@ -362,20 +366,40 @@ CREATE_OIR(1);
|
|||||||
CREATE_OIR(2);
|
CREATE_OIR(2);
|
||||||
CREATE_OIR(3);
|
CREATE_OIR(3);
|
||||||
|
|
||||||
int drvOpen(dev_t, dev_t, int, mode_t) { return 0; }
|
int __fs_Open(struct Inode *, int, mode_t) { return 0; }
|
||||||
int drvClose(dev_t, dev_t) { return 0; }
|
int __fs_Close(struct Inode *) { return 0; }
|
||||||
size_t drvRead(dev_t, dev_t, uint8_t *, size_t, off_t) { return 0; }
|
ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; }
|
||||||
|
|
||||||
size_t drvWrite(dev_t, dev_t min, uint8_t *Buffer, size_t Size, off_t)
|
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t)
|
||||||
{
|
{
|
||||||
return Drivers[AudioID[min]]->write(Buffer, Size);
|
return Drivers[NetID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int drvIoctl(dev_t, dev_t min, unsigned long Request, void *Argp)
|
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
|
||||||
{
|
{
|
||||||
return Drivers[AudioID[min]]->ioctl((NetIoctl)Request, Argp);
|
return Drivers[NetID[Node->GetMinor()]]->ioctl((NetIoctl)Request, Argp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct InodeOperations NetOps = {
|
||||||
|
.Lookup = nullptr,
|
||||||
|
.Create = nullptr,
|
||||||
|
.Remove = nullptr,
|
||||||
|
.Rename = nullptr,
|
||||||
|
.Read = __fs_Read,
|
||||||
|
.Write = __fs_Write,
|
||||||
|
.Truncate = nullptr,
|
||||||
|
.Open = __fs_Open,
|
||||||
|
.Close = __fs_Close,
|
||||||
|
.Ioctl = __fs_Ioctl,
|
||||||
|
.ReadDir = nullptr,
|
||||||
|
.MkDir = nullptr,
|
||||||
|
.RmDir = nullptr,
|
||||||
|
.SymLink = nullptr,
|
||||||
|
.ReadLink = nullptr,
|
||||||
|
.Seek = nullptr,
|
||||||
|
.Stat = nullptr,
|
||||||
|
};
|
||||||
|
|
||||||
PCIArray *Devices;
|
PCIArray *Devices;
|
||||||
EXTERNC int cxx_Panic()
|
EXTERNC int cxx_Panic()
|
||||||
{
|
{
|
||||||
@ -402,10 +426,10 @@ EXTERNC int cxx_Probe()
|
|||||||
0x10EA, /* I217-LM */
|
0x10EA, /* I217-LM */
|
||||||
0x153A, /* 82577LM */
|
0x153A, /* 82577LM */
|
||||||
PCI_END};
|
PCI_END};
|
||||||
Devices = FindPCIDevices(VendorIDs, DeviceIDs);
|
Devices = GetPCIDevices(VendorIDs, DeviceIDs);
|
||||||
if (Devices == nullptr)
|
if (Devices == nullptr)
|
||||||
{
|
{
|
||||||
Log("No E1000 device found.");
|
KernelLog("No E1000 device found.");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -427,11 +451,8 @@ EXTERNC int cxx_Initialize()
|
|||||||
|
|
||||||
if (Drivers[Count]->IsInitialized())
|
if (Drivers[Count]->IsInitialized())
|
||||||
{
|
{
|
||||||
dev_t ret = RegisterNetDevice(ddt_Network,
|
dev_t ret = RegisterDevice(NETWORK_TYPE_ETHERNET, &NetOps);
|
||||||
drvOpen, drvClose,
|
NetID[Count] = ret;
|
||||||
drvRead, drvWrite,
|
|
||||||
drvIoctl);
|
|
||||||
AudioID[Count] = ret;
|
|
||||||
Drivers[Count]->ID = ret;
|
Drivers[Count]->ID = ret;
|
||||||
|
|
||||||
/* FIXME: bad code */
|
/* FIXME: bad code */
|
||||||
@ -460,7 +481,7 @@ EXTERNC int cxx_Initialize()
|
|||||||
|
|
||||||
if (Count == 0)
|
if (Count == 0)
|
||||||
{
|
{
|
||||||
Log("No valid E1000 device found.");
|
KernelLog("No valid E1000 device found.");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,5 +502,11 @@ EXTERNC int cxx_Finalize()
|
|||||||
ctx = (PCIArray *)ctx->Next;
|
ctx = (PCIArray *)ctx->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(NetID) / sizeof(dev_t); i++)
|
||||||
|
{
|
||||||
|
if (NetID[i] != (dev_t)-1)
|
||||||
|
UnregisterDevice(NetID[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -27,5 +27,5 @@ int DriverProbe() { return cxx_Probe(); }
|
|||||||
DriverInfo("e1000",
|
DriverInfo("e1000",
|
||||||
"Intel(R) PRO/1000 Network Driver",
|
"Intel(R) PRO/1000 Network Driver",
|
||||||
"EnderIce2",
|
"EnderIce2",
|
||||||
"0.1",
|
0, 0, 1,
|
||||||
"GPLv3");
|
"GPLv3");
|
||||||
|
@ -1,83 +1,22 @@
|
|||||||
# Config file
|
# Config files
|
||||||
include ../../../Makefile.conf
|
include ../../../Makefile.conf
|
||||||
|
include ../../config.mk
|
||||||
FILENAME = rtl8139.drv
|
|
||||||
|
|
||||||
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
|
||||||
CPP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
|
||||||
LD = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
|
||||||
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
|
||||||
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
|
||||||
|
|
||||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||||
INCLUDE_DIR = ../../include
|
|
||||||
|
|
||||||
LIBS := ../../out/dcrt0.o -L../../out -ldriver
|
FILENAME = rtl8139.drv
|
||||||
|
|
||||||
LDFLAGS := \
|
|
||||||
-fPIC -fPIE -pie \
|
|
||||||
-Wl,--no-dynamic-linker,-ztext,--no-warn-rwx-segment \
|
|
||||||
-nostdlib -nodefaultlibs -nolibc \
|
|
||||||
-zmax-page-size=0x1000 \
|
|
||||||
-Wl,-Map file.map -shared -fvisibility=hidden
|
|
||||||
|
|
||||||
WARNCFLAG = -Wall -Wextra
|
|
||||||
|
|
||||||
CFLAGS := -I$(INCLUDE_DIR) -fvisibility=hidden
|
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 \
|
|
||||||
-march=x86-64 -pipe -ffunction-sections \
|
|
||||||
-msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), i386)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
|
|
||||||
-march=i386 -pipe -msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), aarch64)
|
|
||||||
|
|
||||||
CFLAGS += -pipe -fno-builtin -fPIC
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(DEBUG), 1)
|
|
||||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
CFLAGS += -fverbose-asm
|
|
||||||
endif
|
|
||||||
ifneq ($(OSARCH), aarch64)
|
|
||||||
CFLAGS += -fstack-check
|
|
||||||
endif
|
|
||||||
LDFLAGS += -ggdb3 -O0
|
|
||||||
endif
|
|
||||||
|
|
||||||
build: $(FILENAME)
|
build: $(FILENAME)
|
||||||
mv $(FILENAME) ../../out/$(FILENAME)
|
mv $(FILENAME) ../../out/$(FILENAME)
|
||||||
|
|
||||||
$(FILENAME): $(OBJ)
|
$(FILENAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
$(CC) $(LDFLAGS) $(OBJ) $(LIBS) -o $@
|
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||||
|
|
||||||
%.o: %.c $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CC) $(CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.cpp $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CPP) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.S
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(AS) -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
||||||
|
@ -27,5 +27,5 @@ int DriverProbe() { return cxx_Probe(); }
|
|||||||
DriverInfo("rtl8139",
|
DriverInfo("rtl8139",
|
||||||
"Realtek RTL8139 Network Driver",
|
"Realtek RTL8139 Network Driver",
|
||||||
"EnderIce2",
|
"EnderIce2",
|
||||||
"0.1",
|
0, 0, 1,
|
||||||
"GPLv3");
|
"GPLv3");
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include <regs.h>
|
#include <regs.h>
|
||||||
#include <base.h>
|
#include <base.h>
|
||||||
#include <pci.h>
|
#include <pci.h>
|
||||||
#include <net.h>
|
#include <network.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
|
||||||
#include "rtl8139.hpp"
|
#include "rtl8139.hpp"
|
||||||
@ -99,7 +99,11 @@ public:
|
|||||||
uint16_t dataSz = *(data + 1);
|
uint16_t dataSz = *(data + 1);
|
||||||
data += 2;
|
data += 2;
|
||||||
|
|
||||||
ReportNetworkPacket(ID, data, dataSz);
|
// ReportNetworkPacket(ID, data, dataSz);
|
||||||
|
/* FIXME: Implement */
|
||||||
|
KernelLog("FIXME: Received packet");
|
||||||
|
(void)data;
|
||||||
|
(void)dataSz;
|
||||||
|
|
||||||
/* Update CAPR */
|
/* Update CAPR */
|
||||||
#define RX_READ_PTR_MASK (~0x3)
|
#define RX_READ_PTR_MASK (~0x3)
|
||||||
@ -169,7 +173,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
RTL8139Device *Drivers[4] = {nullptr};
|
RTL8139Device *Drivers[4] = {nullptr};
|
||||||
dev_t AudioID[4] = {0};
|
dev_t NetID[4] = {(dev_t)-1};
|
||||||
|
|
||||||
#define OIR(x) OIR_##x
|
#define OIR(x) OIR_##x
|
||||||
#define CREATE_OIR(x) \
|
#define CREATE_OIR(x) \
|
||||||
@ -180,20 +184,40 @@ CREATE_OIR(1);
|
|||||||
CREATE_OIR(2);
|
CREATE_OIR(2);
|
||||||
CREATE_OIR(3);
|
CREATE_OIR(3);
|
||||||
|
|
||||||
int drvOpen(dev_t, dev_t, int, mode_t) { return 0; }
|
int __fs_Open(struct Inode *, int, mode_t) { return 0; }
|
||||||
int drvClose(dev_t, dev_t) { return 0; }
|
int __fs_Close(struct Inode *) { return 0; }
|
||||||
size_t drvRead(dev_t, dev_t, uint8_t *, size_t, off_t) { return 0; }
|
ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; }
|
||||||
|
|
||||||
size_t drvWrite(dev_t, dev_t min, uint8_t *Buffer, size_t Size, off_t)
|
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t)
|
||||||
{
|
{
|
||||||
return Drivers[AudioID[min]]->write(Buffer, Size);
|
return Drivers[NetID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int drvIoctl(dev_t, dev_t min, unsigned long Request, void *Argp)
|
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
|
||||||
{
|
{
|
||||||
return Drivers[AudioID[min]]->ioctl((NetIoctl)Request, Argp);
|
return Drivers[NetID[Node->GetMinor()]]->ioctl((NetIoctl)Request, Argp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct InodeOperations NetOps = {
|
||||||
|
.Lookup = nullptr,
|
||||||
|
.Create = nullptr,
|
||||||
|
.Remove = nullptr,
|
||||||
|
.Rename = nullptr,
|
||||||
|
.Read = __fs_Read,
|
||||||
|
.Write = __fs_Write,
|
||||||
|
.Truncate = nullptr,
|
||||||
|
.Open = __fs_Open,
|
||||||
|
.Close = __fs_Close,
|
||||||
|
.Ioctl = __fs_Ioctl,
|
||||||
|
.ReadDir = nullptr,
|
||||||
|
.MkDir = nullptr,
|
||||||
|
.RmDir = nullptr,
|
||||||
|
.SymLink = nullptr,
|
||||||
|
.ReadLink = nullptr,
|
||||||
|
.Seek = nullptr,
|
||||||
|
.Stat = nullptr,
|
||||||
|
};
|
||||||
|
|
||||||
PCIArray *Devices;
|
PCIArray *Devices;
|
||||||
EXTERNC int cxx_Panic()
|
EXTERNC int cxx_Panic()
|
||||||
{
|
{
|
||||||
@ -216,10 +240,10 @@ EXTERNC int cxx_Probe()
|
|||||||
PCI_END};
|
PCI_END};
|
||||||
uint16_t DeviceIDs[] = {0x8139, /* RTL8139 */
|
uint16_t DeviceIDs[] = {0x8139, /* RTL8139 */
|
||||||
PCI_END};
|
PCI_END};
|
||||||
Devices = FindPCIDevices(VendorIDs, DeviceIDs);
|
Devices = GetPCIDevices(VendorIDs, DeviceIDs);
|
||||||
if (Devices == nullptr)
|
if (Devices == nullptr)
|
||||||
{
|
{
|
||||||
Log("No RTL8139 device found.");
|
KernelLog("No RTL8139 device found.");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -240,11 +264,8 @@ EXTERNC int cxx_Initialize()
|
|||||||
|
|
||||||
if (Drivers[Count]->IsInitialized())
|
if (Drivers[Count]->IsInitialized())
|
||||||
{
|
{
|
||||||
dev_t ret = RegisterNetDevice(ddt_Network,
|
dev_t ret = RegisterDevice(NETWORK_TYPE_ETHERNET, &NetOps);
|
||||||
drvOpen, drvClose,
|
NetID[Count] = ret;
|
||||||
drvRead, drvWrite,
|
|
||||||
drvIoctl);
|
|
||||||
AudioID[Count] = ret;
|
|
||||||
Drivers[Count]->ID = ret;
|
Drivers[Count]->ID = ret;
|
||||||
|
|
||||||
/* FIXME: bad code */
|
/* FIXME: bad code */
|
||||||
@ -273,7 +294,7 @@ EXTERNC int cxx_Initialize()
|
|||||||
|
|
||||||
if (Count == 0)
|
if (Count == 0)
|
||||||
{
|
{
|
||||||
Log("No valid RTL8139 device found.");
|
KernelLog("No valid RTL8139 device found.");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,5 +315,11 @@ EXTERNC int cxx_Finalize()
|
|||||||
ctx = (PCIArray *)ctx->Next;
|
ctx = (PCIArray *)ctx->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(NetID) / sizeof(dev_t); i++)
|
||||||
|
{
|
||||||
|
if (NetID[i] != (dev_t)-1)
|
||||||
|
UnregisterDevice(NetID[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,83 +1,22 @@
|
|||||||
# Config file
|
# Config files
|
||||||
include ../../../Makefile.conf
|
include ../../../Makefile.conf
|
||||||
|
include ../../config.mk
|
||||||
FILENAME = ahci.drv
|
|
||||||
|
|
||||||
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
|
||||||
CPP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
|
||||||
LD = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
|
||||||
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
|
||||||
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
|
||||||
|
|
||||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||||
INCLUDE_DIR = ../../include
|
|
||||||
|
|
||||||
LIBS := ../../out/dcrt0.o -L../../out -ldriver
|
FILENAME = ahci.drv
|
||||||
|
|
||||||
LDFLAGS := \
|
|
||||||
-fPIC -fPIE -pie \
|
|
||||||
-Wl,--no-dynamic-linker,-ztext,--no-warn-rwx-segment \
|
|
||||||
-nostdlib -nodefaultlibs -nolibc \
|
|
||||||
-zmax-page-size=0x1000 \
|
|
||||||
-Wl,-Map file.map -shared -fvisibility=hidden
|
|
||||||
|
|
||||||
WARNCFLAG = -Wall -Wextra
|
|
||||||
|
|
||||||
CFLAGS := -I$(INCLUDE_DIR) -fvisibility=hidden
|
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 \
|
|
||||||
-march=x86-64 -pipe -ffunction-sections \
|
|
||||||
-msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), i386)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
|
|
||||||
-march=i386 -pipe -msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), aarch64)
|
|
||||||
|
|
||||||
CFLAGS += -pipe -fno-builtin -fPIC
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(DEBUG), 1)
|
|
||||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
CFLAGS += -fverbose-asm
|
|
||||||
endif
|
|
||||||
ifneq ($(OSARCH), aarch64)
|
|
||||||
CFLAGS += -fstack-check
|
|
||||||
endif
|
|
||||||
LDFLAGS += -ggdb3 -O0
|
|
||||||
endif
|
|
||||||
|
|
||||||
build: $(FILENAME)
|
build: $(FILENAME)
|
||||||
mv $(FILENAME) ../../out/$(FILENAME)
|
mv $(FILENAME) ../../out/$(FILENAME)
|
||||||
|
|
||||||
$(FILENAME): $(OBJ)
|
$(FILENAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
$(CC) $(LDFLAGS) $(OBJ) $(LIBS) -o $@
|
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||||
|
|
||||||
%.o: %.c $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CC) $(CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.cpp $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CPP) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.S
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(AS) -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <block.h>
|
#include <device.h>
|
||||||
#include <regs.h>
|
#include <regs.h>
|
||||||
#include <base.h>
|
#include <base.h>
|
||||||
#include <pci.h>
|
#include <pci.h>
|
||||||
@ -634,9 +634,9 @@ public:
|
|||||||
|
|
||||||
Identify();
|
Identify();
|
||||||
|
|
||||||
Log("Port %d \"%x %x %x %x\" configured", PortNumber,
|
KernelLog("Port %d \"%x %x %x %x\" configured", PortNumber,
|
||||||
HBAPortPtr->Vendor[0], HBAPortPtr->Vendor[1],
|
HBAPortPtr->Vendor[0], HBAPortPtr->Vendor[1],
|
||||||
HBAPortPtr->Vendor[2], HBAPortPtr->Vendor[3]);
|
HBAPortPtr->Vendor[2], HBAPortPtr->Vendor[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadWrite(uint64_t Sector, uint32_t SectorCount, uint8_t *Buffer, bool Write)
|
bool ReadWrite(uint64_t Sector, uint32_t SectorCount, uint8_t *Buffer, bool Write)
|
||||||
@ -644,7 +644,7 @@ public:
|
|||||||
if (this->AHCIPortType == PortType::SATAPI &&
|
if (this->AHCIPortType == PortType::SATAPI &&
|
||||||
Write == true)
|
Write == true)
|
||||||
{
|
{
|
||||||
Log("SATAPI port does not support write.");
|
KernelLog("SATAPI port does not support write.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -702,7 +702,7 @@ public:
|
|||||||
|
|
||||||
if (Spin == 1000000)
|
if (Spin == 1000000)
|
||||||
{
|
{
|
||||||
Log("Port not responding.");
|
KernelLog("Port not responding.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -715,8 +715,8 @@ public:
|
|||||||
{
|
{
|
||||||
if (Spin > 100000000)
|
if (Spin > 100000000)
|
||||||
{
|
{
|
||||||
Log("Port %d not responding. (%d)",
|
KernelLog("Port %d not responding. (%d)",
|
||||||
this->PortNumber, TryCount);
|
this->PortNumber, TryCount);
|
||||||
|
|
||||||
Spin = 0;
|
Spin = 0;
|
||||||
TryCount++;
|
TryCount++;
|
||||||
@ -730,7 +730,7 @@ public:
|
|||||||
|
|
||||||
if (HBAPortPtr->InterruptStatus & HBA_PxIS_TFES)
|
if (HBAPortPtr->InterruptStatus & HBA_PxIS_TFES)
|
||||||
{
|
{
|
||||||
Log("Error reading/writing (%d).", Write);
|
KernelLog("Error reading/writing (%d).", Write);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -766,12 +766,12 @@ public:
|
|||||||
|
|
||||||
if (HBAPortPtr->InterruptStatus & HBA_PxIS_TFES)
|
if (HBAPortPtr->InterruptStatus & HBA_PxIS_TFES)
|
||||||
{
|
{
|
||||||
Log("Error reading IDENTIFY command.");
|
KernelLog("Error reading IDENTIFY command.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IdentifyData->Signature != 0xA5)
|
if (IdentifyData->Signature != 0xA5)
|
||||||
Log("Port %d has no validity signature.", PortNumber);
|
KernelLog("Port %d has no validity signature.", PortNumber);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint8_t *ptr = (uint8_t *)IdentifyData;
|
uint8_t *ptr = (uint8_t *)IdentifyData;
|
||||||
@ -780,11 +780,11 @@ public:
|
|||||||
sum += ptr[i];
|
sum += ptr[i];
|
||||||
if (sum != 0)
|
if (sum != 0)
|
||||||
{
|
{
|
||||||
Log("Port %d has invalid checksum.", PortNumber);
|
KernelLog("Port %d has invalid checksum.", PortNumber);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Log("Port %d has valid checksum.", PortNumber);
|
KernelLog("Port %d has valid checksum.", PortNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *Model = (char *)this->IdentifyData->ModelNumber;
|
char *Model = (char *)this->IdentifyData->ModelNumber;
|
||||||
@ -796,11 +796,11 @@ public:
|
|||||||
}
|
}
|
||||||
ModelSwap[40] = 0;
|
ModelSwap[40] = 0;
|
||||||
|
|
||||||
Log("Port %d \"%s\" identified", PortNumber,
|
KernelLog("Port %d \"%s\" identified", PortNumber,
|
||||||
ModelSwap);
|
ModelSwap);
|
||||||
Log("Port %d is %s (%d rotation rate)", PortNumber,
|
KernelLog("Port %d is %s (%d rotation rate)", PortNumber,
|
||||||
IdentifyData->NominalMediaRotationRate == 1 ? "SSD" : "HDD",
|
IdentifyData->NominalMediaRotationRate == 1 ? "SSD" : "HDD",
|
||||||
IdentifyData->NominalMediaRotationRate);
|
IdentifyData->NominalMediaRotationRate);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -839,26 +839,47 @@ PortType CheckPortType(HBAPort *Port)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t drvRead(dev_t, dev_t min,
|
int __fs_Open(struct Inode *, int, mode_t) { return 0; }
|
||||||
uint8_t *Buffer, size_t Size, off_t Offset)
|
int __fs_Close(struct Inode *) { return 0; }
|
||||||
|
|
||||||
|
ssize_t __fs_Read(struct Inode *Node, void *Buffer, size_t Size, off_t Offset)
|
||||||
{
|
{
|
||||||
bool ok = Ports[min]->ReadWrite(Offset / 512,
|
bool ok = Ports[Node->GetMinor()]->ReadWrite(Offset / 512,
|
||||||
uint32_t(Size / 512),
|
uint32_t(Size / 512),
|
||||||
Buffer,
|
(uint8_t *)Buffer,
|
||||||
false);
|
false);
|
||||||
return ok ? Size : 0;
|
return ok ? Size : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t drvWrite(dev_t, dev_t min,
|
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset)
|
||||||
uint8_t *Buffer, size_t Size, off_t Offset)
|
|
||||||
{
|
{
|
||||||
bool ok = Ports[min]->ReadWrite(Offset / 512,
|
bool ok = Ports[Node->GetMinor()]->ReadWrite(Offset / 512,
|
||||||
uint32_t(Size / 512),
|
uint32_t(Size / 512),
|
||||||
Buffer,
|
(uint8_t *)Buffer,
|
||||||
true);
|
true);
|
||||||
return ok ? Size : 0;
|
return ok ? Size : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct InodeOperations BlockOps = {
|
||||||
|
.Lookup = nullptr,
|
||||||
|
.Create = nullptr,
|
||||||
|
.Remove = nullptr,
|
||||||
|
.Rename = nullptr,
|
||||||
|
.Read = __fs_Read,
|
||||||
|
.Write = __fs_Write,
|
||||||
|
.Truncate = nullptr,
|
||||||
|
.Open = __fs_Open,
|
||||||
|
.Close = __fs_Close,
|
||||||
|
.Ioctl = nullptr,
|
||||||
|
.ReadDir = nullptr,
|
||||||
|
.MkDir = nullptr,
|
||||||
|
.RmDir = nullptr,
|
||||||
|
.SymLink = nullptr,
|
||||||
|
.ReadLink = nullptr,
|
||||||
|
.Seek = nullptr,
|
||||||
|
.Stat = nullptr,
|
||||||
|
};
|
||||||
|
|
||||||
void OnInterruptReceived(TrapFrame *)
|
void OnInterruptReceived(TrapFrame *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -880,10 +901,10 @@ EXTERNC int cxx_Probe()
|
|||||||
0x2829, /* ICH8 */
|
0x2829, /* ICH8 */
|
||||||
0x07E0, /* SATA AHCI (VMware) */
|
0x07E0, /* SATA AHCI (VMware) */
|
||||||
PCI_END};
|
PCI_END};
|
||||||
Devices = FindPCIDevices(VendorIDs, DeviceIDs);
|
Devices = GetPCIDevices(VendorIDs, DeviceIDs);
|
||||||
if (Devices == nullptr)
|
if (Devices == nullptr)
|
||||||
{
|
{
|
||||||
Log("No AHCI device found.");
|
KernelLog("No AHCI device found.");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -905,31 +926,28 @@ EXTERNC int cxx_Initialize()
|
|||||||
HBAMemory *HBA = (HBAMemory *)(uintptr_t)GetBAR(5, ctx->Device);
|
HBAMemory *HBA = (HBAMemory *)(uintptr_t)GetBAR(5, ctx->Device);
|
||||||
|
|
||||||
uint32_t PortsImplemented = HBA->PortsImplemented;
|
uint32_t PortsImplemented = HBA->PortsImplemented;
|
||||||
Log("AHCI ports implemented: %x", PortsImplemented);
|
KernelLog("AHCI ports implemented: %x", PortsImplemented);
|
||||||
for (int i = 0; i < 32; i++)
|
for (int i = 0; i < 32; i++)
|
||||||
{
|
{
|
||||||
if (PortCount > 64)
|
if (PortCount > 64)
|
||||||
{
|
{
|
||||||
Log("There are more than 64 AHCI ports implemented");
|
KernelLog("There are more than 64 AHCI ports implemented");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PortsImplemented & (1 << i))
|
if (PortsImplemented & (1 << i))
|
||||||
{
|
{
|
||||||
Log("Port %d implemented", i);
|
KernelLog("Port %d implemented", i);
|
||||||
PortType portType = CheckPortType(&HBA->Ports[i]);
|
PortType portType = CheckPortType(&HBA->Ports[i]);
|
||||||
if (portType == PortType::SATA || portType == PortType::SATAPI)
|
if (portType == PortType::SATA || portType == PortType::SATAPI)
|
||||||
{
|
{
|
||||||
KPrint("%s drive found at port %d", PortTypeName[portType], i);
|
KernelPrint("%s drive found at port %d", PortTypeName[portType], i);
|
||||||
Ports[PortCount] = new Port(portType, &HBA->Ports[i], PortCount);
|
Ports[PortCount] = new Port(portType, &HBA->Ports[i], PortCount);
|
||||||
dev_t ret = RegisterBlockDevice(ddt_SATA,
|
dev_t ret = RegisterDevice(BLOCK_TYPE_HDD, &BlockOps);
|
||||||
nullptr, nullptr,
|
|
||||||
drvRead, drvWrite,
|
|
||||||
nullptr);
|
|
||||||
if (ret != (dev_t)PortCount)
|
if (ret != (dev_t)PortCount)
|
||||||
{
|
{
|
||||||
KPrint("Failed to register block device %d", ret);
|
KernelPrint("Failed to register block device %d", ret);
|
||||||
return -EBADSLT;
|
return -EBADF;
|
||||||
}
|
}
|
||||||
|
|
||||||
PortCount++;
|
PortCount++;
|
||||||
@ -939,8 +957,8 @@ EXTERNC int cxx_Initialize()
|
|||||||
{
|
{
|
||||||
if (portType != PortType::None)
|
if (portType != PortType::None)
|
||||||
{
|
{
|
||||||
KPrint("Unsupported drive type %s found at port %d",
|
KernelPrint("Unsupported drive type %s found at port %d",
|
||||||
PortTypeName[portType], i);
|
PortTypeName[portType], i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -949,7 +967,7 @@ EXTERNC int cxx_Initialize()
|
|||||||
ctx = (PCIArray *)ctx->Next;
|
ctx = (PCIArray *)ctx->Next;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log("Initializing AHCI ports");
|
KernelLog("Initializing AHCI ports");
|
||||||
for (int i = 0; i < PortCount; i++)
|
for (int i = 0; i < PortCount; i++)
|
||||||
Ports[i]->Configure();
|
Ports[i]->Configure();
|
||||||
|
|
||||||
@ -968,7 +986,7 @@ EXTERNC int cxx_Finalize()
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
UnregisterBlockDevice(PortCount, ddt_SATA);
|
UnregisterDevice(PortCount);
|
||||||
PortCount--;
|
PortCount--;
|
||||||
} while (PortCount >= 0);
|
} while (PortCount >= 0);
|
||||||
|
|
||||||
|
@ -27,5 +27,5 @@ int DriverProbe() { return cxx_Probe(); }
|
|||||||
DriverInfo("ahci",
|
DriverInfo("ahci",
|
||||||
"Advanced Host Controller Interface Driver",
|
"Advanced Host Controller Interface Driver",
|
||||||
"EnderIce2",
|
"EnderIce2",
|
||||||
"0.1",
|
0, 0, 1,
|
||||||
"GPLv3");
|
"GPLv3");
|
||||||
|
@ -1,83 +1,22 @@
|
|||||||
# Config file
|
# Config files
|
||||||
include ../../../Makefile.conf
|
include ../../../Makefile.conf
|
||||||
|
include ../../config.mk
|
||||||
FILENAME = ata.drv
|
|
||||||
|
|
||||||
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
|
||||||
CPP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
|
||||||
LD = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
|
||||||
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
|
||||||
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
|
||||||
|
|
||||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||||
INCLUDE_DIR = ../../include
|
|
||||||
|
|
||||||
LIBS := ../../out/dcrt0.o -L../../out -ldriver
|
FILENAME = ata.drv
|
||||||
|
|
||||||
LDFLAGS := \
|
|
||||||
-fPIC -fPIE -pie \
|
|
||||||
-Wl,--no-dynamic-linker,-ztext,--no-warn-rwx-segment \
|
|
||||||
-nostdlib -nodefaultlibs -nolibc \
|
|
||||||
-zmax-page-size=0x1000 \
|
|
||||||
-Wl,-Map file.map -shared -fvisibility=hidden
|
|
||||||
|
|
||||||
WARNCFLAG = -Wall -Wextra
|
|
||||||
|
|
||||||
CFLAGS := -I$(INCLUDE_DIR) -fvisibility=hidden
|
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 \
|
|
||||||
-march=x86-64 -pipe -ffunction-sections \
|
|
||||||
-msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), i386)
|
|
||||||
|
|
||||||
CFLAGS += -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
|
||||||
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
|
|
||||||
-march=i386 -pipe -msoft-float -fno-builtin
|
|
||||||
|
|
||||||
else ifeq ($(OSARCH), aarch64)
|
|
||||||
|
|
||||||
CFLAGS += -pipe -fno-builtin -fPIC
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(DEBUG), 1)
|
|
||||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
CFLAGS += -fverbose-asm
|
|
||||||
endif
|
|
||||||
ifneq ($(OSARCH), aarch64)
|
|
||||||
CFLAGS += -fstack-check
|
|
||||||
endif
|
|
||||||
LDFLAGS += -ggdb3 -O0
|
|
||||||
endif
|
|
||||||
|
|
||||||
build: $(FILENAME)
|
build: $(FILENAME)
|
||||||
mv $(FILENAME) ../../out/$(FILENAME)
|
mv $(FILENAME) ../../out/$(FILENAME)
|
||||||
|
|
||||||
$(FILENAME): $(OBJ)
|
$(FILENAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
$(CC) $(LDFLAGS) $(OBJ) $(LIBS) -o $@
|
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||||
|
|
||||||
%.o: %.c $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CC) $(CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.cpp $(HEADERS)
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(CPP) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
|
|
||||||
|
|
||||||
%.o: %.S
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(AS) -o $@ $<
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
||||||
|
@ -72,5 +72,5 @@ int DriverProbe()
|
|||||||
DriverInfo("ata",
|
DriverInfo("ata",
|
||||||
"Advanced Technology Attachment Driver",
|
"Advanced Technology Attachment Driver",
|
||||||
"EnderIce2",
|
"EnderIce2",
|
||||||
"0.1",
|
0, 0, 1,
|
||||||
"GPLv3");
|
"GPLv3");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user