Merge m5.eecs.umich.edu:/bk/newmem

into  ewok.(none):/home/gblack/m5/newmem

--HG--
extra : convert_revision : bd6352647798275a12d52d55a129cdddd8e25423
This commit is contained in:
Gabe Black 2006-04-06 15:00:11 -04:00
commit 6a962f8343
49 changed files with 726 additions and 662 deletions

View file

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

View file

@ -29,7 +29,7 @@
#include "arch/alpha/arguments.hh"
#include "arch/alpha/vtophys.hh"
#include "cpu/exec_context.hh"
#include "mem/functional/physical.hh"
#include "mem/vport.hh"
using namespace AlphaISA;
@ -59,11 +59,10 @@ AlphaArguments::getArg(bool fp)
return xc->readIntReg(16 + number);
} else {
Addr sp = xc->readIntReg(30);
Addr paddr = vtophys(xc, sp + (number-6) * sizeof(uint64_t));
// @todo: This read must go through the system or something else.
// return xc->getPhysMemPtr()->phys_read_qword(paddr);
panic("Need to fix alpha arguments\n");
return 0;
VirtualPort *vp = xc->getVirtPort(xc);
uint64_t arg = vp->read<uint64_t>(sp + (number-6) * sizeof(uint64_t));
xc->delVirtPort(vp);
return arg;
}
}

View file

@ -26,8 +26,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ARGUMENTS_HH__
#define __ARGUMENTS_HH__
#ifndef __ARCH_ALPHA_ARGUMENTS_HH__
#define __ARCH_ALPHA_ARGUMENTS_HH__
#include <assert.h>
@ -37,6 +37,8 @@
class ExecContext;
namespace AlphaISA {
class AlphaArguments
{
protected:
@ -135,9 +137,11 @@ class AlphaArguments
operator char *() {
char *buf = data->alloc(2048);
CopyString(xc, buf, getArg(), 2048);
CopyStringOut(xc, buf, getArg(), 2048);
return buf;
}
};
#endif // __ARGUMENTS_HH__
}; // namespace AlphaISA
#endif // __ARCH_ALPHA_ARGUMENTS_HH__

View file

@ -105,6 +105,10 @@ FaultName IntegerOverflowFault::_name = "intover";
FaultVect IntegerOverflowFault::_vect = 0x0501;
FaultStat IntegerOverflowFault::_count;
FaultName UnimpFault::_name = "Unimplemented Simulator feature";
FaultVect UnimpFault::_vect = 0x0001;
FaultStat UnimpFault::_count;
#if FULL_SYSTEM
void AlphaFault::invoke(ExecContext * xc)
@ -170,6 +174,12 @@ void ItbFault::invoke(ExecContext * xc)
AlphaFault::invoke(xc);
}
void UnimpFault::invoke(ExecContext * xc)
{
FaultBase::invoke(xc);
panic("Unimpfault: %s\n", panicStr.c_str());
}
#endif
} // namespace AlphaISA

View file

@ -347,6 +347,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__

View file

@ -37,8 +37,8 @@
#include "arch/alpha/freebsd/system.hh"
#include "base/loader/symtab.hh"
#include "cpu/exec_context.hh"
#include "mem/functional/memory_control.hh"
#include "mem/functional/physical.hh"
#include "mem/physical.hh"
#include "mem/port.hh"
#include "arch/isa_traits.hh"
#include "sim/builder.hh"
#include "sim/byteswap.hh"
@ -74,20 +74,12 @@ FreebsdAlphaSystem::doCalibrateClocks(ExecContext *xc)
{
Addr ppc_vaddr = 0;
Addr timer_vaddr = 0;
Addr ppc_paddr = 0;
Addr timer_paddr = 0;
ppc_vaddr = (Addr)xc->readIntReg(ArgumentReg1);
timer_vaddr = (Addr)xc->readIntReg(ArgumentReg2);
ppc_paddr = vtophys(physmem, ppc_vaddr);
timer_paddr = vtophys(physmem, timer_vaddr);
uint8_t *ppc = physmem->dma_addr(ppc_paddr, sizeof(uint32_t));
uint8_t *timer = physmem->dma_addr(timer_paddr, sizeof(uint32_t));
*(uint32_t *)ppc = htog((uint32_t)Clock::Frequency);
*(uint32_t *)timer = htog((uint32_t)TIMER_FREQUENCY);
virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency);
virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
}
@ -102,7 +94,6 @@ FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ExecContext *xc)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
Param<Tick> boot_cpu_frequency;
SimObjectParam<MemoryController *> memctrl;
SimObjectParam<PhysicalMemory *> physmem;
Param<string> kernel;
@ -125,7 +116,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM(memctrl, "memory controller"),
INIT_PARAM(physmem, "phsyical memory"),
INIT_PARAM(kernel, "file that contains the kernel code"),
INIT_PARAM(console, "file that contains the console code"),
@ -147,7 +137,6 @@ CREATE_SIM_OBJECT(FreebsdAlphaSystem)
AlphaSystem::Params *p = new AlphaSystem::Params;
p->name = getInstanceName();
p->boot_cpu_frequency = boot_cpu_frequency;
p->memctrl = memctrl;
p->physmem = physmem;
p->kernel_path = kernel;
p->console_path = console;

View file

