Implement asm functions

This commit is contained in:
Vadim Kaushan 2018-12-23 11:25:04 +01:00
parent 061579f97e
commit a51143d366
9 changed files with 151 additions and 1 deletions

3
.gitignore vendored
View File

@ -1,2 +1,5 @@
Cargo.lock
target/
bin/*.after
bin/*.before
bin/*.o

55
asm.S Normal file
View File

@ -0,0 +1,55 @@
#include "asm.h"
.section .text.__ebreak
.global __ebreak
__ebreak:
ebreak
ret
.section .text.__wfi
.global __wfi
__wfi:
wfi
ret
.section .text.__sfence_vma_all
.global __sfence_vma_all
__sfence_vma_all:
sfence.vma
ret
.section .text.__sfence_vma
.global __sfence_vma
__sfence_vma:
sfence.vma a0, a1
ret
// M-mode registers
REG_READ(mcause, 0x342)
REG_READ(mcycle, 0xB00)
REG_READ(mepc, 0x341)
REG_READ(mie, 0x304)
REG_SET_CLEAR(mie, 0x304)
REG_READ(minstret, 0xB02)
REG_READ(mip, 0x344)
REG_READ(misa, 0x301)
REG_READ(mstatus, 0x300)
REG_SET_CLEAR(mstatus, 0x300)
REG_READ_WRITE(mtvec, 0x305)
REG_READ(mvendorid, 0xF11)
// S-mode registers
REG_READ_WRITE(satp, 0x180)
REG_READ(scause, 0x142)
REG_READ_WRITE(sepc, 0x141)
REG_READ(sie, 0x104)
REG_SET_CLEAR(sie, 0x104)
REG_READ(sip, 0x144)
REG_READ_WRITE(sscratch, 0x140)
REG_READ(sstatus, 0x100)
REG_SET_CLEAR(sstatus, 0x100)
REG_READ(stval, 0x143)
REG_READ_WRITE(stvec, 0x105)
REG_READ(time, 0xC01)

37
asm.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef __ASM_H
#define __ASM_H
#define REG_READ(name, offset) \
.section .text.__read_ ## name; \
.global __read_ ## name; \
__read_ ## name: \
csrrs a0, offset, x0; \
ret
#define REG_WRITE(name, offset) \
.section .text.__write_ ## name; \
.global __write_ ## name; \
__write_ ## name: \
csrrw x0, offset, a0; \
ret
#define REG_SET(name, offset) \
.section .text.__set_ ## name; \
.global __set_ ## name; \
__set_ ## name: \
csrrs x0, offset, a0; \
ret
#define REG_CLEAR(name, offset) \
.section .text.__clear_ ## name; \
.global __clear_ ## name; \
__clear_ ## name: \
csrrc x0, offset, a0; \
ret
#define REG_READ_WRITE(name, offset) REG_READ(name, offset); REG_WRITE(name, offset)
#define REG_SET_CLEAR(name, offset) REG_SET(name, offset); REG_CLEAR(name, offset)
#endif /* __ASM_H */

5
asm32.S Normal file
View File

@ -0,0 +1,5 @@
#include "asm.h"
REG_READ(mcycleh, 0xB80)
REG_READ(minstreth, 0xB82)
REG_READ(timeh, 0xC81)

16
assemble.sh Executable file
View File

@ -0,0 +1,16 @@
#!/bin/bash
set -euxo pipefail
crate=riscv
# remove existing blobs because otherwise this will append object files to the old blobs
rm -f bin/*.a
riscv64-unknown-elf-gcc -c -mabi=ilp32 -march=rv32imac asm.S -o bin/$crate.o
riscv64-unknown-elf-gcc -c -mabi=ilp32 -march=rv32imac asm32.S -o bin/$crate-32.o
ar crs bin/riscv32imac-unknown-none-elf.a bin/$crate.o bin/$crate-32.o
cp bin/riscv32imac-unknown-none-elf.a bin/riscv32imc-unknown-none-elf.a
rm bin/$crate.o
rm bin/$crate-32.o

Binary file not shown.

Binary file not shown.

View File

@ -1,7 +1,20 @@
use std::env;
use std::path::PathBuf;
use std::{env, fs};
fn main() {
let target = env::var("TARGET").unwrap();
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let name = env::var("CARGO_PKG_NAME").unwrap();
if target.starts_with("riscv") && env::var_os("CARGO_FEATURE_INLINE_ASM").is_none() {
fs::copy(
format!("bin/{}.a", target),
out_dir.join(format!("lib{}.a", name)),
).unwrap();
println!("cargo:rustc-link-lib=static={}", name);
println!("cargo:rustc-link-search={}", out_dir.display());
}
if target.starts_with("riscv32") {
println!("cargo:rustc-cfg=riscv");

21
check-blobs.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
# Checks that the blobs are up to date with the committed assembly files
set -euxo pipefail
for lib in $(ls bin/*.a); do
filename=$(basename $lib)
riscv64-unknown-elf-objdump -Cd $lib > bin/${filename%.a}.before
done
./assemble.sh
for lib in $(ls bin/*.a); do
filename=$(basename $lib)
riscv64-unknown-elf-objdump -Cd $lib > bin/${filename%.a}.after
done
for cksum in $(ls bin/*.after); do
diff -u $cksum ${cksum%.after}.before
done