.text
|
.text
|
.align 2
|
.align 2
|
|
|
.global _entry
|
.global _entry
|
_entry:
|
_entry:
|
la a3, _bss_start
|
la a3, _bss_start
|
la a2, _end
|
la a2, _end
|
la gp, _gp
|
la gp, _gp
|
la sp, _stack
|
la sp, _stack
|
la tp, _end + 63
|
la tp, _end + 63
|
and tp, tp, -64
|
and tp, tp, -64
|
|
|
BSS_CLEAR:
|
BSS_CLEAR:
|
# clear the .bss
|
# clear the .bss
|
sw zero, 0(a3)
|
sw zero, 0(a3)
|
addi a3, a3, 4
|
addi a3, a3, 4
|
blt a3, a2, BSS_CLEAR
|
blt a3, a2, BSS_CLEAR
|
|
|
# configure IRQ_VECTOR
|
# configure IRQ_VECTOR
|
la s11, _isr
|
la s11, _isr
|
li s10, 0xf0000000
|
li s10, 0xf0000000
|
sw s11, 0(s10)
|
sw s11, 0(s10)
|
|
|
# jump to main
|
# jump to main
|
jal ra, main
|
jal ra, main
|
|
|
li s10, 0xe0000000 # this will interrupt the simulation (assertion)
|
li s10, 0xe0000000 # this will interrupt the simulation (assertion)
|
sw zero, 0(s10)
|
sw zero, 0(s10)
|
|
|
L1:
|
L1:
|
beq zero, zero, L1
|
beq zero, zero, L1
|
|
|
# interrupt / exception service routine
|
# interrupt / exception service routine
|
.org 0x100
|
.org 0x100
|
.global _isr
|
.global _isr
|
_isr:
|
_isr:
|
nop # this must be a NOP
|
nop # this must be a NOP
|
addi sp, sp, -68
|
addi sp, sp, -68
|
sw ra, 0(sp)
|
sw ra, 0(sp)
|
sw t0, 4(sp)
|
sw t0, 4(sp)
|
sw t1, 8(sp)
|
sw t1, 8(sp)
|
sw t2, 12(sp)
|
sw t2, 12(sp)
|
sw a0, 16(sp)
|
sw a0, 16(sp)
|
sw a1, 20(sp)
|
sw a1, 20(sp)
|
sw a2, 24(sp)
|
sw a2, 24(sp)
|
sw a3, 28(sp)
|
sw a3, 28(sp)
|
sw a4, 32(sp)
|
sw a4, 32(sp)
|
sw a5, 36(sp)
|
sw a5, 36(sp)
|
sw a6, 40(sp)
|
sw a6, 40(sp)
|
sw a7, 44(sp)
|
sw a7, 44(sp)
|
sw t3, 48(sp)
|
sw t3, 48(sp)
|
sw t4, 52(sp)
|
sw t4, 52(sp)
|
sw t5, 56(sp)
|
sw t5, 56(sp)
|
sw t6, 60(sp)
|
sw t6, 60(sp)
|
li s10, 0xf0000040 # read IRQ_EPC
|
li s10, 0xf0000040 # read IRQ_EPC
|
lw s10, 0(s10)
|
lw s10, 0(s10)
|
addi s10, s10, -4 # rollback, last opcode (at EPC) was not commited
|
addi s10, s10, -4 # rollback, last opcode (at EPC) was not commited
|
sw s10, 64(sp)
|
sw s10, 64(sp)
|
lui a1, 0xf0000
|
lui a1, 0xf0000
|
lw a0, 0x10(a1) # read IRQ_CAUSE
|
lw a0, 0x10(a1) # read IRQ_CAUSE
|
lw a2, 0x20(a1) # read IRQ_MASK
|
lw a2, 0x20(a1) # read IRQ_MASK
|
and a0, a0, a2 # pass CAUSE and MASK and the stack pointer to the C handler
|
and a0, a0, a2 # pass CAUSE and MASK and the stack pointer to the C handler
|
addi a1, sp, 0
|
addi a1, sp, 0
|
beq a0, zero, _exception # it's an exception, not an interrupt
|
beq a0, zero, _exception # it's an exception, not an interrupt
|
jal ra, interrupt_handler # jump to C handler
|
jal ra, interrupt_handler # jump to C handler
|
_restore:
|
_restore:
|
lw ra, 0(sp)
|
lw ra, 0(sp)
|
lw t0, 4(sp)
|
lw t0, 4(sp)
|
lw t1, 8(sp)
|
lw t1, 8(sp)
|
lw t2, 12(sp)
|
lw t2, 12(sp)
|
lw a0, 16(sp)
|
lw a0, 16(sp)
|
lw a1, 20(sp)
|
lw a1, 20(sp)
|
lw a2, 24(sp)
|
lw a2, 24(sp)
|
lw a3, 28(sp)
|
lw a3, 28(sp)
|
lw a4, 32(sp)
|
lw a4, 32(sp)
|
lw a5, 36(sp)
|
lw a5, 36(sp)
|
lw a6, 40(sp)
|
lw a6, 40(sp)
|
lw a7, 44(sp)
|
lw a7, 44(sp)
|
lw t3, 48(sp)
|
lw t3, 48(sp)
|
lw t4, 52(sp)
|
lw t4, 52(sp)
|
lw t5, 56(sp)
|
lw t5, 56(sp)
|
lw t6, 60(sp)
|
lw t6, 60(sp)
|
addi sp, sp, 68
|
addi sp, sp, 68
|
ori s11, zero, 0x1
|
ori s11, zero, 0x1
|
li s10, 0xf0000030
|
li s10, 0xf0000030
|
sw s11, 0(s10) # enable interrupts after a few cycles
|
sw s11, 0(s10) # enable interrupts after a few cycles
|
lw s10, -4(sp)
|
lw s10, -4(sp)
|
jalr zero, s10 # context restored, continue
|
jalr zero, s10 # context restored, continue
|
_exception:
|
_exception:
|
addi s10, s10, -4 # s10 is IRQ_EPC-4, actual EPC is IRQ_EPC-8
|
addi s10, s10, -4 # s10 is IRQ_EPC-4, actual EPC is IRQ_EPC-8
|
lw s11, 0(s10) # read opcode
|
lw s11, 0(s10) # read opcode
|
addi a0, s10, 0
|
addi a0, s10, 0
|
addi a1, s11, 0
|
addi a1, s11, 0
|
jal ra, exception_handler # TODO: set rd reg on some exceptions
|
jal ra, exception_handler # TODO: set rd reg on some exceptions
|
jal zero, _restore
|
jal zero, _restore
|
|
|
.global _interrupt_set
|
.global _interrupt_set
|
_interrupt_set:
|
_interrupt_set:
|
li a1, 0xf0000030
|
li a1, 0xf0000030
|
lw a2, 0(a1)
|
lw a2, 0(a1)
|
sw a0, 0(a1)
|
sw a0, 0(a1)
|
addi a0, a2, 0
|
addi a0, a2, 0
|
ret
|
ret
|
|
|
.global setjmp
|
.global setjmp
|
setjmp:
|
setjmp:
|
sw s0, 0(a0)
|
sw s0, 0(a0)
|
sw s1, 4(a0)
|
sw s1, 4(a0)
|
sw s2, 8(a0)
|
sw s2, 8(a0)
|
sw s3, 12(a0)
|
sw s3, 12(a0)
|
sw s4, 16(a0)
|
sw s4, 16(a0)
|
sw s5, 20(a0)
|
sw s5, 20(a0)
|
sw s6, 24(a0)
|
sw s6, 24(a0)
|
sw s7, 28(a0)
|
sw s7, 28(a0)
|
sw s8, 32(a0)
|
sw s8, 32(a0)
|
sw s9, 36(a0)
|
sw s9, 36(a0)
|
# sw gp, 40(a0)
|
# sw gp, 40(a0)
|
sw tp, 44(a0)
|
sw tp, 44(a0)
|
sw sp, 48(a0)
|
sw sp, 48(a0)
|
sw ra, 52(a0)
|
sw ra, 52(a0)
|
ori a0, zero, 0
|
ori a0, zero, 0
|
ret
|
ret
|
|
|
.global longjmp
|
.global longjmp
|
longjmp:
|
longjmp:
|
lw s0, 0(a0)
|
lw s0, 0(a0)
|
lw s1, 4(a0)
|
lw s1, 4(a0)
|
lw s2, 8(a0)
|
lw s2, 8(a0)
|
lw s3, 12(a0)
|
lw s3, 12(a0)
|
lw s4, 16(a0)
|
lw s4, 16(a0)
|
lw s5, 20(a0)
|
lw s5, 20(a0)
|
lw s6, 24(a0)
|
lw s6, 24(a0)
|
lw s7, 28(a0)
|
lw s7, 28(a0)
|
lw s8, 32(a0)
|
lw s8, 32(a0)
|
lw s9, 36(a0)
|
lw s9, 36(a0)
|
# lw gp, 40(a0)
|
# lw gp, 40(a0)
|
lw tp, 44(a0)
|
lw tp, 44(a0)
|
lw sp, 48(a0)
|
lw sp, 48(a0)
|
lw ra, 52(a0)
|
lw ra, 52(a0)
|
ori a0, a1, 0
|
ori a0, a1, 0
|
ret
|
ret
|
|
|
.global _restoreexec
|
|
_restoreexec:
|
|
lw s0, 0(a0)
|
|
lw s1, 4(a0)
|
|
lw s2, 8(a0)
|
|
lw s3, 12(a0)
|
|
lw s4, 16(a0)
|
|
lw s5, 20(a0)
|
|
lw s6, 24(a0)
|
|
lw s7, 28(a0)
|
|
lw s8, 32(a0)
|
|
lw s9, 36(a0)
|
|
# lw gp, 40(a0)
|
|
lw tp, 44(a0)
|
|
lw sp, 48(a0)
|
|
lw ra, 52(a0)
|
|
|
|
ori s11, zero, 0x1
|
|
li s10, 0xf0000030
|
|
|
|
ori a0, a1, 0
|
|
sw s11, 0(s10) # enable interrupts
|
|
|
|
ret
|
|
|
|
No newline at end of file
|
No newline at end of file
|