timerisr.s

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· S 代码 · 共 239 行

S
239
字号
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-1998  Microsoft Corporation

Module Name:

     timerisr.s

Abstract:

Functions:


Notes:


--*/

#define ASSEMBLY_LANGUAGE

#include <kxmips.h>
#include <nkintr.h>
#include <altoona.h>
#include <alt_def.h>
#include "timer.h"

///////////////////////////////////////////////////////////////////////////
//
// LC2W timer interrupt service routine.
//
// Registers: v0, AT, a0-a3 available for use.
//
//      Entry   (a0) = hw interrupt No
//              (a1) = ptr to apvIntrData array
//      Exit    (v0) = interrupt dispostion information
//      Uses    v0, a0-a3, AT
//
///////////////////////////////////////////////////////////////////////////

WatchdogCount:
    .dword 0x00

LEAF_ENTRY(Timer2ISR)
        .set      noat
        .set      noreorder

		la        a3, WatchdogCount
        lw        a2, 0(a3)
        addiu     a2, a2, 1
        sw        a2, 0(a3)

        srl       a2, a2, 8
        li        a3, LED_BASE + KSEG1_BASE
        sb        a2, 0(a3)

isr_guts:
        //-------------------------------------------------------
        // Update CurMSec and DiffMSec (COMMON)

        lw      a2, AddrCurMSec
        lw      a3, AddrDiffMSec

        addiu   a2, a2, CPURTCSHORT_PERIOD
		addiu	a3, a3, CPURTCSHORT_PERIOD

        sw      a2, AddrCurMSec             // +1 mSec
        sw      a3, AddrDiffMSec            // +1 mSec

        //-------------------------------------------------------
        // Normal reschedule processing (NON-INTRTIME)
        //
normal_resched:        
        //
        // Only return SYSINTR_RESCHED when needed, specifically...
        //
#if (CE_MAJOR_VER == 0x0003)
        //  (cedar)
        //  if (ticksleft || (dwSleepMin && (DiffMSec >= dwSleepMin)) || 
        //                    (dwPreempt && (DiffMSec >= dwPreempt)))
        //          return SYSINTR_RESCHED;
        //      else
        //          return SYSINTR_NOP;
        //
        lw      a0, ticksleft
        bne     a0, zero, doresched
        nop

        lw      a0, dwSleepMin
        beq     a0, zero, part2
        nop
        
        lw      a3, AddrDiffMSec
        sltu    a1, a3, a0                      // DiffMSec < dwSleepMin ?
        beq     a1, zero, doresched             // If not, SYSINTR_RESCHED
        nop
part2:
        lw      a0, dwPreempt
        beq     a0, zero, noresched
        nop
        
        sltu    a1, a3, a0                      // DiffMSec < dwPreempt ?
        beq     a1, zero, doresched             // If not, SYSINTR_RESCHED
        nop

#else
        // (dougfir or later)
        //  if ((int) (CurMSec - dwReschedTime) > 0) 
        //          return SYSINTR_RESCHED;
        //  else
        //          return SYSINTR_NOP;
        //
        lw      a0, AddrCurMSec             // a0 == CurMSec
        la      a1, dwReschedTime           // a1 == &dwReschedTime
        lw      a1, (a1)                    // a1 == dwReschedTime
        subu    a0, a0, a1                  // a0 == CurMSec - dwReschedTime
        bgez    a0, doresched               // (int) (CurMSec - dwReschedTime) > 0?
        nop
#endif

noresched:
		//-------------------------------------------------------
        // Clear the interrupt on Vrc5074, INTCLR

        li              a0, 0xbfa000a0
        li              a2, 0x00000040
        sw              a2, 0(a0)

        li      v0, SYSINTR_NOP
		j       ra
		sync

doresched:        
		//-------------------------------------------------------
        // Clear the interrupt on Vrc5074, INTCLR

        li              a0, 0xbfa000a0
        li              a2, 0x00000040
        sw              a2, 0(a0)

        li      v0, SYSINTR_RESCHED
        j       ra
		sync

        .set    reorder
		.set	at
        .end    Timer2ISR

LEAF_ENTRY(InitMIPSClock)
     .set      noreorder

     mfc0      t0,count                // Get current compare value
     li        t1,PERIOD_INC           // Get period increment
     addu      t1,t1,t0                // Compute next compare
     mtc0      t1, compare             // Update next compare

     li        v0, 1                   // return TRUE
     j         ra
     nop

     .set      reorder
     .end      InitClock

#if 0 // briaking - This ISR was not being used...

///////////////////////////////////////////////////////////////////////////
//
// ALTOONA timer interrupt service routine.
//
// Registers: v0, AT, a0-a3 available for use.
//
//      Entry   (a0) = hw interrupt No
//              (a1) = ptr to apvIntrData array
//      Exit    (v0) = interrupt dispostion information
//      Uses    v0, a0-a3, AT
//
///////////////////////////////////////////////////////////////////////////

LEAF_ENTRY(TimerISR)
     .set      noat
     .set      noreorder


     mfc0      a3,count                      // Get current count value
     mfc0      a2,compare                    // Get current compare value
     addiu     a3,a3,32                      // Add in margin
     li        a1,PERIOD_INC                 // Get period increment
     move      v0,zero                       // Clear v0 as period count

10:
     subu      a0,a3,a2
     sltu      AT,a1,a0
     beq       AT,zero,20f                   // Done if count-compare < period
     addiu     v0,v0,1                       // Increment period count

     not       a0,a0
     sltu      AT,a1,a0
     beq       AT,zero,20f                   // Done if count-compare > ~period
     nop

     b         10b
     addu      a2,a2,a1                      // Increment next compare

20:
     addu      a2,a2,a1                      // Compute next compare
     mtc0      a2,compare                    // Update next compare

     lw        a0,CurMSec                    // CurMSec time value
     lw        a1,DiffMSec                   // DiffMSec time value

30:
     addu      a0,CPURTCSHORT_PERIOD
     sltiu     a2,a0,CPURTCSHORT_PERIOD      // Did we wrap?
     beq       a2,zero,40f
     subu      v0,v0,1
     
     la        a3,CurMSecHigh
     lw        a2,0(a3)                      // CurMSecHigh time value
     addiu     a2,a2,1
     sw        a0,0(a3)                      // Update new CurMSecHigh

40:
     bne       v0,zero,30b
     addu      a1,CPURTCSHORT_PERIOD

     sw        a0,CurMSec                    // Update new CurMSec
     sw        a1,DiffMSec                   // Update new DiffMSec

     jr        ra                            // return
     addiu     v0,SYSINTR_RESCHED            // Return that its a timer interrupt

     .set      reorder
     .set      at
     .end      TimerISR

#endif

⌨️ 快捷键说明

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