pil.txt 10 KB

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