Skip to contentSkip to conversation

xtensa queue 2013/08/30

PATCH New Max Filippov 1 participant 12 messages Aug 30, 2013

Subsystems (3)
lore
Share & tools
lore

Max Filippov

author maintainer
#0 lore raw

v2 cover xtensa queue 2013/08/30

Hi Chris,

this is my current patch queue for xtensa, it is based on your for_next branch.
There are fixes for the current issues:
- missing #include <asm/ftrace.h> that fixes build with enabled support for modules and tracing;
- fix for build warning on 64bit hosts;
- echo doesn't need -e, which breaks big endian variants build when the shell is dash;
- TIF_* flags are now checked atomically, and hardirqs tracing call is moved after possible rescheduling point;
- provide ccount_freq definition regardless of CONFIG_XTENSA_CALIBRATE_CCOUNT which fixes build with CONFIG_XTENSA_CALIBRATE_CCOUNT disabled;
- replace CCOUNT_PER_JIFFY with ccount_freq and simplify resulting expressions; remove CCOUNT_PER_JIFFY definition.
There's a patch that enables kernel preemption.
The rest are prerequisites and fixes for SMP:
- spinlock functions are renamed according to current kernel naming scheme, asm/spinlock_types.h is provided;
- exception handlers now get a3 and excsave reversed, exc_table reloads in entry.S are eliminated. This patch is ported from 2.6.29-smp;
- new fast_alloca handler is ported from 2.6.29-smp;
- __delay is fixed for small delays, which in turn fixes SMP kernel hangs with CONFIG_DEBUG_SPINLOCK enabled.

You can pull these changes from my git tree,
the following changes since commit 3b2f64d00c46e1e4e9bd0bb9bb12619adac27a4b:

Linux 3.11-rc2 (2013-07-21 12:05:29 -0700)

are available in the git repository at:
git://github.com/jcmvbkbc/linux-xtensa.git xtensa-fixes-for-upstream

Changes v1->v2:
- make __delay fix more explicit for constant delays less than 2;
- remove unneeded call to trace_hardirqs_off from TIF_* checking patch;
- add timer-related patches from Baruch Siach.

Baruch Siach (2):
xtensa: fix !CONFIG_XTENSA_CALIBRATE_CCOUNT build failure
xtensa: remove CCOUNT_PER_JIFFY

Chen Gang (1):
xtensa: kernel: add "asm/ftrace.h" for pass compiling

Max Filippov (8):
xtensa: fix arch spinlock function names
xtensa: fix __delay for small loop count
xtensa: fix build warning
xtensa: check thread flags atomically on return from user exception
xtensa: enable kernel preemption
xtensa: keep a3 and excsave1 on entry to exception handlers
xtensa: new fast_alloca handler
xtensa: don't use echo -e needlessly

 arch/xtensa/Makefile                     |    4 +-
 arch/xtensa/boot/Makefile                |    2 +-
 arch/xtensa/include/asm/delay.h          |    9 +-
 arch/xtensa/include/asm/regs.h           |    1 +
 arch/xtensa/include/asm/spinlock.h       |   31 ++-
 arch/xtensa/include/asm/spinlock_types.h |   20 ++
 arch/xtensa/include/asm/timex.h          |    6 -
 arch/xtensa/kernel/align.S               |    5 +-
 arch/xtensa/kernel/coprocessor.S         |    9 +-
 arch/xtensa/kernel/entry.S               |  387 ++++++++++--------------------
 arch/xtensa/kernel/setup.c               |    4 +-
 arch/xtensa/kernel/time.c                |    8 +-
 arch/xtensa/kernel/vectors.S             |  250 ++++++++++++++-----
 arch/xtensa/kernel/xtensa_ksyms.c        |    3 +
 arch/xtensa/mm/misc.S                    |    4 +-
 15 files changed, 371 insertions(+), 372 deletions(-)
 create mode 100644 arch/xtensa/include/asm/spinlock_types.h
Signature · 1 line
1.7.7.6
author maintainer
#1 lore raw

PATCH v2 1/11 xtensa: kernel: add "asm/ftrace.h" for pass compiling

From: Chen Gang <[email protected]>

Need add "asm/ftrace.h" for pass compiling.

Cross-compiler is compiled from binutils-2.23.2 and gcc-4.9.0 source.

The related error (with allmodconfig for fsf processor):

arch/xtensa/kernel/xtensa_ksyms.c:129:15: error: '_mcount' undeclared here (not in a function)

---
 arch/xtensa/kernel/xtensa_ksyms.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
arch/xtensa/kernel/xtensa_ksyms.c +3 -0
index d8507f8..316f008 100644
@@ -32,6 +32,9 @@
 #include <net/checksum.h>
 #endif /* CONFIG_NET */
 
