Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions ports/risc-v32/gnu/example_build/qemu_virt/board.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/***************************************************************************
* Copyright (c) 2025 10xEngineers
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/

#include "plic.h"
#include "hwtimer.h"
#include "uart.h"
#include <stdint.h>
#include <stddef.h>

void *memset(const void *des, int c,size_t n)
{
if((des == NULL) || n <=0)
return (void*)des;
char* t = (char*)des;
int i;
for(i=0;i<n;i++)
t[i]=c;
return t;
}


int board_init(void)
{
int ret;
ret = plic_init();
if(ret)
return ret;
ret = uart_init();
if(ret)
return ret;
ret = hwtimer_init();
if(ret)
return ret;
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
pushd ../../../../../
cmake -Bbuild -GNinja -DCMAKE_TOOLCHAIN_FILE=cmake/riscv32_gnu.cmake .
cmake --build ./build/
popd
343 changes: 343 additions & 0 deletions ports/risc-v32/gnu/example_build/qemu_virt/csr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,343 @@
/***************************************************************************
* Copyright (c) 2025 10xEngineers
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/


#ifndef RISCV_CSR_H
#define RISCV_CSR_H


// Machine Status Register, mstatus
#define MSTATUS_MPP_MASK (3L << 11) // previous mode.
#define MSTATUS_MPP_M (3L << 11)
#define MSTATUS_MPP_S (1L << 11)
#define MSTATUS_MPP_U (0L << 11)
#define MSTATUS_MIE (1L << 3) // machine-mode interrupt enable.
#define MSTATUS_MPIE (1L << 7)
#define MSTATUS_FS (1L << 13)

// Machine-mode Interrupt Enable
#define MIE_MTIE (1L << 7)
#define MIE_MSIE (1L << 3)
#define MIE_MEIE (1L << 11)
#define MIE_STIE (1L << 5) // supervisor timer
#define MIE_SSIE (1L << 1)
#define MIE_SEIE (1L << 9)

// Supervisor Status Register, sstatus
#define SSTATUS_SPP (1L << 8) // Previous mode, 1=Supervisor, 0=User
#define SSTATUS_SPIE (1L << 5) // Supervisor Previous Interrupt Enable
#define SSTATUS_UPIE (1L << 4) // User Previous Interrupt Enable
#define SSTATUS_SIE (1L << 1) // Supervisor Interrupt Enable
#define SSTATUS_UIE (1L << 0) // User Interrupt Enable
#define SSTATUS_SPIE (1L << 5)
#define SSTATUS_UPIE (1L << 4)

// Supervisor Interrupt Enable
#define SIE_SEIE (1L << 9) // external
#define SIE_STIE (1L << 5) // timer
#define SIE_SSIE (1L << 1) // software

#ifndef __ASSEMBLER__

#include <stdint.h>

static inline uint32_t riscv_get_core()
{
uint32_t x;
asm volatile("csrr %0, mhartid" : "=r" (x) );
return x;
}

static inline uint32_t riscv_get_mstatus()
{
uint32_t x;
asm volatile("csrr %0, mstatus" : "=r" (x) );
return x;
}

static inline void riscv_writ_mstatus(uint32_t x)
{
asm volatile("csrw mstatus, %0" : : "r" (x));
}

static inline void riscv_writ_mepc(uint32_t x)
{
asm volatile("csrw mepc, %0" : : "r" (x));
}

static inline uint32_t riscv_get_sstatus()
{
uint32_t x;
asm volatile("csrr %0, sstatus" : "=r" (x) );
return x;
}

static inline void riscv_writ_sstatus(uint32_t x)
{
asm volatile("csrw sstatus, %0" : : "r" (x));
}

static inline uint32_t riscv_get_sip()
{
uint32_t x;
asm volatile("csrr %0, sip" : "=r" (x) );
return x;
}

static inline void riscv_writ_sip(uint32_t x)
{
asm volatile("csrw sip, %0" : : "r" (x));
}

static inline uint32_t riscv_get_sie()
{
uint32_t x;
asm volatile("csrr %0, sie" : "=r" (x) );
return x;
}

static inline void riscv_writ_sie(uint32_t x)
{
asm volatile("csrw sie, %0" : : "r" (x));
}

static inline uint32_t riscv_get_mie()
{
uint32_t x;
asm volatile("csrr %0, mie" : "=r" (x) );
return x;
}

static inline void riscv_writ_mie(uint32_t x)
{
asm volatile("csrw mie, %0" : : "r" (x));
}

static inline void riscv_writ_sepc(uint32_t x)
{
asm volatile("csrw sepc, %0" : : "r" (x));
}

static inline uint32_t riscv_get_sepc()
{
uint32_t x;
asm volatile("csrr %0, sepc" : "=r" (x) );
return x;
}

static inline uint32_t riscv_get_medeleg()
{
uint32_t x;
asm volatile("csrr %0, medeleg" : "=r" (x) );
return x;
}

static inline void riscv_writ_medeleg(uint32_t x)
{
asm volatile("csrw medeleg, %0" : : "r" (x));
}

static inline uint32_t riscv_get_mideleg()
{
uint32_t x;
asm volatile("csrr %0, mideleg" : "=r" (x) );
return x;
}

static inline void riscv_writ_mideleg(uint32_t x)
{
asm volatile("csrw mideleg, %0" : : "r" (x));
}

static inline void riscv_writ_stvec(uint32_t x)
{
asm volatile("csrw stvec, %0" : : "r" (x));
}

static inline uint32_t riscv_get_stvec()
{
uint32_t x;
asm volatile("csrr %0, stvec" : "=r" (x) );
return x;
}

static inline uint32_t riscv_get_stimecmp()
{
uint32_t x;
asm volatile("csrr %0, 0x14d" : "=r" (x) );
return x;
}

static inline void riscv_writ_stimecmp(uint32_t x)
{
asm volatile("csrw 0x14d, %0" : : "r" (x));
}

static inline uint32_t riscv_get_menvcfg()
{
uint32_t x;
asm volatile("csrr %0, 0x30a" : "=r" (x) );
return x;
}

static inline void riscv_writ_menvcfg(uint32_t x)
{
asm volatile("csrw 0x30a, %0" : : "r" (x));
}

static inline void riscv_writ_pmpcfg0(uint32_t x)
{
asm volatile("csrw pmpcfg0, %0" : : "r" (x));
}

static inline void riscv_writ_pmpaddr0(uint32_t x)
{
asm volatile("csrw pmpaddr0, %0" : : "r" (x));
}

static inline void riscv_writ_satp(uint32_t x)
{
asm volatile("csrw satp, %0" : : "r" (x));
}

static inline uint32_t riscv_get_satp()
{
uint32_t x;
asm volatile("csrr %0, satp" : "=r" (x) );
return x;
}

static inline uint32_t riscv_get_scause()
{
uint32_t x;
asm volatile("csrr %0, scause" : "=r" (x) );
return x;
}

static inline uint32_t riscv_get_stval()
{
uint32_t x;
asm volatile("csrr %0, stval" : "=r" (x) );
return x;
}

static inline void riscv_writ_mcounteren(uint32_t x)
{
asm volatile("csrw mcounteren, %0" : : "r" (x));
}

static inline uint32_t riscv_get_mcounteren()
{
uint32_t x;
asm volatile("csrr %0, mcounteren" : "=r" (x) );
return x;
}

static inline uint32_t riscv_get_time()
{
uint32_t x;
asm volatile("csrr %0, time" : "=r" (x) );
return x;
}

static inline void riscv_sintr_on()
{
uint32_t sstatus = riscv_get_sstatus();
sstatus |= SSTATUS_SIE;
riscv_writ_sstatus(sstatus);
}

static inline void riscv_sintr_off()
{
uint32_t sstatus = riscv_get_sstatus();
sstatus &= (~SSTATUS_SIE);
riscv_writ_sstatus(sstatus);
}

static inline int riscv_sintr_get()
{
uint32_t x = riscv_get_sstatus();
return (x & SSTATUS_SIE) != 0;
}

static inline void riscv_sintr_restore(int x)
{
if(x)
riscv_sintr_on();
else
riscv_sintr_off();
}

static inline void riscv_mintr_on()
{
uint32_t mstatus = riscv_get_mstatus();
mstatus |= MSTATUS_MIE;
riscv_writ_mstatus(mstatus);
}

static inline void riscv_mintr_off()
{
uint32_t mstatus = riscv_get_mstatus();
mstatus &= (~MSTATUS_MIE);
riscv_writ_mstatus(mstatus);
}

static inline int riscv_mintr_get()
{
uint32_t x = riscv_get_mstatus();
return (x & MSTATUS_MIE) != 0;
}

static inline void riscv_mintr_restore(int x)
{
if(x)
riscv_mintr_on();
else
riscv_mintr_off();
}

static inline uint32_t riscv_get_sp()
{
uint32_t x;
asm volatile("mv %0, sp" : "=r" (x) );
return x;
}

// read and write tp, the thread pointer, which xv6 uses to hold
// this core's hartid (core number), the index into cpus[].
static inline uint32_t riscv_get_tp()
{
uint32_t x;
asm volatile("mv %0, tp" : "=r" (x) );
return x;
}

static inline void riscv_writ_tp(uint32_t x)
{
asm volatile("mv tp, %0" : : "r" (x));
}

static inline uint32_t riscv_get_ra()
{
uint32_t x;
asm volatile("mv %0, ra" : "=r" (x) );
return x;
}

// flush the TLB.
static inline void sfence_vma()
{
// the zero, zero means flush all TLB entries.
asm volatile("sfence.vma zero, zero");
}

#endif // __ASSEMBLER__

#endif
Loading