All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-help] Porting I-Pipe for new ARM board
@ 2009-11-03 15:00 Wael Showair
  2009-11-03 15:13 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 38+ messages in thread
From: Wael Showair @ 2009-11-03 15:00 UTC (permalink / raw)
  To: Xenomai-help; +Cc: didenkos

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

Hi All,
i have TS-7800 board based on Marvell 88F5182 processor core. Unfortunately it is not supported by I-Pipe patch so according to the following link:

http://www.xenomai.org/index.php/I-pipe:ArmPorting

And with aid of this forum thread:

http://www.mail-archive.com/xenomai-help@gna.org/msg09486.html

I have now reached to the same error:
patched Linux is starting to boot as original kernel
and it hangs right after line

"ata2: SATA max UDMA/133 irq 29"

here is the time.c file that i have edited:

************************************************************************************

/*
 * arch/arm/plat-orion/time.c
 *
 * Marvell Orion SoC timer handling.
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 *
 * Timer 0 is used as free-running clocksource, while timer 1 is
 * used as clock_event_device.
 */

#include <linux/kernel.h>
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/mach/time.h>
#include <mach/hardware.h>

/*
 * Number of timer ticks per jiffy.
 */
static u32 ticks_per_jiffy;

/*
 * Timer block registers.
 */
#define TIMER_CTRL		(TIMER_VIRT_BASE + 0x0000)
#define  TIMER0_EN		0x0001
#define  TIMER0_RELOAD_EN	0x0002
#define  TIMER1_EN		0x0004
#define  TIMER1_RELOAD_EN	0x0008
#define TIMER0_RELOAD		(TIMER_VIRT_BASE + 0x0010)
#define TIMER0_VAL		(TIMER_VIRT_BASE + 0x0014)
#define TIMER1_RELOAD		(TIMER_VIRT_BASE + 0x0018)
#define TIMER1_VAL		(TIMER_VIRT_BASE + 0x001c)

#ifdef CONFIG_IPIPE

#define MIN_TIMER1_DELTA		1

#ifdef CONFIG_NO_IDLE_HZ
#error "dynamic tick timer not yet supported with IPIPE"
#endif /* CONFIG_NO_IDLE_HZ */

/* The implementation is instead of io_v2p since the addresses are virtual addresses*/
//# define __PREG(x)    io_v2p(x)

/* #define __REG(x) (*(volatile unsigned long *)x) 
#define OSCR_0        __REG(TIMER0_VAL)     
*/


/*
 *IRQ number of hardware timer  
 *According to the board manual, tables 59 & 61
 *the timer0,1 interrupts are set in Local to System Bridge Interrupt Cause Register 
 *which in turn set bit number zero in the Main Interrupt Cause Register
 *so the __ipipe_mach_timerint variable will be set to zero or one
 */
#define IRQ_MV88FXX_ORION_BRIDGE	0
int __ipipe_mach_timerint = IRQ_MV88FXX_ORION_BRIDGE;
EXPORT_SYMBOL(__ipipe_mach_timerint);


/*TODO: what is this value really represents? is it always intialized by zero?
 * Initialized to 0, it became non zero when the hardware timer is handled by
 * Xenomai. 
 */
int __ipipe_mach_timerstolen = 0;
EXPORT_SYMBOL(__ipipe_mach_timerstolen);


/*
 * Count of hardware timer ticks between two timer interrupts, same thing as
 * the LATCH constant.
 */
unsigned int __ipipe_mach_ticks_per_jiffy = LATCH;
EXPORT_SYMBOL(__ipipe_mach_ticks_per_jiffy);

static int orion_timer_initialized = 0;

/* this union represents the shared tsc area */
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 orion_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 *orion_tsc;
#endif /* !CONFIG_SMP */

static void ipipe_mach_update_tsc(void);

#endif /* CONFIG_IPIPE */

/*
 * Clocksource handling.
 */
static cycle_t orion_clksrc_read(void)
{
	return 0xffffffff - readl(TIMER0_VAL);
}

static struct clocksource orion_clksrc = {
	.name		= "orion_clocksource",
	.shift		= 20,
	.rating		= 300,
	.read		= orion_clksrc_read,
	.mask		= CLOCKSOURCE_MASK(32),
	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
};



/*
 * Clockevent handling.
 */
static int
orion_clkevt_next_event(unsigned long delta, struct clock_event_device *dev)
{
	unsigned long flags;
	u32 u;

	if (delta == 0)
		return -ETIME;

	local_irq_save(flags);

	/*
	 * Clear and enable clockevent timer interrupt.
	 */
	writel(BRIDGE_INT_TIMER1_CLR, BRIDGE_CAUSE);

	u = readl(BRIDGE_MASK);
	u |= BRIDGE_INT_TIMER1;
	writel(u, BRIDGE_MASK);

	/*
	 * Setup new clockevent timer value.
	 */
	writel(delta, TIMER1_VAL);

	/*
	 * Enable the timer.
	 */
	u = readl(TIMER_CTRL);
	u = (u & ~TIMER1_RELOAD_EN) | TIMER1_EN;
	writel(u, TIMER_CTRL);

	local_irq_restore(flags);

	return 0;
}

static void
orion_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
{
	unsigned long flags;
	u32 u;

	local_irq_save(flags);
	if (mode == CLOCK_EVT_MODE_PERIODIC) {
		/*
		 * Setup timer to fire at 1/HZ intervals.
		 */
		writel(ticks_per_jiffy - 1, TIMER1_RELOAD);
		writel(ticks_per_jiffy - 1, TIMER1_VAL);

		/*
		 * Enable timer interrupt.
		 */
		u = readl(BRIDGE_MASK);
		writel(u | BRIDGE_INT_TIMER1, BRIDGE_MASK);

		/*
		 * Enable timer.
		 */
		u = readl(TIMER_CTRL);
		writel(u | TIMER1_EN | TIMER1_RELOAD_EN, TIMER_CTRL);
	} else {
		/*
		 * Disable timer.
		 */
		u = readl(TIMER_CTRL);
		writel(u & ~TIMER1_EN, TIMER_CTRL);

		/*
		 * Disable timer interrupt.
		 */
		u = readl(BRIDGE_MASK);
		writel(u & ~BRIDGE_INT_TIMER1, BRIDGE_MASK);

		/*
		 * ACK pending timer interrupt.
		 */
		writel(BRIDGE_INT_TIMER1_CLR, BRIDGE_CAUSE);

	}
	local_irq_restore(flags);
}

static struct clock_event_device orion_clkevt = {
	.name		= "orion_tick",
	.features	= CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
	.shift		= 32,
	.rating		= 300,
	.set_next_event	= orion_clkevt_next_event,
	.set_mode	= orion_clkevt_mode,
};

static irqreturn_t orion_timer_interrupt(int irq, void *dev_id)
{

#ifndef CONFIG_IPIPE
	/*
	 * ACK timer interrupt and call event handler.
	 */
	writel(BRIDGE_INT_TIMER1_CLR, BRIDGE_CAUSE);

#else

	ipipe_mach_update_tsc();

#endif /* CONFIG_IPIPE */



	/* hrtimer_interrupt is the event handle of the clock event device "orion_tick", i got by cat /proc/timer_list
	 * it is defined in krnl_src/kernel/hrtimer.c
	 * which does not use timer_tick in a while loop so the timer interrupt function is gonna be let as it is.
	 */
	orion_clkevt.event_handler(&orion_clkevt);

	return IRQ_HANDLED;
}

static struct irqaction orion_timer_irq = {
	.name		= "orion_tick",
	.flags		= IRQF_DISABLED | IRQF_TIMER,
	.handler	= orion_timer_interrupt
};

void __init orion_time_init(unsigned int irq, unsigned int tclk)
{
	u32 u;

#ifdef CONFIG_IPIPE
#ifndef CONFIG_SMP
	orion_tsc = (union tsc_reg *) __ipipe_tsc_area;
	barrier();
#endif /* CONFIG_SMP */

	orion_timer_initialized = 1;
#endif /* CONFIG_IPIPE */


	ticks_per_jiffy = (tclk + HZ/2) / HZ;


	/*
	 * Setup free-running clocksource timer (interrupts
	 * disabled.) using TIMER0
	 */
	writel(0xffffffff, TIMER0_VAL);
	writel(0xffffffff, TIMER0_RELOAD);
	u = readl(BRIDGE_MASK);
	writel(u & ~BRIDGE_INT_TIMER0, BRIDGE_MASK);
	u = readl(TIMER_CTRL);
	writel(u | TIMER0_EN | TIMER0_RELOAD_EN, TIMER_CTRL);
	orion_clksrc.mult = clocksource_hz2mult(tclk, orion_clksrc.shift);
	clocksource_register(&orion_clksrc);


	/*
	 * Setup clockevent timer (interrupt-driven.) using TIMER1
	 */
	setup_irq(irq, &orion_timer_irq);
	orion_clkevt.mult = div_sc(tclk, NSEC_PER_SEC, orion_clkevt.shift);
	orion_clkevt.max_delta_ns = clockevent_delta2ns(0xfffffffe, &orion_clkevt);
	orion_clkevt.min_delta_ns = clockevent_delta2ns(MIN_TIMER1_DELTA, &orion_clkevt);
	orion_clkevt.cpumask = cpumask_of(0);
	clockevents_register_device(&orion_clkevt);
}



#ifdef CONFIG_IPIPE

/*
 * Acknowledge the hardware timer interrupt at hardware timer level.  
 */
void __ipipe_mach_acktimer(void)
{
	/*
	 * ACK timer interrupt and call event handler.
	 */
	writel(BRIDGE_INT_TIMER1_CLR, BRIDGE_CAUSE);

}


/* 
 * __ipipe_mach_get_tsc
 * High resolution counter, or its emulation using the hardware decrementer or free-running counter 
 */
notrace unsigned long long __ipipe_mach_get_tsc(void)
{
    if (likely(orion_timer_initialized)) {
        union tsc_reg *local_tsc, result;
        unsigned long stamp;

        local_tsc = orion_tsc;
        __asm__ ("ldmia %1, %M0\n":
             "=r"(result.full): "r"(local_tsc), "m"(*local_tsc));
        barrier();
        stamp = readl(TIMER0_VAL);


        if (unlikely(stamp < result.low))
            /* 32 bit counter wrapped, increment high word. */
            result.high++;
        result.low = stamp;

        return result.full;
    }

        return 0;
}
EXPORT_SYMBOL(__ipipe_mach_get_tsc);


/* 
 * __ipipe_mach_get_tscinfo
 * export the tsc to user-space
 */

void __ipipe_mach_get_tscinfo(struct __ipipe_tscinfo *info)
{
	/* info->type indicates that the tsc is based on a free-running counter */
	info->type = IPIPE_TSC_TYPE_FREERUNNING;

	/* info->u.fr.counter is set to the PHYSICAL address of the free-running counter 
           since we are using the free-running counter (i.e. TIMER0) for TSC emulation */
	info->u.fr.counter = (unsigned *) TIMER0_VAL;

	/* info->u.fr.mask is a mask indicating which bits in the free-running counter are valid */
	info->u.fr.mask = 0xffffffff;

	/* info->u.fr.tsc is a pointer to the shared tsc area */
	info->u.fr.tsc = &orion_tsc->full;
}
EXPORT_SYMBOL(__ipipe_mach_get_tscinfo);


/* __ipipe_mach_get_dec
 * Returns the count of hardware timer ticks remaining before the next timer interrupt. 
 */
unsigned long __ipipe_mach_get_dec(void)
{
    /* return OSMR0 - OSCR; */
    /* since we are using clockevent timer(i.e. TIMER1) for hardware timer */
    return (readl(TIMER1_RELOAD) - readl(TIMER1_VAL));

}
EXPORT_SYMBOL(__ipipe_mach_get_dec);

/*
 * __ipipe_mach_set_dec
 * Program the hardware timer to trig an interrupt in 'delay' hardware timer ticks.
 */
void __ipipe_mach_set_dec(unsigned long delay)
{
    u32 u;

    /* check if the required delay is greater than the min threshold ticks (delta) of TIMER1 */
    if (delay > MIN_TIMER1_DELTA) {
        unsigned long flags;

        local_irq_save(flags);

	/* load the relaod register of TIMER1 with the ner value */
        writel(delay + readl(TIMER1_VAL), TIMER1_RELOAD);


        /*
         * Clear and enable clockevent timer interrupt.
         */
        writel(BRIDGE_INT_TIMER1_CLR, BRIDGE_CAUSE);

        u = readl(BRIDGE_MASK);
        u |= BRIDGE_INT_TIMER1;
        writel(u, BRIDGE_MASK);


        local_irq_restore(flags);
    } else
	/* generate the interrupt now */
        ipipe_trigger_irq(IRQ_MV88FXX_ORION_BRIDGE);

}
EXPORT_SYMBOL(__ipipe_mach_set_dec);


/*
 * __ipipe_mach_release_timer
 */
void __ipipe_mach_release_timer(void)
{
        orion_clkevt_mode(orion_clkevt.mode, &orion_clkevt);
        if (orion_clkevt.mode == CLOCK_EVT_MODE_ONESHOT)
                orion_clkevt_next_event(LATCH, &orion_clkevt);
}

int __ipipe_check_tickdev(const char *devname)
{
    return !strcmp(devname, orion_clkevt.name);
}


/*
 * ipipe_mach_update_tsc
 * If the free-running counter wraps fast, the best place to do this is __ipipe_mach_acktimer. 
 * If the free-running counter wraps slowly, doing this from Linux timer interrupt will reduce the timer interrupt latency. 
 * Assume the implementation wraps slowly
 */
static void ipipe_mach_update_tsc(void)
{
	union tsc_reg *local_tsc;
	unsigned long stamp, flags;

	local_irq_save_hw(flags);
	local_tsc = &orion_tsc[ipipe_processor_id()];
	/*local_tsc = orion_tsc;*/


	/* since we are using the free-running counter (i.e. TIMER0) for TSC emulation */
	stamp = readl(TIMER0_VAL);

	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);
}

#endif /* CONFIG_IPIPE */

************************************************************************************



And here is the kernel booting output:

####################################################################################
Uncompressing Linux............................................................................................................................ done, bootin.
Linux version 2.6.29.5-xenomai (root@domain.hid) (gcc version 4.3.2 (Debian 4.3.2-1.1) ) #14 PREEMPT Tue Nov 3 16:11:38 EST 2009
CPU: Feroceon [41069260] revision 0 (ARMv5TEJ), cr=b0053177
CPU: VIVT data cache, VIVT instruction cache
Machine: Technologic Systems TS-78xx SBC
Memory policy: ECC disabled, Data cache writeback
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32512
Kernel command line: root=/dev/nfs rw nfsroot=172.25.25.100:/home/wael/LTE/exports/emdebian-rootfs ip=dhcp console=ttyS0,115200
PID hash table entries: 512 (order: 9, 2048 bytes)
I-pipe 1.13-03: pipeline enabled.
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
Memory: 128MB = 128MB total
Memory: 121472KB available (3584K code, 452K data, 148K init)
SLUB: Genslabs=12, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Calibrating delay loop... 331.77 BogoMIPS (lpj=1658880)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 520 bytes
NET: Registered protocol family 16
Orion ID: MV88F5182-A2. TCLK=166666667.
TS-78xx Info: FPGA rev=05, Board Magic=00b480, JP1=1, JP2=1
TS-78xx RTC not detected or enabled
bio: create slab <bio-0> at 0
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 4096 (order: 3, 32768 bytes)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
TCP: Hash tables configured (established 4096 bind 4096)
TCP reno registered
NET: Registered protocol family 1
checking if image is initramfs...it isn't (bad gzip magic numbers); looks like an initrd
Freeing initrd memory: 4096K
NetWinder Floating Point Emulator V0.97 (double precision)
I-pipe: Domain Xenomai registered.
Xenomai: hal/arm started.
Xenomai: real-time nucleus v2.4.9.1 (Big Bad Moon) loaded.
Xenomai: starting POSIX services.
Xenomai: starting RTDM services.
JFFS2 version 2.2. (NAND) �© 2001-2006 Red Hat, Inc.
msgmni has been set to 245
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO 0xf1012000 (irq = 3) is a 16550A
console [ttyS0] enabled
serial8250.1: ttyS1 at MMIO 0xf1012100 (irq = 4) is a 16550A
brd: module loaded
loop: module loaded
MV-643xx 10/100/1000 ethernet driver version 1.4
mv643xx_eth smi: probed
eth0 (mv643xx_eth_port): not using net_device_ops yet
net eth0: port 0 with MAC address 00:d0:69:41:cc:43
Driver 'sd' needs updating - please use bus_type methods
sata_mv sata_mv.0: version 1.25
sata_mv sata_mv.0: slots 32 ports 2
scsi0 : sata_mv
scsi1 : sata_mv
ata1: SATA max UDMA/133 irq 29
ata2: SATA max UDMA/133 irq 29

####################################################################################

I cant guess what is my error?
Is there any hint to solve this problem?

thanks,
Wael


      

[-- Attachment #2: Type: text/html, Size: 17594 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2009-11-03 15:00 [Xenomai-help] Porting I-Pipe for new ARM board Wael Showair
@ 2009-11-03 15:13 ` Gilles Chanteperdrix
  2009-11-03 15:45   ` Didenko Sergey
  0 siblings, 1 reply; 38+ messages in thread
From: Gilles Chanteperdrix @ 2009-11-03 15:13 UTC (permalink / raw)
  To: Wael Showair; +Cc: Xenomai-help, didenkos

Wael Showair wrote:
> Hi All,
> i have TS-7800 board based on Marvell 88F5182 processor core.
> Unfortunately it is not supported by I-Pipe patch so according to the
> following link:
> 
> http://www.xenomai.org/index.php/I-pipe:ArmPorting
> 
> And with aid of this forum thread:
> 
> http://www.mail-archive.com/xenomai@xenomai.org

If you follow that thread, you will see that I already told its author
that the code was not correct.

Fortunately Philippe did a port which was tested and works, I will fix
one or two details and send it tonight (european time).

-- 
                                          Gilles



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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2009-11-03 15:13 ` Gilles Chanteperdrix
@ 2009-11-03 15:45   ` Didenko Sergey
  2009-11-03 15:48     ` Gilles Chanteperdrix
                       ` (2 more replies)
  0 siblings, 3 replies; 38+ messages in thread
From: Didenko Sergey @ 2009-11-03 15:45 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: Xenomai-help

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

Gilles, I gues you are talking about the code which I got for MV 88F6290.
With some changes it is working on my board now, so, Wael, if you want, I
can send it to you in 10 hours, it should work on your board.

Sergey
2009/11/4 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>

> Wael Showair wrote:
> > Hi All,
> > i have TS-7800 board based on Marvell 88F5182 processor core.
> > Unfortunately it is not supported by I-Pipe patch so according to the
> > following link:
> >
> > http://www.xenomai.org/index.php/I-pipe:ArmPorting
> >
> > And with aid of this forum thread:
> >
> > http://www.mail-archive.com/xenomai@xenomai.org
>
> If you follow that thread, you will see that I already told its author
> that the code was not correct.
>
> Fortunately Philippe did a port which was tested and works, I will fix
> one or two details and send it tonight (european time).
>
> --
>                                          Gilles
>
>

[-- Attachment #2: Type: text/html, Size: 1537 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2009-11-03 15:45   ` Didenko Sergey
@ 2009-11-03 15:48     ` Gilles Chanteperdrix
  2009-11-04  6:58     ` Wael Showair
  2009-11-04 10:54     ` Gilles Chanteperdrix
  2 siblings, 0 replies; 38+ messages in thread
From: Gilles Chanteperdrix @ 2009-11-03 15:48 UTC (permalink / raw)
  To: Didenko Sergey; +Cc: Xenomai-help

Didenko Sergey wrote:
> Gilles, I gues you are talking about the code which I got for MV 88F6290.
> With some changes it is working on my board now, so, Wael, if you
> want, I can send it to you in 10 hours, it should work on your board.

Please keep things public and post that code to the list. I intend to
include that code in the next release of Xenomai, and it would be a good
idea that the code we include is the code which works.

-- 
                                          Gilles



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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2009-11-03 15:45   ` Didenko Sergey
  2009-11-03 15:48     ` Gilles Chanteperdrix
@ 2009-11-04  6:58     ` Wael Showair
  2009-11-04 10:54     ` Gilles Chanteperdrix
  2 siblings, 0 replies; 38+ messages in thread
From: Wael Showair @ 2009-11-04  6:58 UTC (permalink / raw)
  To: Didenko Sergey, Gilles Chanteperdrix; +Cc: Xenomai-help

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

Yes please Didenko i would like that you send your code to me & to the whole xenomai-help post.
thanks



________________________________
From: Didenko Sergey <didenkos@domain.hid>
To: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
Cc: Wael Showair <showair2003@domain.hid>; Xenomai-help@domain.hid
Sent: Tue, November 3, 2009 5:45:06 PM
Subject: Re: [Xenomai-help] Porting I-Pipe for new ARM board


Gilles, I gues you are talking about the code which I got for MV 88F6290.
With some changes it is working on my board now, so, Wael, if you want, I can send it to you in 10 hours, it should work on your board.
 
Sergey

2009/11/4 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>

Wael Showair wrote:
>> Hi All,
>> i have TS-7800 board based on Marvell 88F5182 processor core.
>> Unfortunately it is not supported by I-Pipe patch so according to the
>> following link:
>>>
>> http://www.xenomai.org/index.php/I-pipe:ArmPorting
>>
>> And with aid of this forum thread:
>>
>> http://www.mail-archive.com/xenomai@xenomai.org
>
>>If you follow that thread, you will see that I already told its author
>>that the code was not correct.
>
>>Fortunately Philippe did a port which was tested and works, I will fix
>>one or two details and send it tonight (european time).
>
>--
>                                         Gilles
>
>



      

[-- Attachment #2: Type: text/html, Size: 3283 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2009-11-03 15:45   ` Didenko Sergey
  2009-11-03 15:48     ` Gilles Chanteperdrix
  2009-11-04  6:58     ` Wael Showair
@ 2009-11-04 10:54     ` Gilles Chanteperdrix
  2009-11-06  9:08       ` Wael Showair
  2 siblings, 1 reply; 38+ messages in thread
From: Gilles Chanteperdrix @ 2009-11-04 10:54 UTC (permalink / raw)
  To: Didenko Sergey; +Cc: Xenomai-help

Didenko Sergey wrote:
> Gilles, I gues you are talking about the code which I got for MV 88F6290.
> With some changes it is working on my board now, so, Wael, if you
> want, I can send it to you in 10 hours, it should work on your board.

Hi Sergey,

Do you intend to publish your patch, or should we restart from the one
which Philippe did?

Regards.

-- 
                                          Gilles



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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2009-11-04 10:54     ` Gilles Chanteperdrix
@ 2009-11-06  9:08       ` Wael Showair
  2009-11-06  9:39         ` Sergey Didenko
  0 siblings, 1 reply; 38+ messages in thread
From: Wael Showair @ 2009-11-06  9:08 UTC (permalink / raw)
  To: Gilles Chanteperdrix, Didenko Sergey; +Cc: Xenomai-help

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

Hi Sergey & Gilles,
Could anyone of you please put any version of the patch on the mailing-list.
you said you can send it to me within 10 hours or on last Monday?

i really want to my kernel to boot on orion marvell processor.
thanks for your help




________________________________
From: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
To: Didenko Sergey <didenkos@domain.hid>
Cc: Wael Showair <showair2003@domain.hid>; Xenomai-help@domain.hid
Sent: Wed, November 4, 2009 12:54:32 PM
Subject: Re: [Xenomai-help] Porting I-Pipe for new ARM board

Didenko Sergey wrote:
> Gilles, I gues you are talking about the code which I got for MV 88F6290.
> With some changes it is working on my board now, so, Wael, if you
> want, I can send it to you in 10 hours, it should work on your board.

Hi Sergey,

Do you intend to publish your patch, or should we restart from the one
which Philippe did?

Regards.

-- 
                                          Gilles


      

[-- Attachment #2: Type: text/html, Size: 1869 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2009-11-06  9:08       ` Wael Showair
@ 2009-11-06  9:39         ` Sergey Didenko
  2009-11-06 10:22           ` Gilles Chanteperdrix
                             ` (2 more replies)
  0 siblings, 3 replies; 38+ messages in thread
From: Sergey Didenko @ 2009-11-06  9:39 UTC (permalink / raw)
  To: Wael Showair; +Cc: Xenomai-help


[-- Attachment #1.1: Type: text/plain, Size: 1590 bytes --]

Hello

Here it is!
I'm very sorry for this delay, it was related to 2 facts:
1) before publishing I wanted to put the code in order and to verify once
again
2) I was extremely busy these days, especially with the project on Xenoimai
and I could not do anything with that code except making my project work on
it.

I want to say only that it is working and you can use it with some changes
for your board.
One more time sorry for very late reply.

Gilles, did you get this code (I sent it to you 11.05) ?

Sergey

2009/11/6 Wael Showair <showair2003@domain.hid>

> Hi Sergey & Gilles,
> Could anyone of you please put any version of the patch on the
> mailing-list.
> you said you can send it to me within 10 hours or on last Monday?
>
> i really want to my kernel to boot on orion marvell processor.
> thanks for your help
>
> ------------------------------
> *From:* Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
> *To:* Didenko Sergey <didenkos@domain.hid>
>
> *Cc:* Wael Showair <showair2003@domain.hid>; Xenomai-help@domain.hid
> *Sent:* Wed, November 4, 2009 12:54:32 PM
>
> *Subject:* Re: [Xenomai-help] Porting I-Pipe for new ARM board
>
> Didenko Sergey wrote:
> > Gilles, I gues you are talking about the code which I got for MV 88F6290.
> > With some changes it is working on my board now, so, Wael, if you
> > want, I can send it to you in 10 hours, it should work on your board.
>
> Hi Sergey,
>
> Do you intend to publish your patch, or should we restart from the one
> which Philippe did?
>
> Regards.
>
> --
>                                           Gilles
>
>
>

[-- Attachment #1.2: Type: text/html, Size: 2959 bytes --]

[-- Attachment #2: mv88f6290.tar.bz2 --]
[-- Type: application/x-bzip2, Size: 5319 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2009-11-06  9:39         ` Sergey Didenko
@ 2009-11-06 10:22           ` Gilles Chanteperdrix
  2009-12-15 19:37           ` Олександр Лаврущенко
       [not found]           ` <20091215213210.19d5b6a5@domain.hid>
  2 siblings, 0 replies; 38+ messages in thread
From: Gilles Chanteperdrix @ 2009-11-06 10:22 UTC (permalink / raw)
  To: Sergey Didenko; +Cc: Xenomai-help

Sergey Didenko wrote:
> Hello
> 
> Here it is!
> I'm very sorry for this delay, it was related to 2 facts:
> 1) before publishing I wanted to put the code in order and to verify
> once again
> 2) I was extremely busy these days, especially with the project on
> Xenoimai and I could not do anything with that code except making my
> project work on it.
> 
> I want to say only that it is working and you can use it with some
> changes for your board.
> One more time sorry for very late reply.
> 
> Gilles, did you get this code (I sent it to you 11.05) ?

No, I did not receive anything. Anyway, please send your modifications a
patch against your kernel patched with the original I-pipe patch. That
is the only way for us to review your code efficiently.

-- 
                                          Gilles



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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2009-11-06  9:39         ` Sergey Didenko
  2009-11-06 10:22           ` Gilles Chanteperdrix
@ 2009-12-15 19:37           ` Олександр Лаврущенко
  2009-12-15 20:34             ` Gilles Chanteperdrix
       [not found]           ` <20091215213210.19d5b6a5@domain.hid>
  2 siblings, 1 reply; 38+ messages in thread
From: Олександр Лаврущенко @ 2009-12-15 19:37 UTC (permalink / raw)
  To: xenomai

On Fri, 6 Nov 2009 18:39:05 +0900
Sergey Didenko <didenkos@domain.hid> wrote:

> Hello
> 
> Here it is!
> I'm very sorry for this delay, it was related to 2 facts:
> 1) before publishing I wanted to put the code in order and to verify
> once again
> 2) I was extremely busy these days, especially with the project on
> Xenoimai and I could not do anything with that code except making my
> project work on it.
> 
> I want to say only that it is working and you can use it with some
> changes for your board.
> One more time sorry for very late reply.
Hi.
I want to ask some questions about patch.
For which kernel version (and kernel patches if any) and xenomai version
this patch. And how apply it right, since it's not common patch, rather
suite of files?

Thank you for answer.

-- 
WBR Lavruschenko Oleksandr



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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2009-12-15 19:37           ` Олександр Лаврущенко
@ 2009-12-15 20:34             ` Gilles Chanteperdrix
  0 siblings, 0 replies; 38+ messages in thread
From: Gilles Chanteperdrix @ 2009-12-15 20:34 UTC (permalink / raw)
  To: Олександр
	Лаврущенко
  Cc: xenomai

Олександр Лаврущенко wrote:
> On Fri, 6 Nov 2009 18:39:05 +0900
> Sergey Didenko <didenkos@domain.hid> wrote:
> 
>> Hello
>>
>> Here it is!
>> I'm very sorry for this delay, it was related to 2 facts:
>> 1) before publishing I wanted to put the code in order and to verify
>> once again
>> 2) I was extremely busy these days, especially with the project on
>> Xenoimai and I could not do anything with that code except making my
>> project work on it.
>>
>> I want to say only that it is working and you can use it with some
>> changes for your board.
>> One more time sorry for very late reply.
> Hi.
> I want to ask some questions about patch.
> For which kernel version (and kernel patches if any) and xenomai version
> this patch. And how apply it right, since it's not common patch, rather
> suite of files?

