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) {
79 uint32_t sr_orig, sr_new;
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));
116 return a->rgb0 ==
b->rgb0 &&
a->rgb1 ==
b->rgb1 &&
a->rgb2 ==
b->rgb2
117 &&
a->mac0 ==
b->mac0 &&
a->mac1 ==
b->mac1
118 &&
a->mac2 ==
b->mac2 &&
a->mac3 ==
b->mac3
119 &&
a->ir0 ==
b->ir0 &&
a->ir1 ==
b->ir1
120 &&
a->ir2 ==
b->ir2 &&
a->ir3 ==
b->ir3
121 &&
a->sxy0 ==
b->sxy0 &&
a->sxy1 ==
b->sxy1 &&
a->sxy2 ==
b->sxy2
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 ***");
349 for (
int n = 0; n <=
MAX_N; n++) {
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",
355 results[n].
ir1, results[n].
ir2, results[n].
ir3,
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)); \
ramsyscall_printf("T21 phase=%s t=%u v=%02x cause=%u size=%u stat=%02x\n", phase, t/1000, response[0], cause, size,(nopCause==3 &&nopSize >=1) ? stat[0] :0xff)
uint32_t sr
Definition cop0.c:249
#define cop2_getc(reg, dest)
Definition cop2.h:212
#define cop2_get(reg, dest)
Definition cop2.h:198
uint32_t r
Definition cpu.c:310
int matches
Definition dcache.c:706
int32_t mac1
Definition gte-depthcue.c:118
uint8_t b
Definition gte-depthcue.c:41
int32_t mac2
Definition gte-depthcue.c:118
int32_t mac3
Definition gte-depthcue.c:118
uint32_t rgb2
Definition gte-depthcue.c:37
uint32_t ir1
Definition gte-edgecase.c:110
uint32_t sz3
Definition gte-edgecase.c:377
uint32_t sxy2
Definition gte-edgecase.c:38
uint32_t flag
Definition gte-edgecase.c:38
#define MAX_N
Definition gte-latency-common.h:51
uint32_t rgb1
Definition gte-lighting.c:207
uint32_t rgb0
Definition gte-lighting.c:207
uint32_t ir3
Definition gte-precision.c:322
uint32_t sz1
Definition gte-rtps.c:219
uint32_t sz2
Definition gte-rtps.c:219
uint32_t sxy1
Definition gte-rtps.c:166
uint32_t ir2
Definition gte-sqr.c:26
__asm__(" .section .text.monitorSlotEntry, \"ax\", @progbits\n" " .align 2\n" " .global monitorSlotEntry\n" " .type monitorSlotEntry, @function\n" " .set push\n" " .set noreorder\n" " .set noat\n" "monitorSlotEntry:\n" " mfc0 $v0, $13\n" " nop\n" " andi $v0, $v0, 0x7c\n" " beqz $v0, 1f\n" " srl $v0, $v0, 2\n" " li $v1, " MON_STR(MON_SLOT_EXCMASK) "\n" " srlv $v1, $v1, $v0\n" " andi $v1, $v1, 1\n" " bnez $v1, 2f\n" " nop\n" " jr $ra\n" " nop\n" "1:\n" MON_SLOT_RX_TEST " jr $ra\n" " nop\n" "2:\n" " sw $a0, 0x10($k0)\n" " sw $a1, 0x14($k0)\n" " sw $a2, 0x18($k0)\n" " sw $a3, 0x1c($k0)\n" " mfc0 $a0, $12\n" " nop\n" " sw $a0, 0x8c($k0)\n" " mfc0 $a1, $13\n" " nop\n" " sw $a1, 0x90($k0)\n" " sw $k1, 0x6c($k0)\n" " sw $s0, 0x40($k0)\n" " sw $s1, 0x44($k0)\n" " sw $s2, 0x48($k0)\n" " sw $s3, 0x4c($k0)\n" " sw $s4, 0x50($k0)\n" " sw $s5, 0x54($k0)\n" " sw $s6, 0x58($k0)\n" " sw $s7, 0x5c($k0)\n" " sw $t0, 0x20($k0)\n" " sw $t1, 0x24($k0)\n" " sw $t2, 0x28($k0)\n" " sw $t3, 0x2c($k0)\n" " sw $t4, 0x30($k0)\n" " sw $t5, 0x34($k0)\n" " sw $t6, 0x38($k0)\n" " sw $t7, 0x3c($k0)\n" " sw $t8, 0x60($k0)\n" " sw $t9, 0x64($k0)\n" " sw $gp, 0x70($k0)\n" " sw $sp, 0x74($k0)\n" " sw $fp, 0x78($k0)\n" " mfhi $a0\n" " nop\n" " sw $a0, 0x84($k0)\n" " mflo $a0\n" " nop\n" " sw $a0, 0x88($k0)\n" " move $s0, $ra\n" " la $sp, monitorSlotStack + " MON_STR(MONITOR_SLOT_STACK_WORDS) " * 4 - 16\n" " jal monitorSlotDispatch\n" " nop\n" " lw $k0, 0x108($zero)\n" " move $ra, $s0\n" " lw $k0, 0($k0)\n" " nop\n" " addiu $k0, $k0, 8\n" " lw $a0, 0x84($k0)\n" " lw $a1, 0x88($k0)\n" " mthi $a0\n" " mtlo $a1\n" " lw $a0, 0x10($k0)\n" " lw $a1, 0x14($k0)\n" " lw $a2, 0x18($k0)\n" " lw $a3, 0x1c($k0)\n" " lw $t0, 0x20($k0)\n" " lw $t1, 0x24($k0)\n" " lw $t2, 0x28($k0)\n" " lw $t3, 0x2c($k0)\n" " lw $t4, 0x30($k0)\n" " lw $t5, 0x34($k0)\n" " lw $t6, 0x38($k0)\n" " lw $t7, 0x3c($k0)\n" " lw $t8, 0x60($k0)\n" " lw $t9, 0x64($k0)\n" " lw $s0, 0x40($k0)\n" " lw $sp, 0x74($k0)\n" " jr $ra\n" " nop\n" " .set pop\n" " .size monitorSlotEntry, . - monitorSlotEntry\n" " .previous\n")
int a
Definition mktest.py:134
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
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
int32_t ir3
Definition gte-latency-common.h:63
int32_t mac1
Definition gte-latency-common.h:62
uint32_t rgb0
Definition gte-latency-common.h:61
uint32_t flag
Definition gte-latency-common.h:66
int32_t mac0
Definition gte-latency-common.h:62