OSDN Git Service

I/Oメモリ管理機能追加
[mochi/master.git] / src / kernel / TaskMng / TaskMngTask.c
1 /******************************************************************************/
2 /* src/kernel/TaskMng/TaskMngTask.c                                           */
3 /*                                                                 2018/08/15 */
4 /* Copyright (C) 2017-2018 Mochi.                                             */
5 /******************************************************************************/
6 /******************************************************************************/
7 /* インクルード                                                               */
8 /******************************************************************************/
9 /* 共通ヘッダ */
10 #include <stdarg.h>
11 #include <stdint.h>
12 #include <string.h>
13 #include <hardware/IA32/IA32Instruction.h>
14 #include <MLib/Basic/MLibBasic.h>
15 #include <kernel/config.h>
16 #include <kernel/types.h>
17
18 /* 外部モジュールヘッダ */
19 #include <Cmn.h>
20 #include <Debug.h>
21 #include <MemMng.h>
22 #include <TaskMng.h>
23
24 /* 内部モジュールヘッダ */
25 #include "TaskMngElf.h"
26 #include "TaskMngProc.h"
27 #include "TaskMngSched.h"
28 #include "TaskMngTask.h"
29 #include "TaskMngTss.h"
30
31
32 /******************************************************************************/
33 /* 定義                                                                       */
34 /******************************************************************************/
35 /* デバッグトレースログ出力マクロ */
36 #ifdef DEBUG_LOG_ENABLE
37 #define DEBUG_LOG( ... )                        \
38     DebugLogOutput( CMN_MODULE_TASKMNG_TASK,    \
39                     __LINE__,                   \
40                     __VA_ARGS__ )
41 #else
42 #define DEBUG_LOG( ... )
43 #endif
44
45 /** タスクスタック情報 */
46 typedef struct {
47     void                 *pTopAddr;         /**< 先頭アドレス */
48     void                 *pBottomAddr;      /**< 終端アドレス */
49     size_t               size;              /**< サイズ       */
50 } TaskStackInfo_t;
51
52 /** タスク管理テーブル構造体 */
53 typedef struct {
54     uint8_t              used;              /**< 使用フラグ               */
55     uint8_t              state;             /**< タスク状態               */
56     uint8_t              reserved[ 2 ];     /**< パディング               */
57     MkPid_t              pid;               /**< プロセスID               */
58     MkTid_t              tid;               /**< スレッドID               */
59     TaskStackInfo_t      aplStackInfo;      /**< アプリスタックアドレス   */
60     TaskStackInfo_t      kernelStackInfo;   /**< カーネルスタックアドレス */
61     TaskMngTaskContext_t context;           /**< コンテキスト             */
62 } TaskTbl_t;
63
64
65 /******************************************************************************/
66 /* 変数定義                                                                   */
67 /******************************************************************************/
68 /** タスク管理テーブル */
69 static TaskTbl_t gTaskTbl[ MK_CONFIG_TASKID_NUM ];
70
71
72 /******************************************************************************/
73 /* グローバル関数定義                                                         */
74 /******************************************************************************/
75 /******************************************************************************/
76 /**
77  * @brief       タスク追加
78  * @details     タスク追加を行う。
79  * 
80  * @param[in]   pid       プロセスID
81  * @param[in]   tid       スレッドID
82  * @param[in]   pageDirId ページディレクトリID
83  * @param[in]   *pAddr    実行アドレス
84  * 
85  * @return      タスクID
86  * @retval      MK_CONFIG_TASKID_NULL 失敗
87  * @retval      MK_CONFIG_TASKID_MIN  タスクID最小値
88  * @retval      MK_CONFIG_TASKID_MAX  タスクID最大値
89  */
90 /******************************************************************************/
91 MkTaskId_t TaskMngTaskAdd( MkPid_t  pid,
92                            MkTid_t  tid,
93                            uint32_t pageDirId,
94                            void     *pAddr     )
95 {
96     void            *pAplStack;      /* アプリスタック       */
97     void            *pKernelStack;   /* カーネルスタック     */
98     CmnRet_t        ret;             /* 関数戻り値           */
99     MkTaskId_t      taskId;          /* タスクID             */
100     TaskStackInfo_t *pStackInfo;     /* スタック情報         */
101     
102     /* 初期化 */
103     pAplStack    = NULL;
104     pKernelStack = NULL;
105     ret          = CMN_FAILURE;
106     taskId       = MK_CONFIG_TASKID_MIN;
107     pStackInfo   = NULL;
108     
109     /* デバッグトレースログ出力 */
110     DEBUG_LOG( "%s() start.", __func__ );
111     DEBUG_LOG( "  pid=%u, tid=%u, pageDirId=%u, pAddr=%010p",
112                pid,
113                tid,
114                pageDirId,
115                pAddr                                          );
116     
117     /* 空タスク検索 */
118     for ( taskId = MK_CONFIG_TASKID_MIN;
119           taskId < MK_CONFIG_TASKID_MAX;
120           taskId++                       ) {
121         /* 使用フラグ判定 */
122         if ( gTaskTbl[ taskId ].used == CMN_UNUSED ) {
123             /* 未使用 */
124             
125             /* タスク基本設定 */
126             gTaskTbl[ taskId ].used         = CMN_USED;
127             gTaskTbl[ taskId ].state        = 0;
128             gTaskTbl[ taskId ].pid          = pid;
129             gTaskTbl[ taskId ].tid          = tid;
130             gTaskTbl[ taskId ].context.eip  = ( uint32_t ) pAddr;
131             gTaskTbl[ taskId ].context.esp  = MK_CONFIG_ADDR_KERNEL_STACK +
132                                               MK_CONFIG_SIZE_KERNEL_STACK -
133                                               sizeof ( uint32_t );
134             
135             /* カーネルスタック情報設定 */
136             pStackInfo              = &( gTaskTbl[ taskId ].kernelStackInfo );
137             pStackInfo->pTopAddr    = ( void * ) MK_CONFIG_ADDR_KERNEL_STACK;
138             pStackInfo->pBottomAddr = ( void * )
139                                       ( MK_CONFIG_ADDR_KERNEL_STACK +
140                                         MK_CONFIG_SIZE_KERNEL_STACK -
141                                         sizeof ( uint32_t )            );
142             pStackInfo->size        = MK_CONFIG_SIZE_KERNEL_STACK;
143             
144             /* アプリスタック情報設定 */
145             pStackInfo              = &( gTaskTbl[ taskId ].aplStackInfo );
146             pStackInfo->pTopAddr    = ( void * ) MK_CONFIG_ADDR_APL_STACK;
147             pStackInfo->pBottomAddr = ( void * )
148                                       ( MK_CONFIG_ADDR_APL_STACK +
149                                         MK_CONFIG_SIZE_APL_STACK -
150                                         sizeof ( uint32_t )          );
151             pStackInfo->size        = MK_CONFIG_SIZE_APL_STACK;
152             
153             /* カーネルスタック領域割り当て */
154             pKernelStack = MemMngPhysAlloc( MK_CONFIG_SIZE_KERNEL_STACK );
155             
156             /* 割り当て結果判定 */
157             if ( pKernelStack == NULL ) {
158                 /* 失敗 */
159                 
160                 /* [TODO] */
161                 
162                 return MK_CONFIG_TASKID_NULL;
163             }
164             
165             /* アプリスタック領域割り当て */
166             pAplStack = MemMngPhysAlloc( MK_CONFIG_SIZE_APL_STACK );
167             
168             /* 割り当て結果判定 */
169             if ( pAplStack == NULL ) {
170                 /* 失敗 */
171                 
172                 /* [TODO] */
173                 
174                 return MK_CONFIG_TASKID_NULL;
175             }
176             
177             /* カーネルスタックページマップ設定 */
178             ret = MemMngPageSet( pageDirId,
179                                  ( void * ) MK_CONFIG_ADDR_KERNEL_STACK,
180                                  pKernelStack,
181                                  MK_CONFIG_SIZE_KERNEL_STACK,
182                                  IA32_PAGING_G_NO,
183                                  IA32_PAGING_US_SV,
184                                  IA32_PAGING_RW_RW );
185             
186             /* ページマップ設定結果判定 */
187             if ( ret != CMN_SUCCESS ) {
188                 /* 失敗 */
189                 
190                 /* [TODO] */
191                 
192                 return MK_CONFIG_TASKID_NULL;
193             }
194             
195             /* アプリスタックページマップ設定 */
196             ret = MemMngPageSet( pageDirId,
197                                  ( void * ) MK_CONFIG_ADDR_APL_STACK,
198                                  pAplStack,
199                                  MK_CONFIG_SIZE_APL_STACK,
200                                  IA32_PAGING_G_NO,
201                                  IA32_PAGING_US_USER,
202                                  IA32_PAGING_RW_RW );
203             
204             /* ページマップ設定結果判定 */
205             if ( ret != CMN_SUCCESS ) {
206                 /* 失敗 */
207                 
208                 /* [TODO] */
209                 
210                 return MK_CONFIG_TASKID_NULL;
211             }
212             
213             /* デバッグトレースログ出力 */
214             DEBUG_LOG( "%s() end. ret=%u", __func__, taskId );
215             
216             return taskId;
217         }
218     }
219     
220     /* デバッグトレースログ出力 */
221     DEBUG_LOG( "%s() end. ret=%u", __func__, MK_CONFIG_TASKID_NULL );
222     
223     return MK_CONFIG_TASKID_NULL;
224 }
225
226
227 /******************************************************************************/
228 /**
229  * @brief       タスク存在確認
230  * @details     指定したタスクIDのタスクが存在するか確認する。
231  * 
232  * @param[in]   taskId タスクID
233  * 
234  * @return      タスク有無
235  * @retval      true  タスク有
236  * @retval      false タスク無
237  */
238 /******************************************************************************/
239 bool TaskMngTaskCheckExist( MkTaskId_t taskId )
240 {
241     return gTaskTbl[ taskId ].used == CMN_USED;
242 }
243
244
245 /******************************************************************************/
246 /**
247  * @brief       アプリスタックアドレス取得
248  * @details     指定したタスクIDの終端アプリスタックアドレスを取得する。
249  * 
250  * @param[in]   taskId タスクID
251  *                  - MK_CONFIG_TASKID_MIN タスクID最小値
252  *                  - MK_CONFIG_TASKID_MAX タスクID最大値
253  * 
254  * @return      終端アプリスタックアドレス
255  */
256 /******************************************************************************/
257 void *TaskMngTaskGetAplStack( MkTaskId_t taskId )
258 {
259     /* アプリスタックアドレス */
260     return gTaskTbl[ taskId ].aplStackInfo.pBottomAddr;
261 }
262
263
264 /******************************************************************************/
265 /**
266  * @brief       コンテキスト取得
267  * @details     指定したタスクIDのコンテキストを取得する。
268  * 
269  * @param[in]   taskId タスクID
270  *                  - MK_CONFIG_TASKID_MIN タスクID最小値
271  *                  - MK_CONFIG_TASKID_MAX タスクID最大値
272  * 
273  * @return      コンテキスト
274  */
275 /******************************************************************************/
276 TaskMngTaskContext_t TaskMngTaskGetContext( MkTaskId_t taskId )
277 {
278     /* コンテキスト返却 */
279     return gTaskTbl[ taskId ].context;
280 }
281
282
283 /******************************************************************************/
284 /**
285  * @brief       カーネルスタックアドレス取得
286  * @details     指定したタスクIDの終端カーネルスタックアドレスを取得する。
287  * 
288  * @param[in]   taskId タスクID
289  *                  - MK_CONFIG_TASKID_MIN タスクID最小値
290  *                  - MK_CONFIG_TASKID_MAX タスクID最大値
291  * 
292  * @return      終端カーネルスタックアドレス
293  */
294 /******************************************************************************/
295 void *TaskMngTaskGetKernelStack( MkTaskId_t taskId )
296 {
297     /* カーネルスタックアドレス返却 */
298     return gTaskTbl[ taskId ].kernelStackInfo.pBottomAddr;
299 }
300
301
302 /******************************************************************************/
303 /**
304  * @brief       ページディレクトリID取得
305  * @details     指定したタスクIDのページディレクトリIDを取得する。
306  * 
307  * @param[in]   taskId タスクID
308  *                  - MK_CONFIG_TASKID_MIN タスクID最小値
309  *                  - MK_CONFIG_TASKID_MAX タスクID最大値
310  * 
311  * @return      ページディレクトリID
312  */
313 /******************************************************************************/
314 uint32_t TaskMngTaskGetPageDirId( MkTaskId_t taskId )
315 {
316     /* ページディレクトリID返却 */
317     return TaskMngProcGetPageDirId( gTaskTbl[ taskId ].pid );
318 }
319
320
321 /******************************************************************************/
322 /**
323  * @brief       プロセスID取得
324  * @details     指定したタスクIDのプロセスIDを取得する。
325  * 
326  * @param[in]   taskId タスクID
327  *                  - MK_CONFIG_TASKID_MIN タスクID最小値
328  *                  - MK_CONFIG_TASKID_MAX タスクID最大値
329  * 
330  * @return      プロセスID
331  * @retval      MK_CONFIG_PID_MIN プロセスID最小値
332  * @retval      MK_CONFIG_PID_MAX プロセスID最大値
333  */
334 /******************************************************************************/
335 MkPid_t TaskMngTaskGetPid( MkTaskId_t taskId )
336 {
337     /* プロセスID返却 */
338     return gTaskTbl[ taskId ].pid;
339 }
340
341
342 /******************************************************************************/
343 /**
344  * @brief       プロセスタイプ取得
345  * @details     指定したタスクIDのプロセスタイプを取得する。
346  * 
347  * @param[in]   taskId タスクID
348  *                  - MK_CONFIG_TASKID_MIN タスクID最小値
349  *                  - MK_CONFIG_TASKID_MAX タスクID最大値
350  * 
351  * @return      プロセスタイプ
352  * @retval      TASKMNG_PROC_TYPE_KERNEL カーネル
353  * @retval      TASKMNG_PROC_TYPE_DRIVER ドライバ
354  * @retval      TASKMNG_PROC_TYPE_SERVER サーバ
355  * @retval      TASKMNG_PROC_TYPE_USER   ユーザ
356  */
357 /******************************************************************************/
358 uint8_t TaskMngTaskGetType( MkTaskId_t taskId )
359 {
360     /* タスクタイプ返却 */
361     return TaskMngProcGetType( gTaskTbl[ taskId ].pid );
362 }
363
364
365 /******************************************************************************/
366 /**
367  * @brief       プロセスタイプ差取得
368  * @details     指定したタスクIDのプロセスタイプを比較し階層差を取得する。
369  * 
370  * @param[in]   taskId1 タスクID
371  * @param[in]   taskId2 タスクID
372  * 
373  * @return      プロセスタイプ差
374  * @retval      0 差0
375  * @retval      1 差1
376  * @retval      2 差2
377  * @retval      3 差3
378  */
379 /******************************************************************************/
380 uint8_t TaskMngTaskGetTypeDiff( MkTaskId_t taskId1,
381                                 MkTaskId_t taskId2  )
382 {
383     uint8_t type1;  /* プロセスタイプ */
384     uint8_t type2;  /* プロセスタイプ */
385     
386     /* プロセスタイプ取得 */
387     type1 = TaskMngProcGetType( taskId1 );
388     type2 = TaskMngProcGetType( taskId2 );
389     
390     return MLIB_BASIC_MAX( type1, type2 ) - MLIB_BASIC_MIN( type1, type2 );
391 }
392
393
394 /******************************************************************************/
395 /**
396  * @brief       タスク管理初期化
397  * @details     タスク管理サブモジュールの初期化を行う。
398  */
399 /******************************************************************************/
400 void TaskMngTaskInit( void )
401 {
402     /* デバッグトレースログ出力 */
403     DEBUG_LOG( "%s() start.", __func__ );
404     
405     /* タスク管理テーブル初期化 */
406     memset( gTaskTbl, 0, sizeof ( gTaskTbl ) );
407     
408     /* アイドルタスク設定 */
409     gTaskTbl[ TASKMNG_TASKID_IDLE ].used = CMN_USED;
410     gTaskTbl[ TASKMNG_TASKID_IDLE ].pid  = TASKMNG_PID_IDLE;
411     gTaskTbl[ TASKMNG_TASKID_IDLE ].tid  = 0;
412     
413     /* デバッグトレースログ出力 */
414     DEBUG_LOG( "%s() end.", __func__ );
415     
416     return;
417 }
418
419
420 /******************************************************************************/
421 /**
422  * @brief       コンテキスト設定
423  * @details     指定したタスクIDのコンテキストを設定する。
424  * 
425  * @param[in]   taskId    設定先タスクID
426  *                  - MK_CONFIG_TASKID_MIN タスクID最小値
427  *                  - MK_CONFIG_TASKID_MAX タスクID最大値
428  * @param[in]   *pContext コンテキスト
429  */
430 /******************************************************************************/
431 void TaskMngTaskSetContext( MkTaskId_t           taskId,
432                             TaskMngTaskContext_t *pContext )
433 {
434     /* コンテキスト設定 */
435     gTaskTbl[ taskId ].context = *pContext;
436     
437     return;
438 }
439
440
441 /******************************************************************************/