Annotation of src/sys/arch/i386/include/cpu.h, Revision 1.116.4.1
1.116.4.1! kent 1: /* $NetBSD: cpu.h,v 1.117 2005/02/21 15:10:51 he Exp $ */
1.24 cgd 2:
1.1 cgd 3: /*-
4: * Copyright (c) 1990 The Regents of the University of California.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to Berkeley by
8: * William Jolitz.
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.
1.103 agc 18: * 3. Neither the name of the University nor the names of its contributors
1.1 cgd 19: * may be used to endorse or promote products derived from this software
20: * without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32: * SUCH DAMAGE.
33: *
1.24 cgd 34: * @(#)cpu.h 5.4 (Berkeley) 5/9/91
1.1 cgd 35: */
36:
1.14 mycroft 37: #ifndef _I386_CPU_H_
38: #define _I386_CPU_H_
39:
1.108 simonb 40: #ifdef _KERNEL
1.71 mrg 41: #if defined(_KERNEL_OPT)
1.63 thorpej 42: #include "opt_multiprocessor.h"
1.108 simonb 43: #include "opt_math_emulate.h"
44: #include "opt_user_ldt.h"
45: #include "opt_vm86.h"
1.63 thorpej 46: #endif
47:
1.1 cgd 48: /*
49: * Definitions unique to i386 cpu support.
50: */
1.12 mycroft 51: #include <machine/frame.h>
52: #include <machine/segments.h>
1.83 fvdl 53: #include <machine/tss.h>
1.89 fvdl 54: #include <machine/intrdefs.h>
1.100 fvdl 55: #include <x86/cacheinfo.h>
1.63 thorpej 56:
1.82 fvdl 57: #include <sys/device.h>
58: #include <sys/lock.h> /* will also get LOCKDEBUG */
1.116 yamt 59: #include <sys/cpu_data.h>
60: #include <sys/cc_microtime.h>
1.70 thorpej 61:
1.105 yamt 62: #include <lib/libkern/libkern.h> /* offsetof */
63:
1.89 fvdl 64: struct intrsource;
1.113 yamt 65: struct pmap;
1.85 fvdl 66:
1.82 fvdl 67: /*
68: * a bunch of this belongs in cpuvar.h; move it later..
69: */
70:
1.63 thorpej 71: struct cpu_info {
1.82 fvdl 72: struct device *ci_dev; /* pointer to our device */
73: struct cpu_info *ci_self; /* self-pointer */
74: void *ci_tlog_base; /* Trap log base */
75: int32_t ci_tlog_offset; /* Trap log current offset */
76: struct cpu_info *ci_next; /* next cpu */
77:
78: /*
79: * Public members.
80: */
1.95 thorpej 81: struct lwp *ci_curlwp; /* current owner of the processor */
1.82 fvdl 82: struct simplelock ci_slock; /* lock on this data structure */
83: cpuid_t ci_cpuid; /* our CPU ID */
1.90 fvdl 84: u_int ci_apicid; /* our APIC ID */
1.116 yamt 85: struct cpu_data ci_data; /* MI per-cpu data */
86: struct cc_microtime_state ci_cc;/* cc_microtime state */
1.82 fvdl 87:
88: /*
89: * Private members.
90: */
1.95 thorpej 91: struct lwp *ci_fpcurlwp; /* current owner of the FPU */
1.82 fvdl 92: int ci_fpsaving; /* save in progress */
93:
1.89 fvdl 94: volatile u_int32_t ci_tlb_ipi_mask;
95:
1.113 yamt 96: struct pmap *ci_pmap; /* current pmap */
97: int ci_want_pmapload; /* pmap_load() is needed */
98: int ci_tlbstate; /* one of TLBSTATE_ states. see below */
99: #define TLBSTATE_VALID 0 /* all user tlbs are valid */
100: #define TLBSTATE_LAZY 1 /* tlbs are valid but won't be kept uptodate */
101: #define TLBSTATE_STALE 2 /* we might have stale user tlbs */
102:
1.82 fvdl 103: struct pcb *ci_curpcb; /* VA of current HW PCB */
104: struct pcb *ci_idle_pcb; /* VA of current PCB */
105: int ci_idle_tss_sel; /* TSS selector of idle PCB */
106:
1.89 fvdl 107: struct intrsource *ci_isources[MAX_INTR_SOURCES];
108: u_int32_t ci_ipending;
109: int ci_ilevel;
110: int ci_idepth;
111: u_int32_t ci_imask[NIPL];
112: u_int32_t ci_iunmask[NIPL];
113:
1.82 fvdl 114: paddr_t ci_idle_pcb_paddr; /* PA of idle PCB */
115: u_int32_t ci_flags; /* flags; see below */
116: u_int32_t ci_ipis; /* interprocessor interrupts pending */
117: int sc_apic_version; /* local APIC version */
118:
119: int32_t ci_cpuid_level;
120: u_int32_t ci_signature; /* X86 cpuid type */
1.114 lukem 121: u_int32_t ci_feature_flags;/* X86 %edx CPUID feature bits */
122: u_int32_t ci_feature2_flags;/* X86 %ecx CPUID feature bits */
1.116.4.1! kent 123: u_int32_t ci_feature3_flags;/* X86 extended feature bits */
1.82 fvdl 124: u_int32_t ci_cpu_class; /* CPU class */
125: u_int32_t ci_brand_id; /* Intel brand id */
126: u_int32_t ci_vendor[4]; /* vendor string */
127: u_int32_t ci_cpu_serial[3]; /* PIII serial number */
128: u_int64_t ci_tsc_freq; /* cpu cycles/second */
129:
130: struct cpu_functions *ci_func; /* start/stop functions */
1.109 junyoung 131: void (*cpu_setup)(struct cpu_info *);
1.82 fvdl 132: /* proc-dependant init */
1.109 junyoung 133: void (*ci_info)(struct cpu_info *);
1.82 fvdl 134:
135: int ci_want_resched;
136: int ci_astpending;
137: struct trapframe *ci_ddb_regs;
1.69 thorpej 138:
1.73 thorpej 139: u_int ci_cflush_lsize; /* CFLUSH insn line size */
1.100 fvdl 140: struct x86_cache_info ci_cinfo[CAI_COUNT];
1.82 fvdl 141:
142: union descriptor *ci_gdt;
1.83 fvdl 143:
144: struct i386tss ci_doubleflt_tss;
145: struct i386tss ci_ddbipi_tss;
146:
147: char *ci_doubleflt_stack;
148: char *ci_ddbipi_stack;
1.89 fvdl 149:
1.97 fvdl 150: struct evcnt ci_ipi_events[X86_NIPI];
1.63 thorpej 151: };
152:
1.82 fvdl 153: /*
154: * Processor flag notes: The "primary" CPU has certain MI-defined
155: * roles (mostly relating to hardclock handling); we distinguish
156: * betwen the processor which booted us, and the processor currently
157: * holding the "primary" role just to give us the flexibility later to
158: * change primaries should we be sufficiently twisted.
159: */
160:
161: #define CPUF_BSP 0x0001 /* CPU is the original BSP */
162: #define CPUF_AP 0x0002 /* CPU is an AP */
163: #define CPUF_SP 0x0004 /* CPU is only processor */
164: #define CPUF_PRIMARY 0x0008 /* CPU is active primary processor */
165:
166: #define CPUF_APIC_CD 0x0010 /* CPU has apic configured */
167:
168: #define CPUF_PRESENT 0x1000 /* CPU is present */
169: #define CPUF_RUNNING 0x2000 /* CPU is running */
170: #define CPUF_PAUSE 0x4000 /* CPU is paused in DDB */
171: #define CPUF_GO 0x8000 /* CPU should start running */
172:
173: /*
174: * We statically allocate the CPU info for the primary CPU (or,
175: * the only CPU on uniprocessors), and the primary CPU is the
176: * first CPU on the CPU info list.
177: */
178: extern struct cpu_info cpu_info_primary;
179: extern struct cpu_info *cpu_info_list;
180:
181: #define CPU_INFO_ITERATOR int
182: #define CPU_INFO_FOREACH(cii, ci) cii = 0, ci = cpu_info_list; \
183: ci != NULL; ci = ci->ci_next
184:
185: #if defined(MULTIPROCESSOR)
186:
1.97 fvdl 187: #define X86_MAXPROCS 32 /* because we use a bitmask */
1.82 fvdl 188:
189: #define CPU_STARTUP(_ci) ((_ci)->ci_func->start(_ci))
190: #define CPU_STOP(_ci) ((_ci)->ci_func->stop(_ci))
191: #define CPU_START_CLEANUP(_ci) ((_ci)->ci_func->cleanup(_ci))
192:
1.105 yamt 193: static struct cpu_info *curcpu(void);
194:
195: __inline static struct cpu_info * __attribute__((__unused__))
196: curcpu()
197: {
198: struct cpu_info *ci;
199:
200: __asm __volatile("movl %%fs:%1, %0" :
201: "=r" (ci) :
202: "m"
1.115 yamt 203: (*(struct cpu_info * const *)offsetof(struct cpu_info, ci_self)));
1.105 yamt 204: return ci;
205: }
206:
1.82 fvdl 207: #define cpu_number() (curcpu()->ci_cpuid)
208:
209: #define CPU_IS_PRIMARY(ci) ((ci)->ci_flags & CPUF_PRIMARY)
210:
1.95 thorpej 211: #define aston(p) ((p)->p_md.md_astpending = 1)
1.82 fvdl 212:
1.97 fvdl 213: extern struct cpu_info *cpu_info[X86_MAXPROCS];
1.82 fvdl 214:
1.109 junyoung 215: void cpu_boot_secondary_processors(void);
216: void cpu_init_idle_pcbs(void);
1.82 fvdl 217:
218: /*
219: * Preempt the current process if in interrupt from user mode,
220: * or after the current trap/syscall if in system mode.
221: */
1.109 junyoung 222: extern void need_resched(struct cpu_info *);
1.82 fvdl 223:
224: #else /* !MULTIPROCESSOR */
225:
1.97 fvdl 226: #define X86_MAXPROCS 1
1.82 fvdl 227: #define curcpu() (&cpu_info_primary)
1.95 thorpej 228:
1.1 cgd 229: /*
230: * definitions of cpu-dependent requirements
231: * referenced in generic code
232: */
1.82 fvdl 233: #define cpu_number() 0
1.89 fvdl 234: #define CPU_IS_PRIMARY(ci) 1
1.82 fvdl 235:
236: /*
237: * Preempt the current process if in interrupt from user mode,
238: * or after the current trap/syscall if in system mode.
239: */
240: #define need_resched(ci) \
241: do { \
242: struct cpu_info *__ci = (ci); \
243: __ci->ci_want_resched = 1; \
1.95 thorpej 244: if (__ci->ci_curlwp != NULL) \
245: aston(__ci->ci_curlwp->l_proc); \
1.89 fvdl 246: } while (/*CONSTCOND*/0)
1.82 fvdl 247:
1.95 thorpej 248: #define aston(p) ((p)->p_md.md_astpending = 1)
1.82 fvdl 249:
1.102 drochner 250: #endif /* MULTIPROCESSOR */
1.94 fvdl 251:
252: extern u_int32_t cpus_attached;
1.82 fvdl 253:
254: #define curpcb curcpu()->ci_curpcb
1.95 thorpej 255: #define curlwp curcpu()->ci_curlwp
1.1 cgd 256:
257: /*
1.18 mycroft 258: * Arguments to hardclock, softclock and statclock
1.1 cgd 259: * encapsulate the previous machine state in an opaque
260: * clockframe; for now, use generic intrframe.
1.12 mycroft 261: *
1.79 mycroft 262: * Note: Since spllowersoftclock() does not actually unmask the currently
263: * running (hardclock) interrupt, CLKF_BASEPRI() *must* always be 0; otherwise
264: * we could stall hardclock ticks if another interrupt takes too long.
1.1 cgd 265: */
1.17 cgd 266: #define clockframe intrframe
1.1 cgd 267:
1.30 mycroft 268: #define CLKF_USERMODE(frame) USERMODE((frame)->if_cs, (frame)->if_eflags)
1.79 mycroft 269: #define CLKF_BASEPRI(frame) (0)
1.17 cgd 270: #define CLKF_PC(frame) ((frame)->if_eip)
1.89 fvdl 271: #define CLKF_INTR(frame) (curcpu()->ci_idepth > 1)
1.67 mycroft 272:
273: /*
274: * This is used during profiling to integrate system time. It can safely
275: * assume that the process is resident.
276: */
1.95 thorpej 277: #define LWP_PC(l) ((l)->l_md.md_regs->tf_eip)
1.12 mycroft 278:
279: /*
280: * Give a profiling tick to the current process when the user profiling
281: * buffer pages are invalid. On the i386, request an ast to send us
282: * through trap(), marking the proc as needing a profiling tick.
1.1 cgd 283: */
1.95 thorpej 284: #define need_proftick(p) ((p)->p_flag |= P_OWEUPC, aston(p))
1.1 cgd 285:
286: /*
287: * Notify the current process (p) that it has a signal pending,
288: * process as soon as possible.
289: */
1.95 thorpej 290: #define signotify(p) aston(p)
1.26 mycroft 291:
292: /*
293: * We need a machine-independent name for this.
294: */
1.109 junyoung 295: extern void (*delay_func)(int);
1.82 fvdl 296: struct timeval;
1.109 junyoung 297: extern void (*microtime_func)(struct timeval *);
1.82 fvdl 298:
299: #define DELAY(x) (*delay_func)(x)
300: #define delay(x) (*delay_func)(x)
301: #define microtime(tv) (*microtime_func)(tv)
1.1 cgd 302:
303: /*
1.5 cgd 304: * pull in #defines for kinds of processors
1.1 cgd 305: */
1.15 mycroft 306: #include <machine/cputypes.h>
1.2 cgd 307:
1.38 fvdl 308: struct cpu_nocpuid_nameclass {
309: int cpu_vendor;
310: const char *cpu_vendorname;
311: const char *cpu_name;
312: int cpu_class;
1.109 junyoung 313: void (*cpu_setup)(struct cpu_info *);
314: void (*cpu_cacheinfo)(struct cpu_info *);
315: void (*cpu_info)(struct cpu_info *);
1.38 fvdl 316: };
317:
318:
319: struct cpu_cpuid_nameclass {
320: const char *cpu_id;
321: int cpu_vendor;
322: const char *cpu_vendorname;
323: struct cpu_cpuid_family {
324: int cpu_class;
325: const char *cpu_models[CPU_MAXMODEL+2];
1.109 junyoung 326: void (*cpu_setup)(struct cpu_info *);
327: void (*cpu_probe)(struct cpu_info *);
328: void (*cpu_info)(struct cpu_info *);
1.38 fvdl 329: } cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1];
1.6 cgd 330: };
331:
1.62 thorpej 332: extern int biosbasemem;
333: extern int biosextmem;
1.102 drochner 334: extern unsigned int cpu_feature;
1.114 lukem 335: extern unsigned int cpu_feature2;
1.3 cgd 336: extern int cpu;
1.8 cgd 337: extern int cpu_class;
1.114 lukem 338: extern char cpu_brand_string[];
1.66 jdolecek 339: extern const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[];
340: extern const struct cpu_cpuid_nameclass i386_cpuid_cpus[];
1.74 thorpej 341:
1.75 thorpej 342: extern int i386_use_fxsave;
343: extern int i386_has_sse;
344: extern int i386_has_sse2;
1.34 christos 345:
346: /* machdep.c */
1.109 junyoung 347: void dumpconf(void);
348: int cpu_maxproc(void);
349: void cpu_reset(void);
350: void i386_init_pcb_tss_ldt(struct cpu_info *);
351: void i386_proc0_tss_ldt_init(void);
1.98 fvdl 352:
353: /* identcpu.c */
354: extern int tmx86_has_longrun;
355: extern u_int crusoe_longrun;
356: extern u_int crusoe_frequency;
357: extern u_int crusoe_voltage;
358: extern u_int crusoe_percentage;
359: extern u_int tmx86_set_longrun_mode(u_int);
360: void tmx86_get_longrun_status_all(void);
361: u_int tmx86_get_longrun_mode(void);
1.109 junyoung 362: void identifycpu(struct cpu_info *);
1.34 christos 363:
1.95 thorpej 364: /* vm_machdep.c */
1.109 junyoung 365: void cpu_proc_fork(struct proc *, struct proc *);
1.95 thorpej 366:
1.34 christos 367: /* locore.s */
368: struct region_descriptor;
1.109 junyoung 369: void lgdt(struct region_descriptor *);
370: void fillw(short, void *, size_t);
1.34 christos 371:
372: struct pcb;
1.109 junyoung 373: void savectx(struct pcb *);
374: void proc_trampoline(void);
1.34 christos 375:
376: /* clock.c */
1.109 junyoung 377: void initrtclock(void);
378: void startrtclock(void);
379: void i8254_delay(int);
380: void i8254_microtime(struct timeval *);
381: void i8254_initclocks(void);
1.82 fvdl 382:
383: /* cpu.c */
384:
1.109 junyoung 385: void cpu_probe_features(struct cpu_info *);
1.34 christos 386:
387: /* npx.c */
1.109 junyoung 388: void npxsave_lwp(struct lwp *, int);
389: void npxsave_cpu(struct cpu_info *, int);
1.36 christos 390:
391: /* vm_machdep.c */
1.109 junyoung 392: int kvtop(caddr_t);
1.34 christos 393:
394: #ifdef MATH_EMULATE
395: /* math_emulate.c */
1.109 junyoung 396: int math_emulate(struct trapframe *, ksiginfo_t *);
1.3 cgd 397: #endif
1.34 christos 398:
399: #ifdef USER_LDT
400: /* sys_machdep.h */
1.109 junyoung 401: int i386_get_ldt(struct lwp *, void *, register_t *);
402: int i386_set_ldt(struct lwp *, void *, register_t *);
1.34 christos 403: #endif
404:
405: /* isa_machdep.c */
1.109 junyoung 406: void isa_defaultirq(void);
407: int isa_nmi(void);
1.34 christos 408:
409: #ifdef VM86
410: /* vm86.c */
1.109 junyoung 411: void vm86_gpfault(struct lwp *, int);
1.34 christos 412: #endif /* VM86 */
1.58 drochner 413:
414: /* consinit.c */
1.109 junyoung 415: void kgdb_port_init(void);
1.59 drochner 416:
417: /* bus_machdep.c */
1.109 junyoung 418: void x86_bus_space_init(void);
419: void x86_bus_space_mallocok(void);
1.34 christos 420:
1.108 simonb 421: #include <machine/psl.h> /* Must be after struct cpu_info declaration */
422:
1.114 lukem 423: /* est.c */
424: void est_init(struct cpu_info *);
425:
1.34 christos 426: #endif /* _KERNEL */
1.19 cgd 427:
1.82 fvdl 428: /*
1.19 cgd 429: * CTL_MACHDEP definitions.
430: */
431: #define CPU_CONSDEV 1 /* dev_t: console terminal device */
1.37 fvdl 432: #define CPU_BIOSBASEMEM 2 /* int: bios-reported base mem (K) */
433: #define CPU_BIOSEXTMEM 3 /* int: bios-reported ext. mem (K) */
434: #define CPU_NKPDE 4 /* int: number of kernel PDEs */
1.40 drochner 435: #define CPU_BOOTED_KERNEL 5 /* string: booted kernel name */
1.78 christos 436: #define CPU_DISKINFO 6 /* struct disklist *:
437: * disk geometry information */
438: #define CPU_FPU_PRESENT 7 /* int: FPU is present */
439: #define CPU_OSFXSR 8 /* int: OS uses FXSAVE/FXRSTOR */
440: #define CPU_SSE 9 /* int: OS/CPU supports SSE */
441: #define CPU_SSE2 10 /* int: OS/CPU supports SSE2 */
442: #define CPU_TMLR_MODE 11 /* int: longrun mode
443: * 0: minimum frequency
444: * 1: economy
445: * 2: performance
446: * 3: maximum frequency
447: */
448: #define CPU_TMLR_FREQUENCY 12 /* int: current frequency */
449: #define CPU_TMLR_VOLTAGE 13 /* int: curret voltage */
450: #define CPU_TMLR_PERCENTAGE 14 /* int: current clock percentage */
1.76 christos 451: #define CPU_MAXID 15 /* number of valid machdep ids */
1.19 cgd 452:
453: #define CTL_MACHDEP_NAMES { \
454: { 0, 0 }, \
455: { "console_device", CTLTYPE_STRUCT }, \
1.37 fvdl 456: { "biosbasemem", CTLTYPE_INT }, \
457: { "biosextmem", CTLTYPE_INT }, \
458: { "nkpde", CTLTYPE_INT }, \
1.40 drochner 459: { "booted_kernel", CTLTYPE_STRING }, \
1.52 fvdl 460: { "diskinfo", CTLTYPE_STRUCT }, \
1.56 fvdl 461: { "fpu_present", CTLTYPE_INT }, \
1.75 thorpej 462: { "osfxsr", CTLTYPE_INT }, \
463: { "sse", CTLTYPE_INT }, \
464: { "sse2", CTLTYPE_INT }, \
1.76 christos 465: { "tm_longrun_mode", CTLTYPE_INT }, \
466: { "tm_longrun_frequency", CTLTYPE_INT }, \
467: { "tm_longrun_voltage", CTLTYPE_INT }, \
468: { "tm_longrun_percentage", CTLTYPE_INT }, \
1.19 cgd 469: }
1.52 fvdl 470:
471: /*
472: * Structure for CPU_DISKINFO sysctl call.
473: * XXX this should be somewhere else.
474: */
475: #define MAX_BIOSDISKS 16
476:
477: struct disklist {
478: int dl_nbiosdisks; /* number of bios disks */
479: struct biosdisk_info {
480: int bi_dev; /* BIOS device # (0x80 ..) */
481: int bi_cyl; /* cylinders on disk */
482: int bi_head; /* heads per track */
483: int bi_sec; /* sectors per track */
484: u_int64_t bi_lbasecs; /* total sec. (iff ext13) */
485: #define BIFLAG_INVALID 0x01
486: #define BIFLAG_EXTINT13 0x02
487: int bi_flags;
488: } dl_biosdisks[MAX_BIOSDISKS];
489:
490: int dl_nnativedisks; /* number of native disks */
491: struct nativedisk_info {
492: char ni_devname[16]; /* native device name */
493: int ni_nmatches; /* # of matches w/ BIOS */
494: int ni_biosmatches[MAX_BIOSDISKS]; /* indices in dl_biosdisks */
495: } dl_nativedisks[1]; /* actually longer */
496: };
1.14 mycroft 497: #endif /* !_I386_CPU_H_ */
CVSweb <webmaster@jp.NetBSD.org>