diff options
38 files changed, 610 insertions, 536 deletions
diff --git a/SConscript b/SConscript index ea77f0ec7..30fe3fe17 100644 --- a/SConscript +++ b/SConscript @@ -183,33 +183,7 @@ full_system_sources = Split(''' cpu/profile.cc dev/alpha_console.cc - dev/baddev.cc - dev/simconsole.cc - dev/disk_image.cc - dev/etherbus.cc - dev/etherdump.cc - dev/etherint.cc - dev/etherlink.cc - dev/etherpkt.cc - dev/ethertap.cc - dev/ide_ctrl.cc - dev/ide_disk.cc dev/io_device.cc - dev/ns_gige.cc - dev/pciconfigall.cc - dev/pcidev.cc - dev/pcifake.cc - dev/pktfifo.cc - dev/platform.cc - dev/sinic.cc - dev/simple_disk.cc - dev/tsunami.cc - dev/tsunami_cchip.cc - dev/isa_fake.cc - dev/tsunami_io.cc - dev/tsunami_pchip.cc - dev/uart.cc - dev/uart8250.cc kern/kernel_binning.cc kern/kernel_stats.cc @@ -218,10 +192,38 @@ full_system_sources = Split(''' kern/linux/linux_syscalls.cc kern/linux/printk.cc - mem/functional/memory_control.cc + mem/vport.cc + sim/pseudo_inst.cc ''') +# dev/baddev.cc +# dev/simconsole.cc +# dev/disk_image.cc +# dev/etherbus.cc +# dev/etherdump.cc +# dev/etherint.cc +# dev/etherlink.cc +# dev/etherpkt.cc +# dev/ethertap.cc +# dev/ide_ctrl.cc +# dev/ide_disk.cc +# dev/ns_gige.cc +# dev/pciconfigall.cc +# dev/pcidev.cc +# dev/pcifake.cc +# dev/pktfifo.cc +# dev/platform.cc +# dev/sinic.cc +# dev/simple_disk.cc +# dev/tsunami.cc +# dev/tsunami_cchip.cc +# dev/isa_fake.cc +# dev/tsunami_io.cc +# dev/tsunami_pchip.cc +# dev/uart.cc +# dev/uart8250.cc + if env['TARGET_ISA'] == 'alpha': full_system_sources += Split(''' kern/tru64/dump_mbuf.cc diff --git a/arch/alpha/arguments.cc b/arch/alpha/arguments.cc index fe6e78abc..adc371682 100644 --- a/arch/alpha/arguments.cc +++ b/arch/alpha/arguments.cc @@ -29,7 +29,7 @@ #include "arch/alpha/arguments.hh" #include "arch/alpha/vtophys.hh" #include "cpu/exec_context.hh" -#include "mem/functional/physical.hh" +#include "mem/vport.hh" using namespace AlphaISA; @@ -59,11 +59,10 @@ AlphaArguments::getArg(bool fp) return xc->readIntReg(16 + number); } else { Addr sp = xc->readIntReg(30); - Addr paddr = vtophys(xc, sp + (number-6) * sizeof(uint64_t)); - // @todo: This read must go through the system or something else. -// return xc->getPhysMemPtr()->phys_read_qword(paddr); - panic("Need to fix alpha arguments\n"); - return 0; + VirtualPort *vp = xc->getVirtPort(xc); + uint64_t arg = vp->read<uint64_t>(sp + (number-6) * sizeof(uint64_t)); + xc->delVirtPort(vp); + return arg; } } diff --git a/arch/alpha/arguments.hh b/arch/alpha/arguments.hh index 75346bf58..bd1c6cb1d 100644 --- a/arch/alpha/arguments.hh +++ b/arch/alpha/arguments.hh @@ -26,8 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __ARGUMENTS_HH__ -#define __ARGUMENTS_HH__ +#ifndef __ARCH_ALPHA_ARGUMENTS_HH__ +#define __ARCH_ALPHA_ARGUMENTS_HH__ #include <assert.h> @@ -37,6 +37,8 @@ class ExecContext; +namespace AlphaISA { + class AlphaArguments { protected: @@ -135,9 +137,11 @@ class AlphaArguments operator char *() { char *buf = data->alloc(2048); - CopyString(xc, buf, getArg(), 2048); + CopyStringOut(xc, buf, getArg(), 2048); return buf; } }; -#endif // __ARGUMENTS_HH__ +}; // namespace AlphaISA + +#endif // __ARCH_ALPHA_ARGUMENTS_HH__ diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 0083aa9f3..c8cb9124e 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -105,6 +105,10 @@ FaultName IntegerOverflowFault::_name = "intover"; FaultVect IntegerOverflowFault::_vect = 0x0501; FaultStat IntegerOverflowFault::_count; +FaultName UnimpFault::_name = "Unimplemented Simulator feature"; +FaultVect UnimpFault::_vect = 0x0001; +FaultStat UnimpFault::_count; + #if FULL_SYSTEM void AlphaFault::invoke(ExecContext * xc) @@ -170,6 +174,12 @@ void ItbFault::invoke(ExecContext * xc) AlphaFault::invoke(xc); } +void UnimpFault::invoke(ExecContext * xc) +{ + FaultBase::invoke(xc); + panic("Unimpfault: %s\n", panicStr.c_str()); +} + #endif } // namespace AlphaISA diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index e8ccc6b79..c03d601ad 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -347,6 +347,27 @@ class IntegerOverflowFault : public AlphaFault FaultStat & countStat() {return _count;} }; +class UnimpFault : public AlphaFault +{ +#if FULL_SYSTEM + private: + std::string panicStr; + static FaultName _name; + static FaultVect _vect; + static FaultStat _count; + public: + UnimpFault(std::string _str) + : panicStr(_str) + { } +#endif + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & countStat() {return _count;} +#if FULL_SYSTEM + void invoke(ExecContext * xc); +#endif +}; + } // AlphaISA namespace #endif // __FAULTS_HH__ diff --git a/arch/alpha/freebsd/system.cc b/arch/alpha/freebsd/system.cc index e32053afd..3e50fb9a5 100644 --- a/arch/alpha/freebsd/system.cc +++ b/arch/alpha/freebsd/system.cc @@ -37,8 +37,8 @@ #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 "mem/physical.hh" +#include "mem/port.hh" #include "arch/isa_traits.hh" #include "sim/builder.hh" #include "sim/byteswap.hh" @@ -74,20 +74,12 @@ FreebsdAlphaSystem::doCalibrateClocks(ExecContext *xc) { Addr ppc_vaddr = 0; Addr timer_vaddr = 0; - Addr ppc_paddr = 0; - Addr timer_paddr = 0; 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); + virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency); + virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY); } @@ -102,7 +94,6 @@ FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ExecContext *xc) BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) Param<Tick> boot_cpu_frequency; - SimObjectParam<MemoryController *> memctrl; SimObjectParam<PhysicalMemory *> physmem; Param<string> kernel; @@ -125,7 +116,6 @@ 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"), @@ -147,7 +137,6 @@ 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; diff --git a/arch/alpha/linux/system.cc b/arch/alpha/linux/system.cc index f9275d15e..edd2cdaf1 100644 --- a/arch/alpha/linux/system.cc +++ b/arch/alpha/linux/system.cc @@ -46,8 +46,8 @@ #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 "mem/physical.hh" +#include "mem/port.hh" #include "sim/builder.hh" #include "sim/byteswap.hh" @@ -59,7 +59,6 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p) : AlphaSystem(p) { Addr addr = 0; - Addr paddr = 0; /** * The symbol swapper_pg_dir marks the beginning of the kernel and @@ -73,25 +72,17 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p) * 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); + virtPort.writeBlob(CommandLine(), (uint8_t*)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; - } + if (kernelSymtab->findAddress("est_cycle_freq", addr)) + virtPort.write(addr, (uint64_t)(Clock::Frequency / + p->boot_cpu_frequency)); /** @@ -100,16 +91,9 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p) * @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 + if (kernelSymtab->findAddress("dp264_mv", addr)) + virtPort.write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127)); + else panic("could not find dp264_mv\n"); #ifndef NDEBUG @@ -190,15 +174,10 @@ 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->getCpuPtr()->frequency(); Tick intrFreq = platform->intrFrequency(); - *(uint32_t *)loops_per_jiffy = - (uint32_t)((cpuFreq / intrFreq) * 0.9988); + xc->getVirtPort(xc)->write(addr, + (uint32_t)((cpuFreq / intrFreq) * 0.9988)); } } @@ -224,7 +203,6 @@ LinuxAlphaSystem::PrintThreadInfo::process(ExecContext *xc) BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem) Param<Tick> boot_cpu_frequency; - SimObjectParam<MemoryController *> memctrl; SimObjectParam<PhysicalMemory *> physmem; Param<string> kernel; @@ -247,7 +225,6 @@ 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"), @@ -269,7 +246,6 @@ 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; diff --git a/arch/alpha/stacktrace.cc b/arch/alpha/stacktrace.cc index 26656ab5c..8691e12dc 100644 --- a/arch/alpha/stacktrace.cc +++ b/arch/alpha/stacktrace.cc @@ -47,23 +47,23 @@ ProcessInfo::ProcessInfo(ExecContext *_xc) if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) panic("thread info not compiled into kernel\n"); - thread_info_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); + thread_info_size = gtoh(xc->getVirtPort()->read<int32_t>(addr)); if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) panic("thread info not compiled into kernel\n"); - task_struct_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); + task_struct_size = gtoh(xc->getVirtPort()->read<int32_t>(addr)); if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) panic("thread info not compiled into kernel\n"); - task_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); + task_off = gtoh(xc->getVirtPort()->read<int32_t>(addr)); if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) panic("thread info not compiled into kernel\n"); - pid_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); + pid_off = gtoh(xc->getVirtPort()->read<int32_t>(addr)); if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) panic("thread info not compiled into kernel\n"); - name_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); + name_off = gtoh(xc->getVirtPort()->read<int32_t>(addr)); } Addr @@ -73,9 +73,7 @@ ProcessInfo::task(Addr ksp) const if (base == ULL(0xfffffc0000000000)) return 0; - Addr task; - CopyOut(xc, &task, base + task_off, sizeof(task)); - return task; + return gtoh(xc->getVirtPort()->read<Addr>(base + task_off)); } int @@ -85,9 +83,7 @@ ProcessInfo::pid(Addr ksp) const if (!task) return -1; - uint16_t pid; - CopyOut(xc, &pid, task + pid_off, sizeof(pid)); - return pid; + return gtoh(xc->getVirtPort()->read<uint16_t>(task + pid_off)); } string @@ -98,7 +94,7 @@ ProcessInfo::name(Addr ksp) const return "console"; char comm[256]; - CopyString(xc, comm, task + name_off, sizeof(comm)); + CopyStringOut(xc, comm, task + name_off, sizeof(comm)); if (!comm[0]) return "startup"; diff --git a/arch/alpha/system.cc b/arch/alpha/system.cc index 8dfc3cbc4..21ffa350b 100644 --- a/arch/alpha/system.cc +++ b/arch/alpha/system.cc @@ -33,8 +33,7 @@ #include "base/loader/object_file.hh" #include "base/loader/symtab.hh" #include "base/trace.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" +#include "mem/physical.hh" #include "sim/byteswap.hh" #include "sim/builder.hh" @@ -63,8 +62,8 @@ AlphaSystem::AlphaSystem(Params *p) // Load program sections into memory - pal->loadSections(&functionalPort, LoadAddrMask); - console->loadSections(&functionalPort, LoadAddrMask); + pal->loadSections(&functionalPort, AlphaISA::LoadAddrMask); + console->loadSections(&functionalPort, AlphaISA::LoadAddrMask); // load symbols if (!console->loadGlobalSymbols(consoleSymtab)) @@ -97,11 +96,8 @@ AlphaSystem::AlphaSystem(Params *p) * others do.) */ if (consoleSymtab->findAddress("env_booted_osflags", addr)) { - Addr paddr = vtophys(physmem, addr); - char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t)); - - if (osflags) - strcpy(osflags, params()->boot_osflags.c_str()); + virtPort.writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(), + strlen(params()->boot_osflags.c_str())); } /** @@ -109,14 +105,11 @@ AlphaSystem::AlphaSystem(Params *p) * information to Tsunami. */ if (consoleSymtab->findAddress("m5_rpb", addr)) { - Addr paddr = vtophys(physmem, addr); - char *hwrpb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); - - if (!hwrpb) - panic("could not translate hwrpb addr\n"); - - *(uint64_t*)(hwrpb+0x50) = htog(params()->system_type); - *(uint64_t*)(hwrpb+0x58) = htog(params()->system_rev); + uint64_t data; + data = htog(params()->system_type); + virtPort.write(addr, data); + data = htog(params()->system_rev); + virtPort.write(addr, data); } else panic("could not find hwrpb\n"); @@ -172,16 +165,13 @@ AlphaSystem::fixFuncEventAddr(Addr addr) const uint32_t gp_ldah_pattern = (9 << 26) | (29 << 21) | (27 << 16); // lda gp,Y(gp): opcode 8, Ra = 29, rb = 29 const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16); - // instruction size - const int sz = sizeof(uint32_t); - Addr paddr = vtophys(physmem, addr); - uint32_t i1 = *(uint32_t *)physmem->dma_addr(paddr, sz); - uint32_t i2 = *(uint32_t *)physmem->dma_addr(paddr+sz, sz); + uint32_t i1 = virtPort.read<uint32_t>(addr); + uint32_t i2 = virtPort.read<uint32_t>(addr + sizeof(AlphaISA::MachInst)); if ((i1 & inst_mask) == gp_ldah_pattern && (i2 & inst_mask) == gp_lda_pattern) { - Addr new_addr = addr + 2*sz; + Addr new_addr = addr + 2* sizeof(AlphaISA::MachInst); DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr); return new_addr; } else { @@ -195,14 +185,7 @@ AlphaSystem::setAlphaAccess(Addr access) { Addr addr = 0; if (consoleSymtab->findAddress("m5AlphaAccess", addr)) { - Addr paddr = vtophys(physmem, addr); - uint64_t *m5AlphaAccess = - (uint64_t *)physmem->dma_addr(paddr, sizeof(uint64_t)); - - if (!m5AlphaAccess) - panic("could not translate m5AlphaAccess addr\n"); - - *m5AlphaAccess = htog(EV5::Phys2K0Seg(access)); + virtPort.write(addr, htog(EV5::Phys2K0Seg(access))); } else panic("could not find m5AlphaAccess\n"); } @@ -234,7 +217,6 @@ AlphaSystem::unserialize(Checkpoint *cp, const std::string §ion) BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem) Param<Tick> boot_cpu_frequency; - SimObjectParam<MemoryController *> memctrl; SimObjectParam<PhysicalMemory *> physmem; Param<std::string> kernel; @@ -257,7 +239,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem) BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem) 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"), @@ -279,7 +260,6 @@ CREATE_SIM_OBJECT(AlphaSystem) 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; diff --git a/arch/alpha/tlb.cc b/arch/alpha/tlb.cc index 3f991b10c..a1a7c9366 100644 --- a/arch/alpha/tlb.cc +++ b/arch/alpha/tlb.cc @@ -93,7 +93,7 @@ AlphaTLB::lookup(Addr vpn, uint8_t asn) const } -void +Fault AlphaTLB::checkCacheability(CpuRequestPtr &req) { // in Alpha, cacheability is controlled by upper-level bits of the @@ -115,17 +115,7 @@ AlphaTLB::checkCacheability(CpuRequestPtr &req) #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); - } - } + return new UnimpFault("IPR memory space not implemented!"); } else { // mark request as uncacheable req->flags |= UNCACHEABLE; @@ -136,6 +126,7 @@ AlphaTLB::checkCacheability(CpuRequestPtr &req) #endif } } + return NoFault; } @@ -292,10 +283,8 @@ AlphaITB::regStats() Fault -AlphaITB::translate(CpuRequestPtr &req) const +AlphaITB::translate(CpuRequestPtr &req, ExecContext *xc) const { - ExecContext *xc = req->xc; - if (AlphaISA::PcPAL(req->vaddr)) { // strip off PAL PC marker (lsb is 1) req->paddr = (req->vaddr & ~3) & PAddrImplMask; @@ -368,9 +357,8 @@ AlphaITB::translate(CpuRequestPtr &req) const if (req->paddr & ~PAddrImplMask) return genMachineCheckFault(); - checkCacheability(req); + return checkCacheability(req); - return NoFault; } /////////////////////////////////////////////////////////////////////// @@ -451,9 +439,8 @@ AlphaDTB::regStats() } Fault -AlphaDTB::translate(CpuRequestPtr &req, bool write) const +AlphaDTB::translate(CpuRequestPtr &req, ExecContext *xc, bool write) const { - ExecContext *xc = req->xc; Addr pc = xc->readPC(); AlphaISA::mode_type mode = @@ -583,9 +570,7 @@ AlphaDTB::translate(CpuRequestPtr &req, bool write) const if (req->paddr & ~PAddrImplMask) return genMachineCheckFault(); - checkCacheability(req); - - return NoFault; + return checkCacheability(req); } AlphaISA::PTE & diff --git a/arch/alpha/tlb.hh b/arch/alpha/tlb.hh index fe156b7e3..39faffbee 100644 --- a/arch/alpha/tlb.hh +++ b/arch/alpha/tlb.hh @@ -73,7 +73,7 @@ class AlphaTLB : public SimObject return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask); } - static void checkCacheability(CpuRequestPtr &req); + static Fault checkCacheability(CpuRequestPtr &req); // Checkpointing virtual void serialize(std::ostream &os); @@ -92,7 +92,7 @@ class AlphaITB : public AlphaTLB AlphaITB(const std::string &name, int size); virtual void regStats(); - Fault translate(CpuRequestPtr &req) const; + Fault translate(CpuRequestPtr &req, ExecContext *xc) const; }; class AlphaDTB : public AlphaTLB @@ -115,7 +115,7 @@ class AlphaDTB : public AlphaTLB AlphaDTB(const std::string &name, int size); virtual void regStats(); - Fault translate(CpuRequestPtr &req, bool write) const; + Fault translate(CpuRequestPtr &req, ExecContext *xc, bool write) const; }; #endif // __ALPHA_MEMORY_HH__ diff --git a/arch/alpha/tru64/system.cc b/arch/alpha/tru64/system.cc index d09a0c85d..2ad06d679 100644 --- a/arch/alpha/tru64/system.cc +++ b/arch/alpha/tru64/system.cc @@ -35,8 +35,8 @@ #include "cpu/exec_context.hh" #include "kern/tru64/tru64_events.hh" #include "kern/system_events.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" +#include "mem/physical.hh" +#include "mem/port.hh" #include "sim/builder.hh" using namespace std; @@ -46,12 +46,7 @@ Tru64AlphaSystem::Tru64AlphaSystem(Tru64AlphaSystem::Params *p) { Addr addr = 0; if (kernelSymtab->findAddress("enable_async_printf", addr)) { - Addr paddr = vtophys(physmem, addr); - uint8_t *enable_async_printf = - physmem->dma_addr(paddr, sizeof(uint32_t)); - - if (enable_async_printf) - *(uint32_t *)enable_async_printf = 0; + virtPort.write(addr, (uint32_t)0); } #ifdef DEBUG @@ -96,7 +91,6 @@ Tru64AlphaSystem::~Tru64AlphaSystem() BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem) Param<Tick> boot_cpu_frequency; - SimObjectParam<MemoryController *> memctrl; SimObjectParam<PhysicalMemory *> physmem; Param<string> kernel; @@ -118,7 +112,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem) BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem) 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"), @@ -139,7 +132,6 @@ CREATE_SIM_OBJECT(Tru64AlphaSystem) 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; diff --git a/arch/alpha/vtophys.cc b/arch/alpha/vtophys.cc index 40261426d..41e9b80a3 100644 --- a/arch/alpha/vtophys.cc +++ b/arch/alpha/vtophys.cc @@ -28,33 +28,35 @@ #include <string> +#include "arch/alpha/ev5.hh" #include "arch/alpha/vtophys.hh" +#include "base/chunk_generator.hh" #include "base/trace.hh" #include "cpu/exec_context.hh" -#include "mem/functional/physical.hh" +#include "mem/vport.hh" using namespace std; using namespace AlphaISA; AlphaISA::PageTableEntry -kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, AlphaISA::VAddr vaddr) +AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr) { Addr level1_pte = ptbr + vaddr.level1(); - AlphaISA::PageTableEntry level1 = pmem->phys_read_qword(level1_pte); + AlphaISA::PageTableEntry level1 = mem->read<uint64_t>(level1_pte); if (!level1.valid()) { DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr); return 0; } Addr level2_pte = level1.paddr() + vaddr.level2(); - AlphaISA::PageTableEntry level2 = pmem->phys_read_qword(level2_pte); + AlphaISA::PageTableEntry level2 = mem->read<uint64_t>(level2_pte); if (!level2.valid()) { DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr); return 0; } Addr level3_pte = level2.paddr() + vaddr.level3(); - AlphaISA::PageTableEntry level3 = pmem->phys_read_qword(level3_pte); + AlphaISA::PageTableEntry level3 = mem->read<uint64_t>(level3_pte); if (!level3.valid()) { DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr); return 0; @@ -63,7 +65,7 @@ kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, AlphaISA::VAddr vaddr) } Addr -vtophys(PhysicalMemory *xc, Addr vaddr) +AlphaISA::vtophys(Addr vaddr) { Addr paddr = 0; if (AlphaISA::IsUSeg(vaddr)) @@ -79,7 +81,7 @@ vtophys(PhysicalMemory *xc, Addr vaddr) } Addr -vtophys(ExecContext *xc, Addr addr) +AlphaISA::vtophys(ExecContext *xc, Addr addr) { AlphaISA::VAddr vaddr = addr; Addr ptbr = xc->readMiscReg(AlphaISA::IPR_PALtemp20); @@ -95,7 +97,7 @@ vtophys(ExecContext *xc, Addr addr) paddr = vaddr; } else { AlphaISA::PageTableEntry pte = - kernel_pte_lookup(xc->getPhysMemPtr(), ptbr, vaddr); + kernel_pte_lookup(xc->getPhysPort(), ptbr, vaddr); if (pte.valid()) paddr = pte.paddr() | vaddr.offset(); } @@ -107,162 +109,54 @@ vtophys(ExecContext *xc, Addr addr) return paddr; } -uint8_t * -ptomem(ExecContext *xc, Addr paddr, size_t len) -{ - return xc->getPhysMemPtr()->dma_addr(paddr, len); -} - -uint8_t * -vtomem(ExecContext *xc, Addr vaddr, size_t len) -{ - Addr paddr = vtophys(xc, vaddr); - return xc->getPhysMemPtr()->dma_addr(paddr, len); -} void -CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) +AlphaISA::CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) { - Addr paddr; - char *dmaaddr; - char *dst = (char *)dest; - int len; + uint8_t *dst = (uint8_t *)dest; + VirtualPort *vp = xc->getVirtPort(xc); - paddr = vtophys(xc, src); - len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), - (int)cplen); - dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len); - assert(dmaaddr); + vp->readBlob(src, dst, cplen); - memcpy(dst, dmaaddr, len); - if (len == cplen) - return; - - cplen -= len; - dst += len; - src += len; - - while (cplen > AlphaISA::PageBytes) { - paddr = vtophys(xc, src); - dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, - AlphaISA::PageBytes); - assert(dmaaddr); - - memcpy(dst, dmaaddr, AlphaISA::PageBytes); - cplen -= AlphaISA::PageBytes; - dst += AlphaISA::PageBytes; - src += AlphaISA::PageBytes; - } + xc->delVirtPort(vp); - if (cplen > 0) { - paddr = vtophys(xc, src); - dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, cplen); - assert(dmaaddr); - - memcpy(dst, dmaaddr, cplen); - } } void -CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) +AlphaISA::CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) { - Addr paddr; - char *dmaaddr; - char *src = (char *)source; - int len; - - paddr = vtophys(xc, dest); - len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), - (int)cplen); - dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len); - assert(dmaaddr); - - memcpy(dmaaddr, src, len); - if (len == cplen) - return; - - cplen -= len; - src += len; - dest += len; - - while (cplen > AlphaISA::PageBytes) { - paddr = vtophys(xc, dest); - dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, - AlphaISA::PageBytes); - assert(dmaaddr); - - memcpy(dmaaddr, src, AlphaISA::PageBytes); - cplen -= AlphaISA::PageBytes; - src += AlphaISA::PageBytes; - dest += AlphaISA::PageBytes; - } + uint8_t *src = (uint8_t *)source; + VirtualPort *vp = xc->getVirtPort(xc); - if (cplen > 0) { - paddr = vtophys(xc, dest); - dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, cplen); - assert(dmaaddr); + vp->writeBlob(dest, src, cplen); - memcpy(dmaaddr, src, cplen); - } + xc->delVirtPort(vp); } void -CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) +AlphaISA::CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) { - Addr paddr; - char *dmaaddr; - int len; - - paddr = vtophys(xc, vaddr); - len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), - (int)maxlen); - dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len); - assert(dmaaddr); - - char *term = (char *)memchr(dmaaddr, 0, len); - if (term) - len = term - dmaaddr + 1; - - memcpy(dst, dmaaddr, len); - - if (term || len == maxlen) - return; - - maxlen -= len; - dst += len; - vaddr += len; - - while (maxlen > AlphaISA::PageBytes) { - paddr = vtophys(xc, vaddr); - dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, - AlphaISA::PageBytes); - assert(dmaaddr); - - char *term = (char *)memchr(dmaaddr, 0, AlphaISA::PageBytes); - len = term ? (term - dmaaddr + 1) : AlphaISA::PageBytes; + int len = 0; + VirtualPort *vp = xc->getVirtPort(xc); - memcpy(dst, dmaaddr, len); - if (term) - return; + do { + vp->readBlob(vaddr++, (uint8_t*)dst++, 1); + len++; + } while (len < maxlen && dst[len] != 0 ); - maxlen -= AlphaISA::PageBytes; - dst += AlphaISA::PageBytes; - vaddr += AlphaISA::PageBytes; - } - - if (maxlen > 0) { - paddr = vtophys(xc, vaddr); - dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, maxlen); - assert(dmaaddr); - - char *term = (char *)memchr(dmaaddr, 0, maxlen); - len = term ? (term - dmaaddr + 1) : maxlen; - - memcpy(dst, dmaaddr, len); + xc->delVirtPort(vp); + dst[len] = 0; +} - maxlen -= len; +void +AlphaISA::CopyStringIn(ExecContext *xc, char *src, Addr vaddr) +{ + VirtualPort *vp = xc->getVirtPort(xc); + for (ChunkGenerator gen(vaddr, strlen(src), AlphaISA::PageBytes); !gen.done(); + gen.next()) + { + vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size()); + src += gen.size(); } - - if (maxlen == 0) - dst[maxlen] = '\0'; + xc->delVirtPort(vp); } diff --git a/arch/alpha/vtophys.hh b/arch/alpha/vtophys.hh index 95430ce77..7ab14bc5b 100644 --- a/arch/alpha/vtophys.hh +++ b/arch/alpha/vtophys.hh @@ -32,19 +32,21 @@ #include "arch/alpha/isa_traits.hh" class ExecContext; -class PhysicalMemory; +class FunctionalPort; -AlphaISA::PageTableEntry -kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, AlphaISA::VAddr vaddr); +namespace AlphaISA { -Addr vtophys(PhysicalMemory *xc, Addr vaddr); +PageTableEntry +kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr); + +Addr vtophys(Addr vaddr); Addr vtophys(ExecContext *xc, Addr vaddr); -uint8_t *vtomem(ExecContext *xc, Addr vaddr, size_t len); -uint8_t *ptomem(ExecContext *xc, Addr paddr, size_t len); void CopyOut(ExecContext *xc, void *dst, Addr src, size_t len); void CopyIn(ExecContext *xc, Addr dst, void *src, size_t len); -void CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen); +void CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen); +void CopyStringIn(ExecContext *xc, char *src, Addr vaddr); +}; #endif // __ARCH_ALPHA_VTOPHYS_H__ diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc index 8a6cbdc33..6b85bc680 100644 --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@ -120,16 +120,18 @@ #include <string> #include <unistd.h> +#include "arch/vtophys.hh" #include "base/intmath.hh" #include "base/kgdb.h" #include "base/remote_gdb.hh" #include "base/socket.hh" #include "base/trace.hh" +#include "config/full_system.hh" #include "cpu/exec_context.hh" #include "cpu/static_inst.hh" -#include "mem/functional/physical.hh" +#include "mem/physical.hh" +#include "mem/port.hh" #include "sim/system.hh" -#include "arch/vtophys.hh" using namespace std; using namespace TheISA; @@ -372,7 +374,7 @@ RemoteGDB::acc(Addr va, size_t len) return true; Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20); - TheISA::PageTableEntry pte = kernel_pte_lookup(pmem, ptbr, va); + TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va); if (!pte.valid()) { DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); return false; @@ -632,51 +634,20 @@ RemoteGDB::read(Addr vaddr, size_t size, char *data) static Addr lastaddr = 0; static size_t lastsize = 0; - uint8_t *maddr; - if (vaddr < 10) { DPRINTF(GDBRead, "read: reading memory location zero!\n"); vaddr = lastaddr + lastsize; } DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size); -#if TRACING_ON - char *d = data; - size_t s = size; -#endif - - lastaddr = vaddr; - lastsize = size; - size_t count = min((Addr)size, - VMPageSize - (vaddr & (VMPageSize - 1))); - - maddr = vtomem(context, vaddr, count); - memcpy(data, maddr, count); - - vaddr += count; - data += count; - size -= count; - - while (size >= VMPageSize) { - maddr = vtomem(context, vaddr, count); - memcpy(data, maddr, VMPageSize); - - vaddr += VMPageSize; - data += VMPageSize; - size -= VMPageSize; - } - - if (size > 0) { - maddr = vtomem(context, vaddr, count); - memcpy(data, maddr, size); - } + context->getVirtPort(context)->readBlob(vaddr, (uint8_t*)data, size); #if TRACING_ON if (DTRACE(GDBRead)) { if (DTRACE(GDBExtra)) { char buf[1024]; - mem2hex(buf, d, s); + mem2hex(buf, data, size); DPRINTFNR(": %s\n", buf); } else DPRINTFNR("\n"); @@ -693,8 +664,6 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data) static Addr lastaddr = 0; static size_t lastsize = 0; - uint8_t *maddr; - if (vaddr < 10) { DPRINTF(GDBWrite, "write: writing memory location zero!\n"); vaddr = lastaddr + lastsize; @@ -710,32 +679,7 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data) DPRINTFNR("\n"); } - lastaddr = vaddr; - lastsize = size; - - size_t count = min((Addr)size, - VMPageSize - (vaddr & (VMPageSize - 1))); - - maddr = vtomem(context, vaddr, count); - memcpy(maddr, data, count); - - vaddr += count; - data += count; - size -= count; - - while (size >= VMPageSize) { - maddr = vtomem(context, vaddr, count); - memcpy(maddr, data, VMPageSize); - - vaddr += VMPageSize; - data += VMPageSize; - size -= VMPageSize; - } - - if (size > 0) { - maddr = vtomem(context, vaddr, count); - memcpy(maddr, data, size); - } + context->getVirtPort(context)->writeBlob(vaddr, (uint8_t*)data, size); #ifdef IMB alpha_pal_imb(); diff --git a/cpu/cpu_exec_context.cc b/cpu/cpu_exec_context.cc index a3e6cc432..e76c13fb0 100644 --- a/cpu/cpu_exec_context.cc +++ b/cpu/cpu_exec_context.cc @@ -57,8 +57,9 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, AlphaITB *_itb, AlphaDTB *_dtb) : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0), lastSuspend(0), system(_sys), itb(_itb), - dtb(_dtb), memctrl(_sys->memctrl), profile(NULL), - quiesceEvent(this), func_exe_inst(0), storeCondFailures(0) + dtb(_dtb), profile(NULL), quiesceEvent(this), func_exe_inst(0), + storeCondFailures(0) + { proxy = new ProxyExecContext<CPUExecContext>(this); @@ -77,6 +78,17 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, static ProfileNode dummyNode; profileNode = &dummyNode; profilePC = 3; + + Port *mem_port; + physPort = new FunctionalPort(); + mem_port = system->physmem->getPort("functional"); + mem_port->setPeer(physPort); + physPort->setPeer(mem_port); + + virtPort = new VirtualPort(); + mem_port = system->physmem->getPort("functional"); + mem_port->setPeer(virtPort); + virtPort->setPeer(mem_port); } #else CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, @@ -278,3 +290,31 @@ CPUExecContext::copyArchRegs(ExecContext *xc) TheISA::copyRegs(xc, proxy); } +#if FULL_SYSTEM +VirtualPort* +CPUExecContext::getVirtPort(ExecContext *xc) +{ + if (!xc) + return virtPort; + + VirtualPort *vp; + Port *mem_port; + + vp = new VirtualPort(xc); + mem_port = system->physmem->getPort("functional"); + mem_port->setPeer(vp); + vp->setPeer(mem_port); + return vp; +} + +void +CPUExecContext::delVirtPort(VirtualPort *vp) +{ + assert(!vp->nullExecContext()); + delete vp->getPeer(); + delete vp; +} + + +#endif + diff --git a/cpu/cpu_exec_context.hh b/cpu/cpu_exec_context.hh index 7ceb7f2d8..22d2811d0 100644 --- a/cpu/cpu_exec_context.hh +++ b/cpu/cpu_exec_context.hh @@ -48,7 +48,9 @@ class BaseCPU; class FunctionProfile; class ProfileNode; -class MemoryController; +class FunctionalPort; +class PhysicalPort; + #else // !FULL_SYSTEM @@ -56,6 +58,7 @@ class MemoryController; #include "mem/page_table.hh" class TranslatingPort; + #endif // FULL_SYSTEM // @@ -126,11 +129,13 @@ class CPUExecContext AlphaITB *itb; AlphaDTB *dtb; - // 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; + /** A functional port outgoing only for functional accesses to physical + * addresses.*/ + FunctionalPort *physPort; + + /** A functional port, outgoing only, for functional accesse to virtual + * addresses. That doen't require execution context information */ + VirtualPort *virtPort; FunctionProfile *profile; ProfileNode *profileNode; @@ -238,19 +243,28 @@ class CPUExecContext Fault translateInstReq(CpuRequestPtr &req) { - return itb->translate(req); + return itb->translate(req, proxy); } Fault translateDataReadReq(CpuRequestPtr &req) { - return dtb->translate(req, false); + return dtb->translate(req, proxy, false); } Fault translateDataWriteReq(CpuRequestPtr &req) { - return dtb->translate(req, true); + return dtb->translate(req, proxy, true); } + FunctionalPort *getPhysPort() { return physPort; } + + /** Return a virtual port. If no exec context is specified then a static + * port is returned. Otherwise a port is created and returned. It must be + * deleted by deleteVirtPort(). */ + VirtualPort *getVirtPort(ExecContext *xc); + + void delVirtPort(VirtualPort *vp); + #else TranslatingPort *getMemPort() { return port; } diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 8f93875a1..85e4bfd4a 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -43,6 +43,8 @@ class AlphaITB; class BaseCPU; class Event; class TranslatingPort; +class FunctionalPort; +class VirtualPort; class Process; class System; @@ -93,6 +95,12 @@ class ExecContext virtual AlphaITB *getITBPtr() = 0; virtual AlphaDTB * getDTBPtr() = 0; + + virtual FunctionalPort *getPhysPort() = 0; + + virtual VirtualPort *getVirtPort(ExecContext *xc = NULL) = 0; + + virtual void delVirtPort(VirtualPort *vp) = 0; #else virtual TranslatingPort *getMemPort() = 0; @@ -259,6 +267,12 @@ class ProxyExecContext : public ExecContext AlphaITB *getITBPtr() { return actualXC->getITBPtr(); } AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); } + + FunctionalPort *getPhysPort() { return actualXC->getPhysPort(); } + + VirtualPort *getVirtPort(ExecContext *xc = NULL) { return actualXC->getVirtPort(xc); } + + void delVirtPort(VirtualPort *vp) { return actualXC->delVirtPort(vp); } #else TranslatingPort *getMemPort() { return actualXC->getMemPort(); } diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index ad3b16fc0..91cfc0ec3 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -41,9 +41,10 @@ #include "cpu/base.hh" #include "cpu/exec_context.hh" #include "dev/alpha_console.hh" +#include "dev/platform.hh" #include "dev/simconsole.hh" #include "dev/simple_disk.hh" -#include "dev/tsunami_io.hh" +#include "mem/physical.hh" #include "sim/builder.hh" #include "sim/sim_object.hh" @@ -51,13 +52,14 @@ using namespace std; using namespace AlphaISA; AlphaConsole::AlphaConsole(Params *p) - : PioDevice(p->name, p->platform), disk(p->disk), - console(params()->cons), system(params()->sys), cpu(params()->cpu), - pioSize(sizeof(struct alphaAccess)) + : BasicPioDevice(p), disk(p->disk), + console(params()->cons), system(params()->sys), cpu(params()->cpu) { - alphaAccess = new Access; - alphaAccess->last_offset = size - 1; + pioSize = sizeof(struct AlphaAccess); + + alphaAccess = new Access(); + alphaAccess->last_offset = pioSize - 1; alphaAccess->version = ALPHA_ACCESS_VERSION; alphaAccess->diskUnit = 1; @@ -70,7 +72,7 @@ AlphaConsole::AlphaConsole(Params *p) alphaAccess->inputChar = 0; bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack)); - system->setAlphaAccess(addr); + system->setAlphaAccess(pioAddr); } void @@ -82,9 +84,18 @@ AlphaConsole::startup() alphaAccess->entryPoint = system->getKernelEntry(); alphaAccess->mem_size = system->physmem->size(); alphaAccess->cpuClock = cpu->frequency() / 1000000; // In MHz - alphaAccess->intrClockFrequency = platform->intrFrequency(); + alphaAccess->intrClockFrequency = params()->platform->intrFrequency(); +} + +void +AlphaConsole::addressRanges(AddrRangeList &range_list) +{ + assert(pioSize != 0); + range_list.clear(); + range_list.push_back(RangeSize(pioAddr, sizeof(struct AlphaAccess))); } + Tick AlphaConsole::read(Packet &pkt) { @@ -97,25 +108,34 @@ AlphaConsole::read(Packet &pkt) assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - Addr daddr = req.addr - pioAddr; + Addr daddr = pkt.addr - pioAddr; + + uint32_t *data32; + uint64_t *data64; - switch (req.size) + switch (pkt.size) { case sizeof(uint32_t): - if (!pkt.data) pkt.pkt.data = new uint32_t; + if (!pkt.data) { + data32 = new uint32_t; + pkt.data = (uint8_t*)data32; + } + else + data32 = (uint32_t*)pkt.data; + switch (daddr) { case offsetof(AlphaAccess, last_offset): - *(uint32_t*)pkt.data = alphaAccess->last_offset; + *data32 = alphaAccess->last_offset; break; case offsetof(AlphaAccess, version): - *(uint32_t*)pkt.data = alphaAccess->version; + *data32 = alphaAccess->version; break; case offsetof(AlphaAccess, numCPUs): - *(uint32_t*)pkt.data = alphaAccess->numCPUs; + *data32 = alphaAccess->numCPUs; break; case offsetof(AlphaAccess, intrClockFrequency): - *(uint32_t*)pkt.data = alphaAccess->intrClockFrequency; + *data32 = alphaAccess->intrClockFrequency; break; default: /* Old console code read in everyting as a 32bit int @@ -123,60 +143,63 @@ AlphaConsole::read(Packet &pkt) */ pkt.result = BadAddress; } - DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, - *(uint32_t*)pkt.data); + DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *data32); break; case sizeof(uint64_t): - if (!pkt.data) pkt.pkt.data = new uint64_t; + if (!pkt.data) { + data64 = new uint64_t; + pkt.data = (uint8_t*)data64; + } + else + data64 = (uint64_t*)pkt.data; switch (daddr) { case offsetof(AlphaAccess, inputChar): - *(uint64_t*)pkt.data = console->console_in(); + *data64 = console->console_in(); break; case offsetof(AlphaAccess, cpuClock): - *(uint64_t*)pkt.data = alphaAccess->cpuClock; + *data64 = alphaAccess->cpuClock; break; case offsetof(AlphaAccess, mem_size): - *(uint64_t*)pkt.data = alphaAccess->mem_size; + *data64 = alphaAccess->mem_size; break; case offsetof(AlphaAccess, kernStart): - *(uint64_t*)pkt.data = alphaAccess->kernStart; + *data64 = alphaAccess->kernStart; break; case offsetof(AlphaAccess, kernEnd): - *(uint64_t*)pkt.data = alphaAccess->kernEnd; + *data64 = alphaAccess->kernEnd; break; case offsetof(AlphaAccess, entryPoint): - *(uint64_t*)pkt.data = alphaAccess->entryPoint; + *data64 = alphaAccess->entryPoint; break; case offsetof(AlphaAccess, diskUnit): - *(uint64_t*)pkt.data = alphaAccess->diskUnit; + *data64 = alphaAccess->diskUnit; break; case offsetof(AlphaAccess, diskCount): - *(uint64_t*)pkt.data = alphaAccess->diskCount; + *data64 = alphaAccess->diskCount; break; case offsetof(AlphaAccess, diskPAddr): - *(uint64_t*)pkt.data = alphaAccess->diskPAddr; + *data64 = alphaAccess->diskPAddr; break; case offsetof(AlphaAccess, diskBlock): - *(uint64_t*)pkt.data = alphaAccess->diskBlock; + *data64 = alphaAccess->diskBlock; break; case offsetof(AlphaAccess, diskOperation): - *(uint64_t*)pkt.data = alphaAccess->diskOperation; + *data64 = alphaAccess->diskOperation; break; case offsetof(AlphaAccess, outputChar): - *(uint64_t*)pkt.data = alphaAccess->outputChar; + *data64 = alphaAccess->outputChar; break; default: int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / sizeof(alphaAccess->cpuStack[0]); if (cpunum >= 0 && cpunum < 64) - *(uint64_t*)pkt.data = alphaAccess->cpuStack[cpunum]; + *data64 = alphaAccess->cpuStack[cpunum]; else panic("Unknown 64bit access, %#x\n", daddr); } - DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, - *(uint64_t*)data); + DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *data64); break; default: pkt.result = BadAddress; @@ -186,15 +209,15 @@ AlphaConsole::read(Packet &pkt) } Tick -AlphaConsole::write(MemReqPtr &req, const uint8_t *data) +AlphaConsole::write(Packet &pkt) { pkt.time = curTick + pioDelay; assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); - Addr daddr = req.addr - pioAddr; + Addr daddr = pkt.addr - pioAddr; - uint64_t val = *(uint64_t *)data; + uint64_t val = *(uint64_t *)pkt.data; assert(pkt.size == sizeof(uint64_t)); switch (daddr) { @@ -303,14 +326,11 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) SimObjectParam<SimConsole *> sim_console; SimObjectParam<SimpleDisk *> disk; - SimObjectParam<MemoryController *> mmu; Param<Addr> addr; SimObjectParam<AlphaSystem *> system; SimObjectParam<BaseCPU *> cpu; SimObjectParam<Platform *> platform; - SimObjectParam<Bus*> pio_bus; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; END_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) @@ -318,21 +338,26 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaConsole) INIT_PARAM(sim_console, "The Simulator Console"), INIT_PARAM(disk, "Simple Disk"), - INIT_PARAM(mmu, "Memory Controller"), INIT_PARAM(addr, "Device Address"), INIT_PARAM(system, "system object"), INIT_PARAM(cpu, "Processor"), INIT_PARAM(platform, "platform"), - INIT_PARAM(pio_bus, "The IO Bus to attach to"), - INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) + INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000) END_INIT_SIM_OBJECT_PARAMS(AlphaConsole) CREATE_SIM_OBJECT(AlphaConsole) { - return new AlphaConsole(getInstanceName(), sim_console, disk, - system, cpu, platform, mmu, addr, hier, pio_bus); + AlphaConsole::Params *p = new AlphaConsole::Params; + p->name = getInstanceName(); + p->platform = platform; + p->pio_addr = addr; + p->pio_delay = pio_latency; + p->cons = sim_console; + p->disk = disk; + p->sys = system; + p->cpu = cpu; + return new AlphaConsole(p); } REGISTER_SIM_OBJECT("AlphaConsole", AlphaConsole) diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index 6f3ea15a6..99c4b00a1 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -43,7 +43,6 @@ class BaseCPU; class SimConsole; class AlphaSystem; class SimpleDisk; -class MemoryController; /** * Memory mapped interface to the system console. This device @@ -70,7 +69,7 @@ class MemoryController; * primarily used doing boot before the kernel has loaded its device * drivers. */ -class AlphaConsole : public BasePioDevice +class AlphaConsole : public BasicPioDevice { protected: struct Access : public AlphaAccess @@ -97,12 +96,12 @@ class AlphaConsole : public BasePioDevice BaseCPU *cpu; public: - struct Params : public BasePioDevice::Params + struct Params : public BasicPioDevice::Params { SimConsole *cons; SimpleDisk *disk; AlphaSystem *sys; - BaseCpu *cpu; + BaseCPU *cpu; }; protected: const Params *params() const {return (const Params *)_params; } @@ -120,14 +119,14 @@ class AlphaConsole : public BasePioDevice virtual Tick read(Packet &pkt); virtual Tick write(Packet &pkt); + /** Address ranges this device is sensitive to. */ + virtual void addressRanges(AddrRangeList &range_list); + /** * standard serialization routines for checkpointing */ virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); - - public: - Tick cacheAccess(MemReqPtr &req); }; #endif // __ALPHA_CONSOLE_HH__ diff --git a/dev/io_device.cc b/dev/io_device.cc index ac993d78d..5d3a87006 100644 --- a/dev/io_device.cc +++ b/dev/io_device.cc @@ -48,9 +48,10 @@ PioPort::recvFunctional(Packet &pkt) } void -PioPort::getDeviceAddressRanges(AddrRangeList &range_list, bool &owner) +PioPort::getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) { - device->addressRanges(range_list, owner); + snoop.clear(); + device->addressRanges(resp); } @@ -100,8 +101,8 @@ DmaPort::recvTiming(Packet &pkt) return Success; } -DmaDevice::DmaDevice(const std::string &name, Platform *p) - : PioDevice(name, p) +DmaDevice::DmaDevice(Params *p) + : PioDevice(p) { dmaPort = new DmaPort(this); } @@ -195,13 +196,4 @@ DmaDevice::~DmaDevice() delete dmaPort; } -void -BasePioDevice::addressRanges(AddrRangeList &range_list, bool &owner) -{ - assert(pioSize != 0); - owner = true; - range_list.clear(); - range_list.push_back(RangeSize(pio_addr, sizeof(struct alphaAccess))); -} - diff --git a/dev/io_device.hh b/dev/io_device.hh index e2565cfdc..a8c36fdd9 100644 --- a/dev/io_device.hh +++ b/dev/io_device.hh @@ -75,7 +75,7 @@ class PioPort : public Port virtual void recvStatusChange(Status status) { peerStatus = status; } - virtual void getDeviceAddressRanges(AddrRangeList &range_list, bool &owner); + virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop); /** * This class is used to implemented sendTiming() with a delay. When a delay @@ -131,8 +131,8 @@ class DmaPort : public Port virtual Packet *recvRetry() ; - virtual void getDeviceAddressRanges(AddrRangeList &range_list, bool &owner) - { range_list.clear(); owner = true; } + virtual void getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) + { resp.clear(); snoop.clear(); } class SendEvent : public Event { @@ -183,7 +183,7 @@ class PioDevice : public SimObject * that it sees. */ PioPort *pioPort; - virtual void addressRanges(AddrRangeList &range_list, bool &owner) = 0; + virtual void addressRanges(AddrRangeList &range_list) = 0; /** As far as the devices are concerned they only accept atomic transactions * which are converted to either a write or a read. */ @@ -208,26 +208,27 @@ class PioDevice : public SimObject std::string name; Platform *platform; }; + protected: Params *_params; public: const Params *params() const { return _params; } - PioDevice(Params *params) - : SimObject(params()->name), platform(params()->platform) + PioDevice(Params *p) + : SimObject(params()->name), platform(p->platform), _params(p) {} virtual ~PioDevice(); virtual Port *getPort(const std::string &if_name) { - if (if_name == "pio") + if (if_name == "pio") { if (pioPort != NULL) panic("pio port already connected to."); pioPort = new PioPort(this, params()->platform); return pioPort; - else + } else return NULL; } friend class PioPort; @@ -237,7 +238,7 @@ class PioDevice : public SimObject class BasicPioDevice : public PioDevice { public: - struct Params + struct Params : public PioDevice::Params { Addr pio_addr; Tick pio_delay; @@ -248,17 +249,16 @@ class BasicPioDevice : public PioDevice Addr pioAddr; /** Size that the device's address range. */ - Addr pioSize = 0; + Addr pioSize; /** Delay that the device experinces on an access. */ Tick pioDelay; public: - BasePioDevice(Params *p) - : PioDevice(p), pioAddr(p->pio_addr), pioDelay(p->pioDelay) + BasicPioDevice(Params *p) + : PioDevice(p), pioAddr(p->pio_addr), pioSize(0), pioDelay(p->pio_delay) {} - virtual void addressRanges(AddrRangeList &range_list, bool &owner); }; class DmaDevice : public PioDevice @@ -267,7 +267,7 @@ class DmaDevice : public PioDevice DmaPort *dmaPort; public: - DmaDevice(const std::string &name, Platform *p); + DmaDevice(Params *p); virtual ~DmaDevice(); virtual Port *getPort(const std::string &if_name) diff --git a/kern/linux/events.cc b/kern/linux/events.cc index 9f50eef04..b688e9dd0 100644 --- a/kern/linux/events.cc +++ b/kern/linux/events.cc @@ -46,7 +46,7 @@ DebugPrintkEvent::process(ExecContext *xc) DPRINTFN(""); } - AlphaArguments args(xc); + AlphaISA::AlphaArguments args(xc); Printk(args); SkipFuncEvent::process(xc); } diff --git a/kern/linux/printk.cc b/kern/linux/printk.cc index f5313759b..918b8dabe 100644 --- a/kern/linux/printk.cc +++ b/kern/linux/printk.cc @@ -36,7 +36,7 @@ using namespace std; void -Printk(AlphaArguments args) +Printk(AlphaISA::AlphaArguments args) { char *p = (char *)args++; diff --git a/kern/linux/printk.hh b/kern/linux/printk.hh index 45eab6b88..b88c40f5e 100644 --- a/kern/linux/printk.hh +++ b/kern/linux/printk.hh @@ -29,8 +29,8 @@ #ifndef __PRINTK_HH__ #define __PRINTK_HH__ -class AlphaArguments; +class AlphaISA::AlphaArguments; -void Printk(AlphaArguments args); +void Printk(AlphaISA::AlphaArguments args); #endif // __PRINTK_HH__ diff --git a/kern/tru64/dump_mbuf.hh b/kern/tru64/dump_mbuf.hh index 0ff5da3d7..9e1698ff1 100644 --- a/kern/tru64/dump_mbuf.hh +++ b/kern/tru64/dump_mbuf.hh @@ -29,10 +29,10 @@ #ifndef __DUMP_MBUF_HH__ #define __DUMP_MBUF_HH__ -class AlphaArguments; +#include "arch/arguments.hh" namespace tru64 { - void DumpMbuf(AlphaArguments args); + void DumpMbuf(AlphaISA::AlphaArguments args); } #endif // __DUMP_MBUF_HH__ diff --git a/kern/tru64/printf.cc b/kern/tru64/printf.cc index 77ac17c3a..319d36673 100644 --- a/kern/tru64/printf.cc +++ b/kern/tru64/printf.cc @@ -40,7 +40,7 @@ using namespace std; namespace tru64 { void -Printf(AlphaArguments args) +Printf(AlphaISA::AlphaArguments args) { char *p = (char *)args++; diff --git a/kern/tru64/printf.hh b/kern/tru64/printf.hh index a48b4482c..61236e83a 100644 --- a/kern/tru64/printf.hh +++ b/kern/tru64/printf.hh @@ -29,10 +29,10 @@ #ifndef __PRINTF_HH__ #define __PRINTF_HH__ -class AlphaArguments; +#include "arch/arguments.hh" namespace tru64 { - void Printf(AlphaArguments args); + void Printf(AlphaISA::AlphaArguments args); } #endif // __PRINTF_HH__ diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc index 855c3cd36..69fc5c55d 100644 --- a/kern/tru64/tru64_events.cc +++ b/kern/tru64/tru64_events.cc @@ -32,7 +32,6 @@ #include "kern/tru64/tru64_events.hh" #include "kern/tru64/dump_mbuf.hh" #include "kern/tru64/printf.hh" -#include "mem/functional/memory_control.hh" #include "arch/alpha/ev5.hh" #include "arch/arguments.hh" #include "arch/isa_traits.hh" @@ -51,9 +50,19 @@ BadAddrEvent::process(ExecContext *xc) uint64_t a0 = xc->readIntReg(ArgumentReg0); - if (!TheISA::IsK0Seg(a0) || - xc->getSystemPtr()->memctrl->badaddr( - TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask)) { + AddrRangeList resp; + AddrRangeList snoop; + AddrRangeIter iter; + bool found = false; + + xc->getPhysPort()->getPeerAddressRanges(resp, snoop); + for(iter = resp.begin(); iter != resp.end(); iter++) + { + if (*iter == (TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask)) + found = true; + } + + if (!TheISA::IsK0Seg(a0) || found ) { DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0); xc->setIntReg(ReturnValueReg, 0x1); diff --git a/mem/bus.cc b/mem/bus.cc index dd72ad3b9..0cadc2045 100644 --- a/mem/bus.cc +++ b/mem/bus.cc @@ -89,11 +89,12 @@ Bus::recvStatusChange(Port::Status status, int id) "The other statuses need to be implemented."); Port *port = interfaces[id]; AddrRangeList ranges; - bool owner; + AddrRangeList snoops; + + port->getPeerAddressRanges(ranges, snoops); - port->getPeerAddressRanges(ranges, owner); // not dealing with snooping yet either - assert(owner == true); + assert(snoops.size() == 0); // or multiple ranges assert(ranges.size() == 1); DevMap dm; @@ -104,7 +105,7 @@ Bus::recvStatusChange(Port::Status status, int id) } void -Bus::BusPort::addressRanges(AddrRangeList &range_list, bool &owner) +Bus::BusPort::addressRanges(AddrRangeList &resp, AddrRangeList &snoop) { panic("I'm not implemented.\n"); } diff --git a/mem/physical.hh b/mem/physical.hh index 6d7d809a1..53e86f85f 100644 --- a/mem/physical.hh +++ b/mem/physical.hh @@ -63,14 +63,12 @@ class PhysicalMemory : public MemObject virtual void recvStatusChange(Status status); - virtual void getDeviceAddressRanges(AddrRangeList &range_list, - bool &owner); + virtual void getDeviceAddressRanges(AddrRangeList &resp, + AddrRangeList &snoop); virtual int deviceBlockSize(); }; - virtual Port *getPort(const std::string &if_name); - int numPorts; int lat; @@ -107,7 +105,8 @@ class PhysicalMemory : public MemObject public: int deviceBlockSize(); - void getAddressRanges(AddrRangeList &rangeList, bool &owner); + void getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop); + virtual Port *getPort(const std::string &if_name); void virtual init() { port->sendStatusChange(Port::RangeChange); } // fast back-door memory access for vtophys(), remote gdb, etc. @@ -125,14 +124,4 @@ class PhysicalMemory : public MemObject }; -/*uint64_t -PhysicalMemory::phys_read_qword(Addr addr) const -{ - if (addr + sizeof(uint64_t) > pmem_size) - return 0; - - return *(uint64_t *)(pmem_addr + addr); -}*/ - - #endif //__PHYSICAL_MEMORY_HH__ diff --git a/mem/port.hh b/mem/port.hh index 1884e96bf..9557f654c 100644 --- a/mem/port.hh +++ b/mem/port.hh @@ -38,7 +38,6 @@ #ifndef __MEM_PORT_HH__ #define __MEM_PORT_HH__ -#include <string> #include <list> #include <inttypes.h> @@ -55,6 +54,7 @@ */ typedef std::list<Range<Addr> > AddrRangeList; +typedef std::list<Range<Addr> >::iterator AddrRangeIter; /** * Ports are used to interface memory objects to @@ -132,15 +132,11 @@ class Port /** The peer port is requesting us to reply with a list of the ranges we are responsible for. - @param owner is an output param that, if set, indicates that the - port is the owner of the specified ranges (i.e., slave, default - responder, etc.). If 'owner' is false, the interface is - interested in the specified ranges for snooping purposes. If - an object wants to own some ranges and snoop on others, it will - need to use two different ports. + @param resp is a list of ranges responded to + @param snoop is a list of ranges snooped */ - virtual void getDeviceAddressRanges(AddrRangeList &range_list, - bool &owner) + virtual void getDeviceAddressRanges(AddrRangeList &resp, + AddrRangeList &snoop) { panic("??"); } public: @@ -189,8 +185,8 @@ class Port /** Called by the associated device if it wishes to find out the address ranges connected to the peer ports devices. */ - void getPeerAddressRanges(AddrRangeList &range_list, bool &owner) - { peer->getDeviceAddressRanges(range_list, owner); } + void getPeerAddressRanges(AddrRangeList &resp, AddrRangeList &snoop) + { peer->getDeviceAddressRanges(resp, snoop); } /** This function is a wrapper around sendFunctional() that breaks a larger, arbitrarily aligned access into @@ -232,7 +228,20 @@ class FunctionalPort : public Port virtual Tick recvAtomic(Packet &pkt) { panic("FuncPort is UniDir"); } virtual void recvFunctional(Packet &pkt) { panic("FuncPort is UniDir"); } virtual void recvStatusChange(Status status) {panic("FuncPort is UniDir");} -}; + template <typename T> + inline void write(Addr addr, T d) + { + writeBlob(addr, (uint8_t*)&d, sizeof(T)); + } + + template <typename T> + inline T read(Addr addr) + { + T d; + readBlob(addr, (uint8_t*)&d, sizeof(T)); + return d; + } +}; #endif //__MEM_PORT_HH__ diff --git a/mem/vport.cc b/mem/vport.cc new file mode 100644 index 000000000..cc569acf3 --- /dev/null +++ b/mem/vport.cc @@ -0,0 +1,69 @@ +/* + * Copyright (c) 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. + */ + +/** + * @file Port object definitions. + */ + +#include "base/chunk_generator.hh" +#include "mem/vport.hh" + +void +VirtualPort::readBlob(Addr addr, uint8_t *p, int size) +{ + Addr paddr; + for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done(); + gen.next()) + { + if (xc) + paddr = TheISA::vtophys(xc,gen.addr()); + else + paddr = TheISA::vtophys(gen.addr()); + + FunctionalPort::readBlob(paddr, p, gen.size()); + p += gen.size(); + } +} + +void +VirtualPort::writeBlob(Addr addr, uint8_t *p, int size) +{ + Addr paddr; + for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done(); + gen.next()) + { + if (xc) + paddr = TheISA::vtophys(xc,gen.addr()); + else + paddr = TheISA::vtophys(gen.addr()); + + FunctionalPort::writeBlob(paddr, p, gen.size()); + p += gen.size(); + } +} + diff --git a/mem/vport.hh b/mem/vport.hh new file mode 100644 index 000000000..da036b981 --- /dev/null +++ b/mem/vport.hh @@ -0,0 +1,109 @@ +/* + * Copyright (c) 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. + */ + +/** + * @file + * Virtual Port Object Decleration. These ports incorporate some translation + * into their access methods. Thus you can use one to read and write data + * to/from virtual addresses. + */ + +#ifndef __MEM_VPORT_HH__ +#define __MEM_VPORT_HH__ + +#include "mem/port.hh" +#include "config/full_system.hh" +#include "arch/vtophys.hh" + + +/** A class that translates a virtual address to a physical address and then + * calls the above read/write functions. If an execution context is provided the + * address can alway be translated, If not it can only be translated if it is a + * simple address masking operation (such as alpha super page accesses). + */ + +class VirtualPort : public FunctionalPort +{ + private: + ExecContext *xc; + + public: + VirtualPort(ExecContext *_xc = NULL) + : xc(_xc) + {} + + /** Return true if we have an exec context. This is used to prevent someone + * from accidently deleting the cpus statically allocated vport. + * @return true if an execution context isn't valid + */ + bool nullExecContext() { return xc != NULL; } + + /** Write a piece of data into a virtual address. + * @param vaddr virtual address to write to + * @param data data to write + */ + template <typename T> + inline void write(Addr vaddr, T data) + { + Addr paddr; + if (xc) + paddr = TheISA::vtophys(xc,vaddr); + else + paddr = TheISA::vtophys(vaddr); + + FunctionalPort::write(paddr, data); + } + + /** Read data from a virtual address and return it. + * @param vaddr address to read + * @return data read + */ + + template <typename T> + inline T read(Addr vaddr) + { + Addr paddr; + if (xc) + paddr = TheISA::vtophys(xc,vaddr); + else + paddr = TheISA::vtophys(vaddr); + + return FunctionalPort::read<T>(paddr); + } + + /** Version of readblob that translates virt->phys and deals + * with page boundries. */ + virtual void readBlob(Addr addr, uint8_t *p, int size); + + /** Version of writeBlob that translates virt->phys and deals + * with page boundries. */ + virtual void writeBlob(Addr addr, uint8_t *p, int size); +}; + +#endif //__MEM_VPORT_HH__ + diff --git a/sim/pseudo_inst.cc b/sim/pseudo_inst.cc index e475006e7..3cdc05e78 100644 --- a/sim/pseudo_inst.cc +++ b/sim/pseudo_inst.cc @@ -175,7 +175,7 @@ namespace AlphaPseudo addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr) { char symb[100]; - CopyString(xc, symb, symbolAddr, 100); + CopyStringOut(xc, symb, symbolAddr, 100); std::string symbol(symb); DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); diff --git a/sim/system.cc b/sim/system.cc index cfa316b11..17845ef76 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -1,16 +1,17 @@ +#include "arch/isa_traits.hh" #include "base/loader/object_file.hh" #include "base/loader/symtab.hh" +#include "base/trace.hh" #include "cpu/exec_context.hh" +#include "mem/mem_object.hh" #include "sim/builder.hh" -#include "arch/isa_traits.hh" #include "sim/byteswap.hh" #include "sim/system.hh" -#include "base/trace.hh" -#include "mem/mem_object.hh" #if FULL_SYSTEM +#include "arch/vtophys.hh" #include "base/remote_gdb.hh" #include "kern/kernel_stats.hh" -#include "arch/vtophys.hh" +#include "mem/physical.hh" #endif using namespace std; @@ -23,7 +24,7 @@ int System::numSystemsRunning = 0; System::System(Params *p) : SimObject(p->name), physmem(p->physmem), numcpus(0), #if FULL_SYSTEM - memctrl(p->memctrl), init_param(p->init_param), + init_param(p->init_param), #else page_ptr(0), #endif @@ -45,6 +46,10 @@ System::System(Params *p) functionalPort.setPeer(mem_port); mem_port->setPeer(&functionalPort); + mem_port = physmem->getPort("functional"); + virtPort.setPeer(mem_port); + mem_port->setPeer(&virtPort); + /** * Load the kernel code into memory diff --git a/sim/system.hh b/sim/system.hh index 11f8ac70a..3c2c27bee 100644 --- a/sim/system.hh +++ b/sim/system.hh @@ -40,13 +40,13 @@ #include "sim/sim_object.hh" #if FULL_SYSTEM #include "kern/system_events.hh" +#include "mem/vport.hh" #endif class BaseCPU; class ExecContext; -class MemoryController; class ObjectFile; -class MemObject; +class PhysicalMemory; #if FULL_SYSTEM class Platform; @@ -58,7 +58,7 @@ namespace Kernel { class Binning; } class System : public SimObject { public: - MemObject *physmem; + PhysicalMemory *physmem; PCEventQueue pcEventQueue; std::vector<ExecContext *> execContexts; @@ -73,13 +73,13 @@ class System : public SimObject } #if FULL_SYSTEM - MemoryController *memctrl; Platform *platform; uint64_t init_param; /** Port to physical memory used for writing object files into ram at * boot.*/ FunctionalPort functionalPort; + VirtualPort virtPort; /** kernel symbol table */ SymbolTable *kernelSymtab; @@ -151,11 +151,10 @@ class System : public SimObject struct Params { std::string name; - MemObject *physmem; + PhysicalMemory *physmem; #if FULL_SYSTEM Tick boot_cpu_frequency; - MemoryController *memctrl; uint64_t init_param; bool bin; std::vector<std::string> binned_fns; diff --git a/sim/vptr.hh b/sim/vptr.hh index 0ec452f25..cc57e63f0 100644 --- a/sim/vptr.hh +++ b/sim/vptr.hh @@ -96,20 +96,26 @@ class VPtr operator T *() { - void *addr = vtomem(xc, ptr, sizeof(T)); + panic("Needs to be rewritten\n"); +/* void *addr = vtomem(xc, ptr, sizeof(T)); return (T *)addr; + */ } T *operator->() { - void *addr = vtomem(xc, ptr, sizeof(T)); + panic("Needs to be rewritten\n"); +/* void *addr = vtomem(xc, ptr, sizeof(T)); return (T *)addr; + */ } T &operator*() { - void *addr = vtomem(xc, ptr, sizeof(T)); + panic("Needs to be rewritten\n"); +/* void *addr = vtomem(xc, ptr, sizeof(T)); return *(T *)addr; + */ } }; |