kernel: Refactor kernel to allow cross calling between kernel and arch

Change-Id: Ic0b6c3b4a013f1028cf9432d37a5cb0ef8d4aaed
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/maize/+/260259
Commit-Queue: Erik Gilling <konkers@google.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
Reviewed-by: Travis Geiselbrecht <travisg@google.com>
diff --git a/arch/arm_cortex_m/BUILD.bazel b/arch/arm_cortex_m/BUILD.bazel
index f90f483..d3907a9 100644
--- a/arch/arm_cortex_m/BUILD.bazel
+++ b/arch/arm_cortex_m/BUILD.bazel
@@ -35,6 +35,7 @@
     crate_name = "arch_backend",
     deps = [
         "//arch:arch_interface",
+        "//kernel:kernel_core",
         "//target:linker_script",
         "@pigweed//pw_log/rust:pw_log",
         "@rust_crates//:cortex-m",
diff --git a/build/kernel/BUILD.bazel b/build/kernel/BUILD.bazel
index 14253c7..25fce97 100644
--- a/build/kernel/BUILD.bazel
+++ b/build/kernel/BUILD.bazel
@@ -27,7 +27,8 @@
         "//conditions:default": ["@platforms//:incompatible"],
     }),
     deps = [
-        "//kernel",
+        "//arch",
+        "//kernel:kernel_core",
         "//target:linker_script",
         "@rust_crates//:cortex-m-rt",
         "@rust_crates//:cortex-m-semihosting",
diff --git a/build/kernel/kernel_cortex_m_entry.rs b/build/kernel/kernel_cortex_m_entry.rs
index 3bbd664..795f0e3 100644
--- a/build/kernel/kernel_cortex_m_entry.rs
+++ b/build/kernel/kernel_cortex_m_entry.rs
@@ -23,9 +23,10 @@
 // Cortex M runtime entry macro.
 use cortex_m_rt::entry;
 
-use kernel;
+use arch::Arch;
+use kernel_core::Kernel;
 
 #[entry]
 fn main() -> ! {
-    kernel::kernel_main();
+    Kernel::<Arch>::main();
 }
diff --git a/kernel/BUILD.bazel b/kernel/BUILD.bazel
index f39fc87..1b5c1f5 100644
--- a/kernel/BUILD.bazel
+++ b/kernel/BUILD.bazel
@@ -20,8 +20,19 @@
     name = "kernel",
     srcs = ["kernel.rs"],
     deps = [
+        ":kernel_core",
         "//arch",
         "//target",
         "@pigweed//pw_log/rust:pw_log",
     ],
 )
+
+rust_library(
+    name = "kernel_core",
+    srcs = ["kernel_core/lib.rs"],
+    deps = [
+        "//arch:arch_interface",
+        "//target",
+        "@pigweed//pw_log/rust:pw_log",
+    ],
+)
diff --git a/kernel/kernel.rs b/kernel/kernel.rs
index 05919b5..7ab4c5a 100644
--- a/kernel/kernel.rs
+++ b/kernel/kernel.rs
@@ -13,20 +13,7 @@
 // the License.
 #![no_std]
 
-use arch::{Arch, ArchInterface};
-use pw_log::info;
-use target::{Target, TargetInterface};
+use arch::Arch;
 
-pub fn kernel_main() -> ! {
-    Target::console_init();
-    info!("Welcome to Maize on {}!", Target::NAME);
-    Arch::early_init();
-
-    info!("hello!");
-
-    Arch::init();
-
-    info!("End of kernel test");
-    #[allow(clippy::empty_loop)]
-    loop {}
-}
+// Re-export `Kernel` bound to the configured architecture.
+pub type Kernel = kernel_core::Kernel<Arch>;
diff --git a/kernel/kernel_core/lib.rs b/kernel/kernel_core/lib.rs
new file mode 100644
index 0000000..2c2c5a8
--- /dev/null
+++ b/kernel/kernel_core/lib.rs
@@ -0,0 +1,40 @@
+// Copyright 2025 The Pigweed Authors
+//
+// 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
+//
+//     https://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.
+#![no_std]
+
+use core::marker::PhantomData;
+
+use arch_interface::ArchInterface;
+use pw_log::info;
+use target::{Target, TargetInterface};
+
+pub struct Kernel<Arch: ArchInterface> {
+    _arch: PhantomData<Arch>,
+}
+
+impl<Arch: ArchInterface> Kernel<Arch> {
+    pub fn main() -> ! {
+        Target::console_init();
+        info!("Welcome to Maize on {}!", Target::NAME);
+        Arch::early_init();
+
+        info!("hello!");
+
+        Arch::init();
+
+        info!("End of kernel test");
+        #[allow(clippy::empty_loop)]
+        loop {}
+    }
+}