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