|
#include <syscall.h>
|
|
#include "../syscall-nr.h"
|
|
|
|
/* Invokes syscall NUMBER, passing no arguments, and returns the
|
|
return value as an `int'. */
|
|
#define syscall0(NUMBER) \
|
|
({ \
|
|
int retval; \
|
|
asm volatile \
|
|
("pushl %[number]; int $0x30; addl $4, %%esp" \
|
|
: "=a" (retval) \
|
|
: [number] "i" (NUMBER) \
|
|
: "memory"); \
|
|
retval; \
|
|
})
|
|
|
|
/* Invokes syscall NUMBER, passing argument ARG0, and returns the
|
|
return value as an `int'. */
|
|
#define syscall1(NUMBER, ARG0) \
|
|
({ \
|
|
int retval; \
|
|
asm volatile \
|
|
("pushl %[arg0]; pushl %[number]; int $0x30; addl $8, %%esp" \
|
|
: "=a" (retval) \
|
|
: [number] "i" (NUMBER), \
|
|
[arg0] "g" (ARG0) \
|
|
: "memory"); \
|
|
retval; \
|
|
})
|
|
|
|
/* Invokes syscall NUMBER, passing arguments ARG0 and ARG1, and
|
|
returns the return value as an `int'. */
|
|
#define syscall2(NUMBER, ARG0, ARG1) \
|
|
({ \
|
|
int retval; \
|
|
asm volatile \
|
|
("pushl %[arg1]; pushl %[arg0]; " \
|
|
"pushl %[number]; int $0x30; addl $12, %%esp" \
|
|
: "=a" (retval) \
|
|
: [number] "i" (NUMBER), \
|
|
[arg0] "g" (ARG0), \
|
|
[arg1] "g" (ARG1) \
|
|
: "memory"); \
|
|
retval; \
|
|
})
|
|
|
|
/* Invokes syscall NUMBER, passing arguments ARG0, ARG1, and
|
|
ARG2, and returns the return value as an `int'. */
|
|
#define syscall3(NUMBER, ARG0, ARG1, ARG2) \
|
|
({ \
|
|
int retval; \
|
|
asm volatile \
|
|
("pushl %[arg2]; pushl %[arg1]; pushl %[arg0]; " \
|
|
"pushl %[number]; int $0x30; addl $16, %%esp" \
|
|
: "=a" (retval) \
|
|
: [number] "i" (NUMBER), \
|
|
[arg0] "g" (ARG0), \
|
|
[arg1] "g" (ARG1), \
|
|
[arg2] "g" (ARG2) \
|
|
: "memory"); \
|
|
retval; \
|
|
})
|
|
|
|
struct syscall_args
|
|
{
|
|
int a0;
|
|
int a1;
|
|
int a2;
|
|
};
|
|
|
|
void
|
|
halt (void)
|
|
{
|
|
syscall0 (SYS_HALT);
|
|
NOT_REACHED ();
|
|
}
|
|
|
|
void
|
|
exit (int status)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) status;
|
|
syscall1 (SYS_EXIT, ag.a0);
|
|
//syscall1 (SYS_EXIT, status);
|
|
NOT_REACHED ();
|
|
}
|
|
|
|
pid_t
|
|
exec (const char *file)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) file;
|
|
return syscall1 (SYS_EXEC, ag.a0);
|
|
//return (pid_t) syscall1 (SYS_EXEC, file);
|
|
}
|
|
|
|
int
|
|
wait (pid_t pid)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) pid;
|
|
return syscall1 (SYS_WAIT, ag.a0);
|
|
//return syscall1 (SYS_WAIT, pid);
|
|
}
|
|
|
|
bool
|
|
create (const char *file, unsigned initial_size)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) file;
|
|
ag.a1 = (int) initial_size;
|
|
return syscall2 (SYS_CREATE, ag.a0, ag.a1);
|
|
//return syscall2 (SYS_CREATE, file, initial_size);
|
|
}
|
|
|
|
bool
|
|
remove (const char *file)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) file;
|
|
return syscall1 (SYS_REMOVE, ag.a0);
|
|
//return syscall1 (SYS_REMOVE, file);
|
|
}
|
|
|
|
int
|
|
open (const char *file)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) file;
|
|
return syscall1 (SYS_OPEN, ag.a0);
|
|
//return syscall1 (SYS_OPEN, file);
|
|
}
|
|
|
|
int
|
|
filesize (int fd)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) fd;
|
|
return syscall1 (SYS_FILESIZE, ag.a0);
|
|
//return syscall1 (SYS_FILESIZE, fd);
|
|
}
|
|
|
|
int
|
|
read (int fd, void *buffer, unsigned size)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) fd;
|
|
ag.a1 = (int) buffer;
|
|
ag.a2 = (int) size;
|
|
return syscall3 (SYS_READ, ag.a0, ag.a1, ag.a2);
|
|
//return syscall3 (SYS_READ, fd, buffer, size);
|
|
}
|
|
|
|
int
|
|
write (int fd, const void *buffer, unsigned size)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) fd;
|
|
ag.a1 = (int) buffer;
|
|
ag.a2 = (int) size;
|
|
return syscall3 (SYS_WRITE, ag.a0, ag.a1, ag.a2);
|
|
//return syscall3 (SYS_WRITE, fd, buffer, size);
|
|
}
|
|
|
|
void
|
|
seek (int fd, unsigned position)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) fd;
|
|
ag.a1 = (int) position;
|
|
return syscall2 (SYS_SEEK, ag.a0, ag.a1);
|
|
//syscall2 (SYS_SEEK, fd, position);
|
|
}
|
|
|
|
unsigned
|
|
tell (int fd)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) fd;
|
|
return syscall1 (SYS_TELL, ag.a0);
|
|
//return syscall1 (SYS_TELL, fd);
|
|
}
|
|
|
|
void
|
|
close (int fd)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) fd;
|
|
syscall1 (SYS_CLOSE, ag.a0);
|
|
//syscall1 (SYS_CLOSE, fd);
|
|
}
|
|
|
|
mapid_t
|
|
mmap (int fd, void *addr)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) fd;
|
|
ag.a1 = (int) addr;
|
|
return syscall2 (SYS_MMAP, ag.a0, ag.a1);
|
|
//return syscall2 (SYS_MMAP, fd, addr);
|
|
}
|
|
|
|
void
|
|
munmap (mapid_t mapid)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) mapid;
|
|
syscall1 (SYS_MUNMAP, ag.a0);
|
|
//syscall1 (SYS_MUNMAP, mapid);
|
|
}
|
|
|
|
bool
|
|
chdir (const char *dir)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) dir;
|
|
return syscall1 (SYS_CHDIR, ag.a0);
|
|
//return syscall1 (SYS_CHDIR, dir);
|
|
}
|
|
|
|
bool
|
|
mkdir (const char *dir)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) dir;
|
|
return syscall1 (SYS_MKDIR, ag.a0);
|
|
//return syscall1 (SYS_MKDIR, dir);
|
|
}
|
|
|
|
bool
|
|
readdir (int fd, char name[READDIR_MAX_LEN + 1])
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) fd;
|
|
ag.a1 = (int) name;
|
|
return syscall2 (SYS_READDIR, ag.a0, ag.a1);
|
|
//return syscall2 (SYS_READDIR, fd, name);
|
|
}
|
|
|
|
bool
|
|
isdir (int fd)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) fd;
|
|
return syscall1 (SYS_ISDIR, ag.a0);
|
|
//return syscall1 (SYS_ISDIR, fd);
|
|
}
|
|
|
|
int
|
|
inumber (int fd)
|
|
{
|
|
static struct syscall_args ag;
|
|
ag.a0 = (int) fd;
|
|
return syscall1 (SYS_INUMBER, ag.a0);
|
|
//return syscall1 (SYS_INUMBER, fd);
|
|
}
|