riscv: use atomic CSR bit set/clear operations, refactor
Fix race conditions that cause broken timer interrupts. Change-Id: I78e13a18d394b1566977e894a1def16a66c9ca5f Reviewed-on: https://review.haiku-os.org/c/haiku/+/5883 Reviewed-by: X512 <[email protected]> Reviewed-by: Alex von Gluck IV <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
@@ -19,28 +19,21 @@
|
||||
static inline bool
|
||||
get_ac()
|
||||
{
|
||||
SstatusReg status(Sstatus());
|
||||
return status.sum != 0;
|
||||
return SstatusReg{.val = Sstatus()}.sum;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
set_ac()
|
||||
{
|
||||
// TODO: Could be done atomically via CSRRS?
|
||||
SstatusReg status(Sstatus());
|
||||
status.sum = 1;
|
||||
SetSstatus(status.val);
|
||||
SetBitsSstatus(SstatusReg{.sum = 1}.val);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
clear_ac()
|
||||
{
|
||||
// TODO: Could be done atomically with CSRRC?
|
||||
SstatusReg status(Sstatus());
|
||||
status.sum = 0;
|
||||
SetSstatus(status.val);
|
||||
ClearBitsSstatus(SstatusReg{.sum = 1}.val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,22 +20,15 @@
|
||||
static inline void
|
||||
arch_int_enable_interrupts_inline(void)
|
||||
{
|
||||
// TODO: Use atomic CSRRS?
|
||||
SstatusReg status(Sstatus());
|
||||
status.ie |= (1 << modeS);
|
||||
SetSstatus(status.val);
|
||||
SetBitsSstatus(SstatusReg{.ie = 1 << modeS}.val);
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
arch_int_disable_interrupts_inline(void)
|
||||
{
|
||||
// TODO: Use atomic CSRRC?
|
||||
SstatusReg status(Sstatus());
|
||||
int oldState = ((1 << modeS) & status.ie) != 0;
|
||||
status.ie &= ~(1 << modeS);
|
||||
SetSstatus(status.val);
|
||||
return oldState;
|
||||
SstatusReg oldStatus{.val = GetAndClearBitsSstatus(SstatusReg{.ie = 1 << modeS}.val)};
|
||||
return ((1 << modeS) & oldStatus.ie) != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +43,7 @@ arch_int_restore_interrupts_inline(int oldState)
|
||||
static inline bool
|
||||
arch_int_are_interrupts_enabled_inline(void)
|
||||
{
|
||||
SstatusReg status(Sstatus());
|
||||
SstatusReg status{.val = Sstatus()};
|
||||
return ((1 << modeS) & status.ie) != 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user