Hi, all,
On Tue, Sep 1, 2015 at 12:48 AM, Liu Ting ting.liu@freescale.com
wrote:
When trying to use gcc-linaro-4.9 to build u-boot for ls1021atwr (ARM Cortex-A7 MPCore compliant with ARMv7-A architecture), we face
issue.
U-boot hangs at PCI-E.
After tracing the code, the issue is located at the line “*val = readl(addr);”.
u-boot/drivers/pci/pcie_layerscape.c: ls_pcie_read_config():
After Bisecting, we tracked down a gcc commit:
https://git.linaro.org/toolchain/gcc.git/commitdiff/e4f9e85e8152379a
ef 373772b22075539920ffa2?hp=da278625cc33cbbc893cc50c2ac32fca31053ee8 2015-01-23 Jakub Jelinek jakub@redhat.com PR rtl-optimization/63637 PR rtl-optimization/60663
- cse.c (merge_equiv_classes): Set new_elt->cost to MAX_COST ...
It is hard to look at a compiler issue when I can't reproduce the
problem.
You gave good info about the compiler, but you didn't point at u-boot
sources.
i tried git clone http://git.linaro.org/boot/u-boot-linaro-stable.git but there is no pcie_layerscape.c file.
[Liu Ting-B28495] this is a file added for fsl ls1021atwr board. you can find it at: http://git.freescale.com/git/cgit.cgi/ppc/sdk/u- boot.git/tree/drivers/pci/pcie_layerscape.c
The problem fixed by the patch can be seen here https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63637 A description of the patch can be found in the submission email here: https://gcc.gnu.org/ml/gcc-patches/2015-01/msg00894.html There are testcases in the patch that show what it does.
The patch allows the compiler to optimize away redundant extended asm statements via common subexpression elimination (CSE), when the asm statements aren't volatile, don't have multiple outputs, and don't
have memory clobbers.
If this is breaking your code, then it appears that you are missing a volatile declaration or extended asm memory clobber somewhere. I don't have the code to look at, so I can't suggest what might be
wrong with the code. [Liu Ting-B28495] thanks for your hint. It is very helpful. BTW, we reverted below changes, then the issue disappeared:-)
/* Also do not record result of a non-volatile inline asm with
more than one result or with clobbers, we do not want CSE to
break the inline asm apart. */ else if (GET_CODE (src) == ASM_OPERANDS && GET_CODE (x) == PARALLEL)
sets[i].src_volatile = 1;
{
/* Do not record result of a non-volatile inline asm with
more than one result. */
if (n_sets > 1)
sets[i].src_volatile = 1;
int j, lim = XVECLEN (x, 0);
for (j = 0; j < lim; j++)
{
rtx y = XVECEXP (x, 0, j);
/* And do not record result of a non-volatile inline asm
with "memory" clobber. */
if (GET_CODE (y) == CLOBBER && MEM_P (XEXP (y, 0)))
{
sets[i].src_volatile = 1;
break;
}
}
}
[Alison Wang] After checking the code in u-boot, I found volatile is missing when reading SCTLR register. As volatile is missing when reading SCTLR register and SCTLR is set according to the value read from SCTLR, it causes CR_M bit is not set. Then MMU is not enabled, the access to VA for PCIE fails.
I have sent a patch to upstream to fix this issue. http://patchwork.ozlabs.org/patch/515666/
Thanks a lot for your support.
Best Regards, Alison Wang