diff options
Diffstat (limited to 'arch/arm/include')
29 files changed, 838 insertions, 432 deletions
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index d40229d9a1c..7ade91d8cc6 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h @@ -1,13 +1,115 @@ #ifndef __ASMARM_ARCH_TIMER_H #define __ASMARM_ARCH_TIMER_H +#include <asm/barrier.h> #include <asm/errno.h> #include <linux/clocksource.h> +#include <linux/init.h> +#include <linux/types.h> + +#include <clocksource/arm_arch_timer.h> #ifdef CONFIG_ARM_ARCH_TIMER int arch_timer_of_register(void); int arch_timer_sched_clock_init(void); -struct timecounter *arch_timer_get_timecounter(void); + +/* + * These register accessors are marked inline so the compiler can + * nicely work out which register we want, and chuck away the rest of + * the code. At least it does so with a recent GCC (4.6.3). + */ +static inline void arch_timer_reg_write(const int access, const int reg, u32 val) +{ + if (access == ARCH_TIMER_PHYS_ACCESS) { + switch (reg) { + case ARCH_TIMER_REG_CTRL: + asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val)); + break; + case ARCH_TIMER_REG_TVAL: + asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val)); + break; + } + } + + if (access == ARCH_TIMER_VIRT_ACCESS) { + switch (reg) { + case ARCH_TIMER_REG_CTRL: + asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val)); + break; + case ARCH_TIMER_REG_TVAL: + asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val)); + break; + } + } + + isb(); +} + +static inline u32 arch_timer_reg_read(const int access, const int reg) +{ + u32 val = 0; + + if (access == ARCH_TIMER_PHYS_ACCESS) { + switch (reg) { + case ARCH_TIMER_REG_CTRL: + asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val)); + break; + case ARCH_TIMER_REG_TVAL: + asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val)); + break; + } + } + + if (access == ARCH_TIMER_VIRT_ACCESS) { + switch (reg) { + case ARCH_TIMER_REG_CTRL: + asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val)); + break; + case ARCH_TIMER_REG_TVAL: + asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val)); + break; + } + } + + return val; +} + +static inline u32 arch_timer_get_cntfrq(void) +{ + u32 val; + asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val)); + return val; +} + +static inline u64 arch_counter_get_cntpct(void) +{ + u64 cval; + + isb(); + asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval)); + return cval; +} + +static inline u64 arch_counter_get_cntvct(void) +{ + u64 cval; + + isb(); + asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval)); + return cval; +} + +static inline void __cpuinit arch_counter_set_user_access(void) +{ + u32 cntkctl; + + asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl)); + + /* disable user access to everything */ + cntkctl &= ~((3 << 8) | (7 << 0)); + + asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl)); +} #else static inline int arch_timer_of_register(void) { @@ -18,11 +120,6 @@ static inline int arch_timer_sched_clock_init(void) { return -ENXIO; } - -static inline struct timecounter *arch_timer_get_timecounter(void) -{ - return NULL; -} #endif #endif diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h index b69c0d3285f..dc662fca923 100644 --- a/arch/arm/include/asm/device.h +++ b/arch/arm/include/asm/device.h @@ -27,4 +27,10 @@ struct pdev_archdata { #endif }; +#ifdef CONFIG_ARM_DMA_USE_IOMMU +#define to_dma_iommu_mapping(dev) ((dev)->archdata.mapping) +#else +#define to_dma_iommu_mapping(dev) NULL +#endif + #endif diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h index 799b09409fa..a8c56acc8c9 100644 --- a/arch/arm/include/asm/dma-iommu.h +++ b/arch/arm/include/asm/dma-iommu.h @@ -7,6 +7,7 @@ #include <linux/scatterlist.h> #include <linux/dma-debug.h> #include <linux/kmemcheck.h> +#include <linux/kref.h> struct dma_iommu_mapping { /* iommu specific data */ @@ -29,6 +30,7 @@ void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping); int arm_iommu_attach_device(struct device *dev, struct dma_iommu_mapping *mapping); +void arm_iommu_detach_device(struct device *dev); #endif /* __KERNEL__ */ #endif diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h index 5694a0d6576..58b8c6a0ab1 100644 --- a/arch/arm/include/asm/dma.h +++ b/arch/arm/include/asm/dma.h @@ -105,7 +105,7 @@ extern void set_dma_sg(unsigned int chan, struct scatterlist *sg, int nr_sg); */ extern void __set_dma_addr(unsigned int chan, void *addr); #define set_dma_addr(chan, addr) \ - __set_dma_addr(chan, bus_to_virt(addr)) + __set_dma_addr(chan, (void *)__bus_to_virt(addr)) /* Set the DMA byte count for this channel * diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h deleted file mode 100644 index 4b1ce6cd477..00000000000 --- a/arch/arm/include/asm/hardware/gic.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * arch/arm/include/asm/hardware/gic.h - * - * Copyright (C) 2002 ARM Limited, All Rights Reserved. - * - * 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. - */ -#ifndef __ASM_ARM_HARDWARE_GIC_H -#define __ASM_ARM_HARDWARE_GIC_H - -#include <linux/compiler.h> - -#define GIC_CPU_CTRL 0x00 -#define GIC_CPU_PRIMASK 0x04 -#define GIC_CPU_BINPOINT 0x08 -#define GIC_CPU_INTACK 0x0c -#define GIC_CPU_EOI 0x10 -#define GIC_CPU_RUNNINGPRI 0x14 -#define GIC_CPU_HIGHPRI 0x18 - -#define GIC_DIST_CTRL 0x000 -#define GIC_DIST_CTR 0x004 -#define GIC_DIST_ENABLE_SET 0x100 -#define GIC_DIST_ENABLE_CLEAR 0x180 -#define GIC_DIST_PENDING_SET 0x200 -#define GIC_DIST_PENDING_CLEAR 0x280 -#define GIC_DIST_ACTIVE_BIT 0x300 -#define GIC_DIST_PRI 0x400 -#define GIC_DIST_TARGET 0x800 -#define GIC_DIST_CONFIG 0xc00 -#define GIC_DIST_SOFTINT 0xf00 - -#ifndef __ASSEMBLY__ -#include <linux/irqdomain.h> -struct device_node; - -extern struct irq_chip gic_arch_extn; - -void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, - u32 offset, struct device_node *); -int gic_of_init(struct device_node *node, struct device_node *parent); -void gic_secondary_init(unsigned int); -void gic_handle_irq(struct pt_regs *regs); -void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); -void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); - -static inline void gic_init(unsigned int nr, int start, - void __iomem *dist , void __iomem *cpu) -{ - gic_init_bases(nr, start, dist, cpu, 0, NULL); -} - -#endif - -#endif diff --git a/arch/arm/include/asm/hardware/pl080.h b/arch/arm/include/asm/hardware/pl080.h deleted file mode 100644 index 4eea2107214..00000000000 --- a/arch/arm/include/asm/hardware/pl080.h +++ /dev/null @@ -1,146 +0,0 @@ -/* arch/arm/include/asm/hardware/pl080.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - * - * ARM PrimeCell PL080 DMA controller - * - * 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. -*/ - -/* Note, there are some Samsung updates to this controller block which - * make it not entierly compatible with the PL080 specification from - * ARM. When in doubt, check the Samsung documentation first. - * - * The Samsung defines are PL080S, and add an extra control register, - * the ability to move more than 2^11 counts of data and some extra - * OneNAND features. -*/ - -#ifndef ASM_PL080_H -#define ASM_PL080_H - -#define PL080_INT_STATUS (0x00) -#define PL080_TC_STATUS (0x04) -#define PL080_TC_CLEAR (0x08) -#define PL080_ERR_STATUS (0x0C) -#define PL080_ERR_CLEAR (0x10) -#define PL080_RAW_TC_STATUS (0x14) -#define PL080_RAW_ERR_STATUS (0x18) -#define PL080_EN_CHAN (0x1c) -#define PL080_SOFT_BREQ (0x20) -#define PL080_SOFT_SREQ (0x24) -#define PL080_SOFT_LBREQ (0x28) -#define PL080_SOFT_LSREQ (0x2C) - -#define PL080_CONFIG (0x30) -#define PL080_CONFIG_M2_BE (1 << 2) -#define PL080_CONFIG_M1_BE (1 << 1) -#define PL080_CONFIG_ENABLE (1 << 0) - -#define PL080_SYNC (0x34) - -/* Per channel configuration registers */ - -#define PL080_Cx_STRIDE (0x20) -#define PL080_Cx_BASE(x) ((0x100 + (x * 0x20))) -#define PL080_Cx_SRC_ADDR(x) ((0x100 + (x * 0x20))) -#define PL080_Cx_DST_ADDR(x) ((0x104 + (x * 0x20))) -#define PL080_Cx_LLI(x) ((0x108 + (x * 0x20))) -#define PL080_Cx_CONTROL(x) ((0x10C + (x * 0x20))) -#define PL080_Cx_CONFIG(x) ((0x110 + (x * 0x20))) -#define PL080S_Cx_CONTROL2(x) ((0x110 + (x * 0x20))) -#define PL080S_Cx_CONFIG(x) ((0x114 + (x * 0x20))) - -#define PL080_CH_SRC_ADDR (0x00) -#define PL080_CH_DST_ADDR (0x04) -#define PL080_CH_LLI (0x08) -#define PL080_CH_CONTROL (0x0C) -#define PL080_CH_CONFIG (0x10) -#define PL080S_CH_CONTROL2 (0x10) -#define PL080S_CH_CONFIG (0x14) - -#define PL080_LLI_ADDR_MASK (0x3fffffff << 2) -#define PL080_LLI_ADDR_SHIFT (2) -#define PL080_LLI_LM_AHB2 (1 << 0) - -#define PL080_CONTROL_TC_IRQ_EN (1 << 31) -#define PL080_CONTROL_PROT_MASK (0x7 << 28) -#define PL080_CONTROL_PROT_SHIFT (28) -#define PL080_CONTROL_PROT_CACHE (1 << 30) -#define PL080_CONTROL_PROT_BUFF (1 << 29) -#define PL080_CONTROL_PROT_SYS (1 << 28) -#define PL080_CONTROL_DST_INCR (1 << 27) -#define PL080_CONTROL_SRC_INCR (1 << 26) -#define PL080_CONTROL_DST_AHB2 (1 << 25) -#define PL080_CONTROL_SRC_AHB2 (1 << 24) -#define PL080_CONTROL_DWIDTH_MASK (0x7 << 21) -#define PL080_CONTROL_DWIDTH_SHIFT (21) -#define PL080_CONTROL_SWIDTH_MASK (0x7 << 18) -#define PL080_CONTROL_SWIDTH_SHIFT (18) -#define PL080_CONTROL_DB_SIZE_MASK (0x7 << 15) -#define PL080_CONTROL_DB_SIZE_SHIFT (15) -#define PL080_CONTROL_SB_SIZE_MASK (0x7 << 12) -#define PL080_CONTROL_SB_SIZE_SHIFT (12) -#define PL080_CONTROL_TRANSFER_SIZE_MASK (0xfff << 0) -#define PL080_CONTROL_TRANSFER_SIZE_SHIFT (0) - -#define PL080_BSIZE_1 (0x0) -#define PL080_BSIZE_4 (0x1) -#define PL080_BSIZE_8 (0x2) -#define PL080_BSIZE_16 (0x3) -#define PL080_BSIZE_32 (0x4) -#define PL080_BSIZE_64 (0x5) -#define PL080_BSIZE_128 (0x6) -#define PL080_BSIZE_256 (0x7) - -#define PL080_WIDTH_8BIT (0x0) -#define PL080_WIDTH_16BIT (0x1) -#define PL080_WIDTH_32BIT (0x2) - -#define PL080N_CONFIG_ITPROT (1 << 20) -#define PL080N_CONFIG_SECPROT (1 << 19) -#define PL080_CONFIG_HALT (1 << 18) -#define PL080_CONFIG_ACTIVE (1 << 17) /* RO */ -#define PL080_CONFIG_LOCK (1 << 16) -#define PL080_CONFIG_TC_IRQ_MASK (1 << 15) -#define PL080_CONFIG_ERR_IRQ_MASK (1 << 14) -#define PL080_CONFIG_FLOW_CONTROL_MASK (0x7 << 11) -#define PL080_CONFIG_FLOW_CONTROL_SHIFT (11) -#define PL080_CONFIG_DST_SEL_MASK (0xf << 6) -#define PL080_CONFIG_DST_SEL_SHIFT (6) -#define PL080_CONFIG_SRC_SEL_MASK (0xf << 1) -#define PL080_CONFIG_SRC_SEL_SHIFT (1) -#define PL080_CONFIG_ENABLE (1 << 0) - -#define PL080_FLOW_MEM2MEM (0x0) -#define PL080_FLOW_MEM2PER (0x1) -#define PL080_FLOW_PER2MEM (0x2) -#define PL080_FLOW_SRC2DST (0x3) -#define PL080_FLOW_SRC2DST_DST (0x4) -#define PL080_FLOW_MEM2PER_PER (0x5) -#define PL080_FLOW_PER2MEM_PER (0x6) -#define PL080_FLOW_SRC2DST_SRC (0x7) - -/* DMA linked list chain structure */ - -struct pl080_lli { - u32 src_addr; - u32 dst_addr; - u32 next_lli; - u32 control0; -}; - -struct pl080s_lli { - u32 src_addr; - u32 dst_addr; - u32 next_lli; - u32 control0; - u32 control1; -}; - -#endif /* ASM_PL080_H */ diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h deleted file mode 100644 index 6636430dd0e..00000000000 --- a/arch/arm/include/asm/hardware/sp810.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * arch/arm/include/asm/hardware/sp810.h - * - * ARM PrimeXsys System Controller SP810 header file - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar <viresh.linux@gmail.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __ASM_ARM_SP810_H -#define __ASM_ARM_SP810_H - -#include <linux/io.h> - -/* sysctl registers offset */ -#define SCCTRL 0x000 -#define SCSYSSTAT 0x004 -#define SCIMCTRL 0x008 -#define SCIMSTAT 0x00C -#define SCXTALCTRL 0x010 -#define SCPLLCTRL 0x014 -#define SCPLLFCTRL 0x018 -#define SCPERCTRL0 0x01C -#define SCPERCTRL1 0x020 -#define SCPEREN 0x024 -#define SCPERDIS 0x028 -#define SCPERCLKEN 0x02C -#define SCPERSTAT 0x030 -#define SCSYSID0 0xEE0 -#define SCSYSID1 0xEE4 -#define SCSYSID2 0xEE8 -#define SCSYSID3 0xEEC -#define SCITCR 0xF00 -#define SCITIR0 0xF04 -#define SCITIR1 0xF08 -#define SCITOR 0xF0C -#define SCCNTCTRL 0xF10 -#define SCCNTDATA 0xF14 -#define SCCNTSTEP 0xF18 -#define SCPERIPHID0 0xFE0 -#define SCPERIPHID1 0xFE4 -#define SCPERIPHID2 0xFE8 -#define SCPERIPHID3 0xFEC -#define SCPCELLID0 0xFF0 -#define SCPCELLID1 0xFF4 -#define SCPCELLID2 0xFF8 -#define SCPCELLID3 0xFFC - -#define SCCTRL_TIMERENnSEL_SHIFT(n) (15 + ((n) * 2)) - -static inline void sysctl_soft_reset(void __iomem *base) -{ - /* switch to slow mode */ - writel(0x2, base + SCCTRL); - - /* writing any value to SCSYSSTAT reg will reset system */ - writel(0, base + SCSYSSTAT); -} - -#endif /* __ASM_ARM_SP810_H */ diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h deleted file mode 100644 index 2bebad36fc8..00000000000 --- a/arch/arm/include/asm/hardware/vic.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * arch/arm/include/asm/hardware/vic.h - * - * Copyright (c) ARM Limited 2003. All rights reserved. - * - * 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. - * - * 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARM_HARDWARE_VIC_H -#define __ASM_ARM_HARDWARE_VIC_H - -#define VIC_IRQ_STATUS 0x00 -#define VIC_FIQ_STATUS 0x04 -#define VIC_RAW_STATUS 0x08 -#define VIC_INT_SELECT 0x0c /* 1 = FIQ, 0 = IRQ */ -#define VIC_INT_ENABLE 0x10 /* 1 = enable, 0 = disable */ -#define VIC_INT_ENABLE_CLEAR 0x14 -#define VIC_INT_SOFT 0x18 -#define VIC_INT_SOFT_CLEAR 0x1c -#define VIC_PROTECT 0x20 -#define VIC_PL190_VECT_ADDR 0x30 /* PL190 only */ -#define VIC_PL190_DEF_VECT_ADDR 0x34 /* PL190 only */ - -#define VIC_VECT_ADDR0 0x100 /* 0 to 15 (0..31 PL192) */ -#define VIC_VECT_CNTL0 0x200 /* 0 to 15 (0..31 PL192) */ -#define VIC_ITCR 0x300 /* VIC test control register */ - -#define VIC_VECT_CNTL_ENABLE (1 << 5) - -#define VIC_PL192_VECT_ADDR 0xF00 - -#ifndef __ASSEMBLY__ -#include <linux/compiler.h> -#include <linux/types.h> - -struct device_node; -struct pt_regs; - -void __vic_init(void __iomem *base, int irq_start, u32 vic_sources, - u32 resume_sources, struct device_node *node); -void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); -int vic_of_init(struct device_node *node, struct device_node *parent); -void vic_handle_irq(struct pt_regs *regs); - -#endif /* __ASSEMBLY__ */ -#endif diff --git a/arch/arm/include/asm/kvm_arch_timer.h b/arch/arm/include/asm/kvm_arch_timer.h new file mode 100644 index 00000000000..68cb9e1dfb8 --- /dev/null +++ b/arch/arm/include/asm/kvm_arch_timer.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2012 ARM Ltd. + * Author: Marc Zyngier <marc.zyngier@arm.com> + * + * 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARM_KVM_ARCH_TIMER_H +#define __ASM_ARM_KVM_ARCH_TIMER_H + +#include <linux/clocksource.h> +#include <linux/hrtimer.h> +#include <linux/workqueue.h> + +struct arch_timer_kvm { +#ifdef CONFIG_KVM_ARM_TIMER + /* Is the timer enabled */ + bool enabled; + + /* Virtual offset */ + cycle_t cntvoff; +#endif +}; + +struct arch_timer_cpu { +#ifdef CONFIG_KVM_ARM_TIMER + /* Registers: control register, timer value */ + u32 cntv_ctl; /* Saved/restored */ + cycle_t cntv_cval; /* Saved/restored */ + + /* + * Anything that is not used directly from assembly code goes + * here. + */ + + /* Background timer used when the guest is not running */ + struct hrtimer timer; + + /* Work queued with the above timer expires */ + struct work_struct expired; + + /* Background timer active */ + bool armed; + + /* Timer IRQ */ + const struct kvm_irq_level *irq; +#endif +}; + +#ifdef CONFIG_KVM_ARM_TIMER +int kvm_timer_hyp_init(void); +int kvm_timer_init(struct kvm *kvm); +void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); +void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu); +void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu); +void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu); +#else +static inline int kvm_timer_hyp_init(void) +{ + return 0; +}; + +static inline int kvm_timer_init(struct kvm *kvm) +{ + return 0; +} + +static inline void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) {} +static inline void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) {} +static inline void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu) {} +static inline void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu) {} +#endif + +#endif diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h index 5e06e817778..e4956f4e23e 100644 --- a/arch/arm/include/asm/kvm_asm.h +++ b/arch/arm/include/asm/kvm_asm.h @@ -45,7 +45,8 @@ #define c13_TID_URW 23 /* Thread ID, User R/W */ #define c13_TID_URO 24 /* Thread ID, User R/O */ #define c13_TID_PRIV 25 /* Thread ID, Privileged */ -#define NR_CP15_REGS 26 /* Number of regs (incl. invalid) */ +#define c14_CNTKCTL 26 /* Timer Control Register (PL1) */ +#define NR_CP15_REGS 27 /* Number of regs (incl. invalid) */ #define ARM_EXCEPTION_RESET 0 #define ARM_EXCEPTION_UNDEFINED 1 diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 98b4d1a7292..d1736a53b12 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -23,9 +23,10 @@ #include <asm/kvm_asm.h> #include <asm/kvm_mmio.h> #include <asm/fpstate.h> +#include <asm/kvm_arch_timer.h> #define KVM_MAX_VCPUS CONFIG_KVM_ARM_MAX_VCPUS -#define KVM_MEMORY_SLOTS 32 +#define KVM_USER_MEM_SLOTS 32 #define KVM_PRIVATE_MEM_SLOTS 4 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 #define KVM_HAVE_ONE_REG @@ -37,6 +38,8 @@ #define KVM_NR_PAGE_SIZES 1 #define KVM_PAGES_PER_HPAGE(x) (1UL<<31) +#include <asm/kvm_vgic.h> + struct kvm_vcpu; u32 *kvm_vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num, u32 mode); int kvm_target_cpu(void); @@ -47,6 +50,9 @@ struct kvm_arch { /* VTTBR value associated with below pgd and vmid */ u64 vttbr; + /* Timer */ + struct arch_timer_kvm timer; + /* * Anything that is not used directly from assembly code goes * here. @@ -58,6 +64,9 @@ struct kvm_arch { /* Stage-2 page table */ pgd_t *pgd; + + /* Interrupt controller */ + struct vgic_dist vgic; }; #define KVM_NR_MEM_OBJS 40 @@ -92,6 +101,10 @@ struct kvm_vcpu_arch { struct vfp_hard_struct vfp_guest; struct vfp_hard_struct *vfp_host; + /* VGIC state */ + struct vgic_cpu vgic_cpu; + struct arch_timer_cpu timer_cpu; + /* * Anything that is not used directly from assembly code goes * here. @@ -158,4 +171,14 @@ static inline int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) { return 0; } + +struct kvm_vcpu *kvm_arm_get_running_vcpu(void); +struct kvm_vcpu __percpu **kvm_get_running_vcpus(void); + +int kvm_arm_copy_coproc_indices(struct kvm_vcpu *vcpu, u64 __user *uindices); +unsigned long kvm_arm_num_coproc_regs(struct kvm_vcpu *vcpu); +struct kvm_one_reg; +int kvm_arm_coproc_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); +int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *); + #endif /* __ARM_KVM_HOST_H__ */ diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h new file mode 100644 index 00000000000..ab97207d9cd --- /dev/null +++ b/arch/arm/include/asm/kvm_vgic.h @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2012 ARM Ltd. + * Author: Marc Zyngier <marc.zyngier@arm.com> + * + * 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARM_KVM_VGIC_H +#define __ASM_ARM_KVM_VGIC_H + +#include <linux/kernel.h> +#include <linux/kvm.h> +#include <linux/kvm_host.h> +#include <linux/irqreturn.h> +#include <linux/spinlock.h> +#include <linux/types.h> +#include <linux/irqchip/arm-gic.h> + +#define VGIC_NR_IRQS 128 +#define VGIC_NR_SGIS 16 +#define VGIC_NR_PPIS 16 +#define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS) +#define VGIC_NR_SHARED_IRQS (VGIC_NR_IRQS - VGIC_NR_PRIVATE_IRQS) +#define VGIC_MAX_CPUS KVM_MAX_VCPUS +#define VGIC_MAX_LRS (1 << 6) + +/* Sanity checks... */ +#if (VGIC_MAX_CPUS > 8) +#error Invalid number of CPU interfaces +#endif + +#if (VGIC_NR_IRQS & 31) +#error "VGIC_NR_IRQS must be a multiple of 32" +#endif + +#if (VGIC_NR_IRQS > 1024) +#error "VGIC_NR_IRQS must be <= 1024" +#endif + +/* + * The GIC distributor registers describing interrupts have two parts: + * - 32 per-CPU interrupts (SGI + PPI) + * - a bunch of shared interrupts (SPI) + */ +struct vgic_bitmap { + union { + u32 reg[VGIC_NR_PRIVATE_IRQS / 32]; + DECLARE_BITMAP(reg_ul, VGIC_NR_PRIVATE_IRQS); + } percpu[VGIC_MAX_CPUS]; + union { + u32 reg[VGIC_NR_SHARED_IRQS / 32]; + DECLARE_BITMAP(reg_ul, VGIC_NR_SHARED_IRQS); + } shared; +}; + +struct vgic_bytemap { + u32 percpu[VGIC_MAX_CPUS][VGIC_NR_PRIVATE_IRQS / 4]; + u32 shared[VGIC_NR_SHARED_IRQS / 4]; +}; + +struct vgic_dist { +#ifdef CONFIG_KVM_ARM_VGIC + spinlock_t lock; + bool ready; + + /* Virtual control interface mapping */ + void __iomem *vctrl_base; + + /* Distributor and vcpu interface mapping in the guest */ + phys_addr_t vgic_dist_base; + phys_addr_t vgic_cpu_base; + + /* Distributor enabled */ + u32 enabled; + + /* Interrupt enabled (one bit per IRQ) */ + struct vgic_bitmap irq_enabled; + + /* Interrupt 'pin' level */ + struct vgic_bitmap irq_state; + + /* Level-triggered interrupt in progress */ + struct vgic_bitmap irq_active; + + /* Interrupt priority. Not used yet. */ + struct vgic_bytemap irq_priority; + + /* Level/edge triggered */ + struct vgic_bitmap irq_cfg; + + /* Source CPU per SGI and target CPU */ + u8 irq_sgi_sources[VGIC_MAX_CPUS][VGIC_NR_SGIS]; + + /* Target CPU for each IRQ */ + u8 irq_spi_cpu[VGIC_NR_SHARED_IRQS]; + struct vgic_bitmap irq_spi_target[VGIC_MAX_CPUS]; + + /* Bitmap indicating which CPU has something pending */ + unsigned long irq_pending_on_cpu; +#endif +}; + +struct vgic_cpu { +#ifdef CONFIG_KVM_ARM_VGIC + /* per IRQ to LR mapping */ + u8 vgic_irq_lr_map[VGIC_NR_IRQS]; + + /* Pending interrupts on this VCPU */ + DECLARE_BITMAP( pending_percpu, VGIC_NR_PRIVATE_IRQS); + DECLARE_BITMAP( pending_shared, VGIC_NR_SHARED_IRQS); + + /* Bitmap of used/free list registers */ + DECLARE_BITMAP( lr_used, VGIC_MAX_LRS); + + /* Number of list registers on this CPU */ + int nr_lr; + + /* CPU vif control registers for world switch */ + u32 vgic_hcr; + u32 vgic_vmcr; + u32 vgic_misr; /* Saved only */ + u32 vgic_eisr[2]; /* Saved only */ + u32 vgic_elrsr[2]; /* Saved only */ + u32 vgic_apr; + u32 vgic_lr[VGIC_MAX_LRS]; +#endif +}; + +#define LR_EMPTY 0xff + +struct kvm; +struct kvm_vcpu; +struct kvm_run; +struct kvm_exit_mmio; + +#ifdef CONFIG_KVM_ARM_VGIC +int kvm_vgic_set_addr(struct kvm *kvm, unsigned long type, u64 addr); +int kvm_vgic_hyp_init(void); +int kvm_vgic_init(struct kvm *kvm); +int kvm_vgic_create(struct kvm *kvm); +int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); +void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); +void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu); +int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num, + bool level); +int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); +bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, + struct kvm_exit_mmio *mmio); + +#define irqchip_in_kernel(k) (!!((k)->arch.vgic.vctrl_base)) +#define vgic_initialized(k) ((k)->arch.vgic.ready) + +#else +static inline int kvm_vgic_hyp_init(void) +{ + return 0; +} + +static inline int kvm_vgic_set_addr(struct kvm *kvm, unsigned long type, u64 addr) +{ + return 0; +} + +static inline int kvm_vgic_init(struct kvm *kvm) +{ + return 0; +} + +static inline int kvm_vgic_create(struct kvm *kvm) +{ + return 0; +} + +static inline int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) +{ + return 0; +} + +static inline void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) {} +static inline void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) {} + +static inline int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, + unsigned int irq_num, bool level) +{ + return 0; +} + +static inline int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) +{ + return 0; +} + +static inline bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, + struct kvm_exit_mmio *mmio) +{ + return false; +} + +static inline int irqchip_in_kernel(struct kvm *kvm) +{ + return 0; +} + +static inline bool vgic_initialized(struct kvm *kvm) +{ + return true; +} +#endif + +#endif diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index 917d4fcfd9b..308ad7d6f98 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -12,7 +12,6 @@ struct tag; struct meminfo; -struct sys_timer; struct pt_regs; struct smp_operations; #ifdef CONFIG_SMP @@ -48,7 +47,7 @@ struct machine_desc { void (*map_io)(void);/* IO mapping function */ void (*init_early)(void); void (*init_irq)(void); - struct sys_timer *timer; /* system tick timer */ + void (*init_time)(void); void (*init_machine)(void); void (*init_late)(void); #ifdef CONFIG_MULTI_IRQ_HANDLER diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h index 15cb035309f..18c88302333 100644 --- a/arch/arm/include/asm/mach/irq.h +++ b/arch/arm/include/asm/mach/irq.h @@ -22,6 +22,7 @@ extern int show_fiq_list(struct seq_file *, int); #ifdef CONFIG_MULTI_IRQ_HANDLER extern void (*handle_arch_irq)(struct pt_regs *); +extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); #endif /* diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h index db9fedb57f2..5cf2e979b4b 100644 --- a/arch/arm/include/asm/mach/pci.h +++ b/arch/arm/include/asm/mach/pci.h @@ -23,6 +23,7 @@ struct hw_pci { #endif struct pci_ops *ops; int nr_controllers; + void **private_data; int (*setup)(int nr, struct pci_sys_data *); struct pci_bus *(*scan)(int nr, struct pci_sys_data *); void (*preinit)(void); diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h index 6ca945f534a..90c12e1e695 100644 --- a/arch/arm/include/asm/mach/time.h +++ b/arch/arm/include/asm/mach/time.h @@ -10,36 +10,6 @@ #ifndef __ASM_ARM_MACH_TIME_H #define __ASM_ARM_MACH_TIME_H -/* - * This is our kernel timer structure. - * - * - init - * Initialise the kernels jiffy timer source, claim interrupt - * using setup_irq. This is called early on during initialisation - * while interrupts are still disabled on the local CPU. - * - suspend - * Suspend the kernel jiffy timer source, if necessary. This - * is called with interrupts disabled, after all normal devices - * have been suspended. If no action is required, set this to - * NULL. - * - resume - * Resume the kernel jiffy timer source, if necessary. This - * is called with interrupts disabled before any normal devices - * are resumed. If no action is required, set this to NULL. - * - offset - * Return the timer offset in microseconds since the last timer - * interrupt. Note: this must take account of any unprocessed - * timer interrupt which may be pending. - */ -struct sys_timer { - void (*init)(void); - void (*suspend)(void); - void (*resume)(void); -#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET - unsigned long (*offset)(void); -#endif -}; - extern void timer_tick(void); struct timespec; diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 1c4df27f933..57870ab313c 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -36,23 +36,23 @@ * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area */ #define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET) -#define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(0x01000000)) +#define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(SZ_16M)) #define TASK_UNMAPPED_BASE ALIGN(TASK_SIZE / 3, SZ_16M) /* * The maximum size of a 26-bit user space task. */ -#define TASK_SIZE_26 UL(0x04000000) +#define TASK_SIZE_26 (UL(1) << 26) /* * The module space lives between the addresses given by TASK_SIZE * and PAGE_OFFSET - it must be within 32MB of the kernel text. */ #ifndef CONFIG_THUMB2_KERNEL -#define MODULES_VADDR (PAGE_OFFSET - 16*1024*1024) +#define MODULES_VADDR (PAGE_OFFSET - SZ_16M) #else /* smaller range for Thumb-2 symbols relocation (2^24)*/ -#define MODULES_VADDR (PAGE_OFFSET - 8*1024*1024) +#define MODULES_VADDR (PAGE_OFFSET - SZ_8M) #endif #if TASK_SIZE > MODULES_VADDR @@ -245,6 +245,7 @@ static inline void *phys_to_virt(phys_addr_t x) #define __bus_to_pfn(x) __phys_to_pfn(x) #endif +#ifdef CONFIG_VIRT_TO_BUS static inline __deprecated unsigned long virt_to_bus(void *x) { return __virt_to_bus((unsigned long)x); @@ -254,6 +255,7 @@ static inline __deprecated void *bus_to_virt(unsigned long x) { return (void *)__bus_to_virt(x); } +#endif /* * Conversion between a struct page and a physical address. diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h index 53426c66352..12f71a19042 100644 --- a/arch/arm/include/asm/outercache.h +++ b/arch/arm/include/asm/outercache.h @@ -92,6 +92,7 @@ static inline void outer_flush_range(phys_addr_t start, phys_addr_t end) static inline void outer_flush_all(void) { } static inline void outer_inv_all(void) { } static inline void outer_disable(void) { } +static inline void outer_resume(void) { } #endif diff --git a/arch/arm/include/asm/signal.h b/arch/arm/include/asm/signal.h index 9a0ea6ab988..c0eb412aff0 100644 --- a/arch/arm/include/asm/signal.h +++ b/arch/arm/include/asm/signal.h @@ -16,23 +16,7 @@ typedef struct { unsigned long sig[_NSIG_WORDS]; } sigset_t; -struct old_sigaction { - __sighandler_t sa_handler; - old_sigset_t sa_mask; - unsigned long sa_flags; - __sigrestore_t sa_restorer; -}; - -struct sigaction { - __sighandler_t sa_handler; - unsigned long sa_flags; - __sigrestore_t sa_restorer; - sigset_t sa_mask; /* mask last for extensibility */ -}; - -struct k_sigaction { - struct sigaction sa; -}; +#define __ARCH_HAS_SA_RESTORER #include <asm/sigcontext.h> #endif diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h index 4eb6d005ffa..18d16937361 100644 --- a/arch/arm/include/asm/smp_scu.h +++ b/arch/arm/include/asm/smp_scu.h @@ -6,9 +6,32 @@ #define SCU_PM_POWEROFF 3 #ifndef __ASSEMBLER__ + +#include <asm/cputype.h> + +static inline bool scu_a9_has_base(void) +{ + return read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9; +} + +static inline unsigned long scu_a9_get_base(void) +{ + unsigned long pa; + + asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (pa)); + + return pa; +} + unsigned int scu_get_core_count(void __iomem *); -void scu_enable(void __iomem *); int scu_power_mode(void __iomem *, unsigned int); + +#ifdef CONFIG_SMP +void scu_enable(void __iomem *scu_base); +#else +static inline void scu_enable(void __iomem *scu_base) {} +#endif + #endif #endif diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h index b4ca707d0a6..6220e9fdf4c 100644 --- a/arch/arm/include/asm/spinlock.h +++ b/arch/arm/include/asm/spinlock.h @@ -119,22 +119,8 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) static inline void arch_spin_unlock(arch_spinlock_t *lock) { - unsigned long tmp; - u32 slock; - smp_mb(); - - __asm__ __volatile__( -" mov %1, #1\n" -"1: ldrex %0, [%2]\n" -" uadd16 %0, %0, %1\n" -" strex %1, %0, [%2]\n" -" teq %1, #0\n" -" bne 1b" - : "=&r" (slock), "=&r" (tmp) - : "r" (&lock->slock) - : "cc"); - + lock->tickets.owner++; dsb_sev(); } diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 21a2700d295..e4ddfb39ca3 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h @@ -26,8 +26,6 @@ #define __ARCH_WANT_SYS_NICE #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK -#define __ARCH_WANT_SYS_RT_SIGACTION -#define __ARCH_WANT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_SYS_OLD_MMAP #define __ARCH_WANT_SYS_OLD_SELECT diff --git a/arch/arm/include/asm/xen/events.h b/arch/arm/include/asm/xen/events.h index 94b4e9020b0..5c27696de14 100644 --- a/arch/arm/include/asm/xen/events.h +++ b/arch/arm/include/asm/xen/events.h @@ -15,4 +15,26 @@ static inline int xen_irqs_disabled(struct pt_regs *regs) return raw_irqs_disabled_flags(regs->ARM_cpsr); } +/* + * We cannot use xchg because it does not support 8-byte + * values. However it is safe to use {ldr,dtd}exd directly because all + * platforms which Xen can run on support those instructions. + */ +static inline xen_ulong_t xchg_xen_ulong(xen_ulong_t *ptr, xen_ulong_t val) +{ + xen_ulong_t oldval; + unsigned int tmp; + + wmb(); + asm volatile("@ xchg_xen_ulong\n" + "1: ldrexd %0, %H0, [%3]\n" + " strexd %1, %2, %H2, [%3]\n" + " teq %1, #0\n" + " bne 1b" + : "=&r" (oldval), "=&r" (tmp) + : "r" (val), "r" (ptr) + : "memory", "cc"); + return oldval; +} + #endif /* _ASM_ARM_XEN_EVENTS_H */ diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h index c6b9096cef9..30cdacb675a 100644 --- a/arch/arm/include/asm/xen/page.h +++ b/arch/arm/include/asm/xen/page.h @@ -1,6 +1,7 @@ #ifndef _ASM_ARM_XEN_PAGE_H #define _ASM_ARM_XEN_PAGE_H +#include <asm/mach/map.h> #include <asm/page.h> #include <asm/pgtable.h> @@ -86,4 +87,7 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn) { return __set_phys_to_machine(pfn, mfn); } + +#define xen_remap(cookie, size) __arm_ioremap((cookie), (size), MT_MEMORY); + #endif /* _ASM_ARM_XEN_PAGE_H */ diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h new file mode 100644 index 00000000000..91d38e38a0b --- /dev/null +++ b/arch/arm/include/debug/imx-uart.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2012 Freescale Semiconductor, Inc. + * + * 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. + */ + +#ifndef __DEBUG_IMX_UART_H +#define __DEBUG_IMX_UART_H + +#define IMX1_UART1_BASE_ADDR 0x00206000 +#define IMX1_UART2_BASE_ADDR 0x00207000 +#define IMX1_UART_BASE_ADDR(n) IMX1_UART##n##_BASE_ADDR +#define IMX1_UART_BASE(n) IMX1_UART_BASE_ADDR(n) + +#define IMX21_UART1_BASE_ADDR 0x1000a000 +#define IMX21_UART2_BASE_ADDR 0x1000b000 +#define IMX21_UART3_BASE_ADDR 0x1000c000 +#define IMX21_UART4_BASE_ADDR 0x1000d000 +#define IMX21_UART_BASE_ADDR(n) IMX21_UART##n##_BASE_ADDR +#define IMX21_UART_BASE(n) IMX21_UART_BASE_ADDR(n) + +#define IMX25_UART1_BASE_ADDR 0x43f90000 +#define IMX25_UART2_BASE_ADDR 0x43f94000 +#define IMX25_UART3_BASE_ADDR 0x5000c000 +#define IMX25_UART4_BASE_ADDR 0x50008000 +#define IMX25_UART5_BASE_ADDR 0x5002c000 +#define IMX25_UART_BASE_ADDR(n) IMX25_UART##n##_BASE_ADDR +#define IMX25_UART_BASE(n) IMX25_UART_BASE_ADDR(n) + +#define IMX31_UART1_BASE_ADDR 0x43f90000 +#define IMX31_UART2_BASE_ADDR 0x43f94000 +#define IMX31_UART3_BASE_ADDR 0x5000c000 +#define IMX31_UART4_BASE_ADDR 0x43fb0000 +#define IMX31_UART5_BASE_ADDR 0x43fb4000 +#define IMX31_UART_BASE_ADDR(n) IMX31_UART##n##_BASE_ADDR +#define IMX31_UART_BASE(n) IMX31_UART_BASE_ADDR(n) + +#define IMX35_UART1_BASE_ADDR 0x43f90000 +#define IMX35_UART2_BASE_ADDR 0x43f94000 +#define IMX35_UART3_BASE_ADDR 0x5000c000 +#define IMX35_UART_BASE_ADDR(n) IMX35_UART##n##_BASE_ADDR +#define IMX35_UART_BASE(n) IMX35_UART_BASE_ADDR(n) + +#define IMX51_UART1_BASE_ADDR 0x73fbc000 +#define IMX51_UART2_BASE_ADDR 0x73fc0000 +#define IMX51_UART3_BASE_ADDR 0x7000c000 +#define IMX51_UART_BASE_ADDR(n) IMX51_UART##n##_BASE_ADDR +#define IMX51_UART_BASE(n) IMX51_UART_BASE_ADDR(n) + +#define IMX53_UART1_BASE_ADDR 0x53fbc000 +#define IMX53_UART2_BASE_ADDR 0x53fc0000 +#define IMX53_UART3_BASE_ADDR 0x5000c000 +#define IMX53_UART4_BASE_ADDR 0x53ff0000 +#define IMX53_UART5_BASE_ADDR 0x63f90000 +#define IMX53_UART_BASE_ADDR(n) IMX53_UART##n##_BASE_ADDR +#define IMX53_UART_BASE(n) IMX53_UART_BASE_ADDR(n) + +#define IMX6Q_UART1_BASE_ADDR 0x02020000 +#define IMX6Q_UART2_BASE_ADDR 0x021e8000 +#define IMX6Q_UART3_BASE_ADDR 0x021ec000 +#define IMX6Q_UART4_BASE_ADDR 0x021f0000 +#define IMX6Q_UART5_BASE_ADDR 0x021f4000 +#define IMX6Q_UART_BASE_ADDR(n) IMX6Q_UART##n##_BASE_ADDR +#define IMX6Q_UART_BASE(n) IMX6Q_UART_BASE_ADDR(n) + +#define IMX_DEBUG_UART_BASE(soc) soc##_UART_BASE(CONFIG_DEBUG_IMX_UART_PORT) + +#ifdef CONFIG_DEBUG_IMX1_UART +#define UART_PADDR IMX_DEBUG_UART_BASE(IMX1) +#elif defined(CONFIG_DEBUG_IMX21_IMX27_UART) +#define UART_PADDR IMX_DEBUG_UART_BASE(IMX21) +#elif defined(CONFIG_DEBUG_IMX25_UART) +#define UART_PADDR IMX_DEBUG_UART_BASE(IMX25) +#elif defined(CONFIG_DEBUG_IMX31_UART) +#define UART_PADDR IMX_DEBUG_UART_BASE(IMX31) +#elif defined(CONFIG_DEBUG_IMX35_UART) +#define UART_PADDR IMX_DEBUG_UART_BASE(IMX35) +#elif defined(CONFIG_DEBUG_IMX51_UART) +#define UART_PADDR IMX_DEBUG_UART_BASE(IMX51) +#elif defined(CONFIG_DEBUG_IMX53_UART) +#define UART_PADDR IMX_DEBUG_UART_BASE(IMX53) +#elif defined(CONFIG_DEBUG_IMX6Q_UART) +#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6Q) +#endif + +#endif /* __DEBUG_IMX_UART_H */ diff --git a/arch/arm/include/debug/imx.S b/arch/arm/include/debug/imx.S index 0c4e17d4d35..619d8cc1ac1 100644 --- a/arch/arm/include/debug/imx.S +++ b/arch/arm/include/debug/imx.S @@ -10,35 +10,8 @@ * published by the Free Software Foundation. * */ -#define IMX6Q_UART1_BASE_ADDR 0x02020000 -#define IMX6Q_UART2_BASE_ADDR 0x021e8000 -#define IMX6Q_UART3_BASE_ADDR 0x021ec000 -#define IMX6Q_UART4_BASE_ADDR 0x021f0000 -#define IMX6Q_UART5_BASE_ADDR 0x021f4000 -/* - * IMX6Q_UART_BASE_ADDR is put in the middle to force the expansion - * of IMX6Q_UART##n##_BASE_ADDR. - */ -#define IMX6Q_UART_BASE_ADDR(n) IMX6Q_UART##n##_BASE_ADDR -#define IMX6Q_UART_BASE(n) IMX6Q_UART_BASE_ADDR(n) -#define IMX6Q_DEBUG_UART_BASE IMX6Q_UART_BASE(CONFIG_DEBUG_IMX6Q_UART_PORT) - -#ifdef CONFIG_DEBUG_IMX1_UART -#define UART_PADDR 0x00206000 -#elif defined (CONFIG_DEBUG_IMX25_UART) -#define UART_PADDR 0x43f90000 -#elif defined (CONFIG_DEBUG_IMX21_IMX27_UART) -#define UART_PADDR 0x1000a000 -#elif defined (CONFIG_DEBUG_IMX31_IMX35_UART) -#define UART_PADDR 0x43f90000 -#elif defined (CONFIG_DEBUG_IMX51_UART) -#define UART_PADDR 0x73fbc000 -#elif defined (CONFIG_DEBUG_IMX50_IMX53_UART) -#define UART_PADDR 0x53fbc000 -#elif defined (CONFIG_DEBUG_IMX6Q_UART) -#define UART_PADDR IMX6Q_DEBUG_UART_BASE -#endif +#include "imx-uart.h" /* * FIXME: This is a copy of IMX_IO_P2V in hardware.h, and needs to diff --git a/arch/arm/include/debug/omap2plus.S b/arch/arm/include/debug/omap2plus.S new file mode 100644 index 00000000000..6d867aef18e --- /dev/null +++ b/arch/arm/include/debug/omap2plus.S @@ -0,0 +1,190 @@ +/* + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * 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. + * +*/ + +#include <linux/serial_reg.h> + +/* OMAP2 serial ports */ +#define OMAP2_UART1_BASE 0x4806a000 +#define OMAP2_UART2_BASE 0x4806c000 +#define OMAP2_UART3_BASE 0x4806e000 + +/* OMAP3 serial ports */ +#define OMAP3_UART1_BASE OMAP2_UART1_BASE +#define OMAP3_UART2_BASE OMAP2_UART2_BASE +#define OMAP3_UART3_BASE 0x49020000 +#define OMAP3_UART4_BASE 0x49042000 /* Only on 36xx */ +#define OMAP3_UART4_AM35XX_BASE 0x4809E000 /* Only on AM35xx */ + +/* OMAP4 serial ports */ +#define OMAP4_UART1_BASE OMAP2_UART1_BASE +#define OMAP4_UART2_BASE OMAP2_UART2_BASE +#define OMAP4_UART3_BASE 0x48020000 +#define OMAP4_UART4_BASE 0x4806e000 + +/* TI81XX serial ports */ +#define TI81XX_UART1_BASE 0x48020000 +#define TI81XX_UART2_BASE 0x48022000 +#define TI81XX_UART3_BASE 0x48024000 + +/* AM3505/3517 UART4 */ +#define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */ + +/* AM33XX serial port */ +#define AM33XX_UART1_BASE 0x44E09000 + +/* OMAP5 serial ports */ +#define OMAP5_UART1_BASE OMAP2_UART1_BASE +#define OMAP5_UART2_BASE OMAP2_UART2_BASE +#define OMAP5_UART3_BASE OMAP4_UART3_BASE +#define OMAP5_UART4_BASE OMAP4_UART4_BASE +#define OMAP5_UART5_BASE 0x48066000 +#define OMAP5_UART6_BASE 0x48068000 + +/* External port on Zoom2/3 */ +#define ZOOM_UART_BASE 0x10000000 +#define ZOOM_UART_VIRT 0xfa400000 + +#define OMAP_PORT_SHIFT 2 +#define ZOOM_PORT_SHIFT 1 + +#define UART_OFFSET(addr) ((addr) & 0x00ffffff) + + .pushsection .data +omap_uart_phys: .word 0 +omap_uart_virt: .word 0 +omap_uart_lsr: .word 0 + .popsection + + .macro addruart, rp, rv, tmp + + /* Use omap_uart_phys/virt if already configured */ +10: adr \rp, 99f @ get effective addr of 99f + ldr \rv, [\rp] @ get absolute addr of 99f + sub \rv, \rv, \rp @ offset between the two + ldr \rp, [\rp, #4] @ abs addr of omap_uart_phys + sub \tmp, \rp, \rv @ make it effective + ldr \rp, [\tmp, #0] @ omap_uart_phys + ldr \rv, [\tmp, #4] @ omap_uart_virt + cmp \rp, #0 @ is port configured? + cmpne \rv, #0 + bne 100f @ already configured + + /* Configure the UART offset from the phys/virt base */ +#ifdef CONFIG_DEBUG_OMAP2UART1 + mov \rp, #UART_OFFSET(OMAP2_UART1_BASE) @ omap2/3/4 + b 98f +#endif +#ifdef CONFIG_DEBUG_OMAP2UART2 + mov \rp, #UART_OFFSET(OMAP2_UART2_BASE) @ omap2/3/4 + b 98f +#endif +#ifdef CONFIG_DEBUG_OMAP2UART3 + mov \rp, #UART_OFFSET(OMAP2_UART3_BASE) + b 98f +#endif +#ifdef CONFIG_DEBUG_OMAP3UART3 + mov \rp, #UART_OFFSET(OMAP3_UART1_BASE) + add \rp, \rp, #0x00fb0000 + add \rp, \rp, #0x00006000 @ OMAP3_UART3_BASE + b 98f +#endif +#ifdef CONFIG_DEBUG_OMAP4UART3 + mov \rp, #UART_OFFSET(OMAP4_UART3_BASE) + b 98f +#endif +#ifdef CONFIG_DEBUG_OMAP3UART4 + mov \rp, #UART_OFFSET(OMAP3_UART1_BASE) + add \rp, \rp, #0x00fb0000 + add \rp, \rp, #0x00028000 @ OMAP3_UART4_BASE + b 98f +#endif +#ifdef CONFIG_DEBUG_OMAP4UART4 + mov \rp, #UART_OFFSET(OMAP4_UART4_BASE) + b 98f +#endif +#ifdef CONFIG_DEBUG_TI81XXUART1 + mov \rp, #UART_OFFSET(TI81XX_UART1_BASE) + b 98f +#endif +#ifdef CONFIG_DEBUG_TI81XXUART2 + mov \rp, #UART_OFFSET(TI81XX_UART2_BASE) + b 98f +#endif +#ifdef CONFIG_DEBUG_TI81XXUART3 + mov \rp, #UART_OFFSET(TI81XX_UART3_BASE) + b 98f +#endif +#ifdef CONFIG_DEBUG_AM33XXUART1 + ldr \rp, =AM33XX_UART1_BASE + and \rp, \rp, #0x00ffffff + b 97f +#endif +#ifdef CONFIG_DEBUG_ZOOM_UART + ldr \rp, =ZOOM_UART_BASE + str \rp, [\tmp, #0] @ omap_uart_phys + ldr \rp, =ZOOM_UART_VIRT + str \rp, [\tmp, #4] @ omap_uart_virt + mov \rp, #(UART_LSR << ZOOM_PORT_SHIFT) + str \rp, [\tmp, #8] @ omap_uart_lsr +#endif + b 10b + + /* AM33XX: Store both phys and virt address for the uart */ +97: add \rp, \rp, #0x44000000 @ phys base + str \rp, [\tmp, #0] @ omap_uart_phys + sub \rp, \rp, #0x44000000 @ phys base + add \rp, \rp, #0xf9000000 @ virt base + str \rp, [\tmp, #4] @ omap_uart_virt + mov \rp, #(UART_LSR << OMAP_PORT_SHIFT) + str \rp, [\tmp, #8] @ omap_uart_lsr + + b 10b + + /* Store both phys and virt address for the uart */ +98: add \rp, \rp, #0x48000000 @ phys base + str \rp, [\tmp, #0] @ omap_uart_phys + sub \rp, \rp, #0x48000000 @ phys base + add \rp, \rp, #0xfa000000 @ virt base + str \rp, [\tmp, #4] @ omap_uart_virt + mov \rp, #(UART_LSR << OMAP_PORT_SHIFT) + str \rp, [\tmp, #8] @ omap_uart_lsr + + b 10b + + .align +99: .word . + .word omap_uart_phys + .ltorg + +100: /* Pass the UART_LSR reg address */ + ldr \tmp, [\tmp, #8] @ omap_uart_lsr + add \rp, \rp, \tmp + add \rv, \rv, \tmp + .endm + + .macro senduart,rd,rx + orr \rd, \rd, \rx, lsl #24 @ preserve LSR reg offset + bic \rx, \rx, #0xff @ get base (THR) reg address + strb \rd, [\rx] @ send lower byte of rd + orr \rx, \rx, \rd, lsr #24 @ restore original rx (LSR) + bic \rd, \rd, #(0xff << 24) @ restore original rd + .endm + + .macro busyuart,rd,rx +1001: ldrb \rd, [\rx] @ rx contains UART_LSR address + and \rd, \rd, #(UART_LSR_TEMT | UART_LSR_THRE) + teq \rd, #(UART_LSR_TEMT | UART_LSR_THRE) + bne 1001b + .endm + + .macro waituart,rd,rx + .endm diff --git a/arch/arm/include/debug/vt8500.S b/arch/arm/include/debug/vt8500.S new file mode 100644 index 00000000000..0e0ca0869da --- /dev/null +++ b/arch/arm/include/debug/vt8500.S @@ -0,0 +1,37 @@ +/* + * Debugging macro include header + * + * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> + * Moved from arch/arm/mach-vt8500/include/mach/debug-macro.S + * Minor changes for readability. + * + * 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. + */ + +#define DEBUG_LL_PHYS_BASE 0xD8000000 +#define DEBUG_LL_VIRT_BASE 0xF8000000 +#define DEBUG_LL_UART_OFFSET 0x00200000 + +#if defined(CONFIG_DEBUG_VT8500_UART0) + .macro addruart, rp, rv, tmp + mov \rp, #DEBUG_LL_UART_OFFSET + orr \rv, \rp, #DEBUG_LL_VIRT_BASE + orr \rp, \rp, #DEBUG_LL_PHYS_BASE + .endm + + .macro senduart,rd,rx + strb \rd, [\rx, #0] + .endm + + .macro busyuart,rd,rx +1001: ldr \rd, [\rx, #0x1c] + ands \rd, \rd, #0x2 + bne 1001b + .endm + + .macro waituart,rd,rx + .endm + +#endif diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h index 3303ff5adbf..023bfeb367b 100644 --- a/arch/arm/include/uapi/asm/kvm.h +++ b/arch/arm/include/uapi/asm/kvm.h @@ -65,6 +65,22 @@ struct kvm_regs { #define KVM_ARM_TARGET_CORTEX_A15 0 #define KVM_ARM_NUM_TARGETS 1 +/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */ +#define KVM_ARM_DEVICE_TYPE_SHIFT 0 +#define KVM_ARM_DEVICE_TYPE_MASK (0xffff << KVM_ARM_DEVICE_TYPE_SHIFT) +#define KVM_ARM_DEVICE_ID_SHIFT 16 +#define KVM_ARM_DEVICE_ID_MASK (0xffff << KVM_ARM_DEVICE_ID_SHIFT) + +/* Supported device IDs */ +#define KVM_ARM_DEVICE_VGIC_V2 0 + +/* Supported VGIC address types */ +#define KVM_VGIC_V2_ADDR_TYPE_DIST 0 +#define KVM_VGIC_V2_ADDR_TYPE_CPU 1 + +#define KVM_VGIC_V2_DIST_SIZE 0x1000 +#define KVM_VGIC_V2_CPU_SIZE 0x2000 + #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */ struct kvm_vcpu_init { |