+#ifdef CONFIG_FUNCTION_TRACER
+#include <asm/ftrace.h>
+#endif /* CONFIG_FUNCTION_TRACER */
 
 /*
  * String functions
Signature · 1 line
1.7.7.6
author maintainer
#2 lore raw

PATCH v2 2/11 xtensa: fix arch spinlock function names

In reply to Max Filippov
---
 arch/xtensa/include/asm/spinlock.h       |   31 ++++++++++++++++-------------
 arch/xtensa/include/asm/spinlock_types.h |   20 +++++++++++++++++++
 2 files changed, 37 insertions(+), 14 deletions(-)
 create mode 100644 arch/xtensa/include/asm/spinlock_types.h
arch/xtensa/include/asm/spinlock.h +17 -14
index 0397590..1d95fa5 100644
@@ -28,13 +28,13 @@
  *    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 arch_spin_is_locked(x) ((x)->slock != 0)
+#define arch_spin_unlock_wait(lock) \
+	do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
 
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
 
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
 {
 	unsigned long tmp;
 
@@ -51,7 +51,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
 
 /* Returns 1 if the lock is obtained, 0 otherwise. */
 
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
 {
 	unsigned long tmp;
 
@@ -67,7 +67,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock)
 	return tmp == 0 ? 1 : 0;
 }
 
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
 {
 	unsigned long tmp;
 
@@ -96,9 +96,9 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock)
  *  0x80000000  one writer owns the rwlock, no other writers, no readers
  */
 
-#define __raw_write_can_lock(x)  ((x)->lock == 0)
+#define arch_write_can_lock(x)  ((x)->lock == 0)
 
-static inline void __raw_write_lock(raw_rwlock_t *rw)
+static inline void arch_write_lock(arch_rwlock_t *rw)
 {
 	unsigned long tmp;
 
@@ -116,7 +116,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
 
 /* Returns 1 if the lock is obtained, 0 otherwise. */
 
-static inline int __raw_write_trylock(raw_rwlock_t *rw)
+static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	unsigned long tmp;
 
@@ -133,7 +133,7 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
 	return tmp == 0 ? 1 : 0;
 }
 
-static inline void __raw_write_unlock(raw_rwlock_t *rw)
+static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
 	unsigned long tmp;
 
@@ -145,7 +145,7 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw)
 			: "memory");
 }
 
-static inline void __raw_read_lock(raw_rwlock_t *rw)
+static inline void arch_read_lock(arch_rwlock_t *rw)
 {
 	unsigned long tmp;
 	unsigned long result;
@@ -164,7 +164,7 @@ static inline void __raw_read_lock(raw_rwlock_t *rw)
 
 /* Returns 1 if the lock is obtained, 0 otherwise. */
 
-static inline int __raw_read_trylock(raw_rwlock_t *rw)
+static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
 	unsigned long result;
 	unsigned long tmp;
@@ -184,7 +184,7 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw)
 	return result == 0;
 }
 
-static inline void __raw_read_unlock(raw_rwlock_t *rw)
+static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
 	unsigned long tmp1, tmp2;
 
@@ -199,4 +199,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw)
 			: "memory");
 }
 
+#define arch_read_lock_flags(lock, flags)	arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags)	arch_write_lock(lock)
+
 #endif	/* _XTENSA_SPINLOCK_H */
arch/xtensa/include/asm/spinlock_types.h new file +20 -0
new file mode 100644
index 0000000..7ec5ce1
@@ -0,0 +1,20 @@
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+	volatile unsigned int slock;
+} arch_spinlock_t;
+
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
+
+typedef struct {
+	volatile unsigned int lock;
+} arch_rwlock_t;
+
+#define __ARCH_RW_LOCK_UNLOCKED		{ 0 }
+
+#endif
Signature · 1 line
1.7.7.6
author maintainer
#3 lore raw

PATCH v2 3/11 xtensa: fix __delay for small loop count

In reply to Max Filippov

Avoid __delay counter underflow for loop counts < 2.

---
Changes v1->v2:
- make __delay fix more explicit for constant delays less than 2;

 arch/xtensa/include/asm/delay.h |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)
