Ejemplo n.º 1
0
enum handler_return platform_irq(struct arm64_iframe_short *frame)
{
    uint32_t iar = GICCPUREG(IAR);
    uint vector = iar & 0x3ff;

//    printf("platform_irq: spsr 0x%llx, pc 0x%llx, currthread %p, vector %d\n", frame->spsr, frame->elr, current_thread, vector);

    if (vector >= 0x3fe) {
        // spurious
        return INT_NO_RESCHEDULE;
    }

    THREAD_STATS_INC(interrupts);
    KEVLOG_IRQ_ENTER(vector);

    // deliver the interrupt
    enum handler_return ret;

    ret = INT_NO_RESCHEDULE;
    if (int_handler_table[vector].handler)
        ret = int_handler_table[vector].handler(int_handler_table[vector].arg);

    GICCPUREG(EOIR) = iar;

//  printf("platform_irq: exit %d\n", ret);

    KEVLOG_IRQ_EXIT(vector);

    if (ret != INT_NO_RESCHEDULE)
        thread_preempt();

    return ret;
}
Ejemplo n.º 2
0
Archivo: arch.c Proyecto: M1cha/lk
void arm_cm_irq_entry(void)
{
	inc_critical_section();

	THREAD_STATS_INC(interrupts);
	KEVLOG_IRQ_ENTER(__get_IPSR());
}
Ejemplo n.º 3
0
Archivo: arch.c Proyecto: herhut-ggl/lk
void arm_cm_irq_entry(void)
{
	// Set PRIMASK to 1
	// This is so that later calls to arch_ints_disabled() returns true while we're inside the int handler
	// Note: this will probably screw up future efforts to stack higher priority interrupts since we're setting
	// the cpu to essentially max interrupt priority here. Will have to rethink it then.
	__disable_irq();

	THREAD_STATS_INC(interrupts);
	KEVLOG_IRQ_ENTER(__get_IPSR());
}
Ejemplo n.º 4
0
enum handler_return platform_irq(struct x86_iframe *frame)
{
    // get the current vector
    unsigned int vector = frame->vector;

    THREAD_STATS_INC(interrupts);

    // deliver the interrupt
    enum handler_return ret = INT_NO_RESCHEDULE;

    switch (vector) {
        case INT_GP_FAULT:
            x86_gpf_handler(frame);
            break;

        case INT_INVALID_OP:
            x86_invop_handler(frame);
            break;
        case INT_PAGE_FAULT:
#ifdef ARCH_X86_64
            x86_pfe_handler(frame);
#endif
            break;

        case INT_DEV_NA_EX:
#if X86_WITH_FPU
            fpu_dev_na_handler();
            break;
#endif

        case INT_MF:
        case INT_XM:
        case INT_DIVIDE_0:
        case INT_DEBUG_EX:
        case INT_STACK_FAULT:
        case 3:
            x86_unhandled_exception(frame);
            break;

        default:
            if (int_handler_table[vector].handler)
                ret = int_handler_table[vector].handler(int_handler_table[vector].arg);
    }

    // ack the interrupt
    issueEOI(vector);

    return ret;
}
Ejemplo n.º 5
0
enum handler_return platform_irq(struct arm_iframe *frame)
{
    // get the current vector
    unsigned int vector;

    THREAD_STATS_INC(interrupts);

    // read from the first level int handler
    vector = *ICReg(0, INTCON_SIR_IRQ);

    // see if it's coming from the second level handler
    if (vector == 0) {
        vector = *ICReg(1, INTCON_SIR_IRQ) + 32;
    }

//	dprintf("platform_irq: spsr 0x%x, pc 0x%x, currthread %p, vector %d\n", frame->spsr, frame->pc, current_thread, vector);

    // deliver the interrupt
    enum handler_return ret;

    ret = INT_NO_RESCHEDULE;
    if (int_handler_table[vector].handler)
        ret = int_handler_table[vector].handler(int_handler_table[vector].arg);

    // ack the interrupt
    if (vector >= 32) {
        // interrupt is chained, so ack the second level first, and then the first
        *ICReg(vector / 32, INTCON_ITR) = ~(1 << (vector % 32));
        *ICReg(1, INTCON_CONTROL) |= 1;
        vector = 0; // force the following code to ack the chained first level vector
    }

