All of lore.kernel.org
 help / color / mirror / Atom feed
From: garryt <garryt@domain.hid>
To: xenomai@xenomai.org
Subject: [Xenomai-help] imx1 port.
Date: Mon, 29 Oct 2007 13:54:19 +0100	[thread overview]
Message-ID: <1193662459.4725d7fbcf9e6@domain.hid> (raw)

[-- 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 */

             reply	other threads:[~2007-10-29 12:54 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-29 12:54 garryt [this message]
2007-10-29 13:38 ` [Xenomai-help] imx1 port Gilles Chanteperdrix
2007-10-29 16:30   ` garryt
2007-10-29 16:46     ` Gilles Chanteperdrix

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1193662459.4725d7fbcf9e6@domain.hid \
    --to=garryt@domain.hid \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.