xref: /nrf52832-nimble/rt-thread/libcpu/risc-v/common/riscv-plic.h (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * Copyright (c) 2006-2018, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2018-10-03     Bernard      The first version
9  */
10 
11 #ifndef RISCV_PLIC_H__
12 #define RISCV_PLIC_H__
13 
14 #ifndef PLIC_BASE_ADDR
15 #define PLIC_BASE_ADDR 0x0
16 #endif
17 
18 /* Priority Register - 32 bits per source */
19 #define PLIC_PRIORITY_OFFSET (0x00000000UL)
20 #define PLIC_PRIORITY_SHIFT_PER_SOURCE 2
21 
22 /* Pending Register - 1 bit per soirce */
23 #define PLIC_PENDING_OFFSET (0x00001000UL)
24 #define PLIC_PENDING_SHIFT_PER_SOURCE 0
25 
26 /* Enable Register - 0x80 per target */
27 #define PLIC_ENABLE_OFFSET (0x00002000UL)
28 #define PLIC_ENABLE_SHIFT_PER_TARGET 7
29 
30 /* Priority Threshold Register - 0x1000 per target */
31 #define PLIC_THRESHOLD_OFFSET (0x00200000UL)
32 #define PLIC_THRESHOLD_SHIFT_PER_TARGET 12
33 
34 /* Claim Register - 0x1000 per target */
35 #define PLIC_CLAIM_OFFSET (0x00200004UL)
36 #define PLIC_CLAIM_SHIFT_PER_TARGET 12
37 
38 #if defined(__GNUC__) && !defined(__ASSEMBLER__)
__plic_set_feature(unsigned int feature)39 __attribute__((always_inline)) static inline void __plic_set_feature(unsigned int feature)
40 {
41     volatile unsigned int *feature_ptr = (volatile unsigned int *)PLIC_BASE_ADDR;
42     *feature_ptr = feature;
43 }
44 
__plic_set_threshold(unsigned int threshold)45 __attribute__((always_inline)) static inline void __plic_set_threshold(unsigned int threshold)
46 {
47     unsigned int hart_id = read_csr(mhartid);
48     volatile unsigned int *threshold_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
49                                                                      PLIC_THRESHOLD_OFFSET +
50                                                                      (hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET));
51     *threshold_ptr = threshold;
52 }
53 
__plic_set_priority(unsigned int source,unsigned int priority)54 __attribute__((always_inline)) static inline void __plic_set_priority(unsigned int source, unsigned int priority)
55 {
56     volatile unsigned int *priority_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
57                                                                     PLIC_PRIORITY_OFFSET +
58                                                                     (source << PLIC_PRIORITY_SHIFT_PER_SOURCE));
59     *priority_ptr = priority;
60 }
61 
__plic_set_pending(unsigned int source)62 __attribute__((always_inline)) static inline void __plic_set_pending(unsigned int source)
63 {
64     volatile unsigned int *current_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
65                                                                    PLIC_PENDING_OFFSET +
66                                                                    ((source >> 5) << 2));
67     *current_ptr = (1 << (source & 0x1F));
68 }
69 
__plic_irq_enable(unsigned int source)70 __attribute__((always_inline)) static inline void __plic_irq_enable(unsigned int source)
71 {
72     unsigned int hart_id = read_csr(mhartid);
73     volatile unsigned int *current_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
74                                                                    PLIC_ENABLE_OFFSET +
75                                                                    (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) +
76                                                                    ((source >> 5) << 2));
77     unsigned int current = *current_ptr;
78     current = current | (1 << (source & 0x1F));
79     *current_ptr = current;
80 }
81 
__plic_irq_disable(unsigned int source)82 __attribute__((always_inline)) static inline void __plic_irq_disable(unsigned int source)
83 {
84     unsigned int hart_id = read_csr(mhartid);
85     volatile unsigned int *current_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR +
86                                                                    PLIC_ENABLE_OFFSET +
87                                                                    (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) +
88                                                                    ((source >> 5) << 2));
89     unsigned int current = *current_ptr;
90     current = current & ~((1 << (source & 0x1F)));
91     *current_ptr = current;
92 }
93 
__plic_irq_claim(void)94 __attribute__((always_inline)) static inline unsigned int __plic_irq_claim(void)
95 {
96     unsigned int hart_id = read_csr(mhartid);
97     volatile unsigned int *claim_addr = (volatile unsigned int *)(PLIC_BASE_ADDR +
98                                                                   PLIC_CLAIM_OFFSET +
99                                                                   (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET));
100     return *claim_addr;
101 }
102 
__plic_irq_complete(unsigned int source)103 __attribute__((always_inline)) static inline void __plic_irq_complete(unsigned int source)
104 {
105     unsigned int hart_id = read_csr(mhartid);
106     volatile unsigned int *claim_addr = (volatile unsigned int *)(PLIC_BASE_ADDR +
107                                                                   PLIC_CLAIM_OFFSET +
108                                                                   (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET));
109     *claim_addr = source;
110 }
111 #endif /* end of __GNUC__ */
112 
113 #endif
114