summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYecheng Zhao <zyecheng@google.com>2023-11-22 19:15:24 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-11-22 19:15:24 +0000
commit07b1a3f0b8839add292127b12d93fea1f33185df (patch)
tree6b25c968f557192d1bd4b8139fb964969e70e016
parente66fdc836ae7d74fe111daee74605bf1d56ae83c (diff)
parent62f2a221b836d6c1f6e2842a0bc892ac6b3b12ca (diff)
downloadlibbootloader-07b1a3f0b8839add292127b12d93fea1f33185df.tar.gz
Flush cache and disable MMU before booting linux am: 62f2a221b8
Original change: https://android-review.googlesource.com/c/platform/bootable/libbootloader/+/2833671 Change-Id: I16762abe37d6ee46180e5f876ebdbbac12d8d8ab Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--gbl/integration/aosp_u-boot-mainline/workspace.bzl6
-rw-r--r--gbl/libboot/BUILD7
-rw-r--r--gbl/libboot/aarch64_cache_helper/BUILD46
-rw-r--r--gbl/libboot/aarch64_cache_helper/BUILD.arm_trusted_firmware.bazel33
-rw-r--r--gbl/libboot/aarch64_cache_helper/disable_cache_mmu.S63
-rw-r--r--gbl/libboot/aarch64_cache_helper/include/common/asm_macros_common.S36
-rw-r--r--gbl/libboot/src/aarch64.rs13
7 files changed, 200 insertions, 4 deletions
diff --git a/gbl/integration/aosp_u-boot-mainline/workspace.bzl b/gbl/integration/aosp_u-boot-mainline/workspace.bzl
index 8c1ffc4..111a1cb 100644
--- a/gbl/integration/aosp_u-boot-mainline/workspace.bzl
+++ b/gbl/integration/aosp_u-boot-mainline/workspace.bzl
@@ -100,6 +100,12 @@ cc_library(
build_file = "@gbl//libfdt:BUILD.libfdt_c.bazel",
)
+ native.new_local_repository(
+ name = "arm_trusted_firmware",
+ path = "external/arm-trusted-firmware",
+ build_file = "@gbl//libboot/aarch64_cache_helper:BUILD.arm_trusted_firmware.bazel",
+ )
+
# Following are third party rust crates dependencies.
THIRD_PARTY_CRATES = [
diff --git a/gbl/libboot/BUILD b/gbl/libboot/BUILD
index 1159e50..71dd2f3 100644
--- a/gbl/libboot/BUILD
+++ b/gbl/libboot/BUILD
@@ -59,5 +59,10 @@ rust_library(
deps = [
":x86_bootparam_defs",
"@zerocopy",
- ],
+ ] + select({
+ "@gbl//toolchain:gbl_rust_uefi_aarch64": [
+ "@gbl//libboot/aarch64_cache_helper:aarch64_cache_helper_staticlib",
+ ],
+ "//conditions:default": [],
+ }),
)
diff --git a/gbl/libboot/aarch64_cache_helper/BUILD b/gbl/libboot/aarch64_cache_helper/BUILD
new file mode 100644
index 0000000..2da5b0c
--- /dev/null
+++ b/gbl/libboot/aarch64_cache_helper/BUILD
@@ -0,0 +1,46 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# 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.
+
+load("@gbl//toolchain:gbl_toolchain.bzl", "link_static_cc_library")
+
+package(
+ default_visibility = ["//visibility:public"],
+)
+
+exports_files(glob(["**/*"]))
+
+cc_library(
+ name = "asm_macros_common",
+ hdrs = ["include/common/asm_macros_common.S"],
+ includes = ["include"],
+)
+
+cc_library(
+ name = "aarch64_cache_helper",
+ srcs = [
+ "disable_cache_mmu.S",
+ "@arm_trusted_firmware//:lib/aarch64/cache_helpers.S",
+ ],
+ hdrs = ["@arm_trusted_firmware//:include/arch/aarch64/asm_macros.S"],
+ defines = ["__ASSEMBLER__"],
+ deps = [
+ ":asm_macros_common",
+ "@arm_trusted_firmware//:headers_aarch64",
+ ],
+)
+
+link_static_cc_library(
+ name = "aarch64_cache_helper_staticlib",
+ cc_library = ":aarch64_cache_helper",
+)
diff --git a/gbl/libboot/aarch64_cache_helper/BUILD.arm_trusted_firmware.bazel b/gbl/libboot/aarch64_cache_helper/BUILD.arm_trusted_firmware.bazel
new file mode 100644
index 0000000..1854244
--- /dev/null
+++ b/gbl/libboot/aarch64_cache_helper/BUILD.arm_trusted_firmware.bazel
@@ -0,0 +1,33 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# 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.
+
+package(
+ default_visibility = ["//visibility:public"],
+)
+
+exports_files(glob(["**/*"]))
+
+filegroup(
+ name = "header_files",
+ srcs = glob(["include/**/*.h"]),
+)
+
+cc_library(
+ name = "headers_aarch64",
+ hdrs = glob(["include/**/*.h"]),
+ includes = [
+ "include",
+ "include/arch/aarch64",
+ ],
+)
diff --git a/gbl/libboot/aarch64_cache_helper/disable_cache_mmu.S b/gbl/libboot/aarch64_cache_helper/disable_cache_mmu.S
new file mode 100644
index 0000000..424d543
--- /dev/null
+++ b/gbl/libboot/aarch64_cache_helper/disable_cache_mmu.S
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * 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.
+ */
+
+ #include <arch.h>
+
+.global disable_cache_mmu
+
+/*
+ * Cache flush and Cache/MMU disable should be done in order atomically to make sure RAM is up to
+ * date.
+ */
+disable_cache_mmu:
+ stp x29, x30, [sp, #-0x10]!
+ /*
+ * Call helper function "dcsw_op_all(DCCISW)" from ATF library to flush all cache.
+ */
+ mov x0, #DCCISW
+ bl dcsw_op_all
+ ic iallu
+ isb
+
+ // Query current EL
+ mrs x0, CurrentEL
+ cmp x0, #(1 << 2)
+ beq disable_cache_mmu_el1
+
+disable_cache_mmu_el1:
+ mrs x1, sctlr_el1
+ bic x1, x1, #SCTLR_M_BIT
+ bic x1, x1, #SCTLR_C_BIT
+ bic x1, x1, #SCTLR_I_BIT
+ msr sctlr_el1, x1
+ b finish
+
+disable_cache_mmu_el2:
+ mrs x1, sctlr_el2
+ bic x1, x1, #SCTLR_M_BIT
+ bic x1, x1, #SCTLR_C_BIT
+ bic x1, x1, #SCTLR_I_BIT
+ msr sctlr_el2, x1
+
+finish:
+ mov x0, #DCCISW
+ bl dcsw_op_all
+ ic iallu
+ isb
+ tlbi vmalle1
+
+ ldp x29, x30, [sp], #0x10
+ ret
diff --git a/gbl/libboot/aarch64_cache_helper/include/common/asm_macros_common.S b/gbl/libboot/aarch64_cache_helper/include/common/asm_macros_common.S
new file mode 100644
index 0000000..1bc4bfa
--- /dev/null
+++ b/gbl/libboot/aarch64_cache_helper/include/common/asm_macros_common.S
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * 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.
+ */
+
+/*
+ * This file replaces "external/arm-trusted-firmware/include/common/asm_macros_common.S" for
+ * building "external/arm-trusted-firmware/lib/aarch64/cache_helper.S". It defines the "func"
+ * macro for declaring assembly function. However the original file uses assembly directives
+ * such as ".size" for debug information which are not recogized by LLVM when building for
+ * windows/msvc target. Thus we use our custom definition to workaround.
+ */
+
+/*
+ * This macro marks the begin of a function. It simply creates a label.
+ */
+.macro func _name
+\_name:
+.endm
+
+/*
+ * This macro is used to mark the end of a function. For our usage, it's simply a noop.
+ */
+.macro endfunc _name
+.endm
diff --git a/gbl/libboot/src/aarch64.rs b/gbl/libboot/src/aarch64.rs
index 7fa7a9b..6badb59 100644
--- a/gbl/libboot/src/aarch64.rs
+++ b/gbl/libboot/src/aarch64.rs
@@ -46,6 +46,11 @@ pub fn current_el() -> ExceptionLevel {
}
}
+extern "C" {
+ /// Clean and invalidate data cache and disable data/instruction cache and MMU.
+ fn disable_cache_mmu();
+}
+
/// Boots a Linux kernel in mode EL2 or lower with the given FDT blob.
///
/// # Safety
@@ -53,9 +58,11 @@ pub fn current_el() -> ExceptionLevel {
/// Caller must ensure that `kernel` contains a valid Linux kernel.
pub unsafe fn jump_linux_el2_or_lower(kernel: &[u8], fdt: &[u8]) -> ! {
assert_ne!(current_el(), ExceptionLevel::EL3);
- // TODO(b/305093905): Perform other initialization including disabling MMU, flushing cache and
- // masking interrupt.
-
+ // The following is sufficient to work for existing use cases such as Cuttlefish. But there are
+ // additional initializations listed
+ // https://www.kernel.org/doc/html/v5.11/arm64/booting.html that may need to be performed
+ // explicitly for other platforms.
+ disable_cache_mmu();
asm!(
"mov x1, 0",
"mov x2, 0",