leon3 broken for hello
Daniel Hellstrom
daniel at gaisler.com
Mon Feb 24 11:00:04 UTC 2014
On 02/21/2014 11:42 AM, Sebastian Huber wrote:
> Hello Daniel,
>
> On 2014-02-21 11:10, Daniel Hellstrom wrote:
>> 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.
>
> what is if this second timer is the watchdog? What is if this is an AMP configuration which uses CPU index == Clock timer index?
I think one could safely assume in the general LEON3 case:
* each OS instance have at least two timers each.
* if there is a watchdog timer present, there is an additional timer, the last timer on GPTIMER[0]
For the NGMP however, when running in AMP mode we have different timer cores.
>
>>
>> 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.
>
> One option would be to use a BSP configure option, but this destroys the PnP nature of this BSP.
To be honest, the PnP of the BSP in AMP configuration have never really been very good. There are basically to many assumptions. The Register base and IRQ is PnP which helps a lot, but the system
configuration and resource sharing can never be PnP.
In our RCC release we have a another gptimer/grtimer driver that the user can configure during project compile time (same kernel libraries). The user can use this additional driver to configure a
range of timers per OS instance, using the following:
* - timerStart Timer Index if first Timer, this parameters is typically used
* in AMP systems for resource allocation. The Timers before
* timerStart will not be accessed.
* - timerCnt Number of timers that the driver will use, this parameters is
* typically used in AMP systems for resource allocation between
* OS instances.
* - prescaler Base prescaler, normally set by bootloader but can be
* overridden. The default scaler reload value set by bootloader
* is so that Timers operate in 1MHz. Setting the prescaler to a
* lower value increase the accuracy of the timers but shortens
* the time until underflow happens.
* - clockTimer Used to select a particular timer to be the system clock
* timer. This is useful when multiple GPTIMERs cores are
* available, or in AMP systems. By default the TLIB selects the
* first timer registered as system clock timer.
>
> Another option is to use function pointers in the counter read/difference functions and initialize them with the best option available.
I think a configuration option is required unless we use GPTIMER[0].timer0.
Is this new driver a requirement for single-core or SMP?
>
>>
>> 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.
>
> How can I find this second timer?
Substitute the GPTIMER macro with GRTIMER to search for GRTIMER instead.
>
>>
>> +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?
>
> This could be compensated by a custom _CPU_Counter_difference() function.
Ok.
>
>> Is 1MHz to slow?
>
> I don't have enough data to know if 1MHz is too slow. We first need some profiling data.
Ok.
>
>> 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.
>
> After some discussions with the ESA and our consortium we ended up with the present solution.
>
> My first proposal was to change the prescaler of GPTIMER 0 to an even multiple of the original prescaler close to 8, resulting in a 25MHz timer and adjust the clock driver interval calculation
> accordingly.
This is what I would have done too. But there are other aspects involved here. Reading the current scaler value to improve the resolution is difficult too. As the systems increase in clock frequency
the 1MHz resolution will become to bad.
If 1MHz is not sufficient we must depend on GPTIMER[1] or GRTIMER[0] which then is board specific, and I think the driver shuold only go into the NGMP BSP.
Would it be a solution to use GPTIMER[0].timer0 by default of the implementation, and for NGMP BSP you override using the GPTIMER[4].timer0?
Daniel
More information about the devel
mailing list