Merge branch 'master' of git://git.denx.de/u-boot-x86
authorTom Rini <trini@ti.com>
Fri, 7 Dec 2012 13:43:40 +0000 (06:43 -0700)
committerTom Rini <trini@ti.com>
Fri, 7 Dec 2012 15:47:59 +0000 (08:47 -0700)
44 files changed:
README
arch/x86/cpu/coreboot/Makefile
arch/x86/cpu/coreboot/car.S [moved from arch/x86/cpu/coreboot/coreboot_car.S with 100% similarity]
arch/x86/cpu/coreboot/config.mk [new file with mode: 0644]
arch/x86/cpu/coreboot/coreboot.c
arch/x86/cpu/coreboot/sdram.c
arch/x86/cpu/coreboot/timestamp.c [new file with mode: 0644]
arch/x86/cpu/cpu.c
arch/x86/cpu/interrupts.c
arch/x86/cpu/start.S
arch/x86/cpu/start16.S
arch/x86/dts/coreboot.dtsi [new file with mode: 0644]
arch/x86/dts/skeleton.dtsi [new file with mode: 0644]
arch/x86/include/asm/arch-coreboot/timestamp.h [new file with mode: 0644]
arch/x86/include/asm/cache.h
arch/x86/include/asm/control_regs.h [new file with mode: 0644]
arch/x86/include/asm/global_data.h
arch/x86/include/asm/gpio.h [new file with mode: 0644]
arch/x86/include/asm/init_helpers.h
arch/x86/include/asm/io.h
arch/x86/include/asm/msr-index.h [new file with mode: 0644]
arch/x86/include/asm/msr.h [new file with mode: 0644]
arch/x86/include/asm/mtrr.h [new file with mode: 0644]
arch/x86/include/asm/types.h
arch/x86/include/asm/u-boot-x86.h
arch/x86/lib/Makefile
arch/x86/lib/board.c
arch/x86/lib/init_helpers.c
arch/x86/lib/init_wrappers.c
arch/x86/lib/physmem.c [new file with mode: 0644]
arch/x86/lib/relocate.c
arch/x86/lib/timer.c
arch/x86/lib/zimage.c
board/chromebook-x86/dts/alex.dts [moved from board/chromebook-x86/dts/x86-alex.dts with 53% similarity]
board/chromebook-x86/dts/link.dts [new file with mode: 0644]
boards.cfg
drivers/gpio/Makefile
drivers/gpio/intel_ich6_gpio.c [new file with mode: 0644]
drivers/video/cfb_console.c
include/configs/coreboot.h
include/pci.h
include/physmem.h [new file with mode: 0644]
lib/Makefile
lib/physmem.c [new file with mode: 0644]

diff --git a/README b/README
index 06f5ef2354d6983df2f686a7d51bffd49dec3cda..5a86ae9c5f9188dd53a8b54ce3eb9554f2485f41 100644 (file)
--- a/README
+++ b/README
@@ -1414,6 +1414,13 @@ CBFS (Coreboot Filesystem) support
                boot.  See the documentation file README.video for a
                description of this variable.
 
+               CONFIG_VIDEO_VGA
+
+               Enable the VGA video / BIOS for x86. The alternative if you
+               are using coreboot is to use the coreboot frame buffer
+               driver.
+
+
 - Keyboard Support:
                CONFIG_KEYBOARD
 
@@ -2205,6 +2212,14 @@ CBFS (Coreboot Filesystem) support
                        HERMES, IP860, RPXlite, LWMON,
                        FLAGADM, TQM8260
 
+- Access to physical memory region (> 4GB)
+               Some basic support is provided for operations on memory not
+               normally accessible to U-Boot - e.g. some architectures
+               support access to more than 4GB of memory on 32-bit
+               machines using physical address extension or similar.
+               Define CONFIG_PHYSMEM to access this basic support, which
+               currently only supports clearing the memory.
+
 - Error Recovery:
                CONFIG_PANIC_HANG
 
index 2afd30cd52b77712a81b8a20af0bc8ef2dbe9e7e..b1d3e959f8f63d4f88570973dc415c03995865c0 100644 (file)
@@ -33,14 +33,14 @@ include $(TOPDIR)/config.mk
 
 LIB    := $(obj)lib$(SOC).o
 
+SOBJS-$(CONFIG_SYS_COREBOOT) += car.o
 COBJS-$(CONFIG_SYS_COREBOOT) += coreboot.o
 COBJS-$(CONFIG_SYS_COREBOOT) += tables.o
 COBJS-$(CONFIG_SYS_COREBOOT) += ipchecksum.o
 COBJS-$(CONFIG_SYS_COREBOOT) += sdram.o
+COBJS-$(CONFIG_SYS_COREBOOT) += timestamp.o
 COBJS-$(CONFIG_PCI) += pci.o
 
-SOBJS-$(CONFIG_SYS_COREBOOT) += coreboot_car.o
-
 SRCS   := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
 OBJS   := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
 
diff --git a/arch/x86/cpu/coreboot/config.mk b/arch/x86/cpu/coreboot/config.mk
new file mode 100644 (file)
index 0000000..4858fc3
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2012 The Chromium OS Authors.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+CONFIG_ARCH_DEVICE_TREE := coreboot
index 22a643c9d6bc8098200866471c9b784dc5e8b163..9c9431e0d9dc3f869884f6b10d2d4c0bd147d4ef 100644 (file)
 #include <asm/u-boot-x86.h>
 #include <flash.h>
 #include <netdev.h>
+#include <asm/msr.h>
+#include <asm/cache.h>
+#include <asm/io.h>
 #include <asm/arch-coreboot/tables.h>
 #include <asm/arch-coreboot/sysinfo.h>
+#include <asm/arch/timestamp.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-unsigned long monitor_flash_len = CONFIG_SYS_MONITOR_LEN;
-
 /*
  * Miscellaneous platform dependent initializations
  */
@@ -41,6 +43,9 @@ int cpu_init_f(void)
        int ret = get_coreboot_info(&lib_sysinfo);
        if (ret != 0)
                printf("Failed to parse coreboot tables.\n");
+
+       timestamp_init();
+
        return ret;
 }
 
@@ -62,8 +67,29 @@ int board_early_init_r(void)
 
 void show_boot_progress(int val)
 {
-}
+#if MIN_PORT80_KCLOCKS_DELAY
+       static uint32_t prev_stamp;
+       static uint32_t base;
+
+       /*
+        * Scale the time counter reading to avoid using 64 bit arithmetics.
+        * Can't use get_timer() here becuase it could be not yet
+        * initialized or even implemented.
+        */
+       if (!prev_stamp) {
+               base = rdtsc() / 1000;
+               prev_stamp = 0;
+       } else {
+               uint32_t now;
 
+               do {
+                       now = rdtsc() / 1000 - base;
+               } while (now < (prev_stamp + MIN_PORT80_KCLOCKS_DELAY));
+               prev_stamp = now;
+       }
+#endif
+       outb(val, 0x80);
+}
 
 int last_stage_init(void)
 {
@@ -82,6 +108,33 @@ int board_eth_init(bd_t *bis)
        return pci_eth_init(bis);
 }
 
-void setup_pcat_compatibility()
+#define MTRR_TYPE_WP          5
+#define MTRRcap_MSR           0xfe
+#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
+#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
+
+int board_final_cleanup(void)
 {
+       /* Un-cache the ROM so the kernel has one
+        * more MTRR available.
+        *
+        * Coreboot should have assigned this to the
+        * top available variable MTRR.
+        */
+       u8 top_mtrr = (native_read_msr(MTRRcap_MSR) & 0xff) - 1;
+       u8 top_type = native_read_msr(MTRRphysBase_MSR(top_mtrr)) & 0xff;
+
+       /* Make sure this MTRR is the correct Write-Protected type */
+       if (top_type == MTRR_TYPE_WP) {
+               disable_caches();
+               wrmsrl(MTRRphysBase_MSR(top_mtrr), 0);
+               wrmsrl(MTRRphysMask_MSR(top_mtrr), 0);
+               enable_caches();
+       }
+
+       /* Issue SMI to Coreboot to lock down ME and registers */
+       printf("Finalizing Coreboot\n");
+       outb(0xcb, 0xb2);
+
+       return 0;
 }
index f8fdac6319eebde8d44a88c51b49dca625538025..76274cb88e3824ea3b066afffd7068c2b97832d8 100644 (file)
@@ -27,8 +27,9 @@
 #include <asm/e820.h>
 #include <asm/u-boot-x86.h>
 #include <asm/global_data.h>
-#include <asm/arch-coreboot/sysinfo.h>
-#include <asm/arch-coreboot/tables.h>
+#include <asm/processor.h>
+#include <asm/arch/sysinfo.h>
+#include <asm/arch/tables.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -51,6 +52,58 @@ unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
        return num_entries;
 }
 
+/*
+ * This function looks for the highest region of memory lower than 4GB which
+ * has enough space for U-Boot where U-Boot is aligned on a page boundary. It
+ * overrides the default implementation found elsewhere which simply picks the
+ * end of ram, wherever that may be. The location of the stack, the relocation
+ * address, and how far U-Boot is moved by relocation are set in the global
+ * data structure.
+ */
+int calculate_relocation_address(void)
+{
+       const uint64_t uboot_size = (uintptr_t)&__bss_end -
+                       (uintptr_t)&__text_start;
+       const uint64_t total_size = uboot_size + CONFIG_SYS_MALLOC_LEN +
+               CONFIG_SYS_STACK_SIZE;
+       uintptr_t dest_addr = 0;
+       int i;
+
+       for (i = 0; i < lib_sysinfo.n_memranges; i++) {
+               struct memrange *memrange = &lib_sysinfo.memrange[i];
+               /* Force U-Boot to relocate to a page aligned address. */
+               uint64_t start = roundup(memrange->base, 1 << 12);
+               uint64_t end = memrange->base + memrange->size;
+
+               /* Ignore non-memory regions. */
+               if (memrange->type != CB_MEM_RAM)
+                       continue;
+
+               /* Filter memory over 4GB. */
+               if (end > 0xffffffffULL)
+                       end = 0x100000000ULL;
+               /* Skip this region if it's too small. */
+               if (end - start < total_size)
+                       continue;
+
+               /* Use this address if it's the largest so far. */
+               if (end - uboot_size > dest_addr)
+                       dest_addr = end;
+       }
+
+       /* If no suitable area was found, return an error. */
+       if (!dest_addr)
+               return 1;
+
+       dest_addr -= uboot_size;
+       dest_addr &= ~((1 << 12) - 1);
+       gd->relocaddr = dest_addr;
+       gd->reloc_off = dest_addr - (uintptr_t)&__text_start;
+       gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN;
+
+       return 0;
+}
+
 int dram_init_f(void)
 {
        int i;
@@ -71,5 +124,20 @@ int dram_init_f(void)
 
 int dram_init(void)
 {
+       int i, j;
+
+       if (CONFIG_NR_DRAM_BANKS) {
+               for (i = 0, j = 0; i < lib_sysinfo.n_memranges; i++) {
+                       struct memrange *memrange = &lib_sysinfo.memrange[i];
+
+                       if (memrange->type == CB_MEM_RAM) {
+                               gd->bd->bi_dram[j].start = memrange->base;
+                               gd->bd->bi_dram[j].size = memrange->size;
+                               j++;
+                               if (j >= CONFIG_NR_DRAM_BANKS)
+                                       break;
+                       }
+               }
+       }
        return 0;
 }
diff --git a/arch/x86/cpu/coreboot/timestamp.c b/arch/x86/cpu/coreboot/timestamp.c
new file mode 100644 (file)
index 0000000..2ca7a57
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#include <common.h>
+#include <asm/arch/timestamp.h>
+#include <asm/arch/sysinfo.h>
+#include <linux/compiler.h>
+
+struct timestamp_entry {
+       uint32_t        entry_id;
+       uint64_t        entry_stamp;
+} __packed;
+
+struct timestamp_table {
+       uint64_t        base_time;
+       uint32_t        max_entries;
+       uint32_t        num_entries;
+       struct timestamp_entry entries[0]; /* Variable number of entries */
+} __packed;
+
+static struct timestamp_table *ts_table  __attribute__((section(".data")));
+
+void timestamp_init(void)
+{
+       ts_table = lib_sysinfo.tstamp_table;
+       timer_set_tsc_base(ts_table->base_time);
+       timestamp_add_now(TS_U_BOOT_INITTED);
+}
+
+void timestamp_add(enum timestamp_id id, uint64_t ts_time)
+{
+       struct timestamp_entry *tse;
+
+       if (!ts_table || (ts_table->num_entries == ts_table->max_entries))
+               return;
+
+       tse = &ts_table->entries[ts_table->num_entries++];
+       tse->entry_id = id;
+       tse->entry_stamp = ts_time - ts_table->base_time;
+}
+
+void timestamp_add_now(enum timestamp_id id)
+{
+       timestamp_add(id, rdtsc());
+}
index fabfbd1bf7f9f5deb40ffdcf04f81ec42eb6c52b..315e87afeb2120e4dab4929f7a6eac225348cfa6 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <asm/control_regs.h>
 #include <asm/processor.h>
 #include <asm/processor-flags.h>
 #include <asm/interrupt.h>
@@ -147,16 +148,27 @@ int cpu_init_r(void) __attribute__((weak, alias("x86_cpu_init_r")));
 
 void x86_enable_caches(void)
 {
-       const u32 nw_cd_rst = ~(X86_CR0_NW | X86_CR0_CD);
+       unsigned long cr0;
 
-       /* turn on the cache and disable write through */
-       asm("movl       %%cr0, %%eax\n"
-           "andl       %0, %%eax\n"
-           "movl       %%eax, %%cr0\n"
-           "wbinvd\n" : : "i" (nw_cd_rst) : "eax");
+       cr0 = read_cr0();
+       cr0 &= ~(X86_CR0_NW | X86_CR0_CD);
+       write_cr0(cr0);
+       wbinvd();
 }
 void enable_caches(void) __attribute__((weak, alias("x86_enable_caches")));
 
+void x86_disable_caches(void)
+{
+       unsigned long cr0;
+
+       cr0 = read_cr0();
+       cr0 |= X86_CR0_NW | X86_CR0_CD;
+       wbinvd();
+       write_cr0(cr0);
+       wbinvd();
+}
+void disable_caches(void) __attribute__((weak, alias("x86_disable_caches")));
+
 int x86_init_cache(void)
 {
        enable_caches();
@@ -200,3 +212,17 @@ void __reset_cpu(ulong addr)
        generate_gpf();                 /* start the show */
 }
 void reset_cpu(ulong addr) __attribute__((weak, alias("__reset_cpu")));
+
+int dcache_status(void)
+{
+       return !(read_cr0() & 0x40000000);
+}
+
+/* Define these functions to allow ehch-hcd to function */
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+}
index 43ec3f8b081fc2bf891fb70bf1e2f0af46793f78..dd30a05a9ddf54a97d69a62e29aa26c7e3bd0106 100644 (file)
  */
 
 #include <common.h>
