1 /**********************************************************************
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25 ******************************************************************************/
27 #ifndef __IMG_LINUX_MM_H__
28 #define __IMG_LINUX_MM_H__
30 #include <linux/version.h>
31 #include <linux/slab.h>
33 #include <linux/list.h>
37 #define PHYS_TO_PFN(phys) ((phys) >> PAGE_SHIFT)
38 #define PFN_TO_PHYS(pfn) ((pfn) << PAGE_SHIFT)
40 #define RANGE_TO_PAGES(range) \
41 (((range) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)
43 #define ADDR_TO_PAGE_OFFSET(addr) (((unsigned long)(addr)) & (PAGE_SIZE - 1))
45 #define REMAP_PFN_RANGE(vma, addr, pfn, size, prot) \
46 remap_pfn_range(vma, addr, pfn, size, prot)
48 #define IO_REMAP_PFN_RANGE(vma, addr, pfn, size, prot) \
49 io_remap_pfn_range(vma, addr, pfn, size, prot)
51 #define VM_INSERT_PAGE(vma, addr, page) vm_insert_page(vma, addr, page)
53 static inline u32 VMallocToPhys(void *pCpuVAddr)
55 return page_to_phys(vmalloc_to_page(pCpuVAddr)) +
56 ADDR_TO_PAGE_OFFSET(pCpuVAddr);
60 enum LINUX_MEM_AREA_TYPE {
61 LINUX_MEM_AREA_IOREMAP,
62 LINUX_MEM_AREA_EXTERNAL_KV,
64 LINUX_MEM_AREA_VMALLOC,
65 LINUX_MEM_AREA_ALLOC_PAGES,
66 LINUX_MEM_AREA_SUB_ALLOC,
67 LINUX_MEM_AREA_TYPE_COUNT
73 enum LINUX_MEM_AREA_TYPE eAreaType;
76 struct IMG_CPU_PHYADDR CPUPhysAddr;
77 void __iomem *pvIORemapCookie;
82 struct IMG_SYS_PHYADDR SysPhysAddr;
83 struct IMG_SYS_PHYADDR *pSysPhysAddr;
88 struct IMG_CPU_PHYADDR CPUPhysAddr;
91 void *pvVmallocAddress;
94 struct page **pvPageList;
98 struct LinuxMemArea *psParentLinuxMemArea;
104 IMG_BOOL bMMapRegistered;
105 struct list_head sMMapItem;
106 struct list_head sMMapOffsetStructList;
111 enum PVRSRV_ERROR LinuxMMInit(void);
113 void LinuxMMCleanup(void);
115 #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
116 #define KMallocWrapper(ui32ByteSize) \
117 _KMallocWrapper(ui32ByteSize, __FILE__, __LINE__)
119 #define KMallocWrapper(ui32ByteSize) \
120 _KMallocWrapper(ui32ByteSize, NULL, 0)
122 void *_KMallocWrapper(u32 ui32ByteSize, char *szFileName, u32 ui32Line);
124 #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
125 #define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, __FILE__, __LINE__)
127 #define KFreeWrapper(pvCpuVAddr) _KFreeWrapper(pvCpuVAddr, NULL, 0)
129 void _KFreeWrapper(void *pvCpuVAddr, char *pszFileName, u32 ui32Line);
131 #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
132 #define VMallocWrapper(ui32Bytes, ui32AllocFlags) \
133 _VMallocWrapper(ui32Bytes, ui32AllocFlags, __FILE__, __LINE__)
135 #define VMallocWrapper(ui32Bytes, ui32AllocFlags) \
136 _VMallocWrapper(ui32Bytes, ui32AllocFlags, NULL, 0)
138 void *_VMallocWrapper(u32 ui32Bytes, u32 ui32AllocFlags, char *pszFileName,
141 #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
142 #define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, __FILE__, __LINE__)
144 #define VFreeWrapper(pvCpuVAddr) _VFreeWrapper(pvCpuVAddr, NULL, 0)
146 void _VFreeWrapper(void *pvCpuVAddr, char *pszFileName, u32 ui32Line);
148 struct LinuxMemArea *NewVMallocLinuxMemArea(u32 ui32Bytes, u32 ui32AreaFlags);
150 void FreeVMallocLinuxMemArea(struct LinuxMemArea *psLinuxMemArea);
152 #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
153 #define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \
154 _IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, __FILE__, __LINE__)
156 #define IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags) \
157 _IORemapWrapper(BasePAddr, ui32Bytes, ui32MappingFlags, NULL, 0)
159 void __iomem *_IORemapWrapper(struct IMG_CPU_PHYADDR BasePAddr, u32 ui32Bytes,
160 u32 ui32MappingFlags, char *pszFileName,
163 struct LinuxMemArea *NewIORemapLinuxMemArea(struct IMG_CPU_PHYADDR BasePAddr,
164 u32 ui32Bytes, u32 ui32AreaFlags);
166 void FreeIORemapLinuxMemArea(struct LinuxMemArea *psLinuxMemArea);
168 struct LinuxMemArea *NewExternalKVLinuxMemArea(
169 struct IMG_SYS_PHYADDR *pBasePAddr, void *pvCPUVAddr,
170 u32 ui32Bytes, IMG_BOOL bPhysContig, u32 ui32AreaFlags);
172 void FreeExternalKVLinuxMemArea(struct LinuxMemArea *psLinuxMemArea);
174 #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
175 #define IOUnmapWrapper(pvIORemapCookie) \
176 _IOUnmapWrapper(pvIORemapCookie, __FILE__, __LINE__)
178 #define IOUnmapWrapper(pvIORemapCookie) \
179 _IOUnmapWrapper(pvIORemapCookie, NULL, 0)
181 void _IOUnmapWrapper(void __iomem *pvIORemapCookie, char *pszFileName,
184 struct page *LinuxMemAreaOffsetToPage(struct LinuxMemArea *psLinuxMemArea,
187 #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
188 #define KMemCacheAllocWrapper(psCache, Flags) \
189 _KMemCacheAllocWrapper(psCache, Flags, __FILE__, __LINE__)
191 #define KMemCacheAllocWrapper(psCache, Flags) \
192 _KMemCacheAllocWrapper(psCache, Flags, NULL, 0)
195 void *_KMemCacheAllocWrapper(struct kmem_cache *psCache, gfp_t Flags,
196 char *pszFileName, u32 ui32Line);
198 #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS)
199 #define KMemCacheFreeWrapper(psCache, pvObject) \
200 _KMemCacheFreeWrapper(psCache, pvObject, __FILE__, __LINE__)
202 #define KMemCacheFreeWrapper(psCache, pvObject) \
203 _KMemCacheFreeWrapper(psCache, pvObject, NULL, 0)
205 void _KMemCacheFreeWrapper(struct kmem_cache *psCache, void *pvObject,
206 char *pszFileName, u32 ui32Line);
208 const char *KMemCacheNameWrapper(struct kmem_cache *psCache);
210 struct LinuxMemArea *NewIOLinuxMemArea(struct IMG_CPU_PHYADDR BasePAddr,
211 u32 ui32Bytes, u32 ui32AreaFlags);
213 void FreeIOLinuxMemArea(struct LinuxMemArea *psLinuxMemArea);
215 struct LinuxMemArea *NewAllocPagesLinuxMemArea(u32 ui32Bytes,
218 void FreeAllocPagesLinuxMemArea(struct LinuxMemArea *psLinuxMemArea);
220 struct LinuxMemArea *NewSubLinuxMemArea(
221 struct LinuxMemArea *psParentLinuxMemArea,
222 u32 ui32ByteOffset, u32 ui32Bytes);
224 void LinuxMemAreaDeepFree(struct LinuxMemArea *psLinuxMemArea);
226 void *LinuxMemAreaToCpuVAddr(struct LinuxMemArea *psLinuxMemArea);
228 struct IMG_CPU_PHYADDR LinuxMemAreaToCpuPAddr(
229 struct LinuxMemArea *psLinuxMemArea,
232 #define LinuxMemAreaToCpuPFN(psLinuxMemArea, ui32ByteOffset) \
233 PHYS_TO_PFN(LinuxMemAreaToCpuPAddr(psLinuxMemArea, \
234 ui32ByteOffset).uiAddr)
236 void inv_cache_mem_area(const struct LinuxMemArea *mem_area);
238 IMG_BOOL LinuxMemAreaPhysIsContig(struct LinuxMemArea *psLinuxMemArea);
240 static inline struct LinuxMemArea *LinuxMemAreaRoot(struct LinuxMemArea
243 if (psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC)
244 return psLinuxMemArea->uData.sSubAlloc.psParentLinuxMemArea;
246 return psLinuxMemArea;
249 static inline enum LINUX_MEM_AREA_TYPE LinuxMemAreaRootType(struct LinuxMemArea
252 return LinuxMemAreaRoot(psLinuxMemArea)->eAreaType;
255 const char *LinuxMemAreaTypeToString(enum LINUX_MEM_AREA_TYPE eMemAreaType);
257 #if defined(CONFIG_PVR_DEBUG_EXTRA) || defined(DEBUG_LINUX_MEM_AREAS)
258 const char *HAPFlagsToString(u32 ui32Flags);