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