here we go. 
i'm posting my mestub.s which can handle exceptions and be polled by SC processor, which is proved to be useful when developping on ME processor :
- _me_print_exception() : dump ME registers saved when a ME exception occured.
- _me_exception_regs : array of registers where to copy when an exception raises so that you can dump them with 
- _me_report_exception: boolean to indicate whether a ME exception occured.
I'm still longing for how to activate int31 in ME processor so SC processor can signal it. And how to install an interrupt handler for int31 on SC processor for ME processor to signal it.
Code: Select all
#define zr              $0
#define at              $1
#define v0              $2
#define v1              $3
#define a0              $4
#define a1              $5
#define a2              $6
#define a3              $7
#define a4              $8
#define a5              $9
#define a6              $10
#define a7              $11
#define t0              $8
#define t1              $9
#define t2              $10
#define t3              $11
#define t4              $12
#define t5              $13
#define t6              $14
#define t7              $15
#define t8              $24
#define t9              $25
#define s0              $16
#define s1              $17
#define s2              $18
#define s3              $19
#define s4              $20
#define s5              $21
#define s6              $22
#define s7              $23
#define s8              $30
#define k0              $26
#define k1              $27
#define gp              $28
#define sp              $29
#define fp              $30
#define ra              $31
.set noreorder
.set noat
.extern _me_exception_regs
.global me_stub
me_stub:
        li              k0, 0xbc100000
        li              t0, 7
        sw              t0, 80(k0)
        mtc0            zr, $28
        mtc0            zr, $29
        li              k1, 8192
0:      addi            k1, k1, -64
        bne             k1, zr, 0b
        cache           0x01, 0(k1)
        li              k1, 8192
0:      addi            k1, k1, -64
        bne             k1, zr, 0b
        cache           0x11, 0(k1)
        mtc0            zr, $13
        li              k0, 0x20000000
        mtc0            k0, $12
        sync
        li              v1, 0x80000000
        la              v0, me_exception_vector_table
        or              v0, v1, v0      
        ctc0            v0, $8
        la              v0, me_ebase
        or              v0, v1, v0
        li              t0, 0xbfc00000
        
        mtc0            v0, $25
        li              t0, 0xbfc00000
        lw              a0, 0x604(t0)
        lw              k0, 0x600(t0) 
        li              sp, 0x80200000
        jr              k0      
        nop
.global me_stub_end
me_stub_end:
.global me_interrupt
me_interrupt:
        sync       
        lui             at, 0xbc10
        addiu           v0, zr, 0x0001
        sw              v0, 0x0044(at)
        jr              ra
        sync       
.global me_leave_critical_session
.global me_unlock_mutex
me_leave_critical_session:
me_unlock_mutex:
        sync       
        lui             at, 0xbc10
        sw              zr, 0x0048(at)
        jr              ra
        sync       
.global me_try_lock_mutex
me_try_lock_mutex:
        mfc0            a0, $22
        sync       
        addiu           a0, a0, 1
        lui             at, 0xbc10
        sw              a0, 0x0048(at)
        sync
        lw              v0, 0x0048(at)
        jr              ra
        xor             v0, a0, v0
.global me_enter_critical_session
me_enter_critical_session:
        mfc0            a0, $22
        sync       
        addiu           a0, a0, 1
        lui             at, 0xbc10
        andi            a0, a0, 3
        sw              a0, 0x0048(at)
0:      sync
        lw              v0, 0x0048(at)
        sync
        andi            v0, v0, 3
        bne             v0, a0, 0b
        sw              a0, 0x0048(at)
        jr              ra
        nop
me_exc_31_error_handler:
        ctc0            v0, $4
        ctc0            v1, $5
        mfc0            v0, $30
        mfc0            v1, $12
        ctc0            v0, $1
        mtc0            v1, $19
        mfc0            v0, $13
        ctc0            v0, $20                 
        b               me_exception_handler
        ori             v0, zr, (31<<2)
