1 /*
2 * Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief interrupt management code for riscv SOCs supporting the riscv
10 privileged architecture specification
11 */
12 #include <irq.h>
13
arch_irq_enable(unsigned int irq)14 void arch_irq_enable(unsigned int irq)
15 {
16 uint32_t mie;
17
18 #if defined(CONFIG_RISCV_HAS_PLIC)
19 unsigned int level = irq_get_level(irq);
20
21 if (level == 2) {
22 irq = irq_from_level_2(irq);
23 riscv_plic_irq_enable(irq);
24 return;
25 }
26 #endif
27
28 /*
29 * CSR mie register is updated using atomic instruction csrrs
30 * (atomic read and set bits in CSR register)
31 */
32 __asm__ volatile ("csrrs %0, mie, %1\n"
33 : "=r" (mie)
34 : "r" (1 << irq));
35 }
36
arch_irq_disable(unsigned int irq)37 void arch_irq_disable(unsigned int irq)
38 {
39 uint32_t mie;
40
41 #if defined(CONFIG_RISCV_HAS_PLIC)
42 unsigned int level = irq_get_level(irq);
43
44 if (level == 2) {
45 irq = irq_from_level_2(irq);
46 riscv_plic_irq_disable(irq);
47 return;
48 }
49 #endif
50
51 /*
52 * Use atomic instruction csrrc to disable device interrupt in mie CSR.
53 * (atomic read and clear bits in CSR register)
54 */
55 __asm__ volatile ("csrrc %0, mie, %1\n"
56 : "=r" (mie)
57 : "r" (1 << irq));
58 };
59
arch_irq_priority_set(unsigned int irq,unsigned int prio)60 void arch_irq_priority_set(unsigned int irq, unsigned int prio)
61 {
62 #if defined(CONFIG_RISCV_HAS_PLIC)
63 unsigned int level = irq_get_level(irq);
64
65 if (level == 2) {
66 irq = irq_from_level_2(irq);
67 riscv_plic_set_priority(irq, prio);
68 }
69 #endif
70
71 return ;
72 }
73
arch_irq_is_enabled(unsigned int irq)74 int arch_irq_is_enabled(unsigned int irq)
75 {
76 uint32_t mie;
77
78 #if defined(CONFIG_RISCV_HAS_PLIC)
79 unsigned int level = irq_get_level(irq);
80
81 if (level == 2) {
82 irq = irq_from_level_2(irq);
83 return riscv_plic_irq_is_enabled(irq);
84 }
85 #endif
86
87 __asm__ volatile ("csrr %0, mie" : "=r" (mie));
88
89 return !!(mie & (1 << irq));
90 }
91
92 #if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT)
soc_interrupt_init(void)93 __weak void soc_interrupt_init(void)
94 {
95 /* ensure that all interrupts are disabled */
96 (void)irq_lock();
97
98 __asm__ volatile ("csrwi mie, 0\n"
99 "csrwi mip, 0\n");
100 }
101 #endif
102