source: mainline/kernel/arch/ppc32/src/interrupt.c

Last change on this file was 1fbe639b, checked in by Jakub Jermar <jakub@…>, 6 years ago

Log spurious IRQ on ppc only once per occurrence

When there is no IRQ handler to claim an IRQ on ppc32, log the even
only once, and also acknowledge the interrupt in the pic so that the
same event does not get processed over and over again, looping in
exception_external().

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 * Copyright (c) 2006 Martin Decky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup kernel_ppc32_interrupt
30 * @{
31 */
32/** @file
33 */
34
35#include <ddi/irq.h>
36#include <interrupt.h>
37#include <arch/interrupt.h>
38#include <arch/istate.h>
39#include <stdint.h>
40#include <arch.h>
41#include <ipc/sysipc.h>
42#include <arch/drivers/pic.h>
43#include <arch/mm/tlb.h>
44#include <arch/mm/pht.h>
45#include <log.h>
46
47static uint32_t decrementer_value;
48
49void decrementer_start(uint32_t val)
50{
51 decrementer_value = val;
52 decrementer_restart();
53}
54
55void decrementer_restart(void)
56{
57 asm volatile (
58 "mtdec %[dec]\n"
59 :: [dec] "r" (decrementer_value)
60 );
61}
62
63void istate_decode(istate_t *istate)
64{
65 log_printf("r0 =%0#10" PRIx32 "\tr1 =%0#10" PRIx32 "\t"
66 "r2 =%0#10" PRIx32 "\n", istate->r0, istate->sp, istate->r2);
67
68 log_printf("r3 =%0#10" PRIx32 "\tr4 =%0#10" PRIx32 "\t"
69 "r5 =%0#10" PRIx32 "\n", istate->r3, istate->r4, istate->r5);
70
71 log_printf("r6 =%0#10" PRIx32 "\tr7 =%0#10" PRIx32 "\t"
72 "r8 =%0#10" PRIx32 "\n", istate->r6, istate->r7, istate->r8);
73
74 log_printf("r9 =%0#10" PRIx32 "\tr10=%0#10" PRIx32 "\t"
75 "r11=%0#10" PRIx32 "\n", istate->r9, istate->r10, istate->r11);
76
77 log_printf("r12=%0#10" PRIx32 "\tr13=%0#10" PRIx32 "\t"
78 "r14=%0#10" PRIx32 "\n", istate->r12, istate->r13, istate->r14);
79
80 log_printf("r15=%0#10" PRIx32 "\tr16=%0#10" PRIx32 "\t"
81 "r17=%0#10" PRIx32 "\n", istate->r15, istate->r16, istate->r17);
82
83 log_printf("r18=%0#10" PRIx32 "\tr19=%0#10" PRIx32 "\t"
84 "r20=%0#10" PRIx32 "\n", istate->r18, istate->r19, istate->r20);
85
86 log_printf("r21=%0#10" PRIx32 "\tr22=%0#10" PRIx32 "\t"
87 "r23=%0#10" PRIx32 "\n", istate->r21, istate->r22, istate->r23);
88
89 log_printf("r24=%0#10" PRIx32 "\tr25=%0#10" PRIx32 "\t"
90 "r26=%0#10" PRIx32 "\n", istate->r24, istate->r25, istate->r26);
91
92 log_printf("r27=%0#10" PRIx32 "\tr28=%0#10" PRIx32 "\t"
93 "r29=%0#10" PRIx32 "\n", istate->r27, istate->r28, istate->r29);
94
95 log_printf("r30=%0#10" PRIx32 "\tr31=%0#10" PRIx32 "\n",
96 istate->r30, istate->r31);
97
98 log_printf("cr =%0#10" PRIx32 "\tpc =%0#10" PRIx32 "\t"
99 "lr =%0#10" PRIx32 "\n", istate->cr, istate->pc, istate->lr);
100
101 log_printf("ctr=%0#10" PRIx32 "\txer=%0#10" PRIx32 "\t"
102 "dar=%0#10" PRIx32 "\n", istate->ctr, istate->xer, istate->dar);
103
104 log_printf("srr1=%0#10" PRIx32 "\n", istate->srr1);
105}
106
107/** External interrupts handler
108 *
109 */
110static void exception_external(unsigned int n, istate_t *istate)
111{
112 uint8_t inum;
113
114 while ((inum = pic_get_pending()) != 255) {
115 irq_t *irq = irq_dispatch_and_lock(inum);
116 if (irq) {
117 /*
118 * The IRQ handler was found.
119 */
120
121 if (irq->preack) {
122 /* Acknowledge the interrupt before processing */
123 if (irq->cir)
124 irq->cir(irq->cir_arg, irq->inr);
125 }
126
127 irq->handler(irq);
128
129 if (!irq->preack) {
130 if (irq->cir)
131 irq->cir(irq->cir_arg, irq->inr);
132 }
133
134 irq_spinlock_unlock(&irq->lock, false);
135 } else {
136 /*
137 * Spurious interrupt.
138 */
139#ifdef CONFIG_DEBUG
140 log(LF_ARCH, LVL_DEBUG, "cpu%u: spurious interrupt"
141 " (inum=%" PRIu8 ")", CPU->id, inum);
142#endif
143 pic_ack_interrupt(NULL, inum);
144 break;
145 }
146 }
147}
148
149static void exception_fp_unavailable(unsigned int n, istate_t *istate)
150{
151#ifdef CONFIG_FPU_LAZY
152 scheduler_fpu_lazy_request();
153 /*
154 * Propagate MSR_FP from MSR back to istate's SRR1, which will become
155 * the next MSR.
156 */
157 istate->srr1 |= msr_read() & MSR_FP;
158#else
159 fault_if_from_uspace(istate, "FPU fault.");
160 panic_badtrap(istate, n, "FPU fault.");
161#endif
162}
163
164static void exception_decrementer(unsigned int n, istate_t *istate)
165{
166 decrementer_restart();
167 clock();
168}
169
170/* Initialize basic tables for exception dispatching */
171void interrupt_init(void)
172{
173 exc_register(VECTOR_DATA_STORAGE, "data_storage", true,
174 pht_refill);
175 exc_register(VECTOR_INSTRUCTION_STORAGE, "instruction_storage", true,
176 pht_refill);
177 exc_register(VECTOR_EXTERNAL, "external", true,
178 exception_external);
179 exc_register(VECTOR_FP_UNAVAILABLE, "fp_unavailable", true,
180 exception_fp_unavailable);
181 exc_register(VECTOR_DECREMENTER, "timer", true,
182 exception_decrementer);
183 exc_register(VECTOR_ITLB_MISS, "itlb_miss", true,
184 tlb_refill);
185 exc_register(VECTOR_DTLB_MISS_LOAD, "dtlb_miss_load", true,
186 tlb_refill);
187 exc_register(VECTOR_DTLB_MISS_STORE, "dtlb_miss_store", true,
188 tlb_refill);
189}
190
191/** @}
192 */
Note: See TracBrowser for help on using the repository browser.