Skip to content

Commit

Permalink
hw/intc/arm_gicv3: Use bitops.h uint32_t bit array functions
Browse files Browse the repository at this point in the history
Now we have official uint32_t bit array functions in bitops.h, use
them instead of the hand-rolled local versions.

We retain gic_bmp_replace_bit() because bitops doesn't provide that
specific functionality.

Signed-off-by: Peter Maydell <[email protected]>
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
Message-id: [email protected]
  • Loading branch information
pm215 committed Nov 19, 2024
1 parent 3d7680f commit e05ebbd
Showing 1 changed file with 14 additions and 40 deletions.
54 changes: 14 additions & 40 deletions include/hw/intc/arm_gicv3_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,53 +51,27 @@
/* Maximum number of list registers (architectural limit) */
#define GICV3_LR_MAX 16

/* For some distributor fields we want to model the array of 32-bit
/*
* For some distributor fields we want to model the array of 32-bit
* register values which hold various bitmaps corresponding to enabled,
* pending, etc bits. These macros and functions facilitate that; the
* APIs are generally modelled on the generic bitmap.h functions
* (which are unsuitable here because they use 'unsigned long' as the
* underlying storage type, which is very awkward when you need to
* access the data as 32-bit values.)
* pending, etc bits. We use the set_bit32() etc family of functions
* from bitops.h for this. For a few cases we need to implement some
* extra operations.
*
* Each bitmap contains a bit for each interrupt. Although there is
* space for the PPIs and SGIs, those bits (the first 32) are never
* used as that state lives in the redistributor. The unused bits are
* provided purely so that interrupt X's state is always in bit X; this
* avoids bugs where we forget to subtract GIC_INTERNAL from an
* interrupt number.
*/
#define GICV3_BMP_SIZE DIV_ROUND_UP(GICV3_MAXIRQ, 32)

#define GIC_DECLARE_BITMAP(name) \
uint32_t name[GICV3_BMP_SIZE]

#define GIC_BIT_MASK(nr) (1U << ((nr) % 32))
#define GIC_BIT_WORD(nr) ((nr) / 32)

static inline void gic_bmp_set_bit(int nr, uint32_t *addr)
{
uint32_t mask = GIC_BIT_MASK(nr);
uint32_t *p = addr + GIC_BIT_WORD(nr);

*p |= mask;
}

static inline void gic_bmp_clear_bit(int nr, uint32_t *addr)
{
uint32_t mask = GIC_BIT_MASK(nr);
uint32_t *p = addr + GIC_BIT_WORD(nr);

*p &= ~mask;
}

static inline int gic_bmp_test_bit(int nr, const uint32_t *addr)
{
return 1U & (addr[GIC_BIT_WORD(nr)] >> (nr & 31));
}
#define GIC_DECLARE_BITMAP(name) DECLARE_BITMAP32(name, GICV3_MAXIRQ)
#define GICV3_BMP_SIZE BITS_TO_U32S(GICV3_MAXIRQ)

static inline void gic_bmp_replace_bit(int nr, uint32_t *addr, int val)
{
uint32_t mask = GIC_BIT_MASK(nr);
uint32_t *p = addr + GIC_BIT_WORD(nr);
uint32_t mask = BIT32_MASK(nr);
uint32_t *p = addr + BIT32_WORD(nr);

*p &= ~mask;
*p |= (val & 1U) << (nr % 32);
Expand All @@ -106,7 +80,7 @@ static inline void gic_bmp_replace_bit(int nr, uint32_t *addr, int val)
/* Return a pointer to the 32-bit word containing the specified bit. */
static inline uint32_t *gic_bmp_ptr32(uint32_t *addr, int nr)
{
return addr + GIC_BIT_WORD(nr);
return addr + BIT32_WORD(nr);
}

typedef struct GICv3State GICv3State;
Expand Down Expand Up @@ -301,15 +275,15 @@ struct GICv3State {
#define GICV3_BITMAP_ACCESSORS(BMP) \
static inline void gicv3_gicd_##BMP##_set(GICv3State *s, int irq) \
{ \
gic_bmp_set_bit(irq, s->BMP); \
set_bit32(irq, s->BMP); \
} \
static inline int gicv3_gicd_##BMP##_test(GICv3State *s, int irq) \
{ \
return gic_bmp_test_bit(irq, s->BMP); \
return test_bit32(irq, s->BMP); \
} \
static inline void gicv3_gicd_##BMP##_clear(GICv3State *s, int irq) \
{ \
gic_bmp_clear_bit(irq, s->BMP); \
clear_bit32(irq, s->BMP); \
} \
static inline void gicv3_gicd_##BMP##_replace(GICv3State *s, \
int irq, int value) \
Expand Down

0 comments on commit e05ebbd

Please sign in to comment.