OSDN Git Service

834d7e0c67199d0b930b3d59357835b270e6981c
[mochi/master.git] / src / kernel / MemMng / MemMngArea.c
1 /******************************************************************************/
2 /* src/kernel/MemMng/MemMngArea.c                                             */
3 /*                                                                 2017/03/12 */
4 /* Copyright (C) 2017 Mochi.                                                  */
5 /******************************************************************************/
6 /******************************************************************************/
7 /* インクルード                                                               */
8 /******************************************************************************/
9 /* 共通ヘッダ */
10 #include <stdarg.h>
11 #include <stdbool.h>
12 #include <string.h>
13 #include <kernel/MochiKernel.h>
14 #include <MLib/MLib.h>
15 #include <MLib/Basic/MLibBasic.h>
16 #include <MLib/Basic/MLibBasicList.h>
17
18 /* 外部モジュールヘッダ */
19 #include <Cmn.h>
20 #include <Debug.h>
21
22 /* 内部モジュールヘッダ */
23
24
25 /******************************************************************************/
26 /* 定義                                                                       */
27 /******************************************************************************/
28 /* デバッグトレースログ出力マクロ */
29 #ifdef DEBUG_LOG_ENABLE
30 #define DEBUG_LOG( ... )                    \
31     DebugLogOutput( CMN_MODULE_MEMMNG_AREA, \
32                     __LINE__,               \
33                     __VA_ARGS__ )
34 #else
35 #define DEBUG_LOG( ... )
36 #endif
37
38 /** メモリ領域情報数 */
39 #define AREA_INFO_NUM  ( 1000000 )
40
41 /** 未使用メモリ領域始点 */
42 #define AREA_FREE_ADDR ( 0x100000 )
43
44 /** メモリ領域アライメント */
45 #define AREA_ALIGNMENT ( 0x1000 )
46
47 /* メモリ領域情報使用フラグ */
48 #define AREA_INFO_UNUSED ( 0 )  /** メモリ領域情報使用中 */
49 #define AREA_INFO_USED   ( 1 )  /** メモリ領域情報未使用 */
50
51 /** メモリ領域情報構造体 */
52 typedef struct {
53     MLibBasicListNode_t node;   /**< 連結リストノード情報 */
54     uint32_t            used;   /**< 使用フラグ           */
55     void                *pAddr; /**< 先頭アドレス         */
56     size_t              size;   /**< サイズ               */
57 } AreaInfo_t;
58
59 /** メモリ領域管理テーブル構造体 */
60 typedef struct {
61     MochiKernelMemoryMap_t *pMemoryMap;                 /**< メモリマップ           */
62     size_t                 memoryMapSize;               /**< メモリマップサイズ     */
63     MLibBasicList_t        usedList;                    /**< 使用中メモリ領域リスト */
64     MLibBasicList_t        freeList;                    /**< 未使用メモリ領域リスト */
65     MLibBasicList_t        emptyList;                   /**< 空メモリ領域情報リスト */
66     AreaInfo_t             areaInfo[ AREA_INFO_NUM ];   /**< メモリ領域情報         */
67 } AreaTbl_t;
68
69
70 /******************************************************************************/
71 /* 変数定義                                                                   */
72 /******************************************************************************/
73 /** メモリ領域管理テーブル */
74 static AreaTbl_t gAreaTbl;
75
76
77 /******************************************************************************/
78 /* ローカル関数プロトタイプ宣言                                               */
79 /******************************************************************************/
80 /* 指定メモリ領域割当 */
81 static void *AreaAlloc( AreaInfo_t *pFree );
82
83 /* 指定メモリ領域割当(一部) */
84 static void *AreaAllocPartially( AreaInfo_t *pFree,
85                                  size_t     size    );
86
87 /* 指定メモリ領域解放(結合) */
88 static CmnRet_t AreaFree( AreaInfo_t *pFree,
89                           AreaInfo_t *pUsed  );
90
91 /* 指定メモリ領域解放(最後尾挿入) */
92 static CmnRet_t AreaFreeAfterTail( AreaInfo_t *pUsed );
93
94 /* 指定メモリ領域解放(前挿入) */
95 static CmnRet_t AreaFreeBefore( AreaInfo_t *pFree,
96                                 AreaInfo_t *pUsed  );
97
98 /* 空メモリ領域情報リスト初期化 */
99 static void AreaInitEmptyList( void );
100
101 /* 未使用メモリ領域リスト初期化 */
102 static void AreaInitFreeList( MochiKernelMemoryMap_t *pMap,
103                               size_t                 mapSize );
104
105 /* 使用中メモリ領域リスト初期化 */
106 static void AreaInitUsedList( void );
107
108
109 /******************************************************************************/
110 /* グローバル関数定義                                                         */
111 /******************************************************************************/
112 /******************************************************************************/
113 /**
114  * @brief       メモリ領域割当
115  * @details     指定したサイズを満たすメモリ領域を割り当てる。
116  * 
117  * @param[in]   size 割当サイズ
118  * 
119  * @retval      NULL     失敗
120  * @retval      NULL以外 割り当てたメモリ領域の先頭アドレス
121  * 
122  * @note        割当サイズが4Kバイトアライメントでない場合は、割当サイズが4Kバ
123  *              イトアライメントに合うよう加算して、メモリ領域を割り当てる。
124  */
125 /******************************************************************************/
126 void *MemMngAreaAlloc( size_t size )
127 {
128     void       *pAddr;  /* 割当メモリ領域先頭アドレス */
129     AreaInfo_t *pFree;  /* 未使用メモリ領域情報       */
130     
131     /* 初期化 */
132     pAddr = NULL;
133     pFree = NULL;
134     
135     /* デバッグトレースログ出力 */
136     DEBUG_LOG( "%s() start. size=%#x", __func__, size );
137     
138     /* サイズチェック */
139     if ( size == 0 ) {
140         /* 不正 */
141         
142         /* デバッグトレースログ出力 */
143         DEBUG_LOG( "%s() end. ret=NULL", __func__ );
144         
145         return NULL;
146         
147     } else {
148         /* 正常 */
149         
150         /* アライメント計算 */
151         size = MLIB_BASIC_ALIGN( size, AREA_ALIGNMENT );
152     }
153     
154     /* 割当可能な未使用メモリ領域検索 */
155     do {
156         /* 未使用メモリ領域情報取得 */
157         pFree = ( AreaInfo_t * )
158             MLibBasicListGetNextNode( &( gAreaTbl.freeList ),
159                                       ( MLibBasicListNode_t * ) pFree );
160         
161         /* 取得結果判定 */
162         if ( pFree == NULL ) {
163             /* メモリ領域情報無 */
164             
165             /* デバッグトレースログ出力 */
166             DEBUG_LOG( "%s() end. ret=NULL", __func__ );
167             
168             return NULL;
169         }
170         
171         /* 割当可能判定 */
172     } while ( pFree->size < size );
173     
174     /* 未使用メモリ領域サイズ比較 */
175     if ( pFree->size == size ) {
176         /* 必要サイズと一致 */
177         
178         /* 同サイズの未使用メモリ領域からメモリ割当 */
179         pAddr = AreaAlloc( pFree );
180         
181     } else {
182         /* 必要サイズを超過 */
183         
184         /* 超過サイズの未使用メモリ領域からメモリ割当 */
185         pAddr = AreaAllocPartially( pFree, size );
186     }
187     
188     /* デバッグトレースログ出力 */
189     DEBUG_LOG( "%s() end. ret=%010p", __func__, pAddr );
190     
191     return pAddr;
192 }
193
194
195 /******************************************************************************/
196 /**
197  * @brief       メモリ領域解放
198  * @details     指定したメモリアドレスが先頭アドレスのメモリ領域を解放する。
199  * 
200  * @param[in]   *pAddr 先頭アドレス
201  * 
202  * @retval      CMN_SUCCESS 正常終了
203  * @retval      CMN_FAILURE 異常終了
204  */
205 /******************************************************************************/
206 CmnRet_t MemMngAreaFree( void *pAddr )
207 {
208     CmnRet_t   ret;     /* 関数戻り値           */
209     MLibRet_t  retMLib; /* MLib関数戻り値       */
210     AreaInfo_t *pFree;  /* 未使用メモリ領域情報 */
211     AreaInfo_t *pInfo;  /* 使用中メモリ領域情報 */
212     
213     /* 初期化 */
214     ret     = CMN_FAILURE;
215     retMLib = MLIB_FAILURE;
216     pFree   = NULL;
217     pInfo   = NULL;
218     
219     /* デバッグトレースログ出力 */
220     DEBUG_LOG( "%s() start. pAddr=%010p", __func__, pAddr );
221     
222     /* 引数チェック */
223     if ( pAddr == NULL ) {
224         /* 不正 */
225         
226         /* デバッグトレースログ出力 */
227         DEBUG_LOG( "%s() end. ret=%d", __func__, CMN_FAILURE );
228         
229         return CMN_FAILURE;
230     }
231     
232     /* 該当メモリ領域情報検索 */
233     do {
234         /* 使用中メモリ領域情報取得 */
235         pInfo = ( AreaInfo_t * )
236             MLibBasicListGetPrevNode( &( gAreaTbl.usedList ),
237                                       ( MLibBasicListNode_t * ) pInfo );
238         
239         /* 取得結果判定 */
240         if ( pInfo == NULL ) {
241             /* メモリ領域情報無 */
242             
243             /* デバッグトレースログ出力 */
244             DEBUG_LOG( "%s() end. ret=%d", __func__, CMN_FAILURE );
245             
246             return CMN_FAILURE;
247         }
248         
249         /* 先頭アドレス比較 */
250     } while ( pInfo->pAddr != pAddr );
251     
252     /* 使用中メモリ領域リストから削除 */
253     retMLib = MLibBasicListRemove( &( gAreaTbl.usedList ),
254                                    ( MLibBasicListNode_t * ) pInfo );
255     
256     /* 削除結果判定 */
257     if ( retMLib != MLIB_SUCCESS ) {
258         /* 失敗 */
259         
260         /* デバッグトレースログ出力 */
261         DEBUG_LOG( "%s() end. ret=%d", __func__, CMN_FAILURE );
262         
263         return CMN_FAILURE;
264     }
265     
266     while ( true ) {
267         /* 未使用メモリ領域情報取得 */
268         pFree = ( AreaInfo_t * )
269             MLibBasicListGetNextNode( &( gAreaTbl.freeList ),
270                                       ( MLibBasicListNode_t * ) pFree );
271         
272         /* メモリ領域位置関係比較 */
273         if ( pFree == NULL ) {
274             /* メモリ領域情報無 */
275             
276             /* 未使用メモリ領域リストの最後尾に挿入 */
277             ret = AreaFreeAfterTail( pInfo );
278             
279         } else if ( ( pInfo->pAddr + pInfo->size ) < pFree->pAddr ) {
280             /* 未使用メモリ領域より前 */
281             
282             /* 前に挿入 */
283             ret = AreaFreeBefore( pFree, pInfo );
284             
285         } else if ( ( pFree->pAddr + pFree->size ) < pInfo->pAddr ) {
286             /* 未使用メモリ領域より後 */
287             
288             /* 次の未使用メモリ領域 */
289             continue;
290             
291         } else {
292             /* 未使用メモリ領域に隣接 */
293             
294             /* 結合 */
295             ret = AreaFree( pFree, pInfo );
296         }
297         
298         break;
299     }
300     
301     /* デバッグトレースログ出力 */
302     DEBUG_LOG( "%s() end. ret=%d", __func__, ret );
303     
304     return ret;
305 }
306
307
308 /******************************************************************************/
309 /**
310  * @brief       メモリ領域管理初期化
311  * @details     メモリ領域管理テーブルを初期化する。
312  * 
313  * @param[in]   *pMap   メモリマップ
314  * @param[in]   mapSize メモリマップサイズ
315  */
316 /******************************************************************************/
317 void MemMngAreaInit( MochiKernelMemoryMap_t *pMap,
318                      size_t                 mapSize )
319 {
320     /* デバッグトレースログ出力 */
321     DEBUG_LOG( "%s() start.", __func__ );
322     
323     /* 空メモリ領域情報リスト初期化 */
324     AreaInitEmptyList();
325     
326     /* 未使用メモリ領域リスト初期化 */
327     AreaInitFreeList( pMap, mapSize );
328     
329     /* 使用中メモリ領域リスト初期化 */
330     AreaInitUsedList();
331     
332     /* デバッグトレースログ出力 */
333     DEBUG_LOG( "%s() end.", __func__ );
334     
335     return;
336 }
337
338
339 /******************************************************************************/
340 /* ローカル関数定義                                                           */
341 /******************************************************************************/
342 /******************************************************************************/
343 /**
344  * @brief       指定メモリ領域割当
345  * @details     指定した未使用メモリ領域を割り当てる。
346  * 
347  * @param[in]   *pFree 未使用メモリ領域情報
348  * 
349  * @retval      NULL     失敗
350  * @retval      NULL以外 割当メモリ領域の先頭アドレス
351  */
352 /******************************************************************************/
353 static void *AreaAlloc( AreaInfo_t *pFree )
354 {
355     MLibRet_t retMLib;  /* MLib関数戻り値 */
356     
357     /* デバッグトレースログ出力 */
358     DEBUG_LOG( "%s() start. pFree=%010p", __func__, pFree );
359     
360     /* 未使用メモリ領域リストから削除 */
361     retMLib = MLibBasicListRemove( &( gAreaTbl.freeList ),
362                                    ( MLibBasicListNode_t * ) pFree );
363     
364     /* 削除結果判定 */
365     if ( retMLib != MLIB_SUCCESS ) {
366         /* 失敗 */
367         
368         /* デバッグトレースログ出力 */
369         DEBUG_LOG( "%s() end. ret=NULL", __func__ );
370         
371         return NULL;
372     }
373     
374     /* 使用中メモリ領域リストに追加 */
375     retMLib = MLibBasicListInsertTail( &( gAreaTbl.usedList ),
376                                        ( MLibBasicListNode_t * ) pFree );
377     
378     /* 追加結果判定 */
379     if ( retMLib != MLIB_SUCCESS ) {
380         /* 失敗 */
381         
382         /* デバッグトレースログ出力 */
383         DEBUG_LOG( "%s() end. ret=NULL", __func__ );
384         
385         return NULL;
386     }
387     
388     /* デバッグトレースログ出力 */
389     DEBUG_LOG( "%s() end. ret=%010p", __func__, pFree->pAddr );
390     
391     /* メモリ領域先頭アドレス返却 */
392     return pFree->pAddr;
393 }
394
395
396 /******************************************************************************/
397 /**
398  * @brief       指定メモリ領域割当(一部)
399  * @details     指定した未使用メモリ領域から指定した領域サイズのメモリ領域を割
400  *              り当てる。
401  * 
402  * @param[in]   *pFree 未使用メモリ領域情報
403  * @param[in]   size   割当てサイズ
404  * 
405  * @retval      NULL     失敗
406  * @retval      NULL以外 割当メモリ領域の先頭アドレス
407  */
408 /******************************************************************************/
409 static void *AreaAllocPartially( AreaInfo_t *pFree,
410                                  size_t     size    )
411 {
412     MLibRet_t  retMLib;     /* MLib関数戻り値   */
413     AreaInfo_t *pEmpty;     /* 空メモリ領域情報 */
414     
415     /* 初期化 */
416     retMLib = MLIB_FAILURE;
417     
418     /* デバッグトレースログ出力 */
419     DEBUG_LOG( "%s() start. pFree=%010p, size=%#x", __func__, pFree, size );
420     
421     /* 空メモリ領域情報リストからメモリ領域情報取得 */
422     pEmpty = ( AreaInfo_t * )
423         MLibBasicListRemoveTail( &( gAreaTbl.emptyList ) );
424     
425     /* 取得結果判定 */
426     if ( pEmpty == NULL ) {
427         /* メモリ領域情報無 */
428         
429         /* デバッグトレースログ出力 */
430         DEBUG_LOG( "%s() end. ret=NULL", __func__ );
431         
432         return NULL;
433     }
434     
435     /* 空メモリ領域情報設定 */
436     pEmpty->used  = AREA_INFO_USED;     /* 使用フラグ   */
437     pEmpty->pAddr = pFree->pAddr;       /* 先頭アドレス */
438     pEmpty->size  = size;               /* サイズ       */
439     
440     /* 空メモリ領域情報を使用中メモリ領域リストに追加 */
441     retMLib = MLibBasicListInsertTail( &( gAreaTbl.usedList ),
442                                        ( MLibBasicListNode_t * ) pEmpty );
443     
444     /* 追加結果判定 */
445     if ( retMLib != MLIB_SUCCESS ) {
446         /* 失敗 */
447         
448         /* デバッグトレースログ出力 */
449         DEBUG_LOG( "%s() end. ret=NULL", __func__ );
450         
451         return NULL;
452     }
453     
454     /* 未使用メモリ領域情報設定 */
455     pFree->pAddr += size;               /* 先頭アドレス */
456     pFree->size  -= size;               /* サイズ       */
457     
458     /* デバッグトレースログ出力 */
459     DEBUG_LOG( "%s() end.", __func__ );
460     
461     /* デバッグトレースログ出力 */
462     DEBUG_LOG( "%s() end. ret=%010p", __func__, pEmpty->pAddr );
463     
464     /* メモリ領域先頭アドレス返却 */
465     return pEmpty->pAddr;
466 }
467
468
469 /******************************************************************************/
470 /**
471  * @brief       指定メモリ領域解放(結合)
472  * @details     指定した使用中メモリ領域を指定した未使用メモリ領域に結合する。
473  * 
474  * @param[in]   *pFree 解放先未使用メモリ領域情報
475  * @param[in]   *pUsed 使用中メモリ領域情報
476  * 
477  * @retval      CMN_SUCCESS 正常終了
478  * @retval      CMN_FAILURE 異常終了
479  */
480 /******************************************************************************/
481 static CmnRet_t AreaFree( AreaInfo_t *pFree,
482                           AreaInfo_t *pUsed  )
483 {
484     size_t     size;    /* 未使用メモリ領域サイズ               */
485     MLibRet_t  retMLib; /* MLib関数戻り値                       */
486     AreaInfo_t *pNext;  /* 未使用メモリ領域の次のメモリ領域情報 */
487     
488     /* 初期化 */
489     size    = pFree->size;
490     retMLib = MLIB_FAILURE;
491     pNext   = NULL;
492     
493     /* デバッグトレースログ出力 */
494     DEBUG_LOG( "%s() start. pFree=%010p, pUsed=%010p", __func__, pFree, pUsed );
495     
496     /* メモリ領域位置関係比較 */
497     if ( pUsed->pAddr > pFree->pAddr ) {
498         /* 使用中メモリ領域が未使用メモリ領域の前 */
499         
500         /* 未使用メモリ領域先頭アドレス設定 */
501         pFree->pAddr = pUsed->pAddr;
502     }
503     
504     /* 未使用メモリ領域サイズ設定 */
505     pFree->size += pUsed->size;
506     
507     /* 使用中メモリ領域情報初期化 */
508     memset( pUsed, 0, sizeof ( AreaInfo_t ) );
509     
510     /* 使用中メモリ領域情報を空メモリ領域情報リストの最後尾に挿入 */
511     retMLib = MLibBasicListInsertTail( &( gAreaTbl.emptyList ),
512                                        ( MLibBasicListNode_t * ) pUsed );
513     
514     /* 挿入結果判定 */
515     if ( retMLib != MLIB_SUCCESS ) {
516         /* 失敗 */
517         
518         /* [TODO]トレース情報 */
519     }
520     
521     /* 未使用メモリ領域の次のメモリ領域情報取得 */
522     pNext = ( AreaInfo_t * )
523         MLibBasicListGetNextNode( &( gAreaTbl.freeList ),
524                                   ( MLibBasicListNode_t * ) pFree );
525     
526     /* 取得結果判定 */
527     if ( pNext == NULL ) {
528         /* メモリ領域情報無 */
529         
530         /* デバッグトレースログ出力 */
531         DEBUG_LOG( "%s() end. ret=%d", __func__, CMN_SUCCESS );
532         
533         return CMN_SUCCESS;
534     }
535     
536     /* メモリ領域隣接判定 */
537     if ( ( pFree->pAddr + pFree->size ) == pNext->pAddr ) {
538         /* 隣接する */
539         
540         /* 次メモリ領域情報を未使用メモリ領域リストから削除 */
541         retMLib = MLibBasicListRemove( &( gAreaTbl.freeList ),
542                                        ( MLibBasicListNode_t * ) pNext );
543         
544         /* 削除結果判定 */
545         if ( retMLib != MLIB_SUCCESS ) {
546             /* 失敗 */
547             
548             /* 未使用メモリ領域サイズ復元 */
549             pFree->size = size;
550             
551             /* デバッグトレースログ出力 */
552             DEBUG_LOG( "%s() end. ret=%d", __func__, CMN_FAILURE );
553             
554             return CMN_FAILURE;
555         }
556         
557         /* 未使用メモリ領域サイズ設定 */
558         pFree->size += pNext->size;
559         
560         /* 次メモリ領域情報初期化 */
561         memset( pNext, 0, sizeof ( AreaInfo_t ) );
562         
563         /* 次メモリ領域情報を空メモリ領域情報リストの最後尾に挿入 */
564         retMLib = MLibBasicListInsertTail( &( gAreaTbl.emptyList ),
565                                            ( MLibBasicListNode_t * ) pUsed );
566         
567         /* 挿入結果判定 */
568         if ( retMLib != MLIB_SUCCESS ) {
569             /* 失敗 */
570             
571             /* [TODO]トレース情報 */
572         }
573     }
574     
575     /* デバッグトレースログ出力 */
576     DEBUG_LOG( "%s() end. ret=%d", __func__, CMN_SUCCESS );
577     
578     return CMN_SUCCESS;
579 }
580
581
582 /******************************************************************************/
583 /**
584  * @brief       指定メモリ領域解放(最後尾挿入)
585  * @details     指定した使用中メモリ領域を未使用メモリ領域リストの最後尾に挿入
586  *              する。
587  * 
588  * @param[in]   *pUsed 使用中メモリ領域情報
589  * 
590  * @retval      CMN_SUCCESS 正常終了
591  * @retval      CMN_FAILURE 異常終了
592  */
593 /******************************************************************************/
594 static CmnRet_t AreaFreeAfterTail( AreaInfo_t *pUsed )
595 {
596     MLibRet_t retMLib;  /* MLib関数戻り値 */
597     
598     /* デバッグトレースログ出力 */
599     DEBUG_LOG( "%s() start. pUsed=%010p", __func__, pUsed );
600     
601     /* 最後尾挿入 */
602     retMLib = MLibBasicListInsertTail( &( gAreaTbl.freeList ),
603                                        ( MLibBasicListNode_t * ) pUsed );
604     
605     /* 挿入結果判定 */
606     if ( retMLib != MLIB_SUCCESS ) {
607         /* 失敗 */
608         
609         /* デバッグトレースログ出力 */
610         DEBUG_LOG( "%s() end. ret=%d", __func__, CMN_FAILURE );
611         
612         return CMN_FAILURE;
613     }
614     
615     /* デバッグトレースログ出力 */
616     DEBUG_LOG( "%s() end. ret=%d", __func__, CMN_SUCCESS );
617     
618     return CMN_SUCCESS;
619 }
620
621
622 /******************************************************************************/
623 /**
624  * @brief       指定メモリ領域解放(前挿入)
625  * @details     指定した使用中メモリ領域を指定した未使用メモリ領域の前に挿入す
626  *              る。
627  * 
628  * @param[in]   *pFree 未使用メモリ領域情報
629  * @param[in]   *pUsed 使用中メモリ領域情報
630  * 
631  * @retval      CMN_SUCCESS 正常終了
632  * @retval      CMN_FAILURE 異常終了
633  */
634 /******************************************************************************/
635 static CmnRet_t AreaFreeBefore( AreaInfo_t *pFree,
636                                 AreaInfo_t *pUsed  )
637 {
638     MLibRet_t retMLib;  /* MLib関数戻り値 */
639     
640     /* デバッグトレースログ出力 */
641     DEBUG_LOG( "%s() start. pFree=%010p, pUsed=%010p", __func__, pFree, pUsed );
642     
643     /* 指定した未使用メモリ領域の前に挿入 */
644     retMLib = MLibBasicListInsertPrev( &( gAreaTbl.freeList ),
645                                        ( MLibBasicListNode_t * ) pFree,
646                                        ( MLibBasicListNode_t * ) pUsed  );
647     
648     /* 挿入結果判定 */
649     if ( retMLib != MLIB_SUCCESS ) {
650         /* 失敗 */
651         
652         /* デバッグトレースログ出力 */
653         DEBUG_LOG( "%s() end. ret=%d", __func__, CMN_FAILURE );
654         
655         return CMN_FAILURE;
656     }
657     
658     /* デバッグトレースログ出力 */
659     DEBUG_LOG( "%s() end. ret=%d", __func__, CMN_SUCCESS );
660     
661     return CMN_SUCCESS;
662 }
663
664
665 /******************************************************************************/
666 /**
667  * @brief       空メモリ領域情報リスト初期化
668  * @details     空メモリ領域情報リストを初期化する。
669  */
670 /******************************************************************************/
671 static void AreaInitEmptyList( void )
672 {
673     uint32_t            index;      /* メモリ領域情報リストインデックス */
674     MLibRet_t           retMLib;    /* MLIB関数戻り値                   */
675     MLibBasicListNode_t *pEmpty;    /* 空メモリ領域情報ノード           */
676     
677     /* デバッグトレースログ出力 */
678     DEBUG_LOG( "%s() start.", __func__ );
679     
680     /* 空メモリ領域情報リスト初期化 */
681     retMLib = MLibBasicListInit( &( gAreaTbl.emptyList ) );
682     
683     /* 初期化結果判定 */
684     if ( retMLib != MLIB_SUCCESS ) {
685         /* 失敗 */
686         
687         /* [TODO]カーネルパニック */
688         DEBUG_LOG( "ERROR!!! retMLib=%d", retMLib );
689     }
690     
691     /* メモリ領域情報初期化 */
692     memset( gAreaTbl.areaInfo, 0, sizeof ( gAreaTbl.areaInfo ) );
693     
694     for ( index = 0; index < AREA_INFO_NUM; index++ ) {
695         /* 空メモリ領域情報参照変数設定 */
696         pEmpty = ( MLibBasicListNode_t * ) &( gAreaTbl.areaInfo[ index ] );
697         
698         /* 空メモリ領域情報リスト挿入 */
699         retMLib = MLibBasicListInsertTail( &( gAreaTbl.emptyList ),
700                                            pEmpty );
701         
702         /* 挿入結果判定 */
703         if ( retMLib != MLIB_SUCCESS ) {
704             /* 失敗 */
705             
706             /* [TODO]カーネルパニック */
707             DEBUG_LOG( "ERROR!!! retMLib=%d", retMLib );
708             
709         }
710     }
711     
712     /* デバッグトレースログ出力 */
713     DEBUG_LOG( "%s() end.", __func__ );
714     
715     return;
716 }
717
718
719 /******************************************************************************/
720 /**
721  * @brief       未使用メモリ領域リスト初期化
722  * @details     未使用メモリ領域リストをメモリマップを基に初期化する。
723  * 
724  * @param[in]   *pMap   メモリマップ
725  * @param[in]   mapSize メモリマップサイズ
726  * 
727  * @attention   空メモリ領域情報リストを初期化済みである事。
728  */
729 /******************************************************************************/
730 static void AreaInitFreeList( MochiKernelMemoryMap_t *pMap,
731                               size_t                 mapSize )
732 {
733     size_t                 size;    /* メモリ領域サイズ       */
734     uint32_t               index;   /* インデックス           */
735     uint32_t               addr;    /* メモリ領域先頭アドレス */
736     uint32_t               delta;   /* アライメント差分       */
737     MLibRet_t              retMLib; /* MLIB関数戻り値         */
738     AreaInfo_t             *pEmpty; /* 空メモリ領域情報       */
739     MochiKernelMemoryMap_t *pEntry; /* メモリマップエントリ   */
740     
741     /* 初期化 */
742     size    = 0;
743     index   = 0;
744     addr    = 0;
745     delta   = 0;
746     retMLib = MLIB_FAILURE;
747     pEmpty  = NULL;
748     pEntry  = NULL;
749     
750     /* デバッグトレースログ出力 */
751     DEBUG_LOG( "%s() start. pMap=%010p, mapSize=%u", __func__, pMap, mapSize );
752     
753     /* 未使用メモリ領域リスト初期化 */
754     retMLib = MLibBasicListInit( &( gAreaTbl.freeList ) );
755     
756     /* 初期化結果判定 */
757     if ( retMLib != MLIB_SUCCESS ) {
758         /* 失敗 */
759         
760         /* [TODO]カーネルパニック */
761     }
762     
763     /* メモリマップ有無判定 */
764     if ( pMap == NULL ) {
765         /* メモリマップ無し */
766         
767         /* [TODO]カーネルパニック */
768         
769     }
770     
771     /* メモリマップ設定 */
772     gAreaTbl.pMemoryMap    = pMap;
773     gAreaTbl.memoryMapSize = mapSize;
774     
775     /* メモリマップ全エントリ毎に繰り返し */
776     for ( index = 0; index < gAreaTbl.memoryMapSize; index++ ) {
777         /* メモリマップ参照変数設定 */
778         pEntry = &gAreaTbl.pMemoryMap[ index ];
779         
780         /* メモリ領域タイプ判定 */
781         if ( pEntry->type != MOCHIKERNEL_MEMORY_TYPE_AVAILABLE ) {
782             /* 使用可能メモリ領域でない */
783             
784             /* 次のメモリマップ */
785             continue;
786         }
787         
788         /* 変数設定 */
789         addr  = ( uint32_t ) pEntry->pAddr; /* 先頭アドレス               */
790         delta = addr % AREA_ALIGNMENT;      /* 先頭アドレスアライメント差 */
791         size  = pEntry->size;               /* サイズ                     */
792         
793         /* メモリ領域位置判定 */
794         if ( addr < AREA_FREE_ADDR ) {
795             /* スキップ領域 */
796             
797             /* 次のメモリマップ */
798             continue;
799         }
800         
801         /* 先頭アドレスアライメント判定 */
802         if ( delta != 0 ) {
803             /* アライメント不一致 */
804             
805             /* 変数設定 */
806             addr += AREA_ALIGNMENT - delta; /* 先頭アドレス */
807             size -= AREA_ALIGNMENT - delta; /* サイズ       */
808         }
809         
810         /* サイズアライメント差計算 */
811         delta = size % AREA_ALIGNMENT;
812         
813         /* メモリ領域サイズアライメント判定 */
814         if ( delta != 0 ) {
815             /* アライメント不一致 */
816             
817             /* メモリ領域サイズ修正 */
818             size -= delta;
819         }
820         
821         /* メモリ領域サイズ判定 */
822         if ( ( size / AREA_ALIGNMENT ) == 0 ) {
823             /* サイズ不足 */
824             
825             /* 次のメモリマップ */
826             continue;
827         }
828         
829         /* 空メモリ情報領域リストからメモリ領域情報取得 */
830         pEmpty = ( AreaInfo_t * )
831             MLibBasicListRemoveTail( &( gAreaTbl.emptyList ) );
832         
833         /* 取得結果判定 */
834         if ( pEmpty == NULL ) {
835             /* 失敗 */
836             
837             break;
838         }
839         
840         /* メモリ領域情報設定 */
841         pEmpty->used  = AREA_INFO_USED;     /* 使用フラグ   */
842         pEmpty->pAddr = ( void * ) addr;    /* 先頭アドレス */
843         pEmpty->size  = size;               /* サイズ       */
844         
845         /* 未使用メモリ領域リストの最後尾に挿入 */
846         retMLib = MLibBasicListInsertTail( &( gAreaTbl.usedList ),
847                                            ( MLibBasicListNode_t * ) pEmpty );
848         
849         /* 挿入結果判定 */
850         if ( retMLib != MLIB_SUCCESS ) {
851             /* 失敗 */
852             
853             /* [TODO]トレースログ */
854         }
855     }
856     
857     /* デバッグトレースログ出力 */
858     DEBUG_LOG( "%s() end.", __func__ );
859     
860     return;
861 }
862
863
864 /******************************************************************************/
865 /**
866  * @brief       使用中メモリ領域リスト初期化
867  * @details     使用中メモリ領域リストを初期化する。
868  */
869 /******************************************************************************/
870 static void AreaInitUsedList( void )
871 {
872     MLibRet_t retMLib;  /* MLIB関数戻り値 */
873     
874     /* デバッグトレースログ出力 */
875     DEBUG_LOG( "%s() start.", __func__ );
876     
877     /* 使用中メモリ領域リスト初期化 */
878     retMLib = MLibBasicListInit( &( gAreaTbl.usedList ) );
879     
880     /* 初期化結果判定 */
881     if ( retMLib != MLIB_SUCCESS ) {
882         /* 失敗 */
883         
884         /* [TODO]カーネルパニック */
885         DEBUG_LOG( "ERROR!!! retMLib=%d", retMLib );
886     }
887     
888     /* デバッグトレースログ出力 */
889     DEBUG_LOG( "%s() end.", __func__ );
890     
891     return;
892 }
893
894
895 /******************************************************************************/