diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-01 10:43:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-01 10:43:05 -0400 |
commit | d70b1e06eb331afe1576ac23bb9523708026ba1f (patch) | |
tree | a6e430d45f8f7f37285369dcfd863a0358080c83 /arch/hexagon/kernel | |
parent | b0b885657b6c8ef63a46bc9299b2a7715d19acde (diff) | |
parent | 426d29ccb2a8d44c18d3167327ee82b38287e7bf (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux-hexagon-kernel
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
...
Diffstat (limited to 'arch/hexagon/kernel')
-rw-r--r-- | arch/hexagon/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/hexagon/kernel/asm-offsets.c | 5 | ||||
-rw-r--r-- | arch/hexagon/kernel/dma.c | 27 | ||||
-rw-r--r-- | arch/hexagon/kernel/head.S | 107 | ||||
-rw-r--r-- | arch/hexagon/kernel/kgdb.c | 4 | ||||
-rw-r--r-- | arch/hexagon/kernel/process.c | 42 | ||||
-rw-r--r-- | arch/hexagon/kernel/ptrace.c | 26 | ||||
-rw-r--r-- | arch/hexagon/kernel/setup.c | 9 | ||||
-rw-r--r-- | arch/hexagon/kernel/signal.c | 45 | ||||
-rw-r--r-- | arch/hexagon/kernel/topology.c | 52 | ||||
-rw-r--r-- | arch/hexagon/kernel/traps.c | 36 | ||||
-rw-r--r-- | arch/hexagon/kernel/vm_entry.S | 282 | ||||
-rw-r--r-- | arch/hexagon/kernel/vm_events.c | 4 | ||||
-rw-r--r-- | arch/hexagon/kernel/vm_vectors.S | 4 | ||||
-rw-r--r-- | arch/hexagon/kernel/vmlinux.lds.S | 12 |
15 files changed, 439 insertions, 218 deletions
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 @@ | |||
1 | extra-y := head.o vmlinux.lds | 1 | extra-y := head.o vmlinux.lds |
2 | 2 | ||
3 | obj-$(CONFIG_SMP) += smp.o topology.o | 3 | obj-$(CONFIG_SMP) += smp.o |
4 | 4 | ||
5 | obj-y += setup.o irq_cpu.o traps.o syscalltab.o signal.o time.o | 5 | obj-y += setup.o irq_cpu.o traps.o syscalltab.o signal.o time.o |
6 | obj-y += process.o trampoline.o reset.o ptrace.o vdso.o | 6 | obj-y += process.o trampoline.o reset.o ptrace.o vdso.o |
diff --git a/arch/hexagon/kernel/asm-offsets.c b/arch/hexagon/kernel/asm-offsets.c index 2d5e84d3b00d..308be68d4fb3 100644 --- a/arch/hexagon/kernel/asm-offsets.c +++ b/arch/hexagon/kernel/asm-offsets.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com | 5 | * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com |
6 | * Copyright (C) 2000 MIPS Technologies, Inc. | 6 | * Copyright (C) 2000 MIPS Technologies, Inc. |
7 | * | 7 | * |
8 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | 8 | * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2 and | 11 | * it under the terms of the GNU General Public License version 2 and |
@@ -44,7 +44,8 @@ int main(void) | |||
44 | 44 | ||
45 | COMMENT("Hexagon pt_regs definitions"); | 45 | COMMENT("Hexagon pt_regs definitions"); |
46 | OFFSET(_PT_SYSCALL_NR, pt_regs, syscall_nr); | 46 | OFFSET(_PT_SYSCALL_NR, pt_regs, syscall_nr); |
47 | OFFSET(_PT_UGPGP, pt_regs, ugpgp); | 47 | OFFSET(_PT_GPUGP, pt_regs, gpugp); |
48 | OFFSET(_PT_CS1CS0, pt_regs, cs1cs0); | ||
48 | OFFSET(_PT_R3130, pt_regs, r3130); | 49 | OFFSET(_PT_R3130, pt_regs, r3130); |
49 | OFFSET(_PT_R2928, pt_regs, r2928); | 50 | OFFSET(_PT_R2928, pt_regs, r2928); |
50 | OFFSET(_PT_R2726, pt_regs, r2726); | 51 | OFFSET(_PT_R2726, pt_regs, r2726); |
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 @@ | |||
1 | /* | 1 | /* |
2 | * DMA implementation for Hexagon | 2 | * DMA implementation for Hexagon |
3 | * | 3 | * |
4 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 and | 7 | * it under the terms of the GNU General Public License version 2 and |
@@ -23,12 +23,18 @@ | |||
23 | #include <linux/genalloc.h> | 23 | #include <linux/genalloc.h> |
24 | #include <asm/dma-mapping.h> | 24 | #include <asm/dma-mapping.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <asm/page.h> | ||
26 | 27 | ||
27 | struct dma_map_ops *dma_ops; | 28 | struct dma_map_ops *dma_ops; |
28 | EXPORT_SYMBOL(dma_ops); | 29 | EXPORT_SYMBOL(dma_ops); |
29 | 30 | ||
30 | int bad_dma_address; /* globals are automatically initialized to zero */ | 31 | int bad_dma_address; /* globals are automatically initialized to zero */ |
31 | 32 | ||
33 | static inline void *dma_addr_to_virt(dma_addr_t dma_addr) | ||
34 | { | ||
35 | return phys_to_virt((unsigned long) dma_addr); | ||
36 | } | ||
37 | |||
32 | int dma_supported(struct device *dev, u64 mask) | 38 | int dma_supported(struct device *dev, u64 mask) |
33 | { | 39 | { |
34 | if (mask == DMA_BIT_MASK(32)) | 40 | if (mask == DMA_BIT_MASK(32)) |
@@ -60,6 +66,12 @@ static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, | |||
60 | { | 66 | { |
61 | void *ret; | 67 | void *ret; |
62 | 68 | ||
69 | /* | ||
70 | * Our max_low_pfn should have been backed off by 16MB in | ||
71 | * mm/init.c to create DMA coherent space. Use that as the VA | ||
72 | * for the pool. | ||
73 | */ | ||
74 | |||
63 | if (coherent_pool == NULL) { | 75 | if (coherent_pool == NULL) { |
64 | coherent_pool = gen_pool_create(PAGE_SHIFT, -1); | 76 | coherent_pool = gen_pool_create(PAGE_SHIFT, -1); |
65 | 77 | ||
@@ -67,7 +79,7 @@ static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, | |||
67 | panic("Can't create %s() memory pool!", __func__); | 79 | panic("Can't create %s() memory pool!", __func__); |
68 | else | 80 | else |
69 | gen_pool_add(coherent_pool, | 81 | gen_pool_add(coherent_pool, |
70 | (PAGE_OFFSET + (max_low_pfn << PAGE_SHIFT)), | 82 | pfn_to_virt(max_low_pfn), |
71 | hexagon_coherent_pool_size, -1); | 83 | hexagon_coherent_pool_size, -1); |
72 | } | 84 | } |
73 | 85 | ||
@@ -75,7 +87,7 @@ static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, | |||
75 | 87 | ||
76 | if (ret) { | 88 | if (ret) { |
77 | memset(ret, 0, size); | 89 | memset(ret, 0, size); |
78 | *dma_addr = (dma_addr_t) (ret - PAGE_OFFSET); | 90 | *dma_addr = (dma_addr_t) virt_to_phys(ret); |
79 | } else | 91 | } else |
80 | *dma_addr = ~0; | 92 | *dma_addr = ~0; |
81 | 93 | ||
@@ -118,8 +130,8 @@ static int hexagon_map_sg(struct device *hwdev, struct scatterlist *sg, | |||
118 | 130 | ||
119 | s->dma_length = s->length; | 131 | s->dma_length = s->length; |
120 | 132 | ||
121 | flush_dcache_range(PAGE_OFFSET + s->dma_address, | 133 | flush_dcache_range(dma_addr_to_virt(s->dma_address), |
122 | PAGE_OFFSET + s->dma_address + s->length); | 134 | dma_addr_to_virt(s->dma_address + s->length)); |
123 | } | 135 | } |
124 | 136 | ||
125 | return nents; | 137 | return nents; |
@@ -149,11 +161,6 @@ static inline void dma_sync(void *addr, size_t size, | |||
149 | } | 161 | } |
150 | } | 162 | } |
151 | 163 | ||
152 | static inline void *dma_addr_to_virt(dma_addr_t dma_addr) | ||
153 | { | ||
154 | return phys_to_virt((unsigned long) dma_addr); | ||
155 | } | ||
156 | |||
157 | /** | 164 | /** |
158 | * hexagon_map_page() - maps an address for device DMA | 165 | * hexagon_map_page() - maps an address for device DMA |
159 | * @dev: pointer to DMA device | 166 | * @dev: pointer to DMA device |
diff --git a/arch/hexagon/kernel/head.S b/arch/hexagon/kernel/head.S index d859402c73ba..b9b63d085db2 100644 --- a/arch/hexagon/kernel/head.S +++ b/arch/hexagon/kernel/head.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Early kernel startup code for Hexagon | 2 | * Early kernel startup code for Hexagon |
3 | * | 3 | * |
4 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. |
5 | * | 5 | * |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -25,6 +25,9 @@ | |||
25 | #include <asm/mem-layout.h> | 25 | #include <asm/mem-layout.h> |
26 | #include <asm/vm_mmu.h> | 26 | #include <asm/vm_mmu.h> |
27 | #include <asm/page.h> | 27 | #include <asm/page.h> |
28 | #include <asm/hexagon_vm.h> | ||
29 | |||
30 | #define SEGTABLE_ENTRIES #0x0e0 | ||
28 | 31 | ||
29 | __INIT | 32 | __INIT |
30 | ENTRY(stext) | 33 | ENTRY(stext) |
@@ -43,40 +46,93 @@ ENTRY(stext) | |||
43 | * Symbol is kernel segment address, but we need | 46 | * Symbol is kernel segment address, but we need |
44 | * the logical/physical address. | 47 | * the logical/physical address. |
45 | */ | 48 | */ |
46 | r24 = asl(r24, #2) | 49 | r25 = pc; |
47 | r24 = lsr(r24, #2) | 50 | r2.h = #0xffc0; |
51 | r2.l = #0x0000; | ||
52 | r25 = and(r2,r25); /* R25 holds PHYS_OFFSET now */ | ||
53 | r1.h = #HI(PAGE_OFFSET); | ||
54 | r1.l = #LO(PAGE_OFFSET); | ||
55 | r24 = sub(r24,r1); /* swapper_pg_dir - PAGE_OFFSET */ | ||
56 | r24 = add(r24,r25); /* + PHYS_OFFSET */ | ||
48 | 57 | ||
49 | r0 = r24 | 58 | r0 = r24; /* aka __pa(swapper_pg_dir) */ |
50 | 59 | ||
51 | /* | 60 | /* |
52 | * Initialize a 16MB PTE to make the virtual and physical | 61 | * Initialize page dir to make the virtual and physical |
53 | * addresses where the kernel was loaded be identical. | 62 | * addresses where the kernel was loaded be identical. |
63 | * Done in 4MB chunks. | ||
54 | */ | 64 | */ |
55 | #define PTE_BITS ( __HVM_PTE_R | __HVM_PTE_W | __HVM_PTE_X \ | 65 | #define PTE_BITS ( __HVM_PTE_R | __HVM_PTE_W | __HVM_PTE_X \ |
56 | | __HEXAGON_C_WB_L2 << 6 \ | 66 | | __HEXAGON_C_WB_L2 << 6 \ |
57 | | __HVM_PDE_S_4MB) | 67 | | __HVM_PDE_S_4MB) |
58 | 68 | ||
59 | r1 = pc | 69 | /* |
60 | r2.H = #0xffc0 | 70 | * Get number of VA=PA entries; only really needed for jump |
61 | r2.L = #0x0000 | 71 | * to hyperspace; gets blown away immediately after |
62 | r1 = and(r1,r2) /* round PC to 4MB boundary */ | 72 | */ |
73 | |||
74 | { | ||
75 | r1.l = #LO(_end); | ||
76 | r2.l = #LO(stext); | ||
77 | r3 = #1; | ||
78 | } | ||
79 | { | ||
80 | r1.h = #HI(_end); | ||
81 | r2.h = #HI(stext); | ||
82 | r3 = asl(r3, #22); | ||
83 | } | ||
84 | { | ||
85 | r1 = sub(r1, r2); | ||
86 | r3 = add(r3, #-1); | ||
87 | } /* r1 = _end - stext */ | ||
88 | r1 = add(r1, r3); /* + (4M-1) */ | ||
89 | r26 = lsr(r1, #22); /* / 4M = # of entries */ | ||
90 | |||
91 | r1 = r25; | ||
92 | r2.h = #0xffc0; | ||
93 | r2.l = #0x0000; /* round back down to 4MB boundary */ | ||
94 | r1 = and(r1,r2); | ||
63 | r2 = lsr(r1, #22) /* 4MB page number */ | 95 | r2 = lsr(r1, #22) /* 4MB page number */ |
64 | r2 = asl(r2, #2) /* times sizeof(PTE) (4bytes) */ | 96 | r2 = asl(r2, #2) /* times sizeof(PTE) (4bytes) */ |
65 | r0 = add(r0,r2) /* r0 = address of correct PTE */ | 97 | r0 = add(r0,r2) /* r0 = address of correct PTE */ |
66 | r2 = #PTE_BITS | 98 | r2 = #PTE_BITS |
67 | r1 = add(r1,r2) /* r1 = 4MB PTE for the first entry */ | 99 | r1 = add(r1,r2) /* r1 = 4MB PTE for the first entry */ |
68 | r2.h = #0x0040 | 100 | r2.h = #0x0040 |
69 | r2.l = #0x0000 /* 4MB */ | 101 | r2.l = #0x0000 /* 4MB increments */ |
70 | memw(r0 ++ #4) = r1 | 102 | loop0(1f,r26); |
71 | r1 = add(r1, r2) | 103 | 1: |
72 | memw(r0 ++ #4) = r1 | 104 | memw(r0 ++ #4) = r1 |
105 | { r1 = add(r1, r2); } :endloop0 | ||
106 | |||
107 | /* Also need to overwrite the initial 0xc0000000 entries */ | ||
108 | /* PAGE_OFFSET >> (4MB shift - 4 bytes per entry shift) */ | ||
109 | R1.H = #HI(PAGE_OFFSET >> (22 - 2)) | ||
110 | R1.L = #LO(PAGE_OFFSET >> (22 - 2)) | ||
111 | |||
112 | r0 = add(r1, r24); /* advance to 0xc0000000 entry */ | ||
113 | r1 = r25; | ||
114 | r2.h = #0xffc0; | ||
115 | r2.l = #0x0000; /* round back down to 4MB boundary */ | ||
116 | r1 = and(r1,r2); /* for huge page */ | ||
117 | r2 = #PTE_BITS | ||
118 | r1 = add(r1,r2); | ||
119 | r2.h = #0x0040 | ||
120 | r2.l = #0x0000 /* 4MB increments */ | ||
73 | 121 | ||
74 | r0 = r24 | 122 | loop0(1f,SEGTABLE_ENTRIES); |
123 | 1: | ||
124 | memw(r0 ++ #4) = r1; | ||
125 | { r1 = add(r1,r2); } :endloop0 | ||
126 | |||
127 | r0 = r24; | ||
75 | 128 | ||
76 | /* | 129 | /* |
77 | * The subroutine wrapper around the virtual instruction touches | 130 | * The subroutine wrapper around the virtual instruction touches |
78 | * no memory, so we should be able to use it even here. | 131 | * no memory, so we should be able to use it even here. |
132 | * Note that in this version, R1 and R2 get "clobbered"; see | ||
133 | * vm_ops.S | ||
79 | */ | 134 | */ |
135 | r1 = #VM_TRANS_TYPE_TABLE | ||
80 | call __vmnewmap; | 136 | call __vmnewmap; |
81 | 137 | ||
82 | /* Jump into virtual address range. */ | 138 | /* Jump into virtual address range. */ |
@@ -90,17 +146,29 @@ ENTRY(stext) | |||
90 | __head_s_vaddr_target: | 146 | __head_s_vaddr_target: |
91 | /* | 147 | /* |
92 | * Tear down VA=PA translation now that we are running | 148 | * Tear down VA=PA translation now that we are running |
93 | * in the desgnated kernel segments. | 149 | * in kernel virtual space. |
94 | */ | 150 | */ |
95 | r0 = #__HVM_PDE_S_INVALID | 151 | r0 = #__HVM_PDE_S_INVALID |
96 | r1 = r24 | 152 | |
97 | loop0(1f,#0x100) | 153 | r1.h = #0xffc0; |
154 | r1.l = #0x0000; | ||
155 | r2 = r25; /* phys_offset */ | ||
156 | r2 = and(r1,r2); | ||
157 | |||
158 | r1.l = #lo(swapper_pg_dir) | ||
159 | r1.h = #hi(swapper_pg_dir) | ||
160 | r2 = lsr(r2, #22) /* 4MB page number */ | ||
161 | r2 = asl(r2, #2) /* times sizeof(PTE) (4bytes) */ | ||
162 | r1 = add(r1,r2); | ||
163 | loop0(1f,r26) | ||
164 | |||
98 | 1: | 165 | 1: |
99 | { | 166 | { |
100 | memw(R1 ++ #4) = R0 | 167 | memw(R1 ++ #4) = R0 |
101 | }:endloop0 | 168 | }:endloop0 |
102 | 169 | ||
103 | r0 = r24 | 170 | r0 = r24 |
171 | r1 = #VM_TRANS_TYPE_TABLE | ||
104 | call __vmnewmap | 172 | call __vmnewmap |
105 | 173 | ||
106 | /* Go ahead and install the trap0 return so angel calls work */ | 174 | /* Go ahead and install the trap0 return so angel calls work */ |
@@ -143,6 +211,13 @@ __head_s_vaddr_target: | |||
143 | r2 = sub(r2,r0); | 211 | r2 = sub(r2,r0); |
144 | call memset; | 212 | call memset; |
145 | 213 | ||
214 | /* Set PHYS_OFFSET; should be in R25 */ | ||
215 | #ifdef CONFIG_HEXAGON_PHYS_OFFSET | ||
216 | r0.l = #LO(__phys_offset); | ||
217 | r0.h = #HI(__phys_offset); | ||
218 | memw(r0) = r25; | ||
219 | #endif | ||
220 | |||
146 | /* Time to make the doughnuts. */ | 221 | /* Time to make the doughnuts. */ |
147 | call start_kernel | 222 | call start_kernel |
148 | 223 | ||
diff --git a/arch/hexagon/kernel/kgdb.c b/arch/hexagon/kernel/kgdb.c index 344645370646..82d5c2593323 100644 --- a/arch/hexagon/kernel/kgdb.c +++ b/arch/hexagon/kernel/kgdb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/hexagon/kernel/kgdb.c - Hexagon KGDB Support | 2 | * arch/hexagon/kernel/kgdb.c - Hexagon KGDB Support |
3 | * | 3 | * |
4 | * Copyright (c) 2011, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 and | 7 | * 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] = { | |||
70 | { "lc1", GDB_SIZEOF_REG, offsetof(struct pt_regs, lc1)}, | 70 | { "lc1", GDB_SIZEOF_REG, offsetof(struct pt_regs, lc1)}, |
71 | { " gp", GDB_SIZEOF_REG, offsetof(struct pt_regs, gp)}, | 71 | { " gp", GDB_SIZEOF_REG, offsetof(struct pt_regs, gp)}, |
72 | { "ugp", GDB_SIZEOF_REG, offsetof(struct pt_regs, ugp)}, | 72 | { "ugp", GDB_SIZEOF_REG, offsetof(struct pt_regs, ugp)}, |
73 | { "cs0", GDB_SIZEOF_REG, offsetof(struct pt_regs, cs0)}, | ||
74 | { "cs1", GDB_SIZEOF_REG, offsetof(struct pt_regs, cs1)}, | ||
73 | { "psp", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmpsp)}, | 75 | { "psp", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmpsp)}, |
74 | { "elr", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmel)}, | 76 | { "elr", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmel)}, |
75 | { "est", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmest)}, | 77 | { "est", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmest)}, |
diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c index 9b948c619a03..0a0dd5c05b46 100644 --- a/arch/hexagon/kernel/process.c +++ b/arch/hexagon/kernel/process.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/tick.h> | 24 | #include <linux/tick.h> |
25 | #include <linux/uaccess.h> | 25 | #include <linux/uaccess.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/tracehook.h> | ||
27 | 28 | ||
28 | /* | 29 | /* |
29 | * Program thread launch. Often defined as a macro in processor.h, | 30 | * 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, | |||
95 | if (unlikely(p->flags & PF_KTHREAD)) { | 96 | if (unlikely(p->flags & PF_KTHREAD)) { |
96 | memset(childregs, 0, sizeof(struct pt_regs)); | 97 | memset(childregs, 0, sizeof(struct pt_regs)); |
97 | /* r24 <- fn, r25 <- arg */ | 98 | /* r24 <- fn, r25 <- arg */ |
98 | ss->r2524 = usp | ((u64)arg << 32); | 99 | ss->r24 = usp; |
100 | ss->r25 = arg; | ||
99 | pt_set_kmode(childregs); | 101 | pt_set_kmode(childregs); |
100 | return 0; | 102 | return 0; |
101 | } | 103 | } |
@@ -185,3 +187,41 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) | |||
185 | { | 187 | { |
186 | return 0; | 188 | return 0; |
187 | } | 189 | } |
190 | |||
191 | |||
192 | /* | ||
193 | * Called on the exit path of event entry; see vm_entry.S | ||
194 | * | ||
195 | * Interrupts will already be disabled. | ||
196 | * | ||
197 | * Returns 0 if there's no need to re-check for more work. | ||
198 | */ | ||
199 | |||
200 | int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) | ||
201 | { | ||
202 | if (!(thread_info_flags & _TIF_WORK_MASK)) { | ||
203 | return 0; | ||
204 | } /* shortcut -- no work to be done */ | ||
205 | |||
206 | local_irq_enable(); | ||
207 | |||
208 | if (thread_info_flags & _TIF_NEED_RESCHED) { | ||
209 | schedule(); | ||
210 | return 1; | ||
211 | } | ||
212 | |||
213 | if (thread_info_flags & _TIF_SIGPENDING) { | ||
214 | do_signal(regs); | ||
215 | return 1; | ||
216 | } | ||
217 | |||
218 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | ||
219 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
220 | tracehook_notify_resume(regs); | ||
221 | return 1; | ||
222 | } | ||
223 | |||
224 | /* Should not even reach here */ | ||
225 | panic("%s: bad thread_info flags 0x%08x\n", __func__, | ||
226 | thread_info_flags); | ||
227 | } | ||
diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c index 670b1b0bee63..de829eb7f185 100644 --- a/arch/hexagon/kernel/ptrace.c +++ b/arch/hexagon/kernel/ptrace.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Ptrace support for Hexagon | 2 | * Ptrace support for Hexagon |
3 | * | 3 | * |
4 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 and | 7 | * it under the terms of the GNU General Public License version 2 and |
@@ -32,6 +32,21 @@ | |||
32 | 32 | ||
33 | #include <asm/user.h> | 33 | #include <asm/user.h> |
34 | 34 | ||
35 | #if arch_has_single_step() | ||
36 | /* Both called from ptrace_resume */ | ||
37 | void user_enable_single_step(struct task_struct *child) | ||
38 | { | ||
39 | pt_set_singlestep(task_pt_regs(child)); | ||
40 | set_tsk_thread_flag(child, TIF_SINGLESTEP); | ||
41 | } | ||
42 | |||
43 | void user_disable_single_step(struct task_struct *child) | ||
44 | { | ||
45 | pt_clr_singlestep(task_pt_regs(child)); | ||
46 | clear_tsk_thread_flag(child, TIF_SINGLESTEP); | ||
47 | } | ||
48 | #endif | ||
49 | |||
35 | static int genregs_get(struct task_struct *target, | 50 | static int genregs_get(struct task_struct *target, |
36 | const struct user_regset *regset, | 51 | const struct user_regset *regset, |
37 | unsigned int pos, unsigned int count, | 52 | unsigned int pos, unsigned int count, |
@@ -76,6 +91,10 @@ static int genregs_get(struct task_struct *target, | |||
76 | dummy = pt_cause(regs); | 91 | dummy = pt_cause(regs); |
77 | ONEXT(&dummy, cause); | 92 | ONEXT(&dummy, cause); |
78 | ONEXT(&pt_badva(regs), badva); | 93 | ONEXT(&pt_badva(regs), badva); |
94 | #if CONFIG_HEXAGON_ARCH_VERSION >=4 | ||
95 | ONEXT(®s->cs0, cs0); | ||
96 | ONEXT(®s->cs1, cs1); | ||
97 | #endif | ||
79 | 98 | ||
80 | /* Pad the rest with zeros, if needed */ | 99 | /* Pad the rest with zeros, if needed */ |
81 | if (!ret) | 100 | if (!ret) |
@@ -123,6 +142,11 @@ static int genregs_set(struct task_struct *target, | |||
123 | INEXT(&bucket, cause); | 142 | INEXT(&bucket, cause); |
124 | INEXT(&bucket, badva); | 143 | INEXT(&bucket, badva); |
125 | 144 | ||
145 | #if CONFIG_HEXAGON_ARCH_VERSION >=4 | ||
146 | INEXT(®s->cs0, cs0); | ||
147 | INEXT(®s->cs1, cs1); | ||
148 | #endif | ||
149 | |||
126 | /* Ignore the rest, if needed */ | 150 | /* Ignore the rest, if needed */ |
127 | if (!ret) | 151 | if (!ret) |
128 | ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, | 152 | ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, |
diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c index 94a387835008..bfe13311d70d 100644 --- a/arch/hexagon/kernel/setup.c +++ b/arch/hexagon/kernel/setup.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Arch related setup for Hexagon | 2 | * Arch related setup for Hexagon |
3 | * | 3 | * |
4 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 and | 7 | * it under the terms of the GNU General Public License version 2 and |
@@ -68,6 +68,8 @@ void __init setup_arch(char **cmdline_p) | |||
68 | */ | 68 | */ |
69 | __vmsetvec(_K_VM_event_vector); | 69 | __vmsetvec(_K_VM_event_vector); |
70 | 70 | ||
71 | printk(KERN_INFO "PHYS_OFFSET=0x%08x\n", PHYS_OFFSET); | ||
72 | |||
71 | /* | 73 | /* |
72 | * Simulator has a few differences from the hardware. | 74 | * Simulator has a few differences from the hardware. |
73 | * For now, check uninitialized-but-mapped memory | 75 | * For now, check uninitialized-but-mapped memory |
@@ -128,6 +130,11 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
128 | { | 130 | { |
129 | int cpu = (unsigned long) v - 1; | 131 | int cpu = (unsigned long) v - 1; |
130 | 132 | ||
133 | #ifdef CONFIG_SMP | ||
134 | if (!cpu_online(cpu)) | ||
135 | return 0; | ||
136 | #endif | ||
137 | |||
131 | seq_printf(m, "processor\t: %d\n", cpu); | 138 | seq_printf(m, "processor\t: %d\n", cpu); |
132 | seq_printf(m, "model name\t: Hexagon Virtual Machine\n"); | 139 | seq_printf(m, "model name\t: Hexagon Virtual Machine\n"); |
133 | seq_printf(m, "BogoMips\t: %lu.%02lu\n", | 140 | seq_printf(m, "BogoMips\t: %lu.%02lu\n", |
diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c index 60fa2ca3202b..d7c73874b515 100644 --- a/arch/hexagon/kernel/signal.c +++ b/arch/hexagon/kernel/signal.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Signal support for Hexagon processor | 2 | * Signal support for Hexagon processor |
3 | * | 3 | * |
4 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 and | 7 | * 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, | |||
41 | { | 41 | { |
42 | unsigned long sp = regs->r29; | 42 | unsigned long sp = regs->r29; |
43 | 43 | ||
44 | /* check if we would overflow the alt stack */ | ||
45 | if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) | ||
46 | return (void __user __force *)-1UL; | ||
47 | |||
44 | /* Switch to signal stack if appropriate */ | 48 | /* Switch to signal stack if appropriate */ |
45 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) | 49 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) |
46 | sp = current->sas_ss_sp + current->sas_ss_size; | 50 | 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) | |||
66 | err |= __put_user(regs->preds, &sc->sc_regs.p3_0); | 70 | err |= __put_user(regs->preds, &sc->sc_regs.p3_0); |
67 | err |= __put_user(regs->gp, &sc->sc_regs.gp); | 71 | err |= __put_user(regs->gp, &sc->sc_regs.gp); |
68 | err |= __put_user(regs->ugp, &sc->sc_regs.ugp); | 72 | err |= __put_user(regs->ugp, &sc->sc_regs.ugp); |
69 | 73 | #if CONFIG_HEXAGON_ARCH_VERSION >= 4 | |
74 | err |= __put_user(regs->cs0, &sc->sc_regs.cs0); | ||
75 | err |= __put_user(regs->cs1, &sc->sc_regs.cs1); | ||
76 | #endif | ||
70 | tmp = pt_elr(regs); err |= __put_user(tmp, &sc->sc_regs.pc); | 77 | tmp = pt_elr(regs); err |= __put_user(tmp, &sc->sc_regs.pc); |
71 | tmp = pt_cause(regs); err |= __put_user(tmp, &sc->sc_regs.cause); | 78 | tmp = pt_cause(regs); err |= __put_user(tmp, &sc->sc_regs.cause); |
72 | tmp = pt_badva(regs); err |= __put_user(tmp, &sc->sc_regs.badva); | 79 | tmp = pt_badva(regs); err |= __put_user(tmp, &sc->sc_regs.badva); |
@@ -93,7 +100,10 @@ static int restore_sigcontext(struct pt_regs *regs, | |||
93 | err |= __get_user(regs->preds, &sc->sc_regs.p3_0); | 100 | err |= __get_user(regs->preds, &sc->sc_regs.p3_0); |
94 | err |= __get_user(regs->gp, &sc->sc_regs.gp); | 101 | err |= __get_user(regs->gp, &sc->sc_regs.gp); |
95 | err |= __get_user(regs->ugp, &sc->sc_regs.ugp); | 102 | err |= __get_user(regs->ugp, &sc->sc_regs.ugp); |
96 | 103 | #if CONFIG_HEXAGON_ARCH_VERSION >= 4 | |
104 | err |= __get_user(regs->cs0, &sc->sc_regs.cs0); | ||
105 | err |= __get_user(regs->cs1, &sc->sc_regs.cs1); | ||
106 | #endif | ||
97 | err |= __get_user(tmp, &sc->sc_regs.pc); pt_set_elr(regs, tmp); | 107 | err |= __get_user(tmp, &sc->sc_regs.pc); pt_set_elr(regs, tmp); |
98 | 108 | ||
99 | return err; | 109 | return err; |
@@ -193,7 +203,7 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, | |||
193 | /* | 203 | /* |
194 | * Called from return-from-event code. | 204 | * Called from return-from-event code. |
195 | */ | 205 | */ |
196 | static void do_signal(struct pt_regs *regs) | 206 | void do_signal(struct pt_regs *regs) |
197 | { | 207 | { |
198 | struct k_sigaction sigact; | 208 | struct k_sigaction sigact; |
199 | siginfo_t info; | 209 | siginfo_t info; |
@@ -210,8 +220,9 @@ static void do_signal(struct pt_regs *regs) | |||
210 | } | 220 | } |
211 | 221 | ||
212 | /* | 222 | /* |
213 | * If we came from a system call, handle the restart. | 223 | * No (more) signals; if we came from a system call, handle the restart. |
214 | */ | 224 | */ |
225 | |||
215 | if (regs->syscall_nr >= 0) { | 226 | if (regs->syscall_nr >= 0) { |
216 | switch (regs->r00) { | 227 | switch (regs->r00) { |
217 | case -ERESTARTNOHAND: | 228 | case -ERESTARTNOHAND: |
@@ -234,17 +245,6 @@ no_restart: | |||
234 | restore_saved_sigmask(); | 245 | restore_saved_sigmask(); |
235 | } | 246 | } |
236 | 247 | ||
237 | void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) | ||
238 | { | ||
239 | if (thread_info_flags & _TIF_SIGPENDING) | ||
240 | do_signal(regs); | ||
241 | |||
242 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | ||
243 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
244 | tracehook_notify_resume(regs); | ||
245 | } | ||
246 | } | ||
247 | |||
248 | /* | 248 | /* |
249 | * Architecture-specific wrappers for signal-related system calls | 249 | * Architecture-specific wrappers for signal-related system calls |
250 | */ | 250 | */ |
@@ -272,21 +272,12 @@ asmlinkage int sys_rt_sigreturn(void) | |||
272 | /* Restore the user's stack as well */ | 272 | /* Restore the user's stack as well */ |
273 | pt_psp(regs) = regs->r29; | 273 | pt_psp(regs) = regs->r29; |
274 | 274 | ||
275 | /* | 275 | regs->syscall_nr = -1; |
276 | * Leave a trace in the stack frame that this was a sigreturn. | ||
277 | * If the system call is to replay, we've already restored the | ||
278 | * number in the GPR slot and it will be regenerated on the | ||
279 | * new system call trap entry. Note that if restore_sigcontext() | ||
280 | * did something other than a bulk copy of the pt_regs struct, | ||
281 | * we could avoid this assignment by simply not overwriting | ||
282 | * regs->syscall_nr. | ||
283 | */ | ||
284 | regs->syscall_nr = __NR_rt_sigreturn; | ||
285 | 276 | ||
286 | if (restore_altstack(&frame->uc.uc_stack)) | 277 | if (restore_altstack(&frame->uc.uc_stack)) |
287 | goto badframe; | 278 | goto badframe; |
288 | 279 | ||
289 | return 0; | 280 | return regs->r00; |
290 | 281 | ||
291 | badframe: | 282 | badframe: |
292 | force_sig(SIGSEGV, current); | 283 | force_sig(SIGSEGV, current); |
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 @@ | |||
1 | /* | ||
2 | * CPU topology for Hexagon | ||
3 | * | ||
4 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 and | ||
8 | * only version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | * 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/cpu.h> | ||
22 | #include <linux/cpumask.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/node.h> | ||
25 | #include <linux/nodemask.h> | ||
26 | #include <linux/percpu.h> | ||
27 | |||
28 | /* Swiped from MIPS. */ | ||
29 | |||
30 | static DEFINE_PER_CPU(struct cpu, cpu_devices); | ||
31 | |||
32 | static int __init topology_init(void) | ||
33 | { | ||
34 | int i, ret; | ||
35 | |||
36 | for_each_present_cpu(i) { | ||
37 | |||
38 | /* | ||
39 | * register_cpu takes a per_cpu pointer and | ||
40 | * just points it at another per_cpu struct... | ||
41 | */ | ||
42 | |||
43 | ret = register_cpu(&per_cpu(cpu_devices, i), i); | ||
44 | if (ret) | ||
45 | printk(KERN_WARNING "topology_init: register_cpu %d " | ||
46 | "failed (%d)\n", i, ret); | ||
47 | } | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | subsys_initcall(topology_init); | ||
diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c index cc2171b2aa04..7858663352b9 100644 --- a/arch/hexagon/kernel/traps.c +++ b/arch/hexagon/kernel/traps.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Kernel traps/events for Hexagon processor | 2 | * Kernel traps/events for Hexagon processor |
3 | * | 3 | * |
4 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 and | 7 | * it under the terms of the GNU General Public License version 2 and |
@@ -65,6 +65,10 @@ static const char *ex_name(int ex) | |||
65 | return "Write protection fault"; | 65 | return "Write protection fault"; |
66 | case HVM_GE_C_XMAL: | 66 | case HVM_GE_C_XMAL: |
67 | return "Misaligned instruction"; | 67 | return "Misaligned instruction"; |
68 | case HVM_GE_C_WREG: | ||
69 | return "Multiple writes to same register in packet"; | ||
70 | case HVM_GE_C_PCAL: | ||
71 | return "Program counter values that are not properly aligned"; | ||
68 | case HVM_GE_C_RMAL: | 72 | case HVM_GE_C_RMAL: |
69 | return "Misaligned data load"; | 73 | return "Misaligned data load"; |
70 | case HVM_GE_C_WMAL: | 74 | case HVM_GE_C_WMAL: |
@@ -316,6 +320,12 @@ void do_genex(struct pt_regs *regs) | |||
316 | case HVM_GE_C_XMAL: | 320 | case HVM_GE_C_XMAL: |
317 | misaligned_instruction(regs); | 321 | misaligned_instruction(regs); |
318 | break; | 322 | break; |
323 | case HVM_GE_C_WREG: | ||
324 | illegal_instruction(regs); | ||
325 | break; | ||
326 | case HVM_GE_C_PCAL: | ||
327 | misaligned_instruction(regs); | ||
328 | break; | ||
319 | case HVM_GE_C_RMAL: | 329 | case HVM_GE_C_RMAL: |
320 | misaligned_data_load(regs); | 330 | misaligned_data_load(regs); |
321 | break; | 331 | break; |
@@ -348,7 +358,6 @@ long sys_syscall(void) | |||
348 | 358 | ||
349 | void do_trap0(struct pt_regs *regs) | 359 | void do_trap0(struct pt_regs *regs) |
350 | { | 360 | { |
351 | unsigned long syscallret = 0; | ||
352 | syscall_fn syscall; | 361 | syscall_fn syscall; |
353 | 362 | ||
354 | switch (pt_cause(regs)) { | 363 | switch (pt_cause(regs)) { |
@@ -388,21 +397,11 @@ void do_trap0(struct pt_regs *regs) | |||
388 | } else { | 397 | } else { |
389 | syscall = (syscall_fn) | 398 | syscall = (syscall_fn) |
390 | (sys_call_table[regs->syscall_nr]); | 399 | (sys_call_table[regs->syscall_nr]); |
391 | syscallret = syscall(regs->r00, regs->r01, | 400 | regs->r00 = syscall(regs->r00, regs->r01, |
392 | regs->r02, regs->r03, | 401 | regs->r02, regs->r03, |
393 | regs->r04, regs->r05); | 402 | regs->r04, regs->r05); |
394 | } | 403 | } |
395 | 404 | ||
396 | /* | ||
397 | * If it was a sigreturn system call, don't overwrite | ||
398 | * r0 value in stack frame with return value. | ||
399 | * | ||
400 | * __NR_sigreturn doesn't seem to exist in new unistd.h | ||
401 | */ | ||
402 | |||
403 | if (regs->syscall_nr != __NR_rt_sigreturn) | ||
404 | regs->r00 = syscallret; | ||
405 | |||
406 | /* allow strace to get the syscall return state */ | 405 | /* allow strace to get the syscall return state */ |
407 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE))) | 406 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE))) |
408 | tracehook_report_syscall_exit(regs, 0); | 407 | tracehook_report_syscall_exit(regs, 0); |
@@ -444,3 +443,14 @@ void do_machcheck(struct pt_regs *regs) | |||
444 | /* Halt and catch fire */ | 443 | /* Halt and catch fire */ |
445 | __vmstop(); | 444 | __vmstop(); |
446 | } | 445 | } |
446 | |||
447 | /* | ||
448 | * Treat this like the old 0xdb trap. | ||
449 | */ | ||
450 | |||
451 | void do_debug_exception(struct pt_regs *regs) | ||
452 | { | ||
453 | regs->hvmer.vmest &= ~HVM_VMEST_CAUSE_MSK; | ||
454 | regs->hvmer.vmest |= (TRAP_DEBUG << HVM_VMEST_CAUSE_SFT); | ||
455 | do_trap0(regs); | ||
456 | } | ||
diff --git a/arch/hexagon/kernel/vm_entry.S b/arch/hexagon/kernel/vm_entry.S index 425e50c694f7..e3086185fc9f 100644 --- a/arch/hexagon/kernel/vm_entry.S +++ b/arch/hexagon/kernel/vm_entry.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Event entry/exit for Hexagon | 2 | * Event entry/exit for Hexagon |
3 | * | 3 | * |
4 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 and | 7 | * it under the terms of the GNU General Public License version 2 and |
@@ -45,48 +45,88 @@ | |||
45 | * number in the case where we decode a system call (trap0(#1)). | 45 | * number in the case where we decode a system call (trap0(#1)). |
46 | */ | 46 | */ |
47 | 47 | ||
48 | #if CONFIG_HEXAGON_ARCH_VERSION < 4 | ||
48 | #define save_pt_regs()\ | 49 | #define save_pt_regs()\ |
49 | memd(R0 + #_PT_R3130) = R31:30; \ | 50 | memd(R0 + #_PT_R3130) = R31:30; \ |
51 | { memw(R0 + #_PT_R2928) = R28; \ | ||
52 | R31 = memw(R0 + #_PT_ER_VMPSP); }\ | ||
53 | { memw(R0 + #(_PT_R2928 + 4)) = R31; \ | ||
54 | R31 = ugp; } \ | ||
55 | { memd(R0 + #_PT_R2726) = R27:26; \ | ||
56 | R30 = gp ; } \ | ||
57 | memd(R0 + #_PT_R2524) = R25:24; \ | ||
58 | memd(R0 + #_PT_R2322) = R23:22; \ | ||
59 | memd(R0 + #_PT_R2120) = R21:20; \ | ||
60 | memd(R0 + #_PT_R1918) = R19:18; \ | ||
61 | memd(R0 + #_PT_R1716) = R17:16; \ | ||
62 | memd(R0 + #_PT_R1514) = R15:14; \ | ||
63 | memd(R0 + #_PT_R1312) = R13:12; \ | ||
64 | { memd(R0 + #_PT_R1110) = R11:10; \ | ||
65 | R15 = lc0; } \ | ||
66 | { memd(R0 + #_PT_R0908) = R9:8; \ | ||
67 | R14 = sa0; } \ | ||
68 | { memd(R0 + #_PT_R0706) = R7:6; \ | ||
69 | R13 = lc1; } \ | ||
70 | { memd(R0 + #_PT_R0504) = R5:4; \ | ||
71 | R12 = sa1; } \ | ||
72 | { memd(R0 + #_PT_GPUGP) = R31:30; \ | ||
73 | R11 = m1; \ | ||
74 | R2.H = #HI(_THREAD_SIZE); } \ | ||
75 | { memd(R0 + #_PT_LC0SA0) = R15:14; \ | ||
76 | R10 = m0; \ | ||
77 | R2.L = #LO(_THREAD_SIZE); } \ | ||
78 | { memd(R0 + #_PT_LC1SA1) = R13:12; \ | ||
79 | R15 = p3:0; \ | ||
80 | R2 = neg(R2); } \ | ||
81 | { memd(R0 + #_PT_M1M0) = R11:10; \ | ||
82 | R14 = usr; \ | ||
83 | R2 = and(R0,R2); } \ | ||
84 | { memd(R0 + #_PT_PREDSUSR) = R15:14; \ | ||
85 | THREADINFO_REG = R2; } \ | ||
86 | { r24 = memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS); \ | ||
87 | memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R0; \ | ||
88 | R2 = #-1; } \ | ||
89 | { memw(R0 + #_PT_SYSCALL_NR) = R2; \ | ||
90 | R30 = #0; } | ||
91 | #else | ||
92 | /* V4+ */ | ||
93 | /* the # ## # syntax inserts a literal ## */ | ||
94 | #define save_pt_regs()\ | ||
95 | { memd(R0 + #_PT_R3130) = R31:30; \ | ||
96 | R30 = memw(R0 + #_PT_ER_VMPSP); }\ | ||
50 | { memw(R0 + #_PT_R2928) = R28; \ | 97 | { memw(R0 + #_PT_R2928) = R28; \ |
51 | R31 = memw(R0 + #_PT_ER_VMPSP); }\ | 98 | memw(R0 + #(_PT_R2928 + 4)) = R30; }\ |
52 | { memw(R0 + #(_PT_R2928 + 4)) = R31; \ | 99 | { R31:30 = C11:10; \ |
53 | R31 = ugp; } \ | 100 | memd(R0 + #_PT_R2726) = R27:26; \ |
54 | { memd(R0 + #_PT_R2726) = R27:26; \ | 101 | memd(R0 + #_PT_R2524) = R25:24; }\ |
55 | R30 = gp ; } \ | 102 | { memd(R0 + #_PT_R2322) = R23:22; \ |
56 | memd(R0 + #_PT_R2524) = R25:24; \ | 103 | memd(R0 + #_PT_R2120) = R21:20; }\ |
57 | memd(R0 + #_PT_R2322) = R23:22; \ | 104 | { memd(R0 + #_PT_R1918) = R19:18; \ |
58 | memd(R0 + #_PT_R2120) = R21:20; \ | 105 | memd(R0 + #_PT_R1716) = R17:16; }\ |
59 | memd(R0 + #_PT_R1918) = R19:18; \ | 106 | { memd(R0 + #_PT_R1514) = R15:14; \ |
60 | memd(R0 + #_PT_R1716) = R17:16; \ | 107 | memd(R0 + #_PT_R1312) = R13:12; \ |
61 | memd(R0 + #_PT_R1514) = R15:14; \ | 108 | R17:16 = C13:12; }\ |
62 | memd(R0 + #_PT_R1312) = R13:12; \ | ||
63 | { memd(R0 + #_PT_R1110) = R11:10; \ | 109 | { memd(R0 + #_PT_R1110) = R11:10; \ |
64 | R15 = lc0; } \ | 110 | memd(R0 + #_PT_R0908) = R9:8; \ |
65 | { memd(R0 + #_PT_R0908) = R9:8; \ | 111 | R15:14 = C1:0; } \ |
66 | R14 = sa0; } \ | ||
67 | { memd(R0 + #_PT_R0706) = R7:6; \ | 112 | { memd(R0 + #_PT_R0706) = R7:6; \ |
68 | R13 = lc1; } \ | 113 | memd(R0 + #_PT_R0504) = R5:4; \ |
69 | { memd(R0 + #_PT_R0504) = R5:4; \ | 114 | R13:12 = C3:2; } \ |
70 | R12 = sa1; } \ | 115 | { memd(R0 + #_PT_GPUGP) = R31:30; \ |
71 | { memd(R0 + #_PT_UGPGP) = R31:30; \ | 116 | memd(R0 + #_PT_LC0SA0) = R15:14; \ |
72 | R11 = m1; \ | 117 | R11:10 = C7:6; }\ |
73 | R2.H = #HI(_THREAD_SIZE); } \ | 118 | { THREADINFO_REG = and(R0, # ## #-_THREAD_SIZE); \ |
74 | { memd(R0 + #_PT_LC0SA0) = R15:14; \ | 119 | memd(R0 + #_PT_LC1SA1) = R13:12; \ |
75 | R10 = m0; \ | 120 | R15 = p3:0; }\ |
76 | R2.L = #LO(_THREAD_SIZE); } \ | ||
77 | { memd(R0 + #_PT_LC1SA1) = R13:12; \ | ||
78 | R15 = p3:0; \ | ||
79 | R2 = neg(R2); } \ | ||
80 | { memd(R0 + #_PT_M1M0) = R11:10; \ | 121 | { memd(R0 + #_PT_M1M0) = R11:10; \ |
81 | R14 = usr; \ | 122 | memw(R0 + #_PT_PREDSUSR + 4) = R15; }\ |
82 | R2 = and(R0,R2); } \ | ||
83 | { memd(R0 + #_PT_PREDSUSR) = R15:14; \ | ||
84 | THREADINFO_REG = R2; } \ | ||
85 | { r24 = memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS); \ | 123 | { r24 = memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS); \ |
86 | memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R0; \ | 124 | memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R0; \ |
87 | R2 = #-1; } \ | 125 | R2 = #-1; } \ |
88 | { memw(R0 + #_PT_SYSCALL_NR) = R2; \ | 126 | { memw(R0 + #_PT_SYSCALL_NR) = R2; \ |
127 | memd(R0 + #_PT_CS1CS0) = R17:16; \ | ||
89 | R30 = #0; } | 128 | R30 = #0; } |
129 | #endif | ||
90 | 130 | ||
91 | /* | 131 | /* |
92 | * Restore registers and thread_info.regs state. THREADINFO_REG | 132 | * Restore registers and thread_info.regs state. THREADINFO_REG |
@@ -94,6 +134,7 @@ | |||
94 | * preserved. Don't restore R29 (SP) until later. | 134 | * preserved. Don't restore R29 (SP) until later. |
95 | */ | 135 | */ |
96 | 136 | ||
137 | #if CONFIG_HEXAGON_ARCH_VERSION < 4 | ||
97 | #define restore_pt_regs() \ | 138 | #define restore_pt_regs() \ |
98 | { memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R24; \ | 139 | { memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R24; \ |
99 | R15:14 = memd(R0 + #_PT_PREDSUSR); } \ | 140 | R15:14 = memd(R0 + #_PT_PREDSUSR); } \ |
@@ -121,11 +162,44 @@ | |||
121 | R23:22 = memd(R0 + #_PT_R2322); } \ | 162 | R23:22 = memd(R0 + #_PT_R2322); } \ |
122 | { R25:24 = memd(R0 + #_PT_R2524); \ | 163 | { R25:24 = memd(R0 + #_PT_R2524); \ |
123 | R27:26 = memd(R0 + #_PT_R2726); } \ | 164 | R27:26 = memd(R0 + #_PT_R2726); } \ |
124 | R31:30 = memd(R0 + #_PT_UGPGP); \ | 165 | R31:30 = memd(R0 + #_PT_GPUGP); \ |
125 | { R28 = memw(R0 + #_PT_R2928); \ | 166 | { R28 = memw(R0 + #_PT_R2928); \ |
126 | ugp = R31; } \ | 167 | ugp = R31; } \ |
127 | { R31:30 = memd(R0 + #_PT_R3130); \ | 168 | { R31:30 = memd(R0 + #_PT_R3130); \ |
128 | gp = R30; } | 169 | gp = R30; } |
170 | #else | ||
171 | /* V4+ */ | ||
172 | #define restore_pt_regs() \ | ||
173 | { memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R24; \ | ||
174 | R15:14 = memd(R0 + #_PT_PREDSUSR); } \ | ||
175 | { R11:10 = memd(R0 + #_PT_M1M0); \ | ||
176 | R13:12 = memd(R0 + #_PT_LC1SA1); \ | ||
177 | p3:0 = R15; } \ | ||
178 | { R15:14 = memd(R0 + #_PT_LC0SA0); \ | ||
179 | R3:2 = memd(R0 + #_PT_R0302); \ | ||
180 | usr = R14; } \ | ||
181 | { R5:4 = memd(R0 + #_PT_R0504); \ | ||
182 | R7:6 = memd(R0 + #_PT_R0706); \ | ||
183 | C7:6 = R11:10; }\ | ||
184 | { R9:8 = memd(R0 + #_PT_R0908); \ | ||
185 | R11:10 = memd(R0 + #_PT_R1110); \ | ||
186 | C3:2 = R13:12; }\ | ||
187 | { R13:12 = memd(R0 + #_PT_R1312); \ | ||
188 | R15:14 = memd(R0 + #_PT_R1514); \ | ||
189 | C1:0 = R15:14; }\ | ||
190 | { R17:16 = memd(R0 + #_PT_R1716); \ | ||
191 | R19:18 = memd(R0 + #_PT_R1918); } \ | ||
192 | { R21:20 = memd(R0 + #_PT_R2120); \ | ||
193 | R23:22 = memd(R0 + #_PT_R2322); } \ | ||
194 | { R25:24 = memd(R0 + #_PT_R2524); \ | ||
195 | R27:26 = memd(R0 + #_PT_R2726); } \ | ||
196 | R31:30 = memd(R0 + #_PT_CS1CS0); \ | ||
197 | { C13:12 = R31:30; \ | ||
198 | R31:30 = memd(R0 + #_PT_GPUGP) ; \ | ||
199 | R28 = memw(R0 + #_PT_R2928); }\ | ||
200 | { C11:10 = R31:30; \ | ||
201 | R31:30 = memd(R0 + #_PT_R3130); } | ||
202 | #endif | ||
129 | 203 | ||
130 | /* | 204 | /* |
131 | * Clears off enough space for the rest of pt_regs; evrec is a part | 205 | * Clears off enough space for the rest of pt_regs; evrec is a part |
@@ -139,6 +213,7 @@ | |||
139 | * Need to save off R0, R1, R2, R3 immediately. | 213 | * Need to save off R0, R1, R2, R3 immediately. |
140 | */ | 214 | */ |
141 | 215 | ||
216 | #if CONFIG_HEXAGON_ARCH_VERSION < 4 | ||
142 | #define vm_event_entry(CHandler) \ | 217 | #define vm_event_entry(CHandler) \ |
143 | { \ | 218 | { \ |
144 | R29 = add(R29, #-(_PT_REGS_SIZE)); \ | 219 | R29 = add(R29, #-(_PT_REGS_SIZE)); \ |
@@ -158,6 +233,34 @@ | |||
158 | R1.H = #HI(CHandler); \ | 233 | R1.H = #HI(CHandler); \ |
159 | jump event_dispatch; \ | 234 | jump event_dispatch; \ |
160 | } | 235 | } |
236 | #else | ||
237 | /* V4+ */ | ||
238 | /* turn on I$ prefetch early */ | ||
239 | /* the # ## # syntax inserts a literal ## */ | ||
240 | #define vm_event_entry(CHandler) \ | ||
241 | { \ | ||
242 | R29 = add(R29, #-(_PT_REGS_SIZE)); \ | ||
243 | memd(R29 + #(_PT_R0100 + -_PT_REGS_SIZE)) = R1:0; \ | ||
244 | memd(R29 + #(_PT_R0302 + -_PT_REGS_SIZE)) = R3:2; \ | ||
245 | R0 = usr; \ | ||
246 | } \ | ||
247 | { \ | ||
248 | memw(R29 + #_PT_PREDSUSR) = R0; \ | ||
249 | R0 = setbit(R0, #16); \ | ||
250 | } \ | ||
251 | usr = R0; \ | ||
252 | R1:0 = G1:0; \ | ||
253 | { \ | ||
254 | memd(R29 + #_PT_ER_VMEL) = R1:0; \ | ||
255 | R1 = # ## #(CHandler); \ | ||
256 | R3:2 = G3:2; \ | ||
257 | } \ | ||
258 | { \ | ||
259 | R0 = R29; \ | ||
260 | memd(R29 + #_PT_ER_VMPSP) = R3:2; \ | ||
261 | jump event_dispatch; \ | ||
262 | } | ||
263 | #endif | ||
161 | 264 | ||
162 | .text | 265 | .text |
163 | /* | 266 | /* |
@@ -171,6 +274,9 @@ event_dispatch: | |||
171 | callr r1 | 274 | callr r1 |
172 | 275 | ||
173 | /* | 276 | /* |
277 | * Coming back from the C-world, our thread info pointer | ||
278 | * should be in the designated register (usually R19) | ||
279 | * | ||
174 | * If we were in kernel mode, we don't need to check scheduler | 280 | * If we were in kernel mode, we don't need to check scheduler |
175 | * or signals if CONFIG_PREEMPT is not set. If set, then it has | 281 | * or signals if CONFIG_PREEMPT is not set. If set, then it has |
176 | * to jump to a need_resched kind of block. | 282 | * to jump to a need_resched kind of block. |
@@ -183,69 +289,68 @@ event_dispatch: | |||
183 | #endif | 289 | #endif |
184 | 290 | ||
185 | /* "Nested control path" -- if the previous mode was kernel */ | 291 | /* "Nested control path" -- if the previous mode was kernel */ |
186 | R0 = memw(R29 + #_PT_ER_VMEST); | ||
187 | P0 = tstbit(R0, #HVM_VMEST_UM_SFT); | ||
188 | if !P0 jump restore_all; | ||
189 | /* | ||
190 | * Returning from system call, normally coming back from user mode | ||
191 | */ | ||
192 | return_from_syscall: | ||
193 | /* Disable interrupts while checking TIF */ | ||
194 | R0 = #VM_INT_DISABLE | ||
195 | trap1(#HVM_TRAP1_VMSETIE) | ||
196 | |||
197 | /* | ||
198 | * Coming back from the C-world, our thread info pointer | ||
199 | * should be in the designated register (usually R19) | ||
200 | */ | ||
201 | R1.L = #LO(_TIF_ALLWORK_MASK) | ||
202 | { | 292 | { |
203 | R1.H = #HI(_TIF_ALLWORK_MASK); | 293 | R0 = memw(R29 + #_PT_ER_VMEST); |
204 | R0 = memw(THREADINFO_REG + #_THREAD_INFO_FLAGS); | 294 | R16.L = #LO(do_work_pending); |
295 | } | ||
296 | { | ||
297 | P0 = tstbit(R0, #HVM_VMEST_UM_SFT); | ||
298 | if (!P0.new) jump:nt restore_all; | ||
299 | R16.H = #HI(do_work_pending); | ||
300 | R0 = #VM_INT_DISABLE; | ||
205 | } | 301 | } |
206 | 302 | ||
207 | /* | 303 | /* |
208 | * Compare against the "return to userspace" _TIF_WORK_MASK | 304 | * Check also the return from fork/system call, normally coming back from |
305 | * user mode | ||
306 | * | ||
307 | * R16 needs to have do_work_pending, and R0 should have VM_INT_DISABLE | ||
209 | */ | 308 | */ |
210 | R1 = and(R1,R0); | ||
211 | { P0 = cmp.eq(R1,#0); if (!P0.new) jump:t work_pending;} | ||
212 | jump restore_all; /* we're outta here! */ | ||
213 | 309 | ||
214 | work_pending: | 310 | check_work_pending: |
311 | /* Disable interrupts while checking TIF */ | ||
312 | trap1(#HVM_TRAP1_VMSETIE) | ||
215 | { | 313 | { |
216 | P0 = tstbit(R1, #TIF_NEED_RESCHED); | 314 | R0 = R29; /* regs should still be at top of stack */ |
217 | if (!P0.new) jump:nt work_notifysig; | 315 | R1 = memw(THREADINFO_REG + #_THREAD_INFO_FLAGS); |
316 | callr R16; | ||
218 | } | 317 | } |
219 | call schedule | ||
220 | jump return_from_syscall; /* check for more work */ | ||
221 | 318 | ||
222 | work_notifysig: | 319 | { |
223 | /* this is the part that's kind of fuzzy. */ | 320 | P0 = cmp.eq(R0, #0); if (!P0.new) jump:nt check_work_pending; |
224 | R1 = and(R0, #(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME)); | 321 | R0 = #VM_INT_DISABLE; |
225 | P0 = cmp.eq(R1, #0); | 322 | } |
226 | if P0 jump restore_all | ||
227 | R1 = R0; /* unsigned long thread_info_flags */ | ||
228 | R0 = R29; /* regs should still be at top of stack */ | ||
229 | call do_notify_resume | ||
230 | 323 | ||
231 | restore_all: | 324 | restore_all: |
232 | /* Disable interrupts, if they weren't already, before reg restore. */ | 325 | /* |
233 | R0 = #VM_INT_DISABLE | 326 | * Disable interrupts, if they weren't already, before reg restore. |
327 | * R0 gets preloaded with #VM_INT_DISABLE before we get here. | ||
328 | */ | ||
234 | trap1(#HVM_TRAP1_VMSETIE) | 329 | trap1(#HVM_TRAP1_VMSETIE) |
235 | 330 | ||
236 | /* do the setregs here for VM 0.5 */ | 331 | /* do the setregs here for VM 0.5 */ |
237 | /* R29 here should already be pointing at pt_regs */ | 332 | /* R29 here should already be pointing at pt_regs */ |
238 | R1:0 = memd(R29 + #_PT_ER_VMEL); | 333 | { |
239 | R3:2 = memd(R29 + #_PT_ER_VMPSP); | 334 | R1:0 = memd(R29 + #_PT_ER_VMEL); |
335 | R3:2 = memd(R29 + #_PT_ER_VMPSP); | ||
336 | } | ||
337 | #if CONFIG_HEXAGON_ARCH_VERSION < 4 | ||
240 | trap1(#HVM_TRAP1_VMSETREGS); | 338 | trap1(#HVM_TRAP1_VMSETREGS); |
339 | #else | ||
340 | G1:0 = R1:0; | ||
341 | G3:2 = R3:2; | ||
342 | #endif | ||
241 | 343 | ||
242 | R0 = R29 | 344 | R0 = R29 |
243 | restore_pt_regs() | 345 | restore_pt_regs() |
244 | R1:0 = memd(R29 + #_PT_R0100); | 346 | { |
245 | R29 = add(R29, #_PT_REGS_SIZE); | 347 | R1:0 = memd(R29 + #_PT_R0100); |
348 | R29 = add(R29, #_PT_REGS_SIZE); | ||
349 | } | ||
246 | trap1(#HVM_TRAP1_VMRTE) | 350 | trap1(#HVM_TRAP1_VMRTE) |
247 | /* Notreached */ | 351 | /* Notreached */ |
248 | 352 | ||
353 | |||
249 | .globl _K_enter_genex | 354 | .globl _K_enter_genex |
250 | _K_enter_genex: | 355 | _K_enter_genex: |
251 | vm_event_entry(do_genex) | 356 | vm_event_entry(do_genex) |
@@ -262,12 +367,27 @@ _K_enter_trap0: | |||
262 | _K_enter_machcheck: | 367 | _K_enter_machcheck: |
263 | vm_event_entry(do_machcheck) | 368 | vm_event_entry(do_machcheck) |
264 | 369 | ||
370 | .globl _K_enter_debug | ||
371 | _K_enter_debug: | ||
372 | vm_event_entry(do_debug_exception) | ||
265 | 373 | ||
266 | .globl ret_from_fork | 374 | .globl ret_from_fork |
267 | ret_from_fork: | 375 | ret_from_fork: |
268 | call schedule_tail | 376 | { |
269 | P0 = cmp.eq(R24, #0); | 377 | call schedule_tail |
270 | if P0 jump return_from_syscall | 378 | R16.H = #HI(do_work_pending); |
271 | R0 = R25; | 379 | } |
272 | callr R24 | 380 | { |
273 | jump return_from_syscall | 381 | P0 = cmp.eq(R24, #0); |
382 | R16.L = #LO(do_work_pending); | ||
383 | R0 = #VM_INT_DISABLE; | ||
384 | } | ||
385 | if P0 jump check_work_pending | ||
386 | { | ||
387 | R0 = R25; | ||
388 | callr R24 | ||
389 | } | ||
390 | { | ||
391 | jump check_work_pending | ||
392 | R0 = #VM_INT_DISABLE; | ||
393 | } | ||
diff --git a/arch/hexagon/kernel/vm_events.c b/arch/hexagon/kernel/vm_events.c index f337281ebe67..741aaa917cda 100644 --- a/arch/hexagon/kernel/vm_events.c +++ b/arch/hexagon/kernel/vm_events.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Mostly IRQ support for Hexagon | 2 | * Mostly IRQ support for Hexagon |
3 | * | 3 | * |
4 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 and | 7 | * it under the terms of the GNU General Public License version 2 and |
@@ -44,6 +44,8 @@ void show_regs(struct pt_regs *regs) | |||
44 | regs->lc1, regs->sa1, regs->m1); | 44 | regs->lc1, regs->sa1, regs->m1); |
45 | printk(KERN_EMERG "gp: \t0x%08lx ugp: 0x%08lx usr: 0x%08lx\n", | 45 | printk(KERN_EMERG "gp: \t0x%08lx ugp: 0x%08lx usr: 0x%08lx\n", |
46 | regs->gp, regs->ugp, regs->usr); | 46 | regs->gp, regs->ugp, regs->usr); |
47 | printk(KERN_EMERG "cs0: \t0x%08lx cs1: 0x%08lx\n", | ||
48 | regs->cs0, regs->cs1); | ||
47 | printk(KERN_EMERG "r0: \t0x%08lx %08lx %08lx %08lx\n", regs->r00, | 49 | printk(KERN_EMERG "r0: \t0x%08lx %08lx %08lx %08lx\n", regs->r00, |
48 | regs->r01, | 50 | regs->r01, |
49 | regs->r02, | 51 | regs->r02, |
diff --git a/arch/hexagon/kernel/vm_vectors.S b/arch/hexagon/kernel/vm_vectors.S index 620f42cc582a..791a7422dde4 100644 --- a/arch/hexagon/kernel/vm_vectors.S +++ b/arch/hexagon/kernel/vm_vectors.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Event jump tables | 2 | * Event jump tables |
3 | * | 3 | * |
4 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2010-2012,2013, The Linux Foundation. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 and | 7 | * it under the terms of the GNU General Public License version 2 and |
@@ -41,7 +41,7 @@ _K_VM_event_vector: | |||
41 | jump 1b; /* Reset */ | 41 | jump 1b; /* Reset */ |
42 | jump _K_enter_machcheck; | 42 | jump _K_enter_machcheck; |
43 | jump _K_enter_genex; | 43 | jump _K_enter_genex; |
44 | jump 1b; /* 3 Rsvd */ | 44 | jump _K_enter_debug; |
45 | jump 1b; /* 4 Rsvd */ | 45 | jump 1b; /* 4 Rsvd */ |
46 | jump _K_enter_trap0; | 46 | jump _K_enter_trap0; |
47 | jump 1b; /* 6 Rsvd */ | 47 | jump 1b; /* 6 Rsvd */ |
diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S index 14e793f6abbf..44d8c47bae2f 100644 --- a/arch/hexagon/kernel/vmlinux.lds.S +++ b/arch/hexagon/kernel/vmlinux.lds.S | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Linker script for Hexagon kernel | 2 | * Linker script for Hexagon kernel |
3 | * | 3 | * |
4 | * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | 4 | * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 and | 7 | * it under the terms of the GNU General Public License version 2 and |
@@ -18,8 +18,6 @@ | |||
18 | * 02110-1301, USA. | 18 | * 02110-1301, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #define LOAD_OFFSET PAGE_OFFSET | ||
22 | |||
23 | #include <asm-generic/vmlinux.lds.h> | 21 | #include <asm-generic/vmlinux.lds.h> |
24 | #include <asm/asm-offsets.h> /* Most of the kernel defines are here */ | 22 | #include <asm/asm-offsets.h> /* Most of the kernel defines are here */ |
25 | #include <asm/mem-layout.h> /* except for page_offset */ | 23 | #include <asm/mem-layout.h> /* except for page_offset */ |
@@ -36,13 +34,9 @@ See asm-generic/sections.h for seemingly required labels. | |||
36 | 34 | ||
37 | #define PAGE_SIZE _PAGE_SIZE | 35 | #define PAGE_SIZE _PAGE_SIZE |
38 | 36 | ||
39 | /* This LOAD_OFFSET is temporary for debugging on the simulator; it may change | ||
40 | for hypervisor pseudo-physical memory. */ | ||
41 | |||
42 | |||
43 | SECTIONS | 37 | SECTIONS |
44 | { | 38 | { |
45 | . = PAGE_OFFSET + LOAD_ADDRESS; | 39 | . = PAGE_OFFSET; |
46 | 40 | ||
47 | __init_begin = .; | 41 | __init_begin = .; |
48 | HEAD_TEXT_SECTION | 42 | HEAD_TEXT_SECTION |
@@ -52,7 +46,7 @@ SECTIONS | |||
52 | 46 | ||
53 | . = ALIGN(_PAGE_SIZE); | 47 | . = ALIGN(_PAGE_SIZE); |
54 | _stext = .; | 48 | _stext = .; |
55 | .text : AT(ADDR(.text) - LOAD_OFFSET) { | 49 | .text : AT(ADDR(.text)) { |
56 | _text = .; | 50 | _text = .; |
57 | TEXT_TEXT | 51 | TEXT_TEXT |
58 | SCHED_TEXT | 52 | SCHED_TEXT |