@ -46,8 +46,8 @@
#include "dev/platform.hh"
#include "kern/linux/printk.hh"
#include "kern/linux/events.hh"
#include "mem/functional/memory_control.hh"
#include "mem/functional/physical.hh"
#include "mem/physical.hh"
#include "mem/port.hh"
#include "sim/builder.hh"
#include "sim/byteswap.hh"
@ -59,7 +59,6 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
: AlphaSystem(p)
{
Addr addr = 0;
Addr paddr = 0;
/**
* The symbol swapper_pg_dir marks the beginning of the kernel and
@ -73,25 +72,17 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
* Since we aren't using a bootloader, we have to copy the
* kernel arguments directly into the kernel's memory.
*/
paddr = vtophys(physmem, CommandLine());
char *commandline = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
if (commandline)
strncpy(commandline, params()->boot_osflags.c_str(), CommandLineSize);
virtPort.writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(),
CommandLineSize);
/**
* find the address of the est_cycle_freq variable and insert it
* so we don't through the lengthly process of trying to
* calculated it by using the PIT, RTC, etc.
*/
if (kernelSymtab->findAddress("est_cycle_freq", addr)) {
paddr = vtophys(physmem, addr);
uint8_t *est_cycle_frequency =
physmem->dma_addr(paddr, sizeof(uint64_t));
if (est_cycle_frequency)
*(uint64_t *)est_cycle_frequency =
Clock::Frequency / p->boot_cpu_frequency;
}
if (kernelSymtab->findAddress("est_cycle_freq", addr))
virtPort.write(addr, (uint64_t)(Clock::Frequency /
p->boot_cpu_frequency));
/**
@ -100,16 +91,9 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
* @todo At some point we should change ev5.hh and the palcode to support
* 255 ASNs.
*/
if (kernelSymtab->findAddress("dp264_mv", addr)) {
paddr = vtophys(physmem, addr);
char *dp264_mv = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
if (dp264_mv) {
*(uint32_t*)(dp264_mv+0x18) = LittleEndianGuest::htog((uint32_t)127);
} else
panic("could not translate dp264_mv addr\n");
} else
if (kernelSymtab->findAddress("dp264_mv", addr))
virtPort.write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
else
panic("could not find dp264_mv\n");
#ifndef NDEBUG
@ -190,15 +174,10 @@ LinuxAlphaSystem::setDelayLoop(ExecContext *xc)
{
Addr addr = 0;
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
Addr paddr = vtophys(physmem, addr);
uint8_t *loops_per_jiffy =
physmem->dma_addr(paddr, sizeof(uint32_t));
Tick cpuFreq = xc->getCpuPtr()->frequency();
Tick intrFreq = platform->intrFrequency();
*(uint32_t *)loops_per_jiffy =
(uint32_t)((cpuFreq / intrFreq) * 0.9988);
xc->getVirtPort(xc)->write(addr,
(uint32_t)((cpuFreq / intrFreq) * 0.9988));
}
}
@ -224,7 +203,6 @@ LinuxAlphaSystem::PrintThreadInfo::process(ExecContext *xc)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
Param<Tick> boot_cpu_frequency;
SimObjectParam<MemoryController *> memctrl;
SimObjectParam<PhysicalMemory *> physmem;
Param<string> kernel;
@ -247,7 +225,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM(memctrl, "memory controller"),
INIT_PARAM(physmem, "phsyical memory"),
INIT_PARAM(kernel, "file that contains the kernel code"),
INIT_PARAM(console, "file that contains the console code"),
@ -269,7 +246,6 @@ CREATE_SIM_OBJECT(LinuxAlphaSystem)
AlphaSystem::Params *p = new AlphaSystem::Params;
p->name = getInstanceName();
p->boot_cpu_frequency = boot_cpu_frequency;
p->memctrl = memctrl;
p->physmem = physmem;
p->kernel_path = kernel;
p->console_path = console;

View file

@ -47,23 +47,23 @@ ProcessInfo::ProcessInfo(ExecContext *_xc)
if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
panic("thread info not compiled into kernel\n");
thread_info_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
thread_info_size = gtoh(xc->getVirtPort()->read<int32_t>(addr));
if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
panic("thread info not compiled into kernel\n");
task_struct_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
task_struct_size = gtoh(xc->getVirtPort()->read<int32_t>(addr));
if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
panic("thread info not compiled into kernel\n");
task_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
task_off = gtoh(xc->getVirtPort()->read<int32_t>(addr));
if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
panic("thread info not compiled into kernel\n");
pid_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
pid_off = gtoh(xc->getVirtPort()->read<int32_t>(addr));
if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
panic("thread info not compiled into kernel\n");
name_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
name_off = gtoh(xc->getVirtPort()->read<int32_t>(addr));
}
Addr
@ -73,9 +73,7 @@ ProcessInfo::task(Addr ksp) const
if (base == ULL(0xfffffc0000000000))
return 0;
Addr task;
CopyOut(xc, &task, base + task_off, sizeof(task));
return task;
return gtoh(xc->getVirtPort()->read<Addr>(base + task_off));
}
int
@ -85,9 +83,7 @@ ProcessInfo::pid(Addr ksp) const
if (!task)
return -1;
uint16_t pid;
CopyOut(xc, &pid, task + pid_off, sizeof(pid));
return pid;
return gtoh(xc->getVirtPort()->read<uint16_t>(task + pid_off));
}
string
@ -98,7 +94,7 @@ ProcessInfo::name(Addr ksp) const
return "console";
char comm[256];
CopyString(xc, comm, task + name_off, sizeof(comm));
CopyStringOut(xc, comm, task + name_off, sizeof(comm));
if (!comm[0])
return "startup";

View file

