[Pdbg] [PATCH 2/8] libpdbg: Add in getxer and putxer functions

rashmica rashmicy at gmail.com
Mon Jun 25 18:00:24 AEST 2018



On 25/06/18 16:24, Alistair Popple wrote:
> Thanks Rashmica, couple of questions/comments below...
>
>> +int ram_getxer_field(struct pdbg_target *thread, uint32_t *value, uint32_t field)
>> +{
>> +	uint64_t opcodes[] = {mfxerf(0, field), mtspr(277, 0)};
>> +	uint64_t results[] = {0, 0};
>> +
>> +	CHECK_ERR(ram_instructions(thread, opcodes, results, ARRAY_SIZE(opcodes), 0));
> What is the distinction between getxer_field and getxer? You seem to handle
> getxer specially below which implies it is different between P8 vs. P9 yet the
> getxer_field case is handled the same for both P8 and P9.

getxer should return the XER register regardless of implementation,
while getxer_field is technically only for P8. I left getxer_field in
the chip.c file as to move it to the p8 specific file required changing the
scope of a few things like mfspr, mtspr, ram_instructions.


>  Would just using
> multiple mfxerf()'s for getxer introduce any limitations?

I don't think that wouldn't work for p9 and if it did
would take more time than just getspr 1. But I will try.

>
> If it doesn't it might be preferable to just use that for getxer (like you do
> for P8 anyway) rather than maintaining a special case for P9. Same would
> obviously apply for putxer.


Not sure I follow. Will talk to you about this in person tomorrow?


