]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - qnx/src/ipc3x_dev/ti/syslink/family/hlos/knl/ti81xx/ti81xxducati/ti81xxvideom3/Dm8168M3VideoHalMmu.c
Release the OMAP5 DSP MMU from reset after loading the core
[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)
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;
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)
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 ;
343 Int
344 _DM8168VIDEOM3_halMmuEnable (DM8168VIDEOM3_HalObject * halObject,
345                         UInt32               numMemEntries,
346                         ProcMgr_AddrInfo *   memTable)
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 ;
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)
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;
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)
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(&currentEntry,
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;
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)
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;
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)
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(&currentEntry,
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;
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)
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;
873 #endif /* #if defined(SYSLINK_BUILDOS_LINUX) */
875 #if defined (__cplusplus)
877 #endif