me_ebase:
        ctc0            v0, $4
        ctc0            v1, $5
        lui             v0, 0x1FF0
        lui             v1, 0xBC20
        ori             v0, 0x01FF
        sw              v0, (v1)
        mfc0            v0, $13
        mfc0            v1, $14
        ctc0            v0, $3
        ctc0            v1, $0
        andi            v0, 0x7C
me_exception_handler:
        cfc0            v1, $8
        addu            v0, v1, v0
        lw              v0, (v0)
        jr              v0
        nop
        
        .p2align 6      
me_exception_vector_table:
        .long           me_default_irq_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_sys_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
        .long           me_default_exc_handler
.global _me_report_exception
_me_report_exception:
        .long           0
        
#define ZR              4*6
#define AT              ZR + 4
#define V0              AT + 4
#define V1              V0 + 4
#define A0              V1 + 4
#define A1              A0 + 4
#define A2              A1 + 4
#define A3              A2 + 4
#define T0              A3 + 4
#define T1              T0 + 4
#define T2              T1 + 4
#define T3              T2 + 4
#define T4              T3 + 4
#define T5              T4 + 4
#define T6              T5 + 4
#define T7              T6 + 4
#define S0              T7 + 4
#define S1              S0 + 4
#define S2              S1 + 4
#define S3              S2 + 4
#define S4              S3 + 4
#define S5              S4 + 4
#define S6              S5 + 4
#define S7              S6 + 4
#define T8              S7 + 4
#define T9              T8 + 4
#define K0              T9 + 4
#define K1              K0 + 4
#define GP              K1 + 4
#define SP              GP + 4
#define S8              SP + 4
#define RA              S8 + 4
#define STATUS          RA + 4
#define LO              STATUS + 4
#define HI              LO + 4
#define BADVADDR        HI + 4
#define CAUSE           BADVADDR + 4
#define EPC             CAUSE + 4
#define F0              EPC + 4
#define F1              F0 + 4
#define F2              F1 + 4
#define F3              F2 + 4
#define F4              F3 + 4
#define F5              F4 + 4
#define F6              F5 + 4
#define F7              F6 + 4
#define F8              F7 + 4
#define F9              F8 + 4
#define F10             F9 + 4
#define F11             F10 + 4
#define F12             F11 + 4
#define F13             F12 + 4
#define F14             F13 + 4
#define F15             F14 + 4
#define F16             F15 + 4
#define F17             F16 + 4
#define F18             F17 + 4
#define F19             F18 + 4
#define F20             F19 + 4
#define F21             F20 + 4
#define F22             F21 + 4
#define F23             F22 + 4
#define F24             F23 + 4
#define F25             F24 + 4
#define F26             F25 + 4
#define F27             F26 + 4
#define F28             F27 + 4
#define F29             F28 + 4
#define F30             F29 + 4
#define F31             F30 + 4
#define FSR             F31 + 4
#define FIR             FSR + 4
#define FP              FIR + 4
        .p2align 6      
