public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot-Users] possible ELDK4 gcc compiler bug
@ 2006-12-07 16:21 Matthias Fuchs
  2006-12-07 16:28 ` Matthias Fuchs
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Matthias Fuchs @ 2006-12-07 16:21 UTC (permalink / raw)
  To: u-boot

Hi,

I noticed some strange behavior when using the ELDK4 gcc for compiling 
U-Boot for a (new) 405 target based on the current PMC405 board.

The code needs to read-modify-write a memory mapped FPGA internal register.
But the FPGA access does not appear in the object and therefore it is never 
done.

Here are some code snippets:

1) my 'fifo' BSP command:

int do_fifo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	struct pmc405v2_fpga_s *fpga = (struct pmc405v2_fpga_s *)FPGA_BA;
	int i;
	int n = 0;
	u32 ctrl, data, f;
	char str[] = "\\|/-";
	int abort = 0;
	int count = 0;
	int count2 = 0;

	switch(argc) {
	case 2:
		/* completely read out fifo 'n' */
		if (!strcmp(argv[1],"read")) {
			printf("  #   fifo level data\n");
			printf("__________________________________\n");

			for (i=0; i<FIFO_COUNT; i++) {
				dump_fifo(fpga, i, &n);
			}
		} else if (!strcmp(argv[1],"wait")) {
			got_fifoirq = 0;

			irq_install_handler (FPGA_IRQ,
					     (interrupt_handler_t *)fpga_interrupt,
					     (void*)fpga);

			printf("  #   fifo level data\n");
			printf("__________________________________\n");

			fpga->ctrl |= CTRL_FIFO_IE;
			for (i=0; i<FIFO_COUNT; i++) {
				/* enable interrupts from all fifos */
				printf("DEBUG1: %p:%08x\n", 
				       &(fpga->fifo[i].ctrl), fpga->fifo[i].ctrl);
--> These RMW-ops do not appear in the object and is never done!
-->				fpga->fifo[i].ctrl |= 0x8000;
				printf("DEBUG2: %p:%08x\n", 
				       &(fpga->fifo[i].ctrl), fpga->fifo[i].ctrl);
			}

			while (1) {
				/* wait loop */
				while(!got_fifoirq) {
...


2) Here are the used structs for the fpga variable:
struct pmc405v2_fifo_s {
	volatile u32 data;
	volatile u32 ctrl;
};

/* fifo ctrl register */
#define FIFO_OVERFLOW   0x00000400
#define FIFO_EMPTY      0x00000200
#define FIFO_FULL       0x00000100
#define FIFO_IE         0x00008000
#define FIFO_LEVEL_MASK 0x000000ff

#define FIFO_COUNT      4

struct pmc405v2_fpga_s {
	volatile u32 ctrl;
	volatile u32 status;
	volatile u32 test1;
	volatile u32 test2;
	u32 pad1[0x60 / sizeof(u32) - 4];
	volatile u32 hostctrl;                   /* 0x0060 */
	u32 pad2[0x20 / sizeof(u32) - 1];
	struct pmc405v2_fifo_s fifo[FIFO_COUNT]; /* 0x0080..0x009f */
};


3) Here are some lines from the objectdump. I do not find anything from the 
RMW-op to the FPGA register (fpga->fifo[i].ctrl |= 0x8000;).


/data/home/matthias/projects/pmc405/V2_u-boot.git/board/esd/pmc405v2/cmd_pmc405v2.c:556
     dd8:       48 00 00 01     bl      dd8 <do_fifo+0x178>
                        dd8: R_PPC_PLTREL24     printf
/data/home/matthias/projects/pmc405/V2_u-boot.git/board/esd/pmc405v2/cmd_pmc405v2.c:558
     ddc:       3d 20 ef 00     lis     r9,-4352
     de0:       80 09 00 00     lwz     r0,0(r9)
     de4:       3b 40 00 00     li      r26,0
     de8:       60 00 02 00     ori     r0,r0,512
     dec:       90 09 00 00     stw     r0,0(r9)
     df0:       7f 7f db 78     mr      r31,r27
/data/home/matthias/projects/pmc405/V2_u-boot.git/board/esd/pmc405v2/cmd_pmc405v2.c:561
                        for (i=0; i<FIFO_COUNT; i++) {
                                /* enable interrupts from all fifos */
                                printf("DEBUG1: %p:%08x\n",
     df4:       83 9b 00 00     lwz     r28,0(r27)
     df8:       80 7e 80 cc     lwz     r3,-32564(r30)
     dfc:       7f e4 fb 78     mr      r4,r31
     e00:       7f 85 e3 78     mr      r5,r28
     e04:       48 00 00 01     bl      e04 <do_fifo+0x1a4>
                        e04: R_PPC_PLTREL24     printf
/data/home/matthias/projects/pmc405/V2_u-boot.git/board/esd/pmc405v2/cmd_pmc405v2.c:564
                                       &(fpga->fifo[i].ctrl), 
fpga->fifo[i].ctrl);
                                fpga->fifo[i].ctrl |= 0x8000;
                                printf("DEBUG2: %p:%08x\n",
     e08:       80 7e 80 d0     lwz     r3,-32560(r30)
     e0c:       7f e4 fb 78     mr      r4,r31
     e10:       7f 85 e3 78     mr      r5,r28
     e14:       48 00 00 01     bl      e14 <do_fifo+0x1b4>
                        e14: R_PPC_PLTREL24     printf
/data/home/matthias/projects/pmc405/V2_u-boot.git/board/esd/pmc405v2/cmd_pmc405v2.c:559
     e18:       2f 9a 00 03     cmpwi   cr7,r26,3
     e1c:       3b ff 00 08     addi    r31,r31,8
     e20:       3b 7b 00 08     addi    r27,r27,8
     e24:       3b 5a 00 01     addi    r26,r26,1
     e28:       40 9e ff cc     bne+    cr7,df4 <do_fifo+0x194>
     e2c:       3b e0 00 00     li      r31,0
     e30:       48 00 00 6c     b       e9c <do_fifo+0x23c>
/data/home/matthias/projects/pmc405/V2_u-boot.git/board/esd/pmc405v2/cmd_pmc405v2.c:571
                                       &(fpga->fifo[i].ctrl), 
fpga->fifo[i].ctrl);
                        }

                        while (1) {
                                /* wait loop */
                                while(!got_fifoirq) {
                                        count++;
     e34:       3b ff 00 01     addi    r31,r31,1
/data/home/matthias/projects/pmc405/V2_u-boot.git/board/esd/pmc405v2/cmd_pmc405v2.c:572


4) This is how the compiler is called for the code file:
ppc_4xx-gcc -g  -Os   -fPIC -ffixed-r14 -meabi -fno-strict-aliasing -D__KERNEL__ -DTEXT_BASE=0xFFF80000 
-I/data/home/matthias/projects/pmc405/V2_u-boot.git/include -fno-builtin -ffreestanding -nostdinc 
-isystem /opt/eldk_400/usr/bin/../lib/gcc/powerpc-linux/4.0.0/include -pipe  -DCONFIG_PPC -D__powerpc__ 
-DCONFIG_4xx -ffixed-r2 -ffixed-r29 -mstring -Wa,-m405 -mcpu=405 -msoft-float -Wall -Wstrict-prototypes -c -o
cmd_pmc405v2.o cmd_pmc405v2.c


Any idea about what I am doing wrong?

BTW: Using -O0 instead of -Os makes everything fine - at least for the code 
above.

Matthias

-- 
-----------------------------------------------------------------------
Dipl.-Ing. Matthias Fuchs             esd electronic system design gmbh
http://www.esd-electronics.com                    Vahrenwalder Str. 207
phone: +49-511-37298-0, fax: -68                30165 Hannover, Germany
-----------------------------------------------------------------------

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

* [U-Boot-Users] possible ELDK4 gcc compiler bug
  2006-12-07 16:21 [U-Boot-Users] possible ELDK4 gcc compiler bug Matthias Fuchs
@ 2006-12-07 16:28 ` Matthias Fuchs
  2006-12-07 16:38   ` Pantelis Antoniou
  2006-12-07 16:42   ` Rune Torgersen
  2006-12-07 16:29 ` Pantelis Antoniou
  2006-12-07 16:42 ` Tolunay Orkun
  2 siblings, 2 replies; 10+ messages in thread
