diff --git a/.vscode/c_boilerplates.code-snippets b/.vscode/c_boilerplates.code-snippets index a3c12a1..b191282 100644 --- a/.vscode/c_boilerplates.code-snippets +++ b/.vscode/c_boilerplates.code-snippets @@ -4,14 +4,14 @@ "head", ], "body": [ - "#ifndef __FENNIX_API_${2:header}_H__", - "#define __FENNIX_API_${2:header}_H__", + "#ifndef __FENNIX_DRIVER_${2:header}_H__", + "#define __FENNIX_DRIVER_${2:header}_H__", "", "#include ", "", "$0", "", - "#endif // !__FENNIX_API_${2:header}_H__", + "#endif // !__FENNIX_DRIVER_${2:header}_H__", "" ], "description": "Create header." diff --git a/Makefile b/Makefile index 324f07d..f7bd98d 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ build: - cp -f ../Kernel/driver.h include/driver.h + cp -rf ../Kernel/include/interface/* include/ mkdir -p out make -C library build make -C audio build @@ -7,6 +7,7 @@ build: make -C misc build make -C network build make -C storage build + make -C filesystem build prepare: $(info Nothing to prepare) @@ -19,3 +20,4 @@ clean: make -C misc clean make -C network clean make -C storage clean + make -C filesystem clean diff --git a/audio/ac97/Makefile b/audio/ac97/Makefile index a76f72b..91c439c 100644 --- a/audio/ac97/Makefile +++ b/audio/ac97/Makefile @@ -1,83 +1,22 @@ -# Config file +# Config files include ../../../Makefile.conf - -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 +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) $(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) -INCLUDE_DIR = ../../include -LIBS := ../../out/dcrt0.o -L../../out -ldriver - -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 +FILENAME = ac97.drv build: $(FILENAME) mv $(FILENAME) ../../out/$(FILENAME) $(FILENAME): $(OBJ) $(info Linking $@) - $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -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 $@ $< + $(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@ clean: rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/audio/ac97/ac97.cpp b/audio/ac97/ac97.cpp index d12163b..9664eb7 100644 --- a/audio/ac97/ac97.cpp +++ b/audio/ac97/ac97.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #define DescriptorListLength 0x20 @@ -370,13 +371,13 @@ public: { if (Buffer == nullptr) { - Log("Invalid buffer."); + KernelLog("Invalid buffer."); return -EINVAL; } if ((Size == 0) || (Size % (SampleSize * Channels))) { - Log("Invalid buffer length."); + KernelLog("Invalid buffer length."); return -EINVAL; } @@ -431,7 +432,7 @@ public: if (Wrote == 0) { - Log("Wrote 0 bytes."); + KernelLog("Wrote 0 bytes."); break; } @@ -563,7 +564,7 @@ public: uint16_t CurrentBDL = inb(BusMasterAddress + PCMOUT_BufferDescriptorEntry); uint16_t LastBDL = (CurrentBDL + 2) & (DescriptorListLength - 1); 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) { @@ -577,7 +578,7 @@ public: } else if (Status & TC_FifoERRORInterruptEnable) { - Log("FIFO error"); + KernelLog("FIFO error"); outw(MixerAddress + PCMOUT_Status, TC_FifoERRORInterruptEnable); } else @@ -689,7 +690,7 @@ public: }; AC97Device *Drivers[4] = {nullptr}; -dev_t AudioID[4] = {0}; +dev_t AudioID[4] = {(dev_t)-1}; #define OIR(x) OIR_##x #define CREATE_OIR(x) \ @@ -700,20 +701,40 @@ CREATE_OIR(1); CREATE_OIR(2); CREATE_OIR(3); -int drvOpen(dev_t, dev_t, int, mode_t) { return 0; } -int drvClose(dev_t, dev_t) { return 0; } -size_t drvRead(dev_t, dev_t, uint8_t *, size_t, off_t) { return 0; } +int __fs_Open(struct Inode *, int, mode_t) { return 0; } +int __fs_Close(struct Inode *) { 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; EXTERNC int cxx_Panic() { @@ -734,10 +755,10 @@ EXTERNC int cxx_Probe() { uint16_t VendorIDs[] = {0x8086, PCI_END}; uint16_t DeviceIDs[] = {0x2415, PCI_END}; - Devices = FindPCIDevices(VendorIDs, DeviceIDs); + Devices = GetPCIDevices(VendorIDs, DeviceIDs); if (Devices == nullptr) { - Log("No AC'97 device found."); + KernelLog("No AC'97 device found."); return -ENODEV; } @@ -754,10 +775,10 @@ EXTERNC int cxx_Probe() uint8_t Type = PCIBAR0 & 1; if (Type != 1) { - Log("Device %x:%x.%d BAR0 is not I/O.", - PCIBaseAddress->Header.VendorID, - PCIBaseAddress->Header.DeviceID, - PCIBaseAddress->Header.ProgIF); + KernelLog("Device %x:%x.%d BAR0 is not I/O.", + PCIBaseAddress->Header.VendorID, + PCIBaseAddress->Header.DeviceID, + PCIBaseAddress->Header.ProgIF); continue; } @@ -767,7 +788,7 @@ EXTERNC int cxx_Probe() if (!Found) { - Log("No valid AC'97 device found."); + KernelLog("No valid AC'97 device found."); return -EINVAL; } return 0; @@ -787,10 +808,10 @@ EXTERNC int cxx_Initialize() uint8_t Type = PCIBAR0 & 1; if (Type != 1) { - Log("Device %x:%x.%d BAR0 is not I/O.", - PCIBaseAddress->Header.VendorID, - PCIBaseAddress->Header.DeviceID, - PCIBaseAddress->Header.ProgIF); + KernelLog("Device %x:%x.%d BAR0 is not I/O.", + PCIBaseAddress->Header.VendorID, + PCIBaseAddress->Header.DeviceID, + PCIBaseAddress->Header.ProgIF); continue; } @@ -815,10 +836,7 @@ EXTERNC int cxx_Initialize() default: break; } - dev_t ret = RegisterAudioDevice(ddt_Audio, - drvOpen, drvClose, - drvRead, drvWrite, - drvIoctl); + dev_t ret = RegisterDevice(AUDIO_TYPE_PCM, &AudioOps); AudioID[Count] = ret; Count++; ctx = (PCIArray *)ctx->Next; @@ -841,10 +859,10 @@ EXTERNC int cxx_Finalize() uint8_t Type = PCIBAR0 & 1; if (Type != 1) { - Log("Device %x:%x.%d BAR0 is not I/O.", - PCIBaseAddress->Header.VendorID, - PCIBaseAddress->Header.DeviceID, - PCIBaseAddress->Header.ProgIF); + KernelLog("Device %x:%x.%d BAR0 is not I/O.", + PCIBaseAddress->Header.VendorID, + PCIBaseAddress->Header.DeviceID, + PCIBaseAddress->Header.ProgIF); continue; } @@ -853,5 +871,11 @@ EXTERNC int cxx_Finalize() 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; } diff --git a/audio/ac97/main.c b/audio/ac97/main.c index bfb84d5..ad39fb7 100644 --- a/audio/ac97/main.c +++ b/audio/ac97/main.c @@ -27,5 +27,5 @@ int DriverProbe() { return cxx_Probe(); } DriverInfo("ac97", "Audio Codec '97 Driver", "EnderIce2", - "0.1", + 0, 0, 1, "GPLv3"); diff --git a/audio/hda/Makefile b/audio/hda/Makefile index ade5826..90653fb 100644 --- a/audio/hda/Makefile +++ b/audio/hda/Makefile @@ -1,83 +1,22 @@ -# Config file +# Config files include ../../../Makefile.conf - -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 +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) $(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) -INCLUDE_DIR = ../../include -LIBS := ../../out/dcrt0.o -L../../out -ldriver - -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 +FILENAME = hda.drv build: $(FILENAME) mv $(FILENAME) ../../out/$(FILENAME) $(FILENAME): $(OBJ) $(info Linking $@) - $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -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 $@ $< + $(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@ clean: rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/audio/hda/hda.cpp b/audio/hda/hda.cpp index 40303de..69a6cb6 100644 --- a/audio/hda/hda.cpp +++ b/audio/hda/hda.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "hda.hpp" @@ -62,7 +63,7 @@ public: RIRB((uint64_t *)AllocateMemory(1)) { CTL = (ControllerRegisters *)(uintptr_t)Header->BAR0; - Log("Unimplemented HDA driver"); + KernelLog("Unimplemented HDA driver"); return; Initialized = true; } @@ -75,7 +76,7 @@ public: }; HDADevice *Drivers[4] = {nullptr}; -dev_t AudioID[4] = {0}; +dev_t AudioID[4] = {(dev_t)-1}; #define OIR(x) OIR_##x #define CREATE_OIR(x) \ @@ -86,20 +87,40 @@ CREATE_OIR(1); CREATE_OIR(2); CREATE_OIR(3); -int drvOpen(dev_t, dev_t, int, mode_t) { return 0; } -int drvClose(dev_t, dev_t) { return 0; } -size_t drvRead(dev_t, dev_t, uint8_t *, size_t, off_t) { return 0; } +int __fs_Open(struct Inode *, int, mode_t) { return 0; } +int __fs_Close(struct Inode *) { 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; EXTERNC int cxx_Panic() { @@ -125,10 +146,10 @@ EXTERNC int cxx_Probe() 0x2668 /* ICH6 */, 0x293E /* ICH9 */, PCI_END}; - Devices = FindPCIDevices(VendorIDs, DeviceIDs); + Devices = GetPCIDevices(VendorIDs, DeviceIDs); if (Devices == nullptr) { - Log("No HDA device found."); + KernelLog("No HDA device found."); return -ENODEV; } @@ -145,10 +166,10 @@ EXTERNC int cxx_Probe() uint8_t Type = PCIBAR0 & 1; if (Type == 1) { - Log("Device %x:%x.%d BAR0 is I/O.", - PCIBaseAddress->Header.VendorID, - PCIBaseAddress->Header.DeviceID, - PCIBaseAddress->Header.ProgIF); + KernelLog("Device %x:%x.%d BAR0 is I/O.", + PCIBaseAddress->Header.VendorID, + PCIBaseAddress->Header.DeviceID, + PCIBaseAddress->Header.ProgIF); continue; } @@ -158,7 +179,7 @@ EXTERNC int cxx_Probe() if (!Found) { - Log("No valid HDA device found."); + KernelLog("No valid HDA device found."); return -EINVAL; } return 0; @@ -178,10 +199,10 @@ EXTERNC int cxx_Initialize() uint8_t Type = PCIBAR0 & 1; if (Type == 1) { - Log("Device %x:%x.%d BAR0 is I/O.", - PCIBaseAddress->Header.VendorID, - PCIBaseAddress->Header.DeviceID, - PCIBaseAddress->Header.ProgIF); + KernelLog("Device %x:%x.%d BAR0 is I/O.", + PCIBaseAddress->Header.VendorID, + PCIBaseAddress->Header.DeviceID, + PCIBaseAddress->Header.ProgIF); continue; } @@ -191,10 +212,7 @@ EXTERNC int cxx_Initialize() if (Drivers[Count]->IsInitialized()) { - dev_t ret = RegisterAudioDevice(ddt_Audio, - drvOpen, drvClose, - drvRead, drvWrite, - drvIoctl); + dev_t ret = RegisterDevice(AUDIO_TYPE_PCM, &AudioOps); AudioID[Count] = ret; Count++; } @@ -203,7 +221,7 @@ EXTERNC int cxx_Initialize() if (Count == 0) { - Log("No valid HDA device found."); + KernelLog("No valid HDA device found."); return -EINVAL; } @@ -224,10 +242,10 @@ EXTERNC int cxx_Finalize() uint8_t Type = PCIBAR0 & 1; if (Type == 1) { - Log("Device %x:%x.%d BAR0 is I/O.", - PCIBaseAddress->Header.VendorID, - PCIBaseAddress->Header.DeviceID, - PCIBaseAddress->Header.ProgIF); + KernelLog("Device %x:%x.%d BAR0 is I/O.", + PCIBaseAddress->Header.VendorID, + PCIBaseAddress->Header.DeviceID, + PCIBaseAddress->Header.ProgIF); continue; } @@ -235,5 +253,11 @@ EXTERNC int cxx_Finalize() 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; } diff --git a/audio/hda/main.c b/audio/hda/main.c index 771e0f8..9da8f76 100644 --- a/audio/hda/main.c +++ b/audio/hda/main.c @@ -27,5 +27,5 @@ int DriverProbe() { return cxx_Probe(); } DriverInfo("hda", "Intel High Definition Audio Driver", "EnderIce2", - "0.1", + 0, 0, 1, "GPLv3"); diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..862437f --- /dev/null +++ b/config.mk @@ -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 $@ $< diff --git a/driver.template b/driver.template index 91b4354..8d735f3 100644 --- a/driver.template +++ b/driver.template @@ -46,5 +46,5 @@ int DriverProbe() DriverInfo("name", "description", "author", - "version", + 0, 0, 0, "license"); diff --git a/filesystem/Makefile b/filesystem/Makefile new file mode 100644 index 0000000..67b0766 --- /dev/null +++ b/filesystem/Makefile @@ -0,0 +1,5 @@ +build: + make -C fat build + +clean: + make -C fat clean diff --git a/filesystem/fat/Makefile b/filesystem/fat/Makefile new file mode 100644 index 0000000..80a9fb9 --- /dev/null +++ b/filesystem/fat/Makefile @@ -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) diff --git a/filesystem/fat/fat.h b/filesystem/fat/fat.h new file mode 100644 index 0000000..47a61a5 --- /dev/null +++ b/filesystem/fat/fat.h @@ -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 . +*/ + +#ifndef __FENNIX_DRIVER_FAT_H__ +#define __FENNIX_DRIVER_FAT_H__ + +#include + +/* 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__ diff --git a/include/vm.h b/filesystem/fat/main.c similarity index 71% rename from include/vm.h rename to filesystem/fat/main.c index a90ad18..6a1f407 100644 --- a/include/vm.h +++ b/filesystem/fat/main.c @@ -15,11 +15,31 @@ along with Fennix Drivers. If not, see . */ -#ifndef __FENNIX_API_VM_H__ -#define __FENNIX_API_VM_H__ +#include -#include +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"); diff --git a/include/aip.h b/include/aip.h index 0a070b5..9eebc58 100644 --- a/include/aip.h +++ b/include/aip.h @@ -19,8 +19,6 @@ #define __FENNIX_API_AIP_H__ #include -#include -#include #define PIC1_CMD 0x20 #define PIC1_DATA (PIC1_CMD + 1) @@ -117,7 +115,145 @@ uint8_t PS2ReadAfterACK(); void PS2ClearOutputBuffer(); int PS2ACKTimeout(); -#define WaitOutput PS2Wait(true) -#define WaitInput PS2Wait(false) +#define WaitOutput PS2Wait(DriverID, true) +#define WaitInput PS2Wait(DriverID, false) + + +#define PS2_KBD_CMD_SET_LEDS 0xED +#define PS2_KBD_CMD_ECHO 0xEE +#define PS2_KBD_CMD_SCAN_CODE_SET 0xF0 +#define PS2_KBD_CMD_IDENTIFY 0xF2 +#define PS2_KBD_CMD_TYPEMATIC 0xF3 +#define PS2_KBD_CMD_ENABLE_SCANNING 0xF4 +#define PS2_KBD_CMD_DISABLE_SCANNING 0xF5 +#define PS2_KBD_CMD_DEFAULTS 0xF6 +#define PS2_KBD_CMD_ALL_TYPEMATIC 0xF7 +#define PS2_KBD_CMD_ALL_MAKE_RELEASE 0xF8 +#define PS2_KBD_CMD_ALL_MAKE 0xF9 +#define PS2_KBD_CMD_ALL_TYPEMATIC_MAKE_RELEASE 0xFA +#define PS2_KBD_CMD_SPECIFIC_TYPEMATIC 0xFB +#define PS2_KBD_CMD_SPECIFIC_MAKE_RELEASE 0xFC +#define PS2_KBD_CMD_SPECIFIC_MAKE 0xFD +#define PS2_KBD_CMD_RESEND 0xFE +#define PS2_KBD_CMD_RESET 0xFF + +#define PS2_KBD_RESP_ACK 0xFA +#define PS2_KBD_RESP_ECHO 0xEE +#define PS2_KBD_RESP_RESEND 0xFE +#define PS2_KBD_RESP_TEST_PASSED 0xAA +#define PS2_KBD_RESP_TEST_FAILED 0xFC +#define PS2_KBD_RESP_TEST_FAILED_2 0xFD + +typedef enum +{ + PS2_KBD_LED_SCROLL_LOCK = 1, + PS2_KBD_LED_NUM_LOCK = 2, + PS2_KBD_LED_CAPS_LOCK = 4 +} PS2_KBD_LEDS; + +typedef enum +{ + PS2_KBD_SCAN_CODE_GET_CURRENT = 0, + PS2_KBD_SCAN_CODE_SET_1 = 1, + PS2_KBD_SCAN_CODE_SET_2 = 2, + PS2_KBD_SCAN_CODE_SET_3 = 3, + + PS2_KBD_SC_SET_1 = 0x43, + PS2_KBD_SC_SET_2 = 0x41, + PS2_KBD_SC_SET_3 = 0x3F +} PS2_KBD_SCAN_CODE_SET; + +typedef union +{ + struct + { + /** + * 00000b - 30Hz + * 11111b - 2Hz + */ + uint8_t RepeatRate : 5; + + /** + * 00b - 250ms + * 01b - 500ms + * 10b - 750ms + * 11b - 1000ms + */ + uint8_t Delay : 2; + + /** + * Must be zero + */ + uint8_t Zero : 1; + }; + uint8_t Raw; +} PS2_KBD_TYPEMATIC; + + +#define PS2_MOUSE_CMD_SET_SCALING_1_1 0xE6 +#define PS2_MOUSE_CMD_SET_SCALING_2_1 0xE7 +#define PS2_MOUSE_CMD_SET_RESOLUTION 0xE8 +#define PS2_MOUSE_CMD_GET_STATUS 0xE9 +#define PS2_MOUSE_CMD_SET_STREAM_MODE 0xEA +#define PS2_MOUSE_CMD_READ_DATA 0xEB +#define PS2_MOUSE_CMD_RESET_WRAP_MODE 0xEC +#define PS2_MOUSE_CMD_SET_WRAP_MODE 0xEE +#define PS2_MOUSE_CMD_SET_REMOTE_MODE 0xF0 +#define PS2_MOUSE_CMD_READ_ID 0xF2 +/** Values: 10, 20, 40, 60, 80, 100, 200 */ +#define PS2_MOUSE_CMD_SET_SAMPLE_RATE 0xF3 +#define PS2_MOUSE_CMD_ENABLE_DATA_REPORTING 0xF4 +#define PS2_MOUSE_CMD_DISABLE_DATA_REPORTING 0xF5 +#define PS2_MOUSE_CMD_SET_DEFAULTS 0xF6 +#define PS2_MOUSE_CMD_RESEND 0xFE +#define PS2_MOUSE_CMD_RESET 0xFF + +#define PS2_MOUSE_RESP_ACK 0xFA +#define PS2_MOUSE_RESP_RESEND 0xFE +#define PS2_MOUSE_RESP_TEST_PASSED 0xAA +#define PS2_MOUSE_RESP_TEST_FAILED 0xFC + +typedef enum +{ + PS2_MOUSE_RES_1 = 0, + PS2_MOUSE_RES_2 = 1, + PS2_MOUSE_RES_4 = 2, + PS2_MOUSE_RES_8 = 3 +} PS2_MOUSE_RESOLUTION; + +typedef struct +{ + union + { + struct + { + uint8_t LeftButton : 1; + uint8_t RightButton : 1; + uint8_t MiddleButton : 1; + uint8_t Always1 : 1; + uint8_t XSign : 1; + uint8_t YSign : 1; + uint8_t XOverflow : 1; + uint8_t YOverflow : 1; + } __attribute__((packed)); + uint8_t Raw; + } Base; + + uint8_t XMovement; + uint8_t YMovement; + + union + { + struct + { + uint8_t Z : 4; + uint8_t Button4 : 1; + uint8_t Button5 : 1; + uint8_t Always0 : 1; + uint8_t Always0_2 : 1; + } __attribute__((packed)); + uint8_t Raw; + } ZMovement; +} PS2_MOUSE_PACKET; #endif // !__FENNIX_API_AIP_H__ diff --git a/include/audio.h b/include/audio.h index 73183b0..2c87a13 100644 --- a/include/audio.h +++ b/include/audio.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 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, + 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 Drivers. If not, see . + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_API_AUDIO_H__ #define __FENNIX_API_AUDIO_H__ #include -#include -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 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 +#if __has_include() +#include +#else +#include +#endif #endif // !__FENNIX_API_AUDIO_H__ diff --git a/include/base.h b/include/base.h index 6ae5b4c..2fc7442 100644 --- a/include/base.h +++ b/include/base.h @@ -77,20 +77,20 @@ extern "C" void UnmapPages(void *VirtualAddress, size_t Pages); /** - * @brief Print to the screen + * @brief Print to the kernel terminal * @param Format The format string * @param ... The arguments to the format string * * @note The newline character is automatically appended */ - void KPrint(const char *Format, ...); + void KernelPrint(const char *Format, ...); /** * @brief Print to the kernel logger * @param Format 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 @@ -241,17 +241,20 @@ extern "C" /** @copydoc LeaveCriticalSection */ #define LCS LeaveCriticalSection(__ECS) -#define DriverInfo(Name, Description, Author, Version, License) \ - void __IdentifyDriver( \ - dev_t ID, \ - int (*GetDriverInfo)(dev_t, const char *, const char *, \ - const char *, const char *, const char *)) \ - { \ - GetDriverInfo(ID, Name, Description, Author, Version, License); \ - } +#define DriverInfo(_Name, _Description, _Author, _MajorVersion, \ + _MinorVersion, _PathVersion, _License) \ + __attribute__((section(".driver.info"))) struct __DriverInfo \ + __di = {.Name = _Name, \ + .Description = _Description, \ + .Author = _Author, \ + .Version = {.APIVersion = 0, \ + .Major = _MajorVersion, \ + .Minor = _MinorVersion, \ + .Patch = _PathVersion}, \ + .License = _License} #ifdef DEBUG -#define DebugLog(m, ...) Log(m, ##__VA_ARGS__) +#define DebugLog(m, ...) KernelLog(m, ##__VA_ARGS__) #else #define DebugLog(m, ...) #endif // DEBUG diff --git a/include/block.h b/include/block.h deleted file mode 100644 index e87fa2d..0000000 --- a/include/block.h +++ /dev/null @@ -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 . -*/ - -#ifndef __FENNIX_API_BLOCK_H__ -#define __FENNIX_API_BLOCK_H__ - -#include -#include - -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__ diff --git a/include/device.h b/include/device.h new file mode 100644 index 0000000..108aa82 --- /dev/null +++ b/include/device.h @@ -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 . +*/ + +#ifndef __FENNIX_API_DEVICE_H__ +#define __FENNIX_API_DEVICE_H__ + +#include + +#ifndef __FENNIX_API_FILESYSTEM_H__ +#if __has_include() +#include +#else +#include +#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__ diff --git a/include/driver.h b/include/driver.h index ad5c26d..d51671f 100644 --- a/include/driver.h +++ b/include/driver.h @@ -20,30 +20,6 @@ #include -typedef enum -{ - _drf_Entry, - _drf_Final, - _drf_Panic, - _drf_Probe, -} __driverRegFunc; - -typedef union -{ - struct - { - uint8_t LeftButton : 1; - uint8_t RightButton : 1; - uint8_t MiddleButton : 1; - uint8_t Button4 : 1; - uint8_t Button5 : 1; - uint8_t Button6 : 1; - uint8_t Button7 : 1; - uint8_t Button8 : 1; - }; - uint8_t Value; -} __MouseButtons; - typedef struct { /* PCIDevice */ void *Device; @@ -57,177 +33,22 @@ typedef struct typedef enum { - KEY_1, - KEY_2, - KEY_3, - KEY_4, - KEY_5, - KEY_6, - KEY_7, - KEY_8, - KEY_9, - KEY_0, + IOCTL_AUDIO_GET_VOLUME = 0, + IOCTL_AUDIO_SET_VOLUME = 1, - 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, + IOCTL_AUDIO_GET_MUTE = 2, + IOCTL_AUDIO_SET_MUTE = 3, - KEY_F1, - KEY_F2, - KEY_F3, - KEY_F4, - KEY_F5, - KEY_F6, - KEY_F7, - KEY_F8, - KEY_F9, - KEY_F10, - KEY_F11, - KEY_F12, + IOCTL_AUDIO_GET_SAMPLE_RATE = 4, + IOCTL_AUDIO_SET_SAMPLE_RATE = 5, - KEYPAD_7, - KEYPAD_8, - KEYPAD_9, - KEYPAD_MINUS, - KEYPAD_4, - KEYPAD_5, - KEYPAD_6, - KEYPAD_PLUS, - KEYPAD_1, - KEYPAD_2, - KEYPAD_3, - KEYPAD_0, - KEYPAD_PERIOD, - KEYPAD_RETURN, - KEYPAD_ASTERISK, - KEYPAD_SLASH, - - KEY_LEFT_CTRL, - KEY_RIGHT_CTRL, - KEY_LEFT_SHIFT, - KEY_RIGHT_SHIFT, - KEY_LEFT_ALT, - KEY_RIGHT_ALT, - KEY_ESCAPE, - KEY_MINUS, - KEY_EQUAL, - KEY_BACKSPACE, - KEY_TAB, - KEY_LEFT_BRACKET, - KEY_RIGHT_BRACKET, - KEY_RETURN, - KEY_SEMICOLON, - KEY_APOSTROPHE, - KEY_BACK_TICK, - KEY_BACKSLASH, - KEY_COMMA, - KEY_PERIOD, - KEY_SLASH, - KEY_SPACE, - KEY_CAPS_LOCK, - KEY_NUM_LOCK, - KEY_SCROLL_LOCK, - KEY_PRINT_SCREEN, - - KEY_HOME, - KEY_UP_ARROW, - KEY_LEFT_ARROW, - KEY_RIGHT_ARROW, - KEY_DOWN_ARROW, - KEY_PAGE_UP, - KEY_PAGE_DOWN, - KEY_END, - KEY_INSERT, - KEY_DELETE, - KEY_LEFT_GUI, - KEY_RIGHT_GUI, - KEY_APPS, - - KEY_MULTIMEDIA_PREV_TRACK, - KEY_MULTIMEDIA_NEXT_TRACK, - KEY_MULTIMEDIA_MUTE, - KEY_MULTIMEDIA_CALCULATOR, - KEY_MULTIMEDIA_PLAY, - KEY_MULTIMEDIA_STOP, - KEY_MULTIMEDIA_VOL_DOWN, - KEY_MULTIMEDIA_VOL_UP, - KEY_MULTIMEDIA_WWW_HOME, - KEY_MULTIMEDIA_WWW_SEARCH, - KEY_MULTIMEDIA_WWW_FAVORITES, - KEY_MULTIMEDIA_WWW_REFRESH, - KEY_MULTIMEDIA_WWW_STOP, - KEY_MULTIMEDIA_WWW_FORWARD, - KEY_MULTIMEDIA_WWW_BACK, - KEY_MULTIMEDIA_MY_COMPUTER, - KEY_MULTIMEDIA_EMAIL, - KEY_MULTIMEDIA_MEDIA_SELECT, - - KEY_ACPI_POWER, - KEY_ACPI_SLEEP, - KEY_ACPI_WAKE, - - KEY_PRESSED = 0x80, -} KeyScanCodes; - -typedef enum -{ - 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, + IOCTL_AUDIO_GET_CHANNELS = 6, + IOCTL_AUDIO_SET_CHANNELS = 7, } AudioIoctl; typedef enum { - IOCTL_NET_GET_MAC, + IOCTL_NET_GET_MAC = 0, } NetIoctl; typedef enum @@ -239,89 +60,17 @@ typedef enum MAP_CACHE_DISABLE = 1 << 4, } PageMapFlags; -typedef struct +struct __DriverInfo { - struct + const char *Name; + const char *Description; + const char *Author; + struct __DriverVersion { - uint8_t Major; - uint8_t Minor; - uint8_t Patch; - } APIVersion; - - dev_t MajorID; - uintptr_t Base; - - /* Internal */ - int (*RegisterFunction)(dev_t MajorID, void *Function, __driverRegFunc Type); - int (*GetDriverInfo)(dev_t MajorID, const char *Name, const char *Description, const char *Author, const char *Version, const char *License); - - /* Interrupts */ - int (*RegisterInterruptHandler)(dev_t MajorID, uint8_t IRQ, void *Handler); - int (*OverrideInterruptHandler)(dev_t MajorID, uint8_t IRQ, void *Handler); - int (*UnregisterInterruptHandler)(dev_t MajorID, uint8_t IRQ, void *Handler); - int (*UnregisterAllInterruptHandlers)(dev_t MajorID, void *Handler); - - /* 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; + int APIVersion; + int Major, Minor, Patch; + } Version; + const char *License; +}; #endif // !__FENNIX_API_DRIVER_FUNCTIONS_H__ diff --git a/include/errno.h b/include/errno.h index 159afeb..38aea8c 100644 --- a/include/errno.h +++ b/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 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, + 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 Drivers. If not, see . + along with Fennix Kernel. If not, see . */ -#ifndef _ERRNO_H -#define _ERRNO_H - -/** Operation not permitted */ -#define EPERM 1 - -/** No such file or directory */ -#define ENOENT 2 - -/** No such process */ -#define ESRCH 3 - -/** Interrupted system call */ -#define EINTR 4 - -/** I/O error */ -#define EIO 5 - -/** No such device or address */ -#define ENXIO 6 - -/** Argument list too long */ -#define E2BIG 7 - -/** Exec format error */ -#define ENOEXEC 8 - -/** Bad file number */ -#define EBADF 9 - -/** No child processes */ -#define ECHILD 10 - -/** Try again */ -#define EAGAIN 11 - -/** Out of memory */ -#define ENOMEM 12 - -/** Permission denied */ -#define EACCES 13 - -/** Bad address */ -#define EFAULT 14 - -/** Block device required */ -#define ENOTBLK 15 - -/** Device or resource busy */ -#define EBUSY 16 - -/** File exists */ -#define EEXIST 17 - -/** Cross-device link */ -#define EXDEV 18 - -/** No such device */ -#define ENODEV 19 - -/** Not a directory */ -#define ENOTDIR 20 - -/** Is a directory */ -#define EISDIR 21 - -/** Invalid argument */ -#define EINVAL 22 - -/** File table overflow */ -#define ENFILE 23 - -/** Too many open files */ -#define EMFILE 24 - -/** Not a typewriter */ -#define ENOTTY 25 - -/** Text file busy */ -#define ETXTBSY 26 - -/** File too large */ -#define EFBIG 27 - -/** No space left on device */ -#define ENOSPC 28 - -/** Illegal seek */ -#define ESPIPE 29 - -/** Read-only file system */ -#define EROFS 30 - -/** Too many links */ -#define EMLINK 31 - -/** Broken pipe */ -#define EPIPE 32 - -/** Math argument out of domain of func */ -#define EDOM 33 - -/** Math result not representable */ -#define ERANGE 34 - -/** Resource deadlock would occur */ -#define EDEADLK 35 - -/** File name too long */ -#define ENAMETOOLONG 36 - -/** No record locks available */ -#define ENOLCK 37 - -/** Function not implemented */ -#define ENOSYS 38 - -/** Directory not empty */ -#define ENOTEMPTY 39 - -/** Too many symbolic links encountered */ -#define ELOOP 40 - -/** No message of desired type */ -#define ENOMSG 42 - -/** Identifier removed */ -#define EIDRM 43 - -/** Channel number out of range */ -#define ECHRNG 44 - -/** Level 2 not synchronized */ -#define EL2NSYNC 45 - -/** Level 3 halted */ -#define EL3HLT 46 - -/** Level 3 reset */ -#define EL3RST 47 - -/** Link number out of range */ -#define ELNRNG 48 - -/** Protocol driver not attached */ -#define EUNATCH 49 - -/** No CSI structure available */ -#define ENOCSI 50 - -/** Level 2 halted */ -#define EL2HLT 51 - -/** Invalid exchange */ -#define EBADE 52 - -/** Invalid request descriptor */ -#define EBADR 53 - -/** Exchange full */ -#define EXFULL 54 - -/** No anode */ -#define ENOANO 55 - -/** Invalid request code */ -#define EBADRQC 56 - -/** Invalid slot */ -#define EBADSLT 57 - -/** Bad font file format */ -#define EBFONT 59 - -/** Device not a stream */ -#define ENOSTR 60 - -/** No data available */ -#define ENODATA 61 - -/** Timer expired */ -#define ETIME 62 - -/** Out of streams resources */ -#define ENOSR 63 - -/** Machine is not on the network */ -#define ENONET 64 - -/** Package not installed */ -#define ENOPKG 65 - -/** Object is remote */ -#define EREMOTE 66 - -/** Link has been severed */ -#define ENOLINK 67 - -/** Advertise error */ -#define EADV 68 - -/** Srmount error */ -#define ESRMNT 69 - -/** Communication error on send */ -#define ECOMM 70 - -/** Protocol error */ -#define EPROTO 71 - -/** Multihop attempted */ -#define EMULTIHOP 72 - -/** RFS specific error */ -#define EDOTDOT 73 - -/** Not a data message */ -#define EBADMSG 74 - -/** Value too large for defined data type */ -#define EOVERFLOW 75 - -/** Name not unique on network */ -#define ENOTUNIQ 76 - -/** File descriptor in bad state */ -#define EBADFD 77 - -/** Remote address changed */ -#define EREMCHG 78 - -/** Can not access a needed shared library */ -#define ELIBACC 79 - -/** Accessing a corrupted shared library */ -#define ELIBBAD 80 - -/** .lib section in a.out corrupted */ -#define ELIBSCN 81 - -/** Attempting to link in too many shared libraries */ -#define ELIBMAX 82 - -/** Cannot exec a shared library directly */ -#define ELIBEXEC 83 - -/** Illegal byte sequence */ -#define EILSEQ 84 - -/** Interrupted system call should be restarted */ -#define ERESTART 85 - -/** Streams pipe error */ -#define ESTRPIPE 86 - -/** Too many users */ -#define EUSERS 87 - -/** Socket operation on non-socket */ -#define ENOTSOCK 88 - -/** Destination address required */ -#define EDESTADDRREQ 89 - -/** Message too long */ -#define EMSGSIZE 90 - -/** Protocol wrong type for socket */ -#define EPROTOTYPE 91 - -/** Protocol not available */ -#define ENOPROTOOPT 92 - -/** Protocol not supported */ -#define EPROTONOSUPPORT 93 - -/** Socket type not supported */ -#define ESOCKTNOSUPPORT 94 - -/** Operation not supported on transport endpoint */ -#define EOPNOTSUPP 95 - -/** Protocol family not supported */ -#define EPFNOSUPPORT 96 - -/** Address family not supported by protocol */ -#define EAFNOSUPPORT 97 - -/** Address already in use */ -#define EADDRINUSE 98 - -/** Cannot assign requested address */ -#define EADDRNOTAVAIL 99 - -/** Network is down */ -#define ENETDOWN 100 - -/** Network is unreachable */ -#define ENETUNREACH 101 - -/** Network dropped connection because of reset */ -#define ENETRESET 102 - -/** Software caused connection abort */ -#define ECONNABORTED 103 - -/** Connection reset by peer */ -#define ECONNRESET 104 - -/** No buffer space available */ -#define ENOBUFS 105 - -/** Transport endpoint is already connected */ -#define EISCONN 106 - -/** Transport endpoint is not connected */ -#define ENOTCONN 107 - -/** Cannot send after transport endpoint shutdown */ -#define ESHUTDOWN 108 - -/** Too many references: cannot splice */ -#define ETOOMANYREFS 109 - -/** Connection timed out */ -#define ETIMEDOUT 110 - -/** Connection refused */ -#define ECONNREFUSED 111 - -/** Host is down */ -#define EHOSTDOWN 112 - -/** No route to host */ -#define EHOSTUNREACH 113 - -/** Operation already in progress */ -#define EALREADY 114 - -/** Operation now in progress */ -#define EINPROGRESS 115 - -/** Stale NFS file handle */ -#define ESTALE 116 - -/** Structure needs cleaning */ -#define EUCLEAN 117 - -/** Not a XENIX named type file */ -#define ENOTNAM 118 - -/** No XENIX semaphores available */ -#define ENAVAIL 119 - -/** Is a named type file */ -#define EISNAM 120 - -/** Remote I/O error */ -#define EREMOTEIO 121 - -/** Quota exceeded */ -#define EDQUOT 122 - -/** No medium found */ -#define ENOMEDIUM 123 - -/** Wrong medium type */ -#define EMEDIUMTYPE 124 - -/** Operation Canceled */ -#define ECANCELED 125 - -/** Required key not available */ -#define ENOKEY 126 - -/** Key has expired */ -#define EKEYEXPIRED 127 - -/** Key has been revoked */ -#define EKEYREVOKED 128 - -/** Key was rejected by service */ -#define EKEYREJECTED 129 - -/** Owner died */ -#define EOWNERDEAD 130 - -/** State not recoverable */ -#define ENOTRECOVERABLE 131 - -#endif // !_ERRNO_H +#ifndef __FENNIX_KERNEL_ERRNO_H__ +#define __FENNIX_KERNEL_ERRNO_H__ + +/** + * The documentation for these error codes are from: + * https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html + * + * Full list: + * https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/errno.h.html + */ +typedef enum +{ + /** + * No Error + */ + EOK = 0, + + /** + * Argument list too long. The sum of the number of bytes used by the + * new process image's argument list and environment list is greater + * than the system-imposed limit of {ARG_MAX} bytes. + * or: + * Lack of space in an output buffer. + * or: + * Argument is greater than the system-imposed maximum. + */ + E2BIG = 1, + + /** + * Permission denied. An attempt was made to access a file in a way + * forbidden by its file access permissions. + */ + EACCES = 2, + + /** + * Address in use. The specified address is in use. + */ + EADDRINUSE = 3, + + /** + * Address not available. The specified address is not available from + * the local system. + */ + EADDRNOTAVAIL = 4, + + /** + * Address family not supported. The implementation does not support + * the specified address family, or the specified address is not a + * valid address for the address family of the specified socket. + */ + EAFNOSUPPORT = 5, + + /** + * Resource temporarily unavailable. This is a temporary condition + * and later calls to the same routine may complete normally. + */ + EAGAIN = 6, + + /** + * Connection already in progress. A connection request is already in + * progress for the specified socket. + */ + EALREADY = 7, + + /** + * Bad file descriptor. A file descriptor argument is out of range, + * refers to no open file, or a read (write) request is made to a + * file that is only open for writing (reading). + */ + EBADF = 8, + + /** + * Bad message. During a read(), getmsg(), getpmsg(), or ioctl() + * I_RECVFD request to a STREAMS device, a message arrived at the + * head of the STREAM that is inappropriate for the function + * receiving the message. + * read() + * Message waiting to be read on a STREAM is not a data message. + * getmsg() or getpmsg() + * A file descriptor was received instead of a control message. + * ioctl() + * Control or data information was received instead of a file + * descriptor when I_RECVFD was specified. + */ + EBADMSG = 9, + + /** + * Resource busy. An attempt was made to make use of a system + * resource that is not currently available, as it is being + * used by another process in a manner that would have + * conflicted with the request being made by this process. + */ + EBUSY = 10, + + /** + * Operation canceled. The associated asynchronous operation was + * canceled before completion. + */ + ECANCELED = 11, + + /** + * No child process. A wait(), waitid(), or waitpid() function was + * executed by a process that had no existing or unwaited-for + * child process. + */ + ECHILD = 12, + + /** + * Connection aborted. The connection has been aborted. + */ + ECONNABORTED = 13, + + /** + * Connection refused. An attempt to connect to a socket was refused + * because there was no process listening or because the queue of + * connection requests was full and the underlying protocol does not + * support retransmissions. + */ + ECONNREFUSED = 14, + + /** + * Connection reset. The connection was forcibly closed by the peer. + */ + ECONNRESET = 15, + + /** + * Resource deadlock would occur. An attempt was made to lock a system + * resource that would have resulted in a deadlock situation. + */ + EDEADLK = 16, + + /** + * Destination address required. No bind address was established. + */ + EDESTADDRREQ = 17, + + /** + * Domain error. An input argument is outside the defined domain of the + * mathematical function (defined in the ISO C standard). + */ + EDOM = 18, + + /** + * Reserved. + */ + EDQUOT = 19, + + /** + * File exists. An existing file was mentioned in an inappropriate + * context; for example, as a new link name in the link() function. + */ + EEXIST = 20, + + /** + * Bad address. The system detected an invalid address in attempting + * to use an argument of a call. The reliable detection of this error + * cannot be guaranteed, and when not detected may result in the + * generation of a signal, indicating an address violation, which is + * sent to the process. + */ + EFAULT = 21, + + /** + * File too large. The size of a file would exceed the maximum file + * size of an implementation or offset maximum established in the + * corresponding file description. + */ + EFBIG = 22, + + /** + * Host is unreachable. The destination host cannot be reached + * (probably because the host is down or a remote router cannot + * reach it). + */ + EHOSTUNREACH = 23, + + /** + * Identifier removed. Returned during XSI interprocess communication + * if an identifier has been removed from the system. + */ + EIDRM = 24, + + /** + * Illegal byte sequence. A wide-character code has been detected that + * 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). + */ + EILSEQ = 25, + + /** + * Operation in progress. This code is used to indicate that an + * asynchronous operation has not yet completed. + * or: + * O_NONBLOCK is set for the socket file descriptor and the connection + * cannot be immediately established. + */ + EINPROGRESS = 26, + + /** + * Interrupted function call. An asynchronous signal was caught by the + * process during the execution of an interruptible function. If the + * signal handler performs a normal return, the interrupted function + * call may return this condition (see the Base Definitions volume + * of POSIX.1-2017, ). + */ + EINTR = 27, + + /** + * Invalid argument. Some invalid argument was supplied; for example, + * specifying an undefined signal in a signal() function or a + * kill() function. + */ + EINVAL = 28, + + /** + * Input/output error. Some physical input or output error has occurred. + * This error may be reported on a subsequent operation on the same + * file descriptor. Any other error-causing operation on the same file + * descriptor may cause the [EIO] error indication to be lost. + */ + EIO = 29, + + /** + * Socket is connected. The specified socket is already connected. + */ + EISCONN = 30, + + /** + * Is a directory. An attempt was made to open a directory with write + * mode specified. + */ + EISDIR = 31, + + /** + * Symbolic link loop. A loop exists in symbolic links encountered + * during pathname resolution. This error may also be returned if + * more than {SYMLOOP_MAX} symbolic links are encountered during + * pathname resolution. + */ + ELOOP = 32, + + /** + * File descriptor value too large or too many open streams. An + * attempt was made to open a file descriptor with a value greater + * than or equal to {OPEN_MAX}, or an attempt was made to open more + * than the maximum number of streams allowed in the process. + */ + EMFILE = 33, + + /** + * Too many links. An attempt was made to have the link count of a + * single file exceed {LINK_MAX}. + */ + EMLINK = 34, + + /** + * Message too large. A message sent on a transport provider was + * larger than an internal message buffer or some other network limit. + * or: + * Inappropriate message buffer length. + */ + EMSGSIZE = 35, + + /** + * Reserved. + */ + EMULTIHOP = 36, + + /** + * Filename too long. The length of a pathname exceeds {PATH_MAX} and + * the implementation considers this to be an error, or a pathname + * component is longer than {NAME_MAX}. This error may also occur + * when pathname substitution, as a result of encountering a + * symbolic link during pathname resolution, results in a pathname + * string the size of which exceeds {PATH_MAX}. + */ + ENAMETOOLONG = 37, + + /** + * Network is down. The local network interface used to reach the + * destination is down. + */ + ENETDOWN = 38, + + /** + * The connection was aborted by the network. + */ + ENETRESET = 39, + + /** + * Network unreachable. No route to the network is present. + */ + ENETUNREACH = 40, + + /** + * Too many files open in system. Too many files are currently open + * in the system. The system has reached its predefined limit for + * simultaneously open files and temporarily cannot accept requests + * to open another one. + */ + ENFILE = 41, + + /** + * No buffer space available. Insufficient buffer resources were + * available in the system to perform the socket operation. + */ + ENOBUFS = 42, + + /** + * No message available. No message is available on the STREAM head + * read queue. + */ + ENODATA = 43, + + /** + * No such device. An attempt was made to apply an inappropriate + * function to a device; for example, trying to read a write-only + * device such as a printer. + */ + ENODEV = 44, + + /** + * No such file or directory. A component of a specified pathname + * does not exist, or the pathname is an empty string. + */ + ENOENT = 45, + + /** + * Executable file format error. A request is made to execute a file + * that, although it has appropriate privileges, is not in the + * format required by the implementation for executable files. + */ + ENOEXEC = 46, + + /** + * No locks available. A system-imposed limit on the number of + * simultaneous file and record locks has been reached and no more + * are currently available. + */ + ENOLCK = 47, + + /** + * Reserved. + */ + ENOLINK = 48, + + /** + * Not enough space. The new process image requires more memory than + * is allowed by the hardware or system-imposed memory management + * constraints. + */ + ENOMEM = 49, + + /** + * No message of the desired type. The message queue does not contain + * a message of the required type during XSI interprocess communication. + */ + ENOMSG = 50, + + /** + * Protocol not available. The protocol option specified to + * setsockopt() is not supported by the implementation. + */ + ENOPROTOOPT = 51, + + /** + * No space left on a device. During the write() function on a + * regular file or when extending a directory, there is no free + * space left on the device. + */ + ENOSPC = 52, + + /** + * No STREAM resources. Insufficient STREAMS memory resources are + * available to perform a STREAMS-related function. This is a + * temporary condition; it may be recovered from if other + * processes release resources. + */ + ENOSR = 53, + + /** + * Not a STREAM. A STREAM function was attempted on a file descriptor + * that was not associated with a STREAMS device. + */ + ENOSTR = 54, + + /** + * Functionality not supported. An attempt was made to use optional + * functionality that is not supported in this implementation. + */ + 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- character and ends + * with one or more trailing 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 +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__ diff --git a/include/fs.h b/include/fs.h new file mode 100644 index 0000000..374cc53 --- /dev/null +++ b/include/fs.h @@ -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 . +*/ + +#ifndef __FENNIX_API_FILESYSTEM_H__ +#define __FENNIX_API_FILESYSTEM_H__ + +#include + +#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__ diff --git a/include/input.h b/include/input.h index 4117043..6e124bf 100644 --- a/include/input.h +++ b/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 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, + 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 Drivers. If not, see . + along with Fennix Kernel. If not, see . */ #ifndef __FENNIX_API_INPUT_H__ #define __FENNIX_API_INPUT_H__ #include -#include + +#if __has_include() +#include +#else +#include +#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 { - union - { - struct - { - uint8_t LeftButton : 1; - uint8_t RightButton : 1; - uint8_t MiddleButton : 1; - uint8_t Button4 : 1; - uint8_t Button5 : 1; - }; - uint8_t Buttons; - }; + KeyScanCodes Key; +} KeyboardReport; - /** - * @note Ignored if is absolute - */ - int X; - - /** - * @note Ignored if is absolute - */ - int Y; +typedef struct +{ + long X, Y; int8_t Z; + uint8_t Absolute : 1; + uint8_t LeftButton : 1; + uint8_t RightButton : 1; + uint8_t MiddleButton : 1; + uint8_t Button4 : 1; + uint8_t Button5 : 1; + uint8_t Button6 : 1; + uint8_t Button7 : 1; + uint8_t Button8 : 1; } MouseReport; -#ifdef __cplusplus -extern "C" +typedef struct { -#endif // __cplusplus +} JoystickReport; - dev_t RegisterInputDevice(DeviceDriverType Type); - int UnregisterInputDevice(dev_t DeviceID, DeviceDriverType Type); - int ReportKeyboardEvent(dev_t DeviceID, KeyScanCodes ScanCode, uint8_t Pressed); - int ReportRelativeMouseEvent(dev_t DeviceID, MouseReport Report); - int ReportAbsoluteMouseEvent(dev_t DeviceID, MouseReport Report, uintptr_t X, uintptr_t Y); +typedef struct +{ + uint16_t X, Y; + uint8_t Pressure; +} TouchScreenReport; -#ifdef __cplusplus -} -#endif // __cplusplus +typedef struct +{ +} GamepadReport; + +typedef struct +{ +} AccelerometerReport; + +typedef struct +{ +} GyroscopeReport; + +typedef struct +{ +} MagnetometerReport; + +typedef struct +{ + DeviceType Type; + dev_t Device; + union + { + KeyboardReport Keyboard; + MouseReport Mouse; + JoystickReport Joystick; + TouchScreenReport TouchScreen; + GamepadReport Gamepad; + AccelerometerReport Accelerometer; + GyroscopeReport Gyroscope; + MagnetometerReport Magnetometer; + /* ... */ + }; +} InputReport; + +EXTERNC int ReportInputEvent(InputReport *Report); #endif // !__FENNIX_API_INPUT_H__ diff --git a/include/net.h b/include/net.h deleted file mode 100644 index 42ca0de..0000000 --- a/include/net.h +++ /dev/null @@ -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 . -*/ - -#ifndef __FENNIX_API_AUDIO_H__ -#define __FENNIX_API_AUDIO_H__ - -#include -#include - -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__ diff --git a/include/network.h b/include/network.h new file mode 100644 index 0000000..89f7bb1 --- /dev/null +++ b/include/network.h @@ -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 . +*/ + +#ifndef __FENNIX_API_NETWORK_H__ +#define __FENNIX_API_NETWORK_H__ + +#include + +#if __has_include() +#include +#else +#include +#endif + +#endif // !__FENNIX_API_NETWORK_H__ diff --git a/include/pci.h b/include/pci.h index a307cf7..cd96b6a 100644 --- a/include/pci.h +++ b/include/pci.h @@ -21,7 +21,7 @@ #include /* https://sites.uclouvain.be/SystInfo/usr/include/linux/pci_regs.h.html */ -enum PCICommands +typedef enum { /** @brief Enable response in I/O space */ PCI_COMMAND_IO = 0x1, @@ -45,7 +45,7 @@ enum PCICommands PCI_COMMAND_FAST_BACK = 0x200, /** @brief INTx Emulation Disable */ PCI_COMMAND_INTX_DISABLE = 0x400 -}; +} PCI_COMMANDS; typedef struct { @@ -171,7 +171,7 @@ extern "C" { #endif - PCIArray *FindPCIDevices(uint16_t Vendors[], uint16_t Devices[]); + PCIArray *GetPCIDevices(uint16_t Vendors[], uint16_t Devices[]); void InitializePCI(PCIDevice *Device); uint32_t GetBAR(uint8_t Index, PCIDevice *Device); uint8_t iLine(PCIDevice *Device); diff --git a/include/regs.h b/include/regs.h index c731529..6a6c092 100644 --- a/include/regs.h +++ b/include/regs.h @@ -21,6 +21,7 @@ #include #if defined(__amd64__) + typedef struct { uint64_t r15; // General purpose @@ -49,8 +50,10 @@ typedef struct uint64_t rsp; // Stack Pointer uint64_t ss; // Stack Segment } TrapFrame; + #elif defined(__i386__) -typedef struct TrapFrame + +typedef struct { uint32_t edi; // Destination 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_ss; // Stack Segment } TrapFrame; + #elif defined(__aarch64__) -typedef struct TrapFrame + +typedef struct { uint64_t x19; // General purpose uint64_t x20; // General purpose @@ -95,6 +100,7 @@ typedef struct TrapFrame uint64_t InterruptNumber /* iar_el1 */; // Interrupt Acknowledge Register } TrapFrame; + #endif #endif // !__FENNIX_API_REGISTERS_H__ diff --git a/include/syscall.h b/include/syscall.h deleted file mode 100644 index 1fdf92a..0000000 --- a/include/syscall.h +++ /dev/null @@ -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__ diff --git a/include/syscalls.h b/include/syscalls.h new file mode 100644 index 0000000..f5936f7 --- /dev/null +++ b/include/syscalls.h @@ -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 . +*/ + +#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__ diff --git a/include/types.h b/include/types.h index f9a717d..03fee4a 100644 --- a/include/types.h +++ b/include/types.h @@ -53,11 +53,41 @@ typedef __UINTMAX_TYPE__ uintmax_t; typedef __PTRDIFF_TYPE__ ptrdiff_t; typedef __SIZE_TYPE__ size_t; +typedef intptr_t ssize_t; -typedef __SIZE_TYPE__ dev_t; -typedef __SIZE_TYPE__ off_t; +#if defined(__LP64__) +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_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; +#endif #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 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__ diff --git a/input/aip/Makefile b/input/aip/Makefile index 0c529af..de6f60f 100644 --- a/input/aip/Makefile +++ b/input/aip/Makefile @@ -1,83 +1,22 @@ -# Config file +# Config files include ../../../Makefile.conf - -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 +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) $(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) -INCLUDE_DIR = ../../include -LIBS := ../../out/dcrt0.o -L../../out -ldriver - -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 +FILENAME = aip.drv build: $(FILENAME) mv $(FILENAME) ../../out/$(FILENAME) $(FILENAME): $(OBJ) $(info Linking $@) - $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -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 $@ $< + $(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@ clean: rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/input/aip/keyboard.c b/input/aip/keyboard.c index 7f2c165..36df825 100644 --- a/input/aip/keyboard.c +++ b/input/aip/keyboard.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -161,6 +162,17 @@ const unsigned short ScanCodeSet3[] = { [0x4B] = KEY_L, [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 IsE1 = false; void PS2KbdInterruptHandler(TrapFrame *) @@ -217,12 +229,21 @@ void PS2KbdInterruptHandler(TrapFrame *) { if (IsE0) IsE0 = false; - Log("Unknown PS/2 Keyboard Scan Code Set: %#x", KeyboardScanCodeSet); + KernelLog("Unknown PS/2 Keyboard Scan Code Set: %#x", KeyboardScanCodeSet); break; } } } +int __fs_kb_Ioctl(struct Inode *, unsigned long, void *) +{ + return 0; +} + +const struct InodeOperations KbdOps = { + .Ioctl = __fs_kb_Ioctl, +}; + int InitializeKeyboard() { // PS2WriteData(PS2_KBD_CMD_RESET); @@ -230,45 +251,50 @@ int InitializeKeyboard() // if (test != PS2_KBD_RESP_TEST_PASSED && // test != PS2_KBD_RESP_ACK) // { - // Log("PS/2 keyboard reset failed (%#x)", test); + // KernelLog("PS/2 keyboard reset failed (%#x)", test); // return -EFAULT; // } PS2WriteData(PS2_KBD_CMD_DEFAULTS); 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); 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 */ PS2WriteData(PS2_KBD_SCAN_CODE_SET_2); /* It will set to 1 but with translation? */ 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); 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); 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(); - Log("PS/2 Keyboard Scan Code Set: 0x%X", KeyboardScanCodeSet); + KernelLog("PS/2 Keyboard Scan Code Set: 0x%X", KeyboardScanCodeSet); PS2ClearOutputBuffer(); PS2WriteData(PS2_KBD_CMD_ENABLE_SCANNING); RegisterInterruptHandler(1, PS2KbdInterruptHandler); - KeyboardDevID = RegisterInputDevice(ddt_Keyboard); + + KeyboardDevID = RegisterDevice(INPUT_TYPE_KEYBOARD, &KbdOps); return 0; } 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; } @@ -276,11 +302,11 @@ int DetectPS2Keyboard() { PS2WriteData(PS2_KBD_CMD_DISABLE_SCANNING); if (PS2ACKTimeout() != 0) - Log("PS/2 keyboard failed to disable scanning"); + KernelLog("PS/2 keyboard failed to disable scanning"); PS2WriteData(PS2_KBD_CMD_IDENTIFY); if (PS2ACKTimeout() != 0) - Log("PS/2 keyboard failed to identify"); + KernelLog("PS/2 keyboard failed to identify"); uint8_t recByte; int timeout = 1000000; @@ -300,10 +326,10 @@ int DetectPS2Keyboard() break; } if (timeout == 0) - Log("PS/2 keyboard second byte timed out"); + KernelLog("PS/2 keyboard second byte timed out"); else 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; } diff --git a/input/aip/main.c b/input/aip/main.c index a63a513..606927c 100644 --- a/input/aip/main.c +++ b/input/aip/main.c @@ -104,7 +104,7 @@ int DriverEntry() DualChannel = cfg.Port2Clock; if (DualChannel) - Log("Dual channel PS/2 controller detected"); + KernelLog("Dual channel PS/2 controller detected"); cfg.Port1Interrupt = 1; cfg.Port2Interrupt = 1; cfg.Port1Translation = 1; @@ -116,7 +116,7 @@ int DriverEntry() uint8_t test = PS2ReadData(); 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; } @@ -137,7 +137,7 @@ int DriverEntry() test = PS2ReadData(); 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; } @@ -147,7 +147,7 @@ int DriverEntry() test = PS2ReadData(); 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; } } @@ -204,7 +204,7 @@ int DriverProbe() { if (!IsKeyboard(Device1ID[0])) { - Log("PS/2 Port 1 is not a keyboard"); + KernelLog("PS/2 Port 1 is not a keyboard"); // return -EINVAL; } } @@ -213,15 +213,15 @@ int DriverProbe() { if (!IsMouse(Device2ID[0])) { - Log("PS/2 Port 2 is not a mouse"); + KernelLog("PS/2 Port 2 is not a mouse"); // 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]), 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]), Device2ID[0], Device2ID[1]); return 0; @@ -230,5 +230,5 @@ int DriverProbe() DriverInfo("aip", "Advanced Integrated Peripheral Driver", "EnderIce2", - "0.1", + 0, 0, 1, "GPLv3"); diff --git a/input/aip/mouse.c b/input/aip/mouse.c index 2ac8337..284ccd0 100644 --- a/input/aip/mouse.c +++ b/input/aip/mouse.c @@ -18,8 +18,9 @@ #include "aip.h" #include -#include #include +#include +#include dev_t MouseDevID = -1; bool PacketReady = false; @@ -28,6 +29,7 @@ bool MouseButton45 = false; uint8_t Cycle = 0; PS2_MOUSE_PACKET Packet = {0}; +InputReport mir = {0}; void PS2MouseInterruptHandler(TrapFrame *) { uint8_t data = PS2ReadData(); @@ -114,18 +116,17 @@ void PS2MouseInterruptHandler(TrapFrame *) if (Packet.Base.YOverflow) Y = 0; - MouseReport mr = { - .LeftButton = Packet.Base.LeftButton, - .RightButton = Packet.Base.RightButton, - .MiddleButton = Packet.Base.MiddleButton, - .Button4 = Packet.ZMovement.Button4, - .Button5 = Packet.ZMovement.Button5, - .X = X, - .Y = -Y, - .Z = Packet.ZMovement.Z, - }; - ReportRelativeMouseEvent(MouseDevID, mr); - + mir.Type = INPUT_TYPE_MOUSE; + mir.Device = MouseDevID; + mir.Mouse.LeftButton = Packet.Base.LeftButton; + mir.Mouse.RightButton = Packet.Base.RightButton; + mir.Mouse.MiddleButton = Packet.Base.MiddleButton; + mir.Mouse.Button4 = Packet.ZMovement.Button4; + mir.Mouse.Button5 = Packet.ZMovement.Button5; + mir.Mouse.X = X; + mir.Mouse.Y = -Y; + mir.Mouse.Z = Packet.ZMovement.Z; + ReportInputEvent(&mir); PacketReady = false; } @@ -140,6 +141,15 @@ void MouseSampleRate(uint8_t SampleRate) PS2ReadData(); } +int __fs_ms_Ioctl(struct Inode *, unsigned long, void *) +{ + return 0; +} + +const struct InodeOperations MouseOps = { + .Ioctl = __fs_ms_Ioctl, +}; + int InitializeMouse() { PS2WriteData(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); @@ -148,12 +158,13 @@ int InitializeMouse() if (test != PS2_MOUSE_RESP_TEST_PASSED && test != PS2_MOUSE_RESP_ACK) { - Log("PS/2 mouse reset failed! (%#x)", test); + KernelLog("PS/2 mouse reset failed! (%#x)", test); return -EFAULT; } RegisterInterruptHandler(12, PS2MouseInterruptHandler); - MouseDevID = RegisterInputDevice(ddt_Mouse); + + MouseDevID = RegisterDevice(INPUT_TYPE_MOUSE, &MouseOps); PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); PS2WriteData(PS2_MOUSE_CMD_SET_DEFAULTS); @@ -169,7 +180,7 @@ int InitializeMouse() PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); PS2WriteData(PS2_MOUSE_CMD_READ_ID); uint8_t Device2ID = PS2ReadData(); - Log("PS/2 Mouse ID: %#x", Device2ID); + KernelLog("PS/2 Mouse ID: %#x", Device2ID); MouseSampleRate(200); MouseSampleRate(200); @@ -178,7 +189,7 @@ int InitializeMouse() PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); PS2WriteData(PS2_MOUSE_CMD_READ_ID); Device2ID = PS2ReadData(); - Log("PS/2 Mouse ID: %#x", Device2ID); + KernelLog("PS/2 Mouse ID: %#x", Device2ID); if (Device2ID >= 3 && Device2ID <= 4) FourPackets = true; @@ -190,10 +201,10 @@ int InitializeMouse() int FinalizeMouse() { - UnregisterInputDevice(MouseDevID, ddt_Mouse); - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING); + + UnregisterDevice(MouseDevID); return 0; } @@ -202,12 +213,12 @@ int DetectPS2Mouse() PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING); 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); PS2WriteData(PS2_MOUSE_CMD_READ_ID); if (PS2ACKTimeout() != 0) - Log("PS/2 mouse failed to read ID!"); + KernelLog("PS/2 mouse failed to read ID!"); uint8_t recByte; int timeout = 1000000; @@ -228,6 +239,6 @@ int DetectPS2Mouse() } 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; } diff --git a/library/Makefile b/library/Makefile index 752d3a5..328d43d 100644 --- a/library/Makefile +++ b/library/Makefile @@ -1,7 +1,7 @@ # Config file include ../../Makefile.conf -FILENAME = libdriver.a +FILENAME = libkernel.so CC = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc 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) INCLUDE_DIR = ../include -LDFLAGS := \ - -fPIC -fPIE -pie \ - -nostdlib -nodefaultlibs -nolibc \ - -zmax-page-size=0x1000 \ - -Wl,-Map driver.map -static -fvisibility=hidden +LDFLAGS := -fPIC -fPIE -pie -nostdlib -nodefaultlibs -nolibc \ + -zmax-page-size=0x1000 -Wl,-Map libkernel.map -shared WARNCFLAG = -Wall -Wextra -CFLAGS := -I$(INCLUDE_DIR) -fvisibility=hidden +CFLAGS := -I$(INCLUDE_DIR) -shared ifeq ($(OSARCH), amd64) @@ -46,25 +43,29 @@ CFLAGS += -pipe -fno-builtin -fPIC endif +CRT_CFLAGS := -fPIC -fPIE -pie -mno-red-zone -std=c++20 -I../include + ifeq ($(DEBUG), 1) CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage + CRT_CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage ifeq ($(OSARCH), amd64) CFLAGS += -fverbose-asm + CRT_CFLAGS += -fverbose-asm endif ifneq ($(OSARCH), aarch64) CFLAGS += -fstack-check + CRT_CFLAGS += -fstack-check endif LDFLAGS += -ggdb3 -O0 endif 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 $(FILENAME): $(OBJ) $(info Linking $@) - $(AR) rcs $@ $(OBJ) - mv $(FILENAME) ../out/$(FILENAME) + $(CC) $(LDFLAGS) $(OBJ) -o ../out/$(FILENAME) %.o: %.c $(HEADERS) $(info Compiling $<) @@ -79,4 +80,4 @@ $(FILENAME): $(OBJ) $(AS) -o $@ $< clean: - rm -f driver.map $(OBJ) $(FILENAME) $(STACK_USAGE_OBJ) dcrt0.su + rm -f libkernel.map $(OBJ) $(FILENAME) $(STACK_USAGE_OBJ) dcrt0.su diff --git a/library/aip.c b/library/aip.c deleted file mode 100644 index 6314983..0000000 --- a/library/aip.c +++ /dev/null @@ -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 . -*/ - -#include - -#include -#include - -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; -} diff --git a/library/audio.c b/library/audio.c deleted file mode 100644 index ef51d46..0000000 --- a/library/audio.c +++ /dev/null @@ -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 . -*/ - -#include - -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); -} diff --git a/library/base.c b/library/base.c deleted file mode 100644 index 6b661aa..0000000 --- a/library/base.c +++ /dev/null @@ -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 . -*/ - -#include - -#include -#include - -__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 -} diff --git a/library/base.cpp b/library/base.cpp new file mode 100644 index 0000000..43518a3 --- /dev/null +++ b/library/base.cpp @@ -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 . +*/ + +#include + +#include +#include +#include + +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); diff --git a/library/block.c b/library/block.c deleted file mode 100644 index 10dd2db..0000000 --- a/library/block.c +++ /dev/null @@ -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 . -*/ - -#include - -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); -} diff --git a/library/crt/crt0.c b/library/crt/crt0.c deleted file mode 100644 index 509492c..0000000 --- a/library/crt/crt0.c +++ /dev/null @@ -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 . -*/ - -#include -#include - -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; -} diff --git a/library/crt/crt0.cpp b/library/crt/crt0.cpp new file mode 100644 index 0000000..5b2aeff --- /dev/null +++ b/library/crt/crt0.cpp @@ -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 . +*/ + +#include +#include + +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); diff --git a/library/input.c b/library/input.c deleted file mode 100644 index 19bc1d0..0000000 --- a/library/input.c +++ /dev/null @@ -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 . -*/ - -#include - -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); -} diff --git a/library/net.c b/library/net.c deleted file mode 100644 index fa37a70..0000000 --- a/library/net.c +++ /dev/null @@ -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 . -*/ - -#include - -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); -} diff --git a/library/pci.c b/library/pci.c deleted file mode 100644 index 7bea853..0000000 --- a/library/pci.c +++ /dev/null @@ -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 . -*/ - -#include - -#include - -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; -} diff --git a/library/std.c b/library/std.c deleted file mode 100644 index 3cbe942..0000000 --- a/library/std.c +++ /dev/null @@ -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 . -*/ - -#include -#include - -#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); -} diff --git a/library/stdcpp.cpp b/library/stdcpp.cpp deleted file mode 100644 index ecf7751..0000000 --- a/library/stdcpp.cpp +++ /dev/null @@ -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 . -*/ - -#include -#include - -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); -} diff --git a/library/task.c b/library/task.c deleted file mode 100644 index 515416a..0000000 --- a/library/task.c +++ /dev/null @@ -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 . -*/ - -#include -#include - -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); -} diff --git a/library/vm.c b/library/vm.c deleted file mode 100644 index f0cd2fc..0000000 --- a/library/vm.c +++ /dev/null @@ -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 . -*/ - -#include - -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; -} diff --git a/misc/example/Makefile b/misc/example/Makefile index b15790f..9d07ef3 100644 --- a/misc/example/Makefile +++ b/misc/example/Makefile @@ -1,83 +1,22 @@ -# Config file +# Config files include ../../../Makefile.conf - -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 +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) $(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) -INCLUDE_DIR = ../../include -LIBS := ../../out/dcrt0.o -L../../out -ldriver - -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 +FILENAME = example.drv build: $(FILENAME) mv $(FILENAME) ../../out/$(FILENAME) $(FILENAME): $(OBJ) $(info Linking $@) - $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -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 $@ $< + $(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@ clean: rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/misc/example/main.c b/misc/example/main.c index b4f363b..b1ff813 100644 --- a/misc/example/main.c +++ b/misc/example/main.c @@ -20,16 +20,15 @@ int DriverEntry() { /** 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 * and allocate resources. */ - /* Print a message to the screen */ - KPrint("Hello World from Example Driver!"); + /* Print a message to the kernel terminal */ + KernelPrint("Hello World from Example Driver!"); /* 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 */ DebugLog("Hello World from Example Driver!"); @@ -52,7 +51,7 @@ int DriverPanic() { /** This function is called when the kernel panics. * 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. */ @@ -63,13 +62,14 @@ int DriverProbe() { /** This is the first function that is called when the * driver is loaded. - * We can use this function to test if the driver is - * compatible with the hardware. - * Like if we have a specific PCI device or if we have - * a specific CPU feature. + * + * This function is to test if the driver is compatible + * with the hardware. + * 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. - * 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 * have constructors or destructors. Before DriverEntry, @@ -80,8 +80,18 @@ int DriverProbe() 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", "Example Driver", "EnderIce2", - "0.1", + 0, 0, 1, "GPLv3"); diff --git a/misc/vmware/Makefile b/misc/vmware/Makefile index 171f3b4..cfffabc 100644 --- a/misc/vmware/Makefile +++ b/misc/vmware/Makefile @@ -1,83 +1,22 @@ -# Config file +# Config files include ../../../Makefile.conf - -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 +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) $(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) -INCLUDE_DIR = ../../include -LIBS := ../../out/dcrt0.o -L../../out -ldriver - -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 +FILENAME = vmware.drv build: $(FILENAME) mv $(FILENAME) ../../out/$(FILENAME) $(FILENAME): $(OBJ) $(info Linking $@) - $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -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 $@ $< + $(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@ clean: rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/misc/vmware/main.c b/misc/vmware/main.c index c2a0e7a..d4ea5f6 100644 --- a/misc/vmware/main.c +++ b/misc/vmware/main.c @@ -17,11 +17,11 @@ #include #include +#include #include #include #include #include -#include #include enum RPCMessages @@ -170,7 +170,7 @@ typedef struct "r"(bp) : "memory", "cc") /* 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 @@ -183,6 +183,102 @@ typedef struct 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) { 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) { - Log("Failed to open message channel %#lx", Protocol); + KernelLog("Failed to open message channel %#lx", Protocol); return -EINVAL; } @@ -343,8 +439,8 @@ static int MessageSend(ToolboxContext *ctx, if ((HighWord(cx) & STATUS_SUCCESS) == 0) { - Log("Failed to send message size for \"%s\": %d", - Message, cx); + KernelLog("Failed to send message size for \"%s\": %d", + Message, cx); return -EINVAL; } @@ -363,14 +459,14 @@ static int MessageSend(ToolboxContext *ctx, } else if ((status & STATUS_CPT) == 0) { - Log("Checkpoint occurred for message \"%s\"", Message); + KernelLog("Checkpoint occurred for message \"%s\"", Message); continue; } else break; } - Log("Failed to send message \"%s\": %#lx", Message, bx); + KernelLog("Failed to send message \"%s\": %#lx", Message, bx); return -EINVAL; } @@ -401,12 +497,12 @@ static int MessageReceive(ToolboxContext *ctx, if ((HighWord(cx) & STATUS_SUCCESS) == 0) { - Log("Failed to receive message size: %d", cx); + KernelLog("Failed to receive message size: %d", cx); return -EINVAL; } else if ((HighWord(cx) & STATUS_DORECV) == 0) { - // Log("No message to receive"); + DebugLog("No message to receive"); return -EAGAIN; } @@ -427,11 +523,11 @@ static int MessageReceive(ToolboxContext *ctx, { if ((HighWord(bx) & STATUS_CPT) == 0) { - Log("Checkpoint occurred for message payload"); + KernelLog("Checkpoint occurred for message payload"); continue; } - Log("Failed to receive message payload: %d", HighWord(bx)); + KernelLog("Failed to receive message payload: %d", HighWord(bx)); FreeMemory(ReplyBuf, ReplyBufPages); return -EINVAL; } @@ -451,11 +547,11 @@ static int MessageReceive(ToolboxContext *ctx, { if ((HighWord(cx) & STATUS_CPT) == 0) { - Log("Retrying message receive"); + KernelLog("Retrying message receive"); continue; } - Log("Failed to receive message status: %d", HighWord(cx)); + KernelLog("Failed to receive message status: %d", HighWord(cx)); FreeMemory(ReplyBuf, ReplyBufPages); return -EINVAL; } @@ -465,7 +561,7 @@ static int MessageReceive(ToolboxContext *ctx, if (ReplyBuf == NULL) { - Log("Failed to receive message"); + KernelLog("Failed to receive message"); return -EINVAL; } @@ -481,14 +577,14 @@ static int SendRPCI(ToolboxContext *, const char *Request) int status = OpenMessageChannel(&rpci_ctx, MESSAGE_RPCI); if (status < 0) { - Log("Failed to open RPCI channel: %d", status); + KernelLog("Failed to open RPCI channel: %d", status); return status; } status = MessageSend(&rpci_ctx, Request); if (status < 0) { - Log("Failed to send RPCI request: %d", status); + KernelLog("Failed to send RPCI request: %d", status); return status; } @@ -524,7 +620,7 @@ static int DisplayGetSize(ToolboxContext *ctx) } else if (status < 0) { - Log("Failed to receive message"); + KernelLog("Failed to receive message"); return 1; } @@ -579,7 +675,7 @@ void DisplayScaleThread() while (true) { if (DisplayGetSize(tb_ctx) != 0) - Log("Failed to scale display"); + KernelLog("Failed to scale display"); Sleep(1000); } } @@ -627,6 +723,7 @@ void Relative() CommandSend(&cmd); } +InputReport ir = {0}; void InterruptHandler(TrapFrame *) { uint8_t Data = inb(0x60); @@ -639,7 +736,7 @@ void InterruptHandler(TrapFrame *) if (cmd.ax == 0xFFFF0000) { - Log("VMware mouse is not connected?"); + KernelLog("VMware mouse is not connected?"); Relative(); Absolute(); return; @@ -654,17 +751,6 @@ void InterruptHandler(TrapFrame *) 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? * (cmd.[bx,cx] * Width) / 0xFFFF @@ -672,9 +758,44 @@ void InterruptHandler(TrapFrame *) */ uintptr_t AbsoluteX = cmd.bx; 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; int DriverEntry() { @@ -711,7 +832,8 @@ int DriverEntry() * override its interrupt handler. */ OverrideInterruptHandler(12, InterruptHandler); - MouseDevID = RegisterInputDevice(ddt_Mouse); + + MouseDevID = RegisterDevice(INPUT_TYPE_MOUSE, &MouseOps); return 0; } @@ -721,7 +843,8 @@ int DriverFinal() PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING); Relative(); - UnregisterInputDevice(MouseDevID, ddt_Mouse); + + UnregisterDevice(MouseDevID); if (ToolboxSupported) { @@ -751,5 +874,5 @@ int DriverProbe() DriverInfo("vmware", "VMware Tools Driver", "EnderIce2", - "0.1", + 0, 0, 1, "GPLv3"); diff --git a/network/e1000/Makefile b/network/e1000/Makefile index cd5cbb9..7685158 100644 --- a/network/e1000/Makefile +++ b/network/e1000/Makefile @@ -1,83 +1,22 @@ -# Config file +# Config files include ../../../Makefile.conf - -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 +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) $(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) -INCLUDE_DIR = ../../include -LIBS := ../../out/dcrt0.o -L../../out -ldriver - -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 +FILENAME = e1000.drv build: $(FILENAME) mv $(FILENAME) ../../out/$(FILENAME) $(FILENAME): $(OBJ) $(info Linking $@) - $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -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 $@ $< + $(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@ clean: rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/network/e1000/e1000.cpp b/network/e1000/e1000.cpp index 43f57c2..5de1f68 100644 --- a/network/e1000/e1000.cpp +++ b/network/e1000/e1000.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include "e1000.hpp" @@ -205,7 +205,7 @@ public: mac.Address[i] = BaseMac8[i]; else { - Log("No MAC address found."); + KernelLog("No MAC address found."); return MediaAccessControl(); } } @@ -240,7 +240,11 @@ public: uint8_t *data = (uint8_t *)RX[RXCurrent]->Address; 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; uint16_t OldRXCurrent = RXCurrent; @@ -270,7 +274,7 @@ public: { case 0x100E: { - Log("Found Intel 82540EM Gigabit Ethernet Controller."); + KernelLog("Found Intel 82540EM Gigabit Ethernet Controller."); /* Detect EEPROM */ WriteCMD(REG::EEPROM, 0x1); @@ -282,7 +286,7 @@ public: if (!GetMAC().Valid()) { - Log("Failed to get MAC"); + KernelLog("Failed to get MAC"); return; } @@ -303,7 +307,7 @@ public: } default: { - Log("Unimplemented E1000 device."); + KernelLog("Unimplemented E1000 device."); return; } } @@ -343,7 +347,7 @@ public: } default: { - Log("Unimplemented E1000 device."); + KernelLog("Unimplemented E1000 device."); return; } } @@ -351,7 +355,7 @@ public: }; E1000Device *Drivers[4] = {nullptr}; -dev_t AudioID[4] = {0}; +dev_t NetID[4] = {(dev_t)-1}; #define OIR(x) OIR_##x #define CREATE_OIR(x) \ @@ -362,20 +366,40 @@ CREATE_OIR(1); CREATE_OIR(2); CREATE_OIR(3); -int drvOpen(dev_t, dev_t, int, mode_t) { return 0; } -int drvClose(dev_t, dev_t) { return 0; } -size_t drvRead(dev_t, dev_t, uint8_t *, size_t, off_t) { return 0; } +int __fs_Open(struct Inode *, int, mode_t) { return 0; } +int __fs_Close(struct Inode *) { 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; EXTERNC int cxx_Panic() { @@ -402,10 +426,10 @@ EXTERNC int cxx_Probe() 0x10EA, /* I217-LM */ 0x153A, /* 82577LM */ PCI_END}; - Devices = FindPCIDevices(VendorIDs, DeviceIDs); + Devices = GetPCIDevices(VendorIDs, DeviceIDs); if (Devices == nullptr) { - Log("No E1000 device found."); + KernelLog("No E1000 device found."); return -ENODEV; } return 0; @@ -427,11 +451,8 @@ EXTERNC int cxx_Initialize() if (Drivers[Count]->IsInitialized()) { - dev_t ret = RegisterNetDevice(ddt_Network, - drvOpen, drvClose, - drvRead, drvWrite, - drvIoctl); - AudioID[Count] = ret; + dev_t ret = RegisterDevice(NETWORK_TYPE_ETHERNET, &NetOps); + NetID[Count] = ret; Drivers[Count]->ID = ret; /* FIXME: bad code */ @@ -460,7 +481,7 @@ EXTERNC int cxx_Initialize() if (Count == 0) { - Log("No valid E1000 device found."); + KernelLog("No valid E1000 device found."); return -EINVAL; } @@ -481,5 +502,11 @@ EXTERNC int cxx_Finalize() 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; } diff --git a/network/e1000/main.c b/network/e1000/main.c index 9f3a46e..066773f 100644 --- a/network/e1000/main.c +++ b/network/e1000/main.c @@ -27,5 +27,5 @@ int DriverProbe() { return cxx_Probe(); } DriverInfo("e1000", "Intel(R) PRO/1000 Network Driver", "EnderIce2", - "0.1", + 0, 0, 1, "GPLv3"); diff --git a/network/rtl8139/Makefile b/network/rtl8139/Makefile index 1a41216..59ddc9a 100644 --- a/network/rtl8139/Makefile +++ b/network/rtl8139/Makefile @@ -1,83 +1,22 @@ -# Config file +# Config files include ../../../Makefile.conf - -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 +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) $(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) -INCLUDE_DIR = ../../include -LIBS := ../../out/dcrt0.o -L../../out -ldriver - -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 +FILENAME = rtl8139.drv build: $(FILENAME) mv $(FILENAME) ../../out/$(FILENAME) $(FILENAME): $(OBJ) $(info Linking $@) - $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -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 $@ $< + $(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@ clean: rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/network/rtl8139/main.c b/network/rtl8139/main.c index 0e6e7da..3758edd 100644 --- a/network/rtl8139/main.c +++ b/network/rtl8139/main.c @@ -27,5 +27,5 @@ int DriverProbe() { return cxx_Probe(); } DriverInfo("rtl8139", "Realtek RTL8139 Network Driver", "EnderIce2", - "0.1", + 0, 0, 1, "GPLv3"); diff --git a/network/rtl8139/rtl8139.cpp b/network/rtl8139/rtl8139.cpp index 8f4e413..506d326 100644 --- a/network/rtl8139/rtl8139.cpp +++ b/network/rtl8139/rtl8139.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include "rtl8139.hpp" @@ -99,7 +99,11 @@ public: uint16_t dataSz = *(data + 1); data += 2; - ReportNetworkPacket(ID, data, dataSz); + // ReportNetworkPacket(ID, data, dataSz); + /* FIXME: Implement */ + KernelLog("FIXME: Received packet"); + (void)data; + (void)dataSz; /* Update CAPR */ #define RX_READ_PTR_MASK (~0x3) @@ -169,7 +173,7 @@ public: }; RTL8139Device *Drivers[4] = {nullptr}; -dev_t AudioID[4] = {0}; +dev_t NetID[4] = {(dev_t)-1}; #define OIR(x) OIR_##x #define CREATE_OIR(x) \ @@ -180,20 +184,40 @@ CREATE_OIR(1); CREATE_OIR(2); CREATE_OIR(3); -int drvOpen(dev_t, dev_t, int, mode_t) { return 0; } -int drvClose(dev_t, dev_t) { return 0; } -size_t drvRead(dev_t, dev_t, uint8_t *, size_t, off_t) { return 0; } +int __fs_Open(struct Inode *, int, mode_t) { return 0; } +int __fs_Close(struct Inode *) { 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; EXTERNC int cxx_Panic() { @@ -216,10 +240,10 @@ EXTERNC int cxx_Probe() PCI_END}; uint16_t DeviceIDs[] = {0x8139, /* RTL8139 */ PCI_END}; - Devices = FindPCIDevices(VendorIDs, DeviceIDs); + Devices = GetPCIDevices(VendorIDs, DeviceIDs); if (Devices == nullptr) { - Log("No RTL8139 device found."); + KernelLog("No RTL8139 device found."); return -ENODEV; } return 0; @@ -240,11 +264,8 @@ EXTERNC int cxx_Initialize() if (Drivers[Count]->IsInitialized()) { - dev_t ret = RegisterNetDevice(ddt_Network, - drvOpen, drvClose, - drvRead, drvWrite, - drvIoctl); - AudioID[Count] = ret; + dev_t ret = RegisterDevice(NETWORK_TYPE_ETHERNET, &NetOps); + NetID[Count] = ret; Drivers[Count]->ID = ret; /* FIXME: bad code */ @@ -273,7 +294,7 @@ EXTERNC int cxx_Initialize() if (Count == 0) { - Log("No valid RTL8139 device found."); + KernelLog("No valid RTL8139 device found."); return -EINVAL; } @@ -294,5 +315,11 @@ EXTERNC int cxx_Finalize() 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; } diff --git a/storage/ahci/Makefile b/storage/ahci/Makefile index fd47515..55a0760 100644 --- a/storage/ahci/Makefile +++ b/storage/ahci/Makefile @@ -1,83 +1,22 @@ -# Config file +# Config files include ../../../Makefile.conf - -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 +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) $(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) -INCLUDE_DIR = ../../include -LIBS := ../../out/dcrt0.o -L../../out -ldriver - -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 +FILENAME = ahci.drv build: $(FILENAME) mv $(FILENAME) ../../out/$(FILENAME) $(FILENAME): $(OBJ) $(info Linking $@) - $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -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 $@ $< + $(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@ clean: rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/storage/ahci/ahci.cpp b/storage/ahci/ahci.cpp index fc4776c..1409d53 100644 --- a/storage/ahci/ahci.cpp +++ b/storage/ahci/ahci.cpp @@ -16,7 +16,7 @@ */ #include -#include +#include #include #include #include @@ -634,9 +634,9 @@ public: Identify(); - Log("Port %d \"%x %x %x %x\" configured", PortNumber, - HBAPortPtr->Vendor[0], HBAPortPtr->Vendor[1], - HBAPortPtr->Vendor[2], HBAPortPtr->Vendor[3]); + KernelLog("Port %d \"%x %x %x %x\" configured", PortNumber, + HBAPortPtr->Vendor[0], HBAPortPtr->Vendor[1], + HBAPortPtr->Vendor[2], HBAPortPtr->Vendor[3]); } bool ReadWrite(uint64_t Sector, uint32_t SectorCount, uint8_t *Buffer, bool Write) @@ -644,7 +644,7 @@ public: if (this->AHCIPortType == PortType::SATAPI && Write == true) { - Log("SATAPI port does not support write."); + KernelLog("SATAPI port does not support write."); return false; } @@ -702,7 +702,7 @@ public: if (Spin == 1000000) { - Log("Port not responding."); + KernelLog("Port not responding."); return false; } @@ -715,8 +715,8 @@ public: { if (Spin > 100000000) { - Log("Port %d not responding. (%d)", - this->PortNumber, TryCount); + KernelLog("Port %d not responding. (%d)", + this->PortNumber, TryCount); Spin = 0; TryCount++; @@ -730,7 +730,7 @@ public: if (HBAPortPtr->InterruptStatus & HBA_PxIS_TFES) { - Log("Error reading/writing (%d).", Write); + KernelLog("Error reading/writing (%d).", Write); return false; } } @@ -766,12 +766,12 @@ public: if (HBAPortPtr->InterruptStatus & HBA_PxIS_TFES) { - Log("Error reading IDENTIFY command."); + KernelLog("Error reading IDENTIFY command."); return; } if (IdentifyData->Signature != 0xA5) - Log("Port %d has no validity signature.", PortNumber); + KernelLog("Port %d has no validity signature.", PortNumber); else { uint8_t *ptr = (uint8_t *)IdentifyData; @@ -780,11 +780,11 @@ public: sum += ptr[i]; if (sum != 0) { - Log("Port %d has invalid checksum.", PortNumber); + KernelLog("Port %d has invalid checksum.", PortNumber); return; } else - Log("Port %d has valid checksum.", PortNumber); + KernelLog("Port %d has valid checksum.", PortNumber); } char *Model = (char *)this->IdentifyData->ModelNumber; @@ -796,11 +796,11 @@ public: } ModelSwap[40] = 0; - Log("Port %d \"%s\" identified", PortNumber, - ModelSwap); - Log("Port %d is %s (%d rotation rate)", PortNumber, - IdentifyData->NominalMediaRotationRate == 1 ? "SSD" : "HDD", - IdentifyData->NominalMediaRotationRate); + KernelLog("Port %d \"%s\" identified", PortNumber, + ModelSwap); + KernelLog("Port %d is %s (%d rotation rate)", PortNumber, + IdentifyData->NominalMediaRotationRate == 1 ? "SSD" : "HDD", + IdentifyData->NominalMediaRotationRate); } }; @@ -839,26 +839,47 @@ PortType CheckPortType(HBAPort *Port) } } -size_t drvRead(dev_t, dev_t min, - uint8_t *Buffer, size_t Size, off_t Offset) +int __fs_Open(struct Inode *, int, mode_t) { return 0; } +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, - uint32_t(Size / 512), - Buffer, - false); + bool ok = Ports[Node->GetMinor()]->ReadWrite(Offset / 512, + uint32_t(Size / 512), + (uint8_t *)Buffer, + false); return ok ? Size : 0; } -size_t drvWrite(dev_t, dev_t min, - uint8_t *Buffer, size_t Size, off_t Offset) +ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset) { - bool ok = Ports[min]->ReadWrite(Offset / 512, - uint32_t(Size / 512), - Buffer, - true); + bool ok = Ports[Node->GetMinor()]->ReadWrite(Offset / 512, + uint32_t(Size / 512), + (uint8_t *)Buffer, + true); 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 *) { } @@ -880,10 +901,10 @@ EXTERNC int cxx_Probe() 0x2829, /* ICH8 */ 0x07E0, /* SATA AHCI (VMware) */ PCI_END}; - Devices = FindPCIDevices(VendorIDs, DeviceIDs); + Devices = GetPCIDevices(VendorIDs, DeviceIDs); if (Devices == nullptr) { - Log("No AHCI device found."); + KernelLog("No AHCI device found."); return -ENODEV; } return 0; @@ -905,31 +926,28 @@ EXTERNC int cxx_Initialize() HBAMemory *HBA = (HBAMemory *)(uintptr_t)GetBAR(5, ctx->Device); uint32_t PortsImplemented = HBA->PortsImplemented; - Log("AHCI ports implemented: %x", PortsImplemented); + KernelLog("AHCI ports implemented: %x", PortsImplemented); for (int i = 0; i < 32; i++) { if (PortCount > 64) { - Log("There are more than 64 AHCI ports implemented"); + KernelLog("There are more than 64 AHCI ports implemented"); break; } if (PortsImplemented & (1 << i)) { - Log("Port %d implemented", i); + KernelLog("Port %d implemented", i); PortType portType = CheckPortType(&HBA->Ports[i]); 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); - dev_t ret = RegisterBlockDevice(ddt_SATA, - nullptr, nullptr, - drvRead, drvWrite, - nullptr); + dev_t ret = RegisterDevice(BLOCK_TYPE_HDD, &BlockOps); if (ret != (dev_t)PortCount) { - KPrint("Failed to register block device %d", ret); - return -EBADSLT; + KernelPrint("Failed to register block device %d", ret); + return -EBADF; } PortCount++; @@ -939,8 +957,8 @@ EXTERNC int cxx_Initialize() { if (portType != PortType::None) { - KPrint("Unsupported drive type %s found at port %d", - PortTypeName[portType], i); + KernelPrint("Unsupported drive type %s found at port %d", + PortTypeName[portType], i); } } } @@ -949,7 +967,7 @@ EXTERNC int cxx_Initialize() ctx = (PCIArray *)ctx->Next; } - Log("Initializing AHCI ports"); + KernelLog("Initializing AHCI ports"); for (int i = 0; i < PortCount; i++) Ports[i]->Configure(); @@ -968,7 +986,7 @@ EXTERNC int cxx_Finalize() do { - UnregisterBlockDevice(PortCount, ddt_SATA); + UnregisterDevice(PortCount); PortCount--; } while (PortCount >= 0); diff --git a/storage/ahci/main.c b/storage/ahci/main.c index 8bac95a..ae44b03 100644 --- a/storage/ahci/main.c +++ b/storage/ahci/main.c @@ -27,5 +27,5 @@ int DriverProbe() { return cxx_Probe(); } DriverInfo("ahci", "Advanced Host Controller Interface Driver", "EnderIce2", - "0.1", + 0, 0, 1, "GPLv3"); diff --git a/storage/ata/Makefile b/storage/ata/Makefile index f712d0a..e4b48ea 100644 --- a/storage/ata/Makefile +++ b/storage/ata/Makefile @@ -1,83 +1,22 @@ -# Config file +# Config files include ../../../Makefile.conf - -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 +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) $(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) -INCLUDE_DIR = ../../include -LIBS := ../../out/dcrt0.o -L../../out -ldriver - -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 +FILENAME = ata.drv build: $(FILENAME) mv $(FILENAME) ../../out/$(FILENAME) $(FILENAME): $(OBJ) $(info Linking $@) - $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -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 $@ $< + $(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@ clean: rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/storage/ata/main.c b/storage/ata/main.c index 300dab1..b46ed73 100644 --- a/storage/ata/main.c +++ b/storage/ata/main.c @@ -72,5 +72,5 @@ int DriverProbe() DriverInfo("ata", "Advanced Technology Attachment Driver", "EnderIce2", - "0.1", + 0, 0, 1, "GPLv3");