hlide wrote:
First, if i'm not wrong, doing "_sw(1, 0xbc300008);" will enable a ME/SC irq to interrupt the processor, right ?
No, that would enable irq 0. Here's the me init code I use.
Code: Select all
void me_start() {
u32 i;
__asm__("mtc0 %0, $25"::"r"((unsigned int)&me_exc));
pspSdkDisableFPUExceptions();
_sw(0x80000000, 0xbc300008);
__asm__("mfc0 %0, $12":"=r"(i));
i = (i&0xffff00ff)|0x400;
__asm__("mtc0 %0, $12"::"r"(i));
free_lock();
atomic_mtic_halt(1);
while(1) {
me_read_queue();
atomic_check_queue_halt(1);
}
}
See "_sw(0x80000000, 0xbc300008)" enables irq 31, the sysreg irq. To trigger the irq do "_sw(1, 0xbc100044)"
Second, I can see this code :
Code: Select all
lui $k0, 0xBC30
lw $k1, 0($k0)
beq $k1, $0, leave
sw $k1, 0($k0)
the way I may interpret that code is :
1) mask = _lw(0xbc300000);
there is a pending ME/SC irq when bit 0 is set to 1, right ?
2) _sw(1, 0xbc300000);
we clear the pending ME/SC irq with bit 0 set to 1, right ?
No, the bit set is the number of the irq. Bit 0 is irq 0, bit 1 is irq and so on. To clear the irq, write a word with the bit of the irq set.
Since for ME processor we only allow the ME/SC interrupt to occur, doing "mask = _lw(0xbc3000000); if (!mask) _sw(mask, 0xbc3000000);" is quite equivalent to doing 1) and 2), right ?
Not quite, the store is in the delay slot, so it happens unconditionally. The only thing skipped is adding 4 to EPC, so if for some strange reason (I guess a COP0 timer interrupt could occur, may have to account for that), an irq exception occurs without any bits set in 0xbc300000, the me is halted again.