12f3d633aSShreyansh Jain /* SPDX-License-Identifier: BSD-3-Clause 2c5e6bc12SGagandeep Singh * Copyright 2018-2021 NXP 32f3d633aSShreyansh Jain */ 42f3d633aSShreyansh Jain 52f3d633aSShreyansh Jain #ifndef _DPAAX_IOVA_TABLE_H_ 62f3d633aSShreyansh Jain #define _DPAAX_IOVA_TABLE_H_ 72f3d633aSShreyansh Jain 82f3d633aSShreyansh Jain #include <unistd.h> 92f3d633aSShreyansh Jain #include <stdio.h> 102f3d633aSShreyansh Jain #include <string.h> 112f3d633aSShreyansh Jain #include <stdbool.h> 122f3d633aSShreyansh Jain #include <stdlib.h> 132f3d633aSShreyansh Jain #include <inttypes.h> 142f3d633aSShreyansh Jain #include <sys/stat.h> 152f3d633aSShreyansh Jain #include <sys/types.h> 162f3d633aSShreyansh Jain #include <dirent.h> 172f3d633aSShreyansh Jain #include <fcntl.h> 182f3d633aSShreyansh Jain #include <glob.h> 192f3d633aSShreyansh Jain #include <errno.h> 202f3d633aSShreyansh Jain #include <arpa/inet.h> 212f3d633aSShreyansh Jain 22*1094dd94SDavid Marchand #include <rte_compat.h> 232f3d633aSShreyansh Jain #include <rte_eal.h> 242f3d633aSShreyansh Jain #include <rte_branch_prediction.h> 252f3d633aSShreyansh Jain #include <rte_memory.h> 262f3d633aSShreyansh Jain #include <rte_malloc.h> 272f3d633aSShreyansh Jain 282f3d633aSShreyansh Jain struct dpaax_iovat_element { 292f3d633aSShreyansh Jain phys_addr_t start; /**< Start address of block of physical pages */ 302f3d633aSShreyansh Jain size_t len; /**< Difference of end-start for quick access */ 312f3d633aSShreyansh Jain uint64_t *pages; /**< VA for each physical page in this block */ 322f3d633aSShreyansh Jain }; 332f3d633aSShreyansh Jain 342f3d633aSShreyansh Jain struct dpaax_iova_table { 352f3d633aSShreyansh Jain unsigned int count; /**< No. of blocks of contiguous physical pages */ 36013b4c52SBruce Richardson struct dpaax_iovat_element entries[]; 372f3d633aSShreyansh Jain }; 382f3d633aSShreyansh Jain 392f3d633aSShreyansh Jain /* Pointer to the table, which is common for DPAA/DPAA2 and only a single 402f3d633aSShreyansh Jain * instance is required across net/crypto/event drivers. This table is 412f3d633aSShreyansh Jain * populated iff devices are found on the bus. 422f3d633aSShreyansh Jain */ 432f3d633aSShreyansh Jain extern struct dpaax_iova_table *dpaax_iova_table_p; 442f3d633aSShreyansh Jain 452f3d633aSShreyansh Jain /* Device tree file for memory layout is named 'memory@<addr>' where the 'addr' 462f3d633aSShreyansh Jain * is SoC dependent, or even Uboot fixup dependent. 472f3d633aSShreyansh Jain */ 482f3d633aSShreyansh Jain #define MEM_NODE_PATH_GLOB "/proc/device-tree/memory[@0-9]*/reg" 49c9d9825bSNipun Gupta /* For Virtual Machines memory node is at different path (below) */ 50c9d9825bSNipun Gupta #define MEM_NODE_PATH_GLOB_VM "/proc/device-tree/memory/reg" 512f3d633aSShreyansh Jain /* Device file should be multiple of 16 bytes, each containing 8 byte of addr 522f3d633aSShreyansh Jain * and its length. Assuming max of 5 entries. 532f3d633aSShreyansh Jain */ 542f3d633aSShreyansh Jain #define MEM_NODE_FILE_LEN ((16 * 5) + 1) 552f3d633aSShreyansh Jain 562f3d633aSShreyansh Jain /* Table is made up of DPAAX_MEM_SPLIT elements for each contiguous zone. This 572f3d633aSShreyansh Jain * helps avoid separate handling for cases where more than one size of hugepage 582f3d633aSShreyansh Jain * is supported. 592f3d633aSShreyansh Jain */ 602f3d633aSShreyansh Jain #define DPAAX_MEM_SPLIT (1<<21) 612f3d633aSShreyansh Jain #define DPAAX_MEM_SPLIT_MASK ~(DPAAX_MEM_SPLIT - 1) /**< Floor aligned */ 622f3d633aSShreyansh Jain #define DPAAX_MEM_SPLIT_MASK_OFF (DPAAX_MEM_SPLIT - 1) /**< Offset */ 632f3d633aSShreyansh Jain 642f3d633aSShreyansh Jain /* APIs exposed */ 656ae4ce89SHemant Agrawal __rte_internal 662f3d633aSShreyansh Jain int dpaax_iova_table_populate(void); 676ae4ce89SHemant Agrawal __rte_internal 682f3d633aSShreyansh Jain void dpaax_iova_table_depopulate(void); 696ae4ce89SHemant Agrawal __rte_internal 702f3d633aSShreyansh Jain int dpaax_iova_table_update(phys_addr_t paddr, void *vaddr, size_t length); 716ae4ce89SHemant Agrawal __rte_internal 722f3d633aSShreyansh Jain void dpaax_iova_table_dump(void); 732f3d633aSShreyansh Jain 74e3866e73SThomas Monjalon static inline void *dpaax_iova_table_get_va(phys_addr_t paddr) __rte_hot; 752f3d633aSShreyansh Jain 762f3d633aSShreyansh Jain static inline void * dpaax_iova_table_get_va(phys_addr_t paddr)772f3d633aSShreyansh Jaindpaax_iova_table_get_va(phys_addr_t paddr) { 782f3d633aSShreyansh Jain unsigned int i = 0, index; 792f3d633aSShreyansh Jain void *vaddr = 0; 802f3d633aSShreyansh Jain phys_addr_t paddr_align = paddr & DPAAX_MEM_SPLIT_MASK; 812f3d633aSShreyansh Jain size_t offset = paddr & DPAAX_MEM_SPLIT_MASK_OFF; 822f3d633aSShreyansh Jain struct dpaax_iovat_element *entry; 832f3d633aSShreyansh Jain 8429ba8d94SShreyansh Jain if (unlikely(dpaax_iova_table_p == NULL)) 8529ba8d94SShreyansh Jain return NULL; 8629ba8d94SShreyansh Jain 872f3d633aSShreyansh Jain entry = dpaax_iova_table_p->entries; 882f3d633aSShreyansh Jain 892f3d633aSShreyansh Jain do { 902f3d633aSShreyansh Jain if (unlikely(i > dpaax_iova_table_p->count)) 912f3d633aSShreyansh Jain break; 922f3d633aSShreyansh Jain 932f3d633aSShreyansh Jain if (paddr_align < entry[i].start) { 942f3d633aSShreyansh Jain /* Incorrect paddr; Not in memory range */ 952f3d633aSShreyansh Jain return NULL; 962f3d633aSShreyansh Jain } 972f3d633aSShreyansh Jain 982f3d633aSShreyansh Jain if (paddr_align > (entry[i].start + entry[i].len)) { 992f3d633aSShreyansh Jain i++; 1002f3d633aSShreyansh Jain continue; 1012f3d633aSShreyansh Jain } 1022f3d633aSShreyansh Jain 1032f3d633aSShreyansh Jain /* paddr > entry->start && paddr <= entry->(start+len) */ 1042f3d633aSShreyansh Jain index = (paddr_align - entry[i].start)/DPAAX_MEM_SPLIT; 105c5e6bc12SGagandeep Singh /* paddr is within range, but no vaddr entry ever written 106c5e6bc12SGagandeep Singh * at index 107c5e6bc12SGagandeep Singh */ 108c5e6bc12SGagandeep Singh if ((void *)(uintptr_t)entry[i].pages[index] == NULL) 109c5e6bc12SGagandeep Singh return NULL; 110c5e6bc12SGagandeep Singh 1112f3d633aSShreyansh Jain vaddr = (void *)((uintptr_t)entry[i].pages[index] + offset); 1122f3d633aSShreyansh Jain break; 1132f3d633aSShreyansh Jain } while (1); 1142f3d633aSShreyansh Jain 1152f3d633aSShreyansh Jain return vaddr; 1162f3d633aSShreyansh Jain } 1172f3d633aSShreyansh Jain 1182f3d633aSShreyansh Jain #endif /* _DPAAX_IOVA_TABLE_H_ */ 119