Expand description

Low level access to T-Head XuanTie RISC-V processors

Examples

Here’s a list of example code of how to using this library under different scenarios.

Synchronize instruction cache and data cache

The following code is useful when we need to change memory data and try to execute it as code.

use xuantie::asm::{dcache_cval1, sync, icache_iva};
use core::arch::riscv64::fence_i;
// a new instruction is defined in `new_insn`, is store to
// program virtual memory address defined in `insn_ptr`.
unsafe { core::ptr::write_volatile(insn_ptr, new_insn) };
// synchronize I-cache and D-cache
unsafe {
    // clean the L1 D-cache for new instruction
    dcache_cval1(insn_ptr);
    // ensure completion of clean operation on target hart
    sync(); // or sync_s() for all harts
    // invalidate I-cache according to shareable configuration
    icache_iva(insn_ptr);
    // ensure completion of clean operation on target hart
    fence_i();
}
// now we may execute the target instruction
unsafe { transmute::<_, fn()>(insn_ptr)() };

Enable and invalidate caches

C906 will invalid both I-cache and D-cache automatically when reset. Use the following operation, we can enable I-cache and D-cache.

use xuantie::register::mhcr;
// enable D-cache
unsafe { mhcr::set_de() };
// enable I-cache
unsafe { mhcr::set_ie() };

Additionally, we can invalidate I-cache or D-cache manually if necessary.

// If we don't have `mxstatus.theadisaee` enabled
use xuantie::register::mcor::{self, Cache, Operation};
// invalidate caches. Use `Cache::DATA` or `Cache::INSTRUCION`
// to invalid a specific cache.
unsafe { mcor::cache(Cache::BOTH, Operation::INVALIDATE); }
// If we have `mxstatus.theadisaee` enabled
use xuantie::asm::{icache_iall, dcache_iall, sync_is};
// invalidate I-cache
unsafe { icache_iall(); sync_is(); }
// invalidate D-cache
unsafe { dcache_iall(); sync_is(); }

CPU power down

The following code would power down a Xuantie C906 core. This procedure is useful when developing SBI implementations.

Make sure the hart is at M mode when executing the following code.

use riscv::register::mstatus;
use xuantie::{asm::dcache_call, register::{mhint, mhcr}};
use core::arch::riscv64::wfi;
// power down the current processor hart
unsafe fn shutdown() -> ! {
    // disable interrupt
    mstatus::clear_mie();
    // disable data prefetch
    mhint::clear_dpld();
    // clear D-cache
    dcache_call();
    // disable D-cache
    mhcr::clear_de();
    // execute wait-for-interrupt instruction
    wfi();
    // no instruction would be able to wake this WFI
    unreachable!()
}

Modules

Assembly instructions

Debug module of XuanTie

Paging support

XuanTie extended CSRs