All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-help] imx1 port.
@ 2007-10-29 12:54 garryt
  2007-10-29 13:38 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 4+ messages in thread
From: garryt @ 2007-10-29 12:54 UTC (permalink / raw)
  To: xenomai

[-- Attachment #1: Type: text/plain, Size: 4251 bytes --]

Hello all,

I had time to try again adeos+xenomai on a imx1 board. (i know this is quite
old).

This looks stable, i have been testing for several hours.

I have followed the wiki documentation and performed some tests with xeno-test +
ping flooding on this board, again i have no other *similar* board to compare
results with, but here they are.

I wonder if the difference between user-mode and in-kernel mode should be as
much as this...

By the way enabling ipipe tracer increase response time by a factor 2! is this
ok with such HW ?

I have attached the patch if someone is interested in, any remarks regarding
this are welcome.


All tests have been performed with xeno-test +  ping flooding the board.

----
# cat /proc/ipipe/version
1.7-06
# cat /proc/xenomai/version
2.3.4


running: ./run -- -p 500 -T 120 -t0 # latency
*
*
* Type ^C to stop this application.
*
*
== Sampling period: 500 us
== Test mode: periodic user-mode task
== All results in microseconds
warming up...
RTT|  00:00:01  (periodic user-mode task, 500 us period, priority 99)
RTH|-----lat min|-----lat avg|-----lat max|-overrun|----lat best|---lat worst
RTD|      83.062|     116.437|     125.437|       0|      83.062|     125.437
RTD|      54.500|     118.375|     141.437|       0|      54.500|     141.437
RTD|      53.437|     120.187|     145.500|       0|      53.437|     145.500
RTD|      50.312|     119.375|     149.000|       0|      50.312|     149.000
RTD|      55.562|     116.375|     124.750|       0|      50.312|     149.000
...
---|------------|------------|------------|--------|-------------------------
RTS|      45.250|     118.500|     150.937|       0|    00:02:00/00:02:00

Thu Jan  1 00:24:02 GMT 1970
running: ./run -- -p 500 -T 120 -t1 # latency
*
*
* Type ^C to stop this application.
*
*
== Sampling period: 500 us
== Test mode: in-kernel periodic task
== All results in microseconds
warming up...
RTT|  00:00:01  (in-kernel periodic task, 500 us period, priority 99)
RTH|-----lat min|-----lat avg|-----lat max|-overrun|----lat best|---lat worst
RTD|       8.812|      19.329|      57.625|       0|       8.812|      57.625
RTD|       8.812|      15.628|      57.125|       0|       8.812|      57.625
RTD|       8.812|      16.827|      70.562|       0|       8.812|      70.562
RTD|       8.812|      29.156|      56.562|       0|       8.812|      70.562
...
RTS|       8.437|      17.812|      78.437|       0|    00:02:00/00:02:00

Thu Jan  1 00:26:09 GMT 1970
running: ./run -- -p 500 -T 120 -t2 # latency
*
*
* Type ^C to stop this application.
*
*
== Sampling period: 500 us
== Test mode: in-kernel timer handler
== All results in microseconds
warming up...
RTT|  00:00:01  (in-kernel timer handler, 500 us period, priority 99)
RTH|-----lat min|-----lat avg|-----lat max|-overrun|----lat best|---lat worst
RTD|       1.250|       7.492|      21.000|       0|       1.250|      21.000
RTD|       1.250|       5.211|      27.375|       0|       1.250|      27.375
RTD|       1.312|       5.299|      28.812|       0|       1.250|      28.812
...
RTS|       1.187|       4.335|      44.437|       0|    00:02:00/00:02:00

Thu Jan  1 00:28:15 GMT 1970
running: ./run -- -T 120 # switchtest
*
*
* Type ^C to stop this application.
*
*
== Testing FPU check routines...
== FPU check routines: unimplemented, skipping FPU switches tests.
== Threads: sleeper-0 rtk-1 rtk-2 rtup-3 rtup-4 rtus-5 rtus-6 rtuo-7 rtuo-8
RTT|  00:00:01
RTH|ctx switches|-------total
RTD|         900|         900
RTD|         900|        1800
RTD|         909|        2709
...

running: ./run -- -p 500 -h # switchbench
*
*
* Type ^C to stop this application.
*
*
== Sampling period: 500 us
== Do not interrupt this program
RTH|     lat min|     lat avg|     lat max|        lost
RTD|      47.937|      50.250|      88.687|           0
---|---range-|---samples
HSD| 47 - 48 |          1
HSD| 48 - 49 |      40757
HSD| 49 - 50 |      55940
HSD| 50 - 51 |          9
HSD| 67 - 68 |          1
HSD| 68 - 69 |          4
HSD| 86 - 87 |         75
HSD| 87 - 88 |       2741
HSD| 88 - 89 |        468
HSS|     99996|     49.845|      6.888


[-- Attachment #2: 100-linux-2.6.20-adeos-ipipe.diff --]
[-- Type: application/octet-stream, Size: 11292 bytes --]

--- linux-2.6.20.12/include/asm-arm/arch-imx/irqs.h	2007-05-24 23:21:02.000000000 +0200
+++ linux-2.6.20.12-ipipe/include/asm-arm/arch-imx/irqs.h	2007-07-04 11:47:34.000000000 +0200
@@ -113,4 +113,17 @@
 
 #define NR_IRQS (IRQ_GPIOD(32) + 1)
 #define IRQ_GPIO(x)
+
+#ifdef CONFIG_IPIPE
+#define __ipipe_irqbit(irq) (1ULL << (irq))
+
+#define __ipipe_muxed_irqmask (__ipipe_irqbit(GPIO_INT_PORTA) | \
+                               __ipipe_irqbit(GPIO_INT_PORTB) | \
+                               __ipipe_irqbit(GPIO_INT_PORTC) | \
+                               __ipipe_irqbit(GPIO_INT_PORTD))
+
+#define __ipipe_mach_irq_mux_p(irq) (__ipipe_irqbit(irq) \
+                                     & __ipipe_muxed_irqmask)
+#endif /* CONFIG_IPIPE */         
+
 #endif
