arch, base, dev, kern, sym: FreeBSD support

This adds support for FreeBSD/aarch64 FS and SE mode (basic set of syscalls only)

Committed by: Nilay Vaish <nilay@cs.wisc.edu>
This commit is contained in:
Ruslan Bukin 2015-04-29 22:35:23 -05:00
parent 52a3bc5e5c
commit 81f3211149
25 changed files with 2592 additions and 46 deletions

View file

@ -71,9 +71,9 @@ class ArmSystem(System):
have_large_asid_64 = Param.Bool(False,
"True if ASID is 16 bits in AArch64 (ARMv8)")
class LinuxArmSystem(ArmSystem):
type = 'LinuxArmSystem'
cxx_header = "arch/arm/linux/system.hh"
class GenericArmSystem(ArmSystem):
type = 'GenericArmSystem'
cxx_header = "arch/arm/system.hh"
load_addr_mask = 0x0fffffff
machine_type = Param.ArmMachineType('VExpress_EMM',
"Machine id from http://www.arm.linux.org.uk/developer/machines/")
@ -91,3 +91,11 @@ class LinuxArmSystem(ArmSystem):
"guest kernel panics")
panic_on_oops = Param.Bool(False, "Trigger a gem5 panic if the " \
"guest kernel oopses")
class LinuxArmSystem(GenericArmSystem):
type = 'LinuxArmSystem'
cxx_header = "arch/arm/linux/system.hh"
class FreebsdArmSystem(GenericArmSystem):
type = 'FreebsdArmSystem'
cxx_header = "arch/arm/freebsd/system.hh"

View file

@ -67,6 +67,9 @@ if env['TARGET_ISA'] == 'arm':
Source('linux/linux.cc')
Source('linux/process.cc')
Source('linux/system.cc')
Source('freebsd/freebsd.cc')
Source('freebsd/process.cc')
Source('freebsd/system.cc')
Source('miscregs.cc')
Source('nativetrace.cc')
Source('pmu.cc')

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* This software was developed by the University of Cambridge Computer
* Laboratory as part of the CTSRD Project, with support from the UK Higher
* Education Innovation Fund (HEIF).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "arch/arm/freebsd/freebsd.hh"
#include <fcntl.h>
// open(2) flags translation table
OpenFlagTransTable ArmFreebsd32::openFlagTable[] = {
{ ArmFreebsd32::TGT_O_RDONLY, O_RDONLY },
{ ArmFreebsd32::TGT_O_WRONLY, O_WRONLY },
{ ArmFreebsd32::TGT_O_RDWR, O_RDWR },
{ ArmFreebsd32::TGT_O_CREAT, O_CREAT },
{ ArmFreebsd32::TGT_O_EXCL, O_EXCL },
{ ArmFreebsd32::TGT_O_NOCTTY, O_NOCTTY },
{ ArmFreebsd32::TGT_O_TRUNC, O_TRUNC },
{ ArmFreebsd32::TGT_O_APPEND, O_APPEND },
{ ArmFreebsd32::TGT_O_NONBLOCK, O_NONBLOCK },
{ ArmFreebsd32::TGT_O_SYNC, O_SYNC },
{ ArmFreebsd32::TGT_FASYNC, FASYNC },
{ ArmFreebsd32::TGT_O_DIRECT, O_DIRECT },
{ ArmFreebsd32::TGT_O_DIRECTORY, O_DIRECTORY },
{ ArmFreebsd32::TGT_O_NOFOLLOW, O_NOFOLLOW },
};
const int ArmFreebsd32::NUM_OPEN_FLAGS = sizeof(ArmFreebsd32::openFlagTable) /
sizeof(ArmFreebsd32::openFlagTable[0]);
// open(2) flags translation table
OpenFlagTransTable ArmFreebsd64::openFlagTable[] = {
{ ArmFreebsd32::TGT_O_RDONLY, O_RDONLY },
{ ArmFreebsd32::TGT_O_WRONLY, O_WRONLY },
{ ArmFreebsd32::TGT_O_RDWR, O_RDWR },
{ ArmFreebsd32::TGT_O_CREAT, O_CREAT },
{ ArmFreebsd32::TGT_O_EXCL, O_EXCL },
{ ArmFreebsd32::TGT_O_NOCTTY, O_NOCTTY },
{ ArmFreebsd32::TGT_O_TRUNC, O_TRUNC },
{ ArmFreebsd32::TGT_O_APPEND, O_APPEND },
{ ArmFreebsd32::TGT_O_NONBLOCK, O_NONBLOCK },
{ ArmFreebsd32::TGT_O_SYNC, O_SYNC },
{ ArmFreebsd32::TGT_FASYNC, FASYNC },
{ ArmFreebsd32::TGT_O_DIRECT, O_DIRECT },
{ ArmFreebsd32::TGT_O_DIRECTORY, O_DIRECTORY },
{ ArmFreebsd32::TGT_O_NOFOLLOW, O_NOFOLLOW },
};
const int ArmFreebsd64::NUM_OPEN_FLAGS = sizeof(ArmFreebsd64::openFlagTable) /
sizeof(ArmFreebsd64::openFlagTable[0]);

View file