@ -33,8 +33,7 @@
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "mem/functional/memory_control.hh"
#include "mem/functional/physical.hh"
#include "mem/physical.hh"
#include "sim/byteswap.hh"
#include "sim/builder.hh"
@ -63,8 +62,8 @@ AlphaSystem::AlphaSystem(Params *p)
// Load program sections into memory
pal->loadSections(&functionalPort, LoadAddrMask);
console->loadSections(&functionalPort, LoadAddrMask);
pal->loadSections(&functionalPort, AlphaISA::LoadAddrMask);
console->loadSections(&functionalPort, AlphaISA::LoadAddrMask);
// load symbols
if (!console->loadGlobalSymbols(consoleSymtab))
@ -97,11 +96,8 @@ AlphaSystem::AlphaSystem(Params *p)
* others do.)
*/
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
Addr paddr = vtophys(physmem, addr);
char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));
if (osflags)
strcpy(osflags, params()->boot_osflags.c_str());
virtPort.writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
strlen(params()->boot_osflags.c_str()));
}
/**
@ -109,14 +105,11 @@ AlphaSystem::AlphaSystem(Params *p)
* information to Tsunami.
*/
if (consoleSymtab->findAddress("m5_rpb", addr)) {
Addr paddr = vtophys(physmem, addr);
char *hwrpb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
if (!hwrpb)
panic("could not translate hwrpb addr\n");
*(uint64_t*)(hwrpb+0x50) = htog(params()->system_type);
*(uint64_t*)(hwrpb+0x58) = htog(params()->system_rev);
uint64_t data;
data = htog(params()->system_type);
virtPort.write(addr, data);
data = htog(params()->system_rev);
virtPort.write(addr, data);
} else
panic("could not find hwrpb\n");
@ -172,16 +165,13 @@ AlphaSystem::fixFuncEventAddr(Addr addr)
const uint32_t gp_ldah_pattern = (9 << 26) | (29 << 21) | (27 << 16);
// lda gp,Y(gp): opcode 8, Ra = 29, rb = 29
const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16);
// instruction size
const int sz = sizeof(uint32_t);
Addr paddr = vtophys(physmem, addr);
uint32_t i1 = *(uint32_t *)physmem->dma_addr(paddr, sz);
uint32_t i2 = *(uint32_t *)physmem->dma_addr(paddr+sz, sz);
uint32_t i1 = virtPort.read<uint32_t>(addr);
uint32_t i2 = virtPort.read<uint32_t>(addr + sizeof(AlphaISA::MachInst));
if ((i1 & inst_mask) == gp_ldah_pattern &&
(i2 & inst_mask) == gp_lda_pattern) {
Addr new_addr = addr + 2*sz;
Addr new_addr = addr + 2* sizeof(AlphaISA::MachInst);
DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr);
return new_addr;
} else {
@ -195,14 +185,7 @@ AlphaSystem::setAlphaAccess(Addr access)
{
Addr addr = 0;
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
Addr paddr = vtophys(physmem, addr);
uint64_t *m5AlphaAccess =
(uint64_t *)physmem->dma_addr(paddr, sizeof(uint64_t));
if (!m5AlphaAccess)
panic("could not translate m5AlphaAccess addr\n");
*m5AlphaAccess = htog(EV5::Phys2K0Seg(access));
virtPort.write(addr, htog(EV5::Phys2K0Seg(access)));
} else
panic("could not find m5AlphaAccess\n");
}
@ -234,7 +217,6 @@ AlphaSystem::unserialize(Checkpoint *cp, const std::string &section)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem)
Param<Tick> boot_cpu_frequency;
SimObjectParam<MemoryController *> memctrl;
SimObjectParam<PhysicalMemory *> physmem;
Param<std::string> kernel;
@ -257,7 +239,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem)
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM(memctrl, "memory controller"),
INIT_PARAM(physmem, "phsyical memory"),
INIT_PARAM(kernel, "file that contains the kernel code"),
INIT_PARAM(console, "file that contains the console code"),
@ -279,7 +260,6 @@ CREATE_SIM_OBJECT(AlphaSystem)
AlphaSystem::Params *p = new AlphaSystem::Params;
p->name = getInstanceName();
p->boot_cpu_frequency = boot_cpu_frequency;
p->memctrl = memctrl;
p->physmem = physmem;
p->kernel_path = kernel;
p->console_path = console;

View file

@ -93,7 +93,7 @@ AlphaTLB::lookup(Addr vpn, uint8_t asn) const
}
void
Fault
AlphaTLB::checkCacheability(CpuRequestPtr &req)
{
// in Alpha, cacheability is controlled by upper-level bits of the
@ -115,17 +115,7 @@ AlphaTLB::checkCacheability(CpuRequestPtr &req)
#endif
// IPR memory space not implemented
if (PAddrIprSpace(req->paddr)) {
if (!req->xc->misspeculating()) {
switch (req->paddr) {
case ULL(0xFFFFF00188):
req->data = 0;
break;
default:
panic("IPR memory space not implemented! PA=%x\n",
req->paddr);
}
}
return new UnimpFault("IPR memory space not implemented!");
} else {
// mark request as uncacheable
req->flags |= UNCACHEABLE;
@ -136,6 +126,7 @@ AlphaTLB::checkCacheability(CpuRequestPtr &req)
#endif
}
}
return NoFault;
}
@ -292,10 +283,8 @@ AlphaITB::regStats()
Fault
AlphaITB::translate(CpuRequestPtr &req) const
AlphaITB::translate(CpuRequestPtr &req, ExecContext *xc) const
{
ExecContext *xc = req->xc;
if (AlphaISA::PcPAL(req->vaddr)) {
// strip off PAL PC marker (lsb is 1)
req->paddr = (req->vaddr & ~3) & PAddrImplMask;
@ -368,9 +357,8 @@ AlphaITB::translate(CpuRequestPtr &req) const
if (req->paddr & ~PAddrImplMask)
return genMachineCheckFault();
checkCacheability(req);
return checkCacheability(req);
return NoFault;
}
///////////////////////////////////////////////////////////////////////
@ -451,9 +439,8 @@ AlphaDTB::regStats()
}
Fault
AlphaDTB::translate(CpuRequestPtr &req, bool write) const
AlphaDTB::translate(CpuRequestPtr &req, ExecContext *xc, bool write) const
{
ExecContext *xc = req->xc;
Addr pc = xc->readPC();
AlphaISA::mode_type mode =
@ -583,9 +570,7 @@ AlphaDTB::translate(CpuRequestPtr &req, bool write) const
if (req->paddr & ~PAddrImplMask)
return genMachineCheckFault();
checkCacheability(req);
return NoFault;
return checkCacheability(req);
}
AlphaISA::PTE &

View file

@ -73,7 +73,7 @@ class AlphaTLB : public SimObject
return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask);
}
static void checkCacheability(CpuRequestPtr &req);
static Fault checkCacheability(CpuRequestPtr &req);
// Checkpointing
virtual void serialize(std::ostream &os);
@ -92,7 +92,7 @@ class AlphaITB : public AlphaTLB
AlphaITB(const std::string &name, int size);
virtual void regStats();
Fault translate(CpuRequestPtr &req) const;
Fault translate(CpuRequestPtr &req, ExecContext *xc) const;
};
class AlphaDTB : public AlphaTLB
@ -115,7 +115,7 @@ class AlphaDTB : public AlphaTLB
AlphaDTB(const std::string &name, int size);
virtual void regStats();
Fault translate(CpuRequestPtr &req, bool write) const;
Fault translate(CpuRequestPtr &req, ExecContext *xc, bool write) const;
};
#endif // __ALPHA_MEMORY_HH__

View file

