Project

General

Profile

Statistics
| Revision:

root / lab4 / .minix-src / include / x86 / cpu.h @ 13

History | View | Annotate | Download (15.4 KB)

1 13 up20180614
/*        $NetBSD: cpu.h,v 1.66 2014/02/23 22:38:40 dsl Exp $        */
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.
18
 * 3. Neither the name of the University nor the names of its contributors
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 _X86_CPU_H_
38
#define _X86_CPU_H_
39
40
#if defined(_KERNEL) || defined(_STANDALONE)
41
#include <sys/types.h>
42
#else
43
#include <stdint.h>
44
#include <stdbool.h>
45
#endif /* _KERNEL || _STANDALONE */
46
47
#if defined(_KERNEL) || defined(_KMEMUSER)
48
#if defined(_KERNEL_OPT)
49
#include "opt_xen.h"
50
#ifdef i386
51
#include "opt_user_ldt.h"
52
#include "opt_vm86.h"
53
#endif
54
#endif
55
56
/*
57
 * Definitions unique to x86 cpu support.
58
 */
59
#include <machine/frame.h>
60
#include <machine/pte.h>
61
#include <machine/segments.h>
62
#include <machine/tss.h>
63
#include <machine/intrdefs.h>
64
65
#include <x86/cacheinfo.h>
66
67
#include <sys/cpu_data.h>
68
#include <sys/evcnt.h>
69
#include <sys/device_if.h> /* for device_t */
70
71
#ifdef XEN
72
#include <xen/xen-public/xen.h>
73
#include <xen/xen-public/event_channel.h>
74
#include <sys/mutex.h>
75
#endif /* XEN */
76
77
struct intrsource;
78
struct pmap;
79
80
#ifdef __x86_64__
81
#define        i386tss        x86_64_tss
82
#endif
83
84
#define        NIOPORTS        1024                /* # of ports we allow to be mapped */
85
#define        IOMAPSIZE        (NIOPORTS / 8)        /* I/O bitmap size in bytes */
86
87
/*
88
 * a bunch of this belongs in cpuvar.h; move it later..
89
 */
