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