Merge m5.eecs.umich.edu:/bk/newmem
into ewok.(none):/home/gblack/m5/newmem --HG-- extra : convert_revision : bd6352647798275a12d52d55a129cdddd8e25423
This commit is contained in:
commit
6a962f8343
49 changed files with 726 additions and 662 deletions
46
SConscript
46
SConscript
|
@ -183,31 +183,11 @@ 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/simconsole.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
|
||||
|
||||
|
@ -218,10 +198,32 @@ 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/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/sinic.cc
|
||||
# dev/tsunami.cc
|
||||
# dev/tsunami_cchip.cc
|
||||
# dev/isa_fake.cc
|
||||
# dev/tsunami_io.cc
|
||||
# dev/tsunami_pchip.cc
|
||||
|
||||
if env['TARGET_ISA'] == 'alpha':
|
||||
full_system_sources += Split('''
|
||||
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,26 @@ class IntegerOverflowFault : public AlphaFault
|
|||
FaultStat & countStat() {return _count;}
|
||||
};
|
||||
|
||||
class UnimpFault : public AlphaFault
|
||||
{
|
||||
private:
|
||||
std::string panicStr;
|
||||
static FaultName _name;
|
||||
static FaultVect _vect;
|
||||
static FaultStat _count;
|
||||
public:
|
||||
UnimpFault(std::string _str)
|
||||
: panicStr(_str)
|
||||
{ }
|
||||
|
||||
FaultName name() {return _name;}
|
||||
FaultVect vect() {return _vect;}
|
||||
FaultStat & countStat() {return _count;}
|
||||
#if FULL_SYSTEM
|
||||
void invoke(ExecContext * xc);
|
||||
#endif
|
||||
};
|
||||
|
||||
} // 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;
|
||||
|
||||
|
@ -262,6 +270,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()->alpha_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,13 +84,21 @@ 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)
|
||||
{
|
||||
pkt.time = curTick + pioDelay;
|
||||
|
||||
/** XXX Do we want to push the addr munging to a bus brige or something? So
|
||||
* the device has it's physical address and then the bridge adds on whatever
|
||||
|
@ -97,25 +107,36 @@ AlphaConsole::read(Packet &pkt)
|
|||
|
||||
assert(pkt.result == Unknown);
|
||||
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
||||
Addr daddr = req.addr - pioAddr;
|
||||
|
||||
switch (req.size)
|
||||
pkt.time = curTick + pioDelay;
|
||||
Addr daddr = pkt.addr - pioAddr;
|
||||
|
||||
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 +144,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 +210,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 +327,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 +339,27 @@ 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->alpha_sys = system;
|
||||
p->system = 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;
|
||||
AlphaSystem *alpha_sys;
|
||||
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)));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
class Platform;
|
||||
class PioDevice;
|
||||
class DmaDevice;
|
||||
class System;
|
||||
|
||||
/**
|
||||
* The PioPort class is a programmed i/o port that all devices that are
|
||||
|
@ -75,7 +76,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 +132,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 +184,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. */
|
||||
|
@ -207,27 +208,29 @@ class PioDevice : public SimObject
|
|||
{
|
||||
std::string name;
|
||||
Platform *platform;
|
||||
System *system;
|
||||
};
|
||||
|
||||
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 +240,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 +251,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 +269,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)
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
#include "dev/platform.hh"
|
||||
#include "dev/simconsole.hh"
|
||||
#include "dev/uart.hh"
|
||||
#include "mem/functional/memory_control.hh"
|
||||
#include "sim/builder.hh"
|
||||
|
||||
using namespace std;
|
||||
|
|
|
@ -42,14 +42,14 @@
|
|||
#include "base/trace.hh"
|
||||
#include "dev/disk_image.hh"
|
||||
#include "dev/simple_disk.hh"
|
||||
#include "mem/functional/physical.hh"
|
||||
#include "mem/port.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
SimpleDisk::SimpleDisk(const string &name, PhysicalMemory *pmem,
|
||||
DiskImage *img)
|
||||
: SimObject(name), physmem(pmem), image(img)
|
||||
SimpleDisk::SimpleDisk(const string &name, System *sys, DiskImage *img)
|
||||
: SimObject(name), system(sys), image(img)
|
||||
{}
|
||||
|
||||
SimpleDisk::~SimpleDisk()
|
||||
|
@ -59,9 +59,7 @@ SimpleDisk::~SimpleDisk()
|
|||
void
|
||||
SimpleDisk::read(Addr addr, baddr_t block, int count) const
|
||||
{
|
||||
uint8_t *data = physmem->dma_addr(addr, count);
|
||||
if (!data)
|
||||
panic("dma out of range! read addr=%#x count=%d\n", addr, count);
|
||||
uint8_t *data = new uint8_t[SectorSize * count];
|
||||
|
||||
if (count & (SectorSize - 1))
|
||||
panic("Not reading a multiple of a sector (count = %d)", count);
|
||||
|
@ -69,8 +67,12 @@ SimpleDisk::read(Addr addr, baddr_t block, int count) const
|
|||
for (int i = 0, j = 0; i < count; i += SectorSize, j++)
|
||||
image->read(data + i, block + j);
|
||||
|
||||
system->functionalPort.writeBlob(addr, data, count);
|
||||
|
||||
DPRINTF(SimpleDisk, "read block=%#x len=%d\n", (uint64_t)block, count);
|
||||
DDUMP(SimpleDiskData, data, count);
|
||||
|
||||
delete data;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -89,21 +91,21 @@ SimpleDisk::write(Addr addr, baddr_t block, int count)
|
|||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleDisk)
|
||||
|
||||
SimObjectParam<PhysicalMemory *> physmem;
|
||||
SimObjectParam<System *> system;
|
||||
SimObjectParam<DiskImage *> disk;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(SimpleDisk)
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleDisk)
|
||||
|
||||
INIT_PARAM(physmem, "Physical Memory"),
|
||||
INIT_PARAM(system, "System pointer"),
|
||||
INIT_PARAM(disk, "Disk Image")
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(SimpleDisk)
|
||||
|
||||
CREATE_SIM_OBJECT(SimpleDisk)
|
||||
{
|
||||
return new SimpleDisk(getInstanceName(), physmem, disk);
|
||||
return new SimpleDisk(getInstanceName(), system, disk);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("SimpleDisk", SimpleDisk)
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "arch/isa_traits.hh"
|
||||
|
||||
class DiskImage;
|
||||
class PhysicalMemory;
|
||||
class System;
|
||||
|
||||
/*
|
||||
* Trivial interface to a disk image used by the System Console
|
||||
|
@ -48,11 +48,11 @@ class SimpleDisk : public SimObject
|
|||
typedef uint64_t baddr_t;
|
||||
|
||||
protected:
|
||||
PhysicalMemory *physmem;
|
||||
System *system;
|
||||
DiskImage *image;
|
||||
|
||||
public:
|
||||
SimpleDisk(const std::string &name, PhysicalMemory *pmem, DiskImage *img);
|
||||
SimpleDisk(const std::string &name, System *sys, DiskImage *img);
|
||||
~SimpleDisk();
|
||||
|
||||
void read(Addr addr, baddr_t block, int count) const;
|
||||
|
|
32
dev/uart.cc
32
dev/uart.cc
|
@ -27,39 +27,19 @@
|
|||
*/
|
||||
|
||||
/** @file
|
||||
* Implements a 8250 UART
|
||||
* Implements a base class for UARTs
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/inifile.hh"
|
||||
#include "base/str.hh" // for to_number
|
||||
#include "base/trace.hh"
|
||||
#include "dev/simconsole.hh"
|
||||
#include "dev/uart.hh"
|
||||
#include "dev/platform.hh"
|
||||
#include "mem/bus/bus.hh"
|
||||
#include "mem/bus/pio_interface.hh"
|
||||
#include "mem/bus/pio_interface_impl.hh"
|
||||
#include "mem/functional/memory_control.hh"
|
||||
#include "sim/builder.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a,
|
||||
Addr s, HierParams *hier, Bus *bus, Tick pio_latency, Platform *p)
|
||||
: PioDevice(name, p), addr(a), size(s), cons(c)
|
||||
Uart::Uart(Params *p)
|
||||
: BasicPioDevice(p), platform(p->platform), cons(p->cons)
|
||||
{
|
||||
mmu->add_child(this, RangeSize(addr, size));
|
||||
|
||||
|
||||
if (bus) {
|
||||
pioInterface = newPioInterface(name, hier, bus, this,
|
||||
&Uart::cacheAccess);
|
||||
pioInterface->addAddrRange(RangeSize(addr, size));
|
||||
pioLatency = pio_latency * bus->clockRate;
|
||||
}
|
||||
|
||||
status = 0;
|
||||
|
||||
|
@ -68,11 +48,5 @@ Uart::Uart(const string &name, SimConsole *c, MemoryController *mmu, Addr a,
|
|||
platform->uart = this;
|
||||
}
|
||||
|
||||
Tick
|
||||
Uart::cacheAccess(MemReqPtr &req)
|
||||
{
|
||||
return curTick + pioLatency;
|
||||
}
|
||||
|
||||
DEFINE_SIM_OBJECT_CLASS_NAME("Uart", Uart)
|
||||
|
||||
|
|
26
dev/uart.hh
26
dev/uart.hh
|
@ -37,30 +37,27 @@
|
|||
#include "dev/io_device.hh"
|
||||
|
||||
class SimConsole;
|
||||
class MemoryController;
|
||||
class Platform;
|
||||
|
||||
const int RX_INT = 0x1;
|
||||
const int TX_INT = 0x2;
|
||||
|
||||
|
||||
class Uart : public PioDevice
|
||||
class Uart : public BasicPioDevice
|
||||
{
|
||||
|
||||
protected:
|
||||
int status;
|
||||
Addr addr;
|
||||
Addr size;
|
||||
Platform *platform;
|
||||
SimConsole *cons;
|
||||
|
||||
public:
|
||||
Uart(const std::string &name, SimConsole *c, MemoryController *mmu,
|
||||
Addr a, Addr s, HierParams *hier, Bus *bus, Tick pio_latency,
|
||||
Platform *p);
|
||||
|
||||
virtual Fault read(MemReqPtr &req, uint8_t *data) = 0;
|
||||
virtual Fault write(MemReqPtr &req, const uint8_t *data) = 0;
|
||||
struct Params : public BasicPioDevice::Params
|
||||
{
|
||||
SimConsole *cons;
|
||||
};
|
||||
|
||||
Uart(Params *p);
|
||||
|
||||
/**
|
||||
* Inform the uart that there is data available.
|
||||
|
@ -74,12 +71,9 @@ class Uart : public PioDevice
|
|||
*/
|
||||
bool intStatus() { return status ? true : false; }
|
||||
|
||||
/**
|
||||
* Return how long this access will take.
|
||||
* @param req the memory request to calcuate
|
||||
* @return Tick when the request is done
|
||||
*/
|
||||
Tick cacheAccess(MemReqPtr &req);
|
||||
protected:
|
||||
const Params *params() const {return (const Params *)_params; }
|
||||
|
||||
};
|
||||
|
||||
#endif // __UART_HH__
|
||||
|
|
120
dev/uart8250.cc
120
dev/uart8250.cc
|
@ -40,10 +40,6 @@
|
|||
#include "dev/simconsole.hh"
|
||||
#include "dev/uart8250.hh"
|
||||
#include "dev/platform.hh"
|
||||
#include "mem/bus/bus.hh"
|
||||
#include "mem/bus/pio_interface.hh"
|
||||
#include "mem/bus/pio_interface_impl.hh"
|
||||
#include "mem/functional/memory_control.hh"
|
||||
#include "sim/builder.hh"
|
||||
|
||||
using namespace std;
|
||||
|
@ -100,26 +96,35 @@ Uart8250::IntrEvent::scheduleIntr()
|
|||
}
|
||||
|
||||
|
||||
Uart8250::Uart8250(const string &name, SimConsole *c, MemoryController *mmu,
|
||||
Addr a, Addr s, HierParams *hier, Bus *pio_bus,
|
||||
Tick pio_latency, Platform *p)
|
||||
: Uart(name, c, mmu, a, s, hier, pio_bus, pio_latency, p),
|
||||
txIntrEvent(this, TX_INT), rxIntrEvent(this, RX_INT)
|
||||
Uart8250::Uart8250(Params *p)
|
||||
: Uart(p), txIntrEvent(this, TX_INT), rxIntrEvent(this, RX_INT)
|
||||
{
|
||||
pioSize = 8;
|
||||
|
||||
IER = 0;
|
||||
DLAB = 0;
|
||||
LCR = 0;
|
||||
MCR = 0;
|
||||
|
||||
}
|
||||
|
||||
Fault
|
||||
Uart8250::read(MemReqPtr &req, uint8_t *data)
|
||||
Tick
|
||||
Uart8250::read(Packet &pkt)
|
||||
{
|
||||
Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
|
||||
assert(pkt.result == Unknown);
|
||||
assert(pkt.addr > pioAddr && pkt.addr < pioAddr + pioSize);
|
||||
assert(pkt.size == 1);
|
||||
|
||||
pkt.time = curTick + pioDelay;
|
||||
Addr daddr = pkt.addr - pioAddr;
|
||||
uint8_t *data;
|
||||
|
||||
DPRINTF(Uart, " read register %#x\n", daddr);
|
||||
|
||||
assert(req->size == 1);
|
||||
if (!pkt.data) {
|
||||
data = new uint8_t;
|
||||
pkt.data = data;
|
||||
} else
|
||||
data = pkt.data;
|
||||
|
||||
switch (daddr) {
|
||||
case 0x0:
|
||||
|
@ -127,7 +132,7 @@ Uart8250::read(MemReqPtr &req, uint8_t *data)
|
|||
if (cons->dataAvailable())
|
||||
cons->in(*data);
|
||||
else {
|
||||
*(uint8_t*)data = 0;
|
||||
*data = 0;
|
||||
// A limited amount of these are ok.
|
||||
DPRINTF(Uart, "empty read of RX register\n");
|
||||
}
|
||||
|
@ -142,7 +147,7 @@ Uart8250::read(MemReqPtr &req, uint8_t *data)
|
|||
break;
|
||||
case 0x1:
|
||||
if (!(LCR & 0x80)) { // Intr Enable Register(IER)
|
||||
*(uint8_t*)data = IER;
|
||||
*data = IER;
|
||||
} else { // DLM divisor latch MSB
|
||||
;
|
||||
}
|
||||
|
@ -151,17 +156,17 @@ Uart8250::read(MemReqPtr &req, uint8_t *data)
|
|||
DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status);
|
||||
|
||||
if (status & RX_INT) /* Rx data interrupt has a higher priority */
|
||||
*(uint8_t*)data = IIR_RXID;
|
||||
*data = IIR_RXID;
|
||||
else if (status & TX_INT)
|
||||
*(uint8_t*)data = IIR_TXID;
|
||||
*data = IIR_TXID;
|
||||
else
|
||||
*(uint8_t*)data = IIR_NOPEND;
|
||||
*data = IIR_NOPEND;
|
||||
|
||||
//Tx interrupts are cleared on IIR reads
|
||||
status &= ~TX_INT;
|
||||
break;
|
||||
case 0x3: // Line Control Register (LCR)
|
||||
*(uint8_t*)data = LCR;
|
||||
*data = LCR;
|
||||
break;
|
||||
case 0x4: // Modem Control Register (MCR)
|
||||
break;
|
||||
|
@ -172,34 +177,41 @@ Uart8250::read(MemReqPtr &req, uint8_t *data)
|
|||
if (cons->dataAvailable())
|
||||
lsr = UART_LSR_DR;
|
||||
lsr |= UART_LSR_TEMT | UART_LSR_THRE;
|
||||
*(uint8_t*)data = lsr;
|
||||
*data = lsr;
|
||||
break;
|
||||
case 0x6: // Modem Status Register (MSR)
|
||||
*(uint8_t*)data = 0;
|
||||
*data = 0;
|
||||
break;
|
||||
case 0x7: // Scratch Register (SCR)
|
||||
*(uint8_t*)data = 0; // doesn't exist with at 8250.
|
||||
*data = 0; // doesn't exist with at 8250.
|
||||
break;
|
||||
default:
|
||||
panic("Tried to access a UART port that doesn't exist\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return NoFault;
|
||||
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
Fault
|
||||
Uart8250::write(MemReqPtr &req, const uint8_t *data)
|
||||
Tick
|
||||
Uart8250::write(Packet &pkt)
|
||||
{
|
||||
Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
|
||||
|
||||
DPRINTF(Uart, " write register %#x value %#x\n", daddr, *(uint8_t*)data);
|
||||
assert(pkt.result == Unknown);
|
||||
assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize);
|
||||
assert(pkt.size == 1);
|
||||
|
||||
pkt.time = curTick + pioDelay;
|
||||
Addr daddr = pkt.addr - pioAddr;
|
||||
|
||||
uint8_t *data = pkt.data;
|
||||
|
||||
DPRINTF(Uart, " write register %#x value %#x\n", daddr, *data);
|
||||
|
||||
switch (daddr) {
|
||||
case 0x0:
|
||||
if (!(LCR & 0x80)) { // write byte
|
||||
cons->out(*(uint8_t *)data);
|
||||
cons->out(*data);
|
||||
platform->clearConsoleInt();
|
||||
status &= ~TX_INT;
|
||||
if (UART_IER_THRI & IER)
|
||||
|
@ -210,7 +222,7 @@ Uart8250::write(MemReqPtr &req, const uint8_t *data)
|
|||
break;
|
||||
case 0x1:
|
||||
if (!(LCR & 0x80)) { // Intr Enable Register(IER)
|
||||
IER = *(uint8_t*)data;
|
||||
IER = *data;
|
||||
if (UART_IER_THRI & IER)
|
||||
{
|
||||
DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n");
|
||||
|
@ -244,10 +256,10 @@ Uart8250::write(MemReqPtr &req, const uint8_t *data)
|
|||
case 0x2: // FIFO Control Register (FCR)
|
||||
break;
|
||||
case 0x3: // Line Control Register (LCR)
|
||||
LCR = *(uint8_t*)data;
|
||||
LCR = *data;
|
||||
break;
|
||||
case 0x4: // Modem Control Register (MCR)
|
||||
if (*(uint8_t*)data == (UART_MCR_LOOP | 0x0A))
|
||||
if (*data == (UART_MCR_LOOP | 0x0A))
|
||||
MCR = 0x9A;
|
||||
break;
|
||||
case 0x7: // Scratch Register (SCR)
|
||||
|
@ -257,7 +269,7 @@ Uart8250::write(MemReqPtr &req, const uint8_t *data)
|
|||
panic("Tried to access a UART port that doesn't exist\n");
|
||||
break;
|
||||
}
|
||||
return NoFault;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -272,6 +284,14 @@ Uart8250::dataAvailable()
|
|||
|
||||
}
|
||||
|
||||
void
|
||||
Uart8250::addressRanges(AddrRangeList &range_list)
|
||||
{
|
||||
assert(pioSize != 0);
|
||||
range_list.clear();
|
||||
range_list.push_back(RangeSize(pioAddr, pioSize));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
|
@ -316,35 +336,35 @@ Uart8250::unserialize(Checkpoint *cp, const std::string §ion)
|
|||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Uart8250)
|
||||
|
||||
SimObjectParam<SimConsole *> console;
|
||||
SimObjectParam<MemoryController *> mmu;
|
||||
SimObjectParam<Platform *> platform;
|
||||
Param<Addr> addr;
|
||||
Param<Addr> size;
|
||||
SimObjectParam<Bus*> pio_bus;
|
||||
Param<Tick> pio_latency;
|
||||
SimObjectParam<HierParams *> hier;
|
||||
|
||||
SimObjectParam<Platform *> platform;
|
||||
SimObjectParam<SimConsole *> sim_console;
|
||||
SimObjectParam<System *> system;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(Uart8250)
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(Uart8250)
|
||||
|
||||
INIT_PARAM(console, "The console"),
|
||||
INIT_PARAM(mmu, "Memory Controller"),
|
||||
INIT_PARAM(platform, "Pointer to platfrom"),
|
||||
INIT_PARAM(addr, "Device Address"),
|
||||
INIT_PARAM_DFLT(size, "Device size", 0x8),
|
||||
INIT_PARAM(pio_bus, ""),
|
||||
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
|
||||
INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams)
|
||||
INIT_PARAM_DFLT(pio_latency, "Programmed IO latency", 1000),
|
||||
INIT_PARAM(platform, "platform"),
|
||||
INIT_PARAM(sim_console, "The Simulator Console"),
|
||||
INIT_PARAM(system, "system object")
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(Uart8250)
|
||||
|
||||
CREATE_SIM_OBJECT(Uart8250)
|
||||
{
|
||||
return new Uart8250(getInstanceName(), console, mmu, addr, size, hier,
|
||||
pio_bus, pio_latency, platform);
|
||||
Uart8250::Params *p = new Uart8250::Params;
|
||||
p->name = getInstanceName();
|
||||
p->pio_addr = addr;
|
||||
p->pio_delay = pio_latency;
|
||||
p->platform = platform;
|
||||
p->cons = sim_console;
|
||||
p->system = system;
|
||||
return new Uart8250(p);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("Uart8250", Uart8250)
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
* Defines a 8250 UART
|
||||
*/
|
||||
|
||||
#ifndef __TSUNAMI_UART_HH__
|
||||
#define __TSUNAMI_UART_HH__
|
||||
#ifndef __DEV_UART8250_HH__
|
||||
#define __DEV_UART8250_HH__
|
||||
|
||||
#include "dev/tsunamireg.h"
|
||||
#include "base/range.hh"
|
||||
|
@ -53,7 +53,6 @@
|
|||
#define IIR_LINE 0x06 /* Rx Line Status (highest priority)*/
|
||||
|
||||
class SimConsole;
|
||||
class MemoryController;
|
||||
class Platform;
|
||||
|
||||
class Uart8250 : public Uart
|
||||
|
@ -79,12 +78,11 @@ class Uart8250 : public Uart
|
|||
IntrEvent rxIntrEvent;
|
||||
|
||||
public:
|
||||
Uart8250(const std::string &name, SimConsole *c, MemoryController *mmu,
|
||||
Addr a, Addr s, HierParams *hier, Bus *pio_bus, Tick pio_latency,
|
||||
Platform *p);
|
||||
Uart8250(Params *p);
|
||||
|
||||
virtual Fault read(MemReqPtr &req, uint8_t *data);
|
||||
virtual Fault write(MemReqPtr &req, const uint8_t *data);
|
||||
virtual Tick read(Packet &pkt);
|
||||
virtual Tick write(Packet &pkt);
|
||||
virtual void addressRanges(AddrRangeList &range_list);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ class Bus : public MemObject
|
|||
// downstream from this bus, yes? That is, the union of all
|
||||
// the 'owned' address ranges of all the other interfaces on
|
||||
// this bus...
|
||||
virtual void addressRanges(AddrRangeList &range_list, bool &owner);
|
||||
virtual void addressRanges(AddrRangeList &resp, AddrRangeList &snoop);
|
||||
|
||||
// Hack to make translating port work without changes
|
||||
virtual int deviceBlockSize() { return 32; }
|
||||
|
|
|
@ -184,18 +184,18 @@ PhysicalMemory::MemoryPort::recvStatusChange(Port::Status status)
|
|||
}
|
||||
|
||||
void
|
||||
PhysicalMemory::MemoryPort::getDeviceAddressRanges(AddrRangeList &range_list,
|
||||
bool &owner)
|
||||
PhysicalMemory::MemoryPort::getDeviceAddressRanges(AddrRangeList &resp,
|
||||
AddrRangeList &snoop)
|
||||
{
|
||||
memory->getAddressRanges(range_list, owner);
|
||||
memory->getAddressRanges(resp, snoop);
|
||||
}
|
||||
|
||||
void
|
||||
PhysicalMemory::getAddressRanges(AddrRangeList &range_list, bool &owner)
|
||||
PhysicalMemory::getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
|
||||
{
|
||||
owner = true;
|
||||
range_list.clear();
|
||||
range_list.push_back(RangeSize(base_addr, pmem_size));
|
||||
snoop.clear();
|
||||
resp.clear();
|
||||
resp.push_back(RangeSize(base_addr, pmem_size));
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -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__
|
||||
|
|
@ -2,4 +2,4 @@ from m5 import *
|
|||
class SimpleDisk(SimObject):
|
||||
type = 'SimpleDisk'
|
||||
disk = Param.DiskImage("Disk Image")
|
||||
physmem = Param.PhysicalMemory(Parent.any, "Physical Memory")
|
||||
system = Param.System(Parent.any, "Sysetm Pointer")
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include "config/full_system.hh"
|
||||
#include "cpu/exec_context.hh"
|
||||
#include "mem/page_table.hh"
|
||||
#include "mem/mem_object.hh"
|
||||
#include "mem/physical.hh"
|
||||
#include "mem/translating_port.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "sim/process.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 "mem/physical.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"
|
||||
#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
|
||||
|
@ -237,7 +242,7 @@ DEFINE_SIM_OBJECT_CLASS_NAME("System", System)
|
|||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(System)
|
||||
|
||||
SimObjectParam<MemObject *> physmem;
|
||||
SimObjectParam<PhysicalMemory *> physmem;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(System)
|
||||
|
||||
|
|
|
@ -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