1 #include "qemu/osdep.h" 2 #include "hw/hw.h" 3 #include "hw/irq.h" 4 #include "net/net.h" 5 #include "qemu/module.h" 6 #include "trace.h" 7 #include "hw/sysbus.h" 8 9 /* MIPSnet register offsets */ 10 11 #define MIPSNET_DEV_ID 0x00 12 #define MIPSNET_BUSY 0x08 13 #define MIPSNET_RX_DATA_COUNT 0x0c 14 #define MIPSNET_TX_DATA_COUNT 0x10 15 #define MIPSNET_INT_CTL 0x14 16 # define MIPSNET_INTCTL_TXDONE 0x00000001 17 # define MIPSNET_INTCTL_RXDONE 0x00000002 18 # define MIPSNET_INTCTL_TESTBIT 0x80000000 19 #define MIPSNET_INTERRUPT_INFO 0x18 20 #define MIPSNET_RX_DATA_BUFFER 0x1c 21 #define MIPSNET_TX_DATA_BUFFER 0x20 22 23 #define MAX_ETH_FRAME_SIZE 1514 24 25 #define TYPE_MIPS_NET "mipsnet" 26 #define MIPS_NET(obj) OBJECT_CHECK(MIPSnetState, (obj), TYPE_MIPS_NET) 27 28 typedef struct MIPSnetState { 29 SysBusDevice parent_obj; 30 31 uint32_t busy; 32 uint32_t rx_count; 33 uint32_t rx_read; 34 uint32_t tx_count; 35 uint32_t tx_written; 36 uint32_t intctl; 37 uint8_t rx_buffer[MAX_ETH_FRAME_SIZE]; 38 uint8_t tx_buffer[MAX_ETH_FRAME_SIZE]; 39 MemoryRegion io; 40 qemu_irq irq; 41 NICState *nic; 42 NICConf conf; 43 } MIPSnetState; 44 45 static void mipsnet_reset(MIPSnetState *s) 46 { 47 s->busy = 1; 48 s->rx_count = 0; 49 s->rx_read = 0; 50 s->tx_count = 0; 51 s->tx_written = 0; 52 s->intctl = 0; 53 memset(s->rx_buffer, 0, MAX_ETH_FRAME_SIZE); 54 memset(s->tx_buffer, 0, MAX_ETH_FRAME_SIZE); 55 } 56 57 static void mipsnet_update_irq(MIPSnetState *s) 58 { 59 int isr = !!s->intctl; 60 trace_mipsnet_irq(isr, s->intctl); 61 qemu_set_irq(s->irq, isr); 62 } 63 64 static int mipsnet_buffer_full(MIPSnetState *s) 65 { 66 if (s->rx_count >= MAX_ETH_FRAME_SIZE) 67 return 1; 68 return 0; 69 } 70 71 static int mipsnet_can_receive(NetClientState *nc) 72 { 73 MIPSnetState *s = qemu_get_nic_opaque(nc); 74 75 if (s->busy) 76 return 0; 77 return !mipsnet_buffer_full(s); 78 } 79 80 static ssize_t mipsnet_receive(NetClientState *nc, const uint8_t *buf, size_t size) 81 { 82 MIPSnetState *s = qemu_get_nic_opaque(nc); 83 84 trace_mipsnet_receive(size); 85 if (!mipsnet_can_receive(nc)) 86 return 0; 87 88 if (size >= sizeof(s->rx_buffer)) { 89 return 0; 90 } 91 s->busy = 1; 92 93 /* Just accept everything. */ 94 95 /* Write packet data. */ 96 memcpy(s->rx_buffer, buf, size); 97 98 s->rx_count = size; 99 s->rx_read = 0; 100 101 /* Now we can signal we have received something. */ 102 s->intctl |= MIPSNET_INTCTL_RXDONE; 103 mipsnet_update_irq(s); 104 105 return size; 106 } 107 108 static uint64_t mipsnet_ioport_read(void *opaque, hwaddr addr, 109 unsigned int size) 110 { 111 MIPSnetState *s = opaque; 112 int ret = 0; 113 114 addr &= 0x3f; 115 switch (addr) { 116 case MIPSNET_DEV_ID: 117 ret = be32_to_cpu(0x4d495053); /* MIPS */ 118 break; 119 case MIPSNET_DEV_ID + 4: 120 ret = be32_to_cpu(0x4e455430); /* NET0 */ 121 break; 122 case MIPSNET_BUSY: 123 ret = s->busy; 124 break; 125 case MIPSNET_RX_DATA_COUNT: 126 ret = s->rx_count; 127 break; 128 case MIPSNET_TX_DATA_COUNT: 129 ret = s->tx_count; 130 break; 131 case MIPSNET_INT_CTL: 132 ret = s->intctl; 133 s->intctl &= ~MIPSNET_INTCTL_TESTBIT; 134 break; 135 case MIPSNET_INTERRUPT_INFO: 136 /* XXX: This seems to be a per-VPE interrupt number. */ 137 ret = 0; 138 break; 139 case MIPSNET_RX_DATA_BUFFER: 140 if (s->rx_count) { 141 s->rx_count--; 142 ret = s->rx_buffer[s->rx_read++]; 143 if (mipsnet_can_receive(s->nic->ncs)) { 144 qemu_flush_queued_packets(qemu_get_queue(s->nic)); 145 } 146 } 147 break; 148 /* Reads as zero. */ 149 case MIPSNET_TX_DATA_BUFFER: 150 default: 151 break; 152 } 153 trace_mipsnet_read(addr, ret); 154 return ret; 155 } 156 157 static void mipsnet_ioport_write(void *opaque, hwaddr addr, 158 uint64_t val, unsigned int size) 159 { 160 MIPSnetState *s = opaque; 161 162 addr &= 0x3f; 163 trace_mipsnet_write(addr, val); 164 switch (addr) { 165 case MIPSNET_TX_DATA_COUNT: 166 s->tx_count = (val <= MAX_ETH_FRAME_SIZE) ? val : 0; 167 s->tx_written = 0; 168 break; 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) { 175 mipsnet_reset(s); 176 s->intctl |= MIPSNET_INTCTL_TESTBIT; 177 } else if (!val) { 178 /* ACK testbit interrupt, flag was cleared on read. */ 179 } 180 s->busy = !!s->intctl; 181 mipsnet_update_irq(s); 182 if (mipsnet_can_receive(s->nic->ncs)) { 183 qemu_flush_queued_packets(qemu_get_queue(s->nic)); 184 } 185 break; 186 case MIPSNET_TX_DATA_BUFFER: 187 s->tx_buffer[s->tx_written++] = val; 188 if ((s->tx_written >= MAX_ETH_FRAME_SIZE) 189 || (s->tx_written == s->tx_count)) { 190 /* Send buffer. */ 191 trace_mipsnet_send(s->tx_written); 192 qemu_send_packet(qemu_get_queue(s->nic), 193 s->tx_buffer, s->tx_written); 194 s->tx_count = s->tx_written = 0; 195 s->intctl |= MIPSNET_INTCTL_TXDONE; 196 s->busy = 1; 197 mipsnet_update_irq(s); 198 } 199 break; 200 /* Read-only registers */ 201 case MIPSNET_DEV_ID: 202 case MIPSNET_BUSY: 203 case MIPSNET_RX_DATA_COUNT: 204 case MIPSNET_INTERRUPT_INFO: 205 case MIPSNET_RX_DATA_BUFFER: 206 default: 207 break; 208 } 209 } 210 211 static const VMStateDescription vmstate_mipsnet = { 212 .name = "mipsnet", 213 .version_id = 0, 214 .minimum_version_id = 0, 215 .fields = (VMStateField[]) { 216 VMSTATE_UINT32(busy, MIPSnetState), 217 VMSTATE_UINT32(rx_count, MIPSnetState), 218 VMSTATE_UINT32(rx_read, MIPSnetState), 219 VMSTATE_UINT32(tx_count, MIPSnetState), 220 VMSTATE_UINT32(tx_written, MIPSnetState), 221 VMSTATE_UINT32(intctl, MIPSnetState), 222 VMSTATE_BUFFER(rx_buffer, MIPSnetState), 223 VMSTATE_BUFFER(tx_buffer, MIPSnetState), 224 VMSTATE_END_OF_LIST() 225 } 226 }; 227 228 static NetClientInfo net_mipsnet_info = { 229 .type = NET_CLIENT_DRIVER_NIC, 230 .size = sizeof(NICState), 231 .receive = mipsnet_receive, 232 }; 233 234 static const MemoryRegionOps mipsnet_ioport_ops = { 235 .read = mipsnet_ioport_read, 236 .write = mipsnet_ioport_write, 237 .impl.min_access_size = 1, 238 .impl.max_access_size = 4, 239 }; 240 241 static void mipsnet_realize(DeviceState *dev, Error **errp) 242 { 243 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 244 MIPSnetState *s = MIPS_NET(dev); 245 246 memory_region_init_io(&s->io, OBJECT(dev), &mipsnet_ioport_ops, s, 247 "mipsnet-io", 36); 248 sysbus_init_mmio(sbd, &s->io); 249 sysbus_init_irq(sbd, &s->irq); 250 251 s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf, 252 object_get_typename(OBJECT(dev)), dev->id, s); 253 qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); 254 } 255 256 static void mipsnet_sysbus_reset(DeviceState *dev) 257 { 258 MIPSnetState *s = MIPS_NET(dev); 259 mipsnet_reset(s); 260 } 261 262 static Property mipsnet_properties[] = { 263 DEFINE_NIC_PROPERTIES(MIPSnetState, conf), 264 DEFINE_PROP_END_OF_LIST(), 265 }; 266 267 static void mipsnet_class_init(ObjectClass *klass, void *data) 268 { 269 DeviceClass *dc = DEVICE_CLASS(klass); 270 271 dc->realize = mipsnet_realize; 272 set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); 273 dc->desc = "MIPS Simulator network device"; 274 dc->reset = mipsnet_sysbus_reset; 275 dc->vmsd = &vmstate_mipsnet; 276 dc->props = mipsnet_properties; 277 } 278 279 static const TypeInfo mipsnet_info = { 280 .name = TYPE_MIPS_NET, 281 .parent = TYPE_SYS_BUS_DEVICE, 282 .instance_size = sizeof(MIPSnetState), 283 .class_init = mipsnet_class_init, 284 }; 285 286 static void mipsnet_register_types(void) 287 { 288 type_register_static(&mipsnet_info); 289 } 290 291 type_init(mipsnet_register_types) 292