On Sun, Oct 17, 2010 at 12:33 PM, Maciej W. Rozycki
<macro@linux-mips.org> wrote:
>> where pgd_current is at 0x8054_5008, and PTEBase is 0, 4, 8, 12, ...
>
> It has been always making me wonder (though not as much to go and dig
> through our code ;) ) why Linux is uncapable of using the value presented
> by the CPU in the CP0 Context register as is, or perhaps after a trivial
> operation such as a left-shift by a constant number of bits (where the
> size of the page entry slot assumed by hardware turned out too small).
> There should be no need to add another constant as in the piece of code
> you have quoted -- this constant should already have been preloaded to
> this register when switching the context the last time. The design of the
> TLB refill exception in the MIPS Architecture has been such as to allow
> this register to be readily used as an address into the page table.
On plain old 32-bit MIPS:
The pgd entry for "va" is at address: (unsigned long)pgd + ((va >> 22) << 2)
i.e. each 4-byte entry in the pgd table represents 4MB of virtual address space.
PTEBase only gives you 9 bits to work with. If you use it to store
pgd[31:23] directly, that means every pgd needs to be 8MB-aligned -
ouch.
You could potentially use PTEBase to store more of the significant bits, e.g.
pgd = 0x8000_0000 | (PTEBase << 12)
But that still places limits on where the pgd table can be stored, and
probably adds a decent number of extra arithmetic operations to each
handler.