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

📄 tlbmiss.s

📁 wince下的源代码集合打包
💻 S
字号:
/** Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved. **/

/*+
	TLB Miss handler

	This module contains the code to handle reloading the hardware
 Translation Lookaside Buffer.

 */

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

#define jalfix(func)	\
	jal	func;	\
	nop;

	.text
	.globl	NullSection
NullSection:
	.repeat	BLOCK_MASK+1
	.word	0
	.endr


//-----------------------------------------------------
// CELOG replaces the TLB MISS Handler with its own.
//
#ifdef CELOG
LEAF_ENTRY(CeLogTLBMissHandler)
        .set noreorder

        sw      t0, SaveT0              //                              :1
        la      k0, dwCeLogTLBMiss      // Global variable              :2-3
        lw      t0, 0(k0)               //                              :4
        addi    t0, t0, 1               // increment                    :5
        sw      t0, 0(k0)               // Update counter               :6
        
        lw      t0, SaveT0              //                              :7
        la      k0, TLBMissHandler      // Load address of real handler :8-9
        j       k0                      //                              :10
        nop                             //                              :11
        
        END_REGION(CeLogTLBMissHandler_End)

        .set    reorder
        .set    at
        .end    CeLogTLBMissHandler
#endif


//	The user mode virtual address space is 2GB split into 64 sections
// of 512 blocks of 16 4K pages. For some platforms, the # of blocks in
// a section may be limited to fewer than 512 blocks to reduce the size
// of the intermeditate tables. E.G.: Since the PeRP only has 5MB of total
// RAM, the sections are limited to 4MB. This results in 64 block sections.
//
// Virtual address format:
//	3322222 222221111 1111 110000000000
//	1098765 432109876 5432 109876543210
//	zSSSSSS BBBBBBBBB PPPP oooooooooooo
//
// Context register format:
//	33222222222211111 111110000 0000 00
//	10987654321098765 432109876 5432 10
//	zzzzzzzzzzzSSSSSS BBBBBBBBB PPPP zz


LEAF_ENTRY(TLBMissHandler)
	.set    noreorder
	.set    noat
#if R3000
	mfc0	k0, context		// (k0) = faulting VPN * 4	:1
	sw	t0, SaveT0		//				:2
	sw	k1, SaveK1		//				:3
	srl	t0, k0, CTX_SECTION-2	//				:4
	and	t0, SECTION_MASK*4	// (t0) = section * 4		:5
	lw	t0, SectionTable(t0)	// (t0) = ptr to block table	:6
	srl	k1, k0, CTX_BLOCK-2	//				:7
	and	k1, BLOCK_MASK*4	// (k1) = block * 4		:8
	addu	t0, k1			// (t0) = block table entry	:9
	lw	t0, (t0)		// (t0) = ptr to MEMBLOCK structure
	and	k0, PAGE_MASK*4		// (k0) = page # * 4		:11
	bgez	t0, 80f			// unmapped memblock		:12
	addu	k0, t0			// (k0) = ptr to page entry	:13
	lw	k1, mb_lock(t0)		// (k1) = block access lock	:14
	lw	t0, CurAKey		//				:15
	lw	k0, mb_pages(k0)	// (k0) = page info		:16
	and	k1, t0			// (k1) = 0 if access not allowed
	beq	zero, k1, 80f		// access not allowed		:18
	mtc0	k0, entrylo		// set info to write into TLB	:19
	blez	k0, 81f			// invalid entry		:20
	lw	t0, SaveT0		// restore t0 register		:21
        tlbwr                           // write entry randomly into TLB:22
        nop                             // 3 cycle hazzard		:23
        nop				//				:24
	mfc0	k0, epc			//				:25
	lw	k1, SaveK1		// restore atomic restart flag	:26
	j	k0			//				:27
	rfe				//				:28
	nop
	nop

80:	lw	t0, SaveT0		//				:31
81:	lw	k1, SaveK1		//				:32
	// fall through into general exception handler
	///j	0x80000080

