fixes for new memory system

SConscript:
    comment out most devices
    add vport.cc
arch/alpha/arguments.cc:
arch/alpha/arguments.hh:
    push in alpha name space
    fix for new memory system
arch/alpha/faults.cc:
arch/alpha/faults.hh:
    Added an unimplemented fault that can be returned if a certain
    function isn't implemented
arch/alpha/freebsd/system.cc:
arch/alpha/linux/system.cc:
arch/alpha/stacktrace.cc:
arch/alpha/system.cc:
arch/alpha/tlb.hh:
arch/alpha/tru64/system.cc:
    fixed for new memory system
arch/alpha/tlb.cc:
    fixed for new memory system
    removed code that seems to have no purpose
arch/alpha/vtophys.cc:
arch/alpha/vtophys.hh:
    fixed for new memory system
    put in namespace AlphaISA
base/remote_gdb.cc:
    fix for new memory system
cpu/cpu_exec_context.cc:
cpu/cpu_exec_context.hh:
cpu/exec_context.hh:
    create two ports one of physical accesses and one for superpage accesses
    Add functions getVirtPort() getPhysPort() delVirtPort(). To get statically
    allocated physical or virtual ports or if an execcontext is passed in
    get a dynamically allocated virtual port
dev/alpha_console.cc:
dev/alpha_console.hh:
    Redo for new memory system
dev/io_device.cc:
dev/io_device.hh:
    new I/O devices for new memory system
kern/linux/events.cc:
kern/linux/printk.cc:
kern/linux/printk.hh:
kern/tru64/dump_mbuf.hh:
kern/tru64/printf.cc:
kern/tru64/printf.hh:
    Arguments now in namespaces
kern/tru64/tru64_events.cc:
mem/bus.cc:
    fix for new memory syste
mem/physical.hh:
    new addressranges function
    getPort should be public
mem/port.hh:
    Add write/read methods to functional port
    update getDeviceAddrRanges to have a list of both snoops and response lists
sim/pseudo_inst.cc:
sim/system.cc:
sim/system.hh:
    Update for new mem system
sim/vptr.hh:
    comment out code and replace with panics
    This will need to be fixed at some point, but it's not easy.

--HG--
extra : convert_revision : 41f41f422cfbab3751284d55cccb6ea64a7956e2
This commit is contained in:
Ali Saidi 2006-04-06 00:51:46 -04:00
parent 5936c79ba0
commit bb80f71f21
38 changed files with 611 additions and 537 deletions

View file

@ -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

View file

@ -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;
}
}

View file

@ -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__

View file

@ -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

View file

@ -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__

View file

@ -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;

View file

@ -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;

View file

@ -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";

View file

@ -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 &section)
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;

View file

@ -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 &

View file

@ -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__

View file

@ -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;

View file

@ -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)
void
AlphaISA::CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen)
{
Addr paddr = vtophys(xc, vaddr);
return xc->getPhysMemPtr()->dma_addr(paddr, len);
uint8_t *dst = (uint8_t *)dest;
VirtualPort *vp = xc->getVirtPort(xc);
vp->readBlob(src, dst, cplen);
xc->delVirtPort(vp);
}
void
CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen)
AlphaISA::CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen)
{
Addr paddr;
char *dmaaddr;
char *dst = (char *)dest;
int len;
uint8_t *src = (uint8_t *)source;
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->writeBlob(dest, src, 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;
}
if (cplen > 0) {
paddr = vtophys(xc, src);
dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, cplen);
assert(dmaaddr);
memcpy(dst, dmaaddr, cplen);
}
xc->delVirtPort(vp);
}
void
CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen)
AlphaISA::CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen)
{
Addr paddr;
char *dmaaddr;
char *src = (char *)source;
int len;
int len = 0;
VirtualPort *vp = xc->getVirtPort(xc);
paddr = vtophys(xc, dest);
len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)),
(int)cplen);
dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len);
assert(dmaaddr);
do {
vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
len++;
} while (len < maxlen && dst[len] != 0 );
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;
}
if (cplen > 0) {
paddr = vtophys(xc, dest);
dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, cplen);
assert(dmaaddr);
memcpy(dmaaddr, src, cplen);
}
xc->delVirtPort(vp);
dst[len] = 0;
}
void
CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen)
AlphaISA::CopyStringIn(ExecContext *xc, char *src, Addr vaddr)
{
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;
memcpy(dst, dmaaddr, len);
if (term)
return;
maxlen -= AlphaISA::PageBytes;
dst += AlphaISA::PageBytes;
vaddr += AlphaISA::PageBytes;
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) {
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);
maxlen -= len;
}
if (maxlen == 0)
dst[maxlen] = '\0';
xc->delVirtPort(vp);
}

View file

@ -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__

View file

@ -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();

View file

@ -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

View file

@ -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; }

View file

@ -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(); }

View file

@ -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;
switch (req.size)
uint32_t *data32;
uint64_t *data64;
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)

View file

@ -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 &section);
public:
Tick cacheAccess(MemReqPtr &req);
};
#endif // __ALPHA_CONSOLE_HH__

View file

@ -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)));
}

View file

@ -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)

View file

@ -46,7 +46,7 @@ DebugPrintkEvent::process(ExecContext *xc)
DPRINTFN("");
}
AlphaArguments args(xc);
AlphaISA::AlphaArguments args(xc);
Printk(args);
SkipFuncEvent::process(xc);
}

View file

@ -36,7 +36,7 @@ using namespace std;
void
Printk(AlphaArguments args)
Printk(AlphaISA::AlphaArguments args)
{
char *p = (char *)args++;

View file

@ -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__

View file

@ -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__

View file

@ -40,7 +40,7 @@ using namespace std;
namespace tru64 {
void
Printf(AlphaArguments args)
Printf(AlphaISA::AlphaArguments args)
{
char *p = (char *)args++;

View file

@ -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__

View file

@ -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);

View file

@ -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");
}

View file

@ -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__

View file

@ -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__

69
mem/vport.cc Normal file
View file

@ -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();
}
}

109
mem/vport.hh Normal file
View file

@ -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__

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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;
*/
}
};