114 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			114 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  * Copyright (c) 2006-2021, RT-Thread Development Team | ||
|  |  * | ||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||
|  |  * | ||
|  |  * Change Logs: | ||
|  |  * Date           Author       Notes | ||
|  |  * 2018-10-03     Bernard      The first version | ||
|  |  */ | ||
|  | 
 | ||
|  | #ifndef RISCV_PLIC_H__
 | ||
|  | #define RISCV_PLIC_H__
 | ||
|  | 
 | ||
|  | #ifndef PLIC_BASE_ADDR
 | ||
|  | #define PLIC_BASE_ADDR 0x0
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | /* Priority Register - 32 bits per source */ | ||
|  | #define PLIC_PRIORITY_OFFSET (0x00000000UL)
 | ||
|  | #define PLIC_PRIORITY_SHIFT_PER_SOURCE 2
 | ||
|  | 
 | ||
|  | /* Pending Register - 1 bit per soirce */ | ||
|  | #define PLIC_PENDING_OFFSET (0x00001000UL)
 | ||
|  | #define PLIC_PENDING_SHIFT_PER_SOURCE 0
 | ||
|  | 
 | ||
|  | /* Enable Register - 0x80 per target */ | ||
|  | #define PLIC_ENABLE_OFFSET (0x00002000UL)
 | ||
|  | #define PLIC_ENABLE_SHIFT_PER_TARGET 7
 | ||
|  | 
 | ||
|  | /* Priority Threshold Register - 0x1000 per target */ | ||
|  | #define PLIC_THRESHOLD_OFFSET (0x00200000UL)
 | ||
|  | #define PLIC_THRESHOLD_SHIFT_PER_TARGET 12
 | ||
|  | 
 | ||
|  | /* Claim Register - 0x1000 per target */ | ||
|  | #define PLIC_CLAIM_OFFSET (0x00200004UL)
 | ||
|  | #define PLIC_CLAIM_SHIFT_PER_TARGET 12
 | ||
|  | 
 | ||
|  | #if defined(__GNUC__) && !defined(__ASSEMBLER__)
 | ||
|  | __attribute__((always_inline)) static inline void __plic_set_feature(unsigned int feature) | ||
|  | { | ||
|  |     volatile unsigned int *feature_ptr = (volatile unsigned int *)PLIC_BASE_ADDR; | ||
|  |     *feature_ptr = feature; | ||
|  | } | ||
|  | 
 | ||
|  | __attribute__((always_inline)) static inline void __plic_set_threshold(unsigned int threshold) | ||
|  | { | ||
|  |     unsigned int hart_id = read_csr(mhartid); | ||
|  |     volatile unsigned int *threshold_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR + | ||
|  |                                                                      PLIC_THRESHOLD_OFFSET + | ||
|  |                                                                      (hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET)); | ||
|  |     *threshold_ptr = threshold; | ||
|  | } | ||
|  | 
 | ||
|  | __attribute__((always_inline)) static inline void __plic_set_priority(unsigned int source, unsigned int priority) | ||
|  | { | ||
|  |     volatile unsigned int *priority_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR + | ||
|  |                                                                     PLIC_PRIORITY_OFFSET + | ||
|  |                                                                     (source << PLIC_PRIORITY_SHIFT_PER_SOURCE)); | ||
|  |     *priority_ptr = priority; | ||
|  | } | ||
|  | 
 | ||
|  | __attribute__((always_inline)) static inline void __plic_set_pending(unsigned int source) | ||
|  | { | ||
|  |     volatile unsigned int *current_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR + | ||
|  |                                                                    PLIC_PENDING_OFFSET + | ||
|  |                                                                    ((source >> 5) << 2)); | ||
|  |     *current_ptr = (1 << (source & 0x1F)); | ||
|  | } | ||
|  | 
 | ||
|  | __attribute__((always_inline)) static inline void __plic_irq_enable(unsigned int source) | ||
|  | { | ||
|  |     unsigned int hart_id = read_csr(mhartid); | ||
|  |     volatile unsigned int *current_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR + | ||
|  |                                                                    PLIC_ENABLE_OFFSET + | ||
|  |                                                                    (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) + | ||
|  |                                                                    ((source >> 5) << 2)); | ||
|  |     unsigned int current = *current_ptr; | ||
|  |     current = current | (1 << (source & 0x1F)); | ||
|  |     *current_ptr = current; | ||
|  | } | ||
|  | 
 | ||
|  | __attribute__((always_inline)) static inline void __plic_irq_disable(unsigned int source) | ||
|  | { | ||
|  |     unsigned int hart_id = read_csr(mhartid); | ||
|  |     volatile unsigned int *current_ptr = (volatile unsigned int *)(PLIC_BASE_ADDR + | ||
|  |                                                                    PLIC_ENABLE_OFFSET + | ||
|  |                                                                    (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) + | ||
|  |                                                                    ((source >> 5) << 2)); | ||
|  |     unsigned int current = *current_ptr; | ||
|  |     current = current & ~((1 << (source & 0x1F))); | ||
|  |     *current_ptr = current; | ||
|  | } | ||
|  | 
 | ||
|  | __attribute__((always_inline)) static inline unsigned int __plic_irq_claim(void) | ||
|  | { | ||
|  |     unsigned int hart_id = read_csr(mhartid); | ||
|  |     volatile unsigned int *claim_addr = (volatile unsigned int *)(PLIC_BASE_ADDR + | ||
|  |                                                                   PLIC_CLAIM_OFFSET + | ||
|  |                                                                   (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET)); | ||
|  |     return *claim_addr; | ||
|  | } | ||
|  | 
 | ||
|  | __attribute__((always_inline)) static inline void __plic_irq_complete(unsigned int source) | ||
|  | { | ||
|  |     unsigned int hart_id = read_csr(mhartid); | ||
|  |     volatile unsigned int *claim_addr = (volatile unsigned int *)(PLIC_BASE_ADDR + | ||
|  |                                                                   PLIC_CLAIM_OFFSET + | ||
|  |                                                                   (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET)); | ||
|  |     *claim_addr = source; | ||
|  | } | ||
|  | #endif /* end of __GNUC__ */
 | ||
|  | 
 | ||
|  | #endif
 |