@ -0,0 +1,356 @@
/*
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* This software was developed by the University of Cambridge Computer
* Laboratory as part of the CTSRD Project, with support from the UK Higher
* Education Innovation Fund (HEIF).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ARCH_ARM_FREEBSD_FREEBSD_HH__
#define __ARCH_ARM_FREEBSD_FREEBSD_HH__
#include "kern/freebsd/freebsd.hh"
class ArmFreebsd32 : public FreeBSD
{
public:
/// This table maps the target open() flags to the corresponding
/// host open() flags.
static OpenFlagTransTable openFlagTable[];
/// Number of entries in openFlagTable[].
static const int NUM_OPEN_FLAGS;
//@{
/// Basic ARM FreeBSD types
typedef uint32_t size_t;
typedef uint32_t off_t;
typedef int32_t time_t;
typedef int32_t clock_t;
//@}
//@{
/// open(2) flag values.
static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY
static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY
static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR
static const int TGT_O_CREAT = 0x00000200; //!< O_CREAT
static const int TGT_O_EXCL = 0x00000800; //!< O_EXCL
static const int TGT_O_NOCTTY = 0x00008000; //!< O_NOCTTY
static const int TGT_O_TRUNC = 0x00000400; //!< O_TRUNC
static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
static const int TGT_O_NONBLOCK = 0x00000004; //!< O_NONBLOCK
static const int TGT_O_SYNC = 0x00000080; //!< O_SYNC
static const int TGT_FASYNC = 0x00000040; //!< FASYNC
static const int TGT_O_DIRECT = 0x00010000; //!< O_DIRECT
static const int TGT_O_DIRECTORY = 0x00020000; //!< O_DIRECTORY
static const int TGT_O_NOFOLLOW = 0x00000100; //!< O_NOFOLLOW
static const int TGT_O_CLOEXEC = 0x00100000; //!< O_CLOEXEC
//@}
/// For mmap().
static const unsigned TGT_MAP_ANONYMOUS = 0x1000;
static const unsigned TGT_MAP_FIXED = 0x0010;
/// Limit struct for getrlimit/setrlimit.
struct rlimit {
uint32_t rlim_cur; //!< soft limit
uint32_t rlim_max; //!< hard limit
};
/// For gettimeofday().
struct timeval {
int32_t tv_sec; //!< seconds
int32_t tv_usec; //!< microseconds
};
// For writev/readv
struct tgt_iovec {
uint32_t iov_base; // void *
uint32_t iov_len;
};
/*
* sizeof st 120
* sizeof st_dev 4
* sizeof st_ino 4
* sizeof st_mode 2
* sizeof st_nlink 2
* sizeof st_uid 4
* sizeof st_gid 4
* sizeof st_rdev 4
* sizeof st_atim 16
* sizeof st_size 8
* sizeof st_blocks 8
* sizeof st_blksize 4
* sizeof st_flags 4
* sizeof st_gen 4
* sizeof st_lspare 4
*/
typedef struct {
uint32_t st_dev;
uint32_t st_ino;
uint16_t st_mode;
uint16_t st_nlink;
uint32_t st_uid;
uint32_t st_gid;
uint32_t st_rdev;
uint64_t st_atimeX;
uint64_t st_atime_nsec;
uint64_t st_mtimeX;
uint64_t st_mtime_nsec;
uint64_t st_ctimeX;
uint64_t st_ctime_nsec;
uint64_t st_size;
uint64_t st_blocks;
uint32_t st_blksize;
uint32_t st_flags;
uint32_t st_gen;
uint32_t st_lspare;
uint64_t st_birthtimX;
uint64_t st_birthtim;
} tgt_stat;
typedef struct {
uint32_t st_dev;
uint32_t st_ino;
uint16_t st_mode;
uint16_t st_nlink;
uint32_t st_uid;
uint32_t st_gid;
uint32_t st_rdev;
uint64_t st_atimeX;
uint64_t st_atime_nsec;
uint64_t st_mtimeX;
uint64_t st_mtime_nsec;
uint64_t st_ctimeX;
uint64_t st_ctime_nsec;
uint64_t st_size;
uint64_t st_blocks;
uint32_t st_blksize;
uint32_t st_flags;
uint32_t st_gen;
uint32_t st_lspare;
uint64_t st_birthtimX;
uint64_t st_birthtim;
} tgt_stat64;
/// For getrusage().
struct rusage {
struct timeval ru_utime; //!< user time used
struct timeval ru_stime; //!< system time used
int32_t ru_maxrss; //!< max rss
int32_t ru_ixrss; //!< integral shared memory size
int32_t ru_idrss; //!< integral unshared data "
int32_t ru_isrss; //!< integral unshared stack "
int32_t ru_minflt; //!< page reclaims - total vmfaults
int32_t ru_majflt; //!< page faults
int32_t ru_nswap; //!< swaps
int32_t ru_inblock; //!< block input operations
int32_t ru_oublock; //!< block output operations
int32_t ru_msgsnd; //!< messages sent
int32_t ru_msgrcv; //!< messages received
int32_t ru_nsignals; //!< signals received
int32_t ru_nvcsw; //!< voluntary context switches
int32_t ru_nivcsw; //!< involuntary "
};
/// For times().
struct tms {
int32_t tms_utime; //!< user time
int32_t tms_stime; //!< system time
int32_t tms_cutime; //!< user time of children
int32_t tms_cstime; //!< system time of children
};
};
class ArmFreebsd64 : public FreeBSD
{
public:
/// This table maps the target open() flags to the corresponding
/// host open() flags.
static OpenFlagTransTable openFlagTable[];
/// Number of entries in openFlagTable[].
static const int NUM_OPEN_FLAGS;
//@{
/// Basic ARM FreeBSD types
typedef uint64_t size_t;
typedef uint64_t off_t;
typedef int64_t time_t;
typedef int64_t clock_t;
//@}
//@{
/// open(2) flag values.
static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY
static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY
static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR
static const int TGT_O_CREAT = 0x00000200; //!< O_CREAT
static const int TGT_O_EXCL = 0x00000800; //!< O_EXCL
static const int TGT_O_NOCTTY = 0x00008000; //!< O_NOCTTY
static const int TGT_O_TRUNC = 0x00000400; //!< O_TRUNC
static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
static const int TGT_O_NONBLOCK = 0x00000004; //!< O_NONBLOCK
static const int TGT_O_SYNC = 0x00000080; //!< O_SYNC
static const int TGT_FASYNC = 0x00000040; //!< FASYNC
static const int TGT_O_DIRECT = 0x00010000; //!< O_DIRECT
static const int TGT_O_DIRECTORY = 0x00020000; //!< O_DIRECTORY
static const int TGT_O_NOFOLLOW = 0x00000100; //!< O_NOFOLLOW
static const int TGT_O_CLOEXEC = 0x00100000; //!< O_CLOEXEC
//@}
/// For mmap().
static const unsigned TGT_MAP_ANONYMOUS = 0x1000;
static const unsigned TGT_MAP_FIXED = 0x0010;
//@{
/// For getrusage().
static const int TGT_RUSAGE_SELF = 0;
static const int TGT_RUSAGE_CHILDREN = -1;
static const int TGT_RUSAGE_THREAD = 1;
//@}
/// Resource enumeration for getrlimit().
enum rlimit_resources {
TGT_RLIMIT_CPU = 0,
TGT_RLIMIT_FSIZE = 1,
TGT_RLIMIT_DATA = 2,
TGT_RLIMIT_STACK = 3,
TGT_RLIMIT_CORE = 4,
TGT_RLIMIT_RSS = 5,
TGT_RLIMIT_MEMLOCK = 6,
TGT_RLIMIT_NPROC = 7,
TGT_RLIMIT_NOFILE = 8,
TGT_RLIMIT_SBSIZE = 9,
TGT_RLIMIT_VMEM = 10,
TGT_RLIMIT_AS = TGT_RLIMIT_VMEM,
TGT_RLIMIT_NPTS = 11,
TGT_RLIMIT_SWAP = 12,
TGT_RLIMIT_KQUEUES = 13
};
/// Limit struct for getrlimit/setrlimit.
struct rlimit {
uint64_t rlim_cur; //!< soft limit
uint64_t rlim_max; //!< hard limit
};
/// For gettimeofday().
struct timeval {
int64_t tv_sec; //!< seconds
int64_t tv_usec; //!< microseconds
};
// For writev/readv
struct tgt_iovec {
uint64_t iov_base; // void *
uint64_t iov_len;
};
typedef struct {
uint32_t st_dev;
uint32_t st_ino;
uint16_t st_mode;
uint16_t st_nlink;
uint32_t st_uid;
uint32_t st_gid;
uint32_t st_rdev;
uint64_t st_atimeX;
uint64_t st_atime_nsec;
uint64_t st_mtimeX;
uint64_t st_mtime_nsec;
uint64_t st_ctimeX;
uint64_t st_ctime_nsec;
uint64_t st_size;
uint64_t st_blocks;
uint32_t st_blksize;
uint32_t st_flags;
uint32_t st_gen;
uint32_t st_lspare;
uint64_t st_birthtimX;
uint64_t st_birthtim;
} tgt_stat;
typedef struct {
uint32_t st_dev;
uint32_t st_ino;
uint16_t st_mode;
uint16_t st_nlink;
uint32_t st_uid;
uint32_t st_gid;
uint32_t st_rdev;
uint64_t st_atimeX;
uint64_t st_atime_nsec;
uint64_t st_mtimeX;
uint64_t st_mtime_nsec;
uint64_t st_ctimeX;
uint64_t st_ctime_nsec;
uint64_t st_size;
uint64_t st_blocks;
uint32_t st_blksize;
uint32_t st_flags;
uint32_t st_gen;
uint32_t st_lspare;
uint64_t st_birthtimX;
uint64_t st_birthtim;
} tgt_stat64;
/// For getrusage().
struct rusage {
struct timeval ru_utime; //!< user time used
struct timeval ru_stime; //!< system time used
int64_t ru_maxrss; //!< max rss
int64_t ru_ixrss; //!< integral shared memory size
int64_t ru_idrss; //!< integral unshared data "
int64_t ru_isrss; //!< integral unshared stack "
int64_t ru_minflt; //!< page reclaims - total vmfaults
int64_t ru_majflt; //!< page faults
int64_t ru_nswap; //!< swaps
int64_t ru_inblock; //!< block input operations
int64_t ru_oublock; //!< block output operations
int64_t ru_msgsnd; //!< messages sent
int64_t ru_msgrcv; //!< messages received
int64_t ru_nsignals; //!< signals received
int64_t ru_nvcsw; //!< voluntary context switches
int64_t ru_nivcsw; //!< involuntary "
};
/// For times().
struct tms {
int64_t tms_utime; //!< user time
int64_t tms_stime; //!< system time
int64_t tms_cutime; //!< user time of children
int64_t tms_cstime; //!< system time of children
};
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* This software was developed by the University of Cambridge Computer
* Laboratory as part of the CTSRD Project, with support from the UK Higher
* Education Innovation Fund (HEIF).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ARCH_ARM_FREEBSD_PROCESS_HH__
#define __ARCH_ARM_FREEBSD_PROCESS_HH__
#include <vector>
#include "arch/arm/process.hh"
class ArmFreebsdProcessBits
{
protected:
SyscallDesc* getFreebsdDesc(int callnum);
struct SyscallTable
{
int base;
SyscallDesc *descs;
int size;
SyscallDesc *getDesc(int offset) const;
};
std::vector<SyscallTable> syscallTables;
};
/// A process with emulated Arm/Freebsd syscalls.
class ArmFreebsdProcess32 : public ArmLiveProcess32, public ArmFreebsdProcessBits
{
public:
ArmFreebsdProcess32(LiveProcessParams * params, ObjectFile *objFile,
ObjectFile::Arch _arch);
void initState();
/// Explicitly import the otherwise hidden getSyscallArg
using ArmLiveProcess::getSyscallArg;
/// A page to hold "kernel" provided functions. The name might be wrong.
static const Addr commPage;
SyscallDesc* getDesc(int callnum);
};
/// A process with emulated Arm/Freebsd syscalls.
class ArmFreebsdProcess64 : public ArmLiveProcess64, public ArmFreebsdProcessBits
{
public:
ArmFreebsdProcess64(LiveProcessParams * params, ObjectFile *objFile,
ObjectFile::Arch _arch);
void initState();
SyscallDesc* getDesc(int callnum);
};
#endif // __ARCH_ARM_FREEBSD_PROCESS_HH__

View file

@ -0,0 +1,175 @@
/*
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* This software was developed by the University of Cambridge Computer
* Laboratory as part of the CTSRD Project, with support from the UK Higher
* Education Innovation Fund (HEIF).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "arch/arm/freebsd/system.hh"
#include "arch/arm/isa_traits.hh"
#include "arch/arm/utility.hh"
#include "arch/generic/freebsd/threadinfo.hh"
#include "base/loader/dtb_object.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "cpu/base.hh"
#include "cpu/pc_event.hh"
#include "cpu/thread_context.hh"
#include "debug/Loader.hh"
#include "kern/freebsd/events.hh"
#include "mem/fs_translating_port_proxy.hh"
#include "mem/physical.hh"
#include "sim/stat_control.hh"
using namespace ArmISA;
using namespace FreeBSD;
FreebsdArmSystem::FreebsdArmSystem(Params *p)
: GenericArmSystem(p), dumpStatsPCEventF(nullptr),
enableContextSwitchStatsDump(p->enable_context_switch_stats_dump),
taskFile(nullptr), kernelPanicEvent(nullptr), kernelOopsEvent(nullptr),
bootReleaseAddr(p->boot_release_addr)
{
if (p->panic_on_panic) {
kernelPanicEvent = addKernelFuncEventOrPanic<PanicPCEvent>(
"panic", "Kernel panic in simulated kernel");
} else {
#ifndef NDEBUG
kernelPanicEvent = addKernelFuncEventOrPanic<BreakPCEvent>("panic");
#endif
}
if (p->panic_on_oops) {
kernelOopsEvent = addKernelFuncEventOrPanic<PanicPCEvent>(
"oops_exit", "Kernel oops in guest");
}
uDelaySkipEvent = addKernelFuncEvent<UDelayEvent>(
"DELAY", "DELAY", 1000, 0);
}
bool
FreebsdArmSystem::adderBootUncacheable(Addr a)
{
return false;
}
void
FreebsdArmSystem::initState()
{
// Moved from the constructor to here since it relies on the
// address map being resolved in the interconnect
// Call the initialisation of the super class
GenericArmSystem::initState();
// Load symbols at physical address, we might not want
// to do this permanently, for but early bootup work
// it is helpful.
if (params()->early_kernel_symbols) {
kernel->loadGlobalSymbols(kernelSymtab, loadAddrMask);
kernel->loadGlobalSymbols(debugSymbolTable, loadAddrMask);
}
// Setup boot data structure
Addr addr = 0;
// Check if the kernel image has a symbol that tells us it supports
// device trees.
bool kernel_has_fdt_support =
kernelSymtab->findAddress("fdt_get_range", addr);
bool dtb_file_specified = params()->dtb_filename != "";
if (!dtb_file_specified)
fatal("dtb file is not specified\n");
if (!kernel_has_fdt_support)
fatal("kernel must have fdt support\n");
// Kernel supports flattened device tree and dtb file specified.
// Using Device Tree Blob to describe system configuration.
inform("Loading DTB file: %s at address %#x\n", params()->dtb_filename,
params()->atags_addr + loadAddrOffset);
ObjectFile *dtb_file = createObjectFile(params()->dtb_filename, true);
if (!dtb_file) {
fatal("couldn't load DTB file: %s\n", params()->dtb_filename);
}
DtbObject *_dtb_file = dynamic_cast<DtbObject*>(dtb_file);
if (_dtb_file) {
if (!_dtb_file->addBootCmdLine(params()->boot_osflags.c_str(),
params()->boot_osflags.size())) {
warn("couldn't append bootargs to DTB file: %s\n",
params()->dtb_filename);
}
} else {
warn("dtb_file cast failed; couldn't append bootargs "
"to DTB file: %s\n", params()->dtb_filename);
}
Addr ra = _dtb_file->findReleaseAddr();
if (ra)
bootReleaseAddr = ra & ~ULL(0x7F);
dtb_file->setTextBase(params()->atags_addr + loadAddrOffset);
dtb_file->loadSections(physProxy);
delete dtb_file;
// Kernel boot requirements to set up r0, r1 and r2 in ARMv7
for (int i = 0; i < threadContexts.size(); i++) {
threadContexts[i]->setIntReg(0, 0);
threadContexts[i]->setIntReg(1, params()->machine_type);
threadContexts[i]->setIntReg(2, params()->atags_addr + loadAddrOffset);
}
}
FreebsdArmSystem::~FreebsdArmSystem()
{
if (uDelaySkipEvent)
delete uDelaySkipEvent;
if (constUDelaySkipEvent)
delete constUDelaySkipEvent;
if (dumpStatsPCEventF)
delete dumpStatsPCEventF;
}
FreebsdArmSystem *
FreebsdArmSystemParams::create()
{
return new FreebsdArmSystem(this);
}
void
FreebsdArmSystem::startup()
{
}

View file

@ -0,0 +1,135 @@
/*
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* This software was developed by the University of Cambridge Computer
* Laboratory as part of the CTSRD Project, with support from the UK Higher
* Education Innovation Fund (HEIF).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ARCH_ARM_FREEBSD_SYSTEM_HH__
#define __ARCH_ARM_FREEBSD_SYSTEM_HH__
#include <cstdio>
#include <map>
#include <string>
#include <vector>
#include "arch/arm/system.hh"
#include "base/output.hh"
#include "kern/freebsd/events.hh"
#include "params/FreebsdArmSystem.hh"
#include "sim/core.hh"
class DumpStatsPCEventF;
class FreebsdArmSystem : public GenericArmSystem
{
protected:
DumpStatsPCEventF *dumpStatsPCEventF;
public:
/** Boilerplate params code */
typedef FreebsdArmSystemParams Params;
const Params *
params() const
{
return dynamic_cast<const Params *>(_params);
}
/** When enabled, dump stats/task info on context switches for
* Streamline and per-thread cache occupancy studies, etc. */
bool enableContextSwitchStatsDump;
/** This map stores a mapping of OS process IDs to internal Task IDs. The
* mapping is done because the stats system doesn't tend to like vectors
* that are much greater than 1000 items and the entire process space is
* 65K. */
std::map<uint32_t, uint32_t> taskMap;
/** This is a file that is placed in the run directory that prints out
* mappings between taskIds and OS process IDs */
std::ostream* taskFile;
FreebsdArmSystem(Params *p);
~FreebsdArmSystem();
void initState();
bool adderBootUncacheable(Addr a);
void startup();
/** This function creates a new task Id for the given pid.
* @param tc thread context that is currentyl executing */
void mapPid(ThreadContext* tc, uint32_t pid);
private:
/** Event to halt the simulator if the kernel calls panic() */
PCEvent *kernelPanicEvent;
/** Event to halt the simulator if the kernel calls oopses */
PCEvent *kernelOopsEvent;
/**
* PC based event to skip udelay(<time>) calls and quiesce the
* processor for the appropriate amount of time. This is not functionally
* required but does speed up simulation.
*/
FreeBSD::UDelayEvent *uDelaySkipEvent;
/** Another PC based skip event for const_udelay(). Similar to the udelay
* skip, but this function precomputes the first multiply that is done
* in the generic case since the parameter is known at compile time.
* Thus we need to do some division to get back to us.
*/
FreeBSD::UDelayEvent *constUDelaySkipEvent;
/** These variables store addresses of important data structures
* that are normaly kept coherent at boot with cache mainetence operations.
* Since these operations aren't supported in gem5, we keep them coherent
* by making them uncacheable until all processors in the system boot.
*/
Addr secDataPtrAddr;
Addr secDataAddr;
Addr penReleaseAddr;
Addr pen64ReleaseAddr;
Addr bootReleaseAddr;
};
class DumpStatsPCEventF : public PCEvent
{
public:
DumpStatsPCEventF(PCEventQueue *q, const std::string &desc, Addr addr)
: PCEvent(q, desc, addr)
{}
virtual void process(ThreadContext* tc);
};
#endif // __ARCH_ARM_FREEBSD_SYSTEM_HH__