From: Matthias Fuchs @ 2006-12-07 16:28 UTC (permalink / raw)
  To: u-boot

On Thursday 07 December 2006 17:21, Matthias Fuchs wrote:
> 
> int do_fifo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
> {
> 	struct pmc405v2_fpga_s *fpga = (struct pmc405v2_fpga_s *)FPGA_BA;
Making 'fpga' static solves the problem. But why?

Matthias

-- 
-----------------------------------------------------------------------
Dipl.-Ing. Matthias Fuchs             esd electronic system design gmbh
http://www.esd-electronics.com                    Vahrenwalder Str. 207
phone: +49-511-37298-0, fax: -68                30165 Hannover, Germany
-----------------------------------------------------------------------

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

* [U-Boot-Users] possible ELDK4 gcc compiler bug
  2006-12-07 16:21 [U-Boot-Users] possible ELDK4 gcc compiler bug Matthias Fuchs
  2006-12-07 16:28 ` Matthias Fuchs
@ 2006-12-07 16:29 ` Pantelis Antoniou
  2006-12-07 16:42 ` Tolunay Orkun
  2 siblings, 0 replies; 10+ messages in thread
From: Pantelis Antoniou @ 2006-12-07 16:29 UTC (permalink / raw)
  To: u-boot


On 07 ??? 2006, at 11:21 ??, Matthias Fuchs wrote:

> Hi,
>

[snip]

Declare your struct variable pointer as volatile.

The compiler optimizes all your accesses away.

Even volatile is considered bad form nowadays, the proper one
is using accessors which do the _right_ thing for your specific
hardware.

Regards

Pantelis

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

* [U-Boot-Users] possible ELDK4 gcc compiler bug
  2006-12-07 16:28 ` Matthias Fuchs
@ 2006-12-07 16:38   ` Pantelis Antoniou
  2006-12-07 17:12     ` Matthias Fuchs
  2006-12-07 16:42   ` Rune Torgersen
  1 sibling, 1 reply; 10+ messages in thread
From: Pantelis Antoniou @ 2006-12-07 16:38 UTC (permalink / raw)
  To: u-boot


On 07 ??? 2006, at 11:28 ??, Matthias Fuchs wrote:

> On Thursday 07 December 2006 17:21, Matthias Fuchs wrote:
>>
>> int do_fifo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
>> {
>> 	struct pmc405v2_fpga_s *fpga = (struct pmc405v2_fpga_s *)FPGA_BA;
> Making 'fpga' static solves the problem. But why?
>

You are getting hit by the optimizer, even getting this far was lucky.

Just for kicks, try:

>> volatile struct pmc405v2_fpga_s *fpga = (volatile struct  
>> pmc405v2_fpga_s *)FPGA_BA;

But you should really be using accessors...

Pantelis


> Matthias
>
> -- 
> ---------------------------------------------------------------------- 
> -
> Dipl.-Ing. Matthias Fuchs             esd electronic system design  
> gmbh
> http://www.esd-electronics.com                    Vahrenwalder Str.  
> 207
> phone: +49-511-37298-0, fax: -68                30165 Hannover,  
> Germany
> ---------------------------------------------------------------------- 
> -
>
>
> ---------------------------------------------------------------------- 
> ---
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to  
> share your
> opinions on IT & business topics through brief surveys - and earn cash
> http://www.techsay.com/default.php? 
> page=join.php&p=sourceforge&CID=DEVDEV
> _______________________________________________
> U-Boot-Users mailing list
> U-Boot-Users at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/u-boot-users

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

* [U-Boot-Users] possible ELDK4 gcc compiler bug
  2006-12-07 16:21 [U-Boot-Users] possible ELDK4 gcc compiler bug Matthias Fuchs
  2006-12-07 16:28 ` Matthias Fuchs
  2006-12-07 16:29 ` Pantelis Antoniou
@ 2006-12-07 16:42 ` Tolunay Orkun
  2 siblings, 0 replies; 10+ messages in thread
From: Tolunay Orkun @ 2006-12-07 16:42 UTC (permalink / raw)
  To: u-boot

Matthias Fuchs wrote:
> Hi,
> 
> I noticed some strange behavior when using the ELDK4 gcc for compiling 
> U-Boot for a (new) 405 target based on the current PMC405 board.
> 
> The code needs to read-modify-write a memory mapped FPGA internal register.
> But the FPGA access does not appear in the object and therefore it is never 
> done.
> 
> Here are some code snippets:
> 
> 1) my 'fifo' BSP command:
> 
> int do_fifo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
> {
> 	struct pmc405v2_fpga_s *fpga = (struct pmc405v2_fpga_s *)FPGA_BA;
> 	int i;
> 	int n = 0;

The compiler is optimizing away your code. Check out the 'volatile' 
keyword. It is exactly this situation it was intended. A better way is 
to use in32() out32() etc. The I/O accessors make sure I/O operation is 
completed before next instruction is executed. Simply accessing the 
memory mapped registers might not archive the same.

Best regards,
Tolunay

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

* [U-Boot-Users] possible ELDK4 gcc compiler bug
  2006-12-07 16:28 ` Matthias Fuchs
  2006-12-07 16:38   ` Pantelis Antoniou
@ 2006-12-07 16:42   ` Rune Torgersen
  2006-12-07 16:55     ` Matthias Fuchs
  1 sibling, 1 reply; 10+ messages in thread
From: Rune Torgersen @ 2006-12-07 16:42 UTC (permalink / raw)
  To: u-boot

> -----Original Message-----
> From:  Matthias Fuchs
> *)FPGA_BA;
> Making 'fpga' static solves the problem. But why?
> 

