From: Kevin Lim Date: Sun, 5 Mar 2006 05:34:54 +0000 (-0500) Subject: Merge ktlim@zizzer:/bk/m5 X-Git-Tag: m5_2.0_beta1~87^2~35 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=20eced3ea07f64e50444c00125012d6641416e4b;p=gem5.git Merge ktlim@zizzer:/bk/m5 into zamp.eecs.umich.edu:/z/ktlim2/m5-proxyxc Further changes still need to be made to the XC code. arch/alpha/ev5.cc: arch/alpha/freebsd/system.cc: arch/alpha/linux/system.cc: base/remote_gdb.cc: cpu/cpu_exec_context.cc: cpu/cpu_exec_context.hh: cpu/simple/cpu.cc: cpu/simple/cpu.hh: kern/kernel_stats.cc: sim/pseudo_inst.cc: Hand merge. --HG-- rename : kern/freebsd/freebsd_system.cc => arch/alpha/freebsd/system.cc rename : kern/linux/linux_system.cc => arch/alpha/linux/system.cc rename : kern/linux/linux_threadinfo.hh => arch/alpha/linux/threadinfo.hh rename : arch/alpha/alpha_linux_process.cc => arch/alpha/linux_process.cc rename : arch/alpha/alpha_memory.cc => arch/alpha/tlb.cc rename : arch/alpha/alpha_tru64_process.cc => arch/alpha/tru64_process.cc rename : cpu/exec_context.cc => cpu/cpu_exec_context.cc rename : cpu/exec_context.hh => cpu/cpu_exec_context.hh extra : convert_revision : c1fe71fdd87d1fcd376f4feec69fc3fa29152e3e --- 20eced3ea07f64e50444c00125012d6641416e4b diff --cc arch/alpha/ev5.cc index e313c1a1c,9d2ff4db7..11faf1850 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@@ -49,17 -71,40 +50,17 @@@ using namespace EV5 // Machine dependent functions // void - AlphaISA::initCPU(RegFile *regs, int cpuId) + AlphaISA::initCPU(ExecContext *xc, int cpuId) { - initIPRs(®s->miscRegs, cpuId); + initIPRs(xc, cpuId); - // CPU comes up with PAL regs enabled - swap_palshadow(regs, true); - regs->intRegFile[16] = cpuId; - regs->intRegFile[0] = cpuId; + xc->setIntReg(16, cpuId); + xc->setIntReg(0, cpuId); - regs->pc = regs->miscRegs.readReg(IPR_PAL_BASE) + (new ResetFault)->vect(); - regs->npc = regs->pc + sizeof(MachInst); - xc->setPC(xc->readMiscReg(IPR_PAL_BASE) + fault_addr(ResetFault)); ++ xc->setPC(xc->readMiscReg(IPR_PAL_BASE) + (new ResetFault)->vect()); + xc->setNextPC(xc->readPC() + sizeof(MachInst)); } -//////////////////////////////////////////////////////////////////////// -// -// alpha exceptions - value equals trap address, update with MD_FAULT_TYPE -// -const Addr -AlphaISA::fault_addr(Fault fault) -{ - //Check for the system wide faults - if(fault == NoFault) return 0x0000; - else if(fault == MachineCheckFault) return 0x0401; - else if(fault == AlignmentFault) return 0x0301; - //Deal with the alpha specific faults - return ((AlphaFault*)fault)->vect; -}; - -const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { - /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, - /* 8 */ 1, 1, 1, 1, 1, 1, 1, 0, - /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, - /* 24 */ 0, 1, 0, 0, 0, 0, 0, 0 }; - //////////////////////////////////////////////////////////////////////// // // @@@ -130,21 -177,82 +133,21 @@@ AlphaISA::zeroRegisters(CPU *cpu // Insure ISA semantics // (no longer very clean due to the change in setIntReg() in the // cpu model. Consider changing later.) - cpu->xc->setIntReg(ZeroReg, 0); - cpu->xc->setFloatRegDouble(ZeroReg, 0.0); + cpu->cpuXC->setIntReg(ZeroReg, 0); + cpu->cpuXC->setFloatRegDouble(ZeroReg, 0.0); } -void -CPUExecContext::ev5_trap(Fault fault) -{ - DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name, regs.pc); - cpu->recordEvent(csprintf("Fault %s", fault->name)); - - assert(!misspeculating()); - cpu->kernelStats->fault(fault); - - if (fault == ArithmeticFault) - panic("Arithmetic traps are unimplemented!"); - - // exception restart address - if (fault != InterruptFault || !inPalMode()) - setMiscReg(AlphaISA::IPR_EXC_ADDR, regs.pc); - - if (fault == PalFault || fault == ArithmeticFault /* || - fault == InterruptFault && !inPalMode() */) { - // traps... skip faulting instruction - setMiscReg(AlphaISA::IPR_EXC_ADDR, - readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); - } - - if (!inPalMode()) - AlphaISA::swap_palshadow(®s, true); - - regs.pc = readMiscReg(AlphaISA::IPR_PAL_BASE) + AlphaISA::fault_addr(fault); - regs.npc = regs.pc + sizeof(MachInst); -} - - -void -AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) -{ - bool use_pc = (fault == NoFault); - - if (fault == ArithmeticFault) - panic("arithmetic faults NYI..."); - - // compute exception restart address - if (use_pc || fault == PalFault || fault == ArithmeticFault) { - // traps... skip faulting instruction - regs->miscRegs.setReg(IPR_EXC_ADDR, regs->pc + 4); - } else { - // fault, post fault at excepting instruction - regs->miscRegs.setReg(IPR_EXC_ADDR, regs->pc); - } - - // jump to expection address (PAL PC bit set here as well...) - if (!use_pc) - regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + - fault_addr(fault); - else - regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + pc; - - // that's it! (orders of magnitude less painful than x86) -} - Fault - ExecContext::hwrei() + CPUExecContext::hwrei() { if (!inPalMode()) - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR)); if (!misspeculating()) { - kernelStats->hwrei(); + cpu->kernelStats->hwrei(); - if ((readMiscReg(AlphaISA::IPR_EXC_ADDR) & 1) == 0) - AlphaISA::swap_palshadow(®s, false); - cpu->checkInterrupts = true; } diff --cc arch/alpha/freebsd/system.cc index 681d4ad46,000000000..e32053afd mode 100644,000000..100644 --- a/arch/alpha/freebsd/system.cc +++ b/arch/alpha/freebsd/system.cc @@@ -1,167 -1,0 +1,167 @@@ +/* + * Copyright (c) 2004-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. + */ + +/** + * @file + * Modifications for the FreeBSD kernel. + * Based on kern/linux/linux_system.cc. + * + */ + +#include "arch/alpha/system.hh" +#include "arch/alpha/freebsd/system.hh" +#include "base/loader/symtab.hh" +#include "cpu/exec_context.hh" +#include "mem/functional/memory_control.hh" +#include "mem/functional/physical.hh" - #include "sim/builder.hh" +#include "arch/isa_traits.hh" ++#include "sim/builder.hh" +#include "sim/byteswap.hh" +#include "arch/vtophys.hh" + +#define TIMER_FREQUENCY 1193180 + +using namespace std; +using namespace AlphaISA; + +FreebsdAlphaSystem::FreebsdAlphaSystem(Params *p) + : AlphaSystem(p) +{ + /** + * Any time DELAY is called just skip the function. + * Shouldn't we actually emulate the delay? + */ + skipDelayEvent = addKernelFuncEvent("DELAY"); + skipCalibrateClocks = + addKernelFuncEvent("calibrate_clocks"); +} + + +FreebsdAlphaSystem::~FreebsdAlphaSystem() +{ + delete skipDelayEvent; + delete skipCalibrateClocks; +} + + +void +FreebsdAlphaSystem::doCalibrateClocks(ExecContext *xc) +{ + Addr ppc_vaddr = 0; + Addr timer_vaddr = 0; + Addr ppc_paddr = 0; + Addr timer_paddr = 0; + - ppc_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg1]; - timer_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg2]; ++ ppc_vaddr = (Addr)xc->readIntReg(ArgumentReg1); ++ timer_vaddr = (Addr)xc->readIntReg(ArgumentReg2); + + ppc_paddr = vtophys(physmem, ppc_vaddr); + timer_paddr = vtophys(physmem, timer_vaddr); + + uint8_t *ppc = physmem->dma_addr(ppc_paddr, sizeof(uint32_t)); + uint8_t *timer = physmem->dma_addr(timer_paddr, sizeof(uint32_t)); + + *(uint32_t *)ppc = htog((uint32_t)Clock::Frequency); + *(uint32_t *)timer = htog((uint32_t)TIMER_FREQUENCY); +} + + +void +FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ExecContext *xc) +{ + SkipFuncEvent::process(xc); - ((FreebsdAlphaSystem *)xc->system)->doCalibrateClocks(xc); ++ ((FreebsdAlphaSystem *)xc->getSystemPtr())->doCalibrateClocks(xc); +} + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) + + Param boot_cpu_frequency; + SimObjectParam memctrl; + SimObjectParam physmem; + + Param kernel; + Param console; + Param pal; + + Param boot_osflags; + Param readfile; + Param init_param; + + Param system_type; + Param system_rev; + + Param bin; + VectorParam binned_fns; + Param bin_int; + +END_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) + +BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) + + INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), + INIT_PARAM(memctrl, "memory controller"), + INIT_PARAM(physmem, "phsyical memory"), + INIT_PARAM(kernel, "file that contains the kernel code"), + INIT_PARAM(console, "file that contains the console code"), + INIT_PARAM(pal, "file that contains palcode"), + INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", + "a"), + INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), + INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), + INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), + INIT_PARAM_DFLT(bin, "is this system to be binned", false), + INIT_PARAM(binned_fns, "functions to be broken down and binned"), + INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) + +END_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) + +CREATE_SIM_OBJECT(FreebsdAlphaSystem) +{ + AlphaSystem::Params *p = new AlphaSystem::Params; + p->name = getInstanceName(); + p->boot_cpu_frequency = boot_cpu_frequency; + p->memctrl = memctrl; + p->physmem = physmem; + p->kernel_path = kernel; + p->console_path = console; + p->palcode = pal; + p->boot_osflags = boot_osflags; + p->init_param = init_param; + p->readfile = readfile; + p->system_type = system_type; + p->system_rev = system_rev; + p->bin = bin; + p->binned_fns = binned_fns; + p->bin_int = bin_int; + return new FreebsdAlphaSystem(p); +} + +REGISTER_SIM_OBJECT("FreebsdAlphaSystem", FreebsdAlphaSystem) + diff --cc arch/alpha/linux/system.cc index 6a820d14f,000000000..f9275d15e mode 100644,000000..100644 --- a/arch/alpha/linux/system.cc +++ b/arch/alpha/linux/system.cc @@@ -1,289 -1,0 +1,289 @@@ +/* + * Copyright (c) 2004-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. + */ + +/** + * @file + * This code loads the linux kernel, console, pal and patches certain + * functions. The symbol tables are loaded so that traces can show + * the executing function and we can skip functions. Various delay + * loops are skipped and their final values manually computed to speed + * up boot time. + */ + +#include "arch/arguments.hh" +#include "arch/vtophys.hh" +#include "arch/alpha/linux/system.hh" +#include "arch/alpha/linux/threadinfo.hh" +#include "arch/alpha/system.hh" +#include "base/loader/symtab.hh" +#include "cpu/exec_context.hh" +#include "cpu/base.hh" +#include "dev/platform.hh" +#include "kern/linux/printk.hh" +#include "kern/linux/events.hh" +#include "mem/functional/memory_control.hh" +#include "mem/functional/physical.hh" +#include "sim/builder.hh" +#include "sim/byteswap.hh" + +using namespace std; +using namespace AlphaISA; +using namespace Linux; + +LinuxAlphaSystem::LinuxAlphaSystem(Params *p) + : AlphaSystem(p) +{ + Addr addr = 0; + Addr paddr = 0; + + /** + * The symbol swapper_pg_dir marks the beginning of the kernel and + * the location of bootloader passed arguments + */ + if (!kernelSymtab->findAddress("swapper_pg_dir", KernelStart)) { + panic("Could not determine start location of kernel"); + } + + /** + * Since we aren't using a bootloader, we have to copy the + * kernel arguments directly into the kernel's memory. + */ + paddr = vtophys(physmem, CommandLine()); + char *commandline = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); + if (commandline) + strncpy(commandline, params()->boot_osflags.c_str(), CommandLineSize); + + /** + * find the address of the est_cycle_freq variable and insert it + * so we don't through the lengthly process of trying to + * calculated it by using the PIT, RTC, etc. + */ + if (kernelSymtab->findAddress("est_cycle_freq", addr)) { + paddr = vtophys(physmem, addr); + uint8_t *est_cycle_frequency = + physmem->dma_addr(paddr, sizeof(uint64_t)); + + if (est_cycle_frequency) + *(uint64_t *)est_cycle_frequency = + Clock::Frequency / p->boot_cpu_frequency; + } + + + /** + * EV5 only supports 127 ASNs so we are going to tell the kernel that the + * paritiuclar EV6 we have only supports 127 asns. + * @todo At some point we should change ev5.hh and the palcode to support + * 255 ASNs. + */ + if (kernelSymtab->findAddress("dp264_mv", addr)) { + paddr = vtophys(physmem, addr); + char *dp264_mv = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); + + if (dp264_mv) { + *(uint32_t*)(dp264_mv+0x18) = LittleEndianGuest::htog((uint32_t)127); + } else + panic("could not translate dp264_mv addr\n"); + + } else + panic("could not find dp264_mv\n"); + +#ifndef NDEBUG + kernelPanicEvent = addKernelFuncEvent("panic"); + if (!kernelPanicEvent) + panic("could not find kernel symbol \'panic\'"); + +#if 0 + kernelDieEvent = addKernelFuncEvent("die_if_kernel"); + if (!kernelDieEvent) + panic("could not find kernel symbol \'die_if_kernel\'"); +#endif + +#endif + + /** + * Any time ide_delay_50ms, calibarte_delay or + * determine_cpu_caches is called just skip the + * function. Currently determine_cpu_caches only is used put + * information in proc, however if that changes in the future we + * will have to fill in the cache size variables appropriately. + */ + + skipIdeDelay50msEvent = + addKernelFuncEvent("ide_delay_50ms"); + skipDelayLoopEvent = + addKernelFuncEvent("calibrate_delay"); + skipCacheProbeEvent = + addKernelFuncEvent("determine_cpu_caches"); + debugPrintkEvent = addKernelFuncEvent("dprintk"); + idleStartEvent = addKernelFuncEvent("cpu_idle"); + + if (kernelSymtab->findAddress("alpha_switch_to", addr) && DTRACE(Thread)) { + printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo", + addr + sizeof(MachInst) * 6); + } else { + printThreadEvent = NULL; + } + + if (params()->bin_int) { + intStartEvent = addPalFuncEvent("sys_int_21"); + if (!intStartEvent) + panic("could not find symbol: sys_int_21\n"); + + intEndEvent = addPalFuncEvent("rti_to_kern"); + if (!intEndEvent) + panic("could not find symbol: rti_to_kern\n"); + + intEndEvent2 = addPalFuncEvent("rti_to_user"); + if (!intEndEvent2) + panic("could not find symbol: rti_to_user\n"); + + intEndEvent3 = addKernelFuncEvent("do_softirq"); + if (!intEndEvent3) + panic("could not find symbol: do_softirq\n"); + } +} + +LinuxAlphaSystem::~LinuxAlphaSystem() +{ +#ifndef NDEBUG + delete kernelPanicEvent; +#endif + delete skipIdeDelay50msEvent; + delete skipDelayLoopEvent; + delete skipCacheProbeEvent; + delete debugPrintkEvent; + delete idleStartEvent; + delete printThreadEvent; + delete intStartEvent; + delete intEndEvent; + delete intEndEvent2; +} + + +void +LinuxAlphaSystem::setDelayLoop(ExecContext *xc) +{ + Addr addr = 0; + if (kernelSymtab->findAddress("loops_per_jiffy", addr)) { + Addr paddr = vtophys(physmem, addr); + + uint8_t *loops_per_jiffy = + physmem->dma_addr(paddr, sizeof(uint32_t)); + - Tick cpuFreq = xc->cpu->frequency(); ++ Tick cpuFreq = xc->getCpuPtr()->frequency(); + Tick intrFreq = platform->intrFrequency(); + *(uint32_t *)loops_per_jiffy = + (uint32_t)((cpuFreq / intrFreq) * 0.9988); + } +} + + +void +LinuxAlphaSystem::SkipDelayLoopEvent::process(ExecContext *xc) +{ + SkipFuncEvent::process(xc); + // calculate and set loops_per_jiffy - ((LinuxAlphaSystem *)xc->system)->setDelayLoop(xc); ++ ((LinuxAlphaSystem *)xc->getSystemPtr())->setDelayLoop(xc); +} + +void +LinuxAlphaSystem::PrintThreadInfo::process(ExecContext *xc) +{ + Linux::ThreadInfo ti(xc); + + DPRINTF(Thread, "Currently Executing Thread %s, pid %d, started at: %d\n", + ti.curTaskName(), ti.curTaskPID(), ti.curTaskStart()); +} + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem) + + Param boot_cpu_frequency; + SimObjectParam memctrl; + SimObjectParam physmem; + + Param kernel; + Param console; + Param pal; + + Param boot_osflags; + Param readfile; + Param init_param; + + Param system_type; + Param system_rev; + + Param bin; + VectorParam binned_fns; + Param bin_int; + +END_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem) + +BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem) + + INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), + INIT_PARAM(memctrl, "memory controller"), + INIT_PARAM(physmem, "phsyical memory"), + INIT_PARAM(kernel, "file that contains the kernel code"), + INIT_PARAM(console, "file that contains the console code"), + INIT_PARAM(pal, "file that contains palcode"), + INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", + "a"), + INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), + INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), + INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), + INIT_PARAM_DFLT(bin, "is this system to be binned", false), + INIT_PARAM(binned_fns, "functions to be broken down and binned"), + INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) + +END_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem) + +CREATE_SIM_OBJECT(LinuxAlphaSystem) +{ + AlphaSystem::Params *p = new AlphaSystem::Params; + p->name = getInstanceName(); + p->boot_cpu_frequency = boot_cpu_frequency; + p->memctrl = memctrl; + p->physmem = physmem; + p->kernel_path = kernel; + p->console_path = console; + p->palcode = pal; + p->boot_osflags = boot_osflags; + p->init_param = init_param; + p->readfile = readfile; + p->system_type = system_type; + p->system_rev = system_rev; + p->bin = bin; + p->binned_fns = binned_fns; + p->bin_int = bin_int; + return new LinuxAlphaSystem(p); +} + +REGISTER_SIM_OBJECT("LinuxAlphaSystem", LinuxAlphaSystem) + diff --cc arch/alpha/linux/threadinfo.hh index bdb8e1e4c,000000000..8f03c9314 mode 100644,000000..100644 --- a/arch/alpha/linux/threadinfo.hh +++ b/arch/alpha/linux/threadinfo.hh @@@ -1,89 -1,0 +1,89 @@@ +/* + * Copyright (c) 2004 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 __ARCH_ALPHA_LINUX_LINUX_TREADNIFO_HH__ +#define __ARCH_ALPHA_LINUX_LINUX_TREADNIFO_HH__ + +#include "arch/alpha/linux/thread_info.hh" +#include "cpu/exec_context.hh" +#include "kern/linux/sched.hh" +#include "sim/vptr.hh" + +namespace Linux { + +class ThreadInfo +{ + private: + ExecContext *xc; + + public: + ThreadInfo(ExecContext *exec) : xc(exec) {} + ~ThreadInfo() {} + + inline VPtr + curThreadInfo() + { + Addr current; + + /* Each kernel stack is only 2 pages, the start of which is the + * thread_info struct. So we can get the address by masking off + * the lower 14 bits. + */ - current = xc->regs.intRegFile[TheISA::StackPointerReg] & ~0x3fff; ++ current = xc->readIntReg(TheISA::StackPointerReg) & ~0x3fff; + return VPtr(xc, current); + } + + inline VPtr + curTaskInfo() + { + Addr task = curThreadInfo()->task; + return VPtr(xc, task); + } + + std::string + curTaskName() + { + return curTaskInfo()->name; + } + + int32_t + curTaskPID() + { + return curTaskInfo()->pid; + } + + uint64_t + curTaskStart() + { + return curTaskInfo()->start; + } +}; + +/* namespace Linux */ } + +#endif // __ARCH_ALPHA_LINUX_LINUX_THREADINFO_HH__ diff --cc arch/alpha/linux_process.cc index 0b193fb55,000000000..b80966133 mode 100644,000000..100644 --- a/arch/alpha/linux_process.cc +++ b/arch/alpha/linux_process.cc @@@ -1,613 -1,0 +1,613 @@@ +/* + * 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/common_syscall_emul.hh" +#include "arch/alpha/linux_process.hh" +#include "arch/alpha/isa_traits.hh" + +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "kern/linux/linux.hh" +#include "mem/functional/functional.hh" + +#include "sim/process.hh" +#include "sim/syscall_emul.hh" + +using namespace std; +using namespace AlphaISA; + +/// Target pipe() handler. Even though this is a generic Posix call, +/// the Alpha return convention is funky, so that makes it +/// Alpha-specific. +SyscallReturn +pipeFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + int fds[2], sim_fds[2]; + int pipe_retval = pipe(fds); + + if (pipe_retval < 0) { + // error + return pipe_retval; + } + + sim_fds[0] = process->alloc_fd(fds[0]); + sim_fds[1] = process->alloc_fd(fds[1]); + + // Alpha Linux convention for pipe() is that fd[0] is returned as + // the return value of the function, and fd[1] is returned in r20. - xc->regs.intRegFile[20] = sim_fds[1]; ++ xc->setIntReg(20, sim_fds[1]); + return sim_fds[0]; +} + + +/// Target uname() handler. +static SyscallReturn +unameFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + TypedBufferArg name(xc->getSyscallArg(0)); + + strcpy(name->sysname, "Linux"); + strcpy(name->nodename, "m5.eecs.umich.edu"); + strcpy(name->release, "2.4.20"); + strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); + strcpy(name->machine, "alpha"); + - name.copyOut(xc->mem); ++ name.copyOut(xc->getMemPtr()); + return 0; +} + +/// Target osf_getsysyinfo() handler. Even though this call is +/// borrowed from Tru64, the subcases that get used appear to be +/// different in practice from those used by Tru64 processes. +static SyscallReturn +osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + unsigned op = xc->getSyscallArg(0); + // unsigned nbytes = xc->getSyscallArg(2); + + switch (op) { + + case 45: { // GSI_IEEE_FP_CONTROL + TypedBufferArg fpcr(xc->getSyscallArg(1)); + // I don't think this exactly matches the HW FPCR + *fpcr = 0; - fpcr.copyOut(xc->mem); ++ fpcr.copyOut(xc->getMemPtr()); + return 0; + } + + default: + cerr << "osf_getsysinfo: unknown op " << op << endl; + abort(); + break; + } + + return 1; +} + +/// Target osf_setsysinfo() handler. +static SyscallReturn +osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + unsigned op = xc->getSyscallArg(0); + // unsigned nbytes = xc->getSyscallArg(2); + + switch (op) { + + case 14: { // SSI_IEEE_FP_CONTROL + TypedBufferArg fpcr(xc->getSyscallArg(1)); + // I don't think this exactly matches the HW FPCR - fpcr.copyIn(xc->mem); ++ fpcr.copyIn(xc->getMemPtr()); + DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " + " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); + return 0; + } + + default: + cerr << "osf_setsysinfo: unknown op " << op << endl; + abort(); + break; + } + + return 1; +} + + +SyscallDesc AlphaLinuxProcess::syscallDescs[] = { + /* 0 */ SyscallDesc("osf_syscall", unimplementedFunc), + /* 1 */ SyscallDesc("exit", exitFunc), + /* 2 */ SyscallDesc("fork", unimplementedFunc), + /* 3 */ SyscallDesc("read", readFunc), + /* 4 */ SyscallDesc("write", writeFunc), + /* 5 */ SyscallDesc("osf_old_open", unimplementedFunc), + /* 6 */ SyscallDesc("close", closeFunc), + /* 7 */ SyscallDesc("osf_wait4", unimplementedFunc), + /* 8 */ SyscallDesc("osf_old_creat", unimplementedFunc), + /* 9 */ SyscallDesc("link", unimplementedFunc), + /* 10 */ SyscallDesc("unlink", unlinkFunc), + /* 11 */ SyscallDesc("osf_execve", unimplementedFunc), + /* 12 */ SyscallDesc("chdir", unimplementedFunc), + /* 13 */ SyscallDesc("fchdir", unimplementedFunc), + /* 14 */ SyscallDesc("mknod", unimplementedFunc), + /* 15 */ SyscallDesc("chmod", chmodFunc), + /* 16 */ SyscallDesc("chown", chownFunc), + /* 17 */ SyscallDesc("brk", obreakFunc), + /* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc), + /* 19 */ SyscallDesc("lseek", lseekFunc), + /* 20 */ SyscallDesc("getxpid", getpidFunc), + /* 21 */ SyscallDesc("osf_mount", unimplementedFunc), + /* 22 */ SyscallDesc("umount", unimplementedFunc), + /* 23 */ SyscallDesc("setuid", setuidFunc), + /* 24 */ SyscallDesc("getxuid", getuidFunc), + /* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc), + /* 26 */ SyscallDesc("osf_ptrace", unimplementedFunc), + /* 27 */ SyscallDesc("osf_nrecvmsg", unimplementedFunc), + /* 28 */ SyscallDesc("osf_nsendmsg", unimplementedFunc), + /* 29 */ SyscallDesc("osf_nrecvfrom", unimplementedFunc), + /* 30 */ SyscallDesc("osf_naccept", unimplementedFunc), + /* 31 */ SyscallDesc("osf_ngetpeername", unimplementedFunc), + /* 32 */ SyscallDesc("osf_ngetsockname", unimplementedFunc), + /* 33 */ SyscallDesc("access", unimplementedFunc), + /* 34 */ SyscallDesc("osf_chflags", unimplementedFunc), + /* 35 */ SyscallDesc("osf_fchflags", unimplementedFunc), + /* 36 */ SyscallDesc("sync", unimplementedFunc), + /* 37 */ SyscallDesc("kill", unimplementedFunc), + /* 38 */ SyscallDesc("osf_old_stat", unimplementedFunc), + /* 39 */ SyscallDesc("setpgid", unimplementedFunc), + /* 40 */ SyscallDesc("osf_old_lstat", unimplementedFunc), + /* 41 */ SyscallDesc("dup", unimplementedFunc), + /* 42 */ SyscallDesc("pipe", pipeFunc), + /* 43 */ SyscallDesc("osf_set_program_attributes", unimplementedFunc), + /* 44 */ SyscallDesc("osf_profil", unimplementedFunc), + /* 45 */ SyscallDesc("open", openFunc), + /* 46 */ SyscallDesc("osf_old_sigaction", unimplementedFunc), + /* 47 */ SyscallDesc("getxgid", getgidFunc), + /* 48 */ SyscallDesc("osf_sigprocmask", ignoreFunc), + /* 49 */ SyscallDesc("osf_getlogin", unimplementedFunc), + /* 50 */ SyscallDesc("osf_setlogin", unimplementedFunc), + /* 51 */ SyscallDesc("acct", unimplementedFunc), + /* 52 */ SyscallDesc("sigpending", unimplementedFunc), + /* 53 */ SyscallDesc("osf_classcntl", unimplementedFunc), + /* 54 */ SyscallDesc("ioctl", ioctlFunc), + /* 55 */ SyscallDesc("osf_reboot", unimplementedFunc), + /* 56 */ SyscallDesc("osf_revoke", unimplementedFunc), + /* 57 */ SyscallDesc("symlink", unimplementedFunc), + /* 58 */ SyscallDesc("readlink", unimplementedFunc), + /* 59 */ SyscallDesc("execve", unimplementedFunc), + /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 61 */ SyscallDesc("chroot", unimplementedFunc), + /* 62 */ SyscallDesc("osf_old_fstat", unimplementedFunc), + /* 63 */ SyscallDesc("getpgrp", unimplementedFunc), + /* 64 */ SyscallDesc("getpagesize", getpagesizeFunc), + /* 65 */ SyscallDesc("osf_mremap", unimplementedFunc), + /* 66 */ SyscallDesc("vfork", unimplementedFunc), + /* 67 */ SyscallDesc("stat", statFunc), + /* 68 */ SyscallDesc("lstat", lstatFunc), + /* 69 */ SyscallDesc("osf_sbrk", unimplementedFunc), + /* 70 */ SyscallDesc("osf_sstk", unimplementedFunc), + /* 71 */ SyscallDesc("mmap", mmapFunc), + /* 72 */ SyscallDesc("osf_old_vadvise", unimplementedFunc), + /* 73 */ SyscallDesc("munmap", munmapFunc), + /* 74 */ SyscallDesc("mprotect", ignoreFunc), + /* 75 */ SyscallDesc("madvise", unimplementedFunc), + /* 76 */ SyscallDesc("vhangup", unimplementedFunc), + /* 77 */ SyscallDesc("osf_kmodcall", unimplementedFunc), + /* 78 */ SyscallDesc("osf_mincore", unimplementedFunc), + /* 79 */ SyscallDesc("getgroups", unimplementedFunc), + /* 80 */ SyscallDesc("setgroups", unimplementedFunc), + /* 81 */ SyscallDesc("osf_old_getpgrp", unimplementedFunc), + /* 82 */ SyscallDesc("setpgrp", unimplementedFunc), + /* 83 */ SyscallDesc("osf_setitimer", unimplementedFunc), + /* 84 */ SyscallDesc("osf_old_wait", unimplementedFunc), + /* 85 */ SyscallDesc("osf_table", unimplementedFunc), + /* 86 */ SyscallDesc("osf_getitimer", unimplementedFunc), + /* 87 */ SyscallDesc("gethostname", gethostnameFunc), + /* 88 */ SyscallDesc("sethostname", unimplementedFunc), + /* 89 */ SyscallDesc("getdtablesize", unimplementedFunc), + /* 90 */ SyscallDesc("dup2", unimplementedFunc), + /* 91 */ SyscallDesc("fstat", fstatFunc), + /* 92 */ SyscallDesc("fcntl", fcntlFunc), + /* 93 */ SyscallDesc("osf_select", unimplementedFunc), + /* 94 */ SyscallDesc("poll", unimplementedFunc), + /* 95 */ SyscallDesc("fsync", unimplementedFunc), + /* 96 */ SyscallDesc("setpriority", unimplementedFunc), + /* 97 */ SyscallDesc("socket", unimplementedFunc), + /* 98 */ SyscallDesc("connect", unimplementedFunc), + /* 99 */ SyscallDesc("accept", unimplementedFunc), + /* 100 */ SyscallDesc("getpriority", unimplementedFunc), + /* 101 */ SyscallDesc("send", unimplementedFunc), + /* 102 */ SyscallDesc("recv", unimplementedFunc), + /* 103 */ SyscallDesc("sigreturn", unimplementedFunc), + /* 104 */ SyscallDesc("bind", unimplementedFunc), + /* 105 */ SyscallDesc("setsockopt", unimplementedFunc), + /* 106 */ SyscallDesc("listen", unimplementedFunc), + /* 107 */ SyscallDesc("osf_plock", unimplementedFunc), + /* 108 */ SyscallDesc("osf_old_sigvec", unimplementedFunc), + /* 109 */ SyscallDesc("osf_old_sigblock", unimplementedFunc), + /* 110 */ SyscallDesc("osf_old_sigsetmask", unimplementedFunc), + /* 111 */ SyscallDesc("sigsuspend", unimplementedFunc), + /* 112 */ SyscallDesc("osf_sigstack", ignoreFunc), + /* 113 */ SyscallDesc("recvmsg", unimplementedFunc), + /* 114 */ SyscallDesc("sendmsg", unimplementedFunc), + /* 115 */ SyscallDesc("osf_old_vtrace", unimplementedFunc), + /* 116 */ SyscallDesc("osf_gettimeofday", unimplementedFunc), + /* 117 */ SyscallDesc("osf_getrusage", unimplementedFunc), + /* 118 */ SyscallDesc("getsockopt", unimplementedFunc), + /* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc), + /* 120 */ SyscallDesc("readv", unimplementedFunc), + /* 121 */ SyscallDesc("writev", writevFunc), + /* 122 */ SyscallDesc("osf_settimeofday", unimplementedFunc), + /* 123 */ SyscallDesc("fchown", fchownFunc), + /* 124 */ SyscallDesc("fchmod", fchmodFunc), + /* 125 */ SyscallDesc("recvfrom", unimplementedFunc), + /* 126 */ SyscallDesc("setreuid", unimplementedFunc), + /* 127 */ SyscallDesc("setregid", unimplementedFunc), + /* 128 */ SyscallDesc("rename", renameFunc), + /* 129 */ SyscallDesc("truncate", unimplementedFunc), + /* 130 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 131 */ SyscallDesc("flock", unimplementedFunc), + /* 132 */ SyscallDesc("setgid", unimplementedFunc), + /* 133 */ SyscallDesc("sendto", unimplementedFunc), + /* 134 */ SyscallDesc("shutdown", unimplementedFunc), + /* 135 */ SyscallDesc("socketpair", unimplementedFunc), + /* 136 */ SyscallDesc("mkdir", unimplementedFunc), + /* 137 */ SyscallDesc("rmdir", unimplementedFunc), + /* 138 */ SyscallDesc("osf_utimes", unimplementedFunc), + /* 139 */ SyscallDesc("osf_old_sigreturn", unimplementedFunc), + /* 140 */ SyscallDesc("osf_adjtime", unimplementedFunc), + /* 141 */ SyscallDesc("getpeername", unimplementedFunc), + /* 142 */ SyscallDesc("osf_gethostid", unimplementedFunc), + /* 143 */ SyscallDesc("osf_sethostid", unimplementedFunc), + /* 144 */ SyscallDesc("getrlimit", getrlimitFunc), + /* 145 */ SyscallDesc("setrlimit", ignoreFunc), + /* 146 */ SyscallDesc("osf_old_killpg", unimplementedFunc), + /* 147 */ SyscallDesc("setsid", unimplementedFunc), + /* 148 */ SyscallDesc("quotactl", unimplementedFunc), + /* 149 */ SyscallDesc("osf_oldquota", unimplementedFunc), + /* 150 */ SyscallDesc("getsockname", unimplementedFunc), + /* 151 */ SyscallDesc("osf_pread", unimplementedFunc), + /* 152 */ SyscallDesc("osf_pwrite", unimplementedFunc), + /* 153 */ SyscallDesc("osf_pid_block", unimplementedFunc), + /* 154 */ SyscallDesc("osf_pid_unblock", unimplementedFunc), + /* 155 */ SyscallDesc("osf_signal_urti", unimplementedFunc), + /* 156 */ SyscallDesc("sigaction", ignoreFunc), + /* 157 */ SyscallDesc("osf_sigwaitprim", unimplementedFunc), + /* 158 */ SyscallDesc("osf_nfssvc", unimplementedFunc), + /* 159 */ SyscallDesc("osf_getdirentries", unimplementedFunc), + /* 160 */ SyscallDesc("osf_statfs", unimplementedFunc), + /* 161 */ SyscallDesc("osf_fstatfs", unimplementedFunc), + /* 162 */ SyscallDesc("unknown #162", unimplementedFunc), + /* 163 */ SyscallDesc("osf_async_daemon", unimplementedFunc), + /* 164 */ SyscallDesc("osf_getfh", unimplementedFunc), + /* 165 */ SyscallDesc("osf_getdomainname", unimplementedFunc), + /* 166 */ SyscallDesc("setdomainname", unimplementedFunc), + /* 167 */ SyscallDesc("unknown #167", unimplementedFunc), + /* 168 */ SyscallDesc("unknown #168", unimplementedFunc), + /* 169 */ SyscallDesc("osf_exportfs", unimplementedFunc), + /* 170 */ SyscallDesc("unknown #170", unimplementedFunc), + /* 171 */ SyscallDesc("unknown #171", unimplementedFunc), + /* 172 */ SyscallDesc("unknown #172", unimplementedFunc), + /* 173 */ SyscallDesc("unknown #173", unimplementedFunc), + /* 174 */ SyscallDesc("unknown #174", unimplementedFunc), + /* 175 */ SyscallDesc("unknown #175", unimplementedFunc), + /* 176 */ SyscallDesc("unknown #176", unimplementedFunc), + /* 177 */ SyscallDesc("unknown #177", unimplementedFunc), + /* 178 */ SyscallDesc("unknown #178", unimplementedFunc), + /* 179 */ SyscallDesc("unknown #179", unimplementedFunc), + /* 180 */ SyscallDesc("unknown #180", unimplementedFunc), + /* 181 */ SyscallDesc("osf_alt_plock", unimplementedFunc), + /* 182 */ SyscallDesc("unknown #182", unimplementedFunc), + /* 183 */ SyscallDesc("unknown #183", unimplementedFunc), + /* 184 */ SyscallDesc("osf_getmnt", unimplementedFunc), + /* 185 */ SyscallDesc("unknown #185", unimplementedFunc), + /* 186 */ SyscallDesc("unknown #186", unimplementedFunc), + /* 187 */ SyscallDesc("osf_alt_sigpending", unimplementedFunc), + /* 188 */ SyscallDesc("osf_alt_setsid", unimplementedFunc), + /* 189 */ SyscallDesc("unknown #189", unimplementedFunc), + /* 190 */ SyscallDesc("unknown #190", unimplementedFunc), + /* 191 */ SyscallDesc("unknown #191", unimplementedFunc), + /* 192 */ SyscallDesc("unknown #192", unimplementedFunc), + /* 193 */ SyscallDesc("unknown #193", unimplementedFunc), + /* 194 */ SyscallDesc("unknown #194", unimplementedFunc), + /* 195 */ SyscallDesc("unknown #195", unimplementedFunc), + /* 196 */ SyscallDesc("unknown #196", unimplementedFunc), + /* 197 */ SyscallDesc("unknown #197", unimplementedFunc), + /* 198 */ SyscallDesc("unknown #198", unimplementedFunc), + /* 199 */ SyscallDesc("osf_swapon", unimplementedFunc), + /* 200 */ SyscallDesc("msgctl", unimplementedFunc), + /* 201 */ SyscallDesc("msgget", unimplementedFunc), + /* 202 */ SyscallDesc("msgrcv", unimplementedFunc), + /* 203 */ SyscallDesc("msgsnd", unimplementedFunc), + /* 204 */ SyscallDesc("semctl", unimplementedFunc), + /* 205 */ SyscallDesc("semget", unimplementedFunc), + /* 206 */ SyscallDesc("semop", unimplementedFunc), + /* 207 */ SyscallDesc("osf_utsname", unimplementedFunc), + /* 208 */ SyscallDesc("lchown", unimplementedFunc), + /* 209 */ SyscallDesc("osf_shmat", unimplementedFunc), + /* 210 */ SyscallDesc("shmctl", unimplementedFunc), + /* 211 */ SyscallDesc("shmdt", unimplementedFunc), + /* 212 */ SyscallDesc("shmget", unimplementedFunc), + /* 213 */ SyscallDesc("osf_mvalid", unimplementedFunc), + /* 214 */ SyscallDesc("osf_getaddressconf", unimplementedFunc), + /* 215 */ SyscallDesc("osf_msleep", unimplementedFunc), + /* 216 */ SyscallDesc("osf_mwakeup", unimplementedFunc), + /* 217 */ SyscallDesc("msync", unimplementedFunc), + /* 218 */ SyscallDesc("osf_signal", unimplementedFunc), + /* 219 */ SyscallDesc("osf_utc_gettime", unimplementedFunc), + /* 220 */ SyscallDesc("osf_utc_adjtime", unimplementedFunc), + /* 221 */ SyscallDesc("unknown #221", unimplementedFunc), + /* 222 */ SyscallDesc("osf_security", unimplementedFunc), + /* 223 */ SyscallDesc("osf_kloadcall", unimplementedFunc), + /* 224 */ SyscallDesc("unknown #224", unimplementedFunc), + /* 225 */ SyscallDesc("unknown #225", unimplementedFunc), + /* 226 */ SyscallDesc("unknown #226", unimplementedFunc), + /* 227 */ SyscallDesc("unknown #227", unimplementedFunc), + /* 228 */ SyscallDesc("unknown #228", unimplementedFunc), + /* 229 */ SyscallDesc("unknown #229", unimplementedFunc), + /* 230 */ SyscallDesc("unknown #230", unimplementedFunc), + /* 231 */ SyscallDesc("unknown #231", unimplementedFunc), + /* 232 */ SyscallDesc("unknown #232", unimplementedFunc), + /* 233 */ SyscallDesc("getpgid", unimplementedFunc), + /* 234 */ SyscallDesc("getsid", unimplementedFunc), + /* 235 */ SyscallDesc("sigaltstack", ignoreFunc), + /* 236 */ SyscallDesc("osf_waitid", unimplementedFunc), + /* 237 */ SyscallDesc("osf_priocntlset", unimplementedFunc), + /* 238 */ SyscallDesc("osf_sigsendset", unimplementedFunc), + /* 239 */ SyscallDesc("osf_set_speculative", unimplementedFunc), + /* 240 */ SyscallDesc("osf_msfs_syscall", unimplementedFunc), + /* 241 */ SyscallDesc("osf_sysinfo", unimplementedFunc), + /* 242 */ SyscallDesc("osf_uadmin", unimplementedFunc), + /* 243 */ SyscallDesc("osf_fuser", unimplementedFunc), + /* 244 */ SyscallDesc("osf_proplist_syscall", unimplementedFunc), + /* 245 */ SyscallDesc("osf_ntp_adjtime", unimplementedFunc), + /* 246 */ SyscallDesc("osf_ntp_gettime", unimplementedFunc), + /* 247 */ SyscallDesc("osf_pathconf", unimplementedFunc), + /* 248 */ SyscallDesc("osf_fpathconf", unimplementedFunc), + /* 249 */ SyscallDesc("unknown #249", unimplementedFunc), + /* 250 */ SyscallDesc("osf_uswitch", unimplementedFunc), + /* 251 */ SyscallDesc("osf_usleep_thread", unimplementedFunc), + /* 252 */ SyscallDesc("osf_audcntl", unimplementedFunc), + /* 253 */ SyscallDesc("osf_audgen", unimplementedFunc), + /* 254 */ SyscallDesc("sysfs", unimplementedFunc), + /* 255 */ SyscallDesc("osf_subsys_info", unimplementedFunc), + /* 256 */ SyscallDesc("osf_getsysinfo", osf_getsysinfoFunc), + /* 257 */ SyscallDesc("osf_setsysinfo", osf_setsysinfoFunc), + /* 258 */ SyscallDesc("osf_afs_syscall", unimplementedFunc), + /* 259 */ SyscallDesc("osf_swapctl", unimplementedFunc), + /* 260 */ SyscallDesc("osf_memcntl", unimplementedFunc), + /* 261 */ SyscallDesc("osf_fdatasync", unimplementedFunc), + /* 262 */ SyscallDesc("unknown #262", unimplementedFunc), + /* 263 */ SyscallDesc("unknown #263", unimplementedFunc), + /* 264 */ SyscallDesc("unknown #264", unimplementedFunc), + /* 265 */ SyscallDesc("unknown #265", unimplementedFunc), + /* 266 */ SyscallDesc("unknown #266", unimplementedFunc), + /* 267 */ SyscallDesc("unknown #267", unimplementedFunc), + /* 268 */ SyscallDesc("unknown #268", unimplementedFunc), + /* 269 */ SyscallDesc("unknown #269", unimplementedFunc), + /* 270 */ SyscallDesc("unknown #270", unimplementedFunc), + /* 271 */ SyscallDesc("unknown #271", unimplementedFunc), + /* 272 */ SyscallDesc("unknown #272", unimplementedFunc), + /* 273 */ SyscallDesc("unknown #273", unimplementedFunc), + /* 274 */ SyscallDesc("unknown #274", unimplementedFunc), + /* 275 */ SyscallDesc("unknown #275", unimplementedFunc), + /* 276 */ SyscallDesc("unknown #276", unimplementedFunc), + /* 277 */ SyscallDesc("unknown #277", unimplementedFunc), + /* 278 */ SyscallDesc("unknown #278", unimplementedFunc), + /* 279 */ SyscallDesc("unknown #279", unimplementedFunc), + /* 280 */ SyscallDesc("unknown #280", unimplementedFunc), + /* 281 */ SyscallDesc("unknown #281", unimplementedFunc), + /* 282 */ SyscallDesc("unknown #282", unimplementedFunc), + /* 283 */ SyscallDesc("unknown #283", unimplementedFunc), + /* 284 */ SyscallDesc("unknown #284", unimplementedFunc), + /* 285 */ SyscallDesc("unknown #285", unimplementedFunc), + /* 286 */ SyscallDesc("unknown #286", unimplementedFunc), + /* 287 */ SyscallDesc("unknown #287", unimplementedFunc), + /* 288 */ SyscallDesc("unknown #288", unimplementedFunc), + /* 289 */ SyscallDesc("unknown #289", unimplementedFunc), + /* 290 */ SyscallDesc("unknown #290", unimplementedFunc), + /* 291 */ SyscallDesc("unknown #291", unimplementedFunc), + /* 292 */ SyscallDesc("unknown #292", unimplementedFunc), + /* 293 */ SyscallDesc("unknown #293", unimplementedFunc), + /* 294 */ SyscallDesc("unknown #294", unimplementedFunc), + /* 295 */ SyscallDesc("unknown #295", unimplementedFunc), + /* 296 */ SyscallDesc("unknown #296", unimplementedFunc), + /* 297 */ SyscallDesc("unknown #297", unimplementedFunc), + /* 298 */ SyscallDesc("unknown #298", unimplementedFunc), + /* 299 */ SyscallDesc("unknown #299", unimplementedFunc), +/* + * Linux-specific system calls begin at 300 + */ + /* 300 */ SyscallDesc("bdflush", unimplementedFunc), + /* 301 */ SyscallDesc("sethae", unimplementedFunc), + /* 302 */ SyscallDesc("mount", unimplementedFunc), + /* 303 */ SyscallDesc("old_adjtimex", unimplementedFunc), + /* 304 */ SyscallDesc("swapoff", unimplementedFunc), + /* 305 */ SyscallDesc("getdents", unimplementedFunc), + /* 306 */ SyscallDesc("create_module", unimplementedFunc), + /* 307 */ SyscallDesc("init_module", unimplementedFunc), + /* 308 */ SyscallDesc("delete_module", unimplementedFunc), + /* 309 */ SyscallDesc("get_kernel_syms", unimplementedFunc), + /* 310 */ SyscallDesc("syslog", unimplementedFunc), + /* 311 */ SyscallDesc("reboot", unimplementedFunc), + /* 312 */ SyscallDesc("clone", unimplementedFunc), + /* 313 */ SyscallDesc("uselib", unimplementedFunc), + /* 314 */ SyscallDesc("mlock", unimplementedFunc), + /* 315 */ SyscallDesc("munlock", unimplementedFunc), + /* 316 */ SyscallDesc("mlockall", unimplementedFunc), + /* 317 */ SyscallDesc("munlockall", unimplementedFunc), + /* 318 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 319 */ SyscallDesc("_sysctl", unimplementedFunc), + /* 320 */ SyscallDesc("was sys_idle", unimplementedFunc), + /* 321 */ SyscallDesc("oldumount", unimplementedFunc), + /* 322 */ SyscallDesc("swapon", unimplementedFunc), + /* 323 */ SyscallDesc("times", ignoreFunc), + /* 324 */ SyscallDesc("personality", unimplementedFunc), + /* 325 */ SyscallDesc("setfsuid", unimplementedFunc), + /* 326 */ SyscallDesc("setfsgid", unimplementedFunc), + /* 327 */ SyscallDesc("ustat", unimplementedFunc), + /* 328 */ SyscallDesc("statfs", unimplementedFunc), + /* 329 */ SyscallDesc("fstatfs", unimplementedFunc), + /* 330 */ SyscallDesc("sched_setparam", unimplementedFunc), + /* 331 */ SyscallDesc("sched_getparam", unimplementedFunc), + /* 332 */ SyscallDesc("sched_setscheduler", unimplementedFunc), + /* 333 */ SyscallDesc("sched_getscheduler", unimplementedFunc), + /* 334 */ SyscallDesc("sched_yield", unimplementedFunc), + /* 335 */ SyscallDesc("sched_get_priority_max", unimplementedFunc), + /* 336 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), + /* 337 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), + /* 338 */ SyscallDesc("afs_syscall", unimplementedFunc), + /* 339 */ SyscallDesc("uname", unameFunc), + /* 340 */ SyscallDesc("nanosleep", unimplementedFunc), + /* 341 */ SyscallDesc("mremap", unimplementedFunc), + /* 342 */ SyscallDesc("nfsservctl", unimplementedFunc), + /* 343 */ SyscallDesc("setresuid", unimplementedFunc), + /* 344 */ SyscallDesc("getresuid", unimplementedFunc), + /* 345 */ SyscallDesc("pciconfig_read", unimplementedFunc), + /* 346 */ SyscallDesc("pciconfig_write", unimplementedFunc), + /* 347 */ SyscallDesc("query_module", unimplementedFunc), + /* 348 */ SyscallDesc("prctl", unimplementedFunc), + /* 349 */ SyscallDesc("pread", unimplementedFunc), + /* 350 */ SyscallDesc("pwrite", unimplementedFunc), + /* 351 */ SyscallDesc("rt_sigreturn", unimplementedFunc), + /* 352 */ SyscallDesc("rt_sigaction", ignoreFunc), + /* 353 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), + /* 354 */ SyscallDesc("rt_sigpending", unimplementedFunc), + /* 355 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc), + /* 356 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc), + /* 357 */ SyscallDesc("rt_sigsuspend", unimplementedFunc), + /* 358 */ SyscallDesc("select", unimplementedFunc), + /* 359 */ SyscallDesc("gettimeofday", gettimeofdayFunc), + /* 360 */ SyscallDesc("settimeofday", unimplementedFunc), + /* 361 */ SyscallDesc("getitimer", unimplementedFunc), + /* 362 */ SyscallDesc("setitimer", unimplementedFunc), + /* 363 */ SyscallDesc("utimes", utimesFunc), + /* 364 */ SyscallDesc("getrusage", getrusageFunc), + /* 365 */ SyscallDesc("wait4", unimplementedFunc), + /* 366 */ SyscallDesc("adjtimex", unimplementedFunc), + /* 367 */ SyscallDesc("getcwd", unimplementedFunc), + /* 368 */ SyscallDesc("capget", unimplementedFunc), + /* 369 */ SyscallDesc("capset", unimplementedFunc), + /* 370 */ SyscallDesc("sendfile", unimplementedFunc), + /* 371 */ SyscallDesc("setresgid", unimplementedFunc), + /* 372 */ SyscallDesc("getresgid", unimplementedFunc), + /* 373 */ SyscallDesc("dipc", unimplementedFunc), + /* 374 */ SyscallDesc("pivot_root", unimplementedFunc), + /* 375 */ SyscallDesc("mincore", unimplementedFunc), + /* 376 */ SyscallDesc("pciconfig_iobase", unimplementedFunc), + /* 377 */ SyscallDesc("getdents64", unimplementedFunc), + /* 378 */ SyscallDesc("gettid", unimplementedFunc), + /* 379 */ SyscallDesc("readahead", unimplementedFunc), + /* 380 */ SyscallDesc("security", unimplementedFunc), + /* 381 */ SyscallDesc("tkill", unimplementedFunc), + /* 382 */ SyscallDesc("setxattr", unimplementedFunc), + /* 383 */ SyscallDesc("lsetxattr", unimplementedFunc), + /* 384 */ SyscallDesc("fsetxattr", unimplementedFunc), + /* 385 */ SyscallDesc("getxattr", unimplementedFunc), + /* 386 */ SyscallDesc("lgetxattr", unimplementedFunc), + /* 387 */ SyscallDesc("fgetxattr", unimplementedFunc), + /* 388 */ SyscallDesc("listxattr", unimplementedFunc), + /* 389 */ SyscallDesc("llistxattr", unimplementedFunc), + /* 390 */ SyscallDesc("flistxattr", unimplementedFunc), + /* 391 */ SyscallDesc("removexattr", unimplementedFunc), + /* 392 */ SyscallDesc("lremovexattr", unimplementedFunc), + /* 393 */ SyscallDesc("fremovexattr", unimplementedFunc), + /* 394 */ SyscallDesc("futex", unimplementedFunc), + /* 395 */ SyscallDesc("sched_setaffinity", unimplementedFunc), + /* 396 */ SyscallDesc("sched_getaffinity", unimplementedFunc), + /* 397 */ SyscallDesc("tuxcall", unimplementedFunc), + /* 398 */ SyscallDesc("io_setup", unimplementedFunc), + /* 399 */ SyscallDesc("io_destroy", unimplementedFunc), + /* 400 */ SyscallDesc("io_getevents", unimplementedFunc), + /* 401 */ SyscallDesc("io_submit", unimplementedFunc), + /* 402 */ SyscallDesc("io_cancel", unimplementedFunc), + /* 403 */ SyscallDesc("unknown #403", unimplementedFunc), + /* 404 */ SyscallDesc("unknown #404", unimplementedFunc), + /* 405 */ SyscallDesc("exit_group", exitFunc), // exit all threads... + /* 406 */ SyscallDesc("lookup_dcookie", unimplementedFunc), + /* 407 */ SyscallDesc("sys_epoll_create", unimplementedFunc), + /* 408 */ SyscallDesc("sys_epoll_ctl", unimplementedFunc), + /* 409 */ SyscallDesc("sys_epoll_wait", unimplementedFunc), + /* 410 */ SyscallDesc("remap_file_pages", unimplementedFunc), + /* 411 */ SyscallDesc("set_tid_address", unimplementedFunc), + /* 412 */ SyscallDesc("restart_syscall", unimplementedFunc), + /* 413 */ SyscallDesc("fadvise64", unimplementedFunc), + /* 414 */ SyscallDesc("timer_create", unimplementedFunc), + /* 415 */ SyscallDesc("timer_settime", unimplementedFunc), + /* 416 */ SyscallDesc("timer_gettime", unimplementedFunc), + /* 417 */ SyscallDesc("timer_getoverrun", unimplementedFunc), + /* 418 */ SyscallDesc("timer_delete", unimplementedFunc), + /* 419 */ SyscallDesc("clock_settime", unimplementedFunc), + /* 420 */ SyscallDesc("clock_gettime", unimplementedFunc), + /* 421 */ SyscallDesc("clock_getres", unimplementedFunc), + /* 422 */ SyscallDesc("clock_nanosleep", unimplementedFunc), + /* 423 */ SyscallDesc("semtimedop", unimplementedFunc), + /* 424 */ SyscallDesc("tgkill", unimplementedFunc), + /* 425 */ SyscallDesc("stat64", unimplementedFunc), + /* 426 */ SyscallDesc("lstat64", lstat64Func), + /* 427 */ SyscallDesc("fstat64", fstat64Func), + /* 428 */ SyscallDesc("vserver", unimplementedFunc), + /* 429 */ SyscallDesc("mbind", unimplementedFunc), + /* 430 */ SyscallDesc("get_mempolicy", unimplementedFunc), + /* 431 */ SyscallDesc("set_mempolicy", unimplementedFunc), + /* 432 */ SyscallDesc("mq_open", unimplementedFunc), + /* 433 */ SyscallDesc("mq_unlink", unimplementedFunc), + /* 434 */ SyscallDesc("mq_timedsend", unimplementedFunc), + /* 435 */ SyscallDesc("mq_timedreceive", unimplementedFunc), + /* 436 */ SyscallDesc("mq_notify", unimplementedFunc), + /* 437 */ SyscallDesc("mq_getsetattr", unimplementedFunc), + /* 438 */ SyscallDesc("waitid", unimplementedFunc), + /* 439 */ SyscallDesc("add_key", unimplementedFunc), + /* 440 */ SyscallDesc("request_key", unimplementedFunc), + /* 441 */ SyscallDesc("keyctl", unimplementedFunc) +}; + +AlphaLinuxProcess::AlphaLinuxProcess(const std::string &name, + ObjectFile *objFile, + int stdin_fd, + int stdout_fd, + int stderr_fd, + std::vector &argv, + std::vector &envp) + : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp), + Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) +{ + init_regs->intRegFile[0] = 0; +} + + + +SyscallDesc* +AlphaLinuxProcess::getDesc(int callnum) +{ + if (callnum < 0 || callnum > Num_Syscall_Descs) + return NULL; + return &syscallDescs[callnum]; +} diff --cc arch/alpha/tlb.cc index 0f2cedc83,000000000..e30a8e595 mode 100644,000000..100644 --- a/arch/alpha/tlb.cc +++ b/arch/alpha/tlb.cc @@@ -1,686 -1,0 +1,685 @@@ +/* + * Copyright (c) 2001-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 +#include +#include + +#include "arch/alpha/tlb.hh" +#include "base/inifile.hh" +#include "base/str.hh" +#include "base/trace.hh" +#include "config/alpha_tlaser.hh" +#include "cpu/exec_context.hh" +#include "sim/builder.hh" + +using namespace std; +using namespace EV5; + +/////////////////////////////////////////////////////////////////////// +// +// Alpha TLB +// +#ifdef DEBUG +bool uncacheBit39 = false; +bool uncacheBit40 = false; +#endif + +#define MODE2MASK(X) (1 << (X)) + +AlphaTLB::AlphaTLB(const string &name, int s) + : SimObject(name), size(s), nlu(0) +{ + table = new AlphaISA::PTE[size]; + memset(table, 0, sizeof(AlphaISA::PTE[size])); +} + +AlphaTLB::~AlphaTLB() +{ + if (table) + delete [] table; +} + +// look up an entry in the TLB +AlphaISA::PTE * +AlphaTLB::lookup(Addr vpn, uint8_t asn) const +{ + // assume not found... + AlphaISA::PTE *retval = NULL; + + PageTable::const_iterator i = lookupTable.find(vpn); + if (i != lookupTable.end()) { + while (i->first == vpn) { + int index = i->second; + AlphaISA::PTE *pte = &table[index]; + assert(pte->valid); + if (vpn == pte->tag && (pte->asma || pte->asn == asn)) { + retval = pte; + break; + } + + ++i; + } + } + + DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, + retval ? "hit" : "miss", retval ? retval->ppn : 0); + return retval; +} + + +void +AlphaTLB::checkCacheability(MemReqPtr &req) +{ + // in Alpha, cacheability is controlled by upper-level bits of the + // physical address + + /* + * We support having the uncacheable bit in either bit 39 or bit 40. + * The Turbolaser platform (and EV5) support having the bit in 39, but + * Tsunami (which Linux assumes uses an EV6) generates accesses with + * the bit in 40. So we must check for both, but we have debug flags + * to catch a weird case where both are used, which shouldn't happen. + */ + + +#if ALPHA_TLASER + if (req->paddr & PAddrUncachedBit39) { +#else + if (req->paddr & PAddrUncachedBit43) { +#endif + // IPR memory space not implemented + if (PAddrIprSpace(req->paddr)) { + if (!req->xc->misspeculating()) { + switch (req->paddr) { + case ULL(0xFFFFF00188): + req->data = 0; + break; + + default: + panic("IPR memory space not implemented! PA=%x\n", + req->paddr); + } + } + } else { + // mark request as uncacheable + req->flags |= UNCACHEABLE; + +#if !ALPHA_TLASER + // Clear bits 42:35 of the physical address (10-2 in Tsunami manual) + req->paddr &= PAddrUncachedMask; +#endif + } + } +} + + +// insert a new TLB entry +void +AlphaTLB::insert(Addr addr, AlphaISA::PTE &pte) +{ + AlphaISA::VAddr vaddr = addr; + if (table[nlu].valid) { + Addr oldvpn = table[nlu].tag; + PageTable::iterator i = lookupTable.find(oldvpn); + + if (i == lookupTable.end()) + panic("TLB entry not found in lookupTable"); + + int index; + while ((index = i->second) != nlu) { + if (table[index].tag != oldvpn) + panic("TLB entry not found in lookupTable"); + + ++i; + } + + DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); + + lookupTable.erase(i); + } + + DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn); + + table[nlu] = pte; + table[nlu].tag = vaddr.vpn(); + table[nlu].valid = true; + + lookupTable.insert(make_pair(vaddr.vpn(), nlu)); + nextnlu(); +} + +void +AlphaTLB::flushAll() +{ + DPRINTF(TLB, "flushAll\n"); + memset(table, 0, sizeof(AlphaISA::PTE[size])); + lookupTable.clear(); + nlu = 0; +} + +void +AlphaTLB::flushProcesses() +{ + PageTable::iterator i = lookupTable.begin(); + PageTable::iterator end = lookupTable.end(); + while (i != end) { + int index = i->second; + AlphaISA::PTE *pte = &table[index]; + assert(pte->valid); + + // we can't increment i after we erase it, so save a copy and + // increment it to get the next entry now + PageTable::iterator cur = i; + ++i; + + if (!pte->asma) { + DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); + pte->valid = false; + lookupTable.erase(cur); + } + } +} + +void +AlphaTLB::flushAddr(Addr addr, uint8_t asn) +{ + AlphaISA::VAddr vaddr = addr; + + PageTable::iterator i = lookupTable.find(vaddr.vpn()); + if (i == lookupTable.end()) + return; + + while (i->first == vaddr.vpn()) { + int index = i->second; + AlphaISA::PTE *pte = &table[index]; + assert(pte->valid); + + if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) { + DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(), + pte->ppn); + + // invalidate this entry + pte->valid = false; + + lookupTable.erase(i); + } + + ++i; + } +} + + +void +AlphaTLB::serialize(ostream &os) +{ + SERIALIZE_SCALAR(size); + SERIALIZE_SCALAR(nlu); + + for (int i = 0; i < size; i++) { + nameOut(os, csprintf("%s.PTE%d", name(), i)); + table[i].serialize(os); + } +} + +void +AlphaTLB::unserialize(Checkpoint *cp, const string §ion) +{ + UNSERIALIZE_SCALAR(size); + UNSERIALIZE_SCALAR(nlu); + + for (int i = 0; i < size; i++) { + table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); + if (table[i].valid) { + lookupTable.insert(make_pair(table[i].tag, i)); + } + } +} + + +/////////////////////////////////////////////////////////////////////// +// +// Alpha ITB +// +AlphaITB::AlphaITB(const std::string &name, int size) + : AlphaTLB(name, size) +{} + + +void +AlphaITB::regStats() +{ + hits + .name(name() + ".hits") + .desc("ITB hits"); + misses + .name(name() + ".misses") + .desc("ITB misses"); + acv + .name(name() + ".acv") + .desc("ITB acv"); + accesses + .name(name() + ".accesses") + .desc("ITB accesses"); + + accesses = hits + misses; +} + +void +AlphaITB::fault(Addr pc, ExecContext *xc) const +{ + if (!xc->misspeculating()) { + xc->setMiscReg(AlphaISA::IPR_ITB_TAG, pc); + xc->setMiscReg(AlphaISA::IPR_IFAULT_VA_FORM, + xc->readMiscReg(AlphaISA::IPR_IVPTBR) | + (AlphaISA::VAddr(pc).vpn() << 3)); + } +} + + +Fault +AlphaITB::translate(MemReqPtr &req) const +{ + ExecContext *xc = req->xc; + + if (AlphaISA::PcPAL(req->vaddr)) { + // strip off PAL PC marker (lsb is 1) + req->paddr = (req->vaddr & ~3) & PAddrImplMask; + hits++; + return NoFault; + } + + if (req->flags & PHYSICAL) { + req->paddr = req->vaddr; + } else { + // verify that this is a good virtual address + if (!validVirtualAddress(req->vaddr)) { + fault(req->vaddr, req->xc); + acv++; + return new ItbAcvFault; + } + + + // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5 + // 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) { +#else + if (VAddrSpaceEV6(req->vaddr) == 0x7e) { +#endif + // only valid in kernel mode + if (ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM)) != + AlphaISA::mode_kernel) { + fault(req->vaddr, req->xc); + acv++; + return new ItbAcvFault; + } + + req->paddr = req->vaddr & PAddrImplMask; + +#if !ALPHA_TLASER + // sign extend the physical address properly + if (req->paddr & PAddrUncachedBit40) + req->paddr |= ULL(0xf0000000000); + else + req->paddr &= 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(), + asn); + + if (!pte) { + fault(req->vaddr, req->xc); + misses++; + return new ItbPageFault; + } + + req->paddr = (pte->ppn << AlphaISA::PageShift) + + (AlphaISA::VAddr(req->vaddr).offset() & ~3); + + // check permissions for this access + if (!(pte->xre & + (1 << ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM))))) { + // instruction access fault + fault(req->vaddr, req->xc); + acv++; + return new ItbAcvFault; + } + + hits++; + } + } + + // check that the physical address is ok (catch bad physical addresses) + if (req->paddr & ~PAddrImplMask) + return genMachineCheckFault(); + + checkCacheability(req); + + return NoFault; +} + +/////////////////////////////////////////////////////////////////////// +// +// Alpha DTB +// +AlphaDTB::AlphaDTB(const std::string &name, int size) + : AlphaTLB(name, size) +{} + +void +AlphaDTB::regStats() +{ + read_hits + .name(name() + ".read_hits") + .desc("DTB read hits") + ; + + read_misses + .name(name() + ".read_misses") + .desc("DTB read misses") + ; + + read_acv + .name(name() + ".read_acv") + .desc("DTB read access violations") + ; + + read_accesses + .name(name() + ".read_accesses") + .desc("DTB read accesses") + ; + + write_hits + .name(name() + ".write_hits") + .desc("DTB write hits") + ; + + write_misses + .name(name() + ".write_misses") + .desc("DTB write misses") + ; + + write_acv + .name(name() + ".write_acv") + .desc("DTB write access violations") + ; + + write_accesses + .name(name() + ".write_accesses") + .desc("DTB write accesses") + ; + + hits + .name(name() + ".hits") + .desc("DTB hits") + ; + + misses + .name(name() + ".misses") + .desc("DTB misses") + ; + + acv + .name(name() + ".acv") + .desc("DTB access violations") + ; + + accesses + .name(name() + ".accesses") + .desc("DTB accesses") + ; + + hits = read_hits + write_hits; + misses = read_misses + write_misses; + acv = read_acv + write_acv; + accesses = read_accesses + write_accesses; +} + +void +AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const +{ + ExecContext *xc = req->xc; + AlphaISA::VAddr vaddr = req->vaddr; + + // Set fault address and flags. Even though we're modeling an + // EV5, we use the EV6 technique of not latching fault registers + // on VPTE loads (instead of locking the registers until IPR_VA is + // read, like the EV5). The EV6 approach is cleaner and seems to + // work with EV5 PAL code, but not the other way around. + if (!xc->misspeculating() + && !(req->flags & VPTE) && !(req->flags & NO_FAULT)) { + // set VA register with faulting address + xc->setMiscReg(AlphaISA::IPR_VA, req->vaddr); + + // set MM_STAT register flags + xc->setMiscReg(AlphaISA::IPR_MM_STAT, + (((Opcode(xc->getInst()) & 0x3f) << 11) + | ((Ra(xc->getInst()) & 0x1f) << 6) + | (flags & 0x3f))); + + // set VA_FORM register with faulting formatted address + xc->setMiscReg(AlphaISA::IPR_VA_FORM, + xc->readMiscReg(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3)); + } +} + +Fault +AlphaDTB::translate(MemReqPtr &req, bool write) const +{ - RegFile *regs = &req->xc->regs; + ExecContext *xc = req->xc; - Addr pc = regs->pc; ++ Addr pc = xc->readPC(); + + AlphaISA::mode_type mode = + (AlphaISA::mode_type)DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)); + + + /** + * Check for alignment faults + */ + if (req->vaddr & (req->size - 1)) { + fault(req, write ? MM_STAT_WR_MASK : 0); + DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr, + req->size); + return genAlignmentFault(); + } + + if (pc & 0x1) { + mode = (req->flags & ALTMODE) ? + (AlphaISA::mode_type)ALT_MODE_AM( + xc->readMiscReg(AlphaISA::IPR_ALT_MODE)) + : AlphaISA::mode_kernel; + } + + if (req->flags & PHYSICAL) { + req->paddr = req->vaddr; + } else { + // verify that this is a good virtual address + if (!validVirtualAddress(req->vaddr)) { + fault(req, (write ? MM_STAT_WR_MASK : 0) | + MM_STAT_BAD_VA_MASK | + MM_STAT_ACV_MASK); + + if (write) { write_acv++; } else { read_acv++; } + return new DtbPageFault; + } + + // Check for "superpage" mapping +#if ALPHA_TLASER + if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && + VAddrSpaceEV5(req->vaddr) == 2) { +#else + if (VAddrSpaceEV6(req->vaddr) == 0x7e) { +#endif + + // only valid in kernel mode + if (DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)) != + AlphaISA::mode_kernel) { + fault(req, ((write ? MM_STAT_WR_MASK : 0) | + MM_STAT_ACV_MASK)); + if (write) { write_acv++; } else { read_acv++; } + return new DtbAcvFault; + } + + req->paddr = req->vaddr & PAddrImplMask; + +#if !ALPHA_TLASER + // sign extend the physical address properly + if (req->paddr & PAddrUncachedBit40) + req->paddr |= ULL(0xf0000000000); + else + req->paddr &= ULL(0xffffffffff); +#endif + + } else { + if (write) + write_accesses++; + else + read_accesses++; + + 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(), + asn); + + if (!pte) { + // page fault + fault(req, (write ? MM_STAT_WR_MASK : 0) | + MM_STAT_DTB_MISS_MASK); + if (write) { write_misses++; } else { read_misses++; } + return (req->flags & VPTE) ? + (Fault)(new PDtbMissFault) : + (Fault)(new NDtbMissFault); + } + + req->paddr = (pte->ppn << AlphaISA::PageShift) + + AlphaISA::VAddr(req->vaddr).offset(); + + if (write) { + if (!(pte->xwe & MODE2MASK(mode))) { + // declare the instruction access fault + fault(req, MM_STAT_WR_MASK | + MM_STAT_ACV_MASK | + (pte->fonw ? MM_STAT_FONW_MASK : 0)); + write_acv++; + return new DtbPageFault; + } + if (pte->fonw) { + fault(req, MM_STAT_WR_MASK | + MM_STAT_FONW_MASK); + write_acv++; + return new DtbPageFault; + } + } else { + if (!(pte->xre & MODE2MASK(mode))) { + fault(req, MM_STAT_ACV_MASK | + (pte->fonr ? MM_STAT_FONR_MASK : 0)); + read_acv++; + return new DtbAcvFault; + } + if (pte->fonr) { + fault(req, MM_STAT_FONR_MASK); + read_acv++; + return new DtbPageFault; + } + } + } + + if (write) + write_hits++; + else + read_hits++; + } + + // check that the physical address is ok (catch bad physical addresses) + if (req->paddr & ~PAddrImplMask) + return genMachineCheckFault(); + + checkCacheability(req); + + return NoFault; +} + +AlphaISA::PTE & +AlphaTLB::index(bool advance) +{ + AlphaISA::PTE *pte = &table[nlu]; + + if (advance) + nextnlu(); + + return *pte; +} + +DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", AlphaTLB) + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaITB) + + Param size; + +END_DECLARE_SIM_OBJECT_PARAMS(AlphaITB) + +BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaITB) + + INIT_PARAM_DFLT(size, "TLB size", 48) + +END_INIT_SIM_OBJECT_PARAMS(AlphaITB) + + +CREATE_SIM_OBJECT(AlphaITB) +{ + return new AlphaITB(getInstanceName(), size); +} + +REGISTER_SIM_OBJECT("AlphaITB", AlphaITB) + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB) + + Param size; + +END_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB) + +BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDTB) + + INIT_PARAM_DFLT(size, "TLB size", 64) + +END_INIT_SIM_OBJECT_PARAMS(AlphaDTB) + + +CREATE_SIM_OBJECT(AlphaDTB) +{ + return new AlphaDTB(getInstanceName(), size); +} + +REGISTER_SIM_OBJECT("AlphaDTB", AlphaDTB) + diff --cc arch/alpha/tru64_process.cc index 90e8b1139,000000000..5f6b802e9 mode 100644,000000..100644 --- a/arch/alpha/tru64_process.cc +++ b/arch/alpha/tru64_process.cc @@@ -1,544 -1,0 +1,544 @@@ +/* + * Copyright (c) 2001-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/isa_traits.hh" +#include "arch/alpha/common_syscall_emul.hh" +#include "arch/alpha/tru64_process.hh" +#include "cpu/exec_context.hh" +#include "kern/tru64/tru64.hh" +#include "mem/functional/functional.hh" +#include "sim/fake_syscall.hh" +#include "sim/process.hh" +#include "sim/syscall_emul.hh" + +using namespace std; +using namespace AlphaISA; + +/// Target uname() handler. +static SyscallReturn +unameFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + TypedBufferArg name(xc->getSyscallArg(0)); + + strcpy(name->sysname, "OSF1"); + strcpy(name->nodename, "m5.eecs.umich.edu"); + strcpy(name->release, "V5.1"); + strcpy(name->version, "732"); + strcpy(name->machine, "alpha"); + - name.copyOut(xc->mem); ++ name.copyOut(xc->getMemPtr()); + return 0; +} + +/// Target getsysyinfo() handler. +static SyscallReturn +getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + unsigned op = xc->getSyscallArg(0); + unsigned nbytes = xc->getSyscallArg(2); + + switch (op) { + + case Tru64::GSI_MAX_CPU: { + TypedBufferArg max_cpu(xc->getSyscallArg(1)); + *max_cpu = htog((uint32_t)process->numCpus()); - max_cpu.copyOut(xc->mem); ++ max_cpu.copyOut(xc->getMemPtr()); + return 1; + } + + case Tru64::GSI_CPUS_IN_BOX: { + TypedBufferArg cpus_in_box(xc->getSyscallArg(1)); + *cpus_in_box = htog((uint32_t)process->numCpus()); - cpus_in_box.copyOut(xc->mem); ++ cpus_in_box.copyOut(xc->getMemPtr()); + return 1; + } + + case Tru64::GSI_PHYSMEM: { + TypedBufferArg physmem(xc->getSyscallArg(1)); + *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB - physmem.copyOut(xc->mem); ++ physmem.copyOut(xc->getMemPtr()); + return 1; + } + + case Tru64::GSI_CPU_INFO: { + TypedBufferArg infop(xc->getSyscallArg(1)); + + infop->current_cpu = htog(0); + infop->cpus_in_box = htog(process->numCpus()); + infop->cpu_type = htog(57); + infop->ncpus = htog(process->numCpus()); + uint64_t cpumask = (1 << process->numCpus()) - 1; + infop->cpus_present = infop->cpus_running = htog(cpumask); + infop->cpu_binding = htog(0); + infop->cpu_ex_binding = htog(0); + infop->mhz = htog(667); + - infop.copyOut(xc->mem); ++ infop.copyOut(xc->getMemPtr()); + return 1; + } + + case Tru64::GSI_PROC_TYPE: { + TypedBufferArg proc_type(xc->getSyscallArg(1)); + *proc_type = htog((uint64_t)11); - proc_type.copyOut(xc->mem); ++ proc_type.copyOut(xc->getMemPtr()); + return 1; + } + + case Tru64::GSI_PLATFORM_NAME: { + BufferArg bufArg(xc->getSyscallArg(1), nbytes); + strncpy((char *)bufArg.bufferPtr(), + "COMPAQ Professional Workstation XP1000", + nbytes); - bufArg.copyOut(xc->mem); ++ bufArg.copyOut(xc->getMemPtr()); + return 1; + } + + case Tru64::GSI_CLK_TCK: { + TypedBufferArg clk_hz(xc->getSyscallArg(1)); + *clk_hz = htog((uint64_t)1024); - clk_hz.copyOut(xc->mem); ++ clk_hz.copyOut(xc->getMemPtr()); + return 1; + } + + default: + warn("getsysinfo: unknown op %d\n", op); + break; + } + + return 0; +} + +/// Target setsysyinfo() handler. +static SyscallReturn +setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + unsigned op = xc->getSyscallArg(0); + + switch (op) { + case Tru64::SSI_IEEE_FP_CONTROL: + warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n", + xc->getSyscallArg(1)); + break; + + default: + warn("setsysinfo: unknown op %d\n", op); + break; + } + + return 0; +} + + +SyscallDesc AlphaTru64Process::syscallDescs[] = { + /* 0 */ SyscallDesc("syscall (#0)", Tru64::indirectSyscallFunc, + SyscallDesc::SuppressReturnValue), + /* 1 */ SyscallDesc("exit", exitFunc), + /* 2 */ SyscallDesc("fork", unimplementedFunc), + /* 3 */ SyscallDesc("read", readFunc), + /* 4 */ SyscallDesc("write", writeFunc), + /* 5 */ SyscallDesc("old_open", unimplementedFunc), + /* 6 */ SyscallDesc("close", closeFunc), + /* 7 */ SyscallDesc("wait4", unimplementedFunc), + /* 8 */ SyscallDesc("old_creat", unimplementedFunc), + /* 9 */ SyscallDesc("link", unimplementedFunc), + /* 10 */ SyscallDesc("unlink", unlinkFunc), + /* 11 */ SyscallDesc("execv", unimplementedFunc), + /* 12 */ SyscallDesc("chdir", unimplementedFunc), + /* 13 */ SyscallDesc("fchdir", unimplementedFunc), + /* 14 */ SyscallDesc("mknod", unimplementedFunc), + /* 15 */ SyscallDesc("chmod", unimplementedFunc), + /* 16 */ SyscallDesc("chown", unimplementedFunc), + /* 17 */ SyscallDesc("obreak", obreakFunc), + /* 18 */ SyscallDesc("pre_F64_getfsstat", unimplementedFunc), + /* 19 */ SyscallDesc("lseek", lseekFunc), + /* 20 */ SyscallDesc("getpid", getpidFunc), + /* 21 */ SyscallDesc("mount", unimplementedFunc), + /* 22 */ SyscallDesc("unmount", unimplementedFunc), + /* 23 */ SyscallDesc("setuid", setuidFunc), + /* 24 */ SyscallDesc("getuid", getuidFunc), + /* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc), + /* 26 */ SyscallDesc("ptrace", unimplementedFunc), + /* 27 */ SyscallDesc("recvmsg", unimplementedFunc), + /* 28 */ SyscallDesc("sendmsg", unimplementedFunc), + /* 29 */ SyscallDesc("recvfrom", unimplementedFunc), + /* 30 */ SyscallDesc("accept", unimplementedFunc), + /* 31 */ SyscallDesc("getpeername", unimplementedFunc), + /* 32 */ SyscallDesc("getsockname", unimplementedFunc), + /* 33 */ SyscallDesc("access", unimplementedFunc), + /* 34 */ SyscallDesc("chflags", unimplementedFunc), + /* 35 */ SyscallDesc("fchflags", unimplementedFunc), + /* 36 */ SyscallDesc("sync", unimplementedFunc), + /* 37 */ SyscallDesc("kill", unimplementedFunc), + /* 38 */ SyscallDesc("old_stat", unimplementedFunc), + /* 39 */ SyscallDesc("setpgid", unimplementedFunc), + /* 40 */ SyscallDesc("old_lstat", unimplementedFunc), + /* 41 */ SyscallDesc("dup", unimplementedFunc), + /* 42 */ SyscallDesc("pipe", unimplementedFunc), + /* 43 */ SyscallDesc("set_program_attributes", unimplementedFunc), + /* 44 */ SyscallDesc("profil", unimplementedFunc), + /* 45 */ SyscallDesc("open", openFunc), + /* 46 */ SyscallDesc("obsolete osigaction", unimplementedFunc), + /* 47 */ SyscallDesc("getgid", getgidFunc), + /* 48 */ SyscallDesc("sigprocmask", ignoreFunc), + /* 49 */ SyscallDesc("getlogin", unimplementedFunc), + /* 50 */ SyscallDesc("setlogin", unimplementedFunc), + /* 51 */ SyscallDesc("acct", unimplementedFunc), + /* 52 */ SyscallDesc("sigpending", unimplementedFunc), + /* 53 */ SyscallDesc("classcntl", unimplementedFunc), + /* 54 */ SyscallDesc("ioctl", ioctlFunc), + /* 55 */ SyscallDesc("reboot", unimplementedFunc), + /* 56 */ SyscallDesc("revoke", unimplementedFunc), + /* 57 */ SyscallDesc("symlink", unimplementedFunc), + /* 58 */ SyscallDesc("readlink", unimplementedFunc), + /* 59 */ SyscallDesc("execve", unimplementedFunc), + /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 61 */ SyscallDesc("chroot", unimplementedFunc), + /* 62 */ SyscallDesc("old_fstat", unimplementedFunc), + /* 63 */ SyscallDesc("getpgrp", unimplementedFunc), + /* 64 */ SyscallDesc("getpagesize", getpagesizeFunc), + /* 65 */ SyscallDesc("mremap", unimplementedFunc), + /* 66 */ SyscallDesc("vfork", unimplementedFunc), + /* 67 */ SyscallDesc("pre_F64_stat", statFunc), + /* 68 */ SyscallDesc("pre_F64_lstat", lstatFunc), + /* 69 */ SyscallDesc("sbrk", unimplementedFunc), + /* 70 */ SyscallDesc("sstk", unimplementedFunc), + /* 71 */ SyscallDesc("mmap", mmapFunc), + /* 72 */ SyscallDesc("ovadvise", unimplementedFunc), + /* 73 */ SyscallDesc("munmap", munmapFunc), + /* 74 */ SyscallDesc("mprotect", ignoreFunc), + /* 75 */ SyscallDesc("madvise", unimplementedFunc), + /* 76 */ SyscallDesc("old_vhangup", unimplementedFunc), + /* 77 */ SyscallDesc("kmodcall", unimplementedFunc), + /* 78 */ SyscallDesc("mincore", unimplementedFunc), + /* 79 */ SyscallDesc("getgroups", unimplementedFunc), + /* 80 */ SyscallDesc("setgroups", unimplementedFunc), + /* 81 */ SyscallDesc("old_getpgrp", unimplementedFunc), + /* 82 */ SyscallDesc("setpgrp", unimplementedFunc), + /* 83 */ SyscallDesc("setitimer", unimplementedFunc), + /* 84 */ SyscallDesc("old_wait", unimplementedFunc), + /* 85 */ SyscallDesc("table", Tru64::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), + /* 92 */ SyscallDesc("fcntl", fcntlFunc), + /* 93 */ SyscallDesc("select", unimplementedFunc), + /* 94 */ SyscallDesc("poll", unimplementedFunc), + /* 95 */ SyscallDesc("fsync", unimplementedFunc), + /* 96 */ SyscallDesc("setpriority", unimplementedFunc), + /* 97 */ SyscallDesc("socket", unimplementedFunc), + /* 98 */ SyscallDesc("connect", unimplementedFunc), + /* 99 */ SyscallDesc("old_accept", unimplementedFunc), + /* 100 */ SyscallDesc("getpriority", unimplementedFunc), + /* 101 */ SyscallDesc("old_send", unimplementedFunc), + /* 102 */ SyscallDesc("old_recv", unimplementedFunc), + /* 103 */ SyscallDesc("sigreturn", Tru64::sigreturnFunc, + SyscallDesc::SuppressReturnValue), + /* 104 */ SyscallDesc("bind", unimplementedFunc), + /* 105 */ SyscallDesc("setsockopt", unimplementedFunc), + /* 106 */ SyscallDesc("listen", unimplementedFunc), + /* 107 */ SyscallDesc("plock", unimplementedFunc), + /* 108 */ SyscallDesc("old_sigvec", unimplementedFunc), + /* 109 */ SyscallDesc("old_sigblock", unimplementedFunc), + /* 110 */ SyscallDesc("old_sigsetmask", unimplementedFunc), + /* 111 */ SyscallDesc("sigsuspend", unimplementedFunc), + /* 112 */ SyscallDesc("sigstack", ignoreFunc), + /* 113 */ SyscallDesc("old_recvmsg", unimplementedFunc), + /* 114 */ SyscallDesc("old_sendmsg", unimplementedFunc), + /* 115 */ SyscallDesc("obsolete vtrace", unimplementedFunc), + /* 116 */ SyscallDesc("gettimeofday", gettimeofdayFunc), + /* 117 */ SyscallDesc("getrusage", getrusageFunc), + /* 118 */ SyscallDesc("getsockopt", unimplementedFunc), + /* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc), + /* 120 */ SyscallDesc("readv", unimplementedFunc), + /* 121 */ SyscallDesc("writev", unimplementedFunc), + /* 122 */ SyscallDesc("settimeofday", unimplementedFunc), + /* 123 */ SyscallDesc("fchown", unimplementedFunc), + /* 124 */ SyscallDesc("fchmod", unimplementedFunc), + /* 125 */ SyscallDesc("old_recvfrom", unimplementedFunc), + /* 126 */ SyscallDesc("setreuid", unimplementedFunc), + /* 127 */ SyscallDesc("setregid", unimplementedFunc), + /* 128 */ SyscallDesc("rename", renameFunc), + /* 129 */ SyscallDesc("truncate", truncateFunc), + /* 130 */ SyscallDesc("ftruncate", ftruncateFunc), + /* 131 */ SyscallDesc("flock", unimplementedFunc), + /* 132 */ SyscallDesc("setgid", unimplementedFunc), + /* 133 */ SyscallDesc("sendto", unimplementedFunc), + /* 134 */ SyscallDesc("shutdown", unimplementedFunc), + /* 135 */ SyscallDesc("socketpair", unimplementedFunc), + /* 136 */ SyscallDesc("mkdir", unimplementedFunc), + /* 137 */ SyscallDesc("rmdir", unimplementedFunc), + /* 138 */ SyscallDesc("utimes", unimplementedFunc), + /* 139 */ SyscallDesc("obsolete 4.2 sigreturn", unimplementedFunc), + /* 140 */ SyscallDesc("adjtime", unimplementedFunc), + /* 141 */ SyscallDesc("old_getpeername", unimplementedFunc), + /* 142 */ SyscallDesc("gethostid", unimplementedFunc), + /* 143 */ SyscallDesc("sethostid", unimplementedFunc), + /* 144 */ SyscallDesc("getrlimit", getrlimitFunc), + /* 145 */ SyscallDesc("setrlimit", ignoreFunc), + /* 146 */ SyscallDesc("old_killpg", unimplementedFunc), + /* 147 */ SyscallDesc("setsid", unimplementedFunc), + /* 148 */ SyscallDesc("quotactl", unimplementedFunc), + /* 149 */ SyscallDesc("oldquota", unimplementedFunc), + /* 150 */ SyscallDesc("old_getsockname", unimplementedFunc), + /* 151 */ SyscallDesc("pread", unimplementedFunc), + /* 152 */ SyscallDesc("pwrite", unimplementedFunc), + /* 153 */ SyscallDesc("pid_block", unimplementedFunc), + /* 154 */ SyscallDesc("pid_unblock", unimplementedFunc), + /* 155 */ SyscallDesc("signal_urti", unimplementedFunc), + /* 156 */ SyscallDesc("sigaction", ignoreFunc), + /* 157 */ SyscallDesc("sigwaitprim", unimplementedFunc), + /* 158 */ SyscallDesc("nfssvc", unimplementedFunc), + /* 159 */ SyscallDesc("getdirentries", Tru64::getdirentriesFunc), + /* 160 */ SyscallDesc("pre_F64_statfs", statfsFunc), + /* 161 */ SyscallDesc("pre_F64_fstatfs", fstatfsFunc), + /* 162 */ SyscallDesc("unknown #162", unimplementedFunc), + /* 163 */ SyscallDesc("async_daemon", unimplementedFunc), + /* 164 */ SyscallDesc("getfh", unimplementedFunc), + /* 165 */ SyscallDesc("getdomainname", unimplementedFunc), + /* 166 */ SyscallDesc("setdomainname", unimplementedFunc), + /* 167 */ SyscallDesc("unknown #167", unimplementedFunc), + /* 168 */ SyscallDesc("unknown #168", unimplementedFunc), + /* 169 */ SyscallDesc("exportfs", unimplementedFunc), + /* 170 */ SyscallDesc("unknown #170", unimplementedFunc), + /* 171 */ SyscallDesc("unknown #171", unimplementedFunc), + /* 172 */ SyscallDesc("unknown #172", unimplementedFunc), + /* 173 */ SyscallDesc("unknown #173", unimplementedFunc), + /* 174 */ SyscallDesc("unknown #174", unimplementedFunc), + /* 175 */ SyscallDesc("unknown #175", unimplementedFunc), + /* 176 */ SyscallDesc("unknown #176", unimplementedFunc), + /* 177 */ SyscallDesc("unknown #177", unimplementedFunc), + /* 178 */ SyscallDesc("unknown #178", unimplementedFunc), + /* 179 */ SyscallDesc("unknown #179", unimplementedFunc), + /* 180 */ SyscallDesc("unknown #180", unimplementedFunc), + /* 181 */ SyscallDesc("alt_plock", unimplementedFunc), + /* 182 */ SyscallDesc("unknown #182", unimplementedFunc), + /* 183 */ SyscallDesc("unknown #183", unimplementedFunc), + /* 184 */ SyscallDesc("getmnt", unimplementedFunc), + /* 185 */ SyscallDesc("unknown #185", unimplementedFunc), + /* 186 */ SyscallDesc("unknown #186", unimplementedFunc), + /* 187 */ SyscallDesc("alt_sigpending", unimplementedFunc), + /* 188 */ SyscallDesc("alt_setsid", unimplementedFunc), + /* 189 */ SyscallDesc("unknown #189", unimplementedFunc), + /* 190 */ SyscallDesc("unknown #190", unimplementedFunc), + /* 191 */ SyscallDesc("unknown #191", unimplementedFunc), + /* 192 */ SyscallDesc("unknown #192", unimplementedFunc), + /* 193 */ SyscallDesc("unknown #193", unimplementedFunc), + /* 194 */ SyscallDesc("unknown #194", unimplementedFunc), + /* 195 */ SyscallDesc("unknown #195", unimplementedFunc), + /* 196 */ SyscallDesc("unknown #196", unimplementedFunc), + /* 197 */ SyscallDesc("unknown #197", unimplementedFunc), + /* 198 */ SyscallDesc("unknown #198", unimplementedFunc), + /* 199 */ SyscallDesc("swapon", unimplementedFunc), + /* 200 */ SyscallDesc("msgctl", unimplementedFunc), + /* 201 */ SyscallDesc("msgget", unimplementedFunc), + /* 202 */ SyscallDesc("msgrcv", unimplementedFunc), + /* 203 */ SyscallDesc("msgsnd", unimplementedFunc), + /* 204 */ SyscallDesc("semctl", unimplementedFunc), + /* 205 */ SyscallDesc("semget", unimplementedFunc), + /* 206 */ SyscallDesc("semop", unimplementedFunc), + /* 207 */ SyscallDesc("uname", unameFunc), + /* 208 */ SyscallDesc("lchown", unimplementedFunc), + /* 209 */ SyscallDesc("shmat", unimplementedFunc), + /* 210 */ SyscallDesc("shmctl", unimplementedFunc), + /* 211 */ SyscallDesc("shmdt", unimplementedFunc), + /* 212 */ SyscallDesc("shmget", unimplementedFunc), + /* 213 */ SyscallDesc("mvalid", unimplementedFunc), + /* 214 */ SyscallDesc("getaddressconf", unimplementedFunc), + /* 215 */ SyscallDesc("msleep", unimplementedFunc), + /* 216 */ SyscallDesc("mwakeup", unimplementedFunc), + /* 217 */ SyscallDesc("msync", unimplementedFunc), + /* 218 */ SyscallDesc("signal", unimplementedFunc), + /* 219 */ SyscallDesc("utc_gettime", unimplementedFunc), + /* 220 */ SyscallDesc("utc_adjtime", unimplementedFunc), + /* 221 */ SyscallDesc("unknown #221", unimplementedFunc), + /* 222 */ SyscallDesc("security", unimplementedFunc), + /* 223 */ SyscallDesc("kloadcall", unimplementedFunc), + /* 224 */ SyscallDesc("stat", statFunc), + /* 225 */ SyscallDesc("lstat", lstatFunc), + /* 226 */ SyscallDesc("fstat", fstatFunc), + /* 227 */ SyscallDesc("statfs", statfsFunc), + /* 228 */ SyscallDesc("fstatfs", fstatfsFunc), + /* 229 */ SyscallDesc("getfsstat", unimplementedFunc), + /* 230 */ SyscallDesc("gettimeofday64", unimplementedFunc), + /* 231 */ SyscallDesc("settimeofday64", unimplementedFunc), + /* 232 */ SyscallDesc("unknown #232", unimplementedFunc), + /* 233 */ SyscallDesc("getpgid", unimplementedFunc), + /* 234 */ SyscallDesc("getsid", unimplementedFunc), + /* 235 */ SyscallDesc("sigaltstack", ignoreFunc), + /* 236 */ SyscallDesc("waitid", unimplementedFunc), + /* 237 */ SyscallDesc("priocntlset", unimplementedFunc), + /* 238 */ SyscallDesc("sigsendset", unimplementedFunc), + /* 239 */ SyscallDesc("set_speculative", unimplementedFunc), + /* 240 */ SyscallDesc("msfs_syscall", unimplementedFunc), + /* 241 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 242 */ SyscallDesc("uadmin", unimplementedFunc), + /* 243 */ SyscallDesc("fuser", unimplementedFunc), + /* 244 */ SyscallDesc("proplist_syscall", unimplementedFunc), + /* 245 */ SyscallDesc("ntp_adjtime", unimplementedFunc), + /* 246 */ SyscallDesc("ntp_gettime", unimplementedFunc), + /* 247 */ SyscallDesc("pathconf", unimplementedFunc), + /* 248 */ SyscallDesc("fpathconf", unimplementedFunc), + /* 249 */ SyscallDesc("sync2", unimplementedFunc), + /* 250 */ SyscallDesc("uswitch", unimplementedFunc), + /* 251 */ SyscallDesc("usleep_thread", unimplementedFunc), + /* 252 */ SyscallDesc("audcntl", unimplementedFunc), + /* 253 */ SyscallDesc("audgen", unimplementedFunc), + /* 254 */ SyscallDesc("sysfs", unimplementedFunc), + /* 255 */ SyscallDesc("subsys_info", unimplementedFunc), + /* 256 */ SyscallDesc("getsysinfo", getsysinfoFunc), + /* 257 */ SyscallDesc("setsysinfo", setsysinfoFunc), + /* 258 */ SyscallDesc("afs_syscall", unimplementedFunc), + /* 259 */ SyscallDesc("swapctl", unimplementedFunc), + /* 260 */ SyscallDesc("memcntl", unimplementedFunc), + /* 261 */ SyscallDesc("fdatasync", unimplementedFunc), + /* 262 */ SyscallDesc("oflock", unimplementedFunc), + /* 263 */ SyscallDesc("F64_readv", unimplementedFunc), + /* 264 */ SyscallDesc("F64_writev", unimplementedFunc), + /* 265 */ SyscallDesc("cdslxlate", unimplementedFunc), + /* 266 */ SyscallDesc("sendfile", unimplementedFunc), +}; + + + +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), + /* 8 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 9 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 10 */ SyscallDesc("task_self", unimplementedFunc), + /* 11 */ SyscallDesc("thread_reply", unimplementedFunc), + /* 12 */ SyscallDesc("task_notify", unimplementedFunc), + /* 13 */ SyscallDesc("thread_self", unimplementedFunc), + /* 14 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 15 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 16 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 17 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 18 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 19 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 20 */ SyscallDesc("msg_send_trap", unimplementedFunc), + /* 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), + /* 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), + /* 34 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 35 */ SyscallDesc("nxm_idle", Tru64::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), + /* 40 */ SyscallDesc("nxm_thread_wakeup", unimplementedFunc), + /* 41 */ SyscallDesc("init_process", unimplementedFunc), + /* 42 */ SyscallDesc("nxm_get_binding", unimplementedFunc), + /* 43 */ SyscallDesc("map_fd", unimplementedFunc), + /* 44 */ SyscallDesc("nxm_resched", unimplementedFunc), + /* 45 */ SyscallDesc("nxm_set_cancel", unimplementedFunc), + /* 46 */ SyscallDesc("nxm_set_binding", unimplementedFunc), + /* 47 */ SyscallDesc("stack_create", Tru64::stack_createFunc), + /* 48 */ SyscallDesc("nxm_get_state", unimplementedFunc), + /* 49 */ SyscallDesc("nxm_thread_suspend", unimplementedFunc), + /* 50 */ SyscallDesc("nxm_thread_resume", unimplementedFunc), + /* 51 */ SyscallDesc("nxm_signal_check", unimplementedFunc), + /* 52 */ SyscallDesc("htg_unix_syscall", unimplementedFunc), + /* 53 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 54 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 55 */ SyscallDesc("host_self", unimplementedFunc), + /* 56 */ SyscallDesc("host_priv_self", unimplementedFunc), + /* 57 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 58 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 59 */ SyscallDesc("swtch_pri", Tru64::swtch_priFunc), + /* 60 */ SyscallDesc("swtch", unimplementedFunc), + /* 61 */ SyscallDesc("thread_switch", unimplementedFunc), + /* 62 */ SyscallDesc("semop_fast", unimplementedFunc), + /* 63 */ SyscallDesc("nxm_pshared_init", unimplementedFunc), + /* 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), + /* 68 */ SyscallDesc("lw_syscall", unimplementedFunc), + /* 69 */ SyscallDesc("kern_invalid", unimplementedFunc), + /* 70 */ SyscallDesc("mach_sctimes_0", unimplementedFunc), + /* 71 */ SyscallDesc("mach_sctimes_1", unimplementedFunc), + /* 72 */ SyscallDesc("mach_sctimes_2", unimplementedFunc), + /* 73 */ SyscallDesc("mach_sctimes_3", unimplementedFunc), + /* 74 */ SyscallDesc("mach_sctimes_4", unimplementedFunc), + /* 75 */ SyscallDesc("mach_sctimes_5", unimplementedFunc), + /* 76 */ SyscallDesc("mach_sctimes_6", unimplementedFunc), + /* 77 */ SyscallDesc("mach_sctimes_7", unimplementedFunc), + /* 78 */ SyscallDesc("mach_sctimes_8", unimplementedFunc), + /* 79 */ SyscallDesc("mach_sctimes_9", unimplementedFunc), + /* 80 */ SyscallDesc("mach_sctimes_10", unimplementedFunc), + /* 81 */ SyscallDesc("mach_sctimes_11", unimplementedFunc), + /* 82 */ SyscallDesc("mach_sctimes_port_alloc_dealloc", unimplementedFunc) +}; + +SyscallDesc* +AlphaTru64Process::getDesc(int callnum) +{ + if (callnum < -Num_Mach_Syscall_Descs || callnum > Num_Syscall_Descs) + return NULL; + + if (callnum < 0) + return &machSyscallDescs[-callnum]; + else + return &syscallDescs[callnum]; +} + + +AlphaTru64Process::AlphaTru64Process(const std::string &name, + ObjectFile *objFile, + int stdin_fd, + int stdout_fd, + int stderr_fd, + std::vector &argv, + std::vector &envp) + : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp), + Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)), + Num_Mach_Syscall_Descs(sizeof(machSyscallDescs) / sizeof(SyscallDesc)) +{ +} diff --cc base/remote_gdb.cc index 57a179719,50c4798c4..84093459c --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@@ -454,23 -441,13 +454,23 @@@ RemoteGDB::getregs( void RemoteGDB::setregs() { - memcpy(context->regs.intRegFile, &gdbregs[KGDB_REG_V0], - 32 * sizeof(uint64_t)); + // @todo: Currently this is very Alpha specific. + if (AlphaISA::PcPAL(gdbregs[KGDB_REG_PC])) { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + context->setIntReg(AlphaISA::reg_redir[i], gdbregs[i]); + } + } else { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + context->setIntReg(i, gdbregs[i]); + } + } + #ifdef KGDB_FP_REGS - memcpy(context->regs.floatRegFile.q, &gdbregs[KGDB_REG_F0], - 32 * sizeof(uint64_t)); + for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { + context->setFloatRegInt(i, gdbregs[i + KGDB_REG_F0]); + } #endif - context->regs.pc = gdbregs[KGDB_REG_PC]; + context->setPC(gdbregs[KGDB_REG_PC]); } void diff --cc cpu/cpu_exec_context.cc index 000000000,2fb3d5d53..ae428646d mode 000000,100644..100644 --- a/cpu/cpu_exec_context.cc +++ b/cpu/cpu_exec_context.cc @@@ -1,0 -1,262 +1,288 @@@ + /* - * Copyright (c) 2001-2005 The Regents of The University of Michigan ++ * Copyright (c) 2001-2006 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 + + #include "cpu/base.hh" + #include "cpu/cpu_exec_context.hh" + #include "cpu/exec_context.hh" + + #if FULL_SYSTEM + #include "base/callback.hh" + #include "base/cprintf.hh" + #include "base/output.hh" ++#include "base/trace.hh" + #include "cpu/profile.hh" + #include "kern/kernel_stats.hh" + #include "sim/serialize.hh" + #include "sim/sim_exit.hh" + #include "sim/system.hh" -#include "targetarch/stacktrace.hh" ++#include "arch/stacktrace.hh" + #else + #include "sim/process.hh" + #endif + + using namespace std; + + // constructor + #if FULL_SYSTEM + CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, + AlphaITB *_itb, AlphaDTB *_dtb, + FunctionalMemory *_mem) + : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), - cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys), - memctrl(_sys->memctrl), physmem(_sys->physmem), profile(NULL), ++ cpu_id(-1), lastActivate(0), lastSuspend(0), mem(_mem), itb(_itb), ++ dtb(_dtb), system(_sys), memctrl(_sys->memctrl), physmem(_sys->physmem), ++ fnbin(kernelBinning->fnbin), profile(NULL), quiesceEvent(this), + func_exe_inst(0), storeCondFailures(0) + { + proxy = new ProxyExecContext(this); + + memset(®s, 0, sizeof(RegFile)); + + if (cpu->params->profile) { + profile = new FunctionProfile(system->kernelSymtab); + Callback *cb = + new MakeCallback(this); + registerExitCallback(cb); + } + + // let's fill with a dummy node for now so we don't get a segfault + // on the first cycle when there's no node available. + static ProfileNode dummyNode; + profileNode = &dummyNode; + profilePC = 3; + } + #else + CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, + Process *_process, int _asid) + : _status(ExecContext::Unallocated), - cpu(_cpu), thread_num(_thread_num), cpu_id(-1), - process(_process), mem(process->getMemory()), asid(_asid), ++ cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0), ++ lastSuspend(0), process(_process), mem(process->getMemory()), asid(_asid), + func_exe_inst(0), storeCondFailures(0) + { + memset(®s, 0, sizeof(RegFile)); + proxy = new ProxyExecContext(this); + } + + CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, + FunctionalMemory *_mem, int _asid) + : cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid), + func_exe_inst(0), storeCondFailures(0) + { + memset(®s, 0, sizeof(RegFile)); + proxy = new ProxyExecContext(this); + } + + CPUExecContext::CPUExecContext(RegFile *regFile) + : cpu(NULL), thread_num(-1), process(NULL), mem(NULL), asid(-1), + func_exe_inst(0), storeCondFailures(0) + { + regs = *regFile; + proxy = new ProxyExecContext(this); + } + + #endif + + CPUExecContext::~CPUExecContext() + { + delete proxy; + } + + #if FULL_SYSTEM + void + CPUExecContext::dumpFuncProfile() + { + std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); - profile->dump(proxy, *os); ++} ++ ++ExecContext::EndQuiesceEvent::EndQuiesceEvent(ExecContext *_xc) ++ : Event(&mainEventQueue), xc(_xc) ++{ ++} ++ ++void ++ExecContext::EndQuiesceEvent::process() ++{ ++ xc->activate(); ++} ++ ++const char* ++ExecContext::EndQuiesceEvent::description() ++{ ++ return "End Quiesce Event."; + } + #endif + + void + CPUExecContext::takeOverFrom(ExecContext *oldContext) + { + /* + // some things should already be set up + assert(mem == oldContext->mem); + #if FULL_SYSTEM + assert(system == oldContext->system); + #else + assert(process == oldContext->process); + #endif + + // copy over functional state + _status = oldContext->_status; + regs = oldContext->regs; + cpu_id = oldContext->cpu_id; + func_exe_inst = oldContext->func_exe_inst; + + storeCondFailures = 0; + + oldContext->_status = CPUExecContext::Unallocated; + */ + } + + void + CPUExecContext::serialize(ostream &os) + { + SERIALIZE_ENUM(_status); + regs.serialize(os); + // thread_num and cpu_id are deterministic from the config + SERIALIZE_SCALAR(func_exe_inst); + SERIALIZE_SCALAR(inst); ++ ++#if FULL_SYSTEM ++ Tick quiesceEndTick = 0; ++ if (quiesceEvent.scheduled()) ++ quiesceEndTick = quiesceEvent.when(); ++ SERIALIZE_SCALAR(quiesceEndTick); ++ ++#endif + } + + + void + CPUExecContext::unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_ENUM(_status); + regs.unserialize(cp, section); + // thread_num and cpu_id are deterministic from the config + UNSERIALIZE_SCALAR(func_exe_inst); + UNSERIALIZE_SCALAR(inst); ++ ++#if FULL_SYSTEM ++ Tick quiesceEndTick; ++ UNSERIALIZE_SCALAR(quiesceEndTick); ++ if (quiesceEndTick) ++ quiesceEvent.schedule(quiesceEndTick); ++#endif + } + + + void + CPUExecContext::activate(int delay) + { + if (status() == ExecContext::Active) + return; + ++ lastActivate = curTick; ++ + _status = ExecContext::Active; + cpu->activateContext(thread_num, delay); + } + + void + CPUExecContext::suspend() + { + if (status() == ExecContext::Suspended) + return; + ++ lastActivate = curTick; ++ lastSuspend = curTick; ++/* + #if FULL_SYSTEM + // Don't change the status from active if there are pending interrupts + if (cpu->check_interrupts()) { + assert(status() == ExecContext::Active); + return; + } + #endif - ++*/ + _status = ExecContext::Suspended; + cpu->suspendContext(thread_num); + } + + void + CPUExecContext::deallocate() + { + if (status() == ExecContext::Unallocated) + return; + + _status = ExecContext::Unallocated; + cpu->deallocateContext(thread_num); + } + + void + CPUExecContext::halt() + { + if (status() == ExecContext::Halted) + return; + + _status = ExecContext::Halted; + cpu->haltContext(thread_num); + } + + + void + CPUExecContext::regStats(const string &name) + { + } + + void + CPUExecContext::copyArchRegs(ExecContext *xc) + { + // First loop through the integer registers. + for (int i = 0; i < AlphaISA::NumIntRegs; ++i) { + setIntReg(i, xc->readIntReg(i)); + } + + // Then loop through the floating point registers. + for (int i = 0; i < AlphaISA::NumFloatRegs; ++i) { + setFloatRegDouble(i, xc->readFloatRegDouble(i)); + setFloatRegInt(i, xc->readFloatRegInt(i)); + } + + // Copy misc. registers + setMiscReg(AlphaISA::Fpcr_DepTag, xc->readMiscReg(AlphaISA::Fpcr_DepTag)); + setMiscReg(AlphaISA::Uniq_DepTag, xc->readMiscReg(AlphaISA::Uniq_DepTag)); + setMiscReg(AlphaISA::Lock_Flag_DepTag, + xc->readMiscReg(AlphaISA::Lock_Flag_DepTag)); + setMiscReg(AlphaISA::Lock_Addr_DepTag, + xc->readMiscReg(AlphaISA::Lock_Addr_DepTag)); + + // Lastly copy PC/NPC + setPC(xc->readPC()); + setNextPC(xc->readNextPC()); + } + -void -CPUExecContext::trap(Fault fault) -{ - //TheISA::trap(fault); //One possible way to do it... - - /** @todo: Going to hack it for now. Do a true fixup later. */ -#if FULL_SYSTEM - ev5_trap(fault); -#else - fatal("fault (%d) detected @ PC 0x%08p", fault, readPC()); -#endif -} diff --cc cpu/cpu_exec_context.hh index 000000000,1ae24582d..a40253d4b mode 000000,100644..100644 --- a/cpu/cpu_exec_context.hh +++ b/cpu/cpu_exec_context.hh @@@ -1,0 -1,510 +1,521 @@@ + /* - * Copyright (c) 2001-2005 The Regents of The University of Michigan ++ * Copyright (c) 2001-2006 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 __CPU_CPU_EXEC_CONTEXT_HH__ + #define __CPU_CPU_EXEC_CONTEXT_HH__ + + #include "arch/isa_traits.hh" + #include "config/full_system.hh" + #include "cpu/exec_context.hh" + #include "mem/functional/functional.hh" + #include "mem/mem_req.hh" + #include "sim/byteswap.hh" ++#include "sim/eventq.hh" + #include "sim/host.hh" + #include "sim/serialize.hh" + + // forward declaration: see functional_memory.hh + class FunctionalMemory; + class PhysicalMemory; + class BaseCPU; + + #if FULL_SYSTEM + + #include "sim/system.hh" -#include "targetarch/alpha_memory.hh" ++#include "arch/tlb.hh" + + class FunctionProfile; + class ProfileNode; + class MemoryController; + + #else // !FULL_SYSTEM + + #include "sim/process.hh" + + #endif // FULL_SYSTEM + + // + // The CPUExecContext object represents a functional context for + // instruction execution. It incorporates everything required for + // architecture-level functional simulation of a single thread. + // + + class CPUExecContext + { + protected: + typedef TheISA::RegFile RegFile; + typedef TheISA::MachInst MachInst; + typedef TheISA::MiscRegFile MiscRegFile; + typedef TheISA::MiscReg MiscReg; + public: + typedef ExecContext::Status Status; + + private: + Status _status; + + public: + Status status() const { return _status; } + + void setStatus(Status newStatus) { _status = newStatus; } + + /// Set the status to Active. Optional delay indicates number of + /// cycles to wait before beginning execution. + void activate(int delay = 1); + + /// Set the status to Suspended. + void suspend(); + + /// Set the status to Unallocated. + void deallocate(); + + /// Set the status to Halted. + void halt(); + + protected: + RegFile regs; // correct-path register context + + public: + // pointer to CPU associated with this context + BaseCPU *cpu; + + ProxyExecContext *proxy; + + // Current instruction + MachInst inst; + + // Index of hardware thread context on the CPU that this represents. + int thread_num; + + // ID of this context w.r.t. the System or Process object to which + // it belongs. For full-system mode, this is the system CPU ID. + int cpu_id; + ++ Tick lastActivate; ++ Tick lastSuspend; ++ + #if FULL_SYSTEM + FunctionalMemory *mem; + AlphaITB *itb; + AlphaDTB *dtb; + System *system; + + // the following two fields are redundant, since we can always + // look them up through the system pointer, but we'll leave them + // here for now for convenience + MemoryController *memctrl; + PhysicalMemory *physmem; + + FunctionProfile *profile; + ProfileNode *profileNode; + Addr profilePC; + void dumpFuncProfile(); + ++ /** Event for timing out quiesce instruction */ ++ struct EndQuiesceEvent : public Event ++ { ++ /** A pointer to the execution context that is quiesced */ ++ ExecContext *xc; ++ ++ EndQuiesceEvent(ExecContext *_xc); ++ ++ /** Event process to occur at interrupt*/ ++ virtual void process(); ++ ++ /** Event description */ ++ virtual const char *description(); ++ }; ++ EndQuiesceEvent quiesceEvent; ++ + #else + Process *process; + + FunctionalMemory *mem; // functional storage for process address space + + // Address space ID. Note that this is used for TIMING cache + // simulation only; all functional memory accesses should use + // one of the FunctionalMemory pointers above. + short asid; + + #endif + + /** + * Temporary storage to pass the source address from copy_load to + * copy_store. + * @todo Remove this temporary when we have a better way to do it. + */ + Addr copySrcAddr; + /** + * Temp storage for the physical source address of a copy. + * @todo Remove this temporary when we have a better way to do it. + */ + Addr copySrcPhysAddr; + + + /* + * number of executed instructions, for matching with syscall trace + * points in EIO files. + */ + Counter func_exe_inst; + + // + // Count failed store conditionals so we can warn of apparent + // application deadlock situations. + unsigned storeCondFailures; + + // constructor: initialize context from given process structure + #if FULL_SYSTEM + CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system, + AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem); + #else + CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid); + CPUExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem, + int _asid); + // Constructor to use XC to pass reg file around. Not used for anything + // else. + CPUExecContext(RegFile *regFile); + #endif + virtual ~CPUExecContext(); + + virtual void takeOverFrom(ExecContext *oldContext); + + void regStats(const std::string &name); + + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + + BaseCPU *getCpuPtr() { return cpu; } + + ExecContext *getProxy() { return proxy; } + + int getThreadNum() { return thread_num; } + + #if FULL_SYSTEM + System *getSystemPtr() { return system; } + + PhysicalMemory *getPhysMemPtr() { return physmem; } + + AlphaITB *getITBPtr() { return itb; } + + AlphaDTB *getDTBPtr() { return dtb; } + + bool validInstAddr(Addr addr) { return true; } + bool validDataAddr(Addr addr) { return true; } + int getInstAsid() { return regs.instAsid(); } + int getDataAsid() { return regs.dataAsid(); } + + Fault translateInstReq(MemReqPtr &req) + { + return itb->translate(req); + } + + Fault translateDataReadReq(MemReqPtr &req) + { + return dtb->translate(req, false); + } + + Fault translateDataWriteReq(MemReqPtr &req) + { + return dtb->translate(req, true); + } + + #else + Process *getProcessPtr() { return process; } + + bool validInstAddr(Addr addr) + { return process->validInstAddr(addr); } + + bool validDataAddr(Addr addr) + { return process->validDataAddr(addr); } + + int getInstAsid() { return asid; } + int getDataAsid() { return asid; } + + Fault dummyTranslation(MemReqPtr &req) + { + #if 0 + assert((req->vaddr >> 48 & 0xffff) == 0); + #endif + + // put the asid in the upper 16 bits of the paddr + req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); + req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; + return NoFault; + } + Fault translateInstReq(MemReqPtr &req) + { + return dummyTranslation(req); + } + Fault translateDataReadReq(MemReqPtr &req) + { + return dummyTranslation(req); + } + Fault translateDataWriteReq(MemReqPtr &req) + { + return dummyTranslation(req); + } + + #endif + + template + Fault read(MemReqPtr &req, T &data) + { + #if FULL_SYSTEM && defined(TARGET_ALPHA) + if (req->flags & LOCKED) { + req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr); + req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true); + } + #endif + + Fault error; + error = mem->read(req, data); + data = LittleEndianGuest::gtoh(data); + return error; + } + + template + Fault write(MemReqPtr &req, T &data) + { + #if FULL_SYSTEM && defined(TARGET_ALPHA) + ExecContext *xc; + + // If this is a store conditional, act appropriately + if (req->flags & LOCKED) { + xc = req->xc; + + if (req->flags & UNCACHEABLE) { + // Don't update result register (see stq_c in isa_desc) + req->result = 2; + xc->setStCondFailures(0);//Needed? [RGD] + } else { + bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag); + Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag); + req->result = lock_flag; + if (!lock_flag || + ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { + xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); + xc->setStCondFailures(xc->readStCondFailures() + 1); + if (((xc->readStCondFailures()) % 100000) == 0) { + std::cerr << "Warning: " + << xc->readStCondFailures() + << " consecutive store conditional failures " + << "on cpu " << req->xc->readCpuId() + << std::endl; + } + return NoFault; + } + else xc->setStCondFailures(0); + } + } + + // Need to clear any locked flags on other proccessors for + // this address. Only do this for succsful Store Conditionals + // and all other stores (WH64?). Unsuccessful Store + // Conditionals would have returned above, and wouldn't fall + // through. + for (int i = 0; i < system->execContexts.size(); i++){ + xc = system->execContexts[i]; + if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) == + (req->paddr & ~0xf)) { + xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); + } + } + + #endif + return mem->write(req, (T)LittleEndianGuest::htog(data)); + } + + virtual bool misspeculating(); + + + MachInst getInst() { return inst; } + + void setInst(MachInst new_inst) + { + inst = new_inst; + } + + Fault instRead(MemReqPtr &req) + { + return mem->read(req, inst); + } + + void setCpuId(int id) { cpu_id = id; } + + int readCpuId() { return cpu_id; } + + FunctionalMemory *getMemPtr() { return mem; } + + void copyArchRegs(ExecContext *xc); + + // + // New accessors for new decoder. + // + uint64_t readIntReg(int reg_idx) + { + return regs.intRegFile[reg_idx]; + } + + float readFloatRegSingle(int reg_idx) + { + return (float)regs.floatRegFile.d[reg_idx]; + } + + double readFloatRegDouble(int reg_idx) + { + return regs.floatRegFile.d[reg_idx]; + } + + uint64_t readFloatRegInt(int reg_idx) + { + return regs.floatRegFile.q[reg_idx]; + } + + void setIntReg(int reg_idx, uint64_t val) + { + regs.intRegFile[reg_idx] = val; + } + + void setFloatRegSingle(int reg_idx, float val) + { + regs.floatRegFile.d[reg_idx] = (double)val; + } + + void setFloatRegDouble(int reg_idx, double val) + { + regs.floatRegFile.d[reg_idx] = val; + } + + void setFloatRegInt(int reg_idx, uint64_t val) + { + regs.floatRegFile.q[reg_idx] = val; + } + + uint64_t readPC() + { + return regs.pc; + } + + void setPC(uint64_t val) + { + regs.pc = val; + } + + uint64_t readNextPC() + { + return regs.npc; + } + + void setNextPC(uint64_t val) + { + regs.npc = val; + } + + MiscReg readMiscReg(int misc_reg) + { + return regs.miscRegs.readReg(misc_reg); + } + + MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + { + return regs.miscRegs.readRegWithEffect(misc_reg, fault, proxy); + } + + Fault setMiscReg(int misc_reg, const MiscReg &val) + { + return regs.miscRegs.setReg(misc_reg, val); + } + + Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + { + return regs.miscRegs.setRegWithEffect(misc_reg, val, proxy); + } + + unsigned readStCondFailures() { return storeCondFailures; } + + void setStCondFailures(unsigned sc_failures) + { storeCondFailures = sc_failures; } + + void clearArchRegs() { memset(®s, 0, sizeof(regs)); } + + #if FULL_SYSTEM + int readIntrFlag() { return regs.intrflag; } + void setIntrFlag(int val) { regs.intrflag = val; } + Fault hwrei(); + bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } - void ev5_trap(Fault fault); + bool simPalCheck(int palFunc); + #endif + - /** Meant to be more generic trap function to be - * called when an instruction faults. - * @param fault The fault generated by executing the instruction. - * @todo How to do this properly so it's dependent upon ISA only? - */ - - void trap(Fault fault); - + #if !FULL_SYSTEM + TheISA::IntReg getSyscallArg(int i) + { + return regs.intRegFile[TheISA::ArgumentReg0 + i]; + } + + // used to shift args for indirect syscall + void setSyscallArg(int i, TheISA::IntReg val) + { + regs.intRegFile[TheISA::ArgumentReg0 + i] = val; + } + + void setSyscallReturn(SyscallReturn return_value) + { + // 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). + const int RegA3 = 19; // only place this is used + if (return_value.successful()) { + // no error + regs.intRegFile[RegA3] = 0; + regs.intRegFile[TheISA::ReturnValueReg] = return_value.value(); + } else { + // got an error, return details + regs.intRegFile[RegA3] = (TheISA::IntReg) -1; + regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value(); + } + } + + void syscall() + { + process->syscall(proxy); + } + + Counter readFuncExeInst() { return func_exe_inst; } + + void setFuncExeInst(Counter new_val) { func_exe_inst = new_val; } + #endif + }; + + + // for non-speculative execution context, spec_mode is always false + inline bool + CPUExecContext::misspeculating() + { + return false; + } + + #endif // __CPU_CPU_EXEC_CONTEXT_HH__ diff --cc cpu/simple/cpu.cc index 51d679a63,7c60b242f..38b43fef5 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@@ -345,16 -348,16 +348,16 @@@ SimpleCPU::copySrcTranslate(Addr src memReq->reset(src & ~(blk_size - 1), blk_size); // translate to physical address - Fault fault = xc->translateDataReadReq(memReq); + Fault fault = cpuXC->translateDataReadReq(memReq); - assert(fault != AlignmentFault); - if (fault == NoFault) { - xc->copySrcAddr = src; - xc->copySrcPhysAddr = memReq->paddr + offset; + cpuXC->copySrcAddr = src; + cpuXC->copySrcPhysAddr = memReq->paddr + offset; } else { + assert(!fault->isAlignmentFault()); + - xc->copySrcAddr = 0; - xc->copySrcPhysAddr = 0; + cpuXC->copySrcAddr = 0; + cpuXC->copySrcPhysAddr = 0; } return fault; } @@@ -380,8 -383,10 +383,8 @@@ SimpleCPU::copy(Addr dest memReq->reset(dest & ~(blk_size -1), blk_size); // translate to physical address - Fault fault = xc->translateDataWriteReq(memReq); + Fault fault = cpuXC->translateDataWriteReq(memReq); - assert(fault != AlignmentFault); - if (fault == NoFault) { Addr dest_addr = memReq->paddr + offset; // Need to read straight from memory since we have more than 8 bytes. @@@ -682,16 -684,16 +685,17 @@@ SimpleCPU::tick( } } - if (xc->readMiscReg(IPR_ASTRR)) + if (cpuXC->readMiscReg(IPR_ASTRR)) panic("asynchronous traps not implemented\n"); - if (ipl && ipl > xc->readMiscReg(IPR_IPLR)) { - xc->setMiscReg(IPR_ISR, summary); - xc->setMiscReg(IPR_INTID, ipl); - Fault(new InterruptFault)->invoke(xc); + if (ipl && ipl > cpuXC->readMiscReg(IPR_IPLR)) { + cpuXC->setMiscReg(IPR_ISR, summary); + cpuXC->setMiscReg(IPR_INTID, ipl); - cpuXC->ev5_trap(InterruptFault); ++ ++ Fault(new InterruptFault)->invoke(xcProxy); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - xc->readMiscReg(IPR_IPLR), ipl, summary); + cpuXC->readMiscReg(IPR_IPLR), ipl, summary); } } #endif @@@ -762,16 -764,16 +766,16 @@@ // decode the instruction inst = gtoh(inst); - curStaticInst = StaticInst::decode(inst); + curStaticInst = StaticInst::decode(makeExtMI(inst, xc->readPC())); - traceData = Trace::getInstRecord(curTick, xc, this, curStaticInst, - xc->regs.pc); + traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst, + cpuXC->readPC()); #if FULL_SYSTEM - xc->setInst(inst); + cpuXC->setInst(inst); #endif // FULL_SYSTEM - xc->func_exe_inst++; + cpuXC->func_exe_inst++; fault = curStaticInst->execute(this, traceData); @@@ -812,9 -815,9 +817,9 @@@ if (fault != NoFault) { #if FULL_SYSTEM - fault->invoke(xc); - cpuXC->ev5_trap(fault); ++ fault->invoke(xcProxy); #else // !FULL_SYSTEM - fatal("fault (%d) detected @ PC 0x%08p", fault, xc->regs.pc); + fatal("fault (%d) detected @ PC 0x%08p", fault, cpuXC->readPC()); #endif // FULL_SYSTEM } else { diff --cc cpu/simple/cpu.hh index 0b8d84e53,1441a8fcd..4ab9a1c3e --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@@ -343,18 -346,18 +346,18 @@@ class SimpleCPU : public BaseCP } #if FULL_SYSTEM - Fault hwrei() { return xc->hwrei(); } - int readIntrFlag() { return xc->readIntrFlag(); } - void setIntrFlag(int val) { xc->setIntrFlag(val); } - bool inPalMode() { return xc->inPalMode(); } - void trap(Fault fault) { fault->invoke(xc); } - bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } + Fault hwrei() { return cpuXC->hwrei(); } + int readIntrFlag() { return cpuXC->readIntrFlag(); } + void setIntrFlag(int val) { cpuXC->setIntrFlag(val); } + bool inPalMode() { return cpuXC->inPalMode(); } - void ev5_trap(Fault fault) { cpuXC->ev5_trap(fault); } ++ void ev5_trap(Fault fault) { fault->invoke(xcProxy); } + bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); } #else - void syscall() { xc->syscall(); } + void syscall() { cpuXC->syscall(); } #endif - bool misspeculating() { return xc->misspeculating(); } - ExecContext *xcBase() { return xc; } + bool misspeculating() { return cpuXC->misspeculating(); } + ExecContext *xcBase() { return xcProxy; } }; #endif // __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ diff --cc kern/kernel_stats.cc index 33485ca15,ddf1058e6..988b0f639 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@@ -43,11 -43,11 +43,11 @@@ namespace Kernel const char *modestr[] = { "kernel", "user", "idle", "interrupt" }; - Statistics::Statistics(ExecContext *context) - : xc(context), idleProcess((Addr)-1), themode(kernel), lastModeTick(0), + Statistics::Statistics(System *system) + : idleProcess((Addr)-1), themode(kernel), lastModeTick(0), iplLast(0), iplLastTick(0) { - bin_int = xc->system->params()->bin_int; - bin_int = system->params->bin_int; ++ bin_int = system->params()->bin_int; } void diff --cc kern/kernel_stats.hh index 4896a0705,6689dad01..c0a7fb858 --- a/kern/kernel_stats.hh +++ b/kern/kernel_stats.hh @@@ -178,15 -177,17 +177,15 @@@ class Statistics : public Serializabl void hwrei() { _hwrei++; } void fault(Fault fault) { - if(fault == NoFault) _faults[0]++; - else if(fault == MachineCheckFault) _faults[2]++; - else if(fault == AlignmentFault) _faults[7]++; - else _faults[fault->id]++; + if(fault != NoFault) + fault->stat()++; }// FIXME: When there are no generic system fault objects, this will go back to _faults[fault]++; } void swpipl(int ipl); - void mode(cpu_mode newmode); - void context(Addr oldpcbb, Addr newpcbb); - void callpal(int code); + void mode(cpu_mode newmode, ExecContext *xc); + void context(Addr oldpcbb, Addr newpcbb, ExecContext *xc); + void callpal(int code, ExecContext *xc); - void setIdleProcess(Addr idle); + void setIdleProcess(Addr idle, ExecContext *xc); public: virtual void serialize(std::ostream &os); diff --cc sim/pseudo_inst.cc index f4285be8a,f46f6acf4..85b26ef23 --- a/sim/pseudo_inst.cc +++ b/sim/pseudo_inst.cc @@@ -74,45 -74,9 +74,45 @@@ namespace AlphaPseud return; xc->suspend(); - xc->kernelStats->quiesce(); + xc->getCpuPtr()->kernelStats->quiesce(); } + void + quiesceNs(ExecContext *xc, uint64_t ns) + { + if (!doQuiesce || ns == 0) + return; + + if (xc->quiesceEvent.scheduled()) + xc->quiesceEvent.reschedule(curTick + Clock::Int::ns * ns); + else + xc->quiesceEvent.schedule(curTick + Clock::Int::ns * ns); + + xc->suspend(); + xc->kernelStats->quiesce(); + } + + void + quiesceCycles(ExecContext *xc, uint64_t cycles) + { + if (!doQuiesce || cycles == 0) + return; + + if (xc->quiesceEvent.scheduled()) + xc->quiesceEvent.reschedule(curTick + xc->cpu->cycles(cycles)); + else + xc->quiesceEvent.schedule(curTick + xc->cpu->cycles(cycles)); + + xc->suspend(); + xc->kernelStats->quiesce(); + } + + uint64_t + quiesceTime(ExecContext *xc) + { + return (xc->lastActivate - xc->lastSuspend) / Clock::Int::ns ; + } + void ivlb(ExecContext *xc) { @@@ -207,7 -171,7 +207,7 @@@ uint64_t readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset) { - const string &file = xc->cpu->system->params()->readfile; - const string &file = xc->getCpuPtr()->system->params->readfile; ++ const string &file = xc->getCpuPtr()->system->params()->readfile; if (file.empty()) { return ULL(0); } diff --cc sim/syscall_emul.hh index eca9f79e0,32f98600c..cadaa1cd3 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@@ -428,9 -428,9 +428,9 @@@ statFunc(SyscallDesc *desc, int callnum int result = stat(path.c_str(), &hostBuf); if (result < 0) - return errno; + return -errno; - OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); return 0; } @@@ -457,9 -457,9 +457,9 @@@ fstat64Func(SyscallDesc *desc, int call #endif if (result < 0) - return errno; + return -errno; - OS::copyOutStat64Buf(xc->mem, fd, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStat64Buf(xc->getMemPtr(), fd, xc->getSyscallArg(1), &hostBuf); return 0; } @@@ -553,9 -553,9 +553,9 @@@ statfsFunc(SyscallDesc *desc, int calln int result = statfs(path.c_str(), &hostBuf); if (result < 0) - return errno; + return -errno; - OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatfsBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); return 0; } @@@ -576,9 -576,9 +576,9 @@@ fstatfsFunc(SyscallDesc *desc, int call int result = fstatfs(fd, &hostBuf); if (result < 0) - return errno; + return -errno; - OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatfsBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); return 0; }