forked from xuos/xiuos
110 lines
4.6 KiB
C
110 lines
4.6 KiB
C
/*
|
|
* Copyright (c) 2020 AIIT XUOS Lab
|
|
* XiUOS is licensed under Mulan PSL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
* You may obtain a copy of Mulan PSL v2 at:
|
|
* http://license.coscl.org.cn/MulanPSL2
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PSL v2 for more details.
|
|
*/
|
|
|
|
#ifndef RISCV_PLIC_H__
|
|
#define RISCV_PLIC_H__
|
|
|
|
#ifndef PLIC_BASE_ADDR
|
|
#define PLIC_BASE_ADDR 0x0
|
|
#endif
|
|
|
|
#define PLIC_PRIORITY_OFFSET (0x00000000UL)
|
|
#define PLIC_PRIORITY_SHIFT_PER_SOURCE 2
|
|
|
|
#define PLIC_PENDING_OFFSET (0x00001000UL)
|
|
#define PLIC_PENDING_SHIFT_PER_SOURCE 0
|
|
|
|
#define PLIC_ENABLE_OFFSET (0x00002000UL)
|
|
#define PLIC_ENABLE_SHIFT_PER_TARGET 7
|
|
|
|
#define PLIC_THRESHOLD_OFFSET (0x00200000UL)
|
|
#define PLIC_THRESHOLD_SHIFT_PER_TARGET 12
|
|
|
|
#define PLIC_CLAIM_OFFSET (0x00200004UL)
|
|
#define PLIC_CLAIM_SHIFT_PER_TARGET 12
|
|
|
|
#if defined(__GNUC__) && !defined(__ASSEMBLER__)
|
|
__attribute__((always_inline)) static inline void PlicSetFeature(unsigned int feature)
|
|
{
|
|
volatile unsigned int *feature_ptr = (volatile unsigned int *)PLIC_BASE_ADDR;
|
|
*feature_ptr = feature;
|
|
}
|
|
|
|
__attribute__((always_inline)) static inline void PlicSetThreshold(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 PlicSetPriority(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 PlicSetPending(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 PlicIrqEnable(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 PlicIrqDisable(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 PlicIrqClaim(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 PlicIrqComplete(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
|
|
#endif
|