1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 // Software and any modification/derivatives thereof.
18 // No right, ownership, or interest to MStar Software and any
19 // modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 // supplied together with third party`s software and the use of MStar
23 // Software may require additional licenses from third parties.
24 // Therefore, you hereby agree it is your sole responsibility to separately
25 // obtain any and all third party right and license necessary for your use of
26 // such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 // MStar`s confidential information and you agree to keep MStar`s
30 // confidential information in strictest confidence and not disclose to any
31 // third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 // kind. Any warranties are hereby expressly disclaimed by MStar, including
35 // without limitation, any warranties of merchantability, non-infringement of
36 // intellectual property rights, fitness for a particular purpose, error free
37 // and in conformity with any international standard. You agree to waive any
38 // claim against MStar for any loss, damage, cost or expense that you may
39 // incur related to your use of MStar Software.
40 // In no event shall MStar be liable for any direct, indirect, incidental or
41 // consequential damages, including without limitation, lost of profit or
42 // revenues, lost or damage of data, and unauthorized system use.
43 // You agree that this Section 4 shall still apply without being affected
44 // even if MStar Software has been modified by MStar in accordance with your
45 // request or instruction for your use, except otherwise agreed by both
46 // parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 // services in relation with MStar Software to you for your use of
50 // MStar Software in conjunction with your or your customer`s product
51 // ("Services").
52 // You understand and agree that, except otherwise agreed by both parties in
53 // writing, Services are provided on an "AS IS" basis and the warranty
54 // disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 // or otherwise:
58 // (a) conferring any license or right to use MStar name, trademark, service
59 // mark, symbol or any other identification;
60 // (b) obligating MStar or any of its affiliates to furnish any person,
61 // including without limitation, you and your customers, any assistance
62 // of any kind whatsoever, or any information; or
63 // (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 // of Taiwan, R.O.C., excluding its conflict of law rules.
67 // Any and all dispute arising out hereof or related hereto shall be finally
68 // settled by arbitration referred to the Chinese Arbitration Association,
69 // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 // Rules of the Association by three (3) arbitrators appointed in accordance
71 // with the said Rules.
72 // The place of arbitration shall be in Taipei, Taiwan and the language shall
73 // be English.
74 // The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78
79 //=============================================================================
80 #include <MsCommon.h>
81 #include <cyg/hal/hal_if.h>
82 #include <cyg/hal/hal_arch.h>
83 #include "include/drvConfig.h"
84 #include "include/drvPorts.h"
85 #include "include/drvKernel.h"
86 #include "include/drvBitops.h"
87
88 #if 1
89 #define NOCACHE_MEMORY_SIZE SZ_128K //SZ_64K, Kaiserin
90 //#define NOCACHE_MEMORY_REGION MEM_REGION_8M
91 //#define NOCACHE_REGION_NUM 3
92 //#define NOCACHE_MIN_ALIGN 32
93 //#define NCMEM_BUFFER_POOLS 4
94
95 extern int BaseOfFreeMemory;
96 extern int TopOfFreeMemory;
97 extern int BaseOfHeap;
98 extern int TopOfHeap;
99
100 #define NCM_DEBUG
101
102 #ifdef NCM_DEBUG
103 #define NCM_Dbg(x,...) diag_printf(x,__VA_ARGS__)
104 #else
105 #define NCM_Dbg(x,...)
106 #endif
107
108 struct ncmem_pool_tag { /* the pool */
109 U32 base_addr;
110 size_t pages_per_pool;
111 U32 *bitmap;
112 };
113 static struct ncmem_pool_tag ncmem_pool;
114
115 U32 ncmem_addr;
116 U32 ncmem_base;
117
118 /*******************************************************************************
119 * Routine name : ncmem_free_page
120 * returns : none
121 * Created by : Peter Liao
122 * Date created : 2004/01/25
123 * Description : Create a non-cacheable and non-bufferable page memory pool via
124 * CPU memoryt region declaration API. Page momery pool is splited
125 * by the size of page memory. Each page memory is aligned to
126 * page_size bytes.
127 * Notes :
128 *******************************************************************************/
init_cache_memory(void)129 void init_cache_memory(void)
130 {
131 int mapsize;
132
133
134 ncmem_addr=(U32)KSEG02KSEG1(Usb_AllocateNonCachedMemory(NOCACHE_MEMORY_SIZE + PAGE_SIZE));
135
136 USB_ASSERT(ncmem_addr, "Allocate ncmem buffer fail\n");
137 ncmem_base = (ncmem_addr + PAGE_SIZE)&(~(PAGE_SIZE-1));
138 NCM_Dbg("The base address is 0x%8lX\n", ncmem_base);
139
140 // Initialize non-cached memory pool information
141 ncmem_pool.pages_per_pool = (NOCACHE_MEMORY_SIZE/PAGE_SIZE);
142 mapsize = ncmem_pool.pages_per_pool;
143 mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
144 mapsize *= sizeof (U32);
145 ncmem_pool.base_addr =(U32) KSEG02KSEG1(ncmem_base); // convert cached address to uncached
146 // ncmem_pool.bitmap = (U32 *)LIB_MemoryAllocate(mapsize, MALLOC_CACHED_ADDR);
147 ncmem_pool.bitmap = (U32*)Usb_AllocateNonCachedMemory(mapsize);
148 memset(ncmem_pool.bitmap, ((U32)-1), mapsize);//Bitmap: 0-used 1-unused
149
150 NCM_Dbg("Base addr is 0x%08lX\n",ncmem_pool.base_addr);
151 NCM_Dbg("Top addr is 0x%08lX\n",ncmem_pool.base_addr+NOCACHE_MEMORY_SIZE-1);
152 NCM_Dbg("Pages per pool is %d\n",ncmem_pool.pages_per_pool);
153 NCM_Dbg("Bit map base addr is %p\n",ncmem_pool.bitmap);
154 }
155
156 /*******************************************************************************
157 * Routine name : ncmem_alloc_page
158 * returns : 0 - pointer to allocated virtual address
159 * dma_addr : pointer to allocated physical address
160 * Created by : Peter Liao
161 * Date created : 2004/01/25
162 * Description : It will allocate a new non-cacheable and non-bufferable memory
163 * (size = page_size) from non-cacheable page memory pool for callee
164 * PAGE_SIZE is defined in pci_mem.h file
165 * Notes :
166 *******************************************************************************/
ncmem_alloc_page(dma_addr_t * dma_addr)167 void *ncmem_alloc_page(dma_addr_t *dma_addr)
168 {
169 U32 i;
170 int map, page;
171 size_t offset;
172 void *retval;
173 U32 flags;
174
175 spin_lock_irqsave (&pool->lock, flags);
176 /* only cachable accesses here ... */
177 for (map = 0, i = 0;
178 i < ncmem_pool.pages_per_pool;
179 i += BITS_PER_LONG, map++)
180 {
181 if (ncmem_pool.bitmap[map] == 0)
182 continue;
183 page = ffz (~ ncmem_pool.bitmap [map]);
184 if ((i + page) < ncmem_pool.pages_per_pool) {
185 clear_bit ( page, &ncmem_pool.bitmap [map],U32);
186 offset = (BITS_PER_LONG * map) + page;
187 offset *= PAGE_SIZE;
188 goto ready;
189 }
190 }
191
192 NCM_Dbg("ERROR: No enough non-cached memory space !!%s\n","");
193 retval = 0;
194 goto done;
195
196 ready:
197 retval = (void*) (offset + (size_t) (ncmem_pool.base_addr));
198 *dma_addr = (dma_addr_t)USB_VA2PA((U32)retval); // Convert to physical address for DMA
199 done:
200 spin_unlock_irqrestore (&pool->lock, flags);
201 NCM_Dbg("The allocated addr is %p, bit_map[%d] is 0x%08lX\n",retval,map,(U32)(ncmem_pool.bitmap[map]));
202 return retval;
203 }
204
205 /*******************************************************************************
206 * Routine name : ncmem_free_page
207 * returns : none
208 * addr : allocated virtual base address
209 * Created by : Peter Liao
210 * Date created : 2004/01/25
211 * Description : It will de-allocate/release the allocated non-cacheable memory
212 * page to non-cacheable page memory pool.
213 * Notes :
214 *******************************************************************************/
ncmem_free_page(U32 addr)215 void ncmem_free_page(U32 addr)
216 {
217 U32 flags;
218 int map, page;
219
220 page = addr - ncmem_pool.base_addr;
221 page /= PAGE_SIZE;
222 map = page / BITS_PER_LONG;
223 page %= BITS_PER_LONG;
224 spin_lock_irqsave (NULL, flags);
225 set_bit (page, &(ncmem_pool.bitmap[map]), U32);
226 NCM_Dbg("Free Block: bitmap[%d] is 0x%08lX",map,(U32)ncmem_pool.bitmap[map]);
227 spin_unlock_irqrestore (&pool->lock, flags);
228 }
229 /*******************************************************************************
230 * Routine name : ncmem_alloc
231 * returns : 0 - pointer to allocated virtual address
232 * dma_addr : pointer to allocated physical address
233 * Created by : Peter Liao
234 * Date created : 2004/02/10
235 * Description : It will allocate a new non-cacheable and non-bufferable memory
236 * (size = user specific) from non-cacheable page memory pool for callee
237 * Therefore, it may waste up memory space if the size is not mutiply
238 * of page size. Callee should call this function before calling
239 * ncmem_alloc_page because of continuous issue.
240 * Notes :
241 *******************************************************************************/
ncmem_alloc(dma_addr_t * dma_addr,U32 size)242 void *ncmem_alloc(dma_addr_t *dma_addr, U32 size)
243 {
244 U32 flags;
245 U32 i;
246 U32 map, page;
247 U32 num_of_pages;
248 size_t offset;
249 void *retval;
250
251 //If the size is not multiply of PAGE_SIZE, just allocate a PAGE for remaining space
252 if ( size%PAGE_SIZE != 0)
253 size = size/PAGE_SIZE +1;
254 else
255 size = size/PAGE_SIZE;
256 num_of_pages = size/PAGE_SIZE;
257 spin_lock_irqsave (&pool->lock, flags);
258 /* only cachable accesses here ... */
259 for (map = 0, i = 0;
260 i < ncmem_pool.pages_per_pool;
261 i += BITS_PER_LONG, map++)
262 {
263 if (ncmem_pool.bitmap[map] == 0)
264 continue;
265 page = ffz (~ ncmem_pool.bitmap [map]);
266 if ((i + page) < ncmem_pool.pages_per_pool) {
267 offset = (BITS_PER_LONG * map) + page;
268 offset *= PAGE_SIZE;
269 goto ready;
270 }
271 }
272 NCM_Dbg("ERROR: No enough non-cached memory space !!%s\n","");
273 retval = 0;
274 goto done;
275
276 ready:
277 //Allocate enough pages for required memory space
278 for(i=0;(i < num_of_pages);i++)
279 {
280 if ( page >= BITS_PER_LONG )
281 {
282 page = 0;
283 map++;
284 }
285 clear_bit ( page++, &ncmem_pool.bitmap [map],U32);
286 }
287 retval = (void*) (offset + (size_t) (ncmem_pool.base_addr));
288 *dma_addr = (dma_addr_t)USB_VA2PA((U32)retval);
289 done:
290 spin_unlock_irqrestore (&pool->lock, flags);
291 NCM_Dbg("The allocated addr = %p, size = %ld pages = %ld, end of bitmap[%ld]=0x%08lX",retval ,size, num_of_pages, map,(U32)ncmem_pool.bitmap[map]);
292 return retval;
293 }
294
295 /*******************************************************************************
296 * Routine name : ncmem_free
297 * returns : none
298 * addr : allocated virtual base address
299 * size : allocated size
300 * Created by : Peter Liao
301 * Date created : 2004/02/10
302 * Description : It will de-allocate/release the allocated non-cacheable memory
303 * space groupged by pages.
304 * Notes :
305 *******************************************************************************/
ncmem_free(U32 addr,U32 size)306 void ncmem_free(U32 addr,U32 size)
307 {
308 U32 flags;
309 int i;
310 int map, page, num_of_pages;
311
312 if ( size%PAGE_SIZE != 0)
313 size = size/PAGE_SIZE +1;
314 else
315 size = size/PAGE_SIZE;
316 num_of_pages = size/PAGE_SIZE;
317
318 page = ncmem_pool.base_addr - addr;
319 page /= PAGE_SIZE;
320 map = page / BITS_PER_LONG;
321 page %= BITS_PER_LONG;
322 spin_lock_irqsave (&pool->lock, flags);
323 for(i=0;(i < num_of_pages);i++)
324 {
325 if ( page >= BITS_PER_LONG )
326 {
327 page = 0;
328 map++;
329 }
330 set_bit (page, &(ncmem_pool.bitmap[map]), U32);
331 }
332 NCM_Dbg("Free non-cacheable memory : size = %ld = %d pages, end of bitmap[%d]=0x%08lX",size, num_of_pages, map,(U32)ncmem_pool.bitmap[map]);
333 spin_unlock_irqrestore (&pool->lock, flags);
334 }
335
Destory_NC_mem(void)336 void Destory_NC_mem(void)
337 {
338 #if 0
339 LIB_MemoryFree((void*) ncmem_base);
340 #else
341 //MsOS_FreeMemory((void*)CYGARC_CACHED_ADDRESS( ncmem_addr),gs32NonCachedPoolID_MIU0 );
342 Usb_FreeNonCachedMemory((void*)CYGARC_CACHED_ADDRESS( ncmem_addr));
343 #endif
344 }
345
346 extern void MsOS_FlushMemory(void);
Chip_Flush_Memory(void)347 void Chip_Flush_Memory(void)
348 {
349 MsOS_FlushMemory();
350 }
351
352 #endif //#ifdef
353
354