]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 May 2013 14:43:05 +0000 (07:43 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 May 2013 14:43:05 +0000 (07:43 -0700)
Pull Hexagon fixes from Richard Kuo:
 "Changes for the Hexagon architecture (and one touching OpenRISC).

  They include various fixes to make use of additional arch features and
  cleanups.  The largest functional change is a cleanup of the signal
  and event return paths"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux-hexagon-kernel: (32 commits)
  Hexagon: add v4 CS regs to core copyout macro
  Hexagon: use correct translation for VMALLOC_START
  Hexagon: use correct translations for DMA mappings
  Hexagon: fix return value for notify_resume case in do_work_pending
  Hexagon: fix signal number for user mem faults
  Hexagon: remove two Kconfig entries
  arch: remove CONFIG_GENERIC_FIND_NEXT_BIT again
  Hexagon: update copyright dates
  Hexagon: add translation types for __vmnewmap
  Hexagon: fix signal.c compile error
  Hexagon: break up user fn/arg register setting
  Hexagon: use generic sys_fork, sys_vfork, and sys_clone
  Hexagon: fix psp/sp macro
  Hexagon: fix up int enable/disable at ret_from_fork
  Hexagon: add IOMEM and _relaxed IO macros
  Hexagon: switch to using the device type for IO mappings
  Hexagon: don't print info for offline CPU's
  Hexagon: add support for single-stepping (v4+)
  Hexagon: use correct work mask when checking for more work
  Hexagon: add support for additional exceptions
  ...

34 files changed:
arch/hexagon/Kconfig
arch/hexagon/Makefile
arch/hexagon/include/asm/Kbuild
arch/hexagon/include/asm/atomic.h
arch/hexagon/include/asm/elf.h
arch/hexagon/include/asm/hexagon_vm.h
arch/hexagon/include/asm/io.h
arch/hexagon/include/asm/mem-layout.h
arch/hexagon/include/asm/page.h
arch/hexagon/include/asm/processor.h
arch/hexagon/include/asm/vm_mmu.h
arch/hexagon/include/uapi/asm/ptrace.h
arch/hexagon/include/uapi/asm/registers.h
arch/hexagon/include/uapi/asm/signal.h
arch/hexagon/include/uapi/asm/unistd.h
arch/hexagon/include/uapi/asm/user.h
arch/hexagon/kernel/Makefile
arch/hexagon/kernel/asm-offsets.c
arch/hexagon/kernel/dma.c
arch/hexagon/kernel/head.S
arch/hexagon/kernel/kgdb.c
arch/hexagon/kernel/process.c
arch/hexagon/kernel/ptrace.c
arch/hexagon/kernel/setup.c
arch/hexagon/kernel/signal.c
arch/hexagon/kernel/topology.c [deleted file]
arch/hexagon/kernel/traps.c
arch/hexagon/kernel/vm_entry.S
arch/hexagon/kernel/vm_events.c
arch/hexagon/kernel/vm_vectors.S
arch/hexagon/kernel/vmlinux.lds.S
arch/hexagon/mm/init.c
arch/hexagon/mm/vm_fault.c
arch/openrisc/Kconfig

index e4decc6b8947e4fe68180010a524e0f7b6600084..04dff5bdcbf72b30aebc5c2c5287d247eb3e7d2d 100644 (file)
@@ -29,21 +29,17 @@ config HEXAGON
        select GENERIC_CLOCKEVENTS
        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.
 
-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---
+         Platforms that don't load the kernel at zero set this.
 
 config FRAME_POINTER
        def_bool y
@@ -81,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
 
@@ -103,14 +96,14 @@ choice
 
 config HEXAGON_COMET
        bool "Comet Board"
-       select HEXAGON_ARCH_V2
        ---help---
          Support for the Comet platform.
 
 endchoice
 
-config HEXAGON_VM
-       def_bool y
+config HEXAGON_ARCH_VERSION
+       int "Architecture version"
+       default 2
 
 config CMDLINE
        string "Default kernel command string"
@@ -122,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---
index d00d900b256653b9a139e42a58032fea8fd374c0..207711a0fd0c3a63220675a3752b636a33f6e762 100644 (file)
@@ -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)
index bdb54ceb53bc9a8c564564cb2dfd2d3e0068db64..1da17caac23c9b353c19b84263905c8c75a1d4d4 100644 (file)
@@ -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
index 468fbb0781cdfb9a4ebc6d2b1b2a7ccb16c55dd3..8a64ff2337f651dda91e1d55396e5578262fb9e9 100644 (file)
@@ -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
@@ -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)
index 1f14e082588edc3cc0c5fb8804c72eff604318f1..e1b933a0e121ee92c38d48d93044a431a8d33bd0 100644 (file)
@@ -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
@@ -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.
@@ -168,15 +177,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
 
