2018-09-25 09:22:51 -07:00
|
|
|
// System call stubs.
|
|
|
|
|
|
|
|
#include <inc/syscall.h>
|
|
|
|
#include <inc/lib.h>
|
2019-04-25 17:14:57 -07:00
|
|
|
#include <inc/x86.h>
|
2018-09-25 09:22:51 -07:00
|
|
|
|
|
|
|
static inline int32_t
|
|
|
|
syscall(int num, int check, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
|
|
|
|
{
|
|
|
|
int32_t ret;
|
|
|
|
|
|
|
|
// Generic system call: pass system call number in AX,
|
|
|
|
// up to five parameters in DX, CX, BX, DI, SI.
|
|
|
|
// Interrupt kernel with T_SYSCALL.
|
|
|
|
//
|
|
|
|
// The "volatile" tells the assembler not to optimize
|
|
|
|
// this instruction away just because we don't use the
|
|
|
|
// return value.
|
|
|
|
//
|
|
|
|
// The last clause tells the assembler that this can
|
|
|
|
// potentially change the condition codes and arbitrary
|
|
|
|
// memory locations.
|
|
|
|
|
|
|
|
asm volatile("int %1\n"
|
|
|
|
: "=a" (ret)
|
|
|
|
: "i" (T_SYSCALL),
|
|
|
|
"a" (num),
|
|
|
|
"d" (a1),
|
|
|
|
"c" (a2),
|
|
|
|
"b" (a3),
|
|
|
|
"D" (a4),
|
|
|
|
"S" (a5)
|
|
|
|
: "cc", "memory");
|
|
|
|
|
|
|
|
if(check && ret > 0)
|
|
|
|
panic("syscall %d returned %d (> 0)", num, ret);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2019-04-25 17:14:57 -07:00
|
|
|
int32_t
|
|
|
|
fast_syscall(int num, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4) {
|
|
|
|
asm volatile(
|
|
|
|
"push %%ebp\n\t"
|
|
|
|
"mov %%esp, %%ebp\n\t"
|
|
|
|
"lea syscall_ret_%=, %%esi\n\t"
|
|
|
|
"sysenter\n\t"
|
|
|
|
"syscall_ret_%=: pop %%ebp\n\t"
|
|
|
|
: "+a" (num)
|
|
|
|
: "d" (a1), "c" (a2), "b" (a3), "D" (a4)
|
|
|
|
: "esi");
|
|
|
|
return num;
|
|
|
|
}
|
|
|
|
|
2018-09-25 09:22:51 -07:00
|
|
|
void
|
|
|
|
sys_cputs(const char *s, size_t len)
|
|
|
|
{
|
2019-04-25 17:14:57 -07:00
|
|
|
fast_syscall(SYS_cputs, (uint32_t)s, len, 0, 0);
|
2018-09-25 09:22:51 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
sys_cgetc(void)
|
|
|
|
{
|
2019-04-25 17:26:16 -07:00
|
|
|
return fast_syscall(SYS_cgetc, 0, 0, 0, 0);
|
2018-09-25 09:22:51 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
sys_env_destroy(envid_t envid)
|
|
|
|
{
|
|
|
|
return syscall(SYS_env_destroy, 1, envid, 0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
envid_t
|
|
|
|
sys_getenvid(void)
|
|
|
|
{
|
|
|
|
return syscall(SYS_getenvid, 0, 0, 0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
|