summaryrefslogtreecommitdiffstats
path: root/tboot/include/processor.h
diff options
context:
space:
mode:
Diffstat (limited to 'tboot/include/processor.h')
-rw-r--r--tboot/include/processor.h340
1 files changed, 340 insertions, 0 deletions
diff --git a/tboot/include/processor.h b/tboot/include/processor.h
new file mode 100644
index 0000000..83b9fe4
--- /dev/null
+++ b/tboot/include/processor.h
@@ -0,0 +1,340 @@
+/* Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+/*
+ * Portions copyright (c) 2010, Intel Corporation
+ */
+
+#ifndef __PROCESSOR_H__
+#define __PROCESSOR_H__
+
+/* from: @(#)specialreg.h 7.1 (Berkeley) 5/9/91
+ * $FreeBSD: stable/8/sys/i386/include/specialreg.h 198989 2009-11-06 15:24:48Z attilio $
+ */
+
+/*
+ * 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 */
+
+/*
+ * Bits in 386 special registers:
+ */
+#define CR0_PE 0x00000001 /* Protected mode Enable */
+#define CR0_MP 0x00000002 /* "Math" (fpu) Present */
+#define CR0_EM 0x00000004 /* EMulate FPU instructions. (trap ESC only) */
+#define CR0_TS 0x00000008 /* Task Switched (if MP, trap ESC and WAIT) */
+#define CR0_ET 0x00000010 /* Extension type */
+#define CR0_PG 0x80000000 /* PaGing enable */
+
+/*
+ * Bits in 486 special registers:
+ */
+#define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */
+#define CR0_WP 0x00010000 /* Write Protect (honor page protect in all modes) */
+#define CR0_AM 0x00040000 /* Alignment Mask (set to enable AC flag) */
+#define CR0_NW 0x20000000 /* Not Write-through */
+#define CR0_CD 0x40000000 /* Cache Disable */
+
+/*
+ * Bits in PPro special registers
+ */
+#define CR4_VME 0x00000001 /* Virtual 8086 mode extensions */
+#define CR4_PVI 0x00000002 /* Protected-mode virtual interrupts */
+#define CR4_TSD 0x00000004 /* Time stamp disable */
+#define CR4_DE 0x00000008 /* Debugging extensions */
+#define CR4_PSE 0x00000010 /* Page size extensions */
+#define CR4_PAE 0x00000020 /* Physical address extension */
+#define CR4_MCE 0x00000040 /* Machine check enable */
+#define CR4_PGE 0x00000080 /* Page global enable */
+#define CR4_PCE 0x00000100 /* Performance monitoring counter enable */
+#define CR4_FXSR 0x00000200/* Fast FPU save/restore used by OS */
+#define CR4_XMM 0x00000400 /* enable SIMD/MMX2 to use except 16 */
+#define CR4_VMXE 0x00002000/* enable VMX */
+#define CR4_SMXE 0x00004000/* enable SMX */
+#define CR4_PCIDE 0x00020000/* enable PCID */
+
+#ifndef __ASSEMBLY__
+
+/* from:
+ * $FreeBSD: src/sys/i386/include/cpufunc.h,v 1.158 2010/01/01 20:55:11 obrien Exp $
+ */
+
+static inline void do_cpuid(unsigned int ax, uint32_t *p)
+{
+ __asm__ __volatile__ ("cpuid"
+ : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
+ : "0" (ax));
+}
+
+static inline void do_cpuid1(unsigned int ax, unsigned int cx, uint32_t *p)
+{
+ __asm__ __volatile__ ("cpuid"
+ : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
+ : "0" (ax), "c" (cx));
+}
+
+static always_inline uint32_t cpuid_eax(unsigned int op)
+{
+ /* eax: regs[0], ebx: regs[1], ecx: regs[2], edx: regs[3] */
+ uint32_t regs[4];
+
+ do_cpuid(op, regs);
+
+ return regs[0];
+}
+
+static always_inline uint32_t cpuid_ebx(unsigned int op)
+{
+ /* eax: regs[0], ebx: regs[1], ecx: regs[2], edx: regs[3] */
+ uint32_t regs[4];
+
+ do_cpuid(op, regs);
+
+ return regs[1];
+}
+
+static always_inline uint32_t cpuid_ebx1(unsigned int op1, unsigned int op2)
+{
+ /* eax: regs[0], ebx: regs[1], ecx: regs[2], edx: regs[3] */
+ uint32_t regs[4];
+
+ do_cpuid1(op1, op2, regs);
+
+ return regs[1];
+}
+static always_inline uint32_t cpuid_ecx(unsigned int op)
+{
+ /* eax: regs[0], ebx: regs[1], ecx: regs[2], edx: regs[3] */
+ uint32_t regs[4];
+
+ do_cpuid(op, regs);
+
+ return regs[2];
+}
+
+#define CPUID_X86_FEATURE_XMM3 (1<<0)
+#define CPUID_X86_FEATURE_VMX (1<<5)
+#define CPUID_X86_FEATURE_SMX (1<<6)
+
+/* Note, removed read/write ecx, not used */
+
+static inline unsigned long long read_cr0(void)
+{
+ unsigned long long data;
+ /* 64: movl -> movq */
+ __asm__ __volatile__ ("movq %%cr0,%0" : "=r" (data));
+ return (data);
+}
+
+static inline void write_cr0(unsigned long long data)
+{
+ /* 64: movl -> movq */
+ __asm__ __volatile__("movq %0,%%cr0" : : "r" (data));
+}
+
+static inline unsigned long long read_cr4(void)
+{
+ unsigned long long data;
+ /* 64: movl -> movq */
+ __asm__ __volatile__ ("movq %%cr4,%0" : "=r" (data));
+ return (data);
+}
+
+static inline void write_cr4(unsigned long long data)
+{
+ /* 64: movl -> movq */
+ __asm__ __volatile__ ("movq %0,%%cr4" : : "r" (data));
+}
+
+static inline unsigned long long read_cr3(void)
+{
+ unsigned long long data;
+ /* 64: movl -> movq */
+ __asm__ __volatile__ ("movq %%cr3,%0" : "=r" (data));
+ return (data);
+}
+
+static inline void write_cr3(unsigned long long data)
+{
+ /* 64: movl -> movq */
+ __asm__ __volatile__("movq %0,%%cr3" : : "r" (data) : "memory");
+}
+
+static inline uint64_t read_rflags(void)
+{
+ uint64_t rf;
+ /* 32: EFLAGS stuff __asm__ __volatile__ ("pushfl; popl %0" : "=r" (ef));*/
+ __asm__ __volatile__ ("pushfq; popq %0" : "=r" (rf));
+ return (rf);
+}
+
+static inline void write_rflags(uint64_t rf)
+{
+ /* 32: EFLAGS stuff __asm__ __volatile__ ("pushl %0; popfl" : : "r" (ef));*/
+ __asm__ __volatile__ ("pushq %0; popfq" : : "r" (rf));
+}
+
+static inline void disable_intr(void)
+{
+ __asm__ __volatile__ ("cli" : : : "memory");
+}
+
+static inline void enable_intr(void)
+{
+ __asm__ __volatile__ ("sti");
+}
+
+/* was ia32_pause() */
+static inline void cpu_relax(void)
+{
+ __asm__ __volatile__ ("pause");
+}
+
+static inline void halt(void)
+{
+ __asm__ __volatile__ ("hlt");
+}
+
+static inline unsigned int get_apicid(void)
+{
+ return cpuid_ebx(1) >> 24;
+}
+
+static inline void wbinvd(void)
+{
+ __asm__ __volatile__ ("wbinvd");
+}
+
+static inline uint32_t bsrl(uint32_t mask)
+{
+ uint32_t result;
+
+ /* 64: Ok to shift 32b mask */
+ __asm__ __volatile__ ("bsrl %1,%0" : "=r" (result) : "rm" (mask) : "cc");
+ return (result);
+}
+
+static inline int fls(int mask)
+{
+ return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1);
+}
+
+static always_inline void mb(void)
+{
+ /* 32: __asm__ __volatile__ ("lock;addl $0,0(%%esp)" : : : "memory"); */
+ __asm__ __volatile__ ("lock;addq $0,0(%%rsp)" : : : "memory");
+}
+
+static inline void cpu_monitor(const void *addr, int extensions, int hints)
+{
+ /* 64: a=rax, c=rcx, d=rdx ints are 32b into ecx, edx */
+ __asm __volatile__ ("monitor;" : :"a" (addr), "c" (extensions), "d"(hints));
+}
+
+static inline void cpu_mwait(int extensions, int hints)
+{
+ /* 64: a=rax, c=rcx ints are 32b into eax, ecx */
+ __asm __volatile__ ("mwait;" : :"a" (hints), "c" (extensions));
+}
+
+static inline void flush_tlb(void)
+{
+ __asm__ __volatile__ (
+ "movq %%cr3, %%rax\n"
+ "movq %%rax, %%cr3\n"
+ : : : "rax");
+}
+
+typedef struct __packed lmode_desc {
+ uint16_t limit;
+ uint64_t base;
+} lmode_desc_t;
+
+static inline void store_gdt(lmode_desc_t *gdt)
+{
+ __asm__ __volatile__("sgdt %0\n\t"
+ : "=m" (*gdt) : : "memory");
+}
+
+static inline void store_idt(lmode_desc_t *idt)
+{
+ __asm__ __volatile__("sidt %0\n\t"
+ : "=m" (*idt): : "memory");
+}
+
+#define lea_reference(i, o) __asm__ __volatile__ \
+ ("lea "#i"(%%rip), %%rax\n\t" : "=a" (o))
+
+#define mov_sel(r, o) __asm__ __volatile__ \
+ ("movw %%"#r"s, %0\n\t" : "=m" (o) : : "memory");
+
+/* In inline asm, these 3 use the A constraint to specify the EDX:EAX register
+ * pair. The inline assembler was getting the code badly wrong so the
+ * implementation of these moved to the assembly module (and renamed).
+ */
+uint64_t read_msr(uint32_t msr);
+void write_msr(uint32_t msr, uint64_t newval);
+uint64_t read_tsc(void);
+
+uint64_t get_rip(void);
+uint64_t bsp_stack_ref(void);
+
+#define rdmsr read_msr
+#define wrmsr write_msr
+#define rdtsc read_tsc
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __PROCESSOR_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */