#endif
#ifdef CONFIG_DEBUG_APIC
-static char *shorthand_str[] = {
+static char * shorthand_str[] = {
"(no shorthand)",
"(self)",
"(all)",
"(all-but-me)",
};
-static char *deliverymode_str[] = {
+static char * deliverymode_str[] = {
"(fixed)",
"(lowest priority)",
"(SMI)",
struct guest_info * core;
+ struct v3_timer * timer;
+
uint32_t eoi;
v3_lock_t lock;
icr->dst,
icr->val);
-
switch (icr->dst_shorthand) {
case 0: // no shorthand
PrintDebug("apic %u: core %u: at %p and priv_data is at %p\n",
apic->lapic_id.val, core->cpu_id, apic, priv_data);
- PrintDebug("Write to address space (%p) (val=%x)\n",
- (void *)guest_addr, *(uint32_t *)src);
+ PrintDebug("apic %u: core %u: write to address space (%p) (val=%x)\n",
+ apic->lapic_id.val, core->cpu_id, (void *)guest_addr, *(uint32_t *)src);
if (msr->apic_enable == 0) {
PrintError("apic %u: core %u: Write to APIC address space with disabled APIC, apic msr=0x%llx\n",
}
-int v3_apic_send_ipi(struct v3_vm_info * vm, struct vm_device * dev,
- struct v3_gen_ipi * ipi) {
- struct apic_dev_state * apic_dev = (struct apic_dev_state *)(dev->private_data);
+int v3_apic_send_ipi(struct v3_vm_info * vm, struct v3_gen_ipi * ipi, void * dev_data) {
+ struct apic_dev_state * apic_dev = (struct apic_dev_state *)dev_data;
struct int_cmd_reg tmp_icr;
// zero out all the fields
}
-int v3_apic_raise_intr(struct v3_vm_info * vm, struct vm_device * dev,
- uint32_t irq, uint32_t dst) {
- struct apic_dev_state * apic_dev = (struct apic_dev_state *)(dev->private_data);
+int v3_apic_raise_intr(struct v3_vm_info * vm, uint32_t irq, uint32_t dst, void * dev_data) {
+ struct apic_dev_state * apic_dev = (struct apic_dev_state *)(dev_data);
struct apic_state * apic = &(apic_dev->apics[dst]);
PrintDebug("apic %u core ?: raising interrupt IRQ %u (dst = %u).\n", apic->lapic_id.val, irq, dst);
};
-static struct vm_timer_ops timer_ops = {
+static struct v3_timer_ops timer_ops = {
.update_timer = apic_update_time,
};
-static int apic_free(struct vm_device * dev) {
+static int apic_free(struct apic_dev_state * apic_dev) {
+ int i = 0;
+ struct v3_vm_info * vm = NULL;
- /* TODO: This should crosscall to force an unhook on each CPU */
+ for (i = 0; i < apic_dev->num_apics; i++) {
+ struct apic_state * apic = &(apic_dev->apics[i]);
+ struct guest_info * core = apic->core;
+
+ vm = core->vm_info;
+
+ // unregister intr controller
- // struct apic_state * apic = (struct apic_state *)dev->private_data;
+ if (apic->timer) {
+ v3_remove_timer(core, apic->timer);
+ }
- v3_unhook_msr(dev->vm, BASE_ADDR_MSR);
+ // unhook memory
+ }
+
+ v3_unhook_msr(vm, BASE_ADDR_MSR);
+
+ V3_Free(apic_dev);
return 0;
}
static struct v3_device_ops dev_ops = {
- .free = apic_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
+ .free = (int (*)(void *))apic_free,
};
apic_dev->num_apics = vm->num_cores;
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, apic_dev);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, apic_dev);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("apic: Could not attach device %s\n", dev_id);
+ V3_Free(apic_dev);
return -1;
}
v3_register_intr_controller(core, &intr_ops, apic_dev);
- v3_add_timer(core, &timer_ops, apic_dev);
+ apic->timer = v3_add_timer(core, &timer_ops, apic_dev);
+
+ if (apic->timer == NULL) {
+ PrintError("APIC: Failed to attach timer to core %d\n", i);
+ v3_remove_device(dev);
+ return -1;
+ }
v3_hook_full_mem(vm, core->cpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, apic_dev);