2

when I read SYSTEMC code,I find a function return int like this:

static inline int rp_get_busaccess_response(struct rp_pkt *pkt)
{
    return (pkt->busaccess_ext_base.attributes & RP_BUS_RESP_MASK) >>
                                                            RP_BUS_RESP_SHIFT;
}

pkt->busaccess_ext_base.attributes defined as uint64_t.

RP_BUS_RESP_MASK and RP_BUS_RESP_SHIFT defined as:

enum {
    RP_RESP_OK                  =  0x0,
    RP_RESP_BUS_GENERIC_ERROR   =  0x1,
    RP_RESP_ADDR_ERROR          =  0x2,
    RP_RESP_MAX                 =  0xF,
};
enum {
    RP_BUS_RESP_SHIFT    =  8,
    RP_BUS_RESP_MASK     =  (RP_RESP_MAX << RP_BUS_RESP_SHIFT),
};

What the meaning of this function's return?

Thanks!

6
  • 2
    & is bitwise AND operator, and >> is right shift operator. Next step, use a pen and paper to calculate. Commented Jan 9, 2023 at 10:03
  • 2
    It's a bitmask operation followed by a bitshift operation. Commented Jan 9, 2023 at 10:03
  • 2
    It extracts a number of bits (4) from pkt->busaccess_ext_base.attributes and shift them down to start at bit position zero. Seems it extracts bit[11:8] Commented Jan 9, 2023 at 10:04
  • 1
    This is a very generic way of working with hardware registers. Normally these are squashed with multiple values of various things into a single register. Here, in your case, you obtain some kind of bus response status. To obtain the status value you mask the register to leave only bits of the actual status, and then shift it to make the value usable in your program logic. Commented Jan 9, 2023 at 10:12
  • 1
    @SupportUkraine It extracts a number of bits (4)... But be careful with enum bit values. If the enum is signed (implementation-defined) and the input value is negative, the results of a right shift are implementation-defined. Using enum for bit values that will be shifted can be dangerous if care is not taken. You might get more bits set than you thought you would - or even could. Commented Jan 9, 2023 at 11:39

2 Answers 2

2

a & b is a bitwise operation, this will perform a logical AND to each pair of bits, let's say you have 262 & 261 this will translate to 100000110 & 100000101 the result will be 100000100 (260), the logic behind the result is that each 1 AND 1 will result in 1 whereas 1 AND 0 and 0 AND 0 will result in 0, these are normal logical operations but are performed at bit level:

  100000110
& 100000101
-----------
  100000100

In (a & b) >> c, >> will shift the bits of the resulting value of a & b to the right by c positions. For example for the previous result 100000100 and having a c value of 8, all bits will shift to the right by 8, and the result is 000000001. The left most 1 bit in the original value will become the first most right whereas the third 1 bit from the right in the original value will be shifted away.

With this knowledge in mind and looking at the function, we can see that the RP_BUS_RESP_MASK constant is a mask that protects the field of bits from 9th through 12th position(from the right, i.e. the first four bits of the second byte), setting them to 1 (RP_RESP_MAX << RP_BUS_RESP_SHIFT which translates to 1111 << 8 resulting in 111100000000), this will preserve the bit values in that range. Then it sets the other bits of pkt->busaccess_ext_base.attributes to 0 when it performs the bitwise & against this mask. Finally it shifts this field to the right by RP_BUS_RESP_SHIFT(8).

It basically extracts the the first four bits in the second byte of kt->busaccess_ext_base.attributes and returns the result as an integer.

What it's for specifically? You must consult the documentation if it exists or try to understand its use in the global context, for what I can see this belongs to LibSystemCTLM-SoC (In case you didn't know)

Sign up to request clarification or add additional context in comments.

Comments

2

The function extracts the first 4-Bit of the second byte of the 8-Byte (64-Bit) Attribute. This means, it extracts the following 4-Bits of the Attribute 0xFFFF FFFF FFFFF FAFF resulting in 0x0A

  • First it creates the mask, which is RP_BUS_RESP_MASK = 0x0F00
  • Next it applies the mask to the attribute pkt->busaccess_ext_base.attributes & 0x0F00 resulting in 0x0A00 from the example
  • Next it shifts A by 8-Bit to the right side, leading to 0x0A

4 Comments

Shift is 8 bits, not 16: 0xFFFF FFFF FFFF FAFF
thats of curse correct, I changed the initial post.
Next it shifts A by 8-Bit to the right side. Sorry for nitpicking :D Will give you +1 once fixed.
ah, damn, I was thinking it to the right direction.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.