]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
feat: HAL Device Driver API — driver registry with probe/init/shutdown lifecycle
authorTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 19:54:47 +0000 (16:54 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 19:54:47 +0000 (16:54 -0300)
- Add include/hal/driver.h: struct hal_driver with type, priority, ops (probe/init/shutdown)
- Add src/kernel/driver.c: driver registry with hal_driver_register(), hal_drivers_init_all(),
  hal_drivers_shutdown_all(), hal_driver_find(), hal_driver_count()
- Drivers init in priority order (insertion sort), shutdown in reverse
- HAL_MAX_DRIVERS=32, 6 driver types: PLATFORM, CHAR, BLOCK, NET, DISPLAY, BUS
- Framework ready for existing drivers to self-register (incremental migration)

20/20 smoke, cppcheck clean

include/hal/driver.h [new file with mode: 0644]
src/kernel/driver.c [new file with mode: 0644]

diff --git a/include/hal/driver.h b/include/hal/driver.h
new file mode 100644 (file)
index 0000000..a9bb996
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef HAL_DRIVER_H
+#define HAL_DRIVER_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+/*
+ * HAL Device Driver Model
+ *
+ * Provides a unified registration and lifecycle interface for all
+ * hardware drivers, both platform-specific (x86 PS/2, PIT, LAPIC)
+ * and generic (ATA, E1000, VBE framebuffer).
+ *
+ * Architecture-dependent implementations register themselves at boot
+ * via hal_driver_register().  The kernel init code calls
+ * hal_drivers_init_all() to probe and initialise every registered
+ * driver in priority order.
+ */
+
+/* Driver categories */
+enum hal_driver_type {
+    HAL_DRV_PLATFORM,     /* arch-specific: PIT, PS/2, LAPIC, IOAPIC */
+    HAL_DRV_CHAR,         /* character devices: UART, keyboard, VGA text */
+    HAL_DRV_BLOCK,        /* block devices: ATA, virtio-blk */
+    HAL_DRV_NET,          /* network: E1000 */
+    HAL_DRV_DISPLAY,      /* display: VBE framebuffer */
+    HAL_DRV_BUS,          /* bus controllers: PCI */
+    HAL_DRV_TYPE_COUNT
+};
+
+/* Driver operations table */
+struct hal_driver_ops {
+    int  (*probe)(void);      /* detect hardware; return 0 if present */
+    int  (*init)(void);       /* initialise the driver; return 0 on success */
+    void (*shutdown)(void);   /* graceful shutdown / cleanup */
+};
+
+/* Driver descriptor — typically declared as a const static in each driver */
+struct hal_driver {
+    const char*            name;
+    enum hal_driver_type   type;
+    int                    priority;  /* lower = earlier init (0-99) */
+    struct hal_driver_ops  ops;
+};
+
+#define HAL_MAX_DRIVERS 32
+
+/*
+ * Register a driver with the HAL subsystem.
+ * Must be called before hal_drivers_init_all().
+ * Returns 0 on success, -1 if registry is full.
+ */
+int hal_driver_register(const struct hal_driver* drv);
+
+/*
+ * Probe and initialise all registered drivers in priority order.
+ * Called once during kernel boot.
+ * Returns the number of drivers successfully initialised.
+ */
+int hal_drivers_init_all(void);
+
+/*
+ * Shutdown all initialised drivers in reverse order.
+ */
+void hal_drivers_shutdown_all(void);
+
+/*
+ * Look up a registered driver by name.
+ * Returns NULL if not found.
+ */
+const struct hal_driver* hal_driver_find(const char* name);
+
+/*
+ * Return the number of registered drivers.
+ */
+int hal_driver_count(void);
+
+#endif /* HAL_DRIVER_H */
diff --git a/src/kernel/driver.c b/src/kernel/driver.c
new file mode 100644 (file)
index 0000000..9cc5330
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * HAL Device Driver Registry
+ *
+ * Maintains a table of registered drivers and provides lifecycle
+ * management (probe → init → shutdown) in priority order.
+ */
+#include "hal/driver.h"
+#include "console.h"
+#include "utils.h"
+
+static const struct hal_driver* drivers[HAL_MAX_DRIVERS];
+static int driver_count = 0;
+
+/* Track which drivers were successfully initialised (for shutdown order) */
+static int driver_inited[HAL_MAX_DRIVERS];
+
+int hal_driver_register(const struct hal_driver* drv) {
+    if (!drv || !drv->name) return -1;
+    if (driver_count >= HAL_MAX_DRIVERS) {
+        kprintf("[DRV] registry full, cannot register '%s'\n", drv->name);
+        return -1;
+    }
+    drivers[driver_count] = drv;
+    driver_inited[driver_count] = 0;
+    driver_count++;
+    return 0;
+}
+
+/* Simple insertion sort by priority (stable, in-place on the pointer array) */
+static void sort_drivers(void) {
+    for (int i = 1; i < driver_count; i++) {
+        const struct hal_driver* tmp = drivers[i];
+        int j = i - 1;
+        while (j >= 0 && drivers[j]->priority > tmp->priority) {
+            drivers[j + 1] = drivers[j];
+            j--;
+        }
+        drivers[j + 1] = tmp;
+    }
+}
+
+int hal_drivers_init_all(void) {
+    sort_drivers();
+
+    int ok = 0;
+    for (int i = 0; i < driver_count; i++) {
+        const struct hal_driver* d = drivers[i];
+
+        /* Probe: skip if hardware not present */
+        if (d->ops.probe) {
+            if (d->ops.probe() != 0) {
+                kprintf("[DRV] %s: not detected, skipping\n", d->name);
+                continue;
+            }
+        }
+
+        /* Init */
+        if (d->ops.init) {
+            int rc = d->ops.init();
+            if (rc != 0) {
+                kprintf("[DRV] %s: init failed (%d)\n", d->name, rc);
+                continue;
+            }
+        }
+
+        driver_inited[i] = 1;
+        ok++;
+    }
+
+    return ok;
+}
+
+void hal_drivers_shutdown_all(void) {
+    /* Shutdown in reverse priority order */
+    for (int i = driver_count - 1; i >= 0; i--) {
+        if (driver_inited[i] && drivers[i]->ops.shutdown) {
+            drivers[i]->ops.shutdown();
+            driver_inited[i] = 0;
+        }
+    }
+}
+
+const struct hal_driver* hal_driver_find(const char* name) {
+    if (!name) return NULL;
+    for (int i = 0; i < driver_count; i++) {
+        if (strcmp(drivers[i]->name, name) == 0)
+            return drivers[i];
+    }
+    return NULL;
+}
+
+int hal_driver_count(void) {
+    return driver_count;
+}