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

📄 ppc403.s

📁 wince下的源代码集合打包
💻 S
📖 第 1 页 / 共 2 页
字号:
    mfspr    r5, SPRG2
    mfspr    r6, SPRG3
    rfi

//
// 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 (16mb) TLB entry to map the region.  For an api call, jump to
// the initial api handler code in the KPage.
//
//    (r3) = saved CR value
//    (r5) = missing virtual address
//    (M_TW) = saved R0
//    (SPRG0) = saved R3
//    (SPRG1) = saved R4
//    (SPRG2) = saved R5
//    (SPRG3) = saved R6
//

TBKSpace:

	lis     r6, API_MAX >> 16
	ori     r6, r6, API_MAX & 0xFFFF
	cmplw	r6, r5
	bgt-	TBKMap 			                    // 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 r11, r12, and CR0.
//

    subi    r11, r5, FIRST_METHOD               // FIRST_METHOD based index
    mfspr   r12, SRR1
    mfspr   r3, SPRG0
    mfspr   r4, SPRG1
    mfspr   r5, SPRG2
    mfspr   r6, SPRG3
    ba      KPageAPIHandler

//
//  Invalid address.
//  Set up parameters and branch to the General exception handler.
//
//  (r5) == Exception address
//

ITBInvalid:

    li      r4, ID_CPAGE_FAULT                      // Exception type in r4

    mtcr    r3                                      // restore saved parms
    mfspr   r3, SPRG0
    mfspr   r6, SPRG3

    ba      KPageGeneralHandler

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


//
// Instruction TLB error 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
//
//

ITBError:		
	mtspr	SPRG1, r4
	mtspr	SPRG2, r5
	li	r4, ID_CPAGE_FAULT	// (r4) = ITLB error interrupt code
	mfspr	r5, SRR0
	ba	KPageGeneralHandler	

//   .org   ITBError + 0x100	

	
//  Data TLB error handler
//
//	Entry:	(MSR)   External interrupts disabled
//              	Instruction Relocate OFF
//              	Data Relocate OFF
//		(DEAR)	Instruction address at time of interrupt
//      	(SRR1)	MSR at time of interrupt
//

	
DTBError:

	mtspr	SPRG1, r4
	mtspr	SPRG2, r5
	li	r4, ID_DPAGE_FAULT
	mfspr	r5, DEAR
	ba	KPageGeneralHandler     // Call the general exception handler

//    .org    DTBError+0x100
	
//
//  ClockHandler
//
//  The clock interrupts are routed on the PPC403 so that the PIT, FIT, and
//  watchdog timers all dispatch to the 0x10xx exception vectors. Since there
//  is not an architected PowerPC Timer interrupt, the kernel will simply
//  convert these to hardware interrupts, and dispatch them via
//  OEMInterruptHandler.
//
//

ClockHandler:

    ba      0x0500                      // Offset 0x1000    - PIT Interrupt
    nop
    nop
    nop
    ba      0x0500                      // Offset 0x1010    - FIT Interrupt
    nop
    nop
    nop
    ba      0x0500                      // Offset 0x1020    - Watchdog int.

ClockHandlerEnd:


//
//
//  TLBInit
//
//  Perform the processor specific TLB Initialization:
//
//  Any processor specific TLB initialization is performed here, and two
//  fixed translations are created:
//  
//  1) KSEG Mapping. All address with bit 0 set are mapped 1-to-1
//
//  2) KPage Mapping. The KPAGE is mapped Virtual=Physical. The mapping
//                    is writable and executable in kernel mode, but
//                    read-only in user mode
//
//
// Parameters:
//
// r3 - Address of OEMMemoryMap of Physical -> Virtual mappings
//

    LEAF_ENTRY(TLBInit)

// 
// Build up the Virtual to Physical translation table for the 512MB superpage.
// This table is based upon the Physical to Virtual mappings stored in
// OEMMemoryMap.
// 
// 

// Translate OEMMemoryMap to KPfnMap
//	(r4)	Virtual Address
//	(r5)	Physical Address
//	(r6)	Size

KPFNMapStart:

	// Get entry size
	lwz		r6, 8(r3)

	// Divide size by 16.  This gives us the number of 
	// KPFN entries covered.
	srawi	r6, r6, 4

	// If the size is zero, we're done
	cmpi	0, 0, r6, 0
	beq		KPFNMapDone
		
	// Get physical and virtual address
	lwz		r4, 0(r3)
	lwz		r5, 4(r3)

	// For each address, rotate the upper byte into the low byte 
	// and mask it off.
    rlwinm  r4, r4, 8, 0x0000001F       // KSEG address high byte.  Bits 31-29 are always 100.
    rlwinm  r5, r5, 8, 0x000000FF       // Physical address high byte.

	// Now fill the KPFN entries
	mtctr	r6
