Skip to content

Commit 250f22e

Browse files
authored
Merge pull request #1924 from Gelbpunkt/aarch64_be
feat: aarch64_be support
2 parents 5bb3e34 + 61b14a6 commit 250f22e

File tree

7 files changed

+109
-37
lines changed

7 files changed

+109
-37
lines changed

.github/workflows/ci.yml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ jobs:
3838
cargo hack check --package hermit-kernel --each-feature --no-dev-deps --target aarch64-unknown-none-softfloat --exclude-features dhcpv4,dns,gem-net,net,rtl8139,virtio-net --features pci
3939
cargo hack check --package hermit-kernel --each-feature --no-dev-deps --target aarch64-unknown-none-softfloat --exclude-features gem-net,rtl8139 --features tcp,virtio-net
4040
cargo hack check --package hermit-kernel --each-feature --no-dev-deps --target aarch64-unknown-none-softfloat --exclude-features gem-net,rtl8139 --features pci,tcp,virtio-net
41+
- name: cargo hack check (aarch64_be)
42+
run: |
43+
cargo hack check --package hermit-kernel --each-feature --no-dev-deps --target aarch64_be-unknown-none-softfloat -Zbuild-std=core,alloc --exclude-features dhcpv4,dns,gem-net,net,rtl8139,virtio-net
44+
cargo hack check --package hermit-kernel --each-feature --no-dev-deps --target aarch64_be-unknown-none-softfloat -Zbuild-std=core,alloc --exclude-features dhcpv4,dns,gem-net,net,rtl8139,virtio-net --features pci
45+
cargo hack check --package hermit-kernel --each-feature --no-dev-deps --target aarch64_be-unknown-none-softfloat -Zbuild-std=core,alloc --exclude-features gem-net,rtl8139 --features tcp,virtio-net
46+
cargo hack check --package hermit-kernel --each-feature --no-dev-deps --target aarch64_be-unknown-none-softfloat -Zbuild-std=core,alloc --exclude-features gem-net,rtl8139 --features pci,tcp,virtio-net
4147
- name: cargo hack check (riscv64)
4248
run: |
4349
cargo hack check --package hermit-kernel --each-feature --no-dev-deps --target riscv64gc-unknown-none-elf --exclude-features dhcpv4,dns,gem-net,net,rtl8139,virtio-net
@@ -92,6 +98,7 @@ jobs:
9298
run: |
9399
cargo xtask build --arch x86_64 --no-default-features
94100
cargo xtask build --arch aarch64 --no-default-features
101+
cargo xtask build --arch aarch64_be --no-default-features
95102
96103
test:
97104
name: Test
@@ -119,15 +126,15 @@ jobs:
119126

