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

📄 except.s

📁 wince下的源代码集合打包
💻 S
📖 第 1 页 / 共 4 页
字号:
//      TITLE("Interrupt and Exception Processing")
//++
//
// Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.
//
// Module Name:
//
//    except.s
//
// Abstract:
//
//    This module implements the code necessary to field and process MIPS
//    interrupt and exception conditions.
//
//    WARNING: This module executes in KSEG0 and, in general, cannot
//       tolerate a TLB Miss. Registers k0 and k1 are used during initial
//	 interrupt and exception processing, and therefore, extreme care must
//	 be exercised when modifying this module.
//
//--

#include "ksmips.h"
#include "nkintr.h"
#include "kpage.h"
#include "mem_mips.h"
#include "psyscall.h"
#include "xtime.h"

	.text

	.globl	PtrCurMSec
PtrCurMSec: .word AddrCurMSec

PosTable:
  	.byte 0,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1
  	.byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1
  	.byte 7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1
  	.byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1
  	.byte 8,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1
  	.byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1
  	.byte 7,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1
  	.byte 6,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1,5,1,2,1,3,1,2,1,4,1,2,1,3,1,2,1

LEAF_ENTRY (GetHighPos)
	.set noreorder

	addi t0, zero, -1
	andi t1, a0, 0xff
	lb	v0, PosTable(t1)
	bne zero, v0, res
	srl a0, a0, 8

	addi t0, t0, 8
	andi t1, a0, 0xff
	lb	v0, PosTable(t1)
	bne zero, v0, res
	srl a0, a0, 8

	addi t0, t0, 8
	andi t1, a0, 0xff
	lb	v0, PosTable(t1)
	bne zero, v0, res
	srl a0, a0, 8

	addi t0, t0, 8
	andi t1, a0, 0xff
	lb	v0, PosTable(t1)
	bne zero, v0, res
	nop

	addi v0, v0, 9
res:
	j ra
	add v0, v0, t0
	.end GetHighPos

LEAF_ENTRY(INTERRUPTS_ON)
	.set noreorder
	lw	t0, BasePSR
	nop
	or	t0, 1
	j	ra
	mtc0	t0, psr
	.end INTERRUPTS_ON

LEAF_ENTRY(INTERRUPTS_OFF)
	.set noreorder
	mtc0	zero, psr
	nop			// 3 cycle delay
	j	ra
	nop
	.end INTERRUPTS_OFF

LEAF_ENTRY(SetCPUHardwareWatch)
	.set noreorder
	lui	t0, 0x7fff
	ori t0, t0, 0xfff8
	and a0, a0, t0
	or  a0, a0, a1
	mtc0 a0, $18
	nop
	nop
	mtc0 zero, $19
	nop
	nop
	j ra
	nop
	.end SetCPUHardwareWatch

LEAF_ENTRY(SetCPUASID)
	.set noreorder

#ifdef CELOG
        //
        // NOTE : To make things relatively consistent, I'm going to make
        // the registers v0, t0-t9, a0, a1 available for use. On entry to
        // CeLogThreadMigrateMIPS, a0 will contain the handle of the new process.
        //
        // I'm assuming that at this point the only registers of these that
        // I need to preserve are A0 and RA.
        //

        lw	t0, ThProc(a0)		// (t0) = ptr to new process
	lw	t1, PrcHandle(t0)	// (t1) = handle of new process
	lw	t0, hCurProc		// (t0) = current process handle
	beq	t0, t1, celog10		// if procs are equal then skip CeLog call
        nop

	subu	sp, 8                   // adjust sp
        sw      ra, 0(sp)               // save RA
        sw      a0, 4(sp)               // save arg

        move    a0, t1                  // (a0) = handle of new process

        jal     CELOG_ThreadMigrateMIPS
        nop

        lw      ra, 0(sp)               // restore RA
        lw      a0, 4(sp)               // restore arg
        addu	sp, 8           	// adjust sp

celog10:
#endif

        lw	t0, ThProc(a0)		// (t0) = ptr to current process
	lw	t1, ThAKey(a0)		// (t1) = thread's access key
	lw	t2, PrcHandle(t0)	// (t2) = handle of current process
	sw	t0, CurPrcPtr		// remember current process pointer
	sw	t2, hCurProc		// remember current process handle
	lw	t2, PrcVMBase(t0)	// (t2) = memory section base address
	lb	t0, PrcID(t0)		// (t0) = process ID
	srl	t2, VA_SECTION-2	// (t2) = index into section table
	lw	t2, SectionTable(t2)	// (t2) = process's memory section
	sw	t1, CurAKey		// save access key for TLB handler
#if ENTRYHI_PID != 0
	sll	t0, ENTRYHI_PID
#endif
	mtc0	t0, entryhi		// set ASID
	j	ra
	sw	t2, SectionTable(zero)	// swap in default process slot
	.end SetCPUASID

NESTED_ENTRY(xKCall, 0, zero)
//++
// The following code is never executed. Its purpose is to support unwinding
// through the call to the exception dispatcher.
//--
        .set    noreorder
        .set    noat
        sw      sp,20(sp)         // save stack pointer
        sw      ra,16(sp)         // save return address
        PROLOGUE_END

