1 \r
2 /******************************************************************************\r
3 * FILE netapi_vm.c\r
4 * PURPOSE: Memory allocator for NETAPI and related utilities\r
5 * -- using MSMC for descriptors/buffers (current), use CMA (future) \r
6 ******************************************************************************\r
7 * FILE NAME: netapi_vm.c\r
8 *\r
9 * DESCRIPTION: Memory allocator for netapi \r
10 * This is only a permanent memory allocator.\r
11 *\r
12 * REVISION HISTORY:\r
13 *\r
14 * Copyright (c) Texas Instruments Incorporated 2010-2011\r
15 * \r
16 * Redistribution and use in source and binary forms, with or without \r
17 * modification, are permitted provided that the following conditions \r
18 * are met:\r
19 *\r
20 * Redistributions of source code must retain the above copyright \r
21 * notice, this list of conditions and the following disclaimer.\r
22 *\r
23 * Redistributions in binary form must reproduce the above copyright\r
24 * notice, this list of conditions and the following disclaimer in the \r
25 * documentation and/or other materials provided with the \r
26 * distribution.\r
27 *\r
28 * Neither the name of Texas Instruments Incorporated nor the names of\r
29 * its contributors may be used to endorse or promote products derived\r
30 * from this software without specific prior written permission.\r
31 *\r
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
36 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
37 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
38 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
39 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
40 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
41 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
42 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
43 *\r
44 */\r
45 \r
46 #include <stdint.h>\r
47 #include <stdio.h>\r
48 #include <string.h>\r
49 #include <sys/types.h>\r
50 #include <sys/stat.h>\r
51 #include <fcntl.h>\r
52 #include <sys/mman.h>\r
53 #include <errno.h>\r
54 #include <unistd.h>\r
55 \r
56 #include <ti/drv/nwal/nwal.h> \r
57 #include "netapi_vm.h"\r
58 #include <sys/ioctl.h>\r
59 #include "tools/module/netapimod.h"\r
60 \r
61 \r
62 /***********************RAW MEMORY ALLOCATION & TRANSLATION*************************/\r
63 /* Macro to align x to y */\r
64 #define align(x,y) ((x + y) & (~y))\r
65 \r
66 uint8_t *netapi_VM_mem_start_phy = (uint8_t*)0;\r
67 uint8_t *netapi_VM_mem_start = (uint8_t*)0;\r
68 uint8_t *netapi_VM_mem_end = (uint8_t*)0;\r
69 uint8_t *netapi_VM_mem_end_phy = (uint8_t*)0;\r
70 static uint8_t *netapi_VM_mem_alloc_ptr = (uint8_t*)0;\r
71 static uint32_t netapi_VM_mem_size = 0;\r
72 \r
73 \r
74 \r
75 /* File descriptor for /dev/mem */ \r
76 static int dev_mem_fd;\r
77 static int our_netapi_module_fd;\r
78 #ifndef USE_MODULE_MMAP\r
79 static int temp_fd;\r
80 #endif\r
81 \r
82 nwal_Bool_t netapi_VM_memAllocInit\r
83 (\r
84 uint8_t *addr, /* Physical address */\r
85 uint32_t size /* Size of block */\r
86 )\r
87 {\r
88 void *map_base; \r
89 \r
90 //always open dev/mem, since we need for QM, CPPI, etc\r
91 if((dev_mem_fd = open("/dev/mem", (O_RDWR | O_SYNC))) == -1)\r
92 {\r
93 printf(">netapi_VM_memAllocInit: Failed to open \"dev/mem\" err=%s\n",\r
94 strerror(errno));\r
95 return nwal_FALSE;\r
96 }\r
97 \r
98 #ifdef NETAPI_USE_MSMC\r
99 // memory map in addr to addr+size (msmc)\r
100 map_base = netapi_VM_memMap ((void *)addr, size); \r
101 \r
102 if (!map_base)\r
103 {\r
104 printf(">netapi_VM_memAllocInit: Failed to mmap addr (0x%x)", addr);\r
105 return nwal_FALSE;\r
106 }\r
107 \r
108 printf(">netapi_VM_memAllocInit (uncached msmc) Phy Addr %x Memory (%d bytes) mapped at address %p.\n", addr,size, map_base); \r
109 #else \r
110 //use cached DDR. This requires NETAPI kernel module\r
111 our_netapi_module_fd=netapi_utilModInit();\r
112 \r
113 if (our_netapi_module_fd == -1) {\r
114 printf(">netapi_VM_memAllocInit: failed to open /dev/netapi: '%s'\n", strerror(errno));\r
115 return nwal_FALSE;\r
116 }\r
117 addr= ( uint8_t *) netapi_utilGetPhysOfBufferArea(); //get address that was allocated for us by kernela module */\r
118 size = netapi_utilGetSizeOfBufferArea(); //get the size that was allocated\r
119 #ifdef USE_MODULE_MMAP\r
120 map_base = (void *) netapi_utilGetVaOfBufferArea(); //mmap into our space, return va\r
121 #else\r
122 if( (temp_fd = open("/dev/mem", O_RDWR )) == -1) {\r
123 printf(">netapi_VM_memAllocInit: failed to open dev/mem again cached err=%d\n",errno);\r
124 return nwal_FALSE; \r
125 }\r
126 \r
127 map_base = mmap(0,size , PROT_READ | PROT_WRITE, MAP_SHARED, temp_fd, addr);\r
128 if(map_base == (void *) -1) {\r
129 printf(">netapi_VM_memAllocInit: failed to mmap CMA area at phy %x err=%d\n",\r
130 addr, errno); \r
131 return nwal_FALSE;\r
132 }\r
133 #endif\r
134 printf(">netapi_VM_memAllocInit: (cached ddr) Phy Addr %x Memory (%d bytes) mapped at address %p.\n", addr,size, map_base); \r
135 #endif\r
136 \r
137 netapi_VM_mem_alloc_ptr = netapi_VM_mem_start = map_base;\r
138 netapi_VM_mem_size = size;\r
139 netapi_VM_mem_end = netapi_VM_mem_start + netapi_VM_mem_size;\r
140 netapi_VM_mem_start_phy = addr;\r
141 netapi_VM_mem_end_phy = netapi_VM_mem_start_phy + netapi_VM_mem_size;\r
142 return nwal_TRUE;\r
143 }\r
144 \r
145 void* netapi_VM_memAlloc\r
146 (\r
147 uint32_t size,\r
148 uint32_t align\r
149 )\r
150 {\r
151 uint32_t key;\r
152 uint8_t *alloc_ptr;\r
153 void *p_block =NULL;\r
154 \r
155 Osal_stubCsEnter();\r
156 alloc_ptr = (uint8_t*)align((uint32_t)netapi_VM_mem_alloc_ptr, align);\r
157 if ((alloc_ptr + size) < netapi_VM_mem_end)\r
158 {\r
159 p_block =(void *)alloc_ptr;\r
160 netapi_VM_mem_alloc_ptr = alloc_ptr + size;\r
161 Osal_stubCsExit(key);\r
162 memset (p_block, 0, size);\r
163 }\r
164 else \r
165 {\r
166 Osal_stubCsExit(key);\r
167 }\r
168 return p_block;\r
169 }\r
170 uint32_t xtraLogs=0;\r
171 /* Api to map the give physical address to virtual memory space */\r
172 void *netapi_VM_memMap\r
173 (\r
174 void *addr, /* Physical address */\r
175 uint32_t size /* Size of block */\r
176 )\r
177 {\r
178 void *map_base,*virt_addr,*tmpAddr;\r
179 uint32_t page_sz;\r
180 long retval;\r
181 uint32_t mask = (size-1);\r
182 uint32_t offset;\r
183 \r
184 retval = sysconf(_SC_PAGE_SIZE);\r
185 if (retval == -1)\r
186 {\r
187 printf(">netapi_VM_memMap: Failed to get page size err=%s\n",\r
188 strerror(errno));\r
189 return (void *)0;\r
190 }\r
191 \r
192 page_sz = (uint32_t)retval;\r
193 \r
194 if (size%page_sz)\r
195 {\r
196 printf(">netapi_VM_memMap: error: block size not aligned to page size\n");\r
197 return (void *)0;\r
198 }\r
199 \r
200 if ((uint32_t)addr%page_sz)\r
201 {\r
202 printf(">netapi_VM_memMap: error: addr not aligned to page size\n");\r
203 return (void *)0;\r
204 }\r
205 \r
206 map_base = mmap(0, size, (PROT_READ|PROT_WRITE), MAP_SHARED, dev_mem_fd, (off_t)addr & ~mask);\r
207 if(map_base == (void *) -1) \r
208 {\r
209 printf(">netapi_VM_memMap: Failed to mmap \"dev/mem\" err=%s\n",\r
210 strerror(errno));\r
211 return (void *)0;\r
212 }\r
213 virt_addr = map_base + ((off_t)addr & mask);\r
214 if(xtraLogs)\r
215 {\r
216 printf(">netapi_VM_memMap:Memory mapped Begin Address 0x%x Read Value: 0x%x.\n", virt_addr,*((unsigned long *)virt_addr));\r
217 // offset = size/(sizeof(unsigned long));\r
218 // tmpAddr = (unsigned long *)virt_addr + offset-1;\r
219 tmpAddr = (uint8_t *)virt_addr + 0x6800c;\r
220 printf("netapi_VM_memMap:Memory mapped End Address 0x%x Read Value: 0x%x.\n", (unsigned long *)tmpAddr ,*((unsigned long *)tmpAddr));\r
221 *((unsigned long *)tmpAddr) = 0x1234;\r
222 printf("netapi_VM_memMap:Memory mapped End Address 0x%x Write Value: 0x%x.\n", (unsigned long *)tmpAddr ,*((unsigned long *)tmpAddr));\r
223 \r
224 }\r
225 return(virt_addr);\r
226 }\r
227 \r
228 /***************************************************************/\r
229 /*************** Memory Initilaization**************************/\r
230 /***************************************************************/\r
231 /* for now use msmc */\r
232 /* Total Permanent memory required in NWAL test\r
233 * for Packet buffers & descriptor buffers\r
234 */\r
235 #define NETAPI_PERM_MEM_SZ (TUNE_NETAPI_PERM_MEM_SZ) \r
236 \r
237 /* Physical address map & size for various subsystems */\r
238 #define QMSS_CFG_BASE_ADDR CSL_QM_SS_CFG_QUE_PEEK_REGS\r
239 #define QMSS_CFG_BLK_SZ (1*1024*1024)\r
240 #define QMSS_DATA_BASE_ADDR 0x44020000 \r
241 #define QMSS_DATA_BLK_SZ (0x60000)\r
242 #define SRIO_CFG_BASE_ADDR CSL_SRIO_CONFIG_REGS\r
243 #define SRIO_CFG_BLK_SZ (132*1024)\r
244 #define PASS_CFG_BASE_ADDR CSL_PA_SS_CFG_REGS \r
245 #define PASS_CFG_BLK_SZ (1*1024*1024)\r
246 \r
247 #define MSMC_SRAM_BASE_ADDR CSL_MSMC_SRAM_REGS\r
248 \r
249 /* Global variables to hold virtual address of various subsystems */\r
250 void *netapi_VM_qmssCfgVaddr;\r
251 void *netapi_VM_qmssDataVaddr;\r
252 void *netapi_VM_srioCfgVaddr;\r
253 void *netapi_VM_passCfgVaddr;\r
254 \r
255 /* also for our descriptor area */\r
256 unsigned char *netapi_VM_QMemLocalDescRam=NULL;\r
257 unsigned char *netapi_VM_QMemGlobalDescRam=NULL;\r
258 \r
259 /* finaly SA context area */\r
260 unsigned char *netapi_VM_SaContextVaddr=NULL;\r
261 \r
262 /************************************************\r
263 * teardown VM memory\r
264 ***********************************************/\r
265 void netapi_VM_memory_teardown(void)\r
266 {\r
267 netapi_utilModClose();\r
268 close(dev_mem_fd);\r
269 #ifndef USE_MODULE_MMAP\r
270 close(temp_fd);\r
271 #endif\r
272 }\r
273 /*************************************************\r
274 * setup VM memory\r
275 ************************************************/\r
276 int netapi_VM_memory_setup(void)\r
277 {\r
278 /* (1) big chunck of memory out of MSMC or DDR via kernel CMA */\r
279 #ifdef NETAPI_USE_DDR\r
280 if (netapi_VM_memAllocInit( NULL, 0) == nwal_FALSE) {\r
281 printf(">netapi ERROR: netapi_V_MmemAllocInit from DDR/CMA failed\n");\r
282 return (-1);\r
283 }\r
284 #else //uncached MSMC \r
285 if (netapi_VM_memAllocInit((uint8_t*)MSMC_SRAM_BASE_ADDR,\r
286 NETAPI_PERM_MEM_SZ) == nwal_FALSE) {\r
287 printf(">netapi ERROR: netapi_V_MmemAllocInit from MSMC failed\n");\r
288 return (-1);\r
289 }\r
290 #endif\r
291 \r
292 /* (2) Create virtual memory maps for peripherals */\r
293 /* (2a) QMSS CFG Regs */\r
294 netapi_VM_qmssCfgVaddr = netapi_VM_memMap((void*)QMSS_CFG_BASE_ADDR,\r
295 QMSS_CFG_BLK_SZ);\r
296 if (!netapi_VM_qmssCfgVaddr)\r
297 {\r
298 printf(">netapi ERROR: Failed to map QMSS CFG registers\n");\r
299 return (-1);\r
300 }\r
301 printf(">netapi QMSS_CFG_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)QMSS_CFG_BASE_ADDR, netapi_VM_qmssCfgVaddr);\r
302 \r
303 /* (2b) QMSS DATA Regs */\r
304 netapi_VM_qmssDataVaddr = netapi_VM_memMap((void*)QMSS_DATA_BASE_ADDR,\r
305 QMSS_DATA_BLK_SZ);\r
306 if (!netapi_VM_qmssDataVaddr)\r
307 {\r
308 printf(">netapi ERROR: Failed to map QMSS DATA registers\n");\r
309 return (-1);\r
310 }\r
311 printf(">netapi QMSS_DATA_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)QMSS_DATA_BASE_ADDR, netapi_VM_qmssDataVaddr);\r
312 \r
313 /* (2c) SRIO CFG Regs */\r
314 netapi_VM_srioCfgVaddr = netapi_VM_memMap((void*)SRIO_CFG_BASE_ADDR,\r
315 SRIO_CFG_BLK_SZ);\r
316 if (!netapi_VM_srioCfgVaddr)\r
317 {\r
318 printf(">netapi ERROR: Failed to map SRIO CFG registers\n");\r
319 return (-1);\r
320 }\r
321 printf(">netapi SRIO_CFG_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)SRIO_CFG_BASE_ADDR, netapi_VM_srioCfgVaddr);\r
322 \r
323 /* (2d) PASS CFG Regs */\r
324 netapi_VM_passCfgVaddr = netapi_VM_memMap((void*)PASS_CFG_BASE_ADDR,\r
325 PASS_CFG_BLK_SZ);\r
326 if (!netapi_VM_passCfgVaddr)\r
327 {\r
328 printf(">netapi ERROR: Failed to map PASS CFG registers\n");\r
329 return (-1);\r
330 }\r
331 printf(">netapi PASS_CFG_BASE_ADDR:0x%x Memory mapped at address %p.\n",(void*)PASS_CFG_BASE_ADDR, netapi_VM_passCfgVaddr);\r
332 \r
333 /* (2e) SA COntext area */\r
334 #ifdef NETAPI_ENABLE_SECURITY\r
335 #define SEC_CONTEXT_SZ 384 //not tunable\r
336 /* allocate 2x number of tunnels since we need one for inflow and one for data mode */\r
337 netapi_VM_SaContextVaddr = netapi_VM_memAlloc((TUNE_NETAPI_MAX_NUM_IPSEC_CHANNELS*2 *\r
338 SEC_CONTEXT_SZ),\r
339 128);\r
340 if (!netapi_VM_SaContextVaddr)\r
341 {\r
342 printf(">netapi ERROR: Failed to map SA context memory region\n");\r
343 return (-1);\r
344 }\r
345 printf(">netapi VM_SaContext: Memory mapped/allocated at address %p.\n", netapi_VM_SaContextVaddr);\r
346 \r
347 #else\r
348 netapi_VM_SaContextVaddr= (char *) NULL;\r
349 #endif\r
350 \r
351 /* (2f) Timer */\r
352 t64_memmap(dev_mem_fd);\r
353 \r
354 /* (3) Allocate 2 QM regions from continguous chunk above */\r
355 netapi_VM_QMemGlobalDescRam = (void *)netapi_VM_memAlloc((TUNE_NETAPI_NUM_GLOBAL_DESC *\r
356 TUNE_NETAPI_DESC_SIZE),\r
357 128);\r
358 netapi_VM_QMemLocalDescRam = (void *)netapi_VM_memAlloc((TUNE_NETAPI_NUM_LOCAL_DESC *\r
359 TUNE_NETAPI_DESC_SIZE),\r
360 128);\r
361 printf(">netapi local desc region=%x global desc region=%x\n", netapi_VM_QMemLocalDescRam,netapi_VM_QMemGlobalDescRam);\r
362 \r
363 return 1;\r
364 \r
365 }\r
366 \r