diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4d0d984b..e0928d46 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,7 +42,7 @@ jobs: name: Run strategy: matrix: - target: [x86_64, aarch64, riscv64] + target: [x86_64, aarch64, aarch64_be, riscv64] os: [ubuntu-latest, macos-latest, windows-latest] include: - target: x86_64 @@ -83,8 +83,11 @@ jobs: - uses: actions/checkout@v5 with: lfs: true - - name: Install stable Rust toolchain - uses: dtolnay/rust-toolchain@stable + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.target == 'aarch64_be' && 'nightly' || 'stable' }} + components: ${{ matrix.target == 'aarch64_be' && 'rust-src' || '' }} - name: Dowload OpenSBI if: matrix.target == 'riscv64' run: | diff --git a/data/aarch64_be/hello_world b/data/aarch64_be/hello_world new file mode 100755 index 00000000..3ee062bb --- /dev/null +++ b/data/aarch64_be/hello_world @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:652a3617267de4e2dc79533188dfb35e165ca4324dd354b9ed9c434de2f6320b +size 801232 diff --git a/src/arch/aarch64/entry.rs b/src/arch/aarch64/entry.rs index 55a7bef3..9c06c291 100644 --- a/src/arch/aarch64/entry.rs +++ b/src/arch/aarch64/entry.rs @@ -165,10 +165,13 @@ unsafe fn pre_init() -> ! { or if loading and not setting them would be the appropriate action. */ + #[cfg(target_endian = "big")] + let endian = SCTLR_EL1::EE::BigEndian + SCTLR_EL1::E0E::BigEndian; + #[cfg(target_endian = "little")] + let endian = SCTLR_EL1::EE::LittleEndian + SCTLR_EL1::E0E::LittleEndian; + SCTLR_EL1.write( SCTLR_EL1::UCI::DontTrap - + SCTLR_EL1::EE::LittleEndian - + SCTLR_EL1::E0E::LittleEndian + SCTLR_EL1::WXN::Disable + SCTLR_EL1::NTWE::DontTrap + SCTLR_EL1::NTWI::DontTrap @@ -181,7 +184,8 @@ unsafe fn pre_init() -> ! { + SCTLR_EL1::SA::Enable + SCTLR_EL1::C::Cacheable + SCTLR_EL1::A::Disable - + SCTLR_EL1::M::Disable, + + SCTLR_EL1::M::Disable + + endian, ); // Enter loader diff --git a/src/arch/aarch64/link.ld b/src/arch/aarch64/link.ld index 5b783e58..e7e4206b 100644 --- a/src/arch/aarch64/link.ld +++ b/src/arch/aarch64/link.ld @@ -2,8 +2,6 @@ * https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials/blob/master/16_virtual_mem_part4_higher_half_kernel/src/bsp/raspberrypi/link.ld */ -OUTPUT_FORMAT("elf64-littleaarch64") -OUTPUT_ARCH("aarch64") ENTRY(_start) phys = 0x40200000; diff --git a/xtask/src/ci/qemu.rs b/xtask/src/ci/qemu.rs index 0797935c..d3ab8a48 100644 --- a/xtask/src/ci/qemu.rs +++ b/xtask/src/ci/qemu.rs @@ -63,8 +63,8 @@ impl Qemu { } let target = self.build.target(); - let arch = target.arch(); - let qemu = env::var("QEMU").unwrap_or_else(|_| format!("qemu-system-{arch}")); + let qemu = target.qemu(); + let qemu = env::var("QEMU").unwrap_or_else(|_| format!("qemu-system-{qemu}")); let program = if self.sudo { "sudo" } else { qemu.as_str() }; let arg = self.sudo.then_some(qemu.as_str()); @@ -96,7 +96,7 @@ impl Qemu { "-append".to_string(), format!("-freq {frequency}"), ] - } else if self.build.target() == Target::Aarch64 { + } else if matches!(self.build.target(), Target::Aarch64 | Target::Aarch64Be) { vec!["-machine".to_string(), "virt,gic-version=3".to_string()] } else if self.build.target() == Target::Riscv64 { vec![ @@ -174,7 +174,7 @@ impl Qemu { cpu_args } Target::X86_64Fc => panic!("unsupported"), - Target::Aarch64 => { + Target::Aarch64 | Target::Aarch64Be => { let mut cpu_args = if self.accel { todo!() } else { @@ -233,7 +233,7 @@ impl Qemu { Target::X86_64Uefi => { memory = memory.max(512); } - Target::Aarch64 => { + Target::Aarch64 | Target::Aarch64Be => { memory = memory.max(256); } Target::Riscv64 => { diff --git a/xtask/src/target.rs b/xtask/src/target.rs index aa292f20..acce13e5 100644 --- a/xtask/src/target.rs +++ b/xtask/src/target.rs @@ -9,6 +9,7 @@ pub enum Target { X86_64Fc, X86_64Uefi, Aarch64, + Aarch64Be, Riscv64, } @@ -16,8 +17,10 @@ impl Target { pub fn install(&self) -> xshell::Result<()> { let sh = Shell::new()?; - let triple = self.triple(); - cmd!(sh, "rustup target add {triple}").run()?; + if self.tier() <= 2 { + let triple = self.triple(); + cmd!(sh, "rustup target add {triple}").run()?; + } if self == &Self::X86_64 { cmd!(sh, "rustup component add llvm-tools-preview").run()?; @@ -32,6 +35,7 @@ impl Target { Self::X86_64Fc => "x86_64", Self::X86_64Uefi => "x86_64", Self::Aarch64 => "aarch64", + Self::Aarch64Be => "aarch64_be", Self::Riscv64 => "riscv64", } } @@ -42,16 +46,28 @@ impl Target { Self::X86_64Fc => "x86_64-unknown-none", Self::X86_64Uefi => "x86_64-unknown-uefi", Self::Aarch64 => "aarch64-unknown-none-softfloat", + Self::Aarch64Be => "aarch64_be-unknown-none-softfloat", Self::Riscv64 => "riscv64imac-unknown-none-elf", } } + pub fn tier(&self) -> u8 { + match self { + Self::Aarch64Be => 3, + _ => 2, + } + } + pub fn cargo_args(&self) -> &'static [&'static str] { match self { Self::X86_64 => &["--target=x86_64-unknown-none"], Self::X86_64Fc => &["--target=x86_64-unknown-none"], Self::X86_64Uefi => &["--target=x86_64-unknown-uefi"], Self::Aarch64 => &["--target=aarch64-unknown-none-softfloat"], + Self::Aarch64Be => &[ + "--target=aarch64_be-unknown-none-softfloat", + "-Zbuild-std=core,alloc,panic_abort", + ], Self::Riscv64 => &["--target=riscv64imac-unknown-none-elf"], } } @@ -67,7 +83,7 @@ impl Target { "-Crelocation-model=static", ], Self::X86_64Uefi => &[], - Self::Aarch64 => &["-Clink-arg=-Tsrc/arch/aarch64/link.ld"], + Self::Aarch64 | Self::Aarch64Be => &["-Clink-arg=-Tsrc/arch/aarch64/link.ld"], Self::Riscv64 => &["-Clink-arg=-Tsrc/arch/riscv64/link.ld"], } } @@ -92,9 +108,18 @@ impl Target { Self::X86_64Fc => "hermit-loader-x86_64-fc", Self::X86_64Uefi => "hermit-loader-x86_64.efi", Self::Aarch64 => "hermit-loader-aarch64", + Self::Aarch64Be => "hermit-loader-aarch64_be", Self::Riscv64 => "hermit-loader-riscv64", } } + + pub fn qemu(&self) -> &'static str { + match self { + Self::X86_64 | Self::X86_64Fc | Self::X86_64Uefi => "x86_64", + Self::Aarch64 | Self::Aarch64Be => "aarch64", + Self::Riscv64 => "riscv64", + } + } } impl FromStr for Target { @@ -106,6 +131,7 @@ impl FromStr for Target { "x86_64-fc" => Ok(Self::X86_64Fc), "x86_64-uefi" => Ok(Self::X86_64Uefi), "aarch64" => Ok(Self::Aarch64), + "aarch64_be" => Ok(Self::Aarch64Be), "riscv64" => Ok(Self::Riscv64), s => Err(anyhow!("Unsupported target: {s}")), }