S81 · SOURCE-BOUND GATE EVIDENCE
G8g per-CPU periodic timer sözleşmesi yeşil; runtime bilinçli STOP
Operations --test hedefi → simulation public mod g8g_uart bağı → kaynak kesiti Bu sayfa yalnız S81 kapısına aittir; komşu kapıların kaynakları bu kabulün içine katılmaz.
S81Focused kod testiOperations id exactsource SHA exacttest target exact
operation: rpi5-g8g-contract-parser-runtime-stop
uygulama/model · focused test · Operations · 3 exact excerpt
sequence-bound=true · implementation-bound=false
01 · Testin bağlı olduğu uygulama/model kodu
Kapının yürüttüğü gerçek kaynak
tam Rust öğesiL65–L779
simulation/src/g8g_uart.rs::verify_transcript
pub fn verify_transcript(input: &[u8]) -> Result<G8gEvidence, ValidationError> {
let mut errors = Vec::new();
let g8g_start = [b"ASELSAN/G8G".as_slice(), b"ASELSAN/BOOT8G".as_slice()]
.into_iter()
.filter_map(|needle| find_bytes(input, needle))
.min()
.unwrap_or(input.len());
let g8f = match verify_g8f(&input[..g8g_start]) {
Ok(evidence) => Some(evidence),
Err(error) => {
errors.extend(
error
.messages()
.iter()
.map(|message| format!("G8f prerequisite: {message}")),
);
None
}
};
let leading_nuls = input.iter().take_while(|&&byte| byte == 0).count();
if input[leading_nuls..].contains(&0) {
errors.push("transcript contains a non-leading NUL byte".to_string());
return Err(ValidationError { messages: errors });
}
let transcript = match std::str::from_utf8(&input[leading_nuls..]) {
Ok(value) => value,
Err(error) => {
errors.push(format!("transcript is not UTF-8: {error}"));
return Err(ValidationError { messages: errors });
}
};
let mut positions: BTreeMap<&'static str, Vec<usize>> = MARKERS
.iter()
.copied()
.map(|marker| (marker, Vec::new()))
.collect();
let mut boot8f_line = None;
let mut cpu0_frequency = None;
let mut cpu1_frequency = None;
let mut cpu0_period = None;
let mut cpu1_period = None;
let mut cpu0_start = None;
let mut cpu1_start = None;
let mut cpu0_next_before = None;
let mut cpu0_next_after = None;
let mut cpu0_capture_count = None;
let mut cpu0_ticks_before = None;
let mut cpu0_ticks_after = None;
let mut cpu1_first_cval = None;
let mut first_previous = None;
let mut first_next = None;
let mut first_delta = None;
let mut second_previous = None;
let mut second_next = None;
let mut second_delta = None;
let mut cpu1_local_ticks = None;
let mut cpu1_deliveries = None;
let mut cpu1_acks = None;
let mut cpu1_eois = None;
let mut boot_base = None;
let mut boot_ticks = None;
let mut third_check_count = None;
let mut third_check_delta = None;
let mut cpu0_tick_marker_lines = Vec::new();
for (index, raw_line) in transcript.lines().enumerate() {
let line_number = index + 1;
let line = raw_line.trim_end_matches('\r').trim();
if line.starts_with("[SEC") {
cpu0_tick_marker_lines.push(line_number);
}
if has_marker_tag(line, "ASELSAN/BOOT8F") {
boot8f_line = Some(line_number);
}
if line.contains("ASELSAN/G8GERR")
|| line.contains("ASELSAN/G8FERR")
|| line.contains("panicked at")
|| line.contains("Kernel panic")
|| line.contains("Unknown IRQ")
|| line.contains("Bilinmeyen IRQ")
|| line.contains("Unhandled IRQ")
{
errors.push(format!(
"line {line_number}: failure evidence present: {line:?}"
));
}
let known = MARKERS
.iter()
.copied()
.find(|marker| has_marker_tag(line, marker));
if (line.starts_with("ASELSAN/G8G") || line.starts_with("ASELSAN/BOOT8G"))
&& known.is_none()
{
errors.push(format!(
"line {line_number}: unknown G8g marker present: {line:?}"
));
}
let Some(marker) = known else {
continue;
};
positions
.get_mut(marker)
.expect("known G8g marker")
.push(line_number);
let (fields, field_order) = match parse_fields(line, marker) {
Ok(parsed) => parsed,
Err(message) => {
errors.push(format!("line {line_number}: {message}"));
continue;
}
};
match marker {
"ASELSAN/G8G0" => {
require_exact_keys(
&fields,
&field_order,
&[
"CPU",
"PREREQ",
"TARGET",
"MPIDR",
"TIMER",
"MODE",
"SLOTS",
"CPU0_SLOT",
"CPU1_SLOT",
"ALIAS",
"INVALID_CPU",
"CPU0_FREQ",
"CPU0_PERIOD",
"CPU0_START",
"CPU0_NEXT_CVAL",
"CPU0_TICKS",
"CPU0_CAPTURE_COUNT",
"CPU1_FREQ",
"CPU1_PERIOD",
"CPU1_START",
"CPU1_FIRST_CVAL",
"GIC_REINIT",
"SCHED",
"START_TICKS",
],
line_number,
&mut errors,
);
for (key, expected) in [
("CPU", "0"),
("PREREQ", "BOOT8F"),
("TARGET", "CPU1"),
("MPIDR", "0x100"),
("TIMER", "PPI27"),
("MODE", "PER_CPU_PERIODIC"),
("SLOTS", "4"),
("CPU0_SLOT", "0"),
("CPU1_SLOT", "1"),
("ALIAS", "NO"),
("INVALID_CPU", "REJECT"),
("GIC_REINIT", "OFF"),
("SCHED", "OFF"),
] {
require_field(&fields, key, expected, line_number, &mut errors);
}
cpu0_frequency = parse_decimal(&fields, "CPU0_FREQ", line_number, &mut errors);
cpu1_frequency = parse_decimal(&fields, "CPU1_FREQ", line_number, &mut errors);
cpu0_period = parse_decimal(&fields, "CPU0_PERIOD", line_number, &mut errors);
cpu1_period = parse_decimal(&fields, "CPU1_PERIOD", line_number, &mut errors);
cpu0_start = parse_decimal(&fields, "CPU0_START", line_number, &mut errors);
cpu1_start = parse_decimal(&fields, "CPU1_START", line_number, &mut errors);
cpu0_next_before =
parse_decimal(&fields, "CPU0_NEXT_CVAL", line_number, &mut errors);
cpu0_ticks_before = parse_decimal(&fields, "CPU0_TICKS", line_number, &mut errors);
cpu0_capture_count =
parse_decimal(&fields, "CPU0_CAPTURE_COUNT", line_number, &mut errors);
cpu1_first_cval =
parse_decimal(&fields, "CPU1_FIRST_CVAL", line_number, &mut errors);
let start_ticks = parse_decimal(&fields, "START_TICKS", line_number, &mut errors);
if cpu1_first_cval
.zip(cpu1_start)
.zip(cpu1_period)
.is_some_and(|((first, start), period)| {
first.checked_sub(start) != Some(period)
})
{
errors.push(format!(
"line {line_number}: CPU1_FIRST_CVAL must equal CPU1_START plus one period"
));
}
if start_ticks != cpu0_ticks_before {
errors.push(format!(
"line {line_number}: START_TICKS must equal CPU0_TICKS"
));
}
}
"ASELSAN/G8G1" | "ASELSAN/G8G2" => {
require_exact_keys(
&fields,
&field_order,
&[
"REPORTER",
"CPU",
"MPIDR",
"INTID",
"DELIVERY",
"ACK",
"EOI",
"ACK_RAW",
"EOI_RAW",
"PERIOD",
"PREV_CVAL",
"NEXT_CVAL",
"DELTA",
"FIRED_COUNT",
"DRIFT_COUNTS",
"LOCAL_TICK",
"GLOBAL_TICKS",
"CPU0_STATE_MUTATIONS",
"SCHED",
"TASK_RUNS",
"HEAP_OPS",
"UART_WRITES",
],
line_number,
&mut errors,
);
let expected_round = if marker == "ASELSAN/G8G1" { "1" } else { "2" };
for (key, expected) in [
("REPORTER", "CPU0"),
("CPU", "1"),
("MPIDR", "0x100"),
("INTID", "27"),
("DELIVERY", expected_round),
("ACK", expected_round),
("EOI", expected_round),
("ACK_RAW", "0x1b"),
("EOI_RAW", "0x1b"),
("LOCAL_TICK", expected_round),
("CPU0_STATE_MUTATIONS", "0"),
("SCHED", "OFF"),
("TASK_RUNS", "0"),
("HEAP_OPS", "0"),
("UART_WRITES", "0"),
] {
require_field(&fields, key, expected, line_number, &mut errors);
}
let period = parse_decimal(&fields, "PERIOD", line_number, &mut errors);
let previous = parse_decimal(&fields, "PREV_CVAL", line_number, &mut errors);
let next = parse_decimal(&fields, "NEXT_CVAL", line_number, &mut errors);
let delta = parse_decimal(&fields, "DELTA", line_number, &mut errors);
let fired = parse_decimal(&fields, "FIRED_COUNT", line_number, &mut errors);
let drift = parse_decimal(&fields, "DRIFT_COUNTS", line_number, &mut errors);
let global_ticks = parse_decimal(&fields, "GLOBAL_TICKS", line_number, &mut errors);
if previous
.zip(next)
.is_some_and(|(previous, next)| next.checked_sub(previous) != period)
{
errors.push(format!(
"line {line_number}: NEXT_CVAL minus PREV_CVAL must equal PERIOD"
));
}
if delta != period {
errors.push(format!(
"line {line_number}: DELTA must equal PERIOD: delta={delta:?}, period={period:?}"
));
}
if let Some((fired, previous)) = fired.zip(previous) {
match fired.checked_sub(previous) {
Some(observed_drift) => {
if drift.is_some_and(|drift| drift != observed_drift) {
errors.push(format!(
"line {line_number}: DRIFT_COUNTS must equal FIRED_COUNT minus PREV_CVAL"
));
}
}
None => errors.push(format!(
"line {line_number}: timer fired before its absolute deadline"
)),
}
}
if fired.zip(next).is_some_and(|(fired, next)| fired >= next) {
errors.push(format!(
"line {line_number}: FIRED_COUNT must be less than NEXT_CVAL"
));
}
if global_ticks != cpu0_ticks_before {
errors.push(format!(
"line {line_number}: CPU1 IRQ must not mutate global CPU0 ticks"
));
}
if marker == "ASELSAN/G8G1" {
first_previous = previous;
first_next = next;
first_delta = delta;
} else {
second_previous = previous;
second_next = next;
second_delta = delta;
}
}
"ASELSAN/BOOT8G" => {
require_exact_keys(
&fields,
&field_order,
&[
"TIMER",
"CPU0_SLOT",
"CPU1_SLOT",
"ALIAS",
"INVALID_CPU",
"CPU0_FREQ",
"CPU1_FREQ",
"CPU0_PERIOD",
"CPU1_PERIOD",
"CPU0_START",
"CPU1_START",
"CPU0_NEXT_CVAL_BEFORE",
"CPU0_NEXT_CVAL_AFTER",
"CPU0_TICKS_BEFORE",
"CPU0_TICKS_AFTER",
"CPU0_CAPTURE_COUNT",
"CPU0_STATE_MUTATIONS",
"CPU1_IRQS",
"CPU1_DELIVERIES",
"CPU1_ACKS",
"CPU1_EOIS",
"DEADLINE_ADVANCES",
"DEADLINE_DELTA1",
"DEADLINE_DELTA2",
"CPU1_LOCAL_TICKS",
"THIRD_CHECK_COUNT",
"THIRD_IRQ",
"FINAL_TIMER",
"FINAL_IMASK",
"SCHED",
"TASK_RUNS",
"HEAP_OPS",
"UART_WRITES",
"SGI",
"MIGRATION",
"TLB_SHOOTDOWN",
"CPU2_3",
"SCOPE",
"BASE_TICKS",
"TICKS",
],
line_number,
&mut errors,
);
for (key, expected) in [
("TIMER", "PER_CPU"),
("CPU0_SLOT", "0"),
("CPU1_SLOT", "1"),
("ALIAS", "NO"),
("INVALID_CPU", "REJECT"),
("CPU0_STATE_MUTATIONS", "0"),
("CPU1_IRQS", "2"),
("CPU1_DELIVERIES", "2"),
("CPU1_ACKS", "2"),
("CPU1_EOIS", "2"),
("DEADLINE_ADVANCES", "2"),
("CPU1_LOCAL_TICKS", "2"),
("THIRD_IRQ", "NO"),
("FINAL_TIMER", "OFF"),
("FINAL_IMASK", "ON"),
("SCHED", "OFF"),
("TASK_RUNS", "0"),
("HEAP_OPS", "0"),
("UART_WRITES", "0"),
("SGI", "0"),
("MIGRATION", "OFF"),
("TLB_SHOOTDOWN", "OFF"),
("CPU2_3", "OFF"),
("SCOPE", "CPU1_PER_CPU_TIMER_ONLY"),
] {
require_field(&fields, key, expected, line_number, &mut errors);
}
let boot_cpu0_frequency =
parse_decimal(&fields, "CPU0_FREQ", line_number, &mut errors);
let boot_cpu1_frequency =
parse_decimal(&fields, "CPU1_FREQ", line_number, &mut errors);
let boot_cpu0_period =
parse_decimal(&fields, "CPU0_PERIOD", line_number, &mut errors);
let boot_cpu1_period =
parse_decimal(&fields, "CPU1_PERIOD", line_number, &mut errors);
let boot_cpu0_start =
parse_decimal(&fields, "CPU0_START", line_number, &mut errors);
let boot_cpu1_start =
parse_decimal(&fields, "CPU1_START", line_number, &mut errors);
let boot_cpu0_next_before =
parse_decimal(&fields, "CPU0_NEXT_CVAL_BEFORE", line_number, &mut errors);
cpu0_next_after =
parse_decimal(&fields, "CPU0_NEXT_CVAL_AFTER", line_number, &mut errors);
let boot_cpu0_ticks_before =
parse_decimal(&fields, "CPU0_TICKS_BEFORE", line_number, &mut errors);
cpu0_ticks_after =
parse_decimal(&fields, "CPU0_TICKS_AFTER", line_number, &mut errors);
let boot_cpu0_capture_count =
parse_decimal(&fields, "CPU0_CAPTURE_COUNT", line_number, &mut errors);
cpu1_deliveries =
parse_decimal(&fields, "CPU1_DELIVERIES", line_number, &mut errors);
cpu1_acks = parse_decimal(&fields, "CPU1_ACKS", line_number, &mut errors);
cpu1_eois = parse_decimal(&fields, "CPU1_EOIS", line_number, &mut errors);
cpu1_local_ticks =
parse_decimal(&fields, "CPU1_LOCAL_TICKS", line_number, &mut errors);
let deadline_advances =
parse_decimal(&fields, "DEADLINE_ADVANCES", line_number, &mut errors);
let boot_delta1 =
parse_decimal(&fields, "DEADLINE_DELTA1", line_number, &mut errors);
let boot_delta2 =
parse_decimal(&fields, "DEADLINE_DELTA2", line_number, &mut errors);
third_check_count =
parse_decimal(&fields, "THIRD_CHECK_COUNT", line_number, &mut errors);
boot_base = parse_decimal(&fields, "BASE_TICKS", line_number, &mut errors);
boot_ticks = parse_decimal(&fields, "TICKS", line_number, &mut errors);
for (name, left, right) in [
("CPU0_FREQ", cpu0_frequency, boot_cpu0_frequency),
("CPU1_FREQ", cpu1_frequency, boot_cpu1_frequency),
("CPU0_PERIOD", cpu0_period, boot_cpu0_period),
("CPU1_PERIOD", cpu1_period, boot_cpu1_period),
("CPU0_START", cpu0_start, boot_cpu0_start),
("CPU1_START", cpu1_start, boot_cpu1_start),
(
"CPU0_NEXT_CVAL_BEFORE",
cpu0_next_before,
boot_cpu0_next_before,
),
(
"CPU0_TICKS_BEFORE",
cpu0_ticks_before,
boot_cpu0_ticks_before,
),
(
"CPU0_CAPTURE_COUNT",
cpu0_capture_count,
boot_cpu0_capture_count,
),
("DEADLINE_DELTA1", first_delta, boot_delta1),
("DEADLINE_DELTA2", second_delta, boot_delta2),
] {
if left != right {
errors.push(format!(
"line {line_number}: {name} disagrees with prior G8g evidence: prior={left:?}, boot={right:?}"
));
}
}
if deadline_advances != Some(EXPECTED_DEADLINE_ADVANCES) {
errors.push(format!(
"line {line_number}: deadline advances must be exact {}",
EXPECTED_DEADLINE_ADVANCES
));
}
}
_ => unreachable!(),
}
}
for marker in MARKERS {
let observed = positions.get(marker).expect("known marker").len();
if observed != 1 {
errors.push(format!(
"{marker} must occur exactly once, observed {observed}"
));
}
}
let ordered = MARKERS
.iter()
.filter_map(|marker| positions.get(marker)?.first().copied())
.collect::<Vec<_>>();
if ordered.len() == MARKERS.len() && !ordered.windows(2).all(|pair| pair[0] < pair[1]) {
errors.push(format!("G8g marker order mismatch: {ordered:?}"));
}
if ordered.len() == MARKERS.len() && ordered.windows(2).all(|pair| pair[0] < pair[1]) {
let g8g0_line = ordered[0];
let boot8g_line = ordered[3];
for line_number in cpu0_tick_marker_lines
.iter()
.copied()
.filter(|line_number| g8g0_line < *line_number && *line_number < boot8g_line)
{
errors.push(format!(
"line {line_number}: CPU0 [SEC tick marker contradicts immutable G8g CPU0 state"
));
}
}
if let (Some(boot8f), Some(g8g0)) = (boot8f_line, ordered.first().copied()) {
if boot8f >= g8g0 {
errors.push(format!(
"BOOT8F must precede G8G0: BOOT8F@{boot8f}, G8G0@{g8g0}"
));
}
}
if cpu0_frequency.is_some_and(|value| value == 0)
|| cpu1_frequency.is_some_and(|value| value == 0)
|| cpu0_period.is_some_and(|value| value == 0)
|| cpu1_period.is_some_and(|value| value == 0)
{
errors.push("timer frequency and period must be nonzero".to_string());
}
if cpu0_frequency
.zip(cpu0_period)
.is_some_and(|(frequency, period)| frequency / TICK_HZ != period)
{
errors.push("CPU0 period must equal CPU0 frequency divided by TICK_HZ".to_string());
}
if cpu1_frequency
.zip(cpu1_period)
.is_some_and(|(frequency, period)| frequency / TICK_HZ != period)
{
errors.push("CPU1 period must equal CPU1 frequency divided by TICK_HZ".to_string());
}
if let (Some(cpu0_frequency), Some(cpu1_frequency)) = (cpu0_frequency, cpu1_frequency) {
if cpu0_frequency != cpu1_frequency {
errors.push(format!(
"CPU0_FREQ and CPU1_FREQ must describe the same system counter frequency: cpu0={cpu0_frequency}, cpu1={cpu1_frequency}"
));
}
}
if let (Some(cpu0_period), Some(cpu1_period)) = (cpu0_period, cpu1_period) {
if cpu0_period != cpu1_period {
errors.push(format!(
"CPU0_PERIOD and CPU1_PERIOD must be equal: cpu0={cpu0_period}, cpu1={cpu1_period}"
));
}
}
let (cpu0_last_processed, cpu0_expected_next) =
match (cpu0_start, cpu0_period, cpu0_ticks_before) {
(Some(start), Some(period), Some(ticks)) => {
let last_processed = last_processed_cval(start, period, ticks);
if last_processed.is_none() {
errors.push(
"CPU0 last-processed CVAL arithmetic is invalid or overflowed".to_string(),
);
}
let expected_next = expected_next_cval(start, period, ticks);
if expected_next.is_none() {
errors.push("CPU0 next-CVAL arithmetic is invalid or overflowed".to_string());
}
(last_processed, expected_next)
}
_ => (None, None),
};
if let (Some(next), Some(expected)) = (cpu0_next_before, cpu0_expected_next) {
if next != expected {
errors.push(
"CPU0_NEXT_CVAL must equal CPU0_START plus (CPU0_TICKS plus one) periods"
.to_string(),
);
}
}
if let (Some(capture), Some(cpu0_last_processed)) = (cpu0_capture_count, cpu0_last_processed) {
if capture < cpu0_last_processed {
errors.push(format!(
"CPU0_CAPTURE_COUNT must not precede CPU0's last processed deadline: capture={capture}, cpu0_last_processed={cpu0_last_processed}"
));
}
}
if let (Some(cpu1_start), Some(capture)) = (cpu1_start, cpu0_capture_count) {
if cpu1_start <= capture {
errors.push(format!(
"CPU1_START must be greater than CPU0_CAPTURE_COUNT: cpu1_start={cpu1_start}, capture={capture}"
));
}
}
if let (Some(g8f), Some(period)) = (g8f.as_ref(), cpu0_period) {
let g8b = &g8f.g8e.g8d.g8c.g8b;
if period != g8b.timer_period {
errors.push(format!(
"G8g CPU0 period must equal G8b timer period: g8g={period}, g8b={}",
g8b.timer_period
));
}
if let Some(start) = cpu0_start {
let g8b_last = last_processed_cval(start, period, g8b.start_ticks);
match g8b_last {
Some(last) if g8b.timer_start_count < last => errors.push(format!(
"G8b timer start count precedes the CPU0 deadline at G8b release: start_count={}, deadline={last}",
g8b.timer_start_count
)),
Some(_) => {}
None => errors.push(
"G8b release-deadline arithmetic is invalid or overflowed".to_string(),
),
}
}
if let Some(capture) = cpu0_capture_count {
if g8b.timer_fired_count > capture {
errors.push(format!(
"CPU0_CAPTURE_COUNT must not precede G8b timer fired count: capture={capture}, fired={}",
g8b.timer_fired_count
));
}
}
}
if first_previous != cpu1_first_cval {
errors.push(format!(
"G8G1 PREV_CVAL must equal CPU1_FIRST_CVAL: first={cpu1_first_cval:?}, previous={first_previous:?}"
));
}
if second_previous != first_next {
errors.push(format!(
"G8G2 PREV_CVAL must equal G8G1 NEXT_CVAL: first_next={first_next:?}, second_previous={second_previous:?}"
));
}
if first_delta != cpu1_period || second_delta != cpu1_period {
errors.push(format!(
"each CPU1 deadline delta must equal exactly one period: period={cpu1_period:?}, first={first_delta:?}, second={second_delta:?}"
));
}
if let (Some(check), Some(second_next), Some(period)) =
(third_check_count, second_next, cpu1_period)
{
match check.checked_sub(second_next) {
Some(delta) => {
third_check_delta = Some(delta);
match period.checked_mul(THIRD_CHECK_MAX_PERIODS) {
Some(window) if delta < window => {}
Some(window) => errors.push(format!(
"THIRD_CHECK_COUNT must be less than {THIRD_CHECK_MAX_PERIODS} CPU1 period after G8G2 NEXT_CVAL: delta={delta}, window={window}"
)),
None => errors.push(
"third-IRQ check window arithmetic overflowed".to_string(),
),
}
}
None => errors.push(format!(
"THIRD_CHECK_COUNT must not precede G8G2 NEXT_CVAL: check={check}, next={second_next}"
)),
}
}
if cpu0_next_before != cpu0_next_after
|| cpu0_ticks_before != cpu0_ticks_after
|| boot_base != cpu0_ticks_before
|| boot_ticks != cpu0_ticks_after
{
errors.push(format!(
"CPU0 compatibility state changed during G8g: next_before={cpu0_next_before:?}, next_after={cpu0_next_after:?}, ticks_before={cpu0_ticks_before:?}, ticks_after={cpu0_ticks_after:?}, base={boot_base:?}, ticks={boot_ticks:?}"
));
}
if g8f
.as_ref()
.zip(cpu0_ticks_before)
.is_some_and(|(g8f, ticks)| ticks != g8f.boot8f_ticks)
{
errors.push(format!(
"G8g CPU0 start ticks must equal BOOT8F ticks: boot8f={:?}, start={cpu0_ticks_before:?}",
g8f.as_ref().map(|evidence| evidence.boot8f_ticks),
));
}
if TARGET_CPU_INDEX != 1
|| TARGET_MPIDR != 0x100
|| TIMER_PPI != 27
|| MAX_CPU_INDEX != 4
|| SLOT_CPU0 != 0
|| SLOT_CPU1 != 1
|| SLOT_CPU0 == SLOT_CPU1
|| EXPECTED_CPU1_DELIVERIES != 2
|| EXPECTED_CPU1_ACKS != 2
|| EXPECTED_CPU1_EOIS != 2
|| EXPECTED_DEADLINE_ADVANCES != 2
|| EXPECTED_CPU1_TICKS != 2
|| EXPECTED_THIRD_IRQS != 0
|| MAX_STAGE_PERIODS != 100
|| THIRD_CHECK_MAX_PERIODS != 1
|| EXPECTED_CPU0_STATE_MUTATIONS != 0
|| EXPECTED_CPU1_SGI != 0
|| EXPECTED_CPU1_RESCHEDULES != 0
|| EXPECTED_CPU1_TASK_RUNS != 0
|| EXPECTED_CPU1_HEAP_OPS != 0
|| EXPECTED_CPU1_UART_WRITES != 0
|| crate::g8g_contract::timer_slot(MAX_CPU_INDEX).is_some()
|| crate::g8g_contract::timer_slot(usize::MAX).is_some()
{
errors.push("compiled G8g contract constants are inconsistent".to_string());
}
if cpu1_deliveries != Some(EXPECTED_CPU1_DELIVERIES)
|| cpu1_acks != Some(EXPECTED_CPU1_ACKS)
|| cpu1_eois != Some(EXPECTED_CPU1_EOIS)
|| cpu1_local_ticks != Some(EXPECTED_CPU1_TICKS)
{
errors.push(format!(
"G8g CPU1 counts must be exact 2/2/2/2: deliveries={cpu1_deliveries:?}, acks={cpu1_acks:?}, eois={cpu1_eois:?}, ticks={cpu1_local_ticks:?}"
));
}
if errors.is_empty() {
Ok(G8gEvidence {
g8f: g8f.expect("validated G8f prerequisite"),
cpu0_frequency: cpu0_frequency.expect("validated CPU0 frequency"),
cpu1_frequency: cpu1_frequency.expect("validated CPU1 frequency"),
cpu0_period: cpu0_period.expect("validated CPU0 period"),
cpu1_period: cpu1_period.expect("validated CPU1 period"),
cpu0_capture_count: cpu0_capture_count.expect("validated CPU0 capture count"),
cpu0_ticks_before: cpu0_ticks_before.expect("validated CPU0 ticks before"),
cpu0_ticks_after: cpu0_ticks_after.expect("validated CPU0 ticks after"),
cpu1_local_ticks: cpu1_local_ticks.expect("validated CPU1 local ticks"),
cpu1_deliveries: cpu1_deliveries.expect("validated CPU1 deliveries"),
cpu1_acks: cpu1_acks.expect("validated CPU1 acknowledgements"),
cpu1_eois: cpu1_eois.expect("validated CPU1 EOIs"),
first_deadline_delta: first_delta.expect("validated first deadline delta"),
second_deadline_delta: second_delta.expect("validated second deadline delta"),
third_check_count: third_check_count.expect("validated third-IRQ check count"),
third_check_delta: third_check_delta.expect("validated third-IRQ check delta"),
})
} else {
Err(ValidationError { messages: errors })
}
}snippet sha256: b9633ea70451…file sha256: 86989a92613f…
02 · Doğrulayan test kodu
Operations komutuna bağlı focused test
tam Rust öğesiL259–L523
simulation/tests/rpi5_g8g_uart.rs::absolute_deadline_arithmetic_frequency_and_period_fail_closed
#[test]
fn absolute_deadline_arithmetic_frequency_and_period_fail_closed() {
for (from, to, needle) in [
(
"CPU1_FIRST_CVAL=603540100",
"CPU1_FIRST_CVAL=603540101",
"CPU1_FIRST_CVAL must equal",
),
(
"NEXT_CVAL=604080100 DELTA=540000",
"NEXT_CVAL=604080101 DELTA=540000",
"NEXT_CVAL minus PREV_CVAL",
),
(
"NEXT_CVAL=604620100 DELTA=540000",
"NEXT_CVAL=604620100 DELTA=539999",
"DELTA must equal PERIOD",
),
(
"FIRED_COUNT=603540200",
"FIRED_COUNT=603540099",
"timer fired before its absolute deadline",
),
("CPU0_FREQ=54000000", "CPU0_FREQ=0", "nonzero"),
("CPU1_FREQ=54000000", "CPU1_FREQ=0", "nonzero"),
(
"CPU0_PERIOD=540000",
"CPU0_PERIOD=539999",
"CPU0 period must equal",
),
(
"CPU1_PERIOD=540000",
"CPU1_PERIOD=539999",
"CPU1 period must equal",
),
(
"DEADLINE_DELTA1=540000",
"DEADLINE_DELTA1=539999",
"disagrees with prior G8g evidence",
),
] {
let messages = failures(replace_suffix(from, to));
assert!(has(&messages, needle), "{from}->{to}: {messages:?}");
}
let split_system_counter = failures(replace_suffix_many(&[
("CPU1_FREQ=54000000", "CPU1_FREQ=55000000"),
("CPU1_FREQ=54000000", "CPU1_FREQ=55000000"),
("CPU1_PERIOD=540000", "CPU1_PERIOD=550000"),
("CPU1_PERIOD=540000", "CPU1_PERIOD=550000"),
]));
assert!(
has(
&split_system_counter,
"CPU0_FREQ and CPU1_FREQ must describe the same system counter frequency"
) && has(
&split_system_counter,
"CPU0_PERIOD and CPU1_PERIOD must be equal"
),
"coordinated CPU1 frequency/period mutation passed: {split_system_counter:?}"
);
let prior_period_mismatch =
failures(replace_suffix("CPU0_PERIOD=540000", "CPU0_PERIOD=539999"));
assert!(
has(
&prior_period_mismatch,
"G8g CPU0 period must equal G8b timer period"
),
"G8g CPU0 period escaped its G8b binding: {prior_period_mismatch:?}"
);
let prior_start_regression = failures(replace_pass_many(&[
("START_COUNT=378000000", "START_COUNT=377999999"),
("DEADLINE=380700000", "DEADLINE=380699999"),
("FIRED_COUNT=380700100", "FIRED_COUNT=380700099"),
]));
assert!(
has(
&prior_start_regression,
"G8b timer start count precedes the CPU0 deadline at G8b release"
),
"coordinated G8b start/deadline regression escaped the CPU0 timeline: {prior_start_regression:?}"
);
let prior_fired_after_capture = failures(replace_pass_many(&[(
"FIRED_COUNT=380700100",
"FIRED_COUNT=603000001",
)]));
assert!(
has(
&prior_fired_after_capture,
"CPU0_CAPTURE_COUNT must not precede G8b timer fired count"
),
"G8b fired count after the G8g capture escaped chronology: {prior_fired_after_capture:?}"
);
let first_boundary = failures(replace_suffix_many(&[
("PREV_CVAL=603540100", "PREV_CVAL=703540100"),
("NEXT_CVAL=604080100", "NEXT_CVAL=704080100"),
("FIRED_COUNT=603540200", "FIRED_COUNT=703540200"),
("PREV_CVAL=604080100", "PREV_CVAL=704080100"),
("NEXT_CVAL=604620100", "NEXT_CVAL=704620100"),
("FIRED_COUNT=604080220", "FIRED_COUNT=704080220"),
]));
assert!(
has(&first_boundary, "G8G1 PREV_CVAL must equal CPU1_FIRST_CVAL"),
"shifted first deadline chain passed: {first_boundary:?}"
);
let second_boundary = failures(replace_suffix_many(&[
("PREV_CVAL=604080100", "PREV_CVAL=704080100"),
("NEXT_CVAL=604620100", "NEXT_CVAL=704620100"),
("FIRED_COUNT=604080220", "FIRED_COUNT=704080220"),
]));
assert!(
has(&second_boundary, "G8G2 PREV_CVAL must equal G8G1 NEXT_CVAL"),
"discontinuous second deadline passed: {second_boundary:?}"
);
let impossible_old_cpu1_timeline = failures(replace_suffix_many(&[
("CPU1_START=603000100", "CPU1_START=594540000"),
("CPU1_FIRST_CVAL=603540100", "CPU1_FIRST_CVAL=595080000"),
("PREV_CVAL=603540100", "PREV_CVAL=595080000"),
("NEXT_CVAL=604080100", "NEXT_CVAL=595620000"),
("FIRED_COUNT=603540200", "FIRED_COUNT=595080100"),
("PREV_CVAL=604080100", "PREV_CVAL=595620000"),
("NEXT_CVAL=604620100", "NEXT_CVAL=596160000"),
("FIRED_COUNT=604080220", "FIRED_COUNT=595620120"),
("CPU1_START=603000100", "CPU1_START=594540000"),
]));
assert!(
has(
&impossible_old_cpu1_timeline,
"CPU1_START must be greater than CPU0_CAPTURE_COUNT"
),
"internally coordinated but time-regressed CPU1 chain passed: {impossible_old_cpu1_timeline:?}"
);
let impossible_legacy_cpu0_chain = failures(replace_suffix_many(&[
("CPU0_NEXT_CVAL=595080000", "CPU0_NEXT_CVAL=540540000"),
(
"CPU0_NEXT_CVAL_BEFORE=595080000",
"CPU0_NEXT_CVAL_BEFORE=540540000",
),
(
"CPU0_NEXT_CVAL_AFTER=595080000",
"CPU0_NEXT_CVAL_AFTER=540540000",
),
]));
assert!(
has(
&impossible_legacy_cpu0_chain,
"CPU0_NEXT_CVAL must equal CPU0_START plus (CPU0_TICKS plus one) periods"
),
"historical one-period CPU0 chain passed: {impossible_legacy_cpu0_chain:?}"
);
let coordinated_cpu0_origin_lie = failures(replace_suffix_many(&[
("CPU0_START=0", "CPU0_START=540000000"),
("CPU0_START=0", "CPU0_START=540000000"),
]));
assert!(
has(
&coordinated_cpu0_origin_lie,
"G8b timer start count precedes the CPU0 deadline at G8b release"
),
"coordinated CPU0_START=540000000 timeline lie escaped G8b binding: {coordinated_cpu0_origin_lie:?}"
);
let coordinated_tick_and_cval_shift = failures(replace_suffix_many(&[
("CPU0_NEXT_CVAL=595080000", "CPU0_NEXT_CVAL=595620000"),
(
"CPU0_NEXT_CVAL_BEFORE=595080000",
"CPU0_NEXT_CVAL_BEFORE=595620000",
),
(
"CPU0_NEXT_CVAL_AFTER=595080000",
"CPU0_NEXT_CVAL_AFTER=595620000",
),
("CPU0_TICKS=1101", "CPU0_TICKS=1102"),
("START_TICKS=1101", "START_TICKS=1102"),
("CPU0_TICKS_BEFORE=1101", "CPU0_TICKS_BEFORE=1102"),
("CPU0_TICKS_AFTER=1101", "CPU0_TICKS_AFTER=1102"),
("BASE_TICKS=1101", "BASE_TICKS=1102"),
(" TICKS=1101", " TICKS=1102"),
]));
assert!(
has(
&coordinated_tick_and_cval_shift,
"G8g CPU0 start ticks must equal BOOT8F ticks"
),
"coordinated CPU0 tick/CVAL mutation escaped BOOT8F binding: {coordinated_tick_and_cval_shift:?}"
);
let tick_successor_overflow = failures(replace_suffix(
"CPU0_TICKS=1101",
"CPU0_TICKS=18446744073709551615",
));
assert!(
has(
&tick_successor_overflow,
"CPU0 next-CVAL arithmetic is invalid or overflowed"
),
"CPU0 tick-successor overflow passed: {tick_successor_overflow:?}"
);
let elapsed_count_overflow = failures(replace_suffix(
"CPU0_TICKS=1101",
"CPU0_TICKS=18446744073709551614",
));
assert!(
has(
&elapsed_count_overflow,
"CPU0 last-processed CVAL arithmetic is invalid or overflowed"
) && has(
&elapsed_count_overflow,
"CPU0 next-CVAL arithmetic is invalid or overflowed"
),
"CPU0 elapsed-count multiplication overflow passed: {elapsed_count_overflow:?}"
);
let deadline_add_overflow = failures(replace_suffix(
"CPU0_START=0",
"CPU0_START=18446744073709551615",
));
assert!(
has(
&deadline_add_overflow,
"CPU0 last-processed CVAL arithmetic is invalid or overflowed"
) && has(
&deadline_add_overflow,
"CPU0 next-CVAL arithmetic is invalid or overflowed"
),
"CPU0 next-CVAL addition overflow passed: {deadline_add_overflow:?}"
);
let non_decimal_drift = failures(replace_suffix("DRIFT_COUNTS=100", "DRIFT_COUNTS=invalid"));
assert!(
has(&non_decimal_drift, "DRIFT_COUNTS must be unsigned decimal"),
"non-decimal drift passed: {non_decimal_drift:?}"
);
let inconsistent_drift = failures(replace_suffix("DRIFT_COUNTS=100", "DRIFT_COUNTS=99"));
assert!(
has(
&inconsistent_drift,
"DRIFT_COUNTS must equal FIRED_COUNT minus PREV_CVAL"
),
"inconsistent drift passed: {inconsistent_drift:?}"
);
let missed_next_deadline = failures(replace_suffix_many(&[
("FIRED_COUNT=603540200", "FIRED_COUNT=604080100"),
("DRIFT_COUNTS=100", "DRIFT_COUNTS=540000"),
]));
assert!(
has(
&missed_next_deadline,
"FIRED_COUNT must be less than NEXT_CVAL"
),
"one-period drift bound bypassed: {missed_next_deadline:?}"
);
}snippet sha256: 62e2822cca07…file sha256: 2c00c3dc2c65…
03 · Kapı kimlik kaydı
Operations sıra, kimlik ve başlık bağı
tam Operations kaydıL29683–L29771
website/src/lib/operations.ts::rpi5-g8g-contract-parser-runtime-stop
{
id: "rpi5-g8g-contract-parser-runtime-stop",
date: "2026-08-21",
sequence: 81,
status: "partial",
title: "G8g per-CPU periodic timer sözleşmesi yeşil; runtime bilinçli STOP",
summary:
"Sıra 80 fiziksel BOOT8F kabulünden sonraki ilk fail-closed kapı başlatıldı. G8g allocation-free contract, strict G8f-prerequisite UART validator, canonical G8G0/G8G1/G8G2/BOOT8G sentetik suffix'i, adversarial test matrisi ve CLI validator oluşturuldu. Sözleşme CPU0 slot 0 ile CPU1 slot 1'i ayırır; geçersiz CPU kimliğinin modulo, clamp, default veya fallback ile CPU0'a alias edilmesini reddeder. CPU1 için exact iki local PPI27 delivery/ack/EOI ve birbirine bağlı iki exact-period absolute-CVAL advance zorunludur; drift fired-count'tan türetilir ve bir sonraki deadline'ın altında kalır. Üçüncü IRQ yasak, final timer off+masked ve CPU0 next-CVAL/tick görünümü değişmemiş olmalıdır. UART/adversarial 9/9, source-boundary 4/4, tam simulation 197/197 ve CLI check PASS verdi. Runtime bilerek eklenmedi: per-CPU timer storage, G8f→G8g handoff seam'leri, IRQ interceptor, layout, image, microSD ve fiziksel BOOT8G henüz yoktur.",
evidence: [
"Immutable prerequisite Sequence 80 raw'ıdır: 17.363 B / e70e1a9a2cf35f9079ee1b1a73d992106bf5ee9a19f1bbf2628582e836ea5068, direct validator PASS ve SCOPE=QUIESCENT_ATOMIC_HANDOFF_ONLY.",
"Allocation-free G8g contract exact 3.283 B / b99f4fbba8f8b3ae18647f027317965b127a635d98951a03817ce40148a3bf14 olarak donduruldu.",
"Strict G8g validator exact 29.181 B / 9db90d47e2fab66c2a7a428c10e70a1a928a47c0783fe838cef76977024ce978.",
"Canonical sentetik suffix exact 4 satır, 1.664 B / 3b7f01f332674ad5c6d9dd591c465d8627ac19d3c469ea84fb8ec88db890f8c3; fiziksel UART capture değildir.",
"Marker sözleşmesi exact G8G0→G8G1→G8G2→BOOT8G; duplicate, missing, reorder, unknown marker, extra/duplicate field, field-order, UTF-8 ve non-leading NUL sapmaları fail-closed reddedilir.",
"CPU0_SLOT=0, CPU1_SLOT=1, SLOTS=4, ALIAS=NO ve INVALID_CPU=REJECT exact zorunludur; timer_slot(MAX_CPU_INDEX) ve timer_slot(usize::MAX) None verir.",
"CPU1 PPI27 delivery/ack/EOI/local-tick exact 2/2/2/2; DEADLINE_ADVANCES=2 ve iki deadline delta exact bir period 540000'dir.",
"Absolute-CVAL zinciri fail-closed bağlıdır: G8G0 CPU1_FIRST_CVAL, G8G1 PREV/NEXT ve G8G2 PREV birbirinin devamıdır; DRIFT_COUNTS=FIRED_COUNT−PREV_CVAL ve FIRED_COUNT<NEXT_CVAL zorunludur.",
"CPU0 next-CVAL before/after 540540000/540540000, START+PERIOD aritmetiğine bağlıdır; historical ticks before/after 1101/1101 ve CPU0_STATE_MUTATIONS=0'dır.",
"Final CPU1 timer OFF, IMASK ON, THIRD_IRQ=NO; scheduler/task/heap/CPU1 UART/SGI/migration/TLBI/CPU2_3 kapalıdır.",
"G8g UART/adversarial testleri 9/9, source-boundary testleri 4/4 ve tam simulation matrisi 197/197 PASS; `verify_rpi5_g8g_log` example cargo check PASS.",
"Synthetic validator exact `G8g PASS: cpu0_slot=0 cpu1_slot=1 cpu1_irqs=2 acks=2 eois=2 local_ticks=2 deadline_deltas=540000/540000 cpu0_mutations=0 final_timer=off+masked boot8g_tick=1101` çıktısını verdi.",
"Yeni `make verify-rpi5-g8g-contract` hedefi G8f UART regresyonunu, G8g source/UART testlerini ve CLI validator check'ini birlikte çalıştırır.",
"Staged proof exact 4.700 B / a29446b796cda45d4a76cde81ce8dc250febfbf1f64cbd0b096afa1ee8fc20e2; güncellenmiş SMP roadmap exact 13.817 B / 141597ef9c4623d343637e9ac4123dc84440b781867de4747fa0f7925b93cfbf.",
],
terminalSessionsNote:
"Oturumlar yalnız contract/parser ve mevcut-source STOP sınırını gösterir. Sentetik PASS, runtime veya fiziksel BOOT8G kabulü değildir.",
terminalSessions: [
{
id: "g8g-contract-adversarial-green",
title:
"G8g allocation-free contract ve strict adversarial UART validator",
commandLines: [
"cargo test -p aselsan_microkernel_simulation --test rpi5_g8g_uart",
"cargo test -p aselsan_microkernel_simulation --test rpi5_g8g_source",
"cargo check -p aselsan_microkernel_simulation --example verify_rpi5_g8g_log",
"rustfmt --edition 2021 --check <G8g Rust files>",
],
outputLines: [
"rpi5_g8g_uart=9/9 PASS",
"rpi5_g8g_source=4/4 PASS",
"absolute-CVAL chain, CPU0 START+PERIOD and drift bounds=PASS",
"full simulation matrix=197/197 PASS",
"verify_rpi5_g8g_log cargo_check_exit=0",
"targeted rustfmt_check_exit=0",
],
exitCode: 0,
outputMode: "complete",
},
{
id: "g8g-synthetic-validator",
title: "BOOT8F prerequisite ile canonical G8g sentetik zinciri",
commandLines: [
"concatenate G8 through G8g canonical fixtures",
"cargo run --quiet -p aselsan_microkernel_simulation --example verify_rpi5_g8g_log -- <combined.log>",
],
outputLines: [
"combined synthetic transcript=68 lines / 9588 B",
"cpu0_slot=0 cpu1_slot=1 · cpu1_irqs/acks/eois/local_ticks=2/2/2/2",
"deadline_deltas=540000/540000 · cpu0_mutations=0",
"final_timer=off+masked · boot8g_tick=1101 · exit=0",
],
exitCode: 0,
outputMode: "complete",
},
{
id: "g8g-runtime-intentional-stop",
title: "Mevcut global timer baseline ve bilinçli eksik runtime sınırı",
commandLines: [
"inspect kernel timer globals, main module wiring, G8f terminal path and IRQ dispatcher",
"verify G8g runtime/module/interceptor/per-CPU storage are absent",
],
outputLines: [
"current baseline=PERIOD_TICKS/FREQ_HZ/START_COUNT/NEXT_CVAL global atomics",
"kernel/src/rpi5_g8g.rs=ABSENT",
"G8f→G8g CPU0/CPU1 seam=ABSENT · IRQ interceptor=ABSENT",
"runtime/layout/image/microSD/physical BOOT8G=STOP",
],
exitCode: 0,
outputMode: "selected",
},
],
limitations: [
"Bu kayıt contract, sentetik fixture ve host validator kanıtıdır; G8g runtime, layout, image veya fiziksel BOOT8G PASS değildir.",
"`kernel/src/rpi5_g8g.rs`, per-CPU timer storage/API, G8f→G8g handoff seam'leri ve IRQ interceptor henüz yoktur.",
"Yeni image/package üretilmedi; microSD yazılmadı, UART capture yapılmadı ve fiziksel karta dokunulmadı.",
"Generic SMP, CPU1 static preemption, per-CPU runqueue, migration, ASID/TLBI shootdown, CPU2/CPU3, soak ve hotplug kapalıdır.",
"Production deployment dirty/untracked workspace ve stale 47d22c9 source etiketiyle yapılır; canlı artifact doğrulansa da Git-provider provenance kurulmuş sayılmaz.",
],
},snippet sha256: 500167615ba6…file sha256: 9726dbf00f84…
Focused test komutu
cargo test -p aselsan_microkernel_simulation --test rpi5_g8g_uartRegistry schema v5 · generator
website/scripts/generate-code-gates.mjs · Tam SHA-256: 91d38c7b6222f0b4c117be786454853543da55a160e543d9b951057cc20dcc06