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 .\"
14 .Dd February 15, 2020
15 .Dt DDI_UFM 9E
16 .Os
17 .Sh NAME
18 .Nm ddi_ufm ,
19 .Nm ddi_ufm_op_nimages ,
20 .Nm ddi_ufm_op_fill_image ,
21 .Nm ddi_ufm_op_fill_slot ,
22 .Nm ddi_ufm_op_getcaps
23 .Nd DDI upgradable firmware module entry points
24 .Sh SYNOPSIS
25 .Vt typedef struct ddi_ufm_handle ddi_ufm_handle_t
26 .Vt typedef struct ddi_ufm_ops ddi_ufm_ops_t
27 .In sys/ddi_ufm.h
28 .Ft int
29 .Fo ddi_ufm_op_getcaps
30 .Fa "ddi_ufm_handle_t *uhp"
31 .Fa "void *drv_arg"
32 .Fa "ddi_ufm_cap_t *caps"
33 .Fc
34 .Ft int
35 .Fo ddi_ufm_op_nimages
36 .Fa "ddi_ufm_handle_t *uhp"
37 .Fa "void *drv_arg"
38 .Fa "uint_t *nimgp"
39 .Fc
40 .Ft int
41 .Fo ddi_ufm_op_fill_image
42 .Fa "ddi_ufm_handle_t *uhp"
43 .Fa "void *drv_arg"
44 .Fa "uint_t imgid"
45 .Fa "ddi_ufm_image_t *uip"
46 .Fc
47 .Ft int
48 .Fo ddi_ufm_op_fill_slot
49 .Fa "ddi_ufm_handle_t *uhp"
50 .Fa "void *drv_arg"
51 .Fa "uint_t imgid"
52 .Fa "uint_t slotid"
53 .Fa "ddi_ufm_slot_t *usp"
54 .Fc
55 .Sh INTERFACE LEVEL
56 .Sy Evolving - This interface is evolving still in illumos. API and ABI stability is not guaranteed.
57 .Sh PARAMETERS
58 .Bl -tag -width Fa
59 .It Fa uhp
60 A handle corresponding to the device's UFM handle.
61 This is the same value as returned in
62 .Xr ddi_ufm_init 9F .
63 .It Fa drv_arg
64 This is a private value that the driver passed in when calling
65 .Xr ddi_ufm_init 9F .
66 .It Fa nimgp
67 A pointer that the driver should set with a number of images.
68 .It Fa nslotp
69 A pointer that the driver should set with a number of slots.
70 .It Fa imgid
71 An integer indicating which image information is being requested for.
72 .It Fa uip
73 An opaque pointer that represents a UFM image.
74 .It Fa slotid
75 An integer indicating which slot information is being requested for.
76 .It Fa usp
77 An opaque pointer that represents a UFM slot.
78 .El
79 .Sh DESCRIPTION
80 Upgradable firmware modules (UFM) are a potential component of many
81 devices.
82 These interfaces aim to provide a simple series of callbacks
83 for a device driver to implement such that it is easy to report
84 information and in the future, manipulate firmware modules.
85 .Ss UFM Background
86 UFMs may come in different flavors and styles ranging from a
87 firmware blob, to an EEPROM image, to microcode, and more.
88 Take for example a hard drive.
89 While it is a field replaceable unit (FRU), it also contains some amount
90 of firmware that manages the drive which can be updated independently of
91 replacing the drive.
92 .Pp
93 The motherboard often has a UFM in the form of the BIOS or UEFI.
94 The Lights out management controller on a system has a UFM, which is usually
95 the entire system image.
96 CPUs also have a UFM in the form of microcode.
97 .Pp
98 An important property of a UFM is that it is a property of the device
99 itself.
100 For example, many WiFi device drivers are required to send a binary blob of
101 firmware to the device after every reset.
102 Because these images are not properties of the device and must be upgraded by
103 either changing the device driver or related system files, we do not consider
104 these UFMs.
105 .Pp
106 There are also devices that have firmware which is a property of the
107 device, but may not be upgradable from the running OS.
108 This may be because the vendor doesn't have tooling to upgrade the image or
109 because the firmware image itself cannot be upgraded in the field at all.
110 For example, a YubiKey has a firmware image that's burned into it in the
111 factory, but there is no way to change the firmware on it short of
112 replacing the device in its entirety.
113 However, because these images are a permanent part of the device, we also
114 consider them a UFM.
115 .Ss Images and Slots
116 A device that supports UFMs is made up of one or more distinct firmware
117 images.
118 Each image has its own unique purpose.
119 For example, a motherboard may have both a BIOS and a CPLD image, each of which
120 has independent firmware revisions.
121 .Pp
122 A given image may have a number of slots.
123 A slot represents a particular version of the image.
124 Only one slot can be active at a given time.
125 Devices support slots such that a firmware image can be downloaded
126 to the device without impacting the current device if it fails half-way
127 through.
128 The slot that's currently in use is referred to as the
129 .Em active
130 slot.
131 .Pp
132 The various entry points are designed such that all a driver has to do
133 is provide information about the image and its slots to the kernel, it
134 does not have to wrangle with how that is marshalled to users and the
135 appearance of those structures.
136 .Ss Registering with the UFM Subsystem
137 During a device driver's
138 .Xr attach 9E
139 entry point, a device driver should register with the UFM subsystem by
140 filling out a UFM operations vector and then calling
141 .Xr ddi_ufm_init 9F .
142 The driver may pass in a value, usually a pointer to its soft state
143 pointer, which it will then receive when its subsequent entry points are
144 called.
145 .Pp
146 Once the driver has finished initializing, it must call
147 .Xr ddi_ufm_update 9F
148 to indicate that the driver is in a state where it's ready to receive
149 calls to the entry points.
150 .Pp
151 The various UFM entry points may be called from an arbitrary kernel
152 context.
153 However, they will only ever be called from a single thread at
154 a given time.
155 .Ss UFM operations vector
156 The UFM operations vector is a structure that has the following members:
157 .Bd -literal -offset indent
158 typedef struct ddi_ufm_ops {
159 int (*ddi_ufm_op_nimages)(ddi_ufm_handle_t *uhp, void *arg,
160 uint_t *nimgp);
161 int (*ddi_ufm_op_fill_image)(ddi_ufm_handle_t *uhp, void *arg,
162 uint_t imgid, ddi_ufm_image_t *img);
163 int (*ddi_ufm_op_fill_slot)(ddi_ufm_handle_t *uhp, void *arg,
164 int imgid, ddi_ufm_image_t *img, uint_t slotid,
165 ddi_ufm_slot_t *slotp);
166 int (*ddi_ufm_op_getcaps)(ddi_ufm_handle_t *uhp, void *arg,
167 ddi_ufm_cap_t *caps);
168 } ddi_ufm_ops_t;
169 .Ed
170 .Pp
171 The
172 .Fn ddi_ufm_op_nimages
173 entry point is optional.
174 If a device only has a single image, then there is no reason to implement the
175 .Fn ddi_ufm_op_nimages entry point.
176 The system will assume that there is only a single image.
177 .Pp
178 Slots and images are numbered starting at zero.
179 If a driver indicates support for multiple images or slots then the images
180 or slots will be numbered sequentially going from 0 to the number of images or
181 slots minus one.
182 These values will be passed to the various entry points to indicate which image
183 and slot the system is interested in.
184 It is up to the driver to maintain a consistent view of the images and slots
185 for a given UFM.
186 .Pp
187 The members of this structure should be filled in the following ways:
188 .Bl -tag -width Fn
189 .It Fn ddi_ufm_op_nimages
190 The
191 .Fn ddi_ufm_op_nimages
192 entry point is an optional entry point that answers the question of how
193 many different, distinct firmware images are present on the device.
194 Once the driver determines how many are present, it should set the value in
195 .Fa nimgp to the determined value.
196 .Pp
197 It is legal for a device to pass in zero for this value, which indicates
198 that there are none present.
199 .Pp
200 Upon successful completion, the driver should return
201 .Sy 0 .
202 Otherwise, the driver should return the appropriate error number.
203 For a full list of error numbers, see
204 .Xr Intro 2 .
205 Common values are:
206 .Bl -tag -width Er -offset width
207 .It Er EIO
208 An error occurred while communicating with the device to determine the
209 number of firmware images.
210 .El
211 .It Fn ddi_ufm_op_fill_image
212 The
213 .Fn ddi_ufm_op_fill_image
214 entry point is used to fill in information about a given image.
215 The value in
216 .Fa imgid
217 is used to indicate which image the system is asking to fill
218 information about.
219 If the driver does not recognize the image ID in
220 .Fa imgid
221 then it should return an error.
222 .Pp
223 The
224 .Ft ddi_ufm_image_t
225 structure passed in
226 .Fa uip
227 is opaque.
228 To fill in information about the image, the driver should call the functions
229 described in
230 .Xr ddi_ufm_image 9F .
231 .Pp
232 The driver should call the
233 .Xr ddi_ufm_image_set_desc 9F
234 function to set a description of the image which indicates its purpose.
235 This should be a human-readable string.
236 The driver may also set any ancillary data that it deems may be useful with the
237 .Xr ddi_ufm_image_set_misc 9F function.
238 This function takes an nvlist, allowing the driver to set arbitrary keys and values.
239 .Pp
240 Once the driver has finished setting all of the information about the
241 image then the driver should return
242 .Sy 0 .
243 Otherwise, the driver should return the appropriate error number.
244 For a full list of error numbers, see
245 .Xr Intro 2 .
246 Common values are:
247 .Bl -tag -width Er -offset width
248 .It Er EINVAL
249 The image indicated by
250 .Fa imgid
251 is unknown.
252 .It Er EIO
253 An error occurred talking to the device while trying to fill out
254 firmware image information.
255 .It Er ENOMEM
256 The driver was unable to allocate memory while filling out image
257 information.
258 .El
259 .It Fn ddi_ufm_op_fill_slot
260 The
261 .Fn ddi_ufm_op_fill_slot
262 function is used to fill in information about a specific slot for a
263 specific image.
264 The value in
265 .Fa imgid
266 indicates the image the system wants slot information for and the value
267 in
268 .Fa slotid
269 indicates which slot of that image the system is interested in.
270 If the device driver does not recognize the value in either or
271 .Fa imgid
272 or
273 .Fa slotid ,
274 then it should return an error.
275 .Pp
276 The
277 .Ft ddi_ufm_slot_t
278 structure passed in
279 .Fa usp
280 is opaque.
281 To fill in information about the image the driver should call the functions
282 described in
283 .Xr ddi_ufm_slot 9F .
284 .Pp
285 The driver should call the
286 .Xr ddi_ufm_slot_set_version 9F
287 function to indicate the version of the UFM.
288 The version is a device-specific character string.
289 It should contain the current version of the UFM as a human can understand it
290 and it should try to match the format used by device vendor.
291 .Pp
292 The
293 .Xr ddi_ufm_slot_set_attrs 9F
294 function should be used to set the attributes of the UFM slot.
295 These attributes include the following enumeration values:
296 .Bl -tag -width Dv
297 .It Dv DDI_UFM_ATTR_READABLE
298 This attribute indicates that the firmware image in the specified slot
299 may be read, even if the device driver does not currently support such
300 functionality.
301 .It Dv DDI_UFM_ATTR_WRITEABLE
302 This attributes indicates that the firmware image in the specified slot
303 may be updated, even if the driver does not currently support such
304 functionality.
305 .It Dv DDI_UFM_ATTR_ACTIVE
306 This attributes indicates that the firmware image in the specified slot
307 is the active
308 .Pq i.e. currently running
309 firmware.
310 Only one slot should be marked active.
311 .It Dv DDI_UFM_ATTR_EMPTY
312 This attributes indicates that the specified slot does not currently contain
313 any firmware image.
314 .El
315 .Pp
316 Finally, if there are any device-specific key-value pairs that form
317 useful, ancillary data, then the driver should assemble an nvlist and
318 pass it to the
319 .Xr ddi_ufm_set_misc 9F
320 function.
321 .Pp
322 Once the driver has finished setting all of the information about the
323 slot then the driver should return
324 .Sy 0 .
325 Otherwise, the driver should return the appropriate error number.
326 For a full list of error numbers, see
327 .Xr Intro 2 .
328 Common values are:
329 .Bl -tag -width Er -offset width
330 .It Er EINVAL
331 The image or slot indicated by
332 .Fa imgid
333 and
334 .Fa slotid
335 is unknown.
336 .It Er EIO
337 An error occurred talking to the device while trying to fill out
338 firmware slot information.
339 .It Er ENOMEM
340 The driver was unable to allocate memory while filling out slot
341 information.
342 .El
343 .It Fn ddi_ufm_op_getcaps
344 The
345 .Fn ddi_ufm_op_getcaps
346 function is used to indicate which DDI UFM capabilities are supported by this
347 driver instance.
348 Currently there is only a single capability
349 .Pq DDI_UFM_CAP_REPORT
350 which indicates that the driver is capable of reporting UFM information for this
351 instance.
352 Future UFM versions may add additional capabilities such as the ability to
353 obtain a raw dump of the firmware image or to upgrade the firmware.
354 .Pp
355 The driver should indicate the supported capabilities by setting the value in
356 the
357 .Ft caps
358 parameter.
359 Once the driver has populated
360 .Ft caps
361 with an appropriate value, then the driver should return
362 .Sy 0 .
363 Otherwise, the driver should return the appropriate error number.
364 For a full list of error numbers, see
365 .Xr Intro 2 .
366 Common values are:
367 .Bl -tag -width Er -offset width
368 .It Er EIO
369 An error occurred talking to the device while trying to discover firmware
370 capabilities.
371 .It Er ENOMEM
372 The driver was unable to allocate memory.
373 .El
374 .El
375 .Ss Caching and Updates
376 The system will fetch firmware and slot information on an as-needed
377 basis.
378 Once it obtains some information, it may end up caching this information on
379 behalf of the driver.
380 Whenever the driver believes that something could have changed -- it need know
381 that it has -- then the driver must call
382 .Xr ddi_ufm_update 9F .
383 .Ss Locking
384 All UFM operations on a single UFM handle will always be run serially.
385 However, the device driver may still need to apply adequate locking to
386 its structure members as other may be accessing the same data structure
387 or trying to communicate with the device.
388 .Ss Unregistering from the UFM subsystem
389 When a device driver is detached, it should unregister from the UFM
390 subsystem.
391 To do so, the driver should call
392 .Xr ddi_ufm_fini 9F .
393 By the time this function returns, the driver is guaranteed that no UFM
394 entry points will be called.
395 However, if there are outstanding UFM related activity, the function will
396 block until it is terminated.
397 .Ss ioctl Interface
398 Userland consumers can access UFM information via a set of ioctls that are
399 implemented by the
400 .Xr ufm 7D
401 driver.
402 .Sh CONTEXT
403 The various UFM entry points that a device driver must implement will
404 always be called from
405 .Sy kernel
406 context.
407 .Sh SEE ALSO
408 .Xr Intro 2 ,
409 .Xr ufd 7D ,
410 .Xr attach 9E ,
411 .Xr ddi_ufm_fini 9F ,
412 .Xr ddi_ufm_image 9F ,
413 .Xr ddi_ufm_image_set_desc 9F ,
414 .Xr ddi_ufm_image_set_misc 9F ,
415 .Xr ddi_ufm_image_set_nslots 9F ,
416 .Xr ddi_ufm_init 9F ,
417 .Xr ddi_ufm_slot 9F ,
418 .Xr ddi_ufm_slot_set_attrs 9F ,
419 .Xr ddi_ufm_slot_set_misc 9F ,
420 .Xr ddi_ufm_slot_set_version 9F ,
421 .Xr ddi_ufm_update 9F