Annotation of src/sys/arch/i386/include/cpu.h, Revision 1.89
1.88 perry 1: /* $NetBSD: cpu.h,v 1.87 2002/10/06 20:40:27 fvdl 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.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the University of
21: * California, Berkeley and its contributors.
22: * 4. 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: *
1.24 cgd 38: * @(#)cpu.h 5.4 (Berkeley) 5/9/91
1.1 cgd 39: */
40:
1.14 mycroft 41: #ifndef _I386_CPU_H_
42: #define _I386_CPU_H_
43:
1.71 mrg 44: #if defined(_KERNEL_OPT)
1.63 thorpej 45: #include "opt_multiprocessor.h"
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.63 thorpej 55:
1.82 fvdl 56: #include <sys/device.h>
57: #include <sys/lock.h> /* will also get LOCKDEBUG */
1.63 thorpej 58: #include <sys/sched.h>
1.70 thorpej 59:
60: struct i386_cache_info {
1.82 fvdl 61: uint8_t cai_index;
62: uint8_t cai_desc;
63: uint8_t cai_associativity;
64: u_int cai_totalsize; /* #entries for TLB, bytes for cache */
65: u_int cai_linesize; /* or page size for TLB */
66: const char *cai_string;
1.70 thorpej 67: };
68:
69: #define CAI_ITLB 0 /* Instruction TLB (4K pages) */
70: #define CAI_ITLB2 1 /* Instruction TLB (2/4M pages) */
71: #define CAI_DTLB 2 /* Data TLB (4K pages) */
72: #define CAI_DTLB2 3 /* Data TLB (2/4M pages) */
73: #define CAI_ICACHE 4 /* Instruction cache */
74: #define CAI_DCACHE 5 /* Data cache */
75: #define CAI_L2CACHE 6 /* Level 2 cache */
76:
77: #define CAI_COUNT 7
78:
1.89 ! fvdl 79: struct intrsource;
1.85 fvdl 80:
1.82 fvdl 81: /*
82: * a bunch of this belongs in cpuvar.h; move it later..
83: */
84:
1.63 thorpej 85: struct cpu_info {
1.82 fvdl 86: struct device *ci_dev; /* pointer to our device */
87: struct cpu_info *ci_self; /* self-pointer */
88: void *ci_tlog_base; /* Trap log base */
89: int32_t ci_tlog_offset; /* Trap log current offset */
1.63 thorpej 90: struct schedstate_percpu ci_schedstate; /* scheduler state */
1.82 fvdl 91: struct cpu_info *ci_next; /* next cpu */
92:
93: /*
94: * Public members.
95: */
96: struct proc *ci_curproc; /* current owner of the processor */
97: struct simplelock ci_slock; /* lock on this data structure */
98: cpuid_t ci_cpuid; /* our CPU ID */
1.63 thorpej 99: u_long ci_spin_locks; /* # of spin locks held */
100: u_long ci_simple_locks; /* # of simple locks held */
1.82 fvdl 101:
102: /*
103: * Private members.
104: */
105: struct proc *ci_fpcurproc; /* current owner of the FPU */
106: int ci_fpsaving; /* save in progress */
107:
1.89 ! fvdl 108: volatile u_int32_t ci_tlb_ipi_mask;
! 109:
1.82 fvdl 110: struct pcb *ci_curpcb; /* VA of current HW PCB */
111: struct pcb *ci_idle_pcb; /* VA of current PCB */
112: int ci_idle_tss_sel; /* TSS selector of idle PCB */
113:
1.89 ! fvdl 114: struct intrsource *ci_isources[MAX_INTR_SOURCES];
! 115: u_int32_t ci_ipending;
! 116: int ci_ilevel;
! 117: int ci_idepth;
! 118: u_int32_t ci_imask[NIPL];
! 119: u_int32_t ci_iunmask[NIPL];
! 120:
1.82 fvdl 121: paddr_t ci_idle_pcb_paddr; /* PA of idle PCB */
122: u_int32_t ci_flags; /* flags; see below */
123: u_int32_t ci_ipis; /* interprocessor interrupts pending */
124: int sc_apic_version; /* local APIC version */
125:
126: int32_t ci_cpuid_level;
127: u_int32_t ci_signature; /* X86 cpuid type */
128: u_int32_t ci_feature_flags;/* X86 CPUID feature bits */
129: u_int32_t ci_cpu_class; /* CPU class */
130: u_int32_t ci_brand_id; /* Intel brand id */
131: u_int32_t ci_vendor[4]; /* vendor string */
132: u_int32_t ci_cpu_serial[3]; /* PIII serial number */
133: u_int64_t ci_tsc_freq; /* cpu cycles/second */
134:
135: struct cpu_functions *ci_func; /* start/stop functions */
136: void (*cpu_setup) __P((struct cpu_info *));
137: /* proc-dependant init */
138: void (*ci_info) __P((struct cpu_info *));
139:
140: int ci_want_resched;
141: int ci_astpending;
142: struct trapframe *ci_ddb_regs;
1.69 thorpej 143:
1.73 thorpej 144: u_int ci_cflush_lsize; /* CFLUSH insn line size */
1.70 thorpej 145: struct i386_cache_info ci_cinfo[CAI_COUNT];
1.82 fvdl 146:
147: /*
148: * Variables used by tsc_microtime().
149: */
150: struct timeval ci_tsc_time;
151: int64_t ci_tsc_tsc;
152: int64_t ci_tsc_ms_delta;
153: int64_t ci_tsc_denom;
154:
155: union descriptor *ci_gdt;
1.83 fvdl 156:
157: struct i386tss ci_doubleflt_tss;
158: struct i386tss ci_ddbipi_tss;
159:
160: char *ci_doubleflt_stack;
161: char *ci_ddbipi_stack;
1.89 ! fvdl 162:
! 163: struct evcnt ci_ipi_events[I386_NIPI];
1.63 thorpej 164: };
165:
1.82 fvdl 166: /*
167: * Processor flag notes: The "primary" CPU has certain MI-defined
168: * roles (mostly relating to hardclock handling); we distinguish
169: * betwen the processor which booted us, and the processor currently
170: * holding the "primary" role just to give us the flexibility later to
171: * change primaries should we be sufficiently twisted.
172: */
173:
174: #define CPUF_BSP 0x0001 /* CPU is the original BSP */
175: #define CPUF_AP 0x0002 /* CPU is an AP */
176: #define CPUF_SP 0x0004 /* CPU is only processor */
177: #define CPUF_PRIMARY 0x0008 /* CPU is active primary processor */
178:
179: #define CPUF_APIC_CD 0x0010 /* CPU has apic configured */
180:
181: #define CPUF_PRESENT 0x1000 /* CPU is present */
182: #define CPUF_RUNNING 0x2000 /* CPU is running */
183: #define CPUF_PAUSE 0x4000 /* CPU is paused in DDB */
184: #define CPUF_GO 0x8000 /* CPU should start running */
185:
186: /*
187: * We statically allocate the CPU info for the primary CPU (or,
188: * the only CPU on uniprocessors), and the primary CPU is the
189: * first CPU on the CPU info list.
190: */
191: extern struct cpu_info cpu_info_primary;
192: extern struct cpu_info *cpu_info_list;
193:
194: #define CPU_INFO_ITERATOR int
195: #define CPU_INFO_FOREACH(cii, ci) cii = 0, ci = cpu_info_list; \
196: ci != NULL; ci = ci->ci_next
197:
198: #if defined(MULTIPROCESSOR)
199:
200: #define I386_MAXPROCS 32 /* because we use a bitmask */
201:
202: #define CPU_STARTUP(_ci) ((_ci)->ci_func->start(_ci))
203: #define CPU_STOP(_ci) ((_ci)->ci_func->stop(_ci))
204: #define CPU_START_CLEANUP(_ci) ((_ci)->ci_func->cleanup(_ci))
205:
206: #define curcpu() ({struct cpu_info *ci; \
207: asm volatile("movl %%fs:4,%0" : "=r" (ci)); \
208: ci;})
209: #define cpu_number() (curcpu()->ci_cpuid)
210:
211: #define CPU_IS_PRIMARY(ci) ((ci)->ci_flags & CPUF_PRIMARY)
212:
213: #if 0
214: #define i386_ipisend(ci) (((ci) != curcpu()) ? i386_send_ipi((ci),0) : 0)
215: #else
216: #define i386_ipisend(ci) 0
217: #endif
218:
219: #define aston(ci) ((ci)->ci_astpending = 1, i386_ipisend(ci))
220:
221: extern struct cpu_info *cpu_info[I386_MAXPROCS];
222:
223: void cpu_boot_secondary_processors __P((void));
224: void cpu_init_idle_pcbs __P((void));
225:
226: /*
227: * Preempt the current process if in interrupt from user mode,
228: * or after the current trap/syscall if in system mode.
229: */
230: extern void need_resched __P((struct cpu_info *));
231:
232: #else /* !MULTIPROCESSOR */
233:
234: #define I386_MAXPROCS 1
235:
1.63 thorpej 236: #ifdef _KERNEL
1.82 fvdl 237: extern struct cpu_info cpu_info_primary;
1.63 thorpej 238:
1.82 fvdl 239: #define curcpu() (&cpu_info_primary)
1.63 thorpej 240: #endif
1.1 cgd 241:
242: /*
243: * definitions of cpu-dependent requirements
244: * referenced in generic code
245: */
1.82 fvdl 246: #define cpu_number() 0
1.89 ! fvdl 247: #define CPU_IS_PRIMARY(ci) 1
1.82 fvdl 248:
249: /*
250: * Preempt the current process if in interrupt from user mode,
251: * or after the current trap/syscall if in system mode.
252: */
253: #define need_resched(ci) \
254: do { \
255: struct cpu_info *__ci = (ci); \
256: __ci->ci_want_resched = 1; \
257: aston(__ci); \
1.89 ! fvdl 258: } while (/*CONSTCOND*/0)
1.82 fvdl 259:
260: #define aston(ci) (curcpu()->ci_astpending = 1)
261:
262: #endif
263:
264: #define curpcb curcpu()->ci_curpcb
265: #define curproc curcpu()->ci_curproc
1.1 cgd 266:
267: /*
1.18 mycroft 268: * Arguments to hardclock, softclock and statclock
1.1 cgd 269: * encapsulate the previous machine state in an opaque
270: * clockframe; for now, use generic intrframe.
1.12 mycroft 271: *
1.79 mycroft 272: * Note: Since spllowersoftclock() does not actually unmask the currently
273: * running (hardclock) interrupt, CLKF_BASEPRI() *must* always be 0; otherwise
274: * we could stall hardclock ticks if another interrupt takes too long.
1.1 cgd 275: */
1.17 cgd 276: #define clockframe intrframe
1.1 cgd 277:
1.30 mycroft 278: #define CLKF_USERMODE(frame) USERMODE((frame)->if_cs, (frame)->if_eflags)
1.79 mycroft 279: #define CLKF_BASEPRI(frame) (0)
1.17 cgd 280: #define CLKF_PC(frame) ((frame)->if_eip)
1.89 ! fvdl 281: #define CLKF_INTR(frame) (curcpu()->ci_idepth > 1)
1.67 mycroft 282:
283: /*
284: * This is used during profiling to integrate system time. It can safely
285: * assume that the process is resident.
286: */
287: #define PROC_PC(p) ((p)->p_md.md_regs->tf_eip)
1.12 mycroft 288:
289: /*
290: * Give a profiling tick to the current process when the user profiling
291: * buffer pages are invalid. On the i386, request an ast to send us
292: * through trap(), marking the proc as needing a profiling tick.
1.1 cgd 293: */
1.82 fvdl 294: #define need_proftick(p) ((p)->p_flag |= P_OWEUPC, aston(p->p_cpu))
1.1 cgd 295:
296: /*
297: * Notify the current process (p) that it has a signal pending,
298: * process as soon as possible.
299: */
1.82 fvdl 300: #define signotify(p) aston(p->p_cpu)
1.26 mycroft 301:
302: /*
303: * We need a machine-independent name for this.
304: */
1.82 fvdl 305: extern void (*delay_func) __P((int));
306: struct timeval;
307: extern void (*microtime_func) __P((struct timeval *));
308:
309: #define DELAY(x) (*delay_func)(x)
310: #define delay(x) (*delay_func)(x)
311: #define microtime(tv) (*microtime_func)(tv)
1.1 cgd 312:
313: /*
1.5 cgd 314: * pull in #defines for kinds of processors
1.1 cgd 315: */
1.15 mycroft 316: #include <machine/cputypes.h>
1.2 cgd 317:
1.38 fvdl 318: struct cpu_nocpuid_nameclass {
319: int cpu_vendor;
320: const char *cpu_vendorname;
321: const char *cpu_name;
322: int cpu_class;
1.82 fvdl 323: void (*cpu_setup) __P((struct cpu_info *));
1.69 thorpej 324: void (*cpu_cacheinfo) __P((struct cpu_info *));
1.82 fvdl 325: void (*cpu_info) __P((struct cpu_info *));
1.38 fvdl 326: };
327:
328:
329: struct cpu_cpuid_nameclass {
330: const char *cpu_id;
331: int cpu_vendor;
332: const char *cpu_vendorname;
333: struct cpu_cpuid_family {
334: int cpu_class;
335: const char *cpu_models[CPU_MAXMODEL+2];
1.82 fvdl 336: void (*cpu_setup) __P((struct cpu_info *));
337: void (*cpu_probe) __P((struct cpu_info *));
338: void (*cpu_info) __P((struct cpu_info *));
1.38 fvdl 339: } cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1];
1.6 cgd 340: };
341:
1.25 jtc 342: #ifdef _KERNEL
1.62 thorpej 343: extern int biosbasemem;
344: extern int biosextmem;
1.82 fvdl 345: extern int cpu_feature;
1.3 cgd 346: extern int cpu;
1.8 cgd 347: extern int cpu_class;
1.66 jdolecek 348: extern const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[];
349: extern const struct cpu_cpuid_nameclass i386_cpuid_cpus[];
1.74 thorpej 350:
1.75 thorpej 351: extern int i386_use_fxsave;
352: extern int i386_has_sse;
353: extern int i386_has_sse2;
1.34 christos 354:
355: /* machdep.c */
356: void dumpconf __P((void));
357: void cpu_reset __P((void));
1.82 fvdl 358: void i386_init_pcb_tss_ldt __P((struct cpu_info *));
1.53 thorpej 359: void i386_proc0_tss_ldt_init __P((void));
1.46 thorpej 360: void i386_bufinit __P((void));
1.34 christos 361:
362: /* locore.s */
363: struct region_descriptor;
364: void lgdt __P((struct region_descriptor *));
1.35 christos 365: void fillw __P((short, void *, size_t));
1.34 christos 366:
367: struct pcb;
368: void savectx __P((struct pcb *));
369: void switch_exit __P((struct proc *));
370: void proc_trampoline __P((void));
371:
372: /* clock.c */
1.57 enami 373: void initrtclock __P((void));
1.34 christos 374: void startrtclock __P((void));
1.82 fvdl 375: void i8254_delay __P((int));
376: void i8254_microtime __P((struct timeval *));
377: void i8254_initclocks __P((void));
378:
379: /* tsc_microtime.c */
380:
381: void tsc_microtime __P((struct timeval *));
382: void tsc_microset __P((struct cpu_info *));
383:
384: /* cpu.c */
385:
386: void cpu_probe_features __P((struct cpu_info *));
1.34 christos 387:
388: /* npx.c */
1.82 fvdl 389: void npxsave_proc __P((struct proc *, int));
390: void npxsave_cpu __P((struct cpu_info *, int));
1.36 christos 391:
392: /* vm_machdep.c */
393: int kvtop __P((caddr_t));
1.34 christos 394:
1.43 thorpej 395: #if !defined(_LKM)
396: #include "opt_math_emulate.h"
397: #endif
1.34 christos 398: #ifdef MATH_EMULATE
399: /* math_emulate.c */
400: int math_emulate __P((struct trapframe *));
1.3 cgd 401: #endif
1.34 christos 402:
1.44 thorpej 403: #if !defined(_LKM)
404: #include "opt_user_ldt.h"
405: #endif
1.34 christos 406: #ifdef USER_LDT
407: /* sys_machdep.h */
1.68 nathanw 408: int i386_get_ldt __P((struct proc *, void *, register_t *));
409: int i386_set_ldt __P((struct proc *, void *, register_t *));
1.34 christos 410: #endif
411:
412: /* isa_machdep.c */
413: void isa_defaultirq __P((void));
414: int isa_nmi __P((void));
415:
1.42 thorpej 416: #if !defined(_LKM)
417: #include "opt_vm86.h"
418: #endif
1.34 christos 419: #ifdef VM86
420: /* vm86.c */
421: void vm86_gpfault __P((struct proc *, int));
422: #endif /* VM86 */
1.58 drochner 423:
424: /* consinit.c */
425: void kgdb_port_init __P((void));
1.59 drochner 426:
427: /* bus_machdep.c */
428: void i386_bus_space_init __P((void));
429: void i386_bus_space_mallocok __P((void));
1.34 christos 430:
431: #endif /* _KERNEL */
1.19 cgd 432:
1.82 fvdl 433: #include <machine/psl.h>
434:
435: /*
1.19 cgd 436: * CTL_MACHDEP definitions.
437: */
438: #define CPU_CONSDEV 1 /* dev_t: console terminal device */
1.37 fvdl 439: #define CPU_BIOSBASEMEM 2 /* int: bios-reported base mem (K) */
440: #define CPU_BIOSEXTMEM 3 /* int: bios-reported ext. mem (K) */
441: #define CPU_NKPDE 4 /* int: number of kernel PDEs */
1.40 drochner 442: #define CPU_BOOTED_KERNEL 5 /* string: booted kernel name */
1.78 christos 443: #define CPU_DISKINFO 6 /* struct disklist *:
444: * disk geometry information */
445: #define CPU_FPU_PRESENT 7 /* int: FPU is present */
446: #define CPU_OSFXSR 8 /* int: OS uses FXSAVE/FXRSTOR */
447: #define CPU_SSE 9 /* int: OS/CPU supports SSE */
448: #define CPU_SSE2 10 /* int: OS/CPU supports SSE2 */
449: #define CPU_TMLR_MODE 11 /* int: longrun mode
450: * 0: minimum frequency
451: * 1: economy
452: * 2: performance
453: * 3: maximum frequency
454: */
455: #define CPU_TMLR_FREQUENCY 12 /* int: current frequency */
456: #define CPU_TMLR_VOLTAGE 13 /* int: curret voltage */
457: #define CPU_TMLR_PERCENTAGE 14 /* int: current clock percentage */
1.76 christos 458: #define CPU_MAXID 15 /* number of valid machdep ids */
1.19 cgd 459:
460: #define CTL_MACHDEP_NAMES { \
461: { 0, 0 }, \
462: { "console_device", CTLTYPE_STRUCT }, \
1.37 fvdl 463: { "biosbasemem", CTLTYPE_INT }, \
464: { "biosextmem", CTLTYPE_INT }, \
465: { "nkpde", CTLTYPE_INT }, \
1.40 drochner 466: { "booted_kernel", CTLTYPE_STRING }, \
1.52 fvdl 467: { "diskinfo", CTLTYPE_STRUCT }, \
1.56 fvdl 468: { "fpu_present", CTLTYPE_INT }, \
1.75 thorpej 469: { "osfxsr", CTLTYPE_INT }, \
470: { "sse", CTLTYPE_INT }, \
471: { "sse2", CTLTYPE_INT }, \
1.76 christos 472: { "tm_longrun_mode", CTLTYPE_INT }, \
473: { "tm_longrun_frequency", CTLTYPE_INT }, \
474: { "tm_longrun_voltage", CTLTYPE_INT }, \
475: { "tm_longrun_percentage", CTLTYPE_INT }, \
1.19 cgd 476: }
1.52 fvdl 477:
478:
479: /*
480: * Structure for CPU_DISKINFO sysctl call.
481: * XXX this should be somewhere else.
482: */
483: #define MAX_BIOSDISKS 16
484:
485: struct disklist {
486: int dl_nbiosdisks; /* number of bios disks */
487: struct biosdisk_info {
488: int bi_dev; /* BIOS device # (0x80 ..) */
489: int bi_cyl; /* cylinders on disk */
490: int bi_head; /* heads per track */
491: int bi_sec; /* sectors per track */
492: u_int64_t bi_lbasecs; /* total sec. (iff ext13) */
493: #define BIFLAG_INVALID 0x01
494: #define BIFLAG_EXTINT13 0x02
495: int bi_flags;
496: } dl_biosdisks[MAX_BIOSDISKS];
497:
498: int dl_nnativedisks; /* number of native disks */
499: struct nativedisk_info {
500: char ni_devname[16]; /* native device name */
501: int ni_nmatches; /* # of matches w/ BIOS */
502: int ni_biosmatches[MAX_BIOSDISKS]; /* indices in dl_biosdisks */
503: } dl_nativedisks[1]; /* actually longer */
504: };
1.14 mycroft 505:
506: #endif /* !_I386_CPU_H_ */
CVSweb <webmaster@jp.NetBSD.org>