5 //#define DEBUG_MIPSNET_SEND
6 //#define DEBUG_MIPSNET_RECEIVE
7 //#define DEBUG_MIPSNET_DATA
8 //#define DEBUG_MIPSNET_IRQ
10 /* MIPSnet register offsets */
12 #define MIPSNET_DEV_ID 0x00
13 #define MIPSNET_BUSY 0x08
14 #define MIPSNET_RX_DATA_COUNT 0x0c
15 #define MIPSNET_TX_DATA_COUNT 0x10
16 #define MIPSNET_INT_CTL 0x14
17 # define MIPSNET_INTCTL_TXDONE 0x00000001
18 # define MIPSNET_INTCTL_RXDONE 0x00000002
19 # define MIPSNET_INTCTL_TESTBIT 0x80000000
20 #define MIPSNET_INTERRUPT_INFO 0x18
21 #define MIPSNET_RX_DATA_BUFFER 0x1c
22 #define MIPSNET_TX_DATA_BUFFER 0x20
24 #define MAX_ETH_FRAME_SIZE 1514
26 typedef struct MIPSnetState
{
35 uint8_t rx_buffer
[MAX_ETH_FRAME_SIZE
];
36 uint8_t tx_buffer
[MAX_ETH_FRAME_SIZE
];
43 static void mipsnet_reset(MIPSnetState
*s
)
51 memset(s
->rx_buffer
, 0, MAX_ETH_FRAME_SIZE
);
52 memset(s
->tx_buffer
, 0, MAX_ETH_FRAME_SIZE
);
55 static void mipsnet_update_irq(MIPSnetState
*s
)
57 int isr
= !!s
->intctl
;
58 #ifdef DEBUG_MIPSNET_IRQ
59 printf("mipsnet: Set IRQ to %d (%02x)\n", isr
, s
->intctl
);
61 qemu_set_irq(s
->irq
, isr
);
64 static int mipsnet_buffer_full(MIPSnetState
*s
)
66 if (s
->rx_count
>= MAX_ETH_FRAME_SIZE
)
71 static int mipsnet_can_receive(VLANClientState
*nc
)
73 MIPSnetState
*s
= DO_UPCAST(NICState
, nc
, nc
)->opaque
;
77 return !mipsnet_buffer_full(s
);
80 static ssize_t
mipsnet_receive(VLANClientState
*nc
, const uint8_t *buf
, size_t size
)
82 MIPSnetState
*s
= DO_UPCAST(NICState
, nc
, nc
)->opaque
;
84 #ifdef DEBUG_MIPSNET_RECEIVE
85 printf("mipsnet: receiving len=%zu\n", size
);
87 if (!mipsnet_can_receive(nc
))
92 /* Just accept everything. */
94 /* Write packet data. */
95 memcpy(s
->rx_buffer
, buf
, size
);
100 /* Now we can signal we have received something. */
101 s
->intctl
|= MIPSNET_INTCTL_RXDONE
;
102 mipsnet_update_irq(s
);
107 static uint64_t mipsnet_ioport_read(void *opaque
, target_phys_addr_t addr
,
110 MIPSnetState
*s
= opaque
;
116 ret
= be32_to_cpu(0x4d495053); /* MIPS */
118 case MIPSNET_DEV_ID
+ 4:
119 ret
= be32_to_cpu(0x4e455430); /* NET0 */
124 case MIPSNET_RX_DATA_COUNT
:
127 case MIPSNET_TX_DATA_COUNT
:
130 case MIPSNET_INT_CTL
:
132 s
->intctl
&= ~MIPSNET_INTCTL_TESTBIT
;
134 case MIPSNET_INTERRUPT_INFO
:
135 /* XXX: This seems to be a per-VPE interrupt number. */
138 case MIPSNET_RX_DATA_BUFFER
:
141 ret
= s
->rx_buffer
[s
->rx_read
++];
145 case MIPSNET_TX_DATA_BUFFER
:
149 #ifdef DEBUG_MIPSNET_DATA
150 printf("mipsnet: read addr=0x%02x val=0x%02x\n", addr
, ret
);
155 static void mipsnet_ioport_write(void *opaque
, target_phys_addr_t addr
,
156 uint64_t val
, unsigned int size
)
158 MIPSnetState
*s
= opaque
;
161 #ifdef DEBUG_MIPSNET_DATA
162 printf("mipsnet: write addr=0x%02x val=0x%02x\n", addr
, val
);
165 case MIPSNET_TX_DATA_COUNT
:
166 s
->tx_count
= (val
<= MAX_ETH_FRAME_SIZE
) ? val
: 0;
169 case MIPSNET_INT_CTL
:
170 if (val
& MIPSNET_INTCTL_TXDONE
) {
171 s
->intctl
&= ~MIPSNET_INTCTL_TXDONE
;
172 } else if (val
& MIPSNET_INTCTL_RXDONE
) {
173 s
->intctl
&= ~MIPSNET_INTCTL_RXDONE
;
174 } else if (val
& MIPSNET_INTCTL_TESTBIT
) {
176 s
->intctl
|= MIPSNET_INTCTL_TESTBIT
;
178 /* ACK testbit interrupt, flag was cleared on read. */
180 s
->busy
= !!s
->intctl
;
181 mipsnet_update_irq(s
);
183 case MIPSNET_TX_DATA_BUFFER
:
184 s
->tx_buffer
[s
->tx_written
++] = val
;
185 if (s
->tx_written
== s
->tx_count
) {
187 #ifdef DEBUG_MIPSNET_SEND
188 printf("mipsnet: sending len=%d\n", s
->tx_count
);
190 qemu_send_packet(&s
->nic
->nc
, s
->tx_buffer
, s
->tx_count
);
191 s
->tx_count
= s
->tx_written
= 0;
192 s
->intctl
|= MIPSNET_INTCTL_TXDONE
;
194 mipsnet_update_irq(s
);
197 /* Read-only registers */
200 case MIPSNET_RX_DATA_COUNT
:
201 case MIPSNET_INTERRUPT_INFO
:
202 case MIPSNET_RX_DATA_BUFFER
:
208 static const VMStateDescription vmstate_mipsnet
= {
211 .minimum_version_id
= 0,
212 .minimum_version_id_old
= 0,
213 .fields
= (VMStateField
[]) {
214 VMSTATE_UINT32(busy
, MIPSnetState
),
215 VMSTATE_UINT32(rx_count
, MIPSnetState
),
216 VMSTATE_UINT32(rx_read
, MIPSnetState
),
217 VMSTATE_UINT32(tx_count
, MIPSnetState
),
218 VMSTATE_UINT32(tx_written
, MIPSnetState
),
219 VMSTATE_UINT32(intctl
, MIPSnetState
),
220 VMSTATE_BUFFER(rx_buffer
, MIPSnetState
),
221 VMSTATE_BUFFER(tx_buffer
, MIPSnetState
),
222 VMSTATE_END_OF_LIST()
226 static void mipsnet_cleanup(VLANClientState
*nc
)
228 MIPSnetState
*s
= DO_UPCAST(NICState
, nc
, nc
)->opaque
;
233 static NetClientInfo net_mipsnet_info
= {
234 .type
= NET_CLIENT_TYPE_NIC
,
235 .size
= sizeof(NICState
),
236 .can_receive
= mipsnet_can_receive
,
237 .receive
= mipsnet_receive
,
238 .cleanup
= mipsnet_cleanup
,
241 static MemoryRegionOps mipsnet_ioport_ops
= {
242 .read
= mipsnet_ioport_read
,
243 .write
= mipsnet_ioport_write
,
244 .impl
.min_access_size
= 1,
245 .impl
.max_access_size
= 4,
248 static int mipsnet_sysbus_init(SysBusDevice
*dev
)
250 MIPSnetState
*s
= DO_UPCAST(MIPSnetState
, busdev
, dev
);
252 memory_region_init_io(&s
->io
, &mipsnet_ioport_ops
, s
, "mipsnet-io", 36);
253 sysbus_init_mmio_region(dev
, &s
->io
);
254 sysbus_init_irq(dev
, &s
->irq
);
256 s
->nic
= qemu_new_nic(&net_mipsnet_info
, &s
->conf
,
257 dev
->qdev
.info
->name
, dev
->qdev
.id
, s
);
258 qemu_format_nic_info_str(&s
->nic
->nc
, s
->conf
.macaddr
.a
);
263 static void mipsnet_sysbus_reset(DeviceState
*dev
)
265 MIPSnetState
*s
= DO_UPCAST(MIPSnetState
, busdev
.qdev
, dev
);
269 static SysBusDeviceInfo mipsnet_info
= {
270 .init
= mipsnet_sysbus_init
,
271 .qdev
.name
= "mipsnet",
272 .qdev
.desc
= "MIPS Simulator network device",
273 .qdev
.size
= sizeof(MIPSnetState
),
274 .qdev
.vmsd
= &vmstate_mipsnet
,
275 .qdev
.reset
= mipsnet_sysbus_reset
,
276 .qdev
.props
= (Property
[]) {
277 DEFINE_NIC_PROPERTIES(MIPSnetState
, conf
),
278 DEFINE_PROP_END_OF_LIST(),
282 static void mipsnet_register_devices(void)
284 sysbus_register_withprop(&mipsnet_info
);
287 device_init(mipsnet_register_devices
)