sos-code-article7/sos/syscall.c

143 lines
3.3 KiB
C

/* Copyright (C) 2005 David Decotigny
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA.
*/
#include <sos/thread.h>
#include <sos/kmalloc.h>
#include <sos/klibc.h>
#include <drivers/bochs.h>
#include <hwcore/cpu_context.h>
#include <sos/uaccess.h>
#include "syscall.h"
/**
* THE syscall entry point
*/
sos_ret_t sos_do_syscall(int syscall_id,
const struct sos_cpu_state *user_ctxt)
{
sos_ret_t retval;
switch(syscall_id)
{
case SOS_SYSCALL_ID_EXIT:
{
unsigned int status;
retval = sos_syscall_get1arg(user_ctxt, & status);
if (SOS_OK != retval)
break;
sos_thread_exit();
retval = -SOS_EFATAL; /* Not reached */
}
break;
case SOS_SYSCALL_ID_BOCHS_WRITE:
{
sos_uaddr_t user_str;
sos_size_t len;
char * str;
retval = sos_syscall_get2args(user_ctxt, & user_str, & len);
if (SOS_OK != retval)
break;
str = (char*)sos_kmalloc(len + 1, 0);
if (str)
{
retval = sos_strzcpy_from_user(str, user_str, len+1);
str[len] = '\0';
if (SOS_OK == retval)
{
sos_bochs_printf("THR 0x%x: ",
(unsigned)sos_thread_get_current());
retval = sos_bochs_putstring(str);
retval = len;
}
sos_kfree((sos_vaddr_t)str);
}
else
retval = -SOS_ENOMEM;
}
break;
/* ***********************************************
* Debug syscalls (will be removed in the future)
*/
/**
* Syscall 4012: hexdump of a user-space memory region
* args: addr_start size, retval=ignored
*/
case 4012:
{
sos_uaddr_t user_str;
unsigned int len;
unsigned char * str;
retval = sos_syscall_get2args(user_ctxt, & user_str, & len);
if (SOS_OK != retval)
break;
str = (char*)sos_kmalloc(len + 1, 0);
if (str)
{
int i;
sos_bochs_printf("Hexdump(0x%x, %d):\n", user_str, len);
retval = sos_memcpy_from_user((sos_vaddr_t) str, user_str, len);
sos_bochs_printf(" (Successfully copied %d out of %d)\n",
retval, len);
for (i = 0 ; i < retval ; i++)
{
if ((i % 32) == 0)
sos_bochs_printf("%x:", i);
sos_bochs_printf(" %x", str[i]);
if (((i+1) % 32) == 0)
sos_bochs_printf("\n");
}
if (i % 32)
sos_bochs_printf("\n");
sos_kfree((sos_vaddr_t)str);
}
else
retval = -SOS_ENOMEM;
}
break;
/**
* Syscall 4008: dump the list of processes in the system
* args: none, retval=ignored
*/
case 4008:
{
extern void sos_process_dumplist(void);
sos_process_dumplist();
retval = SOS_OK;
}
break;
default:
sos_bochs_printf("Syscall: UNKNOWN[%d]\n", syscall_id);
retval = -SOS_ENOSUP;
}
return retval;
}