[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / family / omap5430 / ipu / omap5430BenelliHalMmu.c
1 /*
2 * @file omap5430BenelliHalMmu.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 OMAP5430BENELLI.
9 *
10 *
11 * @ver 02.00.00.44_pre-alpha3
12 *
13 * ============================================================================
14 *
15 * Copyright (c) 2010-2011, Texas Instruments Incorporated
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 *
21 * * Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 *
24 * * Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
27 *
28 * * Neither the name of Texas Instruments Incorporated nor the names of
29 * its contributors may be used to endorse or promote products derived
30 * from this software without specific prior written permission.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
34 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
35 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
36 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
37 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
38 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
39 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
40 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
41 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
42 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 * Contact information for paper mail:
44 * Texas Instruments
45 * Post Office Box 655303
46 * Dallas, Texas 75265
47 * Contact information:
48 * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
49 * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
50 * ============================================================================
51 *
52 */
55 /* Standard headers */
56 #include <ti/syslink/Std.h>
58 /* OSAL and utils headers */
59 #include <ti/syslink/utils/List.h>
60 #include <ti/syslink/utils/Trace.h>
61 #include <ti/syslink/utils/OsalPrint.h>
63 /* Module level headers */
64 #include <_ProcDefs.h>
65 #include <Processor.h>
67 /* Hardware Abstraction Layer headers */
68 #include <OMAP5430BenelliHal.h>
69 #include <OMAP5430BenelliHalMmu.h>
70 #include <OMAP5430BenelliPhyShmem.h>
71 #include <OMAP5430BenelliEnabler.h>
72 #include <MMUAccInt.h>
73 #include <hw/inout.h>
75 /*QNX specific header include */
76 #include <sys/neutrino.h>
77 #include <errno.h>
78 #include <pthread.h>
80 #if defined (__cplusplus)
81 extern "C" {
82 #endif
86 /* =============================================================================
87 * Macros and types
88 * =============================================================================
89 */
90 /*!
91 * @brief CAM register field values
92 */
93 #define MMU_CAM_PRESERVE (1 << 3)
94 #define MMU_CAM_VALID (1 << 2)
96 /*!
97 * @brief Addresses lower than this do not go through the DSP's MMU
98 */
99 #define MMU_GLOBAL_MEMORY 0x11000000
101 /*!
102 * @brief Interrupt Id for DSP MMU faults
103 */
104 #define MMU_FAULT_INTERRUPT 132
105 #define MMU_FAULT_INTERRUPT_DSP 60
107 /*!
108 * @brief Size constants
109 */
110 #define SIZE_4KB 0x1000
111 #define SIZE_64KB 0x10000
112 #define SIZE_1MB 0x100000
113 #define SIZE_16MB 0x1000000
115 #define MMU_SECTION_ADDR_MASK 0xFFF00000
116 #define MMU_SSECTION_ADDR_MASK 0xFF000000
117 #define MMU_PAGE_TABLE_MASK 0xFFFFFC00
118 #define MMU_LARGE_PAGE_MASK 0xFFFF0000
119 #define MMU_SMALL_PAGE_MASK 0xFFFFF000
122 #define SLAVEVIRTADDR(x) ((x)->addr [ProcMgr_AddrType_SlaveVirt])
123 #define SLAVEPHYSADDR(x) ((x)->addr [ProcMgr_AddrType_SlavePhys])
124 #define MASTERPHYSADDR(x) ((x)->addr [ProcMgr_AddrType_MasterPhys])
126 #define MMUPAGE_ALIGN(size, psz) (((size) + psz - 1) & ~(psz -1))
128 #define IOPTE_SHIFT 12
129 #define IOPTE_SIZE (1 << IOPTE_SHIFT)
130 #define IOPTE_MASK (~(IOPTE_SIZE - 1))
131 #define IOPAGE_MASK IOPTE_MASK
133 /*!
134 * @def REG32
135 * @brief Regsiter access method.
136 */
137 #define REG32(x) (*(volatile UInt32 *) (x))
139 /* =============================================================================
140 * Structures used in this file
141 * =============================================================================
142 */
144 /* =============================================================================
145 * Forward declarations of internal functions
146 * =============================================================================
147 */
148 /* Enables the MMU for GEM Module. */
149 Int _OMAP5430BENELLI_halMmuEnable (OMAP5430BENELLI_HalObject * halObject,
150 UInt32 numMemEntries,
151 ProcMgr_AddrInfo * memTable);
153 /* Disables the MMU for GEM Module. */
154 Int _OMAP5430BENELLI_halMmuDisable (OMAP5430BENELLI_HalObject * halObject);
156 /* This function configures the specified addr to be in the TLB */
157 Int _OMAP5430BENELLI_halMmuAddEntry (OMAP5430BENELLI_HalObject * halObject,
158 OMAP5430BENELLI_HalMmuEntryInfo * entry);
160 int _OMAP5430BENELLI_halMmuAddStaticEntries (OMAP5430BENELLI_HalObject * halObject,
161 UInt32 numMemEntries,
162 ProcMgr_AddrInfo * memTable);
165 /* Delete entry from TLB. */
166 Int _OMAP5430BENELLI_halMmuDeleteEntry (OMAP5430BENELLI_HalObject * halObject,
167 OMAP5430BENELLI_HalMmuEntryInfo * entry);
169 /* Set entry in to TLB. */
170 Int _OMAP5430BENELLI_halMmuPteSet (OMAP5430BENELLI_HalObject * halObject,
171 OMAP5430BENELLI_HalMmuEntryInfo * setPteInfo);
174 /* =============================================================================
175 * APIs called by OMAP5430BENELLIPROC module
176 * =============================================================================
177 */
178 /*!
179 * @brief Function to control MMU operations for this slave device.
180 *
181 * @param halObj Pointer to the HAL object
182 * @param cmd MMU control command
183 * @param arg Arguments specific to the MMU control command
184 *
185 * @sa
186 */
187 Int
188 OMAP5430BENELLI_halMmuCtrl (Ptr halObj, Processor_MmuCtrlCmd cmd, Ptr args)
189 {
190 Int status = PROCESSOR_SUCCESS;
191 OMAP5430BENELLI_HalObject * halObject = NULL;
193 GT_3trace (curTrace, GT_ENTER, "OMAP5430BENELLI_halMmuCtrl", halObj, cmd, args);
195 GT_assert (curTrace, (halObj != NULL));
197 halObject = (OMAP5430BENELLI_HalObject *) halObj ;
199 switch (cmd) {
200 case Processor_MmuCtrlCmd_Enable:
201 {
202 OMAP5430BENELLI_HalMmuCtrlArgs_Enable * enableArgs;
203 enableArgs = (OMAP5430BENELLI_HalMmuCtrlArgs_Enable *) args;
204 halObject = (OMAP5430BENELLI_HalObject *) halObj;
205 status = _OMAP5430BENELLI_halMmuEnable (halObject,
206 enableArgs->numMemEntries,
207 enableArgs->memEntries);
208 #if !defined(SYSLINK_BUILD_OPTIMIZE)
209 if (status < 0) {
210 /*! @retval PROCESSOR_E_FAIL Failed to configure DSP MMU. */
211 status = PROCESSOR_E_FAIL;
212 GT_setFailureReason (curTrace,
213 GT_4CLASS,
214 "OMAP5430BENELLI_halMmuCtrl",
215 status,
216 "Failed to configure DSP MMU");
217 }
218 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
219 }
220 break;
222 case Processor_MmuCtrlCmd_Disable:
223 {
224 /* args are not used. */
225 halObject = (OMAP5430BENELLI_HalObject *) halObj;
226 status = _OMAP5430BENELLI_halMmuDisable (halObject);
227 #if !defined(SYSLINK_BUILD_OPTIMIZE)
228 if (status < 0) {
229 /*! @retval PROCESSOR_E_FAIL Failed to configure DSP MMU. */
230 status = PROCESSOR_E_FAIL;
231 GT_setFailureReason (curTrace,
232 GT_4CLASS,
233 "OMAP5430BENELLI_halMmuCtrl",
234 status,
235 "Failed to disable DSP MMU");
236 }
237 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
238 }
239 break ;
241 case Processor_MmuCtrlCmd_AddEntry:
242 {
243 OMAP5430BENELLI_HalMmuCtrlArgs_AddEntry * addEntry;
244 addEntry = (OMAP5430BENELLI_HalMmuCtrlArgs_AddEntry *) args;
246 halObject = (OMAP5430BENELLI_HalObject *) halObj;
247 /* Add the entry in TLB for new request */
248 //status = _OMAP5430BENELLI_halMmuAddEntry (halObject,addEntry) ;
249 #if !defined(SYSLINK_BUILD_OPTIMIZE)
250 if (status < 0) {
251 status = PROCESSOR_E_FAIL;
252 GT_setFailureReason (curTrace,
253 GT_4CLASS,
254 "OMAP5430BENELLI_halMmuCtrl",
255 status,
256 "Failed to dynamically add DSP MMU entry");
257 }
258 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
260 }
261 break;
263 case Processor_MmuCtrlCmd_DeleteEntry:
264 {
265 OMAP5430BENELLI_HalMmuCtrlArgs_DeleteEntry * deleteEntry;
266 deleteEntry = (OMAP5430BENELLI_HalMmuCtrlArgs_DeleteEntry *) args;
268 halObject = (OMAP5430BENELLI_HalObject *) halObj;
270 //status = _OMAP5430BENELLI_halMmuDeleteEntry (halObject,deleteEntry);
271 #if !defined(SYSLINK_BUILD_OPTIMIZE)
272 if (status < 0) {
273 status = PROCESSOR_E_FAIL;
274 GT_setFailureReason (curTrace,
275 GT_4CLASS,
276 "OMAP5430BENELLI_halMmuCtrl",
277 status,
278 "Failed to dynamically delete DSP MMU entry");
279 }
280 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
281 }
282 break;
283 default:
284 {
285 /*! @retval PROCESSOR_E_INVALIDARG Invalid argument */
286 status = PROCESSOR_E_INVALIDARG;
287 GT_setFailureReason (curTrace,
288 GT_4CLASS,
289 "OMAP5430BENELLI_halMmuCtrl",
290 status,
291 "Unsupported MMU ctrl cmd specified");
292 }
293 break;
294 }
296 GT_1trace (curTrace, GT_LEAVE, "OMAP5430BENELLI_halMmuCtrl",status);
298 /*! @retval PROCESSOR_SUCCESS Operation successful */
299 return status;
300 }
302 /* =============================================================================
303 * Internal functions
304 * =============================================================================
305 */
306 /*!
307 * @brief Enables and configures the DSP MMU as per provided memory map.
308 *
309 * @param halObject Pointer to the HAL object
310 * @param numMemEntries Number of memory entries in memTable
311 * @param memTable Table of memory entries to be configured
312 *
313 * @sa
314 */
316 Int
317 _OMAP5430BENELLI_halMmuAddStaticEntries (OMAP5430BENELLI_HalObject * halObject,
318 UInt32 numMemEntries,
319 ProcMgr_AddrInfo * memTable)
320 {
321 Int status = PROCESSOR_SUCCESS;
322 OMAP5430BENELLI_HalMmuEntryInfo staticEntry;
323 UInt32 i;
325 GT_3trace (curTrace, GT_ENTER, "_OMAP5430BENELLI_halMmuAddStaticEntries",
326 halObject, numMemEntries, memTable);
328 GT_assert (curTrace, (halObject != NULL));
329 /* It is possible that numMemEntries may be 0, if user does not want to
330 * configure any default regions.
331 * memTable may also be NULL.
332 */
334 for (i = 0 ; i < numMemEntries && (status >= 0) ; i++) {
335 if (SLAVEVIRTADDR (&memTable [i]) >= MMU_GLOBAL_MEMORY) {
336 /* Configure the TLB */
337 if (memTable [i].size != 0)
338 {
339 staticEntry.slaveVirtAddr =
340 SLAVEVIRTADDR (&memTable [i]);
341 staticEntry.size = memTable[i].size;
342 staticEntry.masterPhyAddr =
343 MASTERPHYSADDR (&memTable [i]);
344 /*TBD : elementSize, endianism, mixedSized are hard
345 * coded now, must be configurable later*/
346 staticEntry.elementSize = MMU_RAM_ELSZ_16;
347 staticEntry.endianism = LITTLE_ENDIAN;
348 staticEntry.mixedSize = MMU_TLBES;
349 status = _OMAP5430BENELLI_halMmuAddEntry (halObject,
350 &staticEntry);
351 if (status < 0) {
352 /*! @retval PROCESSOR_E_FAIL Failed to add MMU entry. */
353 status = PROCESSOR_E_FAIL;
354 GT_setFailureReason (curTrace,
355 GT_4CLASS,
356 "_OMAP5430BENELLI_halMmuAddStaticEntries",
357 status,
358 "Failed to add MMU entry!");
359 }
360 }
361 }
362 }
363 GT_1trace (curTrace, GT_LEAVE, "_OMAP5430BENELLI_halMmuAddStaticEntries", status);
365 /*! @retval PROCESSOR_SUCCESS Operation completed successfully. */
366 return status ;
367 }
370 /* =============================================================================
371 * Internal functions
372 * =============================================================================
373 */
374 /*!
375 * @brief Function to check and clear the remote proc interrupt
376 *
377 * @param arg Optional argument to the function.
378 *
379 * @sa _OMAP5430BENELLI_halMmuInt_isr
380 */
381 static
382 Bool
383 _OMAP5430BENELLI_halMmuCheckAndClearFunc (Ptr arg)
384 {
385 OMAP5430BENELLI_HalObject * halObject = (OMAP5430BENELLI_HalObject *)arg;
386 OMAP5430BENELLI_HalMmuObject * mmuObj = &(halObject->mmuObj);
388 /* Check the interrupt status */
389 mmuObj->mmuIrqStatus = REG32(halObject->mmuBase + MMU_MMU_IRQSTATUS_OFFSET);
390 mmuObj->mmuIrqStatus &= MMU_IRQ_MASK;
391 if (!(mmuObj->mmuIrqStatus))
392 return (FALSE);
394 /* Get the fault address. */
395 mmuObj->mmuFaultAddr = REG32(halObject->mmuBase + MMU_MMU_FAULT_AD_OFFSET);
397 /* Print the fault information */
398 GT_1trace (curTrace, GT_4CLASS,
399 "**************** %s-MMU Fault ****************",
400 MultiProc_getName(halObject->procId));
402 GT_1trace (curTrace, GT_4CLASS,
403 "**** addr: 0x%x", mmuObj->mmuFaultAddr);
404 if (mmuObj->mmuIrqStatus & MMU_IRQ_TLBMISS)
405 GT_0trace (curTrace, GT_4CLASS, "**** TLBMISS");
406 if (mmuObj->mmuIrqStatus & MMU_IRQ_TRANSLATIONFAULT)
407 GT_0trace (curTrace, GT_4CLASS, "**** TRANSLATIONFAULT");
408 if (mmuObj->mmuIrqStatus & MMU_IRQ_EMUMISS)
409 GT_0trace (curTrace, GT_4CLASS, "**** EMUMISS");
410 if (mmuObj->mmuIrqStatus & MMU_IRQ_TABLEWALKFAULT)
411 GT_0trace (curTrace, GT_4CLASS, "**** TABLEWALKFAULT");
412 if (mmuObj->mmuIrqStatus & MMU_IRQ_MULTIHITFAULT)
413 GT_0trace (curTrace, GT_4CLASS, "**** MULTIHITFAULT");
414 GT_0trace (curTrace, GT_4CLASS,
415 "**************************************************");
417 /* Clear the interrupt and disable further interrupts. */
418 REG32(halObject->mmuBase + MMU_MMU_IRQENABLE_OFFSET) = 0x0;
419 REG32(halObject->mmuBase + MMU_MMU_IRQSTATUS_OFFSET) = mmuObj->mmuIrqStatus;
421 /* This is not a shared interrupt, so interrupt has always occurred */
422 /*! @retval TRUE Interrupt has occurred. */
423 return (TRUE);
424 }
426 /*!
427 * @brief Interrupt Service Routine for Omap5430BenelliHalMmu module
428 *
429 * @param arg Optional argument to the function.
430 *
431 * @sa _OMAP5430BENELLI_halMmuCheckAndClearFunc
432 */
433 static
434 Bool
435 _OMAP5430BENELLI_halMmuInt_isr (Ptr arg)
436 {
437 OMAP5430BENELLI_HalObject * halObject = (OMAP5430BENELLI_HalObject *)arg;
438 OMAP5430BENELLIPROC_Object * proc5430Object = NULL;
440 GT_1trace (curTrace, GT_ENTER, "_OMAP5430BENELLI_halMmuInt_isr", arg);
441 OMAP5430BENELLIPROC_open((OMAP5430BENELLIPROC_Handle *)&proc5430Object, halObject->procId);
442 Processor_setState(proc5430Object->procHandle, ProcMgr_State_Mmu_Fault);
443 OMAP5430BENELLIPROC_close((OMAP5430BENELLIPROC_Handle *)&proc5430Object);
446 GT_1trace (curTrace, GT_LEAVE, "_OMAP5430BENELLI_halMmuInt_isr", TRUE);
448 /*! @retval TRUE Interrupt has been handled. */
449 return (TRUE);
450 }
452 /*!
453 * @brief Enables and configures the DSP MMU as per provided memory map.
454 *
455 * @param halObject Pointer to the HAL object
456 * @param numMemEntries Number of memory entries in memTable
457 * @param memTable Table of memory entries to be configured
458 *
459 * @sa
460 */
461 Int
462 _OMAP5430BENELLI_halMmuEnable (OMAP5430BENELLI_HalObject * halObject,
463 UInt32 numMemEntries,
464 ProcMgr_AddrInfo * memTable)
465 {
466 Int status = PROCESSOR_SUCCESS;
467 OMAP5430BENELLI_HalMmuObject * mmuObj;
468 OsalIsr_Params isrParams;
470 GT_3trace (curTrace, GT_ENTER, "_OMAP5430BENELLI_halMmuEnable",
471 halObject, numMemEntries, memTable);
473 GT_assert (curTrace, (halObject != NULL));
474 /* It is possible that numMemEntries may be 0, if user does not want to
475 * configure any default regions.
476 * memTable may also be NULL.
477 */
478 mmuObj = &(halObject->mmuObj);
480 /* Create the ISR to listen for MMU Faults */
481 isrParams.sharedInt = FALSE;
482 isrParams.checkAndClearFxn = &_OMAP5430BENELLI_halMmuCheckAndClearFunc;
483 isrParams.fxnArgs = halObject;
484 if (halObject->procId == MultiProc_getId("DSP")) {
485 isrParams.intId = MMU_FAULT_INTERRUPT_DSP;
486 }
487 else {
488 isrParams.intId = MMU_FAULT_INTERRUPT;
489 }
491 mmuObj->isrHandle = OsalIsr_create (&_OMAP5430BENELLI_halMmuInt_isr,
492 halObject,
493 &isrParams);
495 #if !defined(SYSLINK_BUILD_OPTIMIZE)
496 if (mmuObj->isrHandle == NULL) {
497 /*! @retval PROCESSOR_E_FAIL OsalIsr_create failed */
498 status = PROCESSOR_E_FAIL;
499 GT_setFailureReason (curTrace,
500 GT_4CLASS,
501 "_OMAP5430BENELLI_halMmuEnable",
502 status,
503 "OsalIsr_create failed");
504 }
505 else {
506 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
508 status = OsalIsr_install (mmuObj->isrHandle);
510 #if !defined(SYSLINK_BUILD_OPTIMIZE)
511 if (status < 0) {
512 GT_setFailureReason (curTrace,
513 GT_4CLASS,
514 "_OMAP5430BENELLI_halMmuEnable",
515 status,
516 "OsalIsr_install failed");
517 }
518 }
519 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
521 GT_1trace (curTrace, GT_LEAVE, "_OMAP5430BENELLI_halMmuEnable", status);
523 /*! @retval PROCESSOR_SUCCESS Operation completed successfully. */
524 return status ;
525 }
528 /*!
529 * @brief Disables the DSP MMU.
530 *
531 * @param halObject Pointer to the HAL object
532 *
533 * @sa
534 */
535 Int
536 _OMAP5430BENELLI_halMmuDisable (OMAP5430BENELLI_HalObject * halObject)
537 {
538 Int status = PROCESSOR_SUCCESS;
539 Int tmpStatus = PROCESSOR_SUCCESS;
540 OMAP5430BENELLI_HalMmuObject * mmuObj;
542 GT_1trace (curTrace, GT_ENTER, "_OMAP5430BENELLI_halMmuDisable", halObject);
544 GT_assert (curTrace, (halObject != NULL));
545 mmuObj = &(halObject->mmuObj);
547 status = OsalIsr_uninstall (mmuObj->isrHandle);
548 #if !defined(SYSLINK_BUILD_OPTIMIZE)
549 if (status < 0) {
550 GT_setFailureReason (curTrace,
551 GT_4CLASS,
552 "_OMAP5430BENELLI_halMmuDisable",
553 status,
554 "OsalIsr_uninstall failed");
555 }
556 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
558 #if !defined(SYSLINK_BUILD_OPTIMIZE)
559 tmpStatus =
560 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
561 OsalIsr_delete (&(mmuObj->isrHandle));
562 #if !defined(SYSLINK_BUILD_OPTIMIZE)
563 if ((status >= 0) && (tmpStatus < 0)) {
564 status = tmpStatus;
565 GT_setFailureReason (curTrace,
566 GT_4CLASS,
567 "_OMAP5430BENELLI_halMmuDisable",
568 status,
569 "OsalIsr_delete failed");
570 }
571 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
573 GT_1trace (curTrace, GT_LEAVE, "_OMAP5430BENELLI_halMmuDisable", status);
575 /*! @retval PROCESSOR_SUCCESS Operation completed successfully. */
576 return status;
577 }
580 /*!
581 * @brief This function adds an MMU entry for the specfied address and
582 * size.
583 *
584 * @param halObject Pointer to the HAL object
585 * @param slaveVirtAddr DSP virtual address of the memory region
586 * @param size Size of the memory region to be configured
587 * @param isDynamic Is the MMU entry being dynamically added?
588 *
589 * @sa
590 */
591 Int _OMAP5430BENELLI_halMmuAddEntry (OMAP5430BENELLI_HalObject * halObject,
592 OMAP5430BENELLI_HalMmuEntryInfo * entry)
593 {
594 Int status = PROCESSOR_SUCCESS;
595 UInt32 * ppgd = NULL;
596 UInt32 * ppte = NULL;
597 OMAP5430BENELLI_HalMmuEntryInfo currentEntry;
598 OMAP5430BENELLI_HalMmuEntryInfo te;
599 Int32 currentEntrySize;
601 GT_2trace (curTrace, GT_ENTER, "_OMAP5430BENELLI_halMmuAddEntry",
602 halObject, entry);
604 GT_assert (curTrace, (halObject != NULL));
605 GT_assert (curTrace, (entry != NULL));
607 /* Add the entry (or entries) */
608 if (status >= 0) {
609 Memory_copy(¤tEntry,
610 entry,
611 sizeof(OMAP5430BENELLI_HalMmuEntryInfo));
613 /* Align the addresses to page size */
614 currentEntry.size += (currentEntry.slaveVirtAddr & (PAGE_SIZE_4KB -1));
615 currentEntry.slaveVirtAddr &= ~(PAGE_SIZE_4KB-1);
616 currentEntry.masterPhyAddr &= ~(PAGE_SIZE_4KB-1);
618 /* Align the size as well */
619 currentEntry.size = MMUPAGE_ALIGN(currentEntry.size, PAGE_SIZE_4KB);
620 currentEntrySize = currentEntry.size;
622 /* Check every page if exists */
623 do {
624 /* Lookup if the entry exists */
625 if (1)//!*ppgd || !*ppte)
626 {
627 /* Entry doesnot exists, insert this page */
628 te.size = PAGE_SIZE_4KB;
629 te.slaveVirtAddr = currentEntry.slaveVirtAddr;
630 te.masterPhyAddr = currentEntry.masterPhyAddr;
631 te.elementSize = ELEM_SIZE_16BIT;
632 te.endianism = LITTLE_ENDIAN;
633 te.mixedSize = MMU_TLBES;
634 status = _OMAP5430BENELLI_halMmuPteSet (halObject, &te);
635 #if !defined(SYSLINK_BUILD_OPTIMIZE)
636 if (status < 0) {
637 GT_setFailureReason (
638 curTrace,
639 GT_4CLASS,
640 "_OMAP5430BENELLI_halMmuAddEntry",
641 status,
642 "Failed to in _OMAP5430BENELLI_halMmuPteSet!");
643 }
644 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
645 }
646 else if (*ppgd && *ppte) {
647 if (currentEntry.masterPhyAddr != (*ppte & IOPAGE_MASK)) {
648 /* Entry doesnot exists, insert this page */
649 te.size = PAGE_SIZE_4KB;
650 te.slaveVirtAddr = currentEntry.slaveVirtAddr;
651 te.masterPhyAddr = currentEntry.masterPhyAddr;
652 te.elementSize = ELEM_SIZE_16BIT;
653 te.endianism = LITTLE_ENDIAN;
654 te.mixedSize = MMU_TLBES;
655 status = _OMAP5430BENELLI_halMmuPteSet (halObject, &te);
656 #if !defined(SYSLINK_BUILD_OPTIMIZE)
657 if (status < 0) {
658 GT_setFailureReason (
659 curTrace,
660 GT_4CLASS,
661 "_OMAP5430BENELLI_halMmuAddEntry",
662 status,
663 "Failed to in _OMAP5430BENELLI_halMmuPteSet!");
664 }
665 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
666 }
667 }
669 currentEntrySize -= PAGE_SIZE_4KB;
670 currentEntry.slaveVirtAddr += PAGE_SIZE_4KB;
671 currentEntry.masterPhyAddr += PAGE_SIZE_4KB;
672 } while (currentEntrySize);
674 }
676 GT_1trace (curTrace, GT_LEAVE, "_OMAP5430BENELLI_halMmuAddEntry", status);
678 /*! @retval PROCESSOR_SUCCESS Operation completed successfully. */
679 return status;
680 }
683 /*!
684 * @brief This function deletes an MMU entry for the specfied address and
685 * size.
686 *
687 * @param halObject Pointer to the HAL object
688 * @param slaveVirtAddr DSP virtual address of the memory region
689 * @param size Size of the memory region to be configured
690 * @param isDynamic Is the MMU entry being dynamically added?
691 *
692 * @sa
693 */
694 Int _OMAP5430BENELLI_halMmuDeleteEntry (OMAP5430BENELLI_HalObject * halObject,
695 OMAP5430BENELLI_HalMmuEntryInfo * entry)
696 {
697 Int status = PROCESSOR_SUCCESS;
698 OMAP5430BENELLI_HalMmuObject * mmuObj;
701 GT_2trace (curTrace, GT_ENTER, "_OMAP5430BENELLI_halMmuDeleteEntry",
702 halObject, entry);
704 GT_assert (curTrace, (halObject != NULL));
705 GT_assert (curTrace, (entry != NULL));
706 //GT_assert (curTrace, (entry->slaveVirtAddr != 0)); // 0 is a valid slave virtual addr
707 GT_assert (curTrace, (entry->size != 0));
709 mmuObj = &(halObject->mmuObj);
711 GT_1trace (curTrace, GT_LEAVE, "_OMAP5430BENELLI_halMmuDeleteEntry", status);
713 /*! @retval PROCESSOR_SUCCESS Operation completed successfully. */
714 return status;
715 }
717 static ULONG HAL_MMU_PteAddrL1(const ULONG L1_base, const ULONG va)
718 {
719 ULONG TTB_13_to_7, VA_31_to_20, desc_13_to_0;
721 TTB_13_to_7 = L1_base & (0x7FUL << 13);
722 VA_31_to_20 = va >> (20 - 2); /* Left-shift by 2 here itself */
723 desc_13_to_0 = (TTB_13_to_7 + VA_31_to_20) & (0xFFFUL << 2);
725 return ( (L1_base & 0xFFFFC000) | desc_13_to_0 );
726 }
728 static ULONG HAL_MMU_PteAddrL2(const ULONG L2_base, const ULONG va)
729 {
730 return ( (L2_base & 0xFFFFFC00) | ( (va >> 10) & 0x3FC ) );
731 }
733 #define OUTREG32(x, y) WRITE_REGISTER_ULONG(x, (ULONG)(y))
735 int OMAP5430BENELLI_InternalMMU_PteSet (const ULONG pgTblVa,
736 struct iotlb_entry *mapAttrs)
737 {
738 Int status = 0;
739 ULONG pteAddr, pteVal;
740 Int numEntries = 1;
741 ULONG physicalAddr = mapAttrs->pa;
742 ULONG virtualAddr = mapAttrs->da;
744 switch (mapAttrs->pgsz)
745 {
746 case MMU_CAM_PGSZ_4K:
747 pteAddr = HAL_MMU_PteAddrL2(pgTblVa, virtualAddr & MMU_SMALL_PAGE_MASK);
748 pteVal = ( (physicalAddr & MMU_SMALL_PAGE_MASK) |
749 (mapAttrs->endian << 9) |
750 (mapAttrs->elsz << 4) |
751 (mapAttrs->mixed << 11) | 2
752 );
753 break;
755 case MMU_CAM_PGSZ_64K:
756 numEntries = 16;
757 pteAddr = HAL_MMU_PteAddrL2(pgTblVa, virtualAddr & MMU_LARGE_PAGE_MASK);
758 pteVal = ( (physicalAddr & MMU_LARGE_PAGE_MASK) |
759 (mapAttrs->endian << 9) |
760 (mapAttrs->elsz << 4) |
761 (mapAttrs->mixed << 11) | 1
762 );
763 break;
765 case MMU_CAM_PGSZ_1M:
766 pteAddr = HAL_MMU_PteAddrL1(pgTblVa, virtualAddr & MMU_SECTION_ADDR_MASK);
767 pteVal = ( ( ( (physicalAddr & MMU_SECTION_ADDR_MASK) |
768 (mapAttrs->endian << 15) |
769 (mapAttrs->elsz << 10) |
770 (mapAttrs->mixed << 17)) &
771 ~0x40000) | 0x2
772 );
773 break;
775 case MMU_CAM_PGSZ_16M:
776 numEntries = 16;
777 pteAddr = HAL_MMU_PteAddrL1(pgTblVa, virtualAddr & MMU_SSECTION_ADDR_MASK);
778 pteVal = ( ( (physicalAddr & MMU_SSECTION_ADDR_MASK) |
779 (mapAttrs->endian << 15) |
780 (mapAttrs->elsz << 10) |
781 (mapAttrs->mixed << 17)
782 ) | 0x40000 | 0x2
783 );
784 break;
786 default:
787 return -1;
788 }
790 while (--numEntries >= 0)
791 {
792 #ifdef MMUTEST
793 ((ULONG*)pteAddr)[numEntries] = pteVal;
794 #endif
795 }
797 return status;
798 }
799 /*!
800 * @brief Updates entries in table.
801 *
802 * @param refData Argument provided to the ISR registration function
803 *
804 * @sa
805 */
806 Int
807 _OMAP5430BENELLI_halMmuPteSet (OMAP5430BENELLI_HalObject * halObject,
808 OMAP5430BENELLI_HalMmuEntryInfo* setPteInfo)
809 {
810 OMAP5430BENELLI_HalMmuObject * mmuObj;
811 struct iotlb_entry tlb_entry;
812 Int status = PROCESSOR_SUCCESS;
813 // Commented as TRACEENTER log takes long time
814 // GT_2trace (curTrace,
815 // GT_ENTER,
816 // "_OMAP5430BENELLI_halMmuPteSet",
817 // halObject,
818 // setPteInfo);
820 GT_assert (curTrace, (halObject != NULL));
821 GT_assert (curTrace, (setPteInfo != NULL));
823 mmuObj = &(halObject->mmuObj);
824 GT_assert(curTrace, (mmuObj != NULL));
826 switch (setPteInfo->size) {
827 case PAGE_SIZE_16MB:
828 tlb_entry.pgsz = MMU_CAM_PGSZ_16M;
829 break;
830 case PAGE_SIZE_1MB:
831 tlb_entry.pgsz = MMU_CAM_PGSZ_1M;
832 break;
833 case PAGE_SIZE_64KB:
834 tlb_entry.pgsz = MMU_CAM_PGSZ_64K;
835 break;
836 case PAGE_SIZE_4KB:
837 tlb_entry.pgsz = MMU_CAM_PGSZ_4K;
838 break;
839 default :
840 status = PROCESSOR_E_INVALIDARG;
841 /*! @retval PROCESSOR_E_INVALIDARG Invalid Page size passed!. */
842 GT_setFailureReason (curTrace,
843 GT_4CLASS,
844 "_OMAP5430BENELLI_halMmuPteSet",
845 status,
846 "Invalid Page size passed!");
847 }
848 #if !defined(SYSLINK_BUILD_OPTIMIZE)
849 if (status >= 0) {
850 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
851 tlb_entry.prsvd = MMU_CAM_PRESERVE;
852 tlb_entry.valid = MMU_CAM_VALID;
853 /*TBD : elsz parameter has to be configured*/
854 switch (setPteInfo->elementSize) {
855 case ELEM_SIZE_8BIT:
856 tlb_entry.elsz = MMU_RAM_ELSZ_8;
857 break;
858 case ELEM_SIZE_16BIT:
859 tlb_entry.elsz = MMU_RAM_ELSZ_16;
860 break;
861 case ELEM_SIZE_32BIT:
862 tlb_entry.elsz = MMU_RAM_ELSZ_32;
863 break;
864 case ELEM_SIZE_64BIT:
865 tlb_entry.elsz = 0x3; /* No translation */
866 break;
867 default :
868 status = PROCESSOR_E_INVALIDARG;
869 /*! @retval PROCESSOR_E_INVALIDARG Invalid elementSize passed!*/
870 GT_setFailureReason (curTrace,
871 GT_4CLASS,
872 "_OMAP5430BENELLI_halMmuPteSet",
873 status,
874 "Invalid elementSize passed!");
875 }
876 #if !defined(SYSLINK_BUILD_OPTIMIZE)
877 if (status >= 0) {
878 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
879 /*TBD : endian parameter has to configured*/
880 switch (setPteInfo->endianism) {
881 case LITTLE_ENDIAN:
882 tlb_entry.endian = MMU_RAM_ENDIAN_LITTLE;
883 break;
884 case BIG_ENDIAN:
885 tlb_entry.endian = MMU_RAM_ENDIAN_BIG;
886 break;
887 default :
888 status = PROCESSOR_E_INVALIDARG;
889 /*! @retval PROCESSOR_E_INVALIDARG Invalid endianism
890 * passed!. */
891 GT_setFailureReason (curTrace,
892 GT_4CLASS,
893 "_OMAP5430BENELLI_halMmuPteSet",
894 status,
895 "Invalid endianism passed!");
896 }
897 #if !defined(SYSLINK_BUILD_OPTIMIZE)
898 if (status >= 0) {
899 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
900 /*TBD : mixed parameter has to configured*/
901 switch (setPteInfo->mixedSize) {
902 case MMU_TLBES:
903 tlb_entry.mixed = MMU_RAM_DEFAULT;
904 break;
905 case MMU_CPUES:
906 tlb_entry.mixed = MMU_RAM_MIXED;
907 break;
908 default :
909 status = PROCESSOR_E_INVALIDARG;
910 /*! @retval PROCESSOR_E_INVALIDARG Invalid
911 * mixed size passed!*/
912 GT_setFailureReason (curTrace,
913 GT_4CLASS,
914 "_OMAP5430BENELLI_halMmuPteSet",
915 status,
916 "Invalid mixed size passed!");
917 }
919 tlb_entry.da = setPteInfo->slaveVirtAddr;
920 tlb_entry.pa = setPteInfo->masterPhyAddr;
922 if (OMAP5430BENELLI_InternalMMU_PteSet(halObject->mmuBase, &tlb_entry)){
923 status = PROCESSOR_E_STOREENTERY;
924 GT_setFailureReason (curTrace,
925 GT_4CLASS,
926 "_OMAP5430BENELLI_halMmuPteSet",
927 status,
928 "iopgtable_store_entry failed!");
929 }
930 #if !defined(SYSLINK_BUILD_OPTIMIZE)
931 }
932 }
933 }
934 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
936 // GT_1trace (curTrace, GT_LEAVE, "_OMAP5430BENELLI_halMmuPteSet", status);
938 /*! @retval PROCESSOR_SUCCESS Operation completed successfully. */
939 return status;
940 }
944 #if defined (__cplusplus)
945 }
946 #endif