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