1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - MB - libraries
3 File: mb_block.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:: 2009-06-09#$
14 $Rev: 10718 $
15 $Author: okajima_manabu $
16 *---------------------------------------------------------------------------*/
17
18 #include <nitro.h>
19 #include "mb_common.h"
20 #include "mb_block.h"
21 #include "mb_private.h"
22
23
24 //============================================================================
25 // Function Prototype Declarations
26 //============================================================================
27 static u8 *MBi_ReceiveRequestDataPiece(const MBCommChildBlockHeader * hdr, u16 child);
28 static BOOL IsGetAllRequestData(u16 child);
29
30
31 //============================================================================
32 // Variable Declarations
33 //============================================================================
34
35 // The size and number of a divided request's fragments
36 static struct
37 {
38 int size;
39 int num;
40 int bufSize;
41 }
42 req_data_piece;
43
44 // For child
45 // Divided request send index.
46 static u8 req_data_piece_idx = 0;
47
48 // For parent
49 // Receive buffer for a divided request
50 static MbRequestPieceBuf *req_buf;
51
52
53 //============================================================================
54 // Function definitions
55 //============================================================================
56
57 /*---------------------------------------------------------------------------*
58 Name: MBi_SetChildMPMaxSize
59
60 Description: Sets the transmission data size for a child and calculates the divided request size.
61
62
63 Arguments: childMaxSize: Child transmission size
64
65 Returns: None.
66 *---------------------------------------------------------------------------*/
MBi_SetChildMPMaxSize(u16 childMaxSize)67 void MBi_SetChildMPMaxSize(u16 childMaxSize)
68 {
69 req_data_piece.size = MB_COMM_CALC_REQ_DATA_PIECE_SIZE(childMaxSize);
70 req_data_piece.num = MB_COMM_CALC_REQ_DATA_PIECE_NUM(childMaxSize);
71 req_data_piece.bufSize = MB_COMM_CALC_REQ_DATA_BUF_SIZE(childMaxSize);
72 }
73
74
75 /*---------------------------------------------------------------------------*
76 Name: MBi_SetParentPieceBuffer
77
78 Description: Sets the receive buffer for a parent's divided request.
79
80 Arguments: buf: Pointer to the receive buffer
81
82 Returns: None.
83 *---------------------------------------------------------------------------*/
MBi_SetParentPieceBuffer(MbRequestPieceBuf * buf)84 void MBi_SetParentPieceBuffer(MbRequestPieceBuf * buf)
85 {
86 req_buf = buf;
87 MI_CpuClear8(req_buf, sizeof(MbRequestPieceBuf));
88 }
89
90
91 /*---------------------------------------------------------------------------*
92 Name: MBi_ClearParentPieceBuffer
93
94 Description: Clears the buffer for receiving divided requests.
95
96 Arguments: child_aid: Child AID of the buffer to clear
97
98 Returns: None.
99 *---------------------------------------------------------------------------*/
MBi_ClearParentPieceBuffer(u16 child_aid)100 void MBi_ClearParentPieceBuffer(u16 child_aid)
101 {
102 // child_aid range check
103 SDK_ASSERT(child_aid != 0 && child_aid <= MB_MAX_CHILD);
104
105 if (req_buf == NULL)
106 {
107 return;
108 }
109
110 MI_CpuClear8(req_buf->data_buf[child_aid - 1],
111 MB_COMM_CALC_REQ_DATA_BUF_SIZE(req_data_piece.bufSize));
112 req_buf->data_bmp[child_aid - 1] = 0;
113 }
114
115
116 /*---------------------------------------------------------------------------*
117 Name: MBi_MakeParentSendBuffer
118
119 Description: Builds the actual data to send, using a parent's send header information.
120
121 Arguments: hdr: Pointer to the parent send header
122 sendbuf: Pointer to the buffer that creates the send data
123
124 Returns: Pointer to send buffer.
125 *---------------------------------------------------------------------------*/
MBi_MakeParentSendBuffer(const MBCommParentBlockHeader * hdr,u8 * sendbuf)126 u8 *MBi_MakeParentSendBuffer(const MBCommParentBlockHeader * hdr, u8 *sendbuf)
127 {
128 u8 *ptr = sendbuf;
129
130 *ptr++ = hdr->type;
131
132 switch (hdr->type)
133 {
134 case MB_COMM_TYPE_PARENT_SENDSTART: // 1
135 break;
136 case MB_COMM_TYPE_PARENT_KICKREQ: // 2
137 break;
138 case MB_COMM_TYPE_PARENT_DL_FILEINFO: // 3
139 break;
140 case MB_COMM_TYPE_PARENT_DATA: // 4
141 *ptr++ = (u8)(0x00ff & hdr->fid); // Lo
142 *ptr++ = (u8)((0xff00 & hdr->fid) >> 8); // Hi
143 *ptr++ = (u8)(0x00ff & hdr->seqno); // Lo
144 *ptr++ = (u8)((0xff00 & hdr->seqno) >> 8); // Hi
145 break;
146 case MB_COMM_TYPE_PARENT_BOOTREQ: // 5
147 break;
148 case MB_COMM_TYPE_PARENT_MEMBER_FULL: // 6
149 break;
150 default:
151 return NULL;
152 }
153
154 return ptr;
155 }
156
157
158 /*---------------------------------------------------------------------------*
159 Name: MBi_SetRecvBufferFromChild
160
161 Description: Get the header portion from a packet received from the child, and return a pointer to the data portion.
162
163
164 Arguments: hdr: Pointer to a variable for getting the header
165 recvbuf: Pointer to the receive buffer
166
167 Returns: Pointer to the data portion.
168 *---------------------------------------------------------------------------*/
MBi_SetRecvBufferFromChild(const u8 * recvbuf,MBCommChildBlockHeader * hdr,u16 child_id)169 u8 *MBi_SetRecvBufferFromChild(const u8 *recvbuf, MBCommChildBlockHeader * hdr, u16 child_id)
170 {
171 u8 *ptr = (u8 *)recvbuf;
172
173 SDK_ASSERT(child_id != 0 && child_id <= MB_MAX_CHILD);
174
175 hdr->type = *ptr++;
176
177 switch (hdr->type)
178 {
179 case MB_COMM_TYPE_CHILD_FILEREQ:
180 // Restore fragmented data
181 if (IsGetAllRequestData(child_id))
182 {
183 return (u8 *)req_buf->data_buf[child_id - 1];
184 }
185
186 hdr->req_data.piece = *ptr++;
187 if (hdr->req_data.piece > req_data_piece.num)
188 {
189 return NULL; // Error
190 }
191 MI_CpuCopy8(ptr, hdr->req_data.data, (u32)req_data_piece.size);
192 ptr = MBi_ReceiveRequestDataPiece(hdr, child_id);
193 break;
194 case MB_COMM_TYPE_CHILD_ACCEPT_FILEINFO:
195 hdr->data.req = (u16)(0x00ff & (*ptr++));
196 hdr->data.req |= (((u16)(*ptr++) << 8) & 0xff00);
197 break;
198 case MB_COMM_TYPE_CHILD_CONTINUE:
199 hdr->data.req = (u16)(0x00ff & (*ptr++));
200 hdr->data.req |= (((u16)(*ptr++) << 8) & 0xff00);
201 MI_CpuCopy8(ptr, hdr->data.reserved, (u32)req_data_piece.size);
202 ptr += req_data_piece.size;
203 break;
204 default:
205 return NULL;
206 }
207
208 return ptr;
209 }
210
211
212 /*---------------------------------------------------------------------------*
213 Name: MBi_ReceiveRequestDataPiece
214
215 Description: Builds data in its entirety from the divided request data that was received from the child.
216
217 Arguments: hdr: Pointer to a variable for getting the header
218 recvbuf: Pointer to the receive buffer
219
220 Returns: Pointer to the data when the divided request data is all complete.
221 NULL when not it is not complete.
222 *---------------------------------------------------------------------------*/
MBi_ReceiveRequestDataPiece(const MBCommChildBlockHeader * hdr,u16 child)223 static u8 *MBi_ReceiveRequestDataPiece(const MBCommChildBlockHeader * hdr, u16 child)
224 {
225 u8 piece;
226 u8 *ptr;
227
228 SDK_ASSERT(child != 0 && child <= MB_MAX_CHILD);
229
230 if (req_buf == NULL)
231 {
232 return NULL;
233 }
234
235 piece = hdr->req_data.piece;
236
237 if (piece > req_data_piece.num)
238 {
239 return NULL;
240 }
241
242 ptr = ((u8 *)req_buf->data_buf[child - 1]) + (piece * req_data_piece.size);
243
244 MI_CpuCopy8(&hdr->req_data.data[0], ptr, (u32)req_data_piece.size);
245
246 req_buf->data_bmp[child - 1] |= (1 << piece);
247
248 MB_DEBUG_OUTPUT(" %02x %02x %02x %02x %02x %02x\n", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4],
249 ptr[5]);
250
251 if (IsGetAllRequestData(child))
252 {
253 return (u8 *)req_buf->data_buf[child - 1];
254 }
255
256 return NULL;
257 }
258
259
260 /*---------------------------------------------------------------------------*
261 Name:
262
263 Description: Builds data in its entirety from the divided request data that was received from the child.
264
265 Arguments: hdr: Pointer to a variable for getting the header
266 recvbuf: Pointer to the receive buffer
267
268 Returns: TRUE if the divided request data is all complete.
269 FALSE if it is not complete.
270 *---------------------------------------------------------------------------*/
IsGetAllRequestData(u16 child)271 static BOOL IsGetAllRequestData(u16 child)
272 {
273 u16 i;
274
275 SDK_ASSERT(child != 0 && child <= MB_MAX_CHILD);
276
277 /* Determine whether Pieces were collected */
278 for (i = 0; i < req_data_piece.num; i++)
279 {
280 if ((req_buf->data_bmp[child - 1] & (1 << i)) == 0)
281 {
282 return FALSE;
283 }
284 }
285
286 return TRUE;
287 }
288
289
290
291 /*---------------------------------------------------------------------------*
292 Name: MBi_MakeChildSendBuffer
293
294 Description: Builds the actual data to send, using a child's send header information.
295
296 Arguments: hdr: Pointer to the child send header
297 sendbuf: Pointer to the buffer that creates the send data
298
299 Returns: Pointer to send buffer.
300 *---------------------------------------------------------------------------*/
MBi_MakeChildSendBuffer(const MBCommChildBlockHeader * hdr,u8 * sendbuf)301 u8 *MBi_MakeChildSendBuffer(const MBCommChildBlockHeader * hdr, u8 *sendbuf)
302 {
303 u8 *pbuf = sendbuf;
304
305 *pbuf++ = hdr->type;
306 switch (hdr->type)
307 {
308 case MB_COMM_TYPE_CHILD_FILEREQ:
309 *pbuf++ = hdr->req_data.piece;
310 if (hdr->req_data.piece > req_data_piece.num)
311 {
312 return NULL; // Error
313 }
314
315 MI_CpuCopy8((void *)(hdr->req_data.data), (void *)pbuf, (u32)req_data_piece.size);
316 pbuf += req_data_piece.size;
317 break;
318 case MB_COMM_TYPE_CHILD_ACCEPT_FILEINFO:
319 break;
320 case MB_COMM_TYPE_CHILD_CONTINUE:
321 *pbuf++ = (u8)(0x00ff & hdr->data.req); // Lo
322 *pbuf++ = (u8)((0xff00 & hdr->data.req) >> 8); // Hi
323 MI_CpuCopy8((void *)(hdr->data.reserved), (void *)pbuf, (u32)req_data_piece.size);
324 pbuf += req_data_piece.size;
325 break;
326 case MB_COMM_TYPE_CHILD_STOPREQ:
327 break;
328 case MB_COMM_TYPE_CHILD_BOOTREQ_ACCEPTED:
329 break;
330 default:
331 return NULL;
332 }
333
334 return pbuf;
335 }
336
337
338 /*---------------------------------------------------------------------------*
339 Name: MBi_SendRequestDataPiece
340
341 Description: Divides request data to send from a child.
342
343 Arguments: pData: Pointer that gets divided data
344 pReq: Request data to divide
345
346 Returns: Index value of the divided data that was obtained.
347 *---------------------------------------------------------------------------*/
MBi_SendRequestDataPiece(u8 * pData,const MBCommRequestData * pReq)348 u8 MBi_SendRequestDataPiece(u8 *pData, const MBCommRequestData *pReq)
349 {
350 const u8 *ptr = (u8 *)pReq;
351
352 /* Decide upon the send piece */
353 req_data_piece_idx = (u8)((req_data_piece_idx + 1) % req_data_piece.num);
354 MB_DEBUG_OUTPUT("req_data piece : %d\n", req_data_piece_idx);
355
356 // Copy data to the send buffer
357 MI_CpuCopy8((void *)&ptr[req_data_piece_idx * req_data_piece.size],
358 pData, (u32)req_data_piece.size);
359
360 MB_DEBUG_OUTPUT(" %02x %02x %02x %02x %02x %02x\n", pData[0], pData[1], pData[2], pData[3],
361 pData[4], pData[5]);
362
363 return req_data_piece_idx;
364 }
365
366
367
368 /*---------------------------------------------------------------------------*
369 Name: MBi_SetRecvBufferFromParent
370
371 Description: Get the header portion from a packet received from the parent, and return a pointer to the data portion.
372
373
374 Arguments: hdr: Pointer to a variable for getting the header
375 recvbuf: Pointer to the receive buffer
376
377 Returns: Pointer to the data portion.
378 *---------------------------------------------------------------------------*/
MBi_SetRecvBufferFromParent(MBCommParentBlockHeader * hdr,const u8 * recvbuf)379 u8 *MBi_SetRecvBufferFromParent(MBCommParentBlockHeader * hdr, const u8 *recvbuf)
380 {
381
382 hdr->type = *recvbuf++;
383
384 switch (hdr->type)
385 {
386 case MB_COMM_TYPE_PARENT_SENDSTART:
387 break;
388 case MB_COMM_TYPE_PARENT_KICKREQ:
389 break;
390 case MB_COMM_TYPE_PARENT_DL_FILEINFO:
391 break;
392 case MB_COMM_TYPE_PARENT_DATA:
393 hdr->fid = (u16)(*recvbuf++); // Lo
394 hdr->fid |= ((u16)(*recvbuf++) << 8); // Hi
395 hdr->seqno = (u16)(*recvbuf++); // Lo
396 hdr->seqno |= ((u16)(*recvbuf++) << 8); // Hi
397 break;
398 case MB_COMM_TYPE_PARENT_BOOTREQ:
399 break;
400 case MB_COMM_TYPE_PARENT_MEMBER_FULL:
401 break;
402 default:
403 return NULL;
404 }
405 return (u8 *)recvbuf;
406 }
407