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

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2018 [email protected]
        !             4: //
        !             5: 
        !             6: #pragma once
        !             7: 
        !             8: #include "ethernet.h"
        !             9: #include "scheduler.h"
        !            10: 
        !            11: struct AM7990
        !            12: {
        !            13:        int rap;                        // レジスタアドレス (0..3)
        !            14: 
        !            15:        // CSR0
        !            16:        static const uint16 CSR0_ERR    = 0x8000;
        !            17:        static const uint16 CSR0_BABL   = 0x4000;
        !            18:        static const uint16 CSR0_CERR   = 0x2000;
        !            19:        static const uint16 CSR0_MISS   = 0x1000;
        !            20:        static const uint16 CSR0_MERR   = 0x0800;
        !            21:        static const uint16 CSR0_RINT   = 0x0400;
        !            22:        static const uint16 CSR0_TINT   = 0x0200;
        !            23:        static const uint16 CSR0_IDON   = 0x0100;
        !            24:        static const uint16 CSR0_INTR   = 0x0080;
        !            25:        static const uint16 CSR0_INEA   = 0x0040;
        !            26:        static const uint16 CSR0_RXON   = 0x0020;
        !            27:        static const uint16 CSR0_TXON   = 0x0010;
        !            28:        static const uint16 CSR0_TDMD   = 0x0008;
        !            29:        static const uint16 CSR0_STOP   = 0x0004;
        !            30:        static const uint16 CSR0_STRT   = 0x0002;
        !            31:        static const uint16 CSR0_INIT   = 0x0001;
        !            32:        // CSR0_ERR はこれらの和
        !            33:        static const uint16 CSR0_ERR_BITS =
        !            34:                CSR0_BABL |
        !            35:                CSR0_CERR |
        !            36:                CSR0_MISS |
        !            37:                CSR0_MERR;
        !            38:        // CSR0_INTR はこれらの和
        !            39:        static const uint16 CSR0_INTR_BITS =
        !            40:                CSR0_BABL |
        !            41:                CSR0_MISS |
        !            42:                CSR0_MERR |
        !            43:                CSR0_RINT |
        !            44:                CSR0_TINT |
        !            45:                CSR0_IDON;
        !            46: 
        !            47:        // CSR1
        !            48:        static const uint16 CSR1_MASK   = 0xfffe;
        !            49:        static const uint16 IADR_L_MASK = 0xfffe;
        !            50: 
        !            51:        // CSR2
        !            52:        static const uint16 CSR2_MASK   = 0x00ff;
        !            53:        static const uint16 IADR_H_MASK = 0x00ff;
        !            54: 
        !            55:        // CSR3
        !            56:        static const uint16 CSR3_MASK   = 0x0007;
        !            57:        static const uint16 CSR3_BSWP   = 0x0004;
        !            58:        static const uint16 CSR3_ACON   = 0x0002;
        !            59:        static const uint16 CSR3_BCON   = 0x0001;
        !            60: 
        !            61:        // IBMODE
        !            62:        static const uint16 IBMODE_PROM = 0x8000;
        !            63:        static const uint16 IBMODE_INTL = 0x0040;
        !            64:        static const uint16 IBMODE_DRTY = 0x0020;
        !            65:        static const uint16 IBMODE_COLL = 0x0010;
        !            66:        static const uint16 IBMODE_DTCR = 0x0008;
        !            67:        static const uint16 IBMODE_LOOP = 0x0004;
        !            68:        static const uint16 IBMODE_DTX  = 0x0002;
        !            69:        static const uint16 IBMODE_DRX  = 0x0001;
        !            70:        // RMD1
        !            71:        static const uint16 RMD1_OWN    = 0x8000;
        !            72:        static const uint16 RMD1_ERR    = 0x4000;
        !            73:        static const uint16 RMD1_FRAM   = 0x2000;
        !            74:        static const uint16 RMD1_OFLO   = 0x1000;
        !            75:        static const uint16 RMD1_CRC    = 0x0800;
        !            76:        static const uint16 RMD1_BUFF   = 0x0400;
        !            77:        static const uint16 RMD1_STP    = 0x0200;
        !            78:        static const uint16 RMD1_ENP    = 0x0100;
        !            79:        // TMD1
        !            80:        static const uint16 TMD1_OWN    = 0x8000;
        !            81:        static const uint16 TMD1_ERR    = 0x4000;
        !            82:        static const uint16 TMD1_resv   = 0x2000;
        !            83:        static const uint16 TMD1_MORE   = 0x1000;
        !            84:        static const uint16 TMD1_ONE    = 0x0800;
        !            85:        static const uint16 TMD1_DEF    = 0x0400;
        !            86:        static const uint16 TMD1_STP    = 0x0200;
        !            87:        static const uint16 TMD1_ENP    = 0x0100;
        !            88:        // TMD3
        !            89:        static const uint16 TMD3_BUFF   = 0x8000;
        !            90:        static const uint16 TMD3_UFLO   = 0x4000;
        !            91:        static const uint16 TMD3_resv   = 0x2000;
        !            92:        static const uint16 TMD3_LCOL   = 0x1000;
        !            93:        static const uint16 TMD3_LCAR   = 0x0800;
        !            94:        static const uint16 TMD3_BTRY   = 0x0400;
        !            95: 
        !            96:        // CSR0 ビットごとに処理方法が異なる。
        !            97:        //
        !            98:        // b15 ERR :    値は計算で求める。csr0 の該当ビットは常時クリア。
        !            99:        // b14 BABL:    csr0 で保持。
        !           100:        // b13 CERR:    csr0 で保持。
        !           101:        // b12 MISS:    csr0 で保持。
        !           102:        // b11 ERR :    csr0 で保持。
        !           103:        // b10 INT :    csr0 で保持。
        !           104:        // b9  TINT:    csr0 で保持。
        !           105:        // b8  IDON:    csr0 で保持。
        !           106:        // b7  INTR:    値は計算で求める。csr0 の該当ビットは常時クリア。
        !           107:        // b6  INEA:    csr0 で保持。
        !           108:        // b5  RXON:    csr0 で保持。
        !           109:        // b4  TXON:    csr0 で保持。
        !           110:        // b2  STOP:    csr0 で保持。
        !           111:        // b1  STRT:    csr0 で保持。
        !           112:        // b0  INIT:    csr0 で保持。
        !           113:        //
        !           114:        // レジスタ値や状態を更新する際にはこれらに注意すること。
        !           115:        // レジスタ値を読み出す時は GetCSR0() を使用すること。
        !           116:        uint16 csr0;
        !           117:        bool IsERR() const              { return ((csr0 & CSR0_ERR_BITS) != 0); }
        !           118:        bool IsINTR() const             { return ((csr0 & CSR0_INTR_BITS) != 0); }
        !           119:        bool IsSTOP() const             { return ((csr0 & CSR0_STOP) != 0); }
        !           120: 
        !           121:        // CSR0 の読み出し値を返す
        !           122:        uint16 GetCSR0() const  {
        !           123:                // ERR, INTR ビットだけ計算による
        !           124:                uint16 intr = IsINTR() ? CSR0_INTR : 0;
        !           125:                uint16 errbit = IsERR() ? CSR0_ERR : 0;
        !           126:                return (csr0 | intr | errbit);
        !           127:        }
        !           128: 
        !           129:        // CSR1, CSR2 は IADR の状態で保持する
        !           130:        uint32 iadr;
        !           131: 
        !           132:        // CSR3
        !           133:        uint16 csr3;
        !           134:        bool IsBSWP() const             { return (csr3 & CSR3_BSWP); }
        !           135: };
        !           136: 
        !           137: class LanceDevice
        !           138:        : public EthernetDevice
        !           139: {
        !           140:        typedef EthernetDevice inherited;
        !           141:  public:
        !           142:        static const uint32 REQ_TXIDLE          = 0x00000001;   // ポーリングフェーズ
        !           143:        static const uint32 REQ_TXCOPY          = 0x00000002;   // バッファ読込フェーズ
        !           144:        static const uint32 REQ_TXSEND          = 0x00000004;   // 送信フェーズ
        !           145:        static const uint32 REQ_TXNEXT          = 0x00000008;   // TMD 更新フェーズ
        !           146:        static const uint32 REQ_RXIDLE          = 0x00000010;   // ポーリングフェーズ
        !           147:        static const uint32 REQ_RXCOPY          = 0x00000020;   // バッファ書込フェーズ
        !           148:        static const uint32 REQ_RXNEXT          = 0x00000040;   // RMD 更新フェーズ
        !           149:        static const uint32 REQ_RXMISS          = 0x00000080;   // 受信 MISS
        !           150:        static const uint32 REQ_RXRECV          = 0x00000100;   // 受信イベント
        !           151:        static const uint32 REQ_TERMINATE       = 0x80000000;   // スレッド終了指示
        !           152: 
        !           153:  public:
        !           154:        LanceDevice();
        !           155:        virtual ~LanceDevice();
        !           156: 
        !           157:        virtual bool Init();
        !           158:        virtual void ResetHard();
        !           159: 
        !           160:        virtual uint64 Read8(uint32 addr);
        !           161:        virtual uint64 Read16(uint32 addr);
        !           162:        virtual uint64 Read32(uint32 addr);
        !           163:        virtual uint64 Write8(uint32 addr, uint32 data);
        !           164:        virtual uint64 Write16(uint32 addr, uint32 data);
        !           165:        virtual uint64 Write32(uint32 addr, uint32 data);
        !           166:        virtual uint64 Peek8(uint32 addr);
        !           167: 
        !           168:        virtual bool MonitorUpdate();
        !           169: 
        !           170:        // ワーカスレッド (エントリポイントから呼ばれる)
        !           171:        void ThreadRun();
        !           172: 
        !           173:        // パケットを受信した (ホストネットワークスレッドから呼ばれる)
        !           174:        virtual bool RecvPacket(qvector<uint8>& buf);
        !           175: 
        !           176:  private:
        !           177:        void MonitorReg(int x, int y, uint32 data, const char * const * names);
        !           178:        uint32 ReadData();
        !           179:        void WriteData(uint32 data);
        !           180: 
        !           181:        // メモリアクセス
        !           182:        uint64 ReadMem(uint32 paddr);
        !           183:        uint64 WriteMem(uint32 paddr, uint32 data);
        !           184:        uint64 PeekMem(uint32 paddr);
        !           185: 
        !           186:        void ChipInit();
        !           187:        void ChipStart();
        !           188:        void ChipStop();
        !           189: 
        !           190:        // 割り込み要因をセットし、許可されていれば割り込みを上げる
        !           191:        void SetInterrupt(uint32 bit);
        !           192:        // 許可されていれば割り込みを上げる
        !           193:        void Interrupt();
        !           194: 
        !           195:        void TXIdle();
        !           196:        void TXCopy();
        !           197:        void TXSend();
        !           198:        void TXNext();
        !           199:        void RXIdle();
        !           200:        void RXCopy();
        !           201:        void RXNext();
        !           202:        void RXRecv();
        !           203:        void RXMiss();
        !           204:        void Callback(int arg);
        !           205: 
        !           206:        const std::string BitToString(const char * const name[], uint16 bits);
        !           207:        const std::string CSR0ToString(uint16 bits);
        !           208:        const std::string CSR3ToString(uint16 bits);
        !           209:        static const char * const csr0names[];
        !           210:        static const char * const csr3names[];
        !           211:        static const char * const ib_mode_names[];
        !           212:        static const char * const rmd1_names[];
        !           213:        static const char * const tmd1_names[];
        !           214:        static const char * const tmd3_names[];
        !           215: 
        !           216:        struct AM7990 reg {};
        !           217: 
        !           218:        // Initialization Block
        !           219:        uint16 initblock[12] {};
        !           220: 
        !           221:        uint32 rmd_base = 0;    // 受信ディスクリプタの(ZRAM での)開始アドレス
        !           222:        int    rmd_num = 0;             // 受信ディスクリプタ数
        !           223:        int    rmd_cur = 0;             // RMD 内の現在の注目インデックス
        !           224:        uint32 tmd_base = 0;    // 送信ディスクリプタの(ZRAM での)開始アドレス
        !           225:        int    tmd_num = 0;             // 送信ディスクリプタ数
        !           226:        int    tmd_cur = 0;             // TMD 内の現在の注目インデックス
        !           227: 
        !           228:        uint16 rmd1 = 0;                // 現在の RMD1
        !           229:        uint32 rmd1_ahead = 0;  // 次の RMD1 先読み (負なら先読みしてない状態)
        !           230:        qvector<uint8> rxq {};  // 受信バッファ
        !           231: 
        !           232:        uint16 tmd1 = 0;                // 現在の TMD1
        !           233:        uint32 tmd1_ahead = 0;  // 次の TMD1 先読み (負なら先読みしてない状態)
        !           234:        std::vector<uint8> txq {};      // 送信バッファ
        !           235: 
        !           236:        // 待ち時間用イベント
        !           237:        Event rx_event {};
        !           238:        Event tx_event {};
        !           239: 
        !           240:        // 前回の TMD 状態文字列 (デバッグ表示用)
        !           241:        std::string last_tmdstr {};
        !           242: };
        !           243: 
        !           244: extern LanceDevice *gLance;

unix.superglobalmegacorp.com

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