FillLoop:
	stb		r5, kPFNMap(r4)
	addi	r4, r4, 1
	addi	r5, r5, 1
	bdnz FillLoop
	
	// Next entry...
	addi	r3, r3, 12
	b		KPFNMapStart

KPFNMapDone:

//
//	Init TLBs
//

    tlbia                                       // clear out all TLB entries

//
//  Set up the Zone Protection Register (ZPR) for the zones used by
//  the TLB entries
//

    LWI(r3, ZPR_INIT)
    mtspr   ZPR, r3

    li      r3, 0
    mtspr   PID, r3                             // Setup PID for global mappings
    isync

//
// Load reserved entry for KPage into the Data TLB.
// The KPage is mapped so that <KPAGE Virtual> == <KPAGE Physical> == KPAGE_BASE
// The KPage is actually 4KB (four one-K pages) mapped as a single page
//
//  Map user mode only for the 2 pages at 0x5800 (requires 2 more tlbs)
//

    li      r4, TB_KPAGE                        // load TB index
    li      r3, (KPAGE_BASE | PG_PROT_EXECUTE | PTE_ZONE2)
#if UNCACHED
    ori     r3, r3, PG_NOCACHE      // Disable kpage caching for testing
#endif
    tlbwelo r3, r4                              // write low part

    li      r3, (KPAGE_BASE | 0xc0)             // Set EPN, Valid, Size=4KB
    tlbwehi r3, r4                              // write high part
    
    isync                                       // Sync the istream

    LEAF_EXIT(TLBInit)


//
//  FlushTLB
//
//  Flush all TLB entries.
//
//  Use tlbia to invalidate all entries, and then refill the reserved KPage
//  translation
//

    LEAF_ENTRY(FlushTLB)

    //
    //  Prevent interrupt from occuring between tlbia and the
    //  KPage translation update:
    //
    
    mfmsr   r6
	rlwinm	r0, r6, 0, ~MSR_EE
    mtmsr   r0

    //
    //  Set PID to zero. KSeg TBMiss following tlbia will be global
    //

    mfspr   r5, PID                             // save the current PID value
    li      r3, 0                               // set PID=0 for shared entry
    mtspr   PID, r3
    isync

    tlbia                                       // Invalidate all entries
    isync                                       // Ensure ITLB consistent

    //
    //  Reset the valid bit for the reserved Kpage translation:
    //  PID == 0. This is a global translation:
    //

    li      r4, TB_KPAGE                        // KPage translation index
    tlbrehi r3, r4                              // read the translation
    ori     r3, r3, PTE_VALID | PTE_LE          // set the valid and little
                                                //   endian bits
    tlbwehi r3, r4                              // and update the entry

    mtspr   PID, r5                             // restore original PID
    isync
    mtmsr   r6                                  // restore MSR

    LEAF_EXIT(FlushTLB)




// SetPID - set PID register
//
// This function is needed because the C compiler won't accept registers
// it doesn't know about in the _sregister_set() call.
//
//	Entry	(r3) = new address space ID
//	Exit	none
//	Uses	none

    LEAF_ENTRY(SetPID)

    isync
    mtspr PID, r3
    isync

    LEAF_EXIT(SetPID)



//
//  LEAF_ENTRY(CPUIdentify)
//
//  Returns information about the current processor.
//
//  Entry   none
//  Exit    (r3) = Processor type (401 or 403)
//
    LEAF_ENTRY(CPUIdentify)

    //  The MEM (Family Member) field of the PVR (PVR[12:15]) is used to
    //  determine if we have a 401 or 403.
    //  MEM=0x1  =>  401
    //  MEM=0x0  =>  403
    //
    //  PVR          CPU
    //  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    //  0x00200200 - 403GC
    //  0x00201400 - 403GCX
    //  0x0022xxxx - 401B2
    //  0x0023xxxx - 401C2
    //  0x0024xxxx - 401D2

    mfspr   r4, PVR                     // Grab the PVR
    rlwinm. r4, r4, 0, 0x00070000       // PVR[12:15]
    li      r3, 403                     // Assume 403
    beq     ProcType403                 // MEM == 0 so have a 403

ProcType401:                            // Have a 401
    li      r3, 401

ProcType403:

    LEAF_EXIT(CPUIdentify)

⌨️ 快捷键说明

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