Files
bsb2/kernel/syscall/handler.cc
2025-11-26 09:28:41 +01:00

63 lines
1.9 KiB
C++

#include "syscall/handler.h"
#include "../arch/core.h"
#include "../arch/core_interrupt.h"
#include "../arch/gdt.h"
#include "../arch/idt.h"
#include "../debug/kernelpanic.h"
#include "../debug/output.h"
#include "../interrupt/guard.h"
#include "../syscall/skeleton.h"
#include "../syscall/stub.h"
#include "types.h"
/*! \brief Interrupt based system call entry function
*
* Low-level function written in assembly (located in `syscall/handler.asm`),
* calls \ref syscall_handler
*/
extern "C" [[gnu::interrupt]] void syscall_entry(InterruptContext *context);
namespace Syscall {
/*! \brief High level system call handler
* called by both low level handler in `syscall/handler.asm`.
*
* Processes the request by delegating it to the appropriate function identified
* by the system call number -- allowing up to five parameters for the system
* call.
*
* \param p1 first parameter
* \param p2 second parameter
* \param p3 third parameter
* \param p4 fourth parameter
* \param p5 fifth parameter
* \param sysnum identifier for the system call
* \param user pointer to the interrupt \ref context (for example to determine
* instruction pointer)
* \return system call return value
*/
extern "C" size_t syscall_handler(size_t sysnum, size_t p1, size_t p2,
size_t p3, size_t p4, size_t p5,
InterruptContext *user) {
switch ((Syscall::ID)sysnum) {
case Syscall::ID::TEST:
Syscall::Skeleton::test(Guard::enter().vault(), p1, p2, p3, p4, p5);
break;
case Syscall::ID::WRITE:
Guarded g = Guard::enter();
g.vault().kout.setPos((int)p4, (int)p5);
Syscall::Skeleton::write(g.vault(), p1, (char*)p2, p3);
break;
}
return static_cast<size_t>(-1);
}
void init() {
// Set interrupt based syscall handler
IDT::set(Core::Interrupt::Vector::SYSCALL, IDT::InterruptDescriptor::Returning(syscall_entry, 0, IDT::DPL_USER));
IDT::load();
}
} // namespace Syscall