+#include <asm/cache.h>
+#include <asm/control_regs.h>
 #include <asm/interrupt.h>
 #include <asm/io.h>
 #include <asm/processor-flags.h>
 #include <linux/compiler.h>
+#include <asm/msr.h>
+#include <asm/u-boot-x86.h>
 
 #define DECLARE_INTERRUPT(x) \
        ".globl irq_"#x"\n" \
        "pushl $"#x"\n" \
        "jmp irq_common_entry\n"
 
-/*
- * Volatile isn't enough to prevent the compiler from reordering the
- * read/write functions for the control registers and messing everything up.
- * A memory clobber would solve the problem, but would prevent reordering of
- * all loads stores around it, which can hurt performance. Solution is to
- * use a variable and mimic reads and writes to it to enforce serialisation
- */
-static unsigned long __force_order;
-
-static inline unsigned long read_cr0(void)
-{
-       unsigned long val;
-       asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order));
-       return val;
-}
-
-static inline unsigned long read_cr2(void)
-{
-       unsigned long val;
-       asm volatile("mov %%cr2,%0\n\t" : "=r" (val), "=m" (__force_order));
-       return val;
-}
-
-static inline unsigned long read_cr3(void)
-{
-       unsigned long val;
-       asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order));
-       return val;
-}
-
-static inline unsigned long read_cr4(void)
-{
-       unsigned long val;
-       asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order));
-       return val;
-}
-
-static inline unsigned long get_debugreg(int regno)
-{
-       unsigned long val = 0;  /* Damn you, gcc! */
-
-       switch (regno) {
-       case 0:
-               asm("mov %%db0, %0" : "=r" (val));
-               break;
-       case 1:
-               asm("mov %%db1, %0" : "=r" (val));
-               break;
-       case 2:
-               asm("mov %%db2, %0" : "=r" (val));
-               break;
-       case 3:
-               asm("mov %%db3, %0" : "=r" (val));
-               break;
-       case 6:
-               asm("mov %%db6, %0" : "=r" (val));
-               break;
-       case 7:
-               asm("mov %%db7, %0" : "=r" (val));
-               break;
-       default:
-               val = 0;
-       }
-       return val;
-}
-
 void dump_regs(struct irq_regs *regs)
 {
        unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
@@ -679,3 +617,32 @@ asm(".globl irq_common_entry\n" \
        DECLARE_INTERRUPT(253) \
        DECLARE_INTERRUPT(254) \
        DECLARE_INTERRUPT(255));
+
+#if defined(CONFIG_INTEL_CORE_ARCH)
+/*
+ * Get the number of CPU time counter ticks since it was read first time after
+ * restart. This yields a free running counter guaranteed to take almost 6
+ * years to wrap around even at 100GHz clock rate.
+ */
+u64 get_ticks(void)
+{
+       static u64 tick_base;
+       u64 now_tick = rdtsc();
+
+       if (!tick_base)
+               tick_base = now_tick;
+
+       return now_tick - tick_base;
+}
+
+#define PLATFORM_INFO_MSR 0xce
+
+unsigned long get_tbclk(void)
+{
+       u32 ratio;
+       u64 platform_info = native_read_msr(PLATFORM_INFO_MSR);
+
+       ratio = (platform_info >> 8) & 0xff;
+       return 100 * 1000 * 1000 * ratio; /* 100MHz times Max Non Turbo ratio */
+}
+#endif
index ec12e8044fd92a6f4c8fcf24057bb19f3645324f..e960e21f6e49d88979b3b502e163f646920dc41d 100644 (file)
@@ -55,8 +55,16 @@ _x86boot_start:
        movl    %eax, %cr0
        wbinvd
 
+       /* Tell 32-bit code it is being entered from an in-RAM copy */
+       movw    $GD_FLG_WARM_BOOT, %bx
+       jmp     1f
 _start:
-       /* This is the 32-bit cold-reset entry point */
+       /*
+        * This is the 32-bit cold-reset entry point. Initialize %bx to 0
+        * in case we're preceeded by some sort of boot stub.
+        */
+       movw    $GD_FLG_COLD_BOOT, %bx
+1:
 
        /* Load the segement registes to match the gdt loaded in start16.S */
        movl    $(X86_GDT_ENTRY_32BIT_DS * X86_GDT_ENTRY_SIZE), %eax
index cc393ff54fccce6efe6cdf84df983bf03cb561ce..603bf1d2d3ecf8a05ae79c54e2bd4dd267800432 100644 (file)
@@ -37,6 +37,9 @@
 .code16
 .globl start16
 start16:
+       /* Set the Cold Boot / Hard Reset flag */
+       movl    $GD_FLG_COLD_BOOT, %ebx
+
        /*
         * First we let the BSP do some early initialization
         * this code have to map the flash to its final position
diff --git a/arch/x86/dts/coreboot.dtsi b/arch/x86/dts/coreboot.dtsi
new file mode 100644 (file)
index 0000000..4862a59
--- /dev/null
@@ -0,0 +1,16 @@
+/include/ "skeleton.dtsi"
+
+/ {
+       aliases {
+               console = "/serial";
+       };
+
+       serial {
+               compatible = "ns16550";
+               reg-shift = <1>;
+               io-mapped = <1>;
+               multiplier = <1>;
+               baudrate = <115200>;
+               status = "disabled";
+       };
+};
diff --git a/arch/x86/dts/skeleton.dtsi b/arch/x86/dts/skeleton.dtsi
new file mode 100644 (file)
index 0000000..b41d241
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Skeleton device tree; the bare minimum needed to boot; just include and
+ * add a compatible value.  The bootloader will typically populate the memory
+ * node.
+ */
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       chosen { };
+       aliases { };
+       memory { device_type = "memory"; reg = <0 0>; };
+};
diff --git a/arch/x86/include/asm/arch-coreboot/timestamp.h b/arch/x86/include/asm/arch-coreboot/timestamp.h
new file mode 100644 (file)
index 0000000..d104912
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#ifndef __COREBOOT_TIMESTAMP_H__
+#define __COREBOOT_TIMESTAMP_H__
+
+enum timestamp_id {
+       /* coreboot specific timestamp IDs */
+       TS_START_ROMSTAGE = 1,
+       TS_BEFORE_INITRAM = 2,
+       TS_AFTER_INITRAM = 3,
+       TS_END_ROMSTAGE = 4,
+       TS_START_COPYRAM = 8,
+       TS_END_COPYRAM = 9,
+       TS_START_RAMSTAGE = 10,
+       TS_DEVICE_ENUMERATE = 30,
+       TS_DEVICE_CONFIGURE = 40,
+       TS_DEVICE_ENABLE = 50,
+       TS_DEVICE_INITIALIZE = 60,
+       TS_DEVICE_DONE = 70,
+       TS_CBMEM_POST = 75,
+       TS_WRITE_TABLES = 80,
+       TS_LOAD_PAYLOAD = 90,
+       TS_ACPI_WAKE_JUMP = 98,
+       TS_SELFBOOT_JUMP = 99,
+
+       /* U-Boot entry IDs start at 1000 */
+       TS_U_BOOT_INITTED = 1000, /* This is where u-boot starts */
+       TS_U_BOOT_START_KERNEL = 1100, /* Right before jumping to kernel. */
+};
+
+void timestamp_init(void);
+void timestamp_add(enum timestamp_id id, uint64_t ts_time);
+void timestamp_add_now(enum timestamp_id id);
+
+#endif
index 87c9e0be42b5a248f8bbe0929a57e4ea5838311e..d4678d4916fb24afbdb2c5bf41d7e536ea59a0e6 100644 (file)
 #define ARCH_DMA_MINALIGN      64
 #endif
 
+static inline void wbinvd(void)
+{
+       asm volatile ("wbinvd" : : : "memory");
+}
+
+static inline void invd(void)
+{
+       asm volatile("invd" : : : "memory");
+}
+
+/* Enable caches and write buffer */
+void enable_caches(void);
+
+/* Disable caches and write buffer */
+void disable_caches(void);
+
 #endif /* __X86_CACHE_H__ */
diff --git a/arch/x86/include/asm/control_regs.h b/arch/x86/include/asm/control_regs.h
new file mode 100644 (file)
index 0000000..aa8be30
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ *
+ * (C) Copyright 2008-2011
+ * Graeme Russ, <graeme.russ@gmail.com>
+ *
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
+ *
+ * Portions of this file are derived from the Linux kernel source
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __X86_CONTROL_REGS_H
+#define __X86_CONTROL_REGS_H
+
+/*
+ * The memory clobber prevents the GCC from reordering the read/write order
+ * of CR0
+*/
+static inline unsigned long read_cr0(void)
+{
+       unsigned long val;
+
+       asm volatile ("movl %%cr0, %0" : "=r" (val) : : "memory");
+       return val;
+}
+
+static inline void write_cr0(unsigned long val)
+{
+       asm volatile ("movl %0, %%cr0" : : "r" (val) : "memory");
+}
+
+static inline unsigned long read_cr2(void)
+{
+       unsigned long val;
+
+       asm volatile("mov %%cr2,%0\n\t" : "=r" (val) : : "memory");
+       return val;
+}
+
+static inline unsigned long read_cr3(void)
+{
+       unsigned long val;
+
+       asm volatile("mov %%cr3,%0\n\t" : "=r" (val) : : "memory");
+       return val;
+}
+
+static inline unsigned long read_cr4(void)
+{
+       unsigned long val;
+
+       asm volatile("mov %%cr4,%0\n\t" : "=r" (val) : : "memory");
+       return val;
+}
+
+static inline unsigned long get_debugreg(int regno)
+{
+       unsigned long val = 0;  /* Damn you, gcc! */
+
+       switch (regno) {
+       case 0:
+               asm("mov %%db0, %0" : "=r" (val));
+               break;
+       case 1:
+               asm("mov %%db1, %0" : "=r" (val));
+               break;
+       case 2:
+               asm("mov %%db2, %0" : "=r" (val));
+               break;
+       case 3:
+               asm("mov %%db3, %0" : "=r" (val));
+               break;
+       case 6:
+               asm("mov %%db6, %0" : "=r" (val));
+               break;
+       case 7:
+               asm("mov %%db7, %0" : "=r" (val));
+               break;
+       default:
+               val = 0;
+       }
+       return val;
+}
+
+#endif
index 35110a33322d8b7573d7b8ed9c5ce40057c322fa..dc6402b67dba5425a19d526749ca0d73db35806b 100644 (file)
@@ -78,6 +78,12 @@ static inline gd_t *get_fs_gd_ptr(void)
 
 #include <asm-generic/global_data_flags.h>
 
+/*
+ * Our private Global Data Flags
+ */
+#define GD_FLG_COLD_BOOT       0x00100 /* Cold Boot */
+#define GD_FLG_WARM_BOOT       0x00200 /* Warm Boot */
+
 #define DECLARE_GLOBAL_DATA_PTR
 
 #endif /* __ASM_GBL_DATA_H */
diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h
new file mode 100644 (file)
index 0000000..0a37a85
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012, Google Inc. All rights reserved.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _X86_GPIO_H_
+#define _X86_GPIO_H_
+
+#include <asm-generic/gpio.h>
+
+#endif /* _X86_GPIO_H_ */
index ade694fba334205f811eabdad389c70cae1769dc..2f437e034313f9734e05d1c9e9d5389a04cc3d7b 100644 (file)
@@ -37,5 +37,6 @@ int init_bd_struct_r(void);
 int flash_init_r(void);
 int status_led_set_r(void);
 int set_load_addr_r(void);
+int init_func_spi(void);
 
 #endif /* !_INIT_HELPERS_H_ */
index 84a638da78df17ca46d8c62c4750d17bc6d97d28..86bac90e8e882650829b7ce9177e5198339237a5 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _ASM_IO_H
 #define _ASM_IO_H
 