120127
run-hermit:
121128
name: Run
122-
runs-on: ${{ matrix.arch == 'aarch64' && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
129+
runs-on: ${{ (matrix.arch == 'aarch64' || matrix.arch == 'aarch64_be') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
123130
env:
124131
HERMIT_CAREFUL: ${{ matrix.hermit-careful }}
125132
defaults:
126133
run:
127134
working-directory: kernel
128135
strategy:
129136
matrix:
130-
arch: [x86_64, aarch64, riscv64]
137+
arch: [x86_64, aarch64, aarch64_be, riscv64]
131138
profile: [dev, release]
132139
include:
133140
- profile: dev
@@ -137,6 +144,8 @@ jobs:
137144
flags: --accel --sudo
138145
- arch: aarch64
139146
packages: qemu-system-aarch64 ipxe-qemu
147+
- arch: aarch64_be
148+
packages: qemu-system-aarch64 ipxe-qemu
140149
- arch: riscv64
141150
packages: qemu-system-misc
142151

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,4 @@ exclude = [
216216
x86_64 = { git = "https://github.com/rust-osdev/x86_64.git" }
217217
# FIXME: remove once merged: https://github.com/rcore-os/trapframe-rs/pull/16
218218
trapframe = { git = "https://github.com/hermit-os/trapframe-rs", branch = "global_asm" }
219+
safe-mmio = { git = "https://github.com/hermit-os/safe-mmio", branch = "be" }

src/arch/aarch64/kernel/start.rs

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,49 @@ const fn mair(attr: u64, mt: u64) -> u64 {
118118
#[cfg(feature = "smp")]
119119
pub(crate) static TTBR0: AtomicPtr<u8> = AtomicPtr::new(core::ptr::null_mut());
120120

121+
// Prepare system control register (SCTRL)
122+
//
123+
// UCI [26] Enables EL0 access in AArch64 for DC CVAU, DC CIVAC,
124+
// DC CVAC and IC IVAU instructions
125+
// EE [25] Explicit data accesses at EL1 and Stage 1 translation
126+
// table walks at EL1 & EL0 are little-endian
127+
// EOE [24] Explicit data accesses at EL0 are little-endian
128+
// WXN [19] Regions with write permission are not forced to XN
129+
// nTWE [18] WFE instructions are executed as normal
130+
// nTWI [16] WFI instructions are executed as normal
131+
// UCT [15] Enables EL0 access in AArch64 to the CTR_EL0 register
132+
// DZE [14] Execution of the DC ZVA instruction is allowed at EL0
133+
// I [12] Instruction caches enabled at EL0 and EL1
134+
// UMA [9] Disable access to the interrupt masks from EL0
135+
// SED [8] The SETEND instruction is available
136+
// ITD [7] The IT instruction functionality is available
137+
// THEE [6] ThumbEE is disabled
138+
// CP15BEN [5] CP15 barrier operations disabled
139+
// SA0 [4] Stack Alignment check for EL0 enabled
140+
// SA [3] Stack Alignment check enabled
141+
// C [2] Data and unified enabled
142+
// A [1] Alignment fault checking disabled
143+
// M [0] MMU enable
144+
#[cfg(all(feature = "smp", target_endian = "little"))]
145+
static SCTLR_EL1: u64 = 0b100_0000_0101_1101_0000_0001_1101;
146+
// The same, but EE and EOE are set to 1 for big endian.
147+
#[cfg(all(feature = "smp", target_endian = "big"))]
148+
static SCTLR_EL1: u64 = 0b111_0000_0101_1101_0000_0001_1101;
149+
150+
#[cfg(all(feature = "smp", target_endian = "little"))]
151+
macro_rules! configure_endianness {
152+
() => {
153+
"bic x2, x2, #(1 << 24 | 1 << 25)"
154+
};
155+
}
156+
157+
#[cfg(all(feature = "smp", target_endian = "big"))]
158+
macro_rules! configure_endianness {
159+
() => {
160+
"orr x2, x2, #(1 << 24 | 1 << 25)"
161+
};
162+
}
163+
121164
#[cfg(feature = "smp")]
122165
#[unsafe(naked)]
123166
pub(crate) unsafe extern "C" fn smp_start() -> ! {
@@ -132,10 +175,12 @@ pub(crate) unsafe extern "C" fn smp_start() -> ! {
132175
"msr tpidr_el0, xzr",
133176
"msr tpidr_el1, xzr",
134177

135-
// Disable the MMU
178+
// Disable the MMU and set the correct endianness
179+
// by either clearing or setting bits 25 and 24 (EE and EOE)
136180
"dsb sy",
137181
"mrs x2, sctlr_el1",
138182
"bic x2, x2, #0x1",
183+
configure_endianness!(),
139184
"msr sctlr_el1, x2",
140185
"isb",
141186

@@ -189,31 +234,8 @@ pub(crate) unsafe extern "C" fn smp_start() -> ! {
189234
"ldr x5, [x8, #:lo12:{ttbr0}]",
190235
"msr ttbr0_el1, x5",
191236

192-
// Prepare system control register (SCTRL)
193-
//
194-
// UCI [26] Enables EL0 access in AArch64 for DC CVAU, DC CIVAC,
195-
// DC CVAC and IC IVAU instructions
196-
// EE [25] Explicit data accesses at EL1 and Stage 1 translation
197-
// table walks at EL1 & EL0 are little-endian
198-
// EOE [24] Explicit data accesses at EL0 are little-endian
199-
// WXN [19] Regions with write permission are not forced to XN
200-
// nTWE [18] WFE instructions are executed as normal
201-
// nTWI [16] WFI instructions are executed as normal
202-
// UCT [15] Enables EL0 access in AArch64 to the CTR_EL0 register
203-
// DZE [14] Execution of the DC ZVA instruction is allowed at EL0
204-
// I [12] Instruction caches enabled at EL0 and EL1
205-
// UMA [9] Disable access to the interrupt masks from EL0
206-
// SED [8] The SETEND instruction is available
207-
// ITD [7] The IT instruction functionality is available
208-
// THEE [6] ThumbEE is disabled
209-
// CP15BEN [5] CP15 barrier operations disabled
210-
// SA0 [4] Stack Alignment check for EL0 enabled
211-
// SA [3] Stack Alignment check enabled
212-
// C [2] Data and unified enabled
213-
// A [1] Alignment fault checking disabled
214-
// M [0] MMU enable
215-
"ldr x0, =0x405d01d",
216-
"msr sctlr_el1, x0",
237+
"ldr x0, ={sctlr_el1}",
238+
"msr sctlr_el1, x0",
217239

218240
// initialize argument for pre_init
219241
"mov x0, xzr",
@@ -227,6 +249,7 @@ pub(crate) unsafe extern "C" fn smp_start() -> ! {
227249
tcr_bits = const tcr_size(VA_BITS) | TCR_TG1_4K | TCR_FLAGS,
228250
stack_top_offset = const KERNEL_STACK_SIZE - TaskStacks::MARKER_SIZE,
229251
current_stack_address = sym super::CURRENT_STACK_ADDRESS,
252+
sctlr_el1 = const SCTLR_EL1,
230253
ttbr0 = sym TTBR0,
231254
pre_init = sym pre_init,
232255
)

xtask/src/arch.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ pub enum Arch {
1111
X86_64,
1212
/// AArch64
1313
Aarch64,
14+
/// AArch64, big-endian
15+
Aarch64Be,
1416
/// 64-bit RISC-V
1517
Riscv64,
1618
}
@@ -21,6 +23,10 @@ impl Arch {
2123
}
2224

2325
pub fn install(&self) -> Result<()> {
26+
if self.tier() > 2 {
27+
return Ok(());
28+
}
29+
2430
let mut rustup = crate::rustup();
2531
rustup.args(["target", "add", self.triple()]);
2632

@@ -42,14 +48,23 @@ impl Arch {
4248
match self {
4349
Self::X86_64 => "x86_64",
4450
Self::Aarch64 => "aarch64",
51+
Self::Aarch64Be => "aarch64_be",
4552
Self::Riscv64 => "riscv64",
4653
}
4754
}
4855

56+
pub fn tier(&self) -> u8 {
57+
match self {
58+
Self::Aarch64Be => 3,
59+
_ => 2,
60+
}
61+
}
62+
4963
pub fn triple(&self) -> &'static str {
5064
match self {
5165
Self::X86_64 => "x86_64-unknown-none",
5266
Self::Aarch64 => "aarch64-unknown-none-softfloat",
67+
Self::Aarch64Be => "aarch64_be-unknown-none-softfloat",
5368
Self::Riscv64 => "riscv64gc-unknown-none-elf",
5469
}
5570
}
@@ -58,6 +73,7 @@ impl Arch {
5873
match self {
5974
Self::X86_64 => "x86_64-unknown-hermit",
6075
Self::Aarch64 => "aarch64-unknown-hermit",
76+
Self::Aarch64Be => "aarch64_be-unknown-hermit",
6177
Self::Riscv64 => "riscv64gc-unknown-hermit",
6278
}
6379
}
@@ -74,6 +90,11 @@ impl Arch {
7490
"-Zbuild-std=core",
7591
"-Zbuild-std-features=compiler-builtins-mem",
7692
],
93+
Self::Aarch64Be => &[
94+
"--target=aarch64_be-unknown-hermit",
95+
"-Zbuild-std=core",
96+
"-Zbuild-std-features=compiler-builtins-mem",
97+
],
7798
Arch::Riscv64 => &[
7899
"--target=riscv64gc-unknown-hermit",
79100
"-Zbuild-std=core",
@@ -92,6 +113,13 @@ impl Arch {
92113
"-Zbuild-std=core,alloc",
93114
"-Zbuild-std-features=compiler-builtins-mem",
94115
],
116+
Self::Aarch64Be => &[
117+
"--target=aarch64_be-unknown-none-softfloat",
118+
// We can't use prebuilt std here because it is built with
119+
// relocation-model=static and we need relocation-model=pic
120+
"-Zbuild-std=core,alloc",
121+
"-Zbuild-std-features=compiler-builtins-mem",
122+
],
95123
Self::Riscv64 => &[
96124
"--target=riscv64gc-unknown-none-elf",
97125
// We can't use prebuilt std here because it is built with
@@ -112,6 +140,10 @@ impl Arch {
112140
"--target=aarch64-unknown-hermit",
113141
"-Zbuild-std=std,panic_abort",
114142
],
143+
Self::Aarch64Be => &[
144+
"--target=aarch64_be-unknown-hermit",
145+
"-Zbuild-std=std,panic_abort",
146+
],
115147
Arch::Riscv64 => &[
116148
"--target=riscv64gc-unknown-hermit",
117149
"-Zbuild-std=std,panic_abort",
@@ -122,10 +154,18 @@ impl Arch {
122154
pub fn rustflags(&self) -> &'static [&'static str] {
123155
match self {
124156
Self::X86_64 => &[],
125-
Self::Aarch64 => &["-Crelocation-model=pic"],
157+
Self::Aarch64 | Self::Aarch64Be => &["-Crelocation-model=pic"],
126158
Self::Riscv64 => &["-Cno-redzone", "-Crelocation-model=pic"],
127159
}
128160
}
161+
162+
pub fn qemu(&self) -> &'static str {
163+
match self {
164+
Self::X86_64 => "x86_64",
165+
Self::Aarch64 | Self::Aarch64Be => "aarch64",
166+
Self::Riscv64 => "riscv64",
167+
}
168+
}
129169
}
130170

131171
impl fmt::Display for Arch {

xtask/src/ci/qemu.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ impl Qemu {
8888
sh.create_dir("shared/tracedir")?;
8989
}
9090

91-
let qemu = env::var("QEMU").unwrap_or_else(|_| format!("qemu-system-{arch}"));
91+
let qemu = env::var("QEMU").unwrap_or_else(|_| format!("qemu-system-{}", arch.qemu()));
9292
let program = if self.sudo { "sudo" } else { qemu.as_str() };
9393
let arg = self.sudo.then_some(qemu.as_str());
9494
let memory = self.memory(image_name, arch, small);
@@ -208,7 +208,7 @@ impl Qemu {
208208
image_args.push("-initrd".to_string());
209209
image_args.push(image.to_str().unwrap().to_string());
210210
}
211-
Arch::Aarch64 => {
211+
Arch::Aarch64 | Arch::Aarch64Be => {
212212
image_args.push("-device".to_string());
213213
image_args.push(format!(
214214
"guest-loader,addr=0x48000000,initrd={}",
@@ -233,7 +233,7 @@ impl Qemu {
233233
"-nodefaults".to_string(),
234234
"-no-user-config".to_string(),
235235
]
236-
} else if arch == Arch::Aarch64 {
236+
} else if arch == Arch::Aarch64 || arch == Arch::Aarch64Be {
237237
vec!["-machine".to_string(), "virt,gic-version=3".to_string()]
238238
} else if arch == Arch::Riscv64 {
239239
// CadenceGem requires sifive_u
@@ -273,7 +273,7 @@ impl Qemu {
273273
cpu_args.push("isa-debug-exit,iobase=0xf4,iosize=0x04".to_string());
274274
cpu_args
275275
}
276-
Arch::Aarch64 => {
276+
Arch::Aarch64 | Arch::Aarch64Be => {
277277
let mut cpu_args = if self.accel {
278278
todo!()
279279
} else {
@@ -306,7 +306,7 @@ impl Qemu {
306306
32
307307
}
308308
}
309-
Arch::Aarch64 => 144,
309+
Arch::Aarch64 | Arch::Aarch64Be => 144,
310310
Arch::Riscv64 => 40,
311311
};
312312
}

xtask/src/clippy.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl Clippy {
3838
Arch::X86_64 => {
3939
clippy().arg("--features=shell").run()?;
4040
}
41-
Arch::Aarch64 => {}
41+
Arch::Aarch64 | Arch::Aarch64Be => {}
4242
Arch::Riscv64 => {
4343
clippy()
4444
.arg("--no-default-features")

0 commit comments

Comments
 (0)