+#include <lunaix/ds/mutex.h>
+#include <lunaix/iopoll.h>
+#include <lunaix/types.h>
+#include <lunaix/changeling.h>
+
+#include <hal/devtreem.h>
+
+#include <usr/lunaix/device.h>
+
+/**
+ * @brief Export a device definition (i.e., device driver metadata)
+ *
+ */
+#define EXPORT_DEVICE(id, devdef, load_order) \
+ export_ldga_el(devdefs, id, ptr_t, devdef); \
+ export_ldga_el_sfx(devdefs, id##_ldorder, ptr_t, devdef, load_order);
+
+/**
+ * @brief Mark the device definition can be loaded on demand, all other loading
+ * options are extended from this
+ */
+#define load_on_demand ld_ondemand
+
+/**
+ * @brief Mark the device definition to be loaded as system configuration
+ * device. These kind of devices are defined to be the devices that talk to the
+ * system firmware to do config, or collecting crucial information about the
+ * system. For instances, ACPI, SoC components, and other **interconnection**
+ * buese (not USB!). Such device driver must only rely on basic memory
+ * management service, and must not try accessing subsystems other than the mm
+ * unit, for example, timer, interrupt, file-system, must not assumed exist.
+ *
+ */
+#define load_sysconf ld_sysconf
+
+/**
+ * @brief Mark the device definition should be loaded automatically during the
+ * bootstrapping stage. Most of the driver do load there.
+ *
+ */
+#define load_onboot ld_kboot
+
+/**
+ * @brief Mark the device definition should be loaded automatically in
+ * the post boostrapping stage (i.e., the start up of proc0), where most of
+ * kernel sub-system are became ready to use. Do your load there if your driver
+ * depends on such condition
+ *
+ */
+#define load_postboot ld_post
+
+#define __foreach_exported_device_of(stage, index, pos) \
+ ldga_foreach(dev_##stage, struct device_def*, index, pos)
+#define foreach_exported_device_of(stage, index, pos) \
+ __foreach_exported_device_of(stage, index, pos)
+
+/**
+ * @brief Declare a device class
+ *
+ */
+#define DEVCLASS(vendor, devfn, dev) \
+ (struct devclass) \
+ { \
+ .fn_grp = DEV_FNGRP(dev_vn(vendor), dev_fn(devfn)), \
+ .device = dev_id(dev), .variant = 0 \
+ }
+
+#define DEV_MSKIF 0x00000003
+#define DEV_IFVOL 0x0 // volumetric (block) device
+#define DEV_IFSEQ 0x1 // sequential (character) device
+#define DEV_IFSYS 0x3 // a system device
+
+#define dev_object_root \
+ ({ extern morph_t* device_mobj_root; device_mobj_root; })
+
+/**
+ * A potens is a capability of the device
+ * ("potens", means "capable" in latin)
+ *
+ * A device can have multiple capabilities
+ * (or "potentes", plural form of potens)
+ *
+ * A group of devices with same capability will forms
+ * a "globus potentis" or "capability group". The
+ * group is completely a logical formation, meaning
+ * that it is not explictly coded.
+ *
+ * The idea of potens is to provide a unified and yet
+ * opaque method to decouple the device provide raw
+ * functionalities with any higher abstraction, such
+ * as other subsystem, or standard-compilance wrapper
+ * (e.g., POSIX terminal)
+ */
+struct potens_meta
+{
+ struct device* owner;
+
+ struct llist_header potentes;
+ unsigned int pot_type;
+};
+
+#define POTENS_META \
+ struct { \
+ union { \
+ struct potens_meta pot_meta; \
+ struct { \
+ struct llist_header potentes; \
+ unsigned int pot_type; \
+ }; \
+ }; \
+ }
+
+#define get_potens(cap, pot_struct) \
+ container_of((cap), pot_struct, pot_meta)
+#define potens_meta(cap) (&(cap)->pot_meta)
+#define potens_dev(cap) (potens_meta(cap)->owner)
+
+#define potens(name) POTENS_##name
+
+#define potens_check_unique(dev, pot_type) \
+ !device_get_potens(dev, pot_type)
+
+enum device_potens_type
+{
+ potens(NON),
+ #include <listings/device_potens.lst>
+};
+
+/**
+ * List of potentes of a device, pay attention to
+ * the spelling, "potentium", genitive plural of "potens".
+ */
+typedef struct llist_header potentium_list_t;
+
+
+#define DEVICE_META_FIELD \
+ struct { \
+ morph_t mobj; \
+ char name_val[DEVICE_NAME_SIZE]; \
+ };
+
+#define DEVICE_METADATA \
+ union { \
+ struct device_meta meta; \
+ DEVICE_META_FIELD; \
+ }
+
+#define devmeta_morpher morphable_attrs(device_meta, mobj)
+#define devalias_morpher morphable_attrs(device_alias, mobj)
+#define devcat_morpher morphable_attrs(device_cat, mobj)
+#define device_morpher morphable_attrs(device, mobj)
+
+#define dev_meta(dev) (&(dev)->meta)
+#define dev_mobj(dev) (&(dev)->mobj)
+#define dev_morph(dev) ({ likely(dev) ? &(dev)->mobj : dev_object_root; })
+#define dev_uid(dev) (morpher_uid(&(dev)->mobj))
+#define to_dev(dev) (container_of(dev,struct device, meta))
+#define to_catdev(dev) (container_of(dev,struct device_cat, meta))
+#define to_aliasdev(dev) (container_of(dev,struct device_alias, meta))
+
+struct device_meta
+{
+ DEVICE_META_FIELD;
+};
+
+struct device_alias {
+ DEVICE_METADATA;
+ struct device_meta* alias;
+};
+
+struct device_cat {
+ DEVICE_METADATA;
+};