First version
[3rdparty/ote_partner/tlk.git] / platform / armemu / interrupts.c
1 /*
2  * Copyright (c) 2008 Travis Geiselbrecht
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 #include <err.h>
24 #include <sys/types.h>
25 #include <debug.h>
26 #include <reg.h>
27 #include <kernel/thread.h>
28 #include <platform/interrupts.h>
29 #include <platform/armemu.h>
30 #include <arch/ops.h>
31 #include <arch/arm.h>
32 #include "platform_p.h"
33
34 struct int_handler_struct {
35         int_handler handler;
36         void *arg;
37 };
38
39 static struct int_handler_struct int_handler_table[PIC_MAX_INT];
40
41 void platform_init_interrupts(void)
42 {
43         // mask all the interrupts
44         *REG32(PIC_MASK_LATCH) = 0xffffffff;
45 }
46
47 status_t mask_interrupt(unsigned int vector)
48 {
49         if (vector >= PIC_MAX_INT)
50                 return ERR_INVALID_ARGS;
51
52 //      dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector);
53
54         enter_critical_section();
55
56         *REG32(PIC_MASK_LATCH) = 1 << vector;
57
58         exit_critical_section();
59
60         return NO_ERROR;
61 }
62
63 status_t unmask_interrupt(unsigned int vector)
64 {
65         if (vector >= PIC_MAX_INT)
66                 return ERR_INVALID_ARGS;
67
68 //      dprintf("%s: vector %d\n", __PRETTY_FUNCTION__, vector);
69
70         enter_critical_section();
71
72         *REG32(PIC_UNMASK_LATCH) = 1 << vector;
73
74         exit_critical_section();
75
76         return NO_ERROR;
77 }
78
79 enum handler_return platform_irq(struct arm_iframe *frame)
80 {
81         // get the current vector
82         unsigned int vector = *REG32(PIC_CURRENT_NUM);
83         if (vector == 0xffffffff)
84                 return INT_NO_RESCHEDULE;
85
86         THREAD_STATS_INC(interrupts);
87
88 //      printf("platform_irq: spsr 0x%x, pc 0x%x, currthread %p, vector %d\n", frame->spsr, frame->pc, current_thread, vector);
89
90         // deliver the interrupt
91         enum handler_return ret; 
92
93         ret = INT_NO_RESCHEDULE;
94         if (int_handler_table[vector].handler)
95                 ret = int_handler_table[vector].handler(int_handler_table[vector].arg);
96
97 //      dprintf("platform_irq: exit %d\n", ret);
98
99         return ret;
100 }
101
102 void platform_fiq(struct arm_iframe *frame)
103 {
104         panic("FIQ: unimplemented\n");
105 }
106
107 void register_int_handler(unsigned int vector, int_handler handler, void *arg)
108 {
109         if (vector >= PIC_MAX_INT)
110                 panic("register_int_handler: vector out of range %d\n", vector);
111
112         enter_critical_section();
113
114         int_handler_table[vector].handler = handler;
115         int_handler_table[vector].arg = arg;
116
117         exit_critical_section();
118 }
119