Merge remote-tracking branch 'origin/master' into isa/arm64
[lunaix-os.git] / lunaix-os / includes / lunaix / device.h
1 #ifndef __LUNAIX_DEVICE_H
2 #define __LUNAIX_DEVICE_H
3
4 #define DEVICE_NAME_SIZE 16
5
6 #include <lunaix/device_num.h>
7 #include <lunaix/ds/hashtable.h>
8 #include <lunaix/ds/hstr.h>
9 #include <lunaix/ds/ldga.h>
10 #include <lunaix/ds/llist.h>
11 #include <lunaix/ds/mutex.h>
12 #include <lunaix/iopoll.h>
13 #include <lunaix/types.h>
14 #include <lunaix/changeling.h>
15
16 #include <hal/devtreem.h>
17
18 #include <usr/lunaix/device.h>
19
20 /**
21  * @brief Export a device definition (i.e., device driver metadata)
22  *
23  */
24 #define EXPORT_DEVICE(id, devdef, load_order)                                  \
25     export_ldga_el(devdefs, id, ptr_t, devdef);                                \
26     export_ldga_el_sfx(devdefs, id##_ldorder, ptr_t, devdef, load_order);
27
28 /**
29  * @brief Mark the device definition can be loaded on demand, all other loading
30  * options are extended from this
31  */
32 #define load_on_demand ld_ondemand
33
34 /**
35  * @brief Mark the device definition to be loaded as system configuration
36  * device. These kind of devices are defined to be the devices that talk to the
37  * system firmware to do config, or collecting crucial information about the
38  * system. For instances, ACPI, SoC components, and other **interconnection**
39  * buese (not USB!). Such device driver must only rely on basic memory
40  * management service, and must not try accessing subsystems other than the mm
41  * unit, for example, timer, interrupt, file-system, must not assumed exist.
42  *
43  */
44 #define load_sysconf ld_sysconf
45
46 /**
47  * @brief Mark the device definition should be loaded automatically during the
48  * bootstrapping stage. Most of the driver do load there.
49  *
50  */
51 #define load_onboot ld_kboot
52
53 /**
54  * @brief Mark the device definition should be loaded automatically in
55  * the post boostrapping stage (i.e., the start up of proc0), where most of
56  * kernel sub-system are became ready to use. Do your load there if your driver
57  * depends on such condition
58  *
59  */
60 #define load_postboot ld_post
61
62 #define __foreach_exported_device_of(stage, index, pos)                        \
63     ldga_foreach(dev_##stage, struct device_def*, index, pos)
64 #define foreach_exported_device_of(stage, index, pos)                          \
65     __foreach_exported_device_of(stage, index, pos)
66
67 /**
68  * @brief Declare a device class
69  *
70  */
71 #define DEVCLASS(vendor, devfn, dev)                                           \
72     (struct devclass)                                                          \
73     {                                                                          \
74         .fn_grp = DEV_FNGRP(dev_vn(vendor), dev_fn(devfn)),                    \
75         .device = dev_id(dev), .variant = 0                                    \
76     }
77
78 #define DEV_MSKIF 0x00000003
79 #define DEV_IFVOL 0x0 // volumetric (block) device
80 #define DEV_IFSEQ 0x1 // sequential (character) device
81 #define DEV_IFSYS 0x3 // a system device
82
83 #define dev_object_root         \
84         ({ extern morph_t* device_mobj_root; device_mobj_root; })
85
86 /**
87  * A potens is a capability of the device
88  *      ("potens", means "capable" in latin)
89  * 
90  * A device can have multiple capabilities 
91  *      (or "potentes", plural form of potens)
92  * 
93  * A group of devices with same capability will forms
94  *  a "globus potentis" or "capability group". The
95  *  group is completely a logical formation, meaning
96  *  that it is not explictly coded.
97  * 
98  * The idea of potens is to provide a unified and yet
99  *  opaque method to decouple the device provide raw
100  *  functionalities with any higher abstraction, such
101  *  as other subsystem, or standard-compilance wrapper
102  *  (e.g., POSIX terminal)
103  */
104 struct potens_meta
105 {
106     struct device* owner;
107     
108     struct llist_header potentes;
109     unsigned int pot_type;
110 };
111
112 #define POTENS_META                                         \
113     struct {                                                \
114         union {                                             \
115             struct potens_meta pot_meta;                    \
116             struct {                                        \
117                 struct llist_header potentes;               \
118                 unsigned int pot_type;                      \
119             };                                              \
120         };                                                  \
121     }
122
123 #define get_potens(cap, pot_struct)       \
124             container_of((cap), pot_struct, pot_meta)
125 #define potens_meta(cap) (&(cap)->pot_meta)
126 #define potens_dev(cap) (potens_meta(cap)->owner)
127
128 #define potens(name)   POTENS_##name
129
130 #define potens_check_unique(dev, pot_type)                   \
131             !device_get_potens(dev, pot_type)
132
133 enum device_potens_type
134 {
135     potens(NON),
136     #include <listings/device_potens.lst>
137 };
138
139 /**
140  * List of potentes of a device, pay attention to 
141  * the spelling, "potentium", genitive plural of "potens".
142  */
143 typedef struct llist_header potentium_list_t;
144
145
146 #define DEVICE_META_FIELD                       \
147     struct {                                    \
148         morph_t mobj;                           \
149         char name_val[DEVICE_NAME_SIZE];        \
150     };
151
152 #define DEVICE_METADATA                             \
153     union {                                         \
154         struct device_meta meta;                    \
155         DEVICE_META_FIELD;                          \
156     }   
157
158 #define devmeta_morpher      morphable_attrs(device_meta, mobj)
159 #define devalias_morpher     morphable_attrs(device_alias, mobj)
160 #define devcat_morpher       morphable_attrs(device_cat, mobj)
161 #define device_morpher       morphable_attrs(device, mobj)
162
163 #define dev_meta(dev)       (&(dev)->meta)
164 #define dev_mobj(dev)       (&(dev)->mobj)
165 #define dev_morph(dev)      ({ likely(dev) ? &(dev)->mobj : dev_object_root; })
166 #define dev_uid(dev)        (morpher_uid(&(dev)->mobj))
167 #define to_dev(dev)         (container_of(dev,struct device, meta))
168 #define to_catdev(dev)      (container_of(dev,struct device_cat, meta))
169 #define to_aliasdev(dev)    (container_of(dev,struct device_alias, meta))
170
171 struct device_meta
172 {
173     DEVICE_META_FIELD;
174 };
175
176 struct device_alias {
177     DEVICE_METADATA;
178     struct device_meta* alias;
179 };
180
181 struct device_cat {
182     DEVICE_METADATA;
183 };
184
185 struct device
186 {
187     /* -- device structing -- */
188
189     DEVICE_METADATA;
190
191     potentium_list_t potentium;
192
193 #ifdef CONFIG_USE_DEVICETREE
194     devtree_link_t devtree_node;
195 #endif
196
197     /* -- device state -- */
198
199     mutex_t lock;
200
201     int dev_type;
202     struct devident ident;
203     void* underlay;
204
205     /* -- polling -- */
206     int poll_evflags;
207     poll_evt_q pollers;
208
209     struct
210     {
211         // TODO Think about where will they fit.
212         int (*acquire)(struct device* dev);
213         int (*release)(struct device* dev);
214
215         int (*read)(struct device*, void*, off_t, size_t);
216         int (*write)(struct device*, void*, off_t, size_t);
217         int (*read_async)(struct device*, void*, off_t, size_t);
218         int (*write_async)(struct device*, void*, off_t, size_t);
219
220         int (*read_page)(struct device*, void*, off_t);
221         int (*write_page)(struct device*, void*, off_t);
222
223         int (*exec_cmd)(struct device*, u32_t, va_list);
224         int (*poll)(struct device*);
225     } ops;
226 };
227
228 struct device_def;
229 typedef int (*devdef_ldfn)(struct device_def*);
230
231 struct device_ldfn_chain
232 {
233     struct device_ldfn_chain* chain;
234     devdef_ldfn load;
235 };
236
237 struct device_def
238 {
239     struct llist_header dev_list;
240     struct hlist_node hlist;
241     struct hlist_node hlist_if;
242     char* name;
243
244     union
245     {
246         struct {
247             bool no_default_realm : 1;
248         };
249         int val;
250     } flags;
251     
252
253     struct {
254         struct devclass class;
255         unsigned int class_hash;
256     };
257
258     struct device_ldfn_chain* load_chain;
259
260     /**
261      * @brief 
262      * Called when driver is required to register itself to the system
263      * All registration code should put it here.
264      * 
265      * ad tabulam -  
266      *      "to the record" in latin. just in case anyone wonders.
267      *      I am ran out of naming idea... have to improvise :)
268      *
269      */
270     devdef_ldfn ad_tabulam;
271
272     /**
273      * @brief Called when the driver is loaded at it's desired load stage
274      *
275      */
276     devdef_ldfn load;
277
278     /**
279      * @brief Called when the driver is required to create device instance
280      * This is for device with their own preference of creation
281      * object that hold parameter for such creation is provided by second argument.
282      */
283     int (*create)(struct device_def*, morph_t*);
284
285     /**
286      * @brief Called when a driver is requested to detach from the device and
287      * free up all it's resources
288      *
289      */
290     int (*free)(struct device_def*, void* instance);
291 };
292
293 #define def_device_name(dev_n)          .name = dev_n
294 #define def_device_class(_if, fn, dev)  .class = DEVCLASS(_if, fn, dev)
295 #define def_on_register(fn)             .ad_tabulam = fn
296 #define def_on_load(fn)                 .load = fn
297 #define def_on_create(fn)               .create = fn
298 #define def_on_free(fn)                 .free = fn
299 #define def_non_trivial                 .flags.no_default_realm = true
300
301 morph_t*
302 resolve_device_morph(void* maybe_dev);
303
304 #define mark_device_doing_write(dev_ptr) (dev_ptr)->poll_evflags &= ~_POLLOUT
305 #define mark_device_done_write(dev_ptr) (dev_ptr)->poll_evflags |= _POLLOUT
306
307 #define mark_device_doing_read(dev_ptr) (dev_ptr)->poll_evflags &= ~_POLLIN
308 #define mark_device_done_read(dev_ptr) (dev_ptr)->poll_evflags |= _POLLIN
309
310 #define mark_device_hanging(dev_ptr) (dev_ptr)->poll_evflags &= ~_POLLHUP
311 #define mark_device_grounded(dev_ptr) (dev_ptr)->poll_evflags |= _POLLHUP
312
313 static inline u32_t
314 device_id_from_class(struct devclass* class)
315 {
316     return ((class->device & 0xffff) << 16) | ((class->variant & 0xffff));
317 }
318
319 static inline struct device*
320 resolve_device(void* maybe_dev) {
321     morph_t* mobj = resolve_device_morph(maybe_dev);
322     return changeling_try_reveal(mobj, device_morpher);
323 }
324
325 void
326 device_scan_drivers();
327
328 void
329 device_setname_vargs(struct device_meta* dev, char* fmt, va_list args);
330
331 void
332 device_setname(struct device_meta* dev, char* fmt, ...);
333
334 void
335 device_register_generic(struct device_meta* dev, struct devclass* class, 
336                         char* fmt, ...);
337
338 #define register_device(dev, class, fmt, ...) \
339             device_register_generic(dev_meta(dev), class, fmt, ## __VA_ARGS__)
340
341 #define register_device_var(dev, class, fmt, ...) \
342             ({device_register_generic(                                     \
343                     dev_meta(dev), class,                                  \
344                     fmt "%d", ## __VA_ARGS__, (class)->variant);           \
345               devclass_mkvar(class); })
346
347 void
348 device_create(struct device* dev,
349               struct device_meta* parent,
350               u32_t type,
351               void* underlay);
352
353 struct device*
354 device_alloc(struct device_meta* parent, u32_t type, void* underlay);
355
356 #ifdef CONFIG_USE_DEVICETREE
357 static inline void
358 device_set_devtree_node(struct device* dev, devtree_link_t node)
359 {
360     dev->devtree_node = node;
361 }
362 #endif
363
364 static inline struct device* must_inline
365 device_allocsys(struct device_meta* parent, void* underlay)
366 {
367     return device_alloc(parent, DEV_IFSYS, underlay);
368 }
369
370 static inline struct device* must_inline
371 device_allocseq(struct device_meta* parent, void* underlay)
372 {
373     return device_alloc(parent, DEV_IFSEQ, underlay);
374 }
375
376 static inline struct device* must_inline
377 device_allocvol(struct device_meta* parent, void* underlay)
378 {
379     return device_alloc(parent, DEV_IFVOL, underlay);
380 }
381
382 struct device_alias*
383 device_addalias(struct device_meta* parent, struct device_meta* aliased, 
384                 char* name_fmt, ...);
385
386 struct device_cat*
387 device_addcat(struct device_meta* parent, char* name_fmt, ...);
388
389 void
390 device_remove(struct device_meta* dev);
391
392 struct hbucket*
393 device_definitions_byif(int if_type);
394
395 struct device_def*
396 devdef_byident(struct devident* class);
397
398 void
399 device_populate_info(struct device* dev, struct dev_info* devinfo);
400
401 void
402 device_scan_drivers();
403
404 /*------ Capability ------*/
405
406 struct potens_meta*
407 alloc_potens(int cap, unsigned int size);
408
409 #define new_potens(pot_type, pot_struct)\
410     ((pot_struct*)alloc_potens((pot_type), sizeof(pot_struct)))
411
412 #define new_potens_marker(pot_type)\
413     (alloc_potens((pot_type), sizeof(struct potens_meta)))
414
415 void
416 device_grant_potens(struct device* dev, struct potens_meta* cap);
417
418 struct potens_meta*
419 device_get_potens(struct device* dev, unsigned int pot_type);
420
421 /*------ Load hooks ------*/
422
423 void
424 device_onboot_load();
425
426 void
427 device_postboot_load();
428
429 void
430 device_sysconf_load();
431
432 /**
433  * @brief Add the loader to the chain, used by device domain
434  *        to inject their custom loading logic to the hook
435  */
436 void
437 device_chain_loader(struct device_def* def, devdef_ldfn fn);
438
439 /**
440  * @brief Walk the chain and load in a use-and-burnt fashion.
441  *        the chain will be deleted and freed after loading,
442  *        regardless successful or not.
443  */
444 void
445 device_chain_load_once(struct device_def* def);
446
447 static inline void
448 device_lock(struct device* dev)
449 {
450     mutex_lock(&dev->lock);
451 }
452
453 static inline void
454 device_unlock(struct device* dev)
455 {
456     mutex_unlock(&dev->lock);
457 }
458
459 static inline int
460 device_locked(struct device* dev)
461 {
462     return mutex_on_hold(&dev->lock);
463 }
464
465 #define devprintf_expand(devident) (devident)->fn_grp, (devident)->unique
466
467
468 /**
469  * 
470  * Device def hooks extern
471  * 
472  */
473
474 static int
475 default_onregister_hook(struct device_def* def)
476 {
477     return 0;
478 }
479
480 static int
481 default_onload_hook(struct device_def* def)
482 {
483     return 0;
484 }
485
486 static int
487 default_oncreate_hook(struct device_def* def, morph_t* morphed)
488 {
489     return 0;
490 }
491
492 #define extern_hook_register(name)  \
493             int weak_alias("default_onregister_hook") \
494                 name(struct device_def* def)
495
496 #define extern_hook_load(name)  \
497             int weak_alias("default_onload_hook") \
498                 name(struct device_def* def)
499
500 #define extern_hook_create(name)  \
501             int weak_alias("default_oncreate_hook") \
502                 name(struct device_def* def, morph_t* morphed)
503
504
505 #endif /* __LUNAIX_DEVICE_H */