1 /** $MirOS: src/sys/arch/i386/include/cpu.h,v 1.11 2010/07/25 16:37:59 tg Exp $ */ 2 /* $OpenBSD: cpu.h,v 1.59 2004/04/02 22:28:41 tedu Exp $ */ 3 /* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */ 4 5 /*- 6 * Copyright (c) 2006, 2008, 2010 7 * Thorsten Glaser <tg@mirbsd.org> 8 * Copyright (c) 1990 The Regents of the University of California. 9 * All rights reserved. 10 * 11 * This code is derived from software contributed to Berkeley by 12 * William Jolitz. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 3. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)cpu.h 5.4 (Berkeley) 5/9/91 39 */ 40 41 #ifndef _I386_CPU_H_ 42 #define _I386_CPU_H_ 43 44 /* 45 * Definitions unique to i386 cpu support. 46 */ 47 #include <machine/psl.h> 48 #include <machine/frame.h> 49 #include <machine/segments.h> 50 51 /* 52 * definitions of cpu-dependent requirements 53 * referenced in generic code 54 */ 55 #define cpu_swapin(p) /* nothing */ 56 57 /* 58 * Arguments to hardclock, softclock and statclock 59 * encapsulate the previous machine state in an opaque 60 * clockframe; for now, use generic intrframe. 61 * 62 * XXX intrframe has a lot of gunk we don't need. 63 */ 64 #define clockframe intrframe 65 66 #define CLKF_USERMODE(frame) USERMODE((frame)->if_cs, (frame)->if_eflags) 67 #define CLKF_PC(frame) ((frame)->if_eip) 68 #define CLKF_INTR(frame) (IDXSEL((frame)->if_cs) == GICODE_SEL) 69 70 /* 71 * Preempt the current process if in interrupt from user mode, 72 * or after the current trap/syscall if in system mode. 73 */ 74 int want_resched; /* resched() was called */ 75 #define need_resched() (want_resched = 1, setsoftast()) 76 77 /* 78 * Give a profiling tick to the current process when the user profiling 79 * buffer pages are invalid. On the i386, request an ast to send us 80 * through trap(), marking the proc as needing a profiling tick. 81 */ 82 #define need_proftick(p) ((p)->p_flag |= P_OWEUPC, setsoftast()) 83 84 /* 85 * Notify the current process (p) that it has a signal pending, 86 * process as soon as possible. 87 */ 88 #define signotify(p) setsoftast() 89 90 /* 91 * We need a machine-independent name for this. 92 */ 93 #define DELAY(x) delay(x) 94 void delay(int); 95 96 #if defined(I586_CPU) || defined(I686_CPU) 97 /* 98 * High resolution clock support (Pentium only) 99 */ 100 void calibrate_cyclecounter(void); 101 #ifndef HZ 102 #ifndef PENTIUM_BROKEN_TSC 103 extern u_quad_t pentium_base_tsc; 104 #define CPU_CLOCKUPDATE() \ 105 do { \ 106 if (pentium_mhz) { \ 107 __asm __volatile("cli\n" \ 108 "rdtsc\n" \ 109 "sti\n" \ 110 : "=A" (pentium_base_tsc) \ 111 : ); \ 112 } \ 113 } while (0) 114 #endif /* !PENTIUM_BROKEN_TSC */ 115 #define CPU_HARDCLOCKENT_DECL \ 116 static u_quad_t cpu_hce_tsc 117 #define CPU_HARDCLOCKENT() do { \ 118 if (pentium_mhz) { \ 119 u_quad_t cpu_hce_val = cpu_hce_tsc; \ 120 \ 121 __asm __volatile("cli\n" \ 122 "rdtsc\n" \ 123 "sti\n" \ 124 : "=A" (cpu_hce_tsc) : ); \ 125 HARDCLOCKENT_APPLY(cpu_hce_tsc - cpu_hce_val); \ 126 } \ 127 } while (0) 128 #endif /* !HZ */ 129 #define __do_calibrate_cyclecounter(rvptr) \ 130 do { \ 131 if (pentium_mhz) { \ 132 int i = splhigh(); \ 133 calibrate_cyclecounter(); \ 134 splx(i); \ 135 } \ 136 } while (0) 137 #else /* !(I586_CPU || I686_CPU) */ 138 #define __do_calibrate_cyclecounter(rvptr) /* nothing */ 139 #endif /* !(I586_CPU || I686_CPU) */ 140 141 /* 142 * pull in #defines for kinds of processors 143 */ 144 #include <machine/cputypes.h> 145 146 struct cpu_nocpuid_nameclass { 147 int cpu_vendor; 148 const char *cpu_vendorname; 149 const char *cpu_name; 150 int cpu_class; 151 void (*cpu_setup)(const char *, int, int); 152 }; 153 154 struct cpu_cpuid_nameclass { 155 const char *cpu_id; 156 int cpu_vendor; 157 const char *cpu_vendorname; 158 struct cpu_cpuid_family { 159 int cpu_class; 160 const char *cpu_models[CPU_MAXMODEL+2]; 161 void (*cpu_setup)(const char *, int, int); 162 } cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1]; 163 }; 164 165 struct cpu_cpuid_feature { 166 int feature_bit; 167 const char *feature_name; 168 }; 169 170 #ifdef _KERNEL 171 extern int cpu; 172 extern int cpu_class; 173 extern int cpu_feature; 174 extern int cpu_ecxfeature; 175 extern int cpu_apmwarn; 176 extern int cpu_apmhalt; 177 extern int cpuid_level; 178 extern const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[]; 179 extern const struct cpu_cpuid_nameclass i386_cpuid_cpus[]; 180 181 #if defined(I586_CPU) || defined(I686_CPU) 182 extern int pentium_mhz; 183 #endif 184 185 #ifdef I586_CPU 186 /* F00F bug fix stuff for pentium cpu */ 187 extern int cpu_f00f_bug; 188 void fix_f00f(void); 189 #endif 190 191 /* dkcsum.c */ 192 void dkcsumattach(void); 193 194 extern int i386_use_fxsave; 195 extern int i386_has_sse; 196 extern int i386_has_sse2; 197 198 /* machdep.c */ 199 void dumpconf(void); 200 void cpu_reset(void) __dead; 201 void i386_proc0_tss_ldt_init(void); 202 void cpuid(u_int32_t, u_int32_t *); 203 204 /* locore.s */ 205 struct region_descriptor; 206 void lgdt(struct region_descriptor *); 207 void fillw(short, void *, size_t); 208 209 struct pcb; 210 void savectx(struct pcb *); 211 void switch_exit(struct proc *); 212 void proc_trampoline(void); 213 214 /* clock.c */ 215 void initrtclock(void); 216 void startrtclock(void); 217 void rtcdrain(void *); 218 219 /* est.c */ 220 #if !defined(SMALL_KERNEL) && defined(I686_CPU) 221 void est_init(const char *); 222 int est_cpuspeed(int *); 223 int est_setperf(int); 224 #endif 225 226 /* longrun.c */ 227 #if !defined(SMALL_KERNEL) && defined(I586_CPU) 228 void longrun_init(void); 229 int longrun_cpuspeed(int *); 230 int longrun_setperf(int); 231 #endif 232 233 /* p4tcc.c */ 234 #if !defined(SMALL_KERNEL) && defined(I686_CPU) 235 void p4tcc_init(int, int); 236 int p4tcc_setperf(int); 237 #endif 238 239 void k6_powernow_init(void); 240 int k6_powernow_setperf(int); 241 void k7_powernow_init(void); 242 int k7_powernow_setperf(int); 243 244 245 /* npx.c */ 246 void npxdrop(void); 247 void npxsave(void); 248 249 #ifdef USER_LDT 250 /* sys_machdep.h */ 251 extern int user_ldt_enable; 252 int i386_get_ldt(struct proc *, void *, register_t *); 253 int i386_set_ldt(struct proc *, void *, register_t *); 254 #endif 255 256 /* isa_machdep.c */ 257 void isa_defaultirq(void); 258 int isa_nmi(void); 259 260 /* pmap.c */ 261 void pmap_bootstrap(vaddr_t); 262 263 /* vm_machdep.c */ 264 int kvtop(caddr_t); 265 266 #ifdef VM86 267 /* vm86.c */ 268 void vm86_gpfault(struct proc *, int); 269 #endif /* VM86 */ 270 271 #ifdef GENERIC 272 /* swapgeneric.c */ 273 void setconf(void); 274 #endif /* GENERIC */ 275 276 #endif /* _KERNEL */ 277 278 /* 279 * CTL_MACHDEP definitions. 280 */ 281 #define CPU_CONSDEV 1 /* dev_t: console terminal device */ 282 #define CPU_BIOS 2 /* BIOS variables */ 283 #define CPU_BLK2CHR 3 /* convert blk maj into chr one */ 284 #define CPU_CHR2BLK 4 /* convert chr maj into blk one */ 285 #define CPU_ALLOWAPERTURE 5 /* allow mmap of /dev/xf86 */ 286 #define CPU_CPUVENDOR 6 /* cpuid vendor string */ 287 #define CPU_CPUID 7 /* cpuid */ 288 #define CPU_CPUFEATURE 8 /* cpuid features */ 289 #define CPU_APMWARN 9 /* APM battery warning percentage */ 290 #define CPU_KBDRESET 10 /* keyboard reset under pcvt */ 291 #define CPU_APMHALT 11 /* halt -p hack */ 292 #define CPU_USERLDT 12 293 #define CPU_OSFXSR 13 /* uses FXSAVE/FXRSTOR */ 294 #define CPU_SSE 14 /* supports SSE */ 295 #define CPU_SSE2 15 /* supports SSE2 */ 296 #define CPU_XCRYPT 16 /* supports VIA xcrypt in userland */ 297 #define CPU_APVRESET 17 /* reset VGA on panic() if XF86 */ 298 #define CPU_MAXID 18 /* number of valid machdep ids */ 299 300 #define CTL_MACHDEP_NAMES { \ 301 { 0, 0 }, \ 302 { "console_device", CTLTYPE_STRUCT }, \ 303 { "bios", CTLTYPE_INT }, \ 304 { "blk2chr", CTLTYPE_STRUCT }, \ 305 { "chr2blk", CTLTYPE_STRUCT }, \ 306 { "allowaperture", CTLTYPE_INT }, \ 307 { "cpuvendor", CTLTYPE_STRING }, \ 308 { "cpuid", CTLTYPE_INT }, \ 309 { "cpufeature", CTLTYPE_INT }, \ 310 { "apmwarn", CTLTYPE_INT }, \ 311 { "kbdreset", CTLTYPE_INT }, \ 312 { "apmhalt", CTLTYPE_INT }, \ 313 { "userldt", CTLTYPE_INT }, \ 314 { "osfxsr", CTLTYPE_INT }, \ 315 { "sse", CTLTYPE_INT }, \ 316 { "sse2", CTLTYPE_INT }, \ 317 { "xcrypt", CTLTYPE_INT }, \ 318 { "apvreset", CTLTYPE_INT }, \ 319 } 320 321 #endif /* !_I386_CPU_H_ */ 322