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
72 extern "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