nios2: convert dma mapping to use dm cpu data
PATCH 1/1 nios2: convert dma mapping to use dm cpu data
Convert dma mapping to use dm cpu data.
--- arch/nios2/include/asm/dma-mapping.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
arch/nios2/include/asm/dma-mapping.h +11 -10
@@ -1,23 +1,24 @@#ifndef __ASM_NIOS2_DMA_MAPPING_H#define __ASM_NIOS2_DMA_MAPPING_H -/* dma_alloc_coherent() return cache-line aligned allocation which is mapped +/* +* dma_alloc_coherent() return cache-line aligned allocation which is mapped * to uncached io region. -* -* IO_REGION_BASE should be defined in board config header file -* 0x80000000 for nommu, 0xe0000000 for mmu */ static inline void *dma_alloc_coherent (size_t len,unsigned long *handle) { -void *addr =malloc (len +CONFIG_SYS_DCACHELINE_SIZE ); +DECLARE_GLOBAL_DATA_PTR ; +unsigned long addr = + (unsigned long )malloc (len + gd->arch.dcache_line_size); +if (!addr)return 0 ; -flush_dcache ((unsigned long )addr, len +CONFIG_SYS_DCACHELINE_SIZE ); - *handle = ((unsigned long )addr + - (CONFIG_SYS_DCACHELINE_SIZE -1 )) & - ~(CONFIG_SYS_DCACHELINE_SIZE -1 ) & ~(IO_REGION_BASE ); -return (void *)(*handle |IO_REGION_BASE ); +flush_dcache (addr, len + gd->arch.dcache_line_size); + *handle = (addr + gd->arch.dcache_line_size -1 ) & + ~(gd->arch.dcache_line_size -1 ) & ~gd->arch.io_region_base; + +return (void *)(*handle | gd->arch.io_region_base); }#endif /* __ASM_NIOS2_DMA_MAPPING_H */
Signature · 1 line
2.1.4
PATCH v2 1/1 nios2: convert dma_alloc_coherent to use memalign
Convert dma_alloc_coherent to use memalign.
---
v2
use memalign.
arch/nios2/include/asm/dma-mapping.h | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-)
arch/nios2/include/asm/dma-mapping.h +8 -13
@@ -1,23 +1,18 @@#ifndef __ASM_NIOS2_DMA_MAPPING_H#define __ASM_NIOS2_DMA_MAPPING_H -/* dma_alloc_coherent() return cache-line aligned allocation which is mapped +#include <asm/io.h> + +/* +* dma_alloc_coherent() return cache-line aligned allocation which is mapped * to uncached io region. -* -* IO_REGION_BASE should be defined in board config header file -* 0x80000000 for nommu, 0xe0000000 for mmu */ -static inline void *dma_alloc_coherent (size_t len,unsigned long *handle) { -void *addr =malloc (len +CONFIG_SYS_DCACHELINE_SIZE ); -if (!addr) -return 0 ; -flush_dcache ((unsigned long )addr, len +CONFIG_SYS_DCACHELINE_SIZE ); - *handle = ((unsigned long )addr + - (CONFIG_SYS_DCACHELINE_SIZE -1 )) & - ~(CONFIG_SYS_DCACHELINE_SIZE -1 ) & ~(IO_REGION_BASE ); -return (void *)(*handle |IO_REGION_BASE ); + *handle = (unsigned long )memalign (ARCH_DMA_MINALIGN , len); +flush_dcache_range (*handle, *handle + len); + +return ioremap (*handle, len); }#endif /* __ASM_NIOS2_DMA_MAPPING_H */
Signature · 1 line
2.1.4
PATCH v2 1/1 nios2: convert dma_alloc_coherent to use memalign
Quoted 33 lines · Thomas Chou
Convert
dma_alloc_coherentto use memalign.Signed-off-by Thomas Chou <[email protected]>---
v2
use memalign.arch/nios2/include/asm/dma-mapping.h | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-)(quoted diff) +0
-0
b/arch/nios2/include/asm/dma-mapping.hindex 1350e3b..e3a338d 100644arch/nios2/include/asm/dma-mapping.h +0
-1@@ -1,23 +1,18 @@#ifndef __ASM_NIOS2_DMA_MAPPING_H#define __ASM_NIOS2_DMA_MAPPING_H -/* dma_alloc_coherent() return cache-line aligned allocation which is mapped +#include <
asm/io.h>arch/nios2/include/asm/dma-mapping.h +3
-0+ +/* +* dma_alloc_coherent() return cache-line aligned allocation which is mapped * to uncached io region.
- *
- *IO_REGION_BASEshould be defined in board config header file
- *0x80000000for nommu,0xe0000000for mmu
*/arch/nios2/include/asm/dma-mapping.h +0
-3-static inline void *dma_alloc_coherent (size_t len,unsigned long *handle) { -void *addr =malloc (len +CONFIG_SYS_DCACHELINE_SIZE ); -if (!addr)
arch/nios2/include/asm/dma-mapping.h line 15
Quoted 10 lines
arch/nios2/include/asm/dma-mapping.h +4
-6-return 0 ; -flush_dcache ((unsigned long )addr, len +CONFIG_SYS_DCACHELINE_SIZE ); - *handle = ((unsigned long )addr + - (CONFIG_SYS_DCACHELINE_SIZE -1 )) & - ~(CONFIG_SYS_DCACHELINE_SIZE -1 ) & ~(IO_REGION_BASE ); -return (void *)(*handle |IO_REGION_BASE ); + *handle = (unsigned long )memalign (ARCH_DMA_MINALIGN , len); +flush_dcache_range (*handle, *handle + len); + +return ioremap (*handle, len);
I'd suggest that you do this:
void *reg;
unsigned long *h = memalign(...);flush_dcache_range();
reg = ioremap();
if (!reg)
fail here
*handle = h; // modify handle after we know ioremap succeeded.
return reg;
Quoted 3 lines
}
#endif /*
__ASM_NIOS2_DMA_MAPPING_H*/
Best regards,
Marek Vasut
PATCH v2 1/1 nios2: convert dma_alloc_coherent to use memalign
Hi Marek,
Quoted 6 lines · Marek Vasut
I'd suggest that you do this:
void *reg;
unsigned long *h = memalign(...);flush_dcache_range();
Quoted 8 lines
reg =
ioremap();
if (!reg)
fail here*handle = h; // modify handle after we know ioremap succeeded.
return reg;
Thanks a lot for your suggestion. It is much clear with this.
Best regards,
Thomas
PATCH v2 1/1 nios2: convert dma_alloc_coherent to use memalign
Hi Marek,
I look into the code again. I think it is the memalign() that might fail due to out of memory. While the ioremap() of nios2 won't fail. So I added a check on memalign() return. Please see v3.
Best regards,
Thomas
PATCH v3 1/1 nios2: convert dma_alloc_coherent to use memalign
In reply to Thomas ChouConvert dma_alloc_coherent to use memalign.
---
v2
use memalign.
v3
check memalign() return for out of memory.
arch/nios2/include/asm/dma-mapping.h | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
arch/nios2/include/asm/dma-mapping.h +10 -13
@@ -1,23 +1,20 @@#ifndef __ASM_NIOS2_DMA_MAPPING_H#define __ASM_NIOS2_DMA_MAPPING_H -/* dma_alloc_coherent() return cache-line aligned allocation which is mapped +#include <asm/io.h> + +/* +* dma_alloc_coherent() return cache-line aligned allocation which is mapped * to uncached io region. -* -* IO_REGION_BASE should be defined in board config header file -* 0x80000000 for nommu, 0xe0000000 for mmu */ -static inline void *dma_alloc_coherent (size_t len,unsigned long *handle) { -void *addr =malloc (len +CONFIG_SYS_DCACHELINE_SIZE ); -if (!addr) -return 0 ; -flush_dcache ((unsigned long )addr, len +CONFIG_SYS_DCACHELINE_SIZE ); - *handle = ((unsigned long )addr + - (CONFIG_SYS_DCACHELINE_SIZE -1 )) & - ~(CONFIG_SYS_DCACHELINE_SIZE -1 ) & ~(IO_REGION_BASE ); -return (void *)(*handle |IO_REGION_BASE ); + *handle = (unsigned long )memalign (ARCH_DMA_MINALIGN , len); +if (!*handle) +return NULL ; +flush_dcache_range (*handle, *handle + len); + +return ioremap (*handle, len); }#endif /* __ASM_NIOS2_DMA_MAPPING_H */
Signature · 1 line
2.1.4
PATCH v3 1/1 nios2: convert dma_alloc_coherent to use memalign
Quoted 32 lines · Thomas Chou
Convert
dma_alloc_coherentto use memalign.Signed-off-by Thomas Chou <[email protected]>---
v2
use memalign.
v3
checkmemalign()return for out of memory.arch/nios2/include/asm/dma-mapping.h | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)(quoted diff) +0
-0
b/arch/nios2/include/asm/dma-mapping.hindex 1350e3b..0618dc2 100644arch/nios2/include/asm/dma-mapping.h +0
-1@@ -1,23 +1,20 @@#ifndef __ASM_NIOS2_DMA_MAPPING_H#define __ASM_NIOS2_DMA_MAPPING_H -/* dma_alloc_coherent() return cache-line aligned allocation which is mapped +#include <
asm/io.h>arch/nios2/include/asm/dma-mapping.h +3
-0+ +/* +* dma_alloc_coherent() return cache-line aligned allocation which is mapped * to uncached io region.
- *
- *IO_REGION_BASEshould be defined in board config header file
- *0x80000000for nommu,0xe0000000for mmu
*/arch/nios2/include/asm/dma-mapping.h +0
-1-static inline void *dma_alloc_coherent (size_t len,unsigned long *handle)
arch/nios2/include/asm/dma-mapping.h line 12
Quoted 10 lines
arch/nios2/include/asm/dma-mapping.h +1
-8{ -void *addr =malloc (len +CONFIG_SYS_DCACHELINE_SIZE ); -if (!addr) -return 0 ; -flush_dcache ((unsigned long )addr, len +CONFIG_SYS_DCACHELINE_SIZE ); - *handle = ((unsigned long )addr + - (CONFIG_SYS_DCACHELINE_SIZE -1 )) & - ~(CONFIG_SYS_DCACHELINE_SIZE -1 ) & ~(IO_REGION_BASE ); -return (void *)(*handle |IO_REGION_BASE ); + *handle = (unsigned long )memalign (ARCH_DMA_MINALIGN , len);
This still modifies the handle in both cases (failure and success). We really want to modify external variables in case of failure, no?
arch/nios2/include/asm/dma-mapping.h line 20
Quoted 8 lines
arch/nios2/include/asm/dma-mapping.h +5
-0+if (!*handle) +return NULL ; +flush_dcache_range (*handle, *handle + len); + + return ioremap(*handle, len); }#endif /* __ASM_NIOS2_DMA_MAPPING_H */
Best regards,
Marek Vasut
PATCH v3 1/1 nios2: convert dma_alloc_coherent to use memalign
Hi Marek,
Quoted 4 lines · Marek Vasut
arch/nios2/include/asm/dma-mapping.h line 12
Quoted 1 line
arch/nios2/include/asm/dma-mapping.h +1
-0+ *handle = (unsigned long )memalign (ARCH_DMA_MINALIGN , len);This still modifies the handle in both cases (failure and success). We really want to modify external variables in case of failure, no?
The *handle return a DMA address, and the function itself return a virtual address. Both of them should be set to NULL in case of failure. It might be wrong to keep DMA address looks alive but actually dead.
Best regards,
Thomas Chou
PATCH v3 1/1 nios2: convert dma_alloc_coherent to use memalign
Quoted 1 line · Thomas Chou
Hi Marek,
Hi!
Quoted 8 lines · Marek Vasut
Quoted 4 lines
arch/nios2/include/asm/dma-mapping.h line 12
Quoted 1 line
arch/nios2/include/asm/dma-mapping.h +1
-0+ *handle = (unsigned long )memalign (ARCH_DMA_MINALIGN , len);This still modifies the handle in both cases (failure and success). We really want to modify external variables in case of failure, no?
The *handle return a DMA address, and the function itself return a virtual address. Both of them should be set to NULL in case of failure.
So you depend on this property of memalign(), ok, I see. Thanks for clarifying!
Quoted 1 line
It might be wrong to keep DMA address looks alive but actually dead.
I don't quite understand this sentence, can you please rephrase it ?
Best regards,
Marek Vasut
PATCH v3 1/1 nios2: convert dma_alloc_coherent to use memalign
Hi Marek,
Quoted 3 lines · Marek Vasut
It might be wrong to keep DMA address looks alive but actually dead.
I don't quite understand this sentence, can you please rephrase it ?
Sorry. I meant the *handle, which is the DMA address, should be invalidated to NULL when the allocation failed.
Best regards,
Thomas
PATCH v3 1/1 nios2: convert dma_alloc_coherent to use memalign
Quoted 1 line · Thomas Chou
Hi Marek,
Hi,
Quoted 7 lines · Marek Vasut
Quoted 3 lines
It might be wrong to keep DMA address looks alive but actually dead.
I don't quite understand this sentence, can you please rephrase it ?
Sorry. I meant the *handle, which is the DMA address, should be invalidated to NULL when the allocation failed.
OK
Best regards,
Marek Vasut
PATCH v4 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
In reply to Thomas ChouConvert dma_alloc_coherent to use memalign.
---
v2
use memalign.
v3
check memalign() return for out of memory.
v4
use malloc_cache_aligned().
arch/nios2/include/asm/dma-mapping.h | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-)
arch/nios2/include/asm/dma-mapping.h +11 -13
@@ -1,23 +1,21 @@#ifndef __ASM_NIOS2_DMA_MAPPING_H#define __ASM_NIOS2_DMA_MAPPING_H -/* dma_alloc_coherent() return cache-line aligned allocation which is mapped +#include <memalign.h> +#include <asm/io.h> + +/* +* dma_alloc_coherent() return cache-line aligned allocation which is mapped * to uncached io region. -* -* IO_REGION_BASE should be defined in board config header file -* 0x80000000 for nommu, 0xe0000000 for mmu */ -static inline void *dma_alloc_coherent (size_t len,unsigned long *handle) { -void *addr =malloc (len +CONFIG_SYS_DCACHELINE_SIZE ); -if (!addr) -return 0 ; -flush_dcache ((unsigned long )addr, len +CONFIG_SYS_DCACHELINE_SIZE ); - *handle = ((unsigned long )addr + - (CONFIG_SYS_DCACHELINE_SIZE -1 )) & - ~(CONFIG_SYS_DCACHELINE_SIZE -1 ) & ~(IO_REGION_BASE ); -return (void *)(*handle |IO_REGION_BASE ); + *handle = (unsigned long )malloc_cache_aligned (len); +if (!*handle) +return NULL ; +flush_dcache_range (*handle, *handle + len); + +return ioremap (*handle, len); }#endif /* __ASM_NIOS2_DMA_MAPPING_H */
Signature · 1 line
2.1.4
PATCH v4 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
Quoted 38 lines · Thomas Chou
Convert
dma_alloc_coherentto use memalign.Signed-off-by Thomas Chou <[email protected]>---
v2
use memalign.
v3
checkmemalign()return for out of memory.
v4
usemalloc_cache_aligned().arch/nios2/include/asm/dma-mapping.h | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-)(quoted diff) +0
-0
b/arch/nios2/include/asm/dma-mapping.hindex 1350e3b..bfaf662 100644arch/nios2/include/asm/dma-mapping.h +0
-1@@ -1,23 +1,21 @@#ifndef __ASM_NIOS2_DMA_MAPPING_H#define __ASM_NIOS2_DMA_MAPPING_H -/* dma_alloc_coherent() return cache-line aligned allocation which is mapped +#include <
memalign.h>arch/nios2/include/asm/dma-mapping.h +4
-0+#include <asm/io.h> + +/* +* dma_alloc_coherent() return cache-line aligned allocation which is mapped * to uncached io region.
- *
- *IO_REGION_BASEshould be defined in board config header file
- *0x80000000for nommu,0xe0000000for mmu
*/arch/nios2/include/asm/dma-mapping.h +0
-3-static inline void *dma_alloc_coherent (size_t len,unsigned long *handle) { -void *addr =malloc (len +CONFIG_SYS_DCACHELINE_SIZE ); -if (!addr)
arch/nios2/include/asm/dma-mapping.h line 16
Quoted 10 lines
arch/nios2/include/asm/dma-mapping.h +4
-6-return 0 ; -flush_dcache ((unsigned long )addr, len +CONFIG_SYS_DCACHELINE_SIZE ); - *handle = ((unsigned long )addr + - (CONFIG_SYS_DCACHELINE_SIZE -1 )) & - ~(CONFIG_SYS_DCACHELINE_SIZE -1 ) & ~(IO_REGION_BASE ); -return (void *)(*handle |IO_REGION_BASE ); + *handle = (unsigned long )malloc_cache_aligned (len); +if (!*handle) +return NULL ; +flush_dcache_range (*handle, *handle + len);
Wouldn't invalidate_dcache_range() be enough here ? You don't care about the data in the newly allocated area at this point I guess -- either you fill them in and then flush, for DMA from CPU to device OR you receive data from device to CPU and then you invalidate this buffer again.
arch/nios2/include/asm/dma-mapping.h line 21
Quoted 4 lines
arch/nios2/include/asm/dma-mapping.h +1
-0+ return ioremap(*handle, len); }#endif /* __ASM_NIOS2_DMA_MAPPING_H */
Best regards,
Marek Vasut
PATCH v4 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
Hi Marek,
Quoted 4 lines · Marek Vasut
Wouldn't
invalidate_dcache_range()be enough here ? You don't care about the data in the newly allocated area at this point I guess -- either you fill them in and then flush, for DMA from CPU to device OR you receive data from device to CPU and then you invalidate this buffer again.
No. We cannot use invalidate cache here. This is related to cache design of nios2, kind of direct mapped cache.
Best regards,
Thomas
PATCH v4 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
Quoted 1 line · Thomas Chou
Hi Marek,
Hi Thomas,
Quoted 8 lines · Marek Vasut
Quoted 4 lines
Wouldn't
invalidate_dcache_range()be enough here ? You don't care about the data in the newly allocated area at this point I guess -- either you fill them in and then flush, for DMA from CPU to device OR you receive data from device to CPU and then you invalidate this buffer again.No. We cannot use invalidate cache here. This is related to cache design of nios2, kind of direct mapped cache.
Can you please expand on this ?
btw. I was thinking about this whole cache situation. Please don't get me wrong, my intention is not to put way more work unto you and/or grind you about minor details. I hope it doesn't look that way to you.
Best regards,
Marek Vasut
PATCH v4 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
Hi Marek,
Quoted 11 lines · Marek Vasut
Quoted 1 line · Thomas Chou
Hi Marek,
Hi Thomas,
Quoted 6 lines · Marek Vasut
Quoted 4 lines
Wouldn't
invalidate_dcache_range()be enough here ? You don't care about the data in the newly allocated area at this point I guess -- either you fill them in and then flush, for DMA from CPU to device OR you receive data from device to CPU and then you invalidate this buffer again.
Quoted 4 lines
Quoted 2 lines
No. We cannot use invalidate cache here. This is related to cache design of nios2, kind of direct mapped cache.
Can you please expand on this ?
This is rather hardware depended.
Please refer to page 7 about cache implementation on the "Nios II Core Implementation Detail" manual,
And page 227, 8-44 about initd and initda instructions on the "Nios II Classic Processor Reference Guide",
https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/hb/nios2/n2cpu_nii5v1.pdf
The initda instruction might do the job. But nios2 cpu with 4 bytes dcache line size does not support this instruction. So we don't implement the invalidate_dcache_range/all() in u-boot yet.
Of course, we can add the invalidate cache ops if we can drop the support of nios2 cpu with 4 bytes dcache line size.
Quoted 4 lines
btw. I was thinking about this whole cache situation. Please don't get me wrong, my intention is not to put way more work unto you and/or grind you about minor details. I hope it doesn't look that way to you.
No worries. It is just that I had very little free time last night to give more details. You are welcome.
Best regards,
Thomas
PATCH v4 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
Hi Marek,
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines · Marek Vasut
Quoted 6 lines
Wouldn't
invalidate_dcache_range()be enough here ? You don't care about
the data in the newly allocated area at this point I guess -- either you
fill them in and then flush, for DMA from CPU to device OR you receive data from device to CPU and then you invalidate this buffer again.
Thanks a lot for your suggestion. I added invalidate_dcache_range() which will check if the initda instruction is supported by the nios2 cpu.
Best regards,
Thomas
PATCH v4 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
Quoted 1 line · Thomas Chou
Hi Marek,
Hi!
Quoted 10 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines · Marek Vasut
Quoted 6 lines
Wouldn't
invalidate_dcache_range()be enough here ? You don't care about
the data in the newly allocated area at this point I guess -- either you
fill them in and then flush, for DMA from CPU to device OR you receive data from device to CPU and then you invalidate this buffer again.Thanks a lot for your suggestion. I added
invalidate_dcache_range()which will check if the initda instruction is supported by the nios2 cpu.
Ah, thanks!
Best regards,
Marek Vasut
PATCH v4 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
In reply to Thomas ChouQuoted 1 line · Thomas Chou
Hi Marek,
Hi!
Quoted 26 lines · Marek Vasut
Quoted 12 lines · Thomas Chou
Quoted 1 line
Hi Marek,
Hi Thomas,
Quoted 7 lines · Marek Vasut
Quoted 5 lines
Wouldn't
invalidate_dcache_range()be enough here ? You don't care about the data in the newly allocated area at this point I guess -- either you fill them in and then flush, for DMA from CPU to device OR you receive data from device to CPU and then you invalidate this buffer again.Quoted 4 lines
Quoted 2 lines
No. We cannot use invalidate cache here. This is related to cache design of nios2, kind of direct mapped cache.
Can you please expand on this ?
This is rather hardware depended.
Please refer to page 7 about cache implementation on the "Nios II Core Implementation Detail" manual,
https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/
hb/nios2/n2cpu_nii51015.pdf
Quoted 7 lines
And page 227, 8-44 about initd and initda instructions on the "Nios II Classic Processor Reference Guide",
https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/
hb/nios2/n2cpu_nii5v1.pdfThe initda instruction might do the job.
I'd say that's the instruction we need, yep.
Quoted 3 lines
But nios2 cpu with 4 bytes
dcache line size does not support this instruction. So we don't implement the invalidate_dcache_range/all() in u-boot yet.
Where did you find this information ?
Quoted 9 lines
Of course, we can add the invalidate cache ops if we can drop the support of nios2 cpu with 4 bytes dcache line size.
Quoted 3 lines
btw. I was thinking about this whole cache situation. Please don't get me wrong, my intention is not to put way more work unto you and/or grind you about minor details. I hope it doesn't look that way to you.
No worries. It is just that I had very little free time last night to give more details. You are welcome.
Thanks!
Best regards,
Marek Vasut
PATCH v4 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
Quoted 5 lines · Marek Vasut
Quoted 3 lines
But nios2 cpu with 4 bytes
dcache line size does not support this instruction. So we don't implement the invalidate_dcache_range/all() in u-boot yet.Where did you find this information ?
Please find it on the foot note of table 7, page 8 of "Nios II Core Implementation Detail" manual,
The 4-byte line data cache implementation substitutes the flushd instruction for the flushda
instruction and triggers an unimplemented instruction exception for the initda instruction. The
16-byte and 32-byte line data cache implementations fully support the flushda and initda
instructions.
Best regards,
Thomas
PATCH v4 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
Quoted 10 lines · Thomas Chou
Quoted 5 lines · Marek Vasut
Quoted 3 lines
But nios2 cpu with 4 bytes
dcache line size does not support this instruction. So we don't implement the invalidate_dcache_range/all() in u-boot yet.Where did you find this information ?
Please find it on the foot note of table 7, page 8 of "Nios II Core Implementation Detail" manual,
Quoted 7 lines
The 4-byte line data cache implementation substitutes the flushd instruction for the flushda
instruction and triggers an unimplemented instruction exception for the initda instruction. The
16-byte and 32-byte line data cache implementations fully support the flushda and initda
instructions.
I see, thank you for looking it up for me. This inconsistency is sad :-(
Best regards,
Marek Vasut
PATCH v4 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
In reply to Thomas ChouHello Thomas,
Quoted 10 lines · Thomas Chou
Hi Marek,
Quoted 4 lines · Marek Vasut
Wouldn't
invalidate_dcache_range()be enough here ? You don't care about the data in the newly allocated area at this point I guess -- either you fill them in and then flush, for DMA from CPU to device OR you receive data from device to CPU and then you invalidate this buffer again.No. We cannot use invalidate cache here. This is related to cache design of nios2, kind of direct mapped cache.
Not sure I'm getting this, so for my own education: what prevents from invalidating the cache, or IOW, what would happen if it was invalidated at this point rather than flushed?
Quoted 2 lines
Best regards,
Thomas
Amicalement,
Signature · 1 line
Albert.
PATCH v4 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
Hi Albert,
Quoted 3 lines · Albert ARIBAUD
Not sure I'm getting this, so for my own education: what prevents from invalidating the cache, or IOW, what would happen if it was invalidated at this point rather than flushed?
This is a hardware limitation. The nios2 cpu with 4 bytes dcache line size does not support the initda instruction, which is needed to invalidate dcache.
Recently we added a check, if the nios2 cpu support initda instruction, then we use invalidate_dcache, otherwise we use flush_dcache.
Best regards,
Thomas
PATCH v4 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
Hello Thomas,
Quoted 7 lines · Thomas Chou
Hi Albert,
Quoted 3 lines · Albert ARIBAUD
Not sure I'm getting this, so for my own education: what prevents from invalidating the cache, or IOW, what would happen if it was invalidated at this point rather than flushed?
Quoted 6 lines
This is a hardware limitation. The nios2 cpu with 4 bytes dcache line size does not support the initda instruction, which is needed to invalidate dcache.
Recently we added a check, if the nios2 cpu support initda instruction, then we use
invalidate_dcache, otherwise we useflush_dcache.
Now I understand. Thanks!
Quoted 2 lines
Best regards,
Thomas
Amicalement,
Signature · 1 line
Albert.
PATCH v5 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
In reply to Thomas ChouConvert dma_alloc_coherent to use memalign.
---
v2
use memalign.
v3
check memalign() return for out of memory.
v4
use malloc_cache_aligned().
v5
use invalidate_dcache_range() as Marek suggested.
arch/nios2/include/asm/dma-mapping.h | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-)
arch/nios2/include/asm/dma-mapping.h +11 -13
@@ -1,23 +1,21 @@#ifndef __ASM_NIOS2_DMA_MAPPING_H#define __ASM_NIOS2_DMA_MAPPING_H -/* dma_alloc_coherent() return cache-line aligned allocation which is mapped +#include <memalign.h> +#include <asm/io.h> + +/* +* dma_alloc_coherent() return cache-line aligned allocation which is mapped * to uncached io region. -* -* IO_REGION_BASE should be defined in board config header file -* 0x80000000 for nommu, 0xe0000000 for mmu */ -static inline void *dma_alloc_coherent (size_t len,unsigned long *handle) { -void *addr =malloc (len +CONFIG_SYS_DCACHELINE_SIZE ); -if (!addr) -return 0 ; -flush_dcache ((unsigned long )addr, len +CONFIG_SYS_DCACHELINE_SIZE ); - *handle = ((unsigned long )addr + - (CONFIG_SYS_DCACHELINE_SIZE -1 )) & - ~(CONFIG_SYS_DCACHELINE_SIZE -1 ) & ~(IO_REGION_BASE ); -return (void *)(*handle |IO_REGION_BASE ); + *handle = (unsigned long )malloc_cache_aligned (len); +if (!*handle) +return NULL ; +invalidate_dcache_range (*handle, *handle + len); + +return ioremap (*handle, len); }#endif /* __ASM_NIOS2_DMA_MAPPING_H */
Signature · 1 line
2.1.4
PATCH v6 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
In reply to Thomas ChouConvert dma_alloc_coherent to use memalign.
---
v2
use memalign.
v3
check memalign() return for out of memory.
v4
use malloc_cache_aligned().
v5
use invalidate_dcache_range() as Marek suggested.
v6
defer assignment of handle as Marek suggested.
arch/nios2/include/asm/dma-mapping.h | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-)
arch/nios2/include/asm/dma-mapping.h +14 -13
@@ -1,23 +1,24 @@#ifndef __ASM_NIOS2_DMA_MAPPING_H#define __ASM_NIOS2_DMA_MAPPING_H -/* dma_alloc_coherent() return cache-line aligned allocation which is mapped +#include <memalign.h> +#include <asm/io.h> + +/* +* dma_alloc_coherent() return cache-line aligned allocation which is mapped * to uncached io region. -* -* IO_REGION_BASE should be defined in board config header file -* 0x80000000 for nommu, 0xe0000000 for mmu */ -static inline void *dma_alloc_coherent (size_t len,unsigned long *handle) { -void *addr =malloc (len +CONFIG_SYS_DCACHELINE_SIZE ); +unsigned long addr = (unsigned long )malloc_cache_aligned (len); +if (!addr) -return 0 ; -flush_dcache ((unsigned long )addr, len +CONFIG_SYS_DCACHELINE_SIZE ); - *handle = ((unsigned long )addr + - (CONFIG_SYS_DCACHELINE_SIZE -1 )) & - ~(CONFIG_SYS_DCACHELINE_SIZE -1 ) & ~(IO_REGION_BASE ); -return (void *)(*handle |IO_REGION_BASE ); -} +return NULL ; + +invalidate_dcache_range (addr, addr + len); +if (handle) + *handle = addr; +return ioremap (addr, len); +}#endif /* __ASM_NIOS2_DMA_MAPPING_H */
Signature · 1 line
2.1.4
PATCH v6 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
Quoted 3 lines · Thomas Chou
Convert
dma_alloc_coherentto use memalign.Signed-off-by Thomas Chou <[email protected]>
Thanks!
Best regards,
Marek Vasut
PATCH v6 1/1 nios2: convert dma_alloc_coherent to use malloc_cache_aligned
In reply to Thomas ChouQuoted 15 lines · Thomas Chou
Convert
dma_alloc_coherentto use memalign.Signed-off-by Thomas Chou <[email protected]>---
v2
use memalign.
v3
checkmemalign()return for out of memory.
v4
usemalloc_cache_aligned().
v5
useinvalidate_dcache_range()as Marek suggested.
v6
defer assignment of handle as Marek suggested.
Quoted 3 lines
arch/nios2/include/asm/dma-mapping.h | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-)
Applied to u-boot-nios.