* [U-Boot] [PATCH v3] nios2: convert cache flush to use dm cpu data
[not found] <1444119600-31999-1-git-send-email-thomas@wytron.com.t>
@ 2015-10-14 1:38 ` Thomas Chou
2015-10-16 23:00 ` Marek Vasut
2015-10-18 23:48 ` Thomas Chou
0 siblings, 2 replies; 5+ messages in thread
From: Thomas Chou @ 2015-10-14 1:38 UTC (permalink / raw)
To: u-boot
Convert cache flush to use dm cpu data.
The original cache flush functions are written in assembly
and use CONFIG_SYS_{I,D}CACHE_SIZE... macros. It is difficult
to convert to use cache configuration in dm cpu data which is
extracted from device tree.
The cacheflush.c of Linux nios2 arch uses cpuinfo structure,
which is very close to our dm cpu data. So we copy and modify
it to arch/nios2/lib/cache.c to replace the old cache.S.
Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
---
v2
change commit message.
v3
check initda instruction support.
add invalidate_dcache_range().
arch/nios2/include/asm/cache.h | 13 ++---
arch/nios2/lib/bootm.c | 6 +--
arch/nios2/lib/cache.S | 68 ------------------------
arch/nios2/lib/cache.c | 114 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 118 insertions(+), 83 deletions(-)
delete mode 100644 arch/nios2/lib/cache.S
create mode 100644 arch/nios2/lib/cache.c
diff --git a/arch/nios2/include/asm/cache.h b/arch/nios2/include/asm/cache.h
index 9b87c9f..dde43cd 100644
--- a/arch/nios2/include/asm/cache.h
+++ b/arch/nios2/include/asm/cache.h
@@ -8,18 +8,11 @@
#ifndef __ASM_NIOS2_CACHE_H_
#define __ASM_NIOS2_CACHE_H_
-extern void flush_dcache (unsigned long start, unsigned long size);
-extern void flush_icache (unsigned long start, unsigned long size);
-
/*
- * Valid L1 data cache line sizes for the NIOS2 architecture are 4, 16, and 32
- * bytes. If the board configuration has not specified one we default to the
- * largest of these values for alignment of DMA buffers.
+ * Valid L1 data cache line sizes for the NIOS2 architecture are 4,
+ * 16, and 32 bytes. We default to the largest of these values for
+ * alignment of DMA buffers.
*/
-#ifdef CONFIG_SYS_CACHELINE_SIZE
-#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE
-#else
#define ARCH_DMA_MINALIGN 32
-#endif
#endif /* __ASM_NIOS2_CACHE_H_ */
diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c
index c730a3f..4e5c269 100644
--- a/arch/nios2/lib/bootm.c
+++ b/arch/nios2/lib/bootm.c
@@ -6,9 +6,6 @@
*/
#include <common.h>
-#include <command.h>
-#include <asm/byteorder.h>
-#include <asm/cache.h>
#define NIOS_MAGIC 0x534f494e /* enable command line and initrd passing */
@@ -40,8 +37,7 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima
/* flushes data and instruction caches before calling the kernel */
disable_interrupts();
- flush_dcache((ulong)kernel, CONFIG_SYS_DCACHE_SIZE);
- flush_icache((ulong)kernel, CONFIG_SYS_ICACHE_SIZE);
+ flush_dcache_all();
debug("bootargs=%s @ 0x%lx\n", commandline, (ulong)&commandline);
debug("initrd=0x%lx-0x%lx\n", (ulong)initrd_start, (ulong)initrd_end);
diff --git a/arch/nios2/lib/cache.S b/arch/nios2/lib/cache.S
deleted file mode 100644
index 683f005..0000000
--- a/arch/nios2/lib/cache.S
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
- * Scott McNutt <smcnutt@psyent.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <config.h>
-
- .text
-
- .global flush_dcache
-
-flush_dcache:
- add r5, r5, r4
- movhi r8, %hi(CONFIG_SYS_DCACHELINE_SIZE)
- ori r8, r8, %lo(CONFIG_SYS_DCACHELINE_SIZE)
-0: flushd 0(r4)
- add r4, r4, r8
- bltu r4, r5, 0b
- ret
-
-
- .global flush_icache
-
-flush_icache:
- add r5, r5, r4
- movhi r8, %hi(CONFIG_SYS_ICACHELINE_SIZE)
- ori r8, r8, %lo(CONFIG_SYS_ICACHELINE_SIZE)
-1: flushi r4
- add r4, r4, r8
- bltu r4, r5, 1b
- ret
-
- .global flush_dcache_range
-
-flush_dcache_range:
- movhi r8, %hi(CONFIG_SYS_DCACHELINE_SIZE)
- ori r8, r8, %lo(CONFIG_SYS_DCACHELINE_SIZE)
-0: flushd 0(r4)
- add r4, r4, r8
- bltu r4, r5, 0b
- ret
-
- .global flush_cache
-
-flush_cache:
- add r5, r5, r4
- mov r9, r4
- mov r10, r5
-
- movhi r8, %hi(CONFIG_SYS_DCACHELINE_SIZE)
- ori r8, r8, %lo(CONFIG_SYS_DCACHELINE_SIZE)
-0: flushd 0(r4)
- add r4, r4, r8
- bltu r4, r5, 0b
-
- mov r4, r9
- mov r5, r10
- movhi r8, %hi(CONFIG_SYS_ICACHELINE_SIZE)
- ori r8, r8, %lo(CONFIG_SYS_ICACHELINE_SIZE)
-1: flushi r4
- add r4, r4, r8
- bltu r4, r5, 1b
-
- sync
- flushp
- ret
diff --git a/arch/nios2/lib/cache.c b/arch/nios2/lib/cache.c
new file mode 100644
index 0000000..1108055
--- /dev/null
+++ b/arch/nios2/lib/cache.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
+ * Copyright (C) 2009, Wind River Systems Inc
+ * Implemented by fredrik.markstrom at gmail.com and ivarholmqvist at gmail.com
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/cache.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void __flush_dcache(unsigned long start, unsigned long end)
+{
+ unsigned long addr;
+
+ start &= ~(gd->arch.dcache_line_size - 1);
+ end += (gd->arch.dcache_line_size - 1);
+ end &= ~(gd->arch.dcache_line_size - 1);
+
+ for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
+ __asm__ __volatile__ (" flushda 0(%0)\n"
+ : /* Outputs */
+ : /* Inputs */ "r"(addr)
+ /* : No clobber */);
+ }
+}
+
+static void __flush_dcache_all(unsigned long start, unsigned long end)
+{
+ unsigned long addr;
+
+ start &= ~(gd->arch.dcache_line_size - 1);
+ end += (gd->arch.dcache_line_size - 1);
+ end &= ~(gd->arch.dcache_line_size - 1);
+
+ if (end > start + gd->arch.dcache_size)
+ end = start + gd->arch.dcache_size;
+
+ for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
+ __asm__ __volatile__ (" flushd 0(%0)\n"
+ : /* Outputs */
+ : /* Inputs */ "r"(addr)
+ /* : No clobber */);
+ }
+}
+
+static void __invalidate_dcache(unsigned long start, unsigned long end)
+{
+ unsigned long addr;
+
+ start &= ~(gd->arch.dcache_line_size - 1);
+ end += (gd->arch.dcache_line_size - 1);
+ end &= ~(gd->arch.dcache_line_size - 1);
+
+ for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
+ __asm__ __volatile__ (" initda 0(%0)\n"
+ : /* Outputs */
+ : /* Inputs */ "r"(addr)
+ /* : No clobber */);
+ }
+}
+
+static void __flush_icache(unsigned long start, unsigned long end)
+{
+ unsigned long addr;
+
+ start &= ~(gd->arch.icache_line_size - 1);
+ end += (gd->arch.icache_line_size - 1);
+ end &= ~(gd->arch.icache_line_size - 1);
+
+ if (end > start + gd->arch.icache_size)
+ end = start + gd->arch.icache_size;
+
+ for (addr = start; addr < end; addr += gd->arch.icache_line_size) {
+ __asm__ __volatile__ (" flushi %0\n"
+ : /* Outputs */
+ : /* Inputs */ "r"(addr)
+ /* : No clobber */);
+ }
+ __asm__ __volatile(" flushp\n");
+}
+
+void flush_dcache_all(void)
+{
+ __flush_dcache_all(0, gd->arch.dcache_size);
+ __flush_icache(0, gd->arch.icache_size);
+}
+
+void flush_dcache_range(unsigned long start, unsigned long end)
+{
+ if (gd->arch.has_initda)
+ __flush_dcache(start, end);
+ else
+ __flush_dcache_all(start, end);
+}
+
+void flush_cache(unsigned long start, unsigned long size)
+{
+ if (gd->arch.has_initda)
+ __flush_dcache(start, start + size);
+ else
+ __flush_dcache_all(start, start + size);
+ __flush_icache(start, start + size);
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+ if (gd->arch.has_initda)
+ __invalidate_dcache(start, end);
+ else
+ __flush_dcache_all(start, end);
+}
--
2.1.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [U-Boot] [PATCH v3] nios2: convert cache flush to use dm cpu data
2015-10-14 1:38 ` [U-Boot] [PATCH v3] nios2: convert cache flush to use dm cpu data Thomas Chou
@ 2015-10-16 23:00 ` Marek Vasut
2015-10-17 6:54 ` Thomas Chou
2015-10-18 23:48 ` Thomas Chou
1 sibling, 1 reply; 5+ messages in thread
From: Marek Vasut @ 2015-10-16 23:00 UTC (permalink / raw)
To: u-boot
On Wednesday, October 14, 2015 at 03:38:39 AM, Thomas Chou wrote:
> Convert cache flush to use dm cpu data.
>
> The original cache flush functions are written in assembly
> and use CONFIG_SYS_{I,D}CACHE_SIZE... macros. It is difficult
> to convert to use cache configuration in dm cpu data which is
> extracted from device tree.
>
> The cacheflush.c of Linux nios2 arch uses cpuinfo structure,
> which is very close to our dm cpu data. So we copy and modify
> it to arch/nios2/lib/cache.c to replace the old cache.S.
>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Hi!
[...]
> +static void __flush_dcache(unsigned long start, unsigned long end)
> +{
> + unsigned long addr;
> +
> + start &= ~(gd->arch.dcache_line_size - 1);
> + end += (gd->arch.dcache_line_size - 1);
> + end &= ~(gd->arch.dcache_line_size - 1);
I really don't think we should do this alignment here :-(
> + for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
> + __asm__ __volatile__ (" flushda 0(%0)\n"
> + : /* Outputs */
> + : /* Inputs */ "r"(addr)
> + /* : No clobber */);
> + }
> +}
[...]
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 5+ messages in thread
* [U-Boot] [PATCH v3] nios2: convert cache flush to use dm cpu data
2015-10-16 23:00 ` Marek Vasut
@ 2015-10-17 6:54 ` Thomas Chou
2015-10-17 11:52 ` Marek Vasut
0 siblings, 1 reply; 5+ messages in thread
From: Thomas Chou @ 2015-10-17 6:54 UTC (permalink / raw)
To: u-boot
Hi Marek,
On 10/17/2015 07:00 AM, Marek Vasut wrote:
>> +static void __flush_dcache(unsigned long start, unsigned long end)
>> +{
>> + unsigned long addr;
>> +
>> + start &= ~(gd->arch.dcache_line_size - 1);
>> + end += (gd->arch.dcache_line_size - 1);
>> + end &= ~(gd->arch.dcache_line_size - 1);
>
> I really don't think we should do this alignment here :-(
The rounding to get flush range is necessary to keep it confirm to the
interface defined in linux/Documentation/cachetlb.txt.
Removing the rounding and adding "range check and keep" is a violation
to the common interface.
You cannot agree to the common interface and, at the same time, insist
on changing the definition by your own.
Best regards,
Thomas
^ permalink raw reply [flat|nested] 5+ messages in thread
* [U-Boot] [PATCH v3] nios2: convert cache flush to use dm cpu data
2015-10-17 6:54 ` Thomas Chou
@ 2015-10-17 11:52 ` Marek Vasut
0 siblings, 0 replies; 5+ messages in thread
From: Marek Vasut @ 2015-10-17 11:52 UTC (permalink / raw)
To: u-boot
On Saturday, October 17, 2015 at 08:54:57 AM, Thomas Chou wrote:
> Hi Marek,
Hi!
> On 10/17/2015 07:00 AM, Marek Vasut wrote:
> >> +static void __flush_dcache(unsigned long start, unsigned long end)
> >> +{
> >> + unsigned long addr;
> >> +
> >> + start &= ~(gd->arch.dcache_line_size - 1);
> >> + end += (gd->arch.dcache_line_size - 1);
> >> + end &= ~(gd->arch.dcache_line_size - 1);
> >
> > I really don't think we should do this alignment here :-(
>
> The rounding to get flush range is necessary to keep it confirm to the
> interface defined in linux/Documentation/cachetlb.txt.
>
> Removing the rounding and adding "range check and keep" is a violation
> to the common interface.
>
> You cannot agree to the common interface and, at the same time, insist
> on changing the definition by your own.
I agree we should strive for such an interface, but it's not in place yet
and there are many nasty places in U-Boot where such an interface is not
directly applicable yet. That's why we need some sort of detection of the
incorrect addresses used in cache ops, since if I am tracking down some
sort of DMA issues and I find that my cache code is hiding them, I'll be
really unhappy.
btw. I think most of the U-Boot code has been already fixed, so if you
add the cache range checks, they shouldn't trigger too much.
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 5+ messages in thread
* [U-Boot] [PATCH v3] nios2: convert cache flush to use dm cpu data
2015-10-14 1:38 ` [U-Boot] [PATCH v3] nios2: convert cache flush to use dm cpu data Thomas Chou
2015-10-16 23:00 ` Marek Vasut
@ 2015-10-18 23:48 ` Thomas Chou
1 sibling, 0 replies; 5+ messages in thread
From: Thomas Chou @ 2015-10-18 23:48 UTC (permalink / raw)
To: u-boot
On 10/14/2015 09:38 AM, Thomas Chou wrote:
> Convert cache flush to use dm cpu data.
>
> The original cache flush functions are written in assembly
> and use CONFIG_SYS_{I,D}CACHE_SIZE... macros. It is difficult
> to convert to use cache configuration in dm cpu data which is
> extracted from device tree.
>
> The cacheflush.c of Linux nios2 arch uses cpuinfo structure,
> which is very close to our dm cpu data. So we copy and modify
> it to arch/nios2/lib/cache.c to replace the old cache.S.
>
> Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
> ---
> v2
> change commit message.
> v3
> check initda instruction support.
> add invalidate_dcache_range().
>
> arch/nios2/include/asm/cache.h | 13 ++---
> arch/nios2/lib/bootm.c | 6 +--
> arch/nios2/lib/cache.S | 68 ------------------------
> arch/nios2/lib/cache.c | 114 +++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 118 insertions(+), 83 deletions(-)
> delete mode 100644 arch/nios2/lib/cache.S
> create mode 100644 arch/nios2/lib/cache.c
>
Applied to u-boot-nios.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-10-18 23:48 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1444119600-31999-1-git-send-email-thomas@wytron.com.t>
2015-10-14 1:38 ` [U-Boot] [PATCH v3] nios2: convert cache flush to use dm cpu data Thomas Chou
2015-10-16 23:00 ` Marek Vasut
2015-10-17 6:54 ` Thomas Chou
2015-10-17 11:52 ` Marek Vasut
2015-10-18 23:48 ` Thomas Chou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox