summaryrefslogtreecommitdiffstats
path: root/arch/mips/doc
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
committer <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
commitbeb116954b9b7f3bb56412b2494b562f02b864b1 (patch)
tree120e997879884e1b9d93b265221b939d2ef1ade1 /arch/mips/doc
parent908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff)
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'arch/mips/doc')
-rw-r--r--arch/mips/doc/pagetables.txt87
1 files changed, 87 insertions, 0 deletions
diff --git a/arch/mips/doc/pagetables.txt b/arch/mips/doc/pagetables.txt
new file mode 100644
index 000000000..3d900a194
--- /dev/null
+++ b/arch/mips/doc/pagetables.txt
@@ -0,0 +1,87 @@
+Format and handling of Linux/MIPS pagetables
+============================================
+
+This file describes the MIPS specific parts of the Linux pagetable handling.
+
+Opposed to other architecures like i386 or m68k architecture all MIPS
+CPUs only implement the TLB itself and a small set of functions to
+maintain it as hardware. The actual maintenance of the TLB's contents
+is implemented in software only.
+
+The TLB has a relativly small number of entries. This limits the
+maximum address space that can mapped by the TLB using 4kb pages and
+without consideration of wired entries to a maximum of 512kb for the
+R1000, 384kb for the R4000/4400 and 256kb for the R2000/R3000. This
+actual size of mappable space is even smaller due to the wired entries.
+
+Especially for processes with a huge working set of pages it is therefore
+important to make the process of reloading entries into the TLB as
+efficient as possible. This means:
+
+ - Choosing a data structure that can be handled as efficient as
+ possible.
+ - The implementation of the low level pagefault handling has to be
+ implemented in a efficient way.
+
+The Linux kernel itself implements three level page tables as a tree
+structure. Linux implementations that don't need three levels of page
+tables can fold one level of the page tables so that effectivly a two
+level page table remains. The exact size and content of the entries
+is upto the implementation.
+
+Opposed to this the MIPS hardware architecture implies by the data
+provided in the c0_context/c0_xcontext registers a simple array of
+4 byte elements (for R2000/R3000/R6000) or 8 byte elements (for the
+other 64bit members of the CPU family).
+
+The page tables are mapped to the address TLBMAP (which is usually
+defined as 0xe4000000 in <asm/mipsconfig.h). The page which contains
+the root of the page table of the current process, the "page directory"
+and is therefore mapped at (TLBMAP + (TLBMAP >> (12-2))) (this is the
+value of the define TLB_ROOT which is defined as 0xe4390000). That
+way the kernel itself can access the page tables as a tree structure
+while the exception handlers can work with maxiumum efficiency accessing
+the page tables as simple array.
+
+The tlb refill handler itself is very simple. For the R4x00 family it
+has just 14 instruction, for the R4600 and derivatives it can be
+optimized to 12 instruction, even further for the R10000. This
+exception handler is very simple and fast and therefore doesn't any
+checking for errors or special cases.
+
+It can therefore happen that the entry that is attempted to be reloaded
+isn't mapped via the pagetables thus resulting in a double tlb refill
+exception. Due to the EXL flag set in c0_status this exception goes
+through the general exception vector and from there to handle_tlbl.
+Handle_tlbl is a more complex exception handler that is - compared
+to the first handler - complex and called far less often. It features
+handling of special cases and some error checking for debugging. This
+second handler still doesn't reenable interrupts, change to the kernel
+stack or save registers to be as efficient as possible. Therefore
+only the two registers k0/k1 are available for use. All this is only
+done when do_page_fault() in arch/mips/mm/fault.c is called. For the
+normal case this handler just reloads the entry mapping the pte table
+which again contains the entries to be loaded in the tlb. Since the
+original fault address has been lost this exception handler cannot
+complete the job. So it just returns to the main program which after
+taking another exception via the first tlb refill handler reloads the
+originally missing entry into the TLB and continues normal execution.
+
+Another special in the Linux/MIPS page handling is the handling of
+pages in non-existant branches of the page tables. To avoid that
+the exception handlers have to handle this special case the kernel
+maps these ptes (page table entries) to invalid_pte_table. This is a
+4kb page full of invalid entries. On an attempted access to such an
+invalid page the kernel then reloads - eventuall via a double fault
+this invalid entry into the tlb. The CPU then takes a tlb invalid
+exception resulting in a call to do_page_fault() which usually will
+take the apropriate measures like sending SIGSEGV.
+
+Downsides of this implementation are it's complexity and the faster
+handling of the majority of exceptions is bought at the expense of
+having to handle page aliasing problems with the page tables (which
+are accessed at TLBMAP and in KSEG1) itself. This is done using
+uncached accesses which are especially on older machines with slow
+memory subsystems painfully slow. The implementation is done this
+way because for the original hardware which Linux/MIPS was intended for
+had a blindingly fast memory interface.