70static inline void gte_enable(
void) {
72 __asm__
volatile(
"mfc0 %0, $12" :
"=r"(sr));
74 __asm__
volatile(
"mtc0 %0, $12; nop; nop" : :
"r"(sr));
78static inline uint32_t irq_disable(
void) {
80 __asm__
volatile(
"mfc0 %0, $12" :
"=r"(sr_orig));
81 sr_new = sr_orig & ~1u;
82 __asm__
volatile(
"mtc0 %0, $12; nop; nop" : :
"r"(sr_new));
86static inline void irq_restore(
uint32_t sr) {
87 __asm__
volatile(
"mtc0 %0, $12; nop; nop" : :
"r"(sr));
119 && a->
ir0 ==
b->ir0 && a->
ir1 ==
b->ir1
120 && a->
ir2 ==
b->ir2 && a->
ir3 ==
b->ir3
122 && a->
sz0 ==
b->sz0 && a->
sz1 ==
b->sz1
123 && a->
sz2 ==
b->sz2 && a->
sz3 ==
b->sz3
124 && a->
flag ==
b->flag;
145#define PROBE_DATA_AT_OFFSET(N, op_imm, dst_reg, canary) do { \
151 "mtc2 %1, $" #dst_reg "\n\t" \
156 : "i"(op_imm), "r"((uint32_t)(canary)) \
160#define PROBE_DATA_BASELINE(op_imm, dst_reg, canary) do { \
166 "mtc2 %1, $" #dst_reg "\n\t" \
171 : "i"(op_imm), "r"((uint32_t)(canary)) \
175#define PROBE_DATA_SANITY_PRE(op_imm, dst_reg, canary) do { \
177 "mtc2 %1, $" #dst_reg "\n\t" \
184 : "i"(op_imm), "r"((uint32_t)(canary)) \
192#define PROBE_CTRL_AT_OFFSET(N, op_imm, dst_reg, canary) do { \
198 "ctc2 %1, $" #dst_reg "\n\t" \
203 : "i"(op_imm), "r"((uint32_t)(canary)) \
207#define PROBE_CTRL_BASELINE(op_imm, dst_reg, canary) do { \
213 "ctc2 %1, $" #dst_reg "\n\t" \
218 : "i"(op_imm), "r"((uint32_t)(canary)) \
222#define PROBE_CTRL_SANITY_PRE(op_imm, dst_reg, canary) do { \
224 "ctc2 %1, $" #dst_reg "\n\t" \
231 : "i"(op_imm), "r"((uint32_t)(canary)) \
246#define DO_SWEEP_DATA(setup_fn, op_imm, dst_reg, canary, results) \
248 setup_fn(); PROBE_DATA_AT_OFFSET( 0, op_imm, dst_reg, canary); read_full_state(&(results)[ 0]); \
249 setup_fn(); PROBE_DATA_AT_OFFSET( 1, op_imm, dst_reg, canary); read_full_state(&(results)[ 1]); \
250 setup_fn(); PROBE_DATA_AT_OFFSET( 2, op_imm, dst_reg, canary); read_full_state(&(results)[ 2]); \
251 setup_fn(); PROBE_DATA_AT_OFFSET( 3, op_imm, dst_reg, canary); read_full_state(&(results)[ 3]); \
252 setup_fn(); PROBE_DATA_AT_OFFSET( 4, op_imm, dst_reg, canary); read_full_state(&(results)[ 4]); \
253 setup_fn(); PROBE_DATA_AT_OFFSET( 5, op_imm, dst_reg, canary); read_full_state(&(results)[ 5]); \
254 setup_fn(); PROBE_DATA_AT_OFFSET( 6, op_imm, dst_reg, canary); read_full_state(&(results)[ 6]); \
255 setup_fn(); PROBE_DATA_AT_OFFSET( 7, op_imm, dst_reg, canary); read_full_state(&(results)[ 7]); \
256 setup_fn(); PROBE_DATA_AT_OFFSET( 8, op_imm, dst_reg, canary); read_full_state(&(results)[ 8]); \
257 setup_fn(); PROBE_DATA_AT_OFFSET( 9, op_imm, dst_reg, canary); read_full_state(&(results)[ 9]); \
258 setup_fn(); PROBE_DATA_AT_OFFSET(10, op_imm, dst_reg, canary); read_full_state(&(results)[10]); \
259 setup_fn(); PROBE_DATA_AT_OFFSET(11, op_imm, dst_reg, canary); read_full_state(&(results)[11]); \
260 setup_fn(); PROBE_DATA_AT_OFFSET(12, op_imm, dst_reg, canary); read_full_state(&(results)[12]); \
261 setup_fn(); PROBE_DATA_AT_OFFSET(13, op_imm, dst_reg, canary); read_full_state(&(results)[13]); \
262 setup_fn(); PROBE_DATA_AT_OFFSET(14, op_imm, dst_reg, canary); read_full_state(&(results)[14]); \
263 setup_fn(); PROBE_DATA_AT_OFFSET(15, op_imm, dst_reg, canary); read_full_state(&(results)[15]); \
264 setup_fn(); PROBE_DATA_AT_OFFSET(16, op_imm, dst_reg, canary); read_full_state(&(results)[16]); \
265 setup_fn(); PROBE_DATA_AT_OFFSET(17, op_imm, dst_reg, canary); read_full_state(&(results)[17]); \
266 setup_fn(); PROBE_DATA_AT_OFFSET(18, op_imm, dst_reg, canary); read_full_state(&(results)[18]); \
267 setup_fn(); PROBE_DATA_AT_OFFSET(19, op_imm, dst_reg, canary); read_full_state(&(results)[19]); \
268 setup_fn(); PROBE_DATA_AT_OFFSET(20, op_imm, dst_reg, canary); read_full_state(&(results)[20]); \
269 setup_fn(); PROBE_DATA_AT_OFFSET(21, op_imm, dst_reg, canary); read_full_state(&(results)[21]); \
270 setup_fn(); PROBE_DATA_AT_OFFSET(22, op_imm, dst_reg, canary); read_full_state(&(results)[22]); \
271 setup_fn(); PROBE_DATA_AT_OFFSET(23, op_imm, dst_reg, canary); read_full_state(&(results)[23]); \
272 setup_fn(); PROBE_DATA_AT_OFFSET(24, op_imm, dst_reg, canary); read_full_state(&(results)[24]); \
273 setup_fn(); PROBE_DATA_AT_OFFSET(25, op_imm, dst_reg, canary); read_full_state(&(results)[25]); \
274 setup_fn(); PROBE_DATA_AT_OFFSET(26, op_imm, dst_reg, canary); read_full_state(&(results)[26]); \
275 setup_fn(); PROBE_DATA_AT_OFFSET(27, op_imm, dst_reg, canary); read_full_state(&(results)[27]); \
276 setup_fn(); PROBE_DATA_AT_OFFSET(28, op_imm, dst_reg, canary); read_full_state(&(results)[28]); \
277 setup_fn(); PROBE_DATA_AT_OFFSET(29, op_imm, dst_reg, canary); read_full_state(&(results)[29]); \
278 setup_fn(); PROBE_DATA_AT_OFFSET(30, op_imm, dst_reg, canary); read_full_state(&(results)[30]); \
279 setup_fn(); PROBE_DATA_AT_OFFSET(31, op_imm, dst_reg, canary); read_full_state(&(results)[31]); \
280 setup_fn(); PROBE_DATA_AT_OFFSET(32, op_imm, dst_reg, canary); read_full_state(&(results)[32]); \
283#define DO_SWEEP_CTRL(setup_fn, op_imm, dst_reg, canary, results) \
285 setup_fn(); PROBE_CTRL_AT_OFFSET( 0, op_imm, dst_reg, canary); read_full_state(&(results)[ 0]); \
286 setup_fn(); PROBE_CTRL_AT_OFFSET( 1, op_imm, dst_reg, canary); read_full_state(&(results)[ 1]); \
287 setup_fn(); PROBE_CTRL_AT_OFFSET( 2, op_imm, dst_reg, canary); read_full_state(&(results)[ 2]); \
288 setup_fn(); PROBE_CTRL_AT_OFFSET( 3, op_imm, dst_reg, canary); read_full_state(&(results)[ 3]); \
289 setup_fn(); PROBE_CTRL_AT_OFFSET( 4, op_imm, dst_reg, canary); read_full_state(&(results)[ 4]); \
290 setup_fn(); PROBE_CTRL_AT_OFFSET( 5, op_imm, dst_reg, canary); read_full_state(&(results)[ 5]); \
291 setup_fn(); PROBE_CTRL_AT_OFFSET( 6, op_imm, dst_reg, canary); read_full_state(&(results)[ 6]); \
292 setup_fn(); PROBE_CTRL_AT_OFFSET( 7, op_imm, dst_reg, canary); read_full_state(&(results)[ 7]); \
293 setup_fn(); PROBE_CTRL_AT_OFFSET( 8, op_imm, dst_reg, canary); read_full_state(&(results)[ 8]); \
294 setup_fn(); PROBE_CTRL_AT_OFFSET( 9, op_imm, dst_reg, canary); read_full_state(&(results)[ 9]); \
295 setup_fn(); PROBE_CTRL_AT_OFFSET(10, op_imm, dst_reg, canary); read_full_state(&(results)[10]); \
296 setup_fn(); PROBE_CTRL_AT_OFFSET(11, op_imm, dst_reg, canary); read_full_state(&(results)[11]); \
297 setup_fn(); PROBE_CTRL_AT_OFFSET(12, op_imm, dst_reg, canary); read_full_state(&(results)[12]); \
298 setup_fn(); PROBE_CTRL_AT_OFFSET(13, op_imm, dst_reg, canary); read_full_state(&(results)[13]); \
299 setup_fn(); PROBE_CTRL_AT_OFFSET(14, op_imm, dst_reg, canary); read_full_state(&(results)[14]); \
300 setup_fn(); PROBE_CTRL_AT_OFFSET(15, op_imm, dst_reg, canary); read_full_state(&(results)[15]); \
301 setup_fn(); PROBE_CTRL_AT_OFFSET(16, op_imm, dst_reg, canary); read_full_state(&(results)[16]); \
302 setup_fn(); PROBE_CTRL_AT_OFFSET(17, op_imm, dst_reg, canary); read_full_state(&(results)[17]); \
303 setup_fn(); PROBE_CTRL_AT_OFFSET(18, op_imm, dst_reg, canary); read_full_state(&(results)[18]); \
304 setup_fn(); PROBE_CTRL_AT_OFFSET(19, op_imm, dst_reg, canary); read_full_state(&(results)[19]); \
305 setup_fn(); PROBE_CTRL_AT_OFFSET(20, op_imm, dst_reg, canary); read_full_state(&(results)[20]); \
306 setup_fn(); PROBE_CTRL_AT_OFFSET(21, op_imm, dst_reg, canary); read_full_state(&(results)[21]); \
307 setup_fn(); PROBE_CTRL_AT_OFFSET(22, op_imm, dst_reg, canary); read_full_state(&(results)[22]); \
308 setup_fn(); PROBE_CTRL_AT_OFFSET(23, op_imm, dst_reg, canary); read_full_state(&(results)[23]); \
309 setup_fn(); PROBE_CTRL_AT_OFFSET(24, op_imm, dst_reg, canary); read_full_state(&(results)[24]); \
310 setup_fn(); PROBE_CTRL_AT_OFFSET(25, op_imm, dst_reg, canary); read_full_state(&(results)[25]); \
311 setup_fn(); PROBE_CTRL_AT_OFFSET(26, op_imm, dst_reg, canary); read_full_state(&(results)[26]); \
312 setup_fn(); PROBE_CTRL_AT_OFFSET(27, op_imm, dst_reg, canary); read_full_state(&(results)[27]); \
313 setup_fn(); PROBE_CTRL_AT_OFFSET(28, op_imm, dst_reg, canary); read_full_state(&(results)[28]); \
314 setup_fn(); PROBE_CTRL_AT_OFFSET(29, op_imm, dst_reg, canary); read_full_state(&(results)[29]); \
315 setup_fn(); PROBE_CTRL_AT_OFFSET(30, op_imm, dst_reg, canary); read_full_state(&(results)[30]); \
316 setup_fn(); PROBE_CTRL_AT_OFFSET(31, op_imm, dst_reg, canary); read_full_state(&(results)[31]); \
317 setup_fn(); PROBE_CTRL_AT_OFFSET(32, op_imm, dst_reg, canary); read_full_state(&(results)[32]); \
331static void report_sweep(
const char* name,
336 ramsyscall_printf(
"baseline RGB=(0x%08x,0x%08x,0x%08x) MAC0=%d MAC=(%d,%d,%d) IR0=%d IR=(%d,%d,%d) FLAG=0x%08x\n",
339 baseline->
ir0, baseline->
ir1, baseline->
ir2, baseline->
ir3,
341 int sanity_differs = !results_equal(baseline, sanity_pre);
342 ramsyscall_printf(
"sanity-pre RGB=(0x%08x,0x%08x,0x%08x) MAC0=%d MAC=(%d,%d,%d) IR0=%d IR=(%d,%d,%d) FLAG=0x%08x %s\n",
345 sanity_pre->
ir0, sanity_pre->
ir1, sanity_pre->
ir2, sanity_pre->
ir3,
347 sanity_differs ?
"DIFFERS_OK" :
"*** SAME_AS_BASELINE_BUG ***");
350 int matches = results_equal(baseline, &results[
n]);
351 ramsyscall_printf(
"N=%2d RGB=(0x%08x,0x%08x,0x%08x) MAC=(%d,%d,%d) IR=(%d,%d,%d) FLAG=0x%08x %s\n",
358 if (
matches && boundary < 0) boundary =
n;
371#define MAKE_DATA_TEST(test_name, scene_setup, op_imm, dst_reg, canary, label) \
372CESTER_TEST(test_name, gte_latency_tests, \
373 static probe_result_t baseline, sanity_pre; \
374 static probe_result_t warmup[MAX_N + 1]; \
375 static probe_result_t results[MAX_N + 1]; \
377 PROBE_DATA_BASELINE(op_imm, dst_reg, canary); \
378 read_full_state(&baseline); \
380 PROBE_DATA_SANITY_PRE(op_imm, dst_reg, canary); \
381 read_full_state(&sanity_pre); \
382 uint32_t saved_sr = irq_disable(); \
383 DO_SWEEP_DATA(scene_setup, op_imm, dst_reg, canary, warmup); \
384 DO_SWEEP_DATA(scene_setup, op_imm, dst_reg, canary, results); \
385 irq_restore(saved_sr); \
386 report_sweep(label, &baseline, &sanity_pre, results); \
387 cester_assert_true(!results_equal(&baseline, &sanity_pre)); \
390#define MAKE_CTRL_TEST(test_name, scene_setup, op_imm, dst_reg, canary, label) \
391CESTER_TEST(test_name, gte_latency_tests, \
392 static probe_result_t baseline, sanity_pre; \
393 static probe_result_t warmup[MAX_N + 1]; \
394 static probe_result_t results[MAX_N + 1]; \
396 PROBE_CTRL_BASELINE(op_imm, dst_reg, canary); \
397 read_full_state(&baseline); \
399 PROBE_CTRL_SANITY_PRE(op_imm, dst_reg, canary); \
400 read_full_state(&sanity_pre); \
401 uint32_t saved_sr = irq_disable(); \
402 DO_SWEEP_CTRL(scene_setup, op_imm, dst_reg, canary, warmup); \
403 DO_SWEEP_CTRL(scene_setup, op_imm, dst_reg, canary, results); \
404 irq_restore(saved_sr); \
405 report_sweep(label, &baseline, &sanity_pre, results); \
406 cester_assert_true(!results_equal(&baseline, &sanity_pre)); \
#define cop2_getc(reg, dest)
Definition cop2.h:203
#define cop2_get(reg, dest)
Definition cop2.h:189
uint32_t r
Definition cpu.c:222
int matches
Definition dcache.c:706
int n
Definition dcache.c:225
ramsyscall_printf("=== e01_kseg1_reads_no_fill ===\n")
int32_t mac1
Definition gte-depthcue.c:116
uint8_t b
Definition gte-depthcue.c:39
int32_t mac2
Definition gte-depthcue.c:116
int32_t mac3
Definition gte-depthcue.c:116
uint32_t rgb2
Definition gte-depthcue.c:35
uint32_t ir1
Definition gte-edgecase.c:108
uint32_t sz3
Definition gte-edgecase.c:375
uint32_t sxy2
Definition gte-edgecase.c:36
uint32_t flag
Definition gte-edgecase.c:36
#define MAX_N
Definition gte-latency-common.h:51
uint32_t rgb1
Definition gte-lighting.c:205
uint32_t rgb0
Definition gte-lighting.c:205
uint32_t ir3
Definition gte-precision.c:320
uint32_t sz1
Definition gte-rtps.c:217
uint32_t sz2
Definition gte-rtps.c:217
uint32_t sxy1
Definition gte-rtps.c:164
uint32_t ir2
Definition gte-sqr.c:24
Definition gte-latency-common.h:60
int32_t mac3
Definition gte-latency-common.h:62
uint32_t rgb1
Definition gte-latency-common.h:61
uint32_t sz0
Definition gte-latency-common.h:65
int32_t ir1
Definition gte-latency-common.h:63
uint32_t sz2
Definition gte-latency-common.h:65
int32_t ir0
Definition gte-latency-common.h:63
uint32_t rgb2
Definition gte-latency-common.h:61
int32_t mac2
Definition gte-latency-common.h:62
uint32_t sxy0
Definition gte-latency-common.h:64
int32_t ir2
Definition gte-latency-common.h:63
uint32_t sz1
Definition gte-latency-common.h:65
int32_t ir3
Definition gte-latency-common.h:63
int32_t mac1
Definition gte-latency-common.h:62
uint32_t sxy1
Definition gte-latency-common.h:64
uint32_t rgb0
Definition gte-latency-common.h:61
uint32_t sz3
Definition gte-latency-common.h:65
uint32_t flag
Definition gte-latency-common.h:66
int32_t mac0
Definition gte-latency-common.h:62
uint32_t sxy2
Definition gte-latency-common.h:64
void uint32_t(classId, spec)