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

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.