ALTERNATE_ENTRY(KCall)
// 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

	.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, 16(sp)		// thread will resume at return address
	jal	t0
	sw	t2, 20(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, 16(sp)		// (ra) = return address

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

	lw	t2, 20(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
	lui t8, 0x2000
	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, 20(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
	sw	t2, TcxIntSp(t0)	// save stack pointer
	sw	v0, TcxIntV0(t0)	// save return value
	sw	s0, TcxIntS0(t0)	// save thread's permanent registers
	sw	s1, TcxIntS1(t0)	// ...
	sw	s2, TcxIntS2(t0)	// ...
	sw	s3, TcxIntS3(t0)	// ...
	sw	s4, TcxIntS4(t0)	// ...
	sw	s5, TcxIntS5(t0)	// ...
	sw	s6, TcxIntS6(t0)	// ...
	sw	s7, TcxIntS7(t0)	// ...
	sw	s8, TcxIntS8(t0)	// ...
	sw	zero, TcxContextFlags(t0)
	sw	gp, TcxIntGp(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:
	move	k1, t0			// 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
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:
	move	k1, t0			// interlocked operation in progress
	lw	v0, (a0)		// (v0) = original list head
	sw	v0, (a1)		// store linkage
	sw	a1, (a0)		// store new list head
	j	ra
	move	k1, zero		// interlocked operation complete
#else
 #error Unimplemented.
#endif
	.end   InterlockedPushList

#ifdef MIPS_HAS_FPU

LEAF_ENTRY(GetAndClearFloatCode)
	mfc0 a1, psr
	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)
	mfc0 t0, psr
	lui t1, 0x2000
	or t0, t1
	mtc0 t0, psr
	nop
	nop
	nop
	cfc1 t0, fsr
	sw t0, TcxFsr(a0)
	swc1 f0, TcxFltF0(a0)
	swc1 f1, TcxFltF1(a0)
	swc1 f2, TcxFltF2(a0)
	swc1 f3, TcxFltF3(a0)
	swc1 f4, TcxFltF4(a0)
	swc1 f5, TcxFltF5(a0)
	swc1 f6, TcxFltF6(a0)
	swc1 f7, TcxFltF7(a0)
	swc1 f8, TcxFltF8(a0)
	swc1 f9, TcxFltF9(a0)
	swc1 f10, TcxFltF10(a0)
	swc1 f11, TcxFltF11(a0)
	swc1 f12, TcxFltF12(a0)
	swc1 f13, TcxFltF13(a0)
	swc1 f14, TcxFltF14(a0)
	swc1 f15, TcxFltF15(a0)
	swc1 f16, TcxFltF16(a0)
	swc1 f17, TcxFltF17(a0)
	swc1 f18, TcxFltF18(a0)
	swc1 f19, TcxFltF19(a0)
	swc1 f20, TcxFltF20(a0)
	swc1 f21, TcxFltF21(a0)
	swc1 f22, TcxFltF22(a0)
	swc1 f23, TcxFltF23(a0)
	swc1 f24, TcxFltF24(a0)
	swc1 f25, TcxFltF25(a0)
	swc1 f26, TcxFltF26(a0)
	swc1 f27, TcxFltF27(a0)
	swc1 f28, TcxFltF28(a0)
	swc1 f29, TcxFltF29(a0)
	swc1 f30, TcxFltF30(a0)
	swc1 f31, TcxFltF31(a0)
	j ra
	nop
	.end SaveFloatContext

LEAF_ENTRY(RestoreFloatContext)
	mfc0 t0, psr
	lui t1, 0x2000
	or t0, t1
	mtc0 t0, psr
	nop
	nop
	nop
	lw t0, TcxFsr(a0)
	ctc1 t0, fsr
	lwc1 f0, TcxFltF0(a0)
	lwc1 f1, TcxFltF1(a0)
	lwc1 f2, TcxFltF2(a0)
	lwc1 f3, TcxFltF3(a0)
	lwc1 f4, TcxFltF4(a0)
	lwc1 f5, TcxFltF5(a0)
	lwc1 f6, TcxFltF6(a0)
	lwc1 f7, TcxFltF7(a0)
	lwc1 f8, TcxFltF8(a0)
	lwc1 f9, TcxFltF9(a0)
	lwc1 f10, TcxFltF10(a0)
	lwc1 f11, TcxFltF11(a0)
	lwc1 f12, TcxFltF12(a0)
	lwc1 f13, TcxFltF13(a0)
	lwc1 f14, TcxFltF14(a0)
	lwc1 f15, TcxFltF15(a0)
	lwc1 f16, TcxFltF16(a0)
	lwc1 f17, TcxFltF17(a0)
	lwc1 f18, TcxFltF18(a0)
	lwc1 f19, TcxFltF19(a0)
	lwc1 f20, TcxFltF20(a0)
	lwc1 f21, TcxFltF21(a0)
	lwc1 f22, TcxFltF22(a0)
	lwc1 f23, TcxFltF23(a0)
	lwc1 f24, TcxFltF24(a0)
	lwc1 f25, TcxFltF25(a0)
	lwc1 f26, TcxFltF26(a0)
	lwc1 f27, TcxFltF27(a0)
	lwc1 f28, TcxFltF28(a0)
	lwc1 f29, TcxFltF29(a0)

⌨️ 快捷键说明

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