Example #1
0
File: apic.c Project: ksandstr/mung
void isr_apic_bottom(struct x86_exregs *regs)
{
	struct lapic_info *apic = &cpu_apics[0];
#if 0
	printf("%s: frame at %p, exregs=%p, frame_len=%u (size=%u)\n",
		__func__, &apic, regs, (unsigned)x86_frame_len(regs),
		(unsigned)sizeof(*regs));
#endif

	/* figure out which interrupt this is from the ISRs. */
	int vecnum;
	bool vec_found = false;
	for(int i=0; i <= apic->max_vector; i += 32) {
		uint32_t isr_limb = mm_inl(apic->base_addr + APIC_ISR(i >> 5));
		if(i == 0) isr_limb &= ~0xffffu;
		if(isr_limb != 0) {
			vecnum = i + ffsl(isr_limb) - 1;
			vec_found = true;
			break;
		}
	}
	if(!vec_found) {
		apic->num_spurious++;
		ioapic_send_eoi(0);		/* just in case. */
		return;
	}

#if 0
	if(vecnum == 0x21) {
		printf("i'm a keyboard, toot toot\n");
#define KBD_STATUS_REG 0x64
#define KBD_DATA_REG 0x60
#define KBD_STAT_OBF 0x01
		for(;;) {
			uint8_t st = inb(KBD_STATUS_REG);
			if((st & KBD_STAT_OBF) == 0) break;
			inb(KBD_DATA_REG);	/* and throw it away */
		}
	} else {
		printf("APIC interrupt vector %d\n", vecnum);
	}
#endif

	regs->reason = vecnum;
	isr_irq_bottom(regs);
	return;

#if 0
	/* TODO: move this into an x86_print_exregs() function */
	printf("exregs: reason=%#lx, es=%#lx, ds=%#lx, cs=%#lx, ss=%#lx\n"
		"\tedi=%#lx, esi=%#lx, ebp=%#lx, __esp=%#lx\n"
		"\tebx=%#lx, edx=%#lx, ecx=%#lx, eax=%#lx\n"
		"\terror=%#lx, eip=%#lx, eflags=%#lx, esp=%#lx\n",
		regs->reason, regs->es, regs->ds, regs->cs, regs->ss,
		regs->edi, regs->esi, regs->ebp, regs->__esp,
		regs->ebx, regs->edx, regs->ecx, regs->eax,
		regs->error, regs->eip, regs->eflags, regs->esp);
#endif
}
Example #2
0
static inline bool irq_in_kernel(const struct x86_exregs *frame) {
	/* ring0 interrupts push a short stack frame. */
	return x86_frame_len(frame) < sizeof(*frame);
}