90
91
struct cpu_info {
92
        struct cpu_data ci_data;        /* MI per-cpu data */
93
        device_t ci_dev;                /* pointer to our device */
94
        struct cpu_info *ci_self;        /* self-pointer */
95
        volatile struct vcpu_info *ci_vcpu; /* for XEN */
96
        void        *ci_tlog_base;                /* Trap log base */
97
        int32_t ci_tlog_offset;                /* Trap log current offset */
98
99
        /*
100
         * Will be accessed by other CPUs.
101
         */
102
        struct cpu_info *ci_next;        /* next cpu */
103
        struct lwp *ci_curlwp;                /* current owner of the processor */
104
        struct lwp *ci_fpcurlwp;        /* current owner of the FPU */
105
        int        _unused1[2];
106
        cpuid_t ci_cpuid;                /* our CPU ID */
107
        int        _unused;
108
        uint32_t ci_acpiid;                /* our ACPI/MADT ID */
109
        uint32_t ci_initapicid;                /* our intitial APIC ID */
110
111
        /*
112
         * Private members.
113
         */
114
        struct evcnt ci_tlb_evcnt;        /* tlb shootdown counter */
115
        struct pmap *ci_pmap;                /* current pmap */
116
        int ci_need_tlbwait;                /* need to wait for TLB invalidations */
117
        int ci_want_pmapload;                /* pmap_load() is needed */
118
        volatile int ci_tlbstate;        /* one of TLBSTATE_ states. see below */
119
#define        TLBSTATE_VALID        0        /* all user tlbs are valid */
120
#define        TLBSTATE_LAZY        1        /* tlbs are valid but won't be kept uptodate */
121
#define        TLBSTATE_STALE        2        /* we might have stale user tlbs */
122
        int ci_curldt;                /* current LDT descriptor */
123
        int ci_nintrhand;        /* number of H/W interrupt handlers */
124
        uint64_t ci_scratch;
125
        uintptr_t ci_pmap_data[128 / sizeof(uintptr_t)];
126
127
#ifdef XEN
128
        struct iplsource  *ci_isources[NIPL];
129
        u_long ci_evtmask[NR_EVENT_CHANNELS]; /* events allowed on this CPU */
130
#else
131
        struct intrsource *ci_isources[MAX_INTR_SOURCES];
132
#endif
133
        volatile int        ci_mtx_count;        /* Negative count of spin mutexes */
134
        volatile int        ci_mtx_oldspl;        /* Old SPL at this ci_idepth */
135
136
        /* The following must be aligned for cmpxchg8b. */
137
        struct {
138
                uint32_t        ipending;
139
                int                ilevel;
140
        } ci_istate __aligned(8);
141
#define ci_ipending        ci_istate.ipending
142
#define        ci_ilevel        ci_istate.ilevel
143
144
        int                ci_idepth;
145
        void *                ci_intrstack;
146
        uint32_t        ci_imask[NIPL];
147
        uint32_t        ci_iunmask[NIPL];
148
149
        uint32_t ci_flags;                /* flags; see below */
150
        uint32_t ci_ipis;                /* interprocessor interrupts pending */
151
        uint32_t sc_apic_version;        /* local APIC version */
152
153
        uint32_t        ci_signature;         /* X86 cpuid type (cpuid.1.%eax) */
154
        uint32_t        ci_vendor[4];         /* vendor string */
155
        uint32_t        _unused2;
156
        uint32_t        ci_max_cpuid;        /* cpuid.0:%eax */
157
        uint32_t        ci_max_ext_cpuid; /* cpuid.80000000:%eax */
158
        volatile uint32_t        ci_lapic_counter;
159
160
        uint32_t        ci_feat_val[5]; /* X86 CPUID feature bits */
161
                        /* [0] basic features cpuid.1:%edx
162
                         * [1] basic features cpuid.1:%ecx (CPUID2_xxx bits)
163
                         * [2] extended features cpuid:80000001:%edx
164
                         * [3] extended features cpuid:80000001:%ecx
165
                         * [4] VIA padlock features
166
                         */
167
168
        const struct cpu_functions *ci_func;  /* start/stop functions */
169
        struct trapframe *ci_ddb_regs;
170
171
        u_int ci_cflush_lsize;        /* CFLUSH insn line size */
172
        struct x86_cache_info ci_cinfo[CAI_COUNT];
173
174
        union descriptor *ci_gdt;
175
176
#ifdef i386
177
        struct i386tss        ci_doubleflt_tss;
178
        struct i386tss        ci_ddbipi_tss;
179
#endif
180
181
#ifdef PAE
182
        uint32_t        ci_pae_l3_pdirpa; /* PA of L3 PD */
183
        pd_entry_t *        ci_pae_l3_pdir; /* VA pointer to L3 PD */
184
#endif
185
186
#if defined(XEN) && (defined(PAE) || defined(__x86_64__))
187
        /* Currently active user PGD (can't use rcr3() with Xen) */
188
        pd_entry_t *        ci_kpm_pdir;        /* per-cpu PMD (va) */
189
        paddr_t                ci_kpm_pdirpa;  /* per-cpu PMD (pa) */
190
        kmutex_t        ci_kpm_mtx;
191
#if defined(__x86_64__)
192
        /* per-cpu version of normal_pdes */
193
        pd_entry_t *        ci_normal_pdes[3]; /* Ok to hardcode. only for x86_64 && XEN */
194
        paddr_t                ci_xen_current_user_pgd;
195
#endif /* __x86_64__ */
196
#endif /* XEN et.al */
197
198
        char *ci_doubleflt_stack;
199
        char *ci_ddbipi_stack;
200
201
#ifndef XEN
202
        struct evcnt ci_ipi_events[X86_NIPI];
203
#else   /* XEN */
204
        struct evcnt ci_ipi_events[XEN_NIPIS];
205
        evtchn_port_t ci_ipi_evtchn;
206
#endif  /* XEN */
207
208
        device_t        ci_frequency;        /* Frequency scaling technology */
209
        device_t        ci_padlock;        /* VIA PadLock private storage */
210
        device_t        ci_temperature;        /* Intel coretemp(4) or equivalent */
211
        device_t        ci_vm;                /* Virtual machine guest driver */
212
213
        struct i386tss        ci_tss;                /* Per-cpu TSS; shared among LWPs */
214
        char                ci_iomap[IOMAPSIZE]; /* I/O Bitmap */
215
        int ci_tss_sel;                        /* TSS selector of this cpu */
216
217
        /*
218
         * The following two are actually region_descriptors,
219
         * but that would pollute the namespace.
220
         */
221
        uintptr_t        ci_suspend_gdt;
222
        uint16_t        ci_suspend_gdt_padding;
223
        uintptr_t        ci_suspend_idt;
224
        uint16_t        ci_suspend_idt_padding;
225
226
        uint16_t        ci_suspend_tr;
227
        uint16_t        ci_suspend_ldt;
228
        uintptr_t        ci_suspend_fs;
229
        uintptr_t        ci_suspend_gs;
230
        uintptr_t        ci_suspend_kgs;
231
        uintptr_t        ci_suspend_efer;
232
        uintptr_t        ci_suspend_reg[12];
233
        uintptr_t        ci_suspend_cr0;
234
        uintptr_t        ci_suspend_cr2;
235
        uintptr_t        ci_suspend_cr3;
236
        uintptr_t        ci_suspend_cr4;
237
        uintptr_t        ci_suspend_cr8;
238
239
        /* The following must be in a single cache line. */
240
        int                ci_want_resched __aligned(64);
241
        int                ci_padout __aligned(64);
242
};
243
244
/*
245
 * Macros to handle (some) trapframe registers for common x86 code.
246
 */
