This is the pci device side in qemu. It just used as
a glue between the pci, tap and virtio code.

Signed-off-by: Dor Laor <[EMAIL PROTECTED]>
---
 qemu/hw/paravirt_net.c |  213
++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 213 insertions(+), 0 deletions(-)
 create mode 100644 qemu/hw/paravirt_net.c

diff --git a/qemu/hw/paravirt_net.c b/qemu/hw/paravirt_net.c
new file mode 100644
index 0000000..fdf2f1c
--- /dev/null
+++ b/qemu/hw/paravirt_net.c
@@ -0,0 +1,213 @@
+/*
+ * QEMU para virtual network emulation
+ * 
+ * Copyright (c) 2007 Qumranet
+ *
+ * Permission is hereby granted, free of charge, to any person
obtaining a copy
+ * of this software and associated documentation files (the
"Software"), to deal
+ * in the Software without restriction, including without limitation
the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell
+ * copies of the Software, and to permit persons to whom the Software
is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "virtio.h"
+#include "qemu-kvm.h"
+
+#define DEBUG_PARANET
+
+typedef struct PARANETState {
+    uint8_t macaddr[6];
+    uint8_t mult[8]; /* multicast mask array */
+    PCIDevice *pci_dev;
+    VLANClientState *vc;
+    struct virtio_device * vdev;
+    int tap_fd;
+} PARANETState;
+
+#define MAX_PARANET_DEVICES 1
+static int used_devices = 0;
+static PARANETState *paranet_devs[MAX_PARANET_DEVICES];
+
+static void paranet_reset(void *opaque)
+{
+}
+
+volatile int kvm_pvnet_pending_irq = 0;
+
+void paranet_update_irq(void *opaque)
+{
+    PARANETState *s = opaque;
+
+    paravirt_set_irq(s->pci_dev->config[0x3c]);
+
+    return;
+}
+
+void paravirt_net_poll(void)
+{
+    int i;
+
+    for (i=0; i<used_devices;i++) {
+        paranet_devs[i]->vdev->handle_input(paranet_devs[i]->vdev);
+    }
+}
+
+static int paranet_receive(void *opaque, const uint8_t *buf, int len)
+{
+   printf("PARANET:paravirt_receive\n");
+   return 0;
+}
+static int paranet_can_receive(void *opaque)
+{
+    return 0;
+}
+
+static void paranet_ioport_write(void *opaque, uint32_t addr, uint32_t
val)
+{
+    addr &= 0xf;
+#ifdef DEBUG_PARANET
+    printf("PARANET: write addr=0x%x val=0x%02x\n", addr, val);
+#endif
+
+    switch (addr) {
+    default:
+        printf("%s: BUG\n", __FUNCTION__);
+        break;
+    }
+}
+
+static uint32_t paranet_ioport_read(void *opaque, uint32_t addr)
+{
+    PARANETState* s=(PARANETState*)opaque;
+    uint32_t val = 0;
+    addr &= 0xf;
+
+    switch (addr) {
+       case 0:
+               val = 0;
+    default:
+        printf("%s: BUG\n", __FUNCTION__);
+        break;
+    }
+
+#ifdef DEBUG_PARANET
+    printf("PARANET: read addr=0x%x, val=%x\n", addr, val);
+#endif
+    return val;
+}
+
+static void paranet_save(QEMUFile* f,void* opaque)
+{
+    PARANETState* s=(PARANETState*)opaque;
+
+    if (s->pci_dev)
+        pci_device_save(s->pci_dev, f);
+
+    qemu_put_buffer(f, s->macaddr, 6);
+    qemu_put_buffer(f, s->mult, 8);
+}
+
+static int paranet_load(QEMUFile* f,void* opaque,int version_id)
+{
+    PARANETState* s=(PARANETState*)opaque;
+    int ret = 0;
+
+    if (s->pci_dev) {
+        ret = pci_device_load(s->pci_dev, f);
+        if (ret < 0)
+           return ret;
+    }
+
+    qemu_get_buffer(f, s->macaddr, 6);
+    qemu_get_buffer(f, s->mult, 8);
+
+    return ret;
+}
+
+/***********************************************************/
+/* PCI PARANET definitions */
+
+typedef struct PCIPARANETState {
+    PCIDevice dev;
+    PARANETState PARANET;
+} PCIPARANETState;
+
+static void paranet_map(PCIDevice *pci_dev, int region_num, 
+                       uint32_t addr, uint32_t size, int type)
+{
+    PCIPARANETState *d = (PCIPARANETState *)pci_dev;
+    PARANETState *s = &d->PARANET;
+
+    register_ioport_write(addr, 16, 1, paranet_ioport_write, s);
+    register_ioport_read(addr, 16, 1, paranet_ioport_read, s);
+}
+
+void pci_paranet_init(PCIBus *bus, NICInfo *nd, int devfn)
+{
+    PCIPARANETState *d;
+    PARANETState *s;
+    uint8_t *pci_conf;
+
+    printf("PARANET: pci_paranet_init start\n");
+
+    virtio_init();
+
+    d = (PCIPARANETState *)pci_register_device(bus,
+                                              "PARANET",
sizeof(PCIPARANETState),
+                                              devfn, 
+                                              NULL, NULL);
+    pci_conf = d->dev.config;
+    pci_conf[0x00] = 0x02; // Qumranet vendor ID 0x5002
+    pci_conf[0x01] = 0x50;
+    pci_conf[0x02] = 0x34;
+    pci_conf[0x03] = 0x12;
+    pci_conf[0x04] = 0x05; // command = I/O space, Bus Master
+    pci_conf[0x0a] = 0x00; // ethernet network controller 
+    pci_conf[0x0b] = 0x02;
+    pci_conf[0x0e] = 0x00; // header_type
+    pci_conf[0x3d] = 0x01; // interrupt pin 0, currently unused
+    
+    pci_register_io_region(&d->dev, 0, 0x100, 
+                           PCI_ADDRESS_SPACE_IO, paranet_map);
+    s = &d->PARANET;
+    s->pci_dev = (PCIDevice *)d;
+    memcpy(s->macaddr, nd->macaddr, 6);
+    paranet_reset(s);
+    paranet_devs[0] = s;
+
+    s->vc = qemu_new_vlan_client(nd->vlan, NULL,
+                                 paranet_can_receive, s);
+    s->tap_fd = get_tap_fd(s->vc->vlan->first_client->opaque);
+
+    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
+             "kvm pv pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
+             s->macaddr[0],
+             s->macaddr[1],
+             s->macaddr[2],
+             s->macaddr[3],
+             s->macaddr[4],
+             s->macaddr[5]);
+
+    register_savevm("PARANET", 0, 1, paranet_save, paranet_load, s);
+    qemu_register_reset(paranet_reset, s);
+
+    s->vdev = setup_virtnet(s,
+                          used_devices,
+                          s->tap_fd,
+                          paranet_update_irq);
+    paranet_devs[used_devices++] = s;
+
+    printf("PARANET: pci_paranet_init end\n");
+}

-----
In simplicity there is elegance.
Dor Laor ;)


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to