diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2009-06-09 23:39:07 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2009-06-09 23:39:07 -0700 |
commit | 37ac2871d5a65dfa19b63c3bed9c6622d6b8b6c9 (patch) | |
tree | eb2826a0af77b3a9a7706313798146690ce482e5 /src/arch/arm/linux/process.cc | |
parent | 5daeefc5059ff98b63f06c963da2ffb17ef95df7 (diff) | |
download | gem5-37ac2871d5a65dfa19b63c3bed9c6622d6b8b6c9.tar.xz |
ARM: Implement TLS. This is not tested.
Diffstat (limited to 'src/arch/arm/linux/process.cc')
-rw-r--r-- | src/arch/arm/linux/process.cc | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc index 25307e106..620bcf116 100644 --- a/src/arch/arm/linux/process.cc +++ b/src/arch/arm/linux/process.cc @@ -40,6 +40,7 @@ #include "sim/process.hh" #include "sim/syscall_emul.hh" +#include "sim/system.hh" using namespace std; using namespace ArmISA; @@ -411,12 +412,25 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = { /* 346 */ SyscallDesc("epoll_pwait", unimplementedFunc), }; +/// Target set_tls() handler. +static SyscallReturn +setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process, + ThreadContext *tc) +{ + uint32_t tlsPtr = process->getSyscallArg(tc, 0); + TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0)); + + tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0, + (uint8_t *)&tlsPtr, sizeof(tlsPtr)); + return 0; +} + SyscallDesc ArmLinuxProcess::privSyscallDescs[] = { /* 1 */ SyscallDesc("breakpoint", unimplementedFunc), /* 2 */ SyscallDesc("cacheflush", unimplementedFunc), /* 3 */ SyscallDesc("usr26", unimplementedFunc), /* 4 */ SyscallDesc("usr32", unimplementedFunc), - /* 5 */ SyscallDesc("set_tls", unimplementedFunc) + /* 5 */ SyscallDesc("set_tls", setTLSFunc) }; ArmLinuxProcess::ArmLinuxProcess(LiveProcessParams * params, @@ -426,6 +440,8 @@ ArmLinuxProcess::ArmLinuxProcess(LiveProcessParams * params, Num_Priv_Syscall_Descs(sizeof(privSyscallDescs) / sizeof(SyscallDesc)) { } +const Addr ArmLinuxProcess::commPage = 0xffff0000; + SyscallDesc* ArmLinuxProcess::getDesc(int callnum) { @@ -448,3 +464,28 @@ ArmLinuxProcess::getDesc(int callnum) return &syscallDescs[callnum]; } + +void +ArmLinuxProcess::startup() +{ + ArmLiveProcess::startup(); + pTable->allocate(commPage, PageBytes); + ThreadContext *tc = system->getThreadContext(contextIds[0]); + + uint8_t swiNeg1[] = { + 0xff, 0xff, 0xff, 0xef //swi -1 + }; + + // Fill this page with swi -1 so we'll no if we land in it somewhere. + for (Addr addr = 0; addr < PageBytes; addr += sizeof(swiNeg1)) { + tc->getMemPort()->writeBlob(commPage + addr, + swiNeg1, sizeof(swiNeg1)); + } + + uint8_t get_tls[] = + { + 0x08, 0x00, 0x9f, 0xe5, //ldr r0, [pc, #(16 - 8)] + 0x0e, 0xf0, 0xa0, 0xe1 //usr_ret lr + }; + tc->getMemPort()->writeBlob(commPage + 0x0fe0, get_tls, sizeof(get_tls)); +} |