--- linux-2.6.20.12/include/asm-arm/arch-imx/imx-regs.h	2007-09-05 11:58:55.000000000 +0200
+++ linux-2.6.20.12-ipipe/include/asm-arm/arch-imx/imx-regs.h	2007-05-31 14:36:31.000000000 +0200
@@ -345,7 +345,16 @@
 #define IMX_INTDISNUM      __REG(IMX_AITC_BASE+0x0c)
 #define IMX_INTENABLEH     __REG(IMX_AITC_BASE+0x10)
 #define IMX_INTENABLEL     __REG(IMX_AITC_BASE+0x14)
+#define IMX_PRIO7          __REG(IMX_AITC_BASE+0x20)
+#define IMX_PRIO6          __REG(IMX_AITC_BASE+0x24)
+#define IMX_PRIO5          __REG(IMX_AITC_BASE+0x28)
+#define IMX_PRIO4          __REG(IMX_AITC_BASE+0x2C)
+#define IMX_PRIO3          __REG(IMX_AITC_BASE+0x30)
+#define IMX_PRIO2          __REG(IMX_AITC_BASE+0x34)
+#define IMX_PRIO1          __REG(IMX_AITC_BASE+0x38)
+#define IMX_PRIO0          __REG(IMX_AITC_BASE+0x3C)
 
+#define IMX_PRIO(x)	   __REG2(IMX_AITC_BASE+0x20,((7-((x)>>3)) <<2) ) 
 /*
  *  General purpose timers
  */
@@ -415,6 +424,7 @@
 #define PCR_BPIX_8      (3<<25)
 #define PCR_BPIX_12     (4<<25)
 #define PCR_BPIX_16     (4<<25)
+#define PCR_BPIX_MASK   (7<<25)
 #define PCR_PIXPOL      (1<<24)
 #define PCR_FLMPOL      (1<<23)
 #define PCR_LPPOL       (1<<22)
--- linux-2.6.20.12/arch/arm/mach-imx/irq.c	2007-09-05 16:28:42.000000000 +0200
+++ linux-2.6.20.12/arch/arm/mach-imx/irq.c	2007-09-05 16:36:02.000000000 +0200
@@ -26,12 +26,87 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/timer.h>
+#ifdef CONFIG_IPIPE
+#include <linux/ipipe.h>
+#endif /* CONFIG_IPIPE */
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 
 #include <asm/mach/irq.h>
