xref: /illumos-gate/usr/src/man/man9e/ddi_ufm.9e (revision 7f3d7c9289dee6488b3cd2848a68c0b8580d750c)
1.\"
2.\" This file and its contents are supplied under the terms of the
3.\" Common Development and Distribution License ("CDDL"), version 1.0.
4.\" You may only use this file in accordance with the terms of version
5.\" 1.0 of the CDDL.
6.\"
7.\" A full copy of the text of the CDDL should have accompanied this
8.\" source.  A copy of the CDDL is also available via the Internet at
9.\" http://www.illumos.org/license/CDDL.
10.\"
11.\"
12.\" Copyright 2019 Joyent, Inc.
13.\" Copyright 2023 Oxide Computer Company
14.\" Copyright 2025 Peter Tribble
15.\"
16.Dd March 19, 2025
17.Dt DDI_UFM 9E
18.Os
19.Sh NAME
20.Nm ddi_ufm ,
21.Nm ddi_ufm_op_nimages ,
22.Nm ddi_ufm_op_fill_image ,
23.Nm ddi_ufm_op_fill_slot ,
24.Nm ddi_ufm_op_getcaps ,
25.Nm ddi_ufm_op_readimg
26.Nd DDI upgradable firmware module entry points
27.Sh SYNOPSIS
28.Vt typedef struct ddi_ufm_handle ddi_ufm_handle_t
29.Vt typedef struct ddi_ufm_ops ddi_ufm_ops_t
30.In sys/ddi_ufm.h
31.Ft int
32.Fo ddi_ufm_op_getcaps
33.Fa "ddi_ufm_handle_t *uhp"
34.Fa "void *drv_arg"
35.Fa "ddi_ufm_cap_t *caps"
36.Fc
37.Ft int
38.Fo ddi_ufm_op_nimages
39.Fa "ddi_ufm_handle_t *uhp"
40.Fa "void *drv_arg"
41.Fa "uint_t *nimgp"
42.Fc
43.Ft int
44.Fo ddi_ufm_op_fill_image
45.Fa "ddi_ufm_handle_t *uhp"
46.Fa "void *drv_arg"
47.Fa "uint_t imgno"
48.Fa "ddi_ufm_image_t *imgp"
49.Fc
50.Ft int
51.Fo ddi_ufm_op_fill_slot
52.Fa "ddi_ufm_handle_t *uhp"
53.Fa "void *drv_arg"
54.Fa "uint_t imgno"
55.Fa "uint_t slotno"
56.Fa "ddi_ufm_slot_t *slotp"
57.Fc
58.Ft int
59.Fo ddi_ufm_op_readimg
60.Fa "ddi_ufm_handle_t *uhp"
61.Fa "void *drv_arg"
62.Fa "uint_t imgno"
63.Fa "uint_t slotno"
64.Fa "uint64_t len"
65.Fa "uint64_t offset"
66.Fa "void *buf"
67.Fa "uint64_t *nreadp"
68.Fc
69.Sh INTERFACE LEVEL
70.Sy Evolving - This interface is evolving still in illumos. API and ABI stability is not guaranteed.
71.Sh PARAMETERS
72.Bl -tag -width Fa
73.It Fa uhp
74A handle corresponding to the device's UFM handle.
75This is the same value as returned in
76.Xr ddi_ufm_init 9F .
77.It Fa drv_arg
78This is a private value that the driver passed in when calling
79.Xr ddi_ufm_init 9F .
80.It Fa nimgp
81A pointer that the driver should set with a number of images.
82.It Fa imgno
83An integer indicating which image information is being requested for.
84.It Fa imgp
85An opaque pointer that represents a UFM image.
86.It Fa slotno
87An integer indicating which slot information is being requested for.
88.It Fa slotp
89An opaque pointer that represents a UFM slot.
90.It Fa len
91Indicates the number of bytes from a firmware payload that are desired.
92.It Fa offset
93Indicates an offset in a firmware payload to start reading from.
94.It Fa buf
95A buffer to place raw firmware data from the device into.
96.It Fa nreadp
97A pointer whose value should be updated with the number of bytes
98actually read from the image.
99.El
100.Sh DESCRIPTION
101Upgradable firmware modules (UFM) are a potential component of many
102devices.
103These interfaces aim to provide a simple series of callbacks
104for a device driver to implement such that it is easy to report
105information and in the future, manipulate firmware modules.
106.Ss UFM Background
107UFMs come in different flavors and styles that vary from device to
108device.
109.Qq Firmware
110generally refers to some form of software that runs on a device and is often
111packaged up as a binary payload.
112However, many things that aren't always called
113.Qq firmware ,
114such as EEPROM images, CPU microcode, flash based configuration, and more, are
115all just as important here.
116Take for example a hard drive.
117While it is a field replaceable unit (FRU), it also contains some amount
118of firmware that manages the drive which can be updated independently of
119replacing the drive.
120.Pp
121The motherboard often has a UFM in the form of the BIOS or UEFI.
122The Lights Out Management controller on a system has a UFM, which is usually
123the entire system image.
124CPUs also have a UFM in the form of microcode.
125.Pp
126An important property of a UFM is that it is a persistent part of the device
127itself.
128For example, many WiFi device drivers are required to send a binary blob of
129firmware to the device after every reset.
130Because these images are not persistent parts of the device and must be upgraded
131by either changing the device driver or related system files, we do not consider
132these UFMs.
133.Pp
134There are also devices that have firmware which is a part of the
135device, but may not be upgradable from the running OS.
136This may be because the vendor doesn't have tooling to upgrade the image or
137because the firmware image itself cannot be upgraded in the field at all.
138For example, a YubiKey has a firmware image that's burned into it in the
139factory, but there is no way to change the firmware on it short of
140replacing the device in its entirety.
141However, because these images are a permanent and persistent part of the device,
142we also consider them a UFM.
143.Ss Images and Slots
144A device that supports UFMs is made up of one or more distinct firmware
145images.
146Each image has its own unique purpose.
147For example, a motherboard may have both a BIOS and a CPLD image, each of which
148has independent firmware revisions.
149.Pp
150A given image may have a number of slots.
151A slot represents a particular version of the image.
152Only one slot is considered the
153.Em active
154slot.
155It represents the currently running version of the image.
156Devices support multiple slots so that an image can be downloaded to an inactive
157slot without risking damage to the active slot.
158This ensures that a power-loss or failure halfway through writing to a slot
159doesn't leave the device with corrupted firmware.
160.Pp
161The various entry points are designed such that all a driver has to do
162is provide information about the image and its slots to the kernel, it
163does not have to wrangle with how that is marshalled to users and the
164appearance of those structures.
165.Ss Registering with the UFM Subsystem
166During a device driver's
167.Xr attach 9E
168entry point, a device driver should register with the UFM subsystem by
169filling out a UFM operations vector and then calling
170.Xr ddi_ufm_init 9F .
171The driver may pass in a value, usually a pointer to its soft state
172pointer, which it will then receive when its subsequent entry points are
173called.
174.Pp
175Once the driver has finished initializing, it must call
176.Xr ddi_ufm_update 9F
177to indicate that the driver is in a state where it's ready to receive
178calls to the entry points.
179.Pp
180The various UFM entry points may be called from an arbitrary kernel
181context.
182However, they will only ever be called from a single thread at
183a given time.
184.Ss UFM operations vector
185The UFM operations vector is a structure that has the following members:
186.Bd -literal -offset indent
187typedef struct ddi_ufm_ops {
188	int (*ddi_ufm_op_nimages)(ddi_ufm_handle_t *uhp, void *drv_arg,
189	    uint_t *nimgp);
190	int (*ddi_ufm_op_fill_image)(ddi_ufm_handle_t *uhp, void *drv_arg,
191            uint_t imgno, ddi_ufm_image_t *imgp);
192	int (*ddi_ufm_op_fill_slot)(ddi_ufm_handle_t *uhp, void *drv_arg,
193            int imgno, ddi_ufm_image_t *img, uint_t slotno,
194	    ddi_ufm_slot_t *slotp);
195	int (*ddi_ufm_op_getcaps)(ddi_ufm_handle_t *uhp, void *drv_arg,
196	    ddi_ufm_cap_t *caps);
197	int (*ddi_ufm_op_readimg)(ddi_ufm_handle_t *uhp, void *drv_arg,
198	    uint_t imgno, uint_t slotno, uint64_t len, uint64_t offset,
199	    void *buf, uint64_t *nreadp);
200} ddi_ufm_ops_t;
201.Ed
202.Pp
203The
204.Fn ddi_ufm_op_nimages
205and
206.Fn ddi_ufm_op_readimg
207entry points are optional.
208If a device only has a single image, then there is no requirement to implement
209the
210.Fn ddi_ufm_op_nimages
211entry point and it may be set to
212.Dv NULL .
213The system will assume that there is only a single image.
214.Pp
215Slots and images are numbered starting at zero.
216If a driver indicates support for multiple images, through the
217.Fn ddi_ufm_op_nimages
218entry point, or slots, by using the
219.Xr ddi_ufm_image_set_nslots 9F
220function in the
221.Fn ddi_fum_op_fill_image
222callback then the images
223or slots will be numbered sequentially going from 0 to the number of images or
224slots minus one.
225These values will be passed to the various entry points to indicate which image
226and slot the system is interested in.
227It is up to the driver to maintain a consistent view of the images and slots
228for a given UFM.
229.Ss Fn ddi_ufm_op_nimages
230The
231.Fn ddi_ufm_op_nimages
232entry point is an optional entry point that answers the question of how
233many different, distinct firmware images are present on the device.
234Once the driver determines how many are present, it should set the value in
235.Fa nimgp
236to the determined value.
237.Pp
238It is legal for a device to pass in zero for this value, which indicates
239that there are none present.
240.Pp
241Upon successful completion, the driver should return
242.Sy 0 .
243Otherwise, the driver should return the appropriate error number.
244For a full list of error numbers, see
245.Xr Intro 2 .
246Common values are:
247.Bl -tag -width Er -offset width
248.It Er EIO
249An error occurred while communicating with the device to determine the
250number of firmware images.
251.El
252.Ss Fn ddi_ufm_op_fill_image
253The
254.Fn ddi_ufm_op_fill_image
255entry point is used to fill in information about a given image.
256The value in
257.Fa imgno
258is used to indicate which image the system is asking to fill
259information about.
260If the driver does not recognize the image ID in
261.Fa imgno
262then it should return an error.
263.Pp
264The
265.Ft ddi_ufm_image_t
266structure passed in
267.Fa imgp
268is opaque.
269To fill in information about the image, the driver should call the functions
270described in
271.Xr ddi_ufm_image 9F .
272.Pp
273The driver must call the
274.Xr ddi_ufm_image_set_desc 9F
275function to set a description of the image which indicates its purpose.
276This should be a human-readable string.
277In addition, the driver must call the
278.Xr ddi_ufm_image_set_nslots 9F
279function to indicate the number of slots that the device supports for
280that particular firmware image.
281The driver may also set any ancillary data that it deems may be useful with the
282.Xr ddi_ufm_image_set_misc 9F function.
283This function takes an nvlist, allowing the driver to set arbitrary keys and values.
284.Pp
285Once the driver has finished setting all of the information about the
286image then the driver should return
287.Sy 0 .
288Otherwise, the driver should return the appropriate error number.
289For a full list of error numbers, see
290.Xr Intro 2 .
291Common values are:
292.Bl -tag -width Er -offset width
293.It Er EINVAL
294The image indicated by
295.Fa imgno
296is unknown.
297.It Er EIO
298An error occurred talking to the device while trying to fill out
299firmware image information.
300.It Er ENOMEM
301The driver was unable to allocate memory while filling out image
302information.
303.El
304.Ss Fn ddi_ufm_op_fill_slot
305The
306.Fn ddi_ufm_op_fill_slot
307function is used to fill in information about a specific slot for a
308specific image.
309The value in
310.Fa imgno
311indicates the image the system wants slot information for and the value
312in
313.Fa slotno
314indicates which slot of that image the system is interested in.
315If the device driver does not recognize the value in either or
316.Fa imgno
317or
318.Fa slotno ,
319then it should return an error.
320.Pp
321The
322.Ft ddi_ufm_slot_t
323structure passed in
324.Fa slotp
325is opaque.
326To fill in information about the image the driver should call the functions
327described in
328.Xr ddi_ufm_slot 9F .
329.Pp
330The driver should call the
331.Xr ddi_ufm_slot_set_version 9F
332function to indicate the version of the UFM.
333The version is a device-specific character string.
334It should contain the current version of the UFM as a human can understand it
335and it should try to match the format used by device vendor.
336.Pp
337The
338.Xr ddi_ufm_slot_set_attrs 9F
339function should be used to set the attributes of the UFM slot.
340These attributes include the following enumeration values:
341.Bl -tag -width Dv
342.It Dv DDI_UFM_ATTR_READABLE
343The
344.Dv DDI_UFM_ATTR_READABLE
345attribute indicates that the firmware image in the specified slot
346may be read, even if the device driver does not currently support such
347functionality.
348.It Dv DDI_UFM_ATTR_WRITEABLE
349The
350.Dv DDI_UFM_ATTR_WRITEABLE
351attribute indicates that the firmware image in the specified slot
352may be updated, even if the driver does not currently support such
353functionality.
354.It Dv DDI_UFM_ATTR_ACTIVE
355The
356.Dv DDI_UFM_ATTR_ACTIVE
357attribute indicates that the firmware image in the specified slot
358is the active
359.Pq i.e. currently running
360firmware.
361Only one slot should be marked active.
362.It Dv DDI_UFM_ATTR_EMPTY
363The
364.Dv DDI_UFM_ATTR_EMPTY
365attribute indicates that the specified slot does not currently contain
366any firmware image.
367.El
368.Pp
369If the driver supports the
370.Fn ddi_ufm_op_readimg
371entry point, then the driver should attempt to determine the size in
372bytes of the image in the slot and indicate that by calling the
373.Xr ddi_ufm_slot_set_imgsize 9F
374function.
375.Pp
376Finally, if there are any device-specific key-value pairs that form
377useful, ancillary data, then the driver should assemble an nvlist and
378pass it to the
379.Xr ddi_ufm_slot_set_misc 9F
380function.
381.Pp
382Once the driver has finished setting all of the information about the
383slot then the driver should return
384.Sy 0 .
385Otherwise, the driver should return the appropriate error number.
386For a full list of error numbers, see
387.Xr Intro 2 .
388Common values are:
389.Bl -tag -width Er -offset width
390.It Er EINVAL
391The image or slot indicated by
392.Fa imgno
393and
394.Fa slotno
395is unknown.
396.It Er EIO
397An error occurred talking to the device while trying to fill out
398firmware slot information.
399.It Er ENOMEM
400The driver was unable to allocate memory while filling out slot
401information.
402.El
403.Ss Fn ddi_ufm_op_getcaps
404The
405.Fn ddi_ufm_op_getcaps
406function is used to indicate which DDI UFM capabilities are supported by this
407driver instance.
408Currently, all UFM-capable drivers are required to implement the
409.Dv DDI_UFM_CAP_REPORT
410capability.
411The following capabilities are supported and the drivers should return a
412bitwise-inclusive-OR of the following values:
413.Bl -tag -width Dv -offset width
414.It Dv DDI_UFM_CAP_REPORT
415Indicates that the driver is capable of reporting UFM information and
416implements the
417.Fn ddi_ufm_op_fill_slot
418and
419.Fn ddi_ufm_op_fill_image
420entry points.
421It also indicates, that it optionally implements
422.Fn ddi_ufm_op_nimages
423entry point.
424.It Dv DDI_UFM_CAP_READIMG
425Indicates that the driver is capable of reading a binary firmware
426payload off of a device.
427.El
428.Pp
429The driver should indicate the supported capabilities by setting the value in
430the
431.Ft caps
432parameter.
433Once the driver has populated
434.Ft caps
435with an appropriate value, then the driver should return
436.Sy 0 .
437Otherwise, the driver should return the appropriate error number.
438For a full list of error numbers, see
439.Xr Intro 2 .
440Common values are:
441.Bl -tag -width Er -offset width
442.It Er EIO
443An error occurred talking to the device while trying to discover firmware
444capabilities.
445.It Er ENOMEM
446The driver was unable to allocate memory.
447.El
448.Ss Fn ddi_ufm_op_readimg
449The
450.Fn ddi_ufm_op_readimg
451is an optional entry point that allows the system to read a binary
452firmware payload from the device.
453The driver should read the firmware payload indicated by both
454.Fa imgno
455and
456.Fa slotno .
457The driver should check to make sure that the region requested, starting
458at
459.Fa offset
460bytes into the image
461and
462.Fa len
463bytes long is valid for the image and if not, return the error
464.Er EINVAL .
465Data from the device should be copied into
466.Fa buf
467and the number of bytes successfully read should be placed into
468.Fa nreadp .
469.Pp
470Upon successfully reading this data, the driver should return
471.Sy 0 .
472Otherwise the driver should return the appropriate error number.
473For a full list of error numbers, see
474.Xr Intro 2 .
475Common values are:
476.Bl -tag -width Er -offset width
477.It Er EINVAL
478The image or slot indicate by
479.Fa imgno
480and
481.Fa slotno
482is unknown.
483The combination of
484.Fa offset
485and
486.Fa len
487would overflow or read from a region of the image which is not valid.
488The device currently has an alignment restriction and the requested
489offset and length do not honor that.
490.It Er EIO
491An error occurred while communicating with the device to read the
492firmware image.
493.It Er ENOTSUP
494The driver does not support reading a firmware payload on this device or
495from a particular image and slot.
496.El
497.Ss Caching and Updates
498The system will fetch firmware and slot information on an as-needed
499basis.
500Once it obtains some information, it may end up caching this information on
501behalf of the driver.
502Whenever the driver believes that something could have changed then the driver
503must call
504.Xr ddi_ufm_update 9F .
505The driver does not need to know for certain that something has changed.
506For example, after a device reset or firmware upgrade, the driver doesn't need
507to check if the firmware revision changed at all, it can simply call
508.Xr ddi_ufm_update 9F .
509.Ss Locking
510All UFM operations on a single UFM handle will always be run serially.
511However, the device driver may still need to apply adequate locking to
512its structure members as other entry points may be called on the device in
513parallel, which could access the same data structures and try to communicate
514with the device.
515.Ss Unregistering from the UFM subsystem
516When a device driver is detached, it should unregister from the UFM
517subsystem.
518To do so, the driver should call
519.Xr ddi_ufm_fini 9F .
520By the time this function returns, the driver is guaranteed that no UFM
521entry points will be called.
522However, if there are outstanding UFM related activity, the function will
523block until it is terminated.
524.Ss ioctl Interface
525Userland consumers can access UFM information via a set of ioctls that are
526implemented by the
527.Xr ufm 4D
528driver.
529.Sh CONTEXT
530The various UFM entry points that a device driver must implement will
531always be called from
532.Sy kernel
533context.
534.Sh SEE ALSO
535.Xr Intro 2 ,
536.Xr ufm 4D ,
537.Xr attach 9E ,
538.Xr ddi_ufm_fini 9F ,
539.Xr ddi_ufm_image 9F ,
540.Xr ddi_ufm_image_set_desc 9F ,
541.Xr ddi_ufm_image_set_misc 9F ,
542.Xr ddi_ufm_image_set_nslots 9F ,
543.Xr ddi_ufm_init 9F ,
544.Xr ddi_ufm_slot 9F ,
545.Xr ddi_ufm_slot_set_attrs 9F ,
546.Xr ddi_ufm_slot_set_misc 9F ,
547.Xr ddi_ufm_slot_set_version 9F ,
548.Xr ddi_ufm_update 9F
549