247
#ifdef __x86_64__
248
#define        X86_TF_RAX(tf)                tf->tf_rax
249
#define        X86_TF_RDX(tf)                tf->tf_rdx
250
#define        X86_TF_RSP(tf)                tf->tf_rsp
251
#define        X86_TF_RIP(tf)                tf->tf_rip
252
#define        X86_TF_RFLAGS(tf)        tf->tf_rflags
253
#else
254
#define        X86_TF_RAX(tf)                tf->tf_eax
255
#define        X86_TF_RDX(tf)                tf->tf_edx
256
#define        X86_TF_RSP(tf)                tf->tf_esp
257
#define        X86_TF_RIP(tf)                tf->tf_eip
258
#define        X86_TF_RFLAGS(tf)        tf->tf_eflags
259
#endif
260
261
/*
262
 * Processor flag notes: The "primary" CPU has certain MI-defined
263
 * roles (mostly relating to hardclock handling); we distinguish
264
 * betwen the processor which booted us, and the processor currently
265
 * holding the "primary" role just to give us the flexibility later to
266
 * change primaries should we be sufficiently twisted.
267
 */
268
269
#define        CPUF_BSP        0x0001                /* CPU is the original BSP */
270
#define        CPUF_AP                0x0002                /* CPU is an AP */
271
#define        CPUF_SP                0x0004                /* CPU is only processor */
272
#define        CPUF_PRIMARY        0x0008                /* CPU is active primary processor */
273
274
#define        CPUF_SYNCTSC        0x0800                /* Synchronize TSC */
275
#define        CPUF_PRESENT        0x1000                /* CPU is present */
276
#define        CPUF_RUNNING        0x2000                /* CPU is running */
277
#define        CPUF_PAUSE        0x4000                /* CPU is paused in DDB */
278
#define        CPUF_GO                0x8000                /* CPU should start running */
279
280
#endif /* _KERNEL || __KMEMUSER */
281
282
#ifdef _KERNEL
283
/*
284
 * We statically allocate the CPU info for the primary CPU (or,
285
 * the only CPU on uniprocessors), and the primary CPU is the
286
 * first CPU on the CPU info list.
287
 */
288
extern struct cpu_info cpu_info_primary;
289
extern struct cpu_info *cpu_info_list;
290
291
#define        CPU_INFO_ITERATOR                int __unused
292
#define        CPU_INFO_FOREACH(cii, ci)        ci = cpu_info_list; \
293
                                        ci != NULL; ci = ci->ci_next