#elif R4000
	mfc0	k0, badvaddr		// (k0) = faulting virtual addr	:1
	sw	t0, SaveT0		//				:2
	sw	k1, SaveK1		//				:3
	srl	t0, k0, VA_SECTION-2	//				:4
	bltz	k0, 80f			// address out of range		:5
	and	t0, SECTION_MASK*4	// (t0) = section * 4		:6
	lw	t0, SectionTable(t0)	// (t0) = ptr to block table	:7
	srl	k1, k0, VA_BLOCK-2	//				:8
	and	k1, BLOCK_MASK*4	// (k1) = block * 4		:9
	addu	t0, k1			// (t0) = block table entry	:10
	lw	t0, (t0)		// (t0) = ptr to MEMBLOCK structure
	srl	k0, VA_PAGE-2		//				:12
	and	k0, (PAGE_MASK/2)*8	// (k0) = (even page #) * 4	:13
	bgez	t0, 80f			// unmapped memblock		:14
	addu	k0, t0			// (k0) = ptr to page entry	:15
	lw	k1, mb_lock(t0)		// (k1) = block access lock	:16
	lw	t0, CurAKey		//				:17
	and	k1, t0			// (k1) = 0 if access not allowed
	lw	t0, mb_pages(k0)	// (t0) = even page info	:19
	beq	zero, k1, 80f		// access not allowed		:20
	lw	k0, mb_pages+4(k0)	// (k0) = odd page info		:21
	mtc0	t0, entrylo0		// set even entry to write into TLB
	mtc0	k0, entrylo1		// set odd entry to write into TLB
	lw	t0, SaveT0		// restore t0 register		:24
	lw	k1, SaveK1		//				:25
	tlbwr                           // write entry randomly into TLB:26
	nop				//				:27
	nop                             // 3 cycle hazzard		:28
70:	eret				//				:29

80:	lw	k1, SaveK1		//				:30
	.word	0x08000060		// j 0x80000180			:31
	lw	t0, SaveT0		//				:32
#else
 #error unknown processor type
#endif

	END_REGION(TLBMissHandler_End)

#ifdef CELOG
#if R3000
        // if we don't relocate the TLBMissHandler for CELOG the "fall-through"
        // doesn't happen. So Jump.
        .word   0x08000020              // j 0x80000080                 :31
        nop
#endif
#endif

	.set    reorder
	.set    at
	.end	TLBMissHandler

LEAF_ENTRY(VerifyAccess)
// VerifyAccess(PVOID pvAddr, DWORD dwFlags, ACCESSKEY aky)
//		- verify access to a pointer
//
//	VerifyAccess checks to see if the current thread has access to
// the given address. If bWrite is TRUE, both read & write access are
// verified.
//
//	Entry	(a0) = virtual address to verify
//		(a1) = type of access to verify
//		(a2) = access key to use for validation
//	Return	TRUE - access is OK
//		FALSE - if access is not valid
//	Uses	t0, t1, t2
	.set noreorder
	bltz	a0, 50f			// check system addresses specially
	srl	t0, a0, VA_SECTION-2
	and	t0, SECTION_MASK*4	// (t0) = section * 4
	lw	t0, SectionTable(t0)	// (t0) = ptr to block table
	srl	t1, a0, VA_BLOCK-2
	and	t1, BLOCK_MASK*4	// (t1) = block * 4
	addu	t0, t1			// (t0) = block table entry
	lw	t0, (t0)		// (t0) = ptr to MEMBLOCK structure
	srl	t2, a0, VA_PAGE-2
	bgez	t0, 30f			// unmapped memblock
	and	t2, PAGE_MASK*4		// (t2) = page # * 4
	lw	t1, mb_lock(t0)		// (t1) = block access lock
	addu	t0, t2			//
	lw	t0, mb_pages(t0)	// (t0) = page info
	and	t1, a2			// (t1) = 0 if access not allowed
	beq	zero, t1, 30f		// access not allowed
	and	a1, VERIFY_WRITE_FLAG
	blez	t0, 30f			// invalid entry
	and	t1, t0, 1<<ENTRYLO_D
	and	a0, PAGE_SIZE-1		// (a0) = offset within page
	lui	v0, 0x8000
	or	a0, v0
	lui	v0, 0x1FFF
	ori	v0, ~(PAGE_SIZE-1) & 0xFFFF
