[U-Boot] [PATCH 2/3] net/designware: invalidate entire descriptor in dw_eth_send
Alexey Brodkin
Alexey.Brodkin at synopsys.com
Mon Apr 28 14:05:57 CEST 2014
Dear Ian,
On Sun, 2014-04-27 at 19:47 +0100, Ian Campbell wrote:
> This is the driver for one particular ARM cache controller and not the
> one used for the SoC. In any case it does "proper" start/end handling
> only for cache flush operations, not cache invalidate.
>
> Cache invalidate is a potentially destructive operation (throwing away
> data in the caches), having it operate on anything more than the precise
> region requested would be very surprising to almost anyone I think.
...
> I think you are missing the important differences between a cache
> flush and a cache invalidate.
IMHO cache invalidation and flush operations are sort of antipodes.
With invalidation you discard all data in corresponding line in cache
and replace it with freshly read data from memory.
With flush you move cache line to corresponding memory location
overriding previously existing values in memory.
So if you deal with 2 independent data fields which both share the same
one cache line it's potentially dangerous to do both flush and
invalidate of this cache line.
In case of MMU utilization we have a luxury of uncached access, so we
may safely access control structures in memory with granularity which is
available for this particular CPU. This is AFAIK drivers deal with
buffer descriptors in Linux kernel.
In case of U-Boot where we prefer to keep things simple we don't use
MMU. So no generic way for cache bypassing. Still some architectures
like ARC700 have special instructions for accessing memory bypassing
cache but I prever to not use them and keep sources
platform-independent.
And in this situation IMHO the only safe solution could be in proper
design of data layout. In other words we need to keep independent data
blocks aligned to cache line.
And as you may see from "designware.h" buffer descriptor structure is
aligned:
==============
struct dmamacdescr {
u32 txrx_status;
u32 dmamac_cntl;
void *dmamac_addr;
struct dmamacdescr *dmamac_next;
} __aligned(ARCH_DMA_MINALIGN);
==============
Regards,
Alexey
More information about the U-Boot
mailing list