294
295
#define CPU_STARTUP(_ci, _target)        ((_ci)->ci_func->start(_ci, _target))
296
#define CPU_STOP(_ci)                        ((_ci)->ci_func->stop(_ci))
297
#define CPU_START_CLEANUP(_ci)                ((_ci)->ci_func->cleanup(_ci))
298
299
#if !defined(__GNUC__) || defined(_MODULE)
300
/* For non-GCC and modules */
301
struct cpu_info        *x86_curcpu(void);
302
void        cpu_set_curpri(int);
303
# ifdef __GNUC__
304
lwp_t        *x86_curlwp(void) __attribute__ ((const));
305
# else
306
lwp_t   *x86_curlwp(void);
307
# endif
308
#endif
309
310
#define cpu_number()                 (cpu_index(curcpu()))
311
312
#define CPU_IS_PRIMARY(ci)        ((ci)->ci_flags & CPUF_PRIMARY)
313
314
#define        X86_AST_GENERIC                0x01
315
#define        X86_AST_PREEMPT                0x02
316
317
#define aston(l, why)                ((l)->l_md.md_astpending |= (why))
318
#define        cpu_did_resched(l)        ((l)->l_md.md_astpending &= ~X86_AST_PREEMPT)
319
320
void cpu_boot_secondary_processors(void);
321
void cpu_init_idle_lwps(void);
322
void cpu_init_msrs(struct cpu_info *, bool);
323
void cpu_load_pmap(struct pmap *, struct pmap *);
324
void cpu_broadcast_halt(void);
325
void cpu_kick(struct cpu_info *);
326
327
#define        curcpu()                x86_curcpu()
328
#define        curlwp                        x86_curlwp()
329
#define        curpcb                        ((struct pcb *)lwp_getpcb(curlwp))
330
331
/*
332
 * Arguments to hardclock, softclock and statclock
333
 * encapsulate the previous machine state in an opaque
334
 * clockframe; for now, use generic intrframe.
335
 */
336
struct clockframe {
337
        struct intrframe cf_if;
338
};
339
340
/*
341
 * Give a profiling tick to the current process when the user profiling
342
 * buffer pages are invalid.  On the i386, request an ast to send us
343
 * through trap(), marking the proc as needing a profiling tick.
344
 */
345
extern void        cpu_need_proftick(struct lwp *l);
346
347
/*
348
 * Notify the LWP l that it has a signal pending, process as soon as
349
 * possible.
350
 */
351
extern void        cpu_signotify(struct lwp *);
352
353
/*
354
 * We need a machine-independent name for this.
355
 */
356
extern void (*delay_func)(unsigned int);
357
struct timeval;
358
359
#define        DELAY(x)                (*delay_func)(x)
360
#define delay(x)                (*delay_func)(x)
361
362
extern int biosbasemem;
363
extern int biosextmem;
364
extern int cputype;
365
extern int cpuid_level;
366
extern int cpu_class;
367
extern char cpu_brand_string[];
368
extern int use_pae;
369
370
#ifdef __i386__
371
extern int i386_fpu_present;
372
int npx586bug1(int, int);
373
extern int i386_fpu_fdivbug;
374
extern int i386_use_fxsave;
375
extern int i386_has_sse;
376
extern int i386_has_sse2;
377
#else
378
#define        i386_fpu_present        1
379
#define        i386_fpu_fdivbug        0
380
#define        i386_use_fxsave                1
381
#define        i386_has_sse                1
382
#define        i386_has_sse2                1
383
#endif
384
385
extern int x86_fpu_save;
386
#define        FPU_SAVE_FSAVE                0
387
#define        FPU_SAVE_FXSAVE                1
388
#define        FPU_SAVE_XSAVE                2
389
#define        FPU_SAVE_XSAVEOPT        3
390
extern unsigned int x86_fpu_save_size;
391
extern uint64_t x86_xsave_features;
392
393
extern void (*x86_cpu_idle)(void);
394
#define        cpu_idle() (*x86_cpu_idle)()
395
396
/* machdep.c */
397
void        dumpconf(void);
398
void        cpu_reset(void);
399
void        i386_proc0_tss_ldt_init(void);
400
void        dumpconf(void);
401
void        cpu_reset(void);
402
void        x86_64_proc0_tss_ldt_init(void);
403
void        x86_64_init_pcb_tss_ldt(struct cpu_info *);
404
405
/* longrun.c */
406
u_int         tmx86_get_longrun_mode(void);
407
void         tmx86_get_longrun_status(u_int *, u_int *, u_int *);
408
void         tmx86_init_longrun(void);
409
410
/* identcpu.c */
411
void         cpu_probe(struct cpu_info *);
412
void        cpu_identify(struct cpu_info *);
413
414
/* cpu_topology.c */
415
void        x86_cpu_topology(struct cpu_info *);
416
417
/* vm_machdep.c */
418
void        cpu_proc_fork(struct proc *, struct proc *);
419
420
/* locore.s */
421
struct region_descriptor;
422
void        lgdt(struct region_descriptor *);
423
#ifdef XEN
424
void        lgdt_finish(void);
425
#endif
426
427
struct pcb;
428
void        savectx(struct pcb *);
429
void        lwp_trampoline(void);
430
#ifdef XEN
431
void        startrtclock(void);
432
void        xen_delay(unsigned int);
433
void        xen_initclocks(void);
434
void        xen_suspendclocks(struct cpu_info *);
435
void        xen_resumeclocks(struct cpu_info *);
436
#else
437
/* clock.c */
438
void        initrtclock(u_long);
439
void        startrtclock(void);
440
void        i8254_delay(unsigned int);
441
void        i8254_microtime(struct timeval *);
442
void        i8254_initclocks(void);
443
#endif
444
445
/* cpu.c */
446
447
void        cpu_probe_features(struct cpu_info *);
448
449
/* vm_machdep.c */
450
paddr_t        kvtop(void *);
451
452
#ifdef USER_LDT
453
/* sys_machdep.h */
454
int        x86_get_ldt(struct lwp *, void *, register_t *);
455
int        x86_set_ldt(struct lwp *, void *, register_t *);
456
#endif
457
458
/* isa_machdep.c */
459
void        isa_defaultirq(void);
460
int        isa_nmi(void);
461
462
#ifdef VM86
463
/* vm86.c */
464
void        vm86_gpfault(struct lwp *, int);
465
#endif /* VM86 */
466
467
/* consinit.c */
468
void kgdb_port_init(void);
469
470
/* bus_machdep.c */
471
void x86_bus_space_init(void);
472
void x86_bus_space_mallocok(void);
473
474
#endif /* _KERNEL */
475
476
#if defined(_KERNEL) || defined(_KMEMUSER)
477
#include <machine/psl.h>        /* Must be after struct cpu_info declaration */
478
#endif /* _KERNEL || __KMEMUSER */
479
480
/*
481
 * CTL_MACHDEP definitions.
482
 */
