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