View file

@ -61,7 +61,7 @@ using namespace ArmISA;
using namespace Linux;
LinuxArmSystem::LinuxArmSystem(Params *p)
: ArmSystem(p), dumpStatsPCEvent(nullptr),
: GenericArmSystem(p), dumpStatsPCEvent(nullptr),
enableContextSwitchStatsDump(p->enable_context_switch_stats_dump),
taskFile(nullptr), kernelPanicEvent(nullptr), kernelOopsEvent(nullptr),
bootReleaseAddr(p->boot_release_addr)
@ -133,7 +133,7 @@ LinuxArmSystem::initState()
// address map being resolved in the interconnect
// Call the initialisation of the super class
ArmSystem::initState();
GenericArmSystem::initState();
// Load symbols at physical address, we might not want
// to do this permanently, for but early bootup work

View file

@ -56,7 +56,7 @@
class DumpStatsPCEvent;
class LinuxArmSystem : public ArmSystem
class LinuxArmSystem : public GenericArmSystem
{
protected:
DumpStatsPCEvent *dumpStatsPCEvent;

View file

@ -181,31 +181,43 @@ ArmLiveProcess::argsInit(int pageSize, IntRegIndex spIndex)
//Auxilliary vectors are loaded only for elf formatted executables.
ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
if (elfObject) {
IntType features =
Arm_Swp |
Arm_Half |
Arm_Thumb |
// Arm_26Bit |
Arm_FastMult |
// Arm_Fpa |
Arm_Vfp |
Arm_Edsp |
// Arm_Java |
// Arm_Iwmmxt |
// Arm_Crunch |
Arm_ThumbEE |
Arm_Neon |
Arm_Vfpv3 |
Arm_Vfpv3d16 |
0;
//Bits which describe the system hardware capabilities
//XXX Figure out what these should be
auxv.push_back(auxv_t(M5_AT_HWCAP, features));
if (objFile->getOpSys() == ObjectFile::Linux) {
IntType features =
Arm_Swp |
Arm_Half |
Arm_Thumb |
// Arm_26Bit |
Arm_FastMult |
// Arm_Fpa |
Arm_Vfp |
Arm_Edsp |
// Arm_Java |
// Arm_Iwmmxt |
// Arm_Crunch |
Arm_ThumbEE |
Arm_Neon |
Arm_Vfpv3 |
Arm_Vfpv3d16 |
0;
//Bits which describe the system hardware capabilities
//XXX Figure out what these should be
auxv.push_back(auxv_t(M5_AT_HWCAP, features));
//Frequency at which times() increments
auxv.push_back(auxv_t(M5_AT_CLKTCK, 0x64));
//Whether to enable "secure mode" in the executable
auxv.push_back(auxv_t(M5_AT_SECURE, 0));
// Pointer to 16 bytes of random data
auxv.push_back(auxv_t(M5_AT_RANDOM, 0));
//The filename of the program
auxv.push_back(auxv_t(M5_AT_EXECFN, 0));
//The string "v71" -- ARM v7 architecture
auxv.push_back(auxv_t(M5_AT_PLATFORM, 0));
}
//The system page size
auxv.push_back(auxv_t(M5_AT_PAGESZ, ArmISA::PageBytes));
//Frequency at which times() increments
auxv.push_back(auxv_t(M5_AT_CLKTCK, 0x64));
// For statically linked executables, this is the virtual address of the
// program header tables if they appear in the executable image
auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
@ -217,7 +229,6 @@ ArmLiveProcess::argsInit(int pageSize, IntRegIndex spIndex)
//to 0 for regular executables. It should be something else
//(not sure what) for dynamic libraries.
auxv.push_back(auxv_t(M5_AT_BASE, 0));
//XXX Figure out what this should be.
auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
//The entry point to the program
@ -227,16 +238,6 @@ ArmLiveProcess::argsInit(int pageSize, IntRegIndex spIndex)
auxv.push_back(auxv_t(M5_AT_EUID, euid()));
auxv.push_back(auxv_t(M5_AT_GID, gid()));
auxv.push_back(auxv_t(M5_AT_EGID, egid()));
//Whether to enable "secure mode" in the executable
auxv.push_back(auxv_t(M5_AT_SECURE, 0));
// Pointer to 16 bytes of random data
auxv.push_back(auxv_t(M5_AT_RANDOM, 0));
//The filename of the program
auxv.push_back(auxv_t(M5_AT_EXECFN, 0));
//The string "v71" -- ARM v7 architecture
auxv.push_back(auxv_t(M5_AT_PLATFORM, 0));
}
//Figure out how big the initial stack nedes to be
@ -456,11 +457,33 @@ ArmLiveProcess64::setSyscallArg(ThreadContext *tc,
void
ArmLiveProcess32::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret)
{
if (objFile->getOpSys() == ObjectFile::FreeBSD) {
// Decode return value
if (sysret.encodedValue() >= 0)
// FreeBSD checks the carry bit to determine if syscall is succeeded
tc->setCCReg(CCREG_C, 0);
else {
sysret = -sysret.encodedValue();
}
}
tc->setIntReg(ReturnValueReg, sysret.encodedValue());
}
void
ArmLiveProcess64::setSyscallReturn(ThreadContext *tc, SyscallReturn sysret)
{
if (objFile->getOpSys() == ObjectFile::FreeBSD) {
// Decode return value
if (sysret.encodedValue() >= 0)
// FreeBSD checks the carry bit to determine if syscall is succeeded
tc->setCCReg(CCREG_C, 0);
else {
sysret = -sysret.encodedValue();
}
}
tc->setIntReg(ReturnValueReg, sysret.encodedValue());
}

View file

@ -244,8 +244,26 @@ ArmSystem::haveLargeAsid64(ThreadContext *tc)
{
return dynamic_cast<ArmSystem *>(tc->getSystemPtr())->haveLargeAsid64();
}
ArmSystem *
ArmSystemParams::create()
{
return new ArmSystem(this);
}
void
GenericArmSystem::initState()
{
// Moved from the constructor to here since it relies on the
// address map being resolved in the interconnect
// Call the initialisation of the super class
ArmSystem::initState();
}
GenericArmSystem *
GenericArmSystemParams::create()
{
return new GenericArmSystem(this);
}

View file

@ -49,6 +49,7 @@
#include "dev/arm/generic_timer.hh"
#include "kern/linux/events.hh"
#include "params/ArmSystem.hh"
#include "params/GenericArmSystem.hh"
#include "sim/sim_object.hh"
#include "sim/system.hh"
@ -265,8 +266,25 @@ class ArmSystem : public System
/** Returns true if ASID is 16 bits for the system of a specific thread
* context while in AArch64 (ARMv8) */
static bool haveLargeAsid64(ThreadContext *tc);
};
class GenericArmSystem : public ArmSystem
{
public:
typedef GenericArmSystemParams Params;
const Params *
params() const
{
return dynamic_cast<const Params *>(_params);
}
GenericArmSystem(Params *p) : ArmSystem(p) {};
virtual ~GenericArmSystem() {};
/**
* Initialise the system
*/
virtual void initState();
};
#endif

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* This software was developed by the University of Cambridge Computer
* Laboratory as part of the CTSRD Project, with support from the UK Higher
* Education Innovation Fund (HEIF).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ARCH_GENERIC_FREEBSD_THREADINFO_HH__
#define __ARCH_GENERIC_FREEBSD_THREADINFO_HH__
#include "cpu/thread_context.hh"
#include "sim/system.hh"
#include "sim/vptr.hh"
namespace FreeBSD {
class ThreadInfo
{
private:
ThreadContext *tc;
System *sys;
public:
ThreadInfo(ThreadContext *_tc)
: tc(_tc), sys(tc->getSystemPtr())
{
}
~ThreadInfo()
{}
};
} // namespace FreeBSD
#endif // __ARCH_GENERIC_FREEBSD_THREADINFO_HH__

