source: atk2-sc3_fl850f1l/arch/v850_ccrh/prc_support.asm@ 117

Last change on this file since 117 was 117, checked in by ertl-ishikawa, 9 years ago

ATK2-SC3 1.3.2 FL850F1L(RH850F1L)依存部(GCC/GHS/CCRH)を追加

File size: 82.1 KB
Line 
1;/*
2 ;* TOPPERS ATK2
3 ;* Toyohashi Open Platform for Embedded Real-Time Systems
4 ;* Automotive Kernel Version 2
5 ;*
6 ;* Copyright (C) 2012-2015 by Center for Embedded Computing Systems
7 ;* Graduate School of Information Science, Nagoya Univ., JAPAN
8 ;* Copyright (C) 2012-2013 by FUJISOFT INCORPORATED, JAPAN
9 ;* Copyright (C) 2012-2013 by FUJITSU VLSI LIMITED, JAPAN
10 ;* Copyright (C) 2012-2013 by NEC Communication Systems, Ltd., JAPAN
11 ;* Copyright (C) 2012-2013 by Panasonic Advanced Technology Development Co., Ltd., JAPAN
12 ;* Copyright (C) 2012-2013 by Renesas Electronics Corporation, JAPAN
13 ;* Copyright (C) 2012-2013 by Sunny Giken Inc., JAPAN
14 ;* Copyright (C) 2012-2013 by TOSHIBA CORPORATION, JAPAN
15 ;* Copyright (C) 2012-2013 by Witz Corporation, JAPAN
16 ;* Copyright (C) 2013 by Embedded and Real-Time Systems Laboratory
17 ;* Graduate School of Information Science, Nagoya Univ., JAPAN
18 ;*
19 ;* 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
20 ;* ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
21 ;* 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
22 ;* (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
23 ;* 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
24 ;* スコード中に含まれていること.
25 ;* (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
26 ;* 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
27 ;* 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
28 ;* の無保証規定を掲載すること.
29 ;* (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
30 ;* 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
31 ;* と.
32 ;* (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
33 ;* 作権表示,この利用条件および下記の無保証規定を掲載すること.
34 ;* (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
35 ;* 報告すること.
36 ;* (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
37 ;* 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
38 ;* また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
39 ;* 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
40 ;* 免責すること.
41 ;*
42 ;* 本ソフトウェアは,AUTOSAR(AUTomotive Open System ARchitecture)仕
43 ;* 様に基づいている.上記の許諾は,AUTOSARの知的財産権を許諾するもので
44 ;* はない.AUTOSARは,AUTOSAR仕様に基づいたソフトウェアを商用目的で利
45 ;* 用する者に対して,AUTOSARパートナーになることを求めている.
46 ;*
47 ;* 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
48 ;* よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
49 ;* に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
50 ;* アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
51 ;* の責任を負わない.
52 ;*
53 ;* $Id: prc_support.asm 189 2015-06-26 01:54:57Z t_ishikawa $
54 ;*/
55
56;/*
57 ;* ターゲット依存情報の定義
58 ;*/
59$include (v850asm.inc)
60$include (offset.h)
61
62$ifdef USE_ASMCONFIG_INC
63$include (asm_config.inc)
64$endif ;/* USE_ASMCONFIG_INC */
65
66$ifdef __v850e2v3__
67
68;/*
69 ;* V850E2用の割込みコントローラ操作ルーチン
70 ;*/
71GET_ISPR .macro reg
72 mov ISPR_H, reg
73 ld.h 0[reg],reg
74.endm
75
76CLEAR_ISPR .macro reg1, reg2
77 mov ISPC_H,reg1
78 mov 0xffff,reg2
79 st.h reg2,0[reg1]
80 mov ISPR_H, reg1
81 st.h r0,0[reg1]
82.endm
83
84SET_PMR .macro reg_val, reg_tmp
85 mov PMR, reg_tmp
86 st.h reg_val, 0[reg_tmp] ;/* set interrupt level */
87 syncm
88.endm
89
90$endif ;/* __v850e2v3__ */
91
92$ifdef __v850e3v5__
93
94;/*
95 ;* V850E3V5用の割込みコントローラ操作ルーチン
96 ;*/
97GET_ISPR .macro reg
98 stsr 10, reg, 2
99.endm
100
101SET_ISPR .macro val, reg
102 movea val,r0,reg
103 ldsr reg, 10, 2
104 syncp
105.endm
106
107SET_INTCFG .macro val, reg
108 movea val,r0,reg
109 ldsr reg, 13, 2
110 syncp
111.endm
112
113CLEAR_ISPR .macro reg1, reg2
114 SET_INTCFG 1, reg1 ;/* ISPR を書き換え可能に */
115 SET_ISPR 0, reg1 ;/* ISPR のクリア */
116 SET_INTCFG 0, reg1 ;/* ISPR を書き換え禁止に(自動更新に) */
117.endm
118
119GET_PMR .macro reg
120 stsr 11, reg, 2
121.endm
122
123SET_PMR .macro reg_val, reg_tmp
124 stsr psw, reg_tmp
125 di
126 ldsr reg_val, 11, 2
127 ldsr reg_tmp, psw
128 syncp
129.endm
130
131GET_ICSR .macro reg
132 stsr sr12, reg, 2
133.endm
134
135SET_ICSR .macro val, reg
136 movea val,r0,reg
137 ldsr \reg, sr12, 2
138.endm
139
140$endif ;/* !__v850e3v5__ */
141
142
143;/*
144 ;* OS割込み禁止マクロ
145 ;* ネストの一番外側で呼び出されることを想定している
146 ;*/
147OUTER_LOCK_OS_INT .macro reg12, reg13
148
149 ;/* pmr_isr2_mask -> PMR */
150 Lea _pmr_isr2_mask, reg13
151 ld.h 0[reg13], reg13
152 SET_PMR reg13, reg12
153
154 ;/* nested_lock_os_int_cnt = 1 */
155 Lea _nested_lock_os_int_cnt, reg12
156 mov 1, reg13
157 st.b reg13, 0[reg12]
158
159.endm
160
161;/*
162 ;* OS割込み禁止解除マクロ
163 ;* ネストの一番外側で呼び出されることを想定している
164 ;*/
165OUTER_UNLOCK_OS_INT .macro reg12, reg13
166
167 ;/* nested_lock_os_int_cnt = 0 */
168 Lea _nested_lock_os_int_cnt, reg12
169 mov r0, reg13
170 st.b reg13, 0[reg12]
171
172 ;/* pmr_setting_tbl[current_iintpri] -> PMR */
173 Lea _current_iintpri, reg12
174 ld.bu 0[reg12], reg12
175 shl 1, reg12
176
177 Lea _pmr_setting_tbl, reg13
178 add reg12, reg13
179 ld.h 0[reg13], reg13
180 SET_PMR reg13, reg12 ;/* set interrupt level */
181
182.endm
183
184;/* =begin modified for SC3 */
185;/*
186 ;* OS割込み禁止マクロ
187 ;* ネストあり
188 ;*/
189NESTED_LOCK_OS_INT .macro reg12, reg13
190
191 ;/* nested_lock_os_int_cnt == 0 ? */
192 Lea _nested_lock_os_int_cnt, reg13
193 ld.b 0[reg13], reg12
194 cmp r0, reg12
195 bne increment_nest_lock
196
197 ;/* pmr_isr2_mask -> PMR */
198 Lea _pmr_isr2_mask, reg13
199 ld.h 0[reg13], reg13
200 SET_PMR reg13, reg12 ;/* set interrupt level */
201 Lea _nested_lock_os_int_cnt, reg13
202 mov r0, reg12 ;/* nested_lock_os_int_cnt = 0 */
203
204increment_nest_lock:
205 ;/* nested_lock_os_int_cnt += 1 */
206 add 1, reg12
207 st.b reg12, 0[reg13]
208
209.endm
210
211;/*
212 ;* OS割込み禁止解除マクロ
213 ;* ネストあり
214 ;*/
215NESTED_UNLOCK_OS_INT .macro reg12, reg13
216
217 ;/* nested_lock_os_int_cnt -= 1 */
218 Lea _nested_lock_os_int_cnt, reg12
219 ld.b 0[reg12], reg13
220 add -1, reg13
221 st.b reg13, 0[reg12]
222 cmp r0, reg13
223 bne nested_unlock_exit
224
225 ;/* pmr_setting_tbl[current_iintpri] -> PMR */
226 Lea _current_iintpri, reg12
227 ld.bu 0[reg12], reg12
228 shl 1, reg12
229
230 Lea _pmr_setting_tbl, reg13
231 add reg12, reg13
232 ld.h 0[reg13], reg13
233 SET_PMR reg13, reg12 ;/* set interrupt level */
234
235nested_unlock_exit:
236.endm
237
238;/* =end modified for SC3 */
239
240 ;/*
241 ;* 割込み例外入り口でのレジスタの保存マクロ
242 ;*/
243INT_EXC_SAVEREG .macro
244$ifdef TOPPERS_USE_HFLOAT
245 addi -88 , sp , sp
246$else ;/* !TOPPERS_USE_HFLOAT */
247 addi -84 , sp , sp
248$endif ;/* TOPPERS_USE_HFLOAT */
249 st.w r30, 12[sp] ;/* r30(ep) */
250 ;/*
251 ;* 割込み発生前のr2はeiwrに保存されている
252 ;* ここで,r2はすでにワークレジスタとして
253 ;* 使用中であるため,上書きしない
254 ;* r2に入っている割込み番号を破壊しないように
255 ;*/
256 stsr eiwr, r30 ;/* r2->r30に復帰 */
257 st.w r30, 76[sp]
258 mov sp, ep
259 sst.w r1, 80[ep]
260 sst.w r5, 72[ep]
261 sst.w r6, 68[ep]
262 sst.w r7, 64[ep]
263 sst.w r8, 60[ep]
264 sst.w r9, 56[ep]
265 sst.w r10, 52[ep]
266 sst.w r11, 48[ep]
267 sst.w r12, 44[ep]
268 sst.w r13, 40[ep]
269 sst.w r14, 36[ep]
270 sst.w r15, 32[ep]
271 sst.w r16, 28[ep]
272 sst.w r17, 24[ep]
273 sst.w r18, 20[ep]
274 sst.w r19, 16[ep]
275 sst.w r31, 8[ep]
276$ifdef TOPPERS_USE_HFLOAT
277 stsr fpsr, r19 ;/* load FPSR */
278 sst.w r19, 84[ep]
279$endif ;/* TOPPERS_USE_HFLOAT */
280.endm
281
282 ;/*
283 ;* 割込み例外入り口でのレジスタの復帰マクロ
284 ;*/
285INT_EXC_RESTOREREG .macro
286$ifdef TOPPERS_USE_HFLOAT
287 sld.w 84[ep], r19
288 ldsr r19, fpsr ;/* store FPSR */
289$endif ;/* TOPPERS_USE_HFLOAT */
290 sld.w 80[ep], r1
291 sld.w 76[ep], r2
292 sld.w 72[ep], r5
293 sld.w 68[ep], r6
294 sld.w 64[ep], r7
295 sld.w 60[ep], r8
296 sld.w 56[ep], r9
297 sld.w 52[ep], r10
298 sld.w 48[ep], r11
299 sld.w 44[ep], r12
300 sld.w 40[ep], r13
301 sld.w 36[ep], r14
302 sld.w 32[ep], r15
303 sld.w 28[ep], r16
304 sld.w 24[ep], r17
305 sld.w 20[ep], r18
306 sld.w 16[ep], r19
307 sld.w 8[ep], r31
308$ifdef TOPPERS_USE_HFLOAT
309 addi 88, ep, sp
310$else ;/* !TOPPERS_USE_HFLOAT */
311 addi 84, ep, sp
312$endif ;/* TOPPERS_USE_HFLOAT */
313 sld.w 12[ep], r30 ;/* r30(ep) */
314 ldsr r2, eiwr ;/* r2を退避 */
315.endm
316
317
318$ifdef __v850e3v5__
319 ;/*
320 ;* V850E3V5用ベクタ
321 ;* ここにRBASEが設定されることを想定(ここが電源投入時の開始アドレス)
322 ;* (EIレベル割込みはテーブル参照方式を使用するため本ベクタは使用しない)
323 ;*/
324 RESET .cseg text
325 .extern __reset
326__reset:
327 jr __start
328 .rept 6
329 nop
330 .endm
331__syserr: ;/* 0x0010 */
332 ldsr r2, eiwr
333 movea E_OS_PROTECTION_EXCEPTION, r0, r2
334 jr _fe_exception_entry
335 .rept 2
336 nop
337 .endm
338__hvtrap: ;/* 0x0020 */
339 ldsr r2, eiwr
340 movea E_OS_PROTECTION_EXCEPTION, r0, r2
341 jr _fe_exception_entry
342 .rept 2
343 nop
344 .endm
345__fetrap: ;/* 0x0030 */
346 ldsr r2, eiwr
347 movea E_OS_PROTECTION_EXCEPTION, r0, r2
348 jr _fe_exception_entry
349 .rept 2
350 nop
351 .endm
352__trap0: ;/* 0x0040 */
353 ldsr r2, eiwr
354 movea E_OS_PROTECTION_EXCEPTION, r0, r2
355 jr _ei_exception_entry
356 .rept 2
357 nop
358 .endm
359__trap1: ;/* 0x0050 */
360 ldsr r2, eiwr
361 movea E_OS_PROTECTION_EXCEPTION, r0, r2
362 jr _ei_exception_entry
363 .rept 2
364 nop
365 .endm
366__rie: ;/* 0x0060 */
367 ldsr r2, eiwr
368 movea E_OS_PROTECTION_EXCEPTION, r0, r2
369 jr _ei_exception_entry
370 .rept 2
371 nop
372 .endm
373__fppfpi: ;/* 0x0070 */
374 ldsr r2, eiwr
375 movea E_OS_PROTECTION_EXCEPTION, r0, r2
376 jr _ei_exception_entry
377 .rept 2
378 nop
379 .endm
380__ucpop: ;/* 0x080 */
381 ldsr r2, eiwr
382 movea E_OS_PROTECTION_EXCEPTION, r0, r2
383 jr _fe_exception_entry
384 .rept 2
385 nop
386 .endm
387__mip: ;/* 0x0090 */
388 ldsr r2, eiwr
389 movea E_OS_PROTECTION_MEMORY, r0, r2
390 jr _fe_exception_entry
391 .rept 2
392 nop
393 .endm
394__pie: ;/* 0x00a0 */
395 ldsr r2, eiwr
396 movea E_OS_PROTECTION_EXCEPTION, r0, r2
397 jr _fe_exception_entry
398 .rept 2
399 nop
400 .endm
401__debug: ;/* 0x00b0 */
402 jr __debug
403 .rept 6
404 nop
405 .endm
406__mae: ;/* 0x00c0 */
407 ldsr r2, eiwr
408 movea E_OS_PROTECTION_EXCEPTION, r0, r2
409 jr _fe_exception_entry
410 .rept 2
411 nop
412 .endm
413__rfu: ;/* 0x00d0 */
414 jr __rfu
415 .rept 6
416 nop
417 .endm
418__fenmi: ;/* 0x00e0 */
419 ldsr r2, eiwr
420 movea E_OS_PROTECTION_EXCEPTION, r0, r2
421 jr _fe_exception_entry
422 .rept 2
423 nop
424 .endm
425__feint: ;/* 0x00f0 */
426 ldsr r2, eiwr
427 movea E_OS_PROTECTION_EXCEPTION, r0, r2
428 jr _fe_exception_entry
429 .rept 2
430 nop
431 .endm
432__eiintn0: ;/*(優先度0) 0x0100 */
433 jr _default_int_handler
434 .rept 6
435 nop
436 .endm
437__eiintn1: ;/*(優先度1) 0x0110 */
438 jr _default_int_handler
439 .rept 6
440 nop
441 .endm
442__eiintn2: ;/*(優先度2) 0x0120 */
443 jr _default_int_handler
444 .rept 6
445 nop
446 .endm
447__eiintn3: ;/*(優先度3) 0x0130 */
448 jr _default_int_handler
449 .rept 6
450 nop
451 .endm
452__eiintn4: ;/*(優先度4) 0x0140 */
453 jr _default_int_handler
454 .rept 6
455 nop
456 .endm
457__eiintn5: ;/*(優先度5) 0x0150 */
458 jr _default_int_handler
459 .rept 6
460 nop
461 .endm
462__eiintn6: ;/*(優先度6) 0x0160 */
463 jr _default_int_handler
464 .rept 6
465 nop
466 .endm
467__eiintn7: ;/*(優先度7) 0x0170 */
468 jr _default_int_handler
469 .rept 6
470 nop
471 .endm
472__eiintn8: ;/*(優先度8) 0x0180 */
473 jr _default_int_handler
474 .rept 6
475 nop
476 .endm
477__eiintn9: ;/*(優先度9) 0x0190 */
478 jr _default_int_handler
479 .rept 6
480 nop
481 .endm
482__eiintn10: ;/*(優先度10) 0x01a0 */
483 jr _default_int_handler
484 .rept 6
485 nop
486 .endm
487__eiintn11: ;/*(優先度11) 0x01b0 */
488 jr _default_int_handler
489 .rept 6
490 nop
491 .endm
492__eiintn12: ;/*(優先度12) 0x01c0 */
493 jr _default_int_handler
494 .rept 6
495 nop
496 .endm
497__eiintn13: ;/*(優先度13) 0x01d0 */
498 jr _default_int_handler
499 .rept 6
500 nop
501 .endm
502__eiintn14: ;/*(優先度14) 0x01e0 */
503 jr _default_int_handler
504 .rept 6
505 nop
506 .endm
507__eiintn15: ;/*(優先度15) 0x01f0 */
508 jr _default_int_handler
509 .rept 6
510 nop
511 .endm
512
513$endif ;/* __v850e3v5__ */
514
515 kernel.text .cseg text
516 ;/*
517 ;* 例外エントリ(feretでリターンする例外用)
518 ;* ここで,CY = FEPSW.IMP,r2 = error code
519 ;* r2は例外エントリでスタックに保存済み
520 ;*/
521 .extern _fe_exception_entry
522_fe_exception_entry:
523 ldsr r2, fewr ;/* エラーコードを保存 */
524 stsr fepsw, r2
525 shl PSW_SV, r2 ;/* r2 << PSW_SV により例外発生時のモード取得 */
526 stsr fewr, r2 ;/* エラーコードを復帰 */
527 bnc fe_exception_0 ;/* 特権からの例外ならばスキップ */
528 ldsr r5, fewr ;/* tp(r5)を退避 */
529 Lea _hook_savedsp, r5
530 ld.w 0[r5], r5
531 cmp r0, r5
532 be fe_exception_from_utask
533 ;/*
534 ;* ユーザフックからの例外
535 ;* hook_savedspをユーザスタック上に保存
536 ;* +------------------+ <- sp
537 ;* | 前のhook_savedsp |
538 ;* +------------------+ <- 前のhook_savedsp
539 ;* | ................ |
540 ;* +------------------+
541 ;*/
542 addi -4, r5, r5
543 st.w sp, 0[r5] ;/* *(hook_savedsp - 4) = sp */
544 mov r5, sp ;/* sp = hook_savedsp - 4 */
545 stsr fewr, r5 ;/* tp(r5)を復帰 */
546 br fe_exception_0
547fe_exception_from_utask:
548 ;/*
549 ;* ユーザタスクからの例外
550 ;*/
551 Lea _p_runtsk, r5
552 ld.w 0[r5], r5
553 st.w sp, TCB_usp[r5] ;/* uspをTCBに保存 */
554 ld.w TCB_p_tinib[r5], r5
555 ld.w TINIB_sstk_bottom[r5], sp ;/* sspを復帰 */
556 stsr fewr, r5 ;/* tp(r5)を復帰 */
557fe_exception_0:
558 ;/* スクラッチレジスタを保存 */
559 INT_EXC_SAVEREG
560
561 ;/* 多重割込みのため,現在のFEPCとFEPSWを保存 */
562 stsr fepc, r6
563 sst.w r6, 4[ep]
564 stsr fepsw, r6
565 sst.w r6, 0[ep]
566
567 ;/*
568 ;* プロテクションフックはOS処理レベルで実行するためOS割込み禁止状態にする
569 ;* OS割込み禁止状態で例外が発生する可能性があるため,ネスト管理を行う.
570 ;* 例外は次の条件で発生する
571 ;* ・ISR1実行状態で発生した場合
572 ;* ・ISR1実行状態以外で発生した場合
573 ;* ・OS割込み解除状態で発生した場合
574 ;* ・OS割込み禁止状態で発生した場合
575 ;*/
576
577 ;/*
578 ;* カテゴリ1の割込み以外で例外が発生したかの判断する
579 ;* カテゴリ1で例外が発生:fe_exception_1へジャンプ
580 ;*/
581 GET_ISPR r6
582 Lea _pmr_isr1_mask, r7
583 ld.h 0[r7], r7
584 and r7, r6
585 cmp r0, r6
586 bne fe_exception_1
587
588 ;/*
589 ;* ISR1実行状態以外で発生した場合
590 ;*/
591 Lea _nested_lock_os_int_cnt, r12
592 ld.b 0[r12], r13
593 mov 1, r14
594 add r14, r13
595 st.b r13, 0[r12]
596 cmp 1, r13
597 bne fe_exception_1
598
599 ;/*
600 ;* OS割込み解除状態で発生した場合
601 ;* OS割込み禁止状態とする
602 ;*/
603 Lea _pmr_isr2_mask, r7
604 ld.h 0[r7], r7
605 SET_PMR r7, r6 ;/* pmr_isr2_mask -> PMR */
606
607fe_exception_1:
608 ;/*
609 ;* 割込み発生時に変更されるので割込み解除前に取得
610 ;*/
611 stsr feic, r19 ;/* 例外要因 */
612 stsr fepc, r18 ;/* 例外発生PC */
613
614 ;/*
615 ;* C1ISRを受け付けるため,NPbit クリア
616 ;*/
617 stsr psw, r12
618 mov !0x0080, r13
619 and r12, r13
620 ldsr r13, psw
621
622fe_exception_2:
623 ;/*
624 ;* カーネル起動していない場合に起きたCPU例外は,無限ループへ
625 ;*/
626 Lea _kerflg, r12 ;/* kerflgがFALSEなら無限ループ */
627 ld.b 0[r12], r12
628 cmp r0, r12
629infinity_loop_fe:
630 be infinity_loop_fe
631
632 ;/*
633 ;* 多重割込みか判定
634 ;*/
635 Lea _except_nest_cnt, r12
636 ld.w 0[r12], r13
637 mov 1, r14 ;/* 割込み・例外のネスト回数のインクリメント */
638 add r14, r13
639 st.w r13, 0[r12]
640
641 mov sp, r9 ;/* sp をr9に退避 */
642
643 cmp 1, r13
644 bne fe_exception_3 ;/* _nested_lock_os_int_cnt > 1 -> fe_exception_3 */
645
646 ;/*
647 ;* C1ISR実行状態で発生した場合はスタックポインタの入れ替えしない
648 ;*/
649 GET_ISPR r6
650 Lea _pmr_isr1_mask, r7
651 ld.h 0[r7], r7
652 and r7, r6
653 cmp r0, r6
654 bne fe_exception_3
655
656 ;/* スタックポインタの保存と入れ替え */
657 Lea __ostkpt, r12
658 ld.w 0[r12], r12
659 add -4, r12
660 st.w sp, 0[r12] ;/* スタックポインタの保存 */
661 mov r12, sp ;/* スタックポインタの切り替え */
662
663fe_exception_3:
664 UNLOCK_ALL_INT
665
666$ifdef CFG_USE_PROTECTIONHOOK
667 ;/* v850_cpu_exp_*を退避するスペースを確保 */
668 addi -12, sp, sp
669
670 ;/* v850_cpu_exp_spの退避と設定 */
671 Lea _v850_cpu_exp_sp, r12
672 st.w r9, 0[r12]
673 st.w ep, 0[sp]
674 mov sp, ep
675
676 ;/* v850_cpu_exp_noの退避と設定 */
677 Lea _v850_cpu_exp_no, r12
678 ld.w 0[r12], r13
679 sst.w r13, 8[ep]
680 st.w r19, 0[r12] ;/* r19 例外要因 */
681
682 ;/* v850_cpu_exp_pcの退避と設定 */
683 Lea _v850_cpu_exp_pc, r12
684 ld.w 0[r12], r13
685 sst.w r13, 4[ep]
686 mov r18, r17 ;/* r18:fepc */
687 add -4, r17
688 st.w r17, 0[r12]
689
690$endif ;/* CFG_USE_PROTECTIONHOOK */
691
692 ;/*
693 ;* CPU例外が発生した場合,OSはE_OS_PROTECTION_EXCEPTIONをパラメータとして
694 ;* プロテクションフックを呼び出す
695 ;*/
696 ;/* =begin modified for SC3 */
697 ;/*
698 ;* 例外要因がMIP or 0xMDPのときのみ
699 ;* E_OS_PROTECTION_MEMORYをパラメータとする
700 ;*/
701 andi FE_MP_MASK, r19, r6
702 addi FE_MP_BIT, r0, ep
703 cmp ep, r6
704 be fe_exception_4
705 mov E_OS_PROTECTION_EXCEPTION, r2
706
707fe_exception_4:
708 mov r2, r6
709 ;/* =end modified for SC3 */
710 jarl _call_protectionhk_main, r31
711
712$ifdef CFG_USE_PROTECTIONHOOK
713 mov sp, ep
714
715 ;/* v850_cpu_exp_noを復帰 */
716 Lea _v850_cpu_exp_no, r12
717 sld.w 8[ep], r13
718 st.w r13, 0[r12]
719
720 ;/* v850_cpu_exp_pcを復帰 */
721 Lea _v850_cpu_exp_pc, r12
722 sld.w 4[ep], r13
723 st.w r13, 0[r12]
724
725 ;/* v850_cpu_exp_sp退避 */
726 Lea _v850_cpu_exp_sp, r12
727 sld.w 0[ep], r13
728 st.w r13, 0[r12]
729
730 ;/* v850_cpu_exp_*を退避したスペースを戻す */
731 addi 12, sp, sp
732$endif ;/* CFG_USE_PROTECTIONHOOK */
733
734fe_ret_exc:
735 LOCK_ALL_INT
736
737 ;/*
738 ;* プロテクションフックはOS割込み禁止状態で実行する
739 ;*/
740
741 ;/*
742 ;* 割込み・例外のネスト回数のデクリメント
743 ;*/
744 Lea _except_nest_cnt, r12
745 ld.w 0[r12], r13
746 mov -1, r14
747 add r14, r13
748 st.w r13, 0[r12]
749
750 ;/*
751 ;* OS割込み禁止状態の解除
752 ;*/
753 ;/*
754 ;* ISR1実行状態で発生した場合は
755 ;* (1)スタックポインタの入れ替えをしない
756 ;* (2)OS割込み禁止状態の解除をしない
757 ;*/
758 GET_ISPR r6
759 Lea _pmr_isr1_mask, r7
760 ld.h 0[r7], r7
761 and r7, r6
762 cmp r0, r6
763 bne ret_exc_2
764
765 ;/*
766 ;* ネスト回数が1以上なら割込み元がISRなため例外発生元へ復帰
767 ;* スタックポインタの入れ替えしない
768 ;*/
769 cmp r0, r13
770 bne ret_exc_1
771
772 ;/*
773 ;* 戻り先がタスクなためスタックを戻す
774 ;*/
775 ld.w 0[sp], sp
776
777ret_exc_1:
778 ;/*
779 ;* ISR1実行状態以外で発生した場合,OS割込み禁止状態の解除
780 ;*/
781 Lea _nested_lock_os_int_cnt, r12
782 ld.b 0[r12], r13
783 mov -1, r14
784 add r14, r13
785 st.b r13, 0[r12]
786 cmp r0, r13
787 bne ret_exc_2
788
789 ;/* OS割込みを解除 */
790 ;/* pmr_setting_tbl[current_iintpri] -> PMR */
791 Lea _current_iintpri, r12
792 ld.bu 0[r12], r12
793 shl 1, r12
794
795 Lea _pmr_setting_tbl, r13
796 add r12, r13
797 ld.h 0[r13], r13
798 SET_PMR r13, r12 ;/* set interrupt level */
799
800 ;/*
801 ;* 例外発生元へ復帰
802 ;*/
803ret_exc_2:
804 ;/*
805 ;* レジスタを復帰
806 ;*/
807 mov sp, ep
808 sld.w 4[ep], r10
809 ldsr r10, fepc
810 sld.w 0[ep], r10
811 ldsr r10, fepsw
812
813 ;/* スクラッチレジスタの復帰 */
814 INT_EXC_RESTOREREG
815
816 ldsr r2, fewr
817 stsr fepsw, r2 ;/* r2 = fepsw */
818 shl PSW_SV, r2 ;/* r2 << PSW_SV により例外発生時のモード取得 */
819 bnc return_from_fe_exception ;/* 特権からの例外ならばスキップ */
820 Lea _hook_savedsp, r2
821 ld.w 0[r2], r2
822 cmp r0, r2
823 be fe_exception_to_utask
824 addi -4, r2, r2
825 ld.w 0[r2], sp ;/* sp *(hook_savedsp - 4) */
826 ;/*
827 ;* ここで,hook_savedspを更新する必要はない
828 ;*/
829 br return_from_fe_exception
830fe_exception_to_utask:
831 Lea _p_runtsk, r2
832 ld.w 0[r2], r2
833 ld.w TCB_usp[r2], sp ;/* uspを復帰 */
834return_from_fe_exception:
835 stsr eiwr, r2
836 feret
837
838 ;/*
839 ;* 例外エントリ(eiretでリターンする例外用)
840 ;* ここで,CY = EIPSW.IMP,r2 = error code
841 ;* r2はOS側で予約する(割込み・例外の出入口の
842 ;* ワークレジスタとして使用する)ため,
843 ;* スタックに保存しない
844 ;*/
845 .extern _ei_exception_entry
846_ei_exception_entry:
847 ldsr r2, fewr ;/* エラーコードを保存 */
848 stsr eipsw, r2
849 shl PSW_SV, r2 ;/* r2 << PSW_SV により例外発生時のモード取得 */
850 stsr fewr, r2 ;/* エラーコードを復帰 */
851 bnc ei_exception_0 ;/* 特権からの例外ならばスキップ */
852 ldsr r5, fewr ;/* tp(r5)を退避 */
853 Lea _hook_savedsp, r5
854 ld.w 0[r5], r5
855 cmp r0, r5
856 be ei_exception_from_utask
857 ;/*
858 ;* ユーザフックからの例外
859 ;* hook_savedspをユーザスタック上に保存
860 ;* +------------------+ <- sp
861 ;* | 前のhook_savedsp |
862 ;* +------------------+ <- 前のhook_savedsp
863 ;* | ................ |
864 ;* +------------------+
865 ;*/
866 addi -4, r5, r5
867 st.w sp, 0[r5] ;/* *(hook_savedsp - 4) = sp */
868 mov r5, sp ;/* sp = hook_savedsp - 4 */
869 stsr fewr, r5 ;/* tp(r5)を復帰 */
870 br ei_exception_0
871ei_exception_from_utask:
872 ;/*
873 ;* ユーザタスクからの例外
874 ;*/
875 Lea _p_runtsk, r5
876 ld.w 0[r5], r5
877 st.w sp, TCB_usp[r5] ;/* uspを保存 */
878 ld.w TCB_p_tinib[r5], r5
879 ld.w TINIB_sstk_bottom[r5], sp ;/* sspを復帰 */
880 stsr fewr, r5 ;/* tp(r5)を復帰 */
881ei_exception_0:
882 ;/* スクラッチレジスタの保存 */
883 INT_EXC_SAVEREG
884
885 ;/* 多重割込みのため,現在のEIPCとEIPSWを保存 */
886 stsr eipc, r6
887 sst.w r6, 4[ep]
888 stsr eipsw, r6
889 sst.w r6, 0[ep]
890
891 ;/*
892 ;* プロテクションフックはOS処理レベルで実行するためOS割込み禁止状態にする
893 ;* OS割込み禁止状態で例外が発生する可能性があるため,ネスト管理を行う.
894 ;* 例外は次の条件で発生する
895 ;* ・ISR1実行状態で発生した場合
896 ;* ・ISR1実行状態以外で発生した場合
897 ;* ・OS割込み解除状態で発生した場合
898 ;* ・OS割込み禁止状態で発生した場合
899 ;*/
900
901 ;/*
902 ;* カテゴリ1の割り込み以外で例外が発生したかの判断する
903 ;* カテゴリ1で例外が発生:ei_exception_1へジャンプ
904 ;*/
905 GET_ISPR r6
906 Lea _pmr_isr1_mask, r7
907 ld.h 0[r7], r7
908 and r7, r6
909 cmp r0, r6
910 bne ei_exception_1
911
912 ;/*
913 ;* ISR1実行状態以外で発生した場合
914 ;*/
915 Lea _nested_lock_os_int_cnt, r12
916 ld.b 0[r12], r13
917 mov 1, r14
918 add r14, r13
919 st.b r13, 0[r12]
920 cmp 1, r13
921 bne ei_exception_1
922
923 ;/*
924 ;* OS割込み解除状態で発生した場合
925 ;* OS割込み禁止状態とする
926 ;*/
927 Lea _pmr_isr2_mask, r7
928 ld.h 0[r7], r7
929 SET_PMR r7, r6 ;/* pmr_isr2_mask -> PMR */
930
931ei_exception_1:
932 ;/*
933 ;* 割込み発生時に変更されるので割込み解除前に取得
934 ;*/
935 stsr eiic, r19 ;/* 例外要因 */
936 stsr eipc, r18 ;/* 例外発生PC */
937
938
939ei_exception_2:
940 ;/*
941 ;* カーネル起動していない場合に起きたCPU例外は,無限ループへ
942 ;*/
943 Lea _kerflg, r12 ;/* kerflgがFALSEなら無限ループ */
944 ld.b 0[r12], r12
945 cmp r0, r12
946infinity_loop_ei:
947 be infinity_loop_ei
948
949 ;/*
950 ;* 多重割込みか判定
951 ;*/
952 Lea _except_nest_cnt, r12
953 ld.w 0[r12], r13
954 mov 1, r14 ;/* 割込み・例外のネスト回数のインクリメント */
955 add r14, r13
956 st.w r13, 0[r12]
957
958 mov sp, r9 ;/* sp をr9に退避 */
959
960 cmp 1, r13
961 bne ei_exception_3 ;/* _nested_lock_os_int_cnt > 1 -> ei_exception_3 */
962
963 ;/*
964 ;* ISR1実行状態で発生した場合はスタックポインタの入れ替えしない
965 ;*/
966 GET_ISPR r6
967 Lea _pmr_isr1_mask, r7
968 ld.h 0[r7], r7
969 and r7, r6
970 cmp r0, r6
971 bne ei_exception_3
972
973 ;/* スタックポインタの保存と入れ替え */
974 Lea __ostkpt, r12
975 ld.w 0[r12], r12
976 add -4, r12
977 st.w sp, 0[r12] ;/* スタックポインタの保存 */
978 mov r12, sp ;/* スタックポインタの切り替え */
979
980ei_exception_3:
981 UNLOCK_ALL_INT
982
983$ifdef CFG_USE_PROTECTIONHOOK
984 ;/* v850_cpu_exp_*を退避するスペースを確保 */
985 addi -12, sp, sp
986
987 ;/* v850_cpu_exp_spの退避と設定 */
988 Lea _v850_cpu_exp_sp, r12
989 st.w r9, 0[r12]
990 st.w ep, 0[sp]
991 mov sp, ep
992
993 ;/* v850_cpu_exp_noの退避と設定 */
994 Lea _v850_cpu_exp_no, r12
995 ld.w 0[r12], r13
996 sst.w r13, 8[ep]
997 st.w r19, 0[r12] ;/* r19 例外要因 */
998
999 ;/* v850_cpu_exp_pcの退避と設定 */
1000 Lea _v850_cpu_exp_pc, r12
1001 ld.w 0[r12], r13
1002 sst.w r13, 4[ep]
1003 mov r18, r17 ;/* r18:fepc */
1004 add -4, r17
1005 st.w r17, 0[r12]
1006
1007$endif ;/* CFG_USE_PROTECTIONHOOK */
1008
1009 ;/*
1010 ;* CPU例外が発生した場合,OSはE_OS_PROTECTION_EXCEPTIONをパラメータとして
1011 ;* プロテクションフックを呼び出す
1012 ;*/
1013 ;/* =begin modified for SC3 */
1014 mov r2, r6
1015 ;/* =end modified for SC3 */
1016 jarl _call_protectionhk_main, r31
1017
1018$ifdef CFG_USE_PROTECTIONHOOK
1019 mov sp, ep
1020
1021 ;/* v850_cpu_exp_noを復帰 */
1022 Lea _v850_cpu_exp_no, r12
1023 sld.w 8[ep], r13
1024 st.w r13, 0[r12]
1025
1026 ;/* v850_cpu_exp_pcを復帰 */
1027 Lea _v850_cpu_exp_pc, r12
1028 sld.w 4[ep], r13
1029 st.w r13, 0[r12]
1030
1031 ;/* v850_cpu_exp_sp退避 */
1032 Lea _v850_cpu_exp_sp, r12
1033 sld.w 0[ep], r13
1034 st.w r13, 0[r12]
1035
1036 ;/* v850_cpu_exp_*を退避したスペースを戻す */
1037 addi 12, sp, sp
1038$endif ;/* CFG_USE_PROTECTIONHOOK */
1039
1040ei_ret_exc:
1041 LOCK_ALL_INT
1042
1043 ;/*
1044 ;* プロテクションフックはOS割込み禁止状態で実行する
1045 ;*/
1046
1047 ;/*
1048 ;* 割込み・例外のネスト回数のデクリメント
1049 ;*/
1050 Lea _except_nest_cnt, r12
1051 ld.w 0[r12], r13
1052 mov -1, r14
1053 add r14, r13
1054 st.w r13, 0[r12]
1055
1056 ;/*
1057 ;* OS割込み禁止状態の解除
1058 ;*/
1059 ;/*
1060 ;* ISR1実行状態で発生した場合は
1061 ;* (1)スタックポインタの入れ替えをしない
1062 ;* (2)OS割込み禁止状態の解除をしない
1063 ;*/
1064 GET_ISPR r6
1065 Lea _pmr_isr1_mask, r7
1066 ld.h 0[r7], r7
1067 and r7, r6
1068 cmp r0, r6
1069 bne ei_ret_exc_2
1070
1071 ;/*
1072 ;* ネスト回数が1以上なら割込み元がISRなため例外発生元へ復帰
1073 ;* スタックポインタの入れ替えしない
1074 ;*/
1075 cmp r0, r13
1076 bne ei_ret_exc_1
1077
1078 ;/*
1079 ;* 戻り先がタスクなためスタックを戻す
1080 ;*/
1081 ld.w 0[sp], sp
1082
1083ei_ret_exc_1:
1084 ;/*
1085 ;* ISR1実行状態以外で発生した場合,OS割込み禁止状態の解除
1086 ;*/
1087 Lea _nested_lock_os_int_cnt, r12
1088 ld.b 0[r12], r13
1089 mov -1, r14
1090 add r14, r13
1091 st.b r13, 0[r12]
1092 cmp r0, r13
1093 bne ei_ret_exc_2
1094
1095 ;/* OS割込みを解除 */
1096 ;/* pmr_setting_tbl[current_iintpri] -> PMR */
1097 Lea _current_iintpri, r12
1098 ld.bu 0[r12], r12
1099 shl 1, r12
1100
1101 Lea _pmr_setting_tbl, r13
1102 add r12, r13
1103 ld.h 0[r13], r13
1104 SET_PMR r13, r12 ;/* set interrupt level */
1105
1106 ;/*
1107 ;* 例外発生元へ復帰
1108 ;*/
1109ei_ret_exc_2:
1110 ;/*
1111 ;* レジスタを復帰
1112 ;*/
1113 mov sp, ep
1114 sld.w 4[ep], r10
1115 ldsr r10, eipc
1116 sld.w 0[ep], r10
1117 ldsr r10, eipsw
1118
1119 ;/* スクラッチレジスタの復帰 */
1120 INT_EXC_RESTOREREG
1121
1122 stsr eipsw, r2 ;/* r2 = eipsw */
1123 shl PSW_SV, r2 ;/* r2 << PSW_SV により例外発生時のモード取得 */
1124 bnc return_from_ei_exception ;/* 特権からの例外ならばスキップ */
1125 Lea _hook_savedsp, r2
1126 ld.w 0[r2], r2
1127 cmp r0, r2
1128 be ei_exception_to_utask
1129 addi -4, r2, r2
1130 ld.w 0[r2], sp ;/* sp *(hook_savedsp - 4) */
1131 ;/*
1132 ;* ここで,hook_savedspを更新する必要はない
1133 ;*/
1134 br return_from_ei_exception
1135ei_exception_to_utask:
1136 Lea _p_runtsk, r2
1137 ld.w 0[r2], r2
1138 ld.w TCB_usp[r2], sp ;/* uspを復帰 */
1139return_from_ei_exception:
1140 stsr eiwr, r2
1141 eiret
1142
1143 ;/*
1144 ;* カーネル起動していない場合に起きたCPU例外の無限ループ
1145 ;*/
1146infinity_loop:
1147 br infinity_loop
1148
1149 ;/*
1150 ;* 割り込みエントリ
1151 ;* V850E2
1152 ;* ベクターテーブルから Os_Lcfg.c に生成される各割込みの割込みエントリ
1153 ;* からジャンプし,r2に割込み番号が保存された状態で実行される
1154 ;* V850E3V5
1155 ;* ベクターテーブルから直接実行されるため,スタックの確保やレジスタの保存は
1156 ;* 特に行われていない状態で実行される
1157 ;*/
1158 .extern _interrupt
1159_interrupt:
1160$ifdef __v850e3v5__
1161 ldsr r2, eiwr
1162 ;/* 割込み要因の特定 */
1163 stsr eiic, r2
1164 ;/* EIC割込みは0x1000 から */
1165 addi -0x1000, r2, r2
1166$endif ;/* __v850e3v5__ */
1167 ;/*
1168 ;* 残りのレジスタ退避, EPでのアクセスに切り替えて行う
1169 ;* ここで,CY = EIPSW.IMP,r2[31:16] = intno
1170 ;* r2はOS側で予約する(割込み・例外の出入口の
1171 ;* ワークレジスタとして使用する)ため,
1172 ;* スタックに保存しない
1173 ;*/
1174 ldsr r2, fewr ;/* エラーコードを保存 */
1175 stsr eipsw, r2
1176 shl PSW_SV, r2 ;/* r2 << PSW_SV により例外発生時のモード取得 */
1177 stsr fewr, r2 ;/* エラーコードを復帰 */
1178 bnc interrupt_0 ;/* 特権からの割込みならばスキップ */
1179 ldsr r5, fewr ;/* tp(r5)を退避 */
1180 Lea _hook_savedsp, r5
1181 ld.w 0[r5], r5
1182 cmp r0, r5
1183 be interrupt_from_utask
1184 ;/*
1185 ;* ユーザフックへの割込み
1186 ;* hook_savedspをユーザスタック上に保存
1187 ;* +------------------+ <- sp
1188 ;* | 前のhook_savedsp |
1189 ;* +------------------+ <- 前のhook_savedsp
1190 ;* | ................ |
1191 ;* +------------------+
1192 ;*/
1193 addi -4, r5, r5
1194 st.w sp, 0[r5] ;/* *(hook_savedsp - 4) = sp */
1195 mov r5, sp ;/* sp = hook_savedsp - 4 */
1196 stsr fewr, r5 ;/* tp(r5)を復帰 */
1197 br interrupt_0
1198interrupt_from_utask:
1199 ;/*
1200 ;* ユーザタスクへの割込み
1201 ;*/
1202 Lea _p_runtsk, r5
1203 ld.w 0[r5], r5
1204 st.w sp, TCB_usp[r5] ;/* uspを保存 */
1205 ld.w TCB_p_tinib[r5], r5
1206 ld.w TINIB_sstk_bottom[r5], sp ;/* sspを復帰 */
1207 stsr fewr, r5 ;/* tp(r5)を復帰 */
1208interrupt_0:
1209 ;/* スクラッチレジスタの保存 */
1210 INT_EXC_SAVEREG
1211
1212 ;/* 多重割込みのため,現在のEIPCとEIPSWを保存 */
1213 stsr eipc, r6
1214 sst.w r6, 4[ep]
1215 stsr eipsw, r6
1216 sst.w r6, 0[ep]
1217
1218$if 0
1219$ifdef __v850e3v5__
1220 ;/* 割込み要因の特定 */
1221 stsr eiic, r12
1222 ;/* EIC割込みは0x1000 から */
1223 addi -0x1000, r12, r12
1224$else ;/* __v850e2v3__ */
1225 ;/*
1226 ;* V850E2V3では,Os_Lcfg.c.xxにより割込み要因がr2に設定され,
1227 ;* _interrupt が呼び出される.
1228 ;* r2 は割込みの許可により上書きされるためr12を使用する.
1229 ;*/
1230 mov r2, r12
1231$endif ;/* __v850e3v5__ */
1232$else
1233 mov r2, r12
1234$endif
1235
1236 ;/* 割込み優先度を取得(r11) */
1237 GET_ISPR r13
1238 sch1r r13, r11
1239 add -1,r11
1240
1241 ;/*
1242 ;* _current_iintpri の更新
1243 ;* 割り込み処理中はISPRが自動的に設定されているため,PMRは設定する必要がない.
1244 ;*/
1245 Lea _current_iintpri, r6
1246 ld.bu 0[r6], r19
1247 st.b r11,0[r6]
1248
1249 ;/*
1250 ;* 多重割込みか判定
1251 ;*/
1252 Lea _except_nest_cnt, r13
1253 ld.w 0[r13], r6
1254
1255 ;/*
1256 ;* 割込み・例外のネスト回数のインクリメント
1257 ;*/
1258 add 1, r6
1259 st.w r6, 0[r13]
1260 cmp 1, r6
1261 bne interrupt_1 ;/* ネストしている場合はスタック切替無し */
1262
1263 ;/*
1264 ;* タスクに割込んだ場合
1265 ;* スタックポインタの保存と入れ替え
1266 ;*/
1267 mov sp , r13
1268 Lea __ostkpt, sp
1269 ld.w 0[r3], r3
1270 add -4, sp
1271 st.w r13, 0[sp]
1272
1273interrupt_1:
1274 ;/*
1275 ;* 割込み発生時の割込み優先度マスクをスタックに保存
1276 ;*/
1277 add -4, sp
1278 st.w r19, 0[sp]
1279
1280 UNLOCK_ALL_INT
1281
1282$ifdef CFG_USE_STACKMONITORING
1283 ;/*
1284 ;* 割込み番号の保存
1285 ;* スタックオーバフローのプロテクションフックで破壊される可能性がある
1286 ;*/
1287 push r12
1288 ;/*
1289 ;* タスクスタックのオーバフローチェック
1290 ;*/
1291
1292 ;/*
1293 ;* 多重割込みの場合はタスクスタックのスタックモニタリングを行わない
1294 ;*/
1295 cmp 1, r6
1296 bne int_nested
1297
1298 ;/*
1299 ;* スタックポインタチェック方式
1300 ;*/
1301 Lea _p_runtsk, r6 ;/* 管理ブロックの先頭アドレス取得 */
1302 ld.w 0[r6], r6
1303 ld.w TCB_p_tinib[r6], r6 ;/* タスク初期化ブロック先頭アドレス取得 */
1304 ;/* =begin modified for SC3 */
1305 ;/* システムスタックモニタリング */
1306 ld.w TINIB_sstksz[r6], r7 ;/* タスクシステムスタックサイズ取得 */
1307 ld.w TINIB_sstk_bottom[r6], r6 ;/* タスクシステムスタック終端アドレス取得 */
1308 sub r7, r6
1309 mov r0, r9
1310 mov PEOB_STACKMONITORING_INTERRUPT, r8 ;/* ISR入口でのスタックモニタリング */
1311 cmp r6, r13 ;/* スタックポインタ <= スタックの先頭の場合NG */
1312 Lea stack_monitoring_exit, lp
1313 ;/* =end modified for SC3 */
1314 bnh stack_monitoring_error_isr
1315
1316 ;/*
1317 ;* マジックナンバーチェック方式
1318 ;*/
1319 ld.w 0[r6], r6
1320 mov STACK_MAGIC_NUMBER, r7
1321 ;/*
1322 ;* マジックナンバー未破壊なら,割込み処理に飛ぶ
1323 ;* タスクに割込んだ場合,割込みスタックをチェックしない
1324 ;*/
1325 cmp r7, r6
1326 be stack_monitoring_exit
1327 ;/* =begin modified for SC3 */
1328 Lea stack_monitoring_exit, lp
1329 ;/* =end modified for SC3 */
1330 br stack_monitoring_error_isr
1331
1332 ;/*
1333 ;* 多重割込みの場合
1334 ;*/
1335int_nested:
1336 ;/*
1337 ;* 割込みスタックのオーバフローチェック
1338 ;*/
1339
1340 ;/*
1341 ;* スタック残量チェック方式
1342 ;*/
1343 Lea _isr_p_isrcb_tbl, r7
1344 mov r12, r11
1345 shl 2, r11 ;/* 割込み番号を4倍してオフセットを生成 */
1346 add r11, r7
1347 ld.w 0[r7], r7 ;/* r7 = &isrcb_table[x] */
1348 ;/* =begin modified for SC3 */
1349 ld.w ISRCB_p_isrinib[r7], r7
1350 ld.w ISRINIB_p_intinib[r7], r7
1351 mov 1, r9
1352 mov PEOB_STACKMONITORING_INTERRUPT, r8 ;/* ISR入口でのスタックモニタリング */
1353 ;/* =end modified for SC3 */
1354 ld.w INTINIB_remain_stksz[r7], r7 ;/* 割込み番号に対応したスタックサイズの取得 */
1355 Lea __ostk, r6 ;/* 割込みスタックの先頭アドレス取得 */
1356 ld.w 0[r6], r6
1357 add r6, r7 ;/* 先頭アドレス+ISRの使用するスタックサイズ */
1358 cmp r7, sp ;/* スタックポインタ <= 先頭アドレス+ISRの使用するスタックサイズの場合OK */
1359 ;/* =begin modified for SC3 */
1360 Lea stack_monitoring_exit, lp
1361 ;/* =end modified for SC3 */
1362 bnh stack_monitoring_error_isr
1363
1364 ;/*
1365 ;* マジックナンバーチェック方式
1366 ;*/
1367 ld.w 0[r6], r6 ;/* このアドレスの示す先にマジックナンバーが入っている */
1368 mov STACK_MAGIC_NUMBER, r7
1369 cmp r7, r6
1370 ;/* =begin modified for SC3 */
1371 Lea stack_monitoring_exit, lp
1372 ;/* =end modified for SC3 */
1373 bne stack_monitoring_error_isr
1374
1375stack_monitoring_exit:
1376 pop r12
1377$endif ;/* CFG_USE_STACKMONITORING */
1378
1379 ;/*
1380 ;* _callevel_stat 保存
1381 ;*/
1382 Lea _callevel_stat, r6
1383 ld.h 0[r6], r7
1384 Push r7
1385
1386 ;/*
1387 ;* _callevel_stat 設定
1388 ;*/
1389 mov TCL_ISR2, r8
1390 or r8, r7
1391 st.h r7, 0[r6]
1392
1393 ;/* =begin added for SC3 */
1394 ;/*
1395 ;* run_trusted 保存
1396 ;*/
1397 Lea _run_trusted, r6
1398 ld.b 0[r6], r7
1399 Push r7
1400
1401 ;/*
1402 ;* run_trusted 設定
1403 ;*/
1404 mov TRUE, r8
1405 st.b r8, 0[r6]
1406
1407 ;/*
1408 ;* p_runosap 保存
1409 ;*/
1410 Lea _p_runosap, r6
1411 ld.w 0[r6], r7
1412 Push r7
1413 ;/* =end added for SC3 */
1414
1415 ;/*
1416 ;* p_runisr 保存
1417 ;*/
1418 Lea _p_runisr, r6
1419 ld.w 0[r6], r7
1420 Push r7
1421
1422 ;/*
1423 ;* p_runisr 設定
1424 ;*/
1425 Lea _isr_p_isrcb_tbl, r7
1426 shl 2, r12 ;/* 割込み番号を4倍してオフセットを生成 */
1427 add r12, r7
1428 Lea _p_runisr, r8
1429 ld.w 0[r7], r7
1430 st.w r7, 0[r8]
1431
1432 ;/*
1433 ;* 割込みハンドラのアドレスを読み込む
1434 ;*/
1435 Lea _isr_tbl, r6
1436 add r12, r6
1437
1438 ;/* =begin modified for SC3 */
1439 ;/*
1440 ;* p_runosap 設定
1441 ;*/
1442 cmp r7, r0 ;/* r7 = p_runisr == NULL ? */
1443 be int_handler_call ;/* p_runisr が NULL でなければスキップ */
1444 ld.w ISRCB_p_isrinib[r7], ep ;/* ep = p_runisr->p_isrinib */
1445 sld.w ISRINIB_p_osapcb[ep], r8 ;/* r8 = p_runisr->p_isrinib->p_osapcb */
1446 Lea _p_runosap, ep
1447 sst.w r8, 0[ep] ;/* p_runosap = p_runisr->p_isrinib->p_osapcb */
1448
1449int_handler_call:
1450 ;/* =end modified for SC3 */
1451 ;/*
1452 ;* 割込みハンドラ呼び出し
1453 ;*/
1454 Lea end_int_handler, r31
1455 ld.w 0[r6], r6
1456 jmp [r6]
1457
1458 ;/*
1459 ;* スタックオーバフロー時の処理
1460 ;*/
1461$ifdef CFG_USE_STACKMONITORING
1462 ;/*
1463 ;* スタックオーバフロー時プロテクションフックを呼び出し
1464 ;* スタックを更に壊さないため,割込みスタックの初期値を使用する
1465 ;* ISRの出入口から相対ジャンプできるようにここに置く
1466 ;* stack_monitoring_errorへの踏み台
1467 ;*/
1468stack_monitoring_error_isr:
1469 br stack_monitoring_error
1470$endif ;/* CFG_USE_STACKMONITORING */
1471
1472end_int_handler:
1473
1474$ifdef CFG_USE_STACKMONITORING
1475 ;/*
1476 ;* 割込みスタックのオーバフローチェック
1477 ;* 割込みから戻った時,スタックポインタも戻ったはずなので,
1478 ;* マジックナンバーチェック方式のみ実施
1479 ;*/
1480
1481 ;/*
1482 ;* マジックナンバーチェック方式
1483 ;*/
1484 Lea __ostk, r6 ;/* 割込みスタックの先頭アドレス取得 */
1485 ld.w 0[r6], r6
1486 ld.w 0[r6], r6 ;/* このアドレスの示す先にマジックナンバーが入っている */
1487 ;/* =begin modified for SC3 */
1488 mov 1, r9
1489 mov PEOB_STACKMONITORING_INTERRUPT, r8 ;/* ISRでのスタックモニタリング */
1490 mov STACK_MAGIC_NUMBER, r7
1491 cmp r7, r6
1492 Lea stack_monitoring_exit2, lp
1493 bne stack_monitoring_error_isr
1494
1495stack_monitoring_exit2:
1496 ;/* =end modified for SC3 */
1497$endif ;/* CFG_USE_STACKMONITORING */
1498
1499 ;/*
1500 ;* ISR2の不正終了チェック
1501 ;*/
1502 jarl _exit_isr2, r31
1503
1504 ;/*
1505 ;* p_runisr の復帰
1506 ;*/
1507 Lea _p_runisr, r7
1508 Pop r6
1509 st.w r6, 0[r7]
1510
1511 ;/* =begin modified for SC3 */
1512 ;/*
1513 ;* p_runosap 復帰
1514 ;*/
1515 Lea _p_runosap, r7
1516 Pop r6
1517 st.w r6, 0[r7]
1518
1519 ;/*
1520 ;* run_trusted 復帰
1521 ;*/
1522 Lea _run_trusted, r7
1523 Pop r6
1524 st.b r6, 0[r7]
1525 ;/* =end modified for SC3 */
1526
1527
1528 ;/*
1529 ;* _callevel_stat の復帰
1530 ;*/
1531 Lea _callevel_stat, r7
1532 Pop r6
1533 st.h r6, 0[r7]
1534
1535;/*
1536 ;* 割込みハンドラ出口処理
1537 ;*/
1538ret_int:
1539 ;/*
1540 ;* _except_nest_cntの操作とスタック切り替えの間はOS割込み禁止にする
1541 ;* 必要がある
1542 ;* この先,割込み先へのリターンか,遅延ディスパッチに分岐する.
1543 ;* 割込み先へのリターンには全割込みが必要であり,遅延ディスパッチ時には
1544 ;* ネスト管理のOS割込み禁止にする必要があるため,ここでは一旦全割込み禁
1545 ;* 止とする
1546 ;*/
1547
1548 LOCK_ALL_INT
1549
1550 ;/*
1551 ;* 割込み発生時の割込み優先度マスクをスタックから復帰
1552 ;*/
1553 ld.w 0[sp], r19
1554 add 4, sp
1555 Lea _current_iintpri, r6
1556 st.b r19, 0[r6] ;/* current_iintpriを復帰 */
1557
1558 ;/*
1559 ;* 割込み・例外のネスト回数のデクリメント
1560 ;*/
1561 Lea _except_nest_cnt, r6
1562 ld.w 0[r6], r7
1563 add -1, r7
1564 st.w r7, 0[r6]
1565
1566 ;/*
1567 ;* ネスト回数が0なら,割込み元がタスク
1568 ;*/
1569 cmp r0, r7
1570 be ret_int_task
1571
1572 ;/*
1573 ;* ISR2割込みからのリターン時は割込み元が
1574 ;* ISR2であるためそのままリターン
1575 ;*/
1576 br ret_int_1
1577
1578
1579 ;/*
1580 ;* 割込み元がタスクの場合
1581 ;*/
1582ret_int_task:
1583 ld.w 0[sp], sp ;/* スタックポインタを戻す */
1584
1585 ;/*
1586 ;* 割込み優先度マスクを変えるAPIがないため,
1587 ;* ATK2では割込み優先度マスクの復帰処理は不要
1588 ;*/
1589 ;/*
1590 ;* 割込みハンドラ実行時には,ISPRで優先度が自動的に上がるため,
1591 ;* PMRは変更していないが,割り込みハンドラ内で x_nested_unlock_os_int() を
1592 ;* 呼び出すとPMRが書き換わる.ディスパッチが必要でない場合は,ret_int_1で
1593 ;* PMRを元の値に戻す.ディスパッチが必要な場合は,OS割り込み禁止とするため,
1594 ;* ここで,PMRを更新する必要はない.
1595 ;*/
1596
1597 ;/*
1598 ;* 戻り先がタスクの場合,ディスパッチの必要があるかチェック
1599 ;*/
1600 Lea _p_runtsk, r6
1601 ld.w 0[r6], r6
1602 Lea _p_schedtsk, r7
1603 ld.w 0[r7], r7
1604 cmp r6, r7
1605 be ret_int_1 ;/* ディスパッチの必要がなければ割込み元へ戻る */
1606
1607 ;/*
1608 ;* ここでは,戻り先がタスクであり,スタックは,タスクスタックに
1609 ;* スクラッチレジスタのみが保存された状態になっている.また,
1610 ;* 全割込みを禁止した状態となっている
1611 ;*/
1612
1613 ;/*
1614 ;* 優先度マスクのクリア
1615 ;* eiretを実行しないため,eiretによる割込みコントローラの優先度マスク
1616 ;* (インサービスプライオリティ)のクリアが行われないため,代わりにISPC
1617 ;* を用いてクリアする.
1618 ;*/
1619 CLEAR_ISPR r10, r12
1620
1621 ;/*
1622 ;* OS割込み禁止状態に移行する
1623 ;*
1624 ;* この時点でOS割込み禁止状態とするのは,dispatcherを実行する際に
1625 ;* OS割込み禁止状態になっている必要があるためである
1626 ;*
1627 ;* (モデル上の)割込み優先度マスクは0であるため,ISR1以外の割込みは全て禁止する
1628 ;*/
1629
1630 OUTER_LOCK_OS_INT r12, r13
1631 ;/* ret_int で全割込み禁止状態としたため解除 */
1632 UNLOCK_ALL_INT
1633
1634 ;/*
1635 ;* コンテキストの退避
1636 ;*/
1637 addi -48, sp, sp
1638 mov sp, ep
1639 sst.w r10, 44[ep]
1640 sst.w r11, 40[ep]
1641 sst.w r20, 36[ep]
1642 sst.w r21, 32[ep]
1643 sst.w r22, 28[ep]
1644 sst.w r23, 24[ep]
1645 sst.w r24, 20[ep]
1646 sst.w r25, 16[ep]
1647 sst.w r26, 12[ep]
1648 sst.w r27, 8[ep]
1649 sst.w r28, 4[ep]
1650 sst.w r29, 0[ep]
1651
1652 ;/* スタックと次の起動番地を保存 */
1653 Lea _p_runtsk, ep
1654 sld.w 0[ep], ep
1655 ;/* =begin modified for SC3 */
1656 sst.w sp, TCB_ssp[ep]
1657 ;/* =end modified for SC3 */
1658 Lea ret_int_r, r6
1659 sst.w r6, TCB_pc[ep]
1660 br dispatcher
1661
1662 ;/*
1663 ;* 割込み・例外でコンテキスト保存した場合の復帰ルーチン
1664 ;*/
1665ret_int_r:
1666 ;/*
1667 ;* コンテキストの復帰
1668 ;*/
1669 mov sp, ep
1670 sld.w 44[ep], r10
1671 sld.w 40[ep], r11
1672 sld.w 36[ep], r20
1673 sld.w 32[ep], r21
1674 sld.w 28[ep], r22
1675 sld.w 24[ep], r23
1676 sld.w 20[ep], r24
1677 sld.w 16[ep], r25
1678 sld.w 12[ep], r26
1679 sld.w 8[ep], r27
1680 sld.w 4[ep], r28
1681 sld.w 0[ep], r29
1682 addi 48, ep, sp
1683
1684 LOCK_ALL_INT
1685
1686 OUTER_UNLOCK_OS_INT r12, r13
1687 ;/*
1688 ;* 割込みからの復帰ルーチン
1689 ;*/
1690ret_int_1:
1691 ;/*
1692 ;* レジスタを復帰
1693 ;*/
1694 mov sp, ep
1695
1696 ;/*
1697 ;* 割込み優先度マスクを変えるAPIがないため,
1698 ;* ATK2では割込み優先度マスクの復帰処理は不要
1699 ;*/
1700 ;/*
1701 ;* PMRを元に戻す.
1702 ;* 割込みハンドラ実行時には,ISPRで優先度が自動的に上がるため,
1703 ;* PMRは変更していないが,割り込みハンドラ内で x_nested_unlock_os_int() を
1704 ;* 呼び出すとPMRが書き換わるためここで元の値に戻す.
1705 ;* OUTER_UNLOCK_OS_INT は nested_lock_os_int_cnt を0にするが,
1706 ;* ここでは既に0であるため問題ない.
1707 ;*/
1708 OUTER_UNLOCK_OS_INT r1, r6
1709 sld.w 4[ep], r10
1710 ldsr r10, eipc
1711 sld.w 0[ep], r10
1712 ldsr r10, eipsw
1713
1714 ;/* スクラッチレジスタを復帰 */
1715 INT_EXC_RESTOREREG
1716
1717 stsr eipsw, r2 ;/* r2 = eipsw */
1718 shl PSW_SV, r2 ;/* r2 << PSW_SV により例外発生時のモード取得 */
1719 bnc return_from_int ;/* 特権からの割込みならばスキップ */
1720 Lea _hook_savedsp, r2
1721 ld.w 0[r2], r2
1722 cmp r0, r2
1723 be int_to_utask
1724 addi -4, r2, r2
1725 ld.w 0[r2], sp ;/* sp *(hook_savedsp - 4) */
1726 ;/*
1727 ;* ここで,hook_savedspを更新する必要はない
1728 ;*/
1729 br return_from_int
1730int_to_utask:
1731 Lea _p_runtsk, r2
1732 ld.w 0[r2], r2
1733 ld.w TCB_usp[r2], sp ;/* uspを復帰 */
1734return_from_int:
1735 stsr eiwr, r2
1736 eiret
1737
1738;/*
1739 ;* タスクディスパッチ
1740 ;*/
1741 .extern _dispatch
1742_dispatch:
1743 ;/*
1744 ;* このルーチンは,タスクコンテキスト・OS割込み禁止状態・ディスパッチ
1745 ;* 許可状態・(モデル上の)割込み優先度マスク全解除状態で呼び出さ
1746 ;* れる
1747 ;*/
1748 addi -60, sp, sp
1749 st.w ep, 0[sp]
1750 mov sp, ep
1751 sst.w r2, 56[ep]
1752 sst.w r10, 52[ep]
1753 sst.w r11, 48[ep]
1754 sst.w r20, 44[ep]
1755 sst.w r21, 40[ep]
1756 sst.w r22, 36[ep]
1757 sst.w r23, 32[ep]
1758 sst.w r24, 28[ep]
1759 sst.w r25, 24[ep]
1760 sst.w r26, 20[ep]
1761 sst.w r27, 16[ep]
1762 sst.w r28, 12[ep]
1763 sst.w r29, 8[ep]
1764 sst.w r31, 4[ep]
1765 ;/* スタックと次の起動番地を保存 */
1766 Lea _p_runtsk, ep
1767 sld.w 0[ep], ep
1768 ;/* =begin modified for SC3 */
1769 sst.w sp, TCB_ssp[ep]
1770 ;/* =end modified for SC3 */
1771 Lea dispatch_r, r10
1772 sst.w r10, TCB_pc[ep]
1773$ifdef CFG_USE_STACKMONITORING
1774 ;/*
1775 ;* 実行中タスクのタスクスタックのオーバフローチェック
1776 ;*/
1777 ;/*
1778 ;* スタックポインタチェック方式
1779 ;*/
1780 Lea _p_runtsk, r6 ;/* 管理ブロックの先頭アドレス取得 */
1781 ld.w 0[r6], r6
1782 ld.w TCB_p_tinib[r6], r6 ;/* タスク初期化ブロック先頭アドレス取得 */
1783 ;/* =begin modified for SC3 */
1784 ;/* システムスタックモニタリング */
1785 ld.w TINIB_sstksz[r6], r7 ;/* タスクシステムスタックサイズ取得 */
1786 ld.w TINIB_sstk_bottom[r6], r6 ;/* タスクシステムスタック終端アドレス取得 */
1787 sub r7, r6
1788 mov 1, r9
1789 mov PEOB_STACKMONITORING_DISPATCH, r8 ;/* ディスパッチャでのスタックモニタリング */
1790 cmp r6, sp ;/* スタックポインタ <= スタックの先頭の場合NG */
1791 Lea dispatcher, lp
1792 ;/* =end modified for SC3 */
1793 bnh stack_monitoring_error
1794 ;/*
1795 ;* マジックナンバーチェック方式
1796 ;*/
1797 ld.w 0[r6], r6
1798 mov STACK_MAGIC_NUMBER, r7
1799 cmp r7, r6
1800 ;/* =begin modified for SC3 */
1801 Lea dispatcher, lp
1802 ;/* =end modified for SC3 */
1803 bne stack_monitoring_error
1804$endif ;/* CFG_USE_STACKMONITORING */
1805 br dispatcher
1806
1807 ;/*
1808 ;* ディスパッチャの復帰ルーチン
1809 ;*/
1810dispatch_r:
1811 mov sp, ep
1812 sld.w 56[ep], r2
1813 sld.w 52[ep], r10
1814 sld.w 48[ep], r11
1815 sld.w 44[ep], r20
1816 sld.w 40[ep], r21
1817 sld.w 36[ep], r22
1818 sld.w 32[ep], r23
1819 sld.w 28[ep], r24
1820 sld.w 24[ep], r25
1821 sld.w 20[ep], r26
1822 sld.w 16[ep], r27
1823 sld.w 12[ep], r28
1824 sld.w 8[ep], r29
1825 sld.w 4[ep], r31
1826 addi 60, ep, sp
1827 ld.w 0[sp], ep
1828 jmp [lp]
1829
1830 ;/*
1831 ;* スタックオーバフロー時の処理
1832 ;*/
1833$ifdef CFG_USE_STACKMONITORING
1834 ;/*
1835 ;* スタックオーバフロー時プロテクションフックを呼び出し
1836 ;* スタックを更に壊さないため,割込みスタックの初期値を使用する
1837 ;* r8 = スタックモニタリングをした箇所
1838 ;* PEOB_STACKMONITORING_TERMTASK ||
1839 ;* PEOB_STACKMONITORING_DISPATCH ||
1840 ;* PEOB_STACKMONITORING_INTERRUPT
1841 ;* r9 = ostkptの初期値に切り替えるか?
1842 ;*/
1843stack_monitoring_error:
1844 ;/*
1845 ;* r9==0の場合でも,既に_ostkptを使っているので,
1846 ;* except_nest_cntをインクリメントしても問題はない
1847 ;*/
1848 Lea _except_nest_cnt, r12 ;/* _ostkptを使う場合はexcept_nest_cntをインクリメントする */
1849 ld.w 0[r12], r13
1850 add 1, r13
1851 st.w r13, 0[r12]
1852
1853 ;/* =begin modified for SC3 */
1854 cmp r0, r9
1855 be stack_monitoring_error_1
1856 ;/* =end modified for SC3 */
1857
1858 Lea __ostkpt, r12 ;/* スタックを更に壊さないため,割込みスタックの初期値を使用する */
1859 ld.w 0[r12], r12
1860 mov r12, sp
1861
1862 ;/* =begin modified for SC3 */
1863stack_monitoring_error_1:
1864 ;/*
1865 ;* プロテクションフックはOS割込み禁止状態で呼び出す
1866 ;*/
1867 NESTED_LOCK_OS_INT r12, r13
1868 ;/* =end modified for SC3 */
1869
1870 mov E_OS_STACKFAULT, r6 ;/* プロテクションフックの引数を設定 */
1871 or r8, r6 ;/* r6 = E_OS_STACKFAULT | PEOB_STACKMONITORING_XXX */
1872 ;/* =begin modified for SC3 */
1873 push lp
1874 jarl _call_protectionhk_main, r31 ;/* プロテクションフックを呼び出し */
1875 pop lp
1876
1877 ;/*
1878 ;* except_nest_cntをデクリメント
1879 ;*/
1880 Lea _except_nest_cnt, r12
1881 ld.w 0[r12], r13
1882 add -1, r13
1883 st.w r13, 0[r12]
1884 ;/*
1885 ;* OS割込み禁止状態をアンネスト
1886 ;*/
1887 NESTED_UNLOCK_OS_INT r12, r13
1888 jmp [lp]
1889 ;/* =end modified for SC3 */
1890$endif ;/* CFG_USE_STACKMONITORING */
1891
1892
1893;/*
1894 ;* ディスパッチャの動作開始
1895 ;*/
1896 .extern _start_dispatch
1897_start_dispatch:
1898 ;/*
1899 ;* このルーチンは,カーネル起動時に,すべての割込みを禁止した状態
1900 ;* (全割込み禁止状態と同等)で呼び出される.また,割込みモード(非
1901 ;* タスクコンテキストと同等)で呼び出されることを想定している
1902 ;*
1903 ;* dispatcherは,OS割込み禁止状態で呼び出す.
1904 ;*/
1905 ;/* OS割込み禁止状態 */
1906 OUTER_LOCK_OS_INT r12, r13
1907 ;/* 全割込み禁止解除状態へ */
1908 UNLOCK_ALL_INT
1909 br dispatcher_0
1910
1911 ;/* =begin modified for SC3 */
1912 .extern _exit_and_dispatch_nohook
1913 ;/*
1914 ;* タスク強制終了の場合はPostTaskHookを呼出さない
1915 ;* その場合のエントリである
1916 ;*/
1917_exit_and_dispatch_nohook:
1918
1919 br dispatcher_0
1920 ;/* =end modified for SC3 */
1921
1922 ;/*
1923 ;* 現在のコンテキストを捨ててディスパッチ
1924 ;*/
1925 .extern _exit_and_dispatch
1926_exit_and_dispatch:
1927$ifdef CFG_USE_STACKMONITORING
1928 ;/*
1929 ;* 実行中のタスクスタックのオーバフローチェック
1930 ;*/
1931 ;/*
1932 ;* スタックポインタチェック方式
1933 ;*/
1934 Lea _p_runtsk, r6 ;/* 管理ブロックの先頭アドレス取得 */
1935 ld.w 0[r6], r6
1936 ld.w TCB_p_tinib[r6], r6 ;/* タスク初期化ブロック先頭アドレス取得 */
1937 ;/* =begin modified for SC3 */
1938 ;/* システムスタックモニタリング */
1939 ld.w TINIB_sstksz[r6], r7 ;/* タスクシステムスタックサイズ取得 */
1940 ld.w TINIB_sstk_bottom[r6], r6 ;/* タスクシステムスタック終端アドレス取得 */
1941 sub r7, r6
1942 mov 1, r9
1943 mov PEOB_STACKMONITORING_TERMTASK, r8 ;/* タスク終了時のスタックモニタリング */
1944 cmp r6, sp ;/* スタックポインタ <= スタックの先頭の場合NG */
1945 Lea dispatcher, lp
1946 ;/* =end modified for SC3 */
1947 bnh stack_monitoring_error
1948 ;/*
1949 ;* マジックナンバーチェック方式
1950 ;*/
1951 ld.w 0[r6], r6
1952 mov STACK_MAGIC_NUMBER, r7
1953 cmp r7, r6
1954 ;/* =begin modified for SC3 */
1955 Lea dispatcher, lp
1956 ;/* =end modified for SC3 */
1957 bne stack_monitoring_error
1958$endif ;/* CFG_USE_STACKMONITORING */
1959 ;/* ディスパッチャ本体(dispatcher)へ */
1960
1961dispatcher:
1962 ;/*
1963 ;* PostTaskHookの呼び出し
1964 ;*/
1965$ifdef CFG_USE_POSTTASKHOOK
1966 Lea _PostTaskHook, r20
1967 cmp r20, r0
1968 be dispatcher_0
1969posttaskhook_call:
1970 Lea _call_posttaskhook, r6
1971 jarl _stack_change_and_call_func_1, r31
1972$endif ;/* CFG_USE_POSTTASKHOOK */
1973
1974dispatcher_0:
1975 ;/*
1976 ;* このルーチンは,タスクコンテキスト・OS割込み禁止状態・ディスパッチ
1977 ;* 許可状態・(モデル上の)割込み優先度マスク全解除状態で呼び出さ
1978 ;* れる.実行再開番地へもこの状態のまま分岐する
1979 ;*/
1980$ifdef LOG_DSP_ENTER
1981 Lea _p_runtsk, r21
1982 ld.w 0[r21], r21
1983 cmp r0, r21
1984 be dispatcher_0_1
1985 mov r21, r6 ;/* 引数に_p_runtskを指定 */
1986 jarl _log_dsp_enter, r31
1987dispatcher_0_1:
1988$endif ;/* LOG_DSP_ENTER */
1989
1990 Lea _callevel_stat, r21
1991 ld.h 0[r21], r22
1992 mov TSYS_DISALLINT, r20
1993 and r22, r20
1994 be dispatcher_1
1995
1996 mov !TSYS_DISALLINT, r20
1997 and r22, r20
1998 st.h r20, 0[r21]
1999 UNLOCK_ALL_INT ;/* 全割込み禁止解除状態へ */
2000
2001 ;/*
2002 ;* 例外(割込み/CPU例外)のネスト回数はstart_dispatchや,dispatcher_3:
2003 ;* から来た場合は'1'となっているため,タスクスタックに切り換え後,
2004 ;* '0'に初期化する.
2005 ;*/
2006dispatcher_1:
2007 Lea _p_runtsk, r21
2008 Lea _p_schedtsk, r20
2009 ld.w 0[r20], r22
2010 st.w r22, 0[r21]
2011 cmp r22, r0
2012 be dispatcher_3
2013
2014 mov r22, ep
2015 ;/* =begin modified for SC3 */
2016 sld.w TCB_ssp[ep], sp
2017 ;/* =end modified for SC3 */
2018 Lea _except_nest_cnt, r20
2019 st.w r0, 0[r20]
2020
2021 ;/* =begin modified for SC3 */
2022 sld.w TCB_p_tinib[ep], ep
2023 mov ep, r25 ;/* r25 = p_tinib */
2024 sld.w TINIB_p_osapcb[ep], r26 ;/* r26 = p_osapcb */
2025 Lea _p_runosap, ep ;/* ep = &p_runosap */
2026 sst.w r26, 0[ep] ;/* p_runosap = p_osapcb */
2027 ld.w OSAPCB_p_osapinib[r26], r29 ;/* r29 = p_osapinib */
2028 ld.bu OSAPINIB_osap_trusted[r29], r24 ;/* r24 = trusted? */
2029 Lea _run_trusted, ep
2030 sst.b r24, 0[ep] ;/* run_trusted = trusted? */
2031 cmp r0, r24 ;/* 信頼ならばスキップ */
2032 bne dispatcher_5
2033
2034$ifdef __v850e2v3__
2035 ori 0x1001, r0, r27
2036 ldsr r27, bsel
2037 ;/*
2038 ;* ユーザスタック領域
2039 ;*/
2040 mov r25, ep
2041 sld.w TINIB_start_ustk[ep], r27 ;/* 先頭番地 */
2042 ori 0x01, r27, r27
2043 sld.w TINIB_limit_ustk[ep], r28 ;/* 保護属性とサイズ */
2044 ori 0x06, r28, r28
2045 ldsr r27, dpa0l
2046 ldsr r28, dpa0u
2047$elseif defined(__v850e3v5__)
2048 ;/*
2049 ;* ユーザスタック領域
2050 ;*/
2051 mov r25, ep
2052 sld.w TINIB_start_ustk[ep], r27 ;/* 先頭番地 */
2053 sld.w TINIB_limit_ustk[ep], r28 ;/* 保護属性とサイズ */
2054 ldsr r27, 0, 6 ;/* MPLA0 */
2055 ldsr r28, 1, 6 ;/* MPUA0 */
2056
2057$endif ;/* __v850e2v3__ */
2058
2059 ;/*
2060 ;* 実行ドメインと保護ドメイン(MPUの設定)が同じならば,
2061 ;* ドメイン毎のコード領域・データ領域をMPUに設定し直す必要はない
2062 ;*/
2063 Lea _p_ctxosap, ep ;/* ep = &p_ctxosap */
2064 sld.w 0[ep], r27 ;/* r27 = p_ctxosap */
2065 cmp r27, r26 ;/* p_ctxosap == p_runosap ? */
2066 be dispatcher_5 ;/* 同じならdispatcher_5へ */
2067 nop
2068 sst.w r26, 0[ep] ;/* p_ctxosap = p_runosap : 保護ドメインを切替え */
2069$ifdef __v850e2v3__
2070 ldsr r26, vmtid ;/* メモリ保護違反タスク識別子をp_runosapとする */
2071 mov r29, ep ;/* ep = p_osapinib */
2072
2073 ;/*
2074 ;* 自保護ドメイン専用のrom領域
2075 ;*/
2076 sld.w OSAPINIB_start_text[ep], r27 ;/* 先頭番地 */
2077 sld.w OSAPINIB_limit_text[ep], r28 ;/* 保護属性とサイズ */
2078 ldsr r27, ipa0l
2079 ldsr r28, ipa0u
2080 ;/*
2081 ;* 自保護ドメイン専用のrosdata領域
2082 ;*/
2083 sld.w OSAPINIB_start_rosdata[ep], r27 ;/* 先頭番地 */
2084 sld.w OSAPINIB_limit_rosdata[ep], r28 ;/* 保護属性とサイズ */
2085 ldsr r27, ipa1l
2086 ldsr r28, ipa1u
2087 ;/*
2088 ;* 自保護ドメイン専用のRWX領域
2089 ;*/
2090 sld.w OSAPINIB_start_ram[ep], r27 ;/* 先頭番地 */
2091 sld.w OSAPINIB_limit_ram[ep], r28 ;/* 保護属性とサイズ */
2092 ldsr r27, dpa1l
2093 ldsr r28, dpa1u
2094 ;/*
2095 ;* 自保護ドメイン専用のRWX領域(sdata)
2096 ;*/
2097 sld.w OSAPINIB_start_sram[ep], r27 ;/* 先頭番地 */
2098 sld.w OSAPINIB_limit_sram[ep], r28 ;/* 保護属性とサイズ */
2099 ldsr r27, dpa2l
2100 ldsr r28, dpa2u
2101 ;/*
2102 ;* 共有リード/専用ライト領域の専用領域
2103 ;*/
2104 sld.w OSAPINIB_start_srpw[ep], r27 ;/* 先頭番地 */
2105 sld.w OSAPINIB_limit_srpw[ep], r28 ;/* 保護属性とサイズ */
2106 ldsr r27, dpa3l
2107 ldsr r28, dpa3u
2108 ;/*
2109 ;* 共有リード/専用ライト領域の専用領域(sdata)
2110 ;*/
2111 sld.w OSAPINIB_start_ssrpw[ep], r27 ;/* 先頭番地 */
2112 sld.w OSAPINIB_limit_ssrpw[ep], r28 ;/* 保護属性とサイズ */
2113 ldsr r27, dpa4l
2114 ldsr r28, dpa4u
2115
2116$elseif defined(__v850e3v5__)
2117 mov r29, ep ;/* ep = p_osapinib */
2118
2119$ifdef MPU_REGION_11
2120 ;/*
2121 ;* 自保護ドメイン専用のrom領域
2122 ;*/
2123 sld.w OSAPINIB_start_text[ep], r27 ;/* 先頭番地 */
2124 sld.w OSAPINIB_limit_text[ep], r28 ;/* 保護属性とサイズ */
2125 ldsr r27, 16, 6 ;/* MPLA4 */
2126 ldsr r28, 17, 6 ;/* MPUA4 */
2127
2128 ;/*
2129 ;* 自保護ドメイン専用のrosdata領域
2130 ;*/
2131 sld.w OSAPINIB_start_rosdata[ep], r27 ;/* 先頭番地 */
2132 sld.w OSAPINIB_limit_rosdata[ep], r28 ;/* 保護属性とサイズ */
2133 ldsr r27, 20, 6 ;/* MPLA5 */
2134 ldsr r28, 21, 6 ;/* MPUA5 */
2135
2136 ;/*
2137 ;* 自保護ドメイン専用のRWX領域
2138 ;*/
2139 sld.w OSAPINIB_start_ram[ep], r27 ;/* 先頭番地 */
2140 sld.w OSAPINIB_limit_ram[ep], r28 ;/* 保護属性とサイズ */
2141 ldsr r27, 24, 6 ;/* MPLA6 */
2142 ldsr r28, 25, 6 ;/* MPUA6 */
2143
2144 ;/*
2145 ;* 自保護ドメイン専用のRWX領域(sdata)
2146 ;*/
2147 sld.w OSAPINIB_start_sram[ep], r27 ;/* 先頭番地 */
2148 sld.w OSAPINIB_limit_sram[ep], r28 ;/* 保護属性とサイズ */
2149 ldsr r27, 28, 6 ;/* MPLA7 */
2150 ldsr r28, 29, 6 ;/* MPUA7 */
2151
2152$endif ;/* (MPU_REGION_NUM >= 11) */
2153
2154 ;/*
2155 ;* 共有リード/専用ライト領域の専用領域
2156 ;*/
2157 sld.w OSAPINIB_start_srpw[ep], r27 ;/* 先頭番地 */
2158 sld.w OSAPINIB_limit_srpw[ep], r28 ;/* 保護属性とサイズ */
2159 ldsr r27, 4, 6 ;/* MPLA1 */
2160 ldsr r28, 5, 6 ;/* MPUA1 */
2161
2162 ;/*
2163 ;* 共有リード/専用ライト領域の専用領域(sdata)
2164 ;*/
2165 sld.w OSAPINIB_start_ssrpw[ep], r27 ;/* 先頭番地 */
2166 sld.w OSAPINIB_limit_ssrpw[ep], r28 ;/* 保護属性とサイズ */
2167 ldsr r27, 8, 6 ;/* MPLA2 */
2168 ldsr r28, 9, 6 ;/* MPUA2 */
2169
2170 sld.w OSAPINIB_mprc[ep], r27 ;/* MPRC */
2171 ldsr r27, 1, 5
2172$endif ;/* __v850e2v3__ */
2173
2174dispatcher_5:
2175$ifdef __v850e2v3__
2176 ldsr r0, bsel ;/* bselを戻す */
2177$endif ;/* __v850e2v3__ */
2178 ;/* =end modified for SC3 */
2179
2180$ifdef LOG_DSP_LEAVE
2181 ld.w 0[r21], r6 ;/* 引数に_p_runtskを指定 */
2182 jarl _log_dsp_leave, r31
2183$endif ;/* LOG_DSP_LEAVE */
2184
2185$ifdef CFG_USE_PRETASKHOOK
2186 Lea _PreTaskHook, r20
2187 cmp r20, r0
2188 be dispatcher_2
2189
2190pretaskhook_call:
2191 Lea _call_pretaskhook, r6
2192 jarl _stack_change_and_call_func_1, r31
2193$endif ;/* CFG_USE_PRETASKHOOK */
2194
2195dispatcher_2:
2196 Lea _p_runtsk, r20
2197 ld.w 0[r20], r22
2198 mov r22, ep
2199 sld.w TCB_pc[ep], r31
2200 jmp [r31]
2201
2202dispatcher_3:
2203 ;/*
2204 ;* OS割込み禁止状態の解除と,非タスクコンテキスト実行状態への
2205 ;* 準備をする
2206 ;*
2207 ;* ここで非タスクコンテキストに切り替える(sp=非タスクコンテキス
2208 ;* ト用スタックポインタ,except_nest_cnt=1)のは,OS割込み禁止解
2209 ;* 除後に発生する割込み処理にどのスタックを使うかという問題の解決
2210 ;* と,割込みハンドラ内でのタスクディスパッチの防止という2つの意
2211 ;* 味がある
2212 ;*/
2213 Lea __ostkpt, r20 ;/* 非タスクコンテキスト用のスタックの読み込みスタックポインタの入れ替え */
2214 ld.w 0[r20], r3
2215
2216 Lea _except_nest_cnt, r20
2217 mov 1, r21
2218 st.w r21, 0[r20]
2219
2220 ;/*
2221 ;* OS割込み禁止解除状態へ
2222 ;* 割込みを許可し,非タスクコンテキスト実行状態とし割込みを待つ
2223 ;*
2224 ;* プロセッサを割込み待ちに移行させる処理と,割込み許可とは,不可
2225 ;* 分に行なう必要がある
2226 ;* これを不可分に行なわない場合,割込みを許可した直後に割込
2227 ;* みが入り,その中でタスクが実行可能状態になると,実行すべきタス
2228 ;* クがあるにもかかわらずプロセッサが割込み待ちになってしまう.
2229 ;* 不可分に行うため,diによりコアでの割り込みを禁止した状態で,
2230 ;* INTCの割り込み優先度マスクを下げてからhaltを呼び出す.
2231 ;* 割り込みが発生した場合は,haltから復帰して次のeiでベクタに
2232 ;* ジャンプする.
2233 ;*
2234 ;* 割込み待ちの間は,p_runtskをNULL(=0)に設定しなければならない
2235 ;* このように設定しないと,割込みハンドラからGetTaskIDを呼び出
2236 ;* した際の動作が仕様に合致しなくなる
2237 ;*/
2238
2239 di
2240 OUTER_UNLOCK_OS_INT r12, r13
2241
2242$if 0
2243 nop
2244 nop
2245 nop
2246 nop
2247$else
2248 halt
2249$endif
2250 ei
2251
2252 ;/*
2253 ;* OS割込み禁止状態へ
2254 ;* (モデル上の)割込み優先度マスクは0であるため,ISR1以外の割込みは全て禁止する
2255 ;* スタックは非タスクコンテキストのスタックを使用しているため,_except_nest_cntは,
2256 ;* '1'のままとする
2257 ;*/
2258 OUTER_LOCK_OS_INT r12, r13
2259 br dispatcher_1
2260
2261
2262;/*
2263 ;* タスク開始時処理
2264 ;*
2265 ;* dispatcherから呼び出される
2266 ;*/
2267 ;/* =begin modified for SC3 */
2268 .extern _start_stask_r
2269_start_stask_r:
2270 Lea _p_runtsk, ep ;/* ep = p_runtsk */
2271 sld.w 0[ep], ep
2272 ;/*
2273 ;* タスクが不正終了した場合は保護処理を行うよう
2274 ;* 戻りアドレスにexit_taskを設定
2275 ;*/
2276 Lea __kernel_exit_task, r31
2277 mov r0, r6
2278 br _start_r
2279
2280 .extern _start_utask_r
2281_start_utask_r:
2282$ifndef __v850e3v5__
2283 ldsr r0, bsel
2284$endif
2285 Lea _p_runtsk, ep ;/* ep = p_runtsk */
2286 sld.w 0[ep], ep
2287 clr1 0, TCB_priv_mode[ep] ;/* 特権モード実行を抜ける */
2288 sld.w TCB_p_tinib[ep], r20 ;/* ep = p_runtsk->p_tinib */
2289 ld.w TINIB_ustk_bottom[r20], r20 ;/* r20 = ユーザスタックポインタの初期値 */
2290 mov r20, sp
2291 ;/*
2292 ;* タスクが不正終了した場合は保護処理を行うよう
2293 ;* 戻りアドレスにexit_utaskを設定
2294 ;*/
2295 Lea _exit_utask, lp ;/* lp = _exit_utask */
2296 stsr psw, r10
2297
2298 ;/*
2299 ;* 全割込み禁止状態へ
2300 ;* タスクコンテキストへのジャンプで解除される
2301 ;*/
2302 di
2303
2304 ;/*
2305 ;* 非特権モードで動作するよう準備
2306 ;* 保護機能有効(非信頼へ),割込み許可
2307 ;* PP,NPV,DMP,IMP = 1, ID = 0
2308 ;*/
2309$ifdef __v850e2v3__
2310 movhi 0x000f, r0, r7
2311$elseif defined(__v850e3v5__)
2312 movhi 0x4000, r0, r7
2313$endif ;/* __v850e2v3__ */
2314 or r7, r10 ;/* psw |= (PP|NPV|DMP|IMP) */
2315 ldsr r10, eipsw ;/* eipsw = psw */
2316 mov 1, r6
2317
2318 .extern _start_r
2319_start_r:
2320 ld.w TCB_p_tinib[ep], r22
2321$ifdef CFG_USE_STACKMONITORING
2322 ;/*
2323 ;* SC3ではタスク強制終了があるので,タスク起動毎にマジックナンバー
2324 ;* を初期化する
2325 ;*/
2326 ld.w TINIB_sstk_bottom[r22], r21
2327 ld.w TINIB_sstksz[r22], r10
2328 sub r10, r21
2329 mov STACK_MAGIC_NUMBER, r10
2330 st.w r10, 0[r21]
2331$endif ;/* CFG_USE_STACKMONITORING */
2332
2333 ;/*
2334 ;* OS割込み禁止解除前に現在優先度(TCB.curpri)を実行優先度(TINIB.exepri)に
2335 ;* 変更(内部リソースを獲得)
2336 ;*/
2337 ld.b TINIB_exepri[r22], r21 ;/* TINIB.exepri -> TCB.curpri */
2338 st.b r21, TCB_curpri[ep]
2339
2340 ;/*
2341 ;* OS割込み禁止解除状態へ
2342 ;* (モデル上の)割込み優先度マスクは0であるため,有効な割込みは全て許可する
2343 ;*/
2344
2345 OUTER_UNLOCK_OS_INT r12, r13
2346
2347 ld.w TCB_p_tinib[ep], r22
2348 ld.w TINIB_task[r22], r10
2349 cmp r0, r6
2350 bne _start_r_1 ;/* r6 != 0 ならば _start_r_1 へ*/
2351 jmp [r10]
2352
2353_start_r_1:
2354 ldsr r10, eipc ;/* EIPC = pc */
2355 eiret
2356 ;/* =end modified for SC3 */
2357
2358 ;/*
2359 ;* ext_tskをsvc命令で呼び出す
2360 ;*/
2361 shared.text .cseg text
2362 .align 4
2363 .public _exit_utask
2364_exit_utask:
2365 mov TFN_EXIT_TASK, r11
2366 syscall NO_SVC
2367 nop
2368
2369 kernel.text .cseg text
2370 .extern _stack_change_and_call_func_1
2371 .extern _stack_change_and_call_func_2
2372_stack_change_and_call_func_1:
2373_stack_change_and_call_func_2:
2374
2375 Lea _except_nest_cnt, r12
2376 ld.w 0[r12], r13
2377 add 1, r13
2378 st.w r13, 0[r12]
2379 cmp 1, r13
2380 bne _stack_change_and_call_func_1_1
2381
2382 ;/* スタックポインタの保存と入れ替え */
2383 Lea __ostkpt, r12
2384 ld.w 0[r12], r12
2385 add -4, r12
2386 st.w sp, 0[r12] ;/* スタックポインタの保存 */
2387 mov r12, sp ;/* スタックポインタの切り替え */
2388
2389
2390_stack_change_and_call_func_1_1:
2391 push lp
2392 Lea stack_change_and_call_func_r, lp ;/* 戻りアドレス */
2393 mov r6, r12
2394 mov r7, r6
2395 mov r8, r7
2396 jmp [r12]
2397
2398stack_change_and_call_func_r:
2399 pop lp
2400 Lea _except_nest_cnt, r12
2401 ld.w 0[r12], r13
2402 add -1, r13
2403 st.w r13, 0[r12]
2404 cmp r0, r13
2405 bne stack_change_and_call_func_r_1
2406
2407 ld.w 0[sp], sp ;/* スタックポインタの復帰 */
2408stack_change_and_call_func_r_1:
2409 jmp [lp]
2410
2411
2412$ifdef ENABLE_RETURN_MAIN
2413;/*
2414 ;* AKTSP用のmain()へのリターンコード
2415 ;*/
2416 .extern _return_main
2417_return_main:
2418 Lea __ostkpt, sp
2419 ld.w 0[sp],sp
2420 jarl _main, r31
2421$endif ;/* ENABLE_RETURN_MAIN */
2422
2423 ;/* =begin modified for SC3 */
2424;/*
2425 ;* SYSCALLテーブル
2426 ;* syscall命令は、scbp + scbp[x] の番地にジャンプする
2427 ;*/
2428 .public _syscall_table
2429 kernel.text .cseg text
2430 .align 4
2431_syscall_table:
2432 .dw (_syscall_error_handler - _syscall_table)
2433 .dw (_svc_entry - _syscall_table)
2434 .dw (_call_nontrusted_hook_trap_ret - _syscall_table)
2435
2436 .public _syscall_error_handler
2437 .public _svc_entry
2438;/*
2439 ;* SYSCALLエラーハンドラ
2440 ;*/
2441_syscall_error_handler:
2442 br _syscall_error_handler
2443 nop
2444
2445;/*
2446 ;* サービスコールの出入口
2447 ;* PP,NPV,DMP,IMP = 0, ID,EP = 1
2448 ;* eipc = pc, eipsw = psw : eiする前に保存
2449 ;* r10 : 返り値
2450 ;* r11:関数コード
2451 ;* r6 - r9 : 引数(4つまで)
2452 ;* r20 : 第5引数
2453 ;* スクラッチレジスタ保存済み
2454 ;* lp保存済み
2455 ;*/
2456_svc_entry:
2457 ;/*
2458 ;* 呼出し元が特権モードか?
2459 ;* eipswをチェックする
2460 ;*/
2461$ifndef __v850e3v5__
2462 ldsr r0, bsel
2463$endif
2464 stsr eipsw, r13
2465 shl PSW_SV, r13 ;/* r13 << PSW_SV により例外発生時のモード取得 */
2466 bnc svc_entry_2 ;/* 特権モードからの呼出しならばスキップ */
2467
2468 ;/*
2469 ;* 呼出し元が非信頼フック実行中か?
2470 ;* hook_savedspをチェックする
2471 ;* 非信頼フック実行中ならばスタック切替
2472 ;*/
2473 Lea _hook_savedsp, ep
2474 sld.w 0[ep], ep
2475 cmp r0, ep
2476 be svc_entry_1 ;/* hook_savedsp == 0:タスクコンテキスト */
2477 addi -4, ep, ep
2478 sst.w sp, 0[ep] ;/* *(hook_savedsp - 4) = sp */
2479 mov ep, sp ;/* sp = hook_savedsp - 4 */
2480 br svc_entry_2
2481
2482svc_entry_1:
2483 ;/*
2484 ;* タスクコンテキストからの呼出しの場合
2485 ;*/
2486 ;/*
2487 ;* ユーザスタックとシステムスタックを入れ替える
2488 ;* タスクの状態を特権モード実行中に移行する
2489 ;* 戻り先が非特権モードで非信頼フック実行中でなければ,
2490 ;* タスク実行中であるはずなので,p_runtskがNULLかどうかの
2491 ;* チェックは必要ないはず
2492 ;*/
2493 Lea _p_runtsk, ep
2494 sld.w 0[ep], ep
2495 set1 0, TCB_priv_mode[ep] ;/* p_runtsk->priv_mode |= 0x01 */
2496 sst.w sp, TCB_usp[ep] ;/* uspを保存 */
2497 sld.w TCB_p_tinib[ep], ep
2498 sld.w TINIB_sstk_bottom[ep], sp ;/* sspを復帰 */
2499
2500svc_entry_2:
2501 ;/*
2502 ;* eipcとeipsw(syscall呼出し元のpcとpsw)を保存して
2503 ;* 割込みからリターン
2504 ;* +--------------+ <- new sp
2505 ;* | eipsw |
2506 ;* +--------------+
2507 ;* | eipc |
2508 ;* +--------------+ <- old sp
2509 ;*/
2510 addi -8, sp, sp
2511 mov sp, ep
2512 stsr eipc, r12
2513 sst.w r12, 4[ep]
2514 stsr eipsw, r12
2515 sst.w r12, 0[ep]
2516 ;/*
2517 ;* eipswの保護関連ビットを0にする
2518 ;*/
2519$ifdef __v850e2v3__
2520 movhi 0x000f, r0, r13
2521$elseif defined(__v850e3v5__)
2522 movhi 0x4000, r0, r13
2523$endif ;/* __v850e2v3__ */
2524 not r13, r13
2525 and r13, r12
2526 ldsr r12, eipsw ;/* PP,NPV,DMP,IMP = 0 */
2527 Lea svc_entry_3, r12
2528 ldsr r12, eipc
2529 eiret
2530
2531svc_entry_3:
2532 ;/*
2533 ;* 機能コードのチェック
2534 ;*/
2535 mov TMAX_SVCID, r12
2536 cmp r12, r11 ;/* 機能コードの上限チェック(TMAX_SVCID < r11) */
2537 bgt svc_entry_error ;/* 上限をオーバしているならばエラー */
2538
2539 ;/*
2540 ;* サービスコールのテーブルを引き,
2541 ;* サービスコールの本体を呼ぶ
2542 ;*/
2543 Lea _svc_table, r12
2544 shl 2, r11 ;/* r11 *= 4 */
2545 add r11, r12 ;/* r12 = &svc_table[r11] */
2546 ld.w 0[r12], r12 ;/* テーブルを引く */
2547 Lea svc_entry_r, lp ;/* 戻り番地を設定 */
2548 jmp [r12] ;/* サービスコール処理ルーチンを呼ぶ */
2549 nop
2550
2551svc_entry_error:
2552 jarl _no_support_service, lp ;/* no_support_service を呼ぶ */
2553
2554svc_entry_r:
2555 ;/*
2556 ;* この時点でのpswをr11に保存する
2557 ;* 全割込み禁止で更新した時への対応
2558 ;*/
2559 stsr psw, r11
2560
2561 ;/*
2562 ;* 全割込み禁止状態へ
2563 ;*/
2564 di
2565
2566 ;/*
2567 ;* eipcとeipsw(syscall呼出し元のpcとpsw)を復帰
2568 ;* ここでは,割込み処理中でない(サービスコール呼出し前に
2569 ;* eiretを発行している)が,eiretを利用してリターンする
2570 ;* +--------------+ <- old sp
2571 ;* | eipc |
2572 ;* +--------------+
2573 ;* | eipsw |
2574 ;* +--------------+ <- new sp
2575 ;*/
2576 mov sp, ep
2577 sld.w 4[ep], r15
2578 sld.w 0[ep], r16
2579 addi 8, sp, sp
2580
2581 ;/*
2582 ;* スタックを戻すかチェック
2583 ;*/
2584 ;/*
2585 ;* 呼出し元が特権モードか?
2586 ;* eipswをチェックする
2587 ;*/
2588$ifdef __v850e2v3__
2589 ldsr r0, bsel
2590 movhi 0x000f, r0, r12
2591$elseif defined(__v850e3v5__)
2592 movhi 0x4000, r0, r12
2593$endif ;/* __v850e2v3__ */
2594 tst r16, r12
2595 be svc_prv_r ;/* 特権モードからの呼出しならばスキップ */
2596
2597 ;/*
2598 ;* 呼出し元が非信頼フック実行中か?
2599 ;* hook_savedspをチェックする
2600 ;* 非信頼フック実行中ならばスタック切替
2601 ;*/
2602 Lea _hook_savedsp, ep
2603 sld.w 0[ep], ep
2604 cmp r0, ep
2605 be svc_entry_r_1 ;/* hook_savedsp == 0:タスクコンテキストのチェックへ */
2606 addi -4, ep, ep
2607 sld.w 0[ep], sp ;/* sp = *(hook_savedsp - 4) */
2608 ;/*
2609 ;* ここで,hook_savedspを更新する必要はない
2610 ;*/
2611 br svc_prv_r
2612
2613svc_entry_r_1:
2614 Lea _p_runtsk, ep
2615 sld.w 0[ep], ep
2616 tst1 0, TCB_priv_mode[ep] ;/* uspを保存したか? */
2617 be svc_prv_r ;/* uspを保存していないならばスキップ */
2618
2619svc_usr_r:
2620 ;/*
2621 ;* 特権モード実行を抜ける
2622 ;* sstkとustkを入れ替える
2623 ;* 戻り先がタスクコンテキストならば,タスク実行中であるはず
2624 ;* なので,p_runtskがNULLかどうかのチェックは必要ないはず
2625 ;*/
2626 clr1 0, TCB_priv_mode[ep] ;/* p_runtsk->priv_mode &= !0x01 */
2627 sld.w TCB_usp[ep], sp ;/* uspを復帰 */
2628
2629svc_prv_r:
2630 ;/*
2631 ;* システムサービスでセットされた割込み優先度マスクを反映する
2632 ;*/
2633 mov 0x20, r12
2634 and r12, r11 ;/* PSW.ID以外を0に */
2635 not r12, r12 ;/* r12 = !0x20 */
2636 and r12, r16 ;/* eipsw &= !0x20 */
2637 or r11, r16 ;/* eipsw |= r11 */
2638 ldsr r16, eipsw
2639 ldsr r15, eipc
2640 eiret ;/* 呼出し元へリターン */
2641 nop
2642
2643 ;/*
2644 ;* 信頼シャットダウンフックの呼出し
2645 ;* r6 = フックのアドレス
2646 ;* r7 = フックに渡すエラーコード
2647 ;*/
2648 .extern _call_trusted_hook
2649_call_trusted_hook:
2650 ;/*
2651 ;* 関数呼出しで呼ばれるので,callee saved のみ保存
2652 ;*/
2653 addi -68, sp, sp
2654 st.w ep, 0[sp]
2655 mov sp, ep
2656 sst.w r2, 56[ep]
2657 sst.w r10, 52[ep]
2658 sst.w r11, 48[ep]
2659 sst.w r20, 44[ep]
2660 sst.w r21, 40[ep]
2661 sst.w r22, 36[ep]
2662 sst.w r23, 32[ep]
2663 sst.w r24, 28[ep]
2664 sst.w r25, 24[ep]
2665 sst.w r26, 20[ep]
2666 sst.w r27, 16[ep]
2667 sst.w r28, 12[ep]
2668 sst.w r29, 8[ep]
2669 sst.w r31, 4[ep] ;/* lp */
2670 ;/*
2671 ;* キャンセルしたときのために下記のデータを保存
2672 ;* except_nest_cntを保存
2673 ;* シャットダウンフック実行中にフックがネストするたびに+1される
2674 ;* のを戻すため
2675 ;* callevel_statを保存
2676 ;* シャットダウンフック実行中に追加されたcallevelを戻すため
2677 ;* sp を保存
2678 ;*/
2679 Lea _except_nest_cnt, r2
2680 ld.w 0[r2], r2
2681 sst.w r2, 64[ep]
2682 Lea _callevel_stat, r2
2683 ld.h 0[r2], r2
2684 sst.w r2, 60[ep]
2685 Lea _trusted_hook_savedsp, ep
2686 sst.w sp, 0[ep]
2687 ;/*
2688 ;* 信頼フックを呼ぶ
2689 ;*/
2690 mov r6, r11
2691 mov r7, r6
2692 Lea _trusted_hook_ret, lp
2693 jmp [r11]
2694
2695 .extern _exit_trusted_shutdown_hook
2696_exit_trusted_shutdown_hook:
2697 ;/*
2698 ;* sp を trusted_hook_savedsp から復帰
2699 ;*/
2700 Lea _trusted_hook_savedsp, ep
2701 sld.w 0[ep], sp
2702 ld.h 60[sp], r2
2703 Lea _callevel_stat, r10
2704 st.h r2, 0[r10]
2705 ld.w 64[sp], r2
2706 Lea _except_nest_cnt, r10
2707 st.w r2, 0[r10]
2708_trusted_hook_ret:
2709 ;/*
2710 ;* trusted_hook_savedsp を0初期化
2711 ;*/
2712 Lea _trusted_hook_savedsp, ep
2713 sst.w r0, 0[ep]
2714 mov sp, ep
2715 sld.w 56[ep], r2
2716 sld.w 52[ep], r10
2717 sld.w 48[ep], r11
2718 sld.w 44[ep], r20
2719 sld.w 40[ep], r21
2720 sld.w 36[ep], r22
2721 sld.w 32[ep], r23
2722 sld.w 28[ep], r24
2723 sld.w 24[ep], r25
2724 sld.w 20[ep], r26
2725 sld.w 16[ep], r27
2726 sld.w 12[ep], r28
2727 sld.w 8[ep], r29
2728 sld.w 4[ep], r31
2729 addi 68, ep, sp
2730 ld.w 0[sp], ep
2731 jmp [lp]
2732
2733 ;/*
2734 ;* 非信頼フックの呼出し
2735 ;* r6 = フックのアドレス
2736 ;* r7 = フックに渡すエラーコード
2737 ;* r8 = フックの種別
2738 ;*/
2739 .extern _call_nontrusted_hook
2740_call_nontrusted_hook:
2741 ;/*
2742 ;* 関数呼出しで呼ばれるので,callee saved のみ保存
2743 ;*/
2744 addi -76, sp, sp
2745 st.w ep, 0[sp]
2746 mov sp, ep
2747 sst.w r2, 56[ep]
2748 sst.w r10, 52[ep]
2749 sst.w r11, 48[ep]
2750 sst.w r20, 44[ep]
2751 sst.w r21, 40[ep]
2752 sst.w r22, 36[ep]
2753 sst.w r23, 32[ep]
2754 sst.w r24, 28[ep]
2755 sst.w r25, 24[ep]
2756 sst.w r26, 20[ep]
2757 sst.w r27, 16[ep]
2758 sst.w r28, 12[ep]
2759 sst.w r29, 8[ep]
2760 sst.w r31, 4[ep]
2761 ;/*
2762 ;* hook_savedspをスタックに保存し,
2763 ;* sp をhook_savedspに保存
2764 ;* shutdown_hook_savedspをスタックに保存
2765 ;*/
2766 Lea _hook_savedsp, r11
2767 ld.w 0[r11], r10
2768 sst.w r10, 60[ep]
2769 st.w sp, 0[r11]
2770 Lea _shutdown_hook_savedsp, r2
2771 ld.h 0[r2], r2
2772 sst.w r2, 72[ep]
2773 ;/*
2774 ;* except_nest_cntを保存
2775 ;* シャットダウンフック実行中にフックがネストするたびに+1される
2776 ;* のを戻すため
2777 ;* callevel_statを保存
2778 ;* シャットダウンフック実行中に追加されたcallevelを戻すため
2779 ;*/
2780 Lea _except_nest_cnt, r2
2781 ld.w 0[r2], r2
2782 sst.w r2, 68[ep]
2783 Lea _callevel_stat, r2
2784 ld.h 0[r2], r2
2785 sst.w r2, 64[ep]
2786 ;/*
2787 ;* 非信頼シャットダウンフックの強制終了のために下記のデータを保存
2788 ;* sp を保存
2789 ;* 非信頼シャットダウンフック実行中かどうかを判断する
2790 ;*/
2791 mov SHUTDOWN_HOOK, r11
2792 cmp r8, r11
2793 bne call_nontrusted_hook_1 ;/* シャットダウンフックでなければスキップ */
2794 Lea _shutdown_hook_savedsp, ep
2795 sst.w sp, 0[ep]
2796call_nontrusted_hook_1:
2797 ;/*
2798 ;* PSWをr13に退避
2799 ;* bselを切り替えるため全割込み禁止
2800 ;*/
2801 stsr psw, r13
2802 LOCK_ALL_INT
2803
2804 ;/*
2805 ;* システムレジスタのバンク切り替え
2806 ;* MPUの設定用
2807 ;*/
2808$ifdef __v850e2v3__
2809 ori 0x1001, r0, r27
2810 ldsr r27, bsel
2811$endif ;/* __v850e2v3__ */
2812 ;/*
2813 ;* 非信頼フックがネストしていない場合は非信頼フック用スタックに切り替える
2814 ;* 前のhook_savedsp == 0の場合は非信頼フックルーチンがネストしていない
2815 ;*/
2816 cmp r0, r10 ;/* 0 == hook_savedsp ? */
2817 bne call_nontrusted_hook_2
2818
2819 ;/*
2820 ;* MPUのスタック領域を切替え
2821 ;* 非信頼フック用のスタック領域
2822 ;* 非信頼フック実行中にはタスクコンテキストに切り替わらないため,
2823 ;* ネストしている場合にはMPUのスタック領域を切り替える必要がない
2824 ;*/
2825 Lea __nthkstk, ep
2826 sld.w 0[ep], r27 ;/* 先頭番地 */
2827 Lea __nthkstksz, ep
2828 sld.w 0[ep], r28 ;/* サイズ */
2829 add r27, r28 ;/* 終端番地 */
2830
2831 ;/*
2832 ;* 非信頼フック用スタックに切り替える
2833 ;* call_nontrusted_hookは特権モードからのみ呼び出される.
2834 ;* よって,この時点でのspは非信頼フック用スタックでありえない.
2835 ;* ここでは非信頼フックはネストしていないので,スタックの底で初期化
2836 ;*/
2837 mov r28, sp
2838
2839$ifdef __v850e2v3__
2840 ori 0x01, r27, r27 ;/* 有効ビット */
2841 ori 0x06, r28, r28 ;/* RWを許可 */
2842 ldsr r27, dpa0l
2843 ldsr r28, dpa0u
2844$elseif defined(__v850e3v5__)
2845 ldsr r27, 0, 6 ;/* MPLA0 */
2846 ldsr r28, 1, 6 ;/* MPUA0 */
2847$endif ;/* __v850e2v3__ */
2848
2849 br call_nontrusted_hook_3
2850
2851call_nontrusted_hook_2:
2852 ;/*
2853 ;* 非信頼フック用スタックに切り替える
2854 ;* call_nontrusted_hookは特権モードからのみ呼び出される.
2855 ;* よって,この時点でのspは非信頼フック用スタックでありえない.
2856 ;* ここでは非信頼フックがネストしており,非信頼フックから特権モード
2857 ;* に移行し,その中で非信頼フックが呼ばれた場合である.
2858 ;* 非信頼フックから特権モードに切り替わるのは,trap命令発行時
2859 ;* (システムサービス呼出し),または,例外や割込み発生時である.
2860 ;* 上記の特権モード切替時に非信頼フック実行中である場合には,
2861 ;* スタックを切り替えるときに,*(hook_savedsp-4)にspを保存することとする
2862 ;* hook_savedspはcall_nontrusted_hookでのみ変化し,
2863 ;* 非信頼フック実行中には(タスクコンテキストに切り替わらないため)
2864 ;* hook_savedspがシステムスタックポインタとなるため,hook_savedspから
2865 ;* spの続きを求めることができる
2866 ;* 非信頼フック用spを退避する専用の変数を設ける方法も考えられるが,
2867 ;* 割込みや例外のエントリ部分が複雑となるため,本実装では使用しない
2868 ;*/
2869 addi -4, r10, r10
2870 ld.w 0[r10], sp
2871
2872call_nontrusted_hook_3:
2873 ;/*
2874 ;* 実行ドメインと保護ドメイン(MPUの設定)が同じならば,
2875 ;* ドメイン毎のコード領域・データ領域をMPUに設定し直す必要はない
2876 ;*/
2877 Lea _p_runosap, ep ;/* ep = &p_runosap */
2878 sld.w 0[ep], r26 ;/* r26 = p_runosap */
2879 Lea _p_ctxosap, ep ;/* ep = &p_ctxosap */
2880 sld.w 0[ep], r27 ;/* r27 = p_ctxosap */
2881 cmp r27, r26 ;/* p_ctxosap == p_runosap ? */
2882 be call_nontrusted_hook_4 ;/* 同じならcall_nontrusted_hook_4へ */
2883 nop
2884 sst.w r26, 0[ep] ;/* p_ctxosap = p_runosap : 保護ドメインを切替え */
2885$ifdef __v850e2v3__
2886 ldsr r26, vmtid ;/* メモリ保護違反タスク識別子をp_runosapとする */
2887 ld.w OSAPCB_p_osapinib[r26], ep ;/* ep = p_osapinib */
2888
2889 ;/*
2890 ;* 自保護ドメイン専用のrom領域
2891 ;*/
2892 sld.w OSAPINIB_start_text[ep], r27 ;/* 先頭番地 */
2893 sld.w OSAPINIB_limit_text[ep], r28 ;/* 保護属性とサイズ */
2894 ldsr r27, ipa0l
2895 ldsr r28, ipa0u
2896 ;/*
2897 ;* 自保護ドメイン専用のrosdata領域
2898 ;*/
2899 sld.w OSAPINIB_start_rosdata[ep], r27 ;/* 先頭番地 */
2900 sld.w OSAPINIB_limit_rosdata[ep], r28 ;/* 保護属性とサイズ */
2901 ldsr r27, ipa1l
2902 ldsr r28, ipa1u
2903 ;/*
2904 ;* 自保護ドメイン専用のRWX領域
2905 ;*/
2906 sld.w OSAPINIB_start_ram[ep], r27 ;/* 先頭番地 */
2907 sld.w OSAPINIB_limit_ram[ep], r28 ;/* 保護属性とサイズ */
2908 ldsr r27, dpa1l
2909 ldsr r28, dpa1u
2910 ;/*
2911 ;* 自保護ドメイン専用のRWX領域(sdata)
2912 ;*/
2913 sld.w OSAPINIB_start_sram[ep], r27 ;/* 先頭番地 */
2914 sld.w OSAPINIB_limit_sram[ep], r28 ;/* 保護属性とサイズ */
2915 ldsr r27, dpa2l
2916 ldsr r28, dpa2u
2917 ;/*
2918 ;* 共有リード/専用ライト領域の専用領域
2919 ;*/
2920 sld.w OSAPINIB_start_srpw[ep], r27 ;/* 先頭番地 */
2921 sld.w OSAPINIB_limit_srpw[ep], r28 ;/* 保護属性とサイズ */
2922 ldsr r27, dpa3l
2923 ldsr r28, dpa3u
2924 ;/*
2925 ;* 共有リード/専用ライト領域の専用領域(sdata)
2926 ;*/
2927 sld.w OSAPINIB_start_ssrpw[ep], r27 ;/* 先頭番地 */
2928 sld.w OSAPINIB_limit_ssrpw[ep], r28 ;/* 保護属性とサイズ */
2929 ldsr r27, dpa4l
2930 ldsr r28, dpa4u
2931$elseif defined(__v850e3v5__)
2932 ld.w OSAPCB_p_osapinib[r26], ep ;/* ep = p_osapinib */
2933
2934 ;/*
2935 ;* 共有リード/専用ライト領域の専用領域
2936 ;*/
2937 sld.w OSAPINIB_start_srpw[ep], r27 ;/* 先頭番地 */
2938 sld.w OSAPINIB_limit_srpw[ep], r28 ;/* 保護属性とサイズ */
2939 ldsr r27, 4, 6 ;/* MPLA1 */
2940 ldsr r28, 5, 6 ;/* MPUA1 */
2941
2942 ;/*
2943 ;* 共有リード/専用ライト領域の専用領域(sdata)
2944 ;*/
2945 sld.w OSAPINIB_start_ssrpw[ep], r27 ;/* 先頭番地 */
2946 sld.w OSAPINIB_limit_ssrpw[ep], r28 ;/* 保護属性とサイズ */
2947 ldsr r27, 8, 6 ;/* MPLA2 */
2948 ldsr r28, 9, 6 ;/* MPUA2 */
2949
2950 sld.w OSAPINIB_mprc[ep], r27 ;/* MPRC */
2951 ldsr r27, 1, 5
2952$endif ;/* __v850e2v3__ */
2953
2954
2955call_nontrusted_hook_4:
2956$ifdef __v850e2v3__
2957 ldsr r0, bsel ;/* bselを戻す */
2958$endif ;/* __v850e2v3__ */
2959
2960 ;/*
2961 ;* 非信頼フックのアドレスを準備
2962 ;* 非信頼フックからの戻り番地をexit_nontrusted_hook_trapに指定
2963 ;*/
2964 ldsr r6, eipc
2965 Lea _exit_nontrusted_hook_trap, lp
2966
2967 ;/*
2968 ;* 非信頼フックの引数を準備
2969 ;*/
2970 mov r7, r6 ;/* エラーコード */
2971
2972 ;/*
2973 ;* 保護機能有効(非信頼へ)
2974 ;* 割込み禁止/許可を戻す
2975 ;* PP,NPV,DMP,IMP = 1, ID = PSW.ID
2976 ;*/
2977$ifdef __v850e2v3__
2978 movhi 0x000f, r0, r14
2979$elseif defined(__v850e3v5__)
2980 movhi 0x4000, r0, r14
2981$endif ;/* __v850e2v3__ */
2982 or r14, r13 ;/* psw |= (PP|NPV|DMP|IMP) */
2983 ldsr r13, eipsw ;/* eipsw = psw */
2984 eiret
2985 nop
2986
2987 .extern _exit_nontrusted_hook
2988_exit_nontrusted_hook:
2989 Lea _hook_savedsp, ep
2990 sld.w 0[ep], sp
2991 ld.h 64[sp], r2
2992 Lea _callevel_stat, r10
2993 st.h r2, 0[r10]
2994 ld.w 68[sp], r2
2995 Lea _except_nest_cnt, r10
2996 st.w r2, 0[r10]
2997 ;/*
2998 ;* 元のPSW.IDをr10に保存
2999 ;*/
3000 stsr eipsw, r10
3001 andi 0x20, r10, r10
3002 br call_nontrusted_hook_r_1
3003
3004 ;/*
3005 ;* スタックチェック関数
3006 ;* 入力 r6 使用するスタック量
3007 ;* 使用するスタック量が残っていない場合はエラー
3008 ;*/
3009 .extern _trustedfunc_stack_check
3010_trustedfunc_stack_check:
3011 Lea _callevel_stat, ep
3012 sld.h 0[ep], r10
3013 addi TCL_ISR2, r0, r11
3014 tst r11, r10
3015 be trustedfunc_stack_check_1 ;/* TCL_TASKの場合はスキップ */
3016
3017 ;/*
3018 ;* _ostkを使用中
3019 ;*/
3020 Lea __ostk, ep
3021 sld.w 0[ep], r11
3022 br trustedfunc_stack_check_2
3023
3024trustedfunc_stack_check_1:
3025 ;/*
3026 ;* タスクのシステムスタックを使用中
3027 ;*/
3028 Lea _p_runtsk, ep
3029 sld.w 0[ep], ep
3030 sld.w TCB_p_tinib[ep], ep
3031 sld.w TINIB_sstk_bottom[ep], r11
3032 sld.w TINIB_sstksz[ep], r12
3033 sub r12, r11
3034trustedfunc_stack_check_2:
3035 ;/*
3036 ;* スタックの残量をチェック
3037 ;* r11 = スタックの先頭
3038 ;*/
3039 subr sp, r6 ;/* r6 = ssp - tf_stksz */
3040 bl trustedfunc_stack_check_3 ;/* ssp < tfstksz ならばエラー処理へ */
3041 cmp r11, r6 ;/* r11 < r6 ? */
3042 bnh trustedfunc_stack_check_3 ;/* そうでなければエラー処理へ */
3043 addi E_OK, r0, r10
3044 jmp [lp]
3045
3046trustedfunc_stack_check_3:
3047 addi E_OS_STACKINSUFFICIENT, r0, r10
3048 jmp [lp]
3049
3050 ;/*
3051 ;* 非信頼フックからのリターン
3052 ;* syscallで呼ばれる
3053 ;*/
3054 .extern _call_nontrusted_hook_trap_ret
3055_call_nontrusted_hook_trap_ret:
3056 ;/*
3057 ;* sp を hook_savedspから復帰
3058 ;*/
3059 Lea _hook_savedsp, ep
3060 sld.w 0[ep], sp
3061 ;/*
3062 ;* syscall前のPSW.IDをr10に保存
3063 ;*/
3064 stsr eipsw, r10
3065 andi 0x20, r10, r10
3066
3067call_nontrusted_hook_r_1:
3068 ;/*
3069 ;* hook_savedspを退避していた値に戻す
3070 ;* shutdown_hook_savedspを退避していた値に戻す
3071 ;*/
3072 ld.w 72[sp], r2
3073 sst.w r2, 0[ep]
3074 ld.w 60[sp], r20
3075 Lea _shutdown_hook_savedsp, ep
3076 sst.w r20, 0[ep]
3077
3078 ;/*
3079 ;* ネストの場合(hook_savedsp != 0)はここでリターン
3080 ;* フック実行中はタスクが切り替わらないためMPU設定を復帰しない
3081 ;*/
3082 cmp r0, r20 ;/* hook_savedsp == NULL ? */
3083 bne call_nontrusted_hook_r_2
3084 Lea _p_runtsk, ep
3085 sld.w 0[ep], ep
3086 cmp r0, ep ;/* p_runtsk != NULL ? */
3087 be call_nontrusted_hook_r_2
3088 sld.w TCB_p_tinib[ep], ep
3089
3090 ;/*
3091 ;* bselを変更するため全割込み禁止
3092 ;*/
3093 LOCK_ALL_INT
3094
3095 ;/*
3096 ;* システムレジスタのバンク切り替え
3097 ;* MPUの設定用
3098 ;*/
3099$ifdef __v850e2v3__
3100 ori 0x1001, r0, r27
3101 ldsr r27, bsel
3102 ;/*
3103 ;* ユーザスタック領域
3104 ;*/
3105 sld.w TINIB_start_ustk[ep], r27 ;/* 先頭番地 */
3106 ori 0x01, r27, r27
3107 sld.w TINIB_limit_ustk[ep], r28 ;/* 保護属性とサイズ */
3108 ori 0x06, r28, r28
3109 ldsr r27, dpa0l
3110 ldsr r28, dpa0u
3111
3112 ldsr r0, bsel ;/* bselを戻す */
3113$elseif defined(__v850e3v5__)
3114 ;/*
3115 ;* ユーザスタック領域
3116 ;*/
3117 sld.w TINIB_start_ustk[ep], r27 ;/* 先頭番地 */
3118 sld.w TINIB_limit_ustk[ep], r28 ;/* 保護属性とサイズ */
3119 ldsr r27, 0, 6 ;/* MPLA0 */
3120 ldsr r28, 1, 6 ;/* MPUA0 */
3121$endif ;/* __v850e2v3__ */
3122
3123$if 0
3124 UNLOCK_ALL_INT
3125$else
3126 ;/*
3127 ;* PSW.IDを戻す
3128 ;*/
3129 mov 0x20, r11
3130 tst r10, r11
3131 bnz call_nontrusted_hook_r_2
3132
3133 UNLOCK_ALL_INT
3134$endif ;/* 0 */
3135
3136call_nontrusted_hook_r_2:
3137 mov sp, ep
3138 sld.w 56[ep], r2
3139 sld.w 52[ep], r10
3140 sld.w 48[ep], r11
3141 sld.w 44[ep], r20
3142 sld.w 40[ep], r21
3143 sld.w 36[ep], r22
3144 sld.w 32[ep], r23
3145 sld.w 28[ep], r24
3146 sld.w 24[ep], r25
3147 sld.w 20[ep], r26
3148 sld.w 16[ep], r27
3149 sld.w 12[ep], r28
3150 sld.w 8[ep], r29
3151 sld.w 4[ep], r31
3152 sld.w 0[ep], ep
3153 addi 76, sp, sp
3154 jmp [lp]
3155
3156 ;/*
3157 ;* (6-22-2) void cancel_nontrusted_hook(void)
3158 ;* cancel_nontrusted_hookはタスク強制終了時に,ターゲット非依存部から呼び出される.
3159 ;* 非信頼フック実行中に非信頼フックスタック領域のMPU設定を無効化する.
3160 ;*/
3161 .extern _cancel_nontrusted_hook
3162_cancel_nontrusted_hook:
3163 ;/*
3164 ;* PSW.IDをr10に保存
3165 ;*/
3166 stsr psw, r10
3167 andi 0x20, r10, r10
3168
3169 Lea _hook_savedsp, r11
3170 ld.w 0[r11], r12
3171 ;/*
3172 ;* ネストの場合(hook_savedsp == 0)はここでリターン
3173 ;*/
3174 cmp r0, r12 ;/* hook_savedsp == NULL ? */
3175 be cancel_nontrusted_hook_r
3176 ;/*
3177 ;* hook_savedsp = 0
3178 ;*/
3179 st.w r0, 0[r11]
3180
3181 ;/*
3182 ;* bselを変更するため全割込み禁止
3183 ;*/
3184 LOCK_ALL_INT
3185
3186$ifdef __v850e2v3__
3187 ;/*
3188 ;* システムレジスタのバンク切り替え
3189 ;* MPUの設定用
3190 ;*/
3191 ori 0x1001, r0, r11
3192 ldsr r11, bsel
3193 ;/*
3194 ;* ユーザスタック領域をNULLに設定
3195 ;*/
3196 ldsr r0, dpa0l
3197 ldsr r0, dpa0u
3198
3199 ldsr r0, bsel ;/* bselを戻す */
3200$elseif defined(__v850e3v5__)
3201 ;/*
3202 ;* ユーザスタック領域
3203 ;*/
3204 ldsr r0, 0, 6 ;/* MPLA0 */
3205 ldsr r0, 1, 6 ;/* MPUA0 */
3206$endif ;/* __v850e2v3__ */
3207
3208 ;/*
3209 ;* PSW.IDを戻す
3210 ;*/
3211 mov 0x20, r11
3212 tst r10, r11
3213 bnz cancel_nontrusted_hook_r
3214
3215 UNLOCK_ALL_INT
3216
3217cancel_nontrusted_hook_r:
3218 jmp [lp]
3219
3220 shared.text .cseg text
3221 .public _exit_nontrusted_hook_trap
3222_exit_nontrusted_hook_trap:
3223 syscall NO_HOOK_RET
3224 nop
3225 ;/* =end modified for SC3 */
Note: See TracBrowser for help on using the repository browser.