@ -35,8 +35,8 @@
#include "cpu/exec_context.hh"
#include "kern/tru64/tru64_events.hh"
#include "kern/system_events.hh"
#include "mem/functional/memory_control.hh"
#include "mem/functional/physical.hh"
#include "mem/physical.hh"
#include "mem/port.hh"
#include "sim/builder.hh"
using namespace std;
@ -46,12 +46,7 @@ Tru64AlphaSystem::Tru64AlphaSystem(Tru64AlphaSystem::Params *p)
{
Addr addr = 0;
if (kernelSymtab->findAddress("enable_async_printf", addr)) {
Addr paddr = vtophys(physmem, addr);
uint8_t *enable_async_printf =
physmem->dma_addr(paddr, sizeof(uint32_t));
if (enable_async_printf)
*(uint32_t *)enable_async_printf = 0;
virtPort.write(addr, (uint32_t)0);
}
#ifdef DEBUG
@ -96,7 +91,6 @@ Tru64AlphaSystem::~Tru64AlphaSystem()
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
Param<Tick> boot_cpu_frequency;
SimObjectParam<MemoryController *> memctrl;
SimObjectParam<PhysicalMemory *> physmem;
Param<string> kernel;
@ -118,7 +112,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
INIT_PARAM(boot_cpu_frequency, "frequency of the boot cpu"),
INIT_PARAM(memctrl, "memory controller"),
INIT_PARAM(physmem, "phsyical memory"),
INIT_PARAM(kernel, "file that contains the kernel code"),
INIT_PARAM(console, "file that contains the console code"),
@ -139,7 +132,6 @@ CREATE_SIM_OBJECT(Tru64AlphaSystem)
AlphaSystem::Params *p = new AlphaSystem::Params;
p->name = getInstanceName();
p->boot_cpu_frequency = boot_cpu_frequency;
p->memctrl = memctrl;
p->physmem = physmem;
p->kernel_path = kernel;
p->console_path = console;

View file

@ -28,33 +28,35 @@
#include <string>
#include "arch/alpha/ev5.hh"
#include "arch/alpha/vtophys.hh"
#include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "mem/functional/physical.hh"
#include "mem/vport.hh"
using namespace std;
using namespace AlphaISA;
AlphaISA::PageTableEntry
kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, AlphaISA::VAddr vaddr)
AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr)
{
Addr level1_pte = ptbr + vaddr.level1();
AlphaISA::PageTableEntry level1 = pmem->phys_read_qword(level1_pte);
AlphaISA::PageTableEntry level1 = mem->read<uint64_t>(level1_pte);
if (!level1.valid()) {
DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr);
return 0;
}
Addr level2_pte = level1.paddr() + vaddr.level2();
AlphaISA::PageTableEntry level2 = pmem->phys_read_qword(level2_pte);
AlphaISA::PageTableEntry level2 = mem->read<uint64_t>(level2_pte);
if (!level2.valid()) {
DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr);
return 0;
}
Addr level3_pte = level2.paddr() + vaddr.level3();
AlphaISA::PageTableEntry level3 = pmem->phys_read_qword(level3_pte);
AlphaISA::PageTableEntry level3 = mem->read<uint64_t>(level3_pte);
if (!level3.valid()) {
DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr);
return 0;
@ -63,7 +65,7 @@ kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, AlphaISA::VAddr vaddr)
}
Addr
vtophys(PhysicalMemory *xc, Addr vaddr)
AlphaISA::vtophys(Addr vaddr)
{
Addr paddr = 0;
if (AlphaISA::IsUSeg(vaddr))
@ -79,7 +81,7 @@ vtophys(PhysicalMemory *xc, Addr vaddr)
}
Addr
vtophys(ExecContext *xc, Addr addr)
AlphaISA::vtophys(ExecContext *xc, Addr addr)
{
AlphaISA::VAddr vaddr = addr;
Addr ptbr = xc->readMiscReg(AlphaISA::IPR_PALtemp20);
@ -95,7 +97,7 @@ vtophys(ExecContext *xc, Addr addr)
paddr = vaddr;
} else {
AlphaISA::PageTableEntry pte =
kernel_pte_lookup(xc->getPhysMemPtr(), ptbr, vaddr);
kernel_pte_lookup(xc->getPhysPort(), ptbr, vaddr);
if (pte.valid())
paddr = pte.paddr() | vaddr.offset();
}
@ -107,162 +109,54 @@ vtophys(ExecContext *xc, Addr addr)
return paddr;
}
uint8_t *
ptomem(ExecContext *xc, Addr paddr, size_t len)
{
return xc->getPhysMemPtr()->dma_addr(paddr, len);
}
uint8_t *
vtomem(ExecContext *xc, Addr vaddr, size_t len)
void
AlphaISA::CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen)
{
Addr paddr = vtophys(xc, vaddr);
return xc->getPhysMemPtr()->dma_addr(paddr, len);
uint8_t *dst = (uint8_t *)dest;
VirtualPort *vp = xc->getVirtPort(xc);
vp->readBlob(src, dst, cplen);
xc->delVirtPort(vp);
}
void
CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen)
AlphaISA::CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen)
{
Addr paddr;
char *dmaaddr;
char *dst = (char *)dest;
int len;
uint8_t *src = (uint8_t *)source;
VirtualPort *vp = xc->getVirtPort(xc);
paddr = vtophys(xc, src);
len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)),
(int)cplen);
dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len);
assert(dmaaddr);
vp->writeBlob(dest, src, cplen);
memcpy(dst, dmaaddr, len);
if (len == cplen)
return;
cplen -= len;
dst += len;
src += len;
while (cplen > AlphaISA::PageBytes) {
paddr = vtophys(xc, src);
dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr,
AlphaISA::PageBytes);
assert(dmaaddr);
memcpy(dst, dmaaddr, AlphaISA::PageBytes);
cplen -= AlphaISA::PageBytes;
dst += AlphaISA::PageBytes;
src += AlphaISA::PageBytes;
}
if (cplen > 0) {
paddr = vtophys(xc, src);
dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, cplen);
assert(dmaaddr);
memcpy(dst, dmaaddr, cplen);
}
xc->delVirtPort(vp);
}
void
CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen)
AlphaISA::CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen)
{
Addr paddr;
char *dmaaddr;
char *src = (char *)source;
int len;
int len = 0;
VirtualPort *vp = xc->getVirtPort(xc);
paddr = vtophys(xc, dest);
len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)),
(int)cplen);
dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len);
assert(dmaaddr);
do {
vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
len++;
} while (len < maxlen && dst[len] != 0 );
memcpy(dmaaddr, src, len);
if (len == cplen)
return;
cplen -= len;
src += len;
dest += len;
while (cplen > AlphaISA::PageBytes) {
paddr = vtophys(xc, dest);
dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr,
AlphaISA::PageBytes);
assert(dmaaddr);
memcpy(dmaaddr, src, AlphaISA::PageBytes);
cplen -= AlphaISA::PageBytes;
src += AlphaISA::PageBytes;
dest += AlphaISA::PageBytes;
}
if (cplen > 0) {
paddr = vtophys(xc, dest);
dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, cplen);
assert(dmaaddr);
memcpy(dmaaddr, src, cplen);
}
xc->delVirtPort(vp);
dst[len] = 0;
}
void
CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen)
AlphaISA::CopyStringIn(ExecContext *xc, char *src, Addr vaddr)
{
Addr paddr;
char *dmaaddr;
int len;
paddr = vtophys(xc, vaddr);
len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)),
(int)maxlen);
dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len);
assert(dmaaddr);
char *term = (char *)memchr(dmaaddr, 0, len);
if (term)
len = term - dmaaddr + 1;
memcpy(dst, dmaaddr, len);
if (term || len == maxlen)
return;
maxlen -= len;
dst += len;
vaddr += len;
while (maxlen > AlphaISA::PageBytes) {
paddr = vtophys(xc, vaddr);
dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr,
AlphaISA::PageBytes);
assert(dmaaddr);
char *term = (char *)memchr(dmaaddr, 0, AlphaISA::PageBytes);
len = term ? (term - dmaaddr + 1) : AlphaISA::PageBytes;
memcpy(dst, dmaaddr, len);
if (term)
return;
maxlen -= AlphaISA::PageBytes;
dst += AlphaISA::PageBytes;
vaddr += AlphaISA::PageBytes;
VirtualPort *vp = xc->getVirtPort(xc);
for (ChunkGenerator gen(vaddr, strlen(src), AlphaISA::PageBytes); !gen.done();
gen.next())
{
vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
src += gen.size();
}
if (maxlen > 0) {
paddr = vtophys(xc, vaddr);
dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, maxlen);
assert(dmaaddr);
char *term = (char *)memchr(dmaaddr, 0, maxlen);
len = term ? (term - dmaaddr + 1) : maxlen;
memcpy(dst, dmaaddr, len);
maxlen -= len;
}
if (maxlen == 0)
dst[maxlen] = '\0';
xc->delVirtPort(vp);
}

