Skip to content

Commit 8cca9f7

Browse files
committed
Implement c.ebreak properly
Add the breakpoint exception handler which triggers a breakpoint exception when the c.ebreak instruction is executed.
1 parent 09f4e65 commit 8cca9f7

File tree

4 files changed

+42
-3
lines changed

4 files changed

+42
-3
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,9 @@ Current progress of this emulator in riscv-arch-test(RV32):
8282
* Passed Tests
8383
- `I`: Base Integer Instruction Set
8484
- `M`: Standard Extension for Integer Multiplication and Division
85+
- `C`: Standard Extension for Compressed Instruction
8586
- `Zifencei`: Instruction-Fetch Fence
8687
* Failed Tests
87-
- `C`: Standard Extension for Compressed Instruction
88-
+ `cebreak`
8988
- `privilege`: RISCV Privileged Specification
9089
+ 2 system calls
9190
* `ebreak`

src/emulate.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,37 @@ static void rv_except_illegal_insn(struct riscv_t *rv, uint32_t insn)
148148
rv->csr_mcause = code;
149149
}
150150

151+
static void rv_except_breakpoint(struct riscv_t *rv, uint32_t old_pc)
152+
{
153+
/* mtvec (Machine Trap-Vector Base Address Register)
154+
* mtvec[MXLEN-1:2]: vector base address
155+
* mtvec[1:0] : vector mode
156+
*/
157+
const uint32_t base = rv->csr_mtvec & ~0x3;
158+
const uint32_t mode = rv->csr_mtvec & 0x3;
159+
160+
/* Exception Code: Breakpoint */
161+
const uint32_t code = 3;
162+
163+
/* mepc (Machine Exception Program Counter)
164+
* mtval(Machine Trap Value Register) : Breakpoint
165+
*/
166+
rv->csr_mepc = old_pc;
167+
rv->csr_mtval = old_pc;
168+
169+
switch (mode) {
170+
case 0: /* DIRECT: All exceptions set PC to base */
171+
rv->PC = base;
172+
break;
173+
case 1: /* VECTORED: Asynchronous interrupts set PC to base + 4 * code */
174+
rv->PC = base + 4 * code;
175+
break;
176+
}
177+
178+
/* mcause (Machine Cause Register): store exception code */
179+
rv->csr_mcause = code;
180+
}
181+
151182
/* RV32I Base Instruction Set
152183
*
153184
* bits 0-6: opcode
@@ -2189,3 +2220,9 @@ void rv_reset(struct riscv_t *rv, riscv_word_t pc)
21892220

21902221
rv->halt = false;
21912222
}
2223+
2224+
void breakpoint_handler(struct riscv_t *rv)
2225+
{
2226+
assert(rv);
2227+
rv_except_breakpoint(rv, rv->PC);
2228+
}

src/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ int main(int argc, char **args)
186186

187187
/* system */
188188
.on_ecall = syscall_handler,
189-
.on_ebreak = rv_halt,
189+
.on_ebreak = breakpoint_handler,
190190
};
191191

192192
state_t *state = state_new();

src/riscv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ riscv_word_t rv_get_reg(struct riscv_t *, uint32_t reg);
125125
/* system call handler */
126126
void syscall_handler(struct riscv_t *rv);
127127

128+
/* breakpoint exception handler */
129+
void breakpoint_handler(struct riscv_t *rv);
130+
128131
/* halt the core */
129132
void rv_halt(struct riscv_t *);
130133

0 commit comments

Comments
 (0)