aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-powerpc')
-rw-r--r--include/asm-powerpc/elf.h22
-rw-r--r--include/asm-powerpc/kexec.h49
-rw-r--r--include/asm-powerpc/machdep.h1
-rw-r--r--include/asm-powerpc/system.h48
4 files changed, 111 insertions, 9 deletions
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index d22b10021b5d..d140577d0a05 100644
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -178,18 +178,22 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
178static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs, 178static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs,
179 struct pt_regs *regs) 179 struct pt_regs *regs)
180{ 180{
181 int i; 181 int i, nregs;
182 int gprs = sizeof(struct pt_regs)/sizeof(ELF_GREG_TYPE);
183 182
184 if (gprs > ELF_NGREG) 183 memset((void *)elf_regs, 0, sizeof(elf_gregset_t));
185 gprs = ELF_NGREG;
186 184
187 for (i=0; i < gprs; i++) 185 /* Our registers are always unsigned longs, whether we're a 32 bit
188 elf_regs[i] = (elf_greg_t)((ELF_GREG_TYPE *)regs)[i]; 186 * process or 64 bit, on either a 64 bit or 32 bit kernel.
189 187 * Don't use ELF_GREG_TYPE here. */
190 memset((char *)(elf_regs) + sizeof(struct pt_regs), 0, \ 188 nregs = sizeof(struct pt_regs) / sizeof(unsigned long);
191 sizeof(elf_gregset_t) - sizeof(struct pt_regs)); 189 if (nregs > ELF_NGREG)
190 nregs = ELF_NGREG;
192 191
192 for (i = 0; i < nregs; i++) {
193 /* This will correctly truncate 64 bit registers to 32 bits
194 * for a 32 bit process on a 64 bit kernel. */
195 elf_regs[i] = (elf_greg_t)((ELF_GREG_TYPE *)regs)[i];
196 }
193} 197}
194#define ELF_CORE_COPY_REGS(gregs, regs) ppc_elf_core_copy_regs(gregs, regs); 198#define ELF_CORE_COPY_REGS(gregs, regs) ppc_elf_core_copy_regs(gregs, regs);
195 199
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h
new file mode 100644
index 000000000000..062ab9ba68eb
--- /dev/null
+++ b/include/asm-powerpc/kexec.h
@@ -0,0 +1,49 @@
1#ifndef _ASM_POWERPC_KEXEC_H
2#define _ASM_POWERPC_KEXEC_H
3
4/*
5 * Maximum page that is mapped directly into kernel memory.
6 * XXX: Since we copy virt we can use any page we allocate
7 */
8#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
9
10/*
11 * Maximum address we can reach in physical address mode.
12 * XXX: I want to allow initrd in highmem. Otherwise set to rmo on LPAR.
13 */
14#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
15
16/* Maximum address we can use for the control code buffer */
17#ifdef __powerpc64__
18#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
19#else
20/* TASK_SIZE, probably left over from use_mm ?? */
21#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
22#endif
23
24#define KEXEC_CONTROL_CODE_SIZE 4096
25
26/* The native architecture */
27#ifdef __powerpc64__
28#define KEXEC_ARCH KEXEC_ARCH_PPC64
29#else
30#define KEXEC_ARCH KEXEC_ARCH_PPC
31#endif
32
33#ifndef __ASSEMBLY__
34
35#define MAX_NOTE_BYTES 1024
36typedef u32 note_buf_t[MAX_NOTE_BYTES / sizeof(u32)];
37
38extern note_buf_t crash_notes[];
39
40#ifdef __powerpc64__
41extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
42 master to copy new code to 0 */
43#else
44struct kimage;
45extern void machine_kexec_simple(struct kimage *image);
46#endif
47
48#endif /* ! __ASSEMBLY__ */
49#endif /* _ASM_POWERPC_KEXEC_H */
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index 451b345cfc78..629ca964b974 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -80,6 +80,7 @@ struct machdep_calls {
80 void (*iommu_dev_setup)(struct pci_dev *dev); 80 void (*iommu_dev_setup)(struct pci_dev *dev);
81 void (*iommu_bus_setup)(struct pci_bus *bus); 81 void (*iommu_bus_setup)(struct pci_bus *bus);
82 void (*irq_bus_setup)(struct pci_bus *bus); 82 void (*irq_bus_setup)(struct pci_bus *bus);
83 int (*set_dabr)(unsigned long dabr);
83#endif 84#endif
84 85
85 int (*probe)(int platform); 86 int (*probe)(int platform);
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 5b2ecbc47907..b5da0b851e02 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -359,5 +359,53 @@ extern void reloc_got2(unsigned long);
359 359
360#define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x))) 360#define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x)))
361 361
362static inline void create_instruction(unsigned long addr, unsigned int instr)
363{
364 unsigned int *p;
365 p = (unsigned int *)addr;
366 *p = instr;
367 asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (p));
368}
369
370/* Flags for create_branch:
371 * "b" == create_branch(addr, target, 0);
372 * "ba" == create_branch(addr, target, BRANCH_ABSOLUTE);
373 * "bl" == create_branch(addr, target, BRANCH_SET_LINK);
374 * "bla" == create_branch(addr, target, BRANCH_ABSOLUTE | BRANCH_SET_LINK);
375 */
376#define BRANCH_SET_LINK 0x1
377#define BRANCH_ABSOLUTE 0x2
378
379static inline void create_branch(unsigned long addr,
380 unsigned long target, int flags)
381{
382 unsigned int instruction;
383
384 if (! (flags & BRANCH_ABSOLUTE))
385 target = target - addr;
386
387 /* Mask out the flags and target, so they don't step on each other. */
388 instruction = 0x48000000 | (flags & 0x3) | (target & 0x03FFFFFC);
389
390 create_instruction(addr, instruction);
391}
392
393static inline void create_function_call(unsigned long addr, void * func)
394{
395 unsigned long func_addr;
396
397#ifdef CONFIG_PPC64
398 /*
399 * On PPC64 the function pointer actually points to the function's
400 * descriptor. The first entry in the descriptor is the address
401 * of the function text.
402 */
403 func_addr = *(unsigned long *)func;
404#else
405 func_addr = (unsigned long)func;
406#endif
407 create_branch(addr, func_addr, BRANCH_SET_LINK);
408}
409
362#endif /* __KERNEL__ */ 410#endif /* __KERNEL__ */
363#endif /* _ASM_POWERPC_SYSTEM_H */ 411#endif /* _ASM_POWERPC_SYSTEM_H */