View file

@ -150,6 +150,9 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
case ELFOSABI_ARM:
opSys = ObjectFile::LinuxArmOABI;
break;
case ELFOSABI_FREEBSD:
opSys = ObjectFile::FreeBSD;
break;
default:
opSys = ObjectFile::UnknownOpSys;
}
@ -160,7 +163,8 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
Elf_Scn *section;
GElf_Shdr shdr;
Elf_Data *data;
uint32_t osAbi;;
uint32_t osAbi;
uint32_t *elem;
int secIdx = 1;
// Get the first section
@ -194,6 +198,16 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
opSys = ObjectFile::Solaris;
if (!strcmp(".stab.index", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name)))
opSys = ObjectFile::Solaris;
if (shdr.sh_type == SHT_NOTE && !strcmp(".note.tag",
elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) {
data = elf_rawdata(section, NULL);
assert(data->d_buf);
elem = (uint32_t *)data->d_buf;
if (elem[0] == 0x8) { //size of name
if (memcmp((void *)&elem[3], "FreeBSD", 0x8) == 0)
opSys = ObjectFile::FreeBSD;
}
}
section = elf_getscn(elf, ++secIdx);
} // while sections

View file

@ -63,7 +63,8 @@ class ObjectFile
Tru64,
Linux,
Solaris,
LinuxArmOABI
LinuxArmOABI,
FreeBSD
};
protected:

