1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - MB - libraries
3   File:     mb_cache.c
4 
5   Copyright 2007-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.h>
19 
20 #include "mb_cache.h"
21 
22 
23 /*---------------------------------------------------------------------------*
24   Name:         MBi_InitCache
25 
26   Description:  Initializes a cache list.
27 
28 
29   Arguments:    pl:         Cache list.
30 
31   Returns:      None.
32  *---------------------------------------------------------------------------*/
MBi_InitCache(MBiCacheList * pl)33 void MBi_InitCache(MBiCacheList * pl)
34 {
35     MI_CpuClear8(pl, sizeof(*pl));
36 }
37 
38 /*---------------------------------------------------------------------------*
39   Name:         MBi_AttachCacheBuffer
40 
41   Description:  Assigns a buffer to a cache list.
42 
43   Arguments:    pl:         Cache list.
44                 ptr:        Buffer to assign.
45                 src:        Source address of ptr.
46                 len:        Byte size of ptr.
47                 state:      Initial state to specify.
48                            (MB_CACHE_STATE_READY or MB_CACHE_STATE_LOCKED)
49 
50   Returns:      None.
51  *---------------------------------------------------------------------------*/
MBi_AttachCacheBuffer(MBiCacheList * pl,u32 src,u32 len,void * ptr,u32 state)52 void MBi_AttachCacheBuffer(MBiCacheList * pl, u32 src, u32 len, void *ptr, u32 state)
53 {
54     OSIntrMode bak_cpsr = OS_DisableInterrupts();
55     {
56         /* Search for an unregistered page. */
57         MBiCacheInfo *pi = pl->list;
58         for (;; ++pi)
59         {
60             if (pi >= &pl->list[MB_CACHE_INFO_MAX])
61             {
62                 OS_TPanic("MBi_AttachCacheBuffer() failed! (over maximum count)");
63             }
64             if (pi->state == MB_CACHE_STATE_EMPTY)
65             {
66                 pi->src = src;
67                 pi->len = len;
68                 pi->ptr = (u8 *)ptr;
69                 pi->state = state;
70                 break;
71             }
72         }
73     }
74     (void)OS_RestoreInterrupts(bak_cpsr);
75 }
76 
77 /*---------------------------------------------------------------------------*
78   Name:         MBi_ReadFromCache
79 
80   Description:  Reads the content of the specified address from the cache.
81 
82   Arguments:    pl:         Cache list.
83                 src:        Source address of the read.
84                 len:        Read size (BYTE)
85                 dst:        Destination address of the read.
86 
87   Returns:      TRUE if the cache hits and a read is performed; FALSE otherwise.
88  *---------------------------------------------------------------------------*/
MBi_ReadFromCache(MBiCacheList * pl,u32 src,void * dst,u32 len)89 BOOL MBi_ReadFromCache(MBiCacheList * pl, u32 src, void *dst, u32 len)
90 {
91     BOOL    ret = FALSE;
92     OSIntrMode bak_cpsr = OS_DisableInterrupts();
93     {
94         /* Only search for usable pages */
95         const MBiCacheInfo *pi = pl->list;
96         for (; pi < &pl->list[MB_CACHE_INFO_MAX]; ++pi)
97         {
98             if (pi->state >= MB_CACHE_STATE_READY)
99             {
100                 /* Determine if the target address is within range. */
101                 const int ofs = (int)(src - pi->src);
102                 if ((ofs >= 0) && (ofs + len <= pi->len))
103                 {
104                     /* Read because the cache was hit. */
105                     MI_CpuCopy8(pi->ptr + ofs, dst, len);
106                     pl->lifetime = 0;
107                     ret = TRUE;
108                     break;
109                 }
110             }
111         }
112     }
113     (void)OS_RestoreInterrupts(bak_cpsr);
114     return ret;
115 }
116 
117 /*---------------------------------------------------------------------------*
118   Name:         MBi_TryLoadCache
119 
120   Description:  Loads the content of the specified address to the cache.
121                 The READY page cache with the lowest address is discarded.
122 
123   Arguments:    pl:         Cache list.
124                 src:        Reload source address.
125                 len:        Reload size (in bytes).
126 
127   Returns:      TRUE if the reload could be started and FALSE otherwise.
128                 (When there is a single reload processing engine in the system, this function should return FALSE if processing was not finished previously.)
129 
130  *---------------------------------------------------------------------------*/
MBi_TryLoadCache(MBiCacheList * pl,u32 src,u32 len)131 BOOL MBi_TryLoadCache(MBiCacheList * pl, u32 src, u32 len)
132 {
133     BOOL    ret = FALSE;
134     OSIntrMode bak_cpsr = OS_DisableInterrupts();
135     {
136         /* Only search for pages that can be reloaded. */
137         MBiCacheInfo *trg = NULL;
138         MBiCacheInfo *pi = pl->list;
139         for (; pi < &pl->list[MB_CACHE_INFO_MAX]; ++pi)
140         {
141             if (pi->state == MB_CACHE_STATE_READY)
142             {
143                 /* Leave it as candidate if it is the smallest address. */
144                 if (!trg || (trg->src > pi->src))
145                 {
146                     trg = pi;
147                 }
148             }
149         }
150         /* Request processing if the reload page target can be found. */
151         if (trg)
152         {
153             /* The processing request to the task thread is described here. */
154             (void)src;
155             (void)len;
156         }
157         OS_TPanic("reload-system is not yet!");
158     }
159     (void)OS_RestoreInterrupts(bak_cpsr);
160     return ret;
161 }
162