    *ICReg(0, INTCON_ITR) = ~(1 << vector);
    *ICReg(0, INTCON_CONTROL) = 1;

    return ret;
}
Ejemplo n.º 6
0
enum handler_return platform_irq(struct arm_iframe *frame)
{
	// get the current vector
	unsigned int vector;

	// read the currently active IRQ
	vector = *REG32(INTC_SIR_IRQ) & 0x7f;

//	TRACEF("spsr 0x%x, pc 0x%x, currthread %p, vector %d, handler %p\n", frame->spsr, frame->pc, current_thread, vector, int_handler_table[vector].handler);

	THREAD_STATS_INC(interrupts);

	// deliver the interrupt
	enum handler_return ret;

	ret = INT_NO_RESCHEDULE;
	if (int_handler_table[vector].handler)
		ret = int_handler_table[vector].handler(int_handler_table[vector].arg);

	// ack the interrupt
	*REG32(INTC_CONTROL) = 0x1;

	return ret;
}
Ejemplo n.º 7
0
Archivo: intc.c Proyecto: cpizano/lk
enum handler_return platform_irq(struct arm_iframe *frame)
{
    uint vector;
    uint cpu = arch_curr_cpu_num();

    THREAD_STATS_INC(interrupts);

    // see what kind of irq it is
    uint32_t pend = *REG32(INTC_LOCAL_IRQ_PEND0 + cpu * 4);

    pend &= ~(1 << (INTERRUPT_ARM_LOCAL_GPU_FAST % 32)); // mask out gpu interrupts

    if (pend != 0) {
        // it's a local interrupt
        LTRACEF("local pend 0x%x\n", pend);
        vector = ARM_IRQ_LOCAL_BASE + ctz(pend);
        goto decoded;
    }

    // XXX disable for now, since all of the interesting irqs are mirrored into the other banks
#if 0
    // look in bank 0 (ARM interrupts)
    pend = *REG32(INTC_PEND0);
    LTRACEF("pend0 0x%x\n", pend);
    pend &= ~((1<<8)|(1<<9)); // mask out bit 8 and 9
    if (pend != 0) {
        // it's a bank 0 interrupt
        vector = ARM_IRQ0_BASE + ctz(pend);
        goto decoded;
    }
#endif

    // look for VC interrupt bank 1
    pend = *REG32(INTC_PEND1);
    LTRACEF("pend1 0x%x\n", pend);
    if (pend != 0) {
        // it's a bank 1 interrupt
        vector = ARM_IRQ1_BASE + ctz(pend);
        goto decoded;
    }

    // look for VC interrupt bank 2
    pend = *REG32(INTC_PEND2);
    LTRACEF("pend2 0x%x\n", pend);
    if (pend != 0) {
        // it's a bank 2 interrupt
        vector = ARM_IRQ2_BASE + ctz(pend);
        goto decoded;
    }

    vector = 0xffffffff;

decoded:
    LTRACEF("cpu %u vector %u\n", cpu, vector);

    // dispatch the irq
    enum handler_return ret = INT_NO_RESCHEDULE;

#if WITH_SMP
    if (vector == INTERRUPT_ARM_LOCAL_MAILBOX0) {
        pend = *REG32(INTC_LOCAL_MAILBOX0_CLR0 + 0x10 * cpu);
        LTRACEF("mailbox0 clr 0x%x\n", pend);

        // ack it
        *REG32(INTC_LOCAL_MAILBOX0_CLR0 + 0x10 * cpu) = pend;

        if (pend & (1 << MP_IPI_GENERIC)) {
            PANIC_UNIMPLEMENTED;
        }
        if (pend & (1 << MP_IPI_RESCHEDULE)) {
            ret = mp_mbx_reschedule_irq();
        }
    } else
#endif // WITH_SMP
    if (vector == 0xffffffff) {
        ret = INT_NO_RESCHEDULE;
    } else if (int_handler_table[vector].handler) {
        ret = int_handler_table[vector].handler(int_handler_table[vector].arg);
    } else {
        panic("irq %u fired on cpu %u but no handler set!\n", vector, cpu);
    }

    return ret;
}
Ejemplo n.º 8
0
Archivo: arch.c Proyecto: dzc1234ok/lk
void arm_cm_irq_entry(void)
{
	THREAD_STATS_INC(interrupts);
	KEVLOG_IRQ_ENTER(__get_IPSR());
}