[Skiboot] [PATCH] cpu: supply ibm,dec-bits via devicetree

oliver oohall at gmail.com
Tue Jun 28 10:50:57 AEST 2016


On Tue, Jun 28, 2016 at 1:31 AM, Vaidyanathan Srinivasan
<svaidy at linux.vnet.ibm.com> wrote:
> * Oliver O'Halloran <oohall at gmail.com> [2016-06-27 15:07:43]:
>
>> ISAv3 adds a mode to increase the size of the decrementer from 32 bits.
>> The enlarged decrementer can be between 32 and 64 bits wide with the
>> exact value being implementation dependent. This patch adds support for
>> detecting the size of the large decrementer and populating each CPU node
>> with the "ibm,dec-bits" property.
>>
>> Signed-off-by: Oliver O'Halloran <oohall at gmail.com>
>
> Reviewed-by: Vaidyanathan Srinivasan <svaidy at linux.vnet.ibm.com>
>
>> ---
>>  core/cpu.c          | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  include/processor.h |  1 +
>>  2 files changed, 49 insertions(+)
>>
>> diff --git a/core/cpu.c b/core/cpu.c
>> index ffc264f90907..32b70e0c3713 100644
>> --- a/core/cpu.c
>> +++ b/core/cpu.c
>> @@ -524,10 +524,55 @@ void init_boot_cpu(void)
>>       list_head_init(&global_job_queue);
>>  }
>>
>> +static void enable_ld(bool on)
>> +{
>> +     u64 lpcr = mfspr(SPR_LPCR);
>> +
>> +     if (on)
>> +             lpcr |= SPR_LPCR_P9_LD;
>> +     else
>> +             lpcr &= ~SPR_LPCR_P9_LD;
>> +
>> +     mtspr(SPR_LPCR, lpcr);
>> +}
>
> How about expanding 'ld' in the function name and also maybe have
> enable/disable for better readability instead of taking a parameter.
>
> static inline void enable_long_dec()
> static inline void disable_long_dec()

I have no real preference. I thought having seperate functions just
resulted in two (ugly) sets of mfspr/bit twiddle/mtspr sequences
rather than this, which I thought was pretty clean. I suppose it could
have a better name...

>
>> +
>> +#define HIGH_BIT (1ull << 63)
>> +
>> +static int find_dec_bits(void)
>> +{
>> +     int bits = 65; /* we always decrement once */
>> +     u64 mask = ~0ull;
>> +
>> +     if (proc_gen < proc_gen_p9)
>> +             return 32;
>> +
>> +     /* The ISA doesn't specify the width of the decrementer register so we
>> +      * need to discover it. When in large mode (LPCR.LD = 1) reads from the
>> +      * DEC SPR are sign extended to 64 bits and writes are truncated to the
>> +      * physical register width. We can use this behaviour to detect the
>> +      * width by starting from an all 1s value and left shifting until we
>> +      * read a value from the DEC with it's high bit cleared.
>> +      */
>> +
>> +     enable_ld(true);
>> +
>> +     do {
>> +             bits--;
>> +             mask = mask >> 1;
>> +             mtspr(SPR_DEC, mask);
>> +     } while (mfspr(SPR_DEC) & HIGH_BIT);
>> +
>> +     enable_ld(false);
>> +
>> +     prlog(PR_DEBUG, "CPU: decrementer bits %d\n", bits);
>> +     return bits;
>
> Number of bits supported by the decrementer is one more than the
> number of bits set in the mask at the time when sign extension stops
> and HIGH_BIT is not set.  Will this be true always?

The ISA says "When the Decrementer is in Large Decrementer mode, it
behaves as a d-bit decrementing counter which is sign-extended to 64
bits." so this behaviour should be reliable.

>
> Also the decrementer would count down from the mask value before we
> compare, but that will not toggle the higher order bits and the loop
> will work correctly :)
>
>
>> +}
>> +
>>  void init_all_cpus(void)
>>  {
>>       struct dt_node *cpus, *cpu;
>>       unsigned int thread, new_max_pir = 0;
>> +     int dec_bits = find_dec_bits();
>
> You already test function of large decrementer and only then export
> ibm,dec-bits > 32.
>
> You leave LD disabled in LPCR and let the Linux kernel check and
> enable.
>
> Why do we have to test the number of bits again in kernel?  Do you
> have a reason to believe that test/check in skiboot is not sufficient?
>
> You have check_large_decrementer() in kernel that will again validate
> the number of bits that you have just discovered.

I'm just being paranoid. I don't like the idea of having the kernel relying on
skiboot to validate architected features. In my mind skiboot is there for
handling platform/chip specific details while anything that appears in Books 1-3
should be handled by the kernel. Given that Power is *technically* an open ISA
it's conceivable that there might the a non-IBM implementation of
ISAv3 that uses
a different firmware stack.

>
>
>>       cpus = dt_find_by_path(dt_root, "/cpus");
>>       assert(cpus);
>> @@ -582,6 +627,9 @@ void init_all_cpus(void)
>>               /* Add associativity properties */
>>               add_core_associativity(t);
>>
>> +             /* Add the decrementer width property */
>> +             dt_add_property_cells(cpu, "ibm,dec-bits", dec_bits);
>> +
>>               /* Adjust max PIR */
>>               if (new_max_pir < (pir + cpu_thread_count - 1))
>>                       new_max_pir = pir + cpu_thread_count - 1;
>> diff --git a/include/processor.h b/include/processor.h
>> index 1236c779aac8..48bbf903df58 100644
>> --- a/include/processor.h
>> +++ b/include/processor.h
>> @@ -96,6 +96,7 @@
>>  #define SPR_LPCR_P8_PECE2    PPC_BIT(49)   /* Wake on external interrupts */
>>  #define SPR_LPCR_P8_PECE3    PPC_BIT(50)   /* Wake on decrementer */
>>  #define SPR_LPCR_P8_PECE4    PPC_BIT(51)   /* Wake on MCs, HMIs, etc... */
>> +#define SPR_LPCR_P9_LD               PPC_BIT(46)   /* Large decrementer mode bit */
>>
>>
>>  /* Bits in TFMR - control bits */
>> --
>> 2.5.5
>>
>> _______________________________________________
>> Skiboot mailing list
>> Skiboot at lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/skiboot
>


More information about the Skiboot mailing list