You may have to implement a custom TLB miss handler for MIPS on Windows CE 3.0 (841192)



The information in this article applies to:

  • Microsoft Windows CE Platform Builder 3.0

SYMPTOMS

Some MIPS processors require more instructions to fill the hazard area after the MTC0 instruction than the MIPS R4000 series processors require. When the hazard area is not filled with instructions such as no-operation (NOP) instructions, code may incorrectly execute.

CAUSE

Microsoft Windows CE 3.0 is only designed to work on the following MIPS processors:
  • MIPS R3000
  • MIPS R4100
  • MIPS R4111
  • MIPS R4200
  • MIPS R4300
Some OEMs used a MIPS processor that claimed to be compatible with one of these processors. However, these OEMs found that small differences in coding techniques are required when you work with the microprocessor control registers. The translation lookaside buffer (TLB) miss exception handler is one location where you may have to change the use of the microprocessor control registers.

RESOLUTION

To resolve this problem, choose a MIPS processor that is compatible with Windows CE 3.0. To see the list of microprocessors that are compatible with Windows CE 3.0, visit the following Microsoft Developer Network (MSDN) Web site:

WORKAROUND

To work around this problem, implement a custom TLB miss handler. The Windows CE 3.0 startup code copies the TLB miss handler for a MIPS processor from ROM to RAM at the exception vector address. This 128-byte region is sufficient to hold the TLB miss handler that is provided in the MIPS version of the Windows CE kernel. To allow for a larger TLB miss handler, you must relocate the whole handler, and you must insert a stub handler in the exception vector address to jump to the replacement handler. The replacement handler must use the Windows CE kernel information to perform required operations, but you can expand the replacement handler as needed.

Use the following code examples to implement the replacement TLB miss handler for a MIPS R4300 version of Windows CE 3.0.

Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure, but they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements. You must put the following lines of code in the OEMInit function of the OEM adaptation layer (OAL).
 extern void InitOEMTLBMiss();

...

	lpWriteDebugStringFunc(TEXT("Installing OEM defined TLB Miss Handler for MIPS.\r\n"));
	InitOEMTLBMiss();
You must put the following lines of code in a MIPS assembler source file that is built into the OAL.
//------------------------------------------------------------------------------
//
// OEM TLB Miss Handler
//
// These definitions are valid for the R4300 build of the kernel.
//      
//------------------------------------------------------------------------------

// Bit offsets of block & section in a virtual address:
#define VA_BLOCK        16
#define VA_SECTION      25

#define VA_PAGE         12
#define PAGE_MASK       0x00F

#define BLOCK_MASK      0x1FF
#define SECTION_MASK	0x03F

#define mb_lock     0
#define mb_pages    12

#define		SaveT0			KPAGE_BASE + 0x888
#define		SaveK1			KPAGE_BASE + 0x88c
#define		CurAKey			KPAGE_BASE + 0x89c
#define		SectionTable	KPAGE_BASE + 0x8C0



//------------------------------------------------------------------------------
//
// OEMTLBMissHandler - Required modifications can be made here.
//      
//------------------------------------------------------------------------------

LEAF_ENTRY(OEMTLBMissHandler)
		.set    noreorder
		.set    noat

		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 
		lw		k1, SaveK1				//    :
		tlbwr							// write entry randomly into TLB:
		nop								//    :
		nop								// 3 cycle hazard  :
70:		eret							//    :
 
80:		lw		k1, SaveK1		//    :
		.word 0x08000060		//	  j 0x80000180   :
		lw		t0, SaveT0		//    :
 
		.set    reorder
		.set    at
		.end OEMTLBMissHandler

//------------------------------------------------------------------------------
//
// StubTLBMissHandler
//
// Generic stub handler - no modification is required.
//      
//------------------------------------------------------------------------------

LEAF_ENTRY(StubTLBMissHandler)
        .set noreorder

        la      k0, OEMTLBMissHandler      // Load address of real handler :0-1
        j       k0                      //                              :2
        nop                             //                              :3
        
        END_REGION(StubTLBMissHandler_End)

        .set    reorder
        .set    at
        .end    StubTLBMissHandler

//------------------------------------------------------------------------------
//
// AlternateTLBInit
//
// Patches stub handler into exception area - no modification is required.
//      
//------------------------------------------------------------------------------


LEAF_ENTRY(InitOEMTLBMiss)
		.set	noreorder
		// Install TLBMiss handler
		li		a0, 0x0000
		la		a1, StubTLBMissHandler
		la		a2, StubTLBMissHandler_End

		subu	sp,4			// save ra
		sw		ra,0(sp)
		jal		InstallHandler
		nop
		lw		ra,0(sp)		// restore ra
		addu	sp,4


		j		ra
		nop
		.set	reorder
		.end	InitOEMTLBMiss

STATUS

This behavior is by design.

Modification Type:MinorLast Reviewed:8/18/2005
Keywords:kbOSWinCE300fix KB841192 kbAudOEM