Making it volatile will solve it.

The reason is that the ctrl member is not used anywhere else (except for
some printf's) sothe compiler just strores the value in a register an
optimizes away the access to the datastructure (and your hardware). 
By making it volatile, you force the compiler to never optimize away the
accesses.

BTW. your original code would probably have worked with -O0
optimizattion level.

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

* [U-Boot-Users] possible ELDK4 gcc compiler bug
  2006-12-07 16:42   ` Rune Torgersen
@ 2006-12-07 16:55     ` Matthias Fuchs
  0 siblings, 0 replies; 10+ messages in thread
From: Matthias Fuchs @ 2006-12-07 16:55 UTC (permalink / raw)
  To: u-boot

On Thursday 07 December 2006 17:42, Rune Torgersen wrote:
> > -----Original Message-----
> > From:  Matthias Fuchs
> > *)FPGA_BA;
> > Making 'fpga' static solves the problem. But why?
> > 
> 
> Making it volatile will solve it.
I tried that - of course. But it didn't solve the problem.

> 
> The reason is that the ctrl member is not used anywhere else (except for
> some printf's) sothe compiler just strores the value in a register an
> optimizes away the access to the datastructure (and your hardware). 
> By making it volatile, you force the compiler to never optimize away the
> accesses.
> 
> BTW. your original code would probably have worked with -O0
> optimizattion level.
Yes, it does.

Matthias

-- 
-----------------------------------------------------------------------
Dipl.-Ing. Matthias Fuchs             esd electronic system design gmbh
http://www.esd-electronics.com                    Vahrenwalder Str. 207
phone: +49-511-37298-0, fax: -68                30165 Hannover, Germany
-----------------------------------------------------------------------

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

* [U-Boot-Users] possible ELDK4 gcc compiler bug
  2006-12-07 16:38   ` Pantelis Antoniou
@ 2006-12-07 17:12     ` Matthias Fuchs
  2006-12-07 17:25       ` Timur Tabi
  0 siblings, 1 reply; 10+ messages in thread
From: Matthias Fuchs @ 2006-12-07 17:12 UTC (permalink / raw)
  To: u-boot

On Thursday 07 December 2006 17:38, Pantelis Antoniou wrote:
> 
> But you should really be using accessors...
You might be right, but I really like to lay a struct over a IO-controllers 
registers.

Do so with accessors result in code like this (still missing some casts):

out32(&(fpga->fifo[i].ctrl), in32(&(fpga->fifo[i].ctrl)) | 0x8000);

Is this really recommended?

For simple IO operations 

out32(FPGA_FIFO_CTRL, in32(FPGA_FIFO_CTRL) | 0x8000);

is fine. But with a more complex register layout like this:

struct pmc405v2_fpga_s {
????????volatile u32 ctrl;
????????volatile u32 status;
????????volatile u32 test1;
????????volatile u32 test2;
????????u32 pad1[0x60 / sizeof(u32) - 4];
????????volatile u32 hostctrl; ? ? ? ? ? ? ? ? ? /* 0x0060 */
????????u32 pad2[0x20 / sizeof(u32) - 1];
????????struct pmc405v2_fifo_s fifo[FIFO_COUNT]; /* 0x0080..0x009f */
};

It results in ugly code.

Matthias

-- 
-----------------------------------------------------------------------
Dipl.-Ing. Matthias Fuchs             esd electronic system design gmbh
http://www.esd-electronics.com                    Vahrenwalder Str. 207
phone: +49-511-37298-0, fax: -68                30165 Hannover, Germany
-----------------------------------------------------------------------

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

* [U-Boot-Users] possible ELDK4 gcc compiler bug
  2006-12-07 17:12     ` Matthias Fuchs
@ 2006-12-07 17:25       ` Timur Tabi
  2006-12-07 17:33         ` Pantelis Antoniou
  0 siblings, 1 reply; 10+ messages in thread
From: Timur Tabi @ 2006-12-07 17:25 UTC (permalink / raw)
  To: u-boot

Matthias Fuchs wrote:

> 
> Do so with accessors result in code like this (still missing some casts):
> 
> out32(&(fpga->fifo[i].ctrl), in32(&(fpga->fifo[i].ctrl)) | 0x8000);
> 
> Is this really recommended?

That's how I would do it.  You could use a temporary variable:

u32 ctrl;

ctrl = in32(&(fpga->fifo[i].ctrl));
out32(&(fpga->fifo[i].ctrl), ctrl | 0x8000);

-- 
Timur Tabi
Linux Kernel Developer @ Freescale

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

* [U-Boot-Users] possible ELDK4 gcc compiler bug
  2006-12-07 17:25       ` Timur Tabi
@ 2006-12-07 17:33         ` Pantelis Antoniou
  0 siblings, 0 replies; 10+ messages in thread
From: Pantelis Antoniou @ 2006-12-07 17:33 UTC (permalink / raw)
  To: u-boot


On 07 ??? 2006, at 12:25 ??, Timur Tabi wrote:

> Matthias Fuchs wrote:
>
>> Do so with accessors result in code like this (still missing some  
>> casts):
>> out32(&(fpga->fifo[i].ctrl), in32(&(fpga->fifo[i].ctrl)) | 0x8000);
>> Is this really recommended?
>
> That's how I would do it.  You could use a temporary variable:
>
> u32 ctrl;
>
> ctrl = in32(&(fpga->fifo[i].ctrl));
> out32(&(fpga->fifo[i].ctrl), ctrl | 0x8000);
>
> -- 
> Timur Tabi
> Linux Kernel Developer @ Freescale

#define FPGA_SETBITS(f, m, v) \
	out32(&(f)->m, in32(&(f)->m | (v))


FPGA_SET_BITS(fifo[i].ctrl, 0x8000)

Knock yourself out.

Pantelis

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

end of thread, other threads:[~2006-12-07 17:33 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-07 16:21 [U-Boot-Users] possible ELDK4 gcc compiler bug Matthias Fuchs
2006-12-07 16:28 ` Matthias Fuchs
2006-12-07 16:38   ` Pantelis Antoniou
2006-12-07 17:12     ` Matthias Fuchs
2006-12-07 17:25       ` Timur Tabi
2006-12-07 17:33         ` Pantelis Antoniou
2006-12-07 16:42   ` Rune Torgersen
2006-12-07 16:55     ` Matthias Fuchs
2006-12-07 16:29 ` Pantelis Antoniou
2006-12-07 16:42 ` Tolunay Orkun

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox