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