From 22493cfd78e4db0ba9c9f46dac4757bee5a0294a Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Thu, 21 Mar 2013 15:17:56 -0500 Subject: Hexagon: clean up generic headers in Kbuild Signed-off-by: Richard Kuo --- arch/hexagon/include/asm/Kbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild index bdb54ceb53bc..1da17caac23c 100644 --- a/arch/hexagon/include/asm/Kbuild +++ b/arch/hexagon/include/asm/Kbuild @@ -25,7 +25,6 @@ generic-y += kdebug.h generic-y += kmap_types.h generic-y += local64.h generic-y += local.h -generic-y += local.h generic-y += mman.h generic-y += msgbuf.h generic-y += pci.h @@ -41,6 +40,7 @@ generic-y += sembuf.h generic-y += shmbuf.h generic-y += shmparam.h generic-y += siginfo.h +generic-y += sizes.h generic-y += socket.h generic-y += sockios.h generic-y += statfs.h -- cgit v1.2.2 From e0025a72c37ca404fbf31d569439c20bfb04295e Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Thu, 21 Mar 2013 18:24:19 -0500 Subject: Hexagon: fix __atomic_add_unless Signed-off-by: Richard Kuo --- arch/hexagon/include/asm/atomic.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/include/asm/atomic.h b/arch/hexagon/include/asm/atomic.h index 468fbb0781cd..c6670390d255 100644 --- a/arch/hexagon/include/asm/atomic.h +++ b/arch/hexagon/include/asm/atomic.h @@ -117,35 +117,37 @@ static inline int atomic_sub_return(int i, atomic_t *v) #define atomic_sub(i, v) atomic_sub_return(i, (v)) /** - * atomic_add_unless - add unless the number is a given value + * __atomic_add_unless - add unless the number is a given value * @v: pointer to value * @a: amount to add * @u: unless value is equal to u * - * Returns 1 if the add happened, 0 if it didn't. + * Returns old value. + * */ + static inline int __atomic_add_unless(atomic_t *v, int a, int u) { - int output, __oldval; + int __oldval; + register int tmp; + asm volatile( "1: %0 = memw_locked(%2);" " {" " p3 = cmp.eq(%0, %4);" " if (p3.new) jump:nt 2f;" - " %0 = add(%0, %3);" - " %1 = #0;" + " %1 = add(%0, %3);" " }" - " memw_locked(%2, p3) = %0;" + " memw_locked(%2, p3) = %1;" " {" " if !p3 jump 1b;" - " %1 = #1;" " }" "2:" - : "=&r" (__oldval), "=&r" (output) + : "=&r" (__oldval), "=&r" (tmp) : "r" (v), "r" (a), "r" (u) : "memory", "p3" ); - return output; + return __oldval; } #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) -- cgit v1.2.2 From 8f5a0b9dffeb3cb94f2b0622b6fe0717512ef54b Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Fri, 22 Mar 2013 16:05:40 -0500 Subject: Hexagon: add support for ARCH_PFN_OFFSET Add support for loading the kernel at a physical offset. The offset should still be 4M aligned. Signed-off-by: Richard Kuo --- arch/hexagon/Kconfig | 6 +++++ arch/hexagon/include/asm/hexagon_vm.h | 47 ++++++++++++++++++----------------- arch/hexagon/include/asm/mem-layout.h | 21 +++++++++++----- arch/hexagon/include/asm/page.h | 5 ++-- arch/hexagon/kernel/head.S | 22 +++++++++++++--- arch/hexagon/kernel/setup.c | 2 ++ arch/hexagon/kernel/vmlinux.lds.S | 10 ++------ arch/hexagon/mm/init.c | 33 +++++++++++++++--------- 8 files changed, 91 insertions(+), 55 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index e4decc6b8947..dd89a7245ac4 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -33,6 +33,7 @@ config HEXAGON Qualcomm Hexagon is a processor architecture designed for high performance and low power across a wide variety of applications. + config HEXAGON_ARCH_V1 bool @@ -45,6 +46,11 @@ config HEXAGON_ARCH_V3 config HEXAGON_ARCH_V4 bool +config HEXAGON_PHYS_OFFSET + def_bool y + ---help--- + Platforms that don't load the kernel at zero set this. + config FRAME_POINTER def_bool y diff --git a/arch/hexagon/include/asm/hexagon_vm.h b/arch/hexagon/include/asm/hexagon_vm.h index c144bee6cabe..6b81e4d5ecb1 100644 --- a/arch/hexagon/include/asm/hexagon_vm.h +++ b/arch/hexagon/include/asm/hexagon_vm.h @@ -31,10 +31,26 @@ * for tracing/debugging. */ -/* - * Lets make this stuff visible only if configured, - * so we can unconditionally include the file. - */ +#define HVM_TRAP1_VMVERSION 0 +#define HVM_TRAP1_VMRTE 1 +#define HVM_TRAP1_VMSETVEC 2 +#define HVM_TRAP1_VMSETIE 3 +#define HVM_TRAP1_VMGETIE 4 +#define HVM_TRAP1_VMINTOP 5 +#define HVM_TRAP1_VMCLRMAP 10 +#define HVM_TRAP1_VMNEWMAP 11 +#define HVM_TRAP1_FORMERLY_VMWIRE 12 +#define HVM_TRAP1_VMCACHE 13 +#define HVM_TRAP1_VMGETTIME 14 +#define HVM_TRAP1_VMSETTIME 15 +#define HVM_TRAP1_VMWAIT 16 +#define HVM_TRAP1_VMYIELD 17 +#define HVM_TRAP1_VMSTART 18 +#define HVM_TRAP1_VMSTOP 19 +#define HVM_TRAP1_VMVPID 20 +#define HVM_TRAP1_VMSETREGS 21 +#define HVM_TRAP1_VMGETREGS 22 +#define HVM_TRAP1_VMTIMEROP 24 #ifndef __ASSEMBLY__ @@ -175,25 +191,6 @@ static inline long __vmintop_clear(long i) #else /* Only assembly code should reference these */ -#define HVM_TRAP1_VMRTE 1 -#define HVM_TRAP1_VMSETVEC 2 -#define HVM_TRAP1_VMSETIE 3 -#define HVM_TRAP1_VMGETIE 4 -#define HVM_TRAP1_VMINTOP 5 -#define HVM_TRAP1_VMCLRMAP 10 -#define HVM_TRAP1_VMNEWMAP 11 -#define HVM_TRAP1_FORMERLY_VMWIRE 12 -#define HVM_TRAP1_VMCACHE 13 -#define HVM_TRAP1_VMGETTIME 14 -#define HVM_TRAP1_VMSETTIME 15 -#define HVM_TRAP1_VMWAIT 16 -#define HVM_TRAP1_VMYIELD 17 -#define HVM_TRAP1_VMSTART 18 -#define HVM_TRAP1_VMSTOP 19 -#define HVM_TRAP1_VMVPID 20 -#define HVM_TRAP1_VMSETREGS 21 -#define HVM_TRAP1_VMGETREGS 22 - #endif /* __ASSEMBLY__ */ /* @@ -224,6 +221,8 @@ static inline long __vmintop_clear(long i) #define HVM_VMEST_UM_MSK 1 #define HVM_VMEST_IE_SFT 30 #define HVM_VMEST_IE_MSK 1 +#define HVM_VMEST_SS_SFT 29 +#define HVM_VMEST_SS_MSK 1 #define HVM_VMEST_EVENTNUM_SFT 16 #define HVM_VMEST_EVENTNUM_MSK 0xff #define HVM_VMEST_CAUSE_SFT 0 @@ -260,6 +259,8 @@ static inline long __vmintop_clear(long i) #define HVM_GE_C_INVI 0x15 #define HVM_GE_C_PRIVI 0x1B #define HVM_GE_C_XMAL 0x1C +#define HVM_GE_C_WREG 0x1D +#define HVM_GE_C_PCAL 0x1E #define HVM_GE_C_RMAL 0x20 #define HVM_GE_C_WMAL 0x21 #define HVM_GE_C_RPROT 0x22 diff --git a/arch/hexagon/include/asm/mem-layout.h b/arch/hexagon/include/asm/mem-layout.h index af16e977c55e..1426cd71a1d3 100644 --- a/arch/hexagon/include/asm/mem-layout.h +++ b/arch/hexagon/include/asm/mem-layout.h @@ -32,16 +32,25 @@ #define PAGE_OFFSET _AC(0xc0000000, UL) /* - * LOAD_ADDRESS is the physical/linear address of where in memory - * the kernel gets loaded. The 12 least significant bits must be zero (0) - * due to limitations on setting the EVB - * + * Compiling for a platform that needs a crazy physical offset + * (like if the memory starts at 1GB and up) means we need + * an actual PHYS_OFFSET. Should be set up in head.S. */ -#ifndef LOAD_ADDRESS -#define LOAD_ADDRESS 0x00000000 +#ifdef CONFIG_HEXAGON_PHYS_OFFSET +#ifndef __ASSEMBLY__ +extern unsigned long __phys_offset; +#endif +#define PHYS_OFFSET __phys_offset +#endif + +#ifndef PHYS_OFFSET +#define PHYS_OFFSET 0 #endif +#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) +#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET + #define TASK_SIZE (PAGE_OFFSET) /* not sure how these are used yet */ diff --git a/arch/hexagon/include/asm/page.h b/arch/hexagon/include/asm/page.h index 692adc213429..de1b2871d09c 100644 --- a/arch/hexagon/include/asm/page.h +++ b/arch/hexagon/include/asm/page.h @@ -96,8 +96,8 @@ typedef struct page *pgtable_t; * MIPS says they're only used during mem_init. * also, check if we need a PHYS_OFFSET. */ -#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET) -#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET)) +#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) +#define __va(x) ((void *)((unsigned long)(x) - PHYS_OFFSET + PAGE_OFFSET)) /* The "page frame" descriptor is defined in linux/mm.h */ struct page; @@ -147,6 +147,7 @@ static inline void clear_page(void *page) */ #define kern_addr_valid(addr) (1) +#include #include /* XXX Todo: implement assembly-optimized version of getorder. */ #include diff --git a/arch/hexagon/kernel/head.S b/arch/hexagon/kernel/head.S index d859402c73ba..477320c455f7 100644 --- a/arch/hexagon/kernel/head.S +++ b/arch/hexagon/kernel/head.S @@ -43,14 +43,21 @@ ENTRY(stext) * Symbol is kernel segment address, but we need * the logical/physical address. */ - r24 = asl(r24, #2) - r24 = lsr(r24, #2) + r25 = pc; + r2.h = #0xffc0; + r2.l = #0x0000; + r25 = and(r2,r25); /* R25 holds PHYS_OFFSET now */ + r1.h = #HI(PAGE_OFFSET); + r1.l = #LO(PAGE_OFFSET); + r24 = sub(r24,r1); /* swapper_pg_dir - PAGE_OFFSET */ + r24 = add(r24,r25); /* + PHYS_OFFSET */ - r0 = r24 + r0 = r24; /* aka __pa(swapper_pg_dir) */ /* - * Initialize a 16MB PTE to make the virtual and physical + * Initialize page dir to make the virtual and physical * addresses where the kernel was loaded be identical. + * Done in 4MB chunks. */ #define PTE_BITS ( __HVM_PTE_R | __HVM_PTE_W | __HVM_PTE_X \ | __HEXAGON_C_WB_L2 << 6 \ @@ -143,6 +150,13 @@ __head_s_vaddr_target: r2 = sub(r2,r0); call memset; + /* Set PHYS_OFFSET; should still be in R25 */ +#ifdef CONFIG_HEXAGON_PHYS_OFFSET + r0.l = #LO(__phys_offset); + r0.h = #HI(__phys_offset); + memw(r0) = r25; +#endif + /* Time to make the doughnuts. */ call start_kernel diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c index 94a387835008..2e2304f7b7ee 100644 --- a/arch/hexagon/kernel/setup.c +++ b/arch/hexagon/kernel/setup.c @@ -68,6 +68,8 @@ void __init setup_arch(char **cmdline_p) */ __vmsetvec(_K_VM_event_vector); + printk(KERN_INFO "PHYS_OFFSET=0x%08x\n", PHYS_OFFSET); + /* * Simulator has a few differences from the hardware. * For now, check uninitialized-but-mapped memory diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S index 14e793f6abbf..fafb886511e3 100644 --- a/arch/hexagon/kernel/vmlinux.lds.S +++ b/arch/hexagon/kernel/vmlinux.lds.S @@ -18,8 +18,6 @@ * 02110-1301, USA. */ -#define LOAD_OFFSET PAGE_OFFSET - #include #include /* Most of the kernel defines are here */ #include /* except for page_offset */ @@ -36,13 +34,9 @@ See asm-generic/sections.h for seemingly required labels. #define PAGE_SIZE _PAGE_SIZE -/* This LOAD_OFFSET is temporary for debugging on the simulator; it may change - for hypervisor pseudo-physical memory. */ - - SECTIONS { - . = PAGE_OFFSET + LOAD_ADDRESS; + . = PAGE_OFFSET; __init_begin = .; HEAD_TEXT_SECTION @@ -52,7 +46,7 @@ SECTIONS . = ALIGN(_PAGE_SIZE); _stext = .; - .text : AT(ADDR(.text) - LOAD_OFFSET) { + .text : AT(ADDR(.text)) { _text = .; TEXT_TEXT SCHED_TEXT diff --git a/arch/hexagon/mm/init.c b/arch/hexagon/mm/init.c index 69ffcfd28794..8e803a6e3402 100644 --- a/arch/hexagon/mm/init.c +++ b/arch/hexagon/mm/init.c @@ -31,9 +31,10 @@ * Define a startpg just past the end of the kernel image and a lastpg * that corresponds to the end of real or simulated platform memory. */ -#define bootmem_startpg (PFN_UP(((unsigned long) _end) - PAGE_OFFSET)) +#define bootmem_startpg (PFN_UP(((unsigned long) _end) - PAGE_OFFSET + PHYS_OFFSET)) -unsigned long bootmem_lastpg; /* Should be set by platform code */ +unsigned long bootmem_lastpg; /* Should be set by platform code */ +unsigned long __phys_offset; /* physical kernel offset >> 12 */ /* Set as variable to limit PMD copies */ int max_kernel_seg = 0x303; @@ -44,7 +45,6 @@ unsigned long zero_page_mask; /* indicate pfn's of high memory */ unsigned long highstart_pfn, highend_pfn; -/* struct mmu_gather defined in asm-generic.h; */ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); /* Default cache attribute for newly created page tables */ @@ -71,7 +71,7 @@ void __init mem_init(void) { /* No idea where this is actually declared. Seems to evade LXR. */ totalram_pages += free_all_bootmem(); - num_physpages = bootmem_lastpg; /* seriously, what? */ + num_physpages = bootmem_lastpg-ARCH_PFN_OFFSET; printk(KERN_INFO "totalram_pages = %ld\n", totalram_pages); @@ -193,6 +193,9 @@ void __init setup_arch_memory(void) * This needs to change for highmem setups. */ + /* Prior to this, bootmem_lastpg is actually mem size */ + bootmem_lastpg += ARCH_PFN_OFFSET; + /* Memory size needs to be a multiple of 16M */ bootmem_lastpg = PFN_DOWN((bootmem_lastpg << PAGE_SHIFT) & ~((BIG_KERNEL_PAGE_SIZE) - 1)); @@ -201,12 +204,15 @@ void __init setup_arch_memory(void) * Reserve the top DMA_RESERVE bytes of RAM for DMA (uncached) * memory allocation */ - bootmap_size = init_bootmem(bootmem_startpg, bootmem_lastpg - - PFN_DOWN(DMA_RESERVED_BYTES)); + + max_low_pfn = bootmem_lastpg - PFN_DOWN(DMA_RESERVED_BYTES); + min_low_pfn = ARCH_PFN_OFFSET; + bootmap_size = init_bootmem_node(NODE_DATA(0), bootmem_startpg, min_low_pfn, max_low_pfn); printk(KERN_INFO "bootmem_startpg: 0x%08lx\n", bootmem_startpg); printk(KERN_INFO "bootmem_lastpg: 0x%08lx\n", bootmem_lastpg); printk(KERN_INFO "bootmap_size: %d\n", bootmap_size); + printk(KERN_INFO "min_low_pfn: 0x%08lx\n", min_low_pfn); printk(KERN_INFO "max_low_pfn: 0x%08lx\n", max_low_pfn); /* @@ -221,14 +227,17 @@ void __init setup_arch_memory(void) /* this actually only goes to the end of the first gig */ segtable_end = segtable + (1<<(30-22)); - /* Move forward to the start of empty pages */ - segtable += bootmem_lastpg >> (22-PAGE_SHIFT); + /* + * Move forward to the start of empty pages; take into account + * phys_offset shift. + */ + segtable += (bootmem_lastpg-ARCH_PFN_OFFSET)>>(22-PAGE_SHIFT); { - int i; + int i; - for (i = 1 ; i <= DMA_RESERVE ; i++) - segtable[-i] = ((segtable[-i] & __HVM_PTE_PGMASK_4MB) + for (i = 1 ; i <= DMA_RESERVE ; i++) + segtable[-i] = ((segtable[-i] & __HVM_PTE_PGMASK_4MB) | __HVM_PTE_R | __HVM_PTE_W | __HVM_PTE_X | __HEXAGON_C_UNC << 6 | __HVM_PDE_S_4MB); @@ -256,7 +265,7 @@ void __init setup_arch_memory(void) * Free all the memory that wasn't taken up by the bootmap, the DMA * reserve, or kernel itself. */ - free_bootmem(PFN_PHYS(bootmem_startpg)+bootmap_size, + free_bootmem(PFN_PHYS(bootmem_startpg) + bootmap_size, PFN_PHYS(bootmem_lastpg - bootmem_startpg) - bootmap_size - DMA_RESERVED_BYTES); -- cgit v1.2.2 From 66b03dbfe605c2566cff55bde35372030aa4b3d0 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Tue, 27 Mar 2012 17:37:33 -0500 Subject: Hexagon: change arch version config to allow comparisons Signed-off-by: Richard Kuo --- arch/hexagon/Kconfig | 18 ++++-------------- arch/hexagon/Makefile | 17 +++-------------- arch/hexagon/include/asm/elf.h | 6 +++--- 3 files changed, 10 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index dd89a7245ac4..d90a495ab791 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -33,19 +33,6 @@ config HEXAGON Qualcomm Hexagon is a processor architecture designed for high performance and low power across a wide variety of applications. - -config HEXAGON_ARCH_V1 - bool - -config HEXAGON_ARCH_V2 - bool - -config HEXAGON_ARCH_V3 - bool - -config HEXAGON_ARCH_V4 - bool - config HEXAGON_PHYS_OFFSET def_bool y ---help--- @@ -109,12 +96,15 @@ choice config HEXAGON_COMET bool "Comet Board" - select HEXAGON_ARCH_V2 ---help--- Support for the Comet platform. endchoice +config HEXAGON_ARCH_VERSION + int "Architecture version" + default 2 + config HEXAGON_VM def_bool y diff --git a/arch/hexagon/Makefile b/arch/hexagon/Makefile index d00d900b2566..207711a0fd0c 100644 --- a/arch/hexagon/Makefile +++ b/arch/hexagon/Makefile @@ -15,20 +15,9 @@ KBUILD_CFLAGS += -fno-short-enums # LDFLAGS_MODULE += -shared CFLAGS_MODULE += -mlong-calls -cflags-$(CONFIG_HEXAGON_ARCH_V1) += $(call cc-option,-mv1) -cflags-$(CONFIG_HEXAGON_ARCH_V2) += $(call cc-option,-mv2) -cflags-$(CONFIG_HEXAGON_ARCH_V3) += $(call cc-option,-mv3) -cflags-$(CONFIG_HEXAGON_ARCH_V4) += $(call cc-option,-mv4) - -aflags-$(CONFIG_HEXAGON_ARCH_V1) += $(call cc-option,-mv1) -aflags-$(CONFIG_HEXAGON_ARCH_V2) += $(call cc-option,-mv2) -aflags-$(CONFIG_HEXAGON_ARCH_V3) += $(call cc-option,-mv3) -aflags-$(CONFIG_HEXAGON_ARCH_V4) += $(call cc-option,-mv4) - -ldflags-$(CONFIG_HEXAGON_ARCH_V1) += $(call cc-option,-mv1) -ldflags-$(CONFIG_HEXAGON_ARCH_V2) += $(call cc-option,-mv2) -ldflags-$(CONFIG_HEXAGON_ARCH_V3) += $(call cc-option,-mv3) -ldflags-$(CONFIG_HEXAGON_ARCH_V4) += $(call cc-option,-mv4) +cflags-y += $(call cc-option,-mv${CONFIG_HEXAGON_ARCH_VERSION}) +aflags-y += $(call cc-option,-mv${CONFIG_HEXAGON_ARCH_VERSION}) +ldflags-y += $(call cc-option,-mv${CONFIG_HEXAGON_ARCH_VERSION}) KBUILD_CFLAGS += $(cflags-y) KBUILD_AFLAGS += $(aflags-y) diff --git a/arch/hexagon/include/asm/elf.h b/arch/hexagon/include/asm/elf.h index 1f14e082588e..83b8d0ea4cb8 100644 --- a/arch/hexagon/include/asm/elf.h +++ b/arch/hexagon/include/asm/elf.h @@ -168,15 +168,15 @@ do { \ #define ELF_DATA ELFDATA2LSB #define ELF_ARCH EM_HEXAGON -#ifdef CONFIG_HEXAGON_ARCH_V2 +#if CONFIG_HEXAGON_ARCH_VERSION == 2 #define ELF_CORE_EFLAGS 0x1 #endif -#ifdef CONFIG_HEXAGON_ARCH_V3 +#if CONFIG_HEXAGON_ARCH_VERSION == 3 #define ELF_CORE_EFLAGS 0x2 #endif -#ifdef CONFIG_HEXAGON_ARCH_V4 +#if CONFIG_HEXAGON_ARCH_VERSION == 4 #define ELF_CORE_EFLAGS 0x3 #endif -- cgit v1.2.2 From 53debcd518e72d01bfe0364f1504fa585826941c Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Tue, 3 Apr 2012 18:15:42 -0500 Subject: Hexagon: use GENERIC_CPU_DEVICES Signed-off-by: Richard Kuo --- arch/hexagon/Kconfig | 1 + arch/hexagon/kernel/Makefile | 2 +- arch/hexagon/kernel/topology.c | 52 ------------------------------------------ 3 files changed, 2 insertions(+), 53 deletions(-) delete mode 100644 arch/hexagon/kernel/topology.c (limited to 'arch') diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index d90a495ab791..b059d8c29fb5 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -29,6 +29,7 @@ config HEXAGON select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS_BROADCAST select MODULES_USE_ELF_RELA + select GENERIC_CPU_DEVICES ---help--- Qualcomm Hexagon is a processor architecture designed for high performance and low power across a wide variety of applications. diff --git a/arch/hexagon/kernel/Makefile b/arch/hexagon/kernel/Makefile index 6c19501b487c..29fc933a7722 100644 --- a/arch/hexagon/kernel/Makefile +++ b/arch/hexagon/kernel/Makefile @@ -1,6 +1,6 @@ extra-y := head.o vmlinux.lds -obj-$(CONFIG_SMP) += smp.o topology.o +obj-$(CONFIG_SMP) += smp.o obj-y += setup.o irq_cpu.o traps.o syscalltab.o signal.o time.o obj-y += process.o trampoline.o reset.o ptrace.o vdso.o diff --git a/arch/hexagon/kernel/topology.c b/arch/hexagon/kernel/topology.c deleted file mode 100644 index 352f27e809fd..000000000000 --- a/arch/hexagon/kernel/topology.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * CPU topology for Hexagon - * - * Copyright (c) 2010-2011, The Linux Foundation. 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 and - * only 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include - -/* Swiped from MIPS. */ - -static DEFINE_PER_CPU(struct cpu, cpu_devices); - -static int __init topology_init(void) -{ - int i, ret; - - for_each_present_cpu(i) { - - /* - * register_cpu takes a per_cpu pointer and - * just points it at another per_cpu struct... - */ - - ret = register_cpu(&per_cpu(cpu_devices, i), i); - if (ret) - printk(KERN_WARNING "topology_init: register_cpu %d " - "failed (%d)\n", i, ret); - } - - return 0; -} - -subsys_initcall(topology_init); -- cgit v1.2.2 From e470d932ce7f998aeab788fdc7b49ef26e76b4eb Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Tue, 8 May 2012 19:06:03 -0500 Subject: Hexagon: use defines for MIN_KERNEL_SEG calculation Signed-off-by: Richard Kuo --- arch/hexagon/include/asm/mem-layout.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/hexagon/include/asm/mem-layout.h b/arch/hexagon/include/asm/mem-layout.h index 1426cd71a1d3..3724cea5c59c 100644 --- a/arch/hexagon/include/asm/mem-layout.h +++ b/arch/hexagon/include/asm/mem-layout.h @@ -64,7 +64,7 @@ enum fixed_addresses { __end_of_fixed_addresses }; -#define MIN_KERNEL_SEG 0x300 /* From 0xc0000000 */ +#define MIN_KERNEL_SEG (PAGE_OFFSET >> PGDIR_SHIFT) /* L1 shift is 22 bits */ extern int max_kernel_seg; /* -- cgit v1.2.2 From 444dd742d3b0353c55c92f77e6732d932120c829 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Thu, 10 May 2012 17:40:14 -0500 Subject: Hexagon: add individual register access for switch_stack Signed-off-by: Richard Kuo --- arch/hexagon/include/asm/processor.h | 49 +++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/include/asm/processor.h b/arch/hexagon/include/asm/processor.h index 6dd5d3706869..758bcd1f290c 100644 --- a/arch/hexagon/include/asm/processor.h +++ b/arch/hexagon/include/asm/processor.h @@ -100,12 +100,49 @@ extern unsigned long get_wchan(struct task_struct *p); */ struct hexagon_switch_stack { - unsigned long long r1716; - unsigned long long r1918; - unsigned long long r2120; - unsigned long long r2322; - unsigned long long r2524; - unsigned long long r2726; + union { + struct { + unsigned long r16; + unsigned long r17; + }; + unsigned long long r1716; + }; + union { + struct { + unsigned long r18; + unsigned long r19; + }; + unsigned long long r1918; + }; + union { + struct { + unsigned long r20; + unsigned long r21; + }; + unsigned long long r2120; + }; + union { + struct { + unsigned long r22; + unsigned long r23; + }; + unsigned long long r2322; + }; + union { + struct { + unsigned long r24; + unsigned long r25; + }; + unsigned long long r2524; + }; + union { + struct { + unsigned long r26; + unsigned long r27; + }; + unsigned long long r2726; + }; + unsigned long fp; unsigned long lr; }; -- cgit v1.2.2 From 60c4ba99e015afe879c2682967c8ca8d233f6d3c Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Tue, 27 Mar 2012 17:38:09 -0500 Subject: Hexagon: add support for new v4+ registers Add support for a couple new v4+ registers, along with newer save/restore pt_regs. Signed-off-by: Richard Kuo --- arch/hexagon/include/uapi/asm/registers.h | 11 +- arch/hexagon/include/uapi/asm/user.h | 6 + arch/hexagon/kernel/asm-offsets.c | 3 +- arch/hexagon/kernel/kgdb.c | 2 + arch/hexagon/kernel/ptrace.c | 9 ++ arch/hexagon/kernel/signal.c | 10 +- arch/hexagon/kernel/vm_entry.S | 211 ++++++++++++++++++++++++------ arch/hexagon/kernel/vm_events.c | 2 + 8 files changed, 206 insertions(+), 48 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/include/uapi/asm/registers.h b/arch/hexagon/include/uapi/asm/registers.h index c20406f63b5c..80504155ca3a 100644 --- a/arch/hexagon/include/uapi/asm/registers.h +++ b/arch/hexagon/include/uapi/asm/registers.h @@ -57,10 +57,17 @@ struct pt_regs { }; union { struct { - unsigned long gp; unsigned long ugp; + unsigned long gp; + }; + long long int gpugp; + }; + union { + struct { + unsigned long cs0; + unsigned long cs1; }; - long long int ugpgp; + long long int cs1cs0; }; /* * Be extremely careful with rearranging these, if at all. Some code diff --git a/arch/hexagon/include/uapi/asm/user.h b/arch/hexagon/include/uapi/asm/user.h index cef13ee1413f..3dae94d9ced7 100644 --- a/arch/hexagon/include/uapi/asm/user.h +++ b/arch/hexagon/include/uapi/asm/user.h @@ -55,9 +55,15 @@ struct user_regs_struct { unsigned long pc; unsigned long cause; unsigned long badva; +#if CONFIG_HEXAGON_ARCH_VERSION < 4 unsigned long pad1; /* pad out to 48 words total */ unsigned long pad2; /* pad out to 48 words total */ unsigned long pad3; /* pad out to 48 words total */ +#else + unsigned long cs0; + unsigned long cs1; + unsigned long pad1; /* pad out to 48 words total */ +#endif }; #endif diff --git a/arch/hexagon/kernel/asm-offsets.c b/arch/hexagon/kernel/asm-offsets.c index 2d5e84d3b00d..181515ba825d 100644 --- a/arch/hexagon/kernel/asm-offsets.c +++ b/arch/hexagon/kernel/asm-offsets.c @@ -44,7 +44,8 @@ int main(void) COMMENT("Hexagon pt_regs definitions"); OFFSET(_PT_SYSCALL_NR, pt_regs, syscall_nr); - OFFSET(_PT_UGPGP, pt_regs, ugpgp); + OFFSET(_PT_GPUGP, pt_regs, gpugp); + OFFSET(_PT_CS1CS0, pt_regs, cs1cs0); OFFSET(_PT_R3130, pt_regs, r3130); OFFSET(_PT_R2928, pt_regs, r2928); OFFSET(_PT_R2726, pt_regs, r2726); diff --git a/arch/hexagon/kernel/kgdb.c b/arch/hexagon/kernel/kgdb.c index 344645370646..19f9e6ca5e33 100644 --- a/arch/hexagon/kernel/kgdb.c +++ b/arch/hexagon/kernel/kgdb.c @@ -70,6 +70,8 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { { "lc1", GDB_SIZEOF_REG, offsetof(struct pt_regs, lc1)}, { " gp", GDB_SIZEOF_REG, offsetof(struct pt_regs, gp)}, { "ugp", GDB_SIZEOF_REG, offsetof(struct pt_regs, ugp)}, + { "cs0", GDB_SIZEOF_REG, offsetof(struct pt_regs, cs0)}, + { "cs1", GDB_SIZEOF_REG, offsetof(struct pt_regs, cs1)}, { "psp", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmpsp)}, { "elr", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmel)}, { "est", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmest)}, diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c index 670b1b0bee63..3982d9c9ec2b 100644 --- a/arch/hexagon/kernel/ptrace.c +++ b/arch/hexagon/kernel/ptrace.c @@ -76,6 +76,10 @@ static int genregs_get(struct task_struct *target, dummy = pt_cause(regs); ONEXT(&dummy, cause); ONEXT(&pt_badva(regs), badva); +#if CONFIG_HEXAGON_ARCH_VERSION >=4 + ONEXT(®s->cs0, cs0); + ONEXT(®s->cs1, cs1); +#endif /* Pad the rest with zeros, if needed */ if (!ret) @@ -123,6 +127,11 @@ static int genregs_set(struct task_struct *target, INEXT(&bucket, cause); INEXT(&bucket, badva); +#if CONFIG_HEXAGON_ARCH_VERSION >=4 + INEXT(®s->cs0, cs0); + INEXT(®s->cs1, cs1); +#endif + /* Ignore the rest, if needed */ if (!ret) ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c index 60fa2ca3202b..a1492a69752b 100644 --- a/arch/hexagon/kernel/signal.c +++ b/arch/hexagon/kernel/signal.c @@ -66,7 +66,10 @@ static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) err |= __put_user(regs->preds, &sc->sc_regs.p3_0); err |= __put_user(regs->gp, &sc->sc_regs.gp); err |= __put_user(regs->ugp, &sc->sc_regs.ugp); - +#if CONFIG_HEXAGON_ARCH_VERSION >= 4 + err |= __put_user(regs->cs0, &sc->sc_regs.cs0); + err |= __put_user(regs->cs1, &sc->sc_regs.cs1); +#endif tmp = pt_elr(regs); err |= __put_user(tmp, &sc->sc_regs.pc); tmp = pt_cause(regs); err |= __put_user(tmp, &sc->sc_regs.cause); tmp = pt_badva(regs); err |= __put_user(tmp, &sc->sc_regs.badva); @@ -93,7 +96,10 @@ static int restore_sigcontext(struct pt_regs *regs, err |= __get_user(regs->preds, &sc->sc_regs.p3_0); err |= __get_user(regs->gp, &sc->sc_regs.gp); err |= __get_user(regs->ugp, &sc->sc_regs.ugp); - +#if CONFIG_HEXAGON_ARCH_VERSION >= 4 + err |= __get_user(regs->cs0, &sc->sc_regs.cs0); + err |= __get_user(regs->cs1, &sc->sc_regs.cs1); +#endif err |= __get_user(tmp, &sc->sc_regs.pc); pt_set_elr(regs, tmp); return err; diff --git a/arch/hexagon/kernel/vm_entry.S b/arch/hexagon/kernel/vm_entry.S index 425e50c694f7..ffe4a424b706 100644 --- a/arch/hexagon/kernel/vm_entry.S +++ b/arch/hexagon/kernel/vm_entry.S @@ -45,48 +45,88 @@ * number in the case where we decode a system call (trap0(#1)). */ +#if CONFIG_HEXAGON_ARCH_VERSION < 4 #define save_pt_regs()\ - memd(R0 + #_PT_R3130) = R31:30; \ + memd(R0 + #_PT_R3130) = R31:30; \ + { memw(R0 + #_PT_R2928) = R28; \ + R31 = memw(R0 + #_PT_ER_VMPSP); }\ + { memw(R0 + #(_PT_R2928 + 4)) = R31; \ + R31 = ugp; } \ + { memd(R0 + #_PT_R2726) = R27:26; \ + R30 = gp ; } \ + memd(R0 + #_PT_R2524) = R25:24; \ + memd(R0 + #_PT_R2322) = R23:22; \ + memd(R0 + #_PT_R2120) = R21:20; \ + memd(R0 + #_PT_R1918) = R19:18; \ + memd(R0 + #_PT_R1716) = R17:16; \ + memd(R0 + #_PT_R1514) = R15:14; \ + memd(R0 + #_PT_R1312) = R13:12; \ + { memd(R0 + #_PT_R1110) = R11:10; \ + R15 = lc0; } \ + { memd(R0 + #_PT_R0908) = R9:8; \ + R14 = sa0; } \ + { memd(R0 + #_PT_R0706) = R7:6; \ + R13 = lc1; } \ + { memd(R0 + #_PT_R0504) = R5:4; \ + R12 = sa1; } \ + { memd(R0 + #_PT_GPUGP) = R31:30; \ + R11 = m1; \ + R2.H = #HI(_THREAD_SIZE); } \ + { memd(R0 + #_PT_LC0SA0) = R15:14; \ + R10 = m0; \ + R2.L = #LO(_THREAD_SIZE); } \ + { memd(R0 + #_PT_LC1SA1) = R13:12; \ + R15 = p3:0; \ + R2 = neg(R2); } \ + { memd(R0 + #_PT_M1M0) = R11:10; \ + R14 = usr; \ + R2 = and(R0,R2); } \ + { memd(R0 + #_PT_PREDSUSR) = R15:14; \ + THREADINFO_REG = R2; } \ + { r24 = memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS); \ + memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R0; \ + R2 = #-1; } \ + { memw(R0 + #_PT_SYSCALL_NR) = R2; \ + R30 = #0; } +#else +/* V4+ */ +/* the # ## # syntax inserts a literal ## */ +#define save_pt_regs()\ + { memd(R0 + #_PT_R3130) = R31:30; \ + R30 = memw(R0 + #_PT_ER_VMPSP); }\ { memw(R0 + #_PT_R2928) = R28; \ - R31 = memw(R0 + #_PT_ER_VMPSP); }\ - { memw(R0 + #(_PT_R2928 + 4)) = R31; \ - R31 = ugp; } \ - { memd(R0 + #_PT_R2726) = R27:26; \ - R30 = gp ; } \ - memd(R0 + #_PT_R2524) = R25:24; \ - memd(R0 + #_PT_R2322) = R23:22; \ - memd(R0 + #_PT_R2120) = R21:20; \ - memd(R0 + #_PT_R1918) = R19:18; \ - memd(R0 + #_PT_R1716) = R17:16; \ - memd(R0 + #_PT_R1514) = R15:14; \ - memd(R0 + #_PT_R1312) = R13:12; \ + memw(R0 + #(_PT_R2928 + 4)) = R30; }\ + { R31:30 = C11:10; \ + memd(R0 + #_PT_R2726) = R27:26; \ + memd(R0 + #_PT_R2524) = R25:24; }\ + { memd(R0 + #_PT_R2322) = R23:22; \ + memd(R0 + #_PT_R2120) = R21:20; }\ + { memd(R0 + #_PT_R1918) = R19:18; \ + memd(R0 + #_PT_R1716) = R17:16; }\ + { memd(R0 + #_PT_R1514) = R15:14; \ + memd(R0 + #_PT_R1312) = R13:12; \ + R17:16 = C13:12; }\ { memd(R0 + #_PT_R1110) = R11:10; \ - R15 = lc0; } \ - { memd(R0 + #_PT_R0908) = R9:8; \ - R14 = sa0; } \ + memd(R0 + #_PT_R0908) = R9:8; \ + R15:14 = C1:0; } \ { memd(R0 + #_PT_R0706) = R7:6; \ - R13 = lc1; } \ - { memd(R0 + #_PT_R0504) = R5:4; \ - R12 = sa1; } \ - { memd(R0 + #_PT_UGPGP) = R31:30; \ - R11 = m1; \ - R2.H = #HI(_THREAD_SIZE); } \ - { memd(R0 + #_PT_LC0SA0) = R15:14; \ - R10 = m0; \ - R2.L = #LO(_THREAD_SIZE); } \ - { memd(R0 + #_PT_LC1SA1) = R13:12; \ - R15 = p3:0; \ - R2 = neg(R2); } \ + memd(R0 + #_PT_R0504) = R5:4; \ + R13:12 = C3:2; } \ + { memd(R0 + #_PT_GPUGP) = R31:30; \ + memd(R0 + #_PT_LC0SA0) = R15:14; \ + R11:10 = C7:6; }\ + { THREADINFO_REG = and(R0, # ## #-_THREAD_SIZE); \ + memd(R0 + #_PT_LC1SA1) = R13:12; \ + R15 = p3:0; }\ { memd(R0 + #_PT_M1M0) = R11:10; \ - R14 = usr; \ - R2 = and(R0,R2); } \ - { memd(R0 + #_PT_PREDSUSR) = R15:14; \ - THREADINFO_REG = R2; } \ + memw(R0 + #_PT_PREDSUSR + 4) = R15; }\ { r24 = memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS); \ memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R0; \ R2 = #-1; } \ { memw(R0 + #_PT_SYSCALL_NR) = R2; \ + memd(R0 + #_PT_CS1CS0) = R17:16; \ R30 = #0; } +#endif /* * Restore registers and thread_info.regs state. THREADINFO_REG @@ -94,6 +134,7 @@ * preserved. Don't restore R29 (SP) until later. */ +#if CONFIG_HEXAGON_ARCH_VERSION < 4 #define restore_pt_regs() \ { memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R24; \ R15:14 = memd(R0 + #_PT_PREDSUSR); } \ @@ -121,11 +162,44 @@ R23:22 = memd(R0 + #_PT_R2322); } \ { R25:24 = memd(R0 + #_PT_R2524); \ R27:26 = memd(R0 + #_PT_R2726); } \ - R31:30 = memd(R0 + #_PT_UGPGP); \ + R31:30 = memd(R0 + #_PT_GPUGP); \ { R28 = memw(R0 + #_PT_R2928); \ ugp = R31; } \ { R31:30 = memd(R0 + #_PT_R3130); \ gp = R30; } +#else +/* V4+ */ +#define restore_pt_regs() \ + { memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R24; \ + R15:14 = memd(R0 + #_PT_PREDSUSR); } \ + { R11:10 = memd(R0 + #_PT_M1M0); \ + R13:12 = memd(R0 + #_PT_LC1SA1); \ + p3:0 = R15; } \ + { R15:14 = memd(R0 + #_PT_LC0SA0); \ + R3:2 = memd(R0 + #_PT_R0302); \ + usr = R14; } \ + { R5:4 = memd(R0 + #_PT_R0504); \ + R7:6 = memd(R0 + #_PT_R0706); \ + C7:6 = R11:10; }\ + { R9:8 = memd(R0 + #_PT_R0908); \ + R11:10 = memd(R0 + #_PT_R1110); \ + C3:2 = R13:12; }\ + { R13:12 = memd(R0 + #_PT_R1312); \ + R15:14 = memd(R0 + #_PT_R1514); \ + C1:0 = R15:14; }\ + { R17:16 = memd(R0 + #_PT_R1716); \ + R19:18 = memd(R0 + #_PT_R1918); } \ + { R21:20 = memd(R0 + #_PT_R2120); \ + R23:22 = memd(R0 + #_PT_R2322); } \ + { R25:24 = memd(R0 + #_PT_R2524); \ + R27:26 = memd(R0 + #_PT_R2726); } \ + R31:30 = memd(R0 + #_PT_CS1CS0); \ + { C13:12 = R31:30; \ + R31:30 = memd(R0 + #_PT_GPUGP) ; \ + R28 = memw(R0 + #_PT_R2928); }\ + { C11:10 = R31:30; \ + R31:30 = memd(R0 + #_PT_R3130); } +#endif /* * Clears off enough space for the rest of pt_regs; evrec is a part @@ -139,6 +213,7 @@ * Need to save off R0, R1, R2, R3 immediately. */ +#if CONFIG_HEXAGON_ARCH_VERSION < 4 #define vm_event_entry(CHandler) \ { \ R29 = add(R29, #-(_PT_REGS_SIZE)); \ @@ -158,6 +233,34 @@ R1.H = #HI(CHandler); \ jump event_dispatch; \ } +#else +/* V4+ */ +/* turn on I$ prefetch early */ +/* the # ## # syntax inserts a literal ## */ +#define vm_event_entry(CHandler) \ + { \ + R29 = add(R29, #-(_PT_REGS_SIZE)); \ + memd(R29 + #(_PT_R0100 + -_PT_REGS_SIZE)) = R1:0; \ + memd(R29 + #(_PT_R0302 + -_PT_REGS_SIZE)) = R3:2; \ + R0 = usr; \ + } \ + { \ + memw(R29 + #_PT_PREDSUSR) = R0; \ + R0 = setbit(R0, #16); \ + } \ + usr = R0; \ + R1:0 = G1:0; \ + { \ + memd(R29 + #_PT_ER_VMEL) = R1:0; \ + R1 = # ## #(CHandler); \ + R3:2 = G3:2; \ + } \ + { \ + R0 = R29; \ + memd(R29 + #_PT_ER_VMPSP) = R3:2; \ + jump event_dispatch; \ + } +#endif .text /* @@ -184,8 +287,10 @@ event_dispatch: /* "Nested control path" -- if the previous mode was kernel */ R0 = memw(R29 + #_PT_ER_VMEST); - P0 = tstbit(R0, #HVM_VMEST_UM_SFT); - if !P0 jump restore_all; + { + P0 = tstbit(R0, #HVM_VMEST_UM_SFT); + if (!P0.new) jump:nt restore_all; + } /* * Returning from system call, normally coming back from user mode */ @@ -198,11 +303,18 @@ return_from_syscall: * Coming back from the C-world, our thread info pointer * should be in the designated register (usually R19) */ +#if CONFIG_HEXAGON_ARCH_VERSION < 4 R1.L = #LO(_TIF_ALLWORK_MASK) { R1.H = #HI(_TIF_ALLWORK_MASK); R0 = memw(THREADINFO_REG + #_THREAD_INFO_FLAGS); } +#else + { + R1 = ##_TIF_ALLWORK_MASK; + R0 = memw(THREADINFO_REG + #_THREAD_INFO_FLAGS); + } +#endif /* * Compare against the "return to userspace" _TIF_WORK_MASK @@ -222,10 +334,14 @@ work_pending: work_notifysig: /* this is the part that's kind of fuzzy. */ R1 = and(R0, #(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME)); - P0 = cmp.eq(R1, #0); - if P0 jump restore_all - R1 = R0; /* unsigned long thread_info_flags */ - R0 = R29; /* regs should still be at top of stack */ + { + P0 = cmp.eq(R1, #0); + if P0.new jump:t restore_all; + } + { + R1 = R0; /* unsigned long thread_info_flags */ + R0 = R29; /* regs should still be at top of stack */ + } call do_notify_resume restore_all: @@ -235,14 +351,23 @@ restore_all: /* do the setregs here for VM 0.5 */ /* R29 here should already be pointing at pt_regs */ - R1:0 = memd(R29 + #_PT_ER_VMEL); - R3:2 = memd(R29 + #_PT_ER_VMPSP); + { + R1:0 = memd(R29 + #_PT_ER_VMEL); + R3:2 = memd(R29 + #_PT_ER_VMPSP); + } +#if CONFIG_HEXAGON_ARCH_VERSION < 4 trap1(#HVM_TRAP1_VMSETREGS); +#else + G1:0 = R1:0; + G3:2 = R3:2; +#endif R0 = R29 restore_pt_regs() - R1:0 = memd(R29 + #_PT_R0100); - R29 = add(R29, #_PT_REGS_SIZE); + { + R1:0 = memd(R29 + #_PT_R0100); + R29 = add(R29, #_PT_REGS_SIZE); + } trap1(#HVM_TRAP1_VMRTE) /* Notreached */ diff --git a/arch/hexagon/kernel/vm_events.c b/arch/hexagon/kernel/vm_events.c index 9b5a4a295a68..5b81bacf7125 100644 --- a/arch/hexagon/kernel/vm_events.c +++ b/arch/hexagon/kernel/vm_events.c @@ -42,6 +42,8 @@ void show_regs(struct pt_regs *regs) regs->lc1, regs->sa1, regs->m1); printk(KERN_EMERG "gp: \t0x%08lx ugp: 0x%08lx usr: 0x%08lx\n", regs->gp, regs->ugp, regs->usr); + printk(KERN_EMERG "cs0: \t0x%08lx cs1: 0x%08lx\n", + regs->cs0, regs->cs1); printk(KERN_EMERG "r0: \t0x%08lx %08lx %08lx %08lx\n", regs->r00, regs->r01, regs->r02, -- cgit v1.2.2 From a11e67c2611d483622aad007a3533e7dfbea700e Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Tue, 29 May 2012 17:23:14 -0500 Subject: Hexagon: Signal and return path fixes This fixes the return value of sigreturn and moves the work pending check into a c routine for readability and fixes the loop for multiple pending signals. Based on feedback from Al Viro. Signed-off-by: Richard Kuo --- arch/hexagon/include/uapi/asm/signal.h | 2 + arch/hexagon/kernel/process.c | 41 ++++++++++++++++ arch/hexagon/kernel/signal.c | 29 ++---------- arch/hexagon/kernel/traps.c | 13 +---- arch/hexagon/kernel/vm_entry.S | 87 ++++++++++++++-------------------- 5 files changed, 84 insertions(+), 88 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/include/uapi/asm/signal.h b/arch/hexagon/include/uapi/asm/signal.h index 939556817d34..24b998888916 100644 --- a/arch/hexagon/include/uapi/asm/signal.h +++ b/arch/hexagon/include/uapi/asm/signal.h @@ -21,6 +21,8 @@ extern unsigned long __rt_sigtramp_template[2]; +void do_signal(struct pt_regs *regs); + #include #endif diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c index 06ae9ffcabd5..dc72ed5b9ed9 100644 --- a/arch/hexagon/kernel/process.c +++ b/arch/hexagon/kernel/process.c @@ -24,6 +24,7 @@ #include #include #include +#include /* * Program thread launch. Often defined as a macro in processor.h, @@ -202,3 +203,43 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) { return 0; } + + +/* + * Called on the exit path of event entry; see vm_entry.S + * + * Interrupts will already be disabled. + * + * Returns 0 if there's no need to re-check for more work. + */ + +int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) +{ + if (!(thread_info_flags & _TIF_ALLWORK_MASK)) { + return 0; + } /* shortcut -- no work to be done */ + + local_irq_enable(); + + if (thread_info_flags & _TIF_NEED_RESCHED) { + schedule(); + return 1; + } + + if (thread_info_flags & _TIF_SIGPENDING) { + do_signal(regs); + return 1; + } + + if (thread_info_flags & _TIF_NOTIFY_RESUME) { + clear_thread_flag(TIF_NOTIFY_RESUME); + tracehook_notify_resume(regs); + if (current->replacement_session_keyring) + key_replace_session_keyring(); + return 1; + } + + /* Should not even reach here */ + panic("%s: bad thread_info flags 0x%08x\n", __func__, + thread_info_flags); +} diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c index a1492a69752b..8a20e8ed5d7d 100644 --- a/arch/hexagon/kernel/signal.c +++ b/arch/hexagon/kernel/signal.c @@ -199,7 +199,7 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, /* * Called from return-from-event code. */ -static void do_signal(struct pt_regs *regs) +void do_signal(struct pt_regs *regs) { struct k_sigaction sigact; siginfo_t info; @@ -216,8 +216,9 @@ static void do_signal(struct pt_regs *regs) } /* - * If we came from a system call, handle the restart. + * No (more) signals; if we came from a system call, handle the restart. */ + if (regs->syscall_nr >= 0) { switch (regs->r00) { case -ERESTARTNOHAND: @@ -240,17 +241,6 @@ no_restart: restore_saved_sigmask(); } -void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) -{ - if (thread_info_flags & _TIF_SIGPENDING) - do_signal(regs); - - if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - } -} - /* * Architecture-specific wrappers for signal-related system calls */ @@ -278,21 +268,12 @@ asmlinkage int sys_rt_sigreturn(void) /* Restore the user's stack as well */ pt_psp(regs) = regs->r29; - /* - * Leave a trace in the stack frame that this was a sigreturn. - * If the system call is to replay, we've already restored the - * number in the GPR slot and it will be regenerated on the - * new system call trap entry. Note that if restore_sigcontext() - * did something other than a bulk copy of the pt_regs struct, - * we could avoid this assignment by simply not overwriting - * regs->syscall_nr. - */ - regs->syscall_nr = __NR_rt_sigreturn; + regs->syscall_nr = -1; if (restore_altstack(&frame->uc.uc_stack)) goto badframe; - return 0; + return regs->r00; badframe: force_sig(SIGSEGV, current); diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c index be5e2dd9c9d3..d59ee62f772d 100644 --- a/arch/hexagon/kernel/traps.c +++ b/arch/hexagon/kernel/traps.c @@ -356,7 +356,6 @@ long sys_syscall(void) void do_trap0(struct pt_regs *regs) { - unsigned long syscallret = 0; syscall_fn syscall; switch (pt_cause(regs)) { @@ -396,21 +395,11 @@ void do_trap0(struct pt_regs *regs) } else { syscall = (syscall_fn) (sys_call_table[regs->syscall_nr]); - syscallret = syscall(regs->r00, regs->r01, + regs->r00 = syscall(regs->r00, regs->r01, regs->r02, regs->r03, regs->r04, regs->r05); } - /* - * If it was a sigreturn system call, don't overwrite - * r0 value in stack frame with return value. - * - * __NR_sigreturn doesn't seem to exist in new unistd.h - */ - - if (regs->syscall_nr != __NR_rt_sigreturn) - regs->r00 = syscallret; - /* allow strace to get the syscall return state */ if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE))) tracehook_report_syscall_exit(regs, 0); diff --git a/arch/hexagon/kernel/vm_entry.S b/arch/hexagon/kernel/vm_entry.S index ffe4a424b706..053551ee7114 100644 --- a/arch/hexagon/kernel/vm_entry.S +++ b/arch/hexagon/kernel/vm_entry.S @@ -274,6 +274,9 @@ event_dispatch: callr r1 /* + * Coming back from the C-world, our thread info pointer + * should be in the designated register (usually R19) + * * If we were in kernel mode, we don't need to check scheduler * or signals if CONFIG_PREEMPT is not set. If set, then it has * to jump to a need_resched kind of block. @@ -286,67 +289,43 @@ event_dispatch: #endif /* "Nested control path" -- if the previous mode was kernel */ - R0 = memw(R29 + #_PT_ER_VMEST); { - P0 = tstbit(R0, #HVM_VMEST_UM_SFT); - if (!P0.new) jump:nt restore_all; + R0 = memw(R29 + #_PT_ER_VMEST); + R16.L = #LO(do_work_pending); } - /* - * Returning from system call, normally coming back from user mode - */ -return_from_syscall: - /* Disable interrupts while checking TIF */ - R0 = #VM_INT_DISABLE - trap1(#HVM_TRAP1_VMSETIE) - - /* - * Coming back from the C-world, our thread info pointer - * should be in the designated register (usually R19) - */ -#if CONFIG_HEXAGON_ARCH_VERSION < 4 - R1.L = #LO(_TIF_ALLWORK_MASK) { - R1.H = #HI(_TIF_ALLWORK_MASK); - R0 = memw(THREADINFO_REG + #_THREAD_INFO_FLAGS); - } -#else - { - R1 = ##_TIF_ALLWORK_MASK; - R0 = memw(THREADINFO_REG + #_THREAD_INFO_FLAGS); + P0 = tstbit(R0, #HVM_VMEST_UM_SFT); + if (!P0.new) jump:nt restore_all; + R16.H = #HI(do_work_pending); + R0 = #VM_INT_DISABLE; } -#endif /* - * Compare against the "return to userspace" _TIF_WORK_MASK + * Check also the return from fork/system call, normally coming back from + * user mode + * + * R16 needs to have do_work_pending, and R0 should have VM_INT_DISABLE */ - R1 = and(R1,R0); - { P0 = cmp.eq(R1,#0); if (!P0.new) jump:t work_pending;} - jump restore_all; /* we're outta here! */ -work_pending: +check_work_pending: + /* Disable interrupts while checking TIF */ + trap1(#HVM_TRAP1_VMSETIE) { - P0 = tstbit(R1, #TIF_NEED_RESCHED); - if (!P0.new) jump:nt work_notifysig; + R0 = R29; /* regs should still be at top of stack */ + R1 = memw(THREADINFO_REG + #_THREAD_INFO_FLAGS); + callr R16; } - call schedule - jump return_from_syscall; /* check for more work */ -work_notifysig: - /* this is the part that's kind of fuzzy. */ - R1 = and(R0, #(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME)); - { - P0 = cmp.eq(R1, #0); - if P0.new jump:t restore_all; - } { - R1 = R0; /* unsigned long thread_info_flags */ - R0 = R29; /* regs should still be at top of stack */ + P0 = cmp.eq(R0, #0); if (!P0.new) jump:nt check_work_pending; + R0 = #VM_INT_DISABLE; } - call do_notify_resume restore_all: - /* Disable interrupts, if they weren't already, before reg restore. */ - R0 = #VM_INT_DISABLE + /* + * Disable interrupts, if they weren't already, before reg restore. + * R0 gets preloaded with #VM_INT_DISABLE before we get here. + */ trap1(#HVM_TRAP1_VMSETIE) /* do the setregs here for VM 0.5 */ @@ -371,6 +350,7 @@ restore_all: trap1(#HVM_TRAP1_VMRTE) /* Notreached */ + .globl _K_enter_genex _K_enter_genex: vm_event_entry(do_genex) @@ -390,9 +370,12 @@ _K_enter_machcheck: .globl ret_from_fork ret_from_fork: - call schedule_tail - P0 = cmp.eq(R24, #0); - if P0 jump return_from_syscall - R0 = R25; - callr R24 - jump return_from_syscall + { + call schedule_tail; + R16.H = #HI(do_work_pending); + } + { + R16.L = #LO(do_work_pending); + R0 = #VM_INT_DISABLE; + jump check_work_pending; + } -- cgit v1.2.2 From 9cdae82d14f8f9e272304dccb48434482e57d43c Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Tue, 29 May 2012 18:56:39 -0500 Subject: Hexagon: check to if we will overflow the signal stack Signed-off-by: Richard Kuo --- arch/hexagon/kernel/signal.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c index 8a20e8ed5d7d..097623c0c4b4 100644 --- a/arch/hexagon/kernel/signal.c +++ b/arch/hexagon/kernel/signal.c @@ -41,6 +41,10 @@ static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, { unsigned long sp = regs->r29; + /* check if we would overflow the alt stack */ + if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) + return (void __user __force *)-1UL; + /* Switch to signal stack if appropriate */ if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) sp = current->sas_ss_sp + current->sas_ss_size; -- cgit v1.2.2 From 0357d2f2a8cde3069d800eb63c1ee41fed31e1b1 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Wed, 20 Jun 2012 16:06:26 -0500 Subject: Hexagon: remove keyring related call Signed-off-by: Richard Kuo --- arch/hexagon/kernel/process.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c index dc72ed5b9ed9..9eb43b3ae802 100644 --- a/arch/hexagon/kernel/process.c +++ b/arch/hexagon/kernel/process.c @@ -234,9 +234,6 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); - return 1; } /* Should not even reach here */ -- cgit v1.2.2 From 20f704b69af63bffbc8e70bcf21990318a8912f5 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Fri, 30 Nov 2012 14:53:56 -0600 Subject: Hexagon: fix initial page table setup prior to jump to VA Use the exact number of pages needed to be mapped pre-VA-jump, then map 896MB afterwards, which the arch mem init will fix up. Signed-off-by: Richard Kuo --- arch/hexagon/kernel/head.S | 85 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/kernel/head.S b/arch/hexagon/kernel/head.S index 477320c455f7..8e88d246ca69 100644 --- a/arch/hexagon/kernel/head.S +++ b/arch/hexagon/kernel/head.S @@ -25,6 +25,9 @@ #include #include #include +#include + +#define SEGTABLE_ENTRIES #0x0e0 __INIT ENTRY(stext) @@ -63,27 +66,73 @@ ENTRY(stext) | __HEXAGON_C_WB_L2 << 6 \ | __HVM_PDE_S_4MB) - r1 = pc - r2.H = #0xffc0 - r2.L = #0x0000 - r1 = and(r1,r2) /* round PC to 4MB boundary */ + /* + * Get number of VA=PA entries; only really needed for jump + * to hyperspace; gets blown away immediately after + */ + + { + r1.l = #LO(_end); + r2.l = #LO(stext); + r3 = #1; + } + { + r1.h = #HI(_end); + r2.h = #HI(stext); + r3 = asl(r3, #22); + } + { + r1 = sub(r1, r2); + r3 = add(r3, #-1); + } /* r1 = _end - stext */ + r1 = add(r1, r3); /* + (4M-1) */ + r26 = lsr(r1, #22); /* / 4M = # of entries */ + + r1 = r25; + r2.h = #0xffc0; + r2.l = #0x0000; /* round back down to 4MB boundary */ + r1 = and(r1,r2); r2 = lsr(r1, #22) /* 4MB page number */ r2 = asl(r2, #2) /* times sizeof(PTE) (4bytes) */ r0 = add(r0,r2) /* r0 = address of correct PTE */ r2 = #PTE_BITS r1 = add(r1,r2) /* r1 = 4MB PTE for the first entry */ r2.h = #0x0040 - r2.l = #0x0000 /* 4MB */ - memw(r0 ++ #4) = r1 - r1 = add(r1, r2) + r2.l = #0x0000 /* 4MB increments */ + loop0(1f,r26); +1: memw(r0 ++ #4) = r1 + { r1 = add(r1, r2); } :endloop0 - r0 = r24 + /* Also need to overwrite the initial 0xc0000000 entries */ + /* PAGE_OFFSET >> (4MB shift - 4 bytes per entry shift) */ + R1.H = #HI(PAGE_OFFSET >> (22 - 2)) + R1.L = #LO(PAGE_OFFSET >> (22 - 2)) + + r0 = add(r1, r24); /* advance to 0xc0000000 entry */ + r1 = r25; + r2.h = #0xffc0; + r2.l = #0x0000; /* round back down to 4MB boundary */ + r1 = and(r1,r2); /* for huge page */ + r2 = #PTE_BITS + r1 = add(r1,r2); + r2.h = #0x0040 + r2.l = #0x0000 /* 4MB increments */ + + loop0(1f,SEGTABLE_ENTRIES); +1: + memw(r0 ++ #4) = r1; + { r1 = add(r1,r2); } :endloop0 + + r0 = r24; /* * The subroutine wrapper around the virtual instruction touches * no memory, so we should be able to use it even here. + * Note that in this version, R1 and R2 get "clobbered"; see + * vm_ops.S */ + r1 = #VM_TRANS_TYPE_TABLE call __vmnewmap; /* Jump into virtual address range. */ @@ -97,17 +146,29 @@ ENTRY(stext) __head_s_vaddr_target: /* * Tear down VA=PA translation now that we are running - * in the desgnated kernel segments. + * in kernel virtual space. */ r0 = #__HVM_PDE_S_INVALID - r1 = r24 - loop0(1f,#0x100) + + r1.h = #0xffc0; + r1.l = #0x0000; + r2 = r25; /* phys_offset */ + r2 = and(r1,r2); + + r1.l = #lo(swapper_pg_dir) + r1.h = #hi(swapper_pg_dir) + r2 = lsr(r2, #22) /* 4MB page number */ + r2 = asl(r2, #2) /* times sizeof(PTE) (4bytes) */ + r1 = add(r1,r2); + loop0(1f,r26) + 1: { memw(R1 ++ #4) = R0 }:endloop0 r0 = r24 + r1 = #VM_TRANS_TYPE_TABLE call __vmnewmap /* Go ahead and install the trap0 return so angel calls work */ @@ -150,7 +211,7 @@ __head_s_vaddr_target: r2 = sub(r2,r0); call memset; - /* Set PHYS_OFFSET; should still be in R25 */ + /* Set PHYS_OFFSET; should be in R25 */ #ifdef CONFIG_HEXAGON_PHYS_OFFSET r0.l = #LO(__phys_offset); r0.h = #HI(__phys_offset); -- cgit v1.2.2 From db0fe532db3f60c93147514adfd1765894ea501e Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Sun, 28 Oct 2012 19:54:37 -0500 Subject: Hexagon: add support for additional exceptions Add multi-reg-write and unaligned-PC exceptions. Signed-off-by: Richard Kuo --- arch/hexagon/kernel/traps.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c index d59ee62f772d..12164a30e8ff 100644 --- a/arch/hexagon/kernel/traps.c +++ b/arch/hexagon/kernel/traps.c @@ -65,6 +65,10 @@ static const char *ex_name(int ex) return "Write protection fault"; case HVM_GE_C_XMAL: return "Misaligned instruction"; + case HVM_GE_C_WREG: + return "Multiple writes to same register in packet"; + case HVM_GE_C_PCAL: + return "Program counter values that are not properly aligned"; case HVM_GE_C_RMAL: return "Misaligned data load"; case HVM_GE_C_WMAL: @@ -324,6 +328,12 @@ void do_genex(struct pt_regs *regs) case HVM_GE_C_XMAL: misaligned_instruction(regs); break; + case HVM_GE_C_WREG: + illegal_instruction(regs); + break; + case HVM_GE_C_PCAL: + misaligned_instruction(regs); + break; case HVM_GE_C_RMAL: misaligned_data_load(regs); break; -- cgit v1.2.2 From f8722a4d5243e779d6795e2d775c9114c44a6c26 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Thu, 6 Dec 2012 16:37:43 -0600 Subject: Hexagon: use correct work mask when checking for more work Signed-off-by: Richard Kuo --- arch/hexagon/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c index 9eb43b3ae802..c300ce37267f 100644 --- a/arch/hexagon/kernel/process.c +++ b/arch/hexagon/kernel/process.c @@ -215,7 +215,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) { - if (!(thread_info_flags & _TIF_ALLWORK_MASK)) { + if (!(thread_info_flags & _TIF_WORK_MASK)) { return 0; } /* shortcut -- no work to be done */ -- cgit v1.2.2 From 7777746c40876834c1527689336e43c8381b1921 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Thu, 7 Mar 2013 12:03:10 -0600 Subject: Hexagon: add support for single-stepping (v4+) Hardware single-step is only available on v4 and later architectures. Signed-off-by: Richard Kuo --- arch/hexagon/include/uapi/asm/ptrace.h | 5 +++++ arch/hexagon/include/uapi/asm/registers.h | 3 +++ arch/hexagon/kernel/ptrace.c | 15 +++++++++++++++ arch/hexagon/kernel/traps.c | 11 +++++++++++ arch/hexagon/kernel/vm_entry.S | 3 +++ arch/hexagon/kernel/vm_vectors.S | 2 +- 6 files changed, 38 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/hexagon/include/uapi/asm/ptrace.h b/arch/hexagon/include/uapi/asm/ptrace.h index 1ffce0c6ee07..065e5b32313f 100644 --- a/arch/hexagon/include/uapi/asm/ptrace.h +++ b/arch/hexagon/include/uapi/asm/ptrace.h @@ -36,4 +36,9 @@ extern const char *regs_query_register_name(unsigned int offset); ((struct pt_regs *) \ ((unsigned long)current_thread_info() + THREAD_SIZE) - 1) +#if CONFIG_HEXAGON_ARCH_VERSION >= 4 +#define arch_has_single_step() (1) +#endif + + #endif diff --git a/arch/hexagon/include/uapi/asm/registers.h b/arch/hexagon/include/uapi/asm/registers.h index 80504155ca3a..fcdb5f96a984 100644 --- a/arch/hexagon/include/uapi/asm/registers.h +++ b/arch/hexagon/include/uapi/asm/registers.h @@ -211,6 +211,9 @@ struct pt_regs { #define pt_psp(regs) ((regs)->hvmer.vmpsp) #define pt_badva(regs) ((regs)->hvmer.vmbadva) +#define pt_set_singlestep(regs) ((regs)->hvmer.vmest |= (1<hvmer.vmest &= ~(1<SP = (unsigned long) &((regs)->hvmer);\ diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c index 3982d9c9ec2b..70df50d797d8 100644 --- a/arch/hexagon/kernel/ptrace.c +++ b/arch/hexagon/kernel/ptrace.c @@ -32,6 +32,21 @@ #include +#if arch_has_single_step() +/* Both called from ptrace_resume */ +void user_enable_single_step(struct task_struct *child) +{ + pt_set_singlestep(task_pt_regs(child)); + set_tsk_thread_flag(child, TIF_SINGLESTEP); +} + +void user_disable_single_step(struct task_struct *child) +{ + pt_clr_singlestep(task_pt_regs(child)); + clear_tsk_thread_flag(child, TIF_SINGLESTEP); +} +#endif + static int genregs_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c index 12164a30e8ff..c2eeeef55335 100644 --- a/arch/hexagon/kernel/traps.c +++ b/arch/hexagon/kernel/traps.c @@ -451,3 +451,14 @@ void do_machcheck(struct pt_regs *regs) /* Halt and catch fire */ __vmstop(); } + +/* + * Treat this like the old 0xdb trap. + */ + +void do_debug_exception(struct pt_regs *regs) +{ + regs->hvmer.vmest &= ~HVM_VMEST_CAUSE_MSK; + regs->hvmer.vmest |= (TRAP_DEBUG << HVM_VMEST_CAUSE_SFT); + do_trap0(regs); +} diff --git a/arch/hexagon/kernel/vm_entry.S b/arch/hexagon/kernel/vm_entry.S index 053551ee7114..9add73ab57d8 100644 --- a/arch/hexagon/kernel/vm_entry.S +++ b/arch/hexagon/kernel/vm_entry.S @@ -367,6 +367,9 @@ _K_enter_trap0: _K_enter_machcheck: vm_event_entry(do_machcheck) + .globl _K_enter_debug +_K_enter_debug: + vm_event_entry(do_debug_exception) .globl ret_from_fork ret_from_fork: diff --git a/arch/hexagon/kernel/vm_vectors.S b/arch/hexagon/kernel/vm_vectors.S index 620f42cc582a..aff4054a2cff 100644 --- a/arch/hexagon/kernel/vm_vectors.S +++ b/arch/hexagon/kernel/vm_vectors.S @@ -41,7 +41,7 @@ _K_VM_event_vector: jump 1b; /* Reset */ jump _K_enter_machcheck; jump _K_enter_genex; - jump 1b; /* 3 Rsvd */ + jump _K_enter_debug; jump 1b; /* 4 Rsvd */ jump _K_enter_trap0; jump 1b; /* 6 Rsvd */ -- cgit v1.2.2 From 2b3c744c3bcaab14ad2cc0f067d76c2f119085a5 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Mon, 4 Feb 2013 14:17:15 -0600 Subject: Hexagon: don't print info for offline CPU's Signed-off-by: Richard Kuo --- arch/hexagon/kernel/setup.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c index 2e2304f7b7ee..d2dcb6bcdad7 100644 --- a/arch/hexagon/kernel/setup.c +++ b/arch/hexagon/kernel/setup.c @@ -130,6 +130,11 @@ static int show_cpuinfo(struct seq_file *m, void *v) { int cpu = (unsigned long) v - 1; +#ifdef CONFIG_SMP + if (!cpu_online(cpu)) + return 0; +#endif + seq_printf(m, "processor\t: %d\n", cpu); seq_printf(m, "model name\t: Hexagon Virtual Machine\n"); seq_printf(m, "BogoMips\t: %lu.%02lu\n", -- cgit v1.2.2 From f167063a0c4e97dfbd8e42df76e71022bb2bdb7f Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Tue, 5 Feb 2013 14:23:37 -0600 Subject: Hexagon: switch to using the device type for IO mappings Uncached on our architecture can still have side effects such as canceled/replayed transactions; device type prevents this. Signed-off-by: Richard Kuo --- arch/hexagon/include/asm/vm_mmu.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/include/asm/vm_mmu.h b/arch/hexagon/include/asm/vm_mmu.h index 9a94de7969bb..e67b573cfef0 100644 --- a/arch/hexagon/include/asm/vm_mmu.h +++ b/arch/hexagon/include/asm/vm_mmu.h @@ -68,14 +68,13 @@ #define __HEXAGON_C_WB 0x0 /* Write-back, no L2 */ #define __HEXAGON_C_WT 0x1 /* Write-through, no L2 */ +#define __HEXAGON_C_UNC 0x6 /* Uncached memory */ +#if CONFIG_HEXAGON_ARCH_VERSION >= 2 #define __HEXAGON_C_DEV 0x4 /* Device register space */ -#define __HEXAGON_C_WT_L2 0x5 /* Write-through, with L2 */ -/* this really should be #if CONFIG_HEXAGON_ARCH = 2 but that's not defined */ -#if defined(CONFIG_HEXAGON_COMET) || defined(CONFIG_QDSP6_ST1) -#define __HEXAGON_C_UNC __HEXAGON_C_DEV #else -#define __HEXAGON_C_UNC 0x6 /* Uncached memory */ +#define __HEXAGON_C_DEV __HEXAGON_C_UNC #endif +#define __HEXAGON_C_WT_L2 0x5 /* Write-through, with L2 */ #define __HEXAGON_C_WB_L2 0x7 /* Write-back, with L2 */ /* -- cgit v1.2.2 From 1ce81f4f8727f42c052fe814f3df20bc92fdb168 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Fri, 1 Mar 2013 13:16:15 -0600 Subject: Hexagon: add IOMEM and _relaxed IO macros Signed-off-by: Richard Kuo --- arch/hexagon/include/asm/io.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'arch') diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h index e527cfeff5ba..6199ed5f064b 100644 --- a/arch/hexagon/include/asm/io.h +++ b/arch/hexagon/include/asm/io.h @@ -40,6 +40,8 @@ #define IO_SPACE_LIMIT 0xffff #define _IO_BASE ((void __iomem *)0xfe000000) +#define IOMEM(x) ((void __force __iomem *)(x)) + extern int remap_area_pages(unsigned long start, unsigned long phys_addr, unsigned long end, unsigned long flags); @@ -175,6 +177,18 @@ static inline void writel(u32 data, volatile void __iomem *addr) #define __raw_readw readw #define __raw_readl readl +/* + * http://comments.gmane.org/gmane.linux.ports.arm.kernel/117626 + */ + +#define readb_relaxed __raw_readb +#define readw_relaxed __raw_readw +#define readl_relaxed __raw_readl + +#define writeb_relaxed __raw_writeb +#define writew_relaxed __raw_writew +#define writel_relaxed __raw_writel + /* * Need an mtype somewhere in here, for cache type deals? * This is probably too long for an inline. -- cgit v1.2.2 From 3981c4728bcec97f352f8518f05a0015c7df6a3c Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Tue, 23 Oct 2012 18:26:01 -0500 Subject: Hexagon: fix up int enable/disable at ret_from_fork Check return coming out of check_work_pending, and if copy_thread passed us a function in r24, call it. Based on feedback from Al Viro. Signed-off-by: Richard Kuo --- arch/hexagon/kernel/vm_entry.S | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/kernel/vm_entry.S b/arch/hexagon/kernel/vm_entry.S index 9add73ab57d8..34470911d4a7 100644 --- a/arch/hexagon/kernel/vm_entry.S +++ b/arch/hexagon/kernel/vm_entry.S @@ -374,11 +374,20 @@ _K_enter_debug: .globl ret_from_fork ret_from_fork: { - call schedule_tail; + call schedule_tail R16.H = #HI(do_work_pending); } { + P0 = cmp.eq(R24, #0); R16.L = #LO(do_work_pending); R0 = #VM_INT_DISABLE; - jump check_work_pending; + } + if P0 jump check_work_pending + { + R0 = R25; + callr R24 + } + { + jump check_work_pending + R0 = #VM_INT_DISABLE; } -- cgit v1.2.2 From 820927768711b3c5c1f4aa7408433ff6ad37fd56 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Thu, 25 Oct 2012 13:50:27 -0500 Subject: Hexagon: fix psp/sp macro Based on feedback from Al Viro; previous-stack-pointer and user reg for same should always be kept consistent. Signed-off-by: Richard Kuo --- arch/hexagon/include/uapi/asm/registers.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/include/uapi/asm/registers.h b/arch/hexagon/include/uapi/asm/registers.h index fcdb5f96a984..487d6ceca5e7 100644 --- a/arch/hexagon/include/uapi/asm/registers.h +++ b/arch/hexagon/include/uapi/asm/registers.h @@ -215,8 +215,7 @@ struct pt_regs { #define pt_clr_singlestep(regs) ((regs)->hvmer.vmest &= ~(1<SP = (unsigned long) &((regs)->hvmer);\ + pt_psp(regs) = (regs)->SP = (sp);\ } while (0) #define pt_set_kmode(regs) \ -- cgit v1.2.2 From c05c3ec401a68888f23f489b7bd6f88117836bc9 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Tue, 19 Feb 2013 19:19:50 -0600 Subject: Hexagon: use generic sys_fork, sys_vfork, and sys_clone Signed-off-by: Richard Kuo --- arch/hexagon/Kconfig | 2 ++ arch/hexagon/include/uapi/asm/unistd.h | 3 +++ 2 files changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index b059d8c29fb5..9b94b0fcb777 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -30,6 +30,8 @@ config HEXAGON select GENERIC_CLOCKEVENTS_BROADCAST select MODULES_USE_ELF_RELA select GENERIC_CPU_DEVICES + select GENERIC_KERNEL_THREAD + select GENERIC_KERNEL_EXECVE ---help--- Qualcomm Hexagon is a processor architecture designed for high performance and low power across a wide variety of applications. diff --git a/arch/hexagon/include/uapi/asm/unistd.h b/arch/hexagon/include/uapi/asm/unistd.h index 4a87cc47075c..ffee405d6803 100644 --- a/arch/hexagon/include/uapi/asm/unistd.h +++ b/arch/hexagon/include/uapi/asm/unistd.h @@ -27,6 +27,9 @@ */ #define sys_mmap2 sys_mmap_pgoff +#define __ARCH_WANT_SYS_EXECVE #define __ARCH_WANT_SYS_CLONE +#define __ARCH_WANT_SYS_VFORK +#define __ARCH_WANT_SYS_FORK #include -- cgit v1.2.2 From 0d3ab450a786a87412ecc57657a3c327efb8c6fe Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Tue, 23 Oct 2012 18:26:20 -0500 Subject: Hexagon: break up user fn/arg register setting Signed-off-by: Richard Kuo --- arch/hexagon/kernel/process.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c index c300ce37267f..a91b290b923a 100644 --- a/arch/hexagon/kernel/process.c +++ b/arch/hexagon/kernel/process.c @@ -113,7 +113,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, if (unlikely(p->flags & PF_KTHREAD)) { memset(childregs, 0, sizeof(struct pt_regs)); /* r24 <- fn, r25 <- arg */ - ss->r2524 = usp | ((u64)arg << 32); + ss->r24 = usp; + ss->r25 = arg; pt_set_kmode(childregs); return 0; } -- cgit v1.2.2 From f3f601c1d2728f02544cfd143eaa82e5398b3e9b Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Tue, 19 Feb 2013 19:25:48 -0600 Subject: Hexagon: fix signal.c compile error Signed-off-by: Richard Kuo --- arch/hexagon/include/uapi/asm/signal.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/hexagon/include/uapi/asm/signal.h b/arch/hexagon/include/uapi/asm/signal.h index 24b998888916..98106e55ad4f 100644 --- a/arch/hexagon/include/uapi/asm/signal.h +++ b/arch/hexagon/include/uapi/asm/signal.h @@ -19,6 +19,8 @@ #ifndef _ASM_SIGNAL_H #define _ASM_SIGNAL_H +#include + extern unsigned long __rt_sigtramp_template[2]; void do_signal(struct pt_regs *regs); -- cgit v1.2.2 From 7959bd76a18cea222eb9ee9040709ffc0a4612de Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Mon, 25 Mar 2013 21:57:36 -0500 Subject: Hexagon: add translation types for __vmnewmap Signed-off-by: Richard Kuo --- arch/hexagon/include/asm/hexagon_vm.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/hexagon/include/asm/hexagon_vm.h b/arch/hexagon/include/asm/hexagon_vm.h index 6b81e4d5ecb1..2d84cef5b8a0 100644 --- a/arch/hexagon/include/asm/hexagon_vm.h +++ b/arch/hexagon/include/asm/hexagon_vm.h @@ -197,6 +197,13 @@ static inline long __vmintop_clear(long i) * Constants for virtual instruction parameters and return values */ +/* vmnewmap arguments */ + +#define VM_TRANS_TYPE_LINEAR 0 +#define VM_TRANS_TYPE_TABLE 1 +#define VM_TLB_INVALIDATE_FALSE 0 +#define VM_TLB_INVALIDATE_TRUE 1 + /* vmsetie arguments */ #define VM_INT_DISABLE 0 -- cgit v1.2.2 From 7c6a5df44fd90a288fe067581c5564859c071fc0 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Thu, 28 Mar 2013 20:45:40 -0500 Subject: Hexagon: update copyright dates Signed-off-by: Richard Kuo --- arch/hexagon/include/asm/atomic.h | 2 +- arch/hexagon/include/asm/elf.h | 2 +- arch/hexagon/include/asm/hexagon_vm.h | 2 +- arch/hexagon/include/asm/io.h | 2 +- arch/hexagon/include/asm/mem-layout.h | 2 +- arch/hexagon/include/asm/page.h | 2 +- arch/hexagon/include/asm/processor.h | 2 +- arch/hexagon/include/asm/vm_mmu.h | 2 +- arch/hexagon/kernel/asm-offsets.c | 2 +- arch/hexagon/kernel/head.S | 2 +- arch/hexagon/kernel/kgdb.c | 2 +- arch/hexagon/kernel/ptrace.c | 2 +- arch/hexagon/kernel/setup.c | 2 +- arch/hexagon/kernel/signal.c | 2 +- arch/hexagon/kernel/traps.c | 2 +- arch/hexagon/kernel/vm_entry.S | 2 +- arch/hexagon/kernel/vm_events.c | 2 +- arch/hexagon/kernel/vm_vectors.S | 2 +- arch/hexagon/kernel/vmlinux.lds.S | 2 +- arch/hexagon/mm/init.c | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/include/asm/atomic.h b/arch/hexagon/include/asm/atomic.h index c6670390d255..8a64ff2337f6 100644 --- a/arch/hexagon/include/asm/atomic.h +++ b/arch/hexagon/include/asm/atomic.h @@ -1,7 +1,7 @@ /* * Atomic operations for the Hexagon architecture * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify diff --git a/arch/hexagon/include/asm/elf.h b/arch/hexagon/include/asm/elf.h index 83b8d0ea4cb8..f52d8ec9ccf2 100644 --- a/arch/hexagon/include/asm/elf.h +++ b/arch/hexagon/include/asm/elf.h @@ -1,7 +1,7 @@ /* * ELF definitions for the Hexagon architecture * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2012, The Linux Foundation. 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 and diff --git a/arch/hexagon/include/asm/hexagon_vm.h b/arch/hexagon/include/asm/hexagon_vm.h index 2d84cef5b8a0..67bb6d6f3337 100644 --- a/arch/hexagon/include/asm/hexagon_vm.h +++ b/arch/hexagon/include/asm/hexagon_vm.h @@ -1,7 +1,7 @@ /* * Declarations for to Hexagon Virtal Machine. * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2013, The Linux Foundation. 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 and diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h index 6199ed5f064b..1b7698e19139 100644 --- a/arch/hexagon/include/asm/io.h +++ b/arch/hexagon/include/asm/io.h @@ -1,7 +1,7 @@ /* * IO definitions for the Hexagon architecture * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2013, The Linux Foundation. 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 and diff --git a/arch/hexagon/include/asm/mem-layout.h b/arch/hexagon/include/asm/mem-layout.h index 3724cea5c59c..2cb7a706208f 100644 --- a/arch/hexagon/include/asm/mem-layout.h +++ b/arch/hexagon/include/asm/mem-layout.h @@ -1,7 +1,7 @@ /* * Memory layout definitions for the Hexagon architecture * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2013, The Linux Foundation. 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 and diff --git a/arch/hexagon/include/asm/page.h b/arch/hexagon/include/asm/page.h index de1b2871d09c..f3b26f14a7c7 100644 --- a/arch/hexagon/include/asm/page.h +++ b/arch/hexagon/include/asm/page.h @@ -1,7 +1,7 @@ /* * Page management definitions for the Hexagon architecture * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2013, The Linux Foundation. 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 and diff --git a/arch/hexagon/include/asm/processor.h b/arch/hexagon/include/asm/processor.h index 758bcd1f290c..45a825402f63 100644 --- a/arch/hexagon/include/asm/processor.h +++ b/arch/hexagon/include/asm/processor.h @@ -1,7 +1,7 @@ /* * Process/processor support for the Hexagon architecture * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2012, The Linux Foundation. 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 and diff --git a/arch/hexagon/include/asm/vm_mmu.h b/arch/hexagon/include/asm/vm_mmu.h index e67b573cfef0..096537d8f4c5 100644 --- a/arch/hexagon/include/asm/vm_mmu.h +++ b/arch/hexagon/include/asm/vm_mmu.h @@ -1,7 +1,7 @@ /* * Hexagon VM page table entry definitions * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2011,2013 The Linux Foundation. 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 and diff --git a/arch/hexagon/kernel/asm-offsets.c b/arch/hexagon/kernel/asm-offsets.c index 181515ba825d..308be68d4fb3 100644 --- a/arch/hexagon/kernel/asm-offsets.c +++ b/arch/hexagon/kernel/asm-offsets.c @@ -5,7 +5,7 @@ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2012, The Linux Foundation. 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 and diff --git a/arch/hexagon/kernel/head.S b/arch/hexagon/kernel/head.S index 8e88d246ca69..b9b63d085db2 100644 --- a/arch/hexagon/kernel/head.S +++ b/arch/hexagon/kernel/head.S @@ -1,7 +1,7 @@ /* * Early kernel startup code for Hexagon * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify diff --git a/arch/hexagon/kernel/kgdb.c b/arch/hexagon/kernel/kgdb.c index 19f9e6ca5e33..82d5c2593323 100644 --- a/arch/hexagon/kernel/kgdb.c +++ b/arch/hexagon/kernel/kgdb.c @@ -1,7 +1,7 @@ /* * arch/hexagon/kernel/kgdb.c - Hexagon KGDB Support * - * Copyright (c) 2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2012, The Linux Foundation. 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 and diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c index 70df50d797d8..de829eb7f185 100644 --- a/arch/hexagon/kernel/ptrace.c +++ b/arch/hexagon/kernel/ptrace.c @@ -1,7 +1,7 @@ /* * Ptrace support for Hexagon * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2013, The Linux Foundation. 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 and diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c index d2dcb6bcdad7..bfe13311d70d 100644 --- a/arch/hexagon/kernel/setup.c +++ b/arch/hexagon/kernel/setup.c @@ -1,7 +1,7 @@ /* * Arch related setup for Hexagon * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2013, The Linux Foundation. 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 and diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c index 097623c0c4b4..d7c73874b515 100644 --- a/arch/hexagon/kernel/signal.c +++ b/arch/hexagon/kernel/signal.c @@ -1,7 +1,7 @@ /* * Signal support for Hexagon processor * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2012, The Linux Foundation. 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 and diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c index c2eeeef55335..aaf53f883710 100644 --- a/arch/hexagon/kernel/traps.c +++ b/arch/hexagon/kernel/traps.c @@ -1,7 +1,7 @@ /* * Kernel traps/events for Hexagon processor * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2013, The Linux Foundation. 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 and diff --git a/arch/hexagon/kernel/vm_entry.S b/arch/hexagon/kernel/vm_entry.S index 34470911d4a7..e3086185fc9f 100644 --- a/arch/hexagon/kernel/vm_entry.S +++ b/arch/hexagon/kernel/vm_entry.S @@ -1,7 +1,7 @@ /* * Event entry/exit for Hexagon * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2013, The Linux Foundation. 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 and diff --git a/arch/hexagon/kernel/vm_events.c b/arch/hexagon/kernel/vm_events.c index 5b81bacf7125..3e4453091889 100644 --- a/arch/hexagon/kernel/vm_events.c +++ b/arch/hexagon/kernel/vm_events.c @@ -1,7 +1,7 @@ /* * Mostly IRQ support for Hexagon * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2012, The Linux Foundation. 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 and diff --git a/arch/hexagon/kernel/vm_vectors.S b/arch/hexagon/kernel/vm_vectors.S index aff4054a2cff..791a7422dde4 100644 --- a/arch/hexagon/kernel/vm_vectors.S +++ b/arch/hexagon/kernel/vm_vectors.S @@ -1,7 +1,7 @@ /* * Event jump tables * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2012,2013, The Linux Foundation. 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 and diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S index fafb886511e3..44d8c47bae2f 100644 --- a/arch/hexagon/kernel/vmlinux.lds.S +++ b/arch/hexagon/kernel/vmlinux.lds.S @@ -1,7 +1,7 @@ /* * Linker script for Hexagon kernel * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2013, The Linux Foundation. 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 and diff --git a/arch/hexagon/mm/init.c b/arch/hexagon/mm/init.c index 8e803a6e3402..2561d259a296 100644 --- a/arch/hexagon/mm/init.c +++ b/arch/hexagon/mm/init.c @@ -1,7 +1,7 @@ /* * Memory subsystem initialization for Hexagon * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2013, The Linux Foundation. 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 and -- cgit v1.2.2 From 65af3a3f89d726701c6436c4e223d9e2e7d525bc Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Thu, 21 Mar 2013 14:34:58 +0100 Subject: arch: remove CONFIG_GENERIC_FIND_NEXT_BIT again CONFIG_GENERIC_FIND_NEXT_BIT was removed in v3.0, but reappeared in two architectures. Remove it again. Signed-off-by: Paul Bolle Acked-by: Jonas Bonn Signed-off-by: Richard Kuo --- arch/hexagon/Kconfig | 3 --- arch/openrisc/Kconfig | 3 --- 2 files changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index 9b94b0fcb777..a0c0fb09d677 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -77,9 +77,6 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM def_bool y -config GENERIC_FIND_NEXT_BIT - def_bool y - config GENERIC_HWEIGHT def_bool y diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index 9ab3bf2eca8d..81b9ddbc9166 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig @@ -55,9 +55,6 @@ config TRACE_IRQFLAGS_SUPPORT config GENERIC_CSUM def_bool y -config GENERIC_FIND_NEXT_BIT - def_bool y - source "init/Kconfig" -- cgit v1.2.2 From 41929798bb71a5997e4b8a760ab8e0dd4f592bb6 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Thu, 21 Mar 2013 11:13:17 +0100 Subject: Hexagon: remove two Kconfig entries The Kconfig entries for HEXAGON_VM and HEXAGON_ANGEL_TRAPS were added, together with the configuration and makefiles for the Hexagon architecture, in v3.2. They have never been used. They can safely be removed. Signed-off-by: Paul Bolle [rkuo@codeaurora.org: adjust for line changes in Kconfig] Signed-off-by: Richard Kuo --- arch/hexagon/Kconfig | 9 --------- 1 file changed, 9 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index a0c0fb09d677..04dff5bdcbf7 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -105,9 +105,6 @@ config HEXAGON_ARCH_VERSION int "Architecture version" default 2 -config HEXAGON_VM - def_bool y - config CMDLINE string "Default kernel command string" default "" @@ -118,12 +115,6 @@ config CMDLINE minimum, you should specify the memory size and the root device (e.g., mem=64M root=/dev/nfs). -config HEXAGON_ANGEL_TRAPS - bool "Use Angel Traps" - default n - ---help--- - Enable angel debug traps (for printk's). - config SMP bool "Multi-Processing support" ---help--- -- cgit v1.2.2 From 610208bc8dec79e0ff4930a330187597d89ab861 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Mon, 8 Apr 2013 17:48:33 -0500 Subject: Hexagon: fix signal number for user mem faults Signed-off-by: Richard Kuo --- arch/hexagon/mm/vm_fault.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/mm/vm_fault.c b/arch/hexagon/mm/vm_fault.c index 308ef0ce648b..1bd276dbec7d 100644 --- a/arch/hexagon/mm/vm_fault.c +++ b/arch/hexagon/mm/vm_fault.c @@ -147,7 +147,7 @@ good_area: } info.si_errno = 0; info.si_addr = (void __user *)address; - force_sig_info(info.si_code, &info, current); + force_sig_info(info.si_signo, &info, current); return; bad_area: @@ -158,7 +158,7 @@ bad_area: info.si_errno = 0; info.si_code = si_code; info.si_addr = (void *)address; - force_sig_info(SIGSEGV, &info, current); + force_sig_info(info.si_signo, &info, current); return; } /* Kernel-mode fault falls through */ -- cgit v1.2.2 From c710f5908768e18d8e8081e917fda362089cb13f Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Mon, 8 Apr 2013 18:26:25 -0500 Subject: Hexagon: fix return value for notify_resume case in do_work_pending Signed-off-by: Richard Kuo --- arch/hexagon/kernel/process.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c index a91b290b923a..7fcc636b6238 100644 --- a/arch/hexagon/kernel/process.c +++ b/arch/hexagon/kernel/process.c @@ -235,6 +235,7 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); + return 1; } /* Should not even reach here */ -- cgit v1.2.2 From 5e1150542fd1d75fe2b6c3491415c860cdc06be2 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Mon, 8 Apr 2013 18:30:12 -0500 Subject: Hexagon: use correct translations for DMA mappings With physical offsets, pa<->va translations aren't just based on PAGE_OFFSET anymore. Signed-off-by: Richard Kuo --- arch/hexagon/include/asm/page.h | 5 +++++ arch/hexagon/kernel/dma.c | 27 +++++++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/include/asm/page.h b/arch/hexagon/include/asm/page.h index f3b26f14a7c7..93f5669b4aa1 100644 --- a/arch/hexagon/include/asm/page.h +++ b/arch/hexagon/include/asm/page.h @@ -140,6 +140,11 @@ static inline void clear_page(void *page) */ #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) +#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) +#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) + +#define page_to_virt(page) __va(page_to_phys(page)) + /* * For port to Hexagon Virtual Machine, MAYBE we check for attempts * to reference reserved HVM space, but in any case, the VM will be diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c index 65c7bdcf565e..b74f9bae31a3 100644 --- a/arch/hexagon/kernel/dma.c +++ b/arch/hexagon/kernel/dma.c @@ -1,7 +1,7 @@ /* * DMA implementation for Hexagon * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2012, The Linux Foundation. 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 and @@ -23,12 +23,18 @@ #include #include #include +#include struct dma_map_ops *dma_ops; EXPORT_SYMBOL(dma_ops); int bad_dma_address; /* globals are automatically initialized to zero */ +static inline void *dma_addr_to_virt(dma_addr_t dma_addr) +{ + return phys_to_virt((unsigned long) dma_addr); +} + int dma_supported(struct device *dev, u64 mask) { if (mask == DMA_BIT_MASK(32)) @@ -60,6 +66,12 @@ static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, { void *ret; + /* + * Our max_low_pfn should have been backed off by 16MB in + * mm/init.c to create DMA coherent space. Use that as the VA + * for the pool. + */ + if (coherent_pool == NULL) { coherent_pool = gen_pool_create(PAGE_SHIFT, -1); @@ -67,7 +79,7 @@ static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, panic("Can't create %s() memory pool!", __func__); else gen_pool_add(coherent_pool, - (PAGE_OFFSET + (max_low_pfn << PAGE_SHIFT)), + pfn_to_virt(max_low_pfn), hexagon_coherent_pool_size, -1); } @@ -75,7 +87,7 @@ static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, if (ret) { memset(ret, 0, size); - *dma_addr = (dma_addr_t) (ret - PAGE_OFFSET); + *dma_addr = (dma_addr_t) virt_to_phys(ret); } else *dma_addr = ~0; @@ -118,8 +130,8 @@ static int hexagon_map_sg(struct device *hwdev, struct scatterlist *sg, s->dma_length = s->length; - flush_dcache_range(PAGE_OFFSET + s->dma_address, - PAGE_OFFSET + s->dma_address + s->length); + flush_dcache_range(dma_addr_to_virt(s->dma_address), + dma_addr_to_virt(s->dma_address + s->length)); } return nents; @@ -149,11 +161,6 @@ static inline void dma_sync(void *addr, size_t size, } } -static inline void *dma_addr_to_virt(dma_addr_t dma_addr) -{ - return phys_to_virt((unsigned long) dma_addr); -} - /** * hexagon_map_page() - maps an address for device DMA * @dev: pointer to DMA device -- cgit v1.2.2 From 5c883b462aa5ecde3da6cabdca00f6abac22aa74 Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Mon, 8 Apr 2013 19:03:05 -0500 Subject: Hexagon: use correct translation for VMALLOC_START Signed-off-by: Richard Kuo --- arch/hexagon/include/asm/mem-layout.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/include/asm/mem-layout.h b/arch/hexagon/include/asm/mem-layout.h index 2cb7a706208f..60556f8c45d8 100644 --- a/arch/hexagon/include/asm/mem-layout.h +++ b/arch/hexagon/include/asm/mem-layout.h @@ -72,8 +72,7 @@ extern int max_kernel_seg; * supposed to be based on the amount of physical memory available */ -#define VMALLOC_START (PAGE_OFFSET + VMALLOC_OFFSET + \ - (unsigned long)high_memory) +#define VMALLOC_START ((unsigned long) __va(high_memory + VMALLOC_OFFSET)) /* Gap between physical ram and vmalloc space for guard purposes. */ #define VMALLOC_OFFSET PAGE_SIZE -- cgit v1.2.2 From 426d29ccb2a8d44c18d3167327ee82b38287e7bf Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Tue, 9 Apr 2013 17:06:08 -0500 Subject: Hexagon: add v4 CS regs to core copyout macro Signed-off-by: Richard Kuo --- arch/hexagon/include/asm/elf.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/hexagon/include/asm/elf.h b/arch/hexagon/include/asm/elf.h index f52d8ec9ccf2..e1b933a0e121 100644 --- a/arch/hexagon/include/asm/elf.h +++ b/arch/hexagon/include/asm/elf.h @@ -104,6 +104,16 @@ typedef unsigned long elf_fpregset_t; * Bypass the whole "regsets" thing for now and use the define. */ +#if CONFIG_HEXAGON_ARCH_VERSION >= 4 +#define CS_COPYREGS(DEST,REGS) \ +do {\ + DEST.cs0 = REGS->cs0;\ + DEST.cs1 = REGS->cs1;\ +} while (0) +#else +#define CS_COPYREGS(DEST,REGS) +#endif + #define ELF_CORE_COPY_REGS(DEST, REGS) \ do { \ DEST.r0 = REGS->r00; \ @@ -148,13 +158,12 @@ do { \ DEST.p3_0 = REGS->preds; \ DEST.gp = REGS->gp; \ DEST.ugp = REGS->ugp; \ - DEST.pc = pt_elr(REGS); \ + CS_COPYREGS(DEST,REGS); \ + DEST.pc = pt_elr(REGS); \ DEST.cause = pt_cause(REGS); \ DEST.badva = pt_badva(REGS); \ } while (0); - - /* * This is used to ensure we don't load something for the wrong architecture. * Checks the machine and ABI type. -- cgit v1.2.2