1 /*************************************************************************
\r
3 * Used with ICCARM and AARM.
\r
5 * (c) Copyright IAR Systems 2012
\r
7 * File name : armv7a_cp15_drv.c
\r
8 * Description : Driver for the CP15 of ARMv7-A
\r
11 * 1. Date : September, 8 2006
\r
12 * Author : Stanimir Bonev
\r
13 * Description : Driver for the ARM926EJ's CP15
\r
15 * 2. Date : October, 2008
\r
16 * Author : Stoyan Choynev
\r
17 * Description : Port for ARM1136JF. The driver is backwards compatible
\r
18 * with ARMv5 or earlier processors.
\r
20 * 3. Date : March, 2012
\r
21 * Author : Atanas Uzunov
\r
22 * Description : Port for ARMv7-A architecture.
\r
23 * Added cache maintenance functions.
\r
25 * $Revision: 52705 $
\r
26 **************************************************************************/
\r
28 #include "armv7a_cp15_drv.h"
\r
30 /*************************************************************************
\r
31 * Function Name: CP15_GetID
\r
36 * Description: Function returns the ID register
\r
38 *************************************************************************/
\r
39 __arm Int32U CP15_GetID (void)
\r
41 return(__MRC(15,0,CP15_ID,0,0));
\r
44 /*************************************************************************
\r
45 * Function Name: CP15_GetCacheType
\r
50 * Description: Function returns the Cache type
\r
52 *************************************************************************/
\r
53 __arm Int32U CP15_GetCacheType (void)
\r
55 return(__MRC(15,0,CP15_ID,0,1));
\r
58 /*************************************************************************
\r
59 * Function Name: CP15_GetTCM_Status
\r
64 * Description: Function returns the TCM status
\r
66 *************************************************************************/
\r
67 __arm Int32U CP15_GetTCM_Status (void)
\r
69 return(__MRC(15,0,CP15_ID,0,2));
\r
72 /*************************************************************************
\r
73 * Function Name: CP15_GetTtb0
\r
78 * Description: Function returns the TTB0 register
\r
80 *************************************************************************/
\r
81 __arm Int32U CP15_GetTtb0 (void)
\r
83 return(__MRC(15,0,CP15_TTB_ADDR,0,0));
\r
86 /*************************************************************************
\r
87 * Function Name: CP15_GetTtb1
\r
92 * Description: Function returns the TTB1 register
\r
94 *************************************************************************/
\r
95 __arm Int32U CP15_GetTtb1 (void)
\r
97 return(__MRC(15,0,CP15_TTB_ADDR,0,1));
\r
100 /*************************************************************************
\r
101 * Function Name: CP15_GetStatus
\r
106 * Description: Function returns the MMU control register
\r
108 *************************************************************************/
\r
109 __arm Int32U CP15_GetStatus (void)
\r
111 return(__MRC(15,0,CP15_CTRL,0,0));
\r
114 /*************************************************************************
\r
115 * Function Name: CP15_GetDomain
\r
120 * Description: Function returns the MMU domain access register
\r
122 *************************************************************************/
\r
123 __arm Int32U CP15_GetDomain (void)
\r
125 return(__MRC(15,0,CP15_DA_CTRL,0,0));
\r
128 /*************************************************************************
\r
129 * Function Name: CP15_SetDomains
\r
130 * Parameters: Int32U DomainAccess
\r
134 * Description: Function set the MMU domain access register
\r
136 *************************************************************************/
\r
137 __arm void CP15_SetDomains (Int32U DomainAccess)
\r
139 register Int32U Val = DomainAccess;
\r
140 __MCR(15,0,Val,CP15_DA_CTRL,0,0);
\r
143 /*************************************************************************
\r
144 * Function Name: log2_n_up
\r
145 * Parameters: Int32U n
\r
149 * Description: Logarithm at base 2 , rounded up
\r
151 *************************************************************************/
\r
152 Int32S log2_up(Int32U n)
\r
160 /* if n not power of 2 -> round up*/
\r
161 if ( n & (n - 1) ) log++;
\r
165 /*************************************************************************
\r
166 * Function Name: CP15_MaintainDCacheSetWay
\r
167 * Parameters: Int32U level - level of cache,
\r
168 * Int32U maint - maintenance type
\r
172 * Description: Maintain data cache line by Set/Way
\r
174 *************************************************************************/
\r
175 __arm void CP15_MaintainDCacheSetWay(Int32U level, Int32U maint)
\r
177 register volatile Int32U Dummy;
\r
178 register volatile Int32U ccsidr;
\r
182 Int32U log2_linesize;
\r
183 Int32U log2_num_ways;
\r
185 Dummy = level << 1;
\r
186 /* set csselr, select ccsidr register */
\r
187 __MCR(15,2,Dummy,0,0,0);
\r
188 /* get current ccsidr register */
\r
189 ccsidr = __MRC(15,1,0,0,0);
\r
190 num_sets = ((ccsidr & 0x0FFFE000) >> 13) + 1;
\r
191 num_ways = ((ccsidr & 0x00001FF8) >> 3) + 1;
\r
192 log2_linesize = (ccsidr & 0x00000007) + 2 + 2;
\r
193 log2_num_ways = log2_up(num_ways);
\r
194 shift_way = 32 - log2_num_ways;
\r
195 for(int way = num_ways-1; way >= 0; way--)
\r
196 for(int set = num_sets-1; set >= 0; set--)
\r
198 Dummy = (level << 1) | (set << log2_linesize) | (way << shift_way);
\r
201 case DCACHE_CLEAN_AND_INVALIDATE:
\r
202 __MCR(15,0,Dummy,7,14,2);
\r
205 case DCACHE_INVALIDATE:
\r
206 __MCR(15,0,Dummy,7,6,2);
\r
213 /*************************************************************************
\r
214 * Function Name: CP15_MaintAllDCache
\r
215 * Parameters: Int32U oper - type of maintenance, one of:
\r
216 * DCACHE_CLEAN_AND_INVALIDATE
\r
217 * DCACHE_INVALIDATE
\r
221 * Description: Maintenance of all data cache
\r
223 *************************************************************************/
\r
224 __arm void CP15_MaintainAllDCache(Int32U oper)
\r
226 register volatile Int32U clidr;
\r
228 clidr = __MRC(15,1,0,0,1);
\r
229 for(Int32U i = 0; i<7; i++)
\r
231 cache_type = (clidr >> i*3) & 0x7UL;
\r
232 if ((cache_type >= 2) && (cache_type <= 4))
\r
234 CP15_MaintainDCacheSetWay(i,oper);
\r
239 /*************************************************************************
\r
240 * Function Name: CP15_InvalInstrCache
\r
245 * Description: Invalidate instruction cache
\r
247 *************************************************************************/
\r
248 __arm void CP15_InvalInstrCache(void)
\r
250 register volatile Int32U Dummy;
\r
251 __MCR(15,0,Dummy,CP15_CACHE_OPR,5,0);
\r
252 CP15_InvalPredictArray();
\r
257 /*************************************************************************
\r
258 * Function Name: CP15_InvalPredictArray
\r
263 * Description: Invalidate prediction array
\r
265 *************************************************************************/
\r
266 __arm void CP15_InvalPredictArray(void)
\r
268 register volatile Int32U Dummy;
\r
269 __MCR(15,0,Dummy,CP15_CACHE_OPR,5,6); __ISB();
\r
272 /*************************************************************************
\r
273 * Function Name: CP15_InvalAllTbl
\r
278 * Description: Invalidate TLB
\r
280 *************************************************************************/
\r
281 __arm void CP15_InvalAllTbl (void)
\r
283 register volatile Int32U Dummy;
\r
284 /* Invalidate entire unified TLB*/
\r
285 __MCR(15,0,Dummy,CP15_TBL_OPR,7,0);
\r
286 /* Invalidate entire data TLB*/
\r
287 __MCR(15,0,Dummy,CP15_TBL_OPR,6,0);
\r
288 /* Invalidate entire instruction TLB*/
\r
289 __MCR(15,0,Dummy,CP15_TBL_OPR,5,0);
\r
294 /*************************************************************************
\r
295 * Function Name: CP15_SetStatus
\r
296 * Parameters: Int32U Ctrl
\r
300 * Description: Set CP15 CTR (control) register
\r
302 *************************************************************************/
\r
303 __arm void CP15_SetStatus (Int32U Ctrl)
\r
305 register volatile Int32U Val = Ctrl;
\r
306 __MCR(15,0,Val,CP15_CTRL,0,0);
\r
309 /*************************************************************************
\r
310 * Function Name: CP15_SetTtb0
\r
311 * Parameters: pInt32U pTtb
\r
315 * Description: Set CP15 TTB0 base address register
\r
317 *************************************************************************/
\r
318 __arm void CP15_SetTtb0 (pInt32U pTtb)
\r
320 register volatile Int32U Val = (Int32U)pTtb;
\r
321 __MCR(15,0,Val,CP15_TTB_ADDR,0,0);
\r
324 /*************************************************************************
\r
325 * Function Name: CP15_SetTtb1
\r
326 * Parameters: pInt32U pTtb
\r
330 * Description: Set CP15 TTB1 base address register
\r
332 *************************************************************************/
\r
333 __arm void CP15_SetTtb1 (pInt32U pTtb)
\r
335 register volatile Int32U Val = (Int32U)pTtb;
\r
336 __MCR(15,0,Val,CP15_TTB_ADDR,0,1);
\r
339 /*************************************************************************
\r
340 * Function Name: CP15_SetDac
\r
341 * Parameters: Int32U da
\r
345 * Description: Set CP15 domain access register
\r
347 *************************************************************************/
\r
348 __arm void CP15_SetDac (Int32U da)
\r
350 register volatile Int32U Val = da;
\r
351 __MCR(15,0,Val,CP15_DA_CTRL,0,0);
\r
354 /*************************************************************************
\r
355 * Function Name: CP15_WriteBuffFlush
\r
360 * Description: Flush the write buffer and wait for completion
\r
363 *************************************************************************/
\r
364 __arm void CP15_WriteBuffFlush (void)
\r
366 register volatile Int32U Val;
\r
367 __MCR(15,0,Val,CP15_CACHE_OPR,10,4);
\r
370 /*************************************************************************
\r
371 * Function Name: CP15_GetFaultStat
\r
376 * Description: Function returns the MMU fault status register
\r
378 *************************************************************************/
\r
379 __arm Int32U CP15_GetFaultStat (void)
\r
381 return(__MRC(15,0,CP15_FAULT_STAT,0,0));
\r
384 /*************************************************************************
\r
385 * Function Name: CP15_GetFaultAddr
\r
390 * Description: Function returns the MMU fault address register
\r
392 *************************************************************************/
\r
393 __arm Int32U CP15_GetFaultAddr (void)
\r
395 return(__MRC(15,0,CP15_FAULT_ADDR,0,0));
\r
398 /*************************************************************************
\r
399 * Function Name: CP15_GetFcsePid
\r
404 * Description: Function returns the MMU Process identifier
\r
405 * FCSE PID register
\r
407 *************************************************************************/
\r
408 __arm Int32U CP15_GetFcsePid (void)
\r
410 return(__MRC(15,0,CP15_PROCESS_IDNF,0,0));
\r
413 /*************************************************************************
\r
414 * Function Name: CP15_GetPraceProcId
\r
419 * Description: Function returns the MMU Trace Process identifier
\r
422 *************************************************************************/
\r
423 __arm Int32U CP15_GetPraceProcId (void)
\r
425 return(__MRC(15,0,CP15_PROCESS_IDNF,0,1));
\r
428 /*************************************************************************
\r
429 * Function Name: CP15_SetFcsePid
\r
430 * Parameters: Int32U FcsePid
\r
434 * Description: Function set the MMU Process identifier
\r
435 * FCSE PID register
\r
437 *************************************************************************/
\r
438 __arm void CP15_SetFcsePid (Int32U FcsePid)
\r
440 register Int32U Val = FcsePid;
\r
441 __MCR(15,0,Val,CP15_PROCESS_IDNF,0,0);
\r
444 /*************************************************************************
\r
445 * Function Name: CP15_GetPraceProcId
\r
446 * Parameters: Int32U
\r
450 * Description: Function set the MMU Trace Process identifier
\r
453 *************************************************************************/
\r
454 __arm void CP15_SetPraceProcId(Int32U Trace)
\r
456 register Int32U Val = Trace;
\r
457 __MCR(15,0,Val,CP15_PROCESS_IDNF,0,1);
\r
460 /*************************************************************************
\r
461 * Function Name: CP15_InitMmuTtb
\r
462 * Parameters: pTtSectionBlock_t pTtSB, pTtTableBlock_t pTtTB
\r
466 * Returns error if MMU is enabled or if target
\r
467 * Translation Table address is not 16K aligned. Clear the
\r
468 * Translation Table area. Build the Translation Table from the
\r
469 * initialization data in the Section Block array. Return no error.
\r
471 * Description: Initializes the MMU tables.
\r
474 *************************************************************************/
\r
475 Boolean CP15_InitMmuTtb(const TtSectionBlock_t * pTtSB,
\r
476 const TtTableBlock_t * pTtTB)
\r
478 Int32U i, pa, pa_inc, va_ind;
\r
480 TableType_t TableType;
\r
483 TableType = pTtTB->TableType;
\r
487 pTtb = pTtTB->TableAddr;
\r
488 if((Int32U)pTtb & L1_ENTRIES_NUMB-1)
\r
493 pa = L1_ENTRIES_NUMB;
\r
495 case TableL2_PageTable:
\r
496 pTtb = pTtTB->TableAddr;
\r
497 if((Int32U)pTtb & L2_CP_ENTRIES_NUMB-1)
\r
502 pa = L2_CP_ENTRIES_NUMB;
\r
508 // Clear the entire Translation Table This results in LxD_TYPE_FAULT
\r
509 // being the default for any uninitialized entries.
\r
510 for(i = 0; i < pa; ++i)
\r
512 *(pTtb+i) = TT_ENTRY_INVALID;
\r
515 // Build the translation table from user provided pTtSectionBlock_t array
\r
516 while(pTtSB->NubrOfSections != 0)
\r
518 Int32U Entrys = pTtSB->NubrOfSections;
\r
519 Int32U Data = pTtSB->Entry.Data;
\r
520 pa = pTtSB->PhysAddr;
\r
525 va_ind = (pTtSB->VirtAddr >> 20) & (L1_ENTRIES_NUMB-1);
\r
527 if((va_ind + Entrys) > L1_ENTRIES_NUMB)
\r
532 case TableL2_PageTable:
\r
533 va_ind = (pTtSB->VirtAddr >> 12) & (L2_CP_ENTRIES_NUMB-1);
\r
534 if((va_ind + Entrys) > L2_CP_ENTRIES_NUMB)
\r
540 for(i = 0; i < Entrys; ++i, ++va_ind)
\r
545 switch(pTtSB->Entry.Type)
\r
547 case TtL1PageTable:
\r
548 *(pTtb+va_ind) |= Data | (pa & TTL1_PT_PADDR_MASK);
\r
551 *(pTtb+va_ind) |= Data | (pa & TTL1_SECTION_PADDR_MASK);
\r
553 case TtL1SuperSection:
\r
554 *(pTtb+va_ind) |= Data | (pa & TTL1_S_SECTION_PADDR_MASK);
\r
560 case TableL2_PageTable:
\r
561 switch(pTtSB->Entry.Type)
\r
563 case TtL2LargePage:
\r
564 *(pTtb+va_ind) |= Data | (pa & TTL2_LP_PADDR_MASK);
\r
566 case TtL2SmallPage:
\r
567 *(pTtb+va_ind) |= Data | (pa & TTL2_SP_PADDR_MASK);
\r
583 /*************************************************************************
\r
584 * Function Name: CP15_Mmu
\r
585 * Parameters: Boolean Enable
\r
589 * Description: Enable/Disable MMU
\r
591 *************************************************************************/
\r
592 void CP15_Mmu(Boolean Enable)
\r
594 Int32U Val = CP15_GetStatus();
\r
597 CP15_InvalAllTbl();
\r
598 Val |= CP15_CTRL_M;
\r
602 Val &= ~(CP15_CTRL_M | CP15_CTRL_C);
\r
604 CP15_SetStatus(Val);
\r
607 /*************************************************************************
\r
608 * Function Name: CP15_Cache
\r
609 * Parameters: Boolean Enable
\r
613 * Description: Enable/Disable Both Cache
\r
615 *************************************************************************/
\r
616 void CP15_Cache(Boolean Enable)
\r
618 Int32U Val = CP15_GetStatus();
\r
621 Val |= CP15_CTRL_M | CP15_CTRL_C | CP15_CTRL_I;
\r
625 Val &= ~CP15_CTRL_C;
\r
627 CP15_SetStatus(Val);
\r
630 /*************************************************************************
\r
631 * Function Name: CP15_InvalidateCache
\r
632 * Parameters: Boolean Enable
\r
636 * Description: Invalidate Cache
\r
638 *************************************************************************/
\r
639 void CP15_InvalidateCache()
\r
641 CP15_MaintainAllDCache(DCACHE_INVALIDATE);
\r
643 CP15_InvalInstrCache(); /* includes invalidation of branch predictor */
\r
648 /*************************************************************************
\r
649 * Function Name: CP15_ICache
\r
650 * Parameters: Boolean Enable
\r
654 * Description: Enable/Disable I cache
\r
656 *************************************************************************/
\r
657 void CP15_ICache (Boolean Enable)
\r
659 Int32U Val = CP15_GetStatus();
\r
662 Val |= CP15_CTRL_I;
\r
666 Val &= ~CP15_CTRL_I;
\r
668 CP15_SetStatus(Val);
\r
671 /*************************************************************************
\r
672 * Function Name: CP15_DCache
\r
673 * Parameters: Boolean Enable
\r
677 * Description: Enable/Disable D cache
\r
679 *************************************************************************/
\r
680 void CP15_DCache (Boolean Enable)
\r
682 Int32U Val = CP15_GetStatus();
\r
685 Val |= CP15_CTRL_M | CP15_CTRL_C;
\r
689 Val &= ~CP15_CTRL_C;
\r
691 CP15_SetStatus(Val);
\r
694 /*************************************************************************
\r
695 * Function Name: CP15_ProgFlowPrediction
\r
696 * Parameters: Boolean Enable
\r
700 * Description: Enable/Disable program flow prediction.
\r
702 *************************************************************************/
\r
703 void CP15_ProgFlowPrediction (Boolean Enable)
\r
705 Int32U Val = CP15_GetStatus();
\r
708 CP15_InvalPredictArray();
\r
709 Val |= CP15_CTRL_Z;
\r
713 Val &= ~CP15_CTRL_Z;
\r
715 CP15_SetStatus(Val);
\r
718 /*************************************************************************
\r
719 * Function Name: CP15_GetVectorBase
\r
724 * Description: Get Vector Base Register (VBAR)
\r
726 *************************************************************************/
\r
727 __arm Int32U CP15_GetVectorBase(void)
\r
729 return(__MRC(15,0,CP15_VBAR,0,0));
\r
732 /*************************************************************************
\r
733 * Function Name: CP15_SetVectorBase
\r
734 * Parameters: Int32U
\r
738 * Description: Set Vector Base Register (VBAR)
\r
740 *************************************************************************/
\r
741 __arm void CP15_SetVectorBase(Int32U vector)
\r
743 register volatile Int32U Val = vector;
\r
744 __MCR(15,0,Val,CP15_VBAR,0,0);
\r
747 /*************************************************************************
\r
748 * Function Name: CP15_SetHighVectors
\r
749 * Parameters: Boolean
\r
753 * Description: Select High or Low vectors base in CP15 control register
\r
755 *************************************************************************/
\r
756 __arm void CP15_SetHighVectors(Boolean Enable)
\r
758 Int32U Val = CP15_GetStatus();
\r
761 Val |= CP15_CTRL_V;
\r
765 Val &= ~CP15_CTRL_V;
\r
767 CP15_SetStatus(Val);
\r