Skip to content

Commit df741d0

Browse files
authored
Merge pull request #246 from hermitcore/riscv64
feat: add 64-bit RISC-V support
2 parents 7637c30 + 3c7a8a1 commit df741d0

File tree

13 files changed

+447
-6
lines changed

13 files changed

+447
-6
lines changed

.github/workflows/ci.yml

+24-2
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ jobs:
4343
name: Run
4444
strategy:
4545
matrix:
46-
target: [x86_64, x86_64-uefi, x86_64-fc, aarch64]
46+
target: [x86_64, x86_64-uefi, x86_64-fc, aarch64, riscv64]
4747
os: [ubuntu-latest, macos-latest, windows-latest]
4848
runs-on: ${{ matrix.os }}
4949
steps:
5050
- name: Install QEMU, NASM (ubuntu)
5151
if: matrix.os == 'ubuntu-latest'
5252
run: |
5353
sudo apt-get update
54-
sudo apt-get install qemu-system-x86 qemu-system-arm nasm
54+
sudo apt-get install qemu-system-x86 qemu-system-arm qemu-system-misc nasm
5555
- name: Install QEMU, NASM (macos)
5656
if: matrix.os == 'macos-latest'
5757
run: |
@@ -96,6 +96,17 @@ jobs:
9696
-display none -serial stdio -semihosting \
9797
-kernel target/aarch64/debug/rusty-loader \
9898
-device guest-loader,addr=0x48000000,initrd=data/aarch64/hello_world
99+
- name: Run loader (riscv64)
100+
if: matrix.target == 'riscv64'
101+
run: |
102+
qemu-system-riscv64 \
103+
-machine virt \
104+
-cpu rv64 \
105+
-smp 1 \
106+
-m 32M \
107+
-display none -serial stdio \
108+
-kernel target/riscv64/debug/rusty-loader \
109+
-initrd data/riscv64/hello_world
99110
- name: Build (release)
100111
run: cargo xtask build --target ${{ matrix.target }} --release
101112
- name: Run loader (release, x86_64)
@@ -123,3 +134,14 @@ jobs:
123134
-display none -serial stdio -semihosting \
124135
-kernel target/aarch64/release/rusty-loader \
125136
-device guest-loader,addr=0x48000000,initrd=data/aarch64/hello_world
137+
- name: Run loader (release, riscv64)
138+
if: matrix.target == 'riscv64'
139+
run: |
140+
qemu-system-riscv64 \
141+
-machine virt \
142+
-cpu rv64 \
143+
-smp 1 \
144+
-m 32M \
145+
-display none -serial stdio \
146+
-kernel target/riscv64/release/rusty-loader \
147+
-initrd data/riscv64/hello_world

Cargo.lock

+94-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+7
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ goblin = { version = "0.7", default-features = false, features = ["elf64"] }
3131
uefi = "0.24"
3232
uefi-services = "0.21"
3333

34+
[target.'cfg(target_arch = "riscv64")'.dependencies]
35+
fdt = "0.1"
36+
naked-function = "0.1"
37+
riscv = "0.10"
38+
sbi = "0.2"
39+
sptr = "0.3"
40+
3441
[build-dependencies]
3542
cc = "1.0"
3643
nasm-rs = "0.2"

data/riscv64/hello_world

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:eced9ae473fa1ffc91f210c038b1abf3552256657645355c0d40fce2445ed687
3+
size 856776

src/arch/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
#[cfg(target_arch = "aarch64")]
22
pub use crate::arch::aarch64::*;
3+
#[cfg(target_arch = "riscv64")]
4+
pub use crate::arch::riscv64::*;
35
#[cfg(target_arch = "x86_64")]
46
pub use crate::arch::x86_64::*;
57

68
#[cfg(target_arch = "aarch64")]
79
pub mod aarch64;
810

11+
#[cfg(target_arch = "riscv64")]
12+
pub mod riscv64;
13+
914
#[cfg(target_arch = "x86_64")]
1015
pub mod x86_64;

src/arch/riscv64/address_range.rs

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// TODO: Move this into its own crate.
2+
#![allow(dead_code)]
3+
4+
use core::cmp::Ordering;
5+
use core::fmt;
6+
use core::ops::Range;
7+
8+
use align_address::Align;
9+
10+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
11+
pub struct AddressRange {
12+
start: usize,
13+
end: usize,
14+
}
15+
16+
impl AddressRange {
17+
pub fn new(start: usize, end: usize) -> Option<Self> {
18+
(start <= end).then_some(Self { start, end })
19+
}
20+
21+
pub fn from_start_len(start: usize, len: usize) -> Self {
22+
Self {
23+
start,
24+
end: start + len,
25+
}
26+
}
27+
28+
pub fn overlaps(self, other: Self) -> bool {
29+
self.partial_cmp(&other).is_none()
30+
}
31+
32+
pub fn next(self, len: usize) -> Self {
33+
Self::from_start_len(self.end, len)
34+
}
35+
36+
pub fn align_to(self, align: usize) -> Self {
37+
Self {
38+
start: self.start.align_down(align),
39+
end: self.end.align_up(align),
40+
}
41+
}
42+
43+
pub fn start(self) -> usize {
44+
self.start
45+
}
46+
47+
pub fn end(self) -> usize {
48+
self.end
49+
}
50+
51+
pub fn len(self) -> usize {
52+
self.end - self.start
53+
}
54+
}
55+
56+
#[derive(Debug)]
57+
pub struct TryFromRangeError(());
58+
59+
impl<T> TryFrom<Range<*const T>> for AddressRange {
60+
type Error = TryFromRangeError;
61+
62+
fn try_from(value: Range<*const T>) -> Result<Self, Self::Error> {
63+
Self::new(value.start as usize, value.end as usize).ok_or(TryFromRangeError(()))
64+
}
65+
}
66+
67+
impl fmt::Display for AddressRange {
68+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69+
let Self { start, end } = self;
70+
let len = self.len();
71+
write!(f, "{start:#x}..{end:#x} (len = {len:#10x})")
72+
}
73+
}
74+
75+
impl PartialOrd for AddressRange {
76+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
77+
if self.end <= other.start {
78+
Some(Ordering::Less)
79+
} else if self.start >= other.end {
80+
Some(Ordering::Greater)
81+
} else if self == other {
82+
Some(Ordering::Equal)
83+
} else {
84+
None
85+
}
86+
}
87+
}

src/arch/riscv64/link.ld

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
SECTIONS {
2+
kernel_start = ADDR (.text.start);
3+
4+
.text.start 0x80200000 : { *(.text._start) }
5+
.text : { *(.text.*) }
6+
.rodata : { *(.rodata.*) }
7+
.data : { *(.data.*) }
8+
.bss : { *(.bss.*) }
9+
10+
kernel_end = .;
11+
}

0 commit comments

Comments
 (0)