#ifndef _MACHINE_CPU_H_
#define _MACHINE_CPU_H_
#ifdef _KERNEL
#include <machine/frame.h>
#include <machine/psl.h>
#include <machine/segments.h>
#include <machine/intrdefs.h>
#include <machine/tss.h>
#ifdef MULTIPROCESSOR
#include <machine/i82489reg.h>
#include <machine/i82489var.h>
#endif
#endif
#define clockframe intrframe
#include <sys/clockintr.h>
#include <sys/device.h>
#include <sys/sched.h>
#include <sys/sensors.h>
#include <sys/srp.h>
#include <uvm/uvm_percpu.h>
struct intrsource;
#ifdef _KERNEL
struct cpu_info {
u_int32_t ci_kern_cr3;
u_int32_t ci_scratch;
#define ci_PAGEALIGN ci_dev
struct device *ci_dev;
struct cpu_info *ci_self;
struct schedstate_percpu ci_schedstate;
struct cpu_info *ci_next;
struct proc *ci_curproc;
cpuid_t ci_cpuid;
u_int ci_apicid;
u_int ci_acpi_proc_id;
u_int32_t ci_randseed;
u_int32_t ci_kern_esp;
u_int32_t ci_intr_esp;
u_int32_t ci_user_cr3;
#if defined(MULTIPROCESSOR)
struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM];
#define __HAVE_UVM_PERCPU
struct uvm_pmr_cache ci_uvm;
#endif
struct proc *ci_fpcurproc;
struct proc *ci_fpsaveproc;
int ci_fpsaving;
struct pcb *ci_curpcb;
struct pcb *ci_idle_pcb;
struct pmap *ci_curpmap;
struct intrsource *ci_isources[MAX_INTR_SOURCES];
u_int32_t ci_ipending;
int ci_ilevel;
int ci_idepth;
u_int32_t ci_imask[NIPL];
u_int32_t ci_iunmask[NIPL];
#ifdef DIAGNOSTIC
int ci_mutex_level;
#endif
paddr_t ci_idle_pcb_paddr;
volatile u_long ci_flags;
u_int32_t ci_ipis;
u_int32_t ci_level;
u_int32_t ci_vendor[4];
u_int32_t ci_signature;
u_int32_t ci_family;
u_int32_t ci_model;
u_int32_t ci_feature_flags;
u_int32_t ci_feature_sefflags_ebx;
u_int32_t ci_feature_sefflags_ecx;
u_int32_t ci_feature_sefflags_edx;
u_int32_t ci_feature_tpmflags;
u_int32_t cpu_class;
u_int32_t ci_cflushsz;
int ci_inatomic;
struct cpu_functions *ci_func;
void (*cpu_setup)(struct cpu_info *);
struct device *ci_acpicpudev;
volatile u_int ci_mwait;
#define MWAIT_IN_IDLE 0x1
#define MWAIT_KEEP_IDLING 0x2
#define MWAIT_ONLY 0x4
#define MWAIT_IDLING (MWAIT_IN_IDLE | MWAIT_KEEP_IDLING)
int ci_want_resched;
union descriptor *ci_gdt;
struct i386tss *ci_tss;
struct i386tss *ci_nmi_tss;
volatile int ci_ddb_paused;
#define CI_DDB_RUNNING 0
#define CI_DDB_SHOULDSTOP 1
#define CI_DDB_STOPPED 2
#define CI_DDB_ENTERDDB 3
#define CI_DDB_INDDB 4
struct ksensordev ci_sensordev;
struct ksensor ci_sensor;
#if defined(GPROF) || defined(DDBPROF)
struct gmonparam *ci_gmon;
struct clockintr ci_gmonclock;
#endif
struct clockqueue ci_queue;
char ci_panicbuf[512];
};
#define CPUF_BSP 0x0001
#define CPUF_AP 0x0002
#define CPUF_SP 0x0004
#define CPUF_PRIMARY 0x0008
#define CPUF_APIC_CD 0x0010
#define CPUF_CONST_TSC 0x0020
#define CPUF_PRESENT 0x1000
#define CPUF_RUNNING 0x2000
#define CPUF_VMM 0x4000
struct cpu_info_full;
extern struct cpu_info_full cpu_info_full_primary;
#define cpu_info_primary (*(struct cpu_info *)((char *)&cpu_info_full_primary + PAGE_SIZE*2 - offsetof(struct cpu_info, ci_PAGEALIGN)))
extern struct cpu_info *cpu_info_list;
#define CPU_INFO_ITERATOR int
#define CPU_INFO_FOREACH(cii, ci) for (cii = 0, ci = cpu_info_list; \
ci != NULL; ci = ci->ci_next)
#define CPU_INFO_UNIT(ci) ((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0)
#ifdef MULTIPROCESSOR
#define MAXCPUS 32
#define CPU_STARTUP(_ci) ((_ci)->ci_func->start(_ci))
#define CPU_STOP(_ci) ((_ci)->ci_func->stop(_ci))
#define CPU_START_CLEANUP(_ci) ((_ci)->ci_func->cleanup(_ci))
static struct cpu_info *curcpu(void);
static __inline struct cpu_info *
curcpu(void)
{
struct cpu_info *ci;
__asm volatile("movl %%fs:%1, %0" :
"=r" (ci) : "m"
(*(struct cpu_info * const *)&((struct cpu_info *)0)->ci_self));
return ci;
}
#define cpu_number() (curcpu()->ci_cpuid)
#define CPU_IS_PRIMARY(ci) ((ci)->ci_flags & CPUF_PRIMARY)
#define CPU_IS_RUNNING(ci) ((ci)->ci_flags & CPUF_RUNNING)
extern struct cpu_info *cpu_info[MAXCPUS];
extern void cpu_boot_secondary_processors(void);
extern void cpu_init_idle_pcbs(void);
void cpu_kick(struct cpu_info *);
void cpu_unidle(struct cpu_info *);
#define CPU_BUSY_CYCLE() __asm volatile("pause": : : "memory")
#else
#define MAXCPUS 1
#define cpu_number() 0
#define curcpu() (&cpu_info_primary)
#define CPU_IS_PRIMARY(ci) 1
#define CPU_IS_RUNNING(ci) 1
#define cpu_kick(ci)
#define cpu_unidle(ci)
#define CPU_BUSY_CYCLE() __asm volatile ("" ::: "memory")
#endif
#include <machine/cpufunc.h>
#define aston(p) ((p)->p_md.md_astpending = 1)
#define curpcb curcpu()->ci_curpcb
unsigned int cpu_rnd_messybits(void);
extern void need_resched(struct cpu_info *);
#define clear_resched(ci) (ci)->ci_want_resched = 0
#define CLKF_USERMODE(frame) USERMODE((frame)->if_cs, (frame)->if_eflags)
#define CLKF_PC(frame) ((frame)->if_eip)
#define CLKF_INTR(frame) (IDXSEL((frame)->if_cs) == GICODE_SEL)
#define PROC_PC(p) ((p)->p_md.md_regs->tf_eip)
#define PROC_STACK(p) ((p)->p_md.md_regs->tf_esp)
#define need_proftick(p) aston(p)
void signotify(struct proc *);
extern void (*delay_func)(int);
void delay_fini(void(*)(int));
void delay_init(void(*)(int), int);
struct timeval;
#define DELAY(x) (*delay_func)(x)
#define delay(x) (*delay_func)(x)
void calibrate_cyclecounter(void);
#include <machine/cputypes.h>
struct cpu_cpuid_nameclass {
const char *cpu_id;
int cpu_vendor;
const char *cpu_vendorname;
struct cpu_cpuid_family {
int cpu_class;
const char *cpu_models[CPU_MAXMODEL+2];
void (*cpu_setup)(struct cpu_info *);
} cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1];
};
struct cpu_cpuid_feature {
int feature_bit;
const char *feature_name;
};
extern int cpu_id;
extern char cpu_vendor[];
extern char cpu_brandstr[];
extern int cpuid_level;
extern int cpu_miscinfo;
extern int cpu_feature;
extern int ecpu_feature;
extern int cpu_ecxfeature;
extern int ecpu_ecxfeature;
extern int cpu_cache_eax;
extern int cpu_cache_ebx;
extern int cpu_cache_ecx;
extern int cpu_cache_edx;
extern int cpu_perf_eax;
extern int cpu_perf_ebx;
extern int cpu_perf_edx;
extern int cpu_apmi_edx;
extern int cpu_pae;
extern u_int cpu_mwait_size;
extern u_int cpu_mwait_states;
extern void cpu_update_nmi_cr3(vaddr_t);
extern void cpu_tsx_disable(struct cpu_info *);
extern int cpu_apmhalt;
extern int cpu_class;
extern char cpu_model[];
extern const struct cpu_cpuid_nameclass i386_cpuid_cpus[];
extern void (*cpu_idle_enter_fcn)(void);
extern void (*cpu_idle_cycle_fcn)(void);
extern void (*cpu_idle_leave_fcn)(void);
extern void (*cpu_suspend_cycle_fcn)(void);
extern int cpuspeed;
#if !defined(SMALL_KERNEL)
#define BUS66 6667
#define BUS100 10000
#define BUS133 13333
#define BUS166 16667
#define BUS200 20000
#define BUS266 26667
#define BUS333 33333
extern int bus_clock;
#endif
extern int cpu_f00f_bug;
void fix_f00f(void);
void dkcsumattach(void);
extern int i386_use_fxsave;
extern int i386_has_sse;
extern int i386_has_sse2;
extern void (*update_cpuspeed)(void);
extern void (*initclock_func)(void);
extern void (*startclock_func)(void);
void dumpconf(void);
void cpu_reset(void);
void i386_proc0_tss_init(void);
void i386_init_pcb_tss(struct cpu_info *);
void cpuid(u_int32_t, u_int32_t *);
struct region_descriptor;
void lgdt(struct region_descriptor *);
struct pcb;
void savectx(struct pcb *);
void proc_trampoline(void);
void startclocks(void);
void rtcinit(void);
void rtcstart(void);
void rtcstop(void);
void i8254_delay(int);
void i8254_initclocks(void);
void i8254_startclock(void);
void i8254_start_both_clocks(void);
void i8254_inittimecounter(void);
void i8254_inittimecounter_simple(void);
#if !defined(SMALL_KERNEL)
void est_init(struct cpu_info *, int);
void est_setperf(int);
void longrun_init(void);
void longrun_setperf(int);
void p4tcc_init(int, int);
void p4tcc_setperf(int);
void k6_powernow_init(void);
void k6_powernow_setperf(int);
void k7_powernow_init(void);
void k7_powernow_setperf(int);
void k8_powernow_init(void);
void k8_powernow_setperf(int);
void k1x_init(struct cpu_info *);
void k1x_setperf(int);
#endif
void npxsave_proc(struct proc *, int);
void npxsave_cpu(struct cpu_info *, int);
void isa_defaultirq(void);
int isa_nmi(void);
void pmap_bootstrap(vaddr_t);
int kvtop(caddr_t);
#ifdef MULTIPROCESSOR
void mp_setperf_init(void);
#endif
int cpu_paenable(void *);
#endif
#define CPU_CONSDEV 1
#define CPU_BIOS 2
#define CPU_BLK2CHR 3
#define CPU_CHR2BLK 4
#define CPU_ALLOWAPERTURE 5
#define CPU_CPUVENDOR 6
#define CPU_CPUID 7
#define CPU_CPUFEATURE 8
#define CPU_KBDRESET 10
#define CPU_OSFXSR 13
#define CPU_SSE 14
#define CPU_SSE2 15
#define CPU_XCRYPT 16
#define CPU_LIDACTION 18
#define CPU_FORCEUKBD 19
#define CPU_MAXID 20
#define CTL_MACHDEP_NAMES { \
{ 0, 0 }, \
{ "console_device", CTLTYPE_STRUCT }, \
{ "bios", CTLTYPE_INT }, \
{ "blk2chr", CTLTYPE_STRUCT }, \
{ "chr2blk", CTLTYPE_STRUCT }, \
{ "allowaperture", CTLTYPE_INT }, \
{ "cpuvendor", CTLTYPE_STRING }, \
{ "cpuid", CTLTYPE_INT }, \
{ "cpufeature", CTLTYPE_INT }, \
{ 0, 0 }, \
{ "kbdreset", CTLTYPE_INT }, \
{ 0, 0 }, \
{ 0, 0 }, \
{ "osfxsr", CTLTYPE_INT }, \
{ "sse", CTLTYPE_INT }, \
{ "sse2", CTLTYPE_INT }, \
{ "xcrypt", CTLTYPE_INT }, \
{ 0, 0 }, \
{ "lidaction", CTLTYPE_INT }, \
{ "forceukbd", CTLTYPE_INT }, \
}
#if defined(MULTIPROCESSOR) && defined(_KERNEL)
#include <sys/mplock.h>
#endif
#endif