staticvoid __pack(void *pbuf, u64 uval, size_t startbit, size_t endbit,
size_t pbuflen, u8 quirks)
{ /* Logical byte indices corresponding to the *startandendofthefield.
*/ int plogical_first_u8 = startbit / BITS_PER_BYTE; int plogical_last_u8 = endbit / BITS_PER_BYTE; int value_width = startbit - endbit + 1; int box;
/* Check if "uval" fits in "value_width" bits. *Thetestonlyworksforvalue_width<64,butinthelattercase, *any64-bituvalwillsurelyfit.
*/
WARN(value_width < 64 && uval >= (1ull << value_width), "Cannot store 0x%llx inside bits %zu-%zu - will truncate\n",
uval, startbit, endbit);
/* Iterate through an idealistic view of the pbuf as an u64 with *noquirks,u8byu8(alignedatu8boundaries),fromhightolow *logicalbitsignificance."box"denotesthecurrentlogicalu8.
*/ for (box = plogical_first_u8; box >= plogical_last_u8; box--) { /* Bit indices into the currently accessed 8-bit box */
size_t box_start_bit, box_end_bit, box_addr;
u8 box_mask; /* Corresponding bits from the unpacked u64 parameter */
size_t proj_start_bit, proj_end_bit;
u64 proj_mask;
u64 pval;
/* This u8 may need to be accessed in its entirety *(frombit7tobit0),ornot,dependingonthe *inputargumentsstartbitandendbit.
*/ if (box == plogical_first_u8)
box_start_bit = startbit % BITS_PER_BYTE; else
box_start_bit = 7; if (box == plogical_last_u8)
box_end_bit = endbit % BITS_PER_BYTE; else
box_end_bit = 0;
/* We have determined the box bit start and end. *Nowwecalculatewherethis(masked)u8boxwouldfit *intheunpacked(CPU-readable)u64-theu8box's *projectionontotheunpackedu64.Thoughthe *boxisu8,theprojectionisu64becauseitmayfall *anywherewithintheunpackedu64.
*/
proj_start_bit = ((box * BITS_PER_BYTE) + box_start_bit) - endbit;
proj_end_bit = ((box * BITS_PER_BYTE) + box_end_bit) - endbit;
proj_mask = GENMASK_ULL(proj_start_bit, proj_end_bit);
box_mask = GENMASK(box_start_bit, box_end_bit);
/* Determine the offset of the u8 box inside the pbuf, *adjustedforquirks.Theadjustedbox_addrwillbeusedfor *effectiveaddressinginsidethepbuf(soit'snot *logicalanylonger).
*/
box_addr = calculate_box_addr(box, pbuflen, quirks);
/* Write to pbuf, read from uval */
pval = uval & proj_mask;
pval >>= proj_end_bit;
pval <<= box_end_bit;
staticvoid __unpack(constvoid *pbuf, u64 *uval, size_t startbit, size_t endbit,
size_t pbuflen, u8 quirks)
{ /* Logical byte indices corresponding to the *startandendofthefield.
*/ int plogical_first_u8 = startbit / BITS_PER_BYTE; int plogical_last_u8 = endbit / BITS_PER_BYTE; int box;
/* Initialize parameter */
*uval = 0;
/* Iterate through an idealistic view of the pbuf as an u64 with *noquirks,u8byu8(alignedatu8boundaries),fromhightolow *logicalbitsignificance."box"denotesthecurrentlogicalu8.
*/ for (box = plogical_first_u8; box >= plogical_last_u8; box--) { /* Bit indices into the currently accessed 8-bit box */
size_t box_start_bit, box_end_bit, box_addr;
u8 box_mask; /* Corresponding bits from the unpacked u64 parameter */
size_t proj_start_bit, proj_end_bit;
u64 proj_mask;
u64 pval;
/* This u8 may need to be accessed in its entirety *(frombit7tobit0),ornot,dependingonthe *inputargumentsstartbitandendbit.
*/ if (box == plogical_first_u8)
box_start_bit = startbit % BITS_PER_BYTE; else
box_start_bit = 7; if (box == plogical_last_u8)
box_end_bit = endbit % BITS_PER_BYTE; else
box_end_bit = 0;
/* We have determined the box bit start and end. *Nowwecalculatewherethis(masked)u8boxwouldfit *intheunpacked(CPU-readable)u64-theu8box's *projectionontotheunpackedu64.Thoughthe *boxisu8,theprojectionisu64becauseitmayfall *anywherewithintheunpackedu64.
*/
proj_start_bit = ((box * BITS_PER_BYTE) + box_start_bit) - endbit;
proj_end_bit = ((box * BITS_PER_BYTE) + box_end_bit) - endbit;
proj_mask = GENMASK_ULL(proj_start_bit, proj_end_bit);
box_mask = GENMASK(box_start_bit, box_end_bit);
/* Determine the offset of the u8 box inside the pbuf, *adjustedforquirks.Theadjustedbox_addrwillbeusedfor *effectiveaddressinginsidethepbuf(soit'snot *logicalanylonger).
*/
box_addr = calculate_box_addr(box, pbuflen, quirks);
/* Read from pbuf, write to uval */
pval = ((u8 *)pbuf)[box_addr];
if (quirks & QUIRK_MSB_ON_THE_RIGHT)
pval = bitrev8(pval);
/** *unpack-Unpacku64numberfrompackedbuffer. * *@pbuf:Pointertoabufferholdingthepackedvalue. *@uval:Pointertoanu64holdingtheunpackedvalue. *@startbit:Theindex(inlogicalnotation,compensatedforquirks)where *thepackedvaluestartswithinpbuf.Mustbelargerthan,or *equalto,endbit. *@endbit:Theindex(inlogicalnotation,compensatedforquirks)where *thepackedvalueendswithinpbuf.Mustbesmallerthan,orequal *to,startbit. *@pbuflen:Thelengthinbytesofthepackedbufferpointedtoby@pbuf. *@quirks:AbitmaskofQUIRK_LITTLE_ENDIAN,QUIRK_LSW32_IS_FIRSTand *QUIRK_MSB_ON_THE_RIGHT. * *Return:0onsuccess,EINVALorERANGEifcalledincorrectly.Assuming *correctusage,returncodemaybediscarded.The@uvalwillbe *modifiedonsuccess.
*/ int unpack(constvoid *pbuf, u64 *uval, size_t startbit, size_t endbit,
size_t pbuflen, u8 quirks)
{ /* width of the field to access in the pbuf */
u64 value_width;
/* startbit is expected to be larger than endbit, and both are *expectedtobewithinthelogicallyaddressablerangeofthebuffer.
*/ if (startbit < endbit || startbit >= BITS_PER_BYTE * pbuflen) /* Invalid function call */ return -EINVAL;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.