source: rtems/bsps/powerpc/qoriq/irq/irq.c @ c7b4eca7

Last change on this file since c7b4eca7 was c7b4eca7, checked in by Sebastian Huber <sebastian.huber@…>, on 07/27/21 at 07:58:43

bsps/irq: bsp_interrupt_facility_initialize()

Do not return a status code in bsp_interrupt_facility_initialize() since this
leads to unreachable code in bsp_interrupt_initialize(). Use RTEMS_DEBUG
assertions in bsp_interrupt_facility_initialize() if necessary.

  • Property mode set to 100644
File size: 12.2 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSBSPsPowerPCQorIQ
5 *
6 * @brief Interrupt implementation.
7 */
8
9/*
10 * Copyright (c) 2010, 2017 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 <sys/param.h>
24
25#include <rtems.h>
26
27#include <libcpu/powerpc-utility.h>
28
29#include <asm/epapr_hcalls.h>
30
31#include <bsp.h>
32#include <bsp/irq.h>
33#include <bsp/irq-generic.h>
34#include <bsp/vectors.h>
35#include <bsp/utility.h>
36#include <bsp/qoriq.h>
37
38#ifdef RTEMS_SMP
39#include <rtems/score/smpimpl.h>
40#endif
41
42RTEMS_INTERRUPT_LOCK_DEFINE(static, lock, "QorIQ IRQ")
43
44#define SPURIOUS 0xffff
45
46#ifdef QORIQ_IS_HYPERVISOR_GUEST
47
48rtems_status_code bsp_interrupt_set_affinity(
49        rtems_vector_number vector,
50        const Processor_mask *affinity
51)
52{
53        uint32_t config;
54        unsigned int priority;
55        uint32_t destination;
56        uint32_t new_destination;
57        rtems_interrupt_lock_context lock_context;
58
59        new_destination = _Processor_mask_Find_last_set(affinity) - 1;
60
61        rtems_interrupt_lock_acquire(&lock, &lock_context);
62        ev_int_get_config(vector, &config, &priority, &destination);
63        ev_int_set_config(vector, config, priority, new_destination);
64        rtems_interrupt_lock_release(&lock, &lock_context);
65        return RTEMS_SUCCESSFUL;
66}
67
68rtems_status_code bsp_interrupt_get_affinity(
69        rtems_vector_number vector,
70        Processor_mask *affinity
71)
72{
73        uint32_t config;
74        unsigned int priority;
75        uint32_t destination;
76
77        ev_int_get_config(vector, &config, &priority, &destination);
78        _Processor_mask_From_uint32_t(affinity, destination, 0);
79        return RTEMS_SUCCESSFUL;
80}
81
82rtems_status_code bsp_interrupt_get_attributes(
83  rtems_vector_number         vector,
84  rtems_interrupt_attributes *attributes
85)
86{
87  return RTEMS_SUCCESSFUL;
88}
89
90rtems_status_code bsp_interrupt_is_pending(
91  rtems_vector_number vector,
92  bool               *pending
93)
94{
95  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
96  bsp_interrupt_assert(pending != NULL);
97  *pending = false;
98  return RTEMS_UNSATISFIED;
99}
100
101rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
102{
103  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
104  return RTEMS_UNSATISFIED;
105}
106
107#if defined(RTEMS_SMP)
108rtems_status_code bsp_interrupt_raise_on(
109  rtems_vector_number vector,
110  uint32_t            cpu_index
111)
112{
113  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
114  return RTEMS_UNSATISFIED;
115}
116#endif
117
118rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
119{
120  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
121  return RTEMS_UNSATISFIED;
122}
123
124rtems_status_code bsp_interrupt_vector_is_enabled(
125  rtems_vector_number vector,
126  bool               *enabled
127)
128{
129  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
130  bsp_interrupt_assert(enabled != NULL);
131  *enabled = false;
132  return RTEMS_UNSATISFIED;
133}
134
135rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
136{
137        bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
138        ev_int_set_mask(vector, 0);
139        return RTEMS_SUCCESSFUL;
140}
141
142rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
143{
144        bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
145        ev_int_set_mask(vector, 1);
146        return RTEMS_SUCCESSFUL;
147}
148
149void bsp_interrupt_dispatch(uintptr_t exception_number)
150{
151        unsigned int vector;
152
153        if (exception_number == 10) {
154                qoriq_decrementer_dispatch();
155                return;
156        }
157
158#ifdef RTEMS_SMP
159        if (exception_number == 36) {
160                _SMP_Inter_processor_interrupt_handler(_Per_CPU_Get());
161                return;
162        }
163#endif
164
165        /*
166         * This works only if the "has-external-proxy" property is present in the
167         * "epapr,hv-pic" device tree node.
168         */
169        vector = PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_EPR);
170
171        if (vector != SPURIOUS) {
172                uint32_t msr;
173
174                msr = ppc_external_exceptions_enable();
175                bsp_interrupt_handler_dispatch(vector);
176                ppc_external_exceptions_disable(msr);
177
178                ev_int_eoi(vector);
179        } else {
180                bsp_interrupt_handler_default(vector);
181        }
182}
183
184void bsp_interrupt_facility_initialize(void)
185{
186        unsigned int i;
187
188        for (i = 0; i < BSP_INTERRUPT_VECTOR_COUNT; ++i) {
189                uint32_t config;
190                unsigned int priority;
191                uint32_t destination;
192                unsigned int err;
193
194                err = ev_int_get_config(i, &config, &priority, &destination);
195                if (err != EV_SUCCESS)
196                        continue;
197
198                priority = QORIQ_PIC_PRIORITY_DEFAULT;
199
200                ev_int_set_config(i, config, priority, destination);
201        }
202
203        return RTEMS_SUCCESSFUL;
204}
205
206#else /* !QORIQ_IS_HYPERVISOR_GUEST */
207
208#define VPR_MSK BSP_BBIT32(0)
209#define VPR_A BSP_BBIT32(1)
210#define VPR_P BSP_BBIT32(8)
211#define VPR_S BSP_BBIT32(9)
212#define VPR_PRIORITY(val) BSP_BFLD32(val, 12, 15)
213#define VPR_PRIORITY_GET(reg) BSP_BFLD32GET(reg, 12, 15)
214#define VPR_PRIORITY_SET(reg, val) BSP_BFLD32SET(reg, val, 12, 15)
215#define VPR_VECTOR(val) BSP_BFLD32(val, 16, 31)
216#define VPR_VECTOR_GET(reg) BSP_BFLD32GET(reg, 16, 31)
217#define VPR_VECTOR_SET(reg, val) BSP_BFLD32SET(reg, val, 16, 31)
218
219#define GCR_RST BSP_BBIT32(0)
220#define GCR_M BSP_BBIT32(2)
221
222#define SRC_CFG_IDX(i) ((i) - QORIQ_IRQ_EXT_BASE)
223
224static const uint16_t src_cfg_offsets [] = {
225        [SRC_CFG_IDX(QORIQ_IRQ_EXT_0)] = 0x10000 >> 4,
226        [SRC_CFG_IDX(QORIQ_IRQ_EXT_1)] = 0x10020 >> 4,
227        [SRC_CFG_IDX(QORIQ_IRQ_EXT_2)] = 0x10040 >> 4,
228        [SRC_CFG_IDX(QORIQ_IRQ_EXT_3)] = 0x10060 >> 4,
229        [SRC_CFG_IDX(QORIQ_IRQ_EXT_4)] = 0x10080 >> 4,
230        [SRC_CFG_IDX(QORIQ_IRQ_EXT_5)] = 0x100a0 >> 4,
231        [SRC_CFG_IDX(QORIQ_IRQ_EXT_6)] = 0x100c0 >> 4,
232        [SRC_CFG_IDX(QORIQ_IRQ_EXT_7)] = 0x100e0 >> 4,
233        [SRC_CFG_IDX(QORIQ_IRQ_EXT_8)] = 0x10100 >> 4,
234        [SRC_CFG_IDX(QORIQ_IRQ_EXT_9)] = 0x10120 >> 4,
235        [SRC_CFG_IDX(QORIQ_IRQ_EXT_10)] = 0x10140 >> 4,
236        [SRC_CFG_IDX(QORIQ_IRQ_EXT_11)] = 0x10160 >> 4,
237        [SRC_CFG_IDX(QORIQ_IRQ_IPI_0)] = 0x010a0 >> 4,
238        [SRC_CFG_IDX(QORIQ_IRQ_IPI_1)] = 0x010b0 >> 4,
239        [SRC_CFG_IDX(QORIQ_IRQ_IPI_2)] = 0x010c0 >> 4,
240        [SRC_CFG_IDX(QORIQ_IRQ_IPI_3)] = 0x010d0 >> 4,
241        [SRC_CFG_IDX(QORIQ_IRQ_MI_0)] = 0x11600 >> 4,
242        [SRC_CFG_IDX(QORIQ_IRQ_MI_1)] = 0x11620 >> 4,
243        [SRC_CFG_IDX(QORIQ_IRQ_MI_2)] = 0x11640 >> 4,
244        [SRC_CFG_IDX(QORIQ_IRQ_MI_3)] = 0x11660 >> 4,
245        [SRC_CFG_IDX(QORIQ_IRQ_MI_4)] = 0x11680 >> 4,
246        [SRC_CFG_IDX(QORIQ_IRQ_MI_5)] = 0x116a0 >> 4,
247        [SRC_CFG_IDX(QORIQ_IRQ_MI_6)] = 0x116c0 >> 4,
248        [SRC_CFG_IDX(QORIQ_IRQ_MI_7)] = 0x116e0 >> 4,
249        [SRC_CFG_IDX(QORIQ_IRQ_MSI_0)] = 0x11c00 >> 4,
250        [SRC_CFG_IDX(QORIQ_IRQ_MSI_1)] = 0x11c20 >> 4,
251        [SRC_CFG_IDX(QORIQ_IRQ_MSI_2)] = 0x11c40 >> 4,
252        [SRC_CFG_IDX(QORIQ_IRQ_MSI_3)] = 0x11c60 >> 4,
253        [SRC_CFG_IDX(QORIQ_IRQ_MSI_4)] = 0x11c80 >> 4,
254        [SRC_CFG_IDX(QORIQ_IRQ_MSI_5)] = 0x11ca0 >> 4,
255        [SRC_CFG_IDX(QORIQ_IRQ_MSI_6)] = 0x11cc0 >> 4,
256        [SRC_CFG_IDX(QORIQ_IRQ_MSI_7)] = 0x11ce0 >> 4,
257        [SRC_CFG_IDX(QORIQ_IRQ_GT_A_0)] = 0x01120 >> 4,
258        [SRC_CFG_IDX(QORIQ_IRQ_GT_A_1)] = 0x01160 >> 4,
259        [SRC_CFG_IDX(QORIQ_IRQ_GT_A_2)] = 0x011a0 >> 4,
260        [SRC_CFG_IDX(QORIQ_IRQ_GT_A_3)] = 0x011e0 >> 4,
261        [SRC_CFG_IDX(QORIQ_IRQ_GT_B_0)] = 0x02120 >> 4,
262        [SRC_CFG_IDX(QORIQ_IRQ_GT_B_1)] = 0x02160 >> 4,
263        [SRC_CFG_IDX(QORIQ_IRQ_GT_B_2)] = 0x021a0 >> 4,
264        [SRC_CFG_IDX(QORIQ_IRQ_GT_B_3)] = 0x021e0 >> 4
265};
266
267static volatile qoriq_pic_src_cfg *get_src_cfg(rtems_vector_number vector)
268{
269        uint32_t n = MIN(RTEMS_ARRAY_SIZE(qoriq.pic.ii_0), QORIQ_IRQ_EXT_BASE);
270
271        if (vector < n) {
272                return &qoriq.pic.ii_0 [vector];
273        } else if (vector < QORIQ_IRQ_EXT_BASE) {
274                return &qoriq.pic.ii_1 [vector - n];
275        } else {
276                uintptr_t offs = ((uintptr_t)
277                        src_cfg_offsets [vector - QORIQ_IRQ_EXT_BASE]) << 4;
278
279                return (volatile qoriq_pic_src_cfg *) ((uintptr_t) &qoriq.pic + offs);
280        }
281}
282
283rtems_status_code qoriq_pic_set_priority(
284        rtems_vector_number vector,
285        int new_priority,
286        int *old_priority
287)
288{
289        rtems_status_code sc = RTEMS_SUCCESSFUL;
290        uint32_t old_vpr = 0;
291
292        if (bsp_interrupt_is_valid_vector(vector)) {
293                volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);
294
295                if (QORIQ_PIC_PRIORITY_IS_VALID(new_priority)) {
296                        rtems_interrupt_lock_context lock_context;
297
298                        rtems_interrupt_lock_acquire(&lock, &lock_context);
299                        old_vpr = src_cfg->vpr;
300                        src_cfg->vpr = VPR_PRIORITY_SET(old_vpr, (uint32_t) new_priority);
301                        rtems_interrupt_lock_release(&lock, &lock_context);
302                } else if (new_priority < 0) {
303                        old_vpr = src_cfg->vpr;
304                } else {
305                        sc = RTEMS_INVALID_PRIORITY;
306                }
307        } else {
308                sc = RTEMS_INVALID_ID;
309        }
310
311        if (old_priority != NULL) {
312                *old_priority = (int) VPR_PRIORITY_GET(old_vpr);
313        }
314
315        return sc;
316}
317
318rtems_status_code bsp_interrupt_set_affinity(
319        rtems_vector_number vector,
320        const Processor_mask *affinity
321)
322{
323        volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);
324
325        src_cfg->dr = _Processor_mask_To_uint32_t(affinity, 0);
326        return RTEMS_SUCCESSFUL;
327}
328
329rtems_status_code bsp_interrupt_get_affinity(
330        rtems_vector_number vector,
331        Processor_mask *affinity
332)
333{
334        volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);
335
336        _Processor_mask_From_uint32_t(affinity, src_cfg->dr, 0);
337        return RTEMS_SUCCESSFUL;
338}
339
340static void pic_vector_enable(rtems_vector_number vector, uint32_t msk)
341{
342        volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);
343        rtems_interrupt_lock_context lock_context;
344
345        bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
346
347        rtems_interrupt_lock_acquire(&lock, &lock_context);
348        src_cfg->vpr = (src_cfg->vpr & ~VPR_MSK) | msk;
349        rtems_interrupt_lock_release(&lock, &lock_context);
350}
351
352rtems_status_code bsp_interrupt_get_attributes(
353  rtems_vector_number         vector,
354  rtems_interrupt_attributes *attributes
355)
356{
357  return RTEMS_SUCCESSFUL;
358}
359
360rtems_status_code bsp_interrupt_is_pending(
361  rtems_vector_number vector,
362  bool               *pending
363)
364{
365  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
366  bsp_interrupt_assert(pending != NULL);
367  *pending = false;
368  return RTEMS_UNSATISFIED;
369}
370
371rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
372{
373  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
374  return RTEMS_UNSATISFIED;
375}
376
377#if defined(RTEMS_SMP)
378rtems_status_code bsp_interrupt_raise_on(
379  rtems_vector_number vector,
380  uint32_t            cpu_index
381)
382{
383  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
384  return RTEMS_UNSATISFIED;
385}
386#endif
387
388rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
389{
390  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
391  return RTEMS_UNSATISFIED;
392}
393
394rtems_status_code bsp_interrupt_vector_is_enabled(
395  rtems_vector_number vector,
396  bool               *enabled
397)
398{
399  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
400  bsp_interrupt_assert(enabled != NULL);
401  *enabled = false;
402  return RTEMS_UNSATISFIED;
403}
404
405rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
406{
407        pic_vector_enable(vector, 0);
408        return RTEMS_SUCCESSFUL;
409}
410
411rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
412{
413        pic_vector_enable(vector, VPR_MSK);
414        return RTEMS_SUCCESSFUL;
415}
416
417void bsp_interrupt_dispatch(uintptr_t exception_number)
418{
419        rtems_vector_number vector = qoriq.pic.iack;
420
421        if (vector != SPURIOUS) {
422                uint32_t msr = ppc_external_exceptions_enable();
423
424                bsp_interrupt_handler_dispatch(vector);
425
426                ppc_external_exceptions_disable(msr);
427
428                qoriq.pic.eoi = 0;
429                qoriq.pic.whoami;
430        } else {
431                bsp_interrupt_handler_default(vector);
432        }
433}
434
435static bool pic_is_ipi(rtems_vector_number vector)
436{
437        return QORIQ_IRQ_IPI_0 <= vector && vector <= QORIQ_IRQ_IPI_3;
438}
439
440static void pic_reset(void)
441{
442        qoriq.pic.gcr = GCR_RST;
443        while ((qoriq.pic.gcr & GCR_RST) != 0) {
444                /* Wait */
445        }
446}
447
448static void pic_global_timer_init(void)
449{
450        int i = 0;
451
452        qoriq.pic.tcra = 0;
453        qoriq.pic.tcrb = 0;
454
455        for (i = 0; i < 4; ++i) {
456                qoriq.pic.gta [0].bcr = GTBCR_CI;
457                qoriq.pic.gtb [0].bcr = GTBCR_CI;
458        }
459}
460
461void bsp_interrupt_facility_initialize(void)
462{
463        rtems_vector_number i = 0;
464        uint32_t processor_id = ppc_processor_id();
465
466        if (processor_id == 0) {
467                /* Core 0 must do the basic initialization */
468
469                pic_reset();
470
471                for (i = 0; i < BSP_INTERRUPT_VECTOR_COUNT; ++i) {
472                        volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(i);
473
474                        src_cfg->vpr = VPR_MSK | VPR_P
475                                | VPR_PRIORITY(QORIQ_PIC_PRIORITY_DEFAULT) | VPR_VECTOR(i);
476
477                        if (!pic_is_ipi(i)) {
478                                src_cfg->dr = 0x1;
479                        }
480                }
481
482                qoriq.pic.mer03 = 0xf;
483                qoriq.pic.mer47 = 0xf;
484                qoriq.pic.svr = SPURIOUS;
485                qoriq.pic.gcr = GCR_M;
486
487                pic_global_timer_init();
488        }
489
490        qoriq.pic.ctpr = 0;
491
492        for (i = 0; i < BSP_INTERRUPT_VECTOR_COUNT; ++i) {
493                qoriq.pic.iack;
494                qoriq.pic.eoi = 0;
495                qoriq.pic.whoami;
496        }
497}
498
499#endif /* QORIQ_IS_HYPERVISOR_GUEST */
Note: See TracBrowser for help on using the repository browser.