b64eae5e52
SConscript: Added more files to compile: dev/pcifake.cc, dev/isa_fake.cc, kern/freebsd/freebsd_system.cc, kern/freebsd/freebsd_events.cc. arch/alpha/isa_traits.hh: Added constant for argument register 2 as it is needed by FreebsdSystem::doCalibrateClocks(). cpu/exec_context.hh: cpu/o3/alpha_cpu.hh: Replaced htoa()s with gtoh() and htog(). cpu/o3/fetch_impl.hh: cpu/simple/cpu.cc: Replaced htoa() with gtoh(). dev/disk_image.cc: Replaced htoa()s with letoh()s. dev/ide_ctrl.cc: Got rid of magic numbers. Added IdeChannel and IdeRegType type names where necessary. dev/ide_ctrl.hh: Got rid of unnecessary macros. Changed RegType_t to IdeRegType. Changed bmi_regs to allow accessing registers by name instead of just by array index. Added IdeChannel enum type to use in place of bool variables which were used to specify IDE channel. dev/ide_disk.cc: Rewrote IdeDisk::read and IdeDisk::write functions to specify registers by name instead of indexing through an array. dev/ide_disk.hh: Updated command register struct. dev/ns_gige.cc: dev/ns_gige.hh: Made ReadConfig and WriteConfig begin with a lower-case letter. writeConfig() now takes a pointer to data as a parameter instead of a copy of data. dev/pciconfigall.cc: writeConfig() now takes a pointer to data as a parameter instead of a copy of data. dev/pcidev.cc: Cleaned up readConfig() and writeConfig() functions. dev/pcidev.hh: Added macros to make code that works with the BARs (base adress registers) more readable. writeConfig() now takes a pointer to data. dev/pcireg.h: Changed PCIConfig struct to make accessing elements more straight forward. Removed type 1 (for PCI-to-PCI bridges) PCI configuration space struct since it is not used. dev/rtcreg.h: Added macros for bit fields in RTC status registers A & B. dev/sinic.cc: Function name change: WriteConfig --> writeConfig. writeConfig() now takes a pointer to data instead of a copy of data. The accessing of elements of PCIConfig structure is updated. dev/sinic.hh: Function name change: WriteConfig --> writeConfig. writeConfig() now takes a pointer to data instead of a copy of data. dev/tsunami_io.cc: Added implementation of new RTC and PIT classes. dev/tsunami_io.hh: Added classes for RTC and PIT modules. dev/tsunamireg.h: Added macros for DMA ports used by Tsunami-Tru64. dev/uart8250.cc: Got rid of a magic number. Transmit (Tx) interrupts should clear upon a read of the Interrupt ID register. dev/uart8250.hh: Added comments and macros dealing with the UART Interrupt ID register. kern/linux/linux_system.cc: Replaced htoa() with htog(). python/m5/objects/Pci.py: PciFake is a python class for Pci Devices that do nothing. python/m5/objects/Tsunami.py: TsunamiFake was renamed as IsaFake. sim/system.cc: Replaced htoa()s with htog()s. dev/isa_fake.cc: New BitKeeper file ``dev/isa_fake.cc'' TsunamiFake was renamed as IsaFake. dev/isa_fake.hh: New BitKeeper file ``dev/isa_fake.hh'' TsunmaiFake was renamed as IsaFake. dev/pitreg.h: New BitKeeper file ``dev/pitreg.h'' Useful macros for working with PIT (Periodic Interval Timer) registers. --HG-- extra : convert_revision : 33f3a8a1034af4f6c71b32dd743e371c8613e780
291 lines
8.9 KiB
C++
291 lines
8.9 KiB
C++
/*
|
|
* Copyright (c) 2004-2005 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.
|
|
*/
|
|
|
|
// Todo: Find all the stuff in ExecContext and ev5 that needs to be
|
|
// specifically designed for this CPU.
|
|
|
|
#ifndef __CPU_O3_CPU_ALPHA_FULL_CPU_HH__
|
|
#define __CPU_O3_CPU_ALPHA_FULL_CPU_HH__
|
|
|
|
#include "cpu/o3/cpu.hh"
|
|
|
|
template <class Impl>
|
|
class AlphaFullCPU : public FullO3CPU<Impl>
|
|
{
|
|
public:
|
|
typedef typename Impl::ISA AlphaISA;
|
|
typedef typename Impl::Params Params;
|
|
|
|
public:
|
|
AlphaFullCPU(Params ¶ms);
|
|
|
|
#ifdef FULL_SYSTEM
|
|
AlphaITB *itb;
|
|
AlphaDTB *dtb;
|
|
#endif
|
|
|
|
public:
|
|
void regStats();
|
|
|
|
#ifdef FULL_SYSTEM
|
|
//Note that the interrupt stuff from the base CPU might be somewhat
|
|
//ISA specific (ie NumInterruptLevels). These functions might not
|
|
//be needed in FullCPU though.
|
|
// void post_interrupt(int int_num, int index);
|
|
// void clear_interrupt(int int_num, int index);
|
|
// void clear_interrupts();
|
|
|
|
Fault translateInstReq(MemReqPtr &req)
|
|
{
|
|
return itb->translate(req);
|
|
}
|
|
|
|
Fault translateDataReadReq(MemReqPtr &req)
|
|
{
|
|
return dtb->translate(req, false);
|
|
}
|
|
|
|
Fault translateDataWriteReq(MemReqPtr &req)
|
|
{
|
|
return dtb->translate(req, true);
|
|
}
|
|
|
|
#else
|
|
Fault dummyTranslation(MemReqPtr &req)
|
|
{
|
|
#if 0
|
|
assert((req->vaddr >> 48 & 0xffff) == 0);
|
|
#endif
|
|
|
|
// put the asid in the upper 16 bits of the paddr
|
|
req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16);
|
|
req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
|
|
return No_Fault;
|
|
}
|
|
|
|
Fault translateInstReq(MemReqPtr &req)
|
|
{
|
|
return dummyTranslation(req);
|
|
}
|
|
|
|
Fault translateDataReadReq(MemReqPtr &req)
|
|
{
|
|
return dummyTranslation(req);
|
|
}
|
|
|
|
Fault translateDataWriteReq(MemReqPtr &req)
|
|
{
|
|
return dummyTranslation(req);
|
|
}
|
|
|
|
#endif
|
|
|
|
// Later on may want to remove this misc stuff from the regfile and
|
|
// have it handled at this level. Might prove to be an issue when
|
|
// trying to rename source/destination registers...
|
|
uint64_t readUniq()
|
|
{
|
|
return this->regFile.readUniq();
|
|
}
|
|
|
|
void setUniq(uint64_t val)
|
|
{
|
|
this->regFile.setUniq(val);
|
|
}
|
|
|
|
uint64_t readFpcr()
|
|
{
|
|
return this->regFile.readFpcr();
|
|
}
|
|
|
|
void setFpcr(uint64_t val)
|
|
{
|
|
this->regFile.setFpcr(val);
|
|
}
|
|
|
|
// Most of the full system code and syscall emulation is not yet
|
|
// implemented. These functions do show what the final interface will
|
|
// look like.
|
|
#ifdef FULL_SYSTEM
|
|
uint64_t *getIpr();
|
|
uint64_t readIpr(int idx, Fault &fault);
|
|
Fault setIpr(int idx, uint64_t val);
|
|
int readIntrFlag();
|
|
void setIntrFlag(int val);
|
|
Fault hwrei();
|
|
bool inPalMode() { return AlphaISA::PcPAL(this->regFile.readPC()); }
|
|
bool inPalMode(uint64_t PC)
|
|
{ return AlphaISA::PcPAL(PC); }
|
|
|
|
void trap(Fault fault);
|
|
bool simPalCheck(int palFunc);
|
|
|
|
void processInterrupts();
|
|
#endif
|
|
|
|
|
|
#ifndef FULL_SYSTEM
|
|
// Need to change these into regfile calls that directly set a certain
|
|
// register. Actually, these functions should handle most of this
|
|
// functionality by themselves; should look up the rename and then
|
|
// set the register.
|
|
IntReg getSyscallArg(int i)
|
|
{
|
|
return this->xc->regs.intRegFile[AlphaISA::ArgumentReg0 + i];
|
|
}
|
|
|
|
// used to shift args for indirect syscall
|
|
void setSyscallArg(int i, IntReg val)
|
|
{
|
|
this->xc->regs.intRegFile[AlphaISA::ArgumentReg0 + i] = val;
|
|
}
|
|
|
|
void setSyscallReturn(int64_t return_value)
|
|
{
|
|
// check for error condition. Alpha syscall convention is to
|
|
// indicate success/failure in reg a3 (r19) and put the
|
|
// return value itself in the standard return value reg (v0).
|
|
const int RegA3 = 19; // only place this is used
|
|
if (return_value >= 0) {
|
|
// no error
|
|
this->xc->regs.intRegFile[RegA3] = 0;
|
|
this->xc->regs.intRegFile[AlphaISA::ReturnValueReg] = return_value;
|
|
} else {
|
|
// got an error, return details
|
|
this->xc->regs.intRegFile[RegA3] = (IntReg) -1;
|
|
this->xc->regs.intRegFile[AlphaISA::ReturnValueReg] = -return_value;
|
|
}
|
|
}
|
|
|
|
void syscall(short thread_num);
|
|
void squashStages();
|
|
|
|
#endif
|
|
|
|
void copyToXC();
|
|
void copyFromXC();
|
|
|
|
public:
|
|
#ifdef FULL_SYSTEM
|
|
bool palShadowEnabled;
|
|
|
|
// Not sure this is used anywhere.
|
|
void intr_post(RegFile *regs, Fault fault, Addr pc);
|
|
// Actually used within exec files. Implement properly.
|
|
void swapPALShadow(bool use_shadow);
|
|
// Called by CPU constructor. Can implement as I please.
|
|
void initCPU(RegFile *regs);
|
|
// Called by initCPU. Implement as I please.
|
|
void initIPRs(RegFile *regs);
|
|
|
|
void halt() { panic("Halt not implemented!\n"); }
|
|
#endif
|
|
|
|
|
|
template <class T>
|
|
Fault read(MemReqPtr &req, T &data)
|
|
{
|
|
#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM)
|
|
if (req->flags & LOCKED) {
|
|
MiscRegFile *cregs = &req->xc->regs.miscRegs;
|
|
cregs->lock_addr = req->paddr;
|
|
cregs->lock_flag = true;
|
|
}
|
|
#endif
|
|
|
|
Fault error;
|
|
error = this->mem->read(req, data);
|
|
data = gtoh(data);
|
|
return error;
|
|
}
|
|
|
|
template <class T>
|
|
Fault read(MemReqPtr &req, T &data, int load_idx)
|
|
{
|
|
return this->iew.ldstQueue.read(req, data, load_idx);
|
|
}
|
|
|
|
template <class T>
|
|
Fault write(MemReqPtr &req, T &data)
|
|
{
|
|
#if defined(TARGET_ALPHA) && defined(FULL_SYSTEM)
|
|
|
|
MiscRegFile *cregs;
|
|
|
|
// If this is a store conditional, act appropriately
|
|
if (req->flags & LOCKED) {
|
|
cregs = &this->xc->regs.miscRegs;
|
|
|
|
if (req->flags & UNCACHEABLE) {
|
|
// Don't update result register (see stq_c in isa_desc)
|
|
req->result = 2;
|
|
req->xc->storeCondFailures = 0;//Needed? [RGD]
|
|
} else {
|
|
req->result = cregs->lock_flag;
|
|
if (!cregs->lock_flag ||
|
|
((cregs->lock_addr & ~0xf) != (req->paddr & ~0xf))) {
|
|
cregs->lock_flag = false;
|
|
if (((++req->xc->storeCondFailures) % 100000) == 0) {
|
|
std::cerr << "Warning: "
|
|
<< req->xc->storeCondFailures
|
|
<< " consecutive store conditional failures "
|
|
<< "on cpu " << this->cpu_id
|
|
<< std::endl;
|
|
}
|
|
return No_Fault;
|
|
}
|
|
else req->xc->storeCondFailures = 0;
|
|
}
|
|
}
|
|
|
|
// Need to clear any locked flags on other proccessors for
|
|
// this address. Only do this for succsful Store Conditionals
|
|
// and all other stores (WH64?). Unsuccessful Store
|
|
// Conditionals would have returned above, and wouldn't fall
|
|
// through.
|
|
for (int i = 0; i < this->system->execContexts.size(); i++){
|
|
cregs = &this->system->execContexts[i]->regs.miscRegs;
|
|
if ((cregs->lock_addr & ~0xf) == (req->paddr & ~0xf)) {
|
|
cregs->lock_flag = false;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
return this->mem->write(req, (T)htog(data));
|
|
}
|
|
|
|
template <class T>
|
|
Fault write(MemReqPtr &req, T &data, int store_idx)
|
|
{
|
|
return this->iew.ldstQueue.write(req, data, store_idx);
|
|
}
|
|
|
|
};
|
|
|
|
#endif // __CPU_O3_CPU_ALPHA_FULL_CPU_HH__
|