[07/10] libpdbg: Add in mtocrf and putcr function

Message ID 20180531052915.31171-7-rashmica.g@gmail.com
State Changes Requested
Headers show
Series
  • [01/10] libpdbg: Print the name of the instruction when erroring
Related show

Commit Message

Rashmica Gupta May 31, 2018, 5:29 a.m.
Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
---
 libpdbg/chip.c       | 36 ++++++++++++++++++++++++++++++++++++
 libpdbg/libpdbg.h    |  1 +
 libpdbg/operations.h |  1 +
 3 files changed, 38 insertions(+)

Comments

Alistair Popple June 15, 2018, 1:39 a.m. | #1
On Thursday, 31 May 2018 3:29:12 PM AEST Rashmica Gupta wrote:
> Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
> ---
>  libpdbg/chip.c       | 36 ++++++++++++++++++++++++++++++++++++
>  libpdbg/libpdbg.h    |  1 +
>  libpdbg/operations.h |  1 +
>  3 files changed, 38 insertions(+)
> 
> diff --git a/libpdbg/chip.c b/libpdbg/chip.c
> index b698bcd..a4642fd 100644
> --- a/libpdbg/chip.c
> +++ b/libpdbg/chip.c
> @@ -60,6 +60,20 @@ static uint64_t mfocrf(uint64_t reg, uint64_t cr)
>  	return MFOCRF_OPCODE | (reg << 21) | (1U << (12 + cr));
>  }
>  
> +static uint64_t mtocrf(uint64_t cr, uint64_t reg)
> +{
> +	if (reg > 31) {
> +		PR_ERROR("Invalid register specified for mfocrf\n");
> +		exit(1);

Same comment here as the previous patch in the series.

> +	}
> +	if (cr > 7) {
> +		PR_ERROR("Invalid CR field specified\n");
> +		exit(1);
> +	}
> +
> +	return MTOCRF_OPCODE | (reg << 21) | (1U << (12 + cr));
> +}
> +
>  static uint64_t mfnia(uint64_t reg)
>  {
>  	if (reg > 31) {
> @@ -368,6 +382,28 @@ int ram_getcr(struct pdbg_target *thread, uint64_t *value)
>  	return 0;
>  }
>  
> +int ram_putcr_field(struct pdbg_target *thread, int cr, uint64_t value)
> +{
> +	uint64_t opcodes[] = {mfspr(0, 277), mtocrf(cr, 0)};
> +	uint64_t results[] = {value, 0};
> +
> +	CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
> +	return 0;
> +}
> +
> +int ram_putcr(struct pdbg_target *thread, uint64_t value)
> +{
> +	uint64_t cr_field;
> +	int i;
> +
> +	for (i = 0; i < 8; i++){
> +		cr_field = value & (0xf << 4*i);

Guessing we don't actually have to do this as the other bits shouldn't get
written anyway right? Otherwise we'd be zeroing the other fields. If this is the
case we should probably remove this to reduce future confusion :-)

> +		ram_putcr_field(thread, i, cr_field);
> +	}
> +
> +	return 0;
> +}
> +
>  int ram_putmsr(struct pdbg_target *thread, uint64_t value)
>  {
>  	uint64_t opcodes[] = {mfspr(0, 277), mtmsr(0)};
> diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h
> index 7f09caa..14645a3 100644
> --- a/libpdbg/libpdbg.h
> +++ b/libpdbg/libpdbg.h
> @@ -141,6 +141,7 @@ int ram_putspr(struct pdbg_target *target, int spr, uint64_t val);
>  int ram_putgpr(struct pdbg_target *target, int spr, uint64_t val);
>  int ram_getmsr(struct pdbg_target *target, uint64_t *val);
>  int ram_getcr(struct pdbg_target *thread,  uint64_t *value);
> +int ram_putcr(struct pdbg_target *thread,  uint64_t value);
>  int ram_getnia(struct pdbg_target *target, uint64_t *val);
>  int ram_getspr(struct pdbg_target *target, int spr, uint64_t *val);
>  int ram_getgpr(struct pdbg_target *target, int gpr, uint64_t *val);
> diff --git a/libpdbg/operations.h b/libpdbg/operations.h
> index c7e3218..74baed8 100644
> --- a/libpdbg/operations.h
> +++ b/libpdbg/operations.h
> @@ -73,6 +73,7 @@
>  #define MFXERF2_OPCODE 0x00000210UL
>  #define MFXERF3_OPCODE 0x00000310UL
>  #define MFOCRF_OPCODE 0x7c100026UL
> +#define MTOCRF_OPCODE 0x7C100120UL
>  #define MFSPR_MASK (MFSPR_OPCODE | ((0x1f) << 16) | ((0x3e0) << 6))
>  #define MFXER_OPCODE (MFSPR_OPCODE | ((1 & 0x1f) << 16) | ((1 & 0x3e0) << 6))
>  #define MTXER_OPCODE (MTSPR_OPCODE | ((1 & 0x1f) << 16) | ((1 & 0x3e0) << 6))
>

Patch

diff --git a/libpdbg/chip.c b/libpdbg/chip.c
index b698bcd..a4642fd 100644
--- a/libpdbg/chip.c
+++ b/libpdbg/chip.c
@@ -60,6 +60,20 @@  static uint64_t mfocrf(uint64_t reg, uint64_t cr)
 	return MFOCRF_OPCODE | (reg << 21) | (1U << (12 + cr));
 }
 
