1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - OS - libraries
3 File: os_vramExclusive.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-17#$
14 $Rev: 8556 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 #include <nitro/os/ARM9/vramExclusive.h>
19 #include <nitro/os/common/interrupt.h>
20 #include <nitro/os/common/system.h>
21
22
23 /*---------------------------------------------------------------------------*
24 Internal Variable Definitions
25 *---------------------------------------------------------------------------*/
26 static u32 OSi_vramExclusive;
27 static u16 OSi_vramLockId[OS_VRAM_BANK_KINDS];
28
29
30 /*===========================================================================*/
31
32 /*---------------------------------------------------------------------------*
33 Name: OsCountZeroBits
34
35 Description: Counts and returns the number of sequential zeroes in the 32-bit value starting from the top.
36
37 Arguments: bitmap: The value to evaluate
38
39 Returns: u32: The number of 0 bits.
40 0x80000000 = 0; 0x00000000 = 32.
41 *---------------------------------------------------------------------------*/
42 #include <nitro/code32.h>
43 static asm u32
OsCountZeroBits(u32 bitmap)44 OsCountZeroBits( u32 bitmap )
45 {
46 clz r0, r0
47 bx lr
48 }
49 #include <nitro/codereset.h>
50
51
52 /*---------------------------------------------------------------------------*
53 Name: OSi_InitVramExclusive
54
55 Description: Initializes VRAM exclusion processes.
56
57 Arguments: None.
58
59 Returns: None.
60 *---------------------------------------------------------------------------*/
61 void
OSi_InitVramExclusive(void)62 OSi_InitVramExclusive( void )
63 {
64 s32 i;
65
66 OSi_vramExclusive = 0x0000;
67 for( i = 0 ; i < OS_VRAM_BANK_KINDS ; i ++ )
68 {
69 OSi_vramLockId[ i ] = 0;
70 }
71 }
72
73 /*---------------------------------------------------------------------------*
74 Name: OSi_TryLockVram
75
76 Description: Tries the VRAM exclusive lock.
77
78 Arguments: bank: ID bitmap of VRAM on which exclusive lock is being tried
79 lockId: Any ID that can be used as key for locking
80
81 Returns: BOOL: Returns TRUE if the lock is successful.
82 *---------------------------------------------------------------------------*/
OSi_TryLockVram(u16 bank,u16 lockId)83 BOOL OSi_TryLockVram(u16 bank, u16 lockId)
84 {
85 u32 workMap;
86 s32 zeroBits;
87 OSIntrMode enabled = OS_DisableInterrupts();
88
89 // Check whether exclusive lock already set with different ID
90 workMap = (u32)(bank & OSi_vramExclusive);
91 while (TRUE)
92 {
93 zeroBits = (s32)(31 - OsCountZeroBits(workMap));
94 if (zeroBits < 0)
95 {
96 break;
97 }
98 workMap &= ~(0x00000001 << zeroBits);
99 if (OSi_vramLockId[zeroBits] != lockId)
100 {
101 (void)OS_RestoreInterrupts(enabled);
102 return FALSE;
103 }
104 }
105
106 // Lock all VRAM with specified ID
107 workMap = (u32)(bank & OS_VRAM_BANK_ID_ALL);
108 while (TRUE)
109 {
110 zeroBits = (s32)(31 - OsCountZeroBits(workMap));
111 if (zeroBits < 0)
112 {
113 break;
114 }
115 workMap &= ~(0x00000001 << zeroBits);
116 OSi_vramLockId[zeroBits] = lockId;
117 OSi_vramExclusive |= (0x00000001 << zeroBits);
118 }
119
120 (void)OS_RestoreInterrupts(enabled);
121 return TRUE;
122 }
123
124 /*---------------------------------------------------------------------------*
125 Name: OSi_UnlockVram
126
127 Description: Releases VRAM exclusive lock.
128
129 Arguments: bank: ID bitmap of VRAM on which exclusive lock is being released
130 lockId: Arbitrary ID specified when locked
131
132 Returns: None.
133 *---------------------------------------------------------------------------*/
OSi_UnlockVram(u16 bank,u16 lockId)134 void OSi_UnlockVram(u16 bank, u16 lockId)
135 {
136 u32 workMap;
137 s32 zeroBits;
138 OSIntrMode enabled = OS_DisableInterrupts();
139
140 workMap = (u32)(bank & OSi_vramExclusive & OS_VRAM_BANK_ID_ALL);
141 while (TRUE)
142 {
143 zeroBits = (s32)(31 - OsCountZeroBits((u32)workMap));
144 if (zeroBits < 0)
145 {
146 break;
147 }
148 workMap &= ~(0x00000001 << zeroBits);
149 if (OSi_vramLockId[zeroBits] == lockId)
150 {
151 OSi_vramLockId[zeroBits] = 0;
152 OSi_vramExclusive &= ~(0x00000001 << zeroBits);
153 }
154 }
155
156 (void)OS_RestoreInterrupts(enabled);
157 }
158
159 /*---------------------------------------------------------------------------*
160 End of file
161 *---------------------------------------------------------------------------*/
162