Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
20 years ago

Registers protecting during Context Switch

Hi, all

Basing on my study, I find that registers r1--r15 aren't protected during context switch in a uC/OS project. So that we can't use them is uC/OS. Am I right?

Thanks any help,

David

8 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    What do you mean with "protected"?

    They are "Caller Saved Registers" (see Table 3.1 in the Nios II Processor Reference Handbook), so they are not saved during the context switch, but only when interrupt arrives (see altera_nios2/HAL/src/alt_exception_entry.S)

    as a result, you can freely use these registers...

    bye

    Paolo
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    originally posted by david_cai@Dec 26 2005, 03:08 AM

    could you kindly tell me what's the meaning of 'caller saved register' in detail?

    <div align='right'><{post_snapback}> (index.php?act=findpost&pid=11780)

    --- quote end ---

    --- Quote End ---

    They are registers typically used for passing parameters and holding temporary values... they are considered "dirty" when a callee returns, so if a function can not make assumptions on their values after the return of a function call...

    bye

    Paolo
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Paolo,

    Sorry, I&#39;m confused...

    You said:

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    as a result, you can freely use these registers...[/b]

    --- Quote End ---

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    they are considered "dirty" when a callee returns[/b]

    --- Quote End ---

    In uC/os project, one of tasks is written in asm code and uses many registers(r1-r23). So during context swithc, r16-r23 will be saved in stack, but how about r1-r15. Basing on my study, r1-r15 only are protected when interrupt occur, and are not protected when context switch. I can&#39;t find any code to protect r1-r15 during context switch. So I think we can&#39;t use them is uC/OS project, am I right?

    best regards,

    David
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    originally posted by david_cai@Dec 27 2005, 03:32 AM

    in uc/os project, one of tasks is written in asm code and uses many registers(r1-r23). so during context swithc, r16-r23 will be saved in stack, but how about r1-r15. basing on my study, r1-r15 only are protected when interrupt occur, and are not protected when context switch. i can&#39;t find any code to protect r1-r15 during context switch. so i think we can&#39;t use them is uc/os project, am i right?

    <div align='right'><{post_snapback}> (index.php?act=findpost&pid=11791)

    --- quote end ---

    --- Quote End ---

    Ok, now I think I understood what you say...

    The kernel subsumes your asm code is compliant with the parameter passing convention used by the compiler.

    That is, if you -call- a primitive that may cause a context switch, then your registers r1-r15 have to be saved -before- calling the primitive, and restored -after- the call because there is no guarantee that they will have the same value after the function returns... and that thing happens with all the C functions you may call from your ASM code!!!

    bye

    Paolo
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Some extra info :

    If you write an interrupt handler, you have to save r1 - r15, not r16 - r23, because if you call in the interrupt handler a c-function to handle the specific interrupt, these are already saved for you (if they are used).

    Doing this, the execution time for the interrupt handler is reduced (less stw instructions to the stackpointer).

    Stefaan
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    If you write an interrupt handler, you have to save r1 - r15, not r16 - r23, because if you call in the interrupt handler a c-function to handle the specific interrupt, these are already saved for you (if they are used).[/b]

    --- Quote End ---

    I think it&#39;s reversed. http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/smile.gif

    If you write an interrupt handler, you have to save r16 - r23, not r1 - r15, because if you call in the interrupt handler a c-function to handle the specific interrupt, these are already saved for you.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    originally posted by david_cai@Jan 6 2006, 10:38 AM

    i think it&#39;s reversed. http://forum.niosforum.com/work2/style_emoticons/<#emo_dir#>/smile.gif

    <div align='right'><{post_snapback}> (index.php?act=findpost&pid=12002)

    --- quote end ---

    --- Quote End ---

    Do you? http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/sad.gif

    I just clarify what I mean. Maybe we talk about different handlers.

    When calling a function :

    - the function itself can freely use r2-r15 (r2 an r3 are the return value, r4 r5 r6 and r7 the arguments). These are &#39;caller saved&#39;, wich means that the caller saves the value of these registers (if necessary) before doing the call.

    - if the function uses r16 - r23 : it first has to save their current value on the stack, and when the function returns, they must be restored. Why? because the caller of the function ( = another function) relies on the values of these registers to be the same as before the call.

    Interrupt behaviour :

    - the processor jumps to the predefined interrupt vector address. (defined at fpga compile time)

    - our intention here is to call a user defined c-function. So we are sure that this function will preserve r16-r23, because it was compiled using the same compiler conventions as &#39;normal&#39; C functions (it is a normal C function).

    - so first thing to do in the interrupt code (at the processors interrupt jump address) is saving the state of the registers :

             --> r1 - r15, because we interrupt some other function that is using these as temporary register. 
             --> r16 - r23, will be saved automatically by the called user &#39;handler&#39; function (if necesary)
             --> of course we need to save some other registers like return address, ...

    - after the user specific handler function is called, we know for sure r16-r23 will have the same value as before the call, we just have to restore r1 - r15.

    Task switch behaviour : (call the task to switch from : TASk1, the task to switch to TASK2)

    - a task switch itself is always a "function". This function is called from two possible places :

             --> case 1 : another function 
             --> case 2 : an interrupt, the code at the processors interrupt jump address

    - in case 1 : we can be sure the value r1 - r15 is not needed anymore (the caller will not rely on their values anymore), but we have to preserve the state of r16-r23 for the case we switch back to TASK1

    - in case two, the interrupt code makes sure r1 - r15 is already saved on the stack of TASK1 (see above), but we have to resume the suspended function that was running in TASK1 at that moment, so r16-r23 must be saved to keep the situation consistent when after the switch back to TASK1, the function that was interrupted returns to its caller. Actually after a swith to TASK1 again, first the rest of the interrupt handler code will be executed to resore r1-r15.

    Hope this is a bit clear to read.

    Stefaan