Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
tests
gte-write-to-use
gwu.h
Go to the documentation of this file.
1
/*
2
3
MIT License
4
5
Copyright (c) 2026 PCSX-Redux authors
6
7
Permission is hereby granted, free of charge, to any person obtaining a copy
8
of this software and associated documentation files (the "Software"), to deal
9
in the Software without restriction, including without limitation the rights
10
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
copies of the Software, and to permit persons to whom the Software is
12
furnished to do so, subject to the following conditions:
13
14
The above copyright notice and this permission notice shall be included in all
15
copies or substantial portions of the Software.
16
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
SOFTWARE.
24
*/
25
26
/*
27
* Write-to-use delay, per cop2 command and per input register.
28
*
29
* Every cell is one (command, input register) pair of the gte-latency tests,
30
* with that test's scene and canary. A cell function writes the register's
31
* scene value, waits 4 nops, writes a second value, waits N nops, runs the
32
* command:
33
*
34
* mtc2/ctc2 a, reg; nop x4; mtc2/ctc2 b, reg; nop x N; cop2 CMD
35
*
36
* and the command's outputs are compared against two references run through
37
* the same function: a = b = scene value (old), a = b = canary (new).
38
* The written register itself is left out of the comparison.
39
*
40
* Varied: N = 0..3; A = 0..3, the word within a 16-byte cache line the
41
* sequence starts at (A0..A3, cached); and cached vs uncached fetch (U,
42
* at A = 0). Held: interrupts off, nop as the filler and as the
43
* instruction before the second write, mtc2/ctc2 as the writer, the
44
* measured pass is the second of two back to back.
45
*
46
* The last column of each cell is the cached result from SCPH-1000, -1001,
47
* -5501 (two) -7001 and -9002 (see RESULTS.md). A letter that is the same
48
* at every A is checked against it, and the program returns 1 on any
49
* difference; '?' marks a letter that moves with A or between consoles,
50
* which is printed and not checked. The uncached pass is printed only.
51
*/
52
53
#pragma once
54
55
#include <stdint.h>
56
57
#include "
gte-latency-common.h
"
58
59
#define GWU_NMAX 4
60
#define GWU_AMAX 4
61
62
typedef
void (*
GwuFn
)(uint32_t, uint32_t);
63
64
typedef
struct
{
65
const
char
*
label
;
66
void (*scene)(void);
67
uint32_t (*read)(void);
68
GwuFn
fn[
GWU_NMAX
][
GWU_AMAX
];
69
uint32_t
canary
;
70
uint8_t
ctrl
;
71
uint8_t
reg
;
72
const
char
*
expect
;
73
}
GwuCell
;
74
75
#define GWU_W_D "mtc2"
76
#define GWU_W_C "ctc2"
77
#define GWU_GET_D cop2_get
78
#define GWU_GET_C cop2_getc
79
#define GWU_ISC_D 0
80
#define GWU_ISC_C 1
81
82
// A = how many words past a 16-byte cache line boundary the sequence starts.
83
#define GWU_FN(W, name, op, reg, N, A) \
84
static void name##_##N##_##A(uint32_t a, uint32_t b) { \
85
__asm__ volatile(".set push\n.set noreorder\n.balign 16\n.rept " #A "\nnop\n.endr\n" W " %0, $" #reg \
86
"\nnop\nnop\nnop\nnop\n" W " %1, $" #reg "\n.rept " #N \
87
"\nnop\n.endr\ncop2 %2\nnop\nnop\n.set pop\n" \
88
: \
89
: "r"(a), "r"(b), "i"(op)); \
90
}
91
92
#define GWU_FN_A(W, name, op, reg, N) \
93
GWU_FN(W, name, op, reg, N, 0) \
94
GWU_FN(W, name, op, reg, N, 1) \
95
GWU_FN(W, name, op, reg, N, 2) \
96
GWU_FN(W, name, op, reg, N, 3)
97
98
#define GWU_FUNCS(K, name, scene, op, reg, canary, label, expect) \
99
GWU_FN_A(GWU_W_##K, name, op, reg, 0) \
100
GWU_FN_A(GWU_W_##K, name, op, reg, 1) \
101
GWU_FN_A(GWU_W_##K, name, op, reg, 2) \
102
GWU_FN_A(GWU_W_##K, name, op, reg, 3) \
103
static uint32_t name##_rd(void) { \
104
uint32_t v; \
105
GWU_GET_##K(reg, v); \
106
return v; \
107
}
108
109
#define GWU_ROW(name, N) {name##_##N##_0, name##_##N##_1, name##_##N##_2, name##_##N##_3}
110
#define GWU_ENTRY(K, name, scene, op, reg, canary, label, expect) \
111
{label, scene, name##_rd, {GWU_ROW(name, 0), GWU_ROW(name, 1), GWU_ROW(name, 2), GWU_ROW(name, 3)}, \
112
canary, GWU_ISC_##K, reg, expect},
gte-latency-common.h
GWU_AMAX
#define GWU_AMAX
Definition
gwu.h:60
GwuFn
void(* GwuFn)(uint32_t, uint32_t)
Definition
gwu.h:62
GWU_NMAX
#define GWU_NMAX
Definition
gwu.h:59
GwuCell
Definition
gwu.h:64
GwuCell::canary
uint32_t canary
Definition
gwu.h:69
GwuCell::reg
uint8_t reg
Definition
gwu.h:71
GwuCell::ctrl
uint8_t ctrl
Definition
gwu.h:70
GwuCell::expect
const char * expect
Definition
gwu.h:72
GwuCell::label
const char * label
Definition
gwu.h:65
Generated by
1.9.8