arm64: Add exception handling, handle pagetables access and dirty flags.

Change-Id: I751d78eb458da16098d236f3829d0c26540fbc17
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5264
Reviewed-by: Adrien Destugues <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
milek7
2022-05-29 18:51:32 +00:00
committed by waddlesplash
parent 78ea9ffc9b
commit d1c3213a6d
7 changed files with 562 additions and 39 deletions
+26 -6
View File
@@ -110,46 +110,66 @@ arm64_address_translate_ ##stage (uint64 addr) \
return (ret); \
}
ADDRESS_TRANSLATE_FUNC(s1e0r)
ADDRESS_TRANSLATE_FUNC(s1e0w)
ADDRESS_TRANSLATE_FUNC(s1e1r)
ADDRESS_TRANSLATE_FUNC(s1e1w)
struct aarch64_fpu_state
{
uint64 regs[32 * 2];
uint64 fpsr;
uint64 fpcr;
};
/* raw exception frames */
struct iframe {
uint64 sp;
uint64 lr;
uint64 elr;
uint32 spsr;
uint32 esr;
uint64 x[30];
// return info
uint64 elr;
uint64 spsr;
uint64 x[20];
uint64 lr;
uint64 sp;
// exception info
uint64 esr;
uint64 far;
};
#ifdef __cplusplus
namespace BKernel {
struct Thread;
} // namespace BKernel
typedef struct arch_cpu_info {
uint32 mpidr;
BKernel::Thread* last_vfp_user;
} arch_cpu_info;
#endif
#ifdef __cplusplus
extern "C" {
#endif
static inline void arch_cpu_pause(void)
{
arm64_yield();
}
static inline void arch_cpu_idle(void)
{
arm64_yield();
}
#ifdef __cplusplus
}
#endif
+6 -13
View File
@@ -15,7 +15,7 @@
static inline void
arch_int_enable_interrupts_inline(void)
{
__asm__ __volatile__("msr daifclr, #2");
asm volatile("msr daifclr, #0xf" : : : "memory");
}
@@ -24,10 +24,7 @@ arch_int_disable_interrupts_inline(void)
{
uint32 flags;
__asm__ __volatile__(
"mrs %0, daif\n\t"
"msr daifset, #2\n\t"
: "=&r"(flags));
asm volatile("mrs %0, daif\n" "msr daifset, #0xf" : "=r"(flags) : : "memory");
return flags;
}
@@ -36,22 +33,17 @@ arch_int_disable_interrupts_inline(void)
static inline void
arch_int_restore_interrupts_inline(int oldState)
{
WRITE_SPECIALREG(daif, oldState);
asm volatile("msr daif, %0" : : "r"(oldState) : "memory");
}
static inline bool
arch_int_are_interrupts_enabled_inline(void)
{
uint32 flags;
__asm__ __volatile__(
"mrs %0, daif\n\t"
: "=&r"(flags));
return (flags & PSR_I) == 0;
return (READ_SPECIALREG(DAIF) & PSR_I) == 0;
}
// map the functions to the inline versions
#define arch_int_enable_interrupts() arch_int_enable_interrupts_inline()
#define arch_int_disable_interrupts() arch_int_disable_interrupts_inline()
@@ -60,4 +52,5 @@ arch_int_are_interrupts_enabled_inline(void)
#define arch_int_are_interrupts_enabled() \
arch_int_are_interrupts_enabled_inline()
#endif /* _KERNEL_ARCH_ARM64_ARCH_INT_H_ */