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) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <devices/para_net.h>
21 #include <palacios/vmm.h>
22 #include <palacios/vm_guest_mem.h>
23 #include <palacios/vmm_hypercall.h>
25 #define TX_HYPERCALL 0x300
26 #define RX_HYPERCALL 0x301
27 #define MACADDR_HYPERCALL 0x302
36 static int tx_call(struct guest_info * info, uint_t call_no, void * priv_data) {
37 // struct nic_state * nic = (struct nic_state *)priv_data;
38 addr_t pkt_gpa = info->vm_regs.rbx;
39 int pkt_len = info->vm_regs.rcx;
40 uchar_t * pkt = V3_Malloc(pkt_len);
42 PrintDebug("Transmitting Packet\n");
44 if (read_guest_pa_memory(info, pkt_gpa, pkt_len, pkt) != -1) {
53 static int rx_call(struct guest_info * info, uint_t call_no, void * priv_data) {
54 // struct nic_state * nic = (struct nic_state *)priv_data;
55 addr_t pkt_gpa = info->vm_regs.rbx;
59 PrintDebug("Receiving Packet\n");
62 if (write_guest_pa_memory(info, pkt_gpa, pkt_len, pkt) != -1) {
70 static int macaddr_call(struct guest_info * info, uint_t call_no, void * priv_data) {
71 struct nic_state * nic = (struct nic_state *)priv_data;
72 addr_t mac_gpa = info->vm_regs.rbx;
75 PrintDebug("Returning MAC ADDR\n");
77 if (write_guest_pa_memory(info, mac_gpa, 6, nic->mac_addr) != 6) {
78 PrintError("Could not write mac address\n");
85 static int net_init(struct vm_device * dev) {
86 struct nic_state * nic = (struct nic_state *)dev->private_data;
88 v3_register_hypercall(dev->vm, TX_HYPERCALL, tx_call, nic);
89 v3_register_hypercall(dev->vm, RX_HYPERCALL, rx_call, nic);
90 v3_register_hypercall(dev->vm, MACADDR_HYPERCALL, macaddr_call, nic);
92 nic->mac_addr[0] = 0x52;
93 nic->mac_addr[1] = 0x54;
94 nic->mac_addr[2] = 0x00;
95 nic->mac_addr[3] = 0x12;
96 nic->mac_addr[4] = 0x34;
97 nic->mac_addr[5] = 0x56;
102 static int net_deinit(struct vm_device * dev) {
108 static struct vm_device_ops dev_ops = {
110 .deinit = net_deinit,
117 struct vm_device * v3_create_para_net() {
118 struct nic_state * state = NULL;
120 state = (struct nic_state *)V3_Malloc(sizeof(struct nic_state));
122 PrintDebug("Creating VMNet Device\n");
124 struct vm_device * device = v3_create_device("VMNET", &dev_ops, state);