1 /*-------------------------------------------------------------
3 aram.c -- ARAM subsystem
6 Michael Wiedenbauer (shagkur)
7 Dave Murphy (WinterMute)
9 This software is provided 'as-is', without any express or implied
10 warranty. In no event will the authors be held liable for any
11 damages arising from the use of this software.
13 Permission is granted to anyone to use this software for any
14 purpose, including commercial applications, and to alter it and
15 redistribute it freely, subject to the following restrictions:
17 1. The origin of this software must not be misrepresented; you
18 must not claim that you wrote the original software. If you use
19 this software in a product, an acknowledgment in the product
20 documentation would be appreciated but is not required.
22 2. Altered source versions must be plainly marked as such, and
23 must not be misrepresented as being the original software.
25 3. This notice may not be removed or altered from any source
28 -------------------------------------------------------------*/
35 #include "processor.h"
43 #define DSPCR_DSPRESET 0x0800 // Reset DSP
44 #define DSPCR_DSPDMA 0x0200 // ARAM dma in progress, if set
45 #define DSPCR_DSPINTMSK 0x0100 // * interrupt mask (RW)
46 #define DSPCR_DSPINT 0x0080 // * interrupt active (RWC)
47 #define DSPCR_ARINTMSK 0x0040
48 #define DSPCR_ARINT 0x0020
49 #define DSPCR_AIINTMSK 0x0010
50 #define DSPCR_AIINT 0x0008
51 #define DSPCR_HALT 0x0004 // halt DSP
52 #define DSPCR_PIINT 0x0002 // assert DSP PI interrupt
53 #define DSPCR_RES 0x0001 // reset DSP
55 #define AR_ARAMEXPANSION 2
57 #define _SHIFTL(v, s, w) \
58 ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s)))
59 #define _SHIFTR(v, s, w) \
60 ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1)))
62 static vu16
* const _dspReg
= (u16
*)0xCC005000;
64 static ARCallback __ARDmaCallback
= NULL
;
65 static u32 __ARInit_Flag
= 0;
66 static u32 __ARStackPointer
= 0;
67 static u32 __ARFreeBlocks
= 0;
68 static u32
*__ARBlockLen
= NULL
;
70 static u32 __ARInternalSize
= 0;
71 static u32 __ARExpansionSize
= 0;
72 static u32 __ARSize
= 0;
74 static void __ARHandler(u32 irq
,void *ctx
);
75 static void __ARCheckSize(void);
76 static void __ARClearArea(u32 aramaddr
,u32 len
);
78 ARCallback
AR_RegisterCallback(ARCallback callback
)
83 _CPU_ISR_Disable(level
);
84 old
= __ARDmaCallback
;
85 __ARDmaCallback
= callback
;
86 _CPU_ISR_Restore(level
);
93 _CPU_ISR_Disable(level
);
94 ret
= ((_dspReg
[5]&DSPCR_DSPDMA
)==DSPCR_DSPDMA
);
95 _CPU_ISR_Restore(level
);
99 u32
AR_Init(u32
*stack_idx_array
,u32 num_entries
)
105 u32 aram_base
= 0x4000;
107 if(__ARInit_Flag
) return aram_base
;
109 _CPU_ISR_Disable(level
);
111 __ARDmaCallback
= NULL
;
113 IRQ_Request(IRQ_DSP_ARAM
,__ARHandler
,NULL
);
114 __UnmaskIrq(IRQMASK(IRQ_DSP_ARAM
));
116 __ARStackPointer
= aram_base
;
117 __ARFreeBlocks
= num_entries
;
118 __ARBlockLen
= stack_idx_array
;
120 freq
= _dspReg
[13]&0xff;
121 if(((f32
)freq
)!=156.0 && ((f32
)freq
)!=176.0) {
122 printf("AR_Init(): Illegal SDRAM refresh value(%f)\n",(f32
)(freq
));
126 _dspReg
[13] = (_dspReg
[13]&~0xff)|(_dspReg
[13]&0xff);
131 _CPU_ISR_Restore(level
);
132 return __ARStackPointer
;
135 void AR_StartDMA(u32 dir
,u32 memaddr
,u32 aramaddr
,u32 len
)
139 _CPU_ISR_Disable(level
);
141 // set main memory address
142 _dspReg
[16] = (_dspReg
[16]&~0x03ff)|_SHIFTR(memaddr
,16,16);
143 _dspReg
[17] = (_dspReg
[17]&~0xffe0)|_SHIFTR(memaddr
, 0,16);
146 _dspReg
[18] = (_dspReg
[18]&~0x03ff)|_SHIFTR(aramaddr
,16,16);
147 _dspReg
[19] = (_dspReg
[19]&~0xffe0)|_SHIFTR(aramaddr
, 0,16);
150 _dspReg
[20] = (_dspReg
[20]&~0x8000)|_SHIFTL(dir
,15,1);
151 _dspReg
[20] = (_dspReg
[20]&~0x03ff)|_SHIFTR(len
,16,16);
152 _dspReg
[21] = (_dspReg
[21]&~0xffe0)|_SHIFTR(len
, 0,16);
154 _CPU_ISR_Restore(level
);
157 u32
AR_Alloc(u32 len
)
162 _CPU_ISR_Disable(level
);
163 curraddr
= __ARStackPointer
;
164 __ARStackPointer
+= len
;
165 *__ARBlockLen
++ = len
;
167 _CPU_ISR_Restore(level
);
172 u32
AR_Free(u32
*len
)
176 _CPU_ISR_Disable(level
);
178 if(len
) *len
= *__ARBlockLen
;
179 __ARStackPointer
-= *__ARBlockLen
;
181 _CPU_ISR_Restore(level
);
183 return __ARStackPointer
;
186 void AR_Clear(u32 flag
)
191 __ARClearArea(0,__ARInternalSize
);
195 __ARClearArea(0x4000,__ARInternalSize
-0x4000);
197 case AR_ARAMEXPANSION
:
198 if(__ARInternalSize
&& __ARExpansionSize
)
199 __ARClearArea(__ARInternalSize
,__ARExpansionSize
);
208 return __ARInit_Flag
;
221 u32
AR_GetBaseAddress()
226 u32
AR_GetInternalSize()
228 return __ARInternalSize
;
231 static __inline__
void __ARClearInterrupt()
235 cause
= _dspReg
[5]&~(DSPCR_DSPINT
|DSPCR_AIINT
);
237 printf("__ARClearInterrupt(0x%04x)\n",cause
);
239 _dspReg
[5] = (cause
|DSPCR_ARINT
);
242 static __inline__
void __ARWaitDma()
244 while(_dspReg
[5]&DSPCR_DSPDMA
);
247 static void __ARReadDMA(u32 memaddr
,u32 aramaddr
,u32 len
)
250 printf("__ARReadDMA(0x%08x,0x%08x,%d)\n",memaddr
,aramaddr
,len
);
252 // set main memory address
253 _dspReg
[16] = (_dspReg
[16]&~0x03ff)|_SHIFTR(memaddr
,16,16);
254 _dspReg
[17] = (_dspReg
[17]&~0xffe0)|_SHIFTR(memaddr
, 0,16);
257 _dspReg
[18] = (_dspReg
[18]&~0x03ff)|_SHIFTR(aramaddr
,16,16);
258 _dspReg
[19] = (_dspReg
[19]&~0xffe0)|_SHIFTR(aramaddr
, 0,16);
261 _dspReg
[20] = (_dspReg
[20]&~0x8000)|0x8000;
262 _dspReg
[20] = (_dspReg
[20]&~0x03ff)|_SHIFTR(len
,16,16);
263 _dspReg
[21] = (_dspReg
[21]&~0xffe0)|_SHIFTR(len
, 0,16);
266 __ARClearInterrupt();
270 static void __ARWriteDMA(u32 memaddr
,u32 aramaddr
,u32 len
)
273 printf("__ARWriteDMA(0x%08x,0x%08x,%d)\n",memaddr
,aramaddr
,len
);
275 // set main memory address
276 _dspReg
[16] = (_dspReg
[16]&~0x03ff)|_SHIFTR(memaddr
,16,16);
277 _dspReg
[17] = (_dspReg
[17]&~0xffe0)|_SHIFTR(memaddr
, 0,16);
280 _dspReg
[18] = (_dspReg
[18]&~0x03ff)|_SHIFTR(aramaddr
,16,16);
281 _dspReg
[19] = (_dspReg
[19]&~0xffe0)|_SHIFTR(aramaddr
, 0,16);
284 _dspReg
[20] = (_dspReg
[20]&~0x8000);
285 _dspReg
[20] = (_dspReg
[20]&~0x03ff)|_SHIFTR(len
,16,16);
286 _dspReg
[21] = (_dspReg
[21]&~0xffe0)|_SHIFTR(len
, 0,16);
289 __ARClearInterrupt();
292 static void __ARClearArea(u32 aramaddr
,u32 len
)
294 u32 currlen
,curraddr
,endaddr
;
295 static u8 zero_buffer
[2048] ATTRIBUTE_ALIGN(32);
297 while(!(_dspReg
[11]&0x0001));
299 memset(zero_buffer
,0,2048);
300 DCFlushRange(zero_buffer
,2048);
303 endaddr
= aramaddr
+len
;
306 while(curraddr
<endaddr
) {
307 if((endaddr
-curraddr
)<currlen
) currlen
= ((endaddr
-curraddr
)+31)&~31;
308 __ARWriteDMA((u32
)zero_buffer
,curraddr
,currlen
);
313 static void __ARCheckSize()
315 u32 i
,arsize
,arszflag
;
316 static u32 test_data
[8] ATTRIBUTE_ALIGN(32);
317 static u32 dummy_data
[8] ATTRIBUTE_ALIGN(32);
318 static u32 buffer
[8] ATTRIBUTE_ALIGN(32);
321 printf("__ARCheckSize()\n");
324 while(!(_dspReg
[11]&0x0001));
326 __ARSize
= __ARInternalSize
= arsize
= 0x1000000;
327 _dspReg
[9] = (_dspReg
[9]&~0x3f)|0x23;
330 test_data
[i
] = 0xBAD1BAD0;
331 dummy_data
[i
] = 0xDEADBEEF;
333 DCFlushRange(test_data
,32);
334 DCFlushRange(dummy_data
,32);
336 __ARExpansionSize
= 0;
337 __ARWriteDMA((u32
)test_data
,0x1000000,32);
338 __ARWriteDMA((u32
)test_data
,0x1200000,32);
339 __ARWriteDMA((u32
)test_data
,0x2000000,32);
340 __ARWriteDMA((u32
)test_data
,0x1000200,32);
341 __ARWriteDMA((u32
)test_data
,0x1400000,32);
344 DCFlushRange(buffer
,32);
346 __ARWriteDMA((u32
)dummy_data
,0x1000000,32);
348 DCInvalidateRange(buffer
,32);
349 __ARReadDMA((u32
)buffer
,0x1000000,32);
353 if(buffer
[0]==dummy_data
[0]) {
355 DCFlushRange(buffer
,32);
356 __ARReadDMA((u32
)buffer
,0x1200000,32);
358 if(buffer
[0]==dummy_data
[0]) {
359 __ARExpansionSize
= 0x200000;
361 goto end_check
; //not nice but fast
365 DCFlushRange(buffer
,32);
366 __ARReadDMA((u32
)buffer
,0x2000000,32);
368 if(buffer
[0]==dummy_data
[0]) {
369 __ARExpansionSize
= 0x400000;
372 goto end_check
; //not nice but fast
376 DCFlushRange(buffer
,32);
377 __ARReadDMA((u32
)buffer
,0x1400000,32);
379 if(buffer
[0]==dummy_data
[0]) {
380 __ARExpansionSize
= 0x1000000;
384 __ARExpansionSize
= 0x2000000;
389 _dspReg
[9] = (_dspReg
[9]&~0x3f)|arszflag
;
393 printf("__ARCheckSize(%d)\n",arsize
);
395 *(u32
*)0x800000d0 = arsize
;
399 static void __ARHandler(u32 irq
,void *ctx
)
402 printf("__ARHandler()\n");
404 __ARClearInterrupt();