This has been sent as a patch, I sent some comments, but I do not
remember if Sergey answered.

The development on the I-pipe patches for ARM will be resumed as soon as
Xenomai 2.5.0 will have been released. This patch is one of the pending
tasks.

The patch should work with any recent version i.e. the I-pipe patches
which come with Xenomai 2.4.10 for instance. As for which kernel version
this patch applies to, I have no idea.

-- 
					    Gilles.



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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
       [not found]           ` <20091215213210.19d5b6a5@domain.hid>
@ 2009-12-16  1:15             ` Sergey Didenko
  2009-12-31 12:52               ` Flavio de Castro Alves Filho
  0 siblings, 1 reply; 38+ messages in thread
From: Sergey Didenko @ 2009-12-16  1:15 UTC (permalink / raw)
  To: Aleksandr Lavrushchenko; +Cc: xenomai

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

hi

you are right, this is not common patch, but still it is a patch and you can
apply it.
to do that, run the command
patch -p0 < new-patch
in you linux kernel folder

if you open the *.patch file with text editor, you will see the changes for
only 4 files.
This patch includes the changes to support Marvell SoC MV88F6290 with
Counting Down free running counter.

Kernel version is 2.6.29-v02.00.29
Xenomai version is 2.4.9.1

Sergey

2009/12/16 Aleksandr Lavrushchenko <aleksandr.lavrushchenko@domain.hid>

> On Fri, 6 Nov 2009 18:39:05 +0900
> Sergey Didenko <didenkos@domain.hid> wrote:
>
> > Hello
> >
> > Here it is!
> > I'm very sorry for this delay, it was related to 2 facts:
> > 1) before publishing I wanted to put the code in order and to verify
> > once again
> > 2) I was extremely busy these days, especially with the project on
> > Xenoimai and I could not do anything with that code except making my
> > project work on it.
> >
> > I want to say only that it is working and you can use it with some
> > changes for your board.
> > One more time sorry for very late reply.
> Hi.
> I want to ask some questions about patch.
> For which kernel version (and kernel patches if any) and xenomai version
> this patch. And how apply it right, since it's not common patch, rather
> suite of files?
>
> Thank you for answer.
> --
> WBR Lavruschenko Oleksandr
>

[-- Attachment #2: Type: text/html, Size: 2735 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2009-12-16  1:15             ` Sergey Didenko
@ 2009-12-31 12:52               ` Flavio de Castro Alves Filho
  2009-12-31 15:41                 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 38+ messages in thread
From: Flavio de Castro Alves Filho @ 2009-12-31 12:52 UTC (permalink / raw)
  To: xenomai

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

Hello,

I am currently working on the port of Xenomai for the TI OMAP L-138
processor (DaVinci platform). I didn't finish yet. As soon as I finish, I
will send the patch, and I intend to do so next week.

I followed the instructions from Xenomai's wiki page. Until now, I am able
to boot my ported kernel with the I-Pipe feature. When I build the kernel
with Xenomai feature, the kernel stops to boot.

I have some questions:

1) How is the better way to debug the boot process? When my kernel stops
booting, after the message "Uncompressing .........." the boot halts. I
don't know what is going on and I don't know what to do in order to follow
the processes internally. Both debuggers (kernel and i-ipipe) are enabled in
the kernel configuration.

2) How tested the code must be done in order to send you a patch? Is there
any minimal set of tests that I should perform just before sending you a
patch for revision?

Best regards,

Flavio

Flavio de Castro Alves Filho
Embedded Software Services
www.phiinnovations.com
+55 11 84 94 56 76


2009/12/15 Sergey Didenko <didenkos@domain.hid>

> hi
>
> you are right, this is not common patch, but still it is a patch and you
> can apply it.
> to do that, run the command
> patch -p0 < new-patch
> in you linux kernel folder
>
> if you open the *.patch file with text editor, you will see the changes for
> only 4 files.
> This patch includes the changes to support Marvell SoC MV88F6290 with
> Counting Down free running counter.
>
> Kernel version is 2.6.29-v02.00.29
> Xenomai version is 2.4.9.1
>
> Sergey
>
> 2009/12/16 Aleksandr Lavrushchenko <aleksandr.lavrushchenko@domain.hid>
>
>>  On Fri, 6 Nov 2009 18:39:05 +0900
>> Sergey Didenko <didenkos@domain.hid> wrote:
>>
>> > Hello
>> >
>> > Here it is!
>> > I'm very sorry for this delay, it was related to 2 facts:
>> > 1) before publishing I wanted to put the code in order and to verify
>> > once again
>> > 2) I was extremely busy these days, especially with the project on
>> > Xenoimai and I could not do anything with that code except making my
>> > project work on it.
>> >
>> > I want to say only that it is working and you can use it with some
>> > changes for your board.
>> > One more time sorry for very late reply.
>> Hi.
>> I want to ask some questions about patch.
>> For which kernel version (and kernel patches if any) and xenomai version
>> this patch. And how apply it right, since it's not common patch, rather
>> suite of files?
>>
>> Thank you for answer.
>> --
>> WBR Lavruschenko Oleksandr
>>
>
>
> _______________________________________________
> Xenomai-help mailing list
> Xenomai-help@domain.hid
> https://mail.gna.org/listinfo/xenomai-help
>
>

[-- Attachment #2: Type: text/html, Size: 4463 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2009-12-31 12:52               ` Flavio de Castro Alves Filho
@ 2009-12-31 15:41                 ` Gilles Chanteperdrix
  2010-01-04 22:14                   ` Flavio Alves
  0 siblings, 1 reply; 38+ messages in thread
From: Gilles Chanteperdrix @ 2009-12-31 15:41 UTC (permalink / raw)
  To: Flavio de Castro Alves Filho; +Cc: xenomai

Flavio de Castro Alves Filho wrote:
> Hello,
>  
> I am currently working on the port of Xenomai for the TI OMAP L-138
> processor (DaVinci platform). I didn't finish yet. As soon as I finish,
> I will send the patch, and I intend to do so next week.
>  
> I followed the instructions from Xenomai's wiki page. Until now, I am
> able to boot my ported kernel with the I-Pipe feature. When I build the
> kernel with Xenomai feature, the kernel stops to boot.
>  
> I have some questions:
>  
> 1) How is the better way to debug the boot process? When my kernel stops
> booting, after the message "Uncompressing .........." the boot halts. I
> don't know what is going on and I don't know what to do in order to
> follow the processes internally. Both debuggers (kernel and i-ipipe) are
> enabled in the kernel configuration.

This is tips and tricks number 1:
http://www.xenomai.org/index.php/I-pipe:ArmPorting#Tips_and_tricks.

>  
> 2) How tested the code must be done in order to send you a patch? Is
> there any minimal set of tests that I should perform just before sending
> you a patch for revision?

The validation tool I use is LTP. You can check that LTP returns the
same results with a vanilla kernel, and with the Xenomai patched kernel
when running LTP while a latency test is running. Unfortunately, to run
ltp on low-end arms, I had to make a few local changes. Which means I am
using an out-dated, patched version of LTP:
http://sisyphus.hd.free.fr/~gilles/ltp-20081130-patched.tar.bz2

-- 
					    Gilles.


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2009-12-31 15:41                 ` Gilles Chanteperdrix
@ 2010-01-04 22:14                   ` Flavio Alves
  2010-01-04 22:22                     ` Gilles Chanteperdrix
  0 siblings, 1 reply; 38+ messages in thread
From: Flavio Alves @ 2010-01-04 22:14 UTC (permalink / raw)
  To: xenomai


[-- Attachment #1.1: Type: text/plain, Size: 6295 bytes --]

Hello Gilles,

Thanks for your advice, now I could continue the porting.

After implementing the tips and tricks number 1, I could see again the
boot messages. The trace is the following:

<6>Xenomai: hal/arm
started.                                                    
<6>Xenomai: real-time nucleus v2.4.9.1 (Big Bad Moon)
loaded.                   
<1>Unable to handle kernel NULL pointer dereference at virtual address
00000000 
<1>pgd =
c0004000                                                               
<1>[00000000]
*pgd=00000000                                                     
Internal error: Oops: 5 [#1]
PREEMPT                                            
Modules linked
in:                                                              
CPU: 0    Not tainted  (2.6.29-rc8-davinci1
#23)                                
PC is at __ipipe_mach_get_tsc
+0x28/0x64                                         
LR is at xnarch_get_cpu_time
+0x10/0x18                                          
pc : [<c0037514>]    lr : [<c0077d24>]    psr:
20000013                         
sp : c1c17e68  ip : c1c17e78  fp :
c1c17e74                                     
r10: c03e0f90  r9 : 00000000  r8 :
c03b95e8                                     
r7 : c03b95e8  r6 : 00000001  r5 : 00000000  r4 :
97a862f8                      
r3 : 00000001  r2 : 00000000  r1 : 00000000  r0 :
97a862f8                      
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment
kernel             
Control: 0005317f  Table: c0004000  DAC:
00000017                               
Process swapper (pid: 1, stack limit =
0xc1c16268)                              
Stack: (0xc1c17e68 to
0xc1c18000)                                               
7e60:                   c1c17e84 c1c17e78 c0077d24 c00374fc c1c17eb4
c1c17e88   
7e80: c007a62c c0077d24 00000000 00000000 c1c17eb4 c1c17ea0 00000000
c03e0f90   
7ea0: 00000001 c03e0fc8 c1c17f34 c1c17eb8 c007a9d4 c007a584 00500080
00000000   
7ec0: 00000000 0000011c 736f685b 69742d74 5d72656d 019bfc00 c0014348
c035fc94   
7ee0: 00000000 00000000 544f4f52 c1c17e00 c02d5d14 c0043a5c c1c17f1c
c1c17f2c   
7f00: c0075664 c03e0f58 00000000 c03e2ccc c03e2cd8 c03e2ce4 c03e2cf0
c03e2cfc   
7f20: 00000000 c03e2c80 c1c17f5c c1c17f38 c0083710 c007a700 c0024acc
00000000   
7f40: 00000000 c0083658 00000001 00000000 c1c17fd4 c1c17f60 c002d464
c0083668   
7f60: 00000000 c035c631 c03dc160 000000db c1c33000 00000000 00000000
00000000   
7f80: c1c17fac c1c17f90 c0106158 c0105e38 00000000 c1c33180 c1c17fc4
c03dc160   
7fa0: c1c17fc4 c1c17fb0 c0070f60 c01060e8 c0024978 c0024acc 00000000
00000000   
7fc0: 00000000 00000000 c1c17ff4 c1c17fd8 c00085a4 c002d418 00000000
00000001   
7fe0: 00000000 00000000 00000000 c1c17ff8 c0046638 c000852c fffdf7ff
ffeffedf   
Backtrace:                                                                      
[<c00374ec>] (__ipipe_mach_get_tsc+0x0/0x64) from [<c0077d24>]
(xnarch_get_cpu_)
[<c0077d14>] (xnarch_get_cpu_time+0x0/0x18) from [<c007a62c>]
(xnpod_enable_tim)
[<c007a574>] (xnpod_enable_timesource+0x0/0x17c) from [<c007a9d4>]
(xnpod_init+)
 r7:c03e0fc8 r6:00000001 r5:c03e0f90
r4:00000000                                
[<c007a6f0>] (xnpod_init+0x0/0x35c) from [<c0083710>]
(__native_skin_init+0xb8/)
[<c0083658>] (__native_skin_init+0x0/0x278) from [<c002d464>]
(do_one_initcall+)
[<c002d408>] (do_one_initcall+0x0/0x1a4) from [<c00085a4>] (kernel_init
+0x88/0x)
 r8:00000000 r7:00000000 r6:00000000 r5:00000000
r4:c0024acc                    
[<c000851c>] (kernel_init+0x0/0xfc) from [<c0046638>] (do_exit
+0x0/0x7e8)       

r4:00000000                                                                    
Code: 03a02000 03a03000 0a00000a e5922000
(e892000c)                            
<4>---[ end trace
da227214a82491b7 ]---                                         
<0>Kernel panic - not syncing: Attempted to kill
init!                          

Looking at the code (and perform some analysis) I saw that the call that
is crashing the kernel is:

 __asm__("ldmia %1, %M0\n":
	    "=r"(result.full): "r"(local_tsc), "m"(*local_tsc));

And looking into the implementation of this function for other
platforms, I can see that it is the same instruction, without
difference.

In my implementation (port for the TI OMAP L-138 processor), I have
CONFIG_GENERIC_CLOCKEVENTS and CONFIG_GENERIC_TIME.

Could you please give me some advice about how to solve this issue?

Thank you for all your help.

Flavio

On Qui, 2009-12-31 at 16:41 +0100, Gilles Chanteperdrix wrote:

> Flavio de Castro Alves Filho wrote:
> > Hello,
> >  
> > I am currently working on the port of Xenomai for the TI OMAP L-138
> > processor (DaVinci platform). I didn't finish yet. As soon as I finish,
> > I will send the patch, and I intend to do so next week.
> >  
> > I followed the instructions from Xenomai's wiki page. Until now, I am
> > able to boot my ported kernel with the I-Pipe feature. When I build the
> > kernel with Xenomai feature, the kernel stops to boot.
> >  
> > I have some questions:
> >  
> > 1) How is the better way to debug the boot process? When my kernel stops
> > booting, after the message "Uncompressing .........." the boot halts. I
> > don't know what is going on and I don't know what to do in order to
> > follow the processes internally. Both debuggers (kernel and i-ipipe) are
> > enabled in the kernel configuration.
> 
> This is tips and tricks number 1:
> http://www.xenomai.org/index.php/I-pipe:ArmPorting#Tips_and_tricks.
> 
> >  
> > 2) How tested the code must be done in order to send you a patch? Is
> > there any minimal set of tests that I should perform just before sending
> > you a patch for revision?
> 
> The validation tool I use is LTP. You can check that LTP returns the
> same results with a vanilla kernel, and with the Xenomai patched kernel
> when running LTP while a latency test is running. Unfortunately, to run
> ltp on low-end arms, I had to make a few local changes. Which means I am
> using an out-dated, patched version of LTP:
> http://sisyphus.hd.free.fr/~gilles/ltp-20081130-patched.tar.bz2
> 










Flavio de
Castro Alves
Filho
flavio.alves@domain.hid

Tel.: + 55 11
8494-5676
Embedded
Software
Services

www.phiinnovations.com











Escritórios::
São Paulo
Campinas



[-- Attachment #1.2: Type: text/html, Size: 13349 bytes --]

[-- Attachment #2: logo.gif --]
[-- Type: image/gif, Size: 5312 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-04 22:14                   ` Flavio Alves
@ 2010-01-04 22:22                     ` Gilles Chanteperdrix
  2010-01-06 10:56                       ` Flavio Alves
  0 siblings, 1 reply; 38+ messages in thread
From: Gilles Chanteperdrix @ 2010-01-04 22:22 UTC (permalink / raw)
  To: flavio.alves; +Cc: xenomai

Flavio Alves wrote:
> <1>Unable to handle kernel NULL pointer dereference at virtual address 00000000 
> Looking at the code (and perform some analysis) I saw that the call that
> is crashing the kernel is:
> 
>  __asm__("ldmia %1, %M0\n":
> 	    "=r"(result.full): "r"(local_tsc), "m"(*local_tsc));
> 
> And looking into the implementation of this function for other
> platforms, I can see that it is the same instruction, without
> difference.

On all other platforms the "local_tsc" pointer is not NULL...

-- 
					    Gilles.


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-04 22:22                     ` Gilles Chanteperdrix
@ 2010-01-06 10:56                       ` Flavio Alves
  2010-01-06 11:01                         ` Gilles Chanteperdrix
  0 siblings, 1 reply; 38+ messages in thread
From: Flavio Alves @ 2010-01-06 10:56 UTC (permalink / raw)
  To: xenomai


[-- Attachment #1.1: Type: text/plain, Size: 7242 bytes --]

Indeed ... 

Making this pointer not null (initializing the tsc pointer) solve this
issue. Thanks again for your help.

Now I have the following situation in my xenomai boot process:

Starting
kernel ...                                                             
                                                                                
Uncompressing
Linux.............................................................
Linux version 2.6.29-rc8-davinci1 (flavio@domain.hid) (gcc version
4.3.3 (So0
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ),
cr=00053177                   
CPU: VIVT data cache, VIVT instruction
cache                                    
Machine: DaVinci DA850
EVM                                                      
Memory policy: ECC disabled, Data cache
writeback                               
DA0850 variant
0x0                                                              
Built 1 zonelists in Zone order, mobility grouping on.  Total pages:
8128       
Kernel command line: mem=32M console=ttyS2,115200n8 root=/dev/ram0 rw
initrd=0x1
PID hash table entries: 128 (order: 7, 512
bytes)                               
I-pipe 1.13-03: pipeline
enabled.                                               
Console: colour dummy device
80x30                                              
Dentry cache hash table entries: 4096 (order: 2, 16384
bytes)                   
Inode-cache hash table entries: 2048 (order: 1, 8192
bytes)                     
Memory: 32MB = 32MB
total                                                       
Memory: 24248KB available (3580K code, 368K data, 148K
init)                    
Calibrating delay loop... 149.09 BogoMIPS
(lpj=745472)                          
Mount-cache hash table entries:
512                                             
CPU: Testing write buffer coherency:
ok                                         
net_namespace: 880
bytes                                                        
NET: Registered protocol family
16                                              
Pin I2C1_SCL already used for
UART2_RXD.                                        
Pin I2C1_SDA already used for
UART2_TXD.                                        
DaVinci: 144 gpio
irqs                                                          
bio: create slab <bio-0> at
0                                                   
SCSI subsystem
initialized                                                      
usbcore: registered new interface driver
usbfs                                  
usbcore: registered new interface driver
hub                                    
usbcore: registered new device driver
usb                                       
musb_hdrc: version 6.0, cppi4.1-dma, host,
debug=0                              
Waiting for PHY clock
good...                                                   
musb_hdrc: USB Host mode controller at fee00000 using DMA, IRQ
58               
musb_hdrc musb_hdrc: MUSB HDRC host
driver                                      
musb_hdrc musb_hdrc: new USB bus registered, assigned bus number
1              
usb usb1: configuration #1 chosen from 1
choice                                 
hub 1-0:1.0: USB hub
found                                                      
hub 1-0:1.0: 1 port
detected                                                    
NET: Registered protocol family
2                                               
IP route cache hash table entries: 1024 (order: 0, 4096
bytes)                  
TCP established hash table entries: 1024 (order: 1, 8192
bytes)                 
TCP bind hash table entries: 1024 (order: 0, 4096
bytes)                        
TCP: Hash tables configured (established 1024 bind
1024)                        
TCP reno
registered                                                             
NET: Registered protocol family
1                                               
checking if image is initramfs...it isn't (no cpio magic); looks like an
initrd 
Freeing initrd memory:
4096K                                                    
I-pipe: Domain Xenomai
registered.                                              
Xenomai: hal/arm
started.                                                       
Xenomai: real-time nucleus v2.4.9.1 (Big Bad Moon)
loaded.                      
Xenomai: starting native API
services.                                          
Xenomai: starting POSIX
services.                                               
Xenomai: starting RTDM
services.                                                
msgmni has been set to
55                                                       
io scheduler noop
registered                                                    
io scheduler anticipatory registered
(default)                                  
Serial: 8250/16550 driver, 3 ports, IRQ sharing
disabled                        
serial8250.0: ttyS0 at MMIO 0x1c42000 (irq = 25) is a
16550A                    
serial8250.0: ttyS1 at MMIO 0x1d0c000 (irq = 53) is a
16550A                    
serial8250.0: ttyS2 at MMIO 0x1d0d000 (irq = 61) is a
16550A                    
console [ttyS2]
enabled                                                         
brd: module
loaded                                                              
davinci_emac_probe: using random MAC addr:
6a:c9:27:5d:9b:5c                    
emac-mii:
probed                                                                
dm9000 Ethernet Driver,
V1.31                                                   
console [netcon0]
enabled                                                       
netconsole: network logging
started                                             
Linux video capture interface:
v2.00                                            
Driver 'sd' needs updating - please use bus_type
methods                        
ahci ahci: forcing PORTS_IMPL to
0x1                                            
ahci ahci: AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl SATA
mode            
ahci ahci: flags: ncq sntf pm led clo only pmp pio slum
part                    
scsi0 :
ahci                                                                    
ata1: SATA max UDMA/133 irq
67                                                  

I still cannot boot my kernel using xenomai.

I would like to ask you some advice about the reasons why the kernel
boot stops at this point?

Thanks again for all the help

Best regards,

Flavio

On Seg, 2010-01-04 at 23:22 +0100, Gilles Chanteperdrix wrote:

> Flavio Alves wrote:
> > <1>Unable to handle kernel NULL pointer dereference at virtual address 00000000 
> > Looking at the code (and perform some analysis) I saw that the call that
> > is crashing the kernel is:
> > 
> >  __asm__("ldmia %1, %M0\n":
> > 	    "=r"(result.full): "r"(local_tsc), "m"(*local_tsc));
> > 
> > And looking into the implementation of this function for other
> > platforms, I can see that it is the same instruction, without
> > difference.
> 
> On all other platforms the "local_tsc" pointer is not NULL...
> 










Flavio de
Castro Alves
Filho
flavio.alves@domain.hid

Tel.: + 55 11
8494-5676
Embedded
Software
Services

www.phiinnovations.com











Escritórios::
São Paulo
Campinas



[-- Attachment #1.2: Type: text/html, Size: 22872 bytes --]

[-- Attachment #2: logo.gif --]
[-- Type: image/gif, Size: 5312 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-06 10:56                       ` Flavio Alves
@ 2010-01-06 11:01                         ` Gilles Chanteperdrix
  2010-01-06 11:38                           ` Flavio de Castro Alves Filho
  0 siblings, 1 reply; 38+ messages in thread
From: Gilles Chanteperdrix @ 2010-01-06 11:01 UTC (permalink / raw)
  To: flavio.alves; +Cc: xenomai

Flavio Alves wrote:
> Indeed ... 
> 
> Making this pointer not null (initializing the tsc pointer) solve this
> issue. Thanks again for your help.
> 
> Now I have the following situation in my xenomai boot process:

Your boot log is unreadable, please tell your MUA no to wrap it or post
it to some pastebin.

-- 
					    Gilles.


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-06 11:01                         ` Gilles Chanteperdrix
@ 2010-01-06 11:38                           ` Flavio de Castro Alves Filho
  2010-01-06 14:01                             ` Gilles Chanteperdrix
  0 siblings, 1 reply; 38+ messages in thread
From: Flavio de Castro Alves Filho @ 2010-01-06 11:38 UTC (permalink / raw)
  To: xenomai

Hello Gilles,

The boot log is the following (I hope this time it works).

Starting kernel ...

Uncompressing Linux.............................................................
Linux version 2.6.29-rc8-davinci1 (flavio@domain.hid) (gcc version 4.3.3 (So0
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
CPU: VIVT data cache, VIVT instruction cache
Machine: DaVinci DA850 EVM
Memory policy: ECC disabled, Data cache writeback
DA0850 variant 0x0
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 8128
Kernel command line: mem=32M console=ttyS2,115200n8 root=/dev/ram0 rw initrd=0x1
PID hash table entries: 128 (order: 7, 512 bytes)
I-pipe 1.13-03: pipeline enabled.
Console: colour dummy device 80x30
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Memory: 32MB = 32MB total
Memory: 24248KB available (3580K code, 368K data, 148K init)
Calibrating delay loop... 149.09 BogoMIPS (lpj=745472)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 880 bytes
NET: Registered protocol family 16
Pin I2C1_SCL already used for UART2_RXD.
Pin I2C1_SDA already used for UART2_TXD.
DaVinci: 144 gpio irqs
bio: create slab <bio-0> at 0
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
musb_hdrc: version 6.0, cppi4.1-dma, host, debug=0
Waiting for PHY clock good...
musb_hdrc: USB Host mode controller at fee00000 using DMA, IRQ 58
musb_hdrc musb_hdrc: MUSB HDRC host driver
musb_hdrc musb_hdrc: new USB bus registered, assigned bus number 1
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 1, 8192 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
TCP reno registered
NET: Registered protocol family 1
checking if image is initramfs...it isn't (no cpio magic); looks like an initrd
Freeing initrd memory: 4096K
I-pipe: Domain Xenomai registered.
Xenomai: hal/arm started.
Xenomai: real-time nucleus v2.4.9.1 (Big Bad Moon) loaded.
Xenomai: starting native API services.
Xenomai: starting POSIX services.
Xenomai: starting RTDM services.
msgmni has been set to 55
io scheduler noop registered
io scheduler anticipatory registered (default)
Serial: 8250/16550 driver, 3 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO 0x1c42000 (irq = 25) is a 16550A
serial8250.0: ttyS1 at MMIO 0x1d0c000 (irq = 53) is a 16550A
serial8250.0: ttyS2 at MMIO 0x1d0d000 (irq = 61) is a 16550A
console [ttyS2] enabled
brd: module loaded
davinci_emac_probe: using random MAC addr: 6a:c9:27:5d:9b:5c
emac-mii: probed
dm9000 Ethernet Driver, V1.31
console [netcon0] enabled
netconsole: network logging started
Linux video capture interface: v2.00
Driver 'sd' needs updating - please use bus_type methods
ahci ahci: forcing PORTS_IMPL to 0x1
ahci ahci: AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl SATA mode
ahci ahci: flags: ncq sntf pm led clo only pmp pio slum part
scsi0 : ahci
ata1: SATA max UDMA/133 irq 67

Thank you and best regards,

Flavio

Flavio de Castro Alves Filho
Embedded Software Services
www.phiinnovations.com
+55 11 84 94 56 76


2010/1/6 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
>
> Flavio Alves wrote:
> > Indeed ...
> >
> > Making this pointer not null (initializing the tsc pointer) solve this
> > issue. Thanks again for your help.
> >
> > Now I have the following situation in my xenomai boot process:
>
> Your boot log is unreadable, please tell your MUA no to wrap it or post
> it to some pastebin.
>
> --
>                                            Gilles.


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-06 11:38                           ` Flavio de Castro Alves Filho
@ 2010-01-06 14:01                             ` Gilles Chanteperdrix
  2010-01-06 19:16                               ` Flavio de Castro Alves Filho
  0 siblings, 1 reply; 38+ messages in thread
From: Gilles Chanteperdrix @ 2010-01-06 14:01 UTC (permalink / raw)
  To: Flavio de Castro Alves Filho; +Cc: xenomai

Flavio de Castro Alves Filho wrote:
> Hello Gilles,
> 
> The boot log is the following (I hope this time it works).
> 
> Starting kernel ...
> 
> Uncompressing Linux.............................................................
> Linux version 2.6.29-rc8-davinci1 (flavio@domain.hid) (gcc version 4.3.3 (So0
> CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
> CPU: VIVT data cache, VIVT instruction cache
> Machine: DaVinci DA850 EVM
> Memory policy: ECC disabled, Data cache writeback
> DA0850 variant 0x0
> Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 8128
> Kernel command line: mem=32M console=ttyS2,115200n8 root=/dev/ram0 rw initrd=0x1
> PID hash table entries: 128 (order: 7, 512 bytes)
> I-pipe 1.13-03: pipeline enabled.
> Console: colour dummy device 80x30
> Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
> Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
> Memory: 32MB = 32MB total
> Memory: 24248KB available (3580K code, 368K data, 148K init)
> Calibrating delay loop... 149.09 BogoMIPS (lpj=745472)
> Mount-cache hash table entries: 512
> CPU: Testing write buffer coherency: ok
> net_namespace: 880 bytes
> NET: Registered protocol family 16
> Pin I2C1_SCL already used for UART2_RXD.
> Pin I2C1_SDA already used for UART2_TXD.
> DaVinci: 144 gpio irqs
> bio: create slab <bio-0> at 0
> SCSI subsystem initialized
> usbcore: registered new interface driver usbfs
> usbcore: registered new interface driver hub
> usbcore: registered new device driver usb
> musb_hdrc: version 6.0, cppi4.1-dma, host, debug=0
> Waiting for PHY clock good...
> musb_hdrc: USB Host mode controller at fee00000 using DMA, IRQ 58
> musb_hdrc musb_hdrc: MUSB HDRC host driver
> musb_hdrc musb_hdrc: new USB bus registered, assigned bus number 1
> usb usb1: configuration #1 chosen from 1 choice
> hub 1-0:1.0: USB hub found
> hub 1-0:1.0: 1 port detected
> NET: Registered protocol family 2
> IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
> TCP established hash table entries: 1024 (order: 1, 8192 bytes)
> TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
> TCP: Hash tables configured (established 1024 bind 1024)
> TCP reno registered
> NET: Registered protocol family 1
> checking if image is initramfs...it isn't (no cpio magic); looks like an initrd
> Freeing initrd memory: 4096K
> I-pipe: Domain Xenomai registered.
> Xenomai: hal/arm started.
> Xenomai: real-time nucleus v2.4.9.1 (Big Bad Moon) loaded.
> Xenomai: starting native API services.
> Xenomai: starting POSIX services.
> Xenomai: starting RTDM services.
> msgmni has been set to 55
> io scheduler noop registered
> io scheduler anticipatory registered (default)
> Serial: 8250/16550 driver, 3 ports, IRQ sharing disabled
> serial8250.0: ttyS0 at MMIO 0x1c42000 (irq = 25) is a 16550A
> serial8250.0: ttyS1 at MMIO 0x1d0c000 (irq = 53) is a 16550A
> serial8250.0: ttyS2 at MMIO 0x1d0d000 (irq = 61) is a 16550A
> console [ttyS2] enabled
> brd: module loaded
> davinci_emac_probe: using random MAC addr: 6a:c9:27:5d:9b:5c
> emac-mii: probed
> dm9000 Ethernet Driver, V1.31
> console [netcon0] enabled
> netconsole: network logging started
> Linux video capture interface: v2.00
> Driver 'sd' needs updating - please use bus_type methods
> ahci ahci: forcing PORTS_IMPL to 0x1
> ahci ahci: AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl SATA mode
> ahci ahci: flags: ncq sntf pm led clo only pmp pio slum part
> scsi0 : ahci
> ata1: SATA max UDMA/133 irq 67
> 
> Thank you and best regards,

Well your log does not show any error. If there is a lockup, bisect to
find where it happens.

-- 
					    Gilles.


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-06 14:01                             ` Gilles Chanteperdrix
@ 2010-01-06 19:16                               ` Flavio de Castro Alves Filho
  2010-01-06 19:23                                 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 38+ messages in thread
From: Flavio de Castro Alves Filho @ 2010-01-06 19:16 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai

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

I believe there is a lockup during the irq handling process.

I could not find where it is blocking.

I performed the following tests:

1) add traces in every function related to interrupt ... and none was called

2) add traces in every function in time.c file. After the last message
("ata1: SATA max UDMA/133 irq 67"), the following functions were called:
- read_cycles()
- timer32_read()

