source: anotherchoice/tags/jsp-1.4.4-full-UTF8/config/powerpc32/cpu_support.S@ 26

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

initial

File size: 57.9 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-2004 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2001-2004 by Industrial Technology Institute,
9 * Miyagi Prefectural Government, JAPAN
10 *
11 * 上記著作権者
12は,以下の (1)〜(4) の条件か,Free Software Foundation
13 * によってå…
14¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
15 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
16 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
17å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
18 * 利用と呼ぶ)することを無償で許諾する.
19 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
20 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
21 * スコード中に含まれていること.
22 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
23 * 用できる形で再é…
24å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
25å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
26 * 者
27マニュアルなど)に,上記の著作権表示,この利用条件および下記
28 * の無保証規定を掲載すること.
29 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
30 * 用できない形で再é…
31å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
32 * と.
33 * (a) 再é…
34å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
35マニュアルなど)に,上記の著
36 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
37 * (b) 再é…
38å¸ƒã®å½¢æ…
39‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
40 * 報告すること.
41 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
42 * 害からも,上記著作権者
43およびTOPPERSプロジェクトをå…
44è²¬ã™ã‚‹ã“と.
45 *
46 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
47お
48 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
49 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
50 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
51 *
52 * @(#) $Id: cpu_support.S,v 1.2 2004/10/07 17:10:56 honda Exp $
53 */
54
55/*
56 * プロセッサ依存モジュール アセンブリ言語部(PowerPC用)
57 *     カーネル内
58部で使用する定義
59 */
60
61#define _MACRO_ONLY
62#include "jsp_kernel.h"
63#include "offset.h"
64
65/*
66 * TCB構造体のオフセットのチェック
67 *   15ビットに収まっていないと符号拡張が起こり、
68 *   期待
69する動作にならない。
70 */
71#define CHECK_OFFSET(offset) (((offset)&~0x8fff) != 0)
72#if CHECK_OFFSET(TCB_pc) || CHECK_OFFSET(TCB_sp) \
73 || CHECK_OFFSET(TCB_enatex) || CHECK_OFFSET(TCB_texptn) \
74 || CHECK_OFFSET(TCB_tinib) || CHECK_OFFSET(TINIB_task) \
75 || CHECK_OFFSET(TINIB_exinf)
76 ここでコンパイルエラー
77#endif
78
79
80/*
81 * 例外処理の前半で退避するレジスタ数
82 *   汎用レジスタ:gpr0-1,3-12
83 *   特殊レジスタ:LR,CTR,XER,SRR0,SRR1
84 */
85#define NUM_REG 17
86
87/* レジスタを待
88避するのに必
89要なバイト数 */
90#define GPR0_12_SPRG_AREA_SIZE (NUM_REG*4 + 4)
91 /* +4は例外要因番号を保存するスペース */
92 /* 注意:4バイト境界になっている */
93
94#define GPR13_31_AREA_SIZE (19*4) /* gpr13-31 */
95
96 /*
97 * 注意
98 *   MPC860は浮動小数点レジスタがないため、この部分は
99 *   テストされていない
100 */
101#ifdef SUPPORT_FLOATING_POINT_REG
102/* ハードウェアで浮動小数点レジスタが実装
103されている場合 */
104#define FPR_AREA_SIZE (32*8+8) /* fpr0-31,FPSCR */
105#define FPR0_13_AREA_SIZE (14*8+8) /* fpr0-14,FPSCR */
106#define FPR14_31_AREA_SIZE (18*8) /* fpr15-31 */
107
108#else /* SUPPORT_FLOATING_POINT_REG */
109/* ハードウェアで浮動小数点レジスタが実装
110されていない場合 */
111#define FPR_AREA_SIZE 0 /* fpr0-31,FPSCR */
112#define FPR0_13_AREA_SIZE 0 /* fpr0-14,FPSCR */
113#define FPR14_31_AREA_SIZE 0 /* fpr15-31 */
114#endif /* SUPPORT_FLOATING_POINT_REG */
115
116/*
117 * 割込み、CPU例外受付時のレジスタの待
118避
119 *  注意
120 *   浮動小数点レジスタの待
121避はディスパッチ呼び出しがあるとき
122 *   (タスクスイッチの可能性があるとき)のみ行う。
123 *   割込みハンドラやCPU例外ハンドラ内
124で浮動小数点レジスタを
125 *   使用する場合は、各ハンドラ内
126で浮動小数点レジスタの待
127避/
128 *   復å…
129ƒã‚’行うこと。
130 *   
131 *   r4のSRR1はCPU例外発生時のCPUロック状æ…
132‹åˆ¤åˆ¥ã«ã‚‚使用する。
133 *   
134 */
135#define SAVE_GPR0_12_SPRG \
136 subi sp, sp, GPR0_12_SPRG_AREA_SIZE; \
137 stw r0, 0*4(sp); \
138 stw r3, 1*4(sp); \
139 stw r4, 2*4(sp); \
140 stw r5, 3*4(sp); \
141 stw r6, 4*4(sp); \
142 stw r7, 5*4(sp); \
143 stw r8, 6*4(sp); \
144 stw r9, 7*4(sp); \
145 stw r10, 8*4(sp); \
146 stw r11, 9*4(sp); \
147 stw r12,10*4(sp); \
148 mfspr r3, SRR0; \
149 stw r3, 11*4(sp); \
150 mfspr r4, SRR1; \
151 stw r4, 12*4(sp); \
152 mfspr r5, LR; \
153 stw r5, 13*4(sp); \
154 mfspr r6, CTR; \
155 stw r6, 14*4(sp); \
156 mfcr r7; /* CR */ \
157 stw r7, 15*4(sp); \
158 mfspr r8, XER; \
159 stw r8, 16*4(sp)
160
161
162/*
163 * 割込み、CPU例外受付時のレジスタの復å…
164ƒ
165 *   (gpr0-1,3-12, 特殊レジスタの復å…
166ƒï¼‰
167 *
168 *   ディスパッチ呼び出しがない場合
169 */
170#define LOAD_R0_12_SPRG \
171 /* 特殊レジスタの復å…
172ƒ */ \
173 lwz r3, 11*4(sp); \
174 mtspr SRR0, r3; \
175 lwz r4, 12*4(sp); \
176 mtspr SRR1, r4; \
177 lwz r5, 13*4(sp); \
178 mtspr LR, r5; \
179 lwz r6, 14*4(sp); \
180 mtspr CTR, r6; \
181 lwz r7, 15*4(sp); \
182 mtcr r7; /* CR */ \
183 lwz r8, 16*4(sp); \
184 mtspr XER, r8; \
185 /* 汎用レジスタgpr0-1,3-12の復å…
186ƒ */ \
187 lwz r0, 0*4(sp); \
188 lwz r3, 1*4(sp); \
189 lwz r4, 2*4(sp); \
190 lwz r5, 3*4(sp); \
191 lwz r6, 4*4(sp); \
192 lwz r7, 5*4(sp); \
193 lwz r8, 6*4(sp); \
194 lwz r9, 7*4(sp); \
195 lwz r10, 8*4(sp); \
196 lwz r11, 9*4(sp); \
197 lwz r12, 10*4(sp)
198 /* マクロ定義ここまで */
199
200
201/*
202 * CPU例外のå…
203¥å£å‡¦ç†ã®å†…
204、各例外ベクタにé…
205ç½®ã™ã‚‹å‰åŠéƒ¨åˆ†
206 *
207 *  マクロ引数
208 *   exc_no:例外番号
209 *  
210 *  レジスタ割り当て
211 *   SPRG2:exc_table(CPU例外擬似ベクタテーブルのå…
212ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹ï¼‰
213 *   CTR:C言語ルーチンのå…
214ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹
215 *   r3:CPU例外ハンドラの引数
216 *   r4:SRR1のコピー
217 */
218#define MAKE_EXCEPTION_ENTRY(exe_no) \
219 SAVE_GPR0_12_SPRG; /* スクラッチレジスタの待
220避 */ \
221 /* (r4にSRR1がコピーされる) */ \
222 mr r3, sp; /* CPU例外ハンドラの引数設定 */ \
223 /* C言語ルーチンのå…
224ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹è¨­å®š */ \
225 mfspr r5, SPRG2; /* r5←SPRG2:exc_table */ \
226 /* 擬似ベクタテーブル読み出し */ \
227 lwz r6, (exe_no<<2)(r5); \
228 li r7, exe_no; /* 例外要因番号の保存 */ \
229 stw r7, NUM_REG*4(sp) /* (cpu_experr()で使用) */
230
231/*
232 * CPU例外のå…
233¥å£å‡¦ç†ã®å†…
234、各例外ベクタにé…
235ç½®ã•ã‚Œãªã„
236 * 前半部分への分岐
237 *
238 * 例外ベクタのé…
239ç½®ã«ã‚ˆã£ã¦ã¯b命令による分岐(前後0x07ff,ffff)で
240 * 届かない場合がある。この場合は絶対番地を指定して分岐する。
241 */
242#ifdef ABSOLUTE_JUMP_EXC_ENTRY
243#define JUMP_EXC_ENTRY(label) \
244 LI32(r8, label); \
245 mtctr r8; \
246 bctr
247
248#else /* ABSOLUTE_JUMP_EXE_ENTRY */
249#define JUMP_EXC_ENTRY(label) b label
250#endif /* ABSOLUTE_JUMP_EXE_ENTRY */
251
252/*
253 * 例外ベクタの定義
254 */
255
256#ifndef IBM_PPC_EMB_ENV
257/*
258 * オリジナルのPowerPCアーキテクチャの場合
259 *   モトローラMPCシリーズ、IPM PowerPC6xx/7xxシリーズは
260 *   こちらに該当する。
261 */
262
263/*
264 * 例外ベクタテーブルのå…
265ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹
266 *   マシンステータスレジスタMSRのIPビットが
267 *     0のとき:0x0000,0000番地
268 *     1のとき:0xfff0,0000番地
269 *    からのオフセットになる
270 */
271#define EXCEPTION_VECTOR_BASE 0x100
272
273/*
274 * システムリセット例外
275 */
276 .section ".exception_vector","rxai"
277 .align 2
278 .org 0x100 - EXCEPTION_VECTOR_BASE
279
280System_reset_exception:
281 JUMP_EXC_ENTRY(start) /* スタートアップルーチン */
282
283/*
284 * マシン・チェック例外
285 */
286 .org 0x200 - EXCEPTION_VECTOR_BASE
287
288Machine_check_exception:
289 MAKE_EXCEPTION_ENTRY(EXC_NO_MACHINE_CHECK)
290 JUMP_EXC_ENTRY(Exception_Entry)
291
292/*
293 * DSI例外
294 *  データ・メモリ・アクセス
295 *  データTLBエラー/ミス
296 */
297 .org 0x300 - EXCEPTION_VECTOR_BASE
298
299DSI_exception:
300 MAKE_EXCEPTION_ENTRY(EXC_NO_DSI)
301 JUMP_EXC_ENTRY(Exception_Entry)
302
303/*
304 * ISI例外
305 *  命令フェッチ
306 *  命令TLBエラー/ミス
307 */
308 .org 0x400 - EXCEPTION_VECTOR_BASE
309
310ISI_exception:
311 MAKE_EXCEPTION_ENTRY(EXC_NO_ISI)
312 JUMP_EXC_ENTRY(Exception_Entry)
313
314
315/*
316 * 外部割込み
317 *  すべての外部割り込みで同じ番地に分岐する
318 */
319 .org 0x500 - EXCEPTION_VECTOR_BASE
320
321External_interrupt:
322 SAVE_GPR0_12_SPRG /* レジスタの待
323避 */
324 /*
325 * 本当はここで続きの処理を行いたいが、0x100バイト(64命令)後ろに
326 * アライメント例外の処理がå…
327¥ã‚‹ãŸã‚ã€ç¶šãã¯External_interrupt_1:で行
328 * う。
329 */
330 JUMP_EXC_ENTRY(External_interrupt_1)
331
332/*
333 * アライメント例外
334 */
335 .org 0x600 - EXCEPTION_VECTOR_BASE
336
337Alignment_exception:
338 MAKE_EXCEPTION_ENTRY(EXC_NO_ALIGNMENT)
339 JUMP_EXC_ENTRY(Exception_Entry)
340
341/*
342 * プログラム例外
343 *   Floating point enabled
344 *   Illegal instruction
345 *   Privileged instruction
346 *   Trap instruction
347 */
348 .org 0x700 - EXCEPTION_VECTOR_BASE
349
350Program_exception:
351 MAKE_EXCEPTION_ENTRY(EXC_NO_PROGRAM)
352 JUMP_EXC_ENTRY(Exception_Entry)
353
354/*
355 * 浮動小数点使用不可
356 */
357 .org 0x800 - EXCEPTION_VECTOR_BASE
358
359Floating_point_unavailable:
360 MAKE_EXCEPTION_ENTRY(EXC_NO_FLOATING_POINT_UNAVAILABLE)
361 JUMP_EXC_ENTRY(Exception_Entry)
362
363/*
364 * デクリメンタ例外
365 */
366 .org 0x900 - EXCEPTION_VECTOR_BASE
367
368Decrementer_exception:
369 MAKE_EXCEPTION_ENTRY(EXC_NO_DECREMENTER)
370 JUMP_EXC_ENTRY(Exception_Entry)
371
372/*
373 * インプリメンテーション固有の例外0x00a00
374 */
375#ifdef IMPLEMENT_EXCEPTION_00A00
376 .org 0xa00 - EXCEPTION_VECTOR_BASE
377
378Implementation_exception_00a00:
379 MAKE_EXCEPTION_ENTRY(EXC_NO_IMPLEMENT_EXCEPTION_00A00)
380 JUMP_EXC_ENTRY(Exception_Entry)
381
382#endif /* IMPLEMENT_EXCEPTION_00A00 */
383
384
385/*
386 * システムコール
387 */
388 .org 0xc00 - EXCEPTION_VECTOR_BASE
389
390System_call:
391 MAKE_EXCEPTION_ENTRY(EXC_NO_SYSTEM_CALL)
392 JUMP_EXC_ENTRY(Exception_Entry)
393
394/*
395 * トレース(オプション)
396 */
397 .org 0xd00 - EXCEPTION_VECTOR_BASE
398
399Trace_exception:
400 MAKE_EXCEPTION_ENTRY(EXC_NO_TRACE)
401 JUMP_EXC_ENTRY(Exception_Entry)
402
403
404/*
405 * 浮動小数点補助
406 */
407 .org 0xe00 - EXCEPTION_VECTOR_BASE
408
409Floating_point_assist:
410 MAKE_EXCEPTION_ENTRY(EXC_NO_FLOATING_POINT_ASSIST)
411 JUMP_EXC_ENTRY(Exception_Entry)
412
413/*
414 * インプリメンテーション専用の処理 0x01000-0x2ffff
415 * インプリメンテーション固有の例外ベクタ(1つとは限らない)や
416 * 他の用途に使用される
417 */
418#ifdef IMPLEMENT_EXCEPTION_01000_PROC
419 .org 0x1000 - EXCEPTION_VECTOR_BASE
420
421 IMPLEMENT_EXCEPTION_01000_PROC
422
423#endif /* IMPLEMENT_EXCEPTION_01000_PROC */
424
425#else /* IBM_PPC_EMB_ENV */
426
427/*
428 * The IBM PowerPC Embedded Environmentの場合
429 *  IBM系PowerPC40xシリーズ対応
430 */
431
432/*
433 * 例外ベクタテーブルのå…
434ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹
435 *   The IBM PowerPC Embedded Environmentの場合
436 *    ・例外ベクタのå…
437ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹ã¯EVPRレジスタで設定する
438 *    ・マシンステータスレジスタMSRのIPビットがない
439 */
440#define EXCEPTION_VECTOR_BASE 0x100
441
442/*
443 * Critical Interrupt
444 *  オフセット:0x100
445 *  Critical Interruptはインプリメンテーション依存なので
446 *  処理内
447容はマクロ定義しておく。
448 *   マクロ名:CRITICAL_INTERRUPT_EXCEPTION_PROC
449 *  この処理内
450容は0x100バイトを超
451えてはいけない。
452 *  (超
453える場合は残りの部分を別の場所にé…
454ç½®ã—て、
455 *   そこに分岐すること)
456 *
457 *  Critical Interruptはカーネル管理外の例外とする。
458 *  (この処理ルーチン内
459でサービスコールを使用しない。)
460 *
461 *  例外クラス:Critical
462 *   リターン命令はrfci(Return From Critical Interrupt)
463 *   を用いる。
464 */
465 .section ".exception_vector","rxai"
466 .align 2
467 .org 0x100 - EXCEPTION_VECTOR_BASE
468
469Critical_Interrupt_exception:
470 CRITICAL_INTERRUPT_EXCEPTION_PROC
471 /* 注意:リターン命令はrfci(Return From Critical Interrupt) */
472
473/*
474 * マシン・チェック例外
475 *  この処理内
476容は0x100バイトを超
477えてはいけない。
478 *  (超
479える場合は残りの部分を別の場所にé…
480ç½®ã—て、
481 *   そこに分岐すること)
482 *
483 *  カーネル管理外の例外とする。
484 *  (この処理ルーチン内
485でサービスコールを使用しない。)
486 *
487 *  例外クラス:Critical
488 *   リターン命令はrfci(Return From Critical Interrupt)
489 *   を用いる。
490 */
491 .org 0x200 - EXCEPTION_VECTOR_BASE
492
493Machine_check_exception:
494 MACHINE_CHECK_PROC
495
496/*
497 * Data storage例外
498 *  データ・メモリ・アクセス
499 */
500 .org 0x300 - EXCEPTION_VECTOR_BASE
501
502DSI_exception:
503 MAKE_EXCEPTION_ENTRY(EXC_NO_DATA_STORAGE)
504 JUMP_EXC_ENTRY(Exception_Entry)
505
506/*
507 * Instruction storage例外
508 *  命令フェッチ
509 */
510 .org 0x400 - EXCEPTION_VECTOR_BASE
511
512ISI_exception:
513 MAKE_EXCEPTION_ENTRY(EXC_NO_INSTRUCTION_STORAGE)
514 JUMP_EXC_ENTRY(Exception_Entry)
515
516
517/*
518 * 外部割込み
519 *  すべての外部割り込みで同じ番地に分岐する
520 */
521 .org 0x500 - EXCEPTION_VECTOR_BASE
522
523External_interrupt:
524 SAVE_GPR0_12_SPRG /* レジスタの待
525避 */
526 /*
527 * 本当はここで続きの処理を行いたいが、0x100バイト(64命令)後ろに
528 * アライメント例外の処理がå…
529¥ã‚‹ãŸã‚ã€ç¶šãã¯External_interrupt_1:で行
530 * う。
531 */
532 JUMP_EXC_ENTRY(External_interrupt_1)
533
534/*
535 * アライメント例外
536 */
537 .org 0x600 - EXCEPTION_VECTOR_BASE
538
539Alignment_exception:
540 MAKE_EXCEPTION_ENTRY(EXC_NO_ALIGNMENT)
541 JUMP_EXC_ENTRY(Exception_Entry)
542
543/*
544 * プログラム例外
545 *   Illegal instruction
546 *   Privileged instruction
547 *   Trap instruction
548 *   Floating point enabled
549 *   Floating point unimplemented
550 *   Auxiliary processor unavailable
551 *   Auxiliary processor enabled
552 */
553 .org 0x700 - EXCEPTION_VECTOR_BASE
554
555Program_exception:
556 MAKE_EXCEPTION_ENTRY(EXC_NO_PROGRAM)
557 JUMP_EXC_ENTRY(Exception_Entry)
558
559/*
560 * 浮動小数点使用不可
561 */
562#ifdef SUPPORT_IBM_PPC_EMB_APU /* APUを持つ機種は利用可能 */
563 .org 0x800 - EXCEPTION_VECTOR_BASE
564
565Floating_point_unavailable:
566 MAKE_EXCEPTION_ENTRY(EXC_NO_FLOATING_POINT_UNAVAILABLE)
567 JUMP_EXC_ENTRY(Exception_Entry)
568
569#endif /* SUPPORT_IBM_PPC_EMB_APU */
570
571
572/*
573 * システムコール
574 */
575 .org 0xc00 - EXCEPTION_VECTOR_BASE
576
577System_call:
578 MAKE_EXCEPTION_ENTRY(EXC_NO_SYSTEM_CALL)
579 JUMP_EXC_ENTRY(Exception_Entry)
580
581/*
582 * インプリメンテーション専用の処理(オフセット 0xd00-0xff0)
583 * インプリメンテーション固有の例外ベクタ
584 *
585 *   オフセットの指定方法に注意すること。
586 *  å…
587·ä½“的には
588 * .org オフセット - EXCEPTION_VECTOR_BASE
589 *   のように指定する。詳しくは他の例外要因の該当個所を参ç…
590§ã€‚
591 * 例えば、PowerPC405ではオフセット0xf20に
592 * APU Unavailable例外の処理をé…
593ç½®ã™ã‚‹
594 */
595#ifdef IMPLEMENT_EXCEPTION_D00_PROC
596
597 IMPLEMENT_EXCEPTION_D00_PROC
598
599#endif /* IMPLEMENT_EXCEPTION_D00_PROC */
600
601/*
602 * Programmable Interval timer
603 *  0x10バイトしか領域が割り当てられていないので注意
604 */
605 .org 0x1000 - EXCEPTION_VECTOR_BASE
606
607Programmable_Interval_timer:
608 PROGRAMMABLE_INTERVAL_TIMER_PROC
609
610/*
611 * Fixed Interval timer
612 *  0x10バイトしか領域が割り当てられていないので注意
613 */
614 .org 0x1010 - EXCEPTION_VECTOR_BASE
615
616Fixed_Interval_timer:
617 FIXED_INTERVAL_TIMER_PROC
618
619/*
620 * Watchdog timer
621 *  オフセット:0x1020
622 *
623 *  例外クラス:Critical
624 *   リターン命令はrfci(Return From Critical Interrupt)
625 *   を用いる。
626 *
627 *  0x10バイトしか領域が割り当てられていないので注意
628 *  カーネル管理外の例外とする。
629 *  (この処理ルーチン内
630でサービスコールを使用しない。)
631 */
632 .org 0x1020 - EXCEPTION_VECTOR_BASE
633
634Watchdog_timer:
635 WATCHDOG_TIMER_PROC
636
637/*
638 * Data TLB miss
639 *  0x10バイトしか領域が割り当てられていないので注意
640 */
641 .org 0x1100 - EXCEPTION_VECTOR_BASE
642
643Data_TLB_miss:
644 DATA_TLB_MISS_PROC
645
646/*
647 * Instruction TLB miss
648 *  0x10バイトしか領域が割り当てられていないので注意
649 */
650 .org 0x1200 - EXCEPTION_VECTOR_BASE
651
652Instruction_TLB_miss:
653 INSTRUCTION_TLB_MISS_PROC
654
655/*
656 * Debug例外
657 *  オフセット:0x2000
658 *
659 *  例外クラス:Critical
660 *   リターン命令はrfci(Return From Critical Interrupt)
661 *   を用いる。
662 *  
663 *  要因は以下の7種類
664 *   Trap
665 *   Instruction address compare
666 *   Data address compare
667 *   Instruction complete
668 *   Branch taken
669 *   Exception
670 *   Unconditional debug event
671 *  
672 *  カーネル管理外の例外とする。
673 *  (この処理ルーチン内
674でサービスコールを使用しない。)
675 *  
676 *  0x10バイトしか領域が割り当てられていないので注意
677 */
678 .org 0x2000 - EXCEPTION_VECTOR_BASE
679
680Debug_exception:
681 DEBUG_PROC
682
683
684/*
685 * インプリメンテーション専用の処理(オフセット 0x2010-0x2ff0)
686 * インプリメンテーション固有の例外ベクタ(1つとは限らない)や
687 * 他の用途に使用される
688 *
689 *   オフセットの指定方法に注意すること。
690 *  å…
691·ä½“的には
692 * .org オフセット - EXCEPTION_VECTOR_BASE
693 *   のように指定する。詳しくは他の例外要因の該当個所を参ç…
694§ã€‚
695 */
696#ifdef IMPLEMENT_EXCEPTION_02010_PROC
697
698 IMPLEMENT_EXCEPTION_02010_PROC
699
700#endif /* IMPLEMENT_EXCEPTION_01000 */
701
702
703/*
704 * System reset
705 * リセットベクタは0xffff,fffc番地に固定されている
706 */
707 .section ".system_reset_vector","rxai"
708 .align 2
709
710/* この行を(0xffff,fffc - 4バイト×4命令)番地にé…
711ç½®ã™ã‚‹ã€‚ */
712jump_to_start:
713 LI32(r8, start)
714 mtctr r8
715 bctrl
716
717/* この行を0xffff,fffc番地にé…
718ç½®ã™ã‚‹ã€‚ */
719reset_vector:
720 b jump_to_start
721 /* ここには1命令しかå…
722¥ã‚‰ãªã„ので相対分岐命令を置き、 */
723 /* startルーチンへの分岐は上記のjump_to_startで行う。 */
724
725
726#endif /* IBM_PPC_EMB_ENV */
727
728
729
730
731/*
732 * CPU例外å…
733¥å£å‡¦ç†ãƒ«ãƒ¼ãƒãƒ³ã®ç¶šã
734 *  例外要因によらず、å…
735±é€šã®å‡¦ç†
736 *  各例外ベクタから合流して、残りの処理をここで行う。
737 *   ・プロセッサコアの汎用レジスタと特殊レジスタの待
738避
739 *   ・C言語ルーチンの
740 *   ・å…
741ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹ã®è¨­å®š
742 *   ・引数の設定
743 *  が済んだ状æ…
744‹ã§ã“こに来る
745 *
746 *  レジスタ割り当て(すべて設定済みの状æ…
747‹ã§ã“こに来る)
748 *   SPRG0:割込み/例外のネストカウンタ
749 *   SPRG2:exc_table(CPU例外擬似ベクタテーブルのå…
750ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹ï¼‰
751 *   r3:CPU例外ハンドラの引数
752 *   r4:SRR1のコピー
753 *   r6:C言語ルーチンのå…
754ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹
755 *
756 * regflg をチェックする前に割り込みを禁止しないと、reqflg をチェック
757 * 後に起動された割り込みハンドラ内
758でディスパッチが要求された場合に、
759 * ディスパッチされない。
760 *
761 * 例外ベクタからtextセクションにPC相対分岐で届かなくなったときのため、
762 * Exception_Entryをグローバル宣言している。
763 *
764 */
765
766 .text
767 .align 2
768#ifdef ABSOLUTE_JUMP_EXC_ENTRY
769 .global Exception_Entry
770#endif /* ABSOLUTE_JUMP_EXC_ENTRY */
771
772Exception_Entry:
773 mtctr r6; /* CTR←C言語ルーチンのå…
774ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹ */
775 /* 割込みネストカウンタのインクリメント */
776 mfspr r8, SPRG0 /* SPRG0:割込み/例外ネストカウンタ */
777 addi r8, r8, 1
778 mtspr SPRG0, r8
779
780 /* CPU例外発生時のコンテキストの判別 */
781 cmpwi crf0, r8, 1
782 bne exception_from_int
783
784 /* 初段のCPU例外の場合 */
785exception_from_task:
786 /*
787 * コーリング・コンベンションに合わせて、スタックポインタを
788 * 8バイトずらしておく。
789 * 
790 * -8 ----------------------
791 * | task sp |
792 * -4 ---------------------- 
793 * | |←C言語ルーチンの呼び出しにより
794 * STACKTOP→ ---------------------- 書き込まれる
795 *
796 */
797 LI32(r9, STACKTOP-STACK_MARGIN)
798 stw sp, 0(r9) /* タスクスタックポインタの保存 */
799 mr sp, r9 /* スタック切り替え */
800
801
802/*
803 * マクロ定義:CPU例外ハンドラの呼出し
804 *       初段の例外と多重例外のå…
805±é€šå‡¦ç†
806 *
807 * 処理内
808容
809 *  C言語ルーチン呼び出し
810 *
811 * 引数
812 *   label:ラベル識別用文字列
813 *       (複数箇所でこのマクロを使用できるようにするため)
814 *
815 * 前提条件
816 *   r3=C言語ルーチンの引数
817 *   r4=SRR1
818 *   CTR=C言語ルーチンのå…
819ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹
820 *   の状æ…
821‹ã§ä½¿ç”¨ã•ã‚Œã‚‹
822 *
823 * 備考
824 *  CPU例外ハンドラの起動により、CPUロック状æ…
825‹ã‚’変更してはいけない
826 *  つまり、CPU例外発生時にCPUロック状æ…
827‹ã§ã‚れば、CPUロック状æ…
828‹ã®
829 *  まま、CPU例外ハンドラを起動する。
830 *  (CPU例外発生時にCPUロック解除状æ…
831‹ã§ã‚れば、CPUロック解除状æ…
832‹ã®
833 *   まま、CPU例外ハンドラを起動する。)
834 *   
835 */
836#define _CALL_EXCEPTION_ROUTINE(label) \
837 andi. r6, r4, MSR_EE; /* r4:SSR1のコピー */ \
838 /* 結果がゼロならば(CPUロック状æ…
839‹ã ã£ãŸãªã‚‰ï¼‰ */ \
840 /* EQフラグがセットされる(CPUロック解除状æ…
841‹ãªã‚‰åˆ†å²ï¼‰ */ \
842 bne exception_from_cpu_unlock_##label; \
843 \
844 /* CPU例外発生時にCPUロック状æ…
845‹ã ã£ãŸå ´åˆ */ \
846 /* CPUロック状æ…
847‹ã®ã¾ã¾ã€CPU例外ハンドラを呼び出す */ \
848 /*  C言語ルーチンからの戻り番地を設定 */ \
849 LI32(r7, exit_CALL_EXCEPTION_ROUTINE_##label); \
850 mtspr LR, r7; \
851 bctr; /* C言語ルーチン呼び出し */ \
852 /* exit_CALL_EXCEPTION_ROUTINE_##label番地に戻ってくる */ \
853 \
854 /* CPU例外発生時にCPUロック解除状æ…
855‹ã ã£ãŸå ´åˆ */ \
856exception_from_cpu_unlock_##label:; \
857 mfmsr r10; \
858 ori r11, r10, MSR_EE; /* EEビットをセット */ \
859 mtmsr r11; /* 割込み許可 */ \
860 bctrl; /* C言語ルーチン呼び出し */ \
861 mfmsr r10; \
862 xori r11, r10, MSR_EE; /* EEビットをクリア */ \
863 mtmsr r11; /* 割込み禁止 (a) */ \
864exit_CALL_EXCEPTION_ROUTINE_##label: /* マクロの出口ラベル */
865
866
867/* マクロ引数labelを確実にマクロ展開するため、マクロを2重にしている */
868#define CALL_EXCEPTION_ROUTINE(label) _CALL_EXCEPTION_ROUTINE(label)
869
870 /* C言語ルーチン呼び出し */
871 CALL_EXCEPTION_ROUTINE(exception_from_task)
872 /*
873 * 割込み禁止で戻ってくる
874 *  例外発生時にCPUロックが解除されていた場合も
875 *  上記(a)行で割込み禁止にしている
876 */
877 li r0, 0
878 mtspr SPRG0, r0 /* 割込みネストカウンタをクリア */
879 lwz sp, 0(sp) /* スタック切替 */
880 lis r3, reqflg@ha
881 lwz r4, reqflg@l(r3) /* r4=reqflg */
882 cmpwi crf0, r4, 0 /* reqflgのチェック */
883 beq ret_to_task_exc /* ディスパッチ要求がない場合は分岐 */
884 stw r0, reqflg@l(r3) /* reqflgのクリア */
885 b ret_exc /* 出口処理へジャンプ */
886
887/* 多重例外の場合 */
888exception_from_int:
889 /*
890 * コーリング・コンベンションに合わせて、スタックポインタを
891 * 8バイトずらしておく
892 * 
893 * -8 ----------------------
894 * | |
895 * -4 ---------------------- 
896 * | |←C言語ルーチンの呼び出しにより
897 * sp→ ---------------------- 書き込まれる
898 *
899 */
900 subi sp, sp, STACK_MARGIN
901
902 /* C言語ルーチン呼び出し */
903 CALL_EXCEPTION_ROUTINE(exception_from_int)
904 /*
905 * 割込み禁止で戻ってくる
906 *  例外発生時にCPUロックが解除されていた場合も
907 *  上記(a)行で割込み禁止にしている
908 *  
909 *  分岐å…
910ˆret_to_task_excではCPU例外からのリターン命令rfiにより
911 *    MSR←SRR1
912 *  となるので、å…
913ƒã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã«æˆ»ã‚‹ã¨ãã«ã¯CPU例外発生
914 *  直前のCPUロック/ロック解除状æ…
915‹ãŒå¾©å…
916ƒã•ã‚Œã‚‹
917 */
918 /* スタックポインタをå…
919ƒã«æˆ»ã™ï¼ˆä¸Šè¨˜å‚ç…
920§ï¼‰ */
921 addi sp, sp, STACK_MARGIN
922 mfspr r3, SPRG0 /* SPRG0:割込み/例外ネストカウンタ */
923 subi r3, r3, 1 /* 割込みネストカウンタのディクリメント */
924 mtspr SPRG0, r3
925 b ret_to_task_exc
926
927
928
929/*
930 * 割込み出å…
931¥å£å‡¦ç†ãƒ«ãƒ¼ãƒãƒ³ã®ç¶šã
932 *  割込みベクタが0x100バイト(64命令分)しかないので、
933 *  残りの処理をここで行う。
934 *  割込みコントローラ依存部が単純であれば64命令に収まる
935 *  かも知れないが、可読性を考æ…
936®ã—て、ここに記述した。
937 *  プロセッサコアの汎用レジスタと特殊レジスタの待
938避が
939 *  済んだ状æ…
940‹ã§ã“こに来る
941 *
942 *  すべての外部割り込みで同じ番地に分岐する
943 *
944 * SPRG0レジスタを割込み/例外のネストカウンタとして使用する。
945 *
946 * regflg をチェックする前に割り込みを禁止しないと、reqflg をチェック
947 * 後に起動された割り込みハンドラ内
948でディスパッチが要求された場合に、
949 * ディスパッチされない。
950 *
951 * 例外ベクタからtextセクションにPC相対分岐で届かなくなったときのため、
952 * External_interrupt_1をグローバル宣言している。
953 *
954 */
955
956 .text
957 .align 2
958#ifdef ABSOLUTE_JUMP_EXC_ENTRY
959 .global External_interrupt_1
960#endif /* ABSOLUTE_JUMP_EXC_ENTRY */
961
962External_interrupt_1:
963 /* プロセッサコアのレジスタの待
964避は済んでいる */
965
966 PUSH_ICU_IPM /* 割込みコントローラICUのIPMを待
967避 */
968 /* IPMのデータサイズの如何によらず、 */
969 /* スタックポインタは4バイト境界を */
970 /* 守ること */
971
972 /* 割込みネストカウンタのインクリメント */
973 mfspr r3, SPRG0 /* SPRG0:割込み/例外ネストカウンタ */
974 addi r3, r3, 1
975 mtspr SPRG0, r3
976
977 /* 割込みå…
978ƒã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®åˆ¤åˆ¥ */
979 cmpwi crf0, r3, 1
980 bne interrupt_from_int
981
982 /* 初段の割込みの場合 */
983interrupt_from_task:
984 /*
985 * コーリング・コンベンションに合わせて、スタックポインタを
986 * 8バイトずらしておく。
987 * 
988 * -8 ----------------------
989 * | task sp |
990 * -4 ---------------------- 
991 * | |←C言語ルーチンの呼び出しにより
992 * STACKTOP→ ---------------------- 書き込まれる
993 *
994 */
995 LI32(r4, STACKTOP-STACK_MARGIN) /* r4=STACKTOP */
996 stw sp, 0(r4) /* タスクスタックポインタの保存 */
997 mr sp, r4 /* スタック切り替え */
998
999 /*
1000 * ICU依存の割込み処理
1001 *   処理内
1002容
1003 *   ・割込み要因の判別
1004 *   ・割込みマスクの設定
1005 *   ・割込み許可
1006 *   ・C言語ルーチン呼び出し
1007 *   ・割込み禁止
1008 *   ・割り込み要求フラグのクリア(必
1009要であれば)
1010 */
1011 PROC_ICU(FROM_TASK)
1012 /* 割込み禁止で戻ってくる */
1013
1014 li r0, 0
1015 mtspr SPRG0, r0 /* 割込みネストカウンタをクリア */
1016 lwz sp, 0(sp) /* スタック切替 */
1017 POP_ICU_IPM /* 割込みコントローラICUのIPMを復帰 */
1018 /* IPMのデータサイズの如何によらず、 */
1019 /* スタックポインタは4バイト境界を */
1020 /* 守ること */
1021 lis r3, reqflg@ha
1022 lwz r4, reqflg@l(r3) /* r4=reqflg */
1023 cmpwi crf0, r4, 0 /* reqflgのチェック */
1024 beq ret_to_task_int /* ディスパッチ要求がない場合は分岐 */
1025 stw r0, reqflg@l(r3) /* reqflgのクリア */
1026 b ret_int /* 出口処理へジャンプ */
1027
1028
1029 /* 多重割込みの場合 */
1030interrupt_from_int:
1031 /*
1032 * コーリング・コンベンションに合わせて、スタックポインタを
1033 * 8バイトずらしておく
1034 * 
1035 * -8 ----------------------
1036 * | |
1037 * -4 ---------------------- 
1038 * | |←C言語ルーチンの呼び出しにより
1039 * sp→ ---------------------- 書き込まれる
1040 *
1041 */
1042 subi sp, sp, STACK_MARGIN
1043
1044 PROC_ICU(FROM_INT) /* ICU依存の割込み処理 */
1045 /* 割込み禁止で戻ってくる */
1046
1047 /* スタックポインタをå…
1048ƒã«æˆ»ã™ï¼ˆä¸Šè¨˜å‚ç…
1049§ï¼‰ */
1050 addi sp, sp, STACK_MARGIN
1051 mfspr r3, SPRG0 /* SPRG0:割込み/例外ネストカウンタ */
1052 subi r3, r3, 1 /* 割込みネストカウンタのディクリメント */
1053 mtspr SPRG0, r3
1054 POP_ICU_IPM /* 割込みコントローラICUのIPMを復帰 */
1055 /* IPMのデータサイズの如何によらず、 */
1056 /* スタックポインタは4バイト境界を */
1057 /* 守ること */
1058
1059 /*
1060 * ディスパッチャを呼ばずに単純に割込みå…
1061ƒï¼ˆä¾‹å¤–発生å…
1062ƒï¼‰ã«æˆ»ã‚‹å ´åˆ
1063 *
1064 * rfi命令は同期命令なので、上記のレジスタの復帰とspの加算が終了して
1065 * からå…
1066ƒã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã«æˆ»ã‚‹ã€‚
1067 * spの加算だけがå…
1068ˆã«æ¸ˆã‚“で割込み許可になる心é…
1069ã¯ãªã„。
1070 *
1071 * CPU例外から復帰する場合
1072 *   CPU例外からのリターン命令rfiにより
1073 *    MSR←SRR1
1074 *   となるので、å…
1075ƒã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã«æˆ»ã‚‹ã¨ãã«ã¯CPU例外発生
1076 *   直前のCPUロック/ロック解除状æ…
1077‹ãŒå¾©å…
1078ƒã•ã‚Œã‚‹
1079 */
1080ret_to_task_int:
1081ret_to_task_exc:
1082 LOAD_R0_12_SPRG /* gpr0-1,3-12, 特殊レジスタの復å…
1083ƒ */
1084 addi sp, sp, GPR0_12_SPRG_AREA_SIZE
1085 rfi /* 割込みå…
1086ƒã¸å¾©å¸° */
1087
1088
1089
1090/* レジスタを待
1091避するのに必
1092要なバイト数 */
1093 /* gpr13-31,LR */
1094#define GPR13_31_LR_AREA_SIZE (GPR13_31_AREA_SIZE +4)
1095
1096/*
1097 * マクロ定義:汎用レジスタgpr13-31の待
1098避
1099 */
1100
1101#ifdef USE_MULTIPLE_WORD_LOAD_STORE
1102 /*
1103 * 整数ロード/ストア・マルチプル命令
1104 *  インプリメンテーションによってはかえって遅
1105くなって
1106 *  しまうので注意が必
1107要
1108 */
1109
1110#if SIL_ENDIAN == SIL_ENDIAN_LITTLE
1111  !ここでコンパイル・エラー
1112   リトル・エンディアン・モードにあるときには機能しない
1113   (ハードウェアによる制限事項
1114)
1115#endif
1116
1117
1118#define STORE_R13_31 \
1119 stmw r13, 0(sp) /* gpr13-31を待
1120避 */
1121
1122#else /* USE_MULTIPLE_WORD_LOAD_STORE */
1123#define STORE_R13_31 \
1124 stw r13, 0*4(sp); \
1125 stw r14, 1*4(sp); \
1126 stw r15, 2*4(sp); \
1127 stw r16, 3*4(sp); \
1128 stw r17, 4*4(sp); \
1129 stw r18, 5*4(sp); \
1130 stw r19, 6*4(sp); \
1131 stw r20, 7*4(sp); \
1132 stw r21, 8*4(sp); \
1133 stw r22, 9*4(sp); \
1134 stw r23, 10*4(sp); \
1135 stw r24, 11*4(sp); \
1136 stw r25, 12*4(sp); \
1137 stw r26, 13*4(sp); \
1138 stw r27, 14*4(sp); \
1139 stw r28, 15*4(sp); \
1140 stw r29, 16*4(sp); \
1141 stw r30, 17*4(sp); \
1142 stw r31, 18*4(sp)
1143#endif /* USE_MULTIPLE_WORD_LOAD_STORE */
1144
1145 /* マクロ定義ここまで */
1146
1147
1148/*
1149 * マクロ定義:汎用レジスタgpr13-31の復å…
1150ƒ
1151 */
1152
1153#ifdef USE_MULTIPLE_WORD_LOAD_STORE
1154 /*
1155 * 整数ロード/ストア・マルチプル命令
1156 *  インプリメンテーションによってはかえって遅
1157くなって
1158 *  しまうので注意が必
1159要
1160 */
1161#define LOAD_R13_31 \
1162 lmw r13, 0(sp) /* gpr13-31を復å…
1163ƒ */
1164
1165#else /* USE_MULTIPLE_WORD_LOAD_STORE */
1166#define LOAD_R13_31 \
1167 lwz r13, 0*4(sp); \
1168 lwz r14, 1*4(sp); \
1169 lwz r15, 2*4(sp); \
1170 lwz r16, 3*4(sp); \
1171 lwz r17, 4*4(sp); \
1172 lwz r18, 5*4(sp); \
1173 lwz r19, 6*4(sp); \
1174 lwz r20, 7*4(sp); \
1175 lwz r21, 8*4(sp); \
1176 lwz r22, 9*4(sp); \
1177 lwz r23, 10*4(sp); \
1178 lwz r24, 11*4(sp); \
1179 lwz r25, 12*4(sp); \
1180 lwz r26, 13*4(sp); \
1181 lwz r27, 14*4(sp); \
1182 lwz r28, 15*4(sp); \
1183 lwz r29, 16*4(sp); \
1184 lwz r30, 17*4(sp); \
1185 lwz r31, 18*4(sp)
1186#endif /* USE_MULTIPLE_WORD_LOAD_STORE */
1187
1188 /* マクロ定義ここまで */
1189
1190
1191
1192
1193/*
1194 * タスクディスパッチャ
1195 *
1196 * dispatch は、SPRG0 = 0,割込み禁止状æ…
1197‹ã§å‘¼ã³å‡ºã•ãªã‘ればならない.
1198 * exit_and_dispatch も,SPRG0 = 0・割込み禁止状æ…
1199‹ã§å‘¼ã³å‡ºã™ã®ãŒåŽŸå‰‡
1200 * であるが,カーネル起動時に対応するため,SPRG0 = 1で呼び出した場合
1201 * にも対応している.
1202 */
1203
1204 .global dispatch
1205dispatch:
1206 /* スクラッチレジスタの待
1207避 */
1208 subi sp, sp, GPR13_31_LR_AREA_SIZE + FPR14_31_AREA_SIZE
1209 STORE_R13_31 /* gpr13-31の待
1210避 */
1211
1212 mfspr r7, LR
1213 stw r7, GPR13_31_LR_AREA_SIZE - 4(sp) /* LRの待
1214避 */
1215
1216 /* 浮動小数点レジスタの待
1217避 */
1218#ifdef SUPPORT_FLOATING_POINT_REG
1219 /* ハードウェアが浮動小数点レジスタを実装
1220している場合 */
1221 /* 未完成:本来なら8バイトにアライメントする */
1222 stfd f14, 0*8+GPR13_31_LR_AREA_SIZE(sp)
1223 stfd f15, 1*8+GPR13_31_LR_AREA_SIZE(sp)
1224 stfd f16, 2*8+GPR13_31_LR_AREA_SIZE(sp)
1225 stfd f17, 3*8+GPR13_31_LR_AREA_SIZE(sp)
1226 stfd f18, 4*8+GPR13_31_LR_AREA_SIZE(sp)
1227 stfd f19, 5*8+GPR13_31_LR_AREA_SIZE(sp)
1228 stfd f20, 6*8+GPR13_31_LR_AREA_SIZE(sp)
1229 stfd f21, 7*8+GPR13_31_LR_AREA_SIZE(sp)
1230 stfd f22, 8*8+GPR13_31_LR_AREA_SIZE(sp)
1231 stfd f23, 9*8+GPR13_31_LR_AREA_SIZE(sp)
1232 stfd f24, 10*8+GPR13_31_LR_AREA_SIZE(sp)
1233 stfd f25, 11*8+GPR13_31_LR_AREA_SIZE(sp)
1234 stfd f26, 12*8+GPR13_31_LR_AREA_SIZE(sp)
1235 stfd f27, 13*8+GPR13_31_LR_AREA_SIZE(sp)
1236 stfd f28, 14*8+GPR13_31_LR_AREA_SIZE(sp)
1237 stfd f29, 15*8+GPR13_31_LR_AREA_SIZE(sp)
1238 stfd f30, 16*8+GPR13_31_LR_AREA_SIZE(sp)
1239 stfd f31, 17*8+GPR13_31_LR_AREA_SIZE(sp)
1240#endif /* SUPPORT_FLOATING_POINT_REG */
1241
1242 lis r3, runtsk@ha
1243 LI32(r4, dispatch_r)
1244 lwz r5, runtsk@l(r3) /* r5 = runtsk */
1245 stw sp, TCB_sp(r5) /* runtsk->sp = sp */
1246 stw r4, TCB_pc(r5) /* runtsk->pc = dispatch_r */
1247 b dispatcher
1248
1249
1250 /* ディスパッチャの出口 */
1251 /* スタックポインタの復å…
1252ƒã¯æ¸ˆã‚“でいる */
1253 /*   r10にruntskがå…
1254¥ã£ã¦å‘¼ã°ã‚Œã‚‹ */
1255dispatch_r:
1256 /* スクラッチレジスタの復帰 */
1257
1258 /* 浮動小数点レジスタ */
1259#ifdef SUPPORT_FLOATING_POINT_REG
1260 /* ハードウェアが浮動小数点レジスタを実装
1261している場合 */
1262 /* 未完成:本来なら8バイトにアライメントする */
1263 lfd f14, 0*8+GPR13_31_LR_AREA_SIZE(sp)
1264 lfd f15, 1*8+GPR13_31_LR_AREA_SIZE(sp)
1265 lfd f16, 2*8+GPR13_31_LR_AREA_SIZE(sp)
1266 lfd f17, 3*8+GPR13_31_LR_AREA_SIZE(sp)
1267 lfd f18, 4*8+GPR13_31_LR_AREA_SIZE(sp)
1268 lfd f19, 5*8+GPR13_31_LR_AREA_SIZE(sp)
1269 lfd f20, 6*8+GPR13_31_LR_AREA_SIZE(sp)
1270 lfd f21, 7*8+GPR13_31_LR_AREA_SIZE(sp)
1271 lfd f22, 8*8+GPR13_31_LR_AREA_SIZE(sp)
1272 lfd f23, 9*8+GPR13_31_LR_AREA_SIZE(sp)
1273 lfd f24, 10*8+GPR13_31_LR_AREA_SIZE(sp)
1274 lfd f25, 11*8+GPR13_31_LR_AREA_SIZE(sp)
1275 lfd f26, 12*8+GPR13_31_LR_AREA_SIZE(sp)
1276 lfd f27, 13*8+GPR13_31_LR_AREA_SIZE(sp)
1277 lfd f28, 14*8+GPR13_31_LR_AREA_SIZE(sp)
1278 lfd f29, 15*8+GPR13_31_LR_AREA_SIZE(sp)
1279 lfd f30, 16*8+GPR13_31_LR_AREA_SIZE(sp)
1280 lfd f31, 17*8+GPR13_31_LR_AREA_SIZE(sp)
1281#endif /* SUPPORT_FLOATING_POINT_REG */
1282
1283 /* 汎用レジスタ */
1284 LOAD_R13_31
1285
1286 /* LRの復å…
1287ƒ */
1288 lwz r7, GPR13_31_LR_AREA_SIZE - 4(sp)
1289 mtspr LR, r7
1290
1291 addi sp, sp, GPR13_31_LR_AREA_SIZE + FPR14_31_AREA_SIZE
1292
1293 /*
1294 * タスク例外処理要求のチェック
1295 * dispatch_rはdispatcherから呼び出されるため,
1296 * runtskはr10にå…
1297¥ã£ã¦ã„る.
1298 */
1299 lbz r4, TCB_enatex(r10) /* r10=runtsk */
1300 /*
1301 * マスクデータのビット幅
1302とエンディアンはmakeoffset.cの
1303 * BIT_BBおよびBIT_LBで指定している
1304 */
1305 andi. r5, r4, TCB_enatex_mask /* r5 = runtsk->enatex */
1306 /* 結果がゼロならば、EQフラグがセットされる */
1307
1308 /* タスク例外処理禁止ならdispatch()の呼び出しå…
1309ƒã«æˆ»ã‚‹ */
1310 beqlr /* (LRに戻り番地が格納されている) */
1311 lwz r6, TCB_texptn(r10) /* r6 = runtsk->texptn */
1312 cmpwi crf0, r6, 0
1313 /* タスク例外要求がなければ */
1314 /* dispatch()の呼び出しå…
1315ƒã«æˆ»ã‚‹ */
1316 beqlr /* (LRに戻り番地が格納されている) */
1317
1318 b call_texrtn /* タスク例外処理ルーチン呼び出し */
1319 /*
1320 * call_texrtn()からここには戻ってこないで、dispatch()の
1321 * 呼び出しå…
1322ƒï¼ˆ=LRレジスタが指し示す番地)に直接戻る。
1323 * 
1324 * call_texrtn()の呼び出しにより(sp+3)〜(ps+7)番地の内
1325容が
1326 * 破壊されるが、spの位置はdispatch()を呼び出したときと同じ
1327 * なので問題ない
1328 * 
1329 * sp→ ----------------------
1330 * | |
1331 * +4 ---------------------- 
1332 * | |←call_texrtn()の呼び出しにより
1333 * +8 ---------------------- 書き込まれる
1334 *
1335 *
1336 * 注意
1337   *  タスク例外処理ルーチン内
1338で浮動小数点レジスタを使用する
1339   *  場合は、タスク例外処理ルーチン側で浮動小数点レジスタの
1340   *  待
1341避/復å…
1342ƒã‚’行うこと。
1343 */
1344
1345
1346 .global exit_and_dispatch
1347exit_and_dispatch:
1348 li r0, 0
1349 mtspr SPRG0, r0 /* ネストカウンタをクリア */
1350
1351dispatcher:
1352 /*
1353 * ここには割り込み禁止で来ること
1354 */
1355 LOAD_VAL32(r10, schedtsk) /* r10 = schedtsk */
1356 lis r5, runtsk@ha
1357 /*
1358 * ここでruntskにschedtskを代å…
1359¥ã™ã‚‹ã®ã¯ï¼’つの意味がある。
1360 *  (1) schedtsk != NULLの場合
1361 *     通常のタスク切り替えを行う。
1362 *  (2) schedtsk == NULLの場合
1363 *     runtskにNULLを代å…
1364¥ã—ておく。
1365 *     (dispatcher_1以降の割込み待
1366ちで割込みがå…
1367¥ã‚Šã€ãã®ä¸­ã§
1368 *      iget_tid()がコールされたときに正しくTSK_NONEを返すため
1369 *      には、実行状æ…
1370‹ã®ã‚¿ã‚¹ã‚¯ãŒãªã„時に、runtskをNULLにして
1371 *      おる必
1372要がある。)
1373 */
1374 stw r10, runtsk@l(r5) /* runtsk=schedtsk(=r10) */
1375
1376 cmpwi crf0, r10, 0
1377 beq dispatcher_1 /* schedtskが無ければ割込み待
1378ちへ */
1379
1380 lwz r6, TCB_pc(r10) /* 実行再開番地を取り出して */
1381 mtctr r6 /* CTR<-実行再開番地 */
1382 lwz sp, TCB_sp(r10) /* スタックポインタを復å…
1383ƒ */
1384 bctr /* ジャンプ(下記参ç…
1385§ï¼‰ */
1386
1387 /*
1388 * 実行再開番地は以下の3通り
1389 *  いずれの場合もr10=runtskで呼び出すこと
1390 *   ・ディスパッチャの出口 dispatch_r
1391 *   ・割込み/例外の出口  ret_int_r
1392 *   ・タスク起動直後    activate_r
1393 */
1394
1395
1396 /*
1397 * 実行すべきタスクが現れるまで待
1398つ処理
1399 *
1400 * ここで非タスクコンテキストに切り換えるのは,ここで発生する割込み
1401 * 処理にどのスタックを使うかという問題の解決と,割込みハンドラ内
1402で
1403 * のタスクディスパッチの防止という二つの意味がある.
1404 */
1405dispatcher_1:
1406 LI32(sp, STACKTOP) /* スタック切り替え */
1407 li r3, 1
1408 mtspr SPRG0, r3 /* ネストカウンタ=1 */
1409
1410 /* ループ内
1411で使う定数を用意しておく */
1412 LI32(r4, reqflg) /* reqflgのアドレス */
1413 li r0, 0
1414
1415dispatcher_2:
1416#ifdef SUPPORT_POWER_MANAGEMENT
1417 /* 省電力モードがある場合 */
1418 /*
1419 * 割込み許可と省電力モードへの移行
1420 *  ・割込みから戻ってきた後に割込み禁止も行う
1421 *  ・r0〜r4の内
1422容を破壊してはならない
1423 *
1424 * 注意
1425 * 「割込み許可」と「省電力モードへの移行」をアトミックに行え
1426 * ないプロセッサでは、割込みのタイミングによっては「割込み許
1427 * 可」と「省電力モードへの移行」の間で割込みを受け付けてしま
1428 * い、意図しない形で省電力モードに移行してしまうので注意。
1429 * 割込みによって実行可能なタスクが現れてもプロセッサがスリー
1430 * プしたままで実行されなくなる。(実際にはタイマ割込みにより
1431 * 省電力モードから復帰するので、タスクが待
1432たされる時間は最大
1433 * でもタイマ割込み周期で押さえられる。)
1434 */
1435 SAVE_POWPER
1436#else /* SUPPORT_POWER_MANAGEMENT */
1437 /* 省電力モードがない場合 */
1438 mfmsr r5
1439 ori r6, r5, MSR_EE
1440 mtmsr r6 /* 割込み許可 */
1441 /* ここで割込みがå…
1442¥ã£ã¦ã€æˆ»ã£ã¦ãã‚‹ */
1443 mtmsr r5 /* 割込み禁止 */
1444#endif /* SUPPORT_POWER_MANAGEMENT */
1445 lwz r6, 0(r4) /* r6 = reqflg */
1446 cmpwi crf0, r6, 0
1447 /* ディスパッチ要求がなければループのå…
1448ˆé ­ã¸ */
1449 beq dispatcher_2
1450 stw r0, 0(r4) /* reqflgをクリア */
1451 mtspr SPRG0, r0 /* ネストカウンタをクリア */
1452 b dispatcher /* 実行再開番地を取り出す処理へジャンプ */
1453
1454 /*
1455 * 割込み待
1456ちの直前に行ったスタック切替の戻しを行っていないが、
1457 * ディスパッチャの出口でTCBから取り出した値をスタックポイン
1458 * タに設定するので問題ない。
1459 */
1460
1461
1462
1463/*
1464 * 割り込みハンドラ/CPU例外ハンドラ出口処理
1465 *
1466 * 戻りå…
1467ˆãŒã‚¿ã‚¹ã‚¯ã§reqflgがセットされている場合のみここにくる。
1468 * SPRG0 = 0,割り込み禁止状æ…
1469‹,スクラッチレジスタを保存した
1470 * 状æ…
1471‹ã§å‘¼ã³å‡ºã™ã“と。
1472 *
1473 * また、r10にruntskの値をå…
1474¥ã‚Œã¦ã‹ã‚‰ret_int_1にジャンプすること
1475 */
1476
1477ret_int:
1478ret_exc:
1479 LOAD_VAL32(r5, enadsp) /* r5 = enadsp */
1480 LOAD_VAL32(r10, runtsk) /* r10 = runtsk */
1481 cmpwi crf0, r5, 0
1482 beq ret_int_1 /* ディスパッチ禁止ならジャンプ */
1483
1484 LOAD_VAL32(r5, schedtsk) /* r5 = schedtsk */
1485 cmpw crf0, r5, r10
1486 beq ret_int_1 /* runtsk=schedtskならジャンプ */
1487
1488
1489 /* 残りのレジスタを保存 */
1490
1491 subi sp, sp, GPR13_31_AREA_SIZE + FPR_AREA_SIZE
1492 /* 汎用レジスタの待
1493避 */
1494 STORE_R13_31 /* gpr13-31の待
1495避 */
1496
1497 /* 浮動小数点レジスタの待
1498避 */
1499#ifdef SUPPORT_FLOATING_POINT_REG
1500 /* ハードウェアが浮動小数点レジスタを実装
1501している場合 */
1502 /* 未完成:本来なら8バイトにアライメントする */
1503 stfd f0, 0*8+GPR13_31_AREA_SIZE(sp)
1504 stfd f1, 1*8+GPR13_31_AREA_SIZE(sp)
1505 stfd f2, 2*8+GPR13_31_AREA_SIZE(sp)
1506 stfd f3, 3*8+GPR13_31_AREA_SIZE(sp)
1507 stfd f4, 4*8+GPR13_31_AREA_SIZE(sp)
1508 stfd f5, 5*8+GPR13_31_AREA_SIZE(sp)
1509 stfd f6, 6*8+GPR13_31_AREA_SIZE(sp)
1510 stfd f7, 7*8+GPR13_31_AREA_SIZE(sp)
1511 stfd f8, 8*8+GPR13_31_AREA_SIZE(sp)
1512 stfd f9, 9*8+GPR13_31_AREA_SIZE(sp)
1513 stfd f10, 10*8+GPR13_31_AREA_SIZE(sp)
1514 stfd f11, 11*8+GPR13_31_AREA_SIZE(sp)
1515 stfd f12, 12*8+GPR13_31_AREA_SIZE(sp)
1516 stfd f13, 13*8+GPR13_31_AREA_SIZE(sp)
1517 stfd f14, 14*8+GPR13_31_AREA_SIZE(sp)
1518 stfd f15, 15*8+GPR13_31_AREA_SIZE(sp)
1519 stfd f16, 16*8+GPR13_31_AREA_SIZE(sp)
1520 stfd f17, 17*8+GPR13_31_AREA_SIZE(sp)
1521 stfd f18, 18*8+GPR13_31_AREA_SIZE(sp)
1522 stfd f19, 19*8+GPR13_31_AREA_SIZE(sp)
1523 stfd f20, 20*8+GPR13_31_AREA_SIZE(sp)
1524 stfd f21, 21*8+GPR13_31_AREA_SIZE(sp)
1525 stfd f22, 22*8+GPR13_31_AREA_SIZE(sp)
1526 stfd f23, 23*8+GPR13_31_AREA_SIZE(sp)
1527 stfd f24, 24*8+GPR13_31_AREA_SIZE(sp)
1528 stfd f25, 25*8+GPR13_31_AREA_SIZE(sp)
1529 stfd f26, 26*8+GPR13_31_AREA_SIZE(sp)
1530 stfd f27, 27*8+GPR13_31_AREA_SIZE(sp)
1531 stfd f28, 28*8+GPR13_31_AREA_SIZE(sp)
1532 stfd f29, 29*8+GPR13_31_AREA_SIZE(sp)
1533 stfd f30, 30*8+GPR13_31_AREA_SIZE(sp)
1534 stfd f31, 31*8+GPR13_31_AREA_SIZE(sp)
1535 /*
1536 * FPSCRの待
1537避
1538 *
1539 *  スタックを8バイト使用するのは無駄であるが、
1540 *  stfiwx命令はオプションなので選択しなかった。
1541 *  (また、対応するロード命令がないのも問題)
1542 *
1543 */
1544 mffs f0 /* f0の下位2バイト←FPSCR */
1545 /* @(sp+オフセット)←f0 */
1546 stfd f0, GPR13_31_AREA_SIZE+FPR0_13_AREA_SIZE-8(sp)
1547#endif /* SUPPORT_FLOATING_POINT_REG */
1548
1549 LI32(r5, ret_int_r)
1550 /* r10 = runtskでここに来る */
1551 stw sp, TCB_sp(r10) /* runtsk->sp = sp */
1552 /* タスクスタックポインタの保存 */
1553 stw r5, TCB_pc(r10) /* runtsk->pc = ret_int_r */
1554 /* (実行再開番地の保存) */
1555
1556 b dispatcher /* ディスパッチャ呼び出し */
1557
1558
1559 /* 割込み/例外の出口処理の後半部分
1560 * ret_intから
1561 *  ・直接、ret_int_1に合流する場合
1562 *  ・ディスパッチャを経由してやって来る場合
1563 *  の2通りある
1564 *  いずれの場合もr10にruntskがå…
1565¥ã£ã¦ã„ã‚‹
1566 */
1567ret_int_r:
1568
1569#ifdef SUPPORT_FLOATING_POINT_REG
1570 /* ハードウェアが浮動小数点レジスタを実装
1571している場合 */
1572
1573 /* FPSCRの復å…
1574ƒ */
1575 lfd f0, GPR13_31_AREA_SIZE+FPR0_13_AREA_SIZE-8(sp)
1576 mtfsf 0xf,f0 /* FPSCR←f0の下位2バイト */
1577
1578 /* 浮動小数点レジスタの復å…
1579ƒ */
1580 lfd f0, 0*8+GPR13_31_AREA_SIZE(sp)
1581 lfd f1, 1*8+GPR13_31_AREA_SIZE(sp)
1582 lfd f2, 2*8+GPR13_31_AREA_SIZE(sp)
1583 lfd f3, 3*8+GPR13_31_AREA_SIZE(sp)
1584 lfd f4, 4*8+GPR13_31_AREA_SIZE(sp)
1585 lfd f5, 5*8+GPR13_31_AREA_SIZE(sp)
1586 lfd f6, 6*8+GPR13_31_AREA_SIZE(sp)
1587 lfd f7, 7*8+GPR13_31_AREA_SIZE(sp)
1588 lfd f8, 8*8+GPR13_31_AREA_SIZE(sp)
1589 lfd f9, 9*8+GPR13_31_AREA_SIZE(sp)
1590 lfd f10, 10*8+GPR13_31_AREA_SIZE(sp)
1591 lfd f11, 11*8+GPR13_31_AREA_SIZE(sp)
1592 lfd f12, 12*8+GPR13_31_AREA_SIZE(sp)
1593 lfd f13, 13*8+GPR13_31_AREA_SIZE(sp)
1594 lfd f14, 14*8+GPR13_31_AREA_SIZE(sp)
1595 lfd f15, 15*8+GPR13_31_AREA_SIZE(sp)
1596 lfd f16, 16*8+GPR13_31_AREA_SIZE(sp)
1597 lfd f17, 17*8+GPR13_31_AREA_SIZE(sp)
1598 lfd f18, 18*8+GPR13_31_AREA_SIZE(sp)
1599 lfd f19, 19*8+GPR13_31_AREA_SIZE(sp)
1600 lfd f20, 20*8+GPR13_31_AREA_SIZE(sp)
1601 lfd f21, 21*8+GPR13_31_AREA_SIZE(sp)
1602 lfd f22, 22*8+GPR13_31_AREA_SIZE(sp)
1603 lfd f23, 23*8+GPR13_31_AREA_SIZE(sp)
1604 lfd f24, 24*8+GPR13_31_AREA_SIZE(sp)
1605 lfd f25, 25*8+GPR13_31_AREA_SIZE(sp)
1606 lfd f26, 26*8+GPR13_31_AREA_SIZE(sp)
1607 lfd f27, 27*8+GPR13_31_AREA_SIZE(sp)
1608 lfd f28, 28*8+GPR13_31_AREA_SIZE(sp)
1609 lfd f29, 29*8+GPR13_31_AREA_SIZE(sp)
1610 lfd f30, 30*8+GPR13_31_AREA_SIZE(sp)
1611 lfd f31, 31*8+GPR13_31_AREA_SIZE(sp)
1612#endif /* SUPPORT_FLOATING_POINT_REG */
1613
1614 /* 汎用レジスタの復å…
1615ƒ */
1616 LOAD_R13_31 /* gpr13-31の復å…
1617ƒ */
1618 addi sp, sp, GPR13_31_AREA_SIZE + FPR_AREA_SIZE
1619
1620 /* ディスパッチャを経由しない場合はここから合流 */
1621 /* (r10にruntskがå…
1622¥ã£ãŸçŠ¶æ…
1623‹ã§ã“こに来る) */
1624ret_int_1:
1625 /* タスク例外処理要求のチェック */
1626 /* r10 = runtsk */
1627 lbz r4, TCB_enatex(r10)
1628 /*
1629 * マスクデータのビット幅
1630とエンディアンはmakeoffset.cの
1631 * BIT_BBおよびBIT_LBで指定している
1632 */
1633 andi. r5, r4, TCB_enatex_mask /* r5 = runtsk->enatex */
1634 /* 結果がゼロならば、EQフラグがセットされる */
1635 beq ret_int_2 /* タスク例外処理禁止ならジャンプ */
1636 lwz r6, TCB_texptn(r10) /* r6 = runtsk->texptn */
1637 /* タスク例外要求がなければならジャンプ */
1638 cmpwi crf0, r6, 0
1639 beq ret_int_2
1640
1641 /*
1642 * コーリング・コンベンションに合わせて、スタックポインタを
1643 * 8バイトずらしておく。
1644 * 
1645 * -8 ----------------------
1646 * | |
1647 * -4 ---------------------- 
1648 * | |←call_texrtn()の呼び出しにより
1649 * sp→ ---------------------- 書き込まれる
1650 *
1651 */
1652 subi sp, sp, STACK_MARGIN
1653
1654 bl call_texrtn /* タスク例外処理ルーチン呼び出し */
1655 /* スタックポインタをå…
1656ƒã«æˆ»ã™ï¼ˆä¸Šè¨˜å‚ç…
1657§ï¼‰ */
1658 addi sp, sp, STACK_MARGIN
1659 /*
1660 * 注意
1661   *  タスク例外処理ルーチン内
1662で浮動小数点レジスタを使用する
1663   *  場合は、タスク例外処理ルーチン側で浮動小数点レジスタの
1664   *  待
1665避/復å…
1666ƒã‚’行うこと。
1667 */
1668
1669ret_int_2:
1670 /*
1671 * call_texrtn()からここに戻って来る。(上記addi命令を経由)
1672 * (call_texrtn()を呼ばない場合は直接ここに来る)
1673 *
1674   *  結果的にret_to_task_intと同じ処理になったが、
1675   *  無理にまとめると可読性が悪くなるので
1676   *  別々
1677のままにしている。
1678 */
1679 LOAD_R0_12_SPRG /* gpr0-1,3-12, 特殊レジスタの復å…
1680ƒ */
1681 addi sp, sp, GPR0_12_SPRG_AREA_SIZE
1682 /*
1683 * rfi命令は同期命令なので、上記のレジスタの復帰とspの加算が終了して
1684 * からå…
1685ƒã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã«æˆ»ã‚‹ã€‚
1686 * spの加算だけがå…
1687ˆã«æ¸ˆã‚“で割込み許可になる心é…
1688ã¯ãªã„。
1689 */
1690 rfi /* 割込みå…
1691ƒã¸å¾©å¸° */
1692
1693
1694
1695
1696/*
1697 * タスク起動処理
1698 *  ディスパッチャから呼び出されるので、r10にはruntskがå…
1699¥ã£ã¦ã„ã‚‹
1700 *  スタックポインタも設定済み
1701 */
1702
1703 .globl activate_r
1704activate_r:
1705 /* r10 = runtsk (ディスパッチャで設定) */
1706 lwz r4, TCB_tinib(r10) /* r4 = runtsk->tinib */
1707
1708 /* タスク起動番地の設定 */
1709 lwz r5, TINIB_task(r4)
1710 mtctr r5 /* CTR = runtsk->tinib->task */
1711
1712 /* タスクへの引数(拡張情
1713報) */
1714 lwz r3, TINIB_exinf(r4) /* r3 = runtsk->tinib->TINIB_exinf */
1715
1716 /*
1717 * LRレジスタにext_tskを設定することにより、ext_tskを
1718 * 呼ばないでタスクの関数を抜ける場合もext_tskに分岐する。
1719 */
1720 LI32(r6, ext_tsk)
1721 mtspr LR, r6 /* タスクからの戻り番地を設定 */
1722
1723 mfmsr r8
1724 ori r9, r8, MSR_EE
1725 mtmsr r9 /* 割込み許可 */
1726
1727 bctr /* C言語ルーチン呼び出し */
1728
1729
1730/*
1731 * 微少時間待
1732ち
1733 *  引数r3:待
1734ち時間をnsec単位で指定する
1735 */
1736 .globl sil_dly_nse
1737sil_dly_nse:
1738 LI32(r4, SIL_DLY_TIM1)
1739 sub. r3, r3, r4 /* r3 からSIL_DLY_TIM1を引く */
1740 blelr /* 結果が0以下ならリターン */
1741
1742 LI32(r5, SIL_DLY_TIM2)
1743sil_dly_nse_1:
1744 sub. r3, r3, r5 /* r3 からSIL_DLY_TIM2を引く */
1745 bgt sil_dly_nse_1 /* 結果が 0 より大きければループ */
1746 blr
1747
1748/* end of file */
Note: See TracBrowser for help on using the repository browser.