#define VPIC_PRIO_NONE 8
static int vpic_get_priority(struct hvm_hw_vpic *vpic, uint8_t mask)
{
- int prio;
-
ASSERT(vpic_is_locked(vpic));
if ( mask == 0 )
return VPIC_PRIO_NONE;
- /* prio = ffs(mask ROR vpic->priority_add); */
- asm ( "ror %%cl,%b1 ; rep; bsf %1,%0"
- : "=r" (prio) : "q" ((uint32_t)mask), "c" (vpic->priority_add) );
- return prio;
+ /*
+ * We use __builtin_ctz() rather than ffs() because the compiler can't
+ * reason that a nonzero mask rotated is still nonzero.
+ */
+ return __builtin_ctz(ror8(mask, vpic->priority_add));
}
/* Return the PIC's highest priority pending interrupt. Return -1 if none. */
{
if ( val & 0x10 )
{
- unsigned int pending = vpic->isr | (vpic->irr & ~vpic->elcr);
+ uint8_t pending = vpic->isr | (vpic->irr & ~vpic->elcr);
/* ICW1 */
/* Clear edge-sensing logic. */
* been cleared from IRR or ISR, or else the dpci logic will get
* out of sync with the state of the interrupt controller.
*/
- while ( pending )
- {
- unsigned int pin = __scanbit(pending, 8);
-
- ASSERT(pin < 8);
+ for_each_set_bit ( pin, pending )
hvm_dpci_eoi(current->domain,
hvm_isa_irq_to_gsi((addr >> 7) ? (pin | 8) : pin));
- __clear_bit(pin, &pending);
- }
return;
}
else if ( val & 0x08 )
return (word << shift) | (word >> (32 - shift));
}
+/* ror8 - rotate an 8-bit value right */
+static inline uint8_t ror8(uint8_t value, unsigned int shift)
+{
+ return (value >> shift) | (value << (8 - shift));
+}
+
/*
* ror32 - rotate a 32-bit value right
*