⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 except.s

📁 WinCE5.0部分核心源码
💻 S
📖 第 1 页 / 共 5 页
字号:
// KCall - call kernel function
//
//  KCall invokes a kernel function in a non-preemtable state by incrementing
// the kernel nest level and switching onto a kernel stack.
//
//  While in a preemtible state, the thread's register save area is
// volatile. On the way in, nothing can be saved into the thread
// structure until KNest is set and on the way out anything needed from the
// thread structure must be loaded before restoring KNest.
//
//  The sequence of stack switching must be handled carefully because
// whenever KNest != 1, the general exception handler assumes that the kernel
// stack is current and will not switch stacks. On the way in, we must switch
// to the kernel stack before setting KNest but not use it until after KNest
// is set.  On the way out, we must reset KNest before restoring the thread's
// stack pointer.
//
//  Entry   (a0) = ptr to function to call
//      (a1) = first function arg
//      (a2) = second fucntion arg
//      (a3) = third function arg
//  Exit    (v0) = function return value
//  Uses    v0, a0-a3, t0-t9
//
//------------------------------------------------------------------------------
ALTERNATE_ENTRY(KCall)

        .set    noreorder
        move    t0, a0                  // (t0) = ptr to function to call
        lh      t1, ReschedFlag         // (t1) = resched flag + nest level
        move    a0, a1                  // ripple args down
        move    a1, a2
        subu    t1, 256
        bltz    t1, 50f                 // nested kernel call
        move    a2, a3
//
// Entering non-preemptible state. We must switch onto the kernel stack
// before setting KNest in case an interrupt occurs during the switch.
//
        move    t2, sp                  // (t2) = original stack pointer
        la      sp, KStack              // switch to kernel stack
        sh      t1, ReschedFlag         // enter non-preemtible state
        sw      ra, KCF_RA(sp)          // thread will resume at return address
        jal     t0
        sw      t2, KCF_SP(sp)          // save thread's stack pointer

//
// Function complete. Return to preemtible state after checking if a reschedule
// is needed.
//
        mtc0    zero, psr
        nop
        nop
        nop

        lh      t9, ReschedFlag         // (t9) = resched flag + nest level
        li      t1, 1
        beq     t9, t1, 20f             // reschedule needed
        lw      ra, KCF_RA(sp)          // (ra) = return address

        lw      t2, dwKCRes
        bne t2, zero, 20f       // reschedule needed
        nop

        lw      t2, KCF_SP(sp)          // (t2) = original stack pointer
        addu    t9, 256
        sh      t9, ReschedFlag         // leave non-preemtible state

        lw      t9, BasePSR
        or t9, 1
#ifdef MIPS_HAS_FPU
        lw      t8, g_CurFPUOwner
        lw      t7, CurThdPtr
        bne     t7, t8, 19f
        nop
        la      t8, dwNKCoProcEnableBits
        lw      t8, (t8)
        or      t9, t8
19:
#endif
        mtc0    t9, psr

        j       ra
        move    sp, t2                  // restore stack pointer

//
// ReschedFlag set, so must run the scheduler to find which thread
// to dispatch next.
//
//  (v0) = KCall return value
//
20:
        lw      t9, BasePSR
        or      t9, 1
        mtc0    t9, psr
        
        lw      t0, CurThdPtr           // (t0) = ptr to current thread
        lw      t2, KCF_SP(sp)          // (t2) = original stack pointer
        li      t3, KERNEL_MODE
        sw      ra, TcxFir(t0)          // thread will resume at return address
        sw      t3, TcxPsr(t0)          //  & in kernel mode
        S_REG   t2, TcxIntSp(t0)        // save stack pointer
        S_REG   v0, TcxIntV0(t0)        // save return value
        S_REG   s0, TcxIntS0(t0)        // save thread's permanent registers
        S_REG   s1, TcxIntS1(t0)        // ...
        S_REG   s2, TcxIntS2(t0)        // ...
        S_REG   s3, TcxIntS3(t0)        // ...
        S_REG   s4, TcxIntS4(t0)        // ...
        S_REG   s5, TcxIntS5(t0)        // ...
        S_REG   s6, TcxIntS6(t0)        // ...
        S_REG   s7, TcxIntS7(t0)        // ...
        S_REG   s8, TcxIntS8(t0)        // ...
        S_REG   gp, TcxIntGp(t0)
        sw      zero, TcxContextFlags(t0)
        
        j       resched
        move    s0, t0                  // (s0) = ptr to current thread struct

