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

📄 ppc821.s

📁 wince下的源代码集合打包
💻 S
📖 第 1 页 / 共 2 页
字号:
//      TITLE("TLB Management and support routines")
//++
//
//
// Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.
//
//
// Module Name:
//
//    ppc821.s
//
// Abstract:
//
//    Initialization of the TLB support for the PPC821 kernel
//
// Environment:
//
//    Kernel mode only.
//
// Revision History:
//
//--

#include "mem_ppc.h"
#include "mmu821.h"

//
//  Definition of Special Purpose Registers (SPRs) used on PPC821
//

#define DSISR   18
#define DAR     19
#define IMMR    638

#define INVALID_PAGE    0x2f1

//#define CPU2_ERRATUM	1
//
// See the MPC821 errata for information on the CPU2 hardware issue. The 
// code inside the conditional CPU2_ERRATUM is specific to this issue.
//
#if defined(CPU2_ERRATUM)
// We need a little memory that we can guarantee will always be present.
// This is located in the kernel data structure 'reserved' block.
#define kErrata 0x5AF0
#endif

//
//  The TLB Handlers are defined here and then copied into low memory
//  The four handlers ITBMiss, DTBMiss, ITBError, and DTBError are copied
//  into the correct location for each processor
//  Each vector must be limited to 256 bytes (64 instructions)
//

#define ITBMissVector   0x1100
#define DTBMissVector   0x1200
#define ITBErrorVector  0x1300
#define DTBErrorVector  0x1400

    .text

// Instruction TLB miss handler
//
//      Entry:  (MSR)   External interrupts disabled
//                      Instruction Relocate OFF
//                      Data Relocate OFF
//                  (SRR0)      Instruction address at time of interrupt
//              (SRR1)  MSR at time of interrupt
//
//      Exit:   
//
//      Uses:   M_TW

ITBMiss:

#if defined(CPU2_ERRATUM)
	mtspr	SPRG0, r1
	li		r1, 0x3f80
	stw		r1, kErrata(r0)
	lwz		r1, kErrata(r0)
	mtspr	M_TW, r0
#else
	mtspr   M_TW, r0                // save r0 for a scratch register
	mtspr   SPRG0, r1
#endif
	mfspr   r1, SRR0                // (r1) = fauling address
	mfcr    r0                      // (r0) = saved condition register
	mtcrf   0x80, r1                // (CR0) = faulting address upper nibble
	mtspr   SPRG3, r3

	bt-     0, itmh50               // high bit of address is set
	mtspr   SPRG1, r4
	mtspr   SPRG2, r5

// Lookup a user virtual address in the kernel virtual memory tables to find the
// physical address translation to be loaded into the TLB.

	rlwinm  r3, r1, (32-VA_SECTION)+2, SECTION_MASK*4 // (r3) = section index
	lwz     r4, SectionTable(r3)    // (r4) = ptr to SECTION
	lwz     r5, CurAKey(0)          // (r5) = current access key
	rlwinm  r3, r1, (32-VA_BLOCK)+2, BLOCK_MASK*4   // (r3) = block index
	rlwinm  r4, r4, 0, 0x1fffffff   // make it physical
	lwzx    r3, r3, r4              // (r3) = ptr to MEMBLOCK structure
	rlwinm  r4, r1, (32-VA_PAGE)+2, PAGE_MASK*4     // (r4) = page index
	rlwinm  r3, r3, 0, 0x1fffffff   // make it physical
	cmplwi  r3, 0x1000
	blt-    itmh40                  // invalid block address
	add     r4, r3, r4
	lwz     r3, mb_lock(r3)         // (r3) = access lock for memory block
	lwz     r4, mb_pages(r4)        // (r4) = PTE entry for the page
	and.    r5, r5, r3
	beq-    itmh40                  // access not allowed
	andi.   r5, r4, PAGE_VALID
	beq-    itmh40                  // invalid entry
itmh30:

#if defined(CPU2_ERRATUM)
	li		r1, 0x2d80
	stw		r1, kErrata(r0)
	lwz		r1, kErrata(r0)
#endif
	mtspr   MI_RPN, r4              // add entry to the TLB

// New entry loaded into the TLB. Restore registers and continue.
//
//      (r0) = condition register
//      (M_TW) = saved R0
//      (SPRG0) = saved R1
//      (SPRG1) = saved R4
//      (SPRG2) = saved R5
//      (SPRG3) = saved R3

	mtcrf   0xff, r0                // restore condition register
	mfspr   r0, M_TW
	mfspr   r1, SPRG0
	mfspr   r4, SPRG1
	mfspr   r5, SPRG2
	mfspr   r3, SPRG3
	rfi

// Invalid address reference. Load invalid entry into the TLB and continue.
// This will cause an ITLB error interrupt.
itmh40: mtcrf   0xff, r0                // restore condition register
	mfspr   r0, M_TW
	mfspr   r1, SPRG0
	mfspr   r3, SPRG3
	
	li      r4, ID_CPAGE_FAULT      // (r4) = ITLB error interrupt code
	mfspr   r5, SRR0                // (r5) = address of fault
	
	ba      KPageGeneralHandler
	
// Address in kernel space. Check if kernel server call or reference to
// an "un-mapped" space.  For an "un-mapped" space reference, generate
// a large (8mb) TLB entry to map the region.  For an api call, jump to
// the initial api handler code in the KPage.
//
//      (r0) = saved CR value
//      (r1) = missing virtual address
//      (M_TW) = saved R0
//      (SPRG0) = saved R1
//      (SPRG3) = saved R3

