malta_cchip.cc

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 536 行 · 第 1/2 页

CC
536
字号
/* * Copyright (c) 2007 MIPS Technologies, Inc.  All Rights Reserved * * This software is part of the M5 simulator. * * THIS IS A LEGAL AGREEMENT.  BY DOWNLOADING, USING, COPYING, CREATING * DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING * TO THESE TERMS AND CONDITIONS. * * Permission is granted to use, copy, create derivative works and * distribute this software and such derivative works for any purpose, * so long as (1) the copyright notice above, this grant of permission, * and the disclaimer below appear in all copies and derivative works * made, (2) the copyright notice above is augmented as appropriate to * reflect the addition of any new copyrightable work in a derivative * work (e.g., Copyright (c) <Publication Year> Copyright Owner), and (3) * the name of MIPS Technologies, Inc. (∪MIPS∩) is not used in any * advertising or publicity pertaining to the use or distribution of * this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED ∪AS IS.∩  MIPS MAKES NO WARRANTIES AND * DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR * OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND * NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE. * IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, * INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF * ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT, * THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY * IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR * STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE * POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE. * * Authors: Richard Strong  * *//** @file * Emulation of the Malta CChip CSRs */#include <deque>#include <string>#include <vector>#include "arch/mips/mips_core_specific.hh"#include "base/trace.hh"#include "cpu/intr_control.hh"#include "cpu/thread_context.hh"#include "dev/mips/malta.hh"#include "dev/mips/malta_cchip.hh"#include "dev/mips/maltareg.h"#include "mem/packet.hh"#include "mem/packet_access.hh"#include "mem/port.hh"#include "params/MaltaCChip.hh"#include "sim/system.hh"using namespace std;using namespace TheISA;MaltaCChip::MaltaCChip(Params *p)    : BasicPioDevice(p), malta(p->malta){                warn("MaltaCCHIP::MaltaCChip() not implemented.");    pioSize = 0xfffffff;    //Put back pointer in malta    malta->cchip = this;}TickMaltaCChip::read(PacketPtr pkt){                panic("MaltaCCHIP::read() not implemented.");                return pioDelay;                /*    DPRINTF(Malta, "read  va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());    assert(pkt->result == Packet::Unknown);    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);    Addr regnum = (pkt->getAddr() - pioAddr) >> 6;    Addr daddr = (pkt->getAddr() - pioAddr);    pkt->allocate();    switch (pkt->getSize()) {      case sizeof(uint64_t):          if (daddr & TSDEV_CC_BDIMS)          {              pkt->set(dim[(daddr >> 4) & 0x3F]);              break;          }          if (daddr & TSDEV_CC_BDIRS)          {              pkt->set(dir[(daddr >> 4) & 0x3F]);              break;          }          switch(regnum) {              case TSDEV_CC_CSR:                  pkt->set(0x0);                  break;              case TSDEV_CC_MTR:                  panic("TSDEV_CC_MTR not implemeted\n");                   break;              case TSDEV_CC_MISC:                  pkt->set((ipint << 8) & 0xF | (itint << 4) & 0xF |                                     (pkt->req->getCpuNum() & 0x3));                  break;              case TSDEV_CC_AAR0:              case TSDEV_CC_AAR1:              case TSDEV_CC_AAR2:              case TSDEV_CC_AAR3:                  pkt->set(0);                  break;              case TSDEV_CC_DIM0:                  pkt->set(dim[0]);                  break;              case TSDEV_CC_DIM1:                  pkt->set(dim[1]);                  break;              case TSDEV_CC_DIM2:                  pkt->set(dim[2]);                  break;              case TSDEV_CC_DIM3:                  pkt->set(dim[3]);                  break;              case TSDEV_CC_DIR0:                  pkt->set(dir[0]);                  break;              case TSDEV_CC_DIR1:                  pkt->set(dir[1]);                  break;              case TSDEV_CC_DIR2:                  pkt->set(dir[2]);                  break;              case TSDEV_CC_DIR3:                  pkt->set(dir[3]);                  break;              case TSDEV_CC_DRIR:                  pkt->set(drir);                  break;              case TSDEV_CC_PRBEN:                  panic("TSDEV_CC_PRBEN not implemented\n");                  break;              case TSDEV_CC_IIC0:              case TSDEV_CC_IIC1:              case TSDEV_CC_IIC2:              case TSDEV_CC_IIC3:                  panic("TSDEV_CC_IICx not implemented\n");                  break;              case TSDEV_CC_MPR0:              case TSDEV_CC_MPR1:              case TSDEV_CC_MPR2:              case TSDEV_CC_MPR3:                  panic("TSDEV_CC_MPRx not implemented\n");                  break;              case TSDEV_CC_IPIR:                  pkt->set(ipint);                  break;              case TSDEV_CC_ITIR:                  pkt->set(itint);                  break;              default:                  panic("default in cchip read reached, accessing 0x%x\n");           } // uint64_t      break;      case sizeof(uint32_t):      case sizeof(uint16_t):      case sizeof(uint8_t):      default:        panic("invalid access size(?) for malta register!\n");    }    DPRINTF(Malta, "Malta CChip: read  regnum=%#x size=%d data=%lld\n",            regnum, pkt->getSize(), pkt->get<uint64_t>());    pkt->result = Packet::Success;    return pioDelay;    */}TickMaltaCChip::write(PacketPtr pkt){                panic("MaltaCCHIP::write() not implemented.");                return pioDelay;                /*    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);    Addr daddr = pkt->getAddr() - pioAddr;    Addr regnum = (pkt->getAddr() - pioAddr) >> 6 ;    assert(pkt->getSize() == sizeof(uint64_t));    DPRINTF(Malta, "write - addr=%#x value=%#x\n", pkt->getAddr(), pkt->get<uint64_t>());    bool supportedWrite = false;    if (daddr & TSDEV_CC_BDIMS)    {        int number = (daddr >> 4) & 0x3F;        uint64_t bitvector;        uint64_t olddim;        uint64_t olddir;        olddim = dim[number];        olddir = dir[number];        dim[number] = pkt->get<uint64_t>();        dir[number] = dim[number] & drir;        for(int x = 0; x < Malta::Max_CPUs; x++)        {            bitvector = ULL(1) << x;            // Figure out which bits have changed            if ((dim[number] & bitvector) != (olddim & bitvector))            {                // The bit is now set and it wasn't before (set)                if((dim[number] & bitvector) && (dir[number] & bitvector))                {                    malta->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x);                    DPRINTF(Malta, "dim write resulting in posting dir"                            " interrupt to cpu %d\n", number);                }                else if ((olddir & bitvector) &&                        !(dir[number] & bitvector))                {                    // The bit was set and now its now clear and                    // we were interrupting on that bit before                    malta->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x);                    DPRINTF(Malta, "dim write resulting in clear"                            " dir interrupt to cpu %d\n", number);                }            }        }    } else {        switch(regnum) {          case TSDEV_CC_CSR:              panic("TSDEV_CC_CSR write\n");          case TSDEV_CC_MTR:              panic("TSDEV_CC_MTR write not implemented\n");          case TSDEV_CC_MISC:            uint64_t ipreq;            ipreq = (pkt->get<uint64_t>() >> 12) & 0xF;            //If it is bit 12-15, this is an IPI post            if (ipreq) {                reqIPI(ipreq);                supportedWrite = true;            }            //If it is bit 8-11, this is an IPI clear            uint64_t ipintr;            ipintr = (pkt->get<uint64_t>() >> 8) & 0xF;            if (ipintr) {                clearIPI(ipintr);                supportedWrite = true;            }            //If it is the 4-7th bit, clear the RTC interrupt            uint64_t itintr;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?