- Initial checkin of the freebios2 tree


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@784 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
diff --git a/src/include/boot/elf.h b/src/include/boot/elf.h
new file mode 100644
index 0000000..3503388
--- /dev/null
+++ b/src/include/boot/elf.h
@@ -0,0 +1,401 @@
+#ifndef ELF_H
+#define	ELF_H
+
+/* Standard ELF types.  */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <arch/boot/boot.h>
+
+/* Type for a 16-bit quantity.  */
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+/* Types for signed and unsigned 32-bit quantities.  */
+typedef uint32_t Elf32_Word;
+typedef	int32_t  Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef	int32_t  Elf64_Sword;
+
+/* Types for signed and unsigned 64-bit quantities.  */
+typedef uint64_t Elf32_Xword;
+typedef	int64_t  Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef	int64_t  Elf64_Sxword;
+
+/* Type of addresses.  */
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+/* Type of file offsets.  */
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+/* Type for section indices, which are 16-bit quantities.  */
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+/* Type of symbol indices.  */
+typedef uint32_t Elf32_Symndx;
+typedef uint64_t Elf64_Symndx;
+
+
+/* The ELF file header.  This appears at the start of every ELF file.  */
+
+#define EI_NIDENT (16)
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf32_Half	e_type;			/* Object file type */
+  Elf32_Half	e_machine;		/* Architecture */
+  Elf32_Word	e_version;		/* Object file version */
+  Elf32_Addr	e_entry;		/* Entry point virtual address */
+  Elf32_Off	e_phoff;		/* Program header table file offset */
+  Elf32_Off	e_shoff;		/* Section header table file offset */
+  Elf32_Word	e_flags;		/* Processor-specific flags */
+  Elf32_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf32_Half	e_phentsize;		/* Program header table entry size */
+  Elf32_Half	e_phnum;		/* Program header table entry count */
+  Elf32_Half	e_shentsize;		/* Section header table entry size */
+  Elf32_Half	e_shnum;		/* Section header table entry count */
+  Elf32_Half	e_shstrndx;		/* Section header string table index */
+} Elf32_Ehdr;
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf64_Half	e_type;			/* Object file type */
+  Elf64_Half	e_machine;		/* Architecture */
+  Elf64_Word	e_version;		/* Object file version */
+  Elf64_Addr	e_entry;		/* Entry point virtual address */
+  Elf64_Off	e_phoff;		/* Program header table file offset */
+  Elf64_Off	e_shoff;		/* Section header table file offset */
+  Elf64_Word	e_flags;		/* Processor-specific flags */
+  Elf64_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf64_Half	e_phentsize;		/* Program header table entry size */
+  Elf64_Half	e_phnum;		/* Program header table entry count */
+  Elf64_Half	e_shentsize;		/* Section header table entry size */
+  Elf64_Half	e_shnum;		/* Section header table entry count */
+  Elf64_Half	e_shstrndx;		/* Section header string table index */
+} Elf64_Ehdr;
+
+/* Fields in the e_ident array.  The EI_* macros are indices into the
+   array.  The macros under each EI_* macro are the values the byte
+   may have.  */
+
+#define EI_MAG0		0		/* File identification byte 0 index */
+#define ELFMAG0		0x7f		/* Magic number byte 0 */
+
+#define EI_MAG1		1		/* File identification byte 1 index */
+#define ELFMAG1		'E'		/* Magic number byte 1 */
+
+#define EI_MAG2		2		/* File identification byte 2 index */
+#define ELFMAG2		'L'		/* Magic number byte 2 */
+
+#define EI_MAG3		3		/* File identification byte 3 index */
+#define ELFMAG3		'F'		/* Magic number byte 3 */
+
+/* Conglomeration of the identification bytes, for easy testing as a word.  */
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+
+#define EI_CLASS	4		/* File class byte index */
+#define ELFCLASSNONE	0		/* Invalid class */
+#define ELFCLASS32	1		/* 32-bit objects */
+#define ELFCLASS64	2		/* 64-bit objects */
+#define ELFCLASSNUM	3
+
+#define EI_DATA		5		/* Data encoding byte index */
+#define ELFDATANONE	0		/* Invalid data encoding */
+#define ELFDATA2LSB	1		/* 2's complement, little endian */
+#define ELFDATA2MSB	2		/* 2's complement, big endian */
+#define ELFDATANUM	3
+
+#define EI_VERSION	6		/* File version byte index */
+					/* Value must be EV_CURRENT */
+
+#define EI_OSABI	7		/* OS ABI identification */
+#define ELFOSABI_SYSV		0	/* UNIX System V ABI */
+#define ELFOSABI_HPUX		1	/* HP-UX */
+#define ELFOSABI_ARM		97	/* ARM */
+#define ELFOSABI_STANDALONE	255	/* Standalone (embedded) application */
+
+#define EI_ABIVERSION	8		/* ABI version */
+
+#define EI_PAD		9		/* Byte index of padding bytes */
+
+/* Legal values for e_type (object file type).  */
+
+#define ET_NONE		0		/* No file type */
+#define ET_REL		1		/* Relocatable file */
+#define ET_EXEC		2		/* Executable file */
+#define ET_DYN		3		/* Shared object file */
+#define ET_CORE		4		/* Core file */
+#define	ET_NUM		5		/* Number of defined types */
+#define ET_LOPROC	0xff00		/* Processor-specific */
+#define ET_HIPROC	0xffff		/* Processor-specific */
+
+/* Legal values for e_machine (architecture).  */
+
+#define EM_NONE		 0		/* No machine */
+#define EM_M32		 1		/* AT&T WE 32100 */
+#define EM_SPARC	 2		/* SUN SPARC */
+#define EM_386		 3		/* Intel 80386 */
+#define EM_68K		 4		/* Motorola m68k family */
+#define EM_88K		 5		/* Motorola m88k family */
+#define EM_486		 6		/* Intel 80486 */
+#define EM_860		 7		/* Intel 80860 */
+#define EM_MIPS		 8		/* MIPS R3000 big-endian */
+#define EM_S370		 9		/* Amdahl */
+#define EM_MIPS_RS4_BE	10		/* MIPS R4000 big-endian */
+#define EM_RS6000	11		/* RS6000 */
+
+#define EM_PARISC	15		/* HPPA */
+#define EM_nCUBE	16		/* nCUBE */
+#define EM_VPP500	17		/* Fujitsu VPP500 */
+#define EM_SPARC32PLUS	18		/* Sun's "v8plus" */
+#define EM_960		19		/* Intel 80960 */
+#define EM_PPC		20		/* PowerPC */
+
+#define EM_V800		36		/* NEC V800 series */
+#define EM_FR20		37		/* Fujitsu FR20 */
+#define EM_RH32		38		/* TRW RH32 */
+#define EM_MMA		39		/* Fujitsu MMA */
+#define EM_ARM		40		/* ARM */
+#define EM_FAKE_ALPHA	41		/* Digital Alpha */
+#define EM_SH		42		/* Hitachi SH */
+#define EM_SPARCV9	43		/* SPARC v9 64-bit */
+#define EM_TRICORE	44		/* Siemens Tricore */
+#define EM_ARC		45		/* Argonaut RISC Core */
+#define EM_H8_300	46		/* Hitachi H8/300 */
+#define EM_H8_300H	47		/* Hitachi H8/300H */
+#define EM_H8S		48		/* Hitachi H8S */
+#define EM_H8_500	49		/* Hitachi H8/500 */
+#define EM_IA_64	50		/* Intel Merced */
+#define EM_MIPS_X	51		/* Stanford MIPS-X */
+#define EM_COLDFIRE	52		/* Motorola Coldfire */
+#define EM_68HC12	53		/* Motorola M68HC12 */
+#define EM_NUM		54
+
+/* If it is necessary to assign new unofficial EM_* values, please
+   pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+   chances of collision with official or non-GNU unofficial values.  */
+
+#define EM_ALPHA	0x9026
+
+/* Legal values for e_version (version).  */
+
+#define EV_NONE		0		/* Invalid ELF version */
+#define EV_CURRENT	1		/* Current version */
+#define EV_NUM		2
+
+
+/* Program segment header.  */
+
+typedef struct
+{
+  Elf32_Word	p_type;			/* Segment type */
+  Elf32_Off	p_offset;		/* Segment file offset */
+  Elf32_Addr	p_vaddr;		/* Segment virtual address */
+  Elf32_Addr	p_paddr;		/* Segment physical address */
+  Elf32_Word	p_filesz;		/* Segment size in file */
+  Elf32_Word	p_memsz;		/* Segment size in memory */
+  Elf32_Word	p_flags;		/* Segment flags */
+  Elf32_Word	p_align;		/* Segment alignment */
+} Elf32_Phdr;
+
+typedef struct
+{
+  Elf64_Word	p_type;			/* Segment type */
+  Elf64_Word	p_flags;		/* Segment flags */
+  Elf64_Off	p_offset;		/* Segment file offset */
+  Elf64_Addr	p_vaddr;		/* Segment virtual address */
+  Elf64_Addr	p_paddr;		/* Segment physical address */
+  Elf64_Xword	p_filesz;		/* Segment size in file */
+  Elf64_Xword	p_memsz;		/* Segment size in memory */
+  Elf64_Xword	p_align;		/* Segment alignment */
+} Elf64_Phdr;
+
+/* Legal values for p_type (segment type).  */
+
+#define	PT_NULL		0		/* Program header table entry unused */
+#define PT_LOAD		1		/* Loadable program segment */
+#define PT_DYNAMIC	2		/* Dynamic linking information */
+#define PT_INTERP	3		/* Program interpreter */
+#define PT_NOTE		4		/* Auxiliary information */
+#define PT_SHLIB	5		/* Reserved */
+#define PT_PHDR		6		/* Entry for header table itself */
+#define	PT_NUM		7		/* Number of defined types.  */
+#define PT_LOOS		0x60000000	/* Start of OS-specific */
+#define PT_HIOS		0x6fffffff	/* End of OS-specific */
+#define PT_LOPROC	0x70000000	/* Start of processor-specific */
+#define PT_HIPROC	0x7fffffff	/* End of processor-specific */
+
+/* Legal values for p_flags (segment flags).  */
+
+#define PF_X		(1 << 0)	/* Segment is executable */
+#define PF_W		(1 << 1)	/* Segment is writable */
+#define PF_R		(1 << 2)	/* Segment is readable */
+#define PF_MASKPROC	0xf0000000	/* Processor-specific */
+
+
+/* Note section contents.  Each entry in the note section begins with
+   a header of a fixed form.  */
+
+typedef struct
+{
+  Elf32_Word n_namesz;			/* Length of the note's name.  */
+  Elf32_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf32_Word n_type;			/* Type of the note.  */
+} Elf32_Nhdr;
+
+typedef struct
+{
+  Elf64_Word n_namesz;			/* Length of the note's name.  */
+  Elf64_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf64_Word n_type;			/* Type of the note.  */
+} Elf64_Nhdr;
+
+/* Known names of notes.  */
+
+/* Solaris entries in the note section have this name.  */
+#define ELF_NOTE_SOLARIS	"SUNW Solaris"
+
+/* Note entries for GNU systems have this name.  */
+#define ELF_NOTE_GNU		"GNU"
+
+
+/* Defined types of notes for Solaris.  */
+
+/* Value of descriptor (one word) is desired pagesize for the binary.  */
+#define ELF_NOTE_PAGESIZE_HINT	1
+
+
+/* Defined note types for GNU systems.  */
+
+/* ABI information.  The descriptor consists of words:
+   word 0: OS descriptor
+   word 1: major version of the ABI
+   word 2: minor version of the ABI
+   word 3: subminor version of the ABI
+*/
+#define ELF_NOTE_ABI		1
+
+/* Known OSes.  These value can appear in word 0 of an ELF_NOTE_ABI
+   note section entry.  */
+#define ELF_NOTE_OS_LINUX	0
+#define ELF_NOTE_OS_GNU		1
+#define ELF_NOTE_OS_SOLARIS2	2
+
+
+/* Motorola 68k specific definitions.  */
+
+/* Intel 80386 specific definitions.  */
+
+/* SUN SPARC specific definitions.  */
+
+/* Values for Elf64_Ehdr.e_flags.  */
+
+#define EF_SPARCV9_MM		3
+#define EF_SPARCV9_TSO		0
+#define EF_SPARCV9_PSO		1
+#define EF_SPARCV9_RMO		2
+#define EF_SPARC_EXT_MASK	0xFFFF00
+#define EF_SPARC_SUN_US1	0x000200
+#define EF_SPARC_HAL_R1		0x000400
+
+/* MIPS R3000 specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_MIPS_NOREORDER   1		/* A .noreorder directive was used */
+#define EF_MIPS_PIC	    2		/* Contains PIC code */
+#define EF_MIPS_CPIC	    4		/* Uses PIC calling sequence */
+#define EF_MIPS_XGOT	    8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2	    32
+#define EF_MIPS_ABI_ON32    64
+#define EF_MIPS_ARCH	    0xf0000000	/* MIPS architecture level */
+
+/* Legal values for MIPS architecture level.  */
+
+#define EF_MIPS_ARCH_1	    0x00000000	/* -mips1 code.  */
+#define EF_MIPS_ARCH_2	    0x10000000	/* -mips2 code.  */
+#define EF_MIPS_ARCH_3	    0x20000000	/* -mips3 code.  */
+#define EF_MIPS_ARCH_4	    0x30000000	/* -mips4 code.  */
+#define EF_MIPS_ARCH_5	    0x40000000	/* -mips5 code.  */
+
+/* Legal values for p_type field of Elf32_Phdr.  */
+
+#define PT_MIPS_REGINFO	0x70000000	/* Register usage information */
+#define PT_MIPS_RTPROC  0x70000001	/* Runtime procedure table. */
+#define PT_MIPS_OPTIONS 0x70000002
+
+/* Special program header types.  */
+
+#define PF_MIPS_LOCAL	0x10000000
+
+
+/* HPPA specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_PARISC_TRAPNL	1	/* Trap nil pointer dereference.  */
+#define EF_PARISC_EXT		2	/* Program uses arch. extensions.  */
+#define EF_PARISC_ARCH		0xffff0000 /* Architecture version.  */
+/* Defined values are:
+				0x020b	PA-RISC 1.0 big-endian
+				0x0210	PA-RISC 1.1 big-endian
+				0x028b	PA-RISC 1.0 little-endian
+				0x0290	PA-RISC 1.1 little-endian
+*/
+
+
+/* Alpha specific definitions.  */
+
+/* Legal values for e_flags field of Elf64_Ehdr.  */
+
+#define EF_ALPHA_32BIT		1	/* All addresses must be < 2GB.  */
+#define EF_ALPHA_CANRELAX	2	/* Relocations for relaxing exist.  */
+
+
+/* PowerPC specific declarations */
+
+/* ARM specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_ARM_RELEXEC     0x01
+#define EF_ARM_HASENTRY    0x02
+#define EF_ARM_INTERWORK   0x04
+#define EF_ARM_APCS_26     0x08
+#define EF_ARM_APCS_FLOAT  0x10
+#define EF_ARM_PIC         0x20
+#define EF_ALIGN8          0x40		/* 8-bit structure alignment is in use */
+#define EF_NEW_ABI         0x80
+#define EF_OLD_ABI         0x100
+
+/* ARM-specific program header flags */
+#define PF_ARM_SB          0x10000000   /* Segment contains the location
+					   addressed by the static base */
+
+#if ELF_CLASS == ELFCLASS32
+typedef Elf32_Ehdr Elf_ehdr;
+typedef Elf32_Phdr Elf_phdr;
+#endif
+
+#if ELF_CLASS == ELFCLASS64
+typedef Elf64_Ehdr Elf_ehdr;
+typedef Elf64_Phdr Elf_phdr;
+#endif
+
+extern int elf_check_arch(Elf_ehdr *ehdr);
+extern void jmp_to_elf_entry(void *entry, unsigned long buffer);
+struct lb_memory;
+extern int elfboot(struct lb_memory *mem);
+
+#define FIRMWARE_TYPE "LinuxBIOS"
+#define BOOTLOADER "elfboot"
+#define BOOTLOADER_VERSION "1.3"
+
+#endif	/* elf.h */
diff --git a/src/include/boot/elf_boot.h b/src/include/boot/elf_boot.h
new file mode 100644
index 0000000..ee6750d
--- /dev/null
+++ b/src/include/boot/elf_boot.h
@@ -0,0 +1,89 @@
+#ifndef ELF_BOOT_H 
+#define ELF_BOOT_H 
+
+#include <stdint.h>
+
+/* This defines the structure of a table of parameters useful for ELF
+ * bootable images.  These parameters are all passed and generated
+ * by the bootloader to the booted image.  For simplicity and
+ * consistency the Elf Note format is reused.
+ *
+ * All of the information must be Position Independent Data.
+ * That is it must be safe to relocate the whole ELF boot parameter
+ * block without changing the meaning or correctnes of the data.
+ * Additionally it must be safe to permute the order of the ELF notes
+ * to any possible permutation without changing the meaning or correctness
+ * of the data.
+ *
+ */
+
+#define ELF_HEAD_SIZE		(8*1024)
+#define ELF_BOOT_MAGIC		0x0E1FB007
+
+typedef uint16_t Elf_Half;
+typedef uint32_t Elf_Word;
+typedef uint64_t Elf_Xword;
+
+typedef struct
+{
+	Elf_Word b_signature; /* "0x0E1FB007" */
+	Elf_Word b_size;
+	Elf_Half b_checksum;
+	Elf_Half b_records;
+} Elf_Bhdr;
+
+typedef struct 
+{
+	Elf_Word n_namesz;		/* Length of the note's name.  */
+	Elf_Word n_descsz;		/* Length of the note's descriptor.  */
+	Elf_Word n_type;		/* Type of the note.  */
+} Elf_Nhdr;
+
+
+/* For standard notes n_namesz must be zero */
+/* All of the following standard note types provide a single null
+ * terminated string in the descriptor.
+ */
+#define EBN_FIRMWARE_TYPE	0x00000001
+/* On platforms that support multiple classes of firmware this field
+ * specifies the class of firmware you are loaded under.
+ */
+#define EBN_BOOTLOADER_NAME	0x00000002
+/* This specifies just the name of the bootloader for easy comparison */
+#define EBN_BOOTLOADER_VERSION	0x00000003
+/* This specifies the version of the bootlader */
+#define EBN_COMMAND_LINE	0x00000004
+/* This specifies a command line that can be set by user interaction,
+ * and is provided as a free form string to the loaded image.
+ */
+
+
+/* Standardized Elf image notes for booting... The name for all of these is ELFBoot */
+
+#define ELF_NOTE_BOOT		"ELFBoot"
+
+#define EIN_PROGRAM_NAME	0x00000001
+/* The program in this ELF file */
+#define EIN_PROGRAM_VERSION	0x00000002
+/* The version of the program in this ELF file */
+#define EIN_PROGRAM_CHECKSUM	0x00000003
+/* ip style checksum of the memory image. */
+
+
+/* Linux image notes for booting... The name for all of these is Linux */
+
+#define LINUX_NOTE_BOOT		"Linux"
+
+#define LIN_COMMAND_LINE	0x00000001
+/* The command line to pass to the loaded kernel. */
+#define LIN_ROOT_DEV		0x00000002
+/* The root dev to pass to the loaded kernel. */
+#define LIN_RAMDISK_FLAGS	0x00000003
+/* Various old ramdisk flags */
+#define LIN_INITRD_START	0x00000004
+/* Start of the ramdisk in bytes */
+#define LIN_INITRD_SIZE		0x00000005
+/* Size of the ramdisk in bytes */
+
+
+#endif /* ELF_BOOT_H */
diff --git a/src/include/boot/linuxbios_tables.h b/src/include/boot/linuxbios_tables.h
new file mode 100644
index 0000000..5f37993
--- /dev/null
+++ b/src/include/boot/linuxbios_tables.h
@@ -0,0 +1,183 @@
+#ifndef LINUXBIOS_TABLES_H
+#define LINUXBIOS_TABLES_H
+
+#include <stdint.h>
+
+/* The linuxbios table information is for conveying information
+ * from the firmware to the loaded OS image.  Primarily this
+ * is expected to be information that cannot be discovered by
+ * other means, such as quering the hardware directly.
+ *
+ * All of the information should be Position Independent Data.  
+ * That is it should be safe to relocated any of the information
+ * without it's meaning/correctnes changing.   For table that
+ * can reasonably be used on multiple architectures the data
+ * size should be fixed.  This should ease the transition between
+ * 32 bit and 64 bit architectures etc.
+ *
+ * The completeness test for the information in this table is:
+ * - Can all of the hardware be detected?
+ * - Are the per motherboard constants available?
+ * - Is there enough to allow a kernel to run that was written before
+ *   a particular motherboard is constructed? (Assuming the kernel
+ *   has drivers for all of the hardware but it does not have
+ *   assumptions on how the hardware is connected together).
+ *
+ * With this test it should be straight forward to determine if a
+ * table entry is required or not.  This should remove much of the
+ * long term compatibility burden as table entries which are
+ * irrelevant or have been replaced by better alternatives may be
+ * dropped.  Of course it is polite and expidite to include extra
+ * table entries and be backwards compatible, but it is not required.
+ */
+
+
+struct lb_header
+{
+	uint8_t  signature[4]; /* LBIO */
+	uint32_t header_bytes;
+	uint32_t header_checksum;
+	uint32_t table_bytes;
+	uint32_t table_checksum;
+	uint32_t table_entries;
+};
+
+/* Every entry in the boot enviroment list will correspond to a boot
+ * info record.  Encoding both type and size.  The type is obviously
+ * so you can tell what it is.  The size allows you to skip that
+ * boot enviroment record if you don't know what it easy.  This allows
+ * forward compatibility with records not yet defined.
+ */
+struct lb_record {
+	uint32_t tag;		/* tag ID */
+	uint32_t size;		/* size of record (in bytes) */
+};
+
+#define LB_TAG_UNUSED	0x0000
+
+#define LB_TAG_MEMORY	0x0001
+
+struct lb_memory_range {
+	uint64_t start;
+	uint64_t size;
+	uint32_t type;
+#define LB_MEM_RAM       1	/* Memory anyone can use */
+#define LB_MEM_RESERVED  2	/* Don't use this memory region */
+#define LB_MEM_TABLE     16	/* Ram configuration tables are kept in */
+	
+};
+
+struct lb_memory {
+	uint32_t tag;
+	uint32_t size;
+	struct lb_memory_range map[0];
+};
+
+#define LB_TAG_HWRPB	0x0002
+struct lb_hwrpb {
+	uint32_t tag;
+	uint32_t size;
+	uint64_t hwrpb;
+};
+
+#define LB_TAG_MAINBOARD	0x0003
+struct lb_mainboard {
+	uint32_t tag;
+	uint32_t size;
+	uint8_t  vendor_idx;
+	uint8_t  part_number_idx;
+	uint8_t  strings[0];
+};
+
+#define LB_TAG_VERSION		0x0004
+#define LB_TAG_EXTRA_VERSION	0x0005
+#define LB_TAG_BUILD		0x0006
+#define LB_TAG_COMPILE_TIME	0x0007
+#define LB_TAG_COMPILE_BY	0x0008
+#define LB_TAG_COMPILE_HOST	0x0009
+#define LB_TAG_COMPILE_DOMAIN	0x000a
+#define LB_TAG_COMPILER		0x000b
+#define LB_TAG_LINKER		0x000c
+#define LB_TAG_ASSEMBLER	0x000d
+struct lb_string {
+	uint32_t tag;
+	uint32_t size;
+	uint8_t  string[0];
+};
+
+/* The following structures are for the cmos definitions table */
+#define LB_TAG_CMOS_OPTION_TABLE 200
+/* cmos header record */
+struct cmos_option_table {
+	uint32_t tag;               /* CMOS definitions table type */
+	uint32_t size;               /* size of the entire table */
+	uint32_t header_length;      /* length of header */
+};
+
+/* cmos entry record
+        This record is variable length.  The name field may be
+        shorter than CMOS_MAX_NAME_LENGTH. The entry may start
+        anywhere in the byte, but can not span bytes unless it
+        starts at the beginning of the byte and the length is
+        fills complete bytes.
+*/
+#define LB_TAG_OPTION 201
+struct cmos_entries {
+	uint32_t tag;                /* entry type */
+	uint32_t size;               /* length of this record */
+	uint32_t bit;                /* starting bit from start of image */
+	uint32_t length;             /* length of field in bits */
+	uint32_t config;             /* e=enumeration, h=hex, r=reserved */
+	uint32_t config_id;          /* a number linking to an enumeration record */
+#define CMOS_MAX_NAME_LENGTH 32
+	uint8_t name[CMOS_MAX_NAME_LENGTH]; /* name of entry in ascii, 
+					       variable length int aligned */
+};
+
+
+/* cmos enumerations record
+        This record is variable length.  The text field may be
+        shorter than CMOS_MAX_TEXT_LENGTH.
+*/
+#define LB_TAG_OPTION_ENUM 202
+struct cmos_enums {
+	uint32_t tag;		     /* enumeration type */
+	uint32_t size; 		     /* length of this record */
+	uint32_t config_id;          /* a number identifying the config id */
+	uint32_t value;              /* the value associated with the text */
+#define CMOS_MAX_TEXT_LENGTH 32
+	uint8_t text[CMOS_MAX_TEXT_LENGTH]; /* enum description in ascii, 
+						variable length int aligned */
+};
+
+/* cmos defaults record
+        This record contains default settings for the cmos ram.
+*/
+#define LB_TAG_OPTION_DEFAULTS 203
+struct cmos_defaults {
+	uint32_t tag;                /* default type */
+	uint32_t size;               /* length of this record */
+	uint32_t name_length;        /* length of the following name field */
+	uint8_t name[CMOS_MAX_NAME_LENGTH]; /* name identifying the default */
+#define CMOS_IMAGE_BUFFER_SIZE 128
+	uint8_t default_set[CMOS_IMAGE_BUFFER_SIZE]; /* default settings */
+};
+
+#define LB_TAG_OPTION_CHECKSUM 204
+struct	cmos_checksum {
+	uint32_t tag;
+	uint32_t size;
+	/* In practice everything is byte aligned, but things are measured
+	 * in bits to be consistent.
+	 */
+	uint32_t range_start;	/* First bit that is checksummed (byte aligned) */
+	uint32_t range_end;	/* Last bit that is checksummed (byte aligned) */
+	uint32_t location;	/* First bit of the checksum (byte aligned) */
+	uint32_t type;		/* Checksum algorithm that is used */
+#define CHECKSUM_NONE	0
+#define CHECKSUM_PCBIOS	1
+};
+
+
+
+#endif /* LINUXBIOS_TABLES_H */
diff --git a/src/include/boot/tables.h b/src/include/boot/tables.h
new file mode 100644
index 0000000..618c32e
--- /dev/null
+++ b/src/include/boot/tables.h
@@ -0,0 +1,9 @@
+#ifndef BOOT_TABLES_H
+#define BOOT_TABLES_H
+
+#include <mem.h>
+#include <boot/linuxbios_tables.h>
+
+struct lb_memory *write_tables(struct mem_range *mem, unsigned long *processor_map);
+
+#endif /* BOOT_TABLES_H */
diff --git a/src/include/console/console.h b/src/include/console/console.h
new file mode 100644
index 0000000..57ba9da
--- /dev/null
+++ b/src/include/console/console.h
@@ -0,0 +1,76 @@
+#ifndef CONSOLE_CONSOLE_H_
+#define CONSOLE_CONSOLE_H_
+
+#include <stdint.h>
+#include <console/loglevel.h>
+
+void console_init(void);
+void console_tx_byte(unsigned char byte);
+void console_tx_flush(void);
+void post_code(uint8_t value);
+void die(char *msg);
+
+struct console_driver {
+	void (*init)(void);
+	void (*tx_byte)(unsigned char byte);
+	void (*tx_flush)(void);
+};
+
+#define __console	__attribute__((unused, __section__ (".rodata.console_drivers")))
+
+/* Defined by the linker... */
+extern struct console_driver console_drivers[];
+extern struct console_driver econsole_drivers[];
+
+extern int console_loglevel;
+int do_printk(int msg_level, const char *fmt, ...);
+
+#define printk_emerg(fmt, arg...)   do_printk(BIOS_EMERG   ,fmt, ##arg)
+#define printk_alert(fmt, arg...)   do_printk(BIOS_ALERT   ,fmt, ##arg)
+#define printk_crit(fmt, arg...)    do_printk(BIOS_CRIT    ,fmt, ##arg)
+#define printk_err(fmt, arg...)     do_printk(BIOS_ERR     ,fmt, ##arg)
+#define printk_warning(fmt, arg...) do_printk(BIOS_WARNING ,fmt, ##arg)
+#define printk_notice(fmt, arg...)  do_printk(BIOS_NOTICE  ,fmt, ##arg)
+#define printk_info(fmt, arg...)    do_printk(BIOS_INFO    ,fmt, ##arg)
+#define printk_debug(fmt, arg...)   do_printk(BIOS_DEBUG   ,fmt, ##arg)
+#define printk_spew(fmt, arg...)    do_printk(BIOS_SPEW    ,fmt, ##arg)
+
+#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_EMERG
+#undef  printk_emerg
+#define printk_emerg(fmt, arg...)   do {} while(0)
+#endif
+#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_ALERT
+#undef  printk_alert
+#define printk_alart(fmt, arg...)   do {} while(0)
+#endif
+#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_CRIT
+#undef  printk_crit
+#define printk_crit(fmt, arg...)    do {} while(0)
+#endif
+#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_ERR
+#undef  printk_err
+#define printk_err(fmt, arg...)     do {} while(0)
+#endif
+#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_WARNING
+#undef  printk_warning
+#define printk_warning(fmt, arg...) do {} while(0)
+#endif
+#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_NOTICE
+#undef  printk_notice
+#define printk_notice(fmt, arg...)  do {} while(0)
+#endif
+#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_INFO
+#undef  printk_info
+#define printk_info(fmt, arg...)    do {} while(0)
+#endif
+#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_DEBUG
+#undef  printk_debug
+#define printk_debug(fmt, arg...)   do {} while(0)
+#endif
+#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_SPEW
+#undef  printk_spew
+#define printk_spew(fmt, arg...)    do {} while(0)
+#endif
+
+
+#endif /* CONSOLE_CONSOLE_H_ */
diff --git a/src/include/console/loglevel.h b/src/include/console/loglevel.h
new file mode 100644
index 0000000..a191b30
--- /dev/null
+++ b/src/include/console/loglevel.h
@@ -0,0 +1,30 @@
+#ifndef LOGLEVEL_H
+#define LOGLEVEL_H
+
+/* Safe for inclusion in assembly */
+
+#ifndef MAXIMUM_CONSOLE_LOGLEVEL
+#define MAXIMUM_CONSOLE_LOGLEVEL 8
+#endif
+
+#ifndef DEFAULT_CONSOLE_LOGLEVEL
+#define DEFAULT_CONSOLE_LOGLEVEL 8 /* anything MORE serious than BIOS_SPEW */
+#endif
+
+#if (DEFAULT_CONSOLE_LOGLEVEL <= MAXIMUM_CONSOLE_LOGLEVEL)
+#define ASM_CONSOLE_LOGLEVEL DEFAULT_CONSOLE_LOGLEVEL
+#else
+#define ASM_CONSOLE_LOGLEVEL MAXIMUM_CONSOLE_LOGLEVEL
+#endif
+
+#define BIOS_EMERG      0   /* system is unusable                   */
+#define BIOS_ALERT      1   /* action must be taken immediately     */
+#define BIOS_CRIT       2   /* critical conditions                  */
+#define BIOS_ERR        3   /* error conditions                     */
+#define BIOS_WARNING    4   /* warning conditions                   */
+#define BIOS_NOTICE     5   /* normal but significant condition     */
+#define BIOS_INFO       6   /* informational                        */
+#define BIOS_DEBUG      7   /* debug-level messages                 */
+#define BIOS_SPEW       8   /* Way too many details                 */
+
+#endif /* LOGLEVEL_H */
diff --git a/src/include/cpu/cpu.h b/src/include/cpu/cpu.h
new file mode 100644
index 0000000..208dab0
--- /dev/null
+++ b/src/include/cpu/cpu.h
@@ -0,0 +1,11 @@
+#ifndef CPU_CPU_H
+#define CPU_CPU_H
+
+#include <mem.h>
+
+unsigned long cpu_initialize(struct mem_range *mem);
+#define CPU_ENABLED		1	/* Processor is available */
+#define CPU_BOOTPROCESSOR	2	/* Processor is the BP */
+
+
+#endif /* CPU_CPU_H */
diff --git a/src/include/cpu/cpufixup.h b/src/include/cpu/cpufixup.h
new file mode 100644
index 0000000..b23afa5
--- /dev/null
+++ b/src/include/cpu/cpufixup.h
@@ -0,0 +1,24 @@
+#ifndef CPU_CPUFIXUP_H
+#define CPU_CPUFIXUP_H
+
+struct mem_range;
+
+#include <cpu/k8/cpufixup.h>
+#include <cpu/k7/cpufixup.h>
+#include <cpu/p6/cpufixup.h>
+
+#if CPU_FIXUP == 1 
+#  if defined(k8)
+#    define cpufixup(mem) k8_cpufixup(mem)
+#  elif defined(k7)
+#    define cpufixup(mem) k7_cpufixup(mem)
+#  elif defined(i786)
+#    define cpufixup(mem) i786_cpufixup(mem)
+#  elif defined(i686)
+#    define cpufixup(mem) p6_cpufixup(mem)
+#  endif
+#else
+#  define cpufixup(mem) do {} while(0)
+#endif
+
+#endif /* CPU_CPUFIXUP_H */
diff --git a/src/include/cpu/k7/cpufixup.h b/src/include/cpu/k7/cpufixup.h
new file mode 100644
index 0000000..0e3db3d
--- /dev/null
+++ b/src/include/cpu/k7/cpufixup.h
@@ -0,0 +1,6 @@
+#ifndef CPU_K7_CPUFIXUP_H
+#define CPU_K7_CPUFIXUP_H
+
+void k7_cpufixup(struct mem_range *mem);
+
+#endif /* CPU_K7_CPUFIXUP_H */
diff --git a/src/include/cpu/k7/mtrr.h b/src/include/cpu/k7/mtrr.h
new file mode 100644
index 0000000..ea376da
--- /dev/null
+++ b/src/include/cpu/k7/mtrr.h
@@ -0,0 +1,42 @@
+#ifndef CPU_K7_MTRR_H
+#define CPU_K7_MTRR_H
+
+#include <cpu/p6/mtrr.h>
+
+#define IORR_FIRST 0xC0010016
+#define IORR_LAST  0xC0010019
+#define SYSCFG     0xC0010010
+
+#define MTRR_READ_MEM			(1 << 4)
+#define MTRR_WRITE_MEM			(1 << 3)
+
+#define SYSCFG_MSR			0xC0010010
+#define SYSCFG_MSR_EvictEn		(1 << 22)
+#define SYSCFG_MSR_TOM2En		(1 << 21)
+#define SYSCFG_MSR_MtrrVarDramEn	(1 << 20)
+#define SYSCFG_MSR_MtrrFixDramModEn	(1 << 19)
+#define SYSCFG_MSR_MtrrFixDramEn	(1 << 18)
+#define SYSCFG_MSR_UcLockEn		(1 << 17)
+#define SYSCFG_MSR_ChxToDirtyDis	(1 << 16)
+#define SYSCFG_MSR_SysEccEn		(1 << 15)
+#define SYSCFG_MSR_RdBlkL2WayEn		(1 << 14)
+#define SYSCFG_MSR_SysFillValIsD1	(1 << 13)
+#define SYSCFG_MSR_IcInclusive		(1 << 12)
+#define SYSCFG_MSR_ClVicBlkEn		(1 << 11)
+#define SYSCFG_MSR_SetDirtyEnO		(1 << 10)
+#define SYSCFG_MSR_SetDirtyEnS		(1 <<  9)
+#define SYSCFG_MSR_SetDirtyEnE		(1 <<  8)
+#define SYSCFG_MSR_SysVicLimitMask	((1 << 8) - (1 << 5))
+#define SYSCFG_MSR_SysAckLimitMask	((1 << 5) - (1 << 0))
+
+
+
+#define IORR0_BASE			0xC0010016
+#define IORR0_MASK			0xC0010017
+#define IORR1_BASE			0xC0010018
+#define IORR1_MASK			0xC0010019
+#define TOP_MEM				0xC001001A
+#define TOP_MEM2			0xC001001D
+#define HWCR_MSR			0xC0010015
+
+#endif /* CPU_K7_MTRR_H */
diff --git a/src/include/cpu/k8/cpufixup.h b/src/include/cpu/k8/cpufixup.h
new file mode 100644
index 0000000..9500ec2
--- /dev/null
+++ b/src/include/cpu/k8/cpufixup.h
@@ -0,0 +1,6 @@
+#ifndef CPU_K8_CPUFIXUP_H
+#define CPU_K8_CPUFIXUP_H
+
+void k8_cpufixup(struct mem_range *mem);
+
+#endif /* CPU_K8_CPUFIXUP_H */
diff --git a/src/include/cpu/k8/mtrr.h b/src/include/cpu/k8/mtrr.h
new file mode 100644
index 0000000..ce9e6d4
--- /dev/null
+++ b/src/include/cpu/k8/mtrr.h
@@ -0,0 +1,45 @@
+#ifndef CPU_K8_MTRR_H
+#define CPU_K8_MTRR_H
+
+#include <cpu/k7/mtrr.h>
+
+#if 0
+#define IORR_FIRST 0xC0010016
+#define IORR_LAST  0xC0010019
+#define SYSCFG     0xC0010010
+
+#define MTRR_READ_MEM			(1 << 4)
+#define MTRR_WRITE_MEM			(1 << 3)
+
+#define SYSCFG_MSR			0xC0010010
+#define SYSCFG_MSR_EvictEn		(1 << 22)
+#define SYSCFG_MSR_TOM2En		(1 << 21)
+#define SYSCFG_MSR_MtrrVarDramEn	(1 << 20)
+#define SYSCFG_MSR_MtrrFixDramModEn	(1 << 19)
+#define SYSCFG_MSR_MtrrFixDramEn	(1 << 18)
+#define SYSCFG_MSR_UcLockEn		(1 << 17)
+#define SYSCFG_MSR_ChxToDirtyDis	(1 << 16)
+#define SYSCFG_MSR_SysEccEn		(1 << 15)
+#define SYSCFG_MSR_RdBlkL2WayEn		(1 << 14)
+#define SYSCFG_MSR_SysFillValIsD1	(1 << 13)
+#define SYSCFG_MSR_IcInclusive		(1 << 12)
+#define SYSCFG_MSR_ClVicBlkEn		(1 << 11)
+#define SYSCFG_MSR_SetDirtyEnO		(1 << 10)
+#define SYSCFG_MSR_SetDirtyEnS		(1 <<  9)
+#define SYSCFG_MSR_SetDirtyEnE		(1 <<  8)
+#define SYSCFG_MSR_SysVicLimitMask	((1 << 8) - (1 << 5))
+#define SYSCFG_MSR_SysAckLimitMask	((1 << 5) - (1 << 0))
+
+
+
+#define IORR0_BASE			0xC0010016
+#define IORR0_MASK			0xC0010017
+#define IORR1_BASE			0xC0010018
+#define IORR1_MASK			0xC0010019
+#define TOP_MEM				0xC001001A
+#define TOP_MEM2			0xC001001D
+#define HWCR_MSR			0xC0010015
+
+#endif
+
+#endif /* CPU_K8_MTRR_H */
diff --git a/src/include/cpu/p5/cpuid.h b/src/include/cpu/p5/cpuid.h
new file mode 100644
index 0000000..b8ffc88
--- /dev/null
+++ b/src/include/cpu/p5/cpuid.h
@@ -0,0 +1,25 @@
+#ifndef CPU_P5_CPUID_H
+#define CPU_P5_CPUID_H
+
+int mtrr_check(void);
+void display_cpuid(void);
+
+/*
+ *      Generic CPUID function. copied from Linux kernel headers
+ */
+
+static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
+{
+        __asm__("pushl %%ebx\n\t"
+		"cpuid\n\t"
+		"movl	%%ebx, %%esi\n\t"
+		"popl	%%ebx\n\t"
+                : "=a" (*eax),
+                  "=S" (*ebx),
+                  "=c" (*ecx),
+                  "=d" (*edx)
+                : "a" (op)
+                : "cc");
+}
+
+#endif /* CPU_P5_CPUID_H */
diff --git a/src/include/cpu/p6/apic.h b/src/include/cpu/p6/apic.h
new file mode 100644
index 0000000..b91cdb2
--- /dev/null
+++ b/src/include/cpu/p6/apic.h
@@ -0,0 +1,175 @@
+#ifndef APIC_H
+#define APIC_H
+
+#define APIC_BASE_MSR 0x1B
+#define APIC_BASE_MSR_BOOTSTRAP_PROCESSOR (1 << 8)
+#define APIC_BASE_MSR_ENABLE (1 << 11)
+#define APIC_BASE_MSR_ADDR_MASK 0xFFFFF000
+
+#define APIC_DEFAULT_BASE 0xfee00000
+
+#define APIC_ID		0x020
+#define APIC_LVR	0x030
+#define APIC_ARBID	0x090
+#define	APIC_RRR	0x0C0
+#define APIC_SVR	0x0f0
+#define APIC_SPIV	0x0f0
+#define 	APIC_SPIV_ENABLE  0x100
+#define APIC_ESR	0x280
+#define		APIC_ESR_SEND_CS	0x00001
+#define		APIC_ESR_RECV_CS	0x00002
+#define		APIC_ESR_SEND_ACC	0x00004
+#define		APIC_ESR_RECV_ACC	0x00008
+#define		APIC_ESR_SENDILL	0x00020
+#define		APIC_ESR_RECVILL	0x00040
+#define		APIC_ESR_ILLREGA	0x00080
+#define APIC_ICR 	0x300
+#define		APIC_DEST_SELF		0x40000
+#define		APIC_DEST_ALLINC	0x80000
+#define		APIC_DEST_ALLBUT	0xC0000
+#define		APIC_ICR_RR_MASK	0x30000
+#define		APIC_ICR_RR_INVALID	0x00000
+#define		APIC_ICR_RR_INPROG	0x10000
+#define		APIC_ICR_RR_VALID	0x20000
+#define		APIC_INT_LEVELTRIG	0x08000
+#define		APIC_INT_ASSERT		0x04000
+#define		APIC_ICR_BUSY		0x01000
+#define		APIC_DEST_LOGICAL	0x00800
+#define		APIC_DM_FIXED		0x00000
+#define		APIC_DM_LOWEST		0x00100
+#define		APIC_DM_SMI		0x00200
+#define		APIC_DM_REMRD		0x00300
+#define		APIC_DM_NMI		0x00400
+#define		APIC_DM_INIT		0x00500
+#define		APIC_DM_STARTUP		0x00600
+#define		APIC_DM_EXTINT		0x00700
+#define		APIC_VECTOR_MASK	0x000FF
+#define APIC_ICR2	0x310
+#define		GET_APIC_DEST_FIELD(x)	(((x)>>24)&0xFF)
+#define		SET_APIC_DEST_FIELD(x)	((x)<<24)
+#define APIC_LVTT	0x320
+#define APIC_LVTPC	0x340
+#define APIC_LVT0	0x350
+#define		APIC_LVT_TIMER_BASE_MASK	(0x3<<18)
+#define		GET_APIC_TIMER_BASE(x)		(((x)>>18)&0x3)
+#define		SET_APIC_TIMER_BASE(x)		(((x)<<18))
+#define		APIC_TIMER_BASE_CLKIN		0x0
+#define		APIC_TIMER_BASE_TMBASE		0x1
+#define		APIC_TIMER_BASE_DIV		0x2
+#define		APIC_LVT_TIMER_PERIODIC		(1<<17)
+#define		APIC_LVT_MASKED			(1<<16)
+#define		APIC_LVT_LEVEL_TRIGGER		(1<<15)
+#define		APIC_LVT_REMOTE_IRR		(1<<14)
+#define		APIC_INPUT_POLARITY		(1<<13)
+#define		APIC_SEND_PENDING		(1<<12)
+#define		APIC_LVT_RESERVED_1		(1<<11)
+#define		APIC_DELIVERY_MODE_MASK		(7<<8)
+#define		APIC_DELIVERY_MODE_FIXED	(0<<8)
+#define		APIC_DELIVERY_MODE_NMI		(4<<8)
+#define		APIC_DELIVERY_MODE_EXTINT	(7<<8)
+#define		GET_APIC_DELIVERY_MODE(x)	(((x)>>8)&0x7)
+#define		SET_APIC_DELIVERY_MODE(x,y)	(((x)&~0x700)|((y)<<8))
+#define			APIC_MODE_FIXED		0x0
+#define			APIC_MODE_NMI		0x4
+#define			APIC_MODE_EXINT		0x7
+#define APIC_LVT1	0x360
+#define APIC_LVTERR	0x370
+
+
+#if !defined(ASSEMBLY)
+
+#include <console/console.h>
+
+
+#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((struct __xchg_dummy *)(x))
+
+/*
+ * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
+ * Note 2: xchg has side effect, so that attribute volatile is necessary,
+ *	  but generally the primitive is invalid, *ptr is output argument. --ANK
+ */
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+	switch (size) {
+		case 1:
+			__asm__ __volatile__("xchgb %b0,%1"
+				:"=q" (x)
+				:"m" (*__xg(ptr)), "0" (x)
+				:"memory");
+			break;
+		case 2:
+			__asm__ __volatile__("xchgw %w0,%1"
+				:"=r" (x)
+				:"m" (*__xg(ptr)), "0" (x)
+				:"memory");
+			break;
+		case 4:
+			__asm__ __volatile__("xchgl %0,%1"
+				:"=r" (x)
+				:"m" (*__xg(ptr)), "0" (x)
+				:"memory");
+			break;
+	}
+	return x;
+}
+
+
+static inline unsigned long apic_read(unsigned long reg)
+{
+	return *((volatile unsigned long *)(APIC_DEFAULT_BASE+reg));
+}
+
+extern inline void apic_write_atomic(unsigned long reg, unsigned long v)
+{
+	xchg((volatile unsigned long *)(APIC_DEFAULT_BASE+reg), v);
+}
+
+static inline void apic_write(unsigned long reg, unsigned long v)
+{
+	*((volatile unsigned long *)(APIC_DEFAULT_BASE+reg)) = v;
+}
+
+static inline void apic_wait_icr_idle(void)
+{
+	do { } while ( apic_read( APIC_ICR ) & APIC_ICR_BUSY );
+}
+
+#ifdef CONFIG_X86_GOOD_APIC
+# define FORCE_READ_AROUND_WRITE 0
+# define apic_read_around(x) apic_read(x)
+# define apic_write_around(x,y) apic_write((x),(y))
+#else
+# define FORCE_READ_AROUND_WRITE 1
+# define apic_read_around(x) apic_read(x)
+# define apic_write_around(x,y) apic_write_atomic((x),(y))
+#endif
+
+static inline int apic_remote_read(int apicid, int reg, unsigned long *pvalue)
+{
+	int timeout;
+	unsigned long status;
+	int result;
+	apic_wait_icr_idle();
+	apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
+	apic_write_around(APIC_ICR, APIC_DM_REMRD | (reg >> 4));
+	timeout = 0;
+	do {
+#if 0
+		udelay(100);
+#endif
+		status = apic_read(APIC_ICR) & APIC_ICR_RR_MASK;
+	} while (status == APIC_ICR_RR_INPROG && timeout++ < 1000);
+
+	result = -1;
+	if (status == APIC_ICR_RR_VALID) {
+		*pvalue = apic_read(APIC_RRR);
+		result = 0;
+	}
+	return result;
+}
+#endif /* ASSEMBLY */
+
+#endif /* APIC_H */
diff --git a/src/include/cpu/p6/cpufixup.h b/src/include/cpu/p6/cpufixup.h
new file mode 100644
index 0000000..9b0f2fa
--- /dev/null
+++ b/src/include/cpu/p6/cpufixup.h
@@ -0,0 +1,6 @@
+#ifndef CPU_P6_CPUFIXUP_H
+#define CPU_P6_CPUFIXUP_H
+
+void p6_cpufixup(struct mem_range *mem);
+
+#endif /* CPU_P6_CPUFIXUP_H */
diff --git a/src/include/cpu/p6/msr.h b/src/include/cpu/p6/msr.h
new file mode 100644
index 0000000..4977b02
--- /dev/null
+++ b/src/include/cpu/p6/msr.h
@@ -0,0 +1,33 @@
+#ifndef CPU_P6_MSR_H
+#define CPU_P6_MSR_H
+
+/*
+ * Access to machine-specific registers (available on 586 and better only)
+ * Note: the rd* operations modify the parameters directly (without using
+ * pointer indirection), this allows gcc to optimize better
+ */
+
+#define rdmsr(msr,val1,val2) \
+       __asm__ __volatile__("rdmsr" \
+			    : "=a" (val1), "=d" (val2) \
+			    : "c" (msr))
+
+#define wrmsr(msr,val1,val2) \
+     __asm__ __volatile__("wrmsr" \
+			  : /* no outputs */ \
+			  : "c" (msr), "a" (val1), "d" (val2))
+
+#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 rdpmc(counter,low,high) \
+     __asm__ __volatile__("rdpmc" \
+			  : "=a" (low), "=d" (high) \
+			  : "c" (counter))
+#endif /* CPU_P6_MSR_H */
diff --git a/src/include/cpu/p6/mtrr.h b/src/include/cpu/p6/mtrr.h
new file mode 100644
index 0000000..16af10b
--- /dev/null
+++ b/src/include/cpu/p6/mtrr.h
@@ -0,0 +1,44 @@
+#ifndef __LINUXBIOS_CPU_P6_MTRR_H
+#define __LINUXBIOS_CPU_P6_MTRR_H
+
+/*  These are the region types  */
+#define MTRR_TYPE_UNCACHABLE 0
+#define MTRR_TYPE_WRCOMB     1
+/*#define MTRR_TYPE_         2*/
+/*#define MTRR_TYPE_         3*/
+#define MTRR_TYPE_WRTHROUGH  4
+#define MTRR_TYPE_WRPROT     5
+#define MTRR_TYPE_WRBACK     6
+#define MTRR_NUM_TYPES       7
+
+#define MTRRcap_MSR     0x0fe
+#define MTRRdefType_MSR 0x2ff
+
+#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
+#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
+
+#define NUM_FIXED_RANGES 88
+#define MTRRfix64K_00000_MSR 0x250
+#define MTRRfix16K_80000_MSR 0x258
+#define MTRRfix16K_A0000_MSR 0x259
+#define MTRRfix4K_C0000_MSR 0x268
+#define MTRRfix4K_C8000_MSR 0x269
+#define MTRRfix4K_D0000_MSR 0x26a
+#define MTRRfix4K_D8000_MSR 0x26b
+#define MTRRfix4K_E0000_MSR 0x26c
+#define MTRRfix4K_E8000_MSR 0x26d
+#define MTRRfix4K_F0000_MSR 0x26e
+#define MTRRfix4K_F8000_MSR 0x26f
+
+
+#if !defined(ASSEMBLY)
+
+void set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsigned char type);
+#if defined(INTEL_PPRO_MTRR) 
+struct mem_range;
+void setup_mtrrs(struct mem_range *mem);
+#endif
+
+#endif /* ASSEMBLY */
+
+#endif /* __LINUXBIOS_CPU_P6_MTRR_H */
diff --git a/src/include/delay.h b/src/include/delay.h
new file mode 100644
index 0000000..bffb719
--- /dev/null
+++ b/src/include/delay.h
@@ -0,0 +1,8 @@
+#ifndef DELAY_H
+#define DELAY_H
+
+void udelay(int usecs);
+void mdelay(int msecs);
+void delay(int secs);
+
+#endif /* DELAY_H */
diff --git a/src/include/ip_checksum.h b/src/include/ip_checksum.h
new file mode 100644
index 0000000..c2cb938
--- /dev/null
+++ b/src/include/ip_checksum.h
@@ -0,0 +1,7 @@
+#ifndef IP_CHECKSUM_H
+#define IP_CHECKSUM_H
+
+unsigned long compute_ip_checksum(void *addr, unsigned long length);
+unsigned long add_ip_checksums(unsigned long offset, unsigned long sum, unsigned long new);
+
+#endif /* IP_CHECKSUM_H */
diff --git a/src/include/mem.h b/src/include/mem.h
new file mode 100644
index 0000000..e8f633b
--- /dev/null
+++ b/src/include/mem.h
@@ -0,0 +1,13 @@
+#ifndef MEM_H
+#define MEM_H
+
+struct mem_range {
+	unsigned long basek;
+	unsigned long sizek;
+};
+
+/* mem_range arrays are non-overlapping, in ascending order and null terminated */
+
+struct mem_range *sizeram(void);
+
+#endif /* MEM_H */
diff --git a/src/include/part/fallback_boot.h b/src/include/part/fallback_boot.h
new file mode 100644
index 0000000..1eb2f7b
--- /dev/null
+++ b/src/include/part/fallback_boot.h
@@ -0,0 +1,16 @@
+#ifndef PART_FALLBACK_BOOT_H
+#define PART_FALLBACK_BOOT_H
+
+#ifndef ASSEMBLY
+
+#if HAVE_FALLBACK_BOOT
+void boot_successful(void);
+#else
+#define boot_successful()
+#endif
+
+#endif /* ASSEMBLY */
+
+#define RTC_BOOT_BYTE	48
+
+#endif /* PART_FALLBACK_BOOT_H */
diff --git a/src/include/part/sizeram.h b/src/include/part/sizeram.h
new file mode 100644
index 0000000..50a44f3
--- /dev/null
+++ b/src/include/part/sizeram.h
@@ -0,0 +1,7 @@
+#ifndef PART_SIZERAM_H
+#define PART_SIZERAM_H
+
+struct mem_rang;
+struct mem_range *sizeram(void);
+
+#endif /* PART_SIZERAM_H */
diff --git a/src/include/pc80/mc146818rtc.h b/src/include/pc80/mc146818rtc.h
new file mode 100644
index 0000000..1daf39a
--- /dev/null
+++ b/src/include/pc80/mc146818rtc.h
@@ -0,0 +1,110 @@
+#ifndef PC80_MC146818RTC_H
+#define PC80_MC146818RTC_H
+
+#ifndef RTC_BASE_PORT
+#define RTC_BASE_PORT 0x70
+#endif
+
+#define RTC_PORT(x)	(RTC_BASE_PORT + (x))
+
+/* On PCs, the checksum is built only over bytes 16..45 */
+#define PC_CKS_RANGE_START	16
+#define PC_CKS_RANGE_END	45
+#define PC_CKS_LOC		46
+
+
+/* Linux bios checksum is built only over bytes 49..125 */
+#define LB_CKS_RANGE_START	49
+#define LB_CKS_RANGE_END	125
+#define LB_CKS_LOC		126
+
+
+/* control registers - Moto names
+ */
+#define RTC_REG_A		10
+#define RTC_REG_B		11
+#define RTC_REG_C		12
+#define RTC_REG_D		13
+
+
+/**********************************************************************
+ * register details
+ **********************************************************************/
+#define RTC_FREQ_SELECT	RTC_REG_A
+
+/* update-in-progress  - set to "1" 244 microsecs before RTC goes off the bus,
+ * reset after update (may take 1.984ms @ 32768Hz RefClock) is complete,
+ * totalling to a max high interval of 2.228 ms.
+ */
+# define RTC_UIP		0x80
+# define RTC_DIV_CTL		0x70
+   /* divider control: refclock values 4.194 / 1.049 MHz / 32.768 kHz */
+#  define RTC_REF_CLCK_4MHZ	0x00
+#  define RTC_REF_CLCK_1MHZ	0x10
+#  define RTC_REF_CLCK_32KHZ	0x20
+   /* 2 values for divider stage reset, others for "testing purposes only" */
+#  define RTC_DIV_RESET1	0x60
+#  define RTC_DIV_RESET2	0x70
+  /* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */
+# define RTC_RATE_SELECT 	0x0F
+#  define RTC_RATE_NONE		0x00
+#  define RTC_RATE_32786HZ	0x01
+#  define RTC_RATE_16384HZ	0x02
+#  define RTC_RATE_8192HZ	0x03
+#  define RTC_RATE_4096HZ	0x04
+#  define RTC_RATE_2048HZ	0x05
+#  define RTC_RATE_1024HZ	0x06
+#  define RTC_RATE_512HZ	0x07
+#  define RTC_RATE_256HZ	0x08
+#  define RTC_RATE_128HZ	0x09
+#  define RTC_RATE_64HZ		0x0a
+#  define RTC_RATE_32HZ		0x0b
+#  define RTC_RATE_16HZ		0x0c
+#  define RTC_RATE_8HZ		0x0d
+#  define RTC_RATE_4HZ		0x0e
+#  define RTC_RATE_2HZ		0x0f
+
+/**********************************************************************/
+#define RTC_CONTROL	RTC_REG_B
+# define RTC_SET 0x80		/* disable updates for clock setting */
+# define RTC_PIE 0x40		/* periodic interrupt enable */
+# define RTC_AIE 0x20		/* alarm interrupt enable */
+# define RTC_UIE 0x10		/* update-finished interrupt enable */
+# define RTC_SQWE 0x08		/* enable square-wave output */
+# define RTC_DM_BINARY 0x04	/* all time/date values are BCD if clear */
+# define RTC_24H 0x02		/* 24 hour mode - else hours bit 7 means pm */
+# define RTC_DST_EN 0x01	/* auto switch DST - works f. USA only */
+
+/**********************************************************************/
+#define RTC_INTR_FLAGS	RTC_REG_C
+/* caution - cleared by read */
+# define RTC_IRQF 0x80		/* any of the following 3 is active */
+# define RTC_PF 0x40
+# define RTC_AF 0x20
+# define RTC_UF 0x10
+
+/**********************************************************************/
+#define RTC_VALID	RTC_REG_D
+# define RTC_VRT 0x80		/* valid RAM and time */
+/**********************************************************************/
+
+
+/* On PCs, the checksum is built only over bytes 16..45 */
+#define PC_CKS_RANGE_START	16
+#define PC_CKS_RANGE_END	45
+#define PC_CKS_LOC		46
+
+#define LB_CKS_RANGE_START	49
+#define LB_CKS_RANGE_END	125
+#define LB_CKS_LOC		126
+
+#if !defined(ASSEMBLY)
+void rtc_init(int invalid);
+#if USE_OPTION_TABLE == 1
+int get_option(void *dest, char *name);
+#else
+#define get_option(dest, name) (-2)
+#endif
+#endif
+
+#endif /*  PC80_MC146818RTC_H */
diff --git a/src/include/smp/atomic.h b/src/include/smp/atomic.h
new file mode 100644
index 0000000..b36e0e2
--- /dev/null
+++ b/src/include/smp/atomic.h
@@ -0,0 +1,53 @@
+#ifndef SMP_ATOMIC_H
+#define SMP_ATOMIC_H
+
+#ifdef SMP
+#include <arch/smp/atomic.h>
+#else
+
+typedef struct { int counter; } atomic_t;
+#define ATOMIC_INIT(i) { (i) }
+
+/**
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ * 
+ * Atomically reads the value of @v.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */ 
+#define atomic_read(v)		((v)->counter)
+
+/**
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ * 
+ * Atomically sets the value of @v to @i.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */ 
+#define atomic_set(v,i)		(((v)->counter) = (i))
+
+
+/**
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ * 
+ * Atomically increments @v by 1.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */ 
+#define atomic_inc(v)	(((v)->counter)++)
+
+
+/**
+ * atomic_dec - decrement atomic variable
+ * @v: pointer of type atomic_t
+ * 
+ * Atomically decrements @v by 1.  Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */ 
+#define atomic_dec(v)	(((v)->counter)--)
+
+
+#endif /* SMP */
+
+#endif /* SMP_ATOMIC_H */
diff --git a/src/include/smp/spinlock.h b/src/include/smp/spinlock.h
new file mode 100644
index 0000000..9e0f8af
--- /dev/null
+++ b/src/include/smp/spinlock.h
@@ -0,0 +1,24 @@
+#ifndef SMP_SPINLOCK_H
+#define SMP_SPINLOCK_H
+
+#ifdef SMP
+#include <arch/smp/spinlock.h>
+#else /* !SMP */
+
+/* Most GCC versions have a nasty bug with empty initializers */
+#if (__GNUC__ > 2) 
+typedef struct { } spinlock_t;
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { }
+#else
+typedef struct { int gcc_is_buggy; } spinlock_t;
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
+#endif
+
+#define barrier()		do {} while(0)
+#define spin_is_locked(lock)	0
+#define spin_unlock_wait(lock)	do {} while(0)
+#define spin_lock(lock)		do {} while(0)
+#define spin_unlock(lock)	do {} while(0)
+#endif
+
+#endif /* SMP_SPINLOCK_H */
diff --git a/src/include/smp/start_stop.h b/src/include/smp/start_stop.h
new file mode 100644
index 0000000..c0eebd0
--- /dev/null
+++ b/src/include/smp/start_stop.h
@@ -0,0 +1,17 @@
+#ifndef SMP_START_STOP_H
+#define SMP_START_STOP_H
+
+#if SMP == 1
+#include <smp/atomic.h>
+unsigned long this_processors_id(void);
+int processor_index(unsigned long processor_id);
+void stop_cpu(unsigned long processor_id);
+int start_cpu(unsigned long processor_id);
+void startup_other_cpus(unsigned long *processor_map);
+#else
+#define this_processors_id()	0
+#define startup_other_cpus(p)	do {} while(0)
+#define processor_index(p) 0
+#endif
+
+#endif /* SMP_START_STOP_H */
diff --git a/src/include/stdlib.h b/src/include/stdlib.h
new file mode 100644
index 0000000..eb67d20
--- /dev/null
+++ b/src/include/stdlib.h
@@ -0,0 +1,14 @@
+#ifndef STDLIB_H
+#define STDLIB_H
+
+#include <stddef.h>
+
+extern void *malloc(size_t size);
+void free(void *ptr);
+
+/* Extensions to malloc... */
+typedef size_t malloc_mark_t;
+void malloc_mark(malloc_mark_t *place);
+void malloc_release(malloc_mark_t *place);
+
+#endif /* STDLIB_H */
diff --git a/src/include/stream/read_bytes.h b/src/include/stream/read_bytes.h
new file mode 100644
index 0000000..dd3ef04
--- /dev/null
+++ b/src/include/stream/read_bytes.h
@@ -0,0 +1,13 @@
+#ifndef STREAM_READ_BYTES_H
+#define STREAM_READ_BYTES_H
+
+#include <stdint.h>
+
+typedef long byte_offset_t;
+
+extern int stream_init(void);
+extern byte_offset_t stream_read(void *vdest, byte_offset_t count);
+extern byte_offset_t stream_skip(byte_offset_t count);
+extern void stream_fini(void);
+
+#endif /* STREAM_READ_BYTES_H */
diff --git a/src/include/string.h b/src/include/string.h
new file mode 100644
index 0000000..cf9bbb1
--- /dev/null
+++ b/src/include/string.h
@@ -0,0 +1,36 @@
+#ifndef STRING_H
+#define STRING_H
+
+#include <stddef.h>
+
+// yes, linux has fancy ones. We don't care. This stuff gets used 
+// hardly at all. And the pain of including those files is just too high.
+
+//extern inline void strcpy(char *dst, char *src) {while (*src) *dst++ = *src++;}
+
+//extern inline int strlen(char *src) { int i = 0; while (*src++) i++; return i;}
+
+static inline size_t strnlen(const char *src, size_t max) 
+{ 
+	size_t i = 0;
+	while((*src++) && (i < max)) {
+		i++;
+	}
+	return i;
+}
+
+static inline size_t strlen(const char *src)
+{
+	size_t i = 0;
+	while(*src++) {
+		i++;
+	}
+	return i;
+}
+
+extern void *memcpy(void *dest, const void *src, size_t n);
+extern void *memset(void *s, int c, size_t n);
+extern int memcmp(const void *s1, const void *s2, size_t n);
+
+extern int sprintf(char * buf, const char *fmt, ...);
+#endif /* STRING_H */
diff --git a/src/include/uart8250.h b/src/include/uart8250.h
new file mode 100644
index 0000000..ae45615
--- /dev/null
+++ b/src/include/uart8250.h
@@ -0,0 +1,7 @@
+#ifndef UART8250_H
+#define UART8250_H
+
+void uart8250_tx_byte(unsigned base_port, unsigned char data);
+void uart8250_init(unsigned base_port, unsigned divisor, unsigned lcs);
+
+#endif /* UART8250_H */
diff --git a/src/include/version.h b/src/include/version.h
new file mode 100644
index 0000000..223b9a3
--- /dev/null
+++ b/src/include/version.h
@@ -0,0 +1,22 @@
+#ifndef VERSION_H
+#define VERSION_H
+
+/* Motherboard Information */
+extern const char mainboard_vendor[];
+extern const char mainboard_part_number[];
+
+/* LinuxBIOS Version */
+extern const char linuxbios_version[];
+extern const char linuxbios_extra_version[];
+extern const char linuxbios_build[];
+
+/* When LinuxBIOS was compiled */
+extern const char linuxbios_compile_time[];
+extern const char linuxbios_compile_by[];
+extern const char linuxbios_compile_host[];
+extern const char linuxbios_compile_domain[];
+extern const char linuxbios_compiler[];
+extern const char linuxbios_linker[];
+extern const char linuxbios_assembler[];
+
+#endif /* VERSION_H */