1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - OS
3   File:     os_protectionRegion.c
4 
5   Copyright 2003-2008 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-09-18#$
14   $Rev: 8573 $
15   $Author: okubata_ryoma $
16 
17  *---------------------------------------------------------------------------*/
18 #include <nitro/os.h>
19 #include <nitro/code32.h>
20 
21 //================================================================================
22 //               Instruction Cache for each protection region
23 //================================================================================
24 /*---------------------------------------------------------------------------*
25   Name:         OS_EnableICacheForProtectionRegion
26                 OS_DisableICacheForProtectionRegion
27 
28   Description:  enable/disable instruction cache for each protection region
29 
30   Arguments:    flags :  Each bit shows the region to be enable/disable.
31                            bit0(LSB) ... protection region 0
32                            bit1      ... protection region 1
33                              :                  :
34                            bit7      ... protection region 7
35 
36   Returns:      None
37  *---------------------------------------------------------------------------*/
OS_EnableICacheForProtectionRegion(register u32 flags)38 asm void OS_EnableICacheForProtectionRegion( register u32 flags )
39 {
40     mrc     p15, 0, r1, c2, c0, 1
41     orr     r1, r1, r0
42     mcr     p15, 0, r1, c2, c0, 1
43     bx      lr
44 }
45 
46 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OS_DisableICacheForProtectionRegion(register u32 flags)47 asm void OS_DisableICacheForProtectionRegion( register u32 flags )
48 {
49     mrc     p15, 0, r1, c2, c0, 1
50     bic     r1, r1, r0
51     mcr     p15, 0, r1, c2, c0, 1
52     bx      lr
53 }
54 
55 /*---------------------------------------------------------------------------*
56   Name:         OS_GetICacheEnableFlagsForProtectionRegion
57 
58   Description:  get instruction cache status for each protection region
59 
60   Arguments:    None
61 
62   Returns:      instruction cache status.
63                 bit for each protection region, means 1... enable, 0... disable
64 
65                            bit0(LSB) ... protection region 0
66                            bit1      ... protection region 1
67                              :                  :
68                            bit7      ... protection region 7
69 
70  *---------------------------------------------------------------------------*/
OS_GetICacheEnableFlagsForProtectionRegion(void)71 asm u32 OS_GetICacheEnableFlagsForProtectionRegion( void )
72 {
73     mrc     p15, 0, r0, c2, c0, 1
74     bx      lr
75 }
76 
77 /*---------------------------------------------------------------------------*
78   Name:         OS_SetIPermissionsForProtectionRegion
79 
80   Description:  set instruction access limitation for each protection region
81 
82   Arguments:    setMask : set mask bit, which is or-ed by mask.
83                 flags   : flag bit, which is or-ed by access limitation.
84 
85                    (mask)
86                           OS_PRn_ACCESS_MASK (n=0-7)
87 
88                    (access limitation)
89                           OS_PRn_ACCESS_NA    no permission to access
90                           OS_PRn_ACCESS_RW    read and write permission
91                           OS_PRn_ACCESS_RO    read only permission
92                           (n=0-7)
93 
94                 ex.
95                     In case to set region3 readonly and region6 no permission, call
96                     OS_SetIPermissionsForProtectionRegion(
97                              OS_PR3_ACCESS_MASK | OS_PR6_ACCESS_MASK,
98                              OS_PR3_ACCESS_RO | OS_PR6_ACCESS_NA );
99 
100   Returns:      None
101  *---------------------------------------------------------------------------*/
OS_SetIPermissionsForProtectionRegion(register u32 setMask,register u32 flags)102 asm void OS_SetIPermissionsForProtectionRegion( register u32 setMask, register u32 flags )
103 {
104     mrc     p15, 0, r2, c5, c0, 3
105     bic     r2, r2, r0
106     orr     r2, r2, r1
107     mcr     p15, 0, r2, c5, c0, 3
108     bx      lr
109 }
110 
111 /*---------------------------------------------------------------------------*
112   Name:         OS_GetIPermissionsForProtectionRegion
113 
114   Description:  get instruction access limitation for each protection region
115 
116   Arguments:    None
117 
118   Returns:      Return value & OS_PRn_ACCESS_MASK (n=0-7) shows access limitation.
119 
120                    (access limitation)
121                           OS_PRn_ACCESS_NA    no permission to access
122                           OS_PRn_ACCESS_RW    read and write permission
123                           OS_PRn_ACCESS_RO    read only permission
124                           (n=0-7)
125 
126  *---------------------------------------------------------------------------*/
OS_GetIPermissionsForProtectionRegion(void)127 asm u32 OS_GetIPermissionsForProtectionRegion( void )
128 {
129     mrc     p15, 0, r0, c5, c0, 3
130     bx      lr
131 }
132 
133 //================================================================================
134 //               Data Cache for each protection region
135 //================================================================================
136 /*---------------------------------------------------------------------------*
137   Name:         OS_EnableDCacheForProtectionRegion
138                 OS_DisableDCacheForProtectionRegion
139 
140   Description:  enable/disable data cache for each protection region
141 
142   Arguments:    flags :  Each bit shows the region to be enable/disable.
143                            bit0(LSB) ... protection region 0
144                            bit1      ... protection region 1
145                              :                  :
146                            bit7      ... protection region 7
147 
148   Returns:      None
149  *---------------------------------------------------------------------------*/
OS_EnableDCacheForProtectionRegion(register u32 flags)150 asm void OS_EnableDCacheForProtectionRegion( register u32 flags )
151 {
152     mrc     p15, 0, r1, c2, c0, 0
153     orr     r1, r1, r0
154     mcr     p15, 0, r1, c2, c0, 0
155     bx      lr
156 }
157 
158 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OS_DisableDCacheForProtectionRegion(register u32 flags)159 asm void OS_DisableDCacheForProtectionRegion( register u32 flags )
160 {
161     mrc     p15, 0, r1, c2, c0, 0
162     bic     r1, r1, r0
163     mcr     p15, 0, r1, c2, c0, 0
164     bx      lr
165 }
166 
167 /*---------------------------------------------------------------------------*
168   Name:         OS_GetDCacheEnableFlagsForProtectionRegion
169 
170   Description:  get data cache status for each protection region
171 
172   Arguments:    None
173 
174   Returns:      data cache status.
175                 bit for each protection region, means 1... enable, 0... disable
176 
177                            bit0(LSB) ... protection region 0
178                            bit1      ... protection region 1
179                              :                  :
180                            bit7      ... protection region 7
181 
182  *---------------------------------------------------------------------------*/
OS_GetDCacheEnableFlagsForProtectionRegion(void)183 asm u32 OS_GetDCacheEnableFlagsForProtectionRegion( void )
184 {
185     mrc     p15, 0, r0, c2, c0, 0
186     bx      lr
187 }
188 
189 /*---------------------------------------------------------------------------*
190   Name:         OS_SetDPermissionsForProtectionRegion
191 
192   Description:  set data access limitation for each protection region
193 
194   Arguments:    setMask : set mask bit, which is or-ed by mask.
195                 flags   : flag bit, which is or-ed by access limitation.
196 
197                    (mask)
198                           OS_PRn_ACCESS_MASK (n=0-7)
199 
200                    (access limitation)
201                           OS_PRn_ACCESS_NA    no permission to access
202                           OS_PRn_ACCESS_RW    read and write permission
203                           OS_PRn_ACCESS_RO    read only permission
204                           (n=0-7)
205 
206                 ex.
207                     In case to set region3 readonly and region6 no permission, call
208                     OS_SetDPermissionsForProtectionRegion(
209                              OS_PR3_ACCESS_MASK | OS_PR6_ACCESS_MASK,
210                              OS_PR3_ACCESS_RO | OS_PR6_ACCESS_NA );
211 
212   Returns:      None
213  *---------------------------------------------------------------------------*/
OS_SetDPermissionsForProtectionRegion(register u32 setMask,register u32 flags)214 asm void OS_SetDPermissionsForProtectionRegion( register u32 setMask, register u32 flags )
215 {
216     mrc     p15, 0, r2, c5, c0, 2
217     bic     r2, r2, r0
218     orr     r2, r2, r1
219     mcr     p15, 0, r2, c5, c0, 2
220     bx      lr
221 }
222 
223 /*---------------------------------------------------------------------------*
224   Name:         OS_GetDPermissionsForProtectionRegion
225 
226   Description:  get data access limitation for each protection region
227 
228   Arguments:    None
229 
230   Returns:      Return value & OS_PRn_ACCESS_MASK (n=0-7) shows access limitation.
231 
232                    (access limitation)
233                           OS_PRn_ACCESS_NA    no permission to access
234                           OS_PRn_ACCESS_RW    read and write permission
235                           OS_PRn_ACCESS_RO    read only permission
236                           (n=0-7)
237 
238  *---------------------------------------------------------------------------*/
OS_GetDPermissionsForProtectionRegion(void)239 asm u32 OS_GetDPermissionsForProtectionRegion( void )
240 {
241     mrc     p15, 0, r0, c5, c0, 2
242     bx      lr
243 }
244 
245 //================================================================================
246 //               Write buffer for each protection region
247 //================================================================================
248 /*---------------------------------------------------------------------------*
249   Name:         OS_EnableWriteBufferForProtectionRegion
250                 OS_DisableWriteBufferForProtectionRegion
251 
252   Description:  enable/disable write buffer for each protection region
253 
254   Arguments:    flags :  Each bit shows the region to be enable/disable.
255                            bit0(LSB) ... protection region 0
256                            bit1      ... protection region 1
257                              :                  :
258                            bit7      ... protection region 7
259 
260   Returns:      None
261  *---------------------------------------------------------------------------*/
OS_EnableWriteBufferForProtectionRegion(register u32 flags)262 asm void OS_EnableWriteBufferForProtectionRegion( register u32 flags )
263 {
264     mrc     p15, 0, r1, c3, c0, 0
265     orr     r1, r1, r0
266     mcr     p15, 0, r1, c3, c0, 0
267     bx      lr
268 }
269 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OS_DisableWriteBufferForProtectionRegion(register u32 flags)270 asm void OS_DisableWriteBufferForProtectionRegion( register u32 flags )
271 {
272     mrc     p15, 0, r1, c3, c0, 0
273     bic     r1, r1, r0
274     mcr     p15, 0, r1, c3, c0, 0
275     bx      lr
276 }
277 
278 /*---------------------------------------------------------------------------*
279   Name:         OS_GetWriteBufferEnableFlagsForProtectionRegion
280 
281   Description:  get write buffer status for each protection region
282 
283   Arguments:    None
284 
285   Returns:      write buffer status.
286                 bit for each protection region, means 1... enable, 0... disable
287 
288                            bit0(LSB) ... protection region 0
289                            bit1      ... protection region 1
290                              :                  :
291                            bit7      ... protection region 7
292 
293  *---------------------------------------------------------------------------*/
OS_GetWriteBufferEnableFlagsForProtectionRegion(register u32 flags)294 asm u32 OS_GetWriteBufferEnableFlagsForProtectionRegion( register u32 flags )
295 {
296     mrc     p15, 0, r0, c3, c0, 0
297     bx      lr
298 }
299 
300 //================================================================================
301 //          protection region
302 //================================================================================
303 /*---------------------------------------------------------------------------*
304   Name:         OS_SetProtectionRegionParam
305 
306   Description:  set up parameter of protection region
307 
308   Arguments:    regionNo :   region number
309                 param    :   parameter ( created from base address and size )
310 
311   Returns:      None
312  *---------------------------------------------------------------------------*/
OS_SetProtectionRegionParam(int regionNo,u32 param)313 void OS_SetProtectionRegionParam( int regionNo, u32 param )
314 {
315 	static void (*f[])(u32) =
316 	{
317 		OS_SetProtectionRegion0,
318 		OS_SetProtectionRegion1,
319 		OS_SetProtectionRegion2,
320 		OS_SetProtectionRegion3,
321 		OS_SetProtectionRegion4,
322 		OS_SetProtectionRegion5,
323 		OS_SetProtectionRegion6,
324 		OS_SetProtectionRegion7
325 	};
326     SDK_ASSERT( regionNo>=0 && regionNo<OS_PROTECTION_REGION_NUM );
327 
328 	f[regionNo](param);
329 }
330 
331 /*---------------------------------------------------------------------------*
332   Name:         OS_SetProtectionRegion*
333 
334   Description:  set up parameter of each protection region
335 
336   Arguments:    param    :   parameter ( created from base address and size )
337 
338   Returns:      None
339  *---------------------------------------------------------------------------*/
OS_SetProtectionRegion0(u32 param)340 asm void OS_SetProtectionRegion0( u32 param )
341 {
342     mcr     p15, 0, r0, c6, c0, 0
343     bx      lr
344 }
345 
OS_SetProtectionRegion1(u32 param)346 asm void OS_SetProtectionRegion1( u32 param )
347 {
348     mcr     p15, 0, r0, c6, c1, 0
349     bx      lr
350 }
351 
OS_SetProtectionRegion2(u32 param)352 asm void OS_SetProtectionRegion2( u32 param )
353 {
354     mcr     p15, 0, r0, c6, c2, 0
355     bx      lr
356 }
357 
OS_SetProtectionRegion3(u32 param)358 asm void OS_SetProtectionRegion3( u32 param )
359 {
360     mcr     p15, 0, r0, c6, c3, 0
361     bx      lr
362 }
363 
OS_SetProtectionRegion4(u32 param)364 asm void OS_SetProtectionRegion4( u32 param )
365 {
366     mcr     p15, 0, r0, c6, c4, 0
367     bx      lr
368 }
369 
OS_SetProtectionRegion5(u32 param)370 asm void OS_SetProtectionRegion5( u32 param )
371 {
372     mcr     p15, 0, r0, c6, c5, 0
373     bx      lr
374 }
375 
OS_SetProtectionRegion6(u32 param)376 asm void OS_SetProtectionRegion6( u32 param )
377 {
378     mcr     p15, 0, r0, c6, c6, 0
379     bx      lr
380 }
381 
OS_SetProtectionRegion7(u32 param)382 asm void OS_SetProtectionRegion7( u32 param )
383 {
384     mcr     p15, 0, r0, c6, c7, 0
385     bx      lr
386 }
387 
388 /*---------------------------------------------------------------------------*
389   Name:         OS_GetProtectionRegionParam
390 
391   Description:  get parameter of protection region
392 
393   Arguments:    regionNo :   region number
394 
395   Returns:      parameter of protection region ( created from base address and size )
396  *---------------------------------------------------------------------------*/
OS_GetProtectionRegionParam(int regionNo)397 u32  OS_GetProtectionRegionParam( int regionNo )
398 {
399 	static u32 (*f[])(void) =
400 	{
401 		OS_GetProtectionRegion0,
402 		OS_GetProtectionRegion1,
403 		OS_GetProtectionRegion2,
404 		OS_GetProtectionRegion3,
405 		OS_GetProtectionRegion4,
406 		OS_GetProtectionRegion5,
407 		OS_GetProtectionRegion6,
408 		OS_GetProtectionRegion7
409 	};
410     SDK_ASSERT( regionNo>=0 && regionNo<OS_PROTECTION_REGION_NUM );
411 
412 	return f[regionNo]();
413 }
414 
415 /*---------------------------------------------------------------------------*
416   Name:         OS_GetProtectionRegion*
417 
418   Description:  get parameter of each protection region
419 
420   Arguments:    None
421 
422   Returns:      parameter of protection region ( created from base address and size )
423  *---------------------------------------------------------------------------*/
OS_GetProtectionRegion0(void)424 asm u32 OS_GetProtectionRegion0( void )
425 {
426     mrc     p15, 0, r0, c6, c0, 0
427     bx      lr
428 }
429 
OS_GetProtectionRegion1(void)430 asm u32 OS_GetProtectionRegion1( void )
431 {
432     mrc     p15, 0, r0, c6, c1, 0
433     bx      lr
434 }
435 
OS_GetProtectionRegion2(void)436 asm u32 OS_GetProtectionRegion2( void )
437 {
438     mrc     p15, 0, r0, c6, c2, 0
439     bx      lr
440 }
441 
OS_GetProtectionRegion3(void)442 asm u32 OS_GetProtectionRegion3( void )
443 {
444     mrc     p15, 0, r0, c6, c3, 0
445     bx      lr
446 }
447 
OS_GetProtectionRegion4(void)448 asm u32 OS_GetProtectionRegion4( void )
449 {
450     mrc     p15, 0, r0, c6, c4, 0
451     bx      lr
452 }
453 
OS_GetProtectionRegion5(void)454 asm u32 OS_GetProtectionRegion5( void )
455 {
456     mrc     p15, 0, r0, c6, c5, 0
457     bx      lr
458 }
459 
OS_GetProtectionRegion6(void)460 asm u32 OS_GetProtectionRegion6( void )
461 {
462     mrc     p15, 0, r0, c6, c6, 0
463     bx      lr
464 }
465 
OS_GetProtectionRegion7(void)466 asm u32 OS_GetProtectionRegion7( void )
467 {
468     mrc     p15, 0, r0, c6, c7, 0
469     bx      lr
470 }
471 
472 /*---------------------------------------------------------------------------*
473   Name:         OS_SetProtectionRegionEx
474 
475   Description:  set up parameter of protection region
476 
477   Arguments:    regionNo :   region number
478                 address  :   base address
479                 sizeDef  :   size value.
480 
481                 regionNo must be immidiate number, from 0 to 7.
482                 sizeStr is OS_PR_SIZE_xxx  (xxx=4KB, 8KB, 16KB, ..., 4GB )
483 
484                 ex. OSi_SetProtectionRegion( 3, 0x2000000, OS_PR_SIZE_4KB );
485 
486   Returns:      None
487  *---------------------------------------------------------------------------*/
OS_SetProtectionRegionEx(int regionNo,u32 address,u32 sizeDef)488 void OS_SetProtectionRegionEx( int regionNo, u32 address, u32 sizeDef )
489 {
490 	u32 mask = 0xfffff000 << OSi_PRDEF_TO_VAL(sizeDef);
491 	u32 param = OSi_CalcPRParam( (address), sizeDef, mask ) | HW_C6_PR_ENABLE;
492 
493 	OS_SetProtectionRegionParam( regionNo, param );
494 }
495 
496 /*---------------------------------------------------------------------------*
497   Name:         OS_DumpProtectionRegion
498 
499   Description:  dump protection region list (for DEBUG)
500 
501   Arguments:    None
502 
503   Returns:      None
504  *---------------------------------------------------------------------------*/
505 #ifndef SDK_FINALROM
OS_DumpProtectionRegion(void)506 void OS_DumpProtectionRegion( void )
507 {
508 	int n;
509     OSIntrMode enable = OS_DisableInterrupts();
510 	u32 i_cache  = OS_GetICacheEnableFlagsForProtectionRegion();
511 	u32 d_cache  = OS_GetDCacheEnableFlagsForProtectionRegion();
512 	u32 i_permit = OS_GetIPermissionsForProtectionRegion();
513 	u32 d_permit = OS_GetDPermissionsForProtectionRegion();
514 
515 	OS_Printf("----Protection Region\nPR ICache DCache IPermit DPermit  Address    Size\n");
516 	for( n=0; n<OS_PROTECTION_REGION_NUM; n++ )
517 	{
518 		char* dpermit;
519 		char* ipermit;
520 
521 		switch( (i_permit >> (n<<2)) & HW_C5_PERMIT_MASK )
522 		{
523 			case HW_C5_PERMIT_NA: ipermit = "--"; break;
524 			case HW_C5_PERMIT_RW: ipermit = "RW"; break;
525 			case HW_C5_PERMIT_RO: ipermit = "R-"; break;
526 			default: ipermit = "??"; break;
527 		}
528 		switch( (d_permit >> (n<<2)) & HW_C5_PERMIT_MASK )
529 		{
530 			case HW_C5_PERMIT_NA: dpermit = "--"; break;
531 			case HW_C5_PERMIT_RW: dpermit = "RW"; break;
532 			case HW_C5_PERMIT_RO: dpermit = "R-"; break;
533 			default: dpermit = "??"; break;
534 		}
535 
536 		OS_Printf(" %d   %c      %c      %s      %s    0x%08x 0x%x\n",
537 				  n,
538 				  (i_cache & (1<<n))? 'O': '-',
539 				  (d_cache & (1<<n))? 'O': '-',
540 				  ipermit,
541 				  dpermit,
542 				  OS_GetProtectionRegionAddress(n),
543 				  0x1000 << OSi_PRDEF_TO_VAL(OS_GetProtectionRegionSize(n)), i_permit, d_permit );
544 	}
545 
546 	(void)OS_RestoreInterrupts(enable);
547 }
548 #endif // ifndef SDK_FINALROM
549 
550 #include <nitro/codereset.h>
551