Skip to content

Commit

Permalink
Merge pull request #246 from hermitcore/riscv64
Browse files Browse the repository at this point in the history
feat: add 64-bit RISC-V support
  • Loading branch information
mkroening authored Aug 11, 2023
2 parents 7637c30 + 3c7a8a1 commit df741d0
Show file tree
Hide file tree
Showing 13 changed files with 447 additions and 6 deletions.
26 changes: 24 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ jobs:
name: Run
strategy:
matrix:
target: [x86_64, x86_64-uefi, x86_64-fc, aarch64]
target: [x86_64, x86_64-uefi, x86_64-fc, aarch64, riscv64]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Install QEMU, NASM (ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install qemu-system-x86 qemu-system-arm nasm
sudo apt-get install qemu-system-x86 qemu-system-arm qemu-system-misc nasm
- name: Install QEMU, NASM (macos)
if: matrix.os == 'macos-latest'
run: |
Expand Down Expand Up @@ -96,6 +96,17 @@ jobs:
-display none -serial stdio -semihosting \
-kernel target/aarch64/debug/rusty-loader \
-device guest-loader,addr=0x48000000,initrd=data/aarch64/hello_world
- name: Run loader (riscv64)
if: matrix.target == 'riscv64'
run: |
qemu-system-riscv64 \
-machine virt \
-cpu rv64 \
-smp 1 \
-m 32M \
-display none -serial stdio \
-kernel target/riscv64/debug/rusty-loader \
-initrd data/riscv64/hello_world
- name: Build (release)
run: cargo xtask build --target ${{ matrix.target }} --release
- name: Run loader (release, x86_64)
Expand Down Expand Up @@ -123,3 +134,14 @@ jobs:
-display none -serial stdio -semihosting \
-kernel target/aarch64/release/rusty-loader \
-device guest-loader,addr=0x48000000,initrd=data/aarch64/hello_world
- name: Run loader (release, riscv64)
if: matrix.target == 'riscv64'
run: |
qemu-system-riscv64 \
-machine virt \
-cpu rv64 \
-smp 1 \
-m 32M \
-display none -serial stdio \
-kernel target/riscv64/release/rusty-loader \
-initrd data/riscv64/hello_world
96 changes: 94 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ goblin = { version = "0.7", default-features = false, features = ["elf64"] }
uefi = "0.24"
uefi-services = "0.21"

[target.'cfg(target_arch = "riscv64")'.dependencies]
fdt = "0.1"
naked-function = "0.1"
riscv = "0.10"
sbi = "0.2"
sptr = "0.3"

[build-dependencies]
cc = "1.0"
nasm-rs = "0.2"
Expand Down
3 changes: 3 additions & 0 deletions data/riscv64/hello_world
Git LFS file not shown
5 changes: 5 additions & 0 deletions src/arch/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
#[cfg(target_arch = "aarch64")]
pub use crate::arch::aarch64::*;
#[cfg(target_arch = "riscv64")]
pub use crate::arch::riscv64::*;
#[cfg(target_arch = "x86_64")]
pub use crate::arch::x86_64::*;

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

#[cfg(target_arch = "riscv64")]
pub mod riscv64;

#[cfg(target_arch = "x86_64")]
pub mod x86_64;
87 changes: 87 additions & 0 deletions src/arch/riscv64/address_range.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// TODO: Move this into its own crate.
#![allow(dead_code)]

use core::cmp::Ordering;
use core::fmt;
use core::ops::Range;

use align_address::Align;

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct AddressRange {
start: usize,
end: usize,
}

impl AddressRange {
pub fn new(start: usize, end: usize) -> Option<Self> {
(start <= end).then_some(Self { start, end })
}

pub fn from_start_len(start: usize, len: usize) -> Self {
Self {
start,
end: start + len,
}
}

pub fn overlaps(self, other: Self) -> bool {
self.partial_cmp(&other).is_none()
}

pub fn next(self, len: usize) -> Self {
Self::from_start_len(self.end, len)
}

pub fn align_to(self, align: usize) -> Self {
Self {
start: self.start.align_down(align),
end: self.end.align_up(align),
}
}

pub fn start(self) -> usize {
self.start
}

pub fn end(self) -> usize {
self.end
}

pub fn len(self) -> usize {
self.end - self.start
}
}

#[derive(Debug)]
pub struct TryFromRangeError(());

impl<T> TryFrom<Range<*const T>> for AddressRange {
type Error = TryFromRangeError;

fn try_from(value: Range<*const T>) -> Result<Self, Self::Error> {
Self::new(value.start as usize, value.end as usize).ok_or(TryFromRangeError(()))
}
}

impl fmt::Display for AddressRange {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self { start, end } = self;
let len = self.len();
write!(f, "{start:#x}..{end:#x} (len = {len:#10x})")
}
}

impl PartialOrd for AddressRange {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
if self.end <= other.start {
Some(Ordering::Less)
} else if self.start >= other.end {
Some(Ordering::Greater)
} else if self == other {
Some(Ordering::Equal)
} else {
None
}
}
}
11 changes: 11 additions & 0 deletions src/arch/riscv64/link.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
SECTIONS {
kernel_start = ADDR (.text.start);

.text.start 0x80200000 : { *(.text._start) }
.text : { *(.text.*) }
.rodata : { *(.rodata.*) }
.data : { *(.data.*) }
.bss : { *(.bss.*) }

kernel_end = .;
}
Loading

0 comments on commit df741d0

Please sign in to comment.