me_default_irq_handler:
me_default_exc_handler:
me_default_sys_handler:
        lui             v1, 0xa000
        la              v0, _me_exception_regs
        or              v0, v1, v0
        mfic            v1, $0
        mtic            zr, $0
        sw              at, AT(v0)
        cfc0            at, $4
        sw              at, V0(v0)
        cfc0            at, $5
        sw              at, V1(v0)
        sw              a0, A0(v0)
        sw              a1, A1(v0)
        sw              a2, A2(v0)
        sw              a3, A3(v0)
        sw              t0, T0(v0)
        sw              t1, T1(v0)
        sw              t2, T2(v0)
        sw              t3, T3(v0)
        sw              t4, T4(v0)
        sw              t5, T5(v0)
        sw              t6, T6(v0)
        sw              t7, T7(v0)
        sw              s0, S0(v0)
        sw              s1, S1(v0)
        sw              s2, S2(v0)
        sw              s3, S3(v0)
        sw              s4, S4(v0)
        sw              s5, S5(v0)
        sw              s6, S6(v0)
        sw              s7, S7(v0)
        sw              t8, T8(v0)
        sw              t9, T9(v0)
        sw              k0, K0(v0)
        sw              k1, K1(v0)
        sw              gp, GP(v0)
        sw              sp, SP(v0)
        sw              s8, S8(v0)
        sw              ra, RA(v0)
        
        mfhi            a0
        mflo            a1
        sw              a0, HI(v0)
        sw              a1, LO(v0)
        
        mfc0            a0, $8
        mfc0            a1, $12
        mfc0            a2, $13
        mfc0            a3, $14
        sw              a0, BADVADDR(v0)
        lui             a0, 0x2000
        sw              a1, STATUS(v0)
        and             a0, a0, a1
        sw              a2, CAUSE(v0)
        beq             a0, zr, 0f
        sw              a3, EPC(v0)
        swc1            $0, F0(v0)
        swc1            $1, F1(v0)
        swc1            $2, F2(v0)
        swc1            $3, F3(v0)
        swc1            $4, F4(v0)
        swc1            $5, F5(v0)
        swc1            $6, F6(v0)
        swc1            $7, F7(v0)
        swc1            $8, F8(v0)
        swc1            $9, F9(v0)
        swc1            $10, F10(v0)
        swc1            $11, F11(v0)
        swc1            $12, F12(v0)
        swc1            $13, F13(v0)
        swc1            $14, F14(v0)
        swc1            $15, F15(v0)
        swc1            $16, F16(v0)
        swc1            $17, F17(v0)
        swc1            $18, F18(v0)
        swc1            $19, F19(v0)
        swc1            $20, F20(v0)
        swc1            $21, F21(v0)
        swc1            $22, F22(v0)
        swc1            $23, F23(v0)
        swc1            $24, F24(v0)
        swc1            $25, F25(v0)
        swc1            $26, F26(v0)
        swc1            $27, F27(v0)
        swc1            $28, F28(v0)
        swc1            $29, F29(v0)
        swc1            $30, F30(v0)
        swc1            $31, F31(v0)
        cfc1            a0, $31
        cfc1            a1, $0
        sw              a0, FSR(v0)
        sw              a1, FIR(v0)
        ctc1            zr, $31
0:      sw              sp, FP(v0)
        mtic            v1, $0
        
        sync
        lui             v0, 0xa000
        lui             at, %hi(_me_report_exception)
        or              at, at, v0
        nor             v0, zr, zr
        sw              v0, %lo(_me_report_exception)(at)
        sync
        
0:      b               0b
        nop
