1. 实现Cache操作接口
在系统启动过程中需要使能icache和dcache来提高系统整体性能,并且后续别的系统模块也需要操作cache比如回写cache、失效cache等等,所以需要封装出cache操作相关接口。
在D1上实现的cache操作接口如下所示:
#ifndef CACHE_H_ #define CACHE_H_ void clean_dcache_all(void); void clean_dcache_range_pa(unsigned long start, unsigned long end); void clean_dcache_range(unsigned long start, unsigned long end); void invalidate_dcache_all(void); void invalidate_dcache_range_pa(unsigned long start, unsigned long end); void invalidate_dcache_range(unsigned long start, unsigned long end); void flush_dcache_all(void); void flush_dcache_range_pa(unsigned long start, unsigned long end); void flush_dcache_range(unsigned long start, unsigned long end); void dcache_enable(void); void dcache_disable(void); int dcache_status(void); void invalidate_icache_all(void); void invalidate_icache_range_pa(unsigned long start, unsigned long end); void invalidate_icache_range(unsigned long start, unsigned long end); void icache_enable(void); void icache_disable(void); int icache_status(void); void cpu_init(void); void cache_test(void); #endif /* CACHE_H_ */
SimpleOS对Cache操作的定义如下:
- flush:回写cache中的数据,可以全部回写也可以根据虚拟地址或者物理地址回写。
- invalidate:失效cache中的数据,可以全部失效也可以根据虚拟地址或者物理地址失效。
- clean:先回写cache中的数据然后再失效cache,可以全部clean也可以根据虚拟地址或者物理地址clean。
C906的核cache可以根据物理地址或者虚拟地址来进行相应的操作,所以在接口封装上设计了两种接口分别使用物理地址和虚拟地址。另外为了简单起见,起始地址和结尾地址由调用者来保证是cacheline对齐的,接口实现不做特殊任何处理。
在接口具体实现方面,主要参考了全志D1的uboot相关代码,如下所示。
全志D1的uboot代码为了兼容不同的riscv编译工具链,直接在接口中使用指令机器码来实现相应的功能,因为标准的riscv编译工具链并不能识别C906的扩展指令,而像cache失效、回写等都是C906扩展指令实现的,所以使用机器码来尽量兼容不同的编译器。
2. 添加内核测试代码
添加了内核测试接口,在系统启动过程中根据条件编译来使用,用于测试系统对应的功能是否正常,如下所示:
#include "print.h" #include "cache.h" void init(void) { pr_debug("hello simpleos!\n"); #ifdef KERNEL_TEST printk_test(); #endif cpu_init(); #ifdef KERNEL_TEST pr_test("before cache enable: "); cache_test(); #endif icache_enable(); dcache_enable(); #ifdef KERNEL_TEST pr_test("after cache enable: "); cache_test(); #endif }
评论