16aec1278SMax Laier.\" Copyright (c) 2006 Max Laier <mlaier@FreeBSD.org> 26aec1278SMax Laier.\" All rights reserved. 36aec1278SMax Laier.\" 46aec1278SMax Laier.\" Redistribution and use in source and binary forms, with or without 56aec1278SMax Laier.\" modification, are permitted provided that the following conditions 66aec1278SMax Laier.\" are met: 76aec1278SMax Laier.\" 1. Redistributions of source code must retain the above copyright 86aec1278SMax Laier.\" notice, this list of conditions and the following disclaimer. 96aec1278SMax Laier.\" 2. Redistributions in binary form must reproduce the above copyright 106aec1278SMax Laier.\" notice, this list of conditions and the following disclaimer in the 116aec1278SMax Laier.\" documentation and/or other materials provided with the distribution. 126aec1278SMax Laier.\" 136aec1278SMax Laier.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 146aec1278SMax Laier.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 156aec1278SMax Laier.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 166aec1278SMax Laier.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 176aec1278SMax Laier.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 186aec1278SMax Laier.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 196aec1278SMax Laier.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 206aec1278SMax Laier.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 216aec1278SMax Laier.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 226aec1278SMax Laier.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 236aec1278SMax Laier.\" 246aec1278SMax Laier.\" $FreeBSD$ 256aec1278SMax Laier.\" 266e0186d5SSam Leffler.Dd May 18, 2008 276aec1278SMax Laier.Os 286aec1278SMax Laier.Dt FIRMWARE 9 296aec1278SMax Laier.Sh NAME 306aec1278SMax Laier.Nm firmware_register , 316aec1278SMax Laier.Nm firmware_unregister , 326aec1278SMax Laier.Nm firmware_get , 336aec1278SMax Laier.Nm firmware_put 346e0186d5SSam Leffler.Nm firmware_drain 356aec1278SMax Laier.Nd firmware image loading and management 366aec1278SMax Laier.Sh SYNOPSIS 376aec1278SMax Laier.In sys/param.h 38dad5bb64SMax Laier.In sys/systm.h 396aec1278SMax Laier.In sys/linker.h 406aec1278SMax Laier.In sys/firmware.h 416aec1278SMax Laier.Bd -literal 426aec1278SMax Laierstruct firmware { 436aec1278SMax Laier const char *name; /* system-wide name */ 446aec1278SMax Laier const void *data; /* location of image */ 456aec1278SMax Laier size_t datasize; /* size of image in bytes */ 466aec1278SMax Laier unsigned int version; /* version of the image */ 476aec1278SMax Laier}; 486aec1278SMax Laier.Ed 49ddb53abcSLuigi Rizzo.Ft "const struct firmware *" 506aec1278SMax Laier.Fo firmware_register 516aec1278SMax Laier.Fa "const char *imagename" 526aec1278SMax Laier.Fa "const void *data" 536aec1278SMax Laier.Fa "size_t datasize" 546aec1278SMax Laier.Fa "unsigned int version" 55ddb53abcSLuigi Rizzo.Fa "const struct firmware *parent" 566aec1278SMax Laier.Fc 576aec1278SMax Laier.Ft int 586aec1278SMax Laier.Fn firmware_unregister "const char *imagename" 59ddb53abcSLuigi Rizzo.Ft "const struct firmware *" 606aec1278SMax Laier.Fn firmware_get "const char *imagename" 616aec1278SMax Laier.Ft void 62ddb53abcSLuigi Rizzo.Fn firmware_put "const struct firmware *fp" "int flags" 636e0186d5SSam Leffler.Ft void 646e0186d5SSam Leffler.Fn firmware_drain "void" 656aec1278SMax Laier.Sh DESCRIPTION 66bd84dd2fSRuslan ErmilovThe 67bd84dd2fSRuslan Ermilov.Nm firmware 6897070dd5SLuigi Rizzoabstraction provides a convenient interface for loading 6997070dd5SLuigi Rizzo.Nm firmware images 7097070dd5SLuigi Rizzointo the kernel, and for accessing such images from kernel components. 716aec1278SMax Laier.Pp 7297070dd5SLuigi RizzoA 7397070dd5SLuigi Rizzo.Nm firmware image 7497070dd5SLuigi Rizzo(or 7597070dd5SLuigi Rizzo.Nm image 7697070dd5SLuigi Rizzofor brevity) 7797070dd5SLuigi Rizzois an opaque block of data residing in kernel memory. 7897070dd5SLuigi RizzoIt is associated to a unique 7997070dd5SLuigi Rizzo.Nm imagename 8097070dd5SLuigi Rizzowhich constitutes a search key, and to an integer 8197070dd5SLuigi Rizzo.Nm version 8297070dd5SLuigi Rizzonumber, which is also an opaque piece of information for the 8397070dd5SLuigi Rizzofirmware subsystem. 8497070dd5SLuigi Rizzo.Pp 8597070dd5SLuigi RizzoAn image is registered with the 86bd84dd2fSRuslan Ermilov.Nm firmware 8797070dd5SLuigi Rizzosubsystem by calling the function 8897070dd5SLuigi Rizzo.Fn firmware_register , 8997070dd5SLuigi Rizzoand unregistered by calling 9097070dd5SLuigi Rizzo.Fn firmware_unregister . 91ddb53abcSLuigi RizzoThese functions are usually (but not exclusively) called by 9297070dd5SLuigi Rizzospecially crafted kernel modules that contain the firmware image. 9397070dd5SLuigi RizzoThe modules can be statically compiled in the kernel, or loaded by 9497070dd5SLuigi Rizzo.Nm /boot/loader , 9597070dd5SLuigi Rizzomanually at runtime, or on demand by the firmware subsystem. 966aec1278SMax Laier.Pp 9797070dd5SLuigi Rizzo.Nm Clients 9897070dd5SLuigi Rizzoof the firmware subsystem can request access to a given image 9997070dd5SLuigi Rizzoby calling the function 10097070dd5SLuigi Rizzo.Fn firmware_get 10197070dd5SLuigi Rizzowith the 10297070dd5SLuigi Rizzo.Nm imagename 10397070dd5SLuigi Rizzothey want as an argument. If a matching image is not already registered, 10497070dd5SLuigi Rizzothe firmware subsystem will try to load it using the 10597070dd5SLuigi Rizzomechanisms specified below (typically, a kernel module 10697070dd5SLuigi Rizzowith 10797070dd5SLuigi Rizzo.Nm the same name 10897070dd5SLuigi Rizzoas the image). 10997070dd5SLuigi Rizzo.Sh API DESCRIPTION 11097070dd5SLuigi RizzoThe kernel 11197070dd5SLuigi Rizzo.Nm firmware API 11297070dd5SLuigi Rizzois made of the following functions: 11397070dd5SLuigi Rizzo.Pp 11497070dd5SLuigi Rizzo.Fn firmware_register 11597070dd5SLuigi Rizzoregisters with the kernel an image of size 11697070dd5SLuigi Rizzo.Nm datasize 11797070dd5SLuigi Rizzolocated at address 11897070dd5SLuigi Rizzo.Nm data , 11997070dd5SLuigi Rizzounder the name 12097070dd5SLuigi Rizzo.Nm imagename . 12197070dd5SLuigi Rizzo.Pp 12297070dd5SLuigi RizzoThe function returns NULL on error (e.g. because an 12397070dd5SLuigi Rizzoimage with the same name already exists, or the image 12497070dd5SLuigi Rizzotable is full), or a 12597070dd5SLuigi Rizzo.Ft const struct firmware * 12697070dd5SLuigi Rizzopointer to the image requested. 12797070dd5SLuigi Rizzo.Pp 1286aec1278SMax Laier.Fn firmware_unregister 12997070dd5SLuigi Rizzotries to unregister the firmware image 13097070dd5SLuigi Rizzo.Nm imagename 13197070dd5SLuigi Rizzofrom the system. The function is successful and returns 0 13297070dd5SLuigi Rizzoif there are no pending references to the image, otherwise 13397070dd5SLuigi Rizzoit does not unregister the image and returns EBUSY. 1346aec1278SMax Laier.Pp 1356aec1278SMax Laier.Fn firmware_get 1366aec1278SMax Laierreturns the requested firmware image. 137bd84dd2fSRuslan ErmilovIf the image is not yet registered with the system, 13897070dd5SLuigi Rizzothe function tries to load it. 13997070dd5SLuigi RizzoThis involves the linker subsystem and disk access, so 1406aec1278SMax Laier.Fn firmware_get 141bd84dd2fSRuslan Ermilovmust not be called with any locks (except for 142bd84dd2fSRuslan Ermilov.Va Giant ) . 1436e0186d5SSam LefflerNote also that if the firmware image is loaded from a filesystem 1446e0186d5SSam Lefflerit must already be mounted. 1456e0186d5SSam LefflerIn particular this means that it may be necessary to defer requests 1466e0186d5SSam Lefflerfrom a driver attach method unless it is known the root filesystem is 1476e0186d5SSam Leffleralready mounted. 14897070dd5SLuigi Rizzo.Pp 149bd84dd2fSRuslan ErmilovOn success, 1506aec1278SMax Laier.Fn firmware_get 1516aec1278SMax Laierreturns a pointer to the image description and increases the reference count 15297070dd5SLuigi Rizzofor this image. On failure, the function returns NULL. 1536aec1278SMax Laier.Pp 1546aec1278SMax Laier.Fn firmware_put 15597070dd5SLuigi Rizzodrops a reference to a firmware image. 156bd84dd2fSRuslan ErmilovThe 157bd84dd2fSRuslan Ermilov.Fa flags 158bd84dd2fSRuslan Ermilovargument may be set to 1596aec1278SMax Laier.Dv FIRMWARE_UNLOAD 16097070dd5SLuigi Rizzoto indicate that 16197070dd5SLuigi Rizzofirmware_put is free to reclaim resources associated with 16297070dd5SLuigi Rizzothe firmware image if this is the last reference. 1636e0186d5SSam LefflerBy default a firmware image will be deferred to a 1646e0186d5SSam Leffler.Xr taskqueue 9 1656e0186d5SSam Lefflerthread so the call may be done while holding a lock. 1666e0186d5SSam LefflerIn certain cases, such as on driver detach, this cannot be allowed. 1676e0186d5SSam LefflerIf the 1686e0186d5SSam Leffler.Dv FIRMWARE_WAIT 1696e0186d5SSam Lefflerflag is or'd into 1706e0186d5SSam Leffler.Fa flags 1716e0186d5SSam Lefflerthen 1726e0186d5SSam Leffler.Fn firmware_put 1736e0186d5SSam Lefflerwill wait for the asynchronous operation to complete. 1746e0186d5SSam LefflerThis can also be accomplished by calling the 1756e0186d5SSam Leffler.Fn firmware_drain 1766e0186d5SSam Lefflerroutine after 1776e0186d5SSam Leffler.Fn firmware_put . 17897070dd5SLuigi Rizzo.Sh FIRMWARE LOADING MECHANISMS 17997070dd5SLuigi RizzoAs mentioned before, any component of the system can register 18097070dd5SLuigi Rizzofirmware images at any time by simply calling 18197070dd5SLuigi Rizzo.Fn firmware_register . 1826aec1278SMax Laier.Pp 18397070dd5SLuigi RizzoThis is typically done when a module containing 18497070dd5SLuigi Rizzoa firmware image is given control, 18597070dd5SLuigi Rizzowhether compiled in, or preloaded by 18697070dd5SLuigi Rizzo.Nm /boot/loader , 18797070dd5SLuigi Rizzoor manually loaded with 18897070dd5SLuigi Rizzo.Xr kldload 8 . 18997070dd5SLuigi RizzoHowever, a system can implement additional mechanisms to bring 19097070dd5SLuigi Rizzothese images in memory before calling 19197070dd5SLuigi Rizzo.Fn firmware_register . 19297070dd5SLuigi Rizzo.Pp 19397070dd5SLuigi RizzoWhen 19497070dd5SLuigi Rizzo.Fn firmware_get 19597070dd5SLuigi Rizzodoes not find the requested image, it tries to load it using 19697070dd5SLuigi Rizzoone of the available loading mechanisms. 19797070dd5SLuigi RizzoAt the moment, there is only one, namely 19897070dd5SLuigi Rizzo.Nm Loadable kernel modules : 19997070dd5SLuigi Rizzo.Pp 20097070dd5SLuigi RizzoA firmware image named 20197070dd5SLuigi Rizzo.Nm foo 20297070dd5SLuigi Rizzois looked up by trying to load the module named 20397070dd5SLuigi Rizzo.Nm foo.ko , 20497070dd5SLuigi Rizzousing the facilities described in 20597070dd5SLuigi Rizzo.Xr kld 4 . 20697070dd5SLuigi RizzoIn particular, images are looked up in the directories specified 20797070dd5SLuigi Rizzoby the sysctl variable 20897070dd5SLuigi Rizzo.Nm kern.module_path 20997070dd5SLuigi Rizzowhich on most systems defaults to 21097070dd5SLuigi Rizzo.Nm /boot/kernel;/boot/modules . 21197070dd5SLuigi Rizzo.Pp 21297070dd5SLuigi RizzoNote that in case a module contains multiple images, 21397070dd5SLuigi Rizzothe caller should first request a 21497070dd5SLuigi Rizzo.Fn firmware_get 21597070dd5SLuigi Rizzofor the first image contained in the module, followed by requests 21697070dd5SLuigi Rizzofor the other images. 21797070dd5SLuigi Rizzo.Sh BUILDING FIRMWARE LOADABLE MODULES 21897070dd5SLuigi RizzoA firmware module is built by embedding the 21997070dd5SLuigi Rizzo.Nm firmware image 22097070dd5SLuigi Rizzointo a suitable loadable kernel module that calls 22197070dd5SLuigi Rizzo.Fn firmware_register 22297070dd5SLuigi Rizzoon loading, and 22397070dd5SLuigi Rizzo.Fn firmware_unregister 22497070dd5SLuigi Rizzoon unloading. 22597070dd5SLuigi Rizzo.Pp 22697070dd5SLuigi RizzoVarious system scripts and makefiles let you build a module 22797070dd5SLuigi Rizzoby simply writing a Makefile with the following entries: 22897070dd5SLuigi Rizzo.Bd -literal 22997070dd5SLuigi Rizzo 23097070dd5SLuigi Rizzo KMOD= imagename 23197070dd5SLuigi Rizzo FIRMWS= image_file:imagename[:version] 23297070dd5SLuigi Rizzo .include <bsd.kmod.mk> 23397070dd5SLuigi Rizzo 23497070dd5SLuigi Rizzo.Ed 23597070dd5SLuigi Rizzowhere KMOD is the basename of the module; FIRMWS is a list of 23697070dd5SLuigi Rizzocolon-separated tuples indicating the image_file's to be embedded 23797070dd5SLuigi Rizzoin the module, the imagename and version of each firmware image. 23897070dd5SLuigi Rizzo.Pp 23997070dd5SLuigi RizzoIf you need to embed firmware images into a system, you should write 24097070dd5SLuigi Rizzoappropriate entries in the <files.arch> file, e.g. this example is 24197070dd5SLuigi Rizzofrom 24297070dd5SLuigi Rizzo.Nm sys/arm/xscale/ixp425/files.ixp425: 24397070dd5SLuigi Rizzo.Bd -literal 24497070dd5SLuigi Rizzoixp425_npe_fw.c optional npe_fw \\ 24597070dd5SLuigi Rizzo compile-with "${AWK} -f $S/tools/fw_stub.awk \\ 24697070dd5SLuigi Rizzo IxNpeMicrocode.dat:npe_fw -mnpe -c${.TARGET}" \\ 24797070dd5SLuigi Rizzo no-implicit-rule before-depend local \\ 24897070dd5SLuigi Rizzo clean "ixp425_npe_fw.c" 24997070dd5SLuigi Rizzo# 25097070dd5SLuigi Rizzo# NB: ld encodes the path in the binary symbols generated for the 25197070dd5SLuigi Rizzo# firmware image so link the file to the object directory to 25297070dd5SLuigi Rizzo# get known values for reference in the _fw.c file. 25397070dd5SLuigi Rizzo# 25497070dd5SLuigi RizzoIxNpeMicrocode.fwo optional npe_fw \\ 25597070dd5SLuigi Rizzo dependency "IxNpeMicrocode.dat" \\ 25697070dd5SLuigi Rizzo compile-with "${LD} -b binary -d -warn-common \\ 25797070dd5SLuigi Rizzo -r -d -o ${.TARGET} IxNpeMicrocode.dat" \\ 25897070dd5SLuigi Rizzo no-implicit-rule \\ 25997070dd5SLuigi Rizzo clean "IxNpeMicrocode.fwo" 26097070dd5SLuigi RizzoIxNpeMicrocode.dat optional npe_fw \\ 26197070dd5SLuigi Rizzo dependency ".PHONY" \\ 2626e0186d5SSam Leffler compile-with "uudecode < $S/contrib/dev/npe/IxNpeMicrocode.dat.uu" \\ 26397070dd5SLuigi Rizzo no-obj no-implicit-rule \\ 26497070dd5SLuigi Rizzo clean "IxNpeMicrocode.dat" 26597070dd5SLuigi Rizzo.Ed 26697070dd5SLuigi Rizzo.Pp 26797070dd5SLuigi RizzoNote that generating the firmware modules in this way requires 26897070dd5SLuigi Rizzothe availability of the following tools: 26997070dd5SLuigi Rizzo.Xr awk , 27097070dd5SLuigi Rizzo.Xr Make , 27197070dd5SLuigi Rizzothe compiler and the linker. 27297070dd5SLuigi Rizzo.Sh SEE ALSO 27397070dd5SLuigi Rizzo.Xr module 9 , 27497070dd5SLuigi Rizzo.Xr kld 4 27597070dd5SLuigi Rizzo.Pp 27697070dd5SLuigi Rizzo.Pa /usr/share/examples/kld/firmware 2776aec1278SMax Laier.Sh HISTORY 278bd84dd2fSRuslan ErmilovThe 279bd84dd2fSRuslan Ermilov.Nm firmware 280bd84dd2fSRuslan Ermilovsystem was introduced in 281999b97c5SHiroki Sato.Fx 6.1 . 2826aec1278SMax Laier.Sh AUTHORS 2836aec1278SMax LaierThis manual page was written by 2846aec1278SMax Laier.An Max Laier Aq mlaier@FreeBSD.org . 285