[Skiboot] [EXTERNAL] [PATCH v6 13/29] xive: make endian-clean
Cédric Le Goater
clg at kaod.org
Thu Nov 7 22:02:01 AEDT 2019
On 07/11/2019 11:29, Nicholas Piggin wrote:
> Cédric Le Goater's on November 7, 2019 6:25 pm:
>> On 07/11/2019 07:26, Nicholas Piggin wrote:
>>> Cédric Le Goater's on November 7, 2019 1:38 am:
>>>> On 06/11/2019 13:10, Nicholas Piggin wrote:
>>>>> Convert xive opal calls, dt construction, and in-memory hardware tables
>>>>> to use explicit endian conversions.
>>>> Thanks for reworking the patch with helper routines. This is a huge
>>>> work. You are setting the standards pretty high for xive2 !
>>> Well once I took your nice helpers then it's only mindless conversions.
>>
>> May be we could generalize the use to other parts of your patchset ?
>
> I had a bit of a look, nothing seems to use fields within words to the
> extent that xive does.
>
>>
>>> I thought I'd better do it rather than pull you away from useful work :)
>>
>> xive2 does not have LE support currently ... I will do the conversion
>> after some tests has been done first.
>>
>>>> Did you run a KVM guest ?
>>> I just pulled the latest qemu and tried. Had some bugs in the
>>> conversion, so here is an updated patch. I'll not re-send the series
>>> until you get a chance to ack it, at least.
>>
>> OK.
>>
>> Here are some remarks below. Nothing really important requiring a resend.
>
> Thanks.
>
>>> @@ -791,8 +791,8 @@ static void xive_init_default_vp(struct xive_vp *vp,
>>> memset(vp, 0, sizeof(struct xive_vp));
>>>
>>> /* Stash the EQ base in the pressure relief interrupt field */
>>> - vp->w1 = (eq_blk << 28) | eq_idx;
>>> - vp->w0 = VP_W0_VALID;
>>> + vp->w1 = cpu_to_be32((eq_blk << 28) | eq_idx);
>>
>> This field is not architected in xive1 and we should had an helper like
>> in xive2 : xive_vp_set_end_base(). It can come later.
>>
>>> + vp->w0 = xive_set_field32(VP_W0_VALID, 0, 1);
>>> }
>>>
>>> static void xive_init_emu_eq(uint32_t vp_blk, uint32_t vp_idx,
>>> @@ -801,18 +801,20 @@ static void xive_init_emu_eq(uint32_t vp_blk, uint32_t vp_idx,
>>> {
>>> memset(eq, 0, sizeof(struct xive_eq));
>>>
>>> - eq->w1 = EQ_W1_GENERATION;
>>> - eq->w3 = ((uint64_t)backing_page) & 0xffffffff;
>>> - eq->w2 = (((uint64_t)backing_page)) >> 32 & 0x0fffffff;
>>> - eq->w6 = SETFIELD(EQ_W6_NVT_BLOCK, 0ul, vp_blk) |
>>> - SETFIELD(EQ_W6_NVT_INDEX, 0ul, vp_idx);
>>> - eq->w7 = SETFIELD(EQ_W7_F0_PRIORITY, 0ul, prio);
>>> - eq->w0 = EQ_W0_VALID | EQ_W0_ENQUEUE |
>>> - SETFIELD(EQ_W0_QSIZE, 0ul, EQ_QSIZE_64K) |
>>> - EQ_W0_FIRMWARE;
>>> + eq->w1 = xive_set_field32(EQ_W1_GENERATION, 0, 1);
>>> + eq->w3 = cpu_to_be32(((uint64_t)backing_page) & 0xffffffff);
>>> + eq->w2 = cpu_to_be32(((((uint64_t)backing_page)) >> 32) & 0x0fffffff);
>>
>> I think we can remove one parenthesis and we should use the field
>> definitions like in opal_xive_set_queue_info() :
>>
>> eq.w3 = ((uint64_t)qpage) & EQ_W3_OP_DESC_LO;
>> eq.w2 = (((uint64_t)qpage) >> 32) & EQ_W2_OP_DESC_HI;
>>
>> I should done that in my cleanup series but I missed the emulation layer.
>> My inconscient refuses to do it I think.
>>
>> I can address that in a prereq patch if you prefer ?
>
> I don't mind before or after. If this is a missing bit from your
> cleanup series sure send a fix for upstream and I can rebase.
>
>>> + eq->w6 = xive_set_field32(EQ_W6_NVT_BLOCK, 0, vp_blk) |
>>> + xive_set_field32(EQ_W6_NVT_INDEX, 0, vp_idx);
>>> + eq->w7 = xive_set_field32(EQ_W7_F0_PRIORITY, 0, prio);
>>> + eq->w0 = xive_set_field32(EQ_W0_VALID, 0, 1) |
>>> + xive_set_field32(EQ_W0_ENQUEUE, 0, 1) |
>>> + xive_set_field32(EQ_W0_FIRMWARE, 0, 1) |
>>> + xive_set_field32(EQ_W0_QSIZE, 0, EQ_QSIZE_64K) |
>>> #ifdef EQ_ALWAYS_NOTIFY
>>> - eq->w0 |= EQ_W0_UCOND_NOTIFY;
>>> + xive_set_field32(EQ_W0_UCOND_NOTIFY, 0, 1) |
>>> #endif
>>> + 0 ;
>>> }
>>>
>>> static uint32_t *xive_get_eq_buf(uint32_t eq_blk, uint32_t eq_idx)
>>> @@ -824,8 +826,8 @@ static uint32_t *xive_get_eq_buf(uint32_t eq_blk, uint32_t eq_idx)
>>> assert(x);
>>> eq = xive_get_eq(x, eq_idx);
>>> assert(eq);
>>> - assert(eq->w0 & EQ_W0_VALID);
>>> - addr = (((uint64_t)eq->w2) & 0x0fffffff) << 32 | eq->w3;
>>> + assert(xive_get_field32(EQ_W0_VALID, eq->w0));
>>> + addr = ((((uint64_t)be32_to_cpu(eq->w2)) & 0x0fffffff) << 32) | be32_to_cpu(eq->w3);
>>
>> This deserves a helper like in QEMU :
>>
>> static inline uint64_t xive_end_qaddr(XiveEND *end)
>> {
>> return ((uint64_t) be32_to_cpu(end->w2) & 0x0fffffff) << 32 |
>> be32_to_cpu(end->w3);
>> }
>
> Sure. That can be done before or after as well.
>
>>> - eq_blk = vp->w1 >> 28;
>>> - eq_idx = vp->w1 & 0x0fffffff;
>>> + eq_blk = be32_to_cpu(vp->w1) >> 28;
>>> + eq_idx = be32_to_cpu(vp->w1) & 0x0fffffff;
>>
>>
>> These are not architected fields but we should add defines. It can come later.
>
>>> + if (xive_get_field32(EQ_W0_ENQUEUE, eq->w0))
>>> + *out_qpage = cpu_to_be64(((uint64_t)xive_get_field32(EQ_W2_OP_DESC_HI, eq->w2) << 32) | be32_to_cpu(eq->w3));
>>
>> we need a helper.
>
>>> *out_qeoi_page =
>>> - (uint64_t)x->eq_mmio + idx * 0x20000;
>>> + cpu_to_be64((uint64_t)x->eq_mmio + idx * 0x20000);
>>
>> There are plenty of 0x10000 values in the code and it would be clearer to use
>> XIVE_PAGE_SIZE or OPAL_PAGE_SIZE. Something for later.
>
>>> - eq_blk = vp->w1 >> 28;
>>> - eq_idx = vp->w1 & 0x0fffffff;
>>> + eq_blk = be32_to_cpu(vp->w1) >> 28;
>>> + eq_idx = be32_to_cpu(vp->w1) & 0x0fffffff;
>>
>> we need a helper for the END base. Later.
>
> So there's a bunch of other small tidy-ups to do, sounds like most
> you are happy to go afterward?
yes. This is not problematic.
Reviewed-by: Cédric Le Goater <clg at kaod.org>
C.
>
> Thanks,
> Nick
>
More information about the Skiboot
mailing list