1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
|
/* ----------------------------------------------------------------------- *
*
* Copyright 2006 Erwan Velu - All Rights Reserved
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall
* be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* ----------------------------------------------------------------------- */
#ifndef _CPUID_H
#define _CPUID_H
#include <stdbool.h>
#include <stdint.h>
#include <cpufeature.h>
#include <sys/cpu.h>
#include <klibc/compiler.h>
#define PAGE_SIZE 4096
#define CPU_MODEL_SIZE 48
#define CPU_VENDOR_SIZE 48
typedef struct {
bool fpu; /* Onboard FPU */
bool vme; /* Virtual Mode Extensions */
bool de; /* Debugging Extensions */
bool pse; /* Page Size Extensions */
bool tsc; /* Time Stamp Counter */
bool msr; /* Model-Specific Registers, RDMSR, WRMSR */
bool pae; /* Physical Address Extensions */
bool mce; /* Machine Check Architecture */
bool cx8; /* CMPXCHG8 instruction */
bool apic;/* Onboard APIC */
bool sep; /* SYSENTER/SYSEXIT */
bool mtrr;/* Memory Type Range Registers */
bool pge; /* Page Global Enable */
bool mca; /* Machine Check Architecture */
bool cmov;/* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
bool pat; /* Page Attribute Table */
bool pse_36; /* 36-bit PSEs */
bool psn; /* Processor serial number */
bool clflsh; /* Supports the CLFLUSH instruction */
bool dts; /* Debug Trace Store */
bool acpi;/* ACPI via MSR */
bool mmx; /* Multimedia Extensions */
bool fxsr;/* FXSAVE and FXRSTOR instructions (fast save and restore */
/* of FPU context), and CR4.OSFXSR available */
bool sse; /* Streaming SIMD Extensions */
bool sse2;/* Streaming SIMD Extensions 2*/
bool ss; /* CPU self snoop */
bool htt; /* Hyper-Threading */
bool acc; /* Automatic clock control */
bool syscall; /* SYSCALL/SYSRET */
bool mp; /* MP Capable. */
bool nx; /* Execute Disable */
bool mmxext; /* AMD MMX extensions */
bool lm; /* Long Mode (x86-64) */
bool nowext;/* AMD 3DNow! extensions */
bool now; /* 3DNow! */
bool smp; /* A smp configuration has been found*/
} s_cpu_flags;
typedef struct {
char vendor[CPU_VENDOR_SIZE];
uint8_t vendor_id;
uint8_t family;
char model[CPU_MODEL_SIZE];
uint8_t model_id;
uint8_t stepping;
s_cpu_flags flags;
} s_cpu;
/**********************************************************************************/
/**********************************************************************************/
/* From this point this is some internal stuff mainly taken from the linux kernel */
/**********************************************************************************/
/**********************************************************************************/
/*
* EFLAGS bits
*/
#define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
#define X86_EFLAGS_PF 0x00000004 /* Parity Flag */
#define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */
#define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */
#define X86_EFLAGS_SF 0x00000080 /* Sign Flag */
#define X86_EFLAGS_TF 0x00000100 /* Trap Flag */
#define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */
#define X86_EFLAGS_DF 0x00000400 /* Direction Flag */
#define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */
#define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */
#define X86_EFLAGS_NT 0x00004000 /* Nested Task */
#define X86_EFLAGS_RF 0x00010000 /* Resume Flag */
#define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
#define X86_EFLAGS_AC 0x00040000 /* Alignment Check */
#define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */
#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */
#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
#define X86_VENDOR_INTEL 0
#define X86_VENDOR_CYRIX 1
#define X86_VENDOR_AMD 2
#define X86_VENDOR_UMC 3
#define X86_VENDOR_NEXGEN 4
#define X86_VENDOR_CENTAUR 5
#define X86_VENDOR_RISE 6
#define X86_VENDOR_TRANSMETA 7
#define X86_VENDOR_NSC 8
#define X86_VENDOR_NUM 9
#define X86_VENDOR_UNKNOWN 0xff
static inline __purefunc bool test_bit(int nr, const uint32_t *addr)
{
return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;
}
#define cpu_has(c, bit) test_bit(bit, (c)->x86_capability)
/*
* CPU type and hardware bug flags. Kept separately for each CPU.
* Members of this structure are referenced in head.S, so think twice
* before touching them. [mj]
*/
struct cpuinfo_x86 {
uint8_t x86; /* CPU family */
uint8_t x86_vendor; /* CPU vendor */
uint8_t x86_model;
uint8_t x86_mask;
char wp_works_ok; /* It doesn't on 386's */
char hlt_works_ok; /* Problems on some 486Dx4's and old 386's */
char hard_math;
char rfu;
int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */
uint32_t x86_capability[NCAPINTS];
char x86_vendor_id[16];
char x86_model_id[64];
int x86_cache_size; /* in KB, if available */
int x86_cache_alignment; /* in bytes */
char fdiv_bug;
char f00f_bug;
char coma_bug;
char pad0;
int x86_power;
unsigned long loops_per_jiffy;
#ifdef CONFIG_SMP
cpumask_t llc_shared_map; /* cpus sharing the last level cache */
#endif
unsigned char x86_max_cores; /* cpuid returned max cores value */
unsigned char booted_cores; /* number of cores as seen by OS */
unsigned char apicid;
} __attribute__((__packed__));
#endif
struct cpu_model_info {
int vendor;
int family;
char *model_names[16];
};
/* attempt to consolidate cpu attributes */
struct cpu_dev {
char * c_vendor;
/* some have two possibilities for cpuid string */
char * c_ident[2];
struct cpu_model_info c_models[4];
void (*c_init)(struct cpuinfo_x86 * c);
void (*c_identify)(struct cpuinfo_x86 * c);
unsigned int (*c_size_cache)(struct cpuinfo_x86 * c, unsigned int size);
};
/*
* Structure definitions for SMP machines following the
* Intel Multiprocessing Specification 1.1 and 1.4.
*/
/*
* This tag identifies where the SMP configuration
* information is.
*/
#define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_')
struct intel_mp_floating
{
char mpf_signature[4]; /* "_MP_" */
uint32_t mpf_physptr; /* Configuration table address */
uint8_t mpf_length; /* Our length (paragraphs) */
uint8_t mpf_specification; /* Specification version */
uint8_t mpf_checksum; /* Checksum (makes sum 0) */
uint8_t mpf_feature1; /* Standard or configuration ? */
uint8_t mpf_feature2; /* Bit7 set for IMCR|PIC */
uint8_t mpf_feature3; /* Unused (0) */
uint8_t mpf_feature4; /* Unused (0) */
uint8_t mpf_feature5; /* Unused (0) */
};
extern void get_cpu_vendor(struct cpuinfo_x86 *c);
extern void detect_cpu(s_cpu *cpu);
|