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