FreeBSD/armv6z/clang on Raspberry Pi 512MB (with U-Boot + ubldr)

Ian Lepore freebsd at damnhippie.dyndns.org
Thu Dec 27 16:11:56 UTC 2012


On Fri, 2012-12-28 at 00:34 +0900, Daisuke Aoyama wrote:
> >>> PTE sync - related part, Im not sure it's strictly required. We use WT 
> >>> caches for page tables
> >>> so we should be OK without implicit sync operations for them. I hope 
> >>> somebody
> >>> more clueful can confirm/disprove this.
> >>
> >> Some digging, I notice "Invalidate Entire Instruction Cache" works 
> >> without segfault.
> >> So, Invalidate D-cache is no effect :)
> >>
> >> It seems following should work for this issue:
> >>
> >>       mov     r0, #0
> >>       mcr     p15, 0, r0, c7, c5, 0           /* Invalidate Entire 
> >> Instruction Cache */
> >>       mcr     p15, 0, r0, c7, c10, 4          /* Data Synchronization 
> >> Barrier */
> (snip)
> >
> > Hmm, I saw problems with i-caches with kernel with WB cache enabled 
> > instead of WT.
> > This patch fixed it for me:
> >
> > http://people.freebsd.org/~gonzo/arm/patches/pmapv6-icache.diff
> > It invalidates i-caches only when new mapping is created, not on every 
> > switch so
> > it should be less taxing on performance.
> >
> > Could you test it on your setup? =
> 
> It does not help. Also both your patch +PTE SYNC and call always WBINV in 
> pmap +PTE SYNC don't help.
> The kernel applied your patch was failed at first "portsnap fetch" step.
> Probably change in pmap is no effect for this segfault.
> 
> Currently, adding invalidate I-cache to swtch.S is only solution.
> My test is:
> 
> 1) ping from other freebsd to RPI.
> 2) login to RPI, then run "top -PHs1" under pi user.
> 3) use simple test (portsnap fetch/extract/build bash) from console.
> 
> Side effect of digging, I found a reason why timer is never fired.
> 
> According to the source, et_min_period.frac set to 2.
> This means the start will be called with 1 (frac - 1).
> So the routine have only 1us(1MHz) to be finished for the request.
> Probably it's impossible even if modern CPU such as 3GHz CPU.
> 
> If failed to setup, it will be fired after 0xffffffff(wrapped about 
> 4294.9sec).
> So, "the interrupt is not fired" is wrong understanding.
> The timer will be fired later. Until this, the world seems to have stopped 
> :)
> 
> This is complete version of systimer patch.
> It should fix stopping interrupt and related things such as USB LAN is 
> unstable,
> SSH is closed suddenly.
> (I've not yet finished all test at this time, but at least portsnap fetch is 
> success.
> Now extracting the ports without any problems.)
> 
> ----------------------------------------------------------------------
> --- bcm2835_systimer.c  (revision 244663)
> +++ bcm2835_systimer.c  (working copy)
> @@ -55,6 +55,7 @@
> 
>  #define        DEFAULT_TIMER           3
>  #define        DEFAULT_FREQUENCY       1000000
> +#define        MIN_PERIOD                 1000LLU
> 
>  #define        SYSTIMER_CS     0x00
>  #define        SYSTIMER_CLO    0x04
> @@ -123,17 +124,20 @@
>         struct systimer *st = et->et_priv;
>         uint32_t clo;
>         uint32_t count;
> +       register_t s;
> 
>         if (first != NULL) {
> -               st->enabled = 1;
> -
>                 count = (st->et.et_frequency * (first->frac >> 32)) >> 32;
>                 if (first->sec != 0)
>                         count += st->et.et_frequency * first->sec;
> 
> +               s = intr_disable();
>                 clo = bcm_systimer_tc_read_4(SYSTIMER_CLO);
>                 clo += count;
>                 bcm_systimer_tc_write_4(SYSTIMER_C0 + st->index*4, clo);
> +               st->enabled = 1;
> +               bcm_systimer_tc_write_4(SYSTIMER_CS, (1 << st->index));
> +               intr_restore(s);
> 
>                 return (0);
>         }
> @@ -154,13 +158,18 @@
>  bcm_systimer_intr(void *arg)
>  {
>         struct systimer *st = (struct systimer *)arg;
> +       uint32_t cs;
> 
> +       cs = bcm_systimer_tc_read_4(SYSTIMER_CS);
> +       if ((cs & (1 << st->index)) == 0)
> +         return (FILTER_STRAY);
> +
>         bcm_systimer_tc_write_4(SYSTIMER_CS, (1 << st->index));
> -       if (st->enabled) {
> +       //if (st->enabled) {
>                 if (st->et.et_active) {
>                         st->et.et_event_cb(&st->et, st->et.et_arg);
>                 }
> -       }
> +       //}
> 
>         return (FILTER_HANDLED);
>  }
> @@ -226,7 +235,7 @@
>         sc->st[DEFAULT_TIMER].et.et_frequency = sc->sysclk_freq;
>         sc->st[DEFAULT_TIMER].et.et_min_period.sec = 0;
>         sc->st[DEFAULT_TIMER].et.et_min_period.frac =
> -           ((0x00000002LLU << 32) / sc->st[DEFAULT_TIMER].et.et_frequency) 
> << 32;
> +           ((MIN_PERIOD << 32) / sc->st[DEFAULT_TIMER].et.et_frequency) << 
> 32;
>         sc->st[DEFAULT_TIMER].et.et_max_period.sec = 0xfffffff0U / 
> sc->st[DEFAULT_TIMER].et.et_frequency;
>         sc->st[DEFAULT_TIMER].et.et_max_period.frac =
>             ((0xfffffffeLLU << 32) / sc->st[DEFAULT_TIMER].et.et_frequency) 
> << 32;
> ----------------------------------------------------------------------
> Thanks.

The thing I don't understand about all this is that I'm not seeing any
of the problems you describe, and I can run this sequence you showed: 

> # rm -rf /var/db/portsnap /usr/ports
> # mkdir /var/db/portsnap
> # portsnap fetch
> # portsnap extract
> # cd /usr/ports/shells/bash
> # make BATCH=y

It works on an SSD drive connected via USB without any errors.  I
noticed your message said to try it with an sdcard, so I'm preparing an
8gb card now to try that with.  But if it fails with sd after working
fine with a USB drive, that would make me suspect the sd-related
drivers.

I don't have any of your patches, I'm just using plain -current @
r244691.  I'm using gcc, not clang.  I probably do need your timer
patch, because I have seen ssh sessions close unexpectedly when the
system is idle.  But I don't seem to be having any problems involving
cache maintence.  I even tested that sequence above a second time while
running lots of other processes -- a make -j3 kernel-toolchain with
other windows running top and vmstat -- just trying to make more process
context switches, trying to provoke problems.

-- Ian




More information about the freebsd-arm mailing list