View file

@ -32,6 +32,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <cassert>
#include <cerrno>

View file

@ -44,16 +44,24 @@
#include <sys/ioctl.h>
#include <sys/stat.h>
#if defined(__FreeBSD__)
#include <termios.h>
#else
#include <sys/termios.h>
#include <sys/types.h>
#endif
#include "base/vnc/vncserver.hh"
#include <fcntl.h>
#include <poll.h>
#include <sys/types.h>
#include <unistd.h>
#include <cerrno>
#include <cstdio>
#include "base/vnc/vncserver.hh"
#include "base/atomicio.hh"
#include "base/bitmap.hh"
#include "base/misc.hh"

View file

@ -276,6 +276,9 @@ Pl390::readCpu(PacketPtr pkt)
ctx_id);
switch(daddr) {
case ICCIIDR:
pkt->set<uint32_t>(0);
break;
case ICCICR:
pkt->set<uint32_t>(cpuEnabled[ctx_id]);
break;
@ -525,7 +528,8 @@ Pl390::writeCpu(PacketPtr pkt)
} else {
uint32_t int_num = 1 << intNumToBit(iar.ack_id);
if (!(activeInt[intNumToWord(iar.ack_id)] & int_num))
panic("Done handling interrupt that isn't active?\n");
warn("Done handling interrupt that isn't active: %d\n",
intNumToBit(iar.ack_id));
activeInt[intNumToWord(iar.ack_id)] &= ~int_num;
}
updateRunPri();

