From 74181295fbc6e65047e85529aa74457d82355ffc Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Thu, 27 May 2010 22:46:46 +0000 Subject: Blackfin: allow cache funcs to be in L1 for IFLUSH Anomaly 05000491 Anomaly 05000491 says that IFLUSH cannot have certain types of memory stalls triggered before it has completed in order to function correctly. One such condition is that it be in L1 instruction. So add a config option to move it there, default it to on, and throw up a warning when it is turned off and this anomaly exists. Since the anomaly should be worked around, we can drop the older method of calling IFLUSH multiple times. Signed-off-by: Mike Frysinger Signed-off-by: Sonic Zhang --- arch/blackfin/Kconfig | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch/blackfin/Kconfig') diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index f66294b4f9d..de4bd432b43 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -853,6 +853,18 @@ config CPLB_SWITCH_TAB_L1 If enabled, the CPLB Switch Tables are linked into L1 data memory. (less latency) +config CACHE_FLUSH_L1 + bool "Locate cache flush funcs in L1 Inst Memory" + default y + help + If enabled, the Blackfin cache flushing functions are linked + into L1 instruction memory. + + Note that this might be required to address anomalies, but + these functions are pretty small, so it shouldn't be too bad. + If you are using a processor affected by an anomaly, the build + system will double check for you and prevent it. + config APP_STACK_L1 bool "Support locating application stack in L1 Scratch Memory" default y -- cgit v1.2.3 From 67df6cc665dc3441bf5eb2ad7018e969463a2588 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 19 Jul 2010 05:37:54 +0000 Subject: Blackfin: add support for LZO compressed kernels Signed-off-by: Mike Frysinger --- arch/blackfin/Kconfig | 1 + arch/blackfin/Makefile | 3 ++- arch/blackfin/boot/Makefile | 11 +++++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) (limited to 'arch/blackfin/Kconfig') diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index de4bd432b43..0f63ed4fe14 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -32,6 +32,7 @@ config BLACKFIN select HAVE_KERNEL_GZIP if RAMKERNEL select HAVE_KERNEL_BZIP2 if RAMKERNEL select HAVE_KERNEL_LZMA if RAMKERNEL + select HAVE_KERNEL_LZO if RAMKERNEL select HAVE_OPROFILE select ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index 9d5ffaf5492..3e65b0ffe08 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile @@ -140,7 +140,7 @@ archclean: INSTALL_PATH ?= /tftpboot boot := arch/$(ARCH)/boot -BOOT_TARGETS = vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.xip +BOOT_TARGETS = vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.lzo vmImage.xip PHONY += $(BOOT_TARGETS) install KBUILD_IMAGE := $(boot)/vmImage @@ -158,6 +158,7 @@ define archhelp echo ' vmImage.bz2 - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.bz2)' echo '* vmImage.gz - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.gz)' echo ' vmImage.lzma - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lzma)' + echo ' vmImage.lzo - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lzo)' echo ' vmImage.xip - XIP Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.xip)' echo ' install - Install kernel using' echo ' (your) ~/bin/$(INSTALLKERNEL) or' diff --git a/arch/blackfin/boot/Makefile b/arch/blackfin/boot/Makefile index d1b3d6051fd..13d2dbd658e 100644 --- a/arch/blackfin/boot/Makefile +++ b/arch/blackfin/boot/Makefile @@ -8,8 +8,8 @@ MKIMAGE := $(srctree)/scripts/mkuboot.sh -targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.xip -extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xip +targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.lzo vmImage.xip +extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.xip UIMAGE_OPTS-y := UIMAGE_OPTS-$(CONFIG_RAMKERNEL) += -a $(CONFIG_BOOT_LOAD) @@ -33,6 +33,9 @@ $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE $(call if_changed,lzma) +$(obj)/vmlinux.bin.lzo: $(obj)/vmlinux.bin FORCE + $(call if_changed,lzo) + # The mkimage tool wants 64bytes prepended to the image quiet_cmd_mk_bin_xip = BIN $@ cmd_mk_bin_xip = ( printf '%64s' | tr ' ' '\377' ; cat $< ) > $@ @@ -51,6 +54,9 @@ $(obj)/vmImage.gz: $(obj)/vmlinux.bin.gz $(obj)/vmImage.lzma: $(obj)/vmlinux.bin.lzma $(call if_changed,uimage,lzma) +$(obj)/vmImage.lzo: $(obj)/vmlinux.bin.lzo + $(call if_changed,uimage,lzo) + $(obj)/vmImage.xip: $(obj)/vmlinux.bin.xip $(call if_changed,uimage,none) @@ -58,6 +64,7 @@ suffix-y := bin suffix-$(CONFIG_KERNEL_GZIP) := gz suffix-$(CONFIG_KERNEL_BZIP2) := bz2 suffix-$(CONFIG_KERNEL_LZMA) := lzma +suffix-$(CONFIG_KERNEL_LZO) := lzo suffix-$(CONFIG_ROMKERNEL) := xip $(obj)/vmImage: $(obj)/vmImage.$(suffix-y) -- cgit v1.2.3 From f5074429621ceb0ec42f8116bd51d02c031faf82 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 21 Jul 2010 09:13:02 -0400 Subject: Blackfin: add support for dynamic ftrace Signed-off-by: Mike Frysinger --- arch/blackfin/Kconfig | 2 + arch/blackfin/include/asm/ftrace.h | 16 +++++++ arch/blackfin/kernel/Makefile | 1 + arch/blackfin/kernel/ftrace-entry.S | 85 ++++++++++++++++++++++++++++++++---- arch/blackfin/kernel/ftrace.c | 86 ++++++++++++++++++++++++++++++++++++- 5 files changed, 181 insertions(+), 9 deletions(-) (limited to 'arch/blackfin/Kconfig') diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 0f63ed4fe14..10bdd8de025 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -25,6 +25,8 @@ config BLACKFIN def_bool y select HAVE_ARCH_KGDB select HAVE_ARCH_TRACEHOOK + select HAVE_DYNAMIC_FTRACE + select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACE_MCOUNT_TEST diff --git a/arch/blackfin/include/asm/ftrace.h b/arch/blackfin/include/asm/ftrace.h index 4cfe2d9ba7e..8a029505d7b 100644 --- a/arch/blackfin/include/asm/ftrace.h +++ b/arch/blackfin/include/asm/ftrace.h @@ -12,6 +12,22 @@ #ifndef __ASSEMBLY__ +#ifdef CONFIG_DYNAMIC_FTRACE + +extern void _mcount(void); +#define MCOUNT_ADDR ((unsigned long)_mcount) + +static inline unsigned long ftrace_call_adjust(unsigned long addr) +{ + return addr; +} + +struct dyn_arch_ftrace { + /* No extra data needed for Blackfin */ +}; + +#endif + #ifdef CONFIG_FRAME_POINTER #include diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 30d0d1f01dc..ca5ccc77777 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -16,6 +16,7 @@ else obj-y += time.o endif +obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_FUNCTION_TRACER) += ftrace-entry.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o CFLAGS_REMOVE_ftrace.o = -pg diff --git a/arch/blackfin/kernel/ftrace-entry.S b/arch/blackfin/kernel/ftrace-entry.S index d66446b572c..7eed00bbd26 100644 --- a/arch/blackfin/kernel/ftrace-entry.S +++ b/arch/blackfin/kernel/ftrace-entry.S @@ -10,6 +10,18 @@ .text +#ifdef CONFIG_DYNAMIC_FTRACE + +/* Simple stub so we can boot the kernel until runtime patching has + * disabled all calls to this. Then it'll be unused. + */ +ENTRY(__mcount) +# if ANOMALY_05000371 + nop; nop; nop; nop; +# endif + rts; +ENDPROC(__mcount) + /* GCC will have called us before setting up the function prologue, so we * can clobber the normal scratch registers, but we need to make sure to * save/restore the registers used for argument passing (R0-R2) in case @@ -20,15 +32,65 @@ * function. And since GCC pushed the previous RETS for us, the previous * function will be waiting there. mmmm pie. */ +ENTRY(_ftrace_caller) +# ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST + /* optional micro optimization: return if stopped */ + p1.l = _function_trace_stop; + p1.h = _function_trace_stop; + r3 = [p1]; + cc = r3 == 0; + if ! cc jump _ftrace_stub (bp); +# endif + + /* save first/second/third function arg and the return register */ + [--sp] = r2; + [--sp] = r0; + [--sp] = r1; + [--sp] = rets; + + /* function_trace_call(unsigned long ip, unsigned long parent_ip): + * ip: this point was called by ... + * parent_ip: ... this function + * the ip itself will need adjusting for the mcount call + */ + r0 = rets; + r1 = [sp + 16]; /* skip the 4 local regs on stack */ + r0 += -MCOUNT_INSN_SIZE; + +.globl _ftrace_call +_ftrace_call: + call _ftrace_stub + +# ifdef CONFIG_FUNCTION_GRAPH_TRACER +.globl _ftrace_graph_call +_ftrace_graph_call: + nop; /* jump _ftrace_graph_caller; */ +# endif + + /* restore state and get out of dodge */ +.Lfinish_trace: + rets = [sp++]; + r1 = [sp++]; + r0 = [sp++]; + r2 = [sp++]; + +.globl _ftrace_stub +_ftrace_stub: + rts; +ENDPROC(_ftrace_caller) + +#else + +/* See documentation for _ftrace_caller */ ENTRY(__mcount) -#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST +# ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST /* optional micro optimization: return if stopped */ p1.l = _function_trace_stop; p1.h = _function_trace_stop; r3 = [p1]; cc = r3 == 0; if ! cc jump _ftrace_stub (bp); -#endif +# endif /* save third function arg early so we can do testing below */ [--sp] = r2; @@ -44,7 +106,7 @@ ENTRY(__mcount) cc = r2 == r3; if ! cc jump .Ldo_trace; -#ifdef CONFIG_FUNCTION_GRAPH_TRACER +# ifdef CONFIG_FUNCTION_GRAPH_TRACER /* if the ftrace_graph_return function pointer is not set to * the ftrace_stub entry, call prepare_ftrace_return(). */ @@ -64,7 +126,7 @@ ENTRY(__mcount) r3 = [p0]; cc = r2 == r3; if ! cc jump _ftrace_graph_caller; -#endif +# endif r2 = [sp++]; rts; @@ -103,6 +165,8 @@ _ftrace_stub: rts; ENDPROC(__mcount) +#endif + #ifdef CONFIG_FUNCTION_GRAPH_TRACER /* The prepare_ftrace_return() function is similar to the trace function * except it takes a pointer to the location of the frompc. This is so @@ -110,6 +174,7 @@ ENDPROC(__mcount) * purposes. */ ENTRY(_ftrace_graph_caller) +# ifndef CONFIG_DYNAMIC_FTRACE /* save first/second function arg and the return register */ [--sp] = r0; [--sp] = r1; @@ -118,9 +183,13 @@ ENTRY(_ftrace_graph_caller) /* prepare_ftrace_return(parent, self_addr, frame_pointer) */ r0 = sp; /* unsigned long *parent */ r1 = rets; /* unsigned long self_addr */ -#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST +# else + r0 = sp; /* unsigned long *parent */ + r1 = [sp]; /* unsigned long self_addr */ +# endif +# ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST r2 = fp; /* unsigned long frame_pointer */ -#endif +# endif r0 += 16; /* skip the 4 local regs on stack */ r1 += -MCOUNT_INSN_SIZE; call _prepare_ftrace_return; @@ -139,9 +208,9 @@ ENTRY(_return_to_handler) [--sp] = r1; /* get original return address */ -#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST +# ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST r0 = fp; /* Blackfin is sane, so omit this */ -#endif +# endif call _ftrace_return_to_handler; rets = r0; diff --git a/arch/blackfin/kernel/ftrace.c b/arch/blackfin/kernel/ftrace.c index a61d948ea92..48808a12b42 100644 --- a/arch/blackfin/kernel/ftrace.c +++ b/arch/blackfin/kernel/ftrace.c @@ -1,17 +1,101 @@ /* * ftrace graph code * - * Copyright (C) 2009 Analog Devices Inc. + * Copyright (C) 2009-2010 Analog Devices Inc. * Licensed under the GPL-2 or later. */ #include #include #include +#include #include +#include + +#ifdef CONFIG_DYNAMIC_FTRACE + +static const unsigned char mnop[] = { + 0x03, 0xc0, 0x00, 0x18, /* MNOP; */ + 0x03, 0xc0, 0x00, 0x18, /* MNOP; */ +}; + +static void bfin_make_pcrel24(unsigned char *insn, unsigned long src, + unsigned long dst) +{ + uint32_t pcrel = (dst - src) >> 1; + insn[0] = pcrel >> 16; + insn[1] = 0xe3; + insn[2] = pcrel; + insn[3] = pcrel >> 8; +} +#define bfin_make_pcrel24(insn, src, dst) bfin_make_pcrel24(insn, src, (unsigned long)(dst)) + +static int ftrace_modify_code(unsigned long ip, const unsigned char *code, + unsigned long len) +{ + int ret = probe_kernel_write((void *)ip, (void *)code, len); + flush_icache_range(ip, ip + len); + return ret; +} + +int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, + unsigned long addr) +{ + /* Turn the mcount call site into two MNOPs as those are 32bit insns */ + return ftrace_modify_code(rec->ip, mnop, sizeof(mnop)); +} + +int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) +{ + /* Restore the mcount call site */ + unsigned char call[8]; + call[0] = 0x67; /* [--SP] = RETS; */ + call[1] = 0x01; + bfin_make_pcrel24(&call[2], rec->ip + 2, addr); + call[6] = 0x27; /* RETS = [SP++]; */ + call[7] = 0x01; + return ftrace_modify_code(rec->ip, call, sizeof(call)); +} + +int ftrace_update_ftrace_func(ftrace_func_t func) +{ + unsigned char call[4]; + unsigned long ip = (unsigned long)&ftrace_call; + bfin_make_pcrel24(call, ip, func); + return ftrace_modify_code(ip, call, sizeof(call)); +} + +int __init ftrace_dyn_arch_init(void *data) +{ + /* return value is done indirectly via data */ + *(unsigned long *)data = 0; + + return 0; +} + +#endif #ifdef CONFIG_FUNCTION_GRAPH_TRACER +# ifdef CONFIG_DYNAMIC_FTRACE + +extern void ftrace_graph_call(void); + +int ftrace_enable_ftrace_graph_caller(void) +{ + unsigned long ip = (unsigned long)&ftrace_graph_call; + uint16_t jump_pcrel12 = ((unsigned long)&ftrace_graph_caller - ip) >> 1; + jump_pcrel12 |= 0x2000; + return ftrace_modify_code(ip, (void *)&jump_pcrel12, sizeof(jump_pcrel12)); +} + +int ftrace_disable_ftrace_graph_caller(void) +{ + return ftrace_modify_code((unsigned long)&ftrace_graph_call, empty_zero_page, 2); +} + +# endif + /* * Hook the return address and push it in the stack of return addrs * in current thread info. -- cgit v1.2.3 From efbd24b5b050c586c059ee68c57c09996e7be886 Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Mon, 2 Aug 2010 18:01:58 +0200 Subject: Blackfin: remove CONFIG_MEM_GENERIC_BOARD MEM_GENERIC_BOARD depends on GENERIC_BOARD, but this flag was removed in 4f25eb85d64640bc656e72917113a84701521b99, therefore all references to it from the source can be removed. Signed-off-by: Christian Dietrich Signed-off-by: Mike Frysinger --- arch/blackfin/Kconfig | 5 ----- arch/blackfin/include/asm/mem_init.h | 18 ------------------ 2 files changed, 23 deletions(-) (limited to 'arch/blackfin/Kconfig') diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 10bdd8de025..57ee4020436 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -331,11 +331,6 @@ config BF53x depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537) default y -config MEM_GENERIC_BOARD - bool - depends on GENERIC_BOARD - default y - config MEM_MT48LC64M4A2FB_7E bool depends on (BFIN533_STAMP) diff --git a/arch/blackfin/include/asm/mem_init.h b/arch/blackfin/include/asm/mem_init.h index 7c8fe834ff2..237579935e2 100644 --- a/arch/blackfin/include/asm/mem_init.h +++ b/arch/blackfin/include/asm/mem_init.h @@ -10,7 +10,6 @@ #if defined(CONFIG_MEM_MT48LC16M16A2TG_75) || \ defined(CONFIG_MEM_MT48LC64M4A2FB_7E) || \ defined(CONFIG_MEM_MT48LC16M8A2TG_75) || \ - defined(CONFIG_MEM_GENERIC_BOARD) || \ defined(CONFIG_MEM_MT48LC32M8A2_75) || \ defined(CONFIG_MEM_MT48LC8M32B2B5_7) || \ defined(CONFIG_MEM_MT48LC32M16A2TG_75) || \ @@ -178,7 +177,6 @@ #if defined(CONFIG_MEM_MT48LC32M8A2_75) || \ defined(CONFIG_MEM_MT48LC64M4A2FB_7E) || \ - defined(CONFIG_MEM_GENERIC_BOARD) || \ defined(CONFIG_MEM_MT48LC32M16A2TG_75) || \ defined(CONFIG_MEM_MT48LC16M16A2TG_75) || \ defined(CONFIG_MEM_MT48LC32M8A2_75) @@ -248,22 +246,6 @@ #define DDR_tWR DDR_TWR(MIN_DDR_SCLK(15)) #endif -#if defined(CONFIG_MEM_GENERIC_BOARD) -#define DDR_SIZE DEVSZ_512 -#define DDR_WIDTH DEVWD_16 -#define DDR_MAX_tCK 13 - -#define DDR_tRCD DDR_TRCD(3) -#define DDR_tWTR DDR_TWTR(2) -#define DDR_tWR DDR_TWR(2) -#define DDR_tMRD DDR_TMRD(2) -#define DDR_tRP DDR_TRP(3) -#define DDR_tRAS DDR_TRAS(7) -#define DDR_tRC DDR_TRC(10) -#define DDR_tRFC DDR_TRFC(12) -#define DDR_tREFI DDR_TREFI(1288) -#endif - #if (CONFIG_SCLK_HZ < DDR_CLK_HZ(DDR_MAX_tCK)) # error "CONFIG_SCLK_HZ is too small (