source: rtems/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c @ b80f920

4.115
Last change on this file since b80f920 was b80f920, checked in by Sebastian Huber <sebastian.huber@…>, on 04/15/14 at 11:36:35

bsp/qoriq: SMP support for IRQ support

  • Property mode set to 100644
File size: 8.1 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup QorIQ
5 *
6 * @brief Interrupt implementation.
7 */
8
9/*
10 * Copyright (c) 2010-2014 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#include <rtems.h>
24
25#include <libcpu/powerpc-utility.h>
26
27#include <bsp.h>
28#include <bsp/irq.h>
29#include <bsp/irq-generic.h>
30#include <bsp/vectors.h>
31#include <bsp/utility.h>
32#include <bsp/qoriq.h>
33
34#define VPR_MSK BSP_BBIT32(0)
35#define VPR_A BSP_BBIT32(1)
36#define VPR_P BSP_BBIT32(8)
37#define VPR_S BSP_BBIT32(9)
38#define VPR_PRIORITY(val) BSP_BFLD32(val, 12, 15)
39#define VPR_PRIORITY_GET(reg) BSP_BFLD32GET(reg, 12, 15)
40#define VPR_PRIORITY_SET(reg, val) BSP_BFLD32SET(reg, val, 12, 15)
41#define VPR_VECTOR(val) BSP_BFLD32(val, 16, 31)
42#define VPR_VECTOR_GET(reg) BSP_BFLD32GET(reg, 16, 31)
43#define VPR_VECTOR_SET(reg, val) BSP_BFLD32SET(reg, val, 16, 31)
44
45#define GCR_RST BSP_BBIT32(0)
46#define GCR_M BSP_BBIT32(2)
47
48#define SPURIOUS 0xffff
49
50static rtems_interrupt_lock lock =
51 RTEMS_INTERRUPT_LOCK_INITIALIZER("QorIQ IRQ");
52
53static const uint16_t vpr_and_dr_offsets [] = {
54        [0] = 0x10200 >> 4,
55        [1] = 0x10220 >> 4,
56        [2] = 0x10240 >> 4,
57        [3] = 0x10260 >> 4,
58        [4] = 0x10280 >> 4,
59        [5] = 0x102a0 >> 4,
60        [6] = 0x102c0 >> 4,
61        [7] = 0x102e0 >> 4,
62        [8] = 0x10300 >> 4,
63        [9] = 0x10320 >> 4,
64        [10] = 0x10340 >> 4,
65        [11] = 0x10360 >> 4,
66        [12] = 0x10380 >> 4,
67        [13] = 0x103a0 >> 4,
68        [14] = 0x103c0 >> 4,
69        [15] = 0x103e0 >> 4,
70        [16] = 0x10400 >> 4,
71        [17] = 0x10420 >> 4,
72        [18] = 0x10440 >> 4,
73        [19] = 0x10460 >> 4,
74        [20] = 0x10480 >> 4,
75        [21] = 0x104a0 >> 4,
76        [22] = 0x104c0 >> 4,
77        [23] = 0x104e0 >> 4,
78        [24] = 0x10500 >> 4,
79        [25] = 0x10520 >> 4,
80        [26] = 0x10540 >> 4,
81        [27] = 0x10560 >> 4,
82        [28] = 0x10580 >> 4,
83        [29] = 0x105a0 >> 4,
84        [30] = 0x105c0 >> 4,
85        [31] = 0x105e0 >> 4,
86        [32] = 0x10600 >> 4,
87        [33] = 0x10620 >> 4,
88        [34] = 0x10640 >> 4,
89        [35] = 0x10660 >> 4,
90        [36] = 0x10680 >> 4,
91        [37] = 0x106a0 >> 4,
92        [38] = 0x106c0 >> 4,
93        [39] = 0x106e0 >> 4,
94        [40] = 0x10700 >> 4,
95        [41] = 0x10720 >> 4,
96        [42] = 0x10740 >> 4,
97        [43] = 0x10760 >> 4,
98        [44] = 0x10780 >> 4,
99        [45] = 0x107a0 >> 4,
100        [46] = 0x107c0 >> 4,
101        [47] = 0x107e0 >> 4,
102        [48] = 0x10800 >> 4,
103        [49] = 0x10820 >> 4,
104        [50] = 0x10840 >> 4,
105        [51] = 0x10860 >> 4,
106        [52] = 0x10880 >> 4,
107        [53] = 0x108a0 >> 4,
108        [54] = 0x108c0 >> 4,
109        [55] = 0x108e0 >> 4,
110        [56] = 0x10900 >> 4,
111        [57] = 0x10920 >> 4,
112        [58] = 0x10940 >> 4,
113        [59] = 0x10960 >> 4,
114        [60] = 0x10980 >> 4,
115        [61] = 0x109a0 >> 4,
116        [62] = 0x109c0 >> 4,
117        [63] = 0x109e0 >> 4,
118        [QORIQ_IRQ_EXT_0] = 0x10000 >> 4,
119        [QORIQ_IRQ_EXT_1] = 0x10020 >> 4,
120        [QORIQ_IRQ_EXT_2] = 0x10040 >> 4,
121        [QORIQ_IRQ_EXT_3] = 0x10060 >> 4,
122        [QORIQ_IRQ_EXT_4] = 0x10080 >> 4,
123        [QORIQ_IRQ_EXT_5] = 0x100a0 >> 4,
124        [QORIQ_IRQ_EXT_6] = 0x100c0 >> 4,
125        [QORIQ_IRQ_EXT_7] = 0x100e0 >> 4,
126        [QORIQ_IRQ_EXT_8] = 0x10100 >> 4,
127        [QORIQ_IRQ_EXT_9] = 0x10120 >> 4,
128        [QORIQ_IRQ_EXT_10] = 0x10140 >> 4,
129        [QORIQ_IRQ_EXT_11] = 0x10160 >> 4,
130        [QORIQ_IRQ_IPI_0] = 0x010a0 >> 4,
131        [QORIQ_IRQ_IPI_1] = 0x010b0 >> 4,
132        [QORIQ_IRQ_IPI_2] = 0x010c0 >> 4,
133        [QORIQ_IRQ_IPI_3] = 0x010d0 >> 4,
134        [QORIQ_IRQ_MI_0] = 0x11600 >> 4,
135        [QORIQ_IRQ_MI_1] = 0x11620 >> 4,
136        [QORIQ_IRQ_MI_2] = 0x11640 >> 4,
137        [QORIQ_IRQ_MI_3] = 0x11660 >> 4,
138        [QORIQ_IRQ_MI_4] = 0x11680 >> 4,
139        [QORIQ_IRQ_MI_5] = 0x116a0 >> 4,
140        [QORIQ_IRQ_MI_6] = 0x116c0 >> 4,
141        [QORIQ_IRQ_MI_7] = 0x116e0 >> 4,
142        [QORIQ_IRQ_MSI_0] = 0x11c00 >> 4,
143        [QORIQ_IRQ_MSI_1] = 0x11c20 >> 4,
144        [QORIQ_IRQ_MSI_2] = 0x11c40 >> 4,
145        [QORIQ_IRQ_MSI_3] = 0x11c60 >> 4,
146        [QORIQ_IRQ_MSI_4] = 0x11c80 >> 4,
147        [QORIQ_IRQ_MSI_5] = 0x11ca0 >> 4,
148        [QORIQ_IRQ_MSI_6] = 0x11cc0 >> 4,
149        [QORIQ_IRQ_MSI_7] = 0x11ce0 >> 4,
150        [QORIQ_IRQ_GT_A_0] = 0x01120 >> 4,
151        [QORIQ_IRQ_GT_A_1] = 0x01160 >> 4,
152        [QORIQ_IRQ_GT_A_2] = 0x011a0 >> 4,
153        [QORIQ_IRQ_GT_A_3] = 0x011e0 >> 4,
154        [QORIQ_IRQ_GT_B_0] = 0x02120 >> 4,
155        [QORIQ_IRQ_GT_B_1] = 0x02160 >> 4,
156        [QORIQ_IRQ_GT_B_2] = 0x021a0 >> 4,
157        [QORIQ_IRQ_GT_B_3] = 0x021e0 >> 4
158};
159
160rtems_status_code qoriq_pic_set_priority(
161        rtems_vector_number vector,
162        int new_priority,
163        int *old_priority
164)
165{
166        rtems_status_code sc = RTEMS_SUCCESSFUL;
167        uint32_t old_vpr = 0;
168
169        if (bsp_interrupt_is_valid_vector(vector)) {
170                int offs = vpr_and_dr_offsets [vector] << 2;
171                volatile uint32_t *vpr = (volatile uint32_t *) &qoriq.pic + offs;
172
173                if (QORIQ_PIC_PRIORITY_IS_VALID(new_priority)) {
174                        rtems_interrupt_lock_context lock_context;
175
176                        rtems_interrupt_lock_acquire(&lock, &lock_context);
177                        old_vpr = *vpr;
178                        *vpr = VPR_PRIORITY_SET(old_vpr, (uint32_t) new_priority);
179                        rtems_interrupt_lock_release(&lock, &lock_context);
180                } else if (new_priority < 0) {
181                        old_vpr = *vpr;
182                } else {
183                        sc = RTEMS_INVALID_PRIORITY;
184                }
185        } else {
186                sc = RTEMS_INVALID_ID;
187        }
188
189        if (old_priority != NULL) {
190                *old_priority = (int) VPR_PRIORITY_GET(old_vpr);
191        }
192
193        return sc;
194}
195
196rtems_status_code qoriq_pic_set_affinity(
197        rtems_vector_number vector,
198        uint32_t processor_index
199)
200{
201        rtems_status_code sc = RTEMS_SUCCESSFUL;
202
203        if (bsp_interrupt_is_valid_vector(vector)) {
204                if (processor_index <= 1) {
205                        int offs = (vpr_and_dr_offsets [vector] << 2) + 4;
206                        volatile uint32_t *dr = (volatile uint32_t *) &qoriq.pic + offs;
207
208                        *dr = BSP_BIT32(processor_index);
209                } else {
210                        sc = RTEMS_INVALID_NUMBER;
211                }
212        } else {
213                sc = RTEMS_INVALID_ID;
214        }
215
216        return sc;
217}
218
219static rtems_status_code pic_vector_enable(rtems_vector_number vector, uint32_t msk)
220{
221        rtems_status_code sc = RTEMS_SUCCESSFUL;
222
223        if (bsp_interrupt_is_valid_vector(vector)) {
224                int offs = vpr_and_dr_offsets [vector] << 2;
225                volatile uint32_t *vpr = (volatile uint32_t *) &qoriq.pic + offs;
226                rtems_interrupt_lock_context lock_context;
227
228                rtems_interrupt_lock_acquire(&lock, &lock_context);
229                *vpr = (*vpr & ~VPR_MSK) | msk;
230                rtems_interrupt_lock_release(&lock, &lock_context);
231        }
232
233        return sc;
234}
235
236rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
237{
238        return pic_vector_enable(vector, 0);
239}
240
241rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
242{
243        return pic_vector_enable(vector, VPR_MSK);
244}
245
246static void qoriq_interrupt_dispatch(void)
247{
248        rtems_vector_number vector = qoriq.pic.iack;
249
250        if (vector != SPURIOUS) {
251                uint32_t msr = ppc_external_exceptions_enable();
252
253                bsp_interrupt_handler_dispatch(vector);
254
255                ppc_external_exceptions_disable(msr);
256
257                qoriq.pic.eoi = 0;
258                qoriq.pic.whoami;
259        } else {
260                bsp_interrupt_handler_default(vector);
261        }
262}
263
264#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER
265static int qoriq_external_exception_handler(BSP_Exception_frame *frame, unsigned exception_number)
266{
267        qoriq_interrupt_dispatch();
268
269        return 0;
270}
271#else
272void bsp_interrupt_dispatch(void)
273{
274        qoriq_interrupt_dispatch();
275}
276#endif
277
278static bool pic_is_ipi(rtems_vector_number vector)
279{
280        return QORIQ_IRQ_IPI_0 <= vector && vector <= QORIQ_IRQ_IPI_3;
281}
282
283static void pic_reset(void)
284{
285        qoriq.pic.gcr = GCR_RST;
286        while ((qoriq.pic.gcr & GCR_RST) != 0) {
287                /* Wait */
288        }
289}
290
291static void pic_global_timer_init(void)
292{
293        int i = 0;
294
295        qoriq.pic.tcra = 0;
296        qoriq.pic.tcrb = 0;
297
298        for (i = 0; i < 4; ++i) {
299                qoriq.pic.gta [0].bcr = GTBCR_CI;
300                qoriq.pic.gtb [0].bcr = GTBCR_CI;
301        }
302}
303
304rtems_status_code bsp_interrupt_facility_initialize(void)
305{
306        rtems_vector_number i = 0;
307        uint32_t processor_id = ppc_processor_id();
308
309#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER
310        if (ppc_exc_set_handler(ASM_EXT_VECTOR, qoriq_external_exception_handler)) {
311                return RTEMS_IO_ERROR;
312        }
313#endif
314
315        if (processor_id == 0) {
316                /* Core 0 must do the basic initialization */
317
318                pic_reset();
319
320                for (i = BSP_INTERRUPT_VECTOR_MIN; i <= BSP_INTERRUPT_VECTOR_MAX; ++i) {
321                        volatile uint32_t *base = (volatile uint32_t *) &qoriq.pic;
322                        int offs = vpr_and_dr_offsets [i] << 2;
323                        volatile uint32_t *vpr = base + offs;
324
325                        *vpr = VPR_MSK | VPR_P | VPR_PRIORITY(1) | VPR_VECTOR(i);
326
327                        if (!pic_is_ipi(i)) {
328                                volatile uint32_t *dr = base + offs + 4;
329
330                                *dr = 0x1;
331                        }
332                }
333
334                qoriq.pic.mer03 = 0xf;
335                qoriq.pic.mer47 = 0xf;
336                qoriq.pic.svr = SPURIOUS;
337                qoriq.pic.gcr = GCR_M;
338
339                pic_global_timer_init();
340        }
341
342        qoriq.pic.ctpr = 0;
343
344        for (i = BSP_INTERRUPT_VECTOR_MIN; i <= BSP_INTERRUPT_VECTOR_MAX; ++i) {
345                qoriq.pic.iack;
346                qoriq.pic.eoi = 0;
347                qoriq.pic.whoami;
348        }
349
350        return RTEMS_SUCCESSFUL;
351}
Note: See TracBrowser for help on using the repository browser.