//
// For CPU2, this is too big, so we moved it to spare space in ITBError
//
#if !defined(CPU2_ERRATUM)
itmh50: 
	lis     r3, API_MAX >> 16
	ori     r3, r3, API_MAX & 0xFFFF
	cmplw   r3, r1
	bgt-    itmKMap                 // not an api call or return

// Setup to invoke the API call or return code.
//
//NOTE: Since this is a C or C++ function call or return, it is not necessary to restore
//      R12 and CR0.

	subi    r11, r1, FIRST_METHOD   // (r11) = iMethod * API_SCALE
	mfspr   r12, SRR1
	mfspr   r1, SPRG0
	mfspr   r3, SPRG3
	ba      KPageAPIHandler 
	
itmKMap:                
	li      r3, PAGE_8MB | PAGE_VALID
	mtspr   MI_TWC, r3              // setup for 8mb valid page

	rlwinm	r3, r1, 8, 0x1f			// (r3) = 16M page number
	lbz		r3, kPFNMap(r3)			// (r3) = physical page number

	rlwinm	r3, r3, 24, 0xff000000	// Puts physical page number into high byte
	rlwimi	r3, r1, 0, 0x00800000	// Preserve 8M bit

	ori     r3, r3, PAGE_VALID | PAGE_SHARED | 0xf8
	rlwimi  r3, r1, 4, 2            // insert cache-inhibit bit

itmh55:
	mtspr   MI_RPN, r3
	mtcrf   0xff, r0                // restore condition register
	mfspr   r0, M_TW
	mfspr   r1, SPRG0
	mfspr   r3, SPRG3
	rfi
#endif

    .org    ITBMiss+0x100                       // Fill out the vector

// Data TLB miss handler
//
//      Entry:  (MSR)   External interrupts disabled
//                      Instruction Relocate OFF
//                      Data Relocate OFF
//              (SRR0)  Instruction address at time of interrupt
//              (SRR1)  MSR at time of interrupt
//
//      Exit:   
//
//      Uses:   SPRG3 and M_TW

DTBMiss:
#if defined(CPU2_ERRATUM)
	mtspr   SPRG0, r1
	li		r1, 0x3f80
	stw		r1, kErrata(r0)
	lwz		r1, kErrata(r0)
	mtspr   M_TW, r0
#else
	mtspr   M_TW, r0                            // save r0 for a scratch register
	mtspr   SPRG0, r1
#endif
	mfspr   r1, MD_EPN                          // (r1) = fauling address
	mfcr    r0                                      // (r0) = saved condition register
	mtcrf   0x80, r1                            // (CR0) = faulting address upper nibble
	mtspr   SPRG3, r3
	bt-         0, dtmh50                       // high bit of address is set
	mtspr   SPRG1, r4
	mtspr   SPRG2, r5

// Lookup a user virtual address in the kernel virtual memory tables to find the
// physical address translation to be loaded into the TLB.

	rlwinm  r3, r1, (32-VA_SECTION)+2, SECTION_MASK*4 // (r3) = section index
	lwz     r4, SectionTable(r3)    // (r4) = ptr to SECTION
	rlwinm  r3, r1, (32-VA_BLOCK)+2, BLOCK_MASK*4   // (r3) = block index
	rlwinm  r4, r4, 0, 0x1fffffff   // make it physical
	lwzx    r3, r3, r4              // (r3) = ptr to MEMBLOCK structure
	rlwinm  r4, r1, (32-VA_PAGE)+2, PAGE_MASK*4     // (r4) = page index
	rlwinm  r3, r3, 0, 0x1fffffff   // make it physical
	cmplwi  r3, 0x1000
	lwz     r1, CurAKey(0)          // (r1) = current access key
	blt-    dtmh40                  // invalid block address
	add     r4, r3, r4
	lwz     r3, mb_lock(r3)         // (r3) = access lock for memory block
	lwz     r4, mb_pages(r4)        // (r4) = PTE entry for the page
	and.    r1, r1, r3
	beq-    dtmh40                  // access not allowed
	andi.   r1, r4, PAGE_VALID
	beq-    dtmh40                  // invalid entry

dtmh30:
#if defined(CPU2_ERRATUM)
	li		r1, 0x3d80
	stw		r1, kErrata(r0)
	lwz		r1, kErrata(r0)
#endif
    mtspr       MD_RPN, r4              // add entry to the TLB

// New entry loaded into the TLB. Restore registers and continue.
//
//      (r0) = condition register
//      (M_TW) = saved R0
//      (SPRG0) = saved R1
//      (SPRG1) = saved R4
//      (SPRG2) = saved R5
//      (SPRG3) = saved R3

	mtcrf   0xff, r0                // restore condition register
	mfspr   r0, M_TW
	mfspr   r1, SPRG0
	mfspr   r4, SPRG1
	mfspr   r5, SPRG2
	mfspr   r3, SPRG3
	rfi

// Invalid address reference. Load invalid entry into the TLB and continue.
// This will cause an ITLB error interrupt.

dtmh40:
	mtcrf   0xff, r0                // restore condition register
	mfspr   r0, M_TW
	mfspr   r1, SPRG0
	mfspr   r3, SPRG3

	li      r4, ID_DPAGE_FAULT      // (r4) = ITLB error interrupt code
	mfspr   r5, DAR
		
	ba      KPageGeneralHandler

// Address in kernel space. For an "un-mapped" space reference, generate
// a large (8mb) TLB entry to map the region.
//

⌨️ 快捷键说明

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