1 DDI_UFM(9E)                   Driver Entry Points                  DDI_UFM(9E)
   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
   8      typedef struct ddi_ufm_handle ddi_ufm_handle_t
   9      typedef struct ddi_ufm_ops ddi_ufm_ops_t
  11      #include <sys/ddi_ufm.h>
  13      int
  14      ddi_ufm_op_getcaps(ddi_ufm_handle_t *uhp, void *drv_arg,
  15          ddi_ufm_cap_t *caps);
  17      int
  18      ddi_ufm_op_nimages(ddi_ufm_handle_t *uhp, void *drv_arg, uint_t *nimgp);
  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);
  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);
  29      Evolving - This interface is evolving still in illumos. API and ABI
  30      stability is not guaranteed.
  33      uhp           A handle corresponding to the device's UFM handle.  This is
  34                    the same value as returned in ddi_ufm_init(9F).
  36      drv_arg       This is a private value that the driver passed in when
  37                    calling ddi_ufm_init(9F).
  39      nimgp         A pointer that the driver should set with a number of
  40                    images.
  42      nslotp        A pointer that the driver should set with a number of
  43                    slots.
  45      imgid         An integer indicating which image information is being
  46                    requested for.
  48      uip           An opaque pointer that represents a UFM image.
  50      slotid        An integer indicating which slot information is being
  51                    requested for.
  53      usp           An opaque pointer that represents a UFM slot.
  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.
  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.
  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.
  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.
  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.
  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.
  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.
 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.
 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.
 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.
 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.
 120    UFM operations vector
 121      The UFM operations vector is a structure that has the following members:
 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;
 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.
 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.
 147      The members of this structure should be filled in the following ways:
 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.
 157                        It is legal for a device to pass in zero for this
 158                        value, which indicates that there are none present.
 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:
 165                             EIO                An error occurred while
 166                                                communicating with the device
 167                                                to determine the number of
 168                                                firmware images.
 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.
 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).
 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.
 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:
 198                             EINVAL             The image indicated by imgid is
 199                                                unknown.
 201                             EIO                An error occurred talking to
 202                                                the device while trying to fill
 203                                                out firmware image information.
 205                             ENOMEM             The driver was unable to
 206                                                allocate memory while filling
 207                                                out image information.
 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.
 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).
 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.
 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:
 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.
 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.
 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.
 254                        DDI_UFM_ATTR_EMPTY
 255                                      This attributes indicates that the
 256                                      specified slot does not currently contain
 257                                      any firmware image.
 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.
 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:
 270                             EINVAL             The image or slot indicated by
 271                                                imgid and slotid is unknown.
 273                             EIO                An error occurred talking to
 274                                                the device while trying to fill
 275                                                out firmware slot information.
 277                             ENOMEM             The driver was unable to
 278                                                allocate memory while filling
 279                                                out slot information.
 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.
 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:
 299                             EIO                An error occurred talking to
 300                                                the device while trying to
 301                                                discover firmware capabilities.
 303                             ENOMEM             The driver was unable to
 304                                                allocate memory.
 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).
 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.
 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.
 326    ioctl Interface
 327      Userland consumers can access UFM information via a set of ioctls that
 328      are implemented by the ufm(7D) driver.
 331      The various UFM entry points that a device driver must implement will
 332      always be called from kernel context.
 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)
 341 illumos                        February 15, 2020                       illumos