[U-Boot] Virtual addresses, u-boot, and the MMU

J. William Campbell jwilliamcampbell at comcast.net
Tue Sep 1 19:50:42 CEST 2009


      I have followed the recent discussions about problems in the CFI 
driver caused by the need to change the attributes of the address at 
which the flash is mapped. This discussion has raised some questions in 
my mind regarding the assumptions u-boot makes regarding the behavior of 
the addresses used in the code. I am writing this message for comments 
that may correct any mis-understandings I have. First, the addresses 
used by the u-boot program to reference memory and code are all 
"virtual" addresses (VA) because they go through the MMU  to become a 
physical address(PA). If there is no MMU, the virtual address and the 
physical address are identical.
        The "normal", or legacy,policy for u-boot is to arrange a memory 
map such that all physical addresses are mapped to some virtual address. 
Originally, the mapping were such that the VA was actually == the PA, 
but today on some CPUs, this is not possible. When the size of the 
physical address space exceeds the size of the virtual address space, 
the VA may not =- the PA numerically, but there is a one-to-one 
correspondence. It MAY also acceptable to map the same PA so that it 
appears more than once in the address space (VA), but if this is done, 
any references inside u-boot (such as in drivers) must be consistent, 
i.e. the flash chip must exist at exactly one virtual address from 
u-boots viewpoint. This is required because the u-boot drivers maintain 
pointers into the flash, and it is important to be able to compare these 
pointers to input virtual addresses. It is also necessary that the VA of 
the flash chip not change after the driver has been set up, or else any 
saved pointers will be wrong.
      Becky Bruce "re-wrote the driver to use VAs instead of PAs." I am 
not exactly sure what this means, but I assume it meant allowing the VA 
referencing the flash
to be distinct from the PA where the flash "lives" (and may require 36 
bits on a PPC system to represent the PA). Does the driver re-map 
portions of the flash in order to access them? If the flash is really 
large, I can certainly see a need to do so. However, I assume on "medium 
size" flashes, it does not need to remap. In that case, don't all 
references just go through the MMU and get translated? The VA != PA, but 
from the point of view of u-boot, the VA is the only address that 
matters. The AVR32 certainly does not map flash dynamically, so it would 
not matter on that CPU.
      The issue with the CFI driver on the AVR32 is that it needs to 
disable cache on the address space of the flash memory when it is 
writing to the flash. This apparently is not trivial to do, but there is 
a second mapping that does have the cache off. Wolfgang has recommended 
the creation of a function to turn off the cache for the flash area, and 
also (presumably) one to turn the flash back on when the write is 
complete. Haavard has at present a function that returns an alternate 
address with the cache already off that addresses the same memory. This 
wouldn't cause a problem if the mapping happened immediately before the 
actual copy operation took place and was used for nothing else. However, 
if it happens early on in the driver, the address will not match the 
structure set up by the rest of the flash code using the non-translated 
address.
        Therefore, I have the following questions: If the map_physmem() 
macro is removed from the driver on the AVR32, does the driver work if 
it is told that the flash PA=VA = the un-cached address? If not, why 
not? Shouldn't this be just like any CFI on an un-cached PPC address? 
The driver will be somewhat slower reading but otherwise it should work. 
If/when it does work, couldn't a map_in_cache() macro be placed directly 
in front of the read code that copies data from flash to other buffers. 
The macro would return an address of the same data referenced through a 
cached address if it exists. This address would go nowhere else and 
never be stored anywhere. This would speed up the copy operation for 
situations where it matters, and is applicable to all platforms that can 
do such a thing. The most general solution would be a call to 
map_in_cache/map_in_not_cache for both reads and writes in the CFI 
driver. These routines would return a "substitute" address (or the same 
input one), and may actually add another mapping dynamically, use a 
pre-existing appropriate mapping, just turn on/turn off data cache 
globally, or do nothing). At the end of the copy, map_restore() would 
put the map back  By default, the assumption would be that the flash is 
not cached and the macros do nothing. Sounds simple to me, what have I 
overlooked?

Bill Campbell
> Haavard Skinnemoen wrote:
>
> <snip>
>
>   
>> Right...I'm beginning to doubt that anyone is familiar enough with the
>> u-boot code, since everyone seems to have their own opinion about how
>> things are supposed to work.
>>
>> To summarize, here are the possible ways to fix the problem as I see it:
>>   - Use virtual address in CONFIG_ENV_ADDR to conform with the way the
>>     CFI driver currently works. Rejected by Wolfgang because virtual
>>     addresses don't exist.
>>   - Fix the API and user interface breakage by reverting commit
>>     09ce9921. Rejected because virtual addresses are used everywhere.
>>   - Fix it by using map_physmem() in a way that works for all
>>     architectures. Rejected because all other architectures than PPC
>>     are evil and need to be punished for doing things differently.
>>     
>
> Your "triple revert" patch doesn't look overly complex, and seems to only
> add a few map_physmem() calls (I'm summarising *quite* a bit there !!).
>
> Is there not some way using weak functions (or similar) to add some AVR32
> specific workarounds.
>
> Or ... there's *plenty* of arch specific #ifdefs in most of the rest of
> u-boot, so could we not just "#ifdef AVR32" the existing code for the
> time being until this sticking point gets unstuck ?
>
>   
>>   - Introduce a custom flash driver for ATNGW100. Rejected because
>>     stupid principles are more important than making things work.
>>
>> So I don't really know where to proceed from here. I guess two
>> additional options are forking the damn thing or creating a proprietary
>> bootloader, but I don't really want to do either.
>>     
>
> Me neither !!
>
> Mark
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
>
>   



More information about the U-Boot mailing list