1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2005,2006,2007,2008 Imagination Technologies 4 */ 5 6 #ifndef __ASM_METAG_PROCESSOR_H 7 #define __ASM_METAG_PROCESSOR_H 8 9 #include <linux/atomic.h> 10 11 #include <asm/page.h> 12 #include <asm/ptrace.h> 13 #include <asm/metag_regs.h> 14 15 /* 16 * Default implementation of macro that returns current 17 * instruction pointer ("program counter"). 18 */ 19 #define current_text_addr() ({ __label__ _l; _l: &&_l; }) 20 21 /* The task stops where the kernel starts */ 22 #define TASK_SIZE PAGE_OFFSET 23 /* Add an extra page of padding at the top of the stack for the guard page. */ 24 #define STACK_TOP (TASK_SIZE - PAGE_SIZE) 25 #define STACK_TOP_MAX STACK_TOP 26 /* Maximum virtual space for stack */ 27 #define STACK_SIZE_MAX (CONFIG_MAX_STACK_SIZE_MB*1024*1024) 28 29 /* This decides where the kernel will search for a free chunk of vm 30 * space during mmap's. 31 */ 32 #define TASK_UNMAPPED_BASE META_MEMORY_BASE 33 34 typedef struct { 35 unsigned long seg; 36 } mm_segment_t; 37 38 #ifdef CONFIG_METAG_FPU 39 struct meta_fpu_context { 40 TBICTXEXTFPU fpstate; 41 union { 42 struct { 43 TBICTXEXTBB4 fx8_15; 44 TBICTXEXTFPACC fpacc; 45 } fx8_15; 46 struct { 47 TBICTXEXTFPACC fpacc; 48 TBICTXEXTBB4 unused; 49 } nofx8_15; 50 } extfpstate; 51 bool needs_restore; 52 }; 53 #else 54 struct meta_fpu_context {}; 55 #endif 56 57 #ifdef CONFIG_METAG_DSP 58 struct meta_ext_context { 59 struct { 60 TBIEXTCTX ctx; 61 TBICTXEXTBB8 bb8; 62 TBIDUAL ax[TBICTXEXTAXX_BYTES / sizeof(TBIDUAL)]; 63 TBICTXEXTHL2 hl2; 64 TBICTXEXTTDPR ext; 65 TBICTXEXTRP6 rp; 66 } regs; 67 68 /* DSPRAM A and B save areas. */ 69 void *ram[2]; 70 71 /* ECH encoded size of DSPRAM save areas. */ 72 unsigned int ram_sz[2]; 73 }; 74 #else 75 struct meta_ext_context {}; 76 #endif 77 78 struct thread_struct { 79 PTBICTX kernel_context; 80 /* A copy of the user process Sig.SaveMask. */ 81 unsigned int user_flags; 82 struct meta_fpu_context *fpu_context; 83 void __user *tls_ptr; 84 unsigned short int_depth; 85 unsigned short txdefr_failure; 86 struct meta_ext_context *dsp_context; 87 }; 88 89 #define INIT_THREAD { \ 90 NULL, /* kernel_context */ \ 91 0, /* user_flags */ \ 92 NULL, /* fpu_context */ \ 93 NULL, /* tls_ptr */ \ 94 1, /* int_depth - we start in kernel */ \ 95 0, /* txdefr_failure */ \ 96 NULL, /* dsp_context */ \ 97 } 98 99 /* Needed to make #define as we are referencing 'current', that is not visible 100 * yet. 101 * 102 * Stack layout is as below. 103 104 argc argument counter (integer) 105 argv[0] program name (pointer) 106 argv[1...N] program args (pointers) 107 argv[argc-1] end of args (integer) 108 NULL 109 env[0...N] environment variables (pointers) 110 NULL 111 112 */ 113 #define start_thread(regs, pc, usp) do { \ 114 unsigned int *argc = (unsigned int *) bprm->exec; \ 115 current->thread.int_depth = 1; \ 116 /* Force this process down to user land */ \ 117 regs->ctx.SaveMask = TBICTX_PRIV_BIT; \ 118 regs->ctx.CurrPC = pc; \ 119 regs->ctx.AX[0].U0 = usp; \ 120 regs->ctx.DX[3].U1 = *((int *)argc); /* argc */ \ 121 regs->ctx.DX[3].U0 = (int)((int *)argc + 1); /* argv */ \ 122 regs->ctx.DX[2].U1 = (int)((int *)argc + \ 123 regs->ctx.DX[3].U1 + 2); /* envp */ \ 124 regs->ctx.DX[2].U0 = 0; /* rtld_fini */ \ 125 } while (0) 126 127 /* Forward declaration, a strange C thing */ 128 struct task_struct; 129 130 /* Free all resources held by a thread. */ 131 static inline void release_thread(struct task_struct *dead_task) 132 { 133 } 134 135 /* 136 * Return saved PC of a blocked thread. 137 */ 138 #define thread_saved_pc(tsk) \ 139 ((unsigned long)(tsk)->thread.kernel_context->CurrPC) 140 #define thread_saved_sp(tsk) \ 141 ((unsigned long)(tsk)->thread.kernel_context->AX[0].U0) 142 #define thread_saved_fp(tsk) \ 143 ((unsigned long)(tsk)->thread.kernel_context->AX[1].U0) 144 145 unsigned long get_wchan(struct task_struct *p); 146 147 #define KSTK_EIP(tsk) (task_pt_regs(tsk)->ctx.CurrPC) 148 #define KSTK_ESP(tsk) (task_pt_regs(tsk)->ctx.AX[0].U0) 149 150 #define user_stack_pointer(regs) ((regs)->ctx.AX[0].U0) 151 152 #define cpu_relax() barrier() 153 154 extern void setup_priv(void); 155 156 static inline unsigned int hard_processor_id(void) 157 { 158 unsigned int id; 159 160 asm volatile ("MOV %0, TXENABLE\n" 161 "AND %0, %0, %1\n" 162 "LSR %0, %0, %2\n" 163 : "=&d" (id) 164 : "I" (TXENABLE_THREAD_BITS), 165 "K" (TXENABLE_THREAD_S) 166 ); 167 168 return id; 169 } 170 171 #define OP3_EXIT 0 172 173 #define HALT_OK 0 174 #define HALT_PANIC -1 175 176 /* 177 * Halt (stop) the hardware thread. This instruction sequence is the 178 * standard way to cause a Meta hardware thread to exit. The exit code 179 * is pushed onto the stack which is interpreted by the debug adapter. 180 */ 181 static inline void hard_processor_halt(int exit_code) 182 { 183 asm volatile ("MOV D1Ar1, %0\n" 184 "MOV D0Ar6, %1\n" 185 "MSETL [A0StP],D0Ar6,D0Ar4,D0Ar2\n" 186 "1:\n" 187 "SWITCH #0xC30006\n" 188 "B 1b\n" 189 : : "r" (exit_code), "K" (OP3_EXIT)); 190 } 191 192 /* Set these hooks to call SoC specific code to restart/halt/power off. */ 193 extern void (*soc_restart)(char *cmd); 194 extern void (*soc_halt)(void); 195 196 extern void show_trace(struct task_struct *tsk, unsigned long *sp, 197 struct pt_regs *regs); 198 199 extern const struct seq_operations cpuinfo_op; 200 201 #endif 202
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.