[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / family / hlos / knl / ti81xx / ti81xxducati / ti81xxvideom3 / Dm8168M3VideoHalMmu.c
1 /*
2 * @file Dm8168M3VideoHalMmu.c
3 *
4 * @brief Hardware abstraction for Memory Management Unit module.
5 *
6 * This module is responsible for handling slave MMU-related
7 * hardware- specific operations.
8 * The implementation is specific to DM8168VIDEOM3.
9 *
10 *
11 * ============================================================================
12 *
13 * Copyright (c) 2008-2012, Texas Instruments Incorporated
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * * Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 *
22 * * Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 *
26 * * Neither the name of Texas Instruments Incorporated nor the names of
27 * its contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
31 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
32 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
35 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
36 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
37 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
38 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
39 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
40 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 * Contact information for paper mail:
42 * Texas Instruments
43 * Post Office Box 655303
44 * Dallas, Texas 75265
45 * Contact information:
46 * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
47 * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
48 * ============================================================================
49 *
50 */
54 /* Standard headers */
55 #include <ti/syslink/Std.h>
57 /* OSAL and utils headers */
58 #include <ti/syslink/utils/List.h>
59 #include <ti/syslink/utils/Trace.h>
60 #include <ti/syslink/utils/OsalPrint.h>
61 #include <ti/syslink/utils/Memory.h>
62 #include <Bitops.h>
64 /* Module level headers */
65 #include <_ProcDefs.h>
66 #include <Processor.h>
68 /* Hardware Abstraction Layer headers */
69 #include <Dm8168M3VideoHal.h>
70 #include <Dm8168M3VideoHalMmu.h>
71 #include <Dm8168M3VideoPhyShmem.h>
74 #if defined (__cplusplus)
75 extern "C" {
76 #endif
79 /* =============================================================================
80 * Macros and types
81 * =============================================================================
82 */
83 /*!
84 * @brief Defines default mixedSize i.e same types of pages in one segment
85 */
86 #define MMU_RAM_DEFAULT 0
87 /*!
88 * @brief returns page number based on physical address
89 */
90 #define ti_syslink_phys_to_page(phys) pfn_to_page((phys) >> PAGE_SHIFT)
92 /*!
93 * @brief helper macros
94 */
95 #define SLAVEVIRTADDR(x) ((x)->addr [ProcMgr_AddrType_SlaveVirt])
96 #define SLAVEPHYSADDR(x) ((x)->addr [ProcMgr_AddrType_SlavePhys])
97 #define MASTERPHYSADDR(x) ((x)->addr [ProcMgr_AddrType_MasterPhys])
99 #define MMUPAGE_ALIGN(size, psz) (((size) + psz - 1) & ~(psz -1))
101 /* =============================================================================
102 * Forward declarations of internal functions
103 * =============================================================================
104 */
105 #if defined(SYSLINK_BUILDOS_LINUX)
106 /* Enables the MMU for GEM Module. */
107 Int _DM8168VIDEOM3_halMmuEnable (DM8168VIDEOM3_HalObject * halObject,
108 UInt32 numMemEntries,
109 ProcMgr_AddrInfo * memTable);
111 /* Disables the MMU for GEM Module. */
112 Int _DM8168VIDEOM3_halMmuDisable (DM8168VIDEOM3_HalObject * halObject);
114 /* Add entry in TWL. */
115 Int
116 _DM8168VIDEOM3_halMmuAddEntry (DM8168VIDEOM3_HalObject * halObject,
117 DM8168VIDEOM3_HalMmuEntryInfo * entry);
118 /* Add static entries in TWL. */
119 Int
120 _DM8168VIDEOM3_halMmuAddStaticEntries (DM8168VIDEOM3_HalObject * halObject,
121 UInt32 numMemEntries,
122 ProcMgr_AddrInfo * memTable);
124 /* Delete entry from TLB. */
125 Int
126 _DM8168VIDEOM3_halMmuDeleteEntry (DM8168VIDEOM3_HalObject * halObject,
127 DM8168VIDEOM3_HalMmuEntryInfo * entry);
128 /* Set entry in to TLB. */
129 Int
130 _DM8168VIDEOM3_halMmuPteSet (DM8168VIDEOM3_HalObject * halObject,
131 DM8168VIDEOM3_HalMmuEntryInfo * setPteInfo);
132 /* Print page dump */
133 Int
134 _DM8168VIDEOM3_badPageDump(UInt32 phyAddr, struct page *pg);
136 /* IOMMU Exported function */
137 extern
138 void
139 iopgtable_lookup_entry (struct iommu *obj, u32 da, u32 **ppgd, u32 **ppte);
140 #endif /* #if defined(SYSLINK_BUILDOS_LINUX) */
142 /* =============================================================================
143 * APIs called by DM8168VIDEOM3PROC module
144 * =============================================================================
145 */
146 /*!
147 * @brief Function to control MMU operations for this slave device.
148 *
149 * @param halObj Pointer to the HAL object
150 * @param cmd MMU control command
151 * @param arg Arguments specific to the MMU control command
152 *
153 * @sa
154 */
155 Int
156 DM8168VIDEOM3_halMmuCtrl (Ptr halObj, Processor_MmuCtrlCmd cmd, Ptr args)
157 {
158 Int status = PROCESSOR_SUCCESS;
159 #if defined(SYSLINK_BUILDOS_LINUX)
160 DM8168VIDEOM3_HalObject * halObject = NULL;
161 #endif /* #if defined(SYSLINK_BUILDOS_LINUX) */
162 GT_3trace (curTrace, GT_ENTER, "DM8168VIDEOM3_halMmuCtrl", halObj, cmd, args);
163 #if defined(SYSLINK_BUILDOS_LINUX)
164 GT_assert (curTrace, (halObj != NULL));
166 halObject = (DM8168VIDEOM3_HalObject *) halObj ;
168 switch (cmd) {
169 case Processor_MmuCtrlCmd_Enable:
170 {
171 DM8168VIDEOM3_HalMmuCtrlArgs_Enable * enableArgs;
172 enableArgs = (DM8168VIDEOM3_HalMmuCtrlArgs_Enable *) args;
173 halObject = (DM8168VIDEOM3_HalObject *) halObj;
174 status = _DM8168VIDEOM3_halMmuEnable (halObject,
175 enableArgs->numMemEntries,
176 enableArgs->memEntries);
178 #if !defined(SYSLINK_BUILD_OPTIMIZE)
179 if (status < 0) {
180 /*! @retval PROCESSOR_E_FAIL Failed to configure VIDEOM3 MMU. */
181 status = PROCESSOR_E_FAIL;
182 GT_setFailureReason (curTrace,
183 GT_4CLASS,
184 "DM8168VIDEOM3_halMmuCtrl",
185 status,
186 "Failed to configure VIDEOM3 MMU"
187 "at _DM8168VIDEOM3_halMmuEnable");
188 }
189 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
190 }
191 break;
193 case Processor_MmuCtrlCmd_Disable:
194 {
195 /* args are not used. */
196 halObject = (DM8168VIDEOM3_HalObject *) halObj;
197 status = _DM8168VIDEOM3_halMmuDisable (halObject);
198 #if !defined(SYSLINK_BUILD_OPTIMIZE)
199 if (status < 0) {
200 /*! @retval PROCESSOR_E_FAIL Failed to disable VIDEOM3 MMU. */
201 status = PROCESSOR_E_FAIL;
202 GT_setFailureReason (curTrace,
203 GT_4CLASS,
204 "DM8168VIDEOM3_halMmuCtrl",
205 status,
206 "Failed to disable VIDEOM3 MMU");
207 }
208 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
209 }
210 break ;
212 case Processor_MmuCtrlCmd_AddEntry:
213 {
214 DM8168VIDEOM3_HalMmuCtrlArgs_AddEntry * addEntry;
215 addEntry = (DM8168VIDEOM3_HalMmuCtrlArgs_AddEntry *) args;
217 halObject = (DM8168VIDEOM3_HalObject *) halObj;
218 /* Add the entry in TLB for new request */
219 status = _DM8168VIDEOM3_halMmuAddEntry (halObject,addEntry) ;
220 #if !defined(SYSLINK_BUILD_OPTIMIZE)
221 if (status < 0) {
222 /*! @retval PROCESSOR_E_FAIL Failed to dynamically add VIDEOM3 MMU
223 * entry. */
224 status = PROCESSOR_E_FAIL;
225 GT_setFailureReason (curTrace,
226 GT_4CLASS,
227 "DM8168VIDEOM3_halMmuCtrl",
228 status,
229 "Failed to dynamically add VIDEOM3 MMU entry");
230 }
231 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
232 }
233 break;
235 case Processor_MmuCtrlCmd_DeleteEntry:
236 {
237 DM8168VIDEOM3_HalMmuCtrlArgs_DeleteEntry * deleteEntry;
238 deleteEntry = (DM8168VIDEOM3_HalMmuCtrlArgs_DeleteEntry *) args;
240 halObject = (DM8168VIDEOM3_HalObject *) halObj;
241 /* Add the entry in TLB for new request */
242 status = _DM8168VIDEOM3_halMmuDeleteEntry (halObject,deleteEntry);
243 #if !defined(SYSLINK_BUILD_OPTIMIZE)
244 if (status < 0) {
245 /*! @retval PROCESSOR_E_FAIL Failed to dynamically delete VIDEOM3
246 * MMU entry */
247 status = PROCESSOR_E_FAIL;
248 GT_setFailureReason (curTrace,
249 GT_4CLASS,
250 "DM8168VIDEOM3_halMmuCtrl",
251 status,
252 "Failed to dynamically add VIDEOM3 MMU entry");
253 }
254 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
255 }
256 break;
258 default:
259 {
260 /*! @retval PROCESSOR_E_INVALIDARG Invalid argument */
261 status = PROCESSOR_E_INVALIDARG;
262 GT_setFailureReason (curTrace,
263 GT_4CLASS,
264 "DM8168VIDEOM3_halMmuCtrl",
265 status,
266 "Unsupported MMU ctrl cmd specified");
267 }
268 break;
269 }
270 #endif /* #if defined(SYSLINK_BUILDOS_LINUX) */
271 GT_1trace (curTrace, GT_LEAVE, "DM8168VIDEOM3_halMmuCtrl",status);
273 /*! @retval PROCESSOR_SUCCESS Operation successful */
274 return status;
275 }
277 #if defined(SYSLINK_BUILDOS_LINUX)
278 /* =============================================================================
279 * Internal functions
280 * =============================================================================
281 */
282 /*!
283 * @brief Enables and configures the VIDEOM3 MMU as per provided memory map.
284 *
285 * @param halObject Pointer to the HAL object
286 * @param numMemEntries Number of memory entries in memTable
287 * @param memTable Table of memory entries to be configured
288 *
289 * @sa
290 */
292 Int
293 _DM8168VIDEOM3_halMmuAddStaticEntries (DM8168VIDEOM3_HalObject * halObject,
294 UInt32 numMemEntries,
295 ProcMgr_AddrInfo * memTable)
296 {
297 Int status = PROCESSOR_SUCCESS;
298 DM8168VIDEOM3_HalMmuEntryInfo staticEntry;
299 UInt32 i;
301 GT_3trace (curTrace, GT_ENTER, "_DM8168VIDEOM3_halMmuAddStaticEntries",
302 halObject, numMemEntries, memTable);
304 GT_assert (curTrace, (halObject != NULL));
305 /* It is possible that numMemEntries may be 0, if user does not want to
306 * configure any default regions.
307 * memTable may also be NULL.
308 */
310 for (i = 0 ; i < numMemEntries && (status >= 0) ; i++) {
311 if (SLAVEVIRTADDR (&memTable [i]) >= MMU_GLOBAL_MEMORY) {
312 /* Configure the TLB */
313 if (memTable [i].size != 0) {
314 staticEntry.slaveVirtAddr =
315 SLAVEVIRTADDR (&memTable [i]);
316 staticEntry.size = memTable[i].size;
317 staticEntry.masterPhyAddr =
318 MASTERPHYSADDR (&memTable [i]);
319 /*TBD : elementSize, endianism, mixedSized are hard
320 * coded now, must be configurable later*/
321 staticEntry.elementSize = MMU_RAM_ELSZ_16;
322 staticEntry.endianism = LITTLE_ENDIAN;
323 staticEntry.mixedSize = MMU_TLBES;
324 status = _DM8168VIDEOM3_halMmuAddEntry (halObject,
325 &staticEntry);
326 if (status < 0) {
327 /*! @retval PROCESSOR_E_FAIL Failed to add MMU entry. */
328 status = PROCESSOR_E_FAIL;
329 GT_setFailureReason (curTrace,
330 GT_4CLASS,
331 "_DM8168VIDEOM3_halMmuAddStaticEntries",
332 status,
333 "Failed to add MMU entry!");
334 }
335 }
336 }
337 }
338 GT_1trace (curTrace, GT_LEAVE, "_DM8168VIDEOM3_halMmuAddStaticEntries", status);
340 /*! @retval PROCESSOR_SUCCESS Operation completed successfully. */
341 return status ;
342 }
343 Int
344 _DM8168VIDEOM3_halMmuEnable (DM8168VIDEOM3_HalObject * halObject,
345 UInt32 numMemEntries,
346 ProcMgr_AddrInfo * memTable)
347 {
348 Int status = PROCESSOR_SUCCESS;
349 DM8168VIDEOM3_HalMmuObject * mmuObj;
351 GT_3trace (curTrace, GT_ENTER, "_DM8168VIDEOM3_halMmuEnable",
352 halObject, numMemEntries, memTable);
354 GT_assert (curTrace, (halObject != NULL));
355 /* It is possible that numMemEntries may be 0, if user does not want to
356 * configure any default regions.
357 * memTable may also be NULL.
358 */
359 mmuObj = &(halObject->mmuObj);
360 /* Check if videoMmuHandler is alreaday available if yes put it back and get
361 * new one */
362 if(mmuObj->videoMmuHandler)
363 {
364 iommu_put(mmuObj->videoMmuHandler);
365 mmuObj->videoMmuHandler = NULL;
366 }
367 mmuObj->videoMmuHandler = iommu_get("ducati");
368 #if !defined(SYSLINK_BUILD_OPTIMIZE)
369 if (IS_ERR(mmuObj->videoMmuHandler)) {
370 /*! @retval PROCESSOR_E_FAIL Failed at iommu_get. */
371 status = PROCESSOR_E_FAIL;
372 GT_setFailureReason (curTrace,
373 GT_4CLASS,
374 "_DM8168VIDEOM3_halMmuEnable",
375 status,
376 "iommu_get failed!");
377 }
378 else {
379 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
381 if ((status >= 0) && (numMemEntries != 0)) {
382 /* Only statically created entries are being added here. */
383 status = _DM8168VIDEOM3_halMmuAddStaticEntries(halObject,
384 numMemEntries,
385 memTable);
386 #if !defined(SYSLINK_BUILD_OPTIMIZE)
387 if (status < 0) {
388 /*! @retval PROCESSOR_E_FAIL Failed at
389 * _DM8168VIDEOM3_halMmuAddStaticEntries. */
390 status = PROCESSOR_E_FAIL;
391 GT_setFailureReason (curTrace,
392 GT_4CLASS,
393 "_DM8168VIDEOM3_halMmuEnable",
394 status,
395 "_DM8168VIDEOM3_halMmuAddStaticEntries failed !");
396 }
397 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
398 }
399 #if !defined(SYSLINK_BUILD_OPTIMIZE)
400 }
401 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
403 GT_1trace (curTrace, GT_LEAVE, "_DM8168VIDEOM3_halMmuEnable", status);
405 /*! @retval PROCESSOR_SUCCESS Operation completed successfully. */
406 return status ;
407 }
410 /*!
411 * @brief Disables the VIDEOM3 MMU.
412 *
413 * @param halObject Pointer to the HAL object
414 *
415 * @sa
416 */
417 Int
418 _DM8168VIDEOM3_halMmuDisable (DM8168VIDEOM3_HalObject * halObject)
419 {
420 Int status = PROCESSOR_SUCCESS;
421 DM8168VIDEOM3_HalMmuObject * mmuObj;
423 GT_1trace (curTrace, GT_ENTER, "_DM8168VIDEOM3_halMmuDisable", halObject);
425 GT_assert (curTrace, (halObject != NULL));
426 mmuObj = &(halObject->mmuObj);
428 /*TBD : Delete all added static entries in TWL*/
430 /* Disable iommu. */
431 #if !defined(SYSLINK_BUILD_OPTIMIZE)
432 if(mmuObj->videoMmuHandler == NULL){
433 /*! @retval PROCESSOR_E_FAIL mmuObj->clkHandle is NULL ! */
434 status = PROCESSOR_E_FAIL;
435 GT_setFailureReason (curTrace,
436 GT_4CLASS,
437 "_DM8168VIDEOM3_halMmuDisable",
438 status,
439 "videoMmuHandler is NULL !");
440 }
441 else {
442 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
443 iommu_put(mmuObj->videoMmuHandler);
444 mmuObj->videoMmuHandler = NULL;
445 #if !defined(SYSLINK_BUILD_OPTIMIZE)
446 }
447 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
448 GT_1trace (curTrace, GT_LEAVE, "_DM8168VIDEOM3_halMmuDisable", status);
450 /*! @retval PROCESSOR_SUCCESS Operation completed successfully. */
451 return status;
452 }
455 /*!
456 * @brief This function adds an MMU entry for the specfied address and
457 * size.
458 *
459 * @param halObject Pointer to the HAL object
460 * @param entry entry to be added
461 *
462 * @sa
463 */
464 Int
465 _DM8168VIDEOM3_halMmuAddEntry (DM8168VIDEOM3_HalObject * halObject,
466 DM8168VIDEOM3_HalMmuEntryInfo * entry)
467 {
468 Int status = PROCESSOR_SUCCESS;
469 UInt32 * ppgd = NULL;
470 UInt32 * ppte = NULL;
471 DM8168VIDEOM3_HalMmuEntryInfo te;
472 DM8168VIDEOM3_HalMmuEntryInfo currentEntry;
473 Int32 currentEntrySize;
475 GT_2trace (curTrace, GT_ENTER, "_DM8168VIDEOM3_halMmuAddEntry",
476 halObject, entry);
478 GT_assert (curTrace, (halObject != NULL));
479 GT_assert (curTrace, (entry != NULL));
481 /* copy the entry (or entries) */
482 Memory_copy(¤tEntry,
483 entry,
484 sizeof(DM8168VIDEOM3_HalMmuEntryInfo));
486 /* Align the addresses to page size */
487 currentEntry.size += (currentEntry.slaveVirtAddr & (PAGE_SIZE_4KB -1));
488 currentEntry.slaveVirtAddr &= ~(PAGE_SIZE_4KB-1);
489 currentEntry.masterPhyAddr &= ~(PAGE_SIZE_4KB-1);
491 /* Align the size as well */
492 currentEntry.size = MMUPAGE_ALIGN(currentEntry.size, PAGE_SIZE_4KB);
493 currentEntrySize = currentEntry.size;
495 /* To find the max. page size with which both PA & VA are
496 * aligned */
497 while ((currentEntrySize != 0) &&
498 (status >= 0) &&
499 (currentEntry.slaveVirtAddr > MMU_GLOBAL_MEMORY)) {
500 if (currentEntrySize >= PAGE_SIZE_16MB
501 && !(currentEntry.slaveVirtAddr & (PAGE_SIZE_16MB - 1))) {
502 currentEntry.size = PAGE_SIZE_16MB;
503 }
504 else if (currentEntrySize >= PAGE_SIZE_1MB
505 && !(currentEntry.slaveVirtAddr & (PAGE_SIZE_1MB - 1))) {
506 currentEntry.size = PAGE_SIZE_1MB;
507 }
508 else if (currentEntrySize >= PAGE_SIZE_64KB
509 && !(currentEntry.slaveVirtAddr & (PAGE_SIZE_64KB - 1))){
510 currentEntry.size = PAGE_SIZE_64KB;
511 }
512 else if (currentEntrySize >= PAGE_SIZE_4KB
513 && !(currentEntry.slaveVirtAddr & (PAGE_SIZE_4KB - 1))){
514 currentEntry.size = PAGE_SIZE_4KB;
515 }
516 else {
517 Osal_printf ("Configuration error: "
518 " MMU entries must be aligned to their"
519 "page size(4KB,"
520 " 64KB, 1MB, or 16MB).\n");
521 Osal_printf ("Since the addresses are not aligned buffer"
522 "of size: %x at address: %x cannot be "
523 "TLB entries\n",
524 currentEntrySize, currentEntry.slaveVirtAddr);
525 /*! @retval DM8168VIDEOM3PROC_E_MMUCONFIG Memory region is not
526 aligned to page size */
527 status = DM8168VIDEOM3PROC_E_MMUCONFIG;
528 GT_setFailureReason (curTrace,
529 GT_4CLASS,
530 "_DM8168VIDEOM3_halMmuAddEntry",
531 status,
532 "Memory region is not aligned to page size!");
533 break ;
534 }
536 /* DO NOT put this check under SYSLINK_BUILD_OPTIMIZE */
537 if (status >= 0) {
538 /* Check every page if exists */
539 iopgtable_lookup_entry (halObject->mmuObj.videoMmuHandler,
540 currentEntry.slaveVirtAddr,
541 (u32 **) &ppgd,
542 (u32 **) &ppte);
544 /* Lookup if the entry exists */
545 if (!ppgd || !ppte) {
546 /* Entry doesnot exists, insert this page */
547 te.size = currentEntry.size;
548 te.slaveVirtAddr = currentEntry.slaveVirtAddr;
549 te.masterPhyAddr = currentEntry.masterPhyAddr;
550 te.elementSize = currentEntry.elementSize;
551 te.endianism = currentEntry.endianism;
552 te.mixedSize = currentEntry.mixedSize;
553 status = _DM8168VIDEOM3_halMmuPteSet (halObject, &te);
554 }
555 else if (ppgd && ppte) {
556 if (currentEntry.masterPhyAddr != (*ppte & IOPAGE_MASK)) {
557 /* Entry doesnot exists, insert this page */
558 te.size = currentEntry.size;
559 te.slaveVirtAddr = currentEntry.slaveVirtAddr;
560 te.masterPhyAddr = currentEntry.masterPhyAddr;
561 te.elementSize = currentEntry.elementSize;
562 te.endianism = currentEntry.endianism;
563 te.mixedSize = currentEntry.mixedSize;
564 status = _DM8168VIDEOM3_halMmuPteSet (halObject, &te);
565 }
566 }
568 #if !defined(SYSLINK_BUILD_OPTIMIZE)
569 if (status < 0) {
570 GT_setFailureReason (
571 curTrace,
572 GT_4CLASS,
573 "_DM8168VIDEOM3_halMmuAddEntry",
574 status,
575 "Failed to in _DM8168VIDEOM3_halMmuPteSet!");
576 break;
577 }
578 else {
579 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
580 currentEntrySize -= currentEntry.size;
581 currentEntry.masterPhyAddr += currentEntry.size;
582 currentEntry.slaveVirtAddr += currentEntry.size;
583 #if !defined(SYSLINK_BUILD_OPTIMIZE)
584 }
585 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
586 }
587 }
589 GT_1trace (curTrace, GT_LEAVE, "_DM8168VIDEOM3_halMmuAddEntry", status);
591 /*! @retval PROCESSOR_SUCCESS Operation completed successfully. */
592 return status;
593 }
596 /*!
597 * @brief Prints the page dump in case of error.
598 *
599 * @param phyAddr Physical address
600 * @param pg Mapped page
601 *
602 * @sa
603 */
604 Int
605 _DM8168VIDEOM3_badPageDump(UInt32 phyAddr, struct page *pg)
606 {
607 Int status = PROCESSOR_SUCCESS;
609 GT_2trace (curTrace, GT_ENTER, "_DM8168VIDEOM3_badPageDump",
610 phyAddr, pg);
612 GT_assert (curTrace, (pg != NULL));
614 Osal_printf("Bad page state in process \n"
615 "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n"
616 "Backtrace:\n",
617 pg, (Int)(2*sizeof(UInt32)),
618 (UInt32)pg->flags, pg->mapping,
619 page_mapcount(pg), page_count(pg));
621 /*! @retval PROCESSOR_SUCCESS Operation completed successfully. */
622 return status;
623 }
626 /*!
627 * @brief This function deletes an MMU entry for the specfied address and
628 * size.
629 *
630 * @param halObject Pointer to the HAL object
631 * @param slaveVirtAddr VIDEOM3 virtual address of the memory region
632 * @param size Size of the memory region to be configured
633 * @param isDynamic Is the MMU entry being dynamically added?
634 *
635 * @sa
636 */
637 Int
638 _DM8168VIDEOM3_halMmuDeleteEntry (DM8168VIDEOM3_HalObject * halObject,
639 DM8168VIDEOM3_HalMmuEntryInfo * entry)
640 {
641 Int status = PROCESSOR_SUCCESS;
642 UInt32 * iopgd = NULL;
643 UInt32 currentEntrySize;
644 DM8168VIDEOM3_HalMmuEntryInfo currentEntry;
645 DM8168VIDEOM3_HalMmuObject * mmuObj;
646 UInt32 clearBytes = 0;
648 GT_2trace (curTrace, GT_ENTER, "_DM8168VIDEOM3_halMmuDeleteEntry",
649 halObject, entry);
651 GT_assert (curTrace, (halObject != NULL));
652 GT_assert (curTrace, (entry != NULL));
653 GT_assert (curTrace, (entry->size != 0));
655 mmuObj = &(halObject->mmuObj);
657 /* copy the entry (or entries) */
658 Memory_copy(¤tEntry,
659 entry,
660 sizeof(DM8168VIDEOM3_HalMmuEntryInfo));
662 /* Align the addresses to page size */
663 currentEntry.size += (currentEntry.slaveVirtAddr & (PAGE_SIZE_4KB -1));
664 currentEntry.slaveVirtAddr &= ~(PAGE_SIZE_4KB-1);
666 /* Align the size as well */
667 currentEntry.size = MMUPAGE_ALIGN(currentEntry.size, PAGE_SIZE_4KB);
668 currentEntrySize = currentEntry.size;
670 /* To find the max. page size with which both PA & VA are
671 * aligned */
672 while ((currentEntrySize != 0)
673 && (status >= 0)
674 && (currentEntry.slaveVirtAddr > MMU_GLOBAL_MEMORY)) {
675 if (currentEntrySize >= PAGE_SIZE_16MB
676 && !(currentEntry.slaveVirtAddr & (PAGE_SIZE_16MB - 1))) {
677 currentEntry.size = PAGE_SIZE_16MB;
678 }
679 else if (currentEntrySize >= PAGE_SIZE_1MB
680 && !(currentEntry.slaveVirtAddr & (PAGE_SIZE_1MB - 1))) {
681 currentEntry.size = PAGE_SIZE_1MB;
682 }
683 else if (currentEntrySize >= PAGE_SIZE_64KB
684 && !(currentEntry.slaveVirtAddr & (PAGE_SIZE_64KB - 1))){
685 currentEntry.size = PAGE_SIZE_64KB;
686 }
687 else if (currentEntrySize >= PAGE_SIZE_4KB
688 && !(currentEntry.slaveVirtAddr & (PAGE_SIZE_4KB - 1))){
689 currentEntry.size = PAGE_SIZE_4KB;
690 }
691 else {
692 Osal_printf ("Configuration error: "
693 " MMU entries must be aligned to their"
694 "page size(4KB,"
695 " 64KB, 1MB, or 16MB).\n");
696 Osal_printf ("Since the addresses are not aligned buffer"
697 "of size: %x at address: %x cannot be "
698 "TLB entries\n",
699 currentEntrySize, currentEntry.slaveVirtAddr);
700 /*! @retval DM8168VIDEOM3PROC_E_MMUCONFIG Memory region is not
701 aligned to page size */
702 status = DM8168VIDEOM3PROC_E_MMUCONFIG;
703 GT_setFailureReason (curTrace,
704 GT_4CLASS,
705 "_DM8168VIDEOM3_halMmuDeleteEntry",
706 status,
707 "Memory region is not aligned to page size!");
708 break ;
709 }
710 /* DO NOT put this check under SYSLINK_BUILD_OPTIMIZE */
711 if (status >= 0) {
712 /* Check every page if exists */
713 iopgd = iopgd_offset(mmuObj->videoMmuHandler,
714 currentEntry.slaveVirtAddr);
716 if (*iopgd) {
717 /* Clear the requested page entry */
718 clearBytes = iopgtable_clear_entry(mmuObj->videoMmuHandler,
719 currentEntry.slaveVirtAddr);
720 }
722 currentEntry.slaveVirtAddr += currentEntry.size;
723 currentEntrySize -= currentEntry.size;
724 }
725 }
727 GT_1trace (curTrace, GT_LEAVE, "_DM8168VIDEOM3_halMmuDeleteEntry", status);
729 /*! @retval PROCESSOR_SUCCESS Operation completed successfully. */
730 return status;
731 }
734 /*!
735 * @brief Updates entries in table.
736 *
737 * @param refData Argument provided to the ISR registration function
738 *
739 * @sa
740 */
741 Int
742 _DM8168VIDEOM3_halMmuPteSet (DM8168VIDEOM3_HalObject * halObject,
743 DM8168VIDEOM3_HalMmuEntryInfo* setPteInfo)
744 {
745 DM8168VIDEOM3_HalMmuObject * mmuObj;
746 struct iotlb_entry tlb_entry;
747 Int status = PROCESSOR_SUCCESS;
748 UInt32 * iopgd = NULL;
750 GT_assert (curTrace, (halObject != NULL));
751 GT_assert (curTrace, (setPteInfo != NULL));
753 mmuObj = &(halObject->mmuObj);
754 GT_assert(curTrace, (mmuObj != NULL));
756 switch (setPteInfo->size) {
757 case PAGE_SIZE_16MB:
758 tlb_entry.pgsz = MMU_CAM_PGSZ_16M;
759 break;
760 case PAGE_SIZE_1MB:
761 tlb_entry.pgsz = MMU_CAM_PGSZ_1M;
762 break;
763 case PAGE_SIZE_64KB:
764 tlb_entry.pgsz = MMU_CAM_PGSZ_64K;
765 break;
766 case PAGE_SIZE_4KB:
767 tlb_entry.pgsz = MMU_CAM_PGSZ_4K;
768 break;
769 default :
770 status = PROCESSOR_E_INVALIDARG;
771 /*! @retval PROCESSOR_E_INVALIDARG Invalid Page size passed!. */
772 GT_setFailureReason (curTrace,
773 GT_4CLASS,
774 "_DM8168VIDEOM3_halMmuPteSet",
775 status,
776 "Invalid Page size passed!");
777 }
778 #if !defined(SYSLINK_BUILD_OPTIMIZE)
779 if (status >= 0) {
780 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
781 tlb_entry.prsvd = MMU_CAM_PRESERVE;
782 tlb_entry.valid = MMU_CAM_VALID;
783 /*TBD : elsz parameter has to be configured*/
784 switch (setPteInfo->elementSize) {
785 case ELEM_SIZE_8BIT:
786 tlb_entry.elsz = MMU_RAM_ELSZ_8;
787 break;
788 case ELEM_SIZE_16BIT:
789 tlb_entry.elsz = MMU_RAM_ELSZ_16;
790 break;
791 case ELEM_SIZE_32BIT:
792 tlb_entry.elsz = MMU_RAM_ELSZ_32;
793 break;
794 case ELEM_SIZE_64BIT:
795 tlb_entry.elsz = 0x3; /* No translation */
796 break;
797 default :
798 status = PROCESSOR_E_INVALIDARG;
799 /*! @retval PROCESSOR_E_INVALIDARG Invalid elementSize passed!*/
800 GT_setFailureReason (curTrace,
801 GT_4CLASS,
802 "_DM8168VIDEOM3_halMmuPteSet",
803 status,
804 "Invalid elementSize passed!");
805 }
806 #if !defined(SYSLINK_BUILD_OPTIMIZE)
807 if (status >= 0) {
808 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
809 /*TBD : endian parameter has to configured*/
810 switch (setPteInfo->endianism) {
811 case LITTLE_ENDIAN:
812 tlb_entry.endian = MMU_RAM_ENDIAN_LITTLE;
813 break;
814 case BIG_ENDIAN:
815 tlb_entry.endian = MMU_RAM_ENDIAN_BIG;
816 break;
817 default :
818 status = PROCESSOR_E_INVALIDARG;
819 /*! @retval PROCESSOR_E_INVALIDARG Invalid endianism
820 * passed!. */
821 GT_setFailureReason (curTrace,
822 GT_4CLASS,
823 "_DM8168VIDEOM3_halMmuPteSet",
824 status,
825 "Invalid endianism passed!");
826 }
827 #if !defined(SYSLINK_BUILD_OPTIMIZE)
828 if (status >= 0) {
829 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
830 /*TBD : mixed parameter has to configured*/
831 switch (setPteInfo->mixedSize) {
832 case MMU_TLBES:
833 tlb_entry.mixed = MMU_RAM_DEFAULT;
834 break;
835 case MMU_CPUES:
836 tlb_entry.mixed = MMU_RAM_MIXED;
837 break;
838 default :
839 status = PROCESSOR_E_INVALIDARG;
840 /*! @retval PROCESSOR_E_INVALIDARG Invalid
841 * mixed size passed!*/
842 GT_setFailureReason (curTrace,
843 GT_4CLASS,
844 "_DM8168VIDEOM3_halMmuPteSet",
845 status,
846 "Invalid mixed size passed!");
847 }
849 tlb_entry.da = setPteInfo->slaveVirtAddr;
850 tlb_entry.pa = setPteInfo->masterPhyAddr;
851 iopgd = iopgd_offset(mmuObj->videoMmuHandler,
852 tlb_entry.da);
854 if (iopgtable_store_entry(mmuObj->videoMmuHandler, &tlb_entry)){
855 status = PROCESSOR_E_STOREENTERY;
856 GT_setFailureReason (curTrace,
857 GT_4CLASS,
858 "_DM8168VIDEOM3_halMmuPteSet",
859 status,
860 "iopgtable_store_entry failed!");
861 }
862 #if !defined(SYSLINK_BUILD_OPTIMIZE)
863 }
864 }
865 }
866 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
868 // GT_1trace (curTrace, GT_LEAVE, "_DM8168VIDEOM3_halMmuPteSet", status);
870 /*! @retval PROCESSOR_SUCCESS Operation completed successfully. */
871 return status;
872 }
873 #endif /* #if defined(SYSLINK_BUILDOS_LINUX) */
875 #if defined (__cplusplus)
876 }
877 #endif