1
+ #include " AM79C973.h"
2
+
3
+ void printHex (uint8_t Key);
4
+
5
+ AM79C973::AM79C973 (PCIDeviceDescriptor *dev, InterruptManager *interrupts)
6
+ : Driver(),
7
+ InterruptHandler(dev->interrupt + interrupts->HardwareInterruptOffset (), interrupts),
8
+ MACAddress0Port(dev->portBase),
9
+ MACAddress2Port(dev->portBase + 0x02 ),
10
+ MACAddress4Port(dev->portBase + 0x04 ),
11
+ registerDataPort(dev->portBase + 0x10 ),
12
+ registerAddressPort(dev->portBase + 0x12 ),
13
+ resetPort(dev->portBase + 0x14 ),
14
+ busControlRegisterDataPort(dev->portBase + 0x16 )
15
+ {
16
+ currentSendBuffer = 0 ;
17
+ currentRecvBuffer = 0 ;
18
+
19
+ uint64_t MAC0 = MACAddress0Port.ReadFromPort () % 256 ;
20
+ uint64_t MAC1 = MACAddress0Port.ReadFromPort () / 256 ;
21
+ uint64_t MAC2 = MACAddress2Port.ReadFromPort () % 256 ;
22
+ uint64_t MAC3 = MACAddress2Port.ReadFromPort () / 256 ;
23
+ uint64_t MAC4 = MACAddress4Port.ReadFromPort () % 256 ;
24
+ uint64_t MAC5 = MACAddress4Port.ReadFromPort () / 256 ;
25
+
26
+ uint64_t MAC = MAC5 << 40 | MAC4 << 32 | MAC3 << 24 | MAC2 << 16 | MAC1 << 8 | MAC0;
27
+
28
+ registerAddressPort.WriteToPort (20 );
29
+ busControlRegisterDataPort.WriteToPort (0x102 );
30
+
31
+ registerAddressPort.WriteToPort (0 );
32
+ registerDataPort.WriteToPort (0x04 );
33
+
34
+ initBlock.mode = 0x0000 ; // promiscuous mode = false
35
+ initBlock.reserved1 = 0 ;
36
+ initBlock.numSendBuffers = 3 ;
37
+ initBlock.reserved2 = 0 ;
38
+ initBlock.numRecvBuffers = 3 ;
39
+ initBlock.physicalAddress = MAC;
40
+ initBlock.reserved3 = 0 ;
41
+ initBlock.logicalAddress = 0 ;
42
+
43
+ sendBufferDescr = (BufferDescriptor *)((((uint32_t )&sendBufferDescrMemory[0 ]) + 15 ) & ~((uint32_t )0xF ));
44
+ initBlock.sendBufferDescrAddress = (uint32_t )sendBufferDescr;
45
+ recvBufferDescr = (BufferDescriptor *)((((uint32_t )&recvBufferDescrMemory[0 ]) + 15 ) & ~((uint32_t )0xF ));
46
+ initBlock.recvBufferDescrAddress = (uint32_t )recvBufferDescr;
47
+
48
+ for (uint8_t i = 0 ; i < 8 ; i++)
49
+ {
50
+ sendBufferDescr[i].address = (((uint32_t )&sendBuffers[i]) + 15 ) & ~(uint32_t )0xF ;
51
+ sendBufferDescr[i].flags = 0x7FF | 0xF000 ;
52
+ sendBufferDescr[i].flags2 = 0 ;
53
+ sendBufferDescr[i].avail = 0 ;
54
+
55
+ recvBufferDescr[i].address = (((uint32_t )&recvBuffers[i]) + 15 ) & ~(uint32_t )0xF ;
56
+ recvBufferDescr[i].flags = 0xF7FF | 0x80000000 ;
57
+ recvBufferDescr[i].flags2 = 0 ;
58
+ sendBufferDescr[i].avail = 0 ;
59
+ }
60
+
61
+ registerAddressPort.WriteToPort (1 );
62
+ registerDataPort.WriteToPort ((uint32_t )(&initBlock) & 0xFFFF );
63
+ registerAddressPort.WriteToPort (2 );
64
+ registerDataPort.WriteToPort (((uint32_t )(&initBlock) >> 16 ) & 0xFFFF );
65
+ }
66
+
67
+ AM79C973::~AM79C973 ()
68
+ {
69
+ }
70
+
71
+ void AM79C973::activate ()
72
+ {
73
+ registerAddressPort.WriteToPort (0 );
74
+ registerDataPort.WriteToPort (0x41 );
75
+
76
+ registerAddressPort.WriteToPort (4 );
77
+ uint32_t temp = registerDataPort.ReadFromPort ();
78
+ registerAddressPort.WriteToPort (4 );
79
+ registerDataPort.WriteToPort (temp | 0xC00 );
80
+
81
+ registerAddressPort.WriteToPort (0 );
82
+ registerDataPort.WriteToPort (0x42 );
83
+ }
84
+
85
+ int AM79C973::reset ()
86
+ {
87
+ resetPort.ReadFromPort ();
88
+ resetPort.WriteToPort (0 );
89
+ return 10 ;
90
+ }
91
+
92
+ void printf (char *);
93
+
94
+ uint32_t AM79C973::HandleInterrupt (uint32_t esp)
95
+ {
96
+ printf (" AM79C973: Interrupt\n " );
97
+
98
+ registerAddressPort.WriteToPort (0 );
99
+ uint32_t temp = registerDataPort.ReadFromPort ();
100
+
101
+ if ((temp & 0x8000 ) == 0x8000 )
102
+ printf (" AM79c973 ERROR\n " );
103
+ if ((temp & 0x2000 ) == 0x2000 )
104
+ printf (" AM79c973 COLLISION ERROR\n " );
105
+ if ((temp & 0x1000 ) == 0x1000 )
106
+ printf (" AM79c973 MISSED FRAME\n " );
107
+ if ((temp & 0x0800 ) == 0x0800 )
108
+ printf (" AM79c973 MEMORY ERROR\n " );
109
+ if ((temp & 0x0400 ) == 0x0400 )
110
+ receive ();
111
+ if ((temp & 0x0200 ) == 0x0200 )
112
+ printf (" AM79c973 DATA SENT\n " );
113
+
114
+ registerAddressPort.WriteToPort (0 );
115
+ registerDataPort.WriteToPort (temp);
116
+
117
+ if ((temp & 0x0200 ) == 0x0200 )
118
+ printf (" AM79c973 INIT DONE\n " );
119
+
120
+ return esp;
121
+ }
122
+
123
+ void AM79C973::send (uint8_t *buffer, int size)
124
+ {
125
+ int sendDescriptor = currentSendBuffer;
126
+ currentSendBuffer = (currentSendBuffer + 1 ) % 8 ;
127
+
128
+ if (size > 1518 )
129
+ size = 1518 ;
130
+
131
+ for (uint8_t *src = buffer + size - 1 ,*dst = (uint8_t *)(sendBufferDescr[sendDescriptor].address + size - 1 );src >= buffer; src--, dst--)
132
+ *dst = *src;
133
+
134
+ sendBufferDescr[sendDescriptor].avail = 0 ;
135
+ sendBufferDescr[sendDescriptor].flags2 = 0 ;
136
+ sendBufferDescr[sendDescriptor].flags = 0x8300F000 | ((uint16_t )((-size) & 0xFFF ));
137
+ registerAddressPort.WriteToPort (0 );
138
+ registerDataPort.WriteToPort (0x48 );
139
+ }
140
+
141
+ void AM79C973::receive ()
142
+ {
143
+ printf (" AM79c973 DATA RECEIVED\n " );
144
+
145
+ for (; (recvBufferDescr[currentRecvBuffer].flags & 0x80000000 ) == 0 ;currentRecvBuffer = (currentRecvBuffer + 1 ) % 8 )
146
+ {
147
+ if (!(recvBufferDescr[currentRecvBuffer].flags & 0x40000000 ) && (recvBufferDescr[currentRecvBuffer].flags & 0x03000000 ) == 0x03000000 )
148
+
149
+ {
150
+ uint32_t size = recvBufferDescr[currentRecvBuffer].flags & 0xFFF ;
151
+ if (size > 64 )
152
+ size -= 4 ;
153
+
154
+ uint8_t *buffer = (uint8_t *)(recvBufferDescr[currentRecvBuffer].address );
155
+
156
+ for (int i = 0 ; i < size; i++)
157
+ {
158
+ printHex (buffer[i]);
159
+ printf (" " );
160
+ }
161
+ }
162
+
163
+ recvBufferDescr[currentRecvBuffer].flags2 = 0 ;
164
+ recvBufferDescr[currentRecvBuffer].flags = 0x8000F7FF ;
165
+ }
166
+ }
0 commit comments