Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions docs/TIERED_ARM_TRACE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Explicit tiered ARM diagnostic parser

The existing `parse_arm64_trace_configuration` entry keeps its profile maximum
of 64 instructions and absent-profile maximum of 8. The new
`parse_arm64_trace_configuration_with_limit` entry requires an explicit limit
of 64, 256, 1024 or 4096. Limits 0, 65 and 4097 are invalid. Budgets above 64
must be one of 256, 1024 or 4096 and fit within that limit. Selecting a larger
limit never provisions a missing platform or raises the absent-profile
maximum of 8. Memory, handoff, platform and DT configuration checks still use
the same parser implementation.

This entry is for an explicit diagnostic-only EFI feature. Default callers
continue using the original function. Original bytes remain unchanged; a
budget outcome proves only bounded instruction execution, not normal boot.
17 changes: 11 additions & 6 deletions repository-files.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
"bytes": 1200,
"sha256": "d7ec3da6c39dcbcb8733c85016874e6f0cd982137c4f4c105a00ab71c9b45fa4"
},
{
"path": "docs/TIERED_ARM_TRACE.md",
"bytes": 820,
"sha256": "7b4ac7b1720869e8b6aa88f2f7a7cb3beb41ca1db8706c47355fc7f865ff45d1"
},
{
"path": "examples/audit_kc.rs",
"bytes": 3210,
Expand Down Expand Up @@ -58,8 +63,8 @@
},
{
"path": "repository.json",
"bytes": 1394,
"sha256": "64f2d11a45a5e2a9bab8a704d63a9757582d4069a1f32e6ec992363253ff912d"
"bytes": 1396,
"sha256": "fe17d7e0d4979fde4916c92631cb65fda8e2732aabd3d5237cf3af2392d86abd"
},
{
"path": "src/acpi.rs",
Expand All @@ -73,8 +78,8 @@
},
{
"path": "src/boot_config.rs",
"bytes": 30591,
"sha256": "c182ddc16b84501f032de336fb4c63ccd35c3b2f5eca6f3da8a4d5a4ea14a253"
"bytes": 31190,
"sha256": "be0e13ec360759c4605f16d34b53c904fb700246da3e7e08382b606069cc81c0"
},
{
"path": "src/boot_picker.rs",
Expand Down Expand Up @@ -198,8 +203,8 @@
},
{
"path": "tests/arm64_platform_config.rs",
"bytes": 5971,
"sha256": "fdd1c27a51a7f71ffb95303de7b2173b1843878836a3bc838fae3ae7a1d6e34e"
"bytes": 7880,
"sha256": "a6d5e6f56a801a639abdc71fe4e8698a38d904e382f0a6db2a5bd757d4de97bb"
},
{
"path": "tests/boot_config.rs",
Expand Down
4 changes: 2 additions & 2 deletions repository.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
"crate": "nextcore-core",
"description": "Public boot configuration and bounded format codecs, including APFS Jumpstart extraction.",
"development": {
"branch": "codex/arm64e-boot-metal",
"branch": "codex/tiered-trace-budget",
"base_commit": "6547be4bbf6b75cf706b89ade4d4a60d5441d223",
"updated_utc": "2026-09-08T14:42:36.688484+00:00",
"updated_utc": "2026-09-08T16:46:07.724853+00:00",
"dependency_revisions": {},
"integration": "Git submodule with an immutable gitlink; workspace source patches for local development"
},
Expand Down
16 changes: 15 additions & 1 deletion src/boot_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,18 @@ fn parse_named_kernel_target(input: &[u8], arm: bool) -> Result<KernelTarget> {
/// provisioned. The prefix is bounded to eight instructions without a platform
/// profile, or64 with the explicit software interrupt compatibility profile.
pub fn parse_arm64_trace_configuration(input: &[u8]) -> Result<Arm64TraceConfiguration> {
parse_arm64_trace_configuration_with_limit(input, 64)
}

/// Explicit diagnostic-only extension. Default callers retain the64/8 entry.
/// The limit and any budget above64 must be an approved bounded tier.
pub fn parse_arm64_trace_configuration_with_limit(
input: &[u8],
maximum_budget: u64,
) -> Result<Arm64TraceConfiguration> {
if !matches!(maximum_budget, 64 | 256 | 1024 | 4096) {
return Err(BootConfigError::InvalidTraceConfiguration);
}
if parse_arm64_kernel_target(input)?.profile != KernelProfile::X86EfiArm64Trace {
return Err(BootConfigError::UnsupportedKernelProfile);
}
Expand Down Expand Up @@ -440,7 +452,9 @@ pub fn parse_arm64_trace_configuration(input: &[u8]) -> Result<Arm64TraceConfigu
|| result.kernel_phys < result.physical_base
|| result.kernel_phys >= result.physical_base + result.memory_size
|| result.instruction_budget == 0
|| result.instruction_budget > if result.platform.is_some() { 64 } else { 8 }
|| result.instruction_budget > if result.platform.is_some() { maximum_budget } else { 8 }
|| (result.instruction_budget > 64
&& !matches!(result.instruction_budget, 256 | 1024 | 4096))
{
return Err(BootConfigError::InvalidTraceConfiguration);
}
Expand Down
42 changes: 42 additions & 0 deletions tests/arm64_platform_config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use nextcore_core::boot_config::{
parse_arm64_trace_configuration as parse, Arm64PlatformProfile, BootConfigError as E,
parse_arm64_trace_configuration_with_limit as parse_with_limit,
};

fn config(profile: Option<&str>, options: Option<&str>, budget: u64) -> Vec<u8> {
Expand All @@ -23,6 +24,47 @@ fn integer(name: &str, value: u64) -> String {
}
const PROFILE: &str = "nextcore-irq-compat-v1";

#[test]
fn explicit_tiers_require_a_valid_ceiling_and_do_not_change_the_default_entry() {
for maximum in [64, 256, 1024, 4096] {
for budget in [1, 8, 63, 64, 256, 1024, 4096] {
let input = config(Some(PROFILE), None, budget);
assert_eq!(parse_with_limit(&input, maximum).is_ok(), budget <= maximum);
assert_eq!(parse(&input).is_ok(), budget <= 64);
}
}
for maximum in [0, 8, 65, 255, 1023, 4097, u64::MAX] {
assert_eq!(parse_with_limit(&config(Some(PROFILE), None, 8), maximum), Err(E::InvalidTraceConfiguration));
}
}

#[test]
fn unsupported_extended_budgets_never_become_arbitrary_long_runs() {
for budget in [0, 65, 128, 255, 257, 512, 1023, 1025, 2048, 4095, 4097, u64::MAX] {
assert_eq!(parse_with_limit(&config(Some(PROFILE), None, budget), 4096), Err(E::InvalidTraceConfiguration));
}
}

#[test]
fn extended_ceiling_does_not_provision_a_profile_or_expand_its_absent_bound() {
for maximum in [64, 256, 1024, 4096] {
assert_eq!(parse_with_limit(&config(None, None, 8), maximum).unwrap().platform, None);
for budget in [9, 64, 256, 1024, 4096] {
assert_eq!(parse_with_limit(&config(None, None, budget), maximum), Err(E::InvalidTraceConfiguration));
}
}
}

#[test]
fn extended_configuration_retains_handoff_memory_and_platform_validation() {
let valid = String::from_utf8(config(Some(PROFILE), None, 256)).unwrap();
for input in [valid.replace("unprovisioned-sptm-prefix", "automatic"),
valid.replace("0x40000000", "0x40000001")] {
assert_eq!(parse_with_limit(input.as_bytes(), 4096), Err(E::InvalidTraceConfiguration));
}
assert_eq!(parse_with_limit(&config(Some(PROFILE), Some(&integer("IrqLevel", 2)), 256), 4096), Err(E::InvalidPlatformConfiguration));
}

#[test]
fn absent_profile_retains_old_bound_and_does_not_create_a_provider() {
assert_eq!(parse(&config(None, None, 8)).unwrap().platform, None);
Expand Down
Loading