From patchwork Thu Jan 29 01:27:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Burton X-Patchwork-Id: 434259 X-Patchwork-Delegate: daniel.schwierzeck@googlemail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id E69041401F6 for ; Thu, 29 Jan 2015 12:29:05 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2A9A64B76B; Thu, 29 Jan 2015 02:29:04 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1Hmf2tLENKnv; Thu, 29 Jan 2015 02:29:03 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id AC0224B748; Thu, 29 Jan 2015 02:29:03 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 97B274B6CD for ; Thu, 29 Jan 2015 02:28:58 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id BL25q8K-l2Yz for ; Thu, 29 Jan 2015 02:28:58 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mailapp01.imgtec.com (mailapp01.imgtec.com [195.59.15.196]) by theia.denx.de (Postfix) with ESMTP id 559534B796 for ; Thu, 29 Jan 2015 02:28:58 +0100 (CET) Received: from KLMAIL01.kl.imgtec.org (unknown [192.168.5.35]) by Websense Email Security Gateway with ESMTPS id EF6309D6CBE88; Thu, 29 Jan 2015 01:28:55 +0000 (GMT) Received: from LEMAIL01.le.imgtec.org (192.168.152.62) by KLMAIL01.kl.imgtec.org (192.168.5.35) with Microsoft SMTP Server (TLS) id 14.3.195.1; Thu, 29 Jan 2015 01:28:56 +0000 Received: from localhost (192.168.159.173) by LEMAIL01.le.imgtec.org (192.168.152.62) with Microsoft SMTP Server (TLS) id 14.3.210.2; Thu, 29 Jan 2015 01:28:55 +0000 From: Paul Burton To: Date: Thu, 29 Jan 2015 01:27:57 +0000 Message-ID: <1422494883-30134-3-git-send-email-paul.burton@imgtec.com> X-Mailer: git-send-email 2.2.2 In-Reply-To: <1422494883-30134-1-git-send-email-paul.burton@imgtec.com> References: <1422494883-30134-1-git-send-email-paul.burton@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [192.168.159.173] Subject: [U-Boot] [PATCH v2 2/8] MIPS: unify cache maintenance functions X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Move the more developed mips32 version of the cache maintenance functions to a common arch/mips/lib/cache.c, in order to reduce duplication between mips32 & mips64. Signed-off-by: Paul Burton Cc: Daniel Schwierzeck --- Changes in v2: - None (rebase atop change to patch 1). --- arch/mips/cpu/mips32/cpu.c | 109 ----------------------------------------- arch/mips/cpu/mips64/cpu.c | 58 ---------------------- arch/mips/lib/Makefile | 1 + arch/mips/lib/cache.c | 118 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 167 deletions(-) create mode 100644 arch/mips/lib/cache.c diff --git a/arch/mips/cpu/mips32/cpu.c b/arch/mips/cpu/mips32/cpu.c index 1af909a..8e1cc4e 100644 --- a/arch/mips/cpu/mips32/cpu.c +++ b/arch/mips/cpu/mips32/cpu.c @@ -9,7 +9,6 @@ #include #include #include -#include #include void __attribute__((weak)) _machine_restart(void) @@ -24,114 +23,6 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } -#ifdef CONFIG_SYS_CACHELINE_SIZE - -static inline unsigned long icache_line_size(void) -{ - return CONFIG_SYS_CACHELINE_SIZE; -} - -static inline unsigned long dcache_line_size(void) -{ - return CONFIG_SYS_CACHELINE_SIZE; -} - -#else /* !CONFIG_SYS_CACHELINE_SIZE */ - -static inline unsigned long icache_line_size(void) -{ - unsigned long conf1, il; - conf1 = read_c0_config1(); - il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHIFT; - if (!il) - return 0; - return 2 << il; -} - -static inline unsigned long dcache_line_size(void) -{ - unsigned long conf1, dl; - conf1 = read_c0_config1(); - dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHIFT; - if (!dl) - return 0; - return 2 << dl; -} - -#endif /* !CONFIG_SYS_CACHELINE_SIZE */ - -void flush_cache(ulong start_addr, ulong size) -{ - unsigned long ilsize = icache_line_size(); - unsigned long dlsize = dcache_line_size(); - const void *addr, *aend; - - /* aend will be miscalculated when size is zero, so we return here */ - if (size == 0) - return; - - addr = (const void *)(start_addr & ~(dlsize - 1)); - aend = (const void *)((start_addr + size - 1) & ~(dlsize - 1)); - - if (ilsize == dlsize) { - /* flush I-cache & D-cache simultaneously */ - while (1) { - mips_cache(HIT_WRITEBACK_INV_D, addr); - mips_cache(HIT_INVALIDATE_I, addr); - if (addr == aend) - break; - addr += dlsize; - } - return; - } - - /* flush D-cache */ - while (1) { - mips_cache(HIT_WRITEBACK_INV_D, addr); - if (addr == aend) - break; - addr += dlsize; - } - - /* flush I-cache */ - addr = (const void *)(start_addr & ~(ilsize - 1)); - aend = (const void *)((start_addr + size - 1) & ~(ilsize - 1)); - while (1) { - mips_cache(HIT_INVALIDATE_I, addr); - if (addr == aend) - break; - addr += ilsize; - } -} - -void flush_dcache_range(ulong start_addr, ulong stop) -{ - unsigned long lsize = dcache_line_size(); - const void *addr = (const void *)(start_addr & ~(lsize - 1)); - const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); - - while (1) { - mips_cache(HIT_WRITEBACK_INV_D, addr); - if (addr == aend) - break; - addr += lsize; - } -} - -void invalidate_dcache_range(ulong start_addr, ulong stop) -{ - unsigned long lsize = dcache_line_size(); - const void *addr = (const void *)(start_addr & ~(lsize - 1)); - const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); - - while (1) { - mips_cache(HIT_INVALIDATE_D, addr); - if (addr == aend) - break; - addr += lsize; - } -} - void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) { write_c0_entrylo0(low0); diff --git a/arch/mips/cpu/mips64/cpu.c b/arch/mips/cpu/mips64/cpu.c index 9f45cfc..1d32705 100644 --- a/arch/mips/cpu/mips64/cpu.c +++ b/arch/mips/cpu/mips64/cpu.c @@ -9,19 +9,8 @@ #include #include #include -#include #include -#define cache_op(op, addr) \ - __asm__ __volatile__( \ - " .set push\n" \ - " .set noreorder\n" \ - " .set mips64\n" \ - " cache %0, %1\n" \ - " .set pop\n" \ - : \ - : "i" (op), "R" (*(unsigned char *)(addr))) - void __attribute__((weak)) _machine_restart(void) { fprintf(stderr, "*** reset failed ***\n"); @@ -37,53 +26,6 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } -void flush_cache(ulong start_addr, ulong size) -{ - unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; - unsigned long addr = start_addr & ~(lsize - 1); - unsigned long aend = (start_addr + size - 1) & ~(lsize - 1); - - /* aend will be miscalculated when size is zero, so we return here */ - if (size == 0) - return; - - while (1) { - cache_op(HIT_WRITEBACK_INV_D, addr); - cache_op(HIT_INVALIDATE_I, addr); - if (addr == aend) - break; - addr += lsize; - } -} - -void flush_dcache_range(ulong start_addr, ulong stop) -{ - unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; - unsigned long addr = start_addr & ~(lsize - 1); - unsigned long aend = (stop - 1) & ~(lsize - 1); - - while (1) { - cache_op(HIT_WRITEBACK_INV_D, addr); - if (addr == aend) - break; - addr += lsize; - } -} - -void invalidate_dcache_range(ulong start_addr, ulong stop) -{ - unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; - unsigned long addr = start_addr & ~(lsize - 1); - unsigned long aend = (stop - 1) & ~(lsize - 1); - - while (1) { - cache_op(HIT_INVALIDATE_D, addr); - if (addr == aend) - break; - addr += lsize; - } -} - void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1) { write_c0_entrylo0(low0); diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 7f9b653..d939ee6 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -5,6 +5,7 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-y += cache.o obj-y += io.o obj-$(CONFIG_CMD_BOOTM) += bootm.o diff --git a/arch/mips/lib/cache.c b/arch/mips/lib/cache.c new file mode 100644 index 0000000..e245614 --- /dev/null +++ b/arch/mips/lib/cache.c @@ -0,0 +1,118 @@ +/* + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#ifdef CONFIG_SYS_CACHELINE_SIZE + +static inline unsigned long icache_line_size(void) +{ + return CONFIG_SYS_CACHELINE_SIZE; +} + +static inline unsigned long dcache_line_size(void) +{ + return CONFIG_SYS_CACHELINE_SIZE; +} + +#else /* !CONFIG_SYS_CACHELINE_SIZE */ + +static inline unsigned long icache_line_size(void) +{ + unsigned long conf1, il; + conf1 = read_c0_config1(); + il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHIFT; + if (!il) + return 0; + return 2 << il; +} + +static inline unsigned long dcache_line_size(void) +{ + unsigned long conf1, dl; + conf1 = read_c0_config1(); + dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHIFT; + if (!dl) + return 0; + return 2 << dl; +} + +#endif /* !CONFIG_SYS_CACHELINE_SIZE */ + +void flush_cache(ulong start_addr, ulong size) +{ + unsigned long ilsize = icache_line_size(); + unsigned long dlsize = dcache_line_size(); + const void *addr, *aend; + + /* aend will be miscalculated when size is zero, so we return here */ + if (size == 0) + return; + + addr = (const void *)(start_addr & ~(dlsize - 1)); + aend = (const void *)((start_addr + size - 1) & ~(dlsize - 1)); + + if (ilsize == dlsize) { + /* flush I-cache & D-cache simultaneously */ + while (1) { + mips_cache(HIT_WRITEBACK_INV_D, addr); + mips_cache(HIT_INVALIDATE_I, addr); + if (addr == aend) + break; + addr += dlsize; + } + return; + } + + /* flush D-cache */ + while (1) { + mips_cache(HIT_WRITEBACK_INV_D, addr); + if (addr == aend) + break; + addr += dlsize; + } + + /* flush I-cache */ + addr = (const void *)(start_addr & ~(ilsize - 1)); + aend = (const void *)((start_addr + size - 1) & ~(ilsize - 1)); + while (1) { + mips_cache(HIT_INVALIDATE_I, addr); + if (addr == aend) + break; + addr += ilsize; + } +} + +void flush_dcache_range(ulong start_addr, ulong stop) +{ + unsigned long lsize = dcache_line_size(); + const void *addr = (const void *)(start_addr & ~(lsize - 1)); + const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); + + while (1) { + mips_cache(HIT_WRITEBACK_INV_D, addr); + if (addr == aend) + break; + addr += lsize; + } +} + +void invalidate_dcache_range(ulong start_addr, ulong stop) +{ + unsigned long lsize = dcache_line_size(); + const void *addr = (const void *)(start_addr & ~(lsize - 1)); + const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); + + while (1) { + mips_cache(HIT_INVALIDATE_D, addr); + if (addr == aend) + break; + addr += lsize; + } +}