0

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?

adrianmcmenamin
  • 1,081
  • 1
  • 15
  • 44

1 Answers1

1

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.

dkz
  • 921
  • 6
  • 10
  • Thanks, will test later - but surely you are setting bit 13 there in big endian unless the assembler is reversing the bit order. I'm a bit confused :) – adrianmcmenamin Nov 14 '14 at 11:15
  • ah, I see what you mean - the manual has got this all back to front. That is pretty bloody unhelpful. – adrianmcmenamin Nov 14 '14 at 11:19
  • 1
    Yes, unfortunately many BigEndian documents tend to number bits in reverse order, including TCP/IP headers even on [Wikipedia](http://en.wikipedia.org/wiki/IPv4#Header). This tradition is really frustrating and brings a lot of confusion. Needless to say, once you switch your MicroBlaze to LittleEndian, this bit will remain the same `0x00002000`. It's just the documentation. – dkz Nov 14 '14 at 15:36
  • Well it looks like your Microblaze system (or emulator) does not have MMU support as it says. Writing to `TLBHI/LO` does not require VM bit to be set in `rmsr`. Its actually opposite, those registers are accessed with VM=0 and only when everything is set up virtual mode is turned on. Please check your configuration or emulator options. You can also check MB version register `PVR0` to see what Microblaze thinks of its configuration. – dkz Nov 14 '14 at 20:04
  • No, it was me getting mixed up. I have to set the TLB up before I poke at the MSR but otherwise your answer seems to have been correct. – adrianmcmenamin Nov 14 '14 at 21:10