X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Ficc_bus.c;h=f5de549646b4cf321c0ca3af78c70a940c8184d7;hb=83790cde959d56c148be1b5f64d2e4a4414acac9;hp=fe76cff81ffc481d55cbfc08ec6b6929b5d86428;hpb=fa3ef2ff5003b7cd27bfe11e970760c940525966;p=palacios.git diff --git a/palacios/src/devices/icc_bus.c b/palacios/src/devices/icc_bus.c index fe76cff..f5de549 100644 --- a/palacios/src/devices/icc_bus.c +++ b/palacios/src/devices/icc_bus.c @@ -20,13 +20,55 @@ #include #include #include -#include -#include +#include -#define MAX_APIC 256 +#define MAX_APICS 256 -struct icc_bus_internal { - struct vm_device * apic[MAX_APIC]; + +struct ipi_thunk_data { + struct vm_device * target; + uint64_t val; +}; + +struct int_cmd_reg { + union { + uint64_t val; + + struct { + uint32_t lo; + uint32_t hi; + } __attribute__((packed)); + + struct { + uint_t vec : 8; + uint_t msg_type : 3; + uint_t dst_mode : 1; + uint_t del_status : 1; + uint_t rsvd1 : 1; + uint_t lvl : 1; + uint_t trig_mode : 1; + uint_t rem_rd_status : 2; + uint_t dst_shorthand : 2; + uint64_t rsvd2 : 36; + uint32_t dst : 8; + } __attribute__((packed)); + } __attribute__((packed)); +} __attribute__((packed)); + + + + +struct apic_data { + struct guest_info * core; + struct v3_icc_ops * ops; + + void * priv_data; + int present; +}; + + +struct icc_bus_state { + struct apic_data apics[MAX_APICS]; }; static struct v3_device_ops dev_ops = { @@ -36,98 +78,98 @@ static struct v3_device_ops dev_ops = { .stop = NULL, }; -int v3_icc_register_apic(struct v3_vm_info *info, struct vm_device *icc_bus, struct vm_device *apic, uint32_t apic_num) -{ - struct icc_bus_internal * icc = (struct icc_bus_internal *)icc_bus->private_data; - - if (apic_num < MAX_APIC) { - if (icc->apic[apic_num]) { - PrintError("Attempt to re-register apic %u\n", apic_num); - return -1; - } else { - icc->apic[apic_num] = apic; - PrintDebug("Registered apic or ioapic %u\n", apic_num); - return 0; - } - } else { - PrintError("Too many apics for icc bus!"); - return -1; - } -} -struct ipi_thunk_data { - struct vm_device *target; - uint64_t val; -} ; -static void icc_force_exit(void *val) -{ - return; -} -int v3_icc_send_ipi(struct vm_device * icc_bus, uint32_t apic_num, uint32_t val) { - struct icc_bus_internal * internal = (struct icc_bus_internal *)icc_bus->private_data; +int v3_icc_send_irq(struct vm_device * icc_bus, uint8_t apic_num, uint32_t irq_num) { + struct icc_bus_state * state = (struct icc_bus_state *)icc_bus->private_data; + struct apic_data * apic = &(state->apics[apic_num]); + struct int_cmd_reg icr; - icr.lo = val; + icr.lo = irq_num; - char *type = NULL, *dest = NULL; + + char * type = NULL; + char * dest = NULL; char foo[8]; - switch (icr.dst_shorthand) - { - case 0x0: - sprintf(foo, "%d", icr.dst); - dest = foo; - break; - case 0x1: - dest = "(self)"; - break; - case 0x2: - dest = "(broadcast inclusive)"; - break; - case 0x3: - dest = "(broadcast)"; - break; + switch (icr.dst_shorthand) { + case 0x0: + sprintf(foo, "%d", icr.dst); + dest = foo; + break; + case 0x1: + dest = "(self)"; + break; + case 0x2: + dest = "(broadcast inclusive)"; + break; + case 0x3: + dest = "(broadcast)"; + break; } - switch (icr.msg_type) - { - case 0x0: - type = ""; - break; - case 0x4: - type = "(NMI)"; - break; - case 0x5: - type = "(INIT)"; - break; - case 0x6: - type = "(Startup)"; - break; + + switch (icr.msg_type) { + case 0x0: + type = ""; + break; + case 0x4: + type = "(NMI)"; + break; + case 0x5: + type = "(INIT)"; + break; + case 0x6: + type = "(Startup)"; + break; } - PrintDebug("Sending IPI of type %s and destination type %s from LAPIC %u to LAPIC %u.\n", type, dest, V3_Get_CPU(), apic_num); + PrintDebug("Sending IPI of type %s and destination type %s from LAPIC %u to LAPIC %u.\n", + type, dest, V3_Get_CPU(), apic_num); - v3_apic_raise_intr(internal->apic[apic_num], val & 0xff); + apic->ops->raise_intr(apic->core, irq_num & 0xff, apic->priv_data); - V3_Call_On_CPU(apic_num, icc_force_exit, (void *)(uint64_t)(val & 0xff)); + //V3_Call_On_CPU(apic_num, icc_force_exit, (void *)(uint64_t)(val & 0xff)); return 0; } -static int init_icc_bus_internal_state(struct icc_bus_internal* icc) { - int i; - for (i=0;iapic[i]=0; } - return 0; + +/* THIS IS A BIG ASSUMPTION: APIC PHYSID == LOGID == CORENUM */ + +int v3_icc_register_apic(struct guest_info * core, struct vm_device * icc_bus, + uint8_t apic_num, struct v3_icc_ops * ops, void * priv_data) { + struct icc_bus_state * icc = (struct icc_bus_state *)icc_bus->private_data; + struct apic_data * apic = &(icc->apics[apic_num]); + + if (apic->present == 1) { + PrintError("Attempt to re-register apic %u\n", apic_num); + return -1; + } + + apic->present = 1; + apic->priv_data = priv_data; + apic->core = core; + apic->ops = ops; + + PrintDebug("Registered apic%u\n", apic_num); + + return 0; } + + + static int icc_bus_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { PrintDebug("Creating ICC_BUS\n"); + char * name = v3_cfg_val(cfg, "name"); - struct icc_bus_internal * icc_bus = (struct icc_bus_internal *)V3_Malloc(sizeof(struct icc_bus_internal)); + struct icc_bus_state * icc_bus = (struct icc_bus_state *)V3_Malloc(sizeof(struct icc_bus_state)); + memset(icc_bus, 0, sizeof(struct icc_bus_state)); struct vm_device * dev = v3_allocate_device(name, &dev_ops, icc_bus); @@ -136,8 +178,6 @@ static int icc_bus_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { return -1; } - init_icc_bus_internal_state(icc_bus); - return 0; }