/Documentation/arm/msm/pil.txt
Plain Text | 267 lines | 204 code | 63 blank | 0 comment | 0 complexity | c36b600055f468a0a1da59649d4eab4b MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
1Introduction
2============
3
4The PIL (Peripheral Image Loader) driver loads peripheral images into memory
5and interfaces with the Peripheral Authentication Service (PAS) to
6authenticate and reset peripherals embedded in the SoC.
7
8The PAS could either be running under secure mode in the application
9processor (secure boot support) or be running as a non-secure kernel driver
10(non-secure boot support).
11
12The PIL driver also does housekeeping to handle cases where more than one
13client driver is using the same peripheral.
14
15Some examples of peripherals are modem, DSP and sensors.
16
17Hardware description
18====================
19
20The memory used by the peripherals for code and data storage will be
21accessible as normal memory to the application processor.
22
23The non-secure code (Linux kernel) will have read/write permissions to the
24peripheral memory by default.
25
26The PAS will have access to a MPU (memory protection unit) that can lock away
27the pages of memory from the Linux kernel. It will also have access to
28registers that can reset each peripheral.
29
30Software description
31====================
32
33The PAS provides the following three APIs:
34
35* Init image - Takes as input the peripheral id and firmware metadata and
36 returns a status indicating the authenticity of the firmware metadata. The
37 firmware metadata consists of a standard ELF32 header followed by a program
38 header table and an optional blob of data used to authenticate the metadata
39 and the rest of the firmware.
40
41* Verify segment - Takes as input the firmware segment id and the length of
42 the segment. Authenticates whatever amount (specified by the "length"
43 parameter) of the firmware segment that has been loaded and removes
44 non-secure mode read/write permissions for the pages belonging to the
45 firmware segment. Allows multiple calls for the same firmware segment to
46 allow partial loading and authentication.
47
48* Auth and Reset - Verifies all the necessary firmware segments have been
49 loaded and authenticated and then resets the peripheral.
50
51The user space is expected to provide the firmware metadata and firmware
52segments as separate files on persistent storage. See "Interface" section for
53further details.
54
55The PIL driver will use the request_firmware API provided by the Linux kernel
56to read the firmware and firmware metadata from persistent storage.
57
58When a client driver requests for a peripheral to be enabled, the PIL driver
59increments the reference count for that peripheral, loads the firmware
60metadata and calls the PAS Init Image API that initializes the authentication
61state machine using the firmware metadata.
62
63If the initialization succeeds, the PIL driver loads the appropriate firmware
64segments into their respective memory locations and call the PAS Verify
65segment API on each of the loaded segments to authenticate and lock it.
66
67After all the firmware segments have been successfully loaded and
68authenticated, the PAS Auth and Reset API is called to reset the peripheral
69and initiate its boot sequence.
70
71A peripheral enable request to the PIL driver will block until it succeeds
72(or fails) to initiate the peripheral boot sequence but will NOT block until
73the peripheral is ready. It is not possible to block until a peripheral is
74ready since the semantics of "ready" is subjective to the caller.
75
76The PIL driver will maintain a reference count for each of the peripherals.
77So, if a peripheral is already under use and another client driver requests
78for the peripheral to be enabled, the PIL driver will immediately return a
79value to indicate success.
80
81When all the client drivers of a particular peripheral no longer need the
82peripheral and the reference count reaches zero, the PIL driver can cleanly
83shut down the peripheral. Since a lot of drivers in their current state can't
84handle a peripheral restart, the PIL driver will never let the reference
85count go back to zero.
86
87All information about a peripheral, like firmware filenames, peripheral ID
88passed to PAS, etc, will be hard coded in the PIL driver.
89
90All the PIL APIs will execute in the context of the caller. This includes
91calls from the PIL driver to the PAS driver. The PAS driver might decide to
92switch into secure mode from a separate workqueue or in the same context as
93the caller, but that shouldn't have any implications for the PIL API callers
94since all the PIL APIs are blocking calls.
95
96Dependencies:
97-------------
98* Firmware class (CONFIG_FW_LOADER) for using the request_firmware API to
99 load firmware from persistent storage.
100* PAS to authenticate firmware and bring a peripheral out of reset.
101
102Error cases:
103------------
104The PIL driver could fail to enable a peripheral for several reasons like not
105having enough memory to load firmware and metadata, being unable to
106communicate with the PAS, the PAS returning with an error, etc. For all
107possible error cases, the PIL driver does not perform any retries and returns
108an appropriate error code. The client drivers should always check for success
109before trying to access the peripheral.
110
111Design
112======
113
114Design goals:
115-------------
116* The PIL driver must be agnostic to the actual format and method used to
117 authenticate the firmware.
118* Allow for future expansion to support demand loading of parts of firmware
119 for each peripheral.
120* Move most of the work into the preprocessing/building stage of the firmware.
121* Provide an API to the client drivers that absolves them from having to know
122 the structure or names of the firmware in persistent storage.
123* Handle multiple client drivers wanting to enable the same peripheral.
124
125
126Design reasons:
127---------------
128The user space is expected to provide the firmware metadata and segments as
129separate files for the following reasons:
130* Don't need to load the whole ELF file if the authentication info is
131 invalid.
132* Works better during low memory conditions since the amount of memory used
133 at any given instant when loading one segment at a time is smaller than
134 loading the whole ELF file.
135* Since an ELF segment in memory can be much bigger than on file, having a
136 flat binary would waste a lot of space due to zero-fills.
137* Allows for future enhancements to the loading procedure.
138
139Design tradeoffs:
140-----------------
141* With appropriate changes to the request_firmware API, the firmware blobs
142 could be directly loaded into the right memory location. But due to the
143 additional work and community approval that would be needed for modifying
144 the request_firmware API, we load the firmware blobs into kernel memory and
145 then copy them into the appropriate locations.
146
147Alternate designs:
148------------------
149One of the alternate designs that were considered required the firmware to be
150a flat binary. Although this design would simplify the PIL driver, it would
151result in the waste of a lot of persistent storage space (due to large
152zero-fills), prevent demand loading of segments in the future and use a lot
153more memory while loading the firmware.
154
155Software layering:
156------------------
157The peripheral authentication, reset and shutdown implementation is factored
158away into a Peripheral Authentication Service driver to allow the PIL driver
159to be agnostic of secure vs. non-secure boot and the mechanisms needed for
160communicating with any code that might be running in secure mode.
161
162Power Management
163================
164
165Some of the peripherals might support being turned off when not in use.
166Support for this might be disabled in the initial implementation of the PIL
167driver since many of the existing drivers can not handle peripheral restart.
168
169SMP/multi-core
170==============
171
172Will use mutexes to protected data that might be shared (reference count,
173etc).
174
175Security
176========
177
178The PIL driver must validate the physical memory addresses specified in the
179ELF and program header table before loading firmware segments to make sure
180it's not overwriting any memory used by the kernel and possibly PMEM regions
181(if it can be done without being an ugly hack). The PIL driver might need to
182maintain a white list or black list of physical memory address ranges to
183perform the address validation.
184
185Performance
186===========
187
188As mentioned in the design section, the loading of firmware segments is not
189optimal and has room for improvement.
190
191Interface
192=========
193
194In kernel APIs:
195void * pil_get(char *peripheral_name)
196 - Enables (if not already enabled) a peripheral and returns a handle
197 that can be used to disable the peripheral at a later time. If
198 peripheral can't be enabled successfully, then returns an error
199 (use IS_ERR) indicating the reason.
200
201void pil_put(void *peripheral_handle)
202 - Inform PIL that this client no longer needs the peripheral to be
203 active. Does not necessarily mean that the peripheral would be
204 disabled or powered off.
205
206
207User space APIs:
208All firmware must be located in the path that is expected by the hotplug (or
209compatible) daemon. A hotplug (or compatible) daemon should be running and be
210able to handle events from the kernel requesting for a firmware file.
211
212The basename of the firmware files will depend on the peripheral. For a given
213peripheral, the metadata filename should end with a ".mdt" and the firmware
214segment files should end with ".bXX" where XX denotes the index of the
215firmware segment starting from 0.
216
217Android hotplug compatible daemon expects the firmware files to be under
218/etc/firmware.
219
220Driver parameters
221=================
222
223No module or kernel command line parameters supported.
224
225Config options
226==============
227
228This driver is enabled using the MSM_PIL kernel config option and will
229depend on the CONFIG_FW_LOADER being available.
230
231Dependencies
232============
233
234Depends on firmware class module for the request_firmware API.
235
236Interacts with the PAS to authenticate the firmware and to initiate the boot
237sequence of a peripheral.
238
239Doesn't communicate with other processors since the secure code, if any, will
240be running on the application processor cores.
241
242User space utilities
243====================
244
245None.
246
247Other
248=====
249
250The firmware_class driver might be changed in the future to directly load the
251firmware into memory locations provided by the caller of request_firmware().
252
253Known issues
254============
255
256Since support for cleanly shutting down peripherals is yet to be added, the
257reference count of peripherals will never be allowed to go to zero once it
258becomes non-zero.
259
260To do
261=====
262
263* Add support for turning off peripherals when they are not in use.
264* Modify request_firmware() to directly copy firmware blobs into the
265 appropriate memory locations.
266* Add support for demand loading of firmware segments.
267* Add support for forced peripheral restarts.