mirror of
				https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
				synced 2025-10-31 08:08:51 +01:00 
			
		
		
		
	Fixed MTP to work with TWRP
This commit is contained in:
		
						commit
						f6dfaef42e
					
				
					 50820 changed files with 20846062 additions and 0 deletions
				
			
		
							
								
								
									
										62
									
								
								arch/hexagon/include/asm/Kbuild
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								arch/hexagon/include/asm/Kbuild
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,62 @@ | |||
| 
 | ||||
| header-y += ucontext.h | ||||
| 
 | ||||
| generic-y += auxvec.h | ||||
| generic-y += barrier.h | ||||
| generic-y += bug.h | ||||
| generic-y += bugs.h | ||||
| generic-y += clkdev.h | ||||
| generic-y += cputime.h | ||||
| generic-y += current.h | ||||
| generic-y += device.h | ||||
| generic-y += div64.h | ||||
| generic-y += emergency-restart.h | ||||
| generic-y += errno.h | ||||
| generic-y += fb.h | ||||
| generic-y += fcntl.h | ||||
| generic-y += ftrace.h | ||||
| generic-y += hardirq.h | ||||
| generic-y += hash.h | ||||
| generic-y += hw_irq.h | ||||
| generic-y += ioctl.h | ||||
| generic-y += ioctls.h | ||||
| generic-y += iomap.h | ||||
| generic-y += ipcbuf.h | ||||
| generic-y += irq_regs.h | ||||
| generic-y += irq_work.h | ||||
| generic-y += kdebug.h | ||||
| generic-y += kmap_types.h | ||||
| generic-y += local.h | ||||
| generic-y += local64.h | ||||
| generic-y += mcs_spinlock.h | ||||
| generic-y += mman.h | ||||
| generic-y += msgbuf.h | ||||
| generic-y += pci.h | ||||
| generic-y += percpu.h | ||||
| generic-y += poll.h | ||||
| generic-y += posix_types.h | ||||
| generic-y += preempt.h | ||||
| generic-y += resource.h | ||||
| generic-y += rwsem.h | ||||
| generic-y += scatterlist.h | ||||
| generic-y += sections.h | ||||
| generic-y += segment.h | ||||
| generic-y += sembuf.h | ||||
| generic-y += serial.h | ||||
| generic-y += shmbuf.h | ||||
| generic-y += shmparam.h | ||||
| generic-y += siginfo.h | ||||
| generic-y += sizes.h | ||||
| generic-y += socket.h | ||||
| generic-y += sockios.h | ||||
| generic-y += stat.h | ||||
| generic-y += statfs.h | ||||
| generic-y += termbits.h | ||||
| generic-y += termios.h | ||||
| generic-y += topology.h | ||||
| generic-y += trace_clock.h | ||||
| generic-y += types.h | ||||
| generic-y += ucontext.h | ||||
| generic-y += unaligned.h | ||||
| generic-y += vga.h | ||||
| generic-y += xor.h | ||||
							
								
								
									
										1
									
								
								arch/hexagon/include/asm/asm-offsets.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								arch/hexagon/include/asm/asm-offsets.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| #include <generated/asm-offsets.h> | ||||
							
								
								
									
										186
									
								
								arch/hexagon/include/asm/atomic.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								arch/hexagon/include/asm/atomic.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,186 @@ | |||
| /*
 | ||||
|  * Atomic operations for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_ATOMIC_H | ||||
| #define _ASM_ATOMIC_H | ||||
| 
 | ||||
| #include <linux/types.h> | ||||
| #include <asm/cmpxchg.h> | ||||
| #include <asm/barrier.h> | ||||
| 
 | ||||
| #define ATOMIC_INIT(i)		{ (i) } | ||||
| 
 | ||||
| /*  Normal writes in our arch don't clear lock reservations  */ | ||||
| 
 | ||||
