Annotation of src/sys/arch/amd64/include/cpu.h, Revision 1.11
1.11 ! kardel 1: /* $NetBSD: cpu.h,v 1.10 2006/03/06 08:30:44 cube Exp $ */
1.1 fvdl 2:
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.2 agc 18: * 3. Neither the name of the University nor the names of its contributors
1.1 fvdl 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: *
34: * @(#)cpu.h 5.4 (Berkeley) 5/9/91
35: */
36:
37: #ifndef _AMD64_CPU_H_
38: #define _AMD64_CPU_H_
39:
1.6 yamt 40: #if defined(_KERNEL)
1.1 fvdl 41: #if defined(_KERNEL_OPT)
42: #include "opt_multiprocessor.h"
43: #include "opt_lockdebug.h"
44: #endif
45:
46: /*
47: * Definitions unique to x86-64 cpu support.
48: */
49: #include <machine/frame.h>
50: #include <machine/segments.h>
51: #include <machine/tss.h>
52: #include <machine/intrdefs.h>
53: #include <x86/cacheinfo.h>
54:
55: #include <sys/device.h>
56: #include <sys/lock.h>
1.4 yamt 57: #include <sys/cpu_data.h>
58: #include <sys/cc_microtime.h>
1.1 fvdl 59:
60: struct cpu_info {
61: struct device *ci_dev;
62: struct cpu_info *ci_self;
1.4 yamt 63: struct cpu_data ci_data; /* MI per-cpu data */
1.5 yamt 64: struct cc_microtime_state ci_cc;/* cc_microtime state */
1.1 fvdl 65: struct cpu_info *ci_next;
66:
67: struct lwp *ci_curlwp;
68: struct simplelock ci_slock;
69: u_int ci_cpuid;
70: u_int ci_apicid;
71:
72: u_int64_t ci_scratch;
73:
74: struct lwp *ci_fpcurlwp;
75: int ci_fpsaving;
76:
77: volatile u_int32_t ci_tlb_ipi_mask;
78:
79: struct pcb *ci_curpcb;
80: struct pcb *ci_idle_pcb;
81: int ci_idle_tss_sel;
82:
83: struct intrsource *ci_isources[MAX_INTR_SOURCES];
84: u_int32_t ci_ipending;
85: int ci_ilevel;
86: int ci_idepth;
87: u_int32_t ci_imask[NIPL];
88: u_int32_t ci_iunmask[NIPL];
89:
90: paddr_t ci_idle_pcb_paddr;
91: u_int ci_flags;
92: u_int32_t ci_ipis;
93:
94: u_int32_t ci_feature_flags;
95: u_int32_t ci_signature;
96: u_int64_t ci_tsc_freq;
97:
98: struct cpu_functions *ci_func;
99: void (*cpu_setup) __P((struct cpu_info *));
100: void (*ci_info) __P((struct cpu_info *));
101:
102: int ci_want_resched;
103: int ci_astpending;
104: struct trapframe *ci_ddb_regs;
105:
106: struct x86_cache_info ci_cinfo[CAI_COUNT];
107:
108: char *ci_gdt;
109:
110: struct x86_64_tss ci_doubleflt_tss;
111: struct x86_64_tss ci_ddbipi_tss;
112:
113: char *ci_doubleflt_stack;
114: char *ci_ddbipi_stack;
115:
116: struct evcnt ci_ipi_events[X86_NIPI];
117: };
118:
119: #define CPUF_BSP 0x0001 /* CPU is the original BSP */
120: #define CPUF_AP 0x0002 /* CPU is an AP */
121: #define CPUF_SP 0x0004 /* CPU is only processor */
122: #define CPUF_PRIMARY 0x0008 /* CPU is active primary processor */
123:
124: #define CPUF_PRESENT 0x1000 /* CPU is present */
125: #define CPUF_RUNNING 0x2000 /* CPU is running */
126: #define CPUF_PAUSE 0x4000 /* CPU is paused in DDB */
127: #define CPUF_GO 0x8000 /* CPU should start running */
128:
129:
130: extern struct cpu_info cpu_info_primary;
131: extern struct cpu_info *cpu_info_list;
132:
133: #define CPU_INFO_ITERATOR int
134: #define CPU_INFO_FOREACH(cii, ci) cii = 0, ci = cpu_info_list; \
135: ci != NULL; ci = ci->ci_next
136:
137: #if defined(MULTIPROCESSOR)
138:
139: #define X86_MAXPROCS 32 /* bitmask; can be bumped to 64 */
140:
141: #define CPU_STARTUP(_ci) ((_ci)->ci_func->start(_ci))
142: #define CPU_STOP(_ci) ((_ci)->ci_func->stop(_ci))
143: #define CPU_START_CLEANUP(_ci) ((_ci)->ci_func->cleanup(_ci))
144:
145: #define curcpu() ({struct cpu_info *__ci; \
1.9 perry 146: __asm volatile("movq %%gs:8,%0" : "=r" (__ci)); \
1.1 fvdl 147: __ci;})
148: #define cpu_number() (curcpu()->ci_cpuid)
149:
150: #define CPU_IS_PRIMARY(ci) ((ci)->ci_flags & CPUF_PRIMARY)
151:
152: extern struct cpu_info *cpu_info[X86_MAXPROCS];
153:
154: void cpu_boot_secondary_processors __P((void));
155: void cpu_init_idle_pcbs __P((void));
156:
157:
158: /*
159: * Preempt the current process if in interrupt from user mode,
160: * or after the current trap/syscall if in system mode.
161: */
162: extern void need_resched __P((struct cpu_info *));
163:
164: #else /* !MULTIPROCESSOR */
165:
166: #define X86_MAXPROCS 1
167:
168: extern struct cpu_info cpu_info_primary;
169:
170: #define curcpu() (&cpu_info_primary)
171:
172: /*
173: * definitions of cpu-dependent requirements
174: * referenced in generic code
175: */
176: #define cpu_number() 0
177: #define CPU_IS_PRIMARY(ci) 1
178:
179: /*
180: * Preempt the current process if in interrupt from user mode,
181: * or after the current trap/syscall if in system mode.
182: */
183:
184: #define need_resched(ci) \
185: do { \
186: struct cpu_info *__ci = (ci); \
187: __ci->ci_want_resched = 1; \
188: if (__ci->ci_curlwp != NULL) \
189: aston(__ci->ci_curlwp->l_proc); \
190: } while (/*CONSTCOND*/0)
191:
192: #endif
193:
194: #define aston(p) ((p)->p_md.md_astpending = 1)
195:
196: extern u_int32_t cpus_attached;
197:
198: #define curpcb curcpu()->ci_curpcb
199: #define curlwp curcpu()->ci_curlwp
200:
201: /*
202: * Arguments to hardclock, softclock and statclock
203: * encapsulate the previous machine state in an opaque
204: * clockframe; for now, use generic intrframe.
205: */
1.7 cube 206: struct clockframe {
207: struct intrframe cf_if;
208: };
1.1 fvdl 209:
1.7 cube 210: #define CLKF_USERMODE(frame) USERMODE((frame)->cf_if.if_cs, (frame)->cf_if.if_rflags)
1.1 fvdl 211: #define CLKF_BASEPRI(frame) (0)
1.7 cube 212: #define CLKF_PC(frame) ((frame)->cf_if.if_rip)
1.1 fvdl 213: #define CLKF_INTR(frame) (curcpu()->ci_idepth > 1)
214:
215: /*
216: * This is used during profiling to integrate system time. It can safely
217: * assume that the process is resident.
218: */
219: #define LWP_PC(l) ((l)->l_md.md_regs->tf_rip)
220:
221: /*
222: * Give a profiling tick to the current process when the user profiling
223: * buffer pages are invalid. On the i386, request an ast to send us
224: * through trap(), marking the proc as needing a profiling tick.
225: */
226: #define need_proftick(p) ((p)->p_flag |= P_OWEUPC, aston(p))
227:
228: /*
229: * Notify the current process (p) that it has a signal pending,
230: * process as soon as possible.
231: */
232: #define signotify(p) aston(p)
233:
234: /*
235: * We need a machine-independent name for this.
236: */
237: extern void (*delay_func) __P((int));
238:
239: #define DELAY(x) (*delay_func)(x)
240: #define delay(x) (*delay_func)(x)
241:
242:
243: /*
244: * pull in #defines for kinds of processors
245: */
246:
247: extern int biosbasemem;
248: extern int biosextmem;
249: extern int cpu;
250: extern int cpu_feature;
251: extern int cpu_id;
252: extern char cpu_vendor[];
253: extern int cpuid_level;
254:
255: /* identcpu.c */
256:
257: void identifycpu __P((struct cpu_info *));
258: void cpu_probe_features __P((struct cpu_info *));
259:
260: /* machdep.c */
261: void dumpconf __P((void));
262: int cpu_maxproc __P((void));
263: void cpu_reset __P((void));
264: void x86_64_proc0_tss_ldt_init __P((void));
265: void x86_64_init_pcb_tss_ldt __P((struct cpu_info *));
266: void cpu_proc_fork __P((struct proc *, struct proc *));
267:
268: struct region_descriptor;
269: void lgdt __P((struct region_descriptor *));
270: void fillw __P((short, void *, size_t));
271:
272: struct pcb;
273: void savectx __P((struct pcb *));
274: void switch_exit __P((struct lwp *, void (*)(struct lwp *)));
275: void proc_trampoline __P((void));
276: void child_trampoline __P((void));
277:
278: /* clock.c */
1.11 ! kardel 279: void initrtclock __P((u_long));
1.1 fvdl 280: void startrtclock __P((void));
281: void i8254_delay __P((int));
282: void i8254_microtime __P((struct timeval *));
283: void i8254_initclocks __P((void));
284:
285: void cpu_init_msrs __P((struct cpu_info *));
286:
287:
288: /* vm_machdep.c */
289: int kvtop __P((caddr_t));
290:
291: /* trap.c */
292: void child_return __P((void *));
293:
294: /* consinit.c */
295: void kgdb_port_init __P((void));
296:
297: /* bus_machdep.c */
298: void x86_bus_space_init __P((void));
299: void x86_bus_space_mallocok __P((void));
300:
301: #endif /* _KERNEL */
302:
303: #include <machine/psl.h>
304:
305: /*
306: * CTL_MACHDEP definitions.
307: */
308: #define CPU_CONSDEV 1 /* dev_t: console terminal device */
309: #define CPU_BIOSBASEMEM 2 /* int: bios-reported base mem (K) */
310: #define CPU_BIOSEXTMEM 3 /* int: bios-reported ext. mem (K) */
311: #define CPU_NKPDE 4 /* int: number of kernel PDEs */
312: #define CPU_BOOTED_KERNEL 5 /* string: booted kernel name */
313: #define CPU_DISKINFO 6 /* disk geometry information */
314: #define CPU_FPU_PRESENT 7 /* FPU is present */
315: #define CPU_MAXID 8 /* number of valid machdep ids */
316:
317: #define CTL_MACHDEP_NAMES { \
318: { 0, 0 }, \
319: { "console_device", CTLTYPE_STRUCT }, \
320: { "biosbasemem", CTLTYPE_INT }, \
321: { "biosextmem", CTLTYPE_INT }, \
322: { "nkpde", CTLTYPE_INT }, \
323: { "booted_kernel", CTLTYPE_STRING }, \
324: { "diskinfo", CTLTYPE_STRUCT }, \
325: { "fpu_present", CTLTYPE_INT }, \
326: }
327:
328:
329: /*
330: * Structure for CPU_DISKINFO sysctl call.
331: * XXX this should be somewhere else.
332: */
333: #define MAX_BIOSDISKS 16
334:
335: struct disklist {
336: int dl_nbiosdisks; /* number of bios disks */
337: struct biosdisk_info {
338: int bi_dev; /* BIOS device # (0x80 ..) */
339: int bi_cyl; /* cylinders on disk */
340: int bi_head; /* heads per track */
341: int bi_sec; /* sectors per track */
342: u_int64_t bi_lbasecs; /* total sec. (iff ext13) */
343: #define BIFLAG_INVALID 0x01
344: #define BIFLAG_EXTINT13 0x02
345: int bi_flags;
346: } dl_biosdisks[MAX_BIOSDISKS];
347:
348: int dl_nnativedisks; /* number of native disks */
349: struct nativedisk_info {
350: char ni_devname[16]; /* native device name */
351: int ni_nmatches; /* # of matches w/ BIOS */
352: int ni_biosmatches[MAX_BIOSDISKS]; /* indices in dl_biosdisks */
353: } dl_nativedisks[1]; /* actually longer */
354: };
355:
356: #endif /* !_AMD64_CPU_H_ */
CVSweb <webmaster@jp.NetBSD.org>