Looking at these functions, they seam to be fine. I have no clue about where
to start debugging.

Thank you for all your help.

Regards,

Flavio

Flavio de Castro Alves Filho
Phi Innovations - Embedded Software Services
www.phiinnovations.com
Phone: +55 11 84 94 56 76
Skype: flavio.de.castro.alves.filho



2010/1/6 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>:
> Flavio de Castro Alves Filho wrote:
>> Hello Gilles,
>>
>> The boot log is the following (I hope this time it works).
>>
>> Starting kernel ...
>>
>> Uncompressing
Linux.............................................................
>> Linux version 2.6.29-rc8-davinci1 (flavio@domain.hid) (gcc version
4.3.3 (So0
>> CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
>> CPU: VIVT data cache, VIVT instruction cache
>> Machine: DaVinci DA850 EVM
>> Memory policy: ECC disabled, Data cache writeback
>> DA0850 variant 0x0
>> Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 8128
>> Kernel command line: mem=32M console=ttyS2,115200n8 root=/dev/ram0 rw
initrd=0x1
>> PID hash table entries: 128 (order: 7, 512 bytes)
>> I-pipe 1.13-03: pipeline enabled.
>> Console: colour dummy device 80x30
>> Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
>> Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
>> Memory: 32MB = 32MB total
>> Memory: 24248KB available (3580K code, 368K data, 148K init)
>> Calibrating delay loop... 149.09 BogoMIPS (lpj=745472)
>> Mount-cache hash table entries: 512
>> CPU: Testing write buffer coherency: ok
>> net_namespace: 880 bytes
>> NET: Registered protocol family 16
>> Pin I2C1_SCL already used for UART2_RXD.
>> Pin I2C1_SDA already used for UART2_TXD.
>> DaVinci: 144 gpio irqs
>> bio: create slab <bio-0> at 0
>> SCSI subsystem initialized
>> usbcore: registered new interface driver usbfs
>> usbcore: registered new interface driver hub
>> usbcore: registered new device driver usb
>> musb_hdrc: version 6.0, cppi4.1-dma, host, debug=0
>> Waiting for PHY clock good...
>> musb_hdrc: USB Host mode controller at fee00000 using DMA, IRQ 58
>> musb_hdrc musb_hdrc: MUSB HDRC host driver
>> musb_hdrc musb_hdrc: new USB bus registered, assigned bus number 1
>> usb usb1: configuration #1 chosen from 1 choice
>> hub 1-0:1.0: USB hub found
>> hub 1-0:1.0: 1 port detected
>> NET: Registered protocol family 2
>> IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
>> TCP established hash table entries: 1024 (order: 1, 8192 bytes)
>> TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
>> TCP: Hash tables configured (established 1024 bind 1024)
>> TCP reno registered
>> NET: Registered protocol family 1
>> checking if image is initramfs...it isn't (no cpio magic); looks like an
initrd
>> Freeing initrd memory: 4096K
>> I-pipe: Domain Xenomai registered.
>> Xenomai: hal/arm started.
>> Xenomai: real-time nucleus v2.4.9.1 (Big Bad Moon) loaded.
>> Xenomai: starting native API services.
>> Xenomai: starting POSIX services.
>> Xenomai: starting RTDM services.
>> msgmni has been set to 55
>> io scheduler noop registered
>> io scheduler anticipatory registered (default)
>> Serial: 8250/16550 driver, 3 ports, IRQ sharing disabled
>> serial8250.0: ttyS0 at MMIO 0x1c42000 (irq = 25) is a 16550A
>> serial8250.0: ttyS1 at MMIO 0x1d0c000 (irq = 53) is a 16550A
>> serial8250.0: ttyS2 at MMIO 0x1d0d000 (irq = 61) is a 16550A
>> console [ttyS2] enabled
>> brd: module loaded
>> davinci_emac_probe: using random MAC addr: 6a:c9:27:5d:9b:5c
>> emac-mii: probed
>> dm9000 Ethernet Driver, V1.31
>> console [netcon0] enabled
>> netconsole: network logging started
>> Linux video capture interface: v2.00
>> Driver 'sd' needs updating - please use bus_type methods
>> ahci ahci: forcing PORTS_IMPL to 0x1
>> ahci ahci: AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl SATA mode
>> ahci ahci: flags: ncq sntf pm led clo only pmp pio slum part
>> scsi0 : ahci
>> ata1: SATA max UDMA/133 irq 67
>>
>> Thank you and best regards,
>
> Well your log does not show any error. If there is a lockup, bisect to
> find where it happens.
>
> --
>                                            Gilles.
>

[-- Attachment #2: Type: text/html, Size: 5592 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-06 19:16                               ` Flavio de Castro Alves Filho
@ 2010-01-06 19:23                                 ` Gilles Chanteperdrix
  2010-01-08 14:11                                   ` Flavio de Castro Alves Filho
  0 siblings, 1 reply; 38+ messages in thread
From: Gilles Chanteperdrix @ 2010-01-06 19:23 UTC (permalink / raw)
  To: Flavio de Castro Alves Filho; +Cc: xenomai

Flavio de Castro Alves Filho wrote:
> I believe there is a lockup during the irq handling process.
> 
> I could not find where it is blocking.
> 
> I performed the following tests:
> 
> 1) add traces in every function related to interrupt ... and none was called

Well, obviously, you missed some, because your boot logs indicate
clearly that at least the timer interrupt is working.

If you are interested in what happens at I-pipe level, the functions you
are interested in are ipipe_grab_irq, ipipe_handle_irq,
ipipe_mach_demux_irq, etc...

> 
> 2) add traces in every function in time.c file. After the last message
> ("ata1: SATA max UDMA/133 irq 67"), the following functions were called:
> - read_cycles()
> - timer32_read()
> 
> Looking at these functions, they seam to be fine. I have no clue about where
> to start debugging.
> 
> Thank you for all your help.

Try this:

diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
index 5a324c9..22ddbe2 100644
--- a/arch/arm/mach-davinci/irq.c
+++ b/arch/arm/mach-davinci/irq.c
@@ -360,9 +360,11 @@ void __init davinci_irq_init(void)
        for (i = 0; i < DAVINCI_N_AINTC_IRQ; i++) {
                set_irq_chip(i, &davinci_irq_chip_0);
                set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+#ifndef CONFIG_IPIPE
                if (i != IRQ_TINT1_TINT34)
                        set_irq_handler(i, handle_edge_irq);
                else
+#endif /* CONFIG_IPIPE */
                        set_irq_handler(i, handle_level_irq);
        }
 }

-- 
					    Gilles.


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-06 19:23                                 ` Gilles Chanteperdrix
@ 2010-01-08 14:11                                   ` Flavio de Castro Alves Filho
  2010-01-08 14:35                                     ` Gilles Chanteperdrix
  0 siblings, 1 reply; 38+ messages in thread
From: Flavio de Castro Alves Filho @ 2010-01-08 14:11 UTC (permalink / raw)
  To: xenomai

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

Hello Gilles,

Unfortunately the patch didn't help... :-(

But ... adding more traces on the code, I can see the irq number when the
function __ipipe_grab_irq() is called.

When everything works fine, the irq number is 21 (IRQ_DA8XX_TINT12_0).

And, sometime, the irq number starts to be 22 (IRQ_DA8XX_TINT34_0). It is
the other timer present at the processor. I believe that, somehow, the
information about the timer (at least, the interrupt location) has been
changed by some code.

I will investigate more, according to these observations. I accept
suggestions :-)

Best regards,

Flavio

Flavio de Castro Alves Filho
Phi Innovations - Embedded Software Services
www.phiinnovations.com
Phone: +55 11 84 94 56 76
Skype: flavio.de.castro.alves.filho


2010/1/6 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>

> Flavio de Castro Alves Filho wrote:
> > I believe there is a lockup during the irq handling process.
> >
> > I could not find where it is blocking.
> >
> > I performed the following tests:
> >
> > 1) add traces in every function related to interrupt ... and none was
> called
>
> Well, obviously, you missed some, because your boot logs indicate
> clearly that at least the timer interrupt is working.
>
> If you are interested in what happens at I-pipe level, the functions you
> are interested in are ipipe_grab_irq, ipipe_handle_irq,
> ipipe_mach_demux_irq, etc...
>
> >
> > 2) add traces in every function in time.c file. After the last message
> > ("ata1: SATA max UDMA/133 irq 67"), the following functions were called:
> > - read_cycles()
> > - timer32_read()
> >
> > Looking at these functions, they seam to be fine. I have no clue about
> where
> > to start debugging.
> >
> > Thank you for all your help.
>
> Try this:
>
> diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
> index 5a324c9..22ddbe2 100644
> --- a/arch/arm/mach-davinci/irq.c
> +++ b/arch/arm/mach-davinci/irq.c
> @@ -360,9 +360,11 @@ void __init davinci_irq_init(void)
>        for (i = 0; i < DAVINCI_N_AINTC_IRQ; i++) {
>                set_irq_chip(i, &davinci_irq_chip_0);
>                set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
> +#ifndef CONFIG_IPIPE
>                if (i != IRQ_TINT1_TINT34)
>                        set_irq_handler(i, handle_edge_irq);
>                else
> +#endif /* CONFIG_IPIPE */
>                        set_irq_handler(i, handle_level_irq);
>        }
>  }
>
> --
>                                             Gilles.
>

[-- Attachment #2: Type: text/html, Size: 3200 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 14:11                                   ` Flavio de Castro Alves Filho
@ 2010-01-08 14:35                                     ` Gilles Chanteperdrix
  2010-01-08 14:58                                       ` Flavio de Castro Alves Filho
  0 siblings, 1 reply; 38+ messages in thread
From: Gilles Chanteperdrix @ 2010-01-08 14:35 UTC (permalink / raw)
  To: Flavio de Castro Alves Filho; +Cc: xenomai

Flavio de Castro Alves Filho wrote:
> Hello Gilles,
> 
> Unfortunately the patch didn't help... :-(
> 
> But ... adding more traces on the code, I can see the irq number when the
> function __ipipe_grab_irq() is called.
> 
> When everything works fine, the irq number is 21 (IRQ_DA8XX_TINT12_0).
> 
> And, sometime, the irq number starts to be 22 (IRQ_DA8XX_TINT34_0). It is
> the other timer present at the processor. I believe that, somehow, the
> information about the timer (at least, the interrupt location) has been
> changed by some code.
> 
> I will investigate more, according to these observations. I accept
> suggestions :-)

Are you sure you recompiled the kernel ? This other timer's irq seems to
be the one for which the handle_edge_irq handler is used, which could
really cause a lockup.

Anyway, the reason why this other timer is used is probably because
clockevent decided it had a better score. But that should not cause a
lockup, unless handle_edge_irq is used.

So, you are probably better off using that timer for xenomai too. If you
do not want that, you will have to give a higher score to the timer you
want Linux to use.

-- 
					    Gilles.


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 14:35                                     ` Gilles Chanteperdrix
@ 2010-01-08 14:58                                       ` Flavio de Castro Alves Filho
  2010-01-08 15:36                                         ` Gilles Chanteperdrix
  0 siblings, 1 reply; 38+ messages in thread
From: Flavio de Castro Alves Filho @ 2010-01-08 14:58 UTC (permalink / raw)
  To: xenomai

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

In fact,

The problem is not really related to the other timer, I believe.

Before the timer with irq 22 is called, another irq is called by
__ipipe_grab_irq(): the irq number 12 (IRQ_DA8XX_CCERRINT).

Now I'm looking for the place there this irq number is passed.

And thank you for this important information about the timers.


Flavio de Castro Alves Filho
Phi Innovations - Embedded Software Services
www.phiinnovations.com
Phone: +55 11 84 94 56 76
Skype: flavio.de.castro.alves.filho


2010/1/8 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>

> Flavio de Castro Alves Filho wrote:
> > Hello Gilles,
> >
> > Unfortunately the patch didn't help... :-(
> >
> > But ... adding more traces on the code, I can see the irq number when the
> > function __ipipe_grab_irq() is called.
> >
> > When everything works fine, the irq number is 21 (IRQ_DA8XX_TINT12_0).
> >
> > And, sometime, the irq number starts to be 22 (IRQ_DA8XX_TINT34_0). It is
> > the other timer present at the processor. I believe that, somehow, the
> > information about the timer (at least, the interrupt location) has been
> > changed by some code.
> >
> > I will investigate more, according to these observations. I accept
> > suggestions :-)
>
> Are you sure you recompiled the kernel ? This other timer's irq seems to
> be the one for which the handle_edge_irq handler is used, which could
> really cause a lockup.
>
> Anyway, the reason why this other timer is used is probably because
> clockevent decided it had a better score. But that should not cause a
> lockup, unless handle_edge_irq is used.
>
> So, you are probably better off using that timer for xenomai too. If you
> do not want that, you will have to give a higher score to the timer you
> want Linux to use.
>
> --
>                                             Gilles.
>

[-- Attachment #2: Type: text/html, Size: 2430 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 14:58                                       ` Flavio de Castro Alves Filho
@ 2010-01-08 15:36                                         ` Gilles Chanteperdrix
  2010-01-08 17:43                                           ` Flavio de Castro Alves Filho
  0 siblings, 1 reply; 38+ messages in thread
From: Gilles Chanteperdrix @ 2010-01-08 15:36 UTC (permalink / raw)
  To: Flavio de Castro Alves Filho; +Cc: xenomai

Flavio de Castro Alves Filho wrote:
> In fact,
> 
> The problem is not really related to the other timer, I believe.
> 
> Before the timer with irq 22 is called, another irq is called by
> __ipipe_grab_irq(): the irq number 12 (IRQ_DA8XX_CCERRINT).
> 
> Now I'm looking for the place there this irq number is passed.
> 
> And thank you for this important information about the timers.

I think your problem really is that irq22 uses handle_edge_irq, somehow.
Could you check whether this is the case, for instance by putting a
printk in the __ipipe_ack_edge_irq function, file kernel/irq/chip.c ?

-- 
					    Gilles.


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 15:36                                         ` Gilles Chanteperdrix
@ 2010-01-08 17:43                                           ` Flavio de Castro Alves Filho
  2010-01-08 18:02                                             ` Flavio de Castro Alves Filho
  0 siblings, 1 reply; 38+ messages in thread
From: Flavio de Castro Alves Filho @ 2010-01-08 17:43 UTC (permalink / raw)
  To: xenomai

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

Hello,

The functions level_egde_irq and __ipipe_ack_edge_irq are not called during
boot process.

I'm sending attached the boot log with my traces separated

irq = 21
__ipipe_mach_irq_mux_p false

Linux version 2.6.29-rc8-davinci1 (flavio@domain.hid) (gcc version 4.3.3
(Sourcery G++ Lite 2009q1-203) ) #57 PREEMPT Fri Jan 8 13:58:39 BRST 2010
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
CPU: VIVT data cache, VIVT instruction cache
Machine: DaVinci DA850 EVM
Memory policy: ECC disabled, Data cache writeback
DA0850 variant 0x0
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 8128
Kernel command line: mem=32M console=ttyS2,115200n8 root=/dev/ram0 rw
initrd=0xc1180000,4M ip=10.1.1.2:10.1.1.1
PID hash table entries: 128 (order: 7, 512 bytes)
I-pipe 1.13-03: pipeline enabled.
Console: colour dummy device 80x30
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Memory: 32MB = 32MB total
Memory: 24236KB available (3592K code, 367K data, 148K init)
Calibrating delay loop... 86.63 BogoMIPS (lpj=433152)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 880 bytes
NET: Registered protocol family 16
Pin I2C1_SCL already used for UART2_RXD.
Pin I2C1_SDA already used for UART2_TXD.
DaVinci: 144 gpio irqs
bio: create slab <bio-0> at 0
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
musb_hdrc: version 6.0, cppi4.1-dma, host, debug=0
Waiting for PHY clock good...
musb_hdrc: USB Host mode controller at fee00000 using DMA, IRQ 58
musb_hdrc musb_hdrc: MUSB HDRC host driver
musb_hdrc musb_hdrc: new USB bus registered, assigned bus number 1
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 1024 (order: 1, 8192 bytes)
TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
TCP reno registered
NET: Registered protocol family 1
checking if image is initramfs...it isn't (no cpio magic); looks like an
initrd
Freeing initrd memory: 4096K
I-pipe: Domain Xenomai registered.
Xenomai: hal/arm started.
Xenomai: real-time nucleus v2.4.9.1 (Big Bad Moon) loaded.
Xenomai: starting native API services.
Xenomai: starting POSIX services.
Xenomai: starting RTDM services.
msgmni has been set to 55
io scheduler noop registered
io scheduler anticipatory registered (default)
Serial: 8250/16550 driver, 3 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO 0x1c42000 (irq = 25) is a 16550A
serial8250.0: ttyS1 at MMIO 0x1d0c000 (irq = 53) is a 16550A
serial8250.0: ttyS2 at MMIO 0x1d0d000 (irq = 61) is a 16550A
console [ttyS2] enabled
brd: module loaded
davinci_emac_probe: using random MAC addr: fe:1e:01:fe:ce:b4
emac-mii: probed
dm9000 Ethernet Driver, V1.31
console [netcon0] enabled
netconsole: network logging started
Linux video capture interface: v2.00
Driver 'sd' needs updating - please use bus_type methods
davinci_nand davinci_nand.1: Using 4-bit hardware ECC - Syndrome
No NAND device found!!!

irq = 12
__ipipe_mach_irq_mux_p false
dma_ccerr_handler
IRQ_HANDLED
irq = 12
__ipipe_mach_irq_mux_p false
dma_ccerr_handler
IRQ_HANDLED

m25p80 spi1.0: m25p64 (8192 Kbytes)
Creating 3 MTD partitions on "m25p80":
0x000000000000-0x000000040000 : "U-Boot"
0x000000040000-0x000000044000 : "U-Boot Environment"
Moving partition 2: 0x000000044000 -> 0x000000050000
0x000000050000-0x000000800000 : "Linux"
dm_spi.1: davinci SPI Controller driver at 0xfef0e000 (irq = 56) use_dma=1
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
usb1 usb1: DA8XX OHCI
usb1 usb1: new USB bus registered, assigned bus number 2
usb1 usb1: irq 59, io mem 0x01e25000

<some time later ... a couple of minutes>

irq = 22
__ipipe_mach_irq_mux_p false
irq = 22
__ipipe_mach_irq_mux_p false


Best regards,

Flavio

Flavio de Castro Alves Filho
Phi Innovations - Embedded Software Services
www.phiinnovations.com
Phone: +55 11 84 94 56 76
Skype: flavio.de.castro.alves.filho


2010/1/8 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>

> Flavio de Castro Alves Filho wrote:
> > In fact,
> >
> > The problem is not really related to the other timer, I believe.
> >
> > Before the timer with irq 22 is called, another irq is called by
> > __ipipe_grab_irq(): the irq number 12 (IRQ_DA8XX_CCERRINT).
> >
> > Now I'm looking for the place there this irq number is passed.
> >
> > And thank you for this important information about the timers.
>
> I think your problem really is that irq22 uses handle_edge_irq, somehow.
> Could you check whether this is the case, for instance by putting a
> printk in the __ipipe_ack_edge_irq function, file kernel/irq/chip.c ?
>
> --
>                                             Gilles.
>

[-- Attachment #2: Type: text/html, Size: 6057 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 17:43                                           ` Flavio de Castro Alves Filho
@ 2010-01-08 18:02                                             ` Flavio de Castro Alves Filho
  2010-01-08 18:08                                               ` Gilles Chanteperdrix
  0 siblings, 1 reply; 38+ messages in thread
From: Flavio de Castro Alves Filho @ 2010-01-08 18:02 UTC (permalink / raw)
  To: xenomai

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

Another interesting information: when I remove the Xenomai from the
compilation options, and still letting the i-pipe compilation, the boot
starts correctly.

Is it correct?

Flavio de Castro Alves Filho
Phi Innovations - Embedded Software Services
www.phiinnovations.com
Phone: +55 11 84 94 56 76
Skype: flavio.de.castro.alves.filho


2010/1/8 Flavio de Castro Alves Filho <flavio.alves@domain.hid>

> Hello,
>
> The functions level_egde_irq and __ipipe_ack_edge_irq are not called during
> boot process.
>
> I'm sending attached the boot log with my traces separated
>
> irq = 21
> __ipipe_mach_irq_mux_p false
>
> Linux version 2.6.29-rc8-davinci1 (flavio@domain.hid) (gcc version
> 4.3.3 (Sourcery G++ Lite 2009q1-203) ) #57 PREEMPT Fri Jan 8 13:58:39 BRST
> 2010
>
> CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
> CPU: VIVT data cache, VIVT instruction cache
> Machine: DaVinci DA850 EVM
> Memory policy: ECC disabled, Data cache writeback
> DA0850 variant 0x0
> Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 8128
> Kernel command line: mem=32M console=ttyS2,115200n8 root=/dev/ram0 rw
> initrd=0xc1180000,4M ip=10.1.1.2:10.1.1.1
>
> PID hash table entries: 128 (order: 7, 512 bytes)
> I-pipe 1.13-03: pipeline enabled.
> Console: colour dummy device 80x30
> Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
> Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
> Memory: 32MB = 32MB total
> Memory: 24236KB available (3592K code, 367K data, 148K init)
> Calibrating delay loop... 86.63 BogoMIPS (lpj=433152)
>
> Mount-cache hash table entries: 512
> CPU: Testing write buffer coherency: ok
> net_namespace: 880 bytes
> NET: Registered protocol family 16
> Pin I2C1_SCL already used for UART2_RXD.
> Pin I2C1_SDA already used for UART2_TXD.
> DaVinci: 144 gpio irqs
> bio: create slab <bio-0> at 0
> SCSI subsystem initialized
> usbcore: registered new interface driver usbfs
> usbcore: registered new interface driver hub
> usbcore: registered new device driver usb
> musb_hdrc: version 6.0, cppi4.1-dma, host, debug=0
> Waiting for PHY clock good...
> musb_hdrc: USB Host mode controller at fee00000 using DMA, IRQ 58
> musb_hdrc musb_hdrc: MUSB HDRC host driver
> musb_hdrc musb_hdrc: new USB bus registered, assigned bus number 1
> usb usb1: configuration #1 chosen from 1 choice
> hub 1-0:1.0: USB hub found
> hub 1-0:1.0: 1 port detected
> NET: Registered protocol family 2
> IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
> TCP established hash table entries: 1024 (order: 1, 8192 bytes)
> TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
> TCP: Hash tables configured (established 1024 bind 1024)
> TCP reno registered
> NET: Registered protocol family 1
> checking if image is initramfs...it isn't (no cpio magic); looks like an
> initrd
> Freeing initrd memory: 4096K
> I-pipe: Domain Xenomai registered.
> Xenomai: hal/arm started.
> Xenomai: real-time nucleus v2.4.9.1 (Big Bad Moon) loaded.
> Xenomai: starting native API services.
> Xenomai: starting POSIX services.
> Xenomai: starting RTDM services.
> msgmni has been set to 55
> io scheduler noop registered
> io scheduler anticipatory registered (default)
> Serial: 8250/16550 driver, 3 ports, IRQ sharing disabled
> serial8250.0: ttyS0 at MMIO 0x1c42000 (irq = 25) is a 16550A
> serial8250.0: ttyS1 at MMIO 0x1d0c000 (irq = 53) is a 16550A
> serial8250.0: ttyS2 at MMIO 0x1d0d000 (irq = 61) is a 16550A
> console [ttyS2] enabled
> brd: module loaded
> davinci_emac_probe: using random MAC addr: fe:1e:01:fe:ce:b4
>
> emac-mii: probed
> dm9000 Ethernet Driver, V1.31
> console [netcon0] enabled
> netconsole: network logging started
> Linux video capture interface: v2.00
> Driver 'sd' needs updating - please use bus_type methods
> davinci_nand davinci_nand.1: Using 4-bit hardware ECC - Syndrome
> No NAND device found!!!
>
> irq = 12
> __ipipe_mach_irq_mux_p false
> dma_ccerr_handler
> IRQ_HANDLED
> irq = 12
> __ipipe_mach_irq_mux_p false
> dma_ccerr_handler
> IRQ_HANDLED
>
> m25p80 spi1.0: m25p64 (8192 Kbytes)
> Creating 3 MTD partitions on "m25p80":
> 0x000000000000-0x000000040000 : "U-Boot"
> 0x000000040000-0x000000044000 : "U-Boot Environment"
> Moving partition 2: 0x000000044000 -> 0x000000050000
> 0x000000050000-0x000000800000 : "Linux"
> dm_spi.1: davinci SPI Controller driver at 0xfef0e000 (irq = 56) use_dma=1
> ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
> usb1 usb1: DA8XX OHCI
> usb1 usb1: new USB bus registered, assigned bus number 2
> usb1 usb1: irq 59, io mem 0x01e25000
>
> <some time later ... a couple of minutes>
>
> irq = 22
> __ipipe_mach_irq_mux_p false
> irq = 22
> __ipipe_mach_irq_mux_p false
>
>
> Best regards,
>
> Flavio
>
>
> Flavio de Castro Alves Filho
> Phi Innovations - Embedded Software Services
> www.phiinnovations.com
> Phone: +55 11 84 94 56 76
> Skype: flavio.de.castro.alves.filho
>
>
> 2010/1/8 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
>
>> Flavio de Castro Alves Filho wrote:
>> > In fact,
>> >
>> > The problem is not really related to the other timer, I believe.
>> >
>> > Before the timer with irq 22 is called, another irq is called by
>> > __ipipe_grab_irq(): the irq number 12 (IRQ_DA8XX_CCERRINT).
>> >
>> > Now I'm looking for the place there this irq number is passed.
>> >
>> > And thank you for this important information about the timers.
>>
>> I think your problem really is that irq22 uses handle_edge_irq, somehow.
>> Could you check whether this is the case, for instance by putting a
>> printk in the __ipipe_ack_edge_irq function, file kernel/irq/chip.c ?
>>
>> --
>>                                             Gilles.
>>
>
>