#if PFN_SHIFT
	sll	t0, PFN_SHIFT
#endif
	bne	zero, a1, 25f		// check for write access
	and	v0, t0			// (v0) = physical page address
20:	j	ra
	or	v0, a0			// (v0) = unmapped version of pvAddr

25:	bne	zero, t1, 20b		// the page is writable
	nop
30:	j	ra
	move	v0, zero

// The address is in the system address range. If the thread's current mode
// is user mode, then fail the access. Also, disallow access to addresses in
// the system mapped region except for the Kpage.

50:	srl	t2, a0, 12		// (t2) = 4k page addr
	subu	t2, KData >> 12
	beq	zero, t2, 51f		// kpage is in system mapped space
	lui	t2, 0xC000
	sltu	t2, a0, t2		// (t2) = 0 if Addr >= 0xC0000000
	beq	zero, t2, 30b		// access not allowed.
51:	lw	t0, CurThdPtr
	and	a1, VERIFY_KERNEL_OK
	lw	t1, TcxPsr(t0)
	bne	zero, a1, 20b		// kernel access allowed
	move	v0, zero
	and	t1, 1 << PSR_PMODE
	beq	zero, t1, 20b		// Kernel mode thread: access allowed
	nop
	j	ra
	move	v0, zero		// return access failed
	.end	VerifyAccess



LEAF_ENTRY(FlushTLB)

	// Clear out all tlb entries

	.set noreorder

#if R3000
	mfc0    t0, psr		// Save current psr
	mfc0    t1, entryhi     // Save current asid
	andi    v0, t0, 0xFFFE	// Mask interrupts
	mtc0    v0, psr		// Disable interrupts
	lw	v1, OEMTLBSize	// (v1) = index & loop counter
	lw	t2, OEMTLBWired	// (t2) = loop limit
	li      v0, 0x80000000	// Unmapped address

10:	mtc0    zero, entrylo	// Clear entrylo - Invalid entry
	mtc0    v0, entryhi	// Clear entryhi - Ivalid address
	mtc0    v1, index	// Set index
	nop                     // Fill delay slot
	tlbwi                   // Write entry (indexed)
	bne     v1, t2, 10b	// If not zero do next one
	addiu   v1, v1, -256	// Decrement index, loop counter

	mtc0    t1, entryhi	// Restore asid
	mtc0    t0, psr		// Restore psr
	j	ra
	nop

#elif R4000
	mfc0    t0, psr		// Save current psr
	mfc0    t1, entryhi     // Save current asid
	nop
	andi    v0, t0, 0xFFFE	// Mask interrupts
	mtc0    v0, psr		// Disable interrupts
	nop                     // fill delay slot
	li      v0, 0x80000000	// Unmapped address
	lw	v1, OEMTLBSize	// (v1) = index & loop counter
	mfc0	t2, wired	// (t2) = loop limit
10:	mtc0    zero, entrylo0	// Clear entrylo0 - Invalid entry
	mtc0    zero, entrylo1	// Clear entrylo1 - Invalid entry
	mtc0    v0, entryhi	// Clear entryhi - Ivalid address
	mtc0    v1, index	// Set index
	add	v0, 0x2000
	nop                     // Fill delay slot
	tlbwi                   // Write entry (indexed)
	nop
	bne     v1, t2, 10b	// If not zero do next one
	addiu   v1, v1, -1	// Decrement index, loop counter

	mtc0    t1, entryhi	// Restore asid
	mtc0    t0, psr		// Restore psr

	// now flush the ICache and the DCache
    addiu   sp, sp, -4
	sw      ra, 4(sp)      // save ra
	jalfix(FlushICache)
	jalfix(FlushDCache)
	lw      ra, 4(sp)      // restore ra
	j	ra
    addiu   sp, sp, 4
#else
 #error unknown processor type
#endif    // R4000

	.set reorder
	.end	FlushTLB

⌨️ 快捷键说明

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