1. 单核缓存基础操作

任务目标

在RISC-V单核处理器上,通过操作自定义内存映射I/O寄存器,实现缓存使能(enable)、失效(invalidate)和清空(clean)三种基础操作,并验证操作后状态寄存器的正确反馈。

必要环境与依赖

  • RISC-V 32位或64位处理器(支持M/S/U模式,本案例在M模式下运行)
  • 内存映射控制寄存器基地址:0x20000000(模拟缓存控制器)
  • 寄存器偏移:ENABLE=0x00,INVALIDATE=0x04,CLEAN=0x08,STATUS=0x0C
  • 写入任意非零值触发操作;STATUS寄存器bit0=1表示使能生效,bit1=1表示最近一次失效完成,bit2=1表示最近一次清空完成

关键完整代码

#include <stdint.h>

#define CACHE_CTRL_BASE  0x20000000UL
#define REG_ENABLE       (*(volatile uint32_t *)(CACHE_CTRL_BASE + 0x00))
#define REG_INVALIDATE   (*(volatile uint32_t *)(CACHE_CTRL_BASE + 0x04))
#define REG_CLEAN        (*(volatile uint32_t *)(CACHE_CTRL_BASE + 0x08))
#define REG_STATUS       (*(volatile uint32_t *)(CACHE_CTRL_BASE + 0x0C))

#define STATUS_ENABLED   (1U << 0)
#define STATUS_INVAL_DONE (1U << 1)
#define STATUS_CLEAN_DONE (1U << 2)

/* 缓存使能:写1触发,轮询等待使能位生效 */
void cache_enable(void) {
    REG_ENABLE = 1;
    while ((REG_STATUS & STATUS_ENABLED) == 0) {
        // 等待硬件置位
    }
}

/* 缓存失效:写1触发,等待完成标志 */
void cache_invalidate(void) {
    REG_INVALIDATE = 1;
    while ((REG_STATUS & STATUS_INVAL_DONE) == 0) {
        // 等待完成
    }
}

/* 缓存清空:写1触发,等待完成标志 */
void cache_clean(void) {
    REG_CLEAN = 1;
    while ((REG_STATUS & STATUS_CLEAN_DONE) == 0) {
        // 等待完成
    }
}

/* 验证入口:依次执行三种操作并检查状态 */
int cache_basic_ops_test(void) {
    cache_enable();
    if ((REG_STATUS & STATUS_ENABLED) == 0) return -1;

    cache_invalidate();
    if ((REG_STATUS & STATUS_INVAL_DONE) == 0) return -2;

    cache_clean();
    if ((REG_STATUS & STATUS_CLEAN_DONE) == 0) return -3;

    return 0; /* 全部通过 */
}

运行与验证

  1. 将代码编译为RISC-V裸机程序(无需操作系统),链接时确保CACHE_CTRL_BASE地址映射到实际缓存控制器的内存窗口。
  2. 在M模式下调用cache_basic_ops_test()作为入口函数。
  3. 验证方法:
    • 若返回值为0,说明三种操作均完成且状态位正确置位,测试通过。
    • 若返回-1、-2或-3,分别对应使能、失效、清空操作超时或状态未更新,测试失败。
  4. 预期输出:函数返回0(前提是硬件控制器按上述寄存器协议正确响应)。

常见问题

  • 若轮询死循环,检查硬件是否真正支持写触发操作,以及状态寄存器地址映射是否正确。
  • 若状态位在操作前已置位,需在触发前先清除对应状态位(本案例硬件设计为写触发时自动清零,若实际硬件不同需增加清除步骤)。