src/include: Add PnP/HWM unset_and_set functions
RMW (read/modify/write) ops on PnP devices has never been so simple. The semantics also allow the compiler to emit valid warnings if the input parameters would overflow, which are silenced when the cast is placed outside of the function. Change-Id: Ica01211af2a9a00aed98880844a836f6b7957b14 Signed-off-by: Angel Pons <th3fanbus@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/42134 Reviewed-by: Nico Huber <nico.h@gmx.de> Reviewed-by: Felix Held <felix-coreboot@felixheld.de> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
1502494cba
commit
64a6b6cb1f
|
@ -133,4 +133,37 @@ static inline void pnp_write_index(u16 port, u8 reg, u8 value)
|
||||||
outb(value, port + 1);
|
outb(value, port + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void pnp_unset_and_set_index(u16 port, u8 reg, u8 unset, u8 set)
|
||||||
|
* Description:
|
||||||
|
* This routine unsets and sets bits from indexed I/O registers. The
|
||||||
|
* reg byte is written to the index register at I/O address = port.
|
||||||
|
* The value byte to update is data register at I/O address = port + 1.
|
||||||
|
*
|
||||||
|
* Unlike and-then-or style operations, no bitwise negation is necessary
|
||||||
|
* to specify the bits to unset. Because the bitwise negation implicitly
|
||||||
|
* promotes operands to int before operating, one may have to explicitly
|
||||||
|
* downcast the result if the data width is smaller than that of an int.
|
||||||
|
* Since warnings are errors in coreboot, explicit casting is necessary.
|
||||||
|
*
|
||||||
|
* Performing said negation inside this routine alleviates this problem,
|
||||||
|
* while allowing the compiler to warn if the input parameters overflow.
|
||||||
|
* Casting outside this function would silence valid compiler warnings.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @param[in] u16 port = The address of the port index register.
|
||||||
|
* @param[in] u8 reg = The offset within the indexed space.
|
||||||
|
* @param[in] u8 unset = Bitmask with ones to the bits to unset from the data register.
|
||||||
|
* @param[in] u8 set = Bitmask with ones to the bits to set from the data register.
|
||||||
|
*/
|
||||||
|
static inline void pnp_unset_and_set_index(u16 port, u8 reg, u8 unset, u8 set)
|
||||||
|
{
|
||||||
|
outb(reg, port);
|
||||||
|
|
||||||
|
u8 value = inb(port + 1);
|
||||||
|
value &= (u8)~unset;
|
||||||
|
value |= set;
|
||||||
|
outb(value, port + 1);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* DEVICE_PNP_H */
|
#endif /* DEVICE_PNP_H */
|
||||||
|
|
|
@ -21,6 +21,12 @@ static __always_inline uint8_t pnp_read_config(
|
||||||
return pnp_read_index(dev >> 8, reg);
|
return pnp_read_index(dev >> 8, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __always_inline void pnp_unset_and_set_config(
|
||||||
|
pnp_devfn_t dev, uint8_t reg, uint8_t unset, uint8_t set)
|
||||||
|
{
|
||||||
|
pnp_unset_and_set_index(dev >> 8, reg, unset, set);
|
||||||
|
}
|
||||||
|
|
||||||
static __always_inline
|
static __always_inline
|
||||||
void pnp_set_logical_device(pnp_devfn_t dev)
|
void pnp_set_logical_device(pnp_devfn_t dev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,4 +45,32 @@ static inline void pnp_write_hwm5_index(u16 base, u8 reg, u8 value)
|
||||||
pnp_write_index(base + 5, reg, value);
|
pnp_write_index(base + 5, reg, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* void pnp_unset_and_set_hwm5_index(u16 base, u8 reg, u8 unset, u8 set)
|
||||||
|
* Description:
|
||||||
|
* This routine unsets and sets bits from indexed I/O registers. The
|
||||||
|
* reg byte is written to the index register at I/O address = base + 5.
|
||||||
|
* The value byte to update is data register at I/O address = base + 6.
|
||||||
|
*
|
||||||
|
* Unlike and-then-or style operations, no bitwise negation is necessary
|
||||||
|
* to specify the bits to unset. Because the bitwise negation implicitly
|
||||||
|
* promotes operands to int before operating, one may have to explicitly
|
||||||
|
* downcast the result if the data width is smaller than that of an int.
|
||||||
|
* Since warnings are errors in coreboot, explicit casting is necessary.
|
||||||
|
*
|
||||||
|
* Performing said negation inside this routine alleviates this problem,
|
||||||
|
* while allowing the compiler to warn if the input parameters overflow.
|
||||||
|
* Casting outside this function would silence valid compiler warnings.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @param[in] u16 base = The address of the base index register.
|
||||||
|
* @param[in] u8 reg = The offset within the indexed space.
|
||||||
|
* @param[in] u8 unset = Bitmask with ones to the bits to unset from the data register.
|
||||||
|
* @param[in] u8 set = Bitmask with ones to the bits to set from the data register.
|
||||||
|
*/
|
||||||
|
static inline void pnp_unset_and_set_hwm5_index(u16 base, u8 reg, u8 unset, u8 set)
|
||||||
|
{
|
||||||
|
pnp_unset_and_set_index(base + 5, reg, unset, set);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* DEVICE_PNP_HWM5_CONF_H */
|
#endif /* DEVICE_PNP_HWM5_CONF_H */
|
||||||
|
|
Loading…
Reference in New Issue