index c144bee6cabe506afc9f99071ad741c9727da8d7..67bb6d6f33372392635e617827ed44e82b3c5188 100644 (file)
@@ -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
  * 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,31 +191,19 @@ 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__ */
 
 /*
  * 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
@@ -224,6 +228,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 +266,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
index e527cfeff5bac6dd18473deb1930ffc77034c13f..1b7698e19139000d235fbb1f71674b21b538aa48 100644 (file)
@@ -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
@@ -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.
index af16e977c55ee4a43cb56e0087c13935640541cf..60556f8c45d87cc1c5f2cc58af53569910f3abc8 100644 (file)
@@ -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
 #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  */
@@ -55,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;
 
 /*
@@ -63,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
index 692adc213429a3e2d85a6c7955e43d54ba62261e..93f5669b4aa1a8c56bea29e999ce8b25c2306b9e 100644 (file)
@@ -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
@@ -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;
@@ -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
@@ -147,6 +152,7 @@ static inline void clear_page(void *page)
  */
 #define kern_addr_valid(addr)   (1)
 
+#include <asm/mem-layout.h>
 #include <asm-generic/memory_model.h>
 /* XXX Todo: implement assembly-optimized version of getorder. */
 #include <asm-generic/getorder.h>
index 6dd5d37068698bd4bcb161f50dac5dcf9de93658..45a825402f634ee4b650a08a60efc5c60d50e261 100644 (file)
@@ -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
@@ -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;
 };
index 9a94de7969bb5e192f57bb9d5bc6ca877376f23c..096537d8f4c51d1db0d69738b4cea73fff4cd14f 100644 (file)
@@ -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
 
 #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 */
 
 /*
index 1ffce0c6ee07559082fa475271e7656c2bbe3f9c..065e5b32313f1884b76365cba3e002d297ee3612 100644 (file)
@@ -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
index c20406f63b5cb2ab1bffc1aa48007f0f84a90344..487d6ceca5e7d407a69bd5c126c1f340bed10fb5 100644 (file)
@@ -57,10 +57,17 @@ struct pt_regs {
        };
        union {
                struct {
-                       unsigned long gp;
                        unsigned long ugp;
+                       unsigned long gp;
                };
-               long long int ugpgp;
+               long long int gpugp;
+       };
+       union {
+               struct {
+                       unsigned long cs0;
+                       unsigned long cs1;
+               };
+               long long int cs1cs0;
        };
        /*
        * Be extremely careful with rearranging these, if at all.  Some code
@@ -204,9 +211,11 @@ 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<<HVM_VMEST_SS_SFT))
+#define pt_clr_singlestep(regs) ((regs)->hvmer.vmest &= ~(1<<HVM_VMEST_SS_SFT))
+
 #define pt_set_rte_sp(regs, sp) do {\
-       pt_psp(regs) = (sp);\
-       (regs)->SP = (unsigned long) &((regs)->hvmer);\
+       pt_psp(regs) = (regs)->SP = (sp);\
        } while (0)
 
 #define pt_set_kmode(regs) \
index 939556817d340fa5e48dc8c46b57bd6e41d17bfd..98106e55ad4ff73299a156b87e527b29bc6384b1 100644 (file)
 #ifndef _ASM_SIGNAL_H
 #define _ASM_SIGNAL_H
 
+#include <uapi/asm/registers.h>
+
 extern unsigned long __rt_sigtramp_template[2];
 
+void do_signal(struct pt_regs *regs);
+
 #include <asm-generic/signal.h>
 
 #endif
index 4a87cc47075c37d4f3f43997876a1383206e8cba..ffee405d68034a004168e0763e26fd146273d14f 100644 (file)
@@ -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 <asm-generic/unistd.h>
index cef13ee1413f483567bb820ad4d893a2eccd3ee0..3dae94d9ced754f339dcaec3daf6044164847e05 100644 (file)
@@ -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
index 6c19501b487c3736deae991b95042d9a98d55c4a..29fc933a77225694b53f34770849b7d1b9d8cf99 100644 (file)
@@ -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
index 2d5e84d3b00d69a738eb52e90388a184fb790d54..308be68d4fb3d93cdbce3eecdec4d0908888e1df 100644 (file)
@@ -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
@@ -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);
index 65c7bdcf565ef94b02882a30a6be129075cee511..b74f9bae31a3b9e81204d3c86b51acd3dcfe65c6 100644 (file)
@@ -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
 #include <linux/genalloc.h>
 #include <asm/dma-mapping.h>
 #include <linux/module.h>
+#include <asm/page.h>
 
 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
index d859402c73bac00251cfde0109ce6a42bab7bf72..b9b63d085db2b1c67fc8c68b2ac0f47f66272d6b 100644 (file)
@@ -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
@@ -25,6 +25,9 @@
 #include <asm/mem-layout.h>
 #include <asm/vm_mmu.h>
 #include <asm/page.h>
+#include <asm/hexagon_vm.h>
+
+#define SEGTABLE_ENTRIES #0x0e0
 
        __INIT
 ENTRY(stext)
@@ -43,40 +46,93 @@ 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                      \
                  | __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
+
+       /*  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 */
 
