cove-salus-tellus测试程序时序逻辑

一、核心说明

以下时序图基于

https://github.com/rivosinc/salus/blob/main/test-workloads/src/bin/tellus.rs

提供的Tellus测试程序逻辑,聚焦主核心(hart 0) 的核心执行流程,覆盖TVM创建、运行、中断/异常处理、资源回收全生命周期;次级核心(hart 1+)仅简化展示"启动→自旋等待任务"逻辑,不展开细节。

时序图使用Mermaid语法,可直接复制到支持Mermaid的工具(如Mermaid Live Editor、VS Code Mermaid插件)中渲染查看。

二、完整时序图

主核心 次级核心 TVM 阶段1:初始化(基础环境准备) kernel_init入口,初始化控制台/FDT/IMSIC 调用hart_start启动次级核心 secondary_init,自旋等待IPI任务 验证COVE扩展,完成初始化 阶段2:TVM创建(资源配置与最终化) 捐赠页→创建TVM→注册共享内存 添加vCPU0/AIA配置/Guest数据页 TVM_finalize,设置入口+中断预配置 阶段3:TVM运行&异常处理(核心循环) 调用tvm_run运行Guest 触发Trap(ECALL/页故障/中断) 处理Trap,关闭对应中断/映射缺页 循环调用tvm_run继续运行 阶段4:资源回收(校验与系统关机) 向量校验→AIA解绑→销毁TVM 验证共享页→回收所有捐赠页 PMU测试→注销共享内存→系统关机 主核心 次级核心 TVM Tellus测试程序核心时序(RISC-V S-mode TVM测试)

start.S
主核心 SBI 次级核心 主核心(hart0)启动流程 触发_start汇编入口 初始化GP全局指针 清空sstatus/sie,禁用所有中断 循环清零BSS段(未初始化全局变量) 设置SP栈指针指向_stack_end 调用Rust层kernel_init(传入hart_id/fdt_addr) kernel_init完成初始化(控制台/FDT/IMSIC) 理论分支:kernel_init返回后进入WFI循环 次级核心(hart1及以上)启动流程 触发_secondary_start汇编入口 初始化GP全局指针 清空sstatus/sie,禁用所有中断 SP/TP绑定a1(PerCpu结构体地址) 调用Rust层secondary_init secondary_init完成,进入WFI休眠循环 (可选)通过IPI唤醒次级核心执行任务 主核心 SBI 次级核心 Tellus程序核心启动完整时序(RISC-V S-mode)

三、关键节点补充说明

  1. 时序核心逻辑

    • 初始化阶段:完成硬件配置(IMSIC、CPU、内存)和环境准备;
    • TVM创建阶段:核心是"捐赠页→创建TVM→配置资源(内存/中断)→最终化",所有convert_pages后需调用fence_memory保证内存一致性;
    • 运行循环:核心是"tvm_run→捕获Trap→处理Trap→循环",覆盖Guest ECALL、缺页、中断三大核心场景;
    • 回收阶段:先校验数据(向量寄存器、共享页),再销毁TVM、回收所有捐赠页,最后执行PMU测试并关机。
  2. 次级核心简化逻辑

    次级核心启动后仅执行secondary_init→进入TaskRunner::spin,等待主核心通过IPI发送任务(如fence_memory中的tsm_local_fence),任务执行完成后回到WFI休眠,时序图中未展开此细节(仅标注"自旋等待任务")。

  3. 中断/异常处理关键

    • 预配置的stimecmp=0si_eip[0] pending位会触发首次中断,处理时会关闭对应中断使能;
    • Guest侧的外部中断通过SupervisorGuestExternal投递,主核心侧外部中断通过SupervisorExternal投递,两者严格区分。

四、启动逻辑总结

该时序图核心覆盖:

  1. 初始化→TVM创建→运行循环→资源回收的全生命周期;
  2. 关键API调用(cove_host/中断/AIA相关)的执行顺序;
  3. Trap处理的分支逻辑(ECALL/缺页/中断)。

五、次级核心启动

rust 复制代码
/// Starts the given cpu executing at `start_addr` with `opaque` in register a1.
///
/// # Safety
///
/// start_addr must point to code that can be safely executed.
/// opaque, if a pointer, must point to data that is safe to access from the newly running context.
pub unsafe fn hart_start(hart_id: u64, start_addr: u64, opaque: u64) -> Result<()> {
    // 1. 构造SBI消息结构体:封装hart_id/start_addr/opaque
    let msg = SbiMessage::HartState(HartStart {
        hart_id,       // 要唤醒的次级核心ID(如1/2/3)
        start_addr,    // 次级核心启动后跳转的地址(_secondary_start的物理地址)
        opaque,        // 传给次级核心的a1参数(PerCpu结构体地址)
    });
    // 2. 发送SBI消息并执行ecall调用
    // Safety注释:保证start_addr是合法的次级核心启动代码地址
    ecall_send::<()>(&msg)?;
    Ok(())
}

这段代码的核心是SbiMessageecall_send,它们是对底层ecall指令的封装,内部逻辑等价于之前的汇编内联代码:

rust 复制代码
// (底层ecall_send的简化实现,帮你补全上下文)
fn ecall_send<T>(msg: &SbiMessage) -> Result<T> {
    unsafe {
        // 按SBI约定,将msg参数映射到a0-a7寄存器
        let (a0, a1, a2, a6, a7) = msg.into_registers();
        let ret: SbiRet;
        // 执行ecall指令,触发SBI调用
        asm!(
            "ecall",
            in("a0") a0,
            in("a1") a1,
            in("a2") a2,
            in("a6") a6,
            in("a7") a7,
            lateout("a0") ret.error,
            lateout("a1") ret.value,
            options(nostack),
        );
        // 处理返回值,转换为Rust的Result类型
        if ret.error == 0 {
            Ok(unsafe { core::mem::transmute(ret.value) })
        } else {
            Err(SbiError::from(ret.error))
        }
    }
}
  • SbiMessage::HartState:对应SBI的HSM扩展(0x48534D),HartStart对应扩展内的hart_start函数(函数号0);
  • into_registers():将hart_id/start_addr/opaque分别映射到a0/a1/a2a6=函数号,a7=扩展号,和手动调用的寄存器约定完全一致。
相关推荐
阎*水19 小时前
Ceph 分布式存储完整实践指南
linux·运维·分布式·ceph
优质网络系统领域创作者19 小时前
IS-IS和OSPF路由协议对比以及两个协议双点双向引入
运维·网络
9稳19 小时前
基于PLC的液体自动混合加热控制系统设计
开发语言·网络·数据库·labview·plc
我爱学习好爱好爱19 小时前
Prometheus监控栈 监控Linux操作系统
linux·grafana·prometheus
sleetdream19 小时前
联想开天统信UOS安装镜像 增加系统分区空间
linux
互联科技报19 小时前
CDN07游戏盾SDK方案详解:为游戏而生的防攻击与稳定连接方案
网络·游戏
ArrebolJiuZhou19 小时前
arm指令集(一)
linux·运维·arm开发
一只旭宝19 小时前
Linux专题三:目录结构即相关操作指令,gdb调试,进程基础,以及makefile工具
linux
lbb 小魔仙20 小时前
Steam Deck OLED 拆解与评测:Valve 对 Linux 掌机的又一次精进
linux·运维·服务器
一枚正在学习的小白20 小时前
prometheus监控redis
linux·运维·服务器·redis·prometheus