mirror of
https://github.com/Fennix-Project/Drivers.git
synced 2025-07-10 22:59:25 +00:00
Fix driver implementation
This commit is contained in:
@ -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
|
||||
|
146
library/aip.c
146
library/aip.c
@ -1,146 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <aip.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <io.h>
|
||||
|
||||
extern void Log(const char *Format, ...);
|
||||
|
||||
void PIC_EOI(uint8_t IRQ)
|
||||
{
|
||||
if (IRQ >= 8)
|
||||
outb(PIC2_CMD, _PIC_EOI);
|
||||
outb(PIC1_CMD, _PIC_EOI);
|
||||
}
|
||||
|
||||
void IRQ_MASK(uint8_t IRQ)
|
||||
{
|
||||
uint16_t port;
|
||||
uint8_t value;
|
||||
|
||||
if (IRQ < 8)
|
||||
port = PIC1_DATA;
|
||||
else
|
||||
{
|
||||
port = PIC2_DATA;
|
||||
IRQ -= 8;
|
||||
}
|
||||
|
||||
value = inb(port) | (1 << IRQ);
|
||||
outb(port, value);
|
||||
}
|
||||
|
||||
void IRQ_UNMASK(uint8_t IRQ)
|
||||
{
|
||||
uint16_t port;
|
||||
uint8_t value;
|
||||
|
||||
if (IRQ < 8)
|
||||
port = PIC1_DATA;
|
||||
else
|
||||
{
|
||||
port = PIC2_DATA;
|
||||
IRQ -= 8;
|
||||
}
|
||||
|
||||
value = inb(port) & ~(1 << IRQ);
|
||||
outb(port, value);
|
||||
}
|
||||
|
||||
void PS2Wait(const bool Output)
|
||||
{
|
||||
int Timeout = 100000;
|
||||
PS2_STATUSES Status = {.Raw = inb(PS2_STATUS)};
|
||||
while (Timeout--)
|
||||
{
|
||||
if (!Output) /* FIXME: Reverse? */
|
||||
{
|
||||
if (Status.OutputBufferFull == 0)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Status.InputBufferFull == 0)
|
||||
return;
|
||||
}
|
||||
Status.Raw = inb(PS2_STATUS);
|
||||
}
|
||||
|
||||
Log("PS/2 controller timeout! (Status: %#x, %d)", Status, Output);
|
||||
}
|
||||
|
||||
void PS2WriteCommand(uint8_t Command)
|
||||
{
|
||||
WaitInput;
|
||||
outb(PS2_CMD, Command);
|
||||
}
|
||||
|
||||
void PS2WriteData(uint8_t Data)
|
||||
{
|
||||
WaitInput;
|
||||
outb(PS2_DATA, Data);
|
||||
}
|
||||
|
||||
uint8_t PS2ReadData()
|
||||
{
|
||||
WaitOutput;
|
||||
return inb(PS2_DATA);
|
||||
}
|
||||
|
||||
uint8_t PS2ReadStatus()
|
||||
{
|
||||
WaitOutput;
|
||||
return inb(PS2_STATUS);
|
||||
}
|
||||
|
||||
uint8_t PS2ReadAfterACK()
|
||||
{
|
||||
uint8_t ret = PS2ReadData();
|
||||
while (ret == PS2_ACK)
|
||||
{
|
||||
WaitOutput;
|
||||
ret = inb(PS2_DATA);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PS2ClearOutputBuffer()
|
||||
{
|
||||
PS2_STATUSES Status;
|
||||
int timeout = 0x500;
|
||||
while (timeout--)
|
||||
{
|
||||
Status.Raw = inb(PS2_STATUS);
|
||||
if (Status.OutputBufferFull == 0)
|
||||
return;
|
||||
inb(PS2_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
int PS2ACKTimeout()
|
||||
{
|
||||
int timeout = 0x500;
|
||||
while (timeout > 0)
|
||||
{
|
||||
if (PS2ReadData() == PS2_ACK)
|
||||
return 0;
|
||||
timeout--;
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <audio.h>
|
||||
|
||||
extern __driverAPI *API;
|
||||
|
||||
dev_t RegisterAudioDevice(DeviceDriverType Type, drvOpen_t Open, drvClose_t Close,
|
||||
drvRead_t Read, drvWrite_t Write, drvIoctl_t Ioctl)
|
||||
{
|
||||
return API->RegisterAudioDevice(API->MajorID, Type, Open, Close, Read, Write, Ioctl);
|
||||
}
|
||||
|
||||
int UnregisterAudioDevice(dev_t DeviceID, DeviceDriverType Type)
|
||||
{
|
||||
return API->UnregisterAudioDevice(API->MajorID, DeviceID, Type);
|
||||
}
|
182
library/base.c
182
library/base.c
@ -1,182 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <base.h>
|
||||
|
||||
#include <driver.h>
|
||||
#include <errno.h>
|
||||
|
||||
__driverAPI *API = NULL;
|
||||
|
||||
int RegisterInterruptHandler(uint8_t IRQ, void *Handler)
|
||||
{
|
||||
if (Handler == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
return API->RegisterInterruptHandler(API->MajorID,
|
||||
IRQ,
|
||||
Handler);
|
||||
}
|
||||
|
||||
int OverrideInterruptHandler(uint8_t IRQ, void *Handler)
|
||||
{
|
||||
if (Handler == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
return API->OverrideInterruptHandler(API->MajorID,
|
||||
IRQ,
|
||||
Handler);
|
||||
}
|
||||
|
||||
int UnregisterInterruptHandler(uint8_t IRQ, void *Handler)
|
||||
{
|
||||
if (Handler == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
return API->UnregisterInterruptHandler(API->MajorID,
|
||||
IRQ,
|
||||
Handler);
|
||||
}
|
||||
|
||||
int UnregisterAllInterruptHandlers(void *Handler)
|
||||
{
|
||||
if (Handler == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
return API->UnregisterAllInterruptHandlers(API->MajorID,
|
||||
Handler);
|
||||
}
|
||||
|
||||
void *AllocateMemory(size_t Pages)
|
||||
{
|
||||
if (Pages == 0)
|
||||
return NULL;
|
||||
|
||||
return API->RequestPages(API->MajorID,
|
||||
Pages);
|
||||
}
|
||||
|
||||
void FreeMemory(void *Pointer, size_t Pages)
|
||||
{
|
||||
if (Pointer == NULL || Pages == 0)
|
||||
return;
|
||||
|
||||
API->FreePages(API->MajorID,
|
||||
Pointer,
|
||||
Pages);
|
||||
}
|
||||
|
||||
void AppendMapFlag(void *Address, PageMapFlags Flag)
|
||||
{
|
||||
API->AppendMapFlag(API->MajorID,
|
||||
Address,
|
||||
Flag);
|
||||
}
|
||||
|
||||
void RemoveMapFlag(void *Address, PageMapFlags Flag)
|
||||
{
|
||||
API->RemoveMapFlag(API->MajorID,
|
||||
Address,
|
||||
Flag);
|
||||
}
|
||||
|
||||
void MapPages(void *PhysicalAddress, void *VirtualAddress, size_t Pages, uint32_t Flags)
|
||||
{
|
||||
API->MapPages(API->MajorID,
|
||||
PhysicalAddress,
|
||||
VirtualAddress,
|
||||
Pages,
|
||||
Flags);
|
||||
}
|
||||
|
||||
void UnmapPages(void *VirtualAddress, size_t Pages)
|
||||
{
|
||||
API->UnmapPages(API->MajorID,
|
||||
VirtualAddress,
|
||||
Pages);
|
||||
}
|
||||
|
||||
void KPrint(const char *Format, ...)
|
||||
{
|
||||
va_list Args;
|
||||
va_start(Args, Format);
|
||||
|
||||
API->KPrint(API->MajorID,
|
||||
Format,
|
||||
Args);
|
||||
|
||||
va_end(Args);
|
||||
}
|
||||
|
||||
void Log(const char *Format, ...)
|
||||
{
|
||||
va_list Args;
|
||||
va_start(Args, Format);
|
||||
|
||||
API->KernelLog(API->MajorID,
|
||||
Format,
|
||||
Args);
|
||||
|
||||
va_end(Args);
|
||||
}
|
||||
|
||||
CriticalState EnterCriticalSection()
|
||||
{
|
||||
CriticalState cs;
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
uintptr_t Flags;
|
||||
#if defined(__x86_64__)
|
||||
asmv("pushfq");
|
||||
asmv("popq %0"
|
||||
: "=r"(Flags));
|
||||
#else
|
||||
asmv("pushfl");
|
||||
asmv("popl %0"
|
||||
: "=r"(Flags));
|
||||
#endif
|
||||
cs = Flags & (1 << 9);
|
||||
asmv("cli");
|
||||
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
|
||||
uintptr_t Flags;
|
||||
asmv("mrs %0, cpsr"
|
||||
: "=r"(Flags));
|
||||
cs = Flags & (1 << 7);
|
||||
asmv("cpsid i");
|
||||
|
||||
#endif
|
||||
|
||||
return cs;
|
||||
}
|
||||
|
||||
void LeaveCriticalSection(CriticalState PreviousState)
|
||||
{
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
if (PreviousState)
|
||||
asmv("sti");
|
||||
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
|
||||
if (PreviousState)
|
||||
asmv("cpsie i");
|
||||
|
||||
#endif
|
||||
}
|
94
library/base.cpp
Normal file
94
library/base.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <base.h>
|
||||
|
||||
#include <driver.h>
|
||||
#include <errno.h>
|
||||
#include <fs.h>
|
||||
|
||||
extern "C" dev_t DriverID;
|
||||
|
||||
#define KernelFunction(Name) \
|
||||
extern "C" __attribute__((naked, used)) long \
|
||||
__##Name(dev_t, long, long, long, \
|
||||
long, long, long) { return 0; }
|
||||
|
||||
void *operator new(__SIZE_TYPE__) { return (void *)1; }
|
||||
void *operator new[](__SIZE_TYPE__) { return (void *)1; }
|
||||
void operator delete(void *) {}
|
||||
void operator delete[](void *) {}
|
||||
void operator delete(void *, __SIZE_TYPE__) {}
|
||||
void operator delete[](void *, __SIZE_TYPE__) {}
|
||||
|
||||
KernelFunction(KernelPrint);
|
||||
KernelFunction(KernelLog);
|
||||
|
||||
KernelFunction(RegisterInterruptHandler);
|
||||
KernelFunction(OverrideInterruptHandler);
|
||||
KernelFunction(UnregisterInterruptHandler);
|
||||
KernelFunction(UnregisterAllInterruptHandlers);
|
||||
|
||||
KernelFunction(AllocateMemory);
|
||||
KernelFunction(FreeMemory);
|
||||
KernelFunction(AppendMapFlag);
|
||||
KernelFunction(RemoveMapFlag);
|
||||
KernelFunction(MapPages);
|
||||
KernelFunction(UnmapPages);
|
||||
|
||||
KernelFunction(MemoryCopy);
|
||||
KernelFunction(MemorySet);
|
||||
KernelFunction(MemoryMove);
|
||||
KernelFunction(StringLength);
|
||||
KernelFunction(strstr);
|
||||
|
||||
KernelFunction(EnterCriticalSection);
|
||||
KernelFunction(LeaveCriticalSection);
|
||||
|
||||
KernelFunction(CreateKernelProcess);
|
||||
KernelFunction(CreateKernelThread);
|
||||
KernelFunction(GetCurrentProcess);
|
||||
KernelFunction(KillProcess);
|
||||
KernelFunction(KillThread);
|
||||
KernelFunction(Yield);
|
||||
KernelFunction(Sleep);
|
||||
|
||||
KernelFunction(RegisterFileSystem);
|
||||
KernelFunction(UnregisterFileSystem);
|
||||
|
||||
KernelFunction(PIC_EOI);
|
||||
KernelFunction(IRQ_MASK);
|
||||
KernelFunction(IRQ_UNMASK);
|
||||
KernelFunction(PS2Wait);
|
||||
KernelFunction(PS2WriteCommand);
|
||||
KernelFunction(PS2WriteData);
|
||||
KernelFunction(PS2ReadData);
|
||||
KernelFunction(PS2ReadStatus);
|
||||
KernelFunction(PS2ReadAfterACK);
|
||||
KernelFunction(PS2ClearOutputBuffer);
|
||||
KernelFunction(PS2ACKTimeout);
|
||||
|
||||
KernelFunction(RegisterDevice);
|
||||
KernelFunction(UnregisterDevice);
|
||||
|
||||
KernelFunction(ReportInputEvent);
|
||||
|
||||
KernelFunction(InitializePCI);
|
||||
KernelFunction(GetPCIDevices);
|
||||
KernelFunction(GetBAR);
|
||||
KernelFunction(iLine);
|
||||
KernelFunction(iPin);
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <block.h>
|
||||
|
||||
extern __driverAPI *API;
|
||||
|
||||
dev_t RegisterBlockDevice(DeviceDriverType Type, drvOpen_t Open, drvClose_t Close,
|
||||
drvRead_t Read, drvWrite_t Write, drvIoctl_t Ioctl)
|
||||
{
|
||||
return API->RegisterBlockDevice(API->MajorID, Type, Open, Close, Read, Write, Ioctl);
|
||||
}
|
||||
|
||||
int UnregisterBlockDevice(dev_t DeviceID, DeviceDriverType Type)
|
||||
{
|
||||
return API->UnregisterBlockDevice(API->MajorID, DeviceID, Type);
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <driver.h>
|
||||
#include <errno.h>
|
||||
|
||||
extern __driverAPI *API;
|
||||
|
||||
int DriverEntry();
|
||||
int DriverFinal();
|
||||
int DriverPanic();
|
||||
int DriverProbe();
|
||||
void __IdentifyDriver(
|
||||
dev_t ID,
|
||||
int (*GetDriverInfo)(dev_t, const char *, const char *,
|
||||
const char *, const char *, const char *));
|
||||
|
||||
typedef void (*CallPtr)(void);
|
||||
extern CallPtr __init_array_start[0], __init_array_end[0];
|
||||
extern CallPtr __fini_array_start[0], __fini_array_end[0];
|
||||
|
||||
int _entry()
|
||||
{
|
||||
for (CallPtr *func = __init_array_start; func != __init_array_end; func++)
|
||||
(*func)();
|
||||
|
||||
return DriverEntry();
|
||||
}
|
||||
|
||||
int _final()
|
||||
{
|
||||
int err = DriverFinal();
|
||||
|
||||
for (CallPtr *func = __fini_array_start; func != __fini_array_end; func++)
|
||||
(*func)();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#define API_MajorRequiredVersion 0
|
||||
#define API_MinorRequiredVersion 0
|
||||
#define API_PatchRequiredVersion 0
|
||||
|
||||
int _start(__driverAPI *__API)
|
||||
{
|
||||
if (unlikely(__API == NULL))
|
||||
return -EINVAL;
|
||||
|
||||
if (unlikely(__API->APIVersion.Major != API_MajorRequiredVersion ||
|
||||
__API->APIVersion.Minor != API_MinorRequiredVersion ||
|
||||
__API->APIVersion.Patch != API_PatchRequiredVersion))
|
||||
return -EPROTO;
|
||||
|
||||
if (unlikely(__API->RegisterFunction == NULL))
|
||||
return -ENOSYS;
|
||||
|
||||
if (unlikely(DriverEntry == NULL ||
|
||||
DriverFinal == NULL ||
|
||||
DriverPanic == NULL ||
|
||||
DriverProbe == NULL ||
|
||||
__IdentifyDriver == NULL))
|
||||
return -EFAULT;
|
||||
|
||||
API = __API;
|
||||
__API->RegisterFunction(__API->MajorID, _entry, _drf_Entry);
|
||||
__API->RegisterFunction(__API->MajorID, _final, _drf_Final);
|
||||
__API->RegisterFunction(__API->MajorID, DriverPanic, _drf_Panic);
|
||||
__API->RegisterFunction(__API->MajorID, DriverProbe, _drf_Probe);
|
||||
__IdentifyDriver(__API->MajorID, __API->GetDriverInfo);
|
||||
return 0;
|
||||
}
|
144
library/crt/crt0.cpp
Normal file
144
library/crt/crt0.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <driver.h>
|
||||
#include <errno.h>
|
||||
|
||||
dev_t DriverID = -1;
|
||||
|
||||
extern "C" int DriverEntry();
|
||||
extern "C" int DriverFinal();
|
||||
extern "C" int DriverPanic();
|
||||
extern "C" int DriverProbe();
|
||||
|
||||
typedef void (*CallPtr)(void);
|
||||
extern "C" CallPtr __init_array_start[0], __init_array_end[0];
|
||||
extern "C" CallPtr __fini_array_start[0], __fini_array_end[0];
|
||||
|
||||
extern "C" int _start(dev_t id)
|
||||
{
|
||||
DriverID = id;
|
||||
|
||||
for (CallPtr *func = __init_array_start; func != __init_array_end; func++)
|
||||
(*func)();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int _final()
|
||||
{
|
||||
int err = DriverFinal();
|
||||
|
||||
for (CallPtr *func = __fini_array_start; func != __fini_array_end; func++)
|
||||
(*func)();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------- */
|
||||
|
||||
#define KCALL extern "C" __attribute__((used))
|
||||
|
||||
#define KernelFunction(Name) \
|
||||
KCALL long __##Name(dev_t id, \
|
||||
long arg0 = 0, long arg1 = 0, long arg2 = 0, \
|
||||
long arg3 = 0, long arg4 = 0, long arg5 = 0);
|
||||
|
||||
#define DefineFunction(ReturnType, Name, ...) \
|
||||
KernelFunction(Name); \
|
||||
KCALL ReturnType Name(__VA_ARGS__)
|
||||
|
||||
#define DefineWrapper(Name) \
|
||||
KernelFunction(Name); \
|
||||
KCALL long Name(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5) \
|
||||
{ \
|
||||
return __##Name(DriverID, arg0, arg1, arg2, arg3, arg4, arg5); \
|
||||
}
|
||||
|
||||
DefineFunction(void, KernelPrint, const char *format, ...)
|
||||
{
|
||||
__builtin_va_list args;
|
||||
__builtin_va_start(args, format);
|
||||
__KernelPrint(DriverID, (long)format, (long)args);
|
||||
__builtin_va_end(args);
|
||||
}
|
||||
|
||||
DefineFunction(void, KernelLog, const char *format, ...)
|
||||
{
|
||||
__builtin_va_list args;
|
||||
__builtin_va_start(args, format);
|
||||
__KernelLog(DriverID, (long)format, (long)args);
|
||||
__builtin_va_end(args);
|
||||
}
|
||||
|
||||
DefineWrapper(RegisterInterruptHandler);
|
||||
DefineWrapper(OverrideInterruptHandler);
|
||||
DefineWrapper(UnregisterInterruptHandler);
|
||||
DefineWrapper(UnregisterAllInterruptHandlers);
|
||||
|
||||
DefineWrapper(AllocateMemory);
|
||||
DefineWrapper(FreeMemory);
|
||||
DefineWrapper(AppendMapFlag);
|
||||
DefineWrapper(RemoveMapFlag);
|
||||
DefineWrapper(MapPages);
|
||||
DefineWrapper(UnmapPages);
|
||||
|
||||
DefineWrapper(MemoryCopy);
|
||||
DefineWrapper(MemorySet);
|
||||
DefineWrapper(MemoryMove);
|
||||
DefineWrapper(StringLength);
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch"
|
||||
DefineWrapper(strstr);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
DefineWrapper(EnterCriticalSection);
|
||||
DefineWrapper(LeaveCriticalSection);
|
||||
|
||||
DefineWrapper(CreateKernelProcess);
|
||||
DefineWrapper(CreateKernelThread);
|
||||
DefineWrapper(GetCurrentProcess);
|
||||
DefineWrapper(KillProcess);
|
||||
DefineWrapper(KillThread);
|
||||
DefineWrapper(Yield);
|
||||
DefineWrapper(Sleep);
|
||||
|
||||
DefineWrapper(RegisterFileSystem);
|
||||
DefineWrapper(UnregisterFileSystem);
|
||||
|
||||
DefineWrapper(PIC_EOI);
|
||||
DefineWrapper(IRQ_MASK);
|
||||
DefineWrapper(IRQ_UNMASK);
|
||||
DefineWrapper(PS2Wait);
|
||||
DefineWrapper(PS2WriteCommand);
|
||||
DefineWrapper(PS2WriteData);
|
||||
DefineWrapper(PS2ReadData);
|
||||
DefineWrapper(PS2ReadStatus);
|
||||
DefineWrapper(PS2ReadAfterACK);
|
||||
DefineWrapper(PS2ClearOutputBuffer);
|
||||
DefineWrapper(PS2ACKTimeout);
|
||||
|
||||
DefineWrapper(RegisterDevice);
|
||||
DefineWrapper(UnregisterDevice);
|
||||
|
||||
DefineWrapper(ReportInputEvent);
|
||||
|
||||
DefineWrapper(InitializePCI);
|
||||
DefineWrapper(GetPCIDevices);
|
||||
DefineWrapper(GetBAR);
|
||||
DefineWrapper(iLine);
|
||||
DefineWrapper(iPin);
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <input.h>
|
||||
|
||||
extern __driverAPI *API;
|
||||
|
||||
dev_t RegisterInputDevice(DeviceDriverType Type)
|
||||
{
|
||||
return API->RegisterInputDevice(API->MajorID, Type);
|
||||
}
|
||||
|
||||
int UnregisterInputDevice(dev_t DeviceID, DeviceDriverType Type)
|
||||
{
|
||||
return API->UnregisterInputDevice(API->MajorID, DeviceID, Type);
|
||||
}
|
||||
|
||||
int ReportKeyboardEvent(dev_t DeviceID, KeyScanCodes ScanCode, uint8_t Pressed)
|
||||
{
|
||||
if (Pressed)
|
||||
ScanCode |= KEY_PRESSED;
|
||||
return API->ReportKeyboardEvent(API->MajorID, DeviceID, ScanCode);
|
||||
}
|
||||
|
||||
int ReportRelativeMouseEvent(dev_t DeviceID, MouseReport Report)
|
||||
{
|
||||
__MouseButtons mb = {
|
||||
.LeftButton = Report.LeftButton,
|
||||
.RightButton = Report.RightButton,
|
||||
.MiddleButton = Report.MiddleButton,
|
||||
.Button4 = Report.Button4,
|
||||
.Button5 = Report.Button5,
|
||||
};
|
||||
return API->ReportRelativeMouseEvent(API->MajorID, DeviceID, mb, Report.X, Report.Y, Report.Z);
|
||||
}
|
||||
|
||||
int ReportAbsoluteMouseEvent(dev_t DeviceID, MouseReport Report, uintptr_t X, uintptr_t Y)
|
||||
{
|
||||
__MouseButtons mb = {
|
||||
.LeftButton = Report.LeftButton,
|
||||
.RightButton = Report.RightButton,
|
||||
.MiddleButton = Report.MiddleButton,
|
||||
.Button4 = Report.Button4,
|
||||
.Button5 = Report.Button5,
|
||||
};
|
||||
return API->ReportAbsoluteMouseEvent(API->MajorID, DeviceID, mb, X, Y, Report.Z);
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <net.h>
|
||||
|
||||
extern __driverAPI *API;
|
||||
|
||||
dev_t RegisterNetDevice(DeviceDriverType Type, drvOpen_t Open, drvClose_t Close,
|
||||
drvRead_t Read, drvWrite_t Write, drvIoctl_t Ioctl)
|
||||
{
|
||||
return API->RegisterNetDevice(API->MajorID, Type, Open, Close, Read, Write, Ioctl);
|
||||
}
|
||||
|
||||
int UnregisterNetDevice(dev_t DeviceID, DeviceDriverType Type)
|
||||
{
|
||||
return API->UnregisterNetDevice(API->MajorID, DeviceID, Type);
|
||||
}
|
||||
|
||||
int ReportNetworkPacket(dev_t DeviceID, void *Buffer, size_t Size)
|
||||
{
|
||||
return API->ReportNetworkPacket(API->MajorID, DeviceID, Buffer, Size);
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <pci.h>
|
||||
|
||||
#include <driver.h>
|
||||
|
||||
extern __driverAPI *API;
|
||||
|
||||
static_assert(sizeof(PCIArray) == sizeof(__PCIArray),
|
||||
"PCIArray size mismatch");
|
||||
|
||||
PCIArray *FindPCIDevices(uint16_t Vendors[], uint16_t Devices[])
|
||||
{
|
||||
return (PCIArray *)API->GetPCIDevices(API->MajorID,
|
||||
Vendors,
|
||||
Devices);
|
||||
}
|
||||
|
||||
void InitializePCI(PCIDevice *Device)
|
||||
{
|
||||
API->InitializePCI(API->MajorID,
|
||||
(void *)Device->Header);
|
||||
}
|
||||
|
||||
uint32_t GetBAR(uint8_t Index, PCIDevice *Device)
|
||||
{
|
||||
return API->GetBAR(API->MajorID,
|
||||
Index,
|
||||
(void *)Device->Header);
|
||||
}
|
||||
|
||||
uint8_t iLine(PCIDevice *Device)
|
||||
{
|
||||
PCIHeader0 *Header = (PCIHeader0 *)Device->Header;
|
||||
return Header->InterruptLine;
|
||||
}
|
||||
|
||||
uint8_t iPin(PCIDevice *Device)
|
||||
{
|
||||
PCIHeader0 *Header = (PCIHeader0 *)Device->Header;
|
||||
return Header->InterruptPin;
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <base.h>
|
||||
#include <driver.h>
|
||||
|
||||
#undef memcpy
|
||||
#undef memset
|
||||
#undef memmove
|
||||
#undef strlen
|
||||
|
||||
extern __driverAPI *API;
|
||||
|
||||
void *MemoryCopy(void *Destination, const void *Source, size_t Length)
|
||||
{
|
||||
return API->memcpy(API->MajorID, Destination, Source, Length);
|
||||
}
|
||||
|
||||
void *MemorySet(void *Destination, int Value, size_t Length)
|
||||
{
|
||||
return API->memset(API->MajorID, Destination, Value, Length);
|
||||
}
|
||||
|
||||
void *MemoryMove(void *Destination, const void *Source, size_t Length)
|
||||
{
|
||||
return API->memmove(API->MajorID, Destination, Source, Length);
|
||||
}
|
||||
|
||||
size_t StringLength(const char String[])
|
||||
{
|
||||
return API->strlen(API->MajorID, String);
|
||||
}
|
||||
|
||||
char *strstr(const char *Haystack, const char *Needle)
|
||||
{
|
||||
return API->strstr(API->MajorID, Haystack, Needle);
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <base.h>
|
||||
#include <driver.h>
|
||||
|
||||
extern __driverAPI *API;
|
||||
|
||||
/**
|
||||
* TODO: memory allocator
|
||||
* we can't really call kernel's malloc because the
|
||||
* kernel keep track of memory usage for each driver
|
||||
*
|
||||
* maybe implement the allocator in vma?
|
||||
*/
|
||||
|
||||
void *__new_alloc_page(std::size_t Size)
|
||||
{
|
||||
/* Do not allow allocations larger than 4 KiB */
|
||||
if (Size > PAGE_SIZE)
|
||||
asmv("ud2");
|
||||
|
||||
return API->RequestPages(API->MajorID, 1);
|
||||
}
|
||||
|
||||
void __delete_alloc_page(void *Pointer)
|
||||
{
|
||||
API->FreePages(API->MajorID, Pointer, 1);
|
||||
}
|
||||
|
||||
void *operator new(std::size_t Size)
|
||||
{
|
||||
return __new_alloc_page(Size);
|
||||
}
|
||||
|
||||
void *operator new[](std::size_t Size)
|
||||
{
|
||||
return __new_alloc_page(Size);
|
||||
}
|
||||
|
||||
void operator delete(void *Pointer)
|
||||
{
|
||||
__delete_alloc_page(Pointer);
|
||||
}
|
||||
|
||||
void operator delete[](void *Pointer)
|
||||
{
|
||||
__delete_alloc_page(Pointer);
|
||||
}
|
||||
|
||||
void operator delete(void *Pointer, std::size_t)
|
||||
{
|
||||
__delete_alloc_page(Pointer);
|
||||
}
|
||||
|
||||
void operator delete[](void *Pointer, std::size_t)
|
||||
{
|
||||
__delete_alloc_page(Pointer);
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <driver.h>
|
||||
#include <base.h>
|
||||
|
||||
extern __driverAPI *API;
|
||||
|
||||
pid_t CreateKernelProcess(const char *Name)
|
||||
{
|
||||
return API->CreateKernelProcess(API->MajorID,
|
||||
Name);
|
||||
}
|
||||
|
||||
pid_t CreateKernelThread(pid_t pId, const char *Name, void *EntryPoint, void *Argument)
|
||||
{
|
||||
return API->CreateKernelThread(API->MajorID,
|
||||
pId,
|
||||
Name,
|
||||
EntryPoint,
|
||||
Argument);
|
||||
}
|
||||
|
||||
pid_t GetCurrentProcess()
|
||||
{
|
||||
return API->GetCurrentProcess(API->MajorID);
|
||||
}
|
||||
|
||||
int KillProcess(pid_t pId, int ExitCode)
|
||||
{
|
||||
return API->KillProcess(API->MajorID,
|
||||
pId, ExitCode);
|
||||
}
|
||||
|
||||
int KillThread(pid_t tId, pid_t pId, int ExitCode)
|
||||
{
|
||||
return API->KillThread(API->MajorID,
|
||||
tId, pId, ExitCode);
|
||||
}
|
||||
|
||||
void Yield()
|
||||
{
|
||||
API->Yield(API->MajorID);
|
||||
}
|
||||
|
||||
void Sleep(uint64_t Milliseconds)
|
||||
{
|
||||
API->Sleep(API->MajorID,
|
||||
Milliseconds);
|
||||
}
|
114
library/vm.c
114
library/vm.c
@ -1,114 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <vm.h>
|
||||
|
||||
int __strcmp(const char *l, const char *r)
|
||||
{
|
||||
for (; *l == *r && *l; l++, r++)
|
||||
;
|
||||
|
||||
return *(unsigned char *)l - *(unsigned char *)r;
|
||||
}
|
||||
|
||||
void __cpuid(uint32_t Function,
|
||||
uint32_t *eax, uint32_t *ebx,
|
||||
uint32_t *ecx, uint32_t *edx)
|
||||
{
|
||||
asmv("cpuid"
|
||||
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
||||
: "a"(Function));
|
||||
}
|
||||
|
||||
bool __CheckHypervisorBit()
|
||||
{
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
__cpuid(0x1, &eax, &ebx, &ecx, &edx);
|
||||
if (!(ecx & (1 << 31)))
|
||||
return false; /* Hypervisor not detected */
|
||||
return true;
|
||||
}
|
||||
|
||||
bool __VMwareBackdoorHypervisors()
|
||||
{
|
||||
const char hv[13] = {0};
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
__cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
*(uint32_t *)hv = ebx;
|
||||
*(uint32_t *)(hv + 4) = ecx;
|
||||
*(uint32_t *)(hv + 8) = edx;
|
||||
|
||||
if (__strcmp(hv, "VMwareVMware") != 0 &&
|
||||
__strcmp(hv, "KVMKVMKVM") != 0 &&
|
||||
__strcmp(hv, "TCGTCGTCGTCG") != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsVMwareBackdoorAvailable()
|
||||
{
|
||||
if (!__CheckHypervisorBit())
|
||||
return false;
|
||||
|
||||
if (!__VMwareBackdoorHypervisors())
|
||||
return false;
|
||||
|
||||
struct
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t ax;
|
||||
uint32_t magic;
|
||||
};
|
||||
union
|
||||
{
|
||||
uint32_t bx;
|
||||
size_t size;
|
||||
};
|
||||
union
|
||||
{
|
||||
uint32_t cx;
|
||||
uint16_t command;
|
||||
};
|
||||
union
|
||||
{
|
||||
uint32_t dx;
|
||||
uint16_t port;
|
||||
};
|
||||
uint32_t si;
|
||||
uint32_t di;
|
||||
} cmd;
|
||||
|
||||
cmd.si = cmd.di = 0;
|
||||
cmd.bx = ~0x564D5868;
|
||||
cmd.command = 0xA;
|
||||
cmd.magic = 0x564D5868;
|
||||
cmd.port = 0x5658;
|
||||
|
||||
asmv("in %%dx, %0"
|
||||
: "+a"(cmd.ax), "+b"(cmd.bx),
|
||||
"+c"(cmd.cx), "+d"(cmd.dx),
|
||||
"+S"(cmd.si), "+D"(cmd.di));
|
||||
|
||||
if (cmd.bx != 0x564D5868 ||
|
||||
cmd.ax == 0xFFFFFFFF)
|
||||
return false;
|
||||
return true;
|
||||
}
|
Reference in New Issue
Block a user