"Das U-Boot" Source Tree
at master 108 lines 4.1 kB view raw
1.. SPDX-License-Identifier: GPL-2.0+ 2 3Events 4====== 5 6U-Boot supports a way for various events to be handled by interested 7subsystems. This provide a generic way to handle 'hooks' like setting up the 8CPUs after driver model is active, or reading a partition table after a new 9block device is probed. 10 11Rather than using weak functions and direct calls across subsystemss, it is 12often easier to use an event. 13 14An event consists of a type (e.g. EVT_DM_POST_INIT_F) and some optional data, 15in `union event_data`. An event spy can be created to watch for events of a 16particular type. When the event is created, it is sent to each spy in turn. 17 18 19Declaring a spy 20--------------- 21 22To declare a spy, use something like this:: 23 24 static int snow_check_temperature(void) 25 { 26 /* do something */ 27 return 0; 28 } 29 EVENT_SPY_SIMPLE(EVT_DM_POST_INIT_F, snow_check_temperature); 30 31This function is called when EVT_DM_POST_INIT_F is emitted, i.e. after the 32driver model is initialized (in U-Boot proper before and after relocation). 33 34If you need access to the event data, use `EVENT_SPY_FULL`, like this:: 35 36 static int snow_setup_cpus(void *ctx, struct event *event) 37 { 38 /* do something that uses event->data*/ 39 return 0; 40 } 41 EVENT_SPY_FULL(EVT_DM_POST_INIT_F, snow_setup_cpus); 42 43Note that the context is always NULL for a static spy. See below for information 44about how to use a dynamic spy. 45 46The return value is handled by the event emitter. If non-zero, then the error 47is returned to the function which emitted the event, i.e. the one that called 48`event_notify()`. 49 50Debugging 51--------- 52 53To assist with debugging events, enable `CONFIG_EVENT_DEBUG` and 54`CONFIG_CMD_EVENT`. The :doc:`../usage/cmd/event` command can then be used to 55provide a spy list. 56 57It is also possible to list spy information from the U-Boot executable,, using 58the `event_dump.py` script:: 59 60 $ scripts/event_dump.py /tmp/b/sandbox/u-boot 61 Event type Id Source location 62 -------------------- ------------------------------ ------------------------------ 63 EVT_MISC_INIT_F f:sandbox_misc_init_f arch/sandbox/cpu/start.c:125 64 65This shows each event spy in U-Boot, along with the event type, function name 66(or ID) and source location. 67 68Note that if `CONFIG_EVENT_DEBUG` is not enabled, the event ID is missing, so 69the function is shown instead (with an `f:` prefix as above). Since the ID is 70generally the same as the function name, this does not matter much. 71 72The event type is decoded by the symbol used by U-Boot for the event linker 73list. Symbols have the form:: 74 75 _u_boot_list_2_evspy_info_2_EVT_MISC_INIT_F 76 77so the event type can be read from the end. To manually list spy information 78in an image, use $(CROSS_COMPILE)nm:: 79 80 nm u-boot |grep evspy |grep list 81 00000000002d6300 D _u_boot_list_2_evspy_info_2_EVT_MISC_INIT_F 82 83Logging is also available. Events use category `LOGC_EVENT`, so you can enable 84logging on that, or add `#define LOG_DEBUG` to the top of `common/event.c` to 85see events being sent. 86 87 88Dynamic events 89-------------- 90 91Static events provide a way of dealing with events known at build time. In some 92cases we want to attach an event handler at runtime. For example, we may wish 93to be notified when a particular device is probed or removed. 94 95This can be handled by enabling `CONFIG_EVENT_DYNAMIC`. It is then possible to 96call `event_register()` to register a new handler for a particular event. 97 98If some context is need for the spy, you can pass a pointer to 99`event_register()` to provide that. Note that the context is only passed to 100a spy registered with `EVENT_SPY_FULL`. 101 102Dynamic event handlers are called after all the static event spy handlers have 103been processed. Of course, since dynamic event handlers are created at runtime 104it is not possible to use the `event_dump.py` to see them. 105 106At present there is no way to list dynamic event handlers from the command line, 107nor to deregister a dynamic event handler. These features can be added when 108needed.