Skip to content

Commit a51143d

Browse files
committed
Implement asm functions
1 parent 061579f commit a51143d

File tree

9 files changed

+151
-1
lines changed

9 files changed

+151
-1
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
Cargo.lock
22
target/
3+
bin/*.after
4+
bin/*.before
5+
bin/*.o

asm.S

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include "asm.h"
2+
3+
.section .text.__ebreak
4+
.global __ebreak
5+
__ebreak:
6+
ebreak
7+
ret
8+
9+
.section .text.__wfi
10+
.global __wfi
11+
__wfi:
12+
wfi
13+
ret
14+
15+
.section .text.__sfence_vma_all
16+
.global __sfence_vma_all
17+
__sfence_vma_all:
18+
sfence.vma
19+
ret
20+
21+
.section .text.__sfence_vma
22+
.global __sfence_vma
23+
__sfence_vma:
24+
sfence.vma a0, a1
25+
ret
26+
27+
28+
// M-mode registers
29+
REG_READ(mcause, 0x342)
30+
REG_READ(mcycle, 0xB00)
31+
REG_READ(mepc, 0x341)
32+
REG_READ(mie, 0x304)
33+
REG_SET_CLEAR(mie, 0x304)
34+
REG_READ(minstret, 0xB02)
35+
REG_READ(mip, 0x344)
36+
REG_READ(misa, 0x301)
37+
REG_READ(mstatus, 0x300)
38+
REG_SET_CLEAR(mstatus, 0x300)
39+
REG_READ_WRITE(mtvec, 0x305)
40+
REG_READ(mvendorid, 0xF11)
41+
42+
// S-mode registers
43+
REG_READ_WRITE(satp, 0x180)
44+
REG_READ(scause, 0x142)
45+
REG_READ_WRITE(sepc, 0x141)
46+
REG_READ(sie, 0x104)
47+
REG_SET_CLEAR(sie, 0x104)
48+
REG_READ(sip, 0x144)
49+
REG_READ_WRITE(sscratch, 0x140)
50+
REG_READ(sstatus, 0x100)
51+
REG_SET_CLEAR(sstatus, 0x100)
52+
REG_READ(stval, 0x143)
53+
REG_READ_WRITE(stvec, 0x105)
54+
55+
REG_READ(time, 0xC01)

asm.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#ifndef __ASM_H
2+
#define __ASM_H
3+
4+
#define REG_READ(name, offset) \
5+
.section .text.__read_ ## name; \
6+
.global __read_ ## name; \
7+
__read_ ## name: \
8+
csrrs a0, offset, x0; \
9+
ret
10+
11+
#define REG_WRITE(name, offset) \
12+
.section .text.__write_ ## name; \
13+
.global __write_ ## name; \
14+
__write_ ## name: \
15+
csrrw x0, offset, a0; \
16+
ret
17+
18+
#define REG_SET(name, offset) \
19+
.section .text.__set_ ## name; \
20+
.global __set_ ## name; \
21+
__set_ ## name: \
22+
csrrs x0, offset, a0; \
23+
ret
24+
25+
#define REG_CLEAR(name, offset) \
26+
.section .text.__clear_ ## name; \
27+
.global __clear_ ## name; \
28+
__clear_ ## name: \
29+
csrrc x0, offset, a0; \
30+
ret
31+
32+
33+
#define REG_READ_WRITE(name, offset) REG_READ(name, offset); REG_WRITE(name, offset)
34+
#define REG_SET_CLEAR(name, offset) REG_SET(name, offset); REG_CLEAR(name, offset)
35+
36+
#endif /* __ASM_H */
37+

asm32.S

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include "asm.h"
2+
3+
REG_READ(mcycleh, 0xB80)
4+
REG_READ(minstreth, 0xB82)
5+
REG_READ(timeh, 0xC81)

assemble.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
3+
set -euxo pipefail
4+
5+
crate=riscv
6+
7+
# remove existing blobs because otherwise this will append object files to the old blobs
8+
rm -f bin/*.a
9+
10+
riscv64-unknown-elf-gcc -c -mabi=ilp32 -march=rv32imac asm.S -o bin/$crate.o
11+
riscv64-unknown-elf-gcc -c -mabi=ilp32 -march=rv32imac asm32.S -o bin/$crate-32.o
12+
ar crs bin/riscv32imac-unknown-none-elf.a bin/$crate.o bin/$crate-32.o
13+
cp bin/riscv32imac-unknown-none-elf.a bin/riscv32imc-unknown-none-elf.a
14+
15+
rm bin/$crate.o
16+
rm bin/$crate-32.o

bin/riscv32imac-unknown-none-elf.a

6.04 KB
Binary file not shown.

bin/riscv32imc-unknown-none-elf.a

6.04 KB
Binary file not shown.

build.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
1-
use std::env;
1+
use std::path::PathBuf;
2+
use std::{env, fs};
23

34
fn main() {
45
let target = env::var("TARGET").unwrap();
6+
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
7+
let name = env::var("CARGO_PKG_NAME").unwrap();
8+
9+
if target.starts_with("riscv") && env::var_os("CARGO_FEATURE_INLINE_ASM").is_none() {
10+
fs::copy(
11+
format!("bin/{}.a", target),
12+
out_dir.join(format!("lib{}.a", name)),
13+
).unwrap();
14+
15+
println!("cargo:rustc-link-lib=static={}", name);
16+
println!("cargo:rustc-link-search={}", out_dir.display());
17+
}
518

619
if target.starts_with("riscv32") {
720
println!("cargo:rustc-cfg=riscv");

check-blobs.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
3+
# Checks that the blobs are up to date with the committed assembly files
4+
5+
set -euxo pipefail
6+
7+
for lib in $(ls bin/*.a); do
8+
filename=$(basename $lib)
9+
riscv64-unknown-elf-objdump -Cd $lib > bin/${filename%.a}.before
10+
done
11+
12+
./assemble.sh
13+
14+
for lib in $(ls bin/*.a); do
15+
filename=$(basename $lib)
16+
riscv64-unknown-elf-objdump -Cd $lib > bin/${filename%.a}.after
17+
done
18+
19+
for cksum in $(ls bin/*.after); do
20+
diff -u $cksum ${cksum%.after}.before
21+
done

0 commit comments

Comments
 (0)