Merge branch 'merge' into next
This commit is contained in:
commit
5b97259220
|
@ -414,7 +414,7 @@ config KEXEC
|
|||
config CRASH_DUMP
|
||||
bool "Build a kdump crash kernel"
|
||||
depends on PPC64 || 6xx || FSL_BOOKE || (44x && !SMP)
|
||||
select RELOCATABLE if PPC64 || 44x || FSL_BOOKE
|
||||
select RELOCATABLE if (PPC64 && !COMPILE_TEST) || 44x || FSL_BOOKE
|
||||
help
|
||||
Build a kernel suitable for use as a kdump capture kernel.
|
||||
The same kernel binary can be used as production kernel and dump
|
||||
|
@ -1017,6 +1017,7 @@ endmenu
|
|||
if PPC64
|
||||
config RELOCATABLE
|
||||
bool "Build a relocatable kernel"
|
||||
depends on !COMPILE_TEST
|
||||
select NONSTATIC_KERNEL
|
||||
help
|
||||
This builds a kernel image that is capable of running anywhere
|
||||
|
|
|
@ -303,7 +303,6 @@ config PPC_EARLY_DEBUG_OPAL_VTERMNO
|
|||
This correspond to which /dev/hvcN you want to use for early
|
||||
debug.
|
||||
|
||||
On OPAL v1 (takeover) this should always be 0
|
||||
On OPAL v2, this will be 0 for network console and 1 or 2 for
|
||||
the machine built-in serial ports.
|
||||
|
||||
|
|
|
@ -88,4 +88,15 @@ static inline unsigned long ppc_function_entry(void *func)
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline unsigned long ppc_global_function_entry(void *func)
|
||||
{
|
||||
#if defined(CONFIG_PPC64) && defined(_CALL_ELF) && _CALL_ELF == 2
|
||||
/* PPC64 ABIv2 the global entry point is at the address */
|
||||
return (unsigned long)func;
|
||||
#else
|
||||
/* All other cases there is no change vs ppc_function_entry() */
|
||||
return ppc_function_entry(func);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* _ASM_POWERPC_CODE_PATCHING_H */
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
#define MMU_FTR_TYPE_40x ASM_CONST(0x00000004)
|
||||
#define MMU_FTR_TYPE_44x ASM_CONST(0x00000008)
|
||||
#define MMU_FTR_TYPE_FSL_E ASM_CONST(0x00000010)
|
||||
#define MMU_FTR_TYPE_3E ASM_CONST(0x00000020)
|
||||
#define MMU_FTR_TYPE_47x ASM_CONST(0x00000040)
|
||||
#define MMU_FTR_TYPE_47x ASM_CONST(0x00000020)
|
||||
|
||||
/*
|
||||
* This is individual features
|
||||
|
@ -106,13 +105,6 @@
|
|||
MMU_FTR_CI_LARGE_PAGE
|
||||
#define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
|
||||
MMU_FTR_CI_LARGE_PAGE | MMU_FTR_NO_SLBIE_B
|
||||
#define MMU_FTRS_A2 MMU_FTR_TYPE_3E | MMU_FTR_USE_TLBILX | \
|
||||
MMU_FTR_USE_TLBIVAX_BCAST | \
|
||||
MMU_FTR_LOCK_BCAST_INVAL | \
|
||||
MMU_FTR_USE_TLBRSRV | \
|
||||
MMU_FTR_USE_PAIRED_MAS | \
|
||||
MMU_FTR_TLBIEL | \
|
||||
MMU_FTR_16M_PAGE
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm/cputable.h>
|
||||
|
||||
|
|
|
@ -12,27 +12,7 @@
|
|||
#ifndef __OPAL_H
|
||||
#define __OPAL_H
|
||||
|
||||
/****** Takeover interface ********/
|
||||
|
||||
/* PAPR H-Call used to querty the HAL existence and/or instanciate
|
||||
* it from within pHyp (tech preview only).
|
||||
*
|
||||
* This is exclusively used in prom_init.c
|
||||
*/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
struct opal_takeover_args {
|
||||
u64 k_image; /* r4 */
|
||||
u64 k_size; /* r5 */
|
||||
u64 k_entry; /* r6 */
|
||||
u64 k_entry2; /* r7 */
|
||||
u64 hal_addr; /* r8 */
|
||||
u64 rd_image; /* r9 */
|
||||
u64 rd_size; /* r10 */
|
||||
u64 rd_loc; /* r11 */
|
||||
};
|
||||
|
||||
/*
|
||||
* SG entry
|
||||
*
|
||||
|
@ -55,15 +35,6 @@ struct opal_sg_list {
|
|||
/* We calculate number of sg entries based on PAGE_SIZE */
|
||||
#define SG_ENTRIES_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct opal_sg_entry))
|
||||
|
||||
extern long opal_query_takeover(u64 *hal_size, u64 *hal_align);
|
||||
|
||||
extern long opal_do_takeover(struct opal_takeover_args *args);
|
||||
|
||||
struct rtas_args;
|
||||
extern int opal_enter_rtas(struct rtas_args *args,
|
||||
unsigned long data,
|
||||
unsigned long entry);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/****** OPAL APIs ******/
|
||||
|
|
|
@ -61,8 +61,7 @@ struct power_pmu {
|
|||
#define PPMU_SIAR_VALID 0x00000010 /* Processor has SIAR Valid bit */
|
||||
#define PPMU_HAS_SSLOT 0x00000020 /* Has sampled slot in MMCRA */
|
||||
#define PPMU_HAS_SIER 0x00000040 /* Has SIER */
|
||||
#define PPMU_BHRB 0x00000080 /* has BHRB feature enabled */
|
||||
#define PPMU_EBB 0x00000100 /* supports event based branch */
|
||||
#define PPMU_ARCH_207S 0x00000080 /* PMC is architecture v2.07S */
|
||||
|
||||
/*
|
||||
* Values for flags to get_alternatives()
|
||||
|
|
|
@ -9,10 +9,6 @@
|
|||
|
||||
#include <uapi/asm/swab.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifndef __powerpc64__
|
||||
#endif /* __powerpc64__ */
|
||||
|
||||
static __inline__ __u16 ld_le16(const volatile __u16 *addr)
|
||||
{
|
||||
__u16 val;
|
||||
|
@ -20,19 +16,12 @@ static __inline__ __u16 ld_le16(const volatile __u16 *addr)
|
|||
__asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
|
||||
return val;
|
||||
}
|
||||
#define __arch_swab16p ld_le16
|
||||
|
||||
static __inline__ void st_le16(volatile __u16 *addr, const __u16 val)
|
||||
{
|
||||
__asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
|
||||
}
|
||||
|
||||
static inline void __arch_swab16s(__u16 *addr)
|
||||
{
|
||||
st_le16(addr, *addr);
|
||||
}
|
||||
#define __arch_swab16s __arch_swab16s
|
||||
|
||||
static __inline__ __u32 ld_le32(const volatile __u32 *addr)
|
||||
{
|
||||
__u32 val;
|
||||
|
@ -40,42 +29,10 @@ static __inline__ __u32 ld_le32(const volatile __u32 *addr)
|
|||
__asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (addr), "m" (*addr));
|
||||
return val;
|
||||
}
|
||||
#define __arch_swab32p ld_le32
|
||||
|
||||
static __inline__ void st_le32(volatile __u32 *addr, const __u32 val)
|
||||
{
|
||||
__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
|
||||
}
|
||||
|
||||
static inline void __arch_swab32s(__u32 *addr)
|
||||
{
|
||||
st_le32(addr, *addr);
|
||||
}
|
||||
#define __arch_swab32s __arch_swab32s
|
||||
|
||||
static inline __attribute_const__ __u16 __arch_swab16(__u16 value)
|
||||
{
|
||||
__u16 result;
|
||||
|
||||
__asm__("rlwimi %0,%1,8,16,23"
|
||||
: "=r" (result)
|
||||
: "r" (value), "0" (value >> 8));
|
||||
return result;
|
||||
}
|
||||
#define __arch_swab16 __arch_swab16
|
||||
|
||||
static inline __attribute_const__ __u32 __arch_swab32(__u32 value)
|
||||
{
|
||||
__u32 result;
|
||||
|
||||
__asm__("rlwimi %0,%1,24,16,23\n\t"
|
||||
"rlwimi %0,%1,8,8,15\n\t"
|
||||
"rlwimi %0,%1,24,0,7"
|
||||
: "=r" (result)
|
||||
: "r" (value), "0" (value >> 24));
|
||||
return result;
|
||||
}
|
||||
#define __arch_swab32 __arch_swab32
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
#endif /* _ASM_POWERPC_SWAB_H */
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "ftrace-powerpc: " fmt
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
@ -105,7 +107,7 @@ __ftrace_make_nop(struct module *mod,
|
|||
struct dyn_ftrace *rec, unsigned long addr)
|
||||
{
|
||||
unsigned int op;
|
||||
unsigned long ptr;
|
||||
unsigned long entry, ptr;
|
||||
unsigned long ip = rec->ip;
|
||||
void *tramp;
|
||||
|
||||
|
@ -115,7 +117,7 @@ __ftrace_make_nop(struct module *mod,
|
|||
|
||||
/* Make sure that that this is still a 24bit jump */
|
||||
if (!is_bl_op(op)) {
|
||||
printk(KERN_ERR "Not expected bl: opcode is %x\n", op);
|
||||
pr_err("Not expected bl: opcode is %x\n", op);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -125,21 +127,21 @@ __ftrace_make_nop(struct module *mod,
|
|||
pr_devel("ip:%lx jumps to %p", ip, tramp);
|
||||
|
||||
if (!is_module_trampoline(tramp)) {
|
||||
printk(KERN_ERR "Not a trampoline\n");
|
||||
pr_err("Not a trampoline\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (module_trampoline_target(mod, tramp, &ptr)) {
|
||||
printk(KERN_ERR "Failed to get trampoline target\n");
|
||||
pr_err("Failed to get trampoline target\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
pr_devel("trampoline target %lx", ptr);
|
||||
|
||||
entry = ppc_global_function_entry((void *)addr);
|
||||
/* This should match what was called */
|
||||
if (ptr != ppc_function_entry((void *)addr)) {
|
||||
printk(KERN_ERR "addr %lx does not match expected %lx\n",
|
||||
ptr, ppc_function_entry((void *)addr));
|
||||
if (ptr != entry) {
|
||||
pr_err("addr %lx does not match expected %lx\n", ptr, entry);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -179,7 +181,7 @@ __ftrace_make_nop(struct module *mod,
|
|||
|
||||
/* Make sure that that this is still a 24bit jump */
|
||||
if (!is_bl_op(op)) {
|
||||
printk(KERN_ERR "Not expected bl: opcode is %x\n", op);
|
||||
pr_err("Not expected bl: opcode is %x\n", op);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -198,7 +200,7 @@ __ftrace_make_nop(struct module *mod,
|
|||
|
||||
/* Find where the trampoline jumps to */
|
||||
if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
|
||||
printk(KERN_ERR "Failed to read %lx\n", tramp);
|
||||
pr_err("Failed to read %lx\n", tramp);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -209,7 +211,7 @@ __ftrace_make_nop(struct module *mod,
|
|||
((jmp[1] & 0xffff0000) != 0x398c0000) ||
|
||||
(jmp[2] != 0x7d8903a6) ||
|
||||
(jmp[3] != 0x4e800420)) {
|
||||
printk(KERN_ERR "Not a trampoline\n");
|
||||
pr_err("Not a trampoline\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -221,8 +223,7 @@ __ftrace_make_nop(struct module *mod,
|
|||
pr_devel(" %lx ", tramp);
|
||||
|
||||
if (tramp != addr) {
|
||||
printk(KERN_ERR
|
||||
"Trampoline location %08lx does not match addr\n",
|
||||
pr_err("Trampoline location %08lx does not match addr\n",
|
||||
tramp);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -263,15 +264,13 @@ int ftrace_make_nop(struct module *mod,
|
|||
*/
|
||||
if (!rec->arch.mod) {
|
||||
if (!mod) {
|
||||
printk(KERN_ERR "No module loaded addr=%lx\n",
|
||||
addr);
|
||||
pr_err("No module loaded addr=%lx\n", addr);
|
||||
return -EFAULT;
|
||||
}
|
||||
rec->arch.mod = mod;
|
||||
} else if (mod) {
|
||||
if (mod != rec->arch.mod) {
|
||||
printk(KERN_ERR
|
||||
"Record mod %p not equal to passed in mod %p\n",
|
||||
pr_err("Record mod %p not equal to passed in mod %p\n",
|
||||
rec->arch.mod, mod);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -307,26 +306,25 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
|
|||
* The load offset is different depending on the ABI. For simplicity
|
||||
* just mask it out when doing the compare.
|
||||
*/
|
||||
if ((op[0] != 0x48000008) || ((op[1] & 0xffff00000) != 0xe8410000)) {
|
||||
printk(KERN_ERR "Unexpected call sequence: %x %x\n",
|
||||
op[0], op[1]);
|
||||
if ((op[0] != 0x48000008) || ((op[1] & 0xffff0000) != 0xe8410000)) {
|
||||
pr_err("Unexpected call sequence: %x %x\n", op[0], op[1]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* If we never set up a trampoline to ftrace_caller, then bail */
|
||||
if (!rec->arch.mod->arch.tramp) {
|
||||
printk(KERN_ERR "No ftrace trampoline\n");
|
||||
pr_err("No ftrace trampoline\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Ensure branch is within 24 bits */
|
||||
if (create_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) {
|
||||
printk(KERN_ERR "Branch out of range");
|
||||
if (!create_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) {
|
||||
pr_err("Branch out of range\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (patch_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) {
|
||||
printk(KERN_ERR "REL24 out of range!\n");
|
||||
pr_err("REL24 out of range!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -345,13 +343,13 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
|
|||
|
||||
/* It should be pointing to a nop */
|
||||
if (op != PPC_INST_NOP) {
|
||||
printk(KERN_ERR "Expected NOP but have %x\n", op);
|
||||
pr_err("Expected NOP but have %x\n", op);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* If we never set up a trampoline to ftrace_caller, then bail */
|
||||
if (!rec->arch.mod->arch.tramp) {
|
||||
printk(KERN_ERR "No ftrace trampoline\n");
|
||||
pr_err("No ftrace trampoline\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -359,7 +357,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
|
|||
op = create_branch((unsigned int *)ip,
|
||||
rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
|
||||
if (!op) {
|
||||
printk(KERN_ERR "REL24 out of range!\n");
|
||||
pr_err("REL24 out of range!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -397,7 +395,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
|
|||
* already have a module defined.
|
||||
*/
|
||||
if (!rec->arch.mod) {
|
||||
printk(KERN_ERR "No module loaded\n");
|
||||
pr_err("No module loaded\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ _GLOBAL(power7_nap)
|
|||
|
||||
_GLOBAL(power7_sleep)
|
||||
li r3,1
|
||||
li r4,0
|
||||
li r4,1
|
||||
b power7_powersave_common
|
||||
/* No return */
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ unsigned int ioread16(void __iomem *addr)
|
|||
}
|
||||
unsigned int ioread16be(void __iomem *addr)
|
||||
{
|
||||
return in_be16(addr);
|
||||
return readw_be(addr);
|
||||
}
|
||||
unsigned int ioread32(void __iomem *addr)
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ unsigned int ioread32(void __iomem *addr)
|
|||
}
|
||||
unsigned int ioread32be(void __iomem *addr)
|
||||
{
|
||||
return in_be32(addr);
|
||||
return readl_be(addr);
|
||||
}
|
||||
EXPORT_SYMBOL(ioread8);
|
||||
EXPORT_SYMBOL(ioread16);
|
||||
|
@ -49,7 +49,7 @@ void iowrite16(u16 val, void __iomem *addr)
|
|||
}
|
||||
void iowrite16be(u16 val, void __iomem *addr)
|
||||
{
|
||||
out_be16(addr, val);
|
||||
writew_be(val, addr);
|
||||
}
|
||||
void iowrite32(u32 val, void __iomem *addr)
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ void iowrite32(u32 val, void __iomem *addr)
|
|||
}
|
||||
void iowrite32be(u32 val, void __iomem *addr)
|
||||
{
|
||||
out_be32(addr, val);
|
||||
writel_be(val, addr);
|
||||
}
|
||||
EXPORT_SYMBOL(iowrite8);
|
||||
EXPORT_SYMBOL(iowrite16);
|
||||
|
@ -75,15 +75,15 @@ EXPORT_SYMBOL(iowrite32be);
|
|||
*/
|
||||
void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
|
||||
{
|
||||
_insb((u8 __iomem *) addr, dst, count);
|
||||
readsb(addr, dst, count);
|
||||
}
|
||||
void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
|
||||
{
|
||||
_insw_ns((u16 __iomem *) addr, dst, count);
|
||||
readsw(addr, dst, count);
|
||||
}
|
||||
void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
|
||||
{
|
||||
_insl_ns((u32 __iomem *) addr, dst, count);
|
||||
readsl(addr, dst, count);
|
||||
}
|
||||
EXPORT_SYMBOL(ioread8_rep);
|
||||
EXPORT_SYMBOL(ioread16_rep);
|
||||
|
@ -91,15 +91,15 @@ EXPORT_SYMBOL(ioread32_rep);
|
|||
|
||||
void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
|
||||
{
|
||||
_outsb((u8 __iomem *) addr, src, count);
|
||||
writesb(addr, src, count);
|
||||
}
|
||||
void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
|
||||
{
|
||||
_outsw_ns((u16 __iomem *) addr, src, count);
|
||||
writesw(addr, src, count);
|
||||
}
|
||||
void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
|
||||
{
|
||||
_outsl_ns((u32 __iomem *) addr, src, count);
|
||||
writesl(addr, src, count);
|
||||
}
|
||||
EXPORT_SYMBOL(iowrite8_rep);
|
||||
EXPORT_SYMBOL(iowrite16_rep);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/code-patching.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/sstep.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
@ -491,12 +492,10 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
unsigned long arch_deref_entry_point(void *entry)
|
||||
{
|
||||
return ((func_descr_t *)entry)->entry;
|
||||
return ppc_global_function_entry(entry);
|
||||
}
|
||||
#endif
|
||||
|
||||
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
|
@ -508,7 +507,11 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
|||
/* setup return addr to the jprobe handler routine */
|
||||
regs->nip = arch_deref_entry_point(jp->entry);
|
||||
#ifdef CONFIG_PPC64
|
||||
#if defined(_CALL_ELF) && _CALL_ELF == 2
|
||||
regs->gpr[12] = (unsigned long)jp->entry;
|
||||
#else
|
||||
regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -315,8 +315,17 @@ static void dedotify_versions(struct modversion_info *vers,
|
|||
struct modversion_info *end;
|
||||
|
||||
for (end = (void *)vers + size; vers < end; vers++)
|
||||
if (vers->name[0] == '.')
|
||||
if (vers->name[0] == '.') {
|
||||
memmove(vers->name, vers->name+1, strlen(vers->name));
|
||||
#ifdef ARCH_RELOCATES_KCRCTAB
|
||||
/* The TOC symbol has no CRC computed. To avoid CRC
|
||||
* check failing, we must force it to the expected
|
||||
* value (see CRC check in module.c).
|
||||
*/
|
||||
if (!strcmp(vers->name, "TOC."))
|
||||
vers->crc = -(unsigned long)reloc_start;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Undefined symbols which refer to .funcname, hack to funcname (or .TOC.) */
|
||||
|
|
|
@ -662,13 +662,6 @@ void __init early_init_devtree(void *params)
|
|||
of_scan_flat_dt(early_init_dt_scan_fw_dump, NULL);
|
||||
#endif
|
||||
|
||||
/* Pre-initialize the cmd_line with the content of boot_commmand_line,
|
||||
* which will be empty except when the content of the variable has
|
||||
* been overriden by a bootloading mechanism. This happens typically
|
||||
* with HAL takeover
|
||||
*/
|
||||
strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
|
||||
|
||||
/* Retrieve various informations from the /chosen node of the
|
||||
* device-tree, including the platform type, initrd location and
|
||||
* size, TCE reserve, and more ...
|
||||
|
|
|
@ -1268,201 +1268,6 @@ static u64 __initdata prom_opal_base;
|
|||
static u64 __initdata prom_opal_entry;
|
||||
#endif
|
||||
|
||||
#ifdef __BIG_ENDIAN__
|
||||
/* XXX Don't change this structure without updating opal-takeover.S */
|
||||
static struct opal_secondary_data {
|
||||
s64 ack; /* 0 */
|
||||
u64 go; /* 8 */
|
||||
struct opal_takeover_args args; /* 16 */
|
||||
} opal_secondary_data;
|
||||
|
||||
static u64 __initdata prom_opal_align;
|
||||
static u64 __initdata prom_opal_size;
|
||||
static int __initdata prom_rtas_start_cpu;
|
||||
static u64 __initdata prom_rtas_data;
|
||||
static u64 __initdata prom_rtas_entry;
|
||||
|
||||
extern char opal_secondary_entry;
|
||||
|
||||
static void __init prom_query_opal(void)
|
||||
{
|
||||
long rc;
|
||||
|
||||
/* We must not query for OPAL presence on a machine that
|
||||
* supports TNK takeover (970 blades), as this uses the same
|
||||
* h-call with different arguments and will crash
|
||||
*/
|
||||
if (PHANDLE_VALID(call_prom("finddevice", 1, 1,
|
||||
ADDR("/tnk-memory-map")))) {
|
||||
prom_printf("TNK takeover detected, skipping OPAL check\n");
|
||||
return;
|
||||
}
|
||||
|
||||
prom_printf("Querying for OPAL presence... ");
|
||||
|
||||
rc = opal_query_takeover(&prom_opal_size,
|
||||
&prom_opal_align);
|
||||
prom_debug("(rc = %ld) ", rc);
|
||||
if (rc != 0) {
|
||||
prom_printf("not there.\n");
|
||||
return;
|
||||
}
|
||||
of_platform = PLATFORM_OPAL;
|
||||
prom_printf(" there !\n");
|
||||
prom_debug(" opal_size = 0x%lx\n", prom_opal_size);
|
||||
prom_debug(" opal_align = 0x%lx\n", prom_opal_align);
|
||||
if (prom_opal_align < 0x10000)
|
||||
prom_opal_align = 0x10000;
|
||||
}
|
||||
|
||||
static int __init prom_rtas_call(int token, int nargs, int nret,
|
||||
int *outputs, ...)
|
||||
{
|
||||
struct rtas_args rtas_args;
|
||||
va_list list;
|
||||
int i;
|
||||
|
||||
rtas_args.token = token;
|
||||
rtas_args.nargs = nargs;
|
||||
rtas_args.nret = nret;
|
||||
rtas_args.rets = (rtas_arg_t *)&(rtas_args.args[nargs]);
|
||||
va_start(list, outputs);
|
||||
for (i = 0; i < nargs; ++i)
|
||||
rtas_args.args[i] = va_arg(list, rtas_arg_t);
|
||||
va_end(list);
|
||||
|
||||
for (i = 0; i < nret; ++i)
|
||||
rtas_args.rets[i] = 0;
|
||||
|
||||
opal_enter_rtas(&rtas_args, prom_rtas_data,
|
||||
prom_rtas_entry);
|
||||
|
||||
if (nret > 1 && outputs != NULL)
|
||||
for (i = 0; i < nret-1; ++i)
|
||||
outputs[i] = rtas_args.rets[i+1];
|
||||
return (nret > 0)? rtas_args.rets[0]: 0;
|
||||
}
|
||||
|
||||
static void __init prom_opal_hold_cpus(void)
|
||||
{
|
||||
int i, cnt, cpu, rc;
|
||||
long j;
|
||||
phandle node;
|
||||
char type[64];
|
||||
u32 servers[8];
|
||||
void *entry = (unsigned long *)&opal_secondary_entry;
|
||||
struct opal_secondary_data *data = &opal_secondary_data;
|
||||
|
||||
prom_debug("prom_opal_hold_cpus: start...\n");
|
||||
prom_debug(" - entry = 0x%x\n", entry);
|
||||
prom_debug(" - data = 0x%x\n", data);
|
||||
|
||||
data->ack = -1;
|
||||
data->go = 0;
|
||||
|
||||
/* look for cpus */
|
||||
for (node = 0; prom_next_node(&node); ) {
|
||||
type[0] = 0;
|
||||
prom_getprop(node, "device_type", type, sizeof(type));
|
||||
if (strcmp(type, "cpu") != 0)
|
||||
continue;
|
||||
|
||||
/* Skip non-configured cpus. */
|
||||
if (prom_getprop(node, "status", type, sizeof(type)) > 0)
|
||||
if (strcmp(type, "okay") != 0)
|
||||
continue;
|
||||
|
||||
cnt = prom_getprop(node, "ibm,ppc-interrupt-server#s", servers,
|
||||
sizeof(servers));
|
||||
if (cnt == PROM_ERROR)
|
||||
break;
|
||||
cnt >>= 2;
|
||||
for (i = 0; i < cnt; i++) {
|
||||
cpu = servers[i];
|
||||
prom_debug("CPU %d ... ", cpu);
|
||||
if (cpu == prom.cpu) {
|
||||
prom_debug("booted !\n");
|
||||
continue;
|
||||
}
|
||||
prom_debug("starting ... ");
|
||||
|
||||
/* Init the acknowledge var which will be reset by
|
||||
* the secondary cpu when it awakens from its OF
|
||||
* spinloop.
|
||||
*/
|
||||
data->ack = -1;
|
||||
rc = prom_rtas_call(prom_rtas_start_cpu, 3, 1,
|
||||
NULL, cpu, entry, data);
|
||||
prom_debug("rtas rc=%d ...", rc);
|
||||
|
||||
for (j = 0; j < 100000000 && data->ack == -1; j++) {
|
||||
HMT_low();
|
||||
mb();
|
||||
}
|
||||
HMT_medium();
|
||||
if (data->ack != -1)
|
||||
prom_debug("done, PIR=0x%x\n", data->ack);
|
||||
else
|
||||
prom_debug("timeout !\n");
|
||||
}
|
||||
}
|
||||
prom_debug("prom_opal_hold_cpus: end...\n");
|
||||
}
|
||||
|
||||
static void __init prom_opal_takeover(void)
|
||||
{
|
||||
struct opal_secondary_data *data = &opal_secondary_data;
|
||||
struct opal_takeover_args *args = &data->args;
|
||||
u64 align = prom_opal_align;
|
||||
u64 top_addr, opal_addr;
|
||||
|
||||
args->k_image = (u64)_stext;
|
||||
args->k_size = _end - _stext;
|
||||
args->k_entry = 0;
|
||||
args->k_entry2 = 0x60;
|
||||
|
||||
top_addr = _ALIGN_UP(args->k_size, align);
|
||||
|
||||
if (prom_initrd_start != 0) {
|
||||
args->rd_image = prom_initrd_start;
|
||||
args->rd_size = prom_initrd_end - args->rd_image;
|
||||
args->rd_loc = top_addr;
|
||||
top_addr = _ALIGN_UP(args->rd_loc + args->rd_size, align);
|
||||
}
|
||||
|
||||
/* Pickup an address for the HAL. We want to go really high
|
||||
* up to avoid problem with future kexecs. On the other hand
|
||||
* we don't want to be all over the TCEs on P5IOC2 machines
|
||||
* which are going to be up there too. We assume the machine
|
||||
* has plenty of memory, and we ask for the HAL for now to
|
||||
* be just below the 1G point, or above the initrd
|
||||
*/
|
||||
opal_addr = _ALIGN_DOWN(0x40000000 - prom_opal_size, align);
|
||||
if (opal_addr < top_addr)
|
||||
opal_addr = top_addr;
|
||||
args->hal_addr = opal_addr;
|
||||
|
||||
/* Copy the command line to the kernel image */
|
||||
strlcpy(boot_command_line, prom_cmd_line,
|
||||
COMMAND_LINE_SIZE);
|
||||
|
||||
prom_debug(" k_image = 0x%lx\n", args->k_image);
|
||||
prom_debug(" k_size = 0x%lx\n", args->k_size);
|
||||
prom_debug(" k_entry = 0x%lx\n", args->k_entry);
|
||||
prom_debug(" k_entry2 = 0x%lx\n", args->k_entry2);
|
||||
prom_debug(" hal_addr = 0x%lx\n", args->hal_addr);
|
||||
prom_debug(" rd_image = 0x%lx\n", args->rd_image);
|
||||
prom_debug(" rd_size = 0x%lx\n", args->rd_size);
|
||||
prom_debug(" rd_loc = 0x%lx\n", args->rd_loc);
|
||||
prom_printf("Performing OPAL takeover,this can take a few minutes..\n");
|
||||
prom_close_stdin();
|
||||
mb();
|
||||
data->go = 1;
|
||||
for (;;)
|
||||
opal_do_takeover(args);
|
||||
}
|
||||
#endif /* __BIG_ENDIAN__ */
|
||||
|
||||
/*
|
||||
* Allocate room for and instantiate OPAL
|
||||
*/
|
||||
|
@ -1597,12 +1402,6 @@ static void __init prom_instantiate_rtas(void)
|
|||
&val, sizeof(val)) != PROM_ERROR)
|
||||
rtas_has_query_cpu_stopped = true;
|
||||
|
||||
#if defined(CONFIG_PPC_POWERNV) && defined(__BIG_ENDIAN__)
|
||||
/* PowerVN takeover hack */
|
||||
prom_rtas_data = base;
|
||||
prom_rtas_entry = entry;
|
||||
prom_getprop(rtas_node, "start-cpu", &prom_rtas_start_cpu, 4);
|
||||
#endif
|
||||
prom_debug("rtas base = 0x%x\n", base);
|
||||
prom_debug("rtas entry = 0x%x\n", entry);
|
||||
prom_debug("rtas size = 0x%x\n", (long)size);
|
||||
|
@ -3027,16 +2826,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
|
|||
prom_instantiate_rtas();
|
||||
|
||||
#ifdef CONFIG_PPC_POWERNV
|
||||
#ifdef __BIG_ENDIAN__
|
||||
/* Detect HAL and try instanciating it & doing takeover */
|
||||
if (of_platform == PLATFORM_PSERIES_LPAR) {
|
||||
prom_query_opal();
|
||||
if (of_platform == PLATFORM_OPAL) {
|
||||
prom_opal_hold_cpus();
|
||||
prom_opal_takeover();
|
||||
}
|
||||
} else
|
||||
#endif /* __BIG_ENDIAN__ */
|
||||
if (of_platform == PLATFORM_OPAL)
|
||||
prom_instantiate_opal();
|
||||
#endif /* CONFIG_PPC_POWERNV */
|
||||
|
|
|
@ -21,9 +21,7 @@ _end enter_prom memcpy memset reloc_offset __secondary_hold
|
|||
__secondary_hold_acknowledge __secondary_hold_spinloop __start
|
||||
strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
|
||||
reloc_got2 kernstart_addr memstart_addr linux_banner _stext
|
||||
opal_query_takeover opal_do_takeover opal_enter_rtas opal_secondary_entry
|
||||
boot_command_line __prom_init_toc_start __prom_init_toc_end
|
||||
btext_setup_display TOC."
|
||||
__prom_init_toc_start __prom_init_toc_end btext_setup_display TOC."
|
||||
|
||||
NM="$1"
|
||||
OBJ="$2"
|
||||
|
|
|
@ -469,9 +469,17 @@ void __init smp_setup_cpu_maps(void)
|
|||
}
|
||||
|
||||
for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) {
|
||||
bool avail;
|
||||
|
||||
DBG(" thread %d -> cpu %d (hard id %d)\n",
|
||||
j, cpu, be32_to_cpu(intserv[j]));
|
||||
set_cpu_present(cpu, of_device_is_available(dn));
|
||||
|
||||
avail = of_device_is_available(dn);
|
||||
if (!avail)
|
||||
avail = !of_property_match_string(dn,
|
||||
"enable-method", "spin-table");
|
||||
|
||||
set_cpu_present(cpu, avail);
|
||||
set_hard_smp_processor_id(cpu, be32_to_cpu(intserv[j]));
|
||||
set_cpu_possible(cpu, true);
|
||||
cpu++;
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
|
||||
#include "signal.h"
|
||||
|
||||
#undef DEBUG_SIG
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
#define sys_rt_sigreturn compat_sys_rt_sigreturn
|
||||
|
@ -1063,10 +1062,6 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
|
|||
return 1;
|
||||
|
||||
badframe:
|
||||
#ifdef DEBUG_SIG
|
||||
printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
|
||||
regs, frame, newsp);
|
||||
#endif
|
||||
if (show_unhandled_signals)
|
||||
printk_ratelimited(KERN_INFO
|
||||
"%s[%d]: bad frame in handle_rt_signal32: "
|
||||
|
@ -1484,10 +1479,6 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
|
|||
return 1;
|
||||
|
||||
badframe:
|
||||
#ifdef DEBUG_SIG
|
||||
printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n",
|
||||
regs, frame, newsp);
|
||||
#endif
|
||||
if (show_unhandled_signals)
|
||||
printk_ratelimited(KERN_INFO
|
||||
"%s[%d]: bad frame in handle_signal32: "
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
|
||||
#include "signal.h"
|
||||
|
||||
#define DEBUG_SIG 0
|
||||
|
||||
#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
|
||||
#define FP_REGS_SIZE sizeof(elf_fpregset_t)
|
||||
|
@ -700,10 +699,6 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
|
|||
return 0;
|
||||
|
||||
badframe:
|
||||
#if DEBUG_SIG
|
||||
printk("badframe in sys_rt_sigreturn, regs=%p uc=%p &uc->uc_mcontext=%p\n",
|
||||
regs, uc, &uc->uc_mcontext);
|
||||
#endif
|
||||
if (show_unhandled_signals)
|
||||
printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
|
||||
current->comm, current->pid, "rt_sigreturn",
|
||||
|
@ -809,10 +804,6 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
|
|||
return 1;
|
||||
|
||||
badframe:
|
||||
#if DEBUG_SIG
|
||||
printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
|
||||
regs, frame, newsp);
|
||||
#endif
|
||||
if (show_unhandled_signals)
|
||||
printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
|
||||
current->comm, current->pid, "setup_rt_frame",
|
||||
|
|
|
@ -127,11 +127,6 @@ BEGIN_FTR_SECTION
|
|||
stw r10, HSTATE_PMC + 24(r13)
|
||||
stw r11, HSTATE_PMC + 28(r13)
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
|
||||
BEGIN_FTR_SECTION
|
||||
mfspr r9, SPRN_SIER
|
||||
std r8, HSTATE_MMCR + 40(r13)
|
||||
std r9, HSTATE_MMCR + 48(r13)
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
|
||||
31:
|
||||
|
||||
/*
|
||||
|
|
|
@ -410,17 +410,7 @@ void __init mmu_context_init(void)
|
|||
} else if (mmu_has_feature(MMU_FTR_TYPE_47x)) {
|
||||
first_context = 1;
|
||||
last_context = 65535;
|
||||
} else
|
||||
#ifdef CONFIG_PPC_BOOK3E_MMU
|
||||
if (mmu_has_feature(MMU_FTR_TYPE_3E)) {
|
||||
u32 mmucfg = mfspr(SPRN_MMUCFG);
|
||||
u32 pid_bits = (mmucfg & MMUCFG_PIDSIZE_MASK)
|
||||
>> MMUCFG_PIDSIZE_SHIFT;
|
||||
first_context = 1;
|
||||
last_context = (1UL << (pid_bits + 1)) - 1;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
first_context = 1;
|
||||
last_context = 255;
|
||||
}
|
||||
|
|
|
@ -485,7 +485,7 @@ static bool is_ebb_event(struct perf_event *event)
|
|||
* check that the PMU supports EBB, meaning those that don't can still
|
||||
* use bit 63 of the event code for something else if they wish.
|
||||
*/
|
||||
return (ppmu->flags & PPMU_EBB) &&
|
||||
return (ppmu->flags & PPMU_ARCH_207S) &&
|
||||
((event->attr.config >> PERF_EVENT_CONFIG_EBB_SHIFT) & 1);
|
||||
}
|
||||
|
||||
|
@ -777,7 +777,7 @@ void perf_event_print_debug(void)
|
|||
if (ppmu->flags & PPMU_HAS_SIER)
|
||||
sier = mfspr(SPRN_SIER);
|
||||
|
||||
if (ppmu->flags & PPMU_EBB) {
|
||||
if (ppmu->flags & PPMU_ARCH_207S) {
|
||||
pr_info("MMCR2: %016lx EBBHR: %016lx\n",
|
||||
mfspr(SPRN_MMCR2), mfspr(SPRN_EBBHR));
|
||||
pr_info("EBBRR: %016lx BESCR: %016lx\n",
|
||||
|
@ -996,7 +996,22 @@ static void power_pmu_read(struct perf_event *event)
|
|||
} while (local64_cmpxchg(&event->hw.prev_count, prev, val) != prev);
|
||||
|
||||
local64_add(delta, &event->count);
|
||||
local64_sub(delta, &event->hw.period_left);
|
||||
|
||||
/*
|
||||
* A number of places program the PMC with (0x80000000 - period_left).
|
||||
* We never want period_left to be less than 1 because we will program
|
||||
* the PMC with a value >= 0x800000000 and an edge detected PMC will
|
||||
* roll around to 0 before taking an exception. We have seen this
|
||||
* on POWER8.
|
||||
*
|
||||
* To fix this, clamp the minimum value of period_left to 1.
|
||||
*/
|
||||
do {
|
||||
prev = local64_read(&event->hw.period_left);
|
||||
val = prev - delta;
|
||||
if (val < 1)
|
||||
val = 1;
|
||||
} while (local64_cmpxchg(&event->hw.period_left, prev, val) != prev);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1300,6 +1315,9 @@ static void power_pmu_enable(struct pmu *pmu)
|
|||
|
||||
write_mmcr0(cpuhw, mmcr0);
|
||||
|
||||
if (ppmu->flags & PPMU_ARCH_207S)
|
||||
mtspr(SPRN_MMCR2, 0);
|
||||
|
||||
/*
|
||||
* Enable instruction sampling if necessary
|
||||
*/
|
||||
|
@ -1696,7 +1714,7 @@ static int power_pmu_event_init(struct perf_event *event)
|
|||
|
||||
if (has_branch_stack(event)) {
|
||||
/* PMU has BHRB enabled */
|
||||
if (!(ppmu->flags & PPMU_BHRB))
|
||||
if (!(ppmu->flags & PPMU_ARCH_207S))
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
|
|
@ -792,7 +792,7 @@ static struct power_pmu power8_pmu = {
|
|||
.get_constraint = power8_get_constraint,
|
||||
.get_alternatives = power8_get_alternatives,
|
||||
.disable_pmc = power8_disable_pmc,
|
||||
.flags = PPMU_HAS_SSLOT | PPMU_HAS_SIER | PPMU_BHRB | PPMU_EBB,
|
||||
.flags = PPMU_HAS_SSLOT | PPMU_HAS_SIER | PPMU_ARCH_207S,
|
||||
.n_generic = ARRAY_SIZE(power8_generic_events),
|
||||
.generic_events = power8_generic_events,
|
||||
.cache_events = &power8_cache_events,
|
||||
|
|
|
@ -125,7 +125,7 @@ static ssize_t show_throttle(struct cbe_pmd_regs __iomem *pmd_regs, char *buf, i
|
|||
static ssize_t store_throttle(struct cbe_pmd_regs __iomem *pmd_regs, const char *buf, size_t size, int pos)
|
||||
{
|
||||
u64 reg_value;
|
||||
int temp;
|
||||
unsigned int temp;
|
||||
u64 new_value;
|
||||
int ret;
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COREDUMP
|
||||
int elf_coredump_extra_notes_size(void)
|
||||
{
|
||||
struct spufs_calls *calls;
|
||||
|
@ -142,6 +143,7 @@ int elf_coredump_extra_notes_write(struct coredump_params *cprm)
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void notify_spus_active(void)
|
||||
{
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
|
||||
obj-$(CONFIG_SPU_FS) += spufs.o
|
||||
spufs-y += inode.o file.o context.o syscalls.o coredump.o
|
||||
spufs-y += inode.o file.o context.o syscalls.o
|
||||
spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o
|
||||
spufs-y += switch.o fault.o lscsa_alloc.o
|
||||
spufs-$(CONFIG_COREDUMP) += coredump.o
|
||||
|
||||
# magic for the trace events
|
||||
CFLAGS_sched.o := -I$(src)
|
||||
|
|
|
@ -79,8 +79,10 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
|
|||
struct spufs_calls spufs_calls = {
|
||||
.create_thread = do_spu_create,
|
||||
.spu_run = do_spu_run,
|
||||
.coredump_extra_notes_size = spufs_coredump_extra_notes_size,
|
||||
.coredump_extra_notes_write = spufs_coredump_extra_notes_write,
|
||||
.notify_spus_active = do_notify_spus_active,
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef CONFIG_COREDUMP
|
||||
.coredump_extra_notes_size = spufs_coredump_extra_notes_size,
|
||||
.coredump_extra_notes_write = spufs_coredump_extra_notes_write,
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
obj-y += setup.o opal-takeover.o opal-wrappers.o opal.o opal-async.o
|
||||
obj-y += setup.o opal-wrappers.o opal.o opal-async.o
|
||||
obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
|
||||
obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
|
||||
obj-y += opal-msglog.o
|
||||
|
|
|
@ -1,140 +0,0 @@
|
|||
/*
|
||||
* PowerNV OPAL takeover assembly code, for use by prom_init.c
|
||||
*
|
||||
* Copyright 2011 IBM Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <asm/ppc_asm.h>
|
||||
#include <asm/hvcall.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/opal.h>
|
||||
|
||||
#define H_HAL_TAKEOVER 0x5124
|
||||
#define H_HAL_TAKEOVER_QUERY_MAGIC -1
|
||||
|
||||
.text
|
||||
_GLOBAL(opal_query_takeover)
|
||||
mfcr r0
|
||||
stw r0,8(r1)
|
||||
stdu r1,-STACKFRAMESIZE(r1)
|
||||
std r3,STK_PARAM(R3)(r1)
|
||||
std r4,STK_PARAM(R4)(r1)
|
||||
li r3,H_HAL_TAKEOVER
|
||||
li r4,H_HAL_TAKEOVER_QUERY_MAGIC
|
||||
HVSC
|
||||
addi r1,r1,STACKFRAMESIZE
|
||||
ld r10,STK_PARAM(R3)(r1)
|
||||
std r4,0(r10)
|
||||
ld r10,STK_PARAM(R4)(r1)
|
||||
std r5,0(r10)
|
||||
lwz r0,8(r1)
|
||||
mtcrf 0xff,r0
|
||||
blr
|
||||
|
||||
_GLOBAL(opal_do_takeover)
|
||||
mfcr r0
|
||||
stw r0,8(r1)
|
||||
mflr r0
|
||||
std r0,16(r1)
|
||||
bl __opal_do_takeover
|
||||
ld r0,16(r1)
|
||||
mtlr r0
|
||||
lwz r0,8(r1)
|
||||
mtcrf 0xff,r0
|
||||
blr
|
||||
|
||||
__opal_do_takeover:
|
||||
ld r4,0(r3)
|
||||
ld r5,0x8(r3)
|
||||
ld r6,0x10(r3)
|
||||
ld r7,0x18(r3)
|
||||
ld r8,0x20(r3)
|
||||
ld r9,0x28(r3)
|
||||
ld r10,0x30(r3)
|
||||
ld r11,0x38(r3)
|
||||
li r3,H_HAL_TAKEOVER
|
||||
HVSC
|
||||
blr
|
||||
|
||||
.globl opal_secondary_entry
|
||||
opal_secondary_entry:
|
||||
mr r31,r3
|
||||
mfmsr r11
|
||||
li r12,(MSR_SF | MSR_ISF)@highest
|
||||
sldi r12,r12,48
|
||||
or r11,r11,r12
|
||||
mtmsrd r11
|
||||
isync
|
||||
mfspr r4,SPRN_PIR
|
||||
std r4,0(r3)
|
||||
1: HMT_LOW
|
||||
ld r4,8(r3)
|
||||
cmpli cr0,r4,0
|
||||
beq 1b
|
||||
HMT_MEDIUM
|
||||
1: addi r3,r31,16
|
||||
bl __opal_do_takeover
|
||||
b 1b
|
||||
|
||||
_GLOBAL(opal_enter_rtas)
|
||||
mflr r0
|
||||
std r0,16(r1)
|
||||
stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
|
||||
|
||||
/* Because PROM is running in 32b mode, it clobbers the high order half
|
||||
* of all registers that it saves. We therefore save those registers
|
||||
* PROM might touch to the stack. (r0, r3-r13 are caller saved)
|
||||
*/
|
||||
SAVE_GPR(2, r1)
|
||||
SAVE_GPR(13, r1)
|
||||
SAVE_8GPRS(14, r1)
|
||||
SAVE_10GPRS(22, r1)
|
||||
mfcr r10
|
||||
mfmsr r11
|
||||
std r10,_CCR(r1)
|
||||
std r11,_MSR(r1)
|
||||
|
||||
/* Get the PROM entrypoint */
|
||||
mtlr r5
|
||||
|
||||
/* Switch MSR to 32 bits mode
|
||||
*/
|
||||
li r12,1
|
||||
rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
|
||||
andc r11,r11,r12
|
||||
li r12,1
|
||||
rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
|
||||
andc r11,r11,r12
|
||||
mtmsrd r11
|
||||
isync
|
||||
|
||||
/* Enter RTAS here... */
|
||||
blrl
|
||||
|
||||
/* Just make sure that r1 top 32 bits didn't get
|
||||
* corrupt by OF
|
||||
*/
|
||||
rldicl r1,r1,0,32
|
||||
|
||||
/* Restore the MSR (back to 64 bits) */
|
||||
ld r0,_MSR(r1)
|
||||
MTMSRD(r0)
|
||||
isync
|
||||
|
||||
/* Restore other registers */
|
||||
REST_GPR(2, r1)
|
||||
REST_GPR(13, r1)
|
||||
REST_8GPRS(14, r1)
|
||||
REST_10GPRS(22, r1)
|
||||
ld r4,_CCR(r1)
|
||||
mtcr r4
|
||||
|
||||
addi r1,r1,PROM_FRAME_SIZE
|
||||
ld r0,16(r1)
|
||||
mtlr r0
|
||||
blr
|
|
@ -476,6 +476,11 @@ void __init alloc_dart_table(void)
|
|||
*/
|
||||
dart_tablebase = (unsigned long)
|
||||
__va(memblock_alloc_base(1UL<<24, 1UL<<24, 0x80000000L));
|
||||
/*
|
||||
* The DART space is later unmapped from the kernel linear mapping and
|
||||
* accessing dart_tablebase during kmemleak scanning will fault.
|
||||
*/
|
||||
kmemleak_no_scan((void *)dart_tablebase);
|
||||
|
||||
printk(KERN_INFO "DART table allocated at: %lx\n", dart_tablebase);
|
||||
}
|
||||
|
|
|
@ -1257,7 +1257,8 @@ static unsigned int smu_fpoll(struct file *file, poll_table *wait)
|
|||
if (pp->busy && pp->cmd.status != 1)
|
||||
mask |= POLLIN;
|
||||
spin_unlock_irqrestore(&pp->lock, flags);
|
||||
} if (pp->mode == smu_file_events) {
|
||||
}
|
||||
if (pp->mode == smu_file_events) {
|
||||
/* Not yet implemented */
|
||||
}
|
||||
return mask;
|
||||
|
|
|
@ -2,7 +2,7 @@ PROGS := tm-resched-dscr
|
|||
|
||||
all: $(PROGS)
|
||||
|
||||
$(PROGS):
|
||||
$(PROGS): ../harness.c
|
||||
|
||||
run_tests: all
|
||||
@-for PROG in $(PROGS); do \
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include <assert.h>
|
||||
#include <asm/tm.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#define TBEGIN ".long 0x7C00051D ;"
|
||||
#define TEND ".long 0x7C00055D ;"
|
||||
#define TCHECK ".long 0x7C00059C ;"
|
||||
|
@ -36,7 +38,8 @@
|
|||
#define SPRN_TEXASR 0x82
|
||||
#define SPRN_DSCR 0x03
|
||||
|
||||
int main(void) {
|
||||
int test_body(void)
|
||||
{
|
||||
uint64_t rv, dscr1 = 1, dscr2, texasr;
|
||||
|
||||
printf("Check DSCR TM context switch: ");
|
||||
|
@ -81,10 +84,15 @@ int main(void) {
|
|||
}
|
||||
if (dscr2 != dscr1) {
|
||||
printf(" FAIL\n");
|
||||
exit(EXIT_FAILURE);
|
||||
return 1;
|
||||
} else {
|
||||
printf(" OK\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return test_harness(test_body, "tm_resched_dscr");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue