1 /*
2  * Copyright (c) 2008 Travis Geiselbrecht
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #include <lk/err.h>
9 #include <sys/types.h>
10 #include <lk/debug.h>
11 #include <lk/reg.h>
12 #include <kernel/thread.h>
13 #include <kernel/debug.h>
14 #include <platform/interrupts.h>
15 #include <platform/armemu.h>
16 #include <arch/ops.h>
17 #include <arch/arm.h>
18 #include "platform_p.h"
19 
20 struct int_handler_struct {
21     int_handler handler;
22     void *arg;
23 };
24 
25 static struct int_handler_struct int_handler_table[PIC_MAX_INT];
26 
platform_init_interrupts(void)27 void platform_init_interrupts(void) {
28     // mask all the interrupts
29     *REG32(PIC_MASK_LATCH) = 0xffffffff;
30 }
31 
mask_interrupt(unsigned int vector)32 status_t mask_interrupt(unsigned int vector) {
33     if (vector >= PIC_MAX_INT)
34         return ERR_INVALID_ARGS;
35 
36 //  dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector);
37 
38     *REG32(PIC_MASK_LATCH) = 1 << vector;
39 
40     return NO_ERROR;
41 }
42 
unmask_interrupt(unsigned int vector)43 status_t unmask_interrupt(unsigned int vector) {
44     if (vector >= PIC_MAX_INT)
45         return ERR_INVALID_ARGS;
46 
47 //  dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector);
48 
49     *REG32(PIC_UNMASK_LATCH) = 1 << vector;
50 
51     return NO_ERROR;
52 }
53 
platform_irq(struct arm_iframe * frame)54 enum handler_return platform_irq(struct arm_iframe *frame) {
55     // get the current vector
56     unsigned int vector = *REG32(PIC_CURRENT_NUM);
57     if (vector == 0xffffffff)
58         return INT_NO_RESCHEDULE;
59 
60     THREAD_STATS_INC(interrupts);
61     KEVLOG_IRQ_ENTER(vector);
62 
63 //  printf("platform_irq: spsr 0x%x, pc 0x%x, currthread %p, vector %d\n", frame->spsr, frame->pc, current_thread, vector);
64 
65     // deliver the interrupt
66     enum handler_return ret;
67 
68     ret = INT_NO_RESCHEDULE;
69     if (int_handler_table[vector].handler)
70         ret = int_handler_table[vector].handler(int_handler_table[vector].arg);
71 
72 //  dprintf("platform_irq: exit %d\n", ret);
73 
74     KEVLOG_IRQ_EXIT(vector);
75 
76     return ret;
77 }
78 
platform_fiq(struct arm_iframe * frame)79 void platform_fiq(struct arm_iframe *frame) {
80     panic("FIQ: unimplemented\n");
81 }
82 
register_int_handler(unsigned int vector,int_handler handler,void * arg)83 void register_int_handler(unsigned int vector, int_handler handler, void *arg) {
84     if (vector >= PIC_MAX_INT)
85         panic("register_int_handler: vector out of range %d\n", vector);
86 
87     int_handler_table[vector].handler = handler;
88     int_handler_table[vector].arg = arg;
89 }
90 
91