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:
X512
2022-12-11 18:43:15 +00:00
committed by Alex von Gluck IV
parent 09b2fc9e11
commit fa557843f2
14 changed files with 148 additions and 236 deletions
+3 -10
View File
@@ -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);
}
+4 -11
View File
@@ -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;
}