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