25:     j       resched
        move    s0, zero                // no current thread

// Nested KCall. Just invoke the function directly.
//
//  (t0) = function address
//  (a0) = 1st function argument
//  (a1) = 2nd function argument
//  (a2) = 3rd function argument
//
50:     j       t0
        nop

        .set reorder
        .end xKCall



//------------------------------------------------------------------------------
//
// Interlocked singly-linked list functions.
//
//  These functions are used internally by the kernel. They are not exported
// because they require privileged instructions on some CPUs.
//
// InterlockedPopList - remove first item from list
//
//  Entry   (a0) = ptr to list head
//  Return  (v0) = item at head of list
//      If (list not emtpy) next item is now head of list
//  Usea    t0, t1
//
//------------------------------------------------------------------------------
LEAF_ENTRY(InterlockedPopList)
#if NO_LL
        la      t0, IPopRestart
        .set    noreorder
IPopRestart:
        addiu   k1, t0, 6 * 4           // (k1) = &IPopDone, indicate interlocked
                                        //        operation in progress
        lw      v0, (a0)                // (v0) = original contents
        beq     v0, zero, 10f           
        nop                             
        lw      t1, (v0)                // (t1) = next item on the list
        sw      t1, (a0)                // update head of list
IPopDone:
10:     j       ra                      
        move    k1, zero                // interlocked operation complete
#else
 #error Unimplemented.
#endif
        .end   InterlockedPopList



//------------------------------------------------------------------------------
// InterlockedPushList - add an item to head of list
//
//  Entry   (a0) = ptr to list head
//      (a1) = ptr to item
//  Return  (v0) = old head of list
//  Uses    t0, v0
//------------------------------------------------------------------------------
LEAF_ENTRY(InterlockedPushList)
#if NO_LL
        la      t0, IPushRestart
        .set    noreorder
IPushRestart:
        addiu   k1, t0, 4 * 4           // (k1) = &IPushDone, indicate interlocked
                                        //        operation in progress
        lw      v0, (a0)                // (v0) = original list head
        sw      v0, (a1)                // store linkage
        sw      a1, (a0)                // store new list head
IPushDone:
        j       ra                      
        move    k1, zero                // interlocked operation complete
#else
 #error Unimplemented.
#endif
        .end   InterlockedPushList

        
        
#ifdef MIPS_HAS_FPU

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LEAF_ENTRY(GetAndClearFloatCode)
        
        CP0_STOP_PREFETCH(mfc0, a1, psr, a2);
        lui     a2, 0x2000
        or      a1, a2
        mtc0    a1, psr
        nop
        nop
        nop
        cfc1    v0, fsr
        
        li      t0, 0xfffc0fff
        and     t0, t0, v0
        
        ctc1    t0, fsr
        j       ra
        nop
        
        .end GetCode

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LEAF_ENTRY(SaveFloatContext)
        CP0_STOP_PREFETCH(mfc0, t0, psr, t1);
        lui     t1, 0x2000
        or      t0, t1
        mtc0    t0, psr
        nop
        nop
        nop
        cfc1    t0, fsr
        sw      t0, TcxFsr(a0)

        // MIPSII - use sdc1 on all even number FP registers
        sdc1    f0, TcxFltF0(a0)
        sdc1    f2, TcxFltF2(a0)
        sdc1    f4, TcxFltF4(a0)
        sdc1    f6, TcxFltF6(a0)
        sdc1    f8, TcxFltF8(a0)
        sdc1    f10, TcxFltF10(a0)
        sdc1    f12, TcxFltF12(a0)
        sdc1    f14, TcxFltF14(a0)
        sdc1    f16, TcxFltF16(a0)
        sdc1    f18, TcxFltF18(a0)
        sdc1    f20, TcxFltF20(a0)
        sdc1    f22, TcxFltF22(a0)
        sdc1    f24, TcxFltF24(a0)
        sdc1    f26, TcxFltF26(a0)
        sdc1    f28, TcxFltF28(a0)
        sdc1    f30, TcxFltF30(a0)
