Jan Kiszka wrote:
>
> If you have anything more pending, please post soon, Gilles is
> collecting the ARM stuff for Xenomai 2.3.
Attached are all patches that I posted in the last two months but didn't get
into Ipipe CVS or Xenomai svn. The first file pools all patches for Ipipe,
here comes an overview what it comprises:
- I-pipe for Samsung S3C24xx
- I-pipe tracer for ARM
- Introduce __ipipe_mach_release_timer()
- Fix ipipe_tsc2ns()
- Don't activate the tracer too early during the boot process
Please consider these patches for Xenomai 2.3. Thanks!
--
Sebastian
diff -upNr linux-2.6.15-ipipe.orig/arch/arm/boot/compressed/head.S linux-2.6.15-ipipe/arch/arm/boot/compressed/head.S
--- linux-2.6.15-ipipe.orig/arch/arm/boot/compressed/head.S 2006-01-03 04:21:10.000000000 +0100
+++ linux-2.6.15-ipipe/arch/arm/boot/compressed/head.S 2006-12-04 17:45:52.000000000 +0100
@@ -710,6 +710,16 @@ memdump: mov r12, r0
mov pc, r10
#endif
+#ifdef CONFIG_IPIPE_TRACE_MCOUNT
+ .text
+ .align 0
+ .type mcount %function
+ .global mcount
+mcount:
+ mov pc, lr @ just return
+#endif
+
+
reloc_end:
.align
diff -upNr linux-2.6.15-ipipe.orig/arch/arm/kernel/entry-common.S linux-2.6.15-ipipe/arch/arm/kernel/entry-common.S
--- linux-2.6.15-ipipe.orig/arch/arm/kernel/entry-common.S 2006-05-04 14:43:39.000000000 +0200
+++ linux-2.6.15-ipipe/arch/arm/kernel/entry-common.S 2006-12-04 09:48:15.000000000 +0100
@@ -294,3 +294,28 @@ sys_mmap2:
str r5, [sp, #4]
b do_mmap2
#endif
+
+#ifdef CONFIG_FRAME_POINTER
+
+ .text
+ .align 0
+ .type arm_return_addr %function
+ .global arm_return_addr
+
+arm_return_addr:
+ mov ip, r0
+ mov r0, fp
+3:
+ cmp r0, #0
+ beq 1f @ frame list hit end, bail
+ cmp ip, #0
+ beq 2f @ reached desired frame
+ ldr r0, [r0, #-12] @ else continue, get next fp
+ sub ip, ip, #1
+ b 3b
+2:
+ ldr r0, [r0, #-4] @ get target return address
+1:
+ mov pc, lr
+
+#endif
diff -upNr linux-2.6.15-ipipe.orig/arch/arm/kernel/ipipe-mcount.S linux-2.6.15-ipipe/arch/arm/kernel/ipipe-mcount.S
--- linux-2.6.15-ipipe.orig/arch/arm/kernel/ipipe-mcount.S 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15-ipipe/arch/arm/kernel/ipipe-mcount.S 2006-12-04 09:46:30.000000000 +0100
@@ -0,0 +1,40 @@
+/*
+ * linux/arch/arm/kernel/ipipe-mcount.S
+ *
+ * Copyright (C) 2006 Sebastian Smolorz <[EMAIL PROTECTED]>, emlix GmbH
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_FRAME_POINTER
+
+ .text
+ .align 0
+ .type mcount %function
+ .global mcount
+
+mcount:
+
+ ldr ip, =ipipe_trace_enable @ leave early, if disabled
+ ldr ip, [ip]
+ cmp ip, #0
+ moveq pc,lr
+
+ mov ip, sp
+ stmdb sp!, {r0 - r3, fp, ip, lr, pc} @ create stack frame
+
+ mov r3, #0 @ no additional value (v)
+ ldr r2, [fp, #-4] @ get lr (the return address
+ @ of the caller of the
+ @ instrumented function)
+ mov r1, lr @ get lr - (the return address
+ @ of the instrumented function)
+ mov r0, #0 @ IPIPE_TRACE_FN
+
+ sub fp, ip, #4 @ point fp at this frame
+
+ bl __ipipe_trace
+
+ ldmdb fp, {r0 - r3, fp, sp, pc} @ pop entry frame and return
+
+#endif
diff -upNr linux-2.6.15-ipipe.orig/arch/arm/kernel/ipipe-root.c linux-2.6.15-ipipe/arch/arm/kernel/ipipe-root.c
--- linux-2.6.15-ipipe.orig/arch/arm/kernel/ipipe-root.c 2006-10-09 22:41:23.000000000 +0200
+++ linux-2.6.15-ipipe/arch/arm/kernel/ipipe-root.c 2006-12-13 17:20:00.000000000 +0100
@@ -306,11 +306,19 @@ asmlinkage int __ipipe_grab_irq(int irq,
}
}
+#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
+ ipipe_trace_begin(regs->ARM_ORIG_r0);
+#endif
+
if (__ipipe_mach_irq_mux_p(irq))
__ipipe_mach_demux_irq(irq, regs);
else
__ipipe_handle_irq(irq, regs);
+#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
+ ipipe_trace_end(regs->ARM_ORIG_r0);
+#endif
+
ipipe_load_cpuid();
return (per_cpu(ipipe_percpu_domain, cpuid) == ipipe_root_domain &&
@@ -376,3 +384,8 @@ EXPORT_SYMBOL_GPL(show_stack);
#ifndef MULTI_CPU
EXPORT_SYMBOL_GPL(cpu_do_switch_mm);
#endif
+
+#ifdef CONFIG_IPIPE_TRACE_MCOUNT
+void notrace mcount(void);
+EXPORT_SYMBOL(mcount);
+#endif /* CONFIG_IPIPE_TRACE_MCOUNT */
diff -upNr linux-2.6.15-ipipe.orig/arch/arm/kernel/Makefile linux-2.6.15-ipipe/arch/arm/kernel/Makefile
--- linux-2.6.15-ipipe.orig/arch/arm/kernel/Makefile 2006-02-20 14:54:22.000000000 +0100
+++ linux-2.6.15-ipipe/arch/arm/kernel/Makefile 2006-12-01 13:42:49.000000000 +0100
@@ -20,6 +20,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_IPIPE_TRACE_MCOUNT) += ipipe-mcount.o
obj-$(CONFIG_IWMMXT) += iwmmxt.o
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
diff -upNr linux-2.6.15-ipipe.orig/arch/arm/kernel/process.c linux-2.6.15-ipipe/arch/arm/kernel/process.c
--- linux-2.6.15-ipipe.orig/arch/arm/kernel/process.c 2006-02-20 14:54:22.000000000 +0100
+++ linux-2.6.15-ipipe/arch/arm/kernel/process.c 2006-12-14 16:35:09.000000000 +0100
@@ -89,12 +89,18 @@ void default_idle(void)
if (hlt_counter)
cpu_relax();
else {
- local_irq_disable_hw();
+ local_irq_disable();
if (!need_resched()) {
timer_dyn_reprogram();
+#ifdef CONFIG_IPIPE
+ __ipipe_unstall_root();
+#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
+ ipipe_trace_end(0x8000000E);
+#endif /* CONFIG_IPIPE_TRACE_IRQSOFF */
+#endif /* CONFIG_IPIPE */
arch_idle();
}
- local_irq_enable_hw();
+ local_irq_enable();
}
}
diff -upNr linux-2.6.15-ipipe.orig/arch/arm/mach-integrator/core.c linux-2.6.15-ipipe/arch/arm/mach-integrator/core.c
--- linux-2.6.15-ipipe.orig/arch/arm/mach-integrator/core.c 2006-01-30 23:46:08.000000000 +0100
+++ linux-2.6.15-ipipe/arch/arm/mach-integrator/core.c 2006-12-18 15:42:03.000000000 +0100
@@ -303,7 +303,7 @@ void __ipipe_mach_acktimer(void)
writel(1, TIMER1_VA_BASE + TIMER_INTCLR);
}
-unsigned long long __ipipe_mach_get_tsc(void)
+notrace unsigned long long __ipipe_mach_get_tsc(void)
{
unsigned long long result;
unsigned long flags;
@@ -330,6 +330,12 @@ void __ipipe_mach_set_dec(unsigned long
}
EXPORT_SYMBOL(__ipipe_mach_set_dec);
+void __ipipe_mach_release_timer(void)
+{
+ __ipipe_mach_set_dec(__ipipe_mach_ticks_per_jiffy);
+}
+EXPORT_SYMBOL(__ipipe_mach_release_timer);
+
unsigned long __ipipe_mach_get_dec(void)
{
return readl(TIMER1_VA_BASE + TIMER_VALUE);
diff -upNr linux-2.6.15-ipipe.orig/arch/arm/mach-pxa/time.c linux-2.6.15-ipipe/arch/arm/mach-pxa/time.c
--- linux-2.6.15-ipipe.orig/arch/arm/mach-pxa/time.c 2006-09-10 17:13:35.000000000 +0200
+++ linux-2.6.15-ipipe/arch/arm/mach-pxa/time.c 2006-12-18 15:44:16.000000000 +0100
@@ -270,7 +270,7 @@ void __ipipe_mach_acktimer(void)
OSSR = OSSR_M0; /* Clear match on timer 0 */
}
-unsigned long long __ipipe_mach_get_tsc(void)
+notrace unsigned long long __ipipe_mach_get_tsc(void)
{
if (likely(pxa_timer_initialized)) {
static union {
@@ -324,6 +324,12 @@ void __ipipe_mach_set_dec(unsigned long
}
EXPORT_SYMBOL(__ipipe_mach_set_dec);
+void __ipipe_mach_release_timer(void)
+{
+ __ipipe_mach_set_dec(__ipipe_mach_ticks_per_jiffy);
+}
+EXPORT_SYMBOL(__ipipe_mach_release_timer);
+
unsigned long __ipipe_mach_get_dec(void)
{
return OSMR0 - OSCR;
diff -upNr linux-2.6.15-ipipe.orig/arch/arm/mach-s3c2410/irq.c linux-2.6.15-ipipe/arch/arm/mach-s3c2410/irq.c
--- linux-2.6.15-ipipe.orig/arch/arm/mach-s3c2410/irq.c 2006-01-03 04:21:10.000000000 +0100
+++ linux-2.6.15-ipipe/arch/arm/mach-s3c2410/irq.c 2006-11-30 12:23:27.000000000 +0100
@@ -3,6 +3,8 @@
* Copyright (c) 2003,2004 Simtec Electronics
* Ben Dooks <[EMAIL PROTECTED]>
*
+ * Copyright (C) 2006 Sebastian Smolorz <[EMAIL PROTECTED]>, emlix GmbH
+ *
* 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
@@ -48,7 +50,10 @@
*
* 25-Jul-2005 Ben Dooks
* Split the S3C2440 IRQ code to seperate file
-*/
+ *
+ * 30-Oct-2006 Sebastian Smolorz
+ * Added Adeos/I-pipe support
+ */
#include <linux/init.h>
#include <linux/module.h>
@@ -56,6 +61,7 @@
#include <linux/ioport.h>
#include <linux/ptrace.h>
#include <linux/sysdev.h>
+#include <linux/ipipe.h>
#include <asm/hardware.h>
#include <asm/irq.h>
@@ -70,6 +76,14 @@
#include "pm.h"
#include "irq.h"
+#ifdef CONFIG_IPIPE
+#ifdef CONFIG_CPU_S3C2440
+extern void __ipipe_s3c_irq_demux_wdtac97(unsigned int irq,
+ struct pt_regs *regs);
+extern void __ipipe_s3c_irq_demux_cam(unsigned int irq, struct pt_regs *regs);
+#endif /* CONFIG_CPU_S3C2440 */
+#endif /* CONFIG_IPIPE */
+
/* wakeup irq control */
#ifdef CONFIG_PM
@@ -573,6 +587,79 @@ s3c_irq_demux_uart2(unsigned int irq,
}
+#ifdef CONFIG_IPIPE
+static void __ipipe_s3c_irq_demux_uart(unsigned int start,
+ unsigned int subsrc,
+ struct pt_regs *regs)
+{
+ unsigned int offset = start - IRQ_S3CUART_RX0;
+
+ subsrc >>= offset;
+ subsrc &= 7;
+
+ if (subsrc != 0) {
+ if (subsrc & 1)
+ __ipipe_handle_irq(start, regs);
+ if (subsrc & 2)
+ __ipipe_handle_irq(start+1, regs);
+ if (subsrc & 4)
+ __ipipe_handle_irq(start+2, regs);
+ }
+}
+
+static void __ipipe_s3c_irq_demux_adc(unsigned int subsrc,
+ struct pt_regs *regs)
+{
+ subsrc >>= 9;
+ subsrc &= 3;
+
+ if (subsrc != 0) {
+ if (subsrc & 1)
+ __ipipe_handle_irq(IRQ_TC, regs);
+ if (subsrc & 2)
+ __ipipe_handle_irq(IRQ_ADC, regs);
+ }
+}
+
+void __ipipe_mach_demux_irq(unsigned irq, struct pt_regs *regs)
+{
+ unsigned int subsrc, submsk;
+ struct irqdesc *desc_unused = irq_desc + irq;
+
+ /* read the current pending interrupts, and the mask
+ * for what it is available */
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+ subsrc &= ~submsk;
+
+ switch (irq) {
+ case IRQ_UART0:
+ __ipipe_s3c_irq_demux_uart(IRQ_S3CUART_RX0, subsrc, regs);
+ break;
+ case IRQ_UART1:
+ __ipipe_s3c_irq_demux_uart(IRQ_S3CUART_RX1, subsrc, regs);
+ break;
+ case IRQ_UART2:
+ __ipipe_s3c_irq_demux_uart(IRQ_S3CUART_RX2, subsrc, regs);
+ break;
+ case IRQ_ADCPARENT:
+ __ipipe_s3c_irq_demux_adc(subsrc, regs);
+ break;
+#ifdef CONFIG_CPU_S3C2440
+ case IRQ_WDT:
+ __ipipe_s3c_irq_demux_wdtac97(subsrc, regs);
+ break;
+ case IRQ_CAM:
+ __ipipe_s3c_irq_demux_cam(subsrc, regs);
+ break;
+#endif /* CONFIG_CPU_S3C2440 */
+ }
+
+ desc_unused->chip->unmask(irq);
+}
+#endif /* CONFIG_IPIPE */
+
/* s3c24xx_init_irq
*
* Initialise S3C2410 IRQ system
diff -upNr linux-2.6.15-ipipe.orig/arch/arm/mach-s3c2410/s3c2440-irq.c linux-2.6.15-ipipe/arch/arm/mach-s3c2410/s3c2440-irq.c
--- linux-2.6.15-ipipe.orig/arch/arm/mach-s3c2410/s3c2440-irq.c 2006-01-03 04:21:10.000000000 +0100
+++ linux-2.6.15-ipipe/arch/arm/mach-s3c2410/s3c2440-irq.c 2006-11-30 12:24:21.000000000 +0100
@@ -3,6 +3,8 @@
* Copyright (c) 2003,2004 Simtec Electronics
* Ben Dooks <[EMAIL PROTECTED]>
*
+ * Copyright (C) 2006 Sebastian Smolorz <[EMAIL PROTECTED]>, emlix GmbH
+ *
* 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
@@ -19,8 +21,10 @@
*
* Changelog:
* 25-Jul-2005 BJD Split from irq.c
+ * 11-Oct-2006 Sebastian Smolorz
+ * Added Adeos/Ipipe support
*
-*/
+ */
#include <linux/init.h>
#include <linux/module.h>
@@ -28,6 +32,7 @@
#include <linux/ioport.h>
#include <linux/ptrace.h>
#include <linux/sysdev.h>
+#include <linux/ipipe.h>
#include <asm/hardware.h>
#include <asm/irq.h>
@@ -157,6 +162,34 @@ static struct irqchip s3c_irq_cam = {
.ack = s3c_irq_cam_ack,
};
+#ifdef CONFIG_IPIPE
+void __ipipe_s3c_irq_demux_wdtac97(unsigned int subsrc, struct pt_regs *regs)
+{
+ subsrc >>= 13;
+ subsrc &= 3;
+
+ if (subsrc != 0) {
+ if (subsrc & 1)
+ __ipipe_handle_irq(IRQ_S3C2440_WDT, regs);
+ if (subsrc & 2)
+ __ipipe_handle_irq(IRQ_S3C2440_AC97, regs);
+ }
+}
+
+void __ipipe_s3c_irq_demux_cam(unsigned int subsrc, struct pt_regs *regs)
+{
+ subsrc >>= 11;
+ subsrc &= 3;
+
+ if (subsrc != 0) {
+ if (subsrc & 1)
+ __ipipe_handle_irq(IRQ_S3C2440_CAM_C, regs);
+ if (subsrc & 2)
+ __ipipe_handle_irq(IRQ_S3C2440_CAM_P, regs);
+ }
+}
+#endif /* CONFIG_IPIPE */
+
static int s3c2440_irq_add(struct sys_device *sysdev)
{
unsigned int irqno;
diff -upNr linux-2.6.15-ipipe.orig/arch/arm/mach-s3c2410/time.c linux-2.6.15-ipipe/arch/arm/mach-s3c2410/time.c
--- linux-2.6.15-ipipe.orig/arch/arm/mach-s3c2410/time.c 2006-01-03 04:21:10.000000000 +0100
+++ linux-2.6.15-ipipe/arch/arm/mach-s3c2410/time.c 2006-12-18 15:25:08.000000000 +0100
@@ -3,6 +3,8 @@
* Copyright (C) 2003-2005 Simtec Electronics
* Ben Dooks, <[EMAIL PROTECTED]>
*
+ * Copyright (C) 2006 Sebastian Smolorz <[EMAIL PROTECTED]>, emlix GmbH
+ *
* 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
@@ -24,6 +26,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/err.h>
+#include <linux/module.h>
#include <asm/system.h>
#include <asm/leds.h>
@@ -40,7 +43,6 @@
#include "clock.h"
#include "cpu.h"
-static unsigned long timer_startval;
static unsigned long timer_usec_ticks;
#define TIMER_USEC_SHIFT 16
@@ -55,6 +57,24 @@ static unsigned long timer_usec_ticks;
* Original patch by Dimitry Andric, updated by Ben Dooks
*/
+static unsigned long last_free_running_tcnt = 0;
+static unsigned long free_running_tcon = 0;
+static unsigned long timer_lxlost = 0;
+
+#ifdef CONFIG_IPIPE
+unsigned int __ipipe_mach_ticks_per_jiffy;
+EXPORT_SYMBOL(__ipipe_mach_ticks_per_jiffy);
+
+int __ipipe_mach_timerint = IRQ_TIMER4;
+EXPORT_SYMBOL(__ipipe_mach_timerint);
+
+static unsigned long long __ipipe_mach_tsc = 0;
+static unsigned long timer_ackval = 1UL << (IRQ_TIMER4 - IRQ_EINT0);
+static DEFINE_SPINLOCK(timer_lock);
+
+int __ipipe_mach_timerstolen = 0;
+EXPORT_SYMBOL(__ipipe_mach_timerstolen);
+#endif /* CONFIG_IPIPE */
/* timer_mask_usec_ticks
*
@@ -85,44 +105,46 @@ static inline unsigned long timer_ticks_
return res >> TIMER_USEC_SHIFT;
}
-/***
- * Returns microsecond since last clock interrupt. Note that interrupts
- * will have been disabled by do_gettimeoffset()
- * IRQs are disabled before entering here from do_gettimeofday()
- */
-
-#define SRCPND_TIMER4 (1<<(IRQ_TIMER4 - IRQ_EINT0))
-static unsigned long s3c2410_gettimeoffset (void)
+static inline unsigned long timer_freerunning_getvalue(void)
{
- unsigned long tdone;
- unsigned long irqpend;
- unsigned long tval;
-
- /* work out how many ticks have gone since last timer interrupt */
+ return __raw_readl(S3C2410_TCNTO(3));
+}
- tval = __raw_readl(S3C2410_TCNTO(4));
- tdone = timer_startval - tval;
+static inline unsigned long timer_freerunning_getticksoffset(unsigned long tval)
+{
+ long tdone;
- /* check to see if there is an interrupt pending */
+ tdone = last_free_running_tcnt - tval;
+ if (tdone < 0)
+ tdone += 0x10000;
- irqpend = __raw_readl(S3C2410_SRCPND);
- if (irqpend & SRCPND_TIMER4) {
- /* re-read the timer, and try and fix up for the missed
- * interrupt. Note, the interrupt may go off before the
- * timer has re-loaded from wrapping.
- */
+ return tdone;
+}
- tval = __raw_readl(S3C2410_TCNTO(4));
- tdone = timer_startval - tval;
+static inline unsigned long getticksoffset(void)
+{
+ return timer_freerunning_getticksoffset(timer_freerunning_getvalue());
+}
- if (tval != 0)
- tdone += timer_startval;
- }
+#ifdef CONFIG_IPIPE
+static inline unsigned long getticksoffset_tscupdate(void)
+{
+ unsigned long tval;
+ unsigned long ticks;
- return timer_ticks_to_usec(tdone);
+ tval = timer_freerunning_getvalue();
+ ticks = timer_freerunning_getticksoffset(tval);
+ last_free_running_tcnt = tval;
+ __ipipe_mach_tsc += ticks;
+ return ticks;
}
+#endif /* CONFIG_IPIPE */
+static unsigned long s3c2410_gettimeoffset (void)
+{
+ return timer_ticks_to_usec(timer_lxlost + getticksoffset());
+}
/*
* IRQ handler for the timer
@@ -131,6 +153,14 @@ static irqreturn_t
s3c2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
write_seqlock(&xtime_lock);
+
+#ifdef CONFIG_IPIPE
+ timer_lxlost = 0;
+
+ if (!__ipipe_mach_timerstolen)
+ getticksoffset_tscupdate();
+#endif /* CONFIG_IPIPE */
+
timer_tick(regs);
write_sequnlock(&xtime_lock);
return IRQ_HANDLED;
@@ -143,10 +173,10 @@ static struct irqaction s3c2410_timer_ir
};
/*
- * Set up timer interrupt, and return the current time in seconds.
+ * Set up timer interrupt.
*
- * Currently we only use timer4, as it is the only timer which has no
- * other function that can be exploited externally
+ * Currently we use timer4 as event timer and timer3 as tick counter which
+ * permanently counts ticks without interrupt generation.
*/
static void s3c2410_timer_setup (void)
{
@@ -154,6 +184,7 @@ static void s3c2410_timer_setup (void)
unsigned long tcnt;
unsigned long tcfg1;
unsigned long tcfg0;
+ unsigned long intmask;
tcnt = 0xffff; /* default value for tcnt */
@@ -170,8 +201,8 @@ static void s3c2410_timer_setup (void)
timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
tcnt = 12000000 / HZ;
- tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
- tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
+ tcfg1 &= ~(S3C2410_TCFG1_MUX4_MASK | S3C2410_TCFG1_MUX3_MASK);
+ tcfg1 |= (S3C2410_TCFG1_MUX4_TCLK1 | S3C2410_TCFG1_MUX3_TCLK1);
} else {
unsigned long pclk;
struct clk *clk;
@@ -200,8 +231,8 @@ static void s3c2410_timer_setup (void)
timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
- tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
- tcfg1 |= S3C2410_TCFG1_MUX4_DIV2;
+ tcfg1 &= ~(S3C2410_TCFG1_MUX4_MASK | S3C2410_TCFG1_MUX3_MASK);
+ tcfg1 |= (S3C2410_TCFG1_MUX4_DIV2 | S3C2410_TCFG1_MUX3_DIV2);
tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
tcfg0 |= ((6 - 1) / 2) << S3C2410_TCFG_PRESCALER1_SHIFT;
@@ -209,6 +240,10 @@ static void s3c2410_timer_setup (void)
tcnt = (pclk / 6) / HZ;
}
+#ifdef CONFIG_IPIPE
+ __ipipe_mach_ticks_per_jiffy = tcnt;
+#endif /* CONFIG_IPIPE */
+
/* timers reload after counting zero, so reduce the count by 1 */
tcnt--;
@@ -225,23 +260,37 @@ static void s3c2410_timer_setup (void)
__raw_writel(tcfg1, S3C2410_TCFG1);
__raw_writel(tcfg0, S3C2410_TCFG0);
- timer_startval = tcnt;
- __raw_writel(tcnt, S3C2410_TCNTB(4));
-
- /* ensure timer is stopped... */
+ /* ensure timers are stopped... */
+ tcon &= ~(0x3f<<17);
+ __raw_writel(tcon, S3C2410_TCON);
- tcon &= ~(7<<20);
- tcon |= S3C2410_TCON_T4RELOAD;
- tcon |= S3C2410_TCON_T4MANUALUPD;
+ /* Mask timer3 interrupt. */
+ intmask = __raw_readl(S3C2410_INTMSK);
+ intmask |= 1UL << (IRQ_TIMER3 - IRQ_EINT0);
+ __raw_writel(intmask, S3C2410_INTMSK);
- __raw_writel(tcon, S3C2410_TCON);
+ /* Set timer values */
__raw_writel(tcnt, S3C2410_TCNTB(4));
__raw_writel(tcnt, S3C2410_TCMPB(4));
+ __raw_writel(0xffff, S3C2410_TCNTB(3));
+ __raw_writel(0xffff, S3C2410_TCMPB(3));
+
+ /* Set base tcon value for later programming of timer 4 by Xenomai. */
+ free_running_tcon = tcon | S3C2410_TCON_T3RELOAD | S3C2410_TCON_T3START;
+
+ /* Set auto reloads for both timers. */
+ tcon |= S3C2410_TCON_T3RELOAD | S3C2410_TCON_T4RELOAD;
+
+ /* Manual update */
+ __raw_writel(tcon | S3C2410_TCON_T3MANUALUPD
+ | S3C2410_TCON_T4MANUALUPD, S3C2410_TCON);
- /* start the timer running */
- tcon |= S3C2410_TCON_T4START;
- tcon &= ~S3C2410_TCON_T4MANUALUPD;
+ tcon |= S3C2410_TCON_T3START | S3C2410_TCON_T4START;
+ /* Start timers.*/
__raw_writel(tcon, S3C2410_TCON);
+
+ /* Save start value of timer 3 as begining of first period. */
+ last_free_running_tcnt = 0xffff;
}
static void __init s3c2410_timer_init (void)
@@ -255,3 +304,56 @@ struct sys_timer s3c24xx_timer = {
.offset = s3c2410_gettimeoffset,
.resume = s3c2410_timer_setup
};
+
+#ifdef CONFIG_IPIPE
+void __ipipe_mach_acktimer(void)
+{
+ __raw_writel(timer_ackval, S3C2410_SRCPND);
+ __raw_writel(timer_ackval, S3C2410_INTPND);
+}
+
+notrace unsigned long long __ipipe_mach_get_tsc(void)
+{
+ unsigned long long result;
+ unsigned long flags;
+
+ spin_lock_irqsave_hw(&timer_lock, flags);
+ result = __ipipe_mach_tsc + getticksoffset();
+ spin_unlock_irqrestore_hw(&timer_lock, flags);
+ return result;
+}
+EXPORT_SYMBOL(__ipipe_mach_get_tsc);
+
+static inline void set_dec(unsigned long reload)
+{
+ __raw_writel(reload, S3C2410_TCNTB(4));
+ /* Manual update */
+ __raw_writel(free_running_tcon | S3C2410_TCON_T4MANUALUPD, S3C2410_TCON);
+ /* Start timer */
+ __raw_writel(free_running_tcon | S3C2410_TCON_T4START, S3C2410_TCON);
+}
+
+void __ipipe_mach_set_dec(unsigned long reload)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave_hw(&timer_lock, flags);
+ timer_lxlost += getticksoffset_tscupdate();
+ set_dec(reload);
+ spin_unlock_irqrestore_hw(&timer_lock, flags);
+}
+EXPORT_SYMBOL(__ipipe_mach_set_dec);
+
+void __ipipe_mach_release_timer(void)
+{
+ free_running_tcon |= S3C2410_TCON_T4RELOAD;
+ __ipipe_mach_set_dec(__ipipe_mach_ticks_per_jiffy - 1);
+ free_running_tcon &= ~S3C2410_TCON_T4RELOAD;
+}
+EXPORT_SYMBOL(__ipipe_mach_release_timer);
+
+unsigned long __ipipe_mach_get_dec(void)
+{
+ return __raw_readl(S3C2410_TCNTO(4));
+}
+#endif /* CONFIG_IPIPE */
diff -upNr linux-2.6.15-ipipe.orig/arch/arm/mach-sa1100/time.c linux-2.6.15-ipipe/arch/arm/mach-sa1100/time.c
--- linux-2.6.15-ipipe.orig/arch/arm/mach-sa1100/time.c 2006-09-10 17:13:35.000000000 +0200
+++ linux-2.6.15-ipipe/arch/arm/mach-sa1100/time.c 2006-12-18 15:44:59.000000000 +0100
@@ -263,7 +263,7 @@ void __ipipe_mach_acktimer(void)
OSSR = OSSR_M0; /* Clear match on timer 0 */
}
-unsigned long long __ipipe_mach_get_tsc(void)
+notrace unsigned long long __ipipe_mach_get_tsc(void)
{
if (likely(sa1100_timer_initialized)) {
static union {
@@ -314,6 +314,12 @@ void __ipipe_mach_set_dec(unsigned long
}
EXPORT_SYMBOL(__ipipe_mach_set_dec);
+void __ipipe_mach_release_timer(void)
+{
+ __ipipe_mach_set_dec(__ipipe_mach_ticks_per_jiffy);
+}
+EXPORT_SYMBOL(__ipipe_mach_release_timer);
+
unsigned long __ipipe_mach_get_dec(void)
{
return OSMR0 - OSCR;
diff -upNr linux-2.6.15-ipipe.orig/include/asm-arm/arch-s3c2410/irqs.h linux-2.6.15-ipipe/include/asm-arm/arch-s3c2410/irqs.h
--- linux-2.6.15-ipipe.orig/include/asm-arm/arch-s3c2410/irqs.h 2006-01-03 04:21:10.000000000 +0100
+++ linux-2.6.15-ipipe/include/asm-arm/arch-s3c2410/irqs.h 2006-11-30 12:20:22.000000000 +0100
@@ -3,6 +3,8 @@
* Copyright (c) 2003-2005 Simtec Electronics
* Ben Dooks <[EMAIL PROTECTED]>
*
+ * Copyright (C) 2006 Sebastian Smolorz <[EMAIL PROTECTED]>, emlix GmbH
+ *
* 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
* published by the Free Software Foundation.
@@ -13,6 +15,7 @@
* 12-Mar-2004 BJD Fixed bug in header protection
* 10-Feb-2005 BJD Added camera IRQ from [EMAIL PROTECTED]
* 28-Feb-2005 BJD Updated s3c2440 IRQs
+ * 30-Oct-2006 Added Adeos/I-pipe support
*/
@@ -123,4 +126,26 @@
#define NR_IRQS (IRQ_S3C2440_AC97+1)
+#ifdef CONFIG_IPIPE
+#define __ipipe_irqbit(irq) (1 << ((irq) - S3C2410_CPUIRQ_OFFSET))
+
+#ifdef CONFIG_CPU_S3C2440
+#define __ipipe_muxed_irqmask (__ipipe_irqbit(IRQ_UART0) | \
+ __ipipe_irqbit(IRQ_UART1) | \
+ __ipipe_irqbit(IRQ_UART2) | \
+ __ipipe_irqbit(IRQ_ADCPARENT) | \
+ __ipipe_irqbit(IRQ_WDT) | \
+ __ipipe_irqbit(IRQ_CAM))
+#else /* !CONFIG_CPU_S3C2440 */
+#define __ipipe_muxed_irqmask (__ipipe_irqbit(IRQ_UART0) | \
+ __ipipe_irqbit(IRQ_UART1) | \
+ __ipipe_irqbit(IRQ_UART2) | \
+ __ipipe_irqbit(IRQ_ADCPARENT))
+#endif /* CONFIG_CPU_S3C2440 */
+
+#define __ipipe_mach_irq_mux_p(irq) ((irq) <= IRQ_ADCPARENT && \
+ (__ipipe_irqbit(irq) & \
+ __ipipe_muxed_irqmask))
+#endif /* CONFIG_IPIPE */
+
#endif /* __ASM_ARCH_IRQ_H */
diff -upNr linux-2.6.15-ipipe.orig/include/asm-arm/ipipe.h linux-2.6.15-ipipe/include/asm-arm/ipipe.h
--- linux-2.6.15-ipipe.orig/include/asm-arm/ipipe.h 2006-11-12 20:33:33.000000000 +0100
+++ linux-2.6.15-ipipe/include/asm-arm/ipipe.h 2006-12-18 15:40:04.000000000 +0100
@@ -95,6 +95,13 @@ do { \
#define IPIPE_LAST_EVENT IPIPE_EVENT_CLEANUP
#define IPIPE_NR_EVENTS (IPIPE_LAST_EVENT + 1)
+extern unsigned long arm_return_addr(int level);
+
+#define BROKEN_BUILTIN_RETURN_ADDRESS
+#define __BUILTIN_RETURN_ADDRESS0 arm_return_addr(0)
+#define __BUILTIN_RETURN_ADDRESS1 arm_return_addr(1)
+
+
struct ipipe_domain;
struct ipipe_sysinfo {
@@ -117,6 +124,7 @@ extern unsigned int __ipipe_mach_ticks_p
extern void __ipipe_mach_acktimer(void);
extern unsigned long long __ipipe_mach_get_tsc(void);
extern void __ipipe_mach_set_dec(unsigned long);
+extern void __ipipe_mach_release_timer(void);
extern unsigned long __ipipe_mach_get_dec(void);
extern void __ipipe_mach_demux_irq(unsigned irq, struct pt_regs *regs);
@@ -124,7 +132,8 @@ extern void __ipipe_mach_demux_irq(unsig
#define __ipipe_read_timebase() __ipipe_mach_get_tsc()
#define ipipe_cpu_freq() (HZ * __ipipe_mach_ticks_per_jiffy)
-#define ipipe_tsc2ns(t) (((t) * 1000) / (ipipe_cpu_freq() / 1000000))
+#define ipipe_tsc2ns(t) (((unsigned long)(t) * 1000) / (ipipe_cpu_freq() / 1000000))
+#define ipipe_tsc2us(t) (((unsigned long)(t)) / (ipipe_cpu_freq() / 1000000))
/* Private interface -- Internal use only */
diff -upNr linux-2.6.15-ipipe.orig/include/asm-arm/system.h linux-2.6.15-ipipe/include/asm-arm/system.h
--- linux-2.6.15-ipipe.orig/include/asm-arm/system.h 2006-10-21 00:08:28.000000000 +0200
+++ linux-2.6.15-ipipe/include/asm-arm/system.h 2006-12-04 17:27:24.000000000 +0100
@@ -177,7 +177,7 @@ do { \
*/
#if __LINUX_ARM_ARCH__ >= 6
-#define local_irq_save_hw(x) \
+#define local_irq_save_hw_notrace(x) \
({ \
__asm__ __volatile__( \
"mrs %0, cpsr @ local_irq_save_hw\n" \
@@ -195,7 +195,7 @@ do { \
/*
* Save the current interrupt enable state & disable IRQs
*/
-#define local_irq_save_hw(x) \
+#define local_irq_save_hw_notrace(x) \
({ \
unsigned long temp; \
(void) (&temp == &x); \
@@ -211,7 +211,7 @@ do { \
/*
* Enable IRQs
*/
-#define local_irq_enable_hw() \
+#define local_irq_enable_hw_notrace() \
({ \
unsigned long temp; \
__asm__ __volatile__( \
@@ -226,7 +226,7 @@ do { \
/*
* Disable IRQs
*/
-#define local_irq_disable_hw() \
+#define local_irq_disable_hw_notrace() \
({ \
unsigned long temp; \
__asm__ __volatile__( \
@@ -241,7 +241,7 @@ do { \
/*
* Enable FIQs
*/
-#define local_fiq_enable_hw() \
+#define local_fiq_enable_hw_notrace() \
({ \
unsigned long temp; \
__asm__ __volatile__( \
@@ -256,7 +256,7 @@ do { \
/*
* Disable FIQs
*/
-#define local_fiq_disable_hw() \
+#define local_fiq_disable_hw_notrace() \
({ \
unsigned long temp; \
__asm__ __volatile__( \
@@ -283,7 +283,7 @@ do { \
/*
* restore saved IRQ & FIQ state
*/
-#define local_irq_restore_hw(x) \
+#define local_irq_restore_hw_notrace(x) \
__asm__ __volatile__( \
"msr cpsr_c, %0 @ local_irq_restore_hw\n"\
: \
@@ -306,6 +306,8 @@ unsigned long __ipipe_test_root(void);
unsigned long __ipipe_test_and_stall_root(void);
void __ipipe_restore_root(unsigned long flags);
+#define local_test_iflag_hw(x) (!((x) & PSR_I_BIT))
+
/* PSR_I_BIT is bit no. 7 and is set if interrupts are _disabled_ */
#define local_irq_save(flags) ((flags) = __ipipe_test_and_stall_root() << 7)
#define local_irq_enable() __ipipe_unstall_root()
@@ -317,15 +319,62 @@ void __ipipe_restore_root(unsigned long
#define irqs_disabled() __ipipe_test_root()
+#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
+
+#include <linux/ipipe_trace.h>
+
+#define local_irq_disable_hw() do { \
+ if (!irqs_disabled_hw()) { \
+ local_irq_disable_hw_notrace(); \
+ ipipe_trace_begin(0x80000000); \
+ } \
+} while (0)
+#define local_irq_enable_hw() do { \
+ if (irqs_disabled_hw()) { \
+ ipipe_trace_end(0x80000000); \
+ local_irq_enable_hw_notrace(); \
+ } \
+} while (0)
+#define local_irq_save_hw(x) do { \
+ local_save_flags_hw(x); \
+ if (local_test_iflag_hw(x)) { \
+ local_irq_disable_hw_notrace(); \
+ ipipe_trace_begin(0x80000001); \
+ } \
+} while (0)
+#define local_irq_restore_hw(x) do { \
+ if (local_test_iflag_hw(x)) \
+ ipipe_trace_end(0x80000001); \
+ local_irq_restore_hw_notrace(x); \
+} while (0)
+
+#else /* !CONFIG_IPIPE_TRACE_IRQSOFF */
+
+#define local_irq_save_hw(flags) local_irq_save_hw_notrace(flags)
+#define local_irq_enable_hw() local_irq_enable_hw_notrace()
+#define local_irq_disable_hw() local_irq_disable_hw_notrace()
+#define local_fiq_enable_hw() local_fiq_enable_hw_notrace()
+#define local_fiq_disable_hw() local_fiq_disable_hw_notrace()
+#define local_irq_restore_hw(flags) local_irq_restore_hw_notrace(flags)
+
+#endif /* CONFIG_IPIPE_TRACE_IRQSOFF */
+
#else /* !CONFIG_IPIPE */
-#define local_irq_save(flags) local_irq_save_hw(flags)
-#define local_irq_enable() local_irq_enable_hw()
-#define local_irq_disable() local_irq_disable_hw()
-#define local_fiq_enable() local_fiq_enable_hw()
-#define local_fiq_disable() local_fiq_disable_hw()
-#define local_save_flags(flags) local_save_flags_hw(flags)
-#define local_irq_restore(flags) local_irq_restore_hw(flags)
+#define local_irq_save(flags) local_irq_save_hw_notrace(flags)
+#define local_irq_enable() local_irq_enable_hw_notrace()
+#define local_irq_disable() local_irq_disable_hw_notrace()
+#define local_fiq_enable() local_fiq_enable_hw_notrace()
+#define local_fiq_disable() local_fiq_disable_hw_notrace()
+#define local_save_flags(flags) local_save_flags_hw(flags)
+#define local_irq_restore(flags) local_irq_restore_hw_notrace(flags)
+
+#define local_irq_save_hw(flags) local_irq_save_hw_notrace(flags)
+#define local_irq_enable_hw() local_irq_enable_hw_notrace()
+#define local_irq_disable_hw() local_irq_disable_hw_notrace()
+#define local_fiq_enable_hw() local_fiq_enable_hw_notrace()
+#define local_fiq_disable_hw() local_fiq_disable_hw_notrace()
+#define local_irq_restore_hw(flags) local_irq_restore_hw_notrace(flags)
#define irqs_disabled() irqs_disabled_hw()
diff -upNr linux-2.6.15-ipipe.orig/include/linux/ipipe.h linux-2.6.15-ipipe/include/linux/ipipe.h
--- linux-2.6.15-ipipe.orig/include/linux/ipipe.h 2006-10-15 16:28:49.000000000 +0200
+++ linux-2.6.15-ipipe/include/linux/ipipe.h 2006-12-14 09:58:24.000000000 +0100
@@ -38,7 +38,7 @@
#ifndef BROKEN_BUILTIN_RETURN_ADDRESS
#define __BUILTIN_RETURN_ADDRESS0 ((unsigned long)__builtin_return_address(0))
#define __BUILTIN_RETURN_ADDRESS1 ((unsigned long)__builtin_return_address(1))
-#endif /* !BUILTIN_RETURN_ADDRESS */
+#endif /* !BROKEN_BUILTIN_RETURN_ADDRESS */
#define IPIPE_ROOT_PRIO 100
#define IPIPE_ROOT_ID 0
diff -upNr linux-2.6.15-ipipe.orig/kernel/ipipe/tracer.c linux-2.6.15-ipipe/kernel/ipipe/tracer.c
--- linux-2.6.15-ipipe.orig/kernel/ipipe/tracer.c 2006-10-12 20:08:50.000000000 +0200
+++ linux-2.6.15-ipipe/kernel/ipipe/tracer.c 2006-12-06 16:53:23.000000000 +0100
@@ -100,12 +100,10 @@ enum ipipe_trace_type
#ifdef CONFIG_IPIPE_TRACE_VMALLOC
-#define IPIPE_DEFAULT_TRACE_STATE 0
static struct ipipe_trace_path *trace_paths[NR_CPUS];
#else /* !CONFIG_IPIPE_TRACE_VMALLOC */
-#define IPIPE_DEFAULT_TRACE_STATE CONFIG_IPIPE_TRACE_ENABLE_VALUE
static struct ipipe_trace_path trace_paths[NR_CPUS][IPIPE_TRACE_PATHS] =
{ [0 ... NR_CPUS-1] =
@@ -115,7 +113,7 @@ static struct ipipe_trace_path trace_pat
};
#endif /* CONFIG_IPIPE_TRACE_VMALLOC */
-int ipipe_trace_enable = IPIPE_DEFAULT_TRACE_STATE;
+int ipipe_trace_enable = 0;
static int active_path[NR_CPUS] =
{ [0 ... NR_CPUS-1] = IPIPE_DEFAULT_ACTIVE };
@@ -1217,8 +1215,8 @@ void __init __ipipe_init_tracer(void)
trace_paths[cpu][path].end = -1;
}
}
- ipipe_trace_enable = CONFIG_IPIPE_TRACE_ENABLE_VALUE;
#endif /* CONFIG_IPIPE_TRACE_VMALLOC */
+ ipipe_trace_enable = CONFIG_IPIPE_TRACE_ENABLE_VALUE;
trace_dir = create_proc_entry("trace", S_IFDIR, ipipe_proc_root);
Index: ChangeLog
===================================================================
--- ChangeLog (Revision 1966)
+++ ChangeLog (Arbeitskopie)
@@ -1,3 +1,8 @@
+2006-12-18 Sebastian Smolorz <[EMAIL PROTECTED]>
+
+ * ksrc/arch/arm/hal.c: Introduce __ipipe_mach_release_timer()
+ according to changes in I-pipe for ARM
+
2006-12-18 Jan Kiszka <[EMAIL PROTECTED]>
* scripts/xeno-test.in, src/testsuite/*: Install testsuite binaries
Index: ksrc/arch/arm/hal.c
===================================================================
--- ksrc/arch/arm/hal.c (Revision 1966)
+++ ksrc/arch/arm/hal.c (Arbeitskopie)
@@ -94,7 +94,7 @@ void rthal_timer_release(void)
if (rthal_periodic_p)
rthal_reset_timer();
else
- __ipipe_mach_set_dec(__ipipe_mach_ticks_per_jiffy);
+ __ipipe_mach_release_timer();
rthal_irq_release(RTHAL_TIMER_IRQ);
_______________________________________________
Adeos-main mailing list
[email protected]
https://mail.gna.org/listinfo/adeos-main