diff options
85 files changed, 2615 insertions, 1797 deletions
diff --git a/SConscript b/SConscript index 921b8bc84..05515562f 100644 --- a/SConscript +++ b/SConscript @@ -88,6 +88,7 @@ base_sources = Split(''' cpu/static_inst.cc cpu/sampler/sampler.cc + mem/request.cc mem/connector.cc mem/mem_object.cc mem/physical.cc @@ -183,11 +184,20 @@ full_system_sources = Split(''' cpu/profile.cc dev/alpha_console.cc + dev/baddev.cc dev/disk_image.cc dev/io_device.cc + dev/isa_fake.cc + dev/pciconfigall.cc dev/platform.cc dev/simconsole.cc dev/simple_disk.cc + dev/tsunami.cc + dev/tsunami_cchip.cc + dev/tsunami_io.cc + dev/tsunami_fake.cc + dev/tsunami_pchip.cc + dev/uart.cc dev/uart8250.cc @@ -203,7 +213,6 @@ full_system_sources = Split(''' sim/pseudo_inst.cc ''') -# dev/baddev.cc # dev/etherbus.cc # dev/etherdump.cc # dev/etherint.cc @@ -213,16 +222,10 @@ full_system_sources = Split(''' # dev/ide_ctrl.cc # dev/ide_disk.cc # dev/ns_gige.cc -# dev/pciconfigall.cc # dev/pcidev.cc # dev/pcifake.cc # dev/pktfifo.cc # dev/sinic.cc -# dev/tsunami.cc -# dev/tsunami_cchip.cc -# dev/isa_fake.cc -# dev/tsunami_io.cc -# dev/tsunami_pchip.cc if env['TARGET_ISA'] == 'alpha': full_system_sources += Split(''' @@ -254,17 +257,16 @@ turbolaser_sources = Split(''' # Syscall emulation (non-full-system) sources syscall_emulation_sources = Split(''' - kern/linux/linux.cc mem/translating_port.cc mem/page_table.cc sim/process.cc sim/syscall_emul.cc ''') -if env['TARGET_ISA'] == 'alpha': - syscall_emulation_sources += Split(''' - kern/tru64/tru64.cc - ''') +#if env['TARGET_ISA'] == 'alpha': +# syscall_emulation_sources += Split(''' +# kern/tru64/tru64.cc +# ''') alpha_eio_sources = Split(''' encumbered/eio/exolex.cc diff --git a/arch/alpha/SConscript b/arch/alpha/SConscript index ed7fd3404..1b20f8b1f 100644 --- a/arch/alpha/SConscript +++ b/arch/alpha/SConscript @@ -65,7 +65,9 @@ full_system_sources = Split(''' # Syscall emulation (non-full-system) sources syscall_emulation_sources = Split(''' + linux/linux.cc linux/process.cc + tru64/tru64.cc tru64/process.cc process.cc ''') diff --git a/arch/alpha/linux/linux.cc b/arch/alpha/linux/linux.cc new file mode 100644 index 000000000..f123ae1fe --- /dev/null +++ b/arch/alpha/linux/linux.cc @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * 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/alpha/linux/linux.hh" + +// open(2) flags translation table +OpenFlagTransTable AlphaLinux::openFlagTable[] = { +#ifdef _MSC_VER + { AlphaLinux::TGT_O_RDONLY, _O_RDONLY }, + { AlphaLinux::TGT_O_WRONLY, _O_WRONLY }, + { AlphaLinux::TGT_O_RDWR, _O_RDWR }, + { AlphaLinux::TGT_O_APPEND, _O_APPEND }, + { AlphaLinux::TGT_O_CREAT, _O_CREAT }, + { AlphaLinux::TGT_O_TRUNC, _O_TRUNC }, + { AlphaLinux::TGT_O_EXCL, _O_EXCL }, +#ifdef _O_NONBLOCK + { AlphaLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, +#endif +#ifdef _O_NOCTTY + { AlphaLinux::TGT_O_NOCTTY, _O_NOCTTY }, +#endif +#ifdef _O_SYNC + { AlphaLinux::TGT_O_SYNC, _O_SYNC }, +#endif +#else /* !_MSC_VER */ + { AlphaLinux::TGT_O_RDONLY, O_RDONLY }, + { AlphaLinux::TGT_O_WRONLY, O_WRONLY }, + { AlphaLinux::TGT_O_RDWR, O_RDWR }, + { AlphaLinux::TGT_O_APPEND, O_APPEND }, + { AlphaLinux::TGT_O_CREAT, O_CREAT }, + { AlphaLinux::TGT_O_TRUNC, O_TRUNC }, + { AlphaLinux::TGT_O_EXCL, O_EXCL }, + { AlphaLinux::TGT_O_NONBLOCK, O_NONBLOCK }, + { AlphaLinux::TGT_O_NOCTTY, O_NOCTTY }, +#ifdef O_SYNC + { AlphaLinux::TGT_O_SYNC, O_SYNC }, +#endif +#endif /* _MSC_VER */ +}; + +const int AlphaLinux::NUM_OPEN_FLAGS = + (sizeof(AlphaLinux::openFlagTable)/sizeof(AlphaLinux::openFlagTable[0])); + + + diff --git a/arch/alpha/linux/linux.hh b/arch/alpha/linux/linux.hh new file mode 100644 index 000000000..f04e2bfa8 --- /dev/null +++ b/arch/alpha/linux/linux.hh @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * 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 __ALPHA_ALPHA_LINUX_HH +#define __ALPHA_ALPHA_LINUX_HH + +#include "kern/linux/linux.hh" + +/* AlphaLinux class contains static constants/definitions/misc. + * structures which are specific to the Linux OS AND the Alpha + * architecture + */ +class AlphaLinux : public Linux +{ + 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; + + //@{ + /// open(2) flag values. + static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 00000002; //!< O_RDWR + static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK + static const int TGT_O_APPEND = 00000010; //!< O_APPEND + static const int TGT_O_CREAT = 00001000; //!< O_CREAT + static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC + static const int TGT_O_EXCL = 00004000; //!< O_EXCL + static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY + static const int TGT_O_SYNC = 00040000; //!< O_SYNC + static const int TGT_O_DRD = 00100000; //!< O_DRD + static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO + static const int TGT_O_CACHE = 00400000; //!< O_CACHE + static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC + static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC + //@} + + /// For mmap(). + static const unsigned TGT_MAP_ANONYMOUS = 0x10; + + //@{ + /// For getsysinfo(). + static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string + static const unsigned GSI_CPU_INFO = 59; //!< CPU information + static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type + static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine + static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system + static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB + static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz + static const unsigned GSI_IEEE_FP_CONTROL = 45; + //@} + + //@{ + /// For getrusage(). + static const int TGT_RUSAGE_SELF = 0; + static const int TGT_RUSAGE_CHILDREN = -1; + static const int TGT_RUSAGE_BOTH = -2; + //@} + + //@{ + /// For setsysinfo(). + static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control() + //@} + + //@{ + /// ioctl() command codes. + static const unsigned TIOCGETP = 0x40067408; + static const unsigned TIOCSETP = 0x80067409; + static const unsigned TIOCSETN = 0x8006740a; + static const unsigned TIOCSETC = 0x80067411; + static const unsigned TIOCGETC = 0x40067412; + static const unsigned FIONREAD = 0x4004667f; + static const unsigned TIOCISATTY = 0x2000745e; + static const unsigned TIOCGETS = 0x402c7413; + static const unsigned TIOCGETA = 0x40127417; + //@} + + /// For table(). + static const int TBL_SYSINFO = 12; + + /// 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_NOFILE = 6, + TGT_RLIMIT_AS = 7, + TGT_RLIMIT_VMEM = 7, + TGT_RLIMIT_NPROC = 8, + TGT_RLIMIT_MEMLOCK = 9, + TGT_RLIMIT_LOCKS = 10 + }; +}; + +#endif diff --git a/arch/alpha/linux/process.cc b/arch/alpha/linux/process.cc index 4bc283563..9f4f65db8 100644 --- a/arch/alpha/linux/process.cc +++ b/arch/alpha/linux/process.cc @@ -26,6 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "arch/alpha/linux/linux.hh" #include "arch/alpha/linux/process.hh" #include "arch/alpha/isa_traits.hh" @@ -132,7 +133,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 12 */ SyscallDesc("chdir", unimplementedFunc), /* 13 */ SyscallDesc("fchdir", unimplementedFunc), /* 14 */ SyscallDesc("mknod", unimplementedFunc), - /* 15 */ SyscallDesc("chmod", chmodFunc<Linux>), + /* 15 */ SyscallDesc("chmod", chmodFunc<AlphaLinux>), /* 16 */ SyscallDesc("chown", chownFunc), /* 17 */ SyscallDesc("brk", obreakFunc), /* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc), @@ -162,7 +163,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 42 */ SyscallDesc("pipe", pipePseudoFunc), /* 43 */ SyscallDesc("osf_set_program_attributes", unimplementedFunc), /* 44 */ SyscallDesc("osf_profil", unimplementedFunc), - /* 45 */ SyscallDesc("open", openFunc<Linux>), + /* 45 */ SyscallDesc("open", openFunc<AlphaLinux>), /* 46 */ SyscallDesc("osf_old_sigaction", unimplementedFunc), /* 47 */ SyscallDesc("getxgid", getgidPseudoFunc), /* 48 */ SyscallDesc("osf_sigprocmask", ignoreFunc), @@ -171,7 +172,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 51 */ SyscallDesc("acct", unimplementedFunc), /* 52 */ SyscallDesc("sigpending", unimplementedFunc), /* 53 */ SyscallDesc("osf_classcntl", unimplementedFunc), - /* 54 */ SyscallDesc("ioctl", ioctlFunc<Linux>), + /* 54 */ SyscallDesc("ioctl", ioctlFunc<AlphaLinux>), /* 55 */ SyscallDesc("osf_reboot", unimplementedFunc), /* 56 */ SyscallDesc("osf_revoke", unimplementedFunc), /* 57 */ SyscallDesc("symlink", unimplementedFunc), @@ -184,11 +185,11 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 64 */ SyscallDesc("getpagesize", getpagesizeFunc), /* 65 */ SyscallDesc("osf_mremap", unimplementedFunc), /* 66 */ SyscallDesc("vfork", unimplementedFunc), - /* 67 */ SyscallDesc("stat", statFunc<Linux>), - /* 68 */ SyscallDesc("lstat", lstatFunc<Linux>), + /* 67 */ SyscallDesc("stat", statFunc<AlphaLinux>), + /* 68 */ SyscallDesc("lstat", lstatFunc<AlphaLinux>), /* 69 */ SyscallDesc("osf_sbrk", unimplementedFunc), /* 70 */ SyscallDesc("osf_sstk", unimplementedFunc), - /* 71 */ SyscallDesc("mmap", mmapFunc<Linux>), + /* 71 */ SyscallDesc("mmap", mmapFunc<AlphaLinux>), /* 72 */ SyscallDesc("osf_old_vadvise", unimplementedFunc), /* 73 */ SyscallDesc("munmap", munmapFunc), /* 74 */ SyscallDesc("mprotect", ignoreFunc), @@ -208,7 +209,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 88 */ SyscallDesc("sethostname", unimplementedFunc), /* 89 */ SyscallDesc("getdtablesize", unimplementedFunc), /* 90 */ SyscallDesc("dup2", unimplementedFunc), - /* 91 */ SyscallDesc("fstat", fstatFunc<Linux>), + /* 91 */ SyscallDesc("fstat", fstatFunc<AlphaLinux>), /* 92 */ SyscallDesc("fcntl", fcntlFunc), /* 93 */ SyscallDesc("osf_select", unimplementedFunc), /* 94 */ SyscallDesc("poll", unimplementedFunc), @@ -238,10 +239,10 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 118 */ SyscallDesc("getsockopt", unimplementedFunc), /* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc), /* 120 */ SyscallDesc("readv", unimplementedFunc), - /* 121 */ SyscallDesc("writev", writevFunc<Linux>), + /* 121 */ SyscallDesc("writev", writevFunc<AlphaLinux>), /* 122 */ SyscallDesc("osf_settimeofday", unimplementedFunc), /* 123 */ SyscallDesc("fchown", fchownFunc), - /* 124 */ SyscallDesc("fchmod", fchmodFunc<Linux>), + /* 124 */ SyscallDesc("fchmod", fchmodFunc<AlphaLinux>), /* 125 */ SyscallDesc("recvfrom", unimplementedFunc), /* 126 */ SyscallDesc("setreuid", unimplementedFunc), /* 127 */ SyscallDesc("setregid", unimplementedFunc), @@ -261,7 +262,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 141 */ SyscallDesc("getpeername", unimplementedFunc), /* 142 */ SyscallDesc("osf_gethostid", unimplementedFunc), /* 143 */ SyscallDesc("osf_sethostid", unimplementedFunc), - /* 144 */ SyscallDesc("getrlimit", getrlimitFunc<Linux>), + /* 144 */ SyscallDesc("getrlimit", getrlimitFunc<AlphaLinux>), /* 145 */ SyscallDesc("setrlimit", ignoreFunc), /* 146 */ SyscallDesc("osf_old_killpg", unimplementedFunc), /* 147 */ SyscallDesc("setsid", unimplementedFunc), @@ -479,12 +480,12 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 356 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc), /* 357 */ SyscallDesc("rt_sigsuspend", unimplementedFunc), /* 358 */ SyscallDesc("select", unimplementedFunc), - /* 359 */ SyscallDesc("gettimeofday", gettimeofdayFunc<Linux>), + /* 359 */ SyscallDesc("gettimeofday", gettimeofdayFunc<AlphaLinux>), /* 360 */ SyscallDesc("settimeofday", unimplementedFunc), /* 361 */ SyscallDesc("getitimer", unimplementedFunc), /* 362 */ SyscallDesc("setitimer", unimplementedFunc), - /* 363 */ SyscallDesc("utimes", utimesFunc<Linux>), - /* 364 */ SyscallDesc("getrusage", getrusageFunc<Linux>), + /* 363 */ SyscallDesc("utimes", utimesFunc<AlphaLinux>), + /* 364 */ SyscallDesc("getrusage", getrusageFunc<AlphaLinux>), /* 365 */ SyscallDesc("wait4", unimplementedFunc), /* 366 */ SyscallDesc("adjtimex", unimplementedFunc), /* 367 */ SyscallDesc("getcwd", unimplementedFunc), @@ -546,8 +547,8 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 423 */ SyscallDesc("semtimedop", unimplementedFunc), /* 424 */ SyscallDesc("tgkill", unimplementedFunc), /* 425 */ SyscallDesc("stat64", unimplementedFunc), - /* 426 */ SyscallDesc("lstat64", lstat64Func<Linux>), - /* 427 */ SyscallDesc("fstat64", fstat64Func<Linux>), + /* 426 */ SyscallDesc("lstat64", lstat64Func<AlphaLinux>), + /* 427 */ SyscallDesc("fstat64", fstat64Func<AlphaLinux>), /* 428 */ SyscallDesc("vserver", unimplementedFunc), /* 429 */ SyscallDesc("mbind", unimplementedFunc), /* 430 */ SyscallDesc("get_mempolicy", unimplementedFunc), diff --git a/arch/alpha/linux/system.cc b/arch/alpha/linux/system.cc index edd2cdaf1..cdb96096c 100644 --- a/arch/alpha/linux/system.cc +++ b/arch/alpha/linux/system.cc @@ -73,7 +73,7 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p) * kernel arguments directly into the kernel's memory. */ virtPort.writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(), - CommandLineSize); + params()->boot_osflags.length()+1); /** * find the address of the est_cycle_freq variable and insert it diff --git a/arch/alpha/system.cc b/arch/alpha/system.cc index 21ffa350b..4234019cd 100644 --- a/arch/alpha/system.cc +++ b/arch/alpha/system.cc @@ -107,9 +107,9 @@ AlphaSystem::AlphaSystem(Params *p) if (consoleSymtab->findAddress("m5_rpb", addr)) { uint64_t data; data = htog(params()->system_type); - virtPort.write(addr, data); + virtPort.write(addr+0x50, data); data = htog(params()->system_rev); - virtPort.write(addr, data); + virtPort.write(addr+0x58, data); } else panic("could not find hwrpb\n"); diff --git a/arch/alpha/tlb.cc b/arch/alpha/tlb.cc index a1a7c9366..877822c31 100644 --- a/arch/alpha/tlb.cc +++ b/arch/alpha/tlb.cc @@ -94,7 +94,7 @@ AlphaTLB::lookup(Addr vpn, uint8_t asn) const Fault -AlphaTLB::checkCacheability(CpuRequestPtr &req) +AlphaTLB::checkCacheability(RequestPtr &req) { // in Alpha, cacheability is controlled by upper-level bits of the // physical address @@ -109,20 +109,20 @@ AlphaTLB::checkCacheability(CpuRequestPtr &req) #if ALPHA_TLASER - if (req->paddr & PAddrUncachedBit39) { + if (req->getPaddr() & PAddrUncachedBit39) { #else - if (req->paddr & PAddrUncachedBit43) { + if (req->getPaddr() & PAddrUncachedBit43) { #endif // IPR memory space not implemented - if (PAddrIprSpace(req->paddr)) { + if (PAddrIprSpace(req->getPaddr())) { return new UnimpFault("IPR memory space not implemented!"); } else { // mark request as uncacheable - req->flags |= UNCACHEABLE; + req->setFlags(req->getFlags() | UNCACHEABLE); #if !ALPHA_TLASER // Clear bits 42:35 of the physical address (10-2 in Tsunami manual) - req->paddr &= PAddrUncachedMask; + req->setPaddr(req->getPaddr() & PAddrUncachedMask); #endif } } @@ -283,22 +283,22 @@ AlphaITB::regStats() Fault -AlphaITB::translate(CpuRequestPtr &req, ExecContext *xc) const +AlphaITB::translate(RequestPtr &req, ExecContext *xc) const { - if (AlphaISA::PcPAL(req->vaddr)) { + if (AlphaISA::PcPAL(req->getVaddr())) { // strip off PAL PC marker (lsb is 1) - req->paddr = (req->vaddr & ~3) & PAddrImplMask; + req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask); hits++; return NoFault; } - if (req->flags & PHYSICAL) { - req->paddr = req->vaddr; + if (req->getFlags() & PHYSICAL) { + req->setPaddr(req->getVaddr()); } else { // verify that this is a good virtual address - if (!validVirtualAddress(req->vaddr)) { + if (!validVirtualAddress(req->getVaddr())) { acv++; - return new ItbAcvFault(req->vaddr); + return new ItbAcvFault(req->getVaddr()); } @@ -306,47 +306,48 @@ AlphaITB::translate(CpuRequestPtr &req, ExecContext *xc) const // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6 #if ALPHA_TLASER if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && - VAddrSpaceEV5(req->vaddr) == 2) { + VAddrSpaceEV5(req->getVaddr()) == 2) { #else - if (VAddrSpaceEV6(req->vaddr) == 0x7e) { + if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { #endif // only valid in kernel mode if (ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM)) != AlphaISA::mode_kernel) { acv++; - return new ItbAcvFault(req->vaddr); + return new ItbAcvFault(req->getVaddr()); } - req->paddr = req->vaddr & PAddrImplMask; + req->setPaddr(req->getVaddr() & PAddrImplMask); #if !ALPHA_TLASER // sign extend the physical address properly - if (req->paddr & PAddrUncachedBit40) - req->paddr |= ULL(0xf0000000000); + if (req->getPaddr() & PAddrUncachedBit40) + req->setPaddr(req->getPaddr() | ULL(0xf0000000000)); else - req->paddr &= ULL(0xffffffffff); + req->setPaddr(req->getPaddr() & ULL(0xffffffffff)); #endif } else { // not a physical address: need to look up pte int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN)); - AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->vaddr).vpn(), + AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(), asn); if (!pte) { misses++; - return new ItbPageFault(req->vaddr); + return new ItbPageFault(req->getVaddr()); } - req->paddr = (pte->ppn << AlphaISA::PageShift) + - (AlphaISA::VAddr(req->vaddr).offset() & ~3); + req->setPaddr((pte->ppn << AlphaISA::PageShift) + + (AlphaISA::VAddr(req->getVaddr()).offset() + & ~3)); // check permissions for this access if (!(pte->xre & (1 << ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM))))) { // instruction access fault acv++; - return new ItbAcvFault(req->vaddr); + return new ItbAcvFault(req->getVaddr()); } hits++; @@ -354,7 +355,7 @@ AlphaITB::translate(CpuRequestPtr &req, ExecContext *xc) const } // check that the physical address is ok (catch bad physical addresses) - if (req->paddr & ~PAddrImplMask) + if (req->getPaddr() & ~PAddrImplMask) return genMachineCheckFault(); return checkCacheability(req); @@ -439,7 +440,7 @@ AlphaDTB::regStats() } Fault -AlphaDTB::translate(CpuRequestPtr &req, ExecContext *xc, bool write) const +AlphaDTB::translate(RequestPtr &req, ExecContext *xc, bool write) const { Addr pc = xc->readPC(); @@ -450,38 +451,38 @@ AlphaDTB::translate(CpuRequestPtr &req, ExecContext *xc, bool write) const /** * Check for alignment faults */ - if (req->vaddr & (req->size - 1)) { - DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr, - req->size); + if (req->getVaddr() & (req->getSize() - 1)) { + DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(), + req->getSize()); uint64_t flags = write ? MM_STAT_WR_MASK : 0; - return new DtbAlignmentFault(req->vaddr, req->flags, flags); + return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags); } if (pc & 0x1) { - mode = (req->flags & ALTMODE) ? + mode = (req->getFlags() & ALTMODE) ? (AlphaISA::mode_type)ALT_MODE_AM( xc->readMiscReg(AlphaISA::IPR_ALT_MODE)) : AlphaISA::mode_kernel; } - if (req->flags & PHYSICAL) { - req->paddr = req->vaddr; + if (req->getFlags() & PHYSICAL) { + req->setPaddr(req->getVaddr()); } else { // verify that this is a good virtual address - if (!validVirtualAddress(req->vaddr)) { + if (!validVirtualAddress(req->getVaddr())) { if (write) { write_acv++; } else { read_acv++; } uint64_t flags = (write ? MM_STAT_WR_MASK : 0) | MM_STAT_BAD_VA_MASK | MM_STAT_ACV_MASK; - return new DtbPageFault(req->vaddr, req->flags, flags); + return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); } // Check for "superpage" mapping #if ALPHA_TLASER if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && - VAddrSpaceEV5(req->vaddr) == 2) { + VAddrSpaceEV5(req->getVaddr()) == 2) { #else - if (VAddrSpaceEV6(req->vaddr) == 0x7e) { + if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { #endif // only valid in kernel mode @@ -490,17 +491,17 @@ AlphaDTB::translate(CpuRequestPtr &req, ExecContext *xc, bool write) const if (write) { write_acv++; } else { read_acv++; } uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK); - return new DtbAcvFault(req->vaddr, req->flags, flags); + return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); } - req->paddr = req->vaddr & PAddrImplMask; + req->setPaddr(req->getVaddr() & PAddrImplMask); #if !ALPHA_TLASER // sign extend the physical address properly - if (req->paddr & PAddrUncachedBit40) - req->paddr |= ULL(0xf0000000000); + if (req->getPaddr() & PAddrUncachedBit40) + req->setPaddr(req->getPaddr() | ULL(0xf0000000000)); else - req->paddr &= ULL(0xffffffffff); + req->setPaddr(req->getPaddr() & ULL(0xffffffffff)); #endif } else { @@ -512,7 +513,7 @@ AlphaDTB::translate(CpuRequestPtr &req, ExecContext *xc, bool write) const int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN)); // not a physical address: need to look up pte - AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->vaddr).vpn(), + AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(), asn); if (!pte) { @@ -520,15 +521,15 @@ AlphaDTB::translate(CpuRequestPtr &req, ExecContext *xc, bool write) const if (write) { write_misses++; } else { read_misses++; } uint64_t flags = (write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK; - return (req->flags & VPTE) ? - (Fault)(new PDtbMissFault(req->vaddr, req->flags, + return (req->getFlags() & VPTE) ? + (Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(), flags)) : - (Fault)(new NDtbMissFault(req->vaddr, req->flags, + (Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(), flags)); } - req->paddr = (pte->ppn << AlphaISA::PageShift) + - AlphaISA::VAddr(req->vaddr).offset(); + req->setPaddr((pte->ppn << AlphaISA::PageShift) + + AlphaISA::VAddr(req->getVaddr()).offset()); if (write) { if (!(pte->xwe & MODE2MASK(mode))) { @@ -537,25 +538,25 @@ AlphaDTB::translate(CpuRequestPtr &req, ExecContext *xc, bool write) const uint64_t flags = MM_STAT_WR_MASK | MM_STAT_ACV_MASK | (pte->fonw ? MM_STAT_FONW_MASK : 0); - return new DtbPageFault(req->vaddr, req->flags, flags); + return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); } if (pte->fonw) { write_acv++; uint64_t flags = MM_STAT_WR_MASK | MM_STAT_FONW_MASK; - return new DtbPageFault(req->vaddr, req->flags, flags); + return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); } } else { if (!(pte->xre & MODE2MASK(mode))) { read_acv++; uint64_t flags = MM_STAT_ACV_MASK | (pte->fonr ? MM_STAT_FONR_MASK : 0); - return new DtbAcvFault(req->vaddr, req->flags, flags); + return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); } if (pte->fonr) { read_acv++; uint64_t flags = MM_STAT_FONR_MASK; - return new DtbPageFault(req->vaddr, req->flags, flags); + return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); } } } @@ -567,7 +568,7 @@ AlphaDTB::translate(CpuRequestPtr &req, ExecContext *xc, bool write) const } // check that the physical address is ok (catch bad physical addresses) - if (req->paddr & ~PAddrImplMask) + if (req->getPaddr() & ~PAddrImplMask) return genMachineCheckFault(); return checkCacheability(req); diff --git a/arch/alpha/tlb.hh b/arch/alpha/tlb.hh index 39faffbee..f6256020e 100644 --- a/arch/alpha/tlb.hh +++ b/arch/alpha/tlb.hh @@ -73,7 +73,7 @@ class AlphaTLB : public SimObject return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask); } - static Fault checkCacheability(CpuRequestPtr &req); + static Fault checkCacheability(RequestPtr &req); // Checkpointing virtual void serialize(std::ostream &os); @@ -92,7 +92,7 @@ class AlphaITB : public AlphaTLB AlphaITB(const std::string &name, int size); virtual void regStats(); - Fault translate(CpuRequestPtr &req, ExecContext *xc) const; + Fault translate(RequestPtr &req, ExecContext *xc) const; }; class AlphaDTB : public AlphaTLB @@ -115,7 +115,7 @@ class AlphaDTB : public AlphaTLB AlphaDTB(const std::string &name, int size); virtual void regStats(); - Fault translate(CpuRequestPtr &req, ExecContext *xc, bool write) const; + Fault translate(RequestPtr &req, ExecContext *xc, bool write) const; }; #endif // __ALPHA_MEMORY_HH__ diff --git a/arch/alpha/tru64/process.cc b/arch/alpha/tru64/process.cc index 355d7f3e6..55f75f7d0 100644 --- a/arch/alpha/tru64/process.cc +++ b/arch/alpha/tru64/process.cc @@ -26,10 +26,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "arch/alpha/tru64/tru64.hh" #include "arch/alpha/isa_traits.hh" #include "arch/alpha/tru64/process.hh" + #include "cpu/exec_context.hh" #include "kern/tru64/tru64.hh" + #include "sim/process.hh" #include "sim/syscall_emul.hh" @@ -41,7 +44,7 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - TypedBufferArg<Tru64::utsname> name(xc->getSyscallArg(0)); + TypedBufferArg<AlphaTru64::utsname> name(xc->getSyscallArg(0)); strcpy(name->sysname, "OSF1"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -63,29 +66,29 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, switch (op) { - case Tru64::GSI_MAX_CPU: { + case AlphaTru64::GSI_MAX_CPU: { TypedBufferArg<uint32_t> max_cpu(xc->getSyscallArg(1)); *max_cpu = htog((uint32_t)process->numCpus()); max_cpu.copyOut(xc->getMemPort()); return 1; } - case Tru64::GSI_CPUS_IN_BOX: { + case AlphaTru64::GSI_CPUS_IN_BOX: { TypedBufferArg<uint32_t> cpus_in_box(xc->getSyscallArg(1)); *cpus_in_box = htog((uint32_t)process->numCpus()); cpus_in_box.copyOut(xc->getMemPort()); return 1; } - case Tru64::GSI_PHYSMEM: { + case AlphaTru64::GSI_PHYSMEM: { TypedBufferArg<uint64_t> physmem(xc->getSyscallArg(1)); *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB physmem.copyOut(xc->getMemPort()); return 1; } - case Tru64::GSI_CPU_INFO: { - TypedBufferArg<Tru64::cpu_info> infop(xc->getSyscallArg(1)); + case AlphaTru64::GSI_CPU_INFO: { + TypedBufferArg<AlphaTru64::cpu_info> infop(xc->getSyscallArg(1)); infop->current_cpu = htog(0); infop->cpus_in_box = htog(process->numCpus()); @@ -101,14 +104,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, return 1; } - case Tru64::GSI_PROC_TYPE: { + case AlphaTru64::GSI_PROC_TYPE: { TypedBufferArg<uint64_t> proc_type(xc->getSyscallArg(1)); *proc_type = htog((uint64_t)11); proc_type.copyOut(xc->getMemPort()); return 1; } - case Tru64::GSI_PLATFORM_NAME: { + case AlphaTru64::GSI_PLATFORM_NAME: { BufferArg bufArg(xc->getSyscallArg(1), nbytes); strncpy((char *)bufArg.bufferPtr(), "COMPAQ Professional Workstation XP1000", @@ -117,7 +120,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, return 1; } - case Tru64::GSI_CLK_TCK: { + case AlphaTru64::GSI_CLK_TCK: { TypedBufferArg<uint64_t> clk_hz(xc->getSyscallArg(1)); *clk_hz = htog((uint64_t)1024); clk_hz.copyOut(xc->getMemPort()); @@ -140,7 +143,7 @@ setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, unsigned op = xc->getSyscallArg(0); switch (op) { - case Tru64::SSI_IEEE_FP_CONTROL: + case AlphaTru64::SSI_IEEE_FP_CONTROL: warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n", xc->getSyscallArg(1)); break; @@ -154,8 +157,48 @@ setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, } +/// Target table() handler. +static +SyscallReturn tableFunc(SyscallDesc *desc, int callnum,Process *process, + ExecContext *xc) +{ + using namespace std; + using namespace TheISA; + + int id = xc->getSyscallArg(0); // table ID + int index = xc->getSyscallArg(1); // index into table + // arg 2 is buffer pointer; type depends on table ID + int nel = xc->getSyscallArg(3); // number of elements + int lel = xc->getSyscallArg(4); // expected element size + + switch (id) { + case AlphaTru64::TBL_SYSINFO: { + if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo)) + return -EINVAL; + TypedBufferArg<Tru64::tbl_sysinfo> elp(xc->getSyscallArg(2)); + + const int clk_hz = one_million; + elp->si_user = htog(curTick / (Clock::Frequency / clk_hz)); + elp->si_nice = htog(0); + elp->si_sys = htog(0); + elp->si_idle = htog(0); + elp->wait = htog(0); + elp->si_hz = htog(clk_hz); + elp->si_phz = htog(clk_hz); + elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch? + elp->si_max_procs = htog(process->numCpus()); + elp.copyOut(xc->getMemPort()); + return 0; + } + + default: + cerr << "table(): id " << id << " unknown." << endl; + return -EINVAL; + } +} + SyscallDesc AlphaTru64Process::syscallDescs[] = { - /* 0 */ SyscallDesc("syscall (#0)", Tru64::indirectSyscallFunc, + /* 0 */ SyscallDesc("syscall (#0)", AlphaTru64::indirectSyscallFunc, SyscallDesc::SuppressReturnValue), /* 1 */ SyscallDesc("exit", exitFunc), /* 2 */ SyscallDesc("fork", unimplementedFunc), @@ -201,7 +244,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 42 */ SyscallDesc("pipe", unimplementedFunc), /* 43 */ SyscallDesc("set_program_attributes", unimplementedFunc), /* 44 */ SyscallDesc("profil", unimplementedFunc), - /* 45 */ SyscallDesc("open", openFunc<Tru64>), + /* 45 */ SyscallDesc("open", openFunc<AlphaTru64>), /* 46 */ SyscallDesc("obsolete osigaction", unimplementedFunc), /* 47 */ SyscallDesc("getgid", getgidPseudoFunc), /* 48 */ SyscallDesc("sigprocmask", ignoreFunc), @@ -210,7 +253,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 51 */ SyscallDesc("acct", unimplementedFunc), /* 52 */ SyscallDesc("sigpending", unimplementedFunc), /* 53 */ SyscallDesc("classcntl", unimplementedFunc), - /* 54 */ SyscallDesc("ioctl", ioctlFunc<Tru64>), + /* 54 */ SyscallDesc("ioctl", ioctlFunc<AlphaTru64>), /* 55 */ SyscallDesc("reboot", unimplementedFunc), /* 56 */ SyscallDesc("revoke", unimplementedFunc), /* 57 */ SyscallDesc("symlink", unimplementedFunc), @@ -223,11 +266,11 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 64 */ SyscallDesc("getpagesize", getpagesizeFunc), /* 65 */ SyscallDesc("mremap", unimplementedFunc), /* 66 */ SyscallDesc("vfork", unimplementedFunc), - /* 67 */ SyscallDesc("pre_F64_stat", statFunc<Tru64::PreF64>), - /* 68 */ SyscallDesc("pre_F64_lstat", lstatFunc<Tru64::PreF64>), + /* 67 */ SyscallDesc("pre_F64_stat", statFunc<AlphaTru64::PreF64>), + /* 68 */ SyscallDesc("pre_F64_lstat", lstatFunc<AlphaTru64::PreF64>), /* 69 */ SyscallDesc("sbrk", unimplementedFunc), /* 70 */ SyscallDesc("sstk", unimplementedFunc), - /* 71 */ SyscallDesc("mmap", mmapFunc<Tru64>), + /* 71 */ SyscallDesc("mmap", mmapFunc<AlphaTru64>), /* 72 */ SyscallDesc("ovadvise", unimplementedFunc), /* 73 */ SyscallDesc("munmap", munmapFunc), /* 74 */ SyscallDesc("mprotect", ignoreFunc), @@ -241,13 +284,13 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 82 */ SyscallDesc("setpgrp", unimplementedFunc), /* 83 */ SyscallDesc("setitimer", unimplementedFunc), /* 84 */ SyscallDesc("old_wait", unimplementedFunc), - /* 85 */ SyscallDesc("table", Tru64::tableFunc), + /* 85 */ SyscallDesc("table", tableFunc), /* 86 */ SyscallDesc("getitimer", unimplementedFunc), /* 87 */ SyscallDesc("gethostname", gethostnameFunc), /* 88 */ SyscallDesc("sethostname", unimplementedFunc), /* 89 */ SyscallDesc("getdtablesize", unimplementedFunc), /* 90 */ SyscallDesc("dup2", unimplementedFunc), - /* 91 */ SyscallDesc("pre_F64_fstat", fstatFunc<Tru64::PreF64>), + /* 91 */ SyscallDesc("pre_F64_fstat", fstatFunc<AlphaTru64::PreF64>), /* 92 */ SyscallDesc("fcntl", fcntlFunc), /* 93 */ SyscallDesc("select", unimplementedFunc), /* 94 */ SyscallDesc("poll", unimplementedFunc), @@ -259,7 +302,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 100 */ SyscallDesc("getpriority", unimplementedFunc), /* 101 */ SyscallDesc("old_send", unimplementedFunc), /* 102 */ SyscallDesc("old_recv", unimplementedFunc), - /* 103 */ SyscallDesc("sigreturn", Tru64::sigreturnFunc, + /* 103 */ SyscallDesc("sigreturn", AlphaTru64::sigreturnFunc, SyscallDesc::SuppressReturnValue), /* 104 */ SyscallDesc("bind", unimplementedFunc), /* 105 */ SyscallDesc("setsockopt", unimplementedFunc), @@ -273,8 +316,8 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 113 */ SyscallDesc("old_recvmsg", unimplementedFunc), /* 114 */ SyscallDesc("old_sendmsg", unimplementedFunc), /* 115 */ SyscallDesc("obsolete vtrace", unimplementedFunc), - /* 116 */ SyscallDesc("gettimeofday", gettimeofdayFunc<Tru64>), - /* 117 */ SyscallDesc("getrusage", getrusageFunc<Tru64>), + /* 116 */ SyscallDesc("gettimeofday", gettimeofdayFunc<AlphaTru64>), + /* 117 */ SyscallDesc("getrusage", getrusageFunc<AlphaTru64>), /* 118 */ SyscallDesc("getsockopt", unimplementedFunc), /* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc), /* 120 */ SyscallDesc("readv", unimplementedFunc), @@ -301,7 +344,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 141 */ SyscallDesc("old_getpeername", unimplementedFunc), /* 142 */ SyscallDesc("gethostid", unimplementedFunc), /* 143 */ SyscallDesc("sethostid", unimplementedFunc), - /* 144 */ SyscallDesc("getrlimit", getrlimitFunc<Tru64>), + /* 144 */ SyscallDesc("getrlimit", getrlimitFunc<AlphaTru64>), /* 145 */ SyscallDesc("setrlimit", ignoreFunc), /* 146 */ SyscallDesc("old_killpg", unimplementedFunc), /* 147 */ SyscallDesc("setsid", unimplementedFunc), @@ -316,9 +359,9 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 156 */ SyscallDesc("sigaction", ignoreFunc), /* 157 */ SyscallDesc("sigwaitprim", unimplementedFunc), /* 158 */ SyscallDesc("nfssvc", unimplementedFunc), - /* 159 */ SyscallDesc("getdirentries", Tru64::getdirentriesFunc), - /* 160 */ SyscallDesc("pre_F64_statfs", statfsFunc<Tru64::PreF64>), - /* 161 */ SyscallDesc("pre_F64_fstatfs", fstatfsFunc<Tru64::PreF64>), + /* 159 */ SyscallDesc("getdirentries", AlphaTru64::getdirentriesFunc), + /* 160 */ SyscallDesc("pre_F64_statfs", statfsFunc<AlphaTru64::PreF64>), + /* 161 */ SyscallDesc("pre_F64_fstatfs", fstatfsFunc<AlphaTru64::PreF64>), /* 162 */ SyscallDesc("unknown #162", unimplementedFunc), /* 163 */ SyscallDesc("async_daemon", unimplementedFunc), /* 164 */ SyscallDesc("getfh", unimplementedFunc), @@ -381,11 +424,11 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 221 */ SyscallDesc("unknown #221", unimplementedFunc), /* 222 */ SyscallDesc("security", unimplementedFunc), /* 223 */ SyscallDesc("kloadcall", unimplementedFunc), - /* 224 */ SyscallDesc("stat", statFunc<Tru64::F64>), - /* 225 */ SyscallDesc("lstat", lstatFunc<Tru64::F64>), - /* 226 */ SyscallDesc("fstat", fstatFunc<Tru64::F64>), - /* 227 */ SyscallDesc("statfs", statfsFunc<Tru64::F64>), - /* 228 */ SyscallDesc("fstatfs", fstatfsFunc<Tru64::F64>), + /* 224 */ SyscallDesc("stat", statFunc<AlphaTru64::F64>), + /* 225 */ SyscallDesc("lstat", lstatFunc<AlphaTru64::F64>), + /* 226 */ SyscallDesc("fstat", fstatFunc<AlphaTru64::F64>), + /* 227 */ SyscallDesc("statfs", statfsFunc<AlphaTru64::F64>), + /* 228 */ SyscallDesc("fstatfs", fstatfsFunc<AlphaTru64::F64>), /* 229 */ SyscallDesc("getfsstat", unimplementedFunc), /* 230 */ SyscallDesc("gettimeofday64", unimplementedFunc), /* 231 */ SyscallDesc("settimeofday64", unimplementedFunc), @@ -430,13 +473,13 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { SyscallDesc AlphaTru64Process::machSyscallDescs[] = { /* 0 */ SyscallDesc("kern_invalid", unimplementedFunc), - /* 1 */ SyscallDesc("m5_mutex_lock", Tru64::m5_mutex_lockFunc), - /* 2 */ SyscallDesc("m5_mutex_trylock", Tru64::m5_mutex_trylockFunc), - /* 3 */ SyscallDesc("m5_mutex_unlock", Tru64::m5_mutex_unlockFunc), - /* 4 */ SyscallDesc("m5_cond_signal", Tru64::m5_cond_signalFunc), - /* 5 */ SyscallDesc("m5_cond_broadcast", Tru64::m5_cond_broadcastFunc), - /* 6 */ SyscallDesc("m5_cond_wait", Tru64::m5_cond_waitFunc), - /* 7 */ SyscallDesc("m5_thread_exit", Tru64::m5_thread_exitFunc), + /* 1 */ SyscallDesc("m5_mutex_lock", AlphaTru64::m5_mutex_lockFunc), + /* 2 */ SyscallDesc("m5_mutex_trylock", AlphaTru64::m5_mutex_trylockFunc), + /* 3 */ SyscallDesc("m5_mutex_unlock", AlphaTru64::m5_mutex_unlockFunc), + /* 4 */ SyscallDesc("m5_cond_signal", AlphaTru64::m5_cond_signalFunc), + /* 5 */ SyscallDesc("m5_cond_broadcast", AlphaTru64::m5_cond_broadcastFunc), + /* 6 */ SyscallDesc("m5_cond_wait", AlphaTru64::m5_cond_waitFunc), + /* 7 */ SyscallDesc("m5_thread_exit", AlphaTru64::m5_thread_exitFunc), /* 8 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 9 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 10 */ SyscallDesc("task_self", unimplementedFunc), @@ -453,22 +496,22 @@ SyscallDesc AlphaTru64Process::machSyscallDescs[] = { /* 21 */ SyscallDesc("msg_receive_trap", unimplementedFunc), /* 22 */ SyscallDesc("msg_rpc_trap", unimplementedFunc), /* 23 */ SyscallDesc("kern_invalid", unimplementedFunc), - /* 24 */ SyscallDesc("nxm_block", Tru64::nxm_blockFunc), - /* 25 */ SyscallDesc("nxm_unblock", Tru64::nxm_unblockFunc), + /* 24 */ SyscallDesc("nxm_block", AlphaTru64::nxm_blockFunc), + /* 25 */ SyscallDesc("nxm_unblock", AlphaTru64::nxm_unblockFunc), /* 26 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 27 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 28 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 29 */ SyscallDesc("nxm_thread_destroy", unimplementedFunc), /* 30 */ SyscallDesc("lw_wire", unimplementedFunc), /* 31 */ SyscallDesc("lw_unwire", unimplementedFunc), - /* 32 */ SyscallDesc("nxm_thread_create", Tru64::nxm_thread_createFunc), - /* 33 */ SyscallDesc("nxm_task_init", Tru64::nxm_task_initFunc), + /* 32 */ SyscallDesc("nxm_thread_create", AlphaTru64::nxm_thread_createFunc), + /* 33 */ SyscallDesc("nxm_task_init", AlphaTru64::nxm_task_initFunc), /* 34 */ SyscallDesc("kern_invalid", unimplementedFunc), - /* 35 */ SyscallDesc("nxm_idle", Tru64::nxm_idleFunc), + /* 35 */ SyscallDesc("nxm_idle", AlphaTru64::nxm_idleFunc), /* 36 */ SyscallDesc("nxm_wakeup_idle", unimplementedFunc), /* 37 */ SyscallDesc("nxm_set_pthid", unimplementedFunc), /* 38 */ SyscallDesc("nxm_thread_kill", unimplementedFunc), - /* 39 */ SyscallDesc("nxm_thread_block", Tru64::nxm_thread_blockFunc), + /* 39 */ SyscallDesc("nxm_thread_block", AlphaTru64::nxm_thread_blockFunc), /* 40 */ SyscallDesc("nxm_thread_wakeup", unimplementedFunc), /* 41 */ SyscallDesc("init_process", unimplementedFunc), /* 42 */ SyscallDesc("nxm_get_binding", unimplementedFunc), @@ -476,7 +519,7 @@ SyscallDesc AlphaTru64Process::machSyscallDescs[] = { /* 44 */ SyscallDesc("nxm_resched", unimplementedFunc), /* 45 */ SyscallDesc("nxm_set_cancel", unimplementedFunc), /* 46 */ SyscallDesc("nxm_set_binding", unimplementedFunc), - /* 47 */ SyscallDesc("stack_create", Tru64::stack_createFunc), + /* 47 */ SyscallDesc("stack_create", AlphaTru64::stack_createFunc), /* 48 */ SyscallDesc("nxm_get_state", unimplementedFunc), /* 49 */ SyscallDesc("nxm_thread_suspend", unimplementedFunc), /* 50 */ SyscallDesc("nxm_thread_resume", unimplementedFunc), @@ -488,7 +531,7 @@ SyscallDesc AlphaTru64Process::machSyscallDescs[] = { /* 56 */ SyscallDesc("host_priv_self", unimplementedFunc), /* 57 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 58 */ SyscallDesc("kern_invalid", unimplementedFunc), - /* 59 */ SyscallDesc("swtch_pri", Tru64::swtch_priFunc), + /* 59 */ SyscallDesc("swtch_pri", AlphaTru64::swtch_priFunc), /* 60 */ SyscallDesc("swtch", unimplementedFunc), /* 61 */ SyscallDesc("thread_switch", unimplementedFunc), /* 62 */ SyscallDesc("semop_fast", unimplementedFunc), @@ -496,7 +539,7 @@ SyscallDesc AlphaTru64Process::machSyscallDescs[] = { /* 64 */ SyscallDesc("nxm_pshared_block", unimplementedFunc), /* 65 */ SyscallDesc("nxm_pshared_unblock", unimplementedFunc), /* 66 */ SyscallDesc("nxm_pshared_destroy", unimplementedFunc), - /* 67 */ SyscallDesc("nxm_swtch_pri", Tru64::swtch_priFunc), + /* 67 */ SyscallDesc("nxm_swtch_pri", AlphaTru64::swtch_priFunc), /* 68 */ SyscallDesc("lw_syscall", unimplementedFunc), /* 69 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 70 */ SyscallDesc("mach_sctimes_0", unimplementedFunc), diff --git a/arch/alpha/tru64/tru64.cc b/arch/alpha/tru64/tru64.cc new file mode 100644 index 000000000..4a3e653c1 --- /dev/null +++ b/arch/alpha/tru64/tru64.cc @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * 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/alpha/tru64/tru64.hh" + +// open(2) flags translation table +OpenFlagTransTable AlphaTru64::openFlagTable[] = { +#ifdef _MSC_VER + { AlphaTru64::TGT_O_RDONLY, _O_RDONLY }, + { AlphaTru64::TGT_O_WRONLY, _O_WRONLY }, + { AlphaTru64::TGT_O_RDWR, _O_RDWR }, + { AlphaTru64::TGT_O_APPEND, _O_APPEND }, + { AlphaTru64::TGT_O_CREAT, _O_CREAT }, + { AlphaTru64::TGT_O_TRUNC, _O_TRUNC }, + { AlphaTru64::TGT_O_EXCL, _O_EXCL }, +#ifdef _O_NONBLOCK + { AlphaTru64::TGT_O_NONBLOCK, _O_NONBLOCK }, +#endif +#ifdef _O_NOCTTY + { AlphaTru64::TGT_O_NOCTTY, _O_NOCTTY }, +#endif +#ifdef _O_SYNC + { AlphaTru64::TGT_O_SYNC, _O_SYNC }, +#endif +#else /* !_MSC_VER */ + { AlphaTru64::TGT_O_RDONLY, O_RDONLY }, + { AlphaTru64::TGT_O_WRONLY, O_WRONLY }, + { AlphaTru64::TGT_O_RDWR, O_RDWR }, + { AlphaTru64::TGT_O_APPEND, O_APPEND }, + { AlphaTru64::TGT_O_CREAT, O_CREAT }, + { AlphaTru64::TGT_O_TRUNC, O_TRUNC }, + { AlphaTru64::TGT_O_EXCL, O_EXCL }, + { AlphaTru64::TGT_O_NONBLOCK, O_NONBLOCK }, + { AlphaTru64::TGT_O_NOCTTY, O_NOCTTY }, +#ifdef O_SYNC + { AlphaTru64::TGT_O_SYNC, O_SYNC }, +#endif +#endif /* _MSC_VER */ +}; + +const int AlphaTru64::NUM_OPEN_FLAGS = + (sizeof(AlphaTru64::openFlagTable)/sizeof(AlphaTru64::openFlagTable[0])); + + + diff --git a/arch/alpha/tru64/tru64.hh b/arch/alpha/tru64/tru64.hh new file mode 100644 index 000000000..19343ba23 --- /dev/null +++ b/arch/alpha/tru64/tru64.hh @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * 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 __ALPHA_ALPHA_TRU64_HH +#define __ALPHA_ALPHA_TRU64_HH + +#include "kern/tru64/tru64.hh" + +class AlphaTru64 : public Tru64 +{ + + 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; + + //@{ + /// open(2) flag values. + static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 00000002; //!< O_RDWR + static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK + static const int TGT_O_APPEND = 00000010; //!< O_APPEND + static const int TGT_O_CREAT = 00001000; //!< O_CREAT + static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC + static const int TGT_O_EXCL = 00004000; //!< O_EXCL + static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY + static const int TGT_O_SYNC = 00040000; //!< O_SYNC + static const int TGT_O_DRD = 00100000; //!< O_DRD + static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO + static const int TGT_O_CACHE = 00400000; //!< O_CACHE + static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC + static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC + //@} + + /// For mmap(). + static const unsigned TGT_MAP_ANONYMOUS = 0x10; + + //@{ + /// For getsysinfo(). + static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string + static const unsigned GSI_CPU_INFO = 59; //!< CPU information + static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type + static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine + static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system + static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB + static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz + //@} + + //@{ + /// For getrusage(). + static const int TGT_RUSAGE_THREAD = 1; + static const int TGT_RUSAGE_SELF = 0; + static const int TGT_RUSAGE_CHILDREN = -1; + //@} + + //@{ + /// For setsysinfo(). + static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control() + //@} + + //@{ + /// ioctl() command codes. + static const unsigned TIOCGETP = 0x40067408; + static const unsigned TIOCSETP = 0x80067409; + static const unsigned TIOCSETN = 0x8006740a; + static const unsigned TIOCSETC = 0x80067411; + static const unsigned TIOCGETC = 0x40067412; + static const unsigned FIONREAD = 0x4004667f; + static const unsigned TIOCISATTY = 0x2000745e; + static const unsigned TIOCGETS = 0x402c7413; + static const unsigned TIOCGETA = 0x40127417; + //@} + + //@{ + /// For table(). + static const int TBL_SYSINFO = 12; + //@} + + /// 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_NOFILE = 6, + TGT_RLIMIT_AS = 7, + TGT_RLIMIT_VMEM = 7, + TGT_RLIMIT_NPROC = 8, + TGT_RLIMIT_MEMLOCK = 9, + TGT_RLIMIT_LOCKS = 10 + }; +}; + + + +#endif diff --git a/arch/mips/SConscript b/arch/mips/SConscript index 73d588f84..06b313203 100644 --- a/arch/mips/SConscript +++ b/arch/mips/SConscript @@ -57,6 +57,7 @@ full_system_sources = Split(''' # Syscall emulation (non-full-system) sources syscall_emulation_sources = Split(''' + mips_linux.cc linux_process.cc process.cc ''') diff --git a/arch/mips/faults.cc b/arch/mips/faults.cc index 1b31dfa69..a31856f07 100644 --- a/arch/mips/faults.cc +++ b/arch/mips/faults.cc @@ -98,6 +98,10 @@ FaultName IntegerOverflowFault::_name = "intover"; FaultVect IntegerOverflowFault::_vect = 0x0501; FaultStat IntegerOverflowFault::_count; +FaultName UnimpFault::_name = "Unimplemented Simulator feature"; +FaultVect UnimpFault::_vect = 0x0001; +FaultStat UnimpFault::_count; + #if FULL_SYSTEM void MipsFault::invoke(ExecContext * xc) @@ -125,6 +129,12 @@ void ArithmeticFault::invoke(ExecContext * xc) panic("Arithmetic traps are unimplemented!"); } +void UnimpFault::invoke(ExecContext * xc) +{ + FaultBase::invoke(xc); + panic("Unimpfault: %s\n", panicStr.c_str()); +} + #endif } // namespace MipsISA diff --git a/arch/mips/faults.hh b/arch/mips/faults.hh index 0bdabe29e..b0d228090 100644 --- a/arch/mips/faults.hh +++ b/arch/mips/faults.hh @@ -264,6 +264,26 @@ class IntegerOverflowFault : public MipsFault FaultStat & countStat() {return _count;} }; +class UnimpFault : public MipsFault +{ + private: + std::string panicStr; + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + UnimpFault(std::string _str) + : panicStr(_str) + { } + + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +#if FULL_SYSTEM + void invoke(ExecContext * xc); +#endif +}; + } // MipsISA namespace #endif // __FAULTS_HH__ diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa index 139a6d876..9ed9651d2 100644 --- a/arch/mips/isa/base.isa +++ b/arch/mips/isa/base.isa @@ -9,8 +9,6 @@ output header {{ #define R31 31 -#include "arch/mips/faults.hh" -#include "arch/mips/isa_traits.hh" using namespace MipsISA; diff --git a/arch/mips/isa/bitfields.isa b/arch/mips/isa/bitfields.isa index 58d487ad2..eb917595c 100644 --- a/arch/mips/isa/bitfields.isa +++ b/arch/mips/isa/bitfields.isa @@ -26,6 +26,7 @@ def bitfield RS <25:21>; def bitfield RS_MSB <25:25>; def bitfield RS_HI <25:24>; def bitfield RS_LO <23:21>; +def bitfield RS_SRL <25:22>; def bitfield RD <15:11>; diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 2df2b0403..077f0afd0 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -43,14 +43,30 @@ decode OPCODE_HI default Unknown::unknown() { } - 0x2: decode SRL { - 0: srl({{ Rd = Rt.uw >> SA; }}); + 0x2: decode RS_SRL { + 0x0:decode SRL { + 0: srl({{ Rd = Rt.uw >> SA; }}); - //Hardcoded assuming 32-bit ISA, probably need parameter here - 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}}); + //Hardcoded assuming 32-bit ISA, probably need parameter here + 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}}); + } } - 0x3: sra({{ Rd = Rt.sw >> SA; }}); + 0x3: decode RS { + 0x0: sra({{ + uint32_t temp = Rt >> SA; + + if ( (Rt & 0x80000000) > 0 ) { + uint32_t mask = 0x80000000; + for(int i=0; i < SA; i++) { + temp |= mask; + mask = mask >> 1; + } + } + + Rd = temp; + }}); + } 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }}); @@ -61,7 +77,21 @@ decode OPCODE_HI default Unknown::unknown() { 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}}); } - 0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }}); + 0x7: srav({{ + int shift_amt = Rs<4:0>; + + uint32_t temp = Rt >> shift_amt; + + if ( (Rt & 0x80000000) > 0 ) { + uint32_t mask = 0x80000000; + for(int i=0; i < shift_amt; i++) { + temp |= mask; + mask = mask >> 1; + } + } + + Rd = temp; + }}); } } @@ -107,13 +137,13 @@ decode OPCODE_HI default Unknown::unknown() { 0x3: decode FUNCTION_LO { format IntOp { 0x0: mult({{ - int64_t temp1 = Rs.sw * Rt.sw; + int64_t temp1 = Rs.sd * Rt.sd; xc->setMiscReg(Hi,temp1<63:32>); xc->setMiscReg(Lo,temp1<31:0>); }}); 0x1: multu({{ - int64_t temp1 = Rs.uw * Rt.uw; + uint64_t temp1 = Rs.ud * Rt.ud; xc->setMiscReg(Hi,temp1<63:32>); xc->setMiscReg(Lo,temp1<31:0>); }}); @@ -130,23 +160,27 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x4: decode FUNCTION_LO { - format IntOp { - 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;/*Trap on Overflow*/}}); - 0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}}); - 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}}); - 0x3: subu({{ Rd.sw = Rs.sw - Rt.uw;}}); - 0x4: and({{ Rd = Rs & Rt;}}); - 0x5: or({{ Rd = Rs | Rt;}}); - 0x6: xor({{ Rd = Rs ^ Rt;}}); - 0x7: nor({{ Rd = ~(Rs | Rt);}}); + 0x4: decode HINT { + 0x0: decode FUNCTION_LO { + format IntOp { + 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;/*Trap on Overflow*/}}); + 0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}}); + 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}}); + 0x3: subu({{ Rd.sw = Rs.sw - Rt.sw;}}); + 0x4: and({{ Rd = Rs & Rt;}}); + 0x5: or({{ Rd = Rs | Rt;}}); + 0x6: xor({{ Rd = Rs ^ Rt;}}); + 0x7: nor({{ Rd = ~(Rs | Rt);}}); + } } } - 0x5: decode FUNCTION_LO { - format IntOp{ - 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}}); - 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}}); + 0x5: decode HINT { + 0x0: decode FUNCTION_LO { + format IntOp{ + 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}}); + 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}}); + } } } @@ -216,8 +250,13 @@ decode OPCODE_HI default Unknown::unknown() { format Branch { 0x4: beq({{ cond = (Rs.sw == Rt.sw); }}); 0x5: bne({{ cond = (Rs.sw != Rt.sw); }}); - 0x6: blez({{ cond = (Rs.sw <= 0); }}); - 0x7: bgtz({{ cond = (Rs.sw > 0); }}); + 0x6: decode RT { + 0x0: blez({{ cond = (Rs.sw <= 0); }}); + } + + 0x7: decode RT { + 0x0: bgtz({{ cond = (Rs.sw > 0); }}); + } } } @@ -226,11 +265,14 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}}); 0x1: addiu({{ Rt.sw = Rs.sw + imm;}}); 0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }}); - 0x3: sltiu({{ Rt.sw = ( Rs.sw < imm ) ? 1 : 0 }}); - 0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}}); - 0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}}); - 0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}}); - 0x7: lui({{ Rt = INTIMM << 16}}); + 0x3: sltiu({{ Rt.uw = ( Rs.uw < (uint32_t)sextImm ) ? 1 : 0 }}); + 0x4: andi({{ Rt.sw = Rs.sw & zextImm;}}); + 0x5: ori({{ Rt.sw = Rs.sw | zextImm;}}); + 0x6: xori({{ Rt.sw = Rs.sw ^ zextImm;}}); + + 0x7: decode RS { + 0x0: lui({{ Rt = imm << 16}}); + } } } @@ -352,13 +394,37 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode RS_HI { 0x0: decode RS_LO { - format FloatOp { - 0x0: mfc1({{ /*Rt.uw = Fs.ud<31:0>;*/ }}); - 0x2: cfc1({{ /*Rt.uw = xc->readMiscReg(FPCR[Fs]);*/}}); - 0x3: mfhc1({{ /*Rt.uw = Fs.ud<63:32>*/;}}); - 0x4: mtc1({{ /*Fs = Rt.uw*/}}); - 0x6: ctc1({{ /*xc->setMiscReg(FPCR[Fs],Rt);*/}}); - 0x7: mthc1({{ /*Fs<63:32> = Rt.uw*/}}); + format WarnUnimpl { + 0x0: mfc1();//{{ /*Rt.uw = Fs.ud<31:0>;*/ }} + 0x3: mfhc1();// /*Rt.uw = Fs.ud<63:32>*/; + 0x4: mtc1();// /*Fs = Rt.uw*/ + 0x7: mthc1();//{{/*Fs<63:32> = Rt.uw*/}} + } + + format System { + 0x2: cfc1({{ + uint32_t fcsr_reg = xc->readMiscReg(FCSR); + + if (Fs == 0){ + Rt = xc->readMiscReg(FIR); + } else if (Fs == 25) { + Rt = 0 | (fcsr_reg & 0xFE000000) >> 24 | (fcsr_reg & 0x00800000) >> 23; + } else if (Fs == 26) { + Rt = 0 | (fcsr_reg & 0x0003F07C); + } else if (Fs == 28) { + Rt = 0 | (fcsr_reg); + } else if (Fs == 31) { + Rt = fcsr_reg; + } else { + panic("FP Control Value (%d) Not Available. Ignoring Access to" + "Floating Control Status Register",fcsr_reg); + } + + }}); + + 0x6: ctc1({{ + /*xc->setMiscReg(FPCR[Fs],Rt);*/ + }}); } } @@ -830,14 +896,14 @@ decode OPCODE_HI default Unknown::unknown() { 0x7: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { - format WarnUnimpl { + format FailUnimpl { 0x1: ext(); 0x4: ins(); } } 0x1: decode FUNCTION_LO { - format WarnUnimpl { + format FailUnimpl { 0x0: fork(); 0x1: yield(); } @@ -847,16 +913,16 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-10 MIPS32 BSHFL Encoding of sa Field 0x4: decode SA { - 0x02: WarnUnimpl::wsbh(); + 0x02: FailUnimpl::wsbh(); format BasicOp { - 0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24) | */ Rt<7:0>}}); - 0x18: seh({{ Rd.sw = /* sext32(Rt<15>,16) | */ Rt<15:0>}}); + 0x10: seb({{ Rd.sw = Rt<7:0>}}); + 0x18: seh({{ Rd.sw = Rt<15:0>}}); } } 0x6: decode FUNCTION_LO { - 0x7: BasicOp::rdhwr({{ /*Rt = xc->hwRegs[RD];*/ }}); + 0x7: FailUnimpl::rdhwr();//{{ /*Rt = xc->hwRegs[RD];*/ }} } } } @@ -865,11 +931,97 @@ decode OPCODE_HI default Unknown::unknown() { format LoadMemory { 0x0: lb({{ Rt.sw = Mem.sb; }}); 0x1: lh({{ Rt.sw = Mem.sh; }}); - 0x2: lwl({{ uint32_t temp = Mem.uw<31:16> << 16; Rt.uw &= 0x00FF; Rt.uw |= temp;}}, {{ EA = (Rs + disp) & ~3; }}); + + 0x2: lwl({{ + uint32_t mem_word = Mem.uw; + uint32_t unalign_addr = Rs + disp; + uint32_t offset = unalign_addr & 0x00000003; +#if BYTE_ORDER == BIG_ENDIAN + std::cout << "Big Endian Byte Order\n"; + + switch(offset) + { + case 0: + Rt = mem_word; + break; + + case 1: + Rt &= 0x000F; + Rt |= (mem_word << 4); + break; + + case 2: + Rt &= 0x00FF; + Rt |= (mem_word << 8); + break; + + case 3: + Rt &= 0x0FFF; + Rt |= (mem_word << 12); + break; + + default: + panic("lwl: bad offset"); + } +#elif BYTE_ORDER == LITTLE_ENDIAN + std::cout << "Little Endian Byte Order\n"; + + switch(offset) + { + case 0: + Rt &= 0x0FFF; + Rt |= (mem_word << 12); + break; + + case 1: + Rt &= 0x00FF; + Rt |= (mem_word << 8); + break; + + case 2: + Rt &= 0x000F; + Rt |= (mem_word << 4); + break; + + case 3: + Rt = mem_word; + break; + + default: + panic("lwl: bad offset"); + } +#endif + }}, {{ EA = (Rs + disp) & ~3; }}); + 0x3: lw({{ Rt.sw = Mem.sw; }}); 0x4: lbu({{ Rt.uw = Mem.ub; }}); 0x5: lhu({{ Rt.uw = Mem.uh; }}); - 0x6: lwr({{ uint32_t temp = 0x00FF & Mem.uw<15:0>; Rt.uw &= 0xFF00; Rt.uw |= temp; }}, {{ EA = (Rs + disp) & ~3; }}); + 0x6: lwr({{ + uint32_t mem_word = Mem.uw; + uint32_t unalign_addr = Rs + disp; + uint32_t offset = unalign_addr & 0x00000003; + +#if BYTE_ORDER == BIG_ENDIAN + switch(offset) + { + case 0: Rt &= 0xFFF0; Rt |= (mem_word >> 12); break; + case 1: Rt &= 0xFF00; Rt |= (mem_word >> 8); break; + case 2: Rt &= 0xF000; Rt |= (mem_word >> 4); break; + case 3: Rt = mem_word; break; + default: panic("lwr: bad offset"); + } +#elif BYTE_ORDER == LITTLE_ENDIAN + switch(offset) + { + case 0: Rt = mem_word; break; + case 1: Rt &= 0xF000; Rt |= (mem_word >> 4); break; + case 2: Rt &= 0xFF00; Rt |= (mem_word >> 8); break; + case 3: Rt &= 0xFFF0; Rt |= (mem_word >> 12); break; + default: panic("lwr: bad offset"); + } +#endif + }}, + {{ EA = (Rs + disp) & ~3; }}); } 0x7: FailUnimpl::reserved(); @@ -879,9 +1031,144 @@ decode OPCODE_HI default Unknown::unknown() { format StoreMemory { 0x0: sb({{ Mem.ub = Rt<7:0>; }}); 0x1: sh({{ Mem.uh = Rt<15:0>; }}); - 0x2: swl({{ Mem.uh = Rt<31:16>; }}, {{ EA = (Rs + disp) & ~3; }}); + 0x2: swl({{ + uint32_t mem_word = 0; + uint32_t aligned_addr = (Rs + disp) & ~3; + uint32_t unalign_addr = Rs + disp; + uint32_t offset = unalign_addr & 0x00000003; + + DPRINTF(IEW,"Execute: aligned=0x%x unaligned=0x%x\n offset=0x%x", + aligned_addr,unalign_addr,offset); + + fault = xc->read(aligned_addr, (uint32_t&)mem_word, memAccessFlags); + +#if BYTE_ORDER == BIG_ENDIAN + switch(offset) + { + case 0: + Mem = Rt; + break; + + case 1: + mem_word &= 0xF000; + mem_word |= (Rt >> 4); + Mem = mem_word; + break; + + case 2: + mem_word &= 0xFF00; + mem_word |= (Rt >> 8); + Mem = mem_word; + break; + + case 3: + mem_word &= 0xFFF0; + mem_word |= (Rt >> 12); + Mem = mem_word; + break; + + default: + panic("swl: bad offset"); + } +#elif BYTE_ORDER == LITTLE_ENDIAN + switch(offset) + { + case 0: + mem_word &= 0xFFF0; + mem_word |= (Rt >> 12); + Mem = mem_word; + break; + + case 1: + mem_word &= 0xFF00; + mem_word |= (Rt >> 8); + Mem = mem_word; + break; + + case 2: + mem_word &= 0xF000; + mem_word |= (Rt >> 4); + Mem = mem_word; + break; + + case 3: + Mem = Rt; + break; + + default: + panic("swl: bad offset"); + } +#endif + }},{{ EA = (Rs + disp) & ~3; }},mem_flags = NO_ALIGN_FAULT); + 0x3: sw({{ Mem.uw = Rt<31:0>; }}); - 0x6: swr({{ Mem.uh = Rt<15:0>; }},{{ EA = ((Rs + disp) & ~3) + 4;}}); + + 0x6: swr({{ + uint32_t mem_word = 0; + uint32_t aligned_addr = (Rs + disp) & ~3; + uint32_t unalign_addr = Rs + disp; + uint32_t offset = unalign_addr & 0x00000003; + + fault = xc->read(aligned_addr, (uint32_t&)mem_word, memAccessFlags); + +#if BYTE_ORDER == BIG_ENDIAN + switch(offset) + { + case 0: + mem_word &= 0x0FFF; + mem_word |= (Rt << 12); + Mem = mem_word; + break; + + case 1: + mem_word &= 0x00FF; + mem_word |= (Rt << 8); + Mem = mem_word; + break; + + case 2: + mem_word &= 0x000F; + mem_word |= (Rt << 4); + Mem = mem_word; + break; + + case 3: + Mem = Rt; + break; + + default: + panic("swr: bad offset"); + } +#elif BYTE_ORDER == LITTLE_ENDIAN + switch(offset) + { + case 0: + Mem = Rt; + break; + + case 1: + mem_word &= 0x000F; + mem_word |= (Rt << 4); + Mem = mem_word; + break; + + case 2: + mem_word &= 0x00FF; + mem_word |= (Rt << 8); + Mem = mem_word; + break; + + case 3: + mem_word &= 0x0FFF; + mem_word |= (Rt << 12); + Mem = mem_word; + break; + + default: + panic("swr: bad offset"); + } +#endif + }},{{ EA = (Rs + disp) & ~3;}},mem_flags = NO_ALIGN_FAULT); } format WarnUnimpl { @@ -891,7 +1178,7 @@ decode OPCODE_HI default Unknown::unknown() { } 0x6: decode OPCODE_LO default FailUnimpl::reserved() { - 0x0: WarnUnimpl::ll(); + 0x0: FailUnimpl::ll(); format LoadMemory { 0x1: lwc1({{ /*F_t<31:0> = Mem.sf; */}}); @@ -901,7 +1188,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x7: decode OPCODE_LO default FailUnimpl::reserved() { - 0x0: WarnUnimpl::sc(); + 0x0: FailUnimpl::sc(); format StoreMemory { 0x1: swc1({{ //Mem.sf = Ft<31:0>; }}); diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index cb0f4ac9c..39db88c23 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -179,7 +179,7 @@ output decoder {{ ss << ","; } - Addr target = pc + 8 + disp; + Addr target = pc + 4 + disp; std::string str; if (symtab && symtab->findSymbol(target, str)) diff --git a/arch/mips/isa/formats/int.isa b/arch/mips/isa/formats/int.isa index a47844bee..7d38b9ff5 100644 --- a/arch/mips/isa/formats/int.isa +++ b/arch/mips/isa/formats/int.isa @@ -29,17 +29,19 @@ output header {{ { protected: - int32_t imm; + int16_t imm; + int32_t sextImm; + uint32_t zextImm; /// Constructor IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) : - MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM) + MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM), + sextImm(INTIMM),zextImm(0x0000FFFF & INTIMM) { //If Bit 15 is 1 then Sign Extend - int32_t temp = imm & 0x00008000; - + int32_t temp = sextImm & 0x00008000; if (temp > 0 && mnemonic != "lui") { - imm |= 0xFFFF0000; + sextImm |= 0xFFFF0000; } } @@ -62,10 +64,9 @@ output decoder {{ // it's generally implicit if (_numDestRegs > 0) { printReg(ss, _destRegIdx[0]); + ss << ","; } - ss << ","; - // just print the first two source regs... if there's // a third one, it's a read-modify-write dest (Rc), // e.g. for CMOVxx @@ -99,9 +100,9 @@ output decoder {{ } if( mnemonic == "lui") - ccprintf(ss, "%08p ", imm); + ccprintf(ss, "%08p ", sextImm); else - ss << (int) imm; + ss << (int) sextImm; return ss.str(); } diff --git a/arch/mips/isa/formats/mem.isa b/arch/mips/isa/formats/mem.isa index 404aa1ee1..df1dca4e1 100644 --- a/arch/mips/isa/formats/mem.isa +++ b/arch/mips/isa/formats/mem.isa @@ -446,6 +446,14 @@ def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, exec_template_base = 'Store') }}; +def format UnalignedStore(memacc_code, postacc_code, + ea_code = {{ EA = Rb + disp; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + postacc_code, exec_template_base = 'Store') +}}; + //FP loads are offloaded to these formats for now ... def format LoadMemory2(ea_code = {{ EA = Rs + disp; }}, memacc_code = {{ }}, mem_flags = [], inst_flags = []) {{ diff --git a/arch/mips/isa/formats/unimp.isa b/arch/mips/isa/formats/unimp.isa index 890cf8d1a..475a88752 100644 --- a/arch/mips/isa/formats/unimp.isa +++ b/arch/mips/isa/formats/unimp.isa @@ -110,7 +110,8 @@ output exec {{ Trace::InstRecord *traceData) const { panic("attempt to execute unimplemented instruction '%s' " - "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); + "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE, + inst2string(machInst)); return new UnimplementedOpcodeFault; } diff --git a/arch/mips/isa/formats/unknown.isa b/arch/mips/isa/formats/unknown.isa index 47d166255..ba83c007e 100644 --- a/arch/mips/isa/formats/unknown.isa +++ b/arch/mips/isa/formats/unknown.isa @@ -26,12 +26,34 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +output header {{ + std::string inst2string(MachInst machInst); +}}; output decoder {{ + +std::string inst2string(MachInst machInst) +{ + string str = ""; + uint32_t mask = 0x80000000; + + for(int i=0; i < 32; i++) { + if ((machInst & mask) == 0) { + str += "0"; + } else { + str += "1"; + } + + mask = mask >> 1; + } + + return str; +} + std::string Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - return csprintf("%-10s (inst 0x%x, opcode 0x%x)", - "unknown", machInst, OPCODE); + return csprintf("%-10s (inst 0x%x, opcode 0x%x, binary:%s)", + "unknown", machInst, OPCODE, inst2string(machInst)); } }}; @@ -41,7 +63,7 @@ output exec {{ Trace::InstRecord *traceData) const { panic("attempt to execute unknown instruction " - "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); + "(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst)); return new UnimplementedOpcodeFault; } }}; diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa index db4bf204a..dcdf46757 100644 --- a/arch/mips/isa/formats/util.isa +++ b/arch/mips/isa/formats/util.isa @@ -93,7 +93,9 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, output exec {{ -using namespace MipsISA; + using namespace MipsISA; + + /// CLEAR ALL CPU INST/EXE HAZARDS diff --git a/arch/mips/isa/includes.isa b/arch/mips/isa/includes.isa index b81c4eda2..9c370fbe3 100644 --- a/arch/mips/isa/includes.isa +++ b/arch/mips/isa/includes.isa @@ -17,6 +17,8 @@ output decoder {{ #include "base/cprintf.hh" #include "base/loader/symtab.hh" #include "cpu/exec_context.hh" // for Jump::branchTarget() +#include "arch/mips/faults.hh" +#include "arch/mips/isa_traits.hh" #include <math.h> #if defined(linux) @@ -27,6 +29,7 @@ using namespace MipsISA; }}; output exec {{ +#include "arch/mips/faults.hh" #include "arch/mips/isa_traits.hh" #include <math.h> #if defined(linux) diff --git a/arch/mips/isa/operands.isa b/arch/mips/isa/operands.isa index c01496dc9..2fa3238dc 100644 --- a/arch/mips/isa/operands.isa +++ b/arch/mips/isa/operands.isa @@ -27,7 +27,7 @@ def operands {{ 'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3), 'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3), - 'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), + 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), 'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4), 'NNPC':('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4) diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 35c207828..1f4ccbd90 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -60,7 +60,7 @@ class SyscallReturn { template <class T> SyscallReturn(T v, bool s) { - retval = (uint64_t)v; + retval = (uint32_t)v; success = s; } @@ -68,7 +68,7 @@ class SyscallReturn { SyscallReturn(T v) { success = (v >= 0); - retval = (uint64_t)v; + retval = (uint32_t)v; } ~SyscallReturn() {} @@ -138,7 +138,7 @@ namespace MipsISA const int SyscallNumReg = ReturnValueReg1; const int SyscallPseudoReturnReg = ReturnValueReg1; - const int SyscallSuccessReg = ReturnValueReg1; + const int SyscallSuccessReg = ArgumentReg3; const int LogVMPageSize = 13; // 8K bytes const int VMPageSize = (1 << LogVMPageSize); @@ -164,7 +164,6 @@ namespace MipsISA }; typedef uint64_t IntReg; - class IntRegFile { protected: @@ -188,21 +187,9 @@ namespace MipsISA }; -/* floating point register file entry type - typedef union { - uint64_t q; - double d; - } FloatReg;*/ - typedef double FloatReg; typedef uint64_t FloatRegBits; - -/*typedef union { - uint64_t q[NumFloatRegs]; // integer qword view - double d[NumFloatRegs]; // double-precision floating point view - } FloatRegFile;*/ - - class FloatRegFile + class FloatRegFile { protected: @@ -473,6 +460,7 @@ namespace MipsISA //More Misc. Regs Hi, Lo, + FIR, FCSR, FPCR, @@ -732,21 +720,15 @@ extern const Addr PageOffset; static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs) { - // check for error condition. Alpha syscall convention is to - // indicate success/failure in reg a3 (r19) and put the - // return value itself in the standard return value reg (v0). if (return_value.successful()) { // no error - regs->setIntReg(ReturnValueReg1, 0); - regs->setIntReg(ReturnValueReg2, return_value.value()); + regs->setIntReg(SyscallSuccessReg, 0); + regs->setIntReg(ReturnValueReg1, return_value.value()); } else { // got an error, return details - regs->setIntReg(ReturnValueReg1, (IntReg) -1); - regs->setIntReg(ReturnValueReg2, -return_value.value()); + regs->setIntReg(SyscallSuccessReg, (IntReg) -1); + regs->setIntReg(ReturnValueReg1, -return_value.value()); } - - //regs->intRegFile[ReturnValueReg1] = (IntReg)return_value; - //panic("Returning from syscall\n"); } // Machine operations diff --git a/arch/mips/linux_process.cc b/arch/mips/linux_process.cc index 92a79cfd1..89407548a 100644 --- a/arch/mips/linux_process.cc +++ b/arch/mips/linux_process.cc @@ -26,6 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "arch/mips/mips_linux.hh" #include "arch/mips/linux_process.hh" #include "arch/mips/isa_traits.hh" @@ -120,7 +121,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 2 */ SyscallDesc("fork", unimplementedFunc), /* 3 */ SyscallDesc("read", readFunc), /* 4 */ SyscallDesc("write", writeFunc), - /* 5 */ SyscallDesc("open", openFunc<Linux>), + /* 5 */ SyscallDesc("open", openFunc<MipsLinux>), /* 6 */ SyscallDesc("close", closeFunc), /* 7 */ SyscallDesc("waitpid", unimplementedFunc), /* 8 */ SyscallDesc("creat", unimplementedFunc), @@ -130,9 +131,9 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 12 */ SyscallDesc("chdir", unimplementedFunc), /* 13 */ SyscallDesc("time", unimplementedFunc), /* 14 */ SyscallDesc("mknod", unimplementedFunc), - /* 15 */ SyscallDesc("chmod", chmodFunc<Linux>), + /* 15 */ SyscallDesc("chmod", chmodFunc<MipsLinux>), /* 16 */ SyscallDesc("lchown", chownFunc), - /* 17 */ SyscallDesc("break", unimplementedFunc), /*obreak*/ + /* 17 */ SyscallDesc("break", obreakFunc), /*obreak*/ /* 18 */ SyscallDesc("unused#18", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getpid", getpidFunc), @@ -160,7 +161,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 42 */ SyscallDesc("pipe", unimplementedFunc), /* 43 */ SyscallDesc("times", unimplementedFunc), /* 44 */ SyscallDesc("prof", unimplementedFunc), - /* 45 */ SyscallDesc("brk", unimplementedFunc),/*openFunc<Linux>*/ + /* 45 */ SyscallDesc("brk", obreakFunc),/*openFunc<MipsLinux>*/ /* 46 */ SyscallDesc("setgid", unimplementedFunc), /* 47 */ SyscallDesc("getgid", getgidFunc), /* 48 */ SyscallDesc("signal", ignoreFunc), @@ -169,7 +170,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 51 */ SyscallDesc("acct", unimplementedFunc), /* 52 */ SyscallDesc("umount2", unimplementedFunc), /* 53 */ SyscallDesc("lock", unimplementedFunc), - /* 54 */ SyscallDesc("ioctl", ioctlFunc<Linux>), + /* 54 */ SyscallDesc("ioctl", ioctlFunc<MipsLinux>), /* 55 */ SyscallDesc("fcntl", unimplementedFunc), /* 56 */ SyscallDesc("mpx", unimplementedFunc), /* 57 */ SyscallDesc("setpgid", unimplementedFunc), @@ -182,13 +183,13 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 64 */ SyscallDesc("getppid", getpagesizeFunc), /* 65 */ SyscallDesc("getpgrp", unimplementedFunc), /* 66 */ SyscallDesc("setsid", unimplementedFunc), - /* 67 */ SyscallDesc("sigaction", statFunc<Linux>), - /* 68 */ SyscallDesc("sgetmask", lstatFunc<Linux>), + /* 67 */ SyscallDesc("sigaction",unimplementedFunc), + /* 68 */ SyscallDesc("sgetmask", unimplementedFunc), /* 69 */ SyscallDesc("ssetmask", unimplementedFunc), /* 70 */ SyscallDesc("setreuid", unimplementedFunc), - /* 71 */ SyscallDesc("setregid", mmapFunc<Linux>), + /* 71 */ SyscallDesc("setregid", unimplementedFunc), /* 72 */ SyscallDesc("sigsuspend", unimplementedFunc), - /* 73 */ SyscallDesc("sigpending", munmapFunc), + /* 73 */ SyscallDesc("sigpending", unimplementedFunc), /* 74 */ SyscallDesc("sethostname", ignoreFunc), /* 75 */ SyscallDesc("setrlimit", unimplementedFunc), /* 76 */ SyscallDesc("getrlimit", unimplementedFunc), @@ -205,8 +206,8 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 87 */ SyscallDesc("swapon", gethostnameFunc), /* 88 */ SyscallDesc("reboot", unimplementedFunc), /* 89 */ SyscallDesc("readdir", unimplementedFunc), - /* 90 */ SyscallDesc("mmap", mmapFunc<Linux>), - /* 91 */ SyscallDesc("munmap",unimplementedFunc),/*fstatFunc<Linux>*/ + /* 90 */ SyscallDesc("mmap", mmapFunc<MipsLinux>), + /* 91 */ SyscallDesc("munmap",munmapFunc), /* 92 */ SyscallDesc("truncate", fcntlFunc), /* 93 */ SyscallDesc("ftruncate", unimplementedFunc), /* 94 */ SyscallDesc("fchmod", unimplementedFunc), @@ -221,9 +222,9 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 103 */ SyscallDesc("syslog", unimplementedFunc), /* 104 */ SyscallDesc("setitimer", unimplementedFunc), /* 105 */ SyscallDesc("getitimer", unimplementedFunc), - /* 106 */ SyscallDesc("stat", unimplementedFunc), + /* 106 */ SyscallDesc("stat", statFunc<MipsLinux>), /* 107 */ SyscallDesc("lstat", unimplementedFunc), - /* 108 */ SyscallDesc("fstat", unimplementedFunc), + /* 108 */ SyscallDesc("fstat", fstatFunc<MipsLinux>), /* 109 */ SyscallDesc("unused#109", unimplementedFunc), /* 110 */ SyscallDesc("iopl", unimplementedFunc), /* 111 */ SyscallDesc("vhangup", unimplementedFunc), @@ -240,7 +241,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 122 */ SyscallDesc("uname", unameFunc), /* 123 */ SyscallDesc("modify_ldt", unimplementedFunc), /* 124 */ SyscallDesc("adjtimex", unimplementedFunc), - /* 125 */ SyscallDesc("mprotect", unimplementedFunc), + /* 125 */ SyscallDesc("mprotect", ignoreFunc), /* 126 */ SyscallDesc("sigprocmask", unimplementedFunc), /* 127 */ SyscallDesc("create_module", unimplementedFunc), /* 128 */ SyscallDesc("init_module", unimplementedFunc), @@ -259,9 +260,9 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 141 */ SyscallDesc("getdents", unimplementedFunc), /* 142 */ SyscallDesc("newselect", unimplementedFunc), /* 143 */ SyscallDesc("flock", unimplementedFunc), - /* 144 */ SyscallDesc("msync", unimplementedFunc),/*getrlimitFunc<Linux>*/ + /* 144 */ SyscallDesc("msync", unimplementedFunc),/*getrlimitFunc<MipsLinux>*/ /* 145 */ SyscallDesc("readv", unimplementedFunc), - /* 146 */ SyscallDesc("writev", writevFunc<Linux>), + /* 146 */ SyscallDesc("writev", writevFunc<MipsLinux>), /* 147 */ SyscallDesc("cacheflush", unimplementedFunc), /* 148 */ SyscallDesc("cachectl", unimplementedFunc), /* 149 */ SyscallDesc("sysmips", unimplementedFunc), @@ -329,8 +330,8 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 211 */ SyscallDesc("truncate64", unimplementedFunc), /* 212 */ SyscallDesc("ftruncate64", unimplementedFunc), /* 213 */ SyscallDesc("stat64", unimplementedFunc), - /* 214 */ SyscallDesc("lstat64", unimplementedFunc), - /* 215 */ SyscallDesc("fstat64", unimplementedFunc), + /* 214 */ SyscallDesc("lstat64", lstat64Func<MipsLinux>), + /* 215 */ SyscallDesc("fstat64", fstat64Func<MipsLinux>), /* 216 */ SyscallDesc("pivot_root", unimplementedFunc), /* 217 */ SyscallDesc("mincore", unimplementedFunc), /* 218 */ SyscallDesc("madvise", unimplementedFunc), @@ -361,7 +362,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 243 */ SyscallDesc("io_getevents", unimplementedFunc), /* 244 */ SyscallDesc("io_submit", unimplementedFunc), /* 245 */ SyscallDesc("io_cancel", unimplementedFunc), - /* 246 */ SyscallDesc("exit_group", unimplementedFunc), + /* 246 */ SyscallDesc("exit_group", exitFunc), /* 247 */ SyscallDesc("lookup_dcookie", unimplementedFunc), /* 248 */ SyscallDesc("epoll_create", unimplementedFunc), /* 249 */ SyscallDesc("epoll_ctl", unimplementedFunc), @@ -415,8 +416,6 @@ MipsLinuxProcess::MipsLinuxProcess(const std::string &name, //init_regs->intRegFile[0] = 0; } - - SyscallDesc* MipsLinuxProcess::getDesc(int callnum) { diff --git a/arch/mips/mips_linux.cc b/arch/mips/mips_linux.cc new file mode 100644 index 000000000..7a9e66470 --- /dev/null +++ b/arch/mips/mips_linux.cc @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * 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/mips/mips_linux.hh" + +// open(2) flags translation table +OpenFlagTransTable MipsLinux::openFlagTable[] = { +#ifdef _MSC_VER + { MipsLinux::TGT_O_RDONLY, _O_RDONLY }, + { MipsLinux::TGT_O_WRONLY, _O_WRONLY }, + { MipsLinux::TGT_O_RDWR, _O_RDWR }, + { MipsLinux::TGT_O_APPEND, _O_APPEND }, + { MipsLinux::TGT_O_CREAT, _O_CREAT }, + { MipsLinux::TGT_O_TRUNC, _O_TRUNC }, + { MipsLinux::TGT_O_EXCL, _O_EXCL }, +#ifdef _O_NONBLOCK + { MipsLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, +#endif +#ifdef _O_NOCTTY + { MipsLinux::TGT_O_NOCTTY, _O_NOCTTY }, +#endif +#ifdef _O_SYNC + { MipsLinux::TGT_O_SYNC, _O_SYNC }, +#endif +#else /* !_MSC_VER */ + { MipsLinux::TGT_O_RDONLY, O_RDONLY }, + { MipsLinux::TGT_O_WRONLY, O_WRONLY }, + { MipsLinux::TGT_O_RDWR, O_RDWR }, + { MipsLinux::TGT_O_APPEND, O_APPEND }, + { MipsLinux::TGT_O_CREAT, O_CREAT }, + { MipsLinux::TGT_O_TRUNC, O_TRUNC }, + { MipsLinux::TGT_O_EXCL, O_EXCL }, + { MipsLinux::TGT_O_NONBLOCK, O_NONBLOCK }, + { MipsLinux::TGT_O_NOCTTY, O_NOCTTY }, +#ifdef O_SYNC + { MipsLinux::TGT_O_SYNC, O_SYNC }, +#endif +#endif /* _MSC_VER */ +}; + +const int MipsLinux::NUM_OPEN_FLAGS = + (sizeof(MipsLinux::openFlagTable)/sizeof(MipsLinux::openFlagTable[0])); + + + diff --git a/arch/mips/mips_linux.hh b/arch/mips/mips_linux.hh new file mode 100644 index 000000000..fd08e8c87 --- /dev/null +++ b/arch/mips/mips_linux.hh @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * 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 __MIPS_MIPS_LINUX_HH +#define __MIPS_MIPS_LINUX_HH + +#include "kern/linux/linux.hh" + +class MipsLinux : public Linux +{ + 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; + + //@{ + /// 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_NONBLOCK = 0x00000080; //!< O_NONBLOCK + static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND + static const int TGT_O_CREAT = 0x00000100; //!< O_CREAT + static const int TGT_O_TRUNC = 0x00000200; //!< O_TRUNC + static const int TGT_O_EXCL = 0x00000400; //!< O_EXCL + static const int TGT_O_NOCTTY = 0x00000800; //!< O_NOCTTY + static const int TGT_O_SYNC = 0x00000010; //!< O_SYNC + static const int TGT_O_DRD = 0x00010000; //!< O_DRD + static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO + static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE + static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC + static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC + //@} + + /// For mmap(). + static const unsigned TGT_MAP_ANONYMOUS = 0x800; + + //@{ + /// For getsysinfo(). + static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string + static const unsigned GSI_CPU_INFO = 59; //!< CPU information + static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type + static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine + static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system + static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB + static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz + //@} + + //@{ + /// For getrusage(). + static const int TGT_RUSAGE_SELF = 0; + static const int TGT_RUSAGE_CHILDREN = -1; + static const int TGT_RUSAGE_BOTH = -2; + //@} + + //@{ + /// For setsysinfo(). + static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control() + //@} + + //@{ + /// ioctl() command codes. + static const unsigned TIOCGETP = 0x7408; + static const unsigned TIOCSETP = 0x7409; + static const unsigned TIOCSETN = 0x740a; + static const unsigned TIOCSETC = 0x7411; + static const unsigned TIOCGETC = 0x7412; + static const unsigned FIONREAD = 0x467f; + static const unsigned TIOCISATTY = 0x5480; + static const unsigned TIOCGETS = 0x7413; + static const unsigned TIOCGETA = 0x7417; + //@} + + /// For table(). + static const int TBL_SYSINFO = 12; + + /// 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_NOFILE = 5, + TGT_RLIMIT_AS = 6, + TGT_RLIMIT_RSS = 7, + TGT_RLIMIT_VMEM = 7, + TGT_RLIMIT_NPROC = 8, + TGT_RLIMIT_MEMLOCK = 9, + TGT_RLIMIT_LOCKS = 10 + }; + +}; + +#endif diff --git a/arch/sparc/faults.cc b/arch/sparc/faults.cc index a26015aae..e83bba800 100644 --- a/arch/sparc/faults.cc +++ b/arch/sparc/faults.cc @@ -215,7 +215,10 @@ TrapType TrapInstruction::_baseTrapType = 0x100; FaultPriority TrapInstruction::_priority = 16; FaultStat TrapInstruction::_count; - +FaultName UnimpFault::_name = "Unimplemented Simulator feature"; +TrapType UnimpFault::_trapType = 0x000; +FaultPriority UnimpFault::_priority = 0; +FaultStat UnimpFault::_count; #if FULL_SYSTEM @@ -242,6 +245,12 @@ void SparcFault::invoke(ExecContext * xc) xc->regs.npc = xc->regs.pc + sizeof(MachInst);*/ } +void UnimpFault::invoke(ExecContext * xc) +{ + panic("Unimpfault: %s\n", panicStr.c_str()); +} + + #endif } // namespace SparcISA diff --git a/arch/sparc/faults.hh b/arch/sparc/faults.hh index 36a72930a..87de8daaa 100644 --- a/arch/sparc/faults.hh +++ b/arch/sparc/faults.hh @@ -581,6 +581,29 @@ class TrapInstruction : public EnumeratedFault FaultStat & countStat() {return _count;} }; +class UnimpFault : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + std::string panicStr; + public: + UnimpFault(std::string _str) + : panicStr(_str) + { } + + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +#if FULL_SYSTEM + void invoke(ExecContext * xc); +#endif +}; + + } // SparcISA namespace #endif // __FAULTS_HH__ diff --git a/configs/test/fs.py b/configs/test/fs.py new file mode 100644 index 000000000..d2e5381f0 --- /dev/null +++ b/configs/test/fs.py @@ -0,0 +1,109 @@ +import os +from SysPaths import * + +# Base for tests is directory containing this file. +test_base = os.path.dirname(__file__) + +class BaseTsunami(Tsunami): + cchip = TsunamiCChip(pio_addr=0x801a0000000) + pchip = TsunamiPChip(pio_addr=0x80180000000) + pciconfig = PciConfigAll(pio_addr=0x801fe000000) + fake_sm_chip = IsaFake(pio_addr=0x801fc000370) + + fake_uart1 = IsaFake(pio_addr=0x801fc0002f8) + fake_uart2 = IsaFake(pio_addr=0x801fc0003e8) + fake_uart3 = IsaFake(pio_addr=0x801fc0002e8) + fake_uart4 = IsaFake(pio_addr=0x801fc0003f0) + + fake_ppc = IsaFake(pio_addr=0x801fc0003bc) + + fake_OROM = IsaFake(pio_addr=0x800000a0000, pio_size=0x60000) + + fake_pnp_addr = IsaFake(pio_addr=0x801fc000279) + fake_pnp_write = IsaFake(pio_addr=0x801fc000a79) + fake_pnp_read0 = IsaFake(pio_addr=0x801fc000203) + fake_pnp_read1 = IsaFake(pio_addr=0x801fc000243) + fake_pnp_read2 = IsaFake(pio_addr=0x801fc000283) + fake_pnp_read3 = IsaFake(pio_addr=0x801fc0002c3) + fake_pnp_read4 = IsaFake(pio_addr=0x801fc000303) + fake_pnp_read5 = IsaFake(pio_addr=0x801fc000343) + fake_pnp_read6 = IsaFake(pio_addr=0x801fc000383) + fake_pnp_read7 = IsaFake(pio_addr=0x801fc0003c3) + + fake_ata0 = IsaFake(pio_addr=0x801fc0001f0) + fake_ata1 = IsaFake(pio_addr=0x801fc000170) + + fb = BadDevice(pio_addr=0x801fc0003d0, devicename='FrameBuffer') + io = TsunamiIO(pio_addr=0x801fc000000) + uart = Uart8250(pio_addr=0x801fc0003f8) +# ethernet = NSGigE(configdata=NSGigEPciData(), +# pci_bus=0, pci_dev=1, pci_func=0) +# etherint = NSGigEInt(device=Parent.ethernet) + console = AlphaConsole(pio_addr=0x80200000000, disk=Parent.simple_disk) +# bridge = PciFake(configdata=BridgePciData(), pci_bus=0, pci_dev=2, pci_func=0) + +#class FreeBSDTsunami(BaseTsunami): +# disk0 = FreeBSDRootDisk(delay='0us', driveID='master') +# ide = IdeController(disks=[Parent.disk0], +# configdata=IdeControllerPciData(), +# pci_func=0, pci_dev=0, pci_bus=0) + +#class LinuxTsunami(BaseTsunami): +# disk0 = LinuxRootDisk(delay='0us', driveID='master') +# ide = IdeController(disks=[Parent.disk0], +# configdata=IdeControllerPciData(), +# pci_func=0, pci_dev=0, pci_bus=0) + +class LinuxAlphaSystem(LinuxAlphaSystem): + magicbus = Bus() + physmem = PhysicalMemory(range = AddrRange('128MB')) + c1 = Connector(side_a=Parent.physmem, side_b=Parent.magicbus) + tsunami = BaseTsunami() + c2 = Connector(side_a=Parent.tsunami.cchip, side_a_name='pio', side_b=Parent.magicbus) + c3 = Connector(side_a=Parent.tsunami.pchip, side_a_name='pio', side_b=Parent.magicbus) + c4 = Connector(side_a=Parent.tsunami.pciconfig, side_a_name='pio', side_b=Parent.magicbus) + c5 = Connector(side_a=Parent.tsunami.fake_sm_chip, side_a_name='pio', side_b=Parent.magicbus) + c7 = Connector(side_a=Parent.tsunami.fake_uart1, side_a_name='pio', side_b=Parent.magicbus) + c8 = Connector(side_a=Parent.tsunami.fake_uart2, side_a_name='pio', side_b=Parent.magicbus) + c9 = Connector(side_a=Parent.tsunami.fake_uart3, side_a_name='pio', side_b=Parent.magicbus) + c10 = Connector(side_a=Parent.tsunami.fake_uart4, side_a_name='pio', side_b=Parent.magicbus) + c12 = Connector(side_a=Parent.tsunami.fake_ppc, side_a_name='pio', side_b=Parent.magicbus) + c14 = Connector(side_a=Parent.tsunami.fake_OROM, side_a_name='pio', side_b=Parent.magicbus) + c16 = Connector(side_a=Parent.tsunami.fake_pnp_addr, side_a_name='pio', side_b=Parent.magicbus) + c17 = Connector(side_a=Parent.tsunami.fake_pnp_write, side_a_name='pio', side_b=Parent.magicbus) + c18 = Connector(side_a=Parent.tsunami.fake_pnp_read0, side_a_name='pio', side_b=Parent.magicbus) + c19 = Connector(side_a=Parent.tsunami.fake_pnp_read1, side_a_name='pio', side_b=Parent.magicbus) + c20 = Connector(side_a=Parent.tsunami.fake_pnp_read2, side_a_name='pio', side_b=Parent.magicbus) + c21 = Connector(side_a=Parent.tsunami.fake_pnp_read3, side_a_name='pio', side_b=Parent.magicbus) + c22 = Connector(side_a=Parent.tsunami.fake_pnp_read4, side_a_name='pio', side_b=Parent.magicbus) + c23 = Connector(side_a=Parent.tsunami.fake_pnp_read5, side_a_name='pio', side_b=Parent.magicbus) + c24 = Connector(side_a=Parent.tsunami.fake_pnp_read6, side_a_name='pio', side_b=Parent.magicbus) + c25 = Connector(side_a=Parent.tsunami.fake_pnp_read7, side_a_name='pio', side_b=Parent.magicbus) + c27 = Connector(side_a=Parent.tsunami.fake_ata0, side_a_name='pio', side_b=Parent.magicbus) + c28 = Connector(side_a=Parent.tsunami.fake_ata1, side_a_name='pio', side_b=Parent.magicbus) + c30 = Connector(side_a=Parent.tsunami.fb, side_a_name='pio', side_b=Parent.magicbus) + c31 = Connector(side_a=Parent.tsunami.io, side_a_name='pio', side_b=Parent.magicbus) + c32 = Connector(side_a=Parent.tsunami.uart, side_a_name='pio', side_b=Parent.magicbus) + c33 = Connector(side_a=Parent.tsunami.console, side_a_name='pio', side_b=Parent.magicbus) + raw_image = RawDiskImage(image_file=disk('linux.img'), + read_only=True) + simple_disk = SimpleDisk(disk=Parent.raw_image) + intrctrl = IntrControl() + cpu = SimpleCPU(mem=Parent.magicbus) + sim_console = SimConsole(listener=ConsoleListener(port=3456)) + kernel = binary('vmlinux') + pal = binary('ts_osfpal') + console = binary('console') + boot_osflags = 'root=/dev/hda1 console=ttyS0' + readfile = os.path.join(test_base, 'halt.sh') + + +BaseCPU.itb = AlphaITB() +BaseCPU.dtb = AlphaDTB() +BaseCPU.system = Parent.any + +class TsunamiRoot(Root): + pass + + +root = TsunamiRoot(clock = '2GHz', system = LinuxAlphaSystem()) diff --git a/configs/test/hello_mips b/configs/test/hello_mips Binary files differindex 182182b4f..a3db001ec 100755 --- a/configs/test/hello_mips +++ b/configs/test/hello_mips diff --git a/configs/test/hello_sparc b/configs/test/hello_sparc Binary files differindex e254ae33f..7b7302771 100755 --- a/configs/test/hello_sparc +++ b/configs/test/hello_sparc diff --git a/cpu/cpu_exec_context.hh b/cpu/cpu_exec_context.hh index 736af85ba..2c06a7b3b 100644 --- a/cpu/cpu_exec_context.hh +++ b/cpu/cpu_exec_context.hh @@ -241,17 +241,17 @@ class CPUExecContext int getInstAsid() { return regs.instAsid(); } int getDataAsid() { return regs.dataAsid(); } - Fault translateInstReq(CpuRequestPtr &req) + Fault translateInstReq(RequestPtr &req) { return itb->translate(req, proxy); } - Fault translateDataReadReq(CpuRequestPtr &req) + Fault translateDataReadReq(RequestPtr &req) { return dtb->translate(req, proxy, false); } - Fault translateDataWriteReq(CpuRequestPtr &req) + Fault translateDataWriteReq(RequestPtr &req) { return dtb->translate(req, proxy, true); } @@ -273,17 +273,17 @@ class CPUExecContext int getInstAsid() { return asid; } int getDataAsid() { return asid; } - Fault translateInstReq(CpuRequestPtr &req) + Fault translateInstReq(RequestPtr &req) { return process->pTable->translate(req); } - Fault translateDataReadReq(CpuRequestPtr &req) + Fault translateDataReadReq(RequestPtr &req) { return process->pTable->translate(req); } - Fault translateDataWriteReq(CpuRequestPtr &req) + Fault translateDataWriteReq(RequestPtr &req) { return process->pTable->translate(req); } @@ -292,7 +292,7 @@ class CPUExecContext /* template <class T> - Fault read(CpuRequestPtr &req, T &data) + Fault read(RequestPtr &req, T &data) { #if FULL_SYSTEM && THE_ISA == ALPHA_ISA if (req->flags & LOCKED) { @@ -308,7 +308,7 @@ class CPUExecContext } template <class T> - Fault write(CpuRequestPtr &req, T &data) + Fault write(RequestPtr &req, T &data) { #if FULL_SYSTEM && THE_ISA == ALPHA_ISA ExecContext *xc; @@ -369,7 +369,7 @@ class CPUExecContext inst = new_inst; } - Fault instRead(CpuRequestPtr &req) + Fault instRead(RequestPtr &req) { panic("instRead not implemented"); // return funcPhysMem->read(req, inst); diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 4e40bc48d..1f26183ab 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -152,11 +152,11 @@ class ExecContext virtual int getInstAsid() = 0; virtual int getDataAsid() = 0; - virtual Fault translateInstReq(CpuRequestPtr &req) = 0; + virtual Fault translateInstReq(RequestPtr &req) = 0; - virtual Fault translateDataReadReq(CpuRequestPtr &req) = 0; + virtual Fault translateDataReadReq(RequestPtr &req) = 0; - virtual Fault translateDataWriteReq(CpuRequestPtr &req) = 0; + virtual Fault translateDataWriteReq(RequestPtr &req) = 0; // Also somewhat obnoxious. Really only used for the TLB fault. // However, may be quite useful in SPARC. @@ -327,13 +327,13 @@ class ProxyExecContext : public ExecContext int getInstAsid() { return actualXC->getInstAsid(); } int getDataAsid() { return actualXC->getDataAsid(); } - Fault translateInstReq(CpuRequestPtr &req) + Fault translateInstReq(RequestPtr &req) { return actualXC->translateInstReq(req); } - Fault translateDataReadReq(CpuRequestPtr &req) + Fault translateDataReadReq(RequestPtr &req) { return actualXC->translateDataReadReq(req); } - Fault translateDataWriteReq(CpuRequestPtr &req) + Fault translateDataWriteReq(RequestPtr &req) { return actualXC->translateDataWriteReq(req); } // @todo: Do I need this? diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 88c99c566..0f1f9574a 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -155,13 +155,8 @@ SimpleCPU::CpuPort::recvRetry() } SimpleCPU::SimpleCPU(Params *p) -#if !FULL_SYSTEM : BaseCPU(p), mem(p->mem), icachePort(this), dcachePort(this), tickEvent(this, p->width), cpuXC(NULL) -#else - : BaseCPU(p), icachePort(this), dcachePort(this), - tickEvent(this, p->width), cpuXC(NULL) -#endif { _status = Idle; @@ -175,24 +170,24 @@ SimpleCPU::SimpleCPU(Params *p) xcProxy = cpuXC->getProxy(); #if SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE - ifetch_req = new CpuRequest; - ifetch_req->asid = 0; - ifetch_req->size = sizeof(MachInst); + ifetch_req = new Request(true); + ifetch_req->setAsid(0); + ifetch_req->setSize(sizeof(MachInst)); ifetch_pkt = new Packet; ifetch_pkt->cmd = Read; ifetch_pkt->data = (uint8_t *)&inst; ifetch_pkt->req = ifetch_req; ifetch_pkt->size = sizeof(MachInst); - data_read_req = new CpuRequest; - data_read_req->asid = 0; + data_read_req = new Request(true); + data_read_req->setAsid(0); data_read_pkt = new Packet; data_read_pkt->cmd = Read; data_read_pkt->data = new uint8_t[8]; data_read_pkt->req = data_read_req; - data_write_req = new CpuRequest; - data_write_req->asid = 0; + data_write_req = new Request(true); + data_write_req->setAsid(0); data_write_pkt = new Packet; data_write_pkt->cmd = Write; data_write_pkt->req = data_write_req; @@ -483,7 +478,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) } if (traceData) { - traceData->setAddr(addr); + traceData->setAddr(data_read_req->getVaddr()); } // @todo: Figure out a way to create a Fault from the packet result. @@ -493,13 +488,13 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) // memReq->reset(addr, sizeof(T), flags); #if SIMPLE_CPU_MEM_TIMING - CpuRequest *data_read_req = new CpuRequest; + CpuRequest *data_read_req = new Request(true); #endif - data_read_req->vaddr = addr; - data_read_req->size = sizeof(T); - data_read_req->flags = flags; - data_read_req->time = curTick; + data_read_req->setVaddr(addr); + data_read_req->setSize(sizeof(T)); + data_read_req->setFlags(flags); + data_read_req->setTime(curTick); // translate to physical address Fault fault = cpuXC->translateDataReadReq(data_read_req); @@ -512,7 +507,8 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) data_read_pkt->req = data_read_req; data_read_pkt->data = new uint8_t[8]; #endif - data_read_pkt->addr = data_read_req->paddr; + data_read_pkt->reset(); + data_read_pkt->addr = data_read_req->getPaddr(); data_read_pkt->size = sizeof(T); sendDcacheRequest(data_read_pkt); @@ -559,7 +555,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) } */ // This will need a new way to tell if it has a dcache attached. - if (data_read_req->flags & UNCACHEABLE) + if (data_read_req->getFlags() & UNCACHEABLE) recordEvent("Uncached Read"); return fault; @@ -612,10 +608,10 @@ template <class T> Fault SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) { - data_write_req->vaddr = addr; - data_write_req->time = curTick; - data_write_req->size = sizeof(T); - data_write_req->flags = flags; + data_write_req->setVaddr(addr); + data_write_req->setTime(curTick); + data_write_req->setSize(sizeof(T)); + data_write_req->setFlags(flags); // translate to physical address Fault fault = cpuXC->translateDataWriteReq(data_write_req); @@ -628,9 +624,10 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) data_write_pkt->data = new uint8_t[64]; memcpy(data_write_pkt->data, &data, sizeof(T)); #else + data_write_pkt->reset(); data_write_pkt->data = (uint8_t *)&data; #endif - data_write_pkt->addr = data_write_req->paddr; + data_write_pkt->addr = data_write_req->getPaddr(); data_write_pkt->size = sizeof(T); sendDcacheRequest(data_write_pkt); @@ -664,9 +661,14 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) *res = data_write_pkt->result; // This will need a new way to tell if it's hooked up to a cache or not. - if (data_write_req->flags & UNCACHEABLE) + if (data_write_req->getFlags() & UNCACHEABLE) recordEvent("Uncached Write"); + // @todo this is a hack and only works on uniprocessor systems some one else + // can implement LL/SC. + if (data_write_req->getFlags() & LOCKED) + *res = 1; + // If the write needs to have a fault on the access, consider calling // changeStatus() and changing it to "bad addr write" or something. return fault; @@ -962,26 +964,23 @@ SimpleCPU::tick() // Try to fetch an instruction // set up memory request for instruction fetch -#if FULL_SYSTEM -#define IFETCH_FLAGS(pc) ((pc) & 1) ? PHYSICAL : 0 -#else -#define IFETCH_FLAGS(pc) 0 -#endif DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(), cpuXC->readNextPC(),cpuXC->readNextNPC()); #if SIMPLE_CPU_MEM_TIMING CpuRequest *ifetch_req = new CpuRequest(); - ifetch_req->size = sizeof(MachInst); + ifetch_req->setSize(sizeof(MachInst)); #endif - ifetch_req->vaddr = cpuXC->readPC() & ~3; - ifetch_req->time = curTick; - -/* memReq->reset(xc->regs.pc & ~3, sizeof(uint32_t), - IFETCH_FLAGS(xc->regs.pc)); -*/ + ifetch_req->resetMin(); + ifetch_req->setVaddr(cpuXC->readPC() & ~3); + ifetch_req->setTime(curTick); +#if FULL_SYSTEM + ifetch_req->setFlags((cpuXC->readPC() & 1) ? PHYSICAL : 0); +#else + ifetch_req->setFlags(0); +#endif fault = cpuXC->translateInstReq(ifetch_req); @@ -993,7 +992,8 @@ SimpleCPU::tick() ifetch_pkt->req = ifetch_req; ifetch_pkt->size = sizeof(MachInst); #endif - ifetch_pkt->addr = ifetch_req->paddr; + ifetch_pkt->reset(); + ifetch_pkt->addr = ifetch_req->getPaddr(); sendIcacheRequest(ifetch_pkt); #if SIMPLE_CPU_MEM_TIMING || SIMPLE_CPU_MEM_ATOMIC @@ -1133,6 +1133,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU) Param<Counter> max_insts_all_threads; Param<Counter> max_loads_any_thread; Param<Counter> max_loads_all_threads; + SimObjectParam<MemObject *> mem; #if FULL_SYSTEM SimObjectParam<AlphaITB *> itb; @@ -1141,7 +1142,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU) Param<int> cpu_id; Param<Tick> profile; #else - SimObjectParam<MemObject *> mem; SimObjectParam<Process *> workload; #endif // FULL_SYSTEM @@ -1164,6 +1164,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU) "terminate when any thread reaches this load count"), INIT_PARAM(max_loads_all_threads, "terminate when all threads have reached this load count"), + INIT_PARAM(mem, "memory"), #if FULL_SYSTEM INIT_PARAM(itb, "Instruction TLB"), @@ -1172,7 +1173,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU) INIT_PARAM(cpu_id, "processor ID"), INIT_PARAM(profile, ""), #else - INIT_PARAM(mem, "memory"), INIT_PARAM(workload, "processes to run"), #endif // FULL_SYSTEM @@ -1199,6 +1199,7 @@ CREATE_SIM_OBJECT(SimpleCPU) params->functionTrace = function_trace; params->functionTraceStart = function_trace_start; params->width = width; + params->mem = mem; #if FULL_SYSTEM params->itb = itb; @@ -1207,7 +1208,6 @@ CREATE_SIM_OBJECT(SimpleCPU) params->cpu_id = cpu_id; params->profile = profile; #else - params->mem = mem; params->process = workload; #endif diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index 9da7072bf..c3ff5cf3d 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -178,11 +178,11 @@ class SimpleCPU : public BaseCPU struct Params : public BaseCPU::Params { int width; + MemObject *mem; #if FULL_SYSTEM AlphaITB *itb; AlphaDTB *dtb; #else - MemObject *mem; Process *process; #endif }; @@ -210,12 +210,12 @@ class SimpleCPU : public BaseCPU #if SIMPLE_CPU_MEM_TIMING Packet *retry_pkt; #elif SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE - CpuRequest *ifetch_req; - Packet *ifetch_pkt; - CpuRequest *data_read_req; - Packet *data_read_pkt; - CpuRequest *data_write_req; - Packet *data_write_pkt; + Request *ifetch_req; + Packet *ifetch_pkt; + Request *data_read_req; + Packet *data_read_pkt; + Request *data_write_req; + Packet *data_write_pkt; #endif // Pointer to the sampler that is telling us to switchover. diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index a200e2849..f0b75c10e 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -397,8 +397,9 @@ class StaticInst : public StaticInstBase int getRs() { return (machInst & 0x03E00000) >> 21; } //25...21 int getRt() { return (machInst & 0x001F0000) >> 16; } //20...16 int getRd() { return (machInst & 0x0000F800) >> 11; } //15...11 - int getOpname(){ return (machInst & 0x0000003F); }//5...0 - int getBranch(){ return (machInst & 0x0000FFFF); }//5...0 + int getImm() { return (machInst & 0x0000FFFF); } //15...0 + int getFunction(){ return (machInst & 0x0000003F); }//5...0 + int getBranch(){ return (machInst & 0x0000FFFF); }//15...0 int getJump(){ return (machInst & 0x03FFFFFF); }//5...0 int getHint(){ return (machInst & 0x000007C0) >> 6; } //10...6 std::string getName() { return mnemonic; } diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 8c097fdd0..fde8af6ae 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -72,12 +72,12 @@ AlphaConsole::AlphaConsole(Params *p) alphaAccess->inputChar = 0; bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack)); - system->setAlphaAccess(pioAddr); } void AlphaConsole::startup() { + system->setAlphaAccess(pioAddr); alphaAccess->numCPUs = system->getNumCPUs(); alphaAccess->kernStart = system->getKernelStart(); alphaAccess->kernEnd = system->getKernelEnd(); @@ -87,15 +87,6 @@ AlphaConsole::startup() alphaAccess->intrClockFrequency = params()->platform->intrFrequency(); } -void -AlphaConsole::addressRanges(AddrRangeList &range_list) -{ - assert(pioSize != 0); - range_list.clear(); - range_list.push_back(RangeSize(pioAddr, sizeof(struct AlphaAccess))); -} - - Tick AlphaConsole::read(Packet &pkt) { @@ -120,8 +111,7 @@ AlphaConsole::read(Packet &pkt) if (!pkt.data) { data32 = new uint32_t; pkt.data = (uint8_t*)data32; - } - else + } else data32 = (uint32_t*)pkt.data; switch (daddr) @@ -150,8 +140,7 @@ AlphaConsole::read(Packet &pkt) if (!pkt.data) { data64 = new uint64_t; pkt.data = (uint8_t*)data64; - } - else + } else data64 = (uint64_t*)pkt.data; switch (daddr) { @@ -327,7 +316,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) SimObjectParam<SimConsole *> sim_console; SimObjectParam<SimpleDisk *> disk; - Param<Addr> addr; + Param<Addr> pio_addr; SimObjectParam<AlphaSystem *> system; SimObjectParam<BaseCPU *> cpu; SimObjectParam<Platform *> platform; @@ -339,7 +328,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole) INIT_PARAM(sim_console, "The Simulator Console"), INIT_PARAM(disk, "Simple Disk"), - INIT_PARAM(addr, "Device Address"), + INIT_PARAM(pio_addr, "Device Address"), INIT_PARAM(system, "system object"), INIT_PARAM(cpu, "Processor"), INIT_PARAM(platform, "platform"), @@ -352,7 +341,7 @@ CREATE_SIM_OBJECT(AlphaConsole) AlphaConsole::Params *p = new AlphaConsole::Params; p->name = getInstanceName(); p->platform = platform; - p->pio_addr = addr; + p->pio_addr = pio_addr; p->pio_delay = pio_latency; p->cons = sim_console; p->disk = disk; diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index 0435feb89..05aec5ec1 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -119,9 +119,6 @@ class AlphaConsole : public BasicPioDevice virtual Tick read(Packet &pkt); virtual Tick write(Packet &pkt); - /** Address ranges this device is sensitive to. */ - virtual void addressRanges(AddrRangeList &range_list); - /** * standard serialization routines for checkpointing */ diff --git a/dev/baddev.cc b/dev/baddev.cc index 87d683a5d..dcabdbe0a 100644 --- a/dev/baddev.cc +++ b/dev/baddev.cc @@ -35,82 +35,63 @@ #include <vector> #include "base/trace.hh" -#include "cpu/exec_context.hh" #include "dev/baddev.hh" #include "dev/platform.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" +#include "mem/port.hh" #include "sim/builder.hh" #include "sim/system.hh" using namespace std; using namespace TheISA; -BadDevice::BadDevice(const string &name, Addr a, MemoryController *mmu, - HierParams *hier, Bus *pio_bus, const string &devicename) - : PioDevice(name, NULL), addr(a), devname(devicename) +BadDevice::BadDevice(Params *p) + : BasicPioDevice(p), devname(p->device_name) { - mmu->add_child(this, RangeSize(addr, size)); - - if (pio_bus) { - pioInterface = newPioInterface(name, hier, pio_bus, this, - &BadDevice::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - } - + pioSize = 0xf; } -Fault -BadDevice::read(MemReqPtr &req, uint8_t *data) -{ - - panic("Device %s not imlpmented\n", devname); - return NoFault; -} - -Fault -BadDevice::write(MemReqPtr &req, const uint8_t *data) +Tick +BadDevice::read(Packet &pkt) { panic("Device %s not imlpmented\n", devname); - return NoFault; } Tick -BadDevice::cacheAccess(MemReqPtr &req) +BadDevice::write(Packet &pkt) { - return curTick; + panic("Device %s not imlpmented\n", devname); } BEGIN_DECLARE_SIM_OBJECT_PARAMS(BadDevice) + Param<string> devicename; + Param<Addr> pio_addr; + SimObjectParam<System *> system; SimObjectParam<Platform *> platform; - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - SimObjectParam<HierParams *> hier; - SimObjectParam<Bus*> pio_bus; Param<Tick> pio_latency; - Param<string> devicename; END_DECLARE_SIM_OBJECT_PARAMS(BadDevice) BEGIN_INIT_SIM_OBJECT_PARAMS(BadDevice) - INIT_PARAM(platform, "Platform"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), - INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000), - INIT_PARAM(devicename, "Name of device to error on") + INIT_PARAM(devicename, "Name of device to error on"), + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(system, "system object"), + INIT_PARAM(platform, "platform"), + INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000) END_INIT_SIM_OBJECT_PARAMS(BadDevice) CREATE_SIM_OBJECT(BadDevice) { - return new BadDevice(getInstanceName(), addr, mmu, hier, pio_bus, - devicename); + BadDevice::Params *p = new BadDevice::Params; + p->name =getInstanceName(); + p->platform = platform; + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->system = system; + p->device_name = devicename; + return new BadDevice(p); } REGISTER_SIM_OBJECT("BadDevice", BadDevice) diff --git a/dev/baddev.hh b/dev/baddev.hh index 189f28331..4cf0d6ba4 100644 --- a/dev/baddev.hh +++ b/dev/baddev.hh @@ -37,7 +37,6 @@ #include "base/range.hh" #include "dev/io_device.hh" -class MemoryController; /** * BadDevice @@ -45,51 +44,29 @@ class MemoryController; * the user that the kernel they are running has unsupported * options (i.e. frame buffer) */ -class BadDevice : public PioDevice +class BadDevice : public BasicPioDevice { private: - Addr addr; - static const Addr size = 0xf; - std::string devname; public: + struct Params : public BasicPioDevice::Params + { + std::string device_name; + }; + protected: + const Params *params() const { return (const Params *)_params; } + + public: /** * Constructor for the Baddev Class. - * @param name name of the object + * @param p object parameters * @param a base address of the write - * @param mmu the memory controller - * @param hier object to store parameters universal the device hierarchy - * @param bus The bus that this device is attached to - * @param devicename device that is not implemented - */ - BadDevice(const std::string &name, Addr a, MemoryController *mmu, - HierParams *hier, Bus *bus, const std::string &devicename); - - /** - * On a read event we just panic aand hopefully print a - * meaningful error message. - * @param req Contains the address to read from. - * @param data A pointer to write the read data to. - * @return The fault condition of the access. - */ - virtual Fault read(MemReqPtr &req, uint8_t *data); - - /** - * On a write event we just panic aand hopefully print a - * meaningful error message. - * @param req Contains the address to write to. - * @param data The data to write. - * @return The fault condition of the access. */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + BadDevice(Params *p); - /** - * Return how long this access will take. - * @param req the memory request to calcuate - * @return Tick when the request is done - */ - Tick cacheAccess(MemReqPtr &req); + virtual Tick read(Packet &pkt); + virtual Tick write(Packet &pkt); }; #endif // __DEV_BADDEV_HH__ diff --git a/dev/io_device.cc b/dev/io_device.cc index 5d3a87006..a2e5a8a0d 100644 --- a/dev/io_device.cc +++ b/dev/io_device.cc @@ -78,7 +78,7 @@ bool PioPort::recvTiming(Packet &pkt) { device->recvAtomic(pkt); - sendTiming(pkt, pkt.time-pkt.req->time); + sendTiming(pkt, pkt.time-pkt.req->getTime()); return Success; } @@ -88,6 +88,22 @@ PioDevice::~PioDevice() delete pioPort; } +void +PioDevice::init() +{ + if (!pioPort) + panic("Pio port not connected to anything!"); + pioPort->sendStatusChange(Port::RangeChange); +} + +void +BasicPioDevice::addressRanges(AddrRangeList &range_list) +{ + assert(pioSize != 0); + range_list.clear(); + range_list.push_back(RangeSize(pioAddr, pioSize)); +} + DmaPort::DmaPort(DmaDevice *dev) : device(dev) @@ -132,7 +148,7 @@ DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size, int prevSize = 0; Packet basePkt; - Request baseReq; + Request baseReq(false); basePkt.flags = 0; basePkt.coherence = NULL; @@ -142,8 +158,8 @@ DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size, basePkt.cmd = cmd; basePkt.result = Unknown; basePkt.req = NULL; - baseReq.nicReq = true; - baseReq.time = curTick; +// baseReq.nicReq = true; + baseReq.setTime(curTick); completionEvent = event; @@ -154,8 +170,8 @@ DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size, pkt->addr = gen.addr(); pkt->size = gen.size(); pkt->req = req; - pkt->req->paddr = pkt->addr; - pkt->req->size = pkt->size; + pkt->req->setPaddr(pkt->addr); + pkt->req->setSize(pkt->size); // Increment the data pointer on a write pkt->data = data ? data + prevSize : NULL ; prevSize += pkt->size; @@ -178,7 +194,7 @@ DmaPort::sendDma(Packet &pkt) transmitList.push_back(&packet); } else if (state == Atomic) {*/ sendAtomic(pkt); - completionEvent->schedule(pkt.time - pkt.req->time); + completionEvent->schedule(pkt.time - pkt.req->getTime()); completionEvent = NULL; /* } else if (state == Functional) { sendFunctional(pkt); diff --git a/dev/io_device.hh b/dev/io_device.hh index a81dae072..5379a664c 100644 --- a/dev/io_device.hh +++ b/dev/io_device.hh @@ -30,7 +30,7 @@ #define __DEV_IO_DEVICE_HH__ #include "base/chunk_generator.hh" -#include "mem/port.hh" +#include "mem/mem_object.hh" #include "sim/eventq.hh" #include "sim/sim_object.hh" @@ -172,7 +172,7 @@ class DmaPort : public Port * bother. */ -class PioDevice : public SimObject +class PioDevice : public MemObject { protected: @@ -192,11 +192,17 @@ class PioDevice : public SimObject { return pkt.cmd == Read ? this->read(pkt) : this->write(pkt); } /** Pure virtual function that the device must implement. Called when a read - * command is recieved by the port. */ + * command is recieved by the port. + * @param pkt Packet describing this request + * @return number of ticks it took to complete + */ virtual Tick read(Packet &pkt) = 0; /** Pure virtual function that the device must implement. Called when a - * write command is recieved by the port. */ + * write command is recieved by the port. + * @param pkt Packet describing this request + * @return number of ticks it took to complete + */ virtual Tick write(Packet &pkt) = 0; public: @@ -218,11 +224,14 @@ class PioDevice : public SimObject const Params *params() const { return _params; } PioDevice(Params *p) - : SimObject(params()->name), platform(p->platform), _params(p) + : MemObject(p->name), platform(p->platform), pioPort(NULL), + _params(p) {} virtual ~PioDevice(); + virtual void init(); + virtual Port *getPort(const std::string &if_name) { if (if_name == "pio") { @@ -261,6 +270,11 @@ class BasicPioDevice : public PioDevice : PioDevice(p), pioAddr(p->pio_addr), pioSize(0), pioDelay(p->pio_delay) {} + /** return the address ranges that this device responds to. + * @params range_list range list to populate with ranges + */ + void addressRanges(AddrRangeList &range_list); + }; class DmaDevice : public PioDevice diff --git a/dev/isa_fake.cc b/dev/isa_fake.cc index 7ce43b712..1ed355499 100644 --- a/dev/isa_fake.cc +++ b/dev/isa_fake.cc @@ -34,108 +34,118 @@ #include <string> #include <vector> -#include "arch/alpha/ev5.hh" #include "base/trace.hh" -#include "cpu/exec_context.hh" #include "dev/isa_fake.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" +#include "mem/packet.hh" #include "sim/builder.hh" #include "sim/system.hh" using namespace std; -using namespace TheISA; -IsaFake::IsaFake(const string &name, Addr a, MemoryController *mmu, - HierParams *hier, Bus *pio_bus, Addr size) - : PioDevice(name, NULL), addr(a) +IsaFake::IsaFake(Params *p) + : BasicPioDevice(p) { - mmu->add_child(this, RangeSize(addr, size)); - - if (pio_bus) { - pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, - &IsaFake::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - } + pioSize = p->pio_size; } -Fault -IsaFake::read(MemReqPtr &req, uint8_t *data) +Tick +IsaFake::read(Packet &pkt) { - DPRINTF(Tsunami, "read va=%#x size=%d\n", - req->vaddr, req->size); + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); -#if TRACING_ON - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; -#endif + pkt.time = curTick + pioDelay; - switch (req->size) { + DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size); + uint8_t *data8; + uint16_t *data16; + uint32_t *data32; + uint64_t *data64; + + switch (pkt.size) { case sizeof(uint64_t): - *(uint64_t*)data = 0xFFFFFFFFFFFFFFFFULL; - return NoFault; + if (!pkt.data) { + data64 = new uint64_t; + pkt.data = (uint8_t*)data64; + } else { + data64 = (uint64_t*)pkt.data; + } + *data64 = 0xFFFFFFFFFFFFFFFFULL; + break; case sizeof(uint32_t): - *(uint32_t*)data = 0xFFFFFFFF; - return NoFault; + if (!pkt.data) { + data32 = new uint32_t; + pkt.data = (uint8_t*)data32; + } else { + data32 = (uint32_t*)pkt.data; + } + *data32 = 0xFFFFFFFF; + break; case sizeof(uint16_t): - *(uint16_t*)data = 0xFFFF; - return NoFault; + if (!pkt.data) { + data16 = new uint16_t; + pkt.data = (uint8_t*)data16; + } else { + data16 = (uint16_t*)pkt.data; + } + *data16 = 0xFFFF; + break; case sizeof(uint8_t): - *(uint8_t*)data = 0xFF; - return NoFault; - + if (!pkt.data) { + data8 = new uint8_t; + pkt.data = data8; + } else { + data8 = (uint8_t*)pkt.data; + } + *data8 = 0xFF; + break; default: panic("invalid access size(?) for PCI configspace!\n"); } - DPRINTFN("Isa FakeSMC ERROR: read daddr=%#x size=%d\n", daddr, req->size); - - return NoFault; -} - -Fault -IsaFake::write(MemReqPtr &req, const uint8_t *data) -{ - DPRINTF(Tsunami, "write - va=%#x size=%d \n", - req->vaddr, req->size); - - //:Addr daddr = (req->paddr & addr_mask) >> 6; - - return NoFault; + pkt.result = Success; + return pioDelay; } Tick -IsaFake::cacheAccess(MemReqPtr &req) +IsaFake::write(Packet &pkt) { - return curTick; + pkt.time = curTick + pioDelay; + DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt.addr, pkt.size); + pkt.result = Success; + return pioDelay; } BEGIN_DECLARE_SIM_OBJECT_PARAMS(IsaFake) - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - SimObjectParam<Bus*> pio_bus; + Param<Addr> pio_addr; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; - Param<Addr> size; + Param<Addr> pio_size; + SimObjectParam<Platform *> platform; + SimObjectParam<System *> system; END_DECLARE_SIM_OBJECT_PARAMS(IsaFake) BEGIN_INIT_SIM_OBJECT_PARAMS(IsaFake) - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), - INIT_PARAM_DFLT(size, "Size of address range", 0x8) + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(pio_size, "Size of address range"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object") END_INIT_SIM_OBJECT_PARAMS(IsaFake) CREATE_SIM_OBJECT(IsaFake) { - return new IsaFake(getInstanceName(), addr, mmu, hier, pio_bus, size); + IsaFake::Params *p = new IsaFake::Params; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->pio_size = pio_size; + p->platform = platform; + p->system = system; + return new IsaFake(p); } REGISTER_SIM_OBJECT("IsaFake", IsaFake) diff --git a/dev/isa_fake.hh b/dev/isa_fake.hh index 73e40c681..29050833d 100644 --- a/dev/isa_fake.hh +++ b/dev/isa_fake.hh @@ -37,51 +37,42 @@ #include "base/range.hh" #include "dev/io_device.hh" -class MemoryController; - /** * IsaFake is a device that returns -1 on all reads and * accepts all writes. It is meant to be placed at an address range * so that an mcheck doesn't occur when an os probes a piece of hw * that doesn't exist (e.g. UARTs1-3). */ -class IsaFake : public PioDevice +class IsaFake : public BasicPioDevice { - private: - /** The address in memory that we respond to */ - Addr addr; + public: + struct Params : public BasicPioDevice::Params + { + Addr pio_size; + }; + protected: + const Params *params() const { return (const Params*)_params; } public: /** * The constructor for Tsunmami Fake just registers itself with the MMU. - * @param name name of this device. - * @param a address to respond to. - * @param mmu the mmu we register with. - * @param size number of addresses to respond to + * @param p params structure */ - IsaFake(const std::string &name, Addr a, MemoryController *mmu, - HierParams *hier, Bus *pio_bus, Addr size = 0x8); + IsaFake(Params *p); /** * This read always returns -1. * @param req The memory request. * @param data Where to put the data. */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Tick read(Packet &pkt); /** * All writes are simply ignored. * @param req The memory request. * @param data the data to not write. */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); - - /** - * Return how long this access will take. - * @param req the memory request to calcuate - * @return Tick when the request is done - */ - Tick cacheAccess(MemReqPtr &req); + virtual Tick write(Packet &pkt); }; -#endif // __ISA_FAKE_HH__ +#endif // __TSUNAMI_FAKE_HH__ diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index 1a138fb39..86a505b9a 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -35,34 +35,25 @@ #include <vector> #include <bitset> -#include "arch/alpha/ev5.hh" #include "base/trace.hh" #include "dev/pciconfigall.hh" -#include "dev/pcidev.hh" +//#include "dev/pcidev.hh" #include "dev/pcireg.h" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" +#include "dev/platform.hh" +#include "mem/packet.hh" #include "sim/builder.hh" #include "sim/system.hh" using namespace std; -using namespace TheISA; -PciConfigAll::PciConfigAll(const string &name, - Addr a, MemoryController *mmu, - HierParams *hier, Bus *pio_bus, Tick pio_latency) - : PioDevice(name, NULL), addr(a) +PciConfigAll::PciConfigAll(Params *p) + : BasicPioDevice(p) { - mmu->add_child(this, RangeSize(addr, size)); + pioSize = 0xffffff; - if (pio_bus) { - pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, - &PciConfigAll::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - pioLatency = pio_latency * pio_bus->clockRate; - } + // Set backpointer for pci config. Really the config stuff should be able to + // automagically do this + p->platform->pciconfig = this; // Make all the pointers to devices null for(int x=0; x < MAX_PCI_DEV; x++) @@ -77,7 +68,7 @@ PciConfigAll::PciConfigAll(const string &name, void PciConfigAll::startup() { - bitset<256> intLines; +/* bitset<256> intLines; PciDev *tempDev; uint8_t intline; @@ -94,79 +85,109 @@ PciConfigAll::startup() } // devices != NULL } // PCI_FUNC } // PCI_DEV - + */ } -Fault -PciConfigAll::read(MemReqPtr &req, uint8_t *data) +Tick +PciConfigAll::read(Packet &pkt) { + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); - - DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", - req->vaddr, daddr, req->size); - + Addr daddr = pkt.addr - pioAddr; int device = (daddr >> 11) & 0x1F; int func = (daddr >> 8) & 0x7; - int reg = daddr & 0xFF; - - if (devices[device][func] == NULL) { - switch (req->size) { - // case sizeof(uint64_t): - // *(uint64_t*)data = 0xFFFFFFFFFFFFFFFF; - // return NoFault; - case sizeof(uint32_t): - *(uint32_t*)data = 0xFFFFFFFF; - return NoFault; - case sizeof(uint16_t): - *(uint16_t*)data = 0xFFFF; - return NoFault; - case sizeof(uint8_t): - *(uint8_t*)data = 0xFF; - return NoFault; - default: - panic("invalid access size(?) for PCI configspace!\n"); - } - } else { - switch (req->size) { - case sizeof(uint32_t): - case sizeof(uint16_t): - case sizeof(uint8_t): - devices[device][func]->readConfig(reg, req->size, data); - return NoFault; - default: - panic("invalid access size(?) for PCI configspace!\n"); - } + //int reg = daddr & 0xFF; + + pkt.time = curTick + pioDelay; + + DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt.addr, daddr, + pkt.size); + + uint8_t *data8; + uint16_t *data16; + uint32_t *data32; + + switch (pkt.size) { +/* case sizeof(uint64_t): + if (!pkt.data) { + data64 = new uint64_t; + pkt.data = (uint8_t*)data64; + } else { + data64 = (uint64_t*)pkt.data; + } + if (devices[device][func] == NULL) + *data64 = 0xFFFFFFFFFFFFFFFFULL; + else + devices[device][func]->readConfig(reg, req.size, data64); + break;*/ + case sizeof(uint32_t): + if (!pkt.data) { + data32 = new uint32_t; + pkt.data = (uint8_t*)data32; + } else { + data32 = (uint32_t*)pkt.data; + } + if (devices[device][func] == NULL) + *data32 = 0xFFFFFFFF; + else + ;//devices[device][func]->readConfig(reg, req.size, data32); + break; + case sizeof(uint16_t): + if (!pkt.data) { + data16 = new uint16_t; + pkt.data = (uint8_t*)data16; + } else { + data16 = (uint16_t*)pkt.data; + } + if (devices[device][func] == NULL) + *data16 = 0xFFFF; + else + ;//devices[device][func]->readConfig(reg, req.size, data16); + break; + case sizeof(uint8_t): + if (!pkt.data) { + data8 = new uint8_t; + pkt.data = data8; + } else { + data8 = (uint8_t*)pkt.data; + } + if (devices[device][func] == NULL) + *data8 = 0xFF; + else + ;//devices[device][func]->readConfig(reg, req.size, data8); + break; + default: + panic("invalid access size(?) for PCI configspace!\n"); } - - DPRINTFN("PCI Configspace ERROR: read daddr=%#x size=%d\n", - daddr, req->size); - - return NoFault; + pkt.result = Success; + return pioDelay; } -Fault -PciConfigAll::write(MemReqPtr &req, const uint8_t *data) +Tick +PciConfigAll::write(Packet &pkt) { - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); + pkt.time = curTick + pioDelay; + + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + assert(pkt.size == sizeof(uint8_t) || pkt.size == sizeof(uint16_t) || + pkt.size == sizeof(uint32_t)); + Addr daddr = pkt.addr - pioAddr; int device = (daddr >> 11) & 0x1F; int func = (daddr >> 8) & 0x7; - int reg = daddr & 0xFF; +// int reg = daddr & 0xFF; if (devices[device][func] == NULL) panic("Attempting to write to config space on non-existant device\n"); - else if (req->size != sizeof(uint8_t) && - req->size != sizeof(uint16_t) && - req->size != sizeof(uint32_t)) - panic("invalid access size(?) for PCI configspace!\n"); DPRINTF(PciConfigAll, "write - va=%#x size=%d data=%#x\n", - req->vaddr, req->size, *(uint32_t*)data); + pkt.addr, pkt.size, *(uint32_t*)pkt.data); - devices[device][func]->writeConfig(reg, req->size, data); +// devices[device][func]->writeConfig(reg, req->size, data); - return NoFault; + return pioDelay; } void @@ -189,40 +210,34 @@ PciConfigAll::unserialize(Checkpoint *cp, const std::string §ion) */ } -Tick -PciConfigAll::cacheAccess(MemReqPtr &req) -{ - return curTick + pioLatency; -} - #ifndef DOXYGEN_SHOULD_SKIP_THIS BEGIN_DECLARE_SIM_OBJECT_PARAMS(PciConfigAll) - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - Param<Addr> mask; - SimObjectParam<Bus*> pio_bus; + Param<Addr> pio_addr; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; + SimObjectParam<Platform *> platform; + SimObjectParam<System *> system; END_DECLARE_SIM_OBJECT_PARAMS(PciConfigAll) BEGIN_INIT_SIM_OBJECT_PARAMS(PciConfigAll) - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM(mask, "Address Mask"), - INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object") END_INIT_SIM_OBJECT_PARAMS(PciConfigAll) CREATE_SIM_OBJECT(PciConfigAll) { - return new PciConfigAll(getInstanceName(), addr, mmu, hier, pio_bus, - pio_latency); + BasicPioDevice::Params *p = new BasicPioDevice::Params; + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + return new PciConfigAll(p); } REGISTER_SIM_OBJECT("PciConfigAll", PciConfigAll) diff --git a/dev/pciconfigall.hh b/dev/pciconfigall.hh index c6a0241d8..b2034594c 100644 --- a/dev/pciconfigall.hh +++ b/dev/pciconfigall.hh @@ -43,7 +43,6 @@ static const uint32_t MAX_PCI_DEV = 32; static const uint32_t MAX_PCI_FUNC = 8; class PciDev; -class MemoryController; /** * PCI Config Space @@ -52,10 +51,9 @@ class MemoryController; * space and passes the requests on to TsunamiPCIDev devices as * appropriate. */ -class PciConfigAll : public PioDevice +class PciConfigAll : public BasicPioDevice { private: - Addr addr; static const Addr size = 0xffffff; /** @@ -67,15 +65,9 @@ class PciConfigAll : public PioDevice public: /** * Constructor for PCIConfigAll - * @param name name of the object - * @param a base address of the write - * @param mmu the memory controller - * @param hier object to store parameters universal the device hierarchy - * @param bus The bus that this device is attached to + * @param p parameters structure */ - PciConfigAll(const std::string &name, Addr a, MemoryController *mmu, - HierParams *hier, Bus *pio_bus, Tick pio_latency); - + PciConfigAll(Params *p); /** * Check if a device exists. @@ -99,11 +91,10 @@ class PciConfigAll : public PioDevice * Read something in PCI config space. If the device does not exist * -1 is returned, if the device does exist its PciDev::ReadConfig (or the * virtual function that overrides) it is called. - * @param req Contains the address of the field to read. - * @param data Return the field read. - * @return The fault condition of the access. + * @param pkt Contains the address of the field to read. + * @return Amount of time to do the read */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Tick read(Packet &pkt); /** * Write to PCI config spcae. If the device does not exit the simulator @@ -114,7 +105,7 @@ class PciConfigAll : public PioDevice * @return The fault condition of the access. */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick write(Packet &pkt); /** * Start up function to check if more than one person is using an interrupt line @@ -134,14 +125,6 @@ class PciConfigAll : public PioDevice * @param section The section name of this object */ virtual void unserialize(Checkpoint *cp, const std::string §ion); - - /** - * Return how long this access will take. - * @param req the memory request to calcuate - * @return Tick when the request is done - */ - Tick cacheAccess(MemReqPtr &req); - }; #endif // __PCICONFIGALL_HH__ diff --git a/dev/platform.cc b/dev/platform.cc index 5b667b12c..9d10e0828 100644 --- a/dev/platform.cc +++ b/dev/platform.cc @@ -33,8 +33,8 @@ using namespace std; using namespace TheISA; -Platform::Platform(const string &name, IntrControl *intctrl, PciConfigAll *pci) - : SimObject(name), intrctrl(intctrl), pciconfig(pci) +Platform::Platform(const string &name, IntrControl *intctrl) + : SimObject(name), intrctrl(intctrl) { } diff --git a/dev/platform.hh b/dev/platform.hh index 2c37048d4..f149ca2fb 100644 --- a/dev/platform.hh +++ b/dev/platform.hh @@ -59,8 +59,9 @@ class Platform : public SimObject System *system; public: - Platform(const std::string &name, IntrControl *intctrl, PciConfigAll *pci); + Platform(const std::string &name, IntrControl *intctrl); virtual ~Platform(); + virtual void init() { if (pciconfig == NULL) panic("PCI Config not set"); } virtual void postConsoleInt() = 0; virtual void clearConsoleInt() = 0; virtual Tick intrFrequency() = 0; diff --git a/dev/tsunami.cc b/dev/tsunami.cc index 58fc7434e..ed011531d 100644 --- a/dev/tsunami.cc +++ b/dev/tsunami.cc @@ -36,12 +36,10 @@ #include "cpu/intr_control.hh" #include "dev/simconsole.hh" -#include "dev/ide_ctrl.hh" #include "dev/tsunami_cchip.hh" #include "dev/tsunami_pchip.hh" #include "dev/tsunami_io.hh" #include "dev/tsunami.hh" -#include "dev/pciconfigall.hh" #include "sim/builder.hh" #include "sim/system.hh" @@ -49,9 +47,8 @@ using namespace std; //Should this be AlphaISA? using namespace TheISA; -Tsunami::Tsunami(const string &name, System *s, IntrControl *ic, - PciConfigAll *pci) - : Platform(name, ic, pci), system(s) +Tsunami::Tsunami(const string &name, System *s, IntrControl *ic) + : Platform(name, ic), system(s) { // set the back pointer from the system to myself system->platform = this; @@ -112,21 +109,19 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tsunami) SimObjectParam<System *> system; SimObjectParam<IntrControl *> intrctrl; - SimObjectParam<PciConfigAll *> pciconfig; END_DECLARE_SIM_OBJECT_PARAMS(Tsunami) BEGIN_INIT_SIM_OBJECT_PARAMS(Tsunami) INIT_PARAM(system, "system"), - INIT_PARAM(intrctrl, "interrupt controller"), - INIT_PARAM(pciconfig, "PCI configuration") + INIT_PARAM(intrctrl, "interrupt controller") END_INIT_SIM_OBJECT_PARAMS(Tsunami) CREATE_SIM_OBJECT(Tsunami) { - return new Tsunami(getInstanceName(), system, intrctrl, pciconfig); + return new Tsunami(getInstanceName(), system, intrctrl); } REGISTER_SIM_OBJECT("Tsunami", Tsunami) diff --git a/dev/tsunami.hh b/dev/tsunami.hh index 7fd91d5b2..668c82674 100644 --- a/dev/tsunami.hh +++ b/dev/tsunami.hh @@ -38,12 +38,9 @@ #include "dev/platform.hh" class IdeController; -class TlaserClock; -class NSGigE; class TsunamiCChip; class TsunamiPChip; class TsunamiIO; -class PciConfigAll; class System; /** @@ -86,8 +83,7 @@ class Tsunami : public Platform * @param name name of the object * @param intrctrl pointer to the interrupt controller */ - Tsunami(const std::string &name, System *s, IntrControl *intctrl, - PciConfigAll *pci); + Tsunami(const std::string &name, System *s, IntrControl *intctrl); /** * Return the interrupting frequency to AlphaAccess diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index 8c6db8a43..81ad9a71d 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -39,10 +39,7 @@ #include "dev/tsunami_cchip.hh" #include "dev/tsunamireg.h" #include "dev/tsunami.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" +#include "mem/port.hh" #include "cpu/exec_context.hh" #include "cpu/intr_control.hh" #include "sim/builder.hh" @@ -52,19 +49,10 @@ using namespace std; //Should this be AlphaISA? using namespace TheISA; -TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, - MemoryController *mmu, HierParams *hier, - Bus* pio_bus, Tick pio_latency) - : PioDevice(name, t), addr(a), tsunami(t) +TsunamiCChip::TsunamiCChip(Params *p) + : BasicPioDevice(p), tsunami(p->tsunami) { - mmu->add_child(this, RangeSize(addr, size)); - - if (pio_bus) { - pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, - &TsunamiCChip::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - pioLatency = pio_latency * pio_bus->clockRate; - } + pioSize = 0xfffffff; drir = 0; ipint = 0; @@ -80,315 +68,310 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, tsunami->cchip = this; } -Fault -TsunamiCChip::read(MemReqPtr &req, uint8_t *data) +Tick +TsunamiCChip::read(Packet &pkt) { - DPRINTF(Tsunami, "read va=%#x size=%d\n", req->vaddr, req->size); + DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size); - Addr regnum = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - ExecContext *xc = req->xc; + pkt.time = curTick + pioDelay; + Addr regnum = (pkt.addr - pioAddr) >> 6; + Addr daddr = (pkt.addr - pioAddr); - switch (req->size) { + uint64_t *data64; + + switch (pkt.size) { case sizeof(uint64_t): + if (!pkt.data) { + data64 = new uint64_t; + pkt.data = (uint8_t*)data64; + } else + data64 = (uint64_t*)pkt.data; + if (daddr & TSDEV_CC_BDIMS) { - *(uint64_t*)data = dim[(daddr >> 4) & 0x3F]; - return NoFault; + *data64 = dim[(daddr >> 4) & 0x3F]; + break; } if (daddr & TSDEV_CC_BDIRS) { - *(uint64_t*)data = dir[(daddr >> 4) & 0x3F]; - return NoFault; + *data64 = dir[(daddr >> 4) & 0x3F]; + break; } switch(regnum) { case TSDEV_CC_CSR: - *(uint64_t*)data = 0x0; - return NoFault; + *data64 = 0x0; + break; case TSDEV_CC_MTR: panic("TSDEV_CC_MTR not implemeted\n"); - return NoFault; + break; case TSDEV_CC_MISC: - *(uint64_t*)data = (ipint << 8) & 0xF | - (itint << 4) & 0xF | - (xc->readCpuId() & 0x3); - return NoFault; + *data64 = (ipint << 8) & 0xF | (itint << 4) & 0xF | + (pkt.req->getCpuNum() & 0x3); + break; case TSDEV_CC_AAR0: case TSDEV_CC_AAR1: case TSDEV_CC_AAR2: case TSDEV_CC_AAR3: - *(uint64_t*)data = 0; - return NoFault; + *data64 = 0; + break; case TSDEV_CC_DIM0: - *(uint64_t*)data = dim[0]; - return NoFault; + *data64 = dim[0]; + break; case TSDEV_CC_DIM1: - *(uint64_t*)data = dim[1]; - return NoFault; + *data64 = dim[1]; + break; case TSDEV_CC_DIM2: - *(uint64_t*)data = dim[2]; - return NoFault; + *data64 = dim[2]; + break; case TSDEV_CC_DIM3: - *(uint64_t*)data = dim[3]; - return NoFault; + *data64 = dim[3]; + break; case TSDEV_CC_DIR0: - *(uint64_t*)data = dir[0]; - return NoFault; + *data64 = dir[0]; + break; case TSDEV_CC_DIR1: - *(uint64_t*)data = dir[1]; - return NoFault; + *data64 = dir[1]; + break; case TSDEV_CC_DIR2: - *(uint64_t*)data = dir[2]; - return NoFault; + *data64 = dir[2]; + break; case TSDEV_CC_DIR3: - *(uint64_t*)data = dir[3]; - return NoFault; + *data64 = dir[3]; + break; case TSDEV_CC_DRIR: - *(uint64_t*)data = drir; - return NoFault; + *data64 = drir; + break; case TSDEV_CC_PRBEN: panic("TSDEV_CC_PRBEN not implemented\n"); - return NoFault; + break; case TSDEV_CC_IIC0: case TSDEV_CC_IIC1: case TSDEV_CC_IIC2: case TSDEV_CC_IIC3: panic("TSDEV_CC_IICx not implemented\n"); - return NoFault; + break; case TSDEV_CC_MPR0: case TSDEV_CC_MPR1: case TSDEV_CC_MPR2: case TSDEV_CC_MPR3: panic("TSDEV_CC_MPRx not implemented\n"); - return NoFault; + break; case TSDEV_CC_IPIR: - *(uint64_t*)data = ipint; - return NoFault; + *data64 = ipint; + break; case TSDEV_CC_ITIR: - *(uint64_t*)data = itint; - return NoFault; + *data64 = itint; + break; default: panic("default in cchip read reached, accessing 0x%x\n"); } // uint64_t break; case sizeof(uint32_t): - if (regnum == TSDEV_CC_DRIR) { - warn("accessing DRIR with 32 bit read, " - "hopefully your just reading this for timing"); - *(uint32_t*)data = drir; - } else - panic("invalid access size(?) for tsunami register!\n"); - return NoFault; case sizeof(uint16_t): case sizeof(uint8_t): default: panic("invalid access size(?) for tsunami register!\n"); } - DPRINTFN("Tsunami CChip ERROR: read regnum=%#x size=%d\n", regnum, req->size); + DPRINTF(Tsunami, "Tsunami CChip: read regnum=%#x size=%d data=%lld\n", + regnum, pkt.size, *data64); - return NoFault; + pkt.result = Success; + return pioDelay; } -Fault -TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) +Tick +TsunamiCChip::write(Packet &pkt) { - DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n", - req->vaddr, *(uint64_t*)data, req->size); + pkt.time = curTick + pioDelay; - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); - Addr regnum = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; - bool supportedWrite = false; + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + Addr daddr = pkt.addr - pioAddr; + Addr regnum = (pkt.addr - pioAddr) >> 6 ; - switch (req->size) { - case sizeof(uint64_t): - if (daddr & TSDEV_CC_BDIMS) - { - int number = (daddr >> 4) & 0x3F; - - uint64_t bitvector; - uint64_t olddim; - uint64_t olddir; - - olddim = dim[number]; - olddir = dir[number]; - dim[number] = *(uint64_t*)data; - dir[number] = dim[number] & drir; - for(int x = 0; x < Tsunami::Max_CPUs; x++) - { - bitvector = ULL(1) << x; - // Figure out which bits have changed - if ((dim[number] & bitvector) != (olddim & bitvector)) - { - // The bit is now set and it wasn't before (set) - if((dim[number] & bitvector) && (dir[number] & bitvector)) - { - tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "dim write resulting in posting dir" - " interrupt to cpu %d\n", number); - } - else if ((olddir & bitvector) && - !(dir[number] & bitvector)) - { - // The bit was set and now its now clear and - // we were interrupting on that bit before - tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "dim write resulting in clear" - " dir interrupt to cpu %d\n", number); + uint64_t val = *(uint64_t *)pkt.data; + assert(pkt.size == sizeof(uint64_t)); - } + DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt.addr, val); + bool supportedWrite = false; - } - } - return NoFault; - } - switch(regnum) { - case TSDEV_CC_CSR: - panic("TSDEV_CC_CSR write\n"); - return NoFault; - case TSDEV_CC_MTR: - panic("TSDEV_CC_MTR write not implemented\n"); - return NoFault; - case TSDEV_CC_MISC: - uint64_t ipreq; - ipreq = (*(uint64_t*)data >> 12) & 0xF; - //If it is bit 12-15, this is an IPI post - if (ipreq) { - reqIPI(ipreq); - supportedWrite = true; + if (daddr & TSDEV_CC_BDIMS) + { + int number = (daddr >> 4) & 0x3F; + + uint64_t bitvector; + uint64_t olddim; + uint64_t olddir; + + olddim = dim[number]; + olddir = dir[number]; + dim[number] = val; + dir[number] = dim[number] & drir; + for(int x = 0; x < Tsunami::Max_CPUs; x++) + { + bitvector = ULL(1) << x; + // Figure out which bits have changed + if ((dim[number] & bitvector) != (olddim & bitvector)) + { + // The bit is now set and it wasn't before (set) + if((dim[number] & bitvector) && (dir[number] & bitvector)) + { + tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "dim write resulting in posting dir" + " interrupt to cpu %d\n", number); } + else if ((olddir & bitvector) && + !(dir[number] & bitvector)) + { + // The bit was set and now its now clear and + // we were interrupting on that bit before + tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "dim write resulting in clear" + " dir interrupt to cpu %d\n", number); - //If it is bit 8-11, this is an IPI clear - uint64_t ipintr; - ipintr = (*(uint64_t*)data >> 8) & 0xF; - if (ipintr) { - clearIPI(ipintr); - supportedWrite = true; } - //If it is the 4-7th bit, clear the RTC interrupt - uint64_t itintr; - itintr = (*(uint64_t*)data >> 4) & 0xF; - if (itintr) { - clearITI(itintr); - supportedWrite = true; - } - // ignore NXMs - if (*(uint64_t*)data & 0x10000000) - supportedWrite = true; + } + } + } else { + switch(regnum) { + case TSDEV_CC_CSR: + panic("TSDEV_CC_CSR write\n"); + case TSDEV_CC_MTR: + panic("TSDEV_CC_MTR write not implemented\n"); + case TSDEV_CC_MISC: + uint64_t ipreq; + ipreq = (val >> 12) & 0xF; + //If it is bit 12-15, this is an IPI post + if (ipreq) { + reqIPI(ipreq); + supportedWrite = true; + } - if(!supportedWrite) - panic("TSDEV_CC_MISC write not implemented\n"); + //If it is bit 8-11, this is an IPI clear + uint64_t ipintr; + ipintr = (val >> 8) & 0xF; + if (ipintr) { + clearIPI(ipintr); + supportedWrite = true; + } - return NoFault; - case TSDEV_CC_AAR0: - case TSDEV_CC_AAR1: - case TSDEV_CC_AAR2: - case TSDEV_CC_AAR3: - panic("TSDEV_CC_AARx write not implemeted\n"); - return NoFault; - case TSDEV_CC_DIM0: - case TSDEV_CC_DIM1: - case TSDEV_CC_DIM2: - case TSDEV_CC_DIM3: - int number; - if(regnum == TSDEV_CC_DIM0) - number = 0; - else if(regnum == TSDEV_CC_DIM1) - number = 1; - else if(regnum == TSDEV_CC_DIM2) - number = 2; - else - number = 3; - - uint64_t bitvector; - uint64_t olddim; - uint64_t olddir; - - olddim = dim[number]; - olddir = dir[number]; - dim[number] = *(uint64_t*)data; - dir[number] = dim[number] & drir; - for(int x = 0; x < 64; x++) - { - bitvector = ULL(1) << x; - // Figure out which bits have changed - if ((dim[number] & bitvector) != (olddim & bitvector)) - { - // The bit is now set and it wasn't before (set) - if((dim[number] & bitvector) && (dir[number] & bitvector)) - { - tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); - } - else if ((olddir & bitvector) && - !(dir[number] & bitvector)) - { - // The bit was set and now its now clear and - // we were interrupting on that bit before - tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); - DPRINTF(Tsunami, "dim write resulting in clear" - " dir interrupt to cpu %d\n", - x); - - } - - - } - } - return NoFault; - case TSDEV_CC_DIR0: - case TSDEV_CC_DIR1: - case TSDEV_CC_DIR2: - case TSDEV_CC_DIR3: - panic("TSDEV_CC_DIR write not implemented\n"); - case TSDEV_CC_DRIR: - panic("TSDEV_CC_DRIR write not implemented\n"); - case TSDEV_CC_PRBEN: - panic("TSDEV_CC_PRBEN write not implemented\n"); - case TSDEV_CC_IIC0: - case TSDEV_CC_IIC1: - case TSDEV_CC_IIC2: - case TSDEV_CC_IIC3: - panic("TSDEV_CC_IICx write not implemented\n"); - case TSDEV_CC_MPR0: - case TSDEV_CC_MPR1: - case TSDEV_CC_MPR2: - case TSDEV_CC_MPR3: - panic("TSDEV_CC_MPRx write not implemented\n"); - case TSDEV_CC_IPIR: - clearIPI(*(uint64_t*)data); - return NoFault; - case TSDEV_CC_ITIR: - clearITI(*(uint64_t*)data); - return NoFault; - case TSDEV_CC_IPIQ: - reqIPI(*(uint64_t*)data); - return NoFault; - default: - panic("default in cchip read reached, accessing 0x%x\n"); - } + //If it is the 4-7th bit, clear the RTC interrupt + uint64_t itintr; + itintr = (val >> 4) & 0xF; + if (itintr) { + clearITI(itintr); + supportedWrite = true; + } - break; - case sizeof(uint32_t): - case sizeof(uint16_t): - case sizeof(uint8_t): - default: - panic("invalid access size(?) for tsunami register!\n"); - } + // ignore NXMs + if (val & 0x10000000) + supportedWrite = true; + + if(!supportedWrite) + panic("TSDEV_CC_MISC write not implemented\n"); + + break; + case TSDEV_CC_AAR0: + case TSDEV_CC_AAR1: + case TSDEV_CC_AAR2: + case TSDEV_CC_AAR3: + panic("TSDEV_CC_AARx write not implemeted\n"); + case TSDEV_CC_DIM0: + case TSDEV_CC_DIM1: + case TSDEV_CC_DIM2: + case TSDEV_CC_DIM3: + int number; + if(regnum == TSDEV_CC_DIM0) + number = 0; + else if(regnum == TSDEV_CC_DIM1) + number = 1; + else if(regnum == TSDEV_CC_DIM2) + number = 2; + else + number = 3; + + uint64_t bitvector; + uint64_t olddim; + uint64_t olddir; + + olddim = dim[number]; + olddir = dir[number]; + dim[number] = val; + dir[number] = dim[number] & drir; + for(int x = 0; x < 64; x++) + { + bitvector = ULL(1) << x; + // Figure out which bits have changed + if ((dim[number] & bitvector) != (olddim & bitvector)) + { + // The bit is now set and it wasn't before (set) + if((dim[number] & bitvector) && (dir[number] & bitvector)) + { + tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); + } + else if ((olddir & bitvector) && + !(dir[number] & bitvector)) + { + // The bit was set and now its now clear and + // we were interrupting on that bit before + tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); + DPRINTF(Tsunami, "dim write resulting in clear" + " dir interrupt to cpu %d\n", + x); - DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); + } - return NoFault; + + } + } + break; + case TSDEV_CC_DIR0: + case TSDEV_CC_DIR1: + case TSDEV_CC_DIR2: + case TSDEV_CC_DIR3: + panic("TSDEV_CC_DIR write not implemented\n"); + case TSDEV_CC_DRIR: + panic("TSDEV_CC_DRIR write not implemented\n"); + case TSDEV_CC_PRBEN: + panic("TSDEV_CC_PRBEN write not implemented\n"); + case TSDEV_CC_IIC0: + case TSDEV_CC_IIC1: + case TSDEV_CC_IIC2: + case TSDEV_CC_IIC3: + panic("TSDEV_CC_IICx write not implemented\n"); + case TSDEV_CC_MPR0: + case TSDEV_CC_MPR1: + case TSDEV_CC_MPR2: + case TSDEV_CC_MPR3: + panic("TSDEV_CC_MPRx write not implemented\n"); + case TSDEV_CC_IPIR: + clearIPI(val); + break; + case TSDEV_CC_ITIR: + clearITI(val); + break; + case TSDEV_CC_IPIQ: + reqIPI(val); + break; + default: + panic("default in cchip read reached, accessing 0x%x\n"); + } // swtich(regnum) + } // not BIG_TSUNAMI write + pkt.result = Success; + return pioDelay; } void @@ -472,11 +455,11 @@ TsunamiCChip::postRTC() for (int i = 0; i < size; i++) { uint64_t cpumask = ULL(1) << i; - if (!(cpumask & itint)) { - itint |= cpumask; - tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0); - DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i); - } + if (!(cpumask & itint)) { + itint |= cpumask; + tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0); + DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i); + } } } @@ -491,11 +474,11 @@ TsunamiCChip::postDRIR(uint32_t interrupt) for(int i=0; i < size; i++) { dir[i] = dim[i] & drir; - if (dim[i] & bitvector) { - tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt); - DPRINTF(Tsunami, "posting dir interrupt to cpu %d," + if (dim[i] & bitvector) { + tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt); + DPRINTF(Tsunami, "posting dir interrupt to cpu %d," "interrupt %d\n",i, interrupt); - } + } } } @@ -510,25 +493,19 @@ TsunamiCChip::clearDRIR(uint32_t interrupt) { drir &= ~bitvector; for(int i=0; i < size; i++) { - if (dir[i] & bitvector) { - tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt); - DPRINTF(Tsunami, "clearing dir interrupt to cpu %d," + if (dir[i] & bitvector) { + tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt); + DPRINTF(Tsunami, "clearing dir interrupt to cpu %d," "interrupt %d\n",i, interrupt); - } - dir[i] = dim[i] & drir; + } + dir[i] = dim[i] & drir; } } else DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt); } -Tick -TsunamiCChip::cacheAccess(MemReqPtr &req) -{ - return curTick + pioLatency; -} - void TsunamiCChip::serialize(std::ostream &os) @@ -552,30 +529,34 @@ TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion) BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) - SimObjectParam<Tsunami *> tsunami; - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - SimObjectParam<Bus*> pio_bus; + Param<Addr> pio_addr; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; + SimObjectParam<Platform *> platform; + SimObjectParam<System *> system; + SimObjectParam<Tsunami *> tsunami; END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) - INIT_PARAM(tsunami, "Tsunami"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object"), + INIT_PARAM(tsunami, "Tsunami") END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) CREATE_SIM_OBJECT(TsunamiCChip) { - return new TsunamiCChip(getInstanceName(), tsunami, addr, mmu, hier, - pio_bus, pio_latency); + TsunamiCChip::Params *p = new TsunamiCChip::Params; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + p->tsunami = tsunami; + return new TsunamiCChip(p); } REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip) diff --git a/dev/tsunami_cchip.hh b/dev/tsunami_cchip.hh index d88ad375f..6cd6cf13f 100644 --- a/dev/tsunami_cchip.hh +++ b/dev/tsunami_cchip.hh @@ -37,21 +37,13 @@ #include "base/range.hh" #include "dev/io_device.hh" -class MemoryController; /** * Tsunami CChip CSR Emulation. This device includes all the interrupt * handling code for the chipset. */ -class TsunamiCChip : public PioDevice +class TsunamiCChip : public BasicPioDevice { - private: - /** The base address of this device */ - Addr addr; - - /** The size of mappad from the above address */ - static const Addr size = 0xfffffff; - protected: /** * pointer to the tsunami object. @@ -85,36 +77,24 @@ class TsunamiCChip : public PioDevice uint64_t itint; public: + struct Params : public BasicPioDevice::Params + { + Tsunami *tsunami; + }; + protected: + const Params *params() const {return (const Params *)_params; } + + public: /** * Initialize the Tsunami CChip by setting all of the * device register to 0. - * @param name name of this device. - * @param t pointer back to the Tsunami object that we belong to. - * @param a address we are mapped at. - * @param mmu pointer to the memory controller that sends us events. - * @param hier object to store parameters universal the device hierarchy - * @param bus The bus that this device is attached to + * @param p params struct */ - TsunamiCChip(const std::string &name, Tsunami *t, Addr a, - MemoryController *mmu, HierParams *hier, Bus *pio_bus, - Tick pio_latency); - - /** - * Process a read to the CChip. - * @param req Contains the address to read from. - * @param data A pointer to write the read data to. - * @return The fault condition of the access. - */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + TsunamiCChip(Params *p); + virtual Tick read(Packet &pkt); - /** - * Process a write to the CChip. - * @param req Contains the address to write to. - * @param data The data to write. - * @return The fault condition of the access. - */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick write(Packet &pkt); /** * post an RTC interrupt to the CPU @@ -165,12 +145,6 @@ class TsunamiCChip : public PioDevice */ virtual void unserialize(Checkpoint *cp, const std::string §ion); - /** - * Return how long this access will take. - * @param req the memory request to calcuate - * @return Tick when the request is done - */ - Tick cacheAccess(MemReqPtr &req); }; #endif // __TSUNAMI_CCHIP_HH__ diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index 14fa97341..ebf3492ac 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -36,19 +36,16 @@ #include <string> #include <vector> -#include "arch/alpha/ev5.hh" #include "base/trace.hh" -#include "dev/tsunami_io.hh" -#include "dev/tsunami.hh" #include "dev/pitreg.h" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "sim/builder.hh" +#include "dev/rtcreg.h" #include "dev/tsunami_cchip.hh" +#include "dev/tsunami.hh" +#include "dev/tsunami_io.hh" #include "dev/tsunamireg.h" -#include "dev/rtcreg.h" -#include "mem/functional/memory_control.hh" +#include "mem/port.hh" +#include "sim/builder.hh" +#include "sim/system.hh" using namespace std; //Should this be AlphaISA? @@ -80,38 +77,38 @@ TsunamiIO::RTC::set_time(time_t t) } void -TsunamiIO::RTC::writeAddr(const uint8_t *data) +TsunamiIO::RTC::writeAddr(const uint8_t data) { - if (*data <= RTC_STAT_REGD) - addr = *data; + if (data <= RTC_STAT_REGD) + addr = data; else panic("RTC addresses over 0xD are not implemented.\n"); } void -TsunamiIO::RTC::writeData(const uint8_t *data) +TsunamiIO::RTC::writeData(const uint8_t data) { if (addr < RTC_STAT_REGA) - clock_data[addr] = *data; + clock_data[addr] = data; else { switch (addr) { case RTC_STAT_REGA: - if (*data != (RTCA_32768HZ | RTCA_1024HZ)) + if (data != (RTCA_32768HZ | RTCA_1024HZ)) panic("Unimplemented RTC register A value write!\n"); - stat_regA = *data; + stat_regA = data; break; case RTC_STAT_REGB: - if ((*data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR)) + if ((data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR)) panic("Write to RTC reg B bits that are not implemented!\n"); - if (*data & RTCB_PRDC_IE) { + if (data & RTCB_PRDC_IE) { if (!event.scheduled()) event.scheduleIntr(); } else { if (event.scheduled()) event.deschedule(); } - stat_regB = *data; + stat_regB = data; break; case RTC_STAT_REGC: case RTC_STAT_REGD: @@ -207,24 +204,24 @@ TsunamiIO::PITimer::PITimer(const string &name) } void -TsunamiIO::PITimer::writeControl(const uint8_t *data) +TsunamiIO::PITimer::writeControl(const uint8_t data) { int rw; int sel; - sel = GET_CTRL_SEL(*data); + sel = GET_CTRL_SEL(data); if (sel == PIT_READ_BACK) panic("PITimer Read-Back Command is not implemented.\n"); - rw = GET_CTRL_RW(*data); + rw = GET_CTRL_RW(data); if (rw == PIT_RW_LATCH_COMMAND) counter[sel]->latchCount(); else { counter[sel]->setRW(rw); - counter[sel]->setMode(GET_CTRL_MODE(*data)); - counter[sel]->setBCD(GET_CTRL_BCD(*data)); + counter[sel]->setMode(GET_CTRL_MODE(data)); + counter[sel]->setBCD(GET_CTRL_BCD(data)); } } @@ -296,11 +293,11 @@ TsunamiIO::PITimer::Counter::read(uint8_t *data) } void -TsunamiIO::PITimer::Counter::write(const uint8_t *data) +TsunamiIO::PITimer::Counter::write(const uint8_t data) { switch (write_byte) { case LSB: - count = (count & 0xFF00) | *data; + count = (count & 0xFF00) | data; if (event.scheduled()) event.deschedule(); @@ -309,7 +306,7 @@ TsunamiIO::PITimer::Counter::write(const uint8_t *data) break; case MSB: - count = (count & 0x00FF) | (*data << 8); + count = (count & 0x00FF) | (data << 8); period = count; if (period > 0) { @@ -417,26 +414,17 @@ TsunamiIO::PITimer::Counter::CounterEvent::description() return "tsunami 8254 Interval timer"; } -TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time, - Addr a, MemoryController *mmu, HierParams *hier, - Bus *pio_bus, Tick pio_latency, Tick ci) - : PioDevice(name, t), addr(a), clockInterval(ci), tsunami(t), - pitimer(name + "pitimer"), rtc(name + ".rtc", t, ci) +TsunamiIO::TsunamiIO(Params *p) + : BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"), + rtc(p->name + ".rtc", p->tsunami, p->frequency) { - mmu->add_child(this, RangeSize(addr, size)); - - if (pio_bus) { - pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, - &TsunamiIO::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - pioLatency = pio_latency * pio_bus->clockRate; - } + pioSize = 0xff; // set the back pointer from tsunami to myself tsunami->io = this; timerData = 0; - rtc.set_time(init_time == 0 ? time(NULL) : init_time); + rtc.set_time(p->init_time == 0 ? time(NULL) : p->init_time); picr = 0; picInterrupting = false; } @@ -444,185 +432,175 @@ TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time, Tick TsunamiIO::frequency() const { - return Clock::Frequency / clockInterval; + return Clock::Frequency / params()->frequency; } -Fault -TsunamiIO::read(MemReqPtr &req, uint8_t *data) +Tick +TsunamiIO::read(Packet &pkt) { - DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", - req->vaddr, req->size, req->vaddr & 0xfff); + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + + pkt.time = curTick + pioDelay; + Addr daddr = pkt.addr - pioAddr; + + DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt.addr, + pkt.size, daddr); - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); + uint8_t *data8; + uint64_t *data64; - switch(req->size) { - case sizeof(uint8_t): + if (pkt.size == sizeof(uint8_t)) { + + if (!pkt.data) { + data8 = new uint8_t; + pkt.data = data8; + } else + data8 = pkt.data; switch(daddr) { // PIC1 mask read case TSDEV_PIC1_MASK: - *(uint8_t*)data = ~mask1; - return NoFault; + *data8 = ~mask1; + break; case TSDEV_PIC2_MASK: - *(uint8_t*)data = ~mask2; - return NoFault; + *data8 = ~mask2; + break; case TSDEV_PIC1_ISR: // !!! If this is modified 64bit case needs to be too // Pal code has to do a 64 bit physical read because there is // no load physical byte instruction - *(uint8_t*)data = picr; - return NoFault; + *data8 = picr; + break; case TSDEV_PIC2_ISR: // PIC2 not implemnted... just return 0 - *(uint8_t*)data = 0x00; - return NoFault; + *data8 = 0x00; + break; case TSDEV_TMR0_DATA: - pitimer.counter0.read(data); - return NoFault; + pitimer.counter0.read(data8); + break; case TSDEV_TMR1_DATA: - pitimer.counter1.read(data); - return NoFault; + pitimer.counter1.read(data8); + break; case TSDEV_TMR2_DATA: - pitimer.counter2.read(data); - return NoFault; + pitimer.counter2.read(data8); + break; case TSDEV_RTC_DATA: - rtc.readData(data); - return NoFault; + rtc.readData(data8); + break; case TSDEV_CTRL_PORTB: if (pitimer.counter2.outputHigh()) - *data = PORTB_SPKR_HIGH; + *data8 = PORTB_SPKR_HIGH; else - *data = 0x00; - return NoFault; + *data8 = 0x00; + break; default: - panic("I/O Read - va%#x size %d\n", req->vaddr, req->size); + panic("I/O Read - va%#x size %d\n", pkt.addr, pkt.size); } - case sizeof(uint16_t): - case sizeof(uint32_t): - panic("I/O Read - invalid size - va %#x size %d\n", - req->vaddr, req->size); - - case sizeof(uint64_t): - switch(daddr) { - case TSDEV_PIC1_ISR: - // !!! If this is modified 8bit case needs to be too - // Pal code has to do a 64 bit physical read because there is - // no load physical byte instruction - *(uint64_t*)data = (uint64_t)picr; - return NoFault; - default: - panic("I/O Read - invalid size - va %#x size %d\n", - req->vaddr, req->size); - } - - default: - panic("I/O Read - invalid size - va %#x size %d\n", - req->vaddr, req->size); + } else if (pkt.size == sizeof(uint64_t)) { + if (!pkt.data) { + data64 = new uint64_t; + pkt.data = (uint8_t*)data64; + } else + data64 = (uint64_t*)pkt.data; + + if (daddr == TSDEV_PIC1_ISR) + *data64 = picr; + else + panic("I/O Read - invalid addr - va %#x size %d\n", + pkt.addr, pkt.size); + } else { + panic("I/O Read - invalid size - va %#x size %d\n", pkt.addr, pkt.size); } - panic("I/O Read - va%#x size %d\n", req->vaddr, req->size); - - return NoFault; + pkt.result = Success; + return pioDelay; } -Fault -TsunamiIO::write(MemReqPtr &req, const uint8_t *data) +Tick +TsunamiIO::write(Packet &pkt) { + pkt.time = curTick + pioDelay; + + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + Addr daddr = pkt.addr - pioAddr; + uint8_t val = *pkt.data; #if TRACING_ON - uint8_t dt = *(uint8_t*)data; - uint64_t dt64 = dt; + uint64_t dt64 = val; #endif DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", - req->vaddr, req->size, req->vaddr & 0xfff, dt64); + pkt.addr, pkt.size, pkt.addr & 0xfff, dt64); - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); + assert(pkt.size == sizeof(uint8_t)); - switch(req->size) { - case sizeof(uint8_t): - switch(daddr) { - case TSDEV_PIC1_MASK: - mask1 = ~(*(uint8_t*)data); - if ((picr & mask1) && !picInterrupting) { - picInterrupting = true; - tsunami->cchip->postDRIR(55); - DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); - } - if ((!(picr & mask1)) && picInterrupting) { - picInterrupting = false; - tsunami->cchip->clearDRIR(55); - DPRINTF(Tsunami, "clearing pic interrupt\n"); - } - return NoFault; - case TSDEV_PIC2_MASK: - mask2 = *(uint8_t*)data; - //PIC2 Not implemented to interrupt - return NoFault; - case TSDEV_PIC1_ACK: - // clear the interrupt on the PIC - picr &= ~(1 << (*(uint8_t*)data & 0xF)); - if (!(picr & mask1)) - tsunami->cchip->clearDRIR(55); - return NoFault; - case TSDEV_DMA1_CMND: - return NoFault; - case TSDEV_DMA2_CMND: - return NoFault; - case TSDEV_DMA1_MMASK: - return NoFault; - case TSDEV_DMA2_MMASK: - return NoFault; - case TSDEV_PIC2_ACK: - return NoFault; - case TSDEV_DMA1_RESET: - return NoFault; - case TSDEV_DMA2_RESET: - return NoFault; - case TSDEV_DMA1_MODE: - mode1 = *(uint8_t*)data; - return NoFault; - case TSDEV_DMA2_MODE: - mode2 = *(uint8_t*)data; - return NoFault; - case TSDEV_DMA1_MASK: - case TSDEV_DMA2_MASK: - return NoFault; - case TSDEV_TMR0_DATA: - pitimer.counter0.write(data); - return NoFault; - case TSDEV_TMR1_DATA: - pitimer.counter1.write(data); - return NoFault; - case TSDEV_TMR2_DATA: - pitimer.counter2.write(data); - return NoFault; - case TSDEV_TMR_CTRL: - pitimer.writeControl(data); - return NoFault; - case TSDEV_RTC_ADDR: - rtc.writeAddr(data); - return NoFault; - case TSDEV_KBD: - return NoFault; - case TSDEV_RTC_DATA: - rtc.writeData(data); - return NoFault; - case TSDEV_CTRL_PORTB: - // System Control Port B not implemented - return NoFault; - default: - panic("I/O Write - va%#x size %d data %#x\n", req->vaddr, req->size, (int)*data); + switch(daddr) { + case TSDEV_PIC1_MASK: + mask1 = ~(val); + if ((picr & mask1) && !picInterrupting) { + picInterrupting = true; + tsunami->cchip->postDRIR(55); + DPRINTF(Tsunami, "posting pic interrupt to cchip\n"); } - case sizeof(uint16_t): - case sizeof(uint32_t): - case sizeof(uint64_t): + if ((!(picr & mask1)) && picInterrupting) { + picInterrupting = false; + tsunami->cchip->clearDRIR(55); + DPRINTF(Tsunami, "clearing pic interrupt\n"); + } + break; + case TSDEV_PIC2_MASK: + mask2 = val; + //PIC2 Not implemented to interrupt + break; + case TSDEV_PIC1_ACK: + // clear the interrupt on the PIC + picr &= ~(1 << (val & 0xF)); + if (!(picr & mask1)) + tsunami->cchip->clearDRIR(55); + break; + case TSDEV_DMA1_MODE: + mode1 = val; + break; + case TSDEV_DMA2_MODE: + mode2 = val; + break; + case TSDEV_TMR0_DATA: + pitimer.counter0.write(val); + break; + case TSDEV_TMR1_DATA: + pitimer.counter1.write(val); + break; + case TSDEV_TMR2_DATA: + pitimer.counter2.write(val); + break; + case TSDEV_TMR_CTRL: + pitimer.writeControl(val); + break; + case TSDEV_RTC_ADDR: + rtc.writeAddr(val); + break; + case TSDEV_RTC_DATA: + rtc.writeData(val); + break; + case TSDEV_KBD: + case TSDEV_DMA1_CMND: + case TSDEV_DMA2_CMND: + case TSDEV_DMA1_MMASK: + case TSDEV_DMA2_MMASK: + case TSDEV_PIC2_ACK: + case TSDEV_DMA1_RESET: + case TSDEV_DMA2_RESET: + case TSDEV_DMA1_MASK: + case TSDEV_DMA2_MASK: + case TSDEV_CTRL_PORTB: + break; default: - panic("I/O Write - invalid size - va %#x size %d\n", - req->vaddr, req->size); + panic("I/O Write - va%#x size %d data %#x\n", pkt.addr, pkt.size, val); } - - return NoFault; + pkt.result = Success; + return pioDelay; } void @@ -647,12 +625,6 @@ TsunamiIO::clearPIC(uint8_t bitvector) } } -Tick -TsunamiIO::cacheAccess(MemReqPtr &req) -{ - return curTick + pioLatency; -} - void TsunamiIO::serialize(ostream &os) { @@ -687,34 +659,40 @@ TsunamiIO::unserialize(Checkpoint *cp, const string §ion) BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) - SimObjectParam<Tsunami *> tsunami; - Param<time_t> time; - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - SimObjectParam<Bus*> pio_bus; + Param<Addr> pio_addr; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; Param<Tick> frequency; + SimObjectParam<Platform *> platform; + SimObjectParam<System *> system; + Param<time_t> time; + SimObjectParam<Tsunami *> tsunami; END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO) - INIT_PARAM(tsunami, "Tsunami"), + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(frequency, "clock interrupt frequency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object"), INIT_PARAM(time, "System time to use (0 for actual time"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM(pio_bus, "The IO Bus to attach to"), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams), - INIT_PARAM(frequency, "clock interrupt frequency") + INIT_PARAM(tsunami, "Tsunami") END_INIT_SIM_OBJECT_PARAMS(TsunamiIO) CREATE_SIM_OBJECT(TsunamiIO) { - return new TsunamiIO(getInstanceName(), tsunami, time, addr, mmu, hier, - pio_bus, pio_latency, frequency); + TsunamiIO::Params *p = new TsunamiIO::Params; + p->frequency = frequency; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + p->init_time = time; + p->tsunami = tsunami; + return new TsunamiIO(p); } REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO) diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh index b024ecd14..c37f3aa16 100644 --- a/dev/tsunami_io.hh +++ b/dev/tsunami_io.hh @@ -38,21 +38,13 @@ #include "dev/tsunami.hh" #include "sim/eventq.hh" -class MemoryController; - /** * Tsunami I/O device is a catch all for all the south bridge stuff we care * to implement. */ -class TsunamiIO : public PioDevice +class TsunamiIO : public BasicPioDevice { private: - /** The base address of this device */ - Addr addr; - - /** The size of mappad from the above address */ - static const Addr size = 0xff; - struct tm tm; protected: @@ -120,10 +112,10 @@ class TsunamiIO : public PioDevice void set_time(time_t t); /** RTC address port: write address of RTC RAM data to access */ - void writeAddr(const uint8_t *data); + void writeAddr(const uint8_t data); /** RTC write data */ - void writeData(const uint8_t *data); + void writeData(const uint8_t data); /** RTC read data */ void readData(uint8_t *data); @@ -218,7 +210,7 @@ class TsunamiIO : public PioDevice void read(uint8_t *data); /** Write a count byte */ - void write(const uint8_t *data); + void write(const uint8_t data); /** Is the output high? */ bool outputHigh(); @@ -254,7 +246,7 @@ class TsunamiIO : public PioDevice PITimer(const std::string &name); /** Write control word */ - void writeControl(const uint8_t* data); + void writeControl(const uint8_t data); /** * Serialize this object to the given output stream. @@ -289,8 +281,6 @@ class TsunamiIO : public PioDevice /** Is the pic interrupting right now or not. */ bool picInterrupting; - Tick clockInterval; - /** A pointer to the Tsunami device which be belong to */ Tsunami *tsunami; @@ -312,33 +302,24 @@ class TsunamiIO : public PioDevice */ Tick frequency() const; + struct Params : public BasicPioDevice::Params + { + Tick frequency; + Tsunami *tsunami; + time_t init_time; + }; + protected: + const Params *params() const { return (const Params*)_params; } + + public: /** * Initialize all the data for devices supported by Tsunami I/O. - * @param name name of this device. - * @param t pointer back to the Tsunami object that we belong to. - * @param init_time Time (as in seconds since 1970) to set RTC to. - * @param a address we are mapped at. - * @param mmu pointer to the memory controller that sends us events. + * @param p pointer to Params struct */ - TsunamiIO(const std::string &name, Tsunami *t, time_t init_time, - Addr a, MemoryController *mmu, HierParams *hier, Bus *pio_bus, - Tick pio_latency, Tick ci); + TsunamiIO(Params *p); - /** - * Process a read to one of the devices we are emulating. - * @param req Contains the address to read from. - * @param data A pointer to write the read data to. - * @return The fault condition of the access. - */ - virtual Fault read(MemReqPtr &req, uint8_t *data); - - /** - * Process a write to one of the devices we emulate. - * @param req Contains the address to write to. - * @param data The data to write. - * @return The fault condition of the access. - */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick read(Packet &pkt); + virtual Tick write(Packet &pkt); /** * Post an PIC interrupt to the CPU via the CChip @@ -365,7 +346,6 @@ class TsunamiIO : public PioDevice */ virtual void unserialize(Checkpoint *cp, const std::string §ion); - Tick cacheAccess(MemReqPtr &req); }; #endif // __DEV_TSUNAMI_IO_HH__ diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc index 202076754..66144b816 100644 --- a/dev/tsunami_pchip.cc +++ b/dev/tsunami_pchip.cc @@ -34,16 +34,11 @@ #include <string> #include <vector> -#include "arch/alpha/ev5.hh" #include "base/trace.hh" #include "dev/tsunami_pchip.hh" #include "dev/tsunamireg.h" #include "dev/tsunami.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" +#include "mem/packet.hh" #include "sim/builder.hh" #include "sim/system.hh" @@ -51,12 +46,10 @@ using namespace std; //Should this be AlphaISA? using namespace TheISA; -TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, - MemoryController *mmu, HierParams *hier, - Bus *pio_bus, Tick pio_latency) - : PioDevice(name, t), addr(a), tsunami(t) +TsunamiPChip::TsunamiPChip(Params *p) +: BasicPioDevice(p) { - mmu->add_child(this, RangeSize(addr, size)); + pioSize = 0xfff; for (int i = 0; i < 4; i++) { wsba[i] = 0; @@ -64,195 +57,180 @@ TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, tba[i] = 0; } - if (pio_bus) { - pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, - &TsunamiPChip::cacheAccess); - pioInterface->addAddrRange(RangeSize(addr, size)); - pioLatency = pio_latency * pio_bus->clockRate; - } - - // initialize pchip control register pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36); //Set back pointer in tsunami - tsunami->pchip = this; + p->tsunami->pchip = this; } -Fault -TsunamiPChip::read(MemReqPtr &req, uint8_t *data) +Tick +TsunamiPChip::read(Packet &pkt) { - DPRINTF(Tsunami, "read va=%#x size=%d\n", - req->vaddr, req->size); - - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; - - switch (req->size) { - - case sizeof(uint64_t): - switch(daddr) { - case TSDEV_PC_WSBA0: - *(uint64_t*)data = wsba[0]; - return NoFault; - case TSDEV_PC_WSBA1: - *(uint64_t*)data = wsba[1]; - return NoFault; - case TSDEV_PC_WSBA2: - *(uint64_t*)data = wsba[2]; - return NoFault; - case TSDEV_PC_WSBA3: - *(uint64_t*)data = wsba[3]; - return NoFault; - case TSDEV_PC_WSM0: - *(uint64_t*)data = wsm[0]; - return NoFault; - case TSDEV_PC_WSM1: - *(uint64_t*)data = wsm[1]; - return NoFault; - case TSDEV_PC_WSM2: - *(uint64_t*)data = wsm[2]; - return NoFault; - case TSDEV_PC_WSM3: - *(uint64_t*)data = wsm[3]; - return NoFault; - case TSDEV_PC_TBA0: - *(uint64_t*)data = tba[0]; - return NoFault; - case TSDEV_PC_TBA1: - *(uint64_t*)data = tba[1]; - return NoFault; - case TSDEV_PC_TBA2: - *(uint64_t*)data = tba[2]; - return NoFault; - case TSDEV_PC_TBA3: - *(uint64_t*)data = tba[3]; - return NoFault; - case TSDEV_PC_PCTL: - *(uint64_t*)data = pctl; - return NoFault; - case TSDEV_PC_PLAT: - panic("PC_PLAT not implemented\n"); - case TSDEV_PC_RES: - panic("PC_RES not implemented\n"); - case TSDEV_PC_PERROR: - *(uint64_t*)data = 0x00; - return NoFault; - case TSDEV_PC_PERRMASK: - *(uint64_t*)data = 0x00; - return NoFault; - case TSDEV_PC_PERRSET: - panic("PC_PERRSET not implemented\n"); - case TSDEV_PC_TLBIV: - panic("PC_TLBIV not implemented\n"); - case TSDEV_PC_TLBIA: - *(uint64_t*)data = 0x00; // shouldn't be readable, but linux - return NoFault; - case TSDEV_PC_PMONCTL: - panic("PC_PMONCTL not implemented\n"); - case TSDEV_PC_PMONCNT: - panic("PC_PMONCTN not implemented\n"); - default: - panic("Default in PChip Read reached reading 0x%x\n", daddr); - - } // uint64_t - - break; - case sizeof(uint32_t): - case sizeof(uint16_t): - case sizeof(uint8_t): + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + + pkt.time = curTick + pioDelay; + Addr daddr = (pkt.addr - pioAddr) >> 6;; + + uint64_t *data64; + + if (!pkt.data) { + data64 = new uint64_t; + pkt.data = (uint8_t*)data64; + } else + data64 = (uint64_t*)pkt.data; + + DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size); + + switch(daddr) { + case TSDEV_PC_WSBA0: + *data64 = wsba[0]; + break; + case TSDEV_PC_WSBA1: + *data64 = wsba[1]; + break; + case TSDEV_PC_WSBA2: + *data64 = wsba[2]; + break; + case TSDEV_PC_WSBA3: + *data64 = wsba[3]; + break; + case TSDEV_PC_WSM0: + *data64 = wsm[0]; + break; + case TSDEV_PC_WSM1: + *data64 = wsm[1]; + break; + case TSDEV_PC_WSM2: + *data64 = wsm[2]; + break; + case TSDEV_PC_WSM3: + *data64 = wsm[3]; + break; + case TSDEV_PC_TBA0: + *data64 = tba[0]; + break; + case TSDEV_PC_TBA1: + *data64 = tba[1]; + break; + case TSDEV_PC_TBA2: + *data64 = tba[2]; + break; + case TSDEV_PC_TBA3: + *data64 = tba[3]; + break; + case TSDEV_PC_PCTL: + *data64 = pctl; + break; + case TSDEV_PC_PLAT: + panic("PC_PLAT not implemented\n"); + case TSDEV_PC_RES: + panic("PC_RES not implemented\n"); + case TSDEV_PC_PERROR: + *data64 = 0x00; + break; + case TSDEV_PC_PERRMASK: + *data64 = 0x00; + break; + case TSDEV_PC_PERRSET: + panic("PC_PERRSET not implemented\n"); + case TSDEV_PC_TLBIV: + panic("PC_TLBIV not implemented\n"); + case TSDEV_PC_TLBIA: + *data64 = 0x00; // shouldn't be readable, but linux + break; + case TSDEV_PC_PMONCTL: + panic("PC_PMONCTL not implemented\n"); + case TSDEV_PC_PMONCNT: + panic("PC_PMONCTN not implemented\n"); default: - panic("invalid access size(?) for tsunami register!\n\n"); + panic("Default in PChip Read reached reading 0x%x\n", daddr); } - DPRINTFN("Tsunami PChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); + pkt.result = Success; + return pioDelay; - return NoFault; } -Fault -TsunamiPChip::write(MemReqPtr &req, const uint8_t *data) +Tick +TsunamiPChip::write(Packet &pkt) { - DPRINTF(Tsunami, "write - va=%#x size=%d \n", - req->vaddr, req->size); - - Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; - - switch (req->size) { - - case sizeof(uint64_t): - switch(daddr) { - case TSDEV_PC_WSBA0: - wsba[0] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSBA1: - wsba[1] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSBA2: - wsba[2] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSBA3: - wsba[3] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSM0: - wsm[0] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSM1: - wsm[1] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSM2: - wsm[2] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_WSM3: - wsm[3] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_TBA0: - tba[0] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_TBA1: - tba[1] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_TBA2: - tba[2] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_TBA3: - tba[3] = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_PCTL: - pctl = *(uint64_t*)data; - return NoFault; - case TSDEV_PC_PLAT: - panic("PC_PLAT not implemented\n"); - case TSDEV_PC_RES: - panic("PC_RES not implemented\n"); - case TSDEV_PC_PERROR: - return NoFault; - case TSDEV_PC_PERRMASK: - panic("PC_PERRMASK not implemented\n"); - case TSDEV_PC_PERRSET: - panic("PC_PERRSET not implemented\n"); - case TSDEV_PC_TLBIV: - panic("PC_TLBIV not implemented\n"); - case TSDEV_PC_TLBIA: - return NoFault; // value ignored, supposted to invalidate SG TLB - case TSDEV_PC_PMONCTL: - panic("PC_PMONCTL not implemented\n"); - case TSDEV_PC_PMONCNT: - panic("PC_PMONCTN not implemented\n"); - default: - panic("Default in PChip Read reached reading 0x%x\n", daddr); - - } // uint64_t - - break; - case sizeof(uint32_t): - case sizeof(uint16_t): - case sizeof(uint8_t): - default: - panic("invalid access size(?) for tsunami register!\n\n"); - } - - DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); - - return NoFault; + pkt.time = curTick + pioDelay; + + assert(pkt.result == Unknown); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + Addr daddr = (pkt.addr - pioAddr) >> 6; + + uint64_t data64 = *(uint64_t *)pkt.data; + assert(pkt.size == sizeof(uint64_t)); + + DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt.addr, pkt.size); + + switch(daddr) { + case TSDEV_PC_WSBA0: + wsba[0] = data64; + break; + case TSDEV_PC_WSBA1: + wsba[1] = data64; + break; + case TSDEV_PC_WSBA2: + wsba[2] = data64; + break; + case TSDEV_PC_WSBA3: + wsba[3] = data64; + break; + case TSDEV_PC_WSM0: + wsm[0] = data64; + break; + case TSDEV_PC_WSM1: + wsm[1] = data64; + break; + case TSDEV_PC_WSM2: + wsm[2] = data64; + break; + case TSDEV_PC_WSM3: + wsm[3] = data64; + break; + case TSDEV_PC_TBA0: + tba[0] = data64; + break; + case TSDEV_PC_TBA1: + tba[1] = data64; + break; + case TSDEV_PC_TBA2: + tba[2] = data64; + break; + case TSDEV_PC_TBA3: + tba[3] = data64; + break; + case TSDEV_PC_PCTL: + pctl = data64; + break; + case TSDEV_PC_PLAT: + panic("PC_PLAT not implemented\n"); + case TSDEV_PC_RES: + panic("PC_RES not implemented\n"); + case TSDEV_PC_PERROR: + break; + case TSDEV_PC_PERRMASK: + panic("PC_PERRMASK not implemented\n"); + case TSDEV_PC_PERRSET: + panic("PC_PERRSET not implemented\n"); + case TSDEV_PC_TLBIV: + panic("PC_TLBIV not implemented\n"); + case TSDEV_PC_TLBIA: + break; // value ignored, supposted to invalidate SG TLB + case TSDEV_PC_PMONCTL: + panic("PC_PMONCTL not implemented\n"); + case TSDEV_PC_PMONCNT: + panic("PC_PMONCTN not implemented\n"); + default: + panic("Default in PChip write reached reading 0x%x\n", daddr); + + } // uint64_t + + pkt.result = Success; + return pioDelay; } #define DMA_ADDR_MASK ULL(0x3ffffffff) @@ -312,10 +290,7 @@ TsunamiPChip::translatePciToDma(Addr busAddr) baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13); pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10); - memcpy((void *)&pteEntry, - tsunami->system-> - physmem->dma_addr(pteAddr, sizeof(uint64_t)), - sizeof(uint64_t)); + pioPort->readBlob(pteAddr, (uint8_t*)&pteEntry, sizeof(uint64_t)); dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff)); @@ -352,38 +327,37 @@ TsunamiPChip::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_ARRAY(tba, 4); } -Tick -TsunamiPChip::cacheAccess(MemReqPtr &req) -{ - return curTick + pioLatency; -} BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) - SimObjectParam<Tsunami *> tsunami; - SimObjectParam<MemoryController *> mmu; - Param<Addr> addr; - SimObjectParam<Bus*> pio_bus; + Param<Addr> pio_addr; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; + SimObjectParam<Platform *> platform; + SimObjectParam<System *> system; + SimObjectParam<Tsunami *> tsunami; END_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip) BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) - INIT_PARAM(tsunami, "Tsunami"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) + INIT_PARAM(pio_addr, "Device Address"), + INIT_PARAM(pio_latency, "Programmed IO latency"), + INIT_PARAM(platform, "platform"), + INIT_PARAM(system, "system object"), + INIT_PARAM(tsunami, "Tsunami") END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip) CREATE_SIM_OBJECT(TsunamiPChip) { - return new TsunamiPChip(getInstanceName(), tsunami, addr, mmu, hier, - pio_bus, pio_latency); + TsunamiPChip::Params *p = new TsunamiPChip::Params; + p->name = getInstanceName(); + p->pio_addr = pio_addr; + p->pio_delay = pio_latency; + p->platform = platform; + p->system = system; + p->tsunami = tsunami; + return new TsunamiPChip(p); } REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip) diff --git a/dev/tsunami_pchip.hh b/dev/tsunami_pchip.hh index c1d95431b..2f3e8f078 100644 --- a/dev/tsunami_pchip.hh +++ b/dev/tsunami_pchip.hh @@ -37,28 +37,12 @@ #include "base/range.hh" #include "dev/io_device.hh" -class MemoryController; - /** * A very simple implementation of the Tsunami PCI interface chips. */ -class TsunamiPChip : public PioDevice +class TsunamiPChip : public BasicPioDevice { - private: - /** The base address of this device */ - Addr addr; - - /** The size of mappad from the above address */ - static const Addr size = 0xfff; - protected: - /** - * pointer to the tsunami object. - * This is our access to all the other tsunami - * devices. - */ - Tsunami *tsunami; - /** Pchip control register */ uint64_t pctl; @@ -72,18 +56,19 @@ class TsunamiPChip : public PioDevice uint64_t tba[4]; public: + struct Params : public BasicPioDevice::Params + { + Tsunami *tsunami; + }; + protected: + const Params *params() const { return (const Params*)_params; } + + public: /** * Register the PChip with the mmu and init all wsba, wsm, and tba to 0 - * @param name the name of thes device - * @param t a pointer to the tsunami device - * @param a the address which we respond to - * @param mmu the mmu we are to register with - * @param hier object to store parameters universal the device hierarchy - * @param bus The bus that this device is attached to + * @param p pointer to the parameters struct */ - TsunamiPChip(const std::string &name, Tsunami *t, Addr a, - MemoryController *mmu, HierParams *hier, Bus *pio_bus, - Tick pio_latency); + TsunamiPChip(Params *p); /** * Translate a PCI bus address to a memory address for DMA. @@ -93,21 +78,8 @@ class TsunamiPChip : public PioDevice */ Addr translatePciToDma(Addr busAddr); - /** - * Process a read to the PChip. - * @param req Contains the address to read from. - * @param data A pointer to write the read data to. - * @return The fault condition of the access. - */ - virtual Fault read(MemReqPtr &req, uint8_t *data); - - /** - * Process a write to the PChip. - * @param req Contains the address to write to. - * @param data The data to write. - * @return The fault condition of the access. - */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick read(Packet &pkt); + virtual Tick write(Packet &pkt); /** * Serialize this object to the given output stream. @@ -121,13 +93,6 @@ class TsunamiPChip : public PioDevice * @param section The section name of this object */ virtual void unserialize(Checkpoint *cp, const std::string §ion); - - /** - * Return how long this access will take. - * @param req the memory request to calcuate - * @return Tick when the request is done - */ - Tick cacheAccess(MemReqPtr &req); }; #endif // __TSUNAMI_PCHIP_HH__ diff --git a/dev/uart8250.cc b/dev/uart8250.cc index bbb42c065..7e2f9d51f 100644 --- a/dev/uart8250.cc +++ b/dev/uart8250.cc @@ -111,7 +111,7 @@ Tick Uart8250::read(Packet &pkt) { assert(pkt.result == Unknown); - assert(pkt.addr > pioAddr && pkt.addr < pioAddr + pioSize); + assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); assert(pkt.size == 1); pkt.time = curTick + pioDelay; @@ -189,7 +189,10 @@ Uart8250::read(Packet &pkt) panic("Tried to access a UART port that doesn't exist\n"); break; } - +/* uint32_t d32 = *data; + DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32); +*/ + pkt.result = Success; return pioDelay; } @@ -269,6 +272,7 @@ Uart8250::write(Packet &pkt) panic("Tried to access a UART port that doesn't exist\n"); break; } + pkt.result = Success; return pioDelay; } @@ -336,7 +340,7 @@ Uart8250::unserialize(Checkpoint *cp, const std::string §ion) BEGIN_DECLARE_SIM_OBJECT_PARAMS(Uart8250) - Param<Addr> addr; + Param<Addr> pio_addr; Param<Tick> pio_latency; SimObjectParam<Platform *> platform; SimObjectParam<SimConsole *> sim_console; @@ -346,7 +350,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(Uart8250) BEGIN_INIT_SIM_OBJECT_PARAMS(Uart8250) - INIT_PARAM(addr, "Device Address"), + INIT_PARAM(pio_addr, "Device Address"), INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000), INIT_PARAM(platform, "platform"), INIT_PARAM(sim_console, "The Simulator Console"), @@ -358,7 +362,7 @@ CREATE_SIM_OBJECT(Uart8250) { Uart8250::Params *p = new Uart8250::Params; p->name = getInstanceName(); - p->pio_addr = addr; + p->pio_addr = pio_addr; p->pio_delay = pio_latency; p->platform = platform; p->cons = sim_console; diff --git a/kern/linux/linux.hh b/kern/linux/linux.hh index 9237084fc..63e0dd5ca 100644 --- a/kern/linux/linux.hh +++ b/kern/linux/linux.hh @@ -44,6 +44,7 @@ class Linux {}; #include <sys/types.h> #include <unistd.h> +#include "arch/isa_traits.hh" #include "sim/syscall_emul.hh" class TranslatingPort; @@ -74,33 +75,6 @@ class Linux { typedef struct stat64 hst_stat64; #endif - - //@{ - /// open(2) flag values. - static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY - static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY - static const int TGT_O_RDWR = 00000002; //!< O_RDWR - static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK - static const int TGT_O_APPEND = 00000010; //!< O_APPEND - static const int TGT_O_CREAT = 00001000; //!< O_CREAT - static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC - static const int TGT_O_EXCL = 00004000; //!< O_EXCL - static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY - static const int TGT_O_SYNC = 00040000; //!< O_SYNC - static const int TGT_O_DRD = 00100000; //!< O_DRD - static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO - static const int TGT_O_CACHE = 00400000; //!< O_CACHE - static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC - static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC - //@} - - /// 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; - /// Stat buffer. Note that we can't call it 'stat' since that /// gets #defined to something else on some systems. struct tgt_stat { @@ -158,46 +132,12 @@ class Linux { char machine[_SYS_NMLN]; //!< Machine type. }; - - //@{ - /// ioctl() command codes. - static const unsigned TIOCGETP = 0x40067408; - static const unsigned TIOCSETP = 0x80067409; - static const unsigned TIOCSETN = 0x8006740a; - static const unsigned TIOCSETC = 0x80067411; - static const unsigned TIOCGETC = 0x40067412; - static const unsigned FIONREAD = 0x4004667f; - static const unsigned TIOCISATTY = 0x2000745e; - static const unsigned TIOCGETS = 0x402c7413; - static const unsigned TIOCGETA = 0x40127417; - //@} - - /// 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_NOFILE = 6, - TGT_RLIMIT_AS = 7, - TGT_RLIMIT_VMEM = 7, - TGT_RLIMIT_NPROC = 8, - TGT_RLIMIT_MEMLOCK = 9, - TGT_RLIMIT_LOCKS = 10 - }; - /// Limit struct for getrlimit/setrlimit. struct rlimit { uint64_t rlim_cur; //!< soft limit uint64_t rlim_max; //!< hard limit }; - - /// For mmap(). - static const unsigned TGT_MAP_ANONYMOUS = 0x10; - /// For gettimeofday(). struct timeval { int64_t tv_sec; //!< seconds @@ -210,12 +150,6 @@ class Linux { uint64_t iov_len; }; - //@{ - /// For getrusage(). - static const int TGT_RUSAGE_SELF = 0; - static const int TGT_RUSAGE_CHILDREN = -1; - static const int TGT_RUSAGE_BOTH = -2; - //@} /// For getrusage(). struct rusage { diff --git a/kern/tru64/tru64.hh b/kern/tru64/tru64.hh index b4f45e650..91db5bb84 100644 --- a/kern/tru64/tru64.hh +++ b/kern/tru64/tru64.hh @@ -85,32 +85,6 @@ class Tru64 { typedef quad fsid_t; //@} - //@{ - /// open(2) flag values. - static const int TGT_O_RDONLY = 00000000; - static const int TGT_O_WRONLY = 00000001; - static const int TGT_O_RDWR = 00000002; - static const int TGT_O_NONBLOCK = 00000004; - static const int TGT_O_APPEND = 00000010; - static const int TGT_O_CREAT = 00001000; - static const int TGT_O_TRUNC = 00002000; - static const int TGT_O_EXCL = 00004000; - static const int TGT_O_NOCTTY = 00010000; - static const int TGT_O_SYNC = 00040000; - static const int TGT_O_DRD = 00100000; - static const int TGT_O_DIRECTIO = 00200000; - static const int TGT_O_CACHE = 00400000; - static const int TGT_O_DSYNC = 02000000; - static const int TGT_O_RSYNC = 04000000; - //@} - - /// 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; - /// Stat buffer. Note that Tru64 v5.0+ use a new "F64" stat /// structure, and a new set of syscall numbers for stat calls. /// On some hosts (notably Linux) define st_atime, st_mtime, and @@ -246,33 +220,6 @@ class Tru64 { char machine[_SYS_NMLN]; //!< Machine type. }; - //@{ - /// ioctl() command codes. - static const unsigned TIOCGETP = 0x40067408; - static const unsigned TIOCSETP = 0x80067409; - static const unsigned TIOCSETN = 0x8006740a; - static const unsigned TIOCSETC = 0x80067411; - static const unsigned TIOCGETC = 0x40067412; - static const unsigned FIONREAD = 0x4004667f; - static const unsigned TIOCISATTY = 0x2000745e; - // TIOCGETS not defined in tru64, so I made up a number - static const unsigned TIOCGETS = 0x40000000; - static const unsigned TIOCGETA = 0x402c7413; - //@} - - /// 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_NOFILE = 6, - TGT_RLIMIT_AS = 7, - TGT_RLIMIT_VMEM = 7 - }; - /// Limit struct for getrlimit/setrlimit. struct rlimit { uint64_t rlim_cur; //!< soft limit @@ -280,21 +227,6 @@ class Tru64 { }; - /// For mmap(). - static const unsigned TGT_MAP_ANONYMOUS = 0x10; - - - //@{ - /// For getsysinfo(). - static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string - static const unsigned GSI_CPU_INFO = 59; //!< CPU information - static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type - static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine - static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system - static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB - static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz - //@} - /// For getsysinfo() GSI_CPU_INFO option. struct cpu_info { uint32_t current_cpu; //!< current_cpu @@ -309,24 +241,12 @@ class Tru64 { uint32_t unused[3]; //!< future expansion }; - //@{ - /// For setsysinfo(). - static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control() - //@} - /// For gettimeofday. struct timeval { uint32_t tv_sec; //!< seconds uint32_t tv_usec; //!< microseconds }; - //@{ - /// For getrusage(). - static const int TGT_RUSAGE_THREAD = 1; - static const int TGT_RUSAGE_SELF = 0; - static const int TGT_RUSAGE_CHILDREN = -1; - //@} - /// For getrusage(). struct rusage { struct timeval ru_utime; //!< user time used @@ -372,8 +292,6 @@ class Tru64 { }; - /// For table(). - static const int TBL_SYSINFO = 12; /// For table(). struct tbl_sysinfo { @@ -744,45 +662,6 @@ class Tru64 { return 0; } - /// Target table() handler. - static SyscallReturn - tableFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - using namespace std; - using namespace TheISA; - - int id = xc->getSyscallArg(0); // table ID - int index = xc->getSyscallArg(1); // index into table - // arg 2 is buffer pointer; type depends on table ID - int nel = xc->getSyscallArg(3); // number of elements - int lel = xc->getSyscallArg(4); // expected element size - - switch (id) { - case Tru64::TBL_SYSINFO: { - if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo)) - return -EINVAL; - TypedBufferArg<Tru64::tbl_sysinfo> elp(xc->getSyscallArg(2)); - - const int clk_hz = one_million; - elp->si_user = htog(curTick / (Clock::Frequency / clk_hz)); - elp->si_nice = htog(0); - elp->si_sys = htog(0); - elp->si_idle = htog(0); - elp->wait = htog(0); - elp->si_hz = htog(clk_hz); - elp->si_phz = htog(clk_hz); - elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch? - elp->si_max_procs = htog(process->numCpus()); - elp.copyOut(xc->getMemPort()); - return 0; - } - - default: - cerr << "table(): id " << id << " unknown." << endl; - return -EINVAL; - } - } // // Mach syscalls -- identified by negated syscall numbers diff --git a/mem/bus.cc b/mem/bus.cc index 0cadc2045..5e84beb83 100644 --- a/mem/bus.cc +++ b/mem/bus.cc @@ -31,7 +31,8 @@ */ -#include "bus.hh" +#include "base/trace.hh" +#include "mem/bus.hh" #include "sim/builder.hh" /** Function called by the port when the bus is recieving a Timing @@ -56,9 +57,13 @@ Bus::findPort(Addr addr, int id) if (portList[i].range == addr) { dest_id = portList[i].portId; found = true; + DPRINTF(Bus, "Found Addr: %llx on device %d\n", addr, dest_id); } + i++; } - assert(dest_id != -1 && "Unable to find destination"); + if (dest_id == -1) + panic("Unable to find destination for addr: %llx", addr); + // we shouldn't be sending this back to where it came from assert(dest_id != id); @@ -85,8 +90,10 @@ Bus::recvFunctional(Packet &pkt, int id) void Bus::recvStatusChange(Port::Status status, int id) { - assert(status == Port:: RangeChange && + assert(status == Port::RangeChange && "The other statuses need to be implemented."); + + assert(id < interfaces.size() && id >= 0); Port *port = interfaces[id]; AddrRangeList ranges; AddrRangeList snoops; @@ -97,11 +104,15 @@ Bus::recvStatusChange(Port::Status status, int id) assert(snoops.size() == 0); // or multiple ranges assert(ranges.size() == 1); + DevMap dm; dm.portId = id; dm.range = ranges.front(); + DPRINTF(MMU, "Adding range %llx - %llx for id %d\n", dm.range.start, + dm.range.end, id); portList.push_back(dm); + DPRINTF(MMU, "port list has %d entries\n", portList.size()); } void diff --git a/mem/bus.hh b/mem/bus.hh index eff42c55a..fad44aba5 100644 --- a/mem/bus.hh +++ b/mem/bus.hh @@ -127,12 +127,9 @@ class Bus : public MemObject }; - /** A count of the number of interfaces connected to this bus. */ - int num_interfaces; - /** An array of pointers to the peer port interfaces connected to this bus.*/ - Port *interfaces[]; + std::vector<Port*> interfaces; public: @@ -140,12 +137,12 @@ class Bus : public MemObject virtual Port *getPort(const std::string &if_name) { // if_name ignored? forced to be empty? - int id = num_interfaces++; - interfaces[id] = new BusPort(this, id); - return interfaces[id]; + int id = interfaces.size(); + interfaces.push_back(new BusPort(this, id)); + return interfaces.back(); } Bus(const std::string &n) - : MemObject(n), num_interfaces(0) {} + : MemObject(n) {} }; diff --git a/mem/packet.hh b/mem/packet.hh index 91e56385d..843d34ac0 100644 --- a/mem/packet.hh +++ b/mem/packet.hh @@ -128,6 +128,12 @@ struct Packet /** Accessor function that returns the destination index of the packet. */ short getDest() const { return dest; } + + Packet() + : result(Unknown) + {} + + void reset() { result = Unknown; } }; #endif //__MEM_PACKET_HH diff --git a/mem/page_table.cc b/mem/page_table.cc index 714ddde35..c4e1ea193 100644 --- a/mem/page_table.cc +++ b/mem/page_table.cc @@ -121,11 +121,14 @@ PageTable::translate(Addr vaddr, Addr &paddr) Fault -PageTable::translate(CpuRequestPtr &req) +PageTable::translate(RequestPtr &req) { - assert(pageAlign(req->vaddr + req->size - 1) == pageAlign(req->vaddr)); - if (!translate(req->vaddr, req->paddr)) { + Addr paddr; + assert(pageAlign(req->getVaddr() + req->getSize() - 1) + == pageAlign(req->getVaddr())); + if (!translate(req->getVaddr(), paddr)) { return genMachineCheckFault(); } - return page_check(req->paddr, req->size); + req->setPaddr(paddr); + return page_check(req->getPaddr(), req->getSize()); } diff --git a/mem/page_table.hh b/mem/page_table.hh index 8f0842f58..26248261a 100644 --- a/mem/page_table.hh +++ b/mem/page_table.hh @@ -83,7 +83,7 @@ class PageTable * field of mem_req. * @param req The memory request. */ - Fault translate(CpuRequestPtr &req); + Fault translate(RequestPtr &req); }; diff --git a/mem/physical.cc b/mem/physical.cc index 4087f3e32..b00935990 100644 --- a/mem/physical.cc +++ b/mem/physical.cc @@ -70,7 +70,7 @@ PhysicalMemory::MemResponseEvent::description() } PhysicalMemory::PhysicalMemory(const string &n) - : MemObject(n), base_addr(0), pmem_addr(NULL) + : MemObject(n), base_addr(0), pmem_addr(NULL), port(NULL) { // Hardcoded to 128 MB for now. pmem_size = 1 << 27; @@ -90,6 +90,14 @@ PhysicalMemory::PhysicalMemory(const string &n) page_ptr = 0; } +void +PhysicalMemory::init() +{ + if (!port) + panic("PhysicalMemory not connected to anything!"); + port->sendStatusChange(Port::RangeChange); +} + PhysicalMemory::~PhysicalMemory() { if (pmem_addr) diff --git a/mem/physical.hh b/mem/physical.hh index 53e86f85f..ce0a2099c 100644 --- a/mem/physical.hh +++ b/mem/physical.hh @@ -107,7 +107,7 @@ class PhysicalMemory : public MemObject int deviceBlockSize(); void getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop); virtual Port *getPort(const std::string &if_name); - void virtual init() { port->sendStatusChange(Port::RangeChange); } + void virtual init(); // fast back-door memory access for vtophys(), remote gdb, etc. // uint64_t phys_read_qword(Addr addr) const; diff --git a/mem/port.cc b/mem/port.cc index fb4f3b4e0..d312f3e3c 100644 --- a/mem/port.cc +++ b/mem/port.cc @@ -36,15 +36,15 @@ void Port::blobHelper(Addr addr, uint8_t *p, int size, Command cmd) { - Request req; + Request req(false); Packet pkt; pkt.req = &req; pkt.cmd = cmd; for (ChunkGenerator gen(addr, size, peerBlockSize()); !gen.done(); gen.next()) { - pkt.addr = req.paddr = gen.addr(); - pkt.size = req.size = gen.size(); + req.setPaddr(pkt.addr = gen.addr()); + req.setSize(pkt.size = gen.size()); pkt.data = p; sendFunctional(pkt); p += gen.size(); @@ -72,5 +72,5 @@ Port::memsetBlob(Addr addr, uint8_t val, int size) memset(buf, val, size); blobHelper(addr, buf, size, Write); - delete buf; + delete [] buf; } diff --git a/mem/request.hh b/mem/request.hh index 5e2275741..903e7503c 100644 --- a/mem/request.hh +++ b/mem/request.hh @@ -37,10 +37,8 @@ #include "arch/isa_traits.hh" class Request; -class CpuRequest; typedef Request* RequestPtr; -typedef CpuRequest* CpuRequestPtr; /** The request is a Load locked/store conditional. */ const unsigned LOCKED = 0x001; @@ -58,50 +56,147 @@ const unsigned NO_FAULT = 0x020; const unsigned PF_EXCLUSIVE = 0x100; /** The request should be marked as LRU. */ const unsigned EVICT_NEXT = 0x200; +/** The request should ignore unaligned access faults */ +const unsigned NO_ALIGN_FAULT = 0x400; class Request { //@todo Make Accesor functions, make these private. public: + /** Constructor, needs a bool to signify if it is/isn't Cpu Request. */ + Request(bool isCpu); + + /** reset the request to it's initial state so it can be reused.*/ + void resetAll(bool isCpu); + + /** reset the request's addrs times, etc, so but not everything to same + * time. */ + void resetMin(); + +//First non-cpu request fields + private: /** The physical address of the request. */ Addr paddr; - - /** whether this req came from the CPU or not **DO we need this??***/ - bool nicReq; + /** Wether or not paddr is valid (has been written yet). */ + bool validPaddr; /** The size of the request. */ int size; + /** Wether or not size is valid (has been written yet). */ + bool validSize; /** The time this request was started. Used to calculate latencies. */ Tick time; + /** Wether or not time is valid (has been written yet). */ + bool validTime; /** Destination address if this is a block copy. */ Addr copyDest; + /** Wether or not copyDest is valid (has been written yet). */ + bool validCopyDest; + /** Flag structure for the request. */ uint32_t flags; -}; + /** Wether or not flags is valid (has been written yet). */ + bool validFlags; -class CpuRequest : public Request -{ - //@todo Make Accesor functions, make these private. +//Accsesors for non-cpu request fields public: + /** Accesor for paddr. */ + Addr getPaddr(); + /** Accesor for paddr. */ + void setPaddr(Addr _paddr); + + /** Accesor for size. */ + int getSize(); + /** Accesor for size. */ + void setSize(int _size); + + /** Accesor for time. */ + Tick getTime(); + /** Accesor for time. */ + void setTime(Tick _time); + + /** Accesor for copy dest. */ + Addr getCopyDest(); + /** Accesor for copy dest. */ + void setCopyDest(Addr _copyDest); + + /** Accesor for flags. */ + uint32_t getFlags(); + /** Accesor for paddr. */ + void setFlags(uint32_t _flags); + +//Now cpu-request fields + private: + /** Bool to signify if this is a cpuRequest. */ + bool cpuReq; + /** The virtual address of the request. */ Addr vaddr; + /** Wether or not the vaddr is valid. */ + bool validVaddr; /** The address space ID. */ int asid; + /** Wether or not the asid is valid. */ + bool validAsid; /** The return value of store conditional. */ uint64_t scResult; + /** Wether or not the sc result is valid. */ + bool validScResult; /** The cpu number for statistics. */ int cpuNum; + /** Wether or not the cpu number is valid. */ + bool validCpuNum; /** The requesting thread id. */ int threadNum; + /** Wether or not the thread id is valid. */ + bool validThreadNum; /** program counter of initiating access; for tracing/debugging */ Addr pc; + /** Wether or not the pc is valid. */ + bool validPC; + +//Accessor Functions for cpu request fields + public: + /** Accesor function to determine if this is a cpu request or not.*/ + bool isCpuRequest(); + + /** Accesor function for vaddr.*/ + Addr getVaddr(); + /** Accesor function for vaddr.*/ + void setVaddr(Addr _vaddr); + + /** Accesor function for asid.*/ + int getAsid(); + /** Accesor function for asid.*/ + void setAsid(int _asid); + + /** Accesor function for store conditional return value.*/ + uint64_t getScResult(); + /** Accesor function for store conditional return value.*/ + void setScResult(uint64_t _scResult); + + /** Accesor function for cpu number.*/ + int getCpuNum(); + /** Accesor function for cpu number.*/ + void setCpuNum(int _cpuNum); + + /** Accesor function for thread number.*/ + int getThreadNum(); + /** Accesor function for thread number.*/ + void setThreadNum(int _threadNum); + + /** Accesor function for pc.*/ + Addr getPC(); + /** Accesor function for pc.*/ + void setPC(Addr _pc); + }; #endif // __MEM_REQUEST_HH__ diff --git a/mem/vport.hh b/mem/vport.hh index da036b981..fbc230ba3 100644 --- a/mem/vport.hh +++ b/mem/vport.hh @@ -63,39 +63,6 @@ class VirtualPort : public FunctionalPort */ bool nullExecContext() { return xc != NULL; } - /** Write a piece of data into a virtual address. - * @param vaddr virtual address to write to - * @param data data to write - */ - template <typename T> - inline void write(Addr vaddr, T data) - { - Addr paddr; - if (xc) - paddr = TheISA::vtophys(xc,vaddr); - else - paddr = TheISA::vtophys(vaddr); - - FunctionalPort::write(paddr, data); - } - - /** Read data from a virtual address and return it. - * @param vaddr address to read - * @return data read - */ - - template <typename T> - inline T read(Addr vaddr) - { - Addr paddr; - if (xc) - paddr = TheISA::vtophys(xc,vaddr); - else - paddr = TheISA::vtophys(vaddr); - - return FunctionalPort::read<T>(paddr); - } - /** Version of readblob that translates virt->phys and deals * with page boundries. */ virtual void readBlob(Addr addr, uint8_t *p, int size); diff --git a/python/m5/objects/AlphaConsole.py b/python/m5/objects/AlphaConsole.py index f8f034682..68e6089ab 100644 --- a/python/m5/objects/AlphaConsole.py +++ b/python/m5/objects/AlphaConsole.py @@ -1,9 +1,9 @@ from m5 import * -from Device import PioDevice +from Device import BasicPioDevice -class AlphaConsole(PioDevice): +class AlphaConsole(BasicPioDevice): type = 'AlphaConsole' cpu = Param.BaseCPU(Parent.any, "Processor") disk = Param.SimpleDisk("Simple Disk") sim_console = Param.SimConsole(Parent.any, "The Simulator Console") - system = Param.System(Parent.any, "system object") + system = Param.AlphaSystem(Parent.any, "system object") diff --git a/python/m5/objects/BadDevice.py b/python/m5/objects/BadDevice.py index 3fba4637d..9cb9a8f03 100644 --- a/python/m5/objects/BadDevice.py +++ b/python/m5/objects/BadDevice.py @@ -1,6 +1,6 @@ from m5 import * -from Device import PioDevice +from Device import BasicPioDevice -class BadDevice(PioDevice): +class BadDevice(BasicPioDevice): type = 'BadDevice' devicename = Param.String("Name of device to error on") diff --git a/python/m5/objects/BaseCPU.py b/python/m5/objects/BaseCPU.py index fccddb1ec..49cb2a8f3 100644 --- a/python/m5/objects/BaseCPU.py +++ b/python/m5/objects/BaseCPU.py @@ -2,6 +2,7 @@ from m5 import * class BaseCPU(SimObject): type = 'BaseCPU' abstract = True + mem = Param.MemObject("memory") if build_env['FULL_SYSTEM']: dtb = Param.AlphaDTB("Data TLB") @@ -9,7 +10,6 @@ class BaseCPU(SimObject): system = Param.System(Parent.any, "system object") cpu_id = Param.Int(-1, "CPU identifier") else: - mem = Param.MemObject("memory") workload = VectorParam.Process("processes to run") max_insts_all_threads = Param.Counter(0, diff --git a/python/m5/objects/Device.py b/python/m5/objects/Device.py index d7ca014a9..cda3b1824 100644 --- a/python/m5/objects/Device.py +++ b/python/m5/objects/Device.py @@ -1,35 +1,14 @@ from m5 import * -from FunctionalMemory import FunctionalMemory +from MemObject import MemObject -# This device exists only because there are some devices that I don't -# want to have a Platform parameter because it would cause a cycle in -# the C++ that cannot be easily solved. -# -# The real solution to this problem is to pass the ParamXXX structure -# to the constructor, but with the express condition that SimObject -# parameter values are not to be available at construction time. If -# some further configuration must be done, it must be done during the -# initialization phase at which point all SimObject pointers will be -# valid. -class FooPioDevice(FunctionalMemory): +class PioDevice(MemObject): type = 'PioDevice' abstract = True - addr = Param.Addr("Device Address") - mmu = Param.MemoryController(Parent.any, "Memory Controller") - pio_bus = Param.Bus(NULL, "Bus to attach to for PIO") - pio_latency = Param.Tick(1, "Programmed IO latency in bus cycles") + platform = Param.Platform(Parent.any, "Platform this device is part of") + system = Param.System(Parent.any, "System this device is part of") -class FooDmaDevice(FooPioDevice): - type = 'DmaDevice' +class BasicPioDevice(PioDevice): + type = 'BasicPioDevice' abstract = True - dma_bus = Param.Bus(Self.pio_bus, "Bus to attach to for DMA") - -class PioDevice(FooPioDevice): - type = 'PioDevice' - abstract = True - platform = Param.Platform(Parent.any, "Platform") - -class DmaDevice(PioDevice): - type = 'DmaDevice' - abstract = True - dma_bus = Param.Bus(Self.pio_bus, "Bus to attach to for DMA") + pio_addr = Param.Addr("Device Address") + pio_latency = Param.Tick(1, "Programmed IO latency in simticks") diff --git a/python/m5/objects/Pci.py b/python/m5/objects/Pci.py index 4124d0b92..f2ccce09f 100644 --- a/python/m5/objects/Pci.py +++ b/python/m5/objects/Pci.py @@ -1,5 +1,6 @@ from m5 import * -from Device import FooPioDevice, DmaDevice +from Device import BasicPioDevice +#, DmaDevice class PciConfigData(SimObject): type = 'PciConfigData' @@ -38,18 +39,18 @@ class PciConfigData(SimObject): MaximumLatency = Param.UInt8(0x00, "Maximum Latency") MinimumGrant = Param.UInt8(0x00, "Minimum Grant") -class PciConfigAll(FooPioDevice): +class PciConfigAll(BasicPioDevice): type = 'PciConfigAll' -class PciDevice(DmaDevice): - type = 'PciDevice' - abstract = True - addr = 0xffffffffL - pci_bus = Param.Int("PCI bus") - pci_dev = Param.Int("PCI device number") - pci_func = Param.Int("PCI function code") - configdata = Param.PciConfigData(Parent.any, "PCI Config data") - configspace = Param.PciConfigAll(Parent.any, "PCI Configspace") - -class PciFake(PciDevice): - type = 'PciFake' +#class PciDevice(DmaDevice): +# type = 'PciDevice' +# abstract = True +# addr = 0xffffffffL +# pci_bus = Param.Int("PCI bus") +# pci_dev = Param.Int("PCI device number") +# pci_func = Param.Int("PCI function code") +# configdata = Param.PciConfigData(Parent.any, "PCI Config data") +# configspace = Param.PciConfigAll(Parent.any, "PCI Configspace") +# +#class PciFake(PciDevice): +# type = 'PciFake' diff --git a/python/m5/objects/PhysicalMemory.py b/python/m5/objects/PhysicalMemory.py index b0aba1a7d..b69c969cb 100644 --- a/python/m5/objects/PhysicalMemory.py +++ b/python/m5/objects/PhysicalMemory.py @@ -5,5 +5,3 @@ class PhysicalMemory(Memory): type = 'PhysicalMemory' range = Param.AddrRange("Device Address") file = Param.String('', "memory mapped file") - if build_env['FULL_SYSTEM']: - mmu = Param.MemoryController(Parent.any, "Memory Controller") diff --git a/python/m5/objects/System.py b/python/m5/objects/System.py index 2959c1d1a..65b621dff 100644 --- a/python/m5/objects/System.py +++ b/python/m5/objects/System.py @@ -6,7 +6,6 @@ class System(SimObject): if build_env['FULL_SYSTEM']: boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency, "boot processor frequency") - memctrl = Param.MemoryController(Parent.any, "memory controller") init_param = Param.UInt64(0, "numerical value to pass into simulator") bin = Param.Bool(False, "is this system binned") binned_fns = VectorParam.String([], "functions broken down and binned") diff --git a/python/m5/objects/Tsunami.py b/python/m5/objects/Tsunami.py index 5425f421f..27ea0bce8 100644 --- a/python/m5/objects/Tsunami.py +++ b/python/m5/objects/Tsunami.py @@ -1,27 +1,27 @@ from m5 import * -from Device import FooPioDevice +from Device import BasicPioDevice from Platform import Platform class Tsunami(Platform): type = 'Tsunami' - pciconfig = Param.PciConfigAll("PCI configuration") +# pciconfig = Param.PciConfigAll("PCI configuration") system = Param.System(Parent.any, "system") -class TsunamiCChip(FooPioDevice): +class TsunamiCChip(BasicPioDevice): type = 'TsunamiCChip' tsunami = Param.Tsunami(Parent.any, "Tsunami") -class IsaFake(FooPioDevice): +class IsaFake(BasicPioDevice): type = 'IsaFake' - size = Param.Addr("Size of address range") + pio_size = Param.Addr(0x8, "Size of address range") -class TsunamiIO(FooPioDevice): +class TsunamiIO(BasicPioDevice): type = 'TsunamiIO' time = Param.UInt64(1136073600, "System time to use (0 for actual time, default is 1/1/06)") tsunami = Param.Tsunami(Parent.any, "Tsunami") frequency = Param.Frequency('1024Hz', "frequency of interrupts") -class TsunamiPChip(FooPioDevice): +class TsunamiPChip(BasicPioDevice): type = 'TsunamiPChip' tsunami = Param.Tsunami(Parent.any, "Tsunami") diff --git a/python/m5/objects/Uart.py b/python/m5/objects/Uart.py index 6eda5cdb3..54754aeb9 100644 --- a/python/m5/objects/Uart.py +++ b/python/m5/objects/Uart.py @@ -1,11 +1,10 @@ from m5 import * -from Device import PioDevice +from Device import BasicPioDevice -class Uart(PioDevice): +class Uart(BasicPioDevice): type = 'Uart' abstract = True - console = Param.SimConsole(Parent.any, "The console") - size = Param.Addr(0x8, "Device size") + sim_console = Param.SimConsole(Parent.any, "The console") class Uart8250(Uart): type = 'Uart8250' diff --git a/sim/process.cc b/sim/process.cc index 1f2e8d0fd..d88716f1e 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -316,7 +316,7 @@ LiveProcess::argsInit(int intSize, int pageSize) roundUp(stack_size, pageSize)); // map out initial stack contents - Addr argv_array_base = stack_min + sizeof(uint64_t); // room for argc + Addr argv_array_base = stack_min + intSize; // room for argc Addr envp_array_base = argv_array_base + argv_array_size; Addr arg_data_base = envp_array_base + envp_array_size; Addr env_data_base = arg_data_base + arg_data_size; diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc index 9e49c6a5e..ed0da628e 100644 --- a/sim/syscall_emul.cc +++ b/sim/syscall_emul.cc @@ -48,13 +48,15 @@ using namespace TheISA; void SyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc) { - DPRINTFR(SyscallVerbose, "%s: syscall %s called\n", - xc->getCpuPtr()->name(), name); + DPRINTFR(SyscallVerbose, "%d: %s: syscall %s called w/arguments %d,%d,%d,%d\n", + curTick,xc->getCpuPtr()->name(), name, + xc->getSyscallArg(0),xc->getSyscallArg(1), + xc->getSyscallArg(2),xc->getSyscallArg(3)); SyscallReturn retval = (*funcPtr)(this, callnum, process, xc); - DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n", - xc->getCpuPtr()->name(), name, retval.value()); + DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n", + curTick,xc->getCpuPtr()->name(), name, retval.value()); if (!(flags & SyscallDesc::SuppressReturnValue)) xc->setSyscallReturn(retval); @@ -65,8 +67,6 @@ SyscallReturn unimplementedFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - //warn("ignoring syscall %s(%d, %d, ...)", desc->name, - // xc->getSyscallArg(0), xc->getSyscallArg(1)); fatal("syscall %s (#%d) unimplemented.", desc->name, callnum); return 1; diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index ae1196f03..00f016410 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -700,22 +700,25 @@ mmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) int flags = xc->getSyscallArg(3); // int fd = p->sim_fd(xc->getSyscallArg(4)); // int offset = xc->getSyscallArg(5); - Addr junk; - - if (start == 0) { - // user didn't give an address... pick one from our "mmap region" - start = p->mmap_end; - for (ChunkGenerator gen(start, roundUp(length, TheISA::VMPageSize), TheISA::VMPageSize); !gen.done(); gen.next()) { - if (!p->pTable->translate(gen.addr(), junk)) - p->pTable->allocate(roundDown(gen.addr(), TheISA::VMPageSize), TheISA::VMPageSize); - } - p->mmap_end += roundUp(length, TheISA::VMPageSize); - if (p->nxm_start != 0) { - //If we have an nxm space, make sure we haven't colided - assert(p->mmap_end < p->nxm_start); - } + + if ((start % TheISA::VMPageSize) != 0 || + (length % TheISA::VMPageSize) != 0) { + warn("mmap failing: arguments not page-aligned: " + "start 0x%x length 0x%x", + start, length); + return -EINVAL; + } + + if (start != 0) { + warn("mmap: ignoring suggested map address 0x%x, using 0x%x", + start, p->mmap_end); } + // pick next address from our "mmap region" + start = p->mmap_end; + p->pTable->allocate(start, length); + p->mmap_end += length; + if (!(flags & OS::TGT_MAP_ANONYMOUS)) { warn("allowing mmap of file @ fd %d. " "This will break if not /dev/zero.", xc->getSyscallArg(4)); @@ -840,4 +843,7 @@ getrusageFunc(SyscallDesc *desc, int callnum, Process *process, return 0; } + + + #endif // __SIM_SYSCALL_EMUL_HH__ |