+#include <compiler.h>
+
 /*
  * This file contains the definitions for the x86 IO instructions
  * inb/inw/inl/outb/outw/outl and the "string versions" of the same
@@ -220,7 +222,7 @@ static inline void sync(void)
 static inline void *
 map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
 {
-       return (void *)paddr;
+       return (void *)(uintptr_t)paddr;
 }
 
 /*
@@ -233,7 +235,7 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags)
 
 static inline phys_addr_t virt_to_phys(void * vaddr)
 {
-       return (phys_addr_t)(vaddr);
+       return (phys_addr_t)(uintptr_t)(vaddr);
 }
 
 /*
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
new file mode 100644 (file)
index 0000000..5017599
--- /dev/null
@@ -0,0 +1,469 @@
+/*
+ * Taken from the linux kernel file of the same name
+ *
+ * (C) Copyright 2012
+ * Graeme Russ, <graeme.russ@gmail.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _ASM_X86_MSR_INDEX_H
+#define _ASM_X86_MSR_INDEX_H
+
+/* CPU model specific register (MSR) numbers */
+
+/* x86-64 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 /* compat mode SYSCALL target */
+#define MSR_SYSCALL_MASK       0xc0000084 /* EFLAGS mask for syscall */
+#define MSR_FS_BASE            0xc0000100 /* 64bit FS base */
+#define MSR_GS_BASE            0xc0000101 /* 64bit GS base */
+#define MSR_KERNEL_GS_BASE     0xc0000102 /* SwapGS GS shadow */
+#define MSR_TSC_AUX            0xc0000103 /* Auxiliary TSC */
+
+/* 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 /* Enable virtualization */
+#define _EFER_LMSLE            13 /* Long Mode Segment Limit Enable */
+#define _EFER_FFXSR            14 /* Enable Fast FXSAVE/FXRSTOR */
+
+#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)
+#define EFER_LMSLE             (1<<_EFER_LMSLE)
+#define EFER_FFXSR             (1<<_EFER_FFXSR)
+
+/* Intel MSRs. Some also available on other CPUs */
+#define MSR_IA32_PERFCTR0              0x000000c1
+#define MSR_IA32_PERFCTR1              0x000000c2
+#define MSR_FSB_FREQ                   0x000000cd
+
+#define MSR_NHM_SNB_PKG_CST_CFG_CTL    0x000000e2
+#define NHM_C3_AUTO_DEMOTE             (1UL << 25)
+#define NHM_C1_AUTO_DEMOTE             (1UL << 26)
+#define ATM_LNC_C6_AUTO_DEMOTE         (1UL << 25)
+
+#define MSR_MTRRcap                    0x000000fe
+#define MSR_IA32_BBL_CR_CTL            0x00000119
+#define MSR_IA32_BBL_CR_CTL3           0x0000011e
+
+#define MSR_IA32_SYSENTER_CS           0x00000174
+#define MSR_IA32_SYSENTER_ESP          0x00000175
+#define MSR_IA32_SYSENTER_EIP          0x00000176
+
+#define MSR_IA32_MCG_CAP               0x00000179
+#define MSR_IA32_MCG_STATUS            0x0000017a
+#define MSR_IA32_MCG_CTL               0x0000017b
+
+#define MSR_OFFCORE_RSP_0              0x000001a6
+#define MSR_OFFCORE_RSP_1              0x000001a7
+
+#define MSR_IA32_PEBS_ENABLE           0x000003f1
+#define MSR_IA32_DS_AREA               0x00000600
+#define MSR_IA32_PERF_CAPABILITIES     0x00000345
+
+#define MSR_MTRRfix64K_00000           0x00000250
+#define MSR_MTRRfix16K_80000           0x00000258
+#define MSR_MTRRfix16K_A0000           0x00000259
+#define MSR_MTRRfix4K_C0000            0x00000268
+#define MSR_MTRRfix4K_C8000            0x00000269
+#define MSR_MTRRfix4K_D0000            0x0000026a
+#define MSR_MTRRfix4K_D8000            0x0000026b
+#define MSR_MTRRfix4K_E0000            0x0000026c
+#define MSR_MTRRfix4K_E8000            0x0000026d
+#define MSR_MTRRfix4K_F0000            0x0000026e
+#define MSR_MTRRfix4K_F8000            0x0000026f
+#define MSR_MTRRdefType                        0x000002ff
+
+#define MSR_IA32_CR_PAT                        0x00000277
+
+#define MSR_IA32_DEBUGCTLMSR           0x000001d9
+#define MSR_IA32_LASTBRANCHFROMIP      0x000001db
+#define MSR_IA32_LASTBRANCHTOIP                0x000001dc
+#define MSR_IA32_LASTINTFROMIP         0x000001dd
+#define MSR_IA32_LASTINTTOIP           0x000001de
+
+/* DEBUGCTLMSR bits (others vary by model): */
+#define DEBUGCTLMSR_LBR                        (1UL <<  0)
+#define DEBUGCTLMSR_BTF                        (1UL <<  1)
+#define DEBUGCTLMSR_TR                 (1UL <<  6)
+#define DEBUGCTLMSR_BTS                        (1UL <<  7)
+#define DEBUGCTLMSR_BTINT              (1UL <<  8)
+#define DEBUGCTLMSR_BTS_OFF_OS         (1UL <<  9)
+#define DEBUGCTLMSR_BTS_OFF_USR                (1UL << 10)
+#define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11)
+
+#define MSR_IA32_MC0_CTL               0x00000400
+#define MSR_IA32_MC0_STATUS            0x00000401
+#define MSR_IA32_MC0_ADDR              0x00000402
+#define MSR_IA32_MC0_MISC              0x00000403
+
+#define MSR_AMD64_MC0_MASK             0xc0010044
+
+#define MSR_IA32_MCx_CTL(x)            (MSR_IA32_MC0_CTL + 4*(x))
+#define MSR_IA32_MCx_STATUS(x)         (MSR_IA32_MC0_STATUS + 4*(x))
+#define MSR_IA32_MCx_ADDR(x)           (MSR_IA32_MC0_ADDR + 4*(x))
+#define MSR_IA32_MCx_MISC(x)           (MSR_IA32_MC0_MISC + 4*(x))
+
+#define MSR_AMD64_MCx_MASK(x)          (MSR_AMD64_MC0_MASK + (x))
+
+/* These are consecutive and not in the normal 4er MCE bank block */
+#define MSR_IA32_MC0_CTL2              0x00000280
+#define MSR_IA32_MCx_CTL2(x)           (MSR_IA32_MC0_CTL2 + (x))
+
+#define MSR_P6_PERFCTR0                        0x000000c1
+#define MSR_P6_PERFCTR1                        0x000000c2
+#define MSR_P6_EVNTSEL0                        0x00000186
+#define MSR_P6_EVNTSEL1                        0x00000187
+
+/* AMD64 MSRs. Not complete. See the architecture manual for a more
+   complete list. */
+
+#define MSR_AMD64_PATCH_LEVEL          0x0000008b
+#define MSR_AMD64_NB_CFG               0xc001001f
+#define MSR_AMD64_PATCH_LOADER         0xc0010020
+#define MSR_AMD64_OSVW_ID_LENGTH       0xc0010140
+#define MSR_AMD64_OSVW_STATUS          0xc0010141
+#define MSR_AMD64_DC_CFG               0xc0011022
+#define MSR_AMD64_IBSFETCHCTL          0xc0011030
+#define MSR_AMD64_IBSFETCHLINAD                0xc0011031
+#define MSR_AMD64_IBSFETCHPHYSAD       0xc0011032
+#define MSR_AMD64_IBSOPCTL             0xc0011033
+#define MSR_AMD64_IBSOPRIP             0xc0011034
+#define MSR_AMD64_IBSOPDATA            0xc0011035
+#define MSR_AMD64_IBSOPDATA2           0xc0011036
+#define MSR_AMD64_IBSOPDATA3           0xc0011037
+#define MSR_AMD64_IBSDCLINAD           0xc0011038
+#define MSR_AMD64_IBSDCPHYSAD          0xc0011039
+#define MSR_AMD64_IBSCTL               0xc001103a
+#define MSR_AMD64_IBSBRTARGET          0xc001103b
+
+/* Fam 15h MSRs */
+#define MSR_F15H_PERF_CTL              0xc0010200
+#define MSR_F15H_PERF_CTR              0xc0010201
+
+/* Fam 10h MSRs */
+#define MSR_FAM10H_MMIO_CONF_BASE      0xc0010058
+#define FAM10H_MMIO_CONF_ENABLE                (1<<0)
+#define FAM10H_MMIO_CONF_BUSRANGE_MASK 0xf
+#define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2
+#define FAM10H_MMIO_CONF_BASE_MASK     0xfffffffULL
+#define FAM10H_MMIO_CONF_BASE_SHIFT    20
+#define MSR_FAM10H_NODE_ID             0xc001100c
+
+/* K8 MSRs */
+#define MSR_K8_TOP_MEM1                        0xc001001a
+#define MSR_K8_TOP_MEM2                        0xc001001d
+#define MSR_K8_SYSCFG                  0xc0010010
+#define MSR_K8_INT_PENDING_MSG         0xc0010055
+/* C1E active bits in int pending message */
+#define K8_INTP_C1E_ACTIVE_MASK                0x18000000
+#define MSR_K8_TSEG_ADDR               0xc0010112
+#define K8_MTRRFIXRANGE_DRAM_ENABLE    0x00040000 /* MtrrFixDramEn bit    */
+#define K8_MTRRFIXRANGE_DRAM_MODIFY    0x00080000 /* MtrrFixDramModEn bit */
+#define K8_MTRR_RDMEM_WRMEM_MASK       0x18181818 /* Mask: RdMem|WrMem    */
+
+/* K7 MSRs */
+#define MSR_K7_EVNTSEL0                        0xc0010000
+#define MSR_K7_PERFCTR0                        0xc0010004
+#define MSR_K7_EVNTSEL1                        0xc0010001
+#define MSR_K7_PERFCTR1                        0xc0010005
+#define MSR_K7_EVNTSEL2                        0xc0010002
+#define MSR_K7_PERFCTR2                        0xc0010006
+#define MSR_K7_EVNTSEL3                        0xc0010003
+#define MSR_K7_PERFCTR3                        0xc0010007
+#define MSR_K7_CLK_CTL                 0xc001001b
+#define MSR_K7_HWCR                    0xc0010015
+#define MSR_K7_FID_VID_CTL             0xc0010041
+#define MSR_K7_FID_VID_STATUS          0xc0010042
+
+/* K6 MSRs */
+#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
+
+/* Centaur-Hauls/IDT defined MSRs. */
+#define MSR_IDT_FCR1                   0x00000107
+#define MSR_IDT_FCR2                   0x00000108
+#define MSR_IDT_FCR3                   0x00000109
+#define MSR_IDT_FCR4                   0x0000010a
+
+#define MSR_IDT_MCR0                   0x00000110
+#define MSR_IDT_MCR1                   0x00000111
+#define MSR_IDT_MCR2                   0x00000112
+#define MSR_IDT_MCR3                   0x00000113
+#define MSR_IDT_MCR4                   0x00000114
+#define MSR_IDT_MCR5                   0x00000115
+#define MSR_IDT_MCR6                   0x00000116
+#define MSR_IDT_MCR7                   0x00000117
+#define MSR_IDT_MCR_CTRL               0x00000120
+
+/* VIA Cyrix defined MSRs*/
+#define MSR_VIA_FCR                    0x00001107
+#define MSR_VIA_LONGHAUL               0x0000110a
+#define MSR_VIA_RNG                    0x0000110b
+#define MSR_VIA_BCR2                   0x00001147
+
+/* 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
+
+/* Intel defined MSRs. */
+#define MSR_IA32_P5_MC_ADDR            0x00000000
+#define MSR_IA32_P5_MC_TYPE            0x00000001
+#define MSR_IA32_TSC                   0x00000010
+#define MSR_IA32_PLATFORM_ID           0x00000017
+#define MSR_IA32_EBL_CR_POWERON                0x0000002a
+#define MSR_EBC_FREQUENCY_ID           0x0000002c
+#define MSR_IA32_FEATURE_CONTROL        0x0000003a
+
+#define FEATURE_CONTROL_LOCKED                         (1<<0)
+#define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX       (1<<1)
+#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX      (1<<2)
+
+#define MSR_IA32_APICBASE              0x0000001b
+#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           0x00000079
+#define MSR_IA32_UCODE_REV             0x0000008b
+
+#define MSR_IA32_PERF_STATUS           0x00000198
+#define MSR_IA32_PERF_CTL              0x00000199
+
+#define MSR_IA32_MPERF                 0x000000e7
+#define MSR_IA32_APERF                 0x000000e8
+
+#define MSR_IA32_THERM_CONTROL         0x0000019a
+#define MSR_IA32_THERM_INTERRUPT       0x0000019b
+
+#define THERM_INT_HIGH_ENABLE          (1 << 0)
+#define THERM_INT_LOW_ENABLE           (1 << 1)
+#define THERM_INT_PLN_ENABLE           (1 << 24)
+
+#define MSR_IA32_THERM_STATUS          0x0000019c
+
+#define THERM_STATUS_PROCHOT           (1 << 0)
+#define THERM_STATUS_POWER_LIMIT       (1 << 10)
+
+#define MSR_THERM2_CTL                 0x0000019d
+
+#define MSR_THERM2_CTL_TM_SELECT       (1ULL << 16)
+
+#define MSR_IA32_MISC_ENABLE           0x000001a0
+
+#define MSR_IA32_TEMPERATURE_TARGET    0x000001a2
+
+#define MSR_IA32_ENERGY_PERF_BIAS      0x000001b0
+
+#define MSR_IA32_PACKAGE_THERM_STATUS          0x000001b1
+
+#define PACKAGE_THERM_STATUS_PROCHOT           (1 << 0)
+#define PACKAGE_THERM_STATUS_POWER_LIMIT       (1 << 10)
+
+#define MSR_IA32_PACKAGE_THERM_INTERRUPT       0x000001b2
+
+#define PACKAGE_THERM_INT_HIGH_ENABLE          (1 << 0)
+#define PACKAGE_THERM_INT_LOW_ENABLE           (1 << 1)
+#define PACKAGE_THERM_INT_PLN_ENABLE           (1 << 24)
+
+/* Thermal Thresholds Support */
+#define THERM_INT_THRESHOLD0_ENABLE    (1 << 15)
+#define THERM_SHIFT_THRESHOLD0        8
+#define THERM_MASK_THRESHOLD0          (0x7f << THERM_SHIFT_THRESHOLD0)
+#define THERM_INT_THRESHOLD1_ENABLE    (1 << 23)
+#define THERM_SHIFT_THRESHOLD1        16
+#define THERM_MASK_THRESHOLD1          (0x7f << THERM_SHIFT_THRESHOLD1)
+#define THERM_STATUS_THRESHOLD0        (1 << 6)
+#define THERM_LOG_THRESHOLD0           (1 << 7)
+#define THERM_STATUS_THRESHOLD1        (1 << 8)
+#define THERM_LOG_THRESHOLD1           (1 << 9)
+
+/* MISC_ENABLE bits: architectural */
+#define MSR_IA32_MISC_ENABLE_FAST_STRING       (1ULL << 0)
+#define MSR_IA32_MISC_ENABLE_TCC               (1ULL << 1)
+#define MSR_IA32_MISC_ENABLE_EMON              (1ULL << 7)
+#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL       (1ULL << 11)
+#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL      (1ULL << 12)
+#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP        (1ULL << 16)
+#define MSR_IA32_MISC_ENABLE_MWAIT             (1ULL << 18)
+#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID       (1ULL << 22)
+#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE      (1ULL << 23)
+#define MSR_IA32_MISC_ENABLE_XD_DISABLE                (1ULL << 34)
+
+/* MISC_ENABLE bits: model-specific, meaning may vary from core to core */
+#define MSR_IA32_MISC_ENABLE_X87_COMPAT                (1ULL << 2)
+#define MSR_IA32_MISC_ENABLE_TM1               (1ULL << 3)
+#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE        (1ULL << 4)
+#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE   (1ULL << 6)
+#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK     (1ULL << 8)
+#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE  (1ULL << 9)
+#define MSR_IA32_MISC_ENABLE_FERR              (1ULL << 10)
+#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX    (1ULL << 10)
+#define MSR_IA32_MISC_ENABLE_TM2               (1ULL << 13)
+#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE  (1ULL << 19)
+#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK    (1ULL << 20)
+#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT       (1ULL << 24)
+#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE  (1ULL << 37)
+#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE     (1ULL << 38)
+#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE   (1ULL << 39)
+
+/* P4/Xeon+ specific */
+#define MSR_IA32_MCG_EAX               0x00000180
+#define MSR_IA32_MCG_EBX               0x00000181
+#define MSR_IA32_MCG_ECX               0x00000182
+#define MSR_IA32_MCG_EDX               0x00000183
+#define MSR_IA32_MCG_ESI               0x00000184
+#define MSR_IA32_MCG_EDI               0x00000185
+#define MSR_IA32_MCG_EBP               0x00000186
+#define MSR_IA32_MCG_ESP               0x00000187
+#define MSR_IA32_MCG_EFLAGS            0x00000188
+#define MSR_IA32_MCG_EIP               0x00000189
+#define MSR_IA32_MCG_RESERVED          0x0000018a
+
+/* Pentium IV performance counter MSRs */
+#define MSR_P4_BPU_PERFCTR0            0x00000300
+#define MSR_P4_BPU_PERFCTR1            0x00000301
+#define MSR_P4_BPU_PERFCTR2            0x00000302
+#define MSR_P4_BPU_PERFCTR3            0x00000303
+#define MSR_P4_MS_PERFCTR0             0x00000304
+#define MSR_P4_MS_PERFCTR1             0x00000305
+#define MSR_P4_MS_PERFCTR2             0x00000306
+#define MSR_P4_MS_PERFCTR3             0x00000307
+#define MSR_P4_FLAME_PERFCTR0          0x00000308
+#define MSR_P4_FLAME_PERFCTR1          0x00000309
+#define MSR_P4_FLAME_PERFCTR2          0x0000030a
+#define MSR_P4_FLAME_PERFCTR3          0x0000030b
+#define MSR_P4_IQ_PERFCTR0             0x0000030c
+#define MSR_P4_IQ_PERFCTR1             0x0000030d
+#define MSR_P4_IQ_PERFCTR2             0x0000030e
+#define MSR_P4_IQ_PERFCTR3             0x0000030f
+#define MSR_P4_IQ_PERFCTR4             0x00000310
+#define MSR_P4_IQ_PERFCTR5             0x00000311
+#define MSR_P4_BPU_CCCR0               0x00000360
+#define MSR_P4_BPU_CCCR1               0x00000361
+#define MSR_P4_BPU_CCCR2               0x00000362
+#define MSR_P4_BPU_CCCR3               0x00000363
+#define MSR_P4_MS_CCCR0                        0x00000364
+#define MSR_P4_MS_CCCR1                        0x00000365
+#define MSR_P4_MS_CCCR2                        0x00000366
+#define MSR_P4_MS_CCCR3                        0x00000367
+#define MSR_P4_FLAME_CCCR0             0x00000368
+#define MSR_P4_FLAME_CCCR1             0x00000369
+#define MSR_P4_FLAME_CCCR2             0x0000036a
+#define MSR_P4_FLAME_CCCR3             0x0000036b
+#define MSR_P4_IQ_CCCR0                        0x0000036c
+#define MSR_P4_IQ_CCCR1                        0x0000036d
+#define MSR_P4_IQ_CCCR2                        0x0000036e
+#define MSR_P4_IQ_CCCR3                        0x0000036f
+#define MSR_P4_IQ_CCCR4                        0x00000370
+#define MSR_P4_IQ_CCCR5                        0x00000371
+#define MSR_P4_ALF_ESCR0               0x000003ca
+#define MSR_P4_ALF_ESCR1               0x000003cb
+#define MSR_P4_BPU_ESCR0               0x000003b2
+#define MSR_P4_BPU_ESCR1               0x000003b3
+#define MSR_P4_BSU_ESCR0               0x000003a0
+#define MSR_P4_BSU_ESCR1               0x000003a1
+#define MSR_P4_CRU_ESCR0               0x000003b8
+#define MSR_P4_CRU_ESCR1               0x000003b9
+#define MSR_P4_CRU_ESCR2               0x000003cc
+#define MSR_P4_CRU_ESCR3               0x000003cd
+#define MSR_P4_CRU_ESCR4               0x000003e0
+#define MSR_P4_CRU_ESCR5               0x000003e1
+#define MSR_P4_DAC_ESCR0               0x000003a8
+#define MSR_P4_DAC_ESCR1               0x000003a9
+#define MSR_P4_FIRM_ESCR0              0x000003a4
+#define MSR_P4_FIRM_ESCR1              0x000003a5
+#define MSR_P4_FLAME_ESCR0             0x000003a6
+#define MSR_P4_FLAME_ESCR1             0x000003a7
+#define MSR_P4_FSB_ESCR0               0x000003a2
+#define MSR_P4_FSB_ESCR1               0x000003a3
+#define MSR_P4_IQ_ESCR0                        0x000003ba
+#define MSR_P4_IQ_ESCR1                        0x000003bb
+#define MSR_P4_IS_ESCR0                        0x000003b4
+#define MSR_P4_IS_ESCR1                        0x000003b5
+#define MSR_P4_ITLB_ESCR0              0x000003b6
+#define MSR_P4_ITLB_ESCR1              0x000003b7
+#define MSR_P4_IX_ESCR0                        0x000003c8
+#define MSR_P4_IX_ESCR1                        0x000003c9
+#define MSR_P4_MOB_ESCR0               0x000003aa
+#define MSR_P4_MOB_ESCR1               0x000003ab
+#define MSR_P4_MS_ESCR0                        0x000003c0
+#define MSR_P4_MS_ESCR1                        0x000003c1
+#define MSR_P4_PMH_ESCR0               0x000003ac
+#define MSR_P4_PMH_ESCR1               0x000003ad
+#define MSR_P4_RAT_ESCR0               0x000003bc
+#define MSR_P4_RAT_ESCR1               0x000003bd
+#define MSR_P4_SAAT_ESCR0              0x000003ae
+#define MSR_P4_SAAT_ESCR1              0x000003af
+#define MSR_P4_SSU_ESCR0               0x000003be
+#define MSR_P4_SSU_ESCR1               0x000003bf /* guess: not in manual */
+
+#define MSR_P4_TBPU_ESCR0              0x000003c2
+#define MSR_P4_TBPU_ESCR1              0x000003c3
+#define MSR_P4_TC_ESCR0                        0x000003c4
+#define MSR_P4_TC_ESCR1                        0x000003c5
+#define MSR_P4_U2L_ESCR0               0x000003b0
+#define MSR_P4_U2L_ESCR1               0x000003b1
+
+#define MSR_P4_PEBS_MATRIX_VERT                0x000003f2
+
+/* Intel Core-based CPU performance counters */
+#define MSR_CORE_PERF_FIXED_CTR0       0x00000309
+#define MSR_CORE_PERF_FIXED_CTR1       0x0000030a
+#define MSR_CORE_PERF_FIXED_CTR2       0x0000030b
+#define MSR_CORE_PERF_FIXED_CTR_CTRL   0x0000038d
+#define MSR_CORE_PERF_GLOBAL_STATUS    0x0000038e
+#define MSR_CORE_PERF_GLOBAL_CTRL      0x0000038f
+#define MSR_CORE_PERF_GLOBAL_OVF_CTRL  0x00000390
+
+/* Geode defined MSRs */
+#define MSR_GEODE_BUSCONT_CONF0                0x00001900
+
+/* Intel VT MSRs */
+#define MSR_IA32_VMX_BASIC              0x00000480
+#define MSR_IA32_VMX_PINBASED_CTLS      0x00000481
+#define MSR_IA32_VMX_PROCBASED_CTLS     0x00000482
+#define MSR_IA32_VMX_EXIT_CTLS          0x00000483
+#define MSR_IA32_VMX_ENTRY_CTLS         0x00000484
+#define MSR_IA32_VMX_MISC               0x00000485
+#define MSR_IA32_VMX_CR0_FIXED0         0x00000486
+#define MSR_IA32_VMX_CR0_FIXED1         0x00000487
+#define MSR_IA32_VMX_CR4_FIXED0         0x00000488
+#define MSR_IA32_VMX_CR4_FIXED1         0x00000489
+#define MSR_IA32_VMX_VMCS_ENUM          0x0000048a
+#define MSR_IA32_VMX_PROCBASED_CTLS2    0x0000048b
+#define MSR_IA32_VMX_EPT_VPID_CAP       0x0000048c
+
+/* AMD-V MSRs */
+
+#define MSR_VM_CR                       0xc0010114
+#define MSR_VM_IGNNE                    0xc0010115
+#define MSR_VM_HSAVE_PA                 0xc0010117
+
+#endif /* _ASM_X86_MSR_INDEX_H */
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
new file mode 100644 (file)
index 0000000..6030633
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Taken from the linux kernel file of the same name
+ *
+ * (C) Copyright 2012
+ * Graeme Russ, <graeme.russ@gmail.com>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _ASM_X86_MSR_H
+#define _ASM_X86_MSR_H
+
+#include <asm/msr-index.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define X86_IOC_RDMSR_REGS     _IOWR('c', 0xA0, __u32[8])
+#define X86_IOC_WRMSR_REGS     _IOWR('c', 0xA1, __u32[8])
+
+#ifdef __KERNEL__
+
+#include <asm/errno.h>
+
+struct msr {
+       union {
+               struct {
+                       u32 l;
+                       u32 h;
+               };
+               u64 q;
+       };
+};
+
+struct msr_info {
+       u32 msr_no;
+       struct msr reg;
+       struct msr *msrs;
+       int err;
+};
+
+struct msr_regs_info {
+       u32 *regs;
+       int err;
+};
+
+static inline unsigned long long native_read_tscp(unsigned int *aux)
+{
+       unsigned long low, high;
+       asm volatile(".byte 0x0f,0x01,0xf9"
+                    : "=a" (low), "=d" (high), "=c" (*aux));
+       return low | ((u64)high << 32);
+}
+
+/*
+ * both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A"
+ * constraint has different meanings. For i386, "A" means exactly
+ * edx:eax, while for x86_64 it doesn't mean rdx:rax or edx:eax. Instead,
+ * it means rax *or* rdx.
+ */
+#ifdef CONFIG_X86_64
+#define DECLARE_ARGS(val, low, high)   unsigned low, high
+#define EAX_EDX_VAL(val, low, high)    ((low) | ((u64)(high) << 32))
+#define EAX_EDX_ARGS(val, low, high)   "a" (low), "d" (high)
+#define EAX_EDX_RET(val, low, high)    "=a" (low), "=d" (high)
+#else
+#define DECLARE_ARGS(val, low, high)   unsigned long long val
+#define EAX_EDX_VAL(val, low, high)    (val)
+#define EAX_EDX_ARGS(val, low, high)   "A" (val)
+#define EAX_EDX_RET(val, low, high)    "=A" (val)
+#endif
+
+static inline unsigned long long native_read_msr(unsigned int msr)
+{
+       DECLARE_ARGS(val, low, high);
+
+       asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
+       return EAX_EDX_VAL(val, low, high);
+}
+
+static inline void native_write_msr(unsigned int msr,
+                                   unsigned low, unsigned high)
+{
+       asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
+}
+
+extern unsigned long long native_read_tsc(void);
+
+extern int native_rdmsr_safe_regs(u32 regs[8]);
+extern int native_wrmsr_safe_regs(u32 regs[8]);
+
+static inline unsigned long long native_read_pmc(int counter)
+{
+       DECLARE_ARGS(val, low, high);
+
+       asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
+       return EAX_EDX_VAL(val, low, high);
+}
+
+#ifdef CONFIG_PARAVIRT
+#include <asm/paravirt.h>
+#else
+#include <errno.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)                                 \
+do {                                                           \
+       u64 __val = native_read_msr((msr));                     \
+       (void)((val1) = (u32)__val);                            \
+       (void)((val2) = (u32)(__val >> 32));                    \
+} while (0)
+
+static inline void wrmsr(unsigned msr, unsigned low, unsigned high)
+{
+       native_write_msr(msr, low, high);
+}
+
+#define rdmsrl(msr, val)                       \
+       ((val) = native_read_msr((msr)))
+
+#define wrmsrl(msr, val)                                               \
+       native_write_msr((msr), (u32)((u64)(val)), (u32)((u64)(val) >> 32))
+
+/* rdmsr with exception handling */
+#define rdmsr_safe(msr, p1, p2)                                        \
+({                                                             \
+       int __err;                                              \
+       u64 __val = native_read_msr_safe((msr), &__err);        \
+       (*p1) = (u32)__val;                                     \
+       (*p2) = (u32)(__val >> 32);                             \
+       __err;                                                  \
+})
+
+static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
+{
+       u32 gprs[8] = { 0 };
+       int err;
+
+       gprs[1] = msr;
+       gprs[7] = 0x9c5a203a;
+
+       err = native_rdmsr_safe_regs(gprs);
+
+       *p = gprs[0] | ((u64)gprs[2] << 32);
+
+       return err;
+}
+
+static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
+{
+       u32 gprs[8] = { 0 };
+
+       gprs[0] = (u32)val;
+       gprs[1] = msr;
+       gprs[2] = val >> 32;
+       gprs[7] = 0x9c5a203a;
+
+       return native_wrmsr_safe_regs(gprs);
+}
+
+static inline int rdmsr_safe_regs(u32 regs[8])
+{
+       return native_rdmsr_safe_regs(regs);
+}
+
+static inline int wrmsr_safe_regs(u32 regs[8])
+{
+       return native_wrmsr_safe_regs(regs);
+}
+
+#define rdtscl(low)                                            \
+       ((low) = (u32)__native_read_tsc())
+
+#define rdtscll(val)                                           \
+       ((val) = __native_read_tsc())
+
+#define rdpmc(counter, low, high)                      \
+do {                                                   \
+       u64 _l = native_read_pmc((counter));            \
+       (low)  = (u32)_l;                               \
+       (high) = (u32)(_l >> 32);                       \
+} while (0)
+
+#define rdtscp(low, high, aux)                                 \
+do {                                                            \
+       unsigned long long _val = native_read_tscp(&(aux));     \
+       (low) = (u32)_val;                                      \
+       (high) = (u32)(_val >> 32);                             \
+} while (0)
+
+#define rdtscpll(val, aux) (val) = native_read_tscp(&(aux))
+
+#endif /* !CONFIG_PARAVIRT */
+
+
+#define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val),                \
+                                            (u32)((val) >> 32))
+
+#define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2))
+
+#define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0)
+
+struct msr *msrs_alloc(void);
+void msrs_free(struct msr *msrs);
+
+#ifdef CONFIG_SMP
+int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
+int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
+void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
+void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
+int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
+int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
+int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
+int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
+
+#endif  /* CONFIG_SMP */
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_X86_MSR_H */
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
new file mode 100644 (file)
index 0000000..6842da5
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Generic MTRR (Memory Type Range Register) ioctls.
+ * Taken from the Linux kernel
+ *
+ * (C) Copyright 2012
+ * Graeme Russ, <graeme.russ@gmail.com>
+ *
+ * Copyright (C) 1997-1999  Richard Gooch <rgooch@atnf.csiro.au>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _ASM_X86_MTRR_H
+#define _ASM_X86_MTRR_H
+
+#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
+#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <errno.h>
+
+#define        MTRR_IOCTL_BASE 'M'
+
+struct mtrr_sentry {
+       unsigned long base;     /*  Base address     */
+       unsigned int size;      /*  Size of region   */
+       unsigned int type;      /*  Type of region   */
+};
+
+/*
+ * Warning: this structure has a different order from i386
+ * on x86-64. The 32bit emulation code takes care of that.
+ * But you need to use this for 64bit, otherwise your X server
+ * will break.
+ */
+
+#ifdef __i386__
+struct mtrr_gentry {
+       unsigned int regnum;    /*  Register number  */
+       unsigned long base;     /*  Base address     */
+       unsigned int size;      /*  Size of region   */
+       unsigned int type;      /*  Type of region   */
+};
+
+#else /* __i386__ */
+
+struct mtrr_gentry {
+       unsigned long base;     /*  Base address     */
+       unsigned int size;      /*  Size of region   */
+       unsigned int regnum;    /*  Register number  */
+       unsigned int type;      /*  Type of region   */
+};
+#endif /* !__i386__ */
+
+struct mtrr_var_range {
+       __u32 base_lo;
+       __u32 base_hi;
+       __u32 mask_lo;
+       __u32 mask_hi;
+};
+
+/*
+ * In the Intel processor's MTRR interface, the MTRR type is always held in
+ * an 8 bit field:
+ */
+typedef __u8 mtrr_type;
+
+#define MTRR_NUM_FIXED_RANGES 88
+#define MTRR_MAX_VAR_RANGES 256
+
+struct mtrr_state_type {
+       struct mtrr_var_range var_ranges[MTRR_MAX_VAR_RANGES];
+       mtrr_type fixed_ranges[MTRR_NUM_FIXED_RANGES];
+       unsigned char enabled;
+       unsigned char have_fixed;
+       mtrr_type def_type;
+};
+
+/*  These are the various ioctls  */
+#define MTRRIOC_ADD_ENTRY        _IOW(MTRR_IOCTL_BASE,  0, struct mtrr_sentry)
+#define MTRRIOC_SET_ENTRY        _IOW(MTRR_IOCTL_BASE,  1, struct mtrr_sentry)
+#define MTRRIOC_DEL_ENTRY        _IOW(MTRR_IOCTL_BASE,  2, struct mtrr_sentry)
+#define MTRRIOC_GET_ENTRY        _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry)
+#define MTRRIOC_KILL_ENTRY       _IOW(MTRR_IOCTL_BASE,  4, struct mtrr_sentry)
+#define MTRRIOC_ADD_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  5, struct mtrr_sentry)
+#define MTRRIOC_SET_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  6, struct mtrr_sentry)
+#define MTRRIOC_DEL_PAGE_ENTRY   _IOW(MTRR_IOCTL_BASE,  7, struct mtrr_sentry)
+#define MTRRIOC_GET_PAGE_ENTRY   _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry)
+#define MTRRIOC_KILL_PAGE_ENTRY  _IOW(MTRR_IOCTL_BASE,  9, struct mtrr_sentry)
+
+/*  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
+
+#ifdef __KERNEL__
+
+/*  The following functions are for use by other drivers  */
+# ifdef CONFIG_MTRR
+extern u8 mtrr_type_lookup(u64 addr, u64 end);
+extern void mtrr_save_fixed_ranges(void *);
+extern void mtrr_save_state(void);
+extern int mtrr_add(unsigned long base, unsigned long size,
+                   unsigned int type, bool increment);
+extern int mtrr_add_page(unsigned long base, unsigned long size,
+                        unsigned int type, bool increment);
+extern int mtrr_del(int reg, unsigned long base, unsigned long size);
+extern int mtrr_del_page(int reg, unsigned long base, unsigned long size);
+extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi);
+extern void mtrr_ap_init(void);
+extern void mtrr_bp_init(void);
+extern void set_mtrr_aps_delayed_init(void);
+extern void mtrr_aps_init(void);
+extern void mtrr_bp_restore(void);
+extern int mtrr_trim_uncached_memory(unsigned long end_pfn);
+extern int amd_special_default_mtrr(void);
+#  else
+static inline u8 mtrr_type_lookup(u64 addr, u64 end)
+{
+       /*
+        * Return no-MTRRs:
+        */
+       return 0xff;
+}
+#define mtrr_save_fixed_ranges(arg) do {} while (0)
+#define mtrr_save_state() do {} while (0)
+static inline int mtrr_del(int reg, unsigned long base, unsigned long size)
+{
+       return -ENODEV;
+}
+static inline int mtrr_del_page(int reg, unsigned long base, unsigned long size)
+{
+       return -ENODEV;
+}
+static inline int mtrr_trim_uncached_memory(unsigned long end_pfn)
+{
+       return 0;
+}
+static inline void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
+{
+}
+
+#define mtrr_ap_init() do {} while (0)
+#define mtrr_bp_init() do {} while (0)
+#define set_mtrr_aps_delayed_init() do {} while (0)
+#define mtrr_aps_init() do {} while (0)
+#define mtrr_bp_restore() do {} while (0)
+#  endif
+
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+
+struct mtrr_sentry32 {
+       compat_ulong_t base;    /*  Base address     */
+       compat_uint_t size;     /*  Size of region   */
+       compat_uint_t type;     /*  Type of region   */
+};
+
+struct mtrr_gentry32 {
+       compat_ulong_t regnum;  /*  Register number  */
+       compat_uint_t base;     /*  Base address     */
+       compat_uint_t size;     /*  Size of region   */
+       compat_uint_t type;     /*  Type of region   */
+};
+
+#define MTRR_IOCTL_BASE 'M'
+
+#define MTRRIOC32_ADD_ENTRY      _IOW(MTRR_IOCTL_BASE,  0, struct mtrr_sentry32)
+#define MTRRIOC32_SET_ENTRY      _IOW(MTRR_IOCTL_BASE,  1, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_ENTRY      _IOW(MTRR_IOCTL_BASE,  2, struct mtrr_sentry32)
+#define MTRRIOC32_GET_ENTRY      _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_ENTRY     _IOW(MTRR_IOCTL_BASE,  4, struct mtrr_sentry32)
+#define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE,  5, struct mtrr_sentry32)
+#define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE,  6, struct mtrr_sentry32)
+#define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE,  7, struct mtrr_sentry32)
+#define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
+#define MTRRIOC32_KILL_PAGE_ENTRY              \
+                                _IOW(MTRR_IOCTL_BASE,  9, struct mtrr_sentry32)
+#endif /* CONFIG_COMPAT */
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_X86_MTRR_H */
index 9a40e383eb35afc93ac0b07cbded5530908b4a18..e9fde88f7d4a52a414d7a44d655185f61f3c96b8 100644 (file)
@@ -45,8 +45,8 @@ typedef unsigned long long u64;
 
 typedef u32 dma_addr_t;
 
