diff --git a/src/target/riscv32.c b/src/target/riscv32.c
index da3b11eb481..08c7d0534bd 100644
--- a/src/target/riscv32.c
+++ b/src/target/riscv32.c
@@ -68,6 +68,7 @@ typedef struct riscv32_regs {
 #define RV32_MATCH_AFTER  0x00040000U
 
 static void riscv32_regs_read(target_s *target, void *data);
+static void riscv32_regs_write(target_s *target, const void *data);
 static void riscv32_mem_read(target_s *target, void *dest, target_addr_t src, size_t len);
 
 static int riscv32_breakwatch_set(target_s *target, breakwatch_s *breakwatch);
@@ -88,6 +89,7 @@ bool riscv32_probe(target_s *const target)
 	/* Provide the length of a suitable registers structure */
 	target->regs_size = sizeof(riscv32_regs_s);
 	target->regs_read = riscv32_regs_read;
+	target->regs_write = riscv32_regs_write;
 	target->mem_read = riscv32_mem_read;
 
 	target->breakwatch_set = riscv32_breakwatch_set;
@@ -122,6 +124,21 @@ static void riscv32_regs_read(target_s *const target, void *const data)
 	riscv_csr_read(hart, RV_DPC, &regs->pc);
 }
 
+static void riscv32_regs_write(target_s *const target, const void *const data)
+{
+	/* Grab the hart structure and figure out how many registers need reading out */
+	riscv_hart_s *const hart = riscv_hart_struct(target);
+	riscv32_regs_s *const regs = (riscv32_regs_s *)data;
+	const size_t gprs_count = hart->extensions & RV_ISA_EXT_EMBEDDED ? 16U : 32U;
+	/* Loop through writing out the GPRs, except for the first which is always 0 */
+	for (size_t gpr = 1; gpr < gprs_count; ++gpr) {
+		// TODO: handle when this fails..
+		riscv_csr_write(hart, RV_GPR_BASE + gpr, &regs->gprs[gpr]);
+	}
+	/* Special access to poke in the program counter that will be executed on resuming the hart */
+	riscv_csr_write(hart, RV_DPC, &regs->pc);
+}
+
 /* Takes in data from abstract command arg0 and, based on the access width, unpacks it to dest */
 void riscv32_unpack_data(void *const dest, const uint32_t data, const uint8_t access_width)
 {
diff --git a/src/target/riscv64.c b/src/target/riscv64.c
index 2f21551c87a..c156fa8c450 100644
--- a/src/target/riscv64.c
+++ b/src/target/riscv64.c
@@ -43,6 +43,7 @@ typedef struct riscv64_regs {
 } riscv64_regs_s;
 
 static void riscv64_regs_read(target_s *target, void *data);
+static void riscv64_regs_write(target_s *target, const void *data);
 static void riscv64_mem_read(target_s *target, void *dest, target_addr_t src, size_t len);
 
 bool riscv64_probe(target_s *const target)
@@ -52,6 +53,7 @@ bool riscv64_probe(target_s *const target)
 	/* Provide the length of a suitable registers structure */
 	target->regs_size = sizeof(riscv64_regs_s);
 	target->regs_read = riscv64_regs_read;
+	target->regs_write = riscv64_regs_write;
 	target->mem_read = riscv64_mem_read;
 
 	return true;
@@ -72,6 +74,21 @@ static void riscv64_regs_read(target_s *const target, void *const data)
 	riscv_csr_read(hart, RV_DPC, &regs->pc);
 }
 
+static void riscv64_regs_write(target_s *const target, const void *const data)
+{
+	/* Grab the hart structure and figure out how many registers need reading out */
+	riscv_hart_s *const hart = riscv_hart_struct(target);
+	riscv64_regs_s *const regs = (riscv64_regs_s *)data;
+	const size_t gprs_count = hart->extensions & RV_ISA_EXT_EMBEDDED ? 16U : 32U;
+	/* Loop through writing out the GPRs, except for the first which is always 0 */
+	for (size_t gpr = 1; gpr < gprs_count; ++gpr) {
+		// TODO: handle when this fails..
+		riscv_csr_write(hart, RV_GPR_BASE + gpr, &regs->gprs[gpr]);
+	}
+	/* Special access to poke in the program counter that will be executed on resuming the hart */
+	riscv_csr_write(hart, RV_DPC, &regs->pc);
+}
+
 /* Takes in data from abstract command arg0 and, based on the access width, unpacks it to dest */
 void riscv64_unpack_data(
 	void *const dest, const uint32_t data_low, const uint32_t data_high, const uint8_t access_width)