root/arch/i386/include/cpu.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. curcpu

    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_ */

/* [<][>][^][v][top][bottom][index][help] */