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

J. William Campbell
2009-09-01T17:50:42Z

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
>
>
>