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
 |