gonzui


Format: Advanced Search

mtkernel_3/kernel/sysdepend/cpu/core/rxv2/dispatch.Sbare sourcepermlink (0.02 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    micro T-Kernel 3.00.01
    4:  *
    5:  *    Copyright (C) 2006-2020 by Ken Sakamura.
    6:  *    This software is distributed under the T-License 2.2.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by TRON Forum(http://www.tron.org) at 2020/05/29.
   10:  *
   11:  *----------------------------------------------------------------------
   12:  */
   13: 
   14: #include <sys/machine.h>
   15: #ifdef CPU_CORE_RXV2
   16: 
   17: /*
   18:  *      dispatch.S (RXv2 core)
   19:  *      Dispatcher
   20:  */
   21: 
   22: #define _in_asm_source_
   23: 
   24: #include <sys/machine.h>
   25: #include <tk/errno.h>
   26: #include <sys/sysdef.h>
   27: #include <sys/knldef.h>
   28: 
   29: #include "offset.h"
   30: 
   31:         .extern        Csym(knl_tmp_stack)
   32:         .extern        Csym(knl_dispatch_disabled)
   33:         .extern        Csym(knl_ctxtsk)
   34:         .extern        Csym(knl_schedtsk)
   35:         .extern        Csym(knl_lowpow_discnt)
   36:         .extern        Csym(low_pow)
   37: 
   38: /* ------------------------------------------------------------------------*/
   39: /*
   40:  * Dispatcher
   41:  *      dispatch_to_schedtsk:
   42:  *              Destroys the current context and forces dispatch to "schedtsk".
   43:  *                      Called directly by a jump (jmp), but does not return.
   44:  *                      Called with an undefined stack state (undefined 'ssp').
   45:  *                      Called when interrupts are disabled.
   46:  *      dispatch_entry:
   47:  *              Normal dispatch processing.
   48:  *      ret_int_dispatch:
   49:  *              Called when dispatch is required with "tk_ret_int ()".
   50:  *
   51:  *      Contexts to save
   52:  *              Saves registers other than SP to the stack. Save the SP to TCB.
   53:  *
   54:  *                 High Address     +---------------+
   55:  *                              | SPSW(32bit)     | Saved by interrupt entry
   56:  *                              | SPC(32bit)      | routines until here.
   57:  *                              +---------------+
   58:  *                              | R15             |
   59:  *                              | R14             |
   60:  *                              | R13             |
   61:  *                              |  :              |
   62:  *                              | R3              |
   63:  *                              | R2              |
   64:  *      Saved to TCB  SP =>  | R1             |-> If USE_FPU,      | R1               |-> If USE_DSP,  | R1               |
   65:  *                  Low Address     +---------------+    SP =>      | FPSW     |                  | ACC1       |
   66:  *                                                    Low Address +---------------+     SP =>          | ACC0        |
   67:  *                                                                                     Low Address +---------------+
   68:  */
   69:         .globl Csym(knl_dispatch_to_schedtsk)
   70:         .globl Csym(knl_dispatch_entry)
   71:         .globl Csym(ret_int_dispatch)
   72: 
   73:         .section .text
   74: Csym(knl_dispatch_to_schedtsk):                         // Forces dispatch entry
   75:         ; During interrupt disable (PSW.I=0)
   76:         mov.l  #(Csym(knl_tmp_stack) + TMP_STACK_SIZE), r0      // Set temporal stack
   77: 
   78:         mov.l  #Csym(knl_dispatch_disabled), r1
   79:         mov.l  #1, [r1]                         // Dispatch disable
   80: 
   81:         mov.l  #Csym(knl_ctxtsk), r7                    
   82: #if USE_DBGSPT != 0
   83:         mov.l  [r7], r2                         // r2 := ctxtsk
   84: #endif
   85:         mov.l  #0, [r7]                         // ctxtsk = NULL
   86:         mvtipl #0                                      // IPL = 0 (Lowest level)
   87:         bra    l_dispatch1
   88: 
   89: Csym(knl_dispatch_entry):                               // Normal dispatch entry
   90:         // During interrupt disable (PSW.I=0).
   91:         mvfc   psw, r1
   92:         bset   #16, r1                                   // PSW compensation (I=1)
   93:         xchg   [r0], r1
   94:         push.l r1
   95: 
   96: Csym(ret_int_dispatch):                                 // tk_ret_int() dispatch entry
   97:         // During interrupt disable (PSW.I=0).
   98:         pushm  r14-r15
   99:         mov.l  #Csym(knl_dispatch_disabled), r15
  100:         mov.l  #1, [r15]                                // Dispatch disable
  101:         pushm  r1-r13                                   // Context save
  102: 
  103: #if USE_FPU                                             // Save FPU registers
  104:         mvfc   fpsw, r1
  105:         push.l r1
  106: #endif
  107: 
  108: #if USE_DSP                                             // Save DSP registers
  109:         mvfaclo #0,a1,r2
  110:         mvfachi #0,a1,r3
  111:         mvfacgu        #0,a1,r4
  112:         pushm  r2-r4
  113:         mvfaclo #0,a0,r2
  114:         mvfachi #0,a0,r3
  115:         mvfacgu        #0,a0,r4
  116:         pushm  r2-r4
  117: #endif
  118:         mov.l  #Csym(knl_ctxtsk), r7
  119:         mov.l  [r7], r2
  120:         mov.l  r0, (TCB_tskctxb + CTXB_ssp)[r2] // Save SSP to ctxtsk's TCB
  121: 
  122:         mvtipl #0                              // IPL = 0 (Lowest level)
  123: l_dispatch1:
  124:         clrpsw I                               // Interrupt disable
  125: 
  126:         mov.l  #Csym(knl_schedtsk), r2
  127:         mov.l  [r2], r6
  128:         cmp    #0, r6                             // ? schedtsk == NULL
  129:         bne    l_dispatch2                        //   No. goto l_dispatch2
  130:                                                 //        Yes.
  131:         // Move to power saving mode because there are no tasks to perform.
  132:         mov.l  #Csym(knl_lowpow_discnt), r1 
  133:         mov.l  [r1], r1                 // Is 'low_pow' disabled?
  134:         cmp    #0, r1
  135:         bne    l_dispatch11
  136: 
  137:         mov.l  #Csym(low_pow), r1
  138:         jsr    r1                         // Move to power saving mode. call low_pow().
  139: l_dispatch11:
  140: 
  141:         setpsw I                               // Interrupt enable
  142:         bra    l_dispatch1
  143: 
  144: l_dispatch2:                                    // Switch to 'schedtsk'
  145:         // During interrupt disable (PSW.I=0).
  146:         mov.l  r6, [r7]                         // ctxtsk := schedtsk
  147:         mov.l  (TCB_tskctxb + CTXB_ssp)[r6], r0 // Restore SSP from TCB
  148: 
  149:         mov.l  #Csym(knl_dispatch_disabled), r2
  150:         mov.l  #0, [r2]                         // Dispatch enable
  151:         
  152: #if USE_DSP                                     // Restore DSP register.
  153:         popm   r2-r4
  154:         mvtacgu        r4,a0
  155:         mvtachi r3,a0
  156:         mvtaclo r2,a0
  157:         popm   r2-r4
  158:         mvtacgu        r4,a1
  159:         mvtachi r3,a1
  160:         mvtaclo r2,a1
  161: #endif
  162: 
  163: #if USE_FPU                                     // Restore FPU register.
  164:         pop    r1
  165:         mvtc   r1, fpsw
  166: #endif
  167: 
  168:         popm   r1-r15                            // Restore context.
  169:         rte
  170: 
  171:         .end
  172: 
  173: #endif  /* CPU_RX231 */