Hello MIPS hackers,
as I've mailed before the DECstation kernel crashes because the return from the
very first syscall instruction does not work properly. After two weeks of
playing my favourite adventure game "Leisure Suit Harry looking for bugs (in
several wrong places)" I think I have found the cause (but not the cure).
This is the begin of the RESTORE_ALL macro, which is used in ret_from_sys_call:
#define RESTORE_ALL \
mfc0 t0, CP0_STATUS; \
nop; \
ori t0, 0x01; \
xori t0, 0x01; \
mtc0 t0, CP0_STATUS; \
lw v0, PT_STATUS(sp); \
lw v1, PT_LO(sp); \
mtc0 v0, CP0_STATUS; \
mtlo v1; \
lw v0, PT_HI(sp); \
lw v1, PT_EPC(sp); \
mthi v0; \
mtc0 v1, CP0_EPC; \
..
PT_EPC is manipulated in do_sys to point behind the syscall instruction and a
PRINT(...) shows that v1 contains the correct value. Nevertheless CP0_EPC
remains to be unchanged.
After finding that, I used the following test code:
#define RESTORE_ALL_TEST \
lui v0,0xffff; \
mtc0 v0,CP0_EPC; \
nop; \
mfc0 a1,CP0_EPC; \
nop; \
PRINT("CP0_EPC : %08x\n"); \
which "compiles" into:
800375d0 <return_test> lui $v0,0xffff
800375d4 <return_test+4> mtc0 $v0,$14
800375dc <return_test+c> mfc0 $a1,$14
800375e4 <return_test+14> lui $a0,0x800c
800375e8 <return_test+18> jal 80054478 <printk>
800375ec <return_test+1c> addiu $a0,$a0,5680
and the result is:
CP0_EPC : 80036aa4
which is the address of the syscall instruction itself. But the result should be
0xFFFF0000, shouldn't it?.
Has anybody an explanation for this, or am I just completely blind?
---
regards,
Harald
|