arch/xtensa/include/asm/delay.h +6 -3
index 3899610..742b89f 100644
@@ -19,9 +19,12 @@ 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));
+	if (__builtin_constant_p(loops) && loops < 2)
+		__asm__ __volatile__ ("nop");
+	else if (loops >= 2)
+		/* 2 cycles per loop. */
+		__asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b"
+				: "+r" (loops));
 }
 
 /* For SMP/NUMA systems, change boot_cpu_data to something like
Signature · 1 line
1.7.7.6
author maintainer
#4 lore raw

PATCH v2 4/11 xtensa: fix build warning

In reply to Max Filippov

This fixes the following build warnings:

arch/xtensa/mm/misc.S: Assembler messages:
arch/xtensa/mm/misc.S:143: Warning: value 0xffffffff30000106 truncated to 0x30000106 arch/xtensa/mm/misc.S:197: Warning: value 0xffffffff30000106 truncated to 0x30000106

---
 arch/xtensa/mm/misc.S |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
arch/xtensa/mm/misc.S +2 -2
index d97ed1b..1f68558 100644
@@ -140,7 +140,7 @@ ENTRY(clear_user_page)
 
 	/* Setup a temporary DTLB with the color of the VPN */
 
-	movi	a4, -PAGE_OFFSET + (PAGE_KERNEL | _PAGE_HW_WRITE)
+	movi	a4, ((PAGE_KERNEL | _PAGE_HW_WRITE) - PAGE_OFFSET) & 0xffffffff
 	movi	a5, TLBTEMP_BASE_1			# virt
 	add	a6, a2, a4				# ppn
 	add	a2, a5, a3				# add 'color'
@@ -194,7 +194,7 @@ ENTRY(copy_user_page)
 	or	a9, a9, a8
 	slli	a4, a4, PAGE_SHIFT
 	s32i	a9, a5, PAGE_FLAGS
-	movi	a5, -PAGE_OFFSET + (PAGE_KERNEL | _PAGE_HW_WRITE)
+	movi	a5, ((PAGE_KERNEL | _PAGE_HW_WRITE) - PAGE_OFFSET) & 0xffffffff
 
 	beqz	a6, 1f
 
Signature · 1 line
1.7.7.6
author maintainer
#5 lore raw

PATCH v2 5/11 xtensa: check thread flags atomically on return from user exception

In reply to Max Filippov

Check pending signals and rescheduling thread flags with interrupts disabled, and don't enable them if no flags are set. Call trace_hardirqs_on after thread flags handling, so that rescheduling is done and hardirqs tracking flag is updated in the correct task context.

---
Changes v1->v2:
- remove unneeded call to trace_hardirqs_off from the loop after rsil a2, LOCKLEVEL

 arch/xtensa/kernel/entry.S |   39 +++++++++++++++++++++------------------
 1 files changed, 21 insertions(+), 18 deletions(-)
arch/xtensa/kernel/entry.S +21 -18
index 9298742..03709ef 100644
@@ -423,29 +423,14 @@ common_exception:
 	.global common_exception_return
 common_exception_return:
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-	l32i	a4, a1, PT_DEPC
-	/* Double exception means we came here with an exception
-	 * while PS.EXCM was set, i.e. interrupts disabled.
-	 */
-	bgeui	a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
-	l32i	a4, a1, PT_EXCCAUSE
-	bnei	a4, EXCCAUSE_LEVEL1_INTERRUPT, 1f
-	/* We came here with an interrupt means interrupts were enabled
-	 * and we'll reenable them on return.
-	 */
-	movi	a4, trace_hardirqs_on
-	callx4	a4
 1:
-#endif
+	rsil	a2, LOCKLEVEL
 
 	/* Jump if we are returning from kernel exceptions. */
 
-1:	l32i	a3, a1, PT_PS
+	l32i	a3, a1, PT_PS
 	_bbci.l	a3, PS_UM_BIT, 4f
 
-	rsil	a2, 0
-
 	/* Specific to a user exception exit:
 	 * We need to check some flags for signal handling and rescheduling,
 	 * and have to restore WB and WS, extra states, and all registers
@@ -465,6 +450,7 @@ common_exception_return:
 
 	/* Call do_signal() */
 
+	rsil	a2, 0
 	movi	a4, do_notify_resume	# int do_notify_resume(struct pt_regs*)
 	mov	a6, a1
 	callx4	a4
@@ -472,6 +458,7 @@ common_exception_return:
 
 3:	/* Reschedule */
 
+	rsil	a2, 0
 	movi	a4, schedule	# void schedule (void)
 	callx4	a4
 	j	1b
@@ -483,7 +470,23 @@ common_exception_return:
 	movi	a4, check_tlb_sanity
 	callx4	a4
 #endif
-4:	/* Restore optional registers. */
+4:
+#ifdef CONFIG_TRACE_IRQFLAGS
+	l32i	a4, a1, PT_DEPC
+	/* Double exception means we came here with an exception
+	 * while PS.EXCM was set, i.e. interrupts disabled.
+	 */
+	bgeui	a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
+	l32i	a4, a1, PT_EXCCAUSE
+	bnei	a4, EXCCAUSE_LEVEL1_INTERRUPT, 1f
+	/* We came here with an interrupt means interrupts were enabled
+	 * and we'll reenable them on return.
+	 */
+	movi	a4, trace_hardirqs_on
+	callx4	a4
+1:
+#endif
+	/* Restore optional registers. */
 
 	load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
 
