Skip to content

Latest commit

 

History

History
83 lines (65 loc) · 2.42 KB

custom.md

File metadata and controls

83 lines (65 loc) · 2.42 KB

Custom Features (non RISC-V standard)

Timer

The timer supported in bi-RISC-V is a 32-bit cycle counter with the option to generate timer interrupts on match.

The RISC-V privileged spec refers to memory mapped mtime and mtimecmp registers.
In bi-RISC-V these are mapped to CSR registers for fast access and low external dependence.

mtime is mapped to CSR mcycle and rdtime and is limited to 32-bits (continuously counting, wrapping). mtimecmp is mapped to a custom CSR address and is limited to 32-bits and will generate an interrupt on matching mtime (interrupt routed to MSTATUS.MTIP).

#define csr_read(reg) ({ uint32_t __tmp; \
  asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
  __tmp; })

#define csr_write(reg, val) ({ \
  asm volatile ("csrw " #reg ", %0" :: "rK"(val)); })

void timer_set_mtimecmp(uint32_t next)
{
    csr_write(0x7c0, next);
}

uint32_t timer_get_mtime(void)
{
    return csr_read(0xc00); // or 0xc01
}
void timer_set_mtime(uint32_t value)
{
    csr_write(0xc01, value);
}

Instruction Cache Flush

Flushing the instruction cache is achieved using fence.i which is in-keeping with the behaviour specified in the Zifence section of the RISC-V ISA specification;

void icache_flush(void)
{
    asm volatile ("fence.i");
}

Data Cache Control

Cacheable regions of memory are specified at the core build time using the following parameters;

    ,.MEM_CACHE_ADDR_MIN(32'h80000000)
    ,.MEM_CACHE_ADDR_MAX(32'h8fffffff)

The data cache also has the following dynamic controls;

  • Flush: Writeback all dirty lines, mark all lines as invalid (global flush).
  • Writeback: Writeback a specific line (if dirty), leave line as valid in the cache (if it was present).
  • Invalidate: Invalidate a specific line without writing back if dirty, mark line as invalid in the cache (if it was present).

These controls are mapped to pmpcfg0, pmpcfg1 and pmpcfg2 CSRs currently;

void dcache_flush(void)
{
    asm volatile ("csrw pmpcfg0, x0"); // 0x3a0
}
void dcache_writeback(uint32_t addr)
{
    asm volatile ("csrw pmpcfg1, %0": : "r" (addr)); // 0x3a1
}
void dcache_invalidate(uint32_t addr)
{
    asm volatile ("csrw pmpcfg2, %0": : "r" (addr)); // 0x3a2
}

However, these mappings can be changed by altering the following definitions;

`define CSR_DFLUSH            12'h3a0
`define CSR_DWRITEBACK        12'h3a1
`define CSR_DINVALIDATE       12'h3a2