| static inline void atomic_set(atomic_t *v, int new) | ||||
| { | ||||
| 	asm volatile( | ||||
| 		"1:	r6 = memw_locked(%0);\n" | ||||
| 		"	memw_locked(%0,p0) = %1;\n" | ||||
| 		"	if (!P0) jump 1b;\n" | ||||
| 		: | ||||
| 		: "r" (&v->counter), "r" (new) | ||||
| 		: "memory", "p0", "r6" | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * atomic_read - reads a word, atomically | ||||
|  * @v: pointer to atomic value | ||||
|  * | ||||
|  * Assumes all word reads on our architecture are atomic. | ||||
|  */ | ||||
| #define atomic_read(v)		((v)->counter) | ||||
| 
 | ||||
| /**
 | ||||
|  * atomic_xchg - atomic | ||||
|  * @v: pointer to memory to change | ||||
|  * @new: new value (technically passed in a register -- see xchg) | ||||
|  */ | ||||
| #define atomic_xchg(v, new)	(xchg(&((v)->counter), (new))) | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * atomic_cmpxchg - atomic compare-and-exchange values | ||||
|  * @v: pointer to value to change | ||||
|  * @old:  desired old value to match | ||||
|  * @new:  new value to put in | ||||
|  * | ||||
|  * Parameters are then pointer, value-in-register, value-in-register, | ||||
|  * and the output is the old value. | ||||
|  * | ||||
|  * Apparently this is complicated for archs that don't support | ||||
|  * the memw_locked like we do (or it's broken or whatever). | ||||
|  * | ||||
|  * Kind of the lynchpin of the rest of the generically defined routines. | ||||
|  * Remember V2 had that bug with dotnew predicate set by memw_locked. | ||||
|  * | ||||
|  * "old" is "expected" old val, __oldval is actual old value | ||||
|  */ | ||||
| static inline int atomic_cmpxchg(atomic_t *v, int old, int new) | ||||
| { | ||||
| 	int __oldval; | ||||
| 
 | ||||
| 	asm volatile( | ||||
| 		"1:	%0 = memw_locked(%1);\n" | ||||
| 		"	{ P0 = cmp.eq(%0,%2);\n" | ||||
| 		"	  if (!P0.new) jump:nt 2f; }\n" | ||||
| 		"	memw_locked(%1,P0) = %3;\n" | ||||
| 		"	if (!P0) jump 1b;\n" | ||||
| 		"2:\n" | ||||
| 		: "=&r" (__oldval) | ||||
| 		: "r" (&v->counter), "r" (old), "r" (new) | ||||
| 		: "memory", "p0" | ||||
| 	); | ||||
| 
 | ||||
| 	return __oldval; | ||||
| } | ||||
| 
 | ||||
| #define ATOMIC_OP(op)							\ | ||||
| static inline void atomic_##op(int i, atomic_t *v)			\ | ||||
| {									\ | ||||
| 	int output;							\ | ||||
| 									\ | ||||
| 	__asm__ __volatile__ (						\ | ||||
| 		"1:	%0 = memw_locked(%1);\n"			\ | ||||
| 		"	%0 = "#op "(%0,%2);\n"				\ | ||||
| 		"	memw_locked(%1,P3)=%0;\n"			\ | ||||
| 		"	if !P3 jump 1b;\n"				\ | ||||
| 		: "=&r" (output)					\ | ||||
| 		: "r" (&v->counter), "r" (i)				\ | ||||
| 		: "memory", "p3"					\ | ||||
| 	);								\ | ||||
| }									\ | ||||
| 
 | ||||
| #define ATOMIC_OP_RETURN(op)							\ | ||||
| static inline int atomic_##op##_return(int i, atomic_t *v)		\ | ||||
| {									\ | ||||
| 	int output;							\ | ||||
| 									\ | ||||
| 	__asm__ __volatile__ (						\ | ||||
| 		"1:	%0 = memw_locked(%1);\n"			\ | ||||
| 		"	%0 = "#op "(%0,%2);\n"				\ | ||||
| 		"	memw_locked(%1,P3)=%0;\n"			\ | ||||
| 		"	if !P3 jump 1b;\n"				\ | ||||
| 		: "=&r" (output)					\ | ||||
| 		: "r" (&v->counter), "r" (i)				\ | ||||
| 		: "memory", "p3"					\ | ||||
| 	);								\ | ||||
| 	return output;							\ | ||||
| } | ||||
| 
 | ||||
| #define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) | ||||
| 
 | ||||
| ATOMIC_OPS(add) | ||||
| ATOMIC_OPS(sub) | ||||
| 
 | ||||
| #undef ATOMIC_OPS | ||||
| #undef ATOMIC_OP_RETURN | ||||
| #undef ATOMIC_OP | ||||
| 
 | ||||
| /**
 | ||||
|  * __atomic_add_unless - add unless the number is a given value | ||||
|  * @v: pointer to value | ||||
|  * @a: amount to add | ||||
|  * @u: unless value is equal to u | ||||
|  * | ||||
|  * Returns old value. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| static inline int __atomic_add_unless(atomic_t *v, int a, int u) | ||||
| { | ||||
| 	int __oldval; | ||||
| 	register int tmp; | ||||
| 
 | ||||
| 	asm volatile( | ||||
| 		"1:	%0 = memw_locked(%2);" | ||||
| 		"	{" | ||||
| 		"		p3 = cmp.eq(%0, %4);" | ||||
| 		"		if (p3.new) jump:nt 2f;" | ||||
| 		"		%1 = add(%0, %3);" | ||||
| 		"	}" | ||||
| 		"	memw_locked(%2, p3) = %1;" | ||||
| 		"	{" | ||||
| 		"		if !p3 jump 1b;" | ||||
| 		"	}" | ||||
| 		"2:" | ||||
| 		: "=&r" (__oldval), "=&r" (tmp) | ||||
| 		: "r" (v), "r" (a), "r" (u) | ||||
| 		: "memory", "p3" | ||||
| 	); | ||||
| 	return __oldval; | ||||
| } | ||||
| 
 | ||||
| #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | ||||
| 
 | ||||
| #define atomic_inc(v) atomic_add(1, (v)) | ||||
| #define atomic_dec(v) atomic_sub(1, (v)) | ||||
| 
 | ||||
| #define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) | ||||
| #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) | ||||
| #define atomic_sub_and_test(i, v) (atomic_sub_return(i, (v)) == 0) | ||||
| #define atomic_add_negative(i, v) (atomic_add_return(i, (v)) < 0) | ||||
| 
 | ||||
| #define atomic_inc_return(v) (atomic_add_return(1, v)) | ||||
| #define atomic_dec_return(v) (atomic_sub_return(1, v)) | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										298
									
								
								arch/hexagon/include/asm/bitops.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										298
									
								
								arch/hexagon/include/asm/bitops.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,298 @@ | |||
| /*
 | ||||
|  * Bit operations for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_BITOPS_H | ||||
| #define _ASM_BITOPS_H | ||||
| 
 | ||||
| #include <linux/compiler.h> | ||||
| #include <asm/byteorder.h> | ||||
| #include <asm/atomic.h> | ||||
| #include <asm/barrier.h> | ||||
| 
 | ||||
| #ifdef __KERNEL__ | ||||
| 
 | ||||
| /*
 | ||||
|  * The offset calculations for these are based on BITS_PER_LONG == 32 | ||||
|  * (i.e. I get to shift by #5-2 (32 bits per long, 4 bytes per access), | ||||
|  * mask by 0x0000001F) | ||||
|  * | ||||
|  * Typically, R10 is clobbered for address, R11 bit nr, and R12 is temp | ||||
|  */ | ||||
| 
 | ||||
| /**
 | ||||
|  * test_and_clear_bit - clear a bit and return its old value | ||||
|  * @nr:  bit number to clear | ||||
|  * @addr:  pointer to memory | ||||
|  */ | ||||
| static inline int test_and_clear_bit(int nr, volatile void *addr) | ||||
| { | ||||
| 	int oldval; | ||||
| 
 | ||||
| 	__asm__ __volatile__ ( | ||||
| 	"	{R10 = %1; R11 = asr(%2,#5); }\n" | ||||
| 	"	{R10 += asl(R11,#2); R11 = and(%2,#0x1f)}\n" | ||||
| 	"1:	R12 = memw_locked(R10);\n" | ||||
| 	"	{ P0 = tstbit(R12,R11); R12 = clrbit(R12,R11); }\n" | ||||
| 	"	memw_locked(R10,P1) = R12;\n" | ||||
| 	"	{if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n" | ||||
| 	: "=&r" (oldval) | ||||
| 	: "r" (addr), "r" (nr) | ||||
| 	: "r10", "r11", "r12", "p0", "p1", "memory" | ||||
| 	); | ||||
| 
 | ||||
| 	return oldval; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * test_and_set_bit - set a bit and return its old value | ||||
|  * @nr:  bit number to set | ||||
|  * @addr:  pointer to memory | ||||
|  */ | ||||
| static inline int test_and_set_bit(int nr, volatile void *addr) | ||||
| { | ||||
| 	int oldval; | ||||
| 
 | ||||
| 	__asm__ __volatile__ ( | ||||
| 	"	{R10 = %1; R11 = asr(%2,#5); }\n" | ||||
| 	"	{R10 += asl(R11,#2); R11 = and(%2,#0x1f)}\n" | ||||
| 	"1:	R12 = memw_locked(R10);\n" | ||||
| 	"	{ P0 = tstbit(R12,R11); R12 = setbit(R12,R11); }\n" | ||||
| 	"	memw_locked(R10,P1) = R12;\n" | ||||
| 	"	{if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n" | ||||
| 	: "=&r" (oldval) | ||||
| 	: "r" (addr), "r" (nr) | ||||
| 	: "r10", "r11", "r12", "p0", "p1", "memory" | ||||
| 	); | ||||
| 
 | ||||
| 
 | ||||
| 	return oldval; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * test_and_change_bit - toggle a bit and return its old value | ||||
|  * @nr:  bit number to set | ||||
|  * @addr:  pointer to memory | ||||
|  */ | ||||
| static inline int test_and_change_bit(int nr, volatile void *addr) | ||||
| { | ||||
| 	int oldval; | ||||
| 
 | ||||
| 	__asm__ __volatile__ ( | ||||
| 	"	{R10 = %1; R11 = asr(%2,#5); }\n" | ||||
| 	"	{R10 += asl(R11,#2); R11 = and(%2,#0x1f)}\n" | ||||
| 	"1:	R12 = memw_locked(R10);\n" | ||||
| 	"	{ P0 = tstbit(R12,R11); R12 = togglebit(R12,R11); }\n" | ||||
| 	"	memw_locked(R10,P1) = R12;\n" | ||||
| 	"	{if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n" | ||||
| 	: "=&r" (oldval) | ||||
| 	: "r" (addr), "r" (nr) | ||||
| 	: "r10", "r11", "r12", "p0", "p1", "memory" | ||||
| 	); | ||||
| 
 | ||||
| 	return oldval; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Atomic, but doesn't care about the return value. | ||||
|  * Rewrite later to save a cycle or two. | ||||
|  */ | ||||
| 
 | ||||
| static inline void clear_bit(int nr, volatile void *addr) | ||||
| { | ||||
| 	test_and_clear_bit(nr, addr); | ||||
| } | ||||
| 
 | ||||
| static inline void set_bit(int nr, volatile void *addr) | ||||
| { | ||||
| 	test_and_set_bit(nr, addr); | ||||
| } | ||||
| 
 | ||||
| static inline void change_bit(int nr, volatile void *addr) | ||||
| { | ||||
| 	test_and_change_bit(nr, addr); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * These are allowed to be non-atomic.  In fact the generic flavors are | ||||
|  * in non-atomic.h.  Would it be better to use intrinsics for this? | ||||
|  * | ||||
|  * OK, writes in our architecture do not invalidate LL/SC, so this has to | ||||
|  * be atomic, particularly for things like slab_lock and slab_unlock. | ||||
|  * | ||||
|  */ | ||||
| static inline void __clear_bit(int nr, volatile unsigned long *addr) | ||||
| { | ||||
| 	test_and_clear_bit(nr, addr); | ||||
| } | ||||
| 
 | ||||
| static inline void __set_bit(int nr, volatile unsigned long *addr) | ||||
| { | ||||
| 	test_and_set_bit(nr, addr); | ||||
| } | ||||
| 
 | ||||
| static inline void __change_bit(int nr, volatile unsigned long *addr) | ||||
| { | ||||
| 	test_and_change_bit(nr, addr); | ||||
| } | ||||
| 
 | ||||
| /*  Apparently, at least some of these are allowed to be non-atomic  */ | ||||
| static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr) | ||||
| { | ||||
| 	return test_and_clear_bit(nr, addr); | ||||
| } | ||||
| 
 | ||||
| static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) | ||||
| { | ||||
| 	return test_and_set_bit(nr, addr); | ||||
| } | ||||
| 
 | ||||
| static inline int __test_and_change_bit(int nr, volatile unsigned long *addr) | ||||
| { | ||||
| 	return test_and_change_bit(nr, addr); | ||||
| } | ||||
| 
 | ||||
| static inline int __test_bit(int nr, const volatile unsigned long *addr) | ||||
| { | ||||
| 	int retval; | ||||
| 
 | ||||
| 	asm volatile( | ||||
| 	"{P0 = tstbit(%1,%2); if (P0.new) %0 = #1; if (!P0.new) %0 = #0;}\n" | ||||
| 	: "=&r" (retval) | ||||
| 	: "r" (addr[BIT_WORD(nr)]), "r" (nr % BITS_PER_LONG) | ||||
| 	: "p0" | ||||
| 	); | ||||
| 
 | ||||
| 	return retval; | ||||
| } | ||||
| 
 | ||||
| #define test_bit(nr, addr) __test_bit(nr, addr) | ||||
| 
 | ||||
| /*
 | ||||
|  * ffz - find first zero in word. | ||||
|  * @word: The word to search | ||||
|  * | ||||
|  * Undefined if no zero exists, so code should check against ~0UL first. | ||||
|  */ | ||||
| static inline long ffz(int x) | ||||
| { | ||||
| 	int r; | ||||
| 
 | ||||
| 	asm("%0 = ct1(%1);\n" | ||||
| 		: "=&r" (r) | ||||
| 		: "r" (x)); | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * fls - find last (most-significant) bit set | ||||
|  * @x: the word to search | ||||
|  * | ||||
|  * This is defined the same way as ffs. | ||||
|  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. | ||||
|  */ | ||||
| static inline long fls(int x) | ||||
| { | ||||
| 	int r; | ||||
| 
 | ||||
| 	asm("{ %0 = cl0(%1);}\n" | ||||
| 		"%0 = sub(#32,%0);\n" | ||||
| 		: "=&r" (r) | ||||
| 		: "r" (x) | ||||
| 		: "p0"); | ||||
| 
 | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * ffs - find first bit set | ||||
|  * @x: the word to search | ||||
|  * | ||||
|  * This is defined the same way as | ||||
|  * the libc and compiler builtin ffs routines, therefore | ||||
|  * differs in spirit from the above ffz (man ffs). | ||||
|  */ | ||||
| static inline long ffs(int x) | ||||
| { | ||||
| 	int r; | ||||
| 
 | ||||
| 	asm("{ P0 = cmp.eq(%1,#0); %0 = ct0(%1);}\n" | ||||
| 		"{ if P0 %0 = #0; if !P0 %0 = add(%0,#1);}\n" | ||||
| 		: "=&r" (r) | ||||
| 		: "r" (x) | ||||
| 		: "p0"); | ||||
| 
 | ||||
| 	return r; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * __ffs - find first bit in word. | ||||
|  * @word: The word to search | ||||
|  * | ||||
|  * Undefined if no bit exists, so code should check against 0 first. | ||||
|  * | ||||
|  * bits_per_long assumed to be 32 | ||||
|  * numbering starts at 0 I think (instead of 1 like ffs) | ||||
|  */ | ||||
| static inline unsigned long __ffs(unsigned long word) | ||||
| { | ||||
| 	int num; | ||||
| 
 | ||||
| 	asm("%0 = ct0(%1);\n" | ||||
| 		: "=&r" (num) | ||||
| 		: "r" (word)); | ||||
| 
 | ||||
| 	return num; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * __fls - find last (most-significant) set bit in a long word | ||||
|  * @word: the word to search | ||||
|  * | ||||
|  * Undefined if no set bit exists, so code should check against 0 first. | ||||
|  * bits_per_long assumed to be 32 | ||||
|  */ | ||||
| static inline unsigned long __fls(unsigned long word) | ||||
| { | ||||
| 	int num; | ||||
| 
 | ||||
| 	asm("%0 = cl0(%1);\n" | ||||
| 		"%0 = sub(#31,%0);\n" | ||||
| 		: "=&r" (num) | ||||
| 		: "r" (word)); | ||||
| 
 | ||||
| 	return num; | ||||
| } | ||||
| 
 | ||||
| #include <asm-generic/bitops/lock.h> | ||||
| #include <asm-generic/bitops/find.h> | ||||
| 
 | ||||
| #include <asm-generic/bitops/fls64.h> | ||||
| #include <asm-generic/bitops/sched.h> | ||||
| #include <asm-generic/bitops/hweight.h> | ||||
| 
 | ||||
| #include <asm-generic/bitops/le.h> | ||||
| #include <asm-generic/bitops/ext2-atomic.h> | ||||
| 
 | ||||
| #endif /* __KERNEL__ */ | ||||
| #endif | ||||
							
								
								
									
										34
									
								
								arch/hexagon/include/asm/cache.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								arch/hexagon/include/asm/cache.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| /*
 | ||||
|  * Cache definitions for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __ASM_CACHE_H | ||||
| #define __ASM_CACHE_H | ||||
| 
 | ||||
| /* Bytes per L1 cache line */ | ||||
| #define L1_CACHE_SHIFT		(5) | ||||
| #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT) | ||||
| 
 | ||||
| #define __cacheline_aligned	__aligned(L1_CACHE_BYTES) | ||||
| #define ____cacheline_aligned	__aligned(L1_CACHE_BYTES) | ||||
| 
 | ||||
| /* See http://lwn.net/Articles/262554/ */ | ||||
| #define __read_mostly | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										99
									
								
								arch/hexagon/include/asm/cacheflush.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								arch/hexagon/include/asm/cacheflush.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,99 @@ | |||
| /*
 | ||||
|  * Cache flush operations for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_CACHEFLUSH_H | ||||
| #define _ASM_CACHEFLUSH_H | ||||
| 
 | ||||
| #include <linux/cache.h> | ||||
| #include <linux/mm.h> | ||||
| #include <asm/string.h> | ||||
| #include <asm-generic/cacheflush.h> | ||||
| 
 | ||||
| /* Cache flushing:
 | ||||
|  * | ||||
|  *  - flush_cache_all() flushes entire cache | ||||
|  *  - flush_cache_mm(mm) flushes the specified mm context's cache lines | ||||
|  *  - flush_cache_page(mm, vmaddr, pfn) flushes a single page | ||||
|  *  - flush_cache_range(vma, start, end) flushes a range of pages | ||||
|  *  - flush_icache_range(start, end) flush a range of instructions | ||||
|  *  - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache | ||||
|  *  - flush_icache_page(vma, pg) flushes(invalidates) a page for icache | ||||
|  * | ||||
|  *  Need to doublecheck which one is really needed for ptrace stuff to work. | ||||
|  */ | ||||
| #define LINESIZE	32 | ||||
| #define LINEBITS	5 | ||||
| 
 | ||||
| /*
 | ||||
|  * Flush Dcache range through current map. | ||||
|  */ | ||||
| extern void flush_dcache_range(unsigned long start, unsigned long end); | ||||
| 
 | ||||
| /*
 | ||||
|  * Flush Icache range through current map. | ||||
|  */ | ||||
| #undef flush_icache_range | ||||
| extern void flush_icache_range(unsigned long start, unsigned long end); | ||||
| 
 | ||||
| /*
 | ||||
|  * Memory-management related flushes are there to ensure in non-physically | ||||
|  * indexed cache schemes that stale lines belonging to a given ASID aren't | ||||
|  * in the cache to confuse things.  The prototype Hexagon Virtual Machine | ||||
|  * only uses a single ASID for all user-mode maps, which should | ||||
|  * mean that they aren't necessary.  A brute-force, flush-everything | ||||
|  * implementation, with the name xxxxx_hexagon() is present in | ||||
|  * arch/hexagon/mm/cache.c, but let's not wire it up until we know | ||||
|  * it is needed. | ||||
|  */ | ||||
| extern void flush_cache_all_hexagon(void); | ||||
| 
 | ||||
| /*
 | ||||
|  * This may or may not ever have to be non-null, depending on the | ||||
|  * virtual machine MMU.  For a native kernel, it's definitiely  a no-op | ||||
|  * | ||||
|  * This is also the place where deferred cache coherency stuff seems | ||||
|  * to happen, classically...  but instead we do it like ia64 and | ||||
|  * clean the cache when the PTE is set. | ||||
|  * | ||||
|  */ | ||||
| static inline void update_mmu_cache(struct vm_area_struct *vma, | ||||
| 					unsigned long address, pte_t *ptep) | ||||
| { | ||||
| 	/*  generic_ptrace_pokedata doesn't wind up here, does it?  */ | ||||
| } | ||||
| 
 | ||||
| #undef copy_to_user_page | ||||
| static inline void copy_to_user_page(struct vm_area_struct *vma, | ||||
| 					     struct page *page, | ||||
| 					     unsigned long vaddr, | ||||
| 					     void *dst, void *src, int len) | ||||
| { | ||||
| 	memcpy(dst, src, len); | ||||
| 	if (vma->vm_flags & VM_EXEC) { | ||||
| 		flush_icache_range((unsigned long) dst, | ||||
| 		(unsigned long) dst + len); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| extern void hexagon_inv_dcache_range(unsigned long start, unsigned long end); | ||||
| extern void hexagon_clean_dcache_range(unsigned long start, unsigned long end); | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										50
									
								
								arch/hexagon/include/asm/checksum.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								arch/hexagon/include/asm/checksum.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,50 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_CHECKSUM_H | ||||
| #define _ASM_CHECKSUM_H | ||||
| 
 | ||||
| #define do_csum	do_csum | ||||
| unsigned int do_csum(const void *voidptr, int len); | ||||
| 
 | ||||
| /*
 | ||||
|  * the same as csum_partial, but copies from src while it | ||||
|  * checksums | ||||
|  * | ||||
|  * here even more important to align src and dst on a 32-bit (or even | ||||
|  * better 64-bit) boundary | ||||
|  */ | ||||
| #define csum_partial_copy_nocheck csum_partial_copy_nocheck | ||||
| __wsum csum_partial_copy_nocheck(const void *src, void *dst, | ||||
| 					int len, __wsum sum); | ||||
| 
 | ||||
| /*
 | ||||
|  * computes the checksum of the TCP/UDP pseudo-header | ||||
|  * returns a 16-bit checksum, already complemented | ||||
|  */ | ||||
| #define csum_tcpudp_nofold csum_tcpudp_nofold | ||||
| __wsum csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, | ||||
| 	unsigned short len, unsigned short proto, __wsum sum); | ||||
| 
 | ||||
| #define csum_tcpudp_magic csum_tcpudp_magic | ||||
| __sum16 csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, | ||||
| 	unsigned short len, unsigned short proto, __wsum sum); | ||||
| 
 | ||||
| #include <asm-generic/checksum.h> | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										90
									
								
								arch/hexagon/include/asm/cmpxchg.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								arch/hexagon/include/asm/cmpxchg.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,90 @@ | |||
| /*
 | ||||
|  * xchg/cmpxchg operations for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_CMPXCHG_H | ||||
| #define _ASM_CMPXCHG_H | ||||
| 
 | ||||
| /*
 | ||||
|  * __xchg - atomically exchange a register and a memory location | ||||
|  * @x: value to swap | ||||
|  * @ptr: pointer to memory | ||||
|  * @size:  size of the value | ||||
|  * | ||||
|  * Only 4 bytes supported currently. | ||||
|  * | ||||
|  * Note:  there was an errata for V2 about .new's and memw_locked. | ||||
|  * | ||||
|  */ | ||||
| static inline unsigned long __xchg(unsigned long x, volatile void *ptr, | ||||
| 				   int size) | ||||
| { | ||||
| 	unsigned long retval; | ||||
| 
 | ||||
| 	/*  Can't seem to use printk or panic here, so just stop  */ | ||||
| 	if (size != 4) do { asm volatile("brkpt;\n"); } while (1); | ||||
| 
 | ||||
| 	__asm__ __volatile__ ( | ||||
| 	"1:	%0 = memw_locked(%1);\n"    /*  load into retval */ | ||||
| 	"	memw_locked(%1,P0) = %2;\n" /*  store into memory */ | ||||
| 	"	if !P0 jump 1b;\n" | ||||
| 	: "=&r" (retval) | ||||
| 	: "r" (ptr), "r" (x) | ||||
| 	: "memory", "p0" | ||||
| 	); | ||||
| 	return retval; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Atomically swap the contents of a register with memory.  Should be atomic | ||||
|  * between multiple CPU's and within interrupts on the same CPU. | ||||
|  */ | ||||
| #define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), (ptr), \ | ||||
| 	sizeof(*(ptr)))) | ||||
| 
 | ||||
| /*
 | ||||
|  *  see rt-mutex-design.txt; cmpxchg supposedly checks if *ptr == A and swaps. | ||||
|  *  looks just like atomic_cmpxchg on our arch currently with a bunch of | ||||
|  *  variable casting. | ||||
|  */ | ||||
| #define __HAVE_ARCH_CMPXCHG 1 | ||||
| 
 | ||||
| #define cmpxchg(ptr, old, new)					\ | ||||
| ({								\ | ||||
| 	__typeof__(ptr) __ptr = (ptr);				\ | ||||
| 	__typeof__(*(ptr)) __old = (old);			\ | ||||
| 	__typeof__(*(ptr)) __new = (new);			\ | ||||
| 	__typeof__(*(ptr)) __oldval = 0;			\ | ||||
| 								\ | ||||
| 	asm volatile(						\ | ||||
| 		"1:	%0 = memw_locked(%1);\n"		\ | ||||
| 		"	{ P0 = cmp.eq(%0,%2);\n"		\ | ||||
| 		"	  if (!P0.new) jump:nt 2f; }\n"		\ | ||||
| 		"	memw_locked(%1,p0) = %3;\n"		\ | ||||
| 		"	if (!P0) jump 1b;\n"			\ | ||||
| 		"2:\n"						\ | ||||
| 		: "=&r" (__oldval)				\ | ||||
| 		: "r" (__ptr), "r" (__old), "r" (__new)		\ | ||||
| 		: "memory", "p0"				\ | ||||
| 	);							\ | ||||
| 	__oldval;						\ | ||||
| }) | ||||
| 
 | ||||
| #endif /* _ASM_CMPXCHG_H */ | ||||
							
								
								
									
										29
									
								
								arch/hexagon/include/asm/delay.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								arch/hexagon/include/asm/delay.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_DELAY_H | ||||
| #define _ASM_DELAY_H | ||||
| 
 | ||||
| #include <asm/param.h> | ||||
| 
 | ||||
| extern void __delay(unsigned long cycles); | ||||
| extern void __udelay(unsigned long usecs); | ||||
| 
 | ||||
| #define udelay(usecs) __udelay((usecs)) | ||||
| 
 | ||||
| #endif /* _ASM_DELAY_H */ | ||||
							
								
								
									
										106
									
								
								arch/hexagon/include/asm/dma-mapping.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								arch/hexagon/include/asm/dma-mapping.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,106 @@ | |||
| /*
 | ||||
|  * DMA operations for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_DMA_MAPPING_H | ||||
| #define _ASM_DMA_MAPPING_H | ||||
| 
 | ||||
| #include <linux/types.h> | ||||
| #include <linux/cache.h> | ||||
| #include <linux/mm.h> | ||||
| #include <linux/scatterlist.h> | ||||
| #include <linux/dma-debug.h> | ||||
| #include <linux/dma-attrs.h> | ||||
| #include <asm/io.h> | ||||
| 
 | ||||
| struct device; | ||||
| extern int bad_dma_address; | ||||
| 
 | ||||
| extern struct dma_map_ops *dma_ops; | ||||
| 
 | ||||
| #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | ||||
| #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | ||||
| 
 | ||||
| static inline struct dma_map_ops *get_dma_ops(struct device *dev) | ||||
| { | ||||
| 	if (unlikely(dev == NULL)) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	return dma_ops; | ||||
| } | ||||
| 
 | ||||
| extern int dma_supported(struct device *dev, u64 mask); | ||||
| extern int dma_set_mask(struct device *dev, u64 mask); | ||||
| extern int dma_is_consistent(struct device *dev, dma_addr_t dma_handle); | ||||
| extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, | ||||
| 			   enum dma_data_direction direction); | ||||
| 
 | ||||
| #include <asm-generic/dma-mapping-common.h> | ||||
| 
 | ||||
| static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) | ||||
| { | ||||
| 	if (!dev->dma_mask) | ||||
| 		return 0; | ||||
| 	return addr + size - 1 <= *dev->dma_mask; | ||||
| } | ||||
| 
 | ||||
| static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | ||||
| { | ||||
| 	struct dma_map_ops *dma_ops = get_dma_ops(dev); | ||||
| 
 | ||||
| 	if (dma_ops->mapping_error) | ||||
| 		return dma_ops->mapping_error(dev, dma_addr); | ||||
| 
 | ||||
| 	return (dma_addr == bad_dma_address); | ||||
| } | ||||
| 
 | ||||
| #define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL) | ||||
| 
 | ||||
| static inline void *dma_alloc_attrs(struct device *dev, size_t size, | ||||
| 				    dma_addr_t *dma_handle, gfp_t flag, | ||||
| 				    struct dma_attrs *attrs) | ||||
| { | ||||
| 	void *ret; | ||||
| 	struct dma_map_ops *ops = get_dma_ops(dev); | ||||
| 
 | ||||
| 	BUG_ON(!dma_ops); | ||||
| 
 | ||||
| 	ret = ops->alloc(dev, size, dma_handle, flag, attrs); | ||||
| 
 | ||||
| 	debug_dma_alloc_coherent(dev, size, *dma_handle, ret); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| #define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) | ||||
| 
 | ||||
| static inline void dma_free_attrs(struct device *dev, size_t size, | ||||
| 				  void *cpu_addr, dma_addr_t dma_handle, | ||||
| 				  struct dma_attrs *attrs) | ||||
| { | ||||
| 	struct dma_map_ops *dma_ops = get_dma_ops(dev); | ||||
| 
 | ||||
| 	BUG_ON(!dma_ops); | ||||
| 
 | ||||
| 	dma_ops->free(dev, size, cpu_addr, dma_handle, attrs); | ||||
| 
 | ||||
| 	debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										29
									
								
								arch/hexagon/include/asm/dma.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								arch/hexagon/include/asm/dma.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_DMA_H | ||||
| #define _ASM_DMA_H | ||||
| 
 | ||||
| #include <asm/io.h> | ||||
| 
 | ||||
| #define MAX_DMA_CHANNELS 1 | ||||
| #define MAX_DMA_ADDRESS  (PAGE_OFFSET) | ||||
| 
 | ||||
| extern size_t hexagon_coherent_pool_size; | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										234
									
								
								arch/hexagon/include/asm/elf.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								arch/hexagon/include/asm/elf.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,234 @@ | |||
| /*
 | ||||
|  * ELF definitions for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __ASM_ELF_H | ||||
| #define __ASM_ELF_H | ||||
| 
 | ||||
| #include <asm/ptrace.h> | ||||
| #include <asm/user.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * This should really be in linux/elf-em.h. | ||||
|  */ | ||||
| #define EM_HEXAGON	164   /* QUALCOMM Hexagon */ | ||||
| 
 | ||||
| struct elf32_hdr; | ||||
| 
 | ||||
| /*
 | ||||
|  * ELF header e_flags defines. | ||||
|  */ | ||||
| 
 | ||||
| /*  should have stuff like "CPU type" and maybe "ABI version", etc  */ | ||||
| 
 | ||||
| /* Hexagon relocations */ | ||||
|   /* V2 */ | ||||
| #define R_HEXAGON_NONE           0 | ||||
| #define R_HEXAGON_B22_PCREL      1 | ||||
| #define R_HEXAGON_B15_PCREL      2 | ||||
| #define R_HEXAGON_B7_PCREL       3 | ||||
| #define R_HEXAGON_LO16           4 | ||||
| #define R_HEXAGON_HI16           5 | ||||
| #define R_HEXAGON_32             6 | ||||
| #define R_HEXAGON_16             7 | ||||
| #define R_HEXAGON_8              8 | ||||
| #define R_HEXAGON_GPREL16_0      9 | ||||
| #define R_HEXAGON_GPREL16_1     10 | ||||
| #define R_HEXAGON_GPREL16_2     11 | ||||
| #define R_HEXAGON_GPREL16_3     12 | ||||
| #define R_HEXAGON_HL16          13 | ||||
|   /* V3 */ | ||||
| #define R_HEXAGON_B13_PCREL     14 | ||||
|   /* V4 */ | ||||
| #define R_HEXAGON_B9_PCREL      15 | ||||
|   /* V4 (extenders) */ | ||||
| #define R_HEXAGON_B32_PCREL_X   16 | ||||
| #define R_HEXAGON_32_6_X        17 | ||||
|   /* V4 (extended) */ | ||||
| #define R_HEXAGON_B22_PCREL_X   18 | ||||
| #define R_HEXAGON_B15_PCREL_X   19 | ||||
| #define R_HEXAGON_B13_PCREL_X   20 | ||||
| #define R_HEXAGON_B9_PCREL_X    21 | ||||
| #define R_HEXAGON_B7_PCREL_X    22 | ||||
| #define R_HEXAGON_16_X          23 | ||||
| #define R_HEXAGON_12_X          24 | ||||
| #define R_HEXAGON_11_X          25 | ||||
| #define R_HEXAGON_10_X          26 | ||||
| #define R_HEXAGON_9_X           27 | ||||
| #define R_HEXAGON_8_X           28 | ||||
| #define R_HEXAGON_7_X           29 | ||||
| #define R_HEXAGON_6_X           30 | ||||
|   /* V2 PIC */ | ||||
| #define R_HEXAGON_32_PCREL      31 | ||||
| #define R_HEXAGON_COPY          32 | ||||
| #define R_HEXAGON_GLOB_DAT      33 | ||||
| #define R_HEXAGON_JMP_SLOT      34 | ||||
| #define R_HEXAGON_RELATIVE      35 | ||||
| #define R_HEXAGON_PLT_B22_PCREL 36 | ||||
| #define R_HEXAGON_GOTOFF_LO16   37 | ||||
| #define R_HEXAGON_GOTOFF_HI16   38 | ||||
| #define R_HEXAGON_GOTOFF_32     39 | ||||
| #define R_HEXAGON_GOT_LO16      40 | ||||
| #define R_HEXAGON_GOT_HI16      41 | ||||
| #define R_HEXAGON_GOT_32        42 | ||||
| #define R_HEXAGON_GOT_16        43 | ||||
| 
 | ||||
| /*
 | ||||
|  * ELF register definitions.. | ||||
|  */ | ||||
| typedef unsigned long elf_greg_t; | ||||
| 
 | ||||
| typedef struct user_regs_struct elf_gregset_t; | ||||
| #define ELF_NGREG (sizeof(elf_gregset_t)/sizeof(unsigned long)) | ||||
| 
 | ||||
| /*  Placeholder  */ | ||||
| typedef unsigned long elf_fpregset_t; | ||||
| 
 | ||||
| /*
 | ||||
|  * Bypass the whole "regsets" thing for now and use the define. | ||||
|  */ | ||||
| 
 | ||||
| #if CONFIG_HEXAGON_ARCH_VERSION >= 4 | ||||
| #define CS_COPYREGS(DEST,REGS) \ | ||||
| do {\ | ||||
| 	DEST.cs0 = REGS->cs0;\ | ||||
| 	DEST.cs1 = REGS->cs1;\ | ||||
| } while (0) | ||||
| #else | ||||
| #define CS_COPYREGS(DEST,REGS) | ||||
| #endif | ||||
| 
 | ||||
| #define ELF_CORE_COPY_REGS(DEST, REGS)	\ | ||||
| do {					\ | ||||
| 	DEST.r0 = REGS->r00;		\ | ||||
| 	DEST.r1 = REGS->r01;		\ | ||||
| 	DEST.r2 = REGS->r02;		\ | ||||
| 	DEST.r3 = REGS->r03;		\ | ||||
| 	DEST.r4 = REGS->r04;		\ | ||||
| 	DEST.r5 = REGS->r05;		\ | ||||
| 	DEST.r6 = REGS->r06;		\ | ||||
| 	DEST.r7 = REGS->r07;		\ | ||||
| 	DEST.r8 = REGS->r08;		\ | ||||
| 	DEST.r9 = REGS->r09;		\ | ||||
| 	DEST.r10 = REGS->r10;		\ | ||||
| 	DEST.r11 = REGS->r11;		\ | ||||
| 	DEST.r12 = REGS->r12;		\ | ||||
| 	DEST.r13 = REGS->r13;		\ | ||||
| 	DEST.r14 = REGS->r14;		\ | ||||
| 	DEST.r15 = REGS->r15;		\ | ||||
| 	DEST.r16 = REGS->r16;		\ | ||||
| 	DEST.r17 = REGS->r17;		\ | ||||
| 	DEST.r18 = REGS->r18;		\ | ||||
| 	DEST.r19 = REGS->r19;		\ | ||||
| 	DEST.r20 = REGS->r20;		\ | ||||
| 	DEST.r21 = REGS->r21;		\ | ||||
| 	DEST.r22 = REGS->r22;		\ | ||||
| 	DEST.r23 = REGS->r23;		\ | ||||
| 	DEST.r24 = REGS->r24;		\ | ||||
| 	DEST.r25 = REGS->r25;		\ | ||||
| 	DEST.r26 = REGS->r26;		\ | ||||
| 	DEST.r27 = REGS->r27;		\ | ||||
| 	DEST.r28 = REGS->r28;		\ | ||||
| 	DEST.r29 = pt_psp(REGS);	\ | ||||
| 	DEST.r30 = REGS->r30;		\ | ||||
| 	DEST.r31 = REGS->r31;		\ | ||||
| 	DEST.sa0 = REGS->sa0;		\ | ||||
| 	DEST.lc0 = REGS->lc0;		\ | ||||
| 	DEST.sa1 = REGS->sa1;		\ | ||||
| 	DEST.lc1 = REGS->lc1;		\ | ||||
| 	DEST.m0 = REGS->m0;		\ | ||||
| 	DEST.m1 = REGS->m1;		\ | ||||
| 	DEST.usr = REGS->usr;		\ | ||||
| 	DEST.p3_0 = REGS->preds;	\ | ||||
| 	DEST.gp = REGS->gp;		\ | ||||
| 	DEST.ugp = REGS->ugp;		\ | ||||
| 	CS_COPYREGS(DEST,REGS);		\ | ||||
| 	DEST.pc = pt_elr(REGS);		\ | ||||
| 	DEST.cause = pt_cause(REGS);	\ | ||||
| 	DEST.badva = pt_badva(REGS);	\ | ||||
| } while (0); | ||||
| 
 | ||||
| /*
 | ||||
|  * This is used to ensure we don't load something for the wrong architecture. | ||||
|  * Checks the machine and ABI type. | ||||
|  */ | ||||
| #define elf_check_arch(hdr)	((hdr)->e_machine == EM_HEXAGON) | ||||
| 
 | ||||
| /*
 | ||||
|  * These are used to set parameters in the core dumps. | ||||
|  */ | ||||
| #define ELF_CLASS	ELFCLASS32 | ||||
| #define ELF_DATA	ELFDATA2LSB | ||||
| #define ELF_ARCH	EM_HEXAGON | ||||
| 
 | ||||
| #if CONFIG_HEXAGON_ARCH_VERSION == 2 | ||||
| #define ELF_CORE_EFLAGS 0x1 | ||||
| #endif | ||||
| 
 | ||||
| #if CONFIG_HEXAGON_ARCH_VERSION == 3 | ||||
| #define ELF_CORE_EFLAGS 0x2 | ||||
| #endif | ||||
| 
 | ||||
| #if CONFIG_HEXAGON_ARCH_VERSION == 4 | ||||
| #define ELF_CORE_EFLAGS 0x3 | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * Some architectures have ld.so set up a pointer to a function | ||||
|  * to be registered using atexit, to facilitate cleanup.  So that | ||||
|  * static executables will be well-behaved, we would null the register | ||||
|  * in question here, in the pt_regs structure passed.  For now, | ||||
|  * leave it a null macro. | ||||
|  */ | ||||
| #define ELF_PLAT_INIT(regs, load_addr) do { } while (0) | ||||
| 
 | ||||
| #define USE_ELF_CORE_DUMP | ||||
| #define CORE_DUMP_USE_REGSET | ||||
| 
 | ||||
| /* Hrm is this going to cause problems for changing PAGE_SIZE?  */ | ||||
| #define ELF_EXEC_PAGESIZE	PAGE_SIZE | ||||
| 
 | ||||
| /*
 | ||||
|  * This is the location that an ET_DYN program is loaded if exec'ed.  Typical | ||||
|  * use of this is to invoke "./ld.so someprog" to test out a new version of | ||||
|  * the loader.  We need to make sure that it is out of the way of the program | ||||
|  * that it will "exec", and that there is sufficient room for the brk. | ||||
|  */ | ||||
| #define ELF_ET_DYN_BASE         0x08000000UL | ||||
| 
 | ||||
| /*
 | ||||
|  * This yields a mask that user programs can use to figure out what | ||||
|  * instruction set this cpu supports. | ||||
|  */ | ||||
| #define ELF_HWCAP	(0) | ||||
| 
 | ||||
| /*
 | ||||
|  * This yields a string that ld.so will use to load implementation | ||||
|  * specific libraries for optimization.  This is more specific in | ||||
|  * intent than poking at uname or /proc/cpuinfo. | ||||
|  */ | ||||
| #define ELF_PLATFORM  (NULL) | ||||
| 
 | ||||
| #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 | ||||
| struct linux_binprm; | ||||
| extern int arch_setup_additional_pages(struct linux_binprm *bprm, | ||||
| 				       int uses_interp); | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										28
									
								
								arch/hexagon/include/asm/exec.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								arch/hexagon/include/asm/exec.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | |||
| /*
 | ||||
|  * Process execution related definitions for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_EXEC_H | ||||
| #define _ASM_EXEC_H | ||||
| 
 | ||||
| /*  Should probably shoot for an 8-byte aligned stack pointer  */ | ||||
| #define STACK_MASK (~7) | ||||
| #define arch_align_stack(x) (x & STACK_MASK) | ||||
| 
 | ||||
| #endif /* _ASM_EXEC_H */ | ||||
							
								
								
									
										35
									
								
								arch/hexagon/include/asm/fixmap.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								arch/hexagon/include/asm/fixmap.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | |||
| /*
 | ||||
|  * Fixmap support for Hexagon - enough to support highmem features | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_FIXMAP_H | ||||
| #define _ASM_FIXMAP_H | ||||
| 
 | ||||
| /*
 | ||||
|  * A lot of the fixmap info is already in mem-layout.h | ||||
|  */ | ||||
| #include <asm/mem-layout.h> | ||||
| 
 | ||||
| #include <asm-generic/fixmap.h> | ||||
| 
 | ||||
| #define kmap_get_fixmap_pte(vaddr) \ | ||||
| 	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), \ | ||||
| 				(vaddr)), (vaddr)), (vaddr)) | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										4
									
								
								arch/hexagon/include/asm/fpu.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								arch/hexagon/include/asm/fpu.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | |||
| /*
 | ||||
|  * If the FPU is used inside the kernel, | ||||
|  * kernel_fpu_end() will be defined here. | ||||
|  */ | ||||
							
								
								
									
										137
									
								
								arch/hexagon/include/asm/futex.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								arch/hexagon/include/asm/futex.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,137 @@ | |||
| #ifndef _ASM_HEXAGON_FUTEX_H | ||||
| #define _ASM_HEXAGON_FUTEX_H | ||||
| 
 | ||||
| #ifdef __KERNEL__ | ||||
| 
 | ||||
| #include <linux/futex.h> | ||||
| #include <linux/uaccess.h> | ||||
| #include <asm/errno.h> | ||||
| 
 | ||||
| /* XXX TODO-- need to add sync barriers! */ | ||||
| 
 | ||||
| #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ | ||||
| 	__asm__ __volatile( \ | ||||
| 	"1: %0 = memw_locked(%3);\n" \ | ||||
| 	    /* For example: %1 = %4 */ \ | ||||
| 	    insn \ | ||||
| 	"2: memw_locked(%3,p2) = %1;\n" \ | ||||
| 	"   if !p2 jump 1b;\n" \ | ||||
| 	"   %1 = #0;\n" \ | ||||
| 	"3:\n" \ | ||||
| 	".section .fixup,\"ax\"\n" \ | ||||
| 	"4: %1 = #%5;\n" \ | ||||
| 	"   jump 3b\n" \ | ||||
| 	".previous\n" \ | ||||
| 	".section __ex_table,\"a\"\n" \ | ||||
| 	".long 1b,4b,2b,4b\n" \ | ||||
| 	".previous\n" \ | ||||
| 	: "=&r" (oldval), "=&r" (ret), "+m" (*uaddr) \ | ||||
| 	: "r" (uaddr), "r" (oparg), "i" (-EFAULT) \ | ||||
| 	: "p2", "memory") | ||||
| 
 | ||||
| 
 | ||||
| static inline int | ||||
| futex_atomic_op_inuser(int encoded_op, int __user *uaddr) | ||||
| { | ||||
| 	int op = (encoded_op >> 28) & 7; | ||||
| 	int cmp = (encoded_op >> 24) & 15; | ||||
| 	int oparg = (encoded_op << 8) >> 20; | ||||
| 	int cmparg = (encoded_op << 20) >> 20; | ||||
| 	int oldval = 0, ret; | ||||
| 	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||||
| 		oparg = 1 << oparg; | ||||
| 
 | ||||
| 	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) | ||||
| 		return -EFAULT; | ||||
| 
 | ||||
| 	pagefault_disable(); | ||||
| 
 | ||||
| 	switch (op) { | ||||
| 	case FUTEX_OP_SET: | ||||
| 		__futex_atomic_op("%1 = %4\n", ret, oldval, uaddr, oparg); | ||||
| 		break; | ||||
| 	case FUTEX_OP_ADD: | ||||
| 		__futex_atomic_op("%1 = add(%0,%4)\n", ret, oldval, uaddr, | ||||
| 				  oparg); | ||||
| 		break; | ||||
| 	case FUTEX_OP_OR: | ||||
| 		__futex_atomic_op("%1 = or(%0,%4)\n", ret, oldval, uaddr, | ||||
| 				  oparg); | ||||
| 		break; | ||||
| 	case FUTEX_OP_ANDN: | ||||
| 		__futex_atomic_op("%1 = not(%4); %1 = and(%0,%1)\n", ret, | ||||
| 				  oldval, uaddr, oparg); | ||||
| 		break; | ||||
| 	case FUTEX_OP_XOR: | ||||
| 		__futex_atomic_op("%1 = xor(%0,%4)\n", ret, oldval, uaddr, | ||||
| 				  oparg); | ||||
| 		break; | ||||
| 	default: | ||||
| 		ret = -ENOSYS; | ||||
| 	} | ||||
| 
 | ||||
| 	pagefault_enable(); | ||||
| 
 | ||||
| 	if (!ret) { | ||||
| 		switch (cmp) { | ||||
| 		case FUTEX_OP_CMP_EQ: | ||||
| 			ret = (oldval == cmparg); | ||||
| 			break; | ||||
| 		case FUTEX_OP_CMP_NE: | ||||
| 			ret = (oldval != cmparg); | ||||
| 			break; | ||||
| 		case FUTEX_OP_CMP_LT: | ||||
| 			ret = (oldval < cmparg); | ||||
| 			break; | ||||
| 		case FUTEX_OP_CMP_GE: | ||||
| 			ret = (oldval >= cmparg); | ||||
| 			break; | ||||
| 		case FUTEX_OP_CMP_LE: | ||||
| 			ret = (oldval <= cmparg); | ||||
| 			break; | ||||
| 		case FUTEX_OP_CMP_GT: | ||||
| 			ret = (oldval > cmparg); | ||||
| 			break; | ||||
| 		default: | ||||
| 			ret = -ENOSYS; | ||||
| 		} | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static inline int | ||||
| futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, | ||||
| 			      u32 newval) | ||||
| { | ||||
| 	int prev; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) | ||||
| 		return -EFAULT; | ||||
| 
 | ||||
| 	__asm__ __volatile__ ( | ||||
| 	"1: %1 = memw_locked(%3)\n" | ||||
| 	"   {\n" | ||||
| 	"      p2 = cmp.eq(%1,%4)\n" | ||||
| 	"      if !p2.new jump:NT 3f\n" | ||||
| 	"   }\n" | ||||
| 	"2: memw_locked(%3,p2) = %5\n" | ||||
| 	"   if !p2 jump 1b\n" | ||||
| 	"3:\n" | ||||
| 	".section .fixup,\"ax\"\n" | ||||
| 	"4: %0 = #%6\n" | ||||
| 	"   jump 3b\n" | ||||
| 	".previous\n" | ||||
| 	".section __ex_table,\"a\"\n" | ||||
| 	".long 1b,4b,2b,4b\n" | ||||
| 	".previous\n" | ||||
| 	: "+r" (ret), "=&r" (prev), "+m" (*uaddr) | ||||
| 	: "r" (uaddr), "r" (oldval), "r" (newval), "i"(-EFAULT) | ||||
| 	: "p2", "memory"); | ||||
| 
 | ||||
| 	*uval = prev; | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| #endif /* __KERNEL__ */ | ||||
| #endif /* _ASM_HEXAGON_FUTEX_H */ | ||||
							
								
								
									
										289
									
								
								arch/hexagon/include/asm/hexagon_vm.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										289
									
								
								arch/hexagon/include/asm/hexagon_vm.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,289 @@ | |||
| /*
 | ||||
|  * Declarations for to Hexagon Virtal Machine. | ||||
|  * | ||||
|  * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef ASM_HEXAGON_VM_H | ||||
| #define ASM_HEXAGON_VM_H | ||||
| 
 | ||||
| /*
 | ||||
|  * In principle, a Linux kernel for the VM could | ||||
|  * selectively define the virtual instructions | ||||
|  * as inline assembler macros, but for a first pass, | ||||
|  * we'll use subroutines for both the VM and the native | ||||
|  * kernels.  It's costing a subroutine call/return, | ||||
|  * but it makes for a single set of entry points | ||||
|  * for tracing/debugging. | ||||
|  */ | ||||
| 
 | ||||
| #define HVM_TRAP1_VMVERSION		0 | ||||
| #define HVM_TRAP1_VMRTE			1 | ||||
| #define HVM_TRAP1_VMSETVEC		2 | ||||
| #define HVM_TRAP1_VMSETIE		3 | ||||
| #define HVM_TRAP1_VMGETIE		4 | ||||
| #define HVM_TRAP1_VMINTOP		5 | ||||
| #define HVM_TRAP1_VMCLRMAP		10 | ||||
| #define HVM_TRAP1_VMNEWMAP		11 | ||||
| #define HVM_TRAP1_FORMERLY_VMWIRE	12 | ||||
| #define HVM_TRAP1_VMCACHE		13 | ||||
| #define HVM_TRAP1_VMGETTIME		14 | ||||
| #define HVM_TRAP1_VMSETTIME		15 | ||||
| #define HVM_TRAP1_VMWAIT		16 | ||||
| #define HVM_TRAP1_VMYIELD		17 | ||||
| #define HVM_TRAP1_VMSTART		18 | ||||
| #define HVM_TRAP1_VMSTOP		19 | ||||
| #define HVM_TRAP1_VMVPID		20 | ||||
| #define HVM_TRAP1_VMSETREGS		21 | ||||
| #define HVM_TRAP1_VMGETREGS		22 | ||||
| #define HVM_TRAP1_VMTIMEROP		24 | ||||
| 
 | ||||
| #ifndef __ASSEMBLY__ | ||||
| 
 | ||||
| enum VM_CACHE_OPS { | ||||
| 	hvmc_ickill, | ||||
| 	hvmc_dckill, | ||||
| 	hvmc_l2kill, | ||||
| 	hvmc_dccleaninva, | ||||
| 	hvmc_icinva, | ||||
| 	hvmc_idsync, | ||||
| 	hvmc_fetch_cfg | ||||
| }; | ||||
| 
 | ||||
| enum VM_INT_OPS { | ||||
| 	hvmi_nop, | ||||
| 	hvmi_globen, | ||||
| 	hvmi_globdis, | ||||
| 	hvmi_locen, | ||||
| 	hvmi_locdis, | ||||
| 	hvmi_affinity, | ||||
| 	hvmi_get, | ||||
| 	hvmi_peek, | ||||
| 	hvmi_status, | ||||
| 	hvmi_post, | ||||
| 	hvmi_clear | ||||
| }; | ||||
| 
 | ||||
| extern void _K_VM_event_vector(void); | ||||
| 
 | ||||
| void __vmrte(void); | ||||
| long __vmsetvec(void *); | ||||
| long __vmsetie(long); | ||||
| long __vmgetie(void); | ||||
| long __vmintop(enum VM_INT_OPS, long, long, long, long); | ||||
| long __vmclrmap(void *, unsigned long); | ||||
| long __vmnewmap(void *); | ||||
| long __vmcache(enum VM_CACHE_OPS op, unsigned long addr, unsigned long len); | ||||
| unsigned long long __vmgettime(void); | ||||
| long __vmsettime(unsigned long long); | ||||
| long __vmstart(void *, void *); | ||||
| void __vmstop(void); | ||||
| long __vmwait(void); | ||||
| void __vmyield(void); | ||||
| long __vmvpid(void); | ||||
| 
 | ||||
| static inline long __vmcache_ickill(void) | ||||
| { | ||||
| 	return __vmcache(hvmc_ickill, 0, 0); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmcache_dckill(void) | ||||
| { | ||||
| 	return __vmcache(hvmc_dckill, 0, 0); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmcache_l2kill(void) | ||||
| { | ||||
| 	return __vmcache(hvmc_l2kill, 0, 0); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmcache_dccleaninva(unsigned long addr, unsigned long len) | ||||
| { | ||||
| 	return __vmcache(hvmc_dccleaninva, addr, len); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmcache_icinva(unsigned long addr, unsigned long len) | ||||
| { | ||||
| 	return __vmcache(hvmc_icinva, addr, len); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmcache_idsync(unsigned long addr, | ||||
| 					   unsigned long len) | ||||
| { | ||||
| 	return __vmcache(hvmc_idsync, addr, len); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmcache_fetch_cfg(unsigned long val) | ||||
| { | ||||
| 	return __vmcache(hvmc_fetch_cfg, val, 0); | ||||
| } | ||||
| 
 | ||||
| /* interrupt operations  */ | ||||
| 
 | ||||
| static inline long __vmintop_nop(void) | ||||
| { | ||||
| 	return __vmintop(hvmi_nop, 0, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmintop_globen(long i) | ||||
| { | ||||
| 	return __vmintop(hvmi_globen, i, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmintop_globdis(long i) | ||||
| { | ||||
| 	return __vmintop(hvmi_globdis, i, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmintop_locen(long i) | ||||
| { | ||||
| 	return __vmintop(hvmi_locen, i, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmintop_locdis(long i) | ||||
| { | ||||
| 	return __vmintop(hvmi_locdis, i, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmintop_affinity(long i, long cpu) | ||||
| { | ||||
| 	return __vmintop(hvmi_affinity, i, cpu, 0, 0); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmintop_get(void) | ||||
| { | ||||
| 	return __vmintop(hvmi_get, 0, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmintop_peek(void) | ||||
| { | ||||
| 	return __vmintop(hvmi_peek, 0, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmintop_status(long i) | ||||
| { | ||||
| 	return __vmintop(hvmi_status, i, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmintop_post(long i) | ||||
| { | ||||
| 	return __vmintop(hvmi_post, i, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| static inline long __vmintop_clear(long i) | ||||
| { | ||||
| 	return __vmintop(hvmi_clear, i, 0, 0, 0); | ||||
| } | ||||
| 
 | ||||
| #else /* Only assembly code should reference these */ | ||||
| 
 | ||||
| #endif /* __ASSEMBLY__ */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Constants for virtual instruction parameters and return values | ||||
|  */ | ||||
| 
 | ||||
| /* vmnewmap arguments */ | ||||
| 
 | ||||
| #define VM_TRANS_TYPE_LINEAR 0 | ||||
| #define VM_TRANS_TYPE_TABLE 1 | ||||
| #define VM_TLB_INVALIDATE_FALSE 0 | ||||
| #define VM_TLB_INVALIDATE_TRUE 1 | ||||
| 
 | ||||
| /* vmsetie arguments */ | ||||
| 
 | ||||
| #define VM_INT_DISABLE	0 | ||||
| #define VM_INT_ENABLE	1 | ||||
| 
 | ||||
| /* vmsetimask arguments */ | ||||
| 
 | ||||
| #define VM_INT_UNMASK	0 | ||||
| #define VM_INT_MASK	1 | ||||
| 
 | ||||
| #define VM_NEWMAP_TYPE_LINEAR	0 | ||||
| #define VM_NEWMAP_TYPE_PGTABLES	1 | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * Event Record definitions useful to both C and Assembler | ||||
|  */ | ||||
| 
 | ||||
| /* VMEST Layout */ | ||||
| 
 | ||||
| #define HVM_VMEST_UM_SFT	31 | ||||
| #define HVM_VMEST_UM_MSK	1 | ||||
| #define HVM_VMEST_IE_SFT	30 | ||||
| #define HVM_VMEST_IE_MSK	1 | ||||
| #define HVM_VMEST_SS_SFT	29 | ||||
| #define HVM_VMEST_SS_MSK	1 | ||||
| #define HVM_VMEST_EVENTNUM_SFT	16 | ||||
| #define HVM_VMEST_EVENTNUM_MSK	0xff | ||||
| #define HVM_VMEST_CAUSE_SFT	0 | ||||
| #define HVM_VMEST_CAUSE_MSK	0xffff | ||||
| 
 | ||||
| /*
 | ||||
|  * The initial program gets to find a system environment descriptor | ||||
|  * on its stack when it begins exection. The first word is a version | ||||
|  * code to indicate what is there.  Zero means nothing more. | ||||
|  */ | ||||
| 
 | ||||
| #define HEXAGON_VM_SED_NULL	0 | ||||
| 
 | ||||
| /*
 | ||||
|  * Event numbers for vector binding | ||||
|  */ | ||||
| 
 | ||||
| #define HVM_EV_RESET		0 | ||||
| #define HVM_EV_MACHCHECK	1 | ||||
| #define HVM_EV_GENEX		2 | ||||
| #define HVM_EV_TRAP		8 | ||||
| #define HVM_EV_INTR		15 | ||||
| /* These shoud be nuked as soon as we know the VM is up to spec v0.1.1 */ | ||||
| #define HVM_EV_INTR_0		16 | ||||
| #define HVM_MAX_INTR		240 | ||||
| 
 | ||||
| /*
 | ||||
|  * Cause values for General Exception | ||||
|  */ | ||||
| 
 | ||||
| #define HVM_GE_C_BUS	0x01 | ||||
| #define HVM_GE_C_XPROT	0x11 | ||||
| #define HVM_GE_C_XUSER	0x14 | ||||
| #define HVM_GE_C_INVI	0x15 | ||||
| #define HVM_GE_C_PRIVI	0x1B | ||||
| #define HVM_GE_C_XMAL	0x1C | ||||
| #define HVM_GE_C_WREG	0x1D | ||||
| #define HVM_GE_C_PCAL	0x1E | ||||
| #define HVM_GE_C_RMAL	0x20 | ||||
| #define HVM_GE_C_WMAL	0x21 | ||||
| #define HVM_GE_C_RPROT	0x22 | ||||
| #define HVM_GE_C_WPROT	0x23 | ||||
| #define HVM_GE_C_RUSER	0x24 | ||||
| #define HVM_GE_C_WUSER	0x25 | ||||
| #define HVM_GE_C_CACHE	0x28 | ||||
| 
 | ||||
| /*
 | ||||
|  * Cause codes for Machine Check | ||||
|  */ | ||||
| 
 | ||||
| #define	HVM_MCHK_C_DOWN		0x00 | ||||
| #define	HVM_MCHK_C_BADSP	0x01 | ||||
| #define	HVM_MCHK_C_BADEX	0x02 | ||||
| #define	HVM_MCHK_C_BADPT	0x03 | ||||
| #define	HVM_MCHK_C_REGWR	0x29 | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										26
									
								
								arch/hexagon/include/asm/intrinsics.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								arch/hexagon/include/asm/intrinsics.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_HEXAGON_INTRINSICS_H | ||||
| #define _ASM_HEXAGON_INTRINSICS_H | ||||
| 
 | ||||
| #define HEXAGON_P_vrmpyhacc_PP	__builtin_HEXAGON_M2_vrmac_s0 | ||||
| #define HEXAGON_P_vrmpyh_PP	__builtin_HEXAGON_M2_vrmpy_s0 | ||||
| #define HEXAGON_R_cl0_R		__builtin_HEXAGON_S2_cl0 | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										342
									
								
								arch/hexagon/include/asm/io.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								arch/hexagon/include/asm/io.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,342 @@ | |||
| /*
 | ||||
|  * IO definitions for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_IO_H | ||||
| #define _ASM_IO_H | ||||
| 
 | ||||
| #ifdef __KERNEL__ | ||||
| 
 | ||||
| #include <linux/types.h> | ||||
| #include <linux/delay.h> | ||||
| #include <linux/vmalloc.h> | ||||
| #include <asm/string.h> | ||||
| #include <asm/mem-layout.h> | ||||
| #include <asm/iomap.h> | ||||
| #include <asm/page.h> | ||||
| #include <asm/cacheflush.h> | ||||
| #include <asm/tlbflush.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * We don't have PCI yet. | ||||
|  * _IO_BASE is pointing at what should be unused virtual space. | ||||
|  */ | ||||
| #define IO_SPACE_LIMIT 0xffff | ||||
| #define _IO_BASE ((void __iomem *)0xfe000000) | ||||
| 
 | ||||
| #define IOMEM(x)        ((void __force __iomem *)(x)) | ||||
| 
 | ||||
| extern int remap_area_pages(unsigned long start, unsigned long phys_addr, | ||||
| 				unsigned long end, unsigned long flags); | ||||
| 
 | ||||
| extern void __iounmap(const volatile void __iomem *addr); | ||||
| 
 | ||||
| /* Defined in lib/io.c, needed for smc91x driver. */ | ||||
| extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen); | ||||
| extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen); | ||||
| 
 | ||||
| extern void __raw_readsl(const void __iomem *addr, void *data, int wordlen); | ||||
| extern void __raw_writesl(void __iomem *addr, const void *data, int wordlen); | ||||
| 
 | ||||
| #define readsw(p, d, l)	__raw_readsw(p, d, l) | ||||
| #define writesw(p, d, l) __raw_writesw(p, d, l) | ||||
| 
 | ||||
| #define readsl(p, d, l)   __raw_readsl(p, d, l) | ||||
| #define writesl(p, d, l)  __raw_writesl(p, d, l) | ||||
| 
 | ||||
| /*
 | ||||
|  * virt_to_phys - map virtual address to physical | ||||
|  * @address:  address to map | ||||
|  */ | ||||
| static inline unsigned long virt_to_phys(volatile void *address) | ||||
| { | ||||
| 	return __pa(address); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * phys_to_virt - map physical address to virtual | ||||
|  * @address: address to map | ||||
|  */ | ||||
| static inline void *phys_to_virt(unsigned long address) | ||||
| { | ||||
| 	return __va(address); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * convert a physical pointer to a virtual kernel pointer for | ||||
|  * /dev/mem access. | ||||
|  */ | ||||
| #define xlate_dev_kmem_ptr(p)    __va(p) | ||||
| #define xlate_dev_mem_ptr(p)    __va(p) | ||||
| 
 | ||||
| /*
 | ||||
|  * IO port access primitives.  Hexagon doesn't have special IO access | ||||
|  * instructions; all I/O is memory mapped. | ||||
|  * | ||||
|  * in/out are used for "ports", but we don't have "port instructions", | ||||
|  * so these are really just memory mapped too. | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * readb - read byte from memory mapped device | ||||
|  * @addr:  pointer to memory | ||||
|  * | ||||
|  * Operates on "I/O bus memory space" | ||||
|  */ | ||||
| static inline u8 readb(const volatile void __iomem *addr) | ||||
| { | ||||
| 	u8 val; | ||||
| 	asm volatile( | ||||
| 		"%0 = memb(%1);" | ||||
| 		: "=&r" (val) | ||||
| 		: "r" (addr) | ||||
| 	); | ||||
| 	return val; | ||||
| } | ||||
| 
 | ||||
| static inline u16 readw(const volatile void __iomem *addr) | ||||
| { | ||||
| 	u16 val; | ||||
| 	asm volatile( | ||||
| 		"%0 = memh(%1);" | ||||
| 		: "=&r" (val) | ||||
| 		: "r" (addr) | ||||
| 	); | ||||
| 	return val; | ||||
| } | ||||
| 
 | ||||
| static inline u32 readl(const volatile void __iomem *addr) | ||||
| { | ||||
| 	u32 val; | ||||
| 	asm volatile( | ||||
| 		"%0 = memw(%1);" | ||||
| 		: "=&r" (val) | ||||
| 		: "r" (addr) | ||||
| 	); | ||||
| 	return val; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * writeb - write a byte to a memory location | ||||
|  * @data: data to write to | ||||
|  * @addr:  pointer to memory | ||||
|  * | ||||
|  */ | ||||
| static inline void writeb(u8 data, volatile void __iomem *addr) | ||||
| { | ||||
| 	asm volatile( | ||||
| 		"memb(%0) = %1;" | ||||
| 		: | ||||
| 		: "r" (addr), "r" (data) | ||||
| 		: "memory" | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| static inline void writew(u16 data, volatile void __iomem *addr) | ||||
| { | ||||
| 	asm volatile( | ||||
| 		"memh(%0) = %1;" | ||||
| 		: | ||||
| 		: "r" (addr), "r" (data) | ||||
| 		: "memory" | ||||
| 	); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static inline void writel(u32 data, volatile void __iomem *addr) | ||||
| { | ||||
| 	asm volatile( | ||||
| 		"memw(%0) = %1;" | ||||
| 		: | ||||
| 		: "r" (addr), "r" (data) | ||||
| 		: "memory" | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| #define __raw_writeb writeb | ||||
| #define __raw_writew writew | ||||
| #define __raw_writel writel | ||||
| 
 | ||||
| #define __raw_readb readb | ||||
| #define __raw_readw readw | ||||
| #define __raw_readl readl | ||||
| 
 | ||||
| /*
 | ||||
|  * http://comments.gmane.org/gmane.linux.ports.arm.kernel/117626
 | ||||
|  */ | ||||
| 
 | ||||
| #define readb_relaxed __raw_readb | ||||
| #define readw_relaxed __raw_readw | ||||
| #define readl_relaxed __raw_readl | ||||
| 
 | ||||
| #define writeb_relaxed __raw_writeb | ||||
| #define writew_relaxed __raw_writew | ||||
| #define writel_relaxed __raw_writel | ||||
| 
 | ||||
| #define mmiowb() | ||||
| 
 | ||||
| /*
 | ||||
|  * Need an mtype somewhere in here, for cache type deals? | ||||
|  * This is probably too long for an inline. | ||||
|  */ | ||||
| void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size); | ||||
| 
 | ||||
| static inline void __iomem *ioremap(unsigned long phys_addr, unsigned long size) | ||||
| { | ||||
| 	return ioremap_nocache(phys_addr, size); | ||||
| } | ||||
| 
 | ||||
| static inline void iounmap(volatile void __iomem *addr) | ||||
| { | ||||
| 	__iounmap(addr); | ||||
| } | ||||
| 
 | ||||
| #define __raw_writel writel | ||||
| 
 | ||||
| static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, | ||||
| 	int count) | ||||
| { | ||||
| 	memcpy(dst, (void *) src, count); | ||||
| } | ||||
| 
 | ||||
| static inline void memcpy_toio(volatile void __iomem *dst, const void *src, | ||||
| 	int count) | ||||
| { | ||||
| 	memcpy((void *) dst, src, count); | ||||
| } | ||||
| 
 | ||||
| #define PCI_IO_ADDR	(volatile void __iomem *) | ||||
| 
 | ||||
| /*
 | ||||
|  * inb - read byte from I/O port or something | ||||
|  * @port:  address in I/O space | ||||
|  * | ||||
|  * Operates on "I/O bus I/O space" | ||||
|  */ | ||||
| static inline u8 inb(unsigned long port) | ||||
| { | ||||
| 	return readb(_IO_BASE + (port & IO_SPACE_LIMIT)); | ||||
| } | ||||
| 
 | ||||
| static inline u16 inw(unsigned long port) | ||||
| { | ||||
| 	return readw(_IO_BASE + (port & IO_SPACE_LIMIT)); | ||||
| } | ||||
| 
 | ||||
| static inline u32 inl(unsigned long port) | ||||
| { | ||||
| 	return readl(_IO_BASE + (port & IO_SPACE_LIMIT)); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * outb - write a byte to a memory location | ||||
|  * @data: data to write to | ||||
|  * @addr:  address in I/O space | ||||
|  */ | ||||
| static inline void outb(u8 data, unsigned long port) | ||||
| { | ||||
| 	writeb(data, _IO_BASE + (port & IO_SPACE_LIMIT)); | ||||
| } | ||||
| 
 | ||||
| static inline void outw(u16 data, unsigned long port) | ||||
| { | ||||
| 	writew(data, _IO_BASE + (port & IO_SPACE_LIMIT)); | ||||
| } | ||||
| 
 | ||||
| static inline void outl(u32 data, unsigned long port) | ||||
| { | ||||
| 	writel(data, _IO_BASE + (port & IO_SPACE_LIMIT)); | ||||
| } | ||||
| 
 | ||||
| #define outb_p outb | ||||
| #define outw_p outw | ||||
| #define outl_p outl | ||||
| 
 | ||||
| #define inb_p inb | ||||
| #define inw_p inw | ||||
| #define inl_p inl | ||||
| 
 | ||||
| static inline void insb(unsigned long port, void *buffer, int count) | ||||
| { | ||||
| 	if (count) { | ||||
| 		u8 *buf = buffer; | ||||
| 		do { | ||||
| 			u8 x = inb(port); | ||||
| 			*buf++ = x; | ||||
| 		} while (--count); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static inline void insw(unsigned long port, void *buffer, int count) | ||||
| { | ||||
| 	if (count) { | ||||
| 		u16 *buf = buffer; | ||||
| 		do { | ||||
| 			u16 x = inw(port); | ||||
| 			*buf++ = x; | ||||
| 		} while (--count); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static inline void insl(unsigned long port, void *buffer, int count) | ||||
| { | ||||
| 	if (count) { | ||||
| 		u32 *buf = buffer; | ||||
| 		do { | ||||
| 			u32 x = inw(port); | ||||
| 			*buf++ = x; | ||||
| 		} while (--count); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static inline void outsb(unsigned long port, const void *buffer, int count) | ||||
| { | ||||
| 	if (count) { | ||||
| 		const u8 *buf = buffer; | ||||
| 		do { | ||||
| 			outb(*buf++, port); | ||||
| 		} while (--count); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static inline void outsw(unsigned long port, const void *buffer, int count) | ||||
| { | ||||
| 	if (count) { | ||||
| 		const u16 *buf = buffer; | ||||
| 		do { | ||||
| 			outw(*buf++, port); | ||||
| 		} while (--count); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static inline void outsl(unsigned long port, const void *buffer, int count) | ||||
| { | ||||
| 	if (count) { | ||||
| 		const u32 *buf = buffer; | ||||
| 		do { | ||||
| 			outl(*buf++, port); | ||||
| 		} while (--count); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #define flush_write_buffers() do { } while (0) | ||||
| 
 | ||||
| #endif /* __KERNEL__ */ | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										36
									
								
								arch/hexagon/include/asm/irq.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								arch/hexagon/include/asm/irq.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_IRQ_H_ | ||||
| #define _ASM_IRQ_H_ | ||||
| 
 | ||||
| /* Number of first-level interrupts associated with the CPU core. */ | ||||
| #define HEXAGON_CPUINTS 32 | ||||
| 
 | ||||
| /*
 | ||||
|  * Must define NR_IRQS before including <asm-generic/irq.h> | ||||
|  * 64 == the two SIRC's, 176 == the two gpio's | ||||
|  * | ||||
|  * IRQ configuration is still in flux; defining this to a comfortably | ||||
|  * large number. | ||||
|  */ | ||||
| #define NR_IRQS 512 | ||||
| 
 | ||||
| #include <asm-generic/irq.h> | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										62
									
								
								arch/hexagon/include/asm/irqflags.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								arch/hexagon/include/asm/irqflags.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,62 @@ | |||
| /*
 | ||||
|  * IRQ support for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_IRQFLAGS_H | ||||
| #define _ASM_IRQFLAGS_H | ||||
| 
 | ||||
| #include <asm/hexagon_vm.h> | ||||
| #include <linux/types.h> | ||||
| 
 | ||||
| static inline unsigned long arch_local_save_flags(void) | ||||
| { | ||||
| 	return __vmgetie(); | ||||
| } | ||||
| 
 | ||||
| static inline unsigned long arch_local_irq_save(void) | ||||
| { | ||||
| 	return __vmsetie(VM_INT_DISABLE); | ||||
| } | ||||
| 
 | ||||
| static inline bool arch_irqs_disabled_flags(unsigned long flags) | ||||
| { | ||||
| 	return !flags; | ||||
| } | ||||
| 
 | ||||
| static inline bool arch_irqs_disabled(void) | ||||
| { | ||||
| 	return !__vmgetie(); | ||||
| } | ||||
| 
 | ||||
| static inline void arch_local_irq_enable(void) | ||||
| { | ||||
| 	__vmsetie(VM_INT_ENABLE); | ||||
| } | ||||
| 
 | ||||
| static inline void arch_local_irq_disable(void) | ||||
| { | ||||
| 	__vmsetie(VM_INT_DISABLE); | ||||
| } | ||||
| 
 | ||||
| static inline void arch_local_irq_restore(unsigned long flags) | ||||
| { | ||||
| 	__vmsetie(flags); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										44
									
								
								arch/hexagon/include/asm/kgdb.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								arch/hexagon/include/asm/kgdb.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| /*
 | ||||
|  * arch/hexagon/include/asm/kgdb.h - Hexagon KGDB Support | ||||
|  * | ||||
|  * Copyright (c) 2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __HEXAGON_KGDB_H__ | ||||
| #define __HEXAGON_KGDB_H__ | ||||
| 
 | ||||
| #define BREAK_INSTR_SIZE 4 | ||||
| #define CACHE_FLUSH_IS_SAFE   1 | ||||
| #define BUFMAX       ((NUMREGBYTES * 2) + 512) | ||||
| 
 | ||||
| static inline void arch_kgdb_breakpoint(void) | ||||
| { | ||||
| 	asm("trap0(#0xDB)"); | ||||
| } | ||||
| 
 | ||||
| /* Registers:
 | ||||
|  * 32 gpr + sa0/1 + lc0/1 + m0/1 + gp + ugp + pred + pc = 42 total. | ||||
|  * vm regs = psp+elr+est+badva = 4 | ||||
|  * syscall+restart = 2 more | ||||
|  * also add cs0/1 = 2 | ||||
|  * so 48 = 42 + 4 + 2 + 2 | ||||
|  */ | ||||
| #define DBG_USER_REGS 42 | ||||
| #define DBG_MAX_REG_NUM (DBG_USER_REGS + 8) | ||||
| #define NUMREGBYTES  (DBG_MAX_REG_NUM*4) | ||||
| 
 | ||||
| #endif /* __HEXAGON_KGDB_H__ */ | ||||
							
								
								
									
										25
									
								
								arch/hexagon/include/asm/linkage.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								arch/hexagon/include/asm/linkage.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __ASM_LINKAGE_H | ||||
| #define __ASM_LINKAGE_H | ||||
| 
 | ||||
| #define __ALIGN		.align 4 | ||||
| #define __ALIGN_STR	".align 4" | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										120
									
								
								arch/hexagon/include/asm/mem-layout.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								arch/hexagon/include/asm/mem-layout.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,120 @@ | |||
| /*
 | ||||
|  * Memory layout definitions for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_HEXAGON_MEM_LAYOUT_H | ||||
| #define _ASM_HEXAGON_MEM_LAYOUT_H | ||||
| 
 | ||||
| #include <linux/const.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * Have to do this for ginormous numbers, else they get printed as | ||||
|  * negative numbers, which the linker no likey when you try to | ||||
|  * assign it to the location counter. | ||||
|  */ | ||||
| 
 | ||||
| #define PAGE_OFFSET			_AC(0xc0000000, UL) | ||||
| 
 | ||||
| /*
 | ||||
|  * Compiling for a platform that needs a crazy physical offset | ||||
|  * (like if the memory starts at 1GB and up) means we need | ||||
|  * an actual PHYS_OFFSET.  Should be set up in head.S. | ||||
|  */ | ||||
| 
 | ||||
| #ifdef CONFIG_HEXAGON_PHYS_OFFSET | ||||
| #ifndef __ASSEMBLY__ | ||||
| extern unsigned long	__phys_offset; | ||||
| #endif | ||||
| #define PHYS_OFFSET	__phys_offset | ||||
| #endif | ||||
| 
 | ||||
| #ifndef PHYS_OFFSET | ||||
| #define PHYS_OFFSET	0 | ||||
| #endif | ||||
| 
 | ||||
| #define PHYS_PFN_OFFSET	(PHYS_OFFSET >> PAGE_SHIFT) | ||||
| #define ARCH_PFN_OFFSET	PHYS_PFN_OFFSET | ||||
| 
 | ||||
| #define TASK_SIZE			(PAGE_OFFSET) | ||||
| 
 | ||||
| /*  not sure how these are used yet  */ | ||||
| #define STACK_TOP			TASK_SIZE | ||||
| #define STACK_TOP_MAX			TASK_SIZE | ||||
| 
 | ||||
| #ifndef __ASSEMBLY__ | ||||
| enum fixed_addresses { | ||||
| 	FIX_KMAP_BEGIN, | ||||
| 	FIX_KMAP_END,  /*  check for per-cpuism  */ | ||||
| 	__end_of_fixed_addresses | ||||
| }; | ||||
| 
 | ||||
| #define MIN_KERNEL_SEG (PAGE_OFFSET >> PGDIR_SHIFT)   /* L1 shift is 22 bits */ | ||||
| extern int max_kernel_seg; | ||||
| 
 | ||||
| /*
 | ||||
|  * Start of vmalloc virtual address space for kernel; | ||||
|  * supposed to be based on the amount of physical memory available | ||||
|  */ | ||||
| 
 | ||||
| #define VMALLOC_START ((unsigned long) __va(high_memory + VMALLOC_OFFSET)) | ||||
| 
 | ||||
| /* Gap between physical ram and vmalloc space for guard purposes. */ | ||||
| #define VMALLOC_OFFSET PAGE_SIZE | ||||
| 
 | ||||
| /*
 | ||||
|  * Create the space between VMALLOC_START and FIXADDR_TOP backwards | ||||
|  * from the ... "top". | ||||
|  * | ||||
|  * Permanent IO mappings will live at 0xfexx_xxxx | ||||
|  * Hypervisor occupies the last 16MB page at 0xffxxxxxx | ||||
|  */ | ||||
| 
 | ||||
| #define FIXADDR_TOP     0xfe000000 | ||||
| #define FIXADDR_SIZE    (__end_of_fixed_addresses << PAGE_SHIFT) | ||||
| #define FIXADDR_START   (FIXADDR_TOP - FIXADDR_SIZE) | ||||
| 
 | ||||
| /*
 | ||||
|  * "permanent kernel mappings", defined as long-lasting mappings of | ||||
|  * high-memory page frames into the kernel address space. | ||||
|  */ | ||||
| 
 | ||||
| #define LAST_PKMAP	PTRS_PER_PTE | ||||
| #define LAST_PKMAP_MASK	(LAST_PKMAP - 1) | ||||
| #define PKMAP_NR(virt)	((virt - PKMAP_BASE) >> PAGE_SHIFT) | ||||
| #define PKMAP_ADDR(nr)	(PKMAP_BASE + ((nr) << PAGE_SHIFT)) | ||||
| 
 | ||||
| /*
 | ||||
|  * To the "left" of the fixed map space is the kmap space | ||||
|  * | ||||
|  * "Permanent Kernel Mappings"; fancy (or less fancy) PTE table | ||||
|  * that looks like it's actually walked. | ||||
|  * Need to check the alignment/shift usage; some archs use | ||||
|  * PMD_MASK on this value | ||||
|  */ | ||||
| #define PKMAP_BASE (FIXADDR_START-PAGE_SIZE*LAST_PKMAP) | ||||
| 
 | ||||
| /*
 | ||||
|  * 2 pages of guard gap between where vmalloc area ends | ||||
|  * and pkmap_base begins. | ||||
|  */ | ||||
| #define VMALLOC_END (PKMAP_BASE-PAGE_SIZE*2) | ||||
| #endif /*  !__ASSEMBLY__  */ | ||||
| 
 | ||||
| 
 | ||||
| #endif /* _ASM_HEXAGON_MEM_LAYOUT_H */ | ||||
							
								
								
									
										37
									
								
								arch/hexagon/include/asm/mmu.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								arch/hexagon/include/asm/mmu.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_MMU_H | ||||
| #define _ASM_MMU_H | ||||
| 
 | ||||
| #include <asm/vdso.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * Architecture-specific state for a mm_struct. | ||||
|  * For the Hexagon Virtual Machine, it can be a copy | ||||
|  * of the pointer to the page table base. | ||||
|  */ | ||||
| struct mm_context { | ||||
| 	unsigned long long generation; | ||||
| 	unsigned long ptbase; | ||||
| 	struct hexagon_vdso *vdso; | ||||
| }; | ||||
| 
 | ||||
| typedef struct mm_context mm_context_t; | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										100
									
								
								arch/hexagon/include/asm/mmu_context.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								arch/hexagon/include/asm/mmu_context.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,100 @@ | |||
| /*
 | ||||
|  * MM context support for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_MMU_CONTEXT_H | ||||
| #define _ASM_MMU_CONTEXT_H | ||||
| 
 | ||||
| #include <asm/setup.h> | ||||
| #include <asm/page.h> | ||||
| #include <asm/pgalloc.h> | ||||
| #include <asm/mem-layout.h> | ||||
| 
 | ||||
| static inline void destroy_context(struct mm_struct *mm) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * VM port hides all TLB management, so "lazy TLB" isn't very | ||||
|  * meaningful.  Even for ports to architectures with visble TLBs, | ||||
|  * this is almost invariably a null function. | ||||
|  */ | ||||
| static inline void enter_lazy_tlb(struct mm_struct *mm, | ||||
| 	struct task_struct *tsk) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Architecture-specific actions, if any, for memory map deactivation. | ||||
|  */ | ||||
| static inline void deactivate_mm(struct task_struct *tsk, | ||||
| 	struct mm_struct *mm) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * init_new_context - initialize context related info for new mm_struct instance | ||||
|  * @tsk: pointer to a task struct | ||||
|  * @mm: pointer to a new mm struct | ||||
|  */ | ||||
| static inline int init_new_context(struct task_struct *tsk, | ||||
| 					struct mm_struct *mm) | ||||
| { | ||||
| 	/* mm->context is set up by pgd_alloc */ | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  *  Switch active mm context | ||||
|  */ | ||||
| static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | ||||
| 				struct task_struct *tsk) | ||||
| { | ||||
| 	int l1; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * For virtual machine, we have to update system map if it's been | ||||
| 	 * touched. | ||||
| 	 */ | ||||
| 	if (next->context.generation < prev->context.generation) { | ||||
| 		for (l1 = MIN_KERNEL_SEG; l1 <= max_kernel_seg; l1++) | ||||
| 			next->pgd[l1] = init_mm.pgd[l1]; | ||||
| 
 | ||||
| 		next->context.generation = prev->context.generation; | ||||
| 	} | ||||
| 
 | ||||
| 	__vmnewmap((void *)next->context.ptbase); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  *  Activate new memory map for task | ||||
|  */ | ||||
| static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	local_irq_save(flags); | ||||
| 	switch_mm(prev, next, current_thread_info()->task); | ||||
| 	local_irq_restore(flags); | ||||
| } | ||||
| 
 | ||||
| /*  Generic hooks for arch_dup_mmap and arch_exit_mmap  */ | ||||
| #include <asm-generic/mm_hooks.h> | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										26
									
								
								arch/hexagon/include/asm/module.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								arch/hexagon/include/asm/module.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_MODULE_H | ||||
| #define _ASM_MODULE_H | ||||
| 
 | ||||
| #include <asm-generic/module.h> | ||||
| 
 | ||||
| #define MODULE_ARCH_VERMAGIC __stringify(PROCESSOR_MODEL_NAME) " " | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										8
									
								
								arch/hexagon/include/asm/mutex.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								arch/hexagon/include/asm/mutex.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| /*
 | ||||
|  * Pull in the generic implementation for the mutex fastpath. | ||||
|  * | ||||
|  * TODO: implement optimized primitives instead, or leave the generic | ||||
|  * implementation in place, or pick the atomic_xchg() based generic | ||||
|  * implementation. (see asm-generic/mutex-xchg.h for details) | ||||
|  */ | ||||
| #include <asm-generic/mutex-xchg.h> | ||||
							
								
								
									
										163
									
								
								arch/hexagon/include/asm/page.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								arch/hexagon/include/asm/page.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,163 @@ | |||
| /*
 | ||||
|  * Page management definitions for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_PAGE_H | ||||
| #define _ASM_PAGE_H | ||||
| 
 | ||||
| #include <linux/const.h> | ||||
| 
 | ||||
| /*  This is probably not the most graceful way to handle this.  */ | ||||
| 
 | ||||
| #ifdef CONFIG_PAGE_SIZE_4KB | ||||
| #define PAGE_SHIFT 12 | ||||
| #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_4KB | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_PAGE_SIZE_16KB | ||||
| #define PAGE_SHIFT 14 | ||||
| #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_16KB | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_PAGE_SIZE_64KB | ||||
| #define PAGE_SHIFT 16 | ||||
| #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_64KB | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_PAGE_SIZE_256KB | ||||
| #define PAGE_SHIFT 18 | ||||
| #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_256KB | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_PAGE_SIZE_1MB | ||||
| #define PAGE_SHIFT 20 | ||||
| #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_1MB | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  *  These should be defined in hugetlb.h, but apparently not. | ||||
|  *  "Huge" for us should be 4MB or 16MB, which are both represented | ||||
|  *  in L1 PTE's.  Right now, it's set up for 4MB. | ||||
|  */ | ||||
| #ifdef CONFIG_HUGETLB_PAGE | ||||
| #define HPAGE_SHIFT 22 | ||||
| #define HPAGE_SIZE (1UL << HPAGE_SHIFT) | ||||
| #define HPAGE_MASK (~(HPAGE_SIZE-1)) | ||||
| #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT-PAGE_SHIFT) | ||||
| #define HVM_HUGEPAGE_SIZE 0x5 | ||||
| #endif | ||||
| 
 | ||||
| #define PAGE_SIZE  (1UL << PAGE_SHIFT) | ||||
| #define PAGE_MASK  (~((1 << PAGE_SHIFT) - 1)) | ||||
| 
 | ||||
| #ifdef __KERNEL__ | ||||
| #ifndef __ASSEMBLY__ | ||||
| 
 | ||||
| /*
 | ||||
|  * This is for PFN_DOWN, which mm.h needs.  Seems the right place to pull it in. | ||||
|  */ | ||||
| #include <linux/pfn.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * We implement a two-level architecture-specific page table structure. | ||||
|  * Null intermediate page table level (pmd, pud) definitions will come from | ||||
|  * asm-generic/pagetable-nopmd.h and asm-generic/pagetable-nopud.h | ||||
|  */ | ||||
| typedef struct { unsigned long pte; } pte_t; | ||||
| typedef struct { unsigned long pgd; } pgd_t; | ||||
| typedef struct { unsigned long pgprot; } pgprot_t; | ||||
| typedef struct page *pgtable_t; | ||||
| 
 | ||||
| #define pte_val(x)     ((x).pte) | ||||
| #define pgd_val(x)     ((x).pgd) | ||||
| #define pgprot_val(x)  ((x).pgprot) | ||||
| #define __pte(x)       ((pte_t) { (x) }) | ||||
| #define __pgd(x)       ((pgd_t) { (x) }) | ||||
| #define __pgprot(x)    ((pgprot_t) { (x) }) | ||||
| 
 | ||||
| /*
 | ||||
|  * We need a __pa and a __va routine for kernel space. | ||||
|  * MIPS says they're only used during mem_init. | ||||
|  * also, check if we need a PHYS_OFFSET. | ||||
|  */ | ||||
| #define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) | ||||
| #define __va(x) ((void *)((unsigned long)(x) - PHYS_OFFSET + PAGE_OFFSET)) | ||||
| 
 | ||||
| /* The "page frame" descriptor is defined in linux/mm.h */ | ||||
| struct page; | ||||
| 
 | ||||
| /* Returns page frame descriptor for virtual address. */ | ||||
| #define virt_to_page(kaddr) pfn_to_page(PFN_DOWN(__pa(kaddr))) | ||||
| 
 | ||||
| /* Default vm area behavior is non-executable.  */ | ||||
| #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ | ||||
| 				VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | ||||
| 
 | ||||
| #define pfn_valid(pfn) ((pfn) < max_mapnr) | ||||
| #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) | ||||
| 
 | ||||
| /*  Need to not use a define for linesize; may move this to another file.  */ | ||||
| static inline void clear_page(void *page) | ||||
| { | ||||
| 	/*  This can only be done on pages with L1 WB cache */ | ||||
| 	asm volatile( | ||||
| 		"	loop0(1f,%1);\n" | ||||
| 		"1:	{ dczeroa(%0);\n" | ||||
| 		"	  %0 = add(%0,#32); }:endloop0\n" | ||||
| 		: "+r" (page) | ||||
| 		: "r" (PAGE_SIZE/32) | ||||
| 		: "lc0", "sa0", "memory" | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| #define copy_page(to, from)	memcpy((to), (from), PAGE_SIZE) | ||||
| 
 | ||||
| /*
 | ||||
|  * Under assumption that kernel always "sees" user map... | ||||
|  */ | ||||
| #define clear_user_page(page, vaddr, pg)	clear_page(page) | ||||
| #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from) | ||||
| 
 | ||||
| /*
 | ||||
|  * page_to_phys - convert page to physical address | ||||
|  * @page - pointer to page entry in mem_map | ||||
|  */ | ||||
| #define page_to_phys(page)      (page_to_pfn(page) << PAGE_SHIFT) | ||||
| 
 | ||||
| #define virt_to_pfn(kaddr)      (__pa(kaddr) >> PAGE_SHIFT) | ||||
| #define pfn_to_virt(pfn)        __va((pfn) << PAGE_SHIFT) | ||||
| 
 | ||||
| #define page_to_virt(page)	__va(page_to_phys(page)) | ||||
| 
 | ||||
| /*
 | ||||
|  * For port to Hexagon Virtual Machine, MAYBE we check for attempts | ||||
|  * to reference reserved HVM space, but in any case, the VM will be | ||||
|  * protected. | ||||
|  */ | ||||
| #define kern_addr_valid(addr)   (1) | ||||
| 
 | ||||
| #include <asm/mem-layout.h> | ||||
| #include <asm-generic/memory_model.h> | ||||
| /* XXX Todo: implement assembly-optimized version of getorder. */ | ||||
| #include <asm-generic/getorder.h> | ||||
| 
 | ||||
| #endif /* ifdef __ASSEMBLY__ */ | ||||
| #endif /* ifdef __KERNEL__ */ | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										22
									
								
								arch/hexagon/include/asm/perf_event.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								arch/hexagon/include/asm/perf_event.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_PERF_EVENT_H | ||||
| #define _ASM_PERF_EVENT_H | ||||
| 
 | ||||
| #endif /* _ASM_PERF_EVENT_H */ | ||||
							
								
								
									
										148
									
								
								arch/hexagon/include/asm/pgalloc.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								arch/hexagon/include/asm/pgalloc.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,148 @@ | |||
| /*
 | ||||
|  * Page table support for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_PGALLOC_H | ||||
| #define _ASM_PGALLOC_H | ||||
| 
 | ||||
| #include <asm/mem-layout.h> | ||||
| #include <asm/atomic.h> | ||||
| 
 | ||||
| #define check_pgt_cache() do {} while (0) | ||||
| 
 | ||||
| extern unsigned long long kmap_generation; | ||||
| 
 | ||||
| /*
 | ||||
|  * Page table creation interface | ||||
|  */ | ||||
| static inline pgd_t *pgd_alloc(struct mm_struct *mm) | ||||
| { | ||||
| 	pgd_t *pgd; | ||||
| 
 | ||||
| 	pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * There may be better ways to do this, but to ensure | ||||
| 	 * that new address spaces always contain the kernel | ||||
| 	 * base mapping, and to ensure that the user area is | ||||
| 	 * initially marked invalid, initialize the new map | ||||
| 	 * map with a copy of the kernel's persistent map. | ||||
| 	 */ | ||||
| 
 | ||||
| 	memcpy(pgd, swapper_pg_dir, PTRS_PER_PGD*sizeof(pgd_t)); | ||||
| 	mm->context.generation = kmap_generation; | ||||
| 
 | ||||
| 	/* Physical version is what is passed to virtual machine on switch */ | ||||
| 	mm->context.ptbase = __pa(pgd); | ||||
| 
 | ||||
| 	return pgd; | ||||
| } | ||||
| 
 | ||||
| static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) | ||||
| { | ||||
| 	free_page((unsigned long) pgd); | ||||
| } | ||||
| 
 | ||||
| static inline struct page *pte_alloc_one(struct mm_struct *mm, | ||||
| 					 unsigned long address) | ||||
| { | ||||
| 	struct page *pte; | ||||
| 
 | ||||
| 	pte = alloc_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO); | ||||
| 	if (!pte) | ||||
| 		return NULL; | ||||
| 	if (!pgtable_page_ctor(pte)) { | ||||
| 		__free_page(pte); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	return pte; | ||||
| } | ||||
| 
 | ||||
| /* _kernel variant gets to use a different allocator */ | ||||
| static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | ||||
| 					  unsigned long address) | ||||
| { | ||||
| 	gfp_t flags =  GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO; | ||||
| 	return (pte_t *) __get_free_page(flags); | ||||
| } | ||||
| 
 | ||||
| static inline void pte_free(struct mm_struct *mm, struct page *pte) | ||||
| { | ||||
| 	pgtable_page_dtor(pte); | ||||
| 	__free_page(pte); | ||||
| } | ||||
| 
 | ||||
| static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) | ||||
| { | ||||
| 	free_page((unsigned long)pte); | ||||
| } | ||||
| 
 | ||||
| static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, | ||||
| 				pgtable_t pte) | ||||
| { | ||||
| 	/*
 | ||||
| 	 * Conveniently, zero in 3 LSB means indirect 4K page table. | ||||
| 	 * Not so convenient when you're trying to vary the page size. | ||||
| 	 */ | ||||
| 	set_pmd(pmd, __pmd(((unsigned long)page_to_pfn(pte) << PAGE_SHIFT) | | ||||
| 		HEXAGON_L1_PTE_SIZE)); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Other architectures seem to have ways of making all processes | ||||
|  * share the same pmd's for their kernel mappings, but the v0.3 | ||||
|  * Hexagon VM spec has a "monolithic" L1 table for user and kernel | ||||
|  * segments.  We track "generations" of the kernel map to minimize | ||||
|  * overhead, and update the "slave" copies of the kernel mappings | ||||
|  * as part of switch_mm.  However, we still need to update the | ||||
|  * kernel map of the active thread who's calling pmd_populate_kernel... | ||||
|  */ | ||||
| static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, | ||||
| 				       pte_t *pte) | ||||
| { | ||||
| 	extern spinlock_t kmap_gen_lock; | ||||
| 	pmd_t *ppmd; | ||||
| 	int pmdindex; | ||||
| 
 | ||||
| 	spin_lock(&kmap_gen_lock); | ||||
| 	kmap_generation++; | ||||
| 	mm->context.generation = kmap_generation; | ||||
| 	current->active_mm->context.generation = kmap_generation; | ||||
| 	spin_unlock(&kmap_gen_lock); | ||||
| 
 | ||||
| 	set_pmd(pmd, __pmd(((unsigned long)__pa(pte)) | HEXAGON_L1_PTE_SIZE)); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Now the "slave" copy of the current thread. | ||||
| 	 * This is pointer arithmetic, not byte addresses! | ||||
| 	 */ | ||||
| 	pmdindex = (pgd_t *)pmd - mm->pgd; | ||||
| 	ppmd = (pmd_t *)current->active_mm->pgd + pmdindex; | ||||
| 	set_pmd(ppmd, __pmd(((unsigned long)__pa(pte)) | HEXAGON_L1_PTE_SIZE)); | ||||
| 	if (pmdindex > max_kernel_seg) | ||||
| 		max_kernel_seg = pmdindex; | ||||
| } | ||||
| 
 | ||||
| #define __pte_free_tlb(tlb, pte, addr)		\ | ||||
| do {						\ | ||||
| 	pgtable_page_dtor((pte));		\ | ||||
| 	tlb_remove_page((tlb), (pte));		\ | ||||
| } while (0) | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										514
									
								
								arch/hexagon/include/asm/pgtable.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										514
									
								
								arch/hexagon/include/asm/pgtable.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,514 @@ | |||
| /*
 | ||||
|  * Page table support for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_PGTABLE_H | ||||
| #define _ASM_PGTABLE_H | ||||
| 
 | ||||
| /*
 | ||||
|  * Page table definitions for Qualcomm Hexagon processor. | ||||
|  */ | ||||
| #include <linux/swap.h> | ||||
| #include <asm/page.h> | ||||
| #include <asm-generic/pgtable-nopmd.h> | ||||
| 
 | ||||
| /* A handy thing to have if one has the RAM. Declared in head.S */ | ||||
| extern unsigned long empty_zero_page; | ||||
| extern unsigned long zero_page_mask; | ||||
| 
 | ||||
| /*
 | ||||
|  * The PTE model described here is that of the Hexagon Virtual Machine, | ||||
|  * which autonomously walks 2-level page tables.  At a lower level, we | ||||
|  * also describe the RISCish software-loaded TLB entry structure of | ||||
|  * the underlying Hexagon processor. A kernel built to run on the | ||||
|  * virtual machine has no need to know about the underlying hardware. | ||||
|  */ | ||||
| #include <asm/vm_mmu.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * To maximize the comfort level for the PTE manipulation macros, | ||||
|  * define the "well known" architecture-specific bits. | ||||
|  */ | ||||
| #define _PAGE_READ	__HVM_PTE_R | ||||
| #define _PAGE_WRITE	__HVM_PTE_W | ||||
| #define _PAGE_EXECUTE	__HVM_PTE_X | ||||
| #define _PAGE_USER	__HVM_PTE_U | ||||
| 
 | ||||
| /*
 | ||||
|  * We have a total of 4 "soft" bits available in the abstract PTE. | ||||
|  * The two mandatory software bits are Dirty and Accessed. | ||||
|  * To make nonlinear swap work according to the more recent | ||||
|  * model, we want a low order "Present" bit to indicate whether | ||||
|  * the PTE describes MMU programming or swap space. | ||||
|  */ | ||||
| #define _PAGE_PRESENT	(1<<0) | ||||
| #define _PAGE_DIRTY	(1<<1) | ||||
| #define _PAGE_ACCESSED	(1<<2) | ||||
| 
 | ||||
| /*
 | ||||
|  * _PAGE_FILE is only meaningful if _PAGE_PRESENT is false, while | ||||
|  * _PAGE_DIRTY is only meaningful if _PAGE_PRESENT is true. | ||||
|  * So we can overload the bit... | ||||
|  */ | ||||
| #define _PAGE_FILE	_PAGE_DIRTY /* set:  pagecache, unset = swap */ | ||||
| 
 | ||||
| /*
 | ||||
|  * For now, let's say that Valid and Present are the same thing. | ||||
|  * Alternatively, we could say that it's the "or" of R, W, and X | ||||
|  * permissions. | ||||
|  */ | ||||
| #define _PAGE_VALID	_PAGE_PRESENT | ||||
| 
 | ||||
| /*
 | ||||
|  * We're not defining _PAGE_GLOBAL here, since there's no concept | ||||
|  * of global pages or ASIDs exposed to the Hexagon Virtual Machine, | ||||
|  * and we want to use the same page table structures and macros in | ||||
|  * the native kernel as we do in the virtual machine kernel. | ||||
|  * So we'll put up with a bit of inefficiency for now... | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Top "FOURTH" level (pgd), which for the Hexagon VM is really | ||||
|  * only the second from the bottom, pgd and pud both being collapsed. | ||||
|  * Each entry represents 4MB of virtual address space, 4K of table | ||||
|  * thus maps the full 4GB. | ||||
|  */ | ||||
| #define PGDIR_SHIFT 22 | ||||
| #define PTRS_PER_PGD 1024 | ||||
| 
 | ||||
| #define PGDIR_SIZE (1UL << PGDIR_SHIFT) | ||||
| #define PGDIR_MASK (~(PGDIR_SIZE-1)) | ||||
| 
 | ||||
| #ifdef CONFIG_PAGE_SIZE_4KB | ||||
| #define PTRS_PER_PTE 1024 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_PAGE_SIZE_16KB | ||||
| #define PTRS_PER_PTE 256 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_PAGE_SIZE_64KB | ||||
| #define PTRS_PER_PTE 64 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_PAGE_SIZE_256KB | ||||
| #define PTRS_PER_PTE 16 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_PAGE_SIZE_1MB | ||||
| #define PTRS_PER_PTE 4 | ||||
| #endif | ||||
| 
 | ||||
| /*  Any bigger and the PTE disappears.  */ | ||||
| #define pgd_ERROR(e) \ | ||||
| 	printk(KERN_ERR "%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__,\ | ||||
| 		pgd_val(e)) | ||||
| 
 | ||||
| /*
 | ||||
|  * Page Protection Constants. Includes (in this variant) cache attributes. | ||||
|  */ | ||||
| extern unsigned long _dflt_cache_att; | ||||
| 
 | ||||
| #define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_USER | \ | ||||
| 				_dflt_cache_att) | ||||
| #define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_USER | \ | ||||
| 				_PAGE_READ | _PAGE_EXECUTE | _dflt_cache_att) | ||||
| #define PAGE_COPY	PAGE_READONLY | ||||
| #define PAGE_EXEC	__pgprot(_PAGE_PRESENT | _PAGE_USER | \ | ||||
| 				_PAGE_READ | _PAGE_EXECUTE | _dflt_cache_att) | ||||
| #define PAGE_COPY_EXEC	PAGE_EXEC | ||||
| #define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | \ | ||||
| 				_PAGE_EXECUTE | _PAGE_WRITE | _dflt_cache_att) | ||||
| #define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | _PAGE_READ | \ | ||||
| 				_PAGE_WRITE | _PAGE_EXECUTE | _dflt_cache_att) | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * Aliases for mapping mmap() protection bits to page protections. | ||||
|  * These get used for static initialization, so using the _dflt_cache_att | ||||
|  * variable for the default cache attribute isn't workable. If the | ||||
|  * default gets changed at boot time, the boot option code has to | ||||
|  * update data structures like the protaction_map[] array. | ||||
|  */ | ||||
| #define CACHEDEF	(CACHE_DEFAULT << 6) | ||||
| 
 | ||||
| /* Private (copy-on-write) page protections. */ | ||||
| #define __P000 __pgprot(_PAGE_PRESENT | _PAGE_USER | CACHEDEF) | ||||
| #define __P001 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | CACHEDEF) | ||||
| #define __P010 __P000	/* Write-only copy-on-write */ | ||||
| #define __P011 __P001	/* Read/Write copy-on-write */ | ||||
| #define __P100 __pgprot(_PAGE_PRESENT | _PAGE_USER | \ | ||||
| 			_PAGE_EXECUTE | CACHEDEF) | ||||
| #define __P101 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_EXECUTE | \ | ||||
| 			_PAGE_READ | CACHEDEF) | ||||
| #define __P110 __P100	/* Write/execute copy-on-write */ | ||||
| #define __P111 __P101	/* Read/Write/Execute, copy-on-write */ | ||||
| 
 | ||||
| /* Shared page protections. */ | ||||
| #define __S000 __P000 | ||||
| #define __S001 __P001 | ||||
| #define __S010 __pgprot(_PAGE_PRESENT | _PAGE_USER | \ | ||||
| 			_PAGE_WRITE | CACHEDEF) | ||||
| #define __S011 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | \ | ||||
| 			_PAGE_WRITE | CACHEDEF) | ||||
| #define __S100 __pgprot(_PAGE_PRESENT | _PAGE_USER | \ | ||||
| 			_PAGE_EXECUTE | CACHEDEF) | ||||
| #define __S101 __P101 | ||||
| #define __S110 __pgprot(_PAGE_PRESENT | _PAGE_USER | \ | ||||
| 			_PAGE_EXECUTE | _PAGE_WRITE | CACHEDEF) | ||||
| #define __S111 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | \ | ||||
| 			_PAGE_EXECUTE | _PAGE_WRITE | CACHEDEF) | ||||
| 
 | ||||
| extern pgd_t swapper_pg_dir[PTRS_PER_PGD];  /* located in head.S */ | ||||
| 
 | ||||
| /* Seems to be zero even in architectures where the zero page is firewalled? */ | ||||
| #define FIRST_USER_ADDRESS 0 | ||||
| #define pte_special(pte)	0 | ||||
| #define pte_mkspecial(pte)	(pte) | ||||
| 
 | ||||
| /*  HUGETLB not working currently  */ | ||||
| #ifdef CONFIG_HUGETLB_PAGE | ||||
| #define pte_mkhuge(pte) __pte((pte_val(pte) & ~0x3) | HVM_HUGEPAGE_SIZE) | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * For now, assume that higher-level code will do TLB/MMU invalidations | ||||
|  * and don't insert that overhead into this low-level function. | ||||
|  */ | ||||
| extern void sync_icache_dcache(pte_t pte); | ||||
| 
 | ||||
| #define pte_present_exec_user(pte) \ | ||||
| 	((pte_val(pte) & (_PAGE_EXECUTE | _PAGE_USER)) == \ | ||||
| 	(_PAGE_EXECUTE | _PAGE_USER)) | ||||
| 
 | ||||
| static inline void set_pte(pte_t *ptep, pte_t pteval) | ||||
| { | ||||
| 	/*  should really be using pte_exec, if it weren't declared later. */ | ||||
| 	if (pte_present_exec_user(pteval)) | ||||
| 		sync_icache_dcache(pteval); | ||||
| 
 | ||||
| 	*ptep = pteval; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * For the Hexagon Virtual Machine MMU (or its emulation), a null/invalid | ||||
|  * L1 PTE (PMD/PGD) has 7 in the least significant bits. For the L2 PTE | ||||
|  * (Linux PTE), the key is to have bits 11..9 all zero.  We'd use 0x7 | ||||
|  * as a universal null entry, but some of those least significant bits | ||||
|  * are interpreted by software. | ||||
|  */ | ||||
| #define _NULL_PMD	0x7 | ||||
| #define _NULL_PTE	0x0 | ||||
| 
 | ||||
| static inline void pmd_clear(pmd_t *pmd_entry_ptr) | ||||
| { | ||||
| 	 pmd_val(*pmd_entry_ptr) = _NULL_PMD; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Conveniently, a null PTE value is invalid. | ||||
|  */ | ||||
| static inline void pte_clear(struct mm_struct *mm, unsigned long addr, | ||||
| 				pte_t *ptep) | ||||
| { | ||||
| 	pte_val(*ptep) = _NULL_PTE; | ||||
| } | ||||
| 
 | ||||
| #ifdef NEED_PMD_INDEX_DESPITE_BEING_2_LEVEL | ||||
| /**
 | ||||
|  * pmd_index - returns the index of the entry in the PMD page | ||||
|  * which would control the given virtual address | ||||
|  */ | ||||
| #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| /**
 | ||||
|  * pgd_index - returns the index of the entry in the PGD page | ||||
|  * which would control the given virtual address | ||||
|  * | ||||
|  * This returns the *index* for the address in the pgd_t | ||||
|  */ | ||||
| #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) | ||||
| 
 | ||||
| /*
 | ||||
|  * pgd_offset - find an offset in a page-table-directory | ||||
|  */ | ||||
| #define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr)) | ||||
| 
 | ||||
| /*
 | ||||
|  * pgd_offset_k - get kernel (init_mm) pgd entry pointer for addr | ||||
|  */ | ||||
| #define pgd_offset_k(address) pgd_offset(&init_mm, address) | ||||
| 
 | ||||
| /**
 | ||||
|  * pmd_none - check if pmd_entry is mapped | ||||
|  * @pmd_entry:  pmd entry | ||||
|  * | ||||
|  * MIPS checks it against that "invalid pte table" thing. | ||||
|  */ | ||||
| static inline int pmd_none(pmd_t pmd) | ||||
| { | ||||
| 	return pmd_val(pmd) == _NULL_PMD; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * pmd_present - is there a page table behind this? | ||||
|  * Essentially the inverse of pmd_none.  We maybe | ||||
|  * save an inline instruction by defining it this | ||||
|  * way, instead of simply "!pmd_none". | ||||
|  */ | ||||
| static inline int pmd_present(pmd_t pmd) | ||||
| { | ||||
| 	return pmd_val(pmd) != (unsigned long)_NULL_PMD; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * pmd_bad - check if a PMD entry is "bad". That might mean swapped out. | ||||
|  * As we have no known cause of badness, it's null, as it is for many | ||||
|  * architectures. | ||||
|  */ | ||||
| static inline int pmd_bad(pmd_t pmd) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * pmd_page - converts a PMD entry to a page pointer | ||||
|  */ | ||||
| #define pmd_page(pmd)  (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) | ||||
| #define pmd_pgtable(pmd) pmd_page(pmd) | ||||
| 
 | ||||
| /**
 | ||||
|  * pte_none - check if pte is mapped | ||||
|  * @pte: pte_t entry | ||||
|  */ | ||||
| static inline int pte_none(pte_t pte) | ||||
| { | ||||
| 	return pte_val(pte) == _NULL_PTE; | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * pte_present - check if page is present | ||||
|  */ | ||||
| static inline int pte_present(pte_t pte) | ||||
| { | ||||
| 	return pte_val(pte) & _PAGE_PRESENT; | ||||
| } | ||||
| 
 | ||||
| /* mk_pte - make a PTE out of a page pointer and protection bits */ | ||||
| #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) | ||||
| 
 | ||||
| /* pte_page - returns a page (frame pointer/descriptor?) based on a PTE */ | ||||
| #define pte_page(x) pfn_to_page(pte_pfn(x)) | ||||
| 
 | ||||
| /* pte_mkold - mark PTE as not recently accessed */ | ||||
| static inline pte_t pte_mkold(pte_t pte) | ||||
| { | ||||
| 	pte_val(pte) &= ~_PAGE_ACCESSED; | ||||
| 	return pte; | ||||
| } | ||||
| 
 | ||||
| /* pte_mkyoung - mark PTE as recently accessed */ | ||||
| static inline pte_t pte_mkyoung(pte_t pte) | ||||
| { | ||||
| 	pte_val(pte) |= _PAGE_ACCESSED; | ||||
| 	return pte; | ||||
| } | ||||
| 
 | ||||
| /* pte_mkclean - mark page as in sync with backing store */ | ||||
| static inline pte_t pte_mkclean(pte_t pte) | ||||
| { | ||||
| 	pte_val(pte) &= ~_PAGE_DIRTY; | ||||
| 	return pte; | ||||
| } | ||||
| 
 | ||||
| /* pte_mkdirty - mark page as modified */ | ||||
| static inline pte_t pte_mkdirty(pte_t pte) | ||||
| { | ||||
| 	pte_val(pte) |= _PAGE_DIRTY; | ||||
| 	return pte; | ||||
| } | ||||
| 
 | ||||
| /* pte_young - "is PTE marked as accessed"? */ | ||||
| static inline int pte_young(pte_t pte) | ||||
| { | ||||
| 	return pte_val(pte) & _PAGE_ACCESSED; | ||||
| } | ||||
| 
 | ||||
| /* pte_dirty - "is PTE dirty?" */ | ||||
| static inline int pte_dirty(pte_t pte) | ||||
| { | ||||
| 	return pte_val(pte) & _PAGE_DIRTY; | ||||
| } | ||||
| 
 | ||||
| /* pte_modify - set protection bits on PTE */ | ||||
| static inline pte_t pte_modify(pte_t pte, pgprot_t prot) | ||||
| { | ||||
| 	pte_val(pte) &= PAGE_MASK; | ||||
| 	pte_val(pte) |= pgprot_val(prot); | ||||
| 	return pte; | ||||
| } | ||||
| 
 | ||||
| /* pte_wrprotect - mark page as not writable */ | ||||
| static inline pte_t pte_wrprotect(pte_t pte) | ||||
| { | ||||
| 	pte_val(pte) &= ~_PAGE_WRITE; | ||||
| 	return pte; | ||||
| } | ||||
| 
 | ||||
| /* pte_mkwrite - mark page as writable */ | ||||
| static inline pte_t pte_mkwrite(pte_t pte) | ||||
| { | ||||
| 	pte_val(pte) |= _PAGE_WRITE; | ||||
| 	return pte; | ||||
| } | ||||
| 
 | ||||
| /* pte_mkexec - mark PTE as executable */ | ||||
| static inline pte_t pte_mkexec(pte_t pte) | ||||
| { | ||||
| 	pte_val(pte) |= _PAGE_EXECUTE; | ||||
| 	return pte; | ||||
| } | ||||
| 
 | ||||
| /* pte_read - "is PTE marked as readable?" */ | ||||
| static inline int pte_read(pte_t pte) | ||||
| { | ||||
| 	return pte_val(pte) & _PAGE_READ; | ||||
| } | ||||
| 
 | ||||
| /* pte_write - "is PTE marked as writable?" */ | ||||
| static inline int pte_write(pte_t pte) | ||||
| { | ||||
| 	return pte_val(pte) & _PAGE_WRITE; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* pte_exec - "is PTE marked as executable?" */ | ||||
| static inline int pte_exec(pte_t pte) | ||||
| { | ||||
| 	return pte_val(pte) & _PAGE_EXECUTE; | ||||
| } | ||||
| 
 | ||||
| /* __pte_to_swp_entry - extract swap entry from PTE */ | ||||
| #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) | ||||
| 
 | ||||
| /* __swp_entry_to_pte - extract PTE from swap entry */ | ||||
| #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) | ||||
| 
 | ||||
| /* pfn_pte - convert page number and protection value to page table entry */ | ||||
| #define pfn_pte(pfn, pgprot) __pte((pfn << PAGE_SHIFT) | pgprot_val(pgprot)) | ||||
| 
 | ||||
| /* pte_pfn - convert pte to page frame number */ | ||||
| #define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) | ||||
| #define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval)) | ||||
| 
 | ||||
| /*
 | ||||
|  * set_pte_at - update page table and do whatever magic may be | ||||
|  * necessary to make the underlying hardware/firmware take note. | ||||
|  * | ||||
|  * VM may require a virtual instruction to alert the MMU. | ||||
|  */ | ||||
| #define set_pte_at(mm, addr, ptep, pte) set_pte(ptep, pte) | ||||
| 
 | ||||
| /*
 | ||||
|  * May need to invoke the virtual machine as well... | ||||
|  */ | ||||
| #define pte_unmap(pte)		do { } while (0) | ||||
| #define pte_unmap_nested(pte)	do { } while (0) | ||||
| 
 | ||||
| /*
 | ||||
|  * pte_offset_map - returns the linear address of the page table entry | ||||
|  * corresponding to an address | ||||
|  */ | ||||
| #define pte_offset_map(dir, address)                                    \ | ||||
| 	((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) | ||||
| 
 | ||||
| #define pte_offset_map_nested(pmd, addr) pte_offset_map(pmd, addr) | ||||
| 
 | ||||
| /* pte_offset_kernel - kernel version of pte_offset */ | ||||
| #define pte_offset_kernel(dir, address) \ | ||||
| 	((pte_t *) (unsigned long) __va(pmd_val(*dir) & PAGE_MASK) \ | ||||
| 				+  __pte_offset(address)) | ||||
| 
 | ||||
| /* ZERO_PAGE - returns the globally shared zero page */ | ||||
| #define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page)) | ||||
| 
 | ||||
| #define __pte_offset(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) | ||||
| 
 | ||||
| /*  I think this is in case we have page table caches; needed by init/main.c  */ | ||||
| #define pgtable_cache_init()    do { } while (0) | ||||
| 
 | ||||
| /*
 | ||||
|  * Swap/file PTE definitions.  If _PAGE_PRESENT is zero, the rest of the | ||||
|  * PTE is interpreted as swap information.  Depending on the _PAGE_FILE | ||||
|  * bit, the remaining free bits are eitehr interpreted as a file offset | ||||
|  * or a swap type/offset tuple.  Rather than have the TLB fill handler | ||||
|  * test _PAGE_PRESENT, we're going to reserve the permissions bits | ||||
|  * and set them to all zeros for swap entries, which speeds up the | ||||
|  * miss handler at the cost of 3 bits of offset.  That trade-off can | ||||
|  * be revisited if necessary, but Hexagon processor architecture and | ||||
|  * target applications suggest a lot of TLB misses and not much swap space. | ||||
|  * | ||||
|  * Format of swap PTE: | ||||
|  *	bit	0:	Present (zero) | ||||
|  *	bit	1:	_PAGE_FILE (zero) | ||||
|  *	bits	2-6:	swap type (arch independent layer uses 5 bits max) | ||||
|  *	bits	7-9:	bits 2:0 of offset | ||||
|  *	bits 10-12:	effectively _PAGE_PROTNONE (all zero) | ||||
|  *	bits 13-31:  bits 21:3 of swap offset | ||||
|  * | ||||
|  * Format of file PTE: | ||||
|  *	bit	0:	Present (zero) | ||||
|  *	bit	1:	_PAGE_FILE (zero) | ||||
|  *	bits	2-9:	bits 7:0 of offset | ||||
|  *	bits 10-12:	effectively _PAGE_PROTNONE (all zero) | ||||
|  *	bits 13-31:  bits 26:8 of swap offset | ||||
|  * | ||||
|  * The split offset makes some of the following macros a little gnarly, | ||||
|  * but there's plenty of precedent for this sort of thing. | ||||
|  */ | ||||
| #define PTE_FILE_MAX_BITS     27 | ||||
| 
 | ||||
| /* Used for swap PTEs */ | ||||
| #define __swp_type(swp_pte)		(((swp_pte).val >> 2) & 0x1f) | ||||
| 
 | ||||
| #define __swp_offset(swp_pte) \ | ||||
| 	((((swp_pte).val >> 7) & 0x7) | (((swp_pte).val >> 10) & 0x003ffff8)) | ||||
| 
 | ||||
| #define __swp_entry(type, offset) \ | ||||
| 	((swp_entry_t)	{ \ | ||||
| 		((type << 2) | \ | ||||
| 		 ((offset & 0x3ffff8) << 10) | ((offset & 0x7) << 7)) }) | ||||
| 
 | ||||
| /* Used for file PTEs */ | ||||
| #define pte_file(pte) \ | ||||
| 	((pte_val(pte) & (_PAGE_FILE | _PAGE_PRESENT)) == _PAGE_FILE) | ||||
| 
 | ||||
| #define pte_to_pgoff(pte) \ | ||||
| 	(((pte_val(pte) >> 2) & 0xff) | ((pte_val(pte) >> 5) & 0x07ffff00)) | ||||
| 
 | ||||
| #define pgoff_to_pte(off) \ | ||||
| 	((pte_t) { ((((off) & 0x7ffff00) << 5) | (((off) & 0xff) << 2)\ | ||||
| 	| _PAGE_FILE) }) | ||||
| 
 | ||||
| /*  Oh boy.  There are a lot of possible arch overrides found in this file.  */ | ||||
| #include <asm-generic/pgtable.h> | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										153
									
								
								arch/hexagon/include/asm/processor.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								arch/hexagon/include/asm/processor.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,153 @@ | |||
| /*
 | ||||
|  * Process/processor support for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_PROCESSOR_H | ||||
| #define _ASM_PROCESSOR_H | ||||
| 
 | ||||
| #ifndef __ASSEMBLY__ | ||||
| 
 | ||||
| #include <asm/mem-layout.h> | ||||
| #include <asm/registers.h> | ||||
| #include <asm/hexagon_vm.h> | ||||
| 
 | ||||
| /*  must be a macro  */ | ||||
| #define current_text_addr() ({ __label__ _l; _l: &&_l; }) | ||||
| 
 | ||||
| /*  task_struct, defined elsewhere, is the "process descriptor" */ | ||||
| struct task_struct; | ||||
| 
 | ||||
| /*  this is defined in arch/process.c  */ | ||||
| extern unsigned long thread_saved_pc(struct task_struct *tsk); | ||||
| 
 | ||||
| extern void start_thread(struct pt_regs *, unsigned long, unsigned long); | ||||
| 
 | ||||
| /*
 | ||||
|  * thread_struct is supposed to be for context switch data. | ||||
|  * Specifically, to hold the state necessary to perform switch_to... | ||||
|  */ | ||||
| struct thread_struct { | ||||
| 	void *switch_sp; | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * initializes thread_struct | ||||
|  * The only thing we have in there is switch_sp | ||||
|  * which doesn't really need to be initialized. | ||||
|  */ | ||||
| 
 | ||||
| #define INIT_THREAD { \ | ||||
| } | ||||
| 
 | ||||
| #define cpu_relax() __vmyield() | ||||
| #define cpu_relax_lowlatency() cpu_relax() | ||||
| 
 | ||||
| /*
 | ||||
|  * Decides where the kernel will search for a free chunk of vm space during | ||||
|  * mmaps. | ||||
|  * See also arch_get_unmapped_area. | ||||
|  * Doesn't affect if you have MAX_FIXED in the page flags set though... | ||||
|  * | ||||
|  * Apparently the convention is that ld.so will ask for "unmapped" private | ||||
|  * memory to be allocated SOMEWHERE, but it also asks for memory explicitly | ||||
|  * via MAP_FIXED at the lower * addresses starting at VA=0x0. | ||||
|  * | ||||
|  * If the two requests collide, you get authentic segfaulting action, so | ||||
|  * you have to kick the "unmapped" base requests higher up. | ||||
|  */ | ||||
| #define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE/3)) | ||||
| 
 | ||||
| 
 | ||||
| #define task_pt_regs(task) \ | ||||
| 	((struct pt_regs *)(task_stack_page(task) + THREAD_SIZE) - 1) | ||||
| 
 | ||||
| #define KSTK_EIP(tsk) (pt_elr(task_pt_regs(tsk))) | ||||
| #define KSTK_ESP(tsk) (pt_psp(task_pt_regs(tsk))) | ||||
| 
 | ||||
| /*  Free all resources held by a thread; defined in process.c  */ | ||||
| extern void release_thread(struct task_struct *dead_task); | ||||
| 
 | ||||
| /* Get wait channel for task P.  */ | ||||
| extern unsigned long get_wchan(struct task_struct *p); | ||||
| 
 | ||||
| /*  The following stuff is pretty HEXAGON specific.  */ | ||||
| 
 | ||||
| /*  This is really just here for __switch_to.
 | ||||
|     Offsets are pulled via asm-offsets.c  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * No real reason why VM and native switch stacks should be different. | ||||
|  * Ultimately this should merge.  Note that Rev C. ABI called out only | ||||
|  * R24-27 as callee saved GPRs needing explicit attention (R29-31 being | ||||
|  * dealt with automagically by allocframe), but the current ABI has | ||||
|  * more, R16-R27.  By saving more, the worst case is that we waste some | ||||
|  * cycles if building with the old compilers. | ||||
|  */ | ||||
| 
 | ||||
| struct hexagon_switch_stack { | ||||
| 	union { | ||||
| 		struct { | ||||
| 			unsigned long r16; | ||||
| 			unsigned long r17; | ||||
| 		}; | ||||
| 		unsigned long long	r1716; | ||||
| 	}; | ||||
| 	union { | ||||
| 		struct { | ||||
| 			unsigned long r18; | ||||
| 			unsigned long r19; | ||||
| 		}; | ||||
| 		unsigned long long	r1918; | ||||
| 	}; | ||||
| 	union { | ||||
| 		struct { | ||||
| 			unsigned long r20; | ||||
| 			unsigned long r21; | ||||
| 		}; | ||||
| 		unsigned long long	r2120; | ||||
| 	}; | ||||
| 	union { | ||||
| 		struct { | ||||
| 			unsigned long r22; | ||||
| 			unsigned long r23; | ||||
| 		}; | ||||
| 		unsigned long long	r2322; | ||||
| 	}; | ||||
| 	union { | ||||
| 		struct { | ||||
| 			unsigned long r24; | ||||
| 			unsigned long r25; | ||||
| 		}; | ||||
| 		unsigned long long	r2524; | ||||
| 	}; | ||||
| 	union { | ||||
| 		struct { | ||||
| 			unsigned long r26; | ||||
| 			unsigned long r27; | ||||
| 		}; | ||||
| 		unsigned long long	r2726; | ||||
| 	}; | ||||
| 
 | ||||
| 	unsigned long		fp; | ||||
| 	unsigned long		lr; | ||||
| }; | ||||
| 
 | ||||
| #endif /* !__ASSEMBLY__ */ | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										43
									
								
								arch/hexagon/include/asm/smp.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								arch/hexagon/include/asm/smp.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | |||
| /*
 | ||||
|  * SMP definitions for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __ASM_SMP_H | ||||
| #define __ASM_SMP_H | ||||
| 
 | ||||
| #include <linux/cpumask.h> | ||||
| 
 | ||||
| #define raw_smp_processor_id() (current_thread_info()->cpu) | ||||
| 
 | ||||
| enum ipi_message_type { | ||||
| 	IPI_NOP = 0, | ||||
| 	IPI_RESCHEDULE = 1, | ||||
| 	IPI_CALL_FUNC, | ||||
| 	IPI_CPU_STOP, | ||||
| 	IPI_TIMER, | ||||
| }; | ||||
| 
 | ||||
| extern void send_ipi(const struct cpumask *cpumask, enum ipi_message_type msg); | ||||
| extern void smp_start_cpus(void); | ||||
| extern void arch_send_call_function_single_ipi(int cpu); | ||||
| extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); | ||||
| 
 | ||||
| extern void smp_vm_unmask_irq(void *info); | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										186
									
								
								arch/hexagon/include/asm/spinlock.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								arch/hexagon/include/asm/spinlock.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,186 @@ | |||
| /*
 | ||||
|  * Spinlock support for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_SPINLOCK_H | ||||
| #define _ASM_SPINLOCK_H | ||||
| 
 | ||||
| #include <asm/irqflags.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * This file is pulled in for SMP builds. | ||||
|  * Really need to check all the barrier stuff for "true" SMP | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Read locks: | ||||
|  * - load the lock value | ||||
|  * - increment it | ||||
|  * - if the lock value is still negative, go back and try again. | ||||
|  * - unsuccessful store is unsuccessful.  Go back and try again.  Loser. | ||||
|  * - successful store new lock value if positive -> lock acquired | ||||
|  */ | ||||
| static inline void arch_read_lock(arch_rwlock_t *lock) | ||||
| { | ||||
| 	__asm__ __volatile__( | ||||
| 		"1:	R6 = memw_locked(%0);\n" | ||||
| 		"	{ P3 = cmp.ge(R6,#0); R6 = add(R6,#1);}\n" | ||||
| 		"	{ if !P3 jump 1b; }\n" | ||||
| 		"	memw_locked(%0,P3) = R6;\n" | ||||
| 		"	{ if !P3 jump 1b; }\n" | ||||
| 		: | ||||
| 		: "r" (&lock->lock) | ||||
| 		: "memory", "r6", "p3" | ||||
| 	); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static inline void arch_read_unlock(arch_rwlock_t *lock) | ||||
| { | ||||
| 	__asm__ __volatile__( | ||||
| 		"1:	R6 = memw_locked(%0);\n" | ||||
| 		"	R6 = add(R6,#-1);\n" | ||||
| 		"	memw_locked(%0,P3) = R6\n" | ||||
| 		"	if !P3 jump 1b;\n" | ||||
| 		: | ||||
| 		: "r" (&lock->lock) | ||||
| 		: "memory", "r6", "p3" | ||||
| 	); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /*  I think this returns 0 on fail, 1 on success.  */ | ||||
| static inline int arch_read_trylock(arch_rwlock_t *lock) | ||||
| { | ||||
| 	int temp; | ||||
| 	__asm__ __volatile__( | ||||
| 		"	R6 = memw_locked(%1);\n" | ||||
| 		"	{ %0 = #0; P3 = cmp.ge(R6,#0); R6 = add(R6,#1);}\n" | ||||
| 		"	{ if !P3 jump 1f; }\n" | ||||
| 		"	memw_locked(%1,P3) = R6;\n" | ||||
| 		"	{ %0 = P3 }\n" | ||||
| 		"1:\n" | ||||
| 		: "=&r" (temp) | ||||
| 		: "r" (&lock->lock) | ||||
| 		: "memory", "r6", "p3" | ||||
| 	); | ||||
| 	return temp; | ||||
| } | ||||
| 
 | ||||
| static inline int arch_read_can_lock(arch_rwlock_t *rwlock) | ||||
| { | ||||
| 	return rwlock->lock == 0; | ||||
| } | ||||
| 
 | ||||
| static inline int arch_write_can_lock(arch_rwlock_t *rwlock) | ||||
| { | ||||
| 	return rwlock->lock == 0; | ||||
| } | ||||
| 
 | ||||
| /*  Stuffs a -1 in the lock value?  */ | ||||
| static inline void arch_write_lock(arch_rwlock_t *lock) | ||||
| { | ||||
| 	__asm__ __volatile__( | ||||
| 		"1:	R6 = memw_locked(%0)\n" | ||||
| 		"	{ P3 = cmp.eq(R6,#0);  R6 = #-1;}\n" | ||||
| 		"	{ if !P3 jump 1b; }\n" | ||||
| 		"	memw_locked(%0,P3) = R6;\n" | ||||
| 		"	{ if !P3 jump 1b; }\n" | ||||
| 		: | ||||
| 		: "r" (&lock->lock) | ||||
| 		: "memory", "r6", "p3" | ||||
| 	); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static inline int arch_write_trylock(arch_rwlock_t *lock) | ||||
| { | ||||
| 	int temp; | ||||
| 	__asm__ __volatile__( | ||||
| 		"	R6 = memw_locked(%1)\n" | ||||
| 		"	{ %0 = #0; P3 = cmp.eq(R6,#0);  R6 = #-1;}\n" | ||||
| 		"	{ if !P3 jump 1f; }\n" | ||||
| 		"	memw_locked(%1,P3) = R6;\n" | ||||
| 		"	%0 = P3;\n" | ||||
| 		"1:\n" | ||||
| 		: "=&r" (temp) | ||||
| 		: "r" (&lock->lock) | ||||
| 		: "memory", "r6", "p3" | ||||
| 	); | ||||
| 	return temp; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static inline void arch_write_unlock(arch_rwlock_t *lock) | ||||
| { | ||||
| 	smp_mb(); | ||||
| 	lock->lock = 0; | ||||
| } | ||||
| 
 | ||||
| static inline void arch_spin_lock(arch_spinlock_t *lock) | ||||
| { | ||||
| 	__asm__ __volatile__( | ||||
| 		"1:	R6 = memw_locked(%0);\n" | ||||
| 		"	P3 = cmp.eq(R6,#0);\n" | ||||
| 		"	{ if !P3 jump 1b; R6 = #1; }\n" | ||||
| 		"	memw_locked(%0,P3) = R6;\n" | ||||
| 		"	{ if !P3 jump 1b; }\n" | ||||
| 		: | ||||
| 		: "r" (&lock->lock) | ||||
| 		: "memory", "r6", "p3" | ||||
| 	); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static inline void arch_spin_unlock(arch_spinlock_t *lock) | ||||
| { | ||||
| 	smp_mb(); | ||||
| 	lock->lock = 0; | ||||
| } | ||||
| 
 | ||||
| static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) | ||||
| { | ||||
| 	int temp; | ||||
| 	__asm__ __volatile__( | ||||
| 		"	R6 = memw_locked(%1);\n" | ||||
| 		"	P3 = cmp.eq(R6,#0);\n" | ||||
| 		"	{ if !P3 jump 1f; R6 = #1; %0 = #0; }\n" | ||||
| 		"	memw_locked(%1,P3) = R6;\n" | ||||
| 		"	%0 = P3;\n" | ||||
| 		"1:\n" | ||||
| 		: "=&r" (temp) | ||||
| 		: "r" (&lock->lock) | ||||
| 		: "memory", "r6", "p3" | ||||
| 	); | ||||
| 	return temp; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * SMP spinlocks are intended to allow only a single CPU at the lock | ||||
|  */ | ||||
| #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) | ||||
| #define arch_spin_unlock_wait(lock) \ | ||||
| 	do {while (arch_spin_is_locked(lock)) cpu_relax(); } while (0) | ||||
| #define arch_spin_is_locked(x) ((x)->lock != 0) | ||||
| 
 | ||||
| #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) | ||||
| #define arch_write_lock_flags(lock, flags) arch_write_lock(lock) | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										40
									
								
								arch/hexagon/include/asm/spinlock_types.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								arch/hexagon/include/asm/spinlock_types.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | |||
| /*
 | ||||
|  * Spinlock support for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_SPINLOCK_TYPES_H | ||||
| #define _ASM_SPINLOCK_TYPES_H | ||||
| 
 | ||||
| #ifndef __LINUX_SPINLOCK_TYPES_H | ||||
| # error "please don't include this file directly" | ||||
| #endif | ||||
| 
 | ||||
| typedef struct { | ||||
| 	volatile unsigned int lock; | ||||
| } arch_spinlock_t; | ||||
| 
 | ||||
| #define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 } | ||||
| 
 | ||||
| typedef struct { | ||||
| 	volatile unsigned int lock; | ||||
| } arch_rwlock_t; | ||||
| 
 | ||||
| #define __ARCH_RW_LOCK_UNLOCKED		{ 0 } | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										32
									
								
								arch/hexagon/include/asm/string.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								arch/hexagon/include/asm/string.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_STRING_H_ | ||||
| #define _ASM_STRING_H_ | ||||
| 
 | ||||
| #ifdef __KERNEL__ | ||||
| #define __HAVE_ARCH_MEMCPY | ||||
| extern void *memcpy(void *__to, __const__ void *__from, size_t __n); | ||||
| 
 | ||||
| /*  ToDo:  use dczeroa, accelerate the compiler-constant zero case  */ | ||||
| #define __HAVE_ARCH_MEMSET | ||||
| extern void *memset(void *__to, int c, size_t __n); | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #endif /* _ASM_STRING_H_ */ | ||||
							
								
								
									
										27
									
								
								arch/hexagon/include/asm/suspend.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								arch/hexagon/include/asm/suspend.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_SUSPEND_H | ||||
| #define _ASM_SUSPEND_H | ||||
| 
 | ||||
| static inline int arch_prepare_suspend(void) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										34
									
								
								arch/hexagon/include/asm/switch_to.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								arch/hexagon/include/asm/switch_to.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| /*
 | ||||
|  * Task switching definitions for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_SWITCH_TO_H | ||||
| #define _ASM_SWITCH_TO_H | ||||
| 
 | ||||
| struct thread_struct; | ||||
| 
 | ||||
| extern struct task_struct *__switch_to(struct task_struct *, | ||||
| 	struct task_struct *, | ||||
| 	struct task_struct *); | ||||
| 
 | ||||
| #define switch_to(p, n, r) do {\ | ||||
| 	r = __switch_to((p), (n), (r));\ | ||||
| } while (0) | ||||
| 
 | ||||
| #endif /* _ASM_SWITCH_TO_H */ | ||||
							
								
								
									
										46
									
								
								arch/hexagon/include/asm/syscall.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								arch/hexagon/include/asm/syscall.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | |||
| /*
 | ||||
|  * Syscall support for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_HEXAGON_SYSCALL_H | ||||
| #define _ASM_HEXAGON_SYSCALL_H | ||||
| 
 | ||||
| typedef long (*syscall_fn)(unsigned long, unsigned long, | ||||
| 	unsigned long, unsigned long, | ||||
| 	unsigned long, unsigned long); | ||||
| 
 | ||||
| #include <asm-generic/syscalls.h> | ||||
| 
 | ||||
| extern void *sys_call_table[]; | ||||
| 
 | ||||
| static inline long syscall_get_nr(struct task_struct *task, | ||||
| 				  struct pt_regs *regs) | ||||
| { | ||||
| 	return regs->r06; | ||||
| } | ||||
| 
 | ||||
| static inline void syscall_get_arguments(struct task_struct *task, | ||||
| 					 struct pt_regs *regs, | ||||
| 					 unsigned int i, unsigned int n, | ||||
| 					 unsigned long *args) | ||||
| { | ||||
| 	BUG_ON(i + n > 6); | ||||
| 	memcpy(args, &(®s->r00)[i], n * sizeof(args[0])); | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										137
									
								
								arch/hexagon/include/asm/thread_info.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								arch/hexagon/include/asm/thread_info.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,137 @@ | |||
| /*
 | ||||
|  * Thread support for the Hexagon architecture | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_THREAD_INFO_H | ||||
| #define _ASM_THREAD_INFO_H | ||||
| 
 | ||||
| #ifdef __KERNEL__ | ||||
| 
 | ||||
| #ifndef __ASSEMBLY__ | ||||
| #include <asm/processor.h> | ||||
| #include <asm/registers.h> | ||||
| #include <asm/page.h> | ||||
| #endif | ||||
| 
 | ||||
| #define THREAD_SHIFT		12 | ||||
| #define THREAD_SIZE		(1<<THREAD_SHIFT) | ||||
| #define THREAD_SIZE_ORDER	(THREAD_SHIFT - PAGE_SHIFT) | ||||
| 
 | ||||
| #ifndef __ASSEMBLY__ | ||||
| 
 | ||||
| typedef struct { | ||||
| 	unsigned long seg; | ||||
| } mm_segment_t; | ||||
| 
 | ||||
| /*
 | ||||
|  * This is union'd with the "bottom" of the kernel stack. | ||||
|  * It keeps track of thread info which is handy for routines | ||||
|  * to access quickly. | ||||
|  */ | ||||
| 
 | ||||
| struct thread_info { | ||||
| 	struct task_struct	*task;		/* main task structure */ | ||||
| 	struct exec_domain      *exec_domain;   /* execution domain */ | ||||
| 	unsigned long		flags;          /* low level flags */ | ||||
| 	__u32                   cpu;            /* current cpu */ | ||||
| 	int                     preempt_count;  /* 0=>preemptible,<0=>BUG */ | ||||
| 	mm_segment_t            addr_limit;     /* segmentation sux */ | ||||
| 	/*
 | ||||
| 	 * used for syscalls somehow; | ||||
| 	 * seems to have a function pointer and four arguments | ||||
| 	 */ | ||||
| 	struct restart_block    restart_block; | ||||
| 	/* Points to the current pt_regs frame  */ | ||||
| 	struct pt_regs		*regs; | ||||
| 	/*
 | ||||
| 	 * saved kernel sp at switch_to time; | ||||
| 	 * not sure if this is used (it's not in the VM model it seems; | ||||
| 	 * see thread_struct) | ||||
| 	 */ | ||||
| 	unsigned long		sp; | ||||
| }; | ||||
| 
 | ||||
| #else /* !__ASSEMBLY__ */ | ||||
| 
 | ||||
| #include <asm/asm-offsets.h> | ||||
| 
 | ||||
| #endif  /* __ASSEMBLY__  */ | ||||
| 
 | ||||
| #ifndef __ASSEMBLY__ | ||||
| 
 | ||||
| #define INIT_THREAD_INFO(tsk)                   \ | ||||
| {                                               \ | ||||
| 	.task           = &tsk,                 \ | ||||
| 	.exec_domain    = &default_exec_domain, \ | ||||
| 	.flags          = 0,                    \ | ||||
| 	.cpu            = 0,                    \ | ||||
| 	.preempt_count  = 1,                    \ | ||||
| 	.addr_limit     = KERNEL_DS,            \ | ||||
| 	.restart_block = {                      \ | ||||
| 		.fn = do_no_restart_syscall,    \ | ||||
| 	},                                      \ | ||||
| 	.sp = 0,				\ | ||||
| 	.regs = NULL,			\ | ||||
| } | ||||
| 
 | ||||
| #define init_thread_info        (init_thread_union.thread_info) | ||||
| #define init_stack              (init_thread_union.stack) | ||||
| 
 | ||||
| /* Tacky preprocessor trickery */ | ||||
| #define	qqstr(s) qstr(s) | ||||
| #define qstr(s) #s | ||||
| #define QUOTED_THREADINFO_REG qqstr(THREADINFO_REG) | ||||
| 
 | ||||
| register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG); | ||||
| #define current_thread_info()  __current_thread_info | ||||
| 
 | ||||
| #endif /* __ASSEMBLY__ */ | ||||
| 
 | ||||
| /*
 | ||||
|  * thread information flags | ||||
|  * - these are process state flags that various assembly files | ||||
|  *   may need to access | ||||
|  * - pending work-to-be-done flags are in LSW | ||||
|  * - other flags in MSW | ||||
|  */ | ||||
| 
 | ||||
| #define TIF_SYSCALL_TRACE       0       /* syscall trace active */ | ||||
| #define TIF_NOTIFY_RESUME       1       /* resumption notification requested */ | ||||
| #define TIF_SIGPENDING          2       /* signal pending */ | ||||
| #define TIF_NEED_RESCHED        3       /* rescheduling necessary */ | ||||
| #define TIF_SINGLESTEP          4       /* restore ss @ return to usr mode */ | ||||
| #define TIF_RESTORE_SIGMASK     6       /* restore sig mask in do_signal() */ | ||||
| /* true if poll_idle() is polling TIF_NEED_RESCHED */ | ||||
| #define TIF_MEMDIE              17      /* OOM killer killed process */ | ||||
| 
 | ||||
| #define _TIF_SYSCALL_TRACE      (1 << TIF_SYSCALL_TRACE) | ||||
| #define _TIF_NOTIFY_RESUME      (1 << TIF_NOTIFY_RESUME) | ||||
| #define _TIF_SIGPENDING         (1 << TIF_SIGPENDING) | ||||
| #define _TIF_NEED_RESCHED       (1 << TIF_NEED_RESCHED) | ||||
| #define _TIF_SINGLESTEP         (1 << TIF_SINGLESTEP) | ||||
| 
 | ||||
| /* work to do on interrupt/exception return - All but TIF_SYSCALL_TRACE */ | ||||
| #define _TIF_WORK_MASK          (0x0000FFFF & ~_TIF_SYSCALL_TRACE) | ||||
| 
 | ||||
| /* work to do on any return to u-space */ | ||||
| #define _TIF_ALLWORK_MASK       0x0000FFFF | ||||
| 
 | ||||
| #endif /* __KERNEL__ */ | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										29
									
								
								arch/hexagon/include/asm/time.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								arch/hexagon/include/asm/time.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef ASM_TIME_H | ||||
| #define ASM_TIME_H | ||||
| 
 | ||||
| extern cycles_t        pcycle_freq_mhz; | ||||
| extern cycles_t        thread_freq_mhz; | ||||
| extern cycles_t        sleep_clk_freq; | ||||
| 
 | ||||
| void setup_percpu_clockdev(void); | ||||
| void ipi_timer(void); | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										39
									
								
								arch/hexagon/include/asm/timer-regs.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								arch/hexagon/include/asm/timer-regs.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | |||
| /*
 | ||||
|  * Timer support for Hexagon | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_TIMER_REGS_H | ||||
| #define _ASM_TIMER_REGS_H | ||||
| 
 | ||||
| /*  This stuff should go into a platform specific file  */ | ||||
| #define TCX0_CLK_RATE		19200 | ||||
| #define TIMER_ENABLE		0 | ||||
| #define TIMER_CLR_ON_MATCH	1 | ||||
| 
 | ||||
| /*
 | ||||
|  * 8x50 HDD Specs 5-8.  Simulator co-sim not fixed until | ||||
|  * release 1.1, and then it's "adjustable" and probably not defaulted. | ||||
|  */ | ||||
| #define RTOS_TIMER_INT		3 | ||||
| #ifdef CONFIG_HEXAGON_COMET | ||||
| #define RTOS_TIMER_REGS_ADDR	0xAB000000UL | ||||
| #endif | ||||
| #define SLEEP_CLK_RATE		32000 | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										36
									
								
								arch/hexagon/include/asm/timex.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								arch/hexagon/include/asm/timex.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_TIMEX_H | ||||
| #define _ASM_TIMEX_H | ||||
| 
 | ||||
| #include <asm-generic/timex.h> | ||||
| #include <asm/timer-regs.h> | ||||
| 
 | ||||
| /* Using TCX0 as our clock.  CLOCK_TICK_RATE scheduled to be removed. */ | ||||
| #define CLOCK_TICK_RATE              TCX0_CLK_RATE | ||||
| 
 | ||||
| #define ARCH_HAS_READ_CURRENT_TIMER | ||||
| 
 | ||||
| static inline int read_current_timer(unsigned long *timer_val) | ||||
| { | ||||
| 	*timer_val = (unsigned long) __vmgettime(); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										39
									
								
								arch/hexagon/include/asm/tlb.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								arch/hexagon/include/asm/tlb.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,39 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_TLB_H | ||||
| #define _ASM_TLB_H | ||||
| 
 | ||||
| #include <linux/pagemap.h> | ||||
| #include <asm/tlbflush.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * We don't need any special per-pte or per-vma handling... | ||||
|  */ | ||||
| #define tlb_start_vma(tlb, vma)				do { } while (0) | ||||
| #define tlb_end_vma(tlb, vma)				do { } while (0) | ||||
| #define __tlb_remove_tlb_entry(tlb, ptep, address)	do { } while (0) | ||||
| 
 | ||||
| /*
 | ||||
|  * .. because we flush the whole mm when it fills up | ||||
|  */ | ||||
| #define tlb_flush(tlb)		flush_tlb_mm((tlb)->mm) | ||||
| 
 | ||||
| #include <asm-generic/tlb.h> | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										58
									
								
								arch/hexagon/include/asm/tlbflush.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								arch/hexagon/include/asm/tlbflush.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,58 @@ | |||
| /*
 | ||||
|  * TLB flush support for Hexagon | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_TLBFLUSH_H | ||||
| #define _ASM_TLBFLUSH_H | ||||
| 
 | ||||
| #include <linux/mm.h> | ||||
| #include <asm/processor.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * TLB flushing -- in "SMP", these routines get defined to be the | ||||
|  * ones from smp.c, else they are some local flavors. | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * These functions are commonly macros, but in the interests of | ||||
|  * VM vs. native implementation and code size, we simply declare | ||||
|  * the function prototypes here. | ||||
|  */ | ||||
| extern void tlb_flush_all(void); | ||||
| extern void flush_tlb_mm(struct mm_struct *mm); | ||||
| extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr); | ||||
| extern void flush_tlb_range(struct vm_area_struct *vma, | ||||
| 				unsigned long start, unsigned long end); | ||||
| extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); | ||||
| extern void flush_tlb_one(unsigned long); | ||||
| 
 | ||||
| /*
 | ||||
|  * "This is called in munmap when we have freed up some page-table pages. | ||||
|  * We don't need to do anything here..." | ||||
|  * | ||||
|  * The VM kernel doesn't walk page tables, and they are passed to the VMM | ||||
|  * by logical address. There doesn't seem to be any possibility that they | ||||
|  * could be referenced by the VM kernel based on a stale mapping, since | ||||
|  * they would only be located by consulting the mm structure, and they | ||||
|  * will have been purged from that structure by the munmap.  Seems like | ||||
|  * a noop on HVM as well. | ||||
|  */ | ||||
| #define flush_tlb_pgtables(mm, start, end) | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										29
									
								
								arch/hexagon/include/asm/traps.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								arch/hexagon/include/asm/traps.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| /*
 | ||||
|  * Trap support for Hexagon | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_HEXAGON_TRAPS_H | ||||
| #define _ASM_HEXAGON_TRAPS_H | ||||
| 
 | ||||
| #include <asm/registers.h> | ||||
| 
 | ||||
| extern int die(const char *str, struct pt_regs *regs, long err); | ||||
| extern int die_if_kernel(char *str, struct pt_regs *regs, long err); | ||||
| 
 | ||||
| #endif /* _ASM_HEXAGON_TRAPS_H */ | ||||
							
								
								
									
										116
									
								
								arch/hexagon/include/asm/uaccess.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								arch/hexagon/include/asm/uaccess.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,116 @@ | |||
| /*
 | ||||
|  * User memory access support for Hexagon | ||||
|  * | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_UACCESS_H | ||||
| #define _ASM_UACCESS_H | ||||
| /*
 | ||||
|  * User space memory access functions | ||||
|  */ | ||||
| #include <linux/sched.h> | ||||
| #include <linux/mm.h> | ||||
| #include <asm/segment.h> | ||||
| #include <asm/sections.h> | ||||
| 
 | ||||
| /*
 | ||||
|  * access_ok: - Checks if a user space pointer is valid | ||||
|  * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that | ||||
|  *        %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe | ||||
|  *        to write to a block, it is always safe to read from it. | ||||
|  * @addr: User space pointer to start of block to check | ||||
|  * @size: Size of block to check | ||||
|  * | ||||
|  * Context: User context only.  This function may sleep. | ||||
|  * | ||||
|  * Checks if a pointer to a block of memory in user space is valid. | ||||
|  * | ||||
|  * Returns true (nonzero) if the memory block *may* be valid, false (zero) | ||||
|  * if it is definitely invalid. | ||||
|  * | ||||
|  * User address space in Hexagon, like x86, goes to 0xbfffffff, so the | ||||
|  * simple MSB-based tests used by MIPS won't work.  Some further | ||||
|  * optimization is probably possible here, but for now, keep it | ||||
|  * reasonably simple and not *too* slow.  After all, we've got the | ||||
|  * MMU for backup. | ||||
|  */ | ||||
| #define VERIFY_READ     0 | ||||
| #define VERIFY_WRITE    1 | ||||
| 
 | ||||
| #define __access_ok(addr, size) \ | ||||
| 	((get_fs().seg == KERNEL_DS.seg) || \ | ||||
| 	(((unsigned long)addr < get_fs().seg) && \ | ||||
| 	  (unsigned long)size < (get_fs().seg - (unsigned long)addr))) | ||||
| 
 | ||||
| /*
 | ||||
|  * When a kernel-mode page fault is taken, the faulting instruction | ||||
|  * address is checked against a table of exception_table_entries. | ||||
|  * Each entry is a tuple of the address of an instruction that may | ||||
|  * be authorized to fault, and the address at which execution should | ||||
|  * be resumed instead of the faulting instruction, so as to effect | ||||
|  * a workaround. | ||||
|  */ | ||||
| 
 | ||||
| /*  Assembly somewhat optimized copy routines  */ | ||||
| unsigned long __copy_from_user_hexagon(void *to, const void __user *from, | ||||
| 				     unsigned long n); | ||||
| unsigned long __copy_to_user_hexagon(void __user *to, const void *from, | ||||
| 				   unsigned long n); | ||||
| 
 | ||||
| #define __copy_from_user(to, from, n) __copy_from_user_hexagon(to, from, n) | ||||
| #define __copy_to_user(to, from, n) __copy_to_user_hexagon(to, from, n) | ||||
| 
 | ||||
| /*
 | ||||
|  * XXX todo: some additonal performance gain is possible by | ||||
|  * implementing __copy_to/from_user_inatomic, which is much | ||||
|  * like __copy_to/from_user, but performs slightly less checking. | ||||
|  */ | ||||
| 
 | ||||
| __kernel_size_t __clear_user_hexagon(void __user *dest, unsigned long count); | ||||
| #define __clear_user(a, s) __clear_user_hexagon((a), (s)) | ||||
| 
 | ||||
| #define __strncpy_from_user(dst, src, n) hexagon_strncpy_from_user(dst, src, n) | ||||
| 
 | ||||
| /*  get around the ifndef in asm-generic/uaccess.h  */ | ||||
| #define __strnlen_user __strnlen_user | ||||
| 
 | ||||
| extern long __strnlen_user(const char __user *src, long n); | ||||
| 
 | ||||
| static inline long hexagon_strncpy_from_user(char *dst, const char __user *src, | ||||
| 					     long n); | ||||
| 
 | ||||
| #include <asm-generic/uaccess.h> | ||||
| 
 | ||||
| /*  Todo:  an actual accelerated version of this.  */ | ||||
| static inline long hexagon_strncpy_from_user(char *dst, const char __user *src, | ||||
| 					     long n) | ||||
| { | ||||
| 	long res = __strnlen_user(src, n); | ||||
| 
 | ||||
| 	/* return from strnlen can't be zero -- that would be rubbish. */ | ||||
| 
 | ||||
| 	if (res > n) { | ||||
| 		copy_from_user(dst, src, n); | ||||
| 		return n; | ||||
| 	} else { | ||||
| 		copy_from_user(dst, src, res); | ||||
| 		return res-1; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										30
									
								
								arch/hexagon/include/asm/vdso.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								arch/hexagon/include/asm/vdso.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | |||
| /*
 | ||||
|  * vDSO implementation for Hexagon | ||||
|  * | ||||
|  * Copyright (c) 2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __ASM_VDSO_H | ||||
| #define __ASM_VDSO_H | ||||
| 
 | ||||
| #include <linux/types.h> | ||||
| 
 | ||||
| struct hexagon_vdso { | ||||
| 	u32 rt_signal_trampoline[2]; | ||||
| }; | ||||
| 
 | ||||
| #endif /* __ASM_VDSO_H */ | ||||
							
								
								
									
										26
									
								
								arch/hexagon/include/asm/vm_fault.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								arch/hexagon/include/asm/vm_fault.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_HEXAGON_VM_FAULT_H | ||||
| #define _ASM_HEXAGON_VM_FAULT_H | ||||
| 
 | ||||
| extern void execute_protection_fault(struct pt_regs *); | ||||
| extern void write_protection_fault(struct pt_regs *); | ||||
| extern void read_protection_fault(struct pt_regs *); | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										110
									
								
								arch/hexagon/include/asm/vm_mmu.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								arch/hexagon/include/asm/vm_mmu.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,110 @@ | |||
| /*
 | ||||
|  * Hexagon VM page table entry definitions | ||||
|  * | ||||
|  * Copyright (c) 2010-2011,2013 The Linux Foundation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 and | ||||
|  * only version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_VM_MMU_H | ||||
| #define _ASM_VM_MMU_H | ||||
| 
 | ||||
| /*
 | ||||
|  * Shift, mask, and other constants for the Hexagon Virtual Machine | ||||
|  * page tables. | ||||
|  * | ||||
|  * Virtual machine MMU allows first-level entries to either be | ||||
|  * single-level lookup PTEs for very large pages, or PDEs pointing | ||||
|  * to second-level PTEs for smaller pages. If PTE is single-level, | ||||
|  * the least significant bits cannot be used as software bits to encode | ||||
|  * virtual memory subsystem information about the page, and that state | ||||
|  * must be maintained in some parallel data structure. | ||||
|  */ | ||||
| 
 | ||||
| /* S or Page Size field in PDE */ | ||||
| #define	__HVM_PDE_S		(0x7 << 0) | ||||
| #define __HVM_PDE_S_4KB		0 | ||||
| #define __HVM_PDE_S_16KB	1 | ||||
| #define __HVM_PDE_S_64KB	2 | ||||
| #define __HVM_PDE_S_256KB	3 | ||||
| #define __HVM_PDE_S_1MB		4 | ||||
| #define __HVM_PDE_S_4MB		5 | ||||
| #define __HVM_PDE_S_16MB	6 | ||||
| #define __HVM_PDE_S_INVALID	7 | ||||
| 
 | ||||
| /* Masks for L2 page table pointer, as function of page size */ | ||||
| #define __HVM_PDE_PTMASK_4KB	0xfffff000 | ||||
| #define __HVM_PDE_PTMASK_16KB	0xfffffc00 | ||||
| #define __HVM_PDE_PTMASK_64KB	0xffffff00 | ||||
| #define __HVM_PDE_PTMASK_256KB	0xffffffc0 | ||||
| #define __HVM_PDE_PTMASK_1MB	0xfffffff0 | ||||
| 
 | ||||
| /*
 | ||||
|  * Virtual Machine PTE Bits/Fields | ||||
|  */ | ||||
| #define __HVM_PTE_T		(1<<4) | ||||
| #define __HVM_PTE_U		(1<<5) | ||||
| #define	__HVM_PTE_C		(0x7<<6) | ||||
| #define __HVM_PTE_CVAL(pte)	(((pte) & __HVM_PTE_C) >> 6) | ||||
| #define __HVM_PTE_R		(1<<9) | ||||
| #define __HVM_PTE_W		(1<<10) | ||||
| #define __HVM_PTE_X		(1<<11) | ||||
| 
 | ||||
| /*
 | ||||
|  * Cache Attributes, to be shifted as necessary for virtual/physical PTEs | ||||
|  */ | ||||
| 
 | ||||
| #define __HEXAGON_C_WB		0x0	/* Write-back, no L2 */ | ||||
| #define	__HEXAGON_C_WT		0x1	/* Write-through, no L2 */ | ||||
| #define	__HEXAGON_C_UNC		0x6	/* Uncached memory */ | ||||
| #if CONFIG_HEXAGON_ARCH_VERSION >= 2 | ||||
| #define	__HEXAGON_C_DEV		0x4	/* Device register space */ | ||||
| #else | ||||
| #define __HEXAGON_C_DEV		__HEXAGON_C_UNC | ||||
| #endif | ||||
| #define	__HEXAGON_C_WT_L2	0x5	/* Write-through, with L2 */ | ||||
| #define	__HEXAGON_C_WB_L2	0x7	/* Write-back, with L2 */ | ||||
| 
 | ||||
| /*
 | ||||
|  * This can be overriden, but we're defaulting to the most aggressive | ||||
|  * cache policy, the better to find bugs sooner. | ||||
|  */ | ||||
| 
 | ||||
| #define	CACHE_DEFAULT	__HEXAGON_C_WB_L2 | ||||
| 
 | ||||
| /* Masks for physical page address, as a function of page size */ | ||||
| 
 | ||||
| #define __HVM_PTE_PGMASK_4KB	0xfffff000 | ||||
| #define __HVM_PTE_PGMASK_16KB	0xffffc000 | ||||
| #define __HVM_PTE_PGMASK_64KB	0xffff0000 | ||||
| #define __HVM_PTE_PGMASK_256KB	0xfffc0000 | ||||
| #define __HVM_PTE_PGMASK_1MB	0xfff00000 | ||||
| 
 | ||||
| /* Masks for single-level large page lookups */ | ||||
| 
 | ||||
| #define __HVM_PTE_PGMASK_4MB	0xffc00000 | ||||
| #define __HVM_PTE_PGMASK_16MB	0xff000000 | ||||
| 
 | ||||
| /*
 | ||||
|  * "Big kernel page mappings" (see vm_init_segtable.S) | ||||
|  * are currently 16MB | ||||
|  */ | ||||
| 
 | ||||
| #define BIG_KERNEL_PAGE_SHIFT 24 | ||||
| #define BIG_KERNEL_PAGE_SIZE (1 << BIG_KERNEL_PAGE_SHIFT) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #endif /* _ASM_VM_MMU_H */ | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 awab228
						awab228