1.PLIC软件设计
相关参考文章:
RISC-V教学教案
在软件中对应的PLIC设计主要包括下面几个模块。
1.1. fii_types.h
#define RV_TYPE RV32 //定义RISC-V CPU为32位 //下面的定义是为了便于移植系统,以及对定义数据类型的长度和有无符号进行阐明,简单来说,就是为常用的数据类型取了别名 //举例:unsigned int在不同的系统下不一定都是32位,但在这里,u32_t可以是无符号的整型,也可以是视情况而定,别的长32位,无符号的数据类型 //总的来说,u32_t相对于unsigned int来说,既简化了写法,又包括了更多的信息 typedef unsigned int uintptr_t; typedef unsigned long long u64_t; typedef unsigned int u32_t; typedef unsigned short u16_t; typedef unsigned char u8_t; typedef long long s64_t; typedef int s32_t; typedef short s16_t; typedef char s8_t;
1.2. plic.h
这一个头文件主要是声明了一些和外部平台级中断有关的宏
#ifndef PLIC_H #define PLIC_H #include "const.h" //这些定义都可以在地址图里面找到(详细地址图,点击这里) // 定义外部平台级中断的优先级偏移量和参数 #define PLIC_PRIORITY_OFFSET _AC(0x0000,UL) //UL 是unsigned long,适用于不同系统的移植,可预防计算中的溢出 #define PLIC_PRIORITY_SHIFT_PER_SOURCE 2 // 定义外部平台级中断的悬挂偏移量和参数 #define PLIC_PENDING_OFFSET _AC(0x1000,UL) #define PLIC_PENDING_SHIFT_PER_SOURCE 0 // 定义外部平台级中断的使能偏移量和参数 #define PLIC_ENABLE_OFFSET _AC(0x2000,UL) #define PLIC_ENABLE_SHIFT_PER_TARGET 7 // 定义外部平台级中断的阈值偏移量和参数 #define PLIC_THRESHOLD_OFFSET _AC(0x200000,UL) #define PLIC_THRESHOLD_SHIFT_PER_TARGET 12 // 定义外部平台级中断声明的偏移量和参数 #define PLIC_CLAIM_OFFSET _AC(0x200004,UL) #define PLIC_CLAIM_SHIFT_PER_TARGET 12 //官方定义是最多可以使用1023个中断源 #define PLIC_MAX_SOURCE 1023 #define PLIC_SOURCE_MASK 0x3FF #endif /* PLIC_H */
1.3. plic_driver.h
#ifndef PLIC_DRIVER_H #define PLIC_DRIVER_H #include "plic.h" #include "platform.h" typedef struct __plic_instance_t //C语言的struct { uintptr_t base_addr; u32_t num_sources; u32_t num_priorities; } plic_instance_t; //定义和PLIC有关的变量的数据类型 typedef u32_t plic_source; typedef u32_t plic_priority; typedef u32_t plic_threshold; //初始化PLIC void PLIC_init(plic_instance_t * this_plic, uintptr_t base_addr, u32_t num_sources, u32_t num_priorities); //设置优先级阈值 void PLIC_set_threshold(plic_instance_t * this_plic, plic_threshold threshold); //设置中断使能 void PLIC_enable_interrupt(plic_instance_t * this_plic, plic_source source); //禁用中断 void PLIC_disable_interrupt(plic_instance_t * this_plic, plic_source source); //设置优先级 void PLIC_set_priority(plic_instance_t * this_plic, plic_source source, plic_priority priority); //中断声明 plic_source PLIC_claim_interrupt(plic_instance_t * this_plic); //中断完成 void PLIC_complete_interrupt(plic_instance_t * this_plic, plic_source source); #endif