+#include <asm/arch/imx-regs.h>
+
+/* Used for IMX INTERRUPT priority: Still Experimental */ 
+#ifdef CONFIG_IPIPE 
+
+static unsigned int imx_default_irq_priority[IMX_IRQS] __initdata = {
+        0, /* unused */
+        0, /* unused */
+        0, /* unused */
+        0, /* unused */
+        0, /* unused */
+        0, /* unused */
+        5, /* Common Sensor Interface */
+        5, /* Multimedia Accelerator MAC */
+        5, /* Multimedia Accelerator */
+        0, /* unused */
+        5, /* MS */    
+        4, /* GPIO Port A */
+        4, /* GPIO Port B */
+        4, /* GPIO Port C */                 
+        5,  /* LCDC */   
+        0, /* unused */
+        0, /* unused */
+        7, /* RTC */
+        7, /* RTC */
+        5, /* UART 2 PFerr*/
+        5, /* UART 2 RTS */
+        5, /* UART 2 DTR */
+        5, /* UART 2 UARTC*/
+        5, /* UART 2 Tx*/
+        5, /* UART 2 Rx*/
+        5, /* UART 1 PFerr*/
+        5, /* UART 1 RTS */
+        5, /* UART 1 DTR */
+        5, /* UART 1 UARTC*/
+        5, /* UART 1 Tx*/
+        5, /* UART 1 Rx*/
+        0, /* unused */
+        0, /* unused */
+        0, /* unused */
+        5,/* PWM */
+        5, /* MMC */
+        0, /* unused */
+        0, /* unused */
+        0, /* unused */
+        5, /* I2C */
+        5, /*SPI 2 */
+        5, /*SPI 1 */
+        5, /* SSI Tx*/
+        5, /* SSI Tx Err*/
+        5, /* SSI Rx */
+        5, /* SSI Rx Err*/
+        0, /* unused */
+        5, /* USB0 */
+        5, /* USB1 */
+        5, /* USB2 */
+        5, /* USB3 */
+        5, /* USB4 */
+        5, /* USB5 */
+        5, /* USB6 */
+        0, /* unused */
+        0, /* unused */
+        0, /* unused */
+        0, /* unused */
+        5, /* Timer2 */
+        15, /* Timer1 This is use by IPIPE */
+        12, /* DMA Err */
+        12, /* DMA */
+        4, /* GPIO D */
+        12 /* Watch dog */        /* Advanced Interrupt Controller (IRQ6) */
+        };
+#endif 
 
 /*
  *
@@ -222,6 +296,25 @@
 	.set_type = imx_gpio_irq_type,
 };
 
+#ifdef CONFIG_IPIPE 
+void __init imx_init_priority(void)
+{
+        unsigned int irq; 
+        IMX_PRIO0=0;   
+        IMX_PRIO1=0;     
+        IMX_PRIO2=0;
+        IMX_PRIO3=0;   
+        IMX_PRIO4=0;     
+        IMX_PRIO5=0;  
+        IMX_PRIO6=0;    
+        IMX_PRIO7=0; 
+        printk(KERN_INFO "Initializing imx interrupt priorities\n");
+        for (irq = 0; irq < IMX_IRQS; irq++) {
+	        IMX_PRIO(irq)|=((imx_default_irq_priority[irq]&15)<<((irq%8)*4));
+        }             
+}
+#endif
+
 void __init
 imx_init_irq(void)
 {
@@ -246,7 +339,9 @@
 		set_irq_handler(irq, handle_edge_irq);
 		set_irq_flags(irq, IRQF_VALID);
 	}
-
+#ifdef CONFIG_IPIPE 
+	imx_init_priority(); 
+#endif 
 	set_irq_chained_handler(GPIO_INT_PORTA, imx_gpioa_demux_handler);
 	set_irq_chained_handler(GPIO_INT_PORTB, imx_gpiob_demux_handler);
 	set_irq_chained_handler(GPIO_INT_PORTC, imx_gpioc_demux_handler);
@@ -255,3 +350,29 @@
 	/* Disable all interrupts initially. */
 	/* In IMX this is done in the bootloader. */
 }