Signature · 1 line
1.7.7.6
author maintainer
#6 lore raw

PATCH v2 6/11 xtensa: enable kernel preemption

In reply to Max Filippov
---
 arch/xtensa/kernel/entry.S |   45 ++++++++++++++++---------------------------
 1 files changed, 17 insertions(+), 28 deletions(-)
arch/xtensa/kernel/entry.S +17 -28
index 03709ef..3f3de28 100644
@@ -31,7 +31,6 @@
 /* Unimplemented features. */
 
 #undef KERNEL_STACK_OVERFLOW_CHECK
-#undef PREEMPTIBLE_KERNEL
 #undef ALLOCA_EXCEPTION_IN_IRAM
 
 /* Not well tested.
@@ -429,7 +428,9 @@ common_exception_return:
 	/* Jump if we are returning from kernel exceptions. */
 
 	l32i	a3, a1, PT_PS
-	_bbci.l	a3, PS_UM_BIT, 4f
+	GET_THREAD_INFO(a2, a1)
+	l32i	a4, a2, TI_FLAGS
+	_bbci.l	a3, PS_UM_BIT, 6f
 
 	/* Specific to a user exception exit:
 	 * We need to check some flags for signal handling and rescheduling,
@@ -438,9 +439,6 @@ common_exception_return:
 	 * Note that we don't disable interrupts here. 
 	 */
 
-	GET_THREAD_INFO(a2,a1)
-	l32i	a4, a2, TI_FLAGS
-
 	_bbsi.l	a4, TIF_NEED_RESCHED, 3f
 	_bbsi.l	a4, TIF_NOTIFY_RESUME, 2f
 	_bbci.l	a4, TIF_SIGPENDING, 5f
@@ -463,6 +461,19 @@ common_exception_return:
 	callx4	a4
 	j	1b
 
+#ifdef CONFIG_PREEMPT
+6:
+	_bbci.l	a4, TIF_NEED_RESCHED, 4f
+
+	/* Check current_thread_info->preempt_count */
+
+	l32i	a4, a2, TI_PRE_COUNT
+	bnez	a4, 4f
+	movi	a4, preempt_schedule_irq
+	callx4	a4
+	j	1b
+#endif
+
 5:
 #ifdef CONFIG_DEBUG_TLB_SANITY
 	l32i	a4, a1, PT_DEPC
@@ -470,6 +481,7 @@ common_exception_return:
 	movi	a4, check_tlb_sanity
 	callx4	a4
 #endif
+6:
 4:
 #ifdef CONFIG_TRACE_IRQFLAGS
 	l32i	a4, a1, PT_DEPC
@@ -573,29 +585,6 @@ user_exception_exit:
 
 kernel_exception_exit:
 
