From 09378d7c21a806d5ddb75ebcae242d98cea30e44 Mon Sep 17 00:00:00 2001 From: Wanlong Gao Date: Wed, 1 Jun 2011 22:37:43 +0800 Subject: xtensa:fix the incompatible pointer type warning in time.c Fix the definition of the function ccount_read to be compatible to the member read of the structure clocksource. Signed-off-by: Wanlong Gao Signed-off-by: Chris Zankel --- arch/xtensa/kernel/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index ac62f9cf1e10..19b32a0eaebc 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -31,7 +31,7 @@ unsigned long ccount_per_jiffy; /* per 1/HZ */ unsigned long nsec_per_ccount; /* nsec per ccount increment */ #endif -static cycle_t ccount_read(void) +static cycle_t ccount_read(struct clocksource *cs) { return (cycle_t)get_ccount(); } -- cgit v1.2.1 From 02b25d811f949fc70badd6535dfaf13a3c5decf9 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Sat, 7 May 2011 20:55:42 +0200 Subject: xtensa: unbalanced parentheses Signed-off-by: Nicolas Kaiser Signed-off-by: Chris Zankel --- arch/xtensa/variants/s6000/gpio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/variants/s6000/gpio.c b/arch/xtensa/variants/s6000/gpio.c index b89541ba39ab..da9e85c13b08 100644 --- a/arch/xtensa/variants/s6000/gpio.c +++ b/arch/xtensa/variants/s6000/gpio.c @@ -164,7 +164,7 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc) int cirq; chip->irq_mask(&desc->irq_data); - chip->irq_ack(&desc->irq_data)); + chip->irq_ack(&desc->irq_data); pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask; cirq = IRQ_BASE - 1; while (pending) { @@ -173,7 +173,7 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc) pending >>= n; generic_handle_irq(cirq); } - chip->irq_unmask(&desc->irq_data)); + chip->irq_unmask(&desc->irq_data); } extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS]; -- cgit v1.2.1 From 6550162200b40d1e725167f8a617255c42b57552 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Tue, 13 Nov 2012 15:16:36 -0800 Subject: xtensa: add config option to disable linker relaxation The default linker behavior is to optimize identical literal values and remove unnecessary overhead from assembler-generated "longcall" sequences to reduce code size. Provide an option to disable this behavior to improve compile time. Signed-off-by: Chris Zankel --- arch/xtensa/Kconfig.debug | 13 +++++++++++-- arch/xtensa/Makefile | 4 ++++ 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/Kconfig.debug b/arch/xtensa/Kconfig.debug index 11c585295dd7..be5fb4c6243f 100644 --- a/arch/xtensa/Kconfig.debug +++ b/arch/xtensa/Kconfig.debug @@ -2,6 +2,15 @@ menu "Kernel hacking" source "lib/Kconfig.debug" -endmenu - +config LD_NO_RELAX + bool "Disable linker relaxation" + default n + help + Enable this function to disable link-time optimizations. + The default linker behavior is to combine identical literal + values to reduce code size and remove unnecessary overhead from + assembler-generated 'longcall' sequences. + Enabling this option improves the link time but increases the + code size, and possibly execution time. +endmenu diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index bb5ba61723f7..ab63c9beb930 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -49,6 +49,10 @@ KBUILD_CFLAGS += -pipe -mlongcalls KBUILD_CFLAGS += $(call cc-option,-mforce-no-pic,) +ifneq ($(CONFIG_LD_NO_RELAX),) +LDFLAGS := --no-relax +endif + vardirs := $(patsubst %,arch/xtensa/variants/%/,$(variant-y)) plfdirs := $(patsubst %,arch/xtensa/platforms/%/,$(platform-y)) -- cgit v1.2.1 From c0226e34a4293dee0e7c5787e1ebfc5ee8b44b7c Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 9 Aug 2012 05:25:35 +0400 Subject: xtensa: make DoubleExceptionVector literals fit the gap Manually load references to exc_table from the explicit literal in order to fit DoubleExceptionVector.literals into the available 16-byte gap before DoubleExceptionVector.text in the absence of link time relaxation. Without this fix DoubleExceptionVector.literal section overlaps DoubleExceptionVector.text section in the linked vmlinux image. Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/kernel/vectors.S | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index 4462c1e595c2..3a57c15f7942 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S @@ -225,7 +225,13 @@ ENTRY(_DoubleExceptionVector) /* Window overflow/underflow exception. Get stack pointer. */ mov a3, a2 - movi a2, exc_table + /* This explicit literal and the following references to it are made + * in order to fit DoubleExceptionVector.literals into the available + * 16-byte gap before DoubleExceptionVector.text in the absence of + * link time relaxation. See kernel/vmlinux.lds.S + */ + .literal .Lexc_table, exc_table + l32r a2, .Lexc_table l32i a2, a2, EXC_TABLE_KSTK /* Check for overflow/underflow exception, jump if overflow. */ @@ -255,7 +261,7 @@ ENTRY(_DoubleExceptionVector) s32i a0, a2, PT_AREG0 wsr a3, excsave1 # save a3 - movi a3, exc_table + l32r a3, .Lexc_table rsr a0, exccause s32i a0, a2, PT_DEPC # mark it as a regular exception @@ -267,7 +273,7 @@ ENTRY(_DoubleExceptionVector) /* a0: depc, a1: a1, a2: a2, a3: trashed, depc: a0, excsave1: a3 */ - movi a3, exc_table + l32r a3, .Lexc_table s32i a2, a3, EXC_TABLE_DOUBLE_SAVE # temporary variable /* Enter critical section. */ @@ -296,7 +302,7 @@ ENTRY(_DoubleExceptionVector) /* a0: avail, a1: a1, a2: kstk, a3: avail, depc: a2, excsave: a3 */ - movi a3, exc_table + l32r a3, .Lexc_table rsr a0, exccause addx4 a0, a0, a3 l32i a0, a0, EXC_TABLE_FAST_USER -- cgit v1.2.1 From d1538c4675f37d0eeb34bd38bec798b3b29a5a7e Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Fri, 16 Nov 2012 16:16:20 -0800 Subject: xtensa: provide proper assembler function boundaries with ENDPROC() Use ENDPROC() to mark the end of assembler functions. Signed-off-by: Chris Zankel --- arch/xtensa/kernel/align.S | 1 + arch/xtensa/kernel/coprocessor.S | 22 +++++++++++++++++ arch/xtensa/kernel/entry.S | 30 +++++++++++++++++++++-- arch/xtensa/kernel/head.S | 14 +++++++---- arch/xtensa/kernel/vectors.S | 51 ++++++++++++++++++++++++++-------------- arch/xtensa/lib/checksum.S | 5 +++- arch/xtensa/mm/misc.S | 49 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 147 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S index 934ae58e2c79..39d2f597382d 100644 --- a/arch/xtensa/kernel/align.S +++ b/arch/xtensa/kernel/align.S @@ -450,6 +450,7 @@ ENTRY(fast_unaligned) 1: movi a0, _user_exception jx a0 +ENDPROC(fast_unaligned) #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S index 54c3be313bfa..60bb13589249 100644 --- a/arch/xtensa/kernel/coprocessor.S +++ b/arch/xtensa/kernel/coprocessor.S @@ -43,10 +43,13 @@ /* IO protection is currently unsupported. */ ENTRY(fast_io_protect) + wsr a0, excsave1 movi a0, unrecoverable_exception callx0 a0 +ENDPROC(fast_io_protect) + #if XTENSA_HAVE_COPROCESSORS /* @@ -139,6 +142,7 @@ ENTRY(fast_io_protect) */ ENTRY(coprocessor_save) + entry a1, 32 s32i a0, a1, 0 movi a0, .Lsave_cp_regs_jump_table @@ -150,7 +154,10 @@ ENTRY(coprocessor_save) 1: l32i a0, a1, 0 retw +ENDPROC(coprocessor_save) + ENTRY(coprocessor_load) + entry a1, 32 s32i a0, a1, 0 movi a0, .Lload_cp_regs_jump_table @@ -162,6 +169,8 @@ ENTRY(coprocessor_load) 1: l32i a0, a1, 0 retw +ENDPROC(coprocessor_load) + /* * coprocessor_flush(struct task_info*, index) * a2 a3 @@ -178,6 +187,7 @@ ENTRY(coprocessor_load) ENTRY(coprocessor_flush) + entry a1, 32 s32i a0, a1, 0 movi a0, .Lsave_cp_regs_jump_table @@ -191,6 +201,8 @@ ENTRY(coprocessor_flush) 1: l32i a0, a1, 0 retw +ENDPROC(coprocessor_flush) + ENTRY(coprocessor_restore) entry a1, 32 s32i a0, a1, 0 @@ -205,6 +217,8 @@ ENTRY(coprocessor_restore) 1: l32i a0, a1, 0 retw +ENDPROC(coprocessor_restore) + /* * Entry condition: * @@ -220,10 +234,12 @@ ENTRY(coprocessor_restore) */ ENTRY(fast_coprocessor_double) + wsr a0, excsave1 movi a0, unrecoverable_exception callx0 a0 +ENDPROC(fast_coprocessor_double) ENTRY(fast_coprocessor) @@ -327,9 +343,15 @@ ENTRY(fast_coprocessor) rfe +ENDPROC(fast_coprocessor) + .data + ENTRY(coprocessor_owner) + .fill XCHAL_CP_MAX, 4, 0 +END(coprocessor_owner) + #endif /* XTENSA_HAVE_COPROCESSORS */ diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 90bfc1dbc13d..41ad9cfe9a2a 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -219,6 +219,7 @@ _user_exception: j common_exception +ENDPROC(user_exception) /* * First-level exit handler for kernel exceptions @@ -641,6 +642,8 @@ common_exception_exit: l32i a1, a1, PT_AREG1 rfde +ENDPROC(kernel_exception) + /* * Debug exception handler. * @@ -701,6 +704,7 @@ ENTRY(debug_exception) /* Debug exception while in exception mode. */ 1: j 1b // FIXME!! +ENDPROC(debug_exception) /* * We get here in case of an unrecoverable exception. @@ -751,6 +755,7 @@ ENTRY(unrecoverable_exception) 1: j 1b +ENDPROC(unrecoverable_exception) /* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */ @@ -929,6 +934,7 @@ ENTRY(fast_alloca) l32i a2, a2, PT_AREG2 rfe +ENDPROC(fast_alloca) /* * fast system calls. @@ -966,6 +972,8 @@ ENTRY(fast_syscall_kernel) j kernel_exception +ENDPROC(fast_syscall_kernel) + ENTRY(fast_syscall_user) /* Skip syscall. */ @@ -983,6 +991,8 @@ ENTRY(fast_syscall_user) j user_exception +ENDPROC(fast_syscall_user) + ENTRY(fast_syscall_unrecoverable) /* Restore all states. */ @@ -995,7 +1005,7 @@ ENTRY(fast_syscall_unrecoverable) movi a0, unrecoverable_exception callx0 a0 - +ENDPROC(fast_syscall_unrecoverable) /* * sysxtensa syscall handler @@ -1101,7 +1111,7 @@ CATCH movi a2, -EINVAL rfe - +ENDPROC(fast_syscall_xtensa) /* fast_syscall_spill_registers. @@ -1160,6 +1170,8 @@ ENTRY(fast_syscall_spill_registers) movi a2, 0 rfe +ENDPROC(fast_syscall_spill_registers) + /* Fixup handler. * * We get here if the spill routine causes an exception, e.g. tlb miss. @@ -1464,6 +1476,8 @@ ENTRY(_spill_registers) callx0 a0 # should not return 1: j 1b +ENDPROC(_spill_registers) + #ifdef CONFIG_MMU /* * We should never get here. Bail out! @@ -1475,6 +1489,8 @@ ENTRY(fast_second_level_miss_double_kernel) callx0 a0 # should not return 1: j 1b +ENDPROC(fast_second_level_miss_double_kernel) + /* First-level entry handler for user, kernel, and double 2nd-level * TLB miss exceptions. Note that for now, user and kernel miss * exceptions share the same entry point and are handled identically. @@ -1682,6 +1698,7 @@ ENTRY(fast_second_level_miss) j _kernel_exception 1: j _user_exception +ENDPROC(fast_second_level_miss) /* * StoreProhibitedException @@ -1777,6 +1794,9 @@ ENTRY(fast_store_prohibited) bbsi.l a2, PS_UM_BIT, 1f j _kernel_exception 1: j _user_exception + +ENDPROC(fast_store_prohibited) + #endif /* CONFIG_MMU */ /* @@ -1787,6 +1807,7 @@ ENTRY(fast_store_prohibited) */ ENTRY(system_call) + entry a1, 32 /* regs->syscall = regs->areg[2] */ @@ -1831,6 +1852,8 @@ ENTRY(system_call) callx4 a4 retw +ENDPROC(system_call) + /* * Task switch. @@ -1899,6 +1922,7 @@ ENTRY(_switch_to) retw +ENDPROC(_switch_to) ENTRY(ret_from_fork) @@ -1914,6 +1938,8 @@ ENTRY(ret_from_fork) j common_exception_return +ENDPROC(ret_from_fork) + /* * Kernel thread creation helper * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index bdc50788f35e..417998c02108 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S @@ -47,16 +47,19 @@ */ __HEAD - .globl _start -_start: _j 2f +ENTRY(_start) + + _j 2f .align 4 1: .word _startup 2: l32r a0, 1b jx a0 +ENDPROC(_start) + .section .init.text, "ax" - .align 4 -_startup: + +ENTRY(_startup) /* Disable interrupts and exceptions. */ @@ -230,6 +233,7 @@ _startup: should_never_return: j should_never_return +ENDPROC(_startup) /* * BSS section @@ -239,6 +243,8 @@ __PAGE_ALIGNED_BSS #ifdef CONFIG_MMU ENTRY(swapper_pg_dir) .fill PAGE_SIZE, 1, 0 +END(swapper_pg_dir) #endif ENTRY(empty_zero_page) .fill PAGE_SIZE, 1, 0 +END(empty_zero_page) diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index 3a57c15f7942..9365ee5064d3 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S @@ -79,6 +79,8 @@ ENTRY(_UserExceptionVector) l32i a0, a0, EXC_TABLE_FAST_USER # load handler jx a0 +ENDPROC(_UserExceptionVector) + /* * Kernel exception vector. (Exceptions with PS.UM == 0, PS.EXCM == 0) * @@ -103,6 +105,7 @@ ENTRY(_KernelExceptionVector) l32i a0, a0, EXC_TABLE_FAST_KERNEL # load handler address jx a0 +ENDPROC(_KernelExceptionVector) /* * Double exception vector (Exceptions with PS.EXCM == 1) @@ -344,6 +347,7 @@ ENTRY(_DoubleExceptionVector) .end literal_prefix +ENDPROC(_DoubleExceptionVector) /* * Debug interrupt vector @@ -355,9 +359,11 @@ ENTRY(_DoubleExceptionVector) .section .DebugInterruptVector.text, "ax" ENTRY(_DebugInterruptVector) + xsr a0, SREG_EXCSAVE + XCHAL_DEBUGLEVEL jx a0 +ENDPROC(_DebugInterruptVector) /* Window overflow and underflow handlers. @@ -369,38 +375,43 @@ ENTRY(_DebugInterruptVector) * we try to access any page that would cause a page fault early. */ +#define ENTRY_ALIGN64(name) \ + .globl name; \ + .align 64; \ + name: + .section .WindowVectors.text, "ax" /* 4-Register Window Overflow Vector (Handler) */ - .align 64 -.global _WindowOverflow4 -_WindowOverflow4: +ENTRY_ALIGN64(_WindowOverflow4) + s32e a0, a5, -16 s32e a1, a5, -12 s32e a2, a5, -8 s32e a3, a5, -4 rfwo +ENDPROC(_WindowOverflow4) + /* 4-Register Window Underflow Vector (Handler) */ - .align 64 -.global _WindowUnderflow4 -_WindowUnderflow4: +ENTRY_ALIGN64(_WindowUnderflow4) + l32e a0, a5, -16 l32e a1, a5, -12 l32e a2, a5, -8 l32e a3, a5, -4 rfwu +ENDPROC(_WindowUnderflow4) /* 8-Register Window Overflow Vector (Handler) */ - .align 64 -.global _WindowOverflow8 -_WindowOverflow8: +ENTRY_ALIGN64(_WindowOverflow8) + s32e a0, a9, -16 l32e a0, a1, -12 s32e a2, a9, -8 @@ -412,11 +423,12 @@ _WindowOverflow8: s32e a7, a0, -20 rfwo +ENDPROC(_WindowOverflow8) + /* 8-Register Window Underflow Vector (Handler) */ - .align 64 -.global _WindowUnderflow8 -_WindowUnderflow8: +ENTRY_ALIGN64(_WindowUnderflow8) + l32e a1, a9, -12 l32e a0, a9, -16 l32e a7, a1, -12 @@ -428,12 +440,12 @@ _WindowUnderflow8: l32e a7, a7, -20 rfwu +ENDPROC(_WindowUnderflow8) /* 12-Register Window Overflow Vector (Handler) */ - .align 64 -.global _WindowOverflow12 -_WindowOverflow12: +ENTRY_ALIGN64(_WindowOverflow12) + s32e a0, a13, -16 l32e a0, a1, -12 s32e a1, a13, -12 @@ -449,11 +461,12 @@ _WindowOverflow12: s32e a11, a0, -20 rfwo +ENDPROC(_WindowOverflow12) + /* 12-Register Window Underflow Vector (Handler) */ - .align 64 -.global _WindowUnderflow12 -_WindowUnderflow12: +ENTRY_ALIGN64(_WindowUnderflow12) + l32e a1, a13, -12 l32e a0, a13, -16 l32e a11, a1, -12 @@ -469,6 +482,8 @@ _WindowUnderflow12: l32e a11, a11, -20 rfwu +ENDPROC(_WindowUnderflow12) + .text diff --git a/arch/xtensa/lib/checksum.S b/arch/xtensa/lib/checksum.S index df397f932d0e..0470ca21a359 100644 --- a/arch/xtensa/lib/checksum.S +++ b/arch/xtensa/lib/checksum.S @@ -170,7 +170,7 @@ ENTRY(csum_partial) 3: j 5b /* branch to handle the remaining byte */ - +ENDPROC(csum_partial) /* * Copy from ds while checksumming, otherwise like csum_partial @@ -211,6 +211,7 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst, int len, */ ENTRY(csum_partial_copy_generic) + entry sp, 32 mov a12, a3 mov a11, a4 @@ -367,6 +368,8 @@ DST( s8i a8, a3, 1 ) 6: j 4b /* process the possible trailing odd byte */ +ENDPROC(csum_partial_copy_generic) + # Exception handler: .section .fixup, "ax" diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S index b048406d8756..7f7078f57c41 100644 --- a/arch/xtensa/mm/misc.S +++ b/arch/xtensa/mm/misc.S @@ -29,6 +29,7 @@ */ ENTRY(clear_page) + entry a1, 16 movi a3, 0 @@ -45,6 +46,8 @@ ENTRY(clear_page) retw +ENDPROC(clear_page) + /* * copy_page and copy_user_page are the same for non-cache-aliased configs. * @@ -53,6 +56,7 @@ ENTRY(clear_page) */ ENTRY(copy_page) + entry a1, 16 __loopi a2, a4, PAGE_SIZE, 32 @@ -84,6 +88,8 @@ ENTRY(copy_page) retw +ENDPROC(copy_page) + #ifdef CONFIG_MMU /* * If we have to deal with cache aliasing, we use temporary memory mappings @@ -109,6 +115,7 @@ ENTRY(__tlbtemp_mapping_start) */ ENTRY(clear_user_page) + entry a1, 32 /* Mark page dirty and determine alias. */ @@ -164,6 +171,8 @@ ENTRY(clear_user_page) retw +ENDPROC(clear_user_page) + /* * copy_page_user (void *to, void *from, unsigned long vaddr, struct page *page) * a2 a3 a4 a5 @@ -262,6 +271,8 @@ ENTRY(copy_user_page) retw +ENDPROC(copy_user_page) + #endif #if (DCACHE_WAY_SIZE > PAGE_SIZE) @@ -272,6 +283,7 @@ ENTRY(copy_user_page) */ ENTRY(__flush_invalidate_dcache_page_alias) + entry sp, 16 movi a7, 0 # required for exception handler @@ -287,6 +299,7 @@ ENTRY(__flush_invalidate_dcache_page_alias) retw +ENDPROC(__flush_invalidate_dcache_page_alias) #endif ENTRY(__tlbtemp_mapping_itlb) @@ -294,6 +307,7 @@ ENTRY(__tlbtemp_mapping_itlb) #if (ICACHE_WAY_SIZE > PAGE_SIZE) ENTRY(__invalidate_icache_page_alias) + entry sp, 16 addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE) @@ -307,11 +321,14 @@ ENTRY(__invalidate_icache_page_alias) isync retw +ENDPROC(__invalidate_icache_page_alias) + #endif /* End of special treatment in tlb miss exception */ ENTRY(__tlbtemp_mapping_end) + #endif /* CONFIG_MMU /* @@ -319,6 +336,7 @@ ENTRY(__tlbtemp_mapping_end) */ ENTRY(__invalidate_icache_page) + entry sp, 16 ___invalidate_icache_page a2 a3 @@ -326,11 +344,14 @@ ENTRY(__invalidate_icache_page) retw +ENDPROC(__invalidate_icache_page) + /* * void __invalidate_dcache_page(ulong start) */ ENTRY(__invalidate_dcache_page) + entry sp, 16 ___invalidate_dcache_page a2 a3 @@ -338,11 +359,14 @@ ENTRY(__invalidate_dcache_page) retw +ENDPROC(__invalidate_dcache_page) + /* * void __flush_invalidate_dcache_page(ulong start) */ ENTRY(__flush_invalidate_dcache_page) + entry sp, 16 ___flush_invalidate_dcache_page a2 a3 @@ -350,11 +374,14 @@ ENTRY(__flush_invalidate_dcache_page) dsync retw +ENDPROC(__flush_invalidate_dcache_page) + /* * void __flush_dcache_page(ulong start) */ ENTRY(__flush_dcache_page) + entry sp, 16 ___flush_dcache_page a2 a3 @@ -362,11 +389,14 @@ ENTRY(__flush_dcache_page) dsync retw +ENDPROC(__flush_dcache_page) + /* * void __invalidate_icache_range(ulong start, ulong size) */ ENTRY(__invalidate_icache_range) + entry sp, 16 ___invalidate_icache_range a2 a3 a4 @@ -374,11 +404,14 @@ ENTRY(__invalidate_icache_range) retw +ENDPROC(__invalidate_icache_range) + /* * void __flush_invalidate_dcache_range(ulong start, ulong size) */ ENTRY(__flush_invalidate_dcache_range) + entry sp, 16 ___flush_invalidate_dcache_range a2 a3 a4 @@ -386,11 +419,14 @@ ENTRY(__flush_invalidate_dcache_range) retw +ENDPROC(__flush_invalidate_dcache_range) + /* * void _flush_dcache_range(ulong start, ulong size) */ ENTRY(__flush_dcache_range) + entry sp, 16 ___flush_dcache_range a2 a3 a4 @@ -398,22 +434,28 @@ ENTRY(__flush_dcache_range) retw +ENDPROC(__flush_dcache_range) + /* * void _invalidate_dcache_range(ulong start, ulong size) */ ENTRY(__invalidate_dcache_range) + entry sp, 16 ___invalidate_dcache_range a2 a3 a4 retw +ENDPROC(__invalidate_dcache_range) + /* * void _invalidate_icache_all(void) */ ENTRY(__invalidate_icache_all) + entry sp, 16 ___invalidate_icache_all a2 a3 @@ -421,11 +463,14 @@ ENTRY(__invalidate_icache_all) retw +ENDPROC(__invalidate_icache_all) + /* * void _flush_invalidate_dcache_all(void) */ ENTRY(__flush_invalidate_dcache_all) + entry sp, 16 ___flush_invalidate_dcache_all a2 a3 @@ -433,11 +478,14 @@ ENTRY(__flush_invalidate_dcache_all) retw +ENDPROC(__flush_invalidate_dcache_all) + /* * void _invalidate_dcache_all(void) */ ENTRY(__invalidate_dcache_all) + entry sp, 16 ___invalidate_dcache_all a2 a3 @@ -445,3 +493,4 @@ ENTRY(__invalidate_dcache_all) retw +ENDPROC(__invalidate_dcache_all) -- cgit v1.2.1 From 94d6c61b97cbcb3b538276c3785896ea12ecaecb Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 31 Oct 2012 12:37:04 +0400 Subject: xtensa: ISS: add BASE_BAUD definition to serial.h This fixes the following build error in allyesconfig: drivers/tty/serial/8250/8250_early.c: In function 'parse_options': drivers/tty/serial/8250/8250_early.c:160:18: error: 'BASE_BAUD' undeclared (first use in this function) Reported-by: Fengguang Wu Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/platforms/iss/include/platform/serial.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'arch') diff --git a/arch/xtensa/platforms/iss/include/platform/serial.h b/arch/xtensa/platforms/iss/include/platform/serial.h index e69de29bb2d1..16aec542d435 100644 --- a/arch/xtensa/platforms/iss/include/platform/serial.h +++ b/arch/xtensa/platforms/iss/include/platform/serial.h @@ -0,0 +1,15 @@ +/* + * 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. + * + * Copyright (C) 2012 Tensilica Inc. + */ + +#ifndef __ASM_XTENSA_ISS_SERIAL_H +#define __ASM_XTENSA_ISS_SERIAL_H + +/* Have no meaning on ISS, but needed for 8250_early.c */ +#define BASE_BAUD 0 + +#endif /* __ASM_XTENSA_ISS_SERIAL_H */ -- cgit v1.2.1 From 35b16a9a093757a7a1ef288eea1128b0b4a3eef7 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 1 Nov 2012 18:38:27 +0400 Subject: xtensa: provide DMA_ERROR_CODE definition This fixes the following allmodconfig build error: drivers/uio/uio_dmem_genirq.c:95:18: error: 'DMA_ERROR_CODE' undeclared (first use in this function) drivers/uio/uio_dmem_genirq.c:238:18: error: 'DMA_ERROR_CODE' undeclared (first use in this function) make[3]: *** [drivers/uio/uio_dmem_genirq.o] Error 1 Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/include/asm/dma-mapping.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/xtensa/include/asm/dma-mapping.h b/arch/xtensa/include/asm/dma-mapping.h index 492c95790ad5..eb69743172b1 100644 --- a/arch/xtensa/include/asm/dma-mapping.h +++ b/arch/xtensa/include/asm/dma-mapping.h @@ -16,6 +16,8 @@ #include #include +#define DMA_ERROR_CODE (~(dma_addr_t)0x0) + /* * DMA-consistent mapping functions. */ -- cgit v1.2.1 From 382cb5b91747f4f4d1f9883a39deec1b3d7fb906 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 5 Nov 2012 07:44:03 +0400 Subject: xtensa: fix build warning for arch/xtensa/mm/tlb.c Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/mm/tlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c index e2700b21395b..070fb7a25231 100644 --- a/arch/xtensa/mm/tlb.c +++ b/arch/xtensa/mm/tlb.c @@ -63,7 +63,7 @@ void flush_tlb_all (void) void flush_tlb_mm(struct mm_struct *mm) { if (mm == current->active_mm) { - int flags; + unsigned long flags; local_save_flags(flags); __get_new_mmu_context(mm); __load_mmu_context(mm); -- cgit v1.2.1 From 288dc2b68c110cd2b14b17f047b85859bc644955 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 22 Oct 2012 08:42:39 +0400 Subject: xtensa: properly fix missing compiler barrier in simcall Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/platforms/iss/include/platform/simcall.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/platforms/iss/include/platform/simcall.h b/arch/xtensa/platforms/iss/include/platform/simcall.h index bd78192e2fc9..b5a4edf02d76 100644 --- a/arch/xtensa/platforms/iss/include/platform/simcall.h +++ b/arch/xtensa/platforms/iss/include/platform/simcall.h @@ -74,13 +74,12 @@ static inline int __simc(int a, int b, int c, int d, int e, int f) "mov %1, a3\n" : "=a" (ret), "=a" (errno), "+r"(a1), "+r"(b1) : "r"(c1), "r"(d1), "r"(e1), "r"(f1) - : ); + : "memory"); return ret; } static inline int simc_open(const char *file, int flags, int mode) { - wmb(); return __simc(SYS_open, (int) file, flags, mode, 0, 0); } @@ -91,19 +90,16 @@ static inline int simc_close(int fd) static inline int simc_ioctl(int fd, int request, void *arg) { - wmb(); return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0); } static inline int simc_read(int fd, void *buf, size_t count) { - rmb(); return __simc(SYS_read, fd, (int) buf, count, 0, 0); } static inline int simc_write(int fd, const void *buf, size_t count) { - wmb(); return __simc(SYS_write, fd, (int) buf, count, 0, 0); } @@ -111,7 +107,6 @@ static inline int simc_poll(int fd) { struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; - wmb(); return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv, 0, 0); } -- cgit v1.2.1 From 415217efc132b1237c65b15d1986d123380298f4 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 11 Nov 2012 01:29:10 +0400 Subject: xtensa: fix CPU cache flags formatting Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/kernel/setup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index b237988ba6d7..ffc4fcb35279 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -412,7 +412,7 @@ c_show(struct seq_file *f, void *slot) "icache size\t: %d\n" "icache flags\t: " #if XCHAL_ICACHE_LINE_LOCKABLE - "lock" + "lock " #endif "\n" "dcache line size: %d\n" @@ -420,10 +420,10 @@ c_show(struct seq_file *f, void *slot) "dcache size\t: %d\n" "dcache flags\t: " #if XCHAL_DCACHE_IS_WRITEBACK - "writeback" + "writeback " #endif #if XCHAL_DCACHE_LINE_LOCKABLE - "lock" + "lock " #endif "\n", XCHAL_ICACHE_LINESIZE, -- cgit v1.2.1 From 2f6ea6a767e9e26d23e4de4b03fdebe41f3b88f8 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 11 Nov 2012 04:44:22 +0400 Subject: xtensa: display s32c1i feature flag in cpuinfo Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/kernel/setup.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index ffc4fcb35279..e53a94b3edbc 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -380,6 +380,9 @@ c_show(struct seq_file *f, void *slot) #endif #if XCHAL_HAVE_FP "fpu " +#endif +#if XCHAL_HAVE_S32C1I + "s32c1i " #endif "\n"); -- cgit v1.2.1 From 733536b865441d9bad02c4711a4372d48ce21e54 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 15 Nov 2012 06:25:48 +0400 Subject: xtensa: save and restore scompare1 SR on kernel entry Although scompare1 may be saved/restored by xchal_ncp_{load,store} macros, explicit save/restore of registers manipulated by the kernel itself is considered more correct. Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/include/asm/ptrace.h | 2 +- arch/xtensa/kernel/asm-offsets.c | 1 + arch/xtensa/kernel/entry.S | 13 +++++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h index da21c17f23aa..9fe249c8f90e 100644 --- a/arch/xtensa/include/asm/ptrace.h +++ b/arch/xtensa/include/asm/ptrace.h @@ -37,7 +37,7 @@ struct pt_regs { unsigned long windowstart; /* 52 */ unsigned long syscall; /* 56 */ unsigned long icountlevel; /* 60 */ - int reserved[1]; /* 64 */ + unsigned long scompare1; /* 64 */ /* Additional configurable registers that are used by the compiler. */ xtregs_opt_t xtregs_opt; diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index 7dc3f9157185..845475afc683 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c @@ -41,6 +41,7 @@ int main(void) DEFINE(PT_SAR, offsetof (struct pt_regs, sar)); DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel)); DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall)); + DEFINE(PT_SCOMPARE1, offsetof(struct pt_regs, scompare1)); DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1])); diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 41ad9cfe9a2a..4c2f2706ad5b 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -372,6 +372,13 @@ common_exception: s32i a2, a1, PT_LBEG s32i a3, a1, PT_LEND + /* Save SCOMPARE1 */ + +#if XCHAL_HAVE_S32C1I + rsr a2, scompare1 + s32i a2, a1, PT_SCOMPARE1 +#endif + /* Save optional registers. */ save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT @@ -433,6 +440,12 @@ common_exception_return: load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT + /* Restore SCOMPARE1 */ + +#if XCHAL_HAVE_S32C1I + l32i a2, a1, PT_SCOMPARE1 + wsr a2, scompare1 +#endif wsr a3, ps /* disable interrupts */ _bbci.l a3, PS_UM_BIT, kernel_exception_exit -- cgit v1.2.1 From c622b29d1f38021411965b7e0170ab055551b257 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 19 Nov 2012 07:00:41 +0400 Subject: xtensa: initialize atomctl SR In order to use S32C1I instruction on cores with ATOMCTL SR the register must be properly initialized. Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/include/asm/initialize_mmu.h | 55 ++++++++++++++++++++++++++++++++ arch/xtensa/kernel/head.S | 3 ++ 2 files changed, 58 insertions(+) create mode 100644 arch/xtensa/include/asm/initialize_mmu.h (limited to 'arch') diff --git a/arch/xtensa/include/asm/initialize_mmu.h b/arch/xtensa/include/asm/initialize_mmu.h new file mode 100644 index 000000000000..e1f8ba4061ed --- /dev/null +++ b/arch/xtensa/include/asm/initialize_mmu.h @@ -0,0 +1,55 @@ +/* + * arch/xtensa/include/asm/initialize_mmu.h + * + * Initializes MMU: + * + * For the new V3 MMU we remap the TLB from virtual == physical + * to the standard Linux mapping used in earlier MMU's. + * + * The the MMU we also support a new configuration register that + * specifies how the S32C1I instruction operates with the cache + * controller. + * + * 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. + * + * Copyright (C) 2008 - 2012 Tensilica, Inc. + * + * Marc Gauthier + * Pete Delaney + */ + +#ifndef _XTENSA_INITIALIZE_MMU_H +#define _XTENSA_INITIALIZE_MMU_H + +#ifdef __ASSEMBLY__ + +#define XTENSA_HWVERSION_RC_2009_0 230000 + + .macro initialize_mmu + +#if XCHAL_HAVE_S32C1I && (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0) +/* + * We Have Atomic Operation Control (ATOMCTL) Register; Initialize it. + * For details see Documentation/xtensa/atomctl.txt + */ +#if XCHAL_DCACHE_IS_COHERENT + movi a3, 0x25 /* For SMP/MX -- internal for writeback, + * RCW otherwise + */ +#else + movi a3, 0x29 /* non-MX -- Most cores use Std Memory + * Controlers which usually can't use RCW + */ +#endif + wsr a3, atomctl +#endif /* XCHAL_HAVE_S32C1I && + * (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0) + */ + + .endm + +#endif /*__ASSEMBLY__*/ + +#endif /* _XTENSA_INITIALIZE_MMU_H */ diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index 417998c02108..9013ae0174f8 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -155,6 +156,8 @@ ENTRY(_startup) isync + initialize_mmu + /* Unpack data sections * * The linker script used to build the Linux kernel image -- cgit v1.2.1 From 28570e8dac5c86ab10ce2a7e9c02d3aaece63760 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 19 Nov 2012 08:30:15 +0400 Subject: xtensa: add trap_set_handler function trap_set_handler sets new C-handler in the exception table and returns previous handler. Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/include/asm/traps.h | 23 +++++++++++++++++++++++ arch/xtensa/kernel/traps.c | 11 +++++++++++ 2 files changed, 34 insertions(+) create mode 100644 arch/xtensa/include/asm/traps.h (limited to 'arch') diff --git a/arch/xtensa/include/asm/traps.h b/arch/xtensa/include/asm/traps.h new file mode 100644 index 000000000000..54f70440185e --- /dev/null +++ b/arch/xtensa/include/asm/traps.h @@ -0,0 +1,23 @@ +/* + * arch/xtensa/include/asm/traps.h + * + * 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. + * + * Copyright (C) 2012 Tensilica Inc. + */ +#ifndef _XTENSA_TRAPS_H +#define _XTENSA_TRAPS_H + +#include + +/* + * handler must be either of the following: + * void (*)(struct pt_regs *regs); + * void (*)(struct pt_regs *regs, unsigned long exccause); + */ +extern void * __init trap_set_handler(int cause, void *handler); +extern void do_unhandled(struct pt_regs *regs, unsigned long exccause); + +#endif /* _XTENSA_TRAPS_H */ diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 5caf2b64d43a..691a792b01d3 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -293,6 +293,17 @@ do_debug(struct pt_regs *regs) } +/* Set exception C handler - for temporary use when probing exceptions */ + +void * __init trap_set_handler(int cause, void *handler) +{ + unsigned long *entry = &exc_table[EXC_TABLE_DEFAULT / 4 + cause]; + void *previous = (void *)*entry; + *entry = (unsigned long)handler; + return previous; +} + + /* * Initialize dispatch tables. * -- cgit v1.2.1 From 00273125c39be9cbf619aef90147354a9ed8c385 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 28 Nov 2012 11:33:02 +0400 Subject: xtensa: add s32c1i sanity check Add a brief sanity test of S32C1I functionality. This instruction is needed by the kernel and userland as part of the base ABI (including GCC atomic builtins, certain threading packages, future atomic support in the C++ standard, etc). However, correct operation of this instruction requires some cooperation by hardware external to the processor (such as bus bridge, bus fabric, or memory controller). Minimally exercising this mechanism and reporting explicit status early in the boot process is helpful to chip vendors using the Linux kernel as a benchmark of correctness of hardware. As it turns out, S32C1I is not exercised by the kernel and by uClibc based userland as of early June 2008. This is expected to change soon as both incorporate more recent open source developments. Signed-off-by: Marc Gauthier Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/Kconfig.debug | 11 ++++ arch/xtensa/include/asm/regs.h | 4 ++ arch/xtensa/kernel/setup.c | 120 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) (limited to 'arch') diff --git a/arch/xtensa/Kconfig.debug b/arch/xtensa/Kconfig.debug index be5fb4c6243f..a34010e0e51c 100644 --- a/arch/xtensa/Kconfig.debug +++ b/arch/xtensa/Kconfig.debug @@ -13,4 +13,15 @@ config LD_NO_RELAX Enabling this option improves the link time but increases the code size, and possibly execution time. +config S32C1I_SELFTEST + bool "Perform S32C1I instruction self-test at boot" + default y + help + Enable this option to test S32C1I instruction behavior at boot. + Correct operation of this instruction requires some cooperation from hardware + external to the processor (such as bus bridge, bus fabric, or memory controller). + It is easy to make wrong hardware configuration, this test should catch it early. + + Say 'N' on stable hardware. + endmenu diff --git a/arch/xtensa/include/asm/regs.h b/arch/xtensa/include/asm/regs.h index 8a8aa61ccc8d..6aaf6d6a5fc4 100644 --- a/arch/xtensa/include/asm/regs.h +++ b/arch/xtensa/include/asm/regs.h @@ -52,6 +52,10 @@ #define EXCCAUSE_SPECULATION 7 #define EXCCAUSE_PRIVILEGED 8 #define EXCCAUSE_UNALIGNED 9 +#define EXCCAUSE_INSTR_DATA_ERROR 12 +#define EXCCAUSE_LOAD_STORE_DATA_ERROR 13 +#define EXCCAUSE_INSTR_ADDR_ERROR 14 +#define EXCCAUSE_LOAD_STORE_ADDR_ERROR 15 #define EXCCAUSE_ITLB_MISS 16 #define EXCCAUSE_ITLB_MULTIHIT 17 #define EXCCAUSE_ITLB_PRIVILEGE 18 diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index e53a94b3edbc..45217617c60d 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -42,6 +42,7 @@ #include #include #include +#include #include @@ -235,6 +236,123 @@ extern char _UserExceptionVector_text_end; extern char _DoubleExceptionVector_literal_start; extern char _DoubleExceptionVector_text_end; + +#ifdef CONFIG_S32C1I_SELFTEST +#if XCHAL_HAVE_S32C1I + +static int __initdata rcw_word, rcw_probe_pc, rcw_exc; + +/* + * Basic atomic compare-and-swap, that records PC of S32C1I for probing. + * + * If *v == cmp, set *v = set. Return previous *v. + */ +static inline int probed_compare_swap(int *v, int cmp, int set) +{ + int tmp; + + __asm__ __volatile__( + " movi %1, 1f\n" + " s32i %1, %4, 0\n" + " wsr %2, scompare1\n" + "1: s32c1i %0, %3, 0\n" + : "=a" (set), "=&a" (tmp) + : "a" (cmp), "a" (v), "a" (&rcw_probe_pc), "0" (set) + : "memory" + ); + return set; +} + +/* Handle probed exception */ + +void __init do_probed_exception(struct pt_regs *regs, unsigned long exccause) +{ + if (regs->pc == rcw_probe_pc) { /* exception on s32c1i ? */ + regs->pc += 3; /* skip the s32c1i instruction */ + rcw_exc = exccause; + } else { + do_unhandled(regs, exccause); + } +} + +/* Simple test of S32C1I (soc bringup assist) */ + +void __init check_s32c1i(void) +{ + int n, cause1, cause2; + void *handbus, *handdata, *handaddr; /* temporarily saved handlers */ + + rcw_probe_pc = 0; + handbus = trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, + do_probed_exception); + handdata = trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, + do_probed_exception); + handaddr = trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, + do_probed_exception); + + /* First try an S32C1I that does not store: */ + rcw_exc = 0; + rcw_word = 1; + n = probed_compare_swap(&rcw_word, 0, 2); + cause1 = rcw_exc; + + /* took exception? */ + if (cause1 != 0) { + /* unclean exception? */ + if (n != 2 || rcw_word != 1) + panic("S32C1I exception error"); + } else if (rcw_word != 1 || n != 1) { + panic("S32C1I compare error"); + } + + /* Then an S32C1I that stores: */ + rcw_exc = 0; + rcw_word = 0x1234567; + n = probed_compare_swap(&rcw_word, 0x1234567, 0xabcde); + cause2 = rcw_exc; + + if (cause2 != 0) { + /* unclean exception? */ + if (n != 0xabcde || rcw_word != 0x1234567) + panic("S32C1I exception error (b)"); + } else if (rcw_word != 0xabcde || n != 0x1234567) { + panic("S32C1I store error"); + } + + /* Verify consistency of exceptions: */ + if (cause1 || cause2) { + pr_warn("S32C1I took exception %d, %d\n", cause1, cause2); + /* If emulation of S32C1I upon bus error gets implemented, + we can get rid of this panic for single core (not SMP) */ + panic("S32C1I exceptions not currently supported"); + } + if (cause1 != cause2) + panic("inconsistent S32C1I exceptions"); + + trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, handbus); + trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, handdata); + trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, handaddr); +} + +#else /* XCHAL_HAVE_S32C1I */ + +/* This condition should not occur with a commercially deployed processor. + Display reminder for early engr test or demo chips / FPGA bitstreams */ +void __init check_s32c1i(void) +{ + pr_warn("Processor configuration lacks atomic compare-and-swap support!\n"); +} + +#endif /* XCHAL_HAVE_S32C1I */ +#else /* CONFIG_S32C1I_SELFTEST */ + +void __init check_s32c1i(void) +{ +} + +#endif /* CONFIG_S32C1I_SELFTEST */ + + void __init setup_arch(char **cmdline_p) { extern int mem_reserve(unsigned long, unsigned long, int); @@ -244,6 +362,8 @@ void __init setup_arch(char **cmdline_p) boot_command_line[COMMAND_LINE_SIZE-1] = '\0'; *cmdline_p = command_line; + check_s32c1i(); + /* Reserve some memory regions */ #ifdef CONFIG_BLK_DEV_INITRD -- cgit v1.2.1 From 219b1e4c61c108731bb665962231b1fa057f6c71 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 11 Nov 2012 03:30:02 +0400 Subject: xtensa: add s32c1i-based atomic ops implementations Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/include/asm/atomic.h | 271 ++++++++++++++++++++++++++------------ arch/xtensa/include/asm/cmpxchg.h | 71 +++++++--- 2 files changed, 236 insertions(+), 106 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/include/asm/atomic.h b/arch/xtensa/include/asm/atomic.h index 24f50cada70c..c3f289174c10 100644 --- a/arch/xtensa/include/asm/atomic.h +++ b/arch/xtensa/include/asm/atomic.h @@ -66,19 +66,35 @@ */ static inline void atomic_add(int i, atomic_t * v) { - unsigned int vval; - - __asm__ __volatile__( - "rsil a15, "__stringify(LOCKLEVEL)"\n\t" - "l32i %0, %2, 0 \n\t" - "add %0, %0, %1 \n\t" - "s32i %0, %2, 0 \n\t" - "wsr a15, ps \n\t" - "rsync \n" - : "=&a" (vval) - : "a" (i), "a" (v) - : "a15", "memory" - ); +#if XCHAL_HAVE_S32C1I + unsigned long tmp; + int result; + + __asm__ __volatile__( + "1: l32i %1, %3, 0\n" + " wsr %1, scompare1\n" + " add %0, %1, %2\n" + " s32c1i %0, %3, 0\n" + " bne %0, %1, 1b\n" + : "=&a" (result), "=&a" (tmp) + : "a" (i), "a" (v) + : "memory" + ); +#else + unsigned int vval; + + __asm__ __volatile__( + " rsil a15, "__stringify(LOCKLEVEL)"\n" + " l32i %0, %2, 0\n" + " add %0, %0, %1\n" + " s32i %0, %2, 0\n" + " wsr a15, ps\n" + " rsync\n" + : "=&a" (vval) + : "a" (i), "a" (v) + : "a15", "memory" + ); +#endif } /** @@ -90,19 +106,35 @@ static inline void atomic_add(int i, atomic_t * v) */ static inline void atomic_sub(int i, atomic_t *v) { - unsigned int vval; - - __asm__ __volatile__( - "rsil a15, "__stringify(LOCKLEVEL)"\n\t" - "l32i %0, %2, 0 \n\t" - "sub %0, %0, %1 \n\t" - "s32i %0, %2, 0 \n\t" - "wsr a15, ps \n\t" - "rsync \n" - : "=&a" (vval) - : "a" (i), "a" (v) - : "a15", "memory" - ); +#if XCHAL_HAVE_S32C1I + unsigned long tmp; + int result; + + __asm__ __volatile__( + "1: l32i %1, %3, 0\n" + " wsr %1, scompare1\n" + " sub %0, %1, %2\n" + " s32c1i %0, %3, 0\n" + " bne %0, %1, 1b\n" + : "=&a" (result), "=&a" (tmp) + : "a" (i), "a" (v) + : "memory" + ); +#else + unsigned int vval; + + __asm__ __volatile__( + " rsil a15, "__stringify(LOCKLEVEL)"\n" + " l32i %0, %2, 0\n" + " sub %0, %0, %1\n" + " s32i %0, %2, 0\n" + " wsr a15, ps\n" + " rsync\n" + : "=&a" (vval) + : "a" (i), "a" (v) + : "a15", "memory" + ); +#endif } /* @@ -111,40 +143,78 @@ static inline void atomic_sub(int i, atomic_t *v) static inline int atomic_add_return(int i, atomic_t * v) { - unsigned int vval; - - __asm__ __volatile__( - "rsil a15,"__stringify(LOCKLEVEL)"\n\t" - "l32i %0, %2, 0 \n\t" - "add %0, %0, %1 \n\t" - "s32i %0, %2, 0 \n\t" - "wsr a15, ps \n\t" - "rsync \n" - : "=&a" (vval) - : "a" (i), "a" (v) - : "a15", "memory" - ); - - return vval; +#if XCHAL_HAVE_S32C1I + unsigned long tmp; + int result; + + __asm__ __volatile__( + "1: l32i %1, %3, 0\n" + " wsr %1, scompare1\n" + " add %0, %1, %2\n" + " s32c1i %0, %3, 0\n" + " bne %0, %1, 1b\n" + " add %0, %0, %2\n" + : "=&a" (result), "=&a" (tmp) + : "a" (i), "a" (v) + : "memory" + ); + + return result; +#else + unsigned int vval; + + __asm__ __volatile__( + " rsil a15,"__stringify(LOCKLEVEL)"\n" + " l32i %0, %2, 0\n" + " add %0, %0, %1\n" + " s32i %0, %2, 0\n" + " wsr a15, ps\n" + " rsync\n" + : "=&a" (vval) + : "a" (i), "a" (v) + : "a15", "memory" + ); + + return vval; +#endif } static inline int atomic_sub_return(int i, atomic_t * v) { - unsigned int vval; - - __asm__ __volatile__( - "rsil a15,"__stringify(LOCKLEVEL)"\n\t" - "l32i %0, %2, 0 \n\t" - "sub %0, %0, %1 \n\t" - "s32i %0, %2, 0 \n\t" - "wsr a15, ps \n\t" - "rsync \n" - : "=&a" (vval) - : "a" (i), "a" (v) - : "a15", "memory" - ); - - return vval; +#if XCHAL_HAVE_S32C1I + unsigned long tmp; + int result; + + __asm__ __volatile__( + "1: l32i %1, %3, 0\n" + " wsr %1, scompare1\n" + " sub %0, %1, %2\n" + " s32c1i %0, %3, 0\n" + " bne %0, %1, 1b\n" + " sub %0, %0, %2\n" + : "=&a" (result), "=&a" (tmp) + : "a" (i), "a" (v) + : "memory" + ); + + return result; +#else + unsigned int vval; + + __asm__ __volatile__( + " rsil a15,"__stringify(LOCKLEVEL)"\n" + " l32i %0, %2, 0\n" + " sub %0, %0, %1\n" + " s32i %0, %2, 0\n" + " wsr a15, ps\n" + " rsync\n" + : "=&a" (vval) + : "a" (i), "a" (v) + : "a15", "memory" + ); + + return vval; +#endif } /** @@ -251,38 +321,70 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) { - unsigned int all_f = -1; - unsigned int vval; - - __asm__ __volatile__( - "rsil a15,"__stringify(LOCKLEVEL)"\n\t" - "l32i %0, %2, 0 \n\t" - "xor %1, %4, %3 \n\t" - "and %0, %0, %4 \n\t" - "s32i %0, %2, 0 \n\t" - "wsr a15, ps \n\t" - "rsync \n" - : "=&a" (vval), "=a" (mask) - : "a" (v), "a" (all_f), "1" (mask) - : "a15", "memory" - ); +#if XCHAL_HAVE_S32C1I + unsigned long tmp; + int result; + + __asm__ __volatile__( + "1: l32i %1, %3, 0\n" + " wsr %1, scompare1\n" + " and %0, %1, %2\n" + " s32c1i %0, %3, 0\n" + " bne %0, %1, 1b\n" + : "=&a" (result), "=&a" (tmp) + : "a" (~mask), "a" (v) + : "memory" + ); +#else + unsigned int all_f = -1; + unsigned int vval; + + __asm__ __volatile__( + " rsil a15,"__stringify(LOCKLEVEL)"\n" + " l32i %0, %2, 0\n" + " xor %1, %4, %3\n" + " and %0, %0, %4\n" + " s32i %0, %2, 0\n" + " wsr a15, ps\n" + " rsync\n" + : "=&a" (vval), "=a" (mask) + : "a" (v), "a" (all_f), "1" (mask) + : "a15", "memory" + ); +#endif } static inline void atomic_set_mask(unsigned int mask, atomic_t *v) { - unsigned int vval; - - __asm__ __volatile__( - "rsil a15,"__stringify(LOCKLEVEL)"\n\t" - "l32i %0, %2, 0 \n\t" - "or %0, %0, %1 \n\t" - "s32i %0, %2, 0 \n\t" - "wsr a15, ps \n\t" - "rsync \n" - : "=&a" (vval) - : "a" (mask), "a" (v) - : "a15", "memory" - ); +#if XCHAL_HAVE_S32C1I + unsigned long tmp; + int result; + + __asm__ __volatile__( + "1: l32i %1, %3, 0\n" + " wsr %1, scompare1\n" + " or %0, %1, %2\n" + " s32c1i %0, %3, 0\n" + " bne %0, %1, 1b\n" + : "=&a" (result), "=&a" (tmp) + : "a" (mask), "a" (v) + : "memory" + ); +#else + unsigned int vval; + + __asm__ __volatile__( + " rsil a15,"__stringify(LOCKLEVEL)"\n" + " l32i %0, %2, 0\n" + " or %0, %0, %1\n" + " s32i %0, %2, 0\n" + " wsr a15, ps\n" + " rsync\n" + : "=&a" (vval) + : "a" (mask), "a" (v) + : "a15", "memory" + ); +#endif } /* Atomic operations are already serializing */ @@ -294,4 +396,3 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v) #endif /* __KERNEL__ */ #endif /* _XTENSA_ATOMIC_H */ - diff --git a/arch/xtensa/include/asm/cmpxchg.h b/arch/xtensa/include/asm/cmpxchg.h index 64dad04a9d27..25869a190490 100644 --- a/arch/xtensa/include/asm/cmpxchg.h +++ b/arch/xtensa/include/asm/cmpxchg.h @@ -22,17 +22,30 @@ static inline unsigned long __cmpxchg_u32(volatile int *p, int old, int new) { - __asm__ __volatile__("rsil a15, "__stringify(LOCKLEVEL)"\n\t" - "l32i %0, %1, 0 \n\t" - "bne %0, %2, 1f \n\t" - "s32i %3, %1, 0 \n\t" - "1: \n\t" - "wsr a15, ps \n\t" - "rsync \n\t" - : "=&a" (old) - : "a" (p), "a" (old), "r" (new) - : "a15", "memory"); - return old; +#if XCHAL_HAVE_S32C1I + __asm__ __volatile__( + " wsr %2, scompare1\n" + " s32c1i %0, %1, 0\n" + : "+a" (new) + : "a" (p), "a" (old) + : "memory" + ); + + return new; +#else + __asm__ __volatile__( + " rsil a15, "__stringify(LOCKLEVEL)"\n" + " l32i %0, %1, 0\n" + " bne %0, %2, 1f\n" + " s32i %3, %1, 0\n" + "1:\n" + " wsr a15, ps\n" + " rsync\n" + : "=&a" (old) + : "a" (p), "a" (old), "r" (new) + : "a15", "memory"); + return old; +#endif } /* This function doesn't exist, so you'll get a linker error * if something tries to do an invalid cmpxchg(). */ @@ -93,16 +106,32 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, static inline unsigned long xchg_u32(volatile int * m, unsigned long val) { - unsigned long tmp; - __asm__ __volatile__("rsil a15, "__stringify(LOCKLEVEL)"\n\t" - "l32i %0, %1, 0 \n\t" - "s32i %2, %1, 0 \n\t" - "wsr a15, ps \n\t" - "rsync \n\t" - : "=&a" (tmp) - : "a" (m), "a" (val) - : "a15", "memory"); - return tmp; +#if XCHAL_HAVE_S32C1I + unsigned long tmp, result; + __asm__ __volatile__( + "1: l32i %1, %2, 0\n" + " mov %0, %3\n" + " wsr %1, scompare1\n" + " s32c1i %0, %2, 0\n" + " bne %0, %1, 1b\n" + : "=&a" (result), "=&a" (tmp) + : "a" (m), "a" (val) + : "memory" + ); + return result; +#else + unsigned long tmp; + __asm__ __volatile__( + " rsil a15, "__stringify(LOCKLEVEL)"\n" + " l32i %0, %1, 0\n" + " s32i %2, %1, 0\n" + " wsr a15, ps\n" + " rsync\n" + : "=&a" (tmp) + : "a" (m), "a" (val) + : "a15", "memory"); + return tmp; +#endif } #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) -- cgit v1.2.1 From e5a9f6adba79ce2732330fc6d045e98959af8962 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 11 Nov 2012 05:47:25 +0400 Subject: xtensa: add s32c1i-based bitops implementations Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/include/asm/bitops.h | 127 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/xtensa/include/asm/bitops.h b/arch/xtensa/include/asm/bitops.h index 5270197ddd36..84afe58d5d37 100644 --- a/arch/xtensa/include/asm/bitops.h +++ b/arch/xtensa/include/asm/bitops.h @@ -29,7 +29,6 @@ #define smp_mb__before_clear_bit() barrier() #define smp_mb__after_clear_bit() barrier() -#include #include #if XCHAL_HAVE_NSA @@ -104,6 +103,132 @@ static inline unsigned long __fls(unsigned long word) #endif #include + +#if XCHAL_HAVE_S32C1I + +static inline void set_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long tmp, value; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + __asm__ __volatile__( + "1: l32i %1, %3, 0\n" + " wsr %1, scompare1\n" + " or %0, %1, %2\n" + " s32c1i %0, %3, 0\n" + " bne %0, %1, 1b\n" + : "=&a" (tmp), "=&a" (value) + : "a" (mask), "a" (p) + : "memory"); +} + +static inline void clear_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long tmp, value; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + __asm__ __volatile__( + "1: l32i %1, %3, 0\n" + " wsr %1, scompare1\n" + " and %0, %1, %2\n" + " s32c1i %0, %3, 0\n" + " bne %0, %1, 1b\n" + : "=&a" (tmp), "=&a" (value) + : "a" (~mask), "a" (p) + : "memory"); +} + +static inline void change_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long tmp, value; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + __asm__ __volatile__( + "1: l32i %1, %3, 0\n" + " wsr %1, scompare1\n" + " xor %0, %1, %2\n" + " s32c1i %0, %3, 0\n" + " bne %0, %1, 1b\n" + : "=&a" (tmp), "=&a" (value) + : "a" (mask), "a" (p) + : "memory"); +} + +static inline int +test_and_set_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long tmp, value; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + __asm__ __volatile__( + "1: l32i %1, %3, 0\n" + " wsr %1, scompare1\n" + " or %0, %1, %2\n" + " s32c1i %0, %3, 0\n" + " bne %0, %1, 1b\n" + : "=&a" (tmp), "=&a" (value) + : "a" (mask), "a" (p) + : "memory"); + + return tmp & mask; +} + +static inline int +test_and_clear_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long tmp, value; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + __asm__ __volatile__( + "1: l32i %1, %3, 0\n" + " wsr %1, scompare1\n" + " and %0, %1, %2\n" + " s32c1i %0, %3, 0\n" + " bne %0, %1, 1b\n" + : "=&a" (tmp), "=&a" (value) + : "a" (~mask), "a" (p) + : "memory"); + + return tmp & mask; +} + +static inline int +test_and_change_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long tmp, value; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + __asm__ __volatile__( + "1: l32i %1, %3, 0\n" + " wsr %1, scompare1\n" + " xor %0, %1, %2\n" + " s32c1i %0, %3, 0\n" + " bne %0, %1, 1b\n" + : "=&a" (tmp), "=&a" (value) + : "a" (mask), "a" (p) + : "memory"); + + return tmp & mask; +} + +#else + +#include + +#endif /* XCHAL_HAVE_S32C1I */ + #include #include -- cgit v1.2.1 From 71872b5fb2bed294fd5afd900890880e9faa82c1 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 11 Nov 2012 07:01:21 +0400 Subject: xtensa: add s32c1i-based spinlock implementations Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/include/asm/spinlock.h | 188 ++++++++++++++++++++++++++++++++++++- 1 file changed, 187 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/xtensa/include/asm/spinlock.h b/arch/xtensa/include/asm/spinlock.h index 8ff23649581b..03975906b36f 100644 --- a/arch/xtensa/include/asm/spinlock.h +++ b/arch/xtensa/include/asm/spinlock.h @@ -11,6 +11,192 @@ #ifndef _XTENSA_SPINLOCK_H #define _XTENSA_SPINLOCK_H -#include +/* + * spinlock + * + * There is at most one owner of a spinlock. There are not different + * types of spinlock owners like there are for rwlocks (see below). + * + * When trying to obtain a spinlock, the function "spins" forever, or busy- + * waits, until the lock is obtained. When spinning, presumably some other + * owner will soon give up the spinlock making it available to others. Use + * the trylock functions to avoid spinning forever. + * + * possible values: + * + * 0 nobody owns the spinlock + * 1 somebody owns the spinlock + */ + +#define __raw_spin_is_locked(x) ((x)->slock != 0) +#define __raw_spin_unlock_wait(lock) \ + do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) + +#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) + +static inline void __raw_spin_lock(raw_spinlock_t *lock) +{ + unsigned long tmp; + + __asm__ __volatile__( + " movi %0, 0\n" + " wsr %0, scompare1\n" + "1: movi %0, 1\n" + " s32c1i %0, %1, 0\n" + " bnez %0, 1b\n" + : "=&a" (tmp) + : "a" (&lock->slock) + : "memory"); +} + +/* Returns 1 if the lock is obtained, 0 otherwise. */ + +static inline int __raw_spin_trylock(raw_spinlock_t *lock) +{ + unsigned long tmp; + + __asm__ __volatile__( + " movi %0, 0\n" + " wsr %0, scompare1\n" + " movi %0, 1\n" + " s32c1i %0, %1, 0\n" + : "=&a" (tmp) + : "a" (&lock->slock) + : "memory"); + + return tmp == 0 ? 1 : 0; +} + +static inline void __raw_spin_unlock(raw_spinlock_t *lock) +{ + unsigned long tmp; + + __asm__ __volatile__( + " movi %0, 0\n" + " s32ri %0, %1, 0\n" + : "=&a" (tmp) + : "a" (&lock->slock) + : "memory"); +} + +/* + * rwlock + * + * Read-write locks are really a more flexible spinlock. They allow + * multiple readers but only one writer. Write ownership is exclusive + * (i.e., all other readers and writers are blocked from ownership while + * there is a write owner). These rwlocks are unfair to writers. Writers + * can be starved for an indefinite time by readers. + * + * possible values: + * + * 0 nobody owns the rwlock + * >0 one or more readers own the rwlock + * (the positive value is the actual number of readers) + * 0x80000000 one writer owns the rwlock, no other writers, no readers + */ + +#define __raw_write_can_lock(x) ((x)->lock == 0) + +static inline void __raw_write_lock(raw_rwlock_t *rw) +{ + unsigned long tmp; + + __asm__ __volatile__( + " movi %0, 0\n" + " wsr %0, scompare1\n" + "1: movi %0, 1\n" + " slli %0, %0, 31\n" + " s32c1i %0, %1, 0\n" + " bnez %0, 1b\n" + : "=&a" (tmp) + : "a" (&rw->lock) + : "memory"); +} + +/* Returns 1 if the lock is obtained, 0 otherwise. */ + +static inline int __raw_write_trylock(raw_rwlock_t *rw) +{ + unsigned long tmp; + + __asm__ __volatile__( + " movi %0, 0\n" + " wsr %0, scompare1\n" + " movi %0, 1\n" + " slli %0, %0, 31\n" + " s32c1i %0, %1, 0\n" + : "=&a" (tmp) + : "a" (&rw->lock) + : "memory"); + + return tmp == 0 ? 1 : 0; +} + +static inline void __raw_write_unlock(raw_rwlock_t *rw) +{ + unsigned long tmp; + + __asm__ __volatile__( + " movi %0, 0\n" + " s32ri %0, %1, 0\n" + : "=&a" (tmp) + : "a" (&rw->lock) + : "memory"); +} + +static inline void __raw_read_lock(raw_rwlock_t *rw) +{ + unsigned long tmp; + unsigned long result; + + __asm__ __volatile__( + "1: l32i %1, %2, 0\n" + " bltz %1, 1b\n" + " wsr %1, scompare1\n" + " addi %0, %1, 1\n" + " s32c1i %0, %2, 0\n" + " bne %0, %1, 1b\n" + : "=&a" (result), "=&a" (tmp) + : "a" (&rw->lock) + : "memory"); +} + +/* Returns 1 if the lock is obtained, 0 otherwise. */ + +static inline int __raw_read_trylock(raw_rwlock_t *rw) +{ + unsigned long result; + unsigned long tmp; + + __asm__ __volatile__( + " l32i %1, %2, 0\n" + " addi %0, %1, 1\n" + " bltz %0, 1f\n" + " wsr %1, scompare1\n" + " s32c1i %0, %2, 0\n" + " sub %0, %0, %1\n" + "1:\n" + : "=&a" (result), "=&a" (tmp) + : "a" (&rw->lock) + : "memory"); + + return result == 0; +} + +static inline void __raw_read_unlock(raw_rwlock_t *rw) +{ + unsigned long tmp1, tmp2; + + __asm__ __volatile__( + "1: l32i %1, %2, 0\n" + " addi %0, %1, -1\n" + " wsr %1, scompare1\n" + " s32c1i %0, %2, 0\n" + " bne %0, %1, 1b\n" + : "=&a" (tmp1), "=&a" (tmp2) + : "a" (&rw->lock) + : "memory"); +} #endif /* _XTENSA_SPINLOCK_H */ -- cgit v1.2.1 From 599bf77a0d0b253dd94fd058275b05520c6d25db Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sat, 24 Nov 2012 06:22:08 +0400 Subject: xtensa: fix mb and wmb definitions Define mb and wmb as memw to force memory barrier. Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/include/asm/barrier.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/include/asm/barrier.h b/arch/xtensa/include/asm/barrier.h index 55707a8009d3..ef021677d536 100644 --- a/arch/xtensa/include/asm/barrier.h +++ b/arch/xtensa/include/asm/barrier.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001 - 2005 Tensilica Inc. + * Copyright (C) 2001 - 2012 Tensilica Inc. */ #ifndef _XTENSA_SYSTEM_H @@ -12,8 +12,8 @@ #define smp_read_barrier_depends() do { } while(0) #define read_barrier_depends() do { } while(0) -#define mb() barrier() -#define rmb() mb() +#define mb() ({ __asm__ __volatile__("memw" : : : "memory"); }) +#define rmb() barrier() #define wmb() mb() #ifdef CONFIG_SMP -- cgit v1.2.1 From 3f5ec298e56587462d91320c9e49f3e38f2beb17 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 5 Nov 2012 09:10:00 +0400 Subject: xtensa: clean up boot make rules - remove duplicate rules for binary and packed image - use predefined macros for ld/objcopy/gzip - remove build-id section from bootable elf image Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/boot/Makefile | 10 ++++++++++ arch/xtensa/boot/boot-elf/Makefile | 26 +++++++++++--------------- arch/xtensa/boot/boot-redboot/Makefile | 26 ++++++++++++-------------- 3 files changed, 33 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index 4018f8994196..4453859ebc78 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile @@ -31,3 +31,13 @@ $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ $(addprefix $(obj)/,$(host-progs)) $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) +OBJCOPYFLAGS = --strip-all -R .comment -R .note.gnu.build-id -O binary + +vmlinux.bin: vmlinux FORCE + $(call if_changed,objcopy) + +vmlinux.bin.gz: vmlinux.bin FORCE + $(call if_changed,gzip) + +boot-elf: vmlinux.bin +boot-redboot: vmlinux.bin.gz diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile index f10992b89027..1fe01b78c124 100644 --- a/arch/xtensa/boot/boot-elf/Makefile +++ b/arch/xtensa/boot/boot-elf/Makefile @@ -4,9 +4,6 @@ # for more details. # -GZIP = gzip -GZIP_FLAGS = -v9fc - ifeq ($(BIG_ENDIAN),1) OBJCOPY_ARGS := -O elf32-xtensa-be else @@ -20,18 +17,17 @@ boot-y := bootstrap.o OBJS := $(addprefix $(obj)/,$(boot-y)) -vmlinux.tmp: vmlinux - $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \ - $^ $@ - -Image: vmlinux.tmp $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section image=vmlinux.tmp \ +$(obj)/Image.o: vmlinux.bin $(OBJS) + $(Q)$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section image=vmlinux.bin \ --set-section-flags image=contents,alloc,load,load,data \ - $(OBJS) $@.tmp - $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ - -T arch/$(ARCH)/boot/boot-elf/boot.lds \ - -o arch/$(ARCH)/boot/$@.elf $@.tmp + $(OBJS) $@ -zImage: Image +$(obj)/../Image.elf: $(obj)/Image.o $(obj)/boot.lds + $(Q)$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ + -T $(obj)/boot.lds \ + --build-id=none \ + -o $@ $(obj)/Image.o + $(Q)$(kecho) ' Kernel: $@ is ready' +zImage: $(obj)/../Image.elf diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile index 25a78c6b1530..8be8b9436981 100644 --- a/arch/xtensa/boot/boot-redboot/Makefile +++ b/arch/xtensa/boot/boot-redboot/Makefile @@ -4,8 +4,6 @@ # for more details. # -GZIP = gzip -GZIP_FLAGS = -v9fc ifeq ($(BIG_ENDIAN),1) OBJCOPY_ARGS := -O elf32-xtensa-be else @@ -21,17 +19,17 @@ LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) -vmlinux.tmp: vmlinux - $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \ - $^ $@ +$(obj)/zImage.o: vmlinux.bin.gz $(OBJS) + $(Q)$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section image=vmlinux.bin.gz \ + --set-section-flags image=contents,alloc,load,load,data \ + $(OBJS) $@ -vmlinux.tmp.gz: vmlinux.tmp - $(GZIP) $(GZIP_FLAGS) $^ > $@ +$(obj)/zImage.elf: $(obj)/zImage.o $(LIBS) + $(Q)$(LD) $(LD_ARGS) -o $@ $^ -L/xtensa-elf/lib $(LIBGCC) -zImage: vmlinux.tmp.gz $(OBJS) $(LIBS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section image=vmlinux.tmp.gz \ - --set-section-flags image=contents,alloc,load,load,data \ - $(OBJS) $@.tmp - $(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC) - $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/$@.redboot +$(obj)/../zImage.redboot: $(obj)/zImage.elf + $(Q)$(OBJCOPY) -S -O binary $< $@ + $(Q)$(kecho) ' Kernel: $@ is ready' + +zImage: $(obj)/../zImage.redboot -- cgit v1.2.1 From 0322cabd39e27614772595abb395871e86ebff66 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 5 Nov 2012 07:36:00 +0400 Subject: xtensa: add U-Boot image support (uImage). Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/boot/Makefile | 3 ++- arch/xtensa/boot/boot-uboot/Makefile | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 arch/xtensa/boot/boot-uboot/Makefile (limited to 'arch') diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index 4453859ebc78..ff974fc2935b 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile @@ -22,7 +22,7 @@ subdir-y := lib # Subdirs for the boot loader(s) bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf -bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf +bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot zImage Image: $(bootdir-y) @@ -41,3 +41,4 @@ vmlinux.bin.gz: vmlinux.bin FORCE boot-elf: vmlinux.bin boot-redboot: vmlinux.bin.gz +boot-uboot: vmlinux.bin.gz diff --git a/arch/xtensa/boot/boot-uboot/Makefile b/arch/xtensa/boot/boot-uboot/Makefile new file mode 100644 index 000000000000..bfbf8af582f1 --- /dev/null +++ b/arch/xtensa/boot/boot-uboot/Makefile @@ -0,0 +1,14 @@ +# +# 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. +# + +UIMAGE_LOADADDR = 0xd0001000 +UIMAGE_COMPRESSION = gzip + +$(obj)/../uImage: vmlinux.bin.gz FORCE + $(call if_changed,uimage) + $(Q)$(kecho) ' Kernel: $@ is ready' + +zImage: $(obj)/../uImage -- cgit v1.2.1 From 2206d5dd9a785a74afc6981f2b13b7a4d4da6f31 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 4 Nov 2012 00:29:12 +0400 Subject: xtensa: add IRQ domains support IRQ domains provide a mechanism for conversion of linux IRQ numbers to hardware IRQ numbers and vice versus. It is used by OpenFirmware for linking device tree objects to their respective interrupt controllers. Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/Kconfig | 1 + arch/xtensa/kernel/irq.c | 122 +++++++++++++++++++++++++++++++++------------- arch/xtensa/kernel/time.c | 5 +- 3 files changed, 94 insertions(+), 34 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 2481f267be29..1816abc5c8d5 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -17,6 +17,7 @@ config XTENSA select GENERIC_KERNEL_EXECVE select ARCH_WANT_OPTIONAL_GPIOLIB select CLONE_BACKWARDS + select IRQ_DOMAIN help Xtensa processors are 32-bit RISC machines designed by Tensilica primarily for embedded systems. These processors are both diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index a6ce3e563739..e90d78211195 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -26,19 +27,22 @@ static unsigned int cached_irq_mask; atomic_t irq_err_count; +static struct irq_domain *root_domain; + /* * do_IRQ handles all normal device IRQ's (the special * SMP cross-CPU interrupts have their own specific * handlers). */ -asmlinkage void do_IRQ(int irq, struct pt_regs *regs) +asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); + int irq = irq_find_mapping(root_domain, hwirq); - if (irq >= NR_IRQS) { + if (hwirq >= NR_IRQS) { printk(KERN_EMERG "%s: cannot handle IRQ %d\n", - __func__, irq); + __func__, hwirq); } irq_enter(); @@ -71,40 +75,39 @@ int arch_show_interrupts(struct seq_file *p, int prec) static void xtensa_irq_mask(struct irq_data *d) { - cached_irq_mask &= ~(1 << d->irq); + cached_irq_mask &= ~(1 << d->hwirq); set_sr (cached_irq_mask, intenable); } static void xtensa_irq_unmask(struct irq_data *d) { - cached_irq_mask |= 1 << d->irq; + cached_irq_mask |= 1 << d->hwirq; set_sr (cached_irq_mask, intenable); } static void xtensa_irq_enable(struct irq_data *d) { - variant_irq_enable(d->irq); + variant_irq_enable(d->hwirq); xtensa_irq_unmask(d); } static void xtensa_irq_disable(struct irq_data *d) { xtensa_irq_mask(d); - variant_irq_disable(d->irq); + variant_irq_disable(d->hwirq); } static void xtensa_irq_ack(struct irq_data *d) { - set_sr(1 << d->irq, intclear); + set_sr(1 << d->hwirq, intclear); } static int xtensa_irq_retrigger(struct irq_data *d) { - set_sr (1 << d->irq, INTSET); + set_sr(1 << d->hwirq, intset); return 1; } - static struct irq_chip xtensa_irq_chip = { .name = "xtensa", .irq_enable = xtensa_irq_enable, @@ -115,37 +118,90 @@ static struct irq_chip xtensa_irq_chip = { .irq_retrigger = xtensa_irq_retrigger, }; -void __init init_IRQ(void) +static int xtensa_irq_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) { - int index; - - for (index = 0; index < XTENSA_NR_IRQS; index++) { - int mask = 1 << index; - - if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) - irq_set_chip_and_handler(index, &xtensa_irq_chip, - handle_simple_irq); + u32 mask = 1 << hw; + + if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) { + irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, + handle_simple_irq, "level"); + irq_set_status_flags(irq, IRQ_LEVEL); + } else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) { + irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, + handle_edge_irq, "edge"); + irq_clear_status_flags(irq, IRQ_LEVEL); + } else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) { + irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, + handle_level_irq, "level"); + irq_set_status_flags(irq, IRQ_LEVEL); + } else if (mask & XCHAL_INTTYPE_MASK_TIMER) { + irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, + handle_edge_irq, "edge"); + irq_clear_status_flags(irq, IRQ_LEVEL); + } else {/* XCHAL_INTTYPE_MASK_WRITE_ERROR */ + /* XCHAL_INTTYPE_MASK_NMI */ + + irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, + handle_level_irq, "level"); + irq_set_status_flags(irq, IRQ_LEVEL); + } + return 0; +} - else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) - irq_set_chip_and_handler(index, &xtensa_irq_chip, - handle_edge_irq); +static unsigned map_ext_irq(unsigned ext_irq) +{ + unsigned mask = XCHAL_INTTYPE_MASK_EXTERN_EDGE | + XCHAL_INTTYPE_MASK_EXTERN_LEVEL; + unsigned i; - else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) - irq_set_chip_and_handler(index, &xtensa_irq_chip, - handle_level_irq); + for (i = 0; mask; ++i, mask >>= 1) { + if ((mask & 1) && ext_irq-- == 0) + return i; + } + return XCHAL_NUM_INTERRUPTS; +} - else if (mask & XCHAL_INTTYPE_MASK_TIMER) - irq_set_chip_and_handler(index, &xtensa_irq_chip, - handle_edge_irq); +/* + * Device Tree IRQ specifier translation function which works with one or + * two cell bindings. First cell value maps directly to the hwirq number. + * Second cell if present specifies whether hwirq number is external (1) or + * internal (0). + */ +int xtensa_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, unsigned int *out_type) +{ + if (WARN_ON(intsize < 1 || intsize > 2)) + return -EINVAL; + if (intsize == 2 && intspec[1] == 1) { + unsigned int_irq = map_ext_irq(intspec[0]); + if (int_irq < XCHAL_NUM_INTERRUPTS) + *out_hwirq = int_irq; + else + return -EINVAL; + } else { + *out_hwirq = intspec[0]; + } + *out_type = IRQ_TYPE_NONE; + return 0; +} - else /* XCHAL_INTTYPE_MASK_WRITE_ERROR */ - /* XCHAL_INTTYPE_MASK_NMI */ +static const struct irq_domain_ops xtensa_irq_domain_ops = { + .xlate = xtensa_irq_domain_xlate, + .map = xtensa_irq_map, +}; - irq_set_chip_and_handler(index, &xtensa_irq_chip, - handle_level_irq); - } +void __init init_IRQ(void) +{ + struct device_node *intc = NULL; cached_irq_mask = 0; + set_sr(~0, intclear); + + root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0, + &xtensa_irq_domain_ops, NULL); + irq_set_default_host(root_domain); variant_init_irq(); } diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 19b32a0eaebc..ffb474104311 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -52,6 +53,7 @@ static struct irqaction timer_irqaction = { void __init time_init(void) { + unsigned int irq; #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT printk("Calibrating CPU frequency "); platform_calibrate_ccount(); @@ -62,7 +64,8 @@ void __init time_init(void) /* Initialize the linux timer interrupt. */ - setup_irq(LINUX_TIMER_INT, &timer_irqaction); + irq = irq_create_mapping(NULL, LINUX_TIMER_INT); + setup_irq(irq, &timer_irqaction); set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY); } -- cgit v1.2.1 From da844a81779e2bb263eca4ecb1046541fdb11cf8 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 4 Nov 2012 00:30:13 +0400 Subject: xtensa: add device trees support Device trees allow specification of hardware topology and device parameters at runtime instead of hard-coding them in platform setup code. This allows running single binary kernel on a range of compatible boards. New boot parameters tag BP_TAG_FDT is allocated and a pointer to flat device tree is passed in it. Note that current interrupt mapping scheme uses single cell for interrupt identification. That means that IRQ numbers used in DTS must be CPU internal IRQ numbers, not external. It is possible to extend interrupt identification to two cells, and use second cell to tell external IRQ numbers form internal. That would allow to use single DTS on multiple boards with different mapping of external IRQ numbers. Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/Kconfig | 11 +++ arch/xtensa/Makefile | 7 ++ arch/xtensa/boot/Makefile | 11 +++ arch/xtensa/include/asm/bootparam.h | 1 + arch/xtensa/include/asm/prom.h | 6 ++ arch/xtensa/kernel/irq.c | 10 +++ arch/xtensa/kernel/setup.c | 143 +++++++++++++++++++++++++++++------- 7 files changed, 164 insertions(+), 25 deletions(-) create mode 100644 arch/xtensa/include/asm/prom.h (limited to 'arch') diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 1816abc5c8d5..8ceb5b2ffbb1 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -178,6 +178,17 @@ config CMDLINE time by entering them here. As a minimum, you should specify the memory size and the root device (e.g., mem=64M root=/dev/nfs). +config USE_OF + bool "Flattened Device Tree support" + select OF + select OF_EARLY_FLATTREE + help + Include support for flattened device tree machine descriptions. + +config BUILTIN_DTB + string "DTB to build into the kernel image" + depends on OF + source "mm/Kconfig" source "drivers/pcmcia/Kconfig" diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index ab63c9beb930..227f658fc2b9 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -79,6 +79,10 @@ core-y += $(buildvar) $(buildplf) libs-y += arch/xtensa/lib/ $(LIBGCC) +ifneq ($(CONFIG_BUILTIN_DTB),"") +core-y += arch/xtensa/boot/ +endif + boot := arch/xtensa/boot all: zImage @@ -88,6 +92,9 @@ bzImage : zImage zImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) $@ +%.dtb: + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ + define archhelp @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' endef diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index ff974fc2935b..cb5ff4dbdf88 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile @@ -25,6 +25,17 @@ bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot +BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o +ifneq ($(CONFIG_BUILTIN_DTB),"") +obj-y += $(BUILTIN_DTB) +endif + +# Rule to build device tree blobs +$(obj)/%.dtb: $(src)/dts/%.dts FORCE + $(call if_changed_dep,dtc) + +clean-files := *.dtb.S + zImage Image: $(bootdir-y) $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ diff --git a/arch/xtensa/include/asm/bootparam.h b/arch/xtensa/include/asm/bootparam.h index 9983f2c1b7ee..057077e96c98 100644 --- a/arch/xtensa/include/asm/bootparam.h +++ b/arch/xtensa/include/asm/bootparam.h @@ -22,6 +22,7 @@ #define BP_TAG_MEMORY 0x1003 /* memory addr and size (bp_meminfo) */ #define BP_TAG_SERIAL_BAUSRATE 0x1004 /* baud rate of current console. */ #define BP_TAG_SERIAL_PORT 0x1005 /* serial device of current console */ +#define BP_TAG_FDT 0x1006 /* flat device tree addr */ #define BP_TAG_FIRST 0x7B0B /* first tag with a version number */ #define BP_TAG_LAST 0x7E0B /* last tag */ diff --git a/arch/xtensa/include/asm/prom.h b/arch/xtensa/include/asm/prom.h new file mode 100644 index 000000000000..f3d7cd2c0de7 --- /dev/null +++ b/arch/xtensa/include/asm/prom.h @@ -0,0 +1,6 @@ +#ifndef _XTENSA_ASM_PROM_H +#define _XTENSA_ASM_PROM_H + +#define HAVE_ARCH_DEVTREE_FIXUPS + +#endif /* _XTENSA_ASM_PROM_H */ diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index e90d78211195..6f4f9749cff7 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -199,8 +200,17 @@ void __init init_IRQ(void) cached_irq_mask = 0; set_sr(~0, intclear); +#ifdef CONFIG_OF + /* The interrupt controller device node is mandatory */ + intc = of_find_compatible_node(NULL, NULL, "xtensa,pic"); + BUG_ON(!intc); + + root_domain = irq_domain_add_linear(intc, NR_IRQS, + &xtensa_irq_domain_ops, NULL); +#else root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0, &xtensa_irq_domain_ops, NULL); +#endif irq_set_default_host(root_domain); variant_init_irq(); diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 45217617c60d..64d80e4b0bd4 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -22,6 +22,11 @@ #include #include +#ifdef CONFIG_OF +#include +#include +#endif + #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) # include #endif @@ -65,6 +70,11 @@ int initrd_is_mapped = 0; extern int initrd_below_start_ok; #endif +#ifdef CONFIG_OF +extern u32 __dtb_start[]; +void *dtb_start = __dtb_start; +#endif + unsigned char aux_device_present; extern unsigned long loops_per_jiffy; @@ -84,6 +94,8 @@ extern void init_mmu(void); static inline void init_mmu(void) { } #endif +extern int mem_reserve(unsigned long, unsigned long, int); +extern void bootmem_init(void); extern void zones_init(void); /* @@ -105,28 +117,33 @@ typedef struct tagtable { /* parse current tag */ -static int __init parse_tag_mem(const bp_tag_t *tag) +static int __init add_sysmem_bank(unsigned long type, unsigned long start, + unsigned long end) { - meminfo_t *mi = (meminfo_t*)(tag->data); - - if (mi->type != MEMORY_TYPE_CONVENTIONAL) - return -1; - if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) { printk(KERN_WARNING - "Ignoring memory bank 0x%08lx size %ldKB\n", - (unsigned long)mi->start, - (unsigned long)mi->end - (unsigned long)mi->start); + "Ignoring memory bank 0x%08lx size %ldKB\n", + start, end - start); return -EINVAL; } - sysmem.bank[sysmem.nr_banks].type = mi->type; - sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(mi->start); - sysmem.bank[sysmem.nr_banks].end = mi->end & PAGE_MASK; + sysmem.bank[sysmem.nr_banks].type = type; + sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(start); + sysmem.bank[sysmem.nr_banks].end = end & PAGE_MASK; sysmem.nr_banks++; return 0; } +static int __init parse_tag_mem(const bp_tag_t *tag) +{ + meminfo_t *mi = (meminfo_t *)(tag->data); + + if (mi->type != MEMORY_TYPE_CONVENTIONAL) + return -1; + + return add_sysmem_bank(mi->type, mi->start, mi->end); +} + __tagtable(BP_TAG_MEMORY, parse_tag_mem); #ifdef CONFIG_BLK_DEV_INITRD @@ -143,12 +160,31 @@ static int __init parse_tag_initrd(const bp_tag_t* tag) __tagtable(BP_TAG_INITRD, parse_tag_initrd); +#ifdef CONFIG_OF + +static int __init parse_tag_fdt(const bp_tag_t *tag) +{ + dtb_start = (void *)(tag->data[0]); + return 0; +} + +__tagtable(BP_TAG_FDT, parse_tag_fdt); + +void __init early_init_dt_setup_initrd_arch(unsigned long start, + unsigned long end) +{ + initrd_start = (void *)__va(start); + initrd_end = (void *)__va(end); + initrd_below_start_ok = 1; +} + +#endif /* CONFIG_OF */ + #endif /* CONFIG_BLK_DEV_INITRD */ static int __init parse_tag_cmdline(const bp_tag_t* tag) { - strncpy(command_line, (char*)(tag->data), COMMAND_LINE_SIZE); - command_line[COMMAND_LINE_SIZE - 1] = '\0'; + strlcpy(command_line, (char *)(tag->data), COMMAND_LINE_SIZE); return 0; } @@ -186,6 +222,58 @@ static int __init parse_bootparam(const bp_tag_t* tag) return 0; } +#ifdef CONFIG_OF + +void __init early_init_dt_add_memory_arch(u64 base, u64 size) +{ + size &= PAGE_MASK; + add_sysmem_bank(MEMORY_TYPE_CONVENTIONAL, base, base + size); +} + +void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) +{ + return __alloc_bootmem(size, align, 0); +} + +void __init early_init_devtree(void *params) +{ + /* Setup flat device-tree pointer */ + initial_boot_params = params; + + /* Retrieve various informations from the /chosen node of the + * device-tree, including the platform type, initrd location and + * size, TCE reserve, and more ... + */ + if (!command_line[0]) + of_scan_flat_dt(early_init_dt_scan_chosen, command_line); + + /* Scan memory nodes and rebuild MEMBLOCKs */ + of_scan_flat_dt(early_init_dt_scan_root, NULL); + if (sysmem.nr_banks == 0) + of_scan_flat_dt(early_init_dt_scan_memory, NULL); +} + +static void __init copy_devtree(void) +{ + void *alloc = early_init_dt_alloc_memory_arch( + be32_to_cpu(initial_boot_params->totalsize), 0); + if (alloc) { + memcpy(alloc, initial_boot_params, + be32_to_cpu(initial_boot_params->totalsize)); + initial_boot_params = alloc; + } +} + +static int __init xtensa_device_probe(void) +{ + of_platform_populate(NULL, NULL, NULL, NULL); + return 0; +} + +device_initcall(xtensa_device_probe); + +#endif /* CONFIG_OF */ + /* * Initialize architecture. (Early stage) */ @@ -194,14 +282,14 @@ void __init init_arch(bp_tag_t *bp_start) { sysmem.nr_banks = 0; -#ifdef CONFIG_CMDLINE_BOOL - strcpy(command_line, default_command_line); -#endif - /* Parse boot parameters */ if (bp_start) - parse_bootparam(bp_start); + parse_bootparam(bp_start); + +#ifdef CONFIG_OF + early_init_devtree(dtb_start); +#endif if (sysmem.nr_banks == 0) { sysmem.nr_banks = 1; @@ -210,6 +298,11 @@ void __init init_arch(bp_tag_t *bp_start) + PLATFORM_DEFAULT_MEM_SIZE; } +#ifdef CONFIG_CMDLINE_BOOL + if (!command_line[0]) + strlcpy(command_line, default_command_line, COMMAND_LINE_SIZE); +#endif + /* Early hook for platforms */ platform_init(bp_start); @@ -355,11 +448,7 @@ void __init check_s32c1i(void) void __init setup_arch(char **cmdline_p) { - extern int mem_reserve(unsigned long, unsigned long, int); - extern void bootmem_init(void); - - memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - boot_command_line[COMMAND_LINE_SIZE-1] = '\0'; + strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; check_s32c1i(); @@ -395,8 +484,12 @@ void __init setup_arch(char **cmdline_p) bootmem_init(); - platform_setup(cmdline_p); +#ifdef CONFIG_OF + copy_devtree(); + unflatten_device_tree(); +#endif + platform_setup(cmdline_p); paging_init(); zones_init(); -- cgit v1.2.1 From 0d456bad36d42d16022be045c8a53ddbb59ee478 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 5 Nov 2012 07:37:14 +0400 Subject: xtensa: add support for the XTFPGA boards The Avnet LX60/LX110/LX200 board is an FPGA board that can be configured with an Xtensa processor and an OpenCores Ethernet device. Signed-off-by: Chris Zankel Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/Kconfig | 9 + arch/xtensa/Makefile | 1 + arch/xtensa/boot/Makefile | 1 + arch/xtensa/platforms/xtfpga/Makefile | 9 + .../platforms/xtfpga/include/platform/hardware.h | 69 ++++++ .../xtensa/platforms/xtfpga/include/platform/lcd.h | 20 ++ .../platforms/xtfpga/include/platform/serial.h | 18 ++ arch/xtensa/platforms/xtfpga/lcd.c | 76 ++++++ arch/xtensa/platforms/xtfpga/setup.c | 269 +++++++++++++++++++++ 9 files changed, 472 insertions(+) create mode 100644 arch/xtensa/platforms/xtfpga/Makefile create mode 100644 arch/xtensa/platforms/xtfpga/include/platform/hardware.h create mode 100644 arch/xtensa/platforms/xtfpga/include/platform/lcd.h create mode 100644 arch/xtensa/platforms/xtfpga/include/platform/serial.h create mode 100644 arch/xtensa/platforms/xtfpga/lcd.c create mode 100644 arch/xtensa/platforms/xtfpga/setup.c (limited to 'arch') diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 8ceb5b2ffbb1..73d34e77c39c 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -151,6 +151,15 @@ config XTENSA_PLATFORM_S6105 select SERIAL_CONSOLE select NO_IOPORT +config XTENSA_PLATFORM_XTFPGA + bool "XTFPGA" + select SERIAL_CONSOLE + select ETHOC + select XTENSA_CALIBRATE_CCOUNT + help + XTFPGA is the name of Tensilica board family (LX60, LX110, LX200, ML605). + This hardware is capable of running a full Linux distribution. + endchoice diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 227f658fc2b9..7e0ae8fd4da8 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -38,6 +38,7 @@ endif platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105 +platform-$(CONFIG_XTENSA_PLATFORM_XTFPGA) := xtfpga PLATFORM = $(platform-y) export PLATFORM diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index cb5ff4dbdf88..196bc3c967af 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile @@ -23,6 +23,7 @@ subdir-y := lib bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot +bootdir-$(CONFIG_XTENSA_PLATFORM_XTFPGA) += boot-redboot boot-elf boot-uboot BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o diff --git a/arch/xtensa/platforms/xtfpga/Makefile b/arch/xtensa/platforms/xtfpga/Makefile new file mode 100644 index 000000000000..b9ae206340cd --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/Makefile @@ -0,0 +1,9 @@ +# Makefile for the Tensilica xtavnet Emulation Board +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are in the main makefile... + +obj-y = setup.o lcd.o diff --git a/arch/xtensa/platforms/xtfpga/include/platform/hardware.h b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h new file mode 100644 index 000000000000..4416773cbde5 --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h @@ -0,0 +1,69 @@ +/* + * arch/xtensa/platform/xtavnet/include/platform/hardware.h + * + * 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. + * + * Copyright (C) 2006 Tensilica Inc. + */ + +/* + * This file contains the hardware configuration of the XTAVNET boards. + */ + +#ifndef __XTENSA_XTAVNET_HARDWARE_H +#define __XTENSA_XTAVNET_HARDWARE_H + +/* By default NO_IRQ is defined to 0 in Linux, but we use the + interrupt 0 for UART... */ +#define NO_IRQ -1 + +/* Memory configuration. */ + +#define PLATFORM_DEFAULT_MEM_START 0x00000000 +#define PLATFORM_DEFAULT_MEM_SIZE 0x04000000 + +/* Interrupt configuration. */ + +#define PLATFORM_NR_IRQS 10 + +/* Default assignment of LX60 devices to external interrupts. */ + +#ifdef CONFIG_ARCH_HAS_SMP +#define DUART16552_INTNUM XCHAL_EXTINT3_NUM +#define OETH_IRQ XCHAL_EXTINT4_NUM +#else +#define DUART16552_INTNUM XCHAL_EXTINT0_NUM +#define OETH_IRQ XCHAL_EXTINT1_NUM +#endif + +/* + * Device addresses and parameters. + */ + +/* UART */ +#define DUART16552_PADDR (XCHAL_KIO_PADDR + 0x0D050020) +/* LCD instruction and data addresses. */ +#define LCD_INSTR_ADDR ((char *)IOADDR(0x0D040000)) +#define LCD_DATA_ADDR ((char *)IOADDR(0x0D040004)) + +/* Misc. */ +#define XTFPGA_FPGAREGS_VADDR IOADDR(0x0D020000) +/* Clock frequency in Hz (read-only): */ +#define XTFPGA_CLKFRQ_VADDR (XTFPGA_FPGAREGS_VADDR + 0x04) +/* Setting of 8 DIP switches: */ +#define DIP_SWITCHES_VADDR (XTFPGA_FPGAREGS_VADDR + 0x0C) +/* Software reset (write 0xdead): */ +#define XTFPGA_SWRST_VADDR (XTFPGA_FPGAREGS_VADDR + 0x10) + +/* OpenCores Ethernet controller: */ + /* regs + RX/TX descriptors */ +#define OETH_REGS_PADDR (XCHAL_KIO_PADDR + 0x0D030000) +#define OETH_REGS_SIZE 0x1000 +#define OETH_SRAMBUFF_PADDR (XCHAL_KIO_PADDR + 0x0D800000) + + /* 5*rx buffs + 5*tx buffs */ +#define OETH_SRAMBUFF_SIZE (5 * 0x600 + 5 * 0x600) + +#endif /* __XTENSA_XTAVNET_HARDWARE_H */ diff --git a/arch/xtensa/platforms/xtfpga/include/platform/lcd.h b/arch/xtensa/platforms/xtfpga/include/platform/lcd.h new file mode 100644 index 000000000000..0e435645af5a --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/include/platform/lcd.h @@ -0,0 +1,20 @@ +/* + * arch/xtensa/platform/xtavnet/include/platform/lcd.h + * + * 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. + * + * Copyright (C) 2001, 2006 Tensilica Inc. + */ + +#ifndef __XTENSA_XTAVNET_LCD_H +#define __XTENSA_XTAVNET_LCD_H + +/* Display string STR at position POS on the LCD. */ +void lcd_disp_at_pos(char *str, unsigned char pos); + +/* Shift the contents of the LCD display left or right. */ +void lcd_shiftleft(void); +void lcd_shiftright(void); +#endif diff --git a/arch/xtensa/platforms/xtfpga/include/platform/serial.h b/arch/xtensa/platforms/xtfpga/include/platform/serial.h new file mode 100644 index 000000000000..14d8f7beebfd --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/include/platform/serial.h @@ -0,0 +1,18 @@ +/* + * arch/xtensa/platform/xtavnet/include/platform/serial.h + * + * 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. + * + * Copyright (C) 2001, 2006 Tensilica Inc. + */ + +#ifndef __ASM_XTENSA_XTAVNET_SERIAL_H +#define __ASM_XTENSA_XTAVNET_SERIAL_H + +#include + +#define BASE_BAUD (*(long *)XTFPGA_CLKFRQ_VADDR / 16) + +#endif /* __ASM_XTENSA_XTAVNET_SERIAL_H */ diff --git a/arch/xtensa/platforms/xtfpga/lcd.c b/arch/xtensa/platforms/xtfpga/lcd.c new file mode 100644 index 000000000000..2872301598df --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/lcd.c @@ -0,0 +1,76 @@ +/* + * Driver for the LCD display on the Tensilica LX60 Board. + * + * 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. + * + * Copyright (C) 2001, 2006 Tensilica Inc. + */ + +/* + * + * FIXME: this code is from the examples from the LX60 user guide. + * + * The lcd_pause function does busy waiting, which is probably not + * great. Maybe the code could be changed to use kernel timers, or + * change the hardware to not need to wait. + */ + +#include +#include + +#include +#include +#include + +#define LCD_PAUSE_ITERATIONS 4000 +#define LCD_CLEAR 0x1 +#define LCD_DISPLAY_ON 0xc + +/* 8bit and 2 lines display */ +#define LCD_DISPLAY_MODE8BIT 0x38 +#define LCD_DISPLAY_POS 0x80 +#define LCD_SHIFT_LEFT 0x18 +#define LCD_SHIFT_RIGHT 0x1c + +static int __init lcd_init(void) +{ + *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; + mdelay(5); + *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; + udelay(200); + *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; + udelay(50); + *LCD_INSTR_ADDR = LCD_DISPLAY_ON; + udelay(50); + *LCD_INSTR_ADDR = LCD_CLEAR; + mdelay(10); + lcd_disp_at_pos("XTENSA LINUX", 0); + return 0; +} + +void lcd_disp_at_pos(char *str, unsigned char pos) +{ + *LCD_INSTR_ADDR = LCD_DISPLAY_POS | pos; + udelay(100); + while (*str != 0) { + *LCD_DATA_ADDR = *str; + udelay(200); + str++; + } +} + +void lcd_shiftleft(void) +{ + *LCD_INSTR_ADDR = LCD_SHIFT_LEFT; + udelay(50); +} + +void lcd_shiftright(void) +{ + *LCD_INSTR_ADDR = LCD_SHIFT_RIGHT; + udelay(50); +} + +arch_initcall(lcd_init); diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c new file mode 100644 index 000000000000..71d61ca6a4af --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/setup.c @@ -0,0 +1,269 @@ +/* + * + * arch/xtensa/platform/xtavnet/setup.c + * + * ... + * + * Authors: Chris Zankel + * Joe Taylor + * + * Copyright 2001 - 2006 Tensilica Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +void platform_halt(void) +{ + lcd_disp_at_pos(" HALT ", 0); + local_irq_disable(); + while (1) + cpu_relax(); +} + +void platform_power_off(void) +{ + lcd_disp_at_pos("POWEROFF", 0); + local_irq_disable(); + while (1) + cpu_relax(); +} + +void platform_restart(void) +{ + /* Flush and reset the mmu, simulate a processor reset, and + * jump to the reset vector. */ + + + __asm__ __volatile__ ("movi a2, 15\n\t" + "wsr a2, icountlevel\n\t" + "movi a2, 0\n\t" + "wsr a2, icount\n\t" + "wsr a2, ibreakenable\n\t" + "wsr a2, lcount\n\t" + "movi a2, 0x1f\n\t" + "wsr a2, ps\n\t" + "isync\n\t" + "jx %0\n\t" + : + : "a" (XCHAL_RESET_VECTOR_VADDR) + : "a2" + ); + + /* control never gets here */ +} + +void __init platform_setup(char **cmdline) +{ +} + +#ifdef CONFIG_OF + +static void __init update_clock_frequency(struct device_node *node) +{ + struct property *newfreq; + u32 freq; + + if (!of_property_read_u32(node, "clock-frequency", &freq) && + freq != 0) + return; + + newfreq = kzalloc(sizeof(*newfreq) + sizeof(u32), GFP_KERNEL); + if (!newfreq) + return; + newfreq->value = newfreq + 1; + newfreq->length = sizeof(freq); + newfreq->name = kstrdup("clock-frequency", GFP_KERNEL); + if (!newfreq->name) { + kfree(newfreq); + return; + } + + *(u32 *)newfreq->value = cpu_to_be32(*(u32 *)XTFPGA_CLKFRQ_VADDR); + prom_update_property(node, newfreq); +} + +static int __init machine_setup(void) +{ + struct device_node *serial = NULL; + + while ((serial = of_find_compatible_node(serial, NULL, "ns16550a"))) + update_clock_frequency(serial); + return 0; +} +arch_initcall(machine_setup); + +#endif + +/* early initialization */ + +void __init platform_init(bp_tag_t *first) +{ +} + +/* Heartbeat. */ + +void platform_heartbeat(void) +{ +} + +#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT + +void platform_calibrate_ccount(void) +{ + long clk_freq = 0; +#ifdef CONFIG_OF + struct device_node *cpu = + of_find_compatible_node(NULL, NULL, "xtensa,cpu"); + if (cpu) { + u32 freq; + update_clock_frequency(cpu); + if (!of_property_read_u32(cpu, "clock-frequency", &freq)) + clk_freq = freq; + } +#endif + if (!clk_freq) + clk_freq = *(long *)XTFPGA_CLKFRQ_VADDR; + + ccount_per_jiffy = clk_freq / HZ; + nsec_per_ccount = 1000000000UL / clk_freq; +} + +#endif + +#ifndef CONFIG_OF + +#include +#include +#include + +/*---------------------------------------------------------------------------- + * Ethernet -- OpenCores Ethernet MAC (ethoc driver) + */ + +static struct resource ethoc_res[] __initdata = { + [0] = { /* register space */ + .start = OETH_REGS_PADDR, + .end = OETH_REGS_PADDR + OETH_REGS_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { /* buffer space */ + .start = OETH_SRAMBUFF_PADDR, + .end = OETH_SRAMBUFF_PADDR + OETH_SRAMBUFF_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { /* IRQ number */ + .start = OETH_IRQ, + .end = OETH_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct ethoc_platform_data ethoc_pdata __initdata = { + /* + * The MAC address for these boards is 00:50:c2:13:6f:xx. + * The last byte (here as zero) is read from the DIP switches on the + * board. + */ + .hwaddr = { 0x00, 0x50, 0xc2, 0x13, 0x6f, 0 }, + .phy_id = -1, +}; + +static struct platform_device ethoc_device __initdata = { + .name = "ethoc", + .id = -1, + .num_resources = ARRAY_SIZE(ethoc_res), + .resource = ethoc_res, + .dev = { + .platform_data = ðoc_pdata, + }, +}; + +/*---------------------------------------------------------------------------- + * UART + */ + +static struct resource serial_resource __initdata = { + .start = DUART16552_PADDR, + .end = DUART16552_PADDR + 0x1f, + .flags = IORESOURCE_MEM, +}; + +static struct plat_serial8250_port serial_platform_data[] __initdata = { + [0] = { + .mapbase = DUART16552_PADDR, + .irq = DUART16552_INTNUM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | + UPF_IOREMAP, + .iotype = UPIO_MEM32, + .regshift = 2, + .uartclk = 0, /* set in xtavnet_init() */ + }, + { }, +}; + +static struct platform_device xtavnet_uart __initdata = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = serial_platform_data, + }, + .num_resources = 1, + .resource = &serial_resource, +}; + +/* platform devices */ +static struct platform_device *platform_devices[] __initdata = { + ðoc_device, + &xtavnet_uart, +}; + + +static int __init xtavnet_init(void) +{ + /* Ethernet MAC address. */ + ethoc_pdata.hwaddr[5] = *(u32 *)DIP_SWITCHES_VADDR; + + /* Clock rate varies among FPGA bitstreams; board specific FPGA register + * reports the actual clock rate. + */ + serial_platform_data[0].uartclk = *(long *)XTFPGA_CLKFRQ_VADDR; + + + /* register platform devices */ + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + + /* ETHOC driver is a bit quiet; at least display Ethernet MAC, so user + * knows whether they set it correctly on the DIP switches. + */ + pr_info("XTFPGA: Ethernet MAC %pM\n", ethoc_pdata.hwaddr); + + return 0; +} + +/* + * Register to be done during do_initcalls(). + */ +arch_initcall(xtavnet_init); + +#endif /* CONFIG_OF */ -- cgit v1.2.1 From 5584b4da7814af7d35a72d904140bf9c2a502d4e Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sat, 3 Nov 2012 12:57:52 +0400 Subject: xtensa: add XTFPGA DTS Add common XTFPGA parts as *.dtsi (base board, flash) and DTS for LX60 and for ML605. Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/boot/dts/lx60.dts | 11 ++++++ arch/xtensa/boot/dts/ml605.dts | 11 ++++++ arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi | 26 ++++++++++++++ arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi | 18 ++++++++++ arch/xtensa/boot/dts/xtfpga.dtsi | 56 ++++++++++++++++++++++++++++++ 5 files changed, 122 insertions(+) create mode 100644 arch/xtensa/boot/dts/lx60.dts create mode 100644 arch/xtensa/boot/dts/ml605.dts create mode 100644 arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi create mode 100644 arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi create mode 100644 arch/xtensa/boot/dts/xtfpga.dtsi (limited to 'arch') diff --git a/arch/xtensa/boot/dts/lx60.dts b/arch/xtensa/boot/dts/lx60.dts new file mode 100644 index 000000000000..2eab3658e1bd --- /dev/null +++ b/arch/xtensa/boot/dts/lx60.dts @@ -0,0 +1,11 @@ +/dts-v1/; +/include/ "xtfpga.dtsi" +/include/ "xtfpga-flash-4m.dtsi" + +/ { + compatible = "xtensa,lx60"; + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x04000000>; + }; +}; diff --git a/arch/xtensa/boot/dts/ml605.dts b/arch/xtensa/boot/dts/ml605.dts new file mode 100644 index 000000000000..6ed51d6554e6 --- /dev/null +++ b/arch/xtensa/boot/dts/ml605.dts @@ -0,0 +1,11 @@ +/dts-v1/; +/include/ "xtfpga.dtsi" +/include/ "xtfpga-flash-16m.dtsi" + +/ { + compatible = "xtensa,ml605"; + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x08000000>; + }; +}; diff --git a/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi new file mode 100644 index 000000000000..e5703c7beeb6 --- /dev/null +++ b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi @@ -0,0 +1,26 @@ +/ { + flash: flash@f8000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0xf8000000 0x01000000>; + bank-width = <2>; + device-width = <2>; + partition@0x0 { + label = "boot loader area"; + reg = <0x00000000 0x00400000>; + }; + partition@0x400000 { + label = "kernel image"; + reg = <0x00400000 0x00600000>; + }; + partition@0xa00000 { + label = "data"; + reg = <0x00a00000 0x005e0000>; + }; + partition@0xfe0000 { + label = "boot environment"; + reg = <0x00fe0000 0x00020000>; + }; + }; +}; diff --git a/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi new file mode 100644 index 000000000000..6f9c10d6b689 --- /dev/null +++ b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi @@ -0,0 +1,18 @@ +/ { + flash: flash@f8000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0xf8000000 0x00400000>; + bank-width = <2>; + device-width = <2>; + partition@0x0 { + label = "boot loader area"; + reg = <0x00000000 0x003f0000>; + }; + partition@0x3f0000 { + label = "boot environment"; + reg = <0x003f0000 0x00010000>; + }; + }; +}; diff --git a/arch/xtensa/boot/dts/xtfpga.dtsi b/arch/xtensa/boot/dts/xtfpga.dtsi new file mode 100644 index 000000000000..7eda6ecf7eef --- /dev/null +++ b/arch/xtensa/boot/dts/xtfpga.dtsi @@ -0,0 +1,56 @@ +/ { + compatible = "xtensa,xtfpga"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&pic>; + + chosen { + bootargs = "earlycon=uart8250,mmio32,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x06000000>; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu@0 { + compatible = "xtensa,cpu"; + reg = <0>; + /* Filled in by platform_setup from FPGA register + * clock-frequency = <100000000>; + */ + }; + }; + + pic: pic { + compatible = "xtensa,pic"; + /* one cell: internal irq number, + * two cells: second cell == 0: internal irq number + * second cell == 1: external irq number + */ + #interrupt-cells = <2>; + interrupt-controller; + }; + + serial0: serial@fd050020 { + device_type = "serial"; + compatible = "ns16550a"; + no-loopback-test; + reg = <0xfd050020 0x20>; + reg-shift = <2>; + interrupts = <0 1>; /* external irq 0 */ + /* Filled in by platform_setup from FPGA register + * clock-frequency = <100000000>; + */ + }; + + enet0: ethoc@fd030000 { + compatible = "opencores,ethoc"; + reg = <0xfd030000 0x4000 0xfd800000 0x4000>; + interrupts = <1 1>; /* external irq 1 */ + local-mac-address = [00 50 c2 13 6f 00]; + }; +}; -- cgit v1.2.1 From 90e3bc798bec8b33ba4300a7751b627b54b3bb5b Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 3 Dec 2012 00:35:11 -0800 Subject: Use for_each_compatible_node() macro. Signed-off-by: Wei Yongjun Acked-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/platforms/xtfpga/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c index 71d61ca6a4af..237c36dc18b8 100644 --- a/arch/xtensa/platforms/xtfpga/setup.c +++ b/arch/xtensa/platforms/xtfpga/setup.c @@ -105,9 +105,9 @@ static void __init update_clock_frequency(struct device_node *node) static int __init machine_setup(void) { - struct device_node *serial = NULL; + struct device_node *serial; - while ((serial = of_find_compatible_node(serial, NULL, "ns16550a"))) + for_each_compatible_node(serial, NULL, "ns16550a") update_clock_frequency(serial); return 0; } -- cgit v1.2.1 From 79fcf52ba0dbcb9888812113df2d7248b41e9af1 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 11 Dec 2012 01:26:22 +0400 Subject: xtensa: reset all timers on initialization There are XCHAL_NUM_TIMERS, reset them all. Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/kernel/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index 9013ae0174f8..0cd337a341d9 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S @@ -111,7 +111,7 @@ ENTRY(_startup) /* Disable all timers. */ .set _index, 0 - .rept XCHAL_NUM_TIMERS - 1 + .rept XCHAL_NUM_TIMERS wsr a0, SREG_CCOMPARE + _index .set _index, _index + 1 .endr -- cgit v1.2.1 From eab5e7a79d1bb3d607dabf022bfad9f46d1e3ac8 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 11 Dec 2012 01:26:23 +0400 Subject: xtensa: initialize CPENABLE SR when core has one XCHAL_CP_NUM is defined in variant/tie.h and it is not included by head.S, leaving CPENABLE register uninitialised. XCHAL_HAVE_CP is defined in variant/core.h to 1 when core has CPENABLE SR. Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/kernel/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index 0cd337a341d9..91d9095284de 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S @@ -124,7 +124,7 @@ ENTRY(_startup) /* Disable coprocessors. */ -#if XCHAL_CP_NUM > 0 +#if XCHAL_HAVE_CP wsr a0, cpenable #endif -- cgit v1.2.1 From ec747b21c7c709a712e5eee0b4d4326d755d58b5 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 11 Dec 2012 01:26:24 +0400 Subject: xtensa: fix RASID SR initialization set_rasid_register accepts new RASID SR value, but ASID_USER_FIRST is ASID value for the ring 1; RASID value is made by ASID_INSERT macro. Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/mm/mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index ca81654f3ec2..0f77f9d3bb8b 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c @@ -37,7 +37,7 @@ void __init init_mmu(void) /* Set rasid register to a known value. */ - set_rasid_register(ASID_USER_FIRST); + set_rasid_register(ASID_INSERT(ASID_USER_FIRST)); /* Set PTEVADDR special register to the start of the page * table, which is in kernel mappable space (ie. not -- cgit v1.2.1 From 72100ed7efac290f24bd90a5e7c8bc9f231d167d Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 11 Dec 2012 01:26:25 +0400 Subject: xtensa: provide endianness macro for sparse Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/Makefile | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 7e0ae8fd4da8..4a8a6ffb68ba 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -54,6 +54,13 @@ ifneq ($(CONFIG_LD_NO_RELAX),) LDFLAGS := --no-relax endif +ifeq ($(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#"),1) +CHECKFLAGS += -D__XTENSA_EB__ +endif +ifeq ($(shell echo -e __XTENSA_EL__ | $(CC) -E - | grep -v "\#"),1) +CHECKFLAGS += -D__XTENSA_EL__ +endif + vardirs := $(patsubst %,arch/xtensa/variants/%/,$(variant-y)) plfdirs := $(patsubst %,arch/xtensa/platforms/%/,$(platform-y)) -- cgit v1.2.1 From c4c4594b005d89b56964071bbbdeb07daac5bc76 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Wed, 28 Nov 2012 16:53:51 -0800 Subject: xtensa: clean up files to make them code-style compliant Remove heading and trailing spaces, trim trailing lines, and wrap lines that are longer than 80 characters. Signed-off-by: Chris Zankel --- arch/xtensa/Makefile | 1 - arch/xtensa/include/asm/bootparam.h | 19 ++++++--------- arch/xtensa/include/asm/cacheasm.h | 1 - arch/xtensa/include/asm/cacheflush.h | 3 ++- arch/xtensa/include/asm/checksum.h | 19 +++++++++------ arch/xtensa/include/asm/cmpxchg.h | 3 ++- arch/xtensa/include/asm/current.h | 2 +- arch/xtensa/include/asm/delay.h | 7 +++--- arch/xtensa/include/asm/dma-mapping.h | 4 +-- arch/xtensa/include/asm/elf.h | 10 ++++---- arch/xtensa/include/asm/highmem.h | 1 - arch/xtensa/include/asm/mmu_context.h | 2 +- arch/xtensa/include/asm/nommu_context.h | 2 +- arch/xtensa/include/asm/page.h | 20 ++++++++------- arch/xtensa/include/asm/pci-bridge.h | 2 +- arch/xtensa/include/asm/pci.h | 2 +- arch/xtensa/include/asm/pgalloc.h | 2 +- arch/xtensa/include/asm/pgtable.h | 8 +++--- arch/xtensa/include/asm/platform.h | 1 - arch/xtensa/include/asm/processor.h | 10 ++++---- arch/xtensa/include/asm/ptrace.h | 2 +- arch/xtensa/include/asm/regs.h | 1 - arch/xtensa/include/asm/syscall.h | 11 +++++---- arch/xtensa/include/asm/uaccess.h | 43 ++++++++++++++++++--------------- arch/xtensa/kernel/Makefile | 8 +++--- arch/xtensa/kernel/align.S | 3 +-- arch/xtensa/kernel/asm-offsets.c | 4 +-- arch/xtensa/kernel/coprocessor.S | 3 +-- arch/xtensa/kernel/entry.S | 24 +++++++++--------- arch/xtensa/kernel/module.c | 2 +- arch/xtensa/kernel/platform.c | 1 - arch/xtensa/kernel/process.c | 2 +- arch/xtensa/kernel/ptrace.c | 3 +-- arch/xtensa/kernel/setup.c | 7 +++--- arch/xtensa/kernel/signal.c | 8 +++--- arch/xtensa/kernel/syscall.c | 1 - arch/xtensa/kernel/traps.c | 7 +++--- arch/xtensa/kernel/vectors.S | 2 -- arch/xtensa/lib/checksum.S | 10 ++++---- arch/xtensa/lib/memcopy.S | 6 +++-- arch/xtensa/lib/pci-auto.c | 9 ++----- arch/xtensa/lib/strncpy_user.S | 4 +-- arch/xtensa/lib/strnlen_user.S | 1 - arch/xtensa/lib/usercopy.S | 1 - arch/xtensa/mm/cache.c | 27 ++++++++++----------- arch/xtensa/mm/fault.c | 1 - arch/xtensa/mm/init.c | 16 ++++++------ arch/xtensa/mm/misc.S | 2 +- arch/xtensa/mm/tlb.c | 7 +++--- 49 files changed, 160 insertions(+), 175 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 4a8a6ffb68ba..4276721f5ae1 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -106,4 +106,3 @@ zImage: vmlinux define archhelp @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' endef - diff --git a/arch/xtensa/include/asm/bootparam.h b/arch/xtensa/include/asm/bootparam.h index 057077e96c98..0c25799facab 100644 --- a/arch/xtensa/include/asm/bootparam.h +++ b/arch/xtensa/include/asm/bootparam.h @@ -32,15 +32,15 @@ /* All records are aligned to 4 bytes */ typedef struct bp_tag { - unsigned short id; /* tag id */ - unsigned short size; /* size of this record excluding the structure*/ - unsigned long data[0]; /* data */ + unsigned short id; /* tag id */ + unsigned short size; /* size of this record excluding the structure*/ + unsigned long data[0]; /* data */ } bp_tag_t; typedef struct meminfo { - unsigned long type; - unsigned long start; - unsigned long end; + unsigned long type; + unsigned long start; + unsigned long end; } meminfo_t; #define SYSMEM_BANKS_MAX 5 @@ -49,14 +49,11 @@ typedef struct meminfo { #define MEMORY_TYPE_NONE 0x2000 typedef struct sysmem_info { - int nr_banks; - meminfo_t bank[SYSMEM_BANKS_MAX]; + int nr_banks; + meminfo_t bank[SYSMEM_BANKS_MAX]; } sysmem_info_t; extern sysmem_info_t sysmem; #endif #endif - - - diff --git a/arch/xtensa/include/asm/cacheasm.h b/arch/xtensa/include/asm/cacheasm.h index 2c20a58f94cd..60e18773ecb8 100644 --- a/arch/xtensa/include/asm/cacheasm.h +++ b/arch/xtensa/include/asm/cacheasm.h @@ -174,4 +174,3 @@ __loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH .endm - diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h index 569fec4f9a20..127cd48883c4 100644 --- a/arch/xtensa/include/asm/cacheflush.h +++ b/arch/xtensa/include/asm/cacheflush.h @@ -104,7 +104,8 @@ static inline void __invalidate_icache_page_alias(unsigned long virt, #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 extern void flush_dcache_page(struct page*); extern void flush_cache_range(struct vm_area_struct*, ulong, ulong); -extern void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned long); +extern void flush_cache_page(struct vm_area_struct*, + unsigned long, unsigned long); #else diff --git a/arch/xtensa/include/asm/checksum.h b/arch/xtensa/include/asm/checksum.h index e4d831a30772..aed7ad68ca46 100644 --- a/arch/xtensa/include/asm/checksum.h +++ b/arch/xtensa/include/asm/checksum.h @@ -36,8 +36,9 @@ asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum); * better 64-bit) boundary */ -asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, int len, __wsum sum, - int *src_err_ptr, int *dst_err_ptr); +asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, + int len, __wsum sum, + int *src_err_ptr, int *dst_err_ptr); /* * Note: when you get a NULL pointer exception here this means someone @@ -54,7 +55,7 @@ __wsum csum_partial_copy_nocheck(const void *src, void *dst, static inline __wsum csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) + int len, __wsum sum, int *err_ptr) { return csum_partial_copy_generic((__force const void *)src, dst, len, sum, err_ptr, NULL); @@ -112,7 +113,8 @@ static __inline__ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) /* Since the input registers which are loaded with iph and ihl are modified, we must also specify them as outputs, or gcc will assume they contain their original values. */ - : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), "=&r" (endaddr) + : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), + "=&r" (endaddr) : "1" (iph), "2" (ihl) : "memory"); @@ -168,7 +170,7 @@ static __inline__ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, static __inline__ __sum16 ip_compute_csum(const void *buff, int len) { - return csum_fold (csum_partial(buff, len, 0)); + return csum_fold (csum_partial(buff, len, 0)); } #define _HAVE_ARCH_IPV6_CSUM @@ -238,11 +240,12 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, * Copy and checksum to user */ #define HAVE_CSUM_COPY_USER -static __inline__ __wsum csum_and_copy_to_user(const void *src, void __user *dst, - int len, __wsum sum, int *err_ptr) +static __inline__ __wsum csum_and_copy_to_user(const void *src, + void __user *dst, int len, + __wsum sum, int *err_ptr) { if (access_ok(VERIFY_WRITE, dst, len)) - return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr); + return csum_partial_copy_generic(src,dst,len,sum,NULL,err_ptr); if (len) *err_ptr = -EFAULT; diff --git a/arch/xtensa/include/asm/cmpxchg.h b/arch/xtensa/include/asm/cmpxchg.h index 25869a190490..d9ab131bc1aa 100644 --- a/arch/xtensa/include/asm/cmpxchg.h +++ b/arch/xtensa/include/asm/cmpxchg.h @@ -134,7 +134,8 @@ static inline unsigned long xchg_u32(volatile int * m, unsigned long val) #endif } -#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define xchg(ptr,x) \ + ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) /* * This only works if the compiler isn't horribly bad at optimizing. diff --git a/arch/xtensa/include/asm/current.h b/arch/xtensa/include/asm/current.h index 8d1eb5d78649..47e46dcf5d49 100644 --- a/arch/xtensa/include/asm/current.h +++ b/arch/xtensa/include/asm/current.h @@ -30,7 +30,7 @@ static inline struct task_struct *get_current(void) #define GET_CURRENT(reg,sp) \ GET_THREAD_INFO(reg,sp); \ - l32i reg, reg, TI_TASK \ + l32i reg, reg, TI_TASK \ #endif diff --git a/arch/xtensa/include/asm/delay.h b/arch/xtensa/include/asm/delay.h index 58c0a4fd4003..61fc5faeb46c 100644 --- a/arch/xtensa/include/asm/delay.h +++ b/arch/xtensa/include/asm/delay.h @@ -19,9 +19,9 @@ extern unsigned long loops_per_jiffy; static inline void __delay(unsigned long loops) { - /* 2 cycles per loop. */ - __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" - : "=r" (loops) : "0" (loops)); + /* 2 cycles per loop. */ + __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" + : "=r" (loops) : "0" (loops)); } static __inline__ u32 xtensa_get_ccount(void) @@ -46,4 +46,3 @@ static __inline__ void udelay (unsigned long usecs) } #endif - diff --git a/arch/xtensa/include/asm/dma-mapping.h b/arch/xtensa/include/asm/dma-mapping.h index eb69743172b1..4acb5feba1fb 100644 --- a/arch/xtensa/include/asm/dma-mapping.h +++ b/arch/xtensa/include/asm/dma-mapping.h @@ -100,8 +100,8 @@ dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, } static inline void -dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, - enum dma_data_direction direction) +dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) { consistent_sync((void *)bus_to_virt(dma_handle), size, direction); } diff --git a/arch/xtensa/include/asm/elf.h b/arch/xtensa/include/asm/elf.h index 5293312bc6a4..264d5fa450d8 100644 --- a/arch/xtensa/include/asm/elf.h +++ b/arch/xtensa/include/asm/elf.h @@ -168,11 +168,11 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *); */ #define ELF_PLAT_INIT(_r, load_addr) \ - do { _r->areg[0]=0; /*_r->areg[1]=0;*/ _r->areg[2]=0; _r->areg[3]=0; \ - _r->areg[4]=0; _r->areg[5]=0; _r->areg[6]=0; _r->areg[7]=0; \ - _r->areg[8]=0; _r->areg[9]=0; _r->areg[10]=0; _r->areg[11]=0; \ - _r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \ - } while (0) + do { _r->areg[0]=0; /*_r->areg[1]=0;*/ _r->areg[2]=0; _r->areg[3]=0; \ + _r->areg[4]=0; _r->areg[5]=0; _r->areg[6]=0; _r->areg[7]=0; \ + _r->areg[8]=0; _r->areg[9]=0; _r->areg[10]=0; _r->areg[11]=0; \ + _r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \ + } while (0) typedef struct { xtregs_opt_t opt; diff --git a/arch/xtensa/include/asm/highmem.h b/arch/xtensa/include/asm/highmem.h index 0a046ca5a687..80be15124697 100644 --- a/arch/xtensa/include/asm/highmem.h +++ b/arch/xtensa/include/asm/highmem.h @@ -14,4 +14,3 @@ extern void flush_cache_kmaps(void); #endif - diff --git a/arch/xtensa/include/asm/mmu_context.h b/arch/xtensa/include/asm/mmu_context.h index feb10af96519..d43525a286bb 100644 --- a/arch/xtensa/include/asm/mmu_context.h +++ b/arch/xtensa/include/asm/mmu_context.h @@ -107,7 +107,7 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next) static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, - struct task_struct *tsk) + struct task_struct *tsk) { unsigned long asid = asid_cache; diff --git a/arch/xtensa/include/asm/nommu_context.h b/arch/xtensa/include/asm/nommu_context.h index 599e7a2e729d..3407cf7989b7 100644 --- a/arch/xtensa/include/asm/nommu_context.h +++ b/arch/xtensa/include/asm/nommu_context.h @@ -2,7 +2,7 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { } -static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) +static inline int init_new_context(struct task_struct *tsk,struct mm_struct *mm) { return 0; } diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h index 7a5591a71f85..47f582333f6b 100644 --- a/arch/xtensa/include/asm/page.h +++ b/arch/xtensa/include/asm/page.h @@ -29,19 +29,19 @@ * PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT 12 -#define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#define PAGE_SHIFT 12 +#define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) #ifdef CONFIG_MMU -#define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR -#define MAX_MEM_PFN XCHAL_KSEG_SIZE +#define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR +#define MAX_MEM_PFN XCHAL_KSEG_SIZE #else -#define PAGE_OFFSET 0 -#define MAX_MEM_PFN (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE) +#define PAGE_OFFSET 0 +#define MAX_MEM_PFN (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE) #endif -#define PGTABLE_START 0x80000000 +#define PGTABLE_START 0x80000000 /* * Cache aliasing: @@ -161,7 +161,9 @@ extern void copy_user_page(void*, void*, unsigned long, struct page*); #define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) -#define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr) +#define pfn_valid(pfn) \ + ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr) + #ifdef CONFIG_DISCONTIGMEM # error CONFIG_DISCONTIGMEM not supported #endif diff --git a/arch/xtensa/include/asm/pci-bridge.h b/arch/xtensa/include/asm/pci-bridge.h index 00fcbd7c534a..0b68c76ec1e6 100644 --- a/arch/xtensa/include/asm/pci-bridge.h +++ b/arch/xtensa/include/asm/pci-bridge.h @@ -35,7 +35,7 @@ struct pci_space { struct pci_controller { int index; /* used for pci_controller_num */ struct pci_controller *next; - struct pci_bus *bus; + struct pci_bus *bus; void *arch_data; int first_busno; diff --git a/arch/xtensa/include/asm/pci.h b/arch/xtensa/include/asm/pci.h index 05244f07dd31..614be031a79a 100644 --- a/arch/xtensa/include/asm/pci.h +++ b/arch/xtensa/include/asm/pci.h @@ -53,7 +53,7 @@ struct pci_dev; /* Map a range of PCI memory or I/O space for a device into user space */ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine); + enum pci_mmap_state mmap_state, int write_combine); /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ #define HAVE_PCI_MMAP 1 diff --git a/arch/xtensa/include/asm/pgalloc.h b/arch/xtensa/include/asm/pgalloc.h index 40cf9bceda2c..cf914c8c249a 100644 --- a/arch/xtensa/include/asm/pgalloc.h +++ b/arch/xtensa/include/asm/pgalloc.h @@ -42,7 +42,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) extern struct kmem_cache *pgtable_cache; -static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT); diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index b03c043ce75b..c90ea5bfa1b4 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h @@ -284,7 +284,7 @@ struct vm_area_struct; static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, - pte_t *ptep) + pte_t *ptep) { pte_t pte = *ptep; if (!pte_young(pte)) @@ -304,8 +304,8 @@ ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - pte_t pte = *ptep; - update_pte(ptep, pte_wrprotect(pte)); + pte_t pte = *ptep; + update_pte(ptep, pte_wrprotect(pte)); } /* to find an entry in a kernel page-table-directory */ @@ -399,7 +399,7 @@ extern void update_mmu_cache(struct vm_area_struct * vma, */ #define io_remap_pfn_range(vma,from,pfn,size,prot) \ - remap_pfn_range(vma, from, pfn, size, prot) + remap_pfn_range(vma, from, pfn, size, prot) typedef pte_t *pte_addr_t; diff --git a/arch/xtensa/include/asm/platform.h b/arch/xtensa/include/asm/platform.h index 7d936e58e9be..ec098b68fb9a 100644 --- a/arch/xtensa/include/asm/platform.h +++ b/arch/xtensa/include/asm/platform.h @@ -75,4 +75,3 @@ extern int platform_pcibios_fixup (void); extern void platform_calibrate_ccount (void); #endif /* _XTENSA_PLATFORM_H */ - diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 2d630e7399ca..e5fb6b0abdf4 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -89,7 +89,7 @@ #define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000)) typedef struct { - unsigned long seg; + unsigned long seg; } mm_segment_t; struct thread_struct { @@ -145,10 +145,10 @@ struct thread_struct { * set_thread_state in signal.c depends on it. */ #define USER_PS_VALUE ((1 << PS_WOE_BIT) | \ - (1 << PS_CALLINC_SHIFT) | \ - (USER_RING << PS_RING_SHIFT) | \ - (1 << PS_UM_BIT) | \ - (1 << PS_EXCM_BIT)) + (1 << PS_CALLINC_SHIFT) | \ + (USER_RING << PS_RING_SHIFT) | \ + (1 << PS_UM_BIT) | \ + (1 << PS_EXCM_BIT)) /* Clearing a0 terminates the backtrace. */ #define start_thread(regs, new_pc, new_sp) \ diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h index 9fe249c8f90e..58bf6fd3f913 100644 --- a/arch/xtensa/include/asm/ptrace.h +++ b/arch/xtensa/include/asm/ptrace.h @@ -55,7 +55,7 @@ struct pt_regs { # define arch_has_single_step() (1) # define task_pt_regs(tsk) ((struct pt_regs*) \ - (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1) + (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1) # define user_mode(regs) (((regs)->ps & 0x00000020)!=0) # define instruction_pointer(regs) ((regs)->pc) diff --git a/arch/xtensa/include/asm/regs.h b/arch/xtensa/include/asm/regs.h index 6aaf6d6a5fc4..76096a4e5b8d 100644 --- a/arch/xtensa/include/asm/regs.h +++ b/arch/xtensa/include/asm/regs.h @@ -109,4 +109,3 @@ #define DEBUGCAUSE_ICOUNT_BIT 0 /* ICOUNT would incr. to zero */ #endif /* _XTENSA_SPECREG_H */ - diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h index b00c928d4cce..8d5e47fad095 100644 --- a/arch/xtensa/include/asm/syscall.h +++ b/arch/xtensa/include/asm/syscall.h @@ -25,9 +25,10 @@ asmlinkage long xtensa_fadvise64_64(int, int, /* Should probably move to linux/syscalls.h */ struct pollfd; asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, struct timespec __user *tsp, void __user *sig); + fd_set __user *exp, struct timespec __user *tsp, + void __user *sig); asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds, - struct timespec __user *tsp, const sigset_t __user *sigmask, - size_t sigsetsize); -asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, - size_t sigsetsize); + struct timespec __user *tsp, + const sigset_t __user *sigmask, + size_t sigsetsize); +asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize); diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h index 6e4bb3b791ab..fd686dc45d1a 100644 --- a/arch/xtensa/include/asm/uaccess.h +++ b/arch/xtensa/include/asm/uaccess.h @@ -180,7 +180,8 @@ #define segment_eq(a,b) ((a).seg == (b).seg) #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) -#define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size))) +#define __user_ok(addr,size) \ + (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size))) #define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size))) #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) @@ -234,10 +235,10 @@ do { \ int __cb; \ retval = 0; \ switch (size) { \ - case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb); break; \ - case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break; \ - case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break; \ - case 8: { \ + case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb); break; \ + case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break; \ + case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break; \ + case 8: { \ __typeof__(*ptr) __v64 = x; \ retval = __copy_to_user(ptr,&__v64,8); \ break; \ @@ -291,7 +292,7 @@ do { \ * __check_align_* macros still work. */ #define __put_user_asm(x, addr, err, align, insn, cb) \ - __asm__ __volatile__( \ +__asm__ __volatile__( \ __check_align_##align \ "1: "insn" %2, %3, 0 \n" \ "2: \n" \ @@ -301,8 +302,8 @@ do { \ " .long 2b \n" \ "5: \n" \ " l32r %1, 4b \n" \ - " movi %0, %4 \n" \ - " jx %1 \n" \ + " movi %0, %4 \n" \ + " jx %1 \n" \ " .previous \n" \ " .section __ex_table,\"a\" \n" \ " .long 1b, 5b \n" \ @@ -334,13 +335,13 @@ extern long __get_user_bad(void); do { \ int __cb; \ retval = 0; \ - switch (size) { \ - case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb); break; \ - case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break; \ - case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb); break; \ - case 8: retval = __copy_from_user(&x,ptr,8); break; \ - default: (x) = __get_user_bad(); \ - } \ + switch (size) { \ + case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb); break; \ + case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break; \ + case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb); break; \ + case 8: retval = __copy_from_user(&x,ptr,8); break; \ + default: (x) = __get_user_bad(); \ + } \ } while (0) @@ -349,7 +350,7 @@ do { \ * __check_align_* macros still work. */ #define __get_user_asm(x, addr, err, align, insn, cb) \ - __asm__ __volatile__( \ +__asm__ __volatile__( \ __check_align_##align \ "1: "insn" %2, %3, 0 \n" \ "2: \n" \ @@ -360,8 +361,8 @@ do { \ "5: \n" \ " l32r %1, 4b \n" \ " movi %2, 0 \n" \ - " movi %0, %4 \n" \ - " jx %1 \n" \ + " movi %0, %4 \n" \ + " jx %1 \n" \ " .previous \n" \ " .section __ex_table,\"a\" \n" \ " .long 1b, 5b \n" \ @@ -421,8 +422,10 @@ __generic_copy_from_user(void *to, const void *from, unsigned long n) #define copy_to_user(to,from,n) __generic_copy_to_user((to),(from),(n)) #define copy_from_user(to,from,n) __generic_copy_from_user((to),(from),(n)) -#define __copy_to_user(to,from,n) __generic_copy_to_user_nocheck((to),(from),(n)) -#define __copy_from_user(to,from,n) __generic_copy_from_user_nocheck((to),(from),(n)) +#define __copy_to_user(to,from,n) \ + __generic_copy_to_user_nocheck((to),(from),(n)) +#define __copy_from_user(to,from,n) \ + __generic_copy_from_user_nocheck((to),(from),(n)) #define __copy_to_user_inatomic __copy_to_user #define __copy_from_user_inatomic __copy_from_user diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile index f36cef5a62ff..c3a59d992ac0 100644 --- a/arch/xtensa/kernel/Makefile +++ b/arch/xtensa/kernel/Makefile @@ -23,13 +23,13 @@ obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o # # Replicate rules in scripts/Makefile.build -sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \ - -e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \ +sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \ + -e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \ -e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g' quiet_cmd__cpp_lds_S = LDS $@ - cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \ - | sed $(sed-y) >$@ +cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \ + | sed $(sed-y) >$@ $(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE $(call if_changed_dep,_cpp_lds_S) diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S index 39d2f597382d..aa2e87b8566a 100644 --- a/arch/xtensa/kernel/align.S +++ b/arch/xtensa/kernel/align.S @@ -442,7 +442,7 @@ ENTRY(fast_unaligned) mov a1, a2 rsr a0, ps - bbsi.l a2, PS_UM_BIT, 1f # jump if user mode + bbsi.l a2, PS_UM_BIT, 1f # jump if user mode movi a0, _kernel_exception jx a0 @@ -453,4 +453,3 @@ ENTRY(fast_unaligned) ENDPROC(fast_unaligned) #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ - diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index 845475afc683..0701fad170db 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c @@ -92,7 +92,8 @@ int main(void) #endif DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user)); DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t)); - DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds)); + DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, \ + thread.current_ds)); /* struct mm_struct */ DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users)); @@ -109,4 +110,3 @@ int main(void) return 0; } - diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S index 60bb13589249..647657484866 100644 --- a/arch/xtensa/kernel/coprocessor.S +++ b/arch/xtensa/kernel/coprocessor.S @@ -172,7 +172,7 @@ ENTRY(coprocessor_load) ENDPROC(coprocessor_load) /* - * coprocessor_flush(struct task_info*, index) + * coprocessor_flush(struct task_info*, index) * a2 a3 * coprocessor_restore(struct task_info*, index) * a2 a3 @@ -354,4 +354,3 @@ ENTRY(coprocessor_owner) END(coprocessor_owner) #endif /* XTENSA_HAVE_COPROCESSORS */ - diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 4c2f2706ad5b..3777fec85e7c 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -874,7 +874,7 @@ ENTRY(fast_alloca) _bnei a0, 1, 1f # no 'movsp a1, ax': jump - /* Move the save area. This implies the use of the L32E + /* Move the save area. This implies the use of the L32E * and S32E instructions, because this move must be done with * the user's PS.RING privilege levels, not with ring 0 * (kernel's) privileges currently active with PS.EXCM @@ -1008,15 +1008,15 @@ ENDPROC(fast_syscall_user) ENTRY(fast_syscall_unrecoverable) - /* Restore all states. */ + /* Restore all states. */ - l32i a0, a2, PT_AREG0 # restore a0 - xsr a2, depc # restore a2, depc - rsr a3, excsave1 + l32i a0, a2, PT_AREG0 # restore a0 + xsr a2, depc # restore a2, depc + rsr a3, excsave1 - wsr a0, excsave1 - movi a0, unrecoverable_exception - callx0 a0 + wsr a0, excsave1 + movi a0, unrecoverable_exception + callx0 a0 ENDPROC(fast_syscall_unrecoverable) @@ -1253,9 +1253,9 @@ fast_syscall_spill_registers_fixup: movi a3, exc_table rsr a0, exccause - addx4 a0, a0, a3 # find entry in table - l32i a0, a0, EXC_TABLE_FAST_USER # load handler - jx a0 + addx4 a0, a0, a3 # find entry in table + l32i a0, a0, EXC_TABLE_FAST_USER # load handler + jx a0 fast_syscall_spill_registers_fixup_return: @@ -1457,7 +1457,7 @@ ENTRY(_spill_registers) rsr a0, ps _bbci.l a0, PS_UM_BIT, 1f - /* User space: Setup a dummy frame and kill application. + /* User space: Setup a dummy frame and kill application. * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer. */ diff --git a/arch/xtensa/kernel/module.c b/arch/xtensa/kernel/module.c index 451dda928c93..b715237bae61 100644 --- a/arch/xtensa/kernel/module.c +++ b/arch/xtensa/kernel/module.c @@ -53,7 +53,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, struct module *mod) { unsigned int i; - Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; + Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; Elf32_Sym *sym; unsigned char *location; uint32_t value; diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c index 97230e46cbe7..44bf21c3769a 100644 --- a/arch/xtensa/kernel/platform.c +++ b/arch/xtensa/kernel/platform.c @@ -44,4 +44,3 @@ _F(void, calibrate_ccount, (void), ccount_per_jiffy = 10 * (1000000UL/HZ); }); #endif - diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 1accf28da5f5..0dd5784416d3 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -108,7 +108,7 @@ void coprocessor_flush_all(struct thread_info *ti) void cpu_idle(void) { - local_irq_enable(); + local_irq_enable(); /* endless idle loop with no priority at all */ while (1) { diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 33eea4c16f12..61fb2e9e9035 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -154,7 +154,7 @@ int ptrace_setxregs(struct task_struct *child, void __user *uregs) coprocessor_flush_all(ti); coprocessor_release_all(ti); - ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0, + ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0, sizeof(xtregs_coprocessor_t)); #endif ret |= __copy_from_user(®s->xtregs_opt, &xtregs->opt, @@ -343,4 +343,3 @@ void do_syscall_trace_leave(struct pt_regs *regs) && (current->ptrace & PT_PTRACED)) do_syscall_trace(); } - diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 64d80e4b0bd4..24c1a57abb40 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -284,7 +284,7 @@ void __init init_arch(bp_tag_t *bp_start) /* Parse boot parameters */ - if (bp_start) + if (bp_start) parse_bootparam(bp_start); #ifdef CONFIG_OF @@ -460,7 +460,7 @@ void __init setup_arch(char **cmdline_p) initrd_is_mapped = mem_reserve(__pa(initrd_start), __pa(initrd_end), 0); initrd_below_start_ok = 1; - } else { + } else { initrd_start = 0; } #endif @@ -539,7 +539,7 @@ c_show(struct seq_file *f, void *slot) "core ID\t\t: " XCHAL_CORE_ID "\n" "build ID\t: 0x%x\n" "byte order\t: %s\n" - "cpu MHz\t\t: %lu.%02lu\n" + "cpu MHz\t\t: %lu.%02lu\n" "bogomips\t: %lu.%02lu\n", XCHAL_BUILD_UNIQUE_ID, XCHAL_HAVE_BE ? "big" : "little", @@ -681,4 +681,3 @@ const struct seq_operations cpuinfo_op = }; #endif /* CONFIG_PROC_FS */ - diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index 63c566f627bc..de34d6be91cd 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -212,7 +212,7 @@ restore_sigcontext(struct pt_regs *regs, struct rt_sigframe __user *frame) if (err) return err; - /* The signal handler may have used coprocessors in which + /* The signal handler may have used coprocessors in which * case they are still enabled. We disable them to force a * reloading of the original task's CP state by the lazy * context-switching mechanisms of CP exception handling. @@ -396,7 +396,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, */ /* Set up registers for signal handler */ - start_thread(regs, (unsigned long) ka->sa.sa_handler, + start_thread(regs, (unsigned long) ka->sa.sa_handler, (unsigned long) frame); /* Set up a stack frame for a call4 @@ -424,9 +424,9 @@ give_sigsegv: return -EFAULT; } -asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, +asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, - long a2, long a3, long a4, long a5, + long a2, long a3, long a4, long a5, struct pt_regs *regs) { return do_sigaltstack(uss, uoss, regs->areg[1]); diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index 5702065f472a..54fa8425cee2 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c @@ -52,4 +52,3 @@ asmlinkage long xtensa_fadvise64_64(int fd, int advice, { return sys_fadvise64_64(fd, offset, len, advice); } - diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 691a792b01d3..01e0111bf787 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -408,7 +408,8 @@ static inline void spill_registers(void) "wsr a13, sar\n\t" "wsr a14, ps\n\t" :: "a" (&a0), "a" (&ps) - : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", "memory"); + : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", + "memory"); } void show_trace(struct task_struct *task, unsigned long *sp) @@ -463,7 +464,7 @@ void show_stack(struct task_struct *task, unsigned long *sp) if (!sp) sp = stack_pointer(task); - stack = sp; + stack = sp; printk("\nStack: "); @@ -534,5 +535,3 @@ void die(const char * str, struct pt_regs * regs, long err) do_exit(err); } - - diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index 9365ee5064d3..68df35f66ce3 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S @@ -485,5 +485,3 @@ ENTRY_ALIGN64(_WindowUnderflow12) ENDPROC(_WindowUnderflow12) .text - - diff --git a/arch/xtensa/lib/checksum.S b/arch/xtensa/lib/checksum.S index 0470ca21a359..4eb573d2720e 100644 --- a/arch/xtensa/lib/checksum.S +++ b/arch/xtensa/lib/checksum.S @@ -41,10 +41,11 @@ .text ENTRY(csum_partial) - /* - * Experiments with Ethernet and SLIP connections show that buf - * is aligned on either a 2-byte or 4-byte boundary. - */ + + /* + * Experiments with Ethernet and SLIP connections show that buf + * is aligned on either a 2-byte or 4-byte boundary. + */ entry sp, 32 extui a5, a2, 0, 2 bnez a5, 8f /* branch if 2-byte aligned */ @@ -409,4 +410,3 @@ ENDPROC(csum_partial_copy_generic) retw .previous - diff --git a/arch/xtensa/lib/memcopy.S b/arch/xtensa/lib/memcopy.S index c48b80acb5f0..b1c219acabe7 100644 --- a/arch/xtensa/lib/memcopy.S +++ b/arch/xtensa/lib/memcopy.S @@ -210,8 +210,10 @@ memcpy: _beqz a4, .Ldone # avoid loading anything for zero-length copies # copy 16 bytes per iteration for word-aligned dst and unaligned src ssa8 a3 # set shift amount from byte offset -#define SIM_CHECKS_ALIGNMENT 1 /* set to 1 when running on ISS (simulator) with the - lint or ferret client, or 0 to save a few cycles */ + +/* set to 1 when running on ISS (simulator) with the + lint or ferret client, or 0 to save a few cycles */ +#define SIM_CHECKS_ALIGNMENT 1 #if XCHAL_UNALIGNED_LOAD_EXCEPTION || SIM_CHECKS_ALIGNMENT and a11, a3, a8 # save unalignment offset for below sub a3, a3, a11 # align a3 diff --git a/arch/xtensa/lib/pci-auto.c b/arch/xtensa/lib/pci-auto.c index a71733ae1193..34d05abbd921 100644 --- a/arch/xtensa/lib/pci-auto.c +++ b/arch/xtensa/lib/pci-auto.c @@ -241,8 +241,8 @@ int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus) unsigned char header_type; struct pci_dev *dev = &pciauto_dev; - pciauto_dev.bus = &pciauto_bus; - pciauto_dev.sysdata = pci_ctrl; + pciauto_dev.bus = &pciauto_bus; + pciauto_dev.sysdata = pci_ctrl; pciauto_bus.ops = pci_ctrl->ops; /* @@ -345,8 +345,3 @@ int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus) } return sub_bus; } - - - - - diff --git a/arch/xtensa/lib/strncpy_user.S b/arch/xtensa/lib/strncpy_user.S index 9f603cdaaa68..1ad0ecf45368 100644 --- a/arch/xtensa/lib/strncpy_user.S +++ b/arch/xtensa/lib/strncpy_user.S @@ -166,7 +166,7 @@ __strncpy_user: retw .Lz1: # byte 1 is zero #ifdef __XTENSA_EB__ - extui a9, a9, 16, 16 + extui a9, a9, 16, 16 #endif /* __XTENSA_EB__ */ EX(s16i, a9, a11, 0, fixup_s) addi a11, a11, 1 # advance dst pointer @@ -174,7 +174,7 @@ __strncpy_user: retw .Lz2: # byte 2 is zero #ifdef __XTENSA_EB__ - extui a9, a9, 16, 16 + extui a9, a9, 16, 16 #endif /* __XTENSA_EB__ */ EX(s16i, a9, a11, 0, fixup_s) movi a9, 0 diff --git a/arch/xtensa/lib/strnlen_user.S b/arch/xtensa/lib/strnlen_user.S index 23f2a89816a1..4c03b1e581e9 100644 --- a/arch/xtensa/lib/strnlen_user.S +++ b/arch/xtensa/lib/strnlen_user.S @@ -145,4 +145,3 @@ __strnlen_user: lenfixup: movi a2, 0 retw - diff --git a/arch/xtensa/lib/usercopy.S b/arch/xtensa/lib/usercopy.S index 46d60314bb16..ace1892a875e 100644 --- a/arch/xtensa/lib/usercopy.S +++ b/arch/xtensa/lib/usercopy.S @@ -318,4 +318,3 @@ l_fixup: /* Ignore memset return value in a6. */ /* a2 still contains bytes not copied. */ retw - diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c index 85df4655d326..81edeab82d17 100644 --- a/arch/xtensa/mm/cache.c +++ b/arch/xtensa/mm/cache.c @@ -118,7 +118,7 @@ void flush_dcache_page(struct page *page) * For now, flush the whole cache. FIXME?? */ -void flush_cache_range(struct vm_area_struct* vma, +void flush_cache_range(struct vm_area_struct* vma, unsigned long start, unsigned long end) { __flush_invalidate_dcache_all(); @@ -133,7 +133,7 @@ void flush_cache_range(struct vm_area_struct* vma, */ void flush_cache_page(struct vm_area_struct* vma, unsigned long address, - unsigned long pfn) + unsigned long pfn) { /* Note that we have to use the 'alias' address to avoid multi-hit */ @@ -166,14 +166,14 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) { - unsigned long vaddr = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); unsigned long paddr = (unsigned long) page_address(page); unsigned long phys = page_to_phys(page); + unsigned long tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); __flush_invalidate_dcache_page(paddr); - __flush_invalidate_dcache_page_alias(vaddr, phys); - __invalidate_icache_page_alias(vaddr, phys); + __flush_invalidate_dcache_page_alias(tmp, phys); + __invalidate_icache_page_alias(tmp, phys); clear_bit(PG_arch_1, &page->flags); } @@ -195,7 +195,7 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK -void copy_to_user_page(struct vm_area_struct *vma, struct page *page, +void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len) { @@ -205,8 +205,8 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, /* Flush and invalidate user page if aliased. */ if (alias) { - unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); - __flush_invalidate_dcache_page_alias(temp, phys); + unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); + __flush_invalidate_dcache_page_alias(t, phys); } /* Copy data */ @@ -219,12 +219,11 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, */ if (alias) { - unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); + unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); __flush_invalidate_dcache_range((unsigned long) dst, len); - if ((vma->vm_flags & VM_EXEC) != 0) { - __invalidate_icache_page_alias(temp, phys); - } + if ((vma->vm_flags & VM_EXEC) != 0) + __invalidate_icache_page_alias(t, phys); } else if ((vma->vm_flags & VM_EXEC) != 0) { __flush_dcache_range((unsigned long)dst,len); @@ -245,8 +244,8 @@ extern void copy_from_user_page(struct vm_area_struct *vma, struct page *page, */ if (alias) { - unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); - __flush_invalidate_dcache_page_alias(temp, phys); + unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); + __flush_invalidate_dcache_page_alias(t, phys); } memcpy(dst, src, len); diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c index 245b08f7eaf4..4b7bc8db170f 100644 --- a/arch/xtensa/mm/fault.c +++ b/arch/xtensa/mm/fault.c @@ -254,4 +254,3 @@ bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) die("Oops", regs, sig); do_exit(sig); } - diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index db955179da2d..7a5156ffebb6 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -75,15 +75,15 @@ int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) sysmem.nr_banks++; } sysmem.bank[i].end = start; + + } else if (end < sysmem.bank[i].end) { + sysmem.bank[i].start = end; + } else { - if (end < sysmem.bank[i].end) - sysmem.bank[i].start = end; - else { - /* remove entry */ - sysmem.nr_banks--; - sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start; - sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end; - } + /* remove entry */ + sysmem.nr_banks--; + sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start; + sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end; } return -1; } diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S index 7f7078f57c41..d97ed1ba7b0a 100644 --- a/arch/xtensa/mm/misc.S +++ b/arch/xtensa/mm/misc.S @@ -180,7 +180,7 @@ ENDPROC(clear_user_page) ENTRY(copy_user_page) - entry a1, 32 + entry a1, 32 /* Mark page dirty and determine alias for destination. */ diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c index 070fb7a25231..5411aa67c68e 100644 --- a/arch/xtensa/mm/tlb.c +++ b/arch/xtensa/mm/tlb.c @@ -82,7 +82,7 @@ void flush_tlb_mm(struct mm_struct *mm) #endif void flush_tlb_range (struct vm_area_struct *vma, - unsigned long start, unsigned long end) + unsigned long start, unsigned long end) { struct mm_struct *mm = vma->vm_mm; unsigned long flags; @@ -100,7 +100,7 @@ void flush_tlb_range (struct vm_area_struct *vma, int oldpid = get_rasid_register(); set_rasid_register (ASID_INSERT(mm->context)); start &= PAGE_MASK; - if (vma->vm_flags & VM_EXEC) + if (vma->vm_flags & VM_EXEC) while(start < end) { invalidate_itlb_mapping(start); invalidate_dtlb_mapping(start); @@ -130,7 +130,7 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page) local_save_flags(flags); - oldpid = get_rasid_register(); + oldpid = get_rasid_register(); if (vma->vm_flags & VM_EXEC) invalidate_itlb_mapping(page); @@ -140,4 +140,3 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page) local_irq_restore(flags); } - -- cgit v1.2.1 From 33c760fbb7a8fa46314437746dd7f5540da5498e Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Wed, 28 Nov 2012 16:52:09 -0800 Subject: xtensa: set the correct ethernet address for xtfpga The last byte of the mac address is determined by a DIP switch, so update the OF property with that address. Signed-off-by: Chris Zankel --- arch/xtensa/platforms/xtfpga/setup.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c index 237c36dc18b8..4b9951a4569d 100644 --- a/arch/xtensa/platforms/xtfpga/setup.c +++ b/arch/xtensa/platforms/xtfpga/setup.c @@ -32,6 +32,7 @@ #include #include #include +#include void platform_halt(void) { @@ -84,8 +85,7 @@ static void __init update_clock_frequency(struct device_node *node) struct property *newfreq; u32 freq; - if (!of_property_read_u32(node, "clock-frequency", &freq) && - freq != 0) + if (!of_property_read_u32(node, "clock-frequency", &freq) && freq != 0) return; newfreq = kzalloc(sizeof(*newfreq) + sizeof(u32), GFP_KERNEL); @@ -103,12 +103,44 @@ static void __init update_clock_frequency(struct device_node *node) prom_update_property(node, newfreq); } +#define MAC_LEN 6 +static void __init update_local_mac(struct device_node *node) +{ + struct property *newmac; + const u8* macaddr; + int prop_len; + + macaddr = of_get_property(node, "local-mac-address", &prop_len); + if (macaddr == NULL || prop_len != MAC_LEN) + return; + + newmac = kzalloc(sizeof(*newmac) + MAC_LEN, GFP_KERNEL); + if (newmac == NULL) + return; + + newmac->value = newmac + 1; + newmac->length = MAC_LEN; + newmac->name = kstrdup("local-mac-address", GFP_KERNEL); + if (newmac->name == NULL) { + kfree(newmac); + return; + } + + memcpy(newmac->value, macaddr, MAC_LEN); + ((u8*)newmac->value)[5] = (*(u32*)DIP_SWITCHES_VADDR) & 0x3f; + prom_update_property(node, newmac); +} + static int __init machine_setup(void) { struct device_node *serial; + struct device_node *eth = NULL; for_each_compatible_node(serial, NULL, "ns16550a") update_clock_frequency(serial); + + if ((eth = of_find_compatible_node(eth, NULL, "opencores,ethoc"))) + update_local_mac(eth); return 0; } arch_initcall(machine_setup); -- cgit v1.2.1 From 055d4db1e1ef6f983c3565110fbe6737087e9103 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 11 Dec 2012 01:26:21 +0400 Subject: xtensa: don't try to build DTB when OF is disabled Signed-off-by: Max Filippov Signed-off-by: Chris Zankel --- arch/xtensa/Makefile | 2 +- arch/xtensa/boot/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 4276721f5ae1..0aa72702f179 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -88,7 +88,7 @@ core-y += $(buildvar) $(buildplf) libs-y += arch/xtensa/lib/ $(LIBGCC) ifneq ($(CONFIG_BUILTIN_DTB),"") -core-y += arch/xtensa/boot/ +core-$(CONFIG_OF) += arch/xtensa/boot/ endif boot := arch/xtensa/boot diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index 196bc3c967af..818647e815d7 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile @@ -28,7 +28,7 @@ bootdir-$(CONFIG_XTENSA_PLATFORM_XTFPGA) += boot-redboot boot-elf boot-uboot BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o ifneq ($(CONFIG_BUILTIN_DTB),"") -obj-y += $(BUILTIN_DTB) +obj-$(CONFIG_OF) += $(BUILTIN_DTB) endif # Rule to build device tree blobs -- cgit v1.2.1