octeon: native driver for Marvell Octeon SoC
[vpp.git] / src / plugins / dev_octeon / roc_helper.c
1 /*
2  * Copyright (c) 2023 Marvell.
3  * SPDX-License-Identifier: Apache-2.0
4  * https://spdx.org/licenses/Apache-2.0.html
5  */
6
7 #include <vnet/vnet.h>
8 #include <vlib/pci/pci.h>
9 #include <vlib/linux/vfio.h>
10 #include <base/roc_api.h>
11 #include <common.h>
12
13 static oct_plt_memzone_list_t memzone_list;
14
15 static inline void
16 oct_plt_log (oct_plt_log_level_t level, oct_plt_log_class_t cls, char *fmt,
17              ...)
18 {
19   vlib_log ((vlib_log_level_t) level, cls, fmt);
20 }
21
22 static inline void
23 oct_plt_spinlock_init (oct_plt_spinlock_t *p)
24 {
25   clib_spinlock_init ((clib_spinlock_t *) p);
26 }
27
28 static void
29 oct_plt_spinlock_lock (oct_plt_spinlock_t *p)
30 {
31   clib_spinlock_lock ((clib_spinlock_t *) p);
32 }
33
34 static void
35 oct_plt_spinlock_unlock (oct_plt_spinlock_t *p)
36 {
37   clib_spinlock_unlock ((clib_spinlock_t *) p);
38 }
39
40 static int
41 oct_plt_spinlock_trylock (oct_plt_spinlock_t *p)
42 {
43   return clib_spinlock_trylock ((clib_spinlock_t *) p);
44 }
45
46 static u64
47 oct_plt_get_thread_index (void)
48 {
49   return __os_thread_index;
50 }
51
52 static void
53 oct_drv_physmem_free (vlib_main_t *vm, void *mem)
54 {
55   if (!mem)
56     {
57       clib_warning ("Invalid address %p", mem);
58       return;
59     }
60
61   vlib_physmem_free (vm, mem);
62 }
63
64 static void *
65 oct_drv_physmem_alloc (vlib_main_t *vm, u32 size, u32 align)
66 {
67   clib_error_t *error = NULL;
68   uword *mem = NULL;
69
70   if (align)
71     {
72       /* Force cache line alloc in case alignment is less than cache line */
73       align = align < CLIB_CACHE_LINE_BYTES ? CLIB_CACHE_LINE_BYTES : align;
74       mem = vlib_physmem_alloc_aligned_on_numa (vm, size, align, 0);
75     }
76   else
77     mem =
78       vlib_physmem_alloc_aligned_on_numa (vm, size, CLIB_CACHE_LINE_BYTES, 0);
79   if (!mem)
80     return NULL;
81
82   error = vfio_map_physmem_page (vm, mem);
83   if (error)
84     goto report_error;
85
86   clib_memset (mem, 0, size);
87   return mem;
88
89 report_error:
90   clib_error_report (error);
91   oct_drv_physmem_free (vm, mem);
92
93   return NULL;
94 }
95
96 static void
97 oct_plt_free (void *addr)
98 {
99   vlib_main_t *vm = vlib_get_main ();
100
101   oct_drv_physmem_free ((void *) vm, addr);
102 }
103
104 static void *
105 oct_plt_zmalloc (u32 size, u32 align)
106 {
107   vlib_main_t *vm = vlib_get_main ();
108
109   return oct_drv_physmem_alloc (vm, size, align);
110 }
111
112 static oct_plt_memzone_t *
113 memzone_get (u32 index)
114 {
115   if (index == ((u32) ~0))
116     return 0;
117
118   return pool_elt_at_index (memzone_list.mem_pool, index);
119 }
120
121 static int
122 oct_plt_memzone_free (const oct_plt_memzone_t *name)
123 {
124   uword *p;
125   p = hash_get_mem (memzone_list.memzone_by_name, name);
126
127   if (p[0] == ((u32) ~0))
128     return -EINVAL;
129
130   hash_unset_mem (memzone_list.memzone_by_name, name);
131
132   pool_put_index (memzone_list.mem_pool, p[0]);
133
134   return 0;
135 }
136
137 static oct_plt_memzone_t *
138 oct_plt_memzone_lookup (const char *name)
139 {
140   uword *p;
141   p = hash_get_mem (memzone_list.memzone_by_name, name);
142   if (p)
143     return memzone_get (p[0]);
144
145   return 0;
146 }
147
148 static oct_plt_memzone_t *
149 oct_plt_memzone_reserve_aligned (const char *name, u64 len, u8 socket,
150                                  u32 flags, u32 align)
151 {
152   oct_plt_memzone_t *mem_pool;
153   void *p = NULL;
154
155   pool_get_zero (memzone_list.mem_pool, mem_pool);
156
157   p = oct_plt_zmalloc (len, align);
158   if (!p)
159     return NULL;
160
161   mem_pool->addr = p;
162   mem_pool->index = mem_pool - memzone_list.mem_pool;
163   hash_set_mem (memzone_list.memzone_by_name, name, mem_pool->index);
164
165   return mem_pool;
166 }
167
168 oct_plt_init_param_t oct_plt_init_param = {
169   .oct_plt_log_reg_class = vlib_log_register_class,
170   .oct_plt_log = oct_plt_log,
171   .oct_plt_free = oct_plt_free,
172   .oct_plt_zmalloc = oct_plt_zmalloc,
173   .oct_plt_memzone_free = oct_plt_memzone_free,
174   .oct_plt_memzone_lookup = oct_plt_memzone_lookup,
175   .oct_plt_memzone_reserve_aligned = oct_plt_memzone_reserve_aligned,
176   .oct_plt_spinlock_init = oct_plt_spinlock_init,
177   .oct_plt_spinlock_lock = oct_plt_spinlock_lock,
178   .oct_plt_spinlock_unlock = oct_plt_spinlock_unlock,
179   .oct_plt_spinlock_trylock = oct_plt_spinlock_trylock,
180   .oct_plt_get_thread_index = oct_plt_get_thread_index,
181 };