diff options
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r-- | arch/powerpc/platforms/pseries/iommu.c | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/lpar.c | 13 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/plpar_wrappers.h | 120 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 15 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/smp.c | 3 |
5 files changed, 143 insertions, 11 deletions
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index a73faafaac8..513e2723149 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -42,13 +42,14 @@ #include <asm/pci-bridge.h> #include <asm/machdep.h> #include <asm/abs_addr.h> -#include <asm/plpar_wrappers.h> #include <asm/pSeries_reconfig.h> #include <asm/systemcfg.h> #include <asm/firmware.h> #include <asm/tce.h> #include <asm/ppc-pci.h> +#include "plpar_wrappers.h" + #define DBG(fmt...) extern int is_python(struct device_node *); diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 268d8362dde..e384a5a9179 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -38,7 +38,8 @@ #include <asm/prom.h> #include <asm/abs_addr.h> #include <asm/cputable.h> -#include <asm/plpar_wrappers.h> + +#include "plpar_wrappers.h" #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) @@ -260,22 +261,18 @@ out: void vpa_init(int cpu) { int hwcpu = get_hard_smp_processor_id(cpu); - unsigned long vpa = (unsigned long)&(paca[cpu].lppaca); + unsigned long vpa = __pa(&paca[cpu].lppaca); long ret; - unsigned long flags; - - /* Register the Virtual Processor Area (VPA) */ - flags = 1UL << (63 - 18); if (cpu_has_feature(CPU_FTR_ALTIVEC)) paca[cpu].lppaca.vmxregs_in_use = 1; - ret = register_vpa(flags, hwcpu, __pa(vpa)); + ret = register_vpa(hwcpu, vpa); if (ret) printk(KERN_ERR "WARNING: vpa_init: VPA registration for " "cpu %d (hw %d) of area %lx returns %ld\n", - cpu, hwcpu, __pa(vpa), ret); + cpu, hwcpu, vpa, ret); } long pSeries_lpar_hpte_insert(unsigned long hpte_group, diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h new file mode 100644 index 00000000000..382f8c5b0e7 --- /dev/null +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h @@ -0,0 +1,120 @@ +#ifndef _PSERIES_PLPAR_WRAPPERS_H +#define _PSERIES_PLPAR_WRAPPERS_H + +#include <asm/hvcall.h> + +static inline long poll_pending(void) +{ + unsigned long dummy; + return plpar_hcall(H_POLL_PENDING, 0, 0, 0, 0, &dummy, &dummy, &dummy); +} + +static inline long prod_processor(void) +{ + plpar_hcall_norets(H_PROD); + return 0; +} + +static inline long cede_processor(void) +{ + plpar_hcall_norets(H_CEDE); + return 0; +} + +static inline long vpa_call(unsigned long flags, unsigned long cpu, + unsigned long vpa) +{ + /* flags are in bits 16-18 (counting from most significant bit) */ + flags = flags << (63 - 18); + + return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa); +} + +static inline long unregister_vpa(unsigned long cpu, unsigned long vpa) +{ + return vpa_call(0x5, cpu, vpa); +} + +static inline long register_vpa(unsigned long cpu, unsigned long vpa) +{ + return vpa_call(0x1, cpu, vpa); +} + +extern void vpa_init(int cpu); + +static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex, + unsigned long avpn, unsigned long *old_pteh_ret, + unsigned long *old_ptel_ret) +{ + unsigned long dummy; + return plpar_hcall(H_REMOVE, flags, ptex, avpn, 0, old_pteh_ret, + old_ptel_ret, &dummy); +} + +static inline long plpar_pte_read(unsigned long flags, unsigned long ptex, + unsigned long *old_pteh_ret, unsigned long *old_ptel_ret) +{ + unsigned long dummy; + return plpar_hcall(H_READ, flags, ptex, 0, 0, old_pteh_ret, + old_ptel_ret, &dummy); +} + +static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, + unsigned long avpn) +{ + return plpar_hcall_norets(H_PROTECT, flags, ptex, avpn); +} + +static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba, + unsigned long *tce_ret) +{ + unsigned long dummy; + return plpar_hcall(H_GET_TCE, liobn, ioba, 0, 0, tce_ret, &dummy, + &dummy); +} + +static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba, + unsigned long tceval) +{ + return plpar_hcall_norets(H_PUT_TCE, liobn, ioba, tceval); +} + +static inline long plpar_tce_put_indirect(unsigned long liobn, + unsigned long ioba, unsigned long page, unsigned long count) +{ + return plpar_hcall_norets(H_PUT_TCE_INDIRECT, liobn, ioba, page, count); +} + +static inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba, + unsigned long tceval, unsigned long count) +{ + return plpar_hcall_norets(H_STUFF_TCE, liobn, ioba, tceval, count); +} + +static inline long plpar_get_term_char(unsigned long termno, + unsigned long *len_ret, char *buf_ret) +{ + unsigned long *lbuf = (unsigned long *)buf_ret; /* TODO: alignment? */ + return plpar_hcall(H_GET_TERM_CHAR, termno, 0, 0, 0, len_ret, + lbuf + 0, lbuf + 1); +} + +static inline long plpar_put_term_char(unsigned long termno, unsigned long len, + const char *buffer) +{ + unsigned long *lbuf = (unsigned long *)buffer; /* TODO: alignment? */ + return plpar_hcall_norets(H_PUT_TERM_CHAR, termno, len, lbuf[0], + lbuf[1]); +} + +static inline long plpar_set_xdabr(unsigned long address, unsigned long flags) +{ + return plpar_hcall_norets(H_SET_XDABR, address, flags); +} + +static inline long plpar_set_dabr(unsigned long val) +{ + return plpar_hcall_norets(H_SET_DABR, val); +} + +#endif /* _PSERIES_PLPAR_WRAPPERS_H */ diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index f73d69143d3..65bee939eec 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -58,7 +58,6 @@ #include <asm/irq.h> #include <asm/time.h> #include <asm/nvram.h> -#include <asm/plpar_wrappers.h> #include "xics.h" #include <asm/firmware.h> #include <asm/pmc.h> @@ -67,6 +66,8 @@ #include <asm/i8259.h> #include <asm/udbg.h> +#include "plpar_wrappers.h" + #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) #else @@ -350,6 +351,16 @@ static void pSeries_mach_cpu_die(void) for(;;); } +static int pseries_set_dabr(unsigned long dabr) +{ + if (firmware_has_feature(FW_FEATURE_XDABR)) { + /* We want to catch accesses from kernel and userspace */ + return plpar_set_xdabr(dabr, H_DABRX_KERNEL | H_DABRX_USER); + } + + return plpar_set_dabr(dabr); +} + /* * Early initialization. Relocation is on but do not reference unbolted pages @@ -385,6 +396,8 @@ static void __init pSeries_init_early(void) DBG("Hello World !\n"); } + if (firmware_has_feature(FW_FEATURE_XDABR | FW_FEATURE_DABR)) + ppc_md.set_dabr = pseries_set_dabr; iommu_init_early_pSeries(); diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 9c9458ddfc2..7a243e8ccd7 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -44,10 +44,11 @@ #include <asm/firmware.h> #include <asm/system.h> #include <asm/rtas.h> -#include <asm/plpar_wrappers.h> #include <asm/pSeries_reconfig.h> #include <asm/mpic.h> +#include "plpar_wrappers.h" + #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) #else |