View file

@ -32,19 +32,21 @@
#include "arch/alpha/isa_traits.hh"
class ExecContext;
class PhysicalMemory;
class FunctionalPort;
AlphaISA::PageTableEntry
kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, AlphaISA::VAddr vaddr);
namespace AlphaISA {
Addr vtophys(PhysicalMemory *xc, Addr vaddr);
PageTableEntry
kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr);
Addr vtophys(Addr vaddr);
Addr vtophys(ExecContext *xc, Addr vaddr);
uint8_t *vtomem(ExecContext *xc, Addr vaddr, size_t len);
uint8_t *ptomem(ExecContext *xc, Addr paddr, size_t len);
void CopyOut(ExecContext *xc, void *dst, Addr src, size_t len);
void CopyIn(ExecContext *xc, Addr dst, void *src, size_t len);
void CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen);
void CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen);
void CopyStringIn(ExecContext *xc, char *src, Addr vaddr);
};
#endif // __ARCH_ALPHA_VTOPHYS_H__

View file

@ -120,16 +120,18 @@
#include <string>
#include <unistd.h>
#include "arch/vtophys.hh"
#include "base/intmath.hh"
#include "base/kgdb.h"
#include "base/remote_gdb.hh"
#include "base/socket.hh"
#include "base/trace.hh"
#include "config/full_system.hh"
#include "cpu/exec_context.hh"
#include "cpu/static_inst.hh"
#include "mem/functional/physical.hh"
#include "mem/physical.hh"
#include "mem/port.hh"
#include "sim/system.hh"
#include "arch/vtophys.hh"
using namespace std;
using namespace TheISA;
@ -372,7 +374,7 @@ RemoteGDB::acc(Addr va, size_t len)
return true;
Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20);
TheISA::PageTableEntry pte = kernel_pte_lookup(pmem, ptbr, va);
TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va);
if (!pte.valid()) {
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
return false;
@ -632,51 +634,20 @@ RemoteGDB::read(Addr vaddr, size_t size, char *data)
static Addr lastaddr = 0;
static size_t lastsize = 0;
uint8_t *maddr;
if (vaddr < 10) {
DPRINTF(GDBRead, "read: reading memory location zero!\n");
vaddr = lastaddr + lastsize;
}
DPRINTF(GDBRead, "read: addr=%#x, size=%d", vaddr, size);
#if TRACING_ON
char *d = data;
size_t s = size;
#endif
lastaddr = vaddr;
lastsize = size;
size_t count = min((Addr)size,
VMPageSize - (vaddr & (VMPageSize - 1)));
maddr = vtomem(context, vaddr, count);
memcpy(data, maddr, count);
vaddr += count;
data += count;
size -= count;
while (size >= VMPageSize) {
maddr = vtomem(context, vaddr, count);
memcpy(data, maddr, VMPageSize);
vaddr += VMPageSize;
data += VMPageSize;
size -= VMPageSize;
}
if (size > 0) {
maddr = vtomem(context, vaddr, count);
memcpy(data, maddr, size);
}
context->getVirtPort(context)->readBlob(vaddr, (uint8_t*)data, size);
#if TRACING_ON
if (DTRACE(GDBRead)) {
if (DTRACE(GDBExtra)) {
char buf[1024];
mem2hex(buf, d, s);
mem2hex(buf, data, size);
DPRINTFNR(": %s\n", buf);
} else
DPRINTFNR("\n");
@ -693,8 +664,6 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data)
static Addr lastaddr = 0;
static size_t lastsize = 0;
uint8_t *maddr;
if (vaddr < 10) {
DPRINTF(GDBWrite, "write: writing memory location zero!\n");
vaddr = lastaddr + lastsize;
@ -710,32 +679,7 @@ RemoteGDB::write(Addr vaddr, size_t size, const char *data)
DPRINTFNR("\n");
}
lastaddr = vaddr;
lastsize = size;
size_t count = min((Addr)size,
VMPageSize - (vaddr & (VMPageSize - 1)));
maddr = vtomem(context, vaddr, count);
memcpy(maddr, data, count);
vaddr += count;
data += count;
size -= count;
while (size >= VMPageSize) {
maddr = vtomem(context, vaddr, count);
memcpy(maddr, data, VMPageSize);
vaddr += VMPageSize;
data += VMPageSize;
size -= VMPageSize;
}
if (size > 0) {
maddr = vtomem(context, vaddr, count);
memcpy(maddr, data, size);
}
context->getVirtPort(context)->writeBlob(vaddr, (uint8_t*)data, size);
#ifdef IMB
alpha_pal_imb();

View file

@ -57,8 +57,9 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
AlphaITB *_itb, AlphaDTB *_dtb)
: _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
cpu_id(-1), lastActivate(0), lastSuspend(0), system(_sys), itb(_itb),
dtb(_dtb), memctrl(_sys->memctrl), profile(NULL),
quiesceEvent(this), func_exe_inst(0), storeCondFailures(0)
dtb(_dtb), profile(NULL), quiesceEvent(this), func_exe_inst(0),
storeCondFailures(0)
{
proxy = new ProxyExecContext<CPUExecContext>(this);
@ -77,6 +78,17 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
static ProfileNode dummyNode;
profileNode = &dummyNode;
profilePC = 3;
Port *mem_port;
physPort = new FunctionalPort();
mem_port = system->physmem->getPort("functional");
mem_port->setPeer(physPort);
physPort->setPeer(mem_port);
virtPort = new VirtualPort();
mem_port = system->physmem->getPort("functional");
mem_port->setPeer(virtPort);
virtPort->setPeer(mem_port);
}
#else
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
@ -278,3 +290,31 @@ CPUExecContext::copyArchRegs(ExecContext *xc)
TheISA::copyRegs(xc, proxy);
}
#if FULL_SYSTEM
VirtualPort*
CPUExecContext::getVirtPort(ExecContext *xc)
{
if (!xc)
return virtPort;
VirtualPort *vp;
Port *mem_port;
vp = new VirtualPort(xc);
mem_port = system->physmem->getPort("functional");
mem_port->setPeer(vp);
vp->setPeer(mem_port);
return vp;
}
void
CPUExecContext::delVirtPort(VirtualPort *vp)
{
assert(!vp->nullExecContext());
delete vp->getPeer();
delete vp;
}
#endif