-#ifdef PREEMPTIBLE_KERNEL
-
-#ifdef CONFIG_PREEMPT
-
-	/*
-	 * Note: We've just returned from a call4, so we have
-	 * at least 4 addt'l regs.
-	 */
-
-	/* Check current_thread_info->preempt_count */
-
-	GET_THREAD_INFO(a2)
-	l32i	a3, a2, TI_PREEMPT
-	bnez	a3, 1f
-
-	l32i	a2, a2, TI_FLAGS
-
-1:
-
-#endif
-
-#endif
-
 	/* Check if we have to do a movsp.
 	 *
 	 * We only have to do a movsp if the previous window-frame has
Signature · 1 line
1.7.7.6
author maintainer
#7 lore raw

PATCH v2 7/11 xtensa: keep a3 and excsave1 on entry to exception handlers

In reply to Max Filippov

Based on the SMP patch by Joe Taylor and subsequent fixes. Preserve exception table pointer (normally stored in excsave1 SR) as it cannot be easily restored in SMP environment.

---
 arch/xtensa/include/asm/regs.h   |    1 +
 arch/xtensa/kernel/align.S       |    5 +-
 arch/xtensa/kernel/coprocessor.S |    9 +-
 arch/xtensa/kernel/entry.S       |  115 +++++++----------
 arch/xtensa/kernel/vectors.S     |  250 ++++++++++++++++++++++++++++----------
 5 files changed, 238 insertions(+), 142 deletions(-)
arch/xtensa/include/asm/regs.h +1 -0
index b24de67..4ba9f51 100644
@@ -82,6 +82,7 @@
 #define PS_CALLINC_SHIFT	16
 #define PS_CALLINC_MASK		0x00030000
 #define PS_OWB_SHIFT		8
+#define PS_OWB_WIDTH		4
 #define PS_OWB_MASK		0x00000F00
 #define PS_RING_SHIFT		6
 #define PS_RING_MASK		0x000000C0
arch/xtensa/kernel/align.S +2 -3
index aa2e87b..d4cef60 100644
@@ -146,9 +146,9 @@
  *   a0:	trashed, original value saved on stack (PT_AREG0)
  *   a1:	a1
  *   a2:	new stack pointer, original in DEPC
- *   a3:	dispatch table
+ *   a3:	a3
  *   depc:	a2, original value saved on stack (PT_DEPC)
- *   excsave_1:	a3
+ *   excsave_1:	dispatch table
  *
  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
  *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
@@ -171,7 +171,6 @@ ENTRY(fast_unaligned)
 	s32i	a8, a2, PT_AREG8
 
 	rsr	a0, depc
-	xsr	a3, excsave1
 	s32i	a0, a2, PT_AREG2
 	s32i	a3, a2, PT_AREG3
 
arch/xtensa/kernel/coprocessor.S +4 -5
index 6476574..a482df5 100644
@@ -32,9 +32,9 @@
  *   a0:	trashed, original value saved on stack (PT_AREG0)
  *   a1:	a1
  *   a2:	new stack pointer, original in DEPC
- *   a3:	dispatch table
+ *   a3:	a3
  *   depc:	a2, original value saved on stack (PT_DEPC)
- *   excsave_1:	a3
+ *   excsave_1:	dispatch table
  *
  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
  *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
@@ -225,9 +225,9 @@ ENDPROC(coprocessor_restore)
  *   a0:	trashed, original value saved on stack (PT_AREG0)
  *   a1:	a1
  *   a2:	new stack pointer, original in DEPC
- *   a3:	dispatch table
+ *   a3:	a3
  *   depc:	a2, original value saved on stack (PT_DEPC)
- *   excsave_1:	a3
+ *   excsave_1:	dispatch table
  *
  *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
  *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
@@ -245,7 +245,6 @@ ENTRY(fast_coprocessor)
 
 	/* Save remaining registers a1-a3 and SAR */
 
-	xsr	a3, excsave1
 	s32i	a3, a2, PT_AREG3
 	rsr	a3, sar
 	s32i	a1, a2, PT_AREG1
arch/xtensa/kernel/entry.S +47 -68

351 lines not on this page · raw message

arch/xtensa/kernel/vectors.S +184 -66

346 lines not on this page · raw message

Signature · 1 line
1.7.7.6
author maintainer
#8 lore raw

PATCH v2 8/11 xtensa: new fast_alloca handler

In reply to Max Filippov

Instead of emulating movsp instruction in the kernel use window underflow handler to load missing register window and retry failed movsp.

---
 arch/xtensa/kernel/entry.S |  192 +++++++++----------------------------------
 1 files changed, 40 insertions(+), 152 deletions(-)
arch/xtensa/kernel/entry.S +40 -152
index ab025c1..de1dfa1 100644
@@ -31,7 +31,6 @@
 /* Unimplemented features. */
 
 #undef KERNEL_STACK_OVERFLOW_CHECK
-#undef ALLOCA_EXCEPTION_IN_IRAM
 
 /* Not well tested.
  *
@@ -819,11 +818,27 @@ ENDPROC(unrecoverable_exception)
  *
  *  The ALLOCA handler is entered when user code executes the MOVSP
  *  instruction and the caller's frame is not in the register file.
- *  In this case, the caller frame's a0..a3 are on the stack just
- *  below sp (a1), and this handler moves them.
  *
- *  For "MOVSP <ar>,<as>" without destination register a1, this routine
- *  simply moves the value from <as> to <ar> without moving the save area.
+ * This algorithm was taken from the Ross Morley's RTOS Porting Layer:
+ *
+ *    /home/ross/rtos/porting/XtensaRTOS-PortingLayer-20090507/xtensa_vectors.S
+ *
+ * It leverages the existing window spill/fill routines and their support for
+ * double exceptions. The 'movsp' instruction will only cause an exception if
+ * the next window needs to be loaded. In fact this ALLOCA exception may be
+ * replaced at some point by changing the hardware to do a underflow exception
+ * of the proper size instead.
+ *
+ * This algorithm simply backs out the register changes started by the user
+ * excpetion handler, makes it appear that we have started a window underflow
+ * by rotating the window back and then setting the old window base (OWB) in
+ * the 'ps' register with the rolled back window base. The 'movsp' instruction
+ * will be re-executed and this time since the next window frames is in the
+ * active AR registers it won't cause an exception.
+ *
+ * If the WindowUnderflow code gets a TLB miss the page will get mapped
+ * the the partial windeowUnderflow will be handeled in the double exception
+ * handler.
  *
  * Entry condition:
  *
@@ -838,155 +853,28 @@ ENDPROC(unrecoverable_exception)
  *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
  */
 
