mirror of
https://github.com/google/comprehensive-rust.git
synced 2024-11-29 18:29:40 +02:00
Add page about inline assembly.
This commit is contained in:
parent
f293ede958
commit
8b21f5070e
@ -256,6 +256,7 @@
|
||||
# Bare Metal Rust: Afternoon
|
||||
|
||||
- [Application processors](bare-metal/aps.md)
|
||||
- [Inline assembly](bare-metal/aps/inline-assembly.md)
|
||||
- [MMIO](bare-metal/aps/mmio.md)
|
||||
- [Let's write a UART driver](bare-metal/aps/uart.md)
|
||||
- [More traits](bare-metal/aps/uart/traits.md)
|
||||
|
@ -14,10 +14,6 @@ spin = "0.9.4"
|
||||
[build-dependencies]
|
||||
cc = "1.0.73"
|
||||
|
||||
[[bin]]
|
||||
name = "minimal"
|
||||
path = "src/main_minimal.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "improved"
|
||||
path = "src/main_improved.rs"
|
||||
@ -25,3 +21,11 @@ path = "src/main_improved.rs"
|
||||
[[bin]]
|
||||
name = "logger"
|
||||
path = "src/main_logger.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "minimal"
|
||||
path = "src/main_minimal.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "psci"
|
||||
path = "src/main_psci.rs"
|
||||
|
@ -12,26 +12,30 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
.PHONY: build qemu_minimal qemu qemu_logger
|
||||
.PHONY: build qemu qemu_logger qemu_minimal qemu_psci
|
||||
|
||||
all: minimal.bin improved.bin logger.bin
|
||||
|
||||
build:
|
||||
cargo build
|
||||
|
||||
minimal.bin: build
|
||||
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/minimal $@
|
||||
improved.bin: build
|
||||
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/improved $@
|
||||
logger.bin: build
|
||||
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/logger $@
|
||||
minimal.bin: build
|
||||
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/minimal $@
|
||||
psci.bin: build
|
||||
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/psci $@
|
||||
|
||||
qemu_minimal: minimal.bin
|
||||
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel $< -s
|
||||
qemu: improved.bin
|
||||
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel $< -s
|
||||
qemu_logger: logger.bin
|
||||
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel $< -s
|
||||
qemu_minimal: minimal.bin
|
||||
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel $< -s
|
||||
qemu_psci: psci.bin
|
||||
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel $< -s
|
||||
|
||||
clean:
|
||||
cargo clean
|
||||
|
51
src/bare-metal/aps/examples/src/main_psci.rs
Normal file
51
src/bare-metal/aps/examples/src/main_psci.rs
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// ANCHOR: main
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
use core::arch::asm;
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
mod exceptions;
|
||||
|
||||
const PSCI_SYSTEM_OFF: u32 = 0x84000008;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(_x0: u64, _x1: u64, _x2: u64, _x3: u64) {
|
||||
// Safe because this only uses the declared registers and doesn't do
|
||||
// anything with memory.
|
||||
unsafe {
|
||||
asm!("hvc #0",
|
||||
inout("w0") PSCI_SYSTEM_OFF => _,
|
||||
inout("w1") 0 => _,
|
||||
inout("w2") 0 => _,
|
||||
inout("w3") 0 => _,
|
||||
inout("w4") 0 => _,
|
||||
inout("w5") 0 => _,
|
||||
inout("w6") 0 => _,
|
||||
inout("w7") 0 => _,
|
||||
options(nomem, nostack)
|
||||
);
|
||||
}
|
||||
|
||||
loop {}
|
||||
}
|
||||
// ANCHOR_END: main
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
23
src/bare-metal/aps/inline-assembly.md
Normal file
23
src/bare-metal/aps/inline-assembly.md
Normal file
@ -0,0 +1,23 @@
|
||||
# Inline assembly
|
||||
|
||||
Sometimes we need to use assembly to do things that aren't possible with Rust code. For example,
|
||||
to make an <abbr title="hypervisor call">HVC</abbr> to tell the firmware to power off the system:
|
||||
|
||||
```rust,editable,compile_fail
|
||||
{{#include examples/src/main_psci.rs:main}}
|
||||
```
|
||||
|
||||
(If you actually want to do this, use the [`psci`][1] crate which has wrappers for all these functions.)
|
||||
|
||||
<details>
|
||||
|
||||
* PSCI is the Arm Power State Coordination Interface, a standard set of functions to manage system
|
||||
and CPU power states, among other things. It is implemented by EL3 firmware and hypervisors on
|
||||
many systems.
|
||||
* The `0 => _` syntax means initialise the register to 0 before running the inline assembly code,
|
||||
and ignore its contents afterwards. We need to use `inout` rather than `in` because the call could
|
||||
potentially clobber the contents of the registers.
|
||||
|
||||
</details>
|
||||
|
||||
[1]: https://crates.io/crates/psci
|
Loading…
Reference in New Issue
Block a user