View file

@ -34,7 +34,16 @@
*/
#include <sys/ioctl.h>
#if defined(__FreeBSD__)
#include <termios.h>
#else
#include <sys/termios.h>
#endif
#include "dev/terminal.hh"
#include <poll.h>
#include <unistd.h>
@ -53,7 +62,6 @@
#include "debug/Terminal.hh"
#include "debug/TerminalVerbose.hh"
#include "dev/platform.hh"
#include "dev/terminal.hh"
#include "dev/uart.hh"
using namespace std;

View file

@ -37,6 +37,7 @@ Source('kernel_stats.cc')
Source('linux/events.cc')
Source('linux/linux.cc')
Source('linux/printk.cc')
Source('freebsd/events.cc')
Source('operatingsystem.cc')
Source('system_events.cc')

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* This software was developed by the University of Cambridge Computer
* Laboratory as part of the CTSRD Project, with support from the UK Higher
* Education Innovation Fund (HEIF).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "kern/freebsd/events.hh"
#include <sstream>
#include "arch/utility.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/DebugPrintf.hh"
#include "kern/system_events.hh"
#include "sim/arguments.hh"
#include "sim/pseudo_inst.hh"
#include "sim/system.hh"
namespace FreeBSD {
void
UDelayEvent::process(ThreadContext *tc)
{
int arg_num;
arg_num = 0;
// Get the time in native size
uint64_t time = TheISA::getArgument(tc, arg_num, (uint16_t)-1, false);
//DPRINTFN("DELAY(%d)\n", time);
// convert parameter to ns
if (argDivToNs)
time /= argDivToNs;
time *= argMultToNs;
SkipFuncEvent::process(tc);
PseudoInst::quiesceNs(tc, time);
}
} // namespace FreeBSD

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* This software was developed by the University of Cambridge Computer
* Laboratory as part of the CTSRD Project, with support from the UK Higher
* Education Innovation Fund (HEIF).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __KERN_FREEBSD_EVENTS_HH__
#define __KERN_FREEBSD_EVENTS_HH__
#include "kern/system_events.hh"
namespace FreeBSD {
/** A class to skip udelay() and related calls in the kernel.
* This class has two additional parameters that take the argument to udelay and
* manipulated it to come up with ns and eventually ticks to quiesce for.
* See descriptions of argDivToNs and argMultToNs below.
*/
class UDelayEvent : public SkipFuncEvent
{
private:
/** value to divide arg by to create ns. This is present beacues the linux
* kernel code sometime precomputes the first multiply that is done in
* udelay() if the parameter is a constant. We need to undo it so here is
* how. */
uint64_t argDivToNs;
/** value to multiple arg by to create ns. Nominally, this is 1000 to
* convert us to ns, but since linux can do some preprocessing of constant
* values something else might be required. */
uint64_t argMultToNs;
public:
UDelayEvent(PCEventQueue *q, const std::string &desc, Addr addr,
uint64_t mult, uint64_t div)
: SkipFuncEvent(q, desc, addr), argDivToNs(div), argMultToNs(mult) {}
virtual void process(ThreadContext *xc);
};
}
#endif

