dev_rtl8139c.cc Source File
Back to the index.
src
devices
dev_rtl8139c.cc
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2007-2009 Anders Gavare. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
6
*
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
12
* 3. The name of the author may not be used to endorse or promote products
13
* derived from this software without specific prior written permission.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*
27
*
28
* COMMENT: Realtek 8139 ethernet controller
29
*
30
* TODO: Pretty much everything.
31
*/
32
33
#include <stdio.h>
34
#include <stdlib.h>
35
#include <string.h>
36
37
#include "
cpu.h
"
38
#include "
device.h
"
39
#include "
emul.h
"
40
#include "
interrupt.h
"
41
#include "
machine.h
"
42
#include "
memory.h
"
43
#include "
misc.h
"
44
#include "
net.h
"
45
46
#include "
thirdparty/rtl81x9reg.h
"
47
48
49
#define DEV_RTL8139C_LENGTH 0x100
50
#define EEPROM_SIZE 0x100
51
52
struct
rtl8139c_data
{
53
struct
interrupt
irq
;
54
unsigned
char
macaddr
[6];
55
56
/* Registers: */
57
uint8_t
rl_command
;
58
uint8_t
rl_eecmd
;
59
60
/* EEPROM: */
61
int
eeprom_address_width
;
62
int
eeprom_selected
;
63
int8_t
eeprom_cur_cmd_bit
;
64
uint16_t
eeprom_cur_cmd
;
65
uint16_t
eeprom_cur_data
;
66
uint16_t
eeprom_reg
[
EEPROM_SIZE
];
67
};
68
69
70
/*
71
* eeprom_clk():
72
*
73
* Called whenever the eeprom CLK bit is toggled from 0 to 1.
74
*/
75
static
void
eeprom_clk(
struct
rtl8139c_data
*d)
76
{
77
int
data_in = d->
rl_eecmd
&
RL_EE_DATAIN
? 1 : 0;
78
79
if
(d->
eeprom_cur_cmd_bit
< d->
eeprom_address_width
+ 4) {
80
d->
eeprom_cur_cmd
<<= 1;
81
d->
eeprom_cur_cmd
|= data_in;
82
}
83
84
if
(d->
eeprom_cur_cmd_bit
== d->
eeprom_address_width
+ 3) {
85
int
cmd
= d->
eeprom_cur_cmd
>> d->
eeprom_address_width
;
86
int
addr
= d->
eeprom_cur_cmd
& ((1<<d->
eeprom_address_width
)-1);
87
88
debug
(
"[ rtl8139c eeprom cmd=0x%x addr=0x%02x ]\n"
,
cmd
,
addr
);
89
90
switch
(
cmd
) {
91
92
case
RL_9346_READ
:
93
d->
eeprom_cur_data
= d->
eeprom_reg
[
addr
%
EEPROM_SIZE
];
94
break
;
95
96
default
:
fatal
(
"[ rtl8139c eeprom: only the read command has"
97
" been implemented. sorry. ]\n"
);
98
exit(1);
99
}
100
}
101
102
/* Data output: (Note: Only the READ command has been implemented.) */
103
if
(d->
eeprom_cur_cmd_bit
>= d->
eeprom_address_width
+ 4) {
104
int
cur_out_bit = d->
eeprom_cur_cmd_bit
-
105
(d->
eeprom_address_width
+ 4);
106
int
bit = d->
eeprom_cur_data
& (1 << (15-cur_out_bit));
107
108
if
(bit)
109
d->
rl_eecmd
|=
RL_EE_DATAOUT
;
110
else
111
d->
rl_eecmd
&= ~
RL_EE_DATAOUT
;
112
}
113
114
d->
eeprom_cur_cmd_bit
++;
115
116
if
(d->
eeprom_cur_cmd_bit
>= d->
eeprom_address_width
+ 4 + 16) {
117
d->
eeprom_cur_cmd
= 0;
118
d->
eeprom_cur_cmd_bit
= 0;
119
}
120
}
121
122
123
DEVICE_ACCESS
(rtl8139c)
124
{
125
struct
rtl8139c_data
*d = (
struct
rtl8139c_data
*) extra;
126
uint64_t idata = 0, odata = 0;
127
128
if
(writeflag ==
MEM_WRITE
)
129
idata =
memory_readmax64
(
cpu
,
data
, len);
130
131
switch
(relative_addr) {
132
133
case
RL_COMMAND
:
134
if
(writeflag ==
MEM_WRITE
) {
135
if
(idata &
RL_CMD_RESET
) {
136
/* Reset. TODO */
137
138
/* ... and then clear the reset bit: */
139
idata &= ~
RL_CMD_RESET
;
140
}
141
142
d->
rl_command
= idata;
143
}
else
{
144
odata = d->
rl_command
;
145
}
146
break
;
147
148
case
RL_EECMD
:
149
if
(writeflag ==
MEM_WRITE
) {
150
uint8_t old = d->
rl_eecmd
;
151
d->
rl_eecmd
= idata;
152
153
if
(!d->
eeprom_selected
&& d->
rl_eecmd
&
RL_EE_SEL
) {
154
/* Reset eeprom cmd bit state: */
155
d->
eeprom_cur_cmd
= 0;
156
d->
eeprom_cur_cmd_bit
= 0;
157
}
158
d->
eeprom_selected
= d->
rl_eecmd
&
RL_EE_SEL
;
159
160
if
(idata &
RL_EE_CLK
&& !(old &
RL_EE_CLK
))
161
eeprom_clk(d);
162
}
else
{
163
odata = d->
rl_eecmd
;
164
}
165
break
;
166
167
case
0x82:
168
/* Unknown address, but OpenBSD's re driver writes
169
a 0x01 to this address, in re_reset(). */
170
if
(writeflag ==
MEM_WRITE
) {
171
if
(idata != 0x01) {
172
fatal
(
"rtl8139c: unimplemented write to"
173
" register 0x82.\n"
);
174
exit(1);
175
}
176
}
177
break
;
178
179
default
:
if
(writeflag ==
MEM_WRITE
) {
180
fatal
(
"[ rtl8139c: unimplemented write to "
181
"offset 0x%x: data=0x%x ]\n"
, (
int
)
182
relative_addr, (
int
)idata);
183
}
else
{
184
fatal
(
"[ rtl8139c: unimplemented read from "
185
"offset 0x%x ]\n"
, (
int
)relative_addr);
186
}
187
exit(1);
188
}
189
190
if
(writeflag ==
MEM_READ
)
191
memory_writemax64
(
cpu
,
data
, len, odata);
192
193
return
1;
194
}
195
196
197
DEVINIT
(rtl8139c)
198
{
199
char
*name2;
200
size_t
nlen = 100;
201
struct
rtl8139c_data
*d;
202
203
CHECK_ALLOCATION
(d = (
struct
rtl8139c_data
*) malloc(
sizeof
(
struct
rtl8139c_data
)));
204
memset(d, 0,
sizeof
(
struct
rtl8139c_data
));
205
206
INTERRUPT_CONNECT
(
devinit
->
interrupt_path
, d->
irq
);
207
208
net_generate_unique_mac
(
devinit
->
machine
, d->
macaddr
);
209
210
/* TODO: eeprom address width = 6 on 8129? */
211
d->
eeprom_address_width
= 8;
212
d->
eeprom_reg
[0] = 0x8139;
213
d->
eeprom_reg
[7] = d->
macaddr
[0] + (d->
macaddr
[1] << 8);
214
d->
eeprom_reg
[8] = d->
macaddr
[2] + (d->
macaddr
[3] << 8);
215
d->
eeprom_reg
[9] = d->
macaddr
[4] + (d->
macaddr
[5] << 8);
216
217
CHECK_ALLOCATION
(name2 = (
char
*) malloc(nlen));
218
snprintf(name2, nlen,
"%s [%02x:%02x:%02x:%02x:%02x:%02x]"
,
219
devinit
->
name
, d->
macaddr
[0], d->
macaddr
[1], d->
macaddr
[2],
220
d->
macaddr
[3], d->
macaddr
[4], d->
macaddr
[5]);
221
222
memory_device_register
(
devinit
->
machine
->
memory
, name2,
223
devinit
->
addr
,
DEV_RTL8139C_LENGTH
, dev_rtl8139c_access, (
void
*)d,
224
DM_DEFAULT
, NULL);
225
226
net_add_nic
(
devinit
->
machine
->
emul
->
net
, d, d->macaddr);
227
228
return
1;
229
}
230
data
u_short data
Definition:
siireg.h:79
DEV_RTL8139C_LENGTH
#define DEV_RTL8139C_LENGTH
Definition:
dev_rtl8139c.cc:49
INTERRUPT_CONNECT
#define INTERRUPT_CONNECT(name, istruct)
Definition:
interrupt.h:77
debug
#define debug
Definition:
dev_adb.cc:57
rtl8139c_data
Definition:
dev_rtl8139c.cc:52
machine::emul
struct emul * emul
Definition:
machine.h:99
EEPROM_SIZE
#define EEPROM_SIZE
Definition:
dev_rtl8139c.cc:50
RL_EE_DATAOUT
#define RL_EE_DATAOUT
Definition:
rtl81x9reg.h:302
devinit::addr
uint64_t addr
Definition:
device.h:46
memory_device_register
void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
Definition:
memory.cc:339
RL_CMD_RESET
#define RL_CMD_RESET
Definition:
rtl81x9reg.h:297
MEM_READ
#define MEM_READ
Definition:
memory.h:116
DM_DEFAULT
#define DM_DEFAULT
Definition:
memory.h:130
devinit::machine
struct machine * machine
Definition:
device.h:41
addr
uint32_t addr
Definition:
tmp_arm_multi.cc:52
device.h
rtl8139c_data::eeprom_selected
int eeprom_selected
Definition:
dev_rtl8139c.cc:62
rtl8139c_data::eeprom_cur_cmd_bit
int8_t eeprom_cur_cmd_bit
Definition:
dev_rtl8139c.cc:63
cmd
Definition:
debugger_cmds.cc:1189
rtl8139c_data::rl_eecmd
uint8_t rl_eecmd
Definition:
dev_rtl8139c.cc:58
MEM_WRITE
#define MEM_WRITE
Definition:
memory.h:117
DEVICE_ACCESS
DEVICE_ACCESS(rtl8139c)
Definition:
dev_rtl8139c.cc:123
devinit::interrupt_path
char * interrupt_path
Definition:
device.h:50
RL_EE_SEL
#define RL_EE_SEL
Definition:
rtl81x9reg.h:305
interrupt.h
fatal
void fatal(const char *fmt,...)
Definition:
main.cc:152
misc.h
RL_EE_DATAIN
#define RL_EE_DATAIN
Definition:
rtl81x9reg.h:303
memory_readmax64
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
Definition:
memory.cc:55
rtl8139c_data::eeprom_address_width
int eeprom_address_width
Definition:
dev_rtl8139c.cc:61
RL_9346_READ
#define RL_9346_READ
Definition:
rtl81x9reg.h:316
machine.h
rtl8139c_data::eeprom_cur_data
uint16_t eeprom_cur_data
Definition:
dev_rtl8139c.cc:65
net_generate_unique_mac
void net_generate_unique_mac(struct machine *, unsigned char *macbuf)
Definition:
net_misc.cc:88
devinit::name
char * name
Definition:
device.h:43
emul.h
net_add_nic
void net_add_nic(struct net *net, void *extra, unsigned char *macaddr)
Definition:
net.cc:598
devinit
Definition:
device.h:40
cpu.h
rtl8139c_data::eeprom_reg
uint16_t eeprom_reg[EEPROM_SIZE]
Definition:
dev_rtl8139c.cc:66
rtl8139c_data::rl_command
uint8_t rl_command
Definition:
dev_rtl8139c.cc:57
emul::net
struct net * net
Definition:
emul.h:43
machine::memory
struct memory * memory
Definition:
machine.h:126
rtl8139c_data::macaddr
unsigned char macaddr[6]
Definition:
dev_rtl8139c.cc:54
rtl8139c_data::irq
struct interrupt irq
Definition:
dev_rtl8139c.cc:53
RL_EECMD
#define RL_EECMD
Definition:
rtl81x9reg.h:81
rtl8139c_data::eeprom_cur_cmd
uint16_t eeprom_cur_cmd
Definition:
dev_rtl8139c.cc:64
RL_EE_CLK
#define RL_EE_CLK
Definition:
rtl81x9reg.h:304
RL_COMMAND
#define RL_COMMAND
Definition:
rtl81x9reg.h:72
interrupt
Definition:
interrupt.h:36
memory_writemax64
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
Definition:
memory.cc:89
rtl81x9reg.h
cpu
Definition:
cpu.h:326
DEVINIT
DEVINIT(rtl8139c)
Definition:
dev_rtl8139c.cc:197
net.h
memory.h
CHECK_ALLOCATION
#define CHECK_ALLOCATION(ptr)
Definition:
misc.h:239
Generated on Tue Mar 24 2020 14:04:48 for GXemul by
1.8.17