diff mbox series

[12/19] libpdbg: Add in enable_attn function for p8

Message ID 20180829015047.7355-13-rashmica.g@gmail.com
State Superseded
Headers show
Series Basic gdbserver for POWER8 | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success master/apply_patch Successfully applied
snowpatch_ozlabs/build-multiarch success Test build-multiarch on branch master

Commit Message

Rashmica Gupta Aug. 29, 2018, 1:50 a.m. UTC
Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
---
 libpdbg/p8chip.c | 41 +++++++++++++++++++++++++++++++++++++++++
 libpdbg/target.h |  1 +
 2 files changed, 42 insertions(+)

Comments

Nicholas Piggin Aug. 29, 2018, 7:57 a.m. UTC | #1
On Wed, 29 Aug 2018 11:50:40 +1000
Rashmica Gupta <rashmica.g@gmail.com> wrote:

> Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
> ---
>  libpdbg/p8chip.c | 41 +++++++++++++++++++++++++++++++++++++++++
>  libpdbg/target.h |  1 +
>  2 files changed, 42 insertions(+)
> 
> diff --git a/libpdbg/p8chip.c b/libpdbg/p8chip.c
> index 89ecfd6..2f1d599 100644
> --- a/libpdbg/p8chip.c
> +++ b/libpdbg/p8chip.c
> @@ -82,6 +82,8 @@
>  #define  FSP_SPECIAL_WAKEUP		PPC_BIT(0)
>  #define EX_PM_GP0_REG			0xf0100
>  #define  SPECIAL_WKUP_DONE		PPC_BIT(31)
> +#define HID0_REG                 	0x1329c
> +#define EN_ATTN                 	PPC_BIT(31)
>  
>  /* p8 specific opcodes for instruction ramming*/
>  #define MTXERF0_OPCODE 0x00000008UL
> @@ -483,6 +485,44 @@ static int p8_thread_probe(struct pdbg_target *target)
>  	return 0;
>  }
>  
> +static int p8_get_hid0(struct pdbg_target *chip, uint64_t *value)
> +{
> +	CHECK_ERR(pib_read(chip, HID0_REG, value));
> +	return 0;
> +}
> +
> +static int p8_put_hid0(struct pdbg_target *chip, uint64_t value)
> +{
> +	CHECK_ERR(pib_write(chip, HID0_REG, value));
> +	return 0;
> +}
> +
> +static int p8_enable_attn(struct pdbg_target *target)
> +{
> +	struct pdbg_target *core;
> +	uint64_t hid0;
> +
> +	core = pdbg_target_parent("core", target);
> +	if (core == NULL)
> +	{
> +		PR_ERROR("CORE NOT FOUND\n");
> +		return 1;
> +	}
> +
> +	/* Need to enable the attn instruction in HID0 */
> +	if (p8_get_hid0(core, &hid0)) {
> +		PR_ERROR("Unable to get HID0\n");
> +		return 1;
> +	}
> +	hid0 |= EN_ATTN;
> +
> +	if (p8_put_hid0(core, hid0)) {
> +		PR_ERROR("Unable to set HID0\n");
> +		return 1;
> +	}
> +	return 0;
> +}
> +