View file

@ -48,7 +48,9 @@ class BaseCPU;
class FunctionProfile;
class ProfileNode;
class MemoryController;
class FunctionalPort;
class PhysicalPort;
#else // !FULL_SYSTEM
@ -56,6 +58,7 @@ class MemoryController;
#include "mem/page_table.hh"
class TranslatingPort;
#endif // FULL_SYSTEM
//
@ -126,11 +129,13 @@ class CPUExecContext
AlphaITB *itb;
AlphaDTB *dtb;
// the following two fields are redundant, since we can always
// look them up through the system pointer, but we'll leave them
// here for now for convenience
MemoryController *memctrl;
// PhysicalMemory *physmem;
/** A functional port outgoing only for functional accesses to physical
* addresses.*/
FunctionalPort *physPort;
/** A functional port, outgoing only, for functional accesse to virtual
* addresses. That doen't require execution context information */
VirtualPort *virtPort;
FunctionProfile *profile;
ProfileNode *profileNode;
@ -238,19 +243,28 @@ class CPUExecContext
Fault translateInstReq(CpuRequestPtr &req)
{
return itb->translate(req);
return itb->translate(req, proxy);
}
Fault translateDataReadReq(CpuRequestPtr &req)
{
return dtb->translate(req, false);
return dtb->translate(req, proxy, false);
}
Fault translateDataWriteReq(CpuRequestPtr &req)
{
return dtb->translate(req, true);
return dtb->translate(req, proxy, true);
}
FunctionalPort *getPhysPort() { return physPort; }
/** Return a virtual port. If no exec context is specified then a static
* port is returned. Otherwise a port is created and returned. It must be
* deleted by deleteVirtPort(). */
VirtualPort *getVirtPort(ExecContext *xc);
void delVirtPort(VirtualPort *vp);
#else
TranslatingPort *getMemPort() { return port; }

View file

@ -43,6 +43,8 @@ class AlphaITB;
class BaseCPU;
class Event;
class TranslatingPort;
class FunctionalPort;
class VirtualPort;
class Process;
class System;
@ -93,6 +95,12 @@ class ExecContext
virtual AlphaITB *getITBPtr() = 0;
virtual AlphaDTB * getDTBPtr() = 0;
virtual FunctionalPort *getPhysPort() = 0;
virtual VirtualPort *getVirtPort(ExecContext *xc = NULL) = 0;
virtual void delVirtPort(VirtualPort *vp) = 0;
#else
virtual TranslatingPort *getMemPort() = 0;
@ -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(); }

View file

@ -41,9 +41,10 @@
#include "cpu/base.hh"
#include "cpu/exec_context.hh"
#include "dev/alpha_console.hh"
#include "dev/platform.hh"
#include "dev/simconsole.hh"
#include "dev/simple_disk.hh"
#include "dev/tsunami_io.hh"
#include "mem/physical.hh"
#include "sim/builder.hh"
#include "sim/sim_object.hh"
@ -51,13 +52,14 @@ using namespace std;
using namespace AlphaISA;
AlphaConsole::AlphaConsole(Params *p)
: PioDevice(p->name, p->platform), disk(p->disk),
console(params()->cons), system(params()->sys), cpu(params()->cpu),
pioSize(sizeof(struct alphaAccess))
: BasicPioDevice(p), disk(p->disk),
console(params()->cons), system(params()->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)

View file

@ -43,7 +43,6 @@ class BaseCPU;
class SimConsole;
class AlphaSystem;
class SimpleDisk;
class MemoryController;
/**
* Memory mapped interface to the system console. This device
@ -70,7 +69,7 @@ class MemoryController;
* primarily used doing boot before the kernel has loaded its device
* drivers.
*/
class AlphaConsole : public BasePioDevice
class AlphaConsole : public BasicPioDevice
{
protected:
struct Access : public AlphaAccess
@ -97,12 +96,12 @@ class AlphaConsole : public BasePioDevice
BaseCPU *cpu;
public:
struct Params : public BasePioDevice::Params
struct Params : public BasicPioDevice::Params
{
SimConsole *cons;
SimpleDisk *disk;
AlphaSystem *sys;
BaseCpu *cpu;
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 &section);
public:
Tick cacheAccess(MemReqPtr &req);
};
#endif // __ALPHA_CONSOLE_HH__