[-- Attachment #2: Type: text/html, Size: 7066 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 18:02                                             ` Flavio de Castro Alves Filho
@ 2010-01-08 18:08                                               ` Gilles Chanteperdrix
  2010-01-08 19:27                                                 ` Flavio de Castro Alves Filho
  0 siblings, 1 reply; 38+ messages in thread
From: Gilles Chanteperdrix @ 2010-01-08 18:08 UTC (permalink / raw)
  To: Flavio de Castro Alves Filho; +Cc: xenomai

Flavio de Castro Alves Filho wrote:
> Another interesting information: when I remove the Xenomai from the
> compilation options, and still letting the i-pipe compilation, the boot
> starts correctly.
> 
> Is it correct?

It means that there is something wrong when Xenomai takes over the timer
management. And thinking more about it, the problem you have is probably
the one described in tips and tricks number 4.

http://www.xenomai.org/index.php/I-pipe:ArmPorting#Tips_and_tricks.

-- 
					    Gilles.


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 18:08                                               ` Gilles Chanteperdrix
@ 2010-01-08 19:27                                                 ` Flavio de Castro Alves Filho
  2010-01-08 19:31                                                   ` Gilles Chanteperdrix
  2010-01-08 19:32                                                   ` Gilles Chanteperdrix
  0 siblings, 2 replies; 38+ messages in thread
From: Flavio de Castro Alves Filho @ 2010-01-08 19:27 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai

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

Not this time :-(

I increased the value, but it didn't work.

I was thinking here. The problem related in the first message of this thread
is exactly the same problem that I am having:

http://www.mail-archive.com/xenomai@xenomai.org


How this problem was solved? I couldn't find (or understand) the answer.

Flavio de Castro Alves Filho
Phi Innovations - Embedded Software Services
www.phiinnovations.com
Phone: +55 11 84 94 56 76
Skype: flavio.de.castro.alves.filho


2010/1/8 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>

> Flavio de Castro Alves Filho wrote:
> > Another interesting information: when I remove the Xenomai from the
> > compilation options, and still letting the i-pipe compilation, the boot
> > starts correctly.
> >
> > Is it correct?
>
> It means that there is something wrong when Xenomai takes over the timer
> management. And thinking more about it, the problem you have is probably
> the one described in tips and tricks number 4.
>
> http://www.xenomai.org/index.php/I-pipe:ArmPorting#Tips_and_tricks.
>
> --
>                                             Gilles.
>

[-- Attachment #2: Type: text/html, Size: 1825 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 19:27                                                 ` Flavio de Castro Alves Filho
@ 2010-01-08 19:31                                                   ` Gilles Chanteperdrix
  2010-01-08 19:42                                                     ` Flavio de Castro Alves Filho
  2010-01-08 19:32                                                   ` Gilles Chanteperdrix
  1 sibling, 1 reply; 38+ messages in thread
From: Gilles Chanteperdrix @ 2010-01-08 19:31 UTC (permalink / raw)
  To: Flavio de Castro Alves Filho; +Cc: xenomai

Flavio de Castro Alves Filho wrote:
> Not this time :-(
> 
> I increased the value, but it didn't work.
> 
> I was thinking here. The problem related in the first message of this thread
> is exactly the same problem that I am having:
> 
> http://www.mail-archive.com/xenomai@xenomai.org

The answer is here:
http://www.mail-archive.com/xenomai@xenomai.org

Sergey copied the PXA hardware timer support (a free-running counter
with a match register) instead of writing the code for his real hardware
timer (a decrementer). This could not work.

So, now, the only thing I can suggest you is to show us your code.

-- 
					    Gilles.


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 19:27                                                 ` Flavio de Castro Alves Filho
  2010-01-08 19:31                                                   ` Gilles Chanteperdrix
@ 2010-01-08 19:32                                                   ` Gilles Chanteperdrix
  1 sibling, 0 replies; 38+ messages in thread
From: Gilles Chanteperdrix @ 2010-01-08 19:32 UTC (permalink / raw)
  To: Flavio de Castro Alves Filho; +Cc: xenomai

Flavio de Castro Alves Filho wrote:
> Not this time :-(
> 
> I increased the value, but it didn't work.

This is not what you should be doing. What you should be doing is read
the datasheet to know what the minimum value is.

-- 
					    Gilles.


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 19:31                                                   ` Gilles Chanteperdrix
@ 2010-01-08 19:42                                                     ` Flavio de Castro Alves Filho
  2010-01-08 19:45                                                       ` Gilles Chanteperdrix
  0 siblings, 1 reply; 38+ messages in thread
From: Flavio de Castro Alves Filho @ 2010-01-08 19:42 UTC (permalink / raw)
  To: xenomai


[-- Attachment #1.1: Type: text/plain, Size: 937 bytes --]

Of course :-)

As I don't know the best way to send it, I attached the files.

I hope everything is in there. I'm sorry if you find some ugly commented
debug code.

2010/1/8 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>

> Flavio de Castro Alves Filho wrote:
> > Not this time :-(
> >
> > I increased the value, but it didn't work.
> >
> > I was thinking here. The problem related in the first message of this
> thread
> > is exactly the same problem that I am having:
> >
> > http://www.mail-archive.com/xenomai@xenomai.org
>
> The answer is here:
> http://www.mail-archive.com/xenomai@xenomai.org
>
> Sergey copied the PXA hardware timer support (a free-running counter
> with a match register) instead of writing the code for his real hardware
> timer (a decrementer). This could not work.
>
> So, now, the only thing I can suggest you is to show us your code.
>
> --
>                                             Gilles.
>

[-- Attachment #1.2: Type: text/html, Size: 1566 bytes --]

[-- Attachment #2: gpio.c --]
[-- Type: text/x-csrc, Size: 9854 bytes --]

/*
 * TI DaVinci GPIO Support
 *
 * Copyright (c) 2006-2007 David Brownell
 * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
 *
 * 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
 * (at your option) any later version.
 */

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/bitops.h>

#include <mach/cpu.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/gpio.h>

#include <asm/mach/irq.h>

#include <asm/ipipe.h>

static DEFINE_SPINLOCK(gpio_lock);

struct davinci_gpio {
	struct gpio_chip	chip;
	struct gpio_controller	*__iomem regs;
};

static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];

static unsigned __initdata ngpio;

/* create a non-inlined version */
static struct gpio_controller *__iomem __init gpio2controller(unsigned gpio)
{
	return __gpio_to_controller(gpio);
}


/*--------------------------------------------------------------------------*/

/*
 * board setup code *MUST* set PINMUX0 and PINMUX1 as
 * needed, and enable the GPIO clock.
 */

static int davinci_direction_in(struct gpio_chip *chip, unsigned offset)
{
	struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
	struct gpio_controller *__iomem g = d->regs;
	u32 temp;

	spin_lock(&gpio_lock);
	temp = __raw_readl(&g->dir);
	temp |= (1 << offset);
	__raw_writel(temp, &g->dir);
	spin_unlock(&gpio_lock);

	return 0;
}

/*
 * Read the pin's value (works even if it's set up as output);
 * returns zero/nonzero.
 *
 * Note that changes are synched to the GPIO clock, so reading values back
 * right after you've set them may give old values.
 */
static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset)
{
	struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
	struct gpio_controller *__iomem g = d->regs;

	return (1 << offset) & __raw_readl(&g->in_data);
}

static int
davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value)
{
	struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
	struct gpio_controller *__iomem g = d->regs;
	u32 temp;
	u32 mask = 1 << offset;

	spin_lock(&gpio_lock);
	temp = __raw_readl(&g->dir);
	temp &= ~mask;
	__raw_writel(mask, value ? &g->set_data : &g->clr_data);
	__raw_writel(temp, &g->dir);
	spin_unlock(&gpio_lock);
	return 0;
}

/*
 * Assuming the pin is muxed as a gpio output, set its output value.
 */
static void
davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
	struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
	struct gpio_controller *__iomem g = d->regs;

	__raw_writel((1 << offset), value ? &g->set_data : &g->clr_data);
}

static int __init davinci_gpio_setup(void)
{
	int i, base;

	/* The gpio banks conceptually expose a segmented bitmap,
	 * and "ngpio" is one more than the largest zero-based
	 * bit index that's valid.
	 */
	if (cpu_is_davinci_dm355()) {		/* or dm335() */
		ngpio = 104;
	} else if (cpu_is_davinci_dm644x()) {	/* or dm337() */
		ngpio = 71;
	} else if (cpu_is_davinci_dm646x()) {
		/* NOTE:  each bank has several "reserved" bits,
		 * unusable as GPIOs.  Only 33 of the GPIO numbers
		 * are usable, and we're not rejecting the others.
		 */
		ngpio = 43;
	} else if (cpu_is_da830()) {		/* or da830 */
		ngpio = 128;
	} else if (cpu_is_da850()) {
		ngpio = 144;
	} else {
		/* if cpu_is_davinci_dm643x() ngpio = 111 */
		pr_err("GPIO setup:  how many GPIOs?\n");
		return -EINVAL;
	}

	if (WARN_ON(DAVINCI_N_GPIO < ngpio))
		ngpio = DAVINCI_N_GPIO;

	for (i = 0, base = 0; base < ngpio; i++, base += 32) {
		chips[i].chip.label = "DaVinci";

		chips[i].chip.direction_input = davinci_direction_in;
		chips[i].chip.get = davinci_gpio_get;
		chips[i].chip.direction_output = davinci_direction_out;
		chips[i].chip.set = davinci_gpio_set;

		chips[i].chip.base = base;
		chips[i].chip.ngpio = ngpio - base;
		if (chips[i].chip.ngpio > 32)
			chips[i].chip.ngpio = 32;

		chips[i].regs = gpio2controller(base);

		gpiochip_add(&chips[i].chip);
	}

	return 0;
}
pure_initcall(davinci_gpio_setup);

/*--------------------------------------------------------------------------*/
/*
 * We expect irqs will normally be set up as input pins, but they can also be
 * used as output pins ... which is convenient for testing.
 *
 * NOTE:  The first few GPIOs also have direct INTC hookups in addition
 * to their GPIOBNK0 irq, with a bit less overhead but less flexibility
 * on triggering (e.g. no edge options).  We don't try to use those.
 *
 * All those INTC hookups (direct, plus several IRQ banks) can also
 * serve as EDMA event triggers.
 */

static void gpio_irq_disable(unsigned irq)
{
	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
	u32 mask = __gpio_mask(irq_to_gpio(irq));

	__raw_writel(mask, &g->clr_falling);
	__raw_writel(mask, &g->clr_rising);
}

static void gpio_irq_enable(unsigned irq)
{
	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
	u32 mask = __gpio_mask(irq_to_gpio(irq));

	if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING)
		__raw_writel(mask, &g->set_falling);
	if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING)
		__raw_writel(mask, &g->set_rising);
}

static int gpio_irq_type(unsigned irq, unsigned trigger)
{
	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
	u32 mask = __gpio_mask(irq_to_gpio(irq));

	if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
		return -EINVAL;

	irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
	irq_desc[irq].status |= trigger;

	__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
		     ? &g->set_falling : &g->clr_falling);
	__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
		     ? &g->set_rising : &g->clr_rising);
	return 0;
}

static struct irq_chip gpio_irqchip = {
	.name		= "GPIO",
	.enable		= gpio_irq_enable,
	.disable	= gpio_irq_disable,
	.set_type	= gpio_irq_type,
};

static void
gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
	u32 mask = 0xffff;

	/* we only care about one bank */
	if (irq & 1)
		mask <<= 16;

	/* temporarily mask (level sensitive) parent IRQ */
	desc->chip->ack(irq);
	while (1) {
		u32		status;
		int		n;
		int		res;

		/* ack any irqs */
		status = __raw_readl(&g->intstat) & mask;
		if (!status)
			break;
		__raw_writel(status, &g->intstat);
		if (irq & 1)
			status >>= 16;

		/* now demux them to the right lowlevel handler */
		n = (int)get_irq_data(irq);
		while (status) {
			res = ffs(status);
			n += res;
			generic_handle_irq(n - 1);
			status >>= res;
		}
	}
	desc->chip->unmask(irq);
	/* now it may re-trigger */
}

#ifdef CONFIG_IPIPE

/* Flavio Alves: for debugging */
extern void printascii(const char *);

void __ipipe_mach_demux_irq(unsigned irq, struct pt_regs *regs)
{
	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
	struct irq_desc *desc;
	u32 mask = 0xffff;

	//printascii("1__ipipe_mach_demux_irq\n");

	/* we only care about one bank */
	if (irq & 1)
		mask <<= 16;

	desc = &irq_desc[irq];

	/* temporarily mask (level sensitive) parent IRQ */
	desc->chip->ack(irq);
	while (1) {
		u32		status;
		int		n;
		int		res;

		/* ack any irqs */
		status = __raw_readl(&g->intstat) & mask;
		if (!status)
			break;
		__raw_writel(status, &g->intstat);
		if (irq & 1)
			status >>= 16;

		/* now demux them to the right lowlevel handler */
		n = (int)get_irq_data(irq);
		while (status) {
			res = ffs(status);
			n += res;
			__ipipe_handle_irq((n-1),regs);
			status >>= res;
		}
	}
	desc->chip->unmask(irq);
	/* now it may re-trigger */
}
#endif /* CONFIG_IPIPE */

/*
 * NOTE:  for suspend/resume, probably best to make a platform_device with
 * suspend_late/resume_resume calls hooking into results of the set_wake()
 * calls ... so if no gpios are wakeup events the clock can be disabled,
 * with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0
 * (dm6446) can be set appropriately for GPIOV33 pins.
 */

static int __init davinci_gpio_irq_setup(void)
{
	unsigned	gpio, irq, bank;
	unsigned	bank_irq;
	struct clk	*clk;
	u32		binten = 0;

	if (cpu_is_davinci_dm355()) {		/* or dm335() */
		bank_irq = IRQ_DM355_GPIOBNK0;
	} else if (cpu_is_davinci_dm644x()) {
		bank_irq = IRQ_GPIOBNK0;
	} else if (cpu_is_davinci_dm646x()) {
		bank_irq = IRQ_DM646X_GPIOBNK0;
	} else if (cpu_is_da8xx()) {
		bank_irq = IRQ_DA8XX_GPIO0;
	} else {
		printk(KERN_ERR "Don't know first GPIO bank IRQ.\n");
		return -EINVAL;
	}

	clk = clk_get(NULL, "gpio");
	if (IS_ERR(clk)) {
		printk(KERN_ERR "Error %ld getting gpio clock?\n",
		       PTR_ERR(clk));
		return PTR_ERR(clk);
	}
	clk_enable(clk);

	for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
			gpio < ngpio;
			bank++, bank_irq++) {
		struct gpio_controller	*__iomem g = gpio2controller(gpio);
		unsigned		i;

		__raw_writel(~0, &g->clr_falling);
		__raw_writel(~0, &g->clr_rising);

		/* set up all irqs in this bank */
		set_irq_chained_handler(bank_irq, gpio_irq_handler);
		set_irq_chip_data(bank_irq, g);
		set_irq_data(bank_irq, (void *)irq);

		for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
			set_irq_chip(irq, &gpio_irqchip);
			set_irq_chip_data(irq, g);
			set_irq_handler(irq, handle_simple_irq);
			set_irq_flags(irq, IRQF_VALID);
		}

		binten |= BIT(bank);
	}

	/* BINTEN -- per-bank interrupt enable. genirq would also let these
	 * bits be set/cleared dynamically.
	 */
	__raw_writel(binten, (void *__iomem)
		     IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));

	printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));

	return 0;
}
arch_initcall(davinci_gpio_irq_setup);

[-- Attachment #3: irq.c --]
[-- Type: text/x-csrc, Size: 14712 bytes --]

/*
 * Interrupt handler for DaVinci boards.
 *
 * Copyright (C) 2006 Texas Instruments.
 *
 * 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
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>

#include <mach/hardware.h>
#include <mach/cpu.h>
#include <asm/io.h>
#include <asm/mach/irq.h>

#define IRQ_BIT(irq)		((irq) & 0x1f)

#define FIQ_REG0_OFFSET		0x0000
#define FIQ_REG1_OFFSET		0x0004
#define IRQ_REG0_OFFSET		0x0008
#define IRQ_REG1_OFFSET		0x000C
#define IRQ_ENT_REG0_OFFSET	0x0018
#define IRQ_ENT_REG1_OFFSET	0x001C
#define IRQ_INCTL_REG_OFFSET	0x0020
#define IRQ_EABASE_REG_OFFSET	0x0024
#define IRQ_INTPRI0_REG_OFFSET	0x0030
#define IRQ_INTPRI7_REG_OFFSET	0x004C

const u8 *davinci_def_priorities;

#define INTC_BASE IO_ADDRESS(DAVINCI_ARM_INTC_BASE)

static inline unsigned int davinci_irq_readl(int offset)
{
	return __raw_readl(INTC_BASE + offset);
}

static inline void davinci_irq_writel(unsigned long value, int offset)
{
	__raw_writel(value, INTC_BASE + offset);
}

/* Disable interrupt */
static void davinci_mask_irq(unsigned int irq)
{
	unsigned int mask;
	u32 l;

	mask = 1 << IRQ_BIT(irq);

	if (irq > 31) {
		l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
		l &= ~mask;
		davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
	} else {
		l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
		l &= ~mask;
		davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
	}
}

/* Enable interrupt */
static void davinci_unmask_irq(unsigned int irq)
{
	unsigned int mask;
	u32 l;

	mask = 1 << IRQ_BIT(irq);

	if (irq > 31) {
		l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
		l |= mask;
		davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
	} else {
		l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
		l |= mask;
		davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
	}
}

/* EOI interrupt */
static void davinci_ack_irq(unsigned int irq)
{
	unsigned int mask;

	mask = 1 << IRQ_BIT(irq);

	if (irq > 31)
		davinci_irq_writel(mask, IRQ_REG1_OFFSET);
	else
		davinci_irq_writel(mask, IRQ_REG0_OFFSET);
}

static struct irq_chip davinci_irq_chip_0 = {
	.name	= "AINTC",
	.ack	= davinci_ack_irq,
	.mask	= davinci_mask_irq,
#ifdef CONFIG_IPIPE
	.mask_ack = davinci_mask_irq,
#endif /* CONFIG_IPIPE */
	.unmask = davinci_unmask_irq,
};

#ifdef CONFIG_IPIPE
static const u8 da850_default_priorities[DAVINCI_N_AINTC_IRQ] __initdata = {
  [IRQ_DA8XX_COMMTX]             = 7,
  [IRQ_DA8XX_COMMRX]             = 7,
  [IRQ_DA8XX_NINT]               = 7,
  [IRQ_DA8XX_EVTOUT0]            = 7,
  [IRQ_DA8XX_EVTOUT1]            = 7,
  [IRQ_DA8XX_EVTOUT2]            = 7,
  [IRQ_DA8XX_EVTOUT3]            = 7,
  [IRQ_DA8XX_EVTOUT4]            = 7,
  [IRQ_DA8XX_EVTOUT5]            = 7,
  [IRQ_DA8XX_EVTOUT6]            = 7,
  [IRQ_DA8XX_EVTOUT7]            = 7,
  [IRQ_DA8XX_CCINT0]             = 7,
  [IRQ_DA8XX_CCERRINT]           = 7,
  [IRQ_DA8XX_TCERRINT0]          = 7,
  [IRQ_DA8XX_AEMIFINT]           = 7,
  [IRQ_DA8XX_I2CINT0]            = 5,
  [IRQ_DA8XX_MMCSDINT0]          = 5,
  [IRQ_DA8XX_MMCSDINT1]          = 5,
  [IRQ_DA8XX_ALLINT0]            = 5,
  [IRQ_DA8XX_RTC]                = 4,
  [IRQ_DA8XX_SPINT0]             = 5,
  [IRQ_DA8XX_TINT12_0]           = 2,
  [IRQ_DA8XX_TINT34_0]           = 5,
  [IRQ_DA8XX_TINT12_1]           = 5,
  [IRQ_DA8XX_TINT34_1]           = 5,
  [IRQ_DA8XX_UARTINT0]           = 5,
  [IRQ_DA8XX_KEYMGRINT]          = 7,
  [IRQ_DA850_MIOPU_BOOTCFG_ERR]  = 7,
  [IRQ_DA8XX_CHIPINT0]           = 7,
  [IRQ_DA8XX_CHIPINT1]           = 7,
  [IRQ_DA8XX_CHIPINT2]           = 7,
  [IRQ_DA8XX_CHIPINT3]           = 7,
  [IRQ_DA8XX_TCERRINT1]          = 7,
  [IRQ_DA8XX_C0_RX_THRESH_PULSE] = 7,
  [IRQ_DA8XX_C0_RX_PULSE]        = 7,
  [IRQ_DA8XX_C0_TX_PULSE]        = 7,
  [IRQ_DA8XX_C0_MISC_PULSE]      = 7,
  [IRQ_DA8XX_C1_RX_THRESH_PULSE] = 7,
  [IRQ_DA8XX_C1_RX_PULSE]        = 7,
  [IRQ_DA8XX_C1_TX_PULSE]        = 7,
  [IRQ_DA8XX_C1_MISC_PULSE]      = 7,
  [IRQ_DA8XX_MEMERR]             = 5,
  [IRQ_DA8XX_GPIO0]              = 6,
  [IRQ_DA8XX_GPIO1]              = 6,
  [IRQ_DA8XX_GPIO2]              = 6,
  [IRQ_DA8XX_GPIO3]              = 6,
  [IRQ_DA8XX_GPIO4]              = 6,
  [IRQ_DA8XX_GPIO5]              = 6,
  [IRQ_DA8XX_GPIO6]              = 6,
  [IRQ_DA8XX_GPIO7]              = 6,
  [IRQ_DA8XX_GPIO8]              = 6,
  [IRQ_DA8XX_I2CINT1]            = 5,
  [IRQ_DA8XX_LCDINT]             = 5,
  [IRQ_DA8XX_UARTINT1]           = 5,
  [IRQ_DA8XX_MCASPINT]           = 5,
  [IRQ_DA8XX_ALLINT1]            = 5,
  [IRQ_DA8XX_SPINT1]             = 5,
  [IRQ_DA8XX_UHPI_INT1]          = 5,
  [IRQ_DA8XX_USB_INT]            = 5,
  [IRQ_DA8XX_IRQN]               = 5,
  [IRQ_DA8XX_RWAKEUP]            = 5,
  [IRQ_DA8XX_UARTINT2]           = 5,
  [IRQ_DA8XX_DFTSSINT]           = 5,
  [IRQ_DA8XX_EHRPWM0]            = 7,
  [IRQ_DA8XX_EHRPWM0TZ]          = 7,
  [IRQ_DA8XX_EHRPWM1]            = 7,
  [IRQ_DA8XX_EHRPWM1TZ]          = 7,
  [IRQ_DA850_SATAINT]            = 5,
  [IRQ_DA850_TINT12_2]           = 5,
  [IRQ_DA8XX_ECAP0]              = 7,
  [IRQ_DA8XX_ECAP1]              = 7,
  [IRQ_DA8XX_ECAP2]              = 7,
  [IRQ_DA850_MMCSDINT0_1]        = 5,
  [IRQ_DA850_MMCSDINT1_1]        = 5,
  [IRQ_DA850_T12CMPINT0_2]       = 7,
  [IRQ_DA850_T12CMPINT1_2]       = 7,
  [IRQ_DA850_T12CMPINT2_2]       = 7,
  [IRQ_DA850_T12CMPINT3_2]       = 7,
  [IRQ_DA850_T12CMPINT4_2]       = 7,
  [IRQ_DA850_T12CMPINT5_2]       = 7,
  [IRQ_DA850_T12CMPINT6_2]       = 7,
  [IRQ_DA850_T12CMPINT7_2]       = 7,
  [IRQ_DA850_T12CMPINT0_3]       = 7,
  [IRQ_DA850_T12CMPINT1_3]       = 7,
  [IRQ_DA850_T12CMPINT2_3]       = 7,
  [IRQ_DA850_T12CMPINT3_3]       = 7,
  [IRQ_DA850_T12CMPINT4_3]       = 7,
  [IRQ_DA850_T12CMPINT5_3]       = 7,
  [IRQ_DA850_T12CMPINT6_3]       = 7,
  [IRQ_DA850_T12CMPINT7_3]       = 7,
  [IRQ_DA8XX_ARMCLKSTOPREQ]      = 7,
  [IRQ_DA850_RPIINT]             = 7,
  [IRQ_DA850_VPIFINT]            = 7,
  [IRQ_DA850_CCINT1]             = 7,
  [IRQ_DA850_CCERRINT1]          = 7,
  [IRQ_DA850_TCERRINT2]          = 7,
  [IRQ_DA850_TINT12_3]           = 5,
  [IRQ_DA850_MCBSP0RINT]         = 5,
  [IRQ_DA850_MCBSP0XINT]         = 5,
  [IRQ_DA850_MCBSP1RINT]         = 5,
  [IRQ_DA850_MCBSP1XINT]         = 5
};
#endif /* CONFIG_IPIPE */

/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
static const u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] __initdata = {
	[IRQ_VDINT0]		= 2,
	[IRQ_VDINT1]		= 6,
	[IRQ_VDINT2]		= 6,
	[IRQ_HISTINT]		= 6,
	[IRQ_H3AINT]		= 6,
	[IRQ_PRVUINT]		= 6,
	[IRQ_RSZINT]		= 6,
	[7]			= 7,
	[IRQ_VENCINT]		= 6,
	[IRQ_ASQINT]		= 6,
	[IRQ_IMXINT]		= 6,
	[IRQ_VLCDINT]		= 6,
	[IRQ_USBINT]		= 4,
	[IRQ_EMACINT]		= 4,
	[14]			= 7,
	[15]			= 7,
	[IRQ_CCINT0]		= 5,	/* dma */
	[IRQ_CCERRINT]		= 5,	/* dma */
	[IRQ_TCERRINT0]		= 5,	/* dma */
	[IRQ_TCERRINT]		= 5,	/* dma */
	[IRQ_PSCIN]		= 7,
	[21]			= 7,
	[IRQ_IDE]		= 4,
	[23]			= 7,
	[IRQ_MBXINT]		= 7,
	[IRQ_MBRINT]		= 7,
	[IRQ_MMCINT]		= 7,
	[IRQ_SDIOINT]		= 7,
	[28]			= 7,
	[IRQ_DDRINT]		= 7,
	[IRQ_AEMIFINT]		= 7,
	[IRQ_VLQINT]		= 4,
	[IRQ_TINT0_TINT12]	= 2,	/* clockevent */
	[IRQ_TINT0_TINT34]	= 2,	/* clocksource */
	[IRQ_TINT1_TINT12]	= 7,	/* DSP timer */
	[IRQ_TINT1_TINT34]	= 7,	/* system tick */
	[IRQ_PWMINT0]		= 7,
	[IRQ_PWMINT1]		= 7,
	[IRQ_PWMINT2]		= 7,
	[IRQ_I2C]		= 3,
	[IRQ_UARTINT0]		= 3,
	[IRQ_UARTINT1]		= 3,
	[IRQ_UARTINT2]		= 3,
	[IRQ_SPINT0]		= 3,
	[IRQ_SPINT1]		= 3,
	[45]			= 7,
	[IRQ_DSP2ARM0]		= 4,
	[IRQ_DSP2ARM1]		= 4,
	[IRQ_GPIO0]		= 7,
	[IRQ_GPIO1]		= 7,
	[IRQ_GPIO2]		= 7,
	[IRQ_GPIO3]		= 7,
	[IRQ_GPIO4]		= 7,
	[IRQ_GPIO5]		= 7,
	[IRQ_GPIO6]		= 7,
	[IRQ_GPIO7]		= 7,
	[IRQ_GPIOBNK0]		= 7,
	[IRQ_GPIOBNK1]		= 7,
	[IRQ_GPIOBNK2]		= 7,
	[IRQ_GPIOBNK3]		= 7,
	[IRQ_GPIOBNK4]		= 7,
	[IRQ_COMMTX]		= 7,
	[IRQ_COMMRX]		= 7,
	[IRQ_EMUINT]		= 7,
};

static const u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
	[IRQ_DM646X_VP_VERTINT0]        = 7,
	[IRQ_DM646X_VP_VERTINT1]        = 7,
	[IRQ_DM646X_VP_VERTINT2]        = 7,
	[IRQ_DM646X_VP_VERTINT3]        = 7,
	[IRQ_DM646X_VP_ERRINT]          = 7,
	[IRQ_DM646X_RESERVED_1]         = 7,
	[IRQ_DM646X_RESERVED_2]         = 7,
	[IRQ_DM646X_WDINT]              = 7,
	[IRQ_DM646X_CRGENINT0]          = 7,
	[IRQ_DM646X_CRGENINT1]          = 7,
	[IRQ_DM646X_TSIFINT0]           = 7,
	[IRQ_DM646X_TSIFINT1]           = 7,
	[IRQ_DM646X_VDCEINT]            = 7,
	[IRQ_DM646X_USBINT]             = 7,
	[IRQ_DM646X_USBDMAINT]          = 7,
	[IRQ_DM646X_PCIINT]             = 7,
	[IRQ_CCINT0]                    = 7,    /* dma */
	[IRQ_CCERRINT]                  = 7,    /* dma */
	[IRQ_TCERRINT0]                 = 7,    /* dma */
	[IRQ_TCERRINT]                  = 7,    /* dma */
	[IRQ_DM646X_TCERRINT2]          = 7,
	[IRQ_DM646X_TCERRINT3]          = 7,
	[IRQ_DM646X_IDE]                = 7,
	[IRQ_DM646X_HPIINT]             = 7,
	[IRQ_DM646X_EMACRXTHINT]        = 7,
	[IRQ_DM646X_EMACRXINT]          = 7,
	[IRQ_DM646X_EMACTXINT]          = 7,
	[IRQ_DM646X_EMACMISCINT]        = 7,
	[IRQ_DM646X_MCASP0TXINT]        = 7,
	[IRQ_DM646X_MCASP0RXINT]        = 7,
	[IRQ_AEMIFINT]                  = 7,
	[IRQ_DM646X_RESERVED_3]         = 7,
	[IRQ_DM646X_MCASP1TXINT]        = 7,    /* clockevent */
	[IRQ_TINT0_TINT34]              = 7,    /* clocksource */
	[IRQ_TINT1_TINT12]              = 7,    /* DSP timer */
	[IRQ_TINT1_TINT34]              = 7,    /* system tick */
	[IRQ_PWMINT0]                   = 7,
	[IRQ_PWMINT1]                   = 7,
	[IRQ_DM646X_VLQINT]             = 7,
	[IRQ_I2C]                       = 7,
	[IRQ_UARTINT0]                  = 7,
	[IRQ_UARTINT1]                  = 7,
	[IRQ_DM646X_UARTINT2]           = 7,
	[IRQ_DM646X_SPINT0]             = 7,
	[IRQ_DM646X_SPINT1]             = 7,
	[IRQ_DM646X_DSP2ARMINT]         = 7,
	[IRQ_DM646X_RESERVED_4]         = 7,
	[IRQ_DM646X_PSCINT]             = 7,
	[IRQ_DM646X_GPIO0]              = 7,
	[IRQ_DM646X_GPIO1]              = 7,
	[IRQ_DM646X_GPIO2]              = 7,
	[IRQ_DM646X_GPIO3]              = 7,
	[IRQ_DM646X_GPIO4]              = 7,
	[IRQ_DM646X_GPIO5]              = 7,
	[IRQ_DM646X_GPIO6]              = 7,
	[IRQ_DM646X_GPIO7]              = 7,
	[IRQ_DM646X_GPIOBNK0]           = 7,
	[IRQ_DM646X_GPIOBNK1]           = 7,
	[IRQ_DM646X_GPIOBNK2]           = 7,
	[IRQ_DM646X_DDRINT]             = 7,
	[IRQ_DM646X_AEMIFINT]           = 7,
	[IRQ_COMMTX]                    = 7,
	[IRQ_COMMRX]                    = 7,
	[IRQ_EMUINT]                    = 7,
};

static const u8 dm355_default_priorities[DAVINCI_N_AINTC_IRQ] = {
	[IRQ_DM355_CCDC_VDINT0]		= 2,
	[IRQ_DM355_CCDC_VDINT1]		= 6,
	[IRQ_DM355_CCDC_VDINT2]		= 6,
	[IRQ_DM355_IPIPE_HST]		= 6,
	[IRQ_DM355_H3AINT]		= 6,
	[IRQ_DM355_IPIPE_SDR]		= 6,
	[IRQ_DM355_IPIPEIFINT]		= 6,
	[IRQ_DM355_OSDINT]		= 7,
	[IRQ_DM355_VENCINT]		= 6,
	[IRQ_ASQINT]			= 6,
	[IRQ_IMXINT]			= 6,
	[IRQ_USBINT]			= 4,
	[IRQ_DM355_RTOINT]		= 4,
	[IRQ_DM355_UARTINT2]		= 7,
	[IRQ_DM355_TINT6]		= 7,
	[IRQ_CCINT0]			= 5,	/* dma */
	[IRQ_CCERRINT]			= 5,	/* dma */
	[IRQ_TCERRINT0]			= 5,	/* dma */
	[IRQ_TCERRINT]			= 5,	/* dma */
	[IRQ_DM355_SPINT2_1]		= 7,
	[IRQ_DM355_TINT7]		= 4,
	[IRQ_DM355_SDIOINT0]		= 7,
	[IRQ_MBXINT]			= 7,
	[IRQ_MBRINT]			= 7,
	[IRQ_MMCINT]			= 7,
	[IRQ_DM355_MMCINT1]		= 7,
	[IRQ_DM355_PWMINT3]		= 7,
	[IRQ_DDRINT]			= 7,
	[IRQ_AEMIFINT]			= 7,
	[IRQ_DM355_SDIOINT1]		= 4,
	[IRQ_TINT0_TINT12]		= 2,	/* clockevent */
	[IRQ_TINT0_TINT34]		= 2,	/* clocksource */
	[IRQ_TINT1_TINT12]		= 7,	/* DSP timer */
	[IRQ_TINT1_TINT34]		= 7,	/* system tick */
	[IRQ_PWMINT0]			= 7,
	[IRQ_PWMINT1]			= 7,
	[IRQ_PWMINT2]			= 7,
	[IRQ_I2C]			= 3,
	[IRQ_UARTINT0]			= 3,
	[IRQ_UARTINT1]			= 3,
	[IRQ_DM355_SPINT0_0]		= 3,
	[IRQ_DM355_SPINT0_1]		= 3,
	[IRQ_DM355_GPIO0]		= 3,
	[IRQ_DM355_GPIO1]		= 7,
	[IRQ_DM355_GPIO2]		= 4,
	[IRQ_DM355_GPIO3]		= 4,
	[IRQ_DM355_GPIO4]		= 7,
	[IRQ_DM355_GPIO5]		= 7,
	[IRQ_DM355_GPIO6]		= 7,
	[IRQ_DM355_GPIO7]		= 7,
	[IRQ_DM355_GPIO8]		= 7,
	[IRQ_DM355_GPIO9]		= 7,
	[IRQ_DM355_GPIOBNK0]		= 7,
	[IRQ_DM355_GPIOBNK1]		= 7,
	[IRQ_DM355_GPIOBNK2]		= 7,
	[IRQ_DM355_GPIOBNK3]		= 7,
	[IRQ_DM355_GPIOBNK4]		= 7,
	[IRQ_DM355_GPIOBNK5]		= 7,
	[IRQ_DM355_GPIOBNK6]		= 7,
	[IRQ_COMMTX]			= 7,
	[IRQ_COMMRX]			= 7,
	[IRQ_EMUINT]			= 7,
};

/* ARM Interrupt Controller Initialization */
void __init davinci_irq_init(void)
{
	unsigned i;

	if (cpu_is_davinci_dm644x())
		davinci_def_priorities = dm644x_default_priorities;
	else if (cpu_is_davinci_dm646x())
		davinci_def_priorities = dm646x_default_priorities;
	else if (cpu_is_davinci_dm355())
		davinci_def_priorities = dm355_default_priorities;
#ifdef CONFIG_IPIPE
	else if (cpu_is_da850())
	  davinci_def_priorities = da850_default_priorities;
#endif /* CONFIG_IPIPE */

	/* Clear all interrupt requests */
	davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
	davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
	davinci_irq_writel(~0x0, IRQ_REG0_OFFSET);
	davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);

	/* Disable all interrupts */
	davinci_irq_writel(0x0, IRQ_ENT_REG0_OFFSET);
	davinci_irq_writel(0x0, IRQ_ENT_REG1_OFFSET);

	/* Interrupts disabled immediately, IRQ entry reflects all */
	davinci_irq_writel(0x0, IRQ_INCTL_REG_OFFSET);

	/* we don't use the hardware vector table, just its entry addresses */
	davinci_irq_writel(0, IRQ_EABASE_REG_OFFSET);

	/* Clear all interrupt requests */
	davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
	davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
	davinci_irq_writel(~0x0, IRQ_REG0_OFFSET);
	davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);

	for (i = IRQ_INTPRI0_REG_OFFSET; i <= IRQ_INTPRI7_REG_OFFSET; i += 4) {
		unsigned	j;
		u32		pri;

		for (j = 0, pri = 0; j < 32; j += 4, davinci_def_priorities++)
			pri |= (*davinci_def_priorities & 0x07) << j;
		davinci_irq_writel(pri, i);
	}

	/* set up genirq dispatch for ARM INTC */
	for (i = 0; i < DAVINCI_N_AINTC_IRQ; i++) {
		set_irq_chip(i, &davinci_irq_chip_0);
		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
#ifndef CONFIG_IPIPE
                if (i != IRQ_TINT1_TINT34)
                        set_irq_handler(i, handle_edge_irq);
                else
#endif /* CONFIG IPIPE */
                        set_irq_handler(i, handle_level_irq);
	}
}

[-- Attachment #4: time.c --]
[-- Type: text/x-csrc, Size: 18565 bytes --]

/*
 * DaVinci timer subsystem
 *
 * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
 *
 * 2007 (c) MontaVista Software, Inc. This file is licensed under
 * the terms of the GNU General Public License version 2. This program
 * is licensed "as is" without any warranty of any kind, whether express
 * or implied.
 */
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/device.h>

#include <mach/da8xx.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/errno.h>
#include <mach/io.h>
#include <mach/cpu.h>
#include "clock.h"

#ifdef CONFIG_IPIPE
#ifdef CONFIG_NO_IDLE_HZ
#error "dynamic tick timer not yet supported with IPIPE"
#endif /* CONFIG_NO_IDLE_HZ */
#endif /* CONFIG_IPIPE */

static struct clock_event_device clockevent_davinci;
static unsigned int davinci_clock_tick_rate;

#define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400)
#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800)
#define DAVINCI_WDOG_BASE   (IO_PHYS + 0x21C00)
#define DA8XX_TIMER64P0_BASE		0x01C20000
#define DA8XX_TIMER64P1_BASE		0x01C21000

enum {
	T0_BOT = 0, T0_TOP, T1_BOT, T1_TOP, NUM_TIMERS,
};

#define IS_TIMER1(id)    (id & 0x2)
#define IS_TIMER0(id)    (!IS_TIMER1(id))
#define IS_TIMER_TOP(id) ((id & 0x1))
#define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id))

static int default_timer_irqs[NUM_TIMERS] = {
	IRQ_TINT0_TINT12,
	IRQ_TINT0_TINT34,
	IRQ_TINT1_TINT12,
	IRQ_TINT1_TINT34,
};

static int da8xx_timer_irqs[NUM_TIMERS] = {
	IRQ_DA8XX_TINT12_0,
	IRQ_DA8XX_TINT34_0,
	IRQ_DA8XX_TINT12_1,
	IRQ_DA8XX_TINT34_1
};

/* Compare registers are only available to the bottom timer 0 */
static  int da830_cmp_irqs[NUM_TIMERS] = {
	IRQ_DA830_T12CMPINT0_0,
};

static int tid_system;
static int tid_freerun;

#ifdef CONFIG_IPIPE
int          __ipipe_mach_timerint        = IRQ_DA8XX_TINT12_0;
int          __ipipe_mach_timerstolen     = 0;
unsigned int __ipipe_mach_ticks_per_jiffy = LATCH;
static int   davinci_timer_initialized;
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;
};
#endif /* CONFIG_IPIPE */

/*
 * This driver configures the 2 64-bit count-up timers as 4 independent
 * 32-bit count-up timers used as follows:
 *
 * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
 * T0_TOP: Timer 0, top   :  clocksource for generic timekeeping
 * T1_BOT: Timer 1, bottom:  (used by DSP in TI DSPLink code)
 * T1_TOP: Timer 1, top   :  <unused>
 */
#define TID_CLOCKEVENT  T0_BOT
#define TID_CLOCKSOURCE T0_TOP

/* Timer register offsets */
#define PID12                        0x0
#define TIM12                        0x10
#define TIM34                        0x14
#define PRD12                        0x18
#define PRD34                        0x1c
#define TCR                          0x20
#define TGCR                         0x24
#define WDTCR                        0x28
#define CMP12(n)		     (0x60 + ((n) << 2))
#define INTCTLSTAT                   0x44

/* Timer register bitfields */
#define TCR_ENAMODE_DISABLE          0x0
#define TCR_ENAMODE_ONESHOT          0x1
#define TCR_ENAMODE_PERIODIC         0x2
#define TCR_ENAMODE_MASK             0x3

#define TGCR_TIMMODE_SHIFT           2
#define TGCR_TIMMODE_64BIT_GP        0x0
#define TGCR_TIMMODE_32BIT_UNCHAINED 0x1
#define TGCR_TIMMODE_64BIT_WDOG      0x2
#define TGCR_TIMMODE_32BIT_CHAINED   0x3

#define TGCR_TIM12RS_SHIFT           0
#define TGCR_TIM34RS_SHIFT           1
#define TGCR_RESET                   0x0
#define TGCR_UNRESET                 0x1
#define TGCR_RESET_MASK              0x3

#define WDTCR_WDEN_SHIFT             14
#define WDTCR_WDEN_DISABLE           0x0
#define WDTCR_WDEN_ENABLE            0x1
#define WDTCR_WDKEY_SHIFT            16
#define WDTCR_WDKEY_SEQ0             0xa5c6
#define WDTCR_WDKEY_SEQ1             0xda7e

struct timer_s {
	char *name;
	unsigned int id;
	unsigned long period;
	unsigned long opts;
	void __iomem *base;
	unsigned long tim_off;
	unsigned long prd_off;
	unsigned long cmp_off;
	unsigned long enamode_shift;
	struct irqaction irqaction;
	struct irqaction cmpaction;
};

/* values for 'opts' field of struct timer_s */
#define TIMER_OPTS_DISABLED   0x00
#define TIMER_OPTS_ONESHOT    0x01
#define TIMER_OPTS_PERIODIC   0x02

/* Flags to be set when it is necessary to clear the */
/* status register for timer interrupts              */
#define TIMER12_CLEAR_PRDINT  0x02
#define TIMER12_CLEAR_EVTINT  0x04

#ifdef CONFIG_IPIPE
#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 *)(DAVINCI_TIMER0_BASE + TIM12);
	info->u.fr.mask = 0xffffffff;
	info->u.fr.tsc = &tsc->full;
}
#endif				/* !CONFIG_SMP */

void __ipipe_mach_acktimer(void)
{
  void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
  unsigned long status;

  status = __raw_readl(base + INTCTLSTAT);
  status |= (TIMER12_CLEAR_PRDINT | TIMER12_CLEAR_EVTINT);

  __raw_writel(status,base+INTCTLSTAT);
}

static void ipipe_mach_update_tsc(void)
{
  union tsc_reg *local_tsc;
  unsigned long stamp, flags;
  void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);

  local_irq_save_hw(flags);
  local_tsc = &tsc[ipipe_processor_id()];
  stamp = __raw_readl(base + TIM12);
  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(davinci_timer_initialized)) {
    union tsc_reg *local_tsc, result;
    unsigned long stamp;
    void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);

    local_tsc = &tsc[ipipe_processor_id()];

    __asm__("ldmia %1, %M0\n":
	    "=r"(result.full): "r"(local_tsc), "m"(*local_tsc));
    barrier();
    stamp = __raw_readl(base + TIM12);
    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;
  unsigned int  value;
  void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);

  if (delay > 20) {
    local_irq_save_hw(flags);
    
    value = __raw_readl(base + TIM12) + delay;
    __raw_writel(value,base + CMP12(0));
    local_irq_restore_hw(flags);
  } else {
    ipipe_trigger_irq(IRQ_DA8XX_TINT12_0);
  }
}
EXPORT_SYMBOL(__ipipe_mach_set_dec);

unsigned long __ipipe_mach_get_dec(void)
{
  unsigned long value;
  void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);

  value  = __raw_readl(base + CMP12(0));
  value -= __raw_readl(base + TIM12);

  return value;
}

int __ipipe_check_tickdev(const char *devname)
{
  return !strcmp(devname, clockevent_davinci.name);
}

#endif /* CONFIG_IPIPE */

static int timer32_config(struct timer_s *t)
{
	u32 tcr = __raw_readl(t->base + TCR);

	/* disable timer */
	tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift);
	__raw_writel(tcr, t->base + TCR);

	/* reset counter to zero, set new period */
	__raw_writel(0, t->base + t->tim_off);
	__raw_writel(t->period, t->base + t->prd_off);
	if (t->cmp_off)
		__raw_writel(t->period, t->base + t->cmp_off);

	/* Set enable mode */
	if (t->opts & TIMER_OPTS_ONESHOT) {
		tcr |= TCR_ENAMODE_ONESHOT << t->enamode_shift;
	} else if (t->opts & TIMER_OPTS_PERIODIC) {
		tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift;
	}

	__raw_writel(tcr, t->base + TCR);
	return 0;
}

static inline u32 timer32_read(struct timer_s *t)
{
	return __raw_readl(t->base + t->tim_off);
}

/* Flavio Alves: for debugging */
extern void printascii(const char *);

static irqreturn_t timer_interrupt(int irq, void *dev_id)
{
	struct clock_event_device *evt = &clockevent_davinci;

	//	printascii("entrei\n");
#ifdef CONFIG_IPIPE
	ipipe_mach_update_tsc();
#endif                          /* CONFIG_IPIPE */
	evt->event_handler(evt);
	return IRQ_HANDLED;
}

/* called when 32-bit counter wraps */
static irqreturn_t freerun_interrupt(int irq, void *dev_id)
{
	return IRQ_HANDLED;
}

static irqreturn_t cmp_interrupt(int irq, void *dev_id)
{
	struct timer_s *t = dev_id;
	struct clock_event_device *evt = &clockevent_davinci;
	/* We have to emulate the periodic mode for the clockevents layer */
	if (t->opts & TIMER_OPTS_PERIODIC) {
		unsigned long tim, cmp = __raw_readl(t->base + t->cmp_off);

		cmp += t->period;
		__raw_writel(cmp, t->base + t->cmp_off);

		/*
		 * The interrupts do happen  to be disabled by the kernel for
		 * a long periods of time, thus the timer can go far ahead of
		 * the last set compare value...
		 */
		tim = __raw_readl(t->base + t->tim_off);
		if (time_after(tim, cmp))
			__raw_writel(tim + t->period, t->base + t->cmp_off);
	}

	clockevent_davinci.event_handler(evt);
	return IRQ_HANDLED;
}

static struct timer_s davinci_system_timer = {
	.name      = "clockevent",
	.opts      = TIMER_OPTS_DISABLED,
	.irqaction = {
		.flags   = IRQF_DISABLED | IRQF_TIMER,
		.handler = timer_interrupt,
	}
};

static struct timer_s davinci_freerun_timer = {
	.name       = "free-run counter",
	.period     = ~0,
	.opts       = TIMER_OPTS_PERIODIC,
	.irqaction = {
		.flags   = IRQF_DISABLED | IRQF_TIMER,
		.handler = freerun_interrupt,
	},
	.cmpaction = {
		.name		= "timer compare reg 0",
		.flags		= IRQF_DISABLED | IRQF_TIMER,
		.handler	= cmp_interrupt,
	}
};

static struct timer_s *timers[NUM_TIMERS];

static void __init timer_init(int num_timers, u32 *phys_bases,
			      int *timer_irqs, int *cmp_irqs)
{
	int i;

	/* Global init of each 64-bit timer as a whole */
	for(i=0; i<num_timers; i++) {
		u32 tgcr;
		void __iomem *base = IO_ADDRESS(phys_bases[i]);

		/* Disabled, Internal clock source */
		__raw_writel(0, base + TCR);

		/* reset both timers, no pre-scaler for timer34 */
		tgcr = 0;
		__raw_writel(tgcr, base + TGCR);

		/* Set both timers to unchained 32-bit */
		tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT;
		__raw_writel(tgcr, base + TGCR);

		/* Unreset timers */
		tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
			(TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
		__raw_writel(tgcr, base + TGCR);

		/* Init both counters to zero */
		__raw_writel(0, base + TIM12);
		__raw_writel(0, base + TIM34);
	}

	/* Init of each timer as a 32-bit timer */
	for (i=0; i< NUM_TIMERS; i++) {
		struct timer_s *t = timers[i];
		u32 phys_base;

		if (t && t->name) {
			t->id = i;
			phys_base = phys_bases[i >> 1];
			t->base = IO_ADDRESS(phys_base);

			if (IS_TIMER_BOT(t->id)) {
				t->enamode_shift = 6;
				t->tim_off = TIM12;
				t->prd_off = PRD12;
				/* Check the compare register IRQ */
				if (t->cmpaction.handler != NULL &&
				    cmp_irqs != NULL && cmp_irqs[t->id]) {
					t->cmp_off = CMP12(0);
					t->cmpaction.dev_id = (void *)t;
					setup_irq(cmp_irqs[t->id],
						  &t->cmpaction);
				}
			} else {
				t->enamode_shift = 22;
				t->tim_off = TIM34;
				t->prd_off = PRD34;
			}

			/* Register interrupt */
			t->irqaction.name = t->name;
			t->irqaction.dev_id = (void *)t;
			if (t->irqaction.handler != NULL) {
				setup_irq(timer_irqs[t->id], &t->irqaction);
			}

			timer32_config(timers[i]);
		}
	}

#ifdef CONFIG_IPIPE
#ifndef CONFIG_SMP
	tsc = (union tsc_reg *)__ipipe_tsc_area;
	barrier();
#endif				/* CONFIG_SMP */
	davinci_timer_initialized = 1;
#endif                          /* CONFIG_IPIPE */

}

/*
 * clocksource
 */
static cycle_t read_cycles(void)
{
	struct timer_s *t;

  if (tid_freerun == -1) {
		t = timers[tid_system];
  }
  else {
		t = timers[tid_freerun];
  }
	return (cycles_t)timer32_read(t);
}

static struct clocksource clocksource_davinci = {
	.name		= "timer0_1",
	.rating		= 300,
	.read		= read_cycles,
	.mask		= CLOCKSOURCE_MASK(32),
	.shift		= 24,
	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
};

/*
 * clockevent
 */
static int davinci_set_next_event(unsigned long cycles,
				  struct clock_event_device *evt)
{
	struct timer_s *t = timers[tid_system];

	t->period = cycles;

	/*
	 * We need not (and must not) disable the timer and reprogram
	 * its mode/period when using the compare register...
	 */
	if (t->cmp_off)
		__raw_writel(__raw_readl(t->base + t->tim_off) + cycles,
			     t->base + t->cmp_off);
	else
		timer32_config(t);
	return 0;
}

static void davinci_set_mode(enum clock_event_mode mode,
			     struct clock_event_device *evt)
{
	struct timer_s *t = timers[tid_system];

	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		t->period = davinci_clock_tick_rate / (HZ);
		t->opts = TIMER_OPTS_PERIODIC;

		if (t->cmp_off)
			davinci_set_next_event(davinci_clock_tick_rate / HZ,
						evt);
		else
			timer32_config(t);
		break;
	case CLOCK_EVT_MODE_ONESHOT:
		t->opts = TIMER_OPTS_ONESHOT;
		break;
	case CLOCK_EVT_MODE_UNUSED:
	case CLOCK_EVT_MODE_SHUTDOWN:
		t->opts = TIMER_OPTS_DISABLED;
		break;
	case CLOCK_EVT_MODE_RESUME:
		break;
	}
}

static struct clock_event_device clockevent_davinci = {
	.name		= "timer0_0",
	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
	.shift		= 32,
	.set_next_event	= davinci_set_next_event,
	.set_mode	= davinci_set_mode,
};

static u32 davinci_bases[] = { DAVINCI_TIMER0_BASE, DAVINCI_TIMER1_BASE };
static u32 da8xx_bases[] = { DA8XX_TIMER64P0_BASE, DA8XX_TIMER64P1_BASE };

static void __init davinci_timer_init(void)
{
	int num_timers;
	int *timer_irqs = NULL, *cmp_irqs = NULL;
	u32 *bases;
	struct clk *timer_clk;

	static char err[] __initdata = KERN_ERR
		"%s: can't register clocksource!\n";

	timer_clk = clk_get(NULL, "timer0");
	BUG_ON(IS_ERR(timer_clk));
	clk_enable(timer_clk);

	num_timers = 2;
	bases = davinci_bases;
	timer_irqs = default_timer_irqs;
	/*
	 * DA850 does not support compare IRQs for bottom two timers.
	 * It has 4 timers, so assume using compare registers is not
	 * really a necessity.
	 */
	if (cpu_is_da830())
		cmp_irqs = da830_cmp_irqs;

	if (cpu_is_da8xx()) {
		/*
		 * Configure the 2 64-bit timer as 4 32-bit timers with
		 * following assignments.
		 *
		 * T0_BOT: Timer 0, bottom: free run counter and system clock.
		 * T0_TOP: Timer 0, top:  Reserve for DSP
		 * T1_BOT: Timer 1, watch dog timer.
		 */
		tid_system = T0_BOT;
		bases = da8xx_bases;
		timer_irqs = da8xx_timer_irqs;

		/* timer interrupt using compare reg so free-run not needed */
		if (cmp_irqs != NULL)
			tid_freerun = T0_BOT;
		else
			tid_freerun = T0_TOP;

	} else if (cpu_is_davinci_dm646x()) {
		/*
		 * Configure the 2 64-bit timer as 4 32-bit timers with
		 * following assignments.
		 *
		 * T0_BOT: Timer 0, bottom:  AV Sync
		 * T0_TOP: Timer 0, top:  free-running counter,
		 *                        used for cycle counter
		 * T1_BOT: Timer 1, bottom:  reserved for DSP
		 * T1_TOP: Timer 1, top   :  Linux system tick
		 */
		tid_system = T1_TOP;
		tid_freerun = T0_TOP;
	} else if (cpu_is_davinci_dm644x()) {
		/*
		 * Configure the 2 64-bit timer as 4 32-bit timers with
		 * following assignments.
		 *
		 * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
		 * T0_TOP: Timer 0, top   :  clocksource for generic timekeeping
		 * T1_BOT: Timer 1, bottom:  (used by DSP in TI DSPLink code)
		 * T1_TOP: Timer 1, top   :  <unused>
		 */
		tid_system = T0_BOT;
		tid_freerun = T0_TOP;
	}

	if (tid_system != -1)
		timers[tid_system] = &davinci_system_timer;

	if (tid_freerun != -1)
		timers[tid_freerun] = &davinci_freerun_timer;

	/* init timer hw */
	timer_init(num_timers, bases, timer_irqs, cmp_irqs);
	
	davinci_clock_tick_rate = clk_get_rate(timer_clk);
	clk_put(timer_clk);

	/* setup clocksource */
	clocksource_davinci.mult =
		clocksource_khz2mult(davinci_clock_tick_rate/1000,
				     clocksource_davinci.shift);
	if (clocksource_register(&clocksource_davinci))
		printk(err, clocksource_davinci.name);

	/* setup clockevent */
	clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC,
					 clockevent_davinci.shift);
	clockevent_davinci.max_delta_ns =
		clockevent_delta2ns(0xfffffffe, &clockevent_davinci);
	clockevent_davinci.min_delta_ns =
		clockevent_delta2ns(1, &clockevent_davinci);

	clockevent_davinci.cpumask = cpumask_of(0);
	clockevents_register_device(&clockevent_davinci);
}

struct sys_timer davinci_timer = {
	.init   = davinci_timer_init,
};


/* reset board using watchdog timer */
void davinci_watchdog_reset(void) {
	u32 tgcr, wdtcr;
	void __iomem *base = IO_ADDRESS(DAVINCI_WDOG_BASE);
	struct device dev;
	struct clk *wd_clk;

	dev_set_name(&dev, "watchdog");
	wd_clk = clk_get(&dev, NULL);
	if (WARN_ON(IS_ERR(wd_clk)))
		return;
	clk_enable(wd_clk);

	if (cpu_is_da8xx())
		base = IO_ADDRESS(DA8XX_TIMER64P1_BASE);

	/* disable, internal clock source */
	__raw_writel(0, base + TCR);

	/* reset timer, set mode to 64-bit watchdog, and unreset */
	tgcr = 0;
	__raw_writel(tgcr, base + TGCR);
	tgcr = TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT;
	tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
		(TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
	__raw_writel(tgcr, base + TGCR);

	/* clear counter and period regs */
	__raw_writel(0, base + TIM12);
	__raw_writel(0, base + TIM34);
	__raw_writel(0, base + PRD12);
	__raw_writel(0, base + PRD34);

	/* enable */
	wdtcr = __raw_readl(base + WDTCR);
	wdtcr |= WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT;
	__raw_writel(wdtcr, base + WDTCR);

	/* put watchdog in pre-active state */
	wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) |
		(WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
	__raw_writel(wdtcr, base + WDTCR);

	/* put watchdog in active state */
	wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) |
		(WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
	__raw_writel(wdtcr, base + WDTCR);

	/* write an invalid value to the WDKEY field to trigger
	 * a watchdog reset */
	wdtcr = 0x00004000;
	__raw_writel(wdtcr, base + WDTCR);
}

#ifdef CONFIG_IPIPE
void __ipipe_mach_release_timer(void)
{
  davinci_set_mode(clockevent_davinci.mode, &clockevent_davinci);
  if (clockevent_davinci.mode == CLOCK_EVT_MODE_ONESHOT)
    davinci_set_next_event(LATCH, &clockevent_davinci);
}
EXPORT_SYMBOL(__ipipe_mach_release_timer);
#endif /* CONFIG_IPIPE */

[-- Attachment #5: irqs.h --]
[-- Type: text/x-chdr, Size: 13101 bytes --]

/*
 * DaVinci interrupt controller definitions
 *
 *  Copyright (C) 2006 Texas Instruments.
 *
 *  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 (at your
 *  option) any later version.
 *
 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  You should have received a copy of the  GNU General Public License along
 *  with this program; if not, write  to the Free Software Foundation, Inc.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */
#ifndef __ASM_ARCH_IRQS_H
#define __ASM_ARCH_IRQS_H

/* Base address */
#define DAVINCI_ARM_INTC_BASE 0x01C48000

/* Interrupt lines */
#define IRQ_VDINT0       0
#define IRQ_VDINT1       1
#define IRQ_VDINT2       2
#define IRQ_HISTINT      3
#define IRQ_H3AINT       4
#define IRQ_PRVUINT      5
#define IRQ_RSZINT       6
#define IRQ_VFOCINT      7
#define IRQ_VENCINT      8
#define IRQ_ASQINT       9
#define IRQ_IMXINT       10
#define IRQ_VLCDINT      11
#define IRQ_USBINT       12
#define IRQ_EMACINT      13

#define IRQ_CCINT0       16
#define IRQ_CCERRINT     17
#define IRQ_TCERRINT0    18
#define IRQ_TCERRINT     19
#define IRQ_PSCIN        20

#define IRQ_IDE          22
#define IRQ_HPIINT       23
#define IRQ_MBXINT       24
#define IRQ_MBRINT       25
#define IRQ_MMCINT       26
#define IRQ_SDIOINT      27
#define IRQ_MSINT        28
#define IRQ_DDRINT       29
#define IRQ_AEMIFINT     30
#define IRQ_VLQINT       31
#define IRQ_TINT0_TINT12 32
#define IRQ_TINT0_TINT34 33
#define IRQ_TINT1_TINT12 34
#define IRQ_TINT1_TINT34 35
#define IRQ_PWMINT0      36
#define IRQ_PWMINT1      37
#define IRQ_PWMINT2      38
#define IRQ_I2C          39
#define IRQ_UARTINT0     40
#define IRQ_UARTINT1     41
#define IRQ_UARTINT2     42
#define IRQ_SPINT0       43
#define IRQ_SPINT1       44

#define IRQ_DSP2ARM0     46
#define IRQ_DSP2ARM1     47
#define IRQ_GPIO0        48
#define IRQ_GPIO1        49
#define IRQ_GPIO2        50
#define IRQ_GPIO3        51
#define IRQ_GPIO4        52
#define IRQ_GPIO5        53
#define IRQ_GPIO6        54
#define IRQ_GPIO7        55
#define IRQ_GPIOBNK0     56
#define IRQ_GPIOBNK1     57
#define IRQ_GPIOBNK2     58
#define IRQ_GPIOBNK3     59
#define IRQ_GPIOBNK4     60
#define IRQ_COMMTX       61
#define IRQ_COMMRX       62
#define IRQ_EMUINT       63

/* da850 currently has the most irqs (101) */
#define DAVINCI_N_AINTC_IRQ	101
/* da850 currently has the most gpio pins (144) */
#define DAVINCI_N_GPIO		144

#define NR_IRQS			(DAVINCI_N_AINTC_IRQ + DAVINCI_N_GPIO)

#define ARCH_TIMER_IRQ IRQ_TINT1_TINT34

/* DaVinci DM6467-specific Interrupts */
#define IRQ_DM646X_VP_VERTINT0  0
#define IRQ_DM646X_VP_VERTINT1  1
#define IRQ_DM646X_VP_VERTINT2  2
#define IRQ_DM646X_VP_VERTINT3  3
#define IRQ_DM646X_VP_ERRINT    4
#define IRQ_DM646X_RESERVED_1   5
#define IRQ_DM646X_RESERVED_2   6
#define IRQ_DM646X_WDINT        7
#define IRQ_DM646X_CRGENINT0    8
#define IRQ_DM646X_CRGENINT1    9
#define IRQ_DM646X_TSIFINT0     10
#define IRQ_DM646X_TSIFINT1     11
#define IRQ_DM646X_VDCEINT      12
#define IRQ_DM646X_USBINT       13
#define IRQ_DM646X_USBDMAINT    14
#define IRQ_DM646X_PCIINT       15
#define IRQ_DM646X_TCERRINT2    20
#define IRQ_DM646X_TCERRINT3    21
#define IRQ_DM646X_IDE          22
#define IRQ_DM646X_HPIINT       23
#define IRQ_DM646X_EMACRXTHINT  24
#define IRQ_DM646X_EMACRXINT    25
#define IRQ_DM646X_EMACTXINT    26
#define IRQ_DM646X_EMACMISCINT  27
#define IRQ_DM646X_MCASP0TXINT  28
#define IRQ_DM646X_MCASP0RXINT  29
#define IRQ_DM646X_RESERVED_3   31
#define IRQ_DM646X_MCASP1TXINT  32
#define IRQ_DM646X_VLQINT       38
#define IRQ_DM646X_UARTINT2     42
#define IRQ_DM646X_SPINT0       43
#define IRQ_DM646X_SPINT1       44
#define IRQ_DM646X_DSP2ARMINT   45
#define IRQ_DM646X_RESERVED_4   46
#define IRQ_DM646X_PSCINT       47
#define IRQ_DM646X_GPIO0        48
#define IRQ_DM646X_GPIO1        49
#define IRQ_DM646X_GPIO2        50
#define IRQ_DM646X_GPIO3        51
#define IRQ_DM646X_GPIO4        52
#define IRQ_DM646X_GPIO5        53
#define IRQ_DM646X_GPIO6        54
#define IRQ_DM646X_GPIO7        55
#define IRQ_DM646X_GPIOBNK0     56
#define IRQ_DM646X_GPIOBNK1     57
#define IRQ_DM646X_GPIOBNK2     58
#define IRQ_DM646X_DDRINT       59
#define IRQ_DM646X_AEMIFINT     60

/* DaVinci DM355-specific Interrupts */
#define IRQ_DM355_CCDC_VDINT0	0
#define IRQ_DM355_CCDC_VDINT1	1
#define IRQ_DM355_CCDC_VDINT2	2
#define IRQ_DM355_IPIPE_HST	3
#define IRQ_DM355_H3AINT	4
#define IRQ_DM355_IPIPE_SDR	5
#define IRQ_DM355_IPIPEIFINT	6
#define IRQ_DM355_OSDINT	7
#define IRQ_DM355_VENCINT	8
#define IRQ_DM355_IMCOPINT	11
#define IRQ_DM355_RTOINT	13
#define IRQ_DM355_TINT4		13
#define IRQ_DM355_TINT2_TINT12	13
#define IRQ_DM355_UARTINT2	14
#define IRQ_DM355_TINT5		14
#define IRQ_DM355_TINT2_TINT34	14
#define IRQ_DM355_TINT6		15
#define IRQ_DM355_TINT3_TINT12	15
#define IRQ_DM355_SPINT1_0	17
#define IRQ_DM355_SPINT1_1	18
#define IRQ_DM355_SPINT2_0	19
#define IRQ_DM355_SPINT2_1	21
#define IRQ_DM355_TINT7		22
#define IRQ_DM355_TINT3_TINT34	22
#define IRQ_DM355_SDIOINT0	23
#define IRQ_DM355_MMCINT0	26
#define IRQ_DM355_MSINT		26
#define IRQ_DM355_MMCINT1	27
#define IRQ_DM355_PWMINT3	28
#define IRQ_DM355_SDIOINT1	31
#define IRQ_DM355_SPINT0_0	42
#define IRQ_DM355_SPINT0_1	43
#define IRQ_DM355_GPIO0		44
#define IRQ_DM355_GPIO1		45
#define IRQ_DM355_GPIO2		46
#define IRQ_DM355_GPIO3		47
#define IRQ_DM355_GPIO4		48
#define IRQ_DM355_GPIO5		49
#define IRQ_DM355_GPIO6		50
#define IRQ_DM355_GPIO7		51
#define IRQ_DM355_GPIO8		52
#define IRQ_DM355_GPIO9		53
#define IRQ_DM355_GPIOBNK0	54
#define IRQ_DM355_GPIOBNK1	55
#define IRQ_DM355_GPIOBNK2	56
#define IRQ_DM355_GPIOBNK3	57
#define IRQ_DM355_GPIOBNK4	58
#define IRQ_DM355_GPIOBNK5	59
#define IRQ_DM355_GPIOBNK6	60

/* Interrupts common to DA830 and DA850*/
#define IRQ_DA8XX_COMMTX                0
#define IRQ_DA8XX_COMMRX                1
#define IRQ_DA8XX_NINT                  2
#define IRQ_DA8XX_EVTOUT0               3
#define IRQ_DA8XX_EVTOUT1               4
#define IRQ_DA8XX_EVTOUT2               5
#define IRQ_DA8XX_EVTOUT3               6
#define IRQ_DA8XX_EVTOUT4               7
#define IRQ_DA8XX_EVTOUT5               8
#define IRQ_DA8XX_EVTOUT6               9
#define IRQ_DA8XX_EVTOUT7               10
#define IRQ_DA8XX_CCINT0                11
#define IRQ_DA8XX_CCERRINT              12
#define IRQ_DA8XX_TCERRINT0             13
#define IRQ_DA8XX_AEMIFINT              14
#define IRQ_DA8XX_I2CINT0               15
#define IRQ_DA8XX_MMCSDINT0             16
#define IRQ_DA8XX_MMCSDINT1             17
#define IRQ_DA8XX_ALLINT0               18
#define IRQ_DA8XX_RTC                   19
#define IRQ_DA8XX_SPINT0                20
#define IRQ_DA8XX_TINT12_0              21
#define IRQ_DA8XX_TINT34_0              22
#define IRQ_DA8XX_TINT12_1              23
#define IRQ_DA8XX_TINT34_1              24
#define IRQ_DA8XX_UARTINT0              25
#define IRQ_DA8XX_KEYMGRINT             26
#define IRQ_DA8XX_SECINT                26
#define IRQ_DA8XX_SECKEYERR             26
#define IRQ_DA8XX_CHIPINT0              28
#define IRQ_DA8XX_CHIPINT1              29
#define IRQ_DA8XX_CHIPINT2              30
#define IRQ_DA8XX_CHIPINT3              31
#define IRQ_DA8XX_TCERRINT1             32
#define IRQ_DA8XX_C0_RX_THRESH_PULSE    33
#define IRQ_DA8XX_C0_RX_PULSE           34
#define IRQ_DA8XX_C0_TX_PULSE           35
#define IRQ_DA8XX_C0_MISC_PULSE         36
#define IRQ_DA8XX_C1_RX_THRESH_PULSE    37
#define IRQ_DA8XX_C1_RX_PULSE           38
#define IRQ_DA8XX_C1_TX_PULSE           39
#define IRQ_DA8XX_C1_MISC_PULSE         40
#define IRQ_DA8XX_MEMERR                41
#define IRQ_DA8XX_GPIO0                 42
#define IRQ_DA8XX_GPIO1                 43
#define IRQ_DA8XX_GPIO2                 44
#define IRQ_DA8XX_GPIO3                 45
#define IRQ_DA8XX_GPIO4                 46
#define IRQ_DA8XX_GPIO5                 47
#define IRQ_DA8XX_GPIO6                 48
#define IRQ_DA8XX_GPIO7                 49
#define IRQ_DA8XX_GPIO8                 50
#define IRQ_DA8XX_I2CINT1               51
#define IRQ_DA8XX_LCDINT                52
#define IRQ_DA8XX_UARTINT1              53
#define IRQ_DA8XX_MCASPINT              54
#define IRQ_DA8XX_ALLINT1               55
#define IRQ_DA8XX_SPINT1                56
#define IRQ_DA8XX_UHPI_INT1             57
#define IRQ_DA8XX_USB_INT               58
#define IRQ_DA8XX_IRQN                  59
#define IRQ_DA8XX_RWAKEUP               60
#define IRQ_DA8XX_UARTINT2              61
#define IRQ_DA8XX_DFTSSINT              62
#define IRQ_DA8XX_EHRPWM0               63
#define IRQ_DA8XX_EHRPWM0TZ             64
#define IRQ_DA8XX_EHRPWM1               65
#define IRQ_DA8XX_EHRPWM1TZ             66
#define IRQ_DA8XX_ECAP0                 69
#define IRQ_DA8XX_ECAP1                 70
#define IRQ_DA8XX_ECAP2                 71
#define IRQ_DA8XX_ARMCLKSTOPREQ         90

/* DA830 specific interrupts */
#define IRQ_DA830_MPUERR                27
#define IRQ_DA830_IOPUERR               27
#define IRQ_DA830_BOOTCFGERR            27
#define IRQ_DA830_EHRPWM2               67
#define IRQ_DA830_EHRPWM2TZ             68
#define IRQ_DA830_EQEP0                 72
#define IRQ_DA830_EQEP1                 73
#define IRQ_DA830_T12CMPINT0_0          74
#define IRQ_DA830_T12CMPINT1_0          75
#define IRQ_DA830_T12CMPINT2_0          76
#define IRQ_DA830_T12CMPINT3_0          77
#define IRQ_DA830_T12CMPINT4_0          78
#define IRQ_DA830_T12CMPINT5_0          79
#define IRQ_DA830_T12CMPINT6_0          80
#define IRQ_DA830_T12CMPINT7_0          81
#define IRQ_DA830_T12CMPINT0_1          82
#define IRQ_DA830_T12CMPINT1_1          83
#define IRQ_DA830_T12CMPINT2_1          84
#define IRQ_DA830_T12CMPINT3_1          85
#define IRQ_DA830_T12CMPINT4_1          86
#define IRQ_DA830_T12CMPINT5_1          87
#define IRQ_DA830_T12CMPINT6_1          88
#define IRQ_DA830_T12CMPINT7_1          89

/* DA850 speicific interrupts */
#define IRQ_DA850_MPUADDRERR0		27
#define IRQ_DA850_MPUPROTERR0		27
#define IRQ_DA850_IOPUADDRERR0		27
#define IRQ_DA850_IOPUPROTERR0		27
#define IRQ_DA850_IOPUADDRERR1		27
#define IRQ_DA850_IOPUPROTERR1		27
#define IRQ_DA850_IOPUADDRERR2		27
#define IRQ_DA850_IOPUPROTERR2		27
#define IRQ_DA850_BOOTCFG_ADDR_ERR	27
#define IRQ_DA850_BOOTCFG_PROT_ERR	27
#define IRQ_DA850_MPUADDRERR1		27
#define IRQ_DA850_MPUPROTERR1		27
#define IRQ_DA850_IOPUADDRERR3		27
#define IRQ_DA850_IOPUPROTERR3		27
#define IRQ_DA850_IOPUADDRERR4		27
#define IRQ_DA850_IOPUPROTERR4		27
#define IRQ_DA850_IOPUADDRERR5		27
#define IRQ_DA850_IOPUPROTERR5		27
#define IRQ_DA850_MIOPU_BOOTCFG_ERR	27
#define IRQ_DA850_SATAINT		67
#define IRQ_DA850_TINT12_2		68
#define IRQ_DA850_TINT34_2		68
#define IRQ_DA850_TINTALL_2		68
#define IRQ_DA850_MMCSDINT0_1		72
#define IRQ_DA850_MMCSDINT1_1		73
#define IRQ_DA850_T12CMPINT0_2		74
#define IRQ_DA850_T12CMPINT1_2		75
#define IRQ_DA850_T12CMPINT2_2		76
#define IRQ_DA850_T12CMPINT3_2		77
#define IRQ_DA850_T12CMPINT4_2		78
#define IRQ_DA850_T12CMPINT5_2		79
#define IRQ_DA850_T12CMPINT6_2		80
#define IRQ_DA850_T12CMPINT7_2		81
#define IRQ_DA850_T12CMPINT0_3		82
#define IRQ_DA850_T12CMPINT1_3		83
#define IRQ_DA850_T12CMPINT2_3		84
#define IRQ_DA850_T12CMPINT3_3		85
#define IRQ_DA850_T12CMPINT4_3		86
#define IRQ_DA850_T12CMPINT5_3		87
#define IRQ_DA850_T12CMPINT6_3		88
#define IRQ_DA850_T12CMPINT7_3		89
#define IRQ_DA850_RPIINT		91
#define IRQ_DA850_VPIFINT		92
#define IRQ_DA850_CCINT1		93
#define IRQ_DA850_CCERRINT1		94
#define IRQ_DA850_TCERRINT2		95
#define IRQ_DA850_TINT12_3		96
#define IRQ_DA850_TINT34_3		96
#define IRQ_DA850_TINTALL_3		96
#define IRQ_DA850_MCBSP0RINT		97
#define IRQ_DA850_MCBSP0XINT		98
#define IRQ_DA850_MCBSP1RINT		99
#define IRQ_DA850_MCBSP1XINT		100

#ifdef CONFIG_IPIPE
#if 0
#define __ipipe_mach_irq_mux_p(irq) \
        ((unsigned) (irq - IRQ_DA8XX_GPIO0) \
         <= (IRQ_DA8XX_GPIO7 - IRQ_DA8XX_GPIO0))
#endif
#define __ipipe_mach_irq_mux_p(irq) \
	((irq) == IRQ_DA8XX_GPIO0 \
	 || (irq) == IRQ_DA8XX_GPIO1 \
	 || (irq) == IRQ_DA8XX_GPIO2 \
	 || (irq) == IRQ_DA8XX_GPIO3 \
	 || (irq) == IRQ_DA8XX_GPIO4 \
	 || (irq) == IRQ_DA8XX_GPIO5 \
	 || (irq) == IRQ_DA8XX_GPIO6 \
	 || (irq) == IRQ_DA8XX_GPIO7)


#endif /* CONFIG_IPIPE */

#endif /* __ASM_ARCH_IRQS_H */

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 19:42                                                     ` Flavio de Castro Alves Filho
@ 2010-01-08 19:45                                                       ` Gilles Chanteperdrix
  2010-01-08 21:54                                                         ` Flavio de Castro Alves Filho
  0 siblings, 1 reply; 38+ messages in thread
From: Gilles Chanteperdrix @ 2010-01-08 19:45 UTC (permalink / raw)
  To: Flavio de Castro Alves Filho; +Cc: xenomai

Flavio de Castro Alves Filho wrote:
> Of course :-)
> 
> As I don't know the best way to send it, I attached the files.
> 
> I hope everything is in there. I'm sorry if you find some ugly commented
> debug code.

Please send a diff.

-- 
					    Gilles.


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 19:45                                                       ` Gilles Chanteperdrix
@ 2010-01-08 21:54                                                         ` Flavio de Castro Alves Filho
  2010-01-08 22:26                                                           ` Gilles Chanteperdrix
  0 siblings, 1 reply; 38+ messages in thread
From: Flavio de Castro Alves Filho @ 2010-01-08 21:54 UTC (permalink / raw)
  To: xenomai

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

In fact,

Much easier.

*** linux-03.20.00.05/arch/arm/mach-davinci/gpio.c    2009-07-29
02:53:15.000000000 -0300
--- linux-03.20.00.05_xenomai/arch/arm/mach-davinci/gpio.c    2010-01-08
16:08:35.000000000 -0200
***************
*** 27,32 ****
--- 27,33 ----

  #include <asm/mach/irq.h>

+ #include <asm/ipipe.h>

  static DEFINE_SPINLOCK(gpio_lock);

***************
*** 261,266 ****
--- 262,315 ----
      /* now it may re-trigger */
  }

+ #ifdef CONFIG_IPIPE
+
+ /* Flavio Alves: for debugging */
+ extern void printascii(const char *);
+
+ void __ipipe_mach_demux_irq(unsigned irq, struct pt_regs *regs)
+ {
+     struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+     struct irq_desc *desc;
+     u32 mask = 0xffff;
+
+     //printascii("1__ipipe_mach_demux_irq\n");
+
+     /* we only care about one bank */
+     if (irq & 1)
+         mask <<= 16;
+
+     desc = &irq_desc[irq];
+
+     /* temporarily mask (level sensitive) parent IRQ */
+     desc->chip->ack(irq);
+     while (1) {
+         u32        status;
+         int        n;
+         int        res;
+
+         /* ack any irqs */
+         status = __raw_readl(&g->intstat) & mask;
+         if (!status)
+             break;
+         __raw_writel(status, &g->intstat);
+         if (irq & 1)
+             status >>= 16;
+
+         /* now demux them to the right lowlevel handler */
+         n = (int)get_irq_data(irq);
+         while (status) {
+             res = ffs(status);
+             n += res;
+             __ipipe_handle_irq((n-1),regs);
+             status >>= res;
+         }
+     }
+     desc->chip->unmask(irq);
+     /* now it may re-trigger */
+ }
+ #endif /* CONFIG_IPIPE */
+
  /*
   * NOTE:  for suspend/resume, probably best to make a platform_device with
   * suspend_late/resume_resume calls hooking into results of the set_wake()
diff -crB linux-03.20.00.05/arch/arm/mach-davinci/include/mach/irqs.h
linux-03.20.00.05_xenomai/arch/arm/mach-davinci/include/mach/irqs.h
*** linux-03.20.00.05/arch/arm/mach-davinci/include/mach/irqs.h
2009-07-29 02:53:15.000000000 -0300
--- linux-03.20.00.05_xenomai/arch/arm/mach-davinci/include/mach/irqs.h
2010-01-06 16:45:56.000000000 -0200
***************
*** 359,362 ****
--- 359,381 ----
  #define IRQ_DA850_MCBSP1RINT        99
  #define IRQ_DA850_MCBSP1XINT        100

+ #ifdef CONFIG_IPIPE
+ #if 0
+ #define __ipipe_mach_irq_mux_p(irq) \
+         ((unsigned) (irq - IRQ_DA8XX_GPIO0) \
+          <= (IRQ_DA8XX_GPIO7 - IRQ_DA8XX_GPIO0))
+ #endif
+ #define __ipipe_mach_irq_mux_p(irq) \
+     ((irq) == IRQ_DA8XX_GPIO0 \
+      || (irq) == IRQ_DA8XX_GPIO1 \
+      || (irq) == IRQ_DA8XX_GPIO2 \
+      || (irq) == IRQ_DA8XX_GPIO3 \
+      || (irq) == IRQ_DA8XX_GPIO4 \
+      || (irq) == IRQ_DA8XX_GPIO5 \
+      || (irq) == IRQ_DA8XX_GPIO6 \
+      || (irq) == IRQ_DA8XX_GPIO7)
+
+
+ #endif /* CONFIG_IPIPE */
+
  #endif /* __ASM_ARCH_IRQS_H */
diff -crB linux-03.20.00.05/arch/arm/mach-davinci/irq.c
linux-03.20.00.05_xenomai/arch/arm/mach-davinci/irq.c
*** linux-03.20.00.05/arch/arm/mach-davinci/irq.c    2009-07-29
02:53:15.000000000 -0300
--- linux-03.20.00.05_xenomai/arch/arm/mach-davinci/irq.c    2010-01-08
15:22:13.000000000 -0200
***************
*** 111,119 ****
--- 111,228 ----
      .name    = "AINTC",
      .ack    = davinci_ack_irq,
      .mask    = davinci_mask_irq,
+ #ifdef CONFIG_IPIPE
+     .mask_ack = davinci_mask_irq,
+ #endif /* CONFIG_IPIPE */
      .unmask = davinci_unmask_irq,
  };

+ #ifdef CONFIG_IPIPE
+ static const u8 da850_default_priorities[DAVINCI_N_AINTC_IRQ] __initdata =
{
+   [IRQ_DA8XX_COMMTX]             = 7,
+   [IRQ_DA8XX_COMMRX]             = 7,
+   [IRQ_DA8XX_NINT]               = 7,
+   [IRQ_DA8XX_EVTOUT0]            = 7,
+   [IRQ_DA8XX_EVTOUT1]            = 7,
+   [IRQ_DA8XX_EVTOUT2]            = 7,
+   [IRQ_DA8XX_EVTOUT3]            = 7,
+   [IRQ_DA8XX_EVTOUT4]            = 7,
+   [IRQ_DA8XX_EVTOUT5]            = 7,
+   [IRQ_DA8XX_EVTOUT6]            = 7,
+   [IRQ_DA8XX_EVTOUT7]            = 7,
+   [IRQ_DA8XX_CCINT0]             = 7,
+   [IRQ_DA8XX_CCERRINT]           = 7,
+   [IRQ_DA8XX_TCERRINT0]          = 7,
+   [IRQ_DA8XX_AEMIFINT]           = 7,
+   [IRQ_DA8XX_I2CINT0]            = 5,
+   [IRQ_DA8XX_MMCSDINT0]          = 5,
+   [IRQ_DA8XX_MMCSDINT1]          = 5,
+   [IRQ_DA8XX_ALLINT0]            = 5,
+   [IRQ_DA8XX_RTC]                = 4,
+   [IRQ_DA8XX_SPINT0]             = 5,
+   [IRQ_DA8XX_TINT12_0]           = 2,
+   [IRQ_DA8XX_TINT34_0]           = 5,
+   [IRQ_DA8XX_TINT12_1]           = 5,
+   [IRQ_DA8XX_TINT34_1]           = 5,
+   [IRQ_DA8XX_UARTINT0]           = 5,
+   [IRQ_DA8XX_KEYMGRINT]          = 7,
+   [IRQ_DA850_MIOPU_BOOTCFG_ERR]  = 7,
+   [IRQ_DA8XX_CHIPINT0]           = 7,
+   [IRQ_DA8XX_CHIPINT1]           = 7,
+   [IRQ_DA8XX_CHIPINT2]           = 7,
+   [IRQ_DA8XX_CHIPINT3]           = 7,
+   [IRQ_DA8XX_TCERRINT1]          = 7,
+   [IRQ_DA8XX_C0_RX_THRESH_PULSE] = 7,
+   [IRQ_DA8XX_C0_RX_PULSE]        = 7,
+   [IRQ_DA8XX_C0_TX_PULSE]        = 7,
+   [IRQ_DA8XX_C0_MISC_PULSE]      = 7,
+   [IRQ_DA8XX_C1_RX_THRESH_PULSE] = 7,
+   [IRQ_DA8XX_C1_RX_PULSE]        = 7,
+   [IRQ_DA8XX_C1_TX_PULSE]        = 7,
+   [IRQ_DA8XX_C1_MISC_PULSE]      = 7,
+   [IRQ_DA8XX_MEMERR]             = 5,
+   [IRQ_DA8XX_GPIO0]              = 6,
+   [IRQ_DA8XX_GPIO1]              = 6,
+   [IRQ_DA8XX_GPIO2]              = 6,
+   [IRQ_DA8XX_GPIO3]              = 6,
+   [IRQ_DA8XX_GPIO4]              = 6,
+   [IRQ_DA8XX_GPIO5]              = 6,
+   [IRQ_DA8XX_GPIO6]              = 6,
+   [IRQ_DA8XX_GPIO7]              = 6,
+   [IRQ_DA8XX_GPIO8]              = 6,
+   [IRQ_DA8XX_I2CINT1]            = 5,
+   [IRQ_DA8XX_LCDINT]             = 5,
+   [IRQ_DA8XX_UARTINT1]           = 5,
+   [IRQ_DA8XX_MCASPINT]           = 5,
+   [IRQ_DA8XX_ALLINT1]            = 5,
+   [IRQ_DA8XX_SPINT1]             = 5,
+   [IRQ_DA8XX_UHPI_INT1]          = 5,
+   [IRQ_DA8XX_USB_INT]            = 5,
+   [IRQ_DA8XX_IRQN]               = 5,
+   [IRQ_DA8XX_RWAKEUP]            = 5,
+   [IRQ_DA8XX_UARTINT2]           = 5,
+   [IRQ_DA8XX_DFTSSINT]           = 5,
+   [IRQ_DA8XX_EHRPWM0]            = 7,
+   [IRQ_DA8XX_EHRPWM0TZ]          = 7,
+   [IRQ_DA8XX_EHRPWM1]            = 7,
+   [IRQ_DA8XX_EHRPWM1TZ]          = 7,
+   [IRQ_DA850_SATAINT]            = 5,
+   [IRQ_DA850_TINT12_2]           = 5,
+   [IRQ_DA8XX_ECAP0]              = 7,
+   [IRQ_DA8XX_ECAP1]              = 7,
+   [IRQ_DA8XX_ECAP2]              = 7,
+   [IRQ_DA850_MMCSDINT0_1]        = 5,
+   [IRQ_DA850_MMCSDINT1_1]        = 5,
+   [IRQ_DA850_T12CMPINT0_2]       = 7,
+   [IRQ_DA850_T12CMPINT1_2]       = 7,
+   [IRQ_DA850_T12CMPINT2_2]       = 7,
+   [IRQ_DA850_T12CMPINT3_2]       = 7,
+   [IRQ_DA850_T12CMPINT4_2]       = 7,
+   [IRQ_DA850_T12CMPINT5_2]       = 7,
+   [IRQ_DA850_T12CMPINT6_2]       = 7,
+   [IRQ_DA850_T12CMPINT7_2]       = 7,
+   [IRQ_DA850_T12CMPINT0_3]       = 7,
+   [IRQ_DA850_T12CMPINT1_3]       = 7,
+   [IRQ_DA850_T12CMPINT2_3]       = 7,
+   [IRQ_DA850_T12CMPINT3_3]       = 7,
+   [IRQ_DA850_T12CMPINT4_3]       = 7,
+   [IRQ_DA850_T12CMPINT5_3]       = 7,
+   [IRQ_DA850_T12CMPINT6_3]       = 7,
+   [IRQ_DA850_T12CMPINT7_3]       = 7,
+   [IRQ_DA8XX_ARMCLKSTOPREQ]      = 7,
+   [IRQ_DA850_RPIINT]             = 7,
+   [IRQ_DA850_VPIFINT]            = 7,
+   [IRQ_DA850_CCINT1]             = 7,
+   [IRQ_DA850_CCERRINT1]          = 7,
+   [IRQ_DA850_TCERRINT2]          = 7,
+   [IRQ_DA850_TINT12_3]           = 5,
+   [IRQ_DA850_MCBSP0RINT]         = 5,
+   [IRQ_DA850_MCBSP0XINT]         = 5,
+   [IRQ_DA850_MCBSP1RINT]         = 5,
+   [IRQ_DA850_MCBSP1XINT]         = 5
+ };
+ #endif /* CONFIG_IPIPE */
+
  /* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
  static const u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] __initdata
= {
      [IRQ_VDINT0]        = 2,
***************
*** 325,330 ****
--- 434,443 ----
          davinci_def_priorities = dm646x_default_priorities;
      else if (cpu_is_davinci_dm355())
          davinci_def_priorities = dm355_default_priorities;
+ #ifdef CONFIG_IPIPE
+     else if (cpu_is_da850())
+       davinci_def_priorities = da850_default_priorities;
+ #endif /* CONFIG_IPIPE */

      /* Clear all interrupt requests */
      davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
***************
*** 361,369 ****
--- 474,484 ----
      for (i = 0; i < DAVINCI_N_AINTC_IRQ; i++) {
          set_irq_chip(i, &davinci_irq_chip_0);
          set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ #ifndef CONFIG_IPIPE
                  if (i != IRQ_TINT1_TINT34)
                          set_irq_handler(i, handle_edge_irq);
                  else
+ #endif /* CONFIG IPIPE */
                          set_irq_handler(i, handle_level_irq);
      }
  }
diff -crB linux-03.20.00.05/arch/arm/mach-davinci/time.c
linux-03.20.00.05_xenomai/arch/arm/mach-davinci/time.c
*** linux-03.20.00.05/arch/arm/mach-davinci/time.c    2009-07-29
02:53:15.000000000 -0300
--- linux-03.20.00.05_xenomai/arch/arm/mach-davinci/time.c    2010-01-08
17:07:36.000000000 -0200
***************
*** 30,35 ****
--- 30,41 ----
  #include <mach/cpu.h>
  #include "clock.h"

+ #ifdef CONFIG_IPIPE
+ #ifdef CONFIG_NO_IDLE_HZ
+ #error "dynamic tick timer not yet supported with IPIPE"
+ #endif /* CONFIG_NO_IDLE_HZ */
+ #endif /* CONFIG_IPIPE */
+
  static struct clock_event_device clockevent_davinci;
  static unsigned int davinci_clock_tick_rate;

***************
*** 70,75 ****
--- 76,102 ----
  static int tid_system;
  static int tid_freerun;

+ #ifdef CONFIG_IPIPE
+ int          __ipipe_mach_timerint        = IRQ_DA8XX_TINT12_0;
+ int          __ipipe_mach_timerstolen     = 0;
+ unsigned int __ipipe_mach_ticks_per_jiffy = LATCH;
+ static int   davinci_timer_initialized;
+ 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;
+ };
+ #endif /* CONFIG_IPIPE */
+
  /*
   * This driver configures the 2 64-bit count-up timers as 4 independent
   * 32-bit count-up timers used as follows:
***************
*** 92,97 ****
--- 119,125 ----
  #define TGCR                         0x24
  #define WDTCR                        0x28
  #define CMP12(n)             (0x60 + ((n) << 2))
+ #define INTCTLSTAT                   0x44

  /* Timer register bitfields */
  #define TCR_ENAMODE_DISABLE          0x0
***************
*** 137,142 ****
--- 165,283 ----
  #define TIMER_OPTS_ONESHOT    0x01
  #define TIMER_OPTS_PERIODIC   0x02

+ /* Flags to be set when it is necessary to clear the */
+ /* status register for timer interrupts              */
+ #define TIMER12_CLEAR_PRDINT  0x02
+ #define TIMER12_CLEAR_EVTINT  0x04
+
+ #ifdef CONFIG_IPIPE
+ #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 *)(DAVINCI_TIMER0_BASE + TIM12);
+     info->u.fr.mask = 0xffffffff;
+     info->u.fr.tsc = &tsc->full;
+ }
+ #endif                /* !CONFIG_SMP */
+
+ void __ipipe_mach_acktimer(void)
+ {
+   void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
+   unsigned long status;
+
+   status = __raw_readl(base + INTCTLSTAT);
+   status |= (TIMER12_CLEAR_PRDINT | TIMER12_CLEAR_EVTINT);
+
+   __raw_writel(status,base+INTCTLSTAT);
+ }
+
+ static void ipipe_mach_update_tsc(void)
+ {
+   union tsc_reg *local_tsc;
+   unsigned long stamp, flags;
+   void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
+
+   local_irq_save_hw(flags);
+   local_tsc = &tsc[ipipe_processor_id()];
+   stamp = __raw_readl(base + TIM12);
+   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(davinci_timer_initialized)) {
+     union tsc_reg *local_tsc, result;
+     unsigned long stamp;
+     void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
+
+     local_tsc = &tsc[ipipe_processor_id()];
+
+     __asm__("ldmia %1, %M0\n":
+         "=r"(result.full): "r"(local_tsc), "m"(*local_tsc));
+     barrier();
+     stamp = __raw_readl(base + TIM12);
+     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;
+   unsigned int  value;
+   void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
+
+   if (delay > 20) {
+     local_irq_save_hw(flags);
+
+     value = __raw_readl(base + TIM12) + delay;
+     __raw_writel(value,base + CMP12(0));
+     local_irq_restore_hw(flags);
+   } else {
+     ipipe_trigger_irq(IRQ_DA8XX_TINT12_0);
+   }
+ }
+ EXPORT_SYMBOL(__ipipe_mach_set_dec);
+
+ unsigned long __ipipe_mach_get_dec(void)
+ {
+   unsigned long value;
+   void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
+
+   value  = __raw_readl(base + CMP12(0));
+   value -= __raw_readl(base + TIM12);
+
+   return value;
+ }
+
+ int __ipipe_check_tickdev(const char *devname)
+ {
+   return !strcmp(devname, clockevent_davinci.name);
+ }
+
+ #endif /* CONFIG_IPIPE */
+
  static int timer32_config(struct timer_s *t)
  {
      u32 tcr = __raw_readl(t->base + TCR);
***************
*** 167,176 ****
--- 308,324 ----
      return __raw_readl(t->base + t->tim_off);
  }

+ /* Flavio Alves: for debugging */
+ extern void printascii(const char *);
+
  static irqreturn_t timer_interrupt(int irq, void *dev_id)
  {
      struct clock_event_device *evt = &clockevent_davinci;

+     //    printascii("entrei\n");
+ #ifdef CONFIG_IPIPE
+     ipipe_mach_update_tsc();
+ #endif                          /* CONFIG_IPIPE */
      evt->event_handler(evt);
      return IRQ_HANDLED;
  }
***************
*** 302,307 ****
--- 449,463 ----
              timer32_config(timers[i]);
          }
      }
+
+ #ifdef CONFIG_IPIPE
+ #ifndef CONFIG_SMP
+     tsc = (union tsc_reg *)__ipipe_tsc_area;
+     barrier();
+ #endif                /* CONFIG_SMP */
+     davinci_timer_initialized = 1;
+ #endif                          /* CONFIG_IPIPE */
+
  }

  /*
***************
*** 311,321 ****
  {
      struct timer_s *t;

!     if (tid_freerun == -1)
          t = timers[tid_system];
!     else
          t = timers[tid_freerun];
!
      return (cycles_t)timer32_read(t);
  }

--- 467,478 ----
  {
      struct timer_s *t;

!   if (tid_freerun == -1) {
          t = timers[tid_system];
!   }
!   else {
          t = timers[tid_freerun];
!   }
      return (cycles_t)timer32_read(t);
  }

***************
*** 549,551 ****
--- 706,718 ----
      wdtcr = 0x00004000;
      __raw_writel(wdtcr, base + WDTCR);
  }
+
+ #ifdef CONFIG_IPIPE
+ void __ipipe_mach_release_timer(void)
+ {
+   davinci_set_mode(clockevent_davinci.mode, &clockevent_davinci);
+   if (clockevent_davinci.mode == CLOCK_EVT_MODE_ONESHOT)
+     davinci_set_next_event(LATCH, &clockevent_davinci);
+ }
+ EXPORT_SYMBOL(__ipipe_mach_release_timer);
+ #endif /* CONFIG_IPIPE */

Best regards,

Flavio

Flavio de Castro Alves Filho
Phi Innovations - Embedded Software Services
www.phiinnovations.com
Phone: +55 11 84 94 56 76
Skype: flavio.de.castro.alves.filho


2010/1/8 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>

> Flavio de Castro Alves Filho wrote:
> > Of course :-)
> >
> > As I don't know the best way to send it, I attached the files.
> >
> > I hope everything is in there. I'm sorry if you find some ugly commented
> > debug code.
>
> Please send a diff.
>
> --
>                                             Gilles.
>

[-- Attachment #2: Type: text/html, Size: 18621 bytes --]

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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 21:54                                                         ` Flavio de Castro Alves Filho
@ 2010-01-08 22:26                                                           ` Gilles Chanteperdrix
  2010-01-13  8:50                                                             ` Flavio de Castro Alves Filho
  0 siblings, 1 reply; 38+ messages in thread
From: Gilles Chanteperdrix @ 2010-01-08 22:26 UTC (permalink / raw)
  To: Flavio de Castro Alves Filho; +Cc: xenomai

aFlavio de Castro Alves Filho wrote:
> In fact,
> 
> Much easier.
> 
> *** linux-03.20.00.05/arch/arm/mach-davinci/gpio.c    2009-07-29
> 02:53:15.000000000 -0300
> --- linux-03.20.00.05_xenomai/arch/arm/mach-davinci/gpio.c    2010-01-08
> 16:08:35.000000000 -0200
> ***************
> *** 27,32 ****
> --- 27,33 ----
> 
>   #include <asm/mach/irq.h>
> 
> + #include <asm/ipipe.h>
> 
>   static DEFINE_SPINLOCK(gpio_lock);
> 
> ***************
> *** 261,266 ****
> --- 262,315 ----
>       /* now it may re-trigger */
>   }
> 
> + #ifdef CONFIG_IPIPE
> +
> + /* Flavio Alves: for debugging */
> + extern void printascii(const char *);
> +
> + void __ipipe_mach_demux_irq(unsigned irq, struct pt_regs *regs)
> + {
> +     struct gpio_controller *__iomem g = get_irq_chip_data(irq);
> +     struct irq_desc *desc;
> +     u32 mask = 0xffff;
> +
> +     //printascii("1__ipipe_mach_demux_irq\n");
> +
> +     /* we only care about one bank */
> +     if (irq & 1)
> +         mask <<= 16;
> +
> +     desc = &irq_desc[irq];
> +
> +     /* temporarily mask (level sensitive) parent IRQ */
> +     desc->chip->ack(irq);

Wrong comment. ->ack does not mask the parent irq, it just acks it.
masking it would be wrong by the way, since demux should not be done
with parent irq masked, as you will find out in the linux-arm-kernel
mailing list archives

> +     while (1) {
> +         u32        status;
> +         int        n;
> +         int        res;
> +
> +         /* ack any irqs */
> +         status = __raw_readl(&g->intstat) & mask;
> +         if (!status)
> +             break;
> +         __raw_writel(status, &g->intstat);
> +         if (irq & 1)
> +             status >>= 16;
> +
> +         /* now demux them to the right lowlevel handler */
> +         n = (int)get_irq_data(irq);
> +         while (status) {
> +             res = ffs(status);
> +             n += res;
> +             __ipipe_handle_irq((n-1),regs);
> +             status >>= res;
> +         }

This while loop should reread the hardware status at each iteration, to
take into account new interrupts which would have showed up while
handling the last interrupt.

> +     }
> +     desc->chip->unmask(irq);

Not needed since you did not mask the parent irq.

> +     /* now it may re-trigger */
> + }
> + #endif /* CONFIG_IPIPE */
> +
>   /*
>    * NOTE:  for suspend/resume, probably best to make a platform_device with
>    * suspend_late/resume_resume calls hooking into results of the set_wake()
> diff -crB linux-03.20.00.05/arch/arm/mach-davinci/include/mach/irqs.h
> linux-03.20.00.05_xenomai/arch/arm/mach-davinci/include/mach/irqs.h
> *** linux-03.20.00.05/arch/arm/mach-davinci/include/mach/irqs.h
> 2009-07-29 02:53:15.000000000 -0300
> --- linux-03.20.00.05_xenomai/arch/arm/mach-davinci/include/mach/irqs.h
> 2010-01-06 16:45:56.000000000 -0200
> ***************
> *** 359,362 ****
> --- 359,381 ----
>   #define IRQ_DA850_MCBSP1RINT        99
>   #define IRQ_DA850_MCBSP1XINT        100
> 
> + #ifdef CONFIG_IPIPE
> + #if 0
> + #define __ipipe_mach_irq_mux_p(irq) \
> +         ((unsigned) (irq - IRQ_DA8XX_GPIO0) \
> +          <= (IRQ_DA8XX_GPIO7 - IRQ_DA8XX_GPIO0))
> + #endif
> + #define __ipipe_mach_irq_mux_p(irq) \
> +     ((irq) == IRQ_DA8XX_GPIO0 \
> +      || (irq) == IRQ_DA8XX_GPIO1 \
> +      || (irq) == IRQ_DA8XX_GPIO2 \
> +      || (irq) == IRQ_DA8XX_GPIO3 \
> +      || (irq) == IRQ_DA8XX_GPIO4 \
> +      || (irq) == IRQ_DA8XX_GPIO5 \
> +      || (irq) == IRQ_DA8XX_GPIO6 \
> +      || (irq) == IRQ_DA8XX_GPIO7)

Yuck. The "#if 0"ed one solution seems much better. You have to realize
that this macro is called for every interrupt so, it has to be pretty
fast. If the interrupts are not consecutive, then use a bit field
(s3cxxxx does it IIRC). But to get things working it is ok, you can fix
this later.

> +
> +
> + #endif /* CONFIG_IPIPE */
> +
>   #endif /* __ASM_ARCH_IRQS_H */
> diff -crB linux-03.20.00.05/arch/arm/mach-davinci/irq.c
> linux-03.20.00.05_xenomai/arch/arm/mach-davinci/irq.c
> *** linux-03.20.00.05/arch/arm/mach-davinci/irq.c    2009-07-29
> 02:53:15.000000000 -0300
> --- linux-03.20.00.05_xenomai/arch/arm/mach-davinci/irq.c    2010-01-08
> 15:22:13.000000000 -0200
> ***************
> *** 111,119 ****
> --- 111,228 ----
>       .name    = "AINTC",
>       .ack    = davinci_ack_irq,
>       .mask    = davinci_mask_irq,
> + #ifdef CONFIG_IPIPE
> +     .mask_ack = davinci_mask_irq,
> + #endif /* CONFIG_IPIPE */

No, no, no. BIG BUG here. Your PIC has different ack and mask routines,
so, both should be called by mask_ack.

You did not get this idea from the porting howto. I made this on some
platforms whre the ack and mask routines were the same, so that mask_ack
ended up doing twice the same thing.

Anyway, this kind of optimization is to be left aside when starting the
port.

>       .unmask = davinci_unmask_irq,
>   };
> 
> + #ifdef CONFIG_IPIPE
> + static const u8 da850_default_priorities[DAVINCI_N_AINTC_IRQ] __initdata =
> {
> +   [IRQ_DA8XX_COMMTX]             = 7,
> +   [IRQ_DA8XX_COMMRX]             = 7,
> +   [IRQ_DA8XX_NINT]               = 7,
> +   [IRQ_DA8XX_EVTOUT0]            = 7,
> +   [IRQ_DA8XX_EVTOUT1]            = 7,
> +   [IRQ_DA8XX_EVTOUT2]            = 7,
> +   [IRQ_DA8XX_EVTOUT3]            = 7,
> +   [IRQ_DA8XX_EVTOUT4]            = 7,
> +   [IRQ_DA8XX_EVTOUT5]            = 7,
> +   [IRQ_DA8XX_EVTOUT6]            = 7,
> +   [IRQ_DA8XX_EVTOUT7]            = 7,
> +   [IRQ_DA8XX_CCINT0]             = 7,
> +   [IRQ_DA8XX_CCERRINT]           = 7,
> +   [IRQ_DA8XX_TCERRINT0]          = 7,
> +   [IRQ_DA8XX_AEMIFINT]           = 7,
> +   [IRQ_DA8XX_I2CINT0]            = 5,
> +   [IRQ_DA8XX_MMCSDINT0]          = 5,
> +   [IRQ_DA8XX_MMCSDINT1]          = 5,
> +   [IRQ_DA8XX_ALLINT0]            = 5,
> +   [IRQ_DA8XX_RTC]                = 4,
> +   [IRQ_DA8XX_SPINT0]             = 5,
> +   [IRQ_DA8XX_TINT12_0]           = 2,
> +   [IRQ_DA8XX_TINT34_0]           = 5,
> +   [IRQ_DA8XX_TINT12_1]           = 5,
> +   [IRQ_DA8XX_TINT34_1]           = 5,
> +   [IRQ_DA8XX_UARTINT0]           = 5,
> +   [IRQ_DA8XX_KEYMGRINT]          = 7,
> +   [IRQ_DA850_MIOPU_BOOTCFG_ERR]  = 7,
> +   [IRQ_DA8XX_CHIPINT0]           = 7,
> +   [IRQ_DA8XX_CHIPINT1]           = 7,
> +   [IRQ_DA8XX_CHIPINT2]           = 7,
> +   [IRQ_DA8XX_CHIPINT3]           = 7,
> +   [IRQ_DA8XX_TCERRINT1]          = 7,
> +   [IRQ_DA8XX_C0_RX_THRESH_PULSE] = 7,
> +   [IRQ_DA8XX_C0_RX_PULSE]        = 7,
> +   [IRQ_DA8XX_C0_TX_PULSE]        = 7,
> +   [IRQ_DA8XX_C0_MISC_PULSE]      = 7,
> +   [IRQ_DA8XX_C1_RX_THRESH_PULSE] = 7,
> +   [IRQ_DA8XX_C1_RX_PULSE]        = 7,
> +   [IRQ_DA8XX_C1_TX_PULSE]        = 7,
> +   [IRQ_DA8XX_C1_MISC_PULSE]      = 7,
> +   [IRQ_DA8XX_MEMERR]             = 5,
> +   [IRQ_DA8XX_GPIO0]              = 6,
> +   [IRQ_DA8XX_GPIO1]              = 6,
> +   [IRQ_DA8XX_GPIO2]              = 6,
> +   [IRQ_DA8XX_GPIO3]              = 6,
> +   [IRQ_DA8XX_GPIO4]              = 6,
> +   [IRQ_DA8XX_GPIO5]              = 6,
> +   [IRQ_DA8XX_GPIO6]              = 6,
> +   [IRQ_DA8XX_GPIO7]              = 6,
> +   [IRQ_DA8XX_GPIO8]              = 6,
> +   [IRQ_DA8XX_I2CINT1]            = 5,
> +   [IRQ_DA8XX_LCDINT]             = 5,
> +   [IRQ_DA8XX_UARTINT1]           = 5,
> +   [IRQ_DA8XX_MCASPINT]           = 5,
> +   [IRQ_DA8XX_ALLINT1]            = 5,
> +   [IRQ_DA8XX_SPINT1]             = 5,
> +   [IRQ_DA8XX_UHPI_INT1]          = 5,
> +   [IRQ_DA8XX_USB_INT]            = 5,
> +   [IRQ_DA8XX_IRQN]               = 5,
> +   [IRQ_DA8XX_RWAKEUP]            = 5,
> +   [IRQ_DA8XX_UARTINT2]           = 5,
> +   [IRQ_DA8XX_DFTSSINT]           = 5,
> +   [IRQ_DA8XX_EHRPWM0]            = 7,
> +   [IRQ_DA8XX_EHRPWM0TZ]          = 7,
> +   [IRQ_DA8XX_EHRPWM1]            = 7,
> +   [IRQ_DA8XX_EHRPWM1TZ]          = 7,
> +   [IRQ_DA850_SATAINT]            = 5,
> +   [IRQ_DA850_TINT12_2]           = 5,
> +   [IRQ_DA8XX_ECAP0]              = 7,
> +   [IRQ_DA8XX_ECAP1]              = 7,
> +   [IRQ_DA8XX_ECAP2]              = 7,
> +   [IRQ_DA850_MMCSDINT0_1]        = 5,
> +   [IRQ_DA850_MMCSDINT1_1]        = 5,
> +   [IRQ_DA850_T12CMPINT0_2]       = 7,
> +   [IRQ_DA850_T12CMPINT1_2]       = 7,
> +   [IRQ_DA850_T12CMPINT2_2]       = 7,
> +   [IRQ_DA850_T12CMPINT3_2]       = 7,
> +   [IRQ_DA850_T12CMPINT4_2]       = 7,
> +   [IRQ_DA850_T12CMPINT5_2]       = 7,
> +   [IRQ_DA850_T12CMPINT6_2]       = 7,
> +   [IRQ_DA850_T12CMPINT7_2]       = 7,
> +   [IRQ_DA850_T12CMPINT0_3]       = 7,
> +   [IRQ_DA850_T12CMPINT1_3]       = 7,
> +   [IRQ_DA850_T12CMPINT2_3]       = 7,
> +   [IRQ_DA850_T12CMPINT3_3]       = 7,
> +   [IRQ_DA850_T12CMPINT4_3]       = 7,
> +   [IRQ_DA850_T12CMPINT5_3]       = 7,
> +   [IRQ_DA850_T12CMPINT6_3]       = 7,
> +   [IRQ_DA850_T12CMPINT7_3]       = 7,
> +   [IRQ_DA8XX_ARMCLKSTOPREQ]      = 7,
> +   [IRQ_DA850_RPIINT]             = 7,
> +   [IRQ_DA850_VPIFINT]            = 7,
> +   [IRQ_DA850_CCINT1]             = 7,
> +   [IRQ_DA850_CCERRINT1]          = 7,
> +   [IRQ_DA850_TCERRINT2]          = 7,
> +   [IRQ_DA850_TINT12_3]           = 5,
> +   [IRQ_DA850_MCBSP0RINT]         = 5,
> +   [IRQ_DA850_MCBSP0XINT]         = 5,
> +   [IRQ_DA850_MCBSP1RINT]         = 5,
> +   [IRQ_DA850_MCBSP1XINT]         = 5
> + };
> + #endif /* CONFIG_IPIPE */

Fiddling with IRQ priorities is mostly useless if you send the EOI to
the interrupt controller at the beginning of the interrupt handling as
davinci_ack_irq seems to do it.

Besides, we have the (undocumented) PIC mute functionality wich is even
better than interrupt priorities. I need to document it sometimes.

> +
>   /* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
>   static const u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] __initdata
> = {
>       [IRQ_VDINT0]        = 2,
> ***************
> *** 325,330 ****
> --- 434,443 ----
>           davinci_def_priorities = dm646x_default_priorities;
>       else if (cpu_is_davinci_dm355())
>           davinci_def_priorities = dm355_default_priorities;
> + #ifdef CONFIG_IPIPE
> +     else if (cpu_is_da850())
> +       davinci_def_priorities = da850_default_priorities;
> + #endif /* CONFIG_IPIPE */
> 
>       /* Clear all interrupt requests */
>       davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
> ***************
> *** 361,369 ****
> --- 474,484 ----
>       for (i = 0; i < DAVINCI_N_AINTC_IRQ; i++) {
>           set_irq_chip(i, &davinci_irq_chip_0);
>           set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
> + #ifndef CONFIG_IPIPE
>                   if (i != IRQ_TINT1_TINT34)
>                           set_irq_handler(i, handle_edge_irq);
>                   else
> + #endif /* CONFIG IPIPE */
>                           set_irq_handler(i, handle_level_irq);
>       }
>   }
> diff -crB linux-03.20.00.05/arch/arm/mach-davinci/time.c
> linux-03.20.00.05_xenomai/arch/arm/mach-davinci/time.c
> *** linux-03.20.00.05/arch/arm/mach-davinci/time.c    2009-07-29
> 02:53:15.000000000 -0300
> --- linux-03.20.00.05_xenomai/arch/arm/mach-davinci/time.c    2010-01-08
> 17:07:36.000000000 -0200
> ***************
> *** 30,35 ****
> --- 30,41 ----
>   #include <mach/cpu.h>
>   #include "clock.h"
> 
> + #ifdef CONFIG_IPIPE
> + #ifdef CONFIG_NO_IDLE_HZ
> + #error "dynamic tick timer not yet supported with IPIPE"
> + #endif /* CONFIG_NO_IDLE_HZ */
> + #endif /* CONFIG_IPIPE */
> +
>   static struct clock_event_device clockevent_davinci;
>   static unsigned int davinci_clock_tick_rate;
> 
> ***************
> *** 70,75 ****
> --- 76,102 ----
>   static int tid_system;
>   static int tid_freerun;
> 
> + #ifdef CONFIG_IPIPE
> + int          __ipipe_mach_timerint        = IRQ_DA8XX_TINT12_0;
> + int          __ipipe_mach_timerstolen     = 0;
> + unsigned int __ipipe_mach_ticks_per_jiffy = LATCH;
> + static int   davinci_timer_initialized;
> + 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;
> + };
> + #endif /* CONFIG_IPIPE */
> +
>   /*
>    * This driver configures the 2 64-bit count-up timers as 4 independent
>    * 32-bit count-up timers used as follows:
> ***************
> *** 92,97 ****
> --- 119,125 ----
>   #define TGCR                         0x24
>   #define WDTCR                        0x28
>   #define CMP12(n)             (0x60 + ((n) << 2))
> + #define INTCTLSTAT                   0x44
> 
>   /* Timer register bitfields */
>   #define TCR_ENAMODE_DISABLE          0x0
> ***************
> *** 137,142 ****
> --- 165,283 ----
>   #define TIMER_OPTS_ONESHOT    0x01
>   #define TIMER_OPTS_PERIODIC   0x02
> 
> + /* Flags to be set when it is necessary to clear the */
> + /* status register for timer interrupts              */
> + #define TIMER12_CLEAR_PRDINT  0x02
> + #define TIMER12_CLEAR_EVTINT  0x04
> +
> + #ifdef CONFIG_IPIPE
> + #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 *)(DAVINCI_TIMER0_BASE + TIM12);
> +     info->u.fr.mask = 0xffffffff;
> +     info->u.fr.tsc = &tsc->full;
> + }
> + #endif                /* !CONFIG_SMP */
> +
> + void __ipipe_mach_acktimer(void)
> + {
> +   void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
> +   unsigned long status;
> +
> +   status = __raw_readl(base + INTCTLSTAT);
> +   status |= (TIMER12_CLEAR_PRDINT | TIMER12_CLEAR_EVTINT);
> +
> +   __raw_writel(status,base+INTCTLSTAT);
> + }
> +
> + static void ipipe_mach_update_tsc(void)
> + {
> +   union tsc_reg *local_tsc;
> +   unsigned long stamp, flags;
> +   void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
> +
> +   local_irq_save_hw(flags);
> +   local_tsc = &tsc[ipipe_processor_id()];
> +   stamp = __raw_readl(base + TIM12);
> +   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(davinci_timer_initialized)) {
> +     union tsc_reg *local_tsc, result;
> +     unsigned long stamp;
> +     void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
> +
> +     local_tsc = &tsc[ipipe_processor_id()];
> +
> +     __asm__("ldmia %1, %M0\n":
> +         "=r"(result.full): "r"(local_tsc), "m"(*local_tsc));
> +     barrier();
> +     stamp = __raw_readl(base + TIM12);
> +     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;
> +   unsigned int  value;
> +   void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
> +
> +   if (delay > 20) {
> +     local_irq_save_hw(flags);
> +
> +     value = __raw_readl(base + TIM12) + delay;
> +     __raw_writel(value,base + CMP12(0));
> +     local_irq_restore_hw(flags);
> +   } else {
> +     ipipe_trigger_irq(IRQ_DA8XX_TINT12_0);
> +   }
> + }

