Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (151 commits) powerpc: Fix usage of 64-bit instruction in 32-bit altivec code MAINTAINERS: Add PowerPC patterns powerpc/pseries: Track previous CPPR values to correctly EOI interrupts powerpc/pseries: Correct pseries/dlpar.c build break without CONFIG_SMP powerpc: Make "intspec" pointers in irq_host->xlate() const powerpc/8xx: DTLB Miss cleanup powerpc/8xx: Remove DIRTY pte handling in DTLB Error. powerpc/8xx: Start using dcbX instructions in various copy routines powerpc/8xx: Restore _PAGE_WRITETHRU powerpc/8xx: Add missing Guarded setting in DTLB Error. powerpc/8xx: Fixup DAR from buggy dcbX instructions. powerpc/8xx: Tag DAR with 0x00f0 to catch buggy instructions. powerpc/8xx: Update TLB asm so it behaves as linux mm expects. powerpc/8xx: Invalidate non present TLBs powerpc/pseries: Serialize cpu hotplug operations during deactivate Vs deallocate pseries/pseries: Add code to online/offline CPUs of a DLPAR node powerpc: stop_this_cpu: remove the cpu from the online map. powerpc/pseries: Add kernel based CPU DLPAR handling sysfs/cpu: Add probe/release files powerpc/pseries: Kernel DLPAR Infrastructure ...
This commit is contained in:
@ -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);
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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 {
|
||||
|
@ -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 */ \
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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? */
|
||||
|
||||
|
139
arch/powerpc/include/asm/kvm_book3s.h
Normal file
139
arch/powerpc/include/asm/kvm_book3s.h
Normal file
@ -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__ */
|
58
arch/powerpc/include/asm/kvm_book3s_64_asm.h
Normal file
58
arch/powerpc/include/asm/kvm_book3s_64_asm.h
Normal file
@ -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__ */
|
@ -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 (*tlbie)(struct kvm_vcpu *vcpu, ulong addr, bool large);
|
||||
int (*esid_to_vsid)(struct kvm_vcpu *vcpu, u64 esid, u64 *vsid);
|
||||
u64 (*ea_to_vp)(struct kvm_vcpu *vcpu, gva_t eaddr, bool data);
|
||||
bool (*is_dcbz32)(struct kvm_vcpu *vcpu);
|
||||
};
|
||||
|
||||
struct hpte_cache {
|
||||
u64 host_va;
|
||||
u64 pfn;
|
||||
ulong slot;
|
||||
struct kvmppc_pte pte;
|
||||
};
|
||||
|
||||
struct kvm_vcpu_arch {
|
||||
u32 host_stack;
|
||||
ulong host_stack;
|
||||
u32 host_pid;
|
||||
#ifdef CONFIG_PPC64
|
||||
ulong host_msr;
|
||||
ulong host_r2;
|
||||
void *host_retip;
|
||||
ulong trampoline_lowmem;
|
||||
ulong trampoline_enter;
|
||||
ulong highmem_handler;
|
||||
ulong host_paca_phys;
|
||||
struct kvmppc_mmu mmu;
|
||||
#endif
|
||||
|
||||
u64 fpr[32];
|
||||
ulong gpr[32];
|
||||
@ -123,6 +181,10 @@ struct kvm_vcpu_arch {
|
||||
ulong xer;
|
||||
|
||||
ulong msr;
|
||||
#ifdef CONFIG_PPC64
|
||||
ulong shadow_msr;
|
||||
ulong hflags;
|
||||
#endif
|
||||
u32 mmucr;
|
||||
ulong sprg0;
|
||||
ulong sprg1;
|
||||
@ -149,6 +211,7 @@ struct kvm_vcpu_arch {
|
||||
u32 ivor[64];
|
||||
ulong ivpr;
|
||||
u32 pir;
|
||||
u32 pvr;
|
||||
|
||||
u32 shadow_pid;
|
||||
u32 pid;
|
||||
@ -174,6 +237,9 @@ struct kvm_vcpu_arch {
|
||||
#endif
|
||||
|
||||
u32 last_inst;
|
||||
#ifdef CONFIG_PPC64
|
||||
ulong fault_dsisr;
|
||||
#endif
|
||||
ulong fault_dear;
|
||||
ulong fault_esr;
|
||||
gpa_t paddr_accessed;
|
||||
@ -185,8 +251,15 @@ struct kvm_vcpu_arch {
|
||||
|
||||
u32 cpr0_cfgaddr; /* holds the last set cpr0_cfgaddr */
|
||||
|
||||
struct timer_list dec_timer;
|
||||
struct hrtimer dec_timer;
|
||||
struct tasklet_struct tasklet;
|
||||
u64 dec_jiffies;
|
||||
unsigned long pending_exceptions;
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
struct hpte_cache hpte_cache[HPTEG_CACHE_NUM];
|
||||
int hpte_cache_offset;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* __POWERPC_KVM_HOST_H__ */
|
||||
|
@ -39,6 +39,7 @@ enum emulation_result {
|
||||
extern int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu);
|
||||
extern char kvmppc_handlers_start[];
|
||||
extern unsigned long kvmppc_handler_len;
|
||||
extern void kvmppc_handler_highmem(void);
|
||||
|
||||
extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu);
|
||||
extern int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||
|
@ -100,7 +100,14 @@ struct lppaca {
|
||||
// Used to pass parms from the OS to PLIC for SetAsrAndRfid
|
||||
u64 saved_gpr3; // Saved GPR3 x20-x27
|
||||
u64 saved_gpr4; // Saved GPR4 x28-x2F
|
||||
u64 saved_gpr5; // Saved GPR5 x30-x37
|
||||
union {
|
||||
u64 saved_gpr5; /* Saved GPR5 x30-x37 */
|
||||
struct {
|
||||
u8 cede_latency_hint; /* x30 */
|
||||
u8 reserved[7]; /* x31-x36 */
|
||||
} fields;
|
||||
} gpr5_dword;
|
||||
|
||||
|
||||
u8 dtl_enable_mask; // Dispatch Trace Log mask x38-x38
|
||||
u8 donate_dedicated_cpu; // Donate dedicated CPU cycles x39-x39
|
||||
|
@ -266,6 +266,11 @@ struct machdep_calls {
|
||||
void (*suspend_disable_irqs)(void);
|
||||
void (*suspend_enable_irqs)(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
|
||||
ssize_t (*cpu_probe)(const char *, size_t);
|
||||
ssize_t (*cpu_release)(const char *, size_t);
|
||||
#endif
|
||||
};
|
||||
|
||||
extern void e500_idle(void);
|
||||
|
@ -39,6 +39,7 @@ struct macio_dev
|
||||
struct macio_bus *bus; /* macio bus this device is on */
|
||||
struct macio_dev *media_bay; /* Device is part of a media bay */
|
||||
struct of_device ofdev;
|
||||
struct device_dma_parameters dma_parms; /* ide needs that */
|
||||
int n_resources;
|
||||
struct resource resource[MACIO_DEV_COUNT_RESOURCES];
|
||||
int n_interrupts;
|
||||
@ -78,6 +79,8 @@ static inline unsigned long macio_resource_len(struct macio_dev *dev, int resour
|
||||
return res->end - res->start + 1;
|
||||
}
|
||||
|
||||
extern int macio_enable_devres(struct macio_dev *dev);
|
||||
|
||||
extern int macio_request_resource(struct macio_dev *dev, int resource_no, const char *name);
|
||||
extern void macio_release_resource(struct macio_dev *dev, int resource_no);
|
||||
extern int macio_request_resources(struct macio_dev *dev, const char *name);
|
||||
@ -131,6 +134,9 @@ struct macio_driver
|
||||
int (*resume)(struct macio_dev* dev);
|
||||
int (*shutdown)(struct macio_dev* dev);
|
||||
|
||||
#ifdef CONFIG_PMAC_MEDIABAY
|
||||
void (*mediabay_event)(struct macio_dev* dev, int mb_state);
|
||||
#endif
|
||||
struct device_driver driver;
|
||||
};
|
||||
#define to_macio_driver(drv) container_of(drv,struct macio_driver, driver)
|
||||
|
@ -17,26 +17,31 @@
|
||||
#define MB_POWER 6 /* media bay contains a Power device (???) */
|
||||
#define MB_NO 7 /* media bay contains nothing */
|
||||
|
||||
/* Number of bays in the machine or 0 */
|
||||
extern int media_bay_count;
|
||||
struct macio_dev;
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_IDE_PMAC
|
||||
#include <linux/ide.h>
|
||||
#ifdef CONFIG_PMAC_MEDIABAY
|
||||
|
||||
int check_media_bay_by_base(unsigned long base, int what);
|
||||
/* called by IDE PMAC host driver to register IDE controller for media bay */
|
||||
int media_bay_set_ide_infos(struct device_node *which_bay, unsigned long base,
|
||||
int irq, ide_hwif_t *hwif);
|
||||
/* Check the content type of the bay, returns MB_NO if the bay is still
|
||||
* transitionning
|
||||
*/
|
||||
extern int check_media_bay(struct macio_dev *bay);
|
||||
|
||||
int check_media_bay(struct device_node *which_bay, int what);
|
||||
/* The ATA driver uses the calls below to temporarily hold on the
|
||||
* media bay callbacks while initializing the interface
|
||||
*/
|
||||
extern void lock_media_bay(struct macio_dev *bay);
|
||||
extern void unlock_media_bay(struct macio_dev *bay);
|
||||
|
||||
#else
|
||||
|
||||
static inline int check_media_bay(struct device_node *which_bay, int what)
|
||||
static inline int check_media_bay(struct macio_dev *bay)
|
||||
{
|
||||
return -ENODEV;
|
||||
return MB_NO;
|
||||
}
|
||||
|
||||
static inline void lock_media_bay(struct macio_dev *bay) { }
|
||||
static inline void unlock_media_bay(struct macio_dev *bay) { }
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
@ -173,14 +173,6 @@ extern unsigned long tce_alloc_start, tce_alloc_end;
|
||||
*/
|
||||
extern int mmu_ci_restrictions;
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
/*
|
||||
* The page size indexes of the huge pages for use by hugetlbfs
|
||||
*/
|
||||
extern unsigned int mmu_huge_psizes[MMU_PAGE_COUNT];
|
||||
|
||||
#endif /* CONFIG_HUGETLB_PAGE */
|
||||
|
||||
/*
|
||||
* This function sets the AVPN and L fields of the HPTE appropriately
|
||||
* for the page size
|
||||
@ -253,10 +245,11 @@ extern int __hash_page_64K(unsigned long ea, unsigned long access,
|
||||
unsigned long vsid, pte_t *ptep, unsigned long trap,
|
||||
unsigned int local, int ssize);
|
||||
struct mm_struct;
|
||||
unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap);
|
||||
extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap);
|
||||
extern int hash_huge_page(struct mm_struct *mm, unsigned long access,
|
||||
unsigned long ea, unsigned long vsid, int local,
|
||||
unsigned long trap);
|
||||
int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
|
||||
pte_t *ptep, unsigned long trap, int local, int ssize,
|
||||
unsigned int shift, unsigned int mmu_psize);
|
||||
|
||||
extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
|
||||
unsigned long pstart, unsigned long prot,
|
||||
@ -380,6 +373,38 @@ extern void slb_set_size(u16 size);
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#ifdef CONFIG_PPC_SUBPAGE_PROT
|
||||
/*
|
||||
* For the sub-page protection option, we extend the PGD with one of
|
||||
* these. Basically we have a 3-level tree, with the top level being
|
||||
* the protptrs array. To optimize speed and memory consumption when
|
||||
* only addresses < 4GB are being protected, pointers to the first
|
||||
* four pages of sub-page protection words are stored in the low_prot
|
||||
* array.
|
||||
* Each page of sub-page protection words protects 1GB (4 bytes
|
||||
* protects 64k). For the 3-level tree, each page of pointers then
|
||||
* protects 8TB.
|
||||
*/
|
||||
struct subpage_prot_table {
|
||||
unsigned long maxaddr; /* only addresses < this are protected */
|
||||
unsigned int **protptrs[2];
|
||||
unsigned int *low_prot[4];
|
||||
};
|
||||
|
||||
#define SBP_L1_BITS (PAGE_SHIFT - 2)
|
||||
#define SBP_L2_BITS (PAGE_SHIFT - 3)
|
||||
#define SBP_L1_COUNT (1 << SBP_L1_BITS)
|
||||
#define SBP_L2_COUNT (1 << SBP_L2_BITS)
|
||||
#define SBP_L2_SHIFT (PAGE_SHIFT + SBP_L1_BITS)
|
||||
#define SBP_L3_SHIFT (SBP_L2_SHIFT + SBP_L2_BITS)
|
||||
|
||||
extern void subpage_prot_free(struct mm_struct *mm);
|
||||
extern void subpage_prot_init_new_context(struct mm_struct *mm);
|
||||
#else
|
||||
static inline void subpage_prot_free(struct mm_struct *mm) {}
|
||||
static inline void subpage_prot_init_new_context(struct mm_struct *mm) { }
|
||||
#endif /* CONFIG_PPC_SUBPAGE_PROT */
|
||||
|
||||
typedef unsigned long mm_context_id_t;
|
||||
|
||||
typedef struct {
|
||||
@ -393,6 +418,9 @@ typedef struct {
|
||||
u16 sllp; /* SLB page size encoding */
|
||||
#endif
|
||||
unsigned long vdso_base;
|
||||
#ifdef CONFIG_PPC_SUBPAGE_PROT
|
||||
struct subpage_prot_table spt;
|
||||
#endif /* CONFIG_PPC_SUBPAGE_PROT */
|
||||
} mm_context_t;
|
||||
|
||||
|
||||
|
@ -23,6 +23,8 @@ extern void switch_slb(struct task_struct *tsk, struct mm_struct *mm);
|
||||
extern void set_context(unsigned long id, pgd_t *pgd);
|
||||
|
||||
#ifdef CONFIG_PPC_BOOK3S_64
|
||||
extern int __init_new_context(void);
|
||||
extern void __destroy_context(int context_id);
|
||||
static inline void mmu_context_init(void) { }
|
||||
#else
|
||||
extern void mmu_context_init(void);
|
||||
|
@ -276,6 +276,53 @@ extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv);
|
||||
extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node);
|
||||
extern void mpc52xx_restart(char *cmd);
|
||||
|
||||
/* mpc52xx_gpt.c */
|
||||
struct mpc52xx_gpt_priv;
|
||||
extern struct mpc52xx_gpt_priv *mpc52xx_gpt_from_irq(int irq);
|
||||
extern int mpc52xx_gpt_start_timer(struct mpc52xx_gpt_priv *gpt, u64 period,
|
||||
int continuous);
|
||||
extern u64 mpc52xx_gpt_timer_period(struct mpc52xx_gpt_priv *gpt);
|
||||
extern int mpc52xx_gpt_stop_timer(struct mpc52xx_gpt_priv *gpt);
|
||||
|
||||
/* mpc52xx_lpbfifo.c */
|
||||
#define MPC52XX_LPBFIFO_FLAG_READ (0)
|
||||
#define MPC52XX_LPBFIFO_FLAG_WRITE (1<<0)
|
||||
#define MPC52XX_LPBFIFO_FLAG_NO_INCREMENT (1<<1)
|
||||
#define MPC52XX_LPBFIFO_FLAG_NO_DMA (1<<2)
|
||||
#define MPC52XX_LPBFIFO_FLAG_POLL_DMA (1<<3)
|
||||
|
||||
struct mpc52xx_lpbfifo_request {
|
||||
struct list_head list;
|
||||
|
||||
/* localplus bus address */
|
||||
unsigned int cs;
|
||||
size_t offset;
|
||||
|
||||
/* Memory address */
|
||||
void *data;
|
||||
phys_addr_t data_phys;
|
||||
|
||||
/* Details of transfer */
|
||||
size_t size;
|
||||
size_t pos; /* current position of transfer */
|
||||
int flags;
|
||||
|
||||
/* What to do when finished */
|
||||
void (*callback)(struct mpc52xx_lpbfifo_request *);
|
||||
|
||||
void *priv; /* Driver private data */
|
||||
|
||||
/* statistics */
|
||||
int irq_count;
|
||||
int irq_ticks;
|
||||
u8 last_byte;
|
||||
int buffer_not_done_cnt;
|
||||
};
|
||||
|
||||
extern int mpc52xx_lpbfifo_submit(struct mpc52xx_lpbfifo_request *req);
|
||||
extern void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req);
|
||||
extern void mpc52xx_lpbfifo_poll(void);
|
||||
|
||||
/* mpc52xx_pic.c */
|
||||
extern void mpc52xx_init_irq(void);
|
||||
extern unsigned int mpc52xx_get_irq(void);
|
||||
|
@ -73,7 +73,6 @@ extern int nvram_write_error_log(char * buff, int length,
|
||||
extern int nvram_read_error_log(char * buff, int length,
|
||||
unsigned int * err_type, unsigned int *err_seq);
|
||||
extern int nvram_clear_error_log(void);
|
||||
extern struct nvram_partition *nvram_find_partition(int sig, const char *name);
|
||||
|
||||
extern int pSeries_nvram_init(void);
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#ifdef CONFIG_PPC_PSERIES
|
||||
extern int pSeries_reconfig_notifier_register(struct notifier_block *);
|
||||
extern void pSeries_reconfig_notifier_unregister(struct notifier_block *);
|
||||
extern struct blocking_notifier_head pSeries_reconfig_chain;
|
||||
#else /* !CONFIG_PPC_PSERIES */
|
||||
static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb)
|
||||
{
|
||||
|
@ -129,6 +129,15 @@ struct paca_struct {
|
||||
u64 system_time; /* accumulated system TB ticks */
|
||||
u64 startpurr; /* PURR/TB value snapshot */
|
||||
u64 startspurr; /* SPURR value snapshot */
|
||||
|
||||
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
|
||||
struct {
|
||||
u64 esid;
|
||||
u64 vsid;
|
||||
} kvm_slb[64]; /* guest SLB */
|
||||
u8 kvm_slb_max; /* highest used guest slb entry */
|
||||
u8 kvm_in_guest; /* are we inside the guest? */
|
||||
#endif
|
||||
};
|
||||
|
||||
extern struct paca_struct paca[];
|
||||
|
@ -229,6 +229,20 @@ typedef unsigned long pgprot_t;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct { signed long pd; } hugepd_t;
|
||||
#define HUGEPD_SHIFT_MASK 0x3f
|
||||
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
static inline int hugepd_ok(hugepd_t hpd)
|
||||
{
|
||||
return (hpd.pd > 0);
|
||||
}
|
||||
|
||||
#define is_hugepd(pdep) (hugepd_ok(*((hugepd_t *)(pdep))))
|
||||
#else /* CONFIG_HUGETLB_PAGE */
|
||||
#define is_hugepd(pdep) 0
|
||||
#endif /* CONFIG_HUGETLB_PAGE */
|
||||
|
||||
struct page;
|
||||
extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
|
||||
extern void copy_user_page(void *to, void *from, unsigned long vaddr,
|
||||
|
@ -90,7 +90,7 @@ extern unsigned int HPAGE_SHIFT;
|
||||
#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
|
||||
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
|
||||
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
|
||||
#define HUGE_MAX_HSTATE 3
|
||||
#define HUGE_MAX_HSTATE (MMU_PAGE_COUNT-1)
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
|
@ -3,7 +3,8 @@
|
||||
|
||||
#include <linux/threads.h>
|
||||
|
||||
#define PTE_NONCACHE_NUM 0 /* dummy for now to share code w/ppc64 */
|
||||
/* For 32-bit, all levels of page tables are just drawn from get_free_page() */
|
||||
#define MAX_PGTABLE_INDEX_SIZE 0
|
||||
|
||||
extern void __bad_pte(pmd_t *pmd);
|
||||
|
||||
@ -36,11 +37,10 @@ extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
|
||||
extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
|
||||
extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr);
|
||||
|
||||
static inline void pgtable_free(pgtable_free_t pgf)
|
||||
static inline void pgtable_free(void *table, unsigned index_size)
|
||||
{
|
||||
void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
|
||||
|
||||
free_page((unsigned long)p);
|
||||
BUG_ON(index_size); /* 32-bit doesn't use this */
|
||||
free_page((unsigned long)table);
|
||||
}
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
@ -11,27 +11,34 @@
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/percpu.h>
|
||||
|
||||
#ifndef CONFIG_PPC_SUBPAGE_PROT
|
||||
static inline void subpage_prot_free(pgd_t *pgd) {}
|
||||
#endif
|
||||
/*
|
||||
* Functions that deal with pagetables that could be at any level of
|
||||
* the table need to be passed an "index_size" so they know how to
|
||||
* handle allocation. For PTE pages (which are linked to a struct
|
||||
* page for now, and drawn from the main get_free_pages() pool), the
|
||||
* allocation size will be (2^index_size * sizeof(pointer)) and
|
||||
* allocations are drawn from the kmem_cache in PGT_CACHE(index_size).
|
||||
*
|
||||
* The maximum index size needs to be big enough to allow any
|
||||
* pagetable sizes we need, but small enough to fit in the low bits of
|
||||
* any page table pointer. In other words all pagetables, even tiny
|
||||
* ones, must be aligned to allow at least enough low 0 bits to
|
||||
* contain this value. This value is also used as a mask, so it must
|
||||
* be one less than a power of two.
|
||||
*/
|
||||
#define MAX_PGTABLE_INDEX_SIZE 0xf
|
||||
|
||||
extern struct kmem_cache *pgtable_cache[];
|
||||
|
||||
#define PGD_CACHE_NUM 0
|
||||
#define PUD_CACHE_NUM 1
|
||||
#define PMD_CACHE_NUM 1
|
||||
#define HUGEPTE_CACHE_NUM 2
|
||||
#define PTE_NONCACHE_NUM 7 /* from GFP rather than kmem_cache */
|
||||
#define PGT_CACHE(shift) (pgtable_cache[(shift)-1])
|
||||
|
||||
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
|
||||
{
|
||||
return kmem_cache_alloc(pgtable_cache[PGD_CACHE_NUM], GFP_KERNEL);
|
||||
return kmem_cache_alloc(PGT_CACHE(PGD_INDEX_SIZE), GFP_KERNEL);
|
||||
}
|
||||
|
||||
static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
|
||||
{
|
||||
subpage_prot_free(pgd);
|
||||
kmem_cache_free(pgtable_cache[PGD_CACHE_NUM], pgd);
|
||||
kmem_cache_free(PGT_CACHE(PGD_INDEX_SIZE), pgd);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_PPC_64K_PAGES
|
||||
@ -40,13 +47,13 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
|
||||
|
||||
static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
|
||||
{
|
||||
return kmem_cache_alloc(pgtable_cache[PUD_CACHE_NUM],
|
||||
return kmem_cache_alloc(PGT_CACHE(PUD_INDEX_SIZE),
|
||||
GFP_KERNEL|__GFP_REPEAT);
|
||||
}
|
||||
|
||||
static inline void pud_free(struct mm_struct *mm, pud_t *pud)
|
||||
{
|
||||
kmem_cache_free(pgtable_cache[PUD_CACHE_NUM], pud);
|
||||
kmem_cache_free(PGT_CACHE(PUD_INDEX_SIZE), pud);
|
||||
}
|
||||
|
||||
static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
|
||||
@ -78,13 +85,13 @@ static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
|
||||
|
||||
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
|
||||
{
|
||||
return kmem_cache_alloc(pgtable_cache[PMD_CACHE_NUM],
|
||||
return kmem_cache_alloc(PGT_CACHE(PMD_INDEX_SIZE),
|
||||
GFP_KERNEL|__GFP_REPEAT);
|
||||
}
|
||||
|
||||
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
|
||||
{
|
||||
kmem_cache_free(pgtable_cache[PMD_CACHE_NUM], pmd);
|
||||
kmem_cache_free(PGT_CACHE(PMD_INDEX_SIZE), pmd);
|
||||
}
|
||||
|
||||
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
|
||||
@ -107,24 +114,22 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
|
||||
return page;
|
||||
}
|
||||
|
||||
static inline void pgtable_free(pgtable_free_t pgf)
|
||||
static inline void pgtable_free(void *table, unsigned index_size)
|
||||
{
|
||||
void *p = (void *)(pgf.val & ~PGF_CACHENUM_MASK);
|
||||
int cachenum = pgf.val & PGF_CACHENUM_MASK;
|
||||
|
||||
if (cachenum == PTE_NONCACHE_NUM)
|
||||
free_page((unsigned long)p);
|
||||
else
|
||||
kmem_cache_free(pgtable_cache[cachenum], p);
|
||||
if (!index_size)
|
||||
free_page((unsigned long)table);
|
||||
else {
|
||||
BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE);
|
||||
kmem_cache_free(PGT_CACHE(index_size), table);
|
||||
}
|
||||
}
|
||||
|
||||
#define __pmd_free_tlb(tlb, pmd,addr) \
|
||||
pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \
|
||||
PMD_CACHE_NUM, PMD_TABLE_SIZE-1))
|
||||
#define __pmd_free_tlb(tlb, pmd, addr) \
|
||||
pgtable_free_tlb(tlb, pmd, PMD_INDEX_SIZE)
|
||||
#ifndef CONFIG_PPC_64K_PAGES
|
||||
#define __pud_free_tlb(tlb, pud, addr) \
|
||||
pgtable_free_tlb(tlb, pgtable_free_cache(pud, \
|
||||
PUD_CACHE_NUM, PUD_TABLE_SIZE-1))
|
||||
pgtable_free_tlb(tlb, pud, PUD_INDEX_SIZE)
|
||||
|
||||
#endif /* CONFIG_PPC_64K_PAGES */
|
||||
|
||||
#define check_pgt_cache() do { } while (0)
|
||||
|
@ -24,25 +24,6 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
|
||||
__free_page(ptepage);
|
||||
}
|
||||
|
||||
typedef struct pgtable_free {
|
||||
unsigned long val;
|
||||
} pgtable_free_t;
|
||||
|
||||
/* This needs to be big enough to allow for MMU_PAGE_COUNT + 2 to be stored
|
||||
* and small enough to fit in the low bits of any naturally aligned page
|
||||
* table cache entry. Arbitrarily set to 0x1f, that should give us some
|
||||
* room to grow
|
||||
*/
|
||||
#define PGF_CACHENUM_MASK 0x1f
|
||||
|
||||
static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
|
||||
unsigned long mask)
|
||||
{
|
||||
BUG_ON(cachenum > PGF_CACHENUM_MASK);
|
||||
|
||||
return (pgtable_free_t){.val = ((unsigned long) p & ~mask) | cachenum};
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
#include <asm/pgalloc-64.h>
|
||||
#else
|
||||
@ -50,12 +31,12 @@ static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
|
||||
extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, unsigned shift);
|
||||
extern void pte_free_finish(void);
|
||||
#else /* CONFIG_SMP */
|
||||
static inline void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
|
||||
static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, unsigned shift)
|
||||
{
|
||||
pgtable_free(pgf);
|
||||
pgtable_free(table, shift);
|
||||
}
|
||||
static inline void pte_free_finish(void) { }
|
||||
#endif /* !CONFIG_SMP */
|
||||
@ -63,12 +44,9 @@ static inline void pte_free_finish(void) { }
|
||||
static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage,
|
||||
unsigned long address)
|
||||
{
|
||||
pgtable_free_t pgf = pgtable_free_cache(page_address(ptepage),
|
||||
PTE_NONCACHE_NUM,
|
||||
PTE_TABLE_SIZE-1);
|
||||
tlb_flush_pgtable(tlb, address);
|
||||
pgtable_page_dtor(ptepage);
|
||||
pgtable_free_tlb(tlb, pgf);
|
||||
pgtable_free_tlb(tlb, page_address(ptepage), 0);
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
@ -354,6 +354,7 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
|
||||
#define pgoff_to_pte(off) ((pte_t) {((off) << PTE_RPN_SHIFT)|_PAGE_FILE})
|
||||
#define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_RPN_SHIFT)
|
||||
|
||||
void pgtable_cache_add(unsigned shift, void (*ctor)(void *));
|
||||
void pgtable_cache_init(void);
|
||||
|
||||
/*
|
||||
@ -378,7 +379,18 @@ void pgtable_cache_init(void);
|
||||
return pt;
|
||||
}
|
||||
|
||||
pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long address);
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
|
||||
unsigned *shift);
|
||||
#else
|
||||
static inline pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
|
||||
unsigned *shift)
|
||||
{
|
||||
if (shift)
|
||||
*shift = 0;
|
||||
return find_linux_pte(pgdir, ea);
|
||||
}
|
||||
#endif /* !CONFIG_HUGETLB_PAGE */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
|
@ -211,6 +211,9 @@ extern void paging_init(void);
|
||||
*/
|
||||
extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
|
||||
|
||||
extern int gup_hugepd(hugepd_t *hugepd, unsigned pdshift, unsigned long addr,
|
||||
unsigned long end, int write, struct page **pages, int *nr);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
@ -33,21 +33,21 @@
|
||||
#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */
|
||||
#define _PAGE_SHARED 0x0004 /* No ASID (context) compare */
|
||||
#define _PAGE_SPECIAL 0x0008 /* SW entry, forced to 0 by the TLB miss */
|
||||
#define _PAGE_DIRTY 0x0100 /* C: page changed */
|
||||
|
||||
/* These five software bits must be masked out when the entry is loaded
|
||||
* into the TLB.
|
||||
/* These 4 software bits must be masked out when the entry is loaded
|
||||
* into the TLB, 1 SW bit left(0x0080).
|
||||
*/
|
||||
#define _PAGE_GUARDED 0x0010 /* software: guarded access */
|
||||
#define _PAGE_DIRTY 0x0020 /* software: page changed */
|
||||
#define _PAGE_RW 0x0040 /* software: user write access allowed */
|
||||
#define _PAGE_ACCESSED 0x0080 /* software: page referenced */
|
||||
#define _PAGE_ACCESSED 0x0020 /* software: page referenced */
|
||||
#define _PAGE_WRITETHRU 0x0040 /* software: caching is write through */
|
||||
|
||||
/* Setting any bits in the nibble with the follow two controls will
|
||||
* require a TLB exception handler change. It is assumed unused bits
|
||||
* are always zero.
|
||||
*/
|
||||
#define _PAGE_HWWRITE 0x0100 /* h/w write enable: never set in Linux PTE */
|
||||
#define _PAGE_USER 0x0800 /* One of the PP bits, the other is USER&~RW */
|
||||
#define _PAGE_RW 0x0400 /* lsb PP bits, inverted in HW */
|
||||
#define _PAGE_USER 0x0800 /* msb PP bits */
|
||||
|
||||
#define _PMD_PRESENT 0x0001
|
||||
#define _PMD_BAD 0x0ff0
|
||||
|
@ -76,41 +76,4 @@
|
||||
remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \
|
||||
__pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))
|
||||
|
||||
|
||||
#ifdef CONFIG_PPC_SUBPAGE_PROT
|
||||
/*
|
||||
* For the sub-page protection option, we extend the PGD with one of
|
||||
* these. Basically we have a 3-level tree, with the top level being
|
||||
* the protptrs array. To optimize speed and memory consumption when
|
||||
* only addresses < 4GB are being protected, pointers to the first
|
||||
* four pages of sub-page protection words are stored in the low_prot
|
||||
* array.
|
||||
* Each page of sub-page protection words protects 1GB (4 bytes
|
||||
* protects 64k). For the 3-level tree, each page of pointers then
|
||||
* protects 8TB.
|
||||
*/
|
||||
struct subpage_prot_table {
|
||||
unsigned long maxaddr; /* only addresses < this are protected */
|
||||
unsigned int **protptrs[2];
|
||||
unsigned int *low_prot[4];
|
||||
};
|
||||
|
||||
#undef PGD_TABLE_SIZE
|
||||
#define PGD_TABLE_SIZE ((sizeof(pgd_t) << PGD_INDEX_SIZE) + \
|
||||
sizeof(struct subpage_prot_table))
|
||||
|
||||
#define SBP_L1_BITS (PAGE_SHIFT - 2)
|
||||
#define SBP_L2_BITS (PAGE_SHIFT - 3)
|
||||
#define SBP_L1_COUNT (1 << SBP_L1_BITS)
|
||||
#define SBP_L2_COUNT (1 << SBP_L2_BITS)
|
||||
#define SBP_L2_SHIFT (PAGE_SHIFT + SBP_L1_BITS)
|
||||
#define SBP_L3_SHIFT (SBP_L2_SHIFT + SBP_L2_BITS)
|
||||
|
||||
extern void subpage_prot_free(pgd_t *pgd);
|
||||
|
||||
static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd)
|
||||
{
|
||||
return (struct subpage_prot_table *)(pgd + PTRS_PER_PGD);
|
||||
}
|
||||
#endif /* CONFIG_PPC_SUBPAGE_PROT */
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
@ -87,7 +87,7 @@ extern spinlock_t cmxgcr_lock;
|
||||
|
||||
/* Export QE common operations */
|
||||
#ifdef CONFIG_QUICC_ENGINE
|
||||
extern void __init qe_reset(void);
|
||||
extern void qe_reset(void);
|
||||
#else
|
||||
static inline void qe_reset(void) {}
|
||||
#endif
|
||||
@ -145,8 +145,17 @@ static inline void qe_pin_set_gpio(struct qe_pin *qe_pin) {}
|
||||
static inline void qe_pin_set_dedicated(struct qe_pin *pin) {}
|
||||
#endif /* CONFIG_QE_GPIO */
|
||||
|
||||
/* QE internal API */
|
||||
#ifdef CONFIG_QUICC_ENGINE
|
||||
int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input);
|
||||
#else
|
||||
static inline int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol,
|
||||
u32 cmd_input)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_QUICC_ENGINE */
|
||||
|
||||
/* QE internal API */
|
||||
enum qe_clock qe_clock_source(const char *source);
|
||||
unsigned int qe_get_brg_clk(void);
|
||||
int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier);
|
||||
@ -154,7 +163,28 @@ int qe_get_snum(void);
|
||||
void qe_put_snum(u8 snum);
|
||||
unsigned int qe_get_num_of_risc(void);
|
||||
unsigned int qe_get_num_of_snums(void);
|
||||
int qe_alive_during_sleep(void);
|
||||
|
||||
static inline int qe_alive_during_sleep(void)
|
||||
{
|
||||
/*
|
||||
* MPC8568E reference manual says:
|
||||
*
|
||||
* "...power down sequence waits for all I/O interfaces to become idle.
|
||||
* In some applications this may happen eventually without actively
|
||||
* shutting down interfaces, but most likely, software will have to
|
||||
* take steps to shut down the eTSEC, QUICC Engine Block, and PCI
|
||||
* interfaces before issuing the command (either the write to the core
|
||||
* MSR[WE] as described above or writing to POWMGTCSR) to put the
|
||||
* device into sleep state."
|
||||
*
|
||||
* MPC8569E reference manual has a similar paragraph.
|
||||
*/
|
||||
#ifdef CONFIG_PPC_85xx
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* we actually use cpm_muram implementation, define this for convenience */
|
||||
#define qe_muram_init cpm_muram_init
|
||||
@ -210,8 +240,15 @@ struct qe_firmware_info {
|
||||
u64 extended_modes; /* Extended modes */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_QUICC_ENGINE
|
||||
/* Upload a firmware to the QE */
|
||||
int qe_upload_firmware(const struct qe_firmware *firmware);
|
||||
#else
|
||||
static inline int qe_upload_firmware(const struct qe_firmware *firmware)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_QUICC_ENGINE */
|
||||
|
||||
/* Obtain information on the uploaded firmware */
|
||||
struct qe_firmware_info *qe_get_firmware_info(void);
|
||||
|
@ -145,7 +145,7 @@ SYSCALL_SPU(setfsuid)
|
||||
SYSCALL_SPU(setfsgid)
|
||||
SYSCALL_SPU(llseek)
|
||||
COMPAT_SYS_SPU(getdents)
|
||||
SYSX_SPU(sys_select,ppc32_select,ppc_select)
|
||||
SYSX_SPU(sys_select,ppc32_select,sys_select)
|
||||
SYSCALL_SPU(flock)
|
||||
SYSCALL_SPU(msync)
|
||||
COMPAT_SYS_SPU(readv)
|
||||
|
Reference in New Issue
Block a user