Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
Macros | Functions | Variables
irq-branch-slot.c File Reference
#include "common/hardware/counters.h"
#include "common/hardware/hwregs.h"
#include "common/syscalls/syscalls.h"
#include "exotic/cester.h"
Include dependency graph for irq-branch-slot.c:

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
 

Macro Definition Documentation

◆ CESTER_MAYBE_TEST

#define CESTER_MAYBE_TEST   CESTER_TEST

◆ CESTER_NO_SIGNAL

#define CESTER_NO_SIGNAL

◆ CESTER_NO_TIME

#define CESTER_NO_TIME

◆ EXIT_FAILURE

#define EXIT_FAILURE   1

◆ EXIT_SUCCESS

#define EXIT_SUCCESS   0

◆ IRQ_LIMIT

#define IRQ_LIMIT   1000

◆ ITERATIONS

#define ITERATIONS   200000

◆ PCSX_TESTS

#define PCSX_TESTS   0

◆ TIMER_TARGET

#define TIMER_TARGET   300

Function Documentation

◆ cester_assert_uint_ne()

cester_assert_uint_ne ( 0  ,
s_atB2BD   
)

◆ CESTER_BODY()

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()

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()

installExceptionHandlers ( handler  )

◆ ramsyscall_printf()

ramsyscall_printf ( )

◆ setSR() [1/4]

setSR ( (oldSR &~0x1fu)|  0x401u)

◆ setSR() [2/4]

setSR ( getSR() &~  1u)

◆ setSR() [3/4]

setSR ( oldSR &~  1u)

◆ setSR() [4/4]

setSR ( oldSR  )

◆ syscall_flushCache()

syscall_flushCache ( )

◆ uninstallExceptionHandlers()

uninstallExceptionHandlers ( )

Variable Documentation

◆ IMASK

IMASK = 0

◆ IREG

IREG = 0

◆ irq_branch_slot_tests

irq_branch_slot_tests

◆ mode

COUNTERS [2] mode = 0

◆ oldIMASK

uint32_t oldIMASK = IMASK

◆ oldSR

uint32_t oldSR = getSR()

◆ s_irq

s_irq = pairLoop(ITERATIONS)

◆ s_ref

s_ref = pairLoop(ITERATIONS)

◆ s_srAfter

s_srAfter = getSR()

◆ target

COUNTERS [2] target = TIMER_TARGET

◆ value

COUNTERS [2] value = 0