Annotation of sys/arch/i386/include/cpu.h, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: cpu.h,v 1.95 2007/06/07 11:20:58 dim Exp $ */
! 2: /* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */
! 3:
! 4: /*-
! 5: * Copyright (c) 1990 The Regents of the University of California.
! 6: * All rights reserved.
! 7: *
! 8: * This code is derived from software contributed to Berkeley by
! 9: * William Jolitz.
! 10: *
! 11: * Redistribution and use in source and binary forms, with or without
! 12: * modification, are permitted provided that the following conditions
! 13: * are met:
! 14: * 1. Redistributions of source code must retain the above copyright
! 15: * notice, this list of conditions and the following disclaimer.
! 16: * 2. Redistributions in binary form must reproduce the above copyright
! 17: * notice, this list of conditions and the following disclaimer in the
! 18: * documentation and/or other materials provided with the distribution.
! 19: * 3. Neither the name of the University nor the names of its contributors
! 20: * may be used to endorse or promote products derived from this software
! 21: * without specific prior written permission.
! 22: *
! 23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 33: * SUCH DAMAGE.
! 34: *
! 35: * @(#)cpu.h 5.4 (Berkeley) 5/9/91
! 36: */
! 37:
! 38: #ifndef _I386_CPU_H_
! 39: #define _I386_CPU_H_
! 40:
! 41: /*
! 42: * Definitions unique to i386 cpu support.
! 43: */
! 44: #include <machine/frame.h>
! 45: #include <machine/psl.h>
! 46: #include <machine/segments.h>
! 47: #include <machine/intrdefs.h>
! 48:
! 49: #ifdef MULTIPROCESSOR
! 50: #include <machine/i82489reg.h>
! 51: #include <machine/i82489var.h>
! 52:
! 53: /* XXX for now... */
! 54: #define NLAPIC 1
! 55:
! 56: #endif
! 57:
! 58: /*
! 59: * Arguments to hardclock, softclock and statclock
! 60: * encapsulate the previous machine state in an opaque
! 61: * clockframe; for now, use generic intrframe.
! 62: *
! 63: * XXX intrframe has a lot of gunk we don't need.
! 64: */
! 65: #define clockframe intrframe
! 66:
! 67: #include <sys/device.h>
! 68: #include <sys/lock.h> /* will also get LOCKDEBUG */
! 69: #include <sys/sched.h>
! 70: #include <sys/sensors.h>
! 71:
! 72: struct intrsource;
! 73:
! 74: #ifdef _KERNEL
! 75: /* XXX stuff to move to cpuvar.h later */
! 76: struct cpu_info {
! 77: struct device ci_dev; /* our device */
! 78: struct cpu_info *ci_self; /* pointer to this structure */
! 79: struct schedstate_percpu ci_schedstate; /* scheduler state */
! 80: struct cpu_info *ci_next; /* next cpu */
! 81:
! 82: /*
! 83: * Public members.
! 84: */
! 85: struct proc *ci_curproc; /* current owner of the processor */
! 86: struct simplelock ci_slock; /* lock on this data structure */
! 87: cpuid_t ci_cpuid; /* our CPU ID */
! 88: u_int ci_apicid; /* our APIC ID */
! 89: #if defined(DIAGNOSTIC) || defined(LOCKDEBUG)
! 90: u_long ci_spin_locks; /* # of spin locks held */
! 91: u_long ci_simple_locks; /* # of simple locks held */
! 92: #endif
! 93:
! 94: /*
! 95: * Private members.
! 96: */
! 97: struct proc *ci_fpcurproc; /* current owner of the FPU */
! 98: int ci_fpsaving; /* save in progress */
! 99:
! 100: volatile u_int32_t ci_tlb_ipi_mask;
! 101:
! 102: struct pcb *ci_curpcb; /* VA of current HW PCB */
! 103: struct pcb *ci_idle_pcb; /* VA of current PCB */
! 104: int ci_idle_tss_sel; /* TSS selector of idle PCB */
! 105:
! 106: struct intrsource *ci_isources[MAX_INTR_SOURCES];
! 107: u_int32_t ci_ipending;
! 108: int ci_ilevel;
! 109: int ci_idepth;
! 110: u_int32_t ci_imask[NIPL];
! 111: u_int32_t ci_iunmask[NIPL];
! 112:
! 113: paddr_t ci_idle_pcb_paddr; /* PA of idle PCB */
! 114: u_long ci_flags; /* flags; see below */
! 115: u_int32_t ci_ipis; /* interprocessor interrupts pending */
! 116: int sc_apic_version;/* local APIC version */
! 117: u_int64_t ci_tscbase;
! 118:
! 119: u_int32_t ci_level;
! 120: u_int32_t ci_vendor[4];
! 121: u_int32_t ci_signature; /* X86 cpuid type */
! 122: u_int32_t ci_feature_flags; /* X86 CPUID feature bits */
! 123: u_int32_t cpu_class; /* CPU class */
! 124:
! 125: struct cpu_functions *ci_func; /* start/stop functions */
! 126: void (*cpu_setup)(struct cpu_info *); /* proc-dependant init */
! 127:
! 128: int ci_want_resched;
! 129:
! 130: union descriptor *ci_gdt;
! 131: union descriptor *ci_ldt; /* per-cpu default LDT */
! 132: int ci_ldt_len; /* in bytes */
! 133:
! 134: volatile int ci_ddb_paused; /* paused due to other proc in ddb */
! 135: #define CI_DDB_RUNNING 0
! 136: #define CI_DDB_SHOULDSTOP 1
! 137: #define CI_DDB_STOPPED 2
! 138: #define CI_DDB_ENTERDDB 3
! 139: #define CI_DDB_INDDB 4
! 140:
! 141: volatile int ci_setperf_state;
! 142: #define CI_SETPERF_READY 0
! 143: #define CI_SETPERF_SHOULDSTOP 1
! 144: #define CI_SETPERF_INTRANSIT 2
! 145: #define CI_SETPERF_DONE 3
! 146:
! 147: struct ksensordev ci_sensordev;
! 148: struct ksensor ci_sensor;
! 149: };
! 150:
! 151: /*
! 152: * Processor flag notes: The "primary" CPU has certain MI-defined
! 153: * roles (mostly relating to hardclock handling); we distinguish
! 154: * betwen the processor which booted us, and the processor currently
! 155: * holding the "primary" role just to give us the flexibility later to
! 156: * change primaries should we be sufficiently twisted.
! 157: */
! 158:
! 159: #define CPUF_BSP 0x0001 /* CPU is the original BSP */
! 160: #define CPUF_AP 0x0002 /* CPU is an AP */
! 161: #define CPUF_SP 0x0004 /* CPU is only processor */
! 162: #define CPUF_PRIMARY 0x0008 /* CPU is active primary processor */
! 163: #define CPUF_APIC_CD 0x0010 /* CPU has apic configured */
! 164:
! 165: #define CPUF_PRESENT 0x1000 /* CPU is present */
! 166: #define CPUF_RUNNING 0x2000 /* CPU is running */
! 167:
! 168: /*
! 169: * We statically allocate the CPU info for the primary CPU (or,
! 170: * the only CPU on uniprocessors), and the primary CPU is the
! 171: * first CPU on the CPU info list.
! 172: */
! 173: extern struct cpu_info cpu_info_primary;
! 174: extern struct cpu_info *cpu_info_list;
! 175:
! 176: #define CPU_INFO_ITERATOR int
! 177: #define CPU_INFO_FOREACH(cii, ci) for (cii = 0, ci = cpu_info_list; \
! 178: ci != NULL; ci = ci->ci_next)
! 179:
! 180: #define CPU_INFO_UNIT(ci) ((ci)->ci_dev.dv_unit)
! 181:
! 182: #ifdef MULTIPROCESSOR
! 183:
! 184: #define I386_MAXPROCS 32 /* because we use a bitmask */
! 185:
! 186: #define CPU_STARTUP(_ci) ((_ci)->ci_func->start(_ci))
! 187: #define CPU_STOP(_ci) ((_ci)->ci_func->stop(_ci))
! 188: #define CPU_START_CLEANUP(_ci) ((_ci)->ci_func->cleanup(_ci))
! 189:
! 190: static struct cpu_info *curcpu(void);
! 191:
! 192: __inline static struct cpu_info *
! 193: curcpu(void)
! 194: {
! 195: struct cpu_info *ci;
! 196:
! 197: /* Can't include sys/param.h for offsetof() since it includes us */
! 198: __asm __volatile("movl %%fs:%1, %0" :
! 199: "=r" (ci) : "m"
! 200: (*(struct cpu_info * const *)&((struct cpu_info *)0)->ci_self));
! 201: return ci;
! 202: }
! 203: #define cpu_number() (curcpu()->ci_cpuid)
! 204:
! 205: #define CPU_IS_PRIMARY(ci) ((ci)->ci_flags & CPUF_PRIMARY)
! 206:
! 207: extern struct cpu_info *cpu_info[I386_MAXPROCS];
! 208: extern u_long cpus_running;
! 209:
! 210: extern void cpu_boot_secondary_processors(void);
! 211: extern void cpu_init_idle_pcbs(void);
! 212:
! 213: #else /* MULTIPROCESSOR */
! 214:
! 215: #define I386_MAXPROCS 1
! 216:
! 217: #define cpu_number() 0
! 218: #define curcpu() (&cpu_info_primary)
! 219:
! 220: #define CPU_IS_PRIMARY(ci) 1
! 221:
! 222: #endif
! 223:
! 224: #define curpcb curcpu()->ci_curpcb
! 225:
! 226: #define want_resched (curcpu()->ci_want_resched)
! 227:
! 228: /*
! 229: * Preempt the current process if in interrupt from user mode,
! 230: * or after the current trap/syscall if in system mode.
! 231: */
! 232: extern void need_resched(struct cpu_info *);
! 233:
! 234: #define CLKF_USERMODE(frame) USERMODE((frame)->if_cs, (frame)->if_eflags)
! 235: #define CLKF_PC(frame) ((frame)->if_eip)
! 236: #define CLKF_INTR(frame) (IDXSEL((frame)->if_cs) == GICODE_SEL)
! 237:
! 238: /*
! 239: * This is used during profiling to integrate system time.
! 240: */
! 241: #define PROC_PC(p) ((p)->p_md.md_regs->tf_eip)
! 242:
! 243: void aston(struct proc *);
! 244:
! 245: /*
! 246: * Give a profiling tick to the current process when the user profiling
! 247: * buffer pages are invalid. On the i386, request an ast to send us
! 248: * through trap(), marking the proc as needing a profiling tick.
! 249: */
! 250: #define need_proftick(p) aston(p)
! 251:
! 252: /*
! 253: * Notify the current process (p) that it has a signal pending,
! 254: * process as soon as possible.
! 255: */
! 256: #define signotify(p) aston(p)
! 257:
! 258: /*
! 259: * We need a machine-independent name for this.
! 260: */
! 261: extern void (*delay_func)(int);
! 262: struct timeval;
! 263:
! 264: #define DELAY(x) (*delay_func)(x)
! 265: #define delay(x) (*delay_func)(x)
! 266:
! 267: #if defined(I586_CPU) || defined(I686_CPU)
! 268: /*
! 269: * High resolution clock support (Pentium only)
! 270: */
! 271: void calibrate_cyclecounter(void);
! 272: #endif
! 273:
! 274: /*
! 275: * pull in #defines for kinds of processors
! 276: */
! 277: #include <machine/cputypes.h>
! 278:
! 279: struct cpu_nocpuid_nameclass {
! 280: int cpu_vendor;
! 281: const char *cpu_vendorname;
! 282: const char *cpu_name;
! 283: int cpu_class;
! 284: void (*cpu_setup)(struct cpu_info *);
! 285: };
! 286:
! 287: struct cpu_cpuid_nameclass {
! 288: const char *cpu_id;
! 289: int cpu_vendor;
! 290: const char *cpu_vendorname;
! 291: struct cpu_cpuid_family {
! 292: int cpu_class;
! 293: const char *cpu_models[CPU_MAXMODEL+2];
! 294: void (*cpu_setup)(struct cpu_info *);
! 295: } cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1];
! 296: };
! 297:
! 298: struct cpu_cpuid_feature {
! 299: int feature_bit;
! 300: const char *feature_name;
! 301: };
! 302:
! 303: /* locore.s */
! 304: extern int cpu;
! 305: extern int cpu_id;
! 306: extern char cpu_vendor[]; /* note: NOT nul-terminated */
! 307: extern char cpu_brandstr[];
! 308: extern int cpuid_level;
! 309: extern int cpu_miscinfo;
! 310: extern int cpu_feature;
! 311: extern int cpu_ecxfeature;
! 312: extern int cpu_cache_eax;
! 313: extern int cpu_cache_ebx;
! 314: extern int cpu_cache_ecx;
! 315: extern int cpu_cache_edx;
! 316: /* machdep.c */
! 317: extern int cpu_apmhalt;
! 318: extern int cpu_class;
! 319: extern char cpu_model[];
! 320: extern const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[];
! 321: extern const struct cpu_cpuid_nameclass i386_cpuid_cpus[];
! 322: /* apm.c */
! 323: extern int cpu_apmwarn;
! 324:
! 325: #if defined(I586_CPU) || defined(I686_CPU)
! 326: extern int cpuspeed;
! 327: #endif
! 328:
! 329: #if !defined(SMALL_KERNEL)
! 330: #define BUS66 6667
! 331: #define BUS100 10000
! 332: #define BUS133 13333
! 333: #define BUS166 16667
! 334: #define BUS200 20000
! 335: #define BUS266 26667
! 336: #define BUS333 33333
! 337: extern int bus_clock;
! 338: #endif
! 339:
! 340: #ifdef I586_CPU
! 341: /* F00F bug fix stuff for pentium cpu */
! 342: extern int cpu_f00f_bug;
! 343: void fix_f00f(void);
! 344: #endif
! 345:
! 346: /* dkcsum.c */
! 347: void dkcsumattach(void);
! 348:
! 349: extern int i386_use_fxsave;
! 350: extern int i386_has_sse;
! 351: extern int i386_has_sse2;
! 352:
! 353: extern void (*update_cpuspeed)(void);
! 354:
! 355: /* machdep.c */
! 356: void dumpconf(void);
! 357: void cpu_reset(void);
! 358: void i386_proc0_tss_ldt_init(void);
! 359: void i386_init_pcb_tss_ldt(struct cpu_info *);
! 360: void cpuid(u_int32_t, u_int32_t *);
! 361:
! 362: /* locore.s */
! 363: struct region_descriptor;
! 364: void lgdt(struct region_descriptor *);
! 365: void fillw(short, void *, size_t);
! 366:
! 367: struct pcb;
! 368: void savectx(struct pcb *);
! 369: void switch_exit(struct proc *);
! 370: void proc_trampoline(void);
! 371:
! 372: /* clock.c */
! 373: void initrtclock(void);
! 374: void startrtclock(void);
! 375: void rtcdrain(void *);
! 376: void i8254_delay(int);
! 377: void i8254_initclocks(void);
! 378: void i8254_inittimecounter(void);
! 379: void i8254_inittimecounter_simple(void);
! 380:
! 381:
! 382: /* est.c */
! 383: #if !defined(SMALL_KERNEL) && defined(I686_CPU)
! 384: void est_init(const char *, int);
! 385: void est_setperf(int);
! 386: #endif
! 387:
! 388: /* longrun.c */
! 389: #if !defined(SMALL_KERNEL) && defined(I586_CPU)
! 390: void longrun_init(void);
! 391: void longrun_setperf(int);
! 392: #endif
! 393:
! 394: /* p4tcc.c */
! 395: #if !defined(SMALL_KERNEL) && defined(I686_CPU)
! 396: void p4tcc_init(int, int);
! 397: void p4tcc_setperf(int);
! 398: #endif
! 399:
! 400: #if !defined(SMALL_KERNEL) && defined(I586_CPU)
! 401: /* powernow.c */
! 402: void k6_powernow_init(void);
! 403: void k6_powernow_setperf(int);
! 404: #endif
! 405: #if !defined(SMALL_KERNEL) && defined(I686_CPU)
! 406: /* powernow-k7.c */
! 407: void k7_powernow_init(void);
! 408: void k7_powernow_setperf(int);
! 409: /* powernow-k8.c */
! 410: void k8_powernow_init(void);
! 411: void k8_powernow_setperf(int);
! 412: #endif
! 413:
! 414: /* npx.c */
! 415: void npxdrop(struct proc *);
! 416: void npxsave_proc(struct proc *, int);
! 417: void npxsave_cpu(struct cpu_info *, int);
! 418:
! 419: #ifdef USER_LDT
! 420: /* sys_machdep.h */
! 421: extern int user_ldt_enable;
! 422: int i386_get_ldt(struct proc *, void *, register_t *);
! 423: int i386_set_ldt(struct proc *, void *, register_t *);
! 424: #endif
! 425:
! 426: /* isa_machdep.c */
! 427: void isa_defaultirq(void);
! 428: void isa_nodefaultirq(void);
! 429: int isa_nmi(void);
! 430:
! 431: /* pmap.c */
! 432: void pmap_bootstrap(vaddr_t);
! 433:
! 434: /* vm_machdep.c */
! 435: int kvtop(caddr_t);
! 436:
! 437: #ifdef MULTIPROCESSOR
! 438: /* mp_setperf.c */
! 439: void mp_setperf_init(void);
! 440: #endif
! 441:
! 442: #ifdef VM86
! 443: /* vm86.c */
! 444: void vm86_gpfault(struct proc *, int);
! 445: #endif /* VM86 */
! 446:
! 447: #ifdef GENERIC
! 448: /* swapgeneric.c */
! 449: void setconf(void);
! 450: #endif /* GENERIC */
! 451:
! 452: #endif /* _KERNEL */
! 453:
! 454: /*
! 455: * CTL_MACHDEP definitions.
! 456: */
! 457: #define CPU_CONSDEV 1 /* dev_t: console terminal device */
! 458: #define CPU_BIOS 2 /* BIOS variables */
! 459: #define CPU_BLK2CHR 3 /* convert blk maj into chr one */
! 460: #define CPU_CHR2BLK 4 /* convert chr maj into blk one */
! 461: #define CPU_ALLOWAPERTURE 5 /* allow mmap of /dev/xf86 */
! 462: #define CPU_CPUVENDOR 6 /* cpuid vendor string */
! 463: #define CPU_CPUID 7 /* cpuid */
! 464: #define CPU_CPUFEATURE 8 /* cpuid features */
! 465: #define CPU_APMWARN 9 /* APM battery warning percentage */
! 466: #define CPU_KBDRESET 10 /* keyboard reset under pcvt */
! 467: #define CPU_APMHALT 11 /* halt -p hack */
! 468: #define CPU_USERLDT 12
! 469: #define CPU_OSFXSR 13 /* uses FXSAVE/FXRSTOR */
! 470: #define CPU_SSE 14 /* supports SSE */
! 471: #define CPU_SSE2 15 /* supports SSE2 */
! 472: #define CPU_XCRYPT 16 /* supports VIA xcrypt in userland */
! 473: #define CPU_MAXID 17 /* number of valid machdep ids */
! 474:
! 475: #define CTL_MACHDEP_NAMES { \
! 476: { 0, 0 }, \
! 477: { "console_device", CTLTYPE_STRUCT }, \
! 478: { "bios", CTLTYPE_INT }, \
! 479: { "blk2chr", CTLTYPE_STRUCT }, \
! 480: { "chr2blk", CTLTYPE_STRUCT }, \
! 481: { "allowaperture", CTLTYPE_INT }, \
! 482: { "cpuvendor", CTLTYPE_STRING }, \
! 483: { "cpuid", CTLTYPE_INT }, \
! 484: { "cpufeature", CTLTYPE_INT }, \
! 485: { "apmwarn", CTLTYPE_INT }, \
! 486: { "kbdreset", CTLTYPE_INT }, \
! 487: { "apmhalt", CTLTYPE_INT }, \
! 488: { "userldt", CTLTYPE_INT }, \
! 489: { "osfxsr", CTLTYPE_INT }, \
! 490: { "sse", CTLTYPE_INT }, \
! 491: { "sse2", CTLTYPE_INT }, \
! 492: { "xcrypt", CTLTYPE_INT }, \
! 493: }
! 494:
! 495: /*
! 496: * This needs to be included late since it relies on definitions higher
! 497: * up in this file.
! 498: */
! 499: #if defined(MULTIPROCESSOR) && defined(_KERNEL)
! 500: #include <sys/mplock.h>
! 501: #endif
! 502:
! 503: #endif /* !_I386_CPU_H_ */
CVSweb