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
|
# Bare Metal Rust: Afternoon
|
||||||
|
|
||||||
- [Application processors](bare-metal/aps.md)
|
- [Application processors](bare-metal/aps.md)
|
||||||
|
- [Inline assembly](bare-metal/aps/inline-assembly.md)
|
||||||
- [MMIO](bare-metal/aps/mmio.md)
|
- [MMIO](bare-metal/aps/mmio.md)
|
||||||
- [Let's write a UART driver](bare-metal/aps/uart.md)
|
- [Let's write a UART driver](bare-metal/aps/uart.md)
|
||||||
- [More traits](bare-metal/aps/uart/traits.md)
|
- [More traits](bare-metal/aps/uart/traits.md)
|
||||||
|
@ -14,10 +14,6 @@ spin = "0.9.4"
|
|||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cc = "1.0.73"
|
cc = "1.0.73"
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "minimal"
|
|
||||||
path = "src/main_minimal.rs"
|
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "improved"
|
name = "improved"
|
||||||
path = "src/main_improved.rs"
|
path = "src/main_improved.rs"
|
||||||
@ -25,3 +21,11 @@ path = "src/main_improved.rs"
|
|||||||
[[bin]]
|
[[bin]]
|
||||||
name = "logger"
|
name = "logger"
|
||||||
path = "src/main_logger.rs"
|
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
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# 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
|
all: minimal.bin improved.bin logger.bin
|
||||||
|
|
||||||
build:
|
build:
|
||||||
cargo build
|
cargo build
|
||||||
|
|
||||||
minimal.bin: build
|
|
||||||
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/minimal $@
|
|
||||||
improved.bin: build
|
improved.bin: build
|
||||||
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/improved $@
|
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/improved $@
|
||||||
logger.bin: build
|
logger.bin: build
|
||||||
aarch64-linux-gnu-objcopy -O binary target/aarch64-unknown-none/debug/logger $@
|
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: improved.bin
|
||||||
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel $< -s
|
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel $< -s
|
||||||
qemu_logger: logger.bin
|
qemu_logger: logger.bin
|
||||||
qemu-system-aarch64 -machine virt -cpu max -serial mon:stdio -display none -kernel $< -s
|
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:
|
clean:
|
||||||
cargo 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