1;----------------------------------------------------------------------------- 2; This file contains the startup code used by the V850 C/C++ compiler. 3; 4; Copyright (c) 1998-2009 IAR Systems AB. 5; 6; $Revision: 5028 $ 7; 8;----------------------------------------------------------------------------- 9 10; 11; Naming covention of labels in this file: 12; 13; ?xxx - External labels only accessed from assembler. 14; __xxx - External labels accessed from or defined in C. 15; xxx - Labels local to one module (note: this file contains 16; several modules). 17; main - The starting point of the user program. 18; 19 20#include "lxx.h" 21#include "cfi.h" 22 23 CASEON 24 25#define A0 R1 26#define A1 R5 27#define A2 R6 28 29;---------------------------------------------------------------; 30; Call Frame Informatio ; 31;---------------------------------------------------------------; 32 33 CFNAMES 34 CFCOMMON 35 36;---------------------------------------------------------------; 37; Reset Vector ; 38;---------------------------------------------------------------; 39 40 MODULE ?RESET 41 42 PUBLIC ?creset 43 EXTERN __program_start 44 45 COMMON INTVEC:CODE:ROOT(2) 46 47?creset: 48 MOV __program_start, R1 49 JMP [R1] 50 51 ENDMOD 52 53;---------------------------------------------------------------; 54; Module start. ; 55;---------------------------------------------------------------; 56 57 MODULE __program_start 58 59 PUBLIC __program_start 60 PUBLIC ?cstartup 61 EXTERN ?creset 62 REQUIRE ?creset 63 64;---------------------------------------------------------------; 65; Forward declarations of segments used in this module. ; 66;---------------------------------------------------------------; 67 68 RSEG CODE:CODE:NOROOT(2) 69 RSEG CSTACK:DATA(2) 70 71;---------------------------------------------------------------; 72; The startup code. ; 73;---------------------------------------------------------------; 74 75 RSEG CSTART:CODE:NOROOT(1) 76 77 ;; 78 ;; The startup sequence contained in the final linked 79 ;; application will consist of a mosaic containing 80 ;; modules and segment parts defined in this file. 81 ;; 82 ;; The only part which is required is the call to 83 ;; the function "main". 84 ;; 85 86 EXTERN ?cstart_call_main 87 REQUIRE ?cstart_call_main 88 89 EXTERN __cstart_low_level_init 90 REQUIRE __cstart_low_level_init 91 92 PUBLIC ?BTT_cstart_begin 93?BTT_cstart_begin: 94 95?cstartup: 96__program_start: 97 98;---------------------------------------------------------------; 99; Set up the stack and the global pointer. ; 100;---------------------------------------------------------------; 101 102#if __CORE__ == __CORE_V850__ 103 ;; If an interrupt is issued beteween the MOVEA and 104 ;; MOVHI instructions the SP will point into 105 ;; nowhere. To fix this problem we build the new SP 106 ;; value in R1 and moves it with an atomic operation 107 ;; to SP. 108 MOVE_M SFE CSTACK, R1 109 MOV R1, SP 110#else 111 MOVE_M SFE CSTACK, SP 112#endif 113 114 EXTERN ?BREL_BASE 115 MOVE_M ?BREL_BASE + 0x8000, GP 116 117 EXTERN ?BREL_CBASE 118 MOVE_M ?BREL_CBASE + 0x8000, R25 119 120;---------------------------------------------------------------; 121; Setup constant registers. ; 122;---------------------------------------------------------------; 123 124 RSEG CSTART:CODE:NOROOT(1) 125 PUBLIC ?INIT_REG 126 127?INIT_REG: MOV 255, R18 128 ORI 65535, zero, R19 129 130 ENDMOD 131 132 133;---------------------------------------------------------------; 134; Initialize the saddr base pointers. ; 135;---------------------------------------------------------------; 136 137 MODULE ?INIT_SADDR_BASE 138 139 RTMODEL "__reg_ep", "saddr" 140 141 RSEG CSTART:CODE:NOROOT(1) 142 PUBLIC ?INIT_SADDR_BASE 143 144?INIT_SADDR_BASE: 145 EXTERN ?SADDR_BASE 146 MOVE_M ?SADDR_BASE, EP 147 148 ENDMOD 149 150 151;---------------------------------------------------------------; 152; If hardware must be initialized from C or if watch dog timer ; 153; must be handled or if the segment init should not be ; 154; performed it can now be done in `__low_level_init'. ; 155;---------------------------------------------------------------; 156; Call the user function __low_level_init, if defined. ; 157; It is the responsibility of __low_level_init to require ; 158; __cstart_low_level_init in order to be called by cstartup. ; 159;---------------------------------------------------------------; 160 161 MODULE ?CSTART_LOW_LEVEL_INIT 162 RSEG CSTART:CODE:NOROOT(1) 163 164 PUBLIC __cstart_low_level_init 165 EXTERN __low_level_init 166 REQUIRE __low_level_init 167 EXTERN ?no_seg_init 168 169__cstart_low_level_init: 170 CALL_FUNC __low_level_init, LP, R1 171 ANDI 0xFF, R1, R1 172 BZ ?no_seg_init 173 174 ENDMOD 175 176 177;---------------------------------------------------------------; 178; Segment initialization code. Copy initialized ROMmed code to ; 179; RAM and ?seg_clear uninitialized variables. ; 180;---------------------------------------------------------------; 181 182 MODULE ?INIT_MEMORY 183 184;---------------------------------------------------------------; 185; Zero out NEAR_Z ; 186;---------------------------------------------------------------; 187 PUBLIC ?INIT_NEAR_Z 188 189 RSEG NEAR_Z(2) 190 RSEG CSTART:CODE:NOROOT(1) 191 192 EXTERN ?seg_clear 193?INIT_NEAR_Z: 194 195 MOVE_M SFB NEAR_Z, A0 196 MOVE_M SFE NEAR_Z, A1 197 JARL ?seg_clear, LP 198 199 200;---------------------------------------------------------------; 201; Zero out BREL_Z ; 202;---------------------------------------------------------------; 203 PUBLIC ?INIT_BREL_Z 204 205 RSEG BREL_Z(2) 206 RSEG CSTART:CODE:NOROOT(1) 207 208 EXTERN ?seg_clear 209?INIT_BREL_Z: 210 211 MOVE_M SFB BREL_Z, A0 212 MOVE_M SFE BREL_Z, A1 213 JARL ?seg_clear, LP 214 215;---------------------------------------------------------------; 216; Zero out SADDR7_Z ; 217;---------------------------------------------------------------; 218 PUBLIC ?INIT_SADDR7_Z 219 220 RSEG SADDR7_Z(2) 221 222 RSEG CSTART:CODE:NOROOT(1) 223 224 EXTERN ?seg_clear 225?INIT_SADDR7_Z: 226 227 MOVE_M SFB SADDR7_Z, A0 228 MOVE_M SFE SADDR7_Z, A1 229 JARL ?seg_clear, LP 230 231 232;---------------------------------------------------------------; 233; Zero out SADDR8_Z ; 234;---------------------------------------------------------------; 235 PUBLIC ?INIT_SADDR8_Z 236 237 RSEG SADDR8_Z(2) 238 239 RSEG CSTART:CODE:NOROOT(1) 240 241 EXTERN ?seg_clear 242?INIT_SADDR8_Z: 243 244 MOVE_M SFB SADDR8_Z, A0 245 MOVE_M SFE SADDR8_Z, A1 246 JARL ?seg_clear, LP 247 248 249;---------------------------------------------------------------; 250; Zero out BREL23_Z ; 251;---------------------------------------------------------------; 252 253#if __CORE__ >= __CORE_V850E2M__ 254 255 PUBLIC ?INIT_BREL23_Z 256 257 RSEG BREL23_Z(2) 258 259 RSEG CSTART:CODE:NOROOT(1) 260 261 EXTERN ?seg_clear 262?INIT_BREL23_Z: 263 264 MOVE_M SFB BREL23_Z, A0 265 MOVE_M SFE BREL23_Z, A1 266 JARL ?seg_clear, LP 267#endif 268 269;---------------------------------------------------------------; 270; Zero out HUGE_Z ; 271;---------------------------------------------------------------; 272 PUBLIC ?INIT_HUGE_Z 273 274 RSEG HUGE_Z(2) 275 276 RSEG CSTART:CODE:NOROOT(1) 277 278 EXTERN ?seg_clear 279?INIT_HUGE_Z: 280 281 MOVE_M SFB HUGE_Z, A0 282 MOVE_M SFE HUGE_Z, A1 283 JARL ?seg_clear, LP 284 285;---------------------------------------------------------------; 286; Copy NEAR_ID into NEAR_I ; 287;---------------------------------------------------------------; 288 PUBLIC ?INIT_NEAR_I 289 290 RSEG NEAR_I(2) 291 RSEG NEAR_ID(2) 292 293 RSEG CSTART:CODE:NOROOT(1) 294 295 EXTERN ?seg_copy 296?INIT_NEAR_I: 297 298 MOVE_M SFB NEAR_ID, A0 299 MOVE_M SFE NEAR_ID, A1 300 MOVE_M SFB NEAR_I, A2 301 JARL ?seg_copy, LP 302 303;---------------------------------------------------------------; 304; Copy BREL_ID into BREL_I ; 305;---------------------------------------------------------------; 306 PUBLIC ?INIT_BREL_I 307 308 RSEG BREL_I(2) 309 RSEG BREL_ID(2) 310 311 RSEG CSTART:CODE:NOROOT(1) 312 313 EXTERN ?seg_copy 314?INIT_BREL_I: 315 316 MOVE_M SFB BREL_ID, A0 317 MOVE_M SFE BREL_ID, A1 318 MOVE_M SFB BREL_I, A2 319 JARL ?seg_copy, LP 320 321;---------------------------------------------------------------; 322; Copy SADDR7_ID into SADDR7_I ; 323;---------------------------------------------------------------; 324 PUBLIC ?INIT_SADDR7_I 325 326 RSEG SADDR7_I(2) 327 RSEG SADDR7_ID(2) 328 329 RSEG CSTART:CODE:NOROOT(1) 330 331 EXTERN ?seg_copy 332?INIT_SADDR7_I: 333 334 MOVE_M SFB SADDR7_ID, A0 335 MOVE_M SFE SADDR7_ID, A1 336 MOVE_M SFB SADDR7_I, A2 337 JARL ?seg_copy, LP 338 339;---------------------------------------------------------------; 340; Copy SADDR8_ID into SADDR8_I ; 341;---------------------------------------------------------------; 342 PUBLIC ?INIT_SADDR8_I 343 344 RSEG SADDR8_I(2) 345 RSEG SADDR8_ID(2) 346 347 RSEG CSTART:CODE:NOROOT(1) 348 349 EXTERN ?seg_copy 350?INIT_SADDR8_I: 351 352 MOVE_M SFB SADDR8_ID, A0 353 MOVE_M SFE SADDR8_ID, A1 354 MOVE_M SFB SADDR8_I, A2 355 JARL ?seg_copy, LP 356 357;---------------------------------------------------------------; 358; Copy BREL23_ID into BREL23_I ; 359;---------------------------------------------------------------; 360 361#if __CORE__ >= __CORE_V850E2M__ 362 363 PUBLIC ?INIT_BREL23_I 364 365 RSEG BREL23_I(1) 366 RSEG BREL23_ID(1) 367 368 RSEG CSTART:CODE:NOROOT(1) 369 370 EXTERN ?seg_copy 371 372?INIT_BREL23_I: 373 374 MOVE_M SFB BREL23_ID, A0 375 MOVE_M SFE BREL23_ID, A1 376 MOVE_M SFB BREL23_I, A2 377 JARL ?seg_copy, LP 378 379#endif 380 381;---------------------------------------------------------------; 382; Copy HUGE_ID into HUGE_I ; 383;---------------------------------------------------------------; 384 PUBLIC ?INIT_HUGE_I 385 386 RSEG HUGE_I(1) 387 RSEG HUGE_ID(1) 388 389 RSEG CSTART:CODE:NOROOT(1) 390 391 EXTERN ?seg_copy 392 393?INIT_HUGE_I: 394 395 MOVE_M SFB HUGE_ID, A0 396 MOVE_M SFE HUGE_ID, A1 397 MOVE_M SFB HUGE_I, A2 398 JARL ?seg_copy, LP 399 400 401;---------------------------------------------------------------; 402; Destination label when skipping data initialization. ; 403;---------------------------------------------------------------; 404 PUBLIC ?no_seg_init 405 406 RSEG CSTART:CODE:NOROOT(1) 407 408?no_seg_init: 409 410 ENDMOD 411 412 413;---------------------------------------------------------------; 414; Calculate code distance (PIC only). ; 415;---------------------------------------------------------------; 416 417 MODULE ?INIT_PIC 418 PUBLIC ?INIT_PIC 419 420 RSEG CSTART:CODE:NOROOT(1) 421 422 RTMODEL "__code_model", "pic" 423 424 EXTERN ?CODE_DISTANCE 425 EXTERN_LS_M 426 427?INIT_PIC: 428 JARL ref_point, A1 429ref_point: MOVE_M ref_point, A2 430 SUB A2, A1 431 ;; Expands to correct store instruction/sequence. 432 STORE_M A1, ?CODE_DISTANCE, A2 433 ;; Note: A1 (the value of ?CODE_DISTANCE) is used below! 434 435 ENDMOD 436 437 438#if __CORE__ >= __CORE_V850E2M__ 439 440;---------------------------------------------------------------; 441; Initialize the BSEL system register bank selector. ; 442;---------------------------------------------------------------; 443 444 MODULE ?INIT_BSEL 445 RSEG CSTART:CODE:NOROOT(1) 446 PUBLIC ?INIT_BSEL 447 448?INIT_BSEL: 449 LDSR R0, 31 ; BSEL 450 451 ENDMOD 452 453#endif 454 455 456#if __CORE__ >= __CORE_V850E__ 457 458;---------------------------------------------------------------; 459; Initialize the CALLT base pointers. ; 460;---------------------------------------------------------------; 461 462 463 MODULE ?INIT_CALLT 464 PUBLIC ?INIT_CALLT 465 EXTERN ?CALLT_BASE 466 COMMON CLTVEC(2) 467 RSEG CSTART:CODE:NOROOT(1) 468 469 RTMODEL "__cpu", "v850e" 470 471 REQUIRE ?CALLT_BASE 472 473 ;; The Call table base pointer 474?INIT_CALLT: 475 MOVE_M SFB CLTVEC, A2 476#ifdef CODE_MODEL_PIC 477 EXTERN ?CODE_DISTANCE 478 REQUIRE ?CODE_DISTANCE 479 480 ;; Add the value of ?CODE_DISTANCE calculated above 481 ADD A1, A2 482#endif 483#if __CORE__ >= __CORE_V850E2M__ 484 EXTERN ?INIT_BSEL 485 REQUIRE ?INIT_BSEL 486#endif 487 LDSR A2, 20 ; CTBP 488 489 ENDMOD 490#endif 491 492 493#if __CORE__ >= __CORE_V850E2M__ 494 495;---------------------------------------------------------------; 496; Initialize the SYSCALL base pointers. ; 497;---------------------------------------------------------------; 498 499 MODULE ?INIT_SYSCALL 500 PUBLIC ?INIT_SYSCALL 501 EXTERN ?INIT_BSEL 502 EXTERN ?SYSCALL_BASE 503 COMMON SYSCALLVEC(2) 504 505 RSEG CSTART:CODE:NOROOT(1) 506 507 REQUIRE ?INIT_BSEL 508 REQUIRE ?SYSCALL_BASE 509 510 ;; The syscall table base pointer 511?INIT_SYSCALL: 512 MOVE_M SFB SYSCALLVEC, A2 513#ifdef CODE_MODEL_PIC 514 EXTERN ?CODE_DISTANCE 515 REQUIRE ?CODE_DISTANCE 516 517 ;; Add the value of ?CODE_DISTANCE calculated above 518 ADD A1, A2 519#endif 520 LDSR A2, 12 ; SCBP 521 522 MOVE_M ((SFE SYSCALLVEC - SFB SYSCALLVEC)/4) - 1, A2 523 LDSR A2, 11 ; SCCFG 524 525 ENDMOD 526 527#endif 528 529;---------------------------------------------------------------; 530; This segment part is required by the compiler when it is ; 531; necessary to call constructors of global objects. ; 532;---------------------------------------------------------------; 533 534 MODULE ?CALL_MAIN 535 RSEG DIFUNCT(2) 536 RSEG CSTART:CODE:NOROOT(1) 537 PUBLIC ?cstart_call_ctors 538 539 EXTERN __call_ctors 540 541?cstart_call_ctors: 542 MOVE_M SFB DIFUNCT, R1 543 MOVE_M SFE DIFUNCT, R5 544 545 CALL_FUNC __call_ctors, LP, R6 546 547 548;---------------------------------------------------------------; 549; Call C main() with no parameters. ; 550;---------------------------------------------------------------; 551 552 RSEG CSTART:CODE:NOROOT(1) 553 PUBLIC ?cstart_call_main 554 555 EXTERN main 556 EXTERN exit 557 EXTERN __exit 558 559?cstart_call_main: 560 CALL_FUNC main, LP, R6 561 562;---------------------------------------------------------------; 563; If we come here we have returned from main with a 'return' ; 564; statement, not with a call to exit() or abort(). ; 565; In this case we must call exit() here for a nice ending. ; 566; Note: The return value of main() is the argument to exit(). ; 567;---------------------------------------------------------------; 568 CALL_FUNC exit, LP, R6 569 570;---------------------------------------------------------------; 571; We should never come here, but just in case. ; 572;---------------------------------------------------------------; 573 574 MOV __exit, LP 575 JMP [LP] 576 577 PUBLIC ?BTT_cstart_end 578?BTT_cstart_end: 579 580 581;---------------------------------------------------------------; 582; Copy a chunk of memory. ; 583; A0 = Start of from block ; 584; A1 = End of from block (+1) ; 585; A2 = Start of to block ; 586;---------------------------------------------------------------; 587 588 PUBLIC ?seg_copy 589 PUBLIC ?seg_clear 590 591 RSEG CSTART:CODE:NOROOT(1) 592 REQUIRE done 593 594cp_cont: LD.B 0[A0], R7 595 ADD 1, A0 596 ST.B R7, 0[A2] 597 ADD 1, A2 598 599 ;; Note: The entry point is here. 600?seg_copy: CMP A0, A1 601 BNE cp_cont 602 603 RSEG CSTART:CODE:NOROOT(1) 604 605done: JMP [LP] 606 607;---------------------------------------------------------------; 608; Clear a chunk of memory. ; 609; A0 = Start of block ; 610; A1 = End of block (+1) ; 611;---------------------------------------------------------------; 612 613 RSEG CSTART:CODE:NOROOT(1) 614 REQUIRE done 615 616?seg_clear: CMP A0, A1 617 BE done 618cl_cont: ST.B zero, 0[A0] 619 ADD 1, A0 620 BR ?seg_clear 621 622 ENDMOD 623 624 625;---------------------------------------------------------------; 626; _exit code ; 627; ; 628; Call destructors (if required), then fall through to __exit. ; 629;---------------------------------------------------------------; 630 631 MODULE ?_exit 632 PUBLIC _exit 633 PUBLIC ?BTT_exit_begin 634 EXTERN ?exit_restore2 635 RSEG RCODE:CODE:NOROOT(1) 636 637?BTT_exit_begin: 638_exit: 639 REQUIRE ?exit_restore2 640 ;; If any of the two pieces of code "__cstart_call_dtors" 641 ;; or "__cstart_closeall" is called we need to save the 642 ;; argument to "_exit". However, since we never will 643 ;; from this function we can use a permanent register 644 ;; rather than storing the value on the stack. 645 646 RSEG RCODE:CODE:NOROOT(1) 647 EXTERN ?exit_restore 648 PUBLIC ?exit_save 649?exit_save: 650 REQUIRE ?exit_restore 651 652 MOV R1, R29 653 654 RSEG RCODE:CODE:NOROOT(1) 655 PUBLIC __cstart_call_dtors 656 EXTERN __call_dtors 657 REQUIRE ?exit_save 658 659 ;; This label is required by "__record_needed_destruction". 660 661__cstart_call_dtors: 662 CALL_FUNC __call_dtors, LP, R1 663 664 ENDMOD 665 666 ;; A new module is needed so that a non-terminal-IO program 667 ;; doesn't include this, which requires __putchar. 668 669 MODULE ?__cstart_closeall 670 RSEG RCODE:CODE:NOROOT(1) 671 672 ;; When stdio is used, the following piece of code is 673 ;; required by the _Closreg macro. 674 675 PUBLIC __cstart_closeall 676 EXTERN ?exit_save 677 REQUIRE ?exit_save 678 679 ;; This label is required by _Closreg 680 681__cstart_closeall: 682 EXTERN _Close_all 683 CALL_FUNC _Close_all, LP, R1 684 685 ENDMOD 686 687 ;; Restore the argument previously stored by the "save" section 688 ;; above. 689 690 MODULE ?_exit_end 691 RSEG RCODE:CODE:NOROOT(1) 692 693 PUBLIC ?exit_restore 694 EXTERN ?exit_restore2 695 696?exit_restore: 697 REQUIRE ?exit_restore2 698 MOV R29, R1 699 700 ENDMOD 701 702 MODULE ?_exit_end2 703 PUBLIC ?BTT_exit_end 704 RSEG RCODE:CODE:NOROOT(1) 705 706 PUBLIC ?exit_restore2 707 EXTERN __exit 708?exit_restore2: 709 710 MOV __exit, LP 711 JMP [LP] 712 713?BTT_exit_end: 714 ENDMOD 715 716 717;---------------------------------------------------------------; 718; Define the base of the base relative (brel) data for RAM. ; 719; ; 720; This empty segment should be places in front of the brel ; 721; RAM data segments. ; 722;---------------------------------------------------------------; 723 724 MODULE ?BREL_BASE 725 PUBLIC ?BREL_BASE 726 727 RSEG BREL_BASE:DATA:NOROOT(2) 728 729?BREL_BASE: 730 731 ENDMOD 732 733 734;---------------------------------------------------------------; 735; Define the base of the base relative (brel) data for ROM. ; 736; ; 737; This empty segment should be places in front of the brel ; 738; ROM data segment. ; 739;---------------------------------------------------------------; 740 741 MODULE ?BREL_CBASE 742 PUBLIC ?BREL_CBASE 743 744 RSEG BREL_CBASE:CONST:NOROOT(2) 745 746?BREL_CBASE: 747 748 ENDMOD 749 750 751;---------------------------------------------------------------; 752; Define the base of the short addressing (saddr) data. ; 753; ; 754; This empty segment should be places in front of the saddr ; 755; data segments. ; 756;---------------------------------------------------------------; 757 758 MODULE ?SADDR_BASE 759 760 RTMODEL "__reg_ep", "saddr" 761 762 PUBLIC ?SADDR_BASE 763 RSEG SADDR_BASE:CONST:NOROOT(2) 764 765 EXTERN ?INIT_SADDR_BASE 766 REQUIRE ?INIT_SADDR_BASE 767 768?SADDR_BASE: 769 770 ENDMOD 771 772 773;---------------------------------------------------------------; 774; The base of the CALLT vector. ; 775;---------------------------------------------------------------; 776 777 MODULE ?CALLT_BASE 778 779 PUBLIC ?CALLT_BASE 780 COMMON CLTVEC:CONST:NOROOT(2) 781 DATA 782?CALLT_BASE: 783 784 ENDMOD 785 786 787#if __CORE__ >= __CORE_V850E2M__ 788 789;---------------------------------------------------------------; 790; The base of the SYSCALL vector. ; 791;---------------------------------------------------------------; 792 793 MODULE ?SYSCALL_BASE 794 795 PUBLIC ?SYSCALL_BASE 796 COMMON SYSCALLVEC:CONST:NOROOT(2) 797 DATA 798?SYSCALL_BASE: 799 800 ENDMOD 801 802#endif 803 804;---------------------------------------------------------------; 805; The distance the code has been moved when using position ; 806; independent code. ; 807;---------------------------------------------------------------; 808 809 MODULE ?CODE_DISTANCE 810 811 RTMODEL "__code_model", "pic" 812 813 PUBLIC ?CODE_DISTANCE 814 RSEG LIBRARY_N:DATA:NOROOT(2) 815 816 EXTERN ?INIT_PIC 817 REQUIRE ?INIT_PIC 818 819?CODE_DISTANCE: 820 DS 4 821 822 ENDMOD 823 824 825;---------------------------------------------------------------; 826; A dummy "low level init" that will be used if the user ; 827; hasn't defined this function. ; 828;---------------------------------------------------------------; 829 830 MODULE ?__low_level_init_stub 831 PUBLIC __low_level_init 832 RSEG RCODE:CODE:NOROOT 833__low_level_init: 834 MOV 1, R1 835 JMP [LP] 836 837 ENDMOD 838 839 END 840