-       r0 = r24
+       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.  */
@@ -90,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  */
@@ -143,6 +211,13 @@ __head_s_vaddr_target:
        r2 = sub(r2,r0);
        call memset;
 
+       /*  Set PHYS_OFFSET; should 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
 
index 344645370646bfdb91ffa1e21c0a9a93e060ab52..82d5c2593323ed420ac6b9af62309d85a032e355 100644 (file)
@@ -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
@@ -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)},
index 9b948c619a0320a28d55a23c1524843d133608b7..0a0dd5c05b46af8fda112b2ab9cc606a08d6d5a5 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/tick.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
+#include <linux/tracehook.h>
 
 /*
  * Program thread launch.  Often defined as a macro in processor.h,
@@ -95,7 +96,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;
        }
@@ -185,3 +187,41 @@ 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_WORK_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);
+               return 1;
+       }
+
+       /* Should not even reach here */
+       panic("%s: bad thread_info flags 0x%08x\n", __func__,
+               thread_info_flags);
+}
index 670b1b0bee63bf740e5979a28a12298b8b8084a8..de829eb7f1858f948ac54c7fcbae0c8c91aa6e53 100644 (file)
@@ -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
 
 #include <asm/user.h>
 
+#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,
@@ -76,6 +91,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(&regs->cs0, cs0);
+       ONEXT(&regs->cs1, cs1);
+#endif
 
        /* Pad the rest with zeros, if needed */
        if (!ret)
