summaryrefslogtreecommitdiff
path: root/src/arch/sparc/linux
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-02-28 16:36:38 +0000
committerGabe Black <gblack@eecs.umich.edu>2007-02-28 16:36:38 +0000
commit29e5df890d9512a6a2c726dcb4ee46b92ac4cb22 (patch)
tree4858cf8e087521bba01ad78783a5f4a768b5ab26 /src/arch/sparc/linux
parent99948060b2863b37c0db5e6b609ff7ff30de6d1b (diff)
downloadgem5-29e5df890d9512a6a2c726dcb4ee46b92ac4cb22.tar.xz
Make trap instructions always generate TrapInstruction Fault objects which call into the Process object to handle system calls. Refactored the Process objects, and move the handler code into it's own file, and add some syscalls which are used in a natively compiled hello world. Software traps with trap number 3 (not syscall number 3) are supposed to cause the register windows to be flushed but are ignored right now. Finally, made uname for SPARC report a 2.6.12 kernel which is what m22-018.pool happens to be running.
--HG-- extra : convert_revision : ea873f01c62234c0542f310cc143c6a7c76ade94
Diffstat (limited to 'src/arch/sparc/linux')
-rw-r--r--src/arch/sparc/linux/process.cc101
-rw-r--r--src/arch/sparc/linux/process.hh55
2 files changed, 119 insertions, 37 deletions
diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc
index 565975fe0..9c7c0e643 100644
--- a/src/arch/sparc/linux/process.cc
+++ b/src/arch/sparc/linux/process.cc
@@ -54,7 +54,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
- strcpy(name->release, "2.4.20");
+ strcpy(name->release, "2.6.12");
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "sparc");
@@ -141,7 +141,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 41 */ SyscallDesc("dup", unimplementedFunc),
/* 42 */ SyscallDesc("pipe", pipePseudoFunc),
/* 43 */ SyscallDesc("times", unimplementedFunc),
- /* 44 */ SyscallDesc("getuid32", unimplementedFunc),
+ /* 44 */ SyscallDesc("getuid32", getuidFunc),
/* 45 */ SyscallDesc("umount2", unimplementedFunc),
/* 46 */ SyscallDesc("setgid", unimplementedFunc),
/* 47 */ SyscallDesc("getgid", getgidFunc),
@@ -150,7 +150,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 50 */ SyscallDesc("getegid", getegidFunc),
/* 51 */ SyscallDesc("acct", unimplementedFunc),
/* 52 */ SyscallDesc("memory_ordering", unimplementedFunc),
- /* 53 */ SyscallDesc("getgid32", unimplementedFunc),
+ /* 53 */ SyscallDesc("getgid32", getgidFunc),
/* 54 */ SyscallDesc("ioctl", unimplementedFunc),
/* 55 */ SyscallDesc("reboot", unimplementedFunc),
/* 56 */ SyscallDesc("mmap2", unimplementedFunc),
@@ -160,14 +160,14 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 60 */ SyscallDesc("umask", unimplementedFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
/* 62 */ SyscallDesc("fstat", fstatFunc<SparcLinux>),
- /* 63 */ SyscallDesc("fstat64", unimplementedFunc),
+ /* 63 */ SyscallDesc("fstat64", fstatFunc<SparcLinux>),
/* 64 */ SyscallDesc("getpagesize", unimplementedFunc),
/* 65 */ SyscallDesc("msync", unimplementedFunc),
/* 66 */ SyscallDesc("vfork", unimplementedFunc),
/* 67 */ SyscallDesc("pread64", unimplementedFunc),
/* 68 */ SyscallDesc("pwrite64", unimplementedFunc),
- /* 69 */ SyscallDesc("geteuid32", unimplementedFunc),
- /* 70 */ SyscallDesc("getdgid32", unimplementedFunc),
+ /* 69 */ SyscallDesc("geteuid32", geteuidFunc),
+ /* 70 */ SyscallDesc("getegid32", getegidFunc),
/* 71 */ SyscallDesc("mmap", mmapFunc<SparcLinux>),
/* 72 */ SyscallDesc("setreuid32", unimplementedFunc),
/* 73 */ SyscallDesc("munmap", munmapFunc),
@@ -184,7 +184,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 84 */ SyscallDesc("ftruncate64", unimplementedFunc),
/* 85 */ SyscallDesc("swapon", unimplementedFunc),
/* 86 */ SyscallDesc("getitimer", unimplementedFunc),
- /* 87 */ SyscallDesc("setuid32", unimplementedFunc),
+ /* 87 */ SyscallDesc("setuid32", setuidFunc),
/* 88 */ SyscallDesc("sethostname", unimplementedFunc),
/* 89 */ SyscallDesc("setgid32", unimplementedFunc),
/* 90 */ SyscallDesc("dup2", unimplementedFunc),
@@ -383,34 +383,79 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 283 */ SyscallDesc("keyctl", unimplementedFunc)
};
-SparcLinuxProcess::SparcLinuxProcess(const std::string &name,
- ObjectFile *objFile,
- System * system,
- int stdin_fd,
- int stdout_fd,
- int stderr_fd,
- std::vector<std::string> &argv,
- std::vector<std::string> &envp,
- const std::string &cwd,
- uint64_t _uid, uint64_t _euid,
- uint64_t _gid, uint64_t _egid,
- uint64_t _pid, uint64_t _ppid)
- : SparcLiveProcess(name, objFile, system,
- stdin_fd, stdout_fd, stderr_fd, argv, envp, cwd,
- _uid, _euid, _gid, _egid, _pid, _ppid),
- Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
+SyscallDesc*
+SparcLinuxProcess::getDesc(int callnum)
+{
+ if (callnum < 0 || callnum > Num_Syscall_Descs)
+ return NULL;
+ return &syscallDescs[callnum];
+}
+
+
+
+SparcLinuxProcess::SparcLinuxProcess() :
+ Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
{
// The sparc syscall table must be <= 284 entries because that is all there
// is space for.
assert(Num_Syscall_Descs <= 284);
}
+Sparc32LinuxProcess::Sparc32LinuxProcess(const std::string &name,
+ ObjectFile *objFile,
+ System * system,
+ int stdin_fd,
+ int stdout_fd,
+ int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ const std::string &cwd,
+ uint64_t _uid, uint64_t _euid,
+ uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid)
+ : Sparc32LiveProcess(name, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd, argv, envp, cwd,
+ _uid, _euid, _gid, _egid, _pid, _ppid)
+{}
+void Sparc32LinuxProcess::handleTrap(int trapNum, ThreadContext *tc)
+{
+ switch(trapNum)
+ {
+ case 0x10: //Linux 32 bit syscall trap
+ tc->syscall(tc->readIntReg(1));
+ break;
+ default:
+ SparcLiveProcess::handleTrap(trapNum, tc);
+ }
+}
-SyscallDesc*
-SparcLinuxProcess::getDesc(int callnum)
+Sparc64LinuxProcess::Sparc64LinuxProcess(const std::string &name,
+ ObjectFile *objFile,
+ System * system,
+ int stdin_fd,
+ int stdout_fd,
+ int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ const std::string &cwd,
+ uint64_t _uid, uint64_t _euid,
+ uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid)
+ : Sparc64LiveProcess(name, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd, argv, envp, cwd,
+ _uid, _euid, _gid, _egid, _pid, _ppid)
+{}
+
+void Sparc64LinuxProcess::handleTrap(int trapNum, ThreadContext *tc)
{
- if (callnum < 0 || callnum > Num_Syscall_Descs)
- return NULL;
- return &syscallDescs[callnum];
+ switch(trapNum)
+ {
+ case 0x10: //Linux 32 bit syscall trap
+ case 0x6d: //Linux 64 bit syscall trap
+ tc->syscall(tc->readIntReg(1));
+ break;
+ default:
+ SparcLiveProcess::handleTrap(trapNum, tc);
+ }
}
diff --git a/src/arch/sparc/linux/process.hh b/src/arch/sparc/linux/process.hh
index e212de973..e3373bb6b 100644
--- a/src/arch/sparc/linux/process.hh
+++ b/src/arch/sparc/linux/process.hh
@@ -38,12 +38,28 @@
namespace SparcISA {
+//This contains all of the common elements of a SPARC Linux process which
+//are not shared by other operating systems. The rest come from the common
+//SPARC process class.
+class SparcLinuxProcess
+{
+ public:
+ SparcLinuxProcess();
+
+ /// Array of syscall descriptors, indexed by call number.
+ static SyscallDesc syscallDescs[];
+
+ SyscallDesc* getDesc(int callnum);
+
+ const int Num_Syscall_Descs;
+};
+
/// A process with emulated SPARC/Linux syscalls.
-class SparcLinuxProcess : public SparcLiveProcess
+class Sparc32LinuxProcess : public SparcLinuxProcess, public Sparc32LiveProcess
{
public:
/// Constructor.
- SparcLinuxProcess(const std::string &name,
+ Sparc32LinuxProcess(const std::string &name,
ObjectFile *objFile,
System * system,
int stdin_fd, int stdout_fd, int stderr_fd,
@@ -54,19 +70,40 @@ class SparcLinuxProcess : public SparcLiveProcess
uint64_t _gid, uint64_t _egid,
uint64_t _pid, uint64_t _ppid);
- virtual SyscallDesc* getDesc(int callnum);
+ SyscallDesc* getDesc(int callnum)
+ {
+ return SparcLinuxProcess::getDesc(callnum);
+ }
- /// The target system's hostname.
- static const char *hostname;
+ void handleTrap(int trapNum, ThreadContext *tc);
+};
- /// Array of syscall descriptors, indexed by call number.
- static SyscallDesc syscallDescs[];
+/// A process with emulated 32 bit SPARC/Linux syscalls.
+class Sparc64LinuxProcess : public SparcLinuxProcess, public Sparc64LiveProcess
+{
+ public:
+ /// Constructor.
+ Sparc64LinuxProcess(const std::string &name,
+ ObjectFile *objFile,
+ System * system,
+ int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ const std::string &cwd,
+ uint64_t _uid, uint64_t _euid,
+ uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid);
- const int Num_Syscall_Descs;
+ SyscallDesc* getDesc(int callnum)
+ {
+ return SparcLinuxProcess::getDesc(callnum);
+ }
+
+ void handleTrap(int trapNum, ThreadContext *tc);
};
SyscallReturn getresuidFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc);
} // namespace SparcISA
-#endif // __ALPHA_LINUX_PROCESS_HH__
+#endif // __SPARC_LINUX_PROCESS_HH__