I can not really comment on that, since I do not really know the
hardware details, though the code seems to indicate that the minimum is
1, not 20. 20 should be Ok for a first run though:

        clockevent_davinci.min_delta_ns =
                clockevent_delta2ns(1, &clockevent_davinci);

> + EXPORT_SYMBOL(__ipipe_mach_set_dec);
> +
> + unsigned long __ipipe_mach_get_dec(void)
> + {
> +   unsigned long value;
> +   void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
> +
> +   value  = __raw_readl(base + CMP12(0));
> +   value -= __raw_readl(base + TIM12);
> +
> +   return value;
> + }
> +
> + int __ipipe_check_tickdev(const char *devname)
> + {
> +   return !strcmp(devname, clockevent_davinci.name);
> + }
> +
> + #endif /* CONFIG_IPIPE */
> +
>   static int timer32_config(struct timer_s *t)
>   {
>       u32 tcr = __raw_readl(t->base + TCR);
> ***************
> *** 167,176 ****
> --- 308,324 ----
>       return __raw_readl(t->base + t->tim_off);
>   }
> 
> + /* Flavio Alves: for debugging */
> + extern void printascii(const char *);
> +
>   static irqreturn_t timer_interrupt(int irq, void *dev_id)
>   {
>       struct clock_event_device *evt = &clockevent_davinci;
> 
> +     //    printascii("entrei\n");
> + #ifdef CONFIG_IPIPE
> +     ipipe_mach_update_tsc();
> + #endif                          /* CONFIG_IPIPE */
>       evt->event_handler(evt);
>       return IRQ_HANDLED;
>   }

