420 lines
14 KiB
C
420 lines
14 KiB
C
/*-
|
|
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This code is derived from software contributed to The NetBSD Foundation
|
|
* by Coyote Point Systems, Inc.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/*-
|
|
* Copyright (C) 2001-2003 by NBMK Encryption Technologies.
|
|
* All rights reserved.
|
|
*
|
|
* NBMK Encryption Technologies provides no support of any kind for
|
|
* this software. Questions or concerns about it may be addressed to
|
|
* the members of the relevant open-source community at
|
|
* <tech-crypto@netbsd.org>.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following
|
|
* disclaimer in the documentation and/or other materials provided
|
|
* with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
static char const n8_id[] = "$Id: n8_memory_bsd.c,v 1.4 2009/05/12 08:23:01 cegger Exp $";
|
|
/*****************************************************************************/
|
|
/** @file n8_memory_bsd.c
|
|
* @brief NetOctaveMemory Services - FreeBSD-specific support routines.
|
|
*
|
|
* This file contains all FreeBSD-specific support routines for the large
|
|
* allocation services used by the driver. The cross-platform memory management
|
|
* code uses these routines.
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* Revision history:
|
|
* 05/12/03 brr Modified user pools to take advantage of the support for
|
|
* multiple memory banks.
|
|
* 05/08/03 brr Dimension arrays to allow of multiple user pools.
|
|
* 05/05/03 brr Moved memory functions here from helper.c.
|
|
* 04/22/03 brr Change wait flag passed to contigmalloc to M_WAITOK.
|
|
* 04/22/03 brr Clean up comments & add debug statements.
|
|
* Removed redundant parameter from n8_FreeLargeAllocation.
|
|
* 04/21/03 brr Added support for multiple memory banks.
|
|
* 11/01/02 brr Correctly deallocate memory resources.
|
|
* 10/25/02 brr Temporarily comment out call to contigfree().
|
|
* 10/22/02 brr File created.
|
|
****************************************************************************/
|
|
/** @defgroup NSP2000Driver NSP2000 Device Driver - FreeBSD version.
|
|
*/
|
|
|
|
|
|
#include "helper.h"
|
|
#include "n8_malloc_common.h"
|
|
#include "n8_OS_intf.h"
|
|
#include "n8_memory.h"
|
|
#include "n8_driver_parms.h"
|
|
#include <uvm/uvm.h>
|
|
#include <machine/pmap.h>
|
|
#include "nsp.h"
|
|
|
|
extern NspInstance_t NSPDeviceTable_g[];
|
|
static unsigned long MemBaseAddress_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS];
|
|
static unsigned long MemTopAddress_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS];
|
|
static unsigned long MemSize_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS];
|
|
static void *BasePointer_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS];
|
|
static bus_dmamap_t DmaMap_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS];
|
|
static int Rseg_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS];
|
|
static bus_dma_segment_t Seg_g[N8_MEMBANK_MAX + DEF_USER_POOL_BANKS];
|
|
|
|
/*****************************************************************************
|
|
* n8_vmalloc
|
|
*****************************************************************************/
|
|
/** @ingroup NSP2000Driver
|
|
* @brief n8_memory - Allocates and clears a buffer.
|
|
*
|
|
* This routine abstracts memory allocation for the functions in the driver.
|
|
*
|
|
* @param size RO: Specifies the desired allocation size
|
|
*
|
|
* @return
|
|
* Virtual address of the memory allocation, NULL if failed.
|
|
*
|
|
*
|
|
* @par Errors:
|
|
* See return section for error information.
|
|
*****************************************************************************/
|
|
|
|
void *
|
|
n8_vmalloc(unsigned long size)
|
|
{
|
|
N8_UmallocHdr_t *m;
|
|
|
|
if (size) {
|
|
m = malloc(size, M_DEVBUF, M_WAITOK);
|
|
|
|
if (m) {
|
|
memset(m, 0, sizeof (*m));
|
|
|
|
return m+1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* n8_vfree
|
|
*****************************************************************************/
|
|
/** @ingroup NSP2000Driver
|
|
* @brief n8_memory - Frees a buffer allocated by n8_vmalloc.
|
|
*
|
|
* This routine abstracts memory allocation for the functions in the driver.
|
|
*
|
|
* @param a RO: Specifies the address to free.
|
|
*
|
|
* @return
|
|
* None.
|
|
*
|
|
*
|
|
* @par Errors:
|
|
* See return section for error information.
|
|
*****************************************************************************/
|
|
|
|
void
|
|
n8_vfree(void *a)
|
|
{
|
|
N8_UmallocHdr_t *m = a;
|
|
|
|
if (m) {
|
|
free(m-1, M_DEVBUF);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* N8_PhysToVirt
|
|
*****************************************************************************/
|
|
/** @ingroup NSP2000Driver
|
|
* @brief N8_PhysToVirt - Converts a physical address to it virtual address
|
|
*
|
|
* @param phys RO: Physical address to convert.
|
|
*
|
|
* @return
|
|
* Virtual address of phys
|
|
*
|
|
*
|
|
* @par Errors:
|
|
*****************************************************************************/
|
|
|
|
void *
|
|
N8_PhysToVirt(unsigned long phys)
|
|
{
|
|
unsigned long offset;
|
|
int bankIndex = N8_MEMBANK_QUEUE;
|
|
int ctr;
|
|
void *virtaddr;
|
|
|
|
for (ctr = 0; ctr < (N8_MEMBANK_MAX + DEF_USER_POOL_BANKS); ctr++)
|
|
{
|
|
if ((phys >= MemBaseAddress_g[ctr]) &&
|
|
(phys < MemTopAddress_g[ctr]))
|
|
{
|
|
bankIndex = ctr;
|
|
break;
|
|
}
|
|
}
|
|
if (ctr >= (N8_MEMBANK_MAX + DEF_USER_POOL_BANKS)) {
|
|
printf("N8_PhysToVirt(0x%lx) ran out of banks\n", phys);
|
|
}
|
|
|
|
offset = phys - MemBaseAddress_g[bankIndex];
|
|
|
|
virtaddr = (void *)(offset + (unsigned long)BasePointer_g[bankIndex]);
|
|
return virtaddr;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
* N8_VirtToPhys
|
|
*****************************************************************************/
|
|
/** @ingroup NSP2000Driver
|
|
* @brief Convert a virtual address to a physical address.
|
|
*
|
|
* This routine abstracts the Linux system call to convert a virtual address
|
|
* to a physical address.
|
|
*
|
|
* @param virtaddr RO: Specifies the physical address.
|
|
*
|
|
* @par Externals:
|
|
* N/A
|
|
*
|
|
* @return
|
|
* Returns the corresponding physical address.
|
|
*
|
|
* @par Errors:
|
|
* See return section for error information.
|
|
*****************************************************************************/
|
|
|
|
unsigned long N8_VirtToPhys(void *virtaddr)
|
|
{
|
|
paddr_t phys_addr;
|
|
pmap_extract(pmap_kernel(), (unsigned long)virtaddr, &phys_addr);
|
|
return phys_addr;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
* n8_GetLargeAllocation
|
|
*****************************************************************************/
|
|
/** @ingroup NSP2000Driver
|
|
* @brief n8_memory - Allocates a large physically contiguous memory range.
|
|
*
|
|
* This routine allocates the requested large allocation with a call
|
|
* to contigmalloc.
|
|
*
|
|
* @param bankIndex RO: Bank type for the memory allocation.
|
|
* @param size RO: The allocation size.
|
|
* @param debug RO: Dump debug information.
|
|
*
|
|
* @return
|
|
* Physical address of the memory pool. NULL if failed.
|
|
*
|
|
*
|
|
* @par Errors:
|
|
* See return section for error information.
|
|
*****************************************************************************/
|
|
|
|
unsigned long
|
|
n8_GetLargeAllocation(N8_MemoryType_t bankIndex,
|
|
unsigned long size, unsigned char debug)
|
|
{
|
|
|
|
NspInstance_t *nip = &NSPDeviceTable_g[0]; /* can only attach once */
|
|
struct nsp_softc *sc = device_private(nip->dev);
|
|
|
|
bus_dma_segment_t seg;
|
|
int rseg;
|
|
void *kva = NULL;
|
|
|
|
#if 0
|
|
/* Replacement for: */
|
|
m = contigmalloc(size, M_DEVBUF, M_WAITOK,
|
|
0, /* lower acceptible phys addr */
|
|
0xffffffff, /* upper acceptible phys addr */
|
|
PAGE_SIZE, /* alignment */
|
|
0); /* boundary */
|
|
#endif
|
|
if (bus_dmamem_alloc(sc->dma_tag, size, PAGE_SIZE, 0,
|
|
&seg, 1, &rseg, BUS_DMA_NOWAIT)) {
|
|
printf("%s: can't alloc DMA buffer\n",
|
|
device_xname(&sc->device));
|
|
return 0;
|
|
}
|
|
if (bus_dmamem_map(sc->dma_tag, &seg, rseg, size, &kva,
|
|
BUS_DMA_NOWAIT)) {
|
|
printf("%s: can't map DMA buffers (%lu bytes)\n",
|
|
device_xname(&sc->device), size);
|
|
bus_dmamem_free(sc->dma_tag, &seg, rseg);
|
|
return 0;
|
|
}
|
|
if (bus_dmamap_create(sc->dma_tag, size, 1,
|
|
size, 0, BUS_DMA_NOWAIT, &DmaMap_g[bankIndex])) {
|
|
printf("%s: can't create DMA map\n", device_xname(&sc->device));
|
|
bus_dmamem_unmap(sc->dma_tag, kva, size);
|
|
bus_dmamem_free(sc->dma_tag, &seg, rseg);
|
|
return 0;
|
|
}
|
|
if (bus_dmamap_load(sc->dma_tag, DmaMap_g[bankIndex], kva, size,
|
|
NULL, BUS_DMA_NOWAIT)) {
|
|
printf("%s: can't load DMA map\n", device_xname(&sc->device));
|
|
bus_dmamap_destroy(sc->dma_tag, DmaMap_g[bankIndex]);
|
|
bus_dmamem_unmap(sc->dma_tag, kva, size);
|
|
bus_dmamem_free(sc->dma_tag, &seg, rseg);
|
|
return 0;
|
|
}
|
|
if (kva) {
|
|
/* memset(kva, 0, size) */
|
|
BasePointer_g[bankIndex] = kva;
|
|
MemSize_g[bankIndex] = size;
|
|
Seg_g[bankIndex] = seg;
|
|
Rseg_g[bankIndex] = rseg;
|
|
MemBaseAddress_g[bankIndex] = vtophys((u_int)kva);
|
|
MemTopAddress_g[bankIndex] = MemBaseAddress_g[bankIndex] + size;
|
|
}
|
|
|
|
if (debug)
|
|
{
|
|
printf("n8_GetLargeAllocation: %p (0x%08lx) allocated for bankIndex %d\n",
|
|
BasePointer_g[bankIndex], MemBaseAddress_g[bankIndex], bankIndex);
|
|
}
|
|
|
|
return MemBaseAddress_g[bankIndex];
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* n8_FreeLargeAllocation
|
|
*****************************************************************************/
|
|
/** @ingroup NSP2000Driver
|
|
* @brief n8_memory - Releases a large physically contiguous memory range.
|
|
*
|
|
* This routine deallocates the large allocation with a call to contigfree.
|
|
*
|
|
* @param bankIndex RO: Bank type for the memory free.
|
|
* @param debug RO: Dump debug information.
|
|
*
|
|
* @return
|
|
* N/A
|
|
*
|
|
* @par Errors:
|
|
* See return section for error information.
|
|
*****************************************************************************/
|
|
|
|
|
|
void
|
|
n8_FreeLargeAllocation(N8_MemoryType_t bankIndex,
|
|
unsigned char debug)
|
|
{
|
|
NspInstance_t *nip = &NSPDeviceTable_g[0]; /* can only attach once */
|
|
struct nsp_softc *sc = device_private(nip->dev);
|
|
|
|
printf("n8_FreeLargeAllocation: freeing %p for bankIndex %d\n",
|
|
BasePointer_g[bankIndex], bankIndex);
|
|
if (debug) {
|
|
printf("n8_FreeLargeAllocation: freeing %p for bankIndex %d\n",
|
|
BasePointer_g[bankIndex], bankIndex);
|
|
}
|
|
|
|
if (BasePointer_g[bankIndex]) {
|
|
/* contigfree(BasePointer_g[bankIndex], MemSize_g[bankIndex], M_DEVBUF); */
|
|
printf("n8_FreeLargeAllocation: bus_dmamap_unload(bank %d) (kva=%p)\n",
|
|
bankIndex, BasePointer_g[bankIndex]);
|
|
bus_dmamap_unload(sc->dma_tag, DmaMap_g[bankIndex]);
|
|
printf("n8_FreeLargeAllocation: bus_dmamap_destroy()\n");
|
|
bus_dmamap_destroy(sc->dma_tag, DmaMap_g[bankIndex]);
|
|
printf("n8_FreeLargeAllocation: bus_dmamap_unmap()\n");
|
|
bus_dmamem_unmap(sc->dma_tag, BasePointer_g[bankIndex],
|
|
MemSize_g[bankIndex]);
|
|
printf("n8_FreeLargeAllocation: bus_dmamap_unmap()\n");
|
|
bus_dmamem_free(sc->dma_tag, &Seg_g[bankIndex], Rseg_g[bankIndex]);
|
|
}
|
|
BasePointer_g[bankIndex] = NULL;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* n8_bounds_check
|
|
*****************************************************************************/
|
|
/** @ingroup NSP2000Driver
|
|
* @brief n8_bounds_check - Validates address passed to mmap
|
|
*
|
|
* This routine validates address passed to mmap
|
|
*
|
|
* @param phys RO: Address of mmap request.
|
|
*
|
|
* @return
|
|
* N/A
|
|
*
|
|
* @par Errors:
|
|
* See return section for error information.
|
|
*****************************************************************************/
|
|
|
|
int
|
|
n8_bounds_check(unsigned long phys)
|
|
{
|
|
int ctr;
|
|
|
|
for (ctr = 1; ctr < (N8_MEMBANK_MAX + DEF_USER_POOL_BANKS); ctr++)
|
|
{
|
|
if ((MemBaseAddress_g[ctr] <= phys) &&
|
|
(phys < (MemBaseAddress_g[ctr] + MemSize_g[ctr])))
|
|
{
|
|
/* Valid mmap request */
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|