+
+#ifdef CONFIG_IPIPE
+void __ipipe_mach_demux_irq(unsigned irq, struct pt_regs *regs)
+{
+        struct irq_desc *desc_unused = irq_desc + irq;
+        unsigned irq_unused = irq;
+        unsigned int i, mask;
+
+        /* GPPIOA, GPIOB, GPIOC, GPIOD are INT 11,12,13 and 62 */
+        i=((irq&7)-3);
+
+	/* Get all multiplexed ITs from given GPIO */
+        mask=ISR(i);
+        irq=(i<<5)+IMX_IRQS;
+        do {
+        if (mask & 1 ) {
+		__ipipe_handle_irq(irq, regs);
+		// Ack multiplexed IT from given GPIO
+		ISR(i)=1<<(irq&0x1f);
+		}
+	mask >>=1;
+	irq++;
+	} while (mask);
+	desc_unused->chip->unmask(irq_unused);
+}
+#endif /* CONFIG_IPIPE */
--- linux-2.6.20.12/arch/arm/mach-imx/time.c		2007-10-10 17:11:18.000000000 +0200
+++ linux-2.6.20.12-ipipe/arch/arm/mach-imx/time.c	2007-10-11 12:42:07.000000000 +0200
--- time.c.orig	2007-10-10 17:11:18.000000000 +0200
+++ time.c	2007-10-29 10:18:02.000000000 +0100
@@ -15,6 +15,7 @@
 #include <linux/irq.h>
 #include <linux/time.h>
 #include <linux/clocksource.h>
+#include <linux/module.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -22,6 +23,55 @@
 #include <asm/irq.h>
 #include <asm/mach/time.h>
 
+#ifdef CONFIG_IPIPE
+#ifdef CONFIG_NO_IDLE_HZ
+#error "dynamic tick timer not yet supported with IPIPE"
+#endif				/* CONFIG_NO_IDLE_HZ */
+int __ipipe_mach_timerint = TIM1_INT;
+EXPORT_SYMBOL(__ipipe_mach_timerint);
+
+int __ipipe_mach_timerstolen = 0;
+EXPORT_SYMBOL(__ipipe_mach_timerstolen);
+
+unsigned int __ipipe_mach_ticks_per_jiffy = LATCH;
+EXPORT_SYMBOL(__ipipe_mach_ticks_per_jiffy);
+
+static int imx_timer_initialized;
+static unsigned long last_jiffy_time;
+union tsc_reg {
+#ifdef __BIG_ENDIAN
+	struct {
+		unsigned long high;
+		unsigned long low;
+	};
+#else				/* __LITTLE_ENDIAN */
+	struct {
+		unsigned long low;
+		unsigned long high;
+	};
+#endif				/* __LITTLE_ENDIAN */
+	unsigned long long full;
+};
+#ifdef CONFIG_SMP
+static union tsc_reg tsc[NR_CPUS];
+
+void __ipipe_mach_get_tscinfo(struct __ipipe_tscinfo *info)
+{
+	info->type = IPIPE_TSC_TYPE_NONE;
+}
+#else				/* !CONFIG_SMP */
+static union tsc_reg *tsc;
+
+void __ipipe_mach_get_tscinfo(struct __ipipe_tscinfo *info)
+{
+	info->type = IPIPE_TSC_TYPE_FREERUNNING;
+	info->u.fr.counter = (unsigned *)(0x10 + IMX_TIM1_BASE);
+	info->u.fr.mask = 0xffffffff;
+	info->u.fr.tsc = &tsc->full;
+}
+#endif				/* !CONFIG_SMP */
+#endif				/* CONFIG_IPIPE */
+
 /* Use timer 1 as system timer */
 #define TIMER_BASE IMX_TIM1_BASE
 
@@ -30,26 +80,43 @@
 /*
  * IRQ handler for the timer
  */
