1/*
2 * dspbridge/mpu_api/inc/mem.h
3* DSP-BIOS Bridge driver support functions for TI OMAP processors.
4 *
5 * Copyright (C) 2007 Texas Instruments, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation version 2.1 of the License.
10 *
11 * This program is distributed .as is. WITHOUT ANY WARRANTY of any kind,
12 * whether express or implied; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 */
16
17
18/*
19 *  ======== mem.h ========
20 *  Purpose:
21 *      Memory management and address mapping services for the DSP/BIOS Bridge
22 *      class driver and mini-driver.
23 *
24 *  Public Functions:
25 *      MEM_Alloc
26 *      MEM_AllocObject
27 *      MEM_AllocPhysMem
28 *      MEM_Calloc
29 *      MEM_Exit
30 *      MEM_FlushCache
31 *      MEM_Free
32 *      MEM_FreeObject
33 *      MEM_FreePhysMem
34 *      MEM_GetNumPages
35 *      MEM_Init
36 *      MEM_IsValidHandle
37 *      MEM_LinearAddress
38 *      MEM_PageLock
39 *      MEM_PageUnlock
40 *      MEM_UnMapLinearAddress
41 *      MEM_VirtualToPhysical
42 *
43 *  Notes:
44 *
45 *! Revision History:
46 *! ================
47 *! 19-Apr-2004 sb: Added Alloc/Free PhysMem, FlushCache, VirtualToPhysical
48 *! 01-Sep-2001 ag: Cleaned up notes for MEM_LinearAddress() does not
49 *!                   require phys address to be page aligned!
50 *! 02-Dec-1999 rr: stdwin.h included for retail build
51 *! 12-Nov-1999 kc: Added warning about use of MEM_LinearAddress.
52 *! 29-Oct-1999 kc: Cleaned up for code review.
53 *! 10-Aug-1999 kc: Based on wsx-c18.
54 *! 07-Jan-1998 gp: Added MEM_AllocUMB and MEM_UMBFree for User Mapped Buffers
55 *!                 used by WMD_CHNL.
56 *! 23-Dec-1997 cr: Code review cleanup, removed dead Ring 3 code.
57 *! 04-Aug-1997 cr: Added explicit CDECL identifiers.
58 *! 01-Nov-1996 gp: Updated based on code review.
59 *! 04-Sep-1996 gp: Added MEM_PageLock() and MEM_PageUnlock() services.
60 *! 14-Aug-1996 mg: Added MEM_GetPhysAddr() and MEM_GetNumPages()
61 *! 25-Jul-1996 gp: Added MEM_IsValidHandle() macro.
62 *! 10-May-1996 gp: Added MEM_Calloc().
63 *! 25-Apr-1996 gp: Added MEM_PhysicalAddress()
64 *! 17-Apr-1996 gp: Added MEM_Exit function; updated to latest naming standard.
65 *! 08-Apr-1996 gp: Created.
66 */
67
68#ifndef MEM_
69#define MEM_
70
71#ifdef __cplusplus
72extern "C" {
73#endif
74
75#include <dspapi.h>
76
77#include <memdefs.h>
78
79/*
80 *  ======== MEM_Alloc ========
81 *  Purpose:
82 *      Allocate memory from the paged or non-paged pools.
83 *  Parameters:
84 *      cBytes: Number of bytes to allocate.
85 *      type:   Type of memory to allocate; one of:
86 *              MEM_PAGED: Allocate from pageable memory.
87 *              MEM_NONPAGED: Allocate from page locked memory.
88 *  Returns:
89 *      Pointer to a block of memory;
90 *      NULL if memory couldn't be allocated, if cBytes == 0, or if type is
91 *      not one of MEM_PAGED or MEM_NONPAGED.
92 *  Requires:
93 *      MEM initialized.
94 *  Ensures:
95 *      The returned pointer, if not NULL, points to a valid memory block of
96 *      the size requested.
97 */
98#ifdef __KERNEL__
99	extern PVOID MEM_Alloc(IN ULONG cBytes, IN MEM_POOLATTRS type);
100#else
101#define MEM_Alloc(size, type) malloc (size)
102#endif
103
104/*
105 *  ======== MEM_AllocObject ========
106 *  Purpose:
107 *      Allocate an object, and set it's signature.
108 *  Parameters:
109 *      pObj:       Pointer to the new object.
110 *      Obj:        Type of the object to allocate.
111 *      Signature:  Magic field value.  Must be non-zero.
112 *  Returns:
113 *  Requires:
114 *      Same requirements as MEM_Calloc(); and
115 *      The object structure has a dwSignature field.  The compiler ensures
116 *      this requirement.
117 *  Ensures:
118 *      A subsequent call to MEM_IsValidHandle() will succeed for this object.
119 */
120#define MEM_AllocObject(pObj, Obj, Signature)           \
121{                                                       \
122    pObj = MEM_Calloc(sizeof(Obj), MEM_NONPAGED);       \
123    if (pObj) {                                         \
124        pObj->dwSignature = Signature;                  \
125    }                                                   \
126}
127
128/*  ======== MEM_AllocPhysMem ========
129 *  Purpose:
130 *      Allocate physically contiguous, uncached memory
131 *  Parameters:
132 *      cBytes:     Number of bytes to allocate.
133 *      ulAlign:    Alignment Mask.
134 *      pPhysicalAddress: Physical address of allocated memory.
135 *  Returns:
136 *      Pointer to a block of memory;
137 *      NULL if memory couldn't be allocated, or if cBytes == 0.
138 *  Requires:
139 *      MEM initialized.
140 *  Ensures:
141 *      The returned pointer, if not NULL, points to a valid memory block of
142 *      the size requested.  Returned physical address refers to physical
143 *      location of memory.
144 */
145	extern PVOID MEM_AllocPhysMem(IN ULONG cBytes,
146				      IN ULONG ulAlign,
147				      OUT ULONG * pPhysicalAddress);
148
149/*
150 *  ======== MEM_Calloc ========
151 *  Purpose:
152 *      Allocate zero-initialized memory from the paged or non-paged pools.
153 *  Parameters:
154 *      cBytes: Number of bytes to allocate.
155 *      type:   Type of memory to allocate; one of:
156 *              MEM_PAGED:   Allocate from pageable memory.
157 *              MEM_NONPAGED: Allocate from page locked memory.
158 *  Returns:
159 *      Pointer to a block of zeroed memory;
160 *      NULL if memory couldn't be allocated, if cBytes == 0, or if type is
161 *      not one of MEM_PAGED or MEM_NONPAGED.
162 *  Requires:
163 *      MEM initialized.
164 *  Ensures:
165 *      The returned pointer, if not NULL, points to a valid memory block
166 *      of the size requested.
167 */
168	extern PVOID MEM_Calloc(IN ULONG cBytes, IN MEM_POOLATTRS type);
169
170/*
171 *  ======== MEM_Exit ========
172 *  Purpose:
173 *      Discontinue usage of module; free resources when reference count
174 *      reaches 0.
175 *  Parameters:
176 *  Returns:
177 *  Requires:
178 *      MEM is initialized.
179 *  Ensures:
180 *      Resources used by module are freed when cRef reaches zero.
181 */
182	extern VOID MEM_Exit();
183
184/*
185 *  ======== MEM_FlushCache ========
186 *  Purpose:
187 *      Performs system cache sync with discard
188 *  Parameters:
189 *      pMemBuf:    Pointer to memory region to be flushed.
190 *      pMemBuf:    Size of the memory region to be flushed.
191 *  Returns:
192 *  Requires:
193 *      MEM is initialized.
194 *  Ensures:
195 *      Cache is synchronized
196 */
197	extern VOID MEM_FlushCache(PVOID pMemBuf, ULONG cBytes,INT FlushType);
198
199/*
200 *  ======== MEM_Free ========
201 *  Purpose:
202 *      Free the given block of system memory.
203 *  Parameters:
204 *      pMemBuf:    Pointer to memory allocated by MEM_Calloc/Alloc().
205 *  Returns:
206 *  Requires:
207 *      MEM initialized.
208 *      pMemBuf is a valid memory address returned by MEM_Calloc/Alloc().
209 *  Ensures:
210 *      pMemBuf is no longer a valid pointer to memory.
211 */
212#ifdef __KERNEL__
213	extern VOID MEM_Free(IN PVOID pMemBuf);
214#else
215#define MEM_Free(ptr) free (ptr)
216#endif
217
218/*
219 *  ======== MEM_VFree ========
220 *  Purpose:
221 *      Free the given block of system memory.
222 *  Parameters:
223 *      pMemBuf:    Pointer to memory allocated by MEM_Calloc/Alloc().
224 *  Returns:
225 *  Requires:
226 *      MEM initialized.
227 *      pMemBuf is a valid memory address returned by MEM_Calloc/Alloc().
228 *  Ensures:
229 *      pMemBuf is no longer a valid pointer to memory.
230 */
231#ifdef __KERNEL__
232	extern VOID MEM_VFree(IN PVOID pMemBuf);
233#endif
234
235/*
236 *  ======== MEM_FreePhysMem ========
237 *  Purpose:
238 *      Free the given block of physically contiguous memory.
239 *  Parameters:
240 *      pVirtualAddress:  Pointer to virtual memory region allocated by MEM_AllocPhysMem().
241 *      pPhysicalAddress:  Pointer to physical memory region  allocated by MEM_AllocPhysMem().
242 *      cBytes:  Size of the memory region allocated by MEM_AllocPhysMem().
243 *  Returns:
244 *  Requires:
245 *      MEM initialized.
246 *      pVirtualAddress is a valid memory address returned by
247 *          MEM_AllocPhysMem()
248 *  Ensures:
249 *      pVirtualAddress is no longer a valid pointer to memory.
250 */
251	extern VOID MEM_FreePhysMem(PVOID pVirtualAddress,
252				    DWORD pPhysicalAddress, ULONG cBytes);
253
254/*
255 *  ======== MEM_FreeObject ========
256 *  Purpose:
257 *      Utility macro to invalidate an object's signature, and deallocate it.
258 *  Parameters:
259 *      pObj:   Pointer to the object to free.
260 *  Returns:
261 *  Requires:
262 *      Same requirements as MEM_Free().
263 *  Ensures:
264 *      A subsequent call to MEM_IsValidHandle() will fail for this object.
265 */
266#define MEM_FreeObject(pObj)    \
267{                               \
268    pObj->dwSignature = 0x00;   \
269    MEM_Free(pObj);             \
270}
271
272/*
273 *  ======== MEM_GetNumPages ========
274 *  Purpose:
275 *      Calculate the number of pages corresponding to the supplied buffer.
276 *  Parameters:
277 *      pAddr:  Linear (virtual) address of the buffer.
278 *      cBytes: Number of bytes in the buffer.
279 *  Returns:
280 *      Number of pages.
281 *  Requires:
282 *      MEM initialized.
283 *  Ensures:
284 *      If cBytes > 0, number of pages returned > 0.
285 */
286	extern INT MEM_GetNumPages(IN PVOID pAddr, IN ULONG cBytes);
287
288/*
289 *  ======== MEM_Init ========
290 *  Purpose:
291 *      Initializes private state of MEM module.
292 *  Parameters:
293 *  Returns:
294 *      TRUE if initialized; FALSE if error occured.
295 *  Requires:
296 *  Ensures:
297 *      MEM initialized.
298 */
299	extern bool MEM_Init();
300
301/*
302 *  ======== MEM_IsValidHandle ========
303 *  Purpose:
304 *      Validate the object handle.
305 *  Parameters:
306 *      hObj:   Handle to object created with MEM_AllocObject().
307 *      Sig:    Expected signature DWORD.
308 *  Returns:
309 *      TRUE if handle is valid; FALSE otherwise.
310 *  Requires:
311 *      The object structure has a dwSignature field. Ensured by compiler.
312 *  Ensures:
313 */
314#define MEM_IsValidHandle(hObj, Sig)                \
315     ((hObj != NULL) && (hObj->dwSignature == Sig))
316
317/* Structure reflecting a physical address and size of memory referenced. */
318	struct MEM_PHYSICAL {
319		DWORD dwPhysAddr;
320		DWORD nBytes;
321	} ;
322
323/*
324 *  ======== MEM_LinearAddress ========
325 *  Purpose:
326 *      Get the linear address corresponding to the given physical address.
327 *  Parameters:
328 *      pPhysAddr:  Physical address to be mapped.
329 *      cBytes:     Number of bytes in physical range to map.
330 *  Returns:
331 *      The corresponding linear address, or NULL if unsuccessful.
332 *  Requires:
333 *      MEM initialized.
334 *  Ensures:
335 *  Notes:
336 *      If valid linear address is returned, be sure to call
337 *      MEM_UnmapLinearAddress().
338 */
339#ifndef LINUX
340	extern PVOID MEM_LinearAddress(IN PVOID pPhyAddr, IN ULONG cBytes);
341#else
342#define MEM_LinearAddress(pPhyAddr, cBytes) pPhyAddr
343#endif
344
345#ifndef LINUX
346/*
347 *  ======== MEM_PageLock ========
348 *  Purpose:
349 *      Calls kernel services to map the set of pages identified by a private
350 *      process pointer and a byte count into the calling process's globally
351 *      shared address space.
352 *  Parameters
353 *      pBuffer:    Pointer to a process-private data buffer.
354 *      cSize:      Size in bytes of the data buffer.
355 *  Returns:
356 *      A pointer to linear page locked memory;
357 *      NULL if a failure occured locking memory.
358 *  Requires:
359 *      - MEM initialized.
360 *      - The size (cSize) must accurately reflect the size of the buffer to
361 *        be locked, since the page count is derived from this number.
362 *      - Valid pBuffer.
363 *  Ensures:
364 *      Memory locked by this service can be accessed at interrupt time, or
365 *      from other memory contexts.
366 */
367	extern PVOID MEM_PageLock(IN PVOID pBuffer, IN ULONG cSize);
368
369/*
370 *  ======== MEM_PageUnlock ========
371 *  Purpose:
372 *      Unlocks a buffer previously locked using MEM_PageLock().
373 *  Parameters:
374 *      pBuffer:    Pointer to locked memory (as returned by MEM_PageLock()).
375 *      cSize:      Size in bytes of the buffer.
376 *  Returns:
377 *      Returns DSP_SOK if unlock successful; else, returns DSP_EFAIL;
378 *  Requires:
379 *      - MEM initialized.
380 *      - Valid pBuffer.
381 *  Ensures:
382 *      Will unlock the pages of memory when the lock count drops to zero.
383 *      (MEM_PageLock() increments the lock count, and MEM_PageUnlock
384 *      decrements the count).
385 */
386	extern DSP_STATUS MEM_PageUnlock(IN PVOID pBuffer, IN ULONG cSize);
387#endif
388
389/*
390 *  ======== MEM_UnmapLinearAddress ========
391 *  Purpose:
392 *      Unmap the linear address mapped in MEM_LinearAddress.
393 *  Parameters:
394 *      pBaseAddr: Ptr to mapped memory (as returned by MEM_LinearAddress()).
395 *  Returns:
396 *  Requires:
397 *      - MEM initialized.
398 *      - pBaseAddr is a valid linear address mapped in MEM_LinearAddress.
399 *  Ensures:
400 *      - pBaseAddr no longer points to a valid linear address.
401 */
402#ifndef LINUX
403	extern VOID MEM_UnmapLinearAddress(IN PVOID pBaseAddr);
404#else
405#define MEM_UnmapLinearAddress(pBaseAddr)
406#endif
407
408/*
409 *  ======== MEM_VirtualToPhysical ========
410 *  Purpose:
411 *      Given a user allocated virtual address, return the corresponding
412 *      physical address based on the page frame address.
413 *  Parameters:
414 *      dwVirtAddr: Linear address of user allocated (and mapped) buffer.
415 *  Returns:
416 *      Returns corresponding physical address or NULL if unsuccessful
417 *  Requires:
418 *      - MEM initialized.
419 *      - dwVirtAddr is a valid linear address.
420 */
421	extern DWORD MEM_VirtualToPhysical(IN DWORD dwVirtAddr);
422
423/*
424 *  ======== MEM_ExtPhysPoolInit ========
425 *  Purpose:
426 *      Uses the physical memory chunk passed for internal consitent memory allocations.
427 *      physical address based on the page frame address.
428 *  Parameters:
429 *      poolPhysBase  starting address of the physical memory pool.
430 *      poolSize      size of the physical memory pool.
431 *  Returns:
432 *      none.
433 *  Requires:
434 *      - MEM initialized.
435 *      - valid physical address for the base and size > 0
436 */
437	extern VOID MEM_ExtPhysPoolInit(IN DWORD poolPhysBase,
438					IN DWORD poolSize);
439
440#ifdef __cplusplus
441}
442#endif
443#endif				/* MEM_ */
444