[Skiboot] [PATCH V2] NX: Add NX coprocessor init opal call
Haren Myneni
haren at linux.vnet.ibm.com
Wed Jun 6 14:35:41 AEST 2018
Thanks for the review,
On 06/04/2018 09:08 PM, Stewart Smith wrote:
> Haren Myneni <haren at linux.vnet.ibm.com> writes:
>>
>> The read offset (4:11) in Receive FIFO control register is incremented
>> by FIFO size whenever CRB read by NX. But the index in RxFIFO has to
>> match with the corresponding entry in FIFO maintained by VAS in kernel.
>> VAS entry is reset to 0 when opening the receive window during driver
>> initialization. So when NX842 is reloaded or in kexec boot, possibility
>> of mismatch between RxFIFO control register and VAS entries in kernel.
>> It could cause CRB failure / timeout from NX.
>>
>> This patch adds nx_coproc_init opal call for kernel to initialize
>> readOffset (4:11) and Queued (15:23) in RxFIFO control register.
>>
>> Signed-off-by: Haren Myneni <haren at us.ibm.com>
>> ---
>> Changelog:
>> v2: Added doc/opal-api/opal_nx_coproc_init-167.rst
>>
>> diff --git a/doc/opal-api/opal_nx_coproc_init-167.rst b/doc/opal-api/opal_nx_coproc_init-167.rst
>> new file mode 100644
>> index 0000000..d05aed4
>> --- /dev/null
>> +++ b/doc/opal-api/opal_nx_coproc_init-167.rst
>> @@ -0,0 +1,32 @@
>> +.. _opal_nx_coproc_init:
>> +
>> +OPAL_NX_COPROC_INIT
>> +===================
>> +
>> +This OPAL call resets read offset and queued entries in high and normal
>> +priority receive FIFO control registers. The kernel initializes read
>> +offset entry in RXFIFO that it maintains during initialization. So this
>> +register reset is needed for NX module reload or in kexec boot to make sure
>> +read offset value matches with kernel entries. Otherwise NX reads requests
>> +with wrong offset in RxFIFO which could cause NX request failures.
>> +
>> +The kernel initiates this call for each coprocessor type such as 842 and
>> +GZIP per NX instance.
>> +
>> +Arguments
>> +---------
>> +::
>> +
>> + uint32_t chip_id
>> + Contains value of the chip number identified at boot time.
>> +
>> + uint32_t ct
>> + Contains NX coprocessor type such as 842 and GZIP.
>
> Could you make this:
>
> ``uint32_t chip_id``
> Contains value of the chip number identified at boot time.
> ``uint32_t pid``
> Contains NX coprocessor type (pid from the device tree).
>
> to make it a bit more obvious what's being passed in?
I will make this change.
>
>
>> +
>> +Returns
>> +-------
>> +OPAL_SUCCESS
>> + The quiesce call was successful.
>
> Err... this isn't OPAL_QUIESCE
sorry, my mistake
.
>
>> diff --git a/hw/nx-compress.c b/hw/nx-compress.c
>> index 9b89664..cf1c3e9 100644
>> --- a/hw/nx-compress.c
>> +++ b/hw/nx-compress.c
>> @@ -21,6 +21,7 @@
>> #include <cpu.h>
>> #include <nx.h>
>> #include <vas.h>
>> +#include <opal.h>
>>
>> static int nx_cfg_umac_tx_wc(u32 gcid, u64 xcfg)
>> {
>> @@ -206,14 +207,75 @@ int nx_cfg_rx_fifo(struct dt_node *node, const char *compat,
>> return 0;
>> }
>>
>> +static int nx_init_fifo_ctrl(u32 gcid, u64 fifo_ctrl)
>> +{
>> + u64 cfg;
>> + int rc = 0;
>> +
>> + rc = xscom_read(gcid, fifo_ctrl, &cfg);
>> + if (rc)
>> + return rc;
>> +
>> + cfg = SETFIELD(NX_P9_RX_FIFO_CTRL_READ_OFFSET, cfg, 0);
>> + cfg = SETFIELD(NX_P9_RX_FIFO_CTRL_QUEUED, cfg, 0);
>> +
>> + rc = xscom_write(gcid, fifo_ctrl, cfg);
>> +
>> + return rc;
>> +}
>> +
>> +
>> +static int opal_nx_coproc_init(u32 gcid, u32 ct)
>> +{
>> + struct proc_chip *chip;
>> + u64 fifo, fifo_hi;
>> + u32 nx_base;
>> + int rc;
>> +
>> + chip = get_chip(gcid);
>> + if (!chip)
>> + return OPAL_PARAMETER;
>> +
>> + nx_base = chip->nx_base;
>> + if (!nx_base)
>> + return OPAL_PARAMETER;
>> +
>> + switch (ct) {
>> + case NX_CT_842:
>> + fifo_hi = nx_base + NX_P9_842_HIGH_PRI_RX_FIFO_CTRL;
>> + fifo = nx_base + NX_P9_842_NORMAL_PRI_RX_FIFO_CTRL;
>> + break;
>> + case NX_CT_GZIP:
>> + fifo_hi = nx_base + NX_P9_GZIP_HIGH_PRI_RX_FIFO_CTRL;
>> + fifo = nx_base + NX_P9_GZIP_NORMAL_PRI_RX_FIFO_CTRL;
>> + break;
>> + default:
>> + prlog(PR_EMERG, "OPAL: Unknown NX coprocessor type\n");
>> + return OPAL_PARAMETER;
>> + }
>> +
>> + rc = nx_init_fifo_ctrl(gcid, fifo_hi);
>> +
>> + if (!rc)
>> + rc = nx_init_fifo_ctrl(gcid, fifo);
>> +
>> + return rc;
>> +}
>> +
>> +opal_call(OPAL_NX_COPROC_INIT, opal_nx_coproc_init, 2);
>> +
>> void nx_create_compress_node(struct dt_node *node)
>> {
>> u32 gcid, pb_base;
>> + struct proc_chip *chip;
>> int rc;
>>
>> gcid = dt_get_chip_id(node);
>> pb_base = dt_get_address(node, 0, NULL);
>>
>> + chip = get_chip(gcid);
>> + chip->nx_base = pb_base;
>> +
>> prlog(PR_INFO, "NX%d: 842 at 0x%x\n", gcid, pb_base);
>>
>> if (dt_node_is_compatible(node, "ibm,power9-nx")) {
>
> This looks like it'll break on POWER8 as we're adding the base there
> even on P8, which means that the OPAL call won't error out as you'd
> expect, but rather just do some random SCOMs.
>
> I gather we don't need this kind of call for P8?
>
> Even if we don't, I'd prefer we error out gracefully rather than do
> random scoms.
Correct, this OPAL call should not be executed on P8. I will add < P9 check in opal call.
if (proc_gen < proc_gen_p9)
return OPAL_UNSUPPORTED;
Thanks
Haren
>
More information about the Skiboot
mailing list