peer-review
Your code jumps immediately to the infinite kernel loop when you do syscall. To fix this you should move the loop to the bottom of the program so that the other kernel code runs first. This is because it jumps to the start of kernel code when syscall is called and currently the loop is positioned there.
Also your return to user function does not return to the user unfortunately. To fix this you can replace this(woked for me)
mtc0 $k0, $14 rfe nop
with jr $k0 rfe
and also add nops after each mtc0 instruction in the kernel handeling
Otherwise it is well commented and structured.