-typedef unsigned long phys_addr_t;
-typedef unsigned long phys_size_t;
+typedef unsigned long long phys_addr_t;
+typedef unsigned long long phys_size_t;
 
 #endif /* __KERNEL__ */
 
index a4a5ae05d119a92bd456b94b59e6eac7e5231499..99062e5955356dc9cd755b7e16ea1eb5d19e093f 100644 (file)
@@ -63,9 +63,20 @@ u32 isa_map_rom(u32 bus_addr, int size);
 
 /* arch/x86/lib/... */
 int video_bios_init(void);
-int video_init(void);
 
 void   board_init_f_r_trampoline(ulong) __attribute__ ((noreturn));
 void   board_init_f_r(void) __attribute__ ((noreturn));
 
+/* Read the time stamp counter */
+static inline uint64_t rdtsc(void)
+{
+       uint32_t high, low;
+       __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high));
+       return (((uint64_t)high) << 32) | low;
+}
+
+/* board/... */
+void timer_set_tsc_base(uint64_t new_base);
+uint64_t timer_get_tsc(void);
+
 #endif /* _U_BOOT_I386_H_ */
index 4325b2502ea5e9277fdd4a0b9978892b7de8e4c5..0a52cc896c6b9c36b920f7d3fc91fdd3a2c17603 100644 (file)
@@ -32,7 +32,7 @@ COBJS-y       += realmode.o
 SOBJS-y        += realmode_switch.o
 
 COBJS-$(CONFIG_SYS_PC_BIOS)    += bios_setup.o
