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:
parent
5936c79ba0
commit
bb80f71f21
38 changed files with 611 additions and 537 deletions
56
SConscript
56
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 &
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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(); }
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -46,7 +46,7 @@ DebugPrintkEvent::process(ExecContext *xc)
|
|||
DPRINTFN("");
|
||||
}
|
||||
|
||||
AlphaArguments args(xc);
|
||||
AlphaISA::AlphaArguments args(xc);
|
||||
Printk(args);
|
||||
SkipFuncEvent::process(xc);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ using namespace std;
|
|||
|
||||
|
||||
void
|
||||
Printk(AlphaArguments args)
|
||||
Printk(AlphaISA::AlphaArguments args)
|
||||
{
|
||||
char *p = (char *)args++;
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -40,7 +40,7 @@ using namespace std;
|
|||
namespace tru64 {
|
||||
|
||||
void
|
||||
Printf(AlphaArguments args)
|
||||
Printf(AlphaISA::AlphaArguments args)
|
||||
{
|
||||
char *p = (char *)args++;
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
33
mem/port.hh
33
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__
|
||||
|
|
69
mem/vport.cc
Normal file
69
mem/vport.cc
Normal 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
109
mem/vport.hh
Normal 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__
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
12
sim/vptr.hh
12
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;
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue