|
|
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;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.