Ah. You have to realize that if the clockevent framework chooses an
other clockevent than this one, timer_interrupt will no longer be
called, so the tsc will wrap instead of incrementing correctly. So, as
explained in a previous mail, you have to:
- either increment clockevent_davinci.rating (currently uninitialized if
I read the code correctly, so 0)
- or base Xenomai timer on the other clockevent,
- or call ipipe_mach_update_tsc() in __ipipe_mach_acktimer (not a good
long term solution, but good for a quick test)



> ***************
> *** 302,307 ****
> --- 449,463 ----
>               timer32_config(timers[i]);
>           }
>       }
> +
> + #ifdef CONFIG_IPIPE
> + #ifndef CONFIG_SMP
> +     tsc = (union tsc_reg *)__ipipe_tsc_area;
> +     barrier();
> + #endif                /* CONFIG_SMP */
> +     davinci_timer_initialized = 1;
> + #endif                          /* CONFIG_IPIPE */
> +
>   }
> 
>   /*
> ***************
> *** 311,321 ****
>   {
>       struct timer_s *t;
> 
> !     if (tid_freerun == -1)
>           t = timers[tid_system];
> !     else
>           t = timers[tid_freerun];
> !
>       return (cycles_t)timer32_read(t);
>   }
> 
> --- 467,478 ----
>   {
>       struct timer_s *t;
> 
> !   if (tid_freerun == -1) {
>           t = timers[tid_system];
> !   }
> !   else {
>           t = timers[tid_freerun];
> !   }
>       return (cycles_t)timer32_read(t);
>   }
> 
> ***************
> *** 549,551 ****
> --- 706,718 ----
>       wdtcr = 0x00004000;
>       __raw_writel(wdtcr, base + WDTCR);
>   }
> +
> + #ifdef CONFIG_IPIPE
> + void __ipipe_mach_release_timer(void)
> + {
> +   davinci_set_mode(clockevent_davinci.mode, &clockevent_davinci);
> +   if (clockevent_davinci.mode == CLOCK_EVT_MODE_ONESHOT)
> +     davinci_set_next_event(LATCH, &clockevent_davinci);
> + }
> + EXPORT_SYMBOL(__ipipe_mach_release_timer);
> + #endif /* CONFIG_IPIPE */
> 
> Best regards,

