119 lines
2.7 KiB
C
119 lines
2.7 KiB
C
|
|
#include <stdio.h>
|
||
|
|
#include <drivers/irq.h>
|
||
|
|
|
||
|
|
#include <mm/pmm.h>
|
||
|
|
#include <mm/paging.h>
|
||
|
|
|
||
|
|
#include <tty.h>
|
||
|
|
|
||
|
|
#include <drivers/serio.h>
|
||
|
|
|
||
|
|
#include <kernel/syscall.h>
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
Espresso has two types of syscalls.
|
||
|
|
|
||
|
|
one: int 16, the only one I've worked on. should be able to be used in kernel code and user-space.
|
||
|
|
two: syscall/sysenter, the ones I haven't worked on because it has to do with userspace code.
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
NOTE: passing arguments to fuctions
|
||
|
|
to pass args to functions, use all registers except eax,
|
||
|
|
so ebx is arg0, ecx arg1, edx arg2, esi arg3, edi arg4, ebp arg5
|
||
|
|
*/
|
||
|
|
|
||
|
|
void init_sysints(void)
|
||
|
|
{
|
||
|
|
/* actually nothing to do */
|
||
|
|
|
||
|
|
set_irq_handler(16, (irq_func_t) int16_handler);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 0 in eax means success most of the time */
|
||
|
|
registers_t* int16_handler(registers_t* regs)
|
||
|
|
{
|
||
|
|
//printf("eax: %0x%x\n", regs->eax);
|
||
|
|
|
||
|
|
uint32_t eax = regs->eax;
|
||
|
|
|
||
|
|
if (eax >= __ENUM_END_MARKER__)
|
||
|
|
{
|
||
|
|
printf("Invalid system call %i\n", eax);
|
||
|
|
return regs;
|
||
|
|
}
|
||
|
|
|
||
|
|
switch (eax)
|
||
|
|
{
|
||
|
|
case SYS_MAP_PAGE:
|
||
|
|
map_page((void*) regs->ebx, (void*) regs->ecx);
|
||
|
|
break;
|
||
|
|
case SYS_PMM_ALLOC_PAGE:
|
||
|
|
eax = (uint32_t) pmm_alloc_page();
|
||
|
|
break;
|
||
|
|
case SYS_PMM_FREE_PAGE:
|
||
|
|
pmm_free_page((void*) regs->ebx);
|
||
|
|
break;
|
||
|
|
case SYS_SERIAL_WRITE:
|
||
|
|
serial_write(regs->ebx);
|
||
|
|
break;
|
||
|
|
case SYS_SERIAL_READ:
|
||
|
|
eax = serial_read();
|
||
|
|
break;
|
||
|
|
case SYS_SERIAL_PUTS:
|
||
|
|
serial_puts((const char*) regs->ebx);
|
||
|
|
break;
|
||
|
|
case SYS_USE_SERIAL:
|
||
|
|
eax = use_serial();
|
||
|
|
break;
|
||
|
|
case SYS_TERMINAL_SCROLL:
|
||
|
|
terminal_scroll();
|
||
|
|
break;
|
||
|
|
case SYS_TERMINAL_CLEAR:
|
||
|
|
terminal_clear();
|
||
|
|
break;
|
||
|
|
case SYS_TERMINAL_SET_CURSOR:
|
||
|
|
terminal_set_cursor(regs->ebx, regs->ecx);
|
||
|
|
break;
|
||
|
|
case SYS_TERMINAL_GET_CURSOR:
|
||
|
|
terminal_get_cursor((int*) regs->ebx, (int*) regs->ecx);
|
||
|
|
break;
|
||
|
|
case SYS_TERMINAL_WRITE:
|
||
|
|
terminal_write((const char*) regs->ebx, regs->ecx);
|
||
|
|
break;
|
||
|
|
case SYS_TERMINAL_WRITESTRING:
|
||
|
|
terminal_writestring((const char*) regs->ebx);
|
||
|
|
break;
|
||
|
|
case SYS_TERMINAL_DEBUG_WRITESTRING:
|
||
|
|
terminal_debug_writestring((const char*) regs->ebx);
|
||
|
|
break;
|
||
|
|
case SYS_TERMINAL_PUTCHAR:
|
||
|
|
terminal_putchar(regs->ebx);
|
||
|
|
break;
|
||
|
|
case SYS_TERMINAL_PUTENTRYAT:
|
||
|
|
terminal_putentryat(regs->ebx, regs->ecx, regs->edx, regs->esi);
|
||
|
|
break;
|
||
|
|
case SYS_TERMINAL_GETCOLOR:
|
||
|
|
eax = terminal_getcolor();
|
||
|
|
break;
|
||
|
|
case SYS_TERMINAL_SETCOLOR:
|
||
|
|
terminal_setcolor(regs->ebx);
|
||
|
|
break;
|
||
|
|
case SYS_READ:
|
||
|
|
eax = read(regs->ebx, (void*) regs->ecx, regs->edx);
|
||
|
|
break;
|
||
|
|
case SYS_WRITE:
|
||
|
|
eax = write(regs->ebx, (void*) regs->ecx, regs->edx);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
printf("nothing happened.\n");
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
regs->eax = eax;
|
||
|
|
|
||
|
|
return regs;
|
||
|
|
}
|