uint8_t trig_mode_reg[32];
struct {
- int (*ack)(struct guest_info * core, uint8_t irq, void * private_data);
+ int (*ack)(struct guest_info * core, uint32_t irq, void * private_data);
void * private_data;
} irq_ack_cbs[256];
if (*en_location & flag) {
*req_location |= flag;
+ apic->irq_ack_cbs[irq_num].ack = ack;
+ apic->irq_ack_cbs[irq_num].private_data = private_data;
+
return 1;
} else {
PrintDebug("apic %u: core %d: Interrupt not enabled... %.2x\n",
static void drain_irq_entries(struct apic_state * apic) {
-
while (1) {
unsigned int flags = 0;
struct irq_queue_entry * entry = NULL;
-static int apic_do_eoi(struct apic_state * apic) {
+static int apic_do_eoi(struct guest_info * core, struct apic_state * apic) {
int isr_irq = get_highest_isr(apic);
if (isr_irq != -1) {
*svc_location &= ~flag;
+ if (apic->irq_ack_cbs[isr_irq].ack) {
+ apic->irq_ack_cbs[isr_irq].ack(core, isr_irq, apic->irq_ack_cbs[isr_irq].private_data);
+ }
+
#ifdef V3_CONFIG_CRAY_XT
if ((isr_irq == 238) ||
add_apic_irq_entry(dst_apic, ipi->vector, ipi->ack, ipi->private_data);
-#ifdef V3_CONFIG_MULTITHREAD_OS
if (dst_apic != src_apic) {
PrintDebug(" non-local core with new interrupt, forcing it to exit now\n");
v3_interrupt_cpu(dst_core->vm_info, dst_core->pcpu_id, 0);
}
-#endif
-
break;
}
// Action Registers
case EOI_OFFSET:
// do eoi
- apic_do_eoi(apic);
+ apic_do_eoi(core, apic);
break;
case INT_CMD_LO_OFFSET: {
apic_dev = (struct apic_dev_state *)V3_Malloc(sizeof(struct apic_dev_state) +
sizeof(struct apic_state) * vm->num_cores);
+
+ if (!apic_dev) {
+ PrintError("Failed to allocate space for APIC\n");
+ return -1;
+ }
+
apic_dev->num_apics = vm->num_cores;
v3_lock_init(&(apic_dev->state_lock));