Subversion Repositories HelenOS

Rev

Rev 1909 | Rev 1920 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1909 Rev 1919
Line 33... Line 33...
33
 */
33
 */
34
 
34
 
35
#include <arch/interrupt.h>
35
#include <arch/interrupt.h>
36
#include <arch/trap/interrupt.h>
36
#include <arch/trap/interrupt.h>
37
#include <interrupt.h>
37
#include <interrupt.h>
38
#include <arch/drivers/fhc.h>
-
 
39
#include <arch/drivers/kbd.h>
38
#include <irq.h>
40
#include <typedefs.h>
39
#include <typedefs.h>
41
#include <arch/types.h>
40
#include <arch/types.h>
42
#include <debug.h>
41
#include <debug.h>
43
#include <ipc/sysipc.h>
42
#include <ipc/sysipc.h>
44
#include <arch/asm.h>
43
#include <arch/asm.h>
45
#include <arch/barrier.h>
44
#include <arch/barrier.h>
46
#include <print.h>
45
#include <print.h>
47
#include <genarch/kbd/z8530.h>
-
 
48
#include <arch.h>
46
#include <arch.h>
49
#include <mm/tlb.h>
47
#include <mm/tlb.h>
50
#include <config.h>
48
#include <config.h>
51
 
49
 
-
 
50
/*
-
 
51
 * To be removed once we get rid of the dependency in ipc_irq_bind_arch().
-
 
52
 */
-
 
53
#include <arch/drivers/kbd.h>
-
 
54
#include <genarch/kbd/z8530.h>
-
 
55
 
52
/** Register Interrupt Level Handler.
56
/** Register Interrupt Level Handler.
53
 *
57
 *
54
 * @param n Interrupt Level (1 - 15).
58
 * @param n Interrupt Level (1 - 15).
55
 * @param name Short descriptive string.
59
 * @param name Short descriptive string.
56
 * @param f Handler.
60
 * @param f Handler.
Line 69... Line 73...
69
    if (kbd_type == KBD_Z8530)
73
    if (kbd_type == KBD_Z8530)
70
        z8530_belongs_to_kernel = false;
74
        z8530_belongs_to_kernel = false;
71
#endif
75
#endif
72
}
76
}
73
 
77
 
-
 
78
/** Process hardware interrupt.
-
 
79
 *
-
 
80
 * @param n Ignored.
-
 
81
 * @param istate Ignored.
-
 
82
 */
74
void interrupt(int n, istate_t *istate)
83
void interrupt(int n, istate_t *istate)
75
{
84
{
76
    uint64_t intrcv;
85
    uint64_t intrcv;
77
    uint64_t data0;
86
    uint64_t data0;
78
 
87
 
79
    intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0);
88
    intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0);
80
    data0 = asi_u64_read(ASI_UDB_INTR_R, ASI_UDB_INTR_R_DATA_0);
89
    data0 = asi_u64_read(ASI_UDB_INTR_R, ASI_UDB_INTR_R_DATA_0);
81
 
90
 
82
    switch (data0) {
91
    irq_t *irq = irq_dispatch(data0);
83
#ifdef CONFIG_Z8530
-
 
84
    case Z8530_INTRCV_DATA0:
-
 
85
        if (kbd_type != KBD_Z8530)
-
 
86
            break;
92
    if (irq) {
87
        /*
93
        /*
88
         * So far, we know we got this interrupt through the FHC.
94
         * The IRQ handler was found.
-
 
95
         */
-
 
96
        irq->handler(irq, irq->arg);
89
         * Since we don't have enough information about the FHC and
97
    } else if (data0 > config.base) {
-
 
98
        /*
-
 
99
         * This is a cross-call.
90
         * because the interrupt looks like level sensitive,
100
         * data0 contains address of kernel function.
91
         * we cannot handle it by scheduling one of the level
101
         * We call the function only after we verify
92
         * interrupt traps. Call the interrupt handler directly.
102
         * it is on of the supported ones.
93
         */
103
         */
94
 
-
 
95
        if (z8530_belongs_to_kernel)
-
 
96
            z8530_interrupt();
-
 
97
        else
-
 
98
            ipc_irq_send_notif(0);
-
 
99
        fhc_clear_interrupt(central_fhc, data0);
-
 
100
        break;
-
 
101
 
-
 
102
#endif
-
 
103
    default:
-
 
104
        if (data0 > config.base) {
-
 
105
            /*
-
 
106
             * This is a cross-call.
-
 
107
             * data0 contains address of kernel function.
-
 
108
             * We call the function only after we verify
-
 
109
             * it is on of the supported ones.
-
 
110
             */
-
 
111
#ifdef CONFIG_SMP
104
#ifdef CONFIG_SMP
112
            if (data0 == (uintptr_t) tlb_shootdown_ipi_recv) {
105
        if (data0 == (uintptr_t) tlb_shootdown_ipi_recv) {
113
                tlb_shootdown_ipi_recv();
106
            tlb_shootdown_ipi_recv();
114
                break;
-
 
115
            }
-
 
116
#endif
-
 
117
        }
107
        }
-
 
108
#endif
-
 
109
    } else {
118
           
110
        /*
-
 
111
         * Spurious interrupt.
-
 
112
         */
-
 
113
#ifdef CONFIG_DEBUG
119
        printf("cpu%d: spurious interrupt (intrcv=%#llx, data0=%#llx)\n", CPU->id, intrcv, data0);
114
        printf("cpu%d: spurious interrupt (intrcv=%#llx, data0=%#llx)\n", CPU->id, intrcv, data0);
120
        break;
115
#endif
121
    }
116
    }
122
 
117
 
123
    membar();
118
    membar();
124
    asi_u64_write(ASI_INTR_RECEIVE, 0, 0);
119
    asi_u64_write(ASI_INTR_RECEIVE, 0, 0);
125
}
120
}