Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
spu-irq.c
Go to the documentation of this file.
1// ==========================================================================
2// Characterize SPU IRQs from the voice ADPCM read pointer
3// ==========================================================================
4//
5// Hardware goldens captured on real silicon. Only the deterministic latch-
6// semantics values are pinned: where the IRQ-gated data lands in the capture
7// buffer (firstNonzero, nonzeroCount, sum), that an ack re-arms immediately
8// (rearm.secondPolls), and the mid-block re-fire count (midblock.hits). The
9// poll counts (aligned.polls, rearm.firstPolls, midblock.firstPolls) and the
10// capture tail index (aligned.lastNonzero) are left UNSET on purpose: they are
11// CPU-vs-SPU timing / capture-window-edge quantities that vary run-to-run even
12// on the same console (measured across repeat hardware runs), so pinning them
13// would assert a value neither hardware nor an emulator reproduces.
14
15#ifndef SPU_IRQ_EXPECTED_UNSET
16#define SPU_IRQ_EXPECTED_UNSET 0xffffffffu
17#endif
18
19#ifndef SPU_IRQ_EXPECTED_ALIGNED_POLLS
20#define SPU_IRQ_EXPECTED_ALIGNED_POLLS SPU_IRQ_EXPECTED_UNSET
21#endif
22#ifndef SPU_IRQ_EXPECTED_ALIGNED_FIRST_NONZERO
23#define SPU_IRQ_EXPECTED_ALIGNED_FIRST_NONZERO 0u
24#endif
25#ifndef SPU_IRQ_EXPECTED_ALIGNED_LAST_NONZERO
26#define SPU_IRQ_EXPECTED_ALIGNED_LAST_NONZERO SPU_IRQ_EXPECTED_UNSET
27#endif
28#ifndef SPU_IRQ_EXPECTED_ALIGNED_NONZERO_COUNT
29#define SPU_IRQ_EXPECTED_ALIGNED_NONZERO_COUNT 345u
30#endif
31#ifndef SPU_IRQ_EXPECTED_ALIGNED_SUM
32#define SPU_IRQ_EXPECTED_ALIGNED_SUM 18806188u
33#endif
34
35#ifndef SPU_IRQ_EXPECTED_REARM_FIRST_POLLS
36#define SPU_IRQ_EXPECTED_REARM_FIRST_POLLS SPU_IRQ_EXPECTED_UNSET
37#endif
38#ifndef SPU_IRQ_EXPECTED_REARM_SECOND_POLLS
39#define SPU_IRQ_EXPECTED_REARM_SECOND_POLLS 1u
40#endif
41
42#ifndef SPU_IRQ_EXPECTED_MIDBLOCK_HITS
43#define SPU_IRQ_EXPECTED_MIDBLOCK_HITS 2u
44#endif
45#ifndef SPU_IRQ_EXPECTED_MIDBLOCK_FIRST_POLLS
46#define SPU_IRQ_EXPECTED_MIDBLOCK_FIRST_POLLS SPU_IRQ_EXPECTED_UNSET
47#endif
48
49#define SPU_IRQ_TEST_ADDR 0x2000
50#define SPU_IRQ_DUMMY_ADDR 0x7000
51#define SPU_IRQ_POLL_TIMEOUT 2000000u
52#define SPU_IRQ_REARM_TIMEOUT 6000000u
53
55typedef struct {
56 uint32_t irqAddr;
57 uint32_t fired;
58 uint32_t polls;
59 uint32_t statusAtFire;
60 uint32_t statusAfterAck;
61 uint32_t ackCleared;
62 uint32_t currentVolumeAtFire;
63 uint32_t captureFirstNonzero;
64 uint32_t captureLastNonzero;
65 uint32_t captureNonzeroCount;
66 uint32_t captureSum;
67} SpuIrqMeasurement;
68
69static uint8_t s_irqSample[128] __attribute__((aligned(4)));
70
71static void spu_irq_make_sample(void) {
72 for (int block = 0; block < 8; block++) {
73 uint8_t *p = &s_irqSample[block * 16];
74 p[0] = 0x00;
75 p[1] = 0x00;
76 if (block == 0) p[1] = 0x06; // loop start
77 if (block == 7) p[1] = 0x03; // loop end
78 uint8_t nybble = (uint8_t)((block + 1) & 7);
79 uint8_t packed = (uint8_t)(nybble | (nybble << 4));
80 for (int i = 2; i < 16; i++) p[i] = packed;
81 }
82}
83
84static void spu_irq_arm(uint32_t byteAddr) {
85 SPU_IRQ_ADDR = (uint16_t)(byteAddr >> 3);
86 SPU_CTRL = (SPU_CTRL & ~0x0030) | 0x8000 | 0x4000 | 0x0040;
87 for (volatile int i = 0; i < 120; i++) ;
88}
89
91 SPU_CTRL = SPU_CTRL & ~0x0040;
92 for (uint32_t i = 0; i < 100000; i++) {
93 if ((SPU_STATUS & 0x0040) == 0) return 1;
94 }
95 return 0;
96}
97
98static uint32_t spu_irq_poll_until(uint32_t maxPolls) {
99 for (uint32_t i = 0; i < maxPolls; i++) {
100 if (SPU_STATUS & 0x0040) return i + 1;
101 __asm__ volatile("");
102 }
103 return 0;
104}
105
106static void spu_irq_quiet_unused_voices(void) {
107 for (int v = 0; v < 24; v++) {
108 SPU_VOICES[v].volumeLeft = 0;
109 SPU_VOICES[v].volumeRight = 0;
110 SPU_VOICES[v].sampleRate = 0x1000;
111 SPU_VOICES[v].sampleStartAddr = SPU_IRQ_DUMMY_ADDR >> 3;
112 SPU_VOICES[v].sampleRepeatAddr = SPU_IRQ_DUMMY_ADDR >> 3;
113 SPU_VOICES[v].adsrLo = 0x000f;
114 SPU_VOICES[v].adsrHi = 0x1fc0;
115 }
116 SPU_KEY_OFF_LOW = 0;
118 SPU_KEY_ON_LOW = 0xffff;
119 SPU_KEY_ON_HIGH = 0x00ff;
120 spu_busy_wait(200000);
121}
122
123static void spu_irq_prepare(void) {
125 spu_irq_make_sample();
126 spu_write_sync(SPU_IRQ_DUMMY_ADDR, kAdpcmSilent, sizeof(kAdpcmSilent));
127 spu_write_sync(SPU_IRQ_TEST_ADDR, s_irqSample, sizeof(s_irqSample));
128 SPU_CTRL = 0x8000 | 0x4000;
131 spu_irq_quiet_unused_voices();
133}
134
135static void spu_irq_start_voice1(void) {
136 SPU_VOICES[1].volumeLeft = 0;
137 SPU_VOICES[1].volumeRight = 0;
138 spu_voice1_keyon(SPU_IRQ_TEST_ADDR, 0x1000);
139}
140
141static void spu_irq_analyze_capture(SpuIrqMeasurement *m) {
142 uint32_t first = 0xffffffffu;
143 uint32_t last = 0;
144 uint32_t count = 0;
145 uint32_t sum = 0;
146
147 spu_read_sync(0x0800, s_capture, 1024);
148 for (uint32_t i = 0; i < 512; i++) {
149 uint16_t v = s_capture[i];
150 if (v != 0) {
151 if (first == 0xffffffffu) first = i;
152 last = i;
153 count++;
154 sum += v;
155 }
156 }
157
158 m->captureFirstNonzero = first;
159 m->captureLastNonzero = last;
160 m->captureNonzeroCount = count;
161 m->captureSum = sum;
162}
163
164static void spu_irq_measure_once(uint32_t irqByteAddr, SpuIrqMeasurement *m) {
165 spu_irq_prepare();
166 m->irqAddr = irqByteAddr;
167
168 // The suite disables CPU interrupts globally. For this characterization pass
169 // we deliberately poll SPUSTAT.6 instead of taking IRQ9: it measures the SPU
170 // IRQ latch/ack semantics without re-enabling Unirom/vblank/SIO handlers into
171 // the jitter-sensitive SPU tests. A later interrupt-delivery test can layer on
172 // IMASK/IREG once the SPU-side latch behavior is known.
173 spu_wait_status_bit11_flip();
174 spu_irq_arm(irqByteAddr);
175 spu_irq_start_voice1();
176
177 m->polls = spu_irq_poll_until(SPU_IRQ_POLL_TIMEOUT);
178 m->fired = (m->polls != 0);
179 m->statusAtFire = SPU_STATUS;
180 m->currentVolumeAtFire = SPU_VOICES[1].currentVolume;
181 m->ackCleared = spu_irq_ack_by_disable();
182 m->statusAfterAck = SPU_STATUS;
183 spu_irq_analyze_capture(m);
184
185 SPU_KEY_OFF_LOW = 0xffff;
186 SPU_KEY_OFF_HIGH = 0xffff;
187 muteSpu();
188}
189
190static void spu_irq_print_measurement(const char *name, const SpuIrqMeasurement *m) {
192 "OBS spu_irq %s irq=0x%05lx fired=%lu polls=%lu statusFire=0x%04lx "
193 "ackCleared=%lu statusAck=0x%04lx envx=0x%04lx capFirst=%lu capLast=%lu "
194 "capCount=%lu capSum=0x%08lx\n",
195 name, m->irqAddr, m->fired, m->polls, m->statusAtFire & 0xffff,
196 m->ackCleared, m->statusAfterAck & 0xffff, m->currentVolumeAtFire & 0xffff,
197 m->captureFirstNonzero, m->captureLastNonzero, m->captureNonzeroCount, m->captureSum);
198}
199
200static void spu_irq_expect_u32(const char *name, uint32_t expected, uint32_t got) {
201 if (expected == SPU_IRQ_EXPECTED_UNSET) {
202 ramsyscall_printf("OBS spu_irq expected %s=%lu\n", name, got);
203 } else {
204 cester_assert_uint_eq(expected, got);
205 }
206}
207)
208
209CESTER_MAYBE_TEST(irq_voice_read_pointer_block_aligned, spu_tests,
210 SpuIrqMeasurement m;
211 spu_irq_measure_once(SPU_IRQ_TEST_ADDR + 16, &m);
212 spu_irq_print_measurement("aligned_block1", &m);
213
214 uint32_t statusFlagAfterAck = m.statusAfterAck & 0x0040;
215 cester_assert_uint_eq(1, m.fired);
216 cester_assert_uint_eq(1, m.ackCleared);
217 cester_assert_uint_eq(0, statusFlagAfterAck);
218 spu_irq_expect_u32("aligned.polls", SPU_IRQ_EXPECTED_ALIGNED_POLLS, m.polls);
219 spu_irq_expect_u32("aligned.firstNonzero", SPU_IRQ_EXPECTED_ALIGNED_FIRST_NONZERO, m.captureFirstNonzero);
220 spu_irq_expect_u32("aligned.lastNonzero", SPU_IRQ_EXPECTED_ALIGNED_LAST_NONZERO, m.captureLastNonzero);
221 spu_irq_expect_u32("aligned.nonzeroCount", SPU_IRQ_EXPECTED_ALIGNED_NONZERO_COUNT, m.captureNonzeroCount);
222 spu_irq_expect_u32("aligned.sum", SPU_IRQ_EXPECTED_ALIGNED_SUM, m.captureSum);
223)
224
225CESTER_MAYBE_TEST(irq_voice_read_pointer_ack_rearms, spu_tests,
226 SpuIrqMeasurement first;
227 spu_irq_prepare();
228 spu_wait_status_bit11_flip();
229 spu_irq_arm(SPU_IRQ_TEST_ADDR + 16);
230 spu_irq_start_voice1();
231
232 first.polls = spu_irq_poll_until(SPU_IRQ_POLL_TIMEOUT);
233 first.fired = (first.polls != 0);
234 first.statusAtFire = SPU_STATUS;
235 first.ackCleared = spu_irq_ack_by_disable();
236 first.statusAfterAck = SPU_STATUS;
237
238 spu_irq_arm(SPU_IRQ_TEST_ADDR + 16);
239 uint32_t secondPolls = spu_irq_poll_until(SPU_IRQ_REARM_TIMEOUT);
240 uint32_t secondFired = (secondPolls != 0);
241 uint32_t secondStatus = SPU_STATUS;
242 uint32_t secondAckCleared = spu_irq_ack_by_disable();
243
245 "OBS spu_irq rearm firstFired=%lu firstPolls=%lu firstStatus=0x%04lx "
246 "firstAck=%lu firstStatusAck=0x%04lx secondFired=%lu secondPolls=%lu "
247 "secondStatus=0x%04lx secondAck=%lu\n",
248 first.fired, first.polls, first.statusAtFire & 0xffff, first.ackCleared,
249 first.statusAfterAck & 0xffff, secondFired, secondPolls, secondStatus & 0xffff,
250 secondAckCleared);
251
252 SPU_KEY_OFF_LOW = 0xffff;
253 SPU_KEY_OFF_HIGH = 0xffff;
254 muteSpu();
255
256 cester_assert_uint_eq(1, first.fired);
257 cester_assert_uint_eq(1, first.ackCleared);
258 cester_assert_uint_eq(1, secondFired);
259 cester_assert_uint_eq(1, secondAckCleared);
260 spu_irq_expect_u32("rearm.firstPolls", SPU_IRQ_EXPECTED_REARM_FIRST_POLLS, first.polls);
261 spu_irq_expect_u32("rearm.secondPolls", SPU_IRQ_EXPECTED_REARM_SECOND_POLLS, secondPolls);
262)
263
264CESTER_MAYBE_TEST(irq_voice_read_pointer_mid_block_probe, spu_tests,
265 uint32_t hits = 0;
266 uint32_t firstPolls = 0;
267
268 spu_irq_prepare();
269 spu_wait_status_bit11_flip();
270 spu_irq_arm(SPU_IRQ_TEST_ADDR + 8);
271 spu_irq_start_voice1();
272
273 for (uint32_t attempt = 0; attempt < 8; attempt++) {
274 uint32_t polls = spu_irq_poll_until(SPU_IRQ_REARM_TIMEOUT);
275 if (polls != 0) {
276 hits++;
277 if (firstPolls == 0) firstPolls = polls;
279 spu_irq_arm(SPU_IRQ_TEST_ADDR + 8);
280 } else {
281 break;
282 }
283 }
284
285 ramsyscall_printf("OBS spu_irq midblock irq=0x%05x hits=%lu firstPolls=%lu\n",
286 SPU_IRQ_TEST_ADDR + 8, hits, firstPolls);
287
292
295)
cester_assert_uint_eq(5, cause1)
__attribute__((weak))
Definition clz.c:56
#define SPU_VOICES
Definition spu.h:42
#define SPU_STATUS
Definition spu.h:106
#define SPU_KEY_ON_LOW
Definition spu.h:88
#define SPU_VOL_MAIN_LEFT
Definition spu.h:84
#define SPU_CTRL
Definition spu.h:104
#define SPU_VOL_MAIN_RIGHT
Definition spu.h:85
#define SPU_IRQ_ADDR
Definition spu.h:101
#define SPU_KEY_ON_HIGH
Definition spu.h:89
#define CESTER_MAYBE_TEST
Definition cop0.c:34
int i
Definition gte-regio.c:297
__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")
m
Definition gentable.py:52
spu_tests
Definition spu-adpcm-edge.c:189
#define SPU_IRQ_POLL_TIMEOUT
Definition spu-irq.c:51
#define SPU_IRQ_TEST_ADDR
Definition spu-irq.c:49
muteSpu()
#define SPU_IRQ_EXPECTED_REARM_SECOND_POLLS
Definition spu-irq.c:39
spu_irq_expect_u32("midblock.hits", SPU_IRQ_EXPECTED_MIDBLOCK_HITS, hits)
CESTER_BODY(typedef struct { uint32_t irqAddr;uint32_t fired;uint32_t polls;uint32_t statusAtFire;uint32_t statusAfterAck;uint32_t ackCleared;uint32_t currentVolumeAtFire;uint32_t captureFirstNonzero;uint32_t captureLastNonzero;uint32_t captureNonzeroCount;uint32_t captureSum;} SpuIrqMeasurement;static uint8_t s_irqSample __attribute__((aligned(4)));static void spu_irq_make_sample(void) { for(int block=0;block< 8;block++) { uint8_t *p=&s_irqSample[block *16];p[0]=0x00;p[1]=0x00;if(block==0) p[1]=0x06;if(block==7) p[1]=0x03;uint8_t nybble=(uint8_t)((block+1) &7);uint8_t packed=(uint8_t)(nybble|(nybble<< 4));for(int i=2;i< 16;i++) p[i]=packed;} } static void spu_irq_arm(uint32_t byteAddr) { SPU_IRQ_ADDR=(uint16_t)(byteAddr > > 3);SPU_CTRL=(SPU_CTRL &~0x0030)|0x8000|0x4000|0x0040;for(volatile int i=0;i< 120;i++) ;} static uint32_t spu_irq_ack_by_disable(void) { SPU_CTRL=SPU_CTRL &~0x0040;for(uint32_t i=0;i< 100000;i++) { if((SPU_STATUS &0x0040)==0) return 1;} return 0;} static uint32_t spu_irq_poll_until(uint32_t maxPolls) { for(uint32_t i=0;i< maxPolls;i++) { if(SPU_STATUS &0x0040) return i+1;__asm__ volatile("");} return 0;} static void spu_irq_quiet_unused_voices(void) { for(int v=0;v< 24;v++) { SPU_VOICES[v].volumeLeft=0;SPU_VOICES[v].volumeRight=0;SPU_VOICES[v].sampleRate=0x1000;SPU_VOICES[v].sampleStartAddr=SPU_IRQ_DUMMY_ADDR > > 3;SPU_VOICES[v].sampleRepeatAddr=SPU_IRQ_DUMMY_ADDR > > 3;SPU_VOICES[v].adsrLo=0x000f;SPU_VOICES[v].adsrHi=0x1fc0;} SPU_KEY_OFF_LOW=0;SPU_KEY_OFF_HIGH=0;SPU_KEY_ON_LOW=0xffff;SPU_KEY_ON_HIGH=0x00ff;spu_busy_wait(200000);} static void spu_irq_prepare(void) { spu_reset_quiet();spu_irq_make_sample();spu_write_sync(SPU_IRQ_DUMMY_ADDR, kAdpcmSilent, sizeof(kAdpcmSilent));spu_write_sync(SPU_IRQ_TEST_ADDR, s_irqSample, sizeof(s_irqSample));SPU_CTRL=0x8000|0x4000;SPU_VOL_MAIN_LEFT=0;SPU_VOL_MAIN_RIGHT=0;spu_irq_quiet_unused_voices();(void) spu_irq_ack_by_disable();} static void spu_irq_start_voice1(void) { SPU_VOICES[1].volumeLeft=0;SPU_VOICES[1].volumeRight=0;spu_voice1_keyon(SPU_IRQ_TEST_ADDR, 0x1000);} static void spu_irq_analyze_capture(SpuIrqMeasurement *m) { uint32_t first=0xffffffffu;uint32_t last=0;uint32_t count=0;uint32_t sum=0;spu_read_sync(0x0800, s_capture, 1024);for(uint32_t i=0;i< 512;i++) { uint16_t v=s_capture[i];if(v !=0) { if(first==0xffffffffu) first=i;last=i;count++;sum+=v;} } m->captureFirstNonzero=first;m->captureLastNonzero=last;m->captureNonzeroCount=count;m->captureSum=sum;} static void spu_irq_measure_once(uint32_t irqByteAddr, SpuIrqMeasurement *m) { spu_irq_prepare();m->irqAddr=irqByteAddr;spu_wait_status_bit11_flip();spu_irq_arm(irqByteAddr);spu_irq_start_voice1();m->polls=spu_irq_poll_until(SPU_IRQ_POLL_TIMEOUT);m->fired=(m->polls !=0);m->statusAtFire=SPU_STATUS;m->currentVolumeAtFire=SPU_VOICES[1].currentVolume;m->ackCleared=spu_irq_ack_by_disable();m->statusAfterAck=SPU_STATUS;spu_irq_analyze_capture(m);SPU_KEY_OFF_LOW=0xffff;SPU_KEY_OFF_HIGH=0xffff;muteSpu();} static void spu_irq_print_measurement(const char *name, const SpuIrqMeasurement *m) { ramsyscall_printf("OBS spu_irq %s irq=0x%05lx fired=%lu polls=%lu statusFire=0x%04lx " "ackCleared=%lu statusAck=0x%04lx envx=0x%04lx capFirst=%lu capLast=%lu " "capCount=%lu capSum=0x%08lx\n", name, m->irqAddr, m->fired, m->polls, m->statusAtFire &0xffff, m->ackCleared, m->statusAfterAck &0xffff, m->currentVolumeAtFire &0xffff, m->captureFirstNonzero, m->captureLastNonzero, m->captureNonzeroCount, m->captureSum);} static void spu_irq_expect_u32(const char *name, uint32_t expected, uint32_t got) { if(expected==SPU_IRQ_EXPECTED_UNSET) { ramsyscall_printf("OBS spu_irq expected %s=%lu\n", name, got);} else { cester_assert_uint_eq(expected, got);} }[128])
Definition spu-irq.c:54
#define SPU_IRQ_EXPECTED_MIDBLOCK_FIRST_POLLS
Definition spu-irq.c:46
void spu_irq_ack_by_disable()
SPU_KEY_OFF_LOW
Definition spu-irq.c:288
#define SPU_IRQ_EXPECTED_MIDBLOCK_HITS
Definition spu-irq.c:43
#define SPU_IRQ_EXPECTED_REARM_FIRST_POLLS
Definition spu-irq.c:36
SPU_KEY_OFF_HIGH
Definition spu-irq.c:289
#define SPU_IRQ_EXPECTED_ALIGNED_LAST_NONZERO
Definition spu-irq.c:26
#define SPU_IRQ_DUMMY_ADDR
Definition spu-irq.c:50
#define SPU_IRQ_REARM_TIMEOUT
Definition spu-irq.c:52
#define SPU_IRQ_EXPECTED_ALIGNED_POLLS
Definition spu-irq.c:20
#define SPU_IRQ_EXPECTED_ALIGNED_FIRST_NONZERO
Definition spu-irq.c:23
#define SPU_IRQ_EXPECTED_ALIGNED_NONZERO_COUNT
Definition spu-irq.c:29
#define SPU_IRQ_EXPECTED_ALIGNED_SUM
Definition spu-irq.c:32
#define SPU_IRQ_EXPECTED_UNSET
Definition spu-irq.c:16
ramsyscall_printf("OBS spu_irq midblock irq=0x%05x hits=%lu firstPolls=%lu\n", SPU_IRQ_TEST_ADDR+8, hits, firstPolls)
spu_write_sync(0x1000, s_upload, 128)
spu_busy_wait(500000)
spu_reset_quiet()
spu_read_sync(0x1000, s_readback, 0x80)
static const void size_t count
Definition syscalls.h:146
void void(ptr, size)
void uint32_t(classId, spec)