diff options
Diffstat (limited to 'arch/powerpc/include')
37 files changed, 717 insertions, 251 deletions
diff --git a/arch/powerpc/include/asm/cpm.h b/arch/powerpc/include/asm/cpm.h index 24d79e3abd8..0835eb977ba 100644 --- a/arch/powerpc/include/asm/cpm.h +++ b/arch/powerpc/include/asm/cpm.h @@ -3,8 +3,47 @@ #include <linux/compiler.h> #include <linux/types.h> +#include <linux/errno.h> #include <linux/of.h> +/* + * USB Controller pram common to QE and CPM. + */ +struct usb_ctlr { + u8 usb_usmod; + u8 usb_usadr; + u8 usb_uscom; + u8 res1[1]; + __be16 usb_usep[4]; + u8 res2[4]; + __be16 usb_usber; + u8 res3[2]; + __be16 usb_usbmr; + u8 res4[1]; + u8 usb_usbs; + /* Fields down below are QE-only */ + __be16 usb_ussft; + u8 res5[2]; + __be16 usb_usfrn; + u8 res6[0x22]; +} __attribute__ ((packed)); + +/* + * Function code bits, usually generic to devices. + */ +#ifdef CONFIG_CPM1 +#define CPMFCR_GBL ((u_char)0x00) /* Flag doesn't exist in CPM1 */ +#define CPMFCR_TC2 ((u_char)0x00) /* Flag doesn't exist in CPM1 */ +#define CPMFCR_DTB ((u_char)0x00) /* Flag doesn't exist in CPM1 */ +#define CPMFCR_BDB ((u_char)0x00) /* Flag doesn't exist in CPM1 */ +#else +#define CPMFCR_GBL ((u_char)0x20) /* Set memory snooping */ +#define CPMFCR_TC2 ((u_char)0x04) /* Transfer code 2 value */ +#define CPMFCR_DTB ((u_char)0x02) /* Use local bus for data when set */ +#define CPMFCR_BDB ((u_char)0x01) /* Use local bus for BD when set */ +#endif +#define CPMFCR_EB ((u_char)0x10) /* Set big endian byte order */ + /* Opcodes common to CPM1 and CPM2 */ #define CPM_CR_INIT_TRX ((ushort)0x0000) @@ -93,13 +132,56 @@ typedef struct cpm_buf_desc { #define BD_I2C_START (0x0400) int cpm_muram_init(void); + +#if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) unsigned long cpm_muram_alloc(unsigned long size, unsigned long align); int cpm_muram_free(unsigned long offset); unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); void __iomem *cpm_muram_addr(unsigned long offset); unsigned long cpm_muram_offset(void __iomem *addr); dma_addr_t cpm_muram_dma(void __iomem *addr); +#else +static inline unsigned long cpm_muram_alloc(unsigned long size, + unsigned long align) +{ + return -ENOSYS; +} + +static inline int cpm_muram_free(unsigned long offset) +{ + return -ENOSYS; +} + +static inline unsigned long cpm_muram_alloc_fixed(unsigned long offset, + unsigned long size) +{ + return -ENOSYS; +} + +static inline void __iomem *cpm_muram_addr(unsigned long offset) +{ + return NULL; +} + +static inline unsigned long cpm_muram_offset(void __iomem *addr) +{ + return -ENOSYS; +} + +static inline dma_addr_t cpm_muram_dma(void __iomem *addr) +{ + return 0; +} +#endif /* defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) */ + +#ifdef CONFIG_CPM int cpm_command(u32 command, u8 opcode); +#else +static inline int cpm_command(u32 command, u8 opcode) +{ + return -ENOSYS; +} +#endif /* CONFIG_CPM */ int cpm2_gpiochip_add32(struct device_node *np); diff --git a/arch/powerpc/include/asm/cpm1.h b/arch/powerpc/include/asm/cpm1.h index 7685ffde882..81b01192f44 100644 --- a/arch/powerpc/include/asm/cpm1.h +++ b/arch/powerpc/include/asm/cpm1.h @@ -478,51 +478,6 @@ typedef struct iic { char res2[2]; /* Reserved */ } iic_t; -/* SPI parameter RAM. -*/ -typedef struct spi { - ushort spi_rbase; /* Rx Buffer descriptor base address */ - ushort spi_tbase; /* Tx Buffer descriptor base address */ - u_char spi_rfcr; /* Rx function code */ - u_char spi_tfcr; /* Tx function code */ - ushort spi_mrblr; /* Max receive buffer length */ - uint spi_rstate; /* Internal */ - uint spi_rdp; /* Internal */ - ushort spi_rbptr; /* Internal */ - ushort spi_rbc; /* Internal */ - uint spi_rxtmp; /* Internal */ - uint spi_tstate; /* Internal */ - uint spi_tdp; /* Internal */ - ushort spi_tbptr; /* Internal */ - ushort spi_tbc; /* Internal */ - uint spi_txtmp; /* Internal */ - uint spi_res; - ushort spi_rpbase; /* Relocation pointer */ - ushort spi_res2; -} spi_t; - -/* SPI Mode register. -*/ -#define SPMODE_LOOP ((ushort)0x4000) /* Loopback */ -#define SPMODE_CI ((ushort)0x2000) /* Clock Invert */ -#define SPMODE_CP ((ushort)0x1000) /* Clock Phase */ -#define SPMODE_DIV16 ((ushort)0x0800) /* BRG/16 mode */ -#define SPMODE_REV ((ushort)0x0400) /* Reversed Data */ -#define SPMODE_MSTR ((ushort)0x0200) /* SPI Master */ -#define SPMODE_EN ((ushort)0x0100) /* Enable */ -#define SPMODE_LENMSK ((ushort)0x00f0) /* character length */ -#define SPMODE_LEN4 ((ushort)0x0030) /* 4 bits per char */ -#define SPMODE_LEN8 ((ushort)0x0070) /* 8 bits per char */ -#define SPMODE_LEN16 ((ushort)0x00f0) /* 16 bits per char */ -#define SPMODE_PMMSK ((ushort)0x000f) /* prescale modulus */ - -/* SPIE fields */ -#define SPIE_MME 0x20 -#define SPIE_TXE 0x10 -#define SPIE_BSY 0x04 -#define SPIE_TXB 0x02 -#define SPIE_RXB 0x01 - /* * RISC Controller Configuration Register definitons */ diff --git a/arch/powerpc/include/asm/cpm2.h b/arch/powerpc/include/asm/cpm2.h index 990ff191da8..f42e9baf3a4 100644 --- a/arch/powerpc/include/asm/cpm2.h +++ b/arch/powerpc/include/asm/cpm2.h @@ -124,14 +124,6 @@ static inline void cpm2_fastbrg(uint brg, uint rate, int div16) __cpm2_setbrg(brg, rate, CPM2_BRG_INT_CLK, div16, CPM_BRG_EXTC_INT); } -/* Function code bits, usually generic to devices. -*/ -#define CPMFCR_GBL ((u_char)0x20) /* Set memory snooping */ -#define CPMFCR_EB ((u_char)0x10) /* Set big endian byte order */ -#define CPMFCR_TC2 ((u_char)0x04) /* Transfer code 2 value */ -#define CPMFCR_DTB ((u_char)0x02) /* Use local bus for data when set */ -#define CPMFCR_BDB ((u_char)0x01) /* Use local bus for BD when set */ - /* Parameter RAM offsets from the base. */ #define PROFF_SCC1 ((uint)0x8000) @@ -654,45 +646,6 @@ typedef struct iic { uint iic_txtmp; /* Internal */ } iic_t; -/* SPI parameter RAM. -*/ -typedef struct spi { - ushort spi_rbase; /* Rx Buffer descriptor base address */ - ushort spi_tbase; /* Tx Buffer descriptor base address */ - u_char spi_rfcr; /* Rx function code */ - u_char spi_tfcr; /* Tx function code */ - ushort spi_mrblr; /* Max receive buffer length */ - uint spi_rstate; /* Internal */ - uint spi_rdp; /* Internal */ - ushort spi_rbptr; /* Internal */ - ushort spi_rbc; /* Internal */ - uint spi_rxtmp; /* Internal */ - uint spi_tstate; /* Internal */ - uint spi_tdp; /* Internal */ - ushort spi_tbptr; /* Internal */ - ushort spi_tbc; /* Internal */ - uint spi_txtmp; /* Internal */ - uint spi_res; /* Tx temp. */ - uint spi_res1[4]; /* SDMA temp. */ -} spi_t; - -/* SPI Mode register. -*/ -#define SPMODE_LOOP ((ushort)0x4000) /* Loopback */ -#define SPMODE_CI ((ushort)0x2000) /* Clock Invert */ -#define SPMODE_CP ((ushort)0x1000) /* Clock Phase */ -#define SPMODE_DIV16 ((ushort)0x0800) /* BRG/16 mode */ -#define SPMODE_REV ((ushort)0x0400) /* Reversed Data */ -#define SPMODE_MSTR ((ushort)0x0200) /* SPI Master */ -#define SPMODE_EN ((ushort)0x0100) /* Enable */ -#define SPMODE_LENMSK ((ushort)0x00f0) /* character length */ -#define SPMODE_PMMSK ((ushort)0x000f) /* prescale modulus */ - -#define SPMODE_LEN(x) ((((x)-1)&0xF)<<4) -#define SPMODE_PM(x) ((x) &0xF) - -#define SPI_EB ((u_char)0x10) /* big endian byte order */ - /* IDMA parameter RAM */ typedef struct idma { diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index a98653b2623..57c40007199 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -147,6 +147,7 @@ .globl label##_pSeries; \ label##_pSeries: \ HMT_MEDIUM; \ + DO_KVM n; \ mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) @@ -170,6 +171,7 @@ label##_pSeries: \ .globl label##_pSeries; \ label##_pSeries: \ HMT_MEDIUM; \ + DO_KVM n; \ mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \ mfspr r13,SPRN_SPRG_PACA; /* get paca address into r13 */ \ std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \ diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index b1dafb6a974..5856a66ab40 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -3,6 +3,10 @@ #include <asm/page.h> +pte_t *huge_pte_offset_and_shift(struct mm_struct *mm, + unsigned long addr, unsigned *shift); + +void flush_dcache_icache_hugepage(struct page *page); int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, unsigned long len); @@ -11,12 +15,6 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr, unsigned long end, unsigned long floor, unsigned long ceiling); -void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pte); - -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, - pte_t *ptep); - /* * The version of vma_mmu_pagesize() in arch/powerpc/mm/hugetlbpage.c needs * to override the version in mm/hugetlb.c @@ -42,9 +40,26 @@ static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm) { } + +static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + set_pte_at(mm, addr, ptep, pte); +} + +static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +{ + unsigned long old = pte_update(mm, addr, ptep, ~0UL, 1); + return __pte(old); +} + static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { + pte_t pte; + pte = huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); + flush_tlb_page(vma, addr); } static inline int huge_pte_none(pte_t pte) diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index c27caac47ad..f0275818b95 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -212,6 +212,19 @@ #define H_QUERY_INT_STATE 0x1E4 #define H_POLL_PENDING 0x1D8 #define H_ILLAN_ATTRIBUTES 0x244 +#define H_MODIFY_HEA_QP 0x250 +#define H_QUERY_HEA_QP 0x254 +#define H_QUERY_HEA 0x258 +#define H_QUERY_HEA_PORT 0x25C +#define H_MODIFY_HEA_PORT 0x260 +#define H_REG_BCMC 0x264 +#define H_DEREG_BCMC 0x268 +#define H_REGISTER_HEA_RPAGES 0x26C +#define H_DISABLE_AND_GET_HEA 0x270 +#define H_GET_HEA_INFO 0x274 +#define H_ALLOC_HEA_RESOURCE 0x278 +#define H_ADD_CONN 0x284 +#define H_DEL_CONN 0x288 #define H_JOIN 0x298 #define H_VASI_STATE 0x2A4 #define H_ENABLE_CRQ 0x2B0 diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index abbc2aaaced..9f4c9d4f580 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -64,11 +64,6 @@ extern void iseries_handle_interrupts(void); get_paca()->hard_enabled = 0; \ } while(0) -static inline int irqs_disabled_flags(unsigned long flags) -{ - return flags == 0; -} - #else #if defined(CONFIG_BOOKE) diff --git a/arch/powerpc/include/asm/immap_cpm2.h b/arch/powerpc/include/asm/immap_cpm2.h index d4f069bf0e5..7c64fda5357 100644 --- a/arch/powerpc/include/asm/immap_cpm2.h +++ b/arch/powerpc/include/asm/immap_cpm2.h @@ -549,7 +549,7 @@ typedef struct comm_proc { /* USB Controller. */ -typedef struct usb_ctlr { +typedef struct cpm_usb_ctlr { u8 usb_usmod; u8 usb_usadr; u8 usb_uscom; diff --git a/arch/powerpc/include/asm/immap_qe.h b/arch/powerpc/include/asm/immap_qe.h index c346d0bcd23..4e10f508570 100644 --- a/arch/powerpc/include/asm/immap_qe.h +++ b/arch/powerpc/include/asm/immap_qe.h @@ -210,7 +210,7 @@ struct sir { } __attribute__ ((packed)); /* USB Controller */ -struct usb_ctlr { +struct qe_usb_ctlr { u8 usb_usmod; u8 usb_usadr; u8 usb_uscom; @@ -229,7 +229,7 @@ struct usb_ctlr { } __attribute__ ((packed)); /* MCC */ -struct mcc { +struct qe_mcc { __be32 mcce; /* MCC event register */ __be32 mccm; /* MCC mask register */ __be32 mccf; /* MCC configuration register */ @@ -431,9 +431,9 @@ struct qe_immap { struct qe_mux qmx; /* QE Multiplexer */ struct qe_timers qet; /* QE Timers */ struct spi spi[0x2]; /* spi */ - struct mcc mcc; /* mcc */ + struct qe_mcc mcc; /* mcc */ struct qe_brg brg; /* brg */ - struct usb_ctlr usb; /* USB */ + struct qe_usb_ctlr usb; /* USB */ struct si1 si1; /* SI */ u8 res11[0x800]; struct sir sir; /* SI Routing Tables */ diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index bbcd1aaf3df..e054baef184 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h @@ -17,8 +17,6 @@ #include <asm/atomic.h> -#define get_irq_desc(irq) (&irq_desc[(irq)]) - /* Define a way to iterate across irqs. */ #define for_each_irq(i) \ for ((i) = 0; (i) < NR_IRQS; ++(i)) @@ -34,12 +32,15 @@ extern atomic_t ppc_n_lost_interrupts; */ #define NO_IRQ_IGNORE ((unsigned int)-1) -/* Total number of virq in the platform (make it a CONFIG_* option ? */ -#define NR_IRQS 512 +/* Total number of virq in the platform */ +#define NR_IRQS CONFIG_NR_IRQS /* Number of irqs reserved for the legacy controller */ #define NUM_ISA_INTERRUPTS 16 +/* Same thing, used by the generic IRQ code */ +#define NR_IRQS_LEGACY NUM_ISA_INTERRUPTS + /* This type is the placeholder for a hardware interrupt number. It has to * be big enough to enclose whatever representation is used by a given * platform. @@ -99,7 +100,7 @@ struct irq_host_ops { * interrupt controller has for that line) */ int (*xlate)(struct irq_host *h, struct device_node *ctrler, - u32 *intspec, unsigned int intsize, + const u32 *intspec, unsigned int intsize, irq_hw_number_t *out_hwirq, unsigned int *out_type); }; @@ -313,7 +314,7 @@ extern void irq_free_virt(unsigned int virq, unsigned int count); * of the of_irq_map_*() functions. */ extern unsigned int irq_create_of_mapping(struct device_node *controller, - u32 *intspec, unsigned int intsize); + const u32 *intspec, unsigned int intsize); /** * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h index bb2de6aa5ce..81f3b0b5601 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -46,6 +46,24 @@ struct kvm_regs { }; struct kvm_sregs { + __u32 pvr; + union { + struct { + __u64 sdr1; + struct { + struct { + __u64 slbe; + __u64 slbv; + } slb[64]; + } ppc64; + struct { + __u32 sr[16]; + __u64 ibat[8]; + __u64 dbat[8]; + } ppc32; + } s; + __u8 pad[1020]; + } u; }; struct kvm_fpu { diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index 56bfae59837..af2abe74f54 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h @@ -49,6 +49,46 @@ #define BOOKE_INTERRUPT_SPE_FP_ROUND 34 #define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35 +/* book3s */ + +#define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100 +#define BOOK3S_INTERRUPT_MACHINE_CHECK 0x200 +#define BOOK3S_INTERRUPT_DATA_STORAGE 0x300 +#define BOOK3S_INTERRUPT_DATA_SEGMENT 0x380 +#define BOOK3S_INTERRUPT_INST_STORAGE 0x400 +#define BOOK3S_INTERRUPT_INST_SEGMENT 0x480 +#define BOOK3S_INTERRUPT_EXTERNAL 0x500 +#define BOOK3S_INTERRUPT_ALIGNMENT 0x600 +#define BOOK3S_INTERRUPT_PROGRAM 0x700 +#define BOOK3S_INTERRUPT_FP_UNAVAIL 0x800 +#define BOOK3S_INTERRUPT_DECREMENTER 0x900 +#define BOOK3S_INTERRUPT_SYSCALL 0xc00 +#define BOOK3S_INTERRUPT_TRACE 0xd00 +#define BOOK3S_INTERRUPT_PERFMON 0xf00 +#define BOOK3S_INTERRUPT_ALTIVEC 0xf20 +#define BOOK3S_INTERRUPT_VSX 0xf40 + +#define BOOK3S_IRQPRIO_SYSTEM_RESET 0 +#define BOOK3S_IRQPRIO_DATA_SEGMENT 1 +#define BOOK3S_IRQPRIO_INST_SEGMENT 2 +#define BOOK3S_IRQPRIO_DATA_STORAGE 3 +#define BOOK3S_IRQPRIO_INST_STORAGE 4 +#define BOOK3S_IRQPRIO_ALIGNMENT 5 +#define BOOK3S_IRQPRIO_PROGRAM 6 +#define BOOK3S_IRQPRIO_FP_UNAVAIL 7 +#define BOOK3S_IRQPRIO_ALTIVEC 8 +#define BOOK3S_IRQPRIO_VSX 9 +#define BOOK3S_IRQPRIO_SYSCALL 10 +#define BOOK3S_IRQPRIO_MACHINE_CHECK 11 +#define BOOK3S_IRQPRIO_DEBUG 12 +#define BOOK3S_IRQPRIO_EXTERNAL 13 +#define BOOK3S_IRQPRIO_DECREMENTER 14 +#define BOOK3S_IRQPRIO_PERFORMANCE_MONITOR 15 +#define BOOK3S_IRQPRIO_MAX 16 + +#define BOOK3S_HFLAG_DCBZ32 0x1 +#define BOOK3S_HFLAG_SLB 0x2 + #define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */ #define RESUME_FLAG_HOST (1<<1) /* Resume host? */ diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h new file mode 100644 index 00000000000..74b7369770d --- /dev/null +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -0,0 +1,139 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright SUSE Linux Products GmbH 2009 + * + * Authors: Alexander Graf <agraf@suse.de> + */ + +#ifndef __ASM_KVM_BOOK3S_H__ +#define __ASM_KVM_BOOK3S_H__ + +#include <linux/types.h> +#include <linux/kvm_host.h> +#include <asm/kvm_ppc.h> + +struct kvmppc_slb { + u64 esid; + u64 vsid; + u64 orige; + u64 origv; + bool valid; + bool Ks; + bool Kp; + bool nx; + bool large; + bool class; +}; + +struct kvmppc_sr { + u32 raw; + u32 vsid; + bool Ks; + bool Kp; + bool nx; +}; + +struct kvmppc_bat { + u64 raw; + u32 bepi; + u32 bepi_mask; + bool vs; + bool vp; + u32 brpn; + u8 wimg; + u8 pp; +}; + +struct kvmppc_sid_map { + u64 guest_vsid; + u64 guest_esid; + u64 host_vsid; + bool valid; +}; + +#define SID_MAP_BITS 9 +#define SID_MAP_NUM (1 << SID_MAP_BITS) +#define SID_MAP_MASK (SID_MAP_NUM - 1) + +struct kvmppc_vcpu_book3s { + struct kvm_vcpu vcpu; + struct kvmppc_sid_map sid_map[SID_MAP_NUM]; + struct kvmppc_slb slb[64]; + struct { + u64 esid; + u64 vsid; + } slb_shadow[64]; + u8 slb_shadow_max; + struct kvmppc_sr sr[16]; + struct kvmppc_bat ibat[8]; + struct kvmppc_bat dbat[8]; + u64 hid[6]; + int slb_nr; + u64 sdr1; + u64 dsisr; + u64 hior; + u64 msr_mask; + u64 vsid_first; + u64 vsid_next; + u64 vsid_max; + int context_id; +}; + +#define CONTEXT_HOST 0 +#define CONTEXT_GUEST 1 +#define CONTEXT_GUEST_END 2 + +#define VSID_REAL 0xfffffffffff00000 +#define VSID_REAL_DR 0xffffffffffe00000 +#define VSID_REAL_IR 0xffffffffffd00000 +#define VSID_BAT 0xffffffffffc00000 +#define VSID_PR 0x8000000000000000 + +extern void kvmppc_mmu_pte_flush(struct kvm_vcpu *vcpu, u64 ea, u64 ea_mask); +extern void kvmppc_mmu_pte_vflush(struct kvm_vcpu *vcpu, u64 vp, u64 vp_mask); +extern void kvmppc_mmu_pte_pflush(struct kvm_vcpu *vcpu, u64 pa_start, u64 pa_end); +extern void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 new_msr); +extern void kvmppc_mmu_book3s_64_init(struct kvm_vcpu *vcpu); +extern void kvmppc_mmu_book3s_32_init(struct kvm_vcpu *vcpu); +extern int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte); +extern int kvmppc_mmu_map_segment(struct kvm_vcpu *vcpu, ulong eaddr); +extern void kvmppc_mmu_flush_segments(struct kvm_vcpu *vcpu); +extern struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, bool data); +extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr, bool data); +extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr); +extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec); +extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, + bool upper, u32 val); + +extern u32 kvmppc_trampoline_lowmem; +extern u32 kvmppc_trampoline_enter; + +static inline struct kvmppc_vcpu_book3s *to_book3s(struct kvm_vcpu *vcpu) +{ + return container_of(vcpu, struct kvmppc_vcpu_book3s, vcpu); +} + +static inline ulong dsisr(void) +{ + ulong r; + asm ( "mfdsisr %0 " : "=r" (r) ); + return r; +} + +extern void kvm_return_point(void); + +#define INS_DCBZ 0x7c0007ec + +#endif /* __ASM_KVM_BOOK3S_H__ */ diff --git a/arch/powerpc/include/asm/kvm_book3s_64_asm.h b/arch/powerpc/include/asm/kvm_book3s_64_asm.h new file mode 100644 index 00000000000..2e06ee8184e --- /dev/null +++ b/arch/powerpc/include/asm/kvm_book3s_64_asm.h @@ -0,0 +1,58 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright SUSE Linux Products GmbH 2009 + * + * Authors: Alexander Graf <agraf@suse.de> + */ + +#ifndef __ASM_KVM_BOOK3S_ASM_H__ +#define __ASM_KVM_BOOK3S_ASM_H__ + +#ifdef CONFIG_KVM_BOOK3S_64_HANDLER + +#include <asm/kvm_asm.h> + +.macro DO_KVM intno + .if (\intno == BOOK3S_INTERRUPT_SYSTEM_RESET) || \ + (\intno == BOOK3S_INTERRUPT_MACHINE_CHECK) || \ + (\intno == BOOK3S_INTERRUPT_DATA_STORAGE) || \ + (\intno == BOOK3S_INTERRUPT_INST_STORAGE) || \ + (\intno == BOOK3S_INTERRUPT_DATA_SEGMENT) || \ + (\intno == BOOK3S_INTERRUPT_INST_SEGMENT) || \ + (\intno == BOOK3S_INTERRUPT_EXTERNAL) || \ + (\intno == BOOK3S_INTERRUPT_ALIGNMENT) || \ + (\intno == BOOK3S_INTERRUPT_PROGRAM) || \ + (\intno == BOOK3S_INTERRUPT_FP_UNAVAIL) || \ + (\intno == BOOK3S_INTERRUPT_DECREMENTER) || \ + (\intno == BOOK3S_INTERRUPT_SYSCALL) || \ + (\intno == BOOK3S_INTERRUPT_TRACE) || \ + (\intno == BOOK3S_INTERRUPT_PERFMON) || \ + (\intno == BOOK3S_INTERRUPT_ALTIVEC) || \ + (\intno == BOOK3S_INTERRUPT_VSX) + + b kvmppc_trampoline_\intno +kvmppc_resume_\intno: + + .endif +.endm + +#else + +.macro DO_KVM intno +.endm + +#endif /* CONFIG_KVM_BOOK3S_64_HANDLER */ + +#endif /* __ASM_KVM_BOOK3S_ASM_H__ */ diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index c9c930ed11d..1201f62d0d7 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -21,7 +21,8 @@ #define __POWERPC_KVM_HOST_H__ #include <linux/mutex.h> -#include <linux/timer.h> +#include <linux/hrtimer.h> +#include <linux/interrupt.h> #include <linux/types.h> #include <linux/kvm_types.h> #include <asm/kvm_asm.h> @@ -37,6 +38,8 @@ #define KVM_NR_PAGE_SIZES 1 #define KVM_PAGES_PER_HPAGE(x) (1UL<<31) +#define HPTEG_CACHE_NUM 1024 + struct kvm; struct kvm_run; struct kvm_vcpu; @@ -63,6 +66,17 @@ struct kvm_vcpu_stat { u32 dec_exits; u32 ext_intr_exits; u32 halt_wakeup; +#ifdef CONFIG_PPC64 + u32 pf_storage; + u32 pf_instruc; + u32 sp_storage; + u32 sp_instruc; + u32 queue_intr; + u32 ld; + u32 ld_slow; + u32 st; + u32 st_slow; +#endif }; enum kvm_exit_types { @@ -109,9 +123,53 @@ struct kvmppc_exit_timing { struct kvm_arch { }; +struct kvmppc_pte { + u64 eaddr; + u64 vpage; + u64 raddr; + bool may_read; + bool may_write; + bool may_execute; +}; + +struct kvmppc_mmu { + /* book3s_64 only */ + void (*slbmte)(struct kvm_vcpu *vcpu, u64 rb, u64 rs); + u64 (*slbmfee)(struct kvm_vcpu *vcpu, u64 slb_nr); + u64 (*slbmfev)(struct kvm_vcpu *vcpu, u64 slb_nr); + void (*slbie)(struct kvm_vcpu *vcpu, u64 slb_nr); + void (*slbia)(struct kvm_vcpu *vcpu); + /* book3s */ + void (*mtsrin)(struct kvm_vcpu *vcpu, u32 srnum, ulong value); + u32 (*mfsrin)(struct kvm_vcpu *vcpu, u32 srnum); + int (*xlate)(struct kvm_vcpu *vcpu, gva_t eaddr, struct kvmppc_pte *pte, bool data); + void (*reset_msr)(struct kvm_vcpu *vcpu); + void |