|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2023 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // Nereid イーサネット (RTL8019AS)
9: //
10:
11: #pragma once
12:
13: #include "ethernet.h"
14: #include "event.h"
15: #include "hostnet.h"
16: #include "message.h"
17: #include "monitor.h"
18:
19: class InterruptDevice;
20:
21: struct RTL8019
22: {
23: // レジスタアドレスは $0-$f までの16個 x Page 0-3 の4ページなので、
24: // ここでのレジスタ番号は全部リニアに並べて表現する。
25: // Page0 はほとんどが Read/Write でレジスタが異なるが、
26: // それについてはここでは区別せず、Read/Write のコード中で使い分ける。
27:
28: // Page0 R(/W)
29: static const uint32 CR = 0x00; // RW: Command Register
30: static const uint32 CLDA0 = 0x01; // R-: Current Local DMA Address Regs
31: static const uint32 CLDA1 = 0x02; // R-: Current Local DMA Address Regs
32: static const uint32 BNRY = 0x03; // RW: Boundary Register
33: static const uint32 TSR = 0x04; // R-: Transmit Status Register
34: static const uint32 NCR = 0x05; // R-: Number of Collisions Register
35: static const uint32 FIFO = 0x06; // R-: First In First Out Register
36: static const uint32 ISR = 0x07; // RW: Interrupt Status Register
37: static const uint32 CRDA0 = 0x08; // R-: Current Remote DMA Address Regs
38: static const uint32 CRDA1 = 0x09; // R-: Current Remote DMA Address Regs
39: static const uint32 ID0 = 0x0a; // R-: 8019ID0
40: static const uint32 ID1 = 0x0b; // R-: 8019ID1
41: static const uint32 RSR = 0x0c; // R-: Receive Configuration Register
42: static const uint32 CNTR0 = 0x0d; // R-: Frame Align.Error Tally Counter
43: static const uint32 CNTR1 = 0x0e; // R-: CRC Error Tally Counter Reg.
44: static const uint32 CNTR2 = 0x0f; // R-: Missed Pakcet Tally Counter Reg.
45:
46: // Page0 W
47: static const uint32 PSTART = 0x01; // -W: Page Start Register
48: static const uint32 PSTOP = 0x02; // -W: Page Stop Register
49: static const uint32 TPSR = 0x04; // -W: Transmit Page Start Register
50: static const uint32 TBCR0 = 0x05; // -W: Transmit Byte Counter Registers
51: static const uint32 TBCR1 = 0x06; // -W: Transmit Byte Counter Registers
52: static const uint32 RSAR0 = 0x08; // -W: Remote Start Address Regs
53: static const uint32 RSAR1 = 0x09; // -W: Remote Start Address Regs
54: static const uint32 RBCR0 = 0x0a; // -W: Remote Byte Count Registers
55: static const uint32 RBCR1 = 0x0b; // -W: Remote Byte Count Registers
56: static const uint32 RCR = 0x0c; // -W: Receive Configuration Register
57: static const uint32 TCR = 0x0d; // -W: Transmit Configuration Register
58: static const uint32 DCR = 0x0e; // -W: Data Configuration Register
59: static const uint32 IMR = 0x0f; // -W: Interrupt Mask Register
60:
61: // Page 1 R/W
62: static const uint32 CR_1 = 0x10;
63: static const uint32 PAR0 = 0x11; // RW: Physical Address Registers
64: static const uint32 PAR1 = 0x12; // RW: Physical Address Registers
65: static const uint32 PAR2 = 0x13; // RW: Physical Address Registers
66: static const uint32 PAR3 = 0x14; // RW: Physical Address Registers
67: static const uint32 PAR4 = 0x15; // RW: Physical Address Registers
68: static const uint32 PAR5 = 0x16; // RW: Physical Address Registers
69: static const uint32 CURR = 0x17; // RW: Current Page Register
70: static const uint32 MAR0 = 0x18; // RW: Multicast Address Registers
71: static const uint32 MAR1 = 0x19; // RW: Multicast Address Registers
72: static const uint32 MAR2 = 0x1a; // RW: Multicast Address Registers
73: static const uint32 MAR3 = 0x1b; // RW: Multicast Address Registers
74: static const uint32 MAR4 = 0x1c; // RW: Multicast Address Registers
75: static const uint32 MAR5 = 0x1d; // RW: Multicast Address Registers
76: static const uint32 MAR6 = 0x1e; // RW: Multicast Address Registers
77: static const uint32 MAR7 = 0x1f; // RW: Multicast Address Registers
78:
79: // Page2 R
80: static const uint32 CR_2 = 0x20;
81: static const uint32 PSTART_2= 0x21;
82: static const uint32 PSTOP_2 = 0x22;
83: static const uint32 TPSR_2 = 0x24;
84: static const uint32 RCR_2 = 0x2c;
85: static const uint32 TCR_2 = 0x2d;
86: static const uint32 DCR_2 = 0x2e;
87: static const uint32 IMR_2 = 0x2f;
88:
89: // Page3 R/W
90: static const uint32 CR_3 = 0x30;
91: static const uint32 CR9346 = 0x31; // RW: 9346 Command Register
92: static const uint32 BPAGE = 0x32; // RW: BROM Page Register
93: static const uint32 CONFIG0 = 0x33; // R-: RTL8019AS Config. Register 0
94: static const uint32 CONFIG1 = 0x34; // RW: RTL8019AS Config. Register 1
95: static const uint32 CONFIG2 = 0x35; // RW: RTL8019AS Config. Register 2
96: static const uint32 CONFIG3 = 0x36; // RW: RTL8019AS Config. Register 3
97: static const uint32 TEST = 0x37; // -W:
98: static const uint32 CSNSAV = 0x38; // R-: CSN Save Register (For PnP)
99: static const uint32 HLTCLK = 0x39; // -W: Halt Clock Register
100: static const uint32 INTR = 0x3b; // R-: Interrupt Register
101: static const uint32 FMWP = 0x3c; // -W: Flush Memory Write Protect Reg.
102: static const uint32 CONFIG4 = 0x3d; // R-: RTL8019AS Config. Register 4
103:
104: // 7 6 5 4 3 2 1 0
105: // +-----+-----+-----+-----+-----+-----+-----+-----+
106: // CR | PS | RD | TXP | STA | STP |
107: // +-----+-----+-----+-----+-----+-----+-----+-----+
108: static const uint32 CR_RD_READ = 0x08;
109: static const uint32 CR_RD_WRITE = 0x10;
110: static const uint32 CR_RD_SEND = 0x18;
111: static const uint32 CR_TXP = 0x04;
112: static const uint32 CR_STA = 0x02;
113: static const uint32 CR_STP = 0x01;
114:
115: // 7 6 5 4 3 2 1 0
116: // +-----+-----+-----+-----+-----+-----+-----+-----+
117: // TSR | OWC | CDH | 0 | CRS | ABT | COL | 1 | PTX |
118: // +-----+-----+-----+-----+-----+-----+-----+-----+
119: static const uint32 TSR_OWC = 0x80; // Out of Window Collision
120: static const uint32 TSR_CDH = 0x40; // CD Heartbeat
121: static const uint32 TSR_CRS = 0x10; // Carrier Sense lost bit
122: static const uint32 TSR_ABT = 0x08; // Abort TX due to excessive coll.
123: static const uint32 TSR_COL = 0x04; // TX collied with other station
124: static const uint32 TSR_PTX = 0x01; // TX completes with no errors
125:
126: // 7 6 5 4 3 2 1 0
127: // +-----+-----+-----+-----+-----+-----+-----+-----+
128: // ISR | RST | RDC | CNT | OVW | TXE | RXE | PTX | PRX |
129: // +-----+-----+-----+-----+-----+-----+-----+-----+
130: static const uint32 ISR_RST = 0x80; // Enter reset state
131: static const uint32 ISR_RDC = 0x40; // Remote DMA operation completed
132: static const uint32 ISR_CNT = 0x20; //
133: static const uint32 ISR_OVW = 0x10; // RX buffer overflow
134: static const uint32 ISR_TXE = 0x08; // TX Error
135: static const uint32 ISR_RXE = 0x04; // RX Error
136: static const uint32 ISR_PTX = 0x02; // Packet transmitted with no errors
137: static const uint32 ISR_PRX = 0x01; // Packet received with no errors
138:
139: // 7 6 5 4 3 2 1 0
140: // +-----+-----+-----+-----+-----+-----+-----+-----+
141: // RSR | DFR | DIS | PHY | MPA | 0 | FAE | CRC | PRX |
142: // +-----+-----+-----+-----+-----+-----+-----+-----+
143: static const uint32 RSR_DFR = 0x80; // Deffering
144: static const uint32 RSR_DIS = 0x40; // Receiver Disabled
145: static const uint32 RSR_PHY = 0x20; // Recv'd packet is multi/broadcast
146: static const uint32 RSR_MPA = 0x10; // Missed Packet
147: static const uint32 RSR_FAE = 0x04; // Frame Alignment Error
148: static const uint32 RSR_CRC = 0x02; // CRC Error
149: static const uint32 RSR_PRX = 0x01; // Packet received with no errors
150:
151: // 7 6 5 4 3 2 1 0
152: // +-----+-----+-----+-----+-----+-----+-----+-----+
153: // RCR | 1 | 1 | MON | PRO | AM | AB | AR | SEP |
154: // +-----+-----+-----+-----+-----+-----+-----+-----+
155: static const uint32 RCR_MON = 0x20; // Monitor mode
156: static const uint32 RCR_PRO = 0x10; // Promisc.
157: static const uint32 RCR_AM = 0x08; // Accept multicast dest address
158: static const uint32 RCR_AB = 0x04; // Accept broadcast dest address
159: static const uint32 RCR_AR = 0x02; // Accept <64bytes
160: static const uint32 RCR_SEP = 0x01; // Accept packet with recv errors
161:
162: // 7 6 5 4 3 2 1 0
163: // +-----+-----+-----+-----+-----+-----+-----+-----+
164: // TCR | 1 | 1 | 1 |OFST | ATD | LB | CRC |
165: // +-----+-----+-----+-----+-----+-----+-----+-----+
166: static const uint32 TCR_OFST = 0x10; // Collision Offset Enable
167: static const uint32 TCR_ATD = 0x08; // Auto Transmit Disable
168: static const uint32 TCR_LB_MASK = 0x06; // Loopback mode
169: static const uint32 TCR_CRC = 0x01; // Don't append CRC
170:
171: // 7 6 5 4 3 2 1 0
172: // +-----+-----+-----+-----+-----+-----+-----+-----+
173: // DCR | 1 | FT | ARM | LS | LAS | BOS | WTS |
174: // +-----+-----+-----+-----+-----+-----+-----+-----+
175: static const uint32 DCR_FT_MASK = 0x60; // FIFO threshold
176: static const uint32 DCR_ARM = 0x10; // Auto initialize Remote
177: static const uint32 DCR_LS = 0x08; // Loopback Select
178: static const uint32 DCR_LAS = 0x04; // (32bit DMA not supported by NIC)
179: static const uint32 DCR_BOS = 0x02; // Byte Order Select (Not Impl?)
180: static const uint32 DCR_WTS = 0x01; // Word Transfer Select
181:
182: // 7 6 5 4 3 2 1 0
183: // +-----+-----+-----+-----+-----+-----+-----+-----+
184: // 9346CR | EEM | not used |EECS |EESK |EEDI |EEDO |
185: // +-----+-----+-----+-----+-----+-----+-----+-----+
186: static const uint32 CR9346_EEM_MASK = 0xc0; // RTL8019AS operating mode
187:
188: // 7 6 5 4 3 2 1 0
189: // +-----+-----+-----+-----+-----+-----+-----+-----+
190: // CONFIG0 | VERID | AUI |PNPJP| JP | BNC | 0 | 0 |
191: // +-----+-----+-----+-----+-----+-----+-----+-----+
192: static const uint32 CONFIG0_VERID_MASK = 0xc0;
193: static const uint32 CONFIG0_AUI = 0x20;
194: static const uint32 CONFIG0_PNPJP = 0x10;
195: static const uint32 CONFIG0_JP = 0x08;
196: static const uint32 CONFIG0_BNC = 0x04;
197:
198: // 7 6 5 4 3 2 1 0
199: // +-----+-----+-----+-----+-----+-----+-----+-----+
200: // CONFIG1 |IRQEN| IRQS | IOS |
201: // +-----+-----+-----+-----+-----+-----+-----+-----+
202: static const uint32 CONFIG1_IRQEN = 0x80;
203: static const uint32 CONFIG1_IRQS_MASK = 0x70;
204: static const uint32 CONFIG1_IOS_MASK = 0x0f;
205:
206: // 7 6 5 4 3 2 1 0
207: // +-----+-----+-----+-----+-----+-----+-----+-----+
208: // CONFIG2 | PL |BSELB| BS |
209: // +-----+-----+-----+-----+-----+-----+-----+-----+
210: static const uint32 CONFIG2_PL_MASK = 0xc0;
211: static const uint32 CONFIG2_BSELB = 0x20;
212: static const uint32 CONFIG2_BS = 0x1f;
213:
214: // 7 6 5 4 3 2 1 0
215: // +-----+-----+-----+-----+-----+-----+-----+-----+
216: // CONFIG3 | PNP |FUDUP|LEDS1|LEDS0| 0 |SLEEP|PWRDN|ACTB |
217: // +-----+-----+-----+-----+-----+-----+-----+-----+
218: static const uint32 CONFIG3_PNP = 0x80;
219: static const uint32 CONFIG3_FUDUP = 0x40;
220: static const uint32 CONFIG3_LEDS1 = 0x20;
221: static const uint32 CONFIG3_LEDS0 = 0x10;
222: static const uint32 CONFIG3_SLEEP = 0x04;
223: static const uint32 CONFIG3_PWRDN = 0x02;
224: static const uint32 CONFIG3_ACTB = 0x01;
225:
226: // 7 6 5 4 3 2 1 0
227: // +-----+-----+-----+-----+-----+-----+-----+-----+
228: // CONFIG4 | - | - | - | - | - | - | - |IOMS |
229: // +-----+-----+-----+-----+-----+-----+-----+-----+
230: static const uint32 CONFIG4_IOMS = 0x01;
231:
232: // メディアタイプ (CONFIG2)
233: enum {
234: MediaType_10BaseT_Auto = 0,
235: MediaType_10BaseT = 1,
236: MediaType_10Base5 = 2,
237: MediaType_10Base2 = 3,
238: };
239: };
240:
241: class RTL8019ASDevice : public EthernetDevice
242: {
243: using inherited = EthernetDevice;
244:
245: // 動作状態 (数値比較も行うことに注意)
246: enum class State {
247: Normal = 0, // 送受信可能
248: Stop = 1, // STP
249: StopInProgress = 2, // STP へ移行中 (処理中の送受信のみ継続)
250: };
251:
252: // DMA 状態?
253: enum class DMAMode {
254: NotAllowed = 0,
255: RemoteRead = 1,
256: RemoteWrite = 2,
257: SendPacket = 3,
258: Complete = 4,
259: };
260:
261: public:
1.1.1.3 ! root 262: RTL8019ASDevice(uint n_, int vector_);
1.1.1.2 root 263: ~RTL8019ASDevice() override;
1.1 root 264:
265: bool Init() override;
266: void ResetHard(bool poweron) override;
267:
1.1.1.3 ! root 268: busdata Read(busaddr addr) override;
! 269: busdata Write(busaddr addr, uint32 data) override;
! 270: busdata Peek1(uint32 addr) override;
1.1 root 271:
1.1.1.2 root 272: busdata InterruptAcknowledge();
1.1 root 273:
274: private:
275: static inline uint32 Decoder(uint32 addr);
276:
277: uint32 ReadReg(uint32 rn);
278: uint32 ReadDMA8(uint32 a0);
279: uint32 ReadDMA16();
1.1.1.3 ! root 280: void WriteReg(uint32 rn, uint32 data);
1.1 root 281: void WriteCR(uint32 data);
282: void WritePSTART(uint32 data);
283: void WritePSTOP(uint32 data);
284: void WriteBNRY(uint32 data);
285: void WriteTPSR(uint32 data);
286: void WriteTBCR0(uint32 data);
287: void WriteTBCR1(uint32 data);
288: void WriteISR(uint32 data);
289: void WriteRSAR0(uint32 data);
290: void WriteRSAR1(uint32 data);
291: void WriteRBCR0(uint32 data);
292: void WriteRBCR1(uint32 data);
293: void WriteRCR(uint32 data);
294: void WriteTCR(uint32 data);
295: void WriteDCR(uint32 data);
296: void WriteIMR(uint32 data);
1.1.1.3 ! root 297: void WritePAR(uint n, uint32 data);
1.1 root 298: void WriteCURR(uint32 data);
1.1.1.3 ! root 299: void WriteMAR(uint n, uint32 data);
1.1 root 300: void Write9346CR(uint32 data);
301: void WriteCONFIG0(uint32 data);
302: void WriteCONFIG1(uint32 data);
303: void WriteCONFIG2(uint32 data);
304: void WriteCONFIG3(uint32 data);
305: void WriteDMA8(uint32 data);
306: void WriteDMA16(uint32 data);
307: uint32 PeekReg(uint32 rn) const;
308: uint32 PeekCR() const;
309: uint32 PeekCLDA() const;
310: uint32 PeekBNRY() const;
311: uint32 PeekTSR() const;
312: uint32 PeekNCR() const;
313: uint32 PeekFIFO() const;
314: uint32 PeekISR() const;
315: uint32 PeekCRDA() const;
316: uint32 Peek8019ID0() const;
317: uint32 Peek8019ID1() const;
318: uint32 PeekRSR() const;
319: uint32 PeekCNTR(int n) const;
320: uint32 PeekPAR(int n) const;
321: uint32 PeekCURR() const;
322: uint32 PeekMAR(int n) const;
323: uint32 PeekPSTART() const;
324: uint32 PeekPSTOP() const;
325: uint32 PeekTPSR() const;
326: uint32 PeekRCR() const;
327: uint32 PeekTCR() const;
328: uint32 PeekDCR() const;
329: uint32 PeekIMR() const;
330: uint32 Peek9346CR() const;
331: uint32 PeekBPAGE() const;
332: uint32 PeekCONFIG0() const;
333: uint32 PeekCONFIG1() const;
334: uint32 PeekCONFIG2() const;
335: uint32 PeekCONFIG3() const;
336: uint32 PeekCONFIG4() const;
337: uint32 PeekCSNSAV() const;
338: uint32 PeekReg39() const;
339: uint32 PeekINTR() const;
340: uint32 PeekDMA(uint32 a0) const;
341:
342: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
343: void MonitorReg(TextScreen&, int, int, uint32, const char * const *names);
344:
345: void Reset();
346: void ChangeInterrupt();
347:
348: // DMA 処理の下請け
349: void ReadDMAlog(uint32 addr, uint32 data, int width);
350: void PostDMA();
351:
352: // 内蔵空間アクセス
353: inline uint32 ReadPROM(uint32 addr) const;
354: inline uint32 ReadRAM(uint32 addr) const;
355: inline void WriteRAM(uint32 addr, uint32 data);
356:
357: // 状態
358: bool IsStopOrInProgress() const;
359: void ChangeState(State newstate);
360:
361: // 送信
362: void Transmit();
363: void TXEvent(Event&);
364: // 受信
1.1.1.2 root 365: void RxMessage(MessageID msgid, uint32 arg);
1.1 root 366: void RXEvent(Event&);
1.1.1.3 ! root 367: void RXHead();
! 368: void RXCopy(Event&, uint remain);
1.1 root 369: void RXDone(Event&);
370:
371: void TXLedEvent(Event&);
372: void RXLedEvent(Event&);
373:
374: void IncCounter(int n);
375:
376: // レジスタ名を返す
377: static std::string RegNameR(int rn);
378: static std::string RegNameW(int rn);
379: static const char *GetDMAName(uint32);
380:
381: // 動作状態
382: // ハードウェアリセット(解除?)後、STA が発行されるまではリセット状態。
383: // STP が発行されたら、仕掛りの送受信を終えたところでリセット状態に入る。
384: // リセット状態に入ると ISR:RST が立つ。
385: // このリセット状態をここでは Stop 状態と呼ぶ。
386: State state {};
387: // 送信処理中なら true
388: // (受信処理中の方は rx_packet.length != 0 で判定する)
389: bool tx_in_progress {};
390:
391: // CR: ページ番号 (をあらかじめオフセットしたもの)
392: uint32 pagesel {};
393:
394: // CR_RD: DMA 状態?
395: DMAMode dmamode {};
396:
397: bool cr_sta {};
398:
399: // 割り込みフラグ (bit7 は 0 にすること)
400: uint32 intr_stat {};
401: // 割り込みマスク (bit7 は 0 にすること)
402: uint32 intr_mask {};
403: // 割り込みベクタ (NereidBoardDevice から渡される)
1.1.1.2 root 404: uint32 intr_vector {};
1.1 root 405:
406: uint32 tsr {};
407: uint32 rsr {}; // DIS 以外のビットを保持
408:
409: // RCR: モニタモード
410: bool monitor_mode {};
411: bool promisc_mode {};
412: bool accept_mcast {};
413: bool accept_bcast {};
414: bool accept_short {};
415: bool accept_error {};
416:
417: // TCR
418: uint32 tcr {};
419:
420: // DCR
421: bool word_transfer {};
422: uint32 dcr {}; // それ以外のビット
423:
424: // 折り返しを計算しなくて済むように uint16 にしておく。
425: // またレジスタイメージがバイト単位かページ単位かに関わらず、
426: // すべてバイト単位で統一。
427:
428: uint16 remote_addr {}; // RSAR/CRDA: 現在のアクセス位置
429: uint16 remote_count {}; // RBCR: 残り転送バイト数
430: uint16 remote_start_addr {}; // DMA 開始時の位置 (ログ用)
431: uint16 remote_start_count {}; // DMA 開始時の残り転送バイト数 (ログ用)
432:
433: uint16 transmit_page_start_addr {}; // TPSR
434: uint16 transmit_byte_count {}; // TBCR
435:
436: uint16 pstart_addr {}; // PSTART
437: uint16 pstop_addr {}; // PSTOP
438: uint16 boundary_addr {}; // BNRY
439: uint16 current_page_addr {}; // CURR: 受信開始位置
440: uint16 local_addr {}; // CLDA: 書き込み位置
441: uint16 next_page_addr {}; // 次パケットの受信開始位置
442:
443: macaddr_t par {};
444: std::array<uint8, 8> mar {};
445: std::array<uint8, 3> error_counter {};
446:
447: // 9346CR
448: bool config_write_enable {};
449:
450: // CONFIG
451: uint32 verid {};
452: bool irq_enable {};
453: uint32 mediatype {};
454: bool brom_force_disable {};
455: uint32 config3 {};
456:
457: // バッファ (16KB 固定)
458: std::array<uint8, 16384> buffer {};
459:
460: // PROM (実質 16 バイト)
461: std::array<uint8, 16> prom {};
462:
463: NetPacket tx_packet {};
464: NetPacket rx_packet {};
465:
466: // LED (true で点灯)
467: bool tx_led {};
468: bool rx_led {};
469:
470: Monitor monitor { this };
471:
472: Event tx_event { this };
473: Event rx_event { this };
474: Event txled_event { this };
475: Event rxled_event { this };
476:
477: InterruptDevice *interrupt {};
478:
479: static const char * const regnames[];
480: };
481:
482: static inline RTL8019ASDevice *GetRTL8019ASDevice(int n) {
483: return Object::GetObject<RTL8019ASDevice>(OBJ_ETHERNET(n));
484: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.