Skip to content

Commit

Permalink
fixup : take comments into account
Browse files Browse the repository at this point in the history
  • Loading branch information
mean committed Feb 18, 2024
1 parent c6cf38d commit 022a638
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 64 deletions.
26 changes: 25 additions & 1 deletion src/target/flashstub/riscv32_flashstub.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
#pragma once
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2015 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef TARGET_RISCV_FLASHSTUB_STUB_H
#define TARGET_RISCV_FLASHSTUB_STUB_H


/*
* exit stub, 0 means OK, else error code
Expand All @@ -8,3 +30,5 @@ static inline void __attribute__((always_inline)) riscv_stub_exit(const int code
__asm__("li a0, %0 \n"
"ebreak" ::"i"(code));
}

#endif
114 changes: 51 additions & 63 deletions src/target/riscv32.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "general.h"
#include "target.h"
#include "target_internal.h"
Expand Down Expand Up @@ -671,31 +670,24 @@ static int riscv32_breakwatch_clear(target_s *const target, breakwatch_s *const
return riscv_config_trigger(hart, breakwatch->reserved[0], RISCV_TRIGGER_MODE_UNUSED, &config, &address) ? 0 : -1;
}

#define RISCV_REG_A0 10
#define RISCV_REG_A1 11
#define RISCV_REG_A2 12
#define RISCV_REG_A3 13
#define RISCV_REG_PC 32
#define RISCV_REG_SP 2

/*
Small helper function to translate target to hart and simplify parameters
We assume it is 32 bits
*/
static bool riscv32_target_csr_write(target_s *target, const uint16_t reg, uint32_t val)
static inline bool riscv32_target_csr_write(target_s *target, const uint16_t reg, uint32_t val)
{
riscv_hart_s *const hart = riscv_hart_struct(target);
return riscv_csr_write(hart, reg, &val);
riscv_hart_s *const hart = riscv_hart_struct(target);
return riscv_csr_write(hart, reg, &val);
}

/*
Small helper function to translate target to hart and simplify parameters
We assume it is 32 bits
*/
static bool riscv32_target_csr_read(target_s *target, const uint16_t reg, uint32_t *val)
static inline bool riscv32_target_csr_read(target_s *target, const uint16_t reg, uint32_t *val)
{
riscv_hart_s *const hart = riscv_hart_struct(target);
return riscv_csr_read(hart, reg, val);
riscv_hart_s *const hart = riscv_hart_struct(target);
return riscv_csr_read(hart, reg, val);
}

/*
Expand All @@ -707,55 +699,51 @@ static bool riscv32_target_csr_read(target_s *target, const uint16_t reg, uint32
It returns true on success, false on error
There is a built-in timeout of 10 seconds
*/
bool riscv32_run_stub(target_s *t, uint32_t codeexec, uint32_t param1, uint32_t param2, uint32_t param3,
uint32_t param4)
bool riscv32_run_stub(
target_s *target, uint32_t loadaddr, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4)
{
bool ret = false;
uint32_t pc, mie, zero = 0;
// save PC & MIE
t->reg_read(t, RISCV_REG_PC, &pc, 4);
riscv32_target_csr_read(t, RV_CSR_MIE, &mie);
riscv32_target_csr_write(t, RV_CSR_MIE, zero); // disable interrupt
t->reg_write(t, RISCV_REG_A0, &param1, 4);
t->reg_write(t, RISCV_REG_A1, &param2, 4);
t->reg_write(t, RISCV_REG_A2, &param3, 4);
t->reg_write(t, RISCV_REG_A3, &param4, 4);
t->reg_write(t, RISCV_REG_PC, &codeexec, 4);

target_halt_reason_e reason = TARGET_HALT_RUNNING;
t->halt_resume(t, false); // go!
platform_timeout_s timeout;
platform_timeout_set(&timeout, 10000);
while (reason == TARGET_HALT_RUNNING)
{
if (platform_timeout_is_expired(&timeout))
{
goto the_end;
}
reason = t->halt_poll(t, NULL);
}

if (reason == TARGET_HALT_ERROR)
{
goto the_end;
}

if (reason != TARGET_HALT_REQUEST)
{
goto the_end;
}
ret = true;
bool ret = false;
uint32_t pc = 0;
uint32_t mie = 0;
uint32_t zero = 0;
// save PC & MIE
target->reg_read(target, RISCV_REG_PC, &pc, 4);
riscv32_target_csr_read(target, RV_CSR_MIE, &mie);
riscv32_target_csr_write(target, RV_CSR_MIE, zero); // disable interrupt
target->reg_write(target, RISCV_REG_A0, &param1, 4);
target->reg_write(target, RISCV_REG_A1, &param2, 4);
target->reg_write(target, RISCV_REG_A2, &param3, 4);
target->reg_write(target, RISCV_REG_A3, &param4, 4);
target->reg_write(target, RISCV_REG_PC, &loadaddr, 4);

target_halt_reason_e reason = TARGET_HALT_RUNNING;
target->halt_resume(target, false); // go!
platform_timeout_s timeout;
platform_timeout_set(&timeout, 10000);
while (reason == TARGET_HALT_RUNNING) {
if (platform_timeout_is_expired(&timeout)) {
goto the_end;
}
reason = target->halt_poll(target, NULL);
}

if (reason == TARGET_HALT_ERROR) {
goto the_end;
}

if (reason != TARGET_HALT_REQUEST) {
goto the_end;
}
ret = true;
the_end:
t->halt_request(t);
if (ret)
{
uint32_t a0;
t->reg_read(t, RISCV_REG_A0, &a0, 4);
ret = (a0 == 0);
}
// restore PC & MIE
riscv32_target_csr_write(t, RV_CSR_MIE, mie); // put back MIE
t->reg_write(t, RISCV_REG_PC, &pc, 4);
return ret;
target->halt_request(target);
if (ret) {
uint32_t a0;
target->reg_read(target, RISCV_REG_A0, &a0, 4);
ret = (a0 == 0);
}
// restore PC & MIE
riscv32_target_csr_write(target, RV_CSR_MIE, mie); // put back MIE
target->reg_write(target, RISCV_REG_PC, &pc, 4);
return ret;
}
//----
8 changes: 8 additions & 0 deletions src/target/riscv_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,14 @@ typedef struct riscv_hart {
#define RV_FPU_GDB_OFFSET 33
#define RV_FPU_GDB_CSR_OFFSET 66

// General purpose registers
#define RISCV_REG_A0 10
#define RISCV_REG_A1 11
#define RISCV_REG_A2 12
#define RISCV_REG_A3 13
#define RISCV_REG_PC 32
#define RISCV_REG_SP 2

void riscv_jtag_dtm_handler(uint8_t dev_index);
void riscv_dmi_init(riscv_dmi_s *dmi);
riscv_hart_s *riscv_hart_struct(target_s *target);
Expand Down

0 comments on commit 022a638

Please sign in to comment.