1 |
59 |
zero_gravi |
/* ################################################################################################# */
|
2 |
62 |
zero_gravi |
/* # << NEORV32 - park_loop.S - Execution-Based On-Chip Debugger - Park Loop Code >> # */
|
3 |
59 |
zero_gravi |
/* # ********************************************************************************************* # */
|
4 |
|
|
/* # BSD 3-Clause License # */
|
5 |
|
|
/* # # */
|
6 |
|
|
/* # Copyright (c) 2021, Stephan Nolting. All rights reserved. # */
|
7 |
|
|
/* # # */
|
8 |
|
|
/* # Redistribution and use in source and binary forms, with or without modification, are # */
|
9 |
|
|
/* # permitted provided that the following conditions are met: # */
|
10 |
|
|
/* # # */
|
11 |
|
|
/* # 1. Redistributions of source code must retain the above copyright notice, this list of # */
|
12 |
|
|
/* # conditions and the following disclaimer. # */
|
13 |
|
|
/* # # */
|
14 |
|
|
/* # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # */
|
15 |
|
|
/* # conditions and the following disclaimer in the documentation and/or other materials # */
|
16 |
|
|
/* # provided with the distribution. # */
|
17 |
|
|
/* # # */
|
18 |
|
|
/* # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # */
|
19 |
|
|
/* # endorse or promote products derived from this software without specific prior written # */
|
20 |
|
|
/* # permission. # */
|
21 |
|
|
/* # # */
|
22 |
|
|
/* # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # */
|
23 |
|
|
/* # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # */
|
24 |
|
|
/* # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # */
|
25 |
|
|
/* # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # */
|
26 |
|
|
/* # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # */
|
27 |
|
|
/* # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # */
|
28 |
|
|
/* # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # */
|
29 |
|
|
/* # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # */
|
30 |
|
|
/* # OF THE POSSIBILITY OF SUCH DAMAGE. # */
|
31 |
|
|
/* # ********************************************************************************************* # */
|
32 |
|
|
/* # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # */
|
33 |
|
|
/* ################################################################################################# */
|
34 |
|
|
|
35 |
|
|
// debug memory address map
|
36 |
|
|
.equ DBMEM_CODE_BASE, 0xfffff800 // base address of dbmem.code_memory
|
37 |
|
|
.equ DBMEM_PBUF_BASE, 0xfffff880 // base address of dbmem.program_buffer
|
38 |
|
|
.equ DBMEM_DBUF_BASE, 0xfffff900 // base address of dbmem.data_buffer
|
39 |
|
|
.equ DBMEM_SREG_BASE, 0xfffff980 // base address of dbmem.status_register
|
40 |
|
|
|
41 |
|
|
// status register (SREG) bits
|
42 |
|
|
.equ SREG_HALTED_ACK, (1<<0) // -/w: CPU is halted in debug mode and waits in park loop
|
43 |
|
|
.equ SREG_RESUME_REQ, (1<<1) // r/-: DM requests CPU to resume
|
44 |
|
|
.equ SREG_RESUME_ACK, (1<<2) // -/w: CPU starts resuming
|
45 |
|
|
.equ SREG_EXECUTE_REQ, (1<<3) // r/-: DM requests to execute program buffer
|
46 |
|
|
.equ SREG_EXECUTE_ACK, (1<<4) // -/w: CPU starts to execute program buffer
|
47 |
|
|
.equ SREG_EXCEPTION_ACK, (1<<5) // -/w: CPU has detected an exception
|
48 |
|
|
|
49 |
60 |
zero_gravi |
.file "park_loop.S"
|
50 |
59 |
zero_gravi |
.section .text
|
51 |
|
|
.balign 4
|
52 |
|
|
.option norvc
|
53 |
|
|
.global _start
|
54 |
|
|
.global entry_normal
|
55 |
|
|
.global entry_exception
|
56 |
|
|
|
57 |
|
|
|
58 |
|
|
_start:
|
59 |
|
|
|
60 |
62 |
zero_gravi |
// BASE + 0: entry for ebreak in debug-mode, halt request or return from single-stepped instruction
|
61 |
59 |
zero_gravi |
entry_normal:
|
62 |
|
|
jal zero, parking_loop_start
|
63 |
|
|
|
64 |
60 |
zero_gravi |
// BASE + 4: entry for exceptions - signal EXCEPTION to DM and restart parking loop
|
65 |
59 |
zero_gravi |
entry_exception:
|
66 |
|
|
csrw dscratch0, s0 // save s0 to dscratch0 so we have a general purpose register available
|
67 |
|
|
addi s0, zero, SREG_EXCEPTION_ACK // mask exception acknowledge flag
|
68 |
|
|
sw s0, DBMEM_SREG_BASE(zero) // trigger exception acknowledge to inform DM
|
69 |
|
|
csrr s0, dscratch0 // restore s0 from dscratch0
|
70 |
|
|
ebreak // restart parking loop
|
71 |
|
|
|
72 |
|
|
// "parking loop": endless loop that polls the status register to check if the DM
|
73 |
|
|
// wants to execute code from the program buffer or to resume normal CPU/application operation
|
74 |
|
|
parking_loop_start:
|
75 |
|
|
csrw dscratch0, s0 // save s0 to dscratch0 so we have a general purpose register available
|
76 |
|
|
addi s0, zero, SREG_HALTED_ACK
|
77 |
|
|
sw s0, DBMEM_SREG_BASE(zero) // ACK that CPU has halted
|
78 |
|
|
|
79 |
|
|
parking_loop:
|
80 |
|
|
lw s0, DBMEM_SREG_BASE(zero) // get status register
|
81 |
|
|
andi s0, s0, SREG_EXECUTE_REQ // request to execute program buffer?
|
82 |
|
|
bnez s0, execute_progbuf // execute program buffer
|
83 |
|
|
|
84 |
|
|
lw s0, DBMEM_SREG_BASE(zero) // get status register
|
85 |
|
|
andi s0, s0, SREG_RESUME_REQ // request to resume?
|
86 |
|
|
bnez s0, resume // resume normal operation
|
87 |
|
|
|
88 |
|
|
jal zero, parking_loop // restart parking loop polling
|
89 |
|
|
|
90 |
|
|
// resume normal operation
|
91 |
|
|
resume:
|
92 |
|
|
addi s0, zero, SREG_RESUME_ACK
|
93 |
|
|
sw s0, DBMEM_SREG_BASE(zero) // ACK that CPU is about to resume
|
94 |
|
|
csrr s0, dscratch0 // restore s0 from dscratch0
|
95 |
|
|
dret // end debug mode
|
96 |
|
|
|
97 |
|
|
// execute program buffer
|
98 |
|
|
execute_progbuf:
|
99 |
|
|
addi s0, zero, SREG_EXECUTE_ACK
|
100 |
|
|
sw s0, DBMEM_SREG_BASE(zero) // ACK that execution is about to start
|
101 |
|
|
csrr s0, dscratch0 // restore s0 from dscratch0
|
102 |
61 |
zero_gravi |
fence.i // synchronize i-cache & prefetch with memory (program buffer)
|
103 |
59 |
zero_gravi |
jalr zero, zero, %lo(DBMEM_PBUF_BASE) // jump to beginning of program buffer
|