-COBJS-$(CONFIG_VIDEO)  += video_bios.o
+COBJS-$(CONFIG_VIDEO_VGA)      += video_bios.o
 endif
 
 COBJS-y        += board.o
@@ -47,9 +47,10 @@ COBJS-$(CONFIG_SYS_GENERIC_TIMER) += pcat_timer.o
 COBJS-$(CONFIG_PCI) += pci.o
 COBJS-$(CONFIG_PCI) += pci_type1.o
 COBJS-y        += relocate.o
+COBJS-y += physmem.o
 COBJS-y        += string.o
 COBJS-$(CONFIG_SYS_X86_ISR_TIMER)      += timer.o
-COBJS-$(CONFIG_VIDEO)  += video.o
+COBJS-$(CONFIG_VIDEO_VGA)      += video.o
 COBJS-$(CONFIG_CMD_ZBOOT)      += zimage.o
 
 SRCS   := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
index c7d89604cae88080a6b806c4c9089b87b774e89b..22bc26dde90643f1e8a82ae88564624c8f6bdd70 100644 (file)
@@ -99,10 +99,17 @@ typedef int (init_fnc_t) (void);
 init_fnc_t *init_sequence_f[] = {
        cpu_init_f,
        board_early_init_f,
+#ifdef CONFIG_OF_CONTROL
+       find_fdt,
+       fdtdec_check_fdt,
+#endif
        env_init,
        init_baudrate_f,
        serial_init,
        console_init_f,
+#ifdef CONFIG_OF_CONTROL
+       prepare_fdt,
+#endif
        dram_init_f,
        calculate_relocation_address,
 
@@ -153,6 +160,9 @@ init_fnc_t *init_sequence_r[] = {
        serial_initialize_r,
 #ifndef CONFIG_SYS_NO_FLASH
        flash_init_r,
+#endif
+#ifdef CONFIG_SPI
+       init_func_spi;
 #endif
        env_relocate_r,
 #ifdef CONFIG_PCI
index 87c7263fcb5094824e141cf737a5deac507744d5..3eec9a61d66a680b81ed6c310f938c6dae880623 100644 (file)
 #include <net.h>
 #include <ide.h>
 #include <serial.h>
+#include <spi.h>
 #include <status_led.h>
 #include <asm/processor.h>
 #include <asm/u-boot-x86.h>
+#include <linux/compiler.h>
 
 #include <asm/init_helpers.h>
 
@@ -71,7 +73,7 @@ int init_baudrate_f(void)
        return 0;
 }
 
-int calculate_relocation_address(void)
+__weak int calculate_relocation_address(void)
 {
        ulong text_start = (ulong)&__text_start;
        ulong bss_end = (ulong)&__bss_end;
@@ -85,15 +87,16 @@ int calculate_relocation_address(void)
 
        /* Stack is at top of available memory */
        dest_addr = gd->ram_size;
-       gd->start_addr_sp = dest_addr;
 
-       /* U-Boot is below the stack */
-       dest_addr -= CONFIG_SYS_STACK_SIZE;
+       /* U-Boot is at the top */
        dest_addr -= (bss_end - text_start);
        dest_addr &= ~15;
        gd->relocaddr = dest_addr;
        gd->reloc_off = (dest_addr - text_start);
 
+       /* Stack is at the bottom, so it can grow down */
+       gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN;
+
        return 0;
 }
 
@@ -160,3 +163,40 @@ int set_load_addr_r(void)
 
        return 0;
 }
+
+int init_func_spi(void)
+{
+       puts("SPI:   ");
+       spi_init();
+       puts("ready\n");
+       return 0;
+}
+
+#ifdef CONFIG_OF_CONTROL
+int find_fdt(void)
+{
+#ifdef CONFIG_OF_EMBED
+       /* Get a pointer to the FDT */
+       gd->fdt_blob = _binary_dt_dtb_start;
+#elif defined CONFIG_OF_SEPARATE
+       /* FDT is at end of image */
+       gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE);
+#endif
+       /* Allow the early environment to override the fdt address */
+       gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
+                                               (uintptr_t)gd->fdt_blob);
+
+       return 0;
+}
+
+int prepare_fdt(void)
+{
+       /* For now, put this check after the console is ready */
+       if (fdtdec_prepare_fdt()) {
+               panic("** CONFIG_OF_CONTROL defined but no FDT - please see "
+                       "doc/README.fdt-control");
+       }
+
+       return 0;
+}
+#endif
index 71449fe6fa49d414a1c95a827b768a554caeae08..cca018fa9b06ae174eccb90fea69fb2b4eafa749 100644 (file)
@@ -21,6 +21,7 @@
  * MA 02111-1307 USA
  */
 #include <common.h>
