aboutsummaryrefslogtreecommitdiff
path: root/src/arch/i386/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/i386/include')
-rw-r--r--src/arch/i386/include/arch/asm.h30
-rw-r--r--src/arch/i386/include/arch/boot/boot.h8
-rw-r--r--src/arch/i386/include/arch/intel.h369
-rw-r--r--src/arch/i386/include/arch/io.h76
-rw-r--r--src/arch/i386/include/arch/pciconf.h9
-rw-r--r--src/arch/i386/include/arch/pirq_routing.h54
-rw-r--r--src/arch/i386/include/arch/rom_segs.h10
-rw-r--r--src/arch/i386/include/arch/romcc_io.h84
-rw-r--r--src/arch/i386/include/arch/smp/mpspec.h282
-rw-r--r--src/arch/i386/include/bitops.h20
-rw-r--r--src/arch/i386/include/stddef.h15
-rw-r--r--src/arch/i386/include/stdint.h52
12 files changed, 1009 insertions, 0 deletions
diff --git a/src/arch/i386/include/arch/asm.h b/src/arch/i386/include/arch/asm.h
new file mode 100644
index 0000000000..ea63e2d4eb
--- /dev/null
+++ b/src/arch/i386/include/arch/asm.h
@@ -0,0 +1,30 @@
+#ifndef ASM_H
+#define ASM_H
+
+#define ASSEMBLER
+
+/*
+ * Bootstrap code for the STPC Consumer
+ * Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
+ *
+ * $Id$
+ *
+ */
+
+#define I386_ALIGN_TEXT 0
+#define I386_ALIGN_DATA 0
+
+/*
+ * XXX
+ */
+#ifdef __ELF__
+#define EXT(x) x
+#else
+#define EXT(x) _ ## x
+#endif
+
+#define STATIC(x) .align I386_ALIGN_TEXT; EXT(x):
+#define GLOBAL(x) .globl EXT(x); STATIC(x)
+#define ENTRY(x) .text; GLOBAL(x)
+
+#endif /* ASM_H */
diff --git a/src/arch/i386/include/arch/boot/boot.h b/src/arch/i386/include/arch/boot/boot.h
new file mode 100644
index 0000000000..3ff51c3082
--- /dev/null
+++ b/src/arch/i386/include/arch/boot/boot.h
@@ -0,0 +1,8 @@
+#ifndef ASM_I386_BOOT_H
+#define ASM_I386_BOOT_H
+
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2LSB
+#define ELF_ARCH EM_386
+
+#endif /* ASM_I386_BOOT_H */
diff --git a/src/arch/i386/include/arch/intel.h b/src/arch/i386/include/arch/intel.h
new file mode 100644
index 0000000000..df6604e08e
--- /dev/null
+++ b/src/arch/i386/include/arch/intel.h
@@ -0,0 +1,369 @@
+/*
+This software and ancillary information (herein called SOFTWARE )
+called LinuxBIOS is made available under the terms described
+here. The SOFTWARE has been approved for release with associated
+LA-CC Number 00-34 . Unless otherwise indicated, this SOFTWARE has
+been authored by an employee or employees of the University of
+California, operator of the Los Alamos National Laboratory under
+Contract No. W-7405-ENG-36 with the U.S. Department of Energy. The
+U.S. Government has rights to use, reproduce, and distribute this
+SOFTWARE. The public may copy, distribute, prepare derivative works
+and publicly display this SOFTWARE without charge, provided that this
+Notice and any statement of authorship are reproduced on all copies.
+Neither the Government nor the University makes any warranty, express
+or implied, or assumes any liability or responsibility for the use of
+this SOFTWARE. If SOFTWARE is modified to produce derivative works,
+such modified SOFTWARE should be clearly marked, so as not to confuse
+it with the version available from LANL.
+ */
+/* Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL
+ * rminnich@lanl.gov
+ */
+
+
+#ifndef ROM_INTEL_H
+#define ROM_INTEL_H
+
+/*
+ * Bootstrap code for the Intel
+ *
+ * $Id$
+ *
+ */
+
+/*
+ * Config registers.
+ */
+/* yeah, yeah, I know these are macros, which is bad. Don't forget:
+ * we have almost no assembly, so I am not worrying just yet about this.
+ * we'll fix it someday if we care. My guess is we won't.
+ */
+
+/* well we want functions. But first we want to see it work at all. */
+#undef FUNCTIONS
+#ifndef FUNCTIONS
+
+
+#define RET_LABEL(label) \
+ jmp label##_done
+
+#define CALL_LABEL(label) \
+ jmp label ;\
+label##_done:
+
+#define CALLSP(func) \
+ lea 0f, %esp ; \
+ jmp func ; \
+0:
+
+#define RETSP \
+ jmp *%esp
+
+
+#define DELAY(x) mov x, %ecx ;\
+ 1: loop 1b ;\
+
+
+ /*
+ * Macro: PCI_WRITE_CONFIG_BYTE
+ * Arguments: %eax address to write to (includes bus, device, function, &offset)
+ * %dl byte to write
+ *
+ * Results: none
+ *
+ * Trashed: %eax, %edx
+ * Effects: writes a single byte to pci config space
+ *
+ * Notes: This routine is optimized for minimal register usage.
+ * And the tricks it does cannot scale beyond writing a single byte.
+ *
+ * What it does is almost simple.
+ * It preserves %eax (baring special bits) until it is written
+ * out to the appropriate port. And hides the data byte
+ * in the high half of edx.
+ *
+ * In %edx[3] it stores the byte to write.
+ * In %edx[2] it stores the lower three bits of the address.
+ */
+
+
+#define PCI_WRITE_CONFIG_BYTE \
+ shll $8, %edx ; \
+ movb %al, %dl ; \
+ andb $0x3, %dl ; \
+ shll $16, %edx ; \
+ \
+ orl $0x80000000, %eax ; \
+ andl $0xfffffffc, %eax ; \
+ movw $0xcf8, %dx ; \
+ outl %eax, %dx ; \
+ \
+ shrl $16, %edx ; \
+ movb %dh, %al ; \
+ movb $0, %dh ; \
+ addl $0xcfc, %edx ; \
+ outb %al, %dx
+
+
+ /*
+ * Macro: PCI_WRITE_CONFIG_WORD
+ * Arguments: %eax address to write to (includes bus, device, function, &offset)
+ * %ecx word to write
+ *
+ * Results: none
+ *
+ * Trashed: %eax, %edx
+ * Preserved: %ecx
+ * Effects: writes a single byte to pci config space
+ *
+ * Notes: This routine is optimized for minimal register usage.
+ *
+ * What it does is almost simple.
+ * It preserves %eax (baring special bits) until it is written
+ * out to the appropriate port. And hides the least significant
+ * bits of the address in the high half of edx.
+ *
+ * In %edx[2] it stores the lower three bits of the address.
+ */
+
+
+#define PCI_WRITE_CONFIG_WORD \
+ movb %al, %dl ; \
+ andl $0x3, %edx ; \
+ shll $16, %edx ; \
+ \
+ orl $0x80000000, %eax ; \
+ andl $0xfffffffc, %eax ; \
+ movw $0xcf8, %dx ; \
+ outl %eax, %dx ; \
+ \
+ shrl $16, %edx ; \
+ movl %ecx, %eax ; \
+ addl $0xcfc, %edx ; \
+ outw %ax, %dx
+
+
+
+ /*
+ * Macro: PCI_WRITE_CONFIG_DWORD
+ * Arguments: %eax address to write to (includes bus, device, function, &offset)
+ * %ecx dword to write
+ *
+ * Results: none
+ *
+ * Trashed: %eax, %edx
+ * Preserved: %ecx
+ * Effects: writes a single byte to pci config space
+ *
+ * Notes: This routine is optimized for minimal register usage.
+ *
+ * What it does is almost simple.
+ * It preserves %eax (baring special bits) until it is written
+ * out to the appropriate port. And hides the least significant
+ * bits of the address in the high half of edx.
+ *
+ * In %edx[2] it stores the lower three bits of the address.
+ */
+
+
+#define PCI_WRITE_CONFIG_DWORD \
+ movb %al, %dl ; \
+ andl $0x3, %edx ; \
+ shll $16, %edx ; \
+ \
+ orl $0x80000000, %eax ; \
+ andl $0xfffffffc, %eax ; \
+ movw $0xcf8, %dx ; \
+ outl %eax, %dx ; \
+ \
+ shrl $16, %edx ; \
+ movl %ecx, %eax ; \
+ addl $0xcfc, %edx ; \
+ outl %eax, %dx
+
+
+
+
+ /*
+ * Macro: PCI_READ_CONFIG_BYTE
+ * Arguments: %eax address to read from (includes bus, device, function, &offset)
+ *
+ * Results: %al Byte read
+ *
+ * Trashed: %eax, %edx
+ * Effects: reads a single byte from pci config space
+ *
+ * Notes: This routine is optimized for minimal register usage.
+ *
+ * What it does is almost simple.
+ * It preserves %eax (baring special bits) until it is written
+ * out to the appropriate port. And hides the least significant
+ * bits of the address in the high half of edx.
+ *
+ * In %edx[2] it stores the lower three bits of the address.
+ */
+
+
+#define PCI_READ_CONFIG_BYTE \
+ movb %al, %dl ; \
+ andl $0x3, %edx ; \
+ shll $16, %edx ; \
+ \
+ orl $0x80000000, %eax ; \
+ andl $0xfffffffc, %eax ; \
+ movw $0xcf8, %dx ; \
+ outl %eax, %dx ; \
+ \
+ shrl $16, %edx ; \
+ addl $0xcfc, %edx ; \
+ inb %dx, %al
+
+
+
+ /*
+ * Macro: PCI_READ_CONFIG_WORD
+ * Arguments: %eax address to read from (includes bus, device, function, &offset)
+ *
+ * Results: %ax word read
+ *
+ * Trashed: %eax, %edx
+ * Effects: reads a 2 bytes from pci config space
+ *
+ * Notes: This routine is optimized for minimal register usage.
+ *
+ * What it does is almost simple.
+ * It preserves %eax (baring special bits) until it is written
+ * out to the appropriate port. And hides the least significant
+ * bits of the address in the high half of edx.
+ *
+ * In %edx[2] it stores the lower three bits of the address.
+ */
+
+
+#define PCI_READ_CONFIG_WORD \
+ movb %al, %dl ; \
+ andl $0x3, %edx ; \
+ shll $16, %edx ; \
+ \
+ orl $0x80000000, %eax ; \
+ andl $0xfffffffc, %eax ; \
+ movw $0xcf8, %dx ; \
+ outl %eax, %dx ; \
+ \
+ shrl $16, %edx ; \
+ addl $0xcfc, %edx ; \
+ inw %dx, %ax
+
+
+
+ /*
+ * Macro: PCI_READ_CONFIG_DWORD
+ * Arguments: %eax address to read from (includes bus, device, function, &offset)
+ *
+ * Results: %eax
+ *
+ * Trashed: %edx
+ * Effects: reads 4 bytes from pci config space
+ *
+ * Notes: This routine is optimized for minimal register usage.
+ *
+ * What it does is almost simple.
+ * It preserves %eax (baring special bits) until it is written
+ * out to the appropriate port. And hides the least significant
+ * bits of the address in the high half of edx.
+ *
+ * In %edx[2] it stores the lower three bits of the address.
+ */
+
+
+#define PCI_READ_CONFIG_DWORD \
+ movb %al, %dl ; \
+ andl $0x3, %edx ; \
+ shll $16, %edx ; \
+ \
+ orl $0x80000000, %eax ; \
+ andl $0xfffffffc, %eax ; \
+ movw $0xcf8, %dx ; \
+ outl %eax, %dx ; \
+ \
+ shrl $16, %edx ; \
+ addl $0xcfc, %edx ; \
+ inl %dx, %eax
+
+
+
+
+#define CS_READ(which) \
+ mov $0x80000000,%eax ; \
+ mov which,%ax ; \
+ and $0xfc,%al /* clear bits 1-0 */ ; \
+ mov $0xcf8,%dx /* port 0xcf8 ?*/ ; \
+ outl %eax,%dx /* open up CS config */ ; \
+ add $0x4,%dl /* 0xcfc data port 0 */ ; \
+ mov which,%al ; \
+ and $0x3,%al /* only bits 1-0 */ ; \
+ add %al,%dl ; \
+ inb %dx,%al /* read */ ; \
+
+
+#define CS_WRITE(which, data) \
+ mov $0x80000000,%eax /* 32bit word with bit 31 set */ ; \
+ mov which,%ax /* put the reg# in the low part */ ; \
+ and $0xfc,%al /* dword align the reg# */ ; \
+ mov $0xcf8,%dx /* enable port */ ; \
+ outl %eax,%dx ; \
+ add $0x4,%dl /* 1st data port */ ; \
+ mov which,%ax /* register# */ ; \
+ and $0x3,%ax ; \
+ add %al,%dl ; \
+ mov data, %al ; \
+ outb %al,%dx /* write to reg */
+
+#define REGBIS(which, bis) \
+ CS_READ(which) ;\
+ movb bis, %cl ;\
+ orb %al, %cl ;\
+ CS_WRITE(which, %cl)
+
+#define REGBIC(which, bic) \
+ CS_READ(which) ;\
+ movb bic, %cl ;\
+ notb %cl ;\
+ andb %al, %cl ;\
+ CS_WRITE(which, %cl)
+
+
+/* macro to BIC and BIS a reg. calls read a reg,
+ * does a BIC and then a BIS on it.
+ * to clear no bits, make BIC 0.
+ * to set no bits, make BIS 0
+ */
+#define REGBICBIS(which, bic, bis) \
+ CS_READ(which) ;\
+ movb bic, %cl ;\
+ notb %cl ;\
+ andb %cl, %al ;\
+ movb bis, %cl ;\
+ orb %al, %cl ;\
+ CS_WRITE(which, %cl)
+
+#else
+NO FUNCTIONS YET!
+#endif
+
+
+
+/* originally this macro was from STPC BIOS */
+#define intel_chip_post_macro(value) \
+ movb $value, %al ; \
+ outb %al, $0x80
+
+#define INTEL_PDATA_MAGIC 0xdeadbeef
+
+/* SLOW_DOWN_IO is a delay we can use that is roughly cpu neutral,
+ * and can be used before memory or timer chips come up.
+ * Since this hits the isa bus it's roughly
+ */
+#define SLOW_DOWN_IO inb $0x80, %al
+
+#endif /* ROM_INTEL_H */
diff --git a/src/arch/i386/include/arch/io.h b/src/arch/i386/include/arch/io.h
new file mode 100644
index 0000000000..bcba9a932c
--- /dev/null
+++ b/src/arch/i386/include/arch/io.h
@@ -0,0 +1,76 @@
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+
+/*
+ * This file contains the definitions for the x86 IO instructions
+ * inb/inw/inl/outb/outw/outl and the "string versions" of the same
+ * (insb/insw/insl/outsb/outsw/outsl).
+ *
+ * This file is not meant to be obfuscating: it's just complicated
+ * to (a) handle it all in a way that makes gcc able to optimize it
+ * as well as possible and (b) trying to avoid writing the same thing
+ * over and over again with slight variations and possibly making a
+ * mistake somewhere.
+ */
+
+ /*
+ * Bit simplified and optimized by Jan Hubicka
+ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999.
+ */
+
+/*
+ * Talk about misusing macros..
+ */
+#define __OUT1(s,x) \
+extern inline void out##s(unsigned x value, unsigned short port) {
+
+#define __OUT2(s,s1,s2) \
+__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
+
+#define __OUT(s,s1,x) \
+__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); }
+
+#define __IN1(s) \
+extern inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
+
+#define __IN2(s,s1,s2) \
+__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
+
+#define __IN(s,s1,i...) \
+__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; }
+
+#define __INS(s) \
+extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \
+{ __asm__ __volatile__ ("cld ; rep ; ins" #s \
+: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
+
+#define __OUTS(s) \
+extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
+{ __asm__ __volatile__ ("cld ; rep ; outs" #s \
+: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
+
+#define RETURN_TYPE unsigned char
+__IN(b,"")
+#undef RETURN_TYPE
+#define RETURN_TYPE unsigned short
+__IN(w,"")
+#undef RETURN_TYPE
+#define RETURN_TYPE unsigned int
+__IN(l,"")
+#undef RETURN_TYPE
+
+__OUT(b,"b",char)
+__OUT(w,"w",short)
+__OUT(l,,int)
+
+__INS(b)
+__INS(w)
+__INS(l)
+
+__OUTS(b)
+__OUTS(w)
+__OUTS(l)
+
+
+#endif
+
diff --git a/src/arch/i386/include/arch/pciconf.h b/src/arch/i386/include/arch/pciconf.h
new file mode 100644
index 0000000000..8695ee2294
--- /dev/null
+++ b/src/arch/i386/include/arch/pciconf.h
@@ -0,0 +1,9 @@
+#ifndef PCI_CONF_REG_INDEX
+
+// These are defined in the PCI spec, and hence are theoretically
+// inclusive of ANYTHING that uses a PCI bus.
+#define PCI_CONF_REG_INDEX 0xcf8
+#define PCI_CONF_REG_DATA 0xcfc
+#define CONFIG_ADDR(bus,devfn,where) (((bus) << 16) | ((devfn) << 8) | (where))
+
+#endif
diff --git a/src/arch/i386/include/arch/pirq_routing.h b/src/arch/i386/include/arch/pirq_routing.h
new file mode 100644
index 0000000000..215c4e58c8
--- /dev/null
+++ b/src/arch/i386/include/arch/pirq_routing.h
@@ -0,0 +1,54 @@
+#ifndef ARCH_PIRQ_ROUTING_H
+#define ARCH_PIRQ_ROUTING_H
+
+#include <stdint.h>
+
+#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
+#define PIRQ_VERSION 0x0100
+
+struct irq_info {
+ uint8_t bus, devfn; /* Bus, device and function */
+ struct {
+ uint8_t link; /* IRQ line ID, chipset dependent, 0=not routed */
+ uint16_t bitmap; /* Available IRQs */
+ } __attribute__((packed)) irq[4];
+ uint8_t slot; /* Slot number, 0=onboard */
+ uint8_t rfu;
+} __attribute__((packed));
+
+#if defined(IRQ_SLOT_COUNT)
+#define IRQ_SLOTS_COUNT IRQ_SLOT_COUNT
+#elif (__GNUC__ < 3)
+#define IRQ_SLOTS_COUNT 1
+#else
+#define IRQ_SLOTS_COUNT
+#endif
+
+struct irq_routing_table {
+ uint32_t signature; /* PIRQ_SIGNATURE should be here */
+ uint16_t version; /* PIRQ_VERSION */
+ uint16_t size; /* Table size in bytes */
+ uint8_t rtr_bus, rtr_devfn; /* Where the interrupt router lies */
+ uint16_t exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
+ uint16_t rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
+ uint32_t miniport_data; /* Crap */
+ uint8_t rfu[11];
+ uint8_t checksum; /* Modulo 256 checksum must give zero */
+ struct irq_info slots[IRQ_SLOTS_COUNT];
+} __attribute__((packed));
+
+extern const struct irq_routing_table intel_irq_routing_table;
+
+#if defined(DEBUG) && defined(HAVE_PIRQ_TABLE)
+void check_pirq_routing_table(void);
+#else
+#define check_pirq_routing_table() do {} while(0)
+#endif
+
+#if defined(HAVE_PIRQ_TABLE)
+unsigned long copy_pirq_routing_table(unsigned long start);
+#else
+#define copy_pirq_routing_table(start) (start)
+#endif
+
+#endif /* ARCH_PIRQ_ROUTING_H */
diff --git a/src/arch/i386/include/arch/rom_segs.h b/src/arch/i386/include/arch/rom_segs.h
new file mode 100644
index 0000000000..b51a805948
--- /dev/null
+++ b/src/arch/i386/include/arch/rom_segs.h
@@ -0,0 +1,10 @@
+#ifndef ROM_SEGS_H
+#define ROM_SEGS_H
+
+#define ROM_CODE_SEG 0x08
+#define ROM_DATA_SEG 0x10
+
+#define CACHE_RAM_CODE_SEG 0x18
+#define CACHE_RAM_DATA_SEG 0x20
+
+#endif /* ROM_SEGS_H */
diff --git a/src/arch/i386/include/arch/romcc_io.h b/src/arch/i386/include/arch/romcc_io.h
new file mode 100644
index 0000000000..02cc272884
--- /dev/null
+++ b/src/arch/i386/include/arch/romcc_io.h
@@ -0,0 +1,84 @@
+static void outb(unsigned char value, unsigned short port)
+{
+ __builtin_outb(value, port);
+}
+
+static void outw(unsigned short value, unsigned short port)
+{
+ __builtin_outw(value, port);
+}
+
+static void outl(unsigned int value, unsigned short port)
+{
+ __builtin_outl(value, port);
+}
+
+
+static unsigned char inb(unsigned short port)
+{
+ return __builtin_inb(port);
+}
+
+
+static unsigned char inw(unsigned short port)
+{
+ return __builtin_inw(port);
+}
+
+static unsigned char inl(unsigned short port)
+{
+ return __builtin_inl(port);
+}
+
+static void hlt(void)
+{
+ __builtin_hlt();
+}
+
+static unsigned int config_cmd(unsigned char bus, unsigned devfn, unsigned where)
+{
+ return 0x80000000 | (bus << 16) | (devfn << 8) | (where & ~3);
+}
+
+static unsigned char pcibios_read_config_byte(
+ unsigned char bus, unsigned devfn, unsigned where)
+{
+ outl(config_cmd(bus, devfn, where), 0xCF8);
+ return inb(0xCFC + (where & 3));
+}
+
+static unsigned short pcibios_read_config_word(
+ unsigned char bus, unsigned devfn, unsigned where)
+{
+ outl(config_cmd(bus, devfn, where), 0xCF8);
+ return inw(0xCFC + (where & 2));
+}
+
+static unsigned int pcibios_read_config_dword(
+ unsigned char bus, unsigned devfn, unsigned where)
+{
+ outl(config_cmd(bus, devfn, where), 0xCF8);
+ return inl(0xCFC);
+}
+
+
+static void pcibios_write_config_byte(
+ unsigned char bus, unsigned devfn, unsigned where, unsigned char value)
+{
+ outl(config_cmd(bus, devfn, where), 0xCF8);
+ outb(value, 0xCFC + (where & 3));
+}
+
+static void pcibios_write_config_word(
+ unsigned char bus, unsigned devfn, unsigned where, unsigned short value)
+{
+ outl(config_cmd(bus, devfn, where), 0xCF8);
+ outw(value, 0xCFC + (where & 2));
+}
+
+static void pcibios_write_config_dword(
+ unsigned char bus, unsigned devfn, unsigned where, unsigned int value)
+{
+ outl(config_cmd(bus, devfn, where), 0xCF8);
+ outl(value, 0xCFC);
+}
diff --git a/src/arch/i386/include/arch/smp/mpspec.h b/src/arch/i386/include/arch/smp/mpspec.h
new file mode 100644
index 0000000000..305276e482
--- /dev/null
+++ b/src/arch/i386/include/arch/smp/mpspec.h
@@ -0,0 +1,282 @@
+#ifndef __ASM_MPSPEC_H
+#define __ASM_MPSPEC_H
+
+#ifdef HAVE_MP_TABLE
+
+/*
+ * Structure definitions for SMP machines following the
+ * Intel Multiprocessing Specification 1.1 and 1.4.
+ */
+
+/*
+ * This tag identifies where the SMP configuration
+ * information is.
+ */
+
+#define SMP_MAGIC_IDENT (('_'<<24)|('P'<<16)|('M'<<8)|'_')
+
+/*
+ * a maximum of 16 APICs with the current APIC ID architecture.
+ */
+#define MAX_APICS 16
+
+
+#define SMP_FLOATING_TABLE_LEN sizeof(struct intel_mp_floating)
+
+struct intel_mp_floating
+{
+ char mpf_signature[4]; /* "_MP_" */
+ unsigned long mpf_physptr; /* Configuration table address */
+ unsigned char mpf_length; /* Our length (paragraphs) */
+ unsigned char mpf_specification;/* Specification version */
+ unsigned char mpf_checksum; /* Checksum (makes sum 0) */
+ unsigned char mpf_feature1; /* Standard or configuration ? */
+ unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */
+ unsigned char mpf_feature3; /* Unused (0) */
+ unsigned char mpf_feature4; /* Unused (0) */
+ unsigned char mpf_feature5; /* Unused (0) */
+};
+
+struct mp_config_table
+{
+ char mpc_signature[4];
+#define MPC_SIGNATURE "PCMP"
+ unsigned short mpc_length; /* Size of table */
+ char mpc_spec; /* 0x01 */
+ char mpc_checksum;
+ char mpc_oem[8];
+ char mpc_productid[12];
+ unsigned long mpc_oemptr; /* 0 if not present */
+ unsigned short mpc_oemsize; /* 0 if not present */
+ unsigned short mpc_entry_count;
+ unsigned long mpc_lapic; /* APIC address */
+ unsigned short mpe_length; /* Extended Table size */
+ unsigned char mpe_checksum; /* Extended Table checksum */
+ unsigned char reserved;
+};
+
+/* Followed by entries */
+
+#define MP_PROCESSOR 0
+#define MP_BUS 1
+#define MP_IOAPIC 2
+#define MP_INTSRC 3
+#define MP_LINTSRC 4
+
+struct mpc_config_processor
+{
+ unsigned char mpc_type;
+ unsigned char mpc_apicid; /* Local APIC number */
+ unsigned char mpc_apicver; /* Its versions */
+ unsigned char mpc_cpuflag;
+#define MPC_CPU_ENABLED 1 /* Processor is available */
+#define MPC_CPU_BOOTPROCESSOR 2 /* Processor is the BP */
+ unsigned long mpc_cpufeature;
+#define MPC_CPU_STEPPING_MASK 0x0F
+#define MPC_CPU_MODEL_MASK 0xF0
+#define MPC_CPU_FAMILY_MASK 0xF00
+ unsigned long mpc_featureflag; /* CPUID feature value */
+ unsigned long mpc_reserved[2];
+};
+
+struct mpc_config_bus
+{
+ unsigned char mpc_type;
+ unsigned char mpc_busid;
+ unsigned char mpc_bustype[6] __attribute((packed));
+};
+
+#define BUSTYPE_EISA "EISA"
+#define BUSTYPE_ISA "ISA"
+#define BUSTYPE_INTERN "INTERN" /* Internal BUS */
+#define BUSTYPE_MCA "MCA"
+#define BUSTYPE_VL "VL" /* Local bus */
+#define BUSTYPE_PCI "PCI"
+#define BUSTYPE_PCMCIA "PCMCIA"
+
+struct mpc_config_ioapic
+{
+ unsigned char mpc_type;
+ unsigned char mpc_apicid;
+ unsigned char mpc_apicver;
+ unsigned char mpc_flags;
+#define MPC_APIC_USABLE 0x01
+ unsigned long mpc_apicaddr;
+};
+
+struct mpc_config_intsrc
+{
+ unsigned char mpc_type;
+ unsigned char mpc_irqtype;
+ unsigned short mpc_irqflag;
+ unsigned char mpc_srcbus;
+ unsigned char mpc_srcbusirq;
+ unsigned char mpc_dstapic;
+ unsigned char mpc_dstirq;
+};
+
+enum mp_irq_source_types {
+ mp_INT = 0,
+ mp_NMI = 1,
+ mp_SMI = 2,
+ mp_ExtINT = 3
+};
+
+#define MP_IRQ_POLARITY_DEFAULT 0x0
+#define MP_IRQ_POLARITY_HIGH 0x1
+#define MP_IRQ_POLARITY_LOW 0x3
+#define MP_IRQ_POLARITY_MASK 0x3
+#define MP_IRQ_TRIGGER_DEFAULT 0x0
+#define MP_IRQ_TRIGGER_EDGE 0x4
+#define MP_IRQ_TRIGGER_LEVEL 0xc
+#define MP_IRQ_TRIGGER_MASK 0xc
+
+
+struct mpc_config_lintsrc
+{
+ unsigned char mpc_type;
+ unsigned char mpc_irqtype;
+ unsigned short mpc_irqflag;
+ unsigned char mpc_srcbusid;
+ unsigned char mpc_srcbusirq;
+ unsigned char mpc_destapic;
+#define MP_APIC_ALL 0xFF
+ unsigned char mpc_destapiclint;
+};
+
+/*
+ * Default configurations
+ *
+ * 1 2 CPU ISA 82489DX
+ * 2 2 CPU EISA 82489DX neither IRQ 0 timer nor IRQ 13 DMA chaining
+ * 3 2 CPU EISA 82489DX
+ * 4 2 CPU MCA 82489DX
+ * 5 2 CPU ISA+PCI
+ * 6 2 CPU EISA+PCI
+ * 7 2 CPU MCA+PCI
+ */
+
+#define MAX_IRQ_SOURCES 128
+#define MAX_MP_BUSSES 32
+enum mp_bustype {
+ MP_BUS_ISA,
+ MP_BUS_EISA,
+ MP_BUS_PCI,
+ MP_BUS_MCA
+};
+
+/* Followed by entries */
+
+#define MPE_SYSTEM_ADDRESS_SPACE 0x80
+#define MPE_BUS_HIERARCHY 0x81
+#define MPE_COMPATIBILITY_ADDRESS_SPACE 0x82
+
+struct mp_exten_config {
+ unsigned char mpe_type;
+ unsigned char mpe_length;
+};
+
+typedef struct mp_exten_config *mpe_t;
+
+struct mp_exten_system_address_space {
+ unsigned char mpe_type;
+ unsigned char mpe_length;
+ unsigned char mpe_busid;
+ unsigned char mpe_address_type;
+#define ADDRESS_TYPE_IO 0
+#define ADDRESS_TYPE_MEM 1
+#define ADDRESS_TYPE_PREFETCH 2
+ unsigned int mpe_address_base_low;
+ unsigned int mpe_address_base_high;
+ unsigned int mpe_address_length_low;
+ unsigned int mpe_address_length_high;
+};
+
+struct mp_exten_bus_hierarchy {
+ unsigned char mpe_type;
+ unsigned char mpe_length;
+ unsigned char mpe_busid;
+ unsigned char mpe_bus_info;
+#define BUS_SUBTRACTIVE_DECODE 1
+ unsigned char mpe_parent_busid;
+ unsigned char reserved[3];
+};
+
+struct mp_exten_compatibility_address_space {
+ unsigned char mpe_type;
+ unsigned char mpe_length;
+ unsigned char mpe_busid;
+ unsigned char mpe_address_modifier;
+#define ADDRESS_RANGE_SUBTRACT 1
+#define ADDRESS_RANGE_ADD 0
+ unsigned int mpe_range_list;
+#define RANGE_LIST_IO_ISA 0
+ /* X100 - X3FF
+ * X500 - X7FF
+ * X900 - XBFF
+ * XD00 - XFFF
+ */
+#define RANGE_LIST_IO_VGA 1
+ /* X3B0 - X3BB
+ * X3C0 - X3DF
+ * X7B0 - X7BB
+ * X7C0 - X7DF
+ * XBB0 - XBBB
+ * XBC0 - XBDF
+ * XFB0 - XFBB
+ * XFC0 - XCDF
+ */
+};
+
+/* Default local apic addr */
+#define LAPIC_ADDR 0xFEE00000
+
+void *smp_next_mpc_entry(struct mp_config_table *mc);
+void *smp_next_mpe_entry(struct mp_config_table *mc);
+
+void smp_write_processor(struct mp_config_table *mc,
+ unsigned char apicid, unsigned char apicver,
+ unsigned char cpuflag, unsigned int cpufeature,
+ unsigned int featureflag);
+void smp_write_processors(struct mp_config_table *mc,
+ unsigned long *processor_map);
+void smp_write_bus(struct mp_config_table *mc,
+ unsigned char id, unsigned char *bustype);
+void smp_write_ioapic(struct mp_config_table *mc,
+ unsigned char id, unsigned char ver,
+ unsigned long apicaddr);
+void smp_write_intsrc(struct mp_config_table *mc,
+ unsigned char irqtype, unsigned short irqflag,
+ unsigned char srcbus, unsigned char srcbusirq,
+ unsigned char dstapic, unsigned char dstirq);
+void smp_write_lintsrc(struct mp_config_table *mc,
+ unsigned char irqtype, unsigned short irqflag,
+ unsigned char srcbusid, unsigned char srcbusirq,
+ unsigned char destapic, unsigned char destapiclint);
+void smp_write_address_space(struct mp_config_table *mc,
+ unsigned char busid, unsigned char address_type,
+ unsigned int address_base_low, unsigned int address_base_high,
+ unsigned int address_length_low, unsigned int address_length_high);
+void smp_write_bus_hierarchy(struct mp_config_table *mc,
+ unsigned char busid, unsigned char bus_info,
+ unsigned char parent_busid);
+void smp_write_compatibility_address_space(struct mp_config_table *mc,
+ unsigned char busid, unsigned char address_modifier,
+ unsigned int range_list);
+unsigned char smp_compute_checksum(void *v, int len);
+void *smp_write_floating_table(unsigned long addr);
+unsigned long write_smp_table(unsigned long addr, unsigned long *processor_map);
+
+/* A table (per mainboard) listing the initial apicid of each cpu. */
+extern unsigned long initial_apicid[MAX_CPUS];
+
+#else /* HAVE_MP_TABLE */
+static inline
+unsigned long write_smp_table(unsigned long addr, unsigned long *processor_map)
+{
+ return addr;
+}
+#endif /* HAVE_MP_TABLE */
+
+#endif
+
diff --git a/src/arch/i386/include/bitops.h b/src/arch/i386/include/bitops.h
new file mode 100644
index 0000000000..fae2045b9a
--- /dev/null
+++ b/src/arch/i386/include/bitops.h
@@ -0,0 +1,20 @@
+#ifndef I386_BITOPS_H
+#define I386_BITOPS_H
+
+/**
+ * log2 - Find the truncated log base 2 of x
+ */
+
+static inline unsigned long log2(unsigned long x)
+{
+ unsigned long r = 0;
+ __asm__(
+ "bsrl %1, %0\n\t"
+ "jnz 1f\n\t"
+ "movl $-1, %0\n\t"
+ "1:\n\t"
+ : "=r" (r) : "r" (x));
+ return r;
+
+}
+#endif /* I386_BITOPS_H */
diff --git a/src/arch/i386/include/stddef.h b/src/arch/i386/include/stddef.h
new file mode 100644
index 0000000000..4bf6b0a867
--- /dev/null
+++ b/src/arch/i386/include/stddef.h
@@ -0,0 +1,15 @@
+#ifndef I386_STDDEF_H
+#define I386_STDDEF_H
+
+typedef long ptrdiff_t;
+typedef unsigned long size_t;
+typedef long ssize_t;
+
+typedef int wchar_t;
+typedef unsigned int wint_t;
+
+#define NULL 0
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+#endif /* I386_STDDEF_H */
diff --git a/src/arch/i386/include/stdint.h b/src/arch/i386/include/stdint.h
new file mode 100644
index 0000000000..58d7519cde
--- /dev/null
+++ b/src/arch/i386/include/stdint.h
@@ -0,0 +1,52 @@
+#ifndef I386_STDINT_H
+#define I386_STDINT_H
+
+/* Exact integral types */
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+
+typedef unsigned short uint16_t;
+typedef signed short int16_t;
+
+typedef unsigned int uint32_t;
+typedef signed int int32_t;
+
+typedef unsigned long long uint64_t;
+typedef signed long long int64_t;
+
+/* Small types */
+typedef unsigned char uint_least8_t;
+typedef signed char int_least8_t;
+
+typedef unsigned short uint_least16_t;
+typedef signed short int_least16_t;
+
+typedef unsigned int uint_least32_t;
+typedef signed int int_least32_t;
+
+typedef unsigned long long uint_least64_t;
+typedef signed long long int_least64_t;
+
+/* Fast Types */
+typedef unsigned char uint_fast8_t;
+typedef signed char int_fast8_t;
+
+typedef unsigned int uint_fast16_t;
+typedef signed int int_fast16_t;
+
+typedef unsigned int uint_fast32_t;
+typedef signed int int_fast32_t;
+
+typedef unsigned long long uint_fast64_t;
+typedef signed long long int_fast64_t;
+
+/* Types for `void *' pointers. */
+typedef int intptr_t;
+typedef unsigned int uintptr_t;
+
+/* Largest integral types */
+typedef long long int intmax_t;
+typedef unsigned long long uintmax_t;
+
+
+#endif /* I386_STDINT_H */