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 <palacios/vmm_dev_mgr.h>
21 #include <palacios/vmm_sprintf.h>
22 #include <palacios/vm_guest.h>
23 #include <devices/icc_bus.h>
28 struct ipi_thunk_data {
29 struct vm_device * target;
40 } __attribute__((packed));
46 uint_t del_status : 1;
50 uint_t rem_rd_status : 2;
51 uint_t dst_shorthand : 2;
54 } __attribute__((packed));
55 } __attribute__((packed));
56 } __attribute__((packed));
62 struct guest_info * core;
63 struct v3_icc_ops * ops;
70 struct icc_bus_state {
71 struct apic_data apics[MAX_APICS];
74 static struct v3_device_ops dev_ops = {
84 int v3_icc_send_irq(struct vm_device * icc_bus, uint8_t apic_num, uint32_t irq_num) {
85 struct icc_bus_state * state = (struct icc_bus_state *)icc_bus->private_data;
86 struct apic_data * apic = &(state->apics[apic_num]);
89 struct int_cmd_reg icr;
97 switch (icr.dst_shorthand) {
99 sprintf(foo, "%d", icr.dst);
106 dest = "(broadcast inclusive)";
109 dest = "(broadcast)";
113 switch (icr.msg_type) {
129 PrintDebug("Sending IPI of type %s and destination type %s from LAPIC %u to LAPIC %u.\n",
130 type, dest, V3_Get_CPU(), apic_num);
132 apic->ops->raise_intr(apic->core, irq_num & 0xff, apic->priv_data);
134 //V3_Call_On_CPU(apic_num, icc_force_exit, (void *)(uint64_t)(val & 0xff));
141 /* THIS IS A BIG ASSUMPTION: APIC PHYSID == LOGID == CORENUM */
143 int v3_icc_register_apic(struct guest_info * core, struct vm_device * icc_bus,
144 uint8_t apic_num, struct v3_icc_ops * ops, void * priv_data) {
145 struct icc_bus_state * icc = (struct icc_bus_state *)icc_bus->private_data;
146 struct apic_data * apic = &(icc->apics[apic_num]);
148 if (apic->present == 1) {
149 PrintError("Attempt to re-register apic %u\n", apic_num);
154 apic->priv_data = priv_data;
158 PrintDebug("Registered apic%u\n", apic_num);
166 static int icc_bus_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
167 PrintDebug("Creating ICC_BUS\n");
169 char * name = v3_cfg_val(cfg, "name");
171 struct icc_bus_state * icc_bus = (struct icc_bus_state *)V3_Malloc(sizeof(struct icc_bus_state));
172 memset(icc_bus, 0, sizeof(struct icc_bus_state));
174 struct vm_device * dev = v3_allocate_device(name, &dev_ops, icc_bus);
176 if (v3_attach_device(vm, dev) == -1) {
177 PrintError("Could not attach device %s\n", name);
186 device_register("ICC_BUS", icc_bus_init)