@@ -123,6 +142,11 @@ static int genregs_set(struct task_struct *target,
        INEXT(&bucket, cause);
        INEXT(&bucket, badva);
 
+#if CONFIG_HEXAGON_ARCH_VERSION >=4
+       INEXT(&regs->cs0, cs0);
+       INEXT(&regs->cs1, cs1);
+#endif
+
        /* Ignore the rest, if needed */
        if (!ret)
                ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
index 94a38783500870f06945f993e0840fbc01b0cb75..bfe13311d70d5c853f6f6a65e7f41abe753d16ff 100644 (file)
@@ -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
@@ -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
@@ -128,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",
index 60fa2ca3202be2060f2b9065a51447ab0c34d6d9..d7c73874b5150312196e484bc294b02e14bc7558 100644 (file)
@@ -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
@@ -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;
@@ -66,7 +70,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 +100,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;
@@ -193,7 +203,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;
@@ -210,8 +220,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:
@@ -234,17 +245,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
  */
@@ -272,21 +272,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/topology.c b/arch/hexagon/kernel/topology.c
deleted file mode 100644 (file)
index 352f27e..0000000
+++ /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 <linux/cpu.h>
-#include <linux/cpumask.h>
-#include <linux/init.h>
-#include <linux/node.h>
-#include <linux/nodemask.h>
-#include <linux/percpu.h>
-
-/*  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);
index cc2171b2aa04ce7f46b297f92e85673d38dbf3e1..7858663352b9ec1662959ad759a62ca07e3b639c 100644 (file)
@@ -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
@@ -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:
@@ -316,6 +320,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;
@@ -348,7 +358,6 @@ long sys_syscall(void)
 
 void do_trap0(struct pt_regs *regs)
 {
-       unsigned long syscallret = 0;
        syscall_fn syscall;
 
        switch (pt_cause(regs)) {
@@ -388,21 +397,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);
@@ -444,3 +443,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);
+}
index 425e50c694f7d8a453d6ee82134c2669b8dbd6f5..e3086185fc9ff69a401993597c9a46aba408848d 100644 (file)
@@ -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
  * 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
  * 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); } \
          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
  * 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)); \
                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
        /*
@@ -171,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.
@@ -183,69 +289,68 @@ 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 jump restore_all;
-       /*
-        * 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)
-        */
-       R1.L = #LO(_TIF_ALLWORK_MASK)
        {
-               R1.H = #HI(_TIF_ALLWORK_MASK);
-               R0 = memw(THREADINFO_REG + #_THREAD_INFO_FLAGS);
+               R0 = memw(R29 + #_PT_ER_VMEST);
+               R16.L = #LO(do_work_pending);
+       }
+       {
+               P0 = tstbit(R0, #HVM_VMEST_UM_SFT);
+               if (!P0.new) jump:nt restore_all;
+               R16.H = #HI(do_work_pending);
+               R0 = #VM_INT_DISABLE;
        }
 
        /*
-        * 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 jump restore_all
-       R1 = R0;        /* unsigned long thread_info_flags */
-       R0 = R29;       /* regs should still be at top of stack  */
-       call do_notify_resume
+       {
+               P0 = cmp.eq(R0, #0); if (!P0.new) jump:nt check_work_pending;
+               R0 = #VM_INT_DISABLE;
+       }
 
 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  */
        /*  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 */
 
+
        .globl _K_enter_genex
 _K_enter_genex:
        vm_event_entry(do_genex)
@@ -262,12 +367,27 @@ _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:
-       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);
+       }
+       {
+               P0 = cmp.eq(R24, #0);
+               R16.L = #LO(do_work_pending);
+               R0 = #VM_INT_DISABLE;
+       }
+       if P0 jump check_work_pending
+       {
+               R0 = R25;
+               callr R24
+       }
+       {
+               jump check_work_pending
+               R0 = #VM_INT_DISABLE;
+       }
index f337281ebe67aab12bd4d31a34d0f46e1c061f88..741aaa917cda5c867a1b866de1a6beab6157a93d 100644 (file)
@@ -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
@@ -44,6 +44,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,
index 620f42cc582a17180083058a001d3464b57ac907..791a7422dde42e9e072c1555b43bdbe815edc06b 100644 (file)
@@ -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
@@ -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  */
index 14e793f6abbfff6a4313720710646826233be8ea..44d8c47bae2f6cc6b8ba9566e15ae7af718ad871 100644 (file)
@@ -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
@@ -18,8 +18,6 @@
  * 02110-1301, USA.
  */
 
-#define LOAD_OFFSET PAGE_OFFSET
-
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/asm-offsets.h>   /*  Most of the kernel defines are here  */
 #include <asm/mem-layout.h>    /*  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
index 69ffcfd2879450de9fd16538be3d4acc7ee9e5f7..2561d259a2967f296130ea0393e71f5edabec2d1 100644 (file)
@@ -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
  * 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);
 
index 308ef0ce648baeb77ed933a6c30de55a94d96438..1bd276dbec7d3503f92a19fc7cb5a39df1051621 100644 (file)
@@ -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 */
index 9ab3bf2eca8d2efeef9f0adbadc8b94c356cb857..81b9ddbc9166473ef46a85c7640a135807c920c8 100644 (file)
@@ -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"