From fbb0de088b86a0f87e876531b5ae6077cc0ab14c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 27 Jan 2016 03:13:59 +0100 Subject: mips: cache: Bulletproof the code against cornercases This patch makes sure that the flush/invalidate_dcache_range() functions can handle corner-case calls like this -- invalidate_dcache_range(0, 0, 0); This call is valid and is happily produced by USB EHCI code for example. The expected behavior of the cache function(s) in this case is that they will do no operation, since the size is zero. The current implementation though has a problem where such invocation will result in a hard CPU hang. This is because under such conditions, where the start_addr = 0 and stop = 0, the addr = 0 and aend = 0xffffffe0 . The loop will then try to iterate over the entire address space, which in itself is wrong. But iterating over the entire address space might also hit some odd address which will cause bus hang. The later happens on the Atheros MIPS. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Hans de Goede --- arch/mips/lib/cache.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/mips/lib') diff --git a/arch/mips/lib/cache.c b/arch/mips/lib/cache.c index bf8ff598ac..7482005b67 100644 --- a/arch/mips/lib/cache.c +++ b/arch/mips/lib/cache.c @@ -95,6 +95,10 @@ void flush_dcache_range(ulong start_addr, ulong stop) const void *addr = (const void *)(start_addr & ~(lsize - 1)); const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); + /* aend will be miscalculated when size is zero, so we return here */ + if (start_addr == stop) + return; + while (1) { mips_cache(HIT_WRITEBACK_INV_D, addr); if (addr == aend) @@ -109,6 +113,10 @@ void invalidate_dcache_range(ulong start_addr, ulong stop) const void *addr = (const void *)(start_addr & ~(lsize - 1)); const void *aend = (const void *)((stop - 1) & ~(lsize - 1)); + /* aend will be miscalculated when size is zero, so we return here */ + if (start_addr == stop) + return; + while (1) { mips_cache(HIT_INVALIDATE_D, addr); if (addr == aend) -- cgit v1.2.1 From 05e342554e51767830d7e60f2dab09192fd2a0e1 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 29 Jan 2016 13:54:52 +0000 Subject: MIPS: Support dynamic I/O port base address The existing mips_io_port_base variable isn't suitable for use early during boot since it will be stored in the .data section which may not be writable pre-relocation. Fix this by moving the I/O port base address into struct arch_global_data. In order to avoid adding this field for all targets, make this dependant upon a new Kconfig entry CONFIG_DYNAMIC_IO_PORT_BASE. Malta is the only board which sets a non-zero I/O port base, so select this option only for Malta. Signed-off-by: Paul Burton --- arch/mips/lib/Makefile | 1 - arch/mips/lib/io.c | 12 ------------ 2 files changed, 13 deletions(-) delete mode 100644 arch/mips/lib/io.c (limited to 'arch/mips/lib') diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index ac536da674..b7ce5df765 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -7,7 +7,6 @@ obj-y += cache.o obj-y += cache_init.o -obj-y += io.o obj-$(CONFIG_CMD_BOOTM) += bootm.o diff --git a/arch/mips/lib/io.c b/arch/mips/lib/io.c deleted file mode 100644 index b2d4a094da..0000000000 --- a/arch/mips/lib/io.c +++ /dev/null @@ -1,12 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * mips_io_port_base is the begin of the address space to which x86 style - * I/O ports are mapped. - */ -const unsigned long mips_io_port_base = -1; -- cgit v1.2.1