Commit 5be95b7e24bde4d93ff1bff5911b303043753168

Authored by Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux-hexagon-kernel

Pull arch/hexagon updates from Richard Kuo:
 "Build cleanup and a few misc fixes"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux-hexagon-kernel:
  Hexagon: fix signal delivery for debug traps
  Hexagon: set ARCH_DMA_MINALIGN
  Hexagon: fix alignment of init_task in RW_DATA_SECTION
  hexagon: Fix build failures in linux-next

Showing 8 changed files Inline Diff

arch/hexagon/include/asm/cache.h
1 /* 1 /*
2 * Cache definitions for the Hexagon architecture 2 * Cache definitions for the Hexagon architecture
3 * 3 *
4 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2010-2011,2014 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
8 * only version 2 as published by the Free Software Foundation. 8 * only version 2 as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 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 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA. 18 * 02110-1301, USA.
19 */ 19 */
20 20
21 #ifndef __ASM_CACHE_H 21 #ifndef __ASM_CACHE_H
22 #define __ASM_CACHE_H 22 #define __ASM_CACHE_H
23 23
24 /* Bytes per L1 cache line */ 24 /* Bytes per L1 cache line */
25 #define L1_CACHE_SHIFT (5) 25 #define L1_CACHE_SHIFT (5)
26 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) 26 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
27
28 #define ARCH_DMA_MINALIGN L1_CACHE_BYTES
27 29
28 #define __cacheline_aligned __aligned(L1_CACHE_BYTES) 30 #define __cacheline_aligned __aligned(L1_CACHE_BYTES)
29 #define ____cacheline_aligned __aligned(L1_CACHE_BYTES) 31 #define ____cacheline_aligned __aligned(L1_CACHE_BYTES)
30 32
31 /* See http://lwn.net/Articles/262554/ */ 33 /* See http://lwn.net/Articles/262554/ */
32 #define __read_mostly 34 #define __read_mostly
33 35
34 #endif 36 #endif
35 37
arch/hexagon/include/asm/cacheflush.h
1 /* 1 /*
2 * Cache flush operations for the Hexagon architecture 2 * Cache flush operations for the Hexagon architecture
3 * 3 *
4 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2010-2011, 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
8 * only version 2 as published by the Free Software Foundation. 8 * only version 2 as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 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 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA. 18 * 02110-1301, USA.
19 */ 19 */
20 20
21 #ifndef _ASM_CACHEFLUSH_H 21 #ifndef _ASM_CACHEFLUSH_H
22 #define _ASM_CACHEFLUSH_H 22 #define _ASM_CACHEFLUSH_H
23 23
24 #include <linux/cache.h> 24 #include <linux/mm_types.h>
25 #include <linux/mm.h>
26 #include <asm/string.h>
27 #include <asm-generic/cacheflush.h>
28 25
29 /* Cache flushing: 26 /* Cache flushing:
30 * 27 *
31 * - flush_cache_all() flushes entire cache 28 * - flush_cache_all() flushes entire cache
32 * - flush_cache_mm(mm) flushes the specified mm context's cache lines 29 * - flush_cache_mm(mm) flushes the specified mm context's cache lines
33 * - flush_cache_page(mm, vmaddr, pfn) flushes a single page 30 * - flush_cache_page(mm, vmaddr, pfn) flushes a single page
34 * - flush_cache_range(vma, start, end) flushes a range of pages 31 * - flush_cache_range(vma, start, end) flushes a range of pages
35 * - flush_icache_range(start, end) flush a range of instructions 32 * - flush_icache_range(start, end) flush a range of instructions
36 * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache 33 * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
37 * - flush_icache_page(vma, pg) flushes(invalidates) a page for icache 34 * - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
38 * 35 *
39 * Need to doublecheck which one is really needed for ptrace stuff to work. 36 * Need to doublecheck which one is really needed for ptrace stuff to work.
40 */ 37 */
41 #define LINESIZE 32 38 #define LINESIZE 32
42 #define LINEBITS 5 39 #define LINEBITS 5
43 40
41 #define flush_cache_all() do { } while (0)
42 #define flush_cache_mm(mm) do { } while (0)
43 #define flush_cache_dup_mm(mm) do { } while (0)
44 #define flush_cache_range(vma, start, end) do { } while (0)
45 #define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
46 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
47 #define flush_dcache_page(page) do { } while (0)
48 #define flush_dcache_mmap_lock(mapping) do { } while (0)
49 #define flush_dcache_mmap_unlock(mapping) do { } while (0)
50 #define flush_icache_page(vma, pg) do { } while (0)
51 #define flush_icache_user_range(vma, pg, adr, len) do { } while (0)
52 #define flush_cache_vmap(start, end) do { } while (0)
53 #define flush_cache_vunmap(start, end) do { } while (0)
54
44 /* 55 /*
45 * Flush Dcache range through current map. 56 * Flush Dcache range through current map.
46 */ 57 */
47 extern void flush_dcache_range(unsigned long start, unsigned long end); 58 extern void flush_dcache_range(unsigned long start, unsigned long end);
48 59
49 /* 60 /*
50 * Flush Icache range through current map. 61 * Flush Icache range through current map.
51 */ 62 */
52 #undef flush_icache_range
53 extern void flush_icache_range(unsigned long start, unsigned long end); 63 extern void flush_icache_range(unsigned long start, unsigned long end);
54 64
55 /* 65 /*
56 * Memory-management related flushes are there to ensure in non-physically 66 * Memory-management related flushes are there to ensure in non-physically
57 * indexed cache schemes that stale lines belonging to a given ASID aren't 67 * indexed cache schemes that stale lines belonging to a given ASID aren't
58 * in the cache to confuse things. The prototype Hexagon Virtual Machine 68 * in the cache to confuse things. The prototype Hexagon Virtual Machine
59 * only uses a single ASID for all user-mode maps, which should 69 * only uses a single ASID for all user-mode maps, which should
60 * mean that they aren't necessary. A brute-force, flush-everything 70 * mean that they aren't necessary. A brute-force, flush-everything
61 * implementation, with the name xxxxx_hexagon() is present in 71 * implementation, with the name xxxxx_hexagon() is present in
62 * arch/hexagon/mm/cache.c, but let's not wire it up until we know 72 * arch/hexagon/mm/cache.c, but let's not wire it up until we know
63 * it is needed. 73 * it is needed.
64 */ 74 */
65 extern void flush_cache_all_hexagon(void); 75 extern void flush_cache_all_hexagon(void);
66 76
67 /* 77 /*
68 * This may or may not ever have to be non-null, depending on the 78 * This may or may not ever have to be non-null, depending on the
69 * virtual machine MMU. For a native kernel, it's definitiely a no-op 79 * virtual machine MMU. For a native kernel, it's definitiely a no-op
70 * 80 *
71 * This is also the place where deferred cache coherency stuff seems 81 * This is also the place where deferred cache coherency stuff seems
72 * to happen, classically... but instead we do it like ia64 and 82 * to happen, classically... but instead we do it like ia64 and
73 * clean the cache when the PTE is set. 83 * clean the cache when the PTE is set.
74 * 84 *
75 */ 85 */
76 static inline void update_mmu_cache(struct vm_area_struct *vma, 86 static inline void update_mmu_cache(struct vm_area_struct *vma,
77 unsigned long address, pte_t *ptep) 87 unsigned long address, pte_t *ptep)
78 { 88 {
79 /* generic_ptrace_pokedata doesn't wind up here, does it? */ 89 /* generic_ptrace_pokedata doesn't wind up here, does it? */
80 } 90 }
81 91
82 #undef copy_to_user_page 92 void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
83 static inline void copy_to_user_page(struct vm_area_struct *vma, 93 unsigned long vaddr, void *dst, void *src, int len);
84 struct page *page,
85 unsigned long vaddr,
86 void *dst, void *src, int len)
87 {
88 memcpy(dst, src, len);
arch/hexagon/include/asm/io.h
1 /* 1 /*
2 * IO definitions for the Hexagon architecture 2 * IO definitions for the Hexagon architecture
3 * 3 *
4 * Copyright (c) 2010-2013, 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
8 * only version 2 as published by the Free Software Foundation. 8 * only version 2 as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 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 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA. 18 * 02110-1301, USA.
19 */ 19 */
20 20
21 #ifndef _ASM_IO_H 21 #ifndef _ASM_IO_H
22 #define _ASM_IO_H 22 #define _ASM_IO_H
23 23
24 #ifdef __KERNEL__ 24 #ifdef __KERNEL__
25 25
26 #include <linux/types.h> 26 #include <linux/types.h>
27 #include <linux/delay.h>
28 #include <linux/vmalloc.h>
29 #include <asm/string.h>
30 #include <asm/mem-layout.h>
31 #include <asm/iomap.h> 27 #include <asm/iomap.h>
32 #include <asm/page.h> 28 #include <asm/page.h>
33 #include <asm/cacheflush.h> 29 #include <asm/cacheflush.h>
34 #include <asm/tlbflush.h>
35 30
36 /* 31 /*
37 * We don't have PCI yet. 32 * We don't have PCI yet.
38 * _IO_BASE is pointing at what should be unused virtual space. 33 * _IO_BASE is pointing at what should be unused virtual space.
39 */ 34 */
40 #define IO_SPACE_LIMIT 0xffff 35 #define IO_SPACE_LIMIT 0xffff
41 #define _IO_BASE ((void __iomem *)0xfe000000) 36 #define _IO_BASE ((void __iomem *)0xfe000000)
42 37
43 #define IOMEM(x) ((void __force __iomem *)(x)) 38 #define IOMEM(x) ((void __force __iomem *)(x))
44 39
45 extern int remap_area_pages(unsigned long start, unsigned long phys_addr, 40 extern int remap_area_pages(unsigned long start, unsigned long phys_addr,
46 unsigned long end, unsigned long flags); 41 unsigned long end, unsigned long flags);
47 42
48 extern void __iounmap(const volatile void __iomem *addr); 43 extern void __iounmap(const volatile void __iomem *addr);
49 44
50 /* Defined in lib/io.c, needed for smc91x driver. */ 45 /* Defined in lib/io.c, needed for smc91x driver. */
51 extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen); 46 extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen);
52 extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen); 47 extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen);
53 48
54 extern void __raw_readsl(const void __iomem *addr, void *data, int wordlen); 49 extern void __raw_readsl(const void __iomem *addr, void *data, int wordlen);
55 extern void __raw_writesl(void __iomem *addr, const void *data, int wordlen); 50 extern void __raw_writesl(void __iomem *addr, const void *data, int wordlen);
56 51
57 #define readsw(p, d, l) __raw_readsw(p, d, l) 52 #define readsw(p, d, l) __raw_readsw(p, d, l)
58 #define writesw(p, d, l) __raw_writesw(p, d, l) 53 #define writesw(p, d, l) __raw_writesw(p, d, l)
59 54
60 #define readsl(p, d, l) __raw_readsl(p, d, l) 55 #define readsl(p, d, l) __raw_readsl(p, d, l)
61 #define writesl(p, d, l) __raw_writesl(p, d, l) 56 #define writesl(p, d, l) __raw_writesl(p, d, l)
62 57
63 /* 58 /*
64 * virt_to_phys - map virtual address to physical 59 * virt_to_phys - map virtual address to physical
65 * @address: address to map 60 * @address: address to map
66 */ 61 */
67 static inline unsigned long virt_to_phys(volatile void *address) 62 static inline unsigned long virt_to_phys(volatile void *address)
68 { 63 {
69 return __pa(address); 64 return __pa(address);
70 } 65 }
71 66
72 /* 67 /*
73 * phys_to_virt - map physical address to virtual 68 * phys_to_virt - map physical address to virtual
74 * @address: address to map 69 * @address: address to map
75 */ 70 */
76 static inline void *phys_to_virt(unsigned long address) 71 static inline void *phys_to_virt(unsigned long address)
77 { 72 {
78 return __va(address); 73 return __va(address);
79 } 74 }
80 75
81 /* 76 /*
82 * convert a physical pointer to a virtual kernel pointer for 77 * convert a physical pointer to a virtual kernel pointer for
83 * /dev/mem access. 78 * /dev/mem access.
84 */ 79 */
85 #define xlate_dev_kmem_ptr(p) __va(p) 80 #define xlate_dev_kmem_ptr(p) __va(p)
86 #define xlate_dev_mem_ptr(p) __va(p) 81 #define xlate_dev_mem_ptr(p) __va(p)
87 82
88 /* 83 /*
89 * IO port access primitives. Hexagon doesn't have special IO access 84 * IO port access primitives. Hexagon doesn't have special IO access
90 * instructions; all I/O is memory mapped. 85 * instructions; all I/O is memory mapped.
91 * 86 *
92 * in/out are used for "ports", but we don't have "port instructions", 87 * in/out are used for "ports", but we don't have "port instructions",
93 * so these are really just memory mapped too. 88 * so these are really just memory mapped too.
94 */ 89 */
95 90
96 /* 91 /*
97 * readb - read byte from memory mapped device 92 * readb - read byte from memory mapped device
98 * @addr: pointer to memory 93 * @addr: pointer to memory
99 * 94 *
100 * Operates on "I/O bus memory space" 95 * Operates on "I/O bus memory space"
101 */ 96 */
102 static inline u8 readb(const volatile void __iomem *addr) 97 static inline u8 readb(const volatile void __iomem *addr)
103 { 98 {
104 u8 val; 99 u8 val;
105 asm volatile( 100 asm volatile(
106 "%0 = memb(%1);" 101 "%0 = memb(%1);"
107 : "=&r" (val) 102 : "=&r" (val)
108 : "r" (addr) 103 : "r" (addr)
109 ); 104 );
110 return val; 105 return val;
111 } 106 }
112 107
113 static inline u16 readw(const volatile void __iomem *addr) 108 static inline u16 readw(const volatile void __iomem *addr)
114 { 109 {
115 u16 val; 110 u16 val;
116 asm volatile( 111 asm volatile(
117 "%0 = memh(%1);" 112 "%0 = memh(%1);"
118 : "=&r" (val) 113 : "=&r" (val)
119 : "r" (addr) 114 : "r" (addr)
120 ); 115 );
121 return val; 116 return val;
122 } 117 }
123 118
124 static inline u32 readl(const volatile void __iomem *addr) 119 static inline u32 readl(const volatile void __iomem *addr)
125 { 120 {
126 u32 val; 121 u32 val;
127 asm volatile( 122 asm volatile(
128 "%0 = memw(%1);" 123 "%0 = memw(%1);"
129 : "=&r" (val) 124 : "=&r" (val)
130 : "r" (addr) 125 : "r" (addr)
131 ); 126 );
132 return val; 127 return val;
133 } 128 }
134 129
135 /* 130 /*
136 * writeb - write a byte to a memory location 131 * writeb - write a byte to a memory location
137 * @data: data to write to 132 * @data: data to write to
138 * @addr: pointer to memory 133 * @addr: pointer to memory
139 * 134 *
140 */ 135 */
141 static inline void writeb(u8 data, volatile void __iomem *addr) 136 static inline void writeb(u8 data, volatile void __iomem *addr)
142 { 137 {
143 asm volatile( 138 asm volatile(
144 "memb(%0) = %1;" 139 "memb(%0) = %1;"
145 : 140 :
146 : "r" (addr), "r" (data) 141 : "r" (addr), "r" (data)
147 : "memory" 142 : "memory"
148 ); 143 );
149 } 144 }
150 145
151 static inline void writew(u16 data, volatile void __iomem *addr) 146 static inline void writew(u16 data, volatile void __iomem *addr)
152 { 147 {
153 asm volatile( 148 asm volatile(
154 "memh(%0) = %1;" 149 "memh(%0) = %1;"
155 : 150 :
156 : "r" (addr), "r" (data) 151 : "r" (addr), "r" (data)
157 : "memory" 152 : "memory"
158 ); 153 );
159 154
160 } 155 }
161 156
162 static inline void writel(u32 data, volatile void __iomem *addr) 157 static inline void writel(u32 data, volatile void __iomem *addr)
163 { 158 {
164 asm volatile( 159 asm volatile(
165 "memw(%0) = %1;" 160 "memw(%0) = %1;"
166 : 161 :
167 : "r" (addr), "r" (data) 162 : "r" (addr), "r" (data)
168 : "memory" 163 : "memory"
169 ); 164 );
170 } 165 }
171 166
172 #define __raw_writeb writeb 167 #define __raw_writeb writeb
173 #define __raw_writew writew 168 #define __raw_writew writew
174 #define __raw_writel writel 169 #define __raw_writel writel
175 170
176 #define __raw_readb readb 171 #define __raw_readb readb
177 #define __raw_readw readw 172 #define __raw_readw readw
178 #define __raw_readl readl 173 #define __raw_readl readl
179 174
180 /* 175 /*
181 * http://comments.gmane.org/gmane.linux.ports.arm.kernel/117626 176 * http://comments.gmane.org/gmane.linux.ports.arm.kernel/117626
182 */ 177 */
183 178
184 #define readb_relaxed __raw_readb 179 #define readb_relaxed __raw_readb
185 #define readw_relaxed __raw_readw 180 #define readw_relaxed __raw_readw
186 #define readl_relaxed __raw_readl 181 #define readl_relaxed __raw_readl
187 182
188 #define writeb_relaxed __raw_writeb 183 #define writeb_relaxed __raw_writeb
189 #define writew_relaxed __raw_writew 184 #define writew_relaxed __raw_writew
190 #define writel_relaxed __raw_writel 185 #define writel_relaxed __raw_writel
191 186
192 #define mmiowb() 187 #define mmiowb()
193 188
194 /* 189 /*
195 * Need an mtype somewhere in here, for cache type deals? 190 * Need an mtype somewhere in here, for cache type deals?
196 * This is probably too long for an inline. 191 * This is probably too long for an inline.
197 */ 192 */
198 void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size); 193 void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size);
199 194
200 static inline void __iomem *ioremap(unsigned long phys_addr, unsigned long size) 195 static inline void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
201 { 196 {
202 return ioremap_nocache(phys_addr, size); 197 return ioremap_nocache(phys_addr, size);
203 } 198 }
204 199
205 static inline void iounmap(volatile void __iomem *addr) 200 static inline void iounmap(volatile void __iomem *addr)
206 { 201 {
207 __iounmap(addr); 202 __iounmap(addr);
208 } 203 }
209 204
210 #define __raw_writel writel 205 #define __raw_writel writel
211 206
212 static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, 207 static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
213 int count) 208 int count)
214 { 209 {
215 memcpy(dst, (void *) src, count); 210 memcpy(dst, (void *) src, count);
216 } 211 }
217 212
218 static inline void memcpy_toio(volatile void __iomem *dst, const void *src, 213 static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
219 int count) 214 int count)
220 { 215 {
221 memcpy((void *) dst, src, count); 216 memcpy((void *) dst, src, count);
222 } 217 }
223 218
224 #define PCI_IO_ADDR (volatile void __iomem *) 219 #define PCI_IO_ADDR (volatile void __iomem *)
225 220
226 /* 221 /*
227 * inb - read byte from I/O port or something 222 * inb - read byte from I/O port or something
228 * @port: address in I/O space 223 * @port: address in I/O space
229 * 224 *
230 * Operates on "I/O bus I/O space" 225 * Operates on "I/O bus I/O space"
231 */ 226 */
232 static inline u8 inb(unsigned long port) 227 static inline u8 inb(unsigned long port)
233 { 228 {
234 return readb(_IO_BASE + (port & IO_SPACE_LIMIT)); 229 return readb(_IO_BASE + (port & IO_SPACE_LIMIT));
235 } 230 }
236 231
237 static inline u16 inw(unsigned long port) 232 static inline u16 inw(unsigned long port)
238 { 233 {
239 return readw(_IO_BASE + (port & IO_SPACE_LIMIT)); 234 return readw(_IO_BASE + (port & IO_SPACE_LIMIT));
240 } 235 }
241 236
242 static inline u32 inl(unsigned long port) 237 static inline u32 inl(unsigned long port)
243 { 238 {
244 return readl(_IO_BASE + (port & IO_SPACE_LIMIT)); 239 return readl(_IO_BASE + (port & IO_SPACE_LIMIT));
245 } 240 }
246 241
247 /* 242 /*
248 * outb - write a byte to a memory location 243 * outb - write a byte to a memory location
249 * @data: data to write to 244 * @data: data to write to
250 * @addr: address in I/O space 245 * @addr: address in I/O space
251 */ 246 */
252 static inline void outb(u8 data, unsigned long port) 247 static inline void outb(u8 data, unsigned long port)
253 { 248 {
254 writeb(data, _IO_BASE + (port & IO_SPACE_LIMIT)); 249 writeb(data, _IO_BASE + (port & IO_SPACE_LIMIT));
255 } 250 }
256 251
257 static inline void outw(u16 data, unsigned long port) 252 static inline void outw(u16 data, unsigned long port)
258 { 253 {
259 writew(data, _IO_BASE + (port & IO_SPACE_LIMIT)); 254 writew(data, _IO_BASE + (port & IO_SPACE_LIMIT));
260 } 255 }
261 256
262 static inline void outl(u32 data, unsigned long port) 257 static inline void outl(u32 data, unsigned long port)
263 { 258 {
264 writel(data, _IO_BASE + (port & IO_SPACE_LIMIT)); 259 writel(data, _IO_BASE + (port & IO_SPACE_LIMIT));
265 } 260 }
266 261
267 #define outb_p outb 262 #define outb_p outb
268 #define outw_p outw 263 #define outw_p outw
269 #define outl_p outl 264 #define outl_p outl
270 265
271 #define inb_p inb 266 #define inb_p inb
272 #define inw_p inw 267 #define inw_p inw
273 #define inl_p inl 268 #define inl_p inl
274 269
275 static inline void insb(unsigned long port, void *buffer, int count) 270 static inline void insb(unsigned long port, void *buffer, int count)
276 { 271 {
277 if (count) { 272 if (count) {
278 u8 *buf = buffer; 273 u8 *buf = buffer;
279 do { 274 do {
280 u8 x = inb(port); 275 u8 x = inb(port);
281 *buf++ = x; 276 *buf++ = x;
282 } while (--count); 277 } while (--count);
283 } 278 }
284 } 279 }
285 280
286 static inline void insw(unsigned long port, void *buffer, int count) 281 static inline void insw(unsigned long port, void *buffer, int count)
287 { 282 {
288 if (count) { 283 if (count) {
289 u16 *buf = buffer; 284 u16 *buf = buffer;
290 do { 285 do {
291 u16 x = inw(port); 286 u16 x = inw(port);
292 *buf++ = x; 287 *buf++ = x;
293 } while (--count); 288 } while (--count);
294 } 289 }
295 } 290 }
296 291
297 static inline void insl(unsigned long port, void *buffer, int count) 292 static inline void insl(unsigned long port, void *buffer, int count)
298 { 293 {
299 if (count) { 294 if (count) {
300 u32 *buf = buffer; 295 u32 *buf = buffer;
301 do { 296 do {
302 u32 x = inw(port); 297 u32 x = inw(port);
303 *buf++ = x; 298 *buf++ = x;
304 } while (--count); 299 } while (--count);
305 } 300 }
306 } 301 }
307 302
308 static inline void outsb(unsigned long port, const void *buffer, int count) 303 static inline void outsb(unsigned long port, const void *buffer, int count)
309 { 304 {
310 if (count) { 305 if (count) {
311 const u8 *buf = buffer; 306 const u8 *buf = buffer;
312 do { 307 do {
313 outb(*buf++, port); 308 outb(*buf++, port);
314 } while (--count); 309 } while (--count);
315 } 310 }
316 } 311 }
317 312
318 static inline void outsw(unsigned long port, const void *buffer, int count) 313 static inline void outsw(unsigned long port, const void *buffer, int count)
319 { 314 {
320 if (count) { 315 if (count) {
321 const u16 *buf = buffer; 316 const u16 *buf = buffer;
322 do { 317 do {
323 outw(*buf++, port); 318 outw(*buf++, port);
324 } while (--count); 319 } while (--count);
325 } 320 }
326 } 321 }
327 322
328 static inline void outsl(unsigned long port, const void *buffer, int count) 323 static inline void outsl(unsigned long port, const void *buffer, int count)
329 { 324 {
330 if (count) { 325 if (count) {
331 const u32 *buf = buffer; 326 const u32 *buf = buffer;
332 do { 327 do {
333 outl(*buf++, port); 328 outl(*buf++, port);
334 } while (--count); 329 } while (--count);
335 } 330 }
336 } 331 }
337 332
338 #define flush_write_buffers() do { } while (0) 333 #define flush_write_buffers() do { } while (0)
339 334
340 #endif /* __KERNEL__ */ 335 #endif /* __KERNEL__ */
341 336
342 #endif 337 #endif
343 338
arch/hexagon/kernel/setup.c
1 /* 1 /*
2 * Arch related setup for Hexagon 2 * Arch related setup for Hexagon
3 * 3 *
4 * Copyright (c) 2010-2013, 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
8 * only version 2 as published by the Free Software Foundation. 8 * only version 2 as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 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 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA. 18 * 02110-1301, USA.
19 */ 19 */
20 20
21 #include <linux/init.h> 21 #include <linux/init.h>
22 #include <linux/delay.h>
22 #include <linux/bootmem.h> 23 #include <linux/bootmem.h>
23 #include <linux/mmzone.h> 24 #include <linux/mmzone.h>
24 #include <linux/mm.h> 25 #include <linux/mm.h>
25 #include <linux/seq_file.h> 26 #include <linux/seq_file.h>
26 #include <linux/console.h> 27 #include <linux/console.h>
27 #include <linux/of_fdt.h> 28 #include <linux/of_fdt.h>
28 #include <asm/io.h> 29 #include <asm/io.h>
29 #include <asm/sections.h> 30 #include <asm/sections.h>
30 #include <asm/setup.h> 31 #include <asm/setup.h>
31 #include <asm/processor.h> 32 #include <asm/processor.h>
32 #include <asm/hexagon_vm.h> 33 #include <asm/hexagon_vm.h>
33 #include <asm/vm_mmu.h> 34 #include <asm/vm_mmu.h>
34 #include <asm/time.h> 35 #include <asm/time.h>
35 36
36 char cmd_line[COMMAND_LINE_SIZE]; 37 char cmd_line[COMMAND_LINE_SIZE];
37 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; 38 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
38 39
39 int on_simulator; 40 int on_simulator;
40 41
41 void calibrate_delay(void) 42 void calibrate_delay(void)
42 { 43 {
43 loops_per_jiffy = thread_freq_mhz * 1000000 / HZ; 44 loops_per_jiffy = thread_freq_mhz * 1000000 / HZ;
44 } 45 }
45 46
46 /* 47 /*
47 * setup_arch - high level architectural setup routine 48 * setup_arch - high level architectural setup routine
48 * @cmdline_p: pointer to pointer to command-line arguments 49 * @cmdline_p: pointer to pointer to command-line arguments
49 */ 50 */
50 51
51 void __init setup_arch(char **cmdline_p) 52 void __init setup_arch(char **cmdline_p)
52 { 53 {
53 char *p = &external_cmdline_buffer; 54 char *p = &external_cmdline_buffer;
54 55
55 /* 56 /*
56 * These will eventually be pulled in via either some hypervisor 57 * These will eventually be pulled in via either some hypervisor
57 * or devicetree description. Hardwiring for now. 58 * or devicetree description. Hardwiring for now.
58 */ 59 */
59 pcycle_freq_mhz = 600; 60 pcycle_freq_mhz = 600;
60 thread_freq_mhz = 100; 61 thread_freq_mhz = 100;
61 sleep_clk_freq = 32000; 62 sleep_clk_freq = 32000;
62 63
63 /* 64 /*
64 * Set up event bindings to handle exceptions and interrupts. 65 * Set up event bindings to handle exceptions and interrupts.
65 */ 66 */
66 __vmsetvec(_K_VM_event_vector); 67 __vmsetvec(_K_VM_event_vector);
67 68
68 printk(KERN_INFO "PHYS_OFFSET=0x%08x\n", PHYS_OFFSET); 69 printk(KERN_INFO "PHYS_OFFSET=0x%08x\n", PHYS_OFFSET);
69 70
70 /* 71 /*
71 * Simulator has a few differences from the hardware. 72 * Simulator has a few differences from the hardware.
72 * For now, check uninitialized-but-mapped memory 73 * For now, check uninitialized-but-mapped memory
73 * prior to invoking setup_arch_memory(). 74 * prior to invoking setup_arch_memory().
74 */ 75 */
75 if (*(int *)((unsigned long)_end + 8) == 0x1f1f1f1f) 76 if (*(int *)((unsigned long)_end + 8) == 0x1f1f1f1f)
76 on_simulator = 1; 77 on_simulator = 1;
77 else 78 else
78 on_simulator = 0; 79 on_simulator = 0;
79 80
80 if (p[0] != '\0') 81 if (p[0] != '\0')
81 strlcpy(boot_command_line, p, COMMAND_LINE_SIZE); 82 strlcpy(boot_command_line, p, COMMAND_LINE_SIZE);
82 else 83 else
83 strlcpy(boot_command_line, default_command_line, 84 strlcpy(boot_command_line, default_command_line,
84 COMMAND_LINE_SIZE); 85 COMMAND_LINE_SIZE);
85 86
86 /* 87 /*
87 * boot_command_line and the value set up by setup_arch 88 * boot_command_line and the value set up by setup_arch
88 * are both picked up by the init code. If no reason to 89 * are both picked up by the init code. If no reason to
89 * make them different, pass the same pointer back. 90 * make them different, pass the same pointer back.
90 */ 91 */
91 strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); 92 strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
92 *cmdline_p = cmd_line; 93 *cmdline_p = cmd_line;
93 94
94 parse_early_param(); 95 parse_early_param();
95 96
96 setup_arch_memory(); 97 setup_arch_memory();
97 98
98 #ifdef CONFIG_SMP 99 #ifdef CONFIG_SMP
99 smp_start_cpus(); 100 smp_start_cpus();
100 #endif 101 #endif
101 } 102 }
102 103
103 /* 104 /*
104 * Functions for dumping CPU info via /proc 105 * Functions for dumping CPU info via /proc
105 * Probably should move to kernel/proc.c or something. 106 * Probably should move to kernel/proc.c or something.
106 */ 107 */
107 static void *c_start(struct seq_file *m, loff_t *pos) 108 static void *c_start(struct seq_file *m, loff_t *pos)
108 { 109 {
109 return *pos < nr_cpu_ids ? (void *)((unsigned long) *pos + 1) : NULL; 110 return *pos < nr_cpu_ids ? (void *)((unsigned long) *pos + 1) : NULL;
110 } 111 }
111 112
112 static void *c_next(struct seq_file *m, void *v, loff_t *pos) 113 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
113 { 114 {
114 ++*pos; 115 ++*pos;
115 return c_start(m, pos); 116 return c_start(m, pos);
116 } 117 }
117 118
118 static void c_stop(struct seq_file *m, void *v) 119 static void c_stop(struct seq_file *m, void *v)
119 { 120 {
120 } 121 }
121 122
122 /* 123 /*
123 * Eventually this will dump information about 124 * Eventually this will dump information about
124 * CPU properties like ISA level, TLB size, etc. 125 * CPU properties like ISA level, TLB size, etc.
125 */ 126 */
126 static int show_cpuinfo(struct seq_file *m, void *v) 127 static int show_cpuinfo(struct seq_file *m, void *v)
127 { 128 {
128 int cpu = (unsigned long) v - 1; 129 int cpu = (unsigned long) v - 1;
129 130
130 #ifdef CONFIG_SMP 131 #ifdef CONFIG_SMP
131 if (!cpu_online(cpu)) 132 if (!cpu_online(cpu))
132 return 0; 133 return 0;
133 #endif 134 #endif
134 135
135 seq_printf(m, "processor\t: %d\n", cpu); 136 seq_printf(m, "processor\t: %d\n", cpu);
136 seq_printf(m, "model name\t: Hexagon Virtual Machine\n"); 137 seq_printf(m, "model name\t: Hexagon Virtual Machine\n");
137 seq_printf(m, "BogoMips\t: %lu.%02lu\n", 138 seq_printf(m, "BogoMips\t: %lu.%02lu\n",
138 (loops_per_jiffy * HZ) / 500000, 139 (loops_per_jiffy * HZ) / 500000,
139 ((loops_per_jiffy * HZ) / 5000) % 100); 140 ((loops_per_jiffy * HZ) / 5000) % 100);
140 seq_printf(m, "\n"); 141 seq_printf(m, "\n");
141 return 0; 142 return 0;
142 } 143 }
143 144
144 const struct seq_operations cpuinfo_op = { 145 const struct seq_operations cpuinfo_op = {
145 .start = &c_start, 146 .start = &c_start,
146 .next = &c_next, 147 .next = &c_next,
147 .stop = &c_stop, 148 .stop = &c_stop,
148 .show = &show_cpuinfo, 149 .show = &show_cpuinfo,
149 }; 150 };
150 151
arch/hexagon/kernel/traps.c
1 /* 1 /*
2 * Kernel traps/events for Hexagon processor 2 * Kernel traps/events for Hexagon processor
3 * 3 *
4 * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2010-2014, 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
8 * only version 2 as published by the Free Software Foundation. 8 * only version 2 as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 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 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA. 18 * 02110-1301, USA.
19 */ 19 */
20 20
21 #include <linux/init.h> 21 #include <linux/init.h>
22 #include <linux/sched.h> 22 #include <linux/sched.h>
23 #include <linux/module.h> 23 #include <linux/module.h>
24 #include <linux/kallsyms.h> 24 #include <linux/kallsyms.h>
25 #include <linux/kdebug.h> 25 #include <linux/kdebug.h>
26 #include <linux/syscalls.h> 26 #include <linux/syscalls.h>
27 #include <linux/signal.h> 27 #include <linux/signal.h>
28 #include <linux/tracehook.h> 28 #include <linux/tracehook.h>
29 #include <asm/traps.h> 29 #include <asm/traps.h>
30 #include <asm/vm_fault.h> 30 #include <asm/vm_fault.h>
31 #include <asm/syscall.h> 31 #include <asm/syscall.h>
32 #include <asm/registers.h> 32 #include <asm/registers.h>
33 #include <asm/unistd.h> 33 #include <asm/unistd.h>
34 #include <asm/sections.h> 34 #include <asm/sections.h>
35 #ifdef CONFIG_KGDB 35 #ifdef CONFIG_KGDB
36 # include <linux/kgdb.h> 36 # include <linux/kgdb.h>
37 #endif 37 #endif
38 38
39 #define TRAP_SYSCALL 1 39 #define TRAP_SYSCALL 1
40 #define TRAP_DEBUG 0xdb 40 #define TRAP_DEBUG 0xdb
41 41
42 void __init trap_init(void) 42 void __init trap_init(void)
43 { 43 {
44 } 44 }
45 45
46 #ifdef CONFIG_GENERIC_BUG 46 #ifdef CONFIG_GENERIC_BUG
47 /* Maybe should resemble arch/sh/kernel/traps.c ?? */ 47 /* Maybe should resemble arch/sh/kernel/traps.c ?? */
48 int is_valid_bugaddr(unsigned long addr) 48 int is_valid_bugaddr(unsigned long addr)
49 { 49 {
50 return 1; 50 return 1;
51 } 51 }
52 #endif /* CONFIG_GENERIC_BUG */ 52 #endif /* CONFIG_GENERIC_BUG */
53 53
54 static const char *ex_name(int ex) 54 static const char *ex_name(int ex)
55 { 55 {
56 switch (ex) { 56 switch (ex) {
57 case HVM_GE_C_XPROT: 57 case HVM_GE_C_XPROT:
58 case HVM_GE_C_XUSER: 58 case HVM_GE_C_XUSER:
59 return "Execute protection fault"; 59 return "Execute protection fault";
60 case HVM_GE_C_RPROT: 60 case HVM_GE_C_RPROT:
61 case HVM_GE_C_RUSER: 61 case HVM_GE_C_RUSER:
62 return "Read protection fault"; 62 return "Read protection fault";
63 case HVM_GE_C_WPROT: 63 case HVM_GE_C_WPROT:
64 case HVM_GE_C_WUSER: 64 case HVM_GE_C_WUSER:
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: 68 case HVM_GE_C_WREG:
69 return "Multiple writes to same register in packet"; 69 return "Multiple writes to same register in packet";
70 case HVM_GE_C_PCAL: 70 case HVM_GE_C_PCAL:
71 return "Program counter values that are not properly aligned"; 71 return "Program counter values that are not properly aligned";
72 case HVM_GE_C_RMAL: 72 case HVM_GE_C_RMAL:
73 return "Misaligned data load"; 73 return "Misaligned data load";
74 case HVM_GE_C_WMAL: 74 case HVM_GE_C_WMAL:
75 return "Misaligned data store"; 75 return "Misaligned data store";
76 case HVM_GE_C_INVI: 76 case HVM_GE_C_INVI:
77 case HVM_GE_C_PRIVI: 77 case HVM_GE_C_PRIVI:
78 return "Illegal instruction"; 78 return "Illegal instruction";
79 case HVM_GE_C_BUS: 79 case HVM_GE_C_BUS:
80 return "Precise bus error"; 80 return "Precise bus error";
81 case HVM_GE_C_CACHE: 81 case HVM_GE_C_CACHE:
82 return "Cache error"; 82 return "Cache error";
83 83
84 case 0xdb: 84 case 0xdb:
85 return "Debugger trap"; 85 return "Debugger trap";
86 86
87 default: 87 default:
88 return "Unrecognized exception"; 88 return "Unrecognized exception";
89 } 89 }
90 } 90 }
91 91
92 static void do_show_stack(struct task_struct *task, unsigned long *fp, 92 static void do_show_stack(struct task_struct *task, unsigned long *fp,
93 unsigned long ip) 93 unsigned long ip)
94 { 94 {
95 int kstack_depth_to_print = 24; 95 int kstack_depth_to_print = 24;
96 unsigned long offset, size; 96 unsigned long offset, size;
97 const char *name = NULL; 97 const char *name = NULL;
98 unsigned long *newfp; 98 unsigned long *newfp;
99 unsigned long low, high; 99 unsigned long low, high;
100 char tmpstr[128]; 100 char tmpstr[128];
101 char *modname; 101 char *modname;
102 int i; 102 int i;
103 103
104 if (task == NULL) 104 if (task == NULL)
105 task = current; 105 task = current;
106 106
107 printk(KERN_INFO "CPU#%d, %s/%d, Call Trace:\n", 107 printk(KERN_INFO "CPU#%d, %s/%d, Call Trace:\n",
108 raw_smp_processor_id(), task->comm, 108 raw_smp_processor_id(), task->comm,
109 task_pid_nr(task)); 109 task_pid_nr(task));
110 110
111 if (fp == NULL) { 111 if (fp == NULL) {
112 if (task == current) { 112 if (task == current) {
113 asm("%0 = r30" : "=r" (fp)); 113 asm("%0 = r30" : "=r" (fp));
114 } else { 114 } else {
115 fp = (unsigned long *) 115 fp = (unsigned long *)
116 ((struct hexagon_switch_stack *) 116 ((struct hexagon_switch_stack *)
117 task->thread.switch_sp)->fp; 117 task->thread.switch_sp)->fp;
118 } 118 }
119 } 119 }
120 120
121 if ((((unsigned long) fp) & 0x3) || ((unsigned long) fp < 0x1000)) { 121 if ((((unsigned long) fp) & 0x3) || ((unsigned long) fp < 0x1000)) {
122 printk(KERN_INFO "-- Corrupt frame pointer %p\n", fp); 122 printk(KERN_INFO "-- Corrupt frame pointer %p\n", fp);
123 return; 123 return;
124 } 124 }
125 125
126 /* Saved link reg is one word above FP */ 126 /* Saved link reg is one word above FP */
127 if (!ip) 127 if (!ip)
128 ip = *(fp+1); 128 ip = *(fp+1);
129 129
130 /* Expect kernel stack to be in-bounds */ 130 /* Expect kernel stack to be in-bounds */
131 low = (unsigned long)task_stack_page(task); 131 low = (unsigned long)task_stack_page(task);
132 high = low + THREAD_SIZE - 8; 132 high = low + THREAD_SIZE - 8;
133 low += sizeof(struct thread_info); 133 low += sizeof(struct thread_info);
134 134
135 for (i = 0; i < kstack_depth_to_print; i++) { 135 for (i = 0; i < kstack_depth_to_print; i++) {
136 136
137 name = kallsyms_lookup(ip, &size, &offset, &modname, tmpstr); 137 name = kallsyms_lookup(ip, &size, &offset, &modname, tmpstr);
138 138
139 printk(KERN_INFO "[%p] 0x%lx: %s + 0x%lx", fp, ip, name, 139 printk(KERN_INFO "[%p] 0x%lx: %s + 0x%lx", fp, ip, name,
140 offset); 140 offset);
141 if (((unsigned long) fp < low) || (high < (unsigned long) fp)) 141 if (((unsigned long) fp < low) || (high < (unsigned long) fp))
142 printk(KERN_CONT " (FP out of bounds!)"); 142 printk(KERN_CONT " (FP out of bounds!)");
143 if (modname) 143 if (modname)
144 printk(KERN_CONT " [%s] ", modname); 144 printk(KERN_CONT " [%s] ", modname);
145 printk(KERN_CONT "\n"); 145 printk(KERN_CONT "\n");
146 146
147 newfp = (unsigned long *) *fp; 147 newfp = (unsigned long *) *fp;
148 148
149 if (((unsigned long) newfp) & 0x3) { 149 if (((unsigned long) newfp) & 0x3) {
150 printk(KERN_INFO "-- Corrupt frame pointer %p\n", 150 printk(KERN_INFO "-- Corrupt frame pointer %p\n",
151 newfp); 151 newfp);
152 break; 152 break;
153 } 153 }
154 154
155 /* Attempt to continue past exception. */ 155 /* Attempt to continue past exception. */
156 if (0 == newfp) { 156 if (0 == newfp) {
157 struct pt_regs *regs = (struct pt_regs *) (((void *)fp) 157 struct pt_regs *regs = (struct pt_regs *) (((void *)fp)
158 + 8); 158 + 8);
159 159
160 if (regs->syscall_nr != -1) { 160 if (regs->syscall_nr != -1) {
161 printk(KERN_INFO "-- trap0 -- syscall_nr: %ld", 161 printk(KERN_INFO "-- trap0 -- syscall_nr: %ld",
162 regs->syscall_nr); 162 regs->syscall_nr);
163 printk(KERN_CONT " psp: %lx elr: %lx\n", 163 printk(KERN_CONT " psp: %lx elr: %lx\n",
164 pt_psp(regs), pt_elr(regs)); 164 pt_psp(regs), pt_elr(regs));
165 break; 165 break;
166 } else { 166 } else {
167 /* really want to see more ... */ 167 /* really want to see more ... */
168 kstack_depth_to_print += 6; 168 kstack_depth_to_print += 6;
169 printk(KERN_INFO "-- %s (0x%lx) badva: %lx\n", 169 printk(KERN_INFO "-- %s (0x%lx) badva: %lx\n",
170 ex_name(pt_cause(regs)), pt_cause(regs), 170 ex_name(pt_cause(regs)), pt_cause(regs),
171 pt_badva(regs)); 171 pt_badva(regs));
172 } 172 }
173 173
174 newfp = (unsigned long *) regs->r30; 174 newfp = (unsigned long *) regs->r30;
175 ip = pt_elr(regs); 175 ip = pt_elr(regs);
176 } else { 176 } else {
177 ip = *(newfp + 1); 177 ip = *(newfp + 1);
178 } 178 }
179 179
180 /* If link reg is null, we are done. */ 180 /* If link reg is null, we are done. */
181 if (ip == 0x0) 181 if (ip == 0x0)
182 break; 182 break;
183 183
184 /* If newfp isn't larger, we're tracing garbage. */ 184 /* If newfp isn't larger, we're tracing garbage. */
185 if (newfp > fp) 185 if (newfp > fp)
186 fp = newfp; 186 fp = newfp;
187 else 187 else
188 break; 188 break;
189 } 189 }
190 } 190 }
191 191
192 void show_stack(struct task_struct *task, unsigned long *fp) 192 void show_stack(struct task_struct *task, unsigned long *fp)
193 { 193 {
194 /* Saved link reg is one word above FP */ 194 /* Saved link reg is one word above FP */
195 do_show_stack(task, fp, 0); 195 do_show_stack(task, fp, 0);
196 } 196 }
197 197
198 int die(const char *str, struct pt_regs *regs, long err) 198 int die(const char *str, struct pt_regs *regs, long err)
199 { 199 {
200 static struct { 200 static struct {
201 spinlock_t lock; 201 spinlock_t lock;
202 int counter; 202 int counter;
203 } die = { 203 } die = {
204 .lock = __SPIN_LOCK_UNLOCKED(die.lock), 204 .lock = __SPIN_LOCK_UNLOCKED(die.lock),
205 .counter = 0 205 .counter = 0
206 }; 206 };
207 207
208 console_verbose(); 208 console_verbose();
209 oops_enter(); 209 oops_enter();
210 210
211 spin_lock_irq(&die.lock); 211 spin_lock_irq(&die.lock);
212 bust_spinlocks(1); 212 bust_spinlocks(1);
213 printk(KERN_EMERG "Oops: %s[#%d]:\n", str, ++die.counter); 213 printk(KERN_EMERG "Oops: %s[#%d]:\n", str, ++die.counter);
214 214
215 if (notify_die(DIE_OOPS, str, regs, err, pt_cause(regs), SIGSEGV) == 215 if (notify_die(DIE_OOPS, str, regs, err, pt_cause(regs), SIGSEGV) ==
216 NOTIFY_STOP) 216 NOTIFY_STOP)
217 return 1; 217 return 1;
218 218
219 print_modules(); 219 print_modules();
220 show_regs(regs); 220 show_regs(regs);
221 do_show_stack(current, &regs->r30, pt_elr(regs)); 221 do_show_stack(current, &regs->r30, pt_elr(regs));
222 222
223 bust_spinlocks(0); 223 bust_spinlocks(0);
224 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); 224 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
225 225
226 spin_unlock_irq(&die.lock); 226 spin_unlock_irq(&die.lock);
227 227
228 if (in_interrupt()) 228 if (in_interrupt())
229 panic("Fatal exception in interrupt"); 229 panic("Fatal exception in interrupt");
230 230
231 if (panic_on_oops) 231 if (panic_on_oops)
232 panic("Fatal exception"); 232 panic("Fatal exception");
233 233
234 oops_exit(); 234 oops_exit();
235 do_exit(err); 235 do_exit(err);
236 return 0; 236 return 0;
237 } 237 }
238 238
239 int die_if_kernel(char *str, struct pt_regs *regs, long err) 239 int die_if_kernel(char *str, struct pt_regs *regs, long err)
240 { 240 {
241 if (!user_mode(regs)) 241 if (!user_mode(regs))
242 return die(str, regs, err); 242 return die(str, regs, err);
243 else 243 else
244 return 0; 244 return 0;
245 } 245 }
246 246
247 /* 247 /*
248 * It's not clear that misaligned fetches are ever recoverable. 248 * It's not clear that misaligned fetches are ever recoverable.
249 */ 249 */
250 static void misaligned_instruction(struct pt_regs *regs) 250 static void misaligned_instruction(struct pt_regs *regs)
251 { 251 {
252 die_if_kernel("Misaligned Instruction", regs, 0); 252 die_if_kernel("Misaligned Instruction", regs, 0);
253 force_sig(SIGBUS, current); 253 force_sig(SIGBUS, current);
254 } 254 }
255 255
256 /* 256 /*
257 * Misaligned loads and stores, on the other hand, can be 257 * Misaligned loads and stores, on the other hand, can be
258 * emulated, and probably should be, some day. But for now 258 * emulated, and probably should be, some day. But for now
259 * they will be considered fatal. 259 * they will be considered fatal.
260 */ 260 */
261 static void misaligned_data_load(struct pt_regs *regs) 261 static void misaligned_data_load(struct pt_regs *regs)
262 { 262 {
263 die_if_kernel("Misaligned Data Load", regs, 0); 263 die_if_kernel("Misaligned Data Load", regs, 0);
264 force_sig(SIGBUS, current); 264 force_sig(SIGBUS, current);
265 } 265 }
266 266
267 static void misaligned_data_store(struct pt_regs *regs) 267 static void misaligned_data_store(struct pt_regs *regs)
268 { 268 {
269 die_if_kernel("Misaligned Data Store", regs, 0); 269 die_if_kernel("Misaligned Data Store", regs, 0);
270 force_sig(SIGBUS, current); 270 force_sig(SIGBUS, current);
271 } 271 }
272 272
273 static void illegal_instruction(struct pt_regs *regs) 273 static void illegal_instruction(struct pt_regs *regs)
274 { 274 {
275 die_if_kernel("Illegal Instruction", regs, 0); 275 die_if_kernel("Illegal Instruction", regs, 0);
276 force_sig(SIGILL, current); 276 force_sig(SIGILL, current);
277 } 277 }
278 278
279 /* 279 /*
280 * Precise bus errors may be recoverable with a a retry, 280 * Precise bus errors may be recoverable with a a retry,
281 * but for now, treat them as irrecoverable. 281 * but for now, treat them as irrecoverable.
282 */ 282 */
283 static void precise_bus_error(struct pt_regs *regs) 283 static void precise_bus_error(struct pt_regs *regs)
284 { 284 {
285 die_if_kernel("Precise Bus Error", regs, 0); 285 die_if_kernel("Precise Bus Error", regs, 0);
286 force_sig(SIGBUS, current); 286 force_sig(SIGBUS, current);
287 } 287 }
288 288
289 /* 289 /*
290 * If anything is to be done here other than panic, 290 * If anything is to be done here other than panic,
291 * it will probably be complex and migrate to another 291 * it will probably be complex and migrate to another
292 * source module. For now, just die. 292 * source module. For now, just die.
293 */ 293 */
294 static void cache_error(struct pt_regs *regs) 294 static void cache_error(struct pt_regs *regs)
295 { 295 {
296 die("Cache Error", regs, 0); 296 die("Cache Error", regs, 0);
297 } 297 }
298 298
299 /* 299 /*
300 * General exception handler 300 * General exception handler
301 */ 301 */
302 void do_genex(struct pt_regs *regs) 302 void do_genex(struct pt_regs *regs)
303 { 303 {
304 /* 304 /*
305 * Decode Cause and Dispatch 305 * Decode Cause and Dispatch
306 */ 306 */
307 switch (pt_cause(regs)) { 307 switch (pt_cause(regs)) {
308 case HVM_GE_C_XPROT: 308 case HVM_GE_C_XPROT:
309 case HVM_GE_C_XUSER: 309 case HVM_GE_C_XUSER:
310 execute_protection_fault(regs); 310 execute_protection_fault(regs);
311 break; 311 break;
312 case HVM_GE_C_RPROT: 312 case HVM_GE_C_RPROT:
313 case HVM_GE_C_RUSER: 313 case HVM_GE_C_RUSER:
314 read_protection_fault(regs); 314 read_protection_fault(regs);
315 break; 315 break;
316 case HVM_GE_C_WPROT: 316 case HVM_GE_C_WPROT:
317 case HVM_GE_C_WUSER: 317 case HVM_GE_C_WUSER:
318 write_protection_fault(regs); 318 write_protection_fault(regs);
319 break; 319 break;
320 case HVM_GE_C_XMAL: 320 case HVM_GE_C_XMAL:
321 misaligned_instruction(regs); 321 misaligned_instruction(regs);
322 break; 322 break;
323 case HVM_GE_C_WREG: 323 case HVM_GE_C_WREG:
324 illegal_instruction(regs); 324 illegal_instruction(regs);
325 break; 325 break;
326 case HVM_GE_C_PCAL: 326 case HVM_GE_C_PCAL:
327 misaligned_instruction(regs); 327 misaligned_instruction(regs);
328 break; 328 break;
329 case HVM_GE_C_RMAL: 329 case HVM_GE_C_RMAL:
330 misaligned_data_load(regs); 330 misaligned_data_load(regs);
331 break; 331 break;
332 case HVM_GE_C_WMAL: 332 case HVM_GE_C_WMAL:
333 misaligned_data_store(regs); 333 misaligned_data_store(regs);
334 break; 334 break;
335 case HVM_GE_C_INVI: 335 case HVM_GE_C_INVI:
336 case HVM_GE_C_PRIVI: 336 case HVM_GE_C_PRIVI:
337 illegal_instruction(regs); 337 illegal_instruction(regs);
338 break; 338 break;
339 case HVM_GE_C_BUS: 339 case HVM_GE_C_BUS:
340 precise_bus_error(regs); 340 precise_bus_error(regs);
341 break; 341 break;
342 case HVM_GE_C_CACHE: 342 case HVM_GE_C_CACHE:
343 cache_error(regs); 343 cache_error(regs);
344 break; 344 break;
345 default: 345 default:
346 /* Halt and catch fire */ 346 /* Halt and catch fire */
347 panic("Unrecognized exception 0x%lx\n", pt_cause(regs)); 347 panic("Unrecognized exception 0x%lx\n", pt_cause(regs));
348 break; 348 break;
349 } 349 }
350 } 350 }
351 351
352 /* Indirect system call dispatch */ 352 /* Indirect system call dispatch */
353 long sys_syscall(void) 353 long sys_syscall(void)
354 { 354 {
355 printk(KERN_ERR "sys_syscall invoked!\n"); 355 printk(KERN_ERR "sys_syscall invoked!\n");
356 return -ENOSYS; 356 return -ENOSYS;
357 } 357 }
358 358
359 void do_trap0(struct pt_regs *regs) 359 void do_trap0(struct pt_regs *regs)
360 { 360 {
361 syscall_fn syscall; 361 syscall_fn syscall;
362 362
363 switch (pt_cause(regs)) { 363 switch (pt_cause(regs)) {
364 case TRAP_SYSCALL: 364 case TRAP_SYSCALL:
365 /* System call is trap0 #1 */ 365 /* System call is trap0 #1 */
366 366
367 /* allow strace to catch syscall args */ 367 /* allow strace to catch syscall args */
368 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE) && 368 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE) &&
369 tracehook_report_syscall_entry(regs))) 369 tracehook_report_syscall_entry(regs)))
370 return; /* return -ENOSYS somewhere? */ 370 return; /* return -ENOSYS somewhere? */
371 371
372 /* Interrupts should be re-enabled for syscall processing */ 372 /* Interrupts should be re-enabled for syscall processing */
373 __vmsetie(VM_INT_ENABLE); 373 __vmsetie(VM_INT_ENABLE);
374 374
375 /* 375 /*
376 * System call number is in r6, arguments in r0..r5. 376 * System call number is in r6, arguments in r0..r5.
377 * Fortunately, no Linux syscall has more than 6 arguments, 377 * Fortunately, no Linux syscall has more than 6 arguments,
378 * and Hexagon ABI passes first 6 arguments in registers. 378 * and Hexagon ABI passes first 6 arguments in registers.
379 * 64-bit arguments are passed in odd/even register pairs. 379 * 64-bit arguments are passed in odd/even register pairs.
380 * Fortunately, we have no system calls that take more 380 * Fortunately, we have no system calls that take more
381 * than three arguments with more than one 64-bit value. 381 * than three arguments with more than one 64-bit value.
382 * Should that change, we'd need to redesign to copy 382 * Should that change, we'd need to redesign to copy
383 * between user and kernel stacks. 383 * between user and kernel stacks.
384 */ 384 */
385 regs->syscall_nr = regs->r06; 385 regs->syscall_nr = regs->r06;
386 386
387 /* 387 /*
388 * GPR R0 carries the first parameter, and is also used 388 * GPR R0 carries the first parameter, and is also used
389 * to report the return value. We need a backup of 389 * to report the return value. We need a backup of
390 * the user's value in case we need to do a late restart 390 * the user's value in case we need to do a late restart
391 * of the system call. 391 * of the system call.
392 */ 392 */
393 regs->restart_r0 = regs->r00; 393 regs->restart_r0 = regs->r00;
394 394
395 if ((unsigned long) regs->syscall_nr >= __NR_syscalls) { 395 if ((unsigned long) regs->syscall_nr >= __NR_syscalls) {
396 regs->r00 = -1; 396 regs->r00 = -1;
397 } else { 397 } else {
398 syscall = (syscall_fn) 398 syscall = (syscall_fn)
399 (sys_call_table[regs->syscall_nr]); 399 (sys_call_table[regs->syscall_nr]);
400 regs->r00 = syscall(regs->r00, regs->r01, 400 regs->r00 = syscall(regs->r00, regs->r01,
401 regs->r02, regs->r03, 401 regs->r02, regs->r03,
402 regs->r04, regs->r05); 402 regs->r04, regs->r05);
403 } 403 }
404 404
405 /* allow strace to get the syscall return state */ 405 /* allow strace to get the syscall return state */
406 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE))) 406 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE)))
407 tracehook_report_syscall_exit(regs, 0); 407 tracehook_report_syscall_exit(regs, 0);
408 408
409 break; 409 break;
410 case TRAP_DEBUG: 410 case TRAP_DEBUG:
411 /* Trap0 0xdb is debug breakpoint */ 411 /* Trap0 0xdb is debug breakpoint */
412 if (user_mode(regs)) { 412 if (user_mode(regs)) {
413 struct siginfo info; 413 struct siginfo info;
414 414
415 info.si_signo = SIGTRAP; 415 info.si_signo = SIGTRAP;
416 info.si_errno = 0; 416 info.si_errno = 0;
417 /* 417 /*
418 * Some architecures add some per-thread state 418 * Some architecures add some per-thread state
419 * to distinguish between breakpoint traps and 419 * to distinguish between breakpoint traps and
420 * trace traps. We may want to do that, and 420 * trace traps. We may want to do that, and
421 * set the si_code value appropriately, or we 421 * set the si_code value appropriately, or we
422 * may want to use a different trap0 flavor. 422 * may want to use a different trap0 flavor.
423 */ 423 */
424 info.si_code = TRAP_BRKPT; 424 info.si_code = TRAP_BRKPT;
425 info.si_addr = (void __user *) pt_elr(regs); 425 info.si_addr = (void __user *) pt_elr(regs);
426 send_sig_info(SIGTRAP, &info, current); 426 force_sig_info(SIGTRAP, &info, current);
427 } else { 427 } else {
428 #ifdef CONFIG_KGDB 428 #ifdef CONFIG_KGDB
429 kgdb_handle_exception(pt_cause(regs), SIGTRAP, 429 kgdb_handle_exception(pt_cause(regs), SIGTRAP,
430 TRAP_BRKPT, regs); 430 TRAP_BRKPT, regs);
431 #endif 431 #endif
432 } 432 }
433 break; 433 break;
434 } 434 }
435 /* Ignore other trap0 codes for now, especially 0 (Angel calls) */ 435 /* Ignore other trap0 codes for now, especially 0 (Angel calls) */
436 } 436 }
437 437
438 /* 438 /*
439 * Machine check exception handler 439 * Machine check exception handler
440 */ 440 */
441 void do_machcheck(struct pt_regs *regs) 441 void do_machcheck(struct pt_regs *regs)
442 { 442 {
443 /* Halt and catch fire */ 443 /* Halt and catch fire */
444 __vmstop(); 444 __vmstop();
445 } 445 }
446 446
447 /* 447 /*
448 * Treat this like the old 0xdb trap. 448 * Treat this like the old 0xdb trap.
449 */ 449 */
450 450
451 void do_debug_exception(struct pt_regs *regs) 451 void do_debug_exception(struct pt_regs *regs)
452 { 452 {
453 regs->hvmer.vmest &= ~HVM_VMEST_CAUSE_MSK; 453 regs->hvmer.vmest &= ~HVM_VMEST_CAUSE_MSK;
454 regs->hvmer.vmest |= (TRAP_DEBUG << HVM_VMEST_CAUSE_SFT); 454 regs->hvmer.vmest |= (TRAP_DEBUG << HVM_VMEST_CAUSE_SFT);
455 do_trap0(regs); 455 do_trap0(regs);
456 } 456 }
457 457
arch/hexagon/kernel/vmlinux.lds.S
1 /* 1 /*
2 * Linker script for Hexagon kernel 2 * Linker script for Hexagon kernel
3 * 3 *
4 * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2010-2014, 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
8 * only version 2 as published by the Free Software Foundation. 8 * only version 2 as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 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 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA. 18 * 02110-1301, USA.
19 */ 19 */
20 20
21 #include <asm-generic/vmlinux.lds.h> 21 #include <asm-generic/vmlinux.lds.h>
22 #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 */
23 #include <asm/mem-layout.h> /* except for page_offset */ 23 #include <asm/mem-layout.h> /* except for page_offset */
24 #include <asm/cache.h> /* and now we're pulling cache line size */ 24 #include <asm/cache.h> /* and now we're pulling cache line size */
25 OUTPUT_ARCH(hexagon) 25 OUTPUT_ARCH(hexagon)
26 ENTRY(stext) 26 ENTRY(stext)
27 27
28 jiffies = jiffies_64; 28 jiffies = jiffies_64;
29 29
30 /* 30 /*
31 See asm-generic/vmlinux.lds.h for expansion of some of these macros. 31 See asm-generic/vmlinux.lds.h for expansion of some of these macros.
32 See asm-generic/sections.h for seemingly required labels. 32 See asm-generic/sections.h for seemingly required labels.
33 */ 33 */
34 34
35 #define PAGE_SIZE _PAGE_SIZE 35 #define PAGE_SIZE _PAGE_SIZE
36 36
37 SECTIONS 37 SECTIONS
38 { 38 {
39 . = PAGE_OFFSET; 39 . = PAGE_OFFSET;
40 40
41 __init_begin = .; 41 __init_begin = .;
42 HEAD_TEXT_SECTION 42 HEAD_TEXT_SECTION
43 INIT_TEXT_SECTION(PAGE_SIZE) 43 INIT_TEXT_SECTION(PAGE_SIZE)
44 PERCPU_SECTION(L1_CACHE_BYTES) 44 PERCPU_SECTION(L1_CACHE_BYTES)
45 __init_end = .; 45 __init_end = .;
46 46
47 . = ALIGN(_PAGE_SIZE); 47 . = ALIGN(_PAGE_SIZE);
48 _stext = .; 48 _stext = .;
49 .text : AT(ADDR(.text)) { 49 .text : AT(ADDR(.text)) {
50 _text = .; 50 _text = .;
51 TEXT_TEXT 51 TEXT_TEXT
52 SCHED_TEXT 52 SCHED_TEXT
53 LOCK_TEXT 53 LOCK_TEXT
54 KPROBES_TEXT 54 KPROBES_TEXT
55 *(.fixup) 55 *(.fixup)
56 } 56 }
57 _etext = .; 57 _etext = .;
58 58
59 INIT_DATA_SECTION(PAGE_SIZE) 59 INIT_DATA_SECTION(PAGE_SIZE)
60 60
61 _sdata = .; 61 _sdata = .;
62 RW_DATA_SECTION(32,PAGE_SIZE,PAGE_SIZE) 62 RW_DATA_SECTION(32,PAGE_SIZE,_THREAD_SIZE)
63 RO_DATA_SECTION(PAGE_SIZE) 63 RO_DATA_SECTION(PAGE_SIZE)
64 _edata = .; 64 _edata = .;
65 65
66 EXCEPTION_TABLE(16) 66 EXCEPTION_TABLE(16)
67 NOTES 67 NOTES
68 68
69 BSS_SECTION(_PAGE_SIZE, _PAGE_SIZE, _PAGE_SIZE) 69 BSS_SECTION(_PAGE_SIZE, _PAGE_SIZE, _PAGE_SIZE)
70 70
71 _end = .; 71 _end = .;
72 72
73 /DISCARD/ : { 73 /DISCARD/ : {
74 EXIT_TEXT 74 EXIT_TEXT
75 EXIT_DATA 75 EXIT_DATA
76 EXIT_CALL 76 EXIT_CALL
77 } 77 }
78 78
79 STABS_DEBUG 79 STABS_DEBUG
80 DWARF_DEBUG 80 DWARF_DEBUG
81 81
82 } 82 }
83 83
arch/hexagon/mm/cache.c
1 /* 1 /*
2 * Cache management functions for Hexagon 2 * Cache management functions for Hexagon
3 * 3 *
4 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2010-2011, 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
8 * only version 2 as published by the Free Software Foundation. 8 * only version 2 as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 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 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA. 18 * 02110-1301, USA.
19 */ 19 */
20 20
21 #include <linux/mm.h> 21 #include <linux/mm.h>
22 #include <asm/cacheflush.h> 22 #include <asm/cacheflush.h>
23 #include <asm/hexagon_vm.h> 23 #include <asm/hexagon_vm.h>
24 24
25 #define spanlines(start, end) \ 25 #define spanlines(start, end) \
26 (((end - (start & ~(LINESIZE - 1))) >> LINEBITS) + 1) 26 (((end - (start & ~(LINESIZE - 1))) >> LINEBITS) + 1)
27 27
28 void flush_dcache_range(unsigned long start, unsigned long end) 28 void flush_dcache_range(unsigned long start, unsigned long end)
29 { 29 {
30 unsigned long lines = spanlines(start, end-1); 30 unsigned long lines = spanlines(start, end-1);
31 unsigned long i, flags; 31 unsigned long i, flags;
32 32
33 start &= ~(LINESIZE - 1); 33 start &= ~(LINESIZE - 1);
34 34
35 local_irq_save(flags); 35 local_irq_save(flags);
36 36
37 for (i = 0; i < lines; i++) { 37 for (i = 0; i < lines; i++) {
38 __asm__ __volatile__ ( 38 __asm__ __volatile__ (
39 " dccleaninva(%0); " 39 " dccleaninva(%0); "
40 : 40 :
41 : "r" (start) 41 : "r" (start)
42 ); 42 );
43 start += LINESIZE; 43 start += LINESIZE;
44 } 44 }
45 local_irq_restore(flags); 45 local_irq_restore(flags);
46 } 46 }
47 47
48 void flush_icache_range(unsigned long start, unsigned long end) 48 void flush_icache_range(unsigned long start, unsigned long end)
49 { 49 {
50 unsigned long lines = spanlines(start, end-1); 50 unsigned long lines = spanlines(start, end-1);
51 unsigned long i, flags; 51 unsigned long i, flags;
52 52
53 start &= ~(LINESIZE - 1); 53 start &= ~(LINESIZE - 1);
54 54
55 local_irq_save(flags); 55 local_irq_save(flags);
56 56
57 for (i = 0; i < lines; i++) { 57 for (i = 0; i < lines; i++) {
58 __asm__ __volatile__ ( 58 __asm__ __volatile__ (
59 " dccleana(%0); " 59 " dccleana(%0); "
60 " icinva(%0); " 60 " icinva(%0); "
61 : 61 :
62 : "r" (start) 62 : "r" (start)
63 ); 63 );
64 start += LINESIZE; 64 start += LINESIZE;
65 } 65 }
66 __asm__ __volatile__ ( 66 __asm__ __volatile__ (
67 "isync" 67 "isync"
68 ); 68 );
69 local_irq_restore(flags); 69 local_irq_restore(flags);
70 } 70 }
71 EXPORT_SYMBOL(flush_icache_range); 71 EXPORT_SYMBOL(flush_icache_range);
72 72
73 void hexagon_clean_dcache_range(unsigned long start, unsigned long end) 73 void hexagon_clean_dcache_range(unsigned long start, unsigned long end)
74 { 74 {
75 unsigned long lines = spanlines(start, end-1); 75 unsigned long lines = spanlines(start, end-1);
76 unsigned long i, flags; 76 unsigned long i, flags;
77 77
78 start &= ~(LINESIZE - 1); 78 start &= ~(LINESIZE - 1);
79 79
80 local_irq_save(flags); 80 local_irq_save(flags);
81 81
82 for (i = 0; i < lines; i++) { 82 for (i = 0; i < lines; i++) {
83 __asm__ __volatile__ ( 83 __asm__ __volatile__ (
84 " dccleana(%0); " 84 " dccleana(%0); "
85 : 85 :
86 : "r" (start) 86 : "r" (start)
87 ); 87 );
88 start += LINESIZE; 88 start += LINESIZE;
89 } 89 }
90 local_irq_restore(flags); 90 local_irq_restore(flags);
91 } 91 }
92 92
93 void hexagon_inv_dcache_range(unsigned long start, unsigned long end) 93 void hexagon_inv_dcache_range(unsigned long start, unsigned long end)
94 { 94 {
95 unsigned long lines = spanlines(start, end-1); 95 unsigned long lines = spanlines(start, end-1);
96 unsigned long i, flags; 96 unsigned long i, flags;
97 97
98 start &= ~(LINESIZE - 1); 98 start &= ~(LINESIZE - 1);
99 99
100 local_irq_save(flags); 100 local_irq_save(flags);
101 101
102 for (i = 0; i < lines; i++) { 102 for (i = 0; i < lines; i++) {
103 __asm__ __volatile__ ( 103 __asm__ __volatile__ (
104 " dcinva(%0); " 104 " dcinva(%0); "
105 : 105 :
106 : "r" (start) 106 : "r" (start)
107 ); 107 );
108 start += LINESIZE; 108 start += LINESIZE;
109 } 109 }
110 local_irq_restore(flags); 110 local_irq_restore(flags);
111 } 111 }
112 112
113 113
114 114
115 115
116 /* 116 /*
117 * This is just really brutal and shouldn't be used anyways, 117 * This is just really brutal and shouldn't be used anyways,
118 * especially on V2. Left here just in case. 118 * especially on V2. Left here just in case.
119 */ 119 */
120 void flush_cache_all_hexagon(void) 120 void flush_cache_all_hexagon(void)
121 { 121 {
122 unsigned long flags; 122 unsigned long flags;
123 local_irq_save(flags); 123 local_irq_save(flags);
124 __vmcache_ickill(); 124 __vmcache_ickill();
125 __vmcache_dckill(); 125 __vmcache_dckill();
126 __vmcache_l2kill(); 126 __vmcache_l2kill();
127 local_irq_restore(flags); 127 local_irq_restore(flags);
128 mb(); 128 mb();
129 } 129 }
130
131 void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
132 unsigned long vaddr, void *dst, void *src, int len)
133 {
134 memcpy(dst, src, len);
135 if (vma->vm_flags & VM_EXEC) {
136 flush_icache_range((unsigned long) dst,
137 (unsigned long) dst + len);
138 }
139 }
130 140
arch/hexagon/mm/ioremap.c
1 /* 1 /*
2 * I/O remap functions for Hexagon 2 * I/O remap functions for Hexagon
3 * 3 *
4 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2010-2011, 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
8 * only version 2 as published by the Free Software Foundation. 8 * only version 2 as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 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 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA. 18 * 02110-1301, USA.
19 */ 19 */
20 20
21 #include <linux/io.h> 21 #include <linux/io.h>
22 #include <linux/vmalloc.h> 22 #include <linux/vmalloc.h>
23 #include <linux/mm.h>
23 24
24 void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size) 25 void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size)
25 { 26 {
26 unsigned long last_addr, addr; 27 unsigned long last_addr, addr;
27 unsigned long offset = phys_addr & ~PAGE_MASK; 28 unsigned long offset = phys_addr & ~PAGE_MASK;
28 struct vm_struct *area; 29 struct vm_struct *area;
29 30
30 pgprot_t prot = __pgprot(_PAGE_PRESENT|_PAGE_READ|_PAGE_WRITE 31 pgprot_t prot = __pgprot(_PAGE_PRESENT|_PAGE_READ|_PAGE_WRITE
31 |(__HEXAGON_C_DEV << 6)); 32 |(__HEXAGON_C_DEV << 6));
32 33
33 last_addr = phys_addr + size - 1; 34 last_addr = phys_addr + size - 1;
34 35
35 /* Wrapping not allowed */ 36 /* Wrapping not allowed */
36 if (!size || (last_addr < phys_addr)) 37 if (!size || (last_addr < phys_addr))
37 return NULL; 38 return NULL;
38 39
39 /* Rounds up to next page size, including whole-page offset */ 40 /* Rounds up to next page size, including whole-page offset */
40 size = PAGE_ALIGN(offset + size); 41 size = PAGE_ALIGN(offset + size);
41 42
42 area = get_vm_area(size, VM_IOREMAP); 43 area = get_vm_area(size, VM_IOREMAP);
43 addr = (unsigned long)area->addr; 44 addr = (unsigned long)area->addr;
44 45
45 if (ioremap_page_range(addr, addr+size, phys_addr, prot)) { 46 if (ioremap_page_range(addr, addr+size, phys_addr, prot)) {
46 vunmap((void *)addr); 47 vunmap((void *)addr);
47 return NULL; 48 return NULL;
48 } 49 }
49 50
50 return (void __iomem *) (offset + addr); 51 return (void __iomem *) (offset + addr);
51 } 52 }
52 53
53 void __iounmap(const volatile void __iomem *addr) 54 void __iounmap(const volatile void __iomem *addr)
54 { 55 {
55 vunmap((void *) ((unsigned long) addr & PAGE_MASK)); 56 vunmap((void *) ((unsigned long) addr & PAGE_MASK));
56 } 57 }
57 58