+static uint64_t mtocrf(uint64_t cr, uint64_t reg)
+{
+	if (reg > 31) {
+		PR_ERROR("Invalid register specified for mfocrf\n");
+		exit(1);
+	}
+	if (cr > 7) {
+		PR_ERROR("Invalid CR field specified\n");
+		exit(1);
+	}
+
+	return MTOCRF_OPCODE | (reg << 21) | (1U << (12 + cr));
+}
+
 static uint64_t mfnia(uint64_t reg)
 {
 	if (reg > 31) {
@@ -368,6 +382,28 @@  int ram_getcr(struct pdbg_target *thread, uint64_t *value)
 	return 0;
 }
 
+int ram_putcr_field(struct pdbg_target *thread, int cr, uint64_t value)
+{
+	uint64_t opcodes[] = {mfspr(0, 277), mtocrf(cr, 0)};
+	uint64_t results[] = {value, 0};
+
+	CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
+	return 0;
+}
+
+int ram_putcr(struct pdbg_target *thread, uint64_t value)
+{
+	uint64_t cr_field;
+	int i;
+
+	for (i = 0; i < 8; i++){
+		cr_field = value & (0xf << 4*i);
+		ram_putcr_field(thread, i, cr_field);
+	}
+
+	return 0;
+}
+
 int ram_putmsr(struct pdbg_target *thread, uint64_t value)
 {
 	uint64_t opcodes[] = {mfspr(0, 277), mtmsr(0)};
diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h
index 7f09caa..14645a3 100644
--- a/libpdbg/libpdbg.h
+++ b/libpdbg/libpdbg.h
@@ -141,6 +141,7 @@  int ram_putspr(struct pdbg_target *target, int spr, uint64_t val);
 int ram_putgpr(struct pdbg_target *target, int spr, uint64_t val);
 int ram_getmsr(struct pdbg_target *target, uint64_t *val);
 int ram_getcr(struct pdbg_target *thread,  uint64_t *value);
+int ram_putcr(struct pdbg_target *thread,  uint64_t value);
 int ram_getnia(struct pdbg_target *target, uint64_t *val);
 int ram_getspr(struct pdbg_target *target, int spr, uint64_t *val);
 int ram_getgpr(struct pdbg_target *target, int gpr, uint64_t *val);
diff --git a/libpdbg/operations.h b/libpdbg/operations.h
index c7e3218..74baed8 100644
--- a/libpdbg/operations.h
+++ b/libpdbg/operations.h
@@ -73,6 +73,7 @@ 
 #define MFXERF2_OPCODE 0x00000210UL
 #define MFXERF3_OPCODE 0x00000310UL
 #define MFOCRF_OPCODE 0x7c100026UL
+#define MTOCRF_OPCODE 0x7C100120UL
 #define MFSPR_MASK (MFSPR_OPCODE | ((0x1f) << 16) | ((0x3e0) << 6))
 #define MFXER_OPCODE (MFSPR_OPCODE | ((1 & 0x1f) << 16) | ((1 & 0x3e0) << 6))
 #define MTXER_OPCODE (MTSPR_OPCODE | ((1 & 0x1f) << 16) | ((1 & 0x3e0) << 6))