diff options
-rw-r--r-- | kexec/arch/ppc/kexec-elf-ppc.c | 19 | ||||
-rw-r--r-- | kexec/arch/ppc/kexec-uImage-ppc.c | 17 | ||||
-rw-r--r-- | purgatory/arch/ppc/purgatory-ppc.c | 2 | ||||
-rw-r--r-- | purgatory/arch/ppc/v2wrap_32.S | 4 |
4 files changed, 41 insertions, 1 deletions
diff --git a/kexec/arch/ppc/kexec-elf-ppc.c b/kexec/arch/ppc/kexec-elf-ppc.c index f4443b4..314eb1e 100644 --- a/kexec/arch/ppc/kexec-elf-ppc.c +++ b/kexec/arch/ppc/kexec-elf-ppc.c @@ -414,6 +414,25 @@ int elf_ppc_load(int argc, char **argv, const char *buf, off_t len, elf_rel_set_symbol(&info->rhdr, "stack", &addr, sizeof(addr)); #undef PUL_STACK_SIZE + /* + * Fixup ThreadPointer(r2) for purgatory. + * PPC32 ELF ABI expects : + * ThreadPointer (TP) = TCB + 0x7000 + * We manually allocate a TCB space and set the TP + * accordingly. + */ +#define TCB_SIZE 1024 +#define TCB_TP_OFFSET 0x7000 /* PPC32 ELF ABI */ + + addr = locate_hole(info, TCB_SIZE, 0, 0, + ((unsigned long)elf_max_addr(&ehdr) - TCB_TP_OFFSET), + 1); + addr += TCB_SIZE + TCB_TP_OFFSET; + elf_rel_set_symbol(&info->rhdr, "my_thread_ptr", &addr, sizeof(addr)); + +#undef TCB_SIZE +#undef TCB_TP_OFFSET + addr = elf_rel_get_addr(&info->rhdr, "purgatory_start"); info->entry = (void *)addr; #endif diff --git a/kexec/arch/ppc/kexec-uImage-ppc.c b/kexec/arch/ppc/kexec-uImage-ppc.c index 1d71374..b5579f0 100644 --- a/kexec/arch/ppc/kexec-uImage-ppc.c +++ b/kexec/arch/ppc/kexec-uImage-ppc.c @@ -228,6 +228,23 @@ static int ppc_load_bare_bits(int argc, char **argv, const char *buf, /* No allocation past here in order not to overwrite the stack */ #undef PUL_STACK_SIZE + /* + * Fixup ThreadPointer(r2) for purgatory. + * PPC32 ELF ABI expects : + * ThreadPointer (TP) = TCB + 0x7000 + * We manually allocate a TCB space and set the TP + * accordingly. + */ +#define TCB_SIZE 1024 +#define TCB_TP_OFFSET 0x7000 /* PPC32 ELF ABI */ + addr = locate_hole(info, TCB_SIZE, 0, 0, + ((unsigned long)-1 - TCB_TP_OFFSET), + 1); + addr += TCB_SIZE + TCB_TP_OFFSET; + elf_rel_set_symbol(&info->rhdr, "my_thread_ptr", &addr, sizeof(addr)); +#undef TCB_TP_OFFSET +#undef TCB_SIZE + addr = elf_rel_get_addr(&info->rhdr, "purgatory_start"); info->entry = (void *)addr; diff --git a/purgatory/arch/ppc/purgatory-ppc.c b/purgatory/arch/ppc/purgatory-ppc.c index 349e750..3e6b354 100644 --- a/purgatory/arch/ppc/purgatory-ppc.c +++ b/purgatory/arch/ppc/purgatory-ppc.c @@ -26,7 +26,7 @@ unsigned int panic_kernel = 0; unsigned long backup_start = 0; unsigned long stack = 0; unsigned long dt_offset = 0; -unsigned long my_toc = 0; +unsigned long my_thread_ptr = 0; unsigned long kernel = 0; void setup_arch(void) diff --git a/purgatory/arch/ppc/v2wrap_32.S b/purgatory/arch/ppc/v2wrap_32.S index 8442d16..8b60677 100644 --- a/purgatory/arch/ppc/v2wrap_32.S +++ b/purgatory/arch/ppc/v2wrap_32.S @@ -56,6 +56,10 @@ master: mr 17,3 # save cpu id to r17 mr 15,4 # save physical address in reg15 + lis 6,my_thread_ptr@h + ori 6,6,my_thread_ptr@l + lwz 2,0(6) # setup ThreadPointer(TP) + lis 6,stack@h ori 6,6,stack@l lwz 1,0(6) #setup stack |