483
#define        CPU_CONSDEV                1        /* dev_t: console terminal device */
484
#define        CPU_BIOSBASEMEM                2        /* int: bios-reported base mem (K) */
485
#define        CPU_BIOSEXTMEM                3        /* int: bios-reported ext. mem (K) */
486
/*         CPU_NKPDE                4        obsolete: int: number of kernel PDEs */
487
#define        CPU_BOOTED_KERNEL        5        /* string: booted kernel name */
488
#define CPU_DISKINFO                6        /* struct disklist *:
489
                                         * disk geometry information */
490
#define CPU_FPU_PRESENT                7        /* int: FPU is present */
491
#define        CPU_OSFXSR                8        /* int: OS uses FXSAVE/FXRSTOR */
492
#define        CPU_SSE                        9        /* int: OS/CPU supports SSE */
493
#define        CPU_SSE2                10        /* int: OS/CPU supports SSE2 */
494
#define        CPU_TMLR_MODE                11        /* int: longrun mode
495
                                         * 0: minimum frequency
496
                                         * 1: economy
497
                                         * 2: performance
498
                                         * 3: maximum frequency
499
                                         */
500
#define        CPU_TMLR_FREQUENCY        12        /* int: current frequency */
501
#define        CPU_TMLR_VOLTAGE        13        /* int: curret voltage */
502
#define        CPU_TMLR_PERCENTAGE        14        /* int: current clock percentage */
503
#define        CPU_MAXID                15        /* number of valid machdep ids */
504
505
/*
506
 * Structure for CPU_DISKINFO sysctl call.
507
 * XXX this should be somewhere else.
508
 */
509
#define MAX_BIOSDISKS        16
510
511
struct disklist {
512
        int dl_nbiosdisks;                           /* number of bios disks */
513
        struct biosdisk_info {
514
                int bi_dev;                           /* BIOS device # (0x80 ..) */
515
                int bi_cyl;                           /* cylinders on disk */
516
                int bi_head;                           /* heads per track */
517
                int bi_sec;                           /* sectors per track */
518
                uint64_t bi_lbasecs;                   /* total sec. (iff ext13) */
519
#define BIFLAG_INVALID                0x01
520
#define BIFLAG_EXTINT13                0x02
521
                int bi_flags;
522
        } dl_biosdisks[MAX_BIOSDISKS];
523
524
        int dl_nnativedisks;                           /* number of native disks */
525
        struct nativedisk_info {
526
                char ni_devname[16];                   /* native device name */
527
                int ni_nmatches;                    /* # of matches w/ BIOS */
528
                int ni_biosmatches[MAX_BIOSDISKS]; /* indices in dl_biosdisks */
529
        } dl_nativedisks[1];                           /* actually longer */
530
};
531
#endif /* !_X86_CPU_H_ */