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 + -
显示快捷键?