On Sun, 9 Feb 2014, Yann Sionneau wrote:

> Thank you for your answer Matt,
> 
> Le 09/02/14 19:49, Matt Thomas a écrit :
> > On Feb 9, 2014, at 10:07 AM, Yann Sionneau <yann.sionn...@gmail.com> wrote:


> > > Since the kernel runs with MMU on, using virtual addresses, it cannot
> > > dereference physical pointers then it cannot add/modify/remove PTEs,
> > > right?
> > Wrong.  See above.
> You mean that the TLB contains entries which map a physical address to itself?
> like 0xabcd.0000 is mapped to 0xabcd.0000? Or you mean all RAM is always
> mapped but to the (0xa000.000+physical_pframe) kind of virtual address you
> mention later in your reply?

What I did for BookE is reserve the low half of the kernel address space 
for VA=PA mappings.  The kernel resides in the high half of the address 
space.  I did this because the existing PPC port did strange things with 
BAT registers to access physical memory and copyin/copyout operations and 
I couldn't come up with a better way to do something compatible with the 
BookE MMU.  It did limit the machine to 2GB RAM, which wasn't a problem 
for the 405GP.

Also, the user address space is not shared with the kernel address space 
as on most machines.  Instead, user processes get access to their own 4GB 
address space, and the kernel has 2GB to play with when you deduct the 2GB 
VA==PA region.  (It's the same sort of thing I did for sparc64 way back 
when it was running 32-bit userland.  But it doesn't need VA==PA mappings 
and can access physical and userland addresses while the kernel address 
space is active.  Much nicer design.)

When a BookE machine takes an MMU miss fault, the fault handler examines 
the faulting address if the high bit is zero, it synthesizes a TLB entry 
where the physical address is the same as the virtual address.  If the 
high bit is set, it walks the page tables to find the TLB entry.

This did make the copyin/copyout operations a bit complicated since it 
requires flipping the MMU between two contexts while doing the copy 
operation.

> > > Also, is it possible to make sure that everything (in kernel space) is
> > > mapped so that virtual_addr = physical_addr - RAM_START_ADDR +
> > > virtual_offset
> > > In my case RAM_START_ADDR is 0x40000000 and I am trying to use
> > > virtual_offset of 0xc0000000 (everything in my kernel ELF binary is mapped
> > > at virtual address starting at 0xc0000000)
> > > If I can ensure that this formula is always correct I can then use a very
> > > simple macro to translate "statically" a physical address to a virtual
> > > address.
> > Not knowing how much ram you have, I can only speak in generalities.
> I have 128 MB of RAM.
> > But in general you reserve a part of the address space for direct mapped
> > memory and then place the kernel about that.
> > 
> > For instance, you might have 512MB of RAM which you map at 0xa000.0000
> > and then have the kernel's mapped va space start at 0xc000.0000.
> So if I understand correctly, the first page of physical ram (0x4000.0000) is
> mapped at virtual address 0xa000.0000 *and* at 0xc000.0000 ?
> Isn't it a problem that a physical address is mapped twice in the same process
> (here the kernel)?
> My caches are VIPT, couldn't it generate cache aliases issues?

If the MMU is always on while the kernel is running, and covers all of the 
KVA, then you could relocate the kernel text and data segments wherever 
you want them to be.  If you want to put the kernel text and data segments 
in the direct-mapped range, you can easily do that.  If you want it 
elsewhere, that should work too.  

The cache aliasing issues in VIPT caches only occur if the cache way size 
is larger than the page size.  If you're designing your own hardware, 
don't do that.  Otherwise, remember to only access a page through a single 
mapping and you won't have aliasing issues.  And flush the page from the 
cache wenever establishing a new mapping.

Eduardo

Reply via email to