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