-static irqreturn_t
-imx_timer_interrupt(int irq, void *dev_id)
+static irqreturn_t imx_timer_interrupt(int irq, void *dev_id)
 {
 	uint32_t tstat;
 
+#ifdef CONFIG_IPIPE
+	/*
+	 * - if Linux is running natively (no ipipe), ack and reprogram the timer
+	 * - if Linux is running under ipipe, but it still has the control over
+	 *   the timer (no Xenomai for example), then reprogram the timer (ipipe
+	 *   has already acked it)
+	 * - if some other domain has taken over the timer, then do nothing
+	 *   (ipipe has acked it, and the other domain has reprogramed it)
+	 */
+	if (__ipipe_mach_timerstolen) {
+		timer_tick();
+		last_jiffy_time += LATCH;
+	} else
+#else				/* !CONFIG_IPIPE */
 	/* clear the interrupt */
 	tstat = IMX_TSTAT(TIMER_BASE);
 	IMX_TSTAT(TIMER_BASE) = 0;
 
 	if (tstat & TSTAT_COMP) {
+#endif
 		do {
-
 			write_seqlock(&xtime_lock);
 			timer_tick();
+#ifdef CONFIG_IPIPE
+			last_jiffy_time += LATCH;
+#endif				/*  CONFIG_IPIPE */
 			write_sequnlock(&xtime_lock);
 			IMX_TCMP(TIMER_BASE) += evt_diff;
-
-		} while (unlikely((int32_t)(IMX_TCMP(TIMER_BASE)
+		} while (unlikely((int32_t) (IMX_TCMP(TIMER_BASE)
 					- IMX_TCN(TIMER_BASE)) < 0));
+#ifndef CONFIG_IPIPE
 	}
+#endif				/*  CONFIG_IPIPE */
 
 	return IRQ_HANDLED;
 }
@@ -108,8 +175,91 @@
 	 * Make irqs happen for the system timer
 	 */
 	setup_irq(TIM1_INT, &imx_timer_irq);
+
+#ifdef CONFIG_IPIPE
+#ifndef CONFIG_SMP
+	tsc = (union tsc_reg *)__ipipe_tsc_area;
+	barrier();
+#endif				/* CONFIG_SMP */
+	imx_timer_initialized = 1;
+
+#endif				/* CONFIG_IPIPE */
 }
 
 struct sys_timer imx_timer = {
 	.init		= imx_timer_init,
 };
+
+#ifdef CONFIG_IPIPE
+void __ipipe_mach_acktimer(void)
+{
+	uint32_t tstat;
+	tstat = IMX_TSTAT(TIMER_BASE);
+	IMX_TSTAT(TIMER_BASE) = 0;
+	if (likely(imx_timer_initialized)) {
+		union tsc_reg *local_tsc;
+		unsigned long stamp, flags;
+
+		local_irq_save_hw(flags);
+		local_tsc = &tsc[ipipe_processor_id()];
+		stamp = IMX_TCN(TIMER_BASE);
+		if (unlikely(stamp < local_tsc->low))
+			/* 32 bit counter wrapped, increment high word. */
+			local_tsc->high++;
+		local_tsc->low = stamp;
+		local_irq_restore_hw(flags);
+	}
+}
+
+notrace unsigned long long __ipipe_mach_get_tsc(void)
+{
+	if (likely(imx_timer_initialized)) {
+		union tsc_reg *local_tsc, result;
+		unsigned long stamp;
+
+		local_tsc = &tsc[ipipe_processor_id()];
+
+	      __asm__("ldmia %1, %M0\n":"=r"(result.full),
+			"+&r"
+			(local_tsc)
+	      :	"m"(*local_tsc));
+		barrier();
+		stamp = IMX_TCN(TIMER_BASE);
+		if (unlikely(stamp < result.low))
+			result.high++;
+		result.low = stamp;
+		return result.full;
+	}
+	return 0;
+}
+
+EXPORT_SYMBOL(__ipipe_mach_get_tsc);
+
+/*
+ * Reprogram the timer
+ */
+void __ipipe_mach_set_dec(unsigned long delay)
+{
+	unsigned long flags;
+	if (delay > 8) {
+		local_irq_save_hw(flags);
+		IMX_TCMP(TIMER_BASE) = IMX_TCN(TIMER_BASE) + delay;
+		local_irq_restore_hw(flags);
+	} else
+		ipipe_trigger_irq(TIM1_INT);
+}
+
+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 IMX_TCMP(TIMER_BASE) - IMX_TCN(TIMER_BASE);
+}
+#endif				/* CONFIG_IPIPE */

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-10-29 16:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-29 12:54 [Xenomai-help] imx1 port garryt
2007-10-29 13:38 ` Gilles Chanteperdrix
2007-10-29 16:30   ` garryt
2007-10-29 16:46     ` Gilles Chanteperdrix

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.