[Skiboot] [EXTERNAL] [PATCH v6 13/29] xive: make endian-clean
Nicholas Piggin
npiggin at gmail.com
Thu Nov 7 21:29:39 AEDT 2019
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?
Thanks,
Nick
More information about the Skiboot
mailing list