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

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

initial

File size: 18.5 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 * Copyright (C) 2006 by Monami Software Limited Partnership, JAPAN
9 * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
10 * Graduate School of Information Science, Nagoya Univ., JAPAN
11 *
12 * 上記著作権者
13は,以下の (1)〜(4) の条件か,Free Software Foundation
14 * によってå…
15¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
16 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
17 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
18å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
19 * 利用と呼ぶ)することを無償で許諾する.
20 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
21 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
22 * スコード中に含まれていること.
23 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
24 * 用できる形で再é…
25å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
26å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
27 * 者
28マニュアルなど)に,上記の著作権表示,この利用条件および下記
29 * の無保証規定を掲載すること.
30 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
31 * 用できない形で再é…
32å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
33 * と.
34 * (a) 再é…
35å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
36マニュアルなど)に,上記の著
37 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
38 * (b) 再é…
39å¸ƒã®å½¢æ…
40‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
41 * 報告すること.
42 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
43 * 害からも,上記著作権者
44およびTOPPERSプロジェクトをå…
45è²¬ã™ã‚‹ã“と.
46 *
47 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
48お
49 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
50 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
51 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
52 *
53 * @(#) $Id: cpu_support.S,v 1.12 2007/05/30 03:56:47 honda Exp $
54 */
55
56/*
57 * プロセッサ依存モジュール アセンブリ言語部(M32R用)
58 */
59
60#define _MACRO_ONLY
61
62#include <cpu_rename.h>
63
64#include <m32rasm.inc>
65#include <s_services.h>
66
67#include "offset.h"
68
69#define _trap_handler_0 _kernel__trap_handler_0
70#define _trap_handler_1 _kernel__trap_handler_1
71#define _trap_handler_2 _kernel__trap_handler_2
72#define _trap_handler_3 _kernel__trap_handler_3
73#define _trap_handler_4 _kernel__trap_handler_4
74#define _trap_handler_5 _kernel__trap_handler_5
75#define _trap_handler_6 _kernel__trap_handler_6
76#define _trap_handler_7 _kernel__trap_handler_7
77#define _trap_handler_8 _kernel__trap_handler_8
78#define _trap_handler_9 _kernel__trap_handler_9
79#define _trap_handler_10 _kernel__trap_handler_10
80#define _trap_handler_11 _kernel__trap_handler_11
81#define _trap_handler_12 _kernel__trap_handler_12
82#define _trap_handler_13 _kernel__trap_handler_13
83#define _trap_handler_14 _kernel__trap_handler_14
84#define _trap_handler_15 _kernel__trap_handler_15
85
86 .extern _kernel_runtsk
87 .extern _kernel_schedtsk
88 .extern _kernel_reqflg
89 .extern _kernel_enaflg
90 .extern InterruptHandlerEntry
91 .extern ExceptionHandlerEntry
92 .extern ext_tsk
93
94/*
95 * EITベクタエントリの定義
96 */
97 .section ".vector","ax"
98 .global reset
99 .extern start
100
101 .balign 0x10
102reset:
103 bra start
104
105 .balign 0x10
106vector_entry_SBI:
107 /*
108 * システムブレーク割込み
109 */
110 bra vector_entry_SBI
111
112 .balign 0x10
113vector_entry_RIE:
114 /*
115 * 予約命令例外(Reserved Instruction Exception)
116 */
117 stmdb "r0,r1"
118 ldi r1, #(EXC_RIE*4-4)
119 bra _exception_handler
120
121 .balign 0x10
122vector_entry_AE:
123 /*
124 * アドレス例外(Address Exception)
125 */
126 stmdb "r0,r1"
127 ldi r1, #(EXC_AE*4-4)
128 bra _exception_handler
129
130 .balign 0x10
131vector_entry_trap:
132 /*
133 * トラップベクタエントリ
134 */
135 bra _trap_handler_0
136 bra _trap_handler_1
137 bra _trap_handler_2
138 bra _trap_handler_3
139 bra _trap_handler_4
140 bra _trap_handler_5
141 bra _trap_handler_6
142 bra _trap_handler_7
143 bra _trap_handler_8
144 bra _trap_handler_9
145 bra _trap_handler_10
146 bra _trap_handler_11
147 bra _trap_handler_12
148 bra _trap_handler_13
149 bra _trap_handler_14
150 bra _trap_handler_15
151
152/*
153 * 割込みベクタエントリと割込みハンドラ起動/復帰処理部
154 *
155 * 割込み発生時のハードウエアの動作
156 *
157 * pswレジスタ中のsm,ie,pm,cビットをbsm,bie,bpm,bcビットに退避
158 * する.bpcには割込み発生時のpc値がå…
159¥ã‚‹ï¼Ž
160 *
161 * bsm <- sm
162 * bie <- ie
163 * bpm <- pm
164 * bc <- c
165 * bpc <- 割込み発生時のpc値
166 *
167 * pswレジスタ中のsm,ie,pm,cビットを以下のように更新する.
168 *
169 * sm <- 0
170 * ie <- 0
171 * pm <- 0
172 * c <- 0
173 *
174 * レジスタの積み方
175 * r0-r1(作業領域)
176 * r0-r7,r14,acc(hi/lo),bpc,psw,ICUISTS,psw(割込みハンドラ呼出前)
177 *
178 * 二つ目のpsw以外は,割込み発生時のコンテキストに対応したスタックに
179 * 退避する.2つ目のpswは,割込みハンドラの実行直後に復帰するために,
180 * 必
181ず割込みスタックに退避する.遅
182延ディスパッチする場合には,上記の
183 * レジスタ以外にも,r8-r13を退避してディスパッチャを呼び出す.
184 */
185 .balign 0x10
186interrupt_handler:
187
188 /*
189 * 作業用レジスタの退避
190 *
191 * 最初に作業用レジスタをスタックに退避する.割込み発生直後は,必
192
193 * ず割込みスタックになるので,ここで退避する作業用レジスタは割込
194 * みスタックに積まれる.
195 */
196 stmdb "r0,r1"
197
198 /*
199 * 割込み発生時のコンテキスト判定
200 *
201 * pswのbsmビットから割込み発生時に使用していたスタック情
202報を取得
203 * する.bsmが0の場合は,割込みスタックを使用していたことになるの
204 * で,割込みコンテキストで割込みが発生したと判断する.bsmが1の場
205 * 合は,ユーザスタックを使用していたことになるので,タスクコンテ
206 * キストで割込みが発生したと判断する.後者
207の場合は,作業領域(r0
208 * とr1)の積み直しは必
209要ない.
210 */
211 mvfc r0, psw
212 and3 r1, r0, 0x8000
213 beqz r1, L1
214
215 /*
216 * 退避レジスタのユーザスタックへの積み直し
217 *
218 * タスクコンテキストで割込みが発生した場合は,割込みスタックに退
219 * 避した作業用レジスタr0とr1をユーザスタックに積み直す必
220要がある.
221 */
222
223 or3 r0, r0, 0x80
224 mvtc r0, psw /* ユーザスタックに切替(sp = spu) */
225
226 mvfc r1, spi
227 ld r0, @(4, r1) /* 退避したr0を割込みスタックから取り出す */
228 st r0, @-sp /* r0をユーザスタックに積む */
229 ld r0, @r1 /* 退避したr1を割込みスタックから取り出す */
230 st r0, @-sp /* r1をユーザスタックに積む */
231 addi r1, 8 /* 割込みスタックを作業スタック退避前に戻す */
232 mvtc r1, spi /* 割込みスタック位置をspiに保存 */
233 mvfc r0, psw
234
235L1:
236 /*
237 * コンテキストの退避
238 *
239 * r2-r7, r14, acch, accl, bpc, psw, 割込みマスク(ICUISTS),psw
240 * の順にスタックに退避する.ここでは,必
241ずpswがr0に保存されてい
242 * る.
243 */
244 stmdb "r2,r3,r4,r5,r6,r7,r14"
245 mvfachi r1
246 st r1, @-sp /* acchを退避 */
247 mvfaclo r1
248 st r1, @-sp /* acclを退避 */
249 mvfc r1, bpc
250 st r1, @-sp /* bpcを退避 */
251 st r0, @-sp /* pswを退避 */
252
253 ld24 r1, ICUISTS
254 ld r0, @r1 /* 割込みマスク読み込み(割込み要求はクリアされる)*/
255 st r0, @-sp /* 割込みマスクを退避 */
256
257 lea r1, InterruptHandlerEntry /* 割込みハンドラテーブルのå…
258ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’取り出す */
259 srli r0, 22 /* 割込み要因番号を取得 */
260 addi r0, -1 /* 割込みハンドラテーブルのインデックスを計算 */
261 slli r0, 2 /* 割込みハンドラテーブルのオフセットを計算 */
262 add r1, r0 /* 割込みハンドラテーブル中の割込みハンドラのアドレス計算 */
263 ld r1, @r1 /* 割込みハンドラの起動番地を取り出す */
264
265L2:
266 /*
267 * 割込みハンドラの呼出し
268 *
269 * pswを退避し,割込みスタック, 割込み許可にして割込みハンドラを
270 * 呼び出す.割込みハンドラからの戻り番地をeit_handler_rとする.
271 * ここで,再度pswを退避するのは,eit_handler_rの最初で,使用する
272 * スタックを戻す必
273要があるためで,必
274ず割込みスタックに退避してお
275 * く.
276 */
277 mvfc r2, psw
278 and3 r3, r2, 0xff7f
279 mvtc r3, psw /* 割込みスタック */
280 st r2, @-sp /* pswを割込みスタックに退避 */
281 lea r14, eit_handler_r /* 戻り番地を設定 */
282 or3 r3, r3, 0x40
283 mvtc r3, psw /* 割込み許可 */
284 jmp r1 /* ハンドラ起動 */
285
286 .text
287 .align 4
288eit_handler_r:
289 /*
290 * EITハンドラからの復帰処理
291 *
292 * EITハンドラの実行が終了すると呼び出される.割込み発生時のコン
293 * テキスト,割込み要求の有無,ディスパッチ許可/禁止状æ…
294‹ã‹ã‚‰ï¼Œé©
295 * 切な復帰処理を行なう.
296 */
297 ld r0, @sp+
298 mvtc r0, psw /* 割込みスタックからpswを復帰(EIT発生時
299 のコンテキストに戻る.割込みは禁止状æ…
300‹ï¼‰
301 */
302
303 ld24 r1, ICUIMASK
304 ld r2, @sp+
305 st r2, @r1 /* 割込みマスクの復帰 */
306
307 and3 r0, r0, 0x8000
308 beqz r0, recover_int /* EIT発生時のコンテキストが割込みコンテキ
309 ストであれば,多重割込みであると判断し,
310 即座にå…
311±é€šå¾©å¸°å‡¦ç†ã¸ */
312
313 /*
314 * タスクコンテキストへの復帰ルーチン
315 *
316 * ディスパッチ/タスク例外起動要求がない場合は,即座にå…
317±é€šå¾©å¸°ãƒ«ãƒ¼
318 * チンに飛ぶ.遅
319延ディスパッチ処理を行なう.ディスパッチ要求がな
320 * ければå…
321±é€šã®å¾©å¸°å‡¦ç†ï¼ˆrecover_int)を行なう.
322 */
323 lea r0, _kernel_reqflg
324 ld r1, @r0
325 beqz r1, recover_int /* å…
326±é€šå¾©å¸°ãƒ«ãƒ¼ãƒãƒ³ã¸ */
327
328 /*
329 * ディスパッチ/タスク例外起動要求がある場合の処理
330 *
331 * まず,ディスパッチ要求フラグ(reqflg)をクリアする.そして,ディ
332 * スパッチ許可フラグ(enadsp)がFALSEの場合と,runtskとschedtsk
333 * が同じ場合には,ディスパッチせずに,タスク例外起動処理ルーチン
334 * へ飛ぶ.ディスパッチが許可されており,runtskとschedtskが異なる
335 * 場合には,遅
336延ディスパッチ処理を行う.
337 */
338 ldi r1, #0
339 st r1, @r0 /* reqflgをクリア */
340
341 lea r0, _kernel_enadsp
342 ld r0, @r0
343 beqz r0, recover_task /* enaflgのチェック */
344
345 lea r0, _kernel_runtsk
346 lea r1, _kernel_schedtsk
347 ld r0, @r0
348 ld r1, @r1
349 beq r0, r1, recover_task /* runtskとschedtskが同じ場合はタ
350 スク例外起動処理へ */
351
352 /*
353 * 例外/割込み出口での遅
354延ディスパッチ処理
355 *
356 * 退避していない残りのレジスタを退避し,実行状æ…
357‹ã‚¿ã‚¹ã‚¯ã®pcとspを
358 * 退避してからディスパッチャを呼び出す.
359 */
360 stmdb "r8,r9,r10,r11,r12,r13"
361
362 lea r0, _kernel_runtsk
363 ld r0, @r0
364
365 lea r1, recover_task_r
366 st r1, @(TCB_pc, r0)
367 st sp, @(TCB_sp, r0)
368 bra _kernel_exit_and_dispatch
369
370 .align 4
371recover_task_r:
372 ldmia "r13,r12,r11,r10,r9,r8"
373
374recover_task:
375 /*
376 * タスク例外起動処理
377 *
378 * ここで,enatexがTRUEで,texptnが0でなければ,タスク例外処理ルー
379 * チンを呼び出す.calltexの処理内
380容(runtsk->enatexがTRUEで,
381 * runtsk->texptnが0でない場合に,call_texrtnを呼ぶ)をここにイン
382 * ライン展開した方が効率が良いが,実装
383の簡易化のためにcalltex を
384 * 呼び出す.
385 */
386 bl _kernel_calltex
387
388recover_int:
389 /*
390 * EITå…
391±é€šå¾©å¸°å‡¦ç†ï¼ˆä½Žå„ªå…
392ˆåº¦å‰²è¾¼ã¿ã¸ã®å¾©å¸°å«ã‚€ï¼‰
393 *
394 * 退避した順番(r2-r7, r14, acch, accl, bpc, psw)の逆順でスタッ
395 * クから取り出して復帰する.また,作業用レジスタ(r0,r1)も復帰
396 * する.
397 */
398 ld r0, @sp+
399 mvtc r0, psw /* pswを復帰 */
400 ld r0, @sp+
401 mvtc r0, bpc /* bpcを復帰 */
402 ld r0, @sp+
403 mvtaclo r0 /* acclを復帰 */
404 ld r0, @sp+
405 mvtachi r0 /* acchlを復帰 */
406 ldmia "r14,r7,r6,r5,r4,r3,r2" /* その他のレジスタを復帰 */
407 ldmia "r1,r0" /* 作業用レジスタの復帰 */
408 rte /* 割込み処理から復帰 */
409
410 .section ".vector","ax"
411 /*
412 * トラップのエントリ部 : トラップ番号の格納
413 */
414 .irp num,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
415 .align 4
416
417 _kernel__trap_handler_\num:
418 stmdb "r0,r1"
419 ldi r1, #((\num + EXC_TRAP00 - 1) * 4)
420 bra _exception_handler
421 .endr
422
423/*
424 * 例外/トラップハンドラå…
425¥å£å‡¦ç†
426 *
427 * 例外が発生した場合には,スクラッチレジスタを退避して例外要因(r1に
428 * å…
429¥ã£ã¦ã„る)に対応する例外ハンドラを呼び出す.例外ハンドラからの復
430 * 帰処理は,割込みハンドラからの復帰処理とå…
431±é€šï¼ˆeit_handler_r)である.
432 *
433 * 例外発生時のハードウエアの動作
434 *
435 * pswレジスタ中のsm,ie,pm,cビットをbsm,bie,bpm,bcビットに退避
436 * する.bpcには例外を起こした命令のpc値がå…
437¥ã‚‹ï¼Ž
438 *
439 * bsm <- sm
440 * bie <- ie
441 * bpm <- pm
442 * bc <- c
443 * bpc <- 例外を起こした命令のアドレス
444 *
445 * pswレジスタ中のsm,ie,pm,cビットを以下のように更新する.
446 *
447 * sm <- 不変
448 * ie <- 0
449 * pm <- 0
450 * c <- 0
451 *
452 * レジスタの積み方
453 *
454 * r0-r1(作業領域,ベクタの最初で退避)
455 * r2-r7,r14,acc(hi/lo),bpc,psw,ICUIMASK(例外ハンドラ呼出前)
456 *
457 * ここで,ICUISTSではなくICUIMASKを退避するのは,例外処理中に外部割
458 * 込みが発生した場合に,ICUISTSの読込みにより割込み要因がクリアされ
459 * てしまうのを防ぐためである.
460 */
461_exception_handler:
462
463 stmdb "r2,r3,r4,r5,r6,r7,r14"
464 mvfachi r0
465 st r0, @-sp
466 mvfaclo r0
467 st r0, @-sp
468 mvfc r0, bpc
469 st r0, @-sp
470 mvfc r2, psw
471 st r2, @-sp
472 ld24 r0, ICUIMASK
473 ld r0, @r0
474 st r0, @-sp
475
476 lea r0, ExceptionHandlerEntry
477 add r0, r1
478 ld r1, @r0 /* 例外ハンドラのアドレスを取得 */
479
480 mv r0, sp /* スタックの位置を例外ハンドラの引数
481 に設定 */
482 and3 r3, r2, 0x7f00
483 srli r3, 8
484 mvtc r3, psw /* 割込みスタック,割込み許可状æ…
485‹ã« */
486 st r2, @-sp /* 例外発生直後のpswを割込みスタックに退避 */
487 lea r14, eit_handler_r
488 jmp r1
489
490Function _kernel_dispatch
491 /*
492 * タスク切替えのための退避処理
493 *
494 * このルーチンは,タスクコンテキスト,CPUロック状æ…
495‹ï¼Œãƒ‡ã‚£ã‚¹ãƒ‘ッ
496 * チ許可状æ…
497‹ã§å‘¼ã³å‡ºã•ã‚Œã‚‹ï¼Žå‘¼å‡ºå…
498ƒã§ã¯ä¿å­˜ã•ã‚Œãªã„レジスタをスタッ
499 * クに退避し,pcとspはTCBに退避する.pcはディスパッチャ出口処理
500 * (dispatch_r)に設定する.
501 */
502 stmdb "r8,r9,r10,r11,r12,r13,r14"
503
504 lea r0, _kernel_runtsk
505 lea r1, dispatch_r
506 ld r0, @r0
507 st r1, @(TCB_pc, r0) /* 復帰する時はdispatch_rに帰ってくる */
508 st sp, @(TCB_sp, r0) /* スタックポインタを退避 */
509
510Function _kernel_exit_and_dispatch
511 /*
512 * タスク切替えの前処理
513 *
514 * schedtskが空でないかをチェックする.schedtskが空でない場合は,
515 * タスク切替え処理に移る.空の場合は,割込みを許可してループする
516 * 処理に移る.
517 */
518 xor r0, r0
519 mvtc r0, psw /* 割込み禁止,割込みスタック */
520
521 lea r1, _kernel_schedtsk
522L6: ld r0, @r1
523 bnez r0, L7 /* schedtskの有無をチェック */
524
525 /*
526 * 起動すべきタスクがない場合の処理
527 *
528 * 起動すべきタスクがない場合は,割込みを許可してループする.ルー
529 * プの途中で割込みを許可し,実行可能タスクを待
530つ.
531 */
532 ldi r0, 0x40
533 mvtc r0, psw /* 割込み許可 */
534 xor r0, r0
535 mvtc r0, psw /* 割込み禁止 */
536
537 lea r0, _kernel_reqflg
538 xor r2, r2
539 st r2, @r0 /* reqflg = 0 */
540 bl L6
541
542L7:
543 /*
544 * タスク切替え処理
545 *
546 * 実行中タスク(runtsk)に最高優å…
547ˆé †ä½ã‚¿ã‚¹ã‚¯ï¼ˆschedtsk)を設定し,
548 * スタックをユーザスタックに切替える.runtskのTCBのspとpcを復帰
549 * する.ここでは,r0 = schedtskである.
550 */
551 lea r2, _kernel_runtsk
552 st r0, @r2 /* runtsk = schedtsk */
553
554 ldi r1, 0x80
555 mvtc r1, psw /* ユーザスタック,割込み禁止 */
556
557 ld sp, @(TCB_sp, r0) /* スタックポインタを復帰 */
558 ld r0, @(TCB_pc, r0) /* プログラムカウンタを復帰 */
559 jmp r0
560
561 .align 4
562Label dispatch_r
563 /*
564 * ディスパッチャの出口処理
565 *
566 * dispatchで退避したレジスタを復帰し,タスク例外処理ルーチンを呼
567 * び出す.
568 */
569 bl _kernel_calltex
570 ldmia "r14,r13,r12,r11,r10,r9,r8"
571 rts
572
573Function _kernel_activate_r
574 /*
575 * タスクの起動ルーチン
576 *
577 * runtskのタスク初期化ブロックからタスク関数と拡張情
578報を取り出し
579 * て,拡張情
580報を引数レジスタ(r0)に設定する.ext_tskを呼び出さ
581 * ずにタスクが終了する場合があるため,タスク関数の戻り番地を
582 * ext_tskに設定する.起動準備がå…
583¨ã¦å®Œäº†ã—てから,割込みを許可し
584 * てタスク関数に飛ぶ.
585 */
586 lea r2, _kernel_runtsk
587 ld r2, @r2
588 ld r2, @(TCB_tinib, r2) /* r2 = runtsk->tinib */
589 ld r0, @(TINIB_exinf, r2)
590 ld r1, @(TINIB_task, r2)
591
592 lea r14, ext_tsk /* タスクの戻り番地をext_tskに */
593
594 ldi r2, 0xc0
595 mvtc r2, psw /* ユーザスタック,割込み許可 */
596 jmp r1 /* タスク関数へ */
Note: See TracBrowser for help on using the repository browser.