#ifdef MIPSIV
        // MIPSIV - also save the odd number FP registers
        sdc1    f1, TcxFltF1(a0)
        sdc1    f3, TcxFltF3(a0)
        sdc1    f5, TcxFltF5(a0)
        sdc1    f7, TcxFltF7(a0)
        sdc1    f9, TcxFltF9(a0)
        sdc1    f11, TcxFltF11(a0)
        sdc1    f13, TcxFltF13(a0)
        sdc1    f15, TcxFltF15(a0)
        sdc1    f17, TcxFltF17(a0)
        sdc1    f19, TcxFltF19(a0)
        sdc1    f21, TcxFltF21(a0)
        sdc1    f23, TcxFltF23(a0)
        sdc1    f25, TcxFltF25(a0)
        sdc1    f27, TcxFltF27(a0)
        sdc1    f29, TcxFltF29(a0)
        sdc1    f31, TcxFltF31(a0)
#endif
        j ra
        nop
        .end SaveFloatContext

           
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LEAF_ENTRY(RestoreFloatContext)
        
        CP0_STOP_PREFETCH(mfc0, t0, psr, t1);
        lui     t1, 0x2000
        or      t0, t1
        mtc0    t0, psr
        nop
        nop
        nop
        lw      t0, TcxFsr(a0)
        // For some reason unknown, bit 17 of FSR can be set, which
        // causes the ctc1 instruction to except. Mask bit 17 off the FSR
        // for now.
        li      t1, 0xfffdffff
        and     t0, t0, t1
        ctc1    t0, fsr
        // MIPSII - use sdc1 on all even number FP registers
        ldc1    f0, TcxFltF0(a0)
        ldc1    f2, TcxFltF2(a0)
        ldc1    f4, TcxFltF4(a0)
        ldc1    f6, TcxFltF6(a0)
        ldc1    f8, TcxFltF8(a0)
        ldc1    f10, TcxFltF10(a0)
        ldc1    f12, TcxFltF12(a0)
        ldc1    f14, TcxFltF14(a0)
        ldc1    f16, TcxFltF16(a0)
        ldc1    f18, TcxFltF18(a0)
        ldc1    f20, TcxFltF20(a0)
        ldc1    f22, TcxFltF22(a0)
        ldc1    f24, TcxFltF24(a0)
        ldc1    f26, TcxFltF26(a0)
        ldc1    f28, TcxFltF28(a0)
        ldc1    f30, TcxFltF30(a0)
#ifdef MIPSIV
        // MIPSIV - also save the odd number FP registers
        ldc1    f1, TcxFltF1(a0)
        ldc1    f3, TcxFltF3(a0)
        ldc1    f5, TcxFltF5(a0)
        ldc1    f7, TcxFltF7(a0)
        ldc1    f9, TcxFltF9(a0)
        ldc1    f11, TcxFltF11(a0)
        ldc1    f13, TcxFltF13(a0)
        ldc1    f15, TcxFltF15(a0)
        ldc1    f17, TcxFltF17(a0)
        ldc1    f19, TcxFltF19(a0)
        ldc1    f21, TcxFltF21(a0)
        ldc1    f23, TcxFltF23(a0)
        ldc1    f25, TcxFltF25(a0)
        ldc1    f27, TcxFltF27(a0)
        ldc1    f29, TcxFltF29(a0)
        ldc1    f31, TcxFltF31(a0)
#endif
        j ra
        nop
        .end RestoreFloatContext
#endif

           

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -