From a2e2725541fad72416326798c2d7fa4dafb7d337 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 12 Oct 2009 23:40:10 -0700 Subject: net: Introduce recvmmsg socket syscall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Meaning receive multiple messages, reducing the number of syscalls and net stack entry/exit operations. Next patches will introduce mechanisms where protocols that want to optimize this operation will provide an unlocked_recvmsg operation. This takes into account comments made by: . Paul Moore: sock_recvmsg is called only for the first datagram, sock_recvmsg_nosec is used for the rest. . Caitlin Bestler: recvmmsg now has a struct timespec timeout, that works in the same fashion as the ppoll one. If the underlying protocol returns a datagram with MSG_OOB set, this will make recvmmsg return right away with as many datagrams (+ the OOB one) it has received so far. . Rémi Denis-Courmont & Steven Whitehouse: If we receive N < vlen datagrams and then recvmsg returns an error, recvmmsg will return the successfully received datagrams, store the error and return it in the next call. This paves the way for a subsequent optimization, sk_prot->unlocked_recvmsg, where we will be able to acquire the lock only at batch start and end, not at every underlying recvmsg call. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- arch/microblaze/kernel/syscall_table.S | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index ecec1915513..c1ab1dc1089 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S @@ -371,3 +371,4 @@ ENTRY(sys_call_table) .long sys_ni_syscall .long sys_rt_tgsigqueueinfo /* 365 */ .long sys_perf_event_open + .long sys_recvmmsg -- cgit v1.2.3-18-g5258 From 2d4dc890b5c8fabd818a8586607e6843c4375e62 Mon Sep 17 00:00:00 2001 From: Ilya Loginov Date: Thu, 26 Nov 2009 09:16:19 +0100 Subject: block: add helpers to run flush_dcache_page() against a bio and a request's pages Mtdblock driver doesn't call flush_dcache_page for pages in request. So, this causes problems on architectures where the icache doesn't fill from the dcache or with dcache aliases. The patch fixes this. The ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE symbol was introduced to avoid pointless empty cache-thrashing loops on architectures for which flush_dcache_page() is a no-op. Every architecture was provided with this flush pages on architectires where ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE is equal 1 or do nothing otherwise. See "fix mtd_blkdevs problem with caches on some architectures" discussion on LKML for more information. Signed-off-by: Ilya Loginov Cc: Ingo Molnar Cc: David Woodhouse Cc: Peter Horton Cc: "Ed L. Cashin" Signed-off-by: Jens Axboe --- arch/microblaze/include/asm/cacheflush.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/microblaze') diff --git a/arch/microblaze/include/asm/cacheflush.h b/arch/microblaze/include/asm/cacheflush.h index f989d6aad64..088076e657b 100644 --- a/arch/microblaze/include/asm/cacheflush.h +++ b/arch/microblaze/include/asm/cacheflush.h @@ -37,6 +37,7 @@ #define flush_cache_page(vma, vmaddr, pfn) do { } while (0) #define flush_dcache_range(start, end) __invalidate_dcache_range(start, end) +#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 #define flush_dcache_page(page) do { } while (0) #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) -- cgit v1.2.3-18-g5258 From af901ca181d92aac3a7dc265144a9081a86d8f39 Mon Sep 17 00:00:00 2001 From: André Goddard Rosa Date: Sat, 14 Nov 2009 13:09:05 -0200 Subject: tree-wide: fix assorted typos all over the place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That is "success", "unknown", "through", "performance", "[re|un]mapping" , "access", "default", "reasonable", "[con]currently", "temperature" , "channel", "[un]used", "application", "example","hierarchy", "therefore" , "[over|under]flow", "contiguous", "threshold", "enough" and others. Signed-off-by: André Goddard Rosa Signed-off-by: Jiri Kosina --- arch/microblaze/lib/memcpy.c | 2 +- arch/microblaze/lib/memmove.c | 2 +- arch/microblaze/lib/memset.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c index 6a907c58a4b..cc2108b6b26 100644 --- a/arch/microblaze/lib/memcpy.c +++ b/arch/microblaze/lib/memcpy.c @@ -9,7 +9,7 @@ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from * http://www.embedded.com/showArticle.jhtml?articleID=19205567 * - * Attempts were made, unsuccesfully, to contact the original + * Attempts were made, unsuccessfully, to contact the original * author of this code (Michael Morrow, Intel). Below is the original * copyright notice. * diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c index d4e9f49a71f..0929198c5e6 100644 --- a/arch/microblaze/lib/memmove.c +++ b/arch/microblaze/lib/memmove.c @@ -9,7 +9,7 @@ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from * http://www.embedded.com/showArticle.jhtml?articleID=19205567 * - * Attempts were made, unsuccesfully, to contact the original + * Attempts were made, unsuccessfully, to contact the original * author of this code (Michael Morrow, Intel). Below is the original * copyright notice. * diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c index 941dc8f94b0..4df851d41a2 100644 --- a/arch/microblaze/lib/memset.c +++ b/arch/microblaze/lib/memset.c @@ -9,7 +9,7 @@ * It is based on demo code originally Copyright 2001 by Intel Corp, taken from * http://www.embedded.com/showArticle.jhtml?articleID=19205567 * - * Attempts were made, unsuccesfully, to contact the original + * Attempts were made, unsuccessfully, to contact the original * author of this code (Michael Morrow, Intel). Below is the original * copyright notice. * -- cgit v1.2.3-18-g5258 From f8b7256096a20436f6d0926747e3ac3d64c81d24 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 30 Nov 2009 17:37:04 -0500 Subject: Unify sys_mmap* New helper - sys_mmap_pgoff(); switch syscalls to using it. Acked-by: David S. Miller Signed-off-by: Al Viro --- arch/microblaze/kernel/sys_microblaze.c | 38 +++------------------------------ arch/microblaze/kernel/syscall_table.S | 2 +- 2 files changed, 4 insertions(+), 36 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c index 07cabed4b94..9f3c205fb75 100644 --- a/arch/microblaze/kernel/sys_microblaze.c +++ b/arch/microblaze/kernel/sys_microblaze.c @@ -62,46 +62,14 @@ out: return error; } -asmlinkage long -sys_mmap2(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long pgoff) -{ - struct file *file = NULL; - int ret = -EBADF; - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - if (!(flags & MAP_ANONYMOUS)) { - file = fget(fd); - if (!file) { - printk(KERN_INFO "no fd in mmap\r\n"); - goto out; - } - } - - down_write(¤t->mm->mmap_sem); - ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up_write(¤t->mm->mmap_sem); - if (file) - fput(file); -out: - return ret; -} - asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, off_t pgoff) { - int err = -EINVAL; - - if (pgoff & ~PAGE_MASK) { - printk(KERN_INFO "no pagemask in mmap\r\n"); - goto out; - } + if (pgoff & ~PAGE_MASK) + return -EINVAL; - err = sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); -out: - return err; + return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); } /* diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index c1ab1dc1089..b96f365ea6b 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S @@ -196,7 +196,7 @@ ENTRY(sys_call_table) .long sys_ni_syscall /* reserved for streams2 */ .long sys_vfork /* 190 */ .long sys_getrlimit - .long sys_mmap2 /* mmap2 */ + .long sys_mmap_pgoff /* mmap2 */ .long sys_truncate64 .long sys_ftruncate64 .long sys_stat64 /* 195 */ -- cgit v1.2.3-18-g5258 From 559df2e0210352f83926d178c40c51142292a18c Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 19 Apr 2009 22:35:10 +0200 Subject: kbuild: move asm-offsets.h to include/generated The simplest method was to add an extra asm-offsets.h file in arch/$ARCH/include/asm that references the generated file. We can now migrate the architectures one-by-one to reference the generated file direct - and when done we can delete the temporary arch/$ARCH/include/asm/asm-offsets.h file. Signed-off-by: Sam Ravnborg Cc: Al Viro Signed-off-by: Michal Marek --- arch/microblaze/include/asm/asm-offsets.h | 1 + 1 file changed, 1 insertion(+) create mode 100644 arch/microblaze/include/asm/asm-offsets.h (limited to 'arch/microblaze') diff --git a/arch/microblaze/include/asm/asm-offsets.h b/arch/microblaze/include/asm/asm-offsets.h new file mode 100644 index 00000000000..d370ee36a18 --- /dev/null +++ b/arch/microblaze/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include -- cgit v1.2.3-18-g5258 From 42a2478b789cb1b4335909e0fecc721c07be7d90 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 2 Oct 2009 12:48:47 +0200 Subject: microblaze: GPIO reset support Signed-off-by: Michal Simek --- arch/microblaze/include/asm/setup.h | 2 + arch/microblaze/kernel/Makefile | 2 +- arch/microblaze/kernel/reset.c | 138 ++++++++++++++++++++++++++++ arch/microblaze/kernel/setup.c | 29 ------ arch/microblaze/platform/generic/system.dts | 28 ++++++ arch/microblaze/platform/platform.c | 2 + 6 files changed, 171 insertions(+), 30 deletions(-) create mode 100644 arch/microblaze/kernel/reset.c (limited to 'arch/microblaze') diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h index ed67c9ed15b..7f31394985e 100644 --- a/arch/microblaze/include/asm/setup.h +++ b/arch/microblaze/include/asm/setup.h @@ -35,6 +35,8 @@ extern void mmu_reset(void); extern void early_console_reg_tlb_alloc(unsigned int addr); # endif /* CONFIG_MMU */ +extern void of_platform_reset_gpio_probe(void); + void time_init(void); void init_IRQ(void); void machine_early_init(const char *cmdline, unsigned int ram, diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index d487729683d..fddd0c403d4 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile @@ -7,7 +7,7 @@ extra-y := head.o vmlinux.lds obj-y += exceptions.o \ hw_exception_handler.o init_task.o intc.o irq.o of_device.o \ of_platform.o process.o prom.o prom_parse.o ptrace.o \ - setup.o signal.o sys_microblaze.o timer.o traps.o + setup.o signal.o sys_microblaze.o timer.o traps.o reset.o obj-y += cpu/ diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c new file mode 100644 index 00000000000..ce74a6f436e --- /dev/null +++ b/arch/microblaze/kernel/reset.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2009 Michal Simek + * Copyright (C) 2009 PetaLogix + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include + +/* Trigger specific functions */ +#ifdef CONFIG_GPIOLIB + +#include + +static int handle; /* reset pin handle */ + +static int of_reset_gpio_handle(void) +{ + int ret; /* variable which stored handle reset gpio pin */ + struct device_node *root; /* root node */ + struct device_node *gpio; /* gpio node */ + struct of_gpio_chip *of_gc = NULL; + enum of_gpio_flags flags ; + const void *gpio_spec; + + /* find out root node */ + root = of_find_node_by_path("/"); + + /* give me handle for gpio node to be possible allocate pin */ + ret = of_parse_phandles_with_args(root, "hard-reset-gpios", + "#gpio-cells", 0, &gpio, &gpio_spec); + if (ret) { + pr_debug("%s: can't parse gpios property\n", __func__); + goto err0; + } + + of_gc = gpio->data; + if (!of_gc) { + pr_debug("%s: gpio controller %s isn't registered\n", + root->full_name, gpio->full_name); + ret = -ENODEV; + goto err1; + } + + ret = of_gc->xlate(of_gc, root, gpio_spec, &flags); + if (ret < 0) + goto err1; + + ret += of_gc->gc.base; +err1: + of_node_put(gpio); +err0: + pr_debug("%s exited with status %d\n", __func__, ret); + return ret; +} + +void of_platform_reset_gpio_probe(void) +{ + int ret; + handle = of_reset_gpio_handle(); + + if (!gpio_is_valid(handle)) { + printk(KERN_INFO "Skipping unavailable RESET gpio %d (%s)\n", + handle, "reset"); + } + + ret = gpio_request(handle, "reset"); + if (ret < 0) { + printk(KERN_INFO "GPIO pin is already allocated\n"); + return; + } + + /* get current setup value */ + ret = gpio_get_value(handle); + /* FIXME maybe worth to perform any action */ + pr_debug("Reset: Gpio output state: 0x%x\n", ret); + + /* Setup GPIO as output */ + ret = gpio_direction_output(handle, 0); + if (ret < 0) + goto err; + + /* Setup output direction */ + gpio_set_value(handle, 0); + + printk(KERN_INFO "Registered reset device: %d\n", handle); + return; +err: + gpio_free(handle); + return; +} + + +static void gpio_system_reset(void) +{ + gpio_set_value(handle, 1); +} +#else +#define gpio_system_reset() do {} while (0) +void of_platform_reset_gpio_probe(void) +{ + return; +} +#endif + +void machine_restart(char *cmd) +{ + printk(KERN_NOTICE "Machine restart...\n"); + gpio_system_reset(); + dump_stack(); + while (1) + ; +} + +void machine_shutdown(void) +{ + printk(KERN_NOTICE "Machine shutdown...\n"); + while (1) + ; +} + +void machine_halt(void) +{ + printk(KERN_NOTICE "Machine halt...\n"); + while (1) + ; +} + +void machine_power_off(void) +{ + printk(KERN_NOTICE "Machine power off...\n"); + while (1) + ; +} diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 8c1e0f4dcf1..367ad330148 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -186,32 +186,3 @@ static int microblaze_debugfs_init(void) } arch_initcall(microblaze_debugfs_init); #endif - -void machine_restart(char *cmd) -{ - printk(KERN_NOTICE "Machine restart...\n"); - dump_stack(); - while (1) - ; -} - -void machine_shutdown(void) -{ - printk(KERN_NOTICE "Machine shutdown...\n"); - while (1) - ; -} - -void machine_halt(void) -{ - printk(KERN_NOTICE "Machine halt...\n"); - while (1) - ; -} - -void machine_power_off(void) -{ - printk(KERN_NOTICE "Machine power off...\n"); - while (1) - ; -} diff --git a/arch/microblaze/platform/generic/system.dts b/arch/microblaze/platform/generic/system.dts index 29993f62b30..e00da8971c3 100644 --- a/arch/microblaze/platform/generic/system.dts +++ b/arch/microblaze/platform/generic/system.dts @@ -32,6 +32,7 @@ #address-cells = <1>; #size-cells = <1>; compatible = "xlnx,microblaze"; + hard-reset-gpios = <&LEDs_8Bit 2 1>; model = "testing"; DDR2_SDRAM: memory@90000000 { device_type = "memory"; @@ -261,6 +262,33 @@ xlnx,is-dual = <0x0>; xlnx,tri-default = <0xffffffff>; xlnx,tri-default-2 = <0xffffffff>; + #gpio-cells = <2>; + gpio-controller; + } ; + + gpio-leds { + compatible = "gpio-leds"; + + heartbeat { + label = "Heartbeat"; + gpios = <&LEDs_8Bit 4 1>; + linux,default-trigger = "heartbeat"; + }; + + yellow { + label = "Yellow"; + gpios = <&LEDs_8Bit 5 1>; + }; + + red { + label = "Red"; + gpios = <&LEDs_8Bit 6 1>; + }; + + green { + label = "Green"; + gpios = <&LEDs_8Bit 7 1>; + }; } ; RS232_Uart_1: serial@84000000 { clock-frequency = <125000000>; diff --git a/arch/microblaze/platform/platform.c b/arch/microblaze/platform/platform.c index 56e0234fa34..5b89b58c5ae 100644 --- a/arch/microblaze/platform/platform.c +++ b/arch/microblaze/platform/platform.c @@ -13,6 +13,7 @@ #include #include #include +#include static struct of_device_id xilinx_of_bus_ids[] __initdata = { { .compatible = "simple-bus", }, @@ -26,6 +27,7 @@ static struct of_device_id xilinx_of_bus_ids[] __initdata = { static int __init microblaze_device_probe(void) { of_platform_bus_probe(NULL, xilinx_of_bus_ids, NULL); + of_platform_reset_gpio_probe(); return 0; } device_initcall(microblaze_device_probe); -- cgit v1.2.3-18-g5258 From 13cdee23296c437cdd0262a09c3455de8e1e85b2 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 30 Oct 2009 14:41:52 +0100 Subject: microblaze: __init_begin symbol must be aligned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The problem was that free_initmem pass to free_initrd_mem got bad aligned __init_begin symbol and free_initrd_mem don't care about __init_end but take PAGE_SIZE instead. Here is behavior in kernel bootlog. ramdisk_execute_command from (init/main.c) was rewrite Freeing unused kernel memory: 6224k freed Failed to execute ��������������{��� Failed to execute ��������������{����. Attempting defaults... Mounting proc: Mounting var: Signed-off-by: Michal Simek --- arch/microblaze/kernel/vmlinux.lds.S | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S index e704188d785..ecee15342e6 100644 --- a/arch/microblaze/kernel/vmlinux.lds.S +++ b/arch/microblaze/kernel/vmlinux.lds.S @@ -86,6 +86,7 @@ SECTIONS { _KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2) ; } + . = ALIGN(PAGE_SIZE); __init_begin = .; INIT_TEXT_SECTION(PAGE_SIZE) -- cgit v1.2.3-18-g5258 From 7cf79d59ea650ae82868a99cc2954871d2a239bf Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 6 Nov 2009 12:27:25 +0100 Subject: microblaze: Add IRQENTRY_TEXT to lds It is important for ftrace irqsoff support Signed-off-by: Michal Simek --- arch/microblaze/kernel/vmlinux.lds.S | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S index ecee15342e6..5ef619aad63 100644 --- a/arch/microblaze/kernel/vmlinux.lds.S +++ b/arch/microblaze/kernel/vmlinux.lds.S @@ -26,11 +26,12 @@ SECTIONS { _stext = . ; *(.text .text.*) *(.fixup) - EXIT_TEXT - EXIT_CALL + EXIT_TEXT + EXIT_CALL SCHED_TEXT LOCK_TEXT KPROBES_TEXT + IRQENTRY_TEXT . = ALIGN (4) ; _etext = . ; } -- cgit v1.2.3-18-g5258 From 24b45a12c21132e78e14f3aedf74bb1297228072 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 10 Nov 2009 15:57:01 +0100 Subject: microblaze: Stack trace support This is working implemetation but the problem is that Microblaze misses frame pointer that's why is there big loop which trace and show all addresses which are in text. It shows addresses which are in registers, etc. This is problem and this is the reason why all Microblaze traces are wrong. There is an option to do hacks and trace the kernel code but this is too complicated. Signed-off-by: Michal Simek --- arch/microblaze/Kconfig | 3 ++ arch/microblaze/kernel/Makefile | 1 + arch/microblaze/kernel/stacktrace.c | 65 +++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 arch/microblaze/kernel/stacktrace.c (limited to 'arch/microblaze') diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index bbd8327f189..8e1c4f7d3e6 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -57,6 +57,9 @@ config GENERIC_GPIO config GENERIC_CSUM def_bool y +config STACKTRACE_SUPPORT + def_bool y + config PCI def_bool n diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index fddd0c403d4..c465a5c4669 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile @@ -16,5 +16,6 @@ obj-$(CONFIG_SELFMOD) += selfmod.o obj-$(CONFIG_HEART_BEAT) += heartbeat.o obj-$(CONFIG_MODULES) += microblaze_ksyms.o module.o obj-$(CONFIG_MMU) += misc.o +obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-y += entry$(MMU).o diff --git a/arch/microblaze/kernel/stacktrace.c b/arch/microblaze/kernel/stacktrace.c new file mode 100644 index 00000000000..123692f2264 --- /dev/null +++ b/arch/microblaze/kernel/stacktrace.c @@ -0,0 +1,65 @@ +/* + * Stack trace support for Microblaze. + * + * Copyright (C) 2009 Michal Simek + * Copyright (C) 2009 PetaLogix + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include + +/* FIXME initial support */ +void save_stack_trace(struct stack_trace *trace) +{ + unsigned long *sp; + unsigned long addr; + asm("addik %0, r1, 0" : "=r" (sp)); + + while (!kstack_end(sp)) { + addr = *sp++; + if (__kernel_text_address(addr)) { + if (trace->skip > 0) + trace->skip--; + else + trace->entries[trace->nr_entries++] = addr; + + if (trace->nr_entries >= trace->max_entries) + break; + } + } +} +EXPORT_SYMBOL_GPL(save_stack_trace); + +void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) +{ + unsigned int *sp; + unsigned long addr; + + struct thread_info *ti = task_thread_info(tsk); + + if (tsk == current) + asm("addik %0, r1, 0" : "=r" (sp)); + else + sp = (unsigned int *)ti->cpu_context.r1; + + while (!kstack_end(sp)) { + addr = *sp++; + if (__kernel_text_address(addr)) { + if (trace->skip > 0) + trace->skip--; + else + trace->entries[trace->nr_entries++] = addr; + + if (trace->nr_entries >= trace->max_entries) + break; + } + } +} +EXPORT_SYMBOL_GPL(save_stack_trace_tsk); -- cgit v1.2.3-18-g5258 From 519e9f417388ba055b7604db5f4f492f7c84f427 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 6 Nov 2009 12:31:00 +0100 Subject: microblaze: Register timecounter/cyclecounter It is the same counter as we use as free running one. I would like to use it for ftrace. Signed-off-by: Michal Simek --- arch/microblaze/kernel/timer.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 5499deae7fa..ed61b2f1771 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -183,6 +183,31 @@ static cycle_t microblaze_read(struct clocksource *cs) return (cycle_t) (in_be32(TIMER_BASE + TCR1)); } +static struct timecounter microblaze_tc = { + .cc = NULL, +}; + +static cycle_t microblaze_cc_read(const struct cyclecounter *cc) +{ + return microblaze_read(NULL); +} + +static struct cyclecounter microblaze_cc = { + .read = microblaze_cc_read, + .mask = CLOCKSOURCE_MASK(32), + .shift = 24, +}; + +int __init init_microblaze_timecounter(void) +{ + microblaze_cc.mult = div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, + microblaze_cc.shift); + + timecounter_init(µblaze_tc, µblaze_cc, sched_clock()); + + return 0; +} + static struct clocksource clocksource_microblaze = { .name = "microblaze_clocksource", .rating = 300, @@ -204,6 +229,9 @@ static int __init microblaze_clocksource_init(void) out_be32(TIMER_BASE + TCSR1, in_be32(TIMER_BASE + TCSR1) & ~TCSR_ENT); /* start timer1 - up counting without interrupt */ out_be32(TIMER_BASE + TCSR1, TCSR_TINT|TCSR_ENT|TCSR_ARHT); + + /* register timecounter - for ftrace support */ + init_microblaze_timecounter(); return 0; } -- cgit v1.2.3-18-g5258 From bf2d809668907c69b554459764b36584e4d57e4a Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 10 Dec 2009 12:07:02 +0100 Subject: microblaze: Lockdep support Microblaze needs to do lock_init very soon because MMU init calls lock functions. Here is the explanation from Peter Zijlstra why we have to enable __ARCH_WANTS_INTERRUPTS_ON_CTSW. "So we schedule while holding rq->lock (for obvious reasons), but since lockdep tracks held locks per tasks, we need to transfer the held state from the prev to the next task. We do this by explicity calling spin_release(&rq->lock) in context_switch() right before switch_to(), and calling spin_acquire(&rq->lock) in finish_task_switch()->finish_lock_switch(). Now, for some reason lockdep thinks that interrupts got enabled over the context switch (git grep __ARCH_WANTS_INTERRUPTS_ON_CTSW arch/microblaze doesn't seem to turn up anything). Clearly trying to acquire the rq->lock with interrupts enabled is a bad idea and lockdep warns you about this." Signed-off-by: Michal Simek --- arch/microblaze/Kconfig | 3 +++ arch/microblaze/include/asm/system.h | 2 ++ arch/microblaze/kernel/setup.c | 2 ++ 3 files changed, 7 insertions(+) (limited to 'arch/microblaze') diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 8e1c4f7d3e6..5ba4dcd56ca 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -60,6 +60,9 @@ config GENERIC_CSUM config STACKTRACE_SUPPORT def_bool y +config LOCKDEP_SUPPORT + def_bool y + config PCI def_bool n diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h index b1ed6159066..157970688b2 100644 --- a/arch/microblaze/include/asm/system.h +++ b/arch/microblaze/include/asm/system.h @@ -16,6 +16,8 @@ #include #include +#define __ARCH_WANT_INTERRUPTS_ON_CTXSW + struct task_struct; struct thread_info; diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 367ad330148..acd70fe30a7 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -131,6 +131,8 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, strlcpy(cmd_line, cmdline, COMMAND_LINE_SIZE); #endif + lockdep_init(); + /* initialize device tree for usage in early_printk */ early_init_devtree((void *)_fdt_start); -- cgit v1.2.3-18-g5258 From fb5a32dc1ad7d6378363ad2eb7262edb5fba10f8 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 16 Nov 2009 09:09:47 +0100 Subject: microblaze: preliminary enabling for LATENCYTOP support in Kconfig Signed-off-by: Michal Simek --- arch/microblaze/Kconfig | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/microblaze') diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 5ba4dcd56ca..57eeaa60ca6 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -63,6 +63,9 @@ config STACKTRACE_SUPPORT config LOCKDEP_SUPPORT def_bool y +config HAVE_LATENCYTOP_SUPPORT + def_bool y + config PCI def_bool n -- cgit v1.2.3-18-g5258 From a3cd613b2e775eb59816c2c7c49c038d54917208 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 30 Oct 2009 12:26:53 +0100 Subject: microblaze: Add TRACE_IRQFLAGS_SUPPORT There are just two major changes Renamed local_irq functions to raw_local_irq in irq.c. Added TRACE_IRQFLAGS_SUPPORT to Kconfig.debug. Look at Documentation/irqflags-tracing.txt Signed-off-by: Michal Simek --- arch/microblaze/Kconfig.debug | 3 + arch/microblaze/include/asm/irqflags.h | 112 +++++++++++++++------------------ arch/microblaze/kernel/cpu/pvr.c | 2 +- 3 files changed, 54 insertions(+), 63 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/Kconfig.debug b/arch/microblaze/Kconfig.debug index 242cd35bdb4..9dc708a7f70 100644 --- a/arch/microblaze/Kconfig.debug +++ b/arch/microblaze/Kconfig.debug @@ -3,6 +3,9 @@ menu "Kernel hacking" +config TRACE_IRQFLAGS_SUPPORT + def_bool y + source "lib/Kconfig.debug" config EARLY_PRINTK diff --git a/arch/microblaze/include/asm/irqflags.h b/arch/microblaze/include/asm/irqflags.h index dea65645a4f..2c38c6d8017 100644 --- a/arch/microblaze/include/asm/irqflags.h +++ b/arch/microblaze/include/asm/irqflags.h @@ -10,78 +10,73 @@ #define _ASM_MICROBLAZE_IRQFLAGS_H #include +#include # if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR -# define local_irq_save(flags) \ +# define raw_local_irq_save(flags) \ do { \ - asm volatile ("# local_irq_save \n\t" \ - "msrclr %0, %1 \n\t" \ - "nop \n\t" \ + asm volatile (" msrclr %0, %1; \ + nop;" \ : "=r"(flags) \ : "i"(MSR_IE) \ : "memory"); \ } while (0) -# define local_irq_disable() \ - do { \ - asm volatile ("# local_irq_disable \n\t" \ - "msrclr r0, %0 \n\t" \ - "nop \n\t" \ - : \ - : "i"(MSR_IE) \ - : "memory"); \ +# define raw_local_irq_disable() \ + do { \ + asm volatile (" msrclr r0, %0; \ + nop;" \ + : \ + : "i"(MSR_IE) \ + : "memory"); \ } while (0) -# define local_irq_enable() \ - do { \ - asm volatile ("# local_irq_enable \n\t" \ - "msrset r0, %0 \n\t" \ - "nop \n\t" \ - : \ - : "i"(MSR_IE) \ - : "memory"); \ +# define raw_local_irq_enable() \ + do { \ + asm volatile (" msrset r0, %0; \ + nop;" \ + : \ + : "i"(MSR_IE) \ + : "memory"); \ } while (0) # else /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR == 0 */ -# define local_irq_save(flags) \ +# define raw_local_irq_save(flags) \ do { \ register unsigned tmp; \ - asm volatile ("# local_irq_save \n\t" \ - "mfs %0, rmsr \n\t" \ - "nop \n\t" \ - "andi %1, %0, %2 \n\t" \ - "mts rmsr, %1 \n\t" \ - "nop \n\t" \ + asm volatile (" mfs %0, rmsr; \ + nop; \ + andi %1, %0, %2; \ + mts rmsr, %1; \ + nop;" \ : "=r"(flags), "=r" (tmp) \ : "i"(~MSR_IE) \ : "memory"); \ } while (0) -# define local_irq_disable() \ +# define raw_local_irq_disable() \ do { \ register unsigned tmp; \ - asm volatile ("# local_irq_disable \n\t" \ - "mfs %0, rmsr \n\t" \ - "nop \n\t" \ - "andi %0, %0, %1 \n\t" \ - "mts rmsr, %0 \n\t" \ - "nop \n\t" \ + asm volatile (" mfs %0, rmsr; \ + nop; \ + andi %0, %0, %1; \ + mts rmsr, %0; \ + nop;" \ : "=r"(tmp) \ : "i"(~MSR_IE) \ : "memory"); \ } while (0) -# define local_irq_enable() \ +# define raw_local_irq_enable() \ do { \ register unsigned tmp; \ - asm volatile ("# local_irq_enable \n\t" \ - "mfs %0, rmsr \n\t" \ - "nop \n\t" \ - "ori %0, %0, %1 \n\t" \ - "mts rmsr, %0 \n\t" \ - "nop \n\t" \ + asm volatile (" mfs %0, rmsr; \ + nop; \ + ori %0, %0, %1; \ + mts rmsr, %0; \ + nop;" \ : "=r"(tmp) \ : "i"(MSR_IE) \ : "memory"); \ @@ -89,35 +84,28 @@ # endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */ -#define local_save_flags(flags) \ +#define raw_local_irq_restore(flags) \ do { \ - asm volatile ("# local_save_flags \n\t" \ - "mfs %0, rmsr \n\t" \ - "nop \n\t" \ - : "=r"(flags) \ + asm volatile (" mts rmsr, %0; \ + nop;" \ : \ + : "r"(flags) \ : "memory"); \ } while (0) -#define local_irq_restore(flags) \ - do { \ - asm volatile ("# local_irq_restore \n\t"\ - "mts rmsr, %0 \n\t" \ - "nop \n\t" \ - : \ - : "r"(flags) \ - : "memory"); \ - } while (0) - -static inline int irqs_disabled(void) +static inline unsigned long get_msr(void) { unsigned long flags; - - local_save_flags(flags); - return ((flags & MSR_IE) == 0); + asm volatile (" mfs %0, rmsr; \ + nop;" \ + : "=r"(flags) \ + : \ + : "memory"); \ + return flags; } -#define raw_irqs_disabled irqs_disabled -#define raw_irqs_disabled_flags(flags) ((flags) == 0) +#define raw_local_save_flags(flags) ((flags) = get_msr()) +#define raw_irqs_disabled() ((get_msr() & MSR_IE) == 0) +#define raw_irqs_disabled_flags(flags) ((flags & MSR_IE) == 0) #endif /* _ASM_MICROBLAZE_IRQFLAGS_H */ diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c index c9a4340ddd5..9bee9382bf7 100644 --- a/arch/microblaze/kernel/cpu/pvr.c +++ b/arch/microblaze/kernel/cpu/pvr.c @@ -45,7 +45,7 @@ int cpu_has_pvr(void) { - unsigned flags; + unsigned long flags; unsigned pvr0; local_save_flags(flags); -- cgit v1.2.3-18-g5258 From 2fd7c761a24c28e83d7194b4b4a099451126a503 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 16 Nov 2009 09:40:14 +0100 Subject: microblaze: ftrace: add static function tracer If -pg of gcc is enabled with CONFIG_FUNCTION_TRACER=y. a calling to _mcount will be inserted into each kernel function. so, there is a possibility to trace the kernel functions in _mcount. This patch add the specific _mcount support for static function tracing. by default, ftrace_trace_function is initialized as ftrace_stub(an empty function), so, the default _mcount will introduce very little overhead. after enabling ftrace in user-space, it will jump to a real tracing function and do static function tracing for us. Commit message from Wu Zhangjin Signed-off-by: Michal Simek --- arch/microblaze/Kconfig | 1 + arch/microblaze/include/asm/ftrace.h | 14 ++++ arch/microblaze/kernel/Makefile | 11 ++++ arch/microblaze/kernel/cpu/Makefile | 4 ++ arch/microblaze/kernel/mcount.S | 105 ++++++++++++++++++++++++++++++ arch/microblaze/kernel/microblaze_ksyms.c | 5 ++ 6 files changed, 140 insertions(+) create mode 100644 arch/microblaze/kernel/mcount.S (limited to 'arch/microblaze') diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 57eeaa60ca6..18003ca0819 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -6,6 +6,7 @@ mainmenu "Linux/Microblaze Kernel Configuration" config MICROBLAZE def_bool y select HAVE_LMB + select HAVE_FUNCTION_TRACER select USB_ARCH_HAS_EHCI select ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/arch/microblaze/include/asm/ftrace.h b/arch/microblaze/include/asm/ftrace.h index 8b137891791..22beec58c02 100644 --- a/arch/microblaze/include/asm/ftrace.h +++ b/arch/microblaze/include/asm/ftrace.h @@ -1 +1,15 @@ +#ifndef _ASM_MICROBLAZE_FTRACE +#define _ASM_MICROBLAZE_FTRACE +#ifdef CONFIG_FUNCTION_TRACER + +#define MCOUNT_ADDR ((long)(_mcount)) +#define MCOUNT_INSN_SIZE 8 /* sizeof mcount call */ + +#ifndef __ASSEMBLY__ +extern void _mcount(void); +extern void ftrace_call_graph(void); +#endif + +#endif /* CONFIG_FUNCTION_TRACER */ +#endif /* _ASM_MICROBLAZE_FTRACE */ diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index c465a5c4669..d5ee3264cd7 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile @@ -2,6 +2,16 @@ # Makefile # +ifdef CONFIG_FUNCTION_TRACER +# Do not trace early boot code and low level code +CFLAGS_REMOVE_timer.o = -pg +CFLAGS_REMOVE_intc.o = -pg +CFLAGS_REMOVE_early_printk.o = -pg +CFLAGS_REMOVE_selfmod.o = -pg +CFLAGS_REMOVE_heartbeat.o = -pg +CFLAGS_REMOVE_ftrace.o = -pg +endif + extra-y := head.o vmlinux.lds obj-y += exceptions.o \ @@ -17,5 +27,6 @@ obj-$(CONFIG_HEART_BEAT) += heartbeat.o obj-$(CONFIG_MODULES) += microblaze_ksyms.o module.o obj-$(CONFIG_MMU) += misc.o obj-$(CONFIG_STACKTRACE) += stacktrace.o +obj-$(CONFIG_FUNCTION_TRACER) += mcount.o obj-y += entry$(MMU).o diff --git a/arch/microblaze/kernel/cpu/Makefile b/arch/microblaze/kernel/cpu/Makefile index 20646e54927..59cc7bceaf8 100644 --- a/arch/microblaze/kernel/cpu/Makefile +++ b/arch/microblaze/kernel/cpu/Makefile @@ -2,6 +2,10 @@ # Build the appropriate CPU version support # +ifdef CONFIG_FUNCTION_TRACER +CFLAGS_REMOVE_cache.o = -pg +endif + EXTRA_CFLAGS += -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \ -DCPU_REV=$(CPU_REV) diff --git a/arch/microblaze/kernel/mcount.S b/arch/microblaze/kernel/mcount.S new file mode 100644 index 00000000000..a257a1b75ed --- /dev/null +++ b/arch/microblaze/kernel/mcount.S @@ -0,0 +1,105 @@ +/* + * Low-level ftrace handling + * + * Copyright (C) 2009 Michal Simek + * Copyright (C) 2009 PetaLogix + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of this + * archive for more details. + */ + +#include + +#define NOALIGN_ENTRY(name) .globl name; name: + +/* FIXME MS: I think that I don't need to save all regs */ +#define SAVE_REGS \ + addik r1, r1, -120; \ + swi r2, r1, 4; \ + swi r3, r1, 8; \ + swi r4, r1, 12; \ + swi r5, r1, 116; \ + swi r6, r1, 16; \ + swi r7, r1, 20; \ + swi r8, r1, 24; \ + swi r9, r1, 28; \ + swi r10, r1, 32; \ + swi r11, r1, 36; \ + swi r12, r1, 40; \ + swi r13, r1, 44; \ + swi r14, r1, 48; \ + swi r16, r1, 52; \ + swi r17, r1, 56; \ + swi r18, r1, 60; \ + swi r19, r1, 64; \ + swi r20, r1, 68; \ + swi r21, r1, 72; \ + swi r22, r1, 76; \ + swi r23, r1, 80; \ + swi r24, r1, 84; \ + swi r25, r1, 88; \ + swi r26, r1, 92; \ + swi r27, r1, 96; \ + swi r28, r1, 100; \ + swi r29, r1, 104; \ + swi r30, r1, 108; \ + swi r31, r1, 112; + +#define RESTORE_REGS \ + lwi r2, r1, 4; \ + lwi r3, r1, 8; \ + lwi r4, r1, 12; \ + lwi r5, r1, 116; \ + lwi r6, r1, 16; \ + lwi r7, r1, 20; \ + lwi r8, r1, 24; \ + lwi r9, r1, 28; \ + lwi r10, r1, 32; \ + lwi r11, r1, 36; \ + lwi r12, r1, 40; \ + lwi r13, r1, 44; \ + lwi r14, r1, 48; \ + lwi r16, r1, 52; \ + lwi r17, r1, 56; \ + lwi r18, r1, 60; \ + lwi r19, r1, 64; \ + lwi r20, r1, 68; \ + lwi r21, r1, 72; \ + lwi r22, r1, 76; \ + lwi r23, r1, 80; \ + lwi r24, r1, 84; \ + lwi r25, r1, 88; \ + lwi r26, r1, 92; \ + lwi r27, r1, 96; \ + lwi r28, r1, 100; \ + lwi r29, r1, 104; \ + lwi r30, r1, 108; \ + lwi r31, r1, 112; \ + addik r1, r1, 120; + +ENTRY(ftrace_stub) + rtsd r15, 8; + nop; + +ENTRY(_mcount) + SAVE_REGS + swi r15, r1, 0; + /* MS: test function trace if is taken or not */ + lwi r20, r0, ftrace_trace_function; + addik r6, r0, ftrace_stub; + cmpu r5, r20, r6; /* ftrace_trace_function != ftrace_stub */ + beqid r5, end; /* MS: not taken -> jump over */ + nop; +/* static normal trace */ + lwi r6, r1, 120; /* MS: load parent addr */ + addik r5, r15, 0; /* MS: load current function addr */ + /* MS: here is dependency on previous code */ + brald r15, r20; /* MS: jump to ftrace handler */ + nop; +end: + lwi r15, r1, 0; + RESTORE_REGS + + rtsd r15, 8; /* MS: jump back */ + nop; diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c index 59ff20e33e0..bc4dcb7d386 100644 --- a/arch/microblaze/kernel/microblaze_ksyms.c +++ b/arch/microblaze/kernel/microblaze_ksyms.c @@ -18,6 +18,7 @@ #include #include #include +#include #include /* @@ -47,3 +48,7 @@ extern void __umodsi3(void); EXPORT_SYMBOL(__umodsi3); extern char *_ebss; EXPORT_SYMBOL_GPL(_ebss); +#ifdef CONFIG_FUNCTION_TRACER +extern void _mcount(void); +EXPORT_SYMBOL(_mcount); +#endif -- cgit v1.2.3-18-g5258 From 6d9e60ce30a1be35491c74df00aaa25d869f8a02 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 16 Nov 2009 09:55:08 +0100 Subject: microblaze: ftrace: enable HAVE_FUNCTION_TRACE_MCOUNT_TEST Implement MCOUNT_TEST in asm code - it is faster than use generic code Signed-off-by: Michal Simek --- arch/microblaze/Kconfig | 1 + arch/microblaze/kernel/mcount.S | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'arch/microblaze') diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 18003ca0819..cccf3adfae5 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -7,6 +7,7 @@ config MICROBLAZE def_bool y select HAVE_LMB select HAVE_FUNCTION_TRACER + select HAVE_FUNCTION_TRACE_MCOUNT_TEST select USB_ARCH_HAS_EHCI select ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/arch/microblaze/kernel/mcount.S b/arch/microblaze/kernel/mcount.S index a257a1b75ed..97eef3eea94 100644 --- a/arch/microblaze/kernel/mcount.S +++ b/arch/microblaze/kernel/mcount.S @@ -85,6 +85,11 @@ ENTRY(ftrace_stub) ENTRY(_mcount) SAVE_REGS swi r15, r1, 0; + /* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST begin of checking */ + lwi r5, r0, function_trace_stop; + bneid r5, end; + nop; + /* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST end of checking */ /* MS: test function trace if is taken or not */ lwi r20, r0, ftrace_trace_function; addik r6, r0, ftrace_stub; -- cgit v1.2.3-18-g5258 From 7d241ff0567b9503d79ee775c40927d09b509f83 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 10 Dec 2009 14:15:44 +0100 Subject: microblaze: ftrace: Add dynamic trace support With dynamic function tracer, by default, _mcount is defined as an "empty" function, it returns directly without any more action. When enabling it in user-space, it will jump to a real tracing function(ftrace_caller), and do the real job for us. Differ from the static function tracer, dynamic function tracer provides two functions ftrace_make_call()/ftrace_make_nop() to enable/disable the tracing of some indicated kernel functions(set_ftrace_filter). In the kernel version, there is only one "_mcount" string for every kernel function, so, we just need to match this one in mcount_regex of scripts/recordmcount.pl. For more information please look at code and Documentation/trace folder. Steven ACK that scripts/recordmcount.pl part. Acked-by: Steven Rostedt Signed-off-by: Michal Simek --- arch/microblaze/Kconfig | 2 + arch/microblaze/include/asm/ftrace.h | 11 +++ arch/microblaze/kernel/Makefile | 2 +- arch/microblaze/kernel/ftrace.c | 151 +++++++++++++++++++++++++++++++++++ arch/microblaze/kernel/mcount.S | 13 +++ 5 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 arch/microblaze/kernel/ftrace.c (limited to 'arch/microblaze') diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index cccf3adfae5..102d73aa106 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -8,6 +8,8 @@ config MICROBLAZE select HAVE_LMB select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACE_MCOUNT_TEST + select HAVE_DYNAMIC_FTRACE + select HAVE_FTRACE_MCOUNT_RECORD select USB_ARCH_HAS_EHCI select ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/arch/microblaze/include/asm/ftrace.h b/arch/microblaze/include/asm/ftrace.h index 22beec58c02..fd2fa2eca62 100644 --- a/arch/microblaze/include/asm/ftrace.h +++ b/arch/microblaze/include/asm/ftrace.h @@ -11,5 +11,16 @@ extern void _mcount(void); extern void ftrace_call_graph(void); #endif +#ifdef CONFIG_DYNAMIC_FTRACE +/* reloction of mcount call site is the same as the address */ +static inline unsigned long ftrace_call_adjust(unsigned long addr) +{ + return addr; +} + +struct dyn_arch_ftrace { +}; +#endif /* CONFIG_DYNAMIC_FTRACE */ + #endif /* CONFIG_FUNCTION_TRACER */ #endif /* _ASM_MICROBLAZE_FTRACE */ diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index d5ee3264cd7..b07594eccf9 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile @@ -27,6 +27,6 @@ obj-$(CONFIG_HEART_BEAT) += heartbeat.o obj-$(CONFIG_MODULES) += microblaze_ksyms.o module.o obj-$(CONFIG_MMU) += misc.o obj-$(CONFIG_STACKTRACE) += stacktrace.o -obj-$(CONFIG_FUNCTION_TRACER) += mcount.o +obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o mcount.o obj-y += entry$(MMU).o diff --git a/arch/microblaze/kernel/ftrace.c b/arch/microblaze/kernel/ftrace.c new file mode 100644 index 00000000000..c1889b101cb --- /dev/null +++ b/arch/microblaze/kernel/ftrace.c @@ -0,0 +1,151 @@ +/* + * Ftrace support for Microblaze. + * + * Copyright (C) 2009 Michal Simek + * Copyright (C) 2009 PetaLogix + * + * Based on MIPS and PowerPC ftrace code + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include + +#ifdef CONFIG_DYNAMIC_FTRACE +/* save value to addr - it is save to do it in asm */ +static int ftrace_modify_code(unsigned long addr, unsigned int value) +{ + int faulted = 0; + + __asm__ __volatile__(" 1: swi %2, %1, 0; \ + addik %0, r0, 0; \ + 2: \ + .section .fixup, \"ax\"; \ + 3: brid 2b; \ + addik %0, r0, 1; \ + .previous; \ + .section __ex_table,\"a\"; \ + .word 1b,3b; \ + .previous;" \ + : "=r" (faulted) + : "r" (addr), "r" (value) + ); + + if (unlikely(faulted)) + return -EFAULT; + + return 0; +} + +#define MICROBLAZE_NOP 0x80000000 +#define MICROBLAZE_BRI 0xb800000C + +static unsigned int recorded; /* if save was or not */ +static unsigned int imm; /* saving whole imm instruction */ + +/* There are two approaches howto solve ftrace_make nop function - look below */ +#undef USE_FTRACE_NOP + +#ifdef USE_FTRACE_NOP +static unsigned int bralid; /* saving whole bralid instruction */ +#endif + +int ftrace_make_nop(struct module *mod, + struct dyn_ftrace *rec, unsigned long addr) +{ + /* we have this part of code which we are working with + * b000c000 imm -16384 + * b9fc8e30 bralid r15, -29136 // c0008e30 <_mcount> + * 80000000 or r0, r0, r0 + * + * The first solution (!USE_FTRACE_NOP-could be called branch solution) + * b000c000 bri 12 (0xC - jump to any other instruction) + * b9fc8e30 bralid r15, -29136 // c0008e30 <_mcount> + * 80000000 or r0, r0, r0 + * any other instruction + * + * The second solution (USE_FTRACE_NOP) - no jump just nops + * 80000000 or r0, r0, r0 + * 80000000 or r0, r0, r0 + * 80000000 or r0, r0, r0 + */ + int ret = 0; + + if (recorded == 0) { + recorded = 1; + imm = *(unsigned int *)rec->ip; + pr_debug("%s: imm:0x%x\n", __func__, imm); +#ifdef USE_FTRACE_NOP + bralid = *(unsigned int *)(rec->ip + 4); + pr_debug("%s: bralid 0x%x\n", __func__, bralid); +#endif /* USE_FTRACE_NOP */ + } + +#ifdef USE_FTRACE_NOP + ret = ftrace_modify_code(rec->ip, MICROBLAZE_NOP); + ret += ftrace_modify_code(rec->ip + 4, MICROBLAZE_NOP); +#else /* USE_FTRACE_NOP */ + ret = ftrace_modify_code(rec->ip, MICROBLAZE_BRI); +#endif /* USE_FTRACE_NOP */ + return ret; +} + +static int ret_addr; /* initialized as 0 by default */ + +/* I believe that first is called ftrace_make_nop before this function */ +int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) +{ + int ret; + ret_addr = addr; /* saving where the barrier jump is */ + pr_debug("%s: addr:0x%x, rec->ip: 0x%x, imm:0x%x\n", + __func__, (unsigned int)addr, (unsigned int)rec->ip, imm); + ret = ftrace_modify_code(rec->ip, imm); +#ifdef USE_FTRACE_NOP + pr_debug("%s: bralid:0x%x\n", __func__, bralid); + ret += ftrace_modify_code(rec->ip + 4, bralid); +#endif /* USE_FTRACE_NOP */ + return ret; +} + +int __init ftrace_dyn_arch_init(void *data) +{ + /* The return code is retured via data */ + *(unsigned long *)data = 0; + + return 0; +} + +int ftrace_update_ftrace_func(ftrace_func_t func) +{ + unsigned long ip = (unsigned long)(&ftrace_call); + unsigned int upper = (unsigned int)func; + unsigned int lower = (unsigned int)func; + int ret = 0; + + /* create proper saving to ftrace_call poll */ + upper = 0xb0000000 + (upper >> 16); /* imm func_upper */ + lower = 0x32800000 + (lower & 0xFFFF); /* addik r20, r0, func_lower */ + + pr_debug("%s: func=0x%x, ip=0x%x, upper=0x%x, lower=0x%x\n", + __func__, (unsigned int)func, (unsigned int)ip, upper, lower); + + /* save upper and lower code */ + ret = ftrace_modify_code(ip, upper); + ret += ftrace_modify_code(ip + 4, lower); + + /* We just need to remove the rtsd r15, 8 by NOP */ + BUG_ON(!ret_addr); + if (ret_addr) + ret += ftrace_modify_code(ret_addr, MICROBLAZE_NOP); + else + ret = 1; /* fault */ + + /* All changes are done - lets do caches consistent */ + flush_icache(); + return ret; +} + +#endif /* CONFIG_DYNAMIC_FTRACE */ diff --git a/arch/microblaze/kernel/mcount.S b/arch/microblaze/kernel/mcount.S index 97eef3eea94..30aaf8fb55b 100644 --- a/arch/microblaze/kernel/mcount.S +++ b/arch/microblaze/kernel/mcount.S @@ -83,6 +83,12 @@ ENTRY(ftrace_stub) nop; ENTRY(_mcount) +#ifdef CONFIG_DYNAMIC_FTRACE +ENTRY(ftrace_caller) + /* MS: It is just barrier which is removed from C code */ + rtsd r15, 8 + nop +#endif /* CONFIG_DYNAMIC_FTRACE */ SAVE_REGS swi r15, r1, 0; /* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST begin of checking */ @@ -90,12 +96,19 @@ ENTRY(_mcount) bneid r5, end; nop; /* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST end of checking */ +#ifndef CONFIG_DYNAMIC_FTRACE /* MS: test function trace if is taken or not */ lwi r20, r0, ftrace_trace_function; addik r6, r0, ftrace_stub; cmpu r5, r20, r6; /* ftrace_trace_function != ftrace_stub */ beqid r5, end; /* MS: not taken -> jump over */ nop; +#else /* CONFIG_DYNAMIC_FTRACE */ +NOALIGN_ENTRY(ftrace_call) +/* instruction for setup imm FUNC_part1, addik r20, r0, FUNC_part2 */ + nop + nop +#endif /* CONFIG_DYNAMIC_FTRACE */ /* static normal trace */ lwi r6, r1, 120; /* MS: load parent addr */ addik r5, r15, 0; /* MS: load current function addr */ -- cgit v1.2.3-18-g5258 From a0d3e66522e8f6119f002cf31e5d92d7ae73b409 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 16 Nov 2009 10:32:10 +0100 Subject: microblaze: ftrace: add function graph support For more information look at Documentation/trace folder. Signed-off-by: Michal Simek --- arch/microblaze/Kconfig | 1 + arch/microblaze/kernel/ftrace.c | 58 +++++++++++++++++++++++++++++++++++++++++ arch/microblaze/kernel/mcount.S | 41 +++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) (limited to 'arch/microblaze') diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 102d73aa106..e297802b832 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -8,6 +8,7 @@ config MICROBLAZE select HAVE_LMB select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACE_MCOUNT_TEST + select HAVE_FUNCTION_GRAPH_TRACER select HAVE_DYNAMIC_FTRACE select HAVE_FTRACE_MCOUNT_RECORD select USB_ARCH_HAS_EHCI diff --git a/arch/microblaze/kernel/ftrace.c b/arch/microblaze/kernel/ftrace.c index c1889b101cb..0952a8b52c3 100644 --- a/arch/microblaze/kernel/ftrace.c +++ b/arch/microblaze/kernel/ftrace.c @@ -14,6 +14,64 @@ #include #include +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +/* + * Hook the return address and push it in the stack of return addrs + * in current thread info. + */ +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) +{ + unsigned long old; + int faulted, err; + struct ftrace_graph_ent trace; + unsigned long return_hooker = (unsigned long) + &return_to_handler; + + if (unlikely(atomic_read(¤t->tracing_graph_pause))) + return; + + /* + * Protect against fault, even if it shouldn't + * happen. This tool is too much intrusive to + * ignore such a protection. + */ + asm volatile(" 1: lwi %0, %2, 0; \ + 2: swi %3, %2, 0; \ + addik %1, r0, 0; \ + 3: \ + .section .fixup, \"ax\"; \ + 4: brid 3b; \ + addik %1, r0, 1; \ + .previous; \ + .section __ex_table,\"a\"; \ + .word 1b,4b; \ + .word 2b,4b; \ + .previous;" \ + : "=&r" (old), "=r" (faulted) + : "r" (parent), "r" (return_hooker) + ); + + if (unlikely(faulted)) { + ftrace_graph_stop(); + WARN_ON(1); + return; + } + + err = ftrace_push_return_trace(old, self_addr, &trace.depth, 0); + if (err == -EBUSY) { + *parent = old; + return; + } + + trace.func = self_addr; + /* Only trace if the calling function expects to */ + if (!ftrace_graph_entry(&trace)) { + current->curr_ret_stack--; + *parent = old; + } +} +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ + #ifdef CONFIG_DYNAMIC_FTRACE /* save value to addr - it is save to do it in asm */ static int ftrace_modify_code(unsigned long addr, unsigned int value) diff --git a/arch/microblaze/kernel/mcount.S b/arch/microblaze/kernel/mcount.S index 30aaf8fb55b..84a19458c74 100644 --- a/arch/microblaze/kernel/mcount.S +++ b/arch/microblaze/kernel/mcount.S @@ -96,6 +96,27 @@ ENTRY(ftrace_caller) bneid r5, end; nop; /* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST end of checking */ +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + lwi r5, r0, ftrace_graph_return; + addik r6, r0, ftrace_stub; /* asm implementation */ + cmpu r5, r5, r6; /* ftrace_graph_return != ftrace_stub */ + beqid r5, end_graph_tracer; + nop; + + lwi r6, r0, ftrace_graph_entry; + addik r5, r0, ftrace_graph_entry_stub; /* implemented in C */ + cmpu r5, r5, r6; /* ftrace_graph_entry != ftrace_graph_entry_stub */ + beqid r5, end_graph_tracer; + nop; + addik r5, r1, 120; /* MS: load parent addr */ + addik r6, r15, 0; /* MS: load current function addr */ + bralid r15, prepare_ftrace_return; + nop; + /* MS: graph was taken that's why - can jump over function trace */ + brid end; + nop; +end_graph_tracer: +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ #ifndef CONFIG_DYNAMIC_FTRACE /* MS: test function trace if is taken or not */ lwi r20, r0, ftrace_trace_function; @@ -121,3 +142,23 @@ end: rtsd r15, 8; /* MS: jump back */ nop; + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +ENTRY(return_to_handler) + nop; /* MS: just barrier for rtsd r15, 8 */ + nop; + SAVE_REGS + swi r15, r1, 0; + + /* MS: find out returning address */ + bralid r15, ftrace_return_to_handler; + nop; + + /* MS: return value from ftrace_return_to_handler is my returning addr + * must be before restore regs because I have to restore r3 content */ + addik r15, r3, 0; + RESTORE_REGS + + rtsd r15, 8; /* MS: jump back */ + nop; +#endif /* CONFIG_FUNCTION_TRACER */ -- cgit v1.2.3-18-g5258 From 4f911b0daf0f7028a4fe792b701a48d10da36d84 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 16 Nov 2009 10:34:15 +0100 Subject: microblaze: ftrace: Add dynamic function graph tracer This patch add support for dynamic function graph tracer. There is one my expactation that I can do flush_icache after all code modification. On microblaze is this safer than do flush for every entry. For icache is used name flush but correct should be invalidation - this will be fix in upcomming new cache implementaion and WB support. Signed-off-by: Michal Simek --- arch/microblaze/kernel/ftrace.c | 28 ++++++++++++++++++++++++++++ arch/microblaze/kernel/mcount.S | 6 ++++++ 2 files changed, 34 insertions(+) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/ftrace.c b/arch/microblaze/kernel/ftrace.c index 0952a8b52c3..388b31ca65a 100644 --- a/arch/microblaze/kernel/ftrace.c +++ b/arch/microblaze/kernel/ftrace.c @@ -206,4 +206,32 @@ int ftrace_update_ftrace_func(ftrace_func_t func) return ret; } +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +unsigned int old_jump; /* saving place for jump instruction */ + +int ftrace_enable_ftrace_graph_caller(void) +{ + unsigned int ret; + unsigned long ip = (unsigned long)(&ftrace_call_graph); + + old_jump = *(unsigned int *)ip; /* save jump over instruction */ + ret = ftrace_modify_code(ip, MICROBLAZE_NOP); + flush_icache(); + + pr_debug("%s: Replace instruction: 0x%x\n", __func__, old_jump); + return ret; +} + +int ftrace_disable_ftrace_graph_caller(void) +{ + unsigned int ret; + unsigned long ip = (unsigned long)(&ftrace_call_graph); + + ret = ftrace_modify_code(ip, old_jump); + flush_icache(); + + pr_debug("%s\n", __func__); + return ret; +} +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ #endif /* CONFIG_DYNAMIC_FTRACE */ diff --git a/arch/microblaze/kernel/mcount.S b/arch/microblaze/kernel/mcount.S index 84a19458c74..e7eaa7a8cbd 100644 --- a/arch/microblaze/kernel/mcount.S +++ b/arch/microblaze/kernel/mcount.S @@ -97,6 +97,7 @@ ENTRY(ftrace_caller) nop; /* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST end of checking */ #ifdef CONFIG_FUNCTION_GRAPH_TRACER +#ifndef CONFIG_DYNAMIC_FTRACE lwi r5, r0, ftrace_graph_return; addik r6, r0, ftrace_stub; /* asm implementation */ cmpu r5, r5, r6; /* ftrace_graph_return != ftrace_stub */ @@ -108,6 +109,11 @@ ENTRY(ftrace_caller) cmpu r5, r5, r6; /* ftrace_graph_entry != ftrace_graph_entry_stub */ beqid r5, end_graph_tracer; nop; +#else /* CONFIG_DYNAMIC_FTRACE */ +NOALIGN_ENTRY(ftrace_call_graph) + /* MS: jump over graph function - replaced from C code */ + bri end_graph_tracer +#endif /* CONFIG_DYNAMIC_FTRACE */ addik r5, r1, 120; /* MS: load parent addr */ addik r6, r15, 0; /* MS: load current function addr */ bralid r15, prepare_ftrace_return; -- cgit v1.2.3-18-g5258 From 5dd48a235c3f78620e582ebb253d64d02747d173 Mon Sep 17 00:00:00 2001 From: "steve@digidescorp.com" Date: Fri, 13 Nov 2009 16:08:29 -0600 Subject: microblaze: Fix pfn_valid() for noMMU Configuring DEBUG_SLAB causes a noMMU kernel to die during initialization with an invalid virtual address panic in kfree_debugcheck(). The panic is due to an improper definition of pfn_valid(). Signed-off-by: Steven J. Magnani Signed-off-by: Michal Simek --- arch/microblaze/include/asm/page.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h index 880c988c223..9b66c0fa9a3 100644 --- a/arch/microblaze/include/asm/page.h +++ b/arch/microblaze/include/asm/page.h @@ -164,7 +164,8 @@ extern int page_is_ram(unsigned long pfn); # endif /* CONFIG_MMU */ # ifndef CONFIG_MMU -# define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) <= max_mapnr) +# define pfn_valid(pfn) (((pfn) >= min_low_pfn) && \ + ((pfn) <= (min_low_pfn + max_mapnr))) # define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT) # else /* CONFIG_MMU */ # define ARCH_PFN_OFFSET (memory_start >> PAGE_SHIFT) -- cgit v1.2.3-18-g5258 From f7816e284b72820b295b2d377cc635d7305f6728 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 13 Nov 2009 08:26:49 +0100 Subject: microblaze: Remove saving and restoring before calling signal code Saving is done in SAVE_STATE macros that's why another save discard previous saved value. This change has no effect to normal programs because they ends in any exception and they are killed. On the other side has effect on debugging. Signed-off-by: Michal Simek --- arch/microblaze/kernel/entry.S | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index e3ecb36dd55..7417d9ad0d1 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S @@ -711,15 +711,11 @@ C_ENTRY(ret_from_exc): * (in a possibly modified form) after do_signal returns. * store return registers separately because this macros is use * for others exceptions */ - swi r3, r1, PTO + PT_R3; - swi r4, r1, PTO + PT_R4; la r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ add r6, r0, r0; /* Arg 2: sigset_t *oldset */ addi r7, r0, 0; /* Arg 3: int in_syscall */ bralid r15, do_signal; /* Handle any signals */ nop; - lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ - lwi r4, r1, PTO+PT_R4; /* Finally, return to user state. */ 1: swi r0, r0, PER_CPU(KM); /* Now officially in user state. */ -- cgit v1.2.3-18-g5258 From 753758304019fc7c2ef3af674f52a193b1606d15 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 29 Oct 2009 08:58:15 +0100 Subject: microblaze: Fix announce message for reset gpio I had to change message for gpio-reset because I always not to see it. Prefix RESET is big and visible. Signed-off-by: Michal Simek --- arch/microblaze/kernel/reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c index ce74a6f436e..789af930d72 100644 --- a/arch/microblaze/kernel/reset.c +++ b/arch/microblaze/kernel/reset.c @@ -87,7 +87,7 @@ void of_platform_reset_gpio_probe(void) /* Setup output direction */ gpio_set_value(handle, 0); - printk(KERN_INFO "Registered reset device: %d\n", handle); + printk(KERN_INFO "RESET: Registered gpio device: %d\n", handle); return; err: gpio_free(handle); -- cgit v1.2.3-18-g5258 From 67bf87665466c4ea93e2c54d66dfd4cdac011a4b Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 29 Oct 2009 10:12:59 +0100 Subject: microblaze: Support both levels for reset Till this patch reset always perform writen to 1. Now we can use negative logic and perform reset write to 0. It is opposite level than is currently read from that pin Signed-off-by: Michal Simek --- arch/microblaze/kernel/reset.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c index 789af930d72..a1721a33042 100644 --- a/arch/microblaze/kernel/reset.c +++ b/arch/microblaze/kernel/reset.c @@ -17,6 +17,7 @@ #include static int handle; /* reset pin handle */ +static unsigned int reset_val; static int of_reset_gpio_handle(void) { @@ -75,9 +76,9 @@ void of_platform_reset_gpio_probe(void) } /* get current setup value */ - ret = gpio_get_value(handle); + reset_val = gpio_get_value(handle); /* FIXME maybe worth to perform any action */ - pr_debug("Reset: Gpio output state: 0x%x\n", ret); + pr_debug("Reset: Gpio output state: 0x%x\n", reset_val); /* Setup GPIO as output */ ret = gpio_direction_output(handle, 0); @@ -87,7 +88,8 @@ void of_platform_reset_gpio_probe(void) /* Setup output direction */ gpio_set_value(handle, 0); - printk(KERN_INFO "RESET: Registered gpio device: %d\n", handle); + printk(KERN_INFO "RESET: Registered gpio device: %d, current val: %d\n", + handle, reset_val); return; err: gpio_free(handle); @@ -97,7 +99,7 @@ err: static void gpio_system_reset(void) { - gpio_set_value(handle, 1); + gpio_set_value(handle, 1 - reset_val); } #else #define gpio_system_reset() do {} while (0) -- cgit v1.2.3-18-g5258 From 6cec713b1629228527fb8f813003522817f55da1 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 15 Oct 2009 13:34:31 +0200 Subject: microblaze: Detect new 7.20.d version Signed-off-by: Michal Simek --- arch/microblaze/kernel/cpu/cpuinfo.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c index 3539babc1c1..a9aa5cf11c3 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo.c +++ b/arch/microblaze/kernel/cpu/cpuinfo.c @@ -29,6 +29,7 @@ const struct cpu_ver_key cpu_ver_lookup[] = { {"7.20.a", 0x0c}, {"7.20.b", 0x0d}, {"7.20.c", 0x0e}, + {"7.20.d", 0x0f}, /* FIXME There is no keycode defined in MBV for these versions */ {"2.10.a", 0x10}, {"3.00.a", 0x20}, -- cgit v1.2.3-18-g5258 From 44e4e196a9b3a703ebe273ffe3fb6cda326fe5d3 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 8 Oct 2009 13:06:42 +0200 Subject: microblaze: Fix cache_line_lenght We used cache_line as cache_line_lenght. For this reason we did cache flushing 4 times longer than was necessary. Signed-off-by: Michal Simek --- arch/microblaze/include/asm/cpuinfo.h | 4 ++-- arch/microblaze/kernel/cpu/cache.c | 16 ++++++++-------- arch/microblaze/ke