Ok. I think the bug really comes from the ack_mask thing. Other than
that, great work, the patch looks fine. Good luck.

-- 
					    Gilles.


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-08 22:26                                                           ` Gilles Chanteperdrix
@ 2010-01-13  8:50                                                             ` Flavio de Castro Alves Filho
  2010-01-13 10:05                                                               ` Gilles Chanteperdrix
  0 siblings, 1 reply; 38+ messages in thread
From: Flavio de Castro Alves Filho @ 2010-01-13  8:50 UTC (permalink / raw)
  To: xenomai

Hello Gilles,

First of all, really thank you for you revision. It was really helpful.

And ... about the changes. I implemented the corrections as you
suggested and it is still not working. It is blocking allways at the
same place.

I'm still working to find out a solution.

Thank you very much.

Flavio

Flavio de Castro Alves Filho
Phi Innovations - Embedded Software Services
www.phiinnovations.com
Phone: +55 11 84 94 56 76
Skype: flavio.de.castro.alves.filho



2010/1/8 Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>:
> aFlavio de Castro Alves Filho wrote:
>> In fact,
>>
>> Much easier.
>>
>> *** linux-03.20.00.05/arch/arm/mach-davinci/gpio.c    2009-07-29
>> 02:53:15.000000000 -0300
>> --- linux-03.20.00.05_xenomai/arch/arm/mach-davinci/gpio.c    2010-01-08
>> 16:08:35.000000000 -0200
>> ***************
>> *** 27,32 ****
>> --- 27,33 ----
>>
>>   #include <asm/mach/irq.h>
>>
>> + #include <asm/ipipe.h>
>>
>>   static DEFINE_SPINLOCK(gpio_lock);
>>
>> ***************
>> *** 261,266 ****
>> --- 262,315 ----
>>       /* now it may re-trigger */
>>   }
>>
>> + #ifdef CONFIG_IPIPE
>> +
>> + /* Flavio Alves: for debugging */
>> + extern void printascii(const char *);
>> +
>> + void __ipipe_mach_demux_irq(unsigned irq, struct pt_regs *regs)
>> + {
>> +     struct gpio_controller *__iomem g = get_irq_chip_data(irq);
>> +     struct irq_desc *desc;
>> +     u32 mask = 0xffff;
>> +
>> +     //printascii("1__ipipe_mach_demux_irq\n");
>> +
>> +     /* we only care about one bank */
>> +     if (irq & 1)
>> +         mask <<= 16;
>> +
>> +     desc = &irq_desc[irq];
>> +
>> +     /* temporarily mask (level sensitive) parent IRQ */
>> +     desc->chip->ack(irq);
>
> Wrong comment. ->ack does not mask the parent irq, it just acks it.
> masking it would be wrong by the way, since demux should not be done
> with parent irq masked, as you will find out in the linux-arm-kernel
> mailing list archives
>
>> +     while (1) {
>> +         u32        status;
>> +         int        n;
>> +         int        res;
>> +
>> +         /* ack any irqs */
>> +         status = __raw_readl(&g->intstat) & mask;
>> +         if (!status)
>> +             break;
>> +         __raw_writel(status, &g->intstat);
>> +         if (irq & 1)
>> +             status >>= 16;
>> +
>> +         /* now demux them to the right lowlevel handler */
>> +         n = (int)get_irq_data(irq);
>> +         while (status) {
>> +             res = ffs(status);
>> +             n += res;
>> +             __ipipe_handle_irq((n-1),regs);
>> +             status >>= res;
>> +         }
>
> This while loop should reread the hardware status at each iteration, to
> take into account new interrupts which would have showed up while
> handling the last interrupt.
>
>> +     }
>> +     desc->chip->unmask(irq);
>
> Not needed since you did not mask the parent irq.
>
>> +     /* now it may re-trigger */
>> + }
>> + #endif /* CONFIG_IPIPE */
>> +
>>   /*
>>    * NOTE:  for suspend/resume, probably best to make a platform_device with
>>    * suspend_late/resume_resume calls hooking into results of the set_wake()
>> diff -crB linux-03.20.00.05/arch/arm/mach-davinci/include/mach/irqs.h
>> linux-03.20.00.05_xenomai/arch/arm/mach-davinci/include/mach/irqs.h
>> *** linux-03.20.00.05/arch/arm/mach-davinci/include/mach/irqs.h
>> 2009-07-29 02:53:15.000000000 -0300
>> --- linux-03.20.00.05_xenomai/arch/arm/mach-davinci/include/mach/irqs.h
>> 2010-01-06 16:45:56.000000000 -0200
>> ***************
>> *** 359,362 ****
>> --- 359,381 ----
>>   #define IRQ_DA850_MCBSP1RINT        99
>>   #define IRQ_DA850_MCBSP1XINT        100
>>
>> + #ifdef CONFIG_IPIPE
>> + #if 0
>> + #define __ipipe_mach_irq_mux_p(irq) \
>> +         ((unsigned) (irq - IRQ_DA8XX_GPIO0) \
>> +          <= (IRQ_DA8XX_GPIO7 - IRQ_DA8XX_GPIO0))
>> + #endif
>> + #define __ipipe_mach_irq_mux_p(irq) \
>> +     ((irq) == IRQ_DA8XX_GPIO0 \
>> +      || (irq) == IRQ_DA8XX_GPIO1 \
>> +      || (irq) == IRQ_DA8XX_GPIO2 \
>> +      || (irq) == IRQ_DA8XX_GPIO3 \
>> +      || (irq) == IRQ_DA8XX_GPIO4 \
>> +      || (irq) == IRQ_DA8XX_GPIO5 \
>> +      || (irq) == IRQ_DA8XX_GPIO6 \
>> +      || (irq) == IRQ_DA8XX_GPIO7)
>
> Yuck. The "#if 0"ed one solution seems much better. You have to realize
> that this macro is called for every interrupt so, it has to be pretty
> fast. If the interrupts are not consecutive, then use a bit field
> (s3cxxxx does it IIRC). But to get things working it is ok, you can fix
> this later.
>
>> +
>> +
>> + #endif /* CONFIG_IPIPE */
>> +
>>   #endif /* __ASM_ARCH_IRQS_H */
>> diff -crB linux-03.20.00.05/arch/arm/mach-davinci/irq.c
>> linux-03.20.00.05_xenomai/arch/arm/mach-davinci/irq.c
>> *** linux-03.20.00.05/arch/arm/mach-davinci/irq.c    2009-07-29
>> 02:53:15.000000000 -0300
>> --- linux-03.20.00.05_xenomai/arch/arm/mach-davinci/irq.c    2010-01-08
>> 15:22:13.000000000 -0200
>> ***************
>> *** 111,119 ****
>> --- 111,228 ----
>>       .name    = "AINTC",
>>       .ack    = davinci_ack_irq,
>>       .mask    = davinci_mask_irq,
>> + #ifdef CONFIG_IPIPE
>> +     .mask_ack = davinci_mask_irq,
>> + #endif /* CONFIG_IPIPE */
>
> No, no, no. BIG BUG here. Your PIC has different ack and mask routines,
> so, both should be called by mask_ack.
>
> You did not get this idea from the porting howto. I made this on some
> platforms whre the ack and mask routines were the same, so that mask_ack
> ended up doing twice the same thing.
>
> Anyway, this kind of optimization is to be left aside when starting the
> port.
>
>>       .unmask = davinci_unmask_irq,
>>   };
>>
>> + #ifdef CONFIG_IPIPE
>> + static const u8 da850_default_priorities[DAVINCI_N_AINTC_IRQ] __initdata =
>> {
>> +   [IRQ_DA8XX_COMMTX]             = 7,
>> +   [IRQ_DA8XX_COMMRX]             = 7,
>> +   [IRQ_DA8XX_NINT]               = 7,
>> +   [IRQ_DA8XX_EVTOUT0]            = 7,
>> +   [IRQ_DA8XX_EVTOUT1]            = 7,
>> +   [IRQ_DA8XX_EVTOUT2]            = 7,
>> +   [IRQ_DA8XX_EVTOUT3]            = 7,
>> +   [IRQ_DA8XX_EVTOUT4]            = 7,
>> +   [IRQ_DA8XX_EVTOUT5]            = 7,
>> +   [IRQ_DA8XX_EVTOUT6]            = 7,
>> +   [IRQ_DA8XX_EVTOUT7]            = 7,
>> +   [IRQ_DA8XX_CCINT0]             = 7,
>> +   [IRQ_DA8XX_CCERRINT]           = 7,
>> +   [IRQ_DA8XX_TCERRINT0]          = 7,
>> +   [IRQ_DA8XX_AEMIFINT]           = 7,
>> +   [IRQ_DA8XX_I2CINT0]            = 5,
>> +   [IRQ_DA8XX_MMCSDINT0]          = 5,
>> +   [IRQ_DA8XX_MMCSDINT1]          = 5,
>> +   [IRQ_DA8XX_ALLINT0]            = 5,
>> +   [IRQ_DA8XX_RTC]                = 4,
>> +   [IRQ_DA8XX_SPINT0]             = 5,
>> +   [IRQ_DA8XX_TINT12_0]           = 2,
>> +   [IRQ_DA8XX_TINT34_0]           = 5,
>> +   [IRQ_DA8XX_TINT12_1]           = 5,
>> +   [IRQ_DA8XX_TINT34_1]           = 5,
>> +   [IRQ_DA8XX_UARTINT0]           = 5,
>> +   [IRQ_DA8XX_KEYMGRINT]          = 7,
>> +   [IRQ_DA850_MIOPU_BOOTCFG_ERR]  = 7,
>> +   [IRQ_DA8XX_CHIPINT0]           = 7,
>> +   [IRQ_DA8XX_CHIPINT1]           = 7,
>> +   [IRQ_DA8XX_CHIPINT2]           = 7,
>> +   [IRQ_DA8XX_CHIPINT3]           = 7,
>> +   [IRQ_DA8XX_TCERRINT1]          = 7,
>> +   [IRQ_DA8XX_C0_RX_THRESH_PULSE] = 7,
>> +   [IRQ_DA8XX_C0_RX_PULSE]        = 7,
>> +   [IRQ_DA8XX_C0_TX_PULSE]        = 7,
>> +   [IRQ_DA8XX_C0_MISC_PULSE]      = 7,
>> +   [IRQ_DA8XX_C1_RX_THRESH_PULSE] = 7,
>> +   [IRQ_DA8XX_C1_RX_PULSE]        = 7,
>> +   [IRQ_DA8XX_C1_TX_PULSE]        = 7,
>> +   [IRQ_DA8XX_C1_MISC_PULSE]      = 7,
>> +   [IRQ_DA8XX_MEMERR]             = 5,
>> +   [IRQ_DA8XX_GPIO0]              = 6,
>> +   [IRQ_DA8XX_GPIO1]              = 6,
>> +   [IRQ_DA8XX_GPIO2]              = 6,
>> +   [IRQ_DA8XX_GPIO3]              = 6,
>> +   [IRQ_DA8XX_GPIO4]              = 6,
>> +   [IRQ_DA8XX_GPIO5]              = 6,
>> +   [IRQ_DA8XX_GPIO6]              = 6,
>> +   [IRQ_DA8XX_GPIO7]              = 6,
>> +   [IRQ_DA8XX_GPIO8]              = 6,
>> +   [IRQ_DA8XX_I2CINT1]            = 5,
>> +   [IRQ_DA8XX_LCDINT]             = 5,
>> +   [IRQ_DA8XX_UARTINT1]           = 5,
>> +   [IRQ_DA8XX_MCASPINT]           = 5,
>> +   [IRQ_DA8XX_ALLINT1]            = 5,
>> +   [IRQ_DA8XX_SPINT1]             = 5,
>> +   [IRQ_DA8XX_UHPI_INT1]          = 5,
>> +   [IRQ_DA8XX_USB_INT]            = 5,
>> +   [IRQ_DA8XX_IRQN]               = 5,
>> +   [IRQ_DA8XX_RWAKEUP]            = 5,
>> +   [IRQ_DA8XX_UARTINT2]           = 5,
>> +   [IRQ_DA8XX_DFTSSINT]           = 5,
>> +   [IRQ_DA8XX_EHRPWM0]            = 7,
>> +   [IRQ_DA8XX_EHRPWM0TZ]          = 7,
>> +   [IRQ_DA8XX_EHRPWM1]            = 7,
>> +   [IRQ_DA8XX_EHRPWM1TZ]          = 7,
>> +   [IRQ_DA850_SATAINT]            = 5,
>> +   [IRQ_DA850_TINT12_2]           = 5,
>> +   [IRQ_DA8XX_ECAP0]              = 7,
>> +   [IRQ_DA8XX_ECAP1]              = 7,
>> +   [IRQ_DA8XX_ECAP2]              = 7,
>> +   [IRQ_DA850_MMCSDINT0_1]        = 5,
>> +   [IRQ_DA850_MMCSDINT1_1]        = 5,
>> +   [IRQ_DA850_T12CMPINT0_2]       = 7,
>> +   [IRQ_DA850_T12CMPINT1_2]       = 7,
>> +   [IRQ_DA850_T12CMPINT2_2]       = 7,
>> +   [IRQ_DA850_T12CMPINT3_2]       = 7,
>> +   [IRQ_DA850_T12CMPINT4_2]       = 7,
>> +   [IRQ_DA850_T12CMPINT5_2]       = 7,
>> +   [IRQ_DA850_T12CMPINT6_2]       = 7,
>> +   [IRQ_DA850_T12CMPINT7_2]       = 7,
>> +   [IRQ_DA850_T12CMPINT0_3]       = 7,
>> +   [IRQ_DA850_T12CMPINT1_3]       = 7,
>> +   [IRQ_DA850_T12CMPINT2_3]       = 7,
>> +   [IRQ_DA850_T12CMPINT3_3]       = 7,
>> +   [IRQ_DA850_T12CMPINT4_3]       = 7,
>> +   [IRQ_DA850_T12CMPINT5_3]       = 7,
>> +   [IRQ_DA850_T12CMPINT6_3]       = 7,
>> +   [IRQ_DA850_T12CMPINT7_3]       = 7,
>> +   [IRQ_DA8XX_ARMCLKSTOPREQ]      = 7,
>> +   [IRQ_DA850_RPIINT]             = 7,
>> +   [IRQ_DA850_VPIFINT]            = 7,
>> +   [IRQ_DA850_CCINT1]             = 7,
>> +   [IRQ_DA850_CCERRINT1]          = 7,
>> +   [IRQ_DA850_TCERRINT2]          = 7,
>> +   [IRQ_DA850_TINT12_3]           = 5,
>> +   [IRQ_DA850_MCBSP0RINT]         = 5,
>> +   [IRQ_DA850_MCBSP0XINT]         = 5,
>> +   [IRQ_DA850_MCBSP1RINT]         = 5,
>> +   [IRQ_DA850_MCBSP1XINT]         = 5
>> + };
>> + #endif /* CONFIG_IPIPE */
>
> Fiddling with IRQ priorities is mostly useless if you send the EOI to
> the interrupt controller at the beginning of the interrupt handling as
> davinci_ack_irq seems to do it.
>
> Besides, we have the (undocumented) PIC mute functionality wich is even
> better than interrupt priorities. I need to document it sometimes.
>
>> +
>>   /* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
>>   static const u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] __initdata
>> = {
>>       [IRQ_VDINT0]        = 2,
>> ***************
>> *** 325,330 ****
>> --- 434,443 ----
>>           davinci_def_priorities = dm646x_default_priorities;
>>       else if (cpu_is_davinci_dm355())
>>           davinci_def_priorities = dm355_default_priorities;
>> + #ifdef CONFIG_IPIPE
>> +     else if (cpu_is_da850())
>> +       davinci_def_priorities = da850_default_priorities;
>> + #endif /* CONFIG_IPIPE */
>>
>>       /* Clear all interrupt requests */
>>       davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
>> ***************
>> *** 361,369 ****
>> --- 474,484 ----
>>       for (i = 0; i < DAVINCI_N_AINTC_IRQ; i++) {
>>           set_irq_chip(i, &davinci_irq_chip_0);
>>           set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
>> + #ifndef CONFIG_IPIPE
>>                   if (i != IRQ_TINT1_TINT34)
>>                           set_irq_handler(i, handle_edge_irq);
>>                   else
>> + #endif /* CONFIG IPIPE */
>>                           set_irq_handler(i, handle_level_irq);
>>       }
>>   }
>> diff -crB linux-03.20.00.05/arch/arm/mach-davinci/time.c
>> linux-03.20.00.05_xenomai/arch/arm/mach-davinci/time.c
>> *** linux-03.20.00.05/arch/arm/mach-davinci/time.c    2009-07-29
>> 02:53:15.000000000 -0300
>> --- linux-03.20.00.05_xenomai/arch/arm/mach-davinci/time.c    2010-01-08
>> 17:07:36.000000000 -0200
>> ***************
>> *** 30,35 ****
>> --- 30,41 ----
>>   #include <mach/cpu.h>
>>   #include "clock.h"
>>
>> + #ifdef CONFIG_IPIPE
>> + #ifdef CONFIG_NO_IDLE_HZ
>> + #error "dynamic tick timer not yet supported with IPIPE"
>> + #endif /* CONFIG_NO_IDLE_HZ */
>> + #endif /* CONFIG_IPIPE */
>> +
>>   static struct clock_event_device clockevent_davinci;
>>   static unsigned int davinci_clock_tick_rate;
>>
>> ***************
>> *** 70,75 ****
>> --- 76,102 ----
>>   static int tid_system;
>>   static int tid_freerun;
>>
>> + #ifdef CONFIG_IPIPE
>> + int          __ipipe_mach_timerint        = IRQ_DA8XX_TINT12_0;
>> + int          __ipipe_mach_timerstolen     = 0;
>> + unsigned int __ipipe_mach_ticks_per_jiffy = LATCH;
>> + static int   davinci_timer_initialized;
>> + 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;
>> + };
>> + #endif /* CONFIG_IPIPE */
>> +
>>   /*
>>    * This driver configures the 2 64-bit count-up timers as 4 independent
>>    * 32-bit count-up timers used as follows:
>> ***************
>> *** 92,97 ****
>> --- 119,125 ----
>>   #define TGCR                         0x24
>>   #define WDTCR                        0x28
>>   #define CMP12(n)             (0x60 + ((n) << 2))
>> + #define INTCTLSTAT                   0x44
>>
>>   /* Timer register bitfields */
>>   #define TCR_ENAMODE_DISABLE          0x0
>> ***************
>> *** 137,142 ****
>> --- 165,283 ----
>>   #define TIMER_OPTS_ONESHOT    0x01
>>   #define TIMER_OPTS_PERIODIC   0x02
>>
>> + /* Flags to be set when it is necessary to clear the */
>> + /* status register for timer interrupts              */
>> + #define TIMER12_CLEAR_PRDINT  0x02
>> + #define TIMER12_CLEAR_EVTINT  0x04
>> +
>> + #ifdef CONFIG_IPIPE
>> + #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 *)(DAVINCI_TIMER0_BASE + TIM12);
>> +     info->u.fr.mask = 0xffffffff;
>> +     info->u.fr.tsc = &tsc->full;
>> + }
>> + #endif                /* !CONFIG_SMP */
>> +
>> + void __ipipe_mach_acktimer(void)
>> + {
>> +   void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
>> +   unsigned long status;
>> +
>> +   status = __raw_readl(base + INTCTLSTAT);
>> +   status |= (TIMER12_CLEAR_PRDINT | TIMER12_CLEAR_EVTINT);
>> +
>> +   __raw_writel(status,base+INTCTLSTAT);
>> + }
>> +
>> + static void ipipe_mach_update_tsc(void)
>> + {
>> +   union tsc_reg *local_tsc;
>> +   unsigned long stamp, flags;
>> +   void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
>> +
>> +   local_irq_save_hw(flags);
>> +   local_tsc = &tsc[ipipe_processor_id()];
>> +   stamp = __raw_readl(base + TIM12);
>> +   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(davinci_timer_initialized)) {
>> +     union tsc_reg *local_tsc, result;
>> +     unsigned long stamp;
>> +     void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
>> +
>> +     local_tsc = &tsc[ipipe_processor_id()];
>> +
>> +     __asm__("ldmia %1, %M0\n":
>> +         "=r"(result.full): "r"(local_tsc), "m"(*local_tsc));
>> +     barrier();
>> +     stamp = __raw_readl(base + TIM12);
>> +     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;
>> +   unsigned int  value;
>> +   void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
>> +
>> +   if (delay > 20) {
>> +     local_irq_save_hw(flags);
>> +
>> +     value = __raw_readl(base + TIM12) + delay;
>> +     __raw_writel(value,base + CMP12(0));
>> +     local_irq_restore_hw(flags);
>> +   } else {
>> +     ipipe_trigger_irq(IRQ_DA8XX_TINT12_0);
>> +   }
>> + }
>
> I can not really comment on that, since I do not really know the
> hardware details, though the code seems to indicate that the minimum is
> 1, not 20. 20 should be Ok for a first run though:
>
>        clockevent_davinci.min_delta_ns =
>                clockevent_delta2ns(1, &clockevent_davinci);
>
>> + EXPORT_SYMBOL(__ipipe_mach_set_dec);
>> +
>> + unsigned long __ipipe_mach_get_dec(void)
>> + {
>> +   unsigned long value;
>> +   void __iomem *base = IO_ADDRESS(DAVINCI_TIMER0_BASE);
>> +
>> +   value  = __raw_readl(base + CMP12(0));
>> +   value -= __raw_readl(base + TIM12);
>> +
>> +   return value;
>> + }
>> +
>> + int __ipipe_check_tickdev(const char *devname)
>> + {
>> +   return !strcmp(devname, clockevent_davinci.name);
>> + }
>> +
>> + #endif /* CONFIG_IPIPE */
>> +
>>   static int timer32_config(struct timer_s *t)
>>   {
>>       u32 tcr = __raw_readl(t->base + TCR);
>> ***************
>> *** 167,176 ****
>> --- 308,324 ----
>>       return __raw_readl(t->base + t->tim_off);
>>   }
>>
>> + /* Flavio Alves: for debugging */
>> + extern void printascii(const char *);
>> +
>>   static irqreturn_t timer_interrupt(int irq, void *dev_id)
>>   {
>>       struct clock_event_device *evt = &clockevent_davinci;
>>
>> +     //    printascii("entrei\n");
>> + #ifdef CONFIG_IPIPE
>> +     ipipe_mach_update_tsc();
>> + #endif                          /* CONFIG_IPIPE */
>>       evt->event_handler(evt);
>>       return IRQ_HANDLED;
>>   }
>
> Ah. You have to realize that if the clockevent framework chooses an
> other clockevent than this one, timer_interrupt will no longer be
> called, so the tsc will wrap instead of incrementing correctly. So, as
> explained in a previous mail, you have to:
> - either increment clockevent_davinci.rating (currently uninitialized if
> I read the code correctly, so 0)
> - or base Xenomai timer on the other clockevent,
> - or call ipipe_mach_update_tsc() in __ipipe_mach_acktimer (not a good
> long term solution, but good for a quick test)
>
>
>
>> ***************
>> *** 302,307 ****
>> --- 449,463 ----
>>               timer32_config(timers[i]);
>>           }
>>       }
>> +
>> + #ifdef CONFIG_IPIPE
>> + #ifndef CONFIG_SMP
>> +     tsc = (union tsc_reg *)__ipipe_tsc_area;
>> +     barrier();
>> + #endif                /* CONFIG_SMP */
>> +     davinci_timer_initialized = 1;
>> + #endif                          /* CONFIG_IPIPE */
>> +
>>   }
>>
>>   /*
>> ***************
>> *** 311,321 ****
>>   {
>>       struct timer_s *t;
>>
>> !     if (tid_freerun == -1)
>>           t = timers[tid_system];
>> !     else
>>           t = timers[tid_freerun];
>> !
>>       return (cycles_t)timer32_read(t);
>>   }
>>
>> --- 467,478 ----
>>   {
>>       struct timer_s *t;
>>
>> !   if (tid_freerun == -1) {
>>           t = timers[tid_system];
>> !   }
>> !   else {
>>           t = timers[tid_freerun];
>> !   }
>>       return (cycles_t)timer32_read(t);
>>   }
>>
>> ***************
>> *** 549,551 ****
>> --- 706,718 ----
>>       wdtcr = 0x00004000;
>>       __raw_writel(wdtcr, base + WDTCR);
>>   }
>> +
>> + #ifdef CONFIG_IPIPE
>> + void __ipipe_mach_release_timer(void)
>> + {
>> +   davinci_set_mode(clockevent_davinci.mode, &clockevent_davinci);
>> +   if (clockevent_davinci.mode == CLOCK_EVT_MODE_ONESHOT)
>> +     davinci_set_next_event(LATCH, &clockevent_davinci);
>> + }
>> + EXPORT_SYMBOL(__ipipe_mach_release_timer);
>> + #endif /* CONFIG_IPIPE */
>>
>> Best regards,
>
> Ok. I think the bug really comes from the ack_mask thing. Other than
> that, great work, the patch looks fine. Good luck.
>
> --
>                                            Gilles.
>


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

* Re: [Xenomai-help] Porting I-Pipe for new ARM board
  2010-01-13  8:50                                                             ` Flavio de Castro Alves Filho
