/*
* dspbridge/mpu_api/inc/mem.h
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Copyright (C) 2007 Texas Instruments, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 of the License.
*
* This program is distributed .as is. WITHOUT ANY WARRANTY of any kind,
* whether express or implied; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
/*
* ======== mem.h ========
* Purpose:
* Memory management and address mapping services for the DSP/BIOS Bridge
* class driver and mini-driver.
*
* Public Functions:
* MEM_Alloc
* MEM_AllocObject
* MEM_AllocPhysMem
* MEM_Calloc
* MEM_Exit
* MEM_FlushCache
* MEM_Free
* MEM_FreeObject
* MEM_FreePhysMem
* MEM_GetNumPages
* MEM_Init
* MEM_IsValidHandle
* MEM_LinearAddress
* MEM_PageLock
* MEM_PageUnlock
* MEM_UnMapLinearAddress
* MEM_VirtualToPhysical
*
* Notes:
*
*! Revision History:
*! ================
*! 19-Apr-2004 sb: Added Alloc/Free PhysMem, FlushCache, VirtualToPhysical
*! 01-Sep-2001 ag: Cleaned up notes for MEM_LinearAddress() does not
*! require phys address to be page aligned!
*! 02-Dec-1999 rr: stdwin.h included for retail build
*! 12-Nov-1999 kc: Added warning about use of MEM_LinearAddress.
*! 29-Oct-1999 kc: Cleaned up for code review.
*! 10-Aug-1999 kc: Based on wsx-c18.
*! 07-Jan-1998 gp: Added MEM_AllocUMB and MEM_UMBFree for User Mapped Buffers
*! used by WMD_CHNL.
*! 23-Dec-1997 cr: Code review cleanup, removed dead Ring 3 code.
*! 04-Aug-1997 cr: Added explicit CDECL identifiers.
*! 01-Nov-1996 gp: Updated based on code review.
*! 04-Sep-1996 gp: Added MEM_PageLock() and MEM_PageUnlock() services.
*! 14-Aug-1996 mg: Added MEM_GetPhysAddr() and MEM_GetNumPages()
*! 25-Jul-1996 gp: Added MEM_IsValidHandle() macro.
*! 10-May-1996 gp: Added MEM_Calloc().
*! 25-Apr-1996 gp: Added MEM_PhysicalAddress()
*! 17-Apr-1996 gp: Added MEM_Exit function; updated to latest naming standard.
*! 08-Apr-1996 gp: Created.
*/
#ifndef MEM_
#define MEM_
#ifdef __cplusplus
extern "C" {
#endif
#include <dspapi.h>
#include <memdefs.h>
/*
* ======== MEM_Alloc ========
* Purpose:
* Allocate memory from the paged or non-paged pools.
* Parameters:
* cBytes: Number of bytes to allocate.
* type: Type of memory to allocate; one of:
* MEM_PAGED: Allocate from pageable memory.
* MEM_NONPAGED: Allocate from page locked memory.
* Returns:
* Pointer to a block of memory;
* NULL if memory couldn't be allocated, if cBytes == 0, or if type is
* not one of MEM_PAGED or MEM_NONPAGED.
* Requires:
* MEM initialized.
* Ensures:
* The returned pointer, if not NULL, points to a valid memory block of
* the size requested.
*/
#ifdef __KERNEL__
extern PVOID MEM_Alloc(IN ULONG cBytes, IN MEM_POOLATTRS type);
#else
#define MEM_Alloc(size, type) malloc (size)
#endif
/*
* ======== MEM_AllocObject ========
* Purpose:
* Allocate an object, and set it's signature.
* Parameters:
* pObj: Pointer to the new object.
* Obj: Type of the object to allocate.
* Signature: Magic field value. Must be non-zero.
* Returns:
* Requires:
* Same requirements as MEM_Calloc(); and
* The object structure has a dwSignature field. The compiler ensures
* this requirement.
* Ensures:
* A subsequent call to MEM_IsValidHandle() will succeed for this object.
*/
#define MEM_AllocObject(pObj, Obj, Signature) \
{ \
pObj = MEM_Calloc(sizeof(Obj), MEM_NONPAGED); \
if (pObj) { \
pObj->dwSignature = Signature; \
} \
}
/* ======== MEM_AllocPhysMem ========
* Purpose:
* Allocate physically contiguous, uncached memory
* Parameters:
* cBytes: Number of bytes to allocate.
* ulAlign: Alignment Mask.
* pPhysicalAddress: Physical address of allocated memory.
* Returns:
* Pointer to a block of memory;
* NULL if memory couldn't be allocated, or if cBytes == 0.
* Requires:
* MEM initialized.
* Ensures:
* The returned pointer, if not NULL, points to a valid memory block of
* the size requested. Returned physical address refers to physical
* location of memory.
*/
extern PVOID MEM_AllocPhysMem(IN ULONG cBytes,
IN ULONG ulAlign,
OUT ULONG * pPhysicalAddress);
/*
* ======== MEM_Calloc ========
* Purpose:
* Allocate zero-initialized memory from the paged or non-paged pools.
* Parameters:
* cBytes: Number of bytes to allocate.
* type: Type of memory to allocate; one of:
* MEM_PAGED: Allocate from pageable memory.
* MEM_NONPAGED: Allocate from page locked memory.
* Returns:
* Pointer to a block of zeroed memory;
* NULL if memory couldn't be allocated, if cBytes == 0, or if type is
* not one of MEM_PAGED or MEM_NONPAGED.
* Requires:
* MEM initialized.
* Ensures:
* The returned pointer, if not NULL, points to a valid memory block
* of the size requested.
*/
extern PVOID MEM_Calloc(IN ULONG cBytes, IN MEM_POOLATTRS type);
/*
* ======== MEM_Exit ========
* Purpose:
* Discontinue usage of module; free resources when reference count
* reaches 0.
* Parameters:
* Returns:
* Requires:
* MEM is initialized.
* Ensures:
* Resources used by module are freed when cRef reaches zero.
*/
extern VOID MEM_Exit();
/*
* ======== MEM_FlushCache ========
* Purpose:
* Performs system cache sync with discard
* Parameters:
* pMemBuf: Pointer to memory region to be flushed.
* pMemBuf: Size of the memory region to be flushed.
* Returns:
* Requires:
* MEM is initialized.
* Ensures:
* Cache is synchronized
*/
extern VOID MEM_FlushCache(PVOID pMemBuf, ULONG cBytes,INT FlushType);
/*
* ======== MEM_Free ========
* Purpose:
* Free the given block of system memory.
* Parameters:
* pMemBuf: Pointer to memory allocated by MEM_Calloc/Alloc().
* Returns:
* Requires:
* MEM initialized.
* pMemBuf is a valid memory address returned by MEM_Calloc/Alloc().
* Ensures:
* pMemBuf is no longer a valid pointer to memory.
*/
#ifdef __KERNEL__
extern VOID MEM_Free(IN PVOID pMemBuf);
#else
#define MEM_Free(ptr) free (ptr)
#endif
/*
* ======== MEM_VFree ========
* Purpose:
* Free the given block of system memory.
* Parameters:
* pMemBuf: Pointer to memory allocated by MEM_Calloc/Alloc().
* Returns:
* Requires:
* MEM initialized.
* pMemBuf is a valid memory address returned by MEM_Calloc/Alloc().
* Ensures:
* pMemBuf is no longer a valid pointer to memory.
*/
#ifdef __KERNEL__
extern VOID MEM_VFree(IN PVOID pMemBuf);
#endif
/*
* ======== MEM_FreePhysMem ========
* Purpose:
* Free the given block of physically contiguous memory.
* Parameters:
* pVirtualAddress: Pointer to virtual memory region allocated by MEM_AllocPhysMem().
* pPhysicalAddress: Pointer to physical memory region allocated by MEM_AllocPhysMem().
* cBytes: Size of the memory region allocated by MEM_AllocPhysMem().
* Returns:
* Requires:
* MEM initialized.
* pVirtualAddress is a valid memory address returned by
* MEM_AllocPhysMem()
* Ensures:
* pVirtualAddress is no longer a valid pointer to memory.
*/
extern VOID MEM_FreePhysMem(PVOID pVirtualAddress,
DWORD pPhysicalAddress, ULONG cBytes);
/*
* ======== MEM_FreeObject ========
* Purpose:
* Utility macro to invalidate an object's signature, and deallocate it.
* Parameters:
* pObj: Pointer to the object to free.
* Returns:
* Requires:
* Same requirements as MEM_Free().
* Ensures:
* A subsequent call to MEM_IsValidHandle() will fail for this object.
*/
#define MEM_FreeObject(pObj) \
{ \
pObj->dwSignature = 0x00; \
MEM_Free(pObj); \
}
/*
* ======== MEM_GetNumPages ========
* Purpose:
* Calculate the number of pages corresponding to the supplied buffer.
* Parameters:
* pAddr: Linear (virtual) address of the buffer.
* cBytes: Number of bytes in the buffer.
* Returns:
* Number of pages.
* Requires:
* MEM initialized.
* Ensures:
* If cBytes > 0, number of pages returned > 0.
*/
extern INT MEM_GetNumPages(IN PVOID pAddr, IN ULONG cBytes);
/*
* ======== MEM_Init ========
* Purpose:
* Initializes private state of MEM module.
* Parameters:
* Returns:
* TRUE if initialized; FALSE if error occured.
* Requires:
* Ensures:
* MEM initialized.
*/
extern bool MEM_Init();
/*
* ======== MEM_IsValidHandle ========
* Purpose:
* Validate the object handle.
* Parameters:
* hObj: Handle to object created with MEM_AllocObject().
* Sig: Expected signature DWORD.
* Returns:
* TRUE if handle is valid; FALSE otherwise.
* Requires:
* The object structure has a dwSignature field. Ensured by compiler.
* Ensures:
*/
#define MEM_IsValidHandle(hObj, Sig) \
((hObj != NULL) && (hObj->dwSignature == Sig))
/* Structure reflecting a physical address and size of memory referenced. */
struct MEM_PHYSICAL {
DWORD dwPhysAddr;
DWORD nBytes;
} ;
/*
* ======== MEM_LinearAddress ========
* Purpose:
* Get the linear address corresponding to the given physical address.
* Parameters:
* pPhysAddr: Physical address to be mapped.
* cBytes: Number of bytes in physical range to map.
* Returns:
* The corresponding linear address, or NULL if unsuccessful.
* Requires:
* MEM initialized.
* Ensures:
* Notes:
* If valid linear address is returned, be sure to call
* MEM_UnmapLinearAddress().
*/
#ifndef LINUX
extern PVOID MEM_LinearAddress(IN PVOID pPhyAddr, IN ULONG cBytes);
#else
#define MEM_LinearAddress(pPhyAddr, cBytes) pPhyAddr
#endif
#ifndef LINUX
/*
* ======== MEM_PageLock ========
* Purpose:
* Calls kernel services to map the set of pages identified by a private
* process pointer and a byte count into the calling process's globally
* shared address space.
* Parameters
* pBuffer: Pointer to a process-private data buffer.
* cSize: Size in bytes of the data buffer.
* Returns:
* A pointer to linear page locked memory;
* NULL if a failure occured locking memory.
* Requires:
* - MEM initialized.
* - The size (cSize) must accurately reflect the size of the buffer to
* be locked, since the page count is derived from this number.
* - Valid pBuffer.
* Ensures:
* Memory locked by this service can be accessed at interrupt time, or
* from other memory contexts.
*/
extern PVOID MEM_PageLock(IN PVOID pBuffer, IN ULONG cSize);
/*
* ======== MEM_PageUnlock ========
* Purpose:
* Unlocks a buffer previously locked using MEM_PageLock().
* Parameters:
* pBuffer: Pointer to locked memory (as returned by MEM_PageLock()).
* cSize: Size in bytes of the buffer.
* Returns:
* Returns DSP_SOK if unlock successful; else, returns DSP_EFAIL;
* Requires:
* - MEM initialized.
* - Valid pBuffer.
* Ensures:
* Will unlock the pages of memory when the lock count drops to zero.
* (MEM_PageLock() increments the lock count, and MEM_PageUnlock
* decrements the count).
*/
extern DSP_STATUS MEM_PageUnlock(IN PVOID pBuffer, IN ULONG cSize);
#endif
/*
* ======== MEM_UnmapLinearAddress ========
* Purpose:
* Unmap the linear address mapped in MEM_LinearAddress.
* Parameters:
* pBaseAddr: Ptr to mapped memory (as returned by MEM_LinearAddress()).
* Returns:
* Requires:
* - MEM initialized.
* - pBaseAddr is a valid linear address mapped in MEM_LinearAddress.
* Ensures:
* - pBaseAddr no longer points to a valid linear address.
*/
#ifndef LINUX
extern VOID MEM_UnmapLinearAddress(IN PVOID pBaseAddr);
#else
#define MEM_UnmapLinearAddress(pBaseAddr)
#endif
/*
* ======== MEM_VirtualToPhysical ========
* Purpose:
* Given a user allocated virtual address, return the corresponding
* physical address based on the page frame address.
* Parameters:
* dwVirtAddr: Linear address of user allocated (and mapped) buffer.
* Returns:
* Returns corresponding physical address or NULL if unsuccessful
* Requires:
* - MEM initialized.
* - dwVirtAddr is a valid linear address.
*/
extern DWORD MEM_VirtualToPhysical(IN DWORD dwVirtAddr);
/*
* ======== MEM_ExtPhysPoolInit ========
* Purpose:
* Uses the physical memory chunk passed for internal consitent memory allocations.
* physical address based on the page frame address.
* Parameters:
* poolPhysBase starting address of the physical memory pool.
* poolSize size of the physical memory pool.
* Returns:
* none.
* Requires:
* - MEM initialized.
* - valid physical address for the base and size > 0
*/
extern VOID MEM_ExtPhysPoolInit(IN DWORD poolPhysBase,
IN DWORD poolSize);
#ifdef __cplusplus
}
#endif
#endif /* MEM_ */