summaryrefslogtreecommitdiffhomepage
path: root/dev/libDDK/src
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-08-25 09:50:27 +0200
committerAmlal El Mahrouss <amlal@nekernel.org>2025-08-25 09:50:27 +0200
commita7939c9a20d5f4b83d5df34aa652a88a0764042c (patch)
treed773fa076011ac6a54c1de93755797b09e7bd3ca /dev/libDDK/src
parentd864e0c6281024ce4b9bd654aa83308a50f583d8 (diff)
feat! ddk -> libDDK, use syscall on AMD64.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/libDDK/src')
-rw-r--r--dev/libDDK/src/ddk_abi_cxx.cc27
-rw-r--r--dev/libDDK/src/ddk_alloc.c32
-rw-r--r--dev/libDDK/src/ddk_dev.c26
-rw-r--r--dev/libDDK/src/ddk_io.c32
-rw-r--r--dev/libDDK/src/ddk_kernel_call.c76
-rw-r--r--dev/libDDK/src/ddk_kernel_call_dispatch.S42
-rw-r--r--dev/libDDK/src/ddk_str.c34
-rw-r--r--dev/libDDK/src/ddk_ver.c25
8 files changed, 294 insertions, 0 deletions
diff --git a/dev/libDDK/src/ddk_abi_cxx.cc b/dev/libDDK/src/ddk_abi_cxx.cc
new file mode 100644
index 00000000..fc590c0e
--- /dev/null
+++ b/dev/libDDK/src/ddk_abi_cxx.cc
@@ -0,0 +1,27 @@
+/* -------------------------------------------
+
+ DDK
+ Copyright Amlal El Mahrouss.
+
+ Author: Amlal El Mahrouss
+ Purpose: DDK C++ ABI.
+
+------------------------------------------- */
+
+#include <DriverKit/ddk.h>
+
+void* operator new(size_t sz) {
+ return ::kalloc(sz);
+}
+
+void operator delete(void* ptr) {
+ ::kfree(ptr);
+}
+
+void* operator new[](size_t sz) {
+ return ::kalloc(sz);
+}
+
+void operator delete[](void* ptr) {
+ ::kfree(ptr);
+}
diff --git a/dev/libDDK/src/ddk_alloc.c b/dev/libDDK/src/ddk_alloc.c
new file mode 100644
index 00000000..08527f4d
--- /dev/null
+++ b/dev/libDDK/src/ddk_alloc.c
@@ -0,0 +1,32 @@
+/* -------------------------------------------
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK allocator.
+
+------------------------------------------- */
+
+#include <DriverKit/ddk.h>
+
+/**
+ \brief Allocates a new heap on the Kernel's side.
+ \param sz the size of the heap block.
+ \return the newly allocated pointer.
+*/
+DDK_EXTERN void* kalloc(size_t sz) {
+ if (!sz) ++sz;
+
+ void* ptr = ke_call_dispatch("mm_alloc_ptr", 1, &sz, sizeof(size_t));
+
+ return ptr;
+}
+
+/**
+ \brief Frees a pointer from the heap.
+ \param ptr the pointer to free.
+*/
+DDK_EXTERN void kfree(void* ptr) {
+ if (!ptr) return;
+
+ ke_call_dispatch("mm_free_ptr", 1, ptr, 0);
+}
diff --git a/dev/libDDK/src/ddk_dev.c b/dev/libDDK/src/ddk_dev.c
new file mode 100644
index 00000000..32ec2442
--- /dev/null
+++ b/dev/libDDK/src/ddk_dev.c
@@ -0,0 +1,26 @@
+/* -------------------------------------------
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK Text I/O.
+
+------------------------------------------- */
+
+#include <DriverKit/dev.h>
+#include <DriverKit/str.h>
+
+/// @brief Open a new binary device from path.
+DDK_EXTERN DDK_DEVICE_PTR open(const char* devicePath) {
+ if (!devicePath) return nil;
+
+ return ke_call_dispatch("dk_open_dev", 1, (void*) devicePath, kstrlen(devicePath));
+}
+
+/// @brief Close any device.
+/// @param device valid device.
+DDK_EXTERN BOOL close(DDK_DEVICE_PTR device) {
+ if (!device) return NO;
+
+ ke_call_dispatch("dk_close_dev", 1, device, sizeof(DDK_DEVICE));
+ return YES;
+}
diff --git a/dev/libDDK/src/ddk_io.c b/dev/libDDK/src/ddk_io.c
new file mode 100644
index 00000000..c6cdd457
--- /dev/null
+++ b/dev/libDDK/src/ddk_io.c
@@ -0,0 +1,32 @@
+/* -------------------------------------------
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK Text I/O.
+
+------------------------------------------- */
+
+#include <DriverKit/io.h>
+
+DDK_EXTERN void kputc(const char ch) {
+ char assembled[2] = {0};
+ assembled[0] = ch;
+ assembled[1] = 0;
+
+ ke_call_dispatch("ke_put_string", 1, assembled, 1);
+}
+
+/// @brief print string to UART.
+/// @param message UART to transmit.
+DDK_EXTERN void kprint(const char* message) {
+ if (!message) return;
+ if (*message == 0) return;
+
+ size_t index = 0;
+ size_t len = kstrlen(message);
+
+ while (index < len) {
+ kputc(message[index]);
+ ++index;
+ }
+}
diff --git a/dev/libDDK/src/ddk_kernel_call.c b/dev/libDDK/src/ddk_kernel_call.c
new file mode 100644
index 00000000..1ac0a0aa
--- /dev/null
+++ b/dev/libDDK/src/ddk_kernel_call.c
@@ -0,0 +1,76 @@
+/* -------------------------------------------
+
+ DDK
+ Copyright Amlal El Mahrouss.
+
+ Author: Amlal El Mahrouss
+ Purpose: DDK kernel dispatch system.
+
+------------------------------------------- */
+
+#include <DriverKit/ddk.h>
+#include <stdarg.h>
+
+/// @brief this is an internal call, do not use it.
+DDK_EXTERN ATTRIBUTE(naked) void* __ke_call_dispatch(const int32_t name, int32_t cnt, void* data,
+ size_t sz);
+/// @brief This function hashes the path into a FNV symbol.
+/// @param path the path to hash.
+/// @retval 0 symbol wasn't hashed.
+/// @retval > 0 hashed symbol.
+static uint64_t ddk_fnv_64(const char* path) {
+ if (path == nil || *path == 0) return 0;
+
+ const uint64_t kFnvOffsetBase = 0xcbf29ce484222325ULL;
+ const uint64_t kFnvPrime64 = 0x100000001b3ULL;
+
+ uint64_t hash = kFnvOffsetBase;
+
+ while (*path) {
+ hash ^= (char) (*path++);
+ hash *= kFnvPrime64;
+ }
+
+ return hash;
+}
+
+/// @brief Interrupt Kernel and call it's RPC.
+/// @param name 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)
+DDK_EXTERN void* ke_call_dispatch(const char* name, int32_t cnt, void* data, size_t sz) {
+ if (name == nil || *name == 0 || data == nil || cnt == 0) return nil;
+ return __ke_call_dispatch(ddk_fnv_64(name), cnt, data, sz);
+}
+
+/// @brief Add system call.
+/// @param slot system call slot
+/// @param slotFn, syscall slot.
+DDK_EXTERN void ke_set_syscall(const int slot, void (*slotFn)(void* a0)) {
+ ke_call_dispatch("ke_set_syscall", slot, slotFn, 1);
+}
+
+/// @brief Get a Kernel object.
+/// @param slot property id (always 0)
+/// @param name the object's name.
+/// @return Object manifest.
+DDK_EXTERN struct DDK_OBJECT_MANIFEST* ke_get_obj(const int slot, const char* name) {
+ struct DDK_OBJECT_MANIFEST* manifest =
+ (struct DDK_OBJECT_MANIFEST*) ke_call_dispatch("cfkit_get_kobj", slot, (void*) name, 1);
+
+ if (!manifest) return nil;
+
+ return manifest;
+}
+
+/// @brief Set a Kernel object.
+/// @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.
+DDK_EXTERN void* ke_set_obj(const int slot, const struct DDK_OBJECT_MANIFEST* ddk_pr) {
+ return ke_call_dispatch("cfkit_set_kobj", slot, (void*) ddk_pr, 1);
+}
diff --git a/dev/libDDK/src/ddk_kernel_call_dispatch.S b/dev/libDDK/src/ddk_kernel_call_dispatch.S
new file mode 100644
index 00000000..dfe2d929
--- /dev/null
+++ b/dev/libDDK/src/ddk_kernel_call_dispatch.S
@@ -0,0 +1,42 @@
+/**
+ lang: asm
+ compiler: gnu
+ */
+
+.globl __ke_call_dispatch
+
+.text
+
+/* Really simple function, takes our va-list,
+ and brings it to the trap handler in the Kernel. */
+
+#if defined(__DDK_AMD64__)
+
+/* args rcx, rdx, r8, r9 */
+__ke_call_dispatch:
+ pushq rbp
+ movq rbp, rsp
+
+ syscall
+
+ popq rbp
+
+ ret
+
+#elif defined(__DDK_POWER64__)
+
+/* args r8, r9, r10, r11 */
+ke_call_dispatch:
+ /* 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 */
+ke_call_dispatch:
+ /* 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/libDDK/src/ddk_str.c b/dev/libDDK/src/ddk_str.c
new file mode 100644
index 00000000..514cddc7
--- /dev/null
+++ b/dev/libDDK/src/ddk_str.c
@@ -0,0 +1,34 @@
+/* -------------------------------------------
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK String API.
+
+------------------------------------------- */
+
+#include <DriverKit/str.h>
+
+DDK_EXTERN size_t kstrlen(const char* in) {
+ if (in == nil) return 0;
+
+ if (*in == 0) return 0;
+
+ size_t index = 0;
+
+ while (in[index] != 0) {
+ ++index;
+ }
+
+ return index;
+}
+
+DDK_EXTERN int kstrncpy(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/libDDK/src/ddk_ver.c b/dev/libDDK/src/ddk_ver.c
new file mode 100644
index 00000000..9be3134e
--- /dev/null
+++ b/dev/libDDK/src/ddk_ver.c
@@ -0,0 +1,25 @@
+/* -------------------------------------------
+
+ Copyright Amlal El Mahrouss.
+
+ Purpose: DDK version system.
+
+------------------------------------------- */
+
+#include <DriverKit/ddk.h>
+
+#ifndef kDDKVersionHighest
+#define kDDKVersionHighest 1
+#endif // !kDDKVersionHighest
+
+#ifndef kDDKVersionLowest
+#define kDDKVersionLowest 1
+#endif // !kDDKVersionLowest
+
+#ifndef kDDKVersion
+#define kDDKVersion 1
+#endif // !kDDKVersion
+
+uint32_t kApiVersionHighest = kDDKVersionHighest;
+uint32_t kApiVersionLowest = kDDKVersionLowest;
+uint32_t kApiVersion = kDDKVersion;