⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ns_gige.cc

📁 M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作为模拟平台
💻 CC
📖 第 1 页 / 共 5 页
字号:
/** * This is to write to the PCI general configuration registers */TickNSGigE::writeConfig(PacketPtr pkt){    int offset = pkt->getAddr() & PCI_CONFIG_SIZE;    if (offset < PCI_DEVICE_SPECIFIC)        PciDev::writeConfig(pkt);    else        panic("Device specific PCI config space not implemented!\n");    switch (offset) {        // seems to work fine without all these PCI settings, but i        // put in the IO to double check, an assertion will fail if we        // need to properly implement it      case PCI_COMMAND:        if (config.data[offset] & PCI_CMD_IOSE)            ioEnable = true;        else            ioEnable = false;        break;    }    return configDelay;}EtherInt*NSGigE::getEthPort(const std::string &if_name, int idx){    if (if_name == "interface") {       if (interface->getPeer())           panic("interface already connected to\n");       return interface;    }    return NULL;}/** * This reads the device registers, which are detailed in the NS83820 * spec sheet */TickNSGigE::read(PacketPtr pkt){    assert(ioEnable);    pkt->allocate();    //The mask is to give you only the offset into the device register file    Addr daddr = pkt->getAddr() & 0xfff;    DPRINTF(EthernetPIO, "read  da=%#x pa=%#x size=%d\n",            daddr, pkt->getAddr(), pkt->getSize());    // there are some reserved registers, you can see ns_gige_reg.h and    // the spec sheet for details    if (daddr > LAST && daddr <=  RESERVED) {        panic("Accessing reserved register");    } else if (daddr > RESERVED && daddr <= 0x3FC) {        return readConfig(pkt);    } else if (daddr >= MIB_START && daddr <= MIB_END) {        // don't implement all the MIB's.  hopefully the kernel        // doesn't actually DEPEND upon their values        // MIB are just hardware stats keepers        pkt->set<uint32_t>(0);        pkt->makeAtomicResponse();        return pioDelay;    } else if (daddr > 0x3FC)        panic("Something is messed up!\n");    assert(pkt->getSize() == sizeof(uint32_t));        uint32_t &reg = *pkt->getPtr<uint32_t>();        uint16_t rfaddr;        switch (daddr) {          case CR:            reg = regs.command;            //these are supposed to be cleared on a read            reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR);            break;          case CFGR:            reg = regs.config;            break;          case MEAR:            reg = regs.mear;            break;          case PTSCR:            reg = regs.ptscr;            break;          case ISR:            reg = regs.isr;            devIntrClear(ISR_ALL);            break;          case IMR:            reg = regs.imr;            break;          case IER:            reg = regs.ier;            break;          case IHR:            reg = regs.ihr;            break;          case TXDP:            reg = regs.txdp;            break;          case TXDP_HI:            reg = regs.txdp_hi;            break;          case TX_CFG:            reg = regs.txcfg;            break;          case GPIOR:            reg = regs.gpior;            break;          case RXDP:            reg = regs.rxdp;            break;          case RXDP_HI:            reg = regs.rxdp_hi;            break;          case RX_CFG:            reg = regs.rxcfg;            break;          case PQCR:            reg = regs.pqcr;            break;          case WCSR:            reg = regs.wcsr;            break;          case PCR:            reg = regs.pcr;            break;            // see the spec sheet for how RFCR and RFDR work            // basically, you write to RFCR to tell the machine            // what you want to do next, then you act upon RFDR,            // and the device will be prepared b/c of what you            // wrote to RFCR          case RFCR:            reg = regs.rfcr;            break;          case RFDR:            rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR);            switch (rfaddr) {              // Read from perfect match ROM octets              case 0x000:                reg = rom.perfectMatch[1];                reg = reg << 8;                reg += rom.perfectMatch[0];                break;              case 0x002:                reg = rom.perfectMatch[3] << 8;                reg += rom.perfectMatch[2];                break;              case 0x004:                reg = rom.perfectMatch[5] << 8;                reg += rom.perfectMatch[4];                break;              default:                // Read filter hash table                if (rfaddr >= FHASH_ADDR &&                    rfaddr < FHASH_ADDR + FHASH_SIZE) {                    // Only word-aligned reads supported                    if (rfaddr % 2)                        panic("unaligned read from filter hash table!");                    reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8;                    reg += rom.filterHash[rfaddr - FHASH_ADDR];                    break;                }                panic("reading RFDR for something other than pattern"                      " matching or hashing! %#x\n", rfaddr);            }            break;          case SRR:            reg = regs.srr;            break;          case MIBC:            reg = regs.mibc;            reg &= ~(MIBC_MIBS | MIBC_ACLR);            break;          case VRCR:            reg = regs.vrcr;            break;          case VTCR:            reg = regs.vtcr;            break;          case VDR:            reg = regs.vdr;            break;          case CCSR:            reg = regs.ccsr;            break;          case TBICR:            reg = regs.tbicr;            break;          case TBISR:            reg = regs.tbisr;            break;          case TANAR:            reg = regs.tanar;            break;          case TANLPAR:            reg = regs.tanlpar;            break;          case TANER:            reg = regs.taner;            break;          case TESR:            reg = regs.tesr;            break;          case M5REG:            reg = 0;            if (params()->rx_thread)                reg |= M5REG_RX_THREAD;            if (params()->tx_thread)                reg |= M5REG_TX_THREAD;            if (params()->rss)                reg |= M5REG_RSS;            break;          default:            panic("reading unimplemented register: addr=%#x", daddr);        }        DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n",                daddr, reg, reg);    pkt->makeAtomicResponse();    return pioDelay;}TickNSGigE::write(PacketPtr pkt){    assert(ioEnable);    Addr daddr = pkt->getAddr() & 0xfff;    DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n",            daddr, pkt->getAddr(), pkt->getSize());    if (daddr > LAST && daddr <=  RESERVED) {        panic("Accessing reserved register");    } else if (daddr > RESERVED && daddr <= 0x3FC) {        return writeConfig(pkt);    } else if (daddr > 0x3FC)        panic("Something is messed up!\n");    if (pkt->getSize() == sizeof(uint32_t)) {        uint32_t reg = pkt->get<uint32_t>();        uint16_t rfaddr;        DPRINTF(EthernetPIO, "write data=%d data=%#x\n", reg, reg);        switch (daddr) {          case CR:            regs.command = reg;            if (reg & CR_TXD) {                txEnable = false;            } else if (reg & CR_TXE) {                txEnable = true;                // the kernel is enabling the transmit machine                if (txState == txIdle)                    txKick();            }            if (reg & CR_RXD) {                rxEnable = false;            } else if (reg & CR_RXE) {                rxEnable = true;                if (rxState == rxIdle)                    rxKick();            }            if (reg & CR_TXR)                txReset();            if (reg & CR_RXR)                rxReset();            if (reg & CR_SWI)                devIntrPost(ISR_SWI);            if (reg & CR_RST) {                txReset();                rxReset();                regsReset();            }            break;          case CFGR:            if (reg & CFGR_LNKSTS ||                reg & CFGR_SPDSTS ||                reg & CFGR_DUPSTS ||                reg & CFGR_RESERVED ||                reg & CFGR_T64ADDR ||                reg & CFGR_PCI64_DET)            // First clear all writable bits            regs.config &= CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS |                                   CFGR_RESERVED | CFGR_T64ADDR |                                   CFGR_PCI64_DET;            // Now set the appropriate writable bits            regs.config |= reg & ~(CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS |                                   CFGR_RESERVED | CFGR_T64ADDR |                                   CFGR_PCI64_DET);// all these #if 0's are because i don't THINK the kernel needs to// have these implemented. if there is a problem relating to one of// these, you may need to add functionality in.            if (reg & CFGR_TBI_EN) ;            if (reg & CFGR_MODE_1000) ;            if (reg & CFGR_AUTO_1000)                panic("CFGR_AUTO_1000 not implemented!\n");            if (reg & CFGR_PINT_DUPSTS ||                reg & CFGR_PINT_LNKSTS ||                reg & CFGR_PINT_SPDSTS)                ;            if (reg & CFGR_TMRTEST) ;            if (reg & CFGR_MRM_DIS) ;            if (reg & CFGR_MWI_DIS) ;            if (reg & CFGR_T64ADDR) ;            // panic("CFGR_T64ADDR is read only register!\n");            if (reg & CFGR_PCI64_DET)                panic("CFGR_PCI64_DET is read only register!\n");            if (reg & CFGR_DATA64_EN) ;            if (reg & CFGR_M64ADDR) ;            if (reg & CFGR_PHY_RST) ;            if (reg & CFGR_PHY_DIS) ;            if (reg & CFGR_EXTSTS_EN)                extstsEnable = true;            else                extstsEnable = false;            if (reg & CFGR_REQALG) ;            if (reg & CFGR_SB) ;            if (reg & CFGR_POW) ;            if (reg & CFGR_EXD) ;            if (reg & CFGR_PESEL) ;            if (reg & CFGR_BROM_DIS) ;            if (reg & CFGR_EXT_125) ;            if (reg & CFGR_BEM) ;            break;          case MEAR:            // Clear writable bits            regs.mear &= MEAR_EEDO;            // Set appropriate writable bits            regs.mear |= reg & ~MEAR_EEDO;            // FreeBSD uses the EEPROM to read PMATCH (for the MAC address)            // even though it could get it through RFDR            if (reg & MEAR_EESEL) {                // Rising edge of clock                if (reg & MEAR_EECLK && !eepromClk)                    eepromKick();            }            else {                eepromState = eepromStart;                regs.mear &= ~MEAR_EEDI;            }            eepromClk = reg & MEAR_EECLK;            // since phy is completely faked, MEAR_MD* don't matter            if (reg & MEAR_MDIO) ;            if (reg & MEAR_MDDIR) ;            if (reg & MEAR_MDC) ;            break;          case PTSCR:            regs.ptscr = reg & ~(PTSCR_RBIST_RDONLY);            // these control BISTs for various parts of chip - we            // don't care or do just fake that the BIST is done            if (reg & PTSCR_RBIST_EN)                regs.ptscr |= PTSCR_RBIST_DONE;            if (reg & PTSCR_EEBIST_EN)                regs.ptscr &= ~PTSCR_EEBIST_EN;            if (reg & PTSCR_EELOAD_EN)                regs.ptscr &= ~PTSCR_EELOAD_EN;            break;          case ISR: /* writing to the ISR has no effect */            panic("ISR is a read only register!\n");          case IMR:            regs.imr = reg;            devIntrChangeMask();            break;          case IER:            regs.ier = reg;            break;          case IHR:            regs.ihr = reg;            /* not going to implement real interrupt holdoff */            break;          case TXDP:            regs.txdp = (reg & 0xFFFFFFFC);            assert(txState == txIdle);            CTDD = false;            break;          case TXDP_HI:            regs.txdp_hi = reg;            break;          case TX_CFG:            regs.txcfg = reg;#if 0            if (reg & TX_CFG_CSI) ;            if (reg & TX_CFG_HBI) ;            if (reg & TX_CFG_MLB) ;            if (reg & TX_CFG_ATP) ;            if (reg & TX_CFG_ECRETRY) {                /*                 * this could easily be implemented, but considering                 * the network is just a fake pipe, wouldn't make                 * sense to do this                 */            }

⌨️ 快捷键说明

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