source: anotherchoice/tags/jsp-1.4.4-full-UTF8/config/windows/cpu_defs.c@ 26

Last change on this file since 26 was 26, checked in by ykominami, 10 years ago

initial

File size: 15.8 KB
Line 
1/*
2 * TOPPERS/JSP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 *
9 * 上記著作権者
10は,以下の (1)〜(4) の条件か,Free Software Foundation
11 * によってå…
12¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
13 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
14 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
16 * 利用と呼ぶ)することを無償で許諾する.
17 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
18 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
19 * スコード中に含まれていること.
20 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
21 * 用できる形で再é…
22å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
23å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
24 * 者
25マニュアルなど)に,上記の著作権表示,この利用条件および下記
26 * の無保証規定を掲載すること.
27 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
28 * 用できない形で再é…
29å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
30 * と.
31 * (a) 再é…
32å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
33マニュアルなど)に,上記の著
34 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
35 * (b) 再é…
36å¸ƒã®å½¢æ…
37‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
38 * 報告すること.
39 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
40 * 害からも,上記著作権者
41およびTOPPERSプロジェクトをå…
42è²¬ã™ã‚‹ã“と.
43 *
44 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
45お
46 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
47 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
48 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
49 *
50 * @(#) $Id: cpu_defs.c,v 1.14 2003/12/15 07:19:22 takayuki Exp $
51 */
52
53#define _WIN32_WINNT 0x400
54
55#include <s_services.h>
56#include <hal_msg.h>
57
58/*
59 * m68kっぽい割込みエミュレータ (Windows HAL)
60 */
61
62 /* 現在の割込みマスクレベル */
63unsigned int CurrentInterruptLevel;
64
65 /* 割込み管理テーブル */
66static struct tagInterruptLevel InterruptLevel[INT_NUMINTERRUPTS];
67
68 /* 割込みマスクレベルの有効範囲チェック */
69#define CHECK_IMS(x) ( (x) != 0 && (x) <= INT_NUMINTERRUPTS )
70
71 /* 例外管理テーブル */
72struct tagExceptionLevel ExceptionLevel[EXC_MAXITEMS];
73
74 /* 自分の前に登録されていた構造化例外ハンドラのアドレス */
75static LPTOP_LEVEL_EXCEPTION_FILTER AnotherExceptionFilter;
76
77/*
78 * システムå…
79¨ä½“のクリティカルセクション生成ルーチン
80 * ・どうしてCRITICAL_SECTIONを使うのをやめたのか
81 * -> Windowsのクリティカルセクションは、ITRONで言うところのディスパッチ禁止で実装
82しているらしく、
83 * 外部イベントで起床してしまったスレッドがクリティカルセクション内
84にいるスレッドの動作を
85 * 停止させてしまうことができるらしい。なのでCPUロックのつもりでクリティカルセクションを使っていると、
86 * 実はただのディスパッチ禁止なのでハンドラが起動してしまい、PrimaryThreadがSuspendThreadを発行してデッドロックしてしまう。
87 * この問題は時々
88発生する非常に厄介な問題だったが、まさかそんなことが原因だとは思いもよらなかった。
89 * WinProg系のMLでも「原因不明の不正同期がイヤならクリティカルセクションは使わないほうがよい」といっている。
90 */
91
92static HANDLE SystemMutex = NULL; //システムロック用のミューテックスオブジェクト
93static DWORD SystemMutexOwnerThreadID = 0; //システムロックを取得したスレッドのID
94static DWORD SystemMutexLastOwnerThreadID = 0; //最後にシステムロックを取得していたスレッドのID (デバッグ用)
95
96 /*
97 * enter_system_critical_section : システムのロック権を獲得する
98 * BOOL * lock : クッキー(自分が始めてロック権を獲得するとTRUEが返る)
99 */
100void enter_system_critical_section(BOOL * lock)
101{
102 if(SystemMutex != NULL && SystemMutexOwnerThreadID != GetCurrentThreadId())
103 {
104 WaitForSingleObject(SystemMutex, INFINITE);
105 if(lock != NULL)
106 *lock = TRUE;
107 SystemMutexOwnerThreadID = GetCurrentThreadId();
108 }else
109 {
110 if(lock != NULL)
111 *lock = FALSE;
112 }
113}
114
115 /*
116 * leave_system_critical_section : システムのロック権を開放する
117 * BOOL * lock : enter_system_critical_sectionで使用したクッキー
118 */
119void leave_system_critiacl_section(BOOL * lock)
120{
121 assert(lock != NULL);
122
123 if(*lock == TRUE)
124 {
125 SystemMutexLastOwnerThreadID = SystemMutexOwnerThreadID;
126 SystemMutexOwnerThreadID = 0;
127 if(SystemMutex != NULL)
128 ReleaseMutex(SystemMutex);
129 }
130}
131
132 /*
133 * wait_for_thread_suspension_completion : スレッドをロック権開放状æ…
134‹ã§åœæ­¢ã•ã›ã‚‹
135 */
136ER wait_for_thread_suspension_completion(HANDLE thread)
137{
138 BOOL lock;
139
140 if(thread == 0 || thread == NULL)
141 return E_PAR;
142
143 enter_system_critical_section(&lock);
144 SuspendThread(thread);
145 leave_system_critiacl_section(&lock);
146
147 return 0;
148}
149
150
151
152/*
153 * 次に実行すべき割込みハンドラのあるレベルを取得する
154 * ipl : 割込みマスクレベル
155 *
156 * 割り込みレベルマスクがiplまで下がったときに、次に動かすべき割込みを選択する。
157 * マスクレベルよりも上位の割込みの場合、ペンディングされた要求 or 既に実行が
158 * 始まっているハンドラ を実行する。マスクレベル以下の場合、既に動いている
159 * ハンドラがある場合のみ実行する。何もない場合は0を返す。
160 */
161static unsigned int
162isns_int( unsigned int ipl )
163{
164 unsigned int result = INT_NUMINTERRUPTS;
165
166 if((CPUStatus & CPU_STAT_LOCK) != 0)
167 return 0;
168
169 while(result > ipl)
170 {
171 result --;
172 if( (InterruptLevel[result].Flags & (INT_STAT_PENDING|INT_STAT_RUNNING)) != 0)
173 return result+1;
174 }
175 while(result > 0)
176 {
177 result --;
178 if( (InterruptLevel[result].Flags & INT_STAT_RUNNING) != 0)
179 return result+1;
180 }
181 return 0;
182}
183
184static DWORD WINAPI
185InterruptHandlerWrapper(LPVOID param)
186{
187 unsigned int i;
188 unsigned int PrevLevel;
189 BOOL systemLock;
190
191 struct tagInterruptLevel * intlv = (struct tagInterruptLevel *)param;
192
193 TlsAlloc();
194
195 kprintf(("InterruptHandlerWrapper (%d) : start\n", (intlv - InterruptLevel) + 1 ));
196
197 while(1==1)
198 {
199 /* 割込み前処理 */
200
201 set_logcontrol((intlv->Flags & INT_MOD_LOGMASK) != 0);
202 LOG_INH_ENTER((intlv - InterruptLevel)+1);
203
204 assert((CPUStatus & CPU_STAT_LOCK) == 0);
205 enter_system_critical_section(&systemLock);
206 PrevLevel = CurrentInterruptLevel;
207 CurrentInterruptLevel = (unsigned int)(intlv - InterruptLevel)+1;
208 intlv->Flags &= ~INT_STAT_PENDING;
209 intlv->Flags |= INT_STAT_RUNNING;
210 leave_system_critiacl_section(&systemLock);
211
212 ( (void (*)(void) )(intlv->Routine))();
213
214 /* 割込み後処理
215 * ここで一気にPrevLevelまで落としてはいけない.
216 * 割り込みのå…
217¥ã‚Šæ–¹ã«ã‚ˆã£ã¦ã¯ã€å„ªå…
218ˆåº¦ã®ä½Žã„割込みの脱出処理が優å…
219ˆåº¦ã®é«˜ã„割り込みの進å…
220¥å‡¦ç†ã®ç›´å¾Œã«å®Ÿè¡Œã•ã‚Œã€
221 * 運が悪いと優å…
222ˆåº¦ã®é«˜ã„割込みがCurrentInterruptLevel = 0の状æ…
223‹ã§èµ°ã£ã¦ã—まうことになる。
224 */
225 enter_system_critical_section(&systemLock);
226 intlv->Flags &= ~INT_STAT_RUNNING;
227 i = isns_int(PrevLevel);
228 if(i > PrevLevel)
229 CurrentInterruptLevel = i - 1;
230 else
231 CurrentInterruptLevel = PrevLevel;
232 leave_system_critiacl_section(&systemLock);
233
234 LOG_INH_LEAVE((intlv - InterruptLevel)+1);
235
236 /* 次の割込みを処理するように通知 */
237 HALInterruptRequestAndWait();
238 }
239
240 kprintf(("InterruptHandlerWrapper (%d) : exit\n", (intlv - InterruptLevel) + 1 ));
241
242 ExitThread(0);
243 return 0;
244}
245
246BOOL
247def_int(unsigned int ims, void * rtn)
248{
249 BOOL lock;
250
251 if(!CHECK_IMS(ims) || rtn == NULL)
252 return FALSE;
253
254 kprintf(("def_int : [ims:%d]\n", ims));
255
256 ims--;
257
258 enter_system_critical_section(&lock);
259 if(InterruptLevel[ims].ThreadHandle != NULL)
260 {
261 TerminateThread(InterruptLevel[ims].ThreadHandle,0);
262 CloseHandle(InterruptLevel[ims].ThreadHandle);
263 }
264 InterruptLevel[ims].Routine = rtn;
265 InterruptLevel[ims].ThreadHandle = CreateThread(NULL,0,InterruptHandlerWrapper,(LPVOID)&InterruptLevel[ims],CREATE_SUSPENDED,&InterruptLevel[ims].ThreadID);
266 leave_system_critiacl_section(&lock);
267
268 return TRUE;
269}
270
271BOOL
272ini_int(void)
273{
274 int i;
275
276 kprintf(("ini_int : [Start]\n"));
277
278 SystemMutex = CreateMutex(NULL,TRUE,NULL);
279
280 for(i=0;i<INT_NUMINTERRUPTS;i++)
281 {
282 InterruptLevel[i].Routine = (void *)0l;
283 InterruptLevel[i].ThreadHandle = NULL;
284 InterruptLevel[i].ThreadID = 0;
285 InterruptLevel[i].Flags = INT_MOD_LOGMASK;
286 }
287
288 /* 初期起動でCPUロック状æ…
289‹ã¸ç§»è¡Œã•ã›ã‚‹ */
290 CurrentInterruptLevel = 0; //割込みマスクはå…
291¨è¨±å¯
292 CPUStatus |= CPU_STAT_LOCK; //CPUで割込み禁止に
293
294 ReleaseMutex(SystemMutex);
295
296 kprintf(("ini_int : [Exit]\n"));
297
298 return TRUE;
299}
300
301void
302fin_int(void)
303{
304 int i;
305 HANDLE work;
306
307 kprintf(("fin_int : [Start]\n"));
308
309 enter_system_critical_section(NULL);
310
311 for(i=0;i<INT_NUMINTERRUPTS;i++)
312 {
313 if(InterruptLevel[i].ThreadHandle != NULL)
314 {
315 TerminateThread(InterruptLevel[i].ThreadHandle,0);
316 CloseHandle(InterruptLevel[i].ThreadHandle);
317 }
318 InterruptLevel[i].Routine = (void *)0l;
319 InterruptLevel[i].ThreadHandle = NULL;
320 InterruptLevel[i].ThreadID = 0;
321 InterruptLevel[i].Flags = 0;
322 }
323 CurrentInterruptLevel = 0;
324
325 /* CloseHandle(SystemMutex), SystemMutex = INVALID_HANDLE; を安å…
326¨ã«ã‚„ã‚‹ */
327 work = SystemMutex;
328 SystemMutex = NULL;
329 CloseHandle(work);
330
331 //これ以降はCPUロック状æ…
332‹ã ã¨æ€ã„込む
333 CPUStatus |= CPU_STAT_LOCK;
334
335 kprintf(("fin_int : [Exit]\n"));
336}
337
338BOOL
339ras_int(unsigned int ims)
340{
341 BOOL lock;
342 BOOL result = TRUE;
343
344 if(!CHECK_IMS(ims))
345 return FALSE;
346
347 ims --;
348
349 enter_system_critical_section(&lock);
350 if(InterruptLevel[ims].ThreadHandle == NULL)
351 {
352 result = FALSE;
353 }else
354 InterruptLevel[ims].Flags |= INT_STAT_PENDING;
355 leave_system_critiacl_section(&lock);
356 return result;
357}
358
359unsigned int
360sns_int( void )
361{
362 BOOL lock;
363 int result;
364
365 if(sense_lock() == TRUE)
366 return 0;
367
368 enter_system_critical_section(&lock);
369 result = isns_int(CurrentInterruptLevel);
370 leave_system_critiacl_section(&lock);
371 return result;
372}
373
374HANDLE
375sch_int( void )
376{
377 BOOL lock;
378 HANDLE result;
379 unsigned int level;
380
381 if(sense_lock() == TRUE)
382 return NULL;
383
384 enter_system_critical_section(&lock);
385 level = isns_int(CurrentInterruptLevel);
386 if(level != 0)
387 {
388 result = InterruptLevel[level-1].ThreadHandle;
389 }else
390 result = NULL;
391 leave_system_critiacl_section(&lock);
392
393 return result;
394}
395
396DWORD LockerThreadID = 0;
397
398ER
399ena_int(unsigned int ims)
400{
401 BOOL lock;
402 int i;
403
404 enter_system_critical_section(&lock);
405 i = isns_int(CurrentInterruptLevel);
406 CPUStatus &= ~CPU_STAT_LOCK;
407 LockerThreadID = 0;
408 leave_system_critiacl_section(&lock);
409
410 if(i != 0)
411 HALInterruptRequest(0);
412
413 return 0 /*E_OK*/;
414}
415
416ER
417dis_int(unsigned int ims)
418{
419 BOOL lock;
420
421 enter_system_critical_section(&lock);
422 CPUStatus |= CPU_STAT_LOCK;
423 if(LockerThreadID == 0)
424 {
425 LockerThreadID = GetCurrentThreadId();
426 }else
427 {
428 DWORD newThreadID = GetCurrentThreadId();
429 LockerThreadID = GetCurrentThreadId(); //ブレーク置き場
430 }
431 leave_system_critiacl_section(&lock);
432
433 return 0;
434}
435
436ER
437chg_ims(unsigned int ims)
438{
439 BOOL lock;
440 int i;
441
442 //chg_ims は ims==0 を許す
443 if(ims != 0 && !CHECK_IMS(ims))
444 return -17 /*E_PAR*/;
445
446 enter_system_critical_section(&lock);
447 CurrentInterruptLevel = ims;
448 if(CurrentInterruptLevel == INT_NUMINTERRUPTS)
449 CPUStatus |= CPU_STAT_LOCK;
450 else
451 CPUStatus &= ~CPU_STAT_LOCK;
452 i = isns_int(ims);
453 leave_system_critiacl_section(&lock);
454
455 if(i != 0)
456 HALInterruptRequest(0);
457
458 return 0 /*E_OK*/;
459}
460
461ER
462get_ims(unsigned int *p_ims)
463{
464 BOOL lock;
465
466 if(p_ims == (void *)0l)
467 return -17 /*E_PAR*/;
468
469 enter_system_critical_section(&lock);
470 if((CPUStatus & CPU_STAT_LOCK) != 0)
471 *p_ims = INT_NUMINTERRUPTS;
472 else
473 *p_ims = CurrentInterruptLevel;
474 leave_system_critiacl_section(&lock);
475 return 0 /*E_OK*/;
476}
477
478ER
479vget_ims(unsigned int *p_ims)
480{
481 BOOL lock;
482
483 if(p_ims == (void *)0l)
484 return -17 /*E_PAR*/;
485
486 enter_system_critical_section(&lock);
487 *p_ims = CurrentInterruptLevel;
488 leave_system_critiacl_section(&lock);
489 return 0 /*E_OK*/;
490}
491
492/*
493 * 最上位レベルWindows構造化例外ハンドラ
494 */
495
496LONG WINAPI
497HALExceptionHandler( EXCEPTION_POINTERS * exc )
498{
499 int i;
500 int result;
501
502 if((CPUStatus & CPU_STAT_EXC) == 0)
503 CPUStatus |= CPU_STAT_DOUBLEFAULT;
504
505 /* 馬鹿サーチ (空間がせまいから...) */
506 CPUStatus |= CPU_STAT_EXC;
507 for(i=0;i<EXC_MAXITEMS;i++)
508 {
509 if(ExceptionLevel[i].ExceptionCode == exc->ExceptionRecord->ExceptionCode)
510 {
511 result = EXCEPTION_CONTINUE_SEARCH;
512
513 LOG_EXC_ENTER(i);
514 ( * ((void (*)(void *,int *))ExceptionLevel[i].Routine)) (exc,&i);
515 LOG_EXC_LEAVE(i);
516
517 CPUStatus &= ~CPU_STAT_EXC;
518 return result;
519 }
520 }
521 CPUStatus &= ~CPU_STAT_EXC;
522 return EXCEPTION_CONTINUE_SEARCH;
523}
524
525BOOL
526ini_exc(void)
527{
528 int i;
529
530 for(i=0;i<EXC_MAXITEMS;i++)
531 {
532 ExceptionLevel[i].ExceptionCode = 0;
533 ExceptionLevel[i].Routine = 0l;
534 }
535
536 AnotherExceptionFilter = SetUnhandledExceptionFilter(HALExceptionHandler);
537
538 return TRUE;
539}
540
541void
542fin_exc(void)
543{
544 SetUnhandledExceptionFilter(AnotherExceptionFilter);
545}
546
547BOOL
548def_exc(DWORD exc, void * routine)
549{
550 int j;
551 int i;
552
553 /* 解除ルーチン */
554 if(routine == 0l)
555 {
556 kprintf(("def_exc : [UNREG] 0x%08x\n", exc));
557
558 for(i=0;i<EXC_MAXITEMS;i++)
559 if(ExceptionLevel[i].ExceptionCode == exc)
560 {
561 ExceptionLevel[i].ExceptionCode = 0;
562 ExceptionLevel[i].Routine = 0;
563 return TRUE;
564 }
565 return FALSE;
566 }
567
568 /* 登録ルーチン */
569
570 kprintf(("def_exc : [REG] 0x%08x\n", exc));
571
572 j = EXC_MAXITEMS;
573 for(i=0;i<EXC_MAXITEMS;i++)
574 {
575 if(ExceptionLevel[i].ExceptionCode != 0)
576 {
577 /* 登録しようとしている番号が既に登録されていないかどうか調べる */
578 if(ExceptionLevel[i].ExceptionCode == exc)
579 return FALSE;
580 }else
581 {
582 /* 空き番号の最小を覚える */
583 if(j > i)
584 j = i;
585
586 /* 既登録チェックがあるので、ここでbreakしてはダメ */
587 }
588 }
589
590 FatalAssertion(i == EXC_MAXITEMS, "No available exception slots left.");
591
592 //This sequence will never change
593 ExceptionLevel[j].Routine = routine;
594 ExceptionLevel[j].ExceptionCode = exc;
595
596 return TRUE;
597}
598
599ER set_intlogmask( unsigned int ims, BOOL mask )
600{
601 BOOL lock;
602
603 if( !CHECK_IMS(ims) )
604 return FALSE;
605
606 -- ims;
607
608 enter_system_critical_section(&lock);
609 if(mask == TRUE)
610 InterruptLevel[ims].Flags |= INT_MOD_LOGMASK;
611 else
612 InterruptLevel[ims].Flags &= ~INT_MOD_LOGMASK;
613 leave_system_critiacl_section(&lock);
614
615 return TRUE;
616}
617
618unsigned int current_timer_clock_unit = TIMER_CLOCK_WINDOWS;
619
620ER set_clk(unsigned int clk)
621{
622 BOOL lock;
623
624 if(clk == 0)
625 clk = TIMER_CLOCK_WINDOWS;
626
627 hw_timer_terminate();
628 enter_system_critical_section(&lock);
629 current_timer_clock_unit = clk;
630 leave_system_critiacl_section(&lock);
631 hw_timer_initialize();
632
633 return E_OK;
634}
Note: See TracBrowser for help on using the repository browser.