Skip to content
Merged
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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## Unreleased

### Improvements

- If the `initial-pagetable` or `exceptions` features are specified without any of the `elX`
features, then the exception level will be checked at runtime and the appropriate registers for
the current EL will be used. The `el1` feature is no longer enabled by default, as this runtime
detection should work instead.

### Bugfixes

- Stopped exposing unmangled symbols for `set_exception_vector` and `rust_entry`.

## 0.2.2

### Improvements
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ arm-pl011-uart = "0.4.0"
smccc = "0.2.2"

[features]
default = ["el1", "exceptions", "initial-pagetable", "psci"]
default = ["exceptions", "initial-pagetable", "psci"]
el1 = []
el2 = []
el3 = []
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fn main() {

## Features

`el1`, `exceptions`, `initial-pagetable` and `psci` are enabled by default.
`exceptions`, `initial-pagetable` and `psci` are enabled by default.

### `el1`

Expand Down Expand Up @@ -115,6 +115,10 @@ while the hypervisor or host has cacheable aliases to the same memory can lead t
issues. Even if the host doesn't explicitly access the memory, speculative accesses can lead to
cache fills.

This may be combined with one of the `elX` features to set up the page table for that exception
level. If not, the exception level will be checked at runtime and the corresponding system registers
used.

### `psci`

Adds the `start_core` function to start another CPU core via a PSCI `CPU_ON` call. This adds a
Expand Down
55 changes: 53 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ mod entry;
#[cfg(feature = "initial-pagetable")]
mod pagetable;

#[cfg(feature = "initial-pagetable")]
#[doc(hidden)]
pub mod __private {
pub use crate::pagetable::{__enable_mmu_el1, __enable_mmu_el2, __enable_mmu_el3};
}

#[cfg(any(feature = "exceptions", feature = "psci"))]
use core::arch::asm;
#[cfg(feature = "exceptions")]
Expand All @@ -42,7 +48,6 @@ global_asm!(include_str!("exceptions.S"));

/// Sets the appropriate vbar to point to our `vector_table`, if the `exceptions` feature is
/// enabled.
#[unsafe(no_mangle)]
extern "C" fn set_exception_vector() {
// SAFETY: We provide a valid vector table.
#[cfg(all(feature = "el1", feature = "exceptions"))]
Expand Down Expand Up @@ -74,9 +79,55 @@ extern "C" fn set_exception_vector() {
out("x9") _,
);
}
#[cfg(all(
feature = "exceptions",
not(any(feature = "el1", feature = "el2", feature = "el3"))
))]
{
let current_el: u64;
// SAFETY: Reading CurrentEL is always safe.
unsafe {
asm!(
"mrs {current_el}, CurrentEL",
options(nomem, nostack, preserves_flags),
current_el = out(reg) current_el,
);
}
match (current_el >> 2) & 0b11 {
// SAFETY: We provide a valid vector table.
1 => unsafe {
asm!(
"adr x9, vector_table_el1",
"msr vbar_el1, x9",
options(nomem, nostack, preserves_flags),
out("x9") _,
);
},
// SAFETY: We provide a valid vector table.
2 => unsafe {
asm!(
"adr x9, vector_table_el2",
"msr vbar_el2, x9",
options(nomem, nostack, preserves_flags),
out("x9") _,
);
},
// SAFETY: We provide a valid vector table.
3 => unsafe {
asm!(
"adr x9, vector_table_el3",
"msr vbar_el3, x9",
options(nomem, nostack, preserves_flags),
out("x9") _,
);
},
_ => {
panic!("Unexpected EL");
}
}
}
}

#[unsafe(no_mangle)]
extern "C" fn rust_entry(arg0: u64, arg1: u64, arg2: u64, arg3: u64) -> ! {
set_exception_vector();
__main(arg0, arg1, arg2, arg3)
Expand Down
Loading
Loading