120
src/kern/freebsd/freebsd.hh Normal file
View file

@ -0,0 +1,120 @@
/*
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* This software was developed by the University of Cambridge Computer
* Laboratory as part of the CTSRD Project, with support from the UK Higher
* Education Innovation Fund (HEIF).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __FREEBSD_HH__
#define __FREEBSD_HH__
#include <string>
#include "base/types.hh"
#include "kern/operatingsystem.hh"
class ThreadContext;
class LiveProcess;
///
/// This class encapsulates the types, structures, constants,
/// functions, and syscall-number mappings specific to the Alpha FreeBSD
/// syscall interface.
///
class FreeBSD : public OperatingSystem
{
public:
//@{
/// Basic FreeBSD types.
typedef uint64_t size_t;
typedef uint64_t off_t;
typedef int64_t time_t;
typedef int64_t clock_t;
typedef uint32_t uid_t;
typedef uint32_t gid_t;
//@}
/// Clock ticks per second, for times().
static const int M5_SC_CLK_TCK = 100;
//@{
/// ioctl() command codes.
static const unsigned TGT_TIOCGETA = 0x402c7413;
static const unsigned TGT_TIOCSETA = 0x802c7414;
static const unsigned TGT_TIOCSETAW = 0x802c7415;
static const unsigned TGT_FIONREAD = 0x4004667f;
//@}
/// Return true for the ioctl codes for which we return ENOTTY
/// *without* printing a warning, since we know that ENOTTY is the
/// correct thing to return (and not just a sign that we don't
/// recognize the ioctl code.
static bool
isTtyReq(unsigned req)
{
switch (req) {
case TGT_TIOCGETA:
case TGT_TIOCSETA:
case TGT_TIOCSETAW:
case TGT_FIONREAD:
return true;
default:
return false;
}
}
/// Resource constants for getrlimit().
static const unsigned TGT_RLIMIT_CPU = 0;
static const unsigned TGT_RLIMIT_FSIZE = 1;
static const unsigned TGT_RLIMIT_DATA = 2;
static const unsigned TGT_RLIMIT_STACK = 3;
static const unsigned TGT_RLIMIT_CORE = 4;
static const unsigned TGT_RLIMIT_RSS = 5;
static const unsigned TGT_RLIMIT_MEMLOCK = 6;
static const unsigned TGT_RLIMIT_NPROC = 7;
static const unsigned TGT_RLIMIT_NOFILE = 8;
static const unsigned TGT_RLIMIT_SBSIZE = 9;
static const unsigned TGT_RLIMIT_VMEM = 10;
static const unsigned TGT_RLIMIT_AS = TGT_RLIMIT_VMEM;
static const unsigned TGT_RLIMIT_NPTS = 11;
static const unsigned TGT_RLIMIT_SWAP = 12;
static const unsigned TGT_RLIMIT_KQUEUES = 13;
/// For getrusage().
static const int TGT_RUSAGE_SELF = 0;
static const int TGT_RUSAGE_CHILDREN = -1;
static const int TGT_RUSAGE_THREAD = 1;
// for *at syscalls
static const int TGT_AT_FDCWD = -100;
}; // class FreeBSD
#endif // __FREEBSD_HH__

View file

@ -77,6 +77,7 @@
#include "arch/mips/linux/process.hh"
#elif THE_ISA == ARM_ISA
#include "arch/arm/linux/process.hh"
#include "arch/arm/freebsd/process.hh"
#elif THE_ISA == X86_ISA
#include "arch/x86/linux/process.hh"
#elif THE_ISA == POWER_ISA
@ -736,6 +737,15 @@ LiveProcess::create(LiveProcessParams * params)
objFile->getArch());
}
break;
case ObjectFile::FreeBSD:
if (arch == ObjectFile::Arm64) {
process = new ArmFreebsdProcess64(params, objFile,
objFile->getArch());
} else {
process = new ArmFreebsdProcess32(params, objFile,
objFile->getArch());
}
break;
case ObjectFile::LinuxArmOABI:
fatal("M5 does not support ARM OABI binaries. Please recompile with an"
" EABI compiler.");