Hi Jeff & Paul,
> sorry to bother you directly, but i'm not on the linux/MIPS mailing
> list yet (by the way, is there an archive?).
It's on the FTP server ftp.fnet.fr.
> i'm can't figure out how the value of TLB_ROOT was derived from
> TLBMAP. (both are in asm-mips/mipsconfig.h). why is TLB_ROOT offset
> at all from TLBMAP? i'm having trouble walking through the TLB
> exception handlers.
The trick is actually simple. The generic Linux mm code assumes a
two (or three - we don't use that) level tree in which the page
tables are arranged. This is this what architectures like i386 or
the MC68851/MC68030/MC68040/MC68060 MMUs assumes. On the other
side the MIPS architecture (check the format of the c0_context
register) assumes the page table information is available in a
flat array. How to combine the two contradictive data structures?
On 32 bit MIPS CPUs we've got an address space of 4gb which is
divided up into pages of 4kb. We map a process' address table
to TLBMAP. Check what happend if we access memory:
1) The CPU takes an exception because there is no mapping in the
2) The TLB exception handler will use the address from c0_context
to load the data from the mm tables mapped at TLBMAP into the
TLB. (This is equivalent to accessing the lowest level of the
mm tree!). We don't care the least bit about accessing unmapped
memory which is why we might fault once again.
3a) After return the program continues normal processing.
This is the normal (fast) path. Now let's assume we get a TLB fault
in step 2) above because the appropriate branch of the tree isn't
mapped in the TLB. The CPU will abort step 2).
3b) We load an entry which maps the the appropriate branch in the
TLBMAP area into the TLB.
3c) Now we can retry step 2) which will always success.
3d) After return the program continues normal processing.
(I left out the special cases like accessing non mapped memory).
In step 3b) we have to take care to avoid another special case. If
we try to access the root of the mm tables mapped at TLBMAP (which
happens to be mapped at TLB_ROOT) - who maps that value there? Due
to the way we handle simple and recursive exceptions nobody would
ever load these entries into the TLB. So we need to map a value
manually there which is what entry #0 in the TLB is reserved for.
If you have understood how the above processing works you will
see how the 4mb pagetables array at TLBMAP is itself mapped at TLB_ROOT.
That's why TLB_ROOT is (TLBMAP + (TLBMAP >> (12-2))).
Note that the value of TLBMAP is choosen such that TLB_ROOT is a
value that can be loaded with a single instruction into a register.
Buys a cycle in the exception handlers :-)
It's also important to say that the exception handling of R3000 and
R4000+ is different. The above code was written with R4k in mind and
also has to take care of cache handling which is a non-issue for the
physical indexed R3k caches.
> do you have any guidance, or do you know of someone else who could
> help me?