| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 | /* * Copyright (c) 2006-2018, 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
 |