Annotation of sys/arch/i386/include/cpu.h, Revision 1.1.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