mmu.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. /*!
  2. *****************************************************************************
  3. *
  4. * @File mmu.h
  5. * @Description MMU Library
  6. * ---------------------------------------------------------------------------
  7. *
  8. * Copyright (c) Imagination Technologies Ltd.
  9. *
  10. * The contents of this file are subject to the MIT license as set out below.
  11. *
  12. * Permission is hereby granted, free of charge, to any person obtaining a
  13. * copy of this software and associated documentation files (the "Software"),
  14. * to deal in the Software without restriction, including without limitation
  15. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  16. * and/or sell copies of the Software, and to permit persons to whom the
  17. * Software is furnished to do so, subject to the following conditions:
  18. *
  19. * The above copyright notice and this permission notice shall be included in
  20. * all copies or substantial portions of the Software.
  21. *
  22. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  23. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  24. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  25. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  26. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  27. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  28. * THE SOFTWARE.
  29. *
  30. * Alternatively, the contents of this file may be used under the terms of the
  31. * GNU General Public License Version 2 ("GPL")in which case the provisions of
  32. * GPL are applicable instead of those above.
  33. *
  34. * If you wish to allow use of your version of this file only under the terms
  35. * of GPL, and not to allow others to use your version of this file under the
  36. * terms of the MIT license, indicate your decision by deleting the provisions
  37. * above and replace them with the notice and other provisions required by GPL
  38. * as set out in the file called "GPLHEADER" included in this distribution. If
  39. * you do not delete the provisions above, a recipient may use your version of
  40. * this file under the terms of either the MIT license or GPL.
  41. *
  42. * This License is also included in this distribution in the file called
  43. * "MIT_COPYING".
  44. *
  45. *****************************************************************************/
  46. #ifndef IMGMMU_MMU_H
  47. #define IMGMMU_MMU_H
  48. #include <linux/scatterlist.h>
  49. /**
  50. * @defgroup IMGMMU_lib The MMU page table manager
  51. * @brief The Memory Mapping Unit page table manager library handles the memory
  52. * hierarchy for a multi-directory MMU.
  53. *
  54. * The library is composed of several elements:
  55. * @li the Page Table management, responsible for managing the device memory
  56. * used for the mapping. This requires some functions from the Allocator to
  57. * access the memory and a virtual address from a Heap.
  58. * @li the Heap interface, that is the SW heap API one can re-implement (or use
  59. * the provided TAL one). This is responsible for choosing a virtual address
  60. * for an allocation.
  61. * @li the Allocator, that is not implemented in this library, is responsible
  62. * for providing physical pages list (when mapping) and a few memory operation
  63. * functions (imgmmu_info).
  64. * An example TAL allocator is provided in this code and can be used when
  65. * running in full user-space with pdumps.
  66. *
  67. * Some pre-processor values can be defined to customise the MMU:
  68. * @li IMGMMU_PHYS_SIZE physical address size of the MMU in bits (default: 40)
  69. * - only used for the default memory write function
  70. * @li IMGMMU_PAGE_SIZE page size in bytes (default: 4096) - not used directly
  71. * in the MMU code, but the allocator should take it into account
  72. * If IMGMMU_PAGE_SIZE is defined the following HAVE TO be defined as well:
  73. * @li IMGMMU_PAGE_SHIFT as log2(IMGMMU_PAGE_SIZE) (default: 12) - used in
  74. * virtual address to determine the position of the page offset
  75. * @li IMGMMU_DIR_SHIFT as log2(IMGMMU_PAGE_SIZE)*2-2 (default: 21) - used in
  76. * virtual address to determine the position of the directory offset
  77. * @li IMGMMU_CAT_SHIFT as log2(IMGMMU_PAGE_SIZE)*3-6 (default: 30) - used in
  78. * virtual address to determine the position of the catalogue offset
  79. *
  80. * @{
  81. */
  82. /*-----------------------------------------------------------------------------
  83. * Following elements are in the IMGMMU_lib documentation module
  84. *---------------------------------------------------------------------------*/
  85. /**
  86. * @name MMU page table management
  87. * @brief The public functions to use to control the MMU.
  88. * @image html MMU_class.png "MMU structure organisation"
  89. * @{
  90. */
  91. /*-----------------------------------------------------------------------------
  92. * Following elements are in the public functions
  93. *---------------------------------------------------------------------------*/
  94. /** @brief Opaque type representing an MMU Catalogue page */
  95. struct imgmmu_cat;
  96. /** @brief Opaque type representing an MMU Mapping */
  97. struct imgmmu_map;
  98. struct imgmmu_page;
  99. struct imgmmu_halloc;
  100. /** @brief Define indicating the mmu page type */
  101. #define IMGMMU_PTYPE_PC 0x1
  102. #define IMGMMU_PTYPE_PD 0x2
  103. #define IMGMMU_PTYPE_PT 0x3
  104. /** @brief Bypass phys address translation when using page_write */
  105. #define IMGMMU_BYPASS_ADDR_TRANS 0x80000000
  106. /**
  107. * @brief Pointer to a function implemented by the used allocator to create 1
  108. * page table (used for the MMU mapping - catalogue page and mapping page)
  109. *
  110. * @param type of the mmu page (PC, PD, PT)
  111. *
  112. * This is not done internally to allow the usage of different allocators
  113. *
  114. * @return A populated imgmmu_page structure with the result of the page allocation
  115. * @return NULL if the allocation failed
  116. *
  117. * @see imgmmu_page_free to liberate the page
  118. */
  119. typedef struct imgmmu_page *(*imgmmu_page_alloc) (void *, unsigned char type);
  120. /**
  121. * @brief Pointer to a function to free the allocated page table used for MMU
  122. * mapping
  123. *
  124. * This is not done internally to allow the usage of different allocators
  125. *
  126. * @see imgmmu_page_alloc to allocate the page
  127. */
  128. typedef void (*imgmmu_page_free) (struct imgmmu_page *);
  129. /**
  130. * @brief Pointer to a function to update Device memory on non Unified Memory
  131. */
  132. typedef void (*imgmmu_page_update) (struct imgmmu_page *);
  133. /**
  134. * @brief Write to a device address.
  135. *
  136. * This is not done internally to allow debug operations such a pdumping to
  137. * occur
  138. *
  139. * This function should do all the shifting and masking needed for the used MMU
  140. *
  141. * @param page page to update - asserts it is not NULL
  142. * @param offset in entries (32b word)
  143. * @param write physical address to write
  144. * @param flags bottom part of the entry used as flags for the MMU (including
  145. * valid flag) or IMGMMU_BYPASS_ADDR_TRANS
  146. * @param priv private data passed with map call
  147. */
  148. typedef void (*imgmmu_page_write) (struct imgmmu_page *page,
  149. unsigned int offset, uint64_t write,
  150. unsigned int flags, void *priv);
  151. /**
  152. * @brief Reads a 32 word on a physical page
  153. *
  154. * This is used only when debug operations occures (e.g. access page table
  155. * entry that caused a page fault)
  156. *
  157. * @param page physical page - asserts it is not NULL
  158. * @param offset in entries (32b word)
  159. * @param priv private data passed with map call
  160. * @return physical address at given offset and flags
  161. */
  162. typedef uint64_t(*imgmmu_page_read) (struct imgmmu_page *page,
  163. unsigned int offset, void *priv,
  164. unsigned int *flags);
  165. /**
  166. * @brief Callbacks definition structure
  167. */
  168. struct imgmmu_info {
  169. void *ctx;
  170. /** @brief allocate a physical page used in MMU mapping */
  171. imgmmu_page_alloc page_alloc;
  172. /** @brief liberate a physical page used in MMU mapping */
  173. imgmmu_page_free page_free;
  174. /**
  175. * @brief write a physical address onto a page - optional, if NULL internal
  176. * function is used
  177. *
  178. * The internal function assumes that IMGMMU_PHYS_SIZE is the MMU size.
  179. *
  180. * @note if NULL page_read is also set
  181. *
  182. * @warning The function assumes that the physical page memory is
  183. * accessible
  184. */
  185. imgmmu_page_write page_write;
  186. /**
  187. * @brief read a physical page offset - optional, if NULL access to page
  188. * table and catalogue entries is not supported
  189. *
  190. * @note If page_write and page_read are NULL then the internal
  191. * function is used.
  192. *
  193. * @warning The function assumes that the physical page memory is
  194. * accessible
  195. */
  196. imgmmu_page_read page_read;
  197. /**
  198. * @brief update a physical page on device if non UMA - optional, can be
  199. * NULL if update are not needed
  200. */
  201. imgmmu_page_update page_update;
  202. };
  203. /** @brief Page table entry - used when allocating the MMU pages */
  204. struct imgmmu_page {
  205. /**
  206. * @note Use ui64 instead of uintptr_t to support extended physical address
  207. * on 32b OS
  208. */
  209. uint64_t phys_addr;
  210. uint64_t virt_base;
  211. uintptr_t cpu_addr;
  212. };
  213. /**
  214. * @brief Access the default specified page size of the MMU (in Bytes)
  215. */
  216. size_t imgmmu_get_page_size(void);
  217. /**
  218. * @brief Returns entry shift for given type
  219. */
  220. size_t imgmmu_get_entry_shift(unsigned char type);
  221. /**
  222. * @brief Change the MMU page size in runtime.
  223. */
  224. int imgmmu_set_page_size(size_t pagesize);
  225. /**
  226. * @brief Access the compilation specified physical size of the MMU (in bits)
  227. */
  228. size_t imgmmu_get_phys_size(void);
  229. /**
  230. * @brief Access the compilation specified virtual address size of the MMU
  231. * (in bits)
  232. */
  233. size_t imgmmu_get_virt_size(void);
  234. /**
  235. * @brief Access the CPU page size - similar to PAGE_SIZE macro in Linux
  236. *
  237. * Not directly using PAGE_SIZE because we need a run-time configuration of the
  238. * PAGE_SIZE when running against simulators and different projects define
  239. * PAGE_SIZE in different ways...
  240. *
  241. * The default size is using the PAGE_SIZE macro if defined (or 4kB if not
  242. * defined when running against simulators)
  243. */
  244. size_t imgmmu_get_cpu_page_size(void);
  245. /**
  246. * @brief Change run-time CPU page size
  247. *
  248. * @warning to use against simulators only! default of imgmmu_get_cpu_page_size()
  249. * is PAGE_SIZE otherwise!
  250. */
  251. int imgmmu_set_cpu_page_size(size_t pagesize);
  252. /**
  253. * @brief Create a catalogue entry based on a given catalogue configuration
  254. *
  255. * @warning Obviously creation of the catalogue allocates memory - do not call
  256. * while interrupts are disabled
  257. *
  258. * @param info is copied and not modified - contains the functions to
  259. * use to manage page table memory
  260. * @param res where to store the error code, should not be NULL (trapped by
  261. * assert)
  262. *
  263. * @return The opaque handle to the imgmmu_cat object and res to
  264. * 0
  265. * @return NULL in case of an error and res has the value:
  266. * @li -EINVAL if catConfig is NULL or does not
  267. * contain function pointers
  268. * @li -ENOMEM if an internal allocation failed
  269. * @li -EFAULT if the given imgmmu_page_alloc returned NULL
  270. */
  271. struct imgmmu_cat *imgmmu_cat_create(
  272. const struct imgmmu_info *info,
  273. int *res);
  274. /**
  275. * @brief Destroy the imgmmu_cat - assumes that the HW is not going to access
  276. * the memory any-more
  277. *
  278. * Does not invalidate any memory because it assumes that everything is not
  279. * used any-more
  280. */
  281. int imgmmu_cat_destroy(struct imgmmu_cat *cat);
  282. /**
  283. * @brief Get access to the page table structure used in the catalogue (to be
  284. * able to write it to registers)
  285. *
  286. * @param cat asserts if cat is NULL
  287. *
  288. * @return the page table structure used
  289. */
  290. struct imgmmu_page *imgmmu_cat_get_page(struct imgmmu_cat *cat);
  291. /**
  292. * @brief Returns the page table entry value associated with the virtual
  293. * address
  294. *
  295. * @return -1 if the Catalogue's page_read is NULL or if the associate page
  296. * table is invalid in the catalogue map
  297. *
  298. */
  299. uint64_t imgmmu_cat_get_pte(
  300. struct imgmmu_cat *cat,
  301. uint64_t vaddr);
  302. /**
  303. * @brief Overrides the physical address associated with the virtual address
  304. *
  305. * @return -1 if the Catalogue's page_read is NULL or if the associate page
  306. * table is invalid in the catalogue map
  307. *
  308. */
  309. uint64_t imgmmu_cat_override_phys_addr(struct imgmmu_cat *cat,
  310. uint64_t vaddr, uint64_t new_phys_addr);
  311. /**
  312. * @brief Create a PageTable mapping for a list of physical pages and device
  313. * virtual address
  314. *
  315. * @warning Mapping can cause memory allocation (missing pages) - do not call
  316. * while interrupts are disabled
  317. *
  318. * @param cat catalogue to use for the mapping
  319. * @param phys_page_list sorted array of physical addresses (ascending order).
  320. * The number of elements is virt_mem->size/MMU_PAGE_SIZE
  321. * @note This array can potentially be big, the caller may need to use vmalloc
  322. * if running the linux kernel (e.g. mapping a 1080p NV12 is 760 entries, 6080
  323. * Bytes - 2 CPU pages needed, fine with kmalloc; 4k NV12 is 3038 entries,
  324. * 24304 Bytes - 6 CPU pages needed, kmalloc would try to find 8 contiguous
  325. * pages which may be problematic if memory is fragmented)
  326. * @param virt_mem associated device virtual address. Given structure is
  327. * copied
  328. * @param map_flags flags to apply on the page (typically 0x2 for Write Only,
  329. * 0x4 for Read Only) - the flag should not set bit 1 as 0x1 is the valid flag.
  330. * @param priv private data to be passed in callback interface
  331. * @param res where to store the error code, should not be NULL
  332. *
  333. * @return The opaque handle to the imgmmu_map object and res to
  334. * 0
  335. * @return NULL in case of an error an res has the value:
  336. * @li -EINVAL if the allocation size is not a multiple of
  337. * IMGMMU_PAGE_SIZE,
  338. * if the given list of page table is too long or not long enough for the
  339. * mapping or
  340. * if the give flags set the invalid bit
  341. * @li -EBUSY if the virtual memory is already mapped
  342. * @li -ENOMEM if an internal allocation failed
  343. * @li -EFAULT if a page creation failed
  344. */
  345. struct imgmmu_map *imgmmu_cat_map_arr(
  346. struct imgmmu_cat *cat,
  347. uint64_t *phys_page_list,
  348. const struct imgmmu_halloc *virt_mem,
  349. unsigned int map_flags,
  350. void *priv,
  351. int *res);
  352. struct imgmmu_map *imgmmu_cat_map_sg(
  353. struct imgmmu_cat *cat,
  354. struct scatterlist *phys_page_sg,
  355. bool use_sg_dma,
  356. const struct imgmmu_halloc *virt_mem,
  357. unsigned int map_flags,
  358. void *priv,
  359. int *res);
  360. /**
  361. * @brief Un-map the mapped pages (invalidate their entries) and destroy the
  362. * mapping object
  363. *
  364. * This does not destroy the created Page Table (even if they are becoming
  365. * un-used) and does not change the Catalogue valid bits.
  366. *
  367. * @return 0
  368. */
  369. int imgmmu_cat_unmap(struct imgmmu_map *map);
  370. /**
  371. * @brief Remove the internal Page Table structures and physical pages that
  372. * have no mapping attached to them
  373. *
  374. * @note This function does not have to be used, but can be used to clean some
  375. * un-used memory out and clean the Catalogue valid bits.
  376. *
  377. * @return The number of clean catalogue entries
  378. */
  379. uint32_t imgmmu_cat_clean(struct imgmmu_cat *cat);
  380. /**
  381. * @brief Get cache bits for PTE entry
  382. *
  383. * @return Cache bits
  384. */
  385. uint64_t imgmmu_get_pte_cache_bits(uint64_t pte_entry);
  386. /**
  387. * @brief Get parity bit shift of PTE entry
  388. *
  389. * @return Parity bit shift
  390. */
  391. u8 imgmmu_get_pte_parity_shift(void);
  392. /**
  393. * @brief Set parity for PTE entry
  394. *
  395. * @return Entry with applied parity
  396. */
  397. void imgmmu_set_pte_parity(uint64_t *pte_entry);
  398. #define IMGMMU_GET_MAX_PAGE_SIZE() (max(imgmmu_get_page_size(), imgmmu_get_cpu_page_size()))
  399. /**
  400. * @}
  401. */
  402. /*-----------------------------------------------------------------------------
  403. * End of the public functions
  404. *---------------------------------------------------------------------------*/
  405. /**
  406. * @}
  407. */
  408. /*-----------------------------------------------------------------------------
  409. * End of the IMGMMU_lib documentation module
  410. *---------------------------------------------------------------------------*/
  411. #endif /* IMGMMU_MMU_H */