I am seeking to set up the TLB on a Microblaze (actually simulated on OVP), and have C_USE_MMU
set to 3
.
This is my boot code:
.global _start
.section .vectors.reset, "ax"
.align 2
.ent _start
.type _start, @function
_start:
brai _actualstart
.end _start
....
.section .text
.global _actualstart
.align 4
.ent _actualstart
.type _actualstart, @function
_actualstart:
mfs r1, rmsr
nop
ori r1, r1, 0x00040000
mts rmsr, r1
nop
addik r3, r0, 0x3F /* Microblaze TLB has 64 entries */
_zeroouttlb:
mts rtlbx, r3
mts rtlbhi, r0
mts rtlblo, r0
bgtid r3, _zeroouttlb /* Uses delay slot */
addik r3, r3, -1
The line below updates r1
to 0x00040000
as you would expect:
ori r1, r1, 0x00040000
But on the next line:
mts rmsr, r1
The value of msr
is left unchanged and so the code goes on to fail on:
mts rtlbhi, r0
With:
Fatal (MB_TLB) Attempting Write to TLBHI when no MMU available
(As msr
has not been updated it still reads 0x00000000
so the processor is correct in assessing there is no MMU support available).
Why won't my code update the msr
?
The problem is that you're setting wrong bit. Many reference guides describing BigEndian architecture assume that bit #31 is 2^0 and bit #0 is 2^31. MicroBlaze manual is one of those using this confusing notation.
In your case if you want to set bit VM (BigEndian bit 18) you need to set msr
to 0x00002000
or 1 << (31-18)
.
So basically changing line:
ori r1, r1, 0x00002000
mts rmsr, r1
nop
should make everything work.