123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- /*!
- *****************************************************************************
- *
- * @File mmu.h
- * @Description MMU Library
- * ---------------------------------------------------------------------------
- *
- * Copyright (c) Imagination Technologies Ltd.
- *
- * The contents of this file are subject to the MIT license as set out below.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 ("GPL")in which case the provisions of
- * GPL are applicable instead of those above.
- *
- * If you wish to allow use of your version of this file only under the terms
- * of GPL, and not to allow others to use your version of this file under the
- * terms of the MIT license, indicate your decision by deleting the provisions
- * above and replace them with the notice and other provisions required by GPL
- * as set out in the file called "GPLHEADER" included in this distribution. If
- * you do not delete the provisions above, a recipient may use your version of
- * this file under the terms of either the MIT license or GPL.
- *
- * This License is also included in this distribution in the file called
- * "MIT_COPYING".
- *
- *****************************************************************************/
- #ifndef IMGMMU_MMU_H
- #define IMGMMU_MMU_H
- #include <linux/scatterlist.h>
- /**
- * @defgroup IMGMMU_lib The MMU page table manager
- * @brief The Memory Mapping Unit page table manager library handles the memory
- * hierarchy for a multi-directory MMU.
- *
- * The library is composed of several elements:
- * @li the Page Table management, responsible for managing the device memory
- * used for the mapping. This requires some functions from the Allocator to
- * access the memory and a virtual address from a Heap.
- * @li the Heap interface, that is the SW heap API one can re-implement (or use
- * the provided TAL one). This is responsible for choosing a virtual address
- * for an allocation.
- * @li the Allocator, that is not implemented in this library, is responsible
- * for providing physical pages list (when mapping) and a few memory operation
- * functions (imgmmu_info).
- * An example TAL allocator is provided in this code and can be used when
- * running in full user-space with pdumps.
- *
- * Some pre-processor values can be defined to customise the MMU:
- * @li IMGMMU_PHYS_SIZE physical address size of the MMU in bits (default: 40)
- * - only used for the default memory write function
- * @li IMGMMU_PAGE_SIZE page size in bytes (default: 4096) - not used directly
- * in the MMU code, but the allocator should take it into account
- * If IMGMMU_PAGE_SIZE is defined the following HAVE TO be defined as well:
- * @li IMGMMU_PAGE_SHIFT as log2(IMGMMU_PAGE_SIZE) (default: 12) - used in
- * virtual address to determine the position of the page offset
- * @li IMGMMU_DIR_SHIFT as log2(IMGMMU_PAGE_SIZE)*2-2 (default: 21) - used in
- * virtual address to determine the position of the directory offset
- * @li IMGMMU_CAT_SHIFT as log2(IMGMMU_PAGE_SIZE)*3-6 (default: 30) - used in
- * virtual address to determine the position of the catalogue offset
- *
- * @{
- */
- /*-----------------------------------------------------------------------------
- * Following elements are in the IMGMMU_lib documentation module
- *---------------------------------------------------------------------------*/
- /**
- * @name MMU page table management
- * @brief The public functions to use to control the MMU.
- * @image html MMU_class.png "MMU structure organisation"
- * @{
- */
- /*-----------------------------------------------------------------------------
- * Following elements are in the public functions
- *---------------------------------------------------------------------------*/
- /** @brief Opaque type representing an MMU Catalogue page */
- struct imgmmu_cat;
- /** @brief Opaque type representing an MMU Mapping */
- struct imgmmu_map;
- struct imgmmu_page;
- struct imgmmu_halloc;
- /** @brief Define indicating the mmu page type */
- #define IMGMMU_PTYPE_PC 0x1
- #define IMGMMU_PTYPE_PD 0x2
- #define IMGMMU_PTYPE_PT 0x3
- /** @brief Bypass phys address translation when using page_write */
- #define IMGMMU_BYPASS_ADDR_TRANS 0x80000000
- /**
- * @brief Pointer to a function implemented by the used allocator to create 1
- * page table (used for the MMU mapping - catalogue page and mapping page)
- *
- * @param type of the mmu page (PC, PD, PT)
- *
- * This is not done internally to allow the usage of different allocators
- *
- * @return A populated imgmmu_page structure with the result of the page allocation
- * @return NULL if the allocation failed
- *
- * @see imgmmu_page_free to liberate the page
- */
- typedef struct imgmmu_page *(*imgmmu_page_alloc) (void *, unsigned char type);
- /**
- * @brief Pointer to a function to free the allocated page table used for MMU
- * mapping
- *
- * This is not done internally to allow the usage of different allocators
- *
- * @see imgmmu_page_alloc to allocate the page
- */
- typedef void (*imgmmu_page_free) (struct imgmmu_page *);
- /**
- * @brief Pointer to a function to update Device memory on non Unified Memory
- */
- typedef void (*imgmmu_page_update) (struct imgmmu_page *);
- /**
- * @brief Write to a device address.
- *
- * This is not done internally to allow debug operations such a pdumping to
- * occur
- *
- * This function should do all the shifting and masking needed for the used MMU
- *
- * @param page page to update - asserts it is not NULL
- * @param offset in entries (32b word)
- * @param write physical address to write
- * @param flags bottom part of the entry used as flags for the MMU (including
- * valid flag) or IMGMMU_BYPASS_ADDR_TRANS
- * @param priv private data passed with map call
- */
- typedef void (*imgmmu_page_write) (struct imgmmu_page *page,
- unsigned int offset, uint64_t write,
- unsigned int flags, void *priv);
- /**
- * @brief Reads a 32 word on a physical page
- *
- * This is used only when debug operations occures (e.g. access page table
- * entry that caused a page fault)
- *
- * @param page physical page - asserts it is not NULL
- * @param offset in entries (32b word)
- * @param priv private data passed with map call
- * @return physical address at given offset and flags
- */
- typedef uint64_t(*imgmmu_page_read) (struct imgmmu_page *page,
- unsigned int offset, void *priv,
- unsigned int *flags);
- /**
- * @brief Callbacks definition structure
- */
- struct imgmmu_info {
- void *ctx;
- /** @brief allocate a physical page used in MMU mapping */
- imgmmu_page_alloc page_alloc;
- /** @brief liberate a physical page used in MMU mapping */
- imgmmu_page_free page_free;
- /**
- * @brief write a physical address onto a page - optional, if NULL internal
- * function is used
- *
- * The internal function assumes that IMGMMU_PHYS_SIZE is the MMU size.
- *
- * @note if NULL page_read is also set
- *
- * @warning The function assumes that the physical page memory is
- * accessible
- */
- imgmmu_page_write page_write;
- /**
- * @brief read a physical page offset - optional, if NULL access to page
- * table and catalogue entries is not supported
- *
- * @note If page_write and page_read are NULL then the internal
- * function is used.
- *
- * @warning The function assumes that the physical page memory is
- * accessible
- */
- imgmmu_page_read page_read;
- /**
- * @brief update a physical page on device if non UMA - optional, can be
- * NULL if update are not needed
- */
- imgmmu_page_update page_update;
- };
- /** @brief Page table entry - used when allocating the MMU pages */
- struct imgmmu_page {
- /**
- * @note Use ui64 instead of uintptr_t to support extended physical address
- * on 32b OS
- */
- uint64_t phys_addr;
- uint64_t virt_base;
- uintptr_t cpu_addr;
- };
- /**
- * @brief Access the default specified page size of the MMU (in Bytes)
- */
- size_t imgmmu_get_page_size(void);
- /**
- * @brief Returns entry shift for given type
- */
- size_t imgmmu_get_entry_shift(unsigned char type);
- /**
- * @brief Change the MMU page size in runtime.
- */
- int imgmmu_set_page_size(size_t pagesize);
- /**
- * @brief Access the compilation specified physical size of the MMU (in bits)
- */
- size_t imgmmu_get_phys_size(void);
- /**
- * @brief Access the compilation specified virtual address size of the MMU
- * (in bits)
- */
- size_t imgmmu_get_virt_size(void);
- /**
- * @brief Access the CPU page size - similar to PAGE_SIZE macro in Linux
- *
- * Not directly using PAGE_SIZE because we need a run-time configuration of the
- * PAGE_SIZE when running against simulators and different projects define
- * PAGE_SIZE in different ways...
- *
- * The default size is using the PAGE_SIZE macro if defined (or 4kB if not
- * defined when running against simulators)
- */
- size_t imgmmu_get_cpu_page_size(void);
- /**
- * @brief Change run-time CPU page size
- *
- * @warning to use against simulators only! default of imgmmu_get_cpu_page_size()
- * is PAGE_SIZE otherwise!
- */
- int imgmmu_set_cpu_page_size(size_t pagesize);
- /**
- * @brief Create a catalogue entry based on a given catalogue configuration
- *
- * @warning Obviously creation of the catalogue allocates memory - do not call
- * while interrupts are disabled
- *
- * @param info is copied and not modified - contains the functions to
- * use to manage page table memory
- * @param res where to store the error code, should not be NULL (trapped by
- * assert)
- *
- * @return The opaque handle to the imgmmu_cat object and res to
- * 0
- * @return NULL in case of an error and res has the value:
- * @li -EINVAL if catConfig is NULL or does not
- * contain function pointers
- * @li -ENOMEM if an internal allocation failed
- * @li -EFAULT if the given imgmmu_page_alloc returned NULL
- */
- struct imgmmu_cat *imgmmu_cat_create(
- const struct imgmmu_info *info,
- int *res);
- /**
- * @brief Destroy the imgmmu_cat - assumes that the HW is not going to access
- * the memory any-more
- *
- * Does not invalidate any memory because it assumes that everything is not
- * used any-more
- */
- int imgmmu_cat_destroy(struct imgmmu_cat *cat);
- /**
- * @brief Get access to the page table structure used in the catalogue (to be
- * able to write it to registers)
- *
- * @param cat asserts if cat is NULL
- *
- * @return the page table structure used
- */
- struct imgmmu_page *imgmmu_cat_get_page(struct imgmmu_cat *cat);
- /**
- * @brief Returns the page table entry value associated with the virtual
- * address
- *
- * @return -1 if the Catalogue's page_read is NULL or if the associate page
- * table is invalid in the catalogue map
- *
- */
- uint64_t imgmmu_cat_get_pte(
- struct imgmmu_cat *cat,
- uint64_t vaddr);
-
- /**
- * @brief Overrides the physical address associated with the virtual address
- *
- * @return -1 if the Catalogue's page_read is NULL or if the associate page
- * table is invalid in the catalogue map
- *
- */
- uint64_t imgmmu_cat_override_phys_addr(struct imgmmu_cat *cat,
- uint64_t vaddr, uint64_t new_phys_addr);
- /**
- * @brief Create a PageTable mapping for a list of physical pages and device
- * virtual address
- *
- * @warning Mapping can cause memory allocation (missing pages) - do not call
- * while interrupts are disabled
- *
- * @param cat catalogue to use for the mapping
- * @param phys_page_list sorted array of physical addresses (ascending order).
- * The number of elements is virt_mem->size/MMU_PAGE_SIZE
- * @note This array can potentially be big, the caller may need to use vmalloc
- * if running the linux kernel (e.g. mapping a 1080p NV12 is 760 entries, 6080
- * Bytes - 2 CPU pages needed, fine with kmalloc; 4k NV12 is 3038 entries,
- * 24304 Bytes - 6 CPU pages needed, kmalloc would try to find 8 contiguous
- * pages which may be problematic if memory is fragmented)
- * @param virt_mem associated device virtual address. Given structure is
- * copied
- * @param map_flags flags to apply on the page (typically 0x2 for Write Only,
- * 0x4 for Read Only) - the flag should not set bit 1 as 0x1 is the valid flag.
- * @param priv private data to be passed in callback interface
- * @param res where to store the error code, should not be NULL
- *
- * @return The opaque handle to the imgmmu_map object and res to
- * 0
- * @return NULL in case of an error an res has the value:
- * @li -EINVAL if the allocation size is not a multiple of
- * IMGMMU_PAGE_SIZE,
- * if the given list of page table is too long or not long enough for the
- * mapping or
- * if the give flags set the invalid bit
- * @li -EBUSY if the virtual memory is already mapped
- * @li -ENOMEM if an internal allocation failed
- * @li -EFAULT if a page creation failed
- */
- struct imgmmu_map *imgmmu_cat_map_arr(
- struct imgmmu_cat *cat,
- uint64_t *phys_page_list,
- const struct imgmmu_halloc *virt_mem,
- unsigned int map_flags,
- void *priv,
- int *res);
- struct imgmmu_map *imgmmu_cat_map_sg(
- struct imgmmu_cat *cat,
- struct scatterlist *phys_page_sg,
- bool use_sg_dma,
- const struct imgmmu_halloc *virt_mem,
- unsigned int map_flags,
- void *priv,
- int *res);
- /**
- * @brief Un-map the mapped pages (invalidate their entries) and destroy the
- * mapping object
- *
- * This does not destroy the created Page Table (even if they are becoming
- * un-used) and does not change the Catalogue valid bits.
- *
- * @return 0
- */
- int imgmmu_cat_unmap(struct imgmmu_map *map);
- /**
- * @brief Remove the internal Page Table structures and physical pages that
- * have no mapping attached to them
- *
- * @note This function does not have to be used, but can be used to clean some
- * un-used memory out and clean the Catalogue valid bits.
- *
- * @return The number of clean catalogue entries
- */
- uint32_t imgmmu_cat_clean(struct imgmmu_cat *cat);
- /**
- * @brief Get cache bits for PTE entry
- *
- * @return Cache bits
- */
- uint64_t imgmmu_get_pte_cache_bits(uint64_t pte_entry);
- /**
- * @brief Get parity bit shift of PTE entry
- *
- * @return Parity bit shift
- */
- u8 imgmmu_get_pte_parity_shift(void);
- /**
- * @brief Set parity for PTE entry
- *
- * @return Entry with applied parity
- */
- void imgmmu_set_pte_parity(uint64_t *pte_entry);
- #define IMGMMU_GET_MAX_PAGE_SIZE() (max(imgmmu_get_page_size(), imgmmu_get_cpu_page_size()))
- /**
- * @}
- */
- /*-----------------------------------------------------------------------------
- * End of the public functions
- *---------------------------------------------------------------------------*/
- /**
- * @}
- */
- /*-----------------------------------------------------------------------------
- * End of the IMGMMU_lib documentation module
- *---------------------------------------------------------------------------*/
- #endif /* IMGMMU_MMU_H */
|