1 /*
2  * Copyright © 2014 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including
13  * the next paragraph) shall be included in all copies or substantial
14  * portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  */
25 
26 #ifndef LIBHSAKMT_H_INCLUDED
27 #define LIBHSAKMT_H_INCLUDED
28 
29 #include "hsakmt.h"
30 #include <pthread.h>
31 #include <stdint.h>
32 #include <limits.h>
33 #if defined(__FreeBSD__) || defined(__DragonFly__)
34 #include <sys/mman.h>
35 #endif
36 #include <pci/pci.h>
37 
38 extern int kfd_fd;
39 extern unsigned long kfd_open_count;
40 extern pthread_mutex_t hsakmt_mutex;
41 extern bool is_dgpu;
42 
43 #undef HSAKMTAPI
44 #define HSAKMTAPI __attribute__((visibility ("default")))
45 
46 /*Avoid pointer-to-int-cast warning*/
47 #define PORT_VPTR_TO_UINT64(vptr) ((uint64_t)(unsigned long)(vptr))
48 
49 /*Avoid int-to-pointer-cast warning*/
50 #define PORT_UINT64_TO_VPTR(v) ((void*)(unsigned long)(v))
51 
52 #define CHECK_KFD_OPEN() \
53 	do { if (kfd_open_count == 0) return HSAKMT_STATUS_KERNEL_IO_CHANNEL_NOT_OPENED; } while (0)
54 
55 extern int PAGE_SIZE;
56 extern int PAGE_SHIFT;
57 
58 /* VI HW bug requires this virtual address alignment */
59 #define TONGA_PAGE_SIZE 0x8000
60 
61 /* 64KB BigK fragment size for TLB efficiency */
62 #define GPU_BIGK_PAGE_SIZE (1 << 16)
63 
64 /* 2MB huge page size for 4-level page tables on Vega10 and later GPUs */
65 #define GPU_HUGE_PAGE_SIZE (2 << 20)
66 
67 #define CHECK_PAGE_MULTIPLE(x) \
68 	do { if ((uint64_t)PORT_VPTR_TO_UINT64(x) % PAGE_SIZE) return HSAKMT_STATUS_INVALID_PARAMETER; } while(0)
69 
70 #define ALIGN_UP(x,align) (((uint64_t)(x) + (align) - 1) & ~(uint64_t)((align)-1))
71 #define ALIGN_UP_32(x,align) (((uint32_t)(x) + (align) - 1) & ~(uint32_t)((align)-1))
72 #define PAGE_ALIGN_UP(x) ALIGN_UP(x,PAGE_SIZE)
73 #define BITMASK(n) (((n) < sizeof(1ULL) * CHAR_BIT ? (1ULL << (n)) : 0) - 1ULL)
74 #define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
75 
76 /* HSA Thunk logging usage */
77 extern int hsakmt_debug_level;
78 #define hsakmt_print(level, fmt, ...) \
79 	do { if (level <= hsakmt_debug_level) fprintf(stderr, fmt, ##__VA_ARGS__); } while (0)
80 #define HSAKMT_DEBUG_LEVEL_DEFAULT	-1
81 #define HSAKMT_DEBUG_LEVEL_ERR		3
82 #define HSAKMT_DEBUG_LEVEL_WARNING	4
83 #define HSAKMT_DEBUG_LEVEL_INFO		6
84 #define HSAKMT_DEBUG_LEVEL_DEBUG	7
85 #define pr_err(fmt, ...) \
86 	hsakmt_print(HSAKMT_DEBUG_LEVEL_ERR, fmt, ##__VA_ARGS__)
87 #define pr_warn(fmt, ...) \
88 	hsakmt_print(HSAKMT_DEBUG_LEVEL_WARNING, fmt, ##__VA_ARGS__)
89 #define pr_info(fmt, ...) \
90 	hsakmt_print(HSAKMT_DEBUG_LEVEL_INFO, fmt, ##__VA_ARGS__)
91 #define pr_debug(fmt, ...) \
92 	hsakmt_print(HSAKMT_DEBUG_LEVEL_DEBUG, fmt, ##__VA_ARGS__)
93 
94 enum asic_family_type {
95 	CHIP_KAVERI = 0,
96 	CHIP_HAWAII,
97 	CHIP_CARRIZO,
98 	CHIP_TONGA,
99 	CHIP_FIJI,
100 	CHIP_POLARIS10,
101 	CHIP_POLARIS11,
102 	CHIP_VEGA10,
103 	CHIP_RAVEN,
104 	CHIP_VEGA20
105 };
106 #define IS_DGPU(chip) ((chip) != CHIP_KAVERI && (chip) != CHIP_CARRIZO && \
107 		       (chip) != CHIP_RAVEN)
108 #define IS_SOC15(chip) ((chip) >= CHIP_VEGA10)
109 
110 HSAKMT_STATUS validate_nodeid(uint32_t nodeid, uint32_t *gpu_id);
111 HSAKMT_STATUS gpuid_to_nodeid(uint32_t gpu_id, uint32_t* node_id);
112 uint16_t get_device_id_by_node(HSAuint32 node_id);
113 uint16_t get_device_id_by_gpu_id(HSAuint32 gpu_id);
114 int get_drm_render_fd_by_gpu_id(HSAuint32 gpu_id);
115 HSAKMT_STATUS validate_nodeid_array(uint32_t **gpu_id_array,
116 		uint32_t NumberOfNodes, uint32_t *NodeArray);
117 
118 HSAKMT_STATUS topology_sysfs_get_gpu_id(uint32_t node_id, uint32_t *gpu_id);
119 HSAKMT_STATUS topology_sysfs_get_node_props(uint32_t node_id, HsaNodeProperties *props,
120 		uint32_t *gpu_id, struct pci_access* pacc);
121 HSAKMT_STATUS topology_sysfs_get_system_props(HsaSystemProperties *props);
122 bool topology_is_dgpu(uint16_t device_id);
123 bool topology_is_svm_needed(uint16_t device_id);
124 HSAKMT_STATUS topology_get_asic_family(uint16_t device_id,
125 					enum asic_family_type *asic);
126 
127 HSAuint32 PageSizeFromFlags(unsigned int pageSizeFlags);
128 
129 void* allocate_exec_aligned_memory_gpu(uint32_t size, uint32_t align,
130 				       uint32_t NodeId, bool NonPaged,
131 				       bool DeviceLocal);
132 void free_exec_aligned_memory_gpu(void *addr, uint32_t size, uint32_t align);
133 HSAKMT_STATUS init_process_doorbells(unsigned int NumNodes);
134 void destroy_process_doorbells(void);
135 HSAKMT_STATUS init_device_debugging_memory(unsigned int NumNodes);
136 void destroy_device_debugging_memory(void);
137 HSAKMT_STATUS init_counter_props(unsigned int NumNodes);
138 void destroy_counter_props(void);
139 
140 extern int kmtIoctl(int fd, unsigned long request, void *arg);
141 
142 /* Void pointer arithmetic (or remove -Wpointer-arith to allow void pointers arithmetic) */
143 #define VOID_PTR_ADD32(ptr,n) (void*)((uint32_t*)(ptr) + n)/*ptr + offset*/
144 #define VOID_PTR_ADD(ptr,n) (void*)((uint8_t*)(ptr) + n)/*ptr + offset*/
145 #define VOID_PTR_SUB(ptr,n) (void*)((uint8_t*)(ptr) - n)/*ptr - offset*/
146 #define VOID_PTRS_SUB(ptr1,ptr2) (uint64_t)((uint8_t*)(ptr1) - (uint8_t*)(ptr2)) /*ptr1 - ptr2*/
147 
148 #define MIN(a, b) ({				\
149 	typeof(a) tmp1 = (a), tmp2 = (b);	\
150 	tmp1 < tmp2 ? tmp1 : tmp2; })
151 
152 #define MAX(a, b) ({				\
153 	typeof(a) tmp1 = (a), tmp2 = (b);	\
154 	tmp1 > tmp2 ? tmp1 : tmp2; })
155 
156 void clear_events_page(void);
157 void fmm_clear_all_mem(void);
158 void clear_process_doorbells(void);
159 #endif
160