|
Nugget
Bare-metal libraries and examples for the original PlayStation
|
#include "common/hardware/counters.h"#include "common/hardware/hwregs.h"#include "common/syscalls/syscalls.h"#include "exotic/cester.h"
Macros | |
| #define | PCSX_TESTS 0 |
| #define | CESTER_MAYBE_TEST CESTER_TEST |
| #define | CESTER_NO_SIGNAL |
| #define | CESTER_NO_TIME |
| #define | EXIT_SUCCESS 0 |
| #define | EXIT_FAILURE 1 |
| #define | TIMER_TARGET 300 |
| #define | IRQ_LIMIT 1000 |
| #define | ITERATIONS 200000 |
Functions | |
| CESTER_BODY (uint32_t pairLoop(uint32_t iterations);extern uint32_t pairStart[], pairB1[], pairB2[], pairT1[], pairEnd[];void installExceptionHandlers(uint32_t(*handler)(uint32_t *regs, uint32_t from));void uninstallExceptionHandlers();static volatile uint32_t s_irqs;static volatile uint32_t s_other;static volatile uint32_t s_atB2BD;static volatile uint32_t s_atB2NoBD;static volatile uint32_t s_atT1;static volatile uint32_t s_atB1;static volatile uint32_t s_atB1BD;static volatile uint32_t s_inside;static volatile uint32_t s_outside;static volatile uint32_t s_bdTotal;static uint32_t s_ref, s_irq, s_srAfter;static uint32_t handler(uint32_t *regs, uint32_t from) { uint32_t cause, epc;asm volatile("mfc0 %0, $13\nnop\nmfc0 %1, $14\nnop" :"=r"(cause), "=r"(epc));if((cause &0x7c) !=0) { s_other++;return epc+4;} IREG=~(1u<< 6);(void) COUNTERS[2].mode;s_irqs++;int bd=(cause > > 31) &1;s_bdTotal+=bd;if(epc==(uint32_t) pairB2) { if(bd) s_atB2BD++;else s_atB2NoBD++;} else if(epc==(uint32_t) pairT1) { s_atT1++;} else if(epc==(uint32_t) pairB1) { if(bd) s_atB1BD++;else s_atB1++;} else if(epc >=(uint32_t) pairStart &&epc<=(uint32_t) pairEnd+4) { s_inside++;} else { s_outside++;} if(s_irqs >=IRQ_LIMIT) COUNTERS[2].mode=0;return epc;} static uint32_t getSR() { uint32_t sr;asm volatile("mfc0 %0, $12\nnop" :"=r"(sr));return sr;} static void setSR(uint32_t sr) { asm volatile("mtc0 %0, $12\nnop\nnop" ::"r"(sr));}) CESTER_BEFORE_ALL(irq_branch_slot_tests | |
| setSR (oldSR &~1u) | |
| installExceptionHandlers (handler) | |
| syscall_flushCache () | |
| setSR ((oldSR &~0x1fu)|0x401u) | |
| setSR (getSR() &~1u) | |
| uninstallExceptionHandlers () | |
| setSR (oldSR) | |
| ramsyscall_printf ("IRQBRANCHSLOT: OBS target=%d irqs=%d other=%d B2_bd=%d B2_nobd=%d T1=%d B1=%d B1_bd=%d inside=%d outside=%d bd_total=%d ref=0x%08x irq=0x%08x srAfter=0x%08x\n", TIMER_TARGET, s_irqs, s_other, s_atB2BD, s_atB2NoBD, s_atT1, s_atB1, s_atB1BD, s_inside, s_outside, s_bdTotal, s_ref, s_irq, s_srAfter) | |
| CESTER_TEST (irq_branch_slot_irqs_handled, irq_branch_slot_tests, cester_assert_uint_ge(s_irqs, IRQ_LIMIT);cester_assert_uint_eq(0, s_other);uint32_t iec=s_srAfter &1;cester_assert_uint_eq(1, iec);) CESTER_MAYBE_TEST(irq_branch_slot_epc_on_inner_branch | |
| cester_assert_uint_ne (0, s_atB2BD) | |
Variables | |
| uint32_t | oldSR = getSR() |
| uint32_t | oldIMASK = IMASK |
| IMASK = 0 | |
| IREG = 0 | |
| s_ref = pairLoop(ITERATIONS) | |
| COUNTERS[2] | mode = 0 |
| COUNTERS[2] | value = 0 |
| COUNTERS[2] | target = TIMER_TARGET |
| s_irq = pairLoop(ITERATIONS) | |
| s_srAfter = getSR() | |
| irq_branch_slot_tests | |
| #define CESTER_MAYBE_TEST CESTER_TEST |
| #define CESTER_NO_SIGNAL |
| #define CESTER_NO_TIME |
| #define EXIT_FAILURE 1 |
| #define EXIT_SUCCESS 0 |
| #define IRQ_LIMIT 1000 |
| #define ITERATIONS 200000 |
| #define PCSX_TESTS 0 |
| #define TIMER_TARGET 300 |
| cester_assert_uint_ne | ( | 0 | , |
| s_atB2BD | |||
| ) |
| CESTER_BODY | ( | uint32_t pairLoop(uint32_t iterations);extern uint32_t | pairStart[], |
| pairB1 | [], | ||
| pairB2 | [], | ||
| pairT1 | [], | ||
| pairEnd;[]void installExceptionHandlers(uint32_t(*handler)(uint32_t *regs, uint32_t from));void uninstallExceptionHandlers();static volatile uint32_t s_irqs;static volatile uint32_t s_other;static volatile uint32_t s_atB2BD;static volatile uint32_t s_atB2NoBD;static volatile uint32_t s_atT1;static volatile uint32_t s_atB1;static volatile uint32_t s_atB1BD;static volatile uint32_t s_inside;static volatile uint32_t s_outside;static volatile uint32_t s_bdTotal;static uint32_t | s_ref, | ||
| s_irq | , | ||
| s_srAfter;static uint32_t handler(uint32_t *regs, uint32_t from) { uint32_t cause, epc;asm volatile("mfc0 %0, $13\nnop\nmfc0 %1, $14\nnop" :"=r"(cause), "=r"(epc));if((cause &0x7c) !=0) { s_other++;return epc+4;} IREG=~(1u<< 6);(void) COUNTERS[2].mode;s_irqs++;int bd=(cause > > 31) &1;s_bdTotal+=bd;if(epc==(uint32_t) pairB2) { if(bd) s_atB2BD++;else s_atB2NoBD++;} else if(epc==(uint32_t) pairT1) { s_atT1++;} else if(epc==(uint32_t) pairB1) { if(bd) s_atB1BD++;else s_atB1++;} else if(epc >=(uint32_t) pairStart &&epc<=(uint32_t) pairEnd+4) { s_inside++;} else { s_outside++;} if(s_irqs >=IRQ_LIMIT) COUNTERS[2].mode=0;return epc;} static uint32_t getSR() { uint32_t sr;asm volatile("mfc0 %0, $12\nnop" :"=r"(sr));return sr;} static void setSR(uint32_t sr) { asm volatile("mtc0 %0, $12\nnop\nnop" ::"r"(sr));} | |||
| ) |
| CESTER_TEST | ( | irq_branch_slot_irqs_handled | , |
| irq_branch_slot_tests | , | ||
| cester_assert_uint_ge(s_irqs, IRQ_LIMIT);cester_assert_uint_eq(0, s_other);uint32_t | iec = s_srAfter & 1; cester_assert_uint_eq(1, iec); |
||
| ) |
| installExceptionHandlers | ( | handler | ) |
| ramsyscall_printf | ( | ) |
| setSR | ( | (oldSR &~0x1fu)| | 0x401u | ) |
| setSR | ( | getSR() &~ | 1u | ) |
| setSR | ( | oldSR &~ | 1u | ) |
| setSR | ( | oldSR | ) |
| syscall_flushCache | ( | ) |
| uninstallExceptionHandlers | ( | ) |
| IMASK = 0 |
| IREG = 0 |
| irq_branch_slot_tests |
| COUNTERS [2] mode = 0 |
| uint32_t oldSR = getSR() |
| s_irq = pairLoop(ITERATIONS) |
| s_ref = pairLoop(ITERATIONS) |
| s_srAfter = getSR() |
| COUNTERS [2] target = TIMER_TARGET |
| COUNTERS [2] value = 0 |