leon3 broken for hello
Daniel Hellstrom
daniel at gaisler.com
Fri Feb 21 10:10:24 UTC 2014
Hello,
The problem is that the wrong timer is allocated. In the following code the second GPTIMER core is searched for (idx=1), which most LEON systems don't have. The standard configuration is that the LEON
chip has one GPTIMER core with multiple timer units within that GPTIMER core, what we should do is to use the second timer of the first GPTIMER core instead.
It is safe to assume that there is always two timer instances with the first GPTIMER. If we need a third timer, I think it would be better that it is not an critical error if the hardware is not
present, or that the driver is selectable from project configuration for hardware that supports multiple timers.
The only case I can think of that have multiple GPTIMER instances is NGMP, that reason for that is to be able to support ASMP easier by letting each OS instance have one GPTIMER core itself.
On the GR712RC this code will also fail, this is not because the GR712RC miss a second timer core. But, because the second timer core is a GRTIMER which has a different PnP ID.
+void leon3_cpu_counter_initialize(void)
+{
+ struct ambapp_dev *adev;
+ int idx = 1;
+ volatile struct gptimer_regs *gpt;
+ unsigned new_prescaler = 8;
+ unsigned prescaler;
+ uint32_t frequency;
+
+ adev = (void *) ambapp_for_each(
+ &ambapp_plb,
+ OPTIONS_ALL | OPTIONS_APB_SLVS,
+ VENDOR_GAISLER,
+ GAISLER_GPTIMER,
+ ambapp_find_by_idx,
+ &idx
+ );
+ if (adev == NULL) {
+ rtems_fatal(RTEMS_FATAL_SOURCE_BSP_SPECIFIC, LEON3_FATAL_CPU_COUNTER_INIT);
+ }
Sebastian, what is the problem of using the System Clock timer GPTIMER[0].timer0. It is never stopped right? So basically it is running all the time and reading it would not cause the any conflict
with the Clock Driver. _CPU_Counter_read() does not take into account the underflow of the timer, is this accepted by the caller? Is 1MHz to slow? Will there be a rounding problem with the (prescaler
/ new_prescaler) calculation? The prescaler is always initialized to a value of number of MHz the system clock is running at, which means that LEON is limited to running at a frequency of a multiple
of 1MHz, but the prescaler does not have to be a multiple of 8.
Best Regards,
Daniel Hellstrom
Software Section Head
Aeroflex Gaisler AB
Aeroflex Microelectronic Solutions – HiRel
Kungsgatan 12
SE-411 19 Gothenburg, Sweden
Phone: +46 31 7758657
daniel at gaisler.com
www.Aeroflex.com/Gaisler
On 02/19/2014 06:17 PM, Joel Sherrill wrote:
> OK.. On tsim-leon3, the BSP fails to find the GP_TIMER as best I
> can tell:
>
> (gdb) bt
> #0 _Internal_error_Occurred (
> the_source=the_source at entry=RTEMS_FATAL_SOURCE_BSP,
> is_internal=is_internal at entry=false, the_error=the_error at entry=512)
> at ../../../../../../rtems/c/src/../../cpukit/score/src/interr.c:36
> #1 0x400076f4 in rtems_fatal (source=source at entry=RTEMS_FATAL_SOURCE_BSP,
> error=error at entry=512)
> at ../../../../../../rtems/c/src/../../cpukit/sapi/src/fatal2.c:34
> #2 0x400018a8 in bsp_fatal (code=LEON3_FATAL_CPU_COUNTER_INIT)
> at ../../../../../.././leon3/lib/include/bsp/fatal.h:108
> #3 leon3_cpu_counter_initialize ()
> at
> ../../../../../../../../rtems/c/src/lib/libbsp/sparc/leon3/startup/cpucounter.c:41
>
> Tsim is documented to include a GPTIMER unit with two timers. I have no idea
> why this is failing now since it should be there.
>
> cc'ing Daniel so he can provide some feedback.
>
> --joel
>
>
> On 2/19/2014 3:24 AM, Sebastian Huber wrote:
>> On 2014-02-19 08:48, Sebastian Huber wrote:
>>> Hello Joel,
>>>
>>> since you don't provide much information (e.g. at least a stack trace would
>>> have been helpful) I can only guess. You probably configured only one
>>> GPTIMER instance in the simulators. Since the LEON processors lacks a
>>> free-running CPU counter I had to use a second GPTIMER instance for this.
>>>
>>> You should end up in _Internal_error_Occurred() with the_source ==
>>> RTEMS_FATAL_SOURCE_BSP_SPECIFIC. Now you can look at the <bsp.h> of the
>>> LEON3 BSP and find this:
>>>
>>> typedef enum { LEON3_FATAL_CPU_COUNTER_INIT } leon3_fatal_code;
>>>
>>> If you search for LEON3_FATAL_CPU_COUNTER_INIT you will find this:
>>>
>>> adev = (void *) ambapp_for_each( &ambapp_plb, OPTIONS_ALL |
>>> OPTIONS_APB_SLVS, VENDOR_GAISLER, GAISLER_GPTIMER, ambapp_find_by_idx, &idx
>>> ); if (adev == NULL) { rtems_fatal(RTEMS_FATAL_SOURCE_BSP_SPECIFIC,
>>> LEON3_FATAL_CPU_COUNTER_INIT); }
>> With this change
>>
>> http://git.rtems.org/rtems/commit/?id=33cb8bf64d7b7551ea3a2e7ced5d4b56cd32d6db
>>
>> it is now easier to figure out what cased a BSP specific fatal error:
>>
>> Breakpoint 2, _Internal_error_Occurred (the_source=RTEMS_FATAL_SOURCE_BSP,
>> is_internal=false, the_error=512) at
>> ../../../../../../rtems/c/src/../../cpukit/score/src/interr.c:36
>> 36 {
>> (gdb) where
>> #0 _Internal_error_Occurred (the_source=RTEMS_FATAL_SOURCE_BSP,
>> is_internal=false, the_error=512) at
>> ../../../../../../rtems/c/src/../../cpukit/score/src/interr.c:36
>> #1 0x4000239c in leon3_cpu_counter_initialize () at
>> ../../../../../.././leon3/lib/include/bsp/fatal.h:108
>> #2 0x40001c80 in bsp_start () at
>> ../../../../../../../../rtems/c/src/lib/libbsp/sparc/leon3/startup/bspstart.c:72
>> #3 0x40001b34 in boot_card (cmdline=0x0) at
>> ../../../../../../../../rtems/c/src/lib/libbsp/sparc/leon3/../../shared/bootcard.c:82
>> #4 0x400010c8 in zerobss () at
>> ../../../../../../../../rtems/c/src/lib/libbsp/sparc/leon3/../../sparc/shared/start/start.S:362
>> #5 0x400010c8 in zerobss () at
>> ../../../../../../../../rtems/c/src/lib/libbsp/sparc/leon3/../../sparc/shared/start/start.S:362
>> Backtrace stopped: previous frame identical to this frame (corrupt stack?)
>> (gdb) p (bsp_fatal_code) the_error
>> $4 = LEON3_FATAL_CPU_COUNTER_INIT
>> (gdb)
>>
More information about the devel
mailing list