6 /* MIPSnet register offsets */
8 #define MIPSNET_DEV_ID 0x00
9 #define MIPSNET_BUSY 0x08
10 #define MIPSNET_RX_DATA_COUNT 0x0c
11 #define MIPSNET_TX_DATA_COUNT 0x10
12 #define MIPSNET_INT_CTL 0x14
13 # define MIPSNET_INTCTL_TXDONE 0x00000001
14 # define MIPSNET_INTCTL_RXDONE 0x00000002
15 # define MIPSNET_INTCTL_TESTBIT 0x80000000
16 #define MIPSNET_INTERRUPT_INFO 0x18
17 #define MIPSNET_RX_DATA_BUFFER 0x1c
18 #define MIPSNET_TX_DATA_BUFFER 0x20
20 #define MAX_ETH_FRAME_SIZE 1514
22 typedef struct MIPSnetState
{
31 uint8_t rx_buffer
[MAX_ETH_FRAME_SIZE
];
32 uint8_t tx_buffer
[MAX_ETH_FRAME_SIZE
];
39 static void mipsnet_reset(MIPSnetState
*s
)
47 memset(s
->rx_buffer
, 0, MAX_ETH_FRAME_SIZE
);
48 memset(s
->tx_buffer
, 0, MAX_ETH_FRAME_SIZE
);
51 static void mipsnet_update_irq(MIPSnetState
*s
)
53 int isr
= !!s
->intctl
;
54 trace_mipsnet_irq(isr
, s
->intctl
);
55 qemu_set_irq(s
->irq
, isr
);
58 static int mipsnet_buffer_full(MIPSnetState
*s
)
60 if (s
->rx_count
>= MAX_ETH_FRAME_SIZE
)
65 static int mipsnet_can_receive(VLANClientState
*nc
)
67 MIPSnetState
*s
= DO_UPCAST(NICState
, nc
, nc
)->opaque
;
71 return !mipsnet_buffer_full(s
);
74 static ssize_t
mipsnet_receive(VLANClientState
*nc
, const uint8_t *buf
, size_t size
)
76 MIPSnetState
*s
= DO_UPCAST(NICState
, nc
, nc
)->opaque
;
78 trace_mipsnet_receive(size
);
79 if (!mipsnet_can_receive(nc
))
84 /* Just accept everything. */
86 /* Write packet data. */
87 memcpy(s
->rx_buffer
, buf
, size
);
92 /* Now we can signal we have received something. */
93 s
->intctl
|= MIPSNET_INTCTL_RXDONE
;
94 mipsnet_update_irq(s
);
99 static uint64_t mipsnet_ioport_read(void *opaque
, target_phys_addr_t addr
,
102 MIPSnetState
*s
= opaque
;
108 ret
= be32_to_cpu(0x4d495053); /* MIPS */
110 case MIPSNET_DEV_ID
+ 4:
111 ret
= be32_to_cpu(0x4e455430); /* NET0 */
116 case MIPSNET_RX_DATA_COUNT
:
119 case MIPSNET_TX_DATA_COUNT
:
122 case MIPSNET_INT_CTL
:
124 s
->intctl
&= ~MIPSNET_INTCTL_TESTBIT
;
126 case MIPSNET_INTERRUPT_INFO
:
127 /* XXX: This seems to be a per-VPE interrupt number. */
130 case MIPSNET_RX_DATA_BUFFER
:
133 ret
= s
->rx_buffer
[s
->rx_read
++];
137 case MIPSNET_TX_DATA_BUFFER
:
141 trace_mipsnet_read(addr
, ret
);
145 static void mipsnet_ioport_write(void *opaque
, target_phys_addr_t addr
,
146 uint64_t val
, unsigned int size
)
148 MIPSnetState
*s
= opaque
;
151 trace_mipsnet_write(addr
, val
);
153 case MIPSNET_TX_DATA_COUNT
:
154 s
->tx_count
= (val
<= MAX_ETH_FRAME_SIZE
) ? val
: 0;
157 case MIPSNET_INT_CTL
:
158 if (val
& MIPSNET_INTCTL_TXDONE
) {
159 s
->intctl
&= ~MIPSNET_INTCTL_TXDONE
;
160 } else if (val
& MIPSNET_INTCTL_RXDONE
) {
161 s
->intctl
&= ~MIPSNET_INTCTL_RXDONE
;
162 } else if (val
& MIPSNET_INTCTL_TESTBIT
) {
164 s
->intctl
|= MIPSNET_INTCTL_TESTBIT
;
166 /* ACK testbit interrupt, flag was cleared on read. */
168 s
->busy
= !!s
->intctl
;
169 mipsnet_update_irq(s
);
171 case MIPSNET_TX_DATA_BUFFER
:
172 s
->tx_buffer
[s
->tx_written
++] = val
;
173 if (s
->tx_written
== s
->tx_count
) {
175 trace_mipsnet_send(s
->tx_count
);
176 qemu_send_packet(&s
->nic
->nc
, s
->tx_buffer
, s
->tx_count
);
177 s
->tx_count
= s
->tx_written
= 0;
178 s
->intctl
|= MIPSNET_INTCTL_TXDONE
;
180 mipsnet_update_irq(s
);
183 /* Read-only registers */
186 case MIPSNET_RX_DATA_COUNT
:
187 case MIPSNET_INTERRUPT_INFO
:
188 case MIPSNET_RX_DATA_BUFFER
:
194 static const VMStateDescription vmstate_mipsnet
= {
197 .minimum_version_id
= 0,
198 .minimum_version_id_old
= 0,
199 .fields
= (VMStateField
[]) {
200 VMSTATE_UINT32(busy
, MIPSnetState
),
201 VMSTATE_UINT32(rx_count
, MIPSnetState
),
202 VMSTATE_UINT32(rx_read
, MIPSnetState
),
203 VMSTATE_UINT32(tx_count
, MIPSnetState
),
204 VMSTATE_UINT32(tx_written
, MIPSnetState
),
205 VMSTATE_UINT32(intctl
, MIPSnetState
),
206 VMSTATE_BUFFER(rx_buffer
, MIPSnetState
),
207 VMSTATE_BUFFER(tx_buffer
, MIPSnetState
),
208 VMSTATE_END_OF_LIST()
212 static void mipsnet_cleanup(VLANClientState
*nc
)
214 MIPSnetState
*s
= DO_UPCAST(NICState
, nc
, nc
)->opaque
;
219 static NetClientInfo net_mipsnet_info
= {
220 .type
= NET_CLIENT_TYPE_NIC
,
221 .size
= sizeof(NICState
),
222 .can_receive
= mipsnet_can_receive
,
223 .receive
= mipsnet_receive
,
224 .cleanup
= mipsnet_cleanup
,
227 static MemoryRegionOps mipsnet_ioport_ops
= {
228 .read
= mipsnet_ioport_read
,
229 .write
= mipsnet_ioport_write
,
230 .impl
.min_access_size
= 1,
231 .impl
.max_access_size
= 4,
234 static int mipsnet_sysbus_init(SysBusDevice
*dev
)
236 MIPSnetState
*s
= DO_UPCAST(MIPSnetState
, busdev
, dev
);
238 memory_region_init_io(&s
->io
, &mipsnet_ioport_ops
, s
, "mipsnet-io", 36);
239 sysbus_init_mmio(dev
, &s
->io
);
240 sysbus_init_irq(dev
, &s
->irq
);
242 s
->nic
= qemu_new_nic(&net_mipsnet_info
, &s
->conf
,
243 dev
->qdev
.info
->name
, dev
->qdev
.id
, s
);
244 qemu_format_nic_info_str(&s
->nic
->nc
, s
->conf
.macaddr
.a
);
249 static void mipsnet_sysbus_reset(DeviceState
*dev
)
251 MIPSnetState
*s
= DO_UPCAST(MIPSnetState
, busdev
.qdev
, dev
);
255 static SysBusDeviceInfo mipsnet_info
= {
256 .init
= mipsnet_sysbus_init
,
257 .qdev
.name
= "mipsnet",
258 .qdev
.desc
= "MIPS Simulator network device",
259 .qdev
.size
= sizeof(MIPSnetState
),
260 .qdev
.vmsd
= &vmstate_mipsnet
,
261 .qdev
.reset
= mipsnet_sysbus_reset
,
262 .qdev
.props
= (Property
[]) {
263 DEFINE_NIC_PROPERTIES(MIPSnetState
, conf
),
264 DEFINE_PROP_END_OF_LIST(),
268 static void mipsnet_register_devices(void)
270 sysbus_register_withprop(&mipsnet_info
);
273 device_init(mipsnet_register_devices
)