All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wael Showair <showair2003@domain.hid>
To: Xenomai-help@domain.hid
Cc: didenkos@domain.hid
Subject: [Xenomai-help] Porting I-Pipe for new ARM board
Date: Tue, 3 Nov 2009 07:00:26 -0800 (PST)	[thread overview]
Message-ID: <725957.56219.qm@domain.hid> (raw)

[-- 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 --]

             reply	other threads:[~2009-11-03 15:00 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-03 15:00 Wael Showair [this message]
2009-11-03 15:13 ` [Xenomai-help] Porting I-Pipe for new ARM board 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

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=725957.56219.qm@domain.hid \
    --to=showair2003@domain.hid \
    --cc=Xenomai-help@domain.hid \
    --cc=didenkos@domain.hid \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.