>  static struct thread p8_thread = {
>  	.target = {
>  		.name = "POWER8 Thread",
> @@ -499,6 +539,7 @@ static struct thread p8_thread = {
>  	.ram_destroy = p8_ram_destroy,
>  	.ram_getxer = p8_ram_getxer,
>  	.ram_putxer = p8_ram_putxer,
> +	.enable_attn = p8_enable_attn,
>  };
>  DECLARE_HW_UNIT(p8_thread);
>  
> diff --git a/libpdbg/target.h b/libpdbg/target.h
> index 8bad405..c8da048 100644
> --- a/libpdbg/target.h
> +++ b/libpdbg/target.h
> @@ -155,6 +155,7 @@ struct thread {
>  	int (*ram_destroy)(struct thread *);
>  	int (*ram_getxer)(struct pdbg_target *, uint64_t *value);
>  	int (*ram_putxer)(struct pdbg_target *, uint64_t value);
> +	int (*enable_attn)(struct pdbg_target *);
>  };
>  #define target_to_thread(x) container_of(x, struct thread, target)
>  
> -- 
> 2.14.4
> 


I didn't know we can use attn to get break points, that's pretty cool.
How does that work, attn makes the thread go inactive and the gdb server
notices it by polling?

Thanks,
Nick
Rashmica Gupta Aug. 29, 2018, 11:46 p.m. UTC | #2
On 29/08/18 17:57, Nicholas Piggin wrote:
> On Wed, 29 Aug 2018 11:50:40 +1000
> Rashmica Gupta <rashmica.g@gmail.com> wrote:
>
>> Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
>> ---
>>  libpdbg/p8chip.c | 41 +++++++++++++++++++++++++++++++++++++++++
>>  libpdbg/target.h |  1 +
>>  2 files changed, 42 insertions(+)
>>
>> diff --git a/libpdbg/p8chip.c b/libpdbg/p8chip.c
>> index 89ecfd6..2f1d599 100644
>> --- a/libpdbg/p8chip.c
>> +++ b/libpdbg/p8chip.c
>> @@ -82,6 +82,8 @@
>>  #define  FSP_SPECIAL_WAKEUP		PPC_BIT(0)
>>  #define EX_PM_GP0_REG			0xf0100
>>  #define  SPECIAL_WKUP_DONE		PPC_BIT(31)
>> +#define HID0_REG                 	0x1329c
>> +#define EN_ATTN                 	PPC_BIT(31)
>>  
>>  /* p8 specific opcodes for instruction ramming*/
>>  #define MTXERF0_OPCODE 0x00000008UL
>> @@ -483,6 +485,44 @@ static int p8_thread_probe(struct pdbg_target *target)
>>  	return 0;
>>  }
>>  
>> +static int p8_get_hid0(struct pdbg_target *chip, uint64_t *value)
>> +{
>> +	CHECK_ERR(pib_read(chip, HID0_REG, value));
>> +	return 0;
>> +}
>> +
>> +static int p8_put_hid0(struct pdbg_target *chip, uint64_t value)
>> +{
>> +	CHECK_ERR(pib_write(chip, HID0_REG, value));
>> +	return 0;
>> +}
>> +
>> +static int p8_enable_attn(struct pdbg_target *target)
>> +{
>> +	struct pdbg_target *core;
>> +	uint64_t hid0;
>> +
>> +	core = pdbg_target_parent("core", target);
>> +	if (core == NULL)
>> +	{
>> +		PR_ERROR("CORE NOT FOUND\n");
>> +		return 1;
>> +	}
>> +
>> +	/* Need to enable the attn instruction in HID0 */
>> +	if (p8_get_hid0(core, &hid0)) {
>> +		PR_ERROR("Unable to get HID0\n");
>> +		return 1;
>> +	}
>> +	hid0 |= EN_ATTN;
>> +
>> +	if (p8_put_hid0(core, hid0)) {
>> +		PR_ERROR("Unable to set HID0\n");
>> +		return 1;
>> +	}
>> +	return 0;
>> +}
>> +
>>  static struct thread p8_thread = {
>>  	.target = {
>>  		.name = "POWER8 Thread",
>> @@ -499,6 +539,7 @@ static struct thread p8_thread = {
>>  	.ram_destroy = p8_ram_destroy,
>>  	.ram_getxer = p8_ram_getxer,
>>  	.ram_putxer = p8_ram_putxer,
>> +	.enable_attn = p8_enable_attn,
>>  };
>>  DECLARE_HW_UNIT(p8_thread);
>>  
>> diff --git a/libpdbg/target.h b/libpdbg/target.h
>> index 8bad405..c8da048 100644
>> --- a/libpdbg/target.h
>> +++ b/libpdbg/target.h
>> @@ -155,6 +155,7 @@ struct thread {
>>  	int (*ram_destroy)(struct thread *);
>>  	int (*ram_getxer)(struct pdbg_target *, uint64_t *value);
>>  	int (*ram_putxer)(struct pdbg_target *, uint64_t value);
>> +	int (*enable_attn)(struct pdbg_target *);
>>  };
>>  #define target_to_thread(x) container_of(x, struct thread, target)
>>  
>> -- 
>> 2.14.4
>>
>
> I didn't know we can use attn to get break points, that's pretty cool.
> How does that work, attn makes the thread go inactive and the gdb server
> notices it by polling?

Yup!

> Thanks,
> Nick
diff mbox series

Patch

diff --git a/libpdbg/p8chip.c b/libpdbg/p8chip.c
index 89ecfd6..2f1d599 100644
--- a/libpdbg/p8chip.c
+++ b/libpdbg/p8chip.c
@@ -82,6 +82,8 @@ 
 #define  FSP_SPECIAL_WAKEUP		PPC_BIT(0)
 #define EX_PM_GP0_REG			0xf0100
 #define  SPECIAL_WKUP_DONE		PPC_BIT(31)
+#define HID0_REG                 	0x1329c
+#define EN_ATTN                 	PPC_BIT(31)
 
 /* p8 specific opcodes for instruction ramming*/
 #define MTXERF0_OPCODE 0x00000008UL
@@ -483,6 +485,44 @@  static int p8_thread_probe(struct pdbg_target *target)
 	return 0;
 }
 
+static int p8_get_hid0(struct pdbg_target *chip, uint64_t *value)
+{
+	CHECK_ERR(pib_read(chip, HID0_REG, value));
+	return 0;
+}
+
+static int p8_put_hid0(struct pdbg_target *chip, uint64_t value)
+{
+	CHECK_ERR(pib_write(chip, HID0_REG, value));
+	return 0;
+}
+
+static int p8_enable_attn(struct pdbg_target *target)
+{
+	struct pdbg_target *core;
+	uint64_t hid0;
+
+	core = pdbg_target_parent("core", target);
+	if (core == NULL)
+	{
+		PR_ERROR("CORE NOT FOUND\n");
+		return 1;
+	}
+
+	/* Need to enable the attn instruction in HID0 */
+	if (p8_get_hid0(core, &hid0)) {
+		PR_ERROR("Unable to get HID0\n");
+		return 1;
+	}
+	hid0 |= EN_ATTN;
+
+	if (p8_put_hid0(core, hid0)) {
+		PR_ERROR("Unable to set HID0\n");
+		return 1;
+	}
+	return 0;
+}
+
 static struct thread p8_thread = {
 	.target = {
 		.name = "POWER8 Thread",
@@ -499,6 +539,7 @@  static struct thread p8_thread = {
 	.ram_destroy = p8_ram_destroy,
 	.ram_getxer = p8_ram_getxer,
 	.ram_putxer = p8_ram_putxer,
+	.enable_attn = p8_enable_attn,
 };
 DECLARE_HW_UNIT(p8_thread);
 
diff --git a/libpdbg/target.h b/libpdbg/target.h
index 8bad405..c8da048 100644
--- a/libpdbg/target.h
+++ b/libpdbg/target.h
@@ -155,6 +155,7 @@  struct thread {
 	int (*ram_destroy)(struct thread *);
 	int (*ram_getxer)(struct pdbg_target *, uint64_t *value);
 	int (*ram_putxer)(struct pdbg_target *, uint64_t value);
+	int (*enable_attn)(struct pdbg_target *);
 };
 #define target_to_thread(x) container_of(x, struct thread, target)