|
|
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:
262: RTL8019ASDevice(int 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.2 ! root 268: busdata Read8(uint32 addr) override;
! 269: busdata Read16(uint32 addr) override;
! 270: busdata Write8(uint32 addr, uint32 data) override;
! 271: busdata Write16(uint32 addr, uint32 data) override;
! 272: busdata Peek8(uint32 addr) override;
1.1 root 273:
1.1.1.2 ! root 274: busdata InterruptAcknowledge();
1.1 root 275:
276: private:
277: static inline uint32 Decoder(uint32 addr);
278:
279: uint32 ReadReg(uint32 rn);
280: uint32 ReadDMA8(uint32 a0);
281: uint32 ReadDMA16();
282: uint32 WriteReg(uint32 rn, uint32 data);
283: void WriteCR(uint32 data);
284: void WritePSTART(uint32 data);
285: void WritePSTOP(uint32 data);
286: void WriteBNRY(uint32 data);
287: void WriteTPSR(uint32 data);
288: void WriteTBCR0(uint32 data);
289: void WriteTBCR1(uint32 data);
290: void WriteISR(uint32 data);
291: void WriteRSAR0(uint32 data);
292: void WriteRSAR1(uint32 data);
293: void WriteRBCR0(uint32 data);
294: void WriteRBCR1(uint32 data);
295: void WriteRCR(uint32 data);
296: void WriteTCR(uint32 data);
297: void WriteDCR(uint32 data);
298: void WriteIMR(uint32 data);
299: void WritePAR(int n, uint32 data);
300: void WriteCURR(uint32 data);
301: void WriteMAR(int n, uint32 data);
302: void Write9346CR(uint32 data);
303: void WriteCONFIG0(uint32 data);
304: void WriteCONFIG1(uint32 data);
305: void WriteCONFIG2(uint32 data);
306: void WriteCONFIG3(uint32 data);
307: void WriteDMA8(uint32 data);
308: void WriteDMA16(uint32 data);
309: uint32 PeekReg(uint32 rn) const;
310: uint32 PeekCR() const;
311: uint32 PeekCLDA() const;
312: uint32 PeekBNRY() const;
313: uint32 PeekTSR() const;
314: uint32 PeekNCR() const;
315: uint32 PeekFIFO() const;
316: uint32 PeekISR() const;
317: uint32 PeekCRDA() const;
318: uint32 Peek8019ID0() const;
319: uint32 Peek8019ID1() const;
320: uint32 PeekRSR() const;
321: uint32 PeekCNTR(int n) const;
322: uint32 PeekPAR(int n) const;
323: uint32 PeekCURR() const;
324: uint32 PeekMAR(int n) const;
325: uint32 PeekPSTART() const;
326: uint32 PeekPSTOP() const;
327: uint32 PeekTPSR() const;
328: uint32 PeekRCR() const;
329: uint32 PeekTCR() const;
330: uint32 PeekDCR() const;
331: uint32 PeekIMR() const;
332: uint32 Peek9346CR() const;
333: uint32 PeekBPAGE() const;
334: uint32 PeekCONFIG0() const;
335: uint32 PeekCONFIG1() const;
336: uint32 PeekCONFIG2() const;
337: uint32 PeekCONFIG3() const;
338: uint32 PeekCONFIG4() const;
339: uint32 PeekCSNSAV() const;
340: uint32 PeekReg39() const;
341: uint32 PeekINTR() const;
342: uint32 PeekDMA(uint32 a0) const;
343:
344: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
345: void MonitorReg(TextScreen&, int, int, uint32, const char * const *names);
346:
347: void Reset();
348: void ChangeInterrupt();
349:
350: // DMA 処理の下請け
351: void ReadDMAlog(uint32 addr, uint32 data, int width);
352: void PostDMA();
353:
354: // 内蔵空間アクセス
355: inline uint32 ReadPROM(uint32 addr) const;
356: inline uint32 ReadRAM(uint32 addr) const;
357: inline void WriteRAM(uint32 addr, uint32 data);
358:
359: // 状態
360: bool IsStopOrInProgress() const;
361: void ChangeState(State newstate);
362:
363: // 送信
364: void Transmit();
365: void TXEvent(Event&);
366: // 受信
1.1.1.2 ! root 367: void RxMessage(MessageID msgid, uint32 arg);
1.1 root 368: void RXEvent(Event&);
369: void RXHead(int remain);
370: void RXCopy(Event&, int remain);
371: void RXDone(Event&);
372:
373: void TXLedEvent(Event&);
374: void RXLedEvent(Event&);
375:
376: void IncCounter(int n);
377:
378: // レジスタ名を返す
379: static std::string RegNameR(int rn);
380: static std::string RegNameW(int rn);
381: static const char *GetDMAName(uint32);
382:
383: // 動作状態
384: // ハードウェアリセット(解除?)後、STA が発行されるまではリセット状態。
385: // STP が発行されたら、仕掛りの送受信を終えたところでリセット状態に入る。
386: // リセット状態に入ると ISR:RST が立つ。
387: // このリセット状態をここでは Stop 状態と呼ぶ。
388: State state {};
389: // 送信処理中なら true
390: // (受信処理中の方は rx_packet.length != 0 で判定する)
391: bool tx_in_progress {};
392:
393: // CR: ページ番号 (をあらかじめオフセットしたもの)
394: uint32 pagesel {};
395:
396: // CR_RD: DMA 状態?
397: DMAMode dmamode {};
398:
399: bool cr_sta {};
400:
401: // 割り込みフラグ (bit7 は 0 にすること)
402: uint32 intr_stat {};
403: // 割り込みマスク (bit7 は 0 にすること)
404: uint32 intr_mask {};
405: // 割り込みベクタ (NereidBoardDevice から渡される)
1.1.1.2 ! root 406: uint32 intr_vector {};
1.1 root 407:
408: uint32 tsr {};
409: uint32 rsr {}; // DIS 以外のビットを保持
410:
411: // RCR: モニタモード
412: bool monitor_mode {};
413: bool promisc_mode {};
414: bool accept_mcast {};
415: bool accept_bcast {};
416: bool accept_short {};
417: bool accept_error {};
418:
419: // TCR
420: uint32 tcr {};
421:
422: // DCR
423: bool word_transfer {};
424: uint32 dcr {}; // それ以外のビット
425:
426: // 折り返しを計算しなくて済むように uint16 にしておく。
427: // またレジスタイメージがバイト単位かページ単位かに関わらず、
428: // すべてバイト単位で統一。
429:
430: uint16 remote_addr {}; // RSAR/CRDA: 現在のアクセス位置
431: uint16 remote_count {}; // RBCR: 残り転送バイト数
432: uint16 remote_start_addr {}; // DMA 開始時の位置 (ログ用)
433: uint16 remote_start_count {}; // DMA 開始時の残り転送バイト数 (ログ用)
434:
435: uint16 transmit_page_start_addr {}; // TPSR
436: uint16 transmit_byte_count {}; // TBCR
437:
438: uint16 pstart_addr {}; // PSTART
439: uint16 pstop_addr {}; // PSTOP
440: uint16 boundary_addr {}; // BNRY
441: uint16 current_page_addr {}; // CURR: 受信開始位置
442: uint16 local_addr {}; // CLDA: 書き込み位置
443: uint16 next_page_addr {}; // 次パケットの受信開始位置
444:
445: macaddr_t par {};
446: std::array<uint8, 8> mar {};
447: std::array<uint8, 3> error_counter {};
448:
449: // 9346CR
450: bool config_write_enable {};
451:
452: // CONFIG
453: uint32 verid {};
454: bool irq_enable {};
455: uint32 mediatype {};
456: bool brom_force_disable {};
457: uint32 config3 {};
458:
459: // バッファ (16KB 固定)
460: std::array<uint8, 16384> buffer {};
461:
462: // PROM (実質 16 バイト)
463: std::array<uint8, 16> prom {};
464:
465: NetPacket tx_packet {};
466: NetPacket rx_packet {};
467:
468: // LED (true で点灯)
469: bool tx_led {};
470: bool rx_led {};
471:
472: Monitor monitor { this };
473:
474: Event tx_event { this };
475: Event rx_event { this };
476: Event txled_event { this };
477: Event rxled_event { this };
478:
479: InterruptDevice *interrupt {};
480:
481: static const char * const regnames[];
482: };
483:
484: static inline RTL8019ASDevice *GetRTL8019ASDevice(int n) {
485: return Object::GetObject<RTL8019ASDevice>(OBJ_ETHERNET(n));
486: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.