2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2009, Lei Xia <lxia@northwestern.edu>
11 * Copyright (c) 2009, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Lei Xia <lxia@northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
21 * Virtual NE2K Network Card
24 #include <devices/vnic.h>
25 #include <palacios/vmm.h>
26 #include <palacios/vmm_types.h>
27 #include <palacios/vmm_io.h>
28 #include <palacios/vmm_debug.h>
34 #define PrintDebug(fmts, args...)
37 typedef enum {NIC_READY, NIC_REG_POSTED} nic_state_t;
61 uchar_t phys[6]; //mac address
63 uchar_t mult[8]; //multicast mask array
72 struct guest_info *vm;
74 nic_state_t dev_state;
78 uchar_t mac[6]; //the mac address of this nic
80 uchar_t mem[NE2K_MEM_SIZE];
83 struct vm_device *current_vnic;
85 #define compare_mac(src, dst) ({ \
86 ((src[0] == dst[0]) && \
87 (src[1] == dst[1]) && \
88 (src[2] == dst[2]) && \
89 (src[3] == dst[3]) && \
90 (src[4] == dst[4]) && \
91 (src[5] == dst[5]))? 1:0; \
94 static void dump_state(struct vm_device *dev)
98 struct nic_context *nic_state = (struct nic_context *)dev->private_data;
100 PrintDebug("====VNIC: Dumping state Begin ==========\n");
101 PrintDebug("Registers:\n");
103 p = (uchar_t *)&nic_state->regs;
104 for(i = 0; i < sizeof(struct nic_regs); i++)
105 PrintDebug("Regs[i] = 0x%2x\n", (int)p[i]);
107 PrintDebug("Memory:\n");
108 for(i = 0; i < 32; i++)
109 PrintDebug("0x%02x ", nic_state->mem[i]);
111 PrintDebug("====VNIC: Dumping state End==========\n");
114 static void vnic_update_irq(struct vm_device *dev)
117 struct nic_context *nic_state = (struct nic_context *)dev->private_data;
118 struct guest_info *guest = dev->vm;
120 isr = ((nic_state->regs.isr & nic_state->regs.imr) & 0x7f);
122 if ((isr & 0x7f) != 0x0) {
123 v3_raise_irq(guest, NIC_IRQ);
124 PrintDebug("VNIC: RaiseIrq: isr: 0x%02x imr: 0x%02x\n", nic_state->regs.isr, nic_state->regs.imr);
128 static void init_vnic_context(struct vm_device *dev)
130 struct nic_context *nic_state = (struct nic_context *)dev->private_data;
132 uchar_t mac[6] = {0x52, 0x54, 0x0, 0x12, 0x34, 0x56};
134 nic_state->vm = dev->vm;
136 nic_state->regs.isr = ENISR_RESET;
137 nic_state->regs.imr = 0x00;
138 nic_state->regs.cmd = 0x22;
140 for (i = 0; i < 6; i++)
141 nic_state->regs.macaddr[i] = nic_state->mac[i] = mac[i];
143 for (i = 0; i < 8; i++)
144 nic_state->regs.mult[i] = 0xff;
146 for(i = 0; i < 32; i++) {
147 nic_state->mem[i] = 0xff;
150 memcpy(nic_state->mem, nic_state->mac, 6);
151 nic_state->mem[14] = 0x57;
152 nic_state->mem[15] = 0x57;
157 static int vnic_send_packet(struct vm_device *dev, uchar_t *pkt, int length)
161 PrintDebug("\nVNIC: Sending Packet\n");
163 for (i = 0; i<length; i++)
164 PrintDebug("%x ",pkt[i]);
167 return V3_SEND_PKT(pkt, length);
171 struct vm_device * get_rx_dev(uchar_t *dst_mac)
173 struct nic_context *nic_state = (struct nic_context *)current_vnic->private_data;
174 struct nic_regs *nregs = &(nic_state->regs);
176 static const uchar_t brocast_mac[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
178 if (nregs->rcr & 0x10) {
181 if (compare_mac(dst_mac, brocast_mac)) { //broadcast address
182 if (!(nregs->rcr & 0x04))
184 } else if (dst_mac[0] & 0x01) {
185 // multicast packet, not fully done here
187 if (!(nregs->rcr & 0x08))
189 } else if (!compare_mac(dst_mac, nic_state->mac)) {
199 static int vnic_rxbuf_full(struct vm_device *dev)
201 int empty, index, boundary;
202 struct nic_context *nic_state = (struct nic_context *)dev->private_data;
204 index = nic_state->regs.curpag << 8;
205 boundary = nic_state->regs.boundary << 8;
206 if (index < boundary)
207 empty = boundary - index;
209 empty = ((nic_state->regs.pgstop - nic_state->regs.pgstart) << 8) - (index - boundary);
211 if (empty < (MAX_ETH_FRAME_SIZE + 4))
217 #define MIN_BUF_SIZE 60
219 static void vnic_receive(struct vm_device *dev, const uchar_t *pkt, int length)
221 struct nic_context *nic_state = (struct nic_context *)dev->private_data;
222 struct nic_regs *nregs = &(nic_state->regs);
224 uint32_t total_len, next, len, index, empty;
226 uint32_t start, stop;
229 //PrintDebug("VNIC: received packet, len=%d\n", length);
231 start = nregs->pgstart << 8;
232 stop = nregs->pgstop << 8;
234 if (nregs->cmd & NE2K_STOP)
237 if (vnic_rxbuf_full(dev)){
238 PrintDebug("VNIC: received buffer overflow\n");
242 // if too small buffer, expand it
243 if (length < MIN_BUF_SIZE) {
244 memcpy(buf, pkt, length);
245 memset(buf + length, 0, MIN_BUF_SIZE - length);
247 length = MIN_BUF_SIZE;
250 index = nregs->curpag << 8;
252 total_len = length + 4;
253 // address for next packet (4 bytes for CRC)
254 next = index + ((total_len + 4 + 255) & ~0xff);
256 next -= stop - start;
258 p = nic_state->mem + index;
259 nregs->rsr = ENRSR_RXOK;
262 nregs->rsr |= ENRSR_PHY;
267 p[3] = total_len >> 8;
272 empty = stop - index;
278 memcpy(nic_state->mem + index, pkt, len);
285 nregs->curpag = next >> 8;
287 nregs->isr |= ENISR_RX;
288 vnic_update_irq(dev);
293 void pci_vnic_init(PCIBus *bus, NICInfo *nd, int devfn)
298 struct pci_device *pdev;
300 pdev = pci_register_device(bus,
301 "NE2000", sizeof(PCINE2000State),
304 pci_conf = d->dev.config;
305 pci_conf[0x00] = 0xec; // Realtek 8029
306 pci_conf[0x01] = 0x10;
307 pci_conf[0x02] = 0x29;
308 pci_conf[0x03] = 0x80;
309 pci_conf[0x0a] = 0x00; // ethernet network controller
310 pci_conf[0x0b] = 0x02;
311 pci_conf[0x0e] = 0x00; // header_type
312 pci_conf[0x3d] = 1; // interrupt pin 0
314 pci_register_io_region(&d->dev, 0, 0x100,
315 PCI_ADDRESS_SPACE_IO, ne2000_map);
317 s->irq = d->dev.irq[0];
318 s->pci_dev = (PCIDevice *)d;
319 memcpy(s->macaddr, nd->macaddr, 6);
321 s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive,
322 ne2000_can_receive, s);
324 snprintf(s->vc->info_str, sizeof(s->vc->info_str),
325 "ne2000 pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
333 /* XXX: instance number ? */
334 register_savevm("ne2000", 0, 3, ne2000_save, ne2000_load, s);
337 //End Here====================================
339 static int netif_input(uchar_t * pkt, uint_t size)
342 struct vm_device *dev;
344 PrintDebug("\nVNIC: Packet Received:\nSource:");
345 for (i = 6; i < 12; i++) {
346 PrintDebug("%x ", pkt[i]);
349 dev = get_rx_dev(pkt);
355 for(i= 0; i<size; i++)
356 PrintDebug("%x ", pkt[i]);
358 vnic_receive(dev, pkt, size);
364 static int vnic_ioport_write(ushort_t port,
367 struct vm_device *dev)
370 struct nic_context *nic_state = (struct nic_context* )dev->private_data;
375 memcpy(&val, src, 1);
377 PrintDebug("vnic_write error: length %d\n", length);
383 PrintDebug("vnic_write: port:0x%x (%u bytes): 0x%x\n", port, length, (int)val);
385 if (port == EN0_COMMAND) {
386 nic_state->regs.cmd = val;
387 if (!(val & NE2K_STOP)) {
388 nic_state->regs.isr &= ~ENISR_RESET;
389 if ((val & (NE2K_DMAREAD | NE2K_DMAWRITE)) &&
390 nic_state->regs.rbcr == 0) {
391 nic_state->regs.isr |= ENISR_RDC;
392 vnic_update_irq(dev);
394 if (val & NE2K_TRANSMIT) {
395 index = (nic_state->regs.tpsr << 8);
396 if (index >= NE2K_PMEM_END)
397 index -= NE2K_PMEM_SIZE;
398 if (index + nic_state->regs.tbcr <= NE2K_PMEM_END) {
399 vnic_send_packet(dev, nic_state->mem + index, nic_state->regs.tbcr);
401 nic_state->regs.tsr = ENTSR_PTX;
402 nic_state->regs.isr |= ENISR_TX;
403 nic_state->regs.cmd &= ~NE2K_TRANSMIT;
404 vnic_update_irq(dev);
408 page = nic_state->regs.cmd >> 6;
412 nic_state->regs.pgstart = val;
415 nic_state->regs.pgstop = val;
418 nic_state->regs.boundary = val;
421 nic_state->regs.tpsr = val;
424 nic_state->regs.tbcr = (nic_state->regs.tbcr & 0xff00) | val;
427 nic_state->regs.tbcr = (nic_state->regs.tbcr & 0x00ff) | (val << 8);
430 nic_state->regs.isr &= ~(val & 0x7f);
431 vnic_update_irq(dev);
434 nic_state->regs.rsar = (nic_state->regs.rsar & 0xff00) | val;
437 nic_state->regs.rsar = (nic_state->regs.rsar & 0x00ff) | (val << 8);
440 nic_state->regs.rbcr = (nic_state->regs.rbcr & 0xff00) | val;
443 nic_state->regs.rbcr = (nic_state->regs.rbcr & 0x00ff) | (val << 8);
446 nic_state->regs.rcr = val;
449 nic_state->regs.tcr = val;
451 nic_state->regs.dcr = val;
454 nic_state->regs.imr = val;
455 vnic_update_irq(dev);
458 PrintDebug("vnic_write error: invalid port:0x%x\n", port);
464 case EN1_PHYS ... EN1_PHYS + 5:
465 nic_state->regs.phys[port - EN1_PHYS] = val;
468 nic_state->regs.curpag = val;
470 case EN1_MULT ... EN1_MULT + 7:
471 nic_state->regs.mult[port - EN1_MULT] = val;
474 PrintDebug("vnic_write error: invalid port:0x%x\n", port);
481 nic_state->regs.clda = (nic_state->regs.clda & 0xff00) | val;
484 nic_state->regs.clda = (nic_state->regs.clda & 0x00ff) | (val << 8);
487 nic_state->regs.rnpp = val;
490 nic_state->regs.lnpp = val;
493 nic_state->regs.addcnt = (nic_state->regs.addcnt & 0xff00) | val;
496 nic_state->regs.addcnt = (nic_state->regs.addcnt & 0x00ff) | (val << 8);
499 PrintDebug("vnic_write error: invalid port:0x%x\n", port);
511 static int vnic_ioport_read(ushort_t port,
514 struct vm_device *dev)
518 struct nic_context *nic_state = (struct nic_context* )dev->private_data;
521 PrintDebug("vnic_read error: length %d\n", length);
527 if (port == EN0_COMMAND) {
528 ret = nic_state->regs.cmd;
530 page = nic_state->regs.cmd >> 6;
534 ret = nic_state->regs.clda & 0x00ff;
537 ret = (nic_state->regs.clda & 0xff00) >> 8;
540 ret = nic_state->regs.boundary;
543 ret = nic_state->regs.tsr;
546 ret = nic_state->regs.ncr;
549 ret = nic_state->regs.fifo;
552 ret = nic_state->regs.isr;
553 vnic_update_irq(dev);
556 ret = nic_state->regs.crda & 0x00ff;
559 ret = (nic_state->regs.crda & 0xff00) >> 8;
562 ret = nic_state->regs.rsr;
565 ret = nic_state->regs.cntr & 0x000000ff;
568 ret = (nic_state->regs.cntr & 0x0000ff00) >> 8;
571 ret = (nic_state->regs.cntr & 0x00ff0000) >> 16;
574 PrintDebug("vnic_read error: invalid port:0x%x\n", port);
581 case EN1_PHYS ... EN1_PHYS + 5:
582 ret = nic_state->regs.phys[port - EN1_PHYS];
585 ret = nic_state->regs.curpag;
587 case EN1_MULT ... EN1_MULT + 7:
588 ret = nic_state->regs.mult[port - EN1_MULT];
591 PrintDebug("vnic_read error: invalid port:0x%x\n", port);
599 ret = nic_state->regs.pgstart;
602 ret = nic_state->regs.pgstop;
605 ret = nic_state->regs.rnpp;
608 ret = nic_state->regs.lnpp;
611 ret = nic_state->regs.tpsr;
614 ret = nic_state->regs.addcnt & 0x00ff;
617 ret = (nic_state->regs.addcnt & 0xff00) >> 8;
620 ret = nic_state->regs.rcr;
623 ret = nic_state->regs.tcr;
626 ret = nic_state->regs.dcr;
629 ret = nic_state->regs.imr;
632 PrintDebug("vnic_read error: invalid port:0x%x\n", port);
639 memcpy(dst, &ret, 1);
641 PrintDebug("vnic_read: port:0x%x (%u bytes): 0x%x\n", port,length, (int)ret);
649 static inline uint16_t cpu2le16(uint16_t val)
652 uchar_t *p1 = (uchar_t *)&p;
661 static inline uint32_t cpu2le32(uint32_t val)
664 uchar_t *p1 = (uchar_t *)&p;
674 static inline uint16_t le16_to_cpu(const uint16_t *p)
676 const uchar_t *p1 = (const uchar_t *)p;
677 return p1[0] | (p1[1] << 8);
680 static inline uint32_t le32_to_cpu(const uint32_t *p)
682 const uchar_t *p1 = (const uchar_t *)p;
683 return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
686 static void vnic_mem_writeb(struct nic_context *nic_state,
692 tmp = (uchar_t) (val & 0x000000ff);
693 if (addr < 32 || (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
694 nic_state->mem[addr] = tmp;
697 PrintDebug("wmem addr: %x val: %x\n", addr, val);
700 static void vnic_mem_writew(struct nic_context *nic_state,
704 addr &= ~1; //XXX: check exact behaviour if not even
706 (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
707 *(ushort_t *)(nic_state->mem + addr) = cpu2le16(val);
710 PrintDebug("wmem addr: %x val: %x\n", addr, val);
713 static void vnic_mem_writel(struct nic_context *nic_state,
717 addr &= ~1; // XXX: check exact behaviour if not even
719 (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
720 *(uint32_t *)(nic_state->mem + addr) = cpu2le32(val);
723 PrintDebug("wmem addr: %x val: %x\n", addr, val);
726 static uchar_t vnic_mem_readb(struct nic_context *nic_state, uint32_t addr)
728 PrintDebug("rmem addr: %x\n", addr);
731 (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
732 return nic_state->mem[addr];
738 static ushort_t vnic_mem_readw(struct nic_context *nic_state, uint32_t addr)
740 PrintDebug("rmem addr: %x\n", addr);
742 addr &= ~1; //XXX: check exact behaviour if not even
744 (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
745 return (ushort_t)le16_to_cpu((ushort_t *)(nic_state->mem + addr));
751 static uint32_t vnic_mem_readl(struct nic_context *nic_state, uint32_t addr)
753 PrintDebug("rmem addr: %x\n", addr);
755 addr &= ~1; //XXX: check exact behaviour if not even
757 (addr >= NE2K_PMEM_START && addr < NE2K_MEM_SIZE)) {
758 return (uint32_t)le32_to_cpu((uint32_t *)(nic_state->mem + addr));
764 static void vnic_dma_update(struct vm_device *dev, int len)
766 struct nic_context *nic_state = (struct nic_context *)dev->private_data;
768 nic_state->regs.rsar += len;
770 if (nic_state->regs.rsar == nic_state->regs.pgstop)
771 nic_state->regs.rsar = nic_state->regs.pgstart;
773 if (nic_state->regs.rbcr <= len) {
774 nic_state->regs.rbcr = 0;
775 nic_state->regs.isr |= ENISR_RDC;
776 vnic_update_irq(dev);
778 nic_state->regs.rbcr -= len;
783 //for data port read/write
784 static int vnic_data_read(ushort_t port,
787 struct vm_device *dev)
790 struct nic_context *nic_state = (struct nic_context *)dev->private_data;
792 // current dma address
793 uint32_t addr = nic_state->regs.rsar;
797 val = vnic_mem_readb(nic_state, addr);
800 val = vnic_mem_readw(nic_state, addr);
803 val = vnic_mem_readl(nic_state, addr);
806 PrintDebug("vnic_data_read error: invalid length %d\n", length);
810 vnic_dma_update(dev, length);
812 memcpy(dst, &val, length);
814 PrintDebug("vnic_read: port:0x%x (%u bytes): 0x%x", port & 0x1f,length, val);
819 static int vnic_data_write(ushort_t port,
822 struct vm_device *dev)
825 struct nic_context *nic_state = (struct nic_context *)dev->private_data;
827 uint32_t addr = nic_state->regs.rsar;
829 if (nic_state->regs.rbcr == 0)
832 memcpy(&val, src, length);
834 //determine the starting address of reading/writing
839 vnic_mem_writeb(nic_state, addr, val);
842 vnic_mem_writew(nic_state, addr, val);
845 vnic_mem_writel(nic_state, addr, val);
848 PrintDebug("nic_data_write error: invalid length %d\n", length);
851 vnic_dma_update(dev, length);
853 PrintDebug("vnic_write: port:0x%x (%u bytes): 0x%x\n", port & 0x1f,length, val);
858 static int vnic_reset_device(struct vm_device * dev)
861 PrintDebug("vnic: reset device\n");
863 init_vnic_context(dev);
870 static int vnic_reset_port_read(ushort_t port,
873 struct vm_device *dev)
877 memcpy(dst, &val, length);
879 PrintDebug("vnic_read: port:0x%x (%u bytes): 0x%x\n", port,length, val);
881 vnic_reset_device(dev);
886 static int vnic_reset_port_write(ushort_t port,
889 struct vm_device *dev)
893 memcpy(&val, src, length);
895 PrintDebug("vnic_write: port:0x%x (%u bytes): 0x%x\n", port,length, val);
901 static int vnic_start_device(struct vm_device *dev)
903 PrintDebug("vnic: start device\n");
909 static int vnic_stop_device(struct vm_device *dev)
911 PrintDebug("vnic: stop device\n");
916 static void init_phy_network()
919 V3_REGISTER_PKT_DELIVERY(&netif_input);
923 static int vnic_init_device(struct vm_device * dev)
927 PrintDebug("vnic: init_device\n");
930 init_vnic_context(dev);
934 for (i = 0; i < 16; i++){
935 v3_dev_hook_io(dev, NIC_BASE_ADDR + i, &vnic_ioport_read, &vnic_ioport_write);
937 v3_dev_hook_io(dev, NIC_BASE_ADDR + NIC_DATA_PORT, &vnic_data_read, &vnic_data_write);
938 v3_dev_hook_io(dev, NIC_BASE_ADDR + NIC_RESET_PORT, &vnic_reset_port_read, &vnic_reset_port_write);
945 static int vnic_deinit_device(struct vm_device *dev)
949 for (i = 0; i<16; i++){
950 v3_dev_unhook_io(dev, NIC_BASE_ADDR + i);
953 v3_dev_unhook_io(dev, NIC_BASE_ADDR + NIC_DATA_PORT);
954 v3_dev_unhook_io(dev, NIC_BASE_ADDR + NIC_RESET_PORT);
956 //vnic_reset_device(dev);
962 static struct vm_device_ops dev_ops = {
963 .init = vnic_init_device,
964 .deinit = vnic_deinit_device,
965 .reset = vnic_reset_device,
966 .start = vnic_start_device,
967 .stop = vnic_stop_device,
971 struct vm_device *v3_create_vnic()
973 struct nic_context * nic_state = V3_Malloc(sizeof(struct nic_context));
975 //memset(nic_state, 0, sizeof(struct nic_context));
977 //PrintDebug("VNIC internal at %x\n",(int)nic_state);
979 struct vm_device *device = v3_create_device("VNIC", &dev_ops, nic_state);