>
>> +
>> +	*value = results[1];
>> +	return 0;
>> +}
>> +
>> +int ram_getxer(struct pdbg_target *thread_target, uint32_t *value)
>> +{
>> +
>> +	struct thread *thread;
>> +
>> +	assert(!strcmp(thread_target->class, "thread"));
>> +	thread = target_to_thread(thread_target);
>> +
>> +	CHECK_ERR(thread->ram_getxer(thread_target, value));
>> +
>> +	return 0;
>> +}
>> +
> <snip>
>
>> +static int p8_ram_getxer(struct pdbg_target *thread, uint32_t *value)
>> +{
>> +	uint32_t fields[] = {0, 0, 0, 0};
>> +	int i;
>> +
>> +	/* On POWER8 we can't get xer with getspr. We can only get IBM
>> +	 * bits 33-39 and 41-43 using the xer fields. The rest of the
>> +	 * bits are in latches somewhere. */
>> +	PR_WARNING("Can only get IBM bits 33-39 and 41-43 of the XER register\n");
>> +	for (i = 0; i < 4; i++) {
>> +		CHECK_ERR(ram_getxer_field(thread, &fields[i], i));
> This could be made slightly more efficient by generating the mfxerf opcodes for
> each field here and sending them as a single call to ram_instructions() rather
> than the multiple calls we have here at present.

That would require me to change the scope of ram_instructions, are
you ok with that?

>
> - Alistair
>
>> +	}
>> +	*value = fields[0] | fields[1] | fields[2] | fields[3];
>> +
>> +	return 0;
>> +}
>> +
>> +static int p8_ram_putxer(struct pdbg_target *thread, uint32_t value)
>> +{
>> +	uint32_t fields[] = {0, 0, 0, 0};
>> +	int i;
>> +
>> +	/* On POWER8 we seem to be only able to set IBM bits 33 and 34. This is
>> +	 * f0 and the first bit of f1, the only bits in the four XER fields
>> +	 * that are publicly documented.
>> +	 */
>> +	PR_WARNING("Can only set IBM bits 33 and 34 of the XER register\n");
>> +	fields[0] = (value & (0x1 << 30));
>> +	fields[1] = (value & (0x3 << 28));
>> +	fields[2] = (value & (0xf << 24));
>> +	fields[3] = (value & (0x7 << 20 ));
>> +
>> +	for (i = 0; i < 4; i++) {
>> +		CHECK_ERR(ram_putxer_field(thread, fields[i], i));
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>  /*
>>   * Initialise all viable threads for ramming on the given core.
>>   */
>> @@ -404,6 +443,8 @@ static struct thread p8_thread = {
>>  	.ram_setup = p8_ram_setup,
>>  	.ram_instruction = p8_ram_instruction,
>>  	.ram_destroy = p8_ram_destroy,
>> +	.ram_getxer = p8_ram_getxer,
>> +	.ram_putxer = p8_ram_putxer,
>>  };
>>  DECLARE_HW_UNIT(p8_thread);
>>  
>> diff --git a/libpdbg/p9chip.c b/libpdbg/p9chip.c
>> index c5de3bb..a266188 100644
>> --- a/libpdbg/p9chip.c
>> +++ b/libpdbg/p9chip.c
>> @@ -275,7 +275,6 @@ static int __p9_ram_instruction(struct thread *thread, uint64_t opcode, uint64_t
>>  	switch(opcode & OPCODE_MASK) {
>>  	case MTNIA_OPCODE:
>>  		predecode = 8;
>> -
>>  		/* Not currently supported as we can only MTNIA from LR */
>>  		PR_ERROR("MTNIA is not currently supported\n");
>>  		break;
>> @@ -290,7 +289,18 @@ static int __p9_ram_instruction(struct thread *thread, uint64_t opcode, uint64_t
>>  		break;
>>  
>>  	case MFSPR_OPCODE:
>> -		switch(MFSPR_SPR(opcode)) {
>> +		switch(MXSPR_SPR(opcode)) {
>> +		case 1: /* XER */
>> +			predecode = 4;
>> +			break;
>> +		default:
>> +			predecode = 0;
>> +			break;
>> +		}
>> +		break;
>> +
>> +	case MTSPR_OPCODE:
>> +		switch(MXSPR_SPR(opcode)) {
>>  		case 1: /* XER */
>>  			predecode = 4;
>>  			break;
>> @@ -373,6 +383,22 @@ static int p9_ram_destroy(struct thread *thread)
>>  	return 0;
>>  }
>>  
>> +static int p9_ram_getxer(struct pdbg_target *thread, uint32_t *value)
>> +{
>> +	CHECK_ERR(ram_getspr(thread, 1, (uint64_t *)value));
>> +
>> +	return 0;
>> +}
>> +
>> +static int p9_ram_putxer(struct pdbg_target *thread, uint32_t value)
>> +{
>> +	/* On POWER9 we can only set bits 32-34 and 44-63.*/
>> +	CHECK_ERR(ram_putspr(thread, 1, (uint64_t)value));
>> +
>> +	return 0;
>> +
>> +}
>> +
>>  static struct thread p9_thread = {
>>  	.target = {
>>  		.name = "POWER9 Thread",
>> @@ -387,6 +413,8 @@ static struct thread p9_thread = {
>>  	.ram_setup = p9_ram_setup,
>>  	.ram_instruction = p9_ram_instruction,
>>  	.ram_destroy = p9_ram_destroy,
>> +	.ram_getxer = p9_ram_getxer,
>> +	.ram_putxer = p9_ram_putxer,
>>  };
>>  DECLARE_HW_UNIT(p9_thread);
>>  
>> diff --git a/libpdbg/target.h b/libpdbg/target.h
>> index e4a3ed4..87e9f25 100644
>> --- a/libpdbg/target.h
>> +++ b/libpdbg/target.h
>> @@ -152,6 +152,8 @@ struct thread {
>>  	int (*ram_setup)(struct thread *);
>>  	int (*ram_instruction)(struct thread *, uint64_t opcode, uint64_t *scratch);
>>  	int (*ram_destroy)(struct thread *);
>> +	int (*ram_getxer)(struct pdbg_target *, uint32_t *value);
>> +	int (*ram_putxer)(struct pdbg_target *, uint32_t value);
>>  };
>>  #define target_to_thread(x) container_of(x, struct thread, target)
>>  
>>
>



More information about the Pdbg mailing list