HPM SDK
HPMicro Software Development Kit
hpm_plic_drv.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021-2024 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_PLIC_DRV_H
9 #define HPM_PLIC_DRV_H
10 
17 #define HPM_PLIC_TARGET_M_MODE 0
18 #define HPM_PLIC_TARGET_S_MODE 1
19 
20 /* Feature Register */
21 #define HPM_PLIC_FEATURE_OFFSET (0x00000000UL)
22 #define HPM_PLIC_FEATURE_VECTORED_MODE (0x2UL)
23 #define HPM_PLIC_FEATURE_PREEMPTIVE_PRIORITY_IRQ (0x1UL)
24 
25 /* Priority Register - 32 bits per irq */
26 #define HPM_PLIC_PRIORITY_OFFSET (0x00000004UL)
27 #define HPM_PLIC_PRIORITY_SHIFT_PER_SOURCE 2
28 
29 /* Pending Register - 1 bit per source */
30 #define HPM_PLIC_PENDING_OFFSET (0x00001000UL)
31 #define HPM_PLIC_PENDING_SHIFT_PER_SOURCE 0
32 
33 #define HPM_PLIC_TRIGGER_TYPE_OFFSET (0x00001080UL)
34 #define HPM_PLIC_TRIGGER_TYPE_SHIFT_PER_SORUCE 1
35 
36 /* Enable Register - 0x80 per target */
37 #define HPM_PLIC_ENABLE_OFFSET (0x00002000UL)
38 #define HPM_PLIC_ENABLE_SHIFT_PER_TARGET 7
39 
40 /* Priority Threshold Register - 0x1000 per target */
41 #define HPM_PLIC_THRESHOLD_OFFSET (0x00200000UL)
42 #define HPM_PLIC_THRESHOLD_SHIFT_PER_TARGET 12
43 
44 
45 /* Claim Register - 0x1000 per target */
46 #define HPM_PLIC_CLAIM_OFFSET (0x00200004UL)
47 #define HPM_PLIC_CLAIM_SHIFT_PER_TARGET 12
48 
49 #if !defined(__ASSEMBLER__)
50 
58 ATTR_ALWAYS_INLINE static inline void __plic_set_feature(uint32_t base, uint32_t feature)
59 {
60  *(volatile uint32_t *) (base + HPM_PLIC_FEATURE_OFFSET) = feature;
61 }
62 
71 ATTR_ALWAYS_INLINE static inline void __plic_set_threshold(uint32_t base,
72  uint32_t target,
73  uint32_t threshold)
74 {
75  volatile uint32_t *threshold_ptr = (volatile uint32_t *) (base +
78  *threshold_ptr = threshold;
79 }
80 
88 ATTR_ALWAYS_INLINE static inline uint32_t __plic_get_threshold(uint32_t base,
89  uint32_t target)
90 {
91  volatile uint32_t *threshold_ptr = (volatile uint32_t *)(base +
94  return *threshold_ptr;
95 }
96 
105 ATTR_ALWAYS_INLINE static inline void __plic_set_irq_priority(uint32_t base,
106  uint32_t irq,
107  uint32_t priority)
108 {
109  volatile uint32_t *priority_ptr = (volatile uint32_t *) (base +
111  ((irq - 1) << HPM_PLIC_PRIORITY_SHIFT_PER_SOURCE));
112  *priority_ptr = priority;
113 }
114 
122 ATTR_ALWAYS_INLINE static inline void __plic_set_irq_pending(uint32_t base, uint32_t irq)
123 {
124  volatile uint32_t *current_ptr = (volatile uint32_t *) (base +
125  HPM_PLIC_PENDING_OFFSET + ((irq >> 5) << 2));
126  *current_ptr = (1 << (irq & 0x1F));
127 }
128 
136 ATTR_ALWAYS_INLINE static inline void __plic_enable_irq_edge_trigger(uint32_t base, uint32_t irq)
137 {
138  volatile uint32_t *current_ptr = (volatile uint32_t *) (base +
139  HPM_PLIC_TRIGGER_TYPE_OFFSET + ((irq >> 5) << 2));
140  *current_ptr |= (1UL << (irq & 0x1F));
141 }
142 
150 ATTR_ALWAYS_INLINE static inline void __plic_enable_irq_level_trigger(uint32_t base, uint32_t irq)
151 {
152  volatile uint32_t *current_ptr = (volatile uint32_t *) (base +
153  HPM_PLIC_TRIGGER_TYPE_OFFSET + ((irq >> 5) << 2));
154  *current_ptr &= ~(1UL << (irq & 0x1F));
155 }
156 
165 ATTR_ALWAYS_INLINE static inline void __plic_enable_irq(uint32_t base,
166  uint32_t target,
167  uint32_t irq)
168 {
169  volatile uint32_t *current_ptr = (volatile uint32_t *) (base +
172  ((irq >> 5) << 2));
173  uint32_t current = *current_ptr;
174  current = current | (1 << (irq & 0x1F));
175  *current_ptr = current;
176 }
177 
186 ATTR_ALWAYS_INLINE static inline void __plic_disable_irq(uint32_t base,
187  uint32_t target,
188  uint32_t irq)
189 {
190  volatile uint32_t *current_ptr = (volatile uint32_t *) (base +
193  ((irq >> 5) << 2));
194  uint32_t current = *current_ptr;
195  current = current & ~((1 << (irq & 0x1F)));
196  *current_ptr = current;
197 }
198 
206 ATTR_ALWAYS_INLINE static inline uint32_t __plic_claim_irq(uint32_t base, uint32_t target)
207 {
208  volatile uint32_t *claim_addr = (volatile uint32_t *) (base +
210  (target << HPM_PLIC_CLAIM_SHIFT_PER_TARGET));
211  return *claim_addr;
212 }
213 
222 ATTR_ALWAYS_INLINE static inline void __plic_complete_irq(uint32_t base,
223  uint32_t target,
224  uint32_t irq)
225 {
226  volatile uint32_t *claim_addr = (volatile uint32_t *) (base +
228  (target << HPM_PLIC_CLAIM_SHIFT_PER_TARGET));
229  *claim_addr = irq;
230 }
231 
232 #endif /* __ASSEMBLER__ */
236 #endif /* HPM_PLIC_DRV_H */
#define HPM_PLIC_CLAIM_OFFSET
Definition: hpm_plic_drv.h:46
#define HPM_PLIC_ENABLE_SHIFT_PER_TARGET
Definition: hpm_plic_drv.h:38
#define HPM_PLIC_CLAIM_SHIFT_PER_TARGET
Definition: hpm_plic_drv.h:47
#define HPM_PLIC_ENABLE_OFFSET
Definition: hpm_plic_drv.h:37
#define HPM_PLIC_FEATURE_OFFSET
Definition: hpm_plic_drv.h:21
#define HPM_PLIC_PRIORITY_SHIFT_PER_SOURCE
Definition: hpm_plic_drv.h:27
#define HPM_PLIC_THRESHOLD_OFFSET
Definition: hpm_plic_drv.h:41
#define HPM_PLIC_TRIGGER_TYPE_OFFSET
Definition: hpm_plic_drv.h:33
#define HPM_PLIC_PENDING_OFFSET
Definition: hpm_plic_drv.h:30
#define HPM_PLIC_PRIORITY_OFFSET
Definition: hpm_plic_drv.h:26
#define HPM_PLIC_THRESHOLD_SHIFT_PER_TARGET
Definition: hpm_plic_drv.h:42