Patchwork [U-Boot,1/3] ARM: implement some Cortex-A9 errata workarounds

login
register
mail settings
Submitter Stephen Warren
Date Feb. 26, 2013, 10:28 p.m.
Message ID <1361917709-11536-1-git-send-email-swarren@wwwdotorg.org>
Download mbox | patch
Permalink /patch/223419/
State Accepted
Delegated to: Albert ARIBAUD
Headers show

Comments

Stephen Warren - Feb. 26, 2013, 10:28 p.m.
From: Stephen Warren <swarren@nvidia.com>

Various errata exist in the Cortex-A9 CPU, and may be worked around by
setting some bits in a CP15 diagnostic register. Add code to implement
the workarounds, enabled by new CONFIG_ options.

This code was taken from the Linux kernel, v3.8, arch/arm/mm/proc-v7.S,
and modified to remove the logic to conditionally apply the WAR (since we
know exactly which CPU we're running on given the U-Boot configuration),
and use r0 instead of r10 for consistency with the rest of U-Boot's
cpu_init_cp15().

Signed-off-by: Stephen Warren <swarren@nvidia.com>
---
 README                     |   10 ++++++++++
 arch/arm/cpu/armv7/start.S |   19 +++++++++++++++++++
 2 files changed, 29 insertions(+)
Simon Glass - Feb. 28, 2013, 12:30 a.m.
On Tue, Feb 26, 2013 at 2:28 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> From: Stephen Warren <swarren@nvidia.com>
>
> Various errata exist in the Cortex-A9 CPU, and may be worked around by
> setting some bits in a CP15 diagnostic register. Add code to implement
> the workarounds, enabled by new CONFIG_ options.
>
> This code was taken from the Linux kernel, v3.8, arch/arm/mm/proc-v7.S,
> and modified to remove the logic to conditionally apply the WAR (since we
> know exactly which CPU we're running on given the U-Boot configuration),
> and use r0 instead of r10 for consistency with the rest of U-Boot's
> cpu_init_cp15().
>
> Signed-off-by: Stephen Warren <swarren@nvidia.com>

Acked-by: Simon Glass <sjg@chromium.org>

Good to have. Although I wonder why we wouldn't want to probe it in
U-Boot as with Linux?

> ---
>  README                     |   10 ++++++++++
>  arch/arm/cpu/armv7/start.S |   19 +++++++++++++++++++
>  2 files changed, 29 insertions(+)
>
> diff --git a/README b/README
> index d8cb394..f2b1c88 100644
> --- a/README
> +++ b/README
> @@ -485,6 +485,16 @@ The following options need to be configured:
>                 Thumb2 this flag will result in Thumb2 code generated by
>                 GCC.
>
> +               CONFIG_ARM_ERRATA_742230
> +               CONFIG_ARM_ERRATA_743622
> +               CONFIG_ARM_ERRATA_751472
> +
> +               If set, the workarounds for these ARM errata are applied early
> +               during U-Boot startup. Note that these options force the
> +               workarounds to be applied; no CPU-type/version detection
> +               exists, unlike the similar options in the Linux kernel. Do not
> +               set these options unless they apply!
> +
>  - Linux Kernel Interface:
>                 CONFIG_CLOCKS_IN_MHZ
>
> diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
> index 6b59529d..30f02d3 100644
> --- a/arch/arm/cpu/armv7/start.S
> +++ b/arch/arm/cpu/armv7/start.S
> @@ -309,6 +309,25 @@ ENTRY(cpu_init_cp15)
>         orr     r0, r0, #0x00001000     @ set bit 12 (I) I-cache
>  #endif
>         mcr     p15, 0, r0, c1, c0, 0
> +
> +#ifdef CONFIG_ARM_ERRATA_742230
> +       mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
> +       orr     r0, r0, #1 << 4         @ set bit #4
> +       mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
> +#endif
> +
> +#ifdef CONFIG_ARM_ERRATA_743622
> +       mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
> +       orr     r0, r0, #1 << 6         @ set bit #6
> +       mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
> +#endif
> +
> +#ifdef CONFIG_ARM_ERRATA_751472
> +       mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
> +       orr     r0, r0, #1 << 11        @ set bit #11
> +       mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
> +#endif
> +
>         mov     pc, lr                  @ back to my caller
>  ENDPROC(cpu_init_cp15)
>
> --
> 1.7.10.4
>
Stephen Warren - Feb. 28, 2013, 12:36 a.m.
On 02/27/2013 05:30 PM, Simon Glass wrote:
> On Tue, Feb 26, 2013 at 2:28 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> From: Stephen Warren <swarren@nvidia.com>
>>
>> Various errata exist in the Cortex-A9 CPU, and may be worked around by
>> setting some bits in a CP15 diagnostic register. Add code to implement
>> the workarounds, enabled by new CONFIG_ options.
>>
>> This code was taken from the Linux kernel, v3.8, arch/arm/mm/proc-v7.S,
>> and modified to remove the logic to conditionally apply the WAR (since we
>> know exactly which CPU we're running on given the U-Boot configuration),
>> and use r0 instead of r10 for consistency with the rest of U-Boot's
>> cpu_init_cp15().
>>
>> Signed-off-by: Stephen Warren <swarren@nvidia.com>
> 
> Acked-by: Simon Glass <sjg@chromium.org>
> 
> Good to have. Although I wonder why we wouldn't want to probe it in
> U-Boot as with Linux?

I figured it wasn't worth the complexity initially. Right now, U-Boot is
built for a specific board (or just perhaps a small set of almost
identical boards), so we know exactly which CPU rev is present. If this
becomes false (e.g. DT works so well we can do a combined
Tegra20+Tegra30 U-Boot), we can always add the conditional logic in when
we need it.
Simon Glass - Feb. 28, 2013, 12:38 a.m.
HI Stephen,

On Wed, Feb 27, 2013 at 4:36 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 02/27/2013 05:30 PM, Simon Glass wrote:
>> On Tue, Feb 26, 2013 at 2:28 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>>> From: Stephen Warren <swarren@nvidia.com>
>>>
>>> Various errata exist in the Cortex-A9 CPU, and may be worked around by
>>> setting some bits in a CP15 diagnostic register. Add code to implement
>>> the workarounds, enabled by new CONFIG_ options.
>>>
>>> This code was taken from the Linux kernel, v3.8, arch/arm/mm/proc-v7.S,
>>> and modified to remove the logic to conditionally apply the WAR (since we
>>> know exactly which CPU we're running on given the U-Boot configuration),
>>> and use r0 instead of r10 for consistency with the rest of U-Boot's
>>> cpu_init_cp15().
>>>
>>> Signed-off-by: Stephen Warren <swarren@nvidia.com>
>>
>> Acked-by: Simon Glass <sjg@chromium.org>
>>
>> Good to have. Although I wonder why we wouldn't want to probe it in
>> U-Boot as with Linux?
>
> I figured it wasn't worth the complexity initially. Right now, U-Boot is
> built for a specific board (or just perhaps a small set of almost
> identical boards), so we know exactly which CPU rev is present. If this
> becomes false (e.g. DT works so well we can do a combined
> Tegra20+Tegra30 U-Boot), we can always add the conditional logic in when
> we need it.

Fair enough, thank you.

Regards,
Simon
Stephen Warren - Feb. 28, 2013, 5:08 p.m.
On 02/26/2013 03:28 PM, Stephen Warren wrote:
> From: Stephen Warren <swarren@nvidia.com>
> 
> Various errata exist in the Cortex-A9 CPU, and may be worked around by
> setting some bits in a CP15 diagnostic register. Add code to implement
> the workarounds, enabled by new CONFIG_ options.
> 
> This code was taken from the Linux kernel, v3.8, arch/arm/mm/proc-v7.S,
> and modified to remove the logic to conditionally apply the WAR (since we
> know exactly which CPU we're running on given the U-Boot configuration),
> and use r0 instead of r10 for consistency with the rest of U-Boot's
> cpu_init_cp15().

Hmmm. Lets hold off on this series; there are some conditions under
which the kernel has to be able to apply these WARs anyway (e.g. SMP CPU
power saving), which may impact which of the WARs the bootloader should
apply even when booting the initial CPU 0. I'll repost once that's been
resolved.
Stephen Warren - March 1, 2013, 9:53 p.m.
On 02/28/2013 10:08 AM, Stephen Warren wrote:
> On 02/26/2013 03:28 PM, Stephen Warren wrote:
>> From: Stephen Warren <swarren@nvidia.com>
>>
>> Various errata exist in the Cortex-A9 CPU, and may be worked around by
>> setting some bits in a CP15 diagnostic register. Add code to implement
>> the workarounds, enabled by new CONFIG_ options.
>>
>> This code was taken from the Linux kernel, v3.8, arch/arm/mm/proc-v7.S,
>> and modified to remove the logic to conditionally apply the WAR (since we
>> know exactly which CPU we're running on given the U-Boot configuration),
>> and use r0 instead of r10 for consistency with the rest of U-Boot's
>> cpu_init_cp15().
> 
> Hmmm. Lets hold off on this series; there are some conditions under
> which the kernel has to be able to apply these WARs anyway (e.g. SMP CPU
> power saving), which may impact which of the WARs the bootloader should
> apply even when booting the initial CPU 0. I'll repost once that's been
> resolved.

Tom,

It looks like the bootloader should always apply these WARs for CPU 0.
We just have to make sure that the kernel applies them for CPUs 1..n
if/when running in secure mode.

In other words, I think these patches are good to go in as-is. Since
there are no changes to the patches, I won't repost them, unless you
need me to.
Albert ARIBAUD - March 4, 2013, 6 p.m.
Hi Tom,

On Mon, 4 Mar 2013 08:30:11 -0800, Tom Warren <TWarren@nvidia.com>
wrote:

> Stephen & Albert,
> 
> > -----Original Message-----
> > From: Stephen Warren [mailto:swarren@wwwdotorg.org]
> > Sent: Friday, March 01, 2013 2:54 PM
> > To: Tom Warren
> > Cc: u-boot@lists.denx.de; Stephen Warren
> > Subject: Re: [U-Boot] [PATCH 1/3] ARM: implement some Cortex-A9 errata
> > workarounds
> > 
> > On 02/28/2013 10:08 AM, Stephen Warren wrote:
> > > On 02/26/2013 03:28 PM, Stephen Warren wrote:
> > >> From: Stephen Warren <swarren@nvidia.com>
> > >>
> > >> Various errata exist in the Cortex-A9 CPU, and may be worked around
> > >> by setting some bits in a CP15 diagnostic register. Add code to
> > >> implement the workarounds, enabled by new CONFIG_ options.
> > >>
> > >> This code was taken from the Linux kernel, v3.8,
> > >> arch/arm/mm/proc-v7.S, and modified to remove the logic to
> > >> conditionally apply the WAR (since we know exactly which CPU we're
> > >> running on given the U-Boot configuration), and use r0 instead of r10
> > >> for consistency with the rest of U-Boot's cpu_init_cp15().
> > >
> > > Hmmm. Lets hold off on this series; there are some conditions under
> > > which the kernel has to be able to apply these WARs anyway (e.g. SMP
> > > CPU power saving), which may impact which of the WARs the bootloader
> > > should apply even when booting the initial CPU 0. I'll repost once
> > > that's been resolved.
> > 
> > Tom,
> > 
> > It looks like the bootloader should always apply these WARs for CPU 0.
> > We just have to make sure that the kernel applies them for CPUs 1..n if/when
> > running in secure mode.
> > 
> > In other words, I think these patches are good to go in as-is. Since there
> > are no changes to the patches, I won't repost them, unless you need me to.
> 
> I can take these in via the Tegra tree, but the bulk of the changes are for ARM, not Tegra.
> Albert - do you want to take this directly into the ARM repo, or would you prefer me to take it?

I will take them in tonight.

> Tom
> --
> nvpublic

Amicalement,
Albert ARIBAUD - March 15, 2013, 5:58 a.m.
Hi Stephen,

On Tue, 26 Feb 2013 15:28:27 -0700, Stephen Warren
<swarren@wwwdotorg.org> wrote:

> From: Stephen Warren <swarren@nvidia.com>
> 
> Various errata exist in the Cortex-A9 CPU, and may be worked around by
> setting some bits in a CP15 diagnostic register. Add code to implement
> the workarounds, enabled by new CONFIG_ options.
> 
> This code was taken from the Linux kernel, v3.8, arch/arm/mm/proc-v7.S,
> and modified to remove the logic to conditionally apply the WAR (since we
> know exactly which CPU we're running on given the U-Boot configuration),
> and use r0 instead of r10 for consistency with the rest of U-Boot's
> cpu_init_cp15().
> 
> Signed-off-by: Stephen Warren <swarren@nvidia.com>
> ---
>  README                     |   10 ++++++++++
>  arch/arm/cpu/armv7/start.S |   19 +++++++++++++++++++
>  2 files changed, 29 insertions(+)
> 
> diff --git a/README b/README
> index d8cb394..f2b1c88 100644
> --- a/README
> +++ b/README
> @@ -485,6 +485,16 @@ The following options need to be configured:
>  		Thumb2 this flag will result in Thumb2 code generated by
>  		GCC.
>  
> +		CONFIG_ARM_ERRATA_742230
> +		CONFIG_ARM_ERRATA_743622
> +		CONFIG_ARM_ERRATA_751472
> +
> +		If set, the workarounds for these ARM errata are applied early
> +		during U-Boot startup. Note that these options force the
> +		workarounds to be applied; no CPU-type/version detection
> +		exists, unlike the similar options in the Linux kernel. Do not
> +		set these options unless they apply!
> +
>  - Linux Kernel Interface:
>  		CONFIG_CLOCKS_IN_MHZ
>  
> diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
> index 6b59529d..30f02d3 100644
> --- a/arch/arm/cpu/armv7/start.S
> +++ b/arch/arm/cpu/armv7/start.S
> @@ -309,6 +309,25 @@ ENTRY(cpu_init_cp15)
>  	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-cache
>  #endif
>  	mcr	p15, 0, r0, c1, c0, 0
> +
> +#ifdef CONFIG_ARM_ERRATA_742230
> +	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
> +	orr	r0, r0, #1 << 4		@ set bit #4
> +	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
> +#endif
> +
> +#ifdef CONFIG_ARM_ERRATA_743622
> +	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
> +	orr	r0, r0, #1 << 6		@ set bit #6
> +	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
> +#endif
> +
> +#ifdef CONFIG_ARM_ERRATA_751472
> +	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
> +	orr	r0, r0, #1 << 11	@ set bit #11
> +	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
> +#endif
> +
>  	mov	pc, lr			@ back to my caller
>  ENDPROC(cpu_init_cp15)
>  

Applied to u-boot-arm/master, thanks!

Amicalement,

Patch

diff --git a/README b/README
index d8cb394..f2b1c88 100644
--- a/README
+++ b/README
@@ -485,6 +485,16 @@  The following options need to be configured:
 		Thumb2 this flag will result in Thumb2 code generated by
 		GCC.
 
+		CONFIG_ARM_ERRATA_742230
+		CONFIG_ARM_ERRATA_743622
+		CONFIG_ARM_ERRATA_751472
+
+		If set, the workarounds for these ARM errata are applied early
+		during U-Boot startup. Note that these options force the
+		workarounds to be applied; no CPU-type/version detection
+		exists, unlike the similar options in the Linux kernel. Do not
+		set these options unless they apply!
+
 - Linux Kernel Interface:
 		CONFIG_CLOCKS_IN_MHZ
 
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 6b59529d..30f02d3 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -309,6 +309,25 @@  ENTRY(cpu_init_cp15)
 	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-cache
 #endif
 	mcr	p15, 0, r0, c1, c0, 0
+
+#ifdef CONFIG_ARM_ERRATA_742230
+	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
+	orr	r0, r0, #1 << 4		@ set bit #4
+	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_743622
+	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
+	orr	r0, r0, #1 << 6		@ set bit #6
+	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
+#endif
+
+#ifdef CONFIG_ARM_ERRATA_751472
+	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
+	orr	r0, r0, #1 << 11	@ set bit #11
+	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
+#endif
+
 	mov	pc, lr			@ back to my caller
 ENDPROC(cpu_init_cp15)