Code: Select all
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspctrl.h>
#include <pspdisplay.h>
#include <stdlib.h>
#include <string.h>
PSP_MODULE_INFO("ME", 0x1000, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_VFPU);
#define printf	pspDebugScreenPrintf
void me_stub(void);
void me_stub_end(void);
void me_interrupt();
void me_enter_critical_session();
void me_leave_critical_session();
static void me_startup(u32 func, u32 param)
{
  memcpy((void *)0xbfc00040, me_stub, (int)(me_stub_end - me_stub));
  _sw(func, 0xbfc00600);
  _sw(param, 0xbfc00604);
  sceKernelDcacheWritebackAll();
  sceSysregMeResetEnable();
  sceSysregMeBusClockEnable();
  sceSysregMeResetDisable();
}
volatile unsigned int g_counter1 = 0;
volatile unsigned int g_counter2 = 0;
static __attribute__((aligned(64))) int g_data[0x200000/sizeof(int)];
void me_test_exception(int param)
{
  volatile unsigned int *pctr1 = (volatile unsigned int *)(((int)&g_counter1)|0x40000000);
  volatile unsigned int *pctr2 = (volatile unsigned int *)(((int)&g_counter2)|0x40000000);
  volatile unsigned int *vptr1 = (volatile unsigned int *)((int)g_data|0x40000000);
  volatile unsigned int *vptr2 = (volatile unsigned int *)(0x88000000);
  while (1)
  {
    if (*pctr1)
      _sw(1, 0); // <- exception
  }
}
void me_test_memory(int param)
{
  volatile unsigned int *pctr1 = (volatile unsigned int *)(((int)&g_counter1)|0x40000000);
  volatile unsigned int *pctr2 = (volatile unsigned int *)(((int)&g_counter2)|0x40000000);
  volatile unsigned int *vptr1 = (volatile unsigned int *)((int)g_data|0x40000000);
  volatile unsigned int *vptr2 = (volatile unsigned int *)(0x88000000);
  while (1)
  {
    if (*pctr1)
    {
      me_enter_critical_session();
      while (1)
      {
        *pctr2 = vptr2;
        *vptr1++ = *vptr2++;
        if ((int)vptr2 >= (0x88200000))
        {
          *pctr1 = 0;
          break;
        }
      }
    
      me_leave_critical_session();
      _sw(1, 0); // <- exception
    }
  }
}
#define mfc0(reg) ({ unsigned int res; asm volatile ("mfc0 %0, $%1" : "=r"(res) : "i"(reg)); res; })
#define cfc0(reg) ({ unsigned int res; asm volatile ("cfc0 %0, $%1" : "=r"(res) : "i"(reg)); res; })
void read_cop0_registers(int param)
{
  volatile unsigned int *pctr1 = (volatile unsigned int *)(((int)&g_counter1)|0x40000000);
  volatile unsigned int *vptr1 = (volatile unsigned int *)((int)g_data|0x40000000);
loop:
  while (!(*pctr1));
  me_enter_critical_session();
  if (*pctr1)
  {
    *vptr1++ = mfc0(0);
    *vptr1++ = mfc0(1);
    *vptr1++ = mfc0(2);
    *vptr1++ = mfc0(3);
    *vptr1++ = mfc0(4);
    *vptr1++ = mfc0(5);
    *vptr1++ = mfc0(6);
    *vptr1++ = mfc0(7);
    *vptr1++ = mfc0(8);
    *vptr1++ = mfc0(9);
    *vptr1++ = mfc0(10);
    *vptr1++ = mfc0(11);
    *vptr1++ = mfc0(12);
    *vptr1++ = mfc0(13);
    *vptr1++ = mfc0(14);
    *vptr1++ = mfc0(15);
    *vptr1++ = mfc0(16);
    *vptr1++ = mfc0(17);
    *vptr1++ = mfc0(18);
    *vptr1++ = mfc0(19);
    *vptr1++ = mfc0(20);
    *vptr1++ = mfc0(21);
    *vptr1++ = mfc0(22);
    *vptr1++ = mfc0(23);
    *vptr1++ = mfc0(24);
    *vptr1++ = mfc0(25);
    *vptr1++ = mfc0(26);
    *vptr1++ = mfc0(27);
    *vptr1++ = mfc0(28);
    *vptr1++ = mfc0(29);
    *vptr1++ = mfc0(30);
    *vptr1++ = mfc0(31);
    *vptr1++ = cfc0(0);
    *vptr1++ = cfc0(1);
    *vptr1++ = cfc0(2);
    *vptr1++ = cfc0(3);
    *vptr1++ = cfc0(4);
    *vptr1++ = cfc0(5);
    *vptr1++ = cfc0(6);
    *vptr1++ = cfc0(7);
    *vptr1++ = cfc0(8);
    *vptr1++ = cfc0(9);
    *vptr1++ = cfc0(10);
    *vptr1++ = cfc0(11);
    *vptr1++ = cfc0(12);
    *vptr1++ = cfc0(13);
    *vptr1++ = cfc0(14);
    *vptr1++ = cfc0(15);
    *vptr1++ = cfc0(16);
    *vptr1++ = cfc0(17);
    *vptr1++ = cfc0(18);
    *vptr1++ = cfc0(19);
    *vptr1++ = cfc0(20);
    *vptr1++ = cfc0(21);
    *vptr1++ = cfc0(22);
    *vptr1++ = cfc0(23);
    *vptr1++ = cfc0(24);
    *vptr1++ = cfc0(25);
    *vptr1++ = cfc0(26);
    *vptr1++ = cfc0(27);
    *vptr1++ = cfc0(28);
    *vptr1++ = cfc0(29);
    *vptr1++ = cfc0(30);
    *vptr1++ = cfc0(31);
    *pctr1 = 0;
  }
  me_leave_critical_session();
 
  goto loop; 
}
void save_file(const char *data, unsigned int n, const char *name)
{
  int fdout;
  fdout = sceIoOpen(name, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777);
  sceIoWrite(fdout, data, n);
  sceIoClose(fdout);
}
void load_file(const char *data, unsigned int n, const char *name)
{
  int fdin;
  fdin = sceIoOpen(name, PSP_O_RDONLY, 0777);
  sceIoRead(fdin, data, n);
  sceIoClose(fdin);
}
static void wait()
{
  while (1)
  {
    SceCtrlData pad;
    sceCtrlReadBufferNegative(&pad, 1);
    if (pad.Buttons & PSP_CTRL_CROSS)
      break;
  }
  while (1)
  {
    SceCtrlData pad;
    sceCtrlReadBufferPositive(&pad, 1);
    if (pad.Buttons & PSP_CTRL_CROSS)
      break;
  }
}
void sc_exception_handler(PspDebugRegBlock *regs)
{
  pspDebugScreenInit();
  pspDebugScreenSetBackColor(0x00FF0000);
  pspDebugScreenSetTextColor(0xFFFFFFFF);
  pspDebugScreenClear();
  pspDebugScreenPrintf("\nSC - Exception Details:\n");
  pspDebugDumpException(regs);
  pspDebugScreenPrintf("\n\nPress 'cross' button to exit.");
  wait();
  sceKernelExitGame();
}
PspDebugRegBlock __attribute__((aligned(16))) _me_exception_regs;
extern int _me_report_exception;
static void _me_print_exception()
{
  pspDebugScreenInit();
  pspDebugScreenSetBackColor(0x00FF0000);
  pspDebugScreenSetTextColor(0xFFFFFFFF);
  pspDebugScreenClear();
  pspDebugScreenPrintf("\nME - Exception Details:\n");
  pspDebugDumpException((PspDebugRegBlock *)(((int)&_me_exception_regs)|0xa0000000));
  pspDebugScreenPrintf("\n\nPress 'cross' button to exit.");
  wait();
  sceKernelExitGame();
}
int main(int argc, char *argv[])
{
  SceCtrlData ctl;
  pspDebugScreenInit();
  sceCtrlSetSamplingCycle(0);
  sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL);
  pspDebugInstallErrorHandler(sc_exception_handler);
  me_startup((unsigned)me_test_exception, 0x10000);
  while (1)
  {
    volatile unsigned int *pctr1 = (volatile unsigned int *)(((int)&g_counter1)|0x40000000); // uncached read pointer
    volatile unsigned int *pctr2 = (volatile unsigned int *)(((int)&g_counter2)|0x40000000); // uncached read pointer
    volatile unsigned int *pctr3 = (volatile unsigned int *)(((int)&_me_report_exception)|0x40000000);
    me_enter_critical_session();
    *pctr1 = 1;
    me_leave_critical_session();
    while (*pctr1)
    {
      if (*pctr3)
        _me_print_exception();
    }
    me_enter_critical_session();
    unsigned int val1 = *pctr1;
    unsigned int val2 = *pctr2;
    unsigned int val3 = *pctr3;
    me_leave_critical_session();
    pspDebugScreenSetXY(0, 0);
    pspDebugScreenPrintf("ME test, press Home to exit\n");
    pspDebugScreenPrintf("ME : %08x, %08x\n", val1, val2);
    
    while(1)
    {
      sceCtrlReadBufferPositive(&ctl, 1);
    
      if(ctl.Buttons & PSP_CTRL_HOME)
      {
        save_file(((int)g_data|0x40000000), 0x200000, "ms0:/me.bin");
        sceKernelExitGame();
      }
      sceDisplayWaitVblankStart();
      if (val3)
        _me_print_exception();
    }
  }
  return 0;
}
EDIT: it seems I mess up with critical session so i need to investigate why...