]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A9_RZ_R7S72100_IAR_DS-5/IAR/modules/armv7a_cp15_drv.c
Add missing +TCP code.
[freertos] / FreeRTOS / Demo / CORTEX_A9_RZ_R7S72100_IAR_DS-5 / IAR / modules / armv7a_cp15_drv.c
1 /*************************************************************************\r
2  *\r
3  *    Used with ICCARM and AARM.\r
4  *\r
5  *    (c) Copyright IAR Systems 2012\r
6  *\r
7  *    File name   : armv7a_cp15_drv.c\r
8  *    Description : Driver for the CP15 of ARMv7-A\r
9  *\r
10  *    History :\r
11  *    1. Date        : September, 8 2006\r
12  *       Author      : Stanimir Bonev\r
13  *       Description : Driver for the ARM926EJ's CP15\r
14  *\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
19  *\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
24  *\r
25  *    $Revision: 52705 $\r
26  **************************************************************************/\r
27 \r
28 #include "armv7a_cp15_drv.h"\r
29 \r
30 /*************************************************************************\r
31  * Function Name: CP15_GetID\r
32  * Parameters: none\r
33  *\r
34  * Return: Int32U\r
35  *\r
36  * Description: Function returns the ID register\r
37  *\r
38  *************************************************************************/\r
39 __arm Int32U CP15_GetID (void)\r
40 {\r
41   return(__MRC(15,0,CP15_ID,0,0));\r
42 }\r
43 \r
44 /*************************************************************************\r
45  * Function Name: CP15_GetCacheType\r
46  * Parameters: none\r
47  *\r
48  * Return: Int32U\r
49  *\r
50  * Description: Function returns the Cache type\r
51  *\r
52  *************************************************************************/\r
53 __arm Int32U CP15_GetCacheType (void)\r
54 {\r
55   return(__MRC(15,0,CP15_ID,0,1));\r
56 }\r
57 \r
58 /*************************************************************************\r
59  * Function Name: CP15_GetTCM_Status\r
60  * Parameters: none\r
61  *\r
62  * Return: Int32U\r
63  *\r
64  * Description: Function returns the TCM status\r
65  *\r
66  *************************************************************************/\r
67 __arm Int32U CP15_GetTCM_Status (void)\r
68 {\r
69   return(__MRC(15,0,CP15_ID,0,2));\r
70 }\r
71 \r
72 /*************************************************************************\r
73  * Function Name: CP15_GetTtb0\r
74  * Parameters: none\r
75  *\r
76  * Return: Int32U\r
77  *\r
78  * Description: Function returns the TTB0 register\r
79  *\r
80  *************************************************************************/\r
81 __arm Int32U CP15_GetTtb0 (void)\r
82 {\r
83   return(__MRC(15,0,CP15_TTB_ADDR,0,0));\r
84 }\r
85 \r
86 /*************************************************************************\r
87  * Function Name: CP15_GetTtb1\r
88  * Parameters: none\r
89  *\r
90  * Return: Int32U\r
91  *\r
92  * Description: Function returns the TTB1 register\r
93  *\r
94  *************************************************************************/\r
95 __arm Int32U CP15_GetTtb1 (void)\r
96 {\r
97   return(__MRC(15,0,CP15_TTB_ADDR,0,1));\r
98 }\r
99 \r
100 /*************************************************************************\r
101  * Function Name: CP15_GetStatus\r
102  * Parameters: none\r
103  *\r
104  * Return: Int32U\r
105  *\r
106  * Description: Function returns the MMU control register\r
107  *\r
108  *************************************************************************/\r
109 __arm Int32U CP15_GetStatus (void)\r
110 {\r
111   return(__MRC(15,0,CP15_CTRL,0,0));\r
112 }\r
113 \r
114 /*************************************************************************\r
115  * Function Name: CP15_GetDomain\r
116  * Parameters: none\r
117  *\r
118  * Return: Int32U\r
119  *\r
120  * Description: Function returns the MMU domain access register\r
121  *\r
122  *************************************************************************/\r
123 __arm Int32U CP15_GetDomain (void)\r
124 {\r
125   return(__MRC(15,0,CP15_DA_CTRL,0,0));\r
126 }\r
127 \r
128 /*************************************************************************\r
129  * Function Name: CP15_SetDomains\r
130  * Parameters: Int32U DomainAccess\r
131  *\r
132  * Return: Int32U\r
133  *\r
134  * Description: Function set the MMU domain access register\r
135  *\r
136  *************************************************************************/\r
137 __arm void CP15_SetDomains (Int32U DomainAccess)\r
138 {\r
139 register Int32U Val = DomainAccess;\r
140   __MCR(15,0,Val,CP15_DA_CTRL,0,0);\r
141 }\r
142 \r
143 /*************************************************************************\r
144  * Function Name: log2_n_up\r
145  * Parameters: Int32U n\r
146  *\r
147  * Return: Int32S\r
148  *\r
149  * Description: Logarithm at base 2 , rounded up\r
150  *\r
151  *************************************************************************/\r
152 Int32S log2_up(Int32U n)\r
153 {\r
154   Int32S log = -1;\r
155   Int32U t = n;\r
156   while(t)\r
157   {\r
158     log++; t >>=1;\r
159   }\r
160   /* if n not power of 2 -> round up*/\r
161   if ( n & (n - 1) ) log++;\r
162   return log;\r
163 }\r
164 \r
165 /*************************************************************************\r
166  * Function Name: CP15_MaintainDCacheSetWay\r
167  * Parameters: Int32U level - level of cache, \r
168  *             Int32U maint - maintenance type\r
169  *\r
170  * Return: none\r
171  *\r
172  * Description: Maintain data cache line by Set/Way\r
173  *\r
174  *************************************************************************/\r
175 __arm void CP15_MaintainDCacheSetWay(Int32U level, Int32U maint)\r
176 {\r
177 register volatile Int32U Dummy;\r
178 register volatile Int32U ccsidr;\r
179 Int32U num_sets;\r
180 Int32U num_ways;\r
181 Int32U shift_way;\r
182 Int32U log2_linesize;\r
183 Int32U log2_num_ways;\r
184 \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
197     {\r
198       Dummy = (level << 1) | (set << log2_linesize) | (way << shift_way);\r
199       switch (maint)\r
200       {\r
201         case DCACHE_CLEAN_AND_INVALIDATE:\r
202              __MCR(15,0,Dummy,7,14,2);\r
203              break;\r
204         \r
205         case DCACHE_INVALIDATE:\r
206              __MCR(15,0,Dummy,7,6,2);\r
207              break;\r
208       }\r
209     }\r
210     __DMB();\r
211 }\r
212 \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
218  *\r
219  * Return: none\r
220  *\r
221  * Description: Maintenance of all data cache\r
222  *\r
223  *************************************************************************/\r
224 __arm void CP15_MaintainAllDCache(Int32U oper)\r
225 {\r
226 register volatile Int32U clidr;  \r
227 Int32U cache_type;\r
228   clidr =  __MRC(15,1,0,0,1);\r
229   for(Int32U i = 0; i<7; i++)\r
230   {\r
231     cache_type = (clidr >> i*3) & 0x7UL;\r
232     if ((cache_type >= 2) && (cache_type <= 4))\r
233     {\r
234       CP15_MaintainDCacheSetWay(i,oper);\r
235     }\r
236   }\r
237 }\r
238 \r
239 /*************************************************************************\r
240  * Function Name: CP15_InvalInstrCache\r
241  * Parameters: none\r
242  *\r
243  * Return: none\r
244  *\r
245  * Description: Invalidate instruction cache\r
246  *\r
247  *************************************************************************/\r
248 __arm void CP15_InvalInstrCache(void)\r
249 {\r
250 register volatile Int32U Dummy;\r
251   __MCR(15,0,Dummy,CP15_CACHE_OPR,5,0);\r
252   CP15_InvalPredictArray();\r
253   __DSB();\r
254   __ISB();\r
255 }\r
256 \r
257 /*************************************************************************\r
258  * Function Name: CP15_InvalPredictArray\r
259  * Parameters: none\r
260  *\r
261  * Return: none\r
262  *\r
263  * Description: Invalidate prediction array\r
264  *\r
265  *************************************************************************/\r
266 __arm void CP15_InvalPredictArray(void)\r
267 {\r
268 register volatile Int32U Dummy;\r
269   __MCR(15,0,Dummy,CP15_CACHE_OPR,5,6);  __ISB();\r
270 }\r
271 \r
272 /*************************************************************************\r
273  * Function Name: CP15_InvalAllTbl\r
274  * Parameters: none\r
275  *\r
276  * Return: none\r
277  *\r
278  * Description: Invalidate TLB\r
279  *\r
280  *************************************************************************/\r
281 __arm void CP15_InvalAllTbl (void)\r
282 {\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
290   __DSB();\r
291   __ISB();\r
292 }\r
293 \r
294 /*************************************************************************\r
295  * Function Name: CP15_SetStatus\r
296  * Parameters: Int32U Ctrl\r
297  *\r
298  * Return: none\r
299  *\r
300  * Description: Set CP15 CTR (control) register\r
301  *\r
302  *************************************************************************/\r
303 __arm void CP15_SetStatus (Int32U Ctrl)\r
304 {\r
305 register volatile Int32U Val = Ctrl;\r
306   __MCR(15,0,Val,CP15_CTRL,0,0);\r
307 }\r
308 \r
309 /*************************************************************************\r
310  * Function Name: CP15_SetTtb0\r
311  * Parameters: pInt32U pTtb\r
312  *\r
313  * Return: none\r
314  *\r
315  * Description: Set CP15 TTB0 base address register\r
316  *\r
317  *************************************************************************/\r
318 __arm void CP15_SetTtb0 (pInt32U pTtb)\r
319 {\r
320 register volatile Int32U Val = (Int32U)pTtb;\r
321   __MCR(15,0,Val,CP15_TTB_ADDR,0,0);\r
322 }\r
323 \r
324 /*************************************************************************\r
325  * Function Name: CP15_SetTtb1\r
326  * Parameters: pInt32U pTtb\r
327  *\r
328  * Return: none\r
329  *\r
330  * Description: Set CP15 TTB1 base address register\r
331  *\r
332  *************************************************************************/\r
333 __arm void CP15_SetTtb1 (pInt32U pTtb)\r
334 {\r
335 register volatile Int32U Val = (Int32U)pTtb;\r
336   __MCR(15,0,Val,CP15_TTB_ADDR,0,1);\r
337 }\r
338 \r
339 /*************************************************************************\r
340  * Function Name: CP15_SetDac\r
341  * Parameters: Int32U da\r
342  *\r
343  * Return: none\r
344  *\r
345  * Description: Set CP15 domain access register\r
346  *\r
347  *************************************************************************/\r
348 __arm void CP15_SetDac (Int32U da)\r
349 {\r
350 register volatile Int32U Val = da;\r
351   __MCR(15,0,Val,CP15_DA_CTRL,0,0);\r
352 }\r
353 \r
354 /*************************************************************************\r
355  * Function Name: CP15_WriteBuffFlush\r
356  * Parameters: none\r
357  *\r
358  * Return: none\r
359  *\r
360  * Description:  Flush the write buffer and wait for completion\r
361  *              of the flush.\r
362  *\r
363  *************************************************************************/\r
364 __arm void CP15_WriteBuffFlush (void)\r
365 {\r
366 register volatile Int32U Val;\r
367   __MCR(15,0,Val,CP15_CACHE_OPR,10,4);\r
368 }\r
369 \r
370 /*************************************************************************\r
371  * Function Name: CP15_GetFaultStat\r
372  * Parameters: none\r
373  *\r
374  * Return: Int32U\r
375  *\r
376  * Description: Function returns the MMU fault status register\r
377  *\r
378  *************************************************************************/\r
379 __arm Int32U CP15_GetFaultStat (void)\r
380 {\r
381   return(__MRC(15,0,CP15_FAULT_STAT,0,0));\r
382 }\r
383 \r
384 /*************************************************************************\r
385  * Function Name: CP15_GetFaultAddr\r
386  * Parameters: none\r
387  *\r
388  * Return: Int32U\r
389  *\r
390  * Description: Function returns the MMU fault address register\r
391  *\r
392  *************************************************************************/\r
393 __arm Int32U CP15_GetFaultAddr (void)\r
394 {\r
395   return(__MRC(15,0,CP15_FAULT_ADDR,0,0));\r
396 }\r
397 \r
398 /*************************************************************************\r
399  * Function Name: CP15_GetFcsePid\r
400  * Parameters: none\r
401  *\r
402  * Return: Int32U\r
403  *\r
404  * Description: Function returns the MMU Process identifier\r
405  *             FCSE PID register\r
406  *\r
407  *************************************************************************/\r
408 __arm Int32U CP15_GetFcsePid (void)\r
409 {\r
410   return(__MRC(15,0,CP15_PROCESS_IDNF,0,0));\r
411 }\r
412 \r
413 /*************************************************************************\r
414  * Function Name: CP15_GetPraceProcId\r
415  * Parameters: none\r
416  *\r
417  * Return: Int32U\r
418  *\r
419  * Description: Function returns the MMU Trace Process identifier\r
420  *             register\r
421  *\r
422  *************************************************************************/\r
423 __arm Int32U CP15_GetPraceProcId (void)\r
424 {\r
425   return(__MRC(15,0,CP15_PROCESS_IDNF,0,1));\r
426 }\r
427 \r
428 /*************************************************************************\r
429  * Function Name: CP15_SetFcsePid\r
430  * Parameters: Int32U FcsePid\r
431  *\r
432  * Return: none\r
433  *\r
434  * Description: Function set the MMU Process identifier\r
435  *             FCSE PID register\r
436  *\r
437  *************************************************************************/\r
438 __arm void CP15_SetFcsePid (Int32U FcsePid)\r
439 {\r
440 register Int32U Val = FcsePid;\r
441   __MCR(15,0,Val,CP15_PROCESS_IDNF,0,0);\r
442 }\r
443 \r
444 /*************************************************************************\r
445  * Function Name: CP15_GetPraceProcId\r
446  * Parameters: Int32U\r
447  *\r
448  * Return: none\r
449  *\r
450  * Description: Function set the MMU Trace Process identifier\r
451  *             register\r
452  *\r
453  *************************************************************************/\r
454 __arm void CP15_SetPraceProcId(Int32U Trace)\r
455 {\r
456 register Int32U Val = Trace;\r
457   __MCR(15,0,Val,CP15_PROCESS_IDNF,0,1);\r
458 }\r
459 \r
460 /*************************************************************************\r
461  * Function Name: CP15_InitMmuTtb\r
462  * Parameters: pTtSectionBlock_t pTtSB, pTtTableBlock_t pTtTB\r
463  *\r
464  * Return: Boolean\r
465  *\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
470  *\r
471  * Description:  Initializes the MMU tables.\r
472  *\r
473  *\r
474  *************************************************************************/\r
475 Boolean CP15_InitMmuTtb(const TtSectionBlock_t * pTtSB,\r
476                         const TtTableBlock_t * pTtTB)\r
477 {\r
478 Int32U i, pa, pa_inc, va_ind;\r
479 pInt32U pTtb;\r
480 TableType_t TableType;\r
481   while(1)\r
482   {\r
483     TableType = pTtTB->TableType;\r
484     switch(TableType)\r
485     {\r
486     case TableL1:\r
487       pTtb = pTtTB->TableAddr;\r
488       if((Int32U)pTtb & L1_ENTRIES_NUMB-1)\r
489       {\r
490         return(FALSE);\r
491       }\r
492       pa_inc = 0x100000;\r
493       pa = L1_ENTRIES_NUMB;\r
494       break;\r
495     case TableL2_PageTable:\r
496       pTtb = pTtTB->TableAddr;\r
497       if((Int32U)pTtb & L2_CP_ENTRIES_NUMB-1)\r
498       {\r
499         return(FALSE);\r
500       }\r
501       pa_inc = 0x1000;\r
502       pa = L2_CP_ENTRIES_NUMB;\r
503       break;\r
504     default:\r
505       return(TRUE);\r
506     }\r
507 \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
511     {\r
512       *(pTtb+i) = TT_ENTRY_INVALID;\r
513     }\r
514 \r
515     // Build the translation table from user provided pTtSectionBlock_t array\r
516     while(pTtSB->NubrOfSections != 0)\r
517     {\r
518 Int32U Entrys = pTtSB->NubrOfSections;\r
519 Int32U Data =  pTtSB->Entry.Data;   \r
520       pa = pTtSB->PhysAddr;\r
521       \r
522       switch(TableType)\r
523       {\r
524       case TableL1:\r
525         va_ind = (pTtSB->VirtAddr >> 20) & (L1_ENTRIES_NUMB-1);\r
526                 \r
527         if((va_ind + Entrys) > L1_ENTRIES_NUMB)\r
528         {\r
529           return(FALSE);\r
530         }\r
531         break;\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
535         {\r
536           return(FALSE);\r
537         }\r
538         break;\r
539       }\r
540       for(i = 0; i < Entrys; ++i, ++va_ind)\r
541       {\r
542         switch(TableType)\r
543         {\r
544         case TableL1:\r
545           switch(pTtSB->Entry.Type)\r
546           {\r
547           case TtL1PageTable:\r
548             *(pTtb+va_ind) |= Data | (pa & TTL1_PT_PADDR_MASK);\r
549             break;\r
550           case TtL1Section:\r
551             *(pTtb+va_ind) |= Data | (pa & TTL1_SECTION_PADDR_MASK);\r
552             break;\r
553           case TtL1SuperSection:\r
554               *(pTtb+va_ind) |= Data | (pa & TTL1_S_SECTION_PADDR_MASK);\r
555             break;\r
556           default:\r
557             return(FALSE);\r
558           }\r
559           break;\r
560         case TableL2_PageTable:\r
561           switch(pTtSB->Entry.Type)\r
562           {\r
563           case TtL2LargePage:\r
564             *(pTtb+va_ind) |= Data | (pa & TTL2_LP_PADDR_MASK);\r
565             break;\r
566           case TtL2SmallPage:\r
567             *(pTtb+va_ind) |= Data | (pa & TTL2_SP_PADDR_MASK);\r
568             break;\r
569           default:\r
570             return(FALSE);\r
571           }\r
572           break;\r
573         }\r
574         pa += pa_inc;\r
575       }\r
576       ++pTtSB;\r
577     }\r
578     ++pTtSB;\r
579     ++pTtTB;\r
580   }\r
581 }\r
582 \r
583 /*************************************************************************\r
584  * Function Name: CP15_Mmu\r
585  * Parameters: Boolean Enable\r
586  *\r
587  * Return: none\r
588  *\r
589  * Description: Enable/Disable MMU\r
590  *\r
591  *************************************************************************/\r
592 void CP15_Mmu(Boolean Enable)\r
593 {\r
594 Int32U Val = CP15_GetStatus();\r
595   if(Enable)\r
596   {\r
597     CP15_InvalAllTbl();\r
598     Val |= CP15_CTRL_M;\r
599   }\r
600   else\r
601   {\r
602     Val &= ~(CP15_CTRL_M | CP15_CTRL_C);\r
603   }  \r
604   CP15_SetStatus(Val);\r
605 }\r
606 \r
607 /*************************************************************************\r
608  * Function Name: CP15_Cache\r
609  * Parameters: Boolean Enable\r
610  *\r
611  * Return: none\r
612  *\r
613  * Description: Enable/Disable Both Cache\r
614  *\r
615  *************************************************************************/\r
616 void CP15_Cache(Boolean Enable)\r
617 {\r
618 Int32U Val = CP15_GetStatus();\r
619   if(Enable)\r
620   { \r
621     Val |= CP15_CTRL_M | CP15_CTRL_C | CP15_CTRL_I;\r
622   }\r
623   else\r
624   {\r
625     Val &= ~CP15_CTRL_C;\r
626   }\r
627   CP15_SetStatus(Val);  \r
628 }\r
629 \r
630 /*************************************************************************\r
631  * Function Name: CP15_InvalidateCache\r
632  * Parameters: Boolean Enable\r
633  *\r
634  * Return: none\r
635  *\r
636  * Description: Invalidate Cache\r
637  *\r
638  *************************************************************************/\r
639 void CP15_InvalidateCache()\r
640 {\r
641   CP15_MaintainAllDCache(DCACHE_INVALIDATE);\r
642   __DSB();\r
643   CP15_InvalInstrCache(); /* includes invalidation of branch predictor */\r
644   __DSB();\r
645   __ISB();\r
646 }\r
647 \r
648 /*************************************************************************\r
649  * Function Name: CP15_ICache\r
650  * Parameters: Boolean Enable\r
651  *\r
652  * Return: none\r
653  *\r
654  * Description: Enable/Disable I cache\r
655  *\r
656  *************************************************************************/\r
657 void CP15_ICache (Boolean Enable)\r
658 {\r
659 Int32U Val = CP15_GetStatus();\r
660   if(Enable)\r
661   {\r
662     Val |= CP15_CTRL_I;\r
663   }\r
664   else\r
665   {\r
666     Val &= ~CP15_CTRL_I;\r
667   }\r
668   CP15_SetStatus(Val);\r
669 }\r
670 \r
671 /*************************************************************************\r
672  * Function Name: CP15_DCache\r
673  * Parameters: Boolean Enable\r
674  *\r
675  * Return: none\r
676  *\r
677  * Description: Enable/Disable D cache\r
678  *\r
679  *************************************************************************/\r
680 void CP15_DCache (Boolean Enable)\r
681 {\r
682 Int32U Val = CP15_GetStatus();\r
683   if(Enable)\r
684   {\r
685     Val |= CP15_CTRL_M | CP15_CTRL_C;\r
686   }\r
687   else\r
688   {\r
689     Val &= ~CP15_CTRL_C;\r
690   }\r
691   CP15_SetStatus(Val);\r
692 }\r
693 \r
694 /*************************************************************************\r
695  * Function Name: CP15_ProgFlowPrediction\r
696  * Parameters: Boolean Enable\r
697  *\r
698  * Return: none\r
699  *\r
700  * Description: Enable/Disable program flow prediction.\r
701  *\r
702  *************************************************************************/\r
703 void CP15_ProgFlowPrediction (Boolean Enable)\r
704 {\r
705 Int32U Val = CP15_GetStatus();\r
706   if(Enable)\r
707   {\r
708     CP15_InvalPredictArray();\r
709     Val |= CP15_CTRL_Z;\r
710   }\r
711   else\r
712   {\r
713     Val &= ~CP15_CTRL_Z;\r
714   }\r
715   CP15_SetStatus(Val);\r
716 }\r
717 \r
718 /*************************************************************************\r
719  * Function Name: CP15_GetVectorBase\r
720  * Parameters: none\r
721  *\r
722  * Return: Int32U\r
723  *\r
724  * Description: Get Vector Base Register (VBAR)\r
725  *\r
726  *************************************************************************/\r
727 __arm Int32U CP15_GetVectorBase(void)\r
728 {\r
729   return(__MRC(15,0,CP15_VBAR,0,0));\r
730 }\r
731 \r
732 /*************************************************************************\r
733  * Function Name: CP15_SetVectorBase\r
734  * Parameters: Int32U\r
735  *\r
736  * Return: none\r
737  *\r
738  * Description: Set Vector Base Register (VBAR)\r
739  *\r
740  *************************************************************************/\r
741 __arm void CP15_SetVectorBase(Int32U vector)\r
742 {\r
743 register volatile Int32U Val = vector;\r
744   __MCR(15,0,Val,CP15_VBAR,0,0);\r
745 }\r
746 \r
747 /*************************************************************************\r
748  * Function Name: CP15_SetHighVectors\r
749  * Parameters: Boolean\r
750  *\r
751  * Return: none\r
752  *\r
753  * Description: Select High or Low vectors base in CP15 control register\r
754  *\r
755  *************************************************************************/\r
756 __arm void CP15_SetHighVectors(Boolean Enable)\r
757 {\r
758 Int32U Val = CP15_GetStatus();\r
759   if(Enable)\r
760   {\r
761     Val |= CP15_CTRL_V;\r
762   }\r
763   else\r
764   {\r
765     Val &= ~CP15_CTRL_V;\r
766   }\r
767   CP15_SetStatus(Val);\r
768 }\r