+#include <environment.h>
 #include <serial.h>
 #include <kgdb.h>
 #include <scsi.h>
@@ -36,10 +37,35 @@ int serial_initialize_r(void)
        return 0;
 }
 
+/*
+ * Tell if it's OK to load the environment early in boot.
+ *
+ * If CONFIG_OF_CONFIG is defined, we'll check with the FDT to see
+ * if this is OK (defaulting to saying it's not OK).
+ *
+ * NOTE: Loading the environment early can be a bad idea if security is
+ *       important, since no verification is done on the environment.
+ *
+ * @return 0 if environment should not be loaded, !=0 if it is ok to load
+ */
+static int should_load_env(void)
+{
+#ifdef CONFIG_OF_CONTROL
+       return fdtdec_get_config_int(gd->fdt_blob, "load-environment", 0);
+#elif defined CONFIG_DELAY_ENVIRONMENT
+       return 0;
+#else
+       return 1;
+#endif
+}
+
 int env_relocate_r(void)
 {
        /* initialize environment */
-       env_relocate();
+       if (should_load_env())
+               env_relocate();
+       else
+               set_default_env(NULL);
 
        return 0;
 }
diff --git a/arch/x86/lib/physmem.c b/arch/x86/lib/physmem.c
new file mode 100644 (file)
index 0000000..18f0e62
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+#include <common.h>
+#include <physmem.h>
+#include <linux/compiler.h>
+
+/* Large pages are 2MB. */
+#define LARGE_PAGE_SIZE ((1 << 20) * 2)
+
+/*
+ * Paging data structures.
+ */
+
+struct pdpe {
+       uint64_t p:1;
+       uint64_t mbz_0:2;
+       uint64_t pwt:1;
+       uint64_t pcd:1;
+       uint64_t mbz_1:4;
+       uint64_t avl:3;
+       uint64_t base:40;
+       uint64_t mbz_2:12;
+};
+
+typedef struct pdpe pdpt_t[512];
+
+struct pde {
+       uint64_t p:1;      /* present */
+       uint64_t rw:1;     /* read/write */
+       uint64_t us:1;     /* user/supervisor */
+       uint64_t pwt:1;    /* page-level writethrough */
+       uint64_t pcd:1;    /* page-level cache disable */
+       uint64_t a:1;      /* accessed */
+       uint64_t d:1;      /* dirty */
+       uint64_t ps:1;     /* page size */
+       uint64_t g:1;      /* global page */
+       uint64_t avl:3;    /* available to software */
+       uint64_t pat:1;    /* page-attribute table */
+       uint64_t mbz_0:8;  /* must be zero */
+       uint64_t base:31;  /* base address */
+};
+
+typedef struct pde pdt_t[512];
+
+static pdpt_t pdpt __aligned(4096);
+static pdt_t pdts[4] __aligned(4096);
+
+/*
+ * Map a virtual address to a physical address and optionally invalidate any
+ * old mapping.
+ *
+ * @param virt         The virtual address to use.
+ * @param phys         The physical address to use.
+ * @param invlpg       Whether to use invlpg to clear any old mappings.
+ */
+static void x86_phys_map_page(uintptr_t virt, phys_addr_t phys, int invlpg)
+{
+       /* Extract the two bit PDPT index and the 9 bit PDT index. */
+       uintptr_t pdpt_idx = (virt >> 30) & 0x3;
+       uintptr_t pdt_idx = (virt >> 21) & 0x1ff;
+
+       /* Set up a handy pointer to the appropriate PDE. */
+       struct pde *pde = &(pdts[pdpt_idx][pdt_idx]);
+
+       memset(pde, 0, sizeof(struct pde));
+       pde->p = 1;
+       pde->rw = 1;
+       pde->us = 1;
+       pde->ps = 1;
+       pde->base = phys >> 21;
+
+       if (invlpg) {
+               /* Flush any stale mapping out of the TLBs. */
+               __asm__ __volatile__(
+                       "invlpg %0\n\t"
+                       :
+                       : "m" (*(uint8_t *)virt)
+               );
+       }
+}
+
+/* Identity map the lower 4GB and turn on paging with PAE. */
+static void x86_phys_enter_paging(void)
+{
+       phys_addr_t page_addr;
+       unsigned i;
+
+       /* Zero out the page tables. */
+       memset(pdpt, 0, sizeof(pdpt));
+       memset(pdts, 0, sizeof(pdts));
+
+       /* Set up the PDPT. */
+       for (i = 0; i < ARRAY_SIZE(pdts); i++) {
+               pdpt[i].p = 1;
+               pdpt[i].base = ((uintptr_t)&pdts[i]) >> 12;
+       }
+
+       /* Identity map everything up to 4GB. */
+       for (page_addr = 0; page_addr < (1ULL << 32);
+                       page_addr += LARGE_PAGE_SIZE) {
+               /* There's no reason to invalidate the TLB with paging off. */
+               x86_phys_map_page(page_addr, page_addr, 0);
+       }
+
+       /* Turn on paging */
+       __asm__ __volatile__(
+               /* Load the page table address */
+               "movl   %0, %%cr3\n\t"
+               /* Enable pae */
+               "movl   %%cr4, %%eax\n\t"
+               "orl    $0x00000020, %%eax\n\t"
+               "movl   %%eax, %%cr4\n\t"
+               /* Enable paging */
+               "movl   %%cr0, %%eax\n\t"
+               "orl    $0x80000000, %%eax\n\t"
+               "movl   %%eax, %%cr0\n\t"
+               :
+               : "r" (pdpt)
+               : "eax"
+       );
+}
+
+/* Disable paging and PAE mode. */
+static void x86_phys_exit_paging(void)
+{
+       /* Turn off paging */
+       __asm__ __volatile__ (
+               /* Disable paging */
+               "movl   %%cr0, %%eax\n\t"
+               "andl   $0x7fffffff, %%eax\n\t"
+               "movl   %%eax, %%cr0\n\t"
+               /* Disable pae */
+               "movl   %%cr4, %%eax\n\t"
+               "andl   $0xffffffdf, %%eax\n\t"
+               "movl   %%eax, %%cr4\n\t"
+               :
+               :
+               : "eax"
+       );
+}
+
+/*
+ * Set physical memory to a particular value when the whole region fits on one
+ * page.
+ *
+ * @param map_addr     The address that starts the physical page.
+ * @param offset       How far into that page to start setting a value.
+ * @param c            The value to set memory to.
+ * @param size         The size in bytes of the area to set.
+ */
+static void x86_phys_memset_page(phys_addr_t map_addr, uintptr_t offset, int c,
+                                unsigned size)
+{
+       /*
+        * U-Boot should be far away from the beginning of memory, so that's a
+        * good place to map our window on top of.
+        */
+       const uintptr_t window = LARGE_PAGE_SIZE;
+
+       /* Make sure the window is below U-Boot. */
+       assert(window + LARGE_PAGE_SIZE <
+              gd->relocaddr - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_STACK_SIZE);
+       /* Map the page into the window and then memset the appropriate part. */
+       x86_phys_map_page(window, map_addr, 1);
+       memset((void *)(window + offset), c, size);
+}
+
+/*
+ * A physical memory anologue to memset with matching parameters and return
+ * value.
+ */
+phys_addr_t arch_phys_memset(phys_addr_t start, int c, phys_size_t size)
+{
+       const phys_addr_t max_addr = (phys_addr_t)~(uintptr_t)0;
+       const phys_addr_t orig_start = start;
+
+       if (!size)
+               return orig_start;
+
+       /* Handle memory below 4GB. */
+       if (start <= max_addr) {
+               phys_size_t low_size = MIN(max_addr + 1 - start, size);
+               void *start_ptr = (void *)(uintptr_t)start;
+
+               assert(((phys_addr_t)(uintptr_t)start) == start);
+               memset(start_ptr, c, low_size);
+               start += low_size;
+               size -= low_size;
+       }
+
+       /* Use paging and PAE to handle memory above 4GB up to 64GB. */
+       if (size) {
+               phys_addr_t map_addr = start & ~(LARGE_PAGE_SIZE - 1);
+               phys_addr_t offset = start - map_addr;
+
+               x86_phys_enter_paging();
+
+               /* Handle the first partial page. */
+               if (offset) {
+                       phys_addr_t end =
+                               MIN(map_addr + LARGE_PAGE_SIZE, start + size);
+                       phys_size_t cur_size = end - start;
+                       x86_phys_memset_page(map_addr, offset, c, cur_size);
+                       size -= cur_size;
+                       map_addr += LARGE_PAGE_SIZE;
+               }
+               /* Handle the complete pages. */
+               while (size > LARGE_PAGE_SIZE) {
+                       x86_phys_memset_page(map_addr, 0, c, LARGE_PAGE_SIZE);
+                       size -= LARGE_PAGE_SIZE;
+                       map_addr += LARGE_PAGE_SIZE;
+               }
+               /* Handle the last partial page. */
+               if (size)
+                       x86_phys_memset_page(map_addr, 0, c, size);
+
+               x86_phys_exit_paging();
+       }
+       return orig_start;
+}
index 200baaba6a2707c28fabc82cb93054158cdff5c0..23edca95269f36a7215f040fc1420e009a942541 100644 (file)
@@ -80,12 +80,12 @@ int do_elf_reloc_fixups(void)
 
                        /* Check that the target points into .text */
                        if (*offset_ptr_ram >= CONFIG_SYS_TEXT_BASE &&
-                                       *offset_ptr_ram <
+                                       *offset_ptr_ram <=
                                        (CONFIG_SYS_TEXT_BASE + size)) {
                                *offset_ptr_ram += gd->reloc_off;
                        }
                }
-       } while (re_src++ < re_end);
+       } while (++re_src < re_end);
 
        return 0;
 }
