- Timestamp:
- Jul 3, 2020, 7:19:17 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/asp3_dcre/arch/arm_gcc/common/core_support.S
r331 r429 6 6 * Copyright (C) 2000-2004 by Embedded and Real-Time Systems Laboratory 7 7 * Toyohashi Univ. of Technology, JAPAN 8 * Copyright (C) 2006-201 7by Embedded and Real-Time Systems Laboratory8 * Copyright (C) 2006-2019 by Embedded and Real-Time Systems Laboratory 9 9 * Graduate School of Information Science, Nagoya Univ., JAPAN 10 10 * … … 55 55 56 56 /* 57 * 使用する命令セットの定義 58 */ 59 #ifdef USE_ARM_FPU 60 .fpu vfpv3 61 #endif /* USE_ARM_FPU */ 62 63 /* 57 64 * 例外ベクタ 58 65 */ … … 101 108 * マスク全解除状態・ディスパッチ許可状態で呼び出される. 102 109 */ 103 push {r12,lr} /* 戻り番地を保存,r12はダミー */ 110 push {r12,lr} /* 戻り番地(lr)を保存 */ 111 /* r12はアラインメントのため */ 104 112 #ifdef TOPPERS_SUPPORT_OVRHDR 105 113 bl ovrtimer_stop 106 114 #endif /* TOPPERS_SUPPORT_OVRHDR */ 107 stmfd sp!, {r4-r11}/* 非スクラッチレジスタの保存 */115 push {r4-r11} /* 非スクラッチレジスタの保存 */ 108 116 ldr r0, =p_runtsk /* p_runtsk → r0 */ 109 117 ldr r0, [r0] 118 #ifdef USE_ARM_FPU 119 ldr r2, [r0,#TCB_p_tinib] /* p_runtsk->p_tinib → r2 */ 120 ldr r1, [r2,#TINIB_tskatr] /* p_runtsk->p_tinib->tskatr → r1 */ 121 tst r1, #TA_FPU 122 beq 1f 123 vpush {d8-d15} /* 非スクラッチFPUレジスタの保存 */ 124 1: 125 #endif /* USE_ARM_FPU */ 110 126 str sp, [r0,#TCB_sp] /* スタックポインタを保存 */ 111 127 adr r1, dispatch_r … … 114 130 115 131 ALABEL(dispatch_r) 116 ldmfd sp!, {r4-r11} /* 非スクラッチレジスタの復帰 */ 132 /* 133 * 【この時点のレジスタ状態】 134 * r4:p_runtsk(タスク切換え後) 135 */ 136 #ifdef USE_ARM_FPU 137 ldr r2, [r4,#TCB_p_tinib] /* p_runtsk->p_tinib → r2 */ 138 ldr r1, [r2,#TINIB_tskatr] /* p_runtsk->p_tinib->tskatr → r1 */ 139 tst r1, #TA_FPU 140 vmrs r0, fpexc 141 biceq r0, r0, #FPEXC_ENABLE 142 orrne r0, r0, #FPEXC_ENABLE 143 vmsr fpexc, r0 /* FPEXCを設定 */ 144 beq 1f 145 vpop {d8-d15} /* 非スクラッチFPUレジスタの復帰 */ 146 1: 147 #endif /* USE_ARM_FPU */ 148 pop {r4-r11} /* 非スクラッチレジスタの復帰 */ 117 149 #ifdef TOPPERS_SUPPORT_OVRHDR 118 150 bl ovrtimer_start … … 137 169 138 170 /* 171 * 各種のデバイス(特に割込みコントローラ)の設定が完了するのを待つ. 172 */ 173 asm_data_sync_barrier r0 174 175 /* 139 176 * タスクコンテキストに切り換える. 140 177 */ … … 184 221 bl log_dsp_enter 185 222 #endif /* LOG_DSP_ENTER */ 186 223 187 224 ALABEL(dispatcher_0) 188 225 /* … … 232 269 ALABEL(call_exit_kernel) 233 270 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_INTLOCK) 234 ldr r0, =istkpt /* 非タスクコンテキスト のスタックへ*/271 ldr r0, =istkpt /* 非タスクコンテキスト用のスタックに */ 235 272 ldr sp, [r0] 273 ldr r0, =excpt_nest_count /* 例外ネストカウントを1に */ 274 mov r1, #1 275 str r1, [r0] 236 276 b exit_kernel 237 277 … … 243 283 AGLOBAL(start_r) 244 284 /* 245 * ディスパッチャ本体から呼び出されるため,p_runtskはr4に入っている. 285 * 【この時点のレジスタ状態】 286 * r4:p_runtsk(タスク切換え後) 246 287 */ 247 288 ALABEL(start_r) … … 253 294 ldr lr, =ext_tsk /* タスク本体からの戻り番地を設定 */ 254 295 ldr r2, [r4,#TCB_p_tinib] /* p_runtsk->p_tinib → r2 */ 296 #ifdef USE_ARM_FPU 297 ldr r1, [r2,#TINIB_tskatr] /* p_runtsk->p_tinib->tskatr → r1 */ 298 tst r1, #TA_FPU 299 vmrs r0, fpexc 300 biceq r0, r0, #FPEXC_ENABLE 301 orrne r0, r0, #FPEXC_ENABLE 302 vmsr fpexc, r0 /* FPEXCを設定 */ 303 #endif /* USE_ARM_FPU */ 255 304 ldr r0, [r2,#TINIB_exinf] /* exinfをパラメータに */ 256 305 ldr r1, [r2,#TINIB_task] /* タスク起動番地にジャンプ */ … … 270 319 #if __TARGET_ARCH_ARM < 6 271 320 /* 272 * スーパバイザモードに切り換え,スクラッチレジスタ を保存する.321 * スーパバイザモードに切り換え,スクラッチレジスタ+αを保存する. 273 322 */ 274 323 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_IRQ_BIT) 275 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */ 276 277 /* 278 * IRQモードに戻して,戻り番地とspsr(戻り先のcpsr)を取得する. 324 push {r0-r5,r12,lr,pc} /* pcはスペース確保のため */ 325 326 /* 327 * IRQモードに戻して,戻り番地(lr-4)と戻り先のcpsr(spsr)を取 328 * 得する. 279 329 */ 280 330 msr cpsr_c, #(CPSR_IRQ_MODE AOR CPSR_IRQ_BIT) … … 283 333 284 334 /* 285 * スーパバイザモードに切り換え,戻り番地と spsrを保存する.335 * スーパバイザモードに切り換え,戻り番地と戻り先のcpsrを保存する. 286 336 */ 287 337 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_IRQ_BIT) 288 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 289 push {r1} /* spsrをスタックに保存 */338 str r2, [sp,#0x20] /* 戻り番地をスタックに保存(pcの場所)*/ 339 push {r1} /* 戻り先のcpsrをスタックに保存 */ 290 340 #else /* __TARGET_ARCH_ARM < 6 */ 291 341 /* 292 * 戻り 先(lr)とspsr(cpsr_svc)をスーパバイザモードのスタックに293 * 保存する.342 * 戻り番地(lr)と戻り先のcpsr(spsr)をスーパバイザモードのスタッ 343 * クに保存する. 294 344 */ 295 345 sub lr, lr, #4 /* 戻り番地の算出 */ … … 297 347 298 348 /* 299 * スーパバイザモードに切り換え,スクラッチレジスタ を保存する.349 * スーパバイザモードに切り換え,スクラッチレジスタ+αを保存する. 300 350 */ 301 351 cps #CPSR_SVC_MODE 302 stmfd sp!,{r0-r5,r12,lr}352 push {r0-r5,r12,lr} 303 353 #endif /* __TARGET_ARCH_ARM < 6 */ 304 354 … … 308 358 and r1, sp, #4 309 359 sub sp, sp, r1 310 push {r0,r1} /* r0はスペース確保のため*/311 360 push {r0,r1} /* スタックポインタの調整値を保存 */ 361 /* r0はスペース確保のため */ 312 362 /* 313 363 * 例外ネストカウントをインクリメントする.割込みが非タスクコンテキ … … 328 378 #endif /* TOPPERS_SUPPORT_OVRHDR */ 329 379 380 #ifdef USE_ARM_FPU 381 /* 382 * FPUをディスエーブルする. 383 */ 384 vmrs r0, fpexc 385 str r0, [sp] /* FPEXCを保存(r0の場所)*/ 386 bic r0, r0, #FPEXC_ENABLE 387 vmsr fpexc, r0 /* FPEXCを設定 */ 388 #endif /* USE_ARM_FPU */ 389 330 390 /* 331 391 * 非タスクコンテキスト用のスタックに切り換える. … … 339 399 /* 340 400 * 割込みコントローラを操作し,割込み番号を取得する. 401 * 402 * irc_begin_intは,スタックトップ(r0の場所)に,irc_end_intで用 403 * いる情報を保存する. 341 404 */ 342 405 bl irc_begin_int … … 345 408 #else /* TNUM_INHNO <= 256 || __TARGET_ARCH_ARM <= 6 */ 346 409 movw r3, #TNUM_INHNO 347 cmp r4, r3 410 cmp r4, r3 348 411 #endif /* TNUM_INHNO <= 256 || __TARGET_ARCH_ARM <= 6 */ 349 412 bhs irq_handler_2 /* スプリアス割込みなら */ … … 420 483 mov sp, r3 421 484 485 #ifdef USE_ARM_FPU 486 /* 487 * FPUを元に戻す. 488 */ 489 ldr r0, [sp] /* FPEXCを復帰 */ 490 vmsr fpexc, r0 491 #endif /* USE_ARM_FPU */ 492 422 493 /* 423 494 * p_runtskがNULLか判定する. … … 433 504 pop {r0,r1} /* スタックポインタの調整を元に戻す */ 434 505 add sp, sp, r1 435 add sp, sp, #40 /* スクラッチレジスタ を捨てる */506 add sp, sp, #40 /* スクラッチレジスタ等を捨てる */ 436 507 b dispatcher_0 437 508 … … 440 511 */ 441 512 ALABEL(irq_handler_3) 513 /* 514 * 【この時点のレジスタ状態】 515 * r0:p_runtsk 516 */ 442 517 ldr r1, =p_schedtsk /* p_schedtsk → r1 */ 443 518 ldr r1, [r1] … … 448 523 * コンテキストを保存する. 449 524 */ 450 stmfd sp!, {r6-r11} /* 非スクラッチレジスタの保存 */ 525 push {r6-r11} /* 残りのレジスタの保存 */ 526 #ifdef USE_ARM_FPU 527 ldr r2, [r0,#TCB_p_tinib] /* p_runtsk->p_tinib → r2 */ 528 ldr r1, [r2,#TINIB_tskatr] /* p_runtsk->p_tinib->tskatr → r1 */ 529 tst r1, #TA_FPU 530 beq 1f /* TA_FPU属性でない場合は分岐 */ 531 #ifdef USE_ARM_FPU_D32 532 vpush {d16-d31} 533 #endif /* USE_ARM_FPU_D32 */ 534 vpush {d0-d15} /* 全FPUレジスタの保存 */ 535 vmrs r1, fpscr 536 push {r1,r2} /* FPSCRの保存 */ 537 1: /* r2はアラインメントのため */ 538 #endif /* USE_ARM_FPU */ 451 539 str sp, [r0,#TCB_sp] /* スタックポインタを保存 */ 452 540 adr r1, ret_int_r /* 実行再開番地を保存 */ … … 457 545 /* 458 546 * コンテキストを復帰する. 459 */ 460 ldmfd sp!, {r6-r11} /* 非スクラッチレジスタの復帰 */ 547 * 548 * 【この時点のレジスタ状態】 549 * r4:p_runtsk(タスク切換え後) 550 */ 551 #ifdef USE_ARM_FPU 552 ldr r2, [r4,#TCB_p_tinib] /* p_runtsk->p_tinib → r2 */ 553 ldr r1, [r2,#TINIB_tskatr] /* p_runtsk->p_tinib->tskatr → r1 */ 554 tst r1, #TA_FPU 555 vmrs r0, fpexc 556 biceq r0, r0, #FPEXC_ENABLE 557 orrne r0, r0, #FPEXC_ENABLE 558 vmsr fpexc, r0 /* FPEXCを設定 */ 559 beq 1f /* TA_FPU属性でない場合は分岐 */ 560 pop {r1,r2} /* FPSCRの復帰 */ 561 vmsr fpscr, r1 562 vpop {d0-d15} /* 全FPUレジスタの復帰 */ 563 #ifdef USE_ARM_FPU_D32 564 vpop {d16-d31} 565 #endif /* USE_ARM_FPU_D32 */ 566 1: 567 #endif /* USE_ARM_FPU */ 568 pop {r6-r11} /* 残りのレジスタの復帰 */ 461 569 462 570 ALABEL(irq_handler_4) … … 469 577 470 578 /* 471 * 割込み /CPU例外処理からのリターン579 * 割込み処理からのリターン 472 580 * 473 * 割込み /CPU例外処理からのリターンにより,CPUロック解除状態に遷474 * 移するようにする必要があるが,ARMはCPSRのビットによってCPUロッ475 * ク状態を表しているため,CPSRを元に戻してリターンすればよい.581 * 割込み処理からのリターンにより,CPUロック解除状態に遷移するよ 582 * うにする必要があるが,ARMはCPSRのビットによってCPUロック状態を 583 * 表しているため,CPSRを元に戻してリターンすればよい. 476 584 */ 477 585 ALABEL(irq_handler_5) … … 480 588 481 589 #if __TARGET_ARCH_ARM < 6 482 ldmfd sp!, {r0}/* 戻り先のcpsrをspsrに設定 */590 pop {r0} /* 戻り先のcpsrをspsrに設定 */ 483 591 msr spsr_cxsf, r0 484 592 ldmfd sp!, {r0-r5,r12,lr,pc}^ /* コンテキストの復帰 */ 485 593 /* ^付きなので,spsr → cpsr */ 486 594 #else /* __TARGET_ARCH_ARM < 6 */ 487 ldmfd sp!, {r0-r5,r12,lr}595 pop {r0-r5,r12,lr} /* スクラッチレジスタ+αの復帰 */ 488 596 rfefd sp! 489 597 #endif /* __TARGET_ARCH_ARM < 6 */ … … 509 617 /* 510 618 * IビットとFビットをセットし,スーパバイザモードに切り換え,スク 511 * ラッチレジスタ を保存する.619 * ラッチレジスタ+αを保存する. 512 620 */ 513 621 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT) 514 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */ 515 516 /* 517 * 未定義モードに戻して,戻り番地とspsrを取得する. 622 push {r0-r5,r12,lr,pc} /* pcはスペース確保のため */ 623 624 /* 625 * 未定義モードに戻して,戻り番地(lr)と戻り先のcpsr(spsr)を取 626 * 得する. 518 627 */ 519 628 msr cpsr_c, #(CPSR_UND_MODE AOR CPSR_FIQ_IRQ_BIT) … … 522 631 523 632 /* 524 * スーパバイザモードに切り換え,戻り番地と spsrを保存する.633 * スーパバイザモードに切り換え,戻り番地と戻り先のcpsrを保存する. 525 634 */ 526 635 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT) 527 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 528 push {r1} /* spsrをスタックに保存 */636 str r2, [sp,#0x20] /* 戻り番地をスタックに保存(pcの場所)*/ 637 push {r1} /* 戻り先のcpsrをスタックに保存 */ 529 638 #else /* __TARGET_ARCH_ARM < 6 */ 530 639 /* 531 * 戻り 先(lr)とspsr(cpsr_svc)をスーパバイザモードのスタックに532 * 保存する.640 * 戻り番地(lr)と戻り先のcpsr(spsr)をスーパバイザモードのスタッ 641 * クに保存する. 533 642 */ 534 643 srsfd #CPSR_SVC_MODE! 535 644 536 645 /* 537 * スーパバイザモードに切り換え,スクラッチレジスタ を保存する.646 * スーパバイザモードに切り換え,スクラッチレジスタ+αを保存する. 538 647 */ 539 648 cps #CPSR_SVC_MODE 540 stmfd sp!,{r0-r5,r12,lr}649 push {r0-r5,r12,lr} 541 650 #endif /* __TARGET_ARCH_ARM < 6 */ 542 651 mov r4, #EXCNO_UNDEF … … 558 667 #if __TARGET_ARCH_ARM < 6 559 668 /* 560 * IビットとFビットをセットし,スクラッチレジスタを保存する. 669 * IビットとFビットをセットし,戻り番地(lr),スクラッチレジスタ 670 * +α,戻り先のcpsr(spsr)を保存する(lrは二重に保存される). 561 671 */ 562 672 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT) 563 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */ 564 565 /* 566 * 戻り番地とspsrを取得する. 567 */ 568 mov r2, lr 673 push {lr} 674 push {r0-r5,r12,lr} 569 675 mrs r1, spsr 570 571 /* 572 * 戻り番地とspsrを保存する. 573 */ 574 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 */ 575 push {r1} /* spsrをスタックに保存 */ 676 push {r1} 576 677 #else /* __TARGET_ARCH_ARM < 6 */ 577 678 /* 578 * 戻り 先(lr)とspsr(cpsr_svc)をスーパバイザモードのスタックに579 * 保存する.679 * 戻り番地(lr)と戻り先のcpsr(spsr)をスーパバイザモードのスタッ 680 * クに保存する. 580 681 */ 581 682 srsfd #CPSR_SVC_MODE! 582 683 583 684 /* 584 * スーパバイザモードで,スクラッチレジスタを保存する. 585 */ 586 cps #CPSR_SVC_MODE /* 不要と思われる */ 587 stmfd sp!, {r0-r5,r12,lr} 685 * スーパバイザモードで,スクラッチレジスタ+αを保存する. 686 */ 687 push {r0-r5,r12,lr} 588 688 #endif /* __TARGET_ARCH_ARM < 6 */ 589 689 mov r4, #EXCNO_SVC … … 605 705 /* 606 706 * IビットとFビットをセットし,スーパバイザモードに切り換え,スク 607 * ラッチレジスタ を保存する.707 * ラッチレジスタ+αを保存する. 608 708 */ 609 709 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT) 610 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */ 611 612 /* 613 * アボートモードに戻して,戻り番地とspsrを取得する. 710 push {r0-r5,r12,lr,pc} /* pcはスペース確保のため */ 711 712 /* 713 * アボートモードに戻して,戻り番地(lr)と戻り先のcpsr(spsr)を 714 * 取得する. 614 715 */ 615 716 msr cpsr_c, #(CPSR_ABT_MODE AOR CPSR_FIQ_IRQ_BIT) … … 618 719 619 720 /* 620 * スーパバイザモードに切り換え,戻り番地と spsrを保存する.721 * スーパバイザモードに切り換え,戻り番地と戻り先のcpsrを保存する. 621 722 */ 622 723 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT) 623 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 624 push {r1} /* spsrをスタックに保存 */724 str r2, [sp,#0x20] /* 戻り番地をスタックに保存(pcの場所)*/ 725 push {r1} /* 戻り先のcpsrをスタックに保存 */ 625 726 #else /* __TARGET_ARCH_ARM < 6 */ 626 727 /* 627 * 戻り 先(lr)とspsr(cpsr_svc)をスーパバイザモードのスタックに628 * 保存する.728 * 戻り番地(lr)と戻り先のcpsr(spsr)をスーパバイザモードのスタッ 729 * クに保存する. 629 730 */ 630 731 srsfd #CPSR_SVC_MODE! 631 732 632 733 /* 633 * スーパバイザモードに切り換え,スクラッチレジスタ を保存する.734 * スーパバイザモードに切り換え,スクラッチレジスタ+αを保存する. 634 735 */ 635 736 cps #CPSR_SVC_MODE 636 stmfd sp!,{r0-r5,r12,lr}737 push {r0-r5,r12,lr} 637 738 #endif /* __TARGET_ARCH_ARM < 6 */ 638 739 mov r4, #EXCNO_PABORT … … 653 754 * データアボートが,CPU例外の入口(start_exc_entryとend_exc_entry 654 755 * の間)で発生した場合には,fatal_dabort_handlerに分岐する.アボー 655 * トモードのspを汎用レジスタの代わりに使用する .656 */ 657 ldr sp, =start_exc_entry+8658 cmp lr, sp756 * トモードのspを汎用レジスタの代わりに使用する(r13と記述している). 757 */ 758 adr r13, start_exc_entry+8 759 cmp lr, r13 659 760 bcc dabort_handler_1 660 ldr sp, =end_exc_entry+8661 cmp lr, sp761 adr r13, end_exc_entry+8 762 cmp lr, r13 662 763 bcc fatal_dabort_handler 663 764 … … 666 767 /* 667 768 * IビットとFビットをセットし,スーパバイザモードに切り換え,スク 668 * ラッチレジスタ を保存する.769 * ラッチレジスタ+αを保存する. 669 770 */ 670 771 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT) 671 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */ 672 673 /* 674 * アボートモードに戻して,戻り番地とspsrを取得する. 772 push {r0-r5,r12,lr,pc} /* pcはスペース確保のため */ 773 774 /* 775 * アボートモードに戻して,戻り番地(lr)と戻り先のcpsr(spsr)を 776 * 取得する. 675 777 */ 676 778 msr cpsr_c, #(CPSR_ABT_MODE AOR CPSR_FIQ_IRQ_BIT) … … 679 781 680 782 /* 681 * スーパバイザモードに切り換え,戻り番地と spsrを保存する.783 * スーパバイザモードに切り換え,戻り番地と戻り先のcpsrを保存する. 682 784 */ 683 785 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT) 684 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 685 push {r1} /* spsrをスタックに保存 */786 str r2, [sp,#0x20] /* 戻り番地をスタックに保存(pcの場所)*/ 787 push {r1} /* 戻り先のcpsrをスタックに保存 */ 686 788 #else /* __TARGET_ARCH_ARM < 6 */ 687 789 /* 688 * 戻り 先(lr)とspsr(cpsr_svc)をスーパバイザモードのスタックに689 * 保存する.790 * 戻り番地(lr)と戻り先のcpsr(spsr)をスーパバイザモードのスタッ 791 * クに保存する. 690 792 */ 691 793 srsfd #CPSR_SVC_MODE! 692 794 693 795 /* 694 * スーパバイザモードに切り換え,スクラッチレジスタ を保存する.796 * スーパバイザモードに切り換え,スクラッチレジスタ+αを保存する. 695 797 */ 696 798 cps #CPSR_SVC_MODE 697 stmfd sp!,{r0-r5,r12,lr}799 push {r0-r5,r12,lr} 698 800 #endif /* __TARGET_ARCH_ARM < 6 */ 699 801 mov r4, #EXCNO_DABORT 700 802 b exc_handler_1 701 #endif /* OMIT_DABORT_HANDLER */702 803 703 804 /* … … 708 809 /* 709 810 * IビットとFビットをセットし,スーパバイザモードに切り換え,スタッ 710 * クポインタを初期化し,スクラッチレジスタ を保存する.811 * クポインタを初期化し,スクラッチレジスタ+αを保存する. 711 812 */ 712 813 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT) 713 814 ldr sp, =istkpt 714 815 ldr sp, [sp] 715 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */ 716 717 /* 718 * アボートモードに戻して,戻り番地とspsrを取得する. 816 push {r0-r5,r12,lr,pc} /* pcはスペース確保のため */ 817 818 /* 819 * アボートモードに戻して,戻り番地(lr)と戻り先のcpsr(spsr)を 820 * 取得する. 719 821 */ 720 822 msr cpsr_c, #(CPSR_ABT_MODE AOR CPSR_FIQ_IRQ_BIT) … … 723 825 724 826 /* 725 * スーパバイザモードに切り換え,戻り番地と spsrを保存する.827 * スーパバイザモードに切り換え,戻り番地と戻り先のcpsrを保存する. 726 828 */ 727 829 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT) 728 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 729 push {r1} /* spsrをスタックに保存 */830 str r2, [sp,#0x20] /* 戻り番地をスタックに保存(pcの場所)*/ 831 push {r1} /* 戻り先のcpsrをスタックに保存 */ 730 832 #else /* __TARGET_ARCH_ARM < 6 */ 731 833 /* … … 738 840 739 841 /* 740 * アボートモードに戻して,戻り 先(lr)とspsr(cpsr_svc)をスーパ741 * バイザモードのスタックに保存する.842 * アボートモードに戻して,戻り番地(lr)と戻り先のcpsr(spsr)を 843 * スーパバイザモードのスタックに保存する. 742 844 */ 743 845 cps #CPSR_ABT_MODE … … 745 847 746 848 /* 747 * スーパバイザモードに切り換え,スクラッチレジスタ を保存する.849 * スーパバイザモードに切り換え,スクラッチレジスタ+αを保存する. 748 850 */ 749 851 cps #CPSR_SVC_MODE 750 stmfd sp!,{r0-r5,r12,lr}852 push {r0-r5,r12,lr} 751 853 #endif /* __TARGET_ARCH_ARM < 6 */ 752 854 753 855 /* 754 * 例外ネストカウント の最上位ビットを1にする.856 * 例外ネストカウントをインクリメントする. 755 857 */ 756 858 ldr r2, =excpt_nest_count 757 859 ldr r3, [r2] 758 orr r3, r3, #0x80000000860 add r3, r3, #1 759 861 str r3, [r2] 760 862 761 mov r4, #EXCNO_ DABORT863 mov r4, #EXCNO_FATAL 762 864 b exc_handler_1 865 #endif /* OMIT_DABORT_HANDLER */ 763 866 764 867 /* … … 776 879 /* 777 880 * IビットとFビットをセットし,スーパバイザモードに切り換え,スク 778 * ラッチレジスタ を保存する.881 * ラッチレジスタ+αを保存する. 779 882 */ 780 883 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT) 781 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */ 782 783 /* 784 * FIQモードに戻して,戻り番地とspsrを取得する. 884 push {r0-r5,r12,lr,pc} /* pcはスペース確保のため */ 885 886 /* 887 * FIQモードに戻して,戻り番地(lr)と戻り先のcpsr(spsr)を取得 888 * する. 785 889 */ 786 890 msr cpsr_c, #(CPSR_FIQ_MODE AOR CPSR_FIQ_IRQ_BIT) … … 789 893 790 894 /* 791 * スーパバイザモードに切り換え,戻り番地と spsrを保存する.895 * スーパバイザモードに切り換え,戻り番地と戻り先のcpsrを保存する. 792 896 */ 793 897 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT) 794 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 795 push {r1} /* spsrをスタックに保存 */898 str r2, [sp,#0x20] /* 戻り番地をスタックに保存(pcの場所)*/ 899 push {r1} /* 戻り先のcpsrをスタックに保存 */ 796 900 #else /* __TARGET_ARCH_ARM < 6 */ 797 901 /* 798 * 戻り 先(lr)とspsr(cpsr_svc)をスーパバイザモードのスタックに799 * 保存する.902 * 戻り番地(lr)と戻り先のcpsr(spsr)をスーパバイザモードのスタッ 903 * クに保存する. 800 904 */ 801 905 srsfd #CPSR_SVC_MODE! 802 906 803 907 /* 804 * スーパバイザモードに切り換え,スクラッチレジスタ を保存する.908 * スーパバイザモードに切り換え,スクラッチレジスタ+αを保存する. 805 909 */ 806 910 cps #CPSR_SVC_MODE 807 stmfd sp!,{r0-r5,r12,lr}911 push {r0-r5,r12,lr} 808 912 #endif /* __TARGET_ARCH_ARM < 6 */ 809 913 mov r4, #EXCNO_FIQ 810 914 b exc_handler_1 811 915 #endif /* OMIT_FIQ_HANDLER */ 812 916 813 917 ALABEL(end_exc_entry) 814 918 815 919 /* 816 920 * CPU例外ハンドラ出入口処理の共通部分 817 *818 * 【この時点のレジスタ状態】819 * r4:CPU例外ハンドラ番号820 921 */ 821 922 ALABEL(exc_handler_1) 822 923 /* 924 * 【この時点のレジスタ状態】 925 * r4:CPU例外ハンドラ番号 926 * 823 927 * CPU例外が発生した状況の判断に用いるために,CPU例外発生前の割 824 928 * 込み優先度マスクと例外ネストカウントをスタックに保存する. … … 836 940 and r1, sp, #4 837 941 sub sp, sp, r1 838 push {r0,r1} /* r0はスペース確保のため*/839 942 push {r0,r1} /* スタックポインタの調整値を保存 */ 943 /* r0はスペース確保のため */ 840 944 /* 841 945 * カーネル管理外のCPU例外か判定する … … 873 977 #endif /* TOPPERS_SUPPORT_OVRHDR */ 874 978 979 #ifdef USE_ARM_FPU 980 /* 981 * FPUをディスエーブルする. 982 */ 983 vmrs r0, fpexc 984 str r0, [sp] /* FPEXCを保存(r0の場所)*/ 985 bic r0, r0, #FPEXC_ENABLE 986 vmsr fpexc, r0 /* FPEXCを設定 */ 987 #endif /* USE_ARM_FPU */ 988 875 989 /* 876 990 * 非タスクコンテキスト用のスタックに切り換える. … … 890 1004 /* 891 1005 * (必要なら)割込みコントローラを操作する. 1006 * 1007 * irc_begin_excは,スタックトップ(r0の場所)に,irc_end_excで用 1008 * いる情報を保存する. 892 1009 */ 893 1010 bl irc_begin_exc … … 970 1087 mov sp, r3 971 1088 1089 #ifdef USE_ARM_FPU 1090 /* 1091 * FPUを元に戻す. 1092 */ 1093 ldr r0, [sp] /* FPEXCを復帰 */ 1094 vmsr fpexc, r0 1095 #endif /* USE_ARM_FPU */ 1096 972 1097 /* 973 1098 * p_runtskがNULLか判定する. … … 990 1115 */ 991 1116 ALABEL(exc_handler_3) 1117 /* 1118 * 【この時点のレジスタ状態】 1119 * r0:p_runtsk 1120 */ 992 1121 ldr r1, =p_schedtsk /* p_schedtsk → r1 */ 993 1122 ldr r1, [r1] … … 998 1127 * コンテキストを保存する. 999 1128 */ 1000 stmfd sp!, {r6-r11} /* 非スクラッチレジスタの保存 */ 1129 push {r6-r11} /* 残りのレジスタの保存 */ 1130 #ifdef USE_ARM_FPU 1131 ldr r2, [r0,#TCB_p_tinib] /* p_runtsk->p_tinib → r2 */ 1132 ldr r1, [r2,#TINIB_tskatr] /* p_runtsk->p_tinib->tskatr → r1 */ 1133 tst r1, #TA_FPU 1134 beq 1f /* TA_FPU属性でない場合は分岐 */ 1135 #ifdef USE_ARM_FPU_D32 1136 vpush {d16-d31} 1137 #endif /* USE_ARM_FPU_D32 */ 1138 vpush {d0-d15} /* 全FPUレジスタの保存 */ 1139 vmrs r1, fpscr 1140 push {r1,r2} /* FPSCRの保存 */ 1141 1: /* r2はアラインメントのため */ 1142 #endif /* USE_ARM_FPU */ 1001 1143 str sp, [r0,#TCB_sp] /* スタックポインタを保存 */ 1002 1144 adr r1, ret_exc_r /* 実行再開番地を保存 */ … … 1007 1149 /* 1008 1150 * コンテキストを復帰する. 1009 */ 1010 ldmfd sp!, {r6-r11} /* 非スクラッチレジスタの復帰 */ 1151 * 1152 * 【この時点のレジスタ状態】 1153 * r4:p_runtsk(タスク切換え後) 1154 */ 1155 #ifdef USE_ARM_FPU 1156 ldr r2, [r4,#TCB_p_tinib] /* p_runtsk->p_tinib → r2 */ 1157 ldr r1, [r2,#TINIB_tskatr] /* p_runtsk->p_tinib->tskatr → r1 */ 1158 tst r1, #TA_FPU 1159 vmrs r0, fpexc 1160 biceq r0, r0, #FPEXC_ENABLE 1161 orrne r0, r0, #FPEXC_ENABLE 1162 vmsr fpexc, r0 /* FPEXCを設定 */ 1163 beq 1f /* TA_FPU属性でない場合は分岐 */ 1164 pop {r1,r2} /* FPSCRの復帰 */ 1165 vmsr fpscr, r1 1166 vpop {d0-d15} /* 全FPUレジスタの復帰 */ 1167 #ifdef USE_ARM_FPU_D32 1168 vpop {d16-d31} 1169 #endif /* USE_ARM_FPU_D32 */ 1170 1: 1171 #endif /* USE_ARM_FPU */ 1172 pop {r6-r11} /* 残りのレジスタの復帰 */ 1011 1173 1012 1174 ALABEL(exc_handler_4) … … 1031 1193 1032 1194 #if __TARGET_ARCH_ARM < 6 1033 ldmfd sp!, {r0}/* 戻り先のcpsrをspsrに設定 */1195 pop {r0} /* 戻り先のcpsrをspsrに設定 */ 1034 1196 msr spsr_cxsf, r0 1035 1197 ldmfd sp!, {r0-r5,r12,lr,pc}^ /* コンテキストの復帰 */ 1036 1198 /* ^付きなので,spsr → cpsr */ 1037 1199 #else /* __TARGET_ARCH_ARM < 6 */ 1038 ldmfd sp!, {r0-r5,r12,lr}1200 pop {r0-r5,r12,lr} /* スクラッチレジスタ+αの復帰 */ 1039 1201 rfefd sp! 1040 1202 #endif /* __TARGET_ARCH_ARM < 6 */ … … 1061 1223 bne nk_exc_handler_2 /* ならnk_exc_handler_2に分岐 */ 1062 1224 1225 #ifdef USE_ARM_FPU 1226 /* 1227 * FPUをディスエーブルする. 1228 */ 1229 vmrs r0, fpexc 1230 str r0, [sp] /* FPEXCを保存(r0の場所)*/ 1231 bic r0, r0, #FPEXC_ENABLE 1232 vmsr fpexc, r0 /* FPEXCを設定 */ 1233 #endif /* USE_ARM_FPU */ 1234 1063 1235 /* 1064 1236 * 非タスクコンテキスト用のスタックに切り換える. … … 1068 1240 ldr sp, [r2] 1069 1241 push {r0,r3} /* 切換え前のスタックポインタを保存 */ 1070 /* r0は スペース確保のため */1242 /* r0はアラインメントのため */ 1071 1243 ALABEL(nk_exc_handler_2) 1072 1244 /* … … 1101 1273 pop {r0,r3} 1102 1274 mov sp, r3 1275 1276 #ifdef USE_ARM_FPU 1277 /* 1278 * FPUを元に戻す. 1279 */ 1280 ldr r0, [sp] /* FPEXCを復帰 */ 1281 vmsr fpexc, r0 1282 #endif /* USE_ARM_FPU */ 1103 1283 b exc_handler_5 1104 1284 1105 1285 /* 1106 1286 * ステータスレジスタの操作関数 … … 1113 1293 ATEXT 1114 1294 AALIGN(2) 1115 AWEAK( current_cpsr)1116 ALABEL( current_cpsr)1295 AWEAK(_kernel_current_cpsr) 1296 ALABEL(_kernel_current_cpsr) 1117 1297 mrs r0, cpsr_cxsf 1118 1298 bx lr 1119 1299 1120 1300 AALIGN(2) 1121 AWEAK( set_cpsr)1122 ALABEL( set_cpsr)1301 AWEAK(_kernel_set_cpsr) 1302 ALABEL(_kernel_set_cpsr) 1123 1303 msr cpsr_cxsf, r0 1124 1304 bx lr
Note:
See TracChangeset
for help on using the changeset viewer.