[Skiboot] [PATCH Skiboot v1.2 3/3] Advertise the self-save and self-restore attributes in the device tree
Vasant Hegde
hegdevasant at linux.vnet.ibm.com
Tue Oct 15 04:24:39 AEDT 2019
On 10/14/19 3:07 PM, Pratik Sampat wrote:
>
>
> On 11/10/19 4:21 PM, Vasant Hegde wrote:
>> On 10/10/19 5:40 PM, Pratik Rajesh Sampat wrote:
>>> Support for self save and self restore interface is advertised in the
>>> device tree, along with the list of SPRs it supports for each.
>>>
>>> The Special Purpose Register identification is encoded in a 2048 bitmask
>>> structure, where each bit signifies the identification key of that SPR
>>> which is consistent with that of the Linux kernel for that register.
>>
>> I assume this feature needs supported HCODE level. How do you determine
>> whether HCODE supports
>> new feature or not?
>>
>> -Vasant
> As far as I know, Skiboot tries to make a stop API call with the highest version
> in mind,
> if it fails it falls back to older version. The way we determine today if
In that case shouldn't we check this before advertising capability via DT to kernel?
-Vasant
> self-restore
> works is by checking if the HOMER is populated in the system.
> Ideally we want to do a version check but we leave it to the stop API as it
> would do it
> anyways and give us an error if something went wrong.
>>>
>>> Signed-off-by: Pratik Rajesh Sampat <psampat at linux.ibm.com>
>>> ---
>>> hw/slw.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++
>>> include/skiboot.h | 1 +
>>> 2 files changed, 73 insertions(+)
>>>
>>> diff --git a/hw/slw.c b/hw/slw.c
>>> index b79aaab3..d9c2d091 100644
>>> --- a/hw/slw.c
>>> +++ b/hw/slw.c
>>> @@ -22,6 +22,7 @@
>>> #include <opal-api.h>
>>> #include <nvram.h>
>>> #include <sbe-p8.h>
>>> +#include <bitmap.h>
>>>
>>> #include <p9_stop_api.H>
>>> #include <p8_pore_table_gen_api.H>
>>> @@ -753,6 +754,70 @@ static void slw_late_init_p9(struct proc_chip *chip)
>>> }
>>> }
>>>
>>> +/* Add device tree properties to determine self-save | restore */
>>> +void add_cpu_self_save_properties(struct dt_node *power_mgt)
>>> +{
>>> + int i;
>>> + struct dt_node *self_restore, *self_save;
>>> + bitmap_t *self_restore_map, *self_save_map;
>>> + /* 32 times 64 bits needed to store a 2048 bits bitmask*/
>>> + const int bits_nr = 32;
>>> +
>>> + const uint64_t self_restore_regs[] = {
>>> + 0x130, // HSPRG0
>>> + 0x13E, // LPCR
>>> + 0x151, // HMEER
>>> + 0x3F0, // HID0
>>> + 0x3F1, // HID1
>>> + 0x3F4, // HID4
>>> + 0x3F6, // HID5
>>> + 0x7D0, // MSR
>>> + 0x357 // PSCCR
>>> + };
>>> +
>>> + const uint64_t self_save_regs[] = {
>>> + 0x130, // HSPRG0
>>> + 0x13E, // LPCR
>>> + 0x151, // HMEER
>>> + 0x7D0, // MSR
>>> + 0x357 // PSCCR
>>> + };
>>> + const int self_save_regs_nr = ARRAY_SIZE(self_save_regs);
>>> + const int self_restore_regs_nr = ARRAY_SIZE(self_restore_regs);
>>> +
>>> + self_save_map = zalloc(BITMAP_BYTES(0x800));
>>> + self_restore_map = zalloc(BITMAP_BYTES(0x800));
>>> +
>>> + for (i = 0; i < self_save_regs_nr; i++)
>>> + bitmap_set_bit(*self_save_map, self_save_regs[i]);
>>> +
>>> + for (i = 0; i < self_restore_regs_nr; i++)
>>> + bitmap_set_bit(*self_restore_map, self_restore_regs[i]);
>>> +
>>> + self_restore = dt_new(power_mgt, "self-restore");
>>> + if (!self_restore) {
>>> + prerror("OCC: Failed to create self restore node");
>>> + return;
>>> + }
>>> + dt_add_property_cells(self_restore, "active", 0x1);
>>> +
>>> + dt_add_property(self_restore, "sprn-bitmask", *self_restore_map,
>>> + bits_nr * sizeof(uint64_t));
>>> +
>>> + self_save = dt_new(power_mgt, "self-save");
>>> + if (!self_save) {
>>> + prerror("OCC: Failed to create self save node");
>>> + return;
>>> + }
>>> + if (proc_gen == proc_gen_p9) {
>>> + dt_add_property_cells(self_save, "active", 0x1);
>>> +
>>> + dt_add_property(self_save, "sprn-bitmask", *self_save_map,
>>> + bits_nr * sizeof(uint64_t));
>>> + } else
>>> + dt_add_property_cells(self_save, "active", 0x0);
>>> +}
>>> +
>>> /* Add device tree properties to describe idle states */
>>> void add_cpu_idle_state_properties(void)
>>> {
>>> @@ -1543,6 +1608,7 @@ opal_call(OPAL_SLW_SELF_SAVE_REG,
>>> opal_slw_self_save_reg, 2);
>>> void slw_init(void)
>>> {
>>> struct proc_chip *chip;
>>> + struct dt_node *power_mgt;
>>>
>>> if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS) {
>>> wakeup_engine_state = WAKEUP_ENGINE_NOT_PRESENT;
>>> @@ -1568,4 +1634,10 @@ void slw_init(void)
>>> }
>>> }
>>> add_cpu_idle_state_properties();
>>> + power_mgt = dt_find_by_path(dt_root, "/ibm,opal/power-mgt");
>>> + if (!power_mgt) {
>>> + prerror("OCC: dt node /ibm,opal/power-mgt not found\n");
>>> + return;
>>> + }
>>> + add_cpu_self_save_properties(power_mgt);
>>> }
>>> diff --git a/include/skiboot.h b/include/skiboot.h
>>> index 1aa8bf7c..e8f0f755 100644
>>> --- a/include/skiboot.h
>>> +++ b/include/skiboot.h
>>> @@ -202,6 +202,7 @@ extern void early_uart_init(void);
>>> extern void homer_init(void);
>>> extern void slw_init(void);
>>> extern void add_cpu_idle_state_properties(void);
>>> +extern void add_cpu_self_save_properties(struct dt_node *power_mgt);
>>> extern void lpc_rtc_init(void);
>>>
>>> /* flash support */
>>>
>>
>
More information about the Skiboot
mailing list