@ 2010-01-13 10:05                                                               ` Gilles Chanteperdrix
  0 siblings, 0 replies; 38+ messages in thread
From: Gilles Chanteperdrix @ 2010-01-13 10:05 UTC (permalink / raw)
  To: Flavio de Castro Alves Filho; +Cc: xenomai

Flavio de Castro Alves Filho wrote:
> Hello Gilles,
> 
> First of all, really thank you for you revision. It was really helpful.
> 
> And ... about the changes. I implemented the corrections as you
> suggested and it is still not working. It is blocking allways at the
> same place.
> 
> I'm still working to find out a solution.

Ok. Do you know if the error happens around a multiplexed interrupt?

If that was the case, please try to get __ipipe_irq_mux_p to return
always 0, and modify Linux demuxer to call __ipipe_handle_irq instead of
handle_irq when CONFIG_IPIPE is on.

-- 
					    Gilles.


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

end of thread, other threads:[~2010-01-13 10:05 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-03 15:00 [Xenomai-help] Porting I-Pipe for new ARM board Wael Showair
2009-11-03 15:13 ` Gilles Chanteperdrix
2009-11-03 15:45   ` Didenko Sergey
2009-11-03 15:48     ` Gilles Chanteperdrix
2009-11-04  6:58     ` Wael Showair
2009-11-04 10:54     ` Gilles Chanteperdrix
2009-11-06  9:08       ` Wael Showair
2009-11-06  9:39         ` Sergey Didenko
2009-11-06 10:22           ` Gilles Chanteperdrix
2009-12-15 19:37           ` Олександр Лаврущенко
2009-12-15 20:34             ` Gilles Chanteperdrix
     [not found]           ` <20091215213210.19d5b6a5@domain.hid>
2009-12-16  1:15             ` Sergey Didenko
2009-12-31 12:52               ` Flavio de Castro Alves Filho
2009-12-31 15:41                 ` Gilles Chanteperdrix
2010-01-04 22:14                   ` Flavio Alves
2010-01-04 22:22                     ` Gilles Chanteperdrix
2010-01-06 10:56                       ` Flavio Alves
2010-01-06 11:01                         ` Gilles Chanteperdrix
2010-01-06 11:38                           ` Flavio de Castro Alves Filho
2010-01-06 14:01                             ` Gilles Chanteperdrix
2010-01-06 19:16                               ` Flavio de Castro Alves Filho
2010-01-06 19:23                                 ` Gilles Chanteperdrix
2010-01-08 14:11                                   ` Flavio de Castro Alves Filho
2010-01-08 14:35                                     ` Gilles Chanteperdrix
2010-01-08 14:58                                       ` Flavio de Castro Alves Filho
2010-01-08 15:36                                         ` Gilles Chanteperdrix
2010-01-08 17:43                                           ` Flavio de Castro Alves Filho
2010-01-08 18:02                                             ` Flavio de Castro Alves Filho
2010-01-08 18:08                                               ` Gilles Chanteperdrix
2010-01-08 19:27                                                 ` Flavio de Castro Alves Filho
2010-01-08 19:31                                                   ` Gilles Chanteperdrix
2010-01-08 19:42                                                     ` Flavio de Castro Alves Filho
2010-01-08 19:45                                                       ` Gilles Chanteperdrix
2010-01-08 21:54                                                         ` Flavio de Castro Alves Filho
2010-01-08 22:26                                                           ` Gilles Chanteperdrix
2010-01-13  8:50                                                             ` Flavio de Castro Alves Filho
2010-01-13 10:05                                                               ` Gilles Chanteperdrix
2010-01-08 19:32                                                   ` 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.