[U-Boot] oamp3: bug in clock.c with gcc 4.5.1?

Alexander Holler holler at ahsoftware.de
Fri Dec 17 15:01:03 CET 2010


Hello,

I think I've nailed down, why an u-boot compiled with gcc 4.5.1 fails 
here. Compiling arch/arm/cpu/armv7/omap3/clock.c with

gcc  -g  -Os   -fno-common -ffixed-r8 -msoft-float   -D__KERNEL__ 
-DCONFIG_SYS_TEXT_BASE=0x80008000 -I/usr/src/u-boot/include -fno-builtin 
-ffreestanding -nostdinc -isystem 
/usr/lib/gcc/armv7a-unknown-linux-gnueabi/4.5.1/include -pipe 
-DCONFIG_ARM -D__ARM__ -marm  -mabi=aapcs-linux -mno-thumb-interwork 
-march=armv5 -Wall -Wstrict-prototypes -fno-stack-protector -gstabs+ 
-Wa,-ahldn -c clock.c >clock.s

the following code will be build for get_osc_clk_speed():

--------------
  37:clock.c       **** 
/****************************************************************************** 

   38:clock.c       ****  * get_sys_clk_speed() - determine reference 
oscillator speed 

   39:clock.c       ****  *                       based on known 32kHz 
clock and gptimer. 

   40:clock.c       **** 
*****************************************************************************/ 

   41:clock.c       **** u32 get_osc_clk_speed(void) 
 

   42:clock.c       **** {
  277                    .LM0:
  278                    .LFBB1:
  279
  280
  281
   43:clock.c       ****         u32 start, cstart, cend, cdiff, cdiv, val;
   44:clock.c       ****         struct prcm *prcm_base = (struct prcm 
*)PRCM_BASE;
   45:clock.c       ****         struct prm *prm_base = (struct prm 
*)PRM_BASE;
   46:clock.c       ****         struct gptimer *gpt1_base = (struct 
gptimer *)OMAP34XX_GPT1;
   47:clock.c       ****         struct s32ktimer *s32k_base = (struct 
s32ktimer *)SYNC_32KTIMER_BASE;
   48:clock.c       ****
   49:clock.c       ****         val = readl(&prm_base->clksrc_ctrl);
   50:clock.c       ****
   51:clock.c       ****         if (val & SYSCLKDIV_2)
   52:clock.c       ****                 cdiv = 2;
   53:clock.c       ****         else
   54:clock.c       ****                 cdiv = 1;
   55:clock.c       ****
   56:clock.c       ****         /* enable timer2 */
   57:clock.c       ****         val = readl(&prcm_base->clksel_wkup) | 
CLKSEL_GPT1;
  283                    .LM1:
  284 0000 70309FE5      ldr r3,.L7
  285 0004 002093E5      ldr r2,[r3,#0]
  286 0008 012082E3      orr r2,r2,#1
   58:clock.c       ****
   59:clock.c       ****         /* select sys_clk for GPT1 */
   60:clock.c       ****         writel(val, &prcm_base->clksel_wkup);
  288                    .LM2:
  289 000c 002083E5      str r2,[r3,#0]
   61:clock.c       ****
   62:clock.c       ****         /* Enable I and F Clocks for GPT1 */
   63:clock.c       ****         val = readl(&prcm_base->iclken_wkup) | 
EN_GPT1 | EN_32KSYNC;
  291                    .LM3:
  292 0010 303043E2      sub r3,r3,#48
  293 0014 002093E5      ldr r2,[r3,#0]
  294 0018 052082E3      orr r2,r2,#5
   64:clock.c       ****         writel(val, &prcm_base->iclken_wkup);
  296                    .LM4:
  297 001c 002083E5      str r2,[r3,#0]
   65:clock.c       ****
   66:clock.c       ****         val = readl(&prcm_base->fclken_wkup) | 
EN_GPT1;
  299                    .LM5:
  300 0020 103043E2      sub r3,r3,#16
  301 0024 002093E5      ldr r2,[r3,#0]
  302 0028 012082E3      orr r2,r2,#1
   67:clock.c       ****         writel(val, &prcm_base->fclken_wkup);
  304                    .LM6:
  305 002c 002083E5      str r2,[r3,#0]
   68:clock.c       ****
   69:clock.c       ****         writel(0, &gpt1_base->tldr); 
  /* start counting at 0 */
  307                    .LM7:
  308 0030 44309FE5      ldr r3,.L7+4
  309 0034 0020A0E3      mov r2,#0
  310 0038 002083E5      str r2,[r3,#0]
   70:clock.c       ****         writel(GPT_EN, &gpt1_base->tclr); 
  /* enable clock */
  312                    .LM8:
  313 003c 032082E2      add r2,r2,#3
  314 0040 083043E2      sub r3,r3,#8
  315 0044 002083E5      str r2,[r3,#0]
   71:clock.c       ****
   72:clock.c       ****         /* enable 32kHz source, determine 
sys_clk via gauging */
   73:clock.c       ****
   74:clock.c       ****         /* start time in 20 cycles */
   75:clock.c       ****         start = 20 + readl(&s32k_base->s32k_cr);
  317                    .LM9:
  318 0048 30309FE5      ldr r3,.L7+8
  319 004c 002093E5      ldr r2,[r3,#0]
  320 0050 142082E2      add r2,r2,#20
  321                    .L2:
   76:clock.c       ****
   77:clock.c       ****         /* dead loop till start time */
   78:clock.c       ****         while (readl(&s32k_base->s32k_cr) < start);
  323                    .LM10:
  324 0054 001093E5      ldr r1,[r3,#0]
  325 0058 020051E1      cmp r1,r2
  326 005c FCFFFF3A      bcc .L2
   79:clock.c       ****
   80:clock.c       ****         /* get start sys_clk count */
   81:clock.c       ****         cstart = readl(&gpt1_base->tcrr);
   82:clock.c       ****
   83:clock.c       ****         /* wait for 40 cycles */
   84:clock.c       ****         while (readl(&s32k_base->s32k_cr) < 
(start + 20)) ;
  328                    .LM11:
  329 0060 142082E2      add r2,r2,#20
  330                    .L4:
  331 0064 001093E5      ldr r1,[r3,#0]
  332 0068 020051E1      cmp r1,r2
  333 006c FCFFFF3A      bcc .L4
   85:clock.c       ****         cend = readl(&gpt1_base->tcrr); 
  /* get end sys_clk count */
   86:clock.c       ****         cdiff = cend - cstart; 
  /* get elapsed ticks */
   87:clock.c       ****         cdiff *= cdiv;
   88:clock.c       ****
   89:clock.c       ****         /* based on number of ticks assign speed */
   90:clock.c       ****         if (cdiff > 19000)
   91:clock.c       ****                 return S38_4M;
   92:clock.c       ****         else if (cdiff > 15200)
   93:clock.c       ****                 return S26M;
   94:clock.c       ****         else if (cdiff > 13000)
   95:clock.c       ****                 return S24M;
   96:clock.c       ****         else if (cdiff > 9000)
   97:clock.c       ****                 return S19_2M;
   98:clock.c       ****         else if (cdiff > 7600)
   99:clock.c       ****                 return S13M;
  100:clock.c       ****         else
  101:clock.c       ****                 return S12M;
  102:clock.c       **** }
  335                    .LM12:
  336 0070 0C009FE5      ldr r0,.L7+12
  337 0074 1EFF2FE1      bx lr
  338                    .L8:
  339                    .align 2
  340                    .L7:
  341 0078 404C0048      .word 1207979072
  342 007c 2C803148      .word 1211203628
  343 0080 10003248      .word 1211236368
  344 0084 001BB700      .word 12000000
  349                    .Lscope1:
  351                    .stabd 78,0,0
  352                    .align 2
  356                    .global get_sys_clkin_sel
  358                    get_sys_clkin_sel:
  359                    .stabd 46,0,0
  103:clock.c       ****
  104:clock.c       **** 
/******************************************************************************
  105:clock.c       ****  * get_sys_clkin_sel() - returns the 
sys_clkin_sel field value based on
  106:clock.c       ****  *                       input oscillator clock 
frequency.
  107:clock.c       **** 
*****************************************************************************/
  108:clock.c       **** void get_sys_clkin_sel(u32 osc_clk, u32 
*sys_clkin_sel)
  --------------

That means get_sys_clk_speed() will allways return S12M, at least that 
is what I'm reading here. And I don't see why gcc should be allowed to 
optimize that cdiff to a fixed value and therefor returning only S12M.

Any comments on that?

Regards,

Alexander


More information about the U-Boot mailing list