| /* |
| * 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 |
| * Register and structure descriptions for Intel's 8254x line of gigabit ethernet controllers. |
| */ |
| #include "base/bitfield.hh" |
| #include "base/compiler.hh" |
| |
| namespace gem5 |
| { |
| |
| GEM5_DEPRECATED_NAMESPACE(iGbReg, igbreg); |
| namespace igbreg |
| { |
| |
| // Registers used by the Intel GbE NIC |
| const uint32_t REG_CTRL = 0x00000; |
| const uint32_t REG_STATUS = 0x00008; |
| const uint32_t REG_EECD = 0x00010; |
| const uint32_t REG_EERD = 0x00014; |
| const uint32_t REG_CTRL_EXT = 0x00018; |
| const uint32_t REG_MDIC = 0x00020; |
| const uint32_t REG_FCAL = 0x00028; |
| const uint32_t REG_FCAH = 0x0002C; |
| const uint32_t REG_FCT = 0x00030; |
| const uint32_t REG_VET = 0x00038; |
| const uint32_t REG_PBA = 0x01000; |
| const uint32_t REG_ICR = 0x000C0; |
| const uint32_t REG_ITR = 0x000C4; |
| const uint32_t REG_ICS = 0x000C8; |
| const uint32_t REG_IMS = 0x000D0; |
| const uint32_t REG_IMC = 0x000D8; |
| const uint32_t REG_IAM = 0x000E0; |
| const uint32_t REG_RCTL = 0x00100; |
| const uint32_t REG_FCTTV = 0x00170; |
| const uint32_t REG_TIPG = 0x00410; |
| const uint32_t REG_AIFS = 0x00458; |
| const uint32_t REG_LEDCTL = 0x00e00; |
| const uint32_t REG_EICR = 0x01580; |
| const uint32_t REG_IVAR0 = 0x01700; |
| const uint32_t REG_FCRTL = 0x02160; |
| const uint32_t REG_FCRTH = 0x02168; |
| const uint32_t REG_RDBAL = 0x02800; |
| const uint32_t REG_RDBAH = 0x02804; |
| const uint32_t REG_RDLEN = 0x02808; |
| const uint32_t REG_SRRCTL = 0x0280C; |
| const uint32_t REG_RDH = 0x02810; |
| const uint32_t REG_RDT = 0x02818; |
| const uint32_t REG_RDTR = 0x02820; |
| const uint32_t REG_RXDCTL = 0x02828; |
| const uint32_t REG_RADV = 0x0282C; |
| const uint32_t REG_TCTL = 0x00400; |
| const uint32_t REG_TDBAL = 0x03800; |
| const uint32_t REG_TDBAH = 0x03804; |
| const uint32_t REG_TDLEN = 0x03808; |
| const uint32_t REG_TDH = 0x03810; |
| const uint32_t REG_TXDCA_CTL = 0x03814; |
| const uint32_t REG_TDT = 0x03818; |
| const uint32_t REG_TIDV = 0x03820; |
| const uint32_t REG_TXDCTL = 0x03828; |
| const uint32_t REG_TADV = 0x0382C; |
| const uint32_t REG_TDWBAL = 0x03838; |
| const uint32_t REG_TDWBAH = 0x0383C; |
| const uint32_t REG_CRCERRS = 0x04000; |
| const uint32_t REG_RXCSUM = 0x05000; |
| const uint32_t REG_RLPML = 0x05004; |
| const uint32_t REG_RFCTL = 0x05008; |
| const uint32_t REG_MTA = 0x05200; |
| const uint32_t REG_RAL = 0x05400; |
| const uint32_t REG_RAH = 0x05404; |
| const uint32_t REG_VFTA = 0x05600; |
| |
| const uint32_t REG_WUC = 0x05800; |
| const uint32_t REG_WUFC = 0x05808; |
| const uint32_t REG_WUS = 0x05810; |
| const uint32_t REG_MANC = 0x05820; |
| const uint32_t REG_SWSM = 0x05B50; |
| const uint32_t REG_FWSM = 0x05B54; |
| const uint32_t REG_SWFWSYNC = 0x05B5C; |
| |
| const uint8_t EEPROM_READ_OPCODE_SPI = 0x03; |
| const uint8_t EEPROM_RDSR_OPCODE_SPI = 0x05; |
| const uint8_t EEPROM_SIZE = 64; |
| const uint16_t EEPROM_CSUM = 0xBABA; |
| |
| const uint8_t VLAN_FILTER_TABLE_SIZE = 128; |
| const uint8_t RCV_ADDRESS_TABLE_SIZE = 24; |
| const uint8_t MULTICAST_TABLE_SIZE = 128; |
| const uint32_t STATS_REGS_SIZE = 0x228; |
| |
| |
| // Registers in that are accessed in the PHY |
| const uint8_t PHY_PSTATUS = 0x1; |
| const uint8_t PHY_PID = 0x2; |
| const uint8_t PHY_EPID = 0x3; |
| const uint8_t PHY_GSTATUS = 10; |
| const uint8_t PHY_EPSTATUS = 15; |
| const uint8_t PHY_AGC = 18; |
| |
| // Receive Descriptor Status Flags |
| const uint16_t RXDS_DYNINT = 0x800; |
| const uint16_t RXDS_UDPV = 0x400; |
| const uint16_t RXDS_CRCV = 0x100; |
| const uint16_t RXDS_PIF = 0x080; |
| const uint16_t RXDS_IPCS = 0x040; |
| const uint16_t RXDS_TCPCS = 0x020; |
| const uint16_t RXDS_UDPCS = 0x010; |
| const uint16_t RXDS_VP = 0x008; |
| const uint16_t RXDS_IXSM = 0x004; |
| const uint16_t RXDS_EOP = 0x002; |
| const uint16_t RXDS_DD = 0x001; |
| |
| // Receive Descriptor Error Flags |
| const uint8_t RXDE_RXE = 0x80; |
| const uint8_t RXDE_IPE = 0x40; |
| const uint8_t RXDE_TCPE = 0x20; |
| const uint8_t RXDE_SEQ = 0x04; |
| const uint8_t RXDE_SE = 0x02; |
| const uint8_t RXDE_CE = 0x01; |
| |
| // Receive Descriptor Extended Error Flags |
| const uint16_t RXDEE_HBO = 0x008; |
| const uint16_t RXDEE_CE = 0x010; |
| const uint16_t RXDEE_LE = 0x020; |
| const uint16_t RXDEE_PE = 0x080; |
| const uint16_t RXDEE_OSE = 0x100; |
| const uint16_t RXDEE_USE = 0x200; |
| const uint16_t RXDEE_TCPE = 0x400; |
| const uint16_t RXDEE_IPE = 0x800; |
| |
| |
| // Receive Descriptor Types |
| const uint8_t RXDT_LEGACY = 0x00; |
| const uint8_t RXDT_ADV_ONEBUF = 0x01; |
| const uint8_t RXDT_ADV_SPLIT_A = 0x05; |
| |
| // Receive Descriptor Packet Types |
| const uint16_t RXDP_IPV4 = 0x001; |
| const uint16_t RXDP_IPV4E = 0x002; |
| const uint16_t RXDP_IPV6 = 0x004; |
| const uint16_t RXDP_IPV6E = 0x008; |
| const uint16_t RXDP_TCP = 0x010; |
| const uint16_t RXDP_UDP = 0x020; |
| const uint16_t RXDP_SCTP = 0x040; |
| const uint16_t RXDP_NFS = 0x080; |
| |
| // Interrupt types |
| enum IntTypes |
| { |
| IT_NONE = 0x00000, //dummy value |
| IT_TXDW = 0x00001, |
| IT_TXQE = 0x00002, |
| IT_LSC = 0x00004, |
| IT_RXSEQ = 0x00008, |
| IT_RXDMT = 0x00010, |
| IT_RXO = 0x00040, |
| IT_RXT = 0x00080, |
| IT_MADC = 0x00200, |
| IT_RXCFG = 0x00400, |
| IT_GPI0 = 0x02000, |
| IT_GPI1 = 0x04000, |
| IT_TXDLOW = 0x08000, |
| IT_SRPD = 0x10000, |
| IT_ACK = 0x20000 |
| }; |
| |
| // Receive Descriptor struct |
| struct RxDesc |
| { |
| union |
| { |
| struct |
| { |
| Addr buf; |
| uint16_t len; |
| uint16_t csum; |
| uint8_t status; |
| uint8_t errors; |
| uint16_t vlan; |
| } legacy; |
| struct |
| { |
| Addr pkt; |
| Addr hdr; |
| } adv_read; |
| struct |
| { |
| uint16_t rss_type:4; |
| uint16_t pkt_type:12; |
| uint16_t __reserved1:5; |
| uint16_t header_len:10; |
| uint16_t sph:1; |
| union |
| { |
| struct |
| { |
| uint16_t id; |
| uint16_t csum; |
| }; |
| uint32_t rss_hash; |
| }; |
| uint32_t status:20; |
| uint32_t errors:12; |
| uint16_t pkt_len; |
| uint16_t vlan_tag; |
| } adv_wb ; |
| }; |
| }; |
| |
| struct TxDesc |
| { |
| uint64_t d1; |
| uint64_t d2; |
| }; |
| |
| GEM5_DEPRECATED_NAMESPACE(TxdOp, txd_op); |
| namespace txd_op |
| { |
| |
| const uint8_t TXD_CNXT = 0x0; |
| const uint8_t TXD_DATA = 0x1; |
| const uint8_t TXD_ADVCNXT = 0x2; |
| const uint8_t TXD_ADVDATA = 0x3; |
| |
| inline bool isLegacy(TxDesc *d) { return !bits(d->d2, 29); } |
| inline uint8_t getType(TxDesc *d) { return bits(d->d2, 23, 20); } |
| inline bool isType(TxDesc *d, uint8_t type) { return getType(d) == type; } |
| inline bool |
| isTypes(TxDesc *d, uint8_t t1, uint8_t t2) |
| { |
| return isType(d, t1) || isType(d, t2); |
| } |
| inline bool |
| isAdvDesc(TxDesc *d) |
| { |
| return !isLegacy(d) && isTypes(d, TXD_ADVDATA,TXD_ADVCNXT); |
| } |
| inline bool |
| isContext(TxDesc *d) |
| { |
| return !isLegacy(d) && isTypes(d,TXD_CNXT, TXD_ADVCNXT); |
| } |
| inline bool |
| isData(TxDesc *d) |
| { |
| return !isLegacy(d) && isTypes(d, TXD_DATA, TXD_ADVDATA); |
| } |
| |
| inline Addr |
| getBuf(TxDesc *d) |
| { |
| assert(isLegacy(d) || isData(d)); |
| return d->d1; |
| } |
| inline Addr |
| getLen(TxDesc *d) |
| { |
| if (isLegacy(d)) |
| return bits(d->d2, 15, 0); |
| else |
| return bits(d->d2, 19, 0); |
| } |
| inline void setDd(TxDesc *d) { replaceBits(d->d2, 35, 32, 1ULL); } |
| |
| inline bool |
| ide(TxDesc *d) |
| { |
| return bits(d->d2, 31, 31) && (getType(d) == TXD_DATA || isLegacy(d)); |
| } |
| inline bool |
| vle(TxDesc *d) |
| { |
| assert(isLegacy(d) || isData(d)); |
| return bits(d->d2, 30); |
| } |
| inline bool rs(TxDesc *d) { return bits(d->d2, 27); } |
| inline bool |
| ic(TxDesc *d) |
| { |
| assert(isLegacy(d) || isData(d)); |
| return isLegacy(d) && bits(d->d2, 26); |
| } |
| inline bool |
| tse(TxDesc *d) |
| { |
| if (isTypes(d, TXD_CNXT, TXD_DATA)) |
| return bits(d->d2, 26); |
| if (isType(d, TXD_ADVDATA)) |
| return bits(d->d2, 31); |
| return false; |
| } |
| |
| inline bool |
| ifcs(TxDesc *d) |
| { |
| assert(isLegacy(d) || isData(d)); |
| return bits(d->d2, 25); |
| } |
| inline bool |
| eop(TxDesc *d) |
| { |
| assert(isLegacy(d) || isData(d)); |
| return bits(d->d2, 24); |
| } |
| inline bool |
| ip(TxDesc *d) |
| { |
| assert(isContext(d)); |
| return bits(d->d2, 25); |
| } |
| inline bool |
| tcp(TxDesc *d) |
| { |
| assert(isContext(d)); |
| return bits(d->d2, 24); |
| } |
| |
| inline uint8_t |
| getCso(TxDesc *d) |
| { |
| assert(isLegacy(d)); |
| return bits(d->d2, 23, 16); |
| } |
| inline uint8_t |
| getCss(TxDesc *d) |
| { |
| assert(isLegacy(d)); |
| return bits(d->d2, 47, 40); |
| } |
| |
| inline bool ixsm(TxDesc *d) { return isData(d) && bits(d->d2, 40, 40); } |
| inline bool txsm(TxDesc *d) { return isData(d) && bits(d->d2, 41, 41); } |
| |
| inline int |
| tucse(TxDesc *d) |
| { |
| assert(isContext(d)); |
| return bits(d->d1, 63, 48); |
| } |
| inline int |
| tucso(TxDesc *d) |
| { |
| assert(isContext(d)); |
| return bits(d->d1, 47, 40); |
| } |
| inline int |
| tucss(TxDesc *d) |
| { |
| assert(isContext(d)); |
| return bits(d->d1, 39, 32); |
| } |
| inline int |
| ipcse(TxDesc *d) |
| { |
| assert(isContext(d)); |
| return bits(d->d1, 31, 16); |
| } |
| inline int |
| ipcso(TxDesc *d) |
| { |
| assert(isContext(d)); |
| return bits(d->d1, 15, 8); |
| } |
| inline int |
| ipcss(TxDesc *d) |
| { |
| assert(isContext(d)); |
| return bits(d->d1, 7, 0); |
| } |
| inline int |
| mss(TxDesc *d) |
| { |
| assert(isContext(d)); |
| return bits(d->d2, 63, 48); |
| } |
| inline int |
| hdrlen(TxDesc *d) |
| { |
| assert(isContext(d)); |
| if (!isAdvDesc(d)) |
| return bits(d->d2, 47, 40); |
| return bits(d->d2, 47, 40) + bits(d->d1, 8, 0) + bits(d->d1, 15, 9); |
| } |
| |
| inline int |
| getTsoLen(TxDesc *d) |
| { |
| assert(isType(d, TXD_ADVDATA)); |
| return bits(d->d2, 63, 46); |
| } |
| inline int |
| utcmd(TxDesc *d) |
| { |
| assert(isContext(d)); |
| return bits(d->d2, 24, 31); |
| } |
| |
| } // namespace txd_op |
| |
| |
| #define ADD_FIELD32(NAME, OFFSET, BITS) \ |
| inline uint32_t NAME() { return bits(_data, OFFSET+BITS-1, OFFSET); } \ |
| inline void NAME(uint32_t d) { replaceBits(_data, OFFSET+BITS-1, OFFSET,d); } |
| |
| #define ADD_FIELD64(NAME, OFFSET, BITS) \ |
| inline uint64_t NAME() { return bits(_data, OFFSET+BITS-1, OFFSET); } \ |
| inline void NAME(uint64_t d) { replaceBits(_data, OFFSET+BITS-1, OFFSET,d); } |
| |
| struct Regs : public Serializable |
| { |
| template<class T> |
| struct Reg |
| { |
| T _data; |
| T operator()() { return _data; } |
| const Reg<T> &operator=(T d) { _data = d; return *this;} |
| bool operator==(T d) { return d == _data; } |
| void operator()(T d) { _data = d; } |
| Reg() { _data = 0; } |
| void serialize(CheckpointOut &cp) const |
| { |
| SERIALIZE_SCALAR(_data); |
| } |
| void unserialize(CheckpointIn &cp) |
| { |
| UNSERIALIZE_SCALAR(_data); |
| } |
| }; |
| |
| struct CTRL : public Reg<uint32_t> |
| { |
| // 0x0000 CTRL Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(fd, 0, 1); // full duplex |
| ADD_FIELD32(bem, 1, 1); // big endian mode |
| ADD_FIELD32(pcipr, 2, 1); // PCI priority |
| ADD_FIELD32(lrst, 3, 1); // link reset |
| ADD_FIELD32(tme, 4, 1); // test mode enable |
| ADD_FIELD32(asde, 5, 1); // Auto-speed detection |
| ADD_FIELD32(slu, 6, 1); // Set link up |
| ADD_FIELD32(ilos, 7, 1); // invert los-of-signal |
| ADD_FIELD32(speed, 8, 2); // speed selection bits |
| ADD_FIELD32(be32, 10, 1); // big endian mode 32 |
| ADD_FIELD32(frcspd, 11, 1); // force speed |
| ADD_FIELD32(frcdpx, 12, 1); // force duplex |
| ADD_FIELD32(duden, 13, 1); // dock/undock enable |
| ADD_FIELD32(dudpol, 14, 1); // dock/undock polarity |
| ADD_FIELD32(fphyrst, 15, 1); // force phy reset |
| ADD_FIELD32(extlen, 16, 1); // external link status enable |
| ADD_FIELD32(rsvd, 17, 1); // reserved |
| ADD_FIELD32(sdp0d, 18, 1); // software controlled pin data |
| ADD_FIELD32(sdp1d, 19, 1); // software controlled pin data |
| ADD_FIELD32(sdp2d, 20, 1); // software controlled pin data |
| ADD_FIELD32(sdp3d, 21, 1); // software controlled pin data |
| ADD_FIELD32(sdp0i, 22, 1); // software controlled pin dir |
| ADD_FIELD32(sdp1i, 23, 1); // software controlled pin dir |
| ADD_FIELD32(sdp2i, 24, 1); // software controlled pin dir |
| ADD_FIELD32(sdp3i, 25, 1); // software controlled pin dir |
| ADD_FIELD32(rst, 26, 1); // reset |
| ADD_FIELD32(rfce, 27, 1); // receive flow control enable |
| ADD_FIELD32(tfce, 28, 1); // transmit flow control enable |
| ADD_FIELD32(rte, 29, 1); // routing tag enable |
| ADD_FIELD32(vme, 30, 1); // vlan enable |
| ADD_FIELD32(phyrst, 31, 1); // phy reset |
| }; |
| CTRL ctrl; |
| |
| struct STATUS : public Reg<uint32_t> |
| { |
| // 0x0008 STATUS Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(fd, 0, 1); // full duplex |
| ADD_FIELD32(lu, 1, 1); // link up |
| ADD_FIELD32(func, 2, 2); // function id |
| ADD_FIELD32(txoff, 4, 1); // transmission paused |
| ADD_FIELD32(tbimode, 5, 1); // tbi mode |
| ADD_FIELD32(speed, 6, 2); // link speed |
| ADD_FIELD32(asdv, 8, 2); // auto speed detection value |
| ADD_FIELD32(mtxckok, 10, 1); // mtx clock running ok |
| ADD_FIELD32(pci66, 11, 1); // In 66Mhz pci slot |
| ADD_FIELD32(bus64, 12, 1); // in 64 bit slot |
| ADD_FIELD32(pcix, 13, 1); // Pci mode |
| ADD_FIELD32(pcixspd, 14, 2); // pci x speed |
| }; |
| STATUS sts; |
| |
| struct EECD : public Reg<uint32_t> |
| { |
| // 0x0010 EECD Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(sk, 0, 1); // clack input to the eeprom |
| ADD_FIELD32(cs, 1, 1); // chip select to eeprom |
| ADD_FIELD32(din, 2, 1); // data input to eeprom |
| ADD_FIELD32(dout, 3, 1); // data output bit |
| ADD_FIELD32(fwe, 4, 2); // flash write enable |
| ADD_FIELD32(ee_req, 6, 1); // request eeprom access |
| ADD_FIELD32(ee_gnt, 7, 1); // grant eeprom access |
| ADD_FIELD32(ee_pres, 8, 1); // eeprom present |
| ADD_FIELD32(ee_size, 9, 1); // eeprom size |
| ADD_FIELD32(ee_sz1, 10, 1); // eeprom size |
| ADD_FIELD32(rsvd, 11, 2); // reserved |
| ADD_FIELD32(ee_type, 13, 1); // type of eeprom |
| } ; |
| EECD eecd; |
| |
| struct EERD : public Reg<uint32_t> |
| { |
| // 0x0014 EERD Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(start, 0, 1); // start read |
| ADD_FIELD32(done, 1, 1); // done read |
| ADD_FIELD32(addr, 2, 14); // address |
| ADD_FIELD32(data, 16, 16); // data |
| }; |
| EERD eerd; |
| |
| struct CTRL_EXT : public Reg<uint32_t> |
| { |
| // 0x0018 CTRL_EXT Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(gpi_en, 0, 4); // enable interrupts from gpio |
| ADD_FIELD32(phyint, 5, 1); // reads the phy internal int status |
| ADD_FIELD32(sdp2_data, 6, 1); // data from gpio sdp |
| ADD_FIELD32(spd3_data, 7, 1); // data frmo gpio sdp |
| ADD_FIELD32(spd2_iodir, 10, 1); // direction of sdp2 |
| ADD_FIELD32(spd3_iodir, 11, 1); // direction of sdp2 |
| ADD_FIELD32(asdchk, 12, 1); // initiate auto-speed-detection |
| ADD_FIELD32(eerst, 13, 1); // reset the eeprom |
| ADD_FIELD32(spd_byps, 15, 1); // bypass speed select |
| ADD_FIELD32(ro_dis, 17, 1); // disable relaxed memory ordering |
| ADD_FIELD32(vreg, 21, 1); // power down the voltage regulator |
| ADD_FIELD32(link_mode, 22, 2); // interface to talk to the link |
| ADD_FIELD32(iame, 27, 1); // interrupt acknowledge auto-mask ?? |
| ADD_FIELD32(drv_loaded, 28, 1); // driver is loaded and incharge of |
| // device |
| ADD_FIELD32(timer_clr, 29, 1); // clear interrupt timers after IMS |
| // clear ?? |
| }; |
| CTRL_EXT ctrl_ext; |
| |
| struct MDIC : public Reg<uint32_t> |
| { |
| // 0x0020 MDIC Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(data, 0, 16); // data |
| ADD_FIELD32(regadd, 16, 5); // register address |
| ADD_FIELD32(phyadd, 21, 5); // phy addresses |
| ADD_FIELD32(op, 26, 2); // opcode |
| ADD_FIELD32(r, 28, 1); // ready |
| ADD_FIELD32(i, 29, 1); // interrupt |
| ADD_FIELD32(e, 30, 1); // error |
| }; |
| MDIC mdic; |
| |
| struct ICR : public Reg<uint32_t> |
| { |
| // 0x00C0 ICR Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(txdw, 0, 1) // tx descr witten back |
| ADD_FIELD32(txqe, 1, 1) // tx queue empty |
| ADD_FIELD32(lsc, 2, 1) // link status change |
| ADD_FIELD32(rxseq, 3, 1) // rcv sequence error |
| ADD_FIELD32(rxdmt0, 4, 1) // rcv descriptor min thresh |
| ADD_FIELD32(rsvd1, 5, 1) // reserved |
| ADD_FIELD32(rxo, 6, 1) // receive overrunn |
| ADD_FIELD32(rxt0, 7, 1) // receiver timer interrupt |
| ADD_FIELD32(mdac, 9, 1) // mdi/o access complete |
| ADD_FIELD32(rxcfg, 10, 1) // recv /c/ ordered sets |
| ADD_FIELD32(phyint, 12, 1) // phy interrupt |
| ADD_FIELD32(gpi1, 13, 1) // gpi int 1 |
| ADD_FIELD32(gpi2, 14, 1) // gpi int 2 |
| ADD_FIELD32(txdlow, 15, 1) // transmit desc low thresh |
| ADD_FIELD32(srpd, 16, 1) // small receive packet detected |
| ADD_FIELD32(ack, 17, 1); // receive ack frame |
| ADD_FIELD32(int_assert, 31, 1); // interrupt caused a system interrupt |
| }; |
| ICR icr; |
| |
| uint32_t imr; // register that contains the current interrupt mask |
| |
| struct ITR : public Reg<uint32_t> |
| { |
| // 0x00C4 ITR Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(interval, 0, 16); // minimum inter-interrutp inteval |
| // specified in 256ns interrupts |
| }; |
| ITR itr; |
| |
| // When CTRL_EXT.IAME and the ICR.INT_ASSERT is 1 an ICR read or write |
| // causes the IAM register contents to be written into the IMC |
| // automatically clearing all interrupts that have a bit in the IAM set |
| uint32_t iam; |
| |
| struct RCTL : public Reg<uint32_t> |
| { |
| // 0x0100 RCTL Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(rst, 0, 1); // Reset |
| ADD_FIELD32(en, 1, 1); // Enable |
| ADD_FIELD32(sbp, 2, 1); // Store bad packets |
| ADD_FIELD32(upe, 3, 1); // Unicast Promiscuous enabled |
| ADD_FIELD32(mpe, 4, 1); // Multicast promiscuous enabled |
| ADD_FIELD32(lpe, 5, 1); // long packet reception enabled |
| ADD_FIELD32(lbm, 6, 2); // |
| ADD_FIELD32(rdmts, 8, 2); // |
| ADD_FIELD32(mo, 12, 2); // |
| ADD_FIELD32(mdr, 14, 1); // |
| ADD_FIELD32(bam, 15, 1); // |
| ADD_FIELD32(bsize, 16, 2); // |
| ADD_FIELD32(vfe, 18, 1); // |
| ADD_FIELD32(cfien, 19, 1); // |
| ADD_FIELD32(cfi, 20, 1); // |
| ADD_FIELD32(dpf, 22, 1); // discard pause frames |
| ADD_FIELD32(pmcf, 23, 1); // pass mac control frames |
| ADD_FIELD32(bsex, 25, 1); // buffer size extension |
| ADD_FIELD32(secrc, 26, 1); // strip ethernet crc from incoming packet |
| unsigned descSize() |
| { |
| switch(bsize()) { |
| case 0: return bsex() == 0 ? 2048 : 0; |
| case 1: return bsex() == 0 ? 1024 : 16384; |
| case 2: return bsex() == 0 ? 512 : 8192; |
| case 3: return bsex() == 0 ? 256 : 4096; |
| default: |
| return 0; |
| } |
| } |
| }; |
| RCTL rctl; |
| |
| struct FCTTV : public Reg<uint32_t> |
| { |
| // 0x0170 FCTTV |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(ttv, 0, 16); // Transmit Timer Value |
| }; |
| FCTTV fcttv; |
| |
| struct TCTL : public Reg<uint32_t> |
| { |
| // 0x0400 TCTL Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(rst, 0, 1); // Reset |
| ADD_FIELD32(en, 1, 1); // Enable |
| ADD_FIELD32(bce, 2, 1); // busy check enable |
| ADD_FIELD32(psp, 3, 1); // pad short packets |
| ADD_FIELD32(ct, 4, 8); // collision threshold |
| ADD_FIELD32(cold, 12, 10); // collision distance |
| ADD_FIELD32(swxoff, 22, 1); // software xoff transmission |
| ADD_FIELD32(pbe, 23, 1); // packet burst enable |
| ADD_FIELD32(rtlc, 24, 1); // retransmit late collisions |
| ADD_FIELD32(nrtu, 25, 1); // on underrun no TX |
| ADD_FIELD32(mulr, 26, 1); // multiple request |
| }; |
| TCTL tctl; |
| |
| struct PBA : public Reg<uint32_t> |
| { |
| // 0x1000 PBA Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(rxa, 0, 16); |
| ADD_FIELD32(txa, 16, 16); |
| }; |
| PBA pba; |
| |
| struct FCRTL : public Reg<uint32_t> |
| { |
| // 0x2160 FCRTL Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(rtl, 3, 28); // make this bigger than the spec so we can |
| // have a larger buffer |
| ADD_FIELD32(xone, 31, 1); |
| }; |
| FCRTL fcrtl; |
| |
| struct FCRTH : public Reg<uint32_t> |
| { |
| // 0x2168 FCRTL Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(rth, 3, 13); // make this bigger than the spec so we can |
| // have a larger buffer |
| ADD_FIELD32(xfce, 31, 1); |
| }; |
| FCRTH fcrth; |
| |
| struct RDBA : public Reg<uint64_t> |
| { |
| // 0x2800 RDBA Register |
| using Reg<uint64_t>::operator=; |
| ADD_FIELD64(rdbal, 0, 32); // base address of rx descriptor ring |
| ADD_FIELD64(rdbah, 32, 32); // base address of rx descriptor ring |
| }; |
| RDBA rdba; |
| |
| struct RDLEN : public Reg<uint32_t> |
| { |
| // 0x2808 RDLEN Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(len, 7, 13); // number of bytes in the descriptor buffer |
| }; |
| RDLEN rdlen; |
| |
| struct SRRCTL : public Reg<uint32_t> |
| { |
| // 0x280C SRRCTL Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(pktlen, 0, 8); |
| ADD_FIELD32(hdrlen, 8, 8); // guess based on header, not documented |
| ADD_FIELD32(desctype, 25, 3); // type of descriptor 000 legacy, |
| // 001 adv, 101 hdr split |
| unsigned bufLen() { return pktlen() << 10; } |
| unsigned hdrLen() { return hdrlen() << 6; } |
| }; |
| SRRCTL srrctl; |
| |
| struct RDH : public Reg<uint32_t> |
| { |
| // 0x2810 RDH Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(rdh, 0, 16); // head of the descriptor ring |
| }; |
| RDH rdh; |
| |
| struct RDT : public Reg<uint32_t> |
| { |
| // 0x2818 RDT Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(rdt, 0, 16); // tail of the descriptor ring |
| }; |
| RDT rdt; |
| |
| struct RDTR : public Reg<uint32_t> |
| { |
| // 0x2820 RDTR Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(delay, 0, 16); // receive delay timer |
| ADD_FIELD32(fpd, 31, 1); // flush partial descriptor block ?? |
| }; |
| RDTR rdtr; |
| |
| struct RXDCTL : public Reg<uint32_t> |
| { |
| // 0x2828 RXDCTL Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(pthresh, 0, 6); // prefetch threshold, less that this |
| // consider prefetch |
| ADD_FIELD32(hthresh, 8, 6); // number of descriptors in host mem to |
| // consider prefetch |
| ADD_FIELD32(wthresh, 16, 6); // writeback threshold |
| ADD_FIELD32(gran, 24, 1); // granularity 0 = desc, 1 = cacheline |
| }; |
| RXDCTL rxdctl; |
| |
| struct RADV : public Reg<uint32_t> |
| { |
| // 0x282C RADV Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(idv, 0, 16); // absolute interrupt delay |
| }; |
| RADV radv; |
| |
| struct RSRPD : public Reg<uint32_t> |
| { |
| // 0x2C00 RSRPD Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(idv, 0, 12); // size to interrutp on small packets |
| }; |
| RSRPD rsrpd; |
| |
| struct TDBA : public Reg<uint64_t> |
| { |
| // 0x3800 TDBAL Register |
| using Reg<uint64_t>::operator=; |
| ADD_FIELD64(tdbal, 0, 32); // base address of transmit descriptor ring |
| ADD_FIELD64(tdbah, 32, 32); // base address of transmit descriptor ring |
| }; |
| TDBA tdba; |
| |
| struct TDLEN : public Reg<uint32_t> |
| { |
| // 0x3808 TDLEN Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(len, 7, 13); // number of bytes in the descriptor buffer |
| }; |
| TDLEN tdlen; |
| |
| struct TDH : public Reg<uint32_t> |
| { |
| // 0x3810 TDH Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(tdh, 0, 16); // head of the descriptor ring |
| }; |
| TDH tdh; |
| |
| struct TXDCA_CTL : public Reg<uint32_t> |
| { |
| // 0x3814 TXDCA_CTL Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(cpu_mask, 0, 5); |
| ADD_FIELD32(enabled, 5, 1); |
| ADD_FIELD32(relax_ordering, 6, 1); |
| }; |
| TXDCA_CTL txdca_ctl; |
| |
| struct TDT : public Reg<uint32_t> |
| { |
| // 0x3818 TDT Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(tdt, 0, 16); // tail of the descriptor ring |
| }; |
| TDT tdt; |
| |
| struct TIDV : public Reg<uint32_t> |
| { |
| // 0x3820 TIDV Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(idv, 0, 16); // interrupt delay |
| }; |
| TIDV tidv; |
| |
| struct TXDCTL : public Reg<uint32_t> |
| { |
| // 0x3828 TXDCTL Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(pthresh, 0, 6); // if number of descriptors control has is |
| // below this number, a prefetch is |
| //considered |
| ADD_FIELD32(hthresh, 8, 8); // number of valid descriptors is host |
| // memory before a prefetch is considered |
| ADD_FIELD32(wthresh, 16, 6);// number of descriptors to keep until |
| // writeback is considered |
| ADD_FIELD32(gran, 24, 1); // granulatiry of above values |
| // (0 = cacheline, 1 == desscriptor) |
| ADD_FIELD32(lwthresh, 25, 7); // xmit descriptor low thresh, interrupt |
| // below this level |
| }; |
| TXDCTL txdctl; |
| |
| struct TADV : public Reg<uint32_t> |
| { |
| // 0x382C TADV Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(idv, 0, 16); // absolute interrupt delay |
| }; |
| TADV tadv; |
| uint64_t tdwba; |
| |
| struct RXCSUM : public Reg<uint32_t> |
| { |
| // 0x5000 RXCSUM Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(pcss, 0, 8); |
| ADD_FIELD32(ipofld, 8, 1); |
| ADD_FIELD32(tuofld, 9, 1); |
| ADD_FIELD32(pcsd, 13, 1); |
| }; |
| RXCSUM rxcsum; |
| |
| uint32_t rlpml; // 0x5004 RLPML probably maximum accepted packet size |
| |
| struct RFCTL : public Reg<uint32_t> |
| { |
| // 0x5008 RFCTL Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(iscsi_dis, 0, 1); |
| ADD_FIELD32(iscsi_dwc, 1, 5); |
| ADD_FIELD32(nfsw_dis, 6, 1); |
| ADD_FIELD32(nfsr_dis, 7, 1); |
| ADD_FIELD32(nfs_ver, 8, 2); |
| ADD_FIELD32(ipv6_dis, 10, 1); |
| ADD_FIELD32(ipv6xsum_dis, 11, 1); |
| ADD_FIELD32(ackdis, 13, 1); |
| ADD_FIELD32(ipfrsp_dis, 14, 1); |
| ADD_FIELD32(exsten, 15, 1); |
| }; |
| RFCTL rfctl; |
| |
| struct MANC : public Reg<uint32_t> |
| { |
| // 0x5820 MANC Register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(smbus, 0, 1); // SMBus enabled ##### |
| ADD_FIELD32(asf, 1, 1); // ASF enabled ##### |
| ADD_FIELD32(ronforce, 2, 1); // reset of force |
| ADD_FIELD32(rsvd, 3, 5); // reserved |
| ADD_FIELD32(rmcp1, 8, 1); // rcmp1 filtering |
| ADD_FIELD32(rmcp2, 9, 1); // rcmp2 filtering |
| ADD_FIELD32(ipv4, 10, 1); // enable ipv4 |
| ADD_FIELD32(ipv6, 11, 1); // enable ipv6 |
| ADD_FIELD32(snap, 12, 1); // accept snap |
| ADD_FIELD32(arp, 13, 1); // filter arp ##### |
| ADD_FIELD32(neighbor, 14, 1); // neighbor discovery |
| ADD_FIELD32(arp_resp, 15, 1); // arp response |
| ADD_FIELD32(tcorst, 16, 1); // tco reset happened |
| ADD_FIELD32(rcvtco, 17, 1); // receive tco enabled ###### |
| ADD_FIELD32(blkphyrst, 18, 1);// block phy resets ######## |
| ADD_FIELD32(rcvall, 19, 1); // receive all |
| ADD_FIELD32(macaddrfltr, 20, 1); // mac address filtering ###### |
| ADD_FIELD32(mng2host, 21, 1); // mng2 host packets ####### |
| ADD_FIELD32(ipaddrfltr, 22, 1); // ip address filtering |
| ADD_FIELD32(xsumfilter, 23, 1); // checksum filtering |
| ADD_FIELD32(brfilter, 24, 1); // broadcast filtering |
| ADD_FIELD32(smbreq, 25, 1); // smb request |
| ADD_FIELD32(smbgnt, 26, 1); // smb grant |
| ADD_FIELD32(smbclkin, 27, 1); // smbclkin |
| ADD_FIELD32(smbdatain, 28, 1); // smbdatain |
| ADD_FIELD32(smbdataout, 29, 1); // smb data out |
| ADD_FIELD32(smbclkout, 30, 1); // smb clock out |
| }; |
| MANC manc; |
| |
| struct SWSM : public Reg<uint32_t> |
| { |
| // 0x5B50 SWSM register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(smbi, 0, 1); // Semaphone bit |
| ADD_FIELD32(swesmbi, 1, 1); // Software eeporm semaphore |
| ADD_FIELD32(wmng, 2, 1); // Wake MNG clock |
| ADD_FIELD32(reserved, 3, 29); |
| }; |
| SWSM swsm; |
| |
| struct FWSM : public Reg<uint32_t> |
| { |
| // 0x5B54 FWSM register |
| using Reg<uint32_t>::operator=; |
| ADD_FIELD32(eep_fw_semaphore, 0, 1); |
| ADD_FIELD32(fw_mode, 1, 3); |
| ADD_FIELD32(ide, 4, 1); |
| ADD_FIELD32(sol, 5, 1); |
| ADD_FIELD32(eep_roload, 6, 1); |
| ADD_FIELD32(reserved, 7, 8); |
| ADD_FIELD32(fw_val_bit, 15, 1); |
| ADD_FIELD32(reset_cnt, 16, 3); |
| ADD_FIELD32(ext_err_ind, 19, 6); |
| ADD_FIELD32(reserved2, 25, 7); |
| }; |
| FWSM fwsm; |
| |
| uint32_t sw_fw_sync; |
| |
| void serialize(CheckpointOut &cp) const override |
| { |
| paramOut(cp, "ctrl", ctrl._data); |
| paramOut(cp, "sts", sts._data); |
| paramOut(cp, "eecd", eecd._data); |
| paramOut(cp, "eerd", eerd._data); |
| paramOut(cp, "ctrl_ext", ctrl_ext._data); |
| paramOut(cp, "mdic", mdic._data); |
| paramOut(cp, "icr", icr._data); |
| SERIALIZE_SCALAR(imr); |
| paramOut(cp, "itr", itr._data); |
| SERIALIZE_SCALAR(iam); |
| paramOut(cp, "rctl", rctl._data); |
| paramOut(cp, "fcttv", fcttv._data); |
| paramOut(cp, "tctl", tctl._data); |
| paramOut(cp, "pba", pba._data); |
| paramOut(cp, "fcrtl", fcrtl._data); |
| paramOut(cp, "fcrth", fcrth._data); |
| paramOut(cp, "rdba", rdba._data); |
| paramOut(cp, "rdlen", rdlen._data); |
| paramOut(cp, "srrctl", srrctl._data); |
| paramOut(cp, "rdh", rdh._data); |
| paramOut(cp, "rdt", rdt._data); |
| paramOut(cp, "rdtr", rdtr._data); |
| paramOut(cp, "rxdctl", rxdctl._data); |
| paramOut(cp, "radv", radv._data); |
| paramOut(cp, "rsrpd", rsrpd._data); |
| paramOut(cp, "tdba", tdba._data); |
| paramOut(cp, "tdlen", tdlen._data); |
| paramOut(cp, "tdh", tdh._data); |
| paramOut(cp, "txdca_ctl", txdca_ctl._data); |
| paramOut(cp, "tdt", tdt._data); |
| paramOut(cp, "tidv", tidv._data); |
| paramOut(cp, "txdctl", txdctl._data); |
| paramOut(cp, "tadv", tadv._data); |
| //paramOut(cp, "tdwba", tdwba._data); |
| SERIALIZE_SCALAR(tdwba); |
| paramOut(cp, "rxcsum", rxcsum._data); |
| SERIALIZE_SCALAR(rlpml); |
| paramOut(cp, "rfctl", rfctl._data); |
| paramOut(cp, "manc", manc._data); |
| paramOut(cp, "swsm", swsm._data); |
| paramOut(cp, "fwsm", fwsm._data); |
| SERIALIZE_SCALAR(sw_fw_sync); |
| } |
| |
| void unserialize(CheckpointIn &cp) override |
| { |
| paramIn(cp, "ctrl", ctrl._data); |
| paramIn(cp, "sts", sts._data); |
| paramIn(cp, "eecd", eecd._data); |
| paramIn(cp, "eerd", eerd._data); |
| paramIn(cp, "ctrl_ext", ctrl_ext._data); |
| paramIn(cp, "mdic", mdic._data); |
| paramIn(cp, "icr", icr._data); |
| UNSERIALIZE_SCALAR(imr); |
| paramIn(cp, "itr", itr._data); |
| UNSERIALIZE_SCALAR(iam); |
| paramIn(cp, "rctl", rctl._data); |
| paramIn(cp, "fcttv", fcttv._data); |
| paramIn(cp, "tctl", tctl._data); |
| paramIn(cp, "pba", pba._data); |
| paramIn(cp, "fcrtl", fcrtl._data); |
| paramIn(cp, "fcrth", fcrth._data); |
| paramIn(cp, "rdba", rdba._data); |
| paramIn(cp, "rdlen", rdlen._data); |
| paramIn(cp, "srrctl", srrctl._data); |
| paramIn(cp, "rdh", rdh._data); |
| paramIn(cp, "rdt", rdt._data); |
| paramIn(cp, "rdtr", rdtr._data); |
| paramIn(cp, "rxdctl", rxdctl._data); |
| paramIn(cp, "radv", radv._data); |
| paramIn(cp, "rsrpd", rsrpd._data); |
| paramIn(cp, "tdba", tdba._data); |
| paramIn(cp, "tdlen", tdlen._data); |
| paramIn(cp, "tdh", tdh._data); |
| paramIn(cp, "txdca_ctl", txdca_ctl._data); |
| paramIn(cp, "tdt", tdt._data); |
| paramIn(cp, "tidv", tidv._data); |
| paramIn(cp, "txdctl", txdctl._data); |
| paramIn(cp, "tadv", tadv._data); |
| UNSERIALIZE_SCALAR(tdwba); |
| //paramIn(cp, "tdwba", tdwba._data); |
| paramIn(cp, "rxcsum", rxcsum._data); |
| UNSERIALIZE_SCALAR(rlpml); |
| paramIn(cp, "rfctl", rfctl._data); |
| paramIn(cp, "manc", manc._data); |
| paramIn(cp, "swsm", swsm._data); |
| paramIn(cp, "fwsm", fwsm._data); |
| UNSERIALIZE_SCALAR(sw_fw_sync); |
| } |
| }; |
| |
| } // namespace igbreg |
| } // namespace gem5 |