>> 32); + wrmsr(msr, lo, hi); +} + +/* rdmsr with exception handling */ +#define rdmsr_safe(msr,val1,val2) ({\ + int _rc; \ + __asm__ __volatile__( \ + "1: rdmsr\n2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl %5,%2\n; jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " "__FIXUP_ALIGN"\n" \ + " "__FIXUP_WORD" 1b,3b\n" \ + ".previous\n" \ + : "=a" (val1), "=d" (val2), "=&r" (_rc) \ + : "c" (msr), "2" (0), "i" (-EFAULT)); \ + _rc; }) + +/* wrmsr with exception handling */ +#define wrmsr_safe(msr,val1,val2) ({\ + int _rc; \ + __asm__ __volatile__( \ + "1: wrmsr\n2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl %5,%0\n; jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " "__FIXUP_ALIGN"\n" \ + " "__FIXUP_WORD" 1b,3b\n" \ + ".previous\n" \ + : "=&r" (_rc) \ + : "c" (msr), "a" (val1), "d" (val2), "0" (0), "i" (-EFAULT)); \ + _rc; }) + +#define rdtsc(low,high) \ + __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) + +#define rdtscl(low) \ + __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx") + +#define rdtscll(val) \ + __asm__ __volatile__("rdtsc" : "=A" (val)) + +#define write_tsc(val1,val2) wrmsr(0x10, val1, val2) + +#define rdpmc(counter,low,high) \ + __asm__ __volatile__("rdpmc" \ + : "=a" (low), "=d" (high) \ + : "c" (counter)) + +#endif /* !__ASSEMBLY__ */ + +/* symbolic names for some interesting MSRs */ +/* Intel defined MSRs. */ +#define MSR_IA32_P5_MC_ADDR 0 +#define MSR_IA32_P5_MC_TYPE 1 +#define MSR_IA32_TIME_STAMP_COUNTER 0x10 +#define MSR_IA32_PLATFORM_ID 0x17 +#define MSR_IA32_EBL_CR_POWERON 0x2a + +#define MSR_IA32_APICBASE 0x1b +#define MSR_IA32_APICBASE_BSP (1<<8) +#define MSR_IA32_APICBASE_ENABLE (1<<11) +#define MSR_IA32_APICBASE_BASE (0xfffff<<12) + +#define MSR_IA32_UCODE_WRITE 0x79 +#define MSR_IA32_UCODE_REV 0x8b + +#define MSR_P6_PERFCTR0 0xc1 +#define MSR_P6_PERFCTR1 0xc2 + +/* MSRs & bits used for VMX enabling */ +#define MSR_IA32_VMX_BASIC_MSR 0x480 +#define MSR_IA32_VMX_PINBASED_CTLS_MSR 0x481 +#define MSR_IA32_VMX_PROCBASED_CTLS_MSR 0x482 +#define MSR_IA32_VMX_EXIT_CTLS_MSR 0x483 +#define MSR_IA32_VMX_ENTRY_CTLS_MSR 0x484 +#define MSR_IA32_VMX_MISC_MSR 0x485 +#define MSR_IA32_VMX_CR0_FIXED0 0x486 +#define MSR_IA32_VMX_CR0_FIXED1 0x487 +#define MSR_IA32_VMX_CR4_FIXED0 0x488 +#define MSR_IA32_VMX_CR4_FIXED1 0x489 +#define IA32_FEATURE_CONTROL_MSR 0x3a +#define IA32_FEATURE_CONTROL_MSR_LOCK 0x1 +#define IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_IN_SMX 0x2 +#define IA32_FEATURE_CONTROL_MSR_ENABLE_VMX_OUT_SMX 0x4 +#define IA32_FEATURE_CONTROL_MSR_SENTER_PARAM_CTL 0x7f00 +#define IA32_FEATURE_CONTROL_MSR_ENABLE_SENTER 0x8000 + +/* AMD/K8 specific MSRs */ +#define MSR_EFER 0xc0000080 /* extended feature register */ +#define MSR_STAR 0xc0000081 /* legacy mode SYSCALL target */ +#define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */ +#define MSR_CSTAR 0xc0000083 /* compatibility mode SYSCALL target */ +#define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */ +#define MSR_FS_BASE 0xc0000100 /* 64bit GS base */ +#define MSR_GS_BASE 0xc0000101 /* 64bit FS base */ +#define MSR_SHADOW_GS_BASE 0xc0000102 /* SwapGS GS shadow */ +/* EFER bits: */ +#define _EFER_SCE 0 /* SYSCALL/SYSRET */ +#define _EFER_LME 8 /* Long mode enable */ +#define _EFER_LMA 10 /* Long mode active (read-only) */ +#define _EFER_NX 11 /* No execute enable */ +#define _EFER_SVME 12 + +#define EFER_SCE (1<<_EFER_SCE) +#define EFER_LME (1<<_EFER_LME) +#define EFER_LMA (1<<_EFER_LMA) +#define EFER_NX (1<<_EFER_NX) +#define EFER_SVME (1<<_EFER_SVME) + +/* Intel MSRs. Some also available on other CPUs */ +#define MSR_IA32_PLATFORM_ID 0x17 + +#define MSR_MTRRcap 0x0fe +#define MSR_IA32_MTRRCAP MSR_MTRRcap +#define MSR_IA32_MTRR_DEF_TYPE 0x2ff +#define MSR_IA32_BBL_CR_CTL 0x119 + +#define MSR_IA32_SYSENTER_CS 0x174 +#define MSR_IA32_SYSENTER_ESP 0x175 +#define MSR_IA32_SYSENTER_EIP 0x176 + +#define MSR_IA32_MCG_CAP 0x179 +#define MSR_IA32_MCG_STATUS 0x17a +#define MSR_IA32_MCG_CTL 0x17b + +/* P4/Xeon+ specific */ +#define MSR_IA32_MCG_EAX 0x180 +#define MSR_IA32_MCG_EBX 0x181 +#define MSR_IA32_MCG_ECX 0x182 +#define MSR_IA32_MCG_EDX 0x183 +#define MSR_IA32_MCG_ESI 0x184 +#define MSR_IA32_MCG_EDI 0x185 +#define MSR_IA32_MCG_EBP 0x186 +#define MSR_IA32_MCG_ESP 0x187 +#define MSR_IA32_MCG_EFLAGS 0x188 +#define MSR_IA32_MCG_EIP 0x189 +#define MSR_IA32_MCG_RESERVED 0x18A + +#define MSR_P6_EVNTSEL0 0x186 +#define MSR_P6_EVNTSEL1 0x187 + +#define MSR_IA32_PERF_STATUS 0x198 +#define MSR_IA32_PERF_CTL 0x199 + +#define MSR_IA32_THERM_CONTROL 0x19a +#define MSR_IA32_THERM_INTERRUPT 0x19b +#define MSR_IA32_THERM_STATUS 0x19c +#define MSR_IA32_MISC_ENABLE 0x1a0 + +#define MSR_IA32_MISC_ENABLE_PERF_AVAIL (1<<7) +#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1<<11) +#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1<<12) + +#define MSR_IA32_DEBUGCTLMSR 0x1d9 +#define MSR_IA32_LASTBRANCHFROMIP 0x1db +#define MSR_IA32_LASTBRANCHTOIP 0x1dc +#define MSR_IA32_LASTINTFROMIP 0x1dd +#define MSR_IA32_LASTINTTOIP 0x1de + +#define MSR_IA32_MC0_CTL 0x400 +#define MSR_IA32_MC0_STATUS 0x401 +#define MSR_IA32_MC0_ADDR 0x402 +#define MSR_IA32_MC0_MISC 0x403 + +/* Pentium IV performance counter MSRs */ +#define MSR_P4_BPU_PERFCTR0 0x300 +#define MSR_P4_BPU_PERFCTR1 0x301 +#define MSR_P4_BPU_PERFCTR2 0x302 +#define MSR_P4_BPU_PERFCTR3 0x303 +#define MSR_P4_MS_PERFCTR0 0x304 +#define MSR_P4_MS_PERFCTR1 0x305 +#define MSR_P4_MS_PERFCTR2 0x306 +#define MSR_P4_MS_PERFCTR3 0x307 +#define MSR_P4_FLAME_PERFCTR0 0x308 +#define MSR_P4_FLAME_PERFCTR1 0x309 +#define MSR_P4_FLAME_PERFCTR2 0x30a +#define MSR_P4_FLAME_PERFCTR3 0x30b +#define MSR_P4_IQ_PERFCTR0 0x30c +#define MSR_P4_IQ_PERFCTR1 0x30d +#define MSR_P4_IQ_PERFCTR2 0x30e +#define MSR_P4_IQ_PERFCTR3 0x30f +#define MSR_P4_IQ_PERFCTR4 0x310 +#define MSR_P4_IQ_PERFCTR5 0x311 +#define MSR_P4_BPU_CCCR0 0x360 +#define MSR_P4_BPU_CCCR1 0x361 +#define MSR_P4_BPU_CCCR2 0x362 +#define MSR_P4_BPU_CCCR3 0x363 +#define MSR_P4_MS_CCCR0 0x364 +#define MSR_P4_MS_CCCR1 0x365 +#define MSR_P4_MS_CCCR2 0x366 +#define MSR_P4_MS_CCCR3 0x367 +#define MSR_P4_FLAME_CCCR0 0x368 +#define MSR_P4_FLAME_CCCR1 0x369 +#define MSR_P4_FLAME_CCCR2 0x36a +#define MSR_P4_FLAME_CCCR3 0x36b +#define MSR_P4_IQ_CCCR0 0x36c +#define MSR_P4_IQ_CCCR1 0x36d +#define MSR_P4_IQ_CCCR2 0x36e +#define MSR_P4_IQ_CCCR3 0x36f +#define MSR_P4_IQ_CCCR4 0x370 +#define MSR_P4_IQ_CCCR5 0x371 +#define MSR_P4_ALF_ESCR0 0x3ca +#define MSR_P4_ALF_ESCR1 0x3cb +#define MSR_P4_BPU_ESCR0 0x3b2 +#define MSR_P4_BPU_ESCR1 0x3b3 +#define MSR_P4_BSU_ESCR0 0x3a0 +#define MSR_P4_BSU_ESCR1 0x3a1 +#define MSR_P4_CRU_ESCR0 0x3b8 +#define MSR_P4_CRU_ESCR1 0x3b9 +#define MSR_P4_CRU_ESCR2 0x3cc +#define MSR_P4_CRU_ESCR3 0x3cd +#define MSR_P4_CRU_ESCR4 0x3e0 +#define MSR_P4_CRU_ESCR5 0x3e1 +#define MSR_P4_DAC_ESCR0 0x3a8 +#define MSR_P4_DAC_ESCR1 0x3a9 +#define MSR_P4_FIRM_ESCR0 0x3a4 +#define MSR_P4_FIRM_ESCR1 0x3a5 +#define MSR_P4_FLAME_ESCR0 0x3a6 +#define MSR_P4_FLAME_ESCR1 0x3a7 +#define MSR_P4_FSB_ESCR0 0x3a2 +#define MSR_P4_FSB_ESCR1 0x3a3 +#define MSR_P4_IQ_ESCR0 0x3ba +#define MSR_P4_IQ_ESCR1 0x3bb +#define MSR_P4_IS_ESCR0 0x3b4 +#define MSR_P4_IS_ESCR1 0x3b5 +#define MSR_P4_ITLB_ESCR0 0x3b6 +#define MSR_P4_ITLB_ESCR1 0x3b7 +#define MSR_P4_IX_ESCR0 0x3c8 +#define MSR_P4_IX_ESCR1 0x3c9 +#define MSR_P4_MOB_ESCR0 0x3aa +#define MSR_P4_MOB_ESCR1 0x3ab +#define MSR_P4_MS_ESCR0 0x3c0 +#define MSR_P4_MS_ESCR1 0x3c1 +#define MSR_P4_PMH_ESCR0 0x3ac +#define MSR_P4_PMH_ESCR1 0x3ad +#define MSR_P4_RAT_ESCR0 0x3bc +#define MSR_P4_RAT_ESCR1 0x3bd +#define MSR_P4_SAAT_ESCR0 0x3ae +#define MSR_P4_SAAT_ESCR1 0x3af +#define MSR_P4_SSU_ESCR0 0x3be +#define MSR_P4_SSU_ESCR1 0x3bf /* guess: not defined in manual */ +#define MSR_P4_TBPU_ESCR0 0x3c2 +#define MSR_P4_TBPU_ESCR1 0x3c3 +#define MSR_P4_TC_ESCR0 0x3c4 +#define MSR_P4_TC_ESCR1 0x3c5 +#define MSR_P4_U2L_ESCR0 0x3b0 +#define MSR_P4_U2L_ESCR1 0x3b1 + +#define MSR_K6_EFER 0xC0000080 +#define MSR_K6_STAR 0xC0000081 +#define MSR_K6_WHCR 0xC0000082 +#define MSR_K6_UWCCR 0xC0000085 +#define MSR_K6_EPMR 0xC0000086 +#define MSR_K6_PSOR 0xC0000087 +#define MSR_K6_PFIR 0xC0000088 + +#define MSR_K7_EVNTSEL0 0xC0010000 +#define MSR_K7_EVNTSEL1 0xC0010001 +#define MSR_K7_EVNTSEL2 0xC0010002 +#define MSR_K7_EVNTSEL3 0xC0010003 +#define MSR_K7_PERFCTR0 0xC0010004 +#define MSR_K7_PERFCTR1 0xC0010005 +#define MSR_K7_PERFCTR2 0xC0010006 +#define MSR_K7_PERFCTR3 0xC0010007 +#define MSR_K7_HWCR 0xC0010015 +#define MSR_K7_CLK_CTL 0xC001001b +#define MSR_K7_FID_VID_CTL 0xC0010041 +#define MSR_K7_FID_VID_STATUS 0xC0010042 + +#define MSR_K8_TOP_MEM1 0xC001001A +#define MSR_K8_TOP_MEM2 0xC001001D +#define MSR_K8_SYSCFG 0xC0010010 +#define MSR_K8_HWCR 0xC0010015 +#define MSR_K8_VM_CR 0xC0010114 +#define MSR_K8_VM_HSAVE_PA 0xC0010117 + +/* MSR_K8_VM_CR bits: */ +#define _K8_VMCR_SVME_DISABLE 4 +#define K8_VMCR_SVME_DISABLE (1 << _K8_VMCR_SVME_DISABLE) + +/* Centaur-Hauls/IDT defined MSRs. */ +#define MSR_IDT_FCR1 0x107 +#define MSR_IDT_FCR2 0x108 +#define MSR_IDT_FCR3 0x109 +#define MSR_IDT_FCR4 0x10a + +#define MSR_IDT_MCR0 0x110 +#define MSR_IDT_MCR1 0x111 +#define MSR_IDT_MCR2 0x112 +#define MSR_IDT_MCR3 0x113 +#define MSR_IDT_MCR4 0x114 +#define MSR_IDT_MCR5 0x115 +#define MSR_IDT_MCR6 0x116 +#define MSR_IDT_MCR7 0x117 +#define MSR_IDT_MCR_CTRL 0x120 + +/* VIA Cyrix defined MSRs*/ +#define MSR_VIA_FCR 0x1107 +#define MSR_VIA_LONGHAUL 0x110a +#define MSR_VIA_RNG 0x110b +#define MSR_VIA_BCR2 0x1147 + +/* Transmeta defined MSRs */ +#define MSR_TMTA_LONGRUN_CTRL 0x80868010 +#define MSR_TMTA_LONGRUN_FLAGS 0x80868011 +#define MSR_TMTA_LRTI_READOUT 0x80868018 +#define MSR_TMTA_LRTI_VOLT_MHZ 0x8086801a + +#endif /* __ASM_MSR_H */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/mtrr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/mtrr.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,14 @@ +#ifndef __ASM_X86_MTRR_H__ +#define __ASM_X86_MTRR_H__ + +#include + +/* These are the region types. They match the architectural specification. */ +#define MTRR_TYPE_UNCACHABLE 0 +#define MTRR_TYPE_WRCOMB 1 +#define MTRR_TYPE_WRTHROUGH 4 +#define MTRR_TYPE_WRPROT 5 +#define MTRR_TYPE_WRBACK 6 +#define MTRR_NUM_TYPES 7 + +#endif /* __ASM_X86_MTRR_H__ */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/multiboot.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/multiboot.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,112 @@ +/* multiboot.h - the header for Multiboot */ +/* Copyright (C) 1999, 2001 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef __MULTIBOOT_H__ +#define __MULTIBOOT_H__ + + +/* + * Multiboot header structure. + */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 +#define MULTIBOOT_HEADER_MODS_ALIGNED 0x00000001 +#define MULTIBOOT_HEADER_WANT_MEMORY 0x00000002 +#define MULTIBOOT_HEADER_HAS_VBE 0x00000004 +#define MULTIBOOT_HEADER_HAS_ADDR 0x00010000 + +/* The magic number passed by a Multiboot-compliant boot loader. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +#define MBI_MEMLIMITS (1<<0) +#define MBI_DRIVES (1<<1) +#define MBI_CMDLINE (1<<2) +#define MBI_MODULES (1<<3) +#define MBI_AOUT_SYMS (1<<4) +#define MBI_ELF_SYMS (1<<5) +#define MBI_MEMMAP (1<<6) +#define MBI_LOADERNAME (1<<9) + +#ifndef __ASSEMBLY__ + +/* The symbol table for a.out. */ +typedef struct { + u32 tabsize; + u32 strsize; + u32 addr; + u32 reserved; +} aout_symbol_table_t; + +/* The section header table for ELF. */ +typedef struct { + u32 num; + u32 size; + u32 addr; + u32 shndx; +} elf_section_header_table_t; + +/* The Multiboot information. */ +typedef struct { + u32 flags; + + /* Valid if flags sets MBI_MEMLIMITS */ + u32 mem_lower; + u32 mem_upper; + + /* Valid if flags sets MBI_DRIVES */ + u32 boot_device; + + /* Valid if flags sets MBI_CMDLINE */ + u32 cmdline; + + /* Valid if flags sets MBI_MODULES */ + u32 mods_count; + u32 mods_addr; + + /* Valid if flags sets ... */ + union { + aout_symbol_table_t aout_sym; /* ... MBI_AOUT_SYMS */ + elf_section_header_table_t elf_sec; /* ... MBI_ELF_SYMS */ + } u; + + /* Valid if flags sets MBI_MEMMAP */ + u32 mmap_length; + u32 mmap_addr; +} multiboot_info_t; + +/* The module structure. */ +typedef struct { + u32 mod_start; + u32 mod_end; + u32 string; + u32 reserved; +} module_t; + +/* The memory map. Be careful that the offset 0 is base_addr_low + but no size. */ +typedef struct { + u32 size; + u32 base_addr_low; + u32 base_addr_high; + u32 length_low; + u32 length_high; + u32 type; +} memory_map_t; + + +#endif /* __ASSEMBLY__ */ + +#endif /* __MULTIBOOT_H__ */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/page.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/page.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,33 @@ + +#ifndef __X86_PAGE_H__ +#define __X86_PAGE_H__ + +/* + * It is important that the masks are signed quantities. This ensures that + * the compiler sign-extends a 32-bit mask to 64 bits if that is required. + */ +#define PAGE_SHIFT 12 + +#ifndef __ASSEMBLY__ +#define PAGE_SIZE (1L << PAGE_SHIFT) +#else +#define PAGE_SIZE (1 << PAGE_SHIFT) +#endif +#define PAGE_MASK (~(PAGE_SIZE-1)) +#define PAGE_FLAG_MASK (~0) + + +#define L1_PAGETABLE_SHIFT 12 +#define L2_PAGETABLE_SHIFT 22 + +#endif /* __X86_PAGE_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/printk.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/printk.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,36 @@ +/* + * printk.h: printk to serial for very early boot stages + * + * Copyright (c) 2006-2007, Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + */ + +#ifndef __PRINTK_H__ +#define __PRINTK_H__ + +#ifdef DEBUG +#define printk early_serial_printk +#else +#define printk /**/ +#endif + +extern void init_log(void); +extern void print_log(void); +extern void early_serial_printk(const char *fmt, ...) + __attribute__ ((format (printf, 1, 2))); + + +#endif diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/processor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/processor.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,326 @@ + +/* Portions are: Copyright (c) 1994 Linus Torvalds */ + +#ifndef __ASM_X86_PROCESSOR_H +#define __ASM_X86_PROCESSOR_H + +/* + * CPU vendor IDs + */ +#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 + +/* + * 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 */ + +/* + * Intel CPU flags in CR0 + */ +#define X86_CR0_PE 0x00000001 /* Enable Protected Mode (RW) */ +#define X86_CR0_MP 0x00000002 /* Monitor Coprocessor (RW) */ +#define X86_CR0_EM 0x00000004 /* Require FPU Emulation (RO) */ +#define X86_CR0_TS 0x00000008 /* Task Switched (RW) */ +#define X86_CR0_ET 0x00000010 /* Extension type (RO) */ +#define X86_CR0_NE 0x00000020 /* Numeric Error Reporting (RW) */ +#define X86_CR0_WP 0x00010000 /* Supervisor Write Protect (RW) */ +#define X86_CR0_AM 0x00040000 /* Alignment Checking (RW) */ +#define X86_CR0_NW 0x20000000 /* Not Write-Through (RW) */ +#define X86_CR0_CD 0x40000000 /* Cache Disable (RW) */ +#define X86_CR0_PG 0x80000000 /* Paging (RW) */ + +/* + * Intel CPU features in CR4 + */ +#define X86_CR4_VME 0x0001 /* enable vm86 extensions */ +#define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */ +#define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */ +#define X86_CR4_DE 0x0008 /* enable debugging extensions */ +#define X86_CR4_PSE 0x0010 /* enable page size extensions */ +#define X86_CR4_PAE 0x0020 /* enable physical address extensions */ +#define X86_CR4_MCE 0x0040 /* Machine check enable */ +#define X86_CR4_PGE 0x0080 /* enable global pages */ +#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */ +#define X86_CR4_OSFXSR 0x0200 /* enable fast FPU save and restore */ +#define X86_CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */ +#define X86_CR4_VMXE 0x2000 /* enable VMX */ +#define X86_CR4_SMXE 0x4000 /* enable SMX */ + +/* + * Trap/fault mnemonics. + */ +#define TRAP_divide_error 0 +#define TRAP_debug 1 +#define TRAP_nmi 2 +#define TRAP_int3 3 +#define TRAP_overflow 4 +#define TRAP_bounds 5 +#define TRAP_invalid_op 6 +#define TRAP_no_device 7 +#define TRAP_double_fault 8 +#define TRAP_copro_seg 9 +#define TRAP_invalid_tss 10 +#define TRAP_no_segment 11 +#define TRAP_stack_error 12 +#define TRAP_gp_fault 13 +#define TRAP_page_fault 14 +#define TRAP_spurious_int 15 +#define TRAP_copro_error 16 +#define TRAP_alignment_check 17 +#define TRAP_machine_check 18 +#define TRAP_simd_error 19 +#define TRAP_deferred_nmi 31 + +/* Set for entry via SYSCALL. Informs return code to use SYSRETQ not IRETQ. */ +/* NB. Same as VGCF_in_syscall. No bits in common with any other TRAP_ defn. */ +#define TRAP_syscall 256 + +/* + * Non-fatal fault/trap handlers return an error code to the caller. If the + * code is non-zero, it means that either the exception was not due to a fault + * (i.e., it was a trap) or that the fault has been fixed up so the instruction + * replay ought to succeed. + */ +#define EXCRET_not_a_fault 1 /* It was a trap. No instruction replay needed. */ +#define EXCRET_fault_fixed 1 /* It was fault that we fixed: try a replay. */ + +/* 'trap_bounce' flags values */ +#define TBF_EXCEPTION 1 +#define TBF_EXCEPTION_ERRCODE 2 +#define TBF_INTERRUPT 8 +#define TBF_FAILSAFE 16 + +/* 'arch_vcpu' flags values */ +#define _TF_kernel_mode 0 +#define TF_kernel_mode (1<<_TF_kernel_mode) + +/* #PF error code values. */ +#define PFEC_page_present (1U<<0) +#define PFEC_write_access (1U<<1) +#define PFEC_user_mode (1U<<2) +#define PFEC_reserved_bit (1U<<3) +#define PFEC_insn_fetch (1U<<4) + +#ifndef __ASSEMBLY__ + +/* + * Generic CPUID function + * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx + * resulting in stale register contents being returned. + */ +#define cpuid(_op,_eax,_ebx,_ecx,_edx) \ + __asm__ __volatile__ ("cpuid" \ + : "=a" (*(int *)(_eax)), \ + "=b" (*(int *)(_ebx)), \ + "=c" (*(int *)(_ecx)), \ + "=d" (*(int *)(_edx)) \ + : "0" (_op), "2" (0)) + +/* Some CPUID calls want 'count' to be placed in ecx */ +static inline void cpuid_count( + int op, + int count, + unsigned int *eax, + unsigned int *ebx, + unsigned int *ecx, + unsigned int *edx) +{ + __asm__ __volatile__ ("cpuid" + : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) + : "0" (op), "c" (count)); +} + +/* + * CPUID functions returning a single datum + */ +static always_inline unsigned int cpuid_eax(unsigned int op) +{ + unsigned int eax; + + __asm__ __volatile__ ("cpuid" + : "=a" (eax) + : "0" (op) + : "bx", "cx", "dx"); + return eax; +} +static always_inline unsigned int cpuid_ebx(unsigned int op) +{ + unsigned int eax, ebx; + + __asm__ __volatile__ ("cpuid" + : "=a" (eax), "=b" (ebx) + : "0" (op) + : "cx", "dx" ); + return ebx; +} +static always_inline unsigned int cpuid_ecx(unsigned int op) +{ + unsigned int eax, ecx; + + __asm__ __volatile__ ("cpuid" + : "=a" (eax), "=c" (ecx) + : "0" (op) + : "bx", "dx" ); + return ecx; +} +static always_inline unsigned int cpuid_edx(unsigned int op) +{ + unsigned int eax, edx; + + __asm__ __volatile__ ("cpuid" + : "=a" (eax), "=d" (edx) + : "0" (op) + : "bx", "cx"); + return edx; +} + + + +static inline unsigned long read_cr0(void) +{ + unsigned long __cr0; + __asm__ __volatile__ ("mov %%cr0,%0\n\t" :"=r" (__cr0)); + return __cr0; +} + +static inline void write_cr0(unsigned long val) +{ + __asm__ __volatile__ ("mov %0,%%cr0": :"r" ((unsigned long)val)); +} + +static inline unsigned long read_cr2(void) +{ + unsigned long __cr2; + __asm__ __volatile__ ("mov %%cr2,%0\n\t" :"=r" (__cr2)); + return __cr2; +} + +static inline unsigned long read_cr4(void) +{ + unsigned long __cr4; + __asm__ __volatile__ ("mov %%cr4,%0\n\t" :"=r" (__cr4)); + return __cr4; +} + +static inline void write_cr4(unsigned long val) +{ + __asm__ __volatile__ ("mov %0,%%cr4": :"r" ((unsigned long)val)); +} + +/* Read pagetable base. */ +static inline unsigned long read_cr3(void) +{ + unsigned long cr3; + __asm__ __volatile__ ("mov %%cr3, %0" : "=r" (cr3) : ); + return cr3; +} + +static inline void write_cr3(unsigned long cr3) +{ + __asm__ __volatile__ ( "mov %0, %%cr3" : : "r" (cr3) : "memory" ); +} + +static always_inline void set_in_cr4 (unsigned long mask) +{ + unsigned long dummy; + __asm__ __volatile__ ( + "mov %%cr4,%0\n\t" + "or %1,%0\n\t" + "mov %0,%%cr4\n" + : "=&r" (dummy) : "irg" (mask) ); +} + +static always_inline void clear_in_cr4 (unsigned long mask) +{ + unsigned long dummy; + __asm__ __volatile__ ( + "mov %%cr4,%0\n\t" + "and %1,%0\n\t" + "mov %0,%%cr4\n" + : "=&r" (dummy) : "irg" (~mask) ); +} + +/* Clear and set 'TS' bit respectively */ +static inline void clts(void) +{ + __asm__ __volatile__ ("clts"); +} + +static inline void stts(void) +{ + write_cr0(X86_CR0_TS|read_cr0()); +} + + +/* Stop speculative execution */ +static inline void sync_core(void) +{ + int tmp; + __asm__ __volatile__ ("cpuid" : "=a" (tmp) : "0" (1) + : "ebx","ecx","edx","memory"); +} + +static always_inline void __monitor(const void *eax, unsigned long ecx, + unsigned long edx) +{ + /* "monitor %eax,%ecx,%edx;" */ + __asm__ __volatile__ ( + ".byte 0x0f,0x01,0xc8;" + : :"a" (eax), "c" (ecx), "d"(edx)); +} + +static always_inline void __mwait(unsigned long eax, unsigned long ecx) +{ + /* "mwait %eax,%ecx;" */ + __asm__ __volatile__ ( + ".byte 0x0f,0x01,0xc9;" + : :"a" (eax), "c" (ecx)); +} + +/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ +static always_inline void rep_nop(void) +{ + __asm__ __volatile__ ( "rep;nop" : : : "memory" ); +} + +#define cpu_relax() rep_nop() + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_X86_PROCESSOR_H */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/sboot.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/sboot.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,114 @@ +/* + * sboot.h: shared data structure with MLE and kernel and functions + * used by kernel for runtime support + * + * Copyright (c) 2006-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Intel Corporation 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + */ + +#ifndef __SBOOT_H__ +#define __SBOOT_H__ + +/* + * used to communicate between sboot and the launched kernel (i.e. Xen) + */ +typedef struct { + uuid_t uuid; /* {663C8DFF-E8B3-4b82-AABF-19EA4D057A08} */ + uint32_t version; /* 0x01 */ + uint32_t log_addr; /* physical addr of sb_log_t log */ + uint32_t shutdown_entry32; /* entry point for sboot shutdown from 32b */ + uint32_t shutdown_entry64; /* entry point for sboot shutdown from 64b */ + uint32_t shutdown_type; /* type of shutdown (reboot, S5, etc.) */ +} mle_kernel_shared_t; + +#define SB_SHUTDOWN_REBOOT 0 +#define SB_SHUTDOWN_S5 1 +#define SB_SHUTDOWN_S4 2 +#define SB_SHUTDOWN_S3 3 + +/* {663C8DFF-E8B3-4b82-AABF-19EA4D057A08} */ +static const uuid_t mle_kernel_shared_uuid = + { 0x663c8dff, 0xe8b3, 0x4b82, 0xaabf, + { 0x19, 0xea, 0x4d, 0x5, 0x7a, 0x8 } }; + +/* + * used to log sboot printk output + */ +#define MAX_SB_LOG_SIZE 12288 /* 3 pages */ + +typedef struct { + uuid_t uuid; + uint32_t max_size; + uint32_t curr_pos; + char buf[MAX_SB_LOG_SIZE]; +} sb_log_t; + +/* {C0192526-6B30-4db4-844C-A3E953B88174} */ +#define SB_LOG_UUID { 0xc0192526, 0x6b30, 0x4db4, 0x844c, \ + { 0xa3, 0xe9, 0x53, 0xb8, 0x81, 0x74 } } + + +/* + * these are only used in Xen + */ + +#ifdef __XEN__ +#include +#include +#include +#include +#include +#include + +extern mle_kernel_shared_t *g_mle_shared; + +static inline bool sboot_in_measured_env(void) +{ + return (g_mle_shared != NULL); +} +#else +/* in common/sboot.c */ +extern void cpu_wakeup(uint32_t cpuid, uint32_t sipi_vec); +extern void shutdown_system(uint32_t shutdown_type); +#endif /* __XEN__ */ + +#endif /* __SBOOT_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/spinlock.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/spinlock.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,49 @@ +#ifndef __SPINLOCK_H__ +#define __SPINLOCK_H__ +#include + +/* simple spinlock as part of sboot(WAKEUP) are smp */ +typedef struct { + volatile s16 lock; + s8 recurse_cpu; + u8 recurse_cnt; +} spinlock_t; + +#define SPIN_LOCK_UNLOCKED /*(spinlock_t)*/ { 1, -1, 0 } + +#define spin_lock_init(x) do { *(x) = (spinlock_t) SPIN_LOCK_UNLOCKED; } while(0) +#define spin_is_locked(x) (*(volatile char *)(&(x)->lock) <= 0) +static inline void _raw_spin_lock(spinlock_t *lock) +{ + __asm__ __volatile__ ( + "1: lock; decb %0 \n" + " js 2f \n" + ".section .text.lock,\"ax\"\n" + "2: cmpb $0,%0 \n" + " rep; nop \n" + " jle 2b \n" + " jmp 1b \n" + ".previous" + : "=m" (lock->lock) : : "memory" ); +} + +static inline void _raw_spin_unlock(spinlock_t *lock) +{ +#if !defined(CONFIG_X86_OOSTORE) +/* ASSERT(spin_is_locked(lock));*/ + __asm__ __volatile__ ( + "movb $1,%0" + : "=m" (lock->lock) : : "memory" ); +#else + char oldval = 1; +/* ASSERT(spin_is_locked(lock));*/ + __asm__ __volatile__ ( + "xchgb %b0, %1" + : "=q" (oldval), "=m" (lock->lock) : "0" (oldval) : "memory" ); +#endif +} +#define spin_lock(_lock) _raw_spin_lock(_lock) +#define spin_unlock(_lock) _raw_spin_unlock(_lock) +#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED + +#endif /* __SPINLOCK_H__ */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/string.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/string.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,231 @@ +#ifndef __X86_STRING_H__ +#define __X86_STRING_H__ + +#include + +static inline void *__variable_memcpy(void *to, const void *from, size_t n) +{ + long d0, d1, d2; + __asm__ __volatile__ ( + " rep ; movs"__OS"\n" + " mov %4,%3 \n" + " rep ; movsb \n" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n/BYTES_PER_LONG), "r" (n%BYTES_PER_LONG), "1" (to), "2" (from) + : "memory" ); + return to; +} + +/* + * This looks horribly ugly, but the compiler can optimize it totally, + * as the count is constant. + */ +static always_inline void * __constant_memcpy( + void * to, const void * from, size_t n) +{ + switch ( n ) + { + case 0: + return to; + case 1: + *(u8 *)to = *(const u8 *)from; + return to; + case 2: + *(u16 *)to = *(const u16 *)from; + return to; + case 3: + *(u16 *)to = *(const u16 *)from; + *(2+(u8 *)to) = *(2+(const u8 *)from); + return to; + case 4: + *(u32 *)to = *(const u32 *)from; + return to; + case 5: + *(u32 *)to = *(const u32 *)from; + *(4+(u8 *)to) = *(4+(const u8 *)from); + return to; + case 6: + *(u32 *)to = *(const u32 *)from; + *(2+(u16 *)to) = *(2+(const u16 *)from); + return to; + case 7: + *(u32 *)to = *(const u32 *)from; + *(2+(u16 *)to) = *(2+(const u16 *)from); + *(6+(u8 *)to) = *(6+(const u8 *)from); + return to; + case 8: + *(u64 *)to = *(const u64 *)from; + return to; + case 12: + *(u64 *)to = *(const u64 *)from; + *(2+(u32 *)to) = *(2+(const u32 *)from); + return to; + case 16: + *(u64 *)to = *(const u64 *)from; + *(1+(u64 *)to) = *(1+(const u64 *)from); + return to; + case 20: + *(u64 *)to = *(const u64 *)from; + *(1+(u64 *)to) = *(1+(const u64 *)from); + *(4+(u32 *)to) = *(4+(const u32 *)from); + return to; + } +#define COMMON(x) \ + __asm__ __volatile__ ( \ + "rep ; movs"__OS \ + x \ + : "=&c" (d0), "=&D" (d1), "=&S" (d2) \ + : "0" (n/BYTES_PER_LONG), "1" (to), "2" (from) \ + : "memory" ); + { + long d0, d1, d2; + switch ( n % BYTES_PER_LONG ) + { + case 0: COMMON(""); return to; + case 1: COMMON("\n\tmovsb"); return to; + case 2: COMMON("\n\tmovsw"); return to; + case 3: COMMON("\n\tmovsw\n\tmovsb"); return to; + case 4: COMMON("\n\tmovsl"); return to; + case 5: COMMON("\n\tmovsl\n\tmovsb"); return to; + case 6: COMMON("\n\tmovsl\n\tmovsw"); return to; + case 7: COMMON("\n\tmovsl\n\tmovsw\n\tmovsb"); return to; + } + } +#undef COMMON + return to; +} + +#define __HAVE_ARCH_MEMCPY +#define memcpy(t,f,n) (__memcpy((t),(f),(n))) +static always_inline +void *__memcpy(void *t, const void *f, size_t n) +{ + return (__builtin_constant_p(n) ? + __constant_memcpy((t),(f),(n)) : + __variable_memcpy((t),(f),(n))); +} + +#define __HAVE_ARCH_MEMCMP +#define memcmp __builtin_memcmp + +static inline void *__memset_generic(void *s, char c, size_t count) +{ + long d0, d1; + __asm__ __volatile__ ( + "rep ; stosb" + : "=&c" (d0), "=&D" (d1) : "a" (c), "1" (s), "0" (count) : "memory" ); + return s; +} + +/* we might want to write optimized versions of these later */ +#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count)) + +/* + * memset(x,0,y) is a reasonably common thing to do, so we want to fill + * things 32 bits at a time even when we don't know the size of the + * area at compile-time.. + */ +static inline void *__constant_c_memset(void *s, unsigned long c, size_t count) +{ + long d0, d1; + __asm__ __volatile__( + " rep ; stos"__OS"\n" + " mov %3,%4 \n" + " rep ; stosb \n" + : "=&c" (d0), "=&D" (d1) + : "a" (c), "r" (count%BYTES_PER_LONG), + "0" (count/BYTES_PER_LONG), "1" (s) + : "memory" ); + return s; +} + +/* + * This looks horribly ugly, but the compiler can optimize it totally, + * as we by now know that both pattern and count is constant.. + */ +static always_inline void *__constant_c_and_count_memset( + void *s, unsigned long pattern, size_t count) +{ + switch ( count ) + { + case 0: + return s; + case 1: + *(u8 *)s = pattern; + return s; + case 2: + *(u16 *)s = pattern; + return s; + case 3: + *(u16 *)s = pattern; + *(2+(u8 *)s) = pattern; + return s; + case 4: + *(u32 *)s = pattern; + return s; + case 5: + *(u32 *)s = pattern; + *(4+(u8 *)s) = pattern; + return s; + case 6: + *(u32 *)s = pattern; + *(2+(u16 *)s) = pattern; + return s; + case 7: + *(u32 *)s = pattern; + *(2+(u16 *)s) = pattern; + *(6+(u8 *)s) = pattern; + return s; + case 8: + *(u64 *)s = pattern; + return s; + } +#define COMMON(x) \ + __asm__ __volatile__ ( \ + "rep ; stos"__OS \ + x \ + : "=&c" (d0), "=&D" (d1) \ + : "a" (pattern), "0" (count/BYTES_PER_LONG), "1" (s) \ + : "memory" ) + { + long d0, d1; + switch ( count % BYTES_PER_LONG ) + { + case 0: COMMON(""); return s; + case 1: COMMON("\n\tstosb"); return s; + case 2: COMMON("\n\tstosw"); return s; + case 3: COMMON("\n\tstosw\n\tstosb"); return s; + case 4: COMMON("\n\tstosl"); return s; + case 5: COMMON("\n\tstosl\n\tstosb"); return s; + case 6: COMMON("\n\tstosl\n\tstosw"); return s; + case 7: COMMON("\n\tstosl\n\tstosw\n\tstosb"); return s; + } + } +#undef COMMON + return s; +} + +#define __constant_c_x_memset(s, c, count) \ +(__builtin_constant_p(count) ? \ + __constant_c_and_count_memset((s),(c),(count)) : \ + __constant_c_memset((s),(c),(count))) + +#define __var_x_memset(s, c, count) \ +(__builtin_constant_p(count) ? \ + __constant_count_memset((s),(c),(count)) : \ + __memset_generic((s),(c),(count))) + +#ifdef CONFIG_X86_64 +#define MEMSET_PATTERN_MUL 0x0101010101010101UL +#else +#define MEMSET_PATTERN_MUL 0x01010101UL +#endif + +#define __HAVE_ARCH_MEMSET +#define memset(s, c, count) (__memset((s),(c),(count))) +#define __memset(s, c, count) \ +(__builtin_constant_p(c) ? \ + __constant_c_x_memset((s),(MEMSET_PATTERN_MUL*(unsigned char)(c)),(count)) : \ + __var_x_memset((s),(c),(count))) + +#endif /* __X86_STRING_H__ */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/string2.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/string2.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,15 @@ +#ifndef _LINUX_STRING_H_ +#define _LINUX_STRING_H_ + +#include /* for size_t */ + +/* + * Include machine specific inline routines + */ +#include + +extern size_t strnlen(const char *,size_t); + +extern void * memmove(void *,const void *,size_t); + +#endif /* _LINUX_STRING_H_ */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/tpm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/tpm.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,191 @@ +/* + * tpm.h: TPM-related support functions + * + * Copyright (c) 2006-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Intel Corporation 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + */ + +#ifndef __TPM_H__ +#define __TPM_H__ + +#define TPM_LOCALITY_BASE 0xfed40000 +#define NR_TPM_LOCALITY_PAGES ((TPM_LOCALITY_1 - TPM_LOCALITY_0) >> \ + PAGE_SHIFT) + +#define TPM_LOCALITY_0 TPM_LOCALITY_BASE +#define TPM_LOCALITY_1 (TPM_LOCALITY_BASE | 0x1000) +#define TPM_LOCALITY_2 (TPM_LOCALITY_BASE | 0x2000) +/* these localities (3+4) are mostly not usable by Xen */ +#define TPM_LOCALITY_3 (TPM_LOCALITY_BASE | 0x3000) +#define TPM_LOCALITY_4 (TPM_LOCALITY_BASE | 0x4000) + +#define TPM_LOCALITY_BASE_N(n) (TPM_LOCALITY_BASE | ((n) << 12)) + +#define TPM_NR_LOCALITIES 5 + +/* + * return code: + * The TPM has five types of return code. One indicates successful operation + * and four indicate failure. + * TPM_SUCCESS (00000000) indicates successful execution. + * The failure reports are: + * TPM defined fatal errors (00000001 to 000003FF) + * vendor defined fatal errors (00000400 to 000007FF) + * TPM defined non-fatal errors (00000800 to 00000BFF) + * vendor defined non-fatal errors (00000C00 to 00000FFF). + * Here only give definitions for a few commonly used return code. + */ +#define TPM_BASE 0X00000000 +#define TPM_SUCCESS TPM_BASE +#define TPM_BADINDEX (TPM_BASE + 2) +#define TPM_BAD_PARAMETER (TPM_BASE + 3) +#define TPM_DEACTIVATED (TPM_BASE + 6) +#define TPM_DISABLED (TPM_BASE + 7) +#define TPM_FAIL (TPM_BASE + 9) +#define TPM_BAD_ORDINAL (TPM_BASE + 10) +#define TPM_NOSPACE (TPM_BASE + 17) +#define TPM_NOTRESETABLE (TPM_BASE + 50) +#define TPM_NOTLOCAL (TPM_BASE + 51) +#define TPM_BAD_LOCALITY (TPM_BASE + 61) +#define TPM_READ_ONLY (TPM_BASE + 62) +#define TPM_NOT_FULLWRITE (TPM_BASE + 70) + +extern bool is_tpm_ready(uint32_t locality); + +extern uint32_t tpm_get_version(uint8_t *major, uint8_t *minor); + +#define TPM_DIGEST_SIZE 20 +typedef struct { + uint8_t digest[TPM_DIGEST_SIZE]; +} __attribute__ ((packed)) tpm_digest_t; +typedef tpm_digest_t tpm_pcr_value_t; + +/* + * specified as minimum cmd buffer size should be supported by all 1.2 TPM + * device in the TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf + */ +#define TPM_CMD_SIZE_MAX 768 +#define TPM_RSP_SIZE_MAX 768 + +#define TPM_NR_PCRS 24 + +/* + * tpm_pcr_read fetchs the current value of given PCR vai given locality. + * locality : TPM locality (0 - 4) + * pcr : PCR index (0 - 23) + * out : PCR value buffer, out parameter, should not be NULL + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_pcr_read(uint32_t locality, uint32_t pcr, + tpm_pcr_value_t *pcr_value); + +/* + * tpm_pcr_extend extends data octets into given PCR via given locality, + * and return the PCR value after extending if required. + * locality : TPM locality (0 - 4) + * pcr : PCR index (0 - 23) + * in : Hash value to be extended into PCR, should not be NULL + * out : Out buffer for PCR value after extending, may be NULL + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_pcr_extend(uint32_t locality, uint32_t pcr, + const tpm_digest_t* in, tpm_pcr_value_t* out); + +/* PCRs lower than 16 are not resetable */ +#define TPM_PCR_RESETABLE_MIN 16 + +/* + * tpm_pcr_reset resets given PCR via given locality. + * locality : TPM locality (0 - 4) + * pcr : PCR index (16 - 23) + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_pcr_reset(uint32_t locality, uint32_t pcr); + +#define TPM_NV_READ_VALUE_DATA_SIZE_MAX (TPM_RSP_SIZE_MAX - 14) + +typedef uint32_t tpm_nv_index_t; + +/* + * tpm_nv_read_value reads data from TPM NV ram in the given locality. + * locality : TPM locality (0 - 4) + * index : Predefined index for certain NV space + * offset : Start reading from offset given by this parameter. + * data : Out buffer for read data, should not be NULL + * data_size : As IN, give the size required to read, should not be NULL; + * : as OUT, return the size really read from TPM. + * : The largest nv data size can be read in a single call is + * : defined by TPM_NV_READ_VALUE_DATA_SIZE_MAX. + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_nv_read_value(uint32_t locality, tpm_nv_index_t index, + uint32_t offset, uint8_t *data, + uint32_t *data_size); + +#define TPM_NV_WRITE_VALUE_DATA_SIZE_MAX (TPM_CMD_SIZE_MAX - 22) + +/* + * tpm_nv_write_value writes data into TPM NV ram in the given locality. + * locality : TPM locality (0 - 4) + * index : Predefined index for certain NV space + * offset : Start writing from offset given by this parameter. + * data : Data to be written to TPM NV, should not be NULL + * data_size : The size of data to be written. + * : The largest nv data size can be written in a single call + * : is defined by TPM_NV_WRITE_VALUE_DATA_SIZE_MAX. + * return : TPM_SUCCESS for success, error code defined as TPM_xxx + */ +extern uint32_t tpm_nv_write_value(uint32_t locality, tpm_nv_index_t index, + uint32_t offset, const uint8_t *data, + uint32_t data_size); + +/* #define TPM_UNIT_TEST 1 */ + +#ifdef TPM_UNIT_TEST +void tpm_unit_test_before_senter(void); +void tpm_unit_test_after_senter(void); +#else +#define tpm_unit_test_before_senter() +#define tpm_unit_test_after_senter() +#endif /* TPM_UNIT_TEST */ + +#endif /* __TPM_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/txt/acmod.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/txt/acmod.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,96 @@ +/* + * acmod.c: support functions for use of Intel(r) TXT Authenticated + * Code (AC) Modules + * + * Copyright (c) 2003-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Intel Corporation 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + */ + +#ifndef __TXT_ACMOD_H__ +#define __TXT_ACMOD_H__ + +#include +#include +#include + +/* + * authenticated code (AC) module header (ver 0.0) + */ + +typedef struct { + uint32_t module_type; + uint32_t header_len; + uint32_t header_ver; + uint32_t module_id; + uint32_t module_vendor; + uint32_t date; + uint32_t size; + uint32_t reserved1; + uint32_t code_control; + uint32_t error_entry_point; + uint32_t gdt_limit; + uint32_t gdt_base; + uint32_t seg_sel; + uint32_t entry_point; + uint8_t reserved2[64]; + uint32_t key_size; + uint32_t scratch_size; + uint8_t rsa2048_pubkey[256]; + uint32_t pub_exp; + uint8_t rsa2048_sig[256]; + uint32_t scratch[143]; + uint8_t user_area[]; +} acm_hdr_t; + +/* value of mod_type field */ +#define ACM_TYPE_CHIPSET 0x02 + +/* value of module_vendor field */ +#define ACM_VENDOR_INTEL 0x8086 + +extern bool is_sinit_acmod(void *acmod_base, uint32_t acmod_size); +extern bool does_acmod_match_chipset(acm_hdr_t* hdr); +extern acm_hdr_t *copy_sinit(acm_hdr_t *sinit); +extern bool verify_acmod(acm_hdr_t *acm_hdr); +extern void set_mtrrs_for_acmod(acm_hdr_t *hdr); +extern uint32_t get_supported_os_sinit_data_ver(acm_hdr_t* hdr); + +#endif /* __TXT_ACMOD_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/txt/config_regs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/txt/config_regs.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,207 @@ +/* + * config_regs.h: Intel(r) TXT configuration register -related definitions + * + * Copyright (c) 2003-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Intel Corporation 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + */ + +#ifndef __TXT_CONFIG_REGS_H__ +#define __TXT_CONFIG_REGS_H__ + +/* + * TXT configuration registers (offsets from TXT_{PUB, PRIV}_CONFIG_REGS_BASE) + */ + +#define TXT_PUB_CONFIG_REGS_BASE 0xfed30000 +#define TXT_PRIV_CONFIG_REGS_BASE 0xfed20000 + +/* # pages for each config regs space - used by fixmap */ +#define NR_TXT_CONFIG_PAGES ((TXT_PUB_CONFIG_REGS_BASE - \ + TXT_PRIV_CONFIG_REGS_BASE) >> \ + PAGE_SHIFT) + +/* offsets to config regs (from either public or private _BASE) */ +#define TXTCR_STS 0x0000 +#define TXTCR_ESTS 0x0008 +#define TXTCR_ERRORCODE 0x0030 +#define TXTCR_CMD_SYS_RESET 0x0038 +#define TXTCR_CMD_OPEN_PRIVATE 0x0040 +#define TXTCR_CMD_CLOSE_PRIVATE 0x0048 +#define TXTCR_DIDVID 0x0110 /* TBD: need to publish */ +#define TXTCR_CMD_FLUSH_WB 0x0258 +#define TXTCR_SINIT_BASE 0x0270 +#define TXTCR_SINIT_SIZE 0x0278 +#define TXTCR_MLE_JOIN 0x0290 +#define TXTCR_HEAP_BASE 0x0300 +#define TXTCR_HEAP_SIZE 0x0308 +#define TXTCR_CMD_OPEN_LOCALITY1 0x0380 /* TBD: need to publish */ +#define TXTCR_CMD_CLOSE_LOCALITY1 0x0388 /* TBD: need to publish */ +#define TXTCR_CMD_OPEN_LOCALITY2 0x0390 /* TBD: need to publish */ +#define TXTCR_CMD_CLOSE_LOCALITY2 0x0398 /* TBD: need to publish */ +#define TXTCR_CMD_SECRETS 0x08e0 +#define TXTCR_CMD_NO_SECRETS 0x08e8 +#define TXTCR_E2STS 0x08f0 + +/* + * format of ERRORCODE register + */ +typedef union { + uint64_t _raw; + struct { + uint64_t type : 16; /* external-specific error code */ + uint64_t reserved : 14; + uint64_t external : 1; /* 0=from proc, 1=from external SW */ + uint64_t valid : 1; /* 1=valid */ + }; +} txt_errorcode_t; + +/* + * format of ESTS register + */ +typedef union { + uint64_t _raw; + struct { + uint64_t reserved1 : 1; + uint64_t txt_rogue_sts : 1; + uint64_t bm_write_attack : 1; + uint64_t bm_read_attack : 1; + uint64_t fsb_write_attack : 1; + uint64_t fsb_read_attack : 1; + uint64_t txt_wake_error_sts : 1; + uint64_t reserved2 : 1; + }; +} txt_ests_t; + +/* + * format of E2STS register + */ +typedef union { + uint64_t _raw; + struct { + uint64_t slp_entry_error_sts : 1; + uint64_t secrets_sts : 1; + uint64_t block_mem_sts : 1; + uint64_t reset_sts : 1; + }; +} txt_e2sts_t; + +/* + * format of STS register + */ +typedef union { + uint64_t _raw; + struct { + uint64_t senter_done_sts : 1; + uint64_t sexit_done_sts : 1; + uint64_t reserved1 : 2; + uint64_t mem_unlock_sts : 1; + uint64_t nodma_en_sts : 1; + uint64_t mem_config_lock_sts : 1; + uint64_t private_open_sts : 1; + uint64_t reserved2 : 1; + uint64_t nodma_cache_sts : 1; + uint64_t nodma_table_prot_sts : 1; + uint64_t mem_config_ok_sts : 1; + }; +} txt_sts_t; + +/* + * format of DIDVID register + */ +typedef union { + uint64_t _raw; + struct { + uint16_t vendor_id; + uint16_t device_id; + uint16_t revision_id; + uint16_t reserved; + }; +} txt_didvid_t; + +/* + * RLP JOIN structure for GETSEC[WAKEUP] and MLE_JOIN register + */ +typedef struct { + uint32_t gdt_limit; + uint32_t gdt_base; + uint32_t seg_sel; /* cs (ds, es, ss are seg_sel+8) */ + uint32_t entry_point; /* phys addr */ +} mle_join_t; + + +/* + * fns to read/write TXT config regs + */ + +static inline uint64_t read_config_reg(uint32_t config_regs_base, uint32_t reg) +{ + /* these are MMIO so make sure compiler doesn't optimize */ + return *(volatile uint64_t *)(unsigned long)(config_regs_base + reg); +} + +static inline void write_config_reg(uint32_t config_regs_base, uint32_t reg, + uint64_t val) +{ + /* these are MMIO so make sure compiler doesn't optimize */ + *(volatile uint64_t *)(unsigned long)(config_regs_base + reg) = val; +} + +static inline uint64_t read_pub_config_reg(uint32_t reg) +{ + return read_config_reg(TXT_PUB_CONFIG_REGS_BASE, reg); +} + +static inline void write_pub_config_reg(uint32_t reg, uint64_t val) +{ + write_config_reg(TXT_PUB_CONFIG_REGS_BASE, reg, val); +} + +static inline uint64_t read_priv_config_reg(uint32_t reg) +{ + return read_config_reg(TXT_PRIV_CONFIG_REGS_BASE, reg); +} + +static inline void write_priv_config_reg(uint32_t reg, uint64_t val) +{ + write_config_reg(TXT_PRIV_CONFIG_REGS_BASE, reg, val); +} + +#endif /* __TXT_CONFIG_REGS_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/txt/errorcode.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/txt/errorcode.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,91 @@ +/* + * errorcode.h: Intel(r) TXT error definitions for ERRORCODE config register + * + * Copyright (c) 2003-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Intel Corporation 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + */ + +#ifndef __TXT_ERRORCODE_H__ +#define __TXT_ERRORCODE_H__ + +/* + * error values for processor error codes (ERRORCODE.external = 0) + */ +#define TXT_ERR_PROC_LEGACY_SHUTDOWN 0 +#define TXT_ERR_PROC_INVALID_ACM_MEM_TYPE 5 +#define TXT_ERR_PROC_UNSUPPORTED_ACM 6 +#define TXT_ERR_PROC_AUTH_FAIL 7 +#define TXT_ERR_PROC_INVALID_ACM_FORMAT 8 +#define TXT_ERR_PROC_UNEXPECTED_HITM 9 +#define TXT_ERR_PROC_INVALID_EVENT 10 +#define TXT_ERR_PROC_INVALID_JOIN_FORMAT 11 +#define TXT_ERR_PROC_UNRECOVERABLE_MCE 12 +#define TXT_ERR_PROC_VMX_ABORT 13 +#define TXT_ERR_PROC_ACM_CORRUPT 14 +#define TXT_ERR_PROC_INVALID_VIDB_RATIO 15 + +/* + * for SW errors (ERRORCODE.external = 1) + */ +typedef union { + uint16_t _raw; + struct { + uint16_t err : 15; /* specific to src */ + uint16_t src : 1; /* 0=ACM, 1=other */ + }; +} txt_errorcode_sw_t; + +/* + * ACM errors (txt_errorcode_sw_t.src=0), format of err field + */ +typedef union { + uint16_t _raw; + struct { + uint16_t type : 4; /* 0000=BIOS ACM, 0001=SINIT, */ + /* 0010-1111=reserved */ + uint16_t progress : 6; + uint16_t error : 4; + uint16_t reserved : 1; + }; +} acmod_error_t; + +#endif /* __TXT_ERRORCODE_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/txt/heap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/txt/heap.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,240 @@ +/* + * heap.h: Intel(r) TXT heap definitions + * + * Copyright (c) 2003-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Intel Corporation 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + */ + +#ifndef __TXT_HEAP_H__ +#define __TXT_HEAP_H__ + +#include +#include +#include + +/* + * data-passing structures contained in TXT heap: + * - BIOS to OS/loader + * - OS/loader to MLE + * - OS/loader to SINIT + * - SINIT to MLE + */ + +/* + * BIOS to OS/loader structure + * - not used by current Xen + */ +typedef struct { + uint32_t version; /* SDP3/TEP=0x00, WB=0x02 */ + uint32_t bios_sinit_size; + union { + struct { + uint64_t lcp_pd_base; + uint64_t lcp_pd_size; + uint32_t num_logical_procs; + } v2; + }; +} bios_os_data_t; + +/* + * OS/loader to MLE structure v1 + * - private to Xen (so can be any format we need) + */ +typedef struct { + uint32_t version; /* will be 0x01 */ + mtrr_state_t saved_mtrr_state; /* saved prior to changes for SINIT */ + multiboot_info_t *mbi; /* needs to be restored to ebx */ +} os_mle_data_t; + +/* + * OS/loader to SINIT structure v1 + */ +typedef struct { + uint32_t version; /* SDP3/TEP=0x01, WB=0x03 */ + uint32_t reserved; + uint64_t mle_ptab; + uint64_t mle_size; + uint64_t mle_hdr_base; + union { + struct { + uint64_t vtd_pmr_lo_base; + uint64_t vtd_pmr_lo_size; + uint64_t vtd_pmr_hi_base; + uint64_t vtd_pmr_hi_size; + uint64_t lcp_po_base; + uint64_t lcp_po_size; + } v3; + }; +} os_sinit_data_t; + +/* + * SINIT to MLE structure + */ +#define MDR_MEMTYPE_GOOD 0x00 +#define MDR_MEMTYPE_SMM_OVERLAY 0x01 +#define MDR_MEMTYPE_SMM_NONOVERLAY 0x02 +#define MDR_MEMTYPE_PCIE_CONFIG_SPACE 0x03 +#define MDR_MEMTYPE_PROTECTED 0x04 + +typedef struct __attribute__ ((packed)) { + uint64_t base; + uint64_t length; + uint8_t mem_type; + uint8_t reserved[7]; +} sinit_mdr_t; + +#define SHA1_SIZE 20 +typedef uint8_t sha1_hash_t[SHA1_SIZE]; + +typedef struct { + uint32_t version; /* SDP3/TEP=0x01, WB=0x03/0x05 */ + union { + struct { + uint32_t num_mdrs; + sinit_mdr_t mdrs[]; + } v1; + struct { + sha1_hash_t bios_acm_id; + uint32_t edx_senter_flags; + uint64_t mseg_valid; + sha1_hash_t sinit_hash; + sha1_hash_t mle_hash; + sha1_hash_t stm_hash; + sha1_hash_t lcp_policy_hash; + uint32_t lcp_policy_control; + uint64_t reserved; + uint32_t num_mdrs; + uint32_t mdrs_off; + uint32_t num_vtd_dmars; + uint32_t vtd_dmars_off; + } v5; + }; +} sinit_mle_data_t; + + +/* + * TXT heap data format and field accessor fns + */ + +/* + * offset length field + * ------ ------ ----- + * 0 8 bios_os_data_size + * 8 bios_os_data_size - 8 bios_os_data + * + * bios_os_data_size 8 os_mle_data_size + * bios_os_data_size + os_mle_data_size - 8 os_mle_data + * 8 + * + * bios_os_data_size + 8 os_sinit_data_size + * os_mle_data_size + * bios_os_data_size + os_sinit_data_size - 8 os_sinit_data + * os_mle_data_size + + * 8 + * + * bios_os_data_size + 8 sinit_mle_data_size + * os_mle_data_size + + * os_sinit_data_size + * bios_os_data_size + sinit_mle_data_size - 8 sinit_mle_data + * os_mle_data_size + + * os_sinit_data_size + + * 8 + */ + +typedef void txt_heap_t; + +/* this is a common use with annoying casting, so make it an inline */ +static inline txt_heap_t *get_txt_heap(void) +{ + return (txt_heap_t *)(unsigned long)read_pub_config_reg(TXTCR_HEAP_BASE); +} + +static inline uint64_t get_bios_os_data_size(txt_heap_t *heap) +{ + return *(uint64_t *)heap; +} + +static inline bios_os_data_t *get_bios_os_data_start(txt_heap_t *heap) +{ + return (bios_os_data_t *)((char*)heap + sizeof(uint64_t)); +} + +static inline uint64_t get_os_mle_data_size(txt_heap_t *heap) +{ + return *(uint64_t *)(heap + get_bios_os_data_size(heap)); +} + +static inline os_mle_data_t *get_os_mle_data_start(txt_heap_t *heap) +{ + return (os_mle_data_t *)(heap + get_bios_os_data_size(heap) + + sizeof(uint64_t)); +} + +static inline uint64_t get_os_sinit_data_size(txt_heap_t *heap) +{ + return *(uint64_t *)(heap + get_bios_os_data_size(heap) + + get_os_mle_data_size(heap)); +} + +static inline os_sinit_data_t *get_os_sinit_data_start(txt_heap_t *heap) +{ + return (os_sinit_data_t *)(heap + get_bios_os_data_size(heap) + + get_os_mle_data_size(heap) + + sizeof(uint64_t)); +} + +static inline uint64_t get_sinit_mle_data_size(txt_heap_t *heap) +{ + return *(uint64_t *)(heap + get_bios_os_data_size(heap) + + get_os_mle_data_size(heap) + + get_os_sinit_data_size(heap)); +} + +static inline sinit_mle_data_t *get_sinit_mle_data_start(txt_heap_t *heap) +{ + return (sinit_mle_data_t *)(heap + get_bios_os_data_size(heap) + + get_os_mle_data_size(heap) + + get_os_sinit_data_size(heap) + + sizeof(uint64_t)); +} + +#endif /* __TXT_HEAP_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/txt/lcp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/txt/lcp.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,118 @@ +/* + * Copyright 2001 - 2007 Intel Corporation. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + +#ifndef __LCP_H__ +#define __LCP_H__ + +/*--------- LCP Policy Algorithm ------------*/ +#define LCP_POLHALG_SHA1 0 + +/*--------- LCP Policy Type ------------*/ +#define LCP_POLTYPE_HASHONLY 0 +#define LCP_POLTYPE_UNSIGNED 1 +#define LCP_POLTYPE_SIGNED 2 +#define LCP_POLTYPE_ANY 3 +#define LCP_POLTYPE_FORCEOWNERPOLICY 4 + +/*--------- LCP Policy List type ------------*/ +#define LCP_POLDESC_MLE_UNSIGNED 0x0001 +#define LCP_POLDESC_PCONF_UNSIGNED 0x0002 + +/*--------- LCP UUID ------------*/ +#define LCP_POLICY_DATA_UUID {0xab0d1925, 0xeee7, 0x48eb, 0xa9fc, \ + {0xb, 0xac, 0x5a, 0x26, 0x2d, 0xe}} + +/*--------- LCP reserved Indices------------*/ +#define INDEX_LCP_DEF 0x50000001 +#define INDEX_LCP_OWN 0x40000001 +#define INDEX_AUX 0x50000002 + +/*------ Default Permission, size and locality for reserved Indices--------*/ +#define PERMISSION_DEF 0x00002000 +#define PERMISSION_OWN 0x00000002 +#define PERMISSION_AUX 0x0 + +#define DATASIZE_POL 34 +#define DATASIZE_AUX 64 + +#define LOCALITY_DEFAULT 0x1f +#define WR_LOCALITY_AUX 0x18 + + +/*--------- Other data structures of LCP Policy ------------*/ +typedef union { + uint8_t sha1[20]; + uint8_t sha256[32]; +} lcp_hash_t; + +typedef struct { + uint8_t version; + uint8_t hash_alg; /* one of LCP_POLHALG_* */ + uint8_t policy_type; /* one of LCP_POLTYPE_* */ + uint8_t sinit_revocation_counter; + uint32_t policy_control; + uint16_t reserved[3]; + lcp_hash_t policy_hash; +} __attribute__((packed)) lcp_policy_t; + +typedef struct { + uint32_t data1; + uint16_t data2; + uint16_t data3; + uint16_t data4; + uint8_t data5[6]; +} __attribute__((packed)) uuid_t; + +typedef struct { + uint8_t version; + uint8_t count; + union{ + lcp_hash_t *hashes; + TPM_PCR_INFO_SHORT *pcrs; + }; +} __attribute__((packed)) lcp_unsigned_list_t; + +typedef struct { + uint16_t type; /* One of LCP_POLDESC_* */ + lcp_unsigned_list_t unsigned_list; +} __attribute__((packed)) lcp_policy_list_t; + +typedef struct { + uint8_t version; + uint8_t policy_data_listsize; + lcp_policy_list_t policy_data_list[]; +} __attribute__((packed)) lcp_unsigned_policy_data_t; + +typedef struct { + uuid_t uuid; + lcp_unsigned_policy_data_t unsigned_data; +} __attribute__((packed)) lcp_policy_data_t; + +#endif diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/txt/mtrrs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/txt/mtrrs.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,149 @@ +/* + * mtrrs.c: Intel(r) TXT MTRR-related definitions + * + * Copyright (c) 2003-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Intel Corporation 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + */ + +#ifndef __TXT_MTRRS_H__ +#define __TXT_MTRRS_H__ + +#include +#include + +enum fix_mtrr_t { + MTRR_FIX64K_00000 = 0x250, + MTRR_FIX16K_80000 = 0x258, + MTRR_FIX16K_A0000 = 0x259, + MTRR_FIX4K_C0000 = 0x268, + MTRR_FIX4K_C8000 = 0x269, + MTRR_FIX4K_D0000 = 0x26A, + MTRR_FIX4K_D8000 = 0x26B, + MTRR_FIX4K_E0000 = 0x26C, + MTRR_FIX4K_E8000 = 0x26D, + MTRR_FIX4K_F0000 = 0x26E, + MTRR_FIX4K_F8000 = 0x26F +}; + +typedef union { + uint64_t raw; + uint8_t type[8]; +} mtrr_fix_types_t; + +enum var_mtrr_t { + MTRR_PHYS_BASE0_MSR = 0x200, + MTRR_PHYS_MASK0_MSR = 0x201, + MTRR_PHYS_BASE1_MSR = 0x202, + MTRR_PHYS_MASK1_MSR = 0x203, + MTRR_PHYS_BASE2_MSR = 0x204, + MTRR_PHYS_MASK2_MSR = 0x205, + MTRR_PHYS_BASE3_MSR = 0x206, + MTRR_PHYS_MASK3_MSR = 0x207, + MTRR_PHYS_BASE4_MSR = 0x208, + MTRR_PHYS_MASK4_MSR = 0x209, + MTRR_PHYS_BASE5_MSR = 0x20A, + MTRR_PHYS_MASK5_MSR = 0x20B, + MTRR_PHYS_BASE6_MSR = 0x20C, + MTRR_PHYS_MASK6_MSR = 0x20D, + MTRR_PHYS_BASE7_MSR = 0x20E, + MTRR_PHYS_MASK7_MSR = 0x20F +}; + +typedef union { + uint64_t raw; + struct { + uint64_t vcnt : 8; /* num variable MTRR pairs */ + uint64_t fix : 1; /* fixed range MTRRs are supported */ + uint64_t reserved1 : 1; + uint64_t wc : 1; /* write-combining mem type supported */ + uint64_t reserved2 : 53; + }; +} mtrr_cap_t; + +typedef union { + uint64_t raw; + struct { + uint64_t type : 8; + uint64_t reserved1 : 2; + uint64_t fe : 1; /* fixed MTRR enable */ + uint64_t e : 1; /* (all) MTRR enable */ + uint64_t reserved2 : 52; + }; +} mtrr_def_type_t; + +typedef union { + uint64_t raw; + struct { + uint64_t type : 8; + uint64_t reserved1 : 4; + uint64_t base : 24; + uint64_t reserved2 : 28; + }; +} mtrr_physbase_t; + +typedef union { + uint64_t raw; + struct { + uint64_t reserved1 : 11; + uint64_t v : 1; /* valid */ + uint64_t mask : 24; + uint64_t reserved2 : 28; + }; +} mtrr_physmask_t; + +/* current procs only have 8, so this should hold us for a while */ +#define MAX_VARIABLE_MTRRS 16 + +typedef struct { + mtrr_def_type_t mtrr_def_type; + int num_var_mtrrs; + mtrr_physbase_t mtrr_physbases[MAX_VARIABLE_MTRRS]; + mtrr_physmask_t mtrr_physmasks[MAX_VARIABLE_MTRRS]; +} mtrr_state_t; + +extern void save_mtrrs(mtrr_state_t *saved_state); +extern void set_all_mtrrs(bool enable); +extern bool set_mem_type(void *base, uint32_t size, uint32_t mem_type); +extern void restore_mtrrs(mtrr_state_t *saved_state); +extern bool validate_mtrrs(const mtrr_state_t *saved_state); + +#endif /*__TXT_MTRRS_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/txt/smx.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/txt/smx.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,138 @@ +/* + * smx.h: Intel(r) TXT SMX architecture-related definitions + * + * Copyright (c) 2003-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Intel Corporation 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + */ + +#ifndef __TXT_SMX_H__ +#define __TXT_SMX_H__ + +/* + * GETSEC[] instructions + */ + +/* GETSEC instruction opcode */ +#define IA32_GETSEC_OPCODE ".byte 0x0f,0x37" + +/* GETSEC leaf function codes */ +#define IA32_GETSEC_CAPABILITIES 0 +#define IA32_GETSEC_SENTER 4 +#define IA32_GETSEC_SEXIT 5 +#define IA32_GETSEC_PARAMETERS 6 +#define IA32_GETSEC_SMCTRL 7 +#define IA32_GETSEC_WAKEUP 8 + +/* + * GETSEC[] leaf functions + */ + +typedef union { + uint32_t _raw; + struct { + uint32_t chipset_present : 1; + uint32_t undefined1 : 1; + uint32_t enteraccs : 1; + uint32_t exitac : 1; + uint32_t senter : 1; + uint32_t sexit : 1; + uint32_t parameters : 1; + uint32_t smctrl : 1; + uint32_t wakeup : 1; + uint32_t undefined9 : 22; + uint32_t extended_leafs : 1; + }; +} capabilities_t; + +static inline capabilities_t __getsec_capabilities(uint32_t index) +{ + uint32_t cap; + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n" + : "=a"(cap) + : "a"(IA32_GETSEC_CAPABILITIES), "b"(index)); + return (capabilities_t)cap; +} + +static inline void __getsec_senter(uint32_t sinit_base, uint32_t sinit_size) +{ + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n" + : + : "a"(IA32_GETSEC_SENTER), + "b"(sinit_base), + "c"(sinit_size), + "d"(0x0)); +} + +static inline void __getsec_sexit(void) +{ + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n" + : : "a"(IA32_GETSEC_SEXIT)); +} + +static inline void __getsec_wakeup(void) +{ + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n" + : : "a"(IA32_GETSEC_WAKEUP)); +} + +static inline void __getsec_smctrl(void) +{ + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n" + : : "a"(IA32_GETSEC_SMCTRL), "b"(0x0)); +} + +static inline void __getsec_parameters(uint32_t index, int* param_type, + uint32_t* peax, uint32_t* pebx, + uint32_t* pecx) +{ + uint32_t eax=0, ebx=0, ecx=0; + __asm__ __volatile__ (IA32_GETSEC_OPCODE "\n" + : "=a"(eax), "=b"(ebx), "=c"(ecx) + : "a"(IA32_GETSEC_PARAMETERS), "b"(index)); + + if ( param_type != NULL ) *param_type = eax & 0x1f; + if ( peax != NULL ) *peax = eax; + if ( pebx != NULL ) *pebx = ebx; + if ( pecx != NULL ) *pecx = ecx; +} + + +#endif /* __TXT_SMX_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/txt/txt.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/txt/txt.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,64 @@ +/* + * txt.h: Intel(r) TXT support functions + * + * Copyright (c) 2003-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Intel Corporation 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + */ + +#ifndef __TXT_TXT_H__ +#define __TXT_TXT_H__ + +#include + +extern bool txt_is_launched(void); +extern bool txt_get_error(void); +extern bool txt_verify_platform(void); +extern bool txt_prepare_cpu(void); +extern bool txt_prepare_platform(void); +extern bool txt_launch_environment(multiboot_info_t *mbi); +extern bool txt_post_launch(void); +extern bool txt_protect_mem_regions(void); +extern bool txt_post_launch_verify_platform(void); + + +#endif /* __TXT_TXT_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ + diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/txt/txt_defs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/txt/txt_defs.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,66 @@ +/* + * txt_defs.h: Intel(r) TXT general definitions + * + * Copyright (c) 2003-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Intel Corporation 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + */ + +#ifndef __TXT_TXT_DEFS_H__ +#define __TXT_TXT_DEFS_H__ + +/* + * MLE header structure + * describes an MLE for SINIT and OS/loader SW + */ +typedef struct { + uint32_t guid[4]; + uint32_t length; + uint32_t version; + uint32_t entry_point; + uint32_t first_valid_page; + uint32_t mle_start_off; + uint32_t mle_end_off; +} mle_hdr_t; + +#define MLE_HDR_GUID {0x9082ac5a, 0x74a7476f, 0xa2555c0f, 0x42b651cb} + +#endif /* __TXT_TXT_DEFS_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/txt/verify.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/txt/verify.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,55 @@ +/* + * verify.h: support functions for platform Intel(r) TXT verification + * + * Copyright (c) 2003-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Intel Corporation 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + */ + +#ifndef __TXT_VERIFY_H__ +#define __TXT_VERIFY_H__ + +extern bool verify_txt_heap(txt_heap_t *txt_heap, bool bios_os_data_only); +extern void print_os_sinit_data(os_sinit_data_t *os_sinit_data); +extern void set_vtd_pmrs(os_sinit_data_t *os_sinit_data, uint64_t max_ram); +extern bool verify_e820_map(sinit_mdr_t* mdrs_base, uint32_t num_mdrs); + +#endif /* __TXT_VERIFY_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/txt/vmcs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/txt/vmcs.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,327 @@ +#ifndef __TXT_VMCS_H__ +#define __TXT_VMCS_H__ + +struct vmcs_struct { + uint32_t vmcs_revision_id; + unsigned char data[0]; /* vmcs size is read from MSR */ +}; + +union vmcs_arbytes { + struct arbyte_fields { + unsigned int seg_type : 4, + s : 1, + dpl : 2, + p : 1, + reserved0 : 4, + avl : 1, + reserved1 : 1, + default_ops_size: 1, + g : 1, + null_bit : 1, + reserved2 : 15; + } fields; + unsigned int bytes; +}; + +#define CPU_BASED_HLT_EXITING 0x00000080 +#define CPU_BASED_INVDPG_EXITING 0x00000200 +#define CPU_BASED_MWAIT_EXITING 0x00000400 + +#define PIN_BASED_EXT_INTR_MASK 0x00000001 +#define PIN_BASED_NMI_EXITING 0x00000008 + +#define VM_EXIT_IA32E_MODE 0x00000200 +#define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000 + +#define VM_ENTRY_IA32E_MODE 0x00000200 +#define VM_ENTRY_SMM 0x00000400 +#define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800 + + +/* VMCS Encordings */ +enum vmcs_field { + GUEST_ES_SELECTOR = 0x00000800, + GUEST_CS_SELECTOR = 0x00000802, + GUEST_SS_SELECTOR = 0x00000804, + GUEST_DS_SELECTOR = 0x00000806, + GUEST_FS_SELECTOR = 0x00000808, + GUEST_GS_SELECTOR = 0x0000080a, + GUEST_LDTR_SELECTOR = 0x0000080c, + GUEST_TR_SELECTOR = 0x0000080e, + HOST_ES_SELECTOR = 0x00000c00, + HOST_CS_SELECTOR = 0x00000c02, + HOST_SS_SELECTOR = 0x00000c04, + HOST_DS_SELECTOR = 0x00000c06, + HOST_FS_SELECTOR = 0x00000c08, + HOST_GS_SELECTOR = 0x00000c0a, + HOST_TR_SELECTOR = 0x00000c0c, + IO_BITMAP_A = 0x00002000, + IO_BITMAP_A_HIGH = 0x00002001, + IO_BITMAP_B = 0x00002002, + IO_BITMAP_B_HIGH = 0x00002003, + VM_EXIT_MSR_STORE_ADDR = 0x00002006, + VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007, + VM_EXIT_MSR_LOAD_ADDR = 0x00002008, + VM_EXIT_MSR_LOAD_ADDR_HIGH = 0x00002009, + VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a, + VM_ENTRY_MSR_LOAD_ADDR_HIGH = 0x0000200b, + TSC_OFFSET = 0x00002010, + TSC_OFFSET_HIGH = 0x00002011, + VIRTUAL_APIC_PAGE_ADDR = 0x00002012, + VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013, + VMCS_LINK_POINTER = 0x00002800, + VMCS_LINK_POINTER_HIGH = 0x00002801, + GUEST_IA32_DEBUGCTL = 0x00002802, + GUEST_IA32_DEBUGCTL_HIGH = 0x00002803, + PIN_BASED_VM_EXEC_CONTROL = 0x00004000, + CPU_BASED_VM_EXEC_CONTROL = 0x00004002, + EXCEPTION_BITMAP = 0x00004004, + PAGE_FAULT_ERROR_CODE_MASK = 0x00004006, + PAGE_FAULT_ERROR_CODE_MATCH = 0x00004008, + CR3_TARGET_COUNT = 0x0000400a, + VM_EXIT_CONTROLS = 0x0000400c, + VM_EXIT_MSR_STORE_COUNT = 0x0000400e, + VM_EXIT_MSR_LOAD_COUNT = 0x00004010, + VM_ENTRY_CONTROLS = 0x00004012, + VM_ENTRY_MSR_LOAD_COUNT = 0x00004014, + VM_ENTRY_INTR_INFO_FIELD = 0x00004016, + VM_ENTRY_EXCEPTION_ERROR_CODE = 0x00004018, + VM_ENTRY_INSTRUCTION_LEN = 0x0000401a, + TPR_THRESHOLD = 0x0000401c, + SECONDARY_VM_EXEC_CONTROL = 0x0000401e, + VM_INSTRUCTION_ERROR = 0x00004400, + VM_EXIT_REASON = 0x00004402, + VM_EXIT_INTR_INFO = 0x00004404, + VM_EXIT_INTR_ERROR_CODE = 0x00004406, + IDT_VECTORING_INFO_FIELD = 0x00004408, + IDT_VECTORING_ERROR_CODE = 0x0000440a, + VM_EXIT_INSTRUCTION_LEN = 0x0000440c, + VMX_INSTRUCTION_INFO = 0x0000440e, + GUEST_ES_LIMIT = 0x00004800, + GUEST_CS_LIMIT = 0x00004802, + GUEST_SS_LIMIT = 0x00004804, + GUEST_DS_LIMIT = 0x00004806, + GUEST_FS_LIMIT = 0x00004808, + GUEST_GS_LIMIT = 0x0000480a, + GUEST_LDTR_LIMIT = 0x0000480c, + GUEST_TR_LIMIT = 0x0000480e, + GUEST_GDTR_LIMIT = 0x00004810, + GUEST_IDTR_LIMIT = 0x00004812, + GUEST_ES_AR_BYTES = 0x00004814, + GUEST_CS_AR_BYTES = 0x00004816, + GUEST_SS_AR_BYTES = 0x00004818, + GUEST_DS_AR_BYTES = 0x0000481a, + GUEST_FS_AR_BYTES = 0x0000481c, + GUEST_GS_AR_BYTES = 0x0000481e, + GUEST_LDTR_AR_BYTES = 0x00004820, + GUEST_TR_AR_BYTES = 0x00004822, + GUEST_INTERRUPTIBILITY_INFO = 0x00004824, + GUEST_ACTIVITY_STATE = 0x00004826, + GUEST_SYSENTER_CS = 0x0000482A, + HOST_IA32_SYSENTER_CS = 0x00004c00, + CR0_GUEST_HOST_MASK = 0x00006000, + CR4_GUEST_HOST_MASK = 0x00006002, + CR0_READ_SHADOW = 0x00006004, + CR4_READ_SHADOW = 0x00006006, + CR3_TARGET_VALUE0 = 0x00006008, + CR3_TARGET_VALUE1 = 0x0000600a, + CR3_TARGET_VALUE2 = 0x0000600c, + CR3_TARGET_VALUE3 = 0x0000600e, + EXIT_QUALIFICATION = 0x00006400, + GUEST_LINEAR_ADDRESS = 0x0000640a, + GUEST_CR0 = 0x00006800, + GUEST_CR3 = 0x00006802, + GUEST_CR4 = 0x00006804, + GUEST_ES_BASE = 0x00006806, + GUEST_CS_BASE = 0x00006808, + GUEST_SS_BASE = 0x0000680a, + GUEST_DS_BASE = 0x0000680c, + GUEST_FS_BASE = 0x0000680e, + GUEST_GS_BASE = 0x00006810, + GUEST_LDTR_BASE = 0x00006812, + GUEST_TR_BASE = 0x00006814, + GUEST_GDTR_BASE = 0x00006816, + GUEST_IDTR_BASE = 0x00006818, + GUEST_DR7 = 0x0000681a, + GUEST_RSP = 0x0000681c, + GUEST_RIP = 0x0000681e, + GUEST_RFLAGS = 0x00006820, + GUEST_PENDING_DBG_EXCEPTIONS = 0x00006822, + GUEST_SYSENTER_ESP = 0x00006824, + GUEST_SYSENTER_EIP = 0x00006826, + HOST_CR0 = 0x00006c00, + HOST_CR3 = 0x00006c02, + HOST_CR4 = 0x00006c04, + HOST_FS_BASE = 0x00006c06, + HOST_GS_BASE = 0x00006c08, + HOST_TR_BASE = 0x00006c0a, + HOST_GDTR_BASE = 0x00006c0c, + HOST_IDTR_BASE = 0x00006c0e, + HOST_IA32_SYSENTER_ESP = 0x00006c10, + HOST_IA32_SYSENTER_EIP = 0x00006c12, + HOST_RSP = 0x00006c14, + HOST_RIP = 0x00006c16, +}; + +/* VMX stuff */ +enum ap_init_state { + AP_WAIT_INIT = 0, + AP_WAIT_SIPI1 = 1, + AP_WAIT_SIPI2 = 2, + AP_WAIT_DONE = 3, +}; + +enum guest_activity_state { + GUEST_STATE_ACTIVE = 0, + GUEST_STATE_HALT = 1, + GUEST_STATE_SHUTDOWN = 2, + GUEST_STATE_WAIT_SIPI = 3, +}; + +#define VMCALL_OPCODE ".byte 0x0f,0x01,0xc1\n" +#define VMCLEAR_OPCODE ".byte 0x66,0x0f,0xc7\n" /* reg/opcode: /6 */ +#define VMLAUNCH_OPCODE ".byte 0x0f,0x01,0xc2\n" +#define VMPTRLD_OPCODE ".byte 0x0f,0xc7\n" /* reg/opcode: /6 */ +#define VMPTRST_OPCODE ".byte 0x0f,0xc7\n" /* reg/opcode: /7 */ +#define VMREAD_OPCODE ".byte 0x0f,0x78\n" +#define VMRESUME_OPCODE ".byte 0x0f,0x01,0xc3\n" +#define VMWRITE_OPCODE ".byte 0x0f,0x79\n" +#define VMXOFF_OPCODE ".byte 0x0f,0x01,0xc4\n" +#define VMXON_OPCODE ".byte 0xf3,0x0f,0xc7\n" + +#define MODRM_EAX_06 ".byte 0x30\n" /* [EAX], with reg/opcode: /6 */ +#define MODRM_EAX_07 ".byte 0x38\n" /* [EAX], with reg/opcode: /7 */ +#define MODRM_EAX_ECX ".byte 0xc1\n" /* [EAX], [ECX] */ + +/* + * Exit Reasons + */ +#define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000 + +#define EXIT_REASON_INIT 3 +#define EXIT_REASON_SIPI 4 + +#define EXIT_REASON_INVALID_GUEST_STATE 33 +#define EXIT_REASON_MSR_LOADING 34 + +#define EXIT_REASON_MACHINE_CHECK 41 + +static inline void __vmptrld(uint64_t addr) +{ + __asm__ __volatile__ ( VMPTRLD_OPCODE + MODRM_EAX_06 + /* CF==1 or ZF==1 --> crash (ud2) */ + "ja 1f ; ud2 ; 1:\n" + : + : "a" (&addr) + : "memory"); +} + +static inline void __vmptrst(uint64_t addr) +{ + __asm__ __volatile__ ( VMPTRST_OPCODE + MODRM_EAX_07 + : + : "a" (&addr) + : "memory"); +} + +static inline void __vmpclear(uint64_t addr) +{ + __asm__ __volatile__ ( VMCLEAR_OPCODE + MODRM_EAX_06 + /* CF==1 or ZF==1 --> crash (ud2) */ + "ja 1f ; ud2 ; 1:\n" + : + : "a" (&addr) + : "memory"); +} + +static inline unsigned long __vmread(unsigned long field) +{ + unsigned long ecx; + + __asm__ __volatile__ ( VMREAD_OPCODE + MODRM_EAX_ECX + /* CF==1 or ZF==1 --> crash (ud2) */ + "ja 1f ; ud2 ; 1:\n" + : "=c" (ecx) + : "a" (field) + : "memory"); + + return ecx; +} + +static inline void __vmwrite(unsigned long field, unsigned long value) +{ + __asm__ __volatile__ ( VMWRITE_OPCODE + MODRM_EAX_ECX + /* CF==1 or ZF==1 --> crash (ud2) */ + "ja 1f ; ud2 ; 1:\n" + : + : "a" (field) , "c" (value) + : "memory"); +} + +static inline unsigned long __vmread_safe(unsigned long field, int *error) +{ + unsigned long ecx; + + __asm__ __volatile__ ( VMREAD_OPCODE + MODRM_EAX_ECX + /* CF==1 or ZF==1 --> rc = -1 */ + "setna %b0 ; neg %0" + : "=q" (*error), "=c" (ecx) + : "0" (0), "a" (field) + : "memory"); + + return ecx; +} + +static inline void __vmlaunch (void) +{ + __asm__ __volatile__ ( VMLAUNCH_OPCODE + ::: "memory"); +} + +static inline void __vmresume (void) +{ + __asm__ __volatile__ ( VMRESUME_OPCODE + ::: "memory"); +} + +static inline void __vmxoff (void) +{ + __asm__ __volatile__ ( VMXOFF_OPCODE + ::: "memory"); +} + +static inline int __vmxon (uint64_t addr) +{ + int rc; + + __asm__ __volatile__ ( VMXON_OPCODE + MODRM_EAX_06 + /* CF==1 or ZF==1 --> rc = -1 */ + "setna %b0 ; neg %0" + : "=q" (rc) + : "0" (0), "a" (&addr) + : "memory"); + + return rc; +} + +extern void handle_init_sipi_sipi(void); + +#endif /* __TXT_VMCS_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/types.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,54 @@ +#ifndef __TYPES_H__ +#define __TYPES_H__ + +#include +#include + +#define BITS_TO_LONGS(bits) \ + (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG) +#define DECLARE_BITMAP(name,bits) \ + unsigned long name[BITS_TO_LONGS(bits)] + +#ifndef NULL +#define NULL ((void*)0) +#endif + +#define INT_MAX ((int)(~0U>>1)) +#define INT_MIN (-INT_MAX - 1) +#define UINT_MAX (~0U) +#define LONG_MAX ((long)(~0UL>>1)) +#define LONG_MIN (-LONG_MAX - 1) +#define ULONG_MAX (~0UL) + +#ifndef __ASSEMBLY__ + +/* bsd */ +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; + +/* sysv */ +typedef unsigned char unchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; + +typedef __u8 uint8_t; +typedef __u8 u_int8_t; +typedef __s8 int8_t; + +typedef __u16 uint16_t; +typedef __u16 u_int16_t; +typedef __s16 int16_t; + +typedef __u32 uint32_t; +typedef __u32 u_int32_t; +typedef __s32 int32_t; + +typedef __u64 uint64_t; +typedef __u64 u_int64_t; +typedef __s64 int64_t; +#endif /* __ASSEMBLY__ */ + +#endif /* __TYPES_H__ */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/uuid.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/uuid.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,74 @@ +/* + * uuid.h: support functions for UUIDs + * + * Copyright (c) 2006-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Intel Corporation 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + */ + +#ifndef __UUID_H__ +#define __UUID_H__ + +typedef struct __attribute__ ((__packed__)) { + uint32_t data1; + uint16_t data2; + uint16_t data3; + uint16_t data4; + uint8_t data5[6]; +} uuid_t; + +static inline bool are_uuids_equal(const uuid_t *uuid1, const uuid_t *uuid2) +{ + return (memcmp(uuid1, uuid2, sizeof(*uuid1)) == 0); +} + +static inline void print_uuid(const uuid_t *uuid) +{ + printk("{0x%08x, 0x%04x, 0x%04x, 0x%04x,\n" + "\t\t{0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x}}", + uuid->data1, (uint32_t)uuid->data2, (uint32_t)uuid->data3, + (uint32_t)uuid->data4, (uint32_t)uuid->data5[0], + (uint32_t)uuid->data5[1], (uint32_t)uuid->data5[2], + (uint32_t)uuid->data5[3], (uint32_t)uuid->data5[4], + (uint32_t)uuid->data5[5]); +} + +#endif /* __UUID_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/include/x86_types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/include/x86_types.h Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,49 @@ +#ifndef __X86_TYPES_H__ +#define __X86_TYPES_H__ + +#ifndef __ASSEMBLY__ + +#include + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; +#if defined(CONFIG_X86_PAE) +typedef u64 paddr_t; +#define PRIpaddr "016llx" +#else +typedef unsigned long paddr_t; +#define PRIpaddr "08lx" +#endif + +typedef unsigned long size_t; + +#endif /* __ASSEMBLY__ */ + +#define BITS_PER_LONG 32 +#define BYTES_PER_LONG 4 +#define LONG_BYTEORDER 2 + +#endif /* __X86_TYPES_H__ */ diff -r de942f6fa6b3 -r 5648dc802679 sboot/txt/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/txt/Makefile Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,8 @@ +obj-y += errors.o +obj-y += txt.o +obj-y += verify.o +obj-y += mtrrs.o +obj-y += acmod.o +obj-y += verify.o +obj-y += vmcs.o + diff -r de942f6fa6b3 -r 5648dc802679 sboot/txt/acmod.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sboot/txt/acmod.c Tue Aug 28 16:27:50 2007 -0700 @@ -0,0 +1,583 @@ +/* + * acmod.c: support functions for use of Intel(r) TXT Authenticated + * Code (AC) Modules + * + * Copyright (c) 2003-2007, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the Intel Corporation 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + union { + struct { + uint8_t chipset_acm_type; + uint8_t version; + uint16_t length; + uint32_t chipset_id_list; + } v1; + struct { + uuid_t uuid; + uint8_t chipset_acm_type; + uint8_t version; + uint16_t length; + uint32_t chipset_id_list; + uint32_t os_sinit_data_ver; + uint32_t mle_hdr_ver; + } v2; + }; +} acm_info_table_t; + +/* ACM UUID value */ +const uuid_t ACM_UUID = {0x8024d6cd, 0x4733, 0x2a62, 0xf1d1, + {0x3a, 0x89, 0x3b, 0x11, 0x82, 0xbc}}; + +/* chipset_acm_type field values */ +#define ACM_CHIPSET_TYPE_SINIT 0x01 + +typedef struct { + uint32_t flags; + uint16_t vendor_id; + uint16_t device_id; + uint16_t revision_id; + uint16_t reserved; + uint32_t extended_id; +} acm_chipset_id_t; + +typedef struct { + uint32_t count; + acm_chipset_id_t chipset_ids[]; +} acm_chipset_id_list_t; + + +#define ACM_MEM_TYPE_UC 0x0100 +#define ACM_MEM_TYPE_WC 0x0200 +#define ACM_MEM_TYPE_WT 0x1000 +#define ACM_MEM_TYPE_WP 0x2000 +#define ACM_MEM_TYPE_WB 0x4000 + +/* this is arbitrary and can be increased when needed */ +#define MAX_SUPPORTED_ACM_VERSIONS 16 + +typedef struct { + struct { + uint32_t mask; + uint32_t version; + } acm_versions[MAX_SUPPORTED_ACM_VERSIONS]; + int n_versions; + uint32_t acm_max_size; + uint32_t acm_mem_types; + uint32_t senter_controls; +} getsec_parameters_t; + +#define DEF_ACM_MAX_SIZE 0x8000 +#define DEF_ACM_VER_MASK 0xffffffff +#define DEF_ACM_VER_SUPPORTED 0x00 +#define DEF_ACM_MEM_TYPES ACM_MEM_TYPE_UC +#define DEF_SENTER_CTRLS 0x00 + +static bool get_parameters(getsec_parameters_t *params) +{ + unsigned long cr4; + uint32_t index, eax, ebx, ecx; + int param_type; + + /* sanity check because GETSEC[PARAMETERS] will fail if not set */ + cr4 = read_cr4(); + if ( !(cr4 & X86_CR4_SMXE) ) { + printk("SMXE not enabled, can't read parameters\n"); + return false; + } + + memset(params, 0, sizeof(*params)); + params->acm_max_size = DEF_ACM_MAX_SIZE; + params->acm_mem_types = DEF_ACM_MEM_TYPES; + params->senter_controls = DEF_SENTER_CTRLS; + index = 0; + do { + __getsec_parameters(index++, ¶m_type, &eax, &ebx, &ecx); + /* the code generated for a 'switch' statement doesn't work in this */ + /* environment, so use if/else blocks instead */ + if ( param_type == 0 ) + ; + else if ( param_type == 1 ) { + if ( params->n_versions == MAX_SUPPORTED_ACM_VERSIONS ) + printk("number of supported ACM version exceeds " + "MAX_SUPPORTED_ACM_VERSIONS\n"); + else { + params->acm_versions[params->n_versions].mask = ebx; + params->acm_versions[params->n_versions].version = ecx; + params->n_versions++; + } + } + else if ( param_type == 2 ) + params->acm_max_size = eax & 0xffffffe0; + else if ( param_type == 3 ) + params->acm_mem_types = eax & 0xffffffe0; + else if ( param_type == 4 ) + params->senter_controls = (eax & 0x00007fff) >> 8; + else { + printk("unknown GETSEC[PARAMETERS] type: %d\n", param_type); + param_type = 0; /* set so that we break out of the loop */ + } + } while ( param_type != 0 ); + + if ( params->n_versions == 0 ) { + params->acm_versions[0].mask = DEF_ACM_VER_MASK; + params->acm_versions[0].version = DEF_ACM_VER_SUPPORTED; + params->n_versions = 1; + } + + return true; +} + +static acm_info_table_t *get_acmod_info_table(acm_hdr_t* hdr) +{ + uint32_t user_area_off; + + /* this fn assumes that the ACM has already passed at least the initial */ + /* is_acmod() checks */ + + user_area_off = (hdr->header_len + hdr->scratch_size) * 4; + /* check that table is within module */ + if ( user_area_off + sizeof(acm_info_table_t) > hdr->size*4 ) { + printk("ACM info table size too large: %x\n", + user_area_off + sizeof(acm_info_table_t)); + return NULL; + } + + return (acm_info_table_t *)((uint32_t)hdr + user_area_off); +} + +static void print_acm_hdr(acm_hdr_t *hdr, const char *mod_name) +{ + acm_info_table_t *info_table; + + printk("AC module header dump for %s:\n", + (mod_name == NULL) ? "?" : mod_name); + printk("\t type=%x\n", hdr->module_type); + printk("\t length=%x\n", hdr->header_len); + printk("\t version=%x\n", hdr->header_ver); + printk("\t id=%x\n", hdr->module_id); + printk("\t vendor=%x\n", hdr->module_vendor); + printk("\t date=%08x\n", hdr->date); + printk("\t size*4=%x\n", hdr->size*4); + printk("\t entry point=%08x:%08x\n", hdr->seg_sel, + hdr->entry_point); + printk("\t scratch_size=%x\n", hdr->scratch_size); + + printk("\t info_table:\n"); + info_table = get_acmod_info_table(hdr); + if ( info_table == NULL ) { + printk("\t\t \n"); + return; + } + if ( are_uuids_equal(&(info_table->v2.uuid), &ACM_UUID) ) { + printk("\t\t uuid="); print_uuid(&info_table->v2.uuid); + printk("\n"); + printk("\t\t chipset_acm_type=%x\n", + (uint32_t)info_table->v2.chipset_acm_type); + printk("\t\t version=%x\n", (uint32_t)info_table->v2.version); + printk("\t\t length=%x\n", (uint32_t)info_table->v2.length); + printk("\t\t chipset_id_list=%x\n", + (uint32_t)info_table->v2.chipset_id_list); + printk("\t\t os_sinit_data_ver=%x\n", + (uint32_t)info_table->v2.os_sinit_data_ver); + printk("\t\t mle_hdr_ver=%x\n", (uint32_t)info_table->v2.mle_hdr_ver); + } + else { + printk("\t\tchipset_acm_type=%x\n", + (uint32_t)info_table->v1.chipset_acm_type); + printk("\t\tversion=%x\n", (uint32_t)info_table->v1.version); + printk("\t\tlength=%x\n", (uint32_t)info_table->v1.length); + printk("\t\tchipset_id_list=%x\n", + (uint32_t)info_table->v1.chipset_id_list); + } +} + +uint32_t get_supported_os_sinit_data_ver(acm_hdr_t* hdr) +{ + acm_info_table_t *info_table; + + /* assumes that it passed is_sinit_acmod() */ + + info_table = get_acmod_info_table(hdr); + if ( info_table == NULL ) + return 0x00; + + if ( are_uuids_equal(&(info_table->v2.uuid), &ACM_UUID) ) + return info_table->v2.os_sinit_data_ver; + else + return 0x01; +} + +static bool is_acmod(void *acmod_base, uint32_t acmod_size, uint8_t *type) +{ + acm_hdr_t *acm_hdr; + acm_info_table_t *info_table; + + acm_hdr = (acm_hdr_t *)acmod_base; + + /* first check size */ + if ( acmod_size < sizeof(acm_hdr_t) ) { + printk("ACM size is too small: acmod_size=%x," + " sizeof(acm_hdr)=%x\n", acmod_size, sizeof(acm_hdr) ); + return false; + } + if ( acmod_size != acm_hdr->size * 4 ) { + printk("ACM size is too small: acmod_size=%x," + " acm_hdr->size*4=%x\n", acmod_size, acm_hdr->size*4); + return false; + } + + /* then check type and vendor */ + if ( (acm_hdr->module_type != ACM_TYPE_CHIPSET) || + (acm_hdr->module_vendor != ACM_VENDOR_INTEL) ) { + printk("ACM type/vendor mismatch: module_type=%x," + " module_vendor=%x\n", acm_hdr->module_type, + acm_hdr->module_vendor); + return false; + } + + info_table = get_acmod_info_table(acm_hdr); + if ( info_table == NULL ) + return false; + + /* check if ACM UUID is present */ + if ( are_uuids_equal(&(info_table->v2.uuid), &ACM_UUID) ) { + if ( type != NULL ) + *type = info_table->v2.chipset_acm_type; + /* there is forward compatibility, so this is just a warning */ + if ( info_table->v2.version != 0x02 ) + printk("ACM info_table version mismatch (%x)\n", + (unsigned int)info_table->v2.version); + } + else { + if ( type != NU