summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/i386/include/arch/cpu.h146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/arch/i386/include/arch/cpu.h b/src/arch/i386/include/arch/cpu.h
new file mode 100644
index 0000000000..0c5b0604ad
--- /dev/null
+++ b/src/arch/i386/include/arch/cpu.h
@@ -0,0 +1,146 @@
+#ifndef ARCH_CPU_H
+#define ARCH_CPU_H
+
+/*
+ * 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 */
+
+struct cpuid_result {
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+};
+/*
+ * Generic CPUID function
+ */
+static inline struct cpuid_result cpuid(int op)
+{
+ struct cpuid_result result;
+ asm volatile(
+ "cpuid"
+ : "=a" (result.eax),
+ "=b" (result.ebx),
+ "=c" (result.ecx),
+ "=d" (result.edx)
+ : "0" (op));
+ return result;
+}
+
+
+/*
+ * CPUID functions returning a single datum
+ */
+static inline unsigned int cpuid_eax(unsigned int op)
+{
+ unsigned int eax;
+
+ __asm__("cpuid"
+ : "=a" (eax)
+ : "0" (op)
+ : "ebx", "ecx", "edx");
+ return eax;
+}
+static inline unsigned int cpuid_ebx(unsigned int op)
+{
+ unsigned int eax, ebx;
+
+ __asm__("cpuid"
+ : "=a" (eax), "=b" (ebx)
+ : "0" (op)
+ : "ecx", "edx" );
+ return ebx;
+}
+static inline unsigned int cpuid_ecx(unsigned int op)
+{
+ unsigned int eax, ecx;
+
+ __asm__("cpuid"
+ : "=a" (eax), "=c" (ecx)
+ : "0" (op)
+ : "ebx", "edx" );
+ return ecx;
+}
+static inline unsigned int cpuid_edx(unsigned int op)
+{
+ unsigned int eax, edx;
+
+ __asm__("cpuid"
+ : "=a" (eax), "=d" (edx)
+ : "0" (op)
+ : "ebx", "ecx");
+ return edx;
+}
+
+
+
+#define X86_VENDOR_INVALID 0
+#define X86_VENDOR_INTEL 1
+#define X86_VENDOR_CYRIX 2
+#define X86_VENDOR_AMD 3
+#define X86_VENDOR_UMC 4
+#define X86_VENDOR_NEXGEN 5
+#define X86_VENDOR_CENTAUR 6
+#define X86_VENDOR_RISE 7
+#define X86_VENDOR_TRANSMETA 8
+#define X86_VENDOR_NSC 9
+#define X86_VENDOR_SIS 10
+#define X86_VENDOR_UNKNOWN 0xff
+
+#ifndef __ROMCC__
+#include <device/device.h>
+
+
+struct cpu_device_id {
+ unsigned vendor;
+ unsigned device;
+};
+struct cpu_driver {
+ struct device_operations *ops;
+ struct cpu_device_id *id_table;
+};
+
+struct cpu_info {
+ device_t cpu;
+ unsigned long index;
+};
+
+static inline struct cpu_info *cpu_info(void)
+{
+ struct cpu_info *ci;
+ __asm__("andl %%esp,%0; "
+ "orl %2, %0 "
+ :"=r" (ci)
+ : "0" (~(STACK_SIZE - 1)),
+ "r" (STACK_SIZE - sizeof(struct cpu_info))
+ );
+ return ci;
+}
+
+static inline unsigned long cpu_index(void)
+{
+ struct cpu_info *ci;
+ ci = cpu_info();
+ return ci->index;
+}
+
+#endif
+
+#endif /* ARCH_CPU_H */