powerpc: Use a datatype for instructions
Currently unsigned ints are used to represent instructions on powerpc. This has worked well as instructions have always been 4 byte words. However, ISA v3.1 introduces some changes to instructions that mean this scheme will no longer work as well. This change is Prefixed Instructions. A prefixed instruction is made up of a word prefix followed by a word suffix to make an 8 byte double word instruction. No matter the endianness of the system the prefix always comes first. Prefixed instructions are only planned for powerpc64. Introduce a ppc_inst type to represent both prefixed and word instructions on powerpc64 while keeping it possible to exclusively have word instructions on powerpc32. Signed-off-by: Jordan Niethe <jniethe5@gmail.com> [mpe: Fix compile error in emulate_spe()] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20200506034050.24806-12-jniethe5@gmail.com
This commit is contained in:

committed by
Michael Ellerman

parent
217862d9b9
commit
94afd069d9
@@ -100,7 +100,7 @@ static long *xmon_fault_jmp[NR_CPUS];
|
||||
/* Breakpoint stuff */
|
||||
struct bpt {
|
||||
unsigned long address;
|
||||
unsigned int *instr;
|
||||
struct ppc_inst *instr;
|
||||
atomic_t ref_count;
|
||||
int enabled;
|
||||
unsigned long pad;
|
||||
@@ -876,8 +876,8 @@ static struct bpt *new_breakpoint(unsigned long a)
|
||||
for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
|
||||
if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
|
||||
bp->address = a;
|
||||
bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS);
|
||||
patch_instruction(bp->instr + 1, bpinstr);
|
||||
bp->instr = (void *)(bpt_table + ((bp - bpts) * BPT_WORDS));
|
||||
patch_instruction(bp->instr + 1, ppc_inst(bpinstr));
|
||||
return bp;
|
||||
}
|
||||
}
|
||||
@@ -889,7 +889,7 @@ static struct bpt *new_breakpoint(unsigned long a)
|
||||
static void insert_bpts(void)
|
||||
{
|
||||
int i;
|
||||
unsigned int instr;
|
||||
struct ppc_inst instr;
|
||||
struct bpt *bp;
|
||||
|
||||
bp = bpts;
|
||||
@@ -911,8 +911,8 @@ static void insert_bpts(void)
|
||||
patch_instruction(bp->instr, instr);
|
||||
if (bp->enabled & BP_CIABR)
|
||||
continue;
|
||||
if (patch_instruction((unsigned int *)bp->address,
|
||||
bpinstr) != 0) {
|
||||
if (patch_instruction((struct ppc_inst *)bp->address,
|
||||
ppc_inst(bpinstr)) != 0) {
|
||||
printf("Couldn't write instruction at %lx, "
|
||||
"disabling breakpoint there\n", bp->address);
|
||||
bp->enabled &= ~BP_TRAP;
|
||||
@@ -940,7 +940,7 @@ static void remove_bpts(void)
|
||||
{
|
||||
int i;
|
||||
struct bpt *bp;
|
||||
unsigned instr;
|
||||
struct ppc_inst instr;
|
||||
|
||||
bp = bpts;
|
||||
for (i = 0; i < NBPTS; ++i, ++bp) {
|
||||
@@ -949,7 +949,7 @@ static void remove_bpts(void)
|
||||
if (mread(bp->address, &instr, 4) == 4
|
||||
&& ppc_inst_equal(instr, ppc_inst(bpinstr))
|
||||
&& patch_instruction(
|
||||
(unsigned int *)bp->address, bp->instr[0]) != 0)
|
||||
(struct ppc_inst *)bp->address, bp->instr[0]) != 0)
|
||||
printf("Couldn't remove breakpoint at %lx\n",
|
||||
bp->address);
|
||||
}
|
||||
@@ -1156,7 +1156,7 @@ static int do_step(struct pt_regs *regs)
|
||||
*/
|
||||
static int do_step(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int instr;
|
||||
struct ppc_inst instr;
|
||||
int stepped;
|
||||
|
||||
force_enable_xmon();
|
||||
@@ -1322,7 +1322,7 @@ csum(void)
|
||||
*/
|
||||
static long check_bp_loc(unsigned long addr)
|
||||
{
|
||||
unsigned int instr;
|
||||
struct ppc_inst instr;
|
||||
|
||||
addr &= ~3;
|
||||
if (!is_kernel_addr(addr)) {
|
||||
@@ -2848,7 +2848,7 @@ generic_inst_dump(unsigned long adr, long count, int praddr,
|
||||
{
|
||||
int nr, dotted;
|
||||
unsigned long first_adr;
|
||||
unsigned int inst, last_inst = ppc_inst(0);
|
||||
struct ppc_inst inst, last_inst = ppc_inst(0);
|
||||
unsigned char val[4];
|
||||
|
||||
dotted = 0;
|
||||
|
Reference in New Issue
Block a user