1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * include/asm-m68k/processor.h 4 * 5 * Copyright (C) 1995 Hamish Macdonald 6 */ 7 8 #ifndef __ASM_M68K_PROCESSOR_H 9 #define __ASM_M68K_PROCESSOR_H 10 11 #include <linux/thread_info.h> 12 #include <asm/fpu.h> 13 #include <asm/ptrace.h> 14 15 static inline unsigned long rdusp(void) 16 { 17 #ifdef CONFIG_COLDFIRE_SW_A7 18 extern unsigned int sw_usp; 19 return sw_usp; 20 #else 21 register unsigned long usp __asm__("a0"); 22 /* move %usp,%a0 */ 23 __asm__ __volatile__(".word 0x4e68" : "=a" (usp)); 24 return usp; 25 #endif 26 } 27 28 static inline void wrusp(unsigned long usp) 29 { 30 #ifdef CONFIG_COLDFIRE_SW_A7 31 extern unsigned int sw_usp; 32 sw_usp = usp; 33 #else 34 register unsigned long a0 __asm__("a0") = usp; 35 /* move %a0,%usp */ 36 __asm__ __volatile__(".word 0x4e60" : : "a" (a0) ); 37 #endif 38 } 39 40 /* 41 * User space process size: 3.75GB. This is hardcoded into a few places, 42 * so don't change it unless you know what you are doing. 43 */ 44 #ifdef CONFIG_MMU 45 #if defined(CONFIG_COLDFIRE) 46 #define TASK_SIZE (0xC0000000UL) 47 #elif defined(CONFIG_SUN3) 48 #define TASK_SIZE (0x0E000000UL) 49 #else 50 #define TASK_SIZE (0xF0000000UL) 51 #endif 52 #else 53 #define TASK_SIZE (0xFFFFFFFFUL) 54 #endif 55 56 #ifdef __KERNEL__ 57 #define STACK_TOP TASK_SIZE 58 #define STACK_TOP_MAX STACK_TOP 59 #endif 60 61 /* This decides where the kernel will search for a free chunk of vm 62 * space during mmap's. 63 */ 64 #ifdef CONFIG_MMU 65 #if defined(CONFIG_COLDFIRE) 66 #define TASK_UNMAPPED_BASE 0x60000000UL 67 #elif defined(CONFIG_SUN3) 68 #define TASK_UNMAPPED_BASE 0x0A000000UL 69 #else 70 #define TASK_UNMAPPED_BASE 0xC0000000UL 71 #endif 72 #define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr) 73 #else 74 #define TASK_UNMAPPED_BASE 0 75 #endif 76 77 /* Address spaces (or Function Codes in Motorola lingo) */ 78 #define USER_DATA 1 79 #define USER_PROGRAM 2 80 #define SUPER_DATA 5 81 #define SUPER_PROGRAM 6 82 #define CPU_SPACE 7 83 84 #ifdef CONFIG_CPU_HAS_ADDRESS_SPACES 85 /* 86 * Set the SFC/DFC registers for special MM operations. For most normal 87 * operation these remain set to USER_DATA for the uaccess routines. 88 */ 89 static inline void set_fc(unsigned long val) 90 { 91 WARN_ON_ONCE(in_interrupt()); 92 93 __asm__ __volatile__ ("movec %0,%/sfc\n\t" 94 "movec %0,%/dfc\n\t" 95 : /* no outputs */ : "r" (val) : "memory"); 96 } 97 #else 98 static inline void set_fc(unsigned long val) 99 { 100 } 101 #endif /* CONFIG_CPU_HAS_ADDRESS_SPACES */ 102 103 struct thread_struct { 104 unsigned long ksp; /* kernel stack pointer */ 105 unsigned long usp; /* user stack pointer */ 106 unsigned short sr; /* saved status register */ 107 unsigned short fc; /* saved fc (sfc, dfc) */ 108 unsigned long crp[2]; /* cpu root pointer */ 109 unsigned long esp0; /* points to SR of stack frame */ 110 unsigned long faddr; /* info about last fault */ 111 int signo, code; 112 unsigned long fp[8*3]; 113 unsigned long fpcntl[3]; /* fp control regs */ 114 unsigned char fpstate[FPSTATESIZE]; /* floating point state */ 115 }; 116 117 #define INIT_THREAD { \ 118 .ksp = sizeof(init_stack) + (unsigned long) init_stack, \ 119 .sr = PS_S, \ 120 .fc = USER_DATA, \ 121 } 122 123 /* 124 * ColdFire stack format sbould be 0x4 for an aligned usp (will always be 125 * true on thread creation). We need to set this explicitly. 126 */ 127 #ifdef CONFIG_COLDFIRE 128 #define setframeformat(_regs) do { (_regs)->format = 0x4; } while(0) 129 #else 130 #define setframeformat(_regs) do { } while (0) 131 #endif 132 133 /* 134 * Do necessary setup to start up a newly executed thread. 135 */ 136 static inline void start_thread(struct pt_regs * regs, unsigned long pc, 137 unsigned long usp) 138 { 139 regs->pc = pc; 140 regs->sr &= ~0x2000; 141 setframeformat(regs); 142 wrusp(usp); 143 } 144 145 /* Forward declaration, a strange C thing */ 146 struct task_struct; 147 148 /* Free all resources held by a thread. */ 149 static inline void release_thread(struct task_struct *dead_task) 150 { 151 } 152 153 unsigned long __get_wchan(struct task_struct *p); 154 void show_registers(struct pt_regs *regs); 155 156 #define KSTK_EIP(tsk) \ 157 ({ \ 158 unsigned long eip = 0; \ 159 if ((tsk)->thread.esp0 > PAGE_SIZE && \ 160 (virt_addr_valid((tsk)->thread.esp0))) \ 161 eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ 162 eip; }) 163 #define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) 164 165 #define task_pt_regs(tsk) ((struct pt_regs *) ((tsk)->thread.esp0)) 166 167 #define cpu_relax() barrier() 168 169 #endif 170