<html><body>
<p><font size="2" face="sans-serif">Doesn't hostboot runtime already perform this function?  Is there any collision between opal modifying the occ queue while hostboot runtime is functional?<br>
</font><font size="2" face="sans-serif"><br>
</font><font size="2" face="sans-serif">Patrick Williams<br>
</font><font size="2" face="sans-serif"><br>
</font><font size="2" face="sans-serif">> On May 12, 2015, at 12:31 AM, Stewart Smith <stewart@linux.vnet.ibm.com> wrote:<br>
</font><font size="2" face="sans-serif">> <br>
</font><font size="2" face="sans-serif">> Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> writes:<br>
</font><font size="2" face="sans-serif">>> Add a new class of message definition OPAL_MSG_OCC to<br>
</font><font size="2" face="sans-serif">>> opal_message_type to notify the following OCC events to host:<br>
</font><font size="2" face="sans-serif">>> 1) OCC Reset<br>
</font><font size="2" face="sans-serif">>> 2) OCC Load<br>
</font><font size="2" face="sans-serif">>> 3) OCC Throttle Status Change<br>
</font><font size="2" face="sans-serif">>> <br>
</font><font size="2" face="sans-serif">>> Add an opal poller to periodically read throttle status updated by OCC<br>
</font><font size="2" face="sans-serif">>> for each chip and notify any change in throttle status to host. The<br>
</font><font size="2" face="sans-serif">>> throttle status indicates the reason why OCC may have limited the max<br>
</font><font size="2" face="sans-serif">>> Pstate of the chip.<br>
</font><font size="2" face="sans-serif">> <br>
</font><font size="2" face="sans-serif">> Major comment is that you need to add something to<br>
</font><font size="2" face="sans-serif">> doc/opal-api/opal-messages.txt<br>
</font><font size="2" face="sans-serif">> <br>
</font><font size="2" face="sans-serif">> Also include a description on how we may deal with future expansion<br>
</font><font size="2" face="sans-serif">> (e.g. chip_id and throttle_status only valid for params[0] = 0,1,2 and<br>
</font><font size="2" face="sans-serif">> if params is > 2 then rest of params is something defined in future OPAL<br>
</font><font size="2" face="sans-serif">> version and host should just ignore the message)<br>
</font><font size="2" face="sans-serif">> <br>
</font><font size="2" face="sans-serif">> Do we *really* have to poll? That kind of sucks if so (and how do we get<br>
</font><font size="2" face="sans-serif">> that fixed?)<br>
</font><font size="2" face="sans-serif">> <br>
</font><font size="2" face="sans-serif">>> diff --git a/hw/occ.c b/hw/occ.c<br>
</font><font size="2" face="sans-serif">>> index 34d6de5..d346394 100644<br>
</font><font size="2" face="sans-serif">>> --- a/hw/occ.c<br>
</font><font size="2" face="sans-serif">>> +++ b/hw/occ.c<br>
</font><font size="2" face="sans-serif">>> @@ -24,6 +24,8 @@<br>
</font><font size="2" face="sans-serif">>> #include <timebase.h><br>
</font><font size="2" face="sans-serif">>> #include <hostservices.h><br>
</font><font size="2" face="sans-serif">>> #include <errorlog.h><br>
</font><font size="2" face="sans-serif">>> +#include <opal-api.h><br>
</font><font size="2" face="sans-serif">>> +#include <opal-msg.h><br>
</font><font size="2" face="sans-serif">>> <br>
</font><font size="2" face="sans-serif">>> /* OCC Communication Area for PStates */<br>
</font><font size="2" face="sans-serif">>> <br>
</font><font size="2" face="sans-serif">>> @@ -31,6 +33,16 @@<br>
</font><font size="2" face="sans-serif">>> <br>
</font><font size="2" face="sans-serif">>> #define MAX_PSTATES 256<br>
</font><font size="2" face="sans-serif">>> <br>
</font><font size="2" face="sans-serif">>> +#define OCC_RESET    0<br>
</font><font size="2" face="sans-serif">>> +#define OCC_LOAD    1<br>
</font><font size="2" face="sans-serif">>> +#define OCC_THROTTLE    2<br>
</font><font size="2" face="sans-serif">> <br>
</font><font size="2" face="sans-serif">> Part of ABI? Please add to opal-api.h and doc/<br>
</font><font size="2" face="sans-serif">> <br>
</font><font size="2" face="sans-serif">>> +<br>
</font><font size="2" face="sans-serif">>> +#define chip_occ_data(chip) \<br>
</font><font size="2" face="sans-serif">>> +        ((struct occ_pstate_table *)(chip->homer_base + \<br>
</font><font size="2" face="sans-serif">>> +                P8_HOMER_SAPPHIRE_DATA_OFFSET))<br>
</font><font size="2" face="sans-serif">>> +<br>
</font><font size="2" face="sans-serif">>> +static bool occ_reset;<br>
</font><font size="2" face="sans-serif">>> +<br>
</font><font size="2" face="sans-serif">>> struct occ_pstate_entry {<br>
</font><font size="2" face="sans-serif">>>    s8 id;<br>
</font><font size="2" face="sans-serif">>>    u8 flags;<br>
</font><font size="2" face="sans-serif">>> @@ -302,6 +314,61 @@ static bool cpu_pstates_prepare_core(struct proc_chip *chip, struct cpu_thread *<br>
</font><font size="2" face="sans-serif">>>    return true;<br>
</font><font size="2" face="sans-serif">>> }<br>
</font><font size="2" face="sans-serif">>> <br>
</font><font size="2" face="sans-serif">>> +/* occ_throttle_poll: This function will queue a meassage of type<br>
</font><font size="2" face="sans-serif">>> + * OPAL_MSG_OCC to notify any change in the throttle status of the<br>
</font><font size="2" face="sans-serif">>> + * chip. Throttle status indicates the reason why OCC may have limited<br>
</font><font size="2" face="sans-serif">>> + * the max Pstate of the chip.<br>
</font><font size="2" face="sans-serif">>> + * 0x00 = No throttle<br>
</font><font size="2" face="sans-serif">>> + * 0x01 = Power Cap<br>
</font><font size="2" face="sans-serif">>> + * 0x02 = Processor Over Temperature<br>
</font><font size="2" face="sans-serif">>> + * 0x03 = Power Supply Failure (currently not used)<br>
</font><font size="2" face="sans-serif">>> + * 0x04 = Over current (currently not used)<br>
</font><font size="2" face="sans-serif">>> + * 0x05 = OCC Reset (not reliable as some failures will not allow for<br>
</font><font size="2" face="sans-serif">>> + * OCC to update throttle status, so use 'occ_reset')<br>
</font><font size="2" face="sans-serif">> <br>
</font><font size="2" face="sans-serif">> Looks like these are part of ABI - please add to opal-api.h and document.<br>
</font><font size="2" face="sans-serif">> <br>
</font><font size="2" face="sans-serif">>> + */<br>
</font><font size="2" face="sans-serif">>> +static void occ_throttle_poll(void *data __unused)<br>
</font><font size="2" face="sans-serif">>> +{<br>
</font><font size="2" face="sans-serif">>> +    struct proc_chip *chip;<br>
</font><font size="2" face="sans-serif">>> +    struct occ_pstate_table *occ_data;<br>
</font><font size="2" face="sans-serif">>> +    int rc;<br>
</font><font size="2" face="sans-serif">>> +<br>
</font><font size="2" face="sans-serif">>> +    if (occ_reset) {<br>
</font><font size="2" face="sans-serif">>> +        int inactive = 0;<br>
</font><font size="2" face="sans-serif">>> +<br>
</font><font size="2" face="sans-serif">>> +        for_each_chip(chip) {<br>
</font><font size="2" face="sans-serif">>> +            occ_data = chip_occ_data(chip);<br>
</font><font size="2" face="sans-serif">>> +            if (occ_data->valid != 1) {<br>
</font><font size="2" face="sans-serif">>> +                inactive = 1;<br>
</font><font size="2" face="sans-serif">>> +                break;<br>
</font><font size="2" face="sans-serif">>> +            }<br>
</font><font size="2" face="sans-serif">>> +        }<br>
</font><font size="2" face="sans-serif">>> +        if (!inactive) {<br>
</font><font size="2" face="sans-serif">>> +            /*<br>
</font><font size="2" face="sans-serif">>> +             * Queue OCC_THROTTLE with throttle status as 0 to<br>
</font><font size="2" face="sans-serif">>> +             * indicate all OCCs are active after a reset.<br>
</font><font size="2" face="sans-serif">>> +             */<br>
</font><font size="2" face="sans-serif">>> +            rc = opal_queue_msg(OPAL_MSG_OCC, NULL, NULL,<br>
</font><font size="2" face="sans-serif">>> +                        OCC_THROTTLE, 0, 0);<br>
</font><font size="2" face="sans-serif">>> +            if (!rc)<br>
</font><font size="2" face="sans-serif">>> +                occ_reset = false;<br>
</font><font size="2" face="sans-serif">>> +        }<br>
</font><font size="2" face="sans-serif">>> +    } else {<br>
</font><font size="2" face="sans-serif">>> +        for_each_chip(chip) {<br>
</font><font size="2" face="sans-serif">>> +            occ_data = chip_occ_data(chip);<br>
</font><font size="2" face="sans-serif">>> +            if ((occ_data->valid == 1) &&<br>
</font><font size="2" face="sans-serif">>> +                (chip->prev_throttle != occ_data->throttle) &&<br>
</font><font size="2" face="sans-serif">>> +                (occ_data->throttle <= 5)) {<br>
</font><font size="2" face="sans-serif">>> +                rc = opal_queue_msg(OPAL_MSG_OCC, NULL, NULL,<br>
</font><font size="2" face="sans-serif">>> +                        OCC_THROTTLE, chip->id,<br>
</font><font size="2" face="sans-serif">>> +                        occ_data->throttle);<br>
</font><font size="2" face="sans-serif">>> +                if (!rc)<br>
</font><font size="2" face="sans-serif">>> +                    chip->prev_throttle =<br>
</font><font size="2" face="sans-serif">>> +                        occ_data->throttle;<br>
</font><font size="2" face="sans-serif">>> +            }<br>
</font><font size="2" face="sans-serif">>> +        }<br>
</font><font size="2" face="sans-serif">>> +    }<br>
</font><font size="2" face="sans-serif">>> +}<br>
</font><font size="2" face="sans-serif">>> +<br>
</font><font size="2" face="sans-serif">>> /* CPU-OCC PState init */<br>
</font><font size="2" face="sans-serif">>> /* Called after OCC init on P8 */<br>
</font><font size="2" face="sans-serif">>> void occ_pstates_init(void)<br>
</font><font size="2" face="sans-serif">>> @@ -345,6 +412,11 @@ void occ_pstates_init(void)<br>
</font><font size="2" face="sans-serif">>>            cpu_pstates_prepare_core(chip, c, pstate_nom);<br>
</font><font size="2" face="sans-serif">>>        }<br>
</font><font size="2" face="sans-serif">>>    }<br>
</font><font size="2" face="sans-serif">>> +<br>
</font><font size="2" face="sans-serif">>> +    /* Add opal_poller to poll OCC throttle status of each chip */<br>
</font><font size="2" face="sans-serif">>> +    for_each_chip(chip)<br>
</font><font size="2" face="sans-serif">>> +        chip->prev_throttle = 0;<br>
</font><font size="2" face="sans-serif">>> +    opal_add_poller(occ_throttle_poll, NULL);<br>
</font><font size="2" face="sans-serif">>> }<br>
</font><font size="2" face="sans-serif">>> <br>
</font><font size="2" face="sans-serif">>> struct occ_load_req {<br>
</font><font size="2" face="sans-serif">>> @@ -386,6 +458,11 @@ static void __occ_do_load(u8 scope, u32 dbob_id __unused, u32 seq_id)<br>
</font><font size="2" face="sans-serif">>>        prlog(PR_INFO, "OCC: Load: Fallback to preloaded image\n");<br>
</font><font size="2" face="sans-serif">>>        rc = 0;<br>
</font><font size="2" face="sans-serif">>>    } else if (!rc) {<br>
</font><font size="2" face="sans-serif">>> +        rc = opal_queue_msg(OPAL_MSG_OCC, NULL, NULL, OCC_LOAD);<br>
</font><font size="2" face="sans-serif">>> +        if (rc)<br>
</font><font size="2" face="sans-serif">>> +            prlog(PR_INFO, "OCC: Failed to queue message %d\n",<br>
</font><font size="2" face="sans-serif">>> +                        OCC_LOAD);<br>
</font><font size="2" face="sans-serif">>> +<br>
</font><font size="2" face="sans-serif">>>        /* Success, start OCC */<br>
</font><font size="2" face="sans-serif">>>        rc = host_services_occ_start();<br>
</font><font size="2" face="sans-serif">>>    }<br>
</font><font size="2" face="sans-serif">>> @@ -509,6 +586,24 @@ static void occ_do_reset(u8 scope, u32 dbob_id, u32 seq_id)<br>
</font><font size="2" face="sans-serif">>>        rc = 0;<br>
</font><font size="2" face="sans-serif">>>    }<br>
</font><font size="2" face="sans-serif">>>    if (!rc) {<br>
</font><font size="2" face="sans-serif">>> +        rc = opal_queue_msg(OPAL_MSG_OCC, NULL, NULL, OCC_RESET);<br>
</font><font size="2" face="sans-serif">>> +        if (rc)<br>
</font><font size="2" face="sans-serif">>> +            prlog(PR_INFO, "OCC: Failed to queue message %d\n",<br>
</font><font size="2" face="sans-serif">>> +                        OCC_RESET);<br>
</font><font size="2" face="sans-serif">>> +        /*<br>
</font><font size="2" face="sans-serif">>> +         * Set 'valid' byte of chip_occ_data to 0 since OCC<br>
</font><font size="2" face="sans-serif">>> +         * may not clear this byte on a reset.<br>
</font><font size="2" face="sans-serif">>> +         * OCC will set the 'valid' byte to 1 when it becomes<br>
</font><font size="2" face="sans-serif">>> +         * active again.<br>
</font><font size="2" face="sans-serif">>> +         */<br>
</font><font size="2" face="sans-serif">>> +        for_each_chip(chip) {<br>
</font><font size="2" face="sans-serif">>> +            struct occ_pstate_table *occ_data;<br>
</font><font size="2" face="sans-serif">>> +<br>
</font><font size="2" face="sans-serif">>> +            occ_data = chip_occ_data(chip);<br>
</font><font size="2" face="sans-serif">>> +            occ_data->valid = 0;<br>
</font><font size="2" face="sans-serif">>> +            chip->prev_throttle = 0;<br>
</font><font size="2" face="sans-serif">>> +        }<br>
</font><font size="2" face="sans-serif">>> +        occ_reset = true;<br>
</font><font size="2" face="sans-serif">>>        /* Send a single success response for all chips */<br>
</font><font size="2" face="sans-serif">>>        stat = fsp_mkmsg(FSP_CMD_RESET_OCC_STAT, 2, 0, seq_id);<br>
</font><font size="2" face="sans-serif">>>        if (stat)<br>
</font><font size="2" face="sans-serif">>> diff --git a/include/chip.h b/include/chip.h<br>
</font><font size="2" face="sans-serif">>> index 0547902..340fdfc 100644<br>
</font><font size="2" face="sans-serif">>> --- a/include/chip.h<br>
</font><font size="2" face="sans-serif">>> +++ b/include/chip.h<br>
</font><font size="2" face="sans-serif">>> @@ -147,6 +147,7 @@ struct proc_chip {<br>
</font><font size="2" face="sans-serif">>>    uint64_t        homer_size;<br>
</font><font size="2" face="sans-serif">>>    uint64_t        occ_common_base;<br>
</font><font size="2" face="sans-serif">>>    uint64_t        occ_common_size;<br>
</font><font size="2" face="sans-serif">>> +    u8            prev_throttle;<br>
</font><font size="2" face="sans-serif">>> <br>
</font><font size="2" face="sans-serif">>>    /* Must hold capi_lock to change */<br>
</font><font size="2" face="sans-serif">>>    u8            capp_phb3_attached_mask;<br>
</font><font size="2" face="sans-serif">>> diff --git a/include/opal-api.h b/include/opal-api.h<br>
</font><font size="2" face="sans-serif">>> index 1698311..abe798e 100644<br>
</font><font size="2" face="sans-serif">>> --- a/include/opal-api.h<br>
</font><font size="2" face="sans-serif">>> +++ b/include/opal-api.h<br>
</font><font size="2" face="sans-serif">>> @@ -417,6 +417,13 @@ enum opal_msg_type {<br>
</font><font size="2" face="sans-serif">>>    OPAL_MSG_HMI_EVT,<br>
</font><font size="2" face="sans-serif">>>    OPAL_MSG_DPO,<br>
</font><font size="2" face="sans-serif">>>    OPAL_MSG_PRD,<br>
</font><font size="2" face="sans-serif">>> +    OPAL_MSG_OCC,            /*<br>
</font><font size="2" face="sans-serif">>> +                     * params[0] =    0 reset,<br>
</font><font size="2" face="sans-serif">>> +                     *        1 load,<br>
</font><font size="2" face="sans-serif">>> +                     *        2 throttle<br>
</font><font size="2" face="sans-serif">>> +                     * params[1] = chip_id,<br>
</font><font size="2" face="sans-serif">>> +                     * params[2] = throttle_status<br>
</font><font size="2" face="sans-serif">>> +                     */<br>
</font><font size="2" face="sans-serif">> <br>
</font><font size="2" face="sans-serif">> Perhaps define this in a struct/union somewhere too?<br>
</font><font size="2" face="sans-serif">> <br>
</font><font size="2" face="sans-serif">> _______________________________________________<br>
</font><font size="2" face="sans-serif">> Skiboot mailing list<br>
</font><font size="2" face="sans-serif">> Skiboot@lists.ozlabs.org<br>
</font><font size="2" face="sans-serif">> <a href="https://lists.ozlabs.org/listinfo/skiboot">https://lists.ozlabs.org/listinfo/skiboot</a><br>
</font></body></html>