xref: /openbmc/linux/arch/hexagon/include/asm/processor.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
108dbd0f8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
299a70aa0SRichard Kuo /*
399a70aa0SRichard Kuo  * Process/processor support for the Hexagon architecture
499a70aa0SRichard Kuo  *
57c6a5df4SRichard Kuo  * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
699a70aa0SRichard Kuo  */
799a70aa0SRichard Kuo 
899a70aa0SRichard Kuo #ifndef _ASM_PROCESSOR_H
999a70aa0SRichard Kuo #define _ASM_PROCESSOR_H
1099a70aa0SRichard Kuo 
1199a70aa0SRichard Kuo #ifndef __ASSEMBLY__
1299a70aa0SRichard Kuo 
1399a70aa0SRichard Kuo #include <asm/mem-layout.h>
1499a70aa0SRichard Kuo #include <asm/registers.h>
1599a70aa0SRichard Kuo #include <asm/hexagon_vm.h>
1699a70aa0SRichard Kuo 
1799a70aa0SRichard Kuo /*  task_struct, defined elsewhere, is the "process descriptor" */
1899a70aa0SRichard Kuo struct task_struct;
1999a70aa0SRichard Kuo 
2099a70aa0SRichard Kuo extern void start_thread(struct pt_regs *, unsigned long, unsigned long);
2199a70aa0SRichard Kuo 
2299a70aa0SRichard Kuo /*
2399a70aa0SRichard Kuo  * thread_struct is supposed to be for context switch data.
2499a70aa0SRichard Kuo  * Specifically, to hold the state necessary to perform switch_to...
2599a70aa0SRichard Kuo  */
2699a70aa0SRichard Kuo struct thread_struct {
2799a70aa0SRichard Kuo 	void *switch_sp;
2899a70aa0SRichard Kuo };
2999a70aa0SRichard Kuo 
3099a70aa0SRichard Kuo /*
3199a70aa0SRichard Kuo  * initializes thread_struct
3299a70aa0SRichard Kuo  * The only thing we have in there is switch_sp
3399a70aa0SRichard Kuo  * which doesn't really need to be initialized.
3499a70aa0SRichard Kuo  */
3599a70aa0SRichard Kuo 
3699a70aa0SRichard Kuo #define INIT_THREAD { \
3799a70aa0SRichard Kuo }
3899a70aa0SRichard Kuo 
3999a70aa0SRichard Kuo #define cpu_relax() __vmyield()
4099a70aa0SRichard Kuo 
4199a70aa0SRichard Kuo /*
4299a70aa0SRichard Kuo  * Decides where the kernel will search for a free chunk of vm space during
4399a70aa0SRichard Kuo  * mmaps.
4499a70aa0SRichard Kuo  * See also arch_get_unmapped_area.
4599a70aa0SRichard Kuo  * Doesn't affect if you have MAX_FIXED in the page flags set though...
4699a70aa0SRichard Kuo  *
4799a70aa0SRichard Kuo  * Apparently the convention is that ld.so will ask for "unmapped" private
4899a70aa0SRichard Kuo  * memory to be allocated SOMEWHERE, but it also asks for memory explicitly
4999a70aa0SRichard Kuo  * via MAP_FIXED at the lower * addresses starting at VA=0x0.
5099a70aa0SRichard Kuo  *
5199a70aa0SRichard Kuo  * If the two requests collide, you get authentic segfaulting action, so
5299a70aa0SRichard Kuo  * you have to kick the "unmapped" base requests higher up.
5399a70aa0SRichard Kuo  */
5499a70aa0SRichard Kuo #define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE/3))
5599a70aa0SRichard Kuo 
5699a70aa0SRichard Kuo 
5799a70aa0SRichard Kuo #define task_pt_regs(task) \
5899a70aa0SRichard Kuo 	((struct pt_regs *)(task_stack_page(task) + THREAD_SIZE) - 1)
5999a70aa0SRichard Kuo 
6099a70aa0SRichard Kuo #define KSTK_EIP(tsk) (pt_elr(task_pt_regs(tsk)))
6199a70aa0SRichard Kuo #define KSTK_ESP(tsk) (pt_psp(task_pt_regs(tsk)))
6299a70aa0SRichard Kuo 
63*42a20f86SKees Cook extern unsigned long __get_wchan(struct task_struct *p);
6499a70aa0SRichard Kuo 
6599a70aa0SRichard Kuo /*  The following stuff is pretty HEXAGON specific.  */
6699a70aa0SRichard Kuo 
6799a70aa0SRichard Kuo /*  This is really just here for __switch_to.
6899a70aa0SRichard Kuo     Offsets are pulled via asm-offsets.c  */
6999a70aa0SRichard Kuo 
7099a70aa0SRichard Kuo /*
7199a70aa0SRichard Kuo  * No real reason why VM and native switch stacks should be different.
7299a70aa0SRichard Kuo  * Ultimately this should merge.  Note that Rev C. ABI called out only
7399a70aa0SRichard Kuo  * R24-27 as callee saved GPRs needing explicit attention (R29-31 being
7499a70aa0SRichard Kuo  * dealt with automagically by allocframe), but the current ABI has
7599a70aa0SRichard Kuo  * more, R16-R27.  By saving more, the worst case is that we waste some
7699a70aa0SRichard Kuo  * cycles if building with the old compilers.
7799a70aa0SRichard Kuo  */
7899a70aa0SRichard Kuo 
7999a70aa0SRichard Kuo struct hexagon_switch_stack {
80444dd742SRichard Kuo 	union {
81444dd742SRichard Kuo 		struct {
82444dd742SRichard Kuo 			unsigned long r16;
83444dd742SRichard Kuo 			unsigned long r17;
84444dd742SRichard Kuo 		};
8599a70aa0SRichard Kuo 		unsigned long long	r1716;
86444dd742SRichard Kuo 	};
87444dd742SRichard Kuo 	union {
88444dd742SRichard Kuo 		struct {
89444dd742SRichard Kuo 			unsigned long r18;
90444dd742SRichard Kuo 			unsigned long r19;
91444dd742SRichard Kuo 		};
9299a70aa0SRichard Kuo 		unsigned long long	r1918;
93444dd742SRichard Kuo 	};
94444dd742SRichard Kuo 	union {
95444dd742SRichard Kuo 		struct {
96444dd742SRichard Kuo 			unsigned long r20;
97444dd742SRichard Kuo 			unsigned long r21;
98444dd742SRichard Kuo 		};
9999a70aa0SRichard Kuo 		unsigned long long	r2120;
100444dd742SRichard Kuo 	};
101444dd742SRichard Kuo 	union {
102444dd742SRichard Kuo 		struct {
103444dd742SRichard Kuo 			unsigned long r22;
104444dd742SRichard Kuo 			unsigned long r23;
105444dd742SRichard Kuo 		};
10699a70aa0SRichard Kuo 		unsigned long long	r2322;
107444dd742SRichard Kuo 	};
108444dd742SRichard Kuo 	union {
109444dd742SRichard Kuo 		struct {
110444dd742SRichard Kuo 			unsigned long r24;
111444dd742SRichard Kuo 			unsigned long r25;
112444dd742SRichard Kuo 		};
11399a70aa0SRichard Kuo 		unsigned long long	r2524;
114444dd742SRichard Kuo 	};
115444dd742SRichard Kuo 	union {
116444dd742SRichard Kuo 		struct {
117444dd742SRichard Kuo 			unsigned long r26;
118444dd742SRichard Kuo 			unsigned long r27;
119444dd742SRichard Kuo 		};
12099a70aa0SRichard Kuo 		unsigned long long	r2726;
121444dd742SRichard Kuo 	};
122444dd742SRichard Kuo 
12399a70aa0SRichard Kuo 	unsigned long		fp;
12499a70aa0SRichard Kuo 	unsigned long		lr;
12599a70aa0SRichard Kuo };
12699a70aa0SRichard Kuo 
12799a70aa0SRichard Kuo #endif /* !__ASSEMBLY__ */
12899a70aa0SRichard Kuo 
12999a70aa0SRichard Kuo #endif
130