Monday, September 6, 2010

Jiffies fixed!

It was found that the part of the code used to program INTC was not well structured. There were pieces of GPT IRQ handling code within irq.c, thereby making IRQ file non generic.

This was cleaned up to be generic and following the linux kernel interrupt handling framework.

Following this, it was also found that the GPT timer, which was earlier programmed as a clock source was wrong. Modified the code to use SYS_TIMER framework.
This includes adding


struct sys_timer puppy_timer = {
.init = puppy_timer_init,
};

where


void __init puppy_timer_init(void)
{
u32 val;

/*Claim GPT1 IRQ*/
setup_irq(GPT_IRQ, &puppy_timer_irq);
/* Enable ICLK to gain access to GPT module registers */

val = readl(__io_address(PUPPY_ICLKEN_WKUP));
writel(GPT1_ICLKEN | val, __io_address(PUPPY_ICLKEN_WKUP));

/* Reset GPT */
writel(GPT1_SOFT_RST, __io_address(PUPPY_GPT1_TIOCP_CFG));


writel(0xFFF00000, __io_address(PUPPY_GPT1_TLDR));
writel(0x1, __io_address(PUPPY_GPT1_TTGR));



/*Enable interrupts in INTC for GPT1*/
puppy_irq_unmask(GPT_IRQ);

/*Enable all interrupts in GPT module*/
writel(0x7, __io_address(PUPPY_GPT1_TIER));

/*Configure GPT for Auto Reloading after Overflow and restart timer*/
writel(GPT1_AR | GPT1_STOP_START, __io_address(PUPPY_GPT1_TCLR));


}

In addition to this, it was also found that the IRQ code was looping forever between IVT and asm_do_irq()
The culprit was an irq->action function which was missing in my earlier GPT driver implementation.

Hence, to fix this, I added the following code after referring to mach-at91 timer driver file.



static struct irqaction puppy_timer_irq = {
.name = "puppy_tick",
.flags = IRQF_DISABLED | IRQF_TIMER,
.handler = puppy_timer_isr
};


where


static irqreturn_t puppy_timer_isr(int irq, void *dev_id)
{
/* Increment Jiffies */
do_timer(1);

/* Clear interrupt pending flag (TODO: OVF interrupt flag only for now)*/
writel(0x2, __io_address(PUPPY_GPT1_TISR));

return IRQ_HANDLED;
}

Note that do_timer(1) is the function that updates the jiffies value!

Also, with my earlier implementation, I had a very high initial value loaded for GPT counter (0xFFFF0000), which resulted in too many interrupts triggered, without allowing other parts of the BSP code to get executed and hence, stuck in calibration_loop() as jiffies incremented can be compared here and proceed further.

Hence reduced this value to 0xFFF00000 which now provides chance for other parts of the code to get executed and thus allowing increment of jiffies value and further code execution within calibration_loop( ).

Now, its possible to go beyond calibration loop function. Below is the log that I now see:

OMAP3 beagleboard.org # bootm 0x80300000
## Booting kernel from Legacy Image at 80300000 ...
   Image Name:   Puppy Linux
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    1393096 Bytes =  1.3 MB
   Load Address: 80008000
   Entry Point:  80008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
<5>Linux version 2.6.35-rc3 (amar@amar-laptop) (gcc version 4.4.1 (Sourcery G++                                    Lite 2010q1-188) ) #29 PREEMPT Mon Sep 6 19:54:09 CEST 2010
CPU: ARMv7 Processor [411fc083] revision 3 (ARMv7), cr=10c53c7f
CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
Machine: PuppyBeagle
Memory policy: ECC disabled, Data cache writeback
<7>On node 0 totalpages: 65536
<7>free_area_init_node: node 0, pgdat c02e0774, node_mem_map c02f7000
<7>  Normal zone: 512 pages used for memmap
<7>  Normal zone: 0 pages reserved
<7>  Normal zone: 65024 pages, LIFO batch:15
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 65024
<5>Kernel command line: console=ttyS2,115200n8 console=tty0 root=/dev/mmcblk0p2                                    rw rootfstype=ext3 rootwait omapfb.video_mode=1024x768MR-16@60
<6>PID hash table entries: 1024 (order: 0, 4096 bytes)
<6>Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
<6>Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
<6>Memory: 128MB 128MB = 256MB total
<5>Memory: 256868k/256868k available, 5276k reserved, 0K highmem
<5>Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    DMA     : 0xffc00000 - 0xffe00000   (   2 MB)
    vmalloc : 0xd0800000 - 0xe0000000   ( 248 MB)
    lowmem  : 0xc0000000 - 0xd0000000   ( 256 MB)
    modules : 0xbf000000 - 0xc0000000   (  16 MB)
      .init : 0xc0008000 - 0xc0021000   ( 100 kB)
      .text : 0xc0021000 - 0xc02b3000   (2632 kB)
      .data : 0xc02cc000 - 0xc02e0d80   (  84 kB)
<6>Hierarchical RCU implementation.
<6>     RCU-based detection of stalled CPUs is disabled.
<6>     Verbose stalled-CPUs detection is disabled.
<6>NR_IRQS:96
Console: colour dummy device 80x30
<6>console [tty0] enabled
<6>Calibrating delay loop... 4023.91 BogoMIPS (lpj=20119552)
<6>pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
<6>CPU: Testing write buffer coherency: ok
<6>NET: Registered protocol family 16
bio: create slab at 0
<6>NET: Registered protocol family 2
<6>IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
<6>TCP established hash table entries: 8192 (order: 4, 65536 bytes)
<6>TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
<6>TCP: Hash tables configured (established 8192 bind 8192)
<6>TCP reno registered
<6>UDP hash table entries: 256 (order: 0, 4096 bytes)
<6>UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
<6>RPC: Registered udp transport module.
<6>RPC: Registered tcp transport module.
<6>RPC: Registered tcp NFSv4.1 backchannel transport module.
<6>JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
<6>msgmni has been set to 501
<6>io scheduler noop registered (default)
<6>Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled
<6>i2c /dev entries driver
<6>TCP cubic registered
<6>Waiting for root device /dev/mmcblk0p2...


Next Steps: Start programming Rootfs  !!!

No comments:

Post a Comment