index fd7032e92c9f40e007348aac3a249e5078284b82..a13424b3e378ce14819ca445afb9109c60874359 100644 (file)
@@ -37,6 +37,7 @@ struct timer_isr_function {
 
 static struct timer_isr_function *first_timer_isr;
 static unsigned long system_ticks;
+static uint64_t base_value;
 
 /*
  * register_timer_isr() allows multiple architecture and board specific
@@ -98,3 +99,19 @@ ulong get_timer(ulong base)
 {
        return system_ticks - base;
 }
+
+void timer_set_tsc_base(uint64_t new_base)
+{
+       base_value = new_base;
+}
+
+uint64_t timer_get_tsc(void)
+{
+       uint64_t time_now;
+
+       time_now = rdtsc();
+       if (!base_value)
+               base_value = time_now;
+
+       return time_now - base_value;
+}
index b8c672babddc23fa06189efa31e09f300180a01f..46af391f29f2a82baebd91acf6e55d638dc7524b 100644 (file)
 #include <asm/realmode.h>
 #include <asm/byteorder.h>
 #include <asm/bootparam.h>
+#ifdef CONFIG_SYS_COREBOOT
+#include <asm/arch/timestamp.h>
+#endif
+#include <linux/compiler.h>
 
 /*
  * Memory lay-out:
@@ -279,10 +283,23 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
        return 0;
 }
 
+/*
+ * Implement a weak default function for boards that optionally
+ * need to clean up the system before jumping to the kernel.
+ */
+__weak void board_final_cleanup(void)
+{
+}
+
 void boot_zimage(void *setup_base, void *load_address)
 {
+       board_final_cleanup();
+
        printf("\nStarting kernel ...\n\n");
 
+#ifdef CONFIG_SYS_COREBOOT
+       timestamp_add_now(TS_U_BOOT_START_KERNEL);
+#endif
 #if defined CONFIG_ZBOOT_32
        /*
         * Set %ebx, %ebp, and %edi to 0, %esi to point to the boot_params
@@ -292,9 +309,9 @@ void boot_zimage(void *setup_base, void *load_address)
         * itself in arch/i386/cpu/cpu.c.
         */
        __asm__ __volatile__ (
-       "movl $0, %%ebp         \n"
-       "cli                    \n"
-       "jmp %[kernel_entry]    \n"
+       "movl $0, %%ebp\n"
+       "cli\n"
+       "jmp *%[kernel_entry]\n"
        :: [kernel_entry]"a"(load_address),
           [boot_params] "S"(setup_base),
           "b"(0), "D"(0)
similarity index 53%
rename from board/chromebook-x86/dts/x86-alex.dts
rename to board/chromebook-x86/dts/alex.dts
index bd90d185f1c589398930ef5b4408101c6db87f57..cb6a9e41eeda98746ac27905ee314155b6af862e 100644 (file)
@@ -1,5 +1,7 @@
 /dts-v1/;
 
+/include/ "coreboot.dtsi"
+
 / {
         #address-cells = <1>;
         #size-cells = <1>;
               silent_console = <0>;
        };
 
-       aliases {
-               console = "/serial@e0401000";
-       };
+        gpio: gpio {};
 
-       serial@e0401000 {
-               compatible = "ns16550";
-               reg = <0xe0401000 0x40>;
-               id = <1>;
-               reg-shift = <1>;
-               baudrate = <115200>;
-               clock-frequency = <4000000>;
-               multiplier = <1>;
-               status = "ok";
+       serial {
+               reg = <0x3f8 8>;
+               clock-frequency = <115200>;
        };
 
         chosen { };
diff --git a/board/chromebook-x86/dts/link.dts b/board/chromebook-x86/dts/link.dts
new file mode 100644 (file)
index 0000000..af60f59
--- /dev/null
@@ -0,0 +1,24 @@
+/dts-v1/;
+
+/include/ "coreboot.dtsi"
+
+/ {
+        #address-cells = <1>;
+        #size-cells = <1>;
+       model = "Google Link";
+       compatible = "google,link", "intel,celeron-ivybridge";
+
+       config {
+              silent_console = <0>;
+       };
+
+        gpio: gpio {};
+
+       serial {
+               reg = <0x3f8 8>;
+               clock-frequency = <115200>;
+       };
+
+        chosen { };
+        memory { device_type = "memory"; reg = <0 0>; };
+};
index 70a1569321f9fb6c816454959a5b4c593950328e..35f38f31d4b5a61a8059ae27947ed1d10cf7d425 100644 (file)
@@ -1100,7 +1100,7 @@ gr_cpci_ax2000               sparc       leon3       -                   gaisler
 gr_ep2s60                    sparc       leon3       -                   gaisler
 grsim                        sparc       leon3       -                   gaisler
 gr_xc3s_1500                 sparc       leon3       -                   gaisler
-coreboot-x86                 x86         x86        coreboot            chromebook-x86 coreboot    coreboot:SYS_TEXT_BASE=0xFC0000
+coreboot-x86                 x86         x86        coreboot            chromebook-x86 coreboot    coreboot:SYS_TEXT_BASE=0x01110000
 eNET                         x86         x86        eNET                -              sc520       eNET:SYS_TEXT_BASE=0x38040000
 eNET_SRAM                    x86         x86        eNET                -              sc520       eNET:SYS_TEXT_BASE=0x19000000
 # Target                     ARCH        CPU         Board name          Vendor                SoC         Options
index d50ac3bfefd12b70dd898a4a1d18ae25b8b1f99d..2d97b4f1e4d521796af31646480671465d6a0d1d 100644 (file)
@@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
 LIB    := $(obj)libgpio.o
 
 COBJS-$(CONFIG_AT91_GPIO)      += at91_gpio.o
+COBJS-$(CONFIG_INTEL_ICH6_GPIO)        += intel_ich6_gpio.o
 COBJS-$(CONFIG_KIRKWOOD_GPIO)  += kw_gpio.o
 COBJS-$(CONFIG_MARVELL_GPIO)   += mvgpio.o
 COBJS-$(CONFIG_MARVELL_MFP)    += mvmfp.o
diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
new file mode 100644 (file)
index 0000000..6fed01f
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * This is a GPIO driver for Intel ICH6 and later. The x86 GPIOs are accessed
+ * through the PCI bus. Each PCI device has 256 bytes of configuration space,
+ * consisting of a standard header and a device-specific set of registers. PCI
+ * bus 0, device 31, function 0 gives us access to the chipset GPIOs (among
+ * other things). Within the PCI configuration space, the GPIOBASE register
+ * tells us where in the device's I/O region we can find more registers to
+ * actually access the GPIOs.
+ *
+ * PCI bus/device/function 0:1f:0  => PCI config registers
+ *   PCI config register "GPIOBASE"
+ *     PCI I/O space + [GPIOBASE]  => start of GPIO registers
+ *       GPIO registers => gpio pin function, direction, value
+ *
+ *
+ * Danger Will Robinson! Bank 0 (GPIOs 0-31) seems to be fairly stable. Most
+ * ICH versions have more, but the decoding the matrix that describes them is
+ * absurdly complex and constantly changing. We'll provide Bank 1 and Bank 2,
+ * but they will ONLY work for certain unspecified chipsets because the offset
+ * from GPIOBASE changes randomly. Even then, many GPIOs are unimplemented or
+ * reserved or subject to arcane restrictions.
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+
+/* Where in config space is the register that points to the GPIO registers? */
+#define PCI_CFG_GPIOBASE 0x48
+
+#define NUM_BANKS 3
+
+/* Within the I/O space, where are the registers to control the GPIOs? */
+static struct {
+       u8 use_sel;
+       u8 io_sel;
+       u8 lvl;
+} gpio_bank[NUM_BANKS] = {
+       { 0x00, 0x04, 0x0c },           /* Bank 0 */
+       { 0x30, 0x34, 0x38 },           /* Bank 1 */
+       { 0x40, 0x44, 0x48 }            /* Bank 2 */
+};
+
+static pci_dev_t dev;                  /* handle for 0:1f:0 */
+static u32 gpiobase;                   /* offset into I/O space */
+static int found_it_once;              /* valid GPIO device? */
+static u32 lock[NUM_BANKS];            /* "lock" for access to pins */
+
+static int bad_arg(int num, int *bank, int *bitnum)
+{
+       int i = num / 32;
+       int j = num % 32;
+
+       if (num < 0 || i > NUM_BANKS) {
+               debug("%s: bogus gpio num: %d\n", __func__, num);
+               return -1;
+       }
+       *bank = i;
+       *bitnum = j;
+       return 0;
+}
+
+static int mark_gpio(int bank, int bitnum)
+{
+       if (lock[bank] & (1UL << bitnum)) {
+               debug("%s: %d.%d already marked\n", __func__, bank, bitnum);
+               return -1;
+       }
+       lock[bank] |= (1 << bitnum);
+       return 0;
+}
+
+static void clear_gpio(int bank, int bitnum)
+{
+       lock[bank] &= ~(1 << bitnum);
+}
+
+static int notmine(int num, int *bank, int *bitnum)
+{
+       if (bad_arg(num, bank, bitnum))
+               return -1;
+       return !(lock[*bank] & (1UL << *bitnum));
+}
+
+static int gpio_init(void)
+{
+       u8 tmpbyte;
+       u16 tmpword;
+       u32 tmplong;
+
+       /* Have we already done this? */
+       if (found_it_once)
+               return 0;
+
+       /* Where should it be? */
+       dev = PCI_BDF(0, 0x1f, 0);
+
+       /* Is the device present? */
+       pci_read_config_word(dev, PCI_VENDOR_ID, &tmpword);
+       if (tmpword != PCI_VENDOR_ID_INTEL) {
+               debug("%s: wrong VendorID\n", __func__);
+               return -1;
+       }
+
+       pci_read_config_word(dev, PCI_DEVICE_ID, &tmpword);
+       debug("Found %04x:%04x\n", PCI_VENDOR_ID_INTEL, tmpword);
+       /*
+        * We'd like to validate the Device ID too, but pretty much any
+        * value is either a) correct with slight differences, or b)
+        * correct but undocumented. We'll have to check a bunch of other
+        * things instead...
+        */
+
+       /* I/O should already be enabled (it's a RO bit). */
+       pci_read_config_word(dev, PCI_COMMAND, &tmpword);
+       if (!(tmpword & PCI_COMMAND_IO)) {
+               debug("%s: device IO not enabled\n", __func__);
+               return -1;
+       }
+
+       /* Header Type must be normal (bits 6-0 only; see spec.) */
+       pci_read_config_byte(dev, PCI_HEADER_TYPE, &tmpbyte);
+       if ((tmpbyte & 0x7f) != PCI_HEADER_TYPE_NORMAL) {
+               debug("%s: invalid Header type\n", __func__);
+               return -1;
+       }
+
+       /* Base Class must be a bridge device */
+       pci_read_config_byte(dev, PCI_CLASS_CODE, &tmpbyte);
+       if (tmpbyte != PCI_CLASS_CODE_BRIDGE) {
+               debug("%s: invalid class\n", __func__);
+               return -1;
+       }
+       /* Sub Class must be ISA */
+       pci_read_config_byte(dev, PCI_CLASS_SUB_CODE, &tmpbyte);
+       if (tmpbyte != PCI_CLASS_SUB_CODE_BRIDGE_ISA) {
+               debug("%s: invalid subclass\n", __func__);
+               return -1;
+       }
+
+       /* Programming Interface must be 0x00 (no others exist) */
+       pci_read_config_byte(dev, PCI_CLASS_PROG, &tmpbyte);
+       if (tmpbyte != 0x00) {
+               debug("%s: invalid interface type\n", __func__);
+               return -1;
+       }
+
+       /*
+        * GPIOBASE moved to its current offset with ICH6, but prior to
+        * that it was unused (or undocumented). Check that it looks
+        * okay: not all ones or zeros, and mapped to I/O space (bit 0).
+        */
+       pci_read_config_dword(dev, PCI_CFG_GPIOBASE, &tmplong);
+       if (tmplong == 0x00000000 || tmplong == 0xffffffff ||
+           !(tmplong & 0x00000001)) {
+               debug("%s: unexpected GPIOBASE value\n", __func__);
+               return -1;
+       }
+
+       /*
+        * Okay, I guess we're looking at the right device. The actual
+        * GPIO registers are in the PCI device's I/O space, starting
+        * at the offset that we just read. Bit 0 indicates that it's
+        * an I/O address, not a memory address, so mask that off.
+        */
+       gpiobase = tmplong & 0xfffffffe;
+
+       /* Finally. These are the droids we're looking for. */
+       found_it_once = 1;
+       return 0;
+}
+
+int gpio_request(unsigned num, const char *label /* UNUSED */)
+{
+       u32 tmplong;
+       int i = 0, j = 0;
+
+       /* Is the hardware ready? */
+       if (gpio_init())
+               return -1;
+
+       if (bad_arg(num, &i, &j))
+               return -1;
+
+       /*
+        * Make sure that the GPIO pin we want isn't already in use for some
+        * built-in hardware function. We have to check this for every
+        * requested pin.
+        */
+       tmplong = inl(gpiobase + gpio_bank[i].use_sel);
+       if (!(tmplong & (1UL << j))) {
+               debug("%s: gpio %d is reserved for internal use\n", __func__,
+                     num);
+               return -1;
+       }
+
+       return mark_gpio(i, j);
+}
+
+int gpio_free(unsigned num)
+{
+       int i = 0, j = 0;
+
+       if (notmine(num, &i, &j))
+               return -1;
+
+       clear_gpio(i, j);
+       return 0;
+}
+
+int gpio_direction_input(unsigned num)
+{
+       u32 tmplong;
+       int i = 0, j = 0;
+
+       if (notmine(num, &i, &j))
+               return -1;
+
+       tmplong = inl(gpiobase + gpio_bank[i].io_sel);
+       tmplong |= (1UL << j);
+       outl(gpiobase + gpio_bank[i].io_sel, tmplong);
+       return 0;
+}
+
+int gpio_direction_output(unsigned num, int value)
+{
+       u32 tmplong;
+       int i = 0, j = 0;
+
+       if (notmine(num, &i, &j))
+               return -1;
+
+       tmplong = inl(gpiobase + gpio_bank[i].io_sel);
+       tmplong &= ~(1UL << j);
+       outl(gpiobase + gpio_bank[i].io_sel, tmplong);
+       return 0;
+}
+
+int gpio_get_value(unsigned num)
+{
+       u32 tmplong;
+       int i = 0, j = 0;
+       int r;
+
+       if (notmine(num, &i, &j))
+               return -1;
+
+       tmplong = inl(gpiobase + gpio_bank[i].lvl);
+       r = (tmplong & (1UL << j)) ? 1 : 0;
+       return r;
+}
+
+int gpio_set_value(unsigned num, int value)
+{
+       u32 tmplong;
+       int i = 0, j = 0;
+
+       if (notmine(num, &i, &j))
+               return -1;
+
+       tmplong = inl(gpiobase + gpio_bank[i].lvl);
+       if (value)
+               tmplong |= (1UL << j);
+       else
+               tmplong &= ~(1UL << j);
+       outl(gpiobase + gpio_bank[i].lvl, tmplong);
+       return 0;
+}
index 9388859da7e07f52ca324adfabdd49f9fbadbe08..26f673a96a9b8937932df50395cecbac87b0e23f 100644 (file)
@@ -2293,6 +2293,8 @@ int video_get_screen_columns(void)
 
 void video_clear(void)
 {
+       if (!video_fb_address)
+               return;
 #ifdef VIDEO_HW_RECTFILL
        video_hw_rectfill(VIDEO_PIXEL_SIZE,     /* bytes per pixel */
                          0,                    /* dest pos x */
index a010adc2d99a4f014af0f199d3ce530ec1c94e81..adeace0cf2ef8211ab5bbae66d3e7adfd23d0b0a 100644 (file)
  * (easy to change)
  */
 #define CONFIG_SYS_COREBOOT
-#undef CONFIG_SHOW_BOOT_PROGRESS
+#define CONFIG_SHOW_BOOT_PROGRESS
 #define CONFIG_LAST_STAGE_INIT
 #define CONFIG_X86_NO_RESET_VECTOR
 #define CONFIG_SYS_VSNPRINTF
+#define CONFIG_INTEL_CORE_ARCH /* Sandy bridge and ivy bridge chipsets. */
+#define CONFIG_ZBOOT_32
+#define CONFIG_PHYSMEM
 
 /*-----------------------------------------------------------------------
  * Watchdog Configuration
@@ -77,6 +80,7 @@
  */
 #define CONFIG_RTC_MC146818
 #define CONFIG_SYS_ISA_IO_BASE_ADDRESS 0
+#define CONFIG_SYS_ISA_IO      CONFIG_SYS_ISA_IO_BASE_ADDRESS
 
 /*-----------------------------------------------------------------------
  * Serial Configuration
 #define CONFIG_SYS_STDIO_DEREGISTER
 #define CONFIG_CBMEM_CONSOLE
 
-/* max. 1 IDE bus      */
-#define CONFIG_SYS_IDE_MAXBUS          1
-/* max. 1 drive per IDE bus */
-#define CONFIG_SYS_IDE_MAXDEVICE       (CONFIG_SYS_IDE_MAXBUS * 1)
-
-#define CONFIG_SYS_ATA_BASE_ADDR       CONFIG_SYS_ISA_IO_BASE_ADDRESS
-#define CONFIG_SYS_ATA_IDE0_OFFSET     0x01f0
-#define CONFIG_SYS_ATA_IDE1_OFFSET     0x0170
-#define CONFIG_SYS_ATA_DATA_OFFSET     0
-#define CONFIG_SYS_ATA_REG_OFFSET      0
-#define CONFIG_SYS_ATA_ALT_OFFSET      0x200
-
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_COMMAND_HISTORY
+#define CONFIG_AUTOCOMPLETE
 
 #define CONFIG_SUPPORT_VFAT
 /************************************************************
 /************************************************************
  * DISK Partition support
  ************************************************************/
+#define CONFIG_EFI_PARTITION
 #define CONFIG_DOS_PARTITION
 #define CONFIG_MAC_PARTITION
 #define CONFIG_ISO_PARTITION           /* Experimental */
 
+#define CONFIG_CMD_PART
 #define CONFIG_CMD_CBFS
 #define CONFIG_CMD_EXT4
 #define CONFIG_CMD_EXT4_WRITE
+#define CONFIG_PARTITION_UUIDS
 
 /*-----------------------------------------------------------------------
  * Video Configuration
  */
-#undef CONFIG_VIDEO
-#undef CONFIG_CFB_CONSOLE
+#define CONFIG_VIDEO
+#define CONFIG_VIDEO_COREBOOT
+#define CONFIG_VIDEO_SW_CURSOR
+#define VIDEO_FB_16BPP_WORD_SWAP
+#define CONFIG_I8042_KBD
+#define CONFIG_CFB_CONSOLE
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+
+/* x86 GPIOs are accessed through a PCI device */
+#define CONFIG_INTEL_ICH6_GPIO
 
 /*-----------------------------------------------------------------------
  * Command line configuration.
 #define CONFIG_CMD_ECHO
 #undef CONFIG_CMD_FLASH
 #define CONFIG_CMD_FPGA
+#define CONFIG_CMD_GPIO
 #define CONFIG_CMD_IMI
 #undef CONFIG_CMD_IMLS
 #define CONFIG_CMD_IRQ
 #define CONFIG_CMD_SETGETDCR
 #define CONFIG_CMD_SOURCE
 #define CONFIG_CMD_XIMG
-#define CONFIG_CMD_IDE
+#define CONFIG_CMD_SCSI
+
 #define CONFIG_CMD_FAT
 #define CONFIG_CMD_EXT2
 
+#define CONFIG_CMD_ZBOOT
+
 #define CONFIG_BOOTDELAY       2
-#define CONFIG_BOOTARGS                "root=/dev/mtdblock0 console=ttyS0,9600"
+#define CONFIG_BOOTARGS                \
+       "root=/dev/sdb3 init=/sbin/init rootwait ro"
+#define CONFIG_BOOTCOMMAND     \
+       "ext2load scsi 0:3 01000000 /boot/vmlinuz; zboot 01000000"
+
 
 #if defined(CONFIG_CMD_KGDB)
 #define CONFIG_KGDB_BAUDRATE                   115200
index eba122f8c0e14b48d405e5fd8e55ac607fbf6e08..15f583f069d4ca1c45f09893542af487cb37f998 100644 (file)
 #define PCI_CLASS_PROG         0x09    /* Reg. Level Programming Interface */
 #define PCI_CLASS_DEVICE       0x0a    /* Device class */
 #define PCI_CLASS_CODE         0x0b    /* Device class code */
+#define  PCI_CLASS_CODE_TOO_OLD        0x00
+#define  PCI_CLASS_CODE_STORAGE 0x01
+#define  PCI_CLASS_CODE_NETWORK 0x02
+#define  PCI_CLASS_CODE_DISPLAY        0x03
+#define  PCI_CLASS_CODE_MULTIMEDIA 0x04
+#define  PCI_CLASS_CODE_MEMORY 0x05
+#define  PCI_CLASS_CODE_BRIDGE 0x06
+#define  PCI_CLASS_CODE_COMM   0x07
+#define  PCI_CLASS_CODE_PERIPHERAL 0x08
+#define  PCI_CLASS_CODE_INPUT  0x09
+#define  PCI_CLASS_CODE_DOCKING        0x0A
+#define  PCI_CLASS_CODE_PROCESSOR 0x0B
+#define  PCI_CLASS_CODE_SERIAL 0x0C
+#define  PCI_CLASS_CODE_WIRELESS 0x0D
+#define  PCI_CLASS_CODE_I2O    0x0E
+#define  PCI_CLASS_CODE_SATELLITE 0x0F
+#define  PCI_CLASS_CODE_CRYPTO 0x10
+#define  PCI_CLASS_CODE_DATA   0x11
+/* Base Class 0x12 - 0xFE is reserved */
+#define  PCI_CLASS_CODE_OTHER  0xFF
+
 #define PCI_CLASS_SUB_CODE     0x0a    /* Device sub-class code */
+#define  PCI_CLASS_SUB_CODE_TOO_OLD_NOTVGA     0x00
+#define  PCI_CLASS_SUB_CODE_TOO_OLD_VGA                0x01
+#define  PCI_CLASS_SUB_CODE_STORAGE_SCSI       0x00
+#define  PCI_CLASS_SUB_CODE_STORAGE_IDE                0x01
+#define  PCI_CLASS_SUB_CODE_STORAGE_FLOPPY     0x02
+#define  PCI_CLASS_SUB_CODE_STORAGE_IPIBUS     0x03
+#define  PCI_CLASS_SUB_CODE_STORAGE_RAID       0x04
+#define  PCI_CLASS_SUB_CODE_STORAGE_ATA                0x05
+#define  PCI_CLASS_SUB_CODE_STORAGE_SATA       0x06
+#define  PCI_CLASS_SUB_CODE_STORAGE_SAS                0x07
+#define  PCI_CLASS_SUB_CODE_STORAGE_OTHER      0x80
+#define  PCI_CLASS_SUB_CODE_NETWORK_ETHERNET   0x00
+#define  PCI_CLASS_SUB_CODE_NETWORK_TOKENRING  0x01
+#define  PCI_CLASS_SUB_CODE_NETWORK_FDDI       0x02
+#define  PCI_CLASS_SUB_CODE_NETWORK_ATM                0x03
+#define  PCI_CLASS_SUB_CODE_NETWORK_ISDN       0x04
+#define  PCI_CLASS_SUB_CODE_NETWORK_WORLDFIP   0x05
+#define  PCI_CLASS_SUB_CODE_NETWORK_PICMG      0x06
+#define  PCI_CLASS_SUB_CODE_NETWORK_OTHER      0x80
+#define  PCI_CLASS_SUB_CODE_DISPLAY_VGA                0x00
+#define  PCI_CLASS_SUB_CODE_DISPLAY_XGA                0x01
+#define  PCI_CLASS_SUB_CODE_DISPLAY_3D         0x02
+#define  PCI_CLASS_SUB_CODE_DISPLAY_OTHER      0x80
+#define  PCI_CLASS_SUB_CODE_MULTIMEDIA_VIDEO   0x00
+#define  PCI_CLASS_SUB_CODE_MULTIMEDIA_AUDIO   0x01
+#define  PCI_CLASS_SUB_CODE_MULTIMEDIA_PHONE   0x02
+#define  PCI_CLASS_SUB_CODE_MULTIMEDIA_OTHER   0x80
+#define  PCI_CLASS_SUB_CODE_MEMORY_RAM         0x00
+#define  PCI_CLASS_SUB_CODE_MEMORY_FLASH       0x01
+#define  PCI_CLASS_SUB_CODE_MEMORY_OTHER       0x80
+#define  PCI_CLASS_SUB_CODE_BRIDGE_HOST                0x00
+#define  PCI_CLASS_SUB_CODE_BRIDGE_ISA         0x01
+#define  PCI_CLASS_SUB_CODE_BRIDGE_EISA                0x02
+#define  PCI_CLASS_SUB_CODE_BRIDGE_MCA         0x03
+#define  PCI_CLASS_SUB_CODE_BRIDGE_PCI         0x04
+#define  PCI_CLASS_SUB_CODE_BRIDGE_PCMCIA      0x05
+#define  PCI_CLASS_SUB_CODE_BRIDGE_NUBUS       0x06
+#define  PCI_CLASS_SUB_CODE_BRIDGE_CARDBUS     0x07
+#define  PCI_CLASS_SUB_CODE_BRIDGE_RACEWAY     0x08
+#define  PCI_CLASS_SUB_CODE_BRIDGE_SEMI_PCI    0x09
+#define  PCI_CLASS_SUB_CODE_BRIDGE_INFINIBAND  0x0A
+#define  PCI_CLASS_SUB_CODE_BRIDGE_OTHER       0x80
+#define  PCI_CLASS_SUB_CODE_COMM_SERIAL                0x00
+#define  PCI_CLASS_SUB_CODE_COMM_PARALLEL      0x01
+#define  PCI_CLASS_SUB_CODE_COMM_MULTIPORT     0x02
+#define  PCI_CLASS_SUB_CODE_COMM_MODEM         0x03
+#define  PCI_CLASS_SUB_CODE_COMM_GPIB          0x04
+#define  PCI_CLASS_SUB_CODE_COMM_SMARTCARD     0x05
+#define  PCI_CLASS_SUB_CODE_COMM_OTHER         0x80
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_PIC     0x00
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_DMA     0x01
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_TIMER   0x02
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_RTC     0x03
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_HOTPLUG 0x04
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_SD      0x05
+#define  PCI_CLASS_SUB_CODE_PERIPHERAL_OTHER   0x80
+#define  PCI_CLASS_SUB_CODE_INPUT_KEYBOARD     0x00
+#define  PCI_CLASS_SUB_CODE_INPUT_DIGITIZER    0x01
+#define  PCI_CLASS_SUB_CODE_INPUT_MOUSE                0x02
+#define  PCI_CLASS_SUB_CODE_INPUT_SCANNER      0x03
+#define  PCI_CLASS_SUB_CODE_INPUT_GAMEPORT     0x04
+#define  PCI_CLASS_SUB_CODE_INPUT_OTHER                0x80
+#define  PCI_CLASS_SUB_CODE_DOCKING_GENERIC    0x00
+#define  PCI_CLASS_SUB_CODE_DOCKING_OTHER      0x80
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_386      0x00
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_486      0x01
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_PENTIUM  0x02
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_ALPHA    0x10
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_POWERPC  0x20
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_MIPS     0x30
+#define  PCI_CLASS_SUB_CODE_PROCESSOR_COPROC   0x40
+#define  PCI_CLASS_SUB_CODE_SERIAL_1394                0x00
+#define  PCI_CLASS_SUB_CODE_SERIAL_ACCESSBUS   0x01
+#define  PCI_CLASS_SUB_CODE_SERIAL_SSA         0x02
+#define  PCI_CLASS_SUB_CODE_SERIAL_USB         0x03
+#define  PCI_CLASS_SUB_CODE_SERIAL_FIBRECHAN   0x04
+#define  PCI_CLASS_SUB_CODE_SERIAL_SMBUS       0x05
+#define  PCI_CLASS_SUB_CODE_SERIAL_INFINIBAND  0x06
+#define  PCI_CLASS_SUB_CODE_SERIAL_IPMI                0x07
+#define  PCI_CLASS_SUB_CODE_SERIAL_SERCOS      0x08
+#define  PCI_CLASS_SUB_CODE_SERIAL_CANBUS      0x09
+#define  PCI_CLASS_SUB_CODE_WIRELESS_IRDA      0x00
+#define  PCI_CLASS_SUB_CODE_WIRELESS_IR                0x01
+#define  PCI_CLASS_SUB_CODE_WIRELESS_RF                0x10
+#define  PCI_CLASS_SUB_CODE_WIRELESS_BLUETOOTH 0x11
+#define  PCI_CLASS_SUB_CODE_WIRELESS_BROADBAND 0x12
+#define  PCI_CLASS_SUB_CODE_WIRELESS_80211A    0x20
+#define  PCI_CLASS_SUB_CODE_WIRELESS_80211B    0x21
+#define  PCI_CLASS_SUB_CODE_WIRELESS_OTHER     0x80
+#define  PCI_CLASS_SUB_CODE_I2O_V1_0           0x00
+#define  PCI_CLASS_SUB_CODE_SATELLITE_TV       0x01
+#define  PCI_CLASS_SUB_CODE_SATELLITE_AUDIO    0x02
+#define  PCI_CLASS_SUB_CODE_SATELLITE_VOICE    0x03
+#define  PCI_CLASS_SUB_CODE_SATELLITE_DATA     0x04
+#define  PCI_CLASS_SUB_CODE_CRYPTO_NETWORK     0x00
+#define  PCI_CLASS_SUB_CODE_CRYPTO_ENTERTAINMENT 0x10
+#define  PCI_CLASS_SUB_CODE_CRYPTO_OTHER       0x80
+#define  PCI_CLASS_SUB_CODE_DATA_DPIO          0x00
+#define  PCI_CLASS_SUB_CODE_DATA_PERFCNTR      0x01
+#define  PCI_CLASS_SUB_CODE_DATA_COMMSYNC      0x10
+#define  PCI_CLASS_SUB_CODE_DATA_MGMT          0x20
+#define  PCI_CLASS_SUB_CODE_DATA_OTHER         0x80
 
 #define PCI_CACHE_LINE_SIZE    0x0c    /* 8 bits */
 #define PCI_LATENCY_TIMER      0x0d    /* 8 bits */
diff --git a/include/physmem.h b/include/physmem.h
new file mode 100644 (file)
index 0000000..03d3a78
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+/*
+ * These functions work like memset but operate on physical memory which may
+ * not be accessible directly.
+ *
+ * @param s    The physical address to start setting memory at.
+ * @param c    The character to set each byte of the region to.
+ * @param n    The number of bytes to set.
+ *
+ * @return     The physical address of the memory which was set.
+ */
+phys_addr_t arch_phys_memset(phys_addr_t s, int c, phys_size_t n);
index e44e04523313af357b039330409fb475aca09b65..f83f6e8d8c50cf410632ba7f17635047355606c0 100644 (file)
@@ -48,6 +48,7 @@ COBJS-$(CONFIG_LMB) += lmb.o
 COBJS-y += ldiv.o
 COBJS-$(CONFIG_MD5) += md5.o
 COBJS-y += net_utils.o
+COBJS-$(CONFIG_PHYSMEM) += physmem.o
 COBJS-y += qsort.o
 COBJS-$(CONFIG_SHA1) += sha1.o
 COBJS-$(CONFIG_SHA256) += sha256.o
diff --git a/lib/physmem.c b/lib/physmem.c
new file mode 100644 (file)
index 0000000..0f035ed
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+#include <common.h>
+#include <physmem.h>
+
+static phys_addr_t __arch_phys_memset(phys_addr_t s, int c, phys_size_t n)
+{
+       void *s_ptr = (void *)(uintptr_t)s;
+
+       assert(((phys_addr_t)(uintptr_t)s) == s);
+       assert(((phys_addr_t)(uintptr_t)(s + n)) == s + n);
+       return (phys_addr_t)(uintptr_t)memset(s_ptr, c, n);
+}
+
+phys_addr_t arch_phys_memset(phys_addr_t s, int c, phys_size_t n)
+       __attribute__((weak, alias("__arch_phys_memset")));