1/* 2 * include/asm-sh/processor.h 3 * 4 * Copyright (C) 1999, 2000 Niibe Yutaka 5 */ 6 7#ifndef __ASM_SH_PROCESSOR_H 8#define __ASM_SH_PROCESSOR_H 9 10#include <asm/page.h> 11#include <asm/types.h> 12#include <linux/threads.h> 13 14/* 15 * Default implementation of macro that returns current 16 * instruction pointer ("program counter"). 17 */ 18#define current_text_addr() ({ void *pc; __asm__("mova 1f, %0\n1:":"=z" (pc)); pc; }) 19 20/* 21 * CPU type and hardware bug flags. Kept separately for each CPU. 22 */ 23enum cpu_type { 24 CPU_SH7708, /* Represents 7707, 7708, 7708S, 7708R, 7709 */ 25 CPU_SH7729, /* Represents 7709A, 7729 */ 26 CPU_SH7750, /* Represents 7750, 7751 */ 27 CPU_ST40STB1, 28 CPU_SH_NONE 29}; 30 31struct sh_cpuinfo { 32 enum cpu_type type; 33 char hard_math; 34 unsigned long loops_per_jiffy; 35 36 unsigned int cpu_clock, master_clock, bus_clock, module_clock; 37#ifdef CONFIG_CPU_SUBTYPE_ST40STB1 38 unsigned int memory_clock; 39#endif 40}; 41 42extern struct sh_cpuinfo boot_cpu_data; 43 44#define cpu_data (&boot_cpu_data) 45#define current_cpu_data boot_cpu_data 46 47/* 48 * User space process size: 2GB. 49 * 50 * Since SH7709 and SH7750 have "area 7", we can't use 0x7c000000--0x7fffffff 51 */ 52#define TASK_SIZE 0x7c000000UL 53 54/* This decides where the kernel will search for a free chunk of vm 55 * space during mmap's. 56 */ 57#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) 58 59/* 60 * Bit of SR register 61 * 62 * FD-bit: 63 * When it's set, it means the processor doesn't have right to use FPU, 64 * and it results exception when the floating operation is executed. 65 * 66 * IMASK-bit: 67 * Interrupt level mask 68 */ 69#define SR_FD 0x00008000 70#define SR_IMASK 0x000000f0 71 72/* 73 * FPU structure and data 74 */ 75 76struct sh_fpu_hard_struct { 77 unsigned long fp_regs[16]; 78 unsigned long xfp_regs[16]; 79 unsigned long fpscr; 80 unsigned long fpul; 81 82 long status; /* software status information */ 83}; 84 85/* Dummy fpu emulator */ 86struct sh_fpu_soft_struct { 87 unsigned long fp_regs[16]; 88 unsigned long xfp_regs[16]; 89 unsigned long fpscr; 90 unsigned long fpul; 91 92 unsigned char lookahead; 93 unsigned long entry_pc; 94}; 95 96union sh_fpu_union { 97 struct sh_fpu_hard_struct hard; 98 struct sh_fpu_soft_struct soft; 99}; 100 101struct thread_struct { 102 unsigned long sp; 103 unsigned long pc; 104 105 unsigned long trap_no, error_code; 106 unsigned long address; 107 /* Hardware debugging registers may come here */ 108 109 /* floating point info */ 110 union sh_fpu_union fpu; 111}; 112 113#define INIT_THREAD { \ 114 sizeof(init_stack) + (long) &init_stack, /* sp */ \ 115 0, /* pc */ \ 116 0, 0, \ 117 0, \ 118 {{{0,}},} /* fpu state */ \ 119} 120 121/* 122 * Do necessary setup to start up a newly executed thread. 123 */ 124#define start_thread(regs, new_pc, new_sp) \ 125 set_fs(USER_DS); \ 126 regs->pr = 0; \ 127 regs->sr = 0; /* User mode. */ \ 128 regs->pc = new_pc; \ 129 regs->regs[15] = new_sp 130 131/* Forward declaration, a strange C thing */ 132struct task_struct; 133struct mm_struct; 134 135/* Free all resources held by a thread. */ 136extern void release_thread(struct task_struct *); 137/* 138 * create a kernel thread without removing it from tasklists 139 */ 140extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); 141 142/* 143 * Bus types 144 */ 145#define EISA_bus 0 146#define EISA_bus__is_a_macro /* for versions in ksyms.c */ 147#define MCA_bus 0 148#define MCA_bus__is_a_macro /* for versions in ksyms.c */ 149 150 151/* Copy and release all segment info associated with a VM */ 152#define copy_segments(p, mm) do { } while(0) 153#define release_segments(mm) do { } while(0) 154 155/* 156 * FPU lazy state save handling. 157 */ 158 159static __inline__ void release_fpu(void) 160{ 161 unsigned long __dummy; 162 163 /* Set FD flag in SR */ 164 __asm__ __volatile__("stc sr, %0\n\t" 165 "or %1, %0\n\t" 166 "ldc %0, sr" 167 : "=&r" (__dummy) 168 : "r" (SR_FD)); 169} 170 171static __inline__ void grab_fpu(void) 172{ 173 unsigned long __dummy; 174 175 /* Clear out FD flag in SR */ 176 __asm__ __volatile__("stc sr, %0\n\t" 177 "and %1, %0\n\t" 178 "ldc %0, sr" 179 : "=&r" (__dummy) 180 : "r" (~SR_FD)); 181} 182 183extern void save_fpu(struct task_struct *__tsk); 184 185#define unlazy_fpu(tsk) do { \ 186 if ((tsk)->flags & PF_USEDFPU) { \ 187 grab_fpu(); \ 188 save_fpu(tsk); \ 189 } \ 190} while (0) 191 192#define clear_fpu(tsk) do { \ 193 if ((tsk)->flags & PF_USEDFPU) \ 194 (tsk)->flags &= ~PF_USEDFPU; \ 195} while (0) 196 197/* Double presision, NANS as NANS, rounding to nearest, no exceptions */ 198#define FPSCR_INIT 0x00080000 199 200/* 201 * Return saved PC of a blocked thread. 202 */ 203static __inline__ unsigned long thread_saved_pc(struct thread_struct *t) 204{ 205 return t->pc; 206} 207 208extern unsigned long get_wchan(struct task_struct *p); 209 210#define KSTK_EIP(tsk) ((tsk)->thread.pc) 211#define KSTK_ESP(tsk) ((tsk)->thread.sp) 212 213#define THREAD_SIZE (2*PAGE_SIZE) 214extern struct task_struct * alloc_task_struct(void); 215extern void free_task_struct(struct task_struct *); 216#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count) 217 218#define init_task (init_task_union.task) 219#define init_stack (init_task_union.stack) 220 221#define cpu_relax() do { } while (0) 222 223#endif /* __ASM_SH_PROCESSOR_H */ 224