Skip to contentSkip to conversation

Adeos ARM/2.6 support

PATCH New Stelian Pop 1 participant 3 messages Nov 24, 2005

Subsystems (10)
lore
Share & tools
lore
#0 lore raw

cover Adeos ARM/2.6 support

Hi all,

I'm pleased to announce preliminary support for I-Pipe on ARM/2.6 kernels. I know quite a few people are waiting for this :)

The patch has been relatively well tested, using a hacked version of RTAI 3.1 and running kernel space realtime threads only.

The port has been tested on an ARM Integrator/CP board with an ARM1136 CPU coremodule. Support for other platforms (sa1100, pxa etc) has not been integrated but it should be quite trivial to do so using the code from the older 2.4 Adeos patches.

The only thing missing from this patch is complete exception support (only access trap is catched right now). I'll be adding those while porting Xenomaï over this patch in the next weeks.

While testing this patch on my board, very high latencies have been observed (RTAI's latency tests shows 23 us min, 30 us avg and go as far as 300 us under load). It is unclear at this moment if those latencies are caused by:
* intrinsic ARM cache problems [*]
* a problem in the I-Pipe patch
* hardware issues on my side.

Any idea on those latencies is welcomed, as are tests on other ARM hardware.

In order to enhance readability I've splitted the generic and the arch specific parts in two separate patches. The generic parts are identical to those found in the latest PPC I-Pipe patch.

I'll post the patches as followups to this message. If the mailing list has a size limit and rejects them, I'll put them as well on
http://www.popies.net/tmp/adeos/.

All feedbacks are welcomed.

Stelian.

[*]: see https://mail.rtai.org/pipermail/rtai/2005-April/011056.html

     and http://linuxdevices.com/articles/AT2598317046.html
Signature · 1 line
Stelian Pop <[email protected]>
#1 lore raw

PATCH 1/2 Adeos ARM/2.6 support - generic code

This is the "generic" (not arch specific) part of the ARM I-Pipe patch.

It was ripped off adeos-ipipe-2.6.14-ppc-1.0-06.patch (downloadable at
http://download.gna.org/adeos/patches/v2.6/adeos/ppc/adeos-ipipe-2.6.14-ppc-1.0-06.patch).

---

 include/linux/hardirq.h |   13 
 include/linux/ipipe.h   |  748 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/preempt.h |   59 ++-
 include/linux/sched.h   |    4 
 init/Kconfig            |    1 
 init/main.c             |    9 
 kernel/Makefile         |    1 
 kernel/exit.c           |    1 
 kernel/fork.c           |    8 
 kernel/ipipe/Kconfig    |   18 +
 kernel/ipipe/Makefile   |    2 
 kernel/ipipe/core.c     |  678 +++++++++++++++++++++++++++++++++++++++++++
 kernel/ipipe/generic.c  |  390 +++++++++++++++++++++++++
 kernel/irq/handle.c     |   15 
 kernel/printk.c         |   61 +++
 kernel/sched.c          |   58 +++
 kernel/signal.c         |    1 
 lib/smp_processor_id.c  |    5 
 lib/spinlock_debug.c    |   19 +
 mm/vmalloc.c            |    5 
 20 files changed, 2074 insertions(+), 22 deletions(-)
include/linux/hardirq.h +13 -0
diff -uNrp 2.6.14/include/linux/hardirq.h 2.6.14-ipipe/include/linux/hardirq.h
@@ -87,8 +87,21 @@ extern void synchronize_irq(unsigned int
 # define synchronize_irq(irq)	barrier()
 #endif
 
+#ifdef CONFIG_IPIPE
+#define nmi_enter() \
+do { \
+    if (ipipe_current_domain == ipipe_root_domain) \
+	irq_enter(); \
+} while(0)
+#define nmi_exit() \
+do { \
+    if (ipipe_current_domain == ipipe_root_domain) \
+	sub_preempt_count(HARDIRQ_OFFSET); \
+} while(0)
+#else /* !CONFIG_IPIPE */
 #define nmi_enter()		irq_enter()
 #define nmi_exit()		sub_preempt_count(HARDIRQ_OFFSET)
+#endif /* CONFIG_IPIPE */
 
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING
 static inline void account_user_vtime(struct task_struct *tsk)
include/linux/ipipe.h +748 -0

748 lines not on this page · raw message

include/linux/preempt.h +38 -21

79 lines not on this page · raw message

include/linux/sched.h +4 -0
diff -uNrp 2.6.14/include/linux/sched.h 2.6.14-ipipe/include/linux/sched.h
@@ -4,6 +4,7 @@
 #include <asm/param.h>	/* for HZ */
 
 #include <linux/config.h>
+#include <linux/ipipe.h>
 #include <linux/capability.h>
 #include <linux/threads.h>
 #include <linux/kernel.h>
@@ -813,6 +814,9 @@ struct task_struct {
 	int cpuset_mems_generation;
 #endif
 	atomic_t fs_excl;	/* holding fs exclusive resources */
+#ifdef CONFIG_IPIPE
+        void *ptd[IPIPE_ROOT_NPTDKEYS];
+#endif
 };
 
 static inline pid_t process_group(struct task_struct *tsk)
init/Kconfig +1 -0
diff -uNrp 2.6.14/init/Kconfig 2.6.14-ipipe/init/Kconfig
@@ -69,6 +69,7 @@ menu "General setup"
 
 config LOCALVERSION
 	string "Local version - append to kernel release"
+	default "-ipipe"
 	help
 	  Append an extra string to the end of your kernel version.
 	  This will show up when you type uname, for example.
init/main.c +8 -1
diff -uNrp 2.6.14/init/main.c 2.6.14-ipipe/init/main.c
@@ -402,8 +402,9 @@ static void noinline rest_init(void)
 	 */
 	schedule();
 
+ 	ipipe_reset_stats();
 	cpu_idle();
-} 
+}
 
 /* Check for early params. */
 static int __init do_early_param(char *param, char *val)
@@ -487,6 +488,11 @@ asmlinkage void __init start_kernel(void
 	init_timers();
 	softirq_init();
 	time_init();
+	/*
+	 * We need to wait for the interrupt and time subsystems to be
+	 * initialized before enabling the pipeline.
+	 */
+ 	ipipe_init();
 
 	/*
 	 * HACK ALERT! This is early. We're enabling the console before
@@ -611,6 +617,7 @@ static void __init do_basic_setup(void)
 #ifdef CONFIG_SYSCTL
 	sysctl_init();
 #endif
+	ipipe_init_proc();
 
 	/* Networking initialization needs a process context */ 
 	sock_init();
kernel/Makefile +1 -0
diff -uNrp 2.6.14/kernel/Makefile 2.6.14-ipipe/kernel/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_DETECT_SOFTLOCKUP) += softl
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 obj-$(CONFIG_SECCOMP) += seccomp.o
+obj-$(CONFIG_IPIPE) += ipipe/
 
 ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
kernel/exit.c +1 -0
diff -uNrp 2.6.14/kernel/exit.c 2.6.14-ipipe/kernel/exit.c
@@ -846,6 +846,7 @@ fastcall NORET_TYPE void do_exit(long co
 		exit_itimers(tsk->signal);
 		acct_process(code);
 	}
+ 	ipipe_exit_notify(tsk);
 	exit_mm(tsk);
 
 	exit_sem(tsk);
kernel/fork.c +8 -0
diff -uNrp 2.6.14/kernel/fork.c 2.6.14-ipipe/kernel/fork.c
@@ -1153,6 +1153,14 @@ static task_t *copy_process(unsigned lon
 	total_forks++;
 	write_unlock_irq(&tasklist_lock);
 	retval = 0;
+#ifdef CONFIG_IPIPE
+	{
+	int k;
+
+	for (k = 0; k < IPIPE_ROOT_NPTDKEYS; k++)
+	    p->ptd[k] = NULL;
+	}
+#endif /* CONFIG_IPIPE */
 
 fork_out:
 	if (retval)
kernel/ipipe/Kconfig +18 -0
diff -uNrp 2.6.14/kernel/ipipe/Kconfig 2.6.14-ipipe/kernel/ipipe/Kconfig
@@ -0,0 +1,18 @@
+config IPIPE
+	bool "Interrupt pipeline"
+	default y
+	---help---
+	  Activate this option if you want the interrupt pipeline to be
+	  compiled in.
+
+config IPIPE_STATS
+	bool "Collect statistics"
+	depends on IPIPE
+	default n
+	---help---
+	  Activate this option if you want runtime statistics to be collected
+	  while the I-pipe is operating. This option adds a small overhead, but
+	  is useful to detect unexpected latency points.
+
+config IPIPE_EXTENDED
+	def_bool IPIPE
kernel/ipipe/Makefile +2 -0
diff -uNrp 2.6.14/kernel/ipipe/Makefile 2.6.14-ipipe/kernel/ipipe/Makefile
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_IPIPE)	+= core.o generic.o
kernel/ipipe/core.c +678 -0

678 lines not on this page · raw message

kernel/ipipe/generic.c +390 -0

390 lines not on this page · raw message

kernel/irq/handle.c +15 -0
diff -uNrp 2.6.14/kernel/irq/handle.c 2.6.14-ipipe/kernel/irq/handle.c
@@ -81,6 +81,17 @@ fastcall int handle_IRQ_event(unsigned i
 {
 	int ret, retval = 0, status = 0;
 
+#ifdef CONFIG_IPIPE
+	/*
+	 * If processing a timer tick, pass the original regs as
+	 * collected during preemption and not our phony - always
+	 * kernel-originated - frame, so that we don't wreck the
+	 * profiling code.
+	 */
+	if (__ipipe_tick_irq == irq)
+		regs = __ipipe_tick_regs + smp_processor_id();
+#endif /* CONFIG_IPIPE */
+
 	if (!(action->flags & SA_INTERRUPT))
 		local_irq_enable();
 
@@ -117,14 +128,18 @@ fastcall unsigned int __do_IRQ(unsigned 
 		/*
 		 * No locking required for CPU-local interrupts:
 		 */
+#ifndef CONFIG_IPIPE
 		desc->handler->ack(irq);
+#endif /* CONFIG_IPIPE */
 		action_ret = handle_IRQ_event(irq, regs, desc->action);
 		desc->handler->end(irq);
 		return 1;
 	}
 
 	spin_lock(&desc->lock);
+#ifndef CONFIG_IPIPE
 	desc->handler->ack(irq);
+#endif /* CONFIG_IPIPE */
 	/*
 	 * REPLAY is when Linux resends an IRQ that was dropped earlier
 	 * WAITING is used by probe to mark irqs that are being tested
kernel/printk.c +61 -0

73 lines not on this page · raw message

kernel/sched.c +58 -0

79 lines not on this page · raw message

kernel/signal.c +1 -0
diff -uNrp 2.6.14/kernel/signal.c 2.6.14-ipipe/kernel/signal.c
@@ -601,6 +601,7 @@ void signal_wake_up(struct task_struct *
 	unsigned int mask;
 
 	set_tsk_thread_flag(t, TIF_SIGPENDING);
+	ipipe_sigwake_notify(t); /* TIF_SIGPENDING must be set first. */
 
 	/*
 	 * For SIGKILL, we want to wake it up in the stopped/traced case.
lib/smp_processor_id.c +5 -0
diff -uNrp 2.6.14/lib/smp_processor_id.c 2.6.14-ipipe/lib/smp_processor_id.c
@@ -12,6 +12,11 @@ unsigned int debug_smp_processor_id(void
 	int this_cpu = raw_smp_processor_id();
 	cpumask_t this_mask;
 
+#ifdef CONFIG_IPIPE
+ 	if (ipipe_current_domain != ipipe_root_domain)
+	    return this_cpu;
+#endif /* CONFIG_IPIPE */
+
 	if (likely(preempt_count))
 		goto out;
 
lib/spinlock_debug.c +19 -0
diff -uNrp 2.6.14/lib/spinlock_debug.c 2.6.14-ipipe/lib/spinlock_debug.c
@@ -10,6 +10,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 
 static void spin_bug(spinlock_t *lock, const char *msg)
 {
@@ -93,6 +94,8 @@ void _raw_spin_lock(spinlock_t *lock)
 	debug_spin_lock_after(lock);
 }
 
+EXPORT_SYMBOL(_raw_spin_lock);
+
 int _raw_spin_trylock(spinlock_t *lock)
 {
 	int ret = __raw_spin_trylock(&lock->raw_lock);
@@ -108,12 +111,16 @@ int _raw_spin_trylock(spinlock_t *lock)
 	return ret;
 }
 
+EXPORT_SYMBOL(_raw_spin_trylock);
+
 void _raw_spin_unlock(spinlock_t *lock)
 {
 	debug_spin_unlock(lock);
 	__raw_spin_unlock(&lock->raw_lock);
 }
 
+EXPORT_SYMBOL(_raw_spin_unlock);
+
 static void rwlock_bug(rwlock_t *lock, const char *msg)
 {
 	static long print_once = 1;
@@ -162,6 +169,8 @@ void _raw_read_lock(rwlock_t *lock)
 		__read_lock_debug(lock);
 }
 
+EXPORT_SYMBOL(_raw_read_lock);
+
 int _raw_read_trylock(rwlock_t *lock)
 {
 	int ret = __raw_read_trylock(&lock->raw_lock);
@@ -175,12 +184,16 @@ int _raw_read_trylock(rwlock_t *lock)
 	return ret;
 }
 
+EXPORT_SYMBOL(_raw_read_trylock);
+
 void _raw_read_unlock(rwlock_t *lock)
 {
 	RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
 	__raw_read_unlock(&lock->raw_lock);
 }
 
+EXPORT_SYMBOL(_raw_read_unlock);
+
 static inline void debug_write_lock_before(rwlock_t *lock)
 {
 	RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic");
@@ -235,6 +248,8 @@ void _raw_write_lock(rwlock_t *lock)
 	debug_write_lock_after(lock);
 }
 
+EXPORT_SYMBOL(_raw_write_lock);
+
 int _raw_write_trylock(rwlock_t *lock)
 {
 	int ret = __raw_write_trylock(&lock->raw_lock);
@@ -250,8 +265,12 @@ int _raw_write_trylock(rwlock_t *lock)
 	return ret;
 }
 
+EXPORT_SYMBOL(_raw_write_trylock);
+
 void _raw_write_unlock(rwlock_t *lock)
 {
 	debug_write_unlock(lock);
 	__raw_write_unlock(&lock->raw_lock);
 }
+
+EXPORT_SYMBOL(_raw_write_unlock);
mm/vmalloc.c +5 -0
diff -uNrp 2.6.14/mm/vmalloc.c 2.6.14-ipipe/mm/vmalloc.c
@@ -18,6 +18,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/tlbflush.h>
+#include <asm/pgalloc.h>
 
 
 DEFINE_RWLOCK(vmlist_lock);
@@ -148,10 +149,14 @@ int map_vm_area(struct vm_struct *area, 
 	pgd = pgd_offset_k(addr);
 	spin_lock(&init_mm.page_table_lock);
 	do {
+		pgd_t oldpgd;
+		memcpy(&oldpgd,pgd,sizeof(pgd_t));
 		next = pgd_addr_end(addr, end);
 		err = vmap_pud_range(pgd, addr, next, prot, pages);
 		if (err)
 			break;
+		if (pgd_val(oldpgd) != pgd_val(*pgd))
+			set_pgdir(addr, *pgd);
 	} while (pgd++, addr = next, addr != end);
 	spin_unlock(&init_mm.page_table_lock);
 	flush_cache_vmap((unsigned long) area->addr, end);
Signature · 1 line
Stelian Pop <[email protected]>
#2 lore raw

PATCH 2/2 Adeos ARM/2.6 support - arch specific code

In reply to Stelian Pop

This is the ARM architecture specific part of the I-Pipe patch. The PPC 1.0-06 I-Pipe patch served as a basis for this port.

The port supports the ARM Integrator/CP platform, but other platforms can be easily added.

The processor exception interception is not complete yet, look for the 'TODO' tag in the patch below.

---

 arch/arm/Kconfig                              |    2 
 arch/arm/kernel/Makefile                      |    1 
 arch/arm/kernel/entry-armv.S                  |   25 +
 arch/arm/kernel/entry-common.S                |   30 +
 arch/arm/kernel/entry-header.S                |    9 
 arch/arm/kernel/irq.c                         |    3 
 arch/arm/kernel/process.c                     |    5 
 arch/arm/mach-integrator/core.c               |  166 +++++---
 arch/arm/mach-integrator/integrator_cp.c      |    8 
 arch/arm/mm/fault.c                           |    3 
 b/arch/arm/kernel/ipipe-core.c                |  501 ++++++++++++++++++++++++++
 b/arch/arm/kernel/ipipe-root.c                |  410 +++++++++++++++++++++
 b/include/asm-arm/hw_irq.h                    |    6 
 b/include/asm-arm/ipipe.h                     |  161 ++++++++
 include/asm-arm/arch-integrator/entry-macro.S |    6 
 include/asm-arm/arch-integrator/platform.h    |    9 
 include/asm-arm/arch-integrator/timex.h       |    4 
 include/asm-arm/atomic.h                      |   12 
 include/asm-arm/bitops.h                      |   24 -
 include/asm-arm/mmu_context.h                 |   10 
 include/asm-arm/pgalloc.h                     |    5 
 include/asm-arm/system.h                      |   88 +++-
 22 files changed, 1371 insertions(+), 117 deletions(-)
arch/arm/Kconfig +2 -0
diff -r 0e63a7fee245 arch/arm/Kconfig
@@ -338,6 +338,8 @@
 	range 2 32
 	depends on SMP
 	default "4"
+
+source "kernel/ipipe/Kconfig"
 
 config PREEMPT
 	bool "Preemptible Kernel (EXPERIMENTAL)"
arch/arm/kernel/Makefile +1 -0
diff -r 0e63a7fee245 arch/arm/kernel/Makefile
@@ -19,6 +19,7 @@
 obj-$(CONFIG_ISA_DMA)		+= dma-isa.o
 obj-$(CONFIG_PCI)		+= bios32.o
 obj-$(CONFIG_SMP)		+= smp.o
+obj-$(CONFIG_IPIPE)		+= ipipe-core.o ipipe-root.o
 
 obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
 AFLAGS_iwmmxt.o			:= -Wa,-mcpu=iwmmxt
arch/arm/kernel/entry-armv.S +25 -0
diff -r 0e63a7fee245 arch/arm/kernel/entry-armv.S
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 1996,1997,1998 Russell King.
  *  ARM700 fix by Matthew Godbolt ([email protected])
+ *  Copyright (C) 2005 Stelian Pop.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -33,7 +34,11 @@
 	@ routine called with r0 = irq number, r1 = struct pt_regs *
 	@
 	adrne	lr, 1b
+#ifdef CONFIG_IPIPE
+	bne	__ipipe_grab_irq
+#else
 	bne	asm_do_IRQ
+#endif
 
 #ifdef CONFIG_SMP
 	/*
@@ -182,6 +187,11 @@
 #endif
 
 	irq_handler
+#ifdef CONFIG_IPIPE
+	cmp	r0, #0
+	beq	__ipipe_fast_svc_irq_exit
+#endif
+
 #ifdef CONFIG_PREEMPT
 	ldr	r0, [tsk, #TI_FLAGS]		@ get flags
 	tst	r0, #_TIF_NEED_RESCHED
@@ -191,6 +201,9 @@
 	str	r8, [tsk, #TI_PREEMPT]		@ restore preempt count
 	teq	r0, r7
 	strne	r0, [r0, -r0]			@ bug()
+#endif
+#ifdef CONFIG_IPIPE
+__ipipe_fast_svc_irq_exit:
 #endif
 	ldr	r0, [sp, #S_PSR]		@ irqs are already disabled
 	msr	spsr_cxsf, r0
@@ -220,6 +233,12 @@
 __und_svc:
 	svc_entry
 
+#ifdef CONFIG_IPIPE
+	mov	r1, sp				@ r0 = trapno, r1 = &regs
+	bl	__ipipe_dispatch_event		@ branch to trap handler
+	cmp	r0, #0
+	bne	1f
+#endif /* CONFIG_IPIPE */
 	@
 	@ call emulation code, which returns using r9 if it has emulated
 	@ the instruction, or the more conventional lr if we are to treat
@@ -378,6 +397,12 @@
 #endif
 
 	irq_handler
+#ifdef CONFIG_IPIPE
+	cmp	r0, #0
+	bne	__ipipe_usr_irq_continue
+	slow_restore_user_regs			@ Fast exit path over non-root domains
+__ipipe_usr_irq_continue:
+#endif
 #ifdef CONFIG_PREEMPT
 	ldr	r0, [tsk, #TI_PREEMPT]
 	str	r8, [tsk, #TI_PREEMPT]
arch/arm/kernel/entry-common.S +21 -9
diff -r 0e63a7fee245 arch/arm/kernel/entry-common.S
@@ -2,6 +2,7 @@
  *  linux/arch/arm/kernel/entry-common.S
  *
  *  Copyright (C) 2000 Russell King
+ *  Copyright (C) 2005 Stelian Pop.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -26,7 +27,7 @@
 	tst	r1, #_TIF_WORK_MASK
 	bne	fast_work_pending
 
-	@ fast_restore_user_regs
+fast_restore_user_regs:
 	ldr	r1, [sp, #S_OFF + S_PSR]	@ get calling cpsr
 	ldr	lr, [sp, #S_OFF + S_PC]!	@ get pc
 	msr	spsr_cxsf, r1			@ save in spsr_svc
@@ -34,6 +35,12 @@
 	mov	r0, r0
 	add	sp, sp, #S_FRAME_SIZE - S_PC
 	movs	pc, lr				@ return & move spsr_svc into cpsr
+
+#ifdef CONFIG_IPIPE
+__ipipe_fast_exit_syscall:
+	disable_irq				@ disable interrupts
+	b	fast_restore_user_regs
+#endif /* CONFIG_IPIPE */
 
 /*
  * Ok, we need to do extra processing, enter the slow path.
@@ -63,14 +70,7 @@
 	tst	r1, #_TIF_WORK_MASK
 	bne	work_pending
 no_work_pending:
-	@ slow_restore_user_regs
-	ldr	r1, [sp, #S_PSR]		@ get calling cpsr
-	ldr	lr, [sp, #S_PC]!		@ get pc
-	msr	spsr_cxsf, r1			@ save in spsr_svc
-	ldmdb	sp, {r0 - lr}^			@ get calling r1 - lr
-	mov	r0, r0
-	add	sp, sp, #S_FRAME_SIZE - S_PC
-	movs	pc, lr				@ return & move spsr_svc into cpsr
+	slow_restore_user_regs
 
 /*
  * This is how we return from a fork.
@@ -152,6 +152,15 @@
 	ldr	ip, [tsk, #TI_FLAGS]		@ check for syscall tracing
 	bic	scno, scno, #0xff000000		@ mask off SWI op-code
 	eor	scno, scno, #__NR_SYSCALL_BASE	@ check OS number
+#ifdef CONFIG_IPIPE
+	stmfd	sp!, {r0-r3, ip}
+	add	r0, sp, #S_OFF
+	mov	r1, scno
+	bl	__ipipe_syscall_root
+	cmp	r0,#0
+	ldmfd	sp!, {r0-r3, ip}
+	bne	__ipipe_fast_exit_syscall
+#endif /* CONFIG_IPIPE */
 	adr	tbl, sys_call_table		@ load syscall table pointer
 	tst	ip, #_TIF_SYSCALL_TRACE		@ are we tracing syscalls?
 	bne	__sys_trace
@@ -195,6 +204,9 @@
 	.type	__cr_alignment, #object
 __cr_alignment:
 	.word	cr_alignment
+#endif
+#ifdef CONFIG_IPIPE
+	.word	__ipipe_syscall_root
 #endif
 
 	.type	sys_call_table, #object
arch/arm/kernel/entry-header.S +9 -0
diff -r 0e63a7fee245 arch/arm/kernel/entry-header.S
@@ -67,6 +67,15 @@
 #endif
 	.endm
 
+	.macro slow_restore_user_regs
+	ldr	r1, [sp, #S_PSR]		@ get calling cpsr
+	ldr	lr, [sp, #S_PC]!		@ get pc
+	msr	spsr_cxsf, r1			@ save in spsr_svc
+	ldmdb	sp, {r0 - lr}^			@ get calling r1 - lr
+	mov	r0, r0
+	add	sp, sp, #S_FRAME_SIZE - S_PC
+	movs	pc, lr				@ return & move spsr_svc into cpsr
+	.endm
 
 /*
  * These are the registers used in the syscall handler, and allow us to
arch/arm/kernel/irq.c +2 -1
diff -r 0e63a7fee245 arch/arm/kernel/irq.c
@@ -54,10 +54,11 @@
 
 static int noirqdebug;
 static volatile unsigned long irq_err_count;
-static DEFINE_SPINLOCK(irq_controller_lock);
+DEFINE_SPINLOCK(irq_controller_lock);
 static LIST_HEAD(irq_pending);
 
 struct irqdesc irq_desc[NR_IRQS];
+EXPORT_SYMBOL(irq_desc);
 void (*init_arch_irq)(void) __initdata = NULL;
 
 /*
arch/arm/kernel/process.c +3 -2
diff -r 0e63a7fee245 arch/arm/kernel/process.c
@@ -85,12 +85,12 @@
  */
 void default_idle(void)
 {
-	local_irq_disable();
+	local_irq_disable_hw_cond();
 	if (!need_resched() && !hlt_counter) {
 		timer_dyn_reprogram();
 		arch_idle();
 	}
-	local_irq_enable();
+	local_irq_enable_hw_cond();
 }
 
 /*
@@ -107,6 +107,7 @@
 		void (*idle)(void) = pm_idle;
 		if (!idle)
 			idle = default_idle;
+		ipipe_suspend_domain();
 		preempt_disable();
 		leds_event(led_idle_start);
 		while (!need_resched())
arch/arm/mach-integrator/core.c +111 -55

215 lines not on this page · raw message

arch/arm/mach-integrator/integrator_cp.c +7 -1
diff -r 0e63a7fee245 arch/arm/mach-integrator/integrator_cp.c
@@ -2,6 +2,7 @@
  *  linux/arch/arm/mach-integrator/integrator_cp.c
  *
  *  Copyright (C) 2003 Deep Blue Solutions Ltd
+ *  Copyright (C) 2005 Stelian Pop.
  *
  * 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
@@ -521,9 +522,14 @@
 
 #define TIMER_CTRL_IE	(1 << 5)			/* Interrupt Enable */
 
+#ifdef CONFIG_IPIPE
+unsigned int ipipe_mach_ticks_per_jiffy = 1000000 * TICKS_PER_uSEC / HZ;
+EXPORT_SYMBOL(ipipe_mach_ticks_per_jiffy);
+#endif
+
 static void __init intcp_timer_init(void)
 {
-	integrator_time_init(1000000 / HZ, TIMER_CTRL_IE);
+	integrator_time_init(1000000 * TICKS_PER_uSEC / HZ, TIMER_CTRL_IE);
 }
 
 static struct sys_timer cp_timer = {
arch/arm/mm/fault.c +3 -0
diff -r 0e63a7fee245 arch/arm/mm/fault.c
@@ -225,6 +225,9 @@
 
 	tsk = current;
 	mm  = tsk->mm;
+
+	if (ipipe_trap_notify(IPIPE_TRAP_ACCESS,regs))
+		return 0;
 
 	/*
 	 * If we're in an interrupt or have no user
include/asm-arm/arch-integrator/entry-macro.S +5 -1
diff -r 0e63a7fee245 include/asm-arm/arch-integrator/entry-macro.S
@@ -20,7 +20,11 @@
 		teq	\irqstat, #0
 		ldreq	\irqstat, [\base, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)]
 		moveq	\irqnr, #IRQ_CIC_START
-
+#ifdef CONFIG_IPIPE
+		tst	\irqstat, #0x00000040			@ check IRQ_TIMERINT1 first
+		movne	\irqnr, #6
+		bne	1003f
+#endif /* CONFIG_IPIPE */
 1001:		tst	\irqstat, #15
 		bne	1002f
 		add	\irqnr, \irqnr, #4
include/asm-arm/arch-integrator/platform.h +8 -1
diff -r 0e63a7fee245 include/asm-arm/arch-integrator/platform.h
@@ -32,6 +32,8 @@
 
 #ifndef __address_h
 #define __address_h                     1
+
+#include <linux/config.h>
 
 /* ========================================================================
  *  Integrator definitions
@@ -436,7 +438,7 @@
  *  Timer definitions
  *
  *  Only use timer 1 & 2
- *  (both run at 24MHz and will need the clock divider set to 16).
+ *  (both run at 1MHZ on /CP and at 24MHz on /AP)
  *
  *  Timer 0 runs at bus frequency and therefore could vary and currently
  *  uHAL can't handle that.
@@ -449,7 +451,12 @@
 
 #define MAX_TIMER                       2
 #define MAX_PERIOD                      699050
+
+#ifdef CONFIG_ARCH_INTEGRATOR_CP
+#define TICKS_PER_uSEC                  1
+#else
 #define TICKS_PER_uSEC                  24
+#endif
 
 /*
  *  These are useconds NOT ticks.
include/asm-arm/arch-integrator/timex.h +2 -2
diff -r 0e63a7fee245 include/asm-arm/arch-integrator/timex.h
@@ -21,6 +21,6 @@
  */
 
 /*
- * ??
+ * Timer rate
  */
-#define CLOCK_TICK_RATE		(50000000 / 16)
+#define CLOCK_TICK_RATE		(1000000)
include/asm-arm/atomic.h +6 -6
diff -r 0e63a7fee245 include/asm-arm/atomic.h
@@ -110,10 +110,10 @@
 	unsigned long flags;
 	int val;
 
-	local_irq_save(flags);
+	local_irq_save_hw(flags);
 	val = v->counter;
 	v->counter = val += i;
-	local_irq_restore(flags);
+	local_irq_restore_hw(flags);
 
 	return val;
 }
@@ -123,10 +123,10 @@
 	unsigned long flags;
 	int val;
 
-	local_irq_save(flags);
+	local_irq_save_hw(flags);
 	val = v->counter;
 	v->counter = val -= i;
-	local_irq_restore(flags);
+	local_irq_restore_hw(flags);
 
 	return val;
 }
@@ -135,9 +135,9 @@
 {
 	unsigned long flags;
 
-	local_irq_save(flags);
+	local_irq_save_hw(flags);
 	*addr &= ~mask;
-	local_irq_restore(flags);
+	local_irq_restore_hw(flags);
 }
 
 #endif /* __LINUX_ARM_ARCH__ */
include/asm-arm/bitops.h +12 -12
diff -r 0e63a7fee245 include/asm-arm/bitops.h
@@ -36,9 +36,9 @@
 
 	p += bit >> 5;
 
-	local_irq_save(flags);
+	local_irq_save_hw(flags);
 	*p |= mask;
-	local_irq_restore(flags);
+	local_irq_restore_hw(flags);
 }
 
 static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
@@ -48,9 +48,9 @@
 
 	p += bit >> 5;
 
-	local_irq_save(flags);
+	local_irq_save_hw(flags);
 	*p &= ~mask;
-	local_irq_restore(flags);
+	local_irq_restore_hw(flags);
 }
 
 static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
@@ -60,9 +60,9 @@
 
 	p += bit >> 5;
 
-	local_irq_save(flags);
+	local_irq_save_hw(flags);
 	*p ^= mask;
-	local_irq_restore(flags);
+	local_irq_restore_hw(flags);
 }
 
 static inline int
@@ -74,10 +74,10 @@
 
 	p += bit >> 5;
 
-	local_irq_save(flags);
+	local_irq_save_hw(flags);
 	res = *p;
 	*p = res | mask;
-	local_irq_restore(flags);
+	local_irq_restore_hw(flags);
 
 	return res & mask;
 }
@@ -91,10 +91,10 @@
 
 	p += bit >> 5;
 
-	local_irq_save(flags);
+	local_irq_save_hw(flags);
 	res = *p;
 	*p = res & ~mask;
-	local_irq_restore(flags);
+	local_irq_restore_hw(flags);
 
 	return res & mask;
 }
@@ -108,10 +108,10 @@
 
 	p += bit >> 5;
 
-	local_irq_save(flags);
+	local_irq_save_hw(flags);
 	res = *p;
 	*p = res ^ mask;
-	local_irq_restore(flags);
+	local_irq_restore_hw(flags);
 
 	return res & mask;
 }
include/asm-arm/mmu_context.h +10 -0
diff -r 0e63a7fee245 include/asm-arm/mmu_context.h
@@ -91,6 +91,16 @@
 }
 
 #define deactivate_mm(tsk,mm)	do { } while (0)
+#ifdef CONFIG_IPIPE
+#define activate_mm(active_mm, mm)		\
+do {						\
+	unsigned long flags;			\
+	local_irq_save_hw_cond(flags);		\
+	switch_mm(active_mm, mm, current);	\
+	local_irq_restore_hw_cond(flags);	\
+} while(0)
+#else
 #define activate_mm(prev,next)	switch_mm(prev, next, NULL)
+#endif
 
 #endif
include/asm-arm/pgalloc.h +5 -0
diff -r 0e63a7fee245 include/asm-arm/pgalloc.h
@@ -28,6 +28,11 @@
 #define pgd_free(pgd)			free_pgd_slow(pgd)
 
 #define check_pgt_cache()		do { } while (0)
+
+static inline void set_pgdir(unsigned long address, pgd_t entry)
+{
+	/* nop */
+}
 
 /*
  * Allocate one PTE table.
include/asm-arm/system.h +61 -27

156 lines not on this page · raw message

arch/arm/kernel/ipipe-core.c new file +501 -0

501 lines not on this page · raw message

arch/arm/kernel/ipipe-root.c new file +410 -0

410 lines not on this page · raw message

include/asm-arm/hw_irq.h new file +6 -0
diff -r 0e63a7fee245 include/asm-arm/hw_irq.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_ARM_HW_IRQ_H
+#define __ASM_ARM_HW_IRQ_H
+
+/* Dummy include. */
+
+#endif
include/asm-arm/ipipe.h new file +161 -0

161 lines not on this page · raw message

Signature · 1 line
Stelian Pop <[email protected]>