-#if XCHAL_HAVE_BE
-#define _EXTUI_MOVSP_SRC(ar)	extui ar, ar, 4, 4
-#define _EXTUI_MOVSP_DST(ar)	extui ar, ar, 0, 4
-#else
-#define _EXTUI_MOVSP_SRC(ar)	extui ar, ar, 0, 4
-#define _EXTUI_MOVSP_DST(ar)	extui ar, ar, 4, 4
-#endif
-
 ENTRY(fast_alloca)
+	rsr	a0, windowbase
+	rotw	-1
+	rsr	a2, ps
+	extui	a3, a2, PS_OWB_SHIFT, PS_OWB_WIDTH
+	xor	a3, a3, a4
+	l32i	a4, a6, PT_AREG0
+	l32i	a1, a6, PT_DEPC
+	rsr	a6, depc
+	wsr	a1, depc
+	slli	a3, a3, PS_OWB_SHIFT
+	xor	a2, a2, a3
+	wsr	a2, ps
+	rsync
 
-	/* We shouldn't be in a double exception. */
-
-	l32i	a0, a2, PT_DEPC
-	_bgeui	a0, VALID_DOUBLE_EXCEPTION_ADDRESS, .Lunhandled_double
-
-	rsr	a0, depc		# get a2
-	s32i	a4, a2, PT_AREG4	# save a4 and
-	s32i	a3, a2, PT_AREG3
-	s32i	a0, a2, PT_AREG2	# a2 to stack
-
-	/* Exit critical section. */
-
-	movi	a0, 0
-	rsr	a3, excsave1
-	s32i	a0, a3, EXC_TABLE_FIXUP
-
-	rsr	a4, epc1		# get exception address
-
-#ifdef ALLOCA_EXCEPTION_IN_IRAM
-#error	iram not supported
-#else
-	/* Note: l8ui not allowed in IRAM/IROM!! */
-	l8ui	a0, a4, 1		# read as(src) from MOVSP instruction
-#endif
-	movi	a3, .Lmovsp_src
-	_EXTUI_MOVSP_SRC(a0)		# extract source register number
-	addx8	a3, a0, a3
-	jx	a3
-
-.Lunhandled_double:
-	wsr	a0, excsave1
-	movi	a0, unrecoverable_exception
-	callx0	a0
-
-	.align 8
-.Lmovsp_src:
-	l32i	a3, a2, PT_AREG0;	_j 1f;	.align 8
-	mov	a3, a1;			_j 1f;	.align 8
-	l32i	a3, a2, PT_AREG2;	_j 1f;	.align 8
-	l32i	a3, a2, PT_AREG3;	_j 1f;	.align 8
-	l32i	a3, a2, PT_AREG4;	_j 1f;	.align 8
-	mov	a3, a5;			_j 1f;	.align 8
-	mov	a3, a6;			_j 1f;	.align 8
-	mov	a3, a7;			_j 1f;	.align 8
-	mov	a3, a8;			_j 1f;	.align 8
-	mov	a3, a9;			_j 1f;	.align 8
-	mov	a3, a10;		_j 1f;	.align 8
-	mov	a3, a11;		_j 1f;	.align 8
-	mov	a3, a12;		_j 1f;	.align 8
-	mov	a3, a13;		_j 1f;	.align 8
-	mov	a3, a14;		_j 1f;	.align 8
-	mov	a3, a15;		_j 1f;	.align 8
-
-1:
-
-#ifdef ALLOCA_EXCEPTION_IN_IRAM
-#error	iram not supported
-#else
-	l8ui	a0, a4, 0		# read ar(dst) from MOVSP instruction
-#endif
-	addi	a4, a4, 3		# step over movsp
-	_EXTUI_MOVSP_DST(a0)		# extract destination register
-	wsr	a4, epc1		# save new epc_1
-
-	_bnei	a0, 1, 1f		# no 'movsp a1, ax': jump
-
-	/* 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
-	 * set. Note that we have stil registered a fixup routine with the
-	 * double exception vector in case a double exception occurs.
-	 */
-
-	/* a0,a4:avail a1:old user stack a2:exc. stack a3:new user stack. */
-
-	l32e	a0, a1, -16
-	l32e	a4, a1, -12
-	s32e	a0, a3, -16
-	s32e	a4, a3, -12
-	l32e	a0, a1, -8
-	l32e	a4, a1, -4
-	s32e	a0, a3, -8
-	s32e	a4, a3, -4
-
-	/* Restore stack-pointer and all the other saved registers. */
-
-	mov	a1, a3
-
-	l32i	a4, a2, PT_AREG4
-	l32i	a3, a2, PT_AREG3
-	l32i	a0, a2, PT_AREG0
-	l32i	a2, a2, PT_AREG2
-	rfe
-
-	/*  MOVSP <at>,<as>  was invoked with <at> != a1.
-	 *  Because the stack pointer is not being modified,
-	 *  we should be able to just modify the pointer
-	 *  without moving any save area.
-	 *  The processor only traps these occurrences if the
-	 *  caller window isn't live, so unfortunately we can't
-	 *  use this as an alternate trap mechanism.
-	 *  So we just do the move.  This requires that we
-	 *  resolve the destination register, not just the source,
-	 *  so there's some extra work.
-	 *  (PERHAPS NOT REALLY NEEDED, BUT CLEANER...)
-	 */
-
-	/* a0 dst-reg, a1 user-stack, a2 stack, a3 value of src reg. */
-
-1:	movi	a4, .Lmovsp_dst
-	addx8	a4, a0, a4
-	jx	a4
-
-	.align 8
-.Lmovsp_dst:
-	s32i	a3, a2, PT_AREG0;	_j 1f;	.align 8
-	mov	a1, a3;			_j 1f;	.align 8
-	s32i	a3, a2, PT_AREG2;	_j 1f;	.align 8
-	s32i	a3, a2, PT_AREG3;	_j 1f;	.align 8
-	s32i	a3, a2, PT_AREG4;	_j 1f;	.align 8
-	mov	a5, a3;			_j 1f;	.align 8
-	mov	a6, a3;			_j 1f;	.align 8
-	mov	a7, a3;			_j 1f;	.align 8
-	mov	a8, a3;			_j 1f;	.align 8
-	mov	a9, a3;			_j 1f;	.align 8
-	mov	a10, a3;		_j 1f;	.align 8
-	mov	a11, a3;		_j 1f;	.align 8
-	mov	a12, a3;		_j 1f;	.align 8
-	mov	a13, a3;		_j 1f;	.align 8
-	mov	a14, a3;		_j 1f;	.align 8
-	mov	a15, a3;		_j 1f;	.align 8
-
-1:	l32i	a4, a2, PT_AREG4
-	l32i	a3, a2, PT_AREG3
-	l32i	a0, a2, PT_AREG0
-	l32i	a2, a2, PT_AREG2
-	rfe
-
+	_bbci.l	a4, 31, 4f
+	rotw	-1
+	_bbci.l	a8, 30, 8f
+	rotw	-1
+	j	_WindowUnderflow12
+8:	j	_WindowUnderflow8
+4:	j	_WindowUnderflow4
 ENDPROC(fast_alloca)
 
 /*
Signature · 1 line
1.7.7.6
author maintainer
#9 lore raw

PATCH v2 9/11 xtensa: don't use echo -e needlessly

In reply to Max Filippov

-e is not needed to output strings without escape sequences. This breaks big endian FSF build when the shell is dash, because its builtin echo doesn't understand '-e' switch and outputs it in the echoed string.

---
 arch/xtensa/Makefile      |    4 ++--
 arch/xtensa/boot/Makefile |    2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)
arch/xtensa/Makefile +2 -2
index 136224b..81250ec 100644
@@ -55,10 +55,10 @@ ifneq ($(CONFIG_LD_NO_RELAX),)
 LDFLAGS := --no-relax
 endif
 
-ifeq ($(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#"),1)
+ifeq ($(shell echo __XTENSA_EB__ | $(CC) -E - | grep -v "\#"),1)
 CHECKFLAGS += -D__XTENSA_EB__
 endif
-ifeq ($(shell echo -e __XTENSA_EL__ | $(CC) -E - | grep -v "\#"),1)
+ifeq ($(shell echo __XTENSA_EL__ | $(CC) -E - | grep -v "\#"),1)
 CHECKFLAGS += -D__XTENSA_EL__
 endif
 
arch/xtensa/boot/Makefile +1 -1
index 64ffc4b..ca20a89 100644
@@ -12,7 +12,7 @@
 KBUILD_CFLAGS	+= -fno-builtin -Iarch/$(ARCH)/boot/include
 HOSTFLAGS	+= -Iarch/$(ARCH)/boot/include
 
-BIG_ENDIAN	:= $(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#")
+BIG_ENDIAN	:= $(shell echo __XTENSA_EB__ | $(CC) -E - | grep -v "\#")
 
 export ccflags-y
 export BIG_ENDIAN
Signature · 1 line
1.7.7.6
author maintainer
#10 lore raw

PATCH v2 10/11 xtensa: fix !CONFIG_XTENSA_CALIBRATE_CCOUNT build failure

In reply to Max Filippov

From: Baruch Siach <[email protected]>

Commits 925f5532 (xtensa: ccount based clockevent implementation) and e3f43291 (xtensa: ccount based sched_clock) introduced users of ccount_freq. This variable doesn't exist when CONFIG_XTENSA_CALIBRATE_CCOUNT is disabled. Add ccount_freq definition in this case.

---
 arch/xtensa/include/asm/timex.h |    5 -----
 arch/xtensa/kernel/time.c       |    4 ++--
 2 files changed, 2 insertions(+), 7 deletions(-)
arch/xtensa/include/asm/timex.h +0 -5
index 69f9017..86aca77 100644
@@ -35,13 +35,8 @@
 # error "Bad timer number for Linux configurations!"
 #endif
 
-#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 extern unsigned long ccount_freq;
 #define CCOUNT_PER_JIFFY (ccount_freq / HZ)
-#else
-#define CCOUNT_PER_JIFFY (CONFIG_XTENSA_CPU_CLOCK*(1000000UL/HZ))
-#endif
-
 
 typedef unsigned long long cycles_t;
 
arch/xtensa/kernel/time.c +2 -2
index 24bb0c17..a65cb38 100644
@@ -29,9 +29,7 @@
 #include <asm/timex.h>
 #include <asm/platform.h>
 
-#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 unsigned long ccount_freq;		/* ccount Hz */
-#endif
 
 static cycle_t ccount_read(struct clocksource *cs)
 {
@@ -129,6 +127,8 @@ void __init time_init(void)
 	platform_calibrate_ccount();
 	printk("%d.%02d MHz\n", (int)ccount_freq/1000000,
 			(int)(ccount_freq/10000)%100);
+#else
+	ccount_freq = CONFIG_XTENSA_CPU_CLOCK*1000000UL;
 #endif
 	clocksource_register_hz(&ccount_clocksource, CCOUNT_PER_JIFFY * HZ);
 
Signature · 1 line
1.7.7.6
author maintainer
#11 lore raw

PATCH v2 11/11 xtensa: remove CCOUNT_PER_JIFFY

In reply to Max Filippov

From: Baruch Siach <[email protected]>

Use ccount_freq directly to make the code a little more readable.

---
 arch/xtensa/include/asm/timex.h |    1 -
 arch/xtensa/kernel/setup.c      |    4 ++--
 arch/xtensa/kernel/time.c       |    4 ++--
 3 files changed, 4 insertions(+), 5 deletions(-)
arch/xtensa/include/asm/timex.h +0 -1
index 86aca77..27fa3c1 100644
@@ -36,7 +36,6 @@
 #endif
 
 extern unsigned long ccount_freq;
-#define CCOUNT_PER_JIFFY (ccount_freq / HZ)
 
 typedef unsigned long long cycles_t;
 
arch/xtensa/kernel/setup.c +2 -2
index 42a8bba..4a8f027 100644
@@ -585,8 +585,8 @@ c_show(struct seq_file *f, void *slot)
 		     "bogomips\t: %lu.%02lu\n",
 		     XCHAL_BUILD_UNIQUE_ID,
 		     XCHAL_HAVE_BE ?  "big" : "little",
-		     CCOUNT_PER_JIFFY/(1000000/HZ),
-		     (CCOUNT_PER_JIFFY/(10000/HZ)) % 100,
+		     ccount_freq/1000000,
+		     (ccount_freq/10000) % 100,
 		     loops_per_jiffy/(500000/HZ),
 		     (loops_per_jiffy/(5000/HZ)) % 100);
 
arch/xtensa/kernel/time.c +2 -2
index a65cb38..9af3dd8 100644
@@ -130,7 +130,7 @@ void __init time_init(void)
 #else
 	ccount_freq = CONFIG_XTENSA_CPU_CLOCK*1000000UL;
 #endif
-	clocksource_register_hz(&ccount_clocksource, CCOUNT_PER_JIFFY * HZ);
+	clocksource_register_hz(&ccount_clocksource, ccount_freq);
 
 	ccount_timer.evt.cpumask = cpumask_of(0);
 	ccount_timer.evt.irq = irq_create_mapping(NULL, LINUX_TIMER_INT);
@@ -164,7 +164,7 @@ irqreturn_t timer_interrupt (int irq, void *dev_id)
 #ifndef CONFIG_GENERIC_CALIBRATE_DELAY
 void calibrate_delay(void)
 {
-	loops_per_jiffy = CCOUNT_PER_JIFFY;
+	loops_per_jiffy = ccount_freq / HZ;
 	printk("Calibrating delay loop (skipped)... "
 	       "%lu.%02lu BogoMIPS preset\n",
 	       loops_per_jiffy/(1000000/HZ),
Signature · 1 line
1.7.7.6