struct guest_info * core;
+ struct {
+ int (*ack)(struct guest_info * core, uint32_t irq, void * private_data);
+ void * private_data;
+ } irq_ack_cbs[15];
+
void * router_handle;
void * controller_handle;
}
-static int pic_raise_intr(struct v3_vm_info * vm, void * private_data, int irq) {
+static int pic_raise_intr(struct v3_vm_info * vm, void * private_data, struct v3_irq * irq) {
struct pic_internal * state = (struct pic_internal*)private_data;
+ uint8_t irq_num = irq->irq;
- if (irq == 2) {
- irq = 9;
- state->master_irr |= 0x04; // PAD
+ if (irq_num == 2) {
+ irq_num = 9;
+ state->master_irr |= 0x04;
}
- PrintDebug("8259 PIC: Raising irq %d in the PIC\n", irq);
+ PrintDebug("8259 PIC: Raising irq %d in the PIC\n", irq_num);
- if (irq <= 7) {
- state->master_irr |= 0x01 << irq;
- } else if ((irq > 7) && (irq < 16)) {
- state->slave_irr |= 0x01 << (irq - 8); // PAD if -7 then irq 15=no irq
+ if (irq_num <= 7) {
+ state->master_irr |= 0x01 << irq_num;
+ } else if ((irq_num > 7) && (irq_num < 16)) {
+ state->slave_irr |= 0x01 << (irq_num - 8);
} else {
- PrintDebug("8259 PIC: Invalid IRQ raised (%d)\n", irq);
+ PrintDebug("8259 PIC: Invalid IRQ raised (%d)\n", irq_num);
return -1;
}
-#ifdef V3_CONFIG_MULTITHREAD_OS
- v3_interrupt_cpu(vm, 0, 0);
-#endif
+ state->irq_ack_cbs[irq_num].ack = irq->ack;
+ state->irq_ack_cbs[irq_num].private_data = irq->private_data;
+
+ if (V3_Get_CPU() != vm->cores[0].pcpu_id) {
+ // guest is running on another core, interrupt it to deliver irq
+ v3_interrupt_cpu(vm, 0, 0);
+ }
return 0;
}
-static int pic_lower_intr(struct v3_vm_info * vm, void * private_data, int irq) {
+static int pic_lower_intr(struct v3_vm_info * vm, void * private_data, struct v3_irq * irq) {
struct pic_internal * state = (struct pic_internal*)private_data;
+ uint8_t irq_num = irq->irq;
- PrintDebug("[pic_lower_intr] IRQ line %d now low\n", irq);
- if (irq <= 7) {
- state->master_irr &= ~(1 << irq);
+ PrintDebug("[pic_lower_intr] IRQ line %d now low\n", irq_num);
+ if (irq_num <= 7) {
+
+ state->master_irr &= ~(1 << irq_num);
if ((state->master_irr & ~(state->master_imr)) == 0) {
PrintDebug("\t\tFIXME: Master maybe should do sth\n");
}
- } else if ((irq > 7) && (irq < 16)) {
+ } else if ((irq_num > 7) && (irq_num < 16)) {
- state->slave_irr &= ~(1 << (irq - 8));
+ state->slave_irr &= ~(1 << (irq_num - 8));
if ((state->slave_irr & (~(state->slave_imr))) == 0) {
PrintDebug("\t\tFIXME: Slave maybe should do sth\n");
}
state->master_irr &= ~(0x1 << irq);
}
} else {
- PrintDebug("8259 PIC: (master) Ignoring begin_irq for %d since I don't own it\n",irq);
+ PrintDebug("8259 PIC: (master) Ignoring begin_irq for %d since I don't own it\n", irq);
}
} else {
state->slave_irr &= ~(0x1 << (irq - 8));
}
} else {
- PrintDebug("8259 PIC: (slave) Ignoring begin_irq for %d since I don't own it\n",irq);
+ PrintDebug("8259 PIC: (slave) Ignoring begin_irq for %d since I don't own it\n", irq);
}
-
}
+
+
return 0;
}
if ((cw2->EOI) && (!cw2->R) && (cw2->SL)) {
// specific EOI;
state->master_isr &= ~(0x01 << cw2->level);
+
+
+ /*
+ // ack the irq if requested
+ if (state->irq_ack_cbs[irq].ack) {
+ state->irq_ack_cbs[irq].ack(info, irq, state->irq_ack_cbs[irq].private_data);
+ }
+ */
+
} else if ((cw2->EOI) & (!cw2->R) && (!cw2->SL)) {
int i;
// Non-specific EOI
state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal));
- V3_ASSERT(state != NULL);
+ if (!state) {
+ PrintError("Cannot allocate in init\n");
+ return -1;
+ }
struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state);