nx_etg_probe_cpu.nx source
↩ module page · 336 lines · 11120 B
1// nx_etg_probe_cpu.nx -- E3 first real CPU-tier ETG probe.
2//
3// Bridges the pre-existing nx_calibrate.nx CPU measurements (SA-2
4// shipped) into the ETG framework (E1 NxEtgEntry attestation + E2
5// tournament selector). First REAL silicon probe in the substrate.
6//
7// Two surfaces:
8//
9// 1. nx_etg_classify_outcome(claim, measured, low_thresh_per_1000,
10// high_thresh_per_1000) -> i64
11// Universal classifier: given a vendor CLAIM value and an
12// empirical MEASURED value, classifies the outcome per the
13// 11-value NX_ETG_OUTCOME_* taxonomy. Used by every per-tier
14// probe (CPU / GPU / NVMe / network). Permilles (per-1000)
15// keep the math integer.
16//
17// 2. nx_etg_probe_cpu_syscall_roundtrip(claim_ns, low_thresh_per_1000,
18// high_thresh_per_1000, entry,
19// silicon_serial, selector_version,
20// timestamp_q14) -> i64
21// Runs nx_calibrate_run, extracts the syscall_ns_clock_gettime
22// measurement, classifies vs claim, emits an NxEtgEntry. Returns
23// the outcome (or negative on error).
24//
25// Composes:
26// [[NISHI_ETG_ROADMAP]] E3 (this is the first real probe)
27// nx_etg.nx (E1 NxEtgEntry attestation; SHIPPED)
28// nx_calibrate.nx (SA-2 CPU calibration; SHIPPED) -- the EMPIRICAL
29// MEASUREMENT layer this probe wraps in ETG semantics
30// [[NISHI_SELF_ASSEMBLY_ROADMAP]] SA-2 (prior art being lifted up)
31// [[feedback-physical-truth-over-published-docs-silicon-empirical-gamification]]
32// (cardinal: vendor claim is HYPOTHESIS, calibration measurement
33// is TRUTH; classifier records which side told the truth)
34//
35// Outcome classification rules:
36// measured == 0 || claim == 0 => INCONCLUSIVE (no comparison possible)
37// measured > claim * (1 + high/1000) => FALSIFIED (silicon worse than claimed)
38// measured < claim * (1 - low/1000) => VENDOR_LIED_OMISSION (better than claimed)
39// otherwise => CONFIRMED (within tolerance)
40//
41// Why permille thresholds: simple integer math; 100/1000 = 10% is a
42// reasonable default tolerance for syscall timings.
43
44// nx_safety_envelope:
45// intended_use: "first real CPU-tier ETG probe; bridges
46// nx_calibrate empirical measurements into
47// ETG NxEtgEntry attestations; demonstrates
48// end-to-end E1+E2+E3 wiring"
49// sil_target: SIL2
50// evidence: [kat_classifier_taxonomy_complete,
51// kat_classifier_boundaries_correct,
52// kat_real_calibration_emits_valid_entry]
53// hazard_register: [bug-tape-permille-overflow-on-large-claim,
54// bug-tape-divide-by-zero-claim,
55// bug-tape-measurement-noise-misclassified]
56// verdict: NOT_YET_EVALUATED
57
58import "nx_syscalls.nx"
59import "nx_calibrate.nx"
60import "nx_etg.nx"
61
62// ===== Outcome classifier =========================================
63//
64// Permille thresholds (per-1000) keep math integer:
65// low_thresh_per_1000 = 100 => 10% lower tolerance
66// high_thresh_per_1000 = 100 => 10% upper tolerance
67//
68// Returns NX_ETG_OUTCOME_*.
69
70func nx_etg_classify_outcome(
71 claim: i64,
72 measured: i64,
73 low_thresh_per_1000: i64,
74 high_thresh_per_1000: i64
75) -> i64 {
76 if claim == 0 { return NX_ETG_OUTCOME_INCONCLUSIVE }
77 if measured == 0 { return NX_ETG_OUTCOME_INCONCLUSIVE }
78
79 // upper bound: claim * (1 + high/1000) = (claim * (1000 + high)) / 1000
80 let upper: i64 = (claim * (1000 + high_thresh_per_1000)) / 1000
81 if measured > upper { return NX_ETG_OUTCOME_FALSIFIED }
82
83 // lower bound: claim * (1 - low/1000) = (claim * (1000 - low)) / 1000
84 let lower: i64 = (claim * (1000 - low_thresh_per_1000)) / 1000
85 if measured < lower { return NX_ETG_OUTCOME_VENDOR_LIED_OMISSION }
86
87 return NX_ETG_OUTCOME_CONFIRMED
88}
89
90// ===== Real CPU syscall-roundtrip probe ===========================
91//
92// Runs nx_calibrate_run + classifies syscall_ns_clock_gettime vs
93// the vendor claim + emits an NxEtgEntry. Returns the outcome on
94// success, or a negative value on error.
95//
96// This is the FIRST REAL silicon-side ETG probe. The substrate
97// measures what THIS die actually does for a clock_gettime syscall,
98// then records the verdict against whatever the docs / driver claim.
99
100func nx_etg_probe_cpu_syscall_roundtrip(
101 claim_ns: i64,
102 low_thresh_per_1000: i64,
103 high_thresh_per_1000: i64,
104 entry: *NxEtgEntry,
105 silicon_serial: i64,
106 selector_version: i64,
107 timestamp_q14: i64
108) -> i64 {
109 let cal: *NxCalibrationRecord = nx_calibrate_new()
110 let rc: i64 = nx_calibrate_run(cal)
111 if rc != 0 { return -10 }
112
113 let measured: i64 = cal.syscall_ns_clock_gettime
114 let outcome: i64 = nx_etg_classify_outcome(
115 claim_ns, measured, low_thresh_per_1000, high_thresh_per_1000
116 )
117
118 let rc_attest: i64 = nx_etg_entry_init(
119 entry,
120 silicon_serial,
121 NX_ETG_PROBE_CPU_SYSCALL,
122 NX_ETG_CLAIM_VENDOR_DOC,
123 claim_ns,
124 measured,
125 outcome,
126 selector_version,
127 timestamp_q14
128 )
129 if rc_attest != 0 { return -20 }
130
131 return outcome
132}
133
134// ===== Real CPU int_alu dependent-chain probe =====================
135//
136// Composes nx_calibrate's int_alu_ps_per_op measurement: a dependent-
137// chain ADD throughput in picoseconds per op. The vendor "claim"
138// for picosecond-per-op is rarely published; this probe primarily
139// records measurement for downstream conductor cost-model use, and
140// the classifier verifies it sits in a plausible band when a claim
141// is provided.
142//
143// probe_kind: NX_ETG_PROBE_CPU_ISA (closest taxonomy slot --
144// dependent-chain ALU throughput characterizes the ISA's int-add unit).
145
146func nx_etg_probe_cpu_int_alu(
147 claim_ps_per_op: i64,
148 low_thresh_per_1000: i64,
149 high_thresh_per_1000: i64,
150 entry: *NxEtgEntry,
151 silicon_serial: i64,
152 selector_version: i64,
153 timestamp_q14: i64
154) -> i64 {
155 let cal: *NxCalibrationRecord = nx_calibrate_new()
156 let rc: i64 = nx_calibrate_run(cal)
157 if rc != 0 { return -10 }
158
159 let measured: i64 = cal.int_alu_ps_per_op
160 let outcome: i64 = nx_etg_classify_outcome(
161 claim_ps_per_op, measured, low_thresh_per_1000, high_thresh_per_1000
162 )
163
164 let rc_attest: i64 = nx_etg_entry_init(
165 entry,
166 silicon_serial,
167 NX_ETG_PROBE_CPU_ISA,
168 NX_ETG_CLAIM_VENDOR_DOC,
169 claim_ps_per_op,
170 measured,
171 outcome,
172 selector_version,
173 timestamp_q14
174 )
175 if rc_attest != 0 { return -20 }
176
177 return outcome
178}
179
180// ===== Real CPU mem-bandwidth probe ===============================
181//
182// Composes nx_calibrate's mem_bw_mib_per_s measurement: linear-copy
183// memory bandwidth in MiB/s. Critical for conductor scheduling:
184// vendor RAM datasheets routinely overstate sustainable bandwidth
185// because their numbers assume ideal DIMM topology + zero contention.
186//
187// probe_kind: NX_ETG_PROBE_STORAGE_RAM (RAM is a storage tier in the
188// per-tier catalog).
189
190func nx_etg_probe_cpu_mem_bw(
191 claim_mib_per_s: i64,
192 low_thresh_per_1000: i64,
193 high_thresh_per_1000: i64,
194 entry: *NxEtgEntry,
195 silicon_serial: i64,
196 selector_version: i64,
197 timestamp_q14: i64
198) -> i64 {
199 let cal: *NxCalibrationRecord = nx_calibrate_new()
200 let rc: i64 = nx_calibrate_run(cal)
201 if rc != 0 { return -10 }
202
203 let measured: i64 = cal.mem_bw_mib_per_s
204 let outcome: i64 = nx_etg_classify_outcome(
205 claim_mib_per_s, measured, low_thresh_per_1000, high_thresh_per_1000
206 )
207
208 let rc_attest: i64 = nx_etg_entry_init(
209 entry,
210 silicon_serial,
211 NX_ETG_PROBE_STORAGE_RAM,
212 NX_ETG_CLAIM_VENDOR_DOC,
213 claim_mib_per_s,
214 measured,
215 outcome,
216 selector_version,
217 timestamp_q14
218 )
219 if rc_attest != 0 { return -20 }
220
221 return outcome
222}
223
224// ===== Real CPU cache-hierarchy probes ============================
225//
226// nx_calibrate already measures L1 / L2 / RAM access latency in ns
227// across 4 KiB / 256 KiB / 16 MiB working sets respectively.
228// Three probes wire each tier into the ETG framework. Vendor
229// datasheets typically publish "L1 hit latency ~4 cycles" but
230// per-die actual latency varies with: silicon binning, ambient
231// thermal, BIOS RAPL throttling, hyperthread contention, prefetcher
232// state, page-walk overhead, replacement-policy variant (LRU vs
233// RRIP vs DRRIP). ETG records the empirical truth per silicon
234// serial.
235
236func nx_etg_probe_cpu_cache_l1(
237 claim_ns: i64,
238 low_thresh_per_1000: i64,
239 high_thresh_per_1000: i64,
240 entry: *NxEtgEntry,
241 silicon_serial: i64,
242 selector_version: i64,
243 timestamp_q14: i64
244) -> i64 {
245 let cal: *NxCalibrationRecord = nx_calibrate_new()
246 let rc: i64 = nx_calibrate_run(cal)
247 if rc != 0 { return -10 }
248
249 let measured: i64 = cal.mem_ns_per_access_l1
250 let outcome: i64 = nx_etg_classify_outcome(
251 claim_ns, measured, low_thresh_per_1000, high_thresh_per_1000
252 )
253
254 let rc_attest: i64 = nx_etg_entry_init(
255 entry,
256 silicon_serial,
257 NX_ETG_PROBE_CPU_CACHE,
258 NX_ETG_CLAIM_VENDOR_DOC,
259 claim_ns,
260 measured,
261 outcome,
262 selector_version,
263 timestamp_q14
264 )
265 if rc_attest != 0 { return -20 }
266
267 return outcome
268}
269
270func nx_etg_probe_cpu_cache_l2(
271 claim_ns: i64,
272 low_thresh_per_1000: i64,
273 high_thresh_per_1000: i64,
274 entry: *NxEtgEntry,
275 silicon_serial: i64,
276 selector_version: i64,
277 timestamp_q14: i64
278) -> i64 {
279 let cal: *NxCalibrationRecord = nx_calibrate_new()
280 let rc: i64 = nx_calibrate_run(cal)
281 if rc != 0 { return -10 }
282
283 let measured: i64 = cal.mem_ns_per_access_l2
284 let outcome: i64 = nx_etg_classify_outcome(
285 claim_ns, measured, low_thresh_per_1000, high_thresh_per_1000
286 )
287
288 let rc_attest: i64 = nx_etg_entry_init(
289 entry,
290 silicon_serial,
291 NX_ETG_PROBE_CPU_CACHE,
292 NX_ETG_CLAIM_VENDOR_DOC,
293 claim_ns,
294 measured,
295 outcome,
296 selector_version,
297 timestamp_q14
298 )
299 if rc_attest != 0 { return -20 }
300
301 return outcome
302}
303
304func nx_etg_probe_cpu_cache_ram(
305 claim_ns: i64,
306 low_thresh_per_1000: i64,
307 high_thresh_per_1000: i64,
308 entry: *NxEtgEntry,
309 silicon_serial: i64,
310 selector_version: i64,
311 timestamp_q14: i64
312) -> i64 {
313 let cal: *NxCalibrationRecord = nx_calibrate_new()
314 let rc: i64 = nx_calibrate_run(cal)
315 if rc != 0 { return -10 }
316
317 let measured: i64 = cal.mem_ns_per_access_ram
318 let outcome: i64 = nx_etg_classify_outcome(
319 claim_ns, measured, low_thresh_per_1000, high_thresh_per_1000
320 )
321
322 let rc_attest: i64 = nx_etg_entry_init(
323 entry,
324 silicon_serial,
325 NX_ETG_PROBE_STORAGE_RAM,
326 NX_ETG_CLAIM_VENDOR_DOC,
327 claim_ns,
328 measured,
329 outcome,
330 selector_version,
331 timestamp_q14
332 )
333 if rc_attest != 0 { return -20 }
334
335 return outcome
336}