b0be7fc1494db28c151f9c8a45030ce6aa104480
[riscv-isa-sim.git] / debug_rom / debug_rom.S
1 # This code should be functional. Doesn't have to be optimal.
2 # I'm writing it to prove that it can be done.
3
4 #include "riscv/encoding.h"
5
6 # TODO: Update these constants once they're finalized in the doc.
7
8 #define DEBUG_RAM 0x400
9 #define DEBUG_RAM_SIZE 64
10
11 #define CLEARDEBINT 0x100
12 #define SETHALTNOT 0x10c
13
14 .global entry
15 .global resume
16 .global exception
17
18 # Automatically called when Debug Mode is first entered.
19 entry: j _entry
20 # Should be called by Debug RAM code that has finished execution and
21 # wants to return to Debug Mode.
22 resume:
23 j _resume
24 exception:
25 # Set the last word of Debug RAM to all ones, to indicate that we hit
26 # an exception.
27 li s0, ~0
28 j _resume2
29
30 _resume:
31 li s0, 0
32 _resume2:
33 fence
34
35 # Restore s1.
36 csrr s1, CSR_MISA
37 bltz s1, restore_not_32
38 restore_32:
39 lw s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 4)(zero)
40 j finish_restore
41 restore_not_32:
42 slli s1, s1, 1
43 bltz s1, restore_128
44 restore_64:
45 ld s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 8)(zero)
46 j finish_restore
47 restore_128:
48 nop #lq s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 16)(zero)
49
50 finish_restore:
51 # s0 contains ~0 if we got here through an exception, and 0 otherwise.
52 # Store this to the last word in Debug RAM so the debugger can tell if
53 # an exception occurred.
54 sw s0, (DEBUG_RAM + DEBUG_RAM_SIZE - 4)(zero)
55
56 # Clear debug interrupt.
57 csrr s0, CSR_MHARTID
58 sw s0, CLEARDEBINT(zero)
59
60 check_halt:
61 csrr s0, CSR_DCSR
62 andi s0, s0, DCSR_HALT
63 beqz s0, exit
64 j wait_for_interrupt
65
66 exit:
67 # Restore s0.
68 csrr s0, CSR_DSCRATCH
69 dret
70
71 _entry:
72 # Save s0 in DSCRATCH
73 csrw CSR_DSCRATCH, s0
74
75 # Check why we're here
76 csrr s0, CSR_DCSR
77 # cause is in bits 8:6 of dcsr
78 andi s0, s0, DCSR_CAUSE
79 addi s0, s0, -(DCSR_CAUSE_DEBUGINT<<6)
80 bnez s0, spontaneous_halt
81
82 jdebugram:
83 # Save s1 so that the debug program can use two registers.
84 fence.i
85 csrr s0, CSR_MISA
86 bltz s0, save_not_32
87 save_32:
88 sw s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 4)(zero)
89 jr zero, DEBUG_RAM
90 save_not_32:
91 slli s0, s0, 1
92 bltz s0, save_128
93 save_64:
94 sd s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 8)(zero)
95 jr zero, DEBUG_RAM
96 save_128:
97 nop #sq s1, (DEBUG_RAM + DEBUG_RAM_SIZE - 16)(zero)
98 jr zero, DEBUG_RAM
99
100 spontaneous_halt:
101 csrr s0, CSR_MHARTID
102 sw s0, SETHALTNOT(zero)
103 csrsi CSR_DCSR, DCSR_HALT
104
105 wait_for_interrupt:
106 csrr s0, CSR_DCSR
107 andi s0, s0, DCSR_DEBUGINT
108 beqz s0, wait_for_interrupt
109
110 j jdebugram