cortex-m: add feature struct (unused) start to set up the hardware
Change-Id: Ie12381efe614ec034c4dcdafddef15a29724d203
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/maize/+/261714
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
Commit-Queue: Erik Gilling <konkers@google.com>
Reviewed-by: Erik Gilling <konkers@google.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/kernel/BUILD.bazel b/kernel/BUILD.bazel
index c3a9a5f..ec798df 100644
--- a/kernel/BUILD.bazel
+++ b/kernel/BUILD.bazel
@@ -17,6 +17,7 @@
package(default_visibility = ["//visibility:public"])
CORTEX_M_DEPS = [
+ "@rust_crates//:cortex-m",
"@rust_crates//:cortex-m-rt",
]
@@ -24,6 +25,7 @@
name = "kernel",
srcs = [
"kernel/arch/arm_cortex_m/exceptions.rs",
+ "kernel/arch/arm_cortex_m/features.rs",
"kernel/arch/arm_cortex_m/mod.rs",
"kernel/arch/host/mod.rs",
"kernel/arch/mod.rs",
diff --git a/kernel/kernel/arch/arm_cortex_m/features.rs b/kernel/kernel/arch/arm_cortex_m/features.rs
new file mode 100644
index 0000000..f1d8721
--- /dev/null
+++ b/kernel/kernel/arch/arm_cortex_m/features.rs
@@ -0,0 +1,65 @@
+// 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 cortex_m::peripheral::Peripherals;
+use pw_log::info;
+
+// Start of trying to read features out of CPUID and other registers in hardware.
+
+// Not complete and currently unused.
+
+#[derive(PartialEq, PartialOrd)]
+pub enum ArchVersion {
+ ArmV6m = 0,
+ ArmV7m = 1,
+ ARMv8m = 2,
+}
+pub struct Features {
+ arch_version: ArchVersion,
+ has_vtor: bool,
+}
+
+impl Features {
+ pub const fn new() -> Features {
+ return Features {
+ arch_version: ArchVersion::ArmV6m,
+ has_vtor: false,
+ };
+ }
+
+ pub fn read_features(&mut self) {
+ let p = Peripherals::take().unwrap();
+ let cpuid = p.CPUID.base.read();
+ info!("CPUID 0x{:x}", cpuid);
+
+ let mut f = Features::new();
+ if (cpuid >> 16 & 0xf) != 0xf {
+ // ARMv6m has an architecture field of 0xc
+ f.arch_version = ArchVersion::ArmV6m;
+ f.has_vtor = true;
+ } else {
+ // TODO: figure out more arch version bits here
+ f.arch_version = ArchVersion::ArmV7m;
+ f.has_vtor = true;
+ }
+ }
+
+ pub fn at_least_version(&self, version: ArchVersion) -> bool {
+ if version <= self.arch_version {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/kernel/kernel/arch/arm_cortex_m/mod.rs b/kernel/kernel/arch/arm_cortex_m/mod.rs
index 84db20c..bdd1157 100644
--- a/kernel/kernel/arch/arm_cortex_m/mod.rs
+++ b/kernel/kernel/arch/arm_cortex_m/mod.rs
@@ -12,6 +12,9 @@
// License for the specific language governing permissions and limitations under
// the License.
+use cortex_m::peripheral::Peripherals;
+use pw_log::info;
+
use super::ArchInterface;
mod exceptions;
@@ -31,12 +34,33 @@
fn early_init() {
// TODO: set up the cpu here:
- // interrupt vector table
- // irq priority levels
- // clear pending interrupts
- // FPU initial state
- // enable cache (if present)
- // enable cycle counter?
+ // interrupt vector table
+ // irq priority levels
+ // clear pending interrupts
+ // FPU initial state
+ // enable cache (if present)
+ // enable cycle counter?
+ let p = Peripherals::take().unwrap();
+ let cpuid = p.CPUID.base.read();
+ info!("CPUID 0x{:x}", cpuid);
+
+ // Set the VTOR (assumes it exists)
+ unsafe {
+ extern "C" {
+ fn pw_boot_vector_table_addr();
+ }
+ let vector_table = pw_boot_vector_table_addr as *const ();
+ p.SCB.vtor.write(vector_table as u32);
+ }
+
+ // Intentionally trigger a hard fault to make sure the VTOR is working.
+ // use core::arch::asm;
+ // unsafe {
+ // asm!("bkpt");
+ // }
}
- fn init() {}
+
+ fn init() {
+ info!("arch init");
+ }
}