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