1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - CTRDG - libraries - ARM9
3   File:     ctrdg_flash_common.c
4 
5   Copyright 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:: 2007-11-15#$
14   $Rev: 2414 $
15   $Author: hatamoto_minoru $
16  *---------------------------------------------------------------------------*/
17 #include <nitro.h>
18 
19 // Function's prototype declaration-------------
20 
21 u32     CTRDGi_ReadAgbFlashCore(CTRDGTaskInfo * arg);
22 u32     CTRDGi_VerifyAgbFlashCore(CTRDGTaskInfo * arg);
23 u32     CTRDGi_WriteAndVerifyAgbFlashSectorCore(CTRDGTaskInfo * arg);
24 u32     CTRDGi_WriteAndVerifyAgbFlashSectorCore(CTRDGTaskInfo * arg);
25 
26 u8      CTRDGi_ReadSrFunc(u8 *adr);    //The polling function is referenced separately from 512K and 1M
27 
28 // Global variables-----------------------------
29 
30 u16     ctrdg_flash_remainder;
31 
32 const CTRDGFlashType *AgbFlash;
33 u16     (*CTRDGi_WriteAgbFlashSector) (u16 secNo, u8 *src);
34 u16     (*CTRDGi_EraseAgbFlashChip) (void);
35 u16     (*CTRDGi_EraseAgbFlashSector) (u16 sec_num);
36 void    (*CTRDGi_WriteAgbFlashSectorAsync) (u16 secNo, u8 *src, CTRDG_TASK_FUNC callback);
37 void    (*CTRDGi_EraseAgbFlashChipAsync) (CTRDG_TASK_FUNC callback);
38 void    (*CTRDGi_EraseAgbFlashSectorAsync) (u16 sec_num, CTRDG_TASK_FUNC callback);
39 u16     (*CTRDGi_PollingSR) (u16 phase, u8 *adr, u16 lastData);
40 const u16 (*ctrdgi_fl_maxtime);
41 
42 OSTick  start_tick, timeout_tick;
43 
44 /*Exclusive control*/
45 u16     ctrdgi_flash_lock_id;
46 BOOL    ctrdgi_backup_irq;
47 
48 vu16    ctrdgi_timeoutFlag;            //The polling function is referenced separately from 512K and 1M
49 
50 
51 /*******************************************************
52 
53     Function's description
54 
55 ********************************************************/
CTRDGi_SetFlashBankMx(u16 bank)56 void CTRDGi_SetFlashBankMx(u16 bank)
57 {
58     *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
59     *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
60     *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xb0;
61     *(vu8 *)CTRDG_AGB_FLASH_ADR = (u8)bank;
62 }
63 
64 // Flash Identify functions---------------------
CTRDGi_ReadFlashID(void)65 u16 CTRDGi_ReadFlashID(void)
66 {
67     u16     flashID;
68 
69     // Read flashID
70     ctrdgi_backup_irq = OS_DisableIrq();
71 
72     *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
73     *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
74     *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0x90;
75 
76     (void)OS_RestoreIrq(ctrdgi_backup_irq);
77     /*Wait 20 ms */
78     StartFlashTimer(0);
79     while (!ctrdgi_timeoutFlag)
80     {
81         CheckFlashTimer();
82     };
83 
84     //Manufacturer ID
85     flashID = (u16)(CTRDGi_ReadSrFunc((u8 *)CTRDG_BACKUP_DEVICE_ID_ADR) << 8);
86     flashID |= CTRDGi_ReadSrFunc((u8 *)CTRDG_BACKUP_VENDER_ID_ADR);
87 
88     // Exit readID-mode(ATMEL)
89     ctrdgi_backup_irq = OS_DisableIrq();
90 
91     *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xaa;
92     *(vu8 *)CTRDG_BACKUP_COM_ADR2 = 0x55;
93     *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xf0;
94 
95     // Reset
96     *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xf0;
97 
98     (void)OS_RestoreIrq(ctrdgi_backup_irq);
99 
100     //Wait 20ms
101     StartFlashTimer(0);
102     while (!ctrdgi_timeoutFlag)
103     {
104         CheckFlashTimer();
105     };
106 
107     return flashID;
108 }
109 
110 
StartFlashTimer(u16 phase)111 void StartFlashTimer(u16 phase)
112 {
113     ctrdgi_timeoutFlag = FALSE;
114 
115     timeout_tick = (u64)*(ctrdgi_fl_maxtime + phase);
116     start_tick = OS_GetTick();
117 }
118 
CheckFlashTimer(void)119 void CheckFlashTimer(void)
120 {
121     OSTick  current_tick, process_tick, process_time;
122 
123     current_tick = OS_GetTick();
124     process_tick = current_tick - start_tick;
125     process_time = OS_TicksToMilliSeconds(process_tick);
126     if (timeout_tick <= process_time)
127         ctrdgi_timeoutFlag = TRUE;
128 }
129 
130 // Flash access functions-------------------------------
131 
132 //* Use function pointers corresponding to each routine.
133 
134 // Data Polling ----------------------------------------
CTRDGi_ReadSrFunc(u8 * adr)135 u8 CTRDGi_ReadSrFunc(u8 *adr)
136 {
137     return *adr;
138 }
139 
140 
141 //u8 pollflag;
CTRDGi_PollingSR512kCOMMON(u16 phase,u8 * adr,u16 lastData)142 u16 CTRDGi_PollingSR512kCOMMON(u16 phase, u8 *adr, u16 lastData)
143 {
144     u16     poll;
145     u16     result;
146 
147 //++++++++++++++++++++++++ For debug
148 //  pollflag=1;
149 //++++++++++++++++++++++++
150     result = CTRDG_BACKUP_RESULT_OK;
151     StartFlashTimer(phase);
152     while (1)
153     {
154         poll = CTRDGi_ReadSrFunc(adr);
155         if (poll == lastData)
156         {
157             break;
158         }
159         if (ctrdgi_timeoutFlag)
160         {
161             if (CTRDGi_ReadSrFunc(adr) == lastData)
162             {
163                 break;
164             }
165             else
166             {
167                 if (AgbFlash->makerID == 0xc2)
168                 {                      // Megachips makerID
169                     *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xf0;       // Command reset
170                 }
171                 result = (u16)(CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_RESULT_TIMEOUT | phase);
172                 break;
173             }
174         }
175     }
176     if (!CTRDG_IsExisting())
177         result = CTRDG_BACKUP_RESULT_PULLEDOUT;
178 //++++++++++++++++++++++++ For debug
179 //  pollflag=0;
180 //++++++++++++++++++++++++ For debug
181     return result;
182 }
183 
184 
185 //u8 pollflag;
CTRDGi_PollingSR1MCOMMON(u16 phase,u8 * adr,u16 lastData)186 u16 CTRDGi_PollingSR1MCOMMON(u16 phase, u8 *adr, u16 lastData)
187 {
188     u16     poll;
189     u16     result;
190 
191 //++++++++++++++++++++++++ For debug
192 //  pollflag=1;
193 //++++++++++++++++++++++++
194     result = CTRDG_BACKUP_RESULT_OK;
195     StartFlashTimer(phase);
196     while (1)
197     {
198         CheckFlashTimer();
199         poll = CTRDGi_ReadSrFunc(adr);
200 
201         if (poll == lastData)
202         {
203             break;
204         }
205         else
206         {
207             if ((poll & 0x20) != 0)
208             {                          //Q5(TimeOutFlag)
209                 if (CTRDGi_ReadSrFunc(adr) == lastData)
210                 {
211                     break;
212                 }
213                 else
214                 {
215                     *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xf0;       // Command reset
216                     result =
217                         (u16)(CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_RESULT_Q5TIMEOUT | phase);
218                     break;
219                 }
220             }
221         }
222         if (ctrdgi_timeoutFlag)
223         {
224             if (CTRDGi_ReadSrFunc(adr) == lastData)
225             {
226                 break;
227             }
228             else
229             {
230                 *(vu8 *)CTRDG_BACKUP_COM_ADR1 = 0xf0;   // Command reset
231                 result = (u16)(CTRDG_BACKUP_RESULT_ERROR | CTRDG_BACKUP_RESULT_TIMEOUT | phase);
232                 break;
233             }
234         }
235     }
236     if (!CTRDG_IsExisting())
237         result = CTRDG_BACKUP_RESULT_PULLEDOUT;
238 //++++++++++++++++++++++++ For debug
239 //  pollflag=0;
240 //++++++++++++++++++++++++ For debug
241     return result;
242 }
243 
244 
245 /*------------------------------------------------------------------*/
246 /*          Data readout                                          */
247 /*------------------------------------------------------------------*/
CTRDGi_ReadAgbFlashCore(CTRDGTaskInfo * arg)248 u32 CTRDGi_ReadAgbFlashCore(CTRDGTaskInfo * arg)
249 {
250     u8     *src;
251     MICartridgeRamCycle ram_cycle;
252     CTRDGTaskInfo p = *arg;
253     u16     sec_num = p.sec_num;
254     u32     offset = p.offset;
255     u8     *dst = p.dst;
256     u32     size = p.size;
257 
258     /*Exclusive control (lock) */
259     (void)OS_LockCartridge(ctrdgi_flash_lock_id);
260     /*Access cycle settings */
261     ram_cycle = MI_GetCartridgeRamCycle();
262     MI_SetCartridgeRamCycle(MI_CTRDG_RAMCYCLE_18);
263 
264     // Set bank if 1MbitFlash
265     if (AgbFlash->romSize == 0x00020000)
266     {
267         CTRDGi_SetFlashBankMx((u16)(sec_num >> 4));
268         sec_num &= 0x0f;
269     }
270 
271     src = (u8 *)(CTRDG_AGB_FLASH_ADR + (sec_num << AgbFlash->sector.shift) + offset);
272 
273     while (size--)
274         *dst++ = *src++;
275 
276     /*Access cycle settings */
277     MI_SetCartridgeRamCycle(ram_cycle);
278     /*Exclusive control (unlock) */
279     (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
280 
281     return 0;
282 }
283 
CTRDGi_VerifyFlashSectorCore(u8 * src,u8 * tgt,u32 size)284 static u32 CTRDGi_VerifyFlashSectorCore(u8 *src, u8 *tgt, u32 size)
285 {
286     while (size--)
287     {
288         if (*tgt++ != *src++)
289             return (u32)tgt - 1;
290     }
291     return 0;
292 }
293 
294 /*------------------------------------------------------------------*/
295 /*          Verfiy data by the byte                              */
296 /*------------------------------------------------------------------*/
CTRDGi_VerifyAgbFlashCore(CTRDGTaskInfo * arg)297 u32 CTRDGi_VerifyAgbFlashCore(CTRDGTaskInfo * arg)
298 {
299     u8     *tgt;
300     u32     result;
301     MICartridgeRamCycle ram_cycle;
302     CTRDGTaskInfo p = *arg;
303     u16     sec_num = p.sec_num;
304     u8     *src = p.data;
305     u32     size = p.size;
306 
307     /*Exclusive control (lock) */
308     (void)OS_LockCartridge(ctrdgi_flash_lock_id);
309     /*Access cycle settings */
310     ram_cycle = MI_GetCartridgeRamCycle();
311     MI_SetCartridgeRamCycle(MI_CTRDG_RAMCYCLE_18);
312 
313     // Set bank if 1MbitFlash
314     if (AgbFlash->romSize == 0x00020000)
315     {
316         CTRDGi_SetFlashBankMx((u16)(sec_num >> 4));
317         sec_num &= 0x0f;
318     }
319 
320     tgt = (u8 *)(CTRDG_AGB_FLASH_ADR + (sec_num << AgbFlash->sector.shift));
321     result = CTRDGi_VerifyFlashSectorCore(src, tgt, size);
322 
323     /*Access cycle settings */
324     MI_SetCartridgeRamCycle(ram_cycle);
325     /*Exclusive control (unlock) */
326     (void)OS_UnlockCartridge(ctrdgi_flash_lock_id);
327     return result;
328 }
329 
330 
331 /*------------------------------------------------------------------*/
332 /*          Write data by the sector; verify by the byte          */
333 /*------------------------------------------------------------------*/
CTRDGi_WriteAndVerifyAgbFlashSectorCore(CTRDGTaskInfo * arg)334 u32 CTRDGi_WriteAndVerifyAgbFlashSectorCore(CTRDGTaskInfo * arg)
335 {
336     u16     retry;
337     u32     result;
338     CTRDGTaskInfo p = *arg;
339     u16     sec_num = p.sec_num;
340     u32     offset = p.offset;
341     u8     *src = p.data;
342     u32     verifysize = p.size;
343 
344     retry = 0;
345     while (retry < CTRDG_AGB_FLASH_RETRY_MAX)
346     {
347         result = (u32)CTRDG_WriteAgbFlashSector(sec_num, src);
348         if (result == 0)
349         {
350             result = CTRDG_VerifyAgbFlash(sec_num, src, verifysize);
351             if (result == 0)
352                 break;
353         }
354         retry++;
355     }
356     return result;
357 }
358 
CTRDG_ReadAgbFlash(u16 sec_num,u32 offset,u8 * dst,u32 size)359 void CTRDG_ReadAgbFlash(u16 sec_num, u32 offset, u8 *dst, u32 size)
360 {
361     CTRDGTaskInfo p;
362     p.sec_num = sec_num;
363     p.offset = offset;
364     p.dst = dst;
365     p.size = size;
366 
367     (void)CTRDGi_ReadAgbFlashCore(&p);
368 }
369 
CTRDG_EraseAgbFlashChip(void)370 u16 CTRDG_EraseAgbFlashChip(void)
371 {
372     u16     result = (*CTRDGi_EraseAgbFlashChip) ();
373 
374     return result;
375 }
376 
CTRDG_EraseAgbFlashSector(u16 secNo)377 u16 CTRDG_EraseAgbFlashSector(u16 secNo)
378 {
379     u16     result = (*CTRDGi_EraseAgbFlashSector) (secNo);
380 
381     return result;
382 }
383 
CTRDG_WriteAgbFlashSector(u16 secNo,u8 * src)384 u16 CTRDG_WriteAgbFlashSector(u16 secNo, u8 *src)
385 {
386     u16     result = (*CTRDGi_WriteAgbFlashSector) (secNo, src);
387 
388     return result;
389 }
390 
CTRDG_VerifyAgbFlash(u16 sec_num,u8 * src,u32 size)391 u32 CTRDG_VerifyAgbFlash(u16 sec_num, u8 *src, u32 size)
392 {
393     u32     result;
394     CTRDGTaskInfo p;
395     p.sec_num = sec_num;
396     p.data = src;
397     p.size = size;
398     result = CTRDGi_VerifyAgbFlashCore(&p);
399 
400     return result;
401 }
402 
CTRDG_WriteAndVerifyAgbFlash(u16 sec_num,u8 * src,u32 verifysize)403 u32 CTRDG_WriteAndVerifyAgbFlash(u16 sec_num, u8 *src, u32 verifysize)
404 {
405     u32     result;
406     CTRDGTaskInfo p;
407     p.sec_num = sec_num;
408     p.data = src;
409     p.size = verifysize;
410     result = CTRDGi_WriteAndVerifyAgbFlashSectorCore(&p);
411 
412     return result;
413 }
414 
CTRDG_ReadAgbFlashAsync(u16 sec_num,u32 offset,u8 * dst,u32 size,CTRDG_TASK_FUNC callback)415 void CTRDG_ReadAgbFlashAsync(u16 sec_num, u32 offset, u8 *dst, u32 size, CTRDG_TASK_FUNC callback)
416 {
417     CTRDGTaskInfo p;
418     p.sec_num = sec_num;
419     p.offset = offset;
420     p.dst = dst;
421     p.size = size;
422 
423     CTRDGi_SetTask(&p, CTRDGi_ReadAgbFlashCore, callback);
424 }
425 
CTRDG_EraseAgbFlashChipAsync(CTRDG_TASK_FUNC callback)426 void CTRDG_EraseAgbFlashChipAsync(CTRDG_TASK_FUNC callback)
427 {
428     (*CTRDGi_EraseAgbFlashChipAsync) (callback);
429 }
430 
CTRDG_EraseAgbFlashSectorAsync(u16 secNo,CTRDG_TASK_FUNC callback)431 void CTRDG_EraseAgbFlashSectorAsync(u16 secNo, CTRDG_TASK_FUNC callback)
432 {
433     (*CTRDGi_EraseAgbFlashSectorAsync) (secNo, callback);
434 }
435 
CTRDG_WriteAgbFlashSectorAsync(u16 secNo,u8 * src,CTRDG_TASK_FUNC callback)436 void CTRDG_WriteAgbFlashSectorAsync(u16 secNo, u8 *src, CTRDG_TASK_FUNC callback)
437 {
438     (*CTRDGi_WriteAgbFlashSectorAsync) (secNo, src, callback);
439 }
440 
CTRDG_VerifyAgbFlashAsync(u16 sec_num,u8 * src,u32 size,CTRDG_TASK_FUNC callback)441 void CTRDG_VerifyAgbFlashAsync(u16 sec_num, u8 *src, u32 size, CTRDG_TASK_FUNC callback)
442 {
443     CTRDGTaskInfo p;
444     p.sec_num = sec_num;
445     p.data = src;
446     p.size = size;
447     CTRDGi_SetTask(&p, CTRDGi_VerifyAgbFlashCore, callback);
448 }
449 
CTRDG_WriteAndVerifyAgbFlashAsync(u16 sec_num,u8 * src,u32 verifysize,CTRDG_TASK_FUNC callback)450 void CTRDG_WriteAndVerifyAgbFlashAsync(u16 sec_num, u8 *src, u32 verifysize,
451                                        CTRDG_TASK_FUNC callback)
452 {
453     CTRDGTaskInfo p;
454     p.sec_num = sec_num;
455     p.data = src;
456     p.size = verifysize;
457     CTRDGi_SetTask(&p, CTRDGi_WriteAndVerifyAgbFlashSectorCore, callback);
458 }
459