xref: /dpdk/drivers/common/dpaax/dpaax_iova_table.h (revision 1094dd940ec0cc4e3ce2c5cd94807350855a17f9)
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 Jain dpaax_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