summaryrefslogtreecommitdiffhomepage
path: root/dev/ddk
diff options
context:
space:
mode:
Diffstat (limited to 'dev/ddk')
-rw-r--r--dev/ddk/DispatchKernelCall.S36
-rw-r--r--dev/ddk/KernelAlloc.c36
-rw-r--r--dev/ddk/KernelCall.c60
-rw-r--r--dev/ddk/KernelCxxRt.cxx29
-rw-r--r--dev/ddk/KernelDev.c29
-rw-r--r--dev/ddk/KernelDev.h32
-rw-r--r--dev/ddk/KernelPrint.c37
-rw-r--r--dev/ddk/KernelPrint.h18
-rw-r--r--dev/ddk/KernelStd.h105
-rw-r--r--dev/ddk/KernelString.c39
-rw-r--r--dev/ddk/KernelString.h17
-rw-r--r--dev/ddk/KernelVersion.c25
-rw-r--r--dev/ddk/ReadMe.md9
-rw-r--r--dev/ddk/ddk.json24
-rw-r--r--dev/ddk/source_deploy.xml7
-rw-r--r--dev/ddk/x86_64.make14
16 files changed, 517 insertions, 0 deletions
diff --git a/dev/ddk/DispatchKernelCall.S b/dev/ddk/DispatchKernelCall.S
new file mode 100644
index 00000000..3a9a57b5
--- /dev/null
+++ b/dev/ddk/DispatchKernelCall.S
@@ -0,0 +1,36 @@
+/**
+ lang: asm
+ compiler: gnu
+ */
+
+.globl __KernelCallDispatch
+
+.text
+
+/* Really simple function, takes our va-list,
+ and brings it to the trap handler in the Kernel. */
+
+#ifdef __DDK_AMD64__
+
+/* args rcx, rdx, r8, r9 */
+__KernelCallDispatch:
+ int $0x33
+ ret
+
+#elif defined(__DDK_POWER64__)
+
+/* args r8, r9, r10, r11 */
+__KernelCallDispatch:
+ /* There is no specific interrupt request id for a system call in POWER. */
+ sc
+ blr
+
+#elif defined(__DDK_ARM64__)
+
+/* args x0, x8, x9, x10, x11 is kept to tell that this is a Kernel call */
+__KernelCallDispatch:
+ /* There is no specific interrupt request id for a system call in ARM64 as well. */
+ mov x9, #0x33
+ svc #0
+
+#endif
diff --git a/dev/ddk/KernelAlloc.c b/dev/ddk/KernelAlloc.c
new file mode 100644
index 00000000..af99f23b
--- /dev/null
+++ b/dev/ddk/KernelAlloc.c
@@ -0,0 +1,36 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ Purpose: DDK allocator.
+
+------------------------------------------- */
+
+#include <ddk/KernelStd.h>
+
+/**
+ \brief Allocates a new heap on the Kernel's side.
+ \param sz the size of the heap block.
+ \return the newly allocated pointer.
+*/
+DK_EXTERN void* KernelAlloc(size_t sz)
+{
+ if (!sz)
+ ++sz;
+
+ void* ptr = KernelCall("MmNewKeHeap", 1, &sz, sizeof(size_t));
+
+ return ptr;
+}
+
+/**
+ \brief Frees a pointer from the heap.
+ \param ptr the pointer to free.
+*/
+DK_EXTERN void KernelFree(void* ptr)
+{
+ if (!ptr)
+ return;
+
+ KernelCall("MmDeleteKeHeap", 1, ptr, 0);
+}
diff --git a/dev/ddk/KernelCall.c b/dev/ddk/KernelCall.c
new file mode 100644
index 00000000..ccb401af
--- /dev/null
+++ b/dev/ddk/KernelCall.c
@@ -0,0 +1,60 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ Purpose: DDK Kernel call.
+
+------------------------------------------- */
+
+#include <ddk/KernelStd.h>
+#include <stdarg.h>
+
+/// @brief this is an internal call, do not use it.
+DK_EXTERN ATTRIBUTE(naked) void* __KernelCallDispatch(const char* name, int32_t cnt, void* data, size_t sz);
+
+/// @brief Interupt Kernel
+/// @param KernelRpcName RPC name
+/// @param cnt number of elements in **data** pointer.
+/// @param data data pointer.
+/// @param sz The size of the whole data pointer.
+/// @retval void* Kernel call was successful.
+/// @retval nil Kernel call failed, call KernelLastError(void)
+DK_EXTERN void* KernelCall(const char* name, int32_t cnt, void* data, size_t sz)
+{
+ if (!name || *name == 0 || cnt == 0)
+ return nil;
+
+ return __KernelCallDispatch(name, cnt, data, sz);
+}
+
+/// @brief Add system call.
+/// @param slot system call slot
+/// @param slotFn, syscall slot.
+DK_EXTERN void KernelAddSyscall(const int slot, void (*slotFn)(void* a0))
+{
+ KernelCall("IntAddSyscall", slot, slotFn, 1);
+}
+
+/// @brief Get a Kernel property.
+/// @param slot property id (always 0)
+/// @param name the object's name.
+/// @return Object manifest.
+DK_EXTERN struct DDK_OBJECT_MANIFEST* KernelGetObject(const int slot, const char* name)
+{
+ struct DDK_OBJECT_MANIFEST* manifest = (struct DDK_OBJECT_MANIFEST*)KernelCall("RtlGetObject", slot, (void*)name, 1);
+
+ if (!manifest)
+ return nil;
+
+ return manifest;
+}
+
+/// @brief Set a Kernel property.
+/// @param slot property id (always 0)
+/// @param name the object's name.
+/// @param ddk_pr pointer to a object's DDK_OBJECT_MANIFEST.
+/// @return property's object.
+DK_EXTERN void* KernelSetObject(const int slot, const struct DDK_OBJECT_MANIFEST* ddk_pr)
+{
+ return KernelCall("RtlSetObject", slot, (void*)ddk_pr, 1);
+}
diff --git a/dev/ddk/KernelCxxRt.cxx b/dev/ddk/KernelCxxRt.cxx
new file mode 100644
index 00000000..947e2de7
--- /dev/null
+++ b/dev/ddk/KernelCxxRt.cxx
@@ -0,0 +1,29 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ Purpose: DDK C++ runtime.
+
+------------------------------------------- */
+
+#include <ddk/KernelStd.h>
+
+void* operator new(size_t sz)
+{
+ return KernelAlloc(sz);
+}
+
+void operator delete(void* ptr)
+{
+ KernelFree(ptr);
+}
+
+void* operator new[](size_t sz)
+{
+ return KernelAlloc(sz);
+}
+
+void operator delete[](void* ptr)
+{
+ KernelFree(ptr);
+}
diff --git a/dev/ddk/KernelDev.c b/dev/ddk/KernelDev.c
new file mode 100644
index 00000000..3cf7ed48
--- /dev/null
+++ b/dev/ddk/KernelDev.c
@@ -0,0 +1,29 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ Purpose: DDK Text I/O.
+
+------------------------------------------- */
+
+#include <ddk/KernelDev.h>
+#include <ddk/KernelString.h>
+
+/// @brief Open a new binary device from path.
+DK_EXTERN KERNEL_DEVICE_PTR KernelOpenDevice(const char* devicePath)
+{
+ if (!devicePath)
+ return nil;
+
+ return KernelCall("ZkOpenDevice", 1, (void*)devicePath, KernelStringLength(devicePath));
+}
+
+/// @brief Close any device.
+/// @param device valid device.
+DK_EXTERN void KernelCloseDevice(KERNEL_DEVICE_PTR device)
+{
+ if (!device)
+ return;
+
+ KernelCall("ZkCloseDevice", 1, device, sizeof(KERNEL_DEVICE));
+}
diff --git a/dev/ddk/KernelDev.h b/dev/ddk/KernelDev.h
new file mode 100644
index 00000000..b7dce834
--- /dev/null
+++ b/dev/ddk/KernelDev.h
@@ -0,0 +1,32 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ Purpose: DDK Devices.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <ddk/KernelStd.h>
+
+struct _KERNEL_DEVICE;
+
+/// @brief Kernel Device driver.
+typedef struct _KERNEL_DEVICE DK_FINAL
+{
+ char d_name[255]; // the device name. Could be /./DEVICE_NAME/
+ void* (*d_read)(void* arg, int len); // read from device.
+ void (*d_write)(void* arg, int len);
+ void (*d_wait)(void); // write to device.
+ struct _KERNEL_DEVICE* (*d_open)(const char* path); // open device.
+ void (*d_close)(struct _KERNEL_DEVICE* dev); // close device.
+} KERNEL_DEVICE, *KERNEL_DEVICE_PTR;
+
+/// @brief Open a new device from path.
+/// @param devicePath the device's path.
+DK_EXTERN KERNEL_DEVICE_PTR KernelOpenDevice(const char* devicePath);
+
+/// @brief Close any device.
+/// @param device valid device.
+DK_EXTERN void KernelCloseDevice(KERNEL_DEVICE_PTR device);
diff --git a/dev/ddk/KernelPrint.c b/dev/ddk/KernelPrint.c
new file mode 100644
index 00000000..7f8c8604
--- /dev/null
+++ b/dev/ddk/KernelPrint.c
@@ -0,0 +1,37 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ Purpose: DDK Text I/O.
+
+------------------------------------------- */
+
+#include <ddk/KernelPrint.h>
+
+DK_EXTERN void KernelPrintChar(const char ch)
+{
+ char assembled[2] = {0};
+ assembled[0] = ch;
+ assembled[1] = 0;
+
+ KernelCall("SrWriteCharacter", 1, assembled, 1);
+}
+
+/// @brief print string to UART.
+/// @param message UART to transmit.
+DK_EXTERN void KernelPrintStr(const char* message)
+{
+ if (!message)
+ return;
+ if (*message == 0)
+ return;
+
+ size_t index = 0;
+ size_t len = KernelStringLength(message);
+
+ while (index < len)
+ {
+ KernelPrintChar(message[index]);
+ ++index;
+ }
+}
diff --git a/dev/ddk/KernelPrint.h b/dev/ddk/KernelPrint.h
new file mode 100644
index 00000000..6ab6118e
--- /dev/null
+++ b/dev/ddk/KernelPrint.h
@@ -0,0 +1,18 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ Purpose: DDK Text I/O.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <ddk/KernelString.h>
+
+/// @brief print character into UART.
+DK_EXTERN void KernelPrintChar(const char ch);
+
+/// @brief print string to UART.
+/// @param message string to transmit to UART.
+DK_EXTERN void KernelPrintStr(const char* message);
diff --git a/dev/ddk/KernelStd.h b/dev/ddk/KernelStd.h
new file mode 100644
index 00000000..89fe786d
--- /dev/null
+++ b/dev/ddk/KernelStd.h
@@ -0,0 +1,105 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ FILE: KernelStd.h
+ PURPOSE: DDK Driver model base header.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+
+#if defined(__cplusplus)
+#define DK_EXTERN extern "C" __declspec(dllexport)
+#define nil nullptr
+#undef NULL
+#define NULL 0
+#define DK_FINAL final
+#else
+#define DK_EXTERN extern __declspec(dllexport)
+#define nil ((void*)0)
+#undef NULL
+#define NULL ((void*)0)
+#define DK_FINAL
+#endif // defined(__cplusplus)
+
+#ifndef __DDK__
+#undef DK_EXTERN
+#if defined(__cplusplus)
+#define DK_EXTERN extern "C" __declspec(dllimport)
+#else
+#define DK_EXTERN __declspec(dllimport)
+#endif
+#endif
+
+#define ATTRIBUTE(X) __attribute__((X))
+
+#ifndef __NEWOSKRNL__
+#error !!! including header in low exception/ring-3 mode !!!
+#endif // __NEWOSKRNL__
+
+struct DDK_STATUS_STRUCT;
+struct DDK_OBJECT_MANIFEST;
+
+struct DDK_OBJECT_MANIFEST DK_FINAL
+{
+ char* p_name;
+ int32_t p_kind;
+ void* p_object;
+};
+
+/// \brief DDK status structure (__at_enable, __at_disable...)
+struct DDK_STATUS_STRUCT DK_FINAL
+{
+ int32_t s_action_id;
+ int32_t s_issuer_id;
+ int32_t s_group_id;
+ void* s_object;
+};
+
+/// @brief Call Kernel (interrupt 0x33)
+/// @param KernelRpcName
+/// @param cnt number of elements in **dat**
+/// @param dat data ptr
+/// @param sz sz of whole data ptr.
+/// @return result of call
+DK_EXTERN void* KernelCall(const char* name, int32_t cnt, void* dat, size_t sz);
+
+/// @brief add system call.
+/// @param slot system call slot
+/// @param slotFn, syscall slot.
+DK_EXTERN void KernelAddSyscall(const int32_t slot, void (*slotFn)(void* a0));
+
+/// @brief allocate heap ptr.
+/// @param sz size of ptr.
+/// @return the pointer allocated or **nil**.
+DK_EXTERN void* KernelAlloc(size_t sz);
+
+/// @brief free heap ptr.
+/// @param pointer to free
+DK_EXTERN void KernelFree(void*);
+
+/// @brief Get a Kernel property.
+/// @param slot property id (always 0)
+/// @param name the property's name.
+/// @return property's object.
+DK_EXTERN struct DDK_OBJECT_MANIFEST* KernelGetObject(const int slot, const char* name);
+
+/// @brief Set a Kernel property.
+/// @param slot property id (always 0)
+/// @param name the property's name.
+/// @param ddk_pr pointer to a property's DDK_OBJECT_MANIFEST.
+/// @return property's object.
+DK_EXTERN void* KernelSetObject(const int32_t slot, const struct DDK_OBJECT_MANIFEST* ddk_pr);
+
+/// @brief The highest API version of the DDK.
+DK_EXTERN int32_t c_api_version_highest;
+
+/// @brief The lowest API version of the DDK.
+DK_EXTERN int32_t c_api_version_least;
+
+/// @brief c_api_version_least+c_api_version_highest combined version.
+DK_EXTERN int32_t c_api_version;
diff --git a/dev/ddk/KernelString.c b/dev/ddk/KernelString.c
new file mode 100644
index 00000000..0030aa02
--- /dev/null
+++ b/dev/ddk/KernelString.c
@@ -0,0 +1,39 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ Purpose: DDK Strings.
+
+------------------------------------------- */
+
+#include <ddk/KernelString.h>
+
+DK_EXTERN size_t KernelStringLength(const char* in)
+{
+ if (in == nil)
+ return 0;
+ if (*in == 0)
+ return 0;
+
+ size_t index = 0;
+
+ while (in[index] != 0)
+ {
+ ++index;
+ }
+
+ return index;
+}
+
+DK_EXTERN int KernelStringCopy(char* dst, const char* src, size_t len)
+{
+ size_t index = 0;
+
+ while (index != len)
+ {
+ dst[index] = src[index];
+ ++index;
+ }
+
+ return index;
+}
diff --git a/dev/ddk/KernelString.h b/dev/ddk/KernelString.h
new file mode 100644
index 00000000..01d7d919
--- /dev/null
+++ b/dev/ddk/KernelString.h
@@ -0,0 +1,17 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ Purpose: DDK Strings.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <ddk/KernelStd.h>
+
+/// @brief DDK equivalent of POSIX's string.h
+/// @file KernelString.h
+
+DK_EXTERN size_t KernelStringLength(const char* in);
+DK_EXTERN int KernelStringCopy(char* dst, const char* src, size_t len);
diff --git a/dev/ddk/KernelVersion.c b/dev/ddk/KernelVersion.c
new file mode 100644
index 00000000..c40e8ff9
--- /dev/null
+++ b/dev/ddk/KernelVersion.c
@@ -0,0 +1,25 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ Purpose: DDK versioning.
+
+------------------------------------------- */
+
+#include <KernelStd.h>
+
+#ifndef cDDKVersionHighest
+#define cDDKVersionHighest 1
+#endif // !cDDKVersionHighest
+
+#ifndef cDDKVersionLowest
+#define cDDKVersionLowest 1
+#endif // !cDDKVersionLowest
+
+#ifndef cDDKVersion
+#define cDDKVersion 1
+#endif // !cDDKVersion
+
+int32_t c_api_version_highest = cDDKVersionHighest;
+int32_t c_api_version_least = cDDKVersionLowest;
+int32_t c_api_version = cDDKVersion;
diff --git a/dev/ddk/ReadMe.md b/dev/ddk/ReadMe.md
new file mode 100644
index 00000000..48e35ef2
--- /dev/null
+++ b/dev/ddk/ReadMe.md
@@ -0,0 +1,9 @@
+# ZKA's Device Driver Kit.
+
+A kit used to write Kernel HALs, using the NDK compiler suite.
+
+## How to use it
+
+Simply link against ddk.dll.
+
+###### Copyright 2024 ZKA Technologies, all rights reserved.
diff --git a/dev/ddk/ddk.json b/dev/ddk/ddk.json
new file mode 100644
index 00000000..b930f99c
--- /dev/null
+++ b/dev/ddk/ddk.json
@@ -0,0 +1,24 @@
+{
+ "compiler_path": "x86_64-w64-mingw32-gcc",
+ "compiler_std": "c++20",
+ "headers_path": ["../", "./"],
+ "sources_path": ["*.c", "*.cxx", "*.S"],
+ "output_name": "ddk.dll",
+ "compiler_flags": [
+ "-ffreestanding",
+ "-shared",
+ "-std=c17",
+ "-std=c++20",
+ "-fno-rtti",
+ "-fno-exceptions",
+ " -Wl,--subsystem=17"
+ ],
+ "cpp_macros": [
+ "__NEWOSKRNL__",
+ "__DDK_AMD64__",
+ "__DDK__",
+ "cDDKVersionHighest=0x0100",
+ "cDDKVersionLowest=0x0100",
+ "cDDKVersion=0x0100"
+ ]
+}
diff --git a/dev/ddk/source_deploy.xml b/dev/ddk/source_deploy.xml
new file mode 100644
index 00000000..3d2325a8
--- /dev/null
+++ b/dev/ddk/source_deploy.xml
@@ -0,0 +1,7 @@
+<SourceDeploy>
+<HiddenFiles>
+ <SourceFile>*.cxx</SourceFile>
+ <SourceFile>*.c</SourceFile>
+ <SourceFile>*.S</SourceFile>
+</HiddenFiles>
+</SourceDeploy>
diff --git a/dev/ddk/x86_64.make b/dev/ddk/x86_64.make
new file mode 100644
index 00000000..f1f7bb4b
--- /dev/null
+++ b/dev/ddk/x86_64.make
@@ -0,0 +1,14 @@
+##################################################
+# (C) ZKA Technologies, all rights reserved.
+# This is the DDK's makefile.
+##################################################
+
+CC=x86_64-w64-mingw32-gcc
+INC=-I./ -I../
+FLAGS=-ffreestanding -shared -std=c17 -std=c++20 -D__NEWOSKRNL__ -fno-rtti -fno-exceptions -D__DDK_AMD64__ -Wl,--subsystem=17
+VERSION=-DcDDKVersionLowest=1 -DcDDKVersionHighest=1
+OUTPUT=ddk.dll
+
+.PHONY: x86_64-build
+x86_64-build:
+ $(CC) $(INC) $(FLAGS) $(VERSION) $(wildcard *.c) $(wildcard *.S) $(wildcard *.cxx) -o $(OUTPUT) \ No newline at end of file