Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Dec 2012 01:43:47 +0900
From:      "Daisuke Aoyama" <aoyama@peach.ne.jp>
To:        "Ian Lepore" <freebsd@damnhippie.dyndns.org>
Cc:        freebsd-arm@freebsd.org
Subject:   Re: FreeBSD/armv6z/clang on Raspberry Pi 512MB (with U-Boot + ubldr)
Message-ID:  <234E1E18AC1C4A3985D6C570F78698E6@ad.peach.ne.jp>
In-Reply-To: <1356624694.1144.67.camel@revolution.hippie.lan>
References:  <B5F827FF91C94FF2AFEE00194A2BB2C5@ad.peach.ne.jp> <B508111FCE534B2CBA61F4D1EC1078D3@ad.peach.ne.jp> <E42823D3-D405-40E7-B4CF-75DC947AC119@bluezbox.com> <2BA73CBF02B04DD19D08CDFC556B8750@ad.peach.ne.jp> <BE93F553-E060-45E5-90FE-39AAD1325BAB@bluezbox.com> <F384770FEB784C67BC89AFF7CF57E96C@ad.peach.ne.jp> <1356624694.1144.67.camel@revolution.hippie.lan>

next in thread | previous in thread | raw e-mail | index | archive | help
>> >>> 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.

Thank you for a comment.
Probably it may be clang issue. I didn't check with gcc.

> 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.

Now I have uploaded the patch contains the systimer patch.
Please take the part of this patch if you are interested in.
http://www.peach.ne.jp/archives/rpi/patch/src-244663-20121228.patch.gz

For clang user, this pre-build version can be used:
http://www.peach.ne.jp/archives/rpi/test/kernel-20121228.gz

Thanks.
-- 
Daisuke Aoyama
 




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?234E1E18AC1C4A3985D6C570F78698E6>