1/*- 2 * Copyright (c) 2008 The NetBSD Foundation, Inc. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to The NetBSD Foundation 6 * by Coyote Point Systems, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30/*- 31 * Copyright (C) 2001-2003 by NBMK Encryption Technologies. 32 * All rights reserved. 33 * 34 * NBMK Encryption Technologies provides no support of any kind for 35 * this software. Questions or concerns about it may be addressed to 36 * the members of the relevant open-source community at 37 * <tech-crypto@netbsd.org>. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions are 41 * met: 42 * 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 46 * 2. Redistributions in binary form must reproduce the above 47 * copyright notice, this list of conditions and the following 48 * disclaimer in the documentation and/or other materials provided 49 * with the distribution. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 52 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 53 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 54 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 55 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 56 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 57 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 61 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 */ 63 64static char const n8_id[] = "$Id: n8_memory_bsd.c,v 1.4 2009/05/12 08:23:01 cegger Exp $"; 65/*****************************************************************************/ 66/** @file n8_memory_bsd.c 67 * @brief NetOctaveMemory Services - FreeBSD-specific support routines. 68 * 69 * This file contains all FreeBSD-specific support routines for the large 70 * allocation services used by the driver. The cross-platform memory management 71 * code uses these routines. 72 *****************************************************************************/ 73 74/***************************************************************************** 75 * Revision history: 76 * 05/12/03 brr Modified user pools to take advantage of the support for 77 * multiple memory banks. 78 * 05/08/03 brr Dimension arrays to allow of multiple user pools. 79 * 05/05/03 brr Moved memory functions here from helper.c. 80 * 04/22/03 brr Change wait flag passed to contigmalloc to M_WAITOK. 81 * 04/22/03 brr Clean up comments & add debug statements. 82 * Removed redundant parameter from n8_FreeLargeAllocation. 83 * 04/21/03 brr Added support for multiple memory banks. 84 * 11/01/02 brr Correctly deallocate memory resources. 85 * 10/25/02 brr Temporarily comment out call to contigfree(). 86 * 10/22/02 brr File created. 87 ****************************************************************************/ 88/** @defgroup NSP2000Driver NSP2000 Device Driver - FreeBSD version. 89 */ 90 91 92#include "helper.h" 93#include "n8_malloc_common.h" 94#include "n8_OS_intf.h" 95#include "n8_memory.h" 96#include "n8_driver_parms.h" 97#include <uvm/uvm.h> 98#include <machine/pmap.h> 99#include "nsp.h" 100 101extern NspInstance_t NSPDeviceTable_g[]; 102static unsigned long MemBaseAddress_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS]; 103static unsigned long MemTopAddress_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS]; 104static unsigned long MemSize_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS]; 105static void *BasePointer_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS]; 106static bus_dmamap_t DmaMap_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS]; 107static int Rseg_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS]; 108static bus_dma_segment_t Seg_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS]; 109 110/***************************************************************************** 111 * n8_vmalloc 112 *****************************************************************************/ 113/** @ingroup NSP2000Driver 114 * @brief n8_memory - Allocates and clears a buffer. 115 * 116 * This routine abstracts memory allocation for the functions in the driver. 117 * 118 * @param size RO: Specifies the desired allocation size 119 * 120 * @return 121 * Virtual address of the memory allocation, NULL if failed. 122 * 123 * 124 * @par Errors: 125 * See return section for error information. 126 *****************************************************************************/ 127 128void * 129n8_vmalloc(unsigned long size) 130{ 131 N8_UmallocHdr_t *m; 132 133 if (size) { 134 m = malloc(size, M_DEVBUF, M_WAITOK); 135 136 if (m) { 137 memset(m, 0, sizeof (*m)); 138 139 return m+1; 140 } 141 } 142 143 return 0; 144} 145 146/***************************************************************************** 147 * n8_vfree 148 *****************************************************************************/ 149/** @ingroup NSP2000Driver 150 * @brief n8_memory - Frees a buffer allocated by n8_vmalloc. 151 * 152 * This routine abstracts memory allocation for the functions in the driver. 153 * 154 * @param a RO: Specifies the address to free. 155 * 156 * @return 157 * None. 158 * 159 * 160 * @par Errors: 161 * See return section for error information. 162 *****************************************************************************/ 163 164void 165n8_vfree(void *a) 166{ 167 N8_UmallocHdr_t *m = a; 168 169 if (m) { 170 free(m-1, M_DEVBUF); 171 } 172} 173 174/***************************************************************************** 175 * N8_PhysToVirt 176 *****************************************************************************/ 177/** @ingroup NSP2000Driver 178 * @brief N8_PhysToVirt - Converts a physical address to it virtual address 179 * 180 * @param phys RO: Physical address to convert. 181 * 182 * @return 183 * Virtual address of phys 184 * 185 * 186 * @par Errors: 187 *****************************************************************************/ 188 189void * 190N8_PhysToVirt(unsigned long phys) 191{ 192 unsigned long offset; 193 int bankIndex = N8_MEMBANK_QUEUE; 194 int ctr; 195 void *virtaddr; 196 197 for (ctr = 0; ctr < (N8_MEMBANK_MAX + DEF_USER_POOL_BANKS); ctr++) 198 { 199 if ((phys >= MemBaseAddress_g[ctr]) && 200 (phys < MemTopAddress_g[ctr])) 201 { 202 bankIndex = ctr; 203 break; 204 } 205 } 206 if (ctr >= (N8_MEMBANK_MAX + DEF_USER_POOL_BANKS)) { 207 printf("N8_PhysToVirt(0x%lx) ran out of banks\n", phys); 208 } 209 210 offset = phys - MemBaseAddress_g[bankIndex]; 211 212 virtaddr = (void *)(offset + (unsigned long)BasePointer_g[bankIndex]); 213 return virtaddr; 214} 215 216 217 218/***************************************************************************** 219 * N8_VirtToPhys 220 *****************************************************************************/ 221/** @ingroup NSP2000Driver 222 * @brief Convert a virtual address to a physical address. 223 * 224 * This routine abstracts the Linux system call to convert a virtual address 225 * to a physical address. 226 * 227 * @param virtaddr RO: Specifies the physical address. 228 * 229 * @par Externals: 230 * N/A 231 * 232 * @return 233 * Returns the corresponding physical address. 234 * 235 * @par Errors: 236 * See return section for error information. 237 *****************************************************************************/ 238 239unsigned long N8_VirtToPhys(void *virtaddr) 240{ 241 paddr_t phys_addr; 242 pmap_extract(pmap_kernel(), (unsigned long)virtaddr, &phys_addr); 243 return phys_addr; 244} 245 246 247/***************************************************************************** 248 * n8_GetLargeAllocation 249 *****************************************************************************/ 250/** @ingroup NSP2000Driver 251 * @brief n8_memory - Allocates a large physically contiguous memory range. 252 * 253 * This routine allocates the requested large allocation with a call 254 * to contigmalloc. 255 * 256 * @param bankIndex RO: Bank type for the memory allocation. 257 * @param size RO: The allocation size. 258 * @param debug RO: Dump debug information. 259 * 260 * @return 261 * Physical address of the memory pool. NULL if failed. 262 * 263 * 264 * @par Errors: 265 * See return section for error information. 266 *****************************************************************************/ 267 268unsigned long 269n8_GetLargeAllocation(N8_MemoryType_t bankIndex, 270 unsigned long size, unsigned char debug) 271{ 272 273 NspInstance_t *nip = &NSPDeviceTable_g[0]; /* can only attach once */ 274 struct nsp_softc *sc = device_private(nip->dev); 275 276 bus_dma_segment_t seg; 277 int rseg; 278 void *kva = NULL; 279 280#if 0 281 /* Replacement for: */ 282 m = contigmalloc(size, M_DEVBUF, M_WAITOK, 283 0, /* lower acceptible phys addr */ 284 0xffffffff, /* upper acceptible phys addr */ 285 PAGE_SIZE, /* alignment */ 286 0); /* boundary */ 287#endif 288 if (bus_dmamem_alloc(sc->dma_tag, size, PAGE_SIZE, 0, 289 &seg, 1, &rseg, BUS_DMA_NOWAIT)) { 290 printf("%s: can't alloc DMA buffer\n", 291 device_xname(&sc->device)); 292 return 0; 293 } 294 if (bus_dmamem_map(sc->dma_tag, &seg, rseg, size, &kva, 295 BUS_DMA_NOWAIT)) { 296 printf("%s: can't map DMA buffers (%lu bytes)\n", 297 device_xname(&sc->device), size); 298 bus_dmamem_free(sc->dma_tag, &seg, rseg); 299 return 0; 300 } 301 if (bus_dmamap_create(sc->dma_tag, size, 1, 302 size, 0, BUS_DMA_NOWAIT, &DmaMap_g[bankIndex])) { 303 printf("%s: can't create DMA map\n", device_xname(&sc->device)); 304 bus_dmamem_unmap(sc->dma_tag, kva, size); 305 bus_dmamem_free(sc->dma_tag, &seg, rseg); 306 return 0; 307 } 308 if (bus_dmamap_load(sc->dma_tag, DmaMap_g[bankIndex], kva, size, 309 NULL, BUS_DMA_NOWAIT)) { 310 printf("%s: can't load DMA map\n", device_xname(&sc->device)); 311 bus_dmamap_destroy(sc->dma_tag, DmaMap_g[bankIndex]); 312 bus_dmamem_unmap(sc->dma_tag, kva, size); 313 bus_dmamem_free(sc->dma_tag, &seg, rseg); 314 return 0; 315 } 316 if (kva) { 317 /* memset(kva, 0, size) */ 318 BasePointer_g[bankIndex] = kva; 319 MemSize_g[bankIndex] = size; 320 Seg_g[bankIndex] = seg; 321 Rseg_g[bankIndex] = rseg; 322 MemBaseAddress_g[bankIndex] = vtophys((u_int)kva); 323 MemTopAddress_g[bankIndex] = MemBaseAddress_g[bankIndex] + size; 324 } 325 326 if (debug) 327 { 328 printf("n8_GetLargeAllocation: %p (0x%08lx) allocated for bankIndex %d\n", 329 BasePointer_g[bankIndex], MemBaseAddress_g[bankIndex], bankIndex); 330 } 331 332 return MemBaseAddress_g[bankIndex]; 333} 334 335/***************************************************************************** 336 * n8_FreeLargeAllocation 337 *****************************************************************************/ 338/** @ingroup NSP2000Driver 339 * @brief n8_memory - Releases a large physically contiguous memory range. 340 * 341 * This routine deallocates the large allocation with a call to contigfree. 342 * 343 * @param bankIndex RO: Bank type for the memory free. 344 * @param debug RO: Dump debug information. 345 * 346 * @return 347 * N/A 348 * 349 * @par Errors: 350 * See return section for error information. 351 *****************************************************************************/ 352 353 354void 355n8_FreeLargeAllocation(N8_MemoryType_t bankIndex, 356 unsigned char debug) 357{ 358 NspInstance_t *nip = &NSPDeviceTable_g[0]; /* can only attach once */ 359 struct nsp_softc *sc = device_private(nip->dev); 360 361 printf("n8_FreeLargeAllocation: freeing %p for bankIndex %d\n", 362 BasePointer_g[bankIndex], bankIndex); 363 if (debug) { 364 printf("n8_FreeLargeAllocation: freeing %p for bankIndex %d\n", 365 BasePointer_g[bankIndex], bankIndex); 366 } 367 368 if (BasePointer_g[bankIndex]) { 369 /* contigfree(BasePointer_g[bankIndex], MemSize_g[bankIndex], M_DEVBUF); */ 370 printf("n8_FreeLargeAllocation: bus_dmamap_unload(bank %d) (kva=%p)\n", 371 bankIndex, BasePointer_g[bankIndex]); 372 bus_dmamap_unload(sc->dma_tag, DmaMap_g[bankIndex]); 373 printf("n8_FreeLargeAllocation: bus_dmamap_destroy()\n"); 374 bus_dmamap_destroy(sc->dma_tag, DmaMap_g[bankIndex]); 375 printf("n8_FreeLargeAllocation: bus_dmamap_unmap()\n"); 376 bus_dmamem_unmap(sc->dma_tag, BasePointer_g[bankIndex], 377 MemSize_g[bankIndex]); 378 printf("n8_FreeLargeAllocation: bus_dmamap_unmap()\n"); 379 bus_dmamem_free(sc->dma_tag, &Seg_g[bankIndex], Rseg_g[bankIndex]); 380 } 381 BasePointer_g[bankIndex] = NULL; 382} 383 384/***************************************************************************** 385 * n8_bounds_check 386 *****************************************************************************/ 387/** @ingroup NSP2000Driver 388 * @brief n8_bounds_check - Validates address passed to mmap 389 * 390 * This routine validates address passed to mmap 391 * 392 * @param phys RO: Address of mmap request. 393 * 394 * @return 395 * N/A 396 * 397 * @par Errors: 398 * See return section for error information. 399 *****************************************************************************/ 400 401int 402n8_bounds_check(unsigned long phys) 403{ 404 int ctr; 405 406 for (ctr = 1; ctr < (N8_MEMBANK_MAX + DEF_USER_POOL_BANKS); ctr++) 407 { 408 if ((MemBaseAddress_g[ctr] <= phys) && 409 (phys < (MemBaseAddress_g[ctr] + MemSize_g[ctr]))) 410 { 411 /* Valid mmap request */ 412 return 1; 413 } 414 } 415 416 return 0; 417} 418 419 420