Annotation of nono/vm/lance.h, revision 1.1.1.16

1.1       root        1: //
                      2: // nono
1.1.1.3   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.9   root        7: //
                      8: // Lance (AM7990)
                      9: //
                     10: 
1.1       root       11: #pragma once
                     12: 
                     13: #include "ethernet.h"
1.1.1.9   root       14: #include "hostnet.h"
                     15: #include "message.h"
1.1       root       16: 
1.1.1.10  root       17: class InterruptDevice;
                     18: class SubRAMDevice;
                     19: 
1.1       root       20: struct AM7990
                     21: {
1.1.1.13  root       22:        uint rap;                       // レジスタアドレス (0..3)
1.1       root       23: 
                     24:        // CSR0
                     25:        static const uint16 CSR0_ERR    = 0x8000;
                     26:        static const uint16 CSR0_BABL   = 0x4000;
                     27:        static const uint16 CSR0_CERR   = 0x2000;
                     28:        static const uint16 CSR0_MISS   = 0x1000;
                     29:        static const uint16 CSR0_MERR   = 0x0800;
                     30:        static const uint16 CSR0_RINT   = 0x0400;
                     31:        static const uint16 CSR0_TINT   = 0x0200;
                     32:        static const uint16 CSR0_IDON   = 0x0100;
                     33:        static const uint16 CSR0_INTR   = 0x0080;
                     34:        static const uint16 CSR0_INEA   = 0x0040;
                     35:        static const uint16 CSR0_RXON   = 0x0020;
                     36:        static const uint16 CSR0_TXON   = 0x0010;
                     37:        static const uint16 CSR0_TDMD   = 0x0008;
                     38:        static const uint16 CSR0_STOP   = 0x0004;
                     39:        static const uint16 CSR0_STRT   = 0x0002;
                     40:        static const uint16 CSR0_INIT   = 0x0001;
                     41:        // CSR0_ERR はこれらの和
                     42:        static const uint16 CSR0_ERR_BITS =
                     43:                CSR0_BABL |
                     44:                CSR0_CERR |
                     45:                CSR0_MISS |
                     46:                CSR0_MERR;
                     47:        // CSR0_INTR はこれらの和
                     48:        static const uint16 CSR0_INTR_BITS =
                     49:                CSR0_BABL |
                     50:                CSR0_MISS |
                     51:                CSR0_MERR |
                     52:                CSR0_RINT |
                     53:                CSR0_TINT |
                     54:                CSR0_IDON;
                     55: 
                     56:        // CSR1
                     57:        static const uint16 CSR1_MASK   = 0xfffe;
                     58:        static const uint16 IADR_L_MASK = 0xfffe;
                     59: 
                     60:        // CSR2
                     61:        static const uint16 CSR2_MASK   = 0x00ff;
                     62:        static const uint16 IADR_H_MASK = 0x00ff;
                     63: 
                     64:        // CSR3
                     65:        static const uint16 CSR3_MASK   = 0x0007;
                     66:        static const uint16 CSR3_BSWP   = 0x0004;
                     67:        static const uint16 CSR3_ACON   = 0x0002;
                     68:        static const uint16 CSR3_BCON   = 0x0001;
                     69: 
                     70:        // IBMODE
                     71:        static const uint16 IBMODE_PROM = 0x8000;
                     72:        static const uint16 IBMODE_INTL = 0x0040;
                     73:        static const uint16 IBMODE_DRTY = 0x0020;
                     74:        static const uint16 IBMODE_COLL = 0x0010;
                     75:        static const uint16 IBMODE_DTCR = 0x0008;
                     76:        static const uint16 IBMODE_LOOP = 0x0004;
                     77:        static const uint16 IBMODE_DTX  = 0x0002;
                     78:        static const uint16 IBMODE_DRX  = 0x0001;
                     79:        // RMD1
                     80:        static const uint16 RMD1_OWN    = 0x8000;
                     81:        static const uint16 RMD1_ERR    = 0x4000;
                     82:        static const uint16 RMD1_FRAM   = 0x2000;
                     83:        static const uint16 RMD1_OFLO   = 0x1000;
                     84:        static const uint16 RMD1_CRC    = 0x0800;
                     85:        static const uint16 RMD1_BUFF   = 0x0400;
                     86:        static const uint16 RMD1_STP    = 0x0200;
                     87:        static const uint16 RMD1_ENP    = 0x0100;
                     88:        // TMD1
                     89:        static const uint16 TMD1_OWN    = 0x8000;
                     90:        static const uint16 TMD1_ERR    = 0x4000;
                     91:        static const uint16 TMD1_resv   = 0x2000;
                     92:        static const uint16 TMD1_MORE   = 0x1000;
                     93:        static const uint16 TMD1_ONE    = 0x0800;
                     94:        static const uint16 TMD1_DEF    = 0x0400;
                     95:        static const uint16 TMD1_STP    = 0x0200;
                     96:        static const uint16 TMD1_ENP    = 0x0100;
                     97:        // TMD3
                     98:        static const uint16 TMD3_BUFF   = 0x8000;
                     99:        static const uint16 TMD3_UFLO   = 0x4000;
                    100:        static const uint16 TMD3_resv   = 0x2000;
                    101:        static const uint16 TMD3_LCOL   = 0x1000;
                    102:        static const uint16 TMD3_LCAR   = 0x0800;
                    103:        static const uint16 TMD3_BTRY   = 0x0400;
                    104: 
                    105:        // CSR0 ビットごとに処理方法が異なる。
                    106:        //
                    107:        // b15 ERR :    値は計算で求める。csr0 の該当ビットは常時クリア。
                    108:        // b14 BABL:    csr0 で保持。
                    109:        // b13 CERR:    csr0 で保持。
                    110:        // b12 MISS:    csr0 で保持。
                    111:        // b11 ERR :    csr0 で保持。
                    112:        // b10 INT :    csr0 で保持。
                    113:        // b9  TINT:    csr0 で保持。
                    114:        // b8  IDON:    csr0 で保持。
                    115:        // b7  INTR:    値は計算で求める。csr0 の該当ビットは常時クリア。
                    116:        // b6  INEA:    csr0 で保持。
                    117:        // b5  RXON:    csr0 で保持。
                    118:        // b4  TXON:    csr0 で保持。
                    119:        // b2  STOP:    csr0 で保持。
                    120:        // b1  STRT:    csr0 で保持。
                    121:        // b0  INIT:    csr0 で保持。
                    122:        //
                    123:        // レジスタ値や状態を更新する際にはこれらに注意すること。
                    124:        // レジスタ値を読み出す時は GetCSR0() を使用すること。
                    125:        uint16 csr0;
                    126:        bool IsERR() const              { return ((csr0 & CSR0_ERR_BITS) != 0); }
                    127:        bool IsINTR() const             { return ((csr0 & CSR0_INTR_BITS) != 0); }
                    128:        bool IsSTOP() const             { return ((csr0 & CSR0_STOP) != 0); }
                    129: 
                    130:        // CSR0 の読み出し値を返す
                    131:        uint16 GetCSR0() const  {
                    132:                // ERR, INTR ビットだけ計算による
                    133:                uint16 intr = IsINTR() ? CSR0_INTR : 0;
                    134:                uint16 errbit = IsERR() ? CSR0_ERR : 0;
                    135:                return (csr0 | intr | errbit);
                    136:        }
                    137: 
                    138:        // CSR1, CSR2 は IADR の状態で保持する
                    139:        uint32 iadr;
                    140: 
                    141:        // CSR3
                    142:        uint16 csr3;
                    143:        bool IsBSWP() const             { return (csr3 & CSR3_BSWP); }
                    144: };
                    145: 
