1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
.set noreorder
.include "hwregs_a.h"
.set ISR_STACK_SIZE, 4096
.section .text
# Global ISR handler of PSn00bSDK
.set at
.type _global_isr, @function
_global_isr:
.Lisr_loop:
#la $gp, _gp # Keep restoring GP since it gets
# changed elsewhere sometimes
lui $a0, IOBASE # Get IRQ status
lw $v0, IMASK($a0)
nop
srl $v0, $s1 # Check IRQ mask bit if set
andi $v0, 0x1
beqz $v0, .Lno_irq # Don't execute callback if IRQ not enabled
nop
lw $v0, ISTAT($a0)
nop
srl $v0, $s1 # Check IRQ status bit if set
andi $v0, 0x1
beqz $v0, .Lno_irq # Don't execute callback if no IRQ
nop
lw $v1, 0($s0) # Load IRQ callback function
nop
lw $v0, ISTAT($a0) # Acknowledge the IRQ (by writing a 0 bit)
li $a1, 1
sll $a1, $s1
addiu $a2, $0 , -1
xor $a1, $a2
sw $a1, ISTAT($a0)
beqz $v1, .Lno_irq # Don't execute if callback is not set
nop
jalr $v1 # Call interrupt handler
nop
.Lno_irq:
addiu $s0, 4
blt $s1, 11, .Lisr_loop
addiu $s1, 1
j ReturnFromException
nop
.section .data
# Global ISR callback table
.global _irq_func_table
.type _irq_func_table, @object
_irq_func_table:
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
# Global ISR hook structure
.global _custom_exit
.type _custom_exit, @object
_custom_exit:
.word _global_isr # pc
.word _isr_stack+ISR_STACK_SIZE # sp
.word 0 # fp
.word _irq_func_table # s0
.word 0 # s1
.word 0 # s2
.word 0 # s3
.word 0 # s4
.word 0 # s5
.word 0 # s6
.word 0 # s7
.word _gp # gp
# Global ISR stack
# .fill 1024
#_custom_exit_stack:
# .fill 4
.comm _isr_stack, ISR_STACK_SIZE+4
|