8.2.2 Initialization routines of user programs

The initialization processing for the user program is configured by the following elements.

In the sample program, these elements are located in cstart.asm.

 

(1)

Stack area

The stack area is used for code generated by the compiler. The CC-RH generates code based on the assumption that the stack pointer (sp) is allocated at the 4-byte boundary and the stack area is made to be grown in the direction of address 0x0. Therefore, an address aligned at the 4-byte boundary on the 0xffffffff address side of the .stack.bss section needs to be specified for the stack pointer (sp).

STACKSIZE    .set    0x200
    .section ".stack.bss", bss
    .align   4
    .ds      (STACKSIZE)
    .align   4
_stacktop:

(2)

Entry point

The entry point is the label (address) to which the hardware initialization routine branches at a reset.

    .public __cstart_pm1
    .align  2
__cstart_pm1:

(3)

Initialization of base registers

The stack pointer, gp register, and ep register are all initialized.

    mov     #_stacktop, sp      ;  set sp register
    mov     #__gp_data, gp      ;  set gp register
    mov     #__ep_data, ep      ;  set ep register

For details on __gp_data and __ep_data, see "8.4 Symbols".

(4)

Initialization of RAM sections

Variable areas defined in the C source program or assembly source program are initialized. Prepare a table that holds the addresses of sections to be initialized and pass the address of the table to the _INITSCT_RH library function and call it.

The initialization table for initialized data sections should be written in the following format.

    .section ".INIT_DSEC.const", const
    .align   4
    .dw    #__s<section name 1>, #__e<section name 1>, 
                  #__s<name of the corresponding RAM section to be initialized>
    .dw    #__s<section name 2>, #__e<section name 2>, 
                  #__s<name of the corresponding RAM section to be initialized>
     :
    .dw    #__s<section name n>, #__e<section name n>, 
                  #__s<name of the corresponding RAM section to be initialized>

 

Use the -rom option of the optimizing linker to specify the RAM sections to be initialized.

-rom=.data=.data.R
-rom=.sdata=.sdata.R

 

In this case, code of the initialization table is as follows:

    .section ".INIT_DSEC.const", const
    .align   4
    .dw      #__s.data,  #__e.data,  #__s.data.R
    .dw      #__s.sdata, #__e.sdata, #__s.sdata.R

 

The initialization table for uninitialized data sections should be written in the following format.

    .section ".INIT_BSEC.const", const
    .align   4
    .dw      #__s<section name 1>, #__e<section name 1>
    .dw      #__s<section name 2>, #__e<section name 2>
     :
    .dw      #__s<section name n>, #__e<section name n>

 

Use the -start option of the optimizing linker to specify the addresses of ROM sections containing initial values and the corresponding RAM sections to be initialized.

-start=.data,.sdata/00008000
-start=.data.R,.sdata.R/fedf0000
-start=.bss.sbss/fedf8000

Note

Allocate sections to ROM and RAM in accord with the memory map of the target MCU. For details, refer to the user's manual for the MCU.

 

The start address and end address of the initialization table are passed through parameters of the _INITSCT_RH function and initialization is executed.

The start of each initialization table must be aligned at the 4-byte boundary.

    mov     #__s.INIT_DSEC.const, r6
    mov     #__e.INIT_DSEC.const, r7
    mov     #__s.INIT_BSEC.const, r8
    mov     #__e.INIT_BSEC.const, r9
    jarl32  __INITSCT_RH, lp	     ; initialize RAM area

For the usage method of _INITSCT_RH, see "7.4.11 RAM section initialization function".

(5)

Initial setting of FPU

Reference the PID register to confirm whether the FPU is available.

If available, make the initial settings.

Set the PSW.CU0 bit to 1 to enable usage of the FPU.

Set the FPU operating mode for the FPSR register.

The FPEPC register is initialized as a preparation to use the lockstep function.

    stsr    6, r10, 1        ; r10 <- PID
    shl     21, r10
    shr     30, r10
    bz      .L1              ; detect FPU
    stsr    5, r10, 0        ; r10 <- PSW
    movhi   0x0001, r0, r11
    or      r11, r10
    ldsr    r10, 5, 0        ; enable FPU
    movhi   0x0002, r0, r11
    ldsr    r11, 6, 0        ; initialize FPSR
    ldsr    r0, 7, 0         ; initialize FPEPC
.L1:

Delete these codes from programs that do not use the FPU.

(6)

Initial setting of exception handling

Set the PSW.ID bit to 0 to enable occurrence of exceptions.

Set the PSW.UM bit to 1 to enter the user mode.

To reflect the settings as soon as a branch to the main function occurs, write the settings to the FEPSW instead of the PSW; the FEPSW settings are reflected to the PSW when the feret instruction is executed.

    stsr    5, r10, 0        ; r10 <- PSW
    xori    0x0020, r10, r10 ; enable interrupt
    movhi   0x4000, r0, r11
    or      r11, r10         ; supervisor mode -> user mode
    ldsr    r10, 3, 0        ; FEPSW <- r10

(7)

Branch to main function

A branch to the main function occurs when the feret instruction is executed with the address of the main function set to the FEPC register and the address of the _exit function to be executed subsequent to the main function set to the r31 register.

    mov     #_exit, lp       ; lp <- #_exit
    mov     #_main, r10
    ldsr    r10, 2, 0        ; FEPC <- #_main
    feret