1.1.1.15  root      146: class LanceDevice : public EthernetDevice, public IHWAddrFilter
1.1       root      147: {
1.1.1.3   root      148:        using inherited = EthernetDevice;
1.1.1.8   root      149: 
                    150:        // 受信フェーズ
                    151:        enum class RXPhase {
1.1.1.9   root      152:                STOP = 0,       // (動作していない)
                    153:                IDLE,           // ポーリング
1.1.1.8   root      154:                COPY,           // バッファ書き込み
                    155:                NEXT,           // RMD 更新
                    156:                MISS,           // 受信ミス
                    157:        };
                    158:        // 送信フェーズ
                    159:        enum class TXPhase {
1.1.1.9   root      160:                STOP = 0,       // (動作していない)
                    161:                IDLE,           // ポーリング
1.1.1.8   root      162:                COPY,           // バッファ読み込み
                    163:                SEND,           // 送信
                    164:                NEXT,           // TMD 更新
                    165:        };
1.1       root      166: 
                    167:  public:
                    168:        LanceDevice();
1.1.1.12  root      169:        ~LanceDevice() override;
1.1       root      170: 
1.1.1.3   root      171:        bool Init() override;
1.1.1.9   root      172:        void ResetHard(bool poweron) override;
1.1       root      173: 
1.1.1.15  root      174:        int HWAddrFilter(const MacAddr& dstaddr) const override;
                    175: 
1.1.1.2   root      176:        // BusIO インタフェース
1.1.1.13  root      177:        // (内蔵 ROM からのアクセス用に特別に public にしてある)
                    178:        busdata WritePort(uint32 offset, uint32 data);
                    179:  protected:
1.1.1.2   root      180:        static const uint32 NPORT = 2;
1.1.1.13  root      181:        busdata ReadPort(uint32 offset);
                    182:        busdata PeekPort(uint32 offset);
1.1.1.2   root      183: 
1.1.1.8   root      184:  private:
                    185:        DECLARE_MONITOR_CALLBACK(MonitorUpdate);
1.1.1.4   root      186:        void MonitorReg(TextScreen&,
                    187:                int x, int y, uint32 data, const char * const * names);
1.1       root      188:        uint32 ReadData();
                    189:        void WriteData(uint32 data);
                    190: 
                    191:        // メモリアクセス
1.1.1.13  root      192:        uint32 ReadMem(uint32 paddr);
                    193:        void WriteMem(uint32 paddr, uint32 data);
                    194:        uint32 PeekMem(uint32 paddr) const;
1.1       root      195: 
                    196:        void ChipInit();
                    197:        void ChipStart();
                    198:        void ChipStop();
                    199: 
                    200:        // 割り込み要因をセットし、許可されていれば割り込みを上げる
                    201:        void SetInterrupt(uint32 bit);
1.1.1.6   root      202:        // 割り込み信号線の状態を変える
                    203:        void ChangeInterrupt();
1.1       root      204: 
1.1.1.16! root      205:        void TXIdle(Event *);
1.1.1.9   root      206:        void TXCopy();
1.1.1.16! root      207:        void TXSend(Event *);
        !           208:        void TXNext(Event *);
1.1.1.8   root      209: 
1.1.1.16! root      210:        void RXIdle(Event *);
1.1.1.9   root      211:        void RXCopy();
1.1.1.16! root      212:        void RXNext(Event *);
1.1.1.9   root      213:        void RXMiss();
1.1.1.8   root      214: 
                    215:        // フェーズ遷移
                    216:        void ChangePhase(TXPhase new_phase, uint64 time = 100_nsec);
                    217:        void ChangePhase(RXPhase new_phase, uint64 time = 100_nsec);
1.1       root      218: 
1.1.1.12  root      219:        // パケット受信通知 (HostNet から EthernetDevice 経由で呼ばれる)
                    220:        void RxMessage(MessageID, uint32);
1.1.1.9   root      221: 
1.1       root      222:        const std::string BitToString(const char * const name[], uint16 bits);
                    223:        const std::string CSR0ToString(uint16 bits);
                    224:        const std::string CSR3ToString(uint16 bits);
                    225:        static const char * const csr0names[];
                    226:        static const char * const csr3names[];
                    227:        static const char * const ib_mode_names[];
                    228:        static const char * const rmd1_names[];
                    229:        static const char * const tmd1_names[];
                    230:        static const char * const tmd3_names[];
                    231: 
                    232:        struct AM7990 reg {};
                    233: 
                    234:        // Initialization Block
                    235:        uint16 initblock[12] {};
                    236: 
1.1.1.15  root      237:        MacAddr padr {};
                    238:        uint64 ladrf {};
                    239:        bool promisc {};
1.1.1.8   root      240: 
1.1.1.10  root      241:        uint32 rmd_base {};                     // 受信ディスクリプタの(SubRAMでの)開始アドレス
1.1.1.13  root      242:        uint   rmd_num {};                      // 受信ディスクリプタ数
                    243:        uint   rmd_cur {};                      // RMD 内の現在の注目インデックス
1.1.1.10  root      244:        uint32 tmd_base {};                     // 送信ディスクリプタの(SubRAMでの)開始アドレス
1.1.1.13  root      245:        uint   tmd_num {};                      // 送信ディスクリプタ数
                    246:        uint   tmd_cur {};                      // TMD 内の現在の注目インデックス
1.1.1.5   root      247: 
                    248:        uint16 rmd1 {};                         // 現在の RMD1
                    249:        uint32 rmd1_ahead {};           // 次の RMD1 先読み (負なら先読みしてない状態)
1.1.1.8   root      250: 
1.1.1.5   root      251:        uint16 tmd1 {};                         // 現在の TMD1
                    252:        uint32 tmd1_ahead {};           // 次の TMD1 先読み (負なら先読みしてない状態)
1.1.1.9   root      253: 
                    254:        NetPacket rx_packet {};         // 受信バッファ
                    255:        NetPacket tx_packet {};         // 送信バッファ
1.1       root      256: 
1.1.1.8   root      257:        RXPhase rx_phase {};            // 受信フェーズ
                    258:        TXPhase tx_phase {};            // 送信フェーズ
                    259: 
1.1.1.10  root      260:        // 前回の TMD 状態文字列 (デバッグ表示用)
                    261:        std::string last_tmdstr {};
                    262: 
                    263:        InterruptDevice *interrupt {};
                    264:        SubRAMDevice *subram {};
                    265: 
1.1       root      266:        // 待ち時間用イベント
1.1.1.16! root      267:        Event *rx_event {};
        !           268:        Event *tx_event {};
1.1.1.8   root      269: 
1.1.1.14  root      270:        Monitor *monitor {};
1.1       root      271: };
1.1.1.10  root      272: 
                    273: static inline LanceDevice *GetLanceDevice() {
1.1.1.11  root      274:        return Object::GetObject<LanceDevice>(OBJ_ETHERNET(0));
1.1.1.10  root      275: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.