diff options
Diffstat (limited to 'arch')
540 files changed, 7741 insertions, 3016 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4792d2928fa..7bbb03558d2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -29,6 +29,7 @@ config ARM  	select HAVE_GENERIC_HARDIRQS  	select HAVE_SPARSE_IRQ  	select GENERIC_IRQ_SHOW +	select CPU_PM if (SUSPEND || CPU_IDLE)  	help  	  The ARM series is a line of low-power-consumption RISC chip designs  	  licensed by ARM Ltd and targeted at embedded applications and @@ -195,7 +196,8 @@ config VECTORS_BASE  	  The base address of exception vectors.  config ARM_PATCH_PHYS_VIRT -	bool "Patch physical to virtual translations at runtime" +	bool "Patch physical to virtual translations at runtime" if EMBEDDED +	default y  	depends on !XIP_KERNEL && MMU  	depends on !ARCH_REALVIEW || !SPARSEMEM  	help @@ -204,16 +206,25 @@ config ARM_PATCH_PHYS_VIRT  	  kernel in system memory.  	  This can only be used with non-XIP MMU kernels where the base -	  of physical memory is at a 16MB boundary, or theoretically 64K -	  for the MSM machine class. +	  of physical memory is at a 16MB boundary. -config ARM_PATCH_PHYS_VIRT_16BIT -	def_bool y -	depends on ARM_PATCH_PHYS_VIRT && ARCH_MSM +	  Only disable this option if you know that you do not require +	  this feature (eg, building a kernel for a single machine) and +	  you need to shrink the kernel to the minimal size. + +config NEED_MACH_MEMORY_H +	bool +	help +	  Select this when mach/memory.h is required to provide special +	  definitions for this platform.  The need for mach/memory.h should +	  be avoided when possible. + +config PHYS_OFFSET +	hex "Physical address of main memory" +	depends on !ARM_PATCH_PHYS_VIRT && !NEED_MACH_MEMORY_H  	help -	  This option extends the physical to virtual translation patching -	  to allow physical memory down to a theoretical minimum of 64K -	  boundaries. +	  Please provide the physical address corresponding to the +	  location of main memory in your system.  source "init/Kconfig" @@ -246,6 +257,7 @@ config ARCH_INTEGRATOR  	select GENERIC_CLOCKEVENTS  	select PLAT_VERSATILE  	select PLAT_VERSATILE_FPGA_IRQ +	select NEED_MACH_MEMORY_H  	help  	  Support for ARM's Integrator platform. @@ -261,6 +273,7 @@ config ARCH_REALVIEW  	select PLAT_VERSATILE_CLCD  	select ARM_TIMER_SP804  	select GPIO_PL061 if GPIOLIB +	select NEED_MACH_MEMORY_H  	help  	  This enables support for ARM Ltd RealView boards. @@ -301,7 +314,6 @@ config ARCH_AT91  	select ARCH_REQUIRE_GPIOLIB  	select HAVE_CLK  	select CLKDEV_LOOKUP -	select ARM_PATCH_PHYS_VIRT if MMU  	help  	  This enables support for systems based on the Atmel AT91RM9200,  	  AT91SAM9 and AT91CAP9 processors. @@ -322,6 +334,7 @@ config ARCH_CLPS711X  	bool "Cirrus Logic CLPS711x/EP721x-based"  	select CPU_ARM720T  	select ARCH_USES_GETTIMEOFFSET +	select NEED_MACH_MEMORY_H  	help  	  Support for Cirrus Logic 711x/721x based boards. @@ -362,6 +375,7 @@ config ARCH_EBSA110  	select ISA  	select NO_IOPORT  	select ARCH_USES_GETTIMEOFFSET +	select NEED_MACH_MEMORY_H  	help  	  This is an evaluation board for the StrongARM processor available  	  from Digital. It has limited hardware on-board, including an @@ -377,6 +391,7 @@ config ARCH_EP93XX  	select ARCH_REQUIRE_GPIOLIB  	select ARCH_HAS_HOLES_MEMORYMODEL  	select ARCH_USES_GETTIMEOFFSET +	select NEED_MEMORY_H  	help  	  This enables support for the Cirrus EP93xx series of CPUs. @@ -385,6 +400,7 @@ config ARCH_FOOTBRIDGE  	select CPU_SA110  	select FOOTBRIDGE  	select GENERIC_CLOCKEVENTS +	select NEED_MACH_MEMORY_H  	help  	  Support for systems based on the DC21285 companion chip  	  ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder. @@ -434,6 +450,7 @@ config ARCH_IOP13XX  	select PCI  	select ARCH_SUPPORTS_MSI  	select VMSPLIT_1G +	select NEED_MACH_MEMORY_H  	help  	  Support for Intel's IOP13XX (XScale) family of processors. @@ -464,6 +481,7 @@ config ARCH_IXP23XX  	select CPU_XSC3   	select PCI  	select ARCH_USES_GETTIMEOFFSET +	select NEED_MACH_MEMORY_H  	help  	  Support for Intel's IXP23xx (XScale) family of processors. @@ -473,6 +491,7 @@ config ARCH_IXP2000  	select CPU_XSCALE  	select PCI  	select ARCH_USES_GETTIMEOFFSET +	select NEED_MACH_MEMORY_H  	help  	  Support for Intel's IXP2400/2800 (XScale) family of processors. @@ -566,6 +585,7 @@ config ARCH_KS8695  	select CPU_ARM922T  	select ARCH_REQUIRE_GPIOLIB  	select ARCH_USES_GETTIMEOFFSET +	select NEED_MACH_MEMORY_H  	help  	  Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based  	  System-on-Chip devices. @@ -657,6 +677,7 @@ config ARCH_SHMOBILE  	select SPARSE_IRQ  	select MULTI_IRQ_HANDLER  	select PM_GENERIC_DOMAINS if PM +	select NEED_MACH_MEMORY_H  	help  	  Support for Renesas's SH-Mobile and R-Mobile ARM platforms. @@ -671,6 +692,7 @@ config ARCH_RPC  	select NO_IOPORT  	select ARCH_SPARSEMEM_ENABLE  	select ARCH_USES_GETTIMEOFFSET +	select NEED_MACH_MEMORY_H  	help  	  On the Acorn Risc-PC, Linux can support the internal IDE disk and  	  CD-ROM interface, serial and parallel port, and the floppy drive. @@ -689,6 +711,7 @@ config ARCH_SA1100  	select HAVE_SCHED_CLOCK  	select TICK_ONESHOT  	select ARCH_REQUIRE_GPIOLIB +	select NEED_MACH_MEMORY_H  	help  	  Support for StrongARM 11x0 based boards. @@ -781,6 +804,7 @@ config ARCH_S5PV210  	select HAVE_S3C2410_I2C if I2C  	select HAVE_S3C_RTC if RTC_CLASS  	select HAVE_S3C2410_WATCHDOG if WATCHDOG +	select NEED_MACH_MEMORY_H  	help  	  Samsung S5PV210/S5PC110 series based systems @@ -797,6 +821,7 @@ config ARCH_EXYNOS4  	select HAVE_S3C_RTC if RTC_CLASS  	select HAVE_S3C2410_I2C if I2C  	select HAVE_S3C2410_WATCHDOG if WATCHDOG +	select NEED_MACH_MEMORY_H  	help  	  Samsung EXYNOS4 series based systems @@ -808,6 +833,7 @@ config ARCH_SHARK  	select ZONE_DMA  	select PCI  	select ARCH_USES_GETTIMEOFFSET +	select NEED_MACH_MEMORY_H  	help  	  Support for the StrongARM based Digital DNARD machine, also known  	  as "Shark" (<http://www.shark-linux.de/shark.html>). @@ -836,6 +862,7 @@ config ARCH_U300  	select HAVE_MACH_CLKDEV  	select GENERIC_GPIO  	select ARCH_REQUIRE_GPIOLIB +	select NEED_MACH_MEMORY_H  	help  	  Support for ST-Ericsson U300 series mobile platforms. @@ -1408,6 +1435,31 @@ config SMP_ON_UP  	  If you don't know what to do here, say Y. +config ARM_CPU_TOPOLOGY +	bool "Support cpu topology definition" +	depends on SMP && CPU_V7 +	default y +	help +	  Support ARM cpu topology definition. The MPIDR register defines +	  affinity between processors which is then used to describe the cpu +	  topology of an ARM System. + +config SCHED_MC +	bool "Multi-core scheduler support" +	depends on ARM_CPU_TOPOLOGY +	help +	  Multi-core scheduler support improves the CPU scheduler's decision +	  making when dealing with multi-core CPU chips at a cost of slightly +	  increased overhead in some places. If unsure say N here. + +config SCHED_SMT +	bool "SMT scheduler support" +	depends on ARM_CPU_TOPOLOGY +	help +	  Improves the CPU scheduler's decision making when dealing with +	  MultiThreading at a cost of slightly increased overhead in some +	  places. If unsure say N here. +  config HAVE_ARM_SCU  	bool  	help @@ -1808,6 +1860,38 @@ config ZBOOT_ROM_SH_MOBILE_SDHI  endchoice +config ARM_APPENDED_DTB +	bool "Use appended device tree blob to zImage (EXPERIMENTAL)" +	depends on OF && !ZBOOT_ROM && EXPERIMENTAL +	help +	  With this option, the boot code will look for a device tree binary +	  (DTB) appended to zImage +	  (e.g. cat zImage <filename>.dtb > zImage_w_dtb). + +	  This is meant as a backward compatibility convenience for those +	  systems with a bootloader that can't be upgraded to accommodate +	  the documented boot protocol using a device tree. + +	  Beware that there is very little in terms of protection against +	  this option being confused by leftover garbage in memory that might +	  look like a DTB header after a reboot if no actual DTB is appended +	  to zImage.  Do not leave this option active in a production kernel +	  if you don't intend to always append a DTB.  Proper passing of the +	  location into r2 of a bootloader provided DTB is always preferable +	  to this option. + +config ARM_ATAG_DTB_COMPAT +	bool "Supplement the appended DTB with traditional ATAG information" +	depends on ARM_APPENDED_DTB +	help +	  Some old bootloaders can't be updated to a DTB capable one, yet +	  they provide ATAGs with memory configuration, the ramdisk address, +	  the kernel cmdline string, etc.  Such information is dynamically +	  provided by the bootloader and can't always be stored in a static +	  DTB.  To allow a device tree enabled kernel to be used with such +	  bootloaders, this option allows zImage to extract the information +	  from the ATAG list and store it at run time into the appended DTB. +  config CMDLINE  	string "Default kernel command string"  	default "" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index b3dc1fa3084..0887801c324 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -158,4 +158,10 @@ config DEBUG_S3C_UART  	  The uncompressor code port configuration is now handled  	  by CONFIG_S3C_LOWLEVEL_UART_PORT. +config ARM_KPROBES_TEST +	tristate "Kprobes test module" +	depends on KPROBES && MODULES +	help +	  Perform tests of kprobes API and instruction set simulation. +  endmenu diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 70c424eaf7b..5665c2a3b65 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -128,6 +128,9 @@ textofs-$(CONFIG_PM_H1940)      := 0x00108000  ifeq ($(CONFIG_ARCH_SA1100),y)  textofs-$(CONFIG_SA1111) := 0x00208000  endif +textofs-$(CONFIG_ARCH_MSM7X30) := 0x00208000 +textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000 +textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000  # Machine directory name.  This list is sorted alphanumerically  # by CONFIG_* macro name. diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore index c6028967d33..e0936a14851 100644 --- a/arch/arm/boot/compressed/.gitignore +++ b/arch/arm/boot/compressed/.gitignore @@ -5,3 +5,12 @@ piggy.lzo  piggy.lzma  vmlinux  vmlinux.lds + +# borrowed libfdt files +fdt.c +fdt.h +fdt_ro.c +fdt_rw.c +fdt_wip.c +libfdt.h +libfdt_internal.h diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 0c74a6fab95..e4f32a8e002 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -26,6 +26,10 @@ HEAD	= head.o  OBJS	+= misc.o decompress.o  FONTC	= $(srctree)/drivers/video/console/font_acorn_8x8.c +# string library code (-Os is enforced to keep it much smaller) +OBJS		+= string.o +CFLAGS_string.o	:= -Os +  #  # Architecture dependencies  # @@ -89,21 +93,41 @@ suffix_$(CONFIG_KERNEL_GZIP) = gzip  suffix_$(CONFIG_KERNEL_LZO)  = lzo  suffix_$(CONFIG_KERNEL_LZMA) = lzma +# Borrowed libfdt files for the ATAG compatibility mode + +libfdt		:= fdt_rw.c fdt_ro.c fdt_wip.c fdt.c +libfdt_hdrs	:= fdt.h libfdt.h libfdt_internal.h + +libfdt_objs	:= $(addsuffix .o, $(basename $(libfdt))) + +$(addprefix $(obj)/,$(libfdt) $(libfdt_hdrs)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/% +	$(call cmd,shipped) + +$(addprefix $(obj)/,$(libfdt_objs) atags_to_fdt.o): \ +	$(addprefix $(obj)/,$(libfdt_hdrs)) + +ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y) +OBJS	+= $(libfdt_objs) atags_to_fdt.o +endif +  targets       := vmlinux vmlinux.lds \  		 piggy.$(suffix_y) piggy.$(suffix_y).o \ -		 font.o font.c head.o misc.o $(OBJS) +		 lib1funcs.o lib1funcs.S font.o font.c head.o misc.o $(OBJS)  # Make sure files are removed during clean -extra-y       += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S +extra-y       += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S $(libfdt) $(libfdt_hdrs)  ifeq ($(CONFIG_FUNCTION_TRACER),y)  ORIG_CFLAGS := $(KBUILD_CFLAGS)  KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))  endif -ccflags-y := -fpic -fno-builtin +ccflags-y := -fpic -fno-builtin -I$(obj)  asflags-y := -Wa,-march=all +# Supply kernel BSS size to the decompressor via a linker symbol. +KBSS_SZ = $(shell size $(obj)/../../../../vmlinux | awk 'END{print $$3}') +LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)  # Supply ZRELADDR to the decompressor via a linker symbol.  ifneq ($(CONFIG_AUTO_ZRELADDR),y)  LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR) @@ -123,7 +147,7 @@ LDFLAGS_vmlinux += -T  # For __aeabi_uidivmod  lib1funcs = $(obj)/lib1funcs.o -$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE +$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S  	$(call cmd,shipped)  # We need to prevent any GOTOFF relocs being used with references diff --git a/arch/arm/boot/compressed/atags_to_fdt.c b/arch/arm/boot/compressed/atags_to_fdt.c new file mode 100644 index 00000000000..6ce11c48117 --- /dev/null +++ b/arch/arm/boot/compressed/atags_to_fdt.c @@ -0,0 +1,97 @@ +#include <asm/setup.h> +#include <libfdt.h> + +static int node_offset(void *fdt, const char *node_path) +{ +	int offset = fdt_path_offset(fdt, node_path); +	if (offset == -FDT_ERR_NOTFOUND) +		offset = fdt_add_subnode(fdt, 0, node_path); +	return offset; +} + +static int setprop(void *fdt, const char *node_path, const char *property, +		   uint32_t *val_array, int size) +{ +	int offset = node_offset(fdt, node_path); +	if (offset < 0) +		return offset; +	return fdt_setprop(fdt, offset, property, val_array, size); +} + +static int setprop_string(void *fdt, const char *node_path, +			  const char *property, const char *string) +{ +	int offset = node_offset(fdt, node_path); +	if (offset < 0) +		return offset; +	return fdt_setprop_string(fdt, offset, property, string); +} + +static int setprop_cell(void *fdt, const char *node_path, +			const char *property, uint32_t val) +{ +	int offset = node_offset(fdt, node_path); +	if (offset < 0) +		return offset; +	return fdt_setprop_cell(fdt, offset, property, val); +} + +/* + * Convert and fold provided ATAGs into the provided FDT. + * + * REturn values: + *    = 0 -> pretend success + *    = 1 -> bad ATAG (may retry with another possible ATAG pointer) + *    < 0 -> error from libfdt + */ +int atags_to_fdt(void *atag_list, void *fdt, int total_space) +{ +	struct tag *atag = atag_list; +	uint32_t mem_reg_property[2 * NR_BANKS]; +	int memcount = 0; +	int ret; + +	/* make sure we've got an aligned pointer */ +	if ((u32)atag_list & 0x3) +		return 1; + +	/* if we get a DTB here we're done already */ +	if (*(u32 *)atag_list == fdt32_to_cpu(FDT_MAGIC)) +	       return 0; + +	/* validate the ATAG */ +	if (atag->hdr.tag != ATAG_CORE || +	    (atag->hdr.size != tag_size(tag_core) && +	     atag->hdr.size != 2)) +		return 1; + +	/* let's give it all the room it could need */ +	ret = fdt_open_into(fdt, fdt, total_space); +	if (ret < 0) +		return ret; + +	for_each_tag(atag, atag_list) { +		if (atag->hdr.tag == ATAG_CMDLINE) { +			setprop_string(fdt, "/chosen", "bootargs", +					atag->u.cmdline.cmdline); +		} else if (atag->hdr.tag == ATAG_MEM) { +			if (memcount >= sizeof(mem_reg_property)/4) +				continue; +			mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start); +			mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size); +		} else if (atag->hdr.tag == ATAG_INITRD2) { +			uint32_t initrd_start, initrd_size; +			initrd_start = atag->u.initrd.start; +			initrd_size = atag->u.initrd.size; +			setprop_cell(fdt, "/chosen", "linux,initrd-start", +					initrd_start); +			setprop_cell(fdt, "/chosen", "linux,initrd-end", +					initrd_start + initrd_size); +		} +	} + +	if (memcount) +		setprop(fdt, "/memory", "reg", mem_reg_property, 4*memcount); + +	return fdt_pack(fdt); +} diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index e95a5989602..9f5ac11ccd8 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -216,6 +216,103 @@ restart:	adr	r0, LC0  		mov	r10, r6  #endif +		mov	r5, #0			@ init dtb size to 0 +#ifdef CONFIG_ARM_APPENDED_DTB +/* + *   r0  = delta + *   r2  = BSS start + *   r3  = BSS end + *   r4  = final kernel address + *   r5  = appended dtb size (still unknown) + *   r6  = _edata + *   r7  = architecture ID + *   r8  = atags/device tree pointer + *   r9  = size of decompressed image + *   r10 = end of this image, including  bss/stack/malloc space if non XIP + *   r11 = GOT start + *   r12 = GOT end + *   sp  = stack pointer + * + * if there are device trees (dtb) appended to zImage, advance r10 so that the + * dtb data will get relocated along with the kernel if necessary. + */ + +		ldr	lr, [r6, #0] +#ifndef __ARMEB__ +		ldr	r1, =0xedfe0dd0		@ sig is 0xd00dfeed big endian +#else +		ldr	r1, =0xd00dfeed +#endif +		cmp	lr, r1 +		bne	dtb_check_done		@ not found + +#ifdef CONFIG_ARM_ATAG_DTB_COMPAT +		/* +		 * OK... Let's do some funky business here. +		 * If we do have a DTB appended to zImage, and we do have +		 * an ATAG list around, we want the later to be translated +		 * and folded into the former here.  To be on the safe side, +		 * let's temporarily move  the stack away into the malloc +		 * area.  No GOT fixup has occurred yet, but none of the +		 * code we're about to call uses any global variable. +		*/ +		add	sp, sp, #0x10000 +		stmfd	sp!, {r0-r3, ip, lr} +		mov	r0, r8 +		mov	r1, r6 +		sub	r2, sp, r6 +		bl	atags_to_fdt + +		/* +		 * If returned value is 1, there is no ATAG at the location +		 * pointed by r8.  Try the typical 0x100 offset from start +		 * of RAM and hope for the best. +		 */ +		cmp	r0, #1 +		sub	r0, r4, #(TEXT_OFFSET - 0x100) +		mov	r1, r6 +		sub	r2, sp, r6 +		blne	atags_to_fdt + +		ldmfd	sp!, {r0-r3, ip, lr} +		sub	sp, sp, #0x10000 +#endif + +		mov	r8, r6			@ use the appended device tree + +		/* +		 * Make sure that the DTB doesn't end up in the final +		 * kernel's .bss area. To do so, we adjust the decompressed +		 * kernel size to compensate if that .bss size is larger +		 * than the relocated code. +		 */ +		ldr	r5, =_kernel_bss_size +		adr	r1, wont_overwrite +		sub	r1, r6, r1 +		subs	r1, r5, r1 +		addhi	r9, r9, r1 + +		/* Get the dtb's size */ +		ldr	r5, [r6, #4] +#ifndef __ARMEB__ +		/* convert r5 (dtb size) to little endian */ +		eor	r1, r5, r5, ror #16 +		bic	r1, r1, #0x00ff0000 +		mov	r5, r5, ror #8 +		eor	r5, r5, r1, lsr #8 +#endif + +		/* preserve 64-bit alignment */ +		add	r5, r5, #7 +		bic	r5, r5, #7 + +		/* relocate some pointers past the appended dtb */ +		add	r6, r6, r5 +		add	r10, r10, r5 +		add	sp, sp, r5 +dtb_check_done: +#endif +  /*   * Check to see if we will overwrite ourselves.   *   r4  = final kernel address @@ -223,15 +320,14 @@ restart:	adr	r0, LC0   *   r10 = end of this image, including  bss/stack/malloc space if non XIP   * We basically want:   *   r4 - 16k page directory >= r10 -> OK - *   r4 + image length <= current position (pc) -> OK + *   r4 + image length <= address of wont_overwrite -> OK   */  		add	r10, r10, #16384  		cmp	r4, r10  		bhs	wont_overwrite  		add	r10, r4, r9 -   ARM(		cmp	r10, pc		) - THUMB(		mov	lr, pc		) - THUMB(		cmp	r10, lr		) +		adr	r9, wont_overwrite +		cmp	r10, r9  		bls	wont_overwrite  /* @@ -285,14 +381,16 @@ wont_overwrite:   *   r2  = BSS start   *   r3  = BSS end   *   r4  = kernel execution address + *   r5  = appended dtb size (0 if not present)   *   r7  = architecture ID   *   r8  = atags pointer   *   r11 = GOT start   *   r12 = GOT end   *   sp  = stack pointer   */ -		teq	r0, #0 +		orrs	r1, r0, r5  		beq	not_relocated +  		add	r11, r11, r0  		add	r12, r12, r0 @@ -307,12 +405,21 @@ wont_overwrite:  		/*  		 * Relocate all entries in the GOT table. +		 * Bump bss entries to _edata + dtb size  		 */  1:		ldr	r1, [r11, #0]		@ relocate entries in the GOT -		add	r1, r1, r0		@ table.  This fixes up the -		str	r1, [r11], #4		@ C references. +		add	r1, r1, r0		@ This fixes up C references +		cmp	r1, r2			@ if entry >= bss_start && +		cmphs	r3, r1			@       bss_end > entry +		addhi	r1, r1, r5		@    entry += dtb size +		str	r1, [r11], #4		@ next entry  		cmp	r11, r12  		blo	1b + +		/* bump our bss pointers too */ +		add	r2, r2, r5 +		add	r3, r3, r5 +  #else  		/* diff --git a/arch/arm/boot/compressed/libfdt_env.h b/arch/arm/boot/compressed/libfdt_env.h new file mode 100644 index 00000000000..1f4e71876b0 --- /dev/null +++ b/arch/arm/boot/compressed/libfdt_env.h @@ -0,0 +1,15 @@ +#ifndef _ARM_LIBFDT_ENV_H +#define _ARM_LIBFDT_ENV_H + +#include <linux/types.h> +#include <linux/string.h> +#include <asm/byteorder.h> + +#define fdt16_to_cpu(x)		be16_to_cpu(x) +#define cpu_to_fdt16(x)		cpu_to_be16(x) +#define fdt32_to_cpu(x)		be32_to_cpu(x) +#define cpu_to_fdt32(x)		cpu_to_be32(x) +#define fdt64_to_cpu(x)		be64_to_cpu(x) +#define cpu_to_fdt64(x)		cpu_to_be64(x) + +#endif diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 832d37236c5..8e2a8fca5ed 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -18,14 +18,9 @@  unsigned int __machine_arch_type; -#define _LINUX_STRING_H_ -  #include <linux/compiler.h>	/* for inline */ -#include <linux/types.h>	/* for size_t */ -#include <linux/stddef.h>	/* for NULL */ +#include <linux/types.h>  #include <linux/linkage.h> -#include <asm/string.h> -  static void putstr(const char *ptr);  extern void error(char *x); @@ -101,41 +96,6 @@ static void putstr(const char *ptr)  	flush();  } - -void *memcpy(void *__dest, __const void *__src, size_t __n) -{ -	int i = 0; -	unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src; - -	for (i = __n >> 3; i > 0; i--) { -		*d++ = *s++; -		*d++ = *s++; -		*d++ = *s++; -		*d++ = *s++; -		*d++ = *s++; -		*d++ = *s++; -		*d++ = *s++; -		*d++ = *s++; -	} - -	if (__n & 1 << 2) { -		*d++ = *s++; -		*d++ = *s++; -		*d++ = *s++; -		*d++ = *s++; -	} - -	if (__n & 1 << 1) { -		*d++ = *s++; -		*d++ = *s++; -	} - -	if (__n & 1) -		*d++ = *s++; - -	return __dest; -} -  /*   * gzip declarations   */ diff --git a/arch/arm/boot/compressed/string.c b/arch/arm/boot/compressed/string.c new file mode 100644 index 00000000000..36e53ef9200 --- /dev/null +++ b/arch/arm/boot/compressed/string.c @@ -0,0 +1,127 @@ +/* + * arch/arm/boot/compressed/string.c + * + * Small subset of simple string routines + */ + +#include <linux/string.h> + +void *memcpy(void *__dest, __const void *__src, size_t __n) +{ +	int i = 0; +	unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src; + +	for (i = __n >> 3; i > 0; i--) { +		*d++ = *s++; +		*d++ = *s++; +		*d++ = *s++; +		*d++ = *s++; +		*d++ = *s++; +		*d++ = *s++; +		*d++ = *s++; +		*d++ = *s++; +	} + +	if (__n & 1 << 2) { +		*d++ = *s++; +		*d++ = *s++; +		*d++ = *s++; +		*d++ = *s++; +	} + +	if (__n & 1 << 1) { +		*d++ = *s++; +		*d++ = *s++; +	} + +	if (__n & 1) +		*d++ = *s++; + +	return __dest; +} + +void *memmove(void *__dest, __const void *__src, size_t count) +{ +	unsigned char *d = __dest; +	const unsigned char *s = __src; + +	if (__dest == __src) +		return __dest; + +	if (__dest < __src) +		return memcpy(__dest, __src, count); + +	while (count--) +		d[count] = s[count]; +	return __dest; +} + +size_t strlen(const char *s) +{ +	const char *sc = s; + +	while (*sc != '\0') +		sc++; +	return sc - s; +} + +int memcmp(const void *cs, const void *ct, size_t count) +{ +	const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count; +	int res = 0; + +	while (su1 < end) { +		res = *su1++ - *su2++; +		if (res) +			break; +	} +	return res; +} + +int strcmp(const char *cs, const char *ct) +{ +	unsigned char c1, c2; +	int res = 0; + +	do { +		c1 = *cs++; +		c2 = *ct++; +		res = c1 - c2; +		if (res) +			break; +	} while (c1); +	return res; +} + +void *memchr(const void *s, int c, size_t count) +{ +	const unsigned char *p = s; + +	while (count--) +		if ((unsigned char)c == *p++) +			return (void *)(p - 1); +	return NULL; +} + +char *strchr(const char *s, int c) +{ +	while (*s != (char)c) +		if (*s++ == '\0') +			return NULL; +	return (char *)s; +} + +#undef memset + +void *memset(void *s, int c, size_t count) +{ +	char *xs = s; +	while (count--) +		*xs++ = c; +	return s; +} + +void __memzero(void *s, size_t count) +{ +	memset(s, 0, count); +} diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in index 4e728834a1b..4919f2ac8b8 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.in +++ b/arch/arm/boot/compressed/vmlinux.lds.in @@ -51,6 +51,10 @@ SECTIONS    _got_start = .;    .got			: { *(.got) }    _got_end = .; + +  /* ensure the zImage file size is always a multiple of 64 bits */ +  /* (without a dummy byte, ld just ignores the empty section) */ +  .pad			: { BYTE(0); . = ALIGN(8); }    _edata = .;    . = BSS_START; diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 4b71766fb21..74df9ca2be3 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -1,4 +1,5 @@  config ARM_GIC +	select IRQ_DOMAIN  	bool  config ARM_VIC diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 3227ca952a1..9d77777076f 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -24,10 +24,20 @@   */  #include <linux/init.h>  #include <linux/kernel.h> +#include <linux/err.h> +#include <linux/export.h>  #include <linux/list.h>  #include <linux/smp.h> +#include <linux/cpu_pm.h>  #include <linux/cpumask.h>  #include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/irqdomain.h> +#include <linux/interrupt.h> +#include <linux/percpu.h> +#include <linux/slab.h>  #include <asm/irq.h>  #include <asm/mach/irq.h> @@ -71,8 +81,7 @@ static inline void __iomem *gic_cpu_base(struct irq_data *d)  static inline unsigned int gic_irq(struct irq_data *d)  { -	struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); -	return d->irq - gic_data->irq_offset; +	return d->hwirq;  }  /* @@ -80,7 +89,7 @@ static inline unsigned int gic_irq(struct irq_data *d)   */  static void gic_mask_irq(struct irq_data *d)  { -	u32 mask = 1 << (d->irq % 32); +	u32 mask = 1 << (gic_irq(d) % 32);  	spin_lock(&irq_controller_lock);  	writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4); @@ -91,7 +100,7 @@ static void gic_mask_irq(struct irq_data *d)  static void gic_unmask_irq(struct irq_data *d)  { -	u32 mask = 1 << (d->irq % 32); +	u32 mask = 1 << (gic_irq(d) % 32);  	spin_lock(&irq_controller_lock);  	if (gic_arch_extn.irq_unmask) @@ -172,7 +181,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,  			    bool force)  {  	void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); -	unsigned int shift = (d->irq % 4) * 8; +	unsigned int shift = (gic_irq(d) % 4) * 8;  	unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);  	u32 val, mask, bit; @@ -180,7 +189,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,  		return -EINVAL;  	mask = 0xff << shift; -	bit = 1 << (cpu + shift); +	bit = 1 << (cpu_logical_map(cpu) + shift);  	spin_lock(&irq_controller_lock);  	val = readl_relaxed(reg) & ~mask; @@ -223,7 +232,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)  	if (gic_irq == 1023)  		goto out; -	cascade_irq = gic_irq + chip_data->irq_offset; +	cascade_irq = irq_domain_to_irq(&chip_data->domain, gic_irq);  	if (unlikely(gic_irq < 32 || gic_irq > 1020 || cascade_irq >= NR_IRQS))  		do_bad_IRQ(cascade_irq, desc);  	else @@ -255,28 +264,26 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)  	irq_set_chained_handler(irq, gic_handle_cascade_irq);  } -static void __init gic_dist_init(struct gic_chip_data *gic, -	unsigned int irq_start) +static void __init gic_dist_init(struct gic_chip_data *gic)  { -	unsigned int gic_irqs, irq_limit, i; +	unsigned int i, irq; +	u32 cpumask; +	unsigned int gic_irqs = gic->gic_irqs; +	struct irq_domain *domain = &gic->domain;  	void __iomem *base = gic->dist_base; -	u32 cpumask = 1 << smp_processor_id(); +	u32 cpu = 0; +#ifdef CONFIG_SMP +	cpu = cpu_logical_map(smp_processor_id()); +#endif + +	cpumask = 1 << cpu;  	cpumask |= cpumask << 8;  	cpumask |= cpumask << 16;  	writel_relaxed(0, base + GIC_DIST_CTRL);  	/* -	 * Find out how many interrupts are supported. -	 * The GIC only supports up to 1020 interrupt sources. -	 */ -	gic_irqs = readl_relaxed(base + GIC_DIST_CTR) & 0x1f; -	gic_irqs = (gic_irqs + 1) * 32; -	if (gic_irqs > 1020) -		gic_irqs = 1020; - -	/*  	 * Set all global interrupts to be level triggered, active low.  	 */  	for (i = 32; i < gic_irqs; i += 16) @@ -302,19 +309,20 @@ static void __init gic_dist_init(struct gic_chip_data *gic,  		writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);  	/* -	 * Limit number of interrupts registered to the platform maximum -	 */ -	irq_limit = gic->irq_offset + gic_irqs; -	if (WARN_ON(irq_limit > NR_IRQS)) -		irq_limit = NR_IRQS; - -	/*  	 * Setup the Linux IRQ subsystem.  	 */ -	for (i = irq_start; i < irq_limit; i++) { -		irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq); -		irq_set_chip_data(i, gic); -		set_irq_flags(i, IRQF_VALID | IRQF_PROBE); +	irq_domain_for_each_irq(domain, i, irq) { +		if (i < 32) { +			irq_set_percpu_devid(irq); +			irq_set_chip_and_handler(irq, &gic_chip, +						 handle_percpu_devid_irq); +			set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); +		} else { +			irq_set_chip_and_handler(irq, &gic_chip, +						 handle_fasteoi_irq); +			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); +		} +		irq_set_chip_data(irq, gic);  	}  	writel_relaxed(1, base + GIC_DIST_CTRL); @@ -343,23 +351,270 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)  	writel_relaxed(1, base + GIC_CPU_CTRL);  } -void __init gic_init(unsigned int gic_nr, unsigned int irq_start, +#ifdef CONFIG_CPU_PM +/* + * Saves the GIC distributor registers during suspend or idle.  Must be called + * with interrupts disabled but before powering down the GIC.  After calling + * this function, no interrupts will be delivered by the GIC, and another + * platform-specific wakeup source must be enabled. + */ +static void gic_dist_save(unsigned int gic_nr) +{ +	unsigned int gic_irqs; +	void __iomem *dist_base; +	int i; + +	if (gic_nr >= MAX_GIC_NR) +		BUG(); + +	gic_irqs = gic_data[gic_nr].gic_irqs; +	dist_base = gic_data[gic_nr].dist_base; + +	if (!dist_base) +		return; + +	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++) +		gic_data[gic_nr].saved_spi_conf[i] = +			readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4); + +	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) +		gic_data[gic_nr].saved_spi_target[i] = +			readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4); + +	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) +		gic_data[gic_nr].saved_spi_enable[i] = +			readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); +} + +/* + * Restores the GIC distributor registers during resume or when coming out of + * idle.  Must be called before enabling interrupts.  If a level interrupt + * that occured while the GIC was suspended is still present, it will be + * handled normally, but any edge interrupts that occured will not be seen by + * the GIC and need to be handled by the platform-specific wakeup source. + */ +static void gic_dist_restore(unsigned int gic_nr) +{ +	unsigned int gic_irqs; +	unsigned int i; +	void __iomem *dist_base; + +	if (gic_nr >= MAX_GIC_NR) +		BUG(); + +	gic_irqs = gic_data[gic_nr].gic_irqs; +	dist_base = gic_data[gic_nr].dist_base; + +	if (!dist_base) +		return; + +	writel_relaxed(0, dist_base + GIC_DIST_CTRL); + +	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++) +		writel_relaxed(gic_data[gic_nr].saved_spi_conf[i], +			dist_base + GIC_DIST_CONFIG + i * 4); + +	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) +		writel_relaxed(0xa0a0a0a0, +			dist_base + GIC_DIST_PRI + i * 4); + +	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) +		writel_relaxed(gic_data[gic_nr].saved_spi_target[i], +			dist_base + GIC_DIST_TARGET + i * 4); + +	for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++) +		writel_relaxed(gic_data[gic_nr].saved_spi_enable[i], +			dist_base + GIC_DIST_ENABLE_SET + i * 4); + +	writel_relaxed(1, dist_base + GIC_DIST_CTRL); +} + +static void gic_cpu_save(unsigned int gic_nr) +{ +	int i; +	u32 *ptr; +	void __iomem *dist_base; +	void __iomem *cpu_base; + +	if (gic_nr >= MAX_GIC_NR) +		BUG(); + +	dist_base = gic_data[gic_nr].dist_base; +	cpu_base = gic_data[gic_nr].cpu_base; + +	if (!dist_base || !cpu_base) +		return; + +	ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable); +	for (i = 0; i < DIV_ROUND_UP(32, 32); i++) +		ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); + +	ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf); +	for (i = 0; i < DIV_ROUND_UP(32, 16); i++) +		ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4); + +} + +static void gic_cpu_restore(unsigned int gic_nr) +{ +	int i; +	u32 *ptr; +	void __iomem *dist_base; +	void __iomem *cpu_base; + +	if (gic_nr >= MAX_GIC_NR) +		BUG(); + +	dist_base = gic_data[gic_nr].dist_base; +	cpu_base = gic_data[gic_nr].cpu_base; + +	if (!dist_base || !cpu_base) +		return; + +	ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable); +	for (i = 0; i < DIV_ROUND_UP(32, 32); i++) +		writel_relaxed(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4); + +	ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf); +	for (i = 0; i < DIV_ROUND_UP(32, 16); i++) +		writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4); + +	for (i = 0; i < DIV_ROUND_UP(32, 4); i++) +		writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4); + +	writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK); +	writel_relaxed(1, cpu_base + GIC_CPU_CTRL); +} + +static int gic_notifier(struct notifier_block *self, unsigned long cmd,	void *v) +{ +	int i; + +	for (i = 0; i < MAX_GIC_NR; i++) { +		switch (cmd) { +		case CPU_PM_ENTER: +			gic_cpu_save(i); +			break; +		case CPU_PM_ENTER_FAILED: +		case CPU_PM_EXIT: +			gic_cpu_restore(i); +			break; +		case CPU_CLUSTER_PM_ENTER: +			gic_dist_save(i); +			break; +		case CPU_CLUSTER_PM_ENTER_FAILED: +		case CPU_CLUSTER_PM_EXIT: +			gic_dist_restore(i); +			break; +		} +	} + +	return NOTIFY_OK; +} + +static struct notifier_block gic_notifier_block = { +	.notifier_call = gic_notifier, +}; + +static void __init gic_pm_init(struct gic_chip_data *gic) +{ +	gic->saved_ppi_enable = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4, +		sizeof(u32)); +	BUG_ON(!gic->saved_ppi_enable); + +	gic->saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4, +		sizeof(u32)); +	BUG_ON(!gic->saved_ppi_conf); + +	cpu_pm_register_notifier(&gic_notifier_block); +} +#else +static void __init gic_pm_init(struct gic_chip_data *gic) +{ +} +#endif + +#ifdef CONFIG_OF +static int gic_irq_domain_dt_translate(struct irq_domain *d, +				       struct device_node *controller, +				       const u32 *intspec, unsigned int intsize, +				       unsigned long *out_hwirq, unsigned int *out_type) +{ +	if (d->of_node != controller) +		return -EINVAL; +	if (intsize < 3) +		return -EINVAL; + +	/* Get the interrupt number and add 16 to skip over SGIs */ +	*out_hwirq = intspec[1] + 16; + +	/* For SPIs, we need to add 16 more to get the GIC irq ID number */ +	if (!intspec[0]) +		*out_hwirq += 16; + +	*out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; +	return 0; +} +#endif + +const struct irq_domain_ops gic_irq_domain_ops = { +#ifdef CONFIG_OF +	.dt_translate = gic_irq_domain_dt_translate, +#endif +}; + +void __init gic_init(unsigned int gic_nr, int irq_start,  	void __iomem *dist_base, void __iomem *cpu_base)  {  	struct gic_chip_data *gic; +	struct irq_domain *domain; +	int gic_irqs;  	BUG_ON(gic_nr >= MAX_GIC_NR);  	gic = &gic_data[gic_nr]; +	domain = &gic->domain;  	gic->dist_base = dist_base;  	gic->cpu_base = cpu_base; -	gic->irq_offset = (irq_start - 1) & ~31; -	if (gic_nr == 0) +	/* +	 * For primary GICs, skip over SGIs. +	 * For secondary GICs, skip over PPIs, too. +	 */ +	if (gic_nr == 0) {  		gic_cpu_base_addr = cpu_base; +		domain->hwirq_base = 16; +		if (irq_start > 0) +			irq_start = (irq_start & ~31) + 16; +	} else +		domain->hwirq_base = 32; + +	/* +	 * Find out how many interrupts are supported. +	 * The GIC only supports up to 1020 interrupt sources. +	 */ +	gic_irqs = readl_relaxed(dist_base + GIC_DIST_CTR) & 0x1f; +	gic_irqs = (gic_irqs + 1) * 32; +	if (gic_irqs > 1020) +		gic_irqs = 1020; +	gic->gic_irqs = gic_irqs; -	gic_dist_init(gic, irq_start); +	domain->nr_irq = gic_irqs - domain->hwirq_base; +	domain->irq_base = irq_alloc_descs(irq_start, 16, domain->nr_irq, +					   numa_node_id()); +	if (IS_ERR_VALUE(domain->irq_base)) { +		WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n", +		     irq_start); +		domain->irq_base = irq_start; +	} +	domain->priv = gic; +	domain->ops = &gic_irq_domain_ops; +	irq_domain_add(domain); + +	gic_chip.flags |= gic_arch_extn.flags; +	gic_dist_init(gic);  	gic_cpu_init(gic); +	gic_pm_init(gic);  }  void __cpuinit gic_secondary_init(unsigned int gic_nr) @@ -369,20 +624,15 @@ void __cpuinit gic_secondary_init(unsigned int gic_nr)  	gic_cpu_init(&gic_data[gic_nr]);  } -void __cpuinit gic_enable_ppi(unsigned int irq) -{ -	unsigned long flags; - -	local_irq_save(flags); -	irq_set_status_flags(irq, IRQ_NOPROBE); -	gic_unmask_irq(irq_get_irq_data(irq)); -	local_irq_restore(flags); -} -  #ifdef CONFIG_SMP  void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)  { -	unsigned long map = *cpus_addr(*mask); +	int cpu; +	unsigned long map = 0; + +	/* Convert our logical CPU mask into a physical one. */ +	for_each_cpu(cpu, mask) +		map |= 1 << cpu_logical_map(cpu);  	/*  	 * Ensure that stores to Normal memory are visible to the @@ -394,3 +644,35 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)  	writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);  }  #endif + +#ifdef CONFIG_OF +static int gic_cnt __initdata = 0; + +int __init gic_of_init(struct device_node *node, struct device_node *parent) +{ +	void __iomem *cpu_base; +	void __iomem *dist_base; +	int irq; +	struct irq_domain *domain = &gic_data[gic_cnt].domain; + +	if (WARN_ON(!node)) +		return -ENODEV; + +	dist_base = of_iomap(node, 0); +	WARN(!dist_base, "unable to map gic dist registers\n"); + +	cpu_base = of_iomap(node, 1); +	WARN(!cpu_base, "unable to map gic cpu registers\n"); + +	domain->of_node = of_node_get(node); + +	gic_init(gic_cnt, -1, dist_base, cpu_base); + +	if (parent) { +		irq = irq_of_parse_and_map(node, 0); +		gic_cascade_irq(gic_cnt, irq); +	} +	gic_cnt++; +	return 0; +} +#endif diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index cd4458f6417..cb47d28cbe1 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -8,6 +8,7 @@  #define CPUID_CACHETYPE	1  #define CPUID_TCM	2  #define CPUID_TLBTYPE	3 +#define CPUID_MPIDR	5  #define CPUID_EXT_PFR0	"c1, 0"  #define CPUID_EXT_PFR1	"c1, 1" @@ -70,6 +71,11 @@ static inline unsigned int __attribute_const__ read_cpuid_tcmstatus(void)  	return read_cpuid(CPUID_TCM);  } +static inline unsigned int __attribute_const__ read_cpuid_mpidr(void) +{ +	return read_cpuid(CPUID_MPIDR); +} +  /*   * Intel's XScale3 core supports some v6 features (supersections, L2)   * but advertises itself as v5 as it does not support the v6 ISA.  For diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 7a21d0bf713..7f27fab9d40 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -205,6 +205,13 @@ extern void *dma_alloc_writecombine(struct device *, size_t, dma_addr_t *,  int dma_mmap_writecombine(struct device *, struct vm_area_struct *,  		void *, dma_addr_t, size_t); +/* + * This can be called during boot to increase the size of the consistent + * DMA region above it's default value of 2MB. It must be called before the + * memory allocator is initialised, i.e. before any core_initcall. + */ +extern void __init init_consistent_dma_size(unsigned long size); +  #ifdef CONFIG_DMABOUNCE  /* diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S index 2f1e2098dfe..88d61815f0c 100644 --- a/arch/arm/include/asm/entry-macro-multi.S +++ b/arch/arm/include/asm/entry-macro-multi.S @@ -25,13 +25,6 @@  	movne	r1, sp  	adrne	lr, BSYM(1b)  	bne	do_IPI - -#ifdef CONFIG_LOCAL_TIMERS -	test_for_ltirq r0, r2, r6, lr -	movne	r0, sp -	adrne	lr, BSYM(1b) -	bne	do_local_timer -#endif  #endif  9997:  	.endm diff --git a/arch/arm/include/asm/exception.h b/arch/arm/include/asm/exception.h new file mode 100644 index 00000000000..5abaf5bbd98 --- /dev/null +++ b/arch/arm/include/asm/exception.h @@ -0,0 +1,19 @@ +/* + * Annotations for marking C functions as exception handlers. + * + * These should only be used for C functions that are called from the low + * level exception entry code and not any intervening C code. + */ +#ifndef __ASM_ARM_EXCEPTION_H +#define __ASM_ARM_EXCEPTION_H + +#include <linux/ftrace.h> + +#define __exception	__attribute__((section(".exception.text"))) +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +#define __exception_irq_entry	__irq_entry +#else +#define __exception_irq_entry	__exception +#endif + +#endif /* __ASM_ARM_EXCEPTION_H */ diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h index 89ad1805e57..ddf07a92a6c 100644 --- a/arch/arm/include/asm/hardirq.h +++ b/arch/arm/include/asm/hardirq.h @@ -9,9 +9,6 @@  typedef struct {  	unsigned int __softirq_pending; -#ifdef CONFIG_LOCAL_TIMERS -	unsigned int local_timer_irqs; -#endif  #ifdef CONFIG_SMP  	unsigned int ipi_irqs[NR_IPI];  #endif diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S index c115b82fe80..74ebc803904 100644 --- a/arch/arm/include/asm/hardware/entry-macro-gic.S +++ b/arch/arm/include/asm/hardware/entry-macro-gic.S @@ -22,15 +22,11 @@   * interrupt controller spec.  To wit:   *   * Interrupts 0-15 are IPI - * 16-28 are reserved - * 29-31 are local.  We allow 30 to be used for the watchdog. + * 16-31 are local.  We allow 30 to be used for the watchdog.   * 32-1020 are global   * 1021-1022 are reserved   * 1023 is "spurious" (no interrupt)   * - * For now, we ignore all local interrupts so only return an interrupt if it's - * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs. - *   * A simple read from the controller will tell us the number of the highest   * priority enabled interrupt.  We then just need to check whether it is in the   * valid range for an IRQ (30-1020 inclusive). @@ -43,7 +39,7 @@  	ldr	\tmp, =1021  	bic     \irqnr, \irqstat, #0x1c00 -	cmp     \irqnr, #29 +	cmp     \irqnr, #15  	cmpcc	\irqnr, \irqnr  	cmpne	\irqnr, \tmp  	cmpcs	\irqnr, \irqnr @@ -62,14 +58,3 @@  	strcc	\irqstat, [\base, #GIC_CPU_EOI]  	cmpcs	\irqnr, \irqnr  	.endm - -/* As above, this assumes that irqstat and base are preserved.. */ - -	.macro test_for_ltirq, irqnr, irqstat, base, tmp -	bic	\irqnr, \irqstat, #0x1c00 -	mov 	\tmp, #0 -	cmp	\irqnr, #29 -	moveq	\tmp, #1 -	streq	\irqstat, [\base, #GIC_CPU_EOI] -	cmp	\tmp, #0 -	.endm diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h index 435d3f86c70..3e91f22046f 100644 --- a/arch/arm/include/asm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -33,19 +33,32 @@  #define GIC_DIST_SOFTINT		0xf00  #ifndef __ASSEMBLY__ +#include <linux/irqdomain.h> +struct device_node; +  extern void __iomem *gic_cpu_base_addr;  extern struct irq_chip gic_arch_extn; -void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *); +void gic_init(unsigned int, int, void __iomem *, void __iomem *); +int gic_of_init(struct device_node *node, struct device_node *parent);  void gic_secondary_init(unsigned int);  void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);  void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); -void gic_enable_ppi(unsigned int);  struct gic_chip_data { -	unsigned int irq_offset;  	void __iomem *dist_base;  	void __iomem *cpu_base; +#ifdef CONFIG_CPU_PM +	u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)]; +	u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)]; +	u32 saved_spi_target[DIV_ROUND_UP(1020, 4)]; +	u32 __percpu *saved_ppi_enable; +	u32 __percpu *saved_ppi_conf; +#endif +#ifdef CONFIG_IRQ_DOMAIN +	struct irq_domain domain; +#endif +	unsigned int gic_irqs;  };  #endif diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h index f389b2704d8..c190bc992f0 100644 --- a/arch/arm/include/asm/hw_breakpoint.h +++ b/arch/arm/include/asm/hw_breakpoint.h @@ -50,6 +50,7 @@ static inline void decode_ctrl_reg(u32 reg,  #define ARM_DEBUG_ARCH_V6_1	2  #define ARM_DEBUG_ARCH_V7_ECP14	3  #define ARM_DEBUG_ARCH_V7_MM	4 +#define ARM_DEBUG_ARCH_V7_1	5  /* Breakpoint */  #define ARM_BREAKPOINT_EXECUTE	0 @@ -57,6 +58,7 @@ static inline void decode_ctrl_reg(u32 reg,  /* Watchpoints */  #define ARM_BREAKPOINT_LOAD	1  #define ARM_BREAKPOINT_STORE	2 +#define ARM_FSR_ACCESS_MASK	(1 << 11)  /* Privilege Levels */  #define ARM_BREAKPOINT_PRIV	1 diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h index 080d74f8128..f5e1cec7e35 100644 --- a/arch/arm/include/asm/localtimer.h +++ b/arch/arm/include/asm/localtimer.h @@ -10,6 +10,8 @@  #ifndef __ASM_ARM_LOCALTIMER_H  #define __ASM_ARM_LOCALTIMER_H +#include <linux/interrupt.h> +  struct clock_event_device;  /* @@ -17,27 +19,20 @@ struct clock_event_device;   */  void percpu_timer_setup(void); -/* - * Called from assembly, this is the local timer IRQ handler - */ -asmlinkage void do_local_timer(struct pt_regs *); - -  #ifdef CONFIG_LOCAL_TIMERS  #ifdef CONFIG_HAVE_ARM_TWD  #include "smp_twd.h" -#define local_timer_ack()	twd_timer_ack() +#define local_timer_stop(c)	twd_timer_stop((c))  #else  /* - * Platform provides this to acknowledge a local timer IRQ. - * Returns true if the local timer IRQ is to be processed. + * Stop the local timer   */ -int local_timer_ack(void); +void local_timer_stop(struct clock_event_device *);  #endif @@ -52,6 +47,10 @@ static inline int local_timer_setup(struct clock_event_device *evt)  {  	return -ENXIO;  } + +static inline void local_timer_stop(struct clock_event_device *evt) +{ +}  #endif  #endif diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index 217aa1911dd..727da118bcc 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -17,7 +17,7 @@ struct sys_timer;  struct machine_desc {  	unsigned int		nr;		/* architecture number	*/  	const char		*name;		/* architecture name	*/ -	unsigned long		boot_params;	/* tagged list		*/ +	unsigned long		atag_offset;	/* tagged list (relative) */  	const char		**dt_compat;	/* array of device tree  						 * 'compatible' strings	*/ diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h index d2fedb5aeb1..b36f3654bf5 100644 --- a/arch/arm/include/asm/mach/map.h +++ b/arch/arm/include/asm/mach/map.h @@ -29,6 +29,7 @@ struct map_desc {  #define MT_MEMORY_NONCACHED	11  #define MT_MEMORY_DTCM		12  #define MT_MEMORY_ITCM		13 +#define MT_MEMORY_SO		14  #ifdef CONFIG_MMU  extern void iotable_init(struct map_desc *, int); diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index b8de516e600..a8997d71084 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -16,9 +16,12 @@  #include <linux/compiler.h>  #include <linux/const.h>  #include <linux/types.h> -#include <mach/memory.h>  #include <asm/sizes.h> +#ifdef CONFIG_NEED_MACH_MEMORY_H +#include <mach/memory.h> +#endif +  /*   * Allow for constants defined here to be used from assembly code   * by prepending the UL suffix only with actual C code compilation. @@ -77,16 +80,7 @@   */  #define IOREMAP_MAX_ORDER	24 -/* - * Size of DMA-consistent memory region.  Must be multiple of 2M, - * between 2MB and 14MB inclusive. - */ -#ifndef CONSISTENT_DMA_SIZE -#define CONSISTENT_DMA_SIZE 	SZ_2M -#endif -  #define CONSISTENT_END		(0xffe00000UL) -#define CONSISTENT_BASE		(CONSISTENT_END - CONSISTENT_DMA_SIZE)  #else /* CONFIG_MMU */ @@ -160,7 +154,6 @@   * so that all we need to do is modify the 8-bit constant field.   */  #define __PV_BITS_31_24	0x81000000 -#define __PV_BITS_23_16	0x00810000  extern unsigned long __pv_phys_offset;  #define PHYS_OFFSET __pv_phys_offset @@ -178,9 +171,6 @@ static inline unsigned long __virt_to_phys(unsigned long x)  {  	unsigned long t;  	__pv_stub(x, t, "add", __PV_BITS_31_24); -#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT -	__pv_stub(t, t, "add", __PV_BITS_23_16); -#endif  	return t;  } @@ -188,9 +178,6 @@ static inline unsigned long __phys_to_virt(unsigned long x)  {  	unsigned long t;  	__pv_stub(x, t, "sub", __PV_BITS_31_24); -#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT -	__pv_stub(t, t, "sub", __PV_BITS_23_16); -#endif  	return t;  }  #else @@ -200,7 +187,11 @@ static inline unsigned long __phys_to_virt(unsigned long x)  #endif  #ifndef PHYS_OFFSET +#ifdef PLAT_PHYS_OFFSET  #define PHYS_OFFSET	PLAT_PHYS_OFFSET +#else +#define PHYS_OFFSET	UL(CONFIG_PHYS_OFFSET) +#endif  #endif  /* diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h index 543b44916d2..6c6809f982f 100644 --- a/arch/arm/include/asm/module.h +++ b/arch/arm/include/asm/module.h @@ -31,11 +31,7 @@ struct mod_arch_specific {  /* Add __virt_to_phys patching state as well */  #ifdef CONFIG_ARM_PATCH_PHYS_VIRT -#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT -#define MODULE_ARCH_VERMAGIC_P2V "p2v16 " -#else  #define MODULE_ARCH_VERMAGIC_P2V "p2v8 " -#endif  #else  #define MODULE_ARCH_VERMAGIC_P2V ""  #endif diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 5750704e027..f1956b27ae5 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -232,6 +232,9 @@ extern pgprot_t		pgprot_kernel;  #define pgprot_writecombine(prot) \  	__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE) +#define pgprot_stronglyordered(prot) \ +	__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED) +  #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE  #define pgprot_dmacoherent(prot) \  	__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE | L_PTE_XN) diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index b7e82c4aced..71d99b83cdb 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h @@ -13,7 +13,12 @@  #define __ARM_PMU_H__  #include <linux/interrupt.h> +#include <linux/perf_event.h> +/* + * Types of PMUs that can be accessed directly and require mutual + * exclusion between profiling tools. + */  enum arm_pmu_type {  	ARM_PMU_DEVICE_CPU	= 0,  	ARM_NUM_PMU_DEVICES, @@ -37,21 +42,17 @@ struct arm_pmu_platdata {   * reserve_pmu() - reserve the hardware performance counters   *   * Reserve the hardware performance counters in the system for exclusive use. - * The platform_device for the system is returned on success, ERR_PTR() - * encoded error on failure. + * Returns 0 on success or -EBUSY if the lock is already held.   */ -extern struct platform_device * +extern int  reserve_pmu(enum arm_pmu_type type);  /**   * release_pmu() - Relinquish control of the performance counters   *   * Release the performance counters and allow someone else to use them. - * Callers must have disabled the counters and released IRQs before calling - * this. The platform_device returned from reserve_pmu() must be passed as - * a cookie.   */ -extern int +extern void  release_pmu(enum arm_pmu_type type);  /** @@ -68,24 +69,78 @@ init_pmu(enum arm_pmu_type type);  #include <linux/err.h> -static inline struct platform_device * -reserve_pmu(enum arm_pmu_type type) -{ -	return ERR_PTR(-ENODEV); -} -  static inline int -release_pmu(enum arm_pmu_type type) +reserve_pmu(enum arm_pmu_type type)  {  	return -ENODEV;  } -static inline int -init_pmu(enum arm_pmu_type type) -{ -	return -ENODEV; -} +static inline void +release_pmu(enum arm_pmu_type type)	{ }  #endif /* CONFIG_CPU_HAS_PMU */ +#ifdef CONFIG_HW_PERF_EVENTS + +/* The events for a given PMU register set. */ +struct pmu_hw_events { +	/* +	 * The events that are active on the PMU for the given index. +	 */ +	struct perf_event	**events; + +	/* +	 * A 1 bit for an index indicates that the counter is being used for +	 * an event. A 0 means that the counter can be used. +	 */ +	unsigned long           *used_mask; + +	/* +	 * Hardware lock to serialize accesses to PMU registers. Needed for the +	 * read/modify/write sequences. +	 */ +	raw_spinlock_t		pmu_lock; +}; + +struct arm_pmu { +	struct pmu	pmu; +	enum arm_perf_pmu_ids id; +	enum arm_pmu_type type; +	cpumask_t	active_irqs; +	const char	*name; +	irqreturn_t	(*handle_irq)(int irq_num, void *dev); +	void		(*enable)(struct hw_perf_event *evt, int idx); +	void		(*disable)(struct hw_perf_event *evt, int idx); +	int		(*get_event_idx)(struct pmu_hw_events *hw_events, +					 struct hw_perf_event *hwc); +	int		(*set_event_filter)(struct hw_perf_event *evt, +					    struct perf_event_attr *attr); +	u32		(*read_counter)(int idx); +	void		(*write_counter)(int idx, u32 val); +	void		(*start)(void); +	void		(*stop)(void); +	void		(*reset)(void *); +	int		(*map_event)(struct perf_event *event); +	int		num_events; +	atomic_t	active_events; +	struct mutex	reserve_mutex; +	u64		max_period; +	struct platform_device	*plat_device; +	struct pmu_hw_events	*(*get_hw_events)(void); +}; + +#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu)) + +int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type); + +u64 armpmu_event_update(struct perf_event *event, +			struct hw_perf_event *hwc, +			int idx, int overflow); + +int armpmu_event_set_period(struct perf_event *event, +			    struct hw_perf_event *hwc, +			    int idx); + +#endif /* CONFIG_HW_PERF_EVENTS */ +  #endif /* __ARM_PMU_H__ */ diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h index 633d1cb84d8..9e92cb205e6 100644 --- a/arch/arm/include/asm/proc-fns.h +++ b/arch/arm/include/asm/proc-fns.h @@ -81,6 +81,10 @@ extern void cpu_dcache_clean_area(void *, int);  extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);  extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);  extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); + +/* These three are private to arch/arm/kernel/suspend.c */ +extern void cpu_do_suspend(void *); +extern void cpu_do_resume(void *);  #else  #define cpu_proc_init			processor._proc_init  #define cpu_proc_fin			processor._proc_fin @@ -89,6 +93,10 @@ extern void cpu_reset(unsigned long addr) __attribute__((noreturn));  #define cpu_dcache_clean_area		processor.dcache_clean_area  #define cpu_set_pte_ext			processor.set_pte_ext  #define cpu_do_switch_mm		processor.switch_mm + +/* These three are private to arch/arm/kernel/suspend.c */ +#define cpu_do_suspend			processor.do_suspend +#define cpu_do_resume			processor.do_resume  #endif  extern void cpu_resume(void); diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index e42d96a45d3..1e5717afc4a 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h @@ -33,6 +33,11 @@ extern void show_ipi_list(struct seq_file *, int);  asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);  /* + * Called from C code, this handles an IPI. + */ +void handle_IPI(int ipinr, struct pt_regs *regs); + +/*   * Setup the set of possible CPUs (via set_cpu_possible)   */  extern void smp_init_cpus(void); @@ -66,6 +71,12 @@ extern void platform_secondary_init(unsigned int cpu);  extern void platform_smp_prepare_cpus(unsigned int);  /* + * Logical CPU mapping. + */ +extern int __cpu_logical_map[NR_CPUS]; +#define cpu_logical_map(cpu)	__cpu_logical_map[cpu] + +/*   * Initial data for bringing up a secondary CPU.   */  struct secondary_data { @@ -88,9 +99,4 @@ extern void platform_cpu_enable(unsigned int cpu);  extern void arch_send_call_function_single_ipi(int cpu);  extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); -/* - * show local interrupt info - */ -extern void show_local_irqs(struct seq_file *, int); -  #endif /* ifndef __ASM_ARM_SMP_H */ diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h index fed9981fba0..ef9ffba97ad 100644 --- a/arch/arm/include/asm/smp_twd.h +++ b/arch/arm/include/asm/smp_twd.h @@ -22,7 +22,7 @@ struct clock_event_device;  extern void __iomem *twd_base; -int twd_timer_ack(void);  void twd_timer_setup(struct clock_event_device *); +void twd_timer_stop(struct clock_event_device *);  #endif diff --git a/arch/arm/include/asm/suspend.h b/arch/arm/include/asm/suspend.h index b0e4e1a0231..1c0a551ae37 100644 --- a/arch/arm/include/asm/suspend.h +++ b/arch/arm/include/asm/suspend.h @@ -1,22 +1,7 @@  #ifndef __ASM_ARM_SUSPEND_H  #define __ASM_ARM_SUSPEND_H -#include <asm/memory.h> -#include <asm/tlbflush.h> -  extern void cpu_resume(void); - -/* - * Hide the first two arguments to __cpu_suspend - these are an implementation - * detail which platform code shouldn't have to know about. - */ -static inline int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) -{ -	extern int __cpu_suspend(int, long, unsigned long, -				 int (*)(unsigned long)); -	int ret = __cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, arg, fn); -	flush_tlb_all(); -	return ret; -} +extern int cpu_suspend(unsigned long, int (*)(unsigned long));  #endif diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 832888d0c20..ed6b0499a10 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -62,13 +62,6 @@  #include <asm/outercache.h> -#define __exception	__attribute__((section(".exception.text"))) -#ifdef CONFIG_FUNCTION_GRAPH_TRACER -#define __exception_irq_entry	__irq_entry -#else -#define __exception_irq_entry	__exception -#endif -  struct thread_info;  struct task_struct; diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h index accbd7cad9b..a7e457ed27c 100644 --- a/arch/arm/include/asm/topology.h +++ b/arch/arm/include/asm/topology.h @@ -1,6 +1,39 @@  #ifndef _ASM_ARM_TOPOLOGY_H  #define _ASM_ARM_TOPOLOGY_H +#ifdef CONFIG_ARM_CPU_TOPOLOGY + +#include <linux/cpumask.h> + +struct cputopo_arm { +	int thread_id; +	int core_id; +	int socket_id; +	cpumask_t thread_sibling; +	cpumask_t core_sibling; +}; + +extern struct cputopo_arm cpu_topology[NR_CPUS]; + +#define topology_physical_package_id(cpu)	(cpu_topology[cpu].socket_id) +#define topology_core_id(cpu)		(cpu_topology[cpu].core_id) +#define topology_core_cpumask(cpu)	(&cpu_topology[cpu].core_sibling) +#define topology_thread_cpumask(cpu)	(&cpu_topology[cpu].thread_sibling) + +#define mc_capable()	(cpu_topology[0].socket_id != -1) +#define smt_capable()	(cpu_topology[0].thread_id != -1) + +void init_cpu_topology(void); +void store_cpu_topology(unsigned int cpuid); +const struct cpumask *cpu_coregroup_mask(unsigned int cpu); + +#else + +static inline void init_cpu_topology(void) { } +static inline void store_cpu_topology(unsigned int cpuid) { } + +#endif +  #include <asm-generic/topology.h>  #endif /* _ASM_ARM_TOPOLOGY_H */ diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index f7887dc53c1..7cac26c5f50 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -29,7 +29,7 @@ obj-$(CONFIG_MODULES)		+= armksyms.o module.o  obj-$(CONFIG_ARTHUR)		+= arthur.o  obj-$(CONFIG_ISA_DMA)		+= dma-isa.o  obj-$(CONFIG_PCI)		+= bios32.o isa.o -obj-$(CONFIG_PM_SLEEP)		+= sleep.o +obj-$(CONFIG_PM_SLEEP)		+= sleep.o suspend.o  obj-$(CONFIG_HAVE_SCHED_CLOCK)	+= sched_clock.o  obj-$(CONFIG_SMP)		+= smp.o smp_tlb.o  obj-$(CONFIG_HAVE_ARM_SCU)	+= smp_scu.o @@ -43,6 +43,13 @@ obj-$(CONFIG_KPROBES)		+= kprobes-thumb.o  else  obj-$(CONFIG_KPROBES)		+= kprobes-arm.o  endif +obj-$(CONFIG_ARM_KPROBES_TEST)	+= test-kprobes.o +test-kprobes-objs		:= kprobes-test.o +ifdef CONFIG_THUMB2_KERNEL +test-kprobes-objs		+= kprobes-test-thumb.o +else +test-kprobes-objs		+= kprobes-test-arm.o +endif  obj-$(CONFIG_ATAGS_PROC)	+= atags.o  obj-$(CONFIG_OABI_COMPAT)	+= sys_oabi-compat.o  obj-$(CONFIG_ARM_THUMBEE)	+= thumbee.o @@ -66,6 +73,7 @@ obj-$(CONFIG_IWMMXT)		+= iwmmxt.o  obj-$(CONFIG_CPU_HAS_PMU)	+= pmu.o  obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event.o  AFLAGS_iwmmxt.o			:= -Wa,-mcpu=iwmmxt +obj-$(CONFIG_ARM_CPU_TOPOLOGY)  += topology.o  ifneq ($(CONFIG_ARCH_EBSA110),y)    obj-y		+= io.o diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index bcd66e00bdb..b7685f1bb04 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -22,7 +22,7 @@  #if defined(CONFIG_DEBUG_ICEDCC)  		@@ debug using ARM EmbeddedICE DCC channel -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		.endm  #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7) @@ -106,7 +106,7 @@  #ifdef CONFIG_MMU  		.macro	addruart_current, rx, tmp1, tmp2 -		addruart	\tmp1, \tmp2 +		addruart	\tmp1, \tmp2, \rx  		mrc		p15, 0, \rx, c1, c0  		tst		\rx, #1  		moveq		\rx, \tmp1 diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 742b6108a00..673c806cc10 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -95,7 +95,7 @@ ENTRY(stext)  	sub	r4, r3, r4			@ (PHYS_OFFSET - PAGE_OFFSET)  	add	r8, r8, r4			@ PHYS_OFFSET  #else -	ldr	r8, =PLAT_PHYS_OFFSET +	ldr	r8, =PHYS_OFFSET		@ always constant in this case  #endif  	/* @@ -234,7 +234,7 @@ __create_page_tables:  	 * This allows debug messages to be output  	 * via a serial console before paging_init.  	 */ -	addruart r7, r3 +	addruart r7, r3, r0  	mov	r3, r3, lsr #20  	mov	r3, r3, lsl #2 @@ -488,13 +488,8 @@ __fixup_pv_table:  	add	r5, r5, r3	@ adjust table end address  	add	r7, r7, r3	@ adjust __pv_phys_offset address  	str	r8, [r7]	@ save computed PHYS_OFFSET to __pv_phys_offset -#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT  	mov	r6, r3, lsr #24	@ constant for add/sub instructions  	teq	r3, r6, lsl #24 @ must be 16MiB aligned -#else -	mov	r6, r3, lsr #16	@ constant for add/sub instructions -	teq	r3, r6, lsl #16	@ must be 64kiB aligned -#endif  THUMB(	it	ne		@ cross section branch )  	bne	__error  	str	r6, [r7, #4]	@ save to __pv_offset @@ -510,20 +505,8 @@ ENDPROC(__fixup_pv_table)  	.text  __fixup_a_pv_table:  #ifdef CONFIG_THUMB2_KERNEL -#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT -	lsls	r0, r6, #24 -	lsr	r6, #8 -	beq	1f -	clz	r7, r0 -	lsr	r0, #24 -	lsl	r0, r7 -	bic	r0, 0x0080 -	lsrs	r7, #1 -	orrcs   r0, #0x0080 -	orr	r0, r0, r7, lsl #12 -#endif -1:	lsls	r6, #24 -	beq	4f +	lsls	r6, #24 +	beq	2f  	clz	r7, r6  	lsr	r6, #24  	lsl	r6, r7 @@ -532,43 +515,25 @@ __fixup_a_pv_table:  	orrcs	r6, #0x0080  	orr	r6, r6, r7, lsl #12  	orr	r6, #0x4000 -	b	4f -2:	@ at this point the C flag is always clear -	add     r7, r3 -#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT -	ldrh	ip, [r7] -	tst	ip, 0x0400	@ the i bit tells us LS or MS byte -	beq	3f -	cmp	r0, #0		@ set C flag, and ... -	biceq	ip, 0x0400	@ immediate zero value has a special encoding -	streqh	ip, [r7]	@ that requires the i bit cleared -#endif -3:	ldrh	ip, [r7, #2] +	b	2f +1:	add     r7, r3 +	ldrh	ip, [r7, #2]  	and	ip, 0x8f00 -	orrcc	ip, r6	@ mask in offset bits 31-24 -	orrcs	ip, r0	@ mask in offset bits 23-16 +	orr	ip, r6	@ mask in offset bits 31-24  	strh	ip, [r7, #2] -4:	cmp	r4, r5 +2:	cmp	r4, r5  	ldrcc	r7, [r4], #4	@ use branch for delay slot -	bcc	2b +	bcc	1b  	bx	lr  #else -#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT -	and	r0, r6, #255	@ offset bits 23-16 -	mov	r6, r6, lsr #8	@ offset bits 31-24 -#else -	mov	r0, #0		@ just in case... -#endif -	b	3f -2:	ldr	ip, [r7, r3] +	b	2f +1:	ldr	ip, [r7, r3]  	bic	ip, ip, #0x000000ff -	tst	ip, #0x400	@ rotate shift tells us LS or MS byte -	orrne	ip, ip, r6	@ mask in offset bits 31-24 -	orreq	ip, ip, r0	@ mask in offset bits 23-16 +	orr	ip, ip, r6	@ mask in offset bits 31-24  	str	ip, [r7, r3] -3:	cmp	r4, r5 +2:	cmp	r4, r5  	ldrcc	r7, [r4], #4	@ use branch for delay slot -	bcc	2b +	bcc	1b  	mov	pc, lr  #endif  ENDPROC(__fixup_a_pv_table) diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index a927ca1f556..814a52a9dc3 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -45,7 +45,6 @@ static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]);  /* Number of BRP/WRP registers on this CPU. */  static int core_num_brps; -static int core_num_reserved_brps;  static int core_num_wrps;  /* Debug architecture version. */ @@ -137,10 +136,11 @@ static u8 get_debug_arch(void)  	u32 didr;  	/* Do we implement the extended CPUID interface? */ -	if (WARN_ONCE((((read_cpuid_id() >> 16) & 0xf) != 0xf), -	    "CPUID feature registers not supported. " -	    "Assuming v6 debug is present.\n")) +	if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { +		pr_warning("CPUID feature registers not supported. " +			   "Assuming v6 debug is present.\n");  		return ARM_DEBUG_ARCH_V6; +	}  	ARM_DBG_READ(c0, 0, didr);  	return (didr >> 16) & 0xf; @@ -154,10 +154,21 @@ u8 arch_get_debug_arch(void)  static int debug_arch_supported(void)  {  	u8 arch = get_debug_arch(); -	return arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14; + +	/* We don't support the memory-mapped interface. */ +	return (arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14) || +		arch >= ARM_DEBUG_ARCH_V7_1; +} + +/* Determine number of WRP registers available. */ +static int get_num_wrp_resources(void) +{ +	u32 didr; +	ARM_DBG_READ(c0, 0, didr); +	return ((didr >> 28) & 0xf) + 1;  } -/* Determine number of BRP register available. */ +/* Determine number of BRP registers available. */  static int get_num_brp_resources(void)  {  	u32 didr; @@ -176,9 +187,10 @@ static int core_has_mismatch_brps(void)  static int get_num_wrps(void)  {  	/* -	 * FIXME: When a watchpoint fires, the only way to work out which -	 * watchpoint it was is by disassembling the faulting instruction -	 * and working out the address of the memory access. +	 * On debug architectures prior to 7.1, when a watchpoint fires, the +	 * only way to work out which watchpoint it was is by disassembling +	 * the faulting instruction and working out the address of the memory +	 * access.  	 *  	 * Furthermore, we can only do this if the watchpoint was precise  	 * since imprecise watchpoints prevent us from calculating register @@ -192,36 +204,17 @@ static int get_num_wrps(void)  	 * [the ARM ARM states that the DFAR is UNKNOWN, but experience shows  	 * that it is set on some implementations].  	 */ +	if (get_debug_arch() < ARM_DEBUG_ARCH_V7_1) +		return 1; -#if 0 -	int wrps; -	u32 didr; -	ARM_DBG_READ(c0, 0, didr); -	wrps = ((didr >> 28) & 0xf) + 1; -#endif -	int wrps = 1; - -	if (core_has_mismatch_brps() && wrps >= get_num_brp_resources()) -		wrps = get_num_brp_resources() - 1; - -	return wrps; -} - -/* We reserve one breakpoint for each watchpoint. */ -static int get_num_reserved_brps(void) -{ -	if (core_has_mismatch_brps()) -		return get_num_wrps(); -	return 0; +	return get_num_wrp_resources();  }  /* Determine number of usable BRPs available. */  static int get_num_brps(void)  {  	int brps = get_num_brp_resources(); -	if (core_has_mismatch_brps()) -		brps -= get_num_reserved_brps(); -	return brps; +	return core_has_mismatch_brps() ? brps - 1 : brps;  }  /* @@ -239,7 +232,7 @@ static int enable_monitor_mode(void)  	/* Ensure that halting mode is disabled. */  	if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, -			"halting debug mode enabled. Unable to access hardware resources.\n")) { +		"halting debug mode enabled. Unable to access hardware resources.\n")) {  		ret = -EPERM;  		goto out;  	} @@ -255,6 +248,7 @@ static int enable_monitor_mode(void)  		ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN));  		break;  	case ARM_DEBUG_ARCH_V7_ECP14: +	case ARM_DEBUG_ARCH_V7_1:  		ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN));  		break;  	default: @@ -346,24 +340,10 @@ int arch_install_hw_breakpoint(struct perf_event *bp)  		val_base = ARM_BASE_BVR;  		slots = (struct perf_event **)__get_cpu_var(bp_on_reg);  		max_slots = core_num_brps; -		if (info->step_ctrl.enabled) { -			/* Override the breakpoint data with the step data. */ -			addr = info->trigger & ~0x3; -			ctrl = encode_ctrl_reg(info->step_ctrl); -		}  	} else {  		/* Watchpoint */ -		if (info->step_ctrl.enabled) { -			/* Install into the reserved breakpoint region. */ -			ctrl_base = ARM_BASE_BCR + core_num_brps; -			val_base = ARM_BASE_BVR + core_num_brps; -			/* Override the watchpoint data with the step data. */ -			addr = info->trigger & ~0x3; -			ctrl = encode_ctrl_reg(info->step_ctrl); -		} else { -			ctrl_base = ARM_BASE_WCR; -			val_base = ARM_BASE_WVR; -		} +		ctrl_base = ARM_BASE_WCR; +		val_base = ARM_BASE_WVR;  		slots = (struct perf_event **)__get_cpu_var(wp_on_reg);  		max_slots = core_num_wrps;  	} @@ -382,6 +362,17 @@ int arch_install_hw_breakpoint(struct perf_event *bp)  		goto out;  	} +	/* Override the breakpoint data with the step data. */ +	if (info->step_ctrl.enabled) { +		addr = info->trigger & ~0x3; +		ctrl = encode_ctrl_reg(info->step_ctrl); +		if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE) { +			i = 0; +			ctrl_base = ARM_BASE_BCR + core_num_brps; +			val_base = ARM_BASE_BVR + core_num_brps; +		} +	} +  	/* Setup the address register. */  	write_wb_reg(val_base + i, addr); @@ -405,10 +396,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)  		max_slots = core_num_brps;  	} else {  		/* Watchpoint */ -		if (info->step_ctrl.enabled) -			base = ARM_BASE_BCR + core_num_brps; -		else -			base = ARM_BASE_WCR; +		base = ARM_BASE_WCR;  		slots = (struct perf_event **)__get_cpu_var(wp_on_reg);  		max_slots = core_num_wrps;  	} @@ -426,6 +414,13 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)  	if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n"))  		return; +	/* Ensure that we disable the mismatch breakpoint. */ +	if (info->ctrl.type != ARM_BREAKPOINT_EXECUTE && +	    info->step_ctrl.enabled) { +		i = 0; +		base = ARM_BASE_BCR + core_num_brps; +	} +  	/* Reset the control register. */  	write_wb_reg(base + i, 0);  } @@ -632,10 +627,9 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)  	 * we can use the mismatch feature as a poor-man's hardware  	 * single-step, but this only works for per-task breakpoints.  	 */ -	if (WARN_ONCE(!bp->overflow_handler && -		(arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps() -		 || !bp->hw.bp_target), -			"overflow handler required but none found\n")) { +	if (!bp->overflow_handler && (arch_check_bp_in_kernelspace(bp) || +	    !core_has_mismatch_brps() || !bp->hw.bp_target)) { +		pr_warning("overflow handler required but none found\n");  		ret = -EINVAL;  	}  out: @@ -666,34 +660,62 @@ static void disable_single_step(struct perf_event *bp)  	arch_install_hw_breakpoint(bp);  } -static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs) +static void watchpoint_handler(unsigned long addr, unsigned int fsr, +			       struct pt_regs *regs)  { -	int i; +	int i, access; +	u32 val, ctrl_reg, alignment_mask;  	struct perf_event *wp, **slots;  	struct arch_hw_breakpoint *info; +	struct arch_hw_breakpoint_ctrl ctrl;  	slots = (struct perf_event **)__get_cpu_var(wp_on_reg); -	/* Without a disassembler, we can only handle 1 watchpoint. */ -	BUG_ON(core_num_wrps > 1); -  	for (i = 0; i < core_num_wrps; ++i) {  		rcu_read_lock();  		wp = slots[i]; -		if (wp == NULL) { -			rcu_read_unlock(); -			continue; -		} +		if (wp == NULL) +			goto unlock; +		info = counter_arch_bp(wp);  		/* -		 * The DFAR is an unknown value. Since we only allow a -		 * single watchpoint, we can set the trigger to the lowest -		 * possible faulting address. +		 * The DFAR is an unknown value on debug architectures prior +		 * to 7.1. Since we only allow a single watchpoint on these +		 * older CPUs, we can set the trigger to the lowest possible +		 * faulting address.  		 */ -		info = counter_arch_bp(wp); -		info->trigger = wp->attr.bp_addr; +		if (debug_arch < ARM_DEBUG_ARCH_V7_1) { +			BUG_ON(i > 0); +			info->trigger = wp->attr.bp_addr; +		} else { +			if (info->ctrl.len == ARM_BREAKPOINT_LEN_8) +				alignment_mask = 0x7; +			else +				alignment_mask = 0x3; + +			/* Check if the watchpoint value matches. */ +			val = read_wb_reg(ARM_BASE_WVR + i); +			if (val != (addr & ~alignment_mask)) +				goto unlock; + +			/* Possible match, check the byte address select. */ +			ctrl_reg = read_wb_reg(ARM_BASE_WCR + i); +			decode_ctrl_reg(ctrl_reg, &ctrl); +			if (!((1 << (addr & alignment_mask)) & ctrl.len)) +				goto unlock; + +			/* Check that the access type matches. */ +			access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W : +				 HW_BREAKPOINT_R; +			if (!(access & hw_breakpoint_type(wp))) +				goto unlock; + +			/* We have a winner. */ +			info->trigger = addr; +		} +  		pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);  		perf_bp_event(wp, regs); @@ -705,6 +727,7 @@ static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs)  		if (!wp->overflow_handler)  			enable_single_step(wp, instruction_pointer(regs)); +unlock:  		rcu_read_unlock();  	}  } @@ -717,7 +740,7 @@ static void watchpoint_single_step_handler(unsigned long pc)  	slots = (struct perf_event **)__get_cpu_var(wp_on_reg); -	for (i = 0; i < core_num_reserved_brps; ++i) { +	for (i = 0; i < core_num_wrps; ++i) {  		rcu_read_lock();  		wp = slots[i]; @@ -820,7 +843,7 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,  	case ARM_ENTRY_ASYNC_WATCHPOINT:  		WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n");  	case ARM_ENTRY_SYNC_WATCHPOINT: -		watchpoint_handler(addr, regs); +		watchpoint_handler(addr, fsr, regs);  		break;  	default:  		ret = 1; /* Unhandled fault. */ @@ -834,11 +857,31 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,  /*   * One-time initialisation.   */ -static void reset_ctrl_regs(void *info) +static cpumask_t debug_err_mask; + +static int debug_reg_trap(struct pt_regs *regs, unsigned int instr) +{ +	int cpu = smp_processor_id(); + +	pr_warning("Debug register access (0x%x) caused undefined instruction on CPU %d\n", +		   instr, cpu); + +	/* Set the error flag for this CPU and skip the faulting instruction. */ +	cpumask_set_cpu(cpu, &debug_err_mask); +	instruction_pointer(regs) += 4; +	return 0; +} + +static struct undef_hook debug_reg_hook = { +	.instr_mask	= 0x0fe80f10, +	.instr_val	= 0x0e000e10, +	.fn		= debug_reg_trap, +}; + +static void reset_ctrl_regs(void *unused)  { -	int i, cpu = smp_processor_id(); +	int i, raw_num_brps, err = 0, cpu = smp_processor_id();  	u32 dbg_power; -	cpumask_t *cpumask = info;  	/*  	 * v7 debug contains save and restore registers so that debug state @@ -848,38 +891,57 @@ static void reset_ctrl_regs(void *info)  	 * Access Register to avoid taking undefined instruction exceptions  	 * later on.  	 */ -	if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { +	switch (debug_arch) { +	case ARM_DEBUG_ARCH_V6: +	case ARM_DEBUG_ARCH_V6_1: +		/* ARMv6 cores just need to reset the registers. */ +		goto reset_regs; +	case ARM_DEBUG_ARCH_V7_ECP14:  		/*  		 * Ensure sticky power-down is clear (i.e. debug logic is  		 * powered up).  		 */  		asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power)); -		if ((dbg_power & 0x1) == 0) { -			pr_warning("CPU %d debug is powered down!\n", cpu); -			cpumask_or(cpumask, cpumask, cpumask_of(cpu)); -			return; -		} - +		if ((dbg_power & 0x1) == 0) +			err = -EPERM; +		break; +	case ARM_DEBUG_ARCH_V7_1:  		/* -		 * Unconditionally clear the lock by writing a value -		 * other than 0xC5ACCE55 to the access register. +		 * Ensure the OS double lock is clear.  		 */ -		asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0)); -		isb(); +		asm volatile("mrc p14, 0, %0, c1, c3, 4" : "=r" (dbg_power)); +		if ((dbg_power & 0x1) == 1) +			err = -EPERM; +		break; +	} -		/* -		 * Clear any configured vector-catch events before -		 * enabling monitor mode. -		 */ -		asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0)); -		isb(); +	if (err) { +		pr_warning("CPU %d debug is powered down!\n", cpu); +		cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu)); +		return;  	} +	/* +	 * Unconditionally clear the lock by writing a value +	 * other than 0xC5ACCE55 to the access register. +	 */ +	asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0)); +	isb(); + +	/* +	 * Clear any configured vector-catch events before +	 * enabling monitor mode. +	 */ +	asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0)); +	isb(); + +reset_regs:  	if (enable_monitor_mode())  		return;  	/* We must also reset any reserved registers. */ -	for (i = 0; i < core_num_brps + core_num_reserved_brps; ++i) { +	raw_num_brps = get_num_brp_resources(); +	for (i = 0; i < raw_num_brps; ++i) {  		write_wb_reg(ARM_BASE_BCR + i, 0UL);  		write_wb_reg(ARM_BASE_BVR + i, 0UL);  	} @@ -895,6 +957,7 @@ static int __cpuinit dbg_reset_notify(struct notifier_block *self,  {  	if (action == CPU_ONLINE)  		smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1); +  	return NOTIFY_OK;  } @@ -905,7 +968,6 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = {  static int __init arch_hw_breakpoint_init(void)  {  	u32 dscr; -	cpumask_t cpumask = { CPU_BITS_NONE };  	debug_arch = get_debug_arch(); @@ -916,28 +978,31 @@ static int __init arch_hw_breakpoint_init(void)  	/* Determine how many BRPs/WRPs are available. */  	core_num_brps = get_num_brps(); -	core_num_reserved_brps = get_num_reserved_brps();  	core_num_wrps = get_num_wrps(); -	pr_info("found %d breakpoint and %d watchpoint registers.\n", -		core_num_brps + core_num_reserved_brps, core_num_wrps); - -	if (core_num_reserved_brps) -		pr_info("%d breakpoint(s) reserved for watchpoint " -				"single-step.\n", core_num_reserved_brps); +	/* +	 * We need to tread carefully here because DBGSWENABLE may be +	 * driven low on this core and there isn't an architected way to +	 * determine that. +	 */ +	register_undef_hook(&debug_reg_hook);  	/*  	 * Reset the breakpoint resources. We assume that a halting  	 * debugger will leave the world in a nice state for us.  	 */ -	on_each_cpu(reset_ctrl_regs, &cpumask, 1); -	if (!cpumask_empty(&cpumask)) { +	on_each_cpu(reset_ctrl_regs, NULL, 1); +	unregister_undef_hook(&debug_reg_hook); +	if (!cpumask_empty(&debug_err_mask)) {  		core_num_brps = 0; -		core_num_reserved_brps = 0;  		core_num_wrps = 0;  		return 0;  	} +	pr_info("found %d " "%s" "breakpoint and %d watchpoint registers.\n", +		core_num_brps, core_has_mismatch_brps() ? "(+1 reserved) " : +		"", core_num_wrps); +  	ARM_DBG_READ(c1, 0, dscr);  	if (dscr & ARM_DSCR_HDBGEN) {  		max_watchpoint_len = 4; diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index de3dcab8610..7cb29261249 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -35,8 +35,8 @@  #include <linux/list.h>  #include <linux/kallsyms.h>  #include <linux/proc_fs.h> -#include <linux/ftrace.h> +#include <asm/exception.h>  #include <asm/system.h>  #include <asm/mach/arch.h>  #include <asm/mach/irq.h> @@ -59,9 +59,6 @@ int arch_show_interrupts(struct seq_file *p, int prec)  #ifdef CONFIG_SMP  	show_ipi_list(p, prec);  #endif -#ifdef CONFIG_LOCAL_TIMERS -	show_local_irqs(p, prec); -#endif  	seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);  	return 0;  } diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/kernel/kprobes-arm.c index 79203ee1d03..9fe8910308a 100644 --- a/arch/arm/kernel/kprobes-arm.c +++ b/arch/arm/kernel/kprobes-arm.c @@ -60,6 +60,7 @@  #include <linux/kernel.h>  #include <linux/kprobes.h> +#include <linux/module.h>  #include "kprobes.h" @@ -971,6 +972,9 @@ const union decode_item kprobe_decode_arm_table[] = {  	DECODE_END  }; +#ifdef CONFIG_ARM_KPROBES_TEST_MODULE +EXPORT_SYMBOL_GPL(kprobe_decode_arm_table); +#endif  static void __kprobes arm_singlestep(struct kprobe *p, struct pt_regs *regs)  { diff --git a/arch/arm/kernel/kprobes-test-arm.c b/arch/arm/kernel/kprobes-test-arm.c new file mode 100644 index 00000000000..fc82de8bdcc --- /dev/null +++ b/arch/arm/kernel/kprobes-test-arm.c @@ -0,0 +1,1323 @@ +/* + * arch/arm/kernel/kprobes-test-arm.c + * + * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. + * + * 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/kernel.h> +#include <linux/module.h> + +#include "kprobes-test.h" + + +#define TEST_ISA "32" + +#define TEST_ARM_TO_THUMB_INTERWORK_R(code1, reg, val, code2)	\ +	TESTCASE_START(code1 #reg code2)			\ +	TEST_ARG_REG(reg, val)					\ +	TEST_ARG_REG(14, 99f)					\ +	TEST_ARG_END("")					\ +	"50:	nop			\n\t"			\ +	"1:	"code1 #reg code2"	\n\t"			\ +	"	bx	lr		\n\t"			\ +	".thumb				\n\t"			\ +	"3:	adr	lr, 2f		\n\t"			\ +	"	bx	lr		\n\t"			\ +	".arm				\n\t"			\ +	"2:	nop			\n\t"			\ +	TESTCASE_END + +#define TEST_ARM_TO_THUMB_INTERWORK_P(code1, reg, val, code2)	\ +	TESTCASE_START(code1 #reg code2)			\ +	TEST_ARG_PTR(reg, val)					\ +	TEST_ARG_REG(14, 99f)					\ +	TEST_ARG_MEM(15, 3f+1)					\ +	TEST_ARG_END("")					\ +	"50:	nop			\n\t"			\ +	"1:	"code1 #reg code2"	\n\t"			\ +	"	bx	lr		\n\t"			\ +	".thumb				\n\t"			\ +	"3:	adr	lr, 2f		\n\t"			\ +	"	bx	lr		\n\t"			\ +	".arm				\n\t"			\ +	"2:	nop			\n\t"			\ +	TESTCASE_END + + +void kprobe_arm_test_cases(void) +{ +	kprobe_test_flags = 0; + +	TEST_GROUP("Data-processing (register), (register-shifted register), (immediate)") + +#define _DATA_PROCESSING_DNM(op,s,val)						\ +	TEST_RR(  op "eq" s "	r0,  r",1, VAL1,", r",2, val, "")		\ +	TEST_RR(  op "ne" s "	r1,  r",1, VAL1,", r",2, val, ", lsl #3")	\ +	TEST_RR(  op "cs" s "	r2,  r",3, VAL1,", r",2, val, ", lsr #4")	\ +	TEST_RR(  op "cc" s "	r3,  r",3, VAL1,", r",2, val, ", asr #5")	\ +	TEST_RR(  op "mi" s "	r4,  r",5, VAL1,", r",2, N(val),", asr #6")	\ +	TEST_RR(  op "pl" s "	r5,  r",5, VAL1,", r",2, val, ", ror #7")	\ +	TEST_RR(  op "vs" s "	r6,  r",7, VAL1,", r",2, val, ", rrx")		\ +	TEST_R(   op "vc" s "	r6,  r",7, VAL1,", pc, lsl #3")			\ +	TEST_R(   op "vc" s "	r6,  r",7, VAL1,", sp, lsr #4")			\ +	TEST_R(   op "vc" s "	r6,  pc, r",7, VAL1,", asr #5")			\ +	TEST_R(   op "vc" s "	r6,  sp, r",7, VAL1,", ror #6")			\ +	TEST_RRR( op "hi" s "	r8,  r",9, VAL1,", r",14,val, ", lsl r",0, 3,"")\ +	TEST_RRR( op "ls" s "	r9,  r",9, VAL1,", r",14,val, ", lsr r",7, 4,"")\ +	TEST_RRR( op "ge" s "	r10, r",11,VAL1,", r",14,val, ", asr r",7, 5,"")\ +	TEST_RRR( op "lt" s "	r11, r",11,VAL1,", r",14,N(val),", asr r",7, 6,"")\ +	TEST_RR(  op "gt" s "	r12, r13"       ", r",14,val, ", ror r",14,7,"")\ +	TEST_RR(  op "le" s "	r14, r",0, val, ", r13"       ", lsl r",14,8,"")\ +	TEST_RR(  op s "	r12, pc"        ", r",14,val, ", ror r",14,7,"")\ +	TEST_RR(  op s "	r14, r",0, val, ", pc"        ", lsl r",14,8,"")\ +	TEST_R(   op "eq" s "	r0,  r",11,VAL1,", #0xf5")			\ +	TEST_R(   op "ne" s "	r11, r",0, VAL1,", #0xf5000000")		\ +	TEST_R(   op s "	r7,  r",8, VAL2,", #0x000af000")		\ +	TEST(     op s "	r4,  pc"        ", #0x00005a00") + +#define DATA_PROCESSING_DNM(op,val)		\ +	_DATA_PROCESSING_DNM(op,"",val)		\ +	_DATA_PROCESSING_DNM(op,"s",val) + +#define DATA_PROCESSING_NM(op,val)						\ +	TEST_RR(  op "ne	r",1, VAL1,", r",2, val, "")			\ +	TEST_RR(  op "eq	r",1, VAL1,", r",2, val, ", lsl #3")		\ +	TEST_RR(  op "cc	r",3, VAL1,", r",2, val, ", lsr #4")		\ +	TEST_RR(  op "cs	r",3, VAL1,", r",2, val, ", asr #5")		\ +	TEST_RR(  op "pl	r",5, VAL1,", r",2, N(val),", asr #6")		\ +	TEST_RR(  op "mi	r",5, VAL1,", r",2, val, ", ror #7")		\ +	TEST_RR(  op "vc	r",7, VAL1,", r",2, val, ", rrx")		\ +	TEST_R (  op "vs	r",7, VAL1,", pc, lsl #3")			\ +	TEST_R (  op "vs	r",7, VAL1,", sp, lsr #4")			\ +	TEST_R(   op "vs	pc, r",7, VAL1,", asr #5")			\ +	TEST_R(   op "vs	sp, r",7, VAL1,", ror #6")			\ +	TEST_RRR( op "ls	r",9, VAL1,", r",14,val, ", lsl r",0, 3,"")	\ +	TEST_RRR( op "hi	r",9, VAL1,", r",14,val, ", lsr r",7, 4,"")	\ +	TEST_RRR( op "lt	r",11,VAL1,", r",14,val, ", asr r",7, 5,"")	\ +	TEST_RRR( op "ge	r",11,VAL1,", r",14,N(val),", asr r",7, 6,"")	\ +	TEST_RR(  op "le	r13"       ", r",14,val, ", ror r",14,7,"")	\ +	TEST_RR(  op "gt	r",0, val, ", r13"       ", lsl r",14,8,"")	\ +	TEST_RR(  op "	pc"        ", r",14,val, ", ror r",14,7,"")		\ +	TEST_RR(  op "	r",0, val, ", pc"        ", lsl r",14,8,"")		\ +	TEST_R(   op "eq	r",11,VAL1,", #0xf5")				\ +	TEST_R(   op "ne	r",0, VAL1,", #0xf5000000")			\ +	TEST_R(   op "	r",8, VAL2,", #0x000af000") + +#define _DATA_PROCESSING_DM(op,s,val)					\ +	TEST_R(   op "eq" s "	r0,  r",1, val, "")			\ +	TEST_R(   op "ne" s "	r1,  r",1, val, ", lsl #3")		\ +	TEST_R(   op "cs" s "	r2,  r",3, val, ", lsr #4")		\ +	TEST_R(   op "cc" s "	r3,  r",3, val, ", asr #5")		\ +	TEST_R(   op "mi" s "	r4,  r",5, N(val),", asr #6")		\ +	TEST_R(   op "pl" s "	r5,  r",5, val, ", ror #7")		\ +	TEST_R(   op "vs" s "	r6,  r",10,val, ", rrx")		\ +	TEST(     op "vs" s "	r7,  pc, lsl #3")			\ +	TEST(     op "vs" s "	r7,  sp, lsr #4")			\ +	TEST_RR(  op "vc" s "	r8,  r",7, val, ", lsl r",0, 3,"")	\ +	TEST_RR(  op "hi" s "	r9,  r",9, val, ", lsr r",7, 4,"")	\ +	TEST_RR(  op "ls" s "	r10, r",9, val, ", asr r",7, 5,"")	\ +	TEST_RR(  op "ge" s "	r11, r",11,N(val),", asr r",7, 6,"")	\ +	TEST_RR(  op "lt" s "	r12, r",11,val, ", ror r",14,7,"")	\ +	TEST_R(   op "gt" s "	r14, r13"       ", lsl r",14,8,"")	\ +	TEST_R(   op "le" s "	r14, pc"        ", lsl r",14,8,"")	\ +	TEST(     op "eq" s "	r0,  #0xf5")				\ +	TEST(     op "ne" s "	r11, #0xf5000000")			\ +	TEST(     op s "	r7,  #0x000af000")			\ +	TEST(     op s "	r4,  #0x00005a00") + +#define DATA_PROCESSING_DM(op,val)		\ +	_DATA_PROCESSING_DM(op,"",val)		\ +	_DATA_PROCESSING_DM(op,"s",val) + +	DATA_PROCESSING_DNM("and",0xf00f00ff) +	DATA_PROCESSING_DNM("eor",0xf00f00ff) +	DATA_PROCESSING_DNM("sub",VAL2) +	DATA_PROCESSING_DNM("rsb",VAL2) +	DATA_PROCESSING_DNM("add",VAL2) +	DATA_PROCESSING_DNM("adc",VAL2) +	DATA_PROCESSING_DNM("sbc",VAL2) +	DATA_PROCESSING_DNM("rsc",VAL2) +	DATA_PROCESSING_NM("tst",0xf00f00ff) +	DATA_PROCESSING_NM("teq",0xf00f00ff) +	DATA_PROCESSING_NM("cmp",VAL2) +	DATA_PROCESSING_NM("cmn",VAL2) +	DATA_PROCESSING_DNM("orr",0xf00f00ff) +	DATA_PROCESSING_DM("mov",VAL2) +	DATA_PROCESSING_DNM("bic",0xf00f00ff) +	DATA_PROCESSING_DM("mvn",VAL2) + +	TEST("mov	ip, sp") /* This has special case emulation code */ + +	TEST_SUPPORTED("mov	pc, #0x1000"); +	TEST_SUPPORTED("mov	sp, #0x1000"); +	TEST_SUPPORTED("cmp	pc, #0x1000"); +	TEST_SUPPORTED("cmp	sp, #0x1000"); + +	/* Data-processing with PC as shift*/ +	TEST_UNSUPPORTED(".word 0xe15c0f1e	@ cmp	r12, r14, asl pc") +	TEST_UNSUPPORTED(".word 0xe1a0cf1e	@ mov	r12, r14, asl pc") +	TEST_UNSUPPORTED(".word 0xe08caf1e	@ add	r10, r12, r14, asl pc") + +	/* Data-processing with PC as shift*/ +	TEST_UNSUPPORTED("movs	pc, r1") +	TEST_UNSUPPORTED("movs	pc, r1, lsl r2") +	TEST_UNSUPPORTED("movs	pc, #0x10000") +	TEST_UNSUPPORTED("adds	pc, lr, r1") +	TEST_UNSUPPORTED("adds	pc, lr, r1, lsl r2") +	TEST_UNSUPPORTED("adds	pc, lr, #4") + +	/* Data-processing with SP as target */ +	TEST("add	sp, sp, #16") +	TEST("sub	sp, sp, #8") +	TEST("bic	sp, sp, #0x20") +	TEST("orr	sp, sp, #0x20") +	TEST_PR( "add	sp, r",10,0,", r",11,4,"") +	TEST_PRR("add	sp, r",10,0,", r",11,4,", asl r",12,1,"") +	TEST_P(  "mov	sp, r",10,0,"") +	TEST_PR( "mov	sp, r",10,0,", asl r",12,0,"") + +	/* Data-processing with PC as target */ +	TEST_BF(   "add	pc, pc, #2f-1b-8") +	TEST_BF_R ("add	pc, pc, r",14,2f-1f-8,"") +	TEST_BF_R ("add	pc, r",14,2f-1f-8,", pc") +	TEST_BF_R ("mov	pc, r",0,2f,"") +	TEST_BF_RR("mov	pc, r",0,2f,", asl r",1,0,"") +	TEST_BB(   "sub	pc, pc, #1b-2b+8") +#if __LINUX_ARM_ARCH__ >= 6 +	TEST_BB(   "sub	pc, pc, #1b-2b+8-2") /* UNPREDICTABLE before ARMv6 */ +#endif +	TEST_BB_R( "sub	pc, pc, r",14, 1f-2f+8,"") +	TEST_BB_R( "rsb	pc, r",14,1f-2f+8,", pc") +	TEST_RR(   "add	pc, pc, r",10,-2,", asl r",11,1,"") +#ifdef CONFIG_THUMB2_KERNEL +	TEST_ARM_TO_THUMB_INTERWORK_R("add	pc, pc, r",0,3f-1f-8+1,"") +	TEST_ARM_TO_THUMB_INTERWORK_R("sub	pc, r",0,3f+8+1,", #8") +#endif +	TEST_GROUP("Miscellaneous instructions") + +	TEST("mrs	r0, cpsr") +	TEST("mrspl	r7, cpsr") +	TEST("mrs	r14, cpsr") +	TEST_UNSUPPORTED(".word 0xe10ff000	@ mrs r15, cpsr") +	TEST_UNSUPPORTED("mrs	r0, spsr") +	TEST_UNSUPPORTED("mrs	lr, spsr") + +	TEST_UNSUPPORTED("msr	cpsr, r0") +	TEST_UNSUPPORTED("msr	cpsr_f, lr") +	TEST_UNSUPPORTED("msr	spsr, r0") + +	TEST_BF_R("bx	r",0,2f,"") +	TEST_BB_R("bx	r",7,2f,"") +	TEST_BF_R("bxeq	r",14,2f,"") + +	TEST_R("clz	r0, r",0, 0x0,"") +	TEST_R("clzeq	r7, r",14,0x1,"") +	TEST_R("clz	lr, r",7, 0xffffffff,"") +	TEST(  "clz	r4, sp") +	TEST_UNSUPPORTED(".word 0x016fff10	@ clz pc, r0") +	TEST_UNSUPPORTED(".word 0x016f0f1f	@ clz r0, pc") + +#if __LINUX_ARM_ARCH__ >= 6 +	TEST_UNSUPPORTED("bxj	r0") +#endif + +	TEST_BF_R("blx	r",0,2f,"") +	TEST_BB_R("blx	r",7,2f,"") +	TEST_BF_R("blxeq	r",14,2f,"") +	TEST_UNSUPPORTED(".word 0x0120003f	@ blx pc") + +	TEST_RR(   "qadd	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(   "qaddvs	lr, r",9, VAL2,", r",8, VAL1,"") +	TEST_R(    "qadd	lr, r",9, VAL2,", r13") +	TEST_RR(   "qsub	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(   "qsubvs	lr, r",9, VAL2,", r",8, VAL1,"") +	TEST_R(    "qsub	lr, r",9, VAL2,", r13") +	TEST_RR(   "qdadd	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(   "qdaddvs	lr, r",9, VAL2,", r",8, VAL1,"") +	TEST_R(    "qdadd	lr, r",9, VAL2,", r13") +	TEST_RR(   "qdsub	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(   "qdsubvs	lr, r",9, VAL2,", r",8, VAL1,"") +	TEST_R(    "qdsub	lr, r",9, VAL2,", r13") +	TEST_UNSUPPORTED(".word 0xe101f050	@ qadd pc, r0, r1") +	TEST_UNSUPPORTED(".word 0xe121f050	@ qsub pc, r0, r1") +	TEST_UNSUPPORTED(".word 0xe141f050	@ qdadd pc, r0, r1") +	TEST_UNSUPPORTED(".word 0xe161f050	@ qdsub pc, r0, r1") +	TEST_UNSUPPORTED(".word 0xe16f2050	@ qdsub r2, r0, pc") +	TEST_UNSUPPORTED(".word 0xe161205f	@ qdsub r2, pc, r1") + +	TEST_UNSUPPORTED("bkpt	0xffff") +	TEST_UNSUPPORTED("bkpt	0x0000") + +	TEST_UNSUPPORTED(".word 0xe1600070 @ smc #0") + +	TEST_GROUP("Halfword multiply and multiply-accumulate") + +	TEST_RRR(    "smlabb	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(    "smlabbge	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RR(     "smlabb	lr, r",1, VAL2,", r",2, VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe10f3281 @ smlabb pc, r1, r2, r3") +	TEST_RRR(    "smlatb	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(    "smlatbge	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RR(     "smlatb	lr, r",1, VAL2,", r",2, VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe10f32a1 @ smlatb pc, r1, r2, r3") +	TEST_RRR(    "smlabt	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(    "smlabtge	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RR(     "smlabt	lr, r",1, VAL2,", r",2, VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe10f32c1 @ smlabt pc, r1, r2, r3") +	TEST_RRR(    "smlatt	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(    "smlattge	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RR(     "smlatt	lr, r",1, VAL2,", r",2, VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe10f32e1 @ smlatt pc, r1, r2, r3") + +	TEST_RRR(    "smlawb	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(    "smlawbge	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RR(     "smlawb	lr, r",1, VAL2,", r",2, VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe12f3281 @ smlawb pc, r1, r2, r3") +	TEST_RRR(    "smlawt	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(    "smlawtge	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RR(     "smlawt	lr, r",1, VAL2,", r",2, VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe12f32c1 @ smlawt pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe12032cf @ smlawt r0, pc, r2, r3") +	TEST_UNSUPPORTED(".word 0xe1203fc1 @ smlawt r0, r1, pc, r3") +	TEST_UNSUPPORTED(".word 0xe120f2c1 @ smlawt r0, r1, r2, pc") + +	TEST_RR(    "smulwb	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "smulwbge	r7, r",8, VAL3,", r",9, VAL1,"") +	TEST_R(     "smulwb	lr, r",1, VAL2,", r13") +	TEST_UNSUPPORTED(".word 0xe12f02a1 @ smulwb pc, r1, r2") +	TEST_RR(    "smulwt	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "smulwtge	r7, r",8, VAL3,", r",9, VAL1,"") +	TEST_R(     "smulwt	lr, r",1, VAL2,", r13") +	TEST_UNSUPPORTED(".word 0xe12f02e1 @ smulwt pc, r1, r2") + +	TEST_RRRR(  "smlalbb	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR(  "smlalbble	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) +	TEST_RRR(   "smlalbb	r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13") +	TEST_UNSUPPORTED(".word 0xe14f1382 @ smlalbb pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe141f382 @ smlalbb r1, pc, r2, r3") +	TEST_RRRR(  "smlaltb	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR(  "smlaltble	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) +	TEST_RRR(   "smlaltb	r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13") +	TEST_UNSUPPORTED(".word 0xe14f13a2 @ smlaltb pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe141f3a2 @ smlaltb r1, pc, r2, r3") +	TEST_RRRR(  "smlalbt	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR(  "smlalbtle	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) +	TEST_RRR(   "smlalbt	r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13") +	TEST_UNSUPPORTED(".word 0xe14f13c2 @ smlalbt pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe141f3c2 @ smlalbt r1, pc, r2, r3") +	TEST_RRRR(  "smlaltt	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR(  "smlalttle	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) +	TEST_RRR(   "smlaltt	r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13") +	TEST_UNSUPPORTED(".word 0xe14f13e2 @ smlalbb pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe140f3e2 @ smlalbb r0, pc, r2, r3") +	TEST_UNSUPPORTED(".word 0xe14013ef @ smlalbb r0, r1, pc, r3") +	TEST_UNSUPPORTED(".word 0xe1401fe2 @ smlalbb r0, r1, r2, pc") + +	TEST_RR(    "smulbb	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "smulbbge	r7, r",8, VAL3,", r",9, VAL1,"") +	TEST_R(     "smulbb	lr, r",1, VAL2,", r13") +	TEST_UNSUPPORTED(".word 0xe16f0281 @ smulbb pc, r1, r2") +	TEST_RR(    "smultb	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "smultbge	r7, r",8, VAL3,", r",9, VAL1,"") +	TEST_R(     "smultb	lr, r",1, VAL2,", r13") +	TEST_UNSUPPORTED(".word 0xe16f02a1 @ smultb pc, r1, r2") +	TEST_RR(    "smulbt	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "smulbtge	r7, r",8, VAL3,", r",9, VAL1,"") +	TEST_R(     "smulbt	lr, r",1, VAL2,", r13") +	TEST_UNSUPPORTED(".word 0xe16f02c1 @ smultb pc, r1, r2") +	TEST_RR(    "smultt	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "smulttge	r7, r",8, VAL3,", r",9, VAL1,"") +	TEST_R(     "smultt	lr, r",1, VAL2,", r13") +	TEST_UNSUPPORTED(".word 0xe16f02e1 @ smultt pc, r1, r2") +	TEST_UNSUPPORTED(".word 0xe16002ef @ smultt r0, pc, r2") +	TEST_UNSUPPORTED(".word 0xe1600fe1 @ smultt r0, r1, pc") + +	TEST_GROUP("Multiply and multiply-accumulate") + +	TEST_RR(    "mul	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "mulls	r7, r",8, VAL2,", r",9, VAL2,"") +	TEST_R(     "mul	lr, r",4, VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe00f0291 @ mul pc, r1, r2") +	TEST_UNSUPPORTED(".word 0xe000029f @ mul r0, pc, r2") +	TEST_UNSUPPORTED(".word 0xe0000f91 @ mul r0, r1, pc") +	TEST_RR(    "muls	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "mullss	r7, r",8, VAL2,", r",9, VAL2,"") +	TEST_R(     "muls	lr, r",4, VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe01f0291 @ muls pc, r1, r2") + +	TEST_RRR(    "mla	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(    "mlahi	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RR(     "mla	lr, r",1, VAL2,", r",2, VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe02f3291 @ mla pc, r1, r2, r3") +	TEST_RRR(    "mlas	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(    "mlahis	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RR(     "mlas	lr, r",1, VAL2,", r",2, VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe03f3291 @ mlas pc, r1, r2, r3") + +#if __LINUX_ARM_ARCH__ >= 6 +	TEST_RR(  "umaal	r0, r1, r",2, VAL1,", r",3, VAL2,"") +	TEST_RR(  "umaalls	r7, r8, r",9, VAL2,", r",10, VAL1,"") +	TEST_R(   "umaal	lr, r12, r",11,VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe041f392 @ umaal pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe04f0392 @ umaal r0, pc, r2, r3") +	TEST_UNSUPPORTED(".word 0xe0500090 @ undef") +	TEST_UNSUPPORTED(".word 0xe05fff9f @ undef") + +	TEST_RRR(  "mls		r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(  "mlshi	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RR(   "mls		lr, r",1, VAL2,", r",2, VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe06f3291 @ mls pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe060329f @ mls r0, pc, r2, r3") +	TEST_UNSUPPORTED(".word 0xe0603f91 @ mls r0, r1, pc, r3") +	TEST_UNSUPPORTED(".word 0xe060f291 @ mls r0, r1, r2, pc") +#endif + +	TEST_UNSUPPORTED(".word 0xe0700090 @ undef") +	TEST_UNSUPPORTED(".word 0xe07fff9f @ undef") + +	TEST_RR(  "umull	r0, r1, r",2, VAL1,", r",3, VAL2,"") +	TEST_RR(  "umullls	r7, r8, r",9, VAL2,", r",10, VAL1,"") +	TEST_R(   "umull	lr, r12, r",11,VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe081f392 @ umull pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe08f1392 @ umull r1, pc, r2, r3") +	TEST_RR(  "umulls	r0, r1, r",2, VAL1,", r",3, VAL2,"") +	TEST_RR(  "umulllss	r7, r8, r",9, VAL2,", r",10, VAL1,"") +	TEST_R(   "umulls	lr, r12, r",11,VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe091f392 @ umulls pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe09f1392 @ umulls r1, pc, r2, r3") + +	TEST_RRRR(  "umlal	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR(  "umlalle	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) +	TEST_RRR(   "umlal	r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13") +	TEST_UNSUPPORTED(".word 0xe0af1392 @ umlal pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe0a1f392 @ umlal r1, pc, r2, r3") +	TEST_RRRR(  "umlals	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR(  "umlalles	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) +	TEST_RRR(   "umlals	r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13") +	TEST_UNSUPPORTED(".word 0xe0bf1392 @ umlals pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe0b1f392 @ umlals r1, pc, r2, r3") + +	TEST_RR(  "smull	r0, r1, r",2, VAL1,", r",3, VAL2,"") +	TEST_RR(  "smullls	r7, r8, r",9, VAL2,", r",10, VAL1,"") +	TEST_R(   "smull	lr, r12, r",11,VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe0c1f392 @ smull pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe0cf1392 @ smull r1, pc, r2, r3") +	TEST_RR(  "smulls	r0, r1, r",2, VAL1,", r",3, VAL2,"") +	TEST_RR(  "smulllss	r7, r8, r",9, VAL2,", r",10, VAL1,"") +	TEST_R(   "smulls	lr, r12, r",11,VAL3,", r13") +	TEST_UNSUPPORTED(".word 0xe0d1f392 @ smulls pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe0df1392 @ smulls r1, pc, r2, r3") + +	TEST_RRRR(  "smlal	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR(  "smlalle	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) +	TEST_RRR(   "smlal	r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13") +	TEST_UNSUPPORTED(".word 0xe0ef1392 @ smlal pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe0e1f392 @ smlal r1, pc, r2, r3") +	TEST_RRRR(  "smlals	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR(  "smlalles	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) +	TEST_RRR(   "smlals	r",14,VAL3,", r",7, VAL4,", r",5, VAL1,", r13") +	TEST_UNSUPPORTED(".word 0xe0ff1392 @ smlals pc, r1, r2, r3") +	TEST_UNSUPPORTED(".word 0xe0f0f392 @ smlals r0, pc, r2, r3") +	TEST_UNSUPPORTED(".word 0xe0f0139f @ smlals r0, r1, pc, r3") +	TEST_UNSUPPORTED(".word 0xe0f01f92 @ smlals r0, r1, r2, pc") + +	TEST_GROUP("Synchronization primitives") + +	/* +	 * Use hard coded constants for SWP instructions to avoid warnings +	 * about deprecated instructions. +	 */ +	TEST_RP( ".word 0xe108e097 @ swp	lr, r",7,VAL2,", [r",8,0,"]") +	TEST_R(  ".word 0x610d0091 @ swpvs	r0, r",1,VAL1,", [sp]") +	TEST_RP( ".word 0xe10cd09e @ swp	sp, r",14,VAL2,", [r",12,13*4,"]") +	TEST_UNSUPPORTED(".word 0xe102f091 @ swp pc, r1, [r2]") +	TEST_UNSUPPORTED(".word 0xe102009f @ swp r0, pc, [r2]") +	TEST_UNSUPPORTED(".word 0xe10f0091 @ swp r0, r1, [pc]") +	TEST_RP( ".word 0xe148e097 @ swpb	lr, r",7,VAL2,", [r",8,0,"]") +	TEST_R(  ".word 0x614d0091 @ swpvsb	r0, r",1,VAL1,", [sp]") +	TEST_UNSUPPORTED(".word 0xe142f091 @ swpb pc, r1, [r2]") + +	TEST_UNSUPPORTED(".word	0xe1100090") /* Unallocated space */ +	TEST_UNSUPPORTED(".word	0xe1200090") /* Unallocated space */ +	TEST_UNSUPPORTED(".word	0xe1300090") /* Unallocated space */ +	TEST_UNSUPPORTED(".word	0xe1500090") /* Unallocated space */ +	TEST_UNSUPPORTED(".word	0xe1600090") /* Unallocated space */ +	TEST_UNSUPPORTED(".word	0xe1700090") /* Unallocated space */ +#if __LINUX_ARM_ARCH__ >= 6 +	TEST_UNSUPPORTED("ldrex	r2, [sp]") +	TEST_UNSUPPORTED("strexd	r0, r2, r3, [sp]") +	TEST_UNSUPPORTED("ldrexd	r2, r3, [sp]") +	TEST_UNSUPPORTED("strexb	r0, r2, [sp]") +	TEST_UNSUPPORTED("ldrexb	r2, [sp]") +	TEST_UNSUPPORTED("strexh	r0, r2, [sp]") +	TEST_UNSUPPORTED("ldrexh	r2, [sp]") +#endif +	TEST_GROUP("Extra load/store instructions") + +	TEST_RPR(  "strh	r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") +	TEST_RPR(  "streqh	r",14,VAL2,", [r",13,0, ", r",12, 48,"]") +	TEST_RPR(  "strh	r",1, VAL1,", [r",2, 24,", r",3,  48,"]!") +	TEST_RPR(  "strneh	r",12,VAL2,", [r",11,48,", -r",10,24,"]!") +	TEST_RPR(  "strh	r",2, VAL1,", [r",3, 24,"], r",4, 48,"") +	TEST_RPR(  "strh	r",10,VAL2,", [r",9, 48,"], -r",11,24,"") +	TEST_UNSUPPORTED(".word 0xe1afc0ba	@ strh r12, [pc, r10]!") +	TEST_UNSUPPORTED(".word 0xe089f0bb	@ strh pc, [r9], r11") +	TEST_UNSUPPORTED(".word 0xe089a0bf	@ strh r10, [r9], pc") + +	TEST_PR(   "ldrh	r0, [r",0,  48,", -r",2, 24,"]") +	TEST_PR(   "ldrcsh	r14, [r",13,0, ", r",12, 48,"]") +	TEST_PR(   "ldrh	r1, [r",2,  24,", r",3,  48,"]!") +	TEST_PR(   "ldrcch	r12, [r",11,48,", -r",10,24,"]!") +	TEST_PR(   "ldrh	r2, [r",3,  24,"], r",4, 48,"") +	TEST_PR(   "ldrh	r10, [r",9, 48,"], -r",11,24,"") +	TEST_UNSUPPORTED(".word 0xe1bfc0ba	@ ldrh r12, [pc, r10]!") +	TEST_UNSUPPORTED(".word 0xe099f0bb	@ ldrh pc, [r9], r11") +	TEST_UNSUPPORTED(".word 0xe099a0bf	@ ldrh r10, [r9], pc") + +	TEST_RP(   "strh	r",0, VAL1,", [r",1, 24,", #-2]") +	TEST_RP(   "strmih	r",14,VAL2,", [r",13,0, ", #2]") +	TEST_RP(   "strh	r",1, VAL1,", [r",2, 24,", #4]!") +	TEST_RP(   "strplh	r",12,VAL2,", [r",11,24,", #-4]!") +	TEST_RP(   "strh	r",2, VAL1,", [r",3, 24,"], #48") +	TEST_RP(   "strh	r",10,VAL2,", [r",9, 64,"], #-48") +	TEST_UNSUPPORTED(".word 0xe1efc3b0	@ strh r12, [pc, #48]!") +	TEST_UNSUPPORTED(".word 0xe0c9f3b0	@ strh pc, [r9], #48") + +	TEST_P(	   "ldrh	r0, [r",0,  24,", #-2]") +	TEST_P(	   "ldrvsh	r14, [r",13,0, ", #2]") +	TEST_P(	   "ldrh	r1, [r",2,  24,", #4]!") +	TEST_P(	   "ldrvch	r12, [r",11,24,", #-4]!") +	TEST_P(	   "ldrh	r2, [r",3,  24,"], #48") +	TEST_P(	   "ldrh	r10, [r",9, 64,"], #-48") +	TEST(      "ldrh	r0, [pc, #0]") +	TEST_UNSUPPORTED(".word 0xe1ffc3b0	@ ldrh r12, [pc, #48]!") +	TEST_UNSUPPORTED(".word 0xe0d9f3b0	@ ldrh pc, [r9], #48") + +	TEST_PR(   "ldrsb	r0, [r",0,  48,", -r",2, 24,"]") +	TEST_PR(   "ldrhisb	r14, [r",13,0,", r",12,  48,"]") +	TEST_PR(   "ldrsb	r1, [r",2,  24,", r",3,  48,"]!") +	TEST_PR(   "ldrlssb	r12, [r",11,48,", -r",10,24,"]!") +	TEST_PR(   "ldrsb	r2, [r",3,  24,"], r",4, 48,"") +	TEST_PR(   "ldrsb	r10, [r",9, 48,"], -r",11,24,"") +	TEST_UNSUPPORTED(".word 0xe1bfc0da	@ ldrsb r12, [pc, r10]!") +	TEST_UNSUPPORTED(".word 0xe099f0db	@ ldrsb pc, [r9], r11") + +	TEST_P(	   "ldrsb	r0, [r",0,  24,", #-1]") +	TEST_P(	   "ldrgesb	r14, [r",13,0, ", #1]") +	TEST_P(	   "ldrsb	r1, [r",2,  24,", #4]!") +	TEST_P(	   "ldrltsb	r12, [r",11,24,", #-4]!") +	TEST_P(	   "ldrsb	r2, [r",3,  24,"], #48") +	TEST_P(	   "ldrsb	r10, [r",9, 64,"], #-48") +	TEST(      "ldrsb	r0, [pc, #0]") +	TEST_UNSUPPORTED(".word 0xe1ffc3d0	@ ldrsb r12, [pc, #48]!") +	TEST_UNSUPPORTED(".word 0xe0d9f3d0	@ ldrsb pc, [r9], #48") + +	TEST_PR(   "ldrsh	r0, [r",0,  48,", -r",2, 24,"]") +	TEST_PR(   "ldrgtsh	r14, [r",13,0, ", r",12, 48,"]") +	TEST_PR(   "ldrsh	r1, [r",2,  24,", r",3,  48,"]!") +	TEST_PR(   "ldrlesh	r12, [r",11,48,", -r",10,24,"]!") +	TEST_PR(   "ldrsh	r2, [r",3,  24,"], r",4, 48,"") +	TEST_PR(   "ldrsh	r10, [r",9, 48,"], -r",11,24,"") +	TEST_UNSUPPORTED(".word 0xe1bfc0fa	@ ldrsh r12, [pc, r10]!") +	TEST_UNSUPPORTED(".word 0xe099f0fb	@ ldrsh pc, [r9], r11") + +	TEST_P(	   "ldrsh	r0, [r",0,  24,", #-1]") +	TEST_P(	   "ldreqsh	r14, [r",13,0 ,", #1]") +	TEST_P(	   "ldrsh	r1, [r",2,  24,", #4]!") +	TEST_P(	   "ldrnesh	r12, [r",11,24,", #-4]!") +	TEST_P(	   "ldrsh	r2, [r",3,  24,"], #48") +	TEST_P(	   "ldrsh	r10, [r",9, 64,"], #-48") +	TEST(      "ldrsh	r0, [pc, #0]") +	TEST_UNSUPPORTED(".word 0xe1ffc3f0	@ ldrsh r12, [pc, #48]!") +	TEST_UNSUPPORTED(".word 0xe0d9f3f0	@ ldrsh pc, [r9], #48") + +#if __LINUX_ARM_ARCH__ >= 7 +	TEST_UNSUPPORTED("strht	r1, [r2], r3") +	TEST_UNSUPPORTED("ldrht	r1, [r2], r3") +	TEST_UNSUPPORTED("strht	r1, [r2], #48") +	TEST_UNSUPPORTED("ldrht	r1, [r2], #48") +	TEST_UNSUPPORTED("ldrsbt	r1, [r2], r3") +	TEST_UNSUPPORTED("ldrsbt	r1, [r2], #48") +	TEST_UNSUPPORTED("ldrsht	r1, [r2], r3") +	TEST_UNSUPPORTED("ldrsht	r1, [r2], #48") +#endif + +	TEST_RPR(  "strd	r",0, VAL1,", [r",1, 48,", -r",2,24,"]") +	TEST_RPR(  "strccd	r",8, VAL2,", [r",13,0, ", r",12,48,"]") +	TEST_RPR(  "strd	r",4, VAL1,", [r",2, 24,", r",3, 48,"]!") +	TEST_RPR(  "strcsd	r",12,VAL2,", [r",11,48,", -r",10,24,"]!") +	TEST_RPR(  "strd	r",2, VAL1,", [r",3, 24,"], r",4,48,"") +	TEST_RPR(  "strd	r",10,VAL2,", [r",9, 48,"], -r",7,24,"") +	TEST_UNSUPPORTED(".word 0xe1afc0fa	@ strd r12, [pc, r10]!") + +	TEST_PR(   "ldrd	r0, [r",0, 48,", -r",2,24,"]") +	TEST_PR(   "ldrmid	r8, [r",13,0, ", r",12,48,"]") +	TEST_PR(   "ldrd	r4, [r",2, 24,", r",3, 48,"]!") +	TEST_PR(   "ldrpld	r6, [r",11,48,", -r",10,24,"]!") +	TEST_PR(   "ldrd	r2, [r",5, 24,"], r",4,48,"") +	TEST_PR(   "ldrd	r10, [r",9,48,"], -r",7,24,"") +	TEST_UNSUPPORTED(".word 0xe1afc0da	@ ldrd r12, [pc, r10]!") +	TEST_UNSUPPORTED(".word 0xe089f0db	@ ldrd pc, [r9], r11") +	TEST_UNSUPPORTED(".word 0xe089e0db	@ ldrd lr, [r9], r11") +	TEST_UNSUPPORTED(".word 0xe089c0df	@ ldrd r12, [r9], pc") + +	TEST_RP(   "strd	r",0, VAL1,", [r",1, 24,", #-8]") +	TEST_RP(   "strvsd	r",8, VAL2,", [r",13,0, ", #8]") +	TEST_RP(   "strd	r",4, VAL1,", [r",2, 24,", #16]!") +	TEST_RP(   "strvcd	r",12,VAL2,", [r",11,24,", #-16]!") +	TEST_RP(   "strd	r",2, VAL1,", [r",4, 24,"], #48") +	TEST_RP(   "strd	r",10,VAL2,", [r",9, 64,"], #-48") +	TEST_UNSUPPORTED(".word 0xe1efc3f0	@ strd r12, [pc, #48]!") + +	TEST_P(	   "ldrd	r0, [r",0, 24,", #-8]") +	TEST_P(	   "ldrhid	r8, [r",13,0, ", #8]") +	TEST_P(	   "ldrd	r4, [r",2, 24,", #16]!") +	TEST_P(	   "ldrlsd	r6, [r",11,24,", #-16]!") +	TEST_P(	   "ldrd	r2, [r",5, 24,"], #48") +	TEST_P(	   "ldrd	r10, [r",9,6,"], #-48") +	TEST_UNSUPPORTED(".word 0xe1efc3d0	@ ldrd r12, [pc, #48]!") +	TEST_UNSUPPORTED(".word 0xe0c9f3d0	@ ldrd pc, [r9], #48") +	TEST_UNSUPPORTED(".word 0xe0c9e3d0	@ ldrd lr, [r9], #48") + +	TEST_GROUP("Miscellaneous") + +#if __LINUX_ARM_ARCH__ >= 7 +	TEST("movw	r0, #0") +	TEST("movw	r0, #0xffff") +	TEST("movw	lr, #0xffff") +	TEST_UNSUPPORTED(".word 0xe300f000	@ movw pc, #0") +	TEST_R("movt	r",0, VAL1,", #0") +	TEST_R("movt	r",0, VAL2,", #0xffff") +	TEST_R("movt	r",14,VAL1,", #0xffff") +	TEST_UNSUPPORTED(".word 0xe340f000	@ movt pc, #0") +#endif + +	TEST_UNSUPPORTED("msr	cpsr, 0x13") +	TEST_UNSUPPORTED("msr	cpsr_f, 0xf0000000") +	TEST_UNSUPPORTED("msr	spsr, 0x13") + +#if __LINUX_ARM_ARCH__ >= 7 +	TEST_SUPPORTED("yield") +	TEST("sev") +	TEST("nop") +	TEST("wfi") +	TEST_SUPPORTED("wfe") +	TEST_UNSUPPORTED("dbg #0") +#endif + +	TEST_GROUP("Load/store word and unsigned byte") + +#define LOAD_STORE(byte)							\ +	TEST_RP( "str"byte"	r",0, VAL1,", [r",1, 24,", #-2]")		\ +	TEST_RP( "str"byte"	r",14,VAL2,", [r",13,0, ", #2]")		\ +	TEST_RP( "str"byte"	r",1, VAL1,", [r",2, 24,", #4]!")		\ +	TEST_RP( "str"byte"	r",12,VAL2,", [r",11,24,", #-4]!")		\ +	TEST_RP( "str"byte"	r",2, VAL1,", [r",3, 24,"], #48")		\ +	TEST_RP( "str"byte"	r",10,VAL2,", [r",9, 64,"], #-48")		\ +	TEST_RPR("str"byte"	r",0, VAL1,", [r",1, 48,", -r",2, 24,"]")	\ +	TEST_RPR("str"byte"	r",14,VAL2,", [r",13,0, ", r",12, 48,"]")	\ +	TEST_RPR("str"byte"	r",1, VAL1,", [r",2, 24,", r",3,  48,"]!")	\ +	TEST_RPR("str"byte"	r",12,VAL2,", [r",11,48,", -r",10,24,"]!")	\ +	TEST_RPR("str"byte"	r",2, VAL1,", [r",3, 24,"], r",4, 48,"")	\ +	TEST_RPR("str"byte"	r",10,VAL2,", [r",9, 48,"], -r",11,24,"")	\ +	TEST_RPR("str"byte"	r",0, VAL1,", [r",1, 24,", r",2,  32,", asl #1]")\ +	TEST_RPR("str"byte"	r",14,VAL2,", [r",13,0, ", r",12, 32,", lsr #2]")\ +	TEST_RPR("str"byte"	r",1, VAL1,", [r",2, 24,", r",3,  32,", asr #3]!")\ +	TEST_RPR("str"byte"	r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\ +	TEST_P(  "ldr"byte"	r0, [r",0,  24,", #-2]")			\ +	TEST_P(  "ldr"byte"	r14, [r",13,0, ", #2]")				\ +	TEST_P(  "ldr"byte"	r1, [r",2,  24,", #4]!")			\ +	TEST_P(  "ldr"byte"	r12, [r",11,24,", #-4]!")			\ +	TEST_P(  "ldr"byte"	r2, [r",3,  24,"], #48")			\ +	TEST_P(  "ldr"byte"	r10, [r",9, 64,"], #-48")			\ +	TEST_PR( "ldr"byte"	r0, [r",0,  48,", -r",2, 24,"]")		\ +	TEST_PR( "ldr"byte"	r14, [r",13,0, ", r",12, 48,"]")		\ +	TEST_PR( "ldr"byte"	r1, [r",2,  24,", r",3, 48,"]!")		\ +	TEST_PR( "ldr"byte"	r12, [r",11,48,", -r",10,24,"]!")		\ +	TEST_PR( "ldr"byte"	r2, [r",3,  24,"], r",4, 48,"")			\ +	TEST_PR( "ldr"byte"	r10, [r",9, 48,"], -r",11,24,"")		\ +	TEST_PR( "ldr"byte"	r0, [r",0,  24,", r",2,  32,", asl #1]")	\ +	TEST_PR( "ldr"byte"	r14, [r",13,0, ", r",12, 32,", lsr #2]")	\ +	TEST_PR( "ldr"byte"	r1, [r",2,  24,", r",3,  32,", asr #3]!")	\ +	TEST_PR( "ldr"byte"	r12, [r",11,24,", r",10, 4,", ror #31]!")	\ +	TEST(    "ldr"byte"	r0, [pc, #0]")					\ +	TEST_R(  "ldr"byte"	r12, [pc, r",14,0,"]") + +	LOAD_STORE("") +	TEST_P(   "str	pc, [r",0,0,", #15*4]") +	TEST_R(   "str	pc, [sp, r",2,15*4,"]") +	TEST_BF(  "ldr	pc, [sp, #15*4]") +	TEST_BF_R("ldr	pc, [sp, r",2,15*4,"]") + +	TEST_P(   "str	sp, [r",0,0,", #13*4]") +	TEST_R(   "str	sp, [sp, r",2,13*4,"]") +	TEST_BF(  "ldr	sp, [sp, #13*4]") +	TEST_BF_R("ldr	sp, [sp, r",2,13*4,"]") + +#ifdef CONFIG_THUMB2_KERNEL +	TEST_ARM_TO_THUMB_INTERWORK_P("ldr	pc, [r",0,0,", #15*4]") +#endif +	TEST_UNSUPPORTED(".word 0xe5af6008	@ str r6, [pc, #8]!") +	TEST_UNSUPPORTED(".word 0xe7af6008	@ str r6, [pc, r8]!") +	TEST_UNSUPPORTED(".word 0xe5bf6008	@ ldr r6, [pc, #8]!") +	TEST_UNSUPPORTED(".word 0xe7bf6008	@ ldr r6, [pc, r8]!") +	TEST_UNSUPPORTED(".word 0xe788600f	@ str r6, [r8, pc]") +	TEST_UNSUPPORTED(".word 0xe798600f	@ ldr r6, [r8, pc]") + +	LOAD_STORE("b") +	TEST_UNSUPPORTED(".word 0xe5f7f008	@ ldrb pc, [r7, #8]!") +	TEST_UNSUPPORTED(".word 0xe7f7f008	@ ldrb pc, [r7, r8]!") +	TEST_UNSUPPORTED(".word 0xe5ef6008	@ strb r6, [pc, #8]!") +	TEST_UNSUPPORTED(".word 0xe7ef6008	@ strb r6, [pc, r3]!") +	TEST_UNSUPPORTED(".word 0xe5ff6008	@ ldrb r6, [pc, #8]!") +	TEST_UNSUPPORTED(".word 0xe7ff6008	@ ldrb r6, [pc, r3]!") + +	TEST_UNSUPPORTED("ldrt	r0, [r1], #4") +	TEST_UNSUPPORTED("ldrt	r1, [r2], r3") +	TEST_UNSUPPORTED("strt	r2, [r3], #4") +	TEST_UNSUPPORTED("strt	r3, [r4], r5") +	TEST_UNSUPPORTED("ldrbt	r4, [r5], #4") +	TEST_UNSUPPORTED("ldrbt	r5, [r6], r7") +	TEST_UNSUPPORTED("strbt	r6, [r7], #4") +	TEST_UNSUPPORTED("strbt	r7, [r8], r9") + +#if __LINUX_ARM_ARCH__ >= 7 +	TEST_GROUP("Parallel addition and subtraction, signed") + +	TEST_UNSUPPORTED(".word 0xe6000010") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe60fffff") /* Unallocated space */ + +	TEST_RR(    "sadd16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "sadd16	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe61cff1a	@ sadd16	pc, r12, r10") +	TEST_RR(    "sasx	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "sasx	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe61cff3a	@ sasx	pc, r12, r10") +	TEST_RR(    "ssax	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "ssax	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe61cff5a	@ ssax	pc, r12, r10") +	TEST_RR(    "ssub16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "ssub16	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe61cff7a	@ ssub16	pc, r12, r10") +	TEST_RR(    "sadd8	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "sadd8	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe61cff9a	@ sadd8	pc, r12, r10") +	TEST_UNSUPPORTED(".word 0xe61000b0") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe61fffbf") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe61000d0") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe61fffdf") /* Unallocated space */ +	TEST_RR(    "ssub8	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "ssub8	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe61cfffa	@ ssub8	pc, r12, r10") + +	TEST_RR(    "qadd16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "qadd16	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe62cff1a	@ qadd16	pc, r12, r10") +	TEST_RR(    "qasx	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "qasx	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe62cff3a	@ qasx	pc, r12, r10") +	TEST_RR(    "qsax	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "qsax	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe62cff5a	@ qsax	pc, r12, r10") +	TEST_RR(    "qsub16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "qsub16	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe62cff7a	@ qsub16	pc, r12, r10") +	TEST_RR(    "qadd8	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "qadd8	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe62cff9a	@ qadd8	pc, r12, r10") +	TEST_UNSUPPORTED(".word 0xe62000b0") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe62fffbf") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe62000d0") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe62fffdf") /* Unallocated space */ +	TEST_RR(    "qsub8	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "qsub8	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe62cfffa	@ qsub8	pc, r12, r10") + +	TEST_RR(    "shadd16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "shadd16	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe63cff1a	@ shadd16	pc, r12, r10") +	TEST_RR(    "shasx	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "shasx	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe63cff3a	@ shasx	pc, r12, r10") +	TEST_RR(    "shsax	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "shsax	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe63cff5a	@ shsax	pc, r12, r10") +	TEST_RR(    "shsub16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "shsub16	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe63cff7a	@ shsub16	pc, r12, r10") +	TEST_RR(    "shadd8	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "shadd8	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe63cff9a	@ shadd8	pc, r12, r10") +	TEST_UNSUPPORTED(".word 0xe63000b0") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe63fffbf") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe63000d0") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe63fffdf") /* Unallocated space */ +	TEST_RR(    "shsub8	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "shsub8	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe63cfffa	@ shsub8	pc, r12, r10") + +	TEST_GROUP("Parallel addition and subtraction, unsigned") + +	TEST_UNSUPPORTED(".word 0xe6400010") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe64fffff") /* Unallocated space */ + +	TEST_RR(    "uadd16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uadd16	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe65cff1a	@ uadd16	pc, r12, r10") +	TEST_RR(    "uasx	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uasx	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe65cff3a	@ uasx	pc, r12, r10") +	TEST_RR(    "usax	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "usax	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe65cff5a	@ usax	pc, r12, r10") +	TEST_RR(    "usub16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "usub16	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe65cff7a	@ usub16	pc, r12, r10") +	TEST_RR(    "uadd8	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uadd8	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe65cff9a	@ uadd8	pc, r12, r10") +	TEST_UNSUPPORTED(".word 0xe65000b0") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe65fffbf") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe65000d0") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe65fffdf") /* Unallocated space */ +	TEST_RR(    "usub8	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "usub8	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe65cfffa	@ usub8	pc, r12, r10") + +	TEST_RR(    "uqadd16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uqadd16	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe66cff1a	@ uqadd16	pc, r12, r10") +	TEST_RR(    "uqasx	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uqasx	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe66cff3a	@ uqasx	pc, r12, r10") +	TEST_RR(    "uqsax	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uqsax	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe66cff5a	@ uqsax	pc, r12, r10") +	TEST_RR(    "uqsub16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uqsub16	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe66cff7a	@ uqsub16	pc, r12, r10") +	TEST_RR(    "uqadd8	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uqadd8	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe66cff9a	@ uqadd8	pc, r12, r10") +	TEST_UNSUPPORTED(".word 0xe66000b0") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe66fffbf") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe66000d0") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe66fffdf") /* Unallocated space */ +	TEST_RR(    "uqsub8	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uqsub8	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe66cfffa	@ uqsub8	pc, r12, r10") + +	TEST_RR(    "uhadd16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uhadd16	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe67cff1a	@ uhadd16	pc, r12, r10") +	TEST_RR(    "uhasx	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uhasx	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe67cff3a	@ uhasx	pc, r12, r10") +	TEST_RR(    "uhsax	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uhsax	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe67cff5a	@ uhsax	pc, r12, r10") +	TEST_RR(    "uhsub16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uhsub16	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe67cff7a	@ uhsub16	pc, r12, r10") +	TEST_RR(    "uhadd8	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uhadd8	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe67cff9a	@ uhadd8	pc, r12, r10") +	TEST_UNSUPPORTED(".word 0xe67000b0") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe67fffbf") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe67000d0") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe67fffdf") /* Unallocated space */ +	TEST_RR(    "uhsub8	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uhsub8	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe67cfffa	@ uhsub8	pc, r12, r10") +	TEST_UNSUPPORTED(".word 0xe67feffa	@ uhsub8	r14, pc, r10") +	TEST_UNSUPPORTED(".word 0xe67cefff	@ uhsub8	r14, r12, pc") +#endif /* __LINUX_ARM_ARCH__ >= 7 */ + +#if __LINUX_ARM_ARCH__ >= 6 +	TEST_GROUP("Packing, unpacking, saturation, and reversal") + +	TEST_RR(    "pkhbt	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "pkhbt	r14,r",12, HH1,", r",10,HH2,", lsl #2") +	TEST_UNSUPPORTED(".word 0xe68cf11a	@ pkhbt	pc, r12, r10, lsl #2") +	TEST_RR(    "pkhtb	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "pkhtb	r14,r",12, HH1,", r",10,HH2,", asr #2") +	TEST_UNSUPPORTED(".word 0xe68cf15a	@ pkhtb	pc, r12, r10, asr #2") +	TEST_UNSUPPORTED(".word 0xe68fe15a	@ pkhtb	r14, pc, r10, asr #2") +	TEST_UNSUPPORTED(".word 0xe68ce15f	@ pkhtb	r14, r12, pc, asr #2") +	TEST_UNSUPPORTED(".word 0xe6900010") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe69fffdf") /* Unallocated space */ + +	TEST_R(     "ssat	r0, #24, r",0,   VAL1,"") +	TEST_R(     "ssat	r14, #24, r",12, VAL2,"") +	TEST_R(     "ssat	r0, #24, r",0,   VAL1,", lsl #8") +	TEST_R(     "ssat	r14, #24, r",12, VAL2,", asr #8") +	TEST_UNSUPPORTED(".word 0xe6b7f01c	@ ssat	pc, #24, r12") + +	TEST_R(     "usat	r0, #24, r",0,   VAL1,"") +	TEST_R(     "usat	r14, #24, r",12, VAL2,"") +	TEST_R(     "usat	r0, #24, r",0,   VAL1,", lsl #8") +	TEST_R(     "usat	r14, #24, r",12, VAL2,", asr #8") +	TEST_UNSUPPORTED(".word 0xe6f7f01c	@ usat	pc, #24, r12") + +	TEST_RR(    "sxtab16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "sxtab16	r14,r",12, HH2,", r",10,HH1,", ror #8") +	TEST_R(     "sxtb16	r8, r",7,  HH1,"") +	TEST_UNSUPPORTED(".word 0xe68cf47a	@ sxtab16	pc,r12, r10, ror #8") + +	TEST_RR(    "sel	r0, r",0,  VAL1,", r",1, VAL2,"") +	TEST_RR(    "sel	r14, r",12,VAL1,", r",10, VAL2,"") +	TEST_UNSUPPORTED(".word 0xe68cffba	@ sel	pc, r12, r10") +	TEST_UNSUPPORTED(".word 0xe68fefba	@ sel	r14, pc, r10") +	TEST_UNSUPPORTED(".word 0xe68cefbf	@ sel	r14, r12, pc") + +	TEST_R(     "ssat16	r0, #12, r",0,   HH1,"") +	TEST_R(     "ssat16	r14, #12, r",12, HH2,"") +	TEST_UNSUPPORTED(".word 0xe6abff3c	@ ssat16	pc, #12, r12") + +	TEST_RR(    "sxtab	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "sxtab	r14,r",12, HH2,", r",10,HH1,", ror #8") +	TEST_R(     "sxtb	r8, r",7,  HH1,"") +	TEST_UNSUPPORTED(".word 0xe6acf47a	@ sxtab	pc,r12, r10, ror #8") + +	TEST_R(     "rev	r0, r",0,   VAL1,"") +	TEST_R(     "rev	r14, r",12, VAL2,"") +	TEST_UNSUPPORTED(".word 0xe6bfff3c	@ rev	pc, r12") + +	TEST_RR(    "sxtah	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "sxtah	r14,r",12, HH2,", r",10,HH1,", ror #8") +	TEST_R(     "sxth	r8, r",7,  HH1,"") +	TEST_UNSUPPORTED(".word 0xe6bcf47a	@ sxtah	pc,r12, r10, ror #8") + +	TEST_R(     "rev16	r0, r",0,   VAL1,"") +	TEST_R(     "rev16	r14, r",12, VAL2,"") +	TEST_UNSUPPORTED(".word 0xe6bfffbc	@ rev16	pc, r12") + +	TEST_RR(    "uxtab16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uxtab16	r14,r",12, HH2,", r",10,HH1,", ror #8") +	TEST_R(     "uxtb16	r8, r",7,  HH1,"") +	TEST_UNSUPPORTED(".word 0xe6ccf47a	@ uxtab16	pc,r12, r10, ror #8") + +	TEST_R(     "usat16	r0, #12, r",0,   HH1,"") +	TEST_R(     "usat16	r14, #12, r",12, HH2,"") +	TEST_UNSUPPORTED(".word 0xe6ecff3c	@ usat16	pc, #12, r12") +	TEST_UNSUPPORTED(".word 0xe6ecef3f	@ usat16	r14, #12, pc") + +	TEST_RR(    "uxtab	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uxtab	r14,r",12, HH2,", r",10,HH1,", ror #8") +	TEST_R(     "uxtb	r8, r",7,  HH1,"") +	TEST_UNSUPPORTED(".word 0xe6ecf47a	@ uxtab	pc,r12, r10, ror #8") + +#if __LINUX_ARM_ARCH__ >= 7 +	TEST_R(     "rbit	r0, r",0,   VAL1,"") +	TEST_R(     "rbit	r14, r",12, VAL2,"") +	TEST_UNSUPPORTED(".word 0xe6ffff3c	@ rbit	pc, r12") +#endif + +	TEST_RR(    "uxtah	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uxtah	r14,r",12, HH2,", r",10,HH1,", ror #8") +	TEST_R(     "uxth	r8, r",7,  HH1,"") +	TEST_UNSUPPORTED(".word 0xe6fff077	@ uxth	pc, r7") +	TEST_UNSUPPORTED(".word 0xe6ff807f	@ uxth	r8, pc") +	TEST_UNSUPPORTED(".word 0xe6fcf47a	@ uxtah	pc, r12, r10, ror #8") +	TEST_UNSUPPORTED(".word 0xe6fce47f	@ uxtah	r14, r12, pc, ror #8") + +	TEST_R(     "revsh	r0, r",0,   VAL1,"") +	TEST_R(     "revsh	r14, r",12, VAL2,"") +	TEST_UNSUPPORTED(".word 0xe6ffff3c	@ revsh	pc, r12") +	TEST_UNSUPPORTED(".word 0xe6ffef3f	@ revsh	r14, pc") + +	TEST_UNSUPPORTED(".word 0xe6900070") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe69fff7f") /* Unallocated space */ + +	TEST_UNSUPPORTED(".word 0xe6d00070") /* Unallocated space */ +	TEST_UNSUPPORTED(".word 0xe6dfff7f") /* Unallocated space */ +#endif /* __LINUX_ARM_ARCH__ >= 6 */ + +#if __LINUX_ARM_ARCH__ >= 6 +	TEST_GROUP("Signed multiplies") + +	TEST_RRR(   "smlad	r0, r",0,  HH1,", r",1, HH2,", r",2, VAL1,"") +	TEST_RRR(   "smlad	r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"") +	TEST_UNSUPPORTED(".word 0xe70f8a1c	@ smlad	pc, r12, r10, r8") +	TEST_RRR(   "smladx	r0, r",0,  HH1,", r",1, HH2,", r",2, VAL1,"") +	TEST_RRR(   "smladx	r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"") +	TEST_UNSUPPORTED(".word 0xe70f8a3c	@ smladx	pc, r12, r10, r8") + +	TEST_RR(   "smuad	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(   "smuad	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe70ffa1c	@ smuad	pc, r12, r10") +	TEST_RR(   "smuadx	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(   "smuadx	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe70ffa3c	@ smuadx	pc, r12, r10") + +	TEST_RRR(   "smlsd	r0, r",0,  HH1,", r",1, HH2,", r",2, VAL1,"") +	TEST_RRR(   "smlsd	r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"") +	TEST_UNSUPPORTED(".word 0xe70f8a5c	@ smlsd	pc, r12, r10, r8") +	TEST_RRR(   "smlsdx	r0, r",0,  HH1,", r",1, HH2,", r",2, VAL1,"") +	TEST_RRR(   "smlsdx	r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"") +	TEST_UNSUPPORTED(".word 0xe70f8a7c	@ smlsdx	pc, r12, r10, r8") + +	TEST_RR(   "smusd	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(   "smusd	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe70ffa5c	@ smusd	pc, r12, r10") +	TEST_RR(   "smusdx	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(   "smusdx	r14, r",12,HH2,", r",10,HH1,"") +	TEST_UNSUPPORTED(".word 0xe70ffa7c	@ smusdx	pc, r12, r10") + +	TEST_RRRR( "smlald	r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2) +	TEST_RRRR( "smlald	r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1) +	TEST_UNSUPPORTED(".word 0xe74af819	@ smlald	pc, r10, r9, r8") +	TEST_UNSUPPORTED(".word 0xe74fb819	@ smlald	r11, pc, r9, r8") +	TEST_UNSUPPORTED(".word 0xe74ab81f	@ smlald	r11, r10, pc, r8") +	TEST_UNSUPPORTED(".word 0xe74abf19	@ smlald	r11, r10, r9, pc") + +	TEST_RRRR( "smlaldx	r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2) +	TEST_RRRR( "smlaldx	r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1) +	TEST_UNSUPPORTED(".word 0xe74af839	@ smlaldx	pc, r10, r9, r8") +	TEST_UNSUPPORTED(".word 0xe74fb839	@ smlaldx	r11, pc, r9, r8") + +	TEST_RRR(  "smmla	r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL1,"") +	TEST_RRR(  "smmla	r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"") +	TEST_UNSUPPORTED(".word 0xe75f8a1c	@ smmla	pc, r12, r10, r8") +	TEST_RRR(  "smmlar	r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL1,"") +	TEST_RRR(  "smmlar	r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"") +	TEST_UNSUPPORTED(".word 0xe75f8a3c	@ smmlar	pc, r12, r10, r8") + +	TEST_RR(   "smmul	r0, r",0,  VAL1,", r",1, VAL2,"") +	TEST_RR(   "smmul	r14, r",12,VAL2,", r",10,VAL1,"") +	TEST_UNSUPPORTED(".word 0xe75ffa1c	@ smmul	pc, r12, r10") +	TEST_RR(   "smmulr	r0, r",0,  VAL1,", r",1, VAL2,"") +	TEST_RR(   "smmulr	r14, r",12,VAL2,", r",10,VAL1,"") +	TEST_UNSUPPORTED(".word 0xe75ffa3c	@ smmulr	pc, r12, r10") + +	TEST_RRR(  "smmls	r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL1,"") +	TEST_RRR(  "smmls	r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"") +	TEST_UNSUPPORTED(".word 0xe75f8adc	@ smmls	pc, r12, r10, r8") +	TEST_RRR(  "smmlsr	r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL1,"") +	TEST_RRR(  "smmlsr	r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"") +	TEST_UNSUPPORTED(".word 0xe75f8afc	@ smmlsr	pc, r12, r10, r8") +	TEST_UNSUPPORTED(".word 0xe75e8aff	@ smmlsr	r14, pc, r10, r8") +	TEST_UNSUPPORTED(".word 0xe75e8ffc	@ smmlsr	r14, r12, pc, r8") +	TEST_UNSUPPORTED(".word 0xe75efafc	@ smmlsr	r14, r12, r10, pc") + +	TEST_RR(   "usad8	r0, r",0,  VAL1,", r",1, VAL2,"") +	TEST_RR(   "usad8	r14, r",12,VAL2,", r",10,VAL1,"") +	TEST_UNSUPPORTED(".word 0xe75ffa1c	@ usad8	pc, r12, r10") +	TEST_UNSUPPORTED(".word 0xe75efa1f	@ usad8	r14, pc, r10") +	TEST_UNSUPPORTED(".word 0xe75eff1c	@ usad8	r14, r12, pc") + +	TEST_RRR(  "usada8	r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL3,"") +	TEST_RRR(  "usada8	r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL3,"") +	TEST_UNSUPPORTED(".word 0xe78f8a1c	@ usada8	pc, r12, r10, r8") +	TEST_UNSUPPORTED(".word 0xe78e8a1f	@ usada8	r14, pc, r10, r8") +	TEST_UNSUPPORTED(".word 0xe78e8f1c	@ usada8	r14, r12, pc, r8") +#endif /* __LINUX_ARM_ARCH__ >= 6 */ + +#if __LINUX_ARM_ARCH__ >= 7 +	TEST_GROUP("Bit Field") + +	TEST_R(     "sbfx	r0, r",0  , VAL1,", #0, #31") +	TEST_R(     "sbfxeq	r14, r",12, VAL2,", #8, #16") +	TEST_R(     "sbfx	r4, r",10,  VAL1,", #16, #15") +	TEST_UNSUPPORTED(".word 0xe7aff45c	@ sbfx	pc, r12, #8, #16") + +	TEST_R(     "ubfx	r0, r",0  , VAL1,", #0, #31") +	TEST_R(     "ubfxcs	r14, r",12, VAL2,", #8, #16") +	TEST_R(     "ubfx	r4, r",10,  VAL1,", #16, #15") +	TEST_UNSUPPORTED(".word 0xe7eff45c	@ ubfx	pc, r12, #8, #16") +	TEST_UNSUPPORTED(".word 0xe7efc45f	@ ubfx	r12, pc, #8, #16") + +	TEST_R(     "bfc	r",0, VAL1,", #4, #20") +	TEST_R(     "bfcvs	r",14,VAL2,", #4, #20") +	TEST_R(     "bfc	r",7, VAL1,", #0, #31") +	TEST_R(     "bfc	r",8, VAL2,", #0, #31") +	TEST_UNSUPPORTED(".word 0xe7def01f	@ bfc	pc, #0, #31"); + +	TEST_RR(    "bfi	r",0, VAL1,", r",0  , VAL2,", #0, #31") +	TEST_RR(    "bfipl	r",12,VAL1,", r",14 , VAL2,", #4, #20") +	TEST_UNSUPPORTED(".word 0xe7d7f21e	@ bfi	pc, r14, #4, #20") + +	TEST_UNSUPPORTED(".word 0x07f000f0")  /* Permanently UNDEFINED */ +	TEST_UNSUPPORTED(".word 0x07ffffff")  /* Permanently UNDEFINED */ +#endif /* __LINUX_ARM_ARCH__ >= 6 */ + +	TEST_GROUP("Branch, branch with link, and block data transfer") + +	TEST_P(   "stmda	r",0, 16*4,", {r0}") +	TEST_P(   "stmeqda	r",4, 16*4,", {r0-r15}") +	TEST_P(   "stmneda	r",8, 16*4,"!, {r8-r15}") +	TEST_P(   "stmda	r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") +	TEST_P(   "stmda	r",13,0,   "!, {pc}") + +	TEST_P(   "ldmda	r",0, 16*4,", {r0}") +	TEST_BF_P("ldmcsda	r",4, 15*4,", {r0-r15}") +	TEST_BF_P("ldmccda	r",7, 15*4,"!, {r8-r15}") +	TEST_P(   "ldmda	r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") +	TEST_BF_P("ldmda	r",14,15*4,"!, {pc}") + +	TEST_P(   "stmia	r",0, 16*4,", {r0}") +	TEST_P(   "stmmiia	r",4, 16*4,", {r0-r15}") +	TEST_P(   "stmplia	r",8, 16*4,"!, {r8-r15}") +	TEST_P(   "stmia	r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") +	TEST_P(   "stmia	r",14,0,   "!, {pc}") + +	TEST_P(   "ldmia	r",0, 16*4,", {r0}") +	TEST_BF_P("ldmvsia	r",4, 0,   ", {r0-r15}") +	TEST_BF_P("ldmvcia	r",7, 8*4, "!, {r8-r15}") +	TEST_P(   "ldmia	r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") +	TEST_BF_P("ldmia	r",14,15*4,"!, {pc}") + +	TEST_P(   "stmdb	r",0, 16*4,", {r0}") +	TEST_P(   "stmhidb	r",4, 16*4,", {r0-r15}") +	TEST_P(   "stmlsdb	r",8, 16*4,"!, {r8-r15}") +	TEST_P(   "stmdb	r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") +	TEST_P(   "stmdb	r",13,4,   "!, {pc}") + +	TEST_P(   "ldmdb	r",0, 16*4,", {r0}") +	TEST_BF_P("ldmgedb	r",4, 16*4,", {r0-r15}") +	TEST_BF_P("ldmltdb	r",7, 16*4,"!, {r8-r15}") +	TEST_P(   "ldmdb	r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") +	TEST_BF_P("ldmdb	r",14,16*4,"!, {pc}") + +	TEST_P(   "stmib	r",0, 16*4,", {r0}") +	TEST_P(   "stmgtib	r",4, 16*4,", {r0-r15}") +	TEST_P(   "stmleib	r",8, 16*4,"!, {r8-r15}") +	TEST_P(   "stmib	r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") +	TEST_P(   "stmib	r",13,-4,  "!, {pc}") + +	TEST_P(   "ldmib	r",0, 16*4,", {r0}") +	TEST_BF_P("ldmeqib	r",4, -4,", {r0-r15}") +	TEST_BF_P("ldmneib	r",7, 7*4,"!, {r8-r15}") +	TEST_P(   "ldmib	r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") +	TEST_BF_P("ldmib	r",14,14*4,"!, {pc}") + +	TEST_P(   "stmdb	r",13,16*4,"!, {r3-r12,lr}") +	TEST_P(	  "stmeqdb	r",13,16*4,"!, {r3-r12}") +	TEST_P(   "stmnedb	r",2, 16*4,", {r3-r12,lr}") +	TEST_P(   "stmdb	r",13,16*4,"!, {r2-r12,lr}") +	TEST_P(   "stmdb	r",0, 16*4,", {r0-r12}") +	TEST_P(   "stmdb	r",0, 16*4,", {r0-r12,lr}") + +	TEST_BF_P("ldmia	r",13,5*4, "!, {r3-r12,pc}") +	TEST_P(	  "ldmccia	r",13,5*4, "!, {r3-r12}") +	TEST_BF_P("ldmcsia	r",2, 5*4, "!, {r3-r12,pc}") +	TEST_BF_P("ldmia	r",13,4*4, "!, {r2-r12,pc}") +	TEST_P(   "ldmia	r",0, 16*4,", {r0-r12}") +	TEST_P(   "ldmia	r",0, 16*4,", {r0-r12,lr}") + +#ifdef CONFIG_THUMB2_KERNEL +	TEST_ARM_TO_THUMB_INTERWORK_P("ldmplia	r",0,15*4,", {pc}") +	TEST_ARM_TO_THUMB_INTERWORK_P("ldmmiia	r",13,0,", {r0-r15}") +#endif +	TEST_BF("b	2f") +	TEST_BF("bl	2f") +	TEST_BB("b	2b") +	TEST_BB("bl	2b") + +	TEST_BF("beq	2f") +	TEST_BF("bleq	2f") +	TEST_BB("bne	2b") +	TEST_BB("blne	2b") + +	TEST_BF("bgt	2f") +	TEST_BF("blgt	2f") +	TEST_BB("blt	2b") +	TEST_BB("bllt	2b") + +	TEST_GROUP("Supervisor Call, and coprocessor instructions") + +	/* +	 * We can't really test these by executing them, so all +	 * we can do is check that probes are, or are not allowed. +	 * At the moment none are allowed... +	 */ +#define TEST_COPROCESSOR(code) TEST_UNSUPPORTED(code) + +#define COPROCESSOR_INSTRUCTIONS_ST_LD(two,cc)					\ +	TEST_COPROCESSOR("stc"two"	0, cr0, [r13, #4]")			\ +	TEST_COPROCESSOR("stc"two"	0, cr0, [r13, #-4]")			\ +	TEST_COPROCESSOR("stc"two"	0, cr0, [r13, #4]!")			\ +	TEST_COPROCESSOR("stc"two"	0, cr0, [r13, #-4]!")			\ +	TEST_COPROCESSOR("stc"two"	0, cr0, [r13], #4")			\ +	TEST_COPROCESSOR("stc"two"	0, cr0, [r13], #-4")			\ +	TEST_COPROCESSOR("stc"two"	0, cr0, [r13], {1}")			\ +	TEST_COPROCESSOR("stc"two"l	0, cr0, [r13, #4]")			\ +	TEST_COPROCESSOR("stc"two"l	0, cr0, [r13, #-4]")			\ +	TEST_COPROCESSOR("stc"two"l	0, cr0, [r13, #4]!")			\ +	TEST_COPROCESSOR("stc"two"l	0, cr0, [r13, #-4]!")			\ +	TEST_COPROCESSOR("stc"two"l	0, cr0, [r13], #4")			\ +	TEST_COPROCESSOR("stc"two"l	0, cr0, [r13], #-4")			\ +	TEST_COPROCESSOR("stc"two"l	0, cr0, [r13], {1}")			\ +	TEST_COPROCESSOR("ldc"two"	0, cr0, [r13, #4]")			\ +	TEST_COPROCESSOR("ldc"two"	0, cr0, [r13, #-4]")			\ +	TEST_COPROCESSOR("ldc"two"	0, cr0, [r13, #4]!")			\ +	TEST_COPROCESSOR("ldc"two"	0, cr0, [r13, #-4]!")			\ +	TEST_COPROCESSOR("ldc"two"	0, cr0, [r13], #4")			\ +	TEST_COPROCESSOR("ldc"two"	0, cr0, [r13], #-4")			\ +	TEST_COPROCESSOR("ldc"two"	0, cr0, [r13], {1}")			\ +	TEST_COPROCESSOR("ldc"two"l	0, cr0, [r13, #4]")			\ +	TEST_COPROCESSOR("ldc"two"l	0, cr0, [r13, #-4]")			\ +	TEST_COPROCESSOR("ldc"two"l	0, cr0, [r13, #4]!")			\ +	TEST_COPROCESSOR("ldc"two"l	0, cr0, [r13, #-4]!")			\ +	TEST_COPROCESSOR("ldc"two"l	0, cr0, [r13], #4")			\ +	TEST_COPROCESSOR("ldc"two"l	0, cr0, [r13], #-4")			\ +	TEST_COPROCESSOR("ldc"two"l	0, cr0, [r13], {1}")			\ +										\ +	TEST_COPROCESSOR( "stc"two"	0, cr0, [r15, #4]")			\ +	TEST_COPROCESSOR( "stc"two"	0, cr0, [r15, #-4]")			\ +	TEST_UNSUPPORTED(".word 0x"cc"daf0001	@ stc"two"	0, cr0, [r15, #4]!")	\ +	TEST_UNSUPPORTED(".word 0x"cc"d2f0001	@ stc"two"	0, cr0, [r15, #-4]!")	\ +	TEST_UNSUPPORTED(".word 0x"cc"caf0001	@ stc"two"	0, cr0, [r15], #4")	\ +	TEST_UNSUPPORTED(".word 0x"cc"c2f0001	@ stc"two"	0, cr0, [r15], #-4")	\ +	TEST_COPROCESSOR( "stc"two"	0, cr0, [r15], {1}")			\ +	TEST_COPROCESSOR( "stc"two"l	0, cr0, [r15, #4]")			\ +	TEST_COPROCESSOR( "stc"two"l	0, cr0, [r15, #-4]")			\ +	TEST_UNSUPPORTED(".word 0x"cc"def0001	@ stc"two"l	0, cr0, [r15, #4]!")	\ +	TEST_UNSUPPORTED(".word 0x"cc"d6f0001	@ stc"two"l	0, cr0, [r15, #-4]!")	\ +	TEST_UNSUPPORTED(".word 0x"cc"cef0001	@ stc"two"l	0, cr0, [r15], #4")	\ +	TEST_UNSUPPORTED(".word 0x"cc"c6f0001	@ stc"two"l	0, cr0, [r15], #-4")	\ +	TEST_COPROCESSOR( "stc"two"l	0, cr0, [r15], {1}")			\ +	TEST_COPROCESSOR( "ldc"two"	0, cr0, [r15, #4]")			\ +	TEST_COPROCESSOR( "ldc"two"	0, cr0, [r15, #-4]")			\ +	TEST_UNSUPPORTED(".word 0x"cc"dbf0001	@ ldc"two"	0, cr0, [r15, #4]!")	\ +	TEST_UNSUPPORTED(".word 0x"cc"d3f0001	@ ldc"two"	0, cr0, [r15, #-4]!")	\ +	TEST_UNSUPPORTED(".word 0x"cc"cbf0001	@ ldc"two"	0, cr0, [r15], #4")	\ +	TEST_UNSUPPORTED(".word 0x"cc"c3f0001	@ ldc"two"	0, cr0, [r15], #-4")	\ +	TEST_COPROCESSOR( "ldc"two"	0, cr0, [r15], {1}")			\ +	TEST_COPROCESSOR( "ldc"two"l	0, cr0, [r15, #4]")			\ +	TEST_COPROCESSOR( "ldc"two"l	0, cr0, [r15, #-4]")			\ +	TEST_UNSUPPORTED(".word 0x"cc"dff0001	@ ldc"two"l	0, cr0, [r15, #4]!")	\ +	TEST_UNSUPPORTED(".word 0x"cc"d7f0001	@ ldc"two"l	0, cr0, [r15, #-4]!")	\ +	TEST_UNSUPPORTED(".word 0x"cc"cff0001	@ ldc"two"l	0, cr0, [r15], #4")	\ +	TEST_UNSUPPORTED(".word 0x"cc"c7f0001	@ ldc"two"l	0, cr0, [r15], #-4")	\ +	TEST_COPROCESSOR( "ldc"two"l	0, cr0, [r15], {1}") + +#define COPROCESSOR_INSTRUCTIONS_MC_MR(two,cc)					\ +										\ +	TEST_COPROCESSOR( "mcrr"two"	0, 15, r0, r14, cr0")			\ +	TEST_COPROCESSOR( "mcrr"two"	15, 0, r14, r0, cr15")			\ +	TEST_UNSUPPORTED(".word 0x"cc"c4f00f0	@ mcrr"two"	0, 15, r0, r15, cr0")	\ +	TEST_UNSUPPORTED(".word 0x"cc"c40ff0f	@ mcrr"two"	15, 0, r15, r0, cr15")	\ +	TEST_COPROCESSOR( "mrrc"two"	0, 15, r0, r14, cr0")			\ +	TEST_COPROCESSOR( "mrrc"two"	15, 0, r14, r0, cr15")			\ +	TEST_UNSUPPORTED(".word 0x"cc"c5f00f0	@ mrrc"two"	0, 15, r0, r15, cr0")	\ +	TEST_UNSUPPORTED(".word 0x"cc"c50ff0f	@ mrrc"two"	15, 0, r15, r0, cr15")	\ +	TEST_COPROCESSOR( "cdp"two"	15, 15, cr15, cr15, cr15, 7")		\ +	TEST_COPROCESSOR( "cdp"two"	0, 0, cr0, cr0, cr0, 0")		\ +	TEST_COPROCESSOR( "mcr"two"	15, 7, r15, cr15, cr15, 7")		\ +	TEST_COPROCESSOR( "mcr"two"	0, 0, r0, cr0, cr0, 0")			\ +	TEST_COPROCESSOR( "mrc"two"	15, 7, r15, cr15, cr15, 7")		\ +	TEST_COPROCESSOR( "mrc"two"	0, 0, r0, cr0, cr0, 0") + +	COPROCESSOR_INSTRUCTIONS_ST_LD("","e") +	COPROCESSOR_INSTRUCTIONS_MC_MR("","e") +	TEST_UNSUPPORTED("svc	0") +	TEST_UNSUPPORTED("svc	0xffffff") + +	TEST_UNSUPPORTED("svc	0") + +	TEST_GROUP("Unconditional instruction") + +#if __LINUX_ARM_ARCH__ >= 6 +	TEST_UNSUPPORTED("srsda	sp, 0x13") +	TEST_UNSUPPORTED("srsdb	sp, 0x13") +	TEST_UNSUPPORTED("srsia	sp, 0x13") +	TEST_UNSUPPORTED("srsib	sp, 0x13") +	TEST_UNSUPPORTED("srsda	sp!, 0x13") +	TEST_UNSUPPORTED("srsdb	sp!, 0x13") +	TEST_UNSUPPORTED("srsia	sp!, 0x13") +	TEST_UNSUPPORTED("srsib	sp!, 0x13") + +	TEST_UNSUPPORTED("rfeda	sp") +	TEST_UNSUPPORTED("rfedb	sp") +	TEST_UNSUPPORTED("rfeia	sp") +	TEST_UNSUPPORTED("rfeib	sp") +	TEST_UNSUPPORTED("rfeda	sp!") +	TEST_UNSUPPORTED("rfedb	sp!") +	TEST_UNSUPPORTED("rfeia	sp!") +	TEST_UNSUPPORTED("rfeib	sp!") +	TEST_UNSUPPORTED(".word 0xf81d0a00	@ rfeda	pc") +	TEST_UNSUPPORTED(".word 0xf91d0a00	@ rfedb	pc") +	TEST_UNSUPPORTED(".word 0xf89d0a00	@ rfeia	pc") +	TEST_UNSUPPORTED(".word 0xf99d0a00	@ rfeib	pc") +	TEST_UNSUPPORTED(".word 0xf83d0a00	@ rfeda	pc!") +	TEST_UNSUPPORTED(".word 0xf93d0a00	@ rfedb	pc!") +	TEST_UNSUPPORTED(".word 0xf8bd0a00	@ rfeia	pc!") +	TEST_UNSUPPORTED(".word 0xf9bd0a00	@ rfeib	pc!") +#endif /* __LINUX_ARM_ARCH__ >= 6 */ + +#if __LINUX_ARM_ARCH__ >= 6 +	TEST_X(	"blx	__dummy_thumb_subroutine_even", +		".thumb				\n\t" +		".space 4			\n\t" +		".type __dummy_thumb_subroutine_even, %%function \n\t" +		"__dummy_thumb_subroutine_even:	\n\t" +		"mov	r0, pc			\n\t" +		"bx	lr			\n\t" +		".arm				\n\t" +	) +	TEST(	"blx	__dummy_thumb_subroutine_even") + +	TEST_X(	"blx	__dummy_thumb_subroutine_odd", +		".thumb				\n\t" +		".space 2			\n\t" +		".type __dummy_thumb_subroutine_odd, %%function	\n\t" +		"__dummy_thumb_subroutine_odd:	\n\t" +		"mov	r0, pc			\n\t" +		"bx	lr			\n\t" +		".arm				\n\t" +	) +	TEST(	"blx	__dummy_thumb_subroutine_odd") +#endif /* __LINUX_ARM_ARCH__ >= 6 */ + +	COPROCESSOR_INSTRUCTIONS_ST_LD("2","f") +#if __LINUX_ARM_ARCH__ >= 6 +	COPROCESSOR_INSTRUCTIONS_MC_MR("2","f") +#endif + +	TEST_GROUP("Miscellaneous instructions, memory hints, and Advanced SIMD instructions") + +#if __LINUX_ARM_ARCH__ >= 6 +	TEST_UNSUPPORTED("cps	0x13") +	TEST_UNSUPPORTED("cpsie	i") +	TEST_UNSUPPORTED("cpsid	i") +	TEST_UNSUPPORTED("cpsie	i,0x13") +	TEST_UNSUPPORTED("cpsid	i,0x13") +	TEST_UNSUPPORTED("setend	le") +	TEST_UNSUPPORTED("setend	be") +#endif + +#if __LINUX_ARM_ARCH__ >= 7 +	TEST_P("pli	[r",0,0b,", #16]") +	TEST(  "pli	[pc, #0]") +	TEST_RR("pli	[r",12,0b,", r",0, 16,"]") +	TEST_RR("pli	[r",0, 0b,", -r",12,16,", lsl #4]") +#endif + +#if __LINUX_ARM_ARCH__ >= 5 +	TEST_P("pld	[r",0,32,", #-16]") +	TEST(  "pld	[pc, #0]") +	TEST_PR("pld	[r",7, 24, ", r",0, 16,"]") +	TEST_PR("pld	[r",8, 24, ", -r",12,16,", lsl #4]") +#endif + +#if __LINUX_ARM_ARCH__ >= 7 +	TEST_SUPPORTED(  ".word 0xf590f000	@ pldw [r0, #0]") +	TEST_SUPPORTED(  ".word 0xf797f000	@ pldw	[r7, r0]") +	TEST_SUPPORTED(  ".word 0xf798f18c	@ pldw	[r8, r12, lsl #3]"); +#endif + +#if __LINUX_ARM_ARCH__ >= 7 +	TEST_UNSUPPORTED("clrex") +	TEST_UNSUPPORTED("dsb") +	TEST_UNSUPPORTED("dmb") +	TEST_UNSUPPORTED("isb") +#endif + +	verbose("\n"); +} + diff --git a/arch/arm/kernel/kprobes-test-thumb.c b/arch/arm/kernel/kprobes-test-thumb.c new file mode 100644 index 00000000000..5e726c31c45 --- /dev/null +++ b/arch/arm/kernel/kprobes-test-thumb.c @@ -0,0 +1,1187 @@ +/* + * arch/arm/kernel/kprobes-test-thumb.c + * + * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. + * + * 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/kernel.h> +#include <linux/module.h> + +#include "kprobes-test.h" + + +#define TEST_ISA "16" + +#define DONT_TEST_IN_ITBLOCK(tests)			\ +	kprobe_test_flags |= TEST_FLAG_NO_ITBLOCK;	\ +	tests						\ +	kprobe_test_flags &= ~TEST_FLAG_NO_ITBLOCK; + +#define CONDITION_INSTRUCTIONS(cc_pos, tests)		\ +	kprobe_test_cc_position = cc_pos;		\ +	DONT_TEST_IN_ITBLOCK(tests)			\ +	kprobe_test_cc_position = 0; + +#define TEST_ITBLOCK(code)				\ +	kprobe_test_flags |= TEST_FLAG_FULL_ITBLOCK;	\ +	TESTCASE_START(code)				\ +	TEST_ARG_END("")				\ +	"50:	nop			\n\t"		\ +	"1:	"code"			\n\t"		\ +	"	mov r1, #0x11		\n\t"		\ +	"	mov r2, #0x22		\n\t"		\ +	"	mov r3, #0x33		\n\t"		\ +	"2:	nop			\n\t"		\ +	TESTCASE_END					\ +	kprobe_test_flags &= ~TEST_FLAG_FULL_ITBLOCK; + +#define TEST_THUMB_TO_ARM_INTERWORK_P(code1, reg, val, code2)	\ +	TESTCASE_START(code1 #reg code2)			\ +	TEST_ARG_PTR(reg, val)					\ +	TEST_ARG_REG(14, 99f+1)					\ +	TEST_ARG_MEM(15, 3f)					\ +	TEST_ARG_END("")					\ +	"	nop			\n\t" /* To align 1f */	\ +	"50:	nop			\n\t"			\ +	"1:	"code1 #reg code2"	\n\t"			\ +	"	bx	lr		\n\t"			\ +	".arm				\n\t"			\ +	"3:	adr	lr, 2f+1	\n\t"			\ +	"	bx	lr		\n\t"			\ +	".thumb				\n\t"			\ +	"2:	nop			\n\t"			\ +	TESTCASE_END + + +void kprobe_thumb16_test_cases(void) +{ +	kprobe_test_flags = TEST_FLAG_NARROW_INSTR; + +	TEST_GROUP("Shift (immediate), add, subtract, move, and compare") + +	TEST_R(    "lsls	r7, r",0,VAL1,", #5") +	TEST_R(    "lsls	r0, r",7,VAL2,", #11") +	TEST_R(    "lsrs	r7, r",0,VAL1,", #5") +	TEST_R(    "lsrs	r0, r",7,VAL2,", #11") +	TEST_R(    "asrs	r7, r",0,VAL1,", #5") +	TEST_R(    "asrs	r0, r",7,VAL2,", #11") +	TEST_RR(   "adds	r2, r",0,VAL1,", r",7,VAL2,"") +	TEST_RR(   "adds	r5, r",7,VAL2,", r",0,VAL2,"") +	TEST_RR(   "subs	r2, r",0,VAL1,", r",7,VAL2,"") +	TEST_RR(   "subs	r5, r",7,VAL2,", r",0,VAL2,"") +	TEST_R(    "adds	r7, r",0,VAL1,", #5") +	TEST_R(    "adds	r0, r",7,VAL2,", #2") +	TEST_R(    "subs	r7, r",0,VAL1,", #5") +	TEST_R(    "subs	r0, r",7,VAL2,", #2") +	TEST(      "movs.n	r0, #0x5f") +	TEST(      "movs.n	r7, #0xa0") +	TEST_R(    "cmp.n	r",0,0x5e, ", #0x5f") +	TEST_R(    "cmp.n	r",5,0x15f,", #0x5f") +	TEST_R(    "cmp.n	r",7,0xa0, ", #0xa0") +	TEST_R(    "adds.n	r",0,VAL1,", #0x5f") +	TEST_R(    "adds.n	r",7,VAL2,", #0xa0") +	TEST_R(    "subs.n	r",0,VAL1,", #0x5f") +	TEST_R(    "subs.n	r",7,VAL2,", #0xa0") + +	TEST_GROUP("16-bit Thumb data-processing instructions") + +#define DATA_PROCESSING16(op,val)			\ +	TEST_RR(   op"	r",0,VAL1,", r",7,val,"")	\ +	TEST_RR(   op"	r",7,VAL2,", r",0,val,"") + +	DATA_PROCESSING16("ands",0xf00f00ff) +	DATA_PROCESSING16("eors",0xf00f00ff) +	DATA_PROCESSING16("lsls",11) +	DATA_PROCESSING16("lsrs",11) +	DATA_PROCESSING16("asrs",11) +	DATA_PROCESSING16("adcs",VAL2) +	DATA_PROCESSING16("sbcs",VAL2) +	DATA_PROCESSING16("rors",11) +	DATA_PROCESSING16("tst",0xf00f00ff) +	TEST_R("rsbs	r",0,VAL1,", #0") +	TEST_R("rsbs	r",7,VAL2,", #0") +	DATA_PROCESSING16("cmp",0xf00f00ff) +	DATA_PROCESSING16("cmn",0xf00f00ff) +	DATA_PROCESSING16("orrs",0xf00f00ff) +	DATA_PROCESSING16("muls",VAL2) +	DATA_PROCESSING16("bics",0xf00f00ff) +	DATA_PROCESSING16("mvns",VAL2) + +	TEST_GROUP("Special data instructions and branch and exchange") + +	TEST_RR(  "add	r",0, VAL1,", r",7,VAL2,"") +	TEST_RR(  "add	r",3, VAL2,", r",8,VAL3,"") +	TEST_RR(  "add	r",8, VAL3,", r",0,VAL1,"") +	TEST_R(   "add	sp"        ", r",8,-8,  "") +	TEST_R(   "add	r",14,VAL1,", pc") +	TEST_BF_R("add	pc"        ", r",0,2f-1f-8,"") +	TEST_UNSUPPORTED(".short 0x44ff	@ add pc, pc") + +	TEST_RR(  "cmp	r",3,VAL1,", r",8,VAL2,"") +	TEST_RR(  "cmp	r",8,VAL2,", r",0,VAL1,"") +	TEST_R(   "cmp	sp"       ", r",8,-8,  "") + +	TEST_R(   "mov	r0, r",7,VAL2,"") +	TEST_R(   "mov	r3, r",8,VAL3,"") +	TEST_R(   "mov	r8, r",0,VAL1,"") +	TEST_P(   "mov	sp, r",8,-8,  "") +	TEST(     "mov	lr, pc") +	TEST_BF_R("mov	pc, r",0,2f,  "") + +	TEST_BF_R("bx	r",0, 2f+1,"") +	TEST_BF_R("bx	r",14,2f+1,"") +	TESTCASE_START("bx	pc") +		TEST_ARG_REG(14, 99f+1) +		TEST_ARG_END("") +		"	nop			\n\t" /* To align the bx pc*/ +		"50:	nop			\n\t" +		"1:	bx	pc		\n\t" +		"	bx	lr		\n\t" +		".arm				\n\t" +		"	adr	lr, 2f+1	\n\t" +		"	bx	lr		\n\t" +		".thumb				\n\t" +		"2:	nop			\n\t" +	TESTCASE_END + +	TEST_BF_R("blx	r",0, 2f+1,"") +	TEST_BB_R("blx	r",14,2f+1,"") +	TEST_UNSUPPORTED(".short 0x47f8	@ blx pc") + +	TEST_GROUP("Load from Literal Pool") + +	TEST_X( "ldr	r0, 3f", +		".align					\n\t" +		"3:	.word	"__stringify(VAL1)) +	TEST_X( "ldr	r7, 3f", +		".space 128				\n\t" +		".align					\n\t" +		"3:	.word	"__stringify(VAL2)) + +	TEST_GROUP("16-bit Thumb Load/store instructions") + +	TEST_RPR("str	r",0, VAL1,", [r",1, 24,", r",2,  48,"]") +	TEST_RPR("str	r",7, VAL2,", [r",6, 24,", r",5,  48,"]") +	TEST_RPR("strh	r",0, VAL1,", [r",1, 24,", r",2,  48,"]") +	TEST_RPR("strh	r",7, VAL2,", [r",6, 24,", r",5,  48,"]") +	TEST_RPR("strb	r",0, VAL1,", [r",1, 24,", r",2,  48,"]") +	TEST_RPR("strb	r",7, VAL2,", [r",6, 24,", r",5,  48,"]") +	TEST_PR( "ldrsb	r0, [r",1, 24,", r",2,  48,"]") +	TEST_PR( "ldrsb	r7, [r",6, 24,", r",5,  50,"]") +	TEST_PR( "ldr	r0, [r",1, 24,", r",2,  48,"]") +	TEST_PR( "ldr	r7, [r",6, 24,", r",5,  48,"]") +	TEST_PR( "ldrh	r0, [r",1, 24,", r",2,  48,"]") +	TEST_PR( "ldrh	r7, [r",6, 24,", r",5,  50,"]") +	TEST_PR( "ldrb	r0, [r",1, 24,", r",2,  48,"]") +	TEST_PR( "ldrb	r7, [r",6, 24,", r",5,  50,"]") +	TEST_PR( "ldrsh	r0, [r",1, 24,", r",2,  48,"]") +	TEST_PR( "ldrsh	r7, [r",6, 24,", r",5,  50,"]") + +	TEST_RP("str	r",0, VAL1,", [r",1, 24,", #120]") +	TEST_RP("str	r",7, VAL2,", [r",6, 24,", #120]") +	TEST_P( "ldr	r0, [r",1, 24,", #120]") +	TEST_P( "ldr	r7, [r",6, 24,", #120]") +	TEST_RP("strb	r",0, VAL1,", [r",1, 24,", #30]") +	TEST_RP("strb	r",7, VAL2,", [r",6, 24,", #30]") +	TEST_P( "ldrb	r0, [r",1, 24,", #30]") +	TEST_P( "ldrb	r7, [r",6, 24,", #30]") +	TEST_RP("strh	r",0, VAL1,", [r",1, 24,", #60]") +	TEST_RP("strh	r",7, VAL2,", [r",6, 24,", #60]") +	TEST_P( "ldrh	r0, [r",1, 24,", #60]") +	TEST_P( "ldrh	r7, [r",6, 24,", #60]") + +	TEST_R( "str	r",0, VAL1,", [sp, #0]") +	TEST_R( "str	r",7, VAL2,", [sp, #160]") +	TEST(   "ldr	r0, [sp, #0]") +	TEST(   "ldr	r7, [sp, #160]") + +	TEST_RP("str	r",0, VAL1,", [r",0, 24,"]") +	TEST_P( "ldr	r0, [r",0, 24,"]") + +	TEST_GROUP("Generate PC-/SP-relative address") + +	TEST("add	r0, pc, #4") +	TEST("add	r7, pc, #1020") +	TEST("add	r0, sp, #4") +	TEST("add	r7, sp, #1020") + +	TEST_GROUP("Miscellaneous 16-bit instructions") + +	TEST_UNSUPPORTED( "cpsie	i") +	TEST_UNSUPPORTED( "cpsid	i") +	TEST_UNSUPPORTED( "setend	le") +	TEST_UNSUPPORTED( "setend	be") + +	TEST("add	sp, #"__stringify(TEST_MEMORY_SIZE)) /* Assumes TEST_MEMORY_SIZE < 0x400 */ +	TEST("sub	sp, #0x7f*4") + +DONT_TEST_IN_ITBLOCK( +	TEST_BF_R(  "cbnz	r",0,0, ", 2f") +	TEST_BF_R(  "cbz	r",2,-1,", 2f") +	TEST_BF_RX( "cbnz	r",4,1, ", 2f",0x20) +	TEST_BF_RX( "cbz	r",7,0, ", 2f",0x40) +) +	TEST_R("sxth	r0, r",7, HH1,"") +	TEST_R("sxth	r7, r",0, HH2,"") +	TEST_R("sxtb	r0, r",7, HH1,"") +	TEST_R("sxtb	r7, r",0, HH2,"") +	TEST_R("uxth	r0, r",7, HH1,"") +	TEST_R("uxth	r7, r",0, HH2,"") +	TEST_R("uxtb	r0, r",7, HH1,"") +	TEST_R("uxtb	r7, r",0, HH2,"") +	TEST_R("rev	r0, r",7, VAL1,"") +	TEST_R("rev	r7, r",0, VAL2,"") +	TEST_R("rev16	r0, r",7, VAL1,"") +	TEST_R("rev16	r7, r",0, VAL2,"") +	TEST_UNSUPPORTED(".short 0xba80") +	TEST_UNSUPPORTED(".short 0xbabf") +	TEST_R("revsh	r0, r",7, VAL1,"") +	TEST_R("revsh	r7, r",0, VAL2,"") + +#define TEST_POPPC(code, offset)	\ +	TESTCASE_START(code)		\ +	TEST_ARG_PTR(13, offset)	\ +	TEST_ARG_END("")		\ +	TEST_BRANCH_F(code,0)		\ +	TESTCASE_END + +	TEST("push	{r0}") +	TEST("push	{r7}") +	TEST("push	{r14}") +	TEST("push	{r0-r7,r14}") +	TEST("push	{r0,r2,r4,r6,r14}") +	TEST("push	{r1,r3,r5,r7}") +	TEST("pop	{r0}") +	TEST("pop	{r7}") +	TEST("pop	{r0,r2,r4,r6}") +	TEST_POPPC("pop	{pc}",15*4) +	TEST_POPPC("pop	{r0-r7,pc}",7*4) +	TEST_POPPC("pop	{r1,r3,r5,r7,pc}",11*4) +	TEST_THUMB_TO_ARM_INTERWORK_P("pop	{pc}	@ ",13,15*4,"") +	TEST_THUMB_TO_ARM_INTERWORK_P("pop	{r0-r7,pc}	@ ",13,7*4,"") + +	TEST_UNSUPPORTED("bkpt.n	0") +	TEST_UNSUPPORTED("bkpt.n	255") + +	TEST_SUPPORTED("yield") +	TEST("sev") +	TEST("nop") +	TEST("wfi") +	TEST_SUPPORTED("wfe") +	TEST_UNSUPPORTED(".short 0xbf50") /* Unassigned hints */ +	TEST_UNSUPPORTED(".short 0xbff0") /* Unassigned hints */ + +#define TEST_IT(code, code2)			\ +	TESTCASE_START(code)			\ +	TEST_ARG_END("")			\ +	"50:	nop			\n\t"	\ +	"1:	"code"			\n\t"	\ +	"	"code2"			\n\t"	\ +	"2:	nop			\n\t"	\ +	TESTCASE_END + +DONT_TEST_IN_ITBLOCK( +	TEST_IT("it	eq","moveq r0,#0") +	TEST_IT("it	vc","movvc r0,#0") +	TEST_IT("it	le","movle r0,#0") +	TEST_IT("ite	eq","moveq r0,#0\n\t  movne r1,#1") +	TEST_IT("itet	vc","movvc r0,#0\n\t  movvs r1,#1\n\t  movvc r2,#2") +	TEST_IT("itete	le","movle r0,#0\n\t  movgt r1,#1\n\t  movle r2,#2\n\t  movgt r3,#3") +	TEST_IT("itttt	le","movle r0,#0\n\t  movle r1,#1\n\t  movle r2,#2\n\t  movle r3,#3") +	TEST_IT("iteee	le","movle r0,#0\n\t  movgt r1,#1\n\t  movgt r2,#2\n\t  movgt r3,#3") +) + +	TEST_GROUP("Load and store multiple") + +	TEST_P("ldmia	r",4, 16*4,"!, {r0,r7}") +	TEST_P("ldmia	r",7, 16*4,"!, {r0-r6}") +	TEST_P("stmia	r",4, 16*4,"!, {r0,r7}") +	TEST_P("stmia	r",0, 16*4,"!, {r0-r7}") + +	TEST_GROUP("Conditional branch and Supervisor Call instructions") + +CONDITION_INSTRUCTIONS(8, +	TEST_BF("beq	2f") +	TEST_BB("bne	2b") +	TEST_BF("bgt	2f") +	TEST_BB("blt	2b") +) +	TEST_UNSUPPORTED(".short 0xde00") +	TEST_UNSUPPORTED(".short 0xdeff") +	TEST_UNSUPPORTED("svc	#0x00") +	TEST_UNSUPPORTED("svc	#0xff") + +	TEST_GROUP("Unconditional branch") + +	TEST_BF(  "b	2f") +	TEST_BB(  "b	2b") +	TEST_BF_X("b	2f", 0x400) +	TEST_BB_X("b	2b", 0x400) + +	TEST_GROUP("Testing instructions in IT blocks") + +	TEST_ITBLOCK("subs.n r0, r0") + +	verbose("\n"); +} + + +void kprobe_thumb32_test_cases(void) +{ +	kprobe_test_flags = 0; + +	TEST_GROUP("Load/store multiple") + +	TEST_UNSUPPORTED("rfedb	sp") +	TEST_UNSUPPORTED("rfeia	sp") +	TEST_UNSUPPORTED("rfedb	sp!") +	TEST_UNSUPPORTED("rfeia	sp!") + +	TEST_P(   "stmia	r",0, 16*4,", {r0,r8}") +	TEST_P(   "stmia	r",4, 16*4,", {r0-r12,r14}") +	TEST_P(   "stmia	r",7, 16*4,"!, {r8-r12,r14}") +	TEST_P(   "stmia	r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") + +	TEST_P(   "ldmia	r",0, 16*4,", {r0,r8}") +	TEST_P(   "ldmia	r",4, 0,   ", {r0-r12,r14}") +	TEST_BF_P("ldmia	r",5, 8*4, "!, {r6-r12,r15}") +	TEST_P(   "ldmia	r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") +	TEST_BF_P("ldmia	r",14,14*4,"!, {r4,pc}") + +	TEST_P(   "stmdb	r",0, 16*4,", {r0,r8}") +	TEST_P(   "stmdb	r",4, 16*4,", {r0-r12,r14}") +	TEST_P(   "stmdb	r",5, 16*4,"!, {r8-r12,r14}") +	TEST_P(   "stmdb	r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") + +	TEST_P(   "ldmdb	r",0, 16*4,", {r0,r8}") +	TEST_P(   "ldmdb	r",4, 16*4,", {r0-r12,r14}") +	TEST_BF_P("ldmdb	r",5, 16*4,"!, {r6-r12,r15}") +	TEST_P(   "ldmdb	r",12,16*4,"!, {r1,r3,r5,r7,r8-r11,r14}") +	TEST_BF_P("ldmdb	r",14,16*4,"!, {r4,pc}") + +	TEST_P(   "stmdb	r",13,16*4,"!, {r3-r12,lr}") +	TEST_P(	  "stmdb	r",13,16*4,"!, {r3-r12}") +	TEST_P(   "stmdb	r",2, 16*4,", {r3-r12,lr}") +	TEST_P(   "stmdb	r",13,16*4,"!, {r2-r12,lr}") +	TEST_P(   "stmdb	r",0, 16*4,", {r0-r12}") +	TEST_P(   "stmdb	r",0, 16*4,", {r0-r12,lr}") + +	TEST_BF_P("ldmia	r",13,5*4, "!, {r3-r12,pc}") +	TEST_P(	  "ldmia	r",13,5*4, "!, {r3-r12}") +	TEST_BF_P("ldmia	r",2, 5*4, "!, {r3-r12,pc}") +	TEST_BF_P("ldmia	r",13,4*4, "!, {r2-r12,pc}") +	TEST_P(   "ldmia	r",0, 16*4,", {r0-r12}") +	TEST_P(   "ldmia	r",0, 16*4,", {r0-r12,lr}") + +	TEST_THUMB_TO_ARM_INTERWORK_P("ldmia	r",0,14*4,", {r12,pc}") +	TEST_THUMB_TO_ARM_INTERWORK_P("ldmia	r",13,2*4,", {r0-r12,pc}") + +	TEST_UNSUPPORTED(".short 0xe88f,0x0101	@ stmia	pc, {r0,r8}") +	TEST_UNSUPPORTED(".short 0xe92f,0x5f00	@ stmdb	pc!, {r8-r12,r14}") +	TEST_UNSUPPORTED(".short 0xe8bd,0xc000	@ ldmia	r13!, {r14,pc}") +	TEST_UNSUPPORTED(".short 0xe93e,0xc000	@ ldmdb	r14!, {r14,pc}") +	TEST_UNSUPPORTED(".short 0xe8a7,0x3f00	@ stmia	r7!, {r8-r12,sp}") +	TEST_UNSUPPORTED(".short 0xe8a7,0x9f00	@ stmia	r7!, {r8-r12,pc}") +	TEST_UNSUPPORTED(".short 0xe93e,0x2010	@ ldmdb	r14!, {r4,sp}") + +	TEST_GROUP("Load/store double or exclusive, table branch") + +	TEST_P(  "ldrd	r0, r1, [r",1, 24,", #-16]") +	TEST(    "ldrd	r12, r14, [sp, #16]") +	TEST_P(  "ldrd	r1, r0, [r",7, 24,", #-16]!") +	TEST(    "ldrd	r14, r12, [sp, #16]!") +	TEST_P(  "ldrd	r1, r0, [r",7, 24,"], #16") +	TEST(    "ldrd	r7, r8, [sp], #-16") + +	TEST_X( "ldrd	r12, r14, 3f", +		".align 3				\n\t" +		"3:	.word	"__stringify(VAL1)"	\n\t" +		"	.word	"__stringify(VAL2)) + +	TEST_UNSUPPORTED(".short 0xe9ff,0xec04	@ ldrd	r14, r12, [pc, #16]!") +	TEST_UNSUPPORTED(".short 0xe8ff,0xec04	@ ldrd	r14, r12, [pc], #16") +	TEST_UNSUPPORTED(".short 0xe9d4,0xd800	@ ldrd	sp, r8, [r4]") +	TEST_UNSUPPORTED(".short 0xe9d4,0xf800	@ ldrd	pc, r8, [r4]") +	TEST_UNSUPPORTED(".short 0xe9d4,0x7d00	@ ldrd	r7, sp, [r4]") +	TEST_UNSUPPORTED(".short 0xe9d4,0x7f00	@ ldrd	r7, pc, [r4]") + +	TEST_RRP("strd	r",0, VAL1,", r",1, VAL2,", [r",1, 24,", #-16]") +	TEST_RR( "strd	r",12,VAL2,", r",14,VAL1,", [sp, #16]") +	TEST_RRP("strd	r",1, VAL1,", r",0, VAL2,", [r",7, 24,", #-16]!") +	TEST_RR( "strd	r",14,VAL2,", r",12,VAL1,", [sp, #16]!") +	TEST_RRP("strd	r",1, VAL1,", r",0, VAL2,", [r",7, 24,"], #16") +	TEST_RR( "strd	r",7, VAL2,", r",8, VAL1,", [sp], #-16") +	TEST_UNSUPPORTED(".short 0xe9ef,0xec04	@ strd	r14, r12, [pc, #16]!") +	TEST_UNSUPPORTED(".short 0xe8ef,0xec04	@ strd	r14, r12, [pc], #16") + +	TEST_RX("tbb	[pc, r",0, (9f-(1f+4)),"]", +		"9:			\n\t" +		".byte	(2f-1b-4)>>1	\n\t" +		".byte	(3f-1b-4)>>1	\n\t" +		"3:	mvn	r0, r0	\n\t" +		"2:	nop		\n\t") + +	TEST_RX("tbb	[pc, r",4, (9f-(1f+4)+1),"]", +		"9:			\n\t" +		".byte	(2f-1b-4)>>1	\n\t" +		".byte	(3f-1b-4)>>1	\n\t" +		"3:	mvn	r0, r0	\n\t" +		"2:	nop		\n\t") + +	TEST_RRX("tbb	[r",1,9f,", r",2,0,"]", +		"9:			\n\t" +		".byte	(2f-1b-4)>>1	\n\t" +		".byte	(3f-1b-4)>>1	\n\t" +		"3:	mvn	r0, r0	\n\t" +		"2:	nop		\n\t") + +	TEST_RX("tbh	[pc, r",7, (9f-(1f+4))>>1,"]", +		"9:			\n\t" +		".short	(2f-1b-4)>>1	\n\t" +		".short	(3f-1b-4)>>1	\n\t" +		"3:	mvn	r0, r0	\n\t" +		"2:	nop		\n\t") + +	TEST_RX("tbh	[pc, r",12, ((9f-(1f+4))>>1)+1,"]", +		"9:			\n\t" +		".short	(2f-1b-4)>>1	\n\t" +		".short	(3f-1b-4)>>1	\n\t" +		"3:	mvn	r0, r0	\n\t" +		"2:	nop		\n\t") + +	TEST_RRX("tbh	[r",1,9f, ", r",14,1,"]", +		"9:			\n\t" +		".short	(2f-1b-4)>>1	\n\t" +		".short	(3f-1b-4)>>1	\n\t" +		"3:	mvn	r0, r0	\n\t" +		"2:	nop		\n\t") + +	TEST_UNSUPPORTED(".short 0xe8d1,0xf01f	@ tbh [r1, pc]") +	TEST_UNSUPPORTED(".short 0xe8d1,0xf01d	@ tbh [r1, sp]") +	TEST_UNSUPPORTED(".short 0xe8dd,0xf012	@ tbh [sp, r2]") + +	TEST_UNSUPPORTED("strexb	r0, r1, [r2]") +	TEST_UNSUPPORTED("strexh	r0, r1, [r2]") +	TEST_UNSUPPORTED("strexd	r0, r1, [r2]") +	TEST_UNSUPPORTED("ldrexb	r0, [r1]") +	TEST_UNSUPPORTED("ldrexh	r0, [r1]") +	TEST_UNSUPPORTED("ldrexd	r0, [r1]") + +	TEST_GROUP("Data-processing (shifted register) and (modified immediate)") + +#define _DATA_PROCESSING32_DNM(op,s,val)					\ +	TEST_RR(op s".w	r0,  r",1, VAL1,", r",2, val, "")			\ +	TEST_RR(op s"	r1,  r",1, VAL1,", r",2, val, ", lsl #3")		\ +	TEST_RR(op s"	r2,  r",3, VAL1,", r",2, val, ", lsr #4")		\ +	TEST_RR(op s"	r3,  r",3, VAL1,", r",2, val, ", asr #5")		\ +	TEST_RR(op s"	r4,  r",5, VAL1,", r",2, N(val),", asr #6")		\ +	TEST_RR(op s"	r5,  r",5, VAL1,", r",2, val, ", ror #7")		\ +	TEST_RR(op s"	r8,  r",9, VAL1,", r",10,val, ", rrx")			\ +	TEST_R( op s"	r0,  r",11,VAL1,", #0x00010001")			\ +	TEST_R( op s"	r11, r",0, VAL1,", #0xf5000000")			\ +	TEST_R( op s"	r7,  r",8, VAL2,", #0x000af000") + +#define DATA_PROCESSING32_DNM(op,val)		\ +	_DATA_PROCESSING32_DNM(op,"",val)	\ +	_DATA_PROCESSING32_DNM(op,"s",val) + +#define DATA_PROCESSING32_NM(op,val)					\ +	TEST_RR(op".w	r",1, VAL1,", r",2, val, "")			\ +	TEST_RR(op"	r",1, VAL1,", r",2, val, ", lsl #3")		\ +	TEST_RR(op"	r",3, VAL1,", r",2, val, ", lsr #4")		\ +	TEST_RR(op"	r",3, VAL1,", r",2, val, ", asr #5")		\ +	TEST_RR(op"	r",5, VAL1,", r",2, N(val),", asr #6")		\ +	TEST_RR(op"	r",5, VAL1,", r",2, val, ", ror #7")		\ +	TEST_RR(op"	r",9, VAL1,", r",10,val, ", rrx")		\ +	TEST_R( op"	r",11,VAL1,", #0x00010001")			\ +	TEST_R( op"	r",0, VAL1,", #0xf5000000")			\ +	TEST_R( op"	r",8, VAL2,", #0x000af000") + +#define _DATA_PROCESSING32_DM(op,s,val)				\ +	TEST_R( op s".w	r0,  r",14, val, "")			\ +	TEST_R( op s"	r1,  r",12, val, ", lsl #3")		\ +	TEST_R( op s"	r2,  r",11, val, ", lsr #4")		\ +	TEST_R( op s"	r3,  r",10, val, ", asr #5")		\ +	TEST_R( op s"	r4,  r",9, N(val),", asr #6")		\ +	TEST_R( op s"	r5,  r",8, val, ", ror #7")		\ +	TEST_R( op s"	r8,  r",7,val, ", rrx")			\ +	TEST(   op s"	r0,  #0x00010001")			\ +	TEST(   op s"	r11, #0xf5000000")			\ +	TEST(   op s"	r7,  #0x000af000")			\ +	TEST(   op s"	r4,  #0x00005a00") + +#define DATA_PROCESSING32_DM(op,val)		\ +	_DATA_PROCESSING32_DM(op,"",val)	\ +	_DATA_PROCESSING32_DM(op,"s",val) + +	DATA_PROCESSING32_DNM("and",0xf00f00ff) +	DATA_PROCESSING32_NM("tst",0xf00f00ff) +	DATA_PROCESSING32_DNM("bic",0xf00f00ff) +	DATA_PROCESSING32_DNM("orr",0xf00f00ff) +	DATA_PROCESSING32_DM("mov",VAL2) +	DATA_PROCESSING32_DNM("orn",0xf00f00ff) +	DATA_PROCESSING32_DM("mvn",VAL2) +	DATA_PROCESSING32_DNM("eor",0xf00f00ff) +	DATA_PROCESSING32_NM("teq",0xf00f00ff) +	DATA_PROCESSING32_DNM("add",VAL2) +	DATA_PROCESSING32_NM("cmn",VAL2) +	DATA_PROCESSING32_DNM("adc",VAL2) +	DATA_PROCESSING32_DNM("sbc",VAL2) +	DATA_PROCESSING32_DNM("sub",VAL2) +	DATA_PROCESSING32_NM("cmp",VAL2) +	DATA_PROCESSING32_DNM("rsb",VAL2) + +	TEST_RR("pkhbt	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR("pkhbt	r14,r",12, HH1,", r",10,HH2,", lsl #2") +	TEST_RR("pkhtb	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR("pkhtb	r14,r",12, HH1,", r",10,HH2,", asr #2") + +	TEST_UNSUPPORTED(".short 0xea17,0x0f0d	@ tst.w r7, sp") +	TEST_UNSUPPORTED(".short 0xea17,0x0f0f	@ tst.w r7, pc") +	TEST_UNSUPPORTED(".short 0xea1d,0x0f07	@ tst.w sp, r7") +	TEST_UNSUPPORTED(".short 0xea1f,0x0f07	@ tst.w pc, r7") +	TEST_UNSUPPORTED(".short 0xf01d,0x1f08	@ tst sp, #0x00080008") +	TEST_UNSUPPORTED(".short 0xf01f,0x1f08	@ tst pc, #0x00080008") + +	TEST_UNSUPPORTED(".short 0xea97,0x0f0d	@ teq.w r7, sp") +	TEST_UNSUPPORTED(".short 0xea97,0x0f0f	@ teq.w r7, pc") +	TEST_UNSUPPORTED(".short 0xea9d,0x0f07	@ teq.w sp, r7") +	TEST_UNSUPPORTED(".short 0xea9f,0x0f07	@ teq.w pc, r7") +	TEST_UNSUPPORTED(".short 0xf09d,0x1f08	@ tst sp, #0x00080008") +	TEST_UNSUPPORTED(".short 0xf09f,0x1f08	@ tst pc, #0x00080008") + +	TEST_UNSUPPORTED(".short 0xeb17,0x0f0d	@ cmn.w r7, sp") +	TEST_UNSUPPORTED(".short 0xeb17,0x0f0f	@ cmn.w r7, pc") +	TEST_P("cmn.w	sp, r",7,0,"") +	TEST_UNSUPPORTED(".short 0xeb1f,0x0f07	@ cmn.w pc, r7") +	TEST(  "cmn	sp, #0x00080008") +	TEST_UNSUPPORTED(".short 0xf11f,0x1f08	@ cmn pc, #0x00080008") + +	TEST_UNSUPPORTED(".short 0xebb7,0x0f0d	@ cmp.w r7, sp") +	TEST_UNSUPPORTED(".short 0xebb7,0x0f0f	@ cmp.w r7, pc") +	TEST_P("cmp.w	sp, r",7,0,"") +	TEST_UNSUPPORTED(".short 0xebbf,0x0f07	@ cmp.w pc, r7") +	TEST(  "cmp	sp, #0x00080008") +	TEST_UNSUPPORTED(".short 0xf1bf,0x1f08	@ cmp pc, #0x00080008") + +	TEST_UNSUPPORTED(".short 0xea5f,0x070d	@ movs.w r7, sp") +	TEST_UNSUPPORTED(".short 0xea5f,0x070f	@ movs.w r7, pc") +	TEST_UNSUPPORTED(".short 0xea5f,0x0d07	@ movs.w sp, r7") +	TEST_UNSUPPORTED(".short 0xea4f,0x0f07	@ mov.w  pc, r7") +	TEST_UNSUPPORTED(".short 0xf04f,0x1d08	@ mov sp, #0x00080008") +	TEST_UNSUPPORTED(".short 0xf04f,0x1f08	@ mov pc, #0x00080008") + +	TEST_R("add.w	r0, sp, r",1, 4,"") +	TEST_R("adds	r0, sp, r",1, 4,", asl #3") +	TEST_R("add	r0, sp, r",1, 4,", asl #4") +	TEST_R("add	r0, sp, r",1, 16,", ror #1") +	TEST_R("add.w	sp, sp, r",1, 4,"") +	TEST_R("add	sp, sp, r",1, 4,", asl #3") +	TEST_UNSUPPORTED(".short 0xeb0d,0x1d01	@ add sp, sp, r1, asl #4") +	TEST_UNSUPPORTED(".short 0xeb0d,0x0d71	@ add sp, sp, r1, ror #1") +	TEST(  "add.w	r0, sp, #24") +	TEST(  "add.w	sp, sp, #24") +	TEST_UNSUPPORTED(".short 0xeb0d,0x0f01	@ add pc, sp, r1") +	TEST_UNSUPPORTED(".short 0xeb0d,0x000f	@ add r0, sp, pc") +	TEST_UNSUPPORTED(".short 0xeb0d,0x000d	@ add r0, sp, sp") +	TEST_UNSUPPORTED(".short 0xeb0d,0x0d0f	@ add sp, sp, pc") +	TEST_UNSUPPORTED(".short 0xeb0d,0x0d0d	@ add sp, sp, sp") + +	TEST_R("sub.w	r0, sp, r",1, 4,"") +	TEST_R("subs	r0, sp, r",1, 4,", asl #3") +	TEST_R("sub	r0, sp, r",1, 4,", asl #4") +	TEST_R("sub	r0, sp, r",1, 16,", ror #1") +	TEST_R("sub.w	sp, sp, r",1, 4,"") +	TEST_R("sub	sp, sp, r",1, 4,", asl #3") +	TEST_UNSUPPORTED(".short 0xebad,0x1d01	@ sub sp, sp, r1, asl #4") +	TEST_UNSUPPORTED(".short 0xebad,0x0d71	@ sub sp, sp, r1, ror #1") +	TEST_UNSUPPORTED(".short 0xebad,0x0f01	@ sub pc, sp, r1") +	TEST(  "sub.w	r0, sp, #24") +	TEST(  "sub.w	sp, sp, #24") + +	TEST_UNSUPPORTED(".short 0xea02,0x010f	@ and r1, r2, pc") +	TEST_UNSUPPORTED(".short 0xea0f,0x0103	@ and r1, pc, r3") +	TEST_UNSUPPORTED(".short 0xea02,0x0f03	@ and pc, r2, r3") +	TEST_UNSUPPORTED(".short 0xea02,0x010d	@ and r1, r2, sp") +	TEST_UNSUPPORTED(".short 0xea0d,0x0103	@ and r1, sp, r3") +	TEST_UNSUPPORTED(".short 0xea02,0x0d03	@ and sp, r2, r3") +	TEST_UNSUPPORTED(".short 0xf00d,0x1108	@ and r1, sp, #0x00080008") +	TEST_UNSUPPORTED(".short 0xf00f,0x1108	@ and r1, pc, #0x00080008") +	TEST_UNSUPPORTED(".short 0xf002,0x1d08	@ and sp, r8, #0x00080008") +	TEST_UNSUPPORTED(".short 0xf002,0x1f08	@ and pc, r8, #0x00080008") + +	TEST_UNSUPPORTED(".short 0xeb02,0x010f	@ add r1, r2, pc") +	TEST_UNSUPPORTED(".short 0xeb0f,0x0103	@ add r1, pc, r3") +	TEST_UNSUPPORTED(".short 0xeb02,0x0f03	@ add pc, r2, r3") +	TEST_UNSUPPORTED(".short 0xeb02,0x010d	@ add r1, r2, sp") +	TEST_SUPPORTED(  ".short 0xeb0d,0x0103	@ add r1, sp, r3") +	TEST_UNSUPPORTED(".short 0xeb02,0x0d03	@ add sp, r2, r3") +	TEST_SUPPORTED(  ".short 0xf10d,0x1108	@ add r1, sp, #0x00080008") +	TEST_UNSUPPORTED(".short 0xf10d,0x1f08	@ add pc, sp, #0x00080008") +	TEST_UNSUPPORTED(".short 0xf10f,0x1108	@ add r1, pc, #0x00080008") +	TEST_UNSUPPORTED(".short 0xf102,0x1d08	@ add sp, r8, #0x00080008") +	TEST_UNSUPPORTED(".short 0xf102,0x1f08	@ add pc, r8, #0x00080008") + +	TEST_UNSUPPORTED(".short 0xeaa0,0x0000") +	TEST_UNSUPPORTED(".short 0xeaf0,0x0000") +	TEST_UNSUPPORTED(".short 0xeb20,0x0000") +	TEST_UNSUPPORTED(".short 0xeb80,0x0000") +	TEST_UNSUPPORTED(".short 0xebe0,0x0000") + +	TEST_UNSUPPORTED(".short 0xf0a0,0x0000") +	TEST_UNSUPPORTED(".short 0xf0c0,0x0000") +	TEST_UNSUPPORTED(".short 0xf0f0,0x0000") +	TEST_UNSUPPORTED(".short 0xf120,0x0000") +	TEST_UNSUPPORTED(".short 0xf180,0x0000") +	TEST_UNSUPPORTED(".short 0xf1e0,0x0000") + +	TEST_GROUP("Coprocessor instructions") + +	TEST_UNSUPPORTED(".short 0xec00,0x0000") +	TEST_UNSUPPORTED(".short 0xeff0,0x0000") +	TEST_UNSUPPORTED(".short 0xfc00,0x0000") +	TEST_UNSUPPORTED(".short 0xfff0,0x0000") + +	TEST_GROUP("Data-processing (plain binary immediate)") + +	TEST_R("addw	r0,  r",1, VAL1,", #0x123") +	TEST(  "addw	r14, sp, #0xf5a") +	TEST(  "addw	sp, sp, #0x20") +	TEST(  "addw	r7,  pc, #0x888") +	TEST_UNSUPPORTED(".short 0xf20f,0x1f20	@ addw pc, pc, #0x120") +	TEST_UNSUPPORTED(".short 0xf20d,0x1f20	@ addw pc, sp, #0x120") +	TEST_UNSUPPORTED(".short 0xf20f,0x1d20	@ addw sp, pc, #0x120") +	TEST_UNSUPPORTED(".short 0xf200,0x1d20	@ addw sp, r0, #0x120") + +	TEST_R("subw	r0,  r",1, VAL1,", #0x123") +	TEST(  "subw	r14, sp, #0xf5a") +	TEST(  "subw	sp, sp, #0x20") +	TEST(  "subw	r7,  pc, #0x888") +	TEST_UNSUPPORTED(".short 0xf2af,0x1f20	@ subw pc, pc, #0x120") +	TEST_UNSUPPORTED(".short 0xf2ad,0x1f20	@ subw pc, sp, #0x120") +	TEST_UNSUPPORTED(".short 0xf2af,0x1d20	@ subw sp, pc, #0x120") +	TEST_UNSUPPORTED(".short 0xf2a0,0x1d20	@ subw sp, r0, #0x120") + +	TEST("movw	r0, #0") +	TEST("movw	r0, #0xffff") +	TEST("movw	lr, #0xffff") +	TEST_UNSUPPORTED(".short 0xf240,0x0d00	@ movw sp, #0") +	TEST_UNSUPPORTED(".short 0xf240,0x0f00	@ movw pc, #0") + +	TEST_R("movt	r",0, VAL1,", #0") +	TEST_R("movt	r",0, VAL2,", #0xffff") +	TEST_R("movt	r",14,VAL1,", #0xffff") +	TEST_UNSUPPORTED(".short 0xf2c0,0x0d00	@ movt sp, #0") +	TEST_UNSUPPORTED(".short 0xf2c0,0x0f00	@ movt pc, #0") + +	TEST_R(     "ssat	r0, #24, r",0,   VAL1,"") +	TEST_R(     "ssat	r14, #24, r",12, VAL2,"") +	TEST_R(     "ssat	r0, #24, r",0,   VAL1,", lsl #8") +	TEST_R(     "ssat	r14, #24, r",12, VAL2,", asr #8") +	TEST_UNSUPPORTED(".short 0xf30c,0x0d17	@ ssat	sp, #24, r12") +	TEST_UNSUPPORTED(".short 0xf30c,0x0f17	@ ssat	pc, #24, r12") +	TEST_UNSUPPORTED(".short 0xf30d,0x0c17	@ ssat	r12, #24, sp") +	TEST_UNSUPPORTED(".short 0xf30f,0x0c17	@ ssat	r12, #24, pc") + +	TEST_R(     "usat	r0, #24, r",0,   VAL1,"") +	TEST_R(     "usat	r14, #24, r",12, VAL2,"") +	TEST_R(     "usat	r0, #24, r",0,   VAL1,", lsl #8") +	TEST_R(     "usat	r14, #24, r",12, VAL2,", asr #8") +	TEST_UNSUPPORTED(".short 0xf38c,0x0d17	@ usat	sp, #24, r12") +	TEST_UNSUPPORTED(".short 0xf38c,0x0f17	@ usat	pc, #24, r12") +	TEST_UNSUPPORTED(".short 0xf38d,0x0c17	@ usat	r12, #24, sp") +	TEST_UNSUPPORTED(".short 0xf38f,0x0c17	@ usat	r12, #24, pc") + +	TEST_R(     "ssat16	r0, #12, r",0,   HH1,"") +	TEST_R(     "ssat16	r14, #12, r",12, HH2,"") +	TEST_UNSUPPORTED(".short 0xf32c,0x0d0b	@ ssat16	sp, #12, r12") +	TEST_UNSUPPORTED(".short 0xf32c,0x0f0b	@ ssat16	pc, #12, r12") +	TEST_UNSUPPORTED(".short 0xf32d,0x0c0b	@ ssat16	r12, #12, sp") +	TEST_UNSUPPORTED(".short 0xf32f,0x0c0b	@ ssat16	r12, #12, pc") + +	TEST_R(     "usat16	r0, #12, r",0,   HH1,"") +	TEST_R(     "usat16	r14, #12, r",12, HH2,"") +	TEST_UNSUPPORTED(".short 0xf3ac,0x0d0b	@ usat16	sp, #12, r12") +	TEST_UNSUPPORTED(".short 0xf3ac,0x0f0b	@ usat16	pc, #12, r12") +	TEST_UNSUPPORTED(".short 0xf3ad,0x0c0b	@ usat16	r12, #12, sp") +	TEST_UNSUPPORTED(".short 0xf3af,0x0c0b	@ usat16	r12, #12, pc") + +	TEST_R(     "sbfx	r0, r",0  , VAL1,", #0, #31") +	TEST_R(     "sbfx	r14, r",12, VAL2,", #8, #16") +	TEST_R(     "sbfx	r4, r",10,  VAL1,", #16, #15") +	TEST_UNSUPPORTED(".short 0xf34c,0x2d0f	@ sbfx	sp, r12, #8, #16") +	TEST_UNSUPPORTED(".short 0xf34c,0x2f0f	@ sbfx	pc, r12, #8, #16") +	TEST_UNSUPPORTED(".short 0xf34d,0x2c0f	@ sbfx	r12, sp, #8, #16") +	TEST_UNSUPPORTED(".short 0xf34f,0x2c0f	@ sbfx	r12, pc, #8, #16") + +	TEST_R(     "ubfx	r0, r",0  , VAL1,", #0, #31") +	TEST_R(     "ubfx	r14, r",12, VAL2,", #8, #16") +	TEST_R(     "ubfx	r4, r",10,  VAL1,", #16, #15") +	TEST_UNSUPPORTED(".short 0xf3cc,0x2d0f	@ ubfx	sp, r12, #8, #16") +	TEST_UNSUPPORTED(".short 0xf3cc,0x2f0f	@ ubfx	pc, r12, #8, #16") +	TEST_UNSUPPORTED(".short 0xf3cd,0x2c0f	@ ubfx	r12, sp, #8, #16") +	TEST_UNSUPPORTED(".short 0xf3cf,0x2c0f	@ ubfx	r12, pc, #8, #16") + +	TEST_R(     "bfc	r",0, VAL1,", #4, #20") +	TEST_R(     "bfc	r",14,VAL2,", #4, #20") +	TEST_R(     "bfc	r",7, VAL1,", #0, #31") +	TEST_R(     "bfc	r",8, VAL2,", #0, #31") +	TEST_UNSUPPORTED(".short 0xf36f,0x0d1e	@ bfc	sp, #0, #31") +	TEST_UNSUPPORTED(".short 0xf36f,0x0f1e	@ bfc	pc, #0, #31") + +	TEST_RR(    "bfi	r",0, VAL1,", r",0  , VAL2,", #0, #31") +	TEST_RR(    "bfi	r",12,VAL1,", r",14 , VAL2,", #4, #20") +	TEST_UNSUPPORTED(".short 0xf36e,0x1d17	@ bfi	sp, r14, #4, #20") +	TEST_UNSUPPORTED(".short 0xf36e,0x1f17	@ bfi	pc, r14, #4, #20") +	TEST_UNSUPPORTED(".short 0xf36d,0x1e17	@ bfi	r14, sp, #4, #20") + +	TEST_GROUP("Branches and miscellaneous control") + +CONDITION_INSTRUCTIONS(22, +	TEST_BF("beq.w	2f") +	TEST_BB("bne.w	2b") +	TEST_BF("bgt.w	2f") +	TEST_BB("blt.w	2b") +	TEST_BF_X("bpl.w	2f",0x1000) +) + +	TEST_UNSUPPORTED("msr	cpsr, r0") +	TEST_UNSUPPORTED("msr	cpsr_f, r1") +	TEST_UNSUPPORTED("msr	spsr, r2") + +	TEST_UNSUPPORTED("cpsie.w	i") +	TEST_UNSUPPORTED("cpsid.w	i") +	TEST_UNSUPPORTED("cps	0x13") + +	TEST_SUPPORTED("yield.w") +	TEST("sev.w") +	TEST("nop.w") +	TEST("wfi.w") +	TEST_SUPPORTED("wfe.w") +	TEST_UNSUPPORTED("dbg.w	#0") + +	TEST_UNSUPPORTED("clrex") +	TEST_UNSUPPORTED("dsb") +	TEST_UNSUPPORTED("dmb") +	TEST_UNSUPPORTED("isb") + +	TEST_UNSUPPORTED("bxj	r0") + +	TEST_UNSUPPORTED("subs	pc, lr, #4") + +	TEST("mrs	r0, cpsr") +	TEST("mrs	r14, cpsr") +	TEST_UNSUPPORTED(".short 0xf3ef,0x8d00	@ mrs	sp, spsr") +	TEST_UNSUPPORTED(".short 0xf3ef,0x8f00	@ mrs	pc, spsr") +	TEST_UNSUPPORTED("mrs	r0, spsr") +	TEST_UNSUPPORTED("mrs	lr, spsr") + +	TEST_UNSUPPORTED(".short 0xf7f0,0x8000 @ smc #0") + +	TEST_UNSUPPORTED(".short 0xf7f0,0xa000 @ undefeined") + +	TEST_BF(  "b.w	2f") +	TEST_BB(  "b.w	2b") +	TEST_BF_X("b.w	2f", 0x1000) + +	TEST_BF(  "bl.w	2f") +	TEST_BB(  "bl.w	2b") +	TEST_BB_X("bl.w	2b", 0x1000) + +	TEST_X(	"blx	__dummy_arm_subroutine", +		".arm				\n\t" +		".align				\n\t" +		".type __dummy_arm_subroutine, %%function \n\t" +		"__dummy_arm_subroutine:	\n\t" +		"mov	r0, pc			\n\t" +		"bx	lr			\n\t" +		".thumb				\n\t" +	) +	TEST(	"blx	__dummy_arm_subroutine") + +	TEST_GROUP("Store single data item") + +#define SINGLE_STORE(size)							\ +	TEST_RP( "str"size"	r",0, VAL1,", [r",11,-1024,", #1024]")		\ +	TEST_RP( "str"size"	r",14,VAL2,", [r",1, -1024,", #1080]")		\ +	TEST_RP( "str"size"	r",0, VAL1,", [r",11,256,  ", #-120]")		\ +	TEST_RP( "str"size"	r",14,VAL2,", [r",1, 256,  ", #-128]")		\ +	TEST_RP( "str"size"	r",0, VAL1,", [r",11,24,  "], #120")		\ +	TEST_RP( "str"size"	r",14,VAL2,", [r",1, 24,  "], #128")		\ +	TEST_RP( "str"size"	r",0, VAL1,", [r",11,24,  "], #-120")		\ +	TEST_RP( "str"size"	r",14,VAL2,", [r",1, 24,  "], #-128")		\ +	TEST_RP( "str"size"	r",0, VAL1,", [r",11,24,   ", #120]!")		\ +	TEST_RP( "str"size"	r",14,VAL2,", [r",1, 24,   ", #128]!")		\ +	TEST_RP( "str"size"	r",0, VAL1,", [r",11,256,  ", #-120]!")		\ +	TEST_RP( "str"size"	r",14,VAL2,", [r",1, 256,  ", #-128]!")		\ +	TEST_RPR("str"size".w	r",0, VAL1,", [r",1, 0,", r",2, 4,"]")		\ +	TEST_RPR("str"size"	r",14,VAL2,", [r",10,0,", r",11,4,", lsl #1]")	\ +	TEST_R(  "str"size".w	r",7, VAL1,", [sp, #24]")			\ +	TEST_RP( "str"size".w	r",0, VAL2,", [r",0,0, "]")			\ +	TEST_UNSUPPORTED("str"size"t	r0, [r1, #4]") + +	SINGLE_STORE("b") +	SINGLE_STORE("h") +	SINGLE_STORE("") + +	TEST("str	sp, [sp]") +	TEST_UNSUPPORTED(".short 0xf8cf,0xe000	@ str	r14, [pc]") +	TEST_UNSUPPORTED(".short 0xf8ce,0xf000	@ str	pc, [r14]") + +	TEST_GROUP("Advanced SIMD element or structure load/store instructions") + +	TEST_UNSUPPORTED(".short 0xf900,0x0000") +	TEST_UNSUPPORTED(".short 0xf92f,0xffff") +	TEST_UNSUPPORTED(".short 0xf980,0x0000") +	TEST_UNSUPPORTED(".short 0xf9ef,0xffff") + +	TEST_GROUP("Load single data item and memory hints") + +#define SINGLE_LOAD(size)						\ +	TEST_P( "ldr"size"	r0, [r",11,-1024, ", #1024]")		\ +	TEST_P( "ldr"size"	r14, [r",1, -1024,", #1080]")		\ +	TEST_P( "ldr"size"	r0, [r",11,256,   ", #-120]")		\ +	TEST_P( "ldr"size"	r14, [r",1, 256,  ", #-128]")		\ +	TEST_P( "ldr"size"	r0, [r",11,24,   "], #120")		\ +	TEST_P( "ldr"size"	r14, [r",1, 24,  "], #128")		\ +	TEST_P( "ldr"size"	r0, [r",11,24,   "], #-120")		\ +	TEST_P( "ldr"size"	r14, [r",1,24,   "], #-128")		\ +	TEST_P( "ldr"size"	r0, [r",11,24,    ", #120]!")		\ +	TEST_P( "ldr"size"	r14, [r",1, 24,   ", #128]!")		\ +	TEST_P( "ldr"size"	r0, [r",11,256,   ", #-120]!")		\ +	TEST_P( "ldr"size"	r14, [r",1, 256,  ", #-128]!")		\ +	TEST_PR("ldr"size".w	r0, [r",1, 0,", r",2, 4,"]")		\ +	TEST_PR("ldr"size"	r14, [r",10,0,", r",11,4,", lsl #1]")	\ +	TEST_X( "ldr"size".w	r0, 3f",				\ +		".align 3				\n\t"		\ +		"3:	.word	"__stringify(VAL1))			\ +	TEST_X( "ldr"size".w	r14, 3f",				\ +		".align 3				\n\t"		\ +		"3:	.word	"__stringify(VAL2))			\ +	TEST(   "ldr"size".w	r7, 3b")				\ +	TEST(   "ldr"size".w	r7, [sp, #24]")				\ +	TEST_P( "ldr"size".w	r0, [r",0,0, "]")			\ +	TEST_UNSUPPORTED("ldr"size"t	r0, [r1, #4]") + +	SINGLE_LOAD("b") +	SINGLE_LOAD("sb") +	SINGLE_LOAD("h") +	SINGLE_LOAD("sh") +	SINGLE_LOAD("") + +	TEST_BF_P("ldr	pc, [r",14, 15*4,"]") +	TEST_P(   "ldr	sp, [r",14, 13*4,"]") +	TEST_BF_R("ldr	pc, [sp, r",14, 15*4,"]") +	TEST_R(   "ldr	sp, [sp, r",14, 13*4,"]") +	TEST_THUMB_TO_ARM_INTERWORK_P("ldr	pc, [r",0,0,", #15*4]") +	TEST_SUPPORTED("ldr	sp, 99f") +	TEST_SUPPORTED("ldr	pc, 99f") + +	TEST_UNSUPPORTED(".short 0xf854,0x700d	@ ldr	r7, [r4, sp]") +	TEST_UNSUPPORTED(".short 0xf854,0x700f	@ ldr	r7, [r4, pc]") +	TEST_UNSUPPORTED(".short 0xf814,0x700d	@ ldrb	r7, [r4, sp]") +	TEST_UNSUPPORTED(".short 0xf814,0x700f	@ ldrb	r7, [r4, pc]") +	TEST_UNSUPPORTED(".short 0xf89f,0xd004	@ ldrb	sp, 99f") +	TEST_UNSUPPORTED(".short 0xf814,0xd008	@ ldrb	sp, [r4, r8]") +	TEST_UNSUPPORTED(".short 0xf894,0xd000	@ ldrb	sp, [r4]") + +	TEST_UNSUPPORTED(".short 0xf860,0x0000") /* Unallocated space */ +	TEST_UNSUPPORTED(".short 0xf9ff,0xffff") /* Unallocated space */ +	TEST_UNSUPPORTED(".short 0xf950,0x0000") /* Unallocated space */ +	TEST_UNSUPPORTED(".short 0xf95f,0xffff") /* Unallocated space */ +	TEST_UNSUPPORTED(".short 0xf800,0x0800") /* Unallocated space */ +	TEST_UNSUPPORTED(".short 0xf97f,0xfaff") /* Unallocated space */ + +	TEST(   "pli	[pc, #4]") +	TEST(   "pli	[pc, #-4]") +	TEST(   "pld	[pc, #4]") +	TEST(   "pld	[pc, #-4]") + +	TEST_P( "pld	[r",0,-1024,", #1024]") +	TEST(   ".short 0xf8b0,0xf400	@ pldw	[r0, #1024]") +	TEST_P( "pli	[r",4, 0b,", #1024]") +	TEST_P( "pld	[r",7, 120,", #-120]") +	TEST(   ".short 0xf837,0xfc78	@ pldw	[r7, #-120]") +	TEST_P( "pli	[r",11,120,", #-120]") +	TEST(   "pld	[sp, #0]") + +	TEST_PR("pld	[r",7, 24, ", r",0, 16,"]") +	TEST_PR("pld	[r",8, 24, ", r",12,16,", lsl #3]") +	TEST_SUPPORTED(".short 0xf837,0xf000	@ pldw	[r7, r0]") +	TEST_SUPPORTED(".short 0xf838,0xf03c	@ pldw	[r8, r12, lsl #3]"); +	TEST_RR("pli	[r",12,0b,", r",0, 16,"]") +	TEST_RR("pli	[r",0, 0b,", r",12,16,", lsl #3]") +	TEST_R( "pld	[sp, r",1, 16,"]") +	TEST_UNSUPPORTED(".short 0xf817,0xf00d  @pld	[r7, sp]") +	TEST_UNSUPPORTED(".short 0xf817,0xf00f  @pld	[r7, pc]") + +	TEST_GROUP("Data-processing (register)") + +#define SHIFTS32(op)					\ +	TEST_RR(op"	r0,  r",1, VAL1,", r",2, 3, "")	\ +	TEST_RR(op"	r14, r",12,VAL2,", r",11,10,"") + +	SHIFTS32("lsl") +	SHIFTS32("lsls") +	SHIFTS32("lsr") +	SHIFTS32("lsrs") +	SHIFTS32("asr") +	SHIFTS32("asrs") +	SHIFTS32("ror") +	SHIFTS32("rors") + +	TEST_UNSUPPORTED(".short 0xfa01,0xff02	@ lsl	pc, r1, r2") +	TEST_UNSUPPORTED(".short 0xfa01,0xfd02	@ lsl	sp, r1, r2") +	TEST_UNSUPPORTED(".short 0xfa0f,0xf002	@ lsl	r0, pc, r2") +	TEST_UNSUPPORTED(".short 0xfa0d,0xf002	@ lsl	r0, sp, r2") +	TEST_UNSUPPORTED(".short 0xfa01,0xf00f	@ lsl	r0, r1, pc") +	TEST_UNSUPPORTED(".short 0xfa01,0xf00d	@ lsl	r0, r1, sp") + +	TEST_RR(    "sxtah	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "sxtah	r14,r",12, HH2,", r",10,HH1,", ror #8") +	TEST_R(     "sxth	r8, r",7,  HH1,"") + +	TEST_UNSUPPORTED(".short 0xfa0f,0xff87	@ sxth	pc, r7"); +	TEST_UNSUPPORTED(".short 0xfa0f,0xfd87	@ sxth	sp, r7"); +	TEST_UNSUPPORTED(".short 0xfa0f,0xf88f	@ sxth	r8, pc"); +	TEST_UNSUPPORTED(".short 0xfa0f,0xf88d	@ sxth	r8, sp"); + +	TEST_RR(    "uxtah	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uxtah	r14,r",12, HH2,", r",10,HH1,", ror #8") +	TEST_R(     "uxth	r8, r",7,  HH1,"") + +	TEST_RR(    "sxtab16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "sxtab16	r14,r",12, HH2,", r",10,HH1,", ror #8") +	TEST_R(     "sxtb16	r8, r",7,  HH1,"") + +	TEST_RR(    "uxtab16	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uxtab16	r14,r",12, HH2,", r",10,HH1,", ror #8") +	TEST_R(     "uxtb16	r8, r",7,  HH1,"") + +	TEST_RR(    "sxtab	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "sxtab	r14,r",12, HH2,", r",10,HH1,", ror #8") +	TEST_R(     "sxtb	r8, r",7,  HH1,"") + +	TEST_RR(    "uxtab	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "uxtab	r14,r",12, HH2,", r",10,HH1,", ror #8") +	TEST_R(     "uxtb	r8, r",7,  HH1,"") + +	TEST_UNSUPPORTED(".short 0xfa60,0x00f0") +	TEST_UNSUPPORTED(".short 0xfa7f,0xffff") + +#define PARALLEL_ADD_SUB(op)					\ +	TEST_RR(  op"add16	r0, r",0,  HH1,", r",1, HH2,"")	\ +	TEST_RR(  op"add16	r14, r",12,HH2,", r",10,HH1,"")	\ +	TEST_RR(  op"asx	r0, r",0,  HH1,", r",1, HH2,"")	\ +	TEST_RR(  op"asx	r14, r",12,HH2,", r",10,HH1,"")	\ +	TEST_RR(  op"sax	r0, r",0,  HH1,", r",1, HH2,"")	\ +	TEST_RR(  op"sax	r14, r",12,HH2,", r",10,HH1,"")	\ +	TEST_RR(  op"sub16	r0, r",0,  HH1,", r",1, HH2,"")	\ +	TEST_RR(  op"sub16	r14, r",12,HH2,", r",10,HH1,"")	\ +	TEST_RR(  op"add8	r0, r",0,  HH1,", r",1, HH2,"")	\ +	TEST_RR(  op"add8	r14, r",12,HH2,", r",10,HH1,"")	\ +	TEST_RR(  op"sub8	r0, r",0,  HH1,", r",1, HH2,"")	\ +	TEST_RR(  op"sub8	r14, r",12,HH2,", r",10,HH1,"") + +	TEST_GROUP("Parallel addition and subtraction, signed") + +	PARALLEL_ADD_SUB("s") +	PARALLEL_ADD_SUB("q") +	PARALLEL_ADD_SUB("sh") + +	TEST_GROUP("Parallel addition and subtraction, unsigned") + +	PARALLEL_ADD_SUB("u") +	PARALLEL_ADD_SUB("uq") +	PARALLEL_ADD_SUB("uh") + +	TEST_GROUP("Miscellaneous operations") + +	TEST_RR("qadd	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR("qadd	lr, r",9, VAL2,", r",8, VAL1,"") +	TEST_RR("qsub	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR("qsub	lr, r",9, VAL2,", r",8, VAL1,"") +	TEST_RR("qdadd	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR("qdadd	lr, r",9, VAL2,", r",8, VAL1,"") +	TEST_RR("qdsub	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR("qdsub	lr, r",9, VAL2,", r",8, VAL1,"") + +	TEST_R("rev.w	r0, r",0,   VAL1,"") +	TEST_R("rev	r14, r",12, VAL2,"") +	TEST_R("rev16.w	r0, r",0,   VAL1,"") +	TEST_R("rev16	r14, r",12, VAL2,"") +	TEST_R("rbit	r0, r",0,   VAL1,"") +	TEST_R("rbit	r14, r",12, VAL2,"") +	TEST_R("revsh.w	r0, r",0,   VAL1,"") +	TEST_R("revsh	r14, r",12, VAL2,"") + +	TEST_UNSUPPORTED(".short 0xfa9c,0xff8c	@ rev	pc, r12"); +	TEST_UNSUPPORTED(".short 0xfa9c,0xfd8c	@ rev	sp, r12"); +	TEST_UNSUPPORTED(".short 0xfa9f,0xfe8f	@ rev	r14, pc"); +	TEST_UNSUPPORTED(".short 0xfa9d,0xfe8d	@ rev	r14, sp"); + +	TEST_RR("sel	r0, r",0,  VAL1,", r",1, VAL2,"") +	TEST_RR("sel	r14, r",12,VAL1,", r",10, VAL2,"") + +	TEST_R("clz	r0, r",0, 0x0,"") +	TEST_R("clz	r7, r",14,0x1,"") +	TEST_R("clz	lr, r",7, 0xffffffff,"") + +	TEST_UNSUPPORTED(".short 0xfa80,0xf030") /* Unallocated space */ +	TEST_UNSUPPORTED(".short 0xfaff,0xff7f") /* Unallocated space */ +	TEST_UNSUPPORTED(".short 0xfab0,0xf000") /* Unallocated space */ +	TEST_UNSUPPORTED(".short 0xfaff,0xff7f") /* Unallocated space */ + +	TEST_GROUP("Multiply, multiply accumulate, and absolute difference operations") + +	TEST_RR(    "mul	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "mul	r7, r",8, VAL2,", r",9, VAL2,"") +	TEST_UNSUPPORTED(".short 0xfb08,0xff09	@ mul	pc, r8, r9") +	TEST_UNSUPPORTED(".short 0xfb08,0xfd09	@ mul	sp, r8, r9") +	TEST_UNSUPPORTED(".short 0xfb0f,0xf709	@ mul	r7, pc, r9") +	TEST_UNSUPPORTED(".short 0xfb0d,0xf709	@ mul	r7, sp, r9") +	TEST_UNSUPPORTED(".short 0xfb08,0xf70f	@ mul	r7, r8, pc") +	TEST_UNSUPPORTED(".short 0xfb08,0xf70d	@ mul	r7, r8, sp") + +	TEST_RRR(   "mla	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(   "mla	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_UNSUPPORTED(".short 0xfb08,0xaf09	@ mla	pc, r8, r9, r10"); +	TEST_UNSUPPORTED(".short 0xfb08,0xad09	@ mla	sp, r8, r9, r10"); +	TEST_UNSUPPORTED(".short 0xfb0f,0xa709	@ mla	r7, pc, r9, r10"); +	TEST_UNSUPPORTED(".short 0xfb0d,0xa709	@ mla	r7, sp, r9, r10"); +	TEST_UNSUPPORTED(".short 0xfb08,0xa70f	@ mla	r7, r8, pc, r10"); +	TEST_UNSUPPORTED(".short 0xfb08,0xa70d	@ mla	r7, r8, sp, r10"); +	TEST_UNSUPPORTED(".short 0xfb08,0xd709	@ mla	r7, r8, r9, sp"); + +	TEST_RRR(   "mls	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(   "mls	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") + +	TEST_RRR(   "smlabb	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(   "smlabb	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RRR(   "smlatb	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(   "smlatb	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RRR(   "smlabt	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(   "smlabt	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RRR(   "smlatt	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(   "smlatt	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RR(    "smulbb	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "smulbb	r7, r",8, VAL3,", r",9, VAL1,"") +	TEST_RR(    "smultb	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "smultb	r7, r",8, VAL3,", r",9, VAL1,"") +	TEST_RR(    "smulbt	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "smulbt	r7, r",8, VAL3,", r",9, VAL1,"") +	TEST_RR(    "smultt	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "smultt	r7, r",8, VAL3,", r",9, VAL1,"") + +	TEST_RRR(   "smlad	r0, r",0,  HH1,", r",1, HH2,", r",2, VAL1,"") +	TEST_RRR(   "smlad	r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"") +	TEST_RRR(   "smladx	r0, r",0,  HH1,", r",1, HH2,", r",2, VAL1,"") +	TEST_RRR(   "smladx	r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"") +	TEST_RR(    "smuad	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "smuad	r14, r",12,HH2,", r",10,HH1,"") +	TEST_RR(    "smuadx	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "smuadx	r14, r",12,HH2,", r",10,HH1,"") + +	TEST_RRR(   "smlawb	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(   "smlawb	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RRR(   "smlawt	r0, r",1, VAL1,", r",2, VAL2,", r",3,  VAL3,"") +	TEST_RRR(   "smlawt	r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") +	TEST_RR(    "smulwb	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "smulwb	r7, r",8, VAL3,", r",9, VAL1,"") +	TEST_RR(    "smulwt	r0, r",1, VAL1,", r",2, VAL2,"") +	TEST_RR(    "smulwt	r7, r",8, VAL3,", r",9, VAL1,"") + +	TEST_RRR(   "smlsd	r0, r",0,  HH1,", r",1, HH2,", r",2, VAL1,"") +	TEST_RRR(   "smlsd	r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"") +	TEST_RRR(   "smlsdx	r0, r",0,  HH1,", r",1, HH2,", r",2, VAL1,"") +	TEST_RRR(   "smlsdx	r14, r",12,HH2,", r",10,HH1,", r",8, VAL2,"") +	TEST_RR(    "smusd	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "smusd	r14, r",12,HH2,", r",10,HH1,"") +	TEST_RR(    "smusdx	r0, r",0,  HH1,", r",1, HH2,"") +	TEST_RR(    "smusdx	r14, r",12,HH2,", r",10,HH1,"") + +	TEST_RRR(   "smmla	r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL1,"") +	TEST_RRR(   "smmla	r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"") +	TEST_RRR(   "smmlar	r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL1,"") +	TEST_RRR(   "smmlar	r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"") +	TEST_RR(    "smmul	r0, r",0,  VAL1,", r",1, VAL2,"") +	TEST_RR(    "smmul	r14, r",12,VAL2,", r",10,VAL1,"") +	TEST_RR(    "smmulr	r0, r",0,  VAL1,", r",1, VAL2,"") +	TEST_RR(    "smmulr	r14, r",12,VAL2,", r",10,VAL1,"") + +	TEST_RRR(   "smmls	r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL1,"") +	TEST_RRR(   "smmls	r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"") +	TEST_RRR(   "smmlsr	r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL1,"") +	TEST_RRR(   "smmlsr	r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL2,"") + +	TEST_RRR(   "usada8	r0, r",0,  VAL1,", r",1, VAL2,", r",2, VAL3,"") +	TEST_RRR(   "usada8	r14, r",12,VAL2,", r",10,VAL1,", r",8, VAL3,"") +	TEST_RR(    "usad8	r0, r",0,  VAL1,", r",1, VAL2,"") +	TEST_RR(    "usad8	r14, r",12,VAL2,", r",10,VAL1,"") + +	TEST_UNSUPPORTED(".short 0xfb00,0xf010") /* Unallocated space */ +	TEST_UNSUPPORTED(".short 0xfb0f,0xff1f") /* Unallocated space */ +	TEST_UNSUPPORTED(".short 0xfb70,0xf010") /* Unallocated space */ +	TEST_UNSUPPORTED(".short 0xfb7f,0xff1f") /* Unallocated space */ +	TEST_UNSUPPORTED(".short 0xfb70,0x0010") /* Unallocated space */ +	TEST_UNSUPPORTED(".short 0xfb7f,0xff1f") /* Unallocated space */ + +	TEST_GROUP("Long multiply, long multiply accumulate, and divide") + +	TEST_RR(   "smull	r0, r1, r",2, VAL1,", r",3, VAL2,"") +	TEST_RR(   "smull	r7, r8, r",9, VAL2,", r",10, VAL1,"") +	TEST_UNSUPPORTED(".short 0xfb89,0xf80a	@ smull	pc, r8, r9, r10"); +	TEST_UNSUPPORTED(".short 0xfb89,0xd80a	@ smull	sp, r8, r9, r10"); +	TEST_UNSUPPORTED(".short 0xfb89,0x7f0a	@ smull	r7, pc, r9, r10"); +	TEST_UNSUPPORTED(".short 0xfb89,0x7d0a	@ smull	r7, sp, r9, r10"); +	TEST_UNSUPPORTED(".short 0xfb8f,0x780a	@ smull	r7, r8, pc, r10"); +	TEST_UNSUPPORTED(".short 0xfb8d,0x780a	@ smull	r7, r8, sp, r10"); +	TEST_UNSUPPORTED(".short 0xfb89,0x780f	@ smull	r7, r8, r9, pc"); +	TEST_UNSUPPORTED(".short 0xfb89,0x780d	@ smull	r7, r8, r9, sp"); + +	TEST_RR(   "umull	r0, r1, r",2, VAL1,", r",3, VAL2,"") +	TEST_RR(   "umull	r7, r8, r",9, VAL2,", r",10, VAL1,"") + +	TEST_RRRR( "smlal	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR( "smlal	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) + +	TEST_RRRR( "smlalbb	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR( "smlalbb	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) +	TEST_RRRR( "smlalbt	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR( "smlalbt	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) +	TEST_RRRR( "smlaltb	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR( "smlaltb	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) +	TEST_RRRR( "smlaltt	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR( "smlaltt	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) + +	TEST_RRRR( "smlald	r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2) +	TEST_RRRR( "smlald	r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1) +	TEST_RRRR( "smlaldx	r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2) +	TEST_RRRR( "smlaldx	r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1) + +	TEST_RRRR( "smlsld	r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2) +	TEST_RRRR( "smlsld	r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1) +	TEST_RRRR( "smlsldx	r",0, VAL1,", r",1, VAL2, ", r",0, HH1,", r",1, HH2) +	TEST_RRRR( "smlsldx	r",11,VAL2,", r",10,VAL1, ", r",9, HH2,", r",8, HH1) + +	TEST_RRRR( "umlal	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR( "umlal	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) +	TEST_RRRR( "umaal	r",0, VAL1,", r",1, VAL2,", r",2, VAL3,", r",3, VAL4) +	TEST_RRRR( "umaal	r",8, VAL4,", r",9, VAL1,", r",10,VAL2,", r",11,VAL3) + +	TEST_GROUP("Coprocessor instructions") + +	TEST_UNSUPPORTED(".short 0xfc00,0x0000") +	TEST_UNSUPPORTED(".short 0xffff,0xffff") + +	TEST_GROUP("Testing instructions in IT blocks") + +	TEST_ITBLOCK("sub.w	r0, r0") + +	verbose("\n"); +} + diff --git a/arch/arm/kernel/kprobes-test.c b/arch/arm/kernel/kprobes-test.c new file mode 100644 index 00000000000..e17cdd6d90d --- /dev/null +++ b/arch/arm/kernel/kprobes-test.c @@ -0,0 +1,1748 @@ +/* + * arch/arm/kernel/kprobes-test.c + * + * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. + * + * 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 file contains test code for ARM kprobes. + * + * The top level function run_all_tests() executes tests for all of the + * supported instruction sets: ARM, 16-bit Thumb, and 32-bit Thumb. These tests + * fall into two categories; run_api_tests() checks basic functionality of the + * kprobes API, and run_test_cases() is a comprehensive test for kprobes + * instruction decoding and simulation. + * + * run_test_cases() first checks the kprobes decoding table for self consistency + * (using table_test()) then executes a series of test cases for each of the CPU + * instruction forms. coverage_start() and coverage_end() are used to verify + * that these test cases cover all of the possible combinations of instructions + * described by the kprobes decoding tables. + * + * The individual test cases are in kprobes-test-arm.c and kprobes-test-thumb.c + * which use the macros defined in kprobes-test.h. The rest of this + * documentation will describe the operation of the framework used by these + * test cases. + */ + +/* + * TESTING METHODOLOGY + * ------------------- + * + * The methodology used to test an ARM instruction 'test_insn' is to use + * inline assembler like: + * + * test_before: nop + * test_case:	test_insn + * test_after:	nop + * + * When the test case is run a kprobe is placed of each nop. The + * post-handler of the test_before probe is used to modify the saved CPU + * register context to that which we require for the test case. The + * pre-handler of the of the test_after probe saves a copy of the CPU + * register context. In this way we can execute test_insn with a specific + * register context and see the results afterwards. + * + * To actually test the kprobes instruction emulation we perform the above + * step a second time but with an additional kprobe on the test_case + * instruction itself. If the emulation is accurate then the results seen + * by the test_after probe will be identical to the first run which didn't + * have a probe on test_case. + * + * Each test case is run several times with a variety of variations in the + * flags value of stored in CPSR, and for Thumb code, different ITState. + * + * For instructions which can modify PC, a second test_after probe is used + * like this: + * + * test_before: nop + * test_case:	test_insn + * test_after:	nop + *		b test_done + * test_after2: nop + * test_done: + * + * The test case is constructed such that test_insn branches to + * test_after2, or, if testing a conditional instruction, it may just + * continue to test_after. The probes inserted at both locations let us + * determine which happened. A similar approach is used for testing + * backwards branches... + * + *		b test_before + *		b test_done  @ helps to cope with off by 1 branches + * test_after2: nop + *		b test_done + * test_before: nop + * test_case:	test_insn + * test_after:	nop + * test_done: + * + * The macros used to generate the assembler instructions describe above + * are TEST_INSTRUCTION, TEST_BRANCH_F (branch forwards) and TEST_BRANCH_B + * (branch backwards). In these, the local variables numbered 1, 50, 2 and + * 99 represent: test_before, test_case, test_after2 and test_done. + * + * FRAMEWORK + * --------- + * + * Each test case is wrapped between the pair of macros TESTCASE_START and + * TESTCASE_END. As well as performing the inline assembler boilerplate, + * these call out to the kprobes_test_case_start() and + * kprobes_test_case_end() functions which drive the execution of the test + * case. The specific arguments to use for each test case are stored as + * inline data constructed using the various TEST_ARG_* macros. Putting + * this all together, a simple test case may look like: + * + *	TESTCASE_START("Testing mov r0, r7") + *	TEST_ARG_REG(7, 0x12345678) // Set r7=0x12345678 + *	TEST_ARG_END("") + *	TEST_INSTRUCTION("mov r0, r7") + *	TESTCASE_END + * + * Note, in practice the single convenience macro TEST_R would be used for this + * instead. + * + * The above would expand to assembler looking something like: + * + *	@ TESTCASE_START + *	bl	__kprobes_test_case_start + *	@ start of inline data... + *	.ascii "mov r0, r7"	@ text title for test case + *	.byte	0 + *	.align	2 + * + *	@ TEST_ARG_REG + *	.byte	ARG_TYPE_REG + *	.byte	7 + *	.short	0 + *	.word	0x1234567 + * + *	@ TEST_ARG_END + *	.byte	ARG_TYPE_END + *	.byte	TEST_ISA	@ flags, including ISA being tested + *	.short	50f-0f		@ offset of 'test_before' + *	.short	2f-0f		@ offset of 'test_after2' (if relevent) + *	.short	99f-0f		@ offset of 'test_done' + *	@ start of test case code... + *	0: + *	.code	TEST_ISA	@ switch to ISA being tested + * + *	@ TEST_INSTRUCTION + *	50:	nop		@ location for 'test_before' probe + *	1:	mov r0, r7	@ the test case instruction 'test_insn' + *		nop		@ location for 'test_after' probe + * + *	// TESTCASE_END + *	2: + *	99:	bl __kprobes_test_case_end_##TEST_ISA + *	.code	NONMAL_ISA + * + * When the above is execute the following happens... + * + * __kprobes_test_case_start() is an assembler wrapper which sets up space + * for a stack buffer and calls the C function kprobes_test_case_start(). + * This C function will do some initial processing of the inline data and + * setup some global state. It then inserts the test_before and test_after + * kprobes and returns a value which causes the assembler wrapper to jump + * to the start of the test case code, (local label '0'). + * + * When the test case code executes, the test_before probe will be hit and + * test_before_post_handler will call setup_test_context(). This fills the + * stack buffer and CPU registers with a test pattern and then processes + * the test case arguments. In our example there is one TEST_ARG_REG which + * indicates that R7 should be loaded with the value 0x12345678. + * + * When the test_before probe ends, the test case continues and executes + * the "mov r0, r7" instruction. It then hits the test_after probe and the + * pre-handler for this (test_after_pre_handler) will save a copy of the + * CPU register context. This should now have R0 holding the same value as + * R7. + * + * Finally we get to the call to __kprobes_test_case_end_{32,16}. This is + * an assembler wrapper which switches back to the ISA used by the test + * code and calls the C function kprobes_test_case_end(). + * + * For each run through the test case, test_case_run_count is incremented + * by one. For even runs, kprobes_test_case_end() saves a copy of the + * register and stack buffer contents from the test case just run. It then + * inserts a kprobe on the test case instruction 'test_insn' and returns a + * value to cause the test case code to be re-run. + * + * For odd numbered runs, kprobes_test_case_end() compares the register and + * stack buffer contents to those that were saved on the previous even + * numbered run (the one without the kprobe on test_insn). These should be + * the same if the kprobe instruction simulation routine is correct. + * + * The pair of test case runs is repeated with different combinations of + * flag values in CPSR and, for Thumb, different ITState. This is + * controlled by test_context_cpsr(). + * + * BUILDING TEST CASES + * ------------------- + * + * + * As an aid to building test cases, the stack buffer is initialised with + * some special values: + * + *   [SP+13*4]	Contains SP+120. This can be used to test instructions + *		which load a value into SP. + * + *   [SP+15*4]	When testing branching instructions using TEST_BRANCH_{F,B}, + *		this holds the target address of the branch, 'test_after2'. + *		This can be used to test instructions which load a PC value + *		from memory. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/kprobes.h> + +#include "kprobes.h" +#include "kprobes-test.h" + + +#define BENCHMARKING	1 + + +/* + * Test basic API + */ + +static bool test_regs_ok; +static int test_func_instance; +static int pre_handler_called; +static int post_handler_called; +static int jprobe_func_called; +static int kretprobe_handler_called; + +#define FUNC_ARG1 0x12345678 +#define FUNC_ARG2 0xabcdef + + +#ifndef CONFIG_THUMB2_KERNEL + +long arm_func(long r0, long r1); + +static void __used __naked __arm_kprobes_test_func(void) +{ +	__asm__ __volatile__ ( +		".arm					\n\t" +		".type arm_func, %%function		\n\t" +		"arm_func:				\n\t" +		"adds	r0, r0, r1			\n\t" +		"bx	lr				\n\t" +		".code "NORMAL_ISA	 /* Back to Thumb if necessary */ +		: : : "r0", "r1", "cc" +	); +} + +#else /* CONFIG_THUMB2_KERNEL */ + +long thumb16_func(long r0, long r1); +long thumb32even_func(long r0, long r1); +long thumb32odd_func(long r0, long r1); + +static void __used __naked __thumb_kprobes_test_funcs(void) +{ +	__asm__ __volatile__ ( +		".type thumb16_func, %%function		\n\t" +		"thumb16_func:				\n\t" +		"adds.n	r0, r0, r1			\n\t" +		"bx	lr				\n\t" + +		".align					\n\t" +		".type thumb32even_func, %%function	\n\t" +		"thumb32even_func:			\n\t" +		"adds.w	r0, r0, r1			\n\t" +		"bx	lr				\n\t" + +		".align					\n\t" +		"nop.n					\n\t" +		".type thumb32odd_func, %%function	\n\t" +		"thumb32odd_func:			\n\t" +		"adds.w	r0, r0, r1			\n\t" +		"bx	lr				\n\t" + +		: : : "r0", "r1", "cc" +	); +} + +#endif /* CONFIG_THUMB2_KERNEL */ + + +static int call_test_func(long (*func)(long, long), bool check_test_regs) +{ +	long ret; + +	++test_func_instance; +	test_regs_ok = false; + +	ret = (*func)(FUNC_ARG1, FUNC_ARG2); +	if (ret != FUNC_ARG1 + FUNC_ARG2) { +		pr_err("FAIL: call_test_func: func returned %lx\n", ret); +		return false; +	} + +	if (check_test_regs && !test_regs_ok) { +		pr_err("FAIL: test regs not OK\n"); +		return false; +	} + +	return true; +} + +static int __kprobes pre_handler(struct kprobe *p, struct pt_regs *regs) +{ +	pre_handler_called = test_func_instance; +	if (regs->ARM_r0 == FUNC_ARG1 && regs->ARM_r1 == FUNC_ARG2) +		test_regs_ok = true; +	return 0; +} + +static void __kprobes post_handler(struct kprobe *p, struct pt_regs *regs, +				unsigned long flags) +{ +	post_handler_called = test_func_instance; +	if (regs->ARM_r0 != FUNC_ARG1 + FUNC_ARG2 || regs->ARM_r1 != FUNC_ARG2) +		test_regs_ok = false; +} + +static struct kprobe the_kprobe = { +	.addr		= 0, +	.pre_handler	= pre_handler, +	.post_handler	= post_handler +}; + +static int test_kprobe(long (*func)(long, long)) +{ +	int ret; + +	the_kprobe.addr = (kprobe_opcode_t *)func; +	ret = register_kprobe(&the_kprobe); +	if (ret < 0) { +		pr_err("FAIL: register_kprobe failed with %d\n", ret); +		return ret; +	} + +	ret = call_test_func(func, true); + +	unregister_kprobe(&the_kprobe); +	the_kprobe.flags = 0; /* Clear disable flag to allow reuse */ + +	if (!ret) +		return -EINVAL; +	if (pre_handler_called != test_func_instance) { +		pr_err("FAIL: kprobe pre_handler not called\n"); +		return -EINVAL; +	} +	if (post_handler_called != test_func_instance) { +		pr_err("FAIL: kprobe post_handler not called\n"); +		return -EINVAL; +	} +	if (!call_test_func(func, false)) +		return -EINVAL; +	if (pre_handler_called == test_func_instance || +				post_handler_called == test_func_instance) { +		pr_err("FAIL: probe called after unregistering\n"); +		return -EINVAL; +	} + +	return 0; +} + +static void __kprobes jprobe_func(long r0, long r1) +{ +	jprobe_func_called = test_func_instance; +	if (r0 == FUNC_ARG1 && r1 == FUNC_ARG2) +		test_regs_ok = true; +	jprobe_return(); +} + +static struct jprobe the_jprobe = { +	.entry		= jprobe_func, +}; + +static int test_jprobe(long (*func)(long, long)) +{ +	int ret; + +	the_jprobe.kp.addr = (kprobe_opcode_t *)func; +	ret = register_jprobe(&the_jprobe); +	if (ret < 0) { +		pr_err("FAIL: register_jprobe failed with %d\n", ret); +		return ret; +	} + +	ret = call_test_func(func, true); + +	unregister_jprobe(&the_jprobe); +	the_jprobe.kp.flags = 0; /* Clear disable flag to allow reuse */ + +	if (!ret) +		return -EINVAL; +	if (jprobe_func_called != test_func_instance) { +		pr_err("FAIL: jprobe handler function not called\n"); +		return -EINVAL; +	} +	if (!call_test_func(func, false)) +		return -EINVAL; +	if (jprobe_func_called == test_func_instance) { +		pr_err("FAIL: probe called after unregistering\n"); +		return -EINVAL; +	} + +	return 0; +} + +static int __kprobes +kretprobe_handler(struct kretprobe_instance *ri, struct pt_regs *regs) +{ +	kretprobe_handler_called = test_func_instance; +	if (regs_return_value(regs) == FUNC_ARG1 + FUNC_ARG2) +		test_regs_ok = true; +	return 0; +} + +static struct kretprobe the_kretprobe = { +	.handler	= kretprobe_handler, +}; + +static int test_kretprobe(long (*func)(long, long)) +{ +	int ret; + +	the_kretprobe.kp.addr = (kprobe_opcode_t *)func; +	ret = register_kretprobe(&the_kretprobe); +	if (ret < 0) { +		pr_err("FAIL: register_kretprobe failed with %d\n", ret); +		return ret; +	} + +	ret = call_test_func(func, true); + +	unregister_kretprobe(&the_kretprobe); +	the_kretprobe.kp.flags = 0; /* Clear disable flag to allow reuse */ + +	if (!ret) +		return -EINVAL; +	if (kretprobe_handler_called != test_func_instance) { +		pr_err("FAIL: kretprobe handler not called\n"); +		return -EINVAL; +	} +	if (!call_test_func(func, false)) +		return -EINVAL; +	if (jprobe_func_called == test_func_instance) { +		pr_err("FAIL: kretprobe called after unregistering\n"); +		return -EINVAL; +	} + +	return 0; +} + +static int run_api_tests(long (*func)(long, long)) +{ +	int ret; + +	pr_info("    kprobe\n"); +	ret = test_kprobe(func); +	if (ret < 0) +		return ret; + +	pr_info("    jprobe\n"); +	ret = test_jprobe(func); +	if (ret < 0) +		return ret; + +	pr_info("    kretprobe\n"); +	ret = test_kretprobe(func); +	if (ret < 0) +		return ret; + +	return 0; +} + + +/* + * Benchmarking + */ + +#if BENCHMARKING + +static void __naked benchmark_nop(void) +{ +	__asm__ __volatile__ ( +		"nop		\n\t" +		"bx	lr" +	); +} + +#ifdef CONFIG_THUMB2_KERNEL +#define wide ".w" +#else +#define wide +#endif + +static void __naked benchmark_pushpop1(void) +{ +	__asm__ __volatile__ ( +		"stmdb"wide"	sp!, {r3-r11,lr}  \n\t" +		"ldmia"wide"	sp!, {r3-r11,pc}" +	); +} + +static void __naked benchmark_pushpop2(void) +{ +	__asm__ __volatile__ ( +		"stmdb"wide"	sp!, {r0-r8,lr}  \n\t" +		"ldmia"wide"	sp!, {r0-r8,pc}" +	); +} + +static void __naked benchmark_pushpop3(void) +{ +	__asm__ __volatile__ ( +		"stmdb"wide"	sp!, {r4,lr}  \n\t" +		"ldmia"wide"	sp!, {r4,pc}" +	); +} + +static void __naked benchmark_pushpop4(void) +{ +	__asm__ __volatile__ ( +		"stmdb"wide"	sp!, {r0,lr}  \n\t" +		"ldmia"wide"	sp!, {r0,pc}" +	); +} + + +#ifdef CONFIG_THUMB2_KERNEL + +static void __naked benchmark_pushpop_thumb(void) +{ +	__asm__ __volatile__ ( +		"push.n	{r0-r7,lr}  \n\t" +		"pop.n	{r0-r7,pc}" +	); +} + +#endif + +static int __kprobes +benchmark_pre_handler(struct kprobe *p, struct pt_regs *regs) +{ +	return 0; +} + +static int benchmark(void(*fn)(void)) +{ +	unsigned n, i, t, t0; + +	for (n = 1000; ; n *= 2) { +		t0 = sched_clock(); +		for (i = n; i > 0; --i) +			fn(); +		t = sched_clock() - t0; +		if (t >= 250000000) +			break; /* Stop once we took more than 0.25 seconds */ +	} +	return t / n; /* Time for one iteration in nanoseconds */ +}; + +static int kprobe_benchmark(void(*fn)(void), unsigned offset) +{ +	struct kprobe k = { +		.addr		= (kprobe_opcode_t *)((uintptr_t)fn + offset), +		.pre_handler	= benchmark_pre_handler, +	}; + +	int ret = register_kprobe(&k); +	if (ret < 0) { +		pr_err("FAIL: register_kprobe failed with %d\n", ret); +		return ret; +	} + +	ret = benchmark(fn); + +	unregister_kprobe(&k); +	return ret; +}; + +struct benchmarks { +	void		(*fn)(void); +	unsigned	offset; +	const char	*title; +}; + +static int run_benchmarks(void) +{ +	int ret; +	struct benchmarks list[] = { +		{&benchmark_nop, 0, "nop"}, +		/* +		 * benchmark_pushpop{1,3} will have the optimised +		 * instruction emulation, whilst benchmark_pushpop{2,4} will +		 * be the equivalent unoptimised instructions. +		 */ +		{&benchmark_pushpop1, 0, "stmdb	sp!, {r3-r11,lr}"}, +		{&benchmark_pushpop1, 4, "ldmia	sp!, {r3-r11,pc}"}, +		{&benchmark_pushpop2, 0, "stmdb	sp!, {r0-r8,lr}"}, +		{&benchmark_pushpop2, 4, "ldmia	sp!, {r0-r8,pc}"}, +		{&benchmark_pushpop3, 0, "stmdb	sp!, {r4,lr}"}, +		{&benchmark_pushpop3, 4, "ldmia	sp!, {r4,pc}"}, +		{&benchmark_pushpop4, 0, "stmdb	sp!, {r0,lr}"}, +		{&benchmark_pushpop4, 4, "ldmia	sp!, {r0,pc}"}, +#ifdef CONFIG_THUMB2_KERNEL +		{&benchmark_pushpop_thumb, 0, "push.n	{r0-r7,lr}"}, +		{&benchmark_pushpop_thumb, 2, "pop.n	{r0-r7,pc}"}, +#endif +		{0} +	}; + +	struct benchmarks *b; +	for (b = list; b->fn; ++b) { +		ret = kprobe_benchmark(b->fn, b->offset); +		if (ret < 0) +			return ret; +		pr_info("    %dns for kprobe %s\n", ret, b->title); +	} + +	pr_info("\n"); +	return 0; +} + +#endif /* BENCHMARKING */ + + +/* + * Decoding table self-consistency tests + */ + +static const int decode_struct_sizes[NUM_DECODE_TYPES] = { +	[DECODE_TYPE_TABLE]	= sizeof(struct decode_table), +	[DECODE_TYPE_CUSTOM]	= sizeof(struct decode_custom), +	[DECODE_TYPE_SIMULATE]	= sizeof(struct decode_simulate), +	[DECODE_TYPE_EMULATE]	= sizeof(struct decode_emulate), +	[DECODE_TYPE_OR]	= sizeof(struct decode_or), +	[DECODE_TYPE_REJECT]	= sizeof(struct decode_reject) +}; + +static int table_iter(const union decode_item *table, +			int (*fn)(const struct decode_header *, void *), +			void *args) +{ +	const struct decode_header *h = (struct decode_header *)table; +	int result; + +	for (;;) { +		enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK; + +		if (type == DECODE_TYPE_END) +			return 0; + +		result = fn(h, args); +		if (result) +			return result; + +		h = (struct decode_header *) +			((uintptr_t)h + decode_struct_sizes[type]); + +	} +} + +static int table_test_fail(const struct decode_header *h, const char* message) +{ + +	pr_err("FAIL: kprobes test failure \"%s\" (mask %08x, value %08x)\n", +					message, h->mask.bits, h->value.bits); +	return -EINVAL; +} + +struct table_test_args { +	const union decode_item *root_table; +	u32			parent_mask; +	u32			parent_value; +}; + +static int table_test_fn(const struct decode_header *h, void *args) +{ +	struct table_test_args *a = (struct table_test_args *)args; +	enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK; + +	if (h->value.bits & ~h->mask.bits) +		return table_test_fail(h, "Match value has bits not in mask"); + +	if ((h->mask.bits & a->parent_mask) != a->parent_mask) +		return table_test_fail(h, "Mask has bits not in parent mask"); + +	if ((h->value.bits ^ a->parent_value) & a->parent_mask) +		return table_test_fail(h, "Value is inconsistent with parent"); + +	if (type == DECODE_TYPE_TABLE) { +		struct decode_table *d = (struct decode_table *)h; +		struct table_test_args args2 = *a; +		args2.parent_mask = h->mask.bits; +		args2.parent_value = h->value.bits; +		return table_iter(d->table.table, table_test_fn, &args2); +	} + +	return 0; +} + +static int table_test(const union decode_item *table) +{ +	struct table_test_args args = { +		.root_table	= table, +		.parent_mask	= 0, +		.parent_value	= 0 +	}; +	return table_iter(args.root_table, table_test_fn, &args); +} + + +/* + * Decoding table test coverage analysis + * + * coverage_start() builds a coverage_table which contains a list of + * coverage_entry's to match each entry in the specified kprobes instruction + * decoding table. + * + * When test cases are run, coverage_add() is called to process each case. + * This looks up the corresponding entry in the coverage_table and sets it as + * being matched, as well as clearing the regs flag appropriate for the test. + * + * After all test cases have been run, coverage_end() is called to check that + * all entries in coverage_table have been matched and that all regs flags are + * cleared. I.e. that all possible combinations of instructions described by + * the kprobes decoding tables have had a test case executed for them. + */ + +bool coverage_fail; + +#define MAX_COVERAGE_ENTRIES 256 + +struct coverage_entry { +	const struct decode_header	*header; +	unsigned			regs; +	unsigned			nesting; +	char				matched; +}; + +struct coverage_table { +	struct coverage_entry	*base; +	unsigned		num_entries; +	unsigned		nesting; +}; + +struct coverage_table coverage; + +#define COVERAGE_ANY_REG	(1<<0) +#define COVERAGE_SP		(1<<1) +#define COVERAGE_PC		(1<<2) +#define COVERAGE_PCWB		(1<<3) + +static const char coverage_register_lookup[16] = { +	[REG_TYPE_ANY]		= COVERAGE_ANY_REG | COVERAGE_SP | COVERAGE_PC, +	[REG_TYPE_SAMEAS16]	= COVERAGE_ANY_REG, +	[REG_TYPE_SP]		= COVERAGE_SP, +	[REG_TYPE_PC]		= COVERAGE_PC, +	[REG_TYPE_NOSP]		= COVERAGE_ANY_REG | COVERAGE_SP, +	[REG_TYPE_NOSPPC]	= COVERAGE_ANY_REG | COVERAGE_SP | COVERAGE_PC, +	[REG_TYPE_NOPC]		= COVERAGE_ANY_REG | COVERAGE_PC, +	[REG_TYPE_NOPCWB]	= COVERAGE_ANY_REG | COVERAGE_PC | COVERAGE_PCWB, +	[REG_TYPE_NOPCX]	= COVERAGE_ANY_REG, +	[REG_TYPE_NOSPPCX]	= COVERAGE_ANY_REG | COVERAGE_SP, +}; + +unsigned coverage_start_registers(const struct decode_header *h) +{ +	unsigned regs = 0; +	int i; +	for (i = 0; i < 20; i += 4) { +		int r = (h->type_regs.bits >> (DECODE_TYPE_BITS + i)) & 0xf; +		regs |= coverage_register_lookup[r] << i; +	} +	return regs; +} + +static int coverage_start_fn(const struct decode_header *h, void *args) +{ +	struct coverage_table *coverage = (struct coverage_table *)args; +	enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK; +	struct coverage_entry *entry = coverage->base + coverage->num_entries; + +	if (coverage->num_entries == MAX_COVERAGE_ENTRIES - 1) { +		pr_err("FAIL: Out of space for test coverage data"); +		return -ENOMEM; +	} + +	++coverage->num_entries; + +	entry->header = h; +	entry->regs = coverage_start_registers(h); +	entry->nesting = coverage->nesting; +	entry->matched = false; + +	if (type == DECODE_TYPE_TABLE) { +		struct decode_table *d = (struct decode_table *)h; +		int ret; +		++coverage->nesting; +		ret = table_iter(d->table.table, coverage_start_fn, coverage); +		--coverage->nesting; +		return ret; +	} + +	return 0; +} + +static int coverage_start(const union decode_item *table) +{ +	coverage.base = kmalloc(MAX_COVERAGE_ENTRIES * +				sizeof(struct coverage_entry), GFP_KERNEL); +	coverage.num_entries = 0; +	coverage.nesting = 0; +	return table_iter(table, coverage_start_fn, &coverage); +} + +static void +coverage_add_registers(struct coverage_entry *entry, kprobe_opcode_t insn) +{ +	int regs = entry->header->type_regs.bits >> DECODE_TYPE_BITS; +	int i; +	for (i = 0; i < 20; i += 4) { +		enum decode_reg_type reg_type = (regs >> i) & 0xf; +		int reg = (insn >> i) & 0xf; +		int flag; + +		if (!reg_type) +			continue; + +		if (reg == 13) +			flag = COVERAGE_SP; +		else if (reg == 15) +			flag = COVERAGE_PC; +		else +			flag = COVERAGE_ANY_REG; +		entry->regs &= ~(flag << i); + +		switch (reg_type) { + +		case REG_TYPE_NONE: +		case REG_TYPE_ANY: +		case REG_TYPE_SAMEAS16: +			break; + +		case REG_TYPE_SP: +			if (reg != 13) +				return; +			break; + +		case REG_TYPE_PC: +			if (reg != 15) +				return; +			break; + +		case REG_TYPE_NOSP: +			if (reg == 13) +				return; +			break; + +		case REG_TYPE_NOSPPC: +		case REG_TYPE_NOSPPCX: +			if (reg == 13 || reg == 15) +				return; +			break; + +		case REG_TYPE_NOPCWB: +			if (!is_writeback(insn)) +				break; +			if (reg == 15) { +				entry->regs &= ~(COVERAGE_PCWB << i); +				return; +			} +			break; + +		case REG_TYPE_NOPC: +		case REG_TYPE_NOPCX: +			if (reg == 15) +				return; +			break; +		} + +	} +} + +static void coverage_add(kprobe_opcode_t insn) +{ +	struct coverage_entry *entry = coverage.base; +	struct coverage_entry *end = coverage.base + coverage.num_entries; +	bool matched = false; +	unsigned nesting = 0; + +	for (; entry < end; ++entry) { +		const struct decode_header *h = entry->header; +		enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK; + +		if (entry->nesting > nesting) +			continue; /* Skip sub-table we didn't match */ + +		if (entry->nesting < nesting) +			break; /* End of sub-table we were scanning */ + +		if (!matched) { +			if ((insn & h->mask.bits) != h->value.bits) +				continue; +			entry->matched = true; +		} + +		switch (type) { + +		case DECODE_TYPE_TABLE: +			++nesting; +			break; + +		case DECODE_TYPE_CUSTOM: +		case DECODE_TYPE_SIMULATE: +		case DECODE_TYPE_EMULATE: +			coverage_add_registers(entry, insn); +			return; + +		case DECODE_TYPE_OR: +			matched = true; +			break; + +		case DECODE_TYPE_REJECT: +		default: +			return; +		} + +	} +} + +static void coverage_end(void) +{ +	struct coverage_entry *entry = coverage.base; +	struct coverage_entry *end = coverage.base + coverage.num_entries; + +	for (; entry < end; ++entry) { +		u32 mask = entry->header->mask.bits; +		u32 value = entry->header->value.bits; + +		if (entry->regs) { +			pr_err("FAIL: Register test coverage missing for %08x %08x (%05x)\n", +				mask, value, entry->regs); +			coverage_fail = true; +		} +		if (!entry->matched) { +			pr_err("FAIL: Test coverage entry missing for %08x %08x\n", +				mask, value); +			coverage_fail = true; +		} +	} + +	kfree(coverage.base); +} + + +/* + * Framework for instruction set test cases + */ + +void __naked __kprobes_test_case_start(void) +{ +	__asm__ __volatile__ ( +		"stmdb	sp!, {r4-r11}				\n\t" +		"sub	sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t" +		"bic	r0, lr, #1  @ r0 = inline title string	\n\t" +		"mov	r1, sp					\n\t" +		"bl	kprobes_test_case_start			\n\t" +		"bx	r0					\n\t" +	); +} + +#ifndef CONFIG_THUMB2_KERNEL + +void __naked __kprobes_test_case_end_32(void) +{ +	__asm__ __volatile__ ( +		"mov	r4, lr					\n\t" +		"bl	kprobes_test_case_end			\n\t" +		"cmp	r0, #0					\n\t" +		"movne	pc, r0					\n\t" +		"mov	r0, r4					\n\t" +		"add	sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t" +		"ldmia	sp!, {r4-r11}				\n\t" +		"mov	pc, r0					\n\t" +	); +} + +#else /* CONFIG_THUMB2_KERNEL */ + +void __naked __kprobes_test_case_end_16(void) +{ +	__asm__ __volatile__ ( +		"mov	r4, lr					\n\t" +		"bl	kprobes_test_case_end			\n\t" +		"cmp	r0, #0					\n\t" +		"bxne	r0					\n\t" +		"mov	r0, r4					\n\t" +		"add	sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t" +		"ldmia	sp!, {r4-r11}				\n\t" +		"bx	r0					\n\t" +	); +} + +void __naked __kprobes_test_case_end_32(void) +{ +	__asm__ __volatile__ ( +		".arm						\n\t" +		"orr	lr, lr, #1  @ will return to Thumb code	\n\t" +		"ldr	pc, 1f					\n\t" +		"1:						\n\t" +		".word	__kprobes_test_case_end_16		\n\t" +	); +} + +#endif + + +int kprobe_test_flags; +int kprobe_test_cc_position; + +static int test_try_count; +static int test_pass_count; +static int test_fail_count; + +static struct pt_regs initial_regs; +static struct pt_regs expected_regs; +static struct pt_regs result_regs; + +static u32 expected_memory[TEST_MEMORY_SIZE/sizeof(u32)]; + +static const char *current_title; +static struct test_arg *current_args; +static u32 *current_stack; +static uintptr_t current_branch_target; + +static uintptr_t current_code_start; +static kprobe_opcode_t current_instruction; + + +#define TEST_CASE_PASSED -1 +#define TEST_CASE_FAILED -2 + +static int test_case_run_count; +static bool test_case_is_thumb; +static int test_instance; + +/* + * We ignore the state of the imprecise abort disable flag (CPSR.A) because this + * can change randomly as the kernel doesn't take care to preserve or initialise + * this across context switches. Also, with Security Extentions, the flag may + * not be under control of the kernel; for this reason we ignore the state of + * the FIQ disable flag CPSR.F as well. + */ +#define PSR_IGNORE_BITS (PSR_A_BIT | PSR_F_BIT) + +static unsigned long test_check_cc(int cc, unsigned long cpsr) +{ +	unsigned long temp; + +	switch (cc) { +	case 0x0: /* eq */ +		return cpsr & PSR_Z_BIT; + +	case 0x1: /* ne */ +		return (~cpsr) & PSR_Z_BIT; + +	case 0x2: /* cs */ +		return cpsr & PSR_C_BIT; + +	case 0x3: /* cc */ +		return (~cpsr) & PSR_C_BIT; + +	case 0x4: /* mi */ +		return cpsr & PSR_N_BIT; + +	case 0x5: /* pl */ +		return (~cpsr) & PSR_N_BIT; + +	case 0x6: /* vs */ +		return cpsr & PSR_V_BIT; + +	case 0x7: /* vc */ +		return (~cpsr) & PSR_V_BIT; + +	case 0x8: /* hi */ +		cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ +		return cpsr & PSR_C_BIT; + +	case 0x9: /* ls */ +		cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ +		return (~cpsr) & PSR_C_BIT; + +	case 0xa: /* ge */ +		cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ +		return (~cpsr) & PSR_N_BIT; + +	case 0xb: /* lt */ +		cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ +		return cpsr & PSR_N_BIT; + +	case 0xc: /* gt */ +		temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ +		temp |= (cpsr << 1);	   /* PSR_N_BIT |= PSR_Z_BIT */ +		return (~temp) & PSR_N_BIT; + +	case 0xd: /* le */ +		temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ +		temp |= (cpsr << 1);	   /* PSR_N_BIT |= PSR_Z_BIT */ +		return temp & PSR_N_BIT; + +	case 0xe: /* al */ +	case 0xf: /* unconditional */ +		return true; +	} +	BUG(); +	return false; +} + +static int is_last_scenario; +static int probe_should_run; /* 0 = no, 1 = yes, -1 = unknown */ +static int memory_needs_checking; + +static unsigned long test_context_cpsr(int scenario) +{ +	unsigned long cpsr; + +	probe_should_run = 1; + +	/* Default case is that we cycle through 16 combinations of flags */ +	cpsr  = (scenario & 0xf) << 28; /* N,Z,C,V flags */ +	cpsr |= (scenario & 0xf) << 16; /* GE flags */ +	cpsr |= (scenario & 0x1) << 27; /* Toggle Q flag */ + +	if (!test_case_is_thumb) { +		/* Testing ARM code */ +		probe_should_run = test_check_cc(current_instruction >> 28, cpsr) != 0; +		if (scenario == 15) +			is_last_scenario = true; + +	} else if (kprobe_test_flags & TEST_FLAG_NO_ITBLOCK) { +		/* Testing Thumb code without setting ITSTATE */ +		if (kprobe_test_cc_position) { +			int cc = (current_instruction >> kprobe_test_cc_position) & 0xf; +			probe_should_run = test_check_cc(cc, cpsr) != 0; +		} + +		if (scenario == 15) +			is_last_scenario = true; + +	} else if (kprobe_test_flags & TEST_FLAG_FULL_ITBLOCK) { +		/* Testing Thumb code with all combinations of ITSTATE */ +		unsigned x = (scenario >> 4); +		unsigned cond_base = x % 7; /* ITSTATE<7:5> */ +		unsigned mask = x / 7 + 2;  /* ITSTATE<4:0>, bits reversed */ + +		if (mask > 0x1f) { +			/* Finish by testing state from instruction 'itt al' */ +			cond_base = 7; +			mask = 0x4; +			if ((scenario & 0xf) == 0xf) +				is_last_scenario = true; +		} + +		cpsr |= cond_base << 13;	/* ITSTATE<7:5> */ +		cpsr |= (mask & 0x1) << 12;	/* ITSTATE<4> */ +		cpsr |= (mask & 0x2) << 10;	/* ITSTATE<3> */ +		cpsr |= (mask & 0x4) << 8;	/* ITSTATE<2> */ +		cpsr |= (mask & 0x8) << 23;	/* ITSTATE<1> */ +		cpsr |= (mask & 0x10) << 21;	/* ITSTATE<0> */ + +		probe_should_run = test_check_cc((cpsr >> 12) & 0xf, cpsr) != 0; + +	} else { +		/* Testing Thumb code with several combinations of ITSTATE */ +		switch (scenario) { +		case 16: /* Clear NZCV flags and 'it eq' state (false as Z=0) */ +			cpsr = 0x00000800; +			probe_should_run = 0; +			break; +		case 17: /* Set NZCV flags and 'it vc' state (false as V=1) */ +			cpsr = 0xf0007800; +			probe_should_run = 0; +			break; +		case 18: /* Clear NZCV flags and 'it ls' state (true as C=0) */ +			cpsr = 0x00009800; +			break; +		case 19: /* Set NZCV flags and 'it cs' state (true as C=1) */ +			cpsr = 0xf0002800; +			is_last_scenario = true; +			break; +		} +	} + +	return cpsr; +} + +static void setup_test_context(struct pt_regs *regs) +{ +	int scenario = test_case_run_count>>1; +	unsigned long val; +	struct test_arg *args; +	int i; + +	is_last_scenario = false; +	memory_needs_checking = false; + +	/* Initialise test memory on stack */ +	val = (scenario & 1) ? VALM : ~VALM; +	for (i = 0; i < TEST_MEMORY_SIZE / sizeof(current_stack[0]); ++i) +		current_stack[i] = val + (i << 8); +	/* Put target of branch on stack for tests which load PC from memory */ +	if (current_branch_target) +		current_stack[15] = current_branch_target; +	/* Put a value for SP on stack for tests which load SP from memory */ +	current_stack[13] = (u32)current_stack + 120; + +	/* Initialise register values to their default state */ +	val = (scenario & 2) ? VALR : ~VALR; +	for (i = 0; i < 13; ++i) +		regs->uregs[i] = val ^ (i << 8); +	regs->ARM_lr = val ^ (14 << 8); +	regs->ARM_cpsr &= ~(APSR_MASK | PSR_IT_MASK); +	regs->ARM_cpsr |= test_context_cpsr(scenario); + +	/* Perform testcase specific register setup  */ +	args = current_args; +	for (; args[0].type != ARG_TYPE_END; ++args) +		switch (args[0].type) { +		case ARG_TYPE_REG: { +			struct test_arg_regptr *arg = +				(struct test_arg_regptr *)args; +			regs->uregs[arg->reg] = arg->val; +			break; +		} +		case ARG_TYPE_PTR: { +			struct test_arg_regptr *arg = +				(struct test_arg_regptr *)args; +			regs->uregs[arg->reg] = +				(unsigned long)current_stack + arg->val; +			memory_needs_checking = true; +			break; +		} +		case ARG_TYPE_MEM: { +			struct test_arg_mem *arg = (struct test_arg_mem *)args; +			current_stack[arg->index] = arg->val; +			break; +		} +		default: +			break; +		} +} + +struct test_probe { +	struct kprobe	kprobe; +	bool		registered; +	int		hit; +}; + +static void unregister_test_probe(struct test_probe *probe) +{ +	if (probe->registered) { +		unregister_kprobe(&probe->kprobe); +		probe->kprobe.flags = 0; /* Clear disable flag to allow reuse */ +	} +	probe->registered = false; +} + +static int register_test_probe(struct test_probe *probe) +{ +	int ret; + +	if (probe->registered) +		BUG(); + +	ret = register_kprobe(&probe->kprobe); +	if (ret >= 0) { +		probe->registered = true; +		probe->hit = -1; +	} +	return ret; +} + +static int __kprobes +test_before_pre_handler(struct kprobe *p, struct pt_regs *regs) +{ +	container_of(p, struct test_probe, kprobe)->hit = test_instance; +	return 0; +} + +static void __kprobes +test_before_post_handler(struct kprobe *p, struct pt_regs *regs, +							unsigned long flags) +{ +	setup_test_context(regs); +	initial_regs = *regs; +	initial_regs.ARM_cpsr &= ~PSR_IGNORE_BITS; +} + +static int __kprobes +test_case_pre_handler(struct kprobe *p, struct pt_regs *regs) +{ +	container_of(p, struct test_probe, kprobe)->hit = test_instance; +	return 0; +} + +static int __kprobes +test_after_pre_handler(struct kprobe *p, struct pt_regs *regs) +{ +	if (container_of(p, struct test_probe, kprobe)->hit == test_instance) +		return 0; /* Already run for this test instance */ + +	result_regs = *regs; +	result_regs.ARM_cpsr &= ~PSR_IGNORE_BITS; + +	/* Undo any changes done to SP by the test case */ +	regs->ARM_sp = (unsigned long)current_stack; + +	container_of(p, struct test_probe, kprobe)->hit = test_instance; +	return 0; +} + +static struct test_probe test_before_probe = { +	.kprobe.pre_handler	= test_before_pre_handler, +	.kprobe.post_handler	= test_before_post_handler, +}; + +static struct test_probe test_case_probe = { +	.kprobe.pre_handler	= test_case_pre_handler, +}; + +static struct test_probe test_after_probe = { +	.kprobe.pre_handler	= test_after_pre_handler, +}; + +static struct test_probe test_after2_probe = { +	.kprobe.pre_handler	= test_after_pre_handler, +}; + +static void test_case_cleanup(void) +{ +	unregister_test_probe(&test_before_probe); +	unregister_test_probe(&test_case_probe); +	unregister_test_probe(&test_after_probe); +	unregister_test_probe(&test_after2_probe); +} + +static void print_registers(struct pt_regs *regs) +{ +	pr_err("r0  %08lx | r1  %08lx | r2  %08lx | r3  %08lx\n", +		regs->ARM_r0, regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); +	pr_err("r4  %08lx | r5  %08lx | r6  %08lx | r7  %08lx\n", +		regs->ARM_r4, regs->ARM_r5, regs->ARM_r6, regs->ARM_r7); +	pr_err("r8  %08lx | r9  %08lx | r10 %08lx | r11 %08lx\n", +		regs->ARM_r8, regs->ARM_r9, regs->ARM_r10, regs->ARM_fp); +	pr_err("r12 %08lx | sp  %08lx | lr  %08lx | pc  %08lx\n", +		regs->ARM_ip, regs->ARM_sp, regs->ARM_lr, regs->ARM_pc); +	pr_err("cpsr %08lx\n", regs->ARM_cpsr); +} + +static void print_memory(u32 *mem, size_t size) +{ +	int i; +	for (i = 0; i < size / sizeof(u32); i += 4) +		pr_err("%08x %08x %08x %08x\n", mem[i], mem[i+1], +						mem[i+2], mem[i+3]); +} + +static size_t expected_memory_size(u32 *sp) +{ +	size_t size = sizeof(expected_memory); +	int offset = (uintptr_t)sp - (uintptr_t)current_stack; +	if (offset > 0) +		size -= offset; +	return size; +} + +static void test_case_failed(const char *message) +{ +	test_case_cleanup(); + +	pr_err("FAIL: %s\n", message); +	pr_err("FAIL: Test %s\n", current_title); +	pr_err("FAIL: Scenario %d\n", test_case_run_count >> 1); +} + +static unsigned long next_instruction(unsigned long pc) +{ +#ifdef CONFIG_THUMB2_KERNEL +	if ((pc & 1) && !is_wide_instruction(*(u16 *)(pc - 1))) +		return pc + 2; +	else +#endif +	return pc + 4; +} + +static uintptr_t __used kprobes_test_case_start(const char *title, void *stack) +{ +	struct test_arg *args; +	struct test_arg_end *end_arg; +	unsigned long test_code; + +	args = (struct test_arg *)PTR_ALIGN(title + strlen(title) + 1, 4); + +	current_title = title; +	current_args = args; +	current_stack = stack; + +	++test_try_count; + +	while (args->type != ARG_TYPE_END) +		++args; +	end_arg = (struct test_arg_end *)args; + +	test_code = (unsigned long)(args + 1); /* Code starts after args */ + +	test_case_is_thumb = end_arg->flags & ARG_FLAG_THUMB; +	if (test_case_is_thumb) +		test_code |= 1; + +	current_code_start = test_code; + +	current_branch_target = 0; +	if (end_arg->branch_offset != end_arg->end_offset) +		current_branch_target = test_code + end_arg->branch_offset; + +	test_code += end_arg->code_offset; +	test_before_probe.kprobe.addr = (kprobe_opcode_t *)test_code; + +	test_code = next_instruction(test_code); +	test_case_probe.kprobe.addr = (kprobe_opcode_t *)test_code; + +	if (test_case_is_thumb) { +		u16 *p = (u16 *)(test_code & ~1); +		current_instruction = p[0]; +		if (is_wide_instruction(current_instruction)) { +			current_instruction <<= 16; +			current_instruction |= p[1]; +		} +	} else { +		current_instruction = *(u32 *)test_code; +	} + +	if (current_title[0] == '.') +		verbose("%s\n", current_title); +	else +		verbose("%s\t@ %0*x\n", current_title, +					test_case_is_thumb ? 4 : 8, +					current_instruction); + +	test_code = next_instruction(test_code); +	test_after_probe.kprobe.addr = (kprobe_opcode_t *)test_code; + +	if (kprobe_test_flags & TEST_FLAG_NARROW_INSTR) { +		if (!test_case_is_thumb || +			is_wide_instruction(current_instruction)) { +				test_case_failed("expected 16-bit instruction"); +				goto fail; +		} +	} else { +		if (test_case_is_thumb && +			!is_wide_instruction(current_instruction)) { +				test_case_failed("expected 32-bit instruction"); +				goto fail; +		} +	} + +	coverage_add(current_instruction); + +	if (end_arg->flags & ARG_FLAG_UNSUPPORTED) { +		if (register_test_probe(&test_case_probe) < 0) +			goto pass; +		test_case_failed("registered probe for unsupported instruction"); +		goto fail; +	} + +	if (end_arg->flags & ARG_FLAG_SUPPORTED) { +		if (register_test_probe(&test_case_probe) >= 0) +			goto pass; +		test_case_failed("couldn't register probe for supported instruction"); +		goto fail; +	} + +	if (register_test_probe(&test_before_probe) < 0) { +		test_case_failed("register test_before_probe failed"); +		goto fail; +	} +	if (register_test_probe(&test_after_probe) < 0) { +		test_case_failed("register test_after_probe failed"); +		goto fail; +	} +	if (current_branch_target) { +		test_after2_probe.kprobe.addr = +				(kprobe_opcode_t *)current_branch_target; +		if (register_test_probe(&test_after2_probe) < 0) { +			test_case_failed("register test_after2_probe failed"); +			goto fail; +		} +	} + +	/* Start first run of test case */ +	test_case_run_count = 0; +	++test_instance; +	return current_code_start; +pass: +	test_case_run_count = TEST_CASE_PASSED; +	return (uintptr_t)test_after_probe.kprobe.addr; +fail: +	test_case_run_count = TEST_CASE_FAILED; +	return (uintptr_t)test_after_probe.kprobe.addr; +} + +static bool check_test_results(void) +{ +	size_t mem_size = 0; +	u32 *mem = 0; + +	if (memcmp(&expected_regs, &result_regs, sizeof(expected_regs))) { +		test_case_failed("registers differ"); +		goto fail; +	} + +	if (memory_needs_checking) { +		mem = (u32 *)result_regs.ARM_sp; +		mem_size = expected_memory_size(mem); +		if (memcmp(expected_memory, mem, mem_size)) { +			test_case_failed("test memory differs"); +			goto fail; +		} +	} + +	return true; + +fail: +	pr_err("initial_regs:\n"); +	print_registers(&initial_regs); +	pr_err("expected_regs:\n"); +	print_registers(&expected_regs); +	pr_err("result_regs:\n"); +	print_registers(&result_regs); + +	if (mem) { +		pr_err("current_stack=%p\n", current_stack); +		pr_err("expected_memory:\n"); +		print_memory(expected_memory, mem_size); +		pr_err("result_memory:\n"); +		print_memory(mem, mem_size); +	} + +	return false; +} + +static uintptr_t __used kprobes_test_case_end(void) +{ +	if (test_case_run_count < 0) { +		if (test_case_run_count == TEST_CASE_PASSED) +			/* kprobes_test_case_start did all the needed testing */ +			goto pass; +		else +			/* kprobes_test_case_start failed */ +			goto fail; +	} + +	if (test_before_probe.hit != test_instance) { +		test_case_failed("test_before_handler not run"); +		goto fail; +	} + +	if (test_after_probe.hit != test_instance && +				test_after2_probe.hit != test_instance) { +		test_case_failed("test_after_handler not run"); +		goto fail; +	} + +	/* +	 * Even numbered test runs ran without a probe on the test case so +	 * we can gather reference results. The subsequent odd numbered run +	 * will have the probe inserted. +	*/ +	if ((test_case_run_count & 1) == 0) { +		/* Save results from run without probe */ +		u32 *mem = (u32 *)result_regs.ARM_sp; +		expected_regs = result_regs; +		memcpy(expected_memory, mem, expected_memory_size(mem)); + +		/* Insert probe onto test case instruction */ +		if (register_test_probe(&test_case_probe) < 0) { +			test_case_failed("register test_case_probe failed"); +			goto fail; +		} +	} else { +		/* Check probe ran as expected */ +		if (probe_should_run == 1) { +			if (test_case_probe.hit != test_instance) { +				test_case_failed("test_case_handler not run"); +				goto fail; +			} +		} else if (probe_should_run == 0) { +			if (test_case_probe.hit == test_instance) { +				test_case_failed("test_case_handler ran"); +				goto fail; +			} +		} + +		/* Remove probe for any subsequent reference run */ +		unregister_test_probe(&test_case_probe); + +		if (!check_test_results()) +			goto fail; + +		if (is_last_scenario) +			goto pass; +	} + +	/* Do next test run */ +	++test_case_run_count; +	++test_instance; +	return current_code_start; +fail: +	++test_fail_count; +	goto end; +pass: +	++test_pass_count; +end: +	test_case_cleanup(); +	return 0; +} + + +/* + * Top level test functions + */ + +static int run_test_cases(void (*tests)(void), const union decode_item *table) +{ +	int ret; + +	pr_info("    Check decoding tables\n"); +	ret = table_test(table); +	if (ret) +		return ret; + +	pr_info("    Run test cases\n"); +	ret = coverage_start(table); +	if (ret) +		return ret; + +	tests(); + +	coverage_end(); +	return 0; +} + + +static int __init run_all_tests(void) +{ +	int ret = 0; + +	pr_info("Begining kprobe tests...\n"); + +#ifndef CONFIG_THUMB2_KERNEL + +	pr_info("Probe ARM code\n"); +	ret = run_api_tests(arm_func); +	if (ret) +		goto out; + +	pr_info("ARM instruction simulation\n"); +	ret = run_test_cases(kprobe_arm_test_cases, kprobe_decode_arm_table); +	if (ret) +		goto out; + +#else /* CONFIG_THUMB2_KERNEL */ + +	pr_info("Probe 16-bit Thumb code\n"); +	ret = run_api_tests(thumb16_func); +	if (ret) +		goto out; + +	pr_info("Probe 32-bit Thumb code, even halfword\n"); +	ret = run_api_tests(thumb32even_func); +	if (ret) +		goto out; + +	pr_info("Probe 32-bit Thumb code, odd halfword\n"); +	ret = run_api_tests(thumb32odd_func); +	if (ret) +		goto out; + +	pr_info("16-bit Thumb instruction simulation\n"); +	ret = run_test_cases(kprobe_thumb16_test_cases, +				kprobe_decode_thumb16_table); +	if (ret) +		goto out; + +	pr_info("32-bit Thumb instruction simulation\n"); +	ret = run_test_cases(kprobe_thumb32_test_cases, +				kprobe_decode_thumb32_table); +	if (ret) +		goto out; +#endif + +	pr_info("Total instruction simulation tests=%d, pass=%d fail=%d\n", +		test_try_count, test_pass_count, test_fail_count); +	if (test_fail_count) { +		ret = -EINVAL; +		goto out; +	} + +#if BENCHMARKING +	pr_info("Benchmarks\n"); +	ret = run_benchmarks(); +	if (ret) +		goto out; +#endif + +#if __LINUX_ARM_ARCH__ >= 7 +	/* We are able to run all test cases so coverage should be complete */ +	if (coverage_fail) { +		pr_err("FAIL: Test coverage checks failed\n"); +		ret = -EINVAL; +		goto out; +	} +#endif + +out: +	if (ret == 0) +		pr_info("Finished kprobe tests OK\n"); +	else +		pr_err("kprobe tests failed\n"); + +	return ret; +} + + +/* + * Module setup + */ + +#ifdef MODULE + +static void __exit kprobe_test_exit(void) +{ +} + +module_init(run_all_tests) +module_exit(kprobe_test_exit) +MODULE_LICENSE("GPL"); + +#else /* !MODULE */ + +late_initcall(run_all_tests); + +#endif diff --git a/arch/arm/kernel/kprobes-test.h b/arch/arm/kernel/kprobes-test.h new file mode 100644 index 00000000000..0dc5d77b935 --- /dev/null +++ b/arch/arm/kernel/kprobes-test.h @@ -0,0 +1,392 @@ +/* + * arch/arm/kernel/kprobes-test.h + * + * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>. + * + * 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 VERBOSE 0 /* Set to '1' for more logging of test cases */ + +#ifdef CONFIG_THUMB2_KERNEL +#define NORMAL_ISA "16" +#else +#define NORMAL_ISA "32" +#endif + + +/* Flags used in kprobe_test_flags */ +#define TEST_FLAG_NO_ITBLOCK	(1<<0) +#define TEST_FLAG_FULL_ITBLOCK	(1<<1) +#define TEST_FLAG_NARROW_INSTR	(1<<2) + +extern int kprobe_test_flags; +extern int kprobe_test_cc_position; + + +#define TEST_MEMORY_SIZE 256 + + +/* + * Test case structures. + * + * The arguments given to test cases can be one of three types. + * + *   ARG_TYPE_REG + *	Load a register with the given value. + * + *   ARG_TYPE_PTR + *	Load a register with a pointer into the stack buffer (SP + given value). + * + *   ARG_TYPE_MEM + *	Store the given value into the stack buffer at [SP+index]. + * + */ + +#define	ARG_TYPE_END	0 +#define	ARG_TYPE_REG	1 +#define	ARG_TYPE_PTR	2 +#define	ARG_TYPE_MEM	3 + +#define ARG_FLAG_UNSUPPORTED	0x01 +#define ARG_FLAG_SUPPORTED	0x02 +#define ARG_FLAG_THUMB		0x10	/* Must be 16 so TEST_ISA can be used */ +#define ARG_FLAG_ARM		0x20	/* Must be 32 so TEST_ISA can be used */ + +struct test_arg { +	u8	type;		/* ARG_TYPE_x */ +	u8	_padding[7]; +}; + +struct test_arg_regptr { +	u8	type;		/* ARG_TYPE_REG or ARG_TYPE_PTR */ +	u8	reg; +	u8	_padding[2]; +	u32	val; +}; + +struct test_arg_mem { +	u8	type;		/* ARG_TYPE_MEM */ +	u8	index; +	u8	_padding[2]; +	u32	val; +}; + +struct test_arg_end { +	u8	type;		/* ARG_TYPE_END */ +	u8	flags;		/* ARG_FLAG_x */ +	u16	code_offset; +	u16	branch_offset; +	u16	end_offset; +}; + + +/* + * Building blocks for test cases. + * + * Each test case is wrapped between TESTCASE_START and TESTCASE_END. + * + * To specify arguments for a test case the TEST_ARG_{REG,PTR,MEM} macros are + * used followed by a terminating TEST_ARG_END. + * + * After this, the instruction to be tested is defined with TEST_INSTRUCTION. + * Or for branches, TEST_BRANCH_B and TEST_BRANCH_F (branch forwards/backwards). + * + * Some specific test cases may make use of other custom constructs. + */ + +#if VERBOSE +#define verbose(fmt, ...) pr_info(fmt, ##__VA_ARGS__) +#else +#define verbose(fmt, ...) +#endif + +#define TEST_GROUP(title)					\ +	verbose("\n");						\ +	verbose(title"\n");					\ +	verbose("---------------------------------------------------------\n"); + +#define TESTCASE_START(title)					\ +	__asm__ __volatile__ (					\ +	"bl	__kprobes_test_case_start		\n\t"	\ +	/* don't use .asciz here as 'title' may be */		\ +	/* multiple strings to be concatenated.  */		\ +	".ascii "#title"				\n\t"	\ +	".byte	0					\n\t"	\ +	".align	2					\n\t" + +#define	TEST_ARG_REG(reg, val)					\ +	".byte	"__stringify(ARG_TYPE_REG)"		\n\t"	\ +	".byte	"#reg"					\n\t"	\ +	".short	0					\n\t"	\ +	".word	"#val"					\n\t" + +#define	TEST_ARG_PTR(reg, val)					\ +	".byte	"__stringify(ARG_TYPE_PTR)"		\n\t"	\ +	".byte	"#reg"					\n\t"	\ +	".short	0					\n\t"	\ +	".word	"#val"					\n\t" + +#define	TEST_ARG_MEM(index, val)				\ +	".byte	"__stringify(ARG_TYPE_MEM)"		\n\t"	\ +	".byte	"#index"				\n\t"	\ +	".short	0					\n\t"	\ +	".word	"#val"					\n\t" + +#define	TEST_ARG_END(flags)					\ +	".byte	"__stringify(ARG_TYPE_END)"		\n\t"	\ +	".byte	"TEST_ISA flags"			\n\t"	\ +	".short	50f-0f					\n\t"	\ +	".short	2f-0f					\n\t"	\ +	".short	99f-0f					\n\t"	\ +	".code "TEST_ISA"				\n\t"	\ +	"0:						\n\t" + +#define TEST_INSTRUCTION(instruction)				\ +	"50:	nop					\n\t"	\ +	"1:	"instruction"				\n\t"	\ +	"	nop					\n\t" + +#define TEST_BRANCH_F(instruction, xtra_dist)			\ +	TEST_INSTRUCTION(instruction)				\ +	".if "#xtra_dist"				\n\t"	\ +	"	b	99f				\n\t"	\ +	".space "#xtra_dist"				\n\t"	\ +	".endif						\n\t"	\ +	"	b	99f				\n\t"	\ +	"2:	nop					\n\t" + +#define TEST_BRANCH_B(instruction, xtra_dist)			\ +	"	b	50f				\n\t"	\ +	"	b	99f				\n\t"	\ +	"2:	nop					\n\t"	\ +	"	b	99f				\n\t"	\ +	".if "#xtra_dist"				\n\t"	\ +	".space "#xtra_dist"				\n\t"	\ +	".endif						\n\t"	\ +	TEST_INSTRUCTION(instruction) + +#define TESTCASE_END						\ +	"2:						\n\t"	\ +	"99:						\n\t"	\ +	"	bl __kprobes_test_case_end_"TEST_ISA"	\n\t"	\ +	".code "NORMAL_ISA"				\n\t"	\ +	: :							\ +	: "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"	\ +	); + + +/* + * Macros to define test cases. + * + * Those of the form TEST_{R,P,M}* can be used to define test cases + * which take combinations of the three basic types of arguments. E.g. + * + *   TEST_R	One register argument + *   TEST_RR	Two register arguments + *   TEST_RPR	A register, a pointer, then a register argument + * + * For testing instructions which may branch, there are macros TEST_BF_* + * and TEST_BB_* for branching forwards and backwards. + * + * TEST_SUPPORTED and TEST_UNSUPPORTED don't cause the code to be executed, + * the just verify that a kprobe is or is not allowed on the given instruction. + */ + +#define TEST(code)				\ +	TESTCASE_START(code)			\ +	TEST_ARG_END("")			\ +	TEST_INSTRUCTION(code)			\ +	TESTCASE_END + +#define TEST_UNSUPPORTED(code)					\ +	TESTCASE_START(code)					\ +	TEST_ARG_END("|"__stringify(ARG_FLAG_UNSUPPORTED))	\ +	TEST_INSTRUCTION(code)					\ +	TESTCASE_END + +#define TEST_SUPPORTED(code)					\ +	TESTCASE_START(code)					\ +	TEST_ARG_END("|"__stringify(ARG_FLAG_SUPPORTED))	\ +	TEST_INSTRUCTION(code)					\ +	TESTCASE_END + +#define TEST_R(code1, reg, val, code2)			\ +	TESTCASE_START(code1 #reg code2)		\ +	TEST_ARG_REG(reg, val)				\ +	TEST_ARG_END("")				\ +	TEST_INSTRUCTION(code1 #reg code2)		\ +	TESTCASE_END + +#define TEST_RR(code1, reg1, val1, code2, reg2, val2, code3)	\ +	TESTCASE_START(code1 #reg1 code2 #reg2 code3)		\ +	TEST_ARG_REG(reg1, val1)				\ +	TEST_ARG_REG(reg2, val2)				\ +	TEST_ARG_END("")					\ +	TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3)		\ +	TESTCASE_END + +#define TEST_RRR(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4)\ +	TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4)		\ +	TEST_ARG_REG(reg1, val1)						\ +	TEST_ARG_REG(reg2, val2)						\ +	TEST_ARG_REG(reg3, val3)						\ +	TEST_ARG_END("")							\ +	TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4)		\ +	TESTCASE_END + +#define TEST_RRRR(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4, reg4, val4)	\ +	TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4 #reg4)		\ +	TEST_ARG_REG(reg1, val1)						\ +	TEST_ARG_REG(reg2, val2)						\ +	TEST_ARG_REG(reg3, val3)						\ +	TEST_ARG_REG(reg4, val4)						\ +	TEST_ARG_END("")							\ +	TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4 #reg4)	\ +	TESTCASE_END + +#define TEST_P(code1, reg1, val1, code2)	\ +	TESTCASE_START(code1 #reg1 code2)	\ +	TEST_ARG_PTR(reg1, val1)		\ +	TEST_ARG_END("")			\ +	TEST_INSTRUCTION(code1 #reg1 code2)	\ +	TESTCASE_END + +#define TEST_PR(code1, reg1, val1, code2, reg2, val2, code3)	\ +	TESTCASE_START(code1 #reg1 code2 #reg2 code3)		\ +	TEST_ARG_PTR(reg1, val1)				\ +	TEST_ARG_REG(reg2, val2)				\ +	TEST_ARG_END("")					\ +	TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3)		\ +	TESTCASE_END + +#define TEST_RP(code1, reg1, val1, code2, reg2, val2, code3)	\ +	TESTCASE_START(code1 #reg1 code2 #reg2 code3)		\ +	TEST_ARG_REG(reg1, val1)				\ +	TEST_ARG_PTR(reg2, val2)				\ +	TEST_ARG_END("")					\ +	TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3)		\ +	TESTCASE_END + +#define TEST_PRR(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4)\ +	TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4)		\ +	TEST_ARG_PTR(reg1, val1)						\ +	TEST_ARG_REG(reg2, val2)						\ +	TEST_ARG_REG(reg3, val3)						\ +	TEST_ARG_END("")							\ +	TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4)		\ +	TESTCASE_END + +#define TEST_RPR(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4)\ +	TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4)		\ +	TEST_ARG_REG(reg1, val1)						\ +	TEST_ARG_PTR(reg2, val2)						\ +	TEST_ARG_REG(reg3, val3)						\ +	TEST_ARG_END("")							\ +	TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4)		\ +	TESTCASE_END + +#define TEST_RRP(code1, reg1, val1, code2, reg2, val2, code3, reg3, val3, code4)\ +	TESTCASE_START(code1 #reg1 code2 #reg2 code3 #reg3 code4)		\ +	TEST_ARG_REG(reg1, val1)						\ +	TEST_ARG_REG(reg2, val2)						\ +	TEST_ARG_PTR(reg3, val3)						\ +	TEST_ARG_END("")							\ +	TEST_INSTRUCTION(code1 #reg1 code2 #reg2 code3 #reg3 code4)		\ +	TESTCASE_END + +#define TEST_BF_P(code1, reg1, val1, code2)	\ +	TESTCASE_START(code1 #reg1 code2)	\ +	TEST_ARG_PTR(reg1, val1)		\ +	TEST_ARG_END("")			\ +	TEST_BRANCH_F(code1 #reg1 code2, 0)	\ +	TESTCASE_END + +#define TEST_BF_X(code, xtra_dist)		\ +	TESTCASE_START(code)			\ +	TEST_ARG_END("")			\ +	TEST_BRANCH_F(code, xtra_dist)		\ +	TESTCASE_END + +#define TEST_BB_X(code, xtra_dist)		\ +	TESTCASE_START(code)			\ +	TEST_ARG_END("")			\ +	TEST_BRANCH_B(code, xtra_dist)		\ +	TESTCASE_END + +#define TEST_BF_RX(code1, reg, val, code2, xtra_dist)	\ +	TESTCASE_START(code1 #reg code2)		\ +	TEST_ARG_REG(reg, val)				\ +	TEST_ARG_END("")				\ +	TEST_BRANCH_F(code1 #reg code2, xtra_dist)	\ +	TESTCASE_END + +#define TEST_BB_RX(code1, reg, val, code2, xtra_dist)	\ +	TESTCASE_START(code1 #reg code2)		\ +	TEST_ARG_REG(reg, val)				\ +	TEST_ARG_END("")				\ +	TEST_BRANCH_B(code1 #reg code2, xtra_dist)	\ +	TESTCASE_END + +#define TEST_BF(code)	TEST_BF_X(code, 0) +#define TEST_BB(code)	TEST_BB_X(code, 0) + +#define TEST_BF_R(code1, reg, val, code2) TEST_BF_RX(code1, reg, val, code2, 0) +#define TEST_BB_R(code1, reg, val, code2) TEST_BB_RX(code1, reg, val, code2, 0) + +#define TEST_BF_RR(code1, reg1, val1, code2, reg2, val2, code3)	\ +	TESTCASE_START(code1 #reg1 code2 #reg2 code3)		\ +	TEST_ARG_REG(reg1, val1)				\ +	TEST_ARG_REG(reg2, val2)				\ +	TEST_ARG_END("")					\ +	TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3, 0)		\ +	TESTCASE_END + +#define TEST_X(code, codex)			\ +	TESTCASE_START(code)			\ +	TEST_ARG_END("")			\ +	TEST_INSTRUCTION(code)			\ +	"	b	99f		\n\t"	\ +	"	"codex"			\n\t"	\ +	TESTCASE_END + +#define TEST_RX(code1, reg, val, code2, codex)		\ +	TESTCASE_START(code1 #reg code2)		\ +	TEST_ARG_REG(reg, val)				\ +	TEST_ARG_END("")				\ +	TEST_INSTRUCTION(code1 __stringify(reg) code2)	\ +	"	b	99f		\n\t"		\ +	"	"codex"			\n\t"		\ +	TESTCASE_END + +#define TEST_RRX(code1, reg1, val1, code2, reg2, val2, code3, codex)		\ +	TESTCASE_START(code1 #reg1 code2 #reg2 code3)				\ +	TEST_ARG_REG(reg1, val1)						\ +	TEST_ARG_REG(reg2, val2)						\ +	TEST_ARG_END("")							\ +	TEST_INSTRUCTION(code1 __stringify(reg1) code2 __stringify(reg2) code3)	\ +	"	b	99f		\n\t"					\ +	"	"codex"			\n\t"					\ +	TESTCASE_END + + +/* Various values used in test cases... */ +#define N(val)	(val ^ 0xffffffff) +#define VAL1	0x12345678 +#define VAL2	N(VAL1) +#define VAL3	0xa5f801 +#define VAL4	N(VAL3) +#define VALM	0x456789ab +#define VALR	0xdeaddead +#define HH1	0x0123fecb +#define HH2	0xa9874567 + + +#ifdef CONFIG_THUMB2_KERNEL +void kprobe_thumb16_test_cases(void); +void kprobe_thumb32_test_cases(void); +#else +void kprobe_arm_test_cases(void); +#endif diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/kernel/kprobes-thumb.c index 902ca59e8b1..8f96ec778e8 100644 --- a/arch/arm/kernel/kprobes-thumb.c +++ b/arch/arm/kernel/kprobes-thumb.c @@ -10,6 +10,7 @@  #include <linux/kernel.h>  #include <linux/kprobes.h> +#include <linux/module.h>  #include "kprobes.h" @@ -943,6 +944,9 @@ const union decode_item kprobe_decode_thumb32_table[] = {  	 */  	DECODE_END  }; +#ifdef CONFIG_ARM_KPROBES_TEST_MODULE +EXPORT_SYMBOL_GPL(kprobe_decode_thumb32_table); +#endif  static void __kprobes  t16_simulate_bxblx(struct kprobe *p, struct pt_regs *regs) @@ -1423,6 +1427,9 @@ const union decode_item kprobe_decode_thumb16_table[] = {  	DECODE_END  }; +#ifdef CONFIG_ARM_KPROBES_TEST_MODULE +EXPORT_SYMBOL_GPL(kprobe_decode_thumb16_table); +#endif  static unsigned long __kprobes thumb_check_cc(unsigned long cpsr)  { diff --git a/arch/arm/kernel/kprobes.h b/arch/arm/kernel/kprobes.h index a6aeda0a6c7..38945f78f9f 100644 --- a/arch/arm/kernel/kprobes.h +++ b/arch/arm/kernel/kprobes.h @@ -413,6 +413,14 @@ struct decode_reject {  	DECODE_HEADER(DECODE_TYPE_REJECT, _mask, _value, 0) +#ifdef CONFIG_THUMB2_KERNEL +extern const union decode_item kprobe_decode_thumb16_table[]; +extern const union decode_item kprobe_decode_thumb32_table[]; +#else +extern const union decode_item kprobe_decode_arm_table[]; +#endif + +  int kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,  			const union decode_item *table, bool thumb16); diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 53c9c2610cb..e6e5d7c84f1 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -12,6 +12,7 @@   */  #define pr_fmt(fmt) "hw perfevents: " fmt +#include <linux/bitmap.h>  #include <linux/interrupt.h>  #include <linux/kernel.h>  #include <linux/module.h> @@ -26,16 +27,8 @@  #include <asm/pmu.h>  #include <asm/stacktrace.h> -static struct platform_device *pmu_device; -  /* - * Hardware lock to serialize accesses to PMU registers. Needed for the - * read/modify/write sequences. - */ -static DEFINE_RAW_SPINLOCK(pmu_lock); - -/* - * ARMv6 supports a maximum of 3 events, starting from index 1. If we add + * ARMv6 supports a maximum of 3 events, starting from index 0. If we add   * another platform that supports more, we need to increase this to be the   * largest of all platforms.   * @@ -43,62 +36,24 @@ static DEFINE_RAW_SPINLOCK(pmu_lock);   *  cycle counter CCNT + 31 events counters CNT0..30.   *  Cortex-A8 has 1+4 counters, Cortex-A9 has 1+6 counters.   */ -#define ARMPMU_MAX_HWEVENTS		33 +#define ARMPMU_MAX_HWEVENTS		32 -/* The events for a given CPU. */ -struct cpu_hw_events { -	/* -	 * The events that are active on the CPU for the given index. Index 0 -	 * is reserved. -	 */ -	struct perf_event	*events[ARMPMU_MAX_HWEVENTS]; +static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events); +static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask); +static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events); -	/* -	 * A 1 bit for an index indicates that the counter is being used for -	 * an event. A 0 means that the counter can be used. -	 */ -	unsigned long		used_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)]; - -	/* -	 * A 1 bit for an index indicates that the counter is actively being -	 * used. -	 */ -	unsigned long		active_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)]; -}; -static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); - -struct arm_pmu { -	enum arm_perf_pmu_ids id; -	const char	*name; -	irqreturn_t	(*handle_irq)(int irq_num, void *dev); -	void		(*enable)(struct hw_perf_event *evt, int idx); -	void		(*disable)(struct hw_perf_event *evt, int idx); -	int		(*get_event_idx)(struct cpu_hw_events *cpuc, -					 struct hw_perf_event *hwc); -	u32		(*read_counter)(int idx); -	void		(*write_counter)(int idx, u32 val); -	void		(*start)(void); -	void		(*stop)(void); -	void		(*reset)(void *); -	const unsigned	(*cache_map)[PERF_COUNT_HW_CACHE_MAX] -				    [PERF_COUNT_HW_CACHE_OP_MAX] -				    [PERF_COUNT_HW_CACHE_RESULT_MAX]; -	const unsigned	(*event_map)[PERF_COUNT_HW_MAX]; -	u32		raw_event_mask; -	int		num_events; -	u64		max_period; -}; +#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))  /* Set at runtime when we know what CPU type we are. */ -static const struct arm_pmu *armpmu; +static struct arm_pmu *cpu_pmu;  enum arm_perf_pmu_ids  armpmu_get_pmu_id(void)  {  	int id = -ENODEV; -	if (armpmu != NULL) -		id = armpmu->id; +	if (cpu_pmu != NULL) +		id = cpu_pmu->id;  	return id;  } @@ -109,8 +64,8 @@ armpmu_get_max_events(void)  {  	int max_events = 0; -	if (armpmu != NULL) -		max_events = armpmu->num_events; +	if (cpu_pmu != NULL) +		max_events = cpu_pmu->num_events;  	return max_events;  } @@ -130,7 +85,11 @@ EXPORT_SYMBOL_GPL(perf_num_counters);  #define CACHE_OP_UNSUPPORTED		0xFFFF  static int -armpmu_map_cache_event(u64 config) +armpmu_map_cache_event(const unsigned (*cache_map) +				      [PERF_COUNT_HW_CACHE_MAX] +				      [PERF_COUNT_HW_CACHE_OP_MAX] +				      [PERF_COUNT_HW_CACHE_RESULT_MAX], +		       u64 config)  {  	unsigned int cache_type, cache_op, cache_result, ret; @@ -146,7 +105,7 @@ armpmu_map_cache_event(u64 config)  	if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)  		return -EINVAL; -	ret = (int)(*armpmu->cache_map)[cache_type][cache_op][cache_result]; +	ret = (int)(*cache_map)[cache_type][cache_op][cache_result];  	if (ret == CACHE_OP_UNSUPPORTED)  		return -ENOENT; @@ -155,23 +114,46 @@ armpmu_map_cache_event(u64 config)  }  static int -armpmu_map_event(u64 config) +armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)  { -	int mapping = (*armpmu->event_map)[config]; -	return mapping == HW_OP_UNSUPPORTED ? -EOPNOTSUPP : mapping; +	int mapping = (*event_map)[config]; +	return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;  }  static int -armpmu_map_raw_event(u64 config) +armpmu_map_raw_event(u32 raw_event_mask, u64 config)  { -	return (int)(config & armpmu->raw_event_mask); +	return (int)(config & raw_event_mask);  } -static int +static int map_cpu_event(struct perf_event *event, +			 const unsigned (*event_map)[PERF_COUNT_HW_MAX], +			 const unsigned (*cache_map) +					[PERF_COUNT_HW_CACHE_MAX] +					[PERF_COUNT_HW_CACHE_OP_MAX] +					[PERF_COUNT_HW_CACHE_RESULT_MAX], +			 u32 raw_event_mask) +{ +	u64 config = event->attr.config; + +	switch (event->attr.type) { +	case PERF_TYPE_HARDWARE: +		return armpmu_map_event(event_map, config); +	case PERF_TYPE_HW_CACHE: +		return armpmu_map_cache_event(cache_map, config); +	case PERF_TYPE_RAW: +		return armpmu_map_raw_event(raw_event_mask, config); +	} + +	return -ENOENT; +} + +int  armpmu_event_set_period(struct perf_event *event,  			struct hw_perf_event *hwc,  			int idx)  { +	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);  	s64 left = local64_read(&hwc->period_left);  	s64 period = hwc->sample_period;  	int ret = 0; @@ -202,11 +184,12 @@ armpmu_event_set_period(struct perf_event *event,  	return ret;  } -static u64 +u64  armpmu_event_update(struct perf_event *event,  		    struct hw_perf_event *hwc,  		    int idx, int overflow)  { +	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);  	u64 delta, prev_raw_count, new_raw_count;  again: @@ -246,11 +229,9 @@ armpmu_read(struct perf_event *event)  static void  armpmu_stop(struct perf_event *event, int flags)  { +	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);  	struct hw_perf_event *hwc = &event->hw; -	if (!armpmu) -		return; -  	/*  	 * ARM pmu always has to update the counter, so ignore  	 * PERF_EF_UPDATE, see comments in armpmu_start(). @@ -266,11 +247,9 @@ armpmu_stop(struct perf_event *event, int flags)  static void  armpmu_start(struct perf_event *event, int flags)  { +	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);  	struct hw_perf_event *hwc = &event->hw; -	if (!armpmu) -		return; -  	/*  	 * ARM pmu always has to reprogram the period, so ignore  	 * PERF_EF_RELOAD, see the comment below. @@ -293,16 +272,16 @@ armpmu_start(struct perf_event *event, int flags)  static void  armpmu_del(struct perf_event *event, int flags)  { -	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); +	struct arm_pmu *armpmu = to_arm_pmu(event->pmu); +	struct pmu_hw_events *hw_events = armpmu->get_hw_events();  	struct hw_perf_event *hwc = &event->hw;  	int idx = hwc->idx;  	WARN_ON(idx < 0); -	clear_bit(idx, cpuc->active_mask);  	armpmu_stop(event, PERF_EF_UPDATE); -	cpuc->events[idx] = NULL; -	clear_bit(idx, cpuc->used_mask); +	hw_events->events[idx] = NULL; +	clear_bit(idx, hw_events->used_mask);  	perf_event_update_userpage(event);  } @@ -310,7 +289,8 @@ armpmu_del(struct perf_event *event, int flags)  static int  armpmu_add(struct perf_event *event, int flags)  { -	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); +	struct arm_pmu *armpmu = to_arm_pmu(event->pmu); +	struct pmu_hw_events *hw_events = armpmu->get_hw_events();  	struct hw_perf_event *hwc = &event->hw;  	int idx;  	int err = 0; @@ -318,7 +298,7 @@ armpmu_add(struct perf_event *event, int flags)  	perf_pmu_disable(event->pmu);  	/* If we don't have a space for the counter then finish early. */ -	idx = armpmu->get_event_idx(cpuc, hwc); +	idx = armpmu->get_event_idx(hw_events, hwc);  	if (idx < 0) {  		err = idx;  		goto out; @@ -330,8 +310,7 @@ armpmu_add(struct perf_event *event, int flags)  	 */  	event->hw.idx = idx;  	armpmu->disable(hwc, idx); -	cpuc->events[idx] = event; -	set_bit(idx, cpuc->active_mask); +	hw_events->events[idx] = event;  	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;  	if (flags & PERF_EF_START) @@ -345,25 +324,25 @@ out:  	return err;  } -static struct pmu pmu; -  static int -validate_event(struct cpu_hw_events *cpuc, +validate_event(struct pmu_hw_events *hw_events,  	       struct perf_event *event)  { +	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);  	struct hw_perf_event fake_event = event->hw; +	struct pmu *leader_pmu = event->group_leader->pmu; -	if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF) +	if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF)  		return 1; -	return armpmu->get_event_idx(cpuc, &fake_event) >= 0; +	return armpmu->get_event_idx(hw_events, &fake_event) >= 0;  }  static int  validate_group(struct perf_event *event)  {  	struct perf_event *sibling, *leader = event->group_leader; -	struct cpu_hw_events fake_pmu; +	struct pmu_hw_events fake_pmu;  	memset(&fake_pmu, 0, sizeof(fake_pmu)); @@ -383,110 +362,119 @@ validate_group(struct perf_event *event)  static irqreturn_t armpmu_platform_irq(int irq, void *dev)  { -	struct arm_pmu_platdata *plat = dev_get_platdata(&pmu_device->dev); +	struct arm_pmu *armpmu = (struct arm_pmu *) dev; +	struct platform_device *plat_device = armpmu->plat_device; +	struct arm_pmu_platdata *plat = dev_get_platdata(&plat_device->dev);  	return plat->handle_irq(irq, dev, armpmu->handle_irq);  } +static void +armpmu_release_hardware(struct arm_pmu *armpmu) +{ +	int i, irq, irqs; +	struct platform_device *pmu_device = armpmu->plat_device; + +	irqs = min(pmu_device->num_resources, num_possible_cpus()); + +	for (i = 0; i < irqs; ++i) { +		if (!cpumask_test_and_clear_cpu(i, &armpmu->active_irqs)) +			continue; +		irq = platform_get_irq(pmu_device, i); +		if (irq >= 0) +			free_irq(irq, armpmu); +	} + +	release_pmu(armpmu->type); +} +  static int -armpmu_reserve_hardware(void) +armpmu_reserve_hardware(struct arm_pmu *armpmu)  {  	struct arm_pmu_platdata *plat;  	irq_handler_t handle_irq; -	int i, err = -ENODEV, irq; +	int i, err, irq, irqs; +	struct platform_device *pmu_device = armpmu->plat_device; -	pmu_device = reserve_pmu(ARM_PMU_DEVICE_CPU); -	if (IS_ERR(pmu_device)) { +	err = reserve_pmu(armpmu->type); +	if (err) {  		pr_warning("unable to reserve pmu\n"); -		return PTR_ERR(pmu_device); +		return err;  	} -	init_pmu(ARM_PMU_DEVICE_CPU); -  	plat = dev_get_platdata(&pmu_device->dev);  	if (plat && plat->handle_irq)  		handle_irq = armpmu_platform_irq;  	else  		handle_irq = armpmu->handle_irq; -	if (pmu_device->num_resources < 1) { +	irqs = min(pmu_device->num_resources, num_possible_cpus()); +	if (irqs < 1) {  		pr_err("no irqs for PMUs defined\n");  		return -ENODEV;  	} -	for (i = 0; i < pmu_device->num_resources; ++i) { +	for (i = 0; i < irqs; ++i) { +		err = 0;  		irq = platform_get_irq(pmu_device, i);  		if (irq < 0)  			continue; +		/* +		 * If we have a single PMU interrupt that we can't shift, +		 * assume that we're running on a uniprocessor machine and +		 * continue. Otherwise, continue without this interrupt. +		 */ +		if (irq_set_affinity(irq, cpumask_of(i)) && irqs > 1) { +			pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n", +				    irq, i); +			continue; +		} +  		err = request_irq(irq, handle_irq,  				  IRQF_DISABLED | IRQF_NOBALANCING, -				  "armpmu", NULL); +				  "arm-pmu", armpmu);  		if (err) { -			pr_warning("unable to request IRQ%d for ARM perf " -				"counters\n", irq); -			break; +			pr_err("unable to request IRQ%d for ARM PMU counters\n", +				irq); +			armpmu_release_hardware(armpmu); +			return err;  		} -	} -	if (err) { -		for (i = i - 1; i >= 0; --i) { -			irq = platform_get_irq(pmu_device, i); -			if (irq >= 0) -				free_irq(irq, NULL); -		} -		release_pmu(ARM_PMU_DEVICE_CPU); -		pmu_device = NULL; +		cpumask_set_cpu(i, &armpmu->active_irqs);  	} -	return err; +	return 0;  }  static void -armpmu_release_hardware(void) +hw_perf_event_destroy(struct perf_event *event)  { -	int i, irq; +	struct arm_pmu *armpmu = to_arm_pmu(event->pmu); +	atomic_t *active_events	 = &armpmu->active_events; +	struct mutex *pmu_reserve_mutex = &armpmu->reserve_mutex; -	for (i = pmu_device->num_resources - 1; i >= 0; --i) { -		irq = platform_get_irq(pmu_device, i); -		if (irq >= 0) -			free_irq(irq, NULL); +	if (atomic_dec_and_mutex_lock(active_events, pmu_reserve_mutex)) { +		armpmu_release_hardware(armpmu); +		mutex_unlock(pmu_reserve_mutex);  	} -	armpmu->stop(); - -	release_pmu(ARM_PMU_DEVICE_CPU); -	pmu_device = NULL;  } -static atomic_t active_events = ATOMIC_INIT(0); -static DEFINE_MUTEX(pmu_reserve_mutex); - -static void -hw_perf_event_destroy(struct perf_event *event) +static int +event_requires_mode_exclusion(struct perf_event_attr *attr)  { -	if (atomic_dec_and_mutex_lock(&active_events, &pmu_reserve_mutex)) { -		armpmu_release_hardware(); -		mutex_unlock(&pmu_reserve_mutex); -	} +	return attr->exclude_idle || attr->exclude_user || +	       attr->exclude_kernel || attr->exclude_hv;  }  static int  __hw_perf_event_init(struct perf_event *event)  { +	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);  	struct hw_perf_event *hwc = &event->hw;  	int mapping, err; -	/* Decode the generic type into an ARM event identifier. */ -	if (PERF_TYPE_HARDWARE == event->attr.type) { -		mapping = armpmu_map_event(event->attr.config); -	} else if (PERF_TYPE_HW_CACHE == event->attr.type) { -		mapping = armpmu_map_cache_event(event->attr.config); -	} else if (PERF_TYPE_RAW == event->attr.type) { -		mapping = armpmu_map_raw_event(event->attr.config); -	} else { -		pr_debug("event type %x not supported\n", event->attr.type); -		return -EOPNOTSUPP; -	} +	mapping = armpmu->map_event(event);  	if (mapping < 0) {  		pr_debug("event %x:%llx not supported\n", event->attr.type, @@ -495,34 +483,31 @@ __hw_perf_event_init(struct perf_event *event)  	}  	/* +	 * We don't assign an index until we actually place the event onto +	 * hardware. Use -1 to signify that we haven't decided where to put it +	 * yet. For SMP systems, each core has it's own PMU so we can't do any +	 * clever allocation or constraints checking at this point. +	 */ +	hwc->idx		= -1; +	hwc->config_base	= 0; +	hwc->config		= 0; +	hwc->event_base		= 0; + +	/*  	 * Check whether we need to exclude the counter from certain modes. -	 * The ARM performance counters are on all of the time so if someone -	 * has asked us for some excludes then we have to fail.  	 */ -	if (event->attr.exclude_kernel || event->attr.exclude_user || -	    event->attr.exclude_hv || event->attr.exclude_idle) { +	if ((!armpmu->set_event_filter || +	     armpmu->set_event_filter(hwc, &event->attr)) && +	     event_requires_mode_exclusion(&event->attr)) {  		pr_debug("ARM performance counters do not support "  			 "mode exclusion\n");  		return -EPERM;  	}  	/* -	 * We don't assign an index until we actually place the event onto -	 * hardware. Use -1 to signify that we haven't decided where to put it -	 * yet. For SMP systems, each core has it's own PMU so we can't do any -	 * clever allocation or constraints checking at this point. +	 * Store the event encoding into the config_base field.  	 */ -	hwc->idx = -1; - -	/* -	 * Store the event encoding into the config_base field. config and -	 * event_base are unused as the only 2 things we need to know are -	 * the event mapping and the counter to use. The counter to use is -	 * also the indx and the config_base is the event type. -	 */ -	hwc->config_base	    = (unsigned long)mapping; -	hwc->config		    = 0; -	hwc->event_base		    = 0; +	hwc->config_base	    |= (unsigned long)mapping;  	if (!hwc->sample_period) {  		hwc->sample_period  = armpmu->max_period; @@ -542,32 +527,23 @@ __hw_perf_event_init(struct perf_event *event)  static int armpmu_event_init(struct perf_event *event)  { +	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);  	int err = 0; +	atomic_t *active_events = &armpmu->active_events; -	switch (event->attr.type) { -	case PERF_TYPE_RAW: -	case PERF_TYPE_HARDWARE: -	case PERF_TYPE_HW_CACHE: -		break; - -	default: +	if (armpmu->map_event(event) == -ENOENT)  		return -ENOENT; -	} - -	if (!armpmu) -		return -ENODEV;  	event->destroy = hw_perf_event_destroy; -	if (!atomic_inc_not_zero(&active_events)) { -		mutex_lock(&pmu_reserve_mutex); -		if (atomic_read(&active_events) == 0) { -			err = armpmu_reserve_hardware(); -		} +	if (!atomic_inc_not_zero(active_events)) { +		mutex_lock(&armpmu->reserve_mutex); +		if (atomic_read(active_events) == 0) +			err = armpmu_reserve_hardware(armpmu);  		if (!err) -			atomic_inc(&active_events); -		mutex_unlock(&pmu_reserve_mutex); +			atomic_inc(active_events); +		mutex_unlock(&armpmu->reserve_mutex);  	}  	if (err) @@ -582,22 +558,9 @@ static int armpmu_event_init(struct perf_event *event)  static void armpmu_enable(struct pmu *pmu)  { -	/* Enable all of the perf events on hardware. */ -	int idx, enabled = 0; -	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); - -	if (!armpmu) -		return; - -	for (idx = 0; idx <= armpmu->num_events; ++idx) { -		struct perf_event *event = cpuc->events[idx]; - -		if (!event) -			continue; - -		armpmu->enable(&event->hw, idx); -		enabled = 1; -	} +	struct arm_pmu *armpmu = to_arm_pmu(pmu); +	struct pmu_hw_events *hw_events = armpmu->get_hw_events(); +	int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);  	if (enabled)  		armpmu->start(); @@ -605,20 +568,32 @@ static void armpmu_enable(struct pmu *pmu)  static void armpmu_disable(struct pmu *pmu)  { -	if (armpmu) -		armpmu->stop(); +	struct arm_pmu *armpmu = to_arm_pmu(pmu); +	armpmu->stop(); +} + +static void __init armpmu_init(struct arm_pmu *armpmu) +{ +	atomic_set(&armpmu->active_events, 0); +	mutex_init(&armpmu->reserve_mutex); + +	armpmu->pmu = (struct pmu) { +		.pmu_enable	= armpmu_enable, +		.pmu_disable	= armpmu_disable, +		.event_init	= armpmu_event_init, +		.add		= armpmu_add, +		.del		= armpmu_del, +		.start		= armpmu_start, +		.stop		= armpmu_stop, +		.read		= armpmu_read, +	};  } -static struct pmu pmu = { -	.pmu_enable	= armpmu_enable, -	.pmu_disable	= armpmu_disable, -	.event_init	= armpmu_event_init, -	.add		= armpmu_add, -	.del		= armpmu_del, -	.start		= armpmu_start, -	.stop		= armpmu_stop, -	.read		= armpmu_read, -}; +int __init armpmu_register(struct arm_pmu *armpmu, char *name, int type) +{ +	armpmu_init(armpmu); +	return perf_pmu_register(&armpmu->pmu, name, type); +}  /* Include the PMU-specific implementations. */  #include "perf_event_xscale.c" @@ -630,14 +605,72 @@ static struct pmu pmu = {   * This requires SMP to be available, so exists as a separate initcall.   */  static int __init -armpmu_reset(void) +cpu_pmu_reset(void) +{ +	if (cpu_pmu && cpu_pmu->reset) +		return on_each_cpu(cpu_pmu->reset, NULL, 1); +	return 0; +} +arch_initcall(cpu_pmu_reset); + +/* + * PMU platform driver and devicetree bindings. + */ +static struct of_device_id armpmu_of_device_ids[] = { +	{.compatible = "arm,cortex-a9-pmu"}, +	{.compatible = "arm,cortex-a8-pmu"}, +	{.compatible = "arm,arm1136-pmu"}, +	{.compatible = "arm,arm1176-pmu"}, +	{}, +}; + +static struct platform_device_id armpmu_plat_device_ids[] = { +	{.name = "arm-pmu"}, +	{}, +}; + +static int __devinit armpmu_device_probe(struct platform_device *pdev)  { -	if (armpmu && armpmu->reset) -		return on_each_cpu(armpmu->reset, NULL, 1); +	cpu_pmu->plat_device = pdev;  	return 0;  } -arch_initcall(armpmu_reset); +static struct platform_driver armpmu_driver = { +	.driver		= { +		.name	= "arm-pmu", +		.of_match_table = armpmu_of_device_ids, +	}, +	.probe		= armpmu_device_probe, +	.id_table	= armpmu_plat_device_ids, +}; + +static int __init register_pmu_driver(void) +{ +	return platform_driver_register(&armpmu_driver); +} +device_initcall(register_pmu_driver); + +static struct pmu_hw_events *armpmu_get_cpu_events(void) +{ +	return &__get_cpu_var(cpu_hw_events); +} + +static void __init cpu_pmu_init(struct arm_pmu *armpmu) +{ +	int cpu; +	for_each_possible_cpu(cpu) { +		struct pmu_hw_events *events = &per_cpu(cpu_hw_events, cpu); +		events->events = per_cpu(hw_events, cpu); +		events->used_mask = per_cpu(used_mask, cpu); +		raw_spin_lock_init(&events->pmu_lock); +	} +	armpmu->get_hw_events = armpmu_get_cpu_events; +	armpmu->type = ARM_PMU_DEVICE_CPU; +} + +/* + * CPU PMU identification and registration. + */  static int __init  init_hw_perf_events(void)  { @@ -651,22 +684,22 @@ init_hw_perf_events(void)  		case 0xB360:	/* ARM1136 */  		case 0xB560:	/* ARM1156 */  		case 0xB760:	/* ARM1176 */ -			armpmu = armv6pmu_init(); +			cpu_pmu = armv6pmu_init();  			break;  		case 0xB020:	/* ARM11mpcore */ -			armpmu = armv6mpcore_pmu_init(); +			cpu_pmu = armv6mpcore_pmu_init();  			break;  		case 0xC080:	/* Cortex-A8 */ -			armpmu = armv7_a8_pmu_init(); +			cpu_pmu = armv7_a8_pmu_init();  			break;  		case 0xC090:	/* Cortex-A9 */ -			armpmu = armv7_a9_pmu_init(); +			cpu_pmu = armv7_a9_pmu_init();  			break;  		case 0xC050:	/* Cortex-A5 */ -			armpmu = armv7_a5_pmu_init(); +			cpu_pmu = armv7_a5_pmu_init();  			break;  		case 0xC0F0:	/* Cortex-A15 */ -			armpmu = armv7_a15_pmu_init(); +			cpu_pmu = armv7_a15_pmu_init();  			break;  		}  	/* Intel CPUs [xscale]. */ @@ -674,23 +707,23 @@ init_hw_perf_events(void)  		part_number = (cpuid >> 13) & 0x7;  		switch (part_number) {  		case 1: -			armpmu = xscale1pmu_init(); +			cpu_pmu = xscale1pmu_init();  			break;  		case 2: -			armpmu = xscale2pmu_init(); +			cpu_pmu = xscale2pmu_init();  			break;  		}  	} -	if (armpmu) { +	if (cpu_pmu) {  		pr_info("enabled with %s PMU driver, %d counters available\n", -			armpmu->name, armpmu->num_events); +			cpu_pmu->name, cpu_pmu->num_events); +		cpu_pmu_init(cpu_pmu); +		armpmu_register(cpu_pmu, "cpu", PERF_TYPE_RAW);  	} else {  		pr_info("no hardware support available\n");  	} -	perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW); -  	return 0;  }  early_initcall(init_hw_perf_events); diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c index dd7f3b9f4cb..e63d8115c01 100644 --- a/arch/arm/kernel/perf_event_v6.c +++ b/arch/arm/kernel/perf_event_v6.c @@ -54,7 +54,7 @@ enum armv6_perf_types {  };  enum armv6_counters { -	ARMV6_CYCLE_COUNTER = 1, +	ARMV6_CYCLE_COUNTER = 0,  	ARMV6_COUNTER0,  	ARMV6_COUNTER1,  }; @@ -433,6 +433,7 @@ armv6pmu_enable_event(struct hw_perf_event *hwc,  		      int idx)  {  	unsigned long val, mask, evt, flags; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events();  	if (ARMV6_CYCLE_COUNTER == idx) {  		mask	= 0; @@ -454,12 +455,29 @@ armv6pmu_enable_event(struct hw_perf_event *hwc,  	 * Mask out the current event and set the counter to count the event  	 * that we're interested in.  	 */ -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	val = armv6_pmcr_read();  	val &= ~mask;  	val |= evt;  	armv6_pmcr_write(val); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags); +} + +static int counter_is_active(unsigned long pmcr, int idx) +{ +	unsigned long mask = 0; +	if (idx == ARMV6_CYCLE_COUNTER) +		mask = ARMV6_PMCR_CCOUNT_IEN; +	else if (idx == ARMV6_COUNTER0) +		mask = ARMV6_PMCR_COUNT0_IEN; +	else if (idx == ARMV6_COUNTER1) +		mask = ARMV6_PMCR_COUNT1_IEN; + +	if (mask) +		return pmcr & mask; + +	WARN_ONCE(1, "invalid counter number (%d)\n", idx); +	return 0;  }  static irqreturn_t @@ -468,7 +486,7 @@ armv6pmu_handle_irq(int irq_num,  {  	unsigned long pmcr = armv6_pmcr_read();  	struct perf_sample_data data; -	struct cpu_hw_events *cpuc; +	struct pmu_hw_events *cpuc;  	struct pt_regs *regs;  	int idx; @@ -487,11 +505,11 @@ armv6pmu_handle_irq(int irq_num,  	perf_sample_data_init(&data, 0);  	cpuc = &__get_cpu_var(cpu_hw_events); -	for (idx = 0; idx <= armpmu->num_events; ++idx) { +	for (idx = 0; idx < cpu_pmu->num_events; ++idx) {  		struct perf_event *event = cpuc->events[idx];  		struct hw_perf_event *hwc; -		if (!test_bit(idx, cpuc->active_mask)) +		if (!counter_is_active(pmcr, idx))  			continue;  		/* @@ -508,7 +526,7 @@ armv6pmu_handle_irq(int irq_num,  			continue;  		if (perf_event_overflow(event, &data, regs)) -			armpmu->disable(hwc, idx); +			cpu_pmu->disable(hwc, idx);  	}  	/* @@ -527,28 +545,30 @@ static void  armv6pmu_start(void)  {  	unsigned long flags, val; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events(); -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	val = armv6_pmcr_read();  	val |= ARMV6_PMCR_ENABLE;  	armv6_pmcr_write(val); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static void  armv6pmu_stop(void)  {  	unsigned long flags, val; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events(); -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	val = armv6_pmcr_read();  	val &= ~ARMV6_PMCR_ENABLE;  	armv6_pmcr_write(val); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static int -armv6pmu_get_event_idx(struct cpu_hw_events *cpuc, +armv6pmu_get_event_idx(struct pmu_hw_events *cpuc,  		       struct hw_perf_event *event)  {  	/* Always place a cycle counter into the cycle counter. */ @@ -578,6 +598,7 @@ armv6pmu_disable_event(struct hw_perf_event *hwc,  		       int idx)  {  	unsigned long val, mask, evt, flags; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events();  	if (ARMV6_CYCLE_COUNTER == idx) {  		mask	= ARMV6_PMCR_CCOUNT_IEN; @@ -598,12 +619,12 @@ armv6pmu_disable_event(struct hw_perf_event *hwc,  	 * of ETM bus signal assertion cycles. The external reporting should  	 * be disabled and so this should never increment.  	 */ -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	val = armv6_pmcr_read();  	val &= ~mask;  	val |= evt;  	armv6_pmcr_write(val); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static void @@ -611,6 +632,7 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,  			      int idx)  {  	unsigned long val, mask, flags, evt = 0; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events();  	if (ARMV6_CYCLE_COUNTER == idx) {  		mask	= ARMV6_PMCR_CCOUNT_IEN; @@ -627,15 +649,21 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,  	 * Unlike UP ARMv6, we don't have a way of stopping the counters. We  	 * simply disable the interrupt reporting.  	 */ -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	val = armv6_pmcr_read();  	val &= ~mask;  	val |= evt;  	armv6_pmcr_write(val); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags); +} + +static int armv6_map_event(struct perf_event *event) +{ +	return map_cpu_event(event, &armv6_perf_map, +				&armv6_perf_cache_map, 0xFF);  } -static const struct arm_pmu armv6pmu = { +static struct arm_pmu armv6pmu = {  	.id			= ARM_PERF_PMU_ID_V6,  	.name			= "v6",  	.handle_irq		= armv6pmu_handle_irq, @@ -646,14 +674,12 @@ static const struct arm_pmu armv6pmu = {  	.get_event_idx		= armv6pmu_get_event_idx,  	.start			= armv6pmu_start,  	.stop			= armv6pmu_stop, -	.cache_map		= &armv6_perf_cache_map, -	.event_map		= &armv6_perf_map, -	.raw_event_mask		= 0xFF, +	.map_event		= armv6_map_event,  	.num_events		= 3,  	.max_period		= (1LLU << 32) - 1,  }; -static const struct arm_pmu *__init armv6pmu_init(void) +static struct arm_pmu *__init armv6pmu_init(void)  {  	return &armv6pmu;  } @@ -665,7 +691,14 @@ static const struct arm_pmu *__init armv6pmu_init(void)   * disable the interrupt reporting and update the event. When unthrottling we   * reset the period and enable the interrupt reporting.   */ -static const struct arm_pmu armv6mpcore_pmu = { + +static int armv6mpcore_map_event(struct perf_event *event) +{ +	return map_cpu_event(event, &armv6mpcore_perf_map, +				&armv6mpcore_perf_cache_map, 0xFF); +} + +static struct arm_pmu armv6mpcore_pmu = {  	.id			= ARM_PERF_PMU_ID_V6MP,  	.name			= "v6mpcore",  	.handle_irq		= armv6pmu_handle_irq, @@ -676,24 +709,22 @@ static const struct arm_pmu armv6mpcore_pmu = {  	.get_event_idx		= armv6pmu_get_event_idx,  	.start			= armv6pmu_start,  	.stop			= armv6pmu_stop, -	.cache_map		= &armv6mpcore_perf_cache_map, -	.event_map		= &armv6mpcore_perf_map, -	.raw_event_mask		= 0xFF, +	.map_event		= armv6mpcore_map_event,  	.num_events		= 3,  	.max_period		= (1LLU << 32) - 1,  }; -static const struct arm_pmu *__init armv6mpcore_pmu_init(void) +static struct arm_pmu *__init armv6mpcore_pmu_init(void)  {  	return &armv6mpcore_pmu;  }  #else -static const struct arm_pmu *__init armv6pmu_init(void) +static struct arm_pmu *__init armv6pmu_init(void)  {  	return NULL;  } -static const struct arm_pmu *__init armv6mpcore_pmu_init(void) +static struct arm_pmu *__init armv6mpcore_pmu_init(void)  {  	return NULL;  } diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index 4c851834f68..98b75738345 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c @@ -17,6 +17,9 @@   */  #ifdef CONFIG_CPU_V7 + +static struct arm_pmu armv7pmu; +  /*   * Common ARMv7 event types   * @@ -676,23 +679,24 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]  };  /* - * Perf Events counters + * Perf Events' indices   */ -enum armv7_counters { -	ARMV7_CYCLE_COUNTER		= 1,	/* Cycle counter */ -	ARMV7_COUNTER0			= 2,	/* First event counter */ -}; +#define	ARMV7_IDX_CYCLE_COUNTER	0 +#define	ARMV7_IDX_COUNTER0	1 +#define	ARMV7_IDX_COUNTER_LAST	(ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1) + +#define	ARMV7_MAX_COUNTERS	32 +#define	ARMV7_COUNTER_MASK	(ARMV7_MAX_COUNTERS - 1)  /* - * The cycle counter is ARMV7_CYCLE_COUNTER. - * The first event counter is ARMV7_COUNTER0. - * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1). + * ARMv7 low level PMNC access   */ -#define	ARMV7_COUNTER_LAST	(ARMV7_COUNTER0 + armpmu->num_events - 1)  /* - * ARMv7 low level PMNC access + * Perf Event to low level counters mapping   */ +#define	ARMV7_IDX_TO_COUNTER(x)	\ +	(((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK)  /*   * Per-CPU PMNC: config reg @@ -708,103 +712,76 @@ enum armv7_counters {  #define	ARMV7_PMNC_MASK		0x3f	 /* Mask for writable bits */  /* - * Available counters - */ -#define ARMV7_CNT0		0	/* First event counter */ -#define ARMV7_CCNT		31	/* Cycle counter */ - -/* Perf Event to low level counters mapping */ -#define ARMV7_EVENT_CNT_TO_CNTx	(ARMV7_COUNTER0 - ARMV7_CNT0) - -/* - * CNTENS: counters enable reg - */ -#define ARMV7_CNTENS_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) -#define ARMV7_CNTENS_C		(1 << ARMV7_CCNT) - -/* - * CNTENC: counters disable reg - */ -#define ARMV7_CNTENC_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) -#define ARMV7_CNTENC_C		(1 << ARMV7_CCNT) - -/* - * INTENS: counters overflow interrupt enable reg - */ -#define ARMV7_INTENS_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) -#define ARMV7_INTENS_C		(1 << ARMV7_CCNT) - -/* - * INTENC: counters overflow interrupt disable reg - */ -#define ARMV7_INTENC_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) -#define ARMV7_INTENC_C		(1 << ARMV7_CCNT) - -/* - * EVTSEL: Event selection reg + * FLAG: counters overflow flag status reg   */ -#define	ARMV7_EVTSEL_MASK	0xff		/* Mask for writable bits */ +#define	ARMV7_FLAG_MASK		0xffffffff	/* Mask for writable bits */ +#define	ARMV7_OVERFLOWED_MASK	ARMV7_FLAG_MASK  /* - * SELECT: Counter selection reg + * PMXEVTYPER: Event selection reg   */ -#define	ARMV7_SELECT_MASK	0x1f		/* Mask for writable bits */ +#define	ARMV7_EVTYPE_MASK	0xc00000ff	/* Mask for writable bits */ +#define	ARMV7_EVTYPE_EVENT	0xff		/* Mask for EVENT bits */  /* - * FLAG: counters overflow flag status reg + * Event filters for PMUv2   */ -#define ARMV7_FLAG_P(idx)	(1 << (idx - ARMV7_EVENT_CNT_TO_CNTx)) -#define ARMV7_FLAG_C		(1 << ARMV7_CCNT) -#define	ARMV7_FLAG_MASK		0xffffffff	/* Mask for writable bits */ -#define	ARMV7_OVERFLOWED_MASK	ARMV7_FLAG_MASK +#define	ARMV7_EXCLUDE_PL1	(1 << 31) +#define	ARMV7_EXCLUDE_USER	(1 << 30) +#define	ARMV7_INCLUDE_HYP	(1 << 27) -static inline unsigned long armv7_pmnc_read(void) +static inline u32 armv7_pmnc_read(void)  {  	u32 val;  	asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));  	return val;  } -static inline void armv7_pmnc_write(unsigned long val) +static inline void armv7_pmnc_write(u32 val)  {  	val &= ARMV7_PMNC_MASK;  	isb();  	asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));  } -static inline int armv7_pmnc_has_overflowed(unsigned long pmnc) +static inline int armv7_pmnc_has_overflowed(u32 pmnc)  {  	return pmnc & ARMV7_OVERFLOWED_MASK;  } -static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc, -					enum armv7_counters counter) +static inline int armv7_pmnc_counter_valid(int idx) +{ +	return idx >= ARMV7_IDX_CYCLE_COUNTER && idx <= ARMV7_IDX_COUNTER_LAST; +} + +static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc, int idx)  {  	int ret = 0; +	u32 counter; -	if (counter == ARMV7_CYCLE_COUNTER) -		ret = pmnc & ARMV7_FLAG_C; -	else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST)) -		ret = pmnc & ARMV7_FLAG_P(counter); -	else +	if (!armv7_pmnc_counter_valid(idx)) {  		pr_err("CPU%u checking wrong counter %d overflow status\n", -			smp_processor_id(), counter); +			smp_processor_id(), idx); +	} else { +		counter = ARMV7_IDX_TO_COUNTER(idx); +		ret = pmnc & BIT(counter); +	}  	return ret;  } -static inline int armv7_pmnc_select_counter(unsigned int idx) +static inline int armv7_pmnc_select_counter(int idx)  { -	u32 val; +	u32 counter; -	if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) { -		pr_err("CPU%u selecting wrong PMNC counter" -			" %d\n", smp_processor_id(), idx); -		return -1; +	if (!armv7_pmnc_counter_valid(idx)) { +		pr_err("CPU%u selecting wrong PMNC counter %d\n", +			smp_processor_id(), idx); +		return -EINVAL;  	} -	val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK; -	asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val)); +	counter = ARMV7_IDX_TO_COUNTER(idx); +	asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter));  	isb();  	return idx; @@ -812,124 +789,95 @@ static inline int armv7_pmnc_select_counter(unsigned int idx)  static inline u32 armv7pmu_read_counter(int idx)  { -	unsigned long value = 0; +	u32 value = 0; -	if (idx == ARMV7_CYCLE_COUNTER) -		asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value)); -	else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) { -		if (armv7_pmnc_select_counter(idx) == idx) -			asm volatile("mrc p15, 0, %0, c9, c13, 2" -				     : "=r" (value)); -	} else +	if (!armv7_pmnc_counter_valid(idx))  		pr_err("CPU%u reading wrong counter %d\n",  			smp_processor_id(), idx); +	else if (idx == ARMV7_IDX_CYCLE_COUNTER) +		asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value)); +	else if (armv7_pmnc_select_counter(idx) == idx) +		asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (value));  	return value;  }  static inline void armv7pmu_write_counter(int idx, u32 value)  { -	if (idx == ARMV7_CYCLE_COUNTER) -		asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value)); -	else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) { -		if (armv7_pmnc_select_counter(idx) == idx) -			asm volatile("mcr p15, 0, %0, c9, c13, 2" -				     : : "r" (value)); -	} else +	if (!armv7_pmnc_counter_valid(idx))  		pr_err("CPU%u writing wrong counter %d\n",  			smp_processor_id(), idx); +	else if (idx == ARMV7_IDX_CYCLE_COUNTER) +		asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value)); +	else if (armv7_pmnc_select_counter(idx) == idx) +		asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value));  } -static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val) +static inline void armv7_pmnc_write_evtsel(int idx, u32 val)  {  	if (armv7_pmnc_select_counter(idx) == idx) { -		val &= ARMV7_EVTSEL_MASK; +		val &= ARMV7_EVTYPE_MASK;  		asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));  	}  } -static inline u32 armv7_pmnc_enable_counter(unsigned int idx) +static inline int armv7_pmnc_enable_counter(int idx)  { -	u32 val; +	u32 counter; -	if ((idx != ARMV7_CYCLE_COUNTER) && -	    ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { -		pr_err("CPU%u enabling wrong PMNC counter" -			" %d\n", smp_processor_id(), idx); -		return -1; +	if (!armv7_pmnc_counter_valid(idx)) { +		pr_err("CPU%u enabling wrong PMNC counter %d\n", +			smp_processor_id(), idx); +		return -EINVAL;  	} -	if (idx == ARMV7_CYCLE_COUNTER) -		val = ARMV7_CNTENS_C; -	else -		val = ARMV7_CNTENS_P(idx); - -	asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val)); - +	counter = ARMV7_IDX_TO_COUNTER(idx); +	asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter)));  	return idx;  } -static inline u32 armv7_pmnc_disable_counter(unsigned int idx) +static inline int armv7_pmnc_disable_counter(int idx)  { -	u32 val; - +	u32 counter; -	if ((idx != ARMV7_CYCLE_COUNTER) && -	    ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { -		pr_err("CPU%u disabling wrong PMNC counter" -			" %d\n", smp_processor_id(), idx); -		return -1; +	if (!armv7_pmnc_counter_valid(idx)) { +		pr_err("CPU%u disabling wrong PMNC counter %d\n", +			smp_processor_id(), idx); +		return -EINVAL;  	} -	if (idx == ARMV7_CYCLE_COUNTER) -		val = ARMV7_CNTENC_C; -	else -		val = ARMV7_CNTENC_P(idx); - -	asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val)); - +	counter = ARMV7_IDX_TO_COUNTER(idx); +	asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter)));  	return idx;  } -static inline u32 armv7_pmnc_enable_intens(unsigned int idx) +static inline int armv7_pmnc_enable_intens(int idx)  { -	u32 val; +	u32 counter; -	if ((idx != ARMV7_CYCLE_COUNTER) && -	    ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { -		pr_err("CPU%u enabling wrong PMNC counter" -			" interrupt enable %d\n", smp_processor_id(), idx); -		return -1; +	if (!armv7_pmnc_counter_valid(idx)) { +		pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n", +			smp_processor_id(), idx); +		return -EINVAL;  	} -	if (idx == ARMV7_CYCLE_COUNTER) -		val = ARMV7_INTENS_C; -	else -		val = ARMV7_INTENS_P(idx); - -	asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val)); - +	counter = ARMV7_IDX_TO_COUNTER(idx); +	asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter)));  	return idx;  } -static inline u32 armv7_pmnc_disable_intens(unsigned int idx) +static inline int armv7_pmnc_disable_intens(int idx)  { -	u32 val; +	u32 counter; -	if ((idx != ARMV7_CYCLE_COUNTER) && -	    ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) { -		pr_err("CPU%u disabling wrong PMNC counter" -			" interrupt enable %d\n", smp_processor_id(), idx); -		return -1; +	if (!armv7_pmnc_counter_valid(idx)) { +		pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n", +			smp_processor_id(), idx); +		return -EINVAL;  	} -	if (idx == ARMV7_CYCLE_COUNTER) -		val = ARMV7_INTENC_C; -	else -		val = ARMV7_INTENC_P(idx); - -	asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val)); - +	counter = ARMV7_IDX_TO_COUNTER(idx); +	asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter)));  	return idx;  } @@ -973,14 +921,14 @@ static void armv7_pmnc_dump_regs(void)  	asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));  	printk(KERN_INFO "CCNT  =0x%08x\n", val); -	for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) { +	for (cnt = ARMV7_IDX_COUNTER0; cnt <= ARMV7_IDX_COUNTER_LAST; cnt++) {  		armv7_pmnc_select_counter(cnt);  		asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));  		printk(KERN_INFO "CNT[%d] count =0x%08x\n", -			cnt-ARMV7_EVENT_CNT_TO_CNTx, val); +			ARMV7_IDX_TO_COUNTER(cnt), val);  		asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));  		printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n", -			cnt-ARMV7_EVENT_CNT_TO_CNTx, val); +			ARMV7_IDX_TO_COUNTER(cnt), val);  	}  }  #endif @@ -988,12 +936,13 @@ static void armv7_pmnc_dump_regs(void)  static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)  {  	unsigned long flags; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events();  	/*  	 * Enable counter and interrupt, and set the counter to count  	 * the event that we're interested in.  	 */ -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	/*  	 * Disable counter @@ -1002,9 +951,10 @@ static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)  	/*  	 * Set event (if destined for PMNx counters) -	 * We don't need to set the event if it's a cycle count +	 * We only need to set the event for the cycle counter if we +	 * have the ability to perform event filtering.  	 */ -	if (idx != ARMV7_CYCLE_COUNTER) +	if (armv7pmu.set_event_filter || idx != ARMV7_IDX_CYCLE_COUNTER)  		armv7_pmnc_write_evtsel(idx, hwc->config_base);  	/* @@ -1017,17 +967,18 @@ static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)  	 */  	armv7_pmnc_enable_counter(idx); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)  {  	unsigned long flags; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events();  	/*  	 * Disable counter and interrupt  	 */ -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	/*  	 * Disable counter @@ -1039,14 +990,14 @@ static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)  	 */  	armv7_pmnc_disable_intens(idx); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)  { -	unsigned long pmnc; +	u32 pmnc;  	struct perf_sample_data data; -	struct cpu_hw_events *cpuc; +	struct pmu_hw_events *cpuc;  	struct pt_regs *regs;  	int idx; @@ -1069,13 +1020,10 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)  	perf_sample_data_init(&data, 0);  	cpuc = &__get_cpu_var(cpu_hw_events); -	for (idx = 0; idx <= armpmu->num_events; ++idx) { +	for (idx = 0; idx < cpu_pmu->num_events; ++idx) {  		struct perf_event *event = cpuc->events[idx];  		struct hw_perf_event *hwc; -		if (!test_bit(idx, cpuc->active_mask)) -			continue; -  		/*  		 * We have a single interrupt for all counters. Check that  		 * each counter has overflowed before we process it. @@ -1090,7 +1038,7 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)  			continue;  		if (perf_event_overflow(event, &data, regs)) -			armpmu->disable(hwc, idx); +			cpu_pmu->disable(hwc, idx);  	}  	/* @@ -1108,61 +1056,114 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)  static void armv7pmu_start(void)  {  	unsigned long flags; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events(); -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	/* Enable all counters */  	armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static void armv7pmu_stop(void)  {  	unsigned long flags; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events(); -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	/* Disable all counters */  	armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  } -static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc, +static int armv7pmu_get_event_idx(struct pmu_hw_events *cpuc,  				  struct hw_perf_event *event)  {  	int idx; +	unsigned long evtype = event->config_base & ARMV7_EVTYPE_EVENT;  	/* Always place a cycle counter into the cycle counter. */ -	if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) { -		if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask)) +	if (evtype == ARMV7_PERFCTR_CPU_CYCLES) { +		if (test_and_set_bit(ARMV7_IDX_CYCLE_COUNTER, cpuc->used_mask))  			return -EAGAIN; -		return ARMV7_CYCLE_COUNTER; -	} else { -		/* -		 * For anything other than a cycle counter, try and use -		 * the events counters -		 */ -		for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) { -			if (!test_and_set_bit(idx, cpuc->used_mask)) -				return idx; -		} +		return ARMV7_IDX_CYCLE_COUNTER; +	} -		/* The counters are all in use. */ -		return -EAGAIN; +	/* +	 * For anything other than a cycle counter, try and use +	 * the events counters +	 */ +	for (idx = ARMV7_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) { +		if (!test_and_set_bit(idx, cpuc->used_mask)) +			return idx;  	} + +	/* The counters are all in use. */ +	return -EAGAIN; +} + +/* + * Add an event filter to a given event. This will only work for PMUv2 PMUs. + */ +static int armv7pmu_set_event_filter(struct hw_perf_event *event, +				     struct perf_event_attr *attr) +{ +	unsigned long config_base = 0; + +	if (attr->exclude_idle) +		return -EPERM; +	if (attr->exclude_user) +		config_base |= ARMV7_EXCLUDE_USER; +	if (attr->exclude_kernel) +		config_base |= ARMV7_EXCLUDE_PL1; +	if (!attr->exclude_hv) +		config_base |= ARMV7_INCLUDE_HYP; + +	/* +	 * Install the filter into config_base as this is used to +	 * construct the event type. +	 */ +	event->config_base = config_base; + +	return 0;  }  static void armv7pmu_reset(void *info)  { -	u32 idx, nb_cnt = armpmu->num_events; +	u32 idx, nb_cnt = cpu_pmu->num_events;  	/* The counter and interrupt enable registers are unknown at reset. */ -	for (idx = 1; idx < nb_cnt; ++idx) +	for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx)  		armv7pmu_disable_event(NULL, idx);  	/* Initialize & Reset PMNC: C and P bits */  	armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);  } +static int armv7_a8_map_event(struct perf_event *event) +{ +	return map_cpu_event(event, &armv7_a8_perf_map, +				&armv7_a8_perf_cache_map, 0xFF); +} + +static int armv7_a9_map_event(struct perf_event *event) +{ +	return map_cpu_event(event, &armv7_a9_perf_map, +				&armv7_a9_perf_cache_map, 0xFF); +} + +static int armv7_a5_map_event(struct perf_event *event) +{ +	return map_cpu_event(event, &armv7_a5_perf_map, +				&armv7_a5_perf_cache_map, 0xFF); +} + +static int armv7_a15_map_event(struct perf_event *event) +{ +	return map_cpu_event(event, &armv7_a15_perf_map, +				&armv7_a15_perf_cache_map, 0xFF); +} +  static struct arm_pmu armv7pmu = {  	.handle_irq		= armv7pmu_handle_irq,  	.enable			= armv7pmu_enable_event, @@ -1173,7 +1174,6 @@ static struct arm_pmu armv7pmu = {  	.start			= armv7pmu_start,  	.stop			= armv7pmu_stop,  	.reset			= armv7pmu_reset, -	.raw_event_mask		= 0xFF,  	.max_period		= (1LLU << 32) - 1,  }; @@ -1188,62 +1188,59 @@ static u32 __init armv7_read_num_pmnc_events(void)  	return nb_cnt + 1;  } -static const struct arm_pmu *__init armv7_a8_pmu_init(void) +static struct arm_pmu *__init armv7_a8_pmu_init(void)  {  	armv7pmu.id		= ARM_PERF_PMU_ID_CA8;  	armv7pmu.name		= "ARMv7 Cortex-A8"; -	armv7pmu.cache_map	= &armv7_a8_perf_cache_map; -	armv7pmu.event_map	= &armv7_a8_perf_map; +	armv7pmu.map_event	= armv7_a8_map_event;  	armv7pmu.num_events	= armv7_read_num_pmnc_events();  	return &armv7pmu;  } -static const struct arm_pmu *__init armv7_a9_pmu_init(void) +static struct arm_pmu *__init armv7_a9_pmu_init(void)  {  	armv7pmu.id		= ARM_PERF_PMU_ID_CA9;  	armv7pmu.name		= "ARMv7 Cortex-A9"; -	armv7pmu.cache_map	= &armv7_a9_perf_cache_map; -	armv7pmu.event_map	= &armv7_a9_perf_map; +	armv7pmu.map_event	= armv7_a9_map_event;  	armv7pmu.num_events	= armv7_read_num_pmnc_events();  	return &armv7pmu;  } -static const struct arm_pmu *__init armv7_a5_pmu_init(void) +static struct arm_pmu *__init armv7_a5_pmu_init(void)  {  	armv7pmu.id		= ARM_PERF_PMU_ID_CA5;  	armv7pmu.name		= "ARMv7 Cortex-A5"; -	armv7pmu.cache_map	= &armv7_a5_perf_cache_map; -	armv7pmu.event_map	= &armv7_a5_perf_map; +	armv7pmu.map_event	= armv7_a5_map_event;  	armv7pmu.num_events	= armv7_read_num_pmnc_events();  	return &armv7pmu;  } -static const struct arm_pmu *__init armv7_a15_pmu_init(void) +static struct arm_pmu *__init armv7_a15_pmu_init(void)  {  	armv7pmu.id		= ARM_PERF_PMU_ID_CA15;  	armv7pmu.name		= "ARMv7 Cortex-A15"; -	armv7pmu.cache_map	= &armv7_a15_perf_cache_map; -	armv7pmu.event_map	= &armv7_a15_perf_map; +	armv7pmu.map_event	= armv7_a15_map_event;  	armv7pmu.num_events	= armv7_read_num_pmnc_events(); +	armv7pmu.set_event_filter = armv7pmu_set_event_filter;  	return &armv7pmu;  }  #else -static const struct arm_pmu *__init armv7_a8_pmu_init(void) +static struct arm_pmu *__init armv7_a8_pmu_init(void)  {  	return NULL;  } -static const struct arm_pmu *__init armv7_a9_pmu_init(void) +static struct arm_pmu *__init armv7_a9_pmu_init(void)  {  	return NULL;  } -static const struct arm_pmu *__init armv7_a5_pmu_init(void) +static struct arm_pmu *__init armv7_a5_pmu_init(void)  {  	return NULL;  } -static const struct arm_pmu *__init armv7_a15_pmu_init(void) +static struct arm_pmu *__init armv7_a15_pmu_init(void)  {  	return NULL;  } diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c index 3c4397491d0..e0cca10a841 100644 --- a/arch/arm/kernel/perf_event_xscale.c +++ b/arch/arm/kernel/perf_event_xscale.c @@ -40,7 +40,7 @@ enum xscale_perf_types {  };  enum xscale_counters { -	XSCALE_CYCLE_COUNTER	= 1, +	XSCALE_CYCLE_COUNTER	= 0,  	XSCALE_COUNTER0,  	XSCALE_COUNTER1,  	XSCALE_COUNTER2, @@ -222,7 +222,7 @@ xscale1pmu_handle_irq(int irq_num, void *dev)  {  	unsigned long pmnc;  	struct perf_sample_data data; -	struct cpu_hw_events *cpuc; +	struct pmu_hw_events *cpuc;  	struct pt_regs *regs;  	int idx; @@ -249,13 +249,10 @@ xscale1pmu_handle_irq(int irq_num, void *dev)  	perf_sample_data_init(&data, 0);  	cpuc = &__get_cpu_var(cpu_hw_events); -	for (idx = 0; idx <= armpmu->num_events; ++idx) { +	for (idx = 0; idx < cpu_pmu->num_events; ++idx) {  		struct perf_event *event = cpuc->events[idx];  		struct hw_perf_event *hwc; -		if (!test_bit(idx, cpuc->active_mask)) -			continue; -  		if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx))  			continue; @@ -266,7 +263,7 @@ xscale1pmu_handle_irq(int irq_num, void *dev)  			continue;  		if (perf_event_overflow(event, &data, regs)) -			armpmu->disable(hwc, idx); +			cpu_pmu->disable(hwc, idx);  	}  	irq_work_run(); @@ -284,6 +281,7 @@ static void  xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)  {  	unsigned long val, mask, evt, flags; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events();  	switch (idx) {  	case XSCALE_CYCLE_COUNTER: @@ -305,18 +303,19 @@ xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)  		return;  	} -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	val = xscale1pmu_read_pmnc();  	val &= ~mask;  	val |= evt;  	xscale1pmu_write_pmnc(val); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static void  xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)  {  	unsigned long val, mask, evt, flags; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events();  	switch (idx) {  	case XSCALE_CYCLE_COUNTER: @@ -336,16 +335,16 @@ xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)  		return;  	} -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	val = xscale1pmu_read_pmnc();  	val &= ~mask;  	val |= evt;  	xscale1pmu_write_pmnc(val); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static int -xscale1pmu_get_event_idx(struct cpu_hw_events *cpuc, +xscale1pmu_get_event_idx(struct pmu_hw_events *cpuc,  			struct hw_perf_event *event)  {  	if (XSCALE_PERFCTR_CCNT == event->config_base) { @@ -368,24 +367,26 @@ static void  xscale1pmu_start(void)  {  	unsigned long flags, val; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events(); -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	val = xscale1pmu_read_pmnc();  	val |= XSCALE_PMU_ENABLE;  	xscale1pmu_write_pmnc(val); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static void  xscale1pmu_stop(void)  {  	unsigned long flags, val; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events(); -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	val = xscale1pmu_read_pmnc();  	val &= ~XSCALE_PMU_ENABLE;  	xscale1pmu_write_pmnc(val); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static inline u32 @@ -424,7 +425,13 @@ xscale1pmu_write_counter(int counter, u32 val)  	}  } -static const struct arm_pmu xscale1pmu = { +static int xscale_map_event(struct perf_event *event) +{ +	return map_cpu_event(event, &xscale_perf_map, +				&xscale_perf_cache_map, 0xFF); +} + +static struct arm_pmu xscale1pmu = {  	.id		= ARM_PERF_PMU_ID_XSCALE1,  	.name		= "xscale1",  	.handle_irq	= xscale1pmu_handle_irq, @@ -435,14 +442,12 @@ static const struct arm_pmu xscale1pmu = {  	.get_event_idx	= xscale1pmu_get_event_idx,  	.start		= xscale1pmu_start,  	.stop		= xscale1pmu_stop, -	.cache_map	= &xscale_perf_cache_map, -	.event_map	= &xscale_perf_map, -	.raw_event_mask	= 0xFF, +	.map_event	= xscale_map_event,  	.num_events	= 3,  	.max_period	= (1LLU << 32) - 1,  }; -static const struct arm_pmu *__init xscale1pmu_init(void) +static struct arm_pmu *__init xscale1pmu_init(void)  {  	return &xscale1pmu;  } @@ -560,7 +565,7 @@ xscale2pmu_handle_irq(int irq_num, void *dev)  {  	unsigned long pmnc, of_flags;  	struct perf_sample_data data; -	struct cpu_hw_events *cpuc; +	struct pmu_hw_events *cpuc;  	struct pt_regs *regs;  	int idx; @@ -581,13 +586,10 @@ xscale2pmu_handle_irq(int irq_num, void *dev)  	perf_sample_data_init(&data, 0);  	cpuc = &__get_cpu_var(cpu_hw_events); -	for (idx = 0; idx <= armpmu->num_events; ++idx) { +	for (idx = 0; idx < cpu_pmu->num_events; ++idx) {  		struct perf_event *event = cpuc->events[idx];  		struct hw_perf_event *hwc; -		if (!test_bit(idx, cpuc->active_mask)) -			continue; -  		if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx))  			continue; @@ -598,7 +600,7 @@ xscale2pmu_handle_irq(int irq_num, void *dev)  			continue;  		if (perf_event_overflow(event, &data, regs)) -			armpmu->disable(hwc, idx); +			cpu_pmu->disable(hwc, idx);  	}  	irq_work_run(); @@ -616,6 +618,7 @@ static void  xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)  {  	unsigned long flags, ien, evtsel; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events();  	ien = xscale2pmu_read_int_enable();  	evtsel = xscale2pmu_read_event_select(); @@ -649,16 +652,17 @@ xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)  		return;  	} -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	xscale2pmu_write_event_select(evtsel);  	xscale2pmu_write_int_enable(ien); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static void  xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)  {  	unsigned long flags, ien, evtsel; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events();  	ien = xscale2pmu_read_int_enable();  	evtsel = xscale2pmu_read_event_select(); @@ -692,14 +696,14 @@ xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)  		return;  	} -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	xscale2pmu_write_event_select(evtsel);  	xscale2pmu_write_int_enable(ien); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static int -xscale2pmu_get_event_idx(struct cpu_hw_events *cpuc, +xscale2pmu_get_event_idx(struct pmu_hw_events *cpuc,  			struct hw_perf_event *event)  {  	int idx = xscale1pmu_get_event_idx(cpuc, event); @@ -718,24 +722,26 @@ static void  xscale2pmu_start(void)  {  	unsigned long flags, val; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events(); -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64;  	val |= XSCALE_PMU_ENABLE;  	xscale2pmu_write_pmnc(val); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static void  xscale2pmu_stop(void)  {  	unsigned long flags, val; +	struct pmu_hw_events *events = cpu_pmu->get_hw_events(); -	raw_spin_lock_irqsave(&pmu_lock, flags); +	raw_spin_lock_irqsave(&events->pmu_lock, flags);  	val = xscale2pmu_read_pmnc();  	val &= ~XSCALE_PMU_ENABLE;  	xscale2pmu_write_pmnc(val); -	raw_spin_unlock_irqrestore(&pmu_lock, flags); +	raw_spin_unlock_irqrestore(&events->pmu_lock, flags);  }  static inline u32 @@ -786,7 +792,7 @@ xscale2pmu_write_counter(int counter, u32 val)  	}  } -static const struct arm_pmu xscale2pmu = { +static struct arm_pmu xscale2pmu = {  	.id		= ARM_PERF_PMU_ID_XSCALE2,  	.name		= "xscale2",  	.handle_irq	= xscale2pmu_handle_irq, @@ -797,24 +803,22 @@ static const struct arm_pmu xscale2pmu = {  	.get_event_idx	= xscale2pmu_get_event_idx,  	.start		= xscale2pmu_start,  	.stop		= xscale2pmu_stop, -	.cache_map	= &xscale_perf_cache_map, -	.event_map	= &xscale_perf_map, -	.raw_event_mask	= 0xFF, +	.map_event	= xscale_map_event,  	.num_events	= 5,  	.max_period	= (1LLU << 32) - 1,  }; -static const struct arm_pmu *__init xscale2pmu_init(void) +static struct arm_pmu *__init xscale2pmu_init(void)  {  	return &xscale2pmu;  }  #else -static const struct arm_pmu *__init xscale1pmu_init(void) +static struct arm_pmu *__init xscale1pmu_init(void)  {  	return NULL;  } -static const struct arm_pmu *__init xscale2pmu_init(void) +static struct arm_pmu *__init xscale2pmu_init(void)  {  	return NULL;  } diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c index c53474fe84d..2c3407ee857 100644 --- a/arch/arm/kernel/pmu.c +++ b/arch/arm/kernel/pmu.c @@ -10,192 +10,26 @@   *   */ -#define pr_fmt(fmt) "PMU: " fmt - -#include <linux/cpumask.h>  #include <linux/err.h> -#include <linux/interrupt.h>  #include <linux/kernel.h>  #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/platform_device.h>  #include <asm/pmu.h> -static volatile long pmu_lock; - -static struct platform_device *pmu_devices[ARM_NUM_PMU_DEVICES]; - -static int __devinit pmu_register(struct platform_device *pdev, -					enum arm_pmu_type type) -{ -	if (type < 0 || type >= ARM_NUM_PMU_DEVICES) { -		pr_warning("received registration request for unknown " -				"PMU device type %d\n", type); -		return -EINVAL; -	} - -	if (pmu_devices[type]) { -		pr_warning("rejecting duplicate registration of PMU device " -			"type %d.", type); -		return -ENOSPC; -	} - -	pr_info("registered new PMU device of type %d\n", type); -	pmu_devices[type] = pdev; -	return 0; -} - -#define OF_MATCH_PMU(_name, _type) {	\ -	.compatible = _name,		\ -	.data = (void *)_type,		\ -} - -#define OF_MATCH_CPU(name)	OF_MATCH_PMU(name, ARM_PMU_DEVICE_CPU) - -static struct of_device_id armpmu_of_device_ids[] = { -	OF_MATCH_CPU("arm,cortex-a9-pmu"), -	OF_MATCH_CPU("arm,cortex-a8-pmu"), -	OF_MATCH_CPU("arm,arm1136-pmu"), -	OF_MATCH_CPU("arm,arm1176-pmu"), -	{}, -}; - -#define PLAT_MATCH_PMU(_name, _type) {	\ -	.name		= _name,	\ -	.driver_data	= _type,	\ -} - -#define PLAT_MATCH_CPU(_name)	PLAT_MATCH_PMU(_name, ARM_PMU_DEVICE_CPU) - -static struct platform_device_id armpmu_plat_device_ids[] = { -	PLAT_MATCH_CPU("arm-pmu"), -	{}, -}; - -enum arm_pmu_type armpmu_device_type(struct platform_device *pdev) -{ -	const struct of_device_id	*of_id; -	const struct platform_device_id *pdev_id; - -	/* provided by of_device_id table */ -	if (pdev->dev.of_node) { -		of_id = of_match_device(armpmu_of_device_ids, &pdev->dev); -		BUG_ON(!of_id); -		return (enum arm_pmu_type)of_id->data; -	} - -	/* Provided by platform_device_id table */ -	pdev_id = platform_get_device_id(pdev); -	BUG_ON(!pdev_id); -	return pdev_id->driver_data; -} - -static int __devinit armpmu_device_probe(struct platform_device *pdev) -{ -	return pmu_register(pdev, armpmu_device_type(pdev)); -} - -static struct platform_driver armpmu_driver = { -	.driver		= { -		.name	= "arm-pmu", -		.of_match_table = armpmu_of_device_ids, -	}, -	.probe		= armpmu_device_probe, -	.id_table	= armpmu_plat_device_ids, -}; - -static int __init register_pmu_driver(void) -{ -	return platform_driver_register(&armpmu_driver); -} -device_initcall(register_pmu_driver); +/* + * PMU locking to ensure mutual exclusion between different subsystems. + */ +static unsigned long pmu_lock[BITS_TO_LONGS(ARM_NUM_PMU_DEVICES)]; -struct platform_device * +int  reserve_pmu(enum arm_pmu_type type)  { -	struct platform_device *pdev; - -	if (test_and_set_bit_lock(type, &pmu_lock)) { -		pdev = ERR_PTR(-EBUSY); -	} else if (pmu_devices[type] == NULL) { -		clear_bit_unlock(type, &pmu_lock); -		pdev = ERR_PTR(-ENODEV); -	} else { -		pdev = pmu_devices[type]; -	} - -	return pdev; +	return test_and_set_bit_lock(type, pmu_lock) ? -EBUSY : 0;  }  EXPORT_SYMBOL_GPL(reserve_pmu); -int +void  release_pmu(enum arm_pmu_type type)  { -	if (WARN_ON(!pmu_devices[type])) -		return -EINVAL; -	clear_bit_unlock(type, &pmu_lock); -	return 0; -} -EXPORT_SYMBOL_GPL(release_pmu); - -static int -set_irq_affinity(int irq, -		 unsigned int cpu) -{ -#ifdef CONFIG_SMP -	int err = irq_set_affinity(irq, cpumask_of(cpu)); -	if (err) -		pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n", -			   irq, cpu); -	return err; -#else -	return -EINVAL; -#endif -} - -static int -init_cpu_pmu(void) -{ -	int i, irqs, err = 0; -	struct platform_device *pdev = pmu_devices[ARM_PMU_DEVICE_CPU]; - -	if (!pdev) -		return -ENODEV; - -	irqs = pdev->num_resources; - -	/* -	 * If we have a single PMU interrupt that we can't shift, assume that -	 * we're running on a uniprocessor machine and continue. -	 */ -	if (irqs == 1 && !irq_can_set_affinity(platform_get_irq(pdev, 0))) -		return 0; - -	for (i = 0; i < irqs; ++i) { -		err = set_irq_affinity(platform_get_irq(pdev, i), i); -		if (err) -			break; -	} - -	return err; -} - -int -init_pmu(enum arm_pmu_type type) -{ -	int err = 0; - -	switch (type) { -	case ARM_PMU_DEVICE_CPU: -		err = init_cpu_pmu(); -		break; -	default: -		pr_warning("attempt to initialise PMU of unknown " -			   "type %d\n", type); -		err = -EINVAL; -	} - -	return err; +	clear_bit_unlock(type, pmu_lock);  } -EXPORT_SYMBOL_GPL(init_pmu); diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index e514c76043b..6136144f8f8 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -820,25 +820,8 @@ static struct machine_desc * __init setup_machine_tags(unsigned int nr)  	if (__atags_pointer)  		tags = phys_to_virt(__atags_pointer); -	else if (mdesc->boot_params) { -#ifdef CONFIG_MMU -		/* -		 * We still are executing with a minimal MMU mapping created -		 * with the presumption that the machine default for this -		 * is located in the first MB of RAM.  Anything else will -		 * fault and silently hang the kernel at this point. -		 */ -		if (mdesc->boot_params < PHYS_OFFSET || -		    mdesc->boot_params >= PHYS_OFFSET + SZ_1M) { -			printk(KERN_WARNING -			       "Default boot params at physical 0x%08lx out of reach\n", -			       mdesc->boot_params); -		} else -#endif -		{ -			tags = phys_to_virt(mdesc->boot_params); -		} -	} +	else if (mdesc->atag_offset) +		tags = (void *)(PAGE_OFFSET + mdesc->atag_offset);  #if defined(CONFIG_DEPRECATED_PARAM_STRUCT)  	/* diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index dc902f2c684..020e99c845e 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -8,92 +8,61 @@  	.text  /* - * Save CPU state for a suspend - *  r1 = v:p offset - *  r2 = suspend function arg0 - *  r3 = suspend function + * Save CPU state for a suspend.  This saves the CPU general purpose + * registers, and allocates space on the kernel stack to save the CPU + * specific registers and some other data for resume. + *  r0 = suspend function arg0 + *  r1 = suspend function   */  ENTRY(__cpu_suspend)  	stmfd	sp!, {r4 - r11, lr}  #ifdef MULTI_CPU  	ldr	r10, =processor -	ldr	r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state -	ldr	ip, [r10, #CPU_DO_RESUME] @ virtual resume function +	ldr	r4, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state  #else -	ldr	r5, =cpu_suspend_size -	ldr	ip, =cpu_do_resume +	ldr	r4, =cpu_suspend_size  #endif -	mov	r6, sp			@ current virtual SP -	sub	sp, sp, r5		@ allocate CPU state on stack -	mov	r0, sp			@ save pointer to CPU save block -	add	ip, ip, r1		@ convert resume fn to phys -	stmfd	sp!, {r1, r6, ip}	@ save v:p, virt SP, phys resume fn -	ldr	r5, =sleep_save_sp -	add	r6, sp, r1		@ convert SP to phys -	stmfd	sp!, {r2, r3}		@ save suspend func arg and pointer +	mov	r5, sp			@ current virtual SP +	add	r4, r4, #12		@ Space for pgd, virt sp, phys resume fn +	sub	sp, sp, r4		@ allocate CPU state on stack +	stmfd	sp!, {r0, r1}		@ save suspend func arg and pointer +	add	r0, sp, #8		@ save pointer to save block +	mov	r1, r4			@ size of save block +	mov	r2, r5			@ virtual SP +	ldr	r3, =sleep_save_sp  #ifdef CONFIG_SMP  	ALT_SMP(mrc p15, 0, lr, c0, c0, 5)  	ALT_UP(mov lr, #0)  	and	lr, lr, #15 -	str	r6, [r5, lr, lsl #2]	@ save phys SP -#else -	str	r6, [r5]		@ save phys SP -#endif -#ifdef MULTI_CPU -	mov	lr, pc -	ldr	pc, [r10, #CPU_DO_SUSPEND] @ save CPU state -#else -	bl	cpu_do_suspend -#endif - -	@ flush data cache -#ifdef MULTI_CACHE -	ldr	r10, =cpu_cache -	mov	lr, pc -	ldr	pc, [r10, #CACHE_FLUSH_KERN_ALL] -#else -	bl	__cpuc_flush_kern_all +	add	r3, r3, lr, lsl #2  #endif +	bl	__cpu_suspend_save  	adr	lr, BSYM(cpu_suspend_abort)  	ldmfd	sp!, {r0, pc}		@ call suspend fn  ENDPROC(__cpu_suspend)  	.ltorg  cpu_suspend_abort: -	ldmia	sp!, {r1 - r3}		@ pop v:p, virt SP, phys resume fn +	ldmia	sp!, {r1 - r3}		@ pop phys pgd, virt SP, phys resume fn +	teq	r0, #0 +	moveq	r0, #1			@ force non-zero value  	mov	sp, r2  	ldmfd	sp!, {r4 - r11, pc}  ENDPROC(cpu_suspend_abort)  /*   * r0 = control register value - * r1 = v:p offset (preserved by cpu_do_resume) - * r2 = phys page table base - * r3 = L1 section flags   */ +	.align	5  ENTRY(cpu_resume_mmu) -	adr	r4, cpu_resume_turn_mmu_on -	mov	r4, r4, lsr #20 -	orr	r3, r3, r4, lsl #20 -	ldr	r5, [r2, r4, lsl #2]	@ save old mapping -	str	r3, [r2, r4, lsl #2]	@ setup 1:1 mapping for mmu code -	sub	r2, r2, r1  	ldr	r3, =cpu_resume_after_mmu -	bic	r1, r0, #CR_C		@ ensure D-cache is disabled -	b	cpu_resume_turn_mmu_on -ENDPROC(cpu_resume_mmu) -	.ltorg -	.align	5 -cpu_resume_turn_mmu_on: -	mcr	p15, 0, r1, c1, c0, 0	@ turn on MMU, I-cache, etc -	mrc	p15, 0, r1, c0, c0, 0	@ read id reg -	mov	r1, r1 -	mov	r1, r1 +	mcr	p15, 0, r0, c1, c0, 0	@ turn on MMU, I-cache, etc +	mrc	p15, 0, r0, c0, c0, 0	@ read id reg +	mov	r0, r0 +	mov	r0, r0  	mov	pc, r3			@ jump to virtual address -ENDPROC(cpu_resume_turn_mmu_on) +ENDPROC(cpu_resume_mmu)  cpu_resume_after_mmu: -	str	r5, [r2, r4, lsl #2]	@ restore old mapping -	mcr	p15, 0, r0, c1, c0, 0	@ turn on D-cache  	bl	cpu_init		@ restore the und/abt/irq banked regs  	mov	r0, #0			@ return zero on success  	ldmfd	sp!, {r4 - r11, pc} @@ -119,7 +88,7 @@ ENTRY(cpu_resume)  	ldr	r0, sleep_save_sp	@ stack phys addr  #endif  	setmode	PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1  @ set SVC, irqs off -	@ load v:p, stack, resume fn +	@ load phys pgd, stack, resume fn    ARM(	ldmia	r0!, {r1, sp, pc}	)  THUMB(	ldmia	r0!, {r1, r2, r3}	)  THUMB(	mov	sp, r2			) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index d88ff0230e8..a96c08cd612 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -16,7 +16,6 @@  #include <linux/cache.h>  #include <linux/profile.h>  #include <linux/errno.h> -#include <linux/ftrace.h>  #include <linux/mm.h>  #include <linux/err.h>  #include <linux/cpu.h> @@ -31,6 +30,8 @@  #include <asm/cacheflush.h>  #include <asm/cpu.h>  #include <asm/cputype.h> +#include <asm/exception.h> +#include <asm/topology.h>  #include <asm/mmu_context.h>  #include <asm/pgtable.h>  #include <asm/pgalloc.h> @@ -39,6 +40,7 @@  #include <asm/tlbflush.h>  #include <asm/ptrace.h>  #include <asm/localtimer.h> +#include <asm/smp_plat.h>  /*   * as from 2.5, kernels no longer have an init_tasks structure @@ -259,6 +261,20 @@ void __ref cpu_die(void)  }  #endif /* CONFIG_HOTPLUG_CPU */ +int __cpu_logical_map[NR_CPUS]; + +void __init smp_setup_processor_id(void) +{ +	int i; +	u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0; + +	cpu_logical_map(0) = cpu; +	for (i = 1; i < NR_CPUS; ++i) +		cpu_logical_map(i) = i == cpu ? 0 : i; + +	printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu); +} +  /*   * Called by both boot and secondaries to move global data into   * per-processor storage. @@ -268,6 +284,8 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid)  	struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);  	cpu_info->loops_per_jiffy = loops_per_jiffy; + +	store_cpu_topology(cpuid);  }  /* @@ -358,6 +376,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)  {  	unsigned int ncores = num_possible_cpus(); +	init_cpu_topology(); +  	smp_store_cpu_info(smp_processor_id());  	/* @@ -437,10 +457,6 @@ u64 smp_irq_stat_cpu(unsigned int cpu)  	for (i = 0; i < NR_IPI; i++)  		sum += __get_irq_stat(cpu, ipi_irqs[i]); -#ifdef CONFIG_LOCAL_TIMERS -	sum += __get_irq_stat(cpu, local_timer_irqs); -#endif -  	return sum;  } @@ -457,33 +473,6 @@ static void ipi_timer(void)  	irq_exit();  } -#ifdef CONFIG_LOCAL_TIMERS -asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) -{ -	struct pt_regs *old_regs = set_irq_regs(regs); -	int cpu = smp_processor_id(); - -	if (local_timer_ack()) { -		__inc_irq_stat(cpu, local_timer_irqs); -		ipi_timer(); -	} - -	set_irq_regs(old_regs); -} - -void show_local_irqs(struct seq_file *p, int prec) -{ -	unsigned int cpu; - -	seq_printf(p, "%*s: ", prec, "LOC"); - -	for_each_present_cpu(cpu) -		seq_printf(p, "%10u ", __get_irq_stat(cpu, local_timer_irqs)); - -	seq_printf(p, " Local timer interrupts\n"); -} -#endif -  #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST  static void smp_timer_broadcast(const struct cpumask *mask)  { @@ -534,7 +523,7 @@ static void percpu_timer_stop(void)  	unsigned int cpu = smp_processor_id();  	struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); -	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); +	local_timer_stop(evt);  }  #endif @@ -567,6 +556,11 @@ static void ipi_cpu_stop(unsigned int cpu)   */  asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)  { +	handle_IPI(ipinr, regs); +} + +void handle_IPI(int ipinr, struct pt_regs *regs) +{  	unsigned int cpu = smp_processor_id();  	struct pt_regs *old_regs = set_irq_regs(regs); diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c index 7fcddb75c87..8f5dd796335 100644 --- a/arch/arm/kernel/smp_scu.c +++ b/arch/arm/kernel/smp_scu.c @@ -34,7 +34,7 @@ unsigned int __init scu_get_core_count(void __iomem *scu_base)  /*   * Enable the SCU   */ -void __init scu_enable(void __iomem *scu_base) +void scu_enable(void __iomem *scu_base)  {  	u32 scu_ctrl; diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 01c186222f3..a8a6682d6b5 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -19,6 +19,7 @@  #include <linux/io.h>  #include <asm/smp_twd.h> +#include <asm/localtimer.h>  #include <asm/hardware/gic.h>  /* set up by the platform code */ @@ -26,6 +27,8 @@ void __iomem *twd_base;  static unsigned long twd_timer_rate; +static struct clock_event_device __percpu **twd_evt; +  static void twd_set_mode(enum clock_event_mode mode,  			struct clock_event_device *clk)  { @@ -80,6 +83,12 @@ int twd_timer_ack(void)  	return 0;  } +void twd_timer_stop(struct clock_event_device *clk) +{ +	twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk); +	disable_percpu_irq(clk->irq); +} +  static void __cpuinit twd_calibrate_rate(void)  {  	unsigned long count; @@ -119,11 +128,43 @@ static void __cpuinit twd_calibrate_rate(void)  	}  } +static irqreturn_t twd_handler(int irq, void *dev_id) +{ +	struct clock_event_device *evt = *(struct clock_event_device **)dev_id; + +	if (twd_timer_ack()) { +		evt->event_handler(evt); +		return IRQ_HANDLED; +	} + +	return IRQ_NONE; +} +  /*   * Setup the local clock events for a CPU.   */  void __cpuinit twd_timer_setup(struct clock_event_device *clk)  { +	struct clock_event_device **this_cpu_clk; + +	if (!twd_evt) { +		int err; + +		twd_evt = alloc_percpu(struct clock_event_device *); +		if (!twd_evt) { +			pr_err("twd: can't allocate memory\n"); +			return; +		} + +		err = request_percpu_irq(clk->irq, twd_handler, +					 "twd", twd_evt); +		if (err) { +			pr_err("twd: can't register interrupt %d (%d)\n", +			       clk->irq, err); +			return; +		} +	} +  	twd_calibrate_rate();  	clk->name = "local_timer"; @@ -137,8 +178,10 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)  	clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);  	clk->min_delta_ns = clockevent_delta2ns(0xf, clk); +	this_cpu_clk = __this_cpu_ptr(twd_evt); +	*this_cpu_clk = clk; +  	clockevents_register_device(clk); -	/* Make sure our local interrupt controller has this enabled */ -	gic_enable_ppi(clk->irq); +	enable_percpu_irq(clk->irq, 0);  } diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c new file mode 100644 index 00000000000..93a22d282c1 --- /dev/null +++ b/arch/arm/kernel/suspend.c @@ -0,0 +1,72 @@ +#include <linux/init.h> + +#include <asm/pgalloc.h> +#include <asm/pgtable.h> +#include <asm/memory.h> +#include <asm/suspend.h> +#include <asm/tlbflush.h> + +static pgd_t *suspend_pgd; + +extern int __cpu_suspend(unsigned long, int (*)(unsigned long)); +extern void cpu_resume_mmu(void); + +/* + * This is called by __cpu_suspend() to save the state, and do whatever + * flushing is required to ensure that when the CPU goes to sleep we have + * the necessary data available when the caches are not searched. + */ +void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr) +{ +	*save_ptr = virt_to_phys(ptr); + +	/* This must correspond to the LDM in cpu_resume() assembly */ +	*ptr++ = virt_to_phys(suspend_pgd); +	*ptr++ = sp; +	*ptr++ = virt_to_phys(cpu_do_resume); + +	cpu_do_suspend(ptr); + +	flush_cache_all(); +	outer_clean_range(*save_ptr, *save_ptr + ptrsz); +	outer_clean_range(virt_to_phys(save_ptr), +			  virt_to_phys(save_ptr) + sizeof(*save_ptr)); +} + +/* + * Hide the first two arguments to __cpu_suspend - these are an implementation + * detail which platform code shouldn't have to know about. + */ +int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) +{ +	struct mm_struct *mm = current->active_mm; +	int ret; + +	if (!suspend_pgd) +		return -EINVAL; + +	/* +	 * Provide a temporary page table with an identity mapping for +	 * the MMU-enable code, required for resuming.  On successful +	 * resume (indicated by a zero return code), we need to switch +	 * back to the correct page tables. +	 */ +	ret = __cpu_suspend(arg, fn); +	if (ret == 0) { +		cpu_switch_mm(mm->pgd, mm); +		local_flush_tlb_all(); +	} + +	return ret; +} + +static int __init cpu_suspend_init(void) +{ +	suspend_pgd = pgd_alloc(&init_mm); +	if (suspend_pgd) { +		unsigned long addr = virt_to_phys(cpu_resume_mmu); +		identity_mapping_add(suspend_pgd, addr, addr + SECTION_SIZE); +	} +	return suspend_pgd ? 0 : -ENOMEM; +} +core_initcall(cpu_suspend_init); diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c new file mode 100644 index 00000000000..1040c00405d --- /dev/null +++ b/arch/arm/kernel/topology.c @@ -0,0 +1,148 @@ +/* + * arch/arm/kernel/topology.c + * + * Copyright (C) 2011 Linaro Limited. + * Written by: Vincent Guittot + * + * based on arch/sh/kernel/topology.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License.  See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include <linux/cpu.h> +#include <linux/cpumask.h> +#include <linux/init.h> +#include <linux/percpu.h> +#include <linux/node.h> +#include <linux/nodemask.h> +#include <linux/sched.h> + +#include <asm/cputype.h> +#include <asm/topology.h> + +#define MPIDR_SMP_BITMASK (0x3 << 30) +#define MPIDR_SMP_VALUE (0x2 << 30) + +#define MPIDR_MT_BITMASK (0x1 << 24) + +/* + * These masks reflect the current use of the affinity levels. + * The affinity level can be up to 16 bits according to ARM ARM + */ + +#define MPIDR_LEVEL0_MASK 0x3 +#define MPIDR_LEVEL0_SHIFT 0 + +#define MPIDR_LEVEL1_MASK 0xF +#define MPIDR_LEVEL1_SHIFT 8 + +#define MPIDR_LEVEL2_MASK 0xFF +#define MPIDR_LEVEL2_SHIFT 16 + +struct cputopo_arm cpu_topology[NR_CPUS]; + +const struct cpumask *cpu_coregroup_mask(unsigned int cpu) +{ +	return &cpu_topology[cpu].core_sibling; +} + +/* + * store_cpu_topology is called at boot when only one cpu is running + * and with the mutex cpu_hotplug.lock locked, when several cpus have booted, + * which prevents simultaneous write access to cpu_topology array + */ +void store_cpu_topology(unsigned int cpuid) +{ +	struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid]; +	unsigned int mpidr; +	unsigned int cpu; + +	/* If the cpu topology has been already set, just return */ +	if (cpuid_topo->core_id != -1) +		return; + +	mpidr = read_cpuid_mpidr(); + +	/* create cpu topology mapping */ +	if ((mpidr & MPIDR_SMP_BITMASK) == MPIDR_SMP_VALUE) { +		/* +		 * This is a multiprocessor system +		 * multiprocessor format & multiprocessor mode field are set +		 */ + +		if (mpidr & MPIDR_MT_BITMASK) { +			/* core performance interdependency */ +			cpuid_topo->thread_id = (mpidr >> MPIDR_LEVEL0_SHIFT) +				& MPIDR_LEVEL0_MASK; +			cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL1_SHIFT) +				& MPIDR_LEVEL1_MASK; +			cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL2_SHIFT) +				& MPIDR_LEVEL2_MASK; +		} else { +			/* largely independent cores */ +			cpuid_topo->thread_id = -1; +			cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL0_SHIFT) +				& MPIDR_LEVEL0_MASK; +			cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL1_SHIFT) +				& MPIDR_LEVEL1_MASK; +		} +	} else { +		/* +		 * This is an uniprocessor system +		 * we are in multiprocessor format but uniprocessor system +		 * or in the old uniprocessor format +		 */ +		cpuid_topo->thread_id = -1; +		cpuid_topo->core_id = 0; +		cpuid_topo->socket_id = -1; +	} + +	/* update core and thread sibling masks */ +	for_each_possible_cpu(cpu) { +		struct cputopo_arm *cpu_topo = &cpu_topology[cpu]; + +		if (cpuid_topo->socket_id == cpu_topo->socket_id) { +			cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); +			if (cpu != cpuid) +				cpumask_set_cpu(cpu, +					&cpuid_topo->core_sibling); + +			if (cpuid_topo->core_id == cpu_topo->core_id) { +				cpumask_set_cpu(cpuid, +					&cpu_topo->thread_sibling); +				if (cpu != cpuid) +					cpumask_set_cpu(cpu, +						&cpuid_topo->thread_sibling); +			} +		} +	} +	smp_wmb(); + +	printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", +		cpuid, cpu_topology[cpuid].thread_id, +		cpu_topology[cpuid].core_id, +		cpu_topology[cpuid].socket_id, mpidr); +} + +/* + * init_cpu_topology is called at boot when only one cpu is running + * which prevent simultaneous write access to cpu_topology array + */ +void init_cpu_topology(void) +{ +	unsigned int cpu; + +	/* init core mask */ +	for_each_possible_cpu(cpu) { +		struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]); + +		cpu_topo->thread_id = -1; +		cpu_topo->core_id =  -1; +		cpu_topo->socket_id = -1; +		cpumask_clear(&cpu_topo->core_sibling); +		cpumask_clear(&cpu_topo->thread_sibling); +	} +	smp_wmb(); +} diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index bc9f9da782c..210382555af 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -27,6 +27,7 @@  #include <linux/atomic.h>  #include <asm/cacheflush.h> +#include <asm/exception.h>  #include <asm/system.h>  #include <asm/unistd.h>  #include <asm/traps.h> diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index e04c5fb6f1e..1532b508c81 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -12,6 +12,7 @@  #include <linux/module.h>  #include <linux/pm.h> +#include <linux/dma-mapping.h>  #include <asm/irq.h>  #include <asm/mach/arch.h> @@ -319,6 +320,7 @@ static void at91sam9g45_poweroff(void)  static void __init at91sam9g45_map_io(void)  {  	at91_init_sram(0, AT91SAM9G45_SRAM_BASE, AT91SAM9G45_SRAM_SIZE); +	init_consistent_dma_size(SZ_4M);  }  static void __init at91sam9g45_initialize(void) diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h index 2c611b9a013..406bb649680 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -128,8 +128,6 @@  #define AT91SAM9G45_EHCI_BASE	0x00800000	/* USB Host controller (EHCI) */  #define AT91SAM9G45_VDEC_BASE	0x00900000	/* Video Decoder Controller */ -#define CONSISTENT_DMA_SIZE	SZ_4M -  /*   * DMA peripheral identifiers   * for hardware handshaking interface diff --git a/arch/arm/mach-at91/include/mach/debug-macro.S b/arch/arm/mach-at91/include/mach/debug-macro.S index bc1e0b2e2f4..0ed8648c645 100644 --- a/arch/arm/mach-at91/include/mach/debug-macro.S +++ b/arch/arm/mach-at91/include/mach/debug-macro.S @@ -14,7 +14,7 @@  #include <mach/hardware.h>  #include <mach/at91_dbgu.h> -	.macro	addruart, rp, rv +	.macro	addruart, rp, rv, tmp  	ldr	\rp, =(AT91_BASE_SYS + AT91_DBGU)	@ System peripherals (phys address)  	ldr	\rv, =(AT91_VA_BASE_SYS	+ AT91_DBGU)	@ System peripherals (virt address)  	.endm diff --git a/arch/arm/mach-bcmring/include/mach/hardware.h b/arch/arm/mach-bcmring/include/mach/hardware.h index ed78aabb8e9..6ae20a649a9 100644 --- a/arch/arm/mach-bcmring/include/mach/hardware.h +++ b/arch/arm/mach-bcmring/include/mach/hardware.h @@ -22,7 +22,6 @@  #define __ASM_ARCH_HARDWARE_H  #include <asm/sizes.h> -#include <mach/memory.h>  #include <cfg_global.h>  #include <mach/csp/mm_io.h> @@ -31,7 +30,7 @@   *  *_SIZE  is the size of the region   *  *_BASE  is the virtual address   */ -#define RAM_START               PLAT_PHYS_OFFSET +#define RAM_START               PHYS_OFFSET  #define RAM_SIZE                (CFG_GLOBAL_RAM_SIZE-CFG_GLOBAL_RAM_SIZE_RESERVED)  #define RAM_BASE                PAGE_OFFSET diff --git a/arch/arm/mach-bcmring/include/mach/memory.h b/arch/arm/mach-bcmring/include/mach/memory.h deleted file mode 100644 index 15162e4c75f..00000000000 --- a/arch/arm/mach-bcmring/include/mach/memory.h +++ /dev/null @@ -1,33 +0,0 @@ -/***************************************************************************** -* Copyright 2005 - 2008 Broadcom Corporation.  All rights reserved. -* -* Unless you and Broadcom execute a separate written software license -* agreement governing use of this software, this software is licensed to you -* under the terms of the GNU General Public License version 2, available at -* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). -* -* Notwithstanding the above, under no circumstances may you combine this -* software in any way with any other Broadcom software provided under a -* license other than the GPL, without Broadcom's express prior written -* consent. -*****************************************************************************/ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#include <cfg_global.h> - -/* - * Physical vs virtual RAM address space conversion.  These are - * private definitions which should NOT be used outside memory.h - * files.  Use virt_to_phys/phys_to_virt/__pa/__va instead. - */ - -#define PLAT_PHYS_OFFSET CFG_GLOBAL_RAM_BASE - -/* - * Maximum DMA memory allowed is 14M - */ -#define CONSISTENT_DMA_SIZE (SZ_16M - SZ_2M) - -#endif diff --git a/arch/arm/mach-bcmring/mm.c b/arch/arm/mach-bcmring/mm.c index 0f1c37e4523..8616876abb9 100644 --- a/arch/arm/mach-bcmring/mm.c +++ b/arch/arm/mach-bcmring/mm.c @@ -13,6 +13,7 @@  *****************************************************************************/  #include <linux/platform_device.h> +#include <linux/dma-mapping.h>  #include <asm/mach/map.h>  #include <mach/hardware.h> @@ -53,4 +54,6 @@ void __init bcmring_map_io(void)  {  	iotable_init(bcmring_io_desc, ARRAY_SIZE(bcmring_io_desc)); +	/* Maximum DMA memory allowed is 14M */ +	init_consistent_dma_size(14 << 20);  } diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c index 4a74b2c959b..0276091b7f8 100644 --- a/arch/arm/mach-clps711x/autcpu12.c +++ b/arch/arm/mach-clps711x/autcpu12.c @@ -64,7 +64,7 @@ void __init autcpu12_map_io(void)  MACHINE_START(AUTCPU12, "autronix autcpu12")  	/* Maintainer: Thomas Gleixner */ -	.boot_params	= 0xc0020000, +	.atag_offset	= 0x20000,  	.map_io		= autcpu12_map_io,  	.init_irq	= clps711x_init_irq,  	.timer		= &clps711x_timer, diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c index 5a1689d4879..25b3bfd0e85 100644 --- a/arch/arm/mach-clps711x/cdb89712.c +++ b/arch/arm/mach-clps711x/cdb89712.c @@ -55,7 +55,7 @@ static void __init cdb89712_map_io(void)  MACHINE_START(CDB89712, "Cirrus-CDB89712")  	/* Maintainer: Ray Lehtiniemi */ -	.boot_params	= 0xc0000100, +	.atag_offset	= 0x100,  	.map_io		= cdb89712_map_io,  	.init_irq	= clps711x_init_irq,  	.timer		= &clps711x_timer, diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c index 16481cf3e93..1df9ec67aa9 100644 --- a/arch/arm/mach-clps711x/ceiva.c +++ b/arch/arm/mach-clps711x/ceiva.c @@ -56,7 +56,7 @@ static void __init ceiva_map_io(void)  MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame")  	/* Maintainer: Rob Scott */ -	.boot_params	= 0xc0000100, +	.atag_offset	= 0x100,  	.map_io		= ceiva_map_io,  	.init_irq	= clps711x_init_irq,  	.timer		= &clps711x_timer, diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c index 67b5abb4a60..06c8abd9371 100644 --- a/arch/arm/mach-clps711x/clep7312.c +++ b/arch/arm/mach-clps711x/clep7312.c @@ -37,7 +37,7 @@ fixup_clep7312(struct machine_desc *desc, struct tag *tags,  MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")  	/* Maintainer: Nobody */ -	.boot_params	= 0xc0000100, +	.atag_offset	= 0x0100,  	.fixup		= fixup_clep7312,  	.map_io		= clps711x_map_io,  	.init_irq	= clps711x_init_irq, diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c index 98ca5b2e940..abf522d1ec9 100644 --- a/arch/arm/mach-clps711x/edb7211-arch.c +++ b/arch/arm/mach-clps711x/edb7211-arch.c @@ -57,7 +57,7 @@ fixup_edb7211(struct machine_desc *desc, struct tag *tags,  MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")  	/* Maintainer: Jon McClintock */ -	.boot_params	= 0xc0020100,	/* 0xc0000000 - 0xc001ffff can be video RAM */ +	.atag_offset	= 0x20100,	/* 0xc0000000 - 0xc001ffff can be video RAM */  	.fixup		= fixup_edb7211,  	.map_io		= edb7211_map_io,  	.reserve	= edb7211_reserve, diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c index b1cb479e71e..b6f7d86bb1c 100644 --- a/arch/arm/mach-clps711x/fortunet.c +++ b/arch/arm/mach-clps711x/fortunet.c @@ -75,7 +75,6 @@ fortunet_fixup(struct machine_desc *desc, struct tag *tags,  MACHINE_START(FORTUNET, "ARM-FortuNet")  	/* Maintainer: FortuNet Inc. */ -	.boot_params	= 0x00000000,  	.fixup		= fortunet_fixup,  	.map_io		= clps711x_map_io,  	.init_irq	= clps711x_init_irq, diff --git a/arch/arm/mach-clps711x/include/mach/debug-macro.S b/arch/arm/mach-clps711x/include/mach/debug-macro.S index 507c6873b7e..b802e8a5183 100644 --- a/arch/arm/mach-clps711x/include/mach/debug-macro.S +++ b/arch/arm/mach-clps711x/include/mach/debug-macro.S @@ -14,7 +14,7 @@  #include <mach/hardware.h>  #include <asm/hardware/clps7111.h> -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  #ifndef CONFIG_DEBUG_CLPS711X_UART2  		mov	\rp, #0x0000	@ UART1  #else diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c index cefbce0480b..e7f75aeb1e5 100644 --- a/arch/arm/mach-clps711x/p720t.c +++ b/arch/arm/mach-clps711x/p720t.c @@ -89,7 +89,7 @@ static void __init p720t_map_io(void)  MACHINE_START(P720T, "ARM-Prospector720T")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ -	.boot_params	= 0xc0000100, +	.atag_offset	= 0x100,  	.fixup		= fixup_p720t,  	.map_io		= p720t_map_io,  	.init_irq	= clps711x_init_irq, diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c index 3e7d1496cb4..55f7b4b08ab 100644 --- a/arch/arm/mach-cns3xxx/cns3420vb.c +++ b/arch/arm/mach-cns3xxx/cns3420vb.c @@ -197,7 +197,7 @@ static void __init cns3420_map_io(void)  }  MACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= cns3420_map_io,  	.init_irq	= cns3xxx_init_irq,  	.timer		= &cns3xxx_timer, diff --git a/arch/arm/mach-cns3xxx/include/mach/debug-macro.S b/arch/arm/mach-cns3xxx/include/mach/debug-macro.S index 56d828634db..d04c150baa1 100644 --- a/arch/arm/mach-cns3xxx/include/mach/debug-macro.S +++ b/arch/arm/mach-cns3xxx/include/mach/debug-macro.S @@ -10,7 +10,7 @@   * published by the Free Software Foundation.   */ -		.macro	addruart,rp,rv +		.macro	addruart,rp,rv,tmp  		mov	\rp, #0x00009000  		orr	\rv, \rp, #0xf0000000	@ virtual base  		orr	\rp, \rp, #0x10000000 diff --git a/arch/arm/mach-cns3xxx/include/mach/memory.h b/arch/arm/mach-cns3xxx/include/mach/memory.h deleted file mode 100644 index dc16c5c5d86..00000000000 --- a/arch/arm/mach-cns3xxx/include/mach/memory.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2003 ARM Limited - * Copyright 2008 Cavium Networks - * - * This file 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 __MACH_MEMORY_H -#define __MACH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PLAT_PHYS_OFFSET		UL(0x00000000) - -#define __phys_to_bus(x)	((x) + PHYS_OFFSET) -#define __bus_to_phys(x)	((x) - PHYS_OFFSET) - -#define __virt_to_bus(v)	__phys_to_bus(__virt_to_phys(v)) -#define __bus_to_virt(b)	__phys_to_virt(__bus_to_phys(b)) -#define __pfn_to_bus(p)		__phys_to_bus(__pfn_to_phys(p)) -#define __bus_to_pfn(b)		__phys_to_pfn(__bus_to_phys(b)) - -#endif diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 84fd7868486..26d94c0b555 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -676,7 +676,7 @@ static void __init da830_evm_map_io(void)  }  MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM") -	.boot_params	= (DA8XX_DDR_BASE + 0x100), +	.atag_offset	= 0x100,  	.map_io		= da830_evm_map_io,  	.init_irq	= cp_intc_init,  	.timer		= &davinci_timer, diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 008d51407cd..6e41cb5baeb 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -1291,7 +1291,7 @@ static void __init da850_evm_map_io(void)  }  MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM") -	.boot_params	= (DA8XX_DDR_BASE + 0x100), +	.atag_offset	= 0x100,  	.map_io		= da850_evm_map_io,  	.init_irq	= cp_intc_init,  	.timer		= &davinci_timer, diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 241a6bd6740..65566280b7c 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -351,7 +351,7 @@ static __init void dm355_evm_init(void)  }  MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM") -	.boot_params  = (0x80000100), +	.atag_offset  = 0x100,  	.map_io	      = dm355_evm_map_io,  	.init_irq     = davinci_irq_init,  	.timer	      = &davinci_timer, diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index bee284ca7fd..b307470b071 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -270,7 +270,7 @@ static __init void dm355_leopard_init(void)  }  MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard") -	.boot_params  = (0x80000100), +	.atag_offset  = 0x100,  	.map_io	      = dm355_leopard_map_io,  	.init_irq     = davinci_irq_init,  	.timer	      = &davinci_timer, diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 9818f214d4f..04c43abcca6 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -612,7 +612,7 @@ static __init void dm365_evm_init(void)  }  MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM") -	.boot_params	= (0x80000100), +	.atag_offset	= 0x100,  	.map_io		= dm365_evm_map_io,  	.init_irq	= davinci_irq_init,  	.timer		= &davinci_timer, diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 95607a191e0..a005e7691dd 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -712,7 +712,7 @@ static __init void davinci_evm_init(void)  MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")  	/* Maintainer: MontaVista Software <source@mvista.com> */ -	.boot_params  = (DAVINCI_DDR_BASE + 0x100), +	.atag_offset  = 0x100,  	.map_io	      = davinci_evm_map_io,  	.init_irq     = davinci_irq_init,  	.timer	      = &davinci_timer, diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 993a3146fd3..337c45e3e44 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -792,7 +792,7 @@ static __init void evm_init(void)  }  MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM") -	.boot_params  = (0x80000100), +	.atag_offset  = 0x100,  	.map_io       = davinci_map_io,  	.init_irq     = davinci_irq_init,  	.timer        = &davinci_timer, @@ -801,7 +801,7 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")  MACHINE_END  MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM") -	.boot_params  = (0x80000100), +	.atag_offset  = 0x100,  	.map_io       = davinci_map_io,  	.init_irq     = davinci_irq_init,  	.timer        = &davinci_timer, diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index c278226627a..6efc84cceca 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -566,7 +566,7 @@ static void __init mityomapl138_map_io(void)  }  MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808") -	.boot_params	= (DA8XX_DDR_BASE + 0x100), +	.atag_offset	= 0x100,  	.map_io		= mityomapl138_map_io,  	.init_irq	= cp_intc_init,  	.timer		= &davinci_timer, diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index d60a80028ba..38d6f644d8b 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -272,7 +272,7 @@ static __init void davinci_ntosd2_init(void)  MACHINE_START(NEUROS_OSD2, "Neuros OSD2")  	/* Maintainer: Neuros Technologies <neuros@groups.google.com> */ -	.boot_params	= (DAVINCI_DDR_BASE + 0x100), +	.atag_offset	= 0x100,  	.map_io		 = davinci_ntosd2_map_io,  	.init_irq	= davinci_irq_init,  	.timer		= &davinci_timer, diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 237332a1142..c6701e4a795 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -338,7 +338,7 @@ static void __init omapl138_hawk_map_io(void)  }  MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard") -	.boot_params	= (DA8XX_DDR_BASE + 0x100), +	.atag_offset	= 0x100,  	.map_io		= omapl138_hawk_map_io,  	.init_irq	= cp_intc_init,  	.timer		= &davinci_timer, diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index 5f4385c0a08..5dd4da9d230 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -151,7 +151,7 @@ static __init void davinci_sffsdr_init(void)  MACHINE_START(SFFSDR, "Lyrtech SFFSDR")  	/* Maintainer: Hugo Villeneuve hugo.villeneuve@lyrtech.com */ -	.boot_params  = (DAVINCI_DDR_BASE + 0x100), +	.atag_offset  = 0x100,  	.map_io	      = davinci_sffsdr_map_io,  	.init_irq     = davinci_irq_init,  	.timer	      = &davinci_timer, diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 78289206568..90ee7b5aabd 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -277,7 +277,7 @@ console_initcall(tnetv107x_evm_console_init);  #endif  MACHINE_START(TNETV107X, "TNETV107X EVM") -	.boot_params	= (TNETV107X_DDR_BASE + 0x100), +	.atag_offset	= 0x100,  	.map_io		= tnetv107x_init,  	.init_irq	= cp_intc_init,  	.timer		= &davinci_timer, diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index 1d255739423..865ffe5899a 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -12,6 +12,7 @@  #include <linux/io.h>  #include <linux/etherdevice.h>  #include <linux/davinci_emac.h> +#include <linux/dma-mapping.h>  #include <asm/tlb.h>  #include <asm/mach/map.h> @@ -86,6 +87,8 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info)  		iotable_init(davinci_soc_info.io_desc,  				davinci_soc_info.io_desc_num); +	init_consistent_dma_size(14 << 20); +  	/*  	 * Normally devicemaps_init() would flush caches and tlb after  	 * mdesc->map_io(), but we must also do it here because of the CPU diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c index bd59f31b8a9..0b314bf16f7 100644 --- a/arch/arm/mach-davinci/cpuidle.c +++ b/arch/arm/mach-davinci/cpuidle.c @@ -19,7 +19,7 @@  #include <asm/proc-fns.h>  #include <mach/cpuidle.h> -#include <mach/memory.h> +#include <mach/ddr2.h>  #define DAVINCI_CPUIDLE_MAX_STATES	2 diff --git a/arch/arm/mach-davinci/include/mach/ddr2.h b/arch/arm/mach-davinci/include/mach/ddr2.h new file mode 100644 index 00000000000..c19e047d0e6 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/ddr2.h @@ -0,0 +1,4 @@ +#define DDR2_SDRCR_OFFSET	0xc +#define DDR2_SRPD_BIT		(1 << 23) +#define DDR2_MCLKSTOPEN_BIT	(1 << 30) +#define DDR2_LPMODEN_BIT	(1 << 31) diff --git a/arch/arm/mach-davinci/include/mach/debug-macro.S b/arch/arm/mach-davinci/include/mach/debug-macro.S index f8b7ea4f623..cf94552d527 100644 --- a/arch/arm/mach-davinci/include/mach/debug-macro.S +++ b/arch/arm/mach-davinci/include/mach/debug-macro.S @@ -18,56 +18,50 @@  #include <linux/serial_reg.h> -#include <asm/memory.h> -  #include <mach/serial.h>  #define UART_SHIFT	2 -#define davinci_uart_v2p(x)	((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET) -#define davinci_uart_p2v(x)	((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET) -  		.pushsection .data  davinci_uart_phys:	.word	0  davinci_uart_virt:	.word	0  		.popsection -		.macro addruart, rp, rv +		.macro addruart, rp, rv, tmp  		/* Use davinci_uart_phys/virt if already configured */ -10:		mrc	p15, 0, \rp, c1, c0 -		tst	\rp, #1			@ MMU enabled? -		ldreq	\rp, =davinci_uart_v2p(davinci_uart_phys) -		ldrne	\rp, =davinci_uart_phys -		add	\rv, \rp, #4		@ davinci_uart_virt -		ldr	\rp, [\rp, #0] -		ldr	\rv, [\rv, #0] +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]		@ davinci_uart_phys +		ldr	\rv, [\tmp, #4]		@ davinci_uart_virt  		cmp	\rp, #0			@ is port configured?  		cmpne	\rv, #0 -		bne	99f			@ already configured +		bne	100f			@ already configured  		/* Check the debug UART address set in uncompress.h */ -		mrc	p15, 0, \rp, c1, c0 -		tst	\rp, #1			@ MMU enabled? +		and	\rp, pc, #0xff000000 +		ldr	\rv, =DAVINCI_UART_INFO_OFS +		add	\rp, \rp, \rv  		/* Copy uart phys address from decompressor uart info */ -		ldreq	\rv, =davinci_uart_v2p(davinci_uart_phys) -		ldrne	\rv, =davinci_uart_phys -		ldreq	\rp, =DAVINCI_UART_INFO -		ldrne	\rp, =davinci_uart_p2v(DAVINCI_UART_INFO) -		ldr	\rp, [\rp, #0] -		str	\rp, [\rv] +		ldr	\rv, [\rp, #0] +		str	\rv, [\tmp, #0]  		/* Copy uart virt address from decompressor uart info */ -		ldreq	\rv, =davinci_uart_v2p(davinci_uart_virt) -		ldrne	\rv, =davinci_uart_virt -		ldreq	\rp, =DAVINCI_UART_INFO -		ldrne	\rp, =davinci_uart_p2v(DAVINCI_UART_INFO) -		ldr	\rp, [\rp, #4] -		str	\rp, [\rv] +		ldr	\rv, [\rp, #4] +		str	\rv, [\tmp, #4]  		b	10b -99: + +		.align +99:		.word	. +		.word	davinci_uart_phys +		.ltorg + +100:  		.endm  		.macro	senduart,rd,rx diff --git a/arch/arm/mach-davinci/include/mach/memory.h b/arch/arm/mach-davinci/include/mach/memory.h deleted file mode 100644 index 78731944a70..00000000000 --- a/arch/arm/mach-davinci/include/mach/memory.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * DaVinci memory space definitions - * - * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com> - * - * 2007 (c) MontaVista Software, Inc. 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_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/************************************************************************** - * Included Files - **************************************************************************/ -#include <asm/page.h> -#include <asm/sizes.h> - -/************************************************************************** - * Definitions - **************************************************************************/ -#define DAVINCI_DDR_BASE	0x80000000 -#define DA8XX_DDR_BASE		0xc0000000 - -#if defined(CONFIG_ARCH_DAVINCI_DA8XX) && defined(CONFIG_ARCH_DAVINCI_DMx) -#error Cannot enable DaVinci and DA8XX platforms concurrently -#elif defined(CONFIG_ARCH_DAVINCI_DA8XX) -#define PLAT_PHYS_OFFSET DA8XX_DDR_BASE -#else -#define PLAT_PHYS_OFFSET DAVINCI_DDR_BASE -#endif - -#define DDR2_SDRCR_OFFSET	0xc -#define DDR2_SRPD_BIT		BIT(23) -#define DDR2_MCLKSTOPEN_BIT	BIT(30) -#define DDR2_LPMODEN_BIT	BIT(31) - -/* - * Increase size of DMA-consistent memory region - */ -#define CONSISTENT_DMA_SIZE (14<<20) - -#endif /* __ASM_ARCH_MEMORY_H */ diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h index c9e6ce185a6..e347d88fef9 100644 --- a/arch/arm/mach-davinci/include/mach/serial.h +++ b/arch/arm/mach-davinci/include/mach/serial.h @@ -21,8 +21,9 @@   * macros in debug-macro.S.   *   * This area sits just below the page tables (see arch/arm/kernel/head.S). + * We define it as a relative offset from start of usable RAM.   */ -#define DAVINCI_UART_INFO	(PLAT_PHYS_OFFSET + 0x3ff8) +#define DAVINCI_UART_INFO_OFS	0x3ff8  #define DAVINCI_UART0_BASE	(IO_PHYS + 0x20000)  #define DAVINCI_UART1_BASE	(IO_PHYS + 0x20400) diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h index 78d80683cdc..9dc7cf9664f 100644 --- a/arch/arm/mach-davinci/include/mach/uncompress.h +++ b/arch/arm/mach-davinci/include/mach/uncompress.h @@ -43,7 +43,12 @@ static inline void flush(void)  static inline void set_uart_info(u32 phys, void * __iomem virt)  { -	u32 *uart_info = (u32 *)(DAVINCI_UART_INFO); +	/* +	 * Get address of some.bss variable and round it down +	 * a la CONFIG_AUTO_ZRELADDR. +	 */ +	u32 ram_start = (u32)&uart & 0xf8000000; +	u32 *uart_info = (u32 *)(ram_start + DAVINCI_UART_INFO_OFS);  	uart = (u32 *)phys;  	uart_info[0] = phys; diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S index 5f1e045a3ad..d4e9316ecac 100644 --- a/arch/arm/mach-davinci/sleep.S +++ b/arch/arm/mach-davinci/sleep.S @@ -22,7 +22,7 @@  #include <linux/linkage.h>  #include <asm/assembler.h>  #include <mach/psc.h> -#include <mach/memory.h> +#include <mach/ddr2.h>  #include "clock.h" diff --git a/arch/arm/mach-dove/cm-a510.c b/arch/arm/mach-dove/cm-a510.c index 03e11f9dca9..c8a406f7e94 100644 --- a/arch/arm/mach-dove/cm-a510.c +++ b/arch/arm/mach-dove/cm-a510.c @@ -87,7 +87,7 @@ static void __init cm_a510_init(void)  }  MACHINE_START(CM_A510, "Compulab CM-A510 Board") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= cm_a510_init,  	.map_io		= dove_map_io,  	.init_early	= dove_init_early, diff --git a/arch/arm/mach-dove/dove-db-setup.c b/arch/arm/mach-dove/dove-db-setup.c index 2ac34ecfa74..11ea34e4fc7 100644 --- a/arch/arm/mach-dove/dove-db-setup.c +++ b/arch/arm/mach-dove/dove-db-setup.c @@ -94,7 +94,7 @@ static void __init dove_db_init(void)  }  MACHINE_START(DOVE_DB, "Marvell DB-MV88AP510-BP Development Board") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= dove_db_init,  	.map_io		= dove_map_io,  	.init_early	= dove_init_early, diff --git a/arch/arm/mach-dove/include/mach/debug-macro.S b/arch/arm/mach-dove/include/mach/debug-macro.S index da8bf2bad3b..5929cbc5916 100644 --- a/arch/arm/mach-dove/include/mach/debug-macro.S +++ b/arch/arm/mach-dove/include/mach/debug-macro.S @@ -8,7 +8,7 @@  #include <mach/bridge-regs.h> -	.macro	addruart, rp, rv +	.macro	addruart, rp, rv, tmp  	ldr	\rp, =DOVE_SB_REGS_PHYS_BASE  	ldr	\rv, =DOVE_SB_REGS_VIRT_BASE  	orr	\rp, \rp, #0x00012000 diff --git a/arch/arm/mach-dove/include/mach/memory.h b/arch/arm/mach-dove/include/mach/memory.h deleted file mode 100644 index bbc93fee6c7..00000000000 --- a/arch/arm/mach-dove/include/mach/memory.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * arch/arm/mach-dove/include/mach/memory.h - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET		UL(0x00000000) - -#endif diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index 087bc771ac2..d0ce8abdd4b 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -280,7 +280,7 @@ arch_initcall(ebsa110_init);  MACHINE_START(EBSA110, "EBSA110")  	/* Maintainer: Russell King */ -	.boot_params	= 0x00000400, +	.atag_offset	= 0x400,  	.reserve_lp0	= 1,  	.reserve_lp2	= 1,  	.soft_reboot	= 1, diff --git a/arch/arm/mach-ebsa110/include/mach/debug-macro.S b/arch/arm/mach-ebsa110/include/mach/debug-macro.S index 7ef5690fd08..bb02c05e681 100644 --- a/arch/arm/mach-ebsa110/include/mach/debug-macro.S +++ b/arch/arm/mach-ebsa110/include/mach/debug-macro.S @@ -11,7 +11,7 @@   *  **/ -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #0xf0000000  		orr	\rp, \rp, #0x00000be0  		mov	\rp, \rv diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c index 61b98ce4b67..0713448206a 100644 --- a/arch/arm/mach-ep93xx/adssphere.c +++ b/arch/arm/mach-ep93xx/adssphere.c @@ -33,7 +33,7 @@ static void __init adssphere_init_machine(void)  MACHINE_START(ADSSPHERE, "ADS Sphere board")  	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ -	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index 3f320c6477b..c63a5ec1a8e 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c @@ -241,7 +241,7 @@ static void __init edb93xx_init_machine(void)  #ifdef CONFIG_MACH_EDB9301  MACHINE_START(EDB9301, "Cirrus Logic EDB9301 Evaluation Board")  	/* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */ -	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, @@ -252,7 +252,7 @@ MACHINE_END  #ifdef CONFIG_MACH_EDB9302  MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board")  	/* Maintainer: George Kashperko <george@chas.com.ua> */ -	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, @@ -263,7 +263,7 @@ MACHINE_END  #ifdef CONFIG_MACH_EDB9302A  MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board")  	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ -	.boot_params	= EP93XX_SDCE0_PHYS_BASE + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, @@ -274,7 +274,7 @@ MACHINE_END  #ifdef CONFIG_MACH_EDB9307  MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")  	/* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */ -	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, @@ -285,7 +285,7 @@ MACHINE_END  #ifdef CONFIG_MACH_EDB9307A  MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board")  	/* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */ -	.boot_params	= EP93XX_SDCE0_PHYS_BASE + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, @@ -296,7 +296,7 @@ MACHINE_END  #ifdef CONFIG_MACH_EDB9312  MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")  	/* Maintainer: Toufeeq Hussain <toufeeq_hussain@infosys.com> */ -	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, @@ -307,7 +307,7 @@ MACHINE_END  #ifdef CONFIG_MACH_EDB9315  MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")  	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ -	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, @@ -318,7 +318,7 @@ MACHINE_END  #ifdef CONFIG_MACH_EDB9315A  MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")  	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ -	.boot_params	= EP93XX_SDCE0_PHYS_BASE + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c index 9bd3152bff9..45ee205856f 100644 --- a/arch/arm/mach-ep93xx/gesbc9312.c +++ b/arch/arm/mach-ep93xx/gesbc9312.c @@ -33,7 +33,7 @@ static void __init gesbc9312_init_machine(void)  MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx")  	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ -	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, diff --git a/arch/arm/mach-ep93xx/include/mach/debug-macro.S b/arch/arm/mach-ep93xx/include/mach/debug-macro.S index b25bc907636..af54e43132c 100644 --- a/arch/arm/mach-ep93xx/include/mach/debug-macro.S +++ b/arch/arm/mach-ep93xx/include/mach/debug-macro.S @@ -11,7 +11,7 @@   */  #include <mach/ep93xx-regs.h> -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		ldr	\rp, =EP93XX_APB_PHYS_BASE	@ Physical base  		ldr	\rv, =EP93XX_APB_VIRT_BASE	@ virtual base  		orr	\rp, \rp, #0x000c0000 diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c index 7adea6258ef..e72f7368876 100644 --- a/arch/arm/mach-ep93xx/micro9.c +++ b/arch/arm/mach-ep93xx/micro9.c @@ -77,7 +77,7 @@ static void __init micro9_init_machine(void)  #ifdef CONFIG_MACH_MICRO9H  MACHINE_START(MICRO9, "Contec Micro9-High")  	/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */ -	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, @@ -88,7 +88,7 @@ MACHINE_END  #ifdef CONFIG_MACH_MICRO9M  MACHINE_START(MICRO9M, "Contec Micro9-Mid")  	/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */ -	.boot_params	= EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, @@ -99,7 +99,7 @@ MACHINE_END  #ifdef CONFIG_MACH_MICRO9L  MACHINE_START(MICRO9L, "Contec Micro9-Lite")  	/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */ -	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, @@ -110,7 +110,7 @@ MACHINE_END  #ifdef CONFIG_MACH_MICRO9S  MACHINE_START(MICRO9S, "Contec Micro9-Slim")  	/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */ -	.boot_params	= EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c index 1a472ff12cc..d6f286b4db9 100644 --- a/arch/arm/mach-ep93xx/simone.c +++ b/arch/arm/mach-ep93xx/simone.c @@ -65,8 +65,8 @@ static void __init simone_init_machine(void)  }  MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board") -/* Maintainer: Ryan Mallon */ -	.boot_params	= EP93XX_SDCE0_PHYS_BASE + 0x100, +	/* Maintainer: Ryan Mallon */ +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c index 4f4b0b2c4c3..2b4d4b0201d 100644 --- a/arch/arm/mach-ep93xx/snappercl15.c +++ b/arch/arm/mach-ep93xx/snappercl15.c @@ -163,7 +163,7 @@ static void __init snappercl15_init_machine(void)  MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15")  	/* Maintainer: Ryan Mallon */ -	.boot_params	= EP93XX_SDCE0_PHYS_BASE + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ep93xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer 		= &ep93xx_timer, diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index c2d2cf40ead..1ade3c34050 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -257,7 +257,7 @@ static void __init ts72xx_init_machine(void)  MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")  	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ -	.boot_params	= EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ts72xx_map_io,  	.init_irq	= ep93xx_init_irq,  	.timer		= &ep93xx_timer, diff --git a/arch/arm/mach-exynos4/include/mach/debug-macro.S b/arch/arm/mach-exynos4/include/mach/debug-macro.S index a442ef86116..6cacf16a67a 100644 --- a/arch/arm/mach-exynos4/include/mach/debug-macro.S +++ b/arch/arm/mach-exynos4/include/mach/debug-macro.S @@ -20,7 +20,7 @@  	 * aligned and add in the offset when we load the value here.  	 */ -	.macro addruart, rp, rv +	.macro addruart, rp, rv, tmp  		ldr	\rp, = S3C_PA_UART  		ldr	\rv, = S3C_VA_UART  #if CONFIG_DEBUG_S3C_UART != 0 diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S index d7a1e281ce7..006a4f4c65c 100644 --- a/arch/arm/mach-exynos4/include/mach/entry-macro.S +++ b/arch/arm/mach-exynos4/include/mach/entry-macro.S @@ -55,7 +55,7 @@  		bic     \irqnr, \irqstat, #0x1c00 -		cmp     \irqnr, #29 +		cmp     \irqnr, #15  		cmpcc	\irqnr, \irqnr  		cmpne	\irqnr, \tmp  		cmpcs	\irqnr, \irqnr @@ -76,8 +76,3 @@  		strcc	\irqstat, [\base, #GIC_CPU_EOI]  		cmpcs	\irqnr, \irqnr  		.endm - -		/* As above, this assumes that irqstat and base are preserved.. */ - -		.macro test_for_ltirq, irqnr, irqstat, base, tmp -		.endm diff --git a/arch/arm/mach-exynos4/mach-armlex4210.c b/arch/arm/mach-exynos4/mach-armlex4210.c index b482c6285fc..f0ca6c157d2 100644 --- a/arch/arm/mach-exynos4/mach-armlex4210.c +++ b/arch/arm/mach-exynos4/mach-armlex4210.c @@ -207,7 +207,7 @@ static void __init armlex4210_machine_init(void)  MACHINE_START(ARMLEX4210, "ARMLEX4210")  	/* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */ -	.boot_params	= S5P_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= exynos4_init_irq,  	.map_io		= armlex4210_map_io,  	.init_machine	= armlex4210_machine_init, diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos4/mach-nuri.c index 43be71b799c..6e0536818bf 100644 --- a/arch/arm/mach-exynos4/mach-nuri.c +++ b/arch/arm/mach-exynos4/mach-nuri.c @@ -1152,7 +1152,7 @@ static void __init nuri_machine_init(void)  MACHINE_START(NURI, "NURI")  	/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */ -	.boot_params	= S5P_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= exynos4_init_irq,  	.map_io		= nuri_map_io,  	.init_machine	= nuri_machine_init, diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c index a7c65e05c1e..b24ddd7ad8f 100644 --- a/arch/arm/mach-exynos4/mach-smdkc210.c +++ b/arch/arm/mach-exynos4/mach-smdkc210.c @@ -301,7 +301,7 @@ static void __init smdkc210_machine_init(void)  MACHINE_START(SMDKC210, "SMDKC210")  	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ -	.boot_params	= S5P_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= exynos4_init_irq,  	.map_io		= smdkc210_map_io,  	.init_machine	= smdkc210_machine_init, diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c index ea414955686..d90fcddbee1 100644 --- a/arch/arm/mach-exynos4/mach-smdkv310.c +++ b/arch/arm/mach-exynos4/mach-smdkv310.c @@ -255,7 +255,7 @@ static void __init smdkv310_machine_init(void)  MACHINE_START(SMDKV310, "SMDKV310")  	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */  	/* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */ -	.boot_params	= S5P_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= exynos4_init_irq,  	.map_io		= smdkv310_map_io,  	.init_machine	= smdkv310_machine_init, diff --git a/arch/arm/mach-exynos4/mach-universal_c210.c b/arch/arm/mach-exynos4/mach-universal_c210.c index b3b5d891100..2aac6f755c8 100644 --- a/arch/arm/mach-exynos4/mach-universal_c210.c +++ b/arch/arm/mach-exynos4/mach-universal_c210.c @@ -762,7 +762,7 @@ static void __init universal_machine_init(void)  MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")  	/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */ -	.boot_params	= S5P_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= exynos4_init_irq,  	.map_io		= universal_map_io,  	.init_machine	= universal_machine_init, diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c index ddd86864fb8..582b874aab0 100644 --- a/arch/arm/mach-exynos4/mct.c +++ b/arch/arm/mach-exynos4/mct.c @@ -386,9 +386,11 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)  	if (cpu == 0) {  		mct_tick0_event_irq.dev_id = &mct_tick[cpu]; +		evt->irq = IRQ_MCT_L0;  		setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq);  	} else {  		mct_tick1_event_irq.dev_id = &mct_tick[cpu]; +		evt->irq = IRQ_MCT_L1;  		setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq);  		irq_set_affinity(IRQ_MCT_L1, cpumask_of(1));  	} @@ -402,9 +404,10 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)  	return 0;  } -int local_timer_ack(void) +void local_timer_stop(struct clock_event_device *evt)  { -	return 0; +	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); +	disable_irq(evt->irq);  }  #endif /* CONFIG_LOCAL_TIMERS */ diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c index df6ef1b2f98..0c90896ad9a 100644 --- a/arch/arm/mach-exynos4/platsmp.c +++ b/arch/arm/mach-exynos4/platsmp.c @@ -193,12 +193,10 @@ void __init smp_init_cpus(void)  	ncores = scu_base ? scu_get_core_count(scu_base) : 1;  	/* sanity check */ -	if (ncores > NR_CPUS) { -		printk(KERN_WARNING -		       "EXYNOS4: no. of cores (%d) greater than configured " -		       "maximum of %d - clipping\n", -		       ncores, NR_CPUS); -		ncores = NR_CPUS; +	if (ncores > nr_cpu_ids) { +		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", +			ncores, nr_cpu_ids); +		ncores = nr_cpu_ids;  	}  	for (i = 0; i < ncores; i++) diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c index 5b1a8db779b..a3da5d1106c 100644 --- a/arch/arm/mach-footbridge/cats-hw.c +++ b/arch/arm/mach-footbridge/cats-hw.c @@ -86,7 +86,7 @@ fixup_cats(struct machine_desc *desc, struct tag *tags,  MACHINE_START(CATS, "Chalice-CATS")  	/* Maintainer: Philip Blundell */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.soft_reboot	= 1,  	.fixup		= fixup_cats,  	.map_io		= footbridge_map_io, diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c index 2ef69ff44ba..012210cf7d1 100644 --- a/arch/arm/mach-footbridge/ebsa285.c +++ b/arch/arm/mach-footbridge/ebsa285.c @@ -15,7 +15,7 @@  MACHINE_START(EBSA285, "EBSA285")  	/* Maintainer: Russell King */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.video_start	= 0x000a0000,  	.video_end	= 0x000bffff,  	.map_io		= footbridge_map_io, diff --git a/arch/arm/mach-footbridge/include/mach/debug-macro.S b/arch/arm/mach-footbridge/include/mach/debug-macro.S index 1be2eeb7a0a..e5acde25ffc 100644 --- a/arch/arm/mach-footbridge/include/mach/debug-macro.S +++ b/arch/arm/mach-footbridge/include/mach/debug-macro.S @@ -15,7 +15,7 @@  #ifndef CONFIG_DEBUG_DC21285_PORT  	/* For NetWinder debugging */ -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #0x000003f8  		orr	\rv, \rp, #0xff000000	@ virtual  		orr	\rp, \rp, #0x7c000000	@ physical @@ -31,7 +31,7 @@  		.equ	dc21285_high, ARMCSR_BASE & 0xff000000  		.equ	dc21285_low,  ARMCSR_BASE & 0x00ffffff -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		.if	dc21285_low  		mov	\rp, #dc21285_low  		.else diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c index 06e514f372d..d8c1c922e24 100644 --- a/arch/arm/mach-footbridge/netwinder-hw.c +++ b/arch/arm/mach-footbridge/netwinder-hw.c @@ -648,7 +648,7 @@ fixup_netwinder(struct machine_desc *desc, struct tag *tags,  MACHINE_START(NETWINDER, "Rebel-NetWinder")  	/* Maintainer: Russell King/Rebel.com */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.video_start	= 0x000a0000,  	.video_end	= 0x000bffff,  	.reserve_lp0	= 1, diff --git a/arch/arm/mach-footbridge/personal.c b/arch/arm/mach-footbridge/personal.c index 3285e91ca8c..f41dba39b32 100644 --- a/arch/arm/mach-footbridge/personal.c +++ b/arch/arm/mach-footbridge/personal.c @@ -15,7 +15,7 @@  MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")  	/* Maintainer: Jamey Hicks / George France */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= footbridge_map_io,  	.init_irq	= footbridge_init_irq,  	.timer		= &footbridge_timer, diff --git a/arch/arm/mach-gemini/board-nas4220b.c b/arch/arm/mach-gemini/board-nas4220b.c index 0cf7a07c3f3..5927d3c253a 100644 --- a/arch/arm/mach-gemini/board-nas4220b.c +++ b/arch/arm/mach-gemini/board-nas4220b.c @@ -102,7 +102,7 @@ static void __init ib4220b_init(void)  }  MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B") -	.boot_params	= 0x100, +	.atag_offset	= 0x100,  	.map_io		= gemini_map_io,  	.init_irq	= gemini_init_irq,  	.timer		= &ib4220b_timer, diff --git a/arch/arm/mach-gemini/board-rut1xx.c b/arch/arm/mach-gemini/board-rut1xx.c index 4fa09af9949..cd7437a1cea 100644 --- a/arch/arm/mach-gemini/board-rut1xx.c +++ b/arch/arm/mach-gemini/board-rut1xx.c @@ -86,7 +86,7 @@ static void __init rut1xx_init(void)  }  MACHINE_START(RUT100, "Teltonika RUT100") -	.boot_params	= 0x100, +	.atag_offset	= 0x100,  	.map_io		= gemini_map_io,  	.init_irq	= gemini_init_irq,  	.timer		= &rut1xx_timer, diff --git a/arch/arm/mach-gemini/board-wbd111.c b/arch/arm/mach-gemini/board-wbd111.c index 88cc422ee44..a367880368f 100644 --- a/arch/arm/mach-gemini/board-wbd111.c +++ b/arch/arm/mach-gemini/board-wbd111.c @@ -129,7 +129,7 @@ static void __init wbd111_init(void)  }  MACHINE_START(WBD111, "Wiliboard WBD-111") -	.boot_params	= 0x100, +	.atag_offset	= 0x100,  	.map_io		= gemini_map_io,  	.init_irq	= gemini_init_irq,  	.timer		= &wbd111_timer, diff --git a/arch/arm/mach-gemini/board-wbd222.c b/arch/arm/mach-gemini/board-wbd222.c index 3a220347bc8..f382811c131 100644 --- a/arch/arm/mach-gemini/board-wbd222.c +++ b/arch/arm/mach-gemini/board-wbd222.c @@ -129,7 +129,7 @@ static void __init wbd222_init(void)  }  MACHINE_START(WBD222, "Wiliboard WBD-222") -	.boot_params	= 0x100, +	.atag_offset	= 0x100,  	.map_io		= gemini_map_io,  	.init_irq	= gemini_init_irq,  	.timer		= &wbd222_timer, diff --git a/arch/arm/mach-gemini/include/mach/debug-macro.S b/arch/arm/mach-gemini/include/mach/debug-macro.S index f40e006d296..837670763b8 100644 --- a/arch/arm/mach-gemini/include/mach/debug-macro.S +++ b/arch/arm/mach-gemini/include/mach/debug-macro.S @@ -11,7 +11,7 @@   */  #include <mach/hardware.h> -	.macro	addruart, rp, rv +	.macro	addruart, rp, rv, tmp  	ldr	\rp, =GEMINI_UART_BASE			@ physical  	ldr	\rv, =IO_ADDRESS(GEMINI_UART_BASE)	@ virtual  	.endm diff --git a/arch/arm/mach-gemini/include/mach/memory.h b/arch/arm/mach-gemini/include/mach/memory.h deleted file mode 100644 index a50915f764d..00000000000 --- a/arch/arm/mach-gemini/include/mach/memory.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - *  Copyright (C) 2001-2006 Storlink, Corp. - *  Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> - * - * 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. - */ -#ifndef __MACH_MEMORY_H -#define __MACH_MEMORY_H - -#ifdef CONFIG_GEMINI_MEM_SWAP -# define PLAT_PHYS_OFFSET	UL(0x00000000) -#else -# define PLAT_PHYS_OFFSET	UL(0x10000000) -#endif - -#endif /* __MACH_MEMORY_H */ diff --git a/arch/arm/mach-h720x/h7201-eval.c b/arch/arm/mach-h720x/h7201-eval.c index 65f1bea958e..9886f19805f 100644 --- a/arch/arm/mach-h720x/h7201-eval.c +++ b/arch/arm/mach-h720x/h7201-eval.c @@ -29,7 +29,7 @@  MACHINE_START(H7201, "Hynix GMS30C7201")  	/* Maintainer: Robert Schwebel, Pengutronix */ -	.boot_params	= 0xc0001000, +	.atag_offset	= 0x1000,  	.map_io		= h720x_map_io,  	.init_irq	= h720x_init_irq,  	.timer		= &h7201_timer, diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c index 884584a0975..284a134819e 100644 --- a/arch/arm/mach-h720x/h7202-eval.c +++ b/arch/arm/mach-h720x/h7202-eval.c @@ -71,7 +71,7 @@ static void __init init_eval_h7202(void)  MACHINE_START(H7202, "Hynix HMS30C7202")  	/* Maintainer: Robert Schwebel, Pengutronix */ -	.boot_params	= 0x40000100, +	.atag_offset	= 0x100,  	.map_io		= h720x_map_io,  	.init_irq	= h7202_init_irq,  	.timer		= &h7202_timer, diff --git a/arch/arm/mach-h720x/include/mach/debug-macro.S b/arch/arm/mach-h720x/include/mach/debug-macro.S index c2093e83572..8a46157b058 100644 --- a/arch/arm/mach-h720x/include/mach/debug-macro.S +++ b/arch/arm/mach-h720x/include/mach/debug-macro.S @@ -16,7 +16,7 @@  		.equ    io_virt, IO_VIRT  		.equ    io_phys, IO_PHYS -		.macro  addruart, rp, rv +		.macro  addruart, rp, rv, tmp  		mov     \rp, #0x00020000	@ UART1  		add     \rv, \rp, #io_virt	@ virtual address  		add     \rp, \rp, #io_phys	@ physical base address diff --git a/arch/arm/mach-h720x/include/mach/memory.h b/arch/arm/mach-h720x/include/mach/memory.h deleted file mode 100644 index 96dcf50c51d..00000000000 --- a/arch/arm/mach-h720x/include/mach/memory.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * arch/arm/mach-h720x/include/mach/memory.h - * - * Copyright (c) 2000 Jungjun Kim - * - */ -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET	UL(0x40000000) -#endif diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c index ede2710f8b7..21525908394 100644 --- a/arch/arm/mach-imx/mach-armadillo5x0.c +++ b/arch/arm/mach-imx/mach-armadillo5x0.c @@ -558,7 +558,7 @@ static struct sys_timer armadillo5x0_timer = {  MACHINE_START(ARMADILLO5X0, "Armadillo-500")  	/* Maintainer: Alberto Panizzo  */ -	.boot_params = MX3x_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx31_map_io,  	.init_early = imx31_init_early,  	.init_irq = mx31_init_irq, diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c index f851fe90368..b1ec2cf53bb 100644 --- a/arch/arm/mach-imx/mach-cpuimx27.c +++ b/arch/arm/mach-imx/mach-cpuimx27.c @@ -311,7 +311,7 @@ static struct sys_timer eukrea_cpuimx27_timer = {  };  MACHINE_START(EUKREA_CPUIMX27, "EUKREA CPUIMX27") -	.boot_params = MX27_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx27_map_io,  	.init_early = imx27_init_early,  	.init_irq = mx27_init_irq, diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c index 4bd083ba9af..470b654b0e6 100644 --- a/arch/arm/mach-imx/mach-cpuimx35.c +++ b/arch/arm/mach-imx/mach-cpuimx35.c @@ -194,7 +194,7 @@ struct sys_timer eukrea_cpuimx35_timer = {  MACHINE_START(EUKREA_CPUIMX35SD, "Eukrea CPUIMX35")  	/* Maintainer: Eukrea Electromatique */ -	.boot_params = MX3x_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx35_map_io,  	.init_early = imx35_init_early,  	.init_irq = mx35_init_irq, diff --git a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c index 2442d5da883..9163318e95a 100644 --- a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c +++ b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c @@ -163,7 +163,7 @@ static struct sys_timer eukrea_cpuimx25_timer = {  MACHINE_START(EUKREA_CPUIMX25SD, "Eukrea CPUIMX25")  	/* Maintainer: Eukrea Electromatique */ -	.boot_params = MX25_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx25_map_io,  	.init_early = imx25_init_early,  	.init_irq = mx25_init_irq, diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index 6778f8193bc..22306ce2865 100644 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -275,7 +275,7 @@ static struct sys_timer visstrim_m10_timer = {  };  MACHINE_START(IMX27_VISSTRIM_M10, "Vista Silicon Visstrim_M10") -	.boot_params = MX27_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx27_map_io,  	.init_early = imx27_init_early,  	.init_irq = mx27_init_irq, diff --git a/arch/arm/mach-imx/mach-imx27ipcam.c b/arch/arm/mach-imx/mach-imx27ipcam.c index 272f793e924..8da48b33fc5 100644 --- a/arch/arm/mach-imx/mach-imx27ipcam.c +++ b/arch/arm/mach-imx/mach-imx27ipcam.c @@ -71,7 +71,7 @@ static struct sys_timer mx27ipcam_timer = {  MACHINE_START(IMX27IPCAM, "Freescale IMX27IPCAM")  	/* maintainer: Freescale Semiconductor, Inc. */ -	.boot_params = MX27_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx27_map_io,  	.init_early = imx27_init_early,  	.init_irq = mx27_init_irq, diff --git a/arch/arm/mach-imx/mach-imx27lite.c b/arch/arm/mach-imx/mach-imx27lite.c index d81a769fe89..21a14a20e2c 100644 --- a/arch/arm/mach-imx/mach-imx27lite.c +++ b/arch/arm/mach-imx/mach-imx27lite.c @@ -77,7 +77,7 @@ static struct sys_timer mx27lite_timer = {  };  MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE") -	.boot_params = MX27_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx27_map_io,  	.init_early = imx27_init_early,  	.init_irq = mx27_init_irq, diff --git a/arch/arm/mach-imx/mach-kzm_arm11_01.c b/arch/arm/mach-imx/mach-kzm_arm11_01.c index e472a1d8805..7c20e9e5800 100644 --- a/arch/arm/mach-imx/mach-kzm_arm11_01.c +++ b/arch/arm/mach-imx/mach-kzm_arm11_01.c @@ -271,7 +271,7 @@ static struct sys_timer kzm_timer = {  };  MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01") -	.boot_params = MX3x_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = kzm_map_io,  	.init_early = imx31_init_early,  	.init_irq = mx31_init_irq, diff --git a/arch/arm/mach-imx/mach-mx1ads.c b/arch/arm/mach-imx/mach-mx1ads.c index 5cd8bee4696..530ea08dbaf 100644 --- a/arch/arm/mach-imx/mach-mx1ads.c +++ b/arch/arm/mach-imx/mach-mx1ads.c @@ -145,7 +145,7 @@ struct sys_timer mx1ads_timer = {  MACHINE_START(MX1ADS, "Freescale MX1ADS")  	/* Maintainer: Sascha Hauer, Pengutronix */ -	.boot_params = MX1_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx1_map_io,  	.init_early = imx1_init_early,  	.init_irq = mx1_init_irq, @@ -154,7 +154,7 @@ MACHINE_START(MX1ADS, "Freescale MX1ADS")  MACHINE_END  MACHINE_START(MXLADS, "Freescale MXLADS") -	.boot_params = MX1_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx1_map_io,  	.init_early = imx1_init_early,  	.init_irq = mx1_init_irq, diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c index d389ecf9b5a..e56828da26b 100644 --- a/arch/arm/mach-imx/mach-mx21ads.c +++ b/arch/arm/mach-imx/mach-mx21ads.c @@ -305,7 +305,7 @@ static struct sys_timer mx21ads_timer = {  MACHINE_START(MX21ADS, "Freescale i.MX21ADS")  	/* maintainer: Freescale Semiconductor, Inc. */ -	.boot_params = MX21_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx21ads_map_io,  	.init_early = imx21_init_early,  	.init_irq = mx21_init_irq, diff --git a/arch/arm/mach-imx/mach-mx25_3ds.c b/arch/arm/mach-imx/mach-mx25_3ds.c index 7f66a91df36..dd25ee82e70 100644 --- a/arch/arm/mach-imx/mach-mx25_3ds.c +++ b/arch/arm/mach-imx/mach-mx25_3ds.c @@ -253,7 +253,7 @@ static struct sys_timer mx25pdk_timer = {  MACHINE_START(MX25_3DS, "Freescale MX25PDK (3DS)")  	/* Maintainer: Freescale Semiconductor, Inc. */ -	.boot_params = MX25_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx25_map_io,  	.init_early = imx25_init_early,  	.init_irq = mx25_init_irq, diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c index 6fa6934ab15..2eafbac2c76 100644 --- a/arch/arm/mach-imx/mach-mx27_3ds.c +++ b/arch/arm/mach-imx/mach-mx27_3ds.c @@ -421,7 +421,7 @@ static struct sys_timer mx27pdk_timer = {  MACHINE_START(MX27_3DS, "Freescale MX27PDK")  	/* maintainer: Freescale Semiconductor, Inc. */ -	.boot_params = MX27_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx27_map_io,  	.init_early = imx27_init_early,  	.init_irq = mx27_init_irq, diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c index e1addc1a581..635b0509068 100644 --- a/arch/arm/mach-imx/mach-mx27ads.c +++ b/arch/arm/mach-imx/mach-mx27ads.c @@ -344,7 +344,7 @@ static void __init mx27ads_map_io(void)  MACHINE_START(MX27ADS, "Freescale i.MX27ADS")  	/* maintainer: Freescale Semiconductor, Inc. */ -	.boot_params = MX27_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx27ads_map_io,  	.init_early = imx27_init_early,  	.init_irq = mx27_init_irq, diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c index c20be753092..589066fb331 100644 --- a/arch/arm/mach-imx/mach-mx31_3ds.c +++ b/arch/arm/mach-imx/mach-mx31_3ds.c @@ -764,7 +764,7 @@ static void __init mx31_3ds_reserve(void)  MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")  	/* Maintainer: Freescale Semiconductor, Inc. */ -	.boot_params = MX3x_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx31_map_io,  	.init_early = imx31_init_early,  	.init_irq = mx31_init_irq, diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c index 29ca8907a78..910c4561d35 100644 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ b/arch/arm/mach-imx/mach-mx31ads.c @@ -535,7 +535,7 @@ static struct sys_timer mx31ads_timer = {  MACHINE_START(MX31ADS, "Freescale MX31ADS")  	/* Maintainer: Freescale Semiconductor, Inc. */ -	.boot_params = MX3x_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx31ads_map_io,  	.init_early = imx31_init_early,  	.init_irq = mx31ads_init_irq, diff --git a/arch/arm/mach-imx/mach-mx31lilly.c b/arch/arm/mach-imx/mach-mx31lilly.c index 126913ad106..e92eaf91a7b 100644 --- a/arch/arm/mach-imx/mach-mx31lilly.c +++ b/arch/arm/mach-imx/mach-mx31lilly.c @@ -295,7 +295,7 @@ static struct sys_timer mx31lilly_timer = {  };  MACHINE_START(LILLY1131, "INCO startec LILLY-1131") -	.boot_params = MX3x_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx31_map_io,  	.init_early = imx31_init_early,  	.init_irq = mx31_init_irq, diff --git a/arch/arm/mach-imx/mach-mx31lite.c b/arch/arm/mach-imx/mach-mx31lite.c index 4b47fd9fdd8..5242cb78b56 100644 --- a/arch/arm/mach-imx/mach-mx31lite.c +++ b/arch/arm/mach-imx/mach-mx31lite.c @@ -280,7 +280,7 @@ struct sys_timer mx31lite_timer = {  MACHINE_START(MX31LITE, "LogicPD i.MX31 SOM")  	/* Maintainer: Freescale Semiconductor, Inc. */ -	.boot_params = MX3x_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx31lite_map_io,  	.init_early = imx31_init_early,  	.init_irq = mx31_init_irq, diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index b358383120e..1d01ef28f25 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c @@ -567,7 +567,7 @@ static void __init mx31moboard_reserve(void)  MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")  	/* Maintainer: Valentin Longchamp, EPFL Mobots group */ -	.boot_params = MX3x_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.reserve = mx31moboard_reserve,  	.map_io = mx31_map_io,  	.init_early = imx31_init_early, diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c index b3b9bd8ac2a..f2a873dc08c 100644 --- a/arch/arm/mach-imx/mach-mx35_3ds.c +++ b/arch/arm/mach-imx/mach-mx35_3ds.c @@ -217,7 +217,7 @@ struct sys_timer mx35pdk_timer = {  MACHINE_START(MX35_3DS, "Freescale MX35PDK")  	/* Maintainer: Freescale Semiconductor, Inc */ -	.boot_params = MX3x_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx35_map_io,  	.init_early = imx35_init_early,  	.init_irq = mx35_init_irq, diff --git a/arch/arm/mach-imx/mach-mxt_td60.c b/arch/arm/mach-imx/mach-mxt_td60.c index c85876fed66..5ec3989704f 100644 --- a/arch/arm/mach-imx/mach-mxt_td60.c +++ b/arch/arm/mach-imx/mach-mxt_td60.c @@ -267,7 +267,7 @@ static struct sys_timer mxt_td60_timer = {  MACHINE_START(MXT_TD60, "Maxtrack i-MXT TD60")  	/* maintainer: Maxtrack Industrial */ -	.boot_params = MX27_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx27_map_io,  	.init_early = imx27_init_early,  	.init_irq = mx27_init_irq, diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c index 71083aa1603..0f6bd119903 100644 --- a/arch/arm/mach-imx/mach-pca100.c +++ b/arch/arm/mach-imx/mach-pca100.c @@ -435,7 +435,7 @@ static struct sys_timer pca100_timer = {  };  MACHINE_START(PCA100, "phyCARD-i.MX27") -	.boot_params = MX27_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx27_map_io,  	.init_early = imx27_init_early,  	.init_irq = mx27_init_irq, diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c index f45b7cd72c8..186d4eb9079 100644 --- a/arch/arm/mach-imx/mach-pcm037.c +++ b/arch/arm/mach-imx/mach-pcm037.c @@ -688,7 +688,7 @@ static void __init pcm037_reserve(void)  MACHINE_START(PCM037, "Phytec Phycore pcm037")  	/* Maintainer: Pengutronix */ -	.boot_params = MX3x_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.reserve = pcm037_reserve,  	.map_io = mx31_map_io,  	.init_early = imx31_init_early, diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c index 2d6a64bbac4..091bcf87e1a 100644 --- a/arch/arm/mach-imx/mach-pcm038.c +++ b/arch/arm/mach-imx/mach-pcm038.c @@ -349,7 +349,7 @@ static struct sys_timer pcm038_timer = {  };  MACHINE_START(PCM038, "phyCORE-i.MX27") -	.boot_params = MX27_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx27_map_io,  	.init_early = imx27_init_early,  	.init_irq = mx27_init_irq, diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c index 660ec3e80cf..0a4d31de773 100644 --- a/arch/arm/mach-imx/mach-pcm043.c +++ b/arch/arm/mach-imx/mach-pcm043.c @@ -418,7 +418,7 @@ struct sys_timer pcm043_timer = {  MACHINE_START(PCM043, "Phytec Phycore pcm043")  	/* Maintainer: Pengutronix */ -	.boot_params = MX3x_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx35_map_io,  	.init_early = imx35_init_early,  	.init_irq = mx35_init_irq, diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c index 3626f486498..9e11359c324 100644 --- a/arch/arm/mach-imx/mach-qong.c +++ b/arch/arm/mach-imx/mach-qong.c @@ -262,7 +262,7 @@ static struct sys_timer qong_timer = {  MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")  	/* Maintainer: DENX Software Engineering GmbH */ -	.boot_params = MX3x_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx31_map_io,  	.init_early = imx31_init_early,  	.init_irq = mx31_init_irq, diff --git a/arch/arm/mach-imx/mach-scb9328.c b/arch/arm/mach-imx/mach-scb9328.c index db2d60470e1..85d32845ee1 100644 --- a/arch/arm/mach-imx/mach-scb9328.c +++ b/arch/arm/mach-imx/mach-scb9328.c @@ -137,7 +137,7 @@ static struct sys_timer scb9328_timer = {  MACHINE_START(SCB9328, "Synertronixx scb9328")  	/* Sascha Hauer */ -	.boot_params = 0x08000100, +	.atag_offset = 100,  	.map_io = mx1_map_io,  	.init_early = imx1_init_early,  	.init_irq = mx1_init_irq, diff --git a/arch/arm/mach-integrator/include/mach/debug-macro.S b/arch/arm/mach-integrator/include/mach/debug-macro.S index a1f598fd3a5..411b116077e 100644 --- a/arch/arm/mach-integrator/include/mach/debug-macro.S +++ b/arch/arm/mach-integrator/include/mach/debug-macro.S @@ -11,7 +11,7 @@   *  */ -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #0x16000000	@ physical base address  		mov	\rv, #0xf0000000	@ virtual base  		add	\rv, \rv, #0x16000000 >> 4 diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 8cdc730dcb3..a20fb3f2bc4 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -459,7 +459,7 @@ static struct sys_timer ap_timer = {  MACHINE_START(INTEGRATOR, "ARM-Integrator")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.reserve	= integrator_reserve,  	.map_io		= ap_map_io,  	.init_early	= integrator_init_early, diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 4eb03ab5cb4..5de49c33e4d 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -492,7 +492,7 @@ static struct sys_timer cp_timer = {  MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.reserve	= integrator_reserve,  	.map_io		= intcp_map_io,  	.init_early	= intcp_init_early, diff --git a/arch/arm/mach-iop13xx/include/mach/debug-macro.S b/arch/arm/mach-iop13xx/include/mach/debug-macro.S index e664466d51b..d869a6f67e5 100644 --- a/arch/arm/mach-iop13xx/include/mach/debug-macro.S +++ b/arch/arm/mach-iop13xx/include/mach/debug-macro.S @@ -11,7 +11,7 @@   * published by the Free Software Foundation.   */ -	.macro	addruart, rp, rv +	.macro	addruart, rp, rv, tmp  	mov	\rp, #0x00002300  	orr	\rp, \rp, #0x00000040  	orr	\rv, \rp, #0xfe000000	@ virtual diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c index 23dfaffc586..4cf2cc477ea 100644 --- a/arch/arm/mach-iop13xx/iq81340mc.c +++ b/arch/arm/mach-iop13xx/iq81340mc.c @@ -91,7 +91,7 @@ static struct sys_timer iq81340mc_timer = {  MACHINE_START(IQ81340MC, "Intel IQ81340MC")  	/* Maintainer: Dan Williams <dan.j.williams@intel.com> */ -	.boot_params    = 0x00000100, +	.atag_offset    = 0x100,  	.map_io         = iop13xx_map_io,  	.init_irq       = iop13xx_init_irq,  	.timer          = &iq81340mc_timer, diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c index df3492a9c28..cd9e27499a1 100644 --- a/arch/arm/mach-iop13xx/iq81340sc.c +++ b/arch/arm/mach-iop13xx/iq81340sc.c @@ -93,7 +93,7 @@ static struct sys_timer iq81340sc_timer = {  MACHINE_START(IQ81340SC, "Intel IQ81340SC")  	/* Maintainer: Dan Williams <dan.j.williams@intel.com> */ -	.boot_params    = 0x00000100, +	.atag_offset    = 0x100,  	.map_io         = iop13xx_map_io,  	.init_irq       = iop13xx_init_irq,  	.timer          = &iq81340sc_timer, diff --git a/arch/arm/mach-iop32x/em7210.c b/arch/arm/mach-iop32x/em7210.c index 6cbffbfc2bb..4325055d4e1 100644 --- a/arch/arm/mach-iop32x/em7210.c +++ b/arch/arm/mach-iop32x/em7210.c @@ -203,7 +203,7 @@ static void __init em7210_init_machine(void)  }  MACHINE_START(EM7210, "Lanner EM7210") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= em7210_map_io,  	.init_irq	= iop32x_init_irq,  	.timer		= &em7210_timer, diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c index ceef5d4dce1..0edc8802057 100644 --- a/arch/arm/mach-iop32x/glantank.c +++ b/arch/arm/mach-iop32x/glantank.c @@ -207,7 +207,7 @@ static void __init glantank_init_machine(void)  MACHINE_START(GLANTANK, "GLAN Tank")  	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= glantank_map_io,  	.init_irq	= iop32x_init_irq,  	.timer		= &glantank_timer, diff --git a/arch/arm/mach-iop32x/include/mach/debug-macro.S b/arch/arm/mach-iop32x/include/mach/debug-macro.S index ff9e76c09f3..363bdf90b34 100644 --- a/arch/arm/mach-iop32x/include/mach/debug-macro.S +++ b/arch/arm/mach-iop32x/include/mach/debug-macro.S @@ -11,7 +11,7 @@   * published by the Free Software Foundation.   */ -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #0xfe000000	@ physical as well as virtual  		orr	\rp, \rp, #0x00800000	@ location of the UART  		mov	\rv, \rp diff --git a/arch/arm/mach-iop32x/include/mach/memory.h b/arch/arm/mach-iop32x/include/mach/memory.h deleted file mode 100644 index 169cc239f76..00000000000 --- a/arch/arm/mach-iop32x/include/mach/memory.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-iop32x/include/mach/memory.h - */ - -#ifndef __MEMORY_H -#define __MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PLAT_PHYS_OFFSET	UL(0xa0000000) - -#endif diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c index 3a62514dae7..9e7aaccfeba 100644 --- a/arch/arm/mach-iop32x/iq31244.c +++ b/arch/arm/mach-iop32x/iq31244.c @@ -313,7 +313,7 @@ __setup("force_ep80219", force_ep80219_setup);  MACHINE_START(IQ31244, "Intel IQ31244")  	/* Maintainer: Intel Corp. */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= iq31244_map_io,  	.init_irq	= iop32x_init_irq,  	.timer		= &iq31244_timer, @@ -327,7 +327,7 @@ MACHINE_END   */  MACHINE_START(EP80219, "Intel EP80219")  	/* Maintainer: Intel Corp. */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= iq31244_map_io,  	.init_irq	= iop32x_init_irq,  	.timer		= &iq31244_timer, diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c index 35b7e6914d3..53ea86f649d 100644 --- a/arch/arm/mach-iop32x/iq80321.c +++ b/arch/arm/mach-iop32x/iq80321.c @@ -186,7 +186,7 @@ static void __init iq80321_init_machine(void)  MACHINE_START(IQ80321, "Intel IQ80321")  	/* Maintainer: Intel Corp. */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= iq80321_map_io,  	.init_irq	= iop32x_init_irq,  	.timer		= &iq80321_timer, diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c index 1a374eab600..d7269279968 100644 --- a/arch/arm/mach-iop32x/n2100.c +++ b/arch/arm/mach-iop32x/n2100.c @@ -327,7 +327,7 @@ static void __init n2100_init_machine(void)  MACHINE_START(N2100, "Thecus N2100")  	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= n2100_map_io,  	.init_irq	= iop32x_init_irq,  	.timer		= &n2100_timer, diff --git a/arch/arm/mach-iop33x/include/mach/debug-macro.S b/arch/arm/mach-iop33x/include/mach/debug-macro.S index 40c500dd1fa..361be1f6026 100644 --- a/arch/arm/mach-iop33x/include/mach/debug-macro.S +++ b/arch/arm/mach-iop33x/include/mach/debug-macro.S @@ -11,7 +11,7 @@   * published by the Free Software Foundation.   */ -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #0x00ff0000  		orr	\rp, \rp, #0x0000f700  		orr	\rv, #0xfe000000	@ virtual diff --git a/arch/arm/mach-iop33x/include/mach/memory.h b/arch/arm/mach-iop33x/include/mach/memory.h deleted file mode 100644 index 8e1daf7006b..00000000000 --- a/arch/arm/mach-iop33x/include/mach/memory.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-iop33x/include/mach/memory.h - */ - -#ifndef __MEMORY_H -#define __MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PLAT_PHYS_OFFSET	UL(0x00000000) - -#endif diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c index 637c0272d5e..9e14ccc56f8 100644 --- a/arch/arm/mach-iop33x/iq80331.c +++ b/arch/arm/mach-iop33x/iq80331.c @@ -141,7 +141,7 @@ static void __init iq80331_init_machine(void)  MACHINE_START(IQ80331, "Intel IQ80331")  	/* Maintainer: Intel Corp. */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= iop3xx_map_io,  	.init_irq	= iop33x_init_irq,  	.timer		= &iq80331_timer, diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c index 90a0436d725..09c899a2523 100644 --- a/arch/arm/mach-iop33x/iq80332.c +++ b/arch/arm/mach-iop33x/iq80332.c @@ -141,7 +141,7 @@ static void __init iq80332_init_machine(void)  MACHINE_START(IQ80332, "Intel IQ80332")  	/* Maintainer: Intel Corp. */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= iop3xx_map_io,  	.init_irq	= iop33x_init_irq,  	.timer		= &iq80332_timer, diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index 62c60ade527..af9994537e0 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c @@ -254,7 +254,7 @@ static void __init enp2611_init_machine(void)  MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board")  	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= enp2611_map_io,  	.init_irq	= ixp2000_init_irq,  	.timer		= &enp2611_timer, diff --git a/arch/arm/mach-ixp2000/include/mach/debug-macro.S b/arch/arm/mach-ixp2000/include/mach/debug-macro.S index 0ef533b2097..bdd3ccdc289 100644 --- a/arch/arm/mach-ixp2000/include/mach/debug-macro.S +++ b/arch/arm/mach-ixp2000/include/mach/debug-macro.S @@ -11,7 +11,7 @@   *  */ -		.macro  addruart, rp, rv +		.macro  addruart, rp, rv, tmp  		mov	\rp, #0x00030000  #ifdef	__ARMEB__  		orr	\rp, \rp, #0x00000003 diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index 5bad1a8419b..f7dfd970014 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c @@ -171,7 +171,7 @@ void __init ixdp2400_init_irq(void)  MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform")  	/* Maintainer: MontaVista Software, Inc. */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= ixdp2x00_map_io,  	.init_irq	= ixdp2400_init_irq,  	.timer		= &ixdp2400_timer, diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index 3d3cef87646..d33bcac1ec9 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c @@ -286,7 +286,7 @@ void __init ixdp2800_init_irq(void)  MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform")  	/* Maintainer: MontaVista Software, Inc. */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= ixdp2x00_map_io,  	.init_irq	= ixdp2800_init_irq,  	.timer		= &ixdp2800_timer, diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index be2a254f137..61a28676b5b 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -417,7 +417,7 @@ static void __init ixdp2x01_init_machine(void)  #ifdef CONFIG_ARCH_IXDP2401  MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform")  	/* Maintainer: MontaVista Software, Inc. */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= ixdp2x01_map_io,  	.init_irq	= ixdp2x01_init_irq,  	.timer		= &ixdp2x01_timer, @@ -428,7 +428,7 @@ MACHINE_END  #ifdef CONFIG_ARCH_IXDP2801  MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform")  	/* Maintainer: MontaVista Software, Inc. */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= ixdp2x01_map_io,  	.init_irq	= ixdp2x01_init_irq,  	.timer		= &ixdp2x01_timer, @@ -441,7 +441,7 @@ MACHINE_END   */  MACHINE_START(IXDP28X5, "Intel IXDP2805/2855 Development Platform")  	/* Maintainer: MontaVista Software, Inc. */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= ixdp2x01_map_io,  	.init_irq	= ixdp2x01_init_irq,  	.timer		= &ixdp2x01_timer, diff --git a/arch/arm/mach-ixp23xx/espresso.c b/arch/arm/mach-ixp23xx/espresso.c index e25e5fe183b..30dd31652e9 100644 --- a/arch/arm/mach-ixp23xx/espresso.c +++ b/arch/arm/mach-ixp23xx/espresso.c @@ -88,6 +88,6 @@ MACHINE_START(ESPRESSO, "IP Fabrics Double Espresso")  	.map_io		= ixp23xx_map_io,  	.init_irq	= ixp23xx_init_irq,  	.timer		= &ixp23xx_timer, -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= espresso_init,  MACHINE_END diff --git a/arch/arm/mach-ixp23xx/include/mach/debug-macro.S b/arch/arm/mach-ixp23xx/include/mach/debug-macro.S index f7c6eef7fa2..5ff524c1374 100644 --- a/arch/arm/mach-ixp23xx/include/mach/debug-macro.S +++ b/arch/arm/mach-ixp23xx/include/mach/debug-macro.S @@ -12,7 +12,7 @@   */  #include <mach/ixp23xx.h> -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		ldr	\rp, =IXP23XX_PERIPHERAL_PHYS 	@ physical  		ldr	\rv, =IXP23XX_PERIPHERAL_VIRT	@ virtual  #ifdef __ARMEB__ diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c index ec028e35f40..b3a57e0f341 100644 --- a/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/arch/arm/mach-ixp23xx/ixdp2351.c @@ -331,6 +331,6 @@ MACHINE_START(IXDP2351, "Intel IXDP2351 Development Platform")  	.map_io		= ixdp2351_map_io,  	.init_irq	= ixdp2351_init_irq,  	.timer		= &ixp23xx_timer, -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= ixdp2351_init,  MACHINE_END diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c index 844551d2368..8f4dcbba902 100644 --- a/arch/arm/mach-ixp23xx/roadrunner.c +++ b/arch/arm/mach-ixp23xx/roadrunner.c @@ -175,6 +175,6 @@ MACHINE_START(ROADRUNNER, "ADI Engineering RoadRunner Development Platform")  	.map_io		= ixp23xx_map_io,  	.init_irq	= ixp23xx_init_irq,  	.timer		= &ixp23xx_timer, -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= roadrunner_init,  MACHINE_END diff --git a/arch/arm/mach-ixp4xx/avila-setup.c b/arch/arm/mach-ixp4xx/avila-setup.c index ee19c1d383a..37609a22c45 100644 --- a/arch/arm/mach-ixp4xx/avila-setup.c +++ b/arch/arm/mach-ixp4xx/avila-setup.c @@ -167,7 +167,7 @@ MACHINE_START(AVILA, "Gateworks Avila Network Platform")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= avila_init,  #if defined(CONFIG_PCI)  	.dma_zone_size	= SZ_64M, @@ -185,7 +185,7 @@ MACHINE_START(LOFT, "Giant Shoulder Inc Loft board")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= avila_init,  #if defined(CONFIG_PCI)  	.dma_zone_size	= SZ_64M, diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c index e24564b5d93..81dfec31842 100644 --- a/arch/arm/mach-ixp4xx/coyote-setup.c +++ b/arch/arm/mach-ixp4xx/coyote-setup.c @@ -112,7 +112,7 @@ MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= coyote_init,  #if defined(CONFIG_PCI)  	.dma_zone_size	= SZ_64M, @@ -130,7 +130,7 @@ MACHINE_START(IXDPG425, "Intel IXDPG425")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= coyote_init,  MACHINE_END  #endif diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c index 96e37834580..8837fbca27c 100644 --- a/arch/arm/mach-ixp4xx/dsmg600-setup.c +++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c @@ -278,7 +278,7 @@ static void __init dsmg600_init(void)  MACHINE_START(DSMG600, "D-Link DSM-G600 RevA")  	/* Maintainer: www.nslu2-linux.org */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer          = &dsmg600_timer, diff --git a/arch/arm/mach-ixp4xx/fsg-setup.c b/arch/arm/mach-ixp4xx/fsg-setup.c index 72333a03943..2887c3578c1 100644 --- a/arch/arm/mach-ixp4xx/fsg-setup.c +++ b/arch/arm/mach-ixp4xx/fsg-setup.c @@ -272,7 +272,7 @@ MACHINE_START(FSG, "Freecom FSG-3")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= fsg_init,  #if defined(CONFIG_PCI)  	.dma_zone_size	= SZ_64M, diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c index d4f851bdd9a..d69d1b053bb 100644 --- a/arch/arm/mach-ixp4xx/gateway7001-setup.c +++ b/arch/arm/mach-ixp4xx/gateway7001-setup.c @@ -99,7 +99,7 @@ MACHINE_START(GATEWAY7001, "Gateway 7001 AP")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= gateway7001_init,  #if defined(CONFIG_PCI)  	.dma_zone_size	= SZ_64M, diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c index 7548d9a2efe..bf6678d1a92 100644 --- a/arch/arm/mach-ixp4xx/goramo_mlr.c +++ b/arch/arm/mach-ixp4xx/goramo_mlr.c @@ -499,7 +499,7 @@ MACHINE_START(GORAMO_MLR, "MultiLink")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= gmlr_init,  #if defined(CONFIG_PCI)  	.dma_zone_size	= SZ_64M, diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c index 3790dffd3c3..aa029fc1914 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c @@ -167,7 +167,7 @@ MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= gtwx5715_init,  #if defined(CONFIG_PCI)  	.dma_zone_size	= SZ_64M, diff --git a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S index b974a49c0af..8c9f8d56449 100644 --- a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S +++ b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S @@ -10,7 +10,7 @@   * published by the Free Software Foundation.  */ -                .macro  addruart, rp, rv +                .macro  addruart, rp, rv, tmp  #ifdef __ARMEB__                  mov     \rp, #3         @ Uart regs are at off set of 3 if  					@ byte writes used - Big Endian. diff --git a/arch/arm/mach-ixp4xx/include/mach/memory.h b/arch/arm/mach-ixp4xx/include/mach/memory.h deleted file mode 100644 index 4caf1761f1e..00000000000 --- a/arch/arm/mach-ixp4xx/include/mach/memory.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/arm/mach-ixp4xx/include/mach/memory.h - * - * Copyright (c) 2001-2004 MontaVista Software, Inc. - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#include <asm/sizes.h> - -/* - * Physical DRAM offset. - */ -#define PLAT_PHYS_OFFSET	UL(0x00000000) - -#endif diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index 6a2927956bf..f235f829dfa 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -256,7 +256,7 @@ MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= ixdp425_init,  #if defined(CONFIG_PCI)  	.dma_zone_size	= SZ_64M, @@ -270,7 +270,7 @@ MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= ixdp425_init,  #if defined(CONFIG_PCI)  	.dma_zone_size	= SZ_64M, @@ -284,7 +284,7 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= ixdp425_init,  #if defined(CONFIG_PCI)  	.dma_zone_size	= SZ_64M, @@ -298,7 +298,7 @@ MACHINE_START(KIXRP435, "Intel KIXRP435 Reference Platform")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= ixdp425_init,  #if defined(CONFIG_PCI)  	.dma_zone_size	= SZ_64M, diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c index b752fa4d692..de716fa1aab 100644 --- a/arch/arm/mach-ixp4xx/nas100d-setup.c +++ b/arch/arm/mach-ixp4xx/nas100d-setup.c @@ -313,7 +313,7 @@ static void __init nas100d_init(void)  MACHINE_START(NAS100D, "Iomega NAS 100d")  	/* Maintainer: www.nslu2-linux.org */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer          = &ixp4xx_timer, diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c index 0411a0a0107..ac81ccb26bf 100644 --- a/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/arch/arm/mach-ixp4xx/nslu2-setup.c @@ -299,7 +299,7 @@ static void __init nslu2_init(void)  MACHINE_START(NSLU2, "Linksys NSLU2")  	/* Maintainer: www.nslu2-linux.org */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer          = &nslu2_timer, diff --git a/arch/arm/mach-ixp4xx/vulcan-setup.c b/arch/arm/mach-ixp4xx/vulcan-setup.c index 045336c833a..27e469ef452 100644 --- a/arch/arm/mach-ixp4xx/vulcan-setup.c +++ b/arch/arm/mach-ixp4xx/vulcan-setup.c @@ -239,7 +239,7 @@ MACHINE_START(ARCOM_VULCAN, "Arcom/Eurotech Vulcan")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= vulcan_init,  #if defined(CONFIG_PCI)  	.dma_zone_size	= SZ_64M, diff --git a/arch/arm/mach-ixp4xx/wg302v2-setup.c b/arch/arm/mach-ixp4xx/wg302v2-setup.c index 40b9fad800b..b14144b967a 100644 --- a/arch/arm/mach-ixp4xx/wg302v2-setup.c +++ b/arch/arm/mach-ixp4xx/wg302v2-setup.c @@ -100,7 +100,7 @@ MACHINE_START(WG302V2, "Netgear WG302 v2 / WAG302 v2")  	.map_io		= ixp4xx_map_io,  	.init_irq	= ixp4xx_init_irq,  	.timer		= &ixp4xx_timer, -	.boot_params	= 0x0100, +	.atag_offset	= 0x100,  	.init_machine	= wg302v2_init,  #if defined(CONFIG_PCI)  	.dma_zone_size	= SZ_64M, diff --git a/arch/arm/mach-kirkwood/d2net_v2-setup.c b/arch/arm/mach-kirkwood/d2net_v2-setup.c index 043cfd5e140..f457e07a65f 100644 --- a/arch/arm/mach-kirkwood/d2net_v2-setup.c +++ b/arch/arm/mach-kirkwood/d2net_v2-setup.c @@ -221,7 +221,7 @@ static void __init d2net_v2_init(void)  }  MACHINE_START(D2NET_V2, "LaCie d2 Network v2") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= d2net_v2_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c index bff04e04d67..ff4c21c1f92 100644 --- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c +++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c @@ -97,7 +97,7 @@ subsys_initcall(db88f6281_pci_init);  MACHINE_START(DB88F6281_BP, "Marvell DB-88F6281-BP Development Board")  	/* Maintainer: Saeed Bishara <saeed@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= db88f6281_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-kirkwood/dockstar-setup.c b/arch/arm/mach-kirkwood/dockstar-setup.c index f14dfb8508c..e4d199b2b1e 100644 --- a/arch/arm/mach-kirkwood/dockstar-setup.c +++ b/arch/arm/mach-kirkwood/dockstar-setup.c @@ -102,7 +102,7 @@ static void __init dockstar_init(void)  }  MACHINE_START(DOCKSTAR, "Seagate FreeAgent DockStar") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= dockstar_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-kirkwood/guruplug-setup.c b/arch/arm/mach-kirkwood/guruplug-setup.c index 41d1b40696a..6c40f784b51 100644 --- a/arch/arm/mach-kirkwood/guruplug-setup.c +++ b/arch/arm/mach-kirkwood/guruplug-setup.c @@ -121,7 +121,7 @@ static void __init guruplug_init(void)  MACHINE_START(GURUPLUG, "Marvell GuruPlug Reference Board")  	/* Maintainer: Siddarth Gore <gores@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= guruplug_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-kirkwood/include/mach/debug-macro.S b/arch/arm/mach-kirkwood/include/mach/debug-macro.S index db06ae437d0..f785d401a60 100644 --- a/arch/arm/mach-kirkwood/include/mach/debug-macro.S +++ b/arch/arm/mach-kirkwood/include/mach/debug-macro.S @@ -8,7 +8,7 @@  #include <mach/bridge-regs.h> -	.macro	addruart, rp, rv +	.macro	addruart, rp, rv, tmp  	ldr	\rp, =KIRKWOOD_REGS_PHYS_BASE  	ldr	\rv, =KIRKWOOD_REGS_VIRT_BASE  	orr	\rp, \rp, #0x00012000 diff --git a/arch/arm/mach-kirkwood/include/mach/memory.h b/arch/arm/mach-kirkwood/include/mach/memory.h deleted file mode 100644 index 4600b44e3ad..00000000000 --- a/arch/arm/mach-kirkwood/include/mach/memory.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * arch/arm/mach-kirkwood/include/mach/memory.h - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET		UL(0x00000000) - -#endif diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c index 00cca22eca6..9a1e917352f 100644 --- a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c +++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c @@ -163,7 +163,7 @@ subsys_initcall(mv88f6281gtw_ge_pci_init);  MACHINE_START(MV88F6281GTW_GE, "Marvell 88F6281 GTW GE Board")  	/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= mv88f6281gtw_ge_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-kirkwood/netspace_v2-setup.c b/arch/arm/mach-kirkwood/netspace_v2-setup.c index 7cdab577645..8849bcc7328 100644 --- a/arch/arm/mach-kirkwood/netspace_v2-setup.c +++ b/arch/arm/mach-kirkwood/netspace_v2-setup.c @@ -258,7 +258,7 @@ static void __init netspace_v2_init(void)  #ifdef CONFIG_MACH_NETSPACE_V2  MACHINE_START(NETSPACE_V2, "LaCie Network Space v2") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= netspace_v2_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, @@ -269,7 +269,7 @@ MACHINE_END  #ifdef CONFIG_MACH_INETSPACE_V2  MACHINE_START(INETSPACE_V2, "LaCie Internet Space v2") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= netspace_v2_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, @@ -280,7 +280,7 @@ MACHINE_END  #ifdef CONFIG_MACH_NETSPACE_MAX_V2  MACHINE_START(NETSPACE_MAX_V2, "LaCie Network Space Max v2") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= netspace_v2_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-kirkwood/netxbig_v2-setup.c b/arch/arm/mach-kirkwood/netxbig_v2-setup.c index 6be627deb0f..1ba12c4dff8 100644 --- a/arch/arm/mach-kirkwood/netxbig_v2-setup.c +++ b/arch/arm/mach-kirkwood/netxbig_v2-setup.c @@ -399,7 +399,7 @@ static void __init netxbig_v2_init(void)  #ifdef CONFIG_MACH_NET2BIG_V2  MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= netxbig_v2_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, @@ -410,7 +410,7 @@ MACHINE_END  #ifdef CONFIG_MACH_NET5BIG_V2  MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= netxbig_v2_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c index f69beeff445..5660ca6c3d8 100644 --- a/arch/arm/mach-kirkwood/openrd-setup.c +++ b/arch/arm/mach-kirkwood/openrd-setup.c @@ -214,7 +214,7 @@ subsys_initcall(openrd_pci_init);  #ifdef CONFIG_MACH_OPENRD_BASE  MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board")  	/* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= openrd_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, @@ -226,7 +226,7 @@ MACHINE_END  #ifdef CONFIG_MACH_OPENRD_CLIENT  MACHINE_START(OPENRD_CLIENT, "Marvell OpenRD Client Board")  	/* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= openrd_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, @@ -238,7 +238,7 @@ MACHINE_END  #ifdef CONFIG_MACH_OPENRD_ULTIMATE  MACHINE_START(OPENRD_ULTIMATE, "Marvell OpenRD Ultimate Board")  	/* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= openrd_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c index 75c6601b8d8..6663869773a 100644 --- a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c +++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c @@ -79,7 +79,7 @@ subsys_initcall(rd88f6192_pci_init);  MACHINE_START(RD88F6192_NAS, "Marvell RD-88F6192-NAS Development Board")  	/* Maintainer: Saeed Bishara <saeed@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= rd88f6192_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c index 0f75494d590..66b3c05e37a 100644 --- a/arch/arm/mach-kirkwood/rd88f6281-setup.c +++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c @@ -115,7 +115,7 @@ subsys_initcall(rd88f6281_pci_init);  MACHINE_START(RD88F6281, "Marvell RD-88F6281 Reference Board")  	/* Maintainer: Saeed Bishara <saeed@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= rd88f6281_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-kirkwood/sheevaplug-setup.c b/arch/arm/mach-kirkwood/sheevaplug-setup.c index 17de0bf53c0..8b102d62e82 100644 --- a/arch/arm/mach-kirkwood/sheevaplug-setup.c +++ b/arch/arm/mach-kirkwood/sheevaplug-setup.c @@ -138,7 +138,7 @@ static void __init sheevaplug_init(void)  #ifdef CONFIG_MACH_SHEEVAPLUG  MACHINE_START(SHEEVAPLUG, "Marvell SheevaPlug Reference Board")  	/* Maintainer: shadi Ammouri <shadi@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= sheevaplug_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, @@ -149,7 +149,7 @@ MACHINE_END  #ifdef CONFIG_MACH_ESATA_SHEEVAPLUG  MACHINE_START(ESATA_SHEEVAPLUG, "Marvell eSATA SheevaPlug Reference Board") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= sheevaplug_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-kirkwood/t5325-setup.c b/arch/arm/mach-kirkwood/t5325-setup.c index e6b9b1b22a3..ea104fb5ec3 100644 --- a/arch/arm/mach-kirkwood/t5325-setup.c +++ b/arch/arm/mach-kirkwood/t5325-setup.c @@ -201,7 +201,7 @@ subsys_initcall(hp_t5325_pci_init);  MACHINE_START(T5325, "HP t5325 Thin Client")  	/* Maintainer: Martin Michlmayr <tbm@cyrius.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= hp_t5325_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c index 68f32f2bf55..262c034836d 100644 --- a/arch/arm/mach-kirkwood/ts219-setup.c +++ b/arch/arm/mach-kirkwood/ts219-setup.c @@ -132,7 +132,7 @@ subsys_initcall(ts219_pci_init);  MACHINE_START(TS219, "QNAP TS-119/TS-219")  	/* Maintainer: Martin Michlmayr <tbm@cyrius.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= qnap_ts219_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c index d5d00997070..b68f5b4a9ec 100644 --- a/arch/arm/mach-kirkwood/ts41x-setup.c +++ b/arch/arm/mach-kirkwood/ts41x-setup.c @@ -176,7 +176,7 @@ subsys_initcall(ts41x_pci_init);  MACHINE_START(TS41X, "QNAP TS-41x")  	/* Maintainer: Martin Michlmayr <tbm@cyrius.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= qnap_ts41x_init,  	.map_io		= kirkwood_map_io,  	.init_early	= kirkwood_init_early, diff --git a/arch/arm/mach-ks8695/board-acs5k.c b/arch/arm/mach-ks8695/board-acs5k.c index 3d7d11436aa..a91f99d265a 100644 --- a/arch/arm/mach-ks8695/board-acs5k.c +++ b/arch/arm/mach-ks8695/board-acs5k.c @@ -223,7 +223,7 @@ static void __init acs5k_init(void)  MACHINE_START(ACS5K, "Brivo Systems LLC ACS-5000 Master board")  	/* Maintainer: Simtec Electronics. */ -	.boot_params	= KS8695_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ks8695_map_io,  	.init_irq	= ks8695_init_irq,  	.init_machine	= acs5k_init, diff --git a/arch/arm/mach-ks8695/board-dsm320.c b/arch/arm/mach-ks8695/board-dsm320.c index c3c867ac415..d24bcef2e2d 100644 --- a/arch/arm/mach-ks8695/board-dsm320.c +++ b/arch/arm/mach-ks8695/board-dsm320.c @@ -121,7 +121,7 @@ static void __init dsm320_init(void)  MACHINE_START(DSM320, "D-Link DSM-320 Wireless Media Player")  	/* Maintainer: Simtec Electronics. */ -	.boot_params	= KS8695_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ks8695_map_io,  	.init_irq	= ks8695_init_irq,  	.init_machine	= dsm320_init, diff --git a/arch/arm/mach-ks8695/board-micrel.c b/arch/arm/mach-ks8695/board-micrel.c index 9b9c47cc647..16c95657f8f 100644 --- a/arch/arm/mach-ks8695/board-micrel.c +++ b/arch/arm/mach-ks8695/board-micrel.c @@ -53,7 +53,7 @@ static void __init micrel_init(void)  MACHINE_START(KS8695, "KS8695 Centaur Development Board")  	/* Maintainer: Micrel Semiconductor Inc. */ -	.boot_params	= KS8695_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= ks8695_map_io,  	.init_irq	= ks8695_init_irq,  	.init_machine	= micrel_init, diff --git a/arch/arm/mach-ks8695/include/mach/debug-macro.S b/arch/arm/mach-ks8695/include/mach/debug-macro.S index bf516adf192..a79e4898120 100644 --- a/arch/arm/mach-ks8695/include/mach/debug-macro.S +++ b/arch/arm/mach-ks8695/include/mach/debug-macro.S @@ -14,7 +14,7 @@  #include <mach/hardware.h>  #include <mach/regs-uart.h> -	.macro	addruart, rp, rv +	.macro	addruart, rp, rv, tmp  		ldr	\rp, =KS8695_UART_PA		@ physical base address  		ldr	\rv, =KS8695_UART_VA		@ virtual base address  	.endm diff --git a/arch/arm/mach-l7200/include/mach/debug-macro.S b/arch/arm/mach-l7200/include/mach/debug-macro.S index b0a2db77d39..0b4e760159b 100644 --- a/arch/arm/mach-l7200/include/mach/debug-macro.S +++ b/arch/arm/mach-l7200/include/mach/debug-macro.S @@ -14,7 +14,7 @@  		.equ	io_virt, IO_BASE  		.equ	io_phys, IO_START -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #0x00044000	@ UART1  @		mov	\rp, #0x00045000	@ UART2  		add	\rv, \rp, #io_virt	@ virtual address diff --git a/arch/arm/mach-lpc32xx/include/mach/debug-macro.S b/arch/arm/mach-lpc32xx/include/mach/debug-macro.S index 629e744aeb9..351bd6c8490 100644 --- a/arch/arm/mach-lpc32xx/include/mach/debug-macro.S +++ b/arch/arm/mach-lpc32xx/include/mach/debug-macro.S @@ -20,7 +20,7 @@   * Debug output is hardcoded to standard UART 5  */ -	.macro	addruart, rp, rv +	.macro	addruart, rp, rv, tmp  	ldreq	\rp, =0x40090000  	ldrne	\rv, =0xF4090000  	.endm diff --git a/arch/arm/mach-lpc32xx/include/mach/memory.h b/arch/arm/mach-lpc32xx/include/mach/memory.h deleted file mode 100644 index a647dd624af..00000000000 --- a/arch/arm/mach-lpc32xx/include/mach/memory.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/mach-lpc32xx/include/mach/memory.h - * - * Author: Kevin Wells <kevin.wells@nxp.com> - * - * Copyright (C) 2010 NXP Semiconductors - * - * 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. - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset of bank 0 - */ -#define PLAT_PHYS_OFFSET	UL(0x80000000) - -#endif diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index c3a22fd736a..6d2f0d1b937 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -383,7 +383,7 @@ arch_initcall(lpc32xx_display_uid);  MACHINE_START(PHY3250, "Phytec 3250 board with the LPC3250 Microcontroller")  	/* Maintainer: Kevin Wells, NXP Semiconductors */ -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.map_io		= lpc32xx_map_io,  	.init_irq	= lpc32xx_init_irq,  	.timer		= &lpc32xx_timer, diff --git a/arch/arm/mach-mmp/include/mach/debug-macro.S b/arch/arm/mach-mmp/include/mach/debug-macro.S index 7e2ebd3efc7..b6f14d203c2 100644 --- a/arch/arm/mach-mmp/include/mach/debug-macro.S +++ b/arch/arm/mach-mmp/include/mach/debug-macro.S @@ -11,7 +11,7 @@  #include <mach/addr-map.h> -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		ldr	\rp, =APB_PHYS_BASE		@ physical  		ldr	\rv, =APB_VIRT_BASE		@ virtual  		orr	\rp, \rp, #0x00017000 diff --git a/arch/arm/mach-mmp/include/mach/memory.h b/arch/arm/mach-mmp/include/mach/memory.h deleted file mode 100644 index d68b50a2d6a..00000000000 --- a/arch/arm/mach-mmp/include/mach/memory.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * linux/arch/arm/mach-mmp/include/mach/memory.h - * - * 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_MACH_MEMORY_H -#define __ASM_MACH_MEMORY_H - -#define PLAT_PHYS_OFFSET	UL(0x00000000) - -#endif /* __ASM_MACH_MEMORY_H */ diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index 18a3c97bc86..16c86f8b4f3 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c @@ -93,7 +93,7 @@ static void __init halibut_map_io(void)  }  MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.fixup		= halibut_fixup,  	.map_io		= halibut_map_io,  	.init_irq	= halibut_init_irq, diff --git a/arch/arm/mach-msm/board-mahimahi.c b/arch/arm/mach-msm/board-mahimahi.c index 7a9a03eb189..8a1672ee4e4 100644 --- a/arch/arm/mach-msm/board-mahimahi.c +++ b/arch/arm/mach-msm/board-mahimahi.c @@ -74,7 +74,7 @@ static void __init mahimahi_map_io(void)  extern struct sys_timer msm_timer;  MACHINE_START(MAHIMAHI, "mahimahi") -	.boot_params	= 0x20000100, +	.atag_offset	= 0x100,  	.fixup		= mahimahi_fixup,  	.map_io		= mahimahi_map_io,  	.init_irq	= msm_init_irq, diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c index 1a313e10c68..6d84ee740df 100644 --- a/arch/arm/mach-msm/board-msm7x27.c +++ b/arch/arm/mach-msm/board-msm7x27.c @@ -129,7 +129,7 @@ static void __init msm7x2x_map_io(void)  }  MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF") -	.boot_params	= PLAT_PHYS_OFFSET + 0x100, +	.atag_offset	= 0x100,  	.map_io		= msm7x2x_map_io,  	.init_irq	= msm7x2x_init_irq,  	.init_machine	= msm7x2x_init, @@ -137,7 +137,7 @@ MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF")  MACHINE_END  MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA") -	.boot_params	= PLAT_PHYS_OFFSET + 0x100, +	.atag_offset	= 0x100,  	.map_io		= msm7x2x_map_io,  	.init_irq	= msm7x2x_init_irq,  	.init_machine	= msm7x2x_init, @@ -145,7 +145,7 @@ MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA")  MACHINE_END  MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF") -	.boot_params	= PLAT_PHYS_OFFSET + 0x100, +	.atag_offset	= 0x100,  	.map_io		= msm7x2x_map_io,  	.init_irq	= msm7x2x_init_irq,  	.init_machine	= msm7x2x_init, @@ -153,7 +153,7 @@ MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF")  MACHINE_END  MACHINE_START(MSM7X25_FFA, "QCT MSM7x25 FFA") -	.boot_params	= PLAT_PHYS_OFFSET + 0x100, +	.atag_offset	= 0x100,  	.map_io		= msm7x2x_map_io,  	.init_irq	= msm7x2x_init_irq,  	.init_machine	= msm7x2x_init, diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c index 92afaf6583e..71de5062c71 100644 --- a/arch/arm/mach-msm/board-msm7x30.c +++ b/arch/arm/mach-msm/board-msm7x30.c @@ -24,6 +24,7 @@  #include <linux/smsc911x.h>  #include <linux/usb/msm_hsusb.h>  #include <linux/clkdev.h> +#include <linux/memblock.h>  #include <asm/mach-types.h>  #include <asm/mach/arch.h> @@ -41,6 +42,21 @@  extern struct sys_timer msm_timer; +static void __init msm7x30_fixup(struct machine_desc *desc, struct tag *tag, +			 char **cmdline, struct meminfo *mi) +{ +	for (; tag->hdr.size; tag = tag_next(tag)) +		if (tag->hdr.tag == ATAG_MEM && tag->u.mem.start == 0x200000) { +			tag->u.mem.start = 0; +			tag->u.mem.size += SZ_2M; +		} +} + +static void __init msm7x30_reserve(void) +{ +	memblock_remove(0x0, SZ_2M); +} +  static int hsusb_phy_init_seq[] = {  	0x30, 0x32,	/* Enable and set Pre-Emphasis Depth to 20% */  	0x02, 0x36,	/* Disable CDR Auto Reset feature */ @@ -105,7 +121,9 @@ static void __init msm7x30_map_io(void)  }  MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF") -	.boot_params = PLAT_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100, +	.fixup = msm7x30_fixup, +	.reserve = msm7x30_reserve,  	.map_io = msm7x30_map_io,  	.init_irq = msm7x30_init_irq,  	.init_machine = msm7x30_init, @@ -113,7 +131,9 @@ MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")  MACHINE_END  MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA") -	.boot_params = PLAT_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100, +	.fixup = msm7x30_fixup, +	.reserve = msm7x30_reserve,  	.map_io = msm7x30_map_io,  	.init_irq = msm7x30_init_irq,  	.init_machine = msm7x30_init, @@ -121,7 +141,9 @@ MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")  MACHINE_END  MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID") -	.boot_params = PLAT_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100, +	.fixup = msm7x30_fixup, +	.reserve = msm7x30_reserve,  	.map_io = msm7x30_map_io,  	.init_irq = msm7x30_init_irq,  	.init_machine = msm7x30_init, diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c index 35c7ceeb3f2..b04468e7d00 100644 --- a/arch/arm/mach-msm/board-msm8960.c +++ b/arch/arm/mach-msm/board-msm8960.c @@ -20,16 +20,34 @@  #include <linux/io.h>  #include <linux/irq.h>  #include <linux/clkdev.h> +#include <linux/memblock.h>  #include <asm/mach-types.h>  #include <asm/mach/arch.h>  #include <asm/hardware/gic.h> +#include <asm/setup.h>  #include <mach/board.h>  #include <mach/msm_iomap.h>  #include "devices.h" +static void __init msm8960_fixup(struct machine_desc *desc, struct tag *tag, +			 char **cmdline, struct meminfo *mi) +{ +	for (; tag->hdr.size; tag = tag_next(tag)) +		if (tag->hdr.tag == ATAG_MEM && +				tag->u.mem.start == 0x40200000) { +			tag->u.mem.start = 0x40000000; +			tag->u.mem.size += SZ_2M; +		} +} + +static void __init msm8960_reserve(void) +{ +	memblock_remove(0x40000000, SZ_2M); +} +  static void __init msm8960_map_io(void)  {  	msm_map_msm8960_io(); @@ -76,6 +94,8 @@ static void __init msm8960_rumi3_init(void)  }  MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR") +	.fixup = msm8960_fixup, +	.reserve = msm8960_reserve,  	.map_io = msm8960_map_io,  	.init_irq = msm8960_init_irq,  	.timer = &msm_timer, @@ -83,6 +103,8 @@ MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")  MACHINE_END  MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3") +	.fixup = msm8960_fixup, +	.reserve = msm8960_reserve,  	.map_io = msm8960_map_io,  	.init_irq = msm8960_init_irq,  	.timer = &msm_timer, diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c index 1163b6fd05d..106170fb184 100644 --- a/arch/arm/mach-msm/board-msm8x60.c +++ b/arch/arm/mach-msm/board-msm8x60.c @@ -20,14 +20,31 @@  #include <linux/platform_device.h>  #include <linux/io.h>  #include <linux/irq.h> +#include <linux/memblock.h>  #include <asm/mach-types.h>  #include <asm/mach/arch.h>  #include <asm/hardware/gic.h> +#include <asm/setup.h>  #include <mach/board.h>  #include <mach/msm_iomap.h> +static void __init msm8x60_fixup(struct machine_desc *desc, struct tag *tag, +			 char **cmdline, struct meminfo *mi) +{ +	for (; tag->hdr.size; tag = tag_next(tag)) +		if (tag->hdr.tag == ATAG_MEM && +				tag->u.mem.start == 0x40200000) { +			tag->u.mem.start = 0x40000000; +			tag->u.mem.size += SZ_2M; +		} +} + +static void __init msm8x60_reserve(void) +{ +	memblock_remove(0x40000000, SZ_2M); +}  static void __init msm8x60_map_io(void)  { @@ -36,8 +53,6 @@ static void __init msm8x60_map_io(void)  static void __init msm8x60_init_irq(void)  { -	unsigned int i; -  	gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,  		 (void *)MSM_QGIC_CPU_BASE); @@ -49,15 +64,6 @@ static void __init msm8x60_init_irq(void)  	 */  	if (!machine_is_msm8x60_sim())  		writel(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET); - -	/* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet -	 * as they are configured as level, which does not play nice with -	 * handle_percpu_irq. -	 */ -	for (i = GIC_PPI_START; i < GIC_SPI_START; i++) { -		if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE) -			irq_set_handler(i, handle_percpu_irq); -	}  }  static void __init msm8x60_init(void) @@ -65,6 +71,8 @@ static void __init msm8x60_init(void)  }  MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3") +	.fixup = msm8x60_fixup, +	.reserve = msm8x60_reserve,  	.map_io = msm8x60_map_io,  	.init_irq = msm8x60_init_irq,  	.init_machine = msm8x60_init, @@ -72,6 +80,8 @@ MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")  MACHINE_END  MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF") +	.fixup = msm8x60_fixup, +	.reserve = msm8x60_reserve,  	.map_io = msm8x60_map_io,  	.init_irq = msm8x60_init_irq,  	.init_machine = msm8x60_init, @@ -79,6 +89,8 @@ MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")  MACHINE_END  MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR") +	.fixup = msm8x60_fixup, +	.reserve = msm8x60_reserve,  	.map_io = msm8x60_map_io,  	.init_irq = msm8x60_init_irq,  	.init_machine = msm8x60_init, @@ -86,6 +98,8 @@ MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")  MACHINE_END  MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA") +	.fixup = msm8x60_fixup, +	.reserve = msm8x60_reserve,  	.map_io = msm8x60_map_io,  	.init_irq = msm8x60_init_irq,  	.init_machine = msm8x60_init, diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c index 24e9b89738e..7e8909c978c 100644 --- a/arch/arm/mach-msm/board-qsd8x50.c +++ b/arch/arm/mach-msm/board-qsd8x50.c @@ -192,7 +192,7 @@ static void __init qsd8x50_init(void)  }  MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF") -	.boot_params = PLAT_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = qsd8x50_map_io,  	.init_irq = qsd8x50_init_irq,  	.init_machine = qsd8x50_init, @@ -200,7 +200,7 @@ MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")  MACHINE_END  MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5") -	.boot_params = PLAT_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = qsd8x50_map_io,  	.init_irq = qsd8x50_init_irq,  	.init_machine = qsd8x50_init, diff --git a/arch/arm/mach-msm/board-sapphire.c b/arch/arm/mach-msm/board-sapphire.c index 863394c59e8..afa9293d580 100644 --- a/arch/arm/mach-msm/board-sapphire.c +++ b/arch/arm/mach-msm/board-sapphire.c @@ -104,7 +104,7 @@ static void __init sapphire_map_io(void)  MACHINE_START(SAPPHIRE, "sapphire")  /* Maintainer: Brian Swetland <swetland@google.com> */ -	.boot_params    = PLAT_PHYS_OFFSET + 0x100, +	.atag_offset    = 0x100,  	.fixup          = sapphire_fixup,  	.map_io         = sapphire_map_io,  	.init_irq       = sapphire_init_irq, diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c index 814386772c6..22d5694f5fe 100644 --- a/arch/arm/mach-msm/board-trout.c +++ b/arch/arm/mach-msm/board-trout.c @@ -93,7 +93,7 @@ static void __init trout_map_io(void)  }  MACHINE_START(TROUT, "HTC Dream") -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.fixup		= trout_fixup,  	.map_io		= trout_map_io,  	.init_irq	= trout_init_irq, diff --git a/arch/arm/mach-msm/include/mach/debug-macro.S b/arch/arm/mach-msm/include/mach/debug-macro.S index 646b99ebc77..2dc73ccddb1 100644 --- a/arch/arm/mach-msm/include/mach/debug-macro.S +++ b/arch/arm/mach-msm/include/mach/debug-macro.S @@ -20,7 +20,7 @@  #include <mach/msm_iomap.h>  #if defined(CONFIG_HAS_MSM_DEBUG_UART_PHYS) && !defined(CONFIG_MSM_DEBUG_UART_NONE) -	.macro	addruart, rp, rv +	.macro	addruart, rp, rv, tmp  	ldr	\rp, =MSM_DEBUG_UART_PHYS  	ldr	\rv, =MSM_DEBUG_UART_BASE  	.endm @@ -37,7 +37,7 @@  	beq	1001b  	.endm  #else -	.macro  addruart, rp, rv +	.macro  addruart, rp, rv, tmp  	mov	\rv, #0xff000000  	orr	\rv, \rv, #0x00f00000  	.endm diff --git a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S index 12467157afb..717076f3ca7 100644 --- a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S +++ b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S @@ -8,81 +8,10 @@   * warranty of any kind, whether express or implied.   */ -#include <mach/hardware.h> -#include <asm/hardware/gic.h> +#include <asm/hardware/entry-macro-gic.S>  	.macro	disable_fiq  	.endm -	.macro  get_irqnr_preamble, base, tmp -	ldr	\base, =gic_cpu_base_addr -	ldr	\base, [\base] -	.endm -  	.macro  arch_ret_to_user, tmp1, tmp2  	.endm - -	/* -	 * The interrupt numbering scheme is defined in the -	 * interrupt controller spec.  To wit: -	 * -	 * Migrated the code from ARM MP port to be more consistent -	 * with interrupt processing , the following still holds true -	 * however, all interrupts are treated the same regardless of -	 * if they are local IPI or PPI -	 * -	 * Interrupts 0-15 are IPI -	 * 16-31 are PPI -	 *   (16-18 are the timers) -	 * 32-1020 are global -	 * 1021-1022 are reserved -	 * 1023 is "spurious" (no interrupt) -	 * -	 * A simple read from the controller will tell us the number of the -	 * highest priority enabled interrupt.  We then just need to check -	 * whether it is in the valid range for an IRQ (0-1020 inclusive). -	 * -	 * Base ARM code assumes that the local (private) peripheral interrupts -	 * are not valid, we treat them differently, in that the privates are -	 * handled like normal shared interrupts with the exception that only -	 * one processor can register the interrupt and the handler must be -	 * the same for all processors. -	 */ - -	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp - -	ldr  \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 =srcCPU, -						   9-0 =int # */ - -	bic     \irqnr, \irqstat, #0x1c00	@mask src -	cmp     \irqnr, #15 -	ldr		\tmp, =1021 -	cmpcc	\irqnr, \irqnr -	cmpne	\irqnr, \tmp -	cmpcs	\irqnr, \irqnr - -	.endm - -	/* We assume that irqstat (the raw value of the IRQ acknowledge -	 * register) is preserved from the macro above. -	 * If there is an IPI, we immediately signal end of interrupt on the -	 * controller, since this requires the original irqstat value which -	 * we won't easily be able to recreate later. -	 */ -	.macro test_for_ipi, irqnr, irqstat, base, tmp -    bic \irqnr, \irqstat, #0x1c00 -    cmp \irqnr, #16 -    strcc   \irqstat, [\base, #GIC_CPU_EOI] -    cmpcs   \irqnr, \irqnr -	.endm - -	/* As above, this assumes that irqstat and base are preserved.. */ - -	.macro test_for_ltirq, irqnr, irqstat, base, tmp -    bic \irqnr, \irqstat, #0x1c00 -    mov     \tmp, #0 -    cmp \irqnr, #16 -    moveq   \tmp, #1 -    streq   \irqstat, [\base, #GIC_CPU_EOI] -    cmp \tmp, #0 -	.endm diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h deleted file mode 100644 index f2f8d299ba9..00000000000 --- a/arch/arm/mach-msm/include/mach/memory.h +++ /dev/null @@ -1,35 +0,0 @@ -/* arch/arm/mach-msm/include/mach/memory.h - * - * Copyright (C) 2007 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* physical offset of RAM */ -#if defined(CONFIG_ARCH_QSD8X50) && defined(CONFIG_MSM_SOC_REV_A) -#define PLAT_PHYS_OFFSET		UL(0x00000000) -#elif defined(CONFIG_ARCH_QSD8X50) -#define PLAT_PHYS_OFFSET		UL(0x20000000) -#elif defined(CONFIG_ARCH_MSM7X30) -#define PLAT_PHYS_OFFSET		UL(0x00200000) -#elif defined(CONFIG_ARCH_MSM8X60) -#define PLAT_PHYS_OFFSET		UL(0x40200000) -#elif defined(CONFIG_ARCH_MSM8960) -#define PLAT_PHYS_OFFSET		UL(0x40200000) -#else -#define PLAT_PHYS_OFFSET		UL(0x10000000) -#endif - -#endif - diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c index 1a1af9e5625..72765952091 100644 --- a/arch/arm/mach-msm/platsmp.c +++ b/arch/arm/mach-msm/platsmp.c @@ -156,6 +156,12 @@ void __init smp_init_cpus(void)  {  	unsigned int i, ncores = get_core_count(); +	if (ncores > nr_cpu_ids) { +		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", +			ncores, nr_cpu_ids); +		ncores = nr_cpu_ids; +	} +  	for (i = 0; i < ncores; i++)  		set_cpu_possible(i, true); diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 63621f152c9..afeeca52fc6 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -71,12 +71,16 @@ enum timer_location {  struct msm_clock {  	struct clock_event_device   clockevent;  	struct clocksource          clocksource; -	struct irqaction            irq; +	unsigned int		    irq;  	void __iomem                *regbase;  	uint32_t                    freq;  	uint32_t                    shift;  	void __iomem                *global_counter;  	void __iomem                *local_counter; +	union { +		struct clock_event_device		*evt; +		struct clock_event_device __percpu	**percpu_evt; +	};		  };  enum { @@ -87,13 +91,10 @@ enum {  static struct msm_clock msm_clocks[]; -static struct clock_event_device *local_clock_event;  static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)  { -	struct clock_event_device *evt = dev_id; -	if (smp_processor_id() != 0) -		evt = local_clock_event; +	struct clock_event_device *evt = *(struct clock_event_device **)dev_id;  	if (evt->event_handler == NULL)  		return IRQ_HANDLED;  	evt->event_handler(evt); @@ -171,13 +172,7 @@ static struct msm_clock msm_clocks[] = {  			.mask           = CLOCKSOURCE_MASK(32),  			.flags          = CLOCK_SOURCE_IS_CONTINUOUS,  		}, -		.irq = { -			.name    = "gp_timer", -			.flags   = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING, -			.handler = msm_timer_interrupt, -			.dev_id  = &msm_clocks[0].clockevent, -			.irq     = INT_GP_TIMER_EXP -		}, +		.irq = INT_GP_TIMER_EXP,  		.freq = GPT_HZ,  	},  	[MSM_CLOCK_DGT] = { @@ -196,13 +191,7 @@ static struct msm_clock msm_clocks[] = {  			.mask           = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)),  			.flags          = CLOCK_SOURCE_IS_CONTINUOUS,  		}, -		.irq = { -			.name    = "dg_timer", -			.flags   = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING, -			.handler = msm_timer_interrupt, -			.dev_id  = &msm_clocks[1].clockevent, -			.irq     = INT_DEBUG_TIMER_EXP -		}, +		.irq = INT_DEBUG_TIMER_EXP,  		.freq = DGT_HZ >> MSM_DGT_SHIFT,  		.shift = MSM_DGT_SHIFT,  	} @@ -261,10 +250,30 @@ static void __init msm_timer_init(void)  			printk(KERN_ERR "msm_timer_init: clocksource_register "  			       "failed for %s\n", cs->name); -		res = setup_irq(clock->irq.irq, &clock->irq); +		ce->irq = clock->irq; +		if (cpu_is_msm8x60() || cpu_is_msm8960()) { +			clock->percpu_evt = alloc_percpu(struct clock_event_device *); +			if (!clock->percpu_evt) { +				pr_err("msm_timer_init: memory allocation " +				       "failed for %s\n", ce->name); +				continue; +			} + +			*__this_cpu_ptr(clock->percpu_evt) = ce; +			res = request_percpu_irq(ce->irq, msm_timer_interrupt, +						 ce->name, clock->percpu_evt); +			if (!res) +				enable_percpu_irq(ce->irq, 0); +		} else { +			clock->evt = ce; +			res = request_irq(ce->irq, msm_timer_interrupt, +					  IRQF_TIMER | IRQF_NOBALANCING | IRQF_TRIGGER_RISING, +					  ce->name, &clock->evt); +		} +  		if (res) -			printk(KERN_ERR "msm_timer_init: setup_irq " -			       "failed for %s\n", cs->name); +			pr_err("msm_timer_init: request_irq failed for %s\n", +			       ce->name);  		clockevents_register_device(ce);  	} @@ -273,6 +282,7 @@ static void __init msm_timer_init(void)  #ifdef CONFIG_SMP  int __cpuinit local_timer_setup(struct clock_event_device *evt)  { +	static bool local_timer_inited;  	struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER];  	/* Use existing clock_event for cpu 0 */ @@ -281,12 +291,13 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)  	writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); -	if (!local_clock_event) { +	if (!local_timer_inited) {  		writel(0, clock->regbase  + TIMER_ENABLE);  		writel(0, clock->regbase + TIMER_CLEAR);  		writel(~0, clock->regbase + TIMER_MATCH_VAL); +		local_timer_inited = true;  	} -	evt->irq = clock->irq.irq; +	evt->irq = clock->irq;  	evt->name = "local_timer";  	evt->features = CLOCK_EVT_FEAT_ONESHOT;  	evt->rating = clock->clockevent.rating; @@ -298,17 +309,17 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)  		clockevent_delta2ns(0xf0000000 >> clock->shift, evt);  	evt->min_delta_ns = clockevent_delta2ns(4, evt); -	local_clock_event = evt; - -	gic_enable_ppi(clock->irq.irq); +	*__this_cpu_ptr(clock->percpu_evt) = evt; +	enable_percpu_irq(evt->irq, 0);  	clockevents_register_device(evt);  	return 0;  } -inline int local_timer_ack(void) +void local_timer_stop(struct clock_event_device *evt)  { -	return 1; +	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); +	disable_percpu_irq(evt->irq);  }  #endif diff --git a/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c index 20f3f125ed2..0e94268d6e6 100644 --- a/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c +++ b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c @@ -145,7 +145,7 @@ subsys_initcall(wxl_pci_init);  MACHINE_START(TERASTATION_WXL, "Buffalo Nas WXL")  	/* Maintainer: Sebastien Requiem <sebastien@requiem.fr> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= wxl_init,  	.map_io		= mv78xx0_map_io,  	.init_early	= mv78xx0_init_early, diff --git a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c index df5aebe5b0f..50b85ae2da5 100644 --- a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c +++ b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c @@ -93,7 +93,7 @@ subsys_initcall(db78x00_pci_init);  MACHINE_START(DB78X00_BP, "Marvell DB-78x00-BP Development Board")  	/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= db78x00_init,  	.map_io		= mv78xx0_map_io,  	.init_early	= mv78xx0_init_early, diff --git a/arch/arm/mach-mv78xx0/include/mach/debug-macro.S b/arch/arm/mach-mv78xx0/include/mach/debug-macro.S index 04891428e48..a7df02b049b 100644 --- a/arch/arm/mach-mv78xx0/include/mach/debug-macro.S +++ b/arch/arm/mach-mv78xx0/include/mach/debug-macro.S @@ -8,7 +8,7 @@  #include <mach/mv78xx0.h> -	.macro	addruart, rp, rv +	.macro	addruart, rp, rv, tmp  	ldr	\rp, =MV78XX0_REGS_PHYS_BASE  	ldr	\rv, =MV78XX0_REGS_VIRT_BASE  	orr	\rp, \rp, #0x00012000 diff --git a/arch/arm/mach-mv78xx0/include/mach/memory.h b/arch/arm/mach-mv78xx0/include/mach/memory.h deleted file mode 100644 index a648c51f2e4..00000000000 --- a/arch/arm/mach-mv78xx0/include/mach/memory.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * arch/arm/mach-mv78xx0/include/mach/memory.h - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET		UL(0x00000000) - -#endif diff --git a/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c b/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c index d927f14c681..e85222e5357 100644 --- a/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c +++ b/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c @@ -78,7 +78,7 @@ subsys_initcall(rd78x00_pci_init);  MACHINE_START(RD78X00_MASA, "Marvell RD-78x00-MASA Development Board")  	/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= rd78x00_masa_init,  	.map_io		= mv78xx0_map_io,  	.init_early	= mv78xx0_init_early, diff --git a/arch/arm/mach-mx5/board-cpuimx51.c b/arch/arm/mach-mx5/board-cpuimx51.c index 68934ea8725..e01af948e04 100644 --- a/arch/arm/mach-mx5/board-cpuimx51.c +++ b/arch/arm/mach-mx5/board-cpuimx51.c @@ -293,7 +293,7 @@ static struct sys_timer mxc_timer = {  MACHINE_START(EUKREA_CPUIMX51, "Eukrea CPUIMX51 Module")  	/* Maintainer: Eric Bénard <eric@eukrea.com> */ -	.boot_params = MX51_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx51_map_io,  	.init_early = imx51_init_early,  	.init_irq = mx51_init_irq, diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-mx5/board-cpuimx51sd.c index ff096d58729..b41fc274a42 100644 --- a/arch/arm/mach-mx5/board-cpuimx51sd.c +++ b/arch/arm/mach-mx5/board-cpuimx51sd.c @@ -331,7 +331,7 @@ static struct sys_timer mxc_timer = {  MACHINE_START(EUKREA_CPUIMX51SD, "Eukrea CPUIMX51SD")  	/* Maintainer: Eric Bénard <eric@eukrea.com> */ -	.boot_params = MX51_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx51_map_io,  	.init_early = imx51_init_early,  	.init_irq = mx51_init_irq, diff --git a/arch/arm/mach-mx5/board-mx51_3ds.c b/arch/arm/mach-mx5/board-mx51_3ds.c index 07a38154da2..a50174e69e2 100644 --- a/arch/arm/mach-mx5/board-mx51_3ds.c +++ b/arch/arm/mach-mx5/board-mx51_3ds.c @@ -169,7 +169,7 @@ static struct sys_timer mx51_3ds_timer = {  MACHINE_START(MX51_3DS, "Freescale MX51 3-Stack Board")  	/* Maintainer: Freescale Semiconductor, Inc. */ -	.boot_params = MX51_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx51_map_io,  	.init_early = imx51_init_early,  	.init_irq = mx51_init_irq, diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index 11b0ff67f89..468926a48fe 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c @@ -416,7 +416,7 @@ static struct sys_timer mx51_babbage_timer = {  MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board")  	/* Maintainer: Amit Kucheria <amit.kucheria@canonical.com> */ -	.boot_params = MX51_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx51_map_io,  	.init_early = imx51_init_early,  	.init_irq = mx51_init_irq, diff --git a/arch/arm/mach-mx5/board-mx51_efikamx.c b/arch/arm/mach-mx5/board-mx51_efikamx.c index 551daf85ff8..c36880da03f 100644 --- a/arch/arm/mach-mx5/board-mx51_efikamx.c +++ b/arch/arm/mach-mx5/board-mx51_efikamx.c @@ -280,7 +280,7 @@ static struct sys_timer mx51_efikamx_timer = {  MACHINE_START(MX51_EFIKAMX, "Genesi EfikaMX nettop")  	/* Maintainer: Amit Kucheria <amit.kucheria@linaro.org> */ -	.boot_params = MX51_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx51_map_io,  	.init_early = imx51_init_early,  	.init_irq = mx51_init_irq, diff --git a/arch/arm/mach-mx5/board-mx51_efikasb.c b/arch/arm/mach-mx5/board-mx51_efikasb.c index 8a9bca22beb..ba5436a9fb1 100644 --- a/arch/arm/mach-mx5/board-mx51_efikasb.c +++ b/arch/arm/mach-mx5/board-mx51_efikasb.c @@ -266,7 +266,7 @@ static struct sys_timer mx51_efikasb_timer = {  };  MACHINE_START(MX51_EFIKASB, "Genesi Efika Smartbook") -	.boot_params = MX51_PHYS_OFFSET + 0x100, +	.atag_offset = 0x100,  	.map_io = mx51_map_io,  	.init_early = imx51_init_early,  	.init_irq = mx51_init_irq, diff --git a/arch/arm/mach-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S index 79650a1ad78..714570d8366 100644 --- a/arch/arm/mach-mxs/include/mach/debug-macro.S +++ b/arch/arm/mach-mxs/include/mach/debug-macro.S @@ -30,7 +30,7 @@  #define UART_VADDR	MXS_IO_ADDRESS(UART_PADDR) -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		ldr	\rp, =UART_PADDR	@ physical  		ldr	\rv, =UART_VADDR	@ virtual  		.endm diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h deleted file mode 100644 index b5420a5c2d4..00000000000 --- a/arch/arm/mach-mxs/include/mach/memory.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef __MACH_MXS_MEMORY_H__ -#define __MACH_MXS_MEMORY_H__ - -#define PHYS_OFFSET		UL(0x40000000) - -#endif /* __MACH_MXS_MEMORY_H__ */ diff --git a/arch/arm/mach-netx/include/mach/debug-macro.S b/arch/arm/mach-netx/include/mach/debug-macro.S index 56a91522818..247781e096e 100644 --- a/arch/arm/mach-netx/include/mach/debug-macro.S +++ b/arch/arm/mach-netx/include/mach/debug-macro.S @@ -13,7 +13,7 @@  #include "hardware.h" -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #0x00000a00  		orr	\rv, \rp, #io_p2v(0x00100000)	@ virtual  		orr	\rp, \rp, #0x00100000		@ physical diff --git a/arch/arm/mach-netx/include/mach/memory.h b/arch/arm/mach-netx/include/mach/memory.h deleted file mode 100644 index 59561496c36..00000000000 --- a/arch/arm/mach-netx/include/mach/memory.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - *  arch/arm/mach-netx/include/mach/memory.h - * - * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix - * - * 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_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET UL(0x80000000) - -#endif - diff --git a/arch/arm/mach-netx/nxdb500.c b/arch/arm/mach-netx/nxdb500.c index ca8b203a3c9..90903dd44cb 100644 --- a/arch/arm/mach-netx/nxdb500.c +++ b/arch/arm/mach-netx/nxdb500.c @@ -200,7 +200,7 @@ static void __init nxdb500_init(void)  }  MACHINE_START(NXDB500, "Hilscher nxdb500") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.map_io		= netx_map_io,  	.init_irq	= netx_init_irq,  	.timer		= &netx_timer, diff --git a/arch/arm/mach-netx/nxdkn.c b/arch/arm/mach-netx/nxdkn.c index d775cbe0727..c63384aba50 100644 --- a/arch/arm/mach-netx/nxdkn.c +++ b/arch/arm/mach-netx/nxdkn.c @@ -93,7 +93,7 @@ static void __init nxdkn_init(void)  }  MACHINE_START(NXDKN, "Hilscher nxdkn") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.map_io		= netx_map_io,  	.init_irq	= netx_init_irq,  	.timer		= &netx_timer, diff --git a/arch/arm/mach-netx/nxeb500hmi.c b/arch/arm/mach-netx/nxeb500hmi.c index de369cd1dcb..8f548ec83ad 100644 --- a/arch/arm/mach-netx/nxeb500hmi.c +++ b/arch/arm/mach-netx/nxeb500hmi.c @@ -177,7 +177,7 @@ static void __init nxeb500hmi_init(void)  }  MACHINE_START(NXEB500HMI, "Hilscher nxeb500hmi") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.map_io		= netx_map_io,  	.init_irq	= netx_init_irq,  	.timer		= &netx_timer, diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 97d7186484c..0cbb74c96ef 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c @@ -277,7 +277,7 @@ static void __init nhk8815_platform_init(void)  MACHINE_START(NOMADIK, "NHK8815")  	/* Maintainer: ST MicroElectronics */ -	.boot_params	= 0x100, +	.atag_offset	= 0x100,  	.map_io		= cpu8815_map_io,  	.init_irq	= cpu8815_init_irq,  	.timer		= &nomadik_timer, diff --git a/arch/arm/mach-nomadik/include/mach/debug-macro.S b/arch/arm/mach-nomadik/include/mach/debug-macro.S index e7151b4b888..735417922ce 100644 --- a/arch/arm/mach-nomadik/include/mach/debug-macro.S +++ b/arch/arm/mach-nomadik/include/mach/debug-macro.S @@ -10,7 +10,7 @@   *  */ -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #0x00100000  		add	\rp, \rp, #0x000fb000  		add	\rv, \rp, #0xf0000000	@ virtual base diff --git a/arch/arm/mach-nomadik/include/mach/memory.h b/arch/arm/mach-nomadik/include/mach/memory.h deleted file mode 100644 index d3325211ba6..00000000000 --- a/arch/arm/mach-nomadik/include/mach/memory.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - *  mach-nomadik/include/mach/memory.h - * - *  Copyright (C) 1999 ARM Limited - * - * 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_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PLAT_PHYS_OFFSET	UL(0x00000000) - -#endif diff --git a/arch/arm/mach-nuc93x/include/mach/memory.h b/arch/arm/mach-nuc93x/include/mach/memory.h deleted file mode 100644 index ef9864b002a..00000000000 --- a/arch/arm/mach-nuc93x/include/mach/memory.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * arch/arm/mach-nuc93x/include/mach/memory.h - * - * Copyright (c) 2008 Nuvoton technology corporation - * All rights reserved. - * - * Wan ZongShun <mcuos.com@gmail.com> - * - * 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. - * - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET	UL(0x00000000) - -#endif diff --git a/arch/arm/mach-nuc93x/mach-nuc932evb.c b/arch/arm/mach-nuc93x/mach-nuc932evb.c index d7025704248..1f741b1c160 100644 --- a/arch/arm/mach-nuc93x/mach-nuc932evb.c +++ b/arch/arm/mach-nuc93x/mach-nuc932evb.c @@ -35,7 +35,6 @@ static void __init nuc932evb_init(void)  MACHINE_START(NUC932EVB, "NUC932EVB")  	/* Maintainer: Wan ZongShun */ -	.boot_params	= 0,  	.map_io		= nuc932evb_map_io,  	.init_irq	= nuc93x_init_irq,  	.init_machine	= nuc932evb_init, diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index d86e9af2822..4ea60e2038e 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -385,7 +385,7 @@ static void __init ams_delta_map_io(void)  MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")  	/* Maintainer: Jonathan McDowell <noodles@earth.li> */ -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= ams_delta_map_io,  	.reserve	= omap_reserve,  	.init_irq	= ams_delta_init_irq, diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c index dd814b33cdd..31e089b6f03 100644 --- a/arch/arm/mach-omap1/board-fsample.c +++ b/arch/arm/mach-omap1/board-fsample.c @@ -388,7 +388,7 @@ static void __init omap_fsample_map_io(void)  MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample")  /* Maintainer: Brian Swetland <swetland@google.com> */ -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= omap_fsample_map_io,  	.reserve	= omap_reserve,  	.init_irq	= omap_fsample_init_irq, diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c index 8f7d1158148..05c6e9d858f 100644 --- a/arch/arm/mach-omap1/board-generic.c +++ b/arch/arm/mach-omap1/board-generic.c @@ -93,7 +93,7 @@ static void __init omap_generic_map_io(void)  MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")  	/* Maintainer: Tony Lindgren <tony@atomide.com> */ -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= omap_generic_map_io,  	.reserve	= omap_reserve,  	.init_irq	= omap_generic_init_irq, diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 0796ad7e24b..c2e279173d4 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -460,7 +460,7 @@ static void __init h2_map_io(void)  MACHINE_START(OMAP_H2, "TI-H2")  	/* Maintainer: Imre Deak <imre.deak@nokia.com> */ -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= h2_map_io,  	.reserve	= omap_reserve,  	.init_irq	= h2_init_irq, diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index fe1814c5e74..8f5b6af7ed5 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -448,7 +448,7 @@ static void __init h3_map_io(void)  MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")  	/* Maintainer: Texas Instruments, Inc. */ -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= h3_map_io,  	.reserve	= omap_reserve,  	.init_irq	= h3_init_irq, diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c index 4af7bfa40e4..fcd1a3c3189 100644 --- a/arch/arm/mach-omap1/board-htcherald.c +++ b/arch/arm/mach-omap1/board-htcherald.c @@ -610,7 +610,7 @@ static void __init htcherald_init_irq(void)  MACHINE_START(HERALD, "HTC Herald")  	/* Maintainer: Cory Maccarrone <darkstar6262@gmail.com> */  	/* Maintainer: wing-linux.sourceforge.net */ -	.boot_params    = 0x10000100, +	.atag_offset    = 0x100,  	.map_io         = htcherald_map_io,  	.reserve	= omap_reserve,  	.init_irq       = htcherald_init_irq, diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index e603e5eb32a..c2234caf8a7 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -458,7 +458,7 @@ static void __init innovator_map_io(void)  MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")  	/* Maintainer: MontaVista Software, Inc. */ -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= innovator_map_io,  	.reserve	= omap_reserve,  	.init_irq	= innovator_init_irq, diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 8420535fe51..02789c5d370 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -263,7 +263,7 @@ static void __init omap_nokia770_map_io(void)  }  MACHINE_START(NOKIA770, "Nokia 770") -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= omap_nokia770_map_io,  	.reserve	= omap_reserve,  	.init_irq	= omap_nokia770_init_irq, diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index bf1ebe5b244..e4dca1deebb 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -582,7 +582,7 @@ static void __init osk_map_io(void)  MACHINE_START(OMAP_OSK, "TI-OSK")  	/* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */ -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= osk_map_io,  	.reserve	= omap_reserve,  	.init_irq	= osk_init_irq, diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 45596b5acf0..50c4e398bcc 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -274,7 +274,7 @@ static void __init omap_palmte_map_io(void)  }  MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= omap_palmte_map_io,  	.reserve	= omap_reserve,  	.init_irq	= omap_palmte_init_irq, diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c index f942221f6e7..273771cb1b6 100644 --- a/arch/arm/mach-omap1/board-palmtt.c +++ b/arch/arm/mach-omap1/board-palmtt.c @@ -321,7 +321,7 @@ static void __init omap_palmtt_map_io(void)  }  MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T") -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= omap_palmtt_map_io,  	.reserve	= omap_reserve,  	.init_irq	= omap_palmtt_init_irq, diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index 2b912d46cee..de36ade38ef 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c @@ -341,7 +341,7 @@ omap_palmz71_map_io(void)  }  MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71") -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= omap_palmz71_map_io,  	.reserve	= omap_reserve,  	.init_irq	= omap_palmz71_init_irq, diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 7e2efe52cc3..04b1befaced 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -349,7 +349,7 @@ static void __init omap_perseus2_map_io(void)  MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")  	/* Maintainer: Kevin Hilman <kjh@hilman.org> */ -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= omap_perseus2_map_io,  	.reserve	= omap_reserve,  	.init_irq	= omap_perseus2_init_irq, diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c index 172a28f9a34..2bea941741d 100644 --- a/arch/arm/mach-omap1/board-sx1.c +++ b/arch/arm/mach-omap1/board-sx1.c @@ -420,7 +420,7 @@ static void __init omap_sx1_map_io(void)  }  MACHINE_START(SX1, "OMAP310 based Siemens SX1") -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= omap_sx1_map_io,  	.reserve	= omap_reserve,  	.init_irq	= omap_sx1_init_irq, diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index 236b7ded0cf..940faed82be 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -301,7 +301,7 @@ static void __init voiceblue_init(void)  MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")  	/* Maintainer: Ladislav Michl <michl@2n.cz> */ -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.map_io		= voiceblue_map_io,  	.reserve	= omap_reserve,  	.init_irq	= voiceblue_init_irq, diff --git a/arch/arm/mach-omap1/include/mach/debug-macro.S b/arch/arm/mach-omap1/include/mach/debug-macro.S index 62856044eb6..2b36a281dc8 100644 --- a/arch/arm/mach-omap1/include/mach/debug-macro.S +++ b/arch/arm/mach-omap1/include/mach/debug-macro.S @@ -13,13 +13,8 @@  #include <linux/serial_reg.h> -#include <asm/memory.h> -  #include <plat/serial.h> -#define omap_uart_v2p(x)	((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET) -#define omap_uart_p2v(x)	((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET) -  		.pushsection .data  omap_uart_phys:	.word	0x0  omap_uart_virt:	.word	0x0 @@ -31,26 +26,24 @@ omap_uart_virt:	.word	0x0  		 * the desired UART phys and virt addresses temporarily into  		 * the omap_uart_phys and omap_uart_virt above.  		 */ -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		/* Use omap_uart_phys/virt if already configured */ -9:		mrc	p15, 0, \rp, c1, c0 -		tst	\rp, #1			@ MMU enabled? -		ldreq	\rp, =omap_uart_v2p(omap_uart_phys)	@ MMU disabled -		ldrne	\rp, =omap_uart_phys	@ MMU enabled -		add	\rv, \rp, #4		@ omap_uart_virt -		ldr	\rp, [\rp, #0] -		ldr	\rv, [\rv, #0] +9:		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	99f			@ already configured +		bne	100f			@ already configured  		/* Check the debug UART configuration set in uncompress.h */ -		mrc	p15, 0, \rp, c1, c0 -		tst	\rp, #1			@ MMU enabled? -		ldreq	\rp, =OMAP_UART_INFO	@ MMU not enabled -		ldrne	\rp, =omap_uart_p2v(OMAP_UART_INFO)	@ MMU enabled -		ldr	\rp, [\rp, #0] +		and	\rp, pc, #0xff000000 +		ldr	\rv, =OMAP_UART_INFO_OFS +		ldr	\rp, [\rp, \rv]  		/* Select the UART to use based on the UART1 scratchpad value */  10:		cmp	\rp, #0			@ no port configured? @@ -74,17 +67,18 @@ omap_uart_virt:	.word	0x0  		/* Store both phys and virt address for the uart */  98:		add	\rp, \rp, #0xff000000	@ phys base -		mrc	p15, 0, \rv, c1, c0 -		tst	\rv, #1			@ MMU enabled? -		ldreq	\rv, =omap_uart_v2p(omap_uart_phys)	@ MMU disabled -		ldrne	\rv, =omap_uart_phys	@ MMU enabled -		str	\rp, [\rv, #0] +		str	\rp, [\tmp, #0]		@ omap_uart_phys  		sub	\rp, \rp, #0xff000000	@ phys base  		add	\rp, \rp, #0xfe000000	@ virt base -		add	\rv, \rv, #4		@ omap_uart_lsr -		str	\rp, [\rv, #0] +		str	\rp, [\tmp, #4]		@ omap_uart_virt  		b	9b -99: + +		.align +99:		.word	. +		.word	omap_uart_phys +		.ltorg + +100:  		.endm  		.macro	senduart,rd,rx diff --git a/arch/arm/mach-omap1/include/mach/memory.h b/arch/arm/mach-omap1/include/mach/memory.h index e9b600c113e..c6337645ba8 100644 --- a/arch/arm/mach-omap1/include/mach/memory.h +++ b/arch/arm/mach-omap1/include/mach/memory.h @@ -2,4 +2,55 @@   * arch/arm/mach-omap1/include/mach/memory.h   */ -#include <plat/memory.h> +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +/* + * Physical DRAM offset. + */ +#define PLAT_PHYS_OFFSET		UL(0x10000000) + +/* + * Bus address is physical address, except for OMAP-1510 Local Bus. + * OMAP-1510 bus address is translated into a Local Bus address if the + * OMAP bus type is lbus. We do the address translation based on the + * device overriding the defaults used in the dma-mapping API. + * Note that the is_lbus_device() test is not very efficient on 1510 + * because of the strncmp(). + */ +#ifdef CONFIG_ARCH_OMAP15XX + +/* + * OMAP-1510 Local Bus address offset + */ +#define OMAP1510_LB_OFFSET	UL(0x30000000) + +#define virt_to_lbus(x)		((x) - PAGE_OFFSET + OMAP1510_LB_OFFSET) +#define lbus_to_virt(x)		((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET) +#define is_lbus_device(dev)	(cpu_is_omap15xx() && dev && (strncmp(dev_name(dev), "ohci", 4) == 0)) + +#define __arch_pfn_to_dma(dev, pfn)	\ +	({ dma_addr_t __dma = __pfn_to_phys(pfn); \ +	   if (is_lbus_device(dev)) \ +		__dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \ +	   __dma; }) + +#define __arch_dma_to_pfn(dev, addr)	\ +	({ dma_addr_t __dma = addr;				\ +	   if (is_lbus_device(dev))				\ +		__dma += PHYS_OFFSET - OMAP1510_LB_OFFSET;	\ +	   __phys_to_pfn(__dma);				\ +	}) + +#define __arch_dma_to_virt(dev, addr)	({ (void *) (is_lbus_device(dev) ? \ +						lbus_to_virt(addr) : \ +						__phys_to_virt(addr)); }) + +#define __arch_virt_to_dma(dev, addr)	({ unsigned long __addr = (unsigned long)(addr); \ +					   (dma_addr_t) (is_lbus_device(dev) ? \ +						virt_to_lbus(__addr) : \ +						__virt_to_phys(__addr)); }) + +#endif	/* CONFIG_ARCH_OMAP15XX */ + +#endif diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index 870886a2959..1cfa1b6bb62 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c @@ -121,6 +121,7 @@ void __init omap1_map_common_io(void)  #endif  	omap_sram_init(); +	omap_init_consistent_dma_size();  }  /* diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 2028464cf5b..195157da21e 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c @@ -256,7 +256,7 @@ static void __init omap_2430sdp_map_io(void)  MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")  	/* Maintainer: Syed Khasim - Texas Instruments Inc */ -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap_2430sdp_map_io,  	.init_early	= omap_2430sdp_init_early, diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index bd600cfb7f8..2430531b223 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -729,7 +729,7 @@ static void __init omap_3430sdp_init(void)  MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")  	/* Maintainer: Syed Khasim - Texas Instruments Inc */ -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= omap_3430sdp_init_early, diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index e4f37b57a0c..8b5b5aa751e 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -215,7 +215,7 @@ static void __init omap_sdp_init(void)  }  MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= omap_sdp_init_early, diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index c7cef44c75d..be931105d68 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -838,7 +838,7 @@ static void __init omap_4430sdp_map_io(void)  MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")  	/* Maintainer: Santosh Shilimkar - Texas Instruments Inc */ -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap_4430sdp_map_io,  	.init_early	= omap_4430sdp_init_early, diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c index 933e9353cb3..db110fdb8b2 100644 --- a/arch/arm/mach-omap2/board-am3517crane.c +++ b/arch/arm/mach-omap2/board-am3517crane.c @@ -98,7 +98,7 @@ static void __init am3517_crane_init(void)  }  MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= am3517_crane_init_early, diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index f3006c30415..1325085e453 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -490,7 +490,7 @@ static void __init am3517_evm_init(void)  }  MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= am3517_evm_init_early, diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 70211703ff9..67800e647d7 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c @@ -350,7 +350,7 @@ static void __init omap_apollon_map_io(void)  MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")  	/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */ -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap_apollon_map_io,  	.init_early	= omap_apollon_init_early, diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 3af8aab435b..38179c17550 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -634,7 +634,7 @@ static void __init cm_t3730_init(void)  }  MACHINE_START(CM_T35, "Compulab CM-T35") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= cm_t35_init_early, @@ -644,7 +644,7 @@ MACHINE_START(CM_T35, "Compulab CM-T35")  MACHINE_END  MACHINE_START(CM_T3730, "Compulab CM-T3730") -	.boot_params    = 0x80000100, +	.atag_offset    = 0x100,  	.reserve        = omap_reserve,  	.map_io         = omap3_map_io,  	.init_early     = cm_t35_init_early, diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c index 05c72f4c1b5..aed9c29f9fa 100644 --- a/arch/arm/mach-omap2/board-cm-t3517.c +++ b/arch/arm/mach-omap2/board-cm-t3517.c @@ -299,7 +299,7 @@ static void __init cm_t3517_init(void)  }  MACHINE_START(CM_T3517, "Compulab CM-T3517") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve        = omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= cm_t3517_init_early, diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index b6002ec31c6..99a42432ac9 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -667,7 +667,7 @@ static void __init devkit8000_init(void)  }  MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= devkit8000_init_early, diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index bb4af05c7f0..4431ad36456 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -65,7 +65,7 @@ static void __init omap_generic_map_io(void)  /* XXX This machine entry name should be updated */  MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")  	/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */ -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap_generic_map_io,  	.init_early	= omap_generic_init_early, diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 95319e76180..82421a4cfa9 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -381,7 +381,7 @@ static void __init omap_h4_map_io(void)  MACHINE_START(OMAP_H4, "OMAP2420 H4 board")  	/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */ -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap_h4_map_io,  	.init_early	= omap_h4_init_early, diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 35be778caf1..7040352b16b 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -672,7 +672,7 @@ static void __init igep_init(void)  }  MACHINE_START(IGEP0020, "IGEP v2 board") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= igep_init_early, @@ -682,7 +682,7 @@ MACHINE_START(IGEP0020, "IGEP v2 board")  MACHINE_END  MACHINE_START(IGEP0030, "IGEP OMAP3 module") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= igep_init_early, diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index ddff45c1688..abe8c7e496a 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c @@ -332,7 +332,7 @@ static void __init omap_ldp_init(void)  }  MACHINE_START(OMAP_LDP, "OMAP LDP board") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= omap_ldp_init_early, diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index e11f0c5d608..6ce748154f2 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -695,7 +695,7 @@ static void __init n8x0_init_machine(void)  }  MACHINE_START(NOKIA_N800, "Nokia N800") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= n8x0_map_io,  	.init_early	= n8x0_init_early, @@ -705,7 +705,7 @@ MACHINE_START(NOKIA_N800, "Nokia N800")  MACHINE_END  MACHINE_START(NOKIA_N810, "Nokia N810") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= n8x0_map_io,  	.init_early	= n8x0_init_early, @@ -715,7 +715,7 @@ MACHINE_START(NOKIA_N810, "Nokia N810")  MACHINE_END  MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= n8x0_map_io,  	.init_early	= n8x0_init_early, diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 3ae16b4e3f5..1fde8a0474b 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -557,7 +557,7 @@ static void __init omap3_beagle_init(void)  MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")  	/* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */ -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= omap3_beagle_init_early, diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index c452b3f3331..15c69a0c1ce 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -681,7 +681,7 @@ static void __init omap3_evm_init(void)  MACHINE_START(OMAP3EVM, "OMAP3 EVM")  	/* Maintainer: Syed Mohammed Khasim - Texas Instruments */ -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= omap3_evm_init_early, diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c index 703aeb5b8fd..01354a214ca 100644 --- a/arch/arm/mach-omap2/board-omap3logic.c +++ b/arch/arm/mach-omap2/board-omap3logic.c @@ -209,7 +209,7 @@ static void __init omap3logic_init(void)  }  MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.map_io		= omap3_map_io,  	.init_early	= omap3logic_init_early,  	.init_irq	= omap3_init_irq, @@ -218,7 +218,7 @@ MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board")  MACHINE_END  MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.map_io		= omap3_map_io,  	.init_early	= omap3logic_init_early,  	.init_irq	= omap3_init_irq, diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 080d7bd6795..ace56938dd3 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -606,7 +606,7 @@ static void __init omap3pandora_init(void)  }  MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= omap3pandora_init_early, diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index 8e104980ea2..ba13e1d5d0a 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c @@ -494,7 +494,7 @@ static void __init omap3_stalker_init(void)  MACHINE_START(SBC3530, "OMAP3 STALKER")  	/* Maintainer: Jason Lam -lzg@ema-tech.com */ -	.boot_params		= 0x80000100, +	.atag_offset		= 0x100,  	.map_io			= omap3_map_io,  	.init_early		= omap3_stalker_init_early,  	.init_irq		= omap3_stalker_init_irq, diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c index 852ea046405..49e4bd207cb 100644 --- a/arch/arm/mach-omap2/board-omap3touchbook.c +++ b/arch/arm/mach-omap2/board-omap3touchbook.c @@ -404,7 +404,7 @@ static void __init omap3_touchbook_init(void)  MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")  	/* Maintainer: Gregoire Gentil - http://www.alwaysinnovating.com */ -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= omap3_touchbook_init_early, diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 9aaa9605766..683bede73d5 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -583,7 +583,7 @@ static void __init omap4_panda_map_io(void)  MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")  	/* Maintainer: David Anders - Texas Instruments Inc */ -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap4_panda_map_io,  	.init_early	= omap4_panda_init_early, diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index f949a9954d7..e592fb134c4 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -561,7 +561,7 @@ static void __init overo_init(void)  }  MACHINE_START(OVERO, "Gumstix Overo") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= overo_init_early, diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c index 7dfed24ee12..9a8ce239ba9 100644 --- a/arch/arm/mach-omap2/board-rm680.c +++ b/arch/arm/mach-omap2/board-rm680.c @@ -153,7 +153,7 @@ static void __init rm680_map_io(void)  }  MACHINE_START(NOKIA_RM680, "Nokia RM-680 board") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= rm680_map_io,  	.init_early	= rm680_init_early, diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c index 5ea142f9bc9..a6c473bbb3d 100644 --- a/arch/arm/mach-omap2/board-rx51.c +++ b/arch/arm/mach-omap2/board-rx51.c @@ -156,7 +156,7 @@ static void __init rx51_reserve(void)  MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")  	/* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */ -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= rx51_reserve,  	.map_io		= rx51_map_io,  	.init_early	= rx51_init_early, diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c index a85d5b0b11d..e41958acb6b 100644 --- a/arch/arm/mach-omap2/board-ti8168evm.c +++ b/arch/arm/mach-omap2/board-ti8168evm.c @@ -48,7 +48,7 @@ static void __init ti8168_evm_map_io(void)  MACHINE_START(TI8168EVM, "ti8168evm")  	/* Maintainer: Texas Instruments */ -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.map_io		= ti8168_evm_map_io,  	.init_early	= ti8168_init_early,  	.init_irq	= ti816x_init_irq, diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c index 8a98c3c303f..72f1db4863e 100644 --- a/arch/arm/mach-omap2/board-zoom.c +++ b/arch/arm/mach-omap2/board-zoom.c @@ -133,7 +133,7 @@ static void __init omap_zoom_init(void)  }  MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= omap_zoom_init_early, @@ -143,7 +143,7 @@ MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")  MACHINE_END  MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board") -	.boot_params	= 0x80000100, +	.atag_offset	= 0x100,  	.reserve	= omap_reserve,  	.map_io		= omap3_map_io,  	.init_early	= omap_zoom_init_early, diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S index 48adfe9fe4f..13f98e59cfe 100644 --- a/arch/arm/mach-omap2/include/mach/debug-macro.S +++ b/arch/arm/mach-omap2/include/mach/debug-macro.S @@ -13,15 +13,10 @@  #include <linux/serial_reg.h> -#include <asm/memory.h> -  #include <plat/serial.h>  #define UART_OFFSET(addr)	((addr) & 0x00ffffff) -#define omap_uart_v2p(x)	((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET) -#define omap_uart_p2v(x)	((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET) -  		.pushsection .data  omap_uart_phys:	.word	0  omap_uart_virt:	.word	0 @@ -34,26 +29,25 @@ omap_uart_lsr:	.word	0  		 * the desired UART phys and virt addresses temporarily into  		 * the omap_uart_phys and omap_uart_virt above.  		 */ -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		/* Use omap_uart_phys/virt if already configured */ -10:		mrc	p15, 0, \rp, c1, c0 -		tst	\rp, #1			@ MMU enabled? -		ldreq	\rp, =omap_uart_v2p(omap_uart_phys)	@ MMU disabled -		ldrne	\rp, =omap_uart_phys	@ MMU enabled -		add	\rv, \rp, #4		@ omap_uart_virt -		ldr	\rp, [\rp, #0] -		ldr	\rv, [\rv, #0] +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	99f			@ already configured +		bne	100f			@ already configured  		/* Check the debug UART configuration set in uncompress.h */ -		mrc	p15, 0, \rp, c1, c0 -		tst	\rp, #1			@ MMU enabled? -		ldreq	\rp, =OMAP_UART_INFO	@ MMU not enabled -		ldrne	\rp, =omap_uart_p2v(OMAP_UART_INFO)	@ MMU enabled -		ldr	\rp, [\rp, #0] +		mov	\rp, pc +		ldr	\rv, =OMAP_UART_INFO_OFS +		and	\rp, \rp, #0xff000000 +		ldr	\rp, [\rp, \rv]  		/* Select the UART to use based on the UART1 scratchpad value */  		cmp	\rp, #0			@ no port configured? @@ -106,50 +100,47 @@ omap_uart_lsr:	.word	0  		b	98f  83:		mov	\rp, #UART_OFFSET(TI816X_UART3_BASE)  		b	98f +  95:		ldr	\rp, =ZOOM_UART_BASE -		mrc	p15, 0, \rv, c1, c0 -		tst	\rv, #1			@ MMU enabled? -		ldreq	\rv, =omap_uart_v2p(omap_uart_phys)	@ MMU disabled -		ldrne	\rv, =omap_uart_phys	@ MMU enabled -		str	\rp, [\rv, #0] +		str	\rp, [\tmp, #0]		@ omap_uart_phys  		ldr	\rp, =ZOOM_UART_VIRT -		add	\rv, \rv, #4		@ omap_uart_virt -		str	\rp, [\rv, #0] +		str	\rp, [\tmp, #4]		@ omap_uart_virt  		mov	\rp, #(UART_LSR << ZOOM_PORT_SHIFT) -		add	\rv, \rv, #4		@ omap_uart_lsr -		str	\rp, [\rv, #0] +		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 -		mrc	p15, 0, \rv, c1, c0 -		tst	\rv, #1			@ MMU enabled? -		ldreq	\rv, =omap_uart_v2p(omap_uart_phys)	@ MMU disabled -		ldrne	\rv, =omap_uart_phys	@ MMU enabled -		str	\rp, [\rv, #0] +		str	\rp, [\tmp, #0]		@ omap_uart_phys  		sub	\rp, \rp, #0x48000000	@ phys base  		add	\rp, \rp, #0xfa000000	@ virt base -		add	\rv, \rv, #4		@ omap_uart_virt -		str	\rp, [\rv, #0] +		str	\rp, [\tmp, #4]		@ omap_uart_virt  		mov	\rp, #(UART_LSR << OMAP_PORT_SHIFT) -		add	\rv, \rv, #4		@ omap_uart_lsr -		str	\rp, [\rv, #0] +		str	\rp, [\tmp, #8]		@ omap_uart_lsr  		b	10b -99: + +		.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 -		strb	\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:		mrc	p15, 0, \rd, c1, c0 -		tst	\rd, #1			@ MMU enabled? -		ldreq	\rd, =omap_uart_v2p(omap_uart_lsr)	@ MMU disabled -		ldrne	\rd, =omap_uart_lsr	@ MMU enabled -		ldr	\rd, [\rd, #0] -		ldrb	\rd, [\rx, \rd] +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 diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S index ceb8b7e593d..feb90a10945 100644 --- a/arch/arm/mach-omap2/include/mach/entry-macro.S +++ b/arch/arm/mach-omap2/include/mach/entry-macro.S @@ -78,7 +78,7 @@  4401:		ldr     \irqstat, [\base, #GIC_CPU_INTACK]  		ldr     \tmp, =1021  		bic     \irqnr, \irqstat, #0x1c00 -		cmp     \irqnr, #29 +		cmp     \irqnr, #15  		cmpcc   \irqnr, \irqnr  		cmpne   \irqnr, \tmp  		cmpcs   \irqnr, \irqnr @@ -101,18 +101,6 @@  		it	cs  		cmpcs	\irqnr, \irqnr  		.endm - -		/* As above, this assumes that irqstat and base are preserved */ - -		.macro test_for_ltirq, irqnr, irqstat, base, tmp -		bic	\irqnr, \irqstat, #0x1c00 -		mov 	\tmp, #0 -		cmp	\irqnr, #29 -		itt	eq -		moveq	\tmp, #1 -		streq	\irqstat, [\base, #GIC_CPU_EOI] -		cmp	\tmp, #0 -		.endm  #endif	/* CONFIG_SMP */  #else	/* MULTI_OMAP2 */ diff --git a/arch/arm/mach-omap2/include/mach/memory.h b/arch/arm/mach-omap2/include/mach/memory.h deleted file mode 100644 index ca6d32a917d..00000000000 --- a/arch/arm/mach-omap2/include/mach/memory.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * arch/arm/mach-omap2/include/mach/memory.h - */ - -#include <plat/memory.h> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 2ce1ce6fb4d..d6d01cb7f28 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -16,7 +16,6 @@   * it under the terms of the GNU General Public License version 2 as   * published by the Free Software Foundation.   */ -  #include <linux/module.h>  #include <linux/kernel.h>  #include <linux/init.h> @@ -250,6 +249,7 @@ static void __init _omap2_map_common_io(void)  	omap2_check_revision();  	omap_sram_init(); +	omap_init_consistent_dma_size();  }  #ifdef CONFIG_SOC_OMAP2420 diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index ce65e9329c7..889464dc7b2 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -109,12 +109,10 @@ void __init smp_init_cpus(void)  	ncores = scu_get_core_count(scu_base);  	/* sanity check */ -	if (ncores > NR_CPUS) { -		printk(KERN_WARNING -		       "OMAP4: no. of cores (%d) greater than configured " -		       "maximum of %d - clipping\n", -		       ncores, NR_CPUS); -		ncores = NR_CPUS; +	if (ncores > nr_cpu_ids) { +		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", +			ncores, nr_cpu_ids); +		ncores = nr_cpu_ids;  	}  	for (i = 0; i < ncores; i++) diff --git a/arch/arm/mach-orion5x/d2net-setup.c b/arch/arm/mach-orion5x/d2net-setup.c index 19cf5bf99f1..8c8300951f4 100644 --- a/arch/arm/mach-orion5x/d2net-setup.c +++ b/arch/arm/mach-orion5x/d2net-setup.c @@ -336,7 +336,7 @@ static void __init d2net_init(void)  #ifdef CONFIG_MACH_D2NET  MACHINE_START(D2NET, "LaCie d2 Network") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= d2net_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, @@ -348,7 +348,7 @@ MACHINE_END  #ifdef CONFIG_MACH_BIGDISK  MACHINE_START(BIGDISK, "LaCie Big Disk Network") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= d2net_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c index 6d771cbf06a..4b79a80d5e1 100644 --- a/arch/arm/mach-orion5x/db88f5281-setup.c +++ b/arch/arm/mach-orion5x/db88f5281-setup.c @@ -358,7 +358,7 @@ static void __init db88f5281_init(void)  MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board")  	/* Maintainer: Tzachi Perelstein <tzachi@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= db88f5281_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c index 6fb4908e998..343f60e9639 100644 --- a/arch/arm/mach-orion5x/dns323-setup.c +++ b/arch/arm/mach-orion5x/dns323-setup.c @@ -729,7 +729,7 @@ static void __init dns323_init(void)  /* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */  MACHINE_START(DNS323, "D-Link DNS-323")  	/* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= dns323_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/edmini_v2-setup.c b/arch/arm/mach-orion5x/edmini_v2-setup.c index b67cff0d4cf..70a4e9265f0 100644 --- a/arch/arm/mach-orion5x/edmini_v2-setup.c +++ b/arch/arm/mach-orion5x/edmini_v2-setup.c @@ -251,7 +251,7 @@ static void __init edmini_v2_init(void)  /* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */  MACHINE_START(EDMINI_V2, "LaCie Ethernet Disk mini V2")  	/* Maintainer: Christopher Moore <moore@free.fr> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= edmini_v2_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/include/mach/debug-macro.S b/arch/arm/mach-orion5x/include/mach/debug-macro.S index 5e3bf5b68ae..f340ed8f8dd 100644 --- a/arch/arm/mach-orion5x/include/mach/debug-macro.S +++ b/arch/arm/mach-orion5x/include/mach/debug-macro.S @@ -10,7 +10,7 @@  #include <mach/orion5x.h> -	.macro  addruart, rp, rv +	.macro  addruart, rp, rv, tmp  	ldr	\rp, =ORION5X_REGS_PHYS_BASE  	ldr	\rv, =ORION5X_REGS_VIRT_BASE  	orr	\rp, \rp, #0x00012000 diff --git a/arch/arm/mach-orion5x/include/mach/memory.h b/arch/arm/mach-orion5x/include/mach/memory.h deleted file mode 100644 index 6769917882f..00000000000 --- a/arch/arm/mach-orion5x/include/mach/memory.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/arm/mach-orion5x/include/mach/memory.h - * - * Marvell Orion memory definitions - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET	UL(0x00000000) - -#endif diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c index f88f54bb756..d3cd3f63258 100644 --- a/arch/arm/mach-orion5x/kurobox_pro-setup.c +++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c @@ -379,7 +379,7 @@ static void __init kurobox_pro_init(void)  #ifdef CONFIG_MACH_KUROBOX_PRO  MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro")  	/* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= kurobox_pro_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, @@ -392,7 +392,7 @@ MACHINE_END  #ifdef CONFIG_MACH_LINKSTATION_PRO  MACHINE_START(LINKSTATION_PRO, "Buffalo Linkstation Pro/Live")  	/* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= kurobox_pro_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/ls-chl-setup.c b/arch/arm/mach-orion5x/ls-chl-setup.c index 5065803ca82..9503fff404e 100644 --- a/arch/arm/mach-orion5x/ls-chl-setup.c +++ b/arch/arm/mach-orion5x/ls-chl-setup.c @@ -318,7 +318,7 @@ static void __init lschl_init(void)  MACHINE_START(LINKSTATION_LSCHL, "Buffalo Linkstation LiveV3 (LS-CHL)")  	/* Maintainer: Ash Hughes <ashley.hughes@blueyonder.co.uk> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= lschl_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/ls_hgl-setup.c b/arch/arm/mach-orion5x/ls_hgl-setup.c index 8503d0a42d4..ed6d772f4a2 100644 --- a/arch/arm/mach-orion5x/ls_hgl-setup.c +++ b/arch/arm/mach-orion5x/ls_hgl-setup.c @@ -265,7 +265,7 @@ static void __init ls_hgl_init(void)  MACHINE_START(LINKSTATION_LS_HGL, "Buffalo Linkstation LS-HGL")  	/* Maintainer: Zhu Qingsen <zhuqs@cn.fujistu.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= ls_hgl_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c index 9c82723c05c..743f7f1db18 100644 --- a/arch/arm/mach-orion5x/lsmini-setup.c +++ b/arch/arm/mach-orion5x/lsmini-setup.c @@ -267,7 +267,7 @@ static void __init lsmini_init(void)  #ifdef CONFIG_MACH_LINKSTATION_MINI  MACHINE_START(LINKSTATION_MINI, "Buffalo Linkstation Mini")  	/* Maintainer: Alexey Kopytko <alexey@kopytko.ru> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= lsmini_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/mss2-setup.c b/arch/arm/mach-orion5x/mss2-setup.c index ef3bb8e9a4c..6020e26b1c7 100644 --- a/arch/arm/mach-orion5x/mss2-setup.c +++ b/arch/arm/mach-orion5x/mss2-setup.c @@ -261,7 +261,7 @@ static void __init mss2_init(void)  MACHINE_START(MSS2, "Maxtor Shared Storage II")  	/* Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= mss2_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/mv2120-setup.c b/arch/arm/mach-orion5x/mv2120-setup.c index 525eb128685..201ae367628 100644 --- a/arch/arm/mach-orion5x/mv2120-setup.c +++ b/arch/arm/mach-orion5x/mv2120-setup.c @@ -228,7 +228,7 @@ static void __init mv2120_init(void)  /* Warning: HP uses a wrong mach-type (=526) in their bootloader */  MACHINE_START(MV2120, "HP Media Vault mv2120")  	/* Maintainer: Martin Michlmayr <tbm@cyrius.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= mv2120_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/net2big-setup.c b/arch/arm/mach-orion5x/net2big-setup.c index e43b39cc7fe..6197c79a2ec 100644 --- a/arch/arm/mach-orion5x/net2big-setup.c +++ b/arch/arm/mach-orion5x/net2big-setup.c @@ -419,7 +419,7 @@ static void __init net2big_init(void)  /* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */  MACHINE_START(NET2BIG, "LaCie 2Big Network") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= net2big_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c index 50aae6f571b..ebd6767d8e8 100644 --- a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c +++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c @@ -168,7 +168,7 @@ subsys_initcall(rd88f5181l_fxo_pci_init);  MACHINE_START(RD88F5181L_FXO, "Marvell Orion-VoIP FXO Reference Design")  	/* Maintainer: Nicolas Pitre <nico@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= rd88f5181l_fxo_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c index 35f106ac593..05db2d336b0 100644 --- a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c +++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c @@ -180,7 +180,7 @@ subsys_initcall(rd88f5181l_ge_pci_init);  MACHINE_START(RD88F5181L_GE, "Marvell Orion-VoIP GE Reference Design")  	/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= rd88f5181l_ge_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/rd88f5182-setup.c b/arch/arm/mach-orion5x/rd88f5182-setup.c index 9bb2b8bafbf..e47fa0578ae 100644 --- a/arch/arm/mach-orion5x/rd88f5182-setup.c +++ b/arch/arm/mach-orion5x/rd88f5182-setup.c @@ -305,7 +305,7 @@ static void __init rd88f5182_init(void)  MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design")  	/* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= rd88f5182_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c index 1d00df9ad46..64317251ec0 100644 --- a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c +++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c @@ -121,7 +121,7 @@ subsys_initcall(rd88f6183ap_ge_pci_init);  MACHINE_START(RD88F6183AP_GE, "Marvell Orion-1-90 AP GE Reference Design")  	/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= rd88f6183ap_ge_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c index c9dd31d3486..29f1526f7b7 100644 --- a/arch/arm/mach-orion5x/terastation_pro2-setup.c +++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c @@ -357,7 +357,7 @@ static void __init tsp2_init(void)  MACHINE_START(TERASTATION_PRO2, "Buffalo Terastation Pro II/Live")  	/* Maintainer:  Sylver Bruneau <sylver.bruneau@googlemail.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= tsp2_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c index 764307b8abf..31e51f9b4b6 100644 --- a/arch/arm/mach-orion5x/ts209-setup.c +++ b/arch/arm/mach-orion5x/ts209-setup.c @@ -322,7 +322,7 @@ static void __init qnap_ts209_init(void)  MACHINE_START(TS209, "QNAP TS-109/TS-209")  	/* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= qnap_ts209_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/ts409-setup.c b/arch/arm/mach-orion5x/ts409-setup.c index 0572dd1c8aa..0fbcc14e09d 100644 --- a/arch/arm/mach-orion5x/ts409-setup.c +++ b/arch/arm/mach-orion5x/ts409-setup.c @@ -311,7 +311,7 @@ static void __init qnap_ts409_init(void)  MACHINE_START(TS409, "QNAP TS-409")  	/* Maintainer:  Sylver Bruneau <sylver.bruneau@gmail.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= qnap_ts409_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c index 6b7b54116f3..6c75cd35c4c 100644 --- a/arch/arm/mach-orion5x/ts78xx-setup.c +++ b/arch/arm/mach-orion5x/ts78xx-setup.c @@ -621,7 +621,7 @@ static void __init ts78xx_init(void)  MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")  	/* Maintainer: Alexander Clouter <alex@digriz.org.uk> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= ts78xx_init,  	.map_io		= ts78xx_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c index cdad50bd489..b8be7d8d0cf 100644 --- a/arch/arm/mach-orion5x/wnr854t-setup.c +++ b/arch/arm/mach-orion5x/wnr854t-setup.c @@ -172,7 +172,7 @@ subsys_initcall(wnr854t_pci_init);  MACHINE_START(WNR854T, "Netgear WNR854T")  	/* Maintainer: Imre Kaloz <kaloz@openwrt.org> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= wnr854t_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c index 8f10ffd77ec..faf81a03936 100644 --- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c +++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c @@ -260,7 +260,7 @@ subsys_initcall(wrt350n_v2_pci_init);  MACHINE_START(WRT350N_V2, "Linksys WRT350N v2")  	/* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_machine	= wrt350n_v2_init,  	.map_io		= orion5x_map_io,  	.init_early	= orion5x_init_early, diff --git a/arch/arm/mach-pnx4008/core.c b/arch/arm/mach-pnx4008/core.c index 63399755f19..cdb95e726f5 100644 --- a/arch/arm/mach-pnx4008/core.c +++ b/arch/arm/mach-pnx4008/core.c @@ -264,7 +264,7 @@ extern struct sys_timer pnx4008_timer;  MACHINE_START(PNX4008, "Philips PNX4008")  	/* Maintainer: MontaVista Software Inc. */ -	.boot_params		= 0x80000100, +	.atag_offset		= 0x100,  	.map_io 		= pnx4008_map_io,  	.init_irq 		= pnx4008_init_irq,  	.init_machine 		= pnx4008_init, diff --git a/arch/arm/mach-pnx4008/include/mach/debug-macro.S b/arch/arm/mach-pnx4008/include/mach/debug-macro.S index 931afebaf06..469d60d97f5 100644 --- a/arch/arm/mach-pnx4008/include/mach/debug-macro.S +++ b/arch/arm/mach-pnx4008/include/mach/debug-macro.S @@ -11,7 +11,7 @@   *  */ -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #0x00090000  		add	\rv, \rp, #0xf4000000	@ virtual  		add	\rp, \rp, #0x40000000	@ physical diff --git a/arch/arm/mach-pnx4008/include/mach/memory.h b/arch/arm/mach-pnx4008/include/mach/memory.h deleted file mode 100644 index 1275db61cee..00000000000 --- a/arch/arm/mach-pnx4008/include/mach/memory.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * arch/arm/mach-pnx4008/include/mach/memory.h - * - * Copyright (c) 2005 Philips Semiconductors - * Copyright (c) 2005 MontaVista Software, Inc. - * - *  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. - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PLAT_PHYS_OFFSET	UL(0x80000000) - -#endif diff --git a/arch/arm/mach-prima2/include/mach/debug-macro.S b/arch/arm/mach-prima2/include/mach/debug-macro.S index bf75106333f..cd97492bb07 100644 --- a/arch/arm/mach-prima2/include/mach/debug-macro.S +++ b/arch/arm/mach-prima2/include/mach/debug-macro.S @@ -9,7 +9,7 @@  #include <mach/hardware.h>  #include <mach/uart.h> -	.macro	addruart, rp, rv +	.macro	addruart, rp, rv, tmp  	ldr	\rp, =SIRFSOC_UART1_PA_BASE		@ physical  	ldr	\rv, =SIRFSOC_UART1_VA_BASE		@ virtual  	.endm diff --git a/arch/arm/mach-prima2/include/mach/memory.h b/arch/arm/mach-prima2/include/mach/memory.h deleted file mode 100644 index 368cd5a0601..00000000000 --- a/arch/arm/mach-prima2/include/mach/memory.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * arch/arm/mach-prima2/include/mach/memory.h - * - * Copyright (c) 2010 – 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - * - * Licensed under GPLv2 or later. - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET        UL(0x00000000) - -/* - * Restrict DMA-able region to workaround silicon limitation. - * The limitation restricts buffers available for DMA to SD/MMC - * hardware to be below 256MB - */ -#define ARM_DMA_ZONE_SIZE	(SZ_256M) - -#endif diff --git a/arch/arm/mach-prima2/l2x0.c b/arch/arm/mach-prima2/l2x0.c index 9cda2057bcf..66c6387e5a0 100644 --- a/arch/arm/mach-prima2/l2x0.c +++ b/arch/arm/mach-prima2/l2x0.c @@ -13,7 +13,6 @@  #include <linux/of.h>  #include <linux/of_address.h>  #include <asm/hardware/cache-l2x0.h> -#include <mach/memory.h>  #define L2X0_ADDR_FILTERING_START       0xC00  #define L2X0_ADDR_FILTERING_END         0xC04 @@ -41,9 +40,9 @@ static int __init sirfsoc_of_l2x_init(void)  		/*  		 * set the physical memory windows L2 cache will cover  		 */ -		writel_relaxed(PLAT_PHYS_OFFSET + 1024 * 1024 * 1024, +		writel_relaxed(PHYS_OFFSET + 1024 * 1024 * 1024,  			sirfsoc_l2x_base + L2X0_ADDR_FILTERING_END); -		writel_relaxed(PLAT_PHYS_OFFSET | 0x1, +		writel_relaxed(PHYS_OFFSET | 0x1,  			sirfsoc_l2x_base + L2X0_ADDR_FILTERING_START);  		writel_relaxed(0, diff --git a/arch/arm/mach-prima2/prima2.c b/arch/arm/mach-prima2/prima2.c index f57124bdd14..ee33c3d458f 100644 --- a/arch/arm/mach-prima2/prima2.c +++ b/arch/arm/mach-prima2/prima2.c @@ -31,11 +31,12 @@ static const char *prima2cb_dt_match[] __initdata = {  MACHINE_START(PRIMA2_EVB, "prima2cb")  	/* Maintainer: Barry Song <baohua.song@csr.com> */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.init_early     = sirfsoc_of_clk_init,  	.map_io         = sirfsoc_map_lluart,  	.init_irq	= sirfsoc_of_irq_init,  	.timer		= &sirfsoc_timer, +	.dma_zone_size	= SZ_256M,  	.init_machine	= sirfsoc_mach_init,  	.dt_compat      = prima2cb_dt_match,  MACHINE_END diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index ef3e8b1e06c..7765d677adb 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c @@ -828,5 +828,5 @@ MACHINE_START(BALLOON3, "Balloon3")  	.handle_irq	= pxa27x_handle_irq,  	.timer		= &pxa_timer,  	.init_machine	= balloon3_init, -	.boot_params	= PLAT_PHYS_OFFSET + 0x100, +	.atag_offset	= 0x100,  MACHINE_END diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c index 648b0ab2bf7..4efc16d39c7 100644 --- a/arch/arm/mach-pxa/capc7117.c +++ b/arch/arm/mach-pxa/capc7117.c @@ -148,7 +148,7 @@ static void __init capc7117_init(void)  MACHINE_START(CAPC7117,  	      "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM") -	.boot_params = 0xa0000100, +	.atag_offset = 0x100,  	.map_io = pxa3xx_map_io,  	.init_irq = pxa3xx_init_irq,  	.handle_irq = pxa3xx_handle_irq, diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c index 13cf518bbbf..349896c53ab 100644 --- a/arch/arm/mach-pxa/cm-x2xx.c +++ b/arch/arm/mach-pxa/cm-x2xx.c @@ -513,7 +513,7 @@ static void __init cmx2xx_map_io(void)  #endif  MACHINE_START(ARMCORE, "Compulab CM-X2XX") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= cmx2xx_map_io,  	.nr_irqs	= CMX2XX_NR_IRQS,  	.init_irq	= cmx2xx_init_irq, diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index b6a51340270..9ac0225cd51 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -852,7 +852,7 @@ static void __init cm_x300_fixup(struct machine_desc *mdesc, struct tag *tags,  }  MACHINE_START(CM_X300, "CM-X300 module") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa3xx_map_io,  	.init_irq	= pxa3xx_init_irq,  	.handle_irq	= pxa3xx_handle_irq, diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c index 870920934ec..7db66465716 100644 --- a/arch/arm/mach-pxa/colibri-pxa270.c +++ b/arch/arm/mach-pxa/colibri-pxa270.c @@ -306,7 +306,7 @@ static void __init colibri_pxa270_income_init(void)  }  MACHINE_START(COLIBRI, "Toradex Colibri PXA270") -	.boot_params	= COLIBRI_SDRAM_BASE + 0x100, +	.atag_offset	= 0x100,  	.init_machine	= colibri_pxa270_init,  	.map_io		= pxa27x_map_io,  	.init_irq	= pxa27x_init_irq, @@ -315,7 +315,7 @@ MACHINE_START(COLIBRI, "Toradex Colibri PXA270")  MACHINE_END  MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.init_machine	= colibri_pxa270_income_init,  	.map_io		= pxa27x_map_io,  	.init_irq	= pxa27x_init_irq, diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c index 60a6781e7a8..c825e8bf2db 100644 --- a/arch/arm/mach-pxa/colibri-pxa300.c +++ b/arch/arm/mach-pxa/colibri-pxa300.c @@ -183,7 +183,7 @@ void __init colibri_pxa300_init(void)  }  MACHINE_START(COLIBRI300, "Toradex Colibri PXA300") -	.boot_params	= COLIBRI_SDRAM_BASE + 0x100, +	.atag_offset	= 0x100,  	.init_machine	= colibri_pxa300_init,  	.map_io		= pxa3xx_map_io,  	.init_irq	= pxa3xx_init_irq, diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c index d2c6631915d..692e1ffc558 100644 --- a/arch/arm/mach-pxa/colibri-pxa320.c +++ b/arch/arm/mach-pxa/colibri-pxa320.c @@ -253,7 +253,7 @@ void __init colibri_pxa320_init(void)  }  MACHINE_START(COLIBRI320, "Toradex Colibri PXA320") -	.boot_params	= COLIBRI_SDRAM_BASE + 0x100, +	.atag_offset	= 0x100,  	.init_machine	= colibri_pxa320_init,  	.map_io		= pxa3xx_map_io,  	.init_irq	= pxa3xx_init_irq, diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c index fe812eafb1f..5e2cf39e9e4 100644 --- a/arch/arm/mach-pxa/csb726.c +++ b/arch/arm/mach-pxa/csb726.c @@ -272,7 +272,7 @@ static void __init csb726_init(void)  }  MACHINE_START(CSB726, "Cogent CSB726") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io         = pxa27x_map_io,  	.init_irq       = pxa27x_init_irq,  	.handle_irq       = pxa27x_handle_irq, diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 2e37ea52b37..94acc0b01dd 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -1299,7 +1299,7 @@ static void __init em_x270_init(void)  }  MACHINE_START(EM_X270, "Compulab EM-X270") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa27x_map_io,  	.init_irq	= pxa27x_init_irq,  	.handle_irq	= pxa27x_handle_irq, @@ -1308,7 +1308,7 @@ MACHINE_START(EM_X270, "Compulab EM-X270")  MACHINE_END  MACHINE_START(EXEDA, "Compulab eXeda") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa27x_map_io,  	.init_irq	= pxa27x_init_irq,  	.handle_irq	= pxa27x_handle_irq, diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index b4599ec9d61..e823c54057f 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -189,7 +189,7 @@ static void __init e330_init(void)  MACHINE_START(E330, "Toshiba e330")  	/* Maintainer: Ian Molton (spyro@f2s.com) */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa25x_map_io,  	.nr_irqs	= ESERIES_NR_IRQS,  	.init_irq	= pxa25x_init_irq, @@ -239,7 +239,7 @@ static void __init e350_init(void)  MACHINE_START(E350, "Toshiba e350")  	/* Maintainer: Ian Molton (spyro@f2s.com) */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa25x_map_io,  	.nr_irqs	= ESERIES_NR_IRQS,  	.init_irq	= pxa25x_init_irq, @@ -362,7 +362,7 @@ static void __init e400_init(void)  MACHINE_START(E400, "Toshiba e400")  	/* Maintainer: Ian Molton (spyro@f2s.com) */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa25x_map_io,  	.nr_irqs	= ESERIES_NR_IRQS,  	.init_irq	= pxa25x_init_irq, @@ -551,7 +551,7 @@ static void __init e740_init(void)  MACHINE_START(E740, "Toshiba e740")  	/* Maintainer: Ian Molton (spyro@f2s.com) */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa25x_map_io,  	.nr_irqs	= ESERIES_NR_IRQS,  	.init_irq	= pxa25x_init_irq, @@ -743,7 +743,7 @@ static void __init e750_init(void)  MACHINE_START(E750, "Toshiba e750")  	/* Maintainer: Ian Molton (spyro@f2s.com) */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa25x_map_io,  	.nr_irqs	= ESERIES_NR_IRQS,  	.init_irq	= pxa25x_init_irq, @@ -948,7 +948,7 @@ static void __init e800_init(void)  MACHINE_START(E800, "Toshiba e800")  	/* Maintainer: Ian Molton (spyro@f2s.com) */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa25x_map_io,  	.nr_irqs	= ESERIES_NR_IRQS,  	.init_irq	= pxa25x_init_irq, diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index b73eadb9f5d..8308eee5a92 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c @@ -797,7 +797,7 @@ static void __init a780_init(void)  }  MACHINE_START(EZX_A780, "Motorola EZX A780") -	.boot_params    = 0xa0000100, +	.atag_offset    = 0x100,  	.map_io         = pxa27x_map_io,  	.nr_irqs	= EZX_NR_IRQS,  	.init_irq       = pxa27x_init_irq, @@ -863,7 +863,7 @@ static void __init e680_init(void)  }  MACHINE_START(EZX_E680, "Motorola EZX E680") -	.boot_params    = 0xa0000100, +	.atag_offset    = 0x100,  	.map_io         = pxa27x_map_io,  	.nr_irqs	= EZX_NR_IRQS,  	.init_irq       = pxa27x_init_irq, @@ -929,7 +929,7 @@ static void __init a1200_init(void)  }  MACHINE_START(EZX_A1200, "Motorola EZX A1200") -	.boot_params    = 0xa0000100, +	.atag_offset    = 0x100,  	.map_io         = pxa27x_map_io,  	.nr_irqs	= EZX_NR_IRQS,  	.init_irq       = pxa27x_init_irq, @@ -1120,7 +1120,7 @@ static void __init a910_init(void)  }  MACHINE_START(EZX_A910, "Motorola EZX A910") -	.boot_params    = 0xa0000100, +	.atag_offset    = 0x100,  	.map_io         = pxa27x_map_io,  	.nr_irqs	= EZX_NR_IRQS,  	.init_irq       = pxa27x_init_irq, @@ -1186,7 +1186,7 @@ static void __init e6_init(void)  }  MACHINE_START(EZX_E6, "Motorola EZX E6") -	.boot_params    = 0xa0000100, +	.atag_offset    = 0x100,  	.map_io         = pxa27x_map_io,  	.nr_irqs	= EZX_NR_IRQS,  	.init_irq       = pxa27x_init_irq, @@ -1226,7 +1226,7 @@ static void __init e2_init(void)  }  MACHINE_START(EZX_E2, "Motorola EZX E2") -	.boot_params    = 0xa0000100, +	.atag_offset    = 0x100,  	.map_io         = pxa27x_map_io,  	.nr_irqs	= EZX_NR_IRQS,  	.init_irq       = pxa27x_init_irq, diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index deaa111c91f..9c8208ca041 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c @@ -233,7 +233,7 @@ static void __init gumstix_init(void)  }  MACHINE_START(GUMSTIX, "Gumstix") -	.boot_params	= 0xa0000100, /* match u-boot bi_boot_params */ +	.atag_offset	= 0x100, /* match u-boot bi_boot_params */  	.map_io		= pxa25x_map_io,  	.init_irq	= pxa25x_init_irq,  	.handle_irq	= pxa25x_handle_irq, diff --git a/arch/arm/mach-pxa/h5000.c b/arch/arm/mach-pxa/h5000.c index 0a235128914..4b5e110640b 100644 --- a/arch/arm/mach-pxa/h5000.c +++ b/arch/arm/mach-pxa/h5000.c @@ -203,7 +203,7 @@ static void __init h5000_init(void)  }  MACHINE_START(H5400, "HP iPAQ H5000") -	.boot_params = 0xa0000100, +	.atag_offset = 0x100,  	.map_io = pxa25x_map_io,  	.init_irq = pxa25x_init_irq,  	.handle_irq = pxa25x_handle_irq, diff --git a/arch/arm/mach-pxa/himalaya.c b/arch/arm/mach-pxa/himalaya.c index a997d0ab287..f2c32457084 100644 --- a/arch/arm/mach-pxa/himalaya.c +++ b/arch/arm/mach-pxa/himalaya.c @@ -158,7 +158,7 @@ static void __init himalaya_init(void)  MACHINE_START(HIMALAYA, "HTC Himalaya") -	.boot_params = 0xa0000100, +	.atag_offset = 0x100,  	.map_io = pxa25x_map_io,  	.init_irq = pxa25x_init_irq,  	.handle_irq = pxa25x_handle_irq, diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index c748a473a2f..6f6368ece9b 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c @@ -838,7 +838,7 @@ static void __init hx4700_init(void)  }  MACHINE_START(H4700, "HP iPAQ HX4700") -	.boot_params  = 0xa0000100, +	.atag_offset  = 0x100,  	.map_io       = pxa27x_map_io,  	.nr_irqs      = HX4700_NR_IRQS,  	.init_irq     = pxa27x_init_irq, diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c index d427429f1f3..f78d5db758d 100644 --- a/arch/arm/mach-pxa/icontrol.c +++ b/arch/arm/mach-pxa/icontrol.c @@ -191,7 +191,7 @@ static void __init icontrol_init(void)  }  MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa3xx_map_io,  	.init_irq	= pxa3xx_init_irq,  	.handle_irq	= pxa3xx_handle_irq, diff --git a/arch/arm/mach-pxa/include/mach/debug-macro.S b/arch/arm/mach-pxa/include/mach/debug-macro.S index 7d5c75125d6..70b112e8ef6 100644 --- a/arch/arm/mach-pxa/include/mach/debug-macro.S +++ b/arch/arm/mach-pxa/include/mach/debug-macro.S @@ -13,7 +13,7 @@  #include "hardware.h" -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #0x00100000  		orr	\rv, \rp, #io_p2v(0x40000000)	@ virtual  		orr	\rp, \rp, #0x40000000		@ physical diff --git a/arch/arm/mach-pxa/include/mach/memory.h b/arch/arm/mach-pxa/include/mach/memory.h deleted file mode 100644 index d05a59727d6..00000000000 --- a/arch/arm/mach-pxa/include/mach/memory.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - *  arch/arm/mach-pxa/include/mach/memory.h - * - * Author:	Nicolas Pitre - * Copyright:	(C) 2001 MontaVista Software 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 __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PLAT_PHYS_OFFSET	UL(0xa0000000) - -#endif diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index d493a230add..8d9200f9226 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -18,6 +18,8 @@  #include <linux/io.h>  #include <linux/irq.h> +#include <asm/exception.h> +  #include <mach/hardware.h>  #include <mach/irqs.h>  #include <mach/gpio-pxa.h> diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 8f97e15e86e..0037e57e0ce 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -437,7 +437,7 @@ static void __init littleton_init(void)  }  MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleton)") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa3xx_map_io,  	.nr_irqs	= LITTLETON_NR_IRQS,  	.init_irq	= pxa3xx_init_irq, diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index a3acd968b44..64540d90895 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -498,7 +498,7 @@ static void __init lpd270_map_io(void)  MACHINE_START(LOGICPD_PXA270, "LogicPD PXA270 Card Engine")  	/* Maintainer: Peter Barada */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= lpd270_map_io,  	.nr_irqs	= LPD270_NR_IRQS,  	.init_irq	= lpd270_init_irq, diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 5fe5bcd7c0a..4b796c37af3 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -753,7 +753,7 @@ static void __init magician_init(void)  MACHINE_START(MAGICIAN, "HTC Magician") -	.boot_params = 0xa0000100, +	.atag_offset = 0x100,  	.map_io = pxa27x_map_io,  	.nr_irqs = MAGICIAN_NR_IRQS,  	.init_irq = pxa27x_init_irq, diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 6bc784bb369..0567d3965fd 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -615,7 +615,7 @@ static void __init mainstone_map_io(void)  MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")  	/* Maintainer: MontaVista Software Inc. */ -	.boot_params	= 0xa0000100,	/* BLOB boot parameter setting */ +	.atag_offset	= 0x100,	/* BLOB boot parameter setting */  	.map_io		= mainstone_map_io,  	.nr_irqs	= MAINSTONE_NR_IRQS,  	.init_irq	= mainstone_init_irq, diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index 64810f908e5..b938fc2c316 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -751,7 +751,7 @@ static void mioa701_machine_exit(void)  }  MACHINE_START(MIOA701, "MIO A701") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= &pxa27x_map_io,  	.init_irq	= &pxa27x_init_irq,  	.handle_irq	= &pxa27x_handle_irq, diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c index fb408861dbc..4af5d513c38 100644 --- a/arch/arm/mach-pxa/mp900.c +++ b/arch/arm/mach-pxa/mp900.c @@ -92,7 +92,7 @@ static void __init mp900c_init(void)  /* Maintainer - Michael Petchkovsky <mkpetch@internode.on.net> */  MACHINE_START(NEC_MP900, "MobilePro900/C") -	.boot_params	= 0xa0220100, +	.atag_offset	= 0x220100,  	.timer		= &pxa_timer,  	.map_io		= pxa25x_map_io,  	.init_irq	= pxa25x_init_irq, diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c index 6b77365ed93..3d4a2819cae 100644 --- a/arch/arm/mach-pxa/palmld.c +++ b/arch/arm/mach-pxa/palmld.c @@ -342,7 +342,7 @@ static void __init palmld_init(void)  }  MACHINE_START(PALMLD, "Palm LifeDrive") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= palmld_map_io,  	.init_irq	= pxa27x_init_irq,  	.handle_irq	= pxa27x_handle_irq, diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c index 9bd3e47486f..99d6bcf1f97 100644 --- a/arch/arm/mach-pxa/palmt5.c +++ b/arch/arm/mach-pxa/palmt5.c @@ -202,7 +202,7 @@ static void __init palmt5_init(void)  }  MACHINE_START(PALMT5, "Palm Tungsten|T5") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa27x_map_io,  	.reserve	= palmt5_reserve,  	.init_irq	= pxa27x_init_irq, diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index 6ad4a6c7bc9..6ec7caefb37 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -537,7 +537,7 @@ static void __init palmtc_init(void)  };  MACHINE_START(PALMTC, "Palm Tungsten|C") -	.boot_params 	= 0xa0000100, +	.atag_offset 	= 0x100,  	.map_io		= pxa25x_map_io,  	.init_irq	= pxa25x_init_irq,  	.handle_irq	= pxa25x_handle_irq, diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c index 664232f3e62..9376da06404 100644 --- a/arch/arm/mach-pxa/palmte2.c +++ b/arch/arm/mach-pxa/palmte2.c @@ -356,7 +356,7 @@ static void __init palmte2_init(void)  }  MACHINE_START(PALMTE2, "Palm Tungsten|E2") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa25x_map_io,  	.init_irq	= pxa25x_init_irq,  	.handle_irq	= pxa25x_handle_irq, diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c index bb27d4b688d..7346fbfa810 100644 --- a/arch/arm/mach-pxa/palmtreo.c +++ b/arch/arm/mach-pxa/palmtreo.c @@ -440,7 +440,7 @@ static void __init centro_init(void)  }  MACHINE_START(TREO680, "Palm Treo 680") -	.boot_params    = 0xa0000100, +	.atag_offset    = 0x100,  	.map_io         = pxa27x_map_io,  	.reserve	= treo_reserve,  	.init_irq       = pxa27x_init_irq, @@ -450,7 +450,7 @@ MACHINE_START(TREO680, "Palm Treo 680")  MACHINE_END  MACHINE_START(CENTRO, "Palm Centro 685") -	.boot_params    = 0xa0000100, +	.atag_offset    = 0x100,  	.map_io         = pxa27x_map_io,  	.reserve	= treo_reserve,  	.init_irq       = pxa27x_init_irq, diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index fc4285589c1..2b9e76fc2c9 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -364,7 +364,7 @@ static void __init palmtx_init(void)  }  MACHINE_START(PALMTX, "Palm T|X") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= palmtx_map_io,  	.init_irq	= pxa27x_init_irq,  	.handle_irq	= pxa27x_handle_irq, diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c index e61c1cc0551..68e18baf8e0 100644 --- a/arch/arm/mach-pxa/palmz72.c +++ b/arch/arm/mach-pxa/palmz72.c @@ -399,7 +399,7 @@ static void __init palmz72_init(void)  }  MACHINE_START(PALMZ72, "Palm Zire72") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa27x_map_io,  	.init_irq	= pxa27x_init_irq,  	.handle_irq	= pxa27x_handle_irq, diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c index ffa65dfb8c6..0b825a35353 100644 --- a/arch/arm/mach-pxa/pcm027.c +++ b/arch/arm/mach-pxa/pcm027.c @@ -258,7 +258,7 @@ static void __init pcm027_map_io(void)  MACHINE_START(PCM027, "Phytec Messtechnik GmbH phyCORE-PXA270")  	/* Maintainer: Pengutronix */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pcm027_map_io,  	.nr_irqs	= PCM027_NR_IRQS,  	.init_irq	= pxa27x_init_irq, diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index bbcd90562eb..6810cddec92 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -1086,7 +1086,7 @@ static void __init raumfeld_speaker_init(void)  #ifdef CONFIG_MACH_RAUMFELD_RC  MACHINE_START(RAUMFELD_RC, "Raumfeld Controller") -	.boot_params	= RAUMFELD_SDRAM_BASE + 0x100, +	.atag_offset	= 0x100,  	.init_machine	= raumfeld_controller_init,  	.map_io		= pxa3xx_map_io,  	.init_irq	= pxa3xx_init_irq, @@ -1097,7 +1097,7 @@ MACHINE_END  #ifdef CONFIG_MACH_RAUMFELD_CONNECTOR  MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector") -	.boot_params	= RAUMFELD_SDRAM_BASE + 0x100, +	.atag_offset	= 0x100,  	.init_machine	= raumfeld_connector_init,  	.map_io		= pxa3xx_map_io,  	.init_irq	= pxa3xx_init_irq, @@ -1108,7 +1108,7 @@ MACHINE_END  #ifdef CONFIG_MACH_RAUMFELD_SPEAKER  MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker") -	.boot_params	= RAUMFELD_SDRAM_BASE + 0x100, +	.atag_offset	= 0x100,  	.init_machine	= raumfeld_speaker_init,  	.map_io		= pxa3xx_map_io,  	.init_irq	= pxa3xx_init_irq, diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c index df4356e8aca..602d70b50f8 100644 --- a/arch/arm/mach-pxa/saar.c +++ b/arch/arm/mach-pxa/saar.c @@ -596,7 +596,7 @@ static void __init saar_init(void)  MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)")  	/* Maintainer: Eric Miao <eric.miao@marvell.com> */ -	.boot_params    = 0xa0000100, +	.atag_offset    = 0x100,  	.map_io         = pxa3xx_map_io,  	.init_irq       = pxa3xx_init_irq,  	.handle_irq       = pxa3xx_handle_irq, diff --git a/arch/arm/mach-pxa/saarb.c b/arch/arm/mach-pxa/saarb.c index eb6a10d85b0..3c988b6f718 100644 --- a/arch/arm/mach-pxa/saarb.c +++ b/arch/arm/mach-pxa/saarb.c @@ -103,7 +103,7 @@ static void __init saarb_init(void)  }  MACHINE_START(SAARB, "PXA955 Handheld Platform (aka SAARB)") -	.boot_params    = 0xa0000100, +	.atag_offset    = 0x100,  	.map_io         = pxa3xx_map_io,  	.nr_irqs	= SAARB_NR_IRQS,  	.init_irq       = pxa95x_init_irq, diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index 3f8d0af9e2f..4c9a48bef56 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c @@ -1004,7 +1004,7 @@ MACHINE_START(INTELMOTE2, "IMOTE 2")  	.handle_irq	= pxa27x_handle_irq,  	.timer		= &pxa_timer,  	.init_machine	= imote2_init, -	.boot_params	= 0xA0000100, +	.atag_offset	= 0x100,  MACHINE_END  #endif @@ -1016,6 +1016,6 @@ MACHINE_START(STARGATE2, "Stargate 2")  	.handle_irq = pxa27x_handle_irq,  	.timer = &pxa_timer,  	.init_machine = stargate2_init, -	.boot_params = 0xA0000100, +	.atag_offset = 0x100,  MACHINE_END  #endif diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c index 32fb58e01b1..ad47bb98f30 100644 --- a/arch/arm/mach-pxa/tavorevb.c +++ b/arch/arm/mach-pxa/tavorevb.c @@ -489,7 +489,7 @@ static void __init tavorevb_init(void)  MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)")  	/* Maintainer: Eric Miao <eric.miao@marvell.com> */ -	.boot_params    = 0xa0000100, +	.atag_offset    = 0x100,  	.map_io         = pxa3xx_map_io,  	.init_irq       = pxa3xx_init_irq,  	.handle_irq       = pxa3xx_handle_irq, diff --git a/arch/arm/mach-pxa/tavorevb3.c b/arch/arm/mach-pxa/tavorevb3.c index fd5a8eae0a8..fd569167302 100644 --- a/arch/arm/mach-pxa/tavorevb3.c +++ b/arch/arm/mach-pxa/tavorevb3.c @@ -125,7 +125,7 @@ static void __init evb3_init(void)  }  MACHINE_START(TAVOREVB3, "PXA950 Evaluation Board (aka TavorEVB3)") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io         = pxa3xx_map_io,  	.nr_irqs	= TAVOREVB3_NR_IRQS,  	.init_irq       = pxa3xx_init_irq, diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index c0417508f39..35bbf13724b 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -554,7 +554,7 @@ static void __init trizeps4_map_io(void)  MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")  	/* MAINTAINER("Jürgen Schindele") */ -	.boot_params	= TRIZEPS4_SDRAM_BASE + 0x100, +	.atag_offset	= 0x100,  	.init_machine	= trizeps4_init,  	.map_io		= trizeps4_map_io,  	.init_irq	= pxa27x_init_irq, @@ -564,7 +564,7 @@ MACHINE_END  MACHINE_START(TRIZEPS4WL, "Keith und Koep Trizeps IV-WL module")  	/* MAINTAINER("Jürgen Schindele") */ -	.boot_params	= TRIZEPS4_SDRAM_BASE + 0x100, +	.atag_offset	= 0x100,  	.init_machine	= trizeps4_init,  	.map_io		= trizeps4_map_io,  	.init_irq	= pxa27x_init_irq, diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index d4a3dc74e84..242ddae332d 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -992,7 +992,7 @@ static void __init viper_map_io(void)  MACHINE_START(VIPER, "Arcom/Eurotech VIPER SBC")  	/* Maintainer: Marc Zyngier <maz@misterjones.org> */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= viper_map_io,  	.init_irq	= viper_init_irq,  	.handle_irq	= pxa25x_handle_irq, diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index 5f8490ab07c..a7539a6ed1f 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -716,7 +716,7 @@ static void __init vpac270_init(void)  }  MACHINE_START(VPAC270, "Voipac PXA270") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa27x_map_io,  	.init_irq	= pxa27x_init_irq,  	.handle_irq	= pxa27x_handle_irq, diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c index acc600f5e72..54930cccbe5 100644 --- a/arch/arm/mach-pxa/xcep.c +++ b/arch/arm/mach-pxa/xcep.c @@ -180,7 +180,7 @@ static void __init xcep_init(void)  }  MACHINE_START(XCEP, "Iskratel XCEP") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.init_machine	= xcep_init,  	.map_io		= pxa25x_map_io,  	.init_irq	= pxa25x_init_irq, diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index 6c9275a20c9..84ed72de53b 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c @@ -686,7 +686,7 @@ static void z2_power_off(void)  	 */  	PSPR = 0x0;  	local_irq_disable(); -	pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP, PLAT_PHYS_OFFSET - PAGE_OFFSET); +	pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP, PHYS_OFFSET - PAGE_OFFSET);  }  #else  #define z2_power_off   NULL @@ -718,7 +718,7 @@ static void __init z2_init(void)  }  MACHINE_START(ZIPIT2, "Zipit Z2") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa27x_map_io,  	.init_irq	= pxa27x_init_irq,  	.handle_irq	= pxa27x_handle_irq, diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 99c49bcd9f7..c424e7d85ce 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -904,7 +904,7 @@ static void __init zeus_map_io(void)  MACHINE_START(ARCOM_ZEUS, "Arcom/Eurotech ZEUS")  	/* Maintainer: Marc Zyngier <maz@misterjones.org> */ -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= zeus_map_io,  	.nr_irqs	= ZEUS_NR_IRQS,  	.init_irq	= zeus_init_irq, diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 15ec66b3471..31d49689189 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -422,7 +422,7 @@ static void __init zylonite_init(void)  }  MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)") -	.boot_params	= 0xa0000100, +	.atag_offset	= 0x100,  	.map_io		= pxa3xx_map_io,  	.nr_irqs	= ZYLONITE_NR_IRQS,  	.init_irq	= pxa3xx_init_irq, diff --git a/arch/arm/mach-realview/include/mach/debug-macro.S b/arch/arm/mach-realview/include/mach/debug-macro.S index 90b687cbe04..fb4901c4ef0 100644 --- a/arch/arm/mach-realview/include/mach/debug-macro.S +++ b/arch/arm/mach-realview/include/mach/debug-macro.S @@ -33,7 +33,7 @@  #error "Unknown RealView platform"  #endif -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #DEBUG_LL_UART_OFFSET  		orr	\rv, \rp, #0xfb000000	@ virtual base  		orr	\rp, \rp, #0x10000000	@ physical base diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index 4ae943bafa9..e83c654a58d 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c @@ -52,12 +52,10 @@ void __init smp_init_cpus(void)  	ncores = scu_base ? scu_get_core_count(scu_base) : 1;  	/* sanity check */ -	if (ncores > NR_CPUS) { -		printk(KERN_WARNING -		       "Realview: no. of cores (%d) greater than configured " -		       "maximum of %d - clipping\n", -		       ncores, NR_CPUS); -		ncores = NR_CPUS; +	if (ncores > nr_cpu_ids) { +		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", +			ncores, nr_cpu_ids); +		ncores = nr_cpu_ids;  	}  	for (i = 0; i < ncores; i++) diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 7a4e3b18cb3..026c66ad7ec 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -463,7 +463,7 @@ static void __init realview_eb_init(void)  MACHINE_START(REALVIEW_EB, "ARM-RealView EB")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ -	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100, +	.atag_offset	= 0x100,  	.fixup		= realview_fixup,  	.map_io		= realview_eb_map_io,  	.init_early	= realview_init_early, diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index ad5671acb66..7263dea7777 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c @@ -358,7 +358,7 @@ static void __init realview_pb1176_init(void)  MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ -	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100, +	.atag_offset	= 0x100,  	.fixup		= realview_pb1176_fixup,  	.map_io		= realview_pb1176_map_io,  	.init_early	= realview_init_early, diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index b43644b3685..671ad6d6ff0 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c @@ -360,7 +360,7 @@ static void __init realview_pb11mp_init(void)  MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ -	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100, +	.atag_offset	= 0x100,  	.fixup		= realview_fixup,  	.map_io		= realview_pb11mp_map_io,  	.init_early	= realview_init_early, diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index 763e8f38c15..cbf22df4ad5 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c @@ -310,7 +310,7 @@ static void __init realview_pba8_init(void)  MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ -	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100, +	.atag_offset	= 0x100,  	.fixup		= realview_fixup,  	.map_io		= realview_pba8_map_io,  	.init_early	= realview_init_early, diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c index 363b0ab5615..8ec7e52618b 100644 --- a/arch/arm/mach-realview/realview_pbx.c +++ b/arch/arm/mach-realview/realview_pbx.c @@ -393,7 +393,7 @@ static void __init realview_pbx_init(void)  MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ -	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100, +	.atag_offset	= 0x100,  	.fixup		= realview_pbx_fixup,  	.map_io		= realview_pbx_map_io,  	.init_early	= realview_init_early, diff --git a/arch/arm/mach-rpc/include/mach/debug-macro.S b/arch/arm/mach-rpc/include/mach/debug-macro.S index 85effffdc2b..6d28cc99b12 100644 --- a/arch/arm/mach-rpc/include/mach/debug-macro.S +++ b/arch/arm/mach-rpc/include/mach/debug-macro.S @@ -11,7 +11,7 @@   *  */ -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #0x00010000  		orr	\rp, \rp, #0x00000fe0  		orr	\rv, \rp, #0xe0000000	@ virtual diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index 1e0e60d0462..8559598ab76 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c @@ -218,7 +218,7 @@ extern struct sys_timer ioc_timer;  MACHINE_START(RISCPC, "Acorn-RiscPC")  	/* Maintainer: Russell King */ -	.boot_params	= 0x10000100, +	.atag_offset	= 0x100,  	.reserve_lp0	= 1,  	.reserve_lp1	= 1,  	.map_io		= rpc_map_io, diff --git a/arch/arm/mach-s3c2400/include/mach/memory.h b/arch/arm/mach-s3c2400/include/mach/memory.h deleted file mode 100644 index 3f33670dd01..00000000000 --- a/arch/arm/mach-s3c2400/include/mach/memory.h +++ /dev/null @@ -1,20 +0,0 @@ -/* arch/arm/mach-s3c2400/include/mach/memory.h - *  from arch/arm/mach-rpc/include/mach/memory.h - * - *  Copyright 2007 Simtec Electronics - *	http://armlinux.simtec.co.uk/ - *	Ben Dooks <ben@simtec.co.uk> - * - *  Copyright (C) 1996,1997,1998 Russell King. - * - * 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_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET	UL(0x0C000000) - -#endif diff --git a/arch/arm/mach-s3c2410/include/mach/debug-macro.S b/arch/arm/mach-s3c2410/include/mach/debug-macro.S index 5882deaa56b..4135de87d1f 100644 --- a/arch/arm/mach-s3c2410/include/mach/debug-macro.S +++ b/arch/arm/mach-s3c2410/include/mach/debug-macro.S @@ -19,7 +19,7 @@  #define S3C2410_UART1_OFF (0x4000)  #define SHIFT_2440TXF (14-9) -	.macro addruart, rp, rv +	.macro addruart, rp, rv, tmp  		ldr	\rp, = S3C24XX_PA_UART  		ldr	\rv, = S3C24XX_VA_UART  #if CONFIG_DEBUG_S3C_UART != 0 diff --git a/arch/arm/mach-s3c2410/include/mach/memory.h b/arch/arm/mach-s3c2410/include/mach/memory.h deleted file mode 100644 index f92b97b89c0..00000000000 --- a/arch/arm/mach-s3c2410/include/mach/memory.h +++ /dev/null @@ -1,16 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/memory.h - *  from arch/arm/mach-rpc/include/mach/memory.h - * - *  Copyright (C) 1996,1997,1998 Russell King. - * - * 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_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET	UL(0x30000000) - -#endif diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c index dabc141243f..79838942b0a 100644 --- a/arch/arm/mach-s3c2410/mach-amlm5900.c +++ b/arch/arm/mach-s3c2410/mach-amlm5900.c @@ -236,7 +236,7 @@ static void __init amlm5900_init(void)  }  MACHINE_START(AML_M5900, "AML_M5900") -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= amlm5900_map_io,  	.init_irq	= s3c24xx_init_irq,  	.init_machine	= amlm5900_init, diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 1e2d536adda..a20ae1ad406 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -657,7 +657,7 @@ static void __init bast_init(void)  MACHINE_START(BAST, "Simtec-BAST")  	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= bast_map_io,  	.init_irq	= s3c24xx_init_irq,  	.init_machine	= bast_init, diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 2a2fa062013..556c535829f 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -744,7 +744,7 @@ static void __init h1940_init(void)  MACHINE_START(H1940, "IPAQ-H1940")  	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= h1940_map_io,  	.reserve	= h1940_reserve,  	.init_irq	= h1940_init_irq, diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 079dcaa602d..1dc3e323441 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -586,7 +586,7 @@ MACHINE_START(N30, "Acer-N30")  	/* Maintainer: Christer Weinigel <christer@weinigel.se>,  				Ben Dooks <ben-linux@fluff.org>  	*/ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.timer		= &s3c24xx_timer,  	.init_machine	= n30_init,  	.init_irq	= s3c24xx_init_irq, @@ -596,7 +596,7 @@ MACHINE_END  MACHINE_START(N35, "Acer-N35")  	/* Maintainer: Christer Weinigel <christer@weinigel.se>  	*/ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.timer		= &s3c24xx_timer,  	.init_machine	= n30_init,  	.init_irq	= s3c24xx_init_irq, diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c index 0aa16cd5acb..f03f3fd9cec 100644 --- a/arch/arm/mach-s3c2410/mach-otom.c +++ b/arch/arm/mach-s3c2410/mach-otom.c @@ -116,7 +116,7 @@ static void __init otom11_init(void)  MACHINE_START(OTOM, "Nex Vision - Otom 1.1")  	/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= otom11_map_io,  	.init_machine	= otom11_init,  	.init_irq	= s3c24xx_init_irq, diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c index f44f77531b1..367d376deb9 100644 --- a/arch/arm/mach-s3c2410/mach-qt2410.c +++ b/arch/arm/mach-s3c2410/mach-qt2410.c @@ -344,7 +344,7 @@ static void __init qt2410_machine_init(void)  }  MACHINE_START(QT2410, "QT2410") -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= qt2410_map_io,  	.init_irq	= s3c24xx_init_irq,  	.init_machine	= qt2410_machine_init, diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c index e17f03387ab..99c9dfdb71c 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/arch/arm/mach-s3c2410/mach-smdk2410.c @@ -111,7 +111,7 @@ static void __init smdk2410_init(void)  MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch  				    * to SMDK2410 */  	/* Maintainer: Jonas Dietsche */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= smdk2410_map_io,  	.init_irq	= s3c24xx_init_irq,  	.init_machine	= smdk2410_init, diff --git a/arch/arm/mach-s3c2410/mach-tct_hammer.c b/arch/arm/mach-s3c2410/mach-tct_hammer.c index 43c2b831b9e..e0d0b6fb280 100644 --- a/arch/arm/mach-s3c2410/mach-tct_hammer.c +++ b/arch/arm/mach-s3c2410/mach-tct_hammer.c @@ -146,7 +146,7 @@ static void __init tct_hammer_init(void)  }  MACHINE_START(TCT_HAMMER, "TCT_HAMMER") -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= tct_hammer_map_io,  	.init_irq	= s3c24xx_init_irq,  	.init_machine	= tct_hammer_init, diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index 6ccce5a761b..df47e8e9006 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c @@ -400,7 +400,7 @@ static void __init vr1000_init(void)  MACHINE_START(VR1000, "Thorcom-VR1000")  	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= vr1000_map_io,  	.init_machine	= vr1000_init,  	.init_irq	= s3c24xx_init_irq, diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c index 5eeb47580b0..286ef1738c6 100644 --- a/arch/arm/mach-s3c2412/mach-jive.c +++ b/arch/arm/mach-s3c2412/mach-jive.c @@ -655,7 +655,7 @@ static void __init jive_machine_init(void)  MACHINE_START(JIVE, "JIVE")  	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c24xx_init_irq,  	.map_io		= jive_map_io, diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c index 834cfb61bcf..d6325ede9f2 100644 --- a/arch/arm/mach-s3c2412/mach-smdk2413.c +++ b/arch/arm/mach-s3c2412/mach-smdk2413.c @@ -128,7 +128,7 @@ static void __init smdk2413_machine_init(void)  MACHINE_START(S3C2413, "S3C2413")  	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.fixup		= smdk2413_fixup,  	.init_irq	= s3c24xx_init_irq, @@ -139,7 +139,7 @@ MACHINE_END  MACHINE_START(SMDK2412, "SMDK2412")  	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.fixup		= smdk2413_fixup,  	.init_irq	= s3c24xx_init_irq, @@ -150,7 +150,7 @@ MACHINE_END  MACHINE_START(SMDK2413, "SMDK2413")  	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.fixup		= smdk2413_fixup,  	.init_irq	= s3c24xx_init_irq, diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c index 83544ebe20a..5955c15018b 100644 --- a/arch/arm/mach-s3c2412/mach-vstms.c +++ b/arch/arm/mach-s3c2412/mach-vstms.c @@ -156,7 +156,7 @@ static void __init vstms_init(void)  }  MACHINE_START(VSTMS, "VSTMS") -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.fixup		= vstms_fixup,  	.init_irq	= s3c24xx_init_irq, diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c index ac27ebb31c9..a9eee531ca7 100644 --- a/arch/arm/mach-s3c2416/mach-smdk2416.c +++ b/arch/arm/mach-s3c2416/mach-smdk2416.c @@ -245,7 +245,7 @@ static void __init smdk2416_machine_init(void)  MACHINE_START(SMDK2416, "SMDK2416")  	/* Maintainer: Yauhen Kharuzhy <jekhor@gmail.com> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c24xx_init_irq,  	.map_io		= smdk2416_map_io, diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c index d7086788b1f..74f92fc3fd0 100644 --- a/arch/arm/mach-s3c2440/mach-anubis.c +++ b/arch/arm/mach-s3c2440/mach-anubis.c @@ -498,7 +498,7 @@ static void __init anubis_init(void)  MACHINE_START(ANUBIS, "Simtec-Anubis")  	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= anubis_map_io,  	.init_machine	= anubis_init,  	.init_irq	= s3c24xx_init_irq, diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c index 6c98b789b8c..38887ee0c78 100644 --- a/arch/arm/mach-s3c2440/mach-at2440evb.c +++ b/arch/arm/mach-s3c2440/mach-at2440evb.c @@ -233,7 +233,7 @@ static void __init at2440evb_init(void)  MACHINE_START(AT2440EVB, "AT2440EVB") -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= at2440evb_map_io,  	.init_machine	= at2440evb_init,  	.init_irq	= s3c24xx_init_irq, diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c index c10ddf4ed7f..de1e0ff46ce 100644 --- a/arch/arm/mach-s3c2440/mach-gta02.c +++ b/arch/arm/mach-s3c2440/mach-gta02.c @@ -595,7 +595,7 @@ static void __init gta02_machine_init(void)  MACHINE_START(NEO1973_GTA02, "GTA02")  	/* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= gta02_map_io,  	.init_irq	= s3c24xx_init_irq,  	.init_machine	= gta02_machine_init, diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c index fc2dc0b3d4f..91fe0b4c95f 100644 --- a/arch/arm/mach-s3c2440/mach-mini2440.c +++ b/arch/arm/mach-s3c2440/mach-mini2440.c @@ -676,7 +676,7 @@ static void __init mini2440_init(void)  MACHINE_START(MINI2440, "MINI2440")  	/* Maintainer: Michel Pollet <buserror@gmail.com> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= mini2440_map_io,  	.init_machine	= mini2440_init,  	.init_irq	= s3c24xx_init_irq, diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c index 37dd306fb7d..61c0bf14816 100644 --- a/arch/arm/mach-s3c2440/mach-nexcoder.c +++ b/arch/arm/mach-s3c2440/mach-nexcoder.c @@ -151,7 +151,7 @@ static void __init nexcoder_init(void)  MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")  	/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= nexcoder_map_io,  	.init_machine	= nexcoder_init,  	.init_irq	= s3c24xx_init_irq, diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c index d8853639331..dc142ebf8cb 100644 --- a/arch/arm/mach-s3c2440/mach-osiris.c +++ b/arch/arm/mach-s3c2440/mach-osiris.c @@ -447,7 +447,7 @@ static void __init osiris_init(void)  MACHINE_START(OSIRIS, "Simtec-OSIRIS")  	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= osiris_map_io,  	.init_irq	= s3c24xx_init_irq,  	.init_machine	= osiris_init, diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c index 27ea95096fe..684dbb3567f 100644 --- a/arch/arm/mach-s3c2440/mach-rx1950.c +++ b/arch/arm/mach-s3c2440/mach-rx1950.c @@ -825,7 +825,7 @@ static void __init rx1950_reserve(void)  MACHINE_START(RX1950, "HP iPAQ RX1950")      /* Maintainers: Vasily Khoruzhick */ -	.boot_params = S3C2410_SDRAM_PA + 0x100, +	.atag_offset = 0x100,  	.map_io = rx1950_map_io,  	.reserve	= rx1950_reserve,  	.init_irq = s3c24xx_init_irq, diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c index 1472b1a5b2f..e19499c2f90 100644 --- a/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/arch/arm/mach-s3c2440/mach-rx3715.c @@ -218,7 +218,7 @@ static void __init rx3715_init_machine(void)  MACHINE_START(RX3715, "IPAQ-RX3715")  	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.map_io		= rx3715_map_io,  	.reserve	= rx3715_reserve,  	.init_irq	= rx3715_init_irq, diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c index eedfe0f1164..36eeb4197a8 100644 --- a/arch/arm/mach-s3c2440/mach-smdk2440.c +++ b/arch/arm/mach-s3c2440/mach-smdk2440.c @@ -175,7 +175,7 @@ static void __init smdk2440_machine_init(void)  MACHINE_START(S3C2440, "SMDK2440")  	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c24xx_init_irq,  	.map_io		= smdk2440_map_io, diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c index 514275e43ca..bec107e0044 100644 --- a/arch/arm/mach-s3c2443/mach-smdk2443.c +++ b/arch/arm/mach-s3c2443/mach-smdk2443.c @@ -139,7 +139,7 @@ static void __init smdk2443_machine_init(void)  MACHINE_START(SMDK2443, "SMDK2443")  	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */ -	.boot_params	= S3C2410_SDRAM_PA + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c24xx_init_irq,  	.map_io		= smdk2443_map_io, diff --git a/arch/arm/mach-s3c64xx/cpu.c b/arch/arm/mach-s3c64xx/cpu.c index 374e45e566b..8dc05763a7e 100644 --- a/arch/arm/mach-s3c64xx/cpu.c +++ b/arch/arm/mach-s3c64xx/cpu.c @@ -20,6 +20,7 @@  #include <linux/serial_core.h>  #include <linux/platform_device.h>  #include <linux/io.h> +#include <linux/dma-mapping.h>  #include <mach/hardware.h>  #include <mach/map.h> @@ -145,6 +146,7 @@ void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)  	/* initialise the io descriptors we need for initialisation */  	iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));  	iotable_init(mach_desc, size); +	init_consistent_dma_size(SZ_8M);  	idcode = __raw_readl(S3C_VA_SYS + 0x118);  	if (!idcode) { diff --git a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S index a29e70550c7..c0c076a90f2 100644 --- a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S +++ b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S @@ -21,7 +21,7 @@  	 * aligned and add in the offset when we load the value here.  	 */ -	.macro addruart, rp, rv +	.macro addruart, rp, rv, tmp  		ldr	\rp, = S3C_PA_UART  		ldr	\rv, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)  #if CONFIG_DEBUG_S3C_UART != 0 diff --git a/arch/arm/mach-s3c64xx/include/mach/memory.h b/arch/arm/mach-s3c64xx/include/mach/memory.h deleted file mode 100644 index 4760cdae1eb..00000000000 --- a/arch/arm/mach-s3c64xx/include/mach/memory.h +++ /dev/null @@ -1,20 +0,0 @@ -/* arch/arm/mach-s3c6400/include/mach/memory.h - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - *      Ben Dooks <ben@simtec.co.uk> - *      http://armlinux.simtec.co.uk/ - * - * 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_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET     UL(0x50000000) - -#define CONSISTENT_DMA_SIZE	SZ_8M - -#endif diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c index cb8864327ac..d164a282bfb 100644 --- a/arch/arm/mach-s3c64xx/mach-anw6410.c +++ b/arch/arm/mach-s3c64xx/mach-anw6410.c @@ -233,7 +233,7 @@ static void __init anw6410_machine_init(void)  MACHINE_START(ANW6410, "A&W6410")  	/* Maintainer: Kwangwoo Lee <kwangwoo.lee@gmail.com> */ -	.boot_params	= S3C64XX_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c6410_init_irq,  	.map_io		= anw6410_map_io, diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index af0c2fe1ea3..4c76e08423f 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -766,7 +766,7 @@ static void __init crag6410_machine_init(void)  MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410")  	/* Maintainer: Mark Brown <broonie@opensource.wolfsonmicro.com> */ -	.boot_params	= S3C64XX_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c6410_init_irq,  	.map_io		= crag6410_map_io,  	.init_machine	= crag6410_machine_init, diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c index b3d93cc8dde..19a0887e1c1 100644 --- a/arch/arm/mach-s3c64xx/mach-hmt.c +++ b/arch/arm/mach-s3c64xx/mach-hmt.c @@ -265,7 +265,7 @@ static void __init hmt_machine_init(void)  MACHINE_START(HMT, "Airgoo-HMT")  	/* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */ -	.boot_params	= S3C64XX_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c6410_init_irq,  	.map_io		= hmt_map_io,  	.init_machine	= hmt_machine_init, diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c index 527f49bd1b5..e91f63f7a49 100644 --- a/arch/arm/mach-s3c64xx/mach-mini6410.c +++ b/arch/arm/mach-s3c64xx/mach-mini6410.c @@ -349,7 +349,7 @@ static void __init mini6410_machine_init(void)  MACHINE_START(MINI6410, "MINI6410")  	/* Maintainer: Darius Augulis <augulis.darius@gmail.com> */ -	.boot_params	= S3C64XX_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c6410_init_irq,  	.map_io		= mini6410_map_io,  	.init_machine	= mini6410_machine_init, diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c index 01c6857c5b6..c30f2e5e0d8 100644 --- a/arch/arm/mach-s3c64xx/mach-ncp.c +++ b/arch/arm/mach-s3c64xx/mach-ncp.c @@ -97,7 +97,7 @@ static void __init ncp_machine_init(void)  MACHINE_START(NCP, "NCP")  	/* Maintainer: Samsung Electronics */ -	.boot_params	= S3C64XX_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c6410_init_irq,  	.map_io		= ncp_map_io,  	.init_machine	= ncp_machine_init, diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c index 95b04b1729e..10870cb5b39 100644 --- a/arch/arm/mach-s3c64xx/mach-real6410.c +++ b/arch/arm/mach-s3c64xx/mach-real6410.c @@ -329,7 +329,7 @@ static void __init real6410_machine_init(void)  MACHINE_START(REAL6410, "REAL6410")  	/* Maintainer: Darius Augulis <augulis.darius@gmail.com> */ -	.boot_params	= S3C64XX_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c6410_init_irq,  	.map_io		= real6410_map_io, diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c index 342e8dfddf8..cbb57ded3d9 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq5.c +++ b/arch/arm/mach-s3c64xx/mach-smartq5.c @@ -146,7 +146,7 @@ static void __init smartq5_machine_init(void)  MACHINE_START(SMARTQ5, "SmartQ 5")  	/* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */ -	.boot_params	= S3C64XX_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c6410_init_irq,  	.map_io		= smartq_map_io,  	.init_machine	= smartq5_machine_init, diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c index 57963977da8..04f914b85fd 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq7.c +++ b/arch/arm/mach-s3c64xx/mach-smartq7.c @@ -162,7 +162,7 @@ static void __init smartq7_machine_init(void)  MACHINE_START(SMARTQ7, "SmartQ 7")  	/* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */ -	.boot_params	= S3C64XX_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c6410_init_irq,  	.map_io		= smartq_map_io,  	.init_machine	= smartq7_machine_init, diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c index 3cca642f1e6..6fd5e95f8f7 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6400.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c @@ -85,7 +85,7 @@ static void __init smdk6400_machine_init(void)  MACHINE_START(SMDK6400, "SMDK6400")  	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */ -	.boot_params	= S3C64XX_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c6400_init_irq,  	.map_io		= smdk6400_map_io, diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index a9f3183e029..7b66ede9fbc 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -703,7 +703,7 @@ static void __init smdk6410_machine_init(void)  MACHINE_START(SMDK6410, "SMDK6410")  	/* Maintainer: Ben Dooks <ben-linux@fluff.org> */ -	.boot_params	= S3C64XX_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s3c6410_init_irq,  	.map_io		= smdk6410_map_io, diff --git a/arch/arm/mach-s5p64x0/cpu.c b/arch/arm/mach-s5p64x0/cpu.c index a5c00952ea3..8a938542c54 100644 --- a/arch/arm/mach-s5p64x0/cpu.c +++ b/arch/arm/mach-s5p64x0/cpu.c @@ -20,6 +20,7 @@  #include <linux/serial_core.h>  #include <linux/platform_device.h>  #include <linux/sched.h> +#include <linux/dma-mapping.h>  #include <asm/mach/arch.h>  #include <asm/mach/map.h> @@ -111,6 +112,7 @@ void __init s5p6440_map_io(void)  	iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));  	iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc)); +	init_consistent_dma_size(SZ_8M);  }  void __init s5p6450_map_io(void) @@ -120,6 +122,7 @@ void __init s5p6450_map_io(void)  	iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));  	iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc)); +	init_consistent_dma_size(SZ_8M);  }  /* diff --git a/arch/arm/mach-s5p64x0/include/mach/debug-macro.S b/arch/arm/mach-s5p64x0/include/mach/debug-macro.S index 79b04e6a6f8..e80ba3c6981 100644 --- a/arch/arm/mach-s5p64x0/include/mach/debug-macro.S +++ b/arch/arm/mach-s5p64x0/include/mach/debug-macro.S @@ -15,7 +15,7 @@  #include <plat/regs-serial.h> -	.macro addruart, rp, rv +	.macro addruart, rp, rv, tmp  		mov	\rp, #0xE0000000  		orr	\rp, \rp, #0x00100000  		ldr	\rp, [\rp, #0x118 ] diff --git a/arch/arm/mach-s5p64x0/include/mach/memory.h b/arch/arm/mach-s5p64x0/include/mach/memory.h deleted file mode 100644 index 365a6eb4b88..00000000000 --- a/arch/arm/mach-s5p64x0/include/mach/memory.h +++ /dev/null @@ -1,19 +0,0 @@ -/* linux/arch/arm/mach-s5p64x0/include/mach/memory.h - * - * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. - *		http://www.samsung.com - * - * S5P64X0 - Memory definitions - * - * 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_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H __FILE__ - -#define PLAT_PHYS_OFFSET		UL(0x20000000) -#define CONSISTENT_DMA_SIZE	SZ_8M - -#endif /* __ASM_ARCH_MEMORY_H */ diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c index 346f8dfa6f3..3b84e9bfd07 100644 --- a/arch/arm/mach-s5p64x0/mach-smdk6440.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c @@ -171,7 +171,7 @@ static void __init smdk6440_machine_init(void)  MACHINE_START(SMDK6440, "SMDK6440")  	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ -	.boot_params	= S5P64X0_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s5p6440_init_irq,  	.map_io		= smdk6440_map_io, diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c index 33f2adf8f3f..d99d29b5558 100644 --- a/arch/arm/mach-s5p64x0/mach-smdk6450.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c @@ -190,7 +190,7 @@ static void __init smdk6450_machine_init(void)  MACHINE_START(SMDK6450, "SMDK6450")  	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ -	.boot_params	= S5P64X0_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s5p6450_init_irq,  	.map_io		= smdk6450_map_io, diff --git a/arch/arm/mach-s5pc100/include/mach/debug-macro.S b/arch/arm/mach-s5pc100/include/mach/debug-macro.S index b2ba95ddf8e..694f7593700 100644 --- a/arch/arm/mach-s5pc100/include/mach/debug-macro.S +++ b/arch/arm/mach-s5pc100/include/mach/debug-macro.S @@ -22,7 +22,7 @@  	 * aligned and add in the offset when we load the value here.  	 */ -	.macro addruart, rp, rv +	.macro addruart, rp, rv, tmp  		ldr	\rp, = S3C_PA_UART  		ldr	\rv, = S3C_VA_UART  #if CONFIG_DEBUG_S3C_UART != 0 diff --git a/arch/arm/mach-s5pc100/include/mach/memory.h b/arch/arm/mach-s5pc100/include/mach/memory.h deleted file mode 100644 index bda4e79fd5f..00000000000 --- a/arch/arm/mach-s5pc100/include/mach/memory.h +++ /dev/null @@ -1,18 +0,0 @@ -/* arch/arm/mach-s5pc100/include/mach/memory.h - * - * Copyright 2008 Samsung Electronics Co. - *      Byungho Min <bhmin@samsung.com> - * - * Based on mach-s3c6400/include/mach/memory.h - * - * 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_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET     	UL(0x20000000) - -#endif diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c index 227d8908aab..688f45b7cd0 100644 --- a/arch/arm/mach-s5pc100/mach-smdkc100.c +++ b/arch/arm/mach-s5pc100/mach-smdkc100.c @@ -254,7 +254,7 @@ static void __init smdkc100_machine_init(void)  MACHINE_START(SMDKC100, "SMDKC100")  	/* Maintainer: Byungho Min <bhmin@samsung.com> */ -	.boot_params	= S5P_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s5pc100_init_irq,  	.map_io		= smdkc100_map_io,  	.init_machine	= smdkc100_machine_init, diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c index 79907ec78d4..91145720822 100644 --- a/arch/arm/mach-s5pv210/cpu.c +++ b/arch/arm/mach-s5pv210/cpu.c @@ -20,6 +20,7 @@  #include <linux/sysdev.h>  #include <linux/platform_device.h>  #include <linux/sched.h> +#include <linux/dma-mapping.h>  #include <asm/mach/arch.h>  #include <asm/mach/map.h> @@ -119,6 +120,7 @@ static void s5pv210_sw_reset(void)  void __init s5pv210_map_io(void)  {  	iotable_init(s5pv210_iodesc, ARRAY_SIZE(s5pv210_iodesc)); +	init_consistent_dma_size(14 << 20);  	/* initialise device information early */  	s5pv210_default_sdhci0(); diff --git a/arch/arm/mach-s5pv210/include/mach/debug-macro.S b/arch/arm/mach-s5pv210/include/mach/debug-macro.S index 169fe654a59..79e55597ab6 100644 --- a/arch/arm/mach-s5pv210/include/mach/debug-macro.S +++ b/arch/arm/mach-s5pv210/include/mach/debug-macro.S @@ -21,7 +21,7 @@  	 * aligned and add in the offset when we load the value here.  	 */ -	.macro addruart, rp, rv +	.macro addruart, rp, rv, tmp  		ldr	\rp, = S3C_PA_UART  		ldr	\rv, = S3C_VA_UART  #if CONFIG_DEBUG_S3C_UART != 0 diff --git a/arch/arm/mach-s5pv210/include/mach/memory.h b/arch/arm/mach-s5pv210/include/mach/memory.h index 7b5fcf0da0c..2d3cfa221d5 100644 --- a/arch/arm/mach-s5pv210/include/mach/memory.h +++ b/arch/arm/mach-s5pv210/include/mach/memory.h @@ -14,7 +14,6 @@  #define __ASM_ARCH_MEMORY_H  #define PLAT_PHYS_OFFSET		UL(0x20000000) -#define CONSISTENT_DMA_SIZE	(SZ_8M + SZ_4M + SZ_2M)  /*   * Sparsemem support diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c index 509627f2511..5811a96125f 100644 --- a/arch/arm/mach-s5pv210/mach-aquila.c +++ b/arch/arm/mach-s5pv210/mach-aquila.c @@ -678,7 +678,7 @@ MACHINE_START(AQUILA, "Aquila")  	/* Maintainers:  	   Marek Szyprowski <m.szyprowski@samsung.com>  	   Kyungmin Park <kyungmin.park@samsung.com> */ -	.boot_params	= S5P_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s5pv210_init_irq,  	.map_io		= aquila_map_io,  	.init_machine	= aquila_machine_init, diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c index 85c2d51a095..061cc7e4f48 100644 --- a/arch/arm/mach-s5pv210/mach-goni.c +++ b/arch/arm/mach-s5pv210/mach-goni.c @@ -897,7 +897,7 @@ static void __init goni_machine_init(void)  MACHINE_START(GONI, "GONI")  	/* Maintainers: Kyungmin Park <kyungmin.park@samsung.com> */ -	.boot_params	= S5P_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s5pv210_init_irq,  	.map_io		= goni_map_io,  	.init_machine	= goni_machine_init, diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c index 6c412c8cecc..f7266bb0cac 100644 --- a/arch/arm/mach-s5pv210/mach-smdkc110.c +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c @@ -136,7 +136,7 @@ static void __init smdkc110_machine_init(void)  MACHINE_START(SMDKC110, "SMDKC110")  	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ -	.boot_params	= S5P_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s5pv210_init_irq,  	.map_io		= smdkc110_map_io,  	.init_machine	= smdkc110_machine_init, diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c index 5e011fc6720..e73e3b6d41b 100644 --- a/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c @@ -319,7 +319,7 @@ static void __init smdkv210_machine_init(void)  MACHINE_START(SMDKV210, "SMDKV210")  	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */ -	.boot_params	= S5P_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s5pv210_init_irq,  	.map_io		= smdkv210_map_io,  	.init_machine	= smdkv210_machine_init, diff --git a/arch/arm/mach-s5pv210/mach-torbreck.c b/arch/arm/mach-s5pv210/mach-torbreck.c index 925fc0dc625..97cc066c536 100644 --- a/arch/arm/mach-s5pv210/mach-torbreck.c +++ b/arch/arm/mach-s5pv210/mach-torbreck.c @@ -125,7 +125,7 @@ static void __init torbreck_machine_init(void)  MACHINE_START(TORBRECK, "TORBRECK")  	/* Maintainer: Hyunchul Ko <ghcstop@gmail.com> */ -	.boot_params	= S5P_PA_SDRAM + 0x100, +	.atag_offset	= 0x100,  	.init_irq	= s5pv210_init_irq,  	.map_io		= torbreck_map_io,  	.init_machine	= torbreck_machine_init, diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index 26257df19b6..d40da5f1f37 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c @@ -447,7 +447,7 @@ static void __init assabet_map_io(void)  MACHINE_START(ASSABET, "Intel-Assabet") -	.boot_params	= 0xc0000100, +	.atag_offset	= 0x100,  	.fixup		= fixup_assabet,  	.map_io		= assabet_map_io,  	.init_irq	= sa1100_init_irq, diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index b4311b0a439..bda83e1ab07 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c @@ -302,7 +302,7 @@ static void __init badge4_map_io(void)  }  MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4") -	.boot_params	= 0xc0000100, +	.atag_offset	= 0x100,  	.map_io		= badge4_map_io,  	.init_irq	= sa1100_init_irq,  	.timer		= &sa1100_timer, diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c index 03d7376cf8a..b30733a2b82 100644 --- a/arch/arm/mach-sa1100/h3100.c +++ b/arch/arm/mach-sa1100/h3100.c @@ -84,7 +84,7 @@ static void __init h3100_mach_init(void)  }  MACHINE_START(H3100, "Compaq iPAQ H3100") -	.boot_params	= 0xc0000100, +	.atag_offset	= 0x100,  	.map_io		= h3100_map_io,  	.init_irq	= sa1100_init_irq,  	.timer		= &sa1100_timer, diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c index 965f64a836f..6fd324d9238 100644 --- a/arch/arm/mach-sa1100/h3600.c +++ b/arch/arm/mach-sa1100/h3600.c @@ -125,7 +125,7 @@ static void __init h3600_mach_init(void)  }  MACHINE_START(H3600, "Compaq iPAQ H3600") -	.boot_params	= 0xc0000100, +	.atag_offset	= 0x100,  	.map_io		= h3600_map_io,  	.init_irq	= sa1100_init_irq,  	.timer		= &sa1100_timer, diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c index db5e434a17d..30f4a551b8e 100644 --- a/arch/arm/mach-sa1100/hackkit.c +++ b/arch/arm/mach-sa1100/hackkit.c @@ -195,7 +195,7 @@ static void __init hackkit_init(void)   */  MACHINE_START(HACKKIT, "HackKit Cpu Board") -	.boot_params	= 0xc0000100, +	.atag_offset	= 0x100,  	.map_io		= hackkit_map_io,  	.init_irq	= sa1100_init_irq,  	.timer		= &sa1100_timer, diff --git a/arch/arm/mach-sa1100/include/mach/debug-macro.S b/arch/arm/mach-sa1100/include/mach/debug-macro.S index 0cd0fc9635b..530772d937a 100644 --- a/arch/arm/mach-sa1100/include/mach/debug-macro.S +++ b/arch/arm/mach-sa1100/include/mach/debug-macro.S @@ -12,7 +12,7 @@  */  #include <mach/hardware.h> -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mrc	p15, 0, \rp, c1, c0  		tst	\rp, #1			@ MMU enabled?  		moveq	\rp, #0x80000000	@ physical base address diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index 176c066aec7..0bb520d48ed 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -364,7 +364,7 @@ static void __init jornada720_mach_init(void)  MACHINE_START(JORNADA720, "HP Jornada 720")  	/* Maintainer: Kristoffer Ericson <Kristoffer.Ericson@gmail.com> */ -	.boot_params	= 0xc0000100, +	.atag_offset	= 0x100,  	.map_io		= jornada720_map_io,  	.init_irq	= sa1100_init_irq,  	.timer		= &sa1100_timer, diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c index 7b9556b5905..5bc59d0947b 100644 --- a/arch/arm/mach-sa1100/lart.c +++ b/arch/arm/mach-sa1100/lart.c @@ -61,7 +61,7 @@ static void __init lart_map_io(void)  }  MACHINE_START(LART, "LART") -	.boot_params	= 0xc0000100, +	.atag_offset	= 0x100,  	.map_io		= lart_map_io,  	.init_irq	= sa1100_init_irq,  	.init_machine	= lart_init, diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c index 72087f0658b..032f3881d14 100644 --- a/arch/arm/mach-sa1100/nanoengine.c +++ b/arch/arm/mach-sa1100/nanoengine.c @@ -111,7 +111,7 @@ static void __init nanoengine_init(void)  }  MACHINE_START(NANOENGINE, "BSE nanoEngine") -	.boot_params	= 0xc0000000, +	.atag_offset	= 0x100,  	.map_io		= nanoengine_map_io,  	.init_irq	= sa1100_init_irq,  	.timer		= &sa1100_timer, diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c index 7917b240557..1cccbf5b9e9 100644 --- a/arch/arm/mach-sa1100/shannon.c +++ b/arch/arm/mach-sa1100/shannon.c @@ -82,7 +82,7 @@ static void __init shannon_map_io(void)  }  MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)") -	.boot_params	= 0xc0000100, +	.atag_offset	= 0x100,  	.map_io		= shannon_map_io,  	.init_irq	= sa1100_init_irq,  	.timer		= &sa1100_timer, diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index cfb76077bd2..a1c2427655d 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c @@ -229,7 +229,7 @@ arch_initcall(simpad_init);  MACHINE_START(SIMPAD, "Simpad")  	/* Maintainer: Holger Freyther */ -	.boot_params	= 0xc0000100, +	.atag_offset	= 0x100,  	.map_io		= simpad_map_io,  	.init_irq	= sa1100_init_irq,  	.timer		= &sa1100_timer, diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index ac2873c8014..feda3ca7fc9 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c @@ -152,7 +152,7 @@ static struct sys_timer shark_timer = {  MACHINE_START(SHARK, "Shark")  	/* Maintainer: Alexander Schulz */ -	.boot_params	= 0x08003000, +	.atag_offset	= 0x3000,  	.map_io		= shark_map_io,  	.init_irq	= shark_init_irq,  	.timer		= &shark_timer, diff --git a/arch/arm/mach-shark/include/mach/debug-macro.S b/arch/arm/mach-shark/include/mach/debug-macro.S index a473f55dc71..20eb2bf2a42 100644 --- a/arch/arm/mach-shark/include/mach/debug-macro.S +++ b/arch/arm/mach-shark/include/mach/debug-macro.S @@ -11,7 +11,7 @@   *  */ -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #0xe0000000  		orr	\rp, \rp, #0x000003f8  		mov	\rv, \rp diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index cdfdd624d21..5fde49da399 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -37,6 +37,7 @@  #include <linux/mmc/sh_mobile_sdhi.h>  #include <linux/mfd/tmio.h>  #include <linux/sh_clk.h> +#include <linux/dma-mapping.h>  #include <video/sh_mobile_lcdc.h>  #include <video/sh_mipi_dsi.h>  #include <sound/sh_fsi.h> @@ -447,6 +448,8 @@ static struct map_desc ag5evm_io_desc[] __initdata = {  static void __init ag5evm_map_io(void)  {  	iotable_init(ag5evm_io_desc, ARRAY_SIZE(ag5evm_io_desc)); +	/* DMA memory at 0xf6000000 - 0xffdfffff */ +	init_consistent_dma_size(158 << 20);  	/* setup early devices and console here as well */  	sh73a0_add_early_devices(); diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 523f608eb8c..b622d8d3ab7 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -42,6 +42,7 @@  #include <linux/leds.h>  #include <linux/input/sh_keysc.h>  #include <linux/usb/r8a66597.h> +#include <linux/dma-mapping.h>  #include <media/sh_mobile_ceu.h>  #include <media/sh_mobile_csi2.h> @@ -1170,6 +1171,8 @@ static struct map_desc ap4evb_io_desc[] __initdata = {  static void __init ap4evb_map_io(void)  {  	iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc)); +	/* DMA memory at 0xf6000000 - 0xffdfffff */ +	init_consistent_dma_size(158 << 20);  	/* setup early devices and console here as well */  	sh7372_add_early_devices(); diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c index ef4613b993a..8b620bf0622 100644 --- a/arch/arm/mach-shmobile/board-g3evm.c +++ b/arch/arm/mach-shmobile/board-g3evm.c @@ -32,6 +32,7 @@  #include <linux/gpio.h>  #include <linux/input.h>  #include <linux/input/sh_keysc.h> +#include <linux/dma-mapping.h>  #include <mach/sh7367.h>  #include <mach/common.h>  #include <asm/mach-types.h> @@ -260,6 +261,8 @@ static struct map_desc g3evm_io_desc[] __initdata = {  static void __init g3evm_map_io(void)  {  	iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc)); +	/* DMA memory at 0xf6000000 - 0xffdfffff */ +	init_consistent_dma_size(158 << 20);  	/* setup early devices and console here as well */  	sh7367_add_early_devices(); diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c index 8e3c5559f27..7719ddc5f59 100644 --- a/arch/arm/mach-shmobile/board-g4evm.c +++ b/arch/arm/mach-shmobile/board-g4evm.c @@ -33,6 +33,7 @@  #include <linux/mmc/host.h>  #include <linux/mmc/sh_mobile_sdhi.h>  #include <linux/gpio.h> +#include <linux/dma-mapping.h>  #include <mach/sh7377.h>  #include <mach/common.h>  #include <asm/mach-types.h> @@ -274,6 +275,8 @@ static struct map_desc g4evm_io_desc[] __initdata = {  static void __init g4evm_map_io(void)  {  	iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc)); +	/* DMA memory at 0xf6000000 - 0xffdfffff */ +	init_consistent_dma_size(158 << 20);  	/* setup early devices and console here as well */  	sh7377_add_early_devices(); diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 17c19dc2560..de2253d7f15 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -45,6 +45,7 @@  #include <linux/tca6416_keypad.h>  #include <linux/usb/r8a66597.h>  #include <linux/usb/renesas_usbhs.h> +#include <linux/dma-mapping.h>  #include <video/sh_mobile_hdmi.h>  #include <video/sh_mobile_lcdc.h> @@ -1381,6 +1382,8 @@ static struct map_desc mackerel_io_desc[] __initdata = {  static void __init mackerel_map_io(void)  {  	iotable_init(mackerel_io_desc, ARRAY_SIZE(mackerel_io_desc)); +	/* DMA memory at 0xf6000000 - 0xffdfffff */ +	init_consistent_dma_size(158 << 20);  	/* setup early devices and console here as well */  	sh7372_add_early_devices(); diff --git a/arch/arm/mach-shmobile/entry-intc.S b/arch/arm/mach-shmobile/entry-intc.S index cac0a7ae208..1a1c00ca39a 100644 --- a/arch/arm/mach-shmobile/entry-intc.S +++ b/arch/arm/mach-shmobile/entry-intc.S @@ -51,7 +51,4 @@  	.macro  test_for_ipi, irqnr, irqstat, base, tmp  	.endm -	.macro  test_for_ltirq, irqnr, irqstat, base, tmp -	.endm -  	arch_irq_handler shmobile_handle_irq_intc diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S index d791f10eeac..8d4a416d428 100644 --- a/arch/arm/mach-shmobile/include/mach/entry-macro.S +++ b/arch/arm/mach-shmobile/include/mach/entry-macro.S @@ -27,8 +27,5 @@  	.macro  test_for_ipi, irqnr, irqstat, base, tmp  	.endm -	.macro  test_for_ltirq, irqnr, irqstat, base, tmp -	.endm -  	.macro  arch_ret_to_user, tmp1, tmp2  	.endm diff --git a/arch/arm/mach-shmobile/include/mach/memory.h b/arch/arm/mach-shmobile/include/mach/memory.h index ad00c3c258f..0ffbe8155c7 100644 --- a/arch/arm/mach-shmobile/include/mach/memory.h +++ b/arch/arm/mach-shmobile/include/mach/memory.h @@ -4,7 +4,4 @@  #define PLAT_PHYS_OFFSET	UL(CONFIG_MEMORY_START)  #define MEM_SIZE	UL(CONFIG_MEMORY_SIZE) -/* DMA memory at 0xf6000000 - 0xffdfffff */ -#define CONSISTENT_DMA_SIZE (158 << 20) -  #endif /* __ASM_MACH_MEMORY_H */ diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index 66f980625a3..e4e485fa253 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c @@ -56,6 +56,12 @@ void __init smp_init_cpus(void)  	unsigned int ncores = shmobile_smp_get_core_count();  	unsigned int i; +	if (ncores > nr_cpu_ids) { +		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", +			ncores, nr_cpu_ids); +		ncores = nr_cpu_ids; +	} +  	for (i = 0; i < ncores; i++)  		set_cpu_possible(i, true); diff --git a/arch/arm/mach-spear3xx/include/mach/memory.h b/arch/arm/mach-spear3xx/include/mach/memory.h deleted file mode 100644 index 51735221ea1..00000000000 --- a/arch/arm/mach-spear3xx/include/mach/memory.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-spear3xx/include/mach/memory.h - * - * Memory map for SPEAr3xx machine family - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.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 __MACH_MEMORY_H -#define __MACH_MEMORY_H - -#include <plat/memory.h> - -#endif /* __MACH_MEMORY_H */ diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c index 69006f69422..a5ff98eed1d 100644 --- a/arch/arm/mach-spear3xx/spear300_evb.c +++ b/arch/arm/mach-spear3xx/spear300_evb.c @@ -64,7 +64,7 @@ static void __init spear300_evb_init(void)  }  MACHINE_START(SPEAR300, "ST-SPEAR300-EVB") -	.boot_params	=	0x00000100, +	.atag_offset	=	0x100,  	.map_io		=	spear3xx_map_io,  	.init_irq	=	spear3xx_init_irq,  	.timer		=	&spear3xx_timer, diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c index c8684ce1f9b..45d180d5936 100644 --- a/arch/arm/mach-spear3xx/spear310_evb.c +++ b/arch/arm/mach-spear3xx/spear310_evb.c @@ -70,7 +70,7 @@ static void __init spear310_evb_init(void)  }  MACHINE_START(SPEAR310, "ST-SPEAR310-EVB") -	.boot_params	=	0x00000100, +	.atag_offset	=	0x100,  	.map_io		=	spear3xx_map_io,  	.init_irq	=	spear3xx_init_irq,  	.timer		=	&spear3xx_timer, diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c index a12b353940d..22879848d73 100644 --- a/arch/arm/mach-spear3xx/spear320_evb.c +++ b/arch/arm/mach-spear3xx/spear320_evb.c @@ -68,7 +68,7 @@ static void __init spear320_evb_init(void)  }  MACHINE_START(SPEAR320, "ST-SPEAR320-EVB") -	.boot_params	=	0x00000100, +	.atag_offset	=	0x100,  	.map_io		=	spear3xx_map_io,  	.init_irq	=	spear3xx_init_irq,  	.timer		=	&spear3xx_timer, diff --git a/arch/arm/mach-spear6xx/include/mach/memory.h b/arch/arm/mach-spear6xx/include/mach/memory.h deleted file mode 100644 index 781f088fc22..00000000000 --- a/arch/arm/mach-spear6xx/include/mach/memory.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-spear6xx/include/mach/memory.h - * - * Memory map for SPEAr6xx machine family - * - * Copyright (C) 2009 ST Microelectronics - * Rajeev Kumar<rajeev-dlh.kumar@st.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 __MACH_MEMORY_H -#define __MACH_MEMORY_H - -#include <plat/memory.h> - -#endif	/* __MACH_MEMORY_H */ diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c index f19cefe91a2..8238fe38e71 100644 --- a/arch/arm/mach-spear6xx/spear600_evb.c +++ b/arch/arm/mach-spear6xx/spear600_evb.c @@ -43,7 +43,7 @@ static void __init spear600_evb_init(void)  }  MACHINE_START(SPEAR600, "ST-SPEAR600-EVB") -	.boot_params	=	0x00000100, +	.atag_offset	=	0x100,  	.map_io		=	spear6xx_map_io,  	.init_irq	=	spear6xx_init_irq,  	.timer		=	&spear6xx_timer, diff --git a/arch/arm/mach-tcc8k/board-tcc8000-sdk.c b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c index 4cb3c2dd905..777a5bb9eed 100644 --- a/arch/arm/mach-tcc8k/board-tcc8000-sdk.c +++ b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c @@ -73,7 +73,7 @@ static void __init tcc8k_map_io(void)  }  MACHINE_START(TCC8000_SDK, "Telechips TCC8000-SDK Demo Board") -	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= tcc8k_map_io,  	.init_irq	= tcc8k_init_irq,  	.init_machine	= tcc8k_init, diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c index 846cd7d69e3..a4d1980e697 100644 --- a/arch/arm/mach-tegra/board-harmony.c +++ b/arch/arm/mach-tegra/board-harmony.c @@ -179,7 +179,7 @@ static void __init tegra_harmony_init(void)  }  MACHINE_START(HARMONY, "harmony") -	.boot_params  = 0x00000100, +	.atag_offset	= 0x100,  	.fixup		= tegra_harmony_fixup,  	.map_io         = tegra_map_common_io,  	.init_early	= tegra_init_early, diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c index ea2f79c9879..3197c4cbaa7 100644 --- a/arch/arm/mach-tegra/board-paz00.c +++ b/arch/arm/mach-tegra/board-paz00.c @@ -127,7 +127,7 @@ static void __init tegra_paz00_init(void)  }  MACHINE_START(PAZ00, "Toshiba AC100 / Dynabook AZ") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.fixup		= tegra_paz00_fixup,  	.map_io         = tegra_map_common_io,  	.init_early	= tegra_init_early, diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c index 56cbabf6aa6..9e98ac706f4 100644 --- a/arch/arm/mach-tegra/board-seaboard.c +++ b/arch/arm/mach-tegra/board-seaboard.c @@ -201,7 +201,7 @@ static void __init tegra_wario_init(void)  MACHINE_START(SEABOARD, "seaboard") -	.boot_params    = 0x00000100, +	.atag_offset    = 0x100,  	.map_io         = tegra_map_common_io,  	.init_early     = tegra_init_early,  	.init_irq       = tegra_init_irq, @@ -210,7 +210,7 @@ MACHINE_START(SEABOARD, "seaboard")  MACHINE_END  MACHINE_START(KAEN, "kaen") -	.boot_params    = 0x00000100, +	.atag_offset    = 0x100,  	.map_io         = tegra_map_common_io,  	.init_early     = tegra_init_early,  	.init_irq       = tegra_init_irq, @@ -219,7 +219,7 @@ MACHINE_START(KAEN, "kaen")  MACHINE_END  MACHINE_START(WARIO, "wario") -	.boot_params    = 0x00000100, +	.atag_offset    = 0x100,  	.map_io         = tegra_map_common_io,  	.init_early     = tegra_init_early,  	.init_irq       = tegra_init_irq, diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c index 89a6d2adc1d..8489aa8f515 100644 --- a/arch/arm/mach-tegra/board-trimslice.c +++ b/arch/arm/mach-tegra/board-trimslice.c @@ -171,7 +171,7 @@ static void __init tegra_trimslice_init(void)  }  MACHINE_START(TRIMSLICE, "trimslice") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.fixup		= tegra_trimslice_fixup,  	.map_io         = tegra_map_common_io,  	.init_early	= tegra_init_early, diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S index e0ebe65c165..619abc63aee 100644 --- a/arch/arm/mach-tegra/include/mach/debug-macro.S +++ b/arch/arm/mach-tegra/include/mach/debug-macro.S @@ -21,7 +21,7 @@  #include <mach/io.h>  #include <mach/iomap.h> -	.macro  addruart, rp, rv +	.macro  addruart, rp, rv, tmp          ldr     \rp, =IO_APB_PHYS       @ physical          ldr     \rv, =IO_APB_VIRT        @ virtual  	orr	\rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF) diff --git a/arch/arm/mach-tegra/include/mach/memory.h b/arch/arm/mach-tegra/include/mach/memory.h deleted file mode 100644 index 537db3aa81a..00000000000 --- a/arch/arm/mach-tegra/include/mach/memory.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * arch/arm/mach-tegra/include/mach/memory.h - * - * Copyright (C) 2010 Google, Inc. - * - * Author: - *	Colin Cross <ccross@google.com> - *	Erik Gilling <konkers@google.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ - -#ifndef __MACH_TEGRA_MEMORY_H -#define __MACH_TEGRA_MEMORY_H - -/* physical offset of RAM */ -#define PLAT_PHYS_OFFSET		UL(0) - -#endif - diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 0886cbccdde..7d2b5d03c1d 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -114,10 +114,10 @@ void __init smp_init_cpus(void)  {  	unsigned int i, ncores = scu_get_core_count(scu_base); -	if (ncores > NR_CPUS) { -		printk(KERN_ERR "Tegra: no. of cores (%u) greater than configured (%u), clipping\n", -			ncores, NR_CPUS); -		ncores = NR_CPUS; +	if (ncores > nr_cpu_ids) { +		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", +			ncores, nr_cpu_ids); +		ncores = nr_cpu_ids;  	}  	for (i = 0; i < ncores; i++) diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index fd435f44098..22c5ab79a74 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -25,6 +25,7 @@  #include <linux/err.h>  #include <linux/mtd/nand.h>  #include <linux/mtd/fsmc.h> +#include <linux/dma-mapping.h>  #include <asm/types.h>  #include <asm/setup.h> @@ -93,6 +94,8 @@ static struct map_desc u300_io_desc[] __initdata = {  void __init u300_map_io(void)  {  	iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc)); +	/* We enable a real big DMA buffer if need be. */ +	init_consistent_dma_size(SZ_4M);  }  /* diff --git a/arch/arm/mach-u300/include/mach/debug-macro.S b/arch/arm/mach-u300/include/mach/debug-macro.S index df715707bea..8ae8e4ab34b 100644 --- a/arch/arm/mach-u300/include/mach/debug-macro.S +++ b/arch/arm/mach-u300/include/mach/debug-macro.S @@ -10,7 +10,7 @@   */  #include <mach/hardware.h> -	.macro	addruart, rp, rv +	.macro	addruart, rp, rv, tmp  	/* If we move the address using MMU, use this. */  	ldr	\rp,	  = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address  	ldr	\rv,	  = U300_SLOW_PER_VIRT_BASE @ MMU on, virtual address diff --git a/arch/arm/mach-u300/include/mach/memory.h b/arch/arm/mach-u300/include/mach/memory.h index 888e2e351ee..7034bae95de 100644 --- a/arch/arm/mach-u300/include/mach/memory.h +++ b/arch/arm/mach-u300/include/mach/memory.h @@ -16,7 +16,7 @@  #ifdef CONFIG_MACH_U300_DUAL_RAM  #define PLAT_PHYS_OFFSET		UL(0x48000000) -#define BOOT_PARAMS_OFFSET	(PHYS_OFFSET + 0x100) +#define BOOT_PARAMS_OFFSET		0x100  #else @@ -24,19 +24,14 @@  #define PLAT_PHYS_OFFSET (0x28000000 + \  	     (CONFIG_MACH_U300_ACCESS_MEM_SIZE - \  	     (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024) +#define BOOT_PARAMS_OFFSET (0x100 + \ +	     (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1)*1024*1024*2)  #else  #define PLAT_PHYS_OFFSET (0x28000000 + \  	     (CONFIG_MACH_U300_ACCESS_MEM_SIZE +	\  	     (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024) +#define BOOT_PARAMS_OFFSET 0x100  #endif -#define BOOT_PARAMS_OFFSET (0x28000000 + \ -	    (CONFIG_MACH_U300_ACCESS_MEM_SIZE +		\ -	    (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024 + 0x100)  #endif -/* - * We enable a real big DMA buffer if need be. - */ -#define CONSISTENT_DMA_SIZE SZ_4M -  #endif diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c index 48b3b7f3996..80e7305589c 100644 --- a/arch/arm/mach-u300/u300.c +++ b/arch/arm/mach-u300/u300.c @@ -61,7 +61,7 @@ static void __init u300_init_machine(void)  MACHINE_START(U300, MACH_U300_STRING)  	/* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */ -	.boot_params	= BOOT_PARAMS_OFFSET, +	.atag_offset	= BOOT_PARAMS_OFFSET,  	.map_io		= u300_map_io,  	.reserve	= u300_reserve,  	.init_irq	= u300_init_irq, diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 537ab63c1dc..f67b83dd901 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -646,7 +646,7 @@ static void __init mop500_init_machine(void)  MACHINE_START(U8500, "ST-Ericsson MOP500 platform")  	/* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */ -	.boot_params	= 0x100, +	.atag_offset	= 0x100,  	.map_io		= u8500_map_io,  	.init_irq	= ux500_init_irq,  	/* we re-use nomadik timer here */ @@ -655,7 +655,7 @@ MACHINE_START(U8500, "ST-Ericsson MOP500 platform")  MACHINE_END  MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+") -	.boot_params	= 0x100, +	.atag_offset	= 0x100,  	.map_io		= u8500_map_io,  	.init_irq	= ux500_init_irq,  	.timer		= &ux500_timer, @@ -663,7 +663,7 @@ MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+")  MACHINE_END  MACHINE_START(SNOWBALL, "Calao Systems Snowball platform") -	.boot_params	= 0x100, +	.atag_offset	= 0x100,  	.map_io		= u8500_map_io,  	.init_irq	= ux500_init_irq,  	/* we re-use nomadik timer here */ diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c index 2d9e191bd30..e014aa749b0 100644 --- a/arch/arm/mach-ux500/board-u5500.c +++ b/arch/arm/mach-ux500/board-u5500.c @@ -118,7 +118,7 @@ static void __init u5500_init_machine(void)  }  MACHINE_START(U5500, "ST-Ericsson U5500 Platform") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= u5500_map_io,  	.init_irq	= ux500_init_irq,  	.timer		= &ux500_timer, diff --git a/arch/arm/mach-ux500/include/mach/debug-macro.S b/arch/arm/mach-ux500/include/mach/debug-macro.S index 700fb05ee81..8d74d927d4e 100644 --- a/arch/arm/mach-ux500/include/mach/debug-macro.S +++ b/arch/arm/mach-ux500/include/mach/debug-macro.S @@ -35,7 +35,7 @@  #define UX500_UART(n)	__UX500_UART(n)  #define UART_BASE	UX500_UART(CONFIG_UX500_DEBUG_UART) -	.macro	addruart, rp, rv +	.macro	addruart, rp, rv, tmp  	ldr	\rp, =UART_BASE				@ no, physical address  	ldr	\rv, =IO_ADDRESS(UART_BASE)		@ yes, virtual address  	.endm diff --git a/arch/arm/mach-ux500/include/mach/memory.h b/arch/arm/mach-ux500/include/mach/memory.h deleted file mode 100644 index 2ef697a6700..00000000000 --- a/arch/arm/mach-ux500/include/mach/memory.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 2009 ST-Ericsson - * - * 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. - */ -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PLAT_PHYS_OFFSET	UL(0x00000000) -#define BUS_OFFSET	UL(0x00000000) - -#endif diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index a33df5f4c27..eb5199102cf 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -156,12 +156,10 @@ void __init smp_init_cpus(void)  	ncores = scu_base ? scu_get_core_count(scu_base) : 1;  	/* sanity check */ -	if (ncores > NR_CPUS) { -		printk(KERN_WARNING -		       "U8500: no. of cores (%d) greater than configured " -		       "maximum of %d - clipping\n", -		       ncores, NR_CPUS); -		ncores = NR_CPUS; +	if (ncores > nr_cpu_ids) { +		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", +			ncores, nr_cpu_ids); +		ncores = nr_cpu_ids;  	}  	for (i = 0; i < ncores; i++) diff --git a/arch/arm/mach-versatile/include/mach/debug-macro.S b/arch/arm/mach-versatile/include/mach/debug-macro.S index eb2cf7dc5c4..d0fbd7f1cb0 100644 --- a/arch/arm/mach-versatile/include/mach/debug-macro.S +++ b/arch/arm/mach-versatile/include/mach/debug-macro.S @@ -11,7 +11,7 @@   *  */ -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp,      #0x001F0000  		orr	\rp, \rp, #0x00001000  		orr	\rv, \rp, #0xf1000000	@ virtual base diff --git a/arch/arm/mach-versatile/include/mach/memory.h b/arch/arm/mach-versatile/include/mach/memory.h deleted file mode 100644 index dacc9d8e4e6..00000000000 --- a/arch/arm/mach-versatile/include/mach/memory.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - *  arch/arm/mach-versatile/include/mach/memory.h - * - *  Copyright (C) 2003 ARM Limited - * - * 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_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PLAT_PHYS_OFFSET	UL(0x00000000) - -#endif diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c index f8ae64b3eed..fda4866703c 100644 --- a/arch/arm/mach-versatile/versatile_ab.c +++ b/arch/arm/mach-versatile/versatile_ab.c @@ -35,7 +35,7 @@  MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= versatile_map_io,  	.init_early	= versatile_init_early,  	.init_irq	= versatile_init_irq, diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c index 37c23dfeefb..feaf9cbe60f 100644 --- a/arch/arm/mach-versatile/versatile_pb.c +++ b/arch/arm/mach-versatile/versatile_pb.c @@ -103,7 +103,7 @@ static void __init versatile_pb_init(void)  MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= versatile_map_io,  	.init_early	= versatile_init_early,  	.init_irq	= versatile_init_irq, diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index bfd32f52c2d..2b1e836a76e 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -221,6 +221,12 @@ static void ct_ca9x4_init_cpu_map(void)  {  	int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU)); +	if (ncores > nr_cpu_ids) { +		pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", +			ncores, nr_cpu_ids); +		ncores = nr_cpu_ids; +	} +  	for (i = 0; i < ncores; ++i)  		set_cpu_possible(i, true); diff --git a/arch/arm/mach-vexpress/include/mach/debug-macro.S b/arch/arm/mach-vexpress/include/mach/debug-macro.S index 050d65e02a4..fd9e6c7ea49 100644 --- a/arch/arm/mach-vexpress/include/mach/debug-macro.S +++ b/arch/arm/mach-vexpress/include/mach/debug-macro.S @@ -12,7 +12,7 @@  #define DEBUG_LL_UART_OFFSET	0x00009000 -		.macro	addruart,rp,rv +		.macro	addruart,rp,rv,tmp  		mov	\rp, #DEBUG_LL_UART_OFFSET  		orr	\rv, \rp, #0xf8000000	@ virtual base  		orr	\rp, \rp, #0x10000000	@ physical base diff --git a/arch/arm/mach-vexpress/include/mach/memory.h b/arch/arm/mach-vexpress/include/mach/memory.h deleted file mode 100644 index 5b7fcd439d8..00000000000 --- a/arch/arm/mach-vexpress/include/mach/memory.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - *  arch/arm/mach-vexpress/include/mach/memory.h - * - *  Copyright (C) 2003 ARM Limited - * - * 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_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET		UL(0x60000000) - -#endif diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index d0d267a8d3f..1fafc324460 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -443,7 +443,7 @@ static void __init v2m_init(void)  }  MACHINE_START(VEXPRESS, "ARM-Versatile Express") -	.boot_params	= PLAT_PHYS_OFFSET + 0x00000100, +	.atag_offset	= 0x100,  	.map_io		= v2m_map_io,  	.init_early	= v2m_init_early,  	.init_irq	= v2m_init_irq, diff --git a/arch/arm/mach-vt8500/bv07.c b/arch/arm/mach-vt8500/bv07.c index 94a261d86bf..a464c758441 100644 --- a/arch/arm/mach-vt8500/bv07.c +++ b/arch/arm/mach-vt8500/bv07.c @@ -68,7 +68,7 @@ void __init bv07_init(void)  }  MACHINE_START(BV07, "Benign BV07 Mini Netbook") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.reserve	= vt8500_reserve_mem,  	.map_io		= vt8500_map_io,  	.init_irq	= vt8500_init_irq, diff --git a/arch/arm/mach-vt8500/include/mach/debug-macro.S b/arch/arm/mach-vt8500/include/mach/debug-macro.S index f1191626ad5..ca292f29d4a 100644 --- a/arch/arm/mach-vt8500/include/mach/debug-macro.S +++ b/arch/arm/mach-vt8500/include/mach/debug-macro.S @@ -11,7 +11,7 @@   *  */ -	.macro	addruart, rp, rv +	.macro	addruart, rp, rv, tmp  	mov	\rp,      #0x00200000  	orr	\rv, \rp, #0xf8000000  	orr	\rp, \rp, #0xd8000000 diff --git a/arch/arm/mach-vt8500/include/mach/memory.h b/arch/arm/mach-vt8500/include/mach/memory.h deleted file mode 100644 index 175f914eff9..00000000000 --- a/arch/arm/mach-vt8500/include/mach/memory.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - *  arch/arm/mach-vt8500/include/mach/memory.h - * - *  Copyright (C) 2003 ARM Limited - * - * 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_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PHYS_OFFSET	UL(0x00000000) - -#endif diff --git a/arch/arm/mach-vt8500/wm8505_7in.c b/arch/arm/mach-vt8500/wm8505_7in.c index e73aadbcafd..cf910a95608 100644 --- a/arch/arm/mach-vt8500/wm8505_7in.c +++ b/arch/arm/mach-vt8500/wm8505_7in.c @@ -68,7 +68,7 @@ void __init wm8505_7in_init(void)  }  MACHINE_START(WM8505_7IN_NETBOOK, "WM8505 7-inch generic netbook") -	.boot_params	= 0x00000100, +	.atag_offset	= 0x100,  	.reserve	= wm8505_reserve_mem,  	.map_io		= wm8505_map_io,  	.init_irq	= wm8505_init_irq, diff --git a/arch/arm/mach-w90x900/include/mach/memory.h b/arch/arm/mach-w90x900/include/mach/memory.h deleted file mode 100644 index f02905ba774..00000000000 --- a/arch/arm/mach-w90x900/include/mach/memory.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * arch/arm/mach-w90x900/include/mach/memory.h - * - * Copyright (c) 2008 Nuvoton technology corporation - * All rights reserved. - * - * Wan ZongShun <mcuos.com@gmail.com> - * - * Based on arch/arm/mach-s3c2410/include/mach/memory.h - * - * 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. - * - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -#define PLAT_PHYS_OFFSET	UL(0x00000000) - -#endif diff --git a/arch/arm/mach-w90x900/mach-nuc910evb.c b/arch/arm/mach-w90x900/mach-nuc910evb.c index 30fccde94fb..31c10901822 100644 --- a/arch/arm/mach-w90x900/mach-nuc910evb.c +++ b/arch/arm/mach-w90x900/mach-nuc910evb.c @@ -34,7 +34,6 @@ static void __init nuc910evb_init(void)  MACHINE_START(W90P910EVB, "W90P910EVB")  	/* Maintainer: Wan ZongShun */ -	.boot_params	= 0,  	.map_io		= nuc910evb_map_io,  	.init_irq	= nuc900_init_irq,  	.init_machine	= nuc910evb_init, diff --git a/arch/arm/mach-w90x900/mach-nuc950evb.c b/arch/arm/mach-w90x900/mach-nuc950evb.c index 590c99b96dc..4062e55a57d 100644 --- a/arch/arm/mach-w90x900/mach-nuc950evb.c +++ b/arch/arm/mach-w90x900/mach-nuc950evb.c @@ -37,7 +37,6 @@ static void __init nuc950evb_init(void)  MACHINE_START(W90P950EVB, "W90P950EVB")  	/* Maintainer: Wan ZongShun */ -	.boot_params	= 0,  	.map_io		= nuc950evb_map_io,  	.init_irq	= nuc900_init_irq,  	.init_machine	= nuc950evb_init, diff --git a/arch/arm/mach-w90x900/mach-nuc960evb.c b/arch/arm/mach-w90x900/mach-nuc960evb.c index e09c645d61b..0ab9995d5b5 100644 --- a/arch/arm/mach-w90x900/mach-nuc960evb.c +++ b/arch/arm/mach-w90x900/mach-nuc960evb.c @@ -34,7 +34,6 @@ static void __init nuc960evb_init(void)  MACHINE_START(W90N960EVB, "W90N960EVB")  	/* Maintainer: Wan ZongShun */ -	.boot_params	= 0,  	.map_io		= nuc960evb_map_io,  	.init_irq	= nuc900_init_irq,  	.init_machine	= nuc960evb_init, diff --git a/arch/arm/mach-zynq/include/mach/debug-macro.S b/arch/arm/mach-zynq/include/mach/debug-macro.S index 9f664d5eb81..3ab0be1f619 100644 --- a/arch/arm/mach-zynq/include/mach/debug-macro.S +++ b/arch/arm/mach-zynq/include/mach/debug-macro.S @@ -17,7 +17,7 @@  #include <mach/zynq_soc.h>  #include <mach/uart.h> -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		ldr	\rp, =LL_UART_PADDR	@ physical  		ldr	\rv, =LL_UART_VADDR	@ virtual  		.endm diff --git a/arch/arm/mach-zynq/include/mach/memory.h b/arch/arm/mach-zynq/include/mach/memory.h deleted file mode 100644 index 35a92634dcc..00000000000 --- a/arch/arm/mach-zynq/include/mach/memory.h +++ /dev/null @@ -1,22 +0,0 @@ -/* arch/arm/mach-zynq/include/mach/memory.h - * - *  Copyright (C) 2011 Xilinx - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - */ - -#ifndef __MACH_MEMORY_H__ -#define __MACH_MEMORY_H__ - -#include <asm/sizes.h> - -#define PLAT_PHYS_OFFSET	UL(0x0) - -#endif diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index c3ff82f92d9..01f5987eb1a 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -18,12 +18,14 @@  #include <linux/device.h>  #include <linux/dma-mapping.h>  #include <linux/highmem.h> +#include <linux/slab.h>  #include <asm/memory.h>  #include <asm/highmem.h>  #include <asm/cacheflush.h>  #include <asm/tlbflush.h>  #include <asm/sizes.h> +#include <asm/mach/arch.h>  #include "mm.h" @@ -117,26 +119,37 @@ static void __dma_free_buffer(struct page *page, size_t size)  }  #ifdef CONFIG_MMU -/* Sanity check size */ -#if (CONSISTENT_DMA_SIZE % SZ_2M) -#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB" -#endif -#define CONSISTENT_OFFSET(x)	(((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT) -#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT) -#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT) + +#define CONSISTENT_OFFSET(x)	(((unsigned long)(x) - consistent_base) >> PAGE_SHIFT) +#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - consistent_base) >> PGDIR_SHIFT)  /*   * These are the page tables (2MB each) covering uncached, DMA consistent allocations   */ -static pte_t *consistent_pte[NUM_CONSISTENT_PTES]; +static pte_t **consistent_pte; + +#define DEFAULT_CONSISTENT_DMA_SIZE SZ_2M + +unsigned long consistent_base = CONSISTENT_END - DEFAULT_CONSISTENT_DMA_SIZE; + +void __init init_consistent_dma_size(unsigned long size) +{ +	unsigned long base = CONSISTENT_END - ALIGN(size, SZ_2M); + +	BUG_ON(consistent_pte); /* Check we're called before DMA region init */ +	BUG_ON(base < VMALLOC_END); + +	/* Grow region to accommodate specified size  */ +	if (base < consistent_base) +		consistent_base = base; +}  #include "vmregion.h"  static struct arm_vmregion_head consistent_head = {  	.vm_lock	= __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock),  	.vm_list	= LIST_HEAD_INIT(consistent_head.vm_list), -	.vm_start	= CONSISTENT_BASE,  	.vm_end		= CONSISTENT_END,  }; @@ -155,7 +168,17 @@ static int __init consistent_init(void)  	pmd_t *pmd;  	pte_t *pte;  	int i = 0; -	u32 base = CONSISTENT_BASE; +	unsigned long base = consistent_base; +	unsigned long num_ptes = (CONSISTENT_END - base) >> PGDIR_SHIFT; + +	consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL); +	if (!consistent_pte) { +		pr_err("%s: no memory\n", __func__); +		return -ENOMEM; +	} + +	pr_debug("DMA memory: 0x%08lx - 0x%08lx:\n", base, CONSISTENT_END); +	consistent_head.vm_start = base;  	do {  		pgd = pgd_offset(&init_mm, base); @@ -198,7 +221,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)  	size_t align;  	int bit; -	if (!consistent_pte[0]) { +	if (!consistent_pte) {  		printk(KERN_ERR "%s: not initialised\n", __func__);  		dump_stack();  		return NULL; diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 3b5ea68acbb..aa33949fef6 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -20,6 +20,7 @@  #include <linux/highmem.h>  #include <linux/perf_event.h> +#include <asm/exception.h>  #include <asm/system.h>  #include <asm/pgtable.h>  #include <asm/tlbflush.h> diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index cc7e2d8be9a..34409a08ba0 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -653,9 +653,6 @@ void __init mem_init(void)  			"    ITCM    : 0x%08lx - 0x%08lx   (%4ld kB)\n"  #endif  			"    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n" -#ifdef CONFIG_MMU -			"    DMA     : 0x%08lx - 0x%08lx   (%4ld MB)\n" -#endif  			"    vmalloc : 0x%08lx - 0x%08lx   (%4ld MB)\n"  			"    lowmem  : 0x%08lx - 0x%08lx   (%4ld MB)\n"  #ifdef CONFIG_HIGHMEM @@ -674,9 +671,6 @@ void __init mem_init(void)  			MLK(ITCM_OFFSET, (unsigned long) itcm_end),  #endif  			MLK(FIXADDR_START, FIXADDR_TOP), -#ifdef CONFIG_MMU -			MLM(CONSISTENT_BASE, CONSISTENT_END), -#endif  			MLM(VMALLOC_START, VMALLOC_END),  			MLM(PAGE_OFFSET, (unsigned long)high_memory),  #ifdef CONFIG_HIGHMEM @@ -699,9 +693,6 @@ void __init mem_init(void)  	 * be detected at build time already.  	 */  #ifdef CONFIG_MMU -	BUILD_BUG_ON(VMALLOC_END			> CONSISTENT_BASE); -	BUG_ON(VMALLOC_END				> CONSISTENT_BASE); -  	BUILD_BUG_ON(TASK_SIZE				> MODULES_VADDR);  	BUG_ON(TASK_SIZE 				> MODULES_VADDR);  #endif diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 594d677b92c..ea9c9f3e48b 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -273,6 +273,14 @@ static struct mem_type mem_types[] = {  		.prot_l1   = PMD_TYPE_TABLE,  		.domain    = DOMAIN_KERNEL,  	}, +	[MT_MEMORY_SO] = { +		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | +				L_PTE_MT_UNCACHED, +		.prot_l1   = PMD_TYPE_TABLE, +		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_S | +				PMD_SECT_UNCACHED | PMD_SECT_XN, +		.domain    = DOMAIN_KERNEL, +	},  };  const struct mem_type *get_mem_type(unsigned int type) diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index 2e6849b41f6..88fb3d9e064 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S @@ -379,31 +379,26 @@ ENTRY(cpu_arm920_set_pte_ext)  /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */  .globl	cpu_arm920_suspend_size -.equ	cpu_arm920_suspend_size, 4 * 4 +.equ	cpu_arm920_suspend_size, 4 * 3  #ifdef CONFIG_PM_SLEEP  ENTRY(cpu_arm920_do_suspend) -	stmfd	sp!, {r4 - r7, lr} +	stmfd	sp!, {r4 - r6, lr}  	mrc	p15, 0, r4, c13, c0, 0	@ PID  	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID -	mrc	p15, 0, r6, c2, c0, 0	@ TTB address -	mrc	p15, 0, r7, c1, c0, 0	@ Control register -	stmia	r0, {r4 - r7} -	ldmfd	sp!, {r4 - r7, pc} +	mrc	p15, 0, r6, c1, c0, 0	@ Control register +	stmia	r0, {r4 - r6} +	ldmfd	sp!, {r4 - r6, pc}  ENDPROC(cpu_arm920_do_suspend)  ENTRY(cpu_arm920_do_resume)  	mov	ip, #0  	mcr	p15, 0, ip, c8, c7, 0	@ invalidate I+D TLBs  	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I+D caches -	ldmia	r0, {r4 - r7} +	ldmia	r0, {r4 - r6}  	mcr	p15, 0, r4, c13, c0, 0	@ PID  	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID -	mcr	p15, 0, r6, c2, c0, 0	@ TTB address -	mov	r0, r7			@ control register -	mov	r2, r6, lsr #14		@ get TTB0 base -	mov	r2, r2, lsl #14 -	ldr	r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \ -		     PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE +	mcr	p15, 0, r1, c2, c0, 0	@ TTB address +	mov	r0, r6			@ control register  	b	cpu_resume_mmu  ENDPROC(cpu_arm920_do_resume)  #endif diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S index cd8f79c3a28..9f8fd91f918 100644 --- a/arch/arm/mm/proc-arm926.S +++ b/arch/arm/mm/proc-arm926.S @@ -394,31 +394,26 @@ ENTRY(cpu_arm926_set_pte_ext)  /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */  .globl	cpu_arm926_suspend_size -.equ	cpu_arm926_suspend_size, 4 * 4 +.equ	cpu_arm926_suspend_size, 4 * 3  #ifdef CONFIG_PM_SLEEP  ENTRY(cpu_arm926_do_suspend) -	stmfd	sp!, {r4 - r7, lr} +	stmfd	sp!, {r4 - r6, lr}  	mrc	p15, 0, r4, c13, c0, 0	@ PID  	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID -	mrc	p15, 0, r6, c2, c0, 0	@ TTB address -	mrc	p15, 0, r7, c1, c0, 0	@ Control register -	stmia	r0, {r4 - r7} -	ldmfd	sp!, {r4 - r7, pc} +	mrc	p15, 0, r6, c1, c0, 0	@ Control register +	stmia	r0, {r4 - r6} +	ldmfd	sp!, {r4 - r6, pc}  ENDPROC(cpu_arm926_do_suspend)  ENTRY(cpu_arm926_do_resume)  	mov	ip, #0  	mcr	p15, 0, ip, c8, c7, 0	@ invalidate I+D TLBs  	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I+D caches -	ldmia	r0, {r4 - r7} +	ldmia	r0, {r4 - r6}  	mcr	p15, 0, r4, c13, c0, 0	@ PID  	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID -	mcr	p15, 0, r6, c2, c0, 0	@ TTB address -	mov	r0, r7			@ control register -	mov	r2, r6, lsr #14		@ get TTB0 base -	mov	r2, r2, lsl #14 -	ldr	r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \ -		     PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE +	mcr	p15, 0, r1, c2, c0, 0	@ TTB address +	mov	r0, r6			@ control register  	b	cpu_resume_mmu  ENDPROC(cpu_arm926_do_resume)  #endif diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S index 69e7f2ef738..7d91545d089 100644 --- a/arch/arm/mm/proc-sa1100.S +++ b/arch/arm/mm/proc-sa1100.S @@ -168,20 +168,19 @@ ENTRY(cpu_sa1100_set_pte_ext)  	mov	pc, lr  .globl	cpu_sa1100_suspend_size -.equ	cpu_sa1100_suspend_size, 4*4 +.equ	cpu_sa1100_suspend_size, 4 * 3  #ifdef CONFIG_PM_SLEEP  ENTRY(cpu_sa1100_do_suspend) -	stmfd	sp!, {r4 - r7, lr} +	stmfd	sp!, {r4 - r6, lr}  	mrc	p15, 0, r4, c3, c0, 0		@ domain ID -	mrc	p15, 0, r5, c2, c0, 0		@ translation table base addr -	mrc	p15, 0, r6, c13, c0, 0		@ PID -	mrc	p15, 0, r7, c1, c0, 0		@ control reg -	stmia	r0, {r4 - r7}			@ store cp regs -	ldmfd	sp!, {r4 - r7, pc} +	mrc	p15, 0, r5, c13, c0, 0		@ PID +	mrc	p15, 0, r6, c1, c0, 0		@ control reg +	stmia	r0, {r4 - r6}			@ store cp regs +	ldmfd	sp!, {r4 - r6, pc}  ENDPROC(cpu_sa1100_do_suspend)  ENTRY(cpu_sa1100_do_resume) -	ldmia	r0, {r4 - r7}			@ load cp regs +	ldmia	r0, {r4 - r6}			@ load cp regs  	mov	ip, #0  	mcr	p15, 0, ip, c8, c7, 0		@ flush I+D TLBs  	mcr	p15, 0, ip, c7, c7, 0		@ flush I&D cache @@ -189,13 +188,9 @@ ENTRY(cpu_sa1100_do_resume)  	mcr	p15, 0, ip, c9, c0, 5		@ allow user space to use RB  	mcr	p15, 0, r4, c3, c0, 0		@ domain ID -	mcr	p15, 0, r5, c2, c0, 0		@ translation table base addr -	mcr	p15, 0, r6, c13, c0, 0		@ PID -	mov	r0, r7				@ control register -	mov	r2, r5, lsr #14			@ get TTB0 base -	mov	r2, r2, lsl #14 -	ldr	r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \ -		     PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE +	mcr	p15, 0, r1, c2, c0, 0		@ translation table base addr +	mcr	p15, 0, r5, c13, c0, 0		@ PID +	mov	r0, r6				@ control register  	b	cpu_resume_mmu  ENDPROC(cpu_sa1100_do_resume)  #endif diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index a923aa0fd00..d061d2fa550 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -128,20 +128,18 @@ ENTRY(cpu_v6_set_pte_ext)  /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */  .globl	cpu_v6_suspend_size -.equ	cpu_v6_suspend_size, 4 * 8 +.equ	cpu_v6_suspend_size, 4 * 6  #ifdef CONFIG_PM_SLEEP  ENTRY(cpu_v6_do_suspend) -	stmfd	sp!, {r4 - r11, lr} +	stmfd	sp!, {r4 - r9, lr}  	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID -	mrc	p15, 0, r5, c13, c0, 1	@ Context ID -	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID -	mrc	p15, 0, r7, c2, c0, 0	@ Translation table base 0 -	mrc	p15, 0, r8, c2, c0, 1	@ Translation table base 1 -	mrc	p15, 0, r9, c1, c0, 1	@ auxiliary control register -	mrc	p15, 0, r10, c1, c0, 2	@ co-processor access control -	mrc	p15, 0, r11, c1, c0, 0	@ control register -	stmia	r0, {r4 - r11} -	ldmfd	sp!, {r4- r11, pc} +	mrc	p15, 0, r5, c3, c0, 0	@ Domain ID +	mrc	p15, 0, r6, c2, c0, 1	@ Translation table base 1 +	mrc	p15, 0, r7, c1, c0, 1	@ auxiliary control register +	mrc	p15, 0, r8, c1, c0, 2	@ co-processor access control +	mrc	p15, 0, r9, c1, c0, 0	@ control register +	stmia	r0, {r4 - r9} +	ldmfd	sp!, {r4- r9, pc}  ENDPROC(cpu_v6_do_suspend)  ENTRY(cpu_v6_do_resume) @@ -150,25 +148,21 @@ ENTRY(cpu_v6_do_resume)  	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache  	mcr	p15, 0, ip, c7, c15, 0	@ clean+invalidate cache  	mcr	p15, 0, ip, c7, c10, 4	@ drain write buffer -	ldmia	r0, {r4 - r11} +	mcr	p15, 0, ip, c13, c0, 1	@ set reserved context ID +	ldmia	r0, {r4 - r9}  	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID -	mcr	p15, 0, r5, c13, c0, 1	@ Context ID -	mcr	p15, 0, r6, c3, c0, 0	@ Domain ID -	mcr	p15, 0, r7, c2, c0, 0	@ Translation table base 0 -	mcr	p15, 0, r8, c2, c0, 1	@ Translation table base 1 -	mcr	p15, 0, r9, c1, c0, 1	@ auxiliary control register -	mcr	p15, 0, r10, c1, c0, 2	@ co-processor access control +	mcr	p15, 0, r5, c3, c0, 0	@ Domain ID +	ALT_SMP(orr	r1, r1, #TTB_FLAGS_SMP) +	ALT_UP(orr	r1, r1, #TTB_FLAGS_UP) +	mcr	p15, 0, r1, c2, c0, 0	@ Translation table base 0 +	mcr	p15, 0, r6, c2, c0, 1	@ Translation table base 1 +	mcr	p15, 0, r7, c1, c0, 1	@ auxiliary control register +	mcr	p15, 0, r8, c1, c0, 2	@ co-processor access control  	mcr	p15, 0, ip, c2, c0, 2	@ TTB control register  	mcr	p15, 0, ip, c7, c5, 4	@ ISB -	mov	r0, r11			@ control register -	mov	r2, r7, lsr #14		@ get TTB0 base -	mov	r2, r2, lsl #14 -	ldr	r3, cpu_resume_l1_flags +	mov	r0, r9			@ control register  	b	cpu_resume_mmu  ENDPROC(cpu_v6_do_resume) -cpu_resume_l1_flags: -	ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP) -	ALT_UP(.long  PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)  #endif  	string	cpu_v6_name, "ARMv6-compatible processor" diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 9049c0764db..6af366ce016 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -217,56 +217,50 @@ ENDPROC(cpu_v7_set_pte_ext)  /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */  .globl	cpu_v7_suspend_size -.equ	cpu_v7_suspend_size, 4 * 9 +.equ	cpu_v7_suspend_size, 4 * 7  #ifdef CONFIG_PM_SLEEP  ENTRY(cpu_v7_do_suspend) -	stmfd	sp!, {r4 - r11, lr} +	stmfd	sp!, {r4 - r10, lr}  	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID -	mrc	p15, 0, r5, c13, c0, 1	@ Context ID -	mrc	p15, 0, r6, c13, c0, 3	@ User r/o thread ID -	stmia	r0!, {r4 - r6} +	mrc	p15, 0, r5, c13, c0, 3	@ User r/o thread ID +	stmia	r0!, {r4 - r5}  	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID -	mrc	p15, 0, r7, c2, c0, 0	@ TTB 0 -	mrc	p15, 0, r8, c2, c0, 1	@ TTB 1 -	mrc	p15, 0, r9, c1, c0, 0	@ Control register -	mrc	p15, 0, r10, c1, c0, 1	@ Auxiliary control register -	mrc	p15, 0, r11, c1, c0, 2	@ Co-processor access control -	stmia	r0, {r6 - r11} -	ldmfd	sp!, {r4 - r11, pc} +	mrc	p15, 0, r7, c2, c0, 1	@ TTB 1 +	mrc	p15, 0, r8, c1, c0, 0	@ Control register +	mrc	p15, 0, r9, c1, c0, 1	@ Auxiliary control register +	mrc	p15, 0, r10, c1, c0, 2	@ Co-processor access control +	stmia	r0, {r6 - r10} +	ldmfd	sp!, {r4 - r10, pc}  ENDPROC(cpu_v7_do_suspend)  ENTRY(cpu_v7_do_resume)  	mov	ip, #0  	mcr	p15, 0, ip, c8, c7, 0	@ invalidate TLBs  	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache -	ldmia	r0!, {r4 - r6} +	mcr	p15, 0, ip, c13, c0, 1	@ set reserved context ID +	ldmia	r0!, {r4 - r5}  	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID -	mcr	p15, 0, r5, c13, c0, 1	@ Context ID -	mcr	p15, 0, r6, c13, c0, 3	@ User r/o thread ID -	ldmia	r0, {r6 - r11} +	mcr	p15, 0, r5, c13, c0, 3	@ User r/o thread ID +	ldmia	r0, {r6 - r10}  	mcr	p15, 0, r6, c3, c0, 0	@ Domain ID -	mcr	p15, 0, r7, c2, c0, 0	@ TTB 0 -	mcr	p15, 0, r8, c2, c0, 1	@ TTB 1 +	ALT_SMP(orr	r1, r1, #TTB_FLAGS_SMP) +	ALT_UP(orr	r1, r1, #TTB_FLAGS_UP) +	mcr	p15, 0, r1, c2, c0, 0	@ TTB 0 +	mcr	p15, 0, r7, c2, c0, 1	@ TTB 1  	mcr	p15, 0, ip, c2, c0, 2	@ TTB control register  	mrc	p15, 0, r4, c1, c0, 1	@ Read Auxiliary control register -	teq	r4, r10			@ Is it already set? -	mcrne	p15, 0, r10, c1, c0, 1	@ No, so write it -	mcr	p15, 0, r11, c1, c0, 2	@ Co-processor access control +	teq	r4, r9			@ Is it already set? +	mcrne	p15, 0, r9, c1, c0, 1	@ No, so write it +	mcr	p15, 0, r10, c1, c0, 2	@ Co-processor access control  	ldr	r4, =PRRR		@ PRRR  	ldr	r5, =NMRR		@ NMRR  	mcr	p15, 0, r4, c10, c2, 0	@ write PRRR  	mcr	p15, 0, r5, c10, c2, 1	@ write NMRR  	isb  	dsb -	mov	r0, r9			@ control register -	mov	r2, r7, lsr #14		@ get TTB0 base -	mov	r2, r2, lsl #14 -	ldr	r3, cpu_resume_l1_flags +	mov	r0, r8			@ control register  	b	cpu_resume_mmu  ENDPROC(cpu_v7_do_resume) -cpu_resume_l1_flags: -	ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP) -	ALT_UP(.long  PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)  #endif  	__CPUINIT diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index 755e1bf2268..abf0507a08a 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -406,24 +406,23 @@ ENTRY(cpu_xsc3_set_pte_ext)  	.align  .globl	cpu_xsc3_suspend_size -.equ	cpu_xsc3_suspend_size, 4 * 7 +.equ	cpu_xsc3_suspend_size, 4 * 6  #ifdef CONFIG_PM_SLEEP  ENTRY(cpu_xsc3_do_suspend) -	stmfd	sp!, {r4 - r10, lr} +	stmfd	sp!, {r4 - r9, lr}  	mrc	p14, 0, r4, c6, c0, 0	@ clock configuration, for turbo mode  	mrc	p15, 0, r5, c15, c1, 0	@ CP access reg  	mrc	p15, 0, r6, c13, c0, 0	@ PID  	mrc 	p15, 0, r7, c3, c0, 0	@ domain ID -	mrc 	p15, 0, r8, c2, c0, 0	@ translation table base addr -	mrc	p15, 0, r9, c1, c0, 1	@ auxiliary control reg -	mrc 	p15, 0, r10, c1, c0, 0	@ control reg +	mrc	p15, 0, r8, c1, c0, 1	@ auxiliary control reg +	mrc 	p15, 0, r9, c1, c0, 0	@ control reg  	bic	r4, r4, #2		@ clear frequency change bit -	stmia	r0, {r4 - r10}		@ store cp regs -	ldmia	sp!, {r4 - r10, pc} +	stmia	r0, {r4 - r9}		@ store cp regs +	ldmia	sp!, {r4 - r9, pc}  ENDPROC(cpu_xsc3_do_suspend)  ENTRY(cpu_xsc3_do_resume) -	ldmia	r0, {r4 - r10}		@ load cp regs +	ldmia	r0, {r4 - r9}		@ load cp regs  	mov	ip, #0  	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I & D caches, BTB  	mcr	p15, 0, ip, c7, c10, 4	@ drain write (&fill) buffer @@ -433,15 +432,10 @@ ENTRY(cpu_xsc3_do_resume)  	mcr	p15, 0, r5, c15, c1, 0	@ CP access reg  	mcr	p15, 0, r6, c13, c0, 0	@ PID  	mcr	p15, 0, r7, c3, c0, 0	@ domain ID -	mcr	p15, 0, r8, c2, c0, 0	@ translation table base addr -	mcr	p15, 0, r9, c1, c0, 1	@ auxiliary control reg - -	@ temporarily map resume_turn_on_mmu into the page table, -	@ otherwise prefetch abort occurs after MMU is turned on -	mov	r0, r10			@ control register -	mov	r2, r8, lsr #14		@ get TTB0 base -	mov	r2, r2, lsl #14 -	ldr	r3, =0x542e		@ section flags +	orr	r1, r1, #0x18		@ cache the page table in L2 +	mcr	p15, 0, r1, c2, c0, 0	@ translation table base addr +	mcr	p15, 0, r8, c1, c0, 1	@ auxiliary control reg +	mov	r0, r9			@ control register  	b	cpu_resume_mmu  ENDPROC(cpu_xsc3_do_resume)  #endif diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index fbc06e55b87..3277904beba 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -520,24 +520,23 @@ ENTRY(cpu_xscale_set_pte_ext)  	.align  .globl	cpu_xscale_suspend_size -.equ	cpu_xscale_suspend_size, 4 * 7 +.equ	cpu_xscale_suspend_size, 4 * 6  #ifdef CONFIG_PM_SLEEP  ENTRY(cpu_xscale_do_suspend) -	stmfd	sp!, {r4 - r10, lr} +	stmfd	sp!, {r4 - r9, lr}  	mrc	p14, 0, r4, c6, c0, 0	@ clock configuration, for turbo mode  	mrc	p15, 0, r5, c15, c1, 0	@ CP access reg  	mrc	p15, 0, r6, c13, c0, 0	@ PID  	mrc	p15, 0, r7, c3, c0, 0	@ domain ID -	mrc	p15, 0, r8, c2, c0, 0	@ translation table base addr -	mrc	p15, 0, r9, c1, c1, 0	@ auxiliary control reg -	mrc	p15, 0, r10, c1, c0, 0	@ control reg +	mrc	p15, 0, r8, c1, c1, 0	@ auxiliary control reg +	mrc	p15, 0, r9, c1, c0, 0	@ control reg  	bic	r4, r4, #2		@ clear frequency change bit -	stmia	r0, {r4 - r10}		@ store cp regs -	ldmfd	sp!, {r4 - r10, pc} +	stmia	r0, {r4 - r9}		@ store cp regs +	ldmfd	sp!, {r4 - r9, pc}  ENDPROC(cpu_xscale_do_suspend)  ENTRY(cpu_xscale_do_resume) -	ldmia	r0, {r4 - r10}		@ load cp regs +	ldmia	r0, {r4 - r9}		@ load cp regs  	mov	ip, #0  	mcr	p15, 0, ip, c8, c7, 0	@ invalidate I & D TLBs  	mcr	p15, 0, ip, c7, c7, 0	@ invalidate I & D caches, BTB @@ -545,13 +544,9 @@ ENTRY(cpu_xscale_do_resume)  	mcr	p15, 0, r5, c15, c1, 0	@ CP access reg  	mcr	p15, 0, r6, c13, c0, 0	@ PID  	mcr	p15, 0, r7, c3, c0, 0	@ domain ID -	mcr	p15, 0, r8, c2, c0, 0	@ translation table base addr -	mcr	p15, 0, r9, c1, c1, 0	@ auxiliary control reg -	mov	r0, r10			@ control register -	mov	r2, r8, lsr #14		@ get TTB0 base -	mov	r2, r2, lsl #14 -	ldr	r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \ -		     PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE +	mcr	p15, 0, r1, c2, c0, 0	@ translation table base addr +	mcr	p15, 0, r8, c1, c1, 0	@ auxiliary control reg +	mov	r0, r9			@ control register  	b	cpu_resume_mmu  ENDPROC(cpu_xscale_do_resume)  #endif diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S index e4dde91f023..a3045937fc2 100644 --- a/arch/arm/plat-mxc/include/mach/debug-macro.S +++ b/arch/arm/plat-mxc/include/mach/debug-macro.S @@ -54,7 +54,7 @@  #define UART_VADDR	IMX_IO_ADDRESS(UART_PADDR) -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		ldr	\rp, =UART_PADDR	@ physical  		ldr	\rv, =UART_VADDR	@ virtual  		.endm diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h deleted file mode 100644 index 11be5cdbdd1..00000000000 --- a/arch/arm/plat-mxc/include/mach/memory.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2004-2007 Freescale Semiconductor, Inc. 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_ARCH_MXC_MEMORY_H__ -#define __ASM_ARCH_MXC_MEMORY_H__ - -#define MX1_PHYS_OFFSET		UL(0x08000000) -#define MX21_PHYS_OFFSET	UL(0xc0000000) -#define MX25_PHYS_OFFSET	UL(0x80000000) -#define MX27_PHYS_OFFSET	UL(0xa0000000) -#define MX3x_PHYS_OFFSET	UL(0x80000000) -#define MX50_PHYS_OFFSET	UL(0x70000000) -#define MX51_PHYS_OFFSET	UL(0x90000000) -#define MX53_PHYS_OFFSET	UL(0x70000000) - -#if !defined(CONFIG_RUNTIME_PHYS_OFFSET) -# if defined CONFIG_ARCH_MX1 -#  define PLAT_PHYS_OFFSET		MX1_PHYS_OFFSET -# elif defined CONFIG_MACH_MX21 -#  define PLAT_PHYS_OFFSET		MX21_PHYS_OFFSET -# elif defined CONFIG_ARCH_MX25 -#  define PLAT_PHYS_OFFSET		MX25_PHYS_OFFSET -# elif defined CONFIG_MACH_MX27 -#  define PLAT_PHYS_OFFSET		MX27_PHYS_OFFSET -# elif defined CONFIG_ARCH_MX3 -#  define PLAT_PHYS_OFFSET		MX3x_PHYS_OFFSET -# elif defined CONFIG_ARCH_MX50 -#  define PLAT_PHYS_OFFSET		MX50_PHYS_OFFSET -# elif defined CONFIG_ARCH_MX51 -#  define PLAT_PHYS_OFFSET		MX51_PHYS_OFFSET -# elif defined CONFIG_ARCH_MX53 -#  define PLAT_PHYS_OFFSET		MX53_PHYS_OFFSET -# endif -#endif - -#if defined(CONFIG_MX3_VIDEO) -/* - * Increase size of DMA-consistent memory region. - * This is required for mx3 camera driver to capture at least two QXGA frames. - */ -#define CONSISTENT_DMA_SIZE SZ_8M - -#elif defined(CONFIG_MX1_VIDEO) || defined(CONFIG_VIDEO_MX2_HOSTSUPPORT) -/* - * Increase size of DMA-consistent memory region. - * This is required for i.MX camera driver to capture at least four VGA frames. - */ -#define CONSISTENT_DMA_SIZE SZ_4M -#endif /* CONFIG_MX1_VIDEO || CONFIG_VIDEO_MX2_HOSTSUPPORT */ - -#endif /* __ASM_ARCH_MXC_MEMORY_H__ */ diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index bb8f4a6b3e3..95732af7b20 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -14,6 +14,7 @@ config ARCH_OMAP1  	select CLKDEV_LOOKUP  	select CLKSRC_MMIO  	select GENERIC_IRQ_CHIP +	select NEED_MACH_MEMORY_H  	help  	  "Systems based on omap7xx, omap15xx or omap16xx" diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h index d72ec85c97e..ebe67ea8d06 100644 --- a/arch/arm/plat-omap/include/plat/io.h +++ b/arch/arm/plat-omap/include/plat/io.h @@ -309,6 +309,8 @@ extern void omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0,  void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type);  void omap_iounmap(volatile void __iomem *addr); +extern void __init omap_init_consistent_dma_size(void); +  #endif  #endif diff --git a/arch/arm/plat-omap/include/plat/memory.h b/arch/arm/plat-omap/include/plat/memory.h deleted file mode 100644 index e6720aa2d55..00000000000 --- a/arch/arm/plat-omap/include/plat/memory.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * arch/arm/plat-omap/include/mach/memory.h - * - * Memory map for OMAP-1510 and 1610 - * - * Copyright (C) 2000 RidgeRun, Inc. - * Author: Greg Lonnon <glonnon@ridgerun.com> - * - * This file was derived from arch/arm/mach-intergrator/include/mach/memory.h - * Copyright (C) 1999 ARM Limited - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#if defined(CONFIG_ARCH_OMAP1) -#define PLAT_PHYS_OFFSET		UL(0x10000000) -#else -#define PLAT_PHYS_OFFSET		UL(0x80000000) -#endif - -/* - * Bus address is physical address, except for OMAP-1510 Local Bus. - * OMAP-1510 bus address is translated into a Local Bus address if the - * OMAP bus type is lbus. We do the address translation based on the - * device overriding the defaults used in the dma-mapping API. - * Note that the is_lbus_device() test is not very efficient on 1510 - * because of the strncmp(). - */ -#ifdef CONFIG_ARCH_OMAP15XX - -/* - * OMAP-1510 Local Bus address offset - */ -#define OMAP1510_LB_OFFSET	UL(0x30000000) - -#define virt_to_lbus(x)		((x) - PAGE_OFFSET + OMAP1510_LB_OFFSET) -#define lbus_to_virt(x)		((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET) -#define is_lbus_device(dev)	(cpu_is_omap15xx() && dev && (strncmp(dev_name(dev), "ohci", 4) == 0)) - -#define __arch_pfn_to_dma(dev, pfn)	\ -	({ dma_addr_t __dma = __pfn_to_phys(pfn); \ -	   if (is_lbus_device(dev)) \ -		__dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \ -	   __dma; }) - -#define __arch_dma_to_pfn(dev, addr)	\ -	({ dma_addr_t __dma = addr;				\ -	   if (is_lbus_device(dev))				\ -		__dma += PHYS_OFFSET - OMAP1510_LB_OFFSET;	\ -	   __phys_to_pfn(__dma);				\ -	}) - -#define __arch_dma_to_virt(dev, addr)	({ (void *) (is_lbus_device(dev) ? \ -						lbus_to_virt(addr) : \ -						__phys_to_virt(addr)); }) - -#define __arch_virt_to_dma(dev, addr)	({ unsigned long __addr = (unsigned long)(addr); \ -					   (dma_addr_t) (is_lbus_device(dev) ? \ -						virt_to_lbus(__addr) : \ -						__virt_to_phys(__addr)); }) - -#endif	/* CONFIG_ARCH_OMAP15XX */ - -/* Override the ARM default */ -#ifdef CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE - -#if (CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE == 0) -#undef CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE -#define CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE 2 -#endif - -#define CONSISTENT_DMA_SIZE \ -	(((CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE + 1) & ~1) * 1024 * 1024) - -#endif - -#endif - diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index de3b10c1812..1ab9fd6abe6 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -16,8 +16,8 @@  #include <linux/init.h>  /* - * Memory entry used for the DEBUG_LL UART configuration. See also - * uncompress.h and debug-macro.S. + * Memory entry used for the DEBUG_LL UART configuration, relative to + * start of RAM. See also uncompress.h and debug-macro.S.   *   * Note that using a memory location for storing the UART configuration   * has at least two limitations: @@ -27,7 +27,7 @@   * 2. We assume printascii is called at least once before paging_init,   *    and addruart has a chance to read OMAP_UART_INFO   */ -#define OMAP_UART_INFO		(PLAT_PHYS_OFFSET + 0x3ffc) +#define OMAP_UART_INFO_OFS	0x3ffc  /* OMAP1 serial ports */  #define OMAP1_UART1_BASE	0xfffb0000 diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index a067484cc4a..2f472e989ec 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h @@ -36,7 +36,13 @@ int uart_shift;   */  static void set_omap_uart_info(unsigned char port)  { -	*(volatile u32 *)OMAP_UART_INFO = port; +	/* +	 * Get address of some.bss variable and round it down +	 * a la CONFIG_AUTO_ZRELADDR. +	 */ +	u32 ram_start = (u32)&uart_shift & 0xf8000000; +	u32 *uart_info = (u32 *)(ram_start + OMAP_UART_INFO_OFS); +	*uart_info = port;  }  static void putc(int c) diff --git a/arch/arm/plat-omap/io.c b/arch/arm/plat-omap/io.c index f1ecfa9fc61..e9b0e23edd0 100644 --- a/arch/arm/plat-omap/io.c +++ b/arch/arm/plat-omap/io.c @@ -12,6 +12,7 @@  #include <linux/module.h>  #include <linux/io.h>  #include <linux/mm.h> +#include <linux/dma-mapping.h>  #include <plat/omap7xx.h>  #include <plat/omap1510.h> @@ -139,3 +140,10 @@ void omap_iounmap(volatile void __iomem *addr)  		__iounmap(addr);  }  EXPORT_SYMBOL(omap_iounmap); + +void __init omap_init_consistent_dma_size(void) +{ +#ifdef CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE +	init_consistent_dma_size(CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE << 20); +#endif +} diff --git a/arch/arm/plat-spear/include/plat/debug-macro.S b/arch/arm/plat-spear/include/plat/debug-macro.S index 8501bbf2c09..02b160a1ec9 100644 --- a/arch/arm/plat-spear/include/plat/debug-macro.S +++ b/arch/arm/plat-spear/include/plat/debug-macro.S @@ -14,7 +14,7 @@  #include <linux/amba/serial.h>  #include <mach/hardware.h> -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		mov	\rp, #SPEAR_DBG_UART_BASE		@ Physical base  		mov	\rv, #VA_SPEAR_DBG_UART_BASE		@ Virtual base  		.endm diff --git a/arch/arm/plat-spear/include/plat/memory.h b/arch/arm/plat-spear/include/plat/memory.h deleted file mode 100644 index 7e3599e1104..00000000000 --- a/arch/arm/plat-spear/include/plat/memory.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/arm/plat-spear/include/plat/memory.h - * - * Memory map for SPEAr platform - * - * Copyright (C) 2009 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.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 __PLAT_MEMORY_H -#define __PLAT_MEMORY_H - -/* Physical DRAM offset */ -#define PLAT_PHYS_OFFSET		UL(0x00000000) - -#endif /* __PLAT_MEMORY_H */ diff --git a/arch/arm/plat-tcc/include/mach/debug-macro.S b/arch/arm/plat-tcc/include/mach/debug-macro.S index 7662f736e42..cf17d04ec30 100644 --- a/arch/arm/plat-tcc/include/mach/debug-macro.S +++ b/arch/arm/plat-tcc/include/mach/debug-macro.S @@ -9,7 +9,7 @@   *   */ -		.macro	addruart, rp, rv +		.macro	addruart, rp, rv, tmp  		moveq	\rp, #0x90000000	@ physical base address  		movne	\rv, #0xF1000000	@ virtual base  		orr	\rp, \rp, #0x00007000	@ UART0 diff --git a/arch/arm/plat-tcc/include/mach/memory.h b/arch/arm/plat-tcc/include/mach/memory.h deleted file mode 100644 index 28a6e0cd13b..00000000000 --- a/arch/arm/plat-tcc/include/mach/memory.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 RidgeRun, Inc. - * Copyright (C) 2008-2009 Telechips - * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de> - * - * Licensed under the terms of the GPL v2. - */ - -#ifndef __ASM_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H - -/* - * Physical DRAM offset. - */ -#define PLAT_PHYS_OFFSET		UL(0x20000000) - -#endif diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 79bcb431693..0cbd5a0a933 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -11,6 +11,7 @@  #include <linux/module.h>  #include <linux/types.h>  #include <linux/cpu.h> +#include <linux/cpu_pm.h>  #include <linux/kernel.h>  #include <linux/notifier.h>  #include <linux/signal.h> @@ -68,7 +69,7 @@ static bool vfp_state_in_hw(unsigned int cpu, struct thread_info *thread)  /*   * Force a reload of the VFP context from the thread structure.  We do   * this by ensuring that access to the VFP hardware is disabled, and - * clear last_VFP_context.  Must be called from non-preemptible context. + * clear vfp_current_hw_state.  Must be called from non-preemptible context.   */  static void vfp_force_reload(unsigned int cpu, struct thread_info *thread)  { @@ -436,9 +437,7 @@ static void vfp_enable(void *unused)  	set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));  } -#ifdef CONFIG_PM -#include <linux/syscore_ops.h> - +#ifdef CONFIG_CPU_PM  static int vfp_pm_suspend(void)  {  	struct thread_info *ti = current_thread_info(); @@ -468,19 +467,33 @@ static void vfp_pm_resume(void)  	fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);  } -static struct syscore_ops vfp_pm_syscore_ops = { -	.suspend	= vfp_pm_suspend, -	.resume		= vfp_pm_resume, +static int vfp_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd, +	void *v) +{ +	switch (cmd) { +	case CPU_PM_ENTER: +		vfp_pm_suspend(); +		break; +	case CPU_PM_ENTER_FAILED: +	case CPU_PM_EXIT: +		vfp_pm_resume(); +		break; +	} +	return NOTIFY_OK; +} + +static struct notifier_block vfp_cpu_pm_notifier_block = { +	.notifier_call = vfp_cpu_pm_notifier,  };  static void vfp_pm_init(void)  { -	register_syscore_ops(&vfp_pm_syscore_ops); +	cpu_pm_register_notifier(&vfp_cpu_pm_notifier_block);  }  #else  static inline void vfp_pm_init(void) { } -#endif /* CONFIG_PM */ +#endif /* CONFIG_CPU_PM */  /*   * Ensure that the VFP state stored in 'thread->vfpstate' is up to date  |