xref: /openbmc/linux/arch/m68k/include/asm/processor.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2633ea5d7SGreg Ungerer /*
3633ea5d7SGreg Ungerer  * include/asm-m68k/processor.h
4633ea5d7SGreg Ungerer  *
5633ea5d7SGreg Ungerer  * Copyright (C) 1995 Hamish Macdonald
6633ea5d7SGreg Ungerer  */
7633ea5d7SGreg Ungerer 
8633ea5d7SGreg Ungerer #ifndef __ASM_M68K_PROCESSOR_H
9633ea5d7SGreg Ungerer #define __ASM_M68K_PROCESSOR_H
10633ea5d7SGreg Ungerer 
11633ea5d7SGreg Ungerer #include <linux/thread_info.h>
12633ea5d7SGreg Ungerer #include <asm/fpu.h>
13633ea5d7SGreg Ungerer #include <asm/ptrace.h>
14633ea5d7SGreg Ungerer 
rdusp(void)15633ea5d7SGreg Ungerer static inline unsigned long rdusp(void)
16633ea5d7SGreg Ungerer {
171c83af5fSGreg Ungerer #ifdef CONFIG_COLDFIRE_SW_A7
18633ea5d7SGreg Ungerer 	extern unsigned int sw_usp;
19633ea5d7SGreg Ungerer 	return sw_usp;
2049148020SSam Ravnborg #else
211c83af5fSGreg Ungerer 	register unsigned long usp __asm__("a0");
221c83af5fSGreg Ungerer 	/* move %usp,%a0 */
231c83af5fSGreg Ungerer 	__asm__ __volatile__(".word 0x4e68" : "=a" (usp));
24633ea5d7SGreg Ungerer 	return usp;
25633ea5d7SGreg Ungerer #endif
26633ea5d7SGreg Ungerer }
27633ea5d7SGreg Ungerer 
wrusp(unsigned long usp)28633ea5d7SGreg Ungerer static inline void wrusp(unsigned long usp)
29633ea5d7SGreg Ungerer {
301c83af5fSGreg Ungerer #ifdef CONFIG_COLDFIRE_SW_A7
31633ea5d7SGreg Ungerer 	extern unsigned int sw_usp;
32633ea5d7SGreg Ungerer 	sw_usp = usp;
33633ea5d7SGreg Ungerer #else
341c83af5fSGreg Ungerer 	register unsigned long a0 __asm__("a0") = usp;
351c83af5fSGreg Ungerer 	/* move %a0,%usp */
361c83af5fSGreg Ungerer 	__asm__ __volatile__(".word 0x4e60" : : "a" (a0) );
37633ea5d7SGreg Ungerer #endif
38633ea5d7SGreg Ungerer }
39633ea5d7SGreg Ungerer 
40633ea5d7SGreg Ungerer /*
41633ea5d7SGreg Ungerer  * User space process size: 3.75GB. This is hardcoded into a few places,
42633ea5d7SGreg Ungerer  * so don't change it unless you know what you are doing.
43633ea5d7SGreg Ungerer  */
44cc24c405SGreg Ungerer #ifdef CONFIG_MMU
452c9b82adSGreg Ungerer #if defined(CONFIG_COLDFIRE)
462c9b82adSGreg Ungerer #define TASK_SIZE	(0xC0000000UL)
472c9b82adSGreg Ungerer #elif defined(CONFIG_SUN3)
48633ea5d7SGreg Ungerer #define TASK_SIZE	(0x0E000000UL)
492c9b82adSGreg Ungerer #else
502c9b82adSGreg Ungerer #define TASK_SIZE	(0xF0000000UL)
51633ea5d7SGreg Ungerer #endif
52cc24c405SGreg Ungerer #else
53cc24c405SGreg Ungerer #define TASK_SIZE	(0xFFFFFFFFUL)
54cc24c405SGreg Ungerer #endif
55633ea5d7SGreg Ungerer 
56633ea5d7SGreg Ungerer #ifdef __KERNEL__
57633ea5d7SGreg Ungerer #define STACK_TOP	TASK_SIZE
58633ea5d7SGreg Ungerer #define STACK_TOP_MAX	STACK_TOP
59633ea5d7SGreg Ungerer #endif
60633ea5d7SGreg Ungerer 
61633ea5d7SGreg Ungerer /* This decides where the kernel will search for a free chunk of vm
62633ea5d7SGreg Ungerer  * space during mmap's.
63633ea5d7SGreg Ungerer  */
64633ea5d7SGreg Ungerer #ifdef CONFIG_MMU
652c9b82adSGreg Ungerer #if defined(CONFIG_COLDFIRE)
662c9b82adSGreg Ungerer #define TASK_UNMAPPED_BASE	0x60000000UL
672c9b82adSGreg Ungerer #elif defined(CONFIG_SUN3)
68633ea5d7SGreg Ungerer #define TASK_UNMAPPED_BASE	0x0A000000UL
692c9b82adSGreg Ungerer #else
702c9b82adSGreg Ungerer #define TASK_UNMAPPED_BASE	0xC0000000UL
71633ea5d7SGreg Ungerer #endif
72633ea5d7SGreg Ungerer #define TASK_UNMAPPED_ALIGN(addr, off)	PAGE_ALIGN(addr)
73633ea5d7SGreg Ungerer #else
74633ea5d7SGreg Ungerer #define TASK_UNMAPPED_BASE	0
75633ea5d7SGreg Ungerer #endif
76633ea5d7SGreg Ungerer 
779fde0348SChristoph Hellwig /* Address spaces (or Function Codes in Motorola lingo) */
789fde0348SChristoph Hellwig #define USER_DATA     1
799fde0348SChristoph Hellwig #define USER_PROGRAM  2
809fde0348SChristoph Hellwig #define SUPER_DATA    5
819fde0348SChristoph Hellwig #define SUPER_PROGRAM 6
829fde0348SChristoph Hellwig #define CPU_SPACE     7
839fde0348SChristoph Hellwig 
849fde0348SChristoph Hellwig #ifdef CONFIG_CPU_HAS_ADDRESS_SPACES
859fde0348SChristoph Hellwig /*
869fde0348SChristoph Hellwig  * Set the SFC/DFC registers for special MM operations.  For most normal
879fde0348SChristoph Hellwig  * operation these remain set to USER_DATA for the uaccess routines.
889fde0348SChristoph Hellwig  */
set_fc(unsigned long val)899fde0348SChristoph Hellwig static inline void set_fc(unsigned long val)
909fde0348SChristoph Hellwig {
919fde0348SChristoph Hellwig 	WARN_ON_ONCE(in_interrupt());
929fde0348SChristoph Hellwig 
939fde0348SChristoph Hellwig 	__asm__ __volatile__ ("movec %0,%/sfc\n\t"
949fde0348SChristoph Hellwig 			      "movec %0,%/dfc\n\t"
959fde0348SChristoph Hellwig 			      : /* no outputs */ : "r" (val) : "memory");
969fde0348SChristoph Hellwig }
979fde0348SChristoph Hellwig #else
set_fc(unsigned long val)989fde0348SChristoph Hellwig static inline void set_fc(unsigned long val)
999fde0348SChristoph Hellwig {
1009fde0348SChristoph Hellwig }
1019fde0348SChristoph Hellwig #endif /* CONFIG_CPU_HAS_ADDRESS_SPACES */
1029fde0348SChristoph Hellwig 
103633ea5d7SGreg Ungerer struct thread_struct {
104633ea5d7SGreg Ungerer 	unsigned long  ksp;		/* kernel stack pointer */
105633ea5d7SGreg Ungerer 	unsigned long  usp;		/* user stack pointer */
106633ea5d7SGreg Ungerer 	unsigned short sr;		/* saved status register */
1079fde0348SChristoph Hellwig 	unsigned short fc;		/* saved fc (sfc, dfc) */
108633ea5d7SGreg Ungerer 	unsigned long  crp[2];		/* cpu root pointer */
109633ea5d7SGreg Ungerer 	unsigned long  esp0;		/* points to SR of stack frame */
110633ea5d7SGreg Ungerer 	unsigned long  faddr;		/* info about last fault */
111633ea5d7SGreg Ungerer 	int            signo, code;
112633ea5d7SGreg Ungerer 	unsigned long  fp[8*3];
113633ea5d7SGreg Ungerer 	unsigned long  fpcntl[3];	/* fp control regs */
114633ea5d7SGreg Ungerer 	unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
115633ea5d7SGreg Ungerer };
116633ea5d7SGreg Ungerer 
117633ea5d7SGreg Ungerer #define INIT_THREAD  {							\
118633ea5d7SGreg Ungerer 	.ksp	= sizeof(init_stack) + (unsigned long) init_stack,	\
119633ea5d7SGreg Ungerer 	.sr	= PS_S,							\
1209fde0348SChristoph Hellwig 	.fc	= USER_DATA,						\
121633ea5d7SGreg Ungerer }
122633ea5d7SGreg Ungerer 
1230973c687SGreg Ungerer /*
1240973c687SGreg Ungerer  * ColdFire stack format sbould be 0x4 for an aligned usp (will always be
1250973c687SGreg Ungerer  * true on thread creation). We need to set this explicitly.
1260973c687SGreg Ungerer  */
1270973c687SGreg Ungerer #ifdef CONFIG_COLDFIRE
1280973c687SGreg Ungerer #define setframeformat(_regs)	do { (_regs)->format = 0x4; } while(0)
1290973c687SGreg Ungerer #else
1300973c687SGreg Ungerer #define setframeformat(_regs)	do { } while (0)
1310973c687SGreg Ungerer #endif
1320973c687SGreg Ungerer 
133633ea5d7SGreg Ungerer /*
134633ea5d7SGreg Ungerer  * Do necessary setup to start up a newly executed thread.
135633ea5d7SGreg Ungerer  */
start_thread(struct pt_regs * regs,unsigned long pc,unsigned long usp)136633ea5d7SGreg Ungerer static inline void start_thread(struct pt_regs * regs, unsigned long pc,
137633ea5d7SGreg Ungerer 				unsigned long usp)
138633ea5d7SGreg Ungerer {
139633ea5d7SGreg Ungerer 	regs->pc = pc;
140633ea5d7SGreg Ungerer 	regs->sr &= ~0x2000;
1410973c687SGreg Ungerer 	setframeformat(regs);
142633ea5d7SGreg Ungerer 	wrusp(usp);
143633ea5d7SGreg Ungerer }
144633ea5d7SGreg Ungerer 
145633ea5d7SGreg Ungerer /* Forward declaration, a strange C thing */
146633ea5d7SGreg Ungerer struct task_struct;
147633ea5d7SGreg Ungerer 
14842a20f86SKees Cook unsigned long __get_wchan(struct task_struct *p);
149*c07a1640SGeert Uytterhoeven void show_registers(struct pt_regs *regs);
150633ea5d7SGreg Ungerer 
151633ea5d7SGreg Ungerer #define	KSTK_EIP(tsk)	\
152633ea5d7SGreg Ungerer     ({			\
153633ea5d7SGreg Ungerer 	unsigned long eip = 0;	 \
154633ea5d7SGreg Ungerer 	if ((tsk)->thread.esp0 > PAGE_SIZE && \
155633ea5d7SGreg Ungerer 	    (virt_addr_valid((tsk)->thread.esp0))) \
156633ea5d7SGreg Ungerer 	      eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
157633ea5d7SGreg Ungerer 	eip; })
158633ea5d7SGreg Ungerer #define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
159633ea5d7SGreg Ungerer 
160c23b6538SGreg Ungerer #define task_pt_regs(tsk)	((struct pt_regs *) ((tsk)->thread.esp0))
161c23b6538SGreg Ungerer 
162633ea5d7SGreg Ungerer #define cpu_relax()	barrier()
163633ea5d7SGreg Ungerer 
16449148020SSam Ravnborg #endif
165