View file

@ -48,9 +48,10 @@ PioPort::recvFunctional(Packet &pkt)
}
void
PioPort::getDeviceAddressRanges(AddrRangeList &range_list, bool &owner)
PioPort::getDeviceAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
{
device->addressRanges(range_list, owner);
snoop.clear();
device->addressRanges(resp);
}
@ -100,8 +101,8 @@ DmaPort::recvTiming(Packet &pkt)
return Success;
}
DmaDevice::DmaDevice(const std::string &name, Platform *p)
: PioDevice(name, p)
DmaDevice::DmaDevice(Params *p)
: PioDevice(p)
{
dmaPort = new DmaPort(this);
}
@ -195,13 +196,4 @@ DmaDevice::~DmaDevice()
delete dmaPort;
}
void
BasePioDevice::addressRanges(AddrRangeList &range_list, bool &owner)
{
assert(pioSize != 0);
owner = true;
range_list.clear();
range_list.push_back(RangeSize(pio_addr, sizeof(struct alphaAccess)));
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -29,8 +29,8 @@
#ifndef __PRINTK_HH__
#define __PRINTK_HH__
class AlphaArguments;
class AlphaISA::AlphaArguments;
void Printk(AlphaArguments args);
void Printk(AlphaISA::AlphaArguments args);
#endif // __PRINTK_HH__

View file

@ -29,10 +29,10 @@
#ifndef __DUMP_MBUF_HH__
#define __DUMP_MBUF_HH__
class AlphaArguments;
#include "arch/arguments.hh"
namespace tru64 {
void DumpMbuf(AlphaArguments args);
void DumpMbuf(AlphaISA::AlphaArguments args);
}
#endif // __DUMP_MBUF_HH__

View file

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

View file

@ -29,10 +29,10 @@
#ifndef __PRINTF_HH__
#define __PRINTF_HH__
class AlphaArguments;
#include "arch/arguments.hh"
namespace tru64 {
void Printf(AlphaArguments args);
void Printf(AlphaISA::AlphaArguments args);
}
#endif // __PRINTF_HH__

View file

@ -32,7 +32,6 @@
#include "kern/tru64/tru64_events.hh"
#include "kern/tru64/dump_mbuf.hh"
#include "kern/tru64/printf.hh"
#include "mem/functional/memory_control.hh"
#include "arch/alpha/ev5.hh"
#include "arch/arguments.hh"
#include "arch/isa_traits.hh"
@ -51,9 +50,19 @@ BadAddrEvent::process(ExecContext *xc)
uint64_t a0 = xc->readIntReg(ArgumentReg0);
if (!TheISA::IsK0Seg(a0) ||
xc->getSystemPtr()->memctrl->badaddr(
TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask)) {
AddrRangeList resp;
AddrRangeList snoop;
AddrRangeIter iter;
bool found = false;
xc->getPhysPort()->getPeerAddressRanges(resp, snoop);
for(iter = resp.begin(); iter != resp.end(); iter++)
{
if (*iter == (TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask))
found = true;
}
if (!TheISA::IsK0Seg(a0) || found ) {
DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0);
xc->setIntReg(ReturnValueReg, 0x1);

View file

@ -89,11 +89,12 @@ Bus::recvStatusChange(Port::Status status, int id)
"The other statuses need to be implemented.");
Port *port = interfaces[id];
AddrRangeList ranges;
bool owner;
AddrRangeList snoops;
port->getPeerAddressRanges(ranges, snoops);
port->getPeerAddressRanges(ranges, owner);
// not dealing with snooping yet either
assert(owner == true);
assert(snoops.size() == 0);
// or multiple ranges
assert(ranges.size() == 1);
DevMap dm;
@ -104,7 +105,7 @@ Bus::recvStatusChange(Port::Status status, int id)
}
void
Bus::BusPort::addressRanges(AddrRangeList &range_list, bool &owner)
Bus::BusPort::addressRanges(AddrRangeList &resp, AddrRangeList &snoop)
{
panic("I'm not implemented.\n");
}

View file

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

View file

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

View file

@ -63,14 +63,12 @@ class PhysicalMemory : public MemObject
virtual void recvStatusChange(Status status);
virtual void getDeviceAddressRanges(AddrRangeList &range_list,
bool &owner);
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop);
virtual int deviceBlockSize();
};
virtual Port *getPort(const std::string &if_name);
int numPorts;
int lat;
@ -107,7 +105,8 @@ class PhysicalMemory : public MemObject
public:
int deviceBlockSize();
void getAddressRanges(AddrRangeList &rangeList, bool &owner);
void getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop);
virtual Port *getPort(const std::string &if_name);
void virtual init() { port->sendStatusChange(Port::RangeChange); }
// fast back-door memory access for vtophys(), remote gdb, etc.
@ -125,14 +124,4 @@ class PhysicalMemory : public MemObject
};
/*uint64_t
PhysicalMemory::phys_read_qword(Addr addr) const
{
if (addr + sizeof(uint64_t) > pmem_size)
return 0;
return *(uint64_t *)(pmem_addr + addr);
}*/
#endif //__PHYSICAL_MEMORY_HH__

View file

@ -38,7 +38,6 @@
#ifndef __MEM_PORT_HH__
#define __MEM_PORT_HH__
#include <string>
#include <list>
#include <inttypes.h>
@ -55,6 +54,7 @@
*/
typedef std::list<Range<Addr> > AddrRangeList;
typedef std::list<Range<Addr> >::iterator AddrRangeIter;
/**
* Ports are used to interface memory objects to
@ -132,15 +132,11 @@ class Port
/** The peer port is requesting us to reply with a list of the ranges we
are responsible for.
@param owner is an output param that, if set, indicates that the
port is the owner of the specified ranges (i.e., slave, default
responder, etc.). If 'owner' is false, the interface is
interested in the specified ranges for snooping purposes. If
an object wants to own some ranges and snoop on others, it will
need to use two different ports.
@param resp is a list of ranges responded to
@param snoop is a list of ranges snooped
*/
virtual void getDeviceAddressRanges(AddrRangeList &range_list,
bool &owner)
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
{ panic("??"); }
public:
@ -189,8 +185,8 @@ class Port
/** Called by the associated device if it wishes to find out the address
ranges connected to the peer ports devices.
*/
void getPeerAddressRanges(AddrRangeList &range_list, bool &owner)
{ peer->getDeviceAddressRanges(range_list, owner); }
void getPeerAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
{ peer->getDeviceAddressRanges(resp, snoop); }
/** This function is a wrapper around sendFunctional()
that breaks a larger, arbitrarily aligned access into
@ -232,7 +228,20 @@ class FunctionalPort : public Port
virtual Tick recvAtomic(Packet &pkt) { panic("FuncPort is UniDir"); }
virtual void recvFunctional(Packet &pkt) { panic("FuncPort is UniDir"); }
virtual void recvStatusChange(Status status) {panic("FuncPort is UniDir");}
template <typename T>
inline void write(Addr addr, T d)
{
writeBlob(addr, (uint8_t*)&d, sizeof(T));
}
template <typename T>
inline T read(Addr addr)
{
T d;
readBlob(addr, (uint8_t*)&d, sizeof(T));
return d;
}
};
#endif //__MEM_PORT_HH__

69
mem/vport.cc Normal file
View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file Port object definitions.
*/
#include "base/chunk_generator.hh"
#include "mem/vport.hh"
void
VirtualPort::readBlob(Addr addr, uint8_t *p, int size)
{
Addr paddr;
for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
gen.next())
{
if (xc)
paddr = TheISA::vtophys(xc,gen.addr());
else
paddr = TheISA::vtophys(gen.addr());
FunctionalPort::readBlob(paddr, p, gen.size());
p += gen.size();
}
}
void
VirtualPort::writeBlob(Addr addr, uint8_t *p, int size)
{
Addr paddr;
for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
gen.next())
{
if (xc)
paddr = TheISA::vtophys(xc,gen.addr());
else
paddr = TheISA::vtophys(gen.addr());
FunctionalPort::writeBlob(paddr, p, gen.size());
p += gen.size();
}
}

109
mem/vport.hh Normal file
View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* Virtual Port Object Decleration. These ports incorporate some translation
* into their access methods. Thus you can use one to read and write data
* to/from virtual addresses.
*/
#ifndef __MEM_VPORT_HH__
#define __MEM_VPORT_HH__
#include "mem/port.hh"
#include "config/full_system.hh"
#include "arch/vtophys.hh"
/** A class that translates a virtual address to a physical address and then
* calls the above read/write functions. If an execution context is provided the
* address can alway be translated, If not it can only be translated if it is a
* simple address masking operation (such as alpha super page accesses).
*/
class VirtualPort : public FunctionalPort
{
private:
ExecContext *xc;
public:
VirtualPort(ExecContext *_xc = NULL)
: xc(_xc)
{}
/** Return true if we have an exec context. This is used to prevent someone
* from accidently deleting the cpus statically allocated vport.
* @return true if an execution context isn't valid
*/
bool nullExecContext() { return xc != NULL; }
/** Write a piece of data into a virtual address.
* @param vaddr virtual address to write to
* @param data data to write
*/
template <typename T>
inline void write(Addr vaddr, T data)
{
Addr paddr;
if (xc)
paddr = TheISA::vtophys(xc,vaddr);
else
paddr = TheISA::vtophys(vaddr);
FunctionalPort::write(paddr, data);
}
/** Read data from a virtual address and return it.
* @param vaddr address to read
* @return data read
*/
template <typename T>
inline T read(Addr vaddr)
{
Addr paddr;
if (xc)
paddr = TheISA::vtophys(xc,vaddr);
else
paddr = TheISA::vtophys(vaddr);
return FunctionalPort::read<T>(paddr);
}
/** Version of readblob that translates virt->phys and deals
* with page boundries. */
virtual void readBlob(Addr addr, uint8_t *p, int size);
/** Version of writeBlob that translates virt->phys and deals
* with page boundries. */
virtual void writeBlob(Addr addr, uint8_t *p, int size);
};
#endif //__MEM_VPORT_HH__

View file

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

View file

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

View file

@ -175,7 +175,7 @@ namespace AlphaPseudo
addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr)
{
char symb[100];
CopyString(xc, symb, symbolAddr, 100);
CopyStringOut(xc, symb, symbolAddr, 100);
std::string symbol(symb);
DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);

View file

@ -1,16 +1,17 @@
#include "arch/isa_traits.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "mem/mem_object.hh"
#include "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)

View file

@ -40,13 +40,13 @@
#include "sim/sim_object.hh"
#if FULL_SYSTEM
#include "kern/system_events.hh"
#include "mem/vport.hh"
#endif
class BaseCPU;
class ExecContext;
class MemoryController;
class ObjectFile;
class MemObject;
class PhysicalMemory;
#if FULL_SYSTEM
class Platform;
@ -58,7 +58,7 @@ namespace Kernel { class Binning; }
class System : public SimObject
{
public:
MemObject *physmem;
PhysicalMemory *physmem;
PCEventQueue pcEventQueue;
std::vector<ExecContext *> execContexts;
@ -73,13 +73,13 @@ class System : public SimObject
}
#if FULL_SYSTEM
MemoryController *memctrl;
Platform *platform;
uint64_t init_param;
/** Port to physical memory used for writing object files into ram at
* boot.*/
FunctionalPort functionalPort;
VirtualPort virtPort;
/** kernel symbol table */
SymbolTable *kernelSymtab;
@ -151,11 +151,10 @@ class System : public SimObject
struct Params
{
std::string name;
MemObject *physmem;
PhysicalMemory *physmem;
#if FULL_SYSTEM
Tick boot_cpu_frequency;
MemoryController *memctrl;
uint64_t init_param;
bool bin;
std::vector<std::string> binned_fns;

View file

@ -96,20 +96,26 @@ class VPtr
operator T *()
{
void *addr = vtomem(xc, ptr, sizeof(T));
panic("Needs to be rewritten\n");
/* void *addr = vtomem(xc, ptr, sizeof(T));
return (T *)addr;
*/
}
T *operator->()
{
void *addr = vtomem(xc, ptr, sizeof(T));
panic("Needs to be rewritten\n");
/* void *addr = vtomem(xc, ptr, sizeof(T));
return (T *)addr;
*/
}
T &operator*()
{
void *addr = vtomem(xc, ptr, sizeof(T));
panic("Needs to be rewritten\n");
/* void *addr = vtomem(xc, ptr, sizeof(T));
return *(T *)addr;
*/
}
};