Bug 183740 - mutex on some arm hardware requires dcache enabled
Summary: mutex on some arm hardware requires dcache enabled
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-arm (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-11-07 07:10 UTC by john
Modified: 2014-07-26 04:29 UTC (History)
1 user (show)

See Also:


Attachments
file.diff (565 bytes, patch)
2013-11-07 07:10 UTC, john
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description john 2013-11-07 07:10:00 UTC
In my spare time I'm working on bringing FreeBSD up on amlogic based
arm processors.  While working through various bootstrap issues I got
to the point where initarm calls pmap_bootstrap only to have it splat.

What happens is pmap_bootstrap calls pmap_extract which does PMAP_LOCK(pmap).
This trys to acquire a mutex which invokes atomics that use ldrex / strex.

The ARM documentation at:

  http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0464d/CHDIBJGE.html

notes that the L1 memory system has an internal exclusive monitor which
handles ldrex / strex accesses.

The README at:

  https://github.com/dwelch67/raspberrypi/tree/master/extest

has a nice write up which explains some of the wrinkles regarding hardware
and ldrex / strex.

The attached patch enables the dcache and suffices to get me through
initarm into mi_startup (I'm not to a console login yet ... however
I'm significantly further along).

-- John

Fix: Enable the dcache prior to using a mutex.

Patch attached with submission follows:
Comment 1 ganbold 2013-11-07 07:17:23 UTC
John,


On Thu, Nov 7, 2013 at 3:07 PM, John Wehle <john@feith.com> wrote:

>
> >Number:         183740
> >Category:       arm
> >Synopsis:       mutex on some arm hardware requires dcache enabled
> >Confidential:   no
> >Severity:       non-critical
> >Priority:       low
> >Responsible:    freebsd-arm
> >State:          open
> >Quarter:
> >Keywords:
> >Date-Required:
> >Class:          sw-bug
> >Submitter-Id:   current-users
> >Arrival-Date:   Thu Nov 07 07:10:00 UTC 2013
> >Closed-Date:
> >Last-Modified:
> >Originator:     John Wehle
> >Release:        FreeBSD svn 257205
> >Organization:
> Personal
> >Environment:
> Not Yet
> >Description:
> In my spare time I'm working on bringing FreeBSD up on amlogic based
> arm processors.  While working through various bootstrap issues I got
> to the point where initarm calls pmap_bootstrap only to have it splat.
>
> What happens is pmap_bootstrap calls pmap_extract which does
> PMAP_LOCK(pmap).
> This trys to acquire a mutex which invokes atomics that use ldrex / strex.
>
> The ARM documentation at:
>
>
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0464d/CHDIBJGE.html
>
> notes that the L1 memory system has an internal exclusive monitor which
> handles ldrex / strex accesses.
>
> The README at:
>
>   https://github.com/dwelch67/raspberrypi/tree/master/extest
>
> has a nice write up which explains some of the wrinkles regarding hardware
> and ldrex / strex.
>
> The attached patch enables the dcache and suffices to get me through
> initarm into mi_startup (I'm not to a console login yet ... however
> I'm significantly further along).
>
> -- John
>
> >How-To-Repeat:
>
> >Fix:
> Enable the dcache prior to using a mutex.
>
> >
> --- sys/arm/arm/machdep.c.ORIGINAL      2013-10-27 01:15:39.000000000 -0400
> +++ sys/arm/arm/machdep.c       2013-11-07 01:43:01.000000000 -0500
> @@ -1481,6 +1483,12 @@ initarm(struct arm_boot_params *abp)
>          */
>         cpu_idcache_wbinv_all();
>
> +       /*
> +        * Atomics invoked by mutex use ldrex / strex which on some
> +        * hardware requires the L1 cache.
> +        */
> +       cpu_control(CPU_CONTROL_DC_ENABLE, CPU_CONTROL_DC_ENABLE);
> +
>         /* Set stack for exception handlers */
>         data_abort_handler_address = (u_int)data_abort_handler;
>         prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
>
>
What kind of Amlogic board you are working on? That could be interesting.

As for the patch can you try to put it in initarm_late_init() of your board
machdep code and try?
I meant like in /usr/src/sys/arm/rockchip/rk30xx_machdep.c
Please let us know.

thanks,

Ganbold



>
> >Release-Note:
> >Audit-Trail:
> >Unformatted:
> _______________________________________________
> freebsd-arm@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-arm
> To unsubscribe, send any mail to "freebsd-arm-unsubscribe@freebsd.org"
>
Comment 2 john 2013-11-11 06:31:38 UTC
> What kind of Amlogic board you are working on?

I'm currently using a Visson ATV-102 "Android TV Box" which has an
Amlogic aml8726-m3 SoC.  I have it to the point of attempting to
mount the root filesystem so it's probably time for me to write a
driver for the Amlogic MMC hardware.

I also have a Ainol Elf 2 tablet which has an Amlogic aml8726-mx SoC
which I plan to work on next.

Both chips are dual core Arm Cortex A9 processors.

> As for the patch can you try to put it in initarm_late_init() of
> your board machdep code and try?

Yep ... enabling the dcache in initarm_late_init takes care of the
mutex ldrex / strex problem.

-- John
Comment 3 dfilter service freebsd_committer freebsd_triage 2013-11-20 15:53:57 UTC
Author: ian
Date: Wed Nov 20 15:53:50 2013
New Revision: 258392
URL: http://svnweb.freebsd.org/changeset/base/258392

Log:
  Call cpu_setup() immediately after the page tables are installed.  This
  enables data cache and other chip-specific features.  It was previously
  done via an early SYSINIT, but it was being done after pmap and vm setup,
  and those setups need to use mutexes.  On some modern ARM platforms,
  the ldrex/strex instructions that implement mutexes require the data cache
  to be enabled.
  
  A nice side effect of enabling caching earlier is that it eliminates the
  multi-second pause that used to happen early in boot while physical memory
  and pmap and vm were being set up.  On boards with 1 GB or more of ram
  this pause was very noticible, sometimes 5-6 seconds.
  
  PR:		arm/183740

Modified:
  head/sys/arm/arm/machdep.c

Modified: head/sys/arm/arm/machdep.c
==============================================================================
--- head/sys/arm/arm/machdep.c	Wed Nov 20 13:22:22 2013	(r258391)
+++ head/sys/arm/arm/machdep.c	Wed Nov 20 15:53:50 2013	(r258392)
@@ -361,7 +361,6 @@ cpu_startup(void *dummy)
 #endif
 #endif
 
-	cpu_setup("");
 	identify_arm_cpu();
 
 	printf("real memory  = %ju (%ju MB)\n", (uintmax_t)ptoa(physmem),
@@ -1431,6 +1430,12 @@ initarm(struct arm_boot_params *abp)
 	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2));
 
 	/*
+	 * Now that proper page tables are installed, call cpu_setup() to enable
+	 * instruction and data caches and other chip-specific features.
+	 */
+	cpu_setup("");
+
+	/*
 	 * Only after the SOC registers block is mapped we can perform device
 	 * tree fixups, as they may attempt to read parameters from hardware.
 	 */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"