#include <config.h>
#include <arch/kernel/traps.h>
#include <arch/object/vcpu.h>
#include <arch/machine/registerset.h>
#include <api/syscall.h>
#include <machine/fpu.h>
#include <benchmark/benchmark_track_types.h>
#include <benchmark/benchmark_track.h>
#include <benchmark/benchmark_utilisation.h>
void VISIBLE NORETURN
c_handle_undefined_instruction(void)
{
NODE_LOCK_SYS;
c_entry_hook();
#ifdef TRACK_KERNEL_ENTRIES
ksKernelEntry.path = Entry_UserLevelFault;
ksKernelEntry.word = getRegister(NODE_STATE(ksCurThread), LR_svc);
#endif
handleUserLevelFault(0, 0);
restore_user_context();
UNREACHABLE();
}
#ifdef CONFIG_HAVE_FPU
void VISIBLE NORETURN
c_handle_enfp(void)
{
c_entry_hook();
handleFPUFault();
restore_user_context();
UNREACHABLE();
}
#endif
static inline void NORETURN
c_handle_vm_fault(vm_fault_type_t type)
{
NODE_LOCK_SYS;
c_entry_hook();
#ifdef TRACK_KERNEL_ENTRIES
ksKernelEntry.path = Entry_VMFault;
ksKernelEntry.word = getRegister(NODE_STATE(ksCurThread), LR_svc);
#endif
handleVMFaultEvent(type);
restore_user_context();
UNREACHABLE();
}
void VISIBLE NORETURN
c_handle_data_fault(void)
{
c_handle_vm_fault(seL4_DataFault);
}
void VISIBLE NORETURN
c_handle_instruction_fault(void)
{
c_handle_vm_fault(seL4_InstructionFault);
}
void VISIBLE NORETURN
c_handle_interrupt(void)
{
NODE_LOCK_IRQ_IF(getActiveIRQ() != irq_remote_call_ipi);
c_entry_hook();
#ifdef TRACK_KERNEL_ENTRIES
ksKernelEntry.path = Entry_Interrupt;
ksKernelEntry.word = getActiveIRQ();
#endif
handleInterruptEntry();
restore_user_context();
}
void NORETURN
slowpath(syscall_t syscall)
{
#ifdef TRACK_KERNEL_ENTRIES
ksKernelEntry.is_fastpath = 0;
#endif
handleSyscall(syscall);
restore_user_context();
UNREACHABLE();
}
void VISIBLE
c_handle_syscall(word_t cptr, word_t msgInfo, syscall_t syscall)
{
NODE_LOCK_SYS;
c_entry_hook();
#if TRACK_KERNEL_ENTRIES
benchmark_debug_syscall_start(cptr, msgInfo, syscall);
ksKernelEntry.is_fastpath = 1;
#endif
#ifdef CONFIG_FASTPATH
if (syscall == SysCall) {
fastpath_call(cptr, msgInfo);
UNREACHABLE();
} else if (syscall == SysReplyRecv) {
fastpath_reply_recv(cptr, msgInfo);
UNREACHABLE();
}
#endif
if (unlikely(syscall < SYSCALL_MIN || syscall > SYSCALL_MAX)) {
#ifdef TRACK_KERNEL_ENTRIES
ksKernelEntry.path = Entry_UnknownSyscall;
#endif
handleUnknownSyscall(syscall);
restore_user_context();
UNREACHABLE();
} else {
slowpath(syscall);
UNREACHABLE();
}
}
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
VISIBLE NORETURN void
c_handle_vcpu_fault(word_t hsr)
{
c_entry_hook();
#ifdef TRACK_KERNEL_ENTRIES
ksKernelEntry.path = Entry_VCPUFault;
ksKernelEntry.word = hsr;
#endif
handleVCPUFault(hsr);
restore_user_context();
UNREACHABLE();
}
#endif