Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 101714
b: refs/heads/master
c: e7a5727
h: refs/heads/master
v: v3
  • Loading branch information
Michael Ellerman authored and Paul Mackerras committed Jul 1, 2008
1 parent 13dd31d commit c103755
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 19 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: aaddd3eacaeaef3503035750b3f21ac2bfe97cbf
refs/heads/master: e7a57273c6407bb6903fbaddec8c2119bf318617
6 changes: 4 additions & 2 deletions trunk/arch/powerpc/kernel/crash_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ void __init reserve_kdump_trampoline(void)

static void __init create_trampoline(unsigned long addr)
{
unsigned int *p = (unsigned int *)addr;

/* The maximum range of a single instruction branch, is the current
* instruction's address + (32 MB - 4) bytes. For the trampoline we
* need to branch to current address + 32 MB. So we insert a nop at
Expand All @@ -42,8 +44,8 @@ static void __init create_trampoline(unsigned long addr)
* branch to "addr" we jump to ("addr" + 32 MB). Although it requires
* two instructions it doesn't require any registers.
*/
create_instruction(addr, 0x60000000); /* nop */
create_branch(addr + 4, addr + PHYSICAL_START, 0);
patch_instruction(p, 0x60000000); /* nop */
patch_branch(++p, addr + PHYSICAL_START, 0);
}

void __init setup_kdump_trampoline(void)
Expand Down
20 changes: 12 additions & 8 deletions trunk/arch/powerpc/lib/code-patching.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,27 @@
#include <asm/code-patching.h>


void create_instruction(unsigned long addr, unsigned int instr)
void patch_instruction(unsigned int *addr, unsigned int instr)
{
unsigned int *p;
p = (unsigned int *)addr;
*p = instr;
asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (p));
*addr = instr;
asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (addr));
}

void create_branch(unsigned long addr, unsigned long target, int flags)
void patch_branch(unsigned int *addr, unsigned long target, int flags)
{
patch_instruction(addr, create_branch(addr, target, flags));
}

unsigned int create_branch(const unsigned int *addr,
unsigned long target, int flags)
{
unsigned int instruction;

if (! (flags & BRANCH_ABSOLUTE))
target = target - addr;
target = target - (unsigned long)addr;

/* Mask out the flags and target, so they don't step on each other. */
instruction = 0x48000000 | (flags & 0x3) | (target & 0x03FFFFFC);

create_instruction(addr, instruction);
return instruction;
}
5 changes: 2 additions & 3 deletions trunk/arch/powerpc/platforms/86xx/mpc86xx_smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ smp_86xx_kick_cpu(int nr)
unsigned int save_vector;
unsigned long target, flags;
int n = 0;
volatile unsigned int *vector
= (volatile unsigned int *)(KERNELBASE + 0x100);
unsigned int *vector = (unsigned int *)(KERNELBASE + 0x100);

if (nr < 0 || nr >= NR_CPUS)
return;
Expand All @@ -72,7 +71,7 @@ smp_86xx_kick_cpu(int nr)

/* Setup fake reset vector to call __secondary_start_mpc86xx. */
target = (unsigned long) __secondary_start_mpc86xx;
create_branch((unsigned long)vector, target, BRANCH_SET_LINK);
patch_branch(vector, target, BRANCH_SET_LINK);

/* Kick that CPU */
smp_86xx_release_core(nr);
Expand Down
5 changes: 2 additions & 3 deletions trunk/arch/powerpc/platforms/powermac/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -787,8 +787,7 @@ static void __devinit smp_core99_kick_cpu(int nr)
{
unsigned int save_vector;
unsigned long target, flags;
volatile unsigned int *vector
= ((volatile unsigned int *)(KERNELBASE+0x100));
unsigned int *vector = (unsigned int *)(KERNELBASE+0x100);

if (nr < 0 || nr > 3)
return;
Expand All @@ -805,7 +804,7 @@ static void __devinit smp_core99_kick_cpu(int nr)
* b __secondary_start_pmac_0 + nr*8 - KERNELBASE
*/
target = (unsigned long) __secondary_start_pmac_0 + nr * 8;
create_branch((unsigned long)vector, target, BRANCH_SET_LINK);
patch_branch(vector, target, BRANCH_SET_LINK);

/* Put some life in our friend */
pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
Expand Down
6 changes: 4 additions & 2 deletions trunk/include/asm-powerpc/code-patching.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
#define BRANCH_SET_LINK 0x1
#define BRANCH_ABSOLUTE 0x2

extern void create_branch(unsigned long addr, unsigned long target, int flags);
extern void create_instruction(unsigned long addr, unsigned int instr);
unsigned int create_branch(const unsigned int *addr,
unsigned long target, int flags);
void patch_branch(unsigned int *addr, unsigned long target, int flags);
void patch_instruction(unsigned int *addr, unsigned int instr);

#endif /* _ASM_POWERPC_CODE_PATCHING_H */

0 comments on commit c103755

Please sign in to comment.