1 /* $NetBSD: cpu.h,v 1.30 2003/03/13 17:30:38 matt Exp $ */ 2 3 /* 4 * Copyright (C) 1999 Wolfgang Solfrank. 5 * Copyright (C) 1999 TooLs GmbH. 6 * Copyright (C) 1995-1997 Wolfgang Solfrank. 7 * Copyright (C) 1995-1997 TooLs GmbH. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by TooLs GmbH. 21 * 4. The name of TooLs GmbH may not be used to endorse or promote products 22 * derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 30 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 #ifndef _POWERPC_CPU_H_ 36 #define _POWERPC_CPU_H_ 37 38 struct cache_info { 39 int dcache_size; 40 int dcache_line_size; 41 int icache_size; 42 int icache_line_size; 43 }; 44 45 #ifdef _KERNEL 46 #if defined(_KERNEL_OPT) 47 #include "opt_lockdebug.h" 48 #include "opt_multiprocessor.h" 49 #include "opt_ppcarch.h" 50 #endif 51 52 #include <machine/frame.h> 53 #include <machine/psl.h> 54 #include <machine/intr.h> 55 #include <sys/device.h> 56 57 #include <sys/sched.h> 58 #include <dev/sysmon/sysmonvar.h> 59 60 struct cpu_info { 61 struct schedstate_percpu ci_schedstate; /* scheduler state */ 62 struct device *ci_dev; /* device of corresponding cpu */ 63 struct lwp *ci_curlwp; /* current owner of the processor */ 64 65 struct pcb *ci_curpcb; 66 struct pmap *ci_curpm; 67 struct lwp *ci_fpulwp; 68 struct lwp *ci_veclwp; 69 struct pcb *ci_idle_pcb; /* PA of our idle pcb */ 70 int ci_cpuid; 71 72 volatile int ci_astpending; 73 int ci_want_resched; 74 volatile u_long ci_lasttb; 75 volatile int ci_tickspending; 76 int ci_cpl; 77 int ci_iactive; 78 int ci_ipending; 79 int ci_intrdepth; 80 char *ci_intstk; 81 char *ci_spillstk; 82 register_t ci_tempsave[8]; 83 register_t ci_ddbsave[8]; 84 register_t ci_ipkdbsave[8]; 85 register_t ci_disisave[4]; 86 struct cache_info ci_ci; 87 struct sysmon_envsys ci_sysmon; 88 struct envsys_tre_data ci_tau_info; 89 struct evcnt ci_ev_clock; /* clock intrs */ 90 struct evcnt ci_ev_softclock; /* softclock intrs */ 91 struct evcnt ci_ev_softnet; /* softnet intrs */ 92 struct evcnt ci_ev_softserial; /* softserial intrs */ 93 struct evcnt ci_ev_traps; /* calls to trap() */ 94 struct evcnt ci_ev_kdsi; /* kernel DSI traps */ 95 struct evcnt ci_ev_udsi; /* user DSI traps */ 96 struct evcnt ci_ev_udsi_fatal; /* user DSI trap failures */ 97 struct evcnt ci_ev_isi; /* user ISI traps */ 98 struct evcnt ci_ev_isi_fatal; /* user ISI trap failures */ 99 struct evcnt ci_ev_pgm; /* user PGM traps */ 100 struct evcnt ci_ev_fpu; /* FPU traps */ 101 struct evcnt ci_ev_fpusw; /* FPU context switch */ 102 struct evcnt ci_ev_ali; /* Alignment traps */ 103 struct evcnt ci_ev_ali_fatal; /* Alignment fatal trap */ 104 struct evcnt ci_ev_scalls; /* system call traps */ 105 struct evcnt ci_ev_vec; /* Altivec traps */ 106 struct evcnt ci_ev_vecsw; /* Altivec context switches */ 107 struct evcnt ci_ev_umchk; /* user MCHK events */ 108 #if defined(DIAGNOSTIC) || defined(LOCKDEBUG) 109 u_long ci_spin_locks; /* # of spin locks held */ 110 u_long ci_simple_locks; /* # of simple locks held */ 111 #endif 112 }; 113 114 #ifdef MULTIPROCESSOR 115 static __inline int 116 cpu_number(void) 117 { 118 int pir; 119 120 __asm ("mfspr %0,1023" : "=r"(pir)); 121 return pir; 122 } 123 124 void cpu_boot_secondary_processors(void); 125 126 127 #define CPU_IS_PRIMARY(ci) ((ci)->ci_cpuid == 0) 128 #define CPU_INFO_ITERATOR int 129 #define CPU_INFO_FOREACH(cii, ci) \ 130 cii = 0, ci = &cpu_info[0]; cii < CPU_MAXNUM; cii++, ci++ 131 132 #else 133 134 #define cpu_number() 0 135 136 #define CPU_INFO_ITERATOR int 137 #define CPU_INFO_FOREACH(cii, ci) \ 138 cii = 0, ci = curcpu(); ci != NULL; ci = NULL 139 140 #endif /* MULTIPROCESSOR */ 141 142 extern struct cpu_info cpu_info[]; 143 144 static __inline struct cpu_info * 145 curcpu(void) 146 { 147 struct cpu_info *ci; 148 149 __asm __volatile ("mfsprg %0,0" : "=r"(ci)); 150 return ci; 151 } 152 153 #define curlwp (curcpu()->ci_curlwp) 154 #define curpcb (curcpu()->ci_curpcb) 155 #define curpm (curcpu()->ci_curpm) 156 157 static __inline register_t 158 mfmsr(void) 159 { 160 register_t msr; 161 162 __asm __volatile ("mfmsr %0" : "=r"(msr)); 163 return msr; 164 } 165 166 static __inline void 167 mtmsr(register_t msr) 168 { 169 170 __asm __volatile ("mtmsr %0" : : "r"(msr)); 171 } 172 173 static __inline uint32_t 174 mftbl(void) 175 { 176 uint32_t tbl; 177 178 __asm __volatile ( 179 #ifdef PPC_IBM403 180 " mftblo %0 \n" 181 #else 182 " mftbl %0 \n" 183 #endif 184 : "=r" (tbl)); 185 186 return tbl; 187 } 188 189 static __inline uint64_t 190 mftb(void) 191 { 192 uint64_t tb; 193 int tmp; 194 195 __asm __volatile ( 196 #ifdef PPC_IBM403 197 "1: mftbhi %0 \n" 198 " mftblo %0+1 \n" 199 " mftbhi %1 \n" 200 #else 201 "1: mftbu %0 \n" 202 " mftb %0+1 \n" 203 " mftbu %1 \n" 204 #endif 205 " cmplw %0,%1 \n" 206 " bne- 1b \n" 207 : "=r" (tb), "=r"(tmp) :: "cr0"); 208 209 return tb; 210 } 211 212 static __inline uint32_t 213 mfrtcl(void) 214 { 215 uint32_t rtcl; 216 217 __asm __volatile ("mfrtcl %0" : "=r"(rtcl)); 218 return rtcl; 219 } 220 221 static __inline void 222 mfrtc(uint32_t *rtcp) 223 { 224 uint32_t tmp; 225 226 __asm __volatile ( 227 "1: mfrtcu %0 \n" 228 " mfrtcl %1 \n" 229 " mfrtcu %2 \n" 230 " cmplw %0,%2 \n" 231 " bne- 1b" 232 : "=r"(*rtcp), "=r"(*(rtcp + 1)), "=r"(tmp)); 233 } 234 235 static __inline uint32_t 236 mfpvr(void) 237 { 238 uint32_t pvr; 239 240 __asm __volatile ("mfpvr %0" : "=r"(pvr)); 241 return (pvr); 242 } 243 244 #define CLKF_USERMODE(frame) (((frame)->srr1 & PSL_PR) != 0) 245 #define CLKF_BASEPRI(frame) ((frame)->pri == 0) 246 #define CLKF_PC(frame) ((frame)->srr0) 247 #define CLKF_INTR(frame) ((frame)->depth > 0) 248 249 #define LWP_PC(l) (trapframe(l)->srr0) 250 251 #define cpu_swapout(p) 252 #define cpu_wait(p) 253 #define cpu_proc_fork(p1, p2) 254 255 extern int powersave; 256 extern int cpu_timebase; 257 extern int cpu_printfataltraps; 258 extern char cpu_model[]; 259 260 struct cpu_info *cpu_attach_common(struct device *, int); 261 void cpu_setup(struct device *, struct cpu_info *); 262 void cpu_identify(char *, size_t); 263 void delay (unsigned int); 264 void cpu_probe_cache(void); 265 void dcache_flush_page(vaddr_t); 266 void icache_flush_page(vaddr_t); 267 void dcache_flush(vaddr_t, vsize_t); 268 void icache_flush(vaddr_t, vsize_t); 269 270 #define DELAY(n) delay(n) 271 272 #define need_resched(ci) (ci->ci_want_resched = 1, ci->ci_astpending = 1) 273 #define need_proftick(p) ((p)->p_flag |= P_OWEUPC, curcpu()->ci_astpending = 1) 274 #define signotify(p) (curcpu()->ci_astpending = 1) 275 276 #ifdef PPC_OEA 277 void oea_init(void (*)(void)); 278 void oea_startup(const char *); 279 void oea_dumpsys(void); 280 void oea_install_extint(void (*)(void)); 281 void *mapiodev(paddr_t, psize_t); 282 paddr_t kvtop(caddr_t); 283 void softnet(int); 284 285 extern paddr_t msgbuf_paddr; 286 extern int cpu_altivec; 287 #endif 288 289 #endif /* _KERNEL */ 290 291 #if defined(_KERNEL) || defined(_STANDALONE) 292 #if !defined(CACHELINESIZE) 293 #ifdef PPC_IBM403 294 #define CACHELINESIZE 16 295 #else 296 #define CACHELINESIZE 32 297 #endif 298 #endif 299 #endif 300 301 void __syncicache(void *, size_t); 302 303 /* 304 * CTL_MACHDEP definitions. 305 */ 306 #define CPU_CACHELINE 1 307 #define CPU_TIMEBASE 2 308 #define CPU_CPUTEMP 3 309 #define CPU_PRINTFATALTRAPS 4 310 #define CPU_CACHEINFO 5 311 #define CPU_ALTIVEC 6 312 #define CPU_MODEL 7 313 #define CPU_POWERSAVE 8 314 #define CPU_MAXID 9 315 316 #define CTL_MACHDEP_NAMES { \ 317 { 0, 0 }, \ 318 { "cachelinesize", CTLTYPE_INT }, \ 319 { "timebase", CTLTYPE_INT }, \ 320 { "cputempature", CTLTYPE_INT }, \ 321 { "printfataltraps", CTLTYPE_INT }, \ 322 { "cacheinfo", CTLTYPE_STRUCT }, \ 323 { "altivec", CTLTYPE_INT }, \ 324 { "model", CTLTYPE_STRING }, \ 325 { "powersave", CTLTYPE_INT }, \ 326 } 327 328 #endif /* _POWERPC_CPU_H_ */ 329