#include "platform.h" #include "plic.h" #include "plic_driver.h" #include "encoding.h" #include <string.h> //把区间内的值初始化为0,volatile表示变量不需要进行优化,随时可变 void volatile_memzero(u8_t * base, unsigned int size) { volatile u8_t * ptr; for (ptr = base; ptr < (base + size); ptr++){ *ptr = 0; } } //初始化 void PLIC_init ( plic_instance_t * this_plic, uintptr_t base_addr, u32_t num_sources, u32_t num_priorities ) { //访问this_plic_struct内的变量 this_plic->base_addr = base_addr; this_plic->num_sources = num_sources; this_plic->num_priorities = num_priorities; // 禁用所有中断 unsigned long hart_id = read_csr(mhartid); //可适用于多核系统 volatile_memzero((u8_t*) (this_plic->base_addr + PLIC_ENABLE_OFFSET + (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET)), //地址区间单位为1byte/8 bit,+8是因为整数的除法上舍入(round up), 这里num_sources = 64 (num_sources + 8) / 8); // 将所有中断的优先级设为0 volatile_memzero ((u8_t *)(this_plic->base_addr + PLIC_PRIORITY_OFFSET), (num_sources + 1) << PLIC_PRIORITY_SHIFT_PER_SOURCE); // 将优先级阈值初始化为0, volatile表示变量不需要进行优化,随时可变 volatile plic_threshold* threshold = (plic_threshold*) (this_plic->base_addr + PLIC_THRESHOLD_OFFSET + (hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET)); *threshold = 0; //指针所指向的阈值设为0 } //设置优先级阈值 void PLIC_set_threshold (plic_instance_t * this_plic, plic_threshold threshold){ unsigned long hart_id = read_csr(mhartid); //可适用于多核系统 //pointer value volatile plic_threshold* threshold_ptr = (plic_threshold*) (this_plic->base_addr + PLIC_THRESHOLD_OFFSET + (hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET)); *threshold_ptr = threshold;//address } //设置优先级 void PLIC_set_priority (plic_instance_t * this_plic, plic_source source, plic_priority priority){ if (this_plic->num_priorities > 0) { volatile plic_priority * priority_ptr = (volatile plic_priority *) (this_plic->base_addr + PLIC_PRIORITY_OFFSET + (source << PLIC_PRIORITY_SHIFT_PER_SOURCE)); //地址区间单位为1byte *priority_ptr = priority; } } //读取中断声明寄存器 plic_source PLIC_claim_interrupt(plic_instance_t * this_plic){ unsigned long hart_id = read_csr(mhartid); //可适用于多核系统 volatile plic_source * claim_addr = (volatile plic_source * ) (this_plic->base_addr + PLIC_CLAIM_OFFSET + (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET)); return *claim_addr; } //中断完成 void PLIC_complete_interrupt(plic_instance_t * this_plic, plic_source source){ unsigned long hart_id = read_csr(mhartid); //可适用于多核系统 volatile plic_source * claim_addr = (volatile plic_source *) (this_plic->base_addr + PLIC_CLAIM_OFFSET + (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET)); *claim_addr = source; }
这里只列出了主函数中和PLIC相关的函数,主函数中其他的详细部分将在PLIC有关的工程中进行介绍。
//PLIC使能 static void enable_plic_int(u8_t int_src) { u8_t reg_off = 0; u8_t reg_val = 0; reg_off = (int_src / 32) * 4; //根据定义 reg_val = int_src & 0x1f; //只保留31位,1F(16)=31(10) PLIC_REG(PLIC_ENABLE_OFFSET + reg_off) |= 1 << reg_val; //立起相应的位 return; } //PLIC禁止 static void disable_plic_int(u8_t int_src) { u8_t reg_off = 0; u8_t reg_val = 0; reg_off = (int_src / 32) * 4; //根据定义 reg_val = int_src & 0x1f; //只保留31位,1F(16)=31(10) PLIC_REG(PLIC_ENABLE_OFFSET + reg_off) &= ~(1 << reg_val); //清除相应的位 return; }
声明:文章来源于IC知识库,本文内容及配图的版权归版权所有人所有,内容仅代表作者个人观点,不代表本网站观点或证实其内容的真实性。对于本网刊载的各类评论非本网评论员评论,仅代表评论者个人观点,并不代表本网证实或赞成其描述。如其他媒体、网站或个人转载使用,需保留本网注明的“稿件来源”,并自负法律责任。本文转载仅为更好的传播行业信息,若有内容图片侵权或者其他问题,请及时通过邮件联系我们,以便做侵删处理。