1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - include - dsp
3   File:     dsp_process.h
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:: 2008-10-21#$
14   $Rev: 9018 $
15   $Author: kitase_hirotake $
16  *---------------------------------------------------------------------------*/
17 #ifndef TWL_DSP_PROCESS_H_
18 #define TWL_DSP_PROCESS_H_
19 
20 
21 /*---------------------------------------------------------------------------*
22  * Only TWL systems can use this module.
23  *---------------------------------------------------------------------------*/
24 #ifdef SDK_TWL
25 
26 
27 #include <twl/dsp.h>
28 #include <twl/dsp/common/byteaccess.h>
29 
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 
36 /*---------------------------------------------------------------------------*/
37 /* Constants */
38 
39 // WRAM-B/C slot size.
40 #define DSP_WRAM_SLOT_SIZE (32 * 1024)
41 
42 // Bit definition macros used for hook registration.
43 #define DSP_HOOK_SEMAPHORE_(id) (1 << (id))
44 #define DSP_HOOK_REPLY_(id)     (1 << (16 + (id)))
45 #define DSP_HOOK_MAX            (16 + 3)
46 
47 // Flag that determines whether to use SDK-specific synchronous processing at startup.
48 #define DSP_PROCESS_FLAG_USING_OS   0x0001
49 
50 /*---------------------------------------------------------------------------*/
51 /* Declarations */
52 
53 // Hook function prototype for DSP interrupts
54 typedef void (*DSPHookFunction)(void *userdata);
55 
56 // This structure holds process memory information.
57 // DSP processes are loaded with the following procedure.
58 //
59 //       (1) List the section tables for a process image and calculate the segment placement state (segment map) to utilize.
60 //
61 //       (2) Select the actual DSP segment from one of the WRAM-B/C slots that the DSP is allowed to use and then fix the table (slot map) that maps with each segment.
62 //
63 //   (3) Re-list the process image's section tables and then actually place the process image in WRAM-B/C.
64 //
65 typedef struct DSPProcessContext
66 {
67     // Unidirectional list and process name to support multi-processes.
68     struct DSPProcessContext   *next;
69     char                        name[15 + 1];
70     // The file handle that stores the process image, and usable WRAM.
71     // This is used temporarily only during load processing.
72     FSFile                     *image;
73     u16                         slotB;
74     u16                         slotC;
75     int                         flags;
76     // The segment map held by the process on the DSP.
77     // This is calculated by the DSP_MapProcessSegment function.
78     int                         segmentCode;
79     int                         segmentData;
80     // The slot map assigned to each segment.
81     // The mapper is placed by the DSP_StartupProcess function.
82     int                         slotOfSegmentCode[8];
83     int                         slotOfSegmentData[8];
84     // Hook functions registered for the various factors that lead to DSP interrupts.
85     // The DSP_SetProcessHook function registers these separately for each factor.
86     int                         hookFactors;
87     DSPHookFunction             hookFunction[DSP_HOOK_MAX];
88     void                       *hookUserdata[DSP_HOOK_MAX];
89     int                         hookGroup[DSP_HOOK_MAX];
90 }
91 DSPProcessContext;
92 
93 
94 /*---------------------------------------------------------------------------*/
95 /* Functions */
96 
97 /*---------------------------------------------------------------------------*
98   Name:         DSP_StopDSPComponent
99 
100   Description:  Prepares to shut down the DSP.
101                 Currently, this only stops DMAs for the DSP.
102 
103   Arguments:    None.
104 
105   Returns:      None.
106  *---------------------------------------------------------------------------*/
107 void DSP_StopDSPComponent(void);
108 
109 /*---------------------------------------------------------------------------*
110   Name:         DSP_InitProcessContext
111 
112   Description:  Initializes a process information structure.
113 
114   Arguments:    context: DSPProcessContext structure
115                 name: The process name or NULL.
116 
117   Returns:      None.
118  *---------------------------------------------------------------------------*/
119 void DSP_InitProcessContext(DSPProcessContext *context, const char *name);
120 
121 /*---------------------------------------------------------------------------*
122   Name:         DSP_ExecuteProcess
123 
124   Description:  Loads and starts a DSP process image.
125 
126   Arguments:    context: A DSPProcessContext structure to use for state management.
127                           This will be accessed by the system until the process is destroyed.
128                 image: File handle that points to a process image.
129                           This will only be accessed within this function.
130                 slotB: WRAM-B that was allowed to be used for code memory.
131                 slotC: WRAM-C that was allowed to be used for data memory.
132 
133   Returns:      None.
134  *---------------------------------------------------------------------------*/
135 BOOL DSP_ExecuteProcess(DSPProcessContext *context, FSFile *image, int slotB, int slotC);
136 
137 /*---------------------------------------------------------------------------*
138   Name:         DSP_QuitProcess
139 
140   Description:  Shuts down a DSP process and releases memory.
141 
142   Arguments:    context: A DSPProcessContext structure to use for state management.
143 
144   Returns:      None.
145  *---------------------------------------------------------------------------*/
146 void DSP_QuitProcess(DSPProcessContext *context);
147 
148 /*---------------------------------------------------------------------------*
149   Name:         DSP_FindProcess
150 
151   Description:  Finds a running process.
152 
153   Arguments:    name: The process name.
154                        If NULL is specified, this will find the last process that was registered.
155 
156   Returns:      A DSPProcessContext structure that matches the specified name.
157  *---------------------------------------------------------------------------*/
158 DSPProcessContext* DSP_FindProcess(const char *name);
159 
160 /*---------------------------------------------------------------------------*
161   Name:         DSP_GetProcessSlotFromSegment
162 
163   Description:  Gets the WRAM slot number that corresponds to the specified segment number.
164 
165   Arguments:    context: DSPProcessContext structure
166                 wram: MI_WRAM_B/MI_WRAM_C.
167                 segment: Segment number.
168 
169   Returns:      The WRAM slot number that corresponds to the specified segment number.
170  *---------------------------------------------------------------------------*/
DSP_GetProcessSlotFromSegment(const DSPProcessContext * context,MIWramPos wram,int segment)171 SDK_INLINE int DSP_GetProcessSlotFromSegment(const DSPProcessContext *context, MIWramPos wram, int segment)
172 {
173     return (wram == MI_WRAM_B) ? context->slotOfSegmentCode[segment] : context->slotOfSegmentData[segment];
174 }
175 
176 /*---------------------------------------------------------------------------*
177   Name:         DSP_ConvertProcessAddressFromDSP
178 
179   Description:  Converts an address in DSP memory space to a WRAM address.
180 
181   Arguments:    context: DSPProcessContext structure
182                 wram: MI_WRAM_B/MI_WRAM_C.
183                 address: An address in DSP memory space. (in units of words in DSP memory space)
184 
185   Returns:      The WRAM address that corresponds to the specified DSP address.
186  *---------------------------------------------------------------------------*/
DSP_ConvertProcessAddressFromDSP(const DSPProcessContext * context,MIWramPos wram,int address)187 SDK_INLINE void* DSP_ConvertProcessAddressFromDSP(const DSPProcessContext *context, MIWramPos wram, int address)
188 {
189     int     segment = (address / (DSP_WRAM_SLOT_SIZE/2));
190     int     mod = (address - segment * (DSP_WRAM_SLOT_SIZE/2));
191     int     slot = DSP_GetProcessSlotFromSegment(context, wram, segment);
192     SDK_ASSERT((slot >= 0) && (slot < MI_WRAM_B_MAX_NUM));
193     return (u8*)MI_GetWramMapStart(wram) + slot * DSP_WRAM_SLOT_SIZE + mod * 2;
194 }
195 
196 /*---------------------------------------------------------------------------*
197   Name:         DSP_AttachProcessMemory
198 
199   Description:  Assigns contiguous memory space to unused process regions.
200 
201   Arguments:    context: DSPProcessContext structure
202                 wram: The memory space to assign. (MI_WRAM_B/MI_WRAM_C)
203                 slots: WRAM slots to assign.
204 
205   Returns:      The starting address of the assigned DSP memory space or 0.
206  *---------------------------------------------------------------------------*/
207 u32 DSP_AttachProcessMemory(DSPProcessContext *context, MIWramPos wram, int slots);
208 
209 /*---------------------------------------------------------------------------*
210   Name:         DSP_DetachProcessMemory
211 
212   Description:  Releases the WRAM slots assigned to used process regions.
213 
214   Arguments:    context: DSPProcessContext structure
215                 slots: Assigned WRAM slots.
216 
217   Returns:      None.
218  *---------------------------------------------------------------------------*/
219 void DSP_DetachProcessMemory(DSPProcessContext *context, MIWramPos wram, int slots);
220 
221 /*---------------------------------------------------------------------------*
222   Name:         DSP_SwitchProcessMemory
223 
224   Description:  Switches the DSP address management being used by the specified process.
225 
226   Arguments:    context: DSPProcessContext structure
227                 wram: The memory space to switch. (MI_WRAM_B/MI_WRAM_C)
228                 address: The starting address to switch. (in units of words in DSP memory space)
229                 length: The memory size to switch. (in units of words in DSP memory space)
230                 to: The new master processor.
231 
232   Returns:      TRUE if all slots are switched successfully.
233  *---------------------------------------------------------------------------*/
234 BOOL DSP_SwitchProcessMemory(DSPProcessContext *context, MIWramPos wram, u32 address, u32 length, MIWramProc to);
235 
236 /*---------------------------------------------------------------------------*
237   Name:         DSP_SetProcessHook
238 
239   Description:  Sets a hook for a factor that causes the DSP to interrupt a process.
240 
241   Arguments:    context: DSPProcessContext structure
242                 factors: Bitset to specify the interrupt causes.
243                 function: The hook function that should be called.
244                 userdata: Arbitrary user-defined argument to pass to the hook function.
245 
246   Returns:      None.
247  *---------------------------------------------------------------------------*/
248 void DSP_SetProcessHook(DSPProcessContext *context, int factors, DSPHookFunction function, void *userdata);
249 
250 /*---------------------------------------------------------------------------*
251   Name:         DSPi_CreateMemoryFile
252 
253   Description:  Converts a static DSP process image into a memory file.
254 
255   Arguments:    memfile: The FSFile structure to turn into a memory file.
256                 image: A buffer storing the DSP process image.
257 
258   Returns:      None.
259  *---------------------------------------------------------------------------*/
DSPi_CreateMemoryFile(FSFile * memfile,const void * image)260 SDK_INLINE BOOL DSPi_CreateMemoryFile(FSFile *memfile, const void *image)
261 {
262     if (!FS_IsAvailable())
263     {
264         OS_TWarning("FS is not initialized yet.\n");
265         FS_Init(FS_DMA_NOT_USE);
266     }
267     FS_InitFile(memfile);
268     return FS_CreateFileFromMemory(memfile, (void *)image, (u32)(16 * 1024 * 1024));
269 }
270 
271 /*---------------------------------------------------------------------------*
272   Name:         DSP_ReadProcessPipe
273 
274   Description:  Receives data from the pipe associated with the designated process port.
275 
276   Arguments:    context: DSPProcessContext structure
277                 port: The port to receive data from.
278                 buffer: The received data.
279                 length: The received data size. (in bytes)
280 
281   Returns:      None.
282  *---------------------------------------------------------------------------*/
283 void DSP_ReadProcessPipe(DSPProcessContext *context, int port, void *buffer, u32 length);
284 
285 /*---------------------------------------------------------------------------*
286   Name:         DSP_WriteProcessPipe
287 
288   Description:  Sends data to the pipe associated with the designated process port.
289 
290   Arguments:    context: DSPProcessContext structure
291                 port: The port to send data to.
292                 buffer: The data to send.
293                 length: The size of the data to send. (in bytes)
294 
295   Returns:      None.
296  *---------------------------------------------------------------------------*/
297 void DSP_WriteProcessPipe(DSPProcessContext *context, int port, const void *buffer, u32 length);
298 
299 #if defined(DSP_SUPPORT_OBSOLETE_LOADER)
300 /*---------------------------------------------------------------------------*
301  * The following is a discontinued candidate interface that is not thought to be used at the present.
302  *---------------------------------------------------------------------------*/
303 
304 /*---------------------------------------------------------------------------*
305   Name:         DSP_MapProcessSegment
306 
307   Description:  Calculates the segment map for a process to own.
308 
309   Arguments:    context: DSPProcessContext structure
310 
311   Returns:      None.
312  *---------------------------------------------------------------------------*/
313 void DSP_MapProcessSegment(DSPProcessContext *context);
314 
315 /*---------------------------------------------------------------------------*
316   Name:         DSP_LoadProcessImage
317 
318   Description:  Loads the specified process image.
319                 The segment map must already be calculated.
320 
321   Arguments:    context: DSPProcessContext structure
322 
323   Returns:      TRUE if all images were loaded successfully.
324  *---------------------------------------------------------------------------*/
325 BOOL DSP_LoadProcessImage(DSPProcessContext *context);
326 
327 /*---------------------------------------------------------------------------*
328   Name:         DSP_StartupProcess
329 
330   Description:  Calculates the segment map for a process image and loads it into WRAM.
331                 This is a combination of the DSP_MapProcessSegment and DSP_LoadProcessImage functions.
332 
333   Arguments:    context: DSPProcessContext structure
334                 image: File handle that indicates a process image.
335                              This will only be accessed within this function.
336                 slotB: WRAM-B that was allowed to be used for code memory.
337                 slotC: WRAM-C that was allowed to be used for data memory.
338                 slotMapper: The algorithm to assign WRAM slots to segments.
339                              If NULL is specified, the appropriate default processing will be selected.
340 
341   Returns:      TRUE if all images were loaded successfully.
342  *---------------------------------------------------------------------------*/
343 BOOL DSP_StartupProcess(DSPProcessContext *context, FSFile *image,
344                         int slotB, int slotC, BOOL (*slotMapper)(DSPProcessContext *, int, int));
345 
346 
347 #endif
348 
349 
350 #ifdef __cplusplus
351 } // extern "C"
352 #endif
353 
354 
355 #endif // SDK_TWL
356 
357 
358 /*---------------------------------------------------------------------------*/
359 #endif // TWL_DSP_PROCESS_H_
360