summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/cpu/armv7/am33xx/board.c85
-rw-r--r--arch/arm/cpu/armv7/am33xx/clock.c8
-rw-r--r--arch/arm/cpu/armv7/omap3/Makefile1
-rw-r--r--arch/arm/cpu/armv7/omap3/am35x_musb.c75
-rw-r--r--arch/arm/include/asm/arch-am33xx/cpu.h11
-rw-r--r--arch/arm/include/asm/arch-am33xx/hardware.h4
-rw-r--r--arch/arm/include/asm/arch-exynos/dwmmc.h36
-rw-r--r--arch/arm/include/asm/arch-omap3/am35x_def.h27
-rw-r--r--arch/arm/include/asm/arch-omap3/musb.h28
-rw-r--r--arch/arm/include/asm/imx-common/mx5_video.h21
-rw-r--r--arch/arm/include/asm/omap_musb.h32
-rw-r--r--arch/arm/lib/board.c8
-rw-r--r--arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c2
-rw-r--r--arch/mips/cpu/mips32/time.c1
-rw-r--r--arch/mips/cpu/mips64/time.c1
-rw-r--r--arch/powerpc/config.mk5
-rw-r--r--arch/powerpc/cpu/mpc5xxx/Makefile4
-rw-r--r--arch/powerpc/cpu/mpc5xxx/spl_boot.c79
-rw-r--r--arch/powerpc/cpu/mpc5xxx/start.S22
-rw-r--r--arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds57
-rw-r--r--arch/powerpc/cpu/mpc5xxx/usb_ohci.c2
-rw-r--r--arch/powerpc/cpu/mpc85xx/Makefile38
-rw-r--r--arch/powerpc/cpu/mpc85xx/cmd_errata.c114
-rw-r--r--arch/powerpc/cpu/mpc85xx/cpu.c17
-rw-r--r--arch/powerpc/cpu/mpc85xx/cpu_init.c14
-rw-r--r--arch/powerpc/cpu/mpc85xx/ddr-gen1.c4
-rw-r--r--arch/powerpc/cpu/mpc85xx/ddr-gen2.c9
-rw-r--r--arch/powerpc/cpu/mpc85xx/ddr-gen3.c14
-rw-r--r--arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c20
-rw-r--r--arch/powerpc/cpu/mpc85xx/release.S36
-rw-r--r--arch/powerpc/cpu/mpc85xx/spl_minimal.c (renamed from arch/powerpc/cpu/mpc85xx/cpu_init_nand.c)19
-rw-r--r--arch/powerpc/cpu/mpc85xx/start.S123
-rw-r--r--arch/powerpc/cpu/mpc85xx/tlb.c4
-rw-r--r--arch/powerpc/cpu/mpc85xx/u-boot-spl.lds87
-rw-r--r--arch/powerpc/cpu/mpc86xx/ddr-8641.c4
-rw-r--r--arch/powerpc/cpu/mpc8xxx/Makefile17
-rw-r--r--arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c10
-rw-r--r--arch/powerpc/cpu/mpc8xxx/ddr/util.c14
-rw-r--r--arch/powerpc/cpu/mpc8xxx/fdt.c6
-rw-r--r--arch/powerpc/cpu/mpc8xxx/law.c334
-rw-r--r--arch/powerpc/cpu/ppc4xx/usb_ohci.c2
-rw-r--r--arch/powerpc/include/asm/config_mpc85xx.h20
-rw-r--r--arch/powerpc/include/asm/immap_83xx.h6
-rw-r--r--arch/powerpc/include/asm/immap_85xx.h27
-rw-r--r--arch/powerpc/include/asm/immap_86xx.h8
-rw-r--r--arch/powerpc/include/asm/processor.h6
-rw-r--r--arch/powerpc/include/asm/spl.h31
-rw-r--r--arch/powerpc/lib/Makefile35
-rw-r--r--arch/powerpc/lib/bootm.c6
-rw-r--r--arch/powerpc/lib/spl.c42
-rw-r--r--arch/sh/include/asm/system.h2
-rw-r--r--arch/x86/cpu/Makefile7
-rw-r--r--arch/x86/cpu/coreboot/Makefile7
-rw-r--r--arch/x86/cpu/coreboot/car.S (renamed from arch/x86/cpu/coreboot/coreboot_car.S)0
-rw-r--r--arch/x86/cpu/coreboot/config.mk23
-rw-r--r--arch/x86/cpu/coreboot/coreboot.c140
-rw-r--r--arch/x86/cpu/coreboot/pci.c65
-rw-r--r--arch/x86/cpu/coreboot/sdram.c72
-rw-r--r--arch/x86/cpu/coreboot/sysinfo.c39
-rw-r--r--arch/x86/cpu/coreboot/tables.c117
-rw-r--r--arch/x86/cpu/coreboot/timestamp.c61
-rw-r--r--arch/x86/cpu/cpu.c49
-rw-r--r--arch/x86/cpu/interrupts.c99
-rw-r--r--arch/x86/cpu/start.S77
-rw-r--r--arch/x86/cpu/start16.S3
-rw-r--r--arch/x86/cpu/timer.c17
-rw-r--r--arch/x86/cpu/u-boot.lds3
-rw-r--r--arch/x86/dts/coreboot.dtsi16
-rw-r--r--arch/x86/dts/skeleton.dtsi13
-rw-r--r--arch/x86/include/asm/arch-coreboot/sysinfo.h34
-rw-r--r--arch/x86/include/asm/arch-coreboot/tables.h74
-rw-r--r--arch/x86/include/asm/arch-coreboot/timestamp.h52
-rw-r--r--arch/x86/include/asm/bitops.h5
-rw-r--r--arch/x86/include/asm/cache.h16
-rw-r--r--arch/x86/include/asm/control_regs.h105
-rw-r--r--arch/x86/include/asm/global_data.h18
-rw-r--r--arch/x86/include/asm/gpio.h (renamed from arch/nios2/include/asm/status_led.h)16
-rw-r--r--arch/x86/include/asm/init_helpers.h2
-rw-r--r--arch/x86/include/asm/io.h18
-rw-r--r--arch/x86/include/asm/msr-index.h469
-rw-r--r--arch/x86/include/asm/msr.h238
-rw-r--r--arch/x86/include/asm/mtrr.h206
-rw-r--r--arch/x86/include/asm/pci.h2
-rw-r--r--arch/x86/include/asm/processor.h1
-rw-r--r--arch/x86/include/asm/types.h4
-rw-r--r--arch/x86/include/asm/u-boot-x86.h14
-rw-r--r--arch/x86/include/asm/u-boot.h3
-rw-r--r--arch/x86/lib/Makefile12
-rw-r--r--arch/x86/lib/board.c15
-rw-r--r--arch/x86/lib/init_helpers.c83
-rw-r--r--arch/x86/lib/init_wrappers.c28
-rw-r--r--arch/x86/lib/pcat_timer.c2
-rw-r--r--arch/x86/lib/physmem.c228
-rw-r--r--arch/x86/lib/relocate.c4
-rw-r--r--arch/x86/lib/timer.c17
-rw-r--r--arch/x86/lib/video.c2
-rw-r--r--arch/x86/lib/zimage.c27
97 files changed, 3662 insertions, 419 deletions
diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c
index e4c123cd21..da5bc73185 100644
--- a/arch/arm/cpu/armv7/am33xx/board.c
+++ b/arch/arm/cpu/armv7/am33xx/board.c
@@ -33,6 +33,11 @@
#include <i2c.h>
#include <miiphy.h>
#include <cpsw.h>
+#include <asm/errno.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/musb.h>
+#include <asm/omap_musb.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -63,3 +68,83 @@ void setup_clocks_for_console(void)
/* Not yet implemented */
return;
}
+
+/* AM33XX has two MUSB controllers which can be host or gadget */
+#if (defined(CONFIG_MUSB_GADGET) || defined(CONFIG_MUSB_HOST)) && \
+ (defined(CONFIG_AM335X_USB0) || defined(CONFIG_AM335X_USB1))
+static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
+
+/* USB 2.0 PHY Control */
+#define CM_PHY_PWRDN (1 << 0)
+#define CM_PHY_OTG_PWRDN (1 << 1)
+#define OTGVDET_EN (1 << 19)
+#define OTGSESSENDEN (1 << 20)
+
+static void am33xx_usb_set_phy_power(u8 on, u32 *reg_addr)
+{
+ if (on) {
+ clrsetbits_le32(reg_addr, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN,
+ OTGVDET_EN | OTGSESSENDEN);
+ } else {
+ clrsetbits_le32(reg_addr, 0, CM_PHY_PWRDN | CM_PHY_OTG_PWRDN);
+ }
+}
+
+static struct musb_hdrc_config musb_config = {
+ .multipoint = 1,
+ .dyn_fifo = 1,
+ .num_eps = 16,
+ .ram_bits = 12,
+};
+
+#ifdef CONFIG_AM335X_USB0
+static void am33xx_otg0_set_phy_power(u8 on)
+{
+ am33xx_usb_set_phy_power(on, &cdev->usb_ctrl0);
+}
+
+struct omap_musb_board_data otg0_board_data = {
+ .set_phy_power = am33xx_otg0_set_phy_power,
+};
+
+static struct musb_hdrc_platform_data otg0_plat = {
+ .mode = CONFIG_AM335X_USB0_MODE,
+ .config = &musb_config,
+ .power = 50,
+ .platform_ops = &musb_dsps_ops,
+ .board_data = &otg0_board_data,
+};
+#endif
+
+#ifdef CONFIG_AM335X_USB1
+static void am33xx_otg1_set_phy_power(u8 on)
+{
+ am33xx_usb_set_phy_power(on, &cdev->usb_ctrl1);
+}
+
+struct omap_musb_board_data otg1_board_data = {
+ .set_phy_power = am33xx_otg1_set_phy_power,
+};
+
+static struct musb_hdrc_platform_data otg1_plat = {
+ .mode = CONFIG_AM335X_USB1_MODE,
+ .config = &musb_config,
+ .power = 50,
+ .platform_ops = &musb_dsps_ops,
+ .board_data = &otg1_board_data,
+};
+#endif
+#endif
+
+int arch_misc_init(void)
+{
+#ifdef CONFIG_AM335X_USB0
+ musb_register(&otg0_plat, &otg0_board_data,
+ (void *)AM335X_USB0_OTG_BASE);
+#endif
+#ifdef CONFIG_AM335X_USB1
+ musb_register(&otg1_plat, &otg1_board_data,
+ (void *)AM335X_USB1_OTG_BASE);
+#endif
+ return 0;
+}
diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock.c
index bc2abb657c..0b4cb4e529 100644
--- a/arch/arm/cpu/armv7/am33xx/clock.c
+++ b/arch/arm/cpu/armv7/am33xx/clock.c
@@ -40,6 +40,7 @@
#define CLK_MODE_MASK 0xfffffff8
#define CLK_DIV_SEL 0xFFFFFFE0
#define CPGMAC0_IDLE 0x30000
+#define DPLL_CLKDCOLDO_GATE_CTRL 0x300
const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
@@ -194,6 +195,11 @@ static void enable_per_clocks(void)
writel(PRCM_MOD_EN, &cmrtc->rtcclkctrl);
while (readl(&cmrtc->rtcclkctrl) != PRCM_MOD_EN)
;
+
+ /* MUSB */
+ writel(PRCM_MOD_EN, &cmper->usb0clkctrl);
+ while (readl(&cmper->usb0clkctrl) != PRCM_MOD_EN)
+ ;
}
static void mpu_pll_config(void)
@@ -290,6 +296,8 @@ static void per_pll_config(void)
while (readl(&cmwkup->idlestdpllper) != ST_DPLL_CLK)
;
+
+ writel(DPLL_CLKDCOLDO_GATE_CTRL, &cmwkup->clkdcoldodpllper);
}
void ddr_pll_config(unsigned int ddrpll_m)
diff --git a/arch/arm/cpu/armv7/omap3/Makefile b/arch/arm/cpu/armv7/omap3/Makefile
index ac597be25a..de167eea56 100644
--- a/arch/arm/cpu/armv7/omap3/Makefile
+++ b/arch/arm/cpu/armv7/omap3/Makefile
@@ -38,6 +38,7 @@ endif
COBJS-$(CONFIG_DRIVER_TI_EMAC) += emac.o
COBJS-$(CONFIG_EMIF4) += emif4.o
COBJS-$(CONFIG_SDRC) += sdrc.o
+COBJS-$(CONFIG_USB_MUSB_AM35X) += am35x_musb.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS))
diff --git a/arch/arm/cpu/armv7/omap3/am35x_musb.c b/arch/arm/cpu/armv7/omap3/am35x_musb.c
new file mode 100644
index 0000000000..7183c4f248
--- /dev/null
+++ b/arch/arm/cpu/armv7/omap3/am35x_musb.c
@@ -0,0 +1,75 @@
+/*
+ * This file configures the internal USB PHY in AM35X.
+ *
+ * Copyright (C) 2012 Ilya Yanok <ilya.yanok@gmail.com>
+ *
+ * Based on omap_phy_internal.c code from Linux by
+ * Hema HK <hemahk@ti.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.
+ *
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/am35x_def.h>
+
+void am35x_musb_reset(void)
+{
+ /* Reset the musb interface */
+ clrsetbits_le32(&am35x_scm_general_regs->ip_sw_reset,
+ 0, USBOTGSS_SW_RST);
+ clrsetbits_le32(&am35x_scm_general_regs->ip_sw_reset,
+ USBOTGSS_SW_RST, 0);
+}
+
+void am35x_musb_phy_power(u8 on)
+{
+ unsigned long start = get_timer(0);
+
+ if (on) {
+ /*
+ * Start the on-chip PHY and its PLL.
+ */
+ clrsetbits_le32(&am35x_scm_general_regs->devconf2,
+ CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN,
+ CONF2_PHY_PLLON);
+
+ debug("Waiting for PHY clock good...\n");
+ while (!(readl(&am35x_scm_general_regs->devconf2)
+ & CONF2_PHYCLKGD)) {
+
+ if (get_timer(start) > CONFIG_SYS_HZ / 10) {
+ printf("musb PHY clock good timed out\n");
+ break;
+ }
+ }
+ } else {
+ /*
+ * Power down the on-chip PHY.
+ */
+ clrsetbits_le32(&am35x_scm_general_regs->devconf2,
+ CONF2_PHY_PLLON,
+ CONF2_PHYPWRDN | CONF2_OTGPWRDN);
+ }
+}
+
+void am35x_musb_clear_irq(void)
+{
+ clrsetbits_le32(&am35x_scm_general_regs->lvl_intr_clr,
+ 0, USBOTGSS_INT_CLR);
+ readl(&am35x_scm_general_regs->lvl_intr_clr);
+}
+
diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h
index 819fd2f026..d6c038e3ae 100644
--- a/arch/arm/include/asm/arch-am33xx/cpu.h
+++ b/arch/arm/include/asm/arch-am33xx/cpu.h
@@ -82,7 +82,8 @@ struct cm_wkuppll {
unsigned int clkseldpllcore; /* offset 0x68 */
unsigned int resv9[1];
unsigned int idlestdpllper; /* offset 0x70 */
- unsigned int resv10[3];
+ unsigned int resv10[2];
+ unsigned int clkdcoldodpllper; /* offset 0x7c */
unsigned int divm4dpllcore; /* offset 0x80 */
unsigned int divm5dpllcore; /* offset 0x84 */
unsigned int clkmoddpllmpu; /* offset 0x88 */
@@ -275,12 +276,16 @@ struct ctrl_stat {
/* Control Device Register */
struct ctrl_dev {
unsigned int deviceid; /* offset 0x00 */
- unsigned int resv1[11];
+ unsigned int resv1[7];
+ unsigned int usb_ctrl0; /* offset 0x20 */
+ unsigned int resv2;
+ unsigned int usb_ctrl1; /* offset 0x28 */
+ unsigned int resv3;
unsigned int macid0l; /* offset 0x30 */
unsigned int macid0h; /* offset 0x34 */
unsigned int macid1l; /* offset 0x38 */
unsigned int macid1h; /* offset 0x3c */
- unsigned int resv2[4];
+ unsigned int resv4[4];
unsigned int miisel; /* offset 0x50 */
};
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware.h b/arch/arm/include/asm/arch-am33xx/hardware.h
index 5bd4bc8722..24ab365ea3 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware.h
@@ -87,4 +87,8 @@
/* RTC base address */
#define AM335X_RTC_BASE 0x44E3E000
+/* OTG */
+#define AM335X_USB0_OTG_BASE 0x47401000
+#define AM335X_USB1_OTG_BASE 0x47401800
+
#endif /* __AM33XX_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-exynos/dwmmc.h b/arch/arm/include/asm/arch-exynos/dwmmc.h
new file mode 100644
index 0000000000..8acdf9b725
--- /dev/null
+++ b/arch/arm/include/asm/arch-exynos/dwmmc.h
@@ -0,0 +1,36 @@
+/*
+ * (C) Copyright 2012 SAMSUNG Electronics
+ * Jaehoon Chung <jh80.chung@samsung.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
+ *
+ */
+
+#define DWMCI_CLKSEL 0x09C
+#define DWMCI_SHIFT_0 0x0
+#define DWMCI_SHIFT_1 0x1
+#define DWMCI_SHIFT_2 0x2
+#define DWMCI_SHIFT_3 0x3
+#define DWMCI_SET_SAMPLE_CLK(x) (x)
+#define DWMCI_SET_DRV_CLK(x) ((x) << 16)
+#define DWMCI_SET_DIV_RATIO(x) ((x) << 24)
+
+int exynos_dwmci_init(u32 regbase, int bus_width, int index);
+
+static inline unsigned int exynos_dwmmc_init(int index, int bus_width)
+{
+ unsigned int base = samsung_get_base_mmc() + (0x10000 * index);
+ return exynos_dwmci_init(base, bus_width, index);
+}
diff --git a/arch/arm/include/asm/arch-omap3/am35x_def.h b/arch/arm/include/asm/arch-omap3/am35x_def.h
index bbaf1bc97b..67698bc7ef 100644
--- a/arch/arm/include/asm/arch-omap3/am35x_def.h
+++ b/arch/arm/include/asm/arch-omap3/am35x_def.h
@@ -32,9 +32,34 @@
#ifndef __KERNEL_STRICT_NAMES
#ifndef __ASSEMBLY__
+/* LVL_INTR_CLEAR bits */
+#define USBOTGSS_INT_CLR (1 << 4)
+
/* IP_SW_RESET bits */
+#define USBOTGSS_SW_RST (1 << 0) /* reset USBOTG */
#define CPGMACSS_SW_RST (1 << 1) /* reset CPGMAC */
+/* DEVCONF2 bits */
+#define CONF2_PHY_GPIOMODE (1 << 23)
+#define CONF2_OTGMODE (3 << 14)
+#define CONF2_NO_OVERRIDE (0 << 14)
+#define CONF2_FORCE_HOST (1 << 14)
+#define CONF2_FORCE_DEVICE (2 << 14)
+#define CONF2_FORCE_HOST_VBUS_LOW (3 << 14)
+#define CONF2_SESENDEN (1 << 13)
+#define CONF2_VBDTCTEN (1 << 12)
+#define CONF2_REFFREQ_24MHZ (2 << 8)
+#define CONF2_REFFREQ_26MHZ (7 << 8)
+#define CONF2_REFFREQ_13MHZ (6 << 8)
+#define CONF2_REFFREQ (0xf << 8)
+#define CONF2_PHYCLKGD (1 << 7)
+#define CONF2_VBUSSENSE (1 << 6)
+#define CONF2_PHY_PLLON (1 << 5)
+#define CONF2_RESET (1 << 4)
+#define CONF2_PHYPWRDN (1 << 3)
+#define CONF2_OTGPWRDN (1 << 2)
+#define CONF2_DATPOL (1 << 1)
+
/* General register mappings of system control module */
#define AM35X_SCM_GEN_BASE 0x48002270
struct am35x_scm_general {
@@ -49,6 +74,8 @@ struct am35x_scm_general {
};
#define am35x_scm_general_regs ((struct am35x_scm_general *)AM35X_SCM_GEN_BASE)
+#define AM35XX_IPSS_USBOTGSS_BASE 0x5C040000
+
#endif /*__ASSEMBLY__ */
#endif /* __KERNEL_STRICT_NAMES */
diff --git a/arch/arm/include/asm/arch-omap3/musb.h b/arch/arm/include/asm/arch-omap3/musb.h
new file mode 100644
index 0000000000..423ac500f4
--- /dev/null
+++ b/arch/arm/include/asm/arch-omap3/musb.h
@@ -0,0 +1,28 @@
+/*
+ * (C) Copyright 2012
+ * Ilya Yanok, <ilya.yanok@gmail.com>
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_OMAP3_MUSB_H
+#define __ASM_ARCH_OMAP3_MUSB_H
+extern void am35x_musb_reset(void);
+extern void am35x_musb_phy_power(u8 on);
+extern void am35x_musb_clear_irq(void);
+#endif
diff --git a/arch/arm/include/asm/imx-common/mx5_video.h b/arch/arm/include/asm/imx-common/mx5_video.h
new file mode 100644
index 0000000000..e54c25a560
--- /dev/null
+++ b/arch/arm/include/asm/imx-common/mx5_video.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2012
+ * Anatolij Gustschin, DENX Software Engineering, <agust@denx.de>
+ *
+ * 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.
+ */
+#ifndef __MX5_VIDEO_H
+#define __MX5_VIDEO_H
+
+#ifdef CONFIG_VIDEO
+void lcd_enable(void);
+void setup_iomux_lcd(void);
+#else
+static inline void lcd_enable(void) { }
+static inline void setup_iomux_lcd(void) { }
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/omap_musb.h b/arch/arm/include/asm/omap_musb.h
new file mode 100644
index 0000000000..b04d8650ef
--- /dev/null
+++ b/arch/arm/include/asm/omap_musb.h
@@ -0,0 +1,32 @@
+/*
+ * Board data structure for musb gadget on OMAPs
+ *
+ * Copyright (C) 2012, Ilya Yanok <ilya.yanok@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.
+ */
+
+#ifndef __ASM_ARM_OMAP_MUSB_H
+#define __ASM_ARM_OMAP_MUSB_H
+
+extern struct musb_platform_ops musb_dsps_ops;
+extern const struct musb_platform_ops am35x_ops;
+extern const struct musb_platform_ops omap2430_ops;
+
+struct omap_musb_board_data {
+ u8 interface_type;
+ void (*set_phy_power)(u8 on);
+ void (*clear_irq)(void);
+ void (*reset)(void);
+};
+
+enum musb_interface {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI};
+#endif /* __ASM_ARM_OMAP_MUSB_H */
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 92cad9a6eb..22a4d9cc0e 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -224,6 +224,13 @@ int __arch_cpu_init(void)
int arch_cpu_init(void)
__attribute__((weak, alias("__arch_cpu_init")));
+int __power_init_board(void)
+{
+ return 0;
+}
+int power_init_board(void)
+ __attribute__((weak, alias("__power_init_board")));
+
init_fnc_t *init_sequence[] = {
arch_cpu_init, /* basic arch cpu dependent setup */
@@ -525,6 +532,7 @@ void board_init_r(gd_t *id, ulong dest_addr)
#ifdef CONFIG_ARCH_EARLY_INIT_R
arch_early_init_r();
#endif
+ power_init_board();
#if !defined(CONFIG_SYS_NO_FLASH)
puts("Flash: ");
diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c b/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
index c747767e1e..b9b0998d48 100644
--- a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
+++ b/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
@@ -615,7 +615,7 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
| usb_pipeendpoint (pipe) << 7
| (usb_pipeisoc (pipe)? 0x8000: 0)
| (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
- | usb_pipeslow (pipe) << 13
+ | (usb_dev->speed == USB_SPEED_LOW) << 13
| usb_maxpacket (usb_dev, pipe) << 16);
return ed_ret;
diff --git a/arch/mips/cpu/mips32/time.c b/arch/mips/cpu/mips32/time.c
index 350896a2a5..09fc842b50 100644
--- a/arch/mips/cpu/mips32/time.c
+++ b/arch/mips/cpu/mips32/time.c
@@ -36,7 +36,6 @@ static unsigned long timestamp;
int timer_init(void)
{
/* Set up the timer for the first expiration. */
- timestamp = 0;
write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY);
return 0;
diff --git a/arch/mips/cpu/mips64/time.c b/arch/mips/cpu/mips64/time.c
index 51542808dd..720f7b7f8c 100644
--- a/arch/mips/cpu/mips64/time.c
+++ b/arch/mips/cpu/mips64/time.c
@@ -37,7 +37,6 @@ static unsigned long timestamp;
int timer_init(void)
{
/* Set up the timer for the first expiration. */
- timestamp = 0;
write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY);
return 0;
diff --git a/arch/powerpc/config.mk b/arch/powerpc/config.mk
index a30715459d..b7062818bb 100644
--- a/arch/powerpc/config.mk
+++ b/arch/powerpc/config.mk
@@ -42,3 +42,8 @@ endif
ifeq ($(CROSS_COMPILE),powerpc-openbsd-)
PLATFORM_CPPFLAGS+= -D__PPC__
endif
+
+# Only test once
+ifneq ($(CONFIG_SPL_BUILD),y)
+ALL-y += checkgcc4
+endif
diff --git a/arch/powerpc/cpu/mpc5xxx/Makefile b/arch/powerpc/cpu/mpc5xxx/Makefile
index 1a088b77bc..8de2c13598 100644
--- a/arch/powerpc/cpu/mpc5xxx/Makefile
+++ b/arch/powerpc/cpu/mpc5xxx/Makefile
@@ -41,6 +41,10 @@ COBJS-y += speed.o
COBJS-$(CONFIG_CMD_USB) += usb_ohci.o
COBJS-$(CONFIG_CMD_USB) += usb.o
+ifdef CONFIG_SPL_BUILD
+COBJS-y += spl_boot.o
+endif
+
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
START := $(addprefix $(obj),$(SSTART) $(CSTART))
diff --git a/arch/powerpc/cpu/mpc5xxx/spl_boot.c b/arch/powerpc/cpu/mpc5xxx/spl_boot.c
new file mode 100644
index 0000000000..9f14127dca
--- /dev/null
+++ b/arch/powerpc/cpu/mpc5xxx/spl_boot.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2012 Stefan Roese <sr@denx.de>
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <spl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Needed to align size SPL image to a 4-byte length
+ */
+u32 end_align __attribute__ ((section(".end_align")));
+
+/*
+ * Return selected boot device. On MPC5200 its only NOR flash right now.
+ */
+u32 spl_boot_device(void)
+{
+ return BOOT_DEVICE_NOR;
+}
+
+/*
+ * SPL version of board_init_f()
+ */
+void board_init_f(ulong bootflag)
+{
+ end_align = (u32)__spl_flash_end;
+
+ /*
+ * First we need to initialize the SDRAM, so that the real
+ * U-Boot or the OS (Linux) can be loaded
+ */
+ initdram(0);
+
+ /* Clear bss */
+ memset(__bss_start, '\0', __bss_end__ - __bss_start);
+
+ /*
+ * Init global_data pointer. Has to be done before calling
+ * get_clocks(), as it stores some clock values into gd needed
+ * later on in the serial driver.
+ */
+ /* Pointer is writable since we allocated a register for it */
+ gd = (gd_t *)(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET);
+ /* Clear initial global data */
+ memset((void *)gd, 0, sizeof(gd_t));
+
+ /*
+ * get_clocks() needs to be called so that the serial driver
+ * works correctly
+ */
+ get_clocks();
+
+ /*
+ * Do rudimental console / serial setup
+ */
+ preloader_console_init();
+
+ /*
+ * Call board_init_r() (SPL framework version) to load and boot
+ * real U-Boot or OS
+ */
+ board_init_r(NULL, 0);
+ /* Does not return!!! */
+}
diff --git a/arch/powerpc/cpu/mpc5xxx/start.S b/arch/powerpc/cpu/mpc5xxx/start.S
index 51cc4e2a10..ad5bc0a179 100644
--- a/arch/powerpc/cpu/mpc5xxx/start.S
+++ b/arch/powerpc/cpu/mpc5xxx/start.S
@@ -50,6 +50,7 @@
#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
#endif
+#ifndef CONFIG_SPL_BUILD
/*
* Set up GOT: Global Offset Table
*
@@ -68,6 +69,7 @@
GOT_ENTRY(__bss_end__)
GOT_ENTRY(__bss_start)
END_GOT
+#endif
/*
* Version string
@@ -84,6 +86,18 @@ version_string:
. = EXC_OFF_SYS_RESET
.globl _start
_start:
+
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+ /*
+ * This is the entry of the real U-Boot from a board port
+ * that supports SPL booting on the MPC5200. We only need
+ * to call board_init_f() here. Everything else has already
+ * been done in the SPL u-boot version.
+ */
+ GET_GOT /* initialize GOT access */
+ bl board_init_f /* run 1st part of board init code (in Flash)*/
+ /* NOTREACHED - board_init_f() does not return */
+#else
mfmsr r5 /* save msr contents */
/* Move CSBoot and adjust instruction pointer */
@@ -152,7 +166,9 @@ lowboot_reentry:
/* Be careful to keep code relocatable ! */
/*--------------------------------------------------------------*/
+#ifndef CONFIG_SPL_BUILD
GET_GOT /* initialize GOT access */
+#endif
/* r3: IMMR */
bl cpu_init_f /* run low-level CPU init code (in Flash)*/
@@ -160,7 +176,9 @@ lowboot_reentry:
bl board_init_f /* run 1st part of board init code (in Flash)*/
/* NOTREACHED - board_init_f() does not return */
+#endif
+#ifndef CONFIG_SPL_BUILD
/*
* Vector Table
*/
@@ -333,6 +351,7 @@ int_return:
lwz r1,GPR1(r1)
SYNC
rfi
+#endif /* CONFIG_SPL_BUILD */
/*
* This code initialises the MPC5xxx processor core
@@ -522,6 +541,7 @@ get_pvr:
mfspr r3, PVR
blr
+#ifndef CONFIG_SPL_BUILD
/*------------------------------------------------------------------------------*/
/*
@@ -759,3 +779,5 @@ trap_init:
mtlr r4 /* restore link register */
blr
+
+#endif /* CONFIG_SPL_BUILD */
diff --git a/arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds b/arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds
new file mode 100644
index 0000000000..cab9b9265c
--- /dev/null
+++ b/arch/powerpc/cpu/mpc5xxx/u-boot-spl.lds
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012 Stefan Roese <sr@denx.de>
+ *
+ * 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
+ */
+
+MEMORY
+{
+ sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR,
+ LENGTH = CONFIG_SPL_BSS_MAX_SIZE
+ flash : ORIGIN = CONFIG_SPL_TEXT_BASE,
+ LENGTH = CONFIG_SYS_SPL_MAX_LEN
+}
+
+OUTPUT_ARCH(powerpc)
+ENTRY(_start)
+SECTIONS
+{
+ .text :
+ {
+ __start = .;
+ arch/powerpc/cpu/mpc5xxx/start.o (.text)
+ *(.text*)
+ } > flash
+
+ . = ALIGN(4);
+ .data : { *(SORT_BY_ALIGNMENT(.data*)) } > flash
+
+ . = ALIGN(4);
+ .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } > flash
+
+ . = ALIGN(4);
+ .end_align : { *(.end_align*) } > flash
+ __spl_flash_end = .;
+
+ .bss :
+ {
+ . = ALIGN(4);
+ __bss_start = .;
+ *(.bss*)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ } > sdram
+}
diff --git a/arch/powerpc/cpu/mpc5xxx/usb_ohci.c b/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
index 607034b7c6..de07343d93 100644
--- a/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
+++ b/arch/powerpc/cpu/mpc5xxx/usb_ohci.c
@@ -618,7 +618,7 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
| usb_pipeendpoint (pipe) << 7
| (usb_pipeisoc (pipe)? 0x8000: 0)
| (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
- | usb_pipeslow (pipe) << 13
+ | (usb_dev->speed == USB_SPEED_LOW) << 13
| usb_maxpacket (usb_dev, pipe) << 16);
return ed_ret;
diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile
index 78c412d9f3..4c2b1040d4 100644
--- a/arch/powerpc/cpu/mpc85xx/Makefile
+++ b/arch/powerpc/cpu/mpc85xx/Makefile
@@ -28,7 +28,22 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).o
-START = start.o resetvec.o
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+START = start.o resetvec.o
+
+ifdef MINIMAL
+
+COBJS-y += cpu_init_early.o tlb.o spl_minimal.o
+
+else
+
SOBJS-$(CONFIG_MP) += release.o
SOBJS = $(SOBJS-y)
@@ -121,17 +136,20 @@ COBJS-$(CONFIG_PPC_P5040) += p5040_serdes.o
COBJS-$(CONFIG_PPC_T4240) += t4240_serdes.o
COBJS-$(CONFIG_PPC_B4860) += b4860_serdes.o
-COBJS = $(COBJS-y)
-COBJS += cpu.o
-COBJS += cpu_init.o
-COBJS += cpu_init_early.o
-COBJS += interrupts.o
-COBJS += speed.o
-COBJS += tlb.o
-COBJS += traps.o
+COBJS-y += cpu.o
+COBJS-y += cpu_init.o
+COBJS-y += cpu_init_early.o
+COBJS-y += interrupts.o
+COBJS-y += speed.o
+COBJS-y += tlb.o
+COBJS-y += traps.o
# Stub implementations of cache management functions for USB
-COBJS += cache.o
+COBJS-y += cache.o
+
+endif # not minimal
+
+COBJS = $(COBJS-y)
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
index 2be192d578..e5ecf5dae5 100644
--- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c
+++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
@@ -24,6 +24,109 @@
#include <command.h>
#include <linux/compiler.h>
#include <asm/processor.h>
+#include "fsl_corenet_serdes.h"
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_A004849
+/*
+ * This work-around is implemented in PBI, so just check to see if the
+ * work-around was actually applied. To do this, we check for specific data
+ * at specific addresses in DCSR.
+ *
+ * Array offsets[] contains a list of offsets within DCSR. According to the
+ * erratum document, the value at each offset should be 2.
+ */
+static void check_erratum_a4849(uint32_t svr)
+{
+ void __iomem *dcsr = (void *)CONFIG_SYS_DCSRBAR + 0xb0000;
+ unsigned int i;
+
+#if defined(CONFIG_PPC_P2041) || defined(CONFIG_PPC_P3041)
+ static const uint8_t offsets[] = {
+ 0x50, 0x54, 0x58, 0x90, 0x94, 0x98
+ };
+#endif
+#ifdef CONFIG_PPC_P4080
+ static const uint8_t offsets[] = {
+ 0x60, 0x64, 0x68, 0x6c, 0xa0, 0xa4, 0xa8, 0xac
+ };
+#endif
+ uint32_t x108; /* The value that should be at offset 0x108 */
+
+ for (i = 0; i < ARRAY_SIZE(offsets); i++) {
+ if (in_be32(dcsr + offsets[i]) != 2) {
+ printf("Work-around for Erratum A004849 is not enabled\n");
+ return;
+ }
+ }
+
+#if defined(CONFIG_PPC_P2041) || defined(CONFIG_PPC_P3041)
+ x108 = 0x12;
+#endif
+
+#ifdef CONFIG_PPC_P4080
+ /*
+ * For P4080, the erratum document says that the value at offset 0x108
+ * should be 0x12 on rev2, or 0x1c on rev3.
+ */
+ if (SVR_MAJ(svr) == 2)
+ x108 = 0x12;
+ if (SVR_MAJ(svr) == 3)
+ x108 = 0x1c;
+#endif
+
+ if (in_be32(dcsr + 0x108) != x108) {
+ printf("Work-around for Erratum A004849 is not enabled\n");
+ return;
+ }
+
+ /* Everything matches, so the erratum work-around was applied */
+
+ printf("Work-around for Erratum A004849 enabled\n");
+}
+#endif
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_A004580
+/*
+ * This work-around is implemented in PBI, so just check to see if the
+ * work-around was actually applied. To do this, we check for specific data
+ * at specific addresses in the SerDes register block.
+ *
+ * The work-around says that for each SerDes lane, write BnTTLCRy0 =
+ * 0x1B00_0001, Register 2 = 0x0088_0000, and Register 3 = 0x4000_0000.
+
+ */
+static void check_erratum_a4580(uint32_t svr)
+{
+ const serdes_corenet_t __iomem *srds_regs =
+ (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
+ unsigned int lane;
+
+ for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
+ if (serdes_lane_enabled(lane)) {
+ const struct serdes_lane __iomem *srds_lane =
+ &srds_regs->lane[serdes_get_lane_idx(lane)];
+
+ /*
+ * Verify that the values we were supposed to write in
+ * the PBI are actually there. Also, the lower 15
+ * bits of res4[3] should be the same as the upper 15
+ * bits of res4[1].
+ */
+ if ((in_be32(&srds_lane->ttlcr0) != 0x1b000001) ||
+ (in_be32(&srds_lane->res4[1]) != 0x880000) ||
+ (in_be32(&srds_lane->res4[3]) != 0x40000044)) {
+ printf("Work-around for Erratum A004580 is "
+ "not enabled\n");
+ return;
+ }
+ }
+ }
+
+ /* Everything matches, so the erratum work-around was applied */
+
+ printf("Work-around for Erratum A004580 enabled\n");
+}
+#endif
static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
@@ -137,6 +240,17 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#ifdef CONFIG_SYS_FSL_ERRATUM_A_004934
puts("Work-around for Erratum A004934 enabled\n");
#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A004849
+ /* This work-around is implemented in PBI, so just check for it */
+ check_erratum_a4849(svr);
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A004580
+ /* This work-around is implemented in PBI, so just check for it */
+ check_erratum_a4580(svr);
+#endif
+#ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003
+ puts("Work-around for Erratum PCIe-A003 enabled\n");
+#endif
return 0;
}
diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c
index db232e64f8..9b9832cfc3 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu.c
@@ -332,7 +332,8 @@ void mpc85xx_reginfo(void)
/* Common ddr init for non-corenet fsl 85xx platforms */
#ifndef CONFIG_FSL_CORENET
-#if defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SYS_INIT_L2_ADDR)
+#if (defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)) && \
+ !defined(CONFIG_SYS_INIT_L2_ADDR)
phys_size_t initdram(int board_type)
{
#if defined(CONFIG_SPD_EEPROM) || defined(CONFIG_DDR_SPD)
@@ -450,21 +451,21 @@ static void dump_spd_ddr_reg(void)
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
switch (i) {
case 0:
- ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+ ddr[i] = (void *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
break;
-#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
+#if defined(CONFIG_SYS_MPC8xxx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
- ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR;
+ ddr[i] = (void *)CONFIG_SYS_MPC8xxx_DDR2_ADDR;
break;
#endif
-#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
+#if defined(CONFIG_SYS_MPC8xxx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
- ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR;
+ ddr[i] = (void *)CONFIG_SYS_MPC8xxx_DDR3_ADDR;
break;
#endif
-#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
+#if defined(CONFIG_SYS_MPC8xxx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
- ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR;
+ ddr[i] = (void *)CONFIG_SYS_MPC8xxx_DDR4_ADDR;
break;
#endif
default:
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c
index f01804bbb9..d1155e8126 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c
@@ -350,6 +350,10 @@ int cpu_init_r(void)
#elif defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2)
struct ccsr_cluster_l2 * l2cache = (void __iomem *)CONFIG_SYS_FSL_CLUSTER_1_L2;
#endif
+#if defined(CONFIG_PPC_SPINTABLE_COMPATIBLE) && defined(CONFIG_MP)
+ extern int spin_table_compat;
+ const char *spin;
+#endif
#if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \
defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011)
@@ -395,6 +399,14 @@ int cpu_init_r(void)
}
#endif
+#if defined(CONFIG_PPC_SPINTABLE_COMPATIBLE) && defined(CONFIG_MP)
+ spin = getenv("spin_table_compat");
+ if (spin && (*spin == 'n'))
+ spin_table_compat = 0;
+ else
+ spin_table_compat = 1;
+#endif
+
puts ("L2: ");
#if defined(CONFIG_L2_CACHE)
@@ -470,7 +482,7 @@ int cpu_init_r(void)
&& l2srbar >= CONFIG_SYS_FLASH_BASE) {
l2srbar = CONFIG_SYS_INIT_L2_ADDR;
l2cache->l2srbar0 = l2srbar;
- printf("moving to 0x%08x", CONFIG_SYS_INIT_L2_ADDR);
+ printf(", moving to 0x%08x", CONFIG_SYS_INIT_L2_ADDR);
}
#endif /* CONFIG_SYS_INIT_L2_ADDR */
puts("\n");
diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen1.c b/arch/powerpc/cpu/mpc85xx/ddr-gen1.c
index 54437dd0cb..8a86819fb5 100644
--- a/arch/powerpc/cpu/mpc85xx/ddr-gen1.c
+++ b/arch/powerpc/cpu/mpc85xx/ddr-gen1.c
@@ -18,7 +18,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
unsigned int ctrl_num)
{
unsigned int i;
- volatile ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+ volatile ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
if (ctrl_num != 0) {
printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
@@ -73,7 +73,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
void
ddr_enable_ecc(unsigned int dram_size)
{
- volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
+ volatile ccsr_ddr_t *ddr= (void *)(CONFIG_SYS_MPC8xxx_DDR_ADDR);
dma_meminit(CONFIG_MEM_INIT_VALUE, dram_size);
diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen2.c b/arch/powerpc/cpu/mpc85xx/ddr-gen2.c
index 49000a19e8..a705862522 100644
--- a/arch/powerpc/cpu/mpc85xx/ddr-gen2.c
+++ b/arch/powerpc/cpu/mpc85xx/ddr-gen2.c
@@ -19,15 +19,12 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
unsigned int ctrl_num)
{
unsigned int i;
-#ifdef CONFIG_MPC83xx
- ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC83xx_DDR_ADDR;
-#else
- ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
-#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_DDR120
+ ccsr_ddr_t *ddr = (void *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
+
+#if defined(CONFIG_SYS_FSL_ERRATUM_NMG_DDR120) && defined(CONFIG_MPC85xx)
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
uint svr;
#endif
-#endif
if (ctrl_num) {
printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
index f118dd5daf..ef0dd1da64 100644
--- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
+++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c
@@ -32,21 +32,21 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
switch (ctrl_num) {
case 0:
- ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR;
+ ddr = (void *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
break;
-#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
+#if defined(CONFIG_SYS_MPC8xxx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
- ddr = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR;
+ ddr = (void *)CONFIG_SYS_MPC8xxx_DDR2_ADDR;
break;
#endif
-#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
+#if defined(CONFIG_SYS_MPC8xxx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
- ddr = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR;
+ ddr = (void *)CONFIG_SYS_MPC8xxx_DDR3_ADDR;
break;
#endif
-#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
+#if defined(CONFIG_SYS_MPC8xxx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
- ddr = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR;
+ ddr = (void *)CONFIG_SYS_MPC8xxx_DDR4_ADDR;
break;
#endif
default:
diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
index 7f466ac6a9..5495dc59ee 100644
--- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
@@ -714,9 +714,13 @@ void fsl_serdes_init(void)
#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9
/*
- * Set BnTTLCRy0[FLT_SEL] = 000011 and set BnTTLCRy0[17] = 1 for
- * each of the SerDes lanes selected as SGMII, XAUI, SRIO, or
- * AURORA before the device is initialized.
+ * Set BnTTLCRy0[FLT_SEL] = 011011 and set BnTTLCRy0[31] = 1
+ * for each of the SerDes lanes selected as SGMII, XAUI, SRIO,
+ * or AURORA before the device is initialized.
+ *
+ * Note that this part of the SERDES-9 work-around is
+ * redundant if the work-around for A-4580 has already been
+ * applied via PBI.
*/
switch (lane_prtcl) {
case SGMII_FM1_DTSEC1:
@@ -733,10 +737,12 @@ void fsl_serdes_init(void)
case SRIO1:
case SRIO2:
case AURORA:
- clrsetbits_be32(&srds_regs->lane[idx].ttlcr0,
- SRDS_TTLCR0_FLT_SEL_MASK,
- SRDS_TTLCR0_FLT_SEL_750PPM |
- SRDS_TTLCR0_PM_DIS);
+ out_be32(&srds_regs->lane[idx].ttlcr0,
+ SRDS_TTLCR0_FLT_SEL_KFR_26 |
+ SRDS_TTLCR0_FLT_SEL_KPH_28 |
+ SRDS_TTLCR0_FLT_SEL_750PPM |
+ SRDS_TTLCR0_FREQOVD_EN);
+ break;
default:
break;
}
diff --git a/arch/powerpc/cpu/mpc85xx/release.S b/arch/powerpc/cpu/mpc85xx/release.S
index 4ba44a9028..5c4b1e3b75 100644
--- a/arch/powerpc/cpu/mpc85xx/release.S
+++ b/arch/powerpc/cpu/mpc85xx/release.S
@@ -351,7 +351,13 @@ __secondary_reset_vector:
.align L1_CACHE_SHIFT
.global __second_half_boot_page
__second_half_boot_page:
-#define EPAPR_MAGIC 0x45504150
+#ifdef CONFIG_PPC_SPINTABLE_COMPATIBLE
+ lis r3,(spin_table_compat - __second_half_boot_page)@h
+ ori r3,r3,(spin_table_compat - __second_half_boot_page)@l
+ add r3,r3,r11 /* r11 has the address of __second_half_boot_page */
+ lwz r14,0(r3)
+#endif
+
#define ENTRY_ADDR_UPPER 0
#define ENTRY_ADDR_LOWER 4
#define ENTRY_R3_UPPER 8
@@ -383,7 +389,24 @@ __second_half_boot_page:
stw r8,ENTRY_ADDR_LOWER(r10)
/* spin waiting for addr */
-3: lwz r4,ENTRY_ADDR_LOWER(r10)
+3:
+/*
+ * To comply with ePAPR 1.1, the spin table has been moved to cache-enabled
+ * memory. Old OS may not work with this change. A patch is waiting to be
+ * accepted for Linux kernel. Other OS needs similar fix to spin table.
+ * For OSes with old spin table code, we can enable this temporary fix by
+ * setting environmental variable "spin_table_compat". For new OSes, set
+ * "spin_table_compat=no". After Linux is fixed, we can remove this macro
+ * and related code. For now, it is enabled by default.
+ */
+#ifdef CONFIG_PPC_SPINTABLE_COMPATIBLE
+ cmpwi r14,0
+ beq 4f
+ dcbf 0, r10
+ sync
+4:
+#endif
+ lwz r4,ENTRY_ADDR_LOWER(r10)
andi. r11,r4,1
bne 3b
isync
@@ -460,5 +483,14 @@ __second_half_boot_page:
.globl __spin_table
__spin_table:
.space CONFIG_MAX_CPUS*ENTRY_SIZE
+
+#ifdef CONFIG_PPC_SPINTABLE_COMPATIBLE
+ .align L1_CACHE_SHIFT
+ .global spin_table_compat
+spin_table_compat:
+ .long 1
+
+#endif
+
__spin_table_end:
.space 4096 - (__spin_table_end - __spin_table)
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c b/arch/powerpc/cpu/mpc85xx/spl_minimal.c
index bf7a6f6be6..c6b9cd0acc 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init_nand.c
+++ b/arch/powerpc/cpu/mpc85xx/spl_minimal.c
@@ -21,12 +21,16 @@
*/
#include <common.h>
+#include <asm/processor.h>
+#include <asm/global_data.h>
#include <asm/fsl_ifc.h>
#include <asm/io.h>
+DECLARE_GLOBAL_DATA_PTR;
+
void cpu_init_f(void)
{
-#if defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SYS_INIT_L2_ADDR)
+#ifdef CONFIG_SYS_INIT_L2_ADDR
ccsr_l2cache_t *l2cache = (void *)CONFIG_SYS_MPC85xx_L2_ADDR;
out_be32(&l2cache->l2srbar0, CONFIG_SYS_INIT_L2_ADDR);
@@ -40,3 +44,16 @@ void cpu_init_f(void)
(MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2SRAM_ENTIRE));
#endif
}
+
+#ifndef CONFIG_SYS_FSL_TBCLK_DIV
+#define CONFIG_SYS_FSL_TBCLK_DIV 8
+#endif
+
+void udelay(unsigned long usec)
+{
+ u32 ticks_per_usec = gd->bus_clk / (CONFIG_SYS_FSL_TBCLK_DIV * 1000000);
+ u32 ticks = ticks_per_usec * usec;
+ u32 s = mfspr(SPRN_TBRL);
+
+ while ((mfspr(SPRN_TBRL) - s) < ticks);
+}
diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S
index ac17f9d3ca..bb0dc1a653 100644
--- a/arch/powerpc/cpu/mpc85xx/start.S
+++ b/arch/powerpc/cpu/mpc85xx/start.S
@@ -44,6 +44,15 @@
#undef MSR_KERNEL
#define MSR_KERNEL ( MSR_ME ) /* Machine Check */
+#if defined(CONFIG_NAND_SPL) || \
+ (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_INIT_MINIMAL))
+#define MINIMAL_SPL
+#endif
+
+#if !defined(CONFIG_SPL) && !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SECURE_BOOT)
+#define NOR_BOOT
+#endif
+
/*
* Set up GOT: Global Offset Table
*
@@ -53,7 +62,7 @@
GOT_ENTRY(_GOT2_TABLE_)
GOT_ENTRY(_FIXUP_TABLE_)
-#ifndef CONFIG_NAND_SPL
+#ifndef MINIMAL_SPL
GOT_ENTRY(_start)
GOT_ENTRY(_start_of_vectors)
GOT_ENTRY(_end_of_vectors)
@@ -282,51 +291,8 @@ l2_disabled:
isync
.endm
-#if defined(CONFIG_SYS_PPC_E500_DEBUG_TLB) && !defined(CONFIG_NAND_SPL)
-/*
- * TLB entry for debuggging in AS1
- * Create temporary TLB entry in AS0 to handle debug exception
- * As on debug exception MSR is cleared i.e. Address space is changed
- * to 0. A TLB entry (in AS0) is required to handle debug exception generated
- * in AS1.
- */
-
-#if !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SECURE_BOOT)
-/*
- * TLB entry is created for IVPR + IVOR15 to map on valid OP code address
- * bacause flash's virtual address maps to 0xff800000 - 0xffffffff.
- * and this window is outside of 4K boot window.
- */
- create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
- 0, BOOKE_PAGESZ_4M, \
- CONFIG_SYS_MONITOR_BASE & 0xffc00000, MAS2_I|MAS2_G, \
- 0xffc00000, MAS3_SX|MAS3_SW|MAS3_SR, \
- 0, r6
-
-#elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT)
- create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
- 0, BOOKE_PAGESZ_1M, \
- CONFIG_SYS_MONITOR_BASE, MAS2_I|MAS2_G, \
- CONFIG_SYS_PBI_FLASH_WINDOW, MAS3_SX|MAS3_SW|MAS3_SR, \
- 0, r6
-#else
-/*
- * TLB entry is created for IVPR + IVOR15 to map on valid OP code address
- * because "nexti" will resize TLB to 4K
- */
- create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
- 0, BOOKE_PAGESZ_256K, \
- CONFIG_SYS_MONITOR_BASE, MAS2_I, \
- CONFIG_SYS_MONITOR_BASE, MAS3_SX|MAS3_SW|MAS3_SR, \
- 0, r6
-#endif
-#endif
-
-/*
- * Ne need to setup interrupt vector for NAND SPL
- * because NAND SPL never compiles it.
- */
-#if !defined(CONFIG_NAND_SPL)
+/* Interrupt vectors do not fit in minimal SPL. */
+#if !defined(MINIMAL_SPL)
/* Setup interrupt vectors */
lis r1,CONFIG_SYS_MONITOR_BASE@h
mtspr IVPR,r1
@@ -534,10 +500,6 @@ nexti: mflr r1 /* R1 = our PC */
li r3, 0
mtspr MAS1, r3
1: cmpw r3, r14
-#if defined(CONFIG_SYS_PPC_E500_DEBUG_TLB) && !defined(CONFIG_NAND_SPL)
- cmpwi cr1, r3, CONFIG_SYS_PPC_E500_DEBUG_TLB
- cror cr0*4+eq, cr0*4+eq, cr1*4+eq
-#endif
rlwinm r5, r3, 16, MAS0_ESEL_MSK
addi r3, r3, 1
beq 2f /* skip the entry we're executing from */
@@ -553,6 +515,46 @@ nexti: mflr r1 /* R1 = our PC */
2: cmpw r3, r4
blt 1b
+#if defined(CONFIG_SYS_PPC_E500_DEBUG_TLB) && !defined(MINIMAL_SPL)
+/*
+ * TLB entry for debuggging in AS1
+ * Create temporary TLB entry in AS0 to handle debug exception
+ * As on debug exception MSR is cleared i.e. Address space is changed
+ * to 0. A TLB entry (in AS0) is required to handle debug exception generated
+ * in AS1.
+ */
+
+#ifdef NOR_BOOT
+/*
+ * TLB entry is created for IVPR + IVOR15 to map on valid OP code address
+ * bacause flash's virtual address maps to 0xff800000 - 0xffffffff.
+ * and this window is outside of 4K boot window.
+ */
+ create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
+ 0, BOOKE_PAGESZ_4M, \
+ CONFIG_SYS_MONITOR_BASE & 0xffc00000, MAS2_I|MAS2_G, \
+ 0xffc00000, MAS3_SX|MAS3_SW|MAS3_SR, \
+ 0, r6
+
+#elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT)
+ create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
+ 0, BOOKE_PAGESZ_1M, \
+ CONFIG_SYS_MONITOR_BASE, MAS2_I|MAS2_G, \
+ CONFIG_SYS_PBI_FLASH_WINDOW, MAS3_SX|MAS3_SW|MAS3_SR, \
+ 0, r6
+#else
+/*
+ * TLB entry is created for IVPR + IVOR15 to map on valid OP code address
+ * because "nexti" will resize TLB to 4K
+ */
+ create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \
+ 0, BOOKE_PAGESZ_256K, \
+ CONFIG_SYS_MONITOR_BASE & 0xfffc0000, MAS2_I, \
+ CONFIG_SYS_MONITOR_BASE & 0xfffc0000, MAS3_SX|MAS3_SW|MAS3_SR, \
+ 0, r6
+#endif
+#endif
+
/*
* Relocate CCSR, if necessary. We relocate CCSR if (obviously) the default
* location is not where we want it. This typically happens on a 36-bit
@@ -1036,7 +1038,7 @@ create_init_ram_area:
lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h
ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l
-#if !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SECURE_BOOT)
+#ifdef NOR_BOOT
/* create a temp mapping in AS=1 to the 4M boot window */
create_tlb1_entry 15, \
1, BOOKE_PAGESZ_4M, \
@@ -1050,8 +1052,8 @@ create_init_ram_area:
*/
create_tlb1_entry 15, \
1, BOOKE_PAGESZ_1M, \
- CONFIG_SYS_MONITOR_BASE, MAS2_I|MAS2_G, \
- CONFIG_SYS_PBI_FLASH_WINDOW, MAS3_SX|MAS3_SW|MAS3_SR, \
+ CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS2_I|MAS2_G, \
+ CONFIG_SYS_PBI_FLASH_WINDOW & 0xfff00000, MAS3_SX|MAS3_SW|MAS3_SR, \
0, r6
#else
/*
@@ -1060,8 +1062,8 @@ create_init_ram_area:
*/
create_tlb1_entry 15, \
1, BOOKE_PAGESZ_1M, \
- CONFIG_SYS_MONITOR_BASE, MAS2_I|MAS2_G, \
- CONFIG_SYS_MONITOR_BASE, MAS3_SX|MAS3_SW|MAS3_SR, \
+ CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS2_I|MAS2_G, \
+ CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS3_SX|MAS3_SW|MAS3_SR, \
0, r6
#endif
@@ -1111,7 +1113,8 @@ switch_as:
bdnz 1b
/* Jump out the last 4K page and continue to 'normal' start */
-#ifdef CONFIG_SYS_RAMBOOT
+#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)
+ /* We assume that we're already running at the address we're linked at */
b _start_cont
#else
/* Calculate absolute address in FLASH and jump there */
@@ -1157,7 +1160,7 @@ _start_cont:
/* NOTREACHED - board_init_f() does not return */
-#ifndef CONFIG_NAND_SPL
+#ifndef MINIMAL_SPL
. = EXC_OFF_SYS_RESET
.globl _start_of_vectors
_start_of_vectors:
@@ -1601,7 +1604,7 @@ in32:
in32r:
lwbrx r3,r0,r3
blr
-#endif /* !CONFIG_NAND_SPL */
+#endif /* !MINIMAL_SPL */
/*------------------------------------------------------------------------------*/
@@ -1798,7 +1801,7 @@ clear_bss:
mr r4,r10 /* Destination Address */
bl board_init_r
-#ifndef CONFIG_NAND_SPL
+#ifndef MINIMAL_SPL
/*
* Copy exception vector code to low memory
*
@@ -1971,4 +1974,4 @@ setup_ivors:
#include "fixed_ivor.S"
blr
-#endif /* !CONFIG_NAND_SPL */
+#endif /* !MINIMAL_SPL */
diff --git a/arch/powerpc/cpu/mpc85xx/tlb.c b/arch/powerpc/cpu/mpc85xx/tlb.c
index a548dec9a7..f44fadcffd 100644
--- a/arch/powerpc/cpu/mpc85xx/tlb.c
+++ b/arch/powerpc/cpu/mpc85xx/tlb.c
@@ -55,7 +55,7 @@ void init_tlbs(void)
return ;
}
-#ifndef CONFIG_NAND_SPL
+#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)
void read_tlbcam_entry(int idx, u32 *valid, u32 *tsize, unsigned long *epn,
phys_addr_t *rpn)
{
@@ -332,4 +332,4 @@ void clear_ddr_tlbs(unsigned int memsize_in_meg)
}
-#endif /* !CONFIG_NAND_SPL */
+#endif /* not SPL */
diff --git a/arch/powerpc/cpu/mpc85xx/u-boot-spl.lds b/arch/powerpc/cpu/mpc85xx/u-boot-spl.lds
new file mode 100644
index 0000000000..1c408e29f5
--- /dev/null
+++ b/arch/powerpc/cpu/mpc85xx/u-boot-spl.lds
@@ -0,0 +1,87 @@
+/*
+ * (C) Copyright 2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de
+ *
+ * Copyright 2009 Freescale Semiconductor, Inc.
+ *
+ * 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
+ */
+
+#include "config.h" /* CONFIG_BOARDDIR */
+
+OUTPUT_ARCH(powerpc)
+SECTIONS
+{
+ . = CONFIG_SPL_TEXT_BASE;
+ .text : {
+ *(.text*)
+ }
+ _etext = .;
+
+ .reloc : {
+ _GOT2_TABLE_ = .;
+ KEEP(*(.got2))
+ KEEP(*(.got))
+ PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
+ _FIXUP_TABLE_ = .;
+ KEEP(*(.fixup))
+ }
+ __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
+ __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
+
+ . = ALIGN(8);
+ .data : {
+ *(.rodata*)
+ *(.data*)
+ *(.sdata*)
+ }
+ _edata = .;
+
+ . = ALIGN(8);
+ __init_begin = .;
+ __init_end = .;
+/* FIXME for non-NAND SPL */
+#if defined(CONFIG_FSL_IFC) /* Restrict bootpg at 4K boundry for IFC */
+ .bootpg ADDR(.text) + 0x1000 :
+ {
+ start.o (.bootpg)
+ }
+#define RESET_VECTOR_OFFSET 0x1ffc /* IFC has 8K sram */
+#elif defined(CONFIG_FSL_ELBC)
+#define RESET_VECTOR_OFFSET 0xffc /* LBC has 4k sram */
+#else
+#error unknown NAND controller
+#endif
+ .resetvec ADDR(.text) + RESET_VECTOR_OFFSET : {
+ KEEP(*(.resetvec))
+ } = 0xffff
+
+ /*
+ * Make sure that the bss segment isn't linked at 0x0, otherwise its
+ * address won't be updated during relocation fixups.
+ */
+ . |= 0x10;
+
+ __bss_start = .;
+ .bss : {
+ *(.sbss*)
+ *(.bss*)
+ }
+ __bss_end__ = .;
+}
diff --git a/arch/powerpc/cpu/mpc86xx/ddr-8641.c b/arch/powerpc/cpu/mpc86xx/ddr-8641.c
index b8f2c9387f..92ba26dc8e 100644
--- a/arch/powerpc/cpu/mpc86xx/ddr-8641.c
+++ b/arch/powerpc/cpu/mpc86xx/ddr-8641.c
@@ -22,10 +22,10 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
switch (ctrl_num) {
case 0:
- ddr = (void *)CONFIG_SYS_MPC86xx_DDR_ADDR;
+ ddr = (void *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
break;
case 1:
- ddr = (void *)CONFIG_SYS_MPC86xx_DDR2_ADDR;
+ ddr = (void *)CONFIG_SYS_MPC8xxx_DDR2_ADDR;
break;
default:
printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
diff --git a/arch/powerpc/cpu/mpc8xxx/Makefile b/arch/powerpc/cpu/mpc8xxx/Makefile
index 4ae26e4210..3dc8e055b6 100644
--- a/arch/powerpc/cpu/mpc8xxx/Makefile
+++ b/arch/powerpc/cpu/mpc8xxx/Makefile
@@ -10,6 +10,20 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib8xxx.o
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+ifdef MINIMAL
+
+COBJS-$(CONFIG_FSL_LAW) += law.o
+
+else
+
ifneq ($(CPU),mpc83xx)
COBJS-y += cpu.o
endif
@@ -18,6 +32,9 @@ COBJS-$(CONFIG_OF_LIBFDT) += fdt.o
COBJS-$(CONFIG_FSL_IFC) += fsl_ifc.o
COBJS-$(CONFIG_FSL_LBC) += fsl_lbc.o
COBJS-$(CONFIG_SYS_SRIO) += srio.o
+COBJS-$(CONFIG_FSL_LAW) += law.o
+
+endif
SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
index 088cc0e855..8016bcdc22 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
@@ -18,15 +18,7 @@
#include "ddr.h"
-#ifdef CONFIG_MPC83xx
- #define _DDR_ADDR CONFIG_SYS_MPC83xx_DDR_ADDR
-#elif defined(CONFIG_MPC85xx)
- #define _DDR_ADDR CONFIG_SYS_MPC85xx_DDR_ADDR
-#elif defined(CONFIG_MPC86xx)
- #define _DDR_ADDR CONFIG_SYS_MPC86xx_DDR_ADDR
-#else
- #error "Undefined _DDR_ADDR"
-#endif
+#define _DDR_ADDR CONFIG_SYS_MPC8xxx_DDR_ADDR
static u32 fsl_ddr_get_version(void)
{
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/util.c b/arch/powerpc/cpu/mpc8xxx/ddr/util.c
index 940ffff773..acfe1f095f 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/util.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/util.c
@@ -133,14 +133,8 @@ u32 fsl_ddr_get_intl3r(void)
void board_add_ram_info(int use_default)
{
-#if defined(CONFIG_MPC83xx)
- immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
- ccsr_ddr_t *ddr = (void *)&immap->ddr;
-#elif defined(CONFIG_MPC85xx)
- ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
-#elif defined(CONFIG_MPC86xx)
- ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC86xx_DDR_ADDR);
-#endif
+ ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC8xxx_DDR_ADDR);
+
#if defined(CONFIG_E6500) && (CONFIG_NUM_DDR_CONTROLLERS == 3)
u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004);
#endif
@@ -152,13 +146,13 @@ void board_add_ram_info(int use_default)
#if CONFIG_NUM_DDR_CONTROLLERS >= 2
if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
- ddr = (void __iomem *)CONFIG_SYS_MPC85xx_DDR2_ADDR;
+ ddr = (void __iomem *)CONFIG_SYS_MPC8xxx_DDR2_ADDR;
sdram_cfg = in_be32(&ddr->sdram_cfg);
}
#endif
#if CONFIG_NUM_DDR_CONTROLLERS >= 3
if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
- ddr = (void __iomem *)CONFIG_SYS_MPC85xx_DDR3_ADDR;
+ ddr = (void __iomem *)CONFIG_SYS_MPC8xxx_DDR3_ADDR;
sdram_cfg = in_be32(&ddr->sdram_cfg);
}
#endif
diff --git a/arch/powerpc/cpu/mpc8xxx/fdt.c b/arch/powerpc/cpu/mpc8xxx/fdt.c
index 68db8e2448..1986fea030 100644
--- a/arch/powerpc/cpu/mpc8xxx/fdt.c
+++ b/arch/powerpc/cpu/mpc8xxx/fdt.c
@@ -217,7 +217,7 @@ void fdt_fixup_dr_usb(void *blob, bd_t *bd)
#if CONFIG_SYS_FSL_SEC_COMPAT == 2 /* SEC 2.x/3.x */
void fdt_fixup_crypto_node(void *blob, int sec_rev)
{
- const struct sec_rev_prop {
+ static const struct sec_rev_prop {
u32 sec_rev;
u32 num_channels;
u32 channel_fifo_len;
@@ -232,8 +232,8 @@ void fdt_fixup_crypto_node(void *blob, int sec_rev)
{ 0x0301, 4, 24, 0xbfe, 0x03ab0ebf }, /* SEC 3.1 */
{ 0x0303, 4, 24, 0x97c, 0x03a30abf }, /* SEC 3.3 */
};
- char compat_strlist[ARRAY_SIZE(sec_rev_prop_list) *
- sizeof("fsl,secX.Y")];
+ static char compat_strlist[ARRAY_SIZE(sec_rev_prop_list) *
+ sizeof("fsl,secX.Y")];
int crypto_node, sec_idx, err;
char *p;
u32 val;
diff --git a/arch/powerpc/cpu/mpc8xxx/law.c b/arch/powerpc/cpu/mpc8xxx/law.c
new file mode 100644
index 0000000000..ce1d71e307
--- /dev/null
+++ b/arch/powerpc/cpu/mpc8xxx/law.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <linux/compiler.h>
+#include <asm/fsl_law.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define FSL_HW_NUM_LAWS CONFIG_SYS_FSL_NUM_LAWS
+
+#ifdef CONFIG_FSL_CORENET
+#define LAW_BASE (CONFIG_SYS_FSL_CORENET_CCM_ADDR)
+#define LAWAR_ADDR(x) (&((ccsr_local_t *)LAW_BASE)->law[x].lawar)
+#define LAWBARH_ADDR(x) (&((ccsr_local_t *)LAW_BASE)->law[x].lawbarh)
+#define LAWBARL_ADDR(x) (&((ccsr_local_t *)LAW_BASE)->law[x].lawbarl)
+#define LAWBAR_SHIFT 0
+#else
+#define LAW_BASE (CONFIG_SYS_IMMR + 0xc08)
+#define LAWAR_ADDR(x) ((u32 *)LAW_BASE + 8 * x + 2)
+#define LAWBAR_ADDR(x) ((u32 *)LAW_BASE + 8 * x)
+#define LAWBAR_SHIFT 12
+#endif
+
+
+static inline phys_addr_t get_law_base_addr(int idx)
+{
+#ifdef CONFIG_FSL_CORENET
+ return (phys_addr_t)
+ ((u64)in_be32(LAWBARH_ADDR(idx)) << 32) |
+ in_be32(LAWBARL_ADDR(idx));
+#else
+ return (phys_addr_t)in_be32(LAWBAR_ADDR(idx)) << LAWBAR_SHIFT;
+#endif
+}
+
+static inline void set_law_base_addr(int idx, phys_addr_t addr)
+{
+#ifdef CONFIG_FSL_CORENET
+ out_be32(LAWBARL_ADDR(idx), addr & 0xffffffff);
+ out_be32(LAWBARH_ADDR(idx), (u64)addr >> 32);
+#else
+ out_be32(LAWBAR_ADDR(idx), addr >> LAWBAR_SHIFT);
+#endif
+}
+
+void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
+{
+ gd->used_laws |= (1 << idx);
+
+ out_be32(LAWAR_ADDR(idx), 0);
+ set_law_base_addr(idx, addr);
+ out_be32(LAWAR_ADDR(idx), LAW_EN | ((u32)id << 20) | (u32)sz);
+
+ /* Read back so that we sync the writes */
+ in_be32(LAWAR_ADDR(idx));
+}
+
+void disable_law(u8 idx)
+{
+ gd->used_laws &= ~(1 << idx);
+
+ out_be32(LAWAR_ADDR(idx), 0);
+ set_law_base_addr(idx, 0);
+
+ /* Read back so that we sync the writes */
+ in_be32(LAWAR_ADDR(idx));
+
+ return;
+}
+
+#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)
+static int get_law_entry(u8 i, struct law_entry *e)
+{
+ u32 lawar;
+
+ lawar = in_be32(LAWAR_ADDR(i));
+
+ if (!(lawar & LAW_EN))
+ return 0;
+
+ e->addr = get_law_base_addr(i);
+ e->size = lawar & 0x3f;
+ e->trgt_id = (lawar >> 20) & 0xff;
+
+ return 1;
+}
+#endif
+
+int set_next_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
+{
+ u32 idx = ffz(gd->used_laws);
+
+ if (idx >= FSL_HW_NUM_LAWS)
+ return -1;
+
+ set_law(idx, addr, sz, id);
+
+ return idx;
+}
+
+#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)
+int set_last_law(phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
+{
+ u32 idx;
+
+ /* we have no LAWs free */
+ if (gd->used_laws == -1)
+ return -1;
+
+ /* grab the last free law */
+ idx = __ilog2(~(gd->used_laws));
+
+ if (idx >= FSL_HW_NUM_LAWS)
+ return -1;
+
+ set_law(idx, addr, sz, id);
+
+ return idx;
+}
+
+struct law_entry find_law(phys_addr_t addr)
+{
+ struct law_entry entry;
+ int i;
+
+ entry.index = -1;
+ entry.addr = 0;
+ entry.size = 0;
+ entry.trgt_id = 0;
+
+ for (i = 0; i < FSL_HW_NUM_LAWS; i++) {
+ u64 upper;
+
+ if (!get_law_entry(i, &entry))
+ continue;
+
+ upper = entry.addr + (2ull << entry.size);
+ if ((addr >= entry.addr) && (addr < upper)) {
+ entry.index = i;
+ break;
+ }
+ }
+
+ return entry;
+}
+
+void print_laws(void)
+{
+ int i;
+ u32 lawar;
+
+ printf("\nLocal Access Window Configuration\n");
+ for (i = 0; i < FSL_HW_NUM_LAWS; i++) {
+ lawar = in_be32(LAWAR_ADDR(i));
+#ifdef CONFIG_FSL_CORENET
+ printf("LAWBARH%02d: 0x%08x LAWBARL%02d: 0x%08x",
+ i, in_be32(LAWBARH_ADDR(i)),
+ i, in_be32(LAWBARL_ADDR(i)));
+#else
+ printf("LAWBAR%02d: 0x%08x", i, in_be32(LAWBAR_ADDR(i)));
+#endif
+ printf(" LAWAR%02d: 0x%08x\n", i, lawar);
+ printf("\t(EN: %d TGT: 0x%02x SIZE: ",
+ (lawar & LAW_EN) ? 1 : 0, (lawar >> 20) & 0xff);
+ print_size(lawar_size(lawar), ")\n");
+ }
+
+ return;
+}
+
+/* use up to 2 LAWs for DDR, used the last available LAWs */
+int set_ddr_laws(u64 start, u64 sz, enum law_trgt_if id)
+{
+ u64 start_align, law_sz;
+ int law_sz_enc;
+
+ if (start == 0)
+ start_align = 1ull << (LAW_SIZE_32G + 1);
+ else
+ start_align = 1ull << (ffs64(start) - 1);
+ law_sz = min(start_align, sz);
+ law_sz_enc = __ilog2_u64(law_sz) - 1;
+
+ if (set_last_law(start, law_sz_enc, id) < 0)
+ return -1;
+
+ /* recalculate size based on what was actually covered by the law */
+ law_sz = 1ull << __ilog2_u64(law_sz);
+
+ /* do we still have anything to map */
+ sz = sz - law_sz;
+ if (sz) {
+ start += law_sz;
+
+ start_align = 1ull << (ffs64(start) - 1);
+ law_sz = min(start_align, sz);
+ law_sz_enc = __ilog2_u64(law_sz) - 1;
+
+ if (set_last_law(start, law_sz_enc, id) < 0)
+ return -1;
+ } else {
+ return 0;
+ }
+
+ /* do we still have anything to map */
+ sz = sz - law_sz;
+ if (sz)
+ return 1;
+
+ return 0;
+}
+#endif /* not SPL */
+
+void init_laws(void)
+{
+ int i;
+
+#if FSL_HW_NUM_LAWS < 32
+ gd->used_laws = ~((1 << FSL_HW_NUM_LAWS) - 1);
+#elif FSL_HW_NUM_LAWS == 32
+ gd->used_laws = 0;
+#else
+#error FSL_HW_NUM_LAWS can not be greater than 32 w/o code changes
+#endif
+
+ /*
+ * Any LAWs that were set up before we booted assume they are meant to
+ * be around and mark them used.
+ */
+ for (i = 0; i < FSL_HW_NUM_LAWS; i++) {
+ u32 lawar = in_be32(LAWAR_ADDR(i));
+
+ if (lawar & LAW_EN)
+ gd->used_laws |= (1 << i);
+ }
+
+#if (defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)) || \
+ (defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD))
+ /*
+ * in SPL boot we've already parsed the law_table and setup those LAWs
+ * so don't do it again.
+ */
+ return;
+#endif
+
+ for (i = 0; i < num_law_entries; i++) {
+ if (law_table[i].index == -1)
+ set_next_law(law_table[i].addr, law_table[i].size,
+ law_table[i].trgt_id);
+ else
+ set_law(law_table[i].index, law_table[i].addr,
+ law_table[i].size, law_table[i].trgt_id);
+ }
+
+#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE
+ /* check RCW to get which port is used for boot */
+ ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
+ u32 bootloc = in_be32(&gur->rcwsr[6]);
+ /*
+ * in SRIO or PCIE boot we need to set specail LAWs for
+ * SRIO or PCIE interfaces.
+ */
+ switch ((bootloc & FSL_CORENET_RCWSR6_BOOT_LOC) >> 23) {
+ case 0x0: /* boot from PCIE1 */
+ set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
+ LAW_SIZE_1M,
+ LAW_TRGT_IF_PCIE_1);
+ set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
+ LAW_SIZE_1M,
+ LAW_TRGT_IF_PCIE_1);
+ break;
+ case 0x1: /* boot from PCIE2 */
+ set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
+ LAW_SIZE_1M,
+ LAW_TRGT_IF_PCIE_2);
+ set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
+ LAW_SIZE_1M,
+ LAW_TRGT_IF_PCIE_2);
+ break;
+ case 0x2: /* boot from PCIE3 */
+ set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
+ LAW_SIZE_1M,
+ LAW_TRGT_IF_PCIE_3);
+ set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
+ LAW_SIZE_1M,
+ LAW_TRGT_IF_PCIE_3);
+ break;
+ case 0x8: /* boot from SRIO1 */
+ set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
+ LAW_SIZE_1M,
+ LAW_TRGT_IF_RIO_1);
+ set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
+ LAW_SIZE_1M,
+ LAW_TRGT_IF_RIO_1);
+ break;
+ case 0x9: /* boot from SRIO2 */
+ set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS,
+ LAW_SIZE_1M,
+ LAW_TRGT_IF_RIO_2);
+ set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS,
+ LAW_SIZE_1M,
+ LAW_TRGT_IF_RIO_2);
+ break;
+ default:
+ break;
+ }
+#endif
+
+ return ;
+}
diff --git a/arch/powerpc/cpu/ppc4xx/usb_ohci.c b/arch/powerpc/cpu/ppc4xx/usb_ohci.c
index 4ce2726297..f820c37a8f 100644
--- a/arch/powerpc/cpu/ppc4xx/usb_ohci.c
+++ b/arch/powerpc/cpu/ppc4xx/usb_ohci.c
@@ -621,7 +621,7 @@ static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe)
| usb_pipeendpoint (pipe) << 7
| (usb_pipeisoc (pipe)? 0x8000: 0)
| (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
- | usb_pipeslow (pipe) << 13
+ | (usb_dev->speed == USB_SPEED_LOW) << 13
| usb_maxpacket (usb_dev, pipe) << 16);
return ed_ret;
diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h
index 03baaee1b7..0b9638bcee 100644
--- a/arch/powerpc/include/asm/config_mpc85xx.h
+++ b/arch/powerpc/include/asm/config_mpc85xx.h
@@ -27,6 +27,12 @@
#error "Do not define CONFIG_SYS_CCSRBAR_DEFAULT in the board header file."
#endif
+/*
+ * This macro should be removed when we no longer care about backwards
+ * compatibility with older operating systems.
+ */
+#define CONFIG_PPC_SPINTABLE_COMPATIBLE
+
#define FSL_DDR_VER_4_7 47
/* Number of TLB CAM entries we have on FSL Book-E chips */
@@ -131,7 +137,6 @@
#define CONFIG_SYS_PPC_E500_DEBUG_TLB 3
#define CONFIG_TSECV2
#define CONFIG_SYS_FSL_SEC_COMPAT 4
-#define CONFIG_FSL_SATA_V2
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
#define CONFIG_NUM_DDR_CONTROLLERS 1
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000
@@ -175,7 +180,6 @@
#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2
#define CONFIG_TSECV2
#define CONFIG_SYS_FSL_SEC_COMPAT 2
-#define CONFIG_FSL_SATA_V2
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000
#define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
@@ -188,7 +192,6 @@
#define CONFIG_SYS_PPC_E500_DEBUG_TLB 3
#define CONFIG_TSECV2
#define CONFIG_SYS_FSL_SEC_COMPAT 4
-#define CONFIG_FSL_SATA_V2
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
#define CONFIG_NUM_DDR_CONTROLLERS 1
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000
@@ -242,7 +245,6 @@
#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2
#define CONFIG_TSECV2
#define CONFIG_SYS_FSL_SEC_COMPAT 2
-#define CONFIG_FSL_SATA_V2
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000
#define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
@@ -318,7 +320,6 @@
#define CONFIG_SYS_FSL_NUM_CC_PLLS 2
#define CONFIG_SYS_FSL_NUM_LAWS 32
#define CONFIG_SYS_FSL_SEC_COMPAT 4
-#define CONFIG_FSL_SATA_V2
#define CONFIG_SYS_NUM_FMAN 1
#define CONFIG_SYS_NUM_FM1_DTSEC 5
#define CONFIG_SYS_NUM_FM1_10GEC 1
@@ -343,6 +344,7 @@
#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 0x11
#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000
#define CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
+#define CONFIG_SYS_FSL_ERRATUM_A004849
#elif defined(CONFIG_PPC_P3041)
#define CONFIG_SYS_FSL_QORIQ_CHASSIS1
@@ -350,7 +352,6 @@
#define CONFIG_SYS_FSL_NUM_CC_PLLS 2
#define CONFIG_SYS_FSL_NUM_LAWS 32
#define CONFIG_SYS_FSL_SEC_COMPAT 4
-#define CONFIG_FSL_SATA_V2
#define CONFIG_SYS_NUM_FMAN 1
#define CONFIG_SYS_NUM_FM1_DTSEC 5
#define CONFIG_SYS_NUM_FM1_10GEC 1
@@ -375,6 +376,7 @@
#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 0x11
#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000
#define CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
+#define CONFIG_SYS_FSL_ERRATUM_A004849
#elif defined(CONFIG_PPC_P4080) /* also supports P4040 */
#define CONFIG_SYS_FSL_QORIQ_CHASSIS1
@@ -417,6 +419,9 @@
#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x20
#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xff000000
#define CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
+#define CONFIG_SYS_FSL_ERRATUM_A004849
+#define CONFIG_SYS_FSL_ERRATUM_A004580
+#define CONFIG_SYS_P4080_ERRATUM_PCIE_A003
#elif defined(CONFIG_PPC_P5020) /* also supports P5010 */
#define CONFIG_SYS_PPC64 /* 64-bit core */
@@ -425,7 +430,6 @@
#define CONFIG_SYS_FSL_NUM_CC_PLLS 2
#define CONFIG_SYS_FSL_NUM_LAWS 32
#define CONFIG_SYS_FSL_SEC_COMPAT 4
-#define CONFIG_FSL_SATA_V2
#define CONFIG_SYS_NUM_FMAN 1
#define CONFIG_SYS_NUM_FM1_DTSEC 5
#define CONFIG_SYS_NUM_FM1_10GEC 1
@@ -449,6 +453,7 @@
#define CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
#elif defined(CONFIG_PPC_P5040)
+#define CONFIG_SYS_PPC64
#define CONFIG_SYS_FSL_QORIQ_CHASSIS1
#define CONFIG_MAX_CPUS 4
#define CONFIG_SYS_FSL_NUM_CC_PLLS 3
@@ -472,7 +477,6 @@
#define CONFIG_SYS_FSL_ERRATUM_DDR_A003
#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
#define CONFIG_SYS_FSL_ERRATUM_A004699
-#define CONFIG_SYS_FSL_ELBC_MULTIBIT_ECC
#define CONFIG_SYS_FSL_ERRATUM_A004510
#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x10
#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000
diff --git a/arch/powerpc/include/asm/immap_83xx.h b/arch/powerpc/include/asm/immap_83xx.h
index 679832cd6c..8ac13fc05c 100644
--- a/arch/powerpc/include/asm/immap_83xx.h
+++ b/arch/powerpc/include/asm/immap_83xx.h
@@ -1035,9 +1035,9 @@ typedef struct immap {
} immap_t;
#endif
-#define CONFIG_SYS_MPC83xx_DDR_OFFSET (0x2000)
-#define CONFIG_SYS_MPC83xx_DDR_ADDR \
- (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DDR_OFFSET)
+#define CONFIG_SYS_MPC8xxx_DDR_OFFSET (0x2000)
+#define CONFIG_SYS_MPC8xxx_DDR_ADDR \
+ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC8xxx_DDR_OFFSET)
#define CONFIG_SYS_MPC83xx_DMA_OFFSET (0x8000)
#define CONFIG_SYS_MPC83xx_DMA_ADDR \
(CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DMA_OFFSET)
diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h
index 969f726c36..296b549779 100644
--- a/arch/powerpc/include/asm/immap_85xx.h
+++ b/arch/powerpc/include/asm/immap_85xx.h
@@ -2619,7 +2619,7 @@ typedef struct serdes_corenet {
#define SRDS_PCCR2_RST_XGMII1 0x00800000
#define SRDS_PCCR2_RST_XGMII2 0x00400000
u32 res5[197];
- struct {
+ struct serdes_lane {
u32 gcr0; /* General Control Register 0 */
#define SRDS_GCR0_RRST 0x00400000
#define SRDS_GCR0_1STLANE 0x00010000
@@ -2637,8 +2637,11 @@ typedef struct serdes_corenet {
u32 res3;
u32 ttlcr0; /* Transition Tracking Loop Ctrl 0 */
#define SRDS_TTLCR0_FLT_SEL_MASK 0x3f000000
+#define SRDS_TTLCR0_FLT_SEL_KFR_26 0x10000000
+#define SRDS_TTLCR0_FLT_SEL_KPH_28 0x08000000
#define SRDS_TTLCR0_FLT_SEL_750PPM 0x03000000
#define SRDS_TTLCR0_PM_DIS 0x00004000
+#define SRDS_TTLCR0_FREQOVD_EN 0x00000001
u32 res4[7];
} lane[24];
u32 res6[384];
@@ -2867,9 +2870,9 @@ struct ccsr_pman {
#define CONFIG_SYS_FSL_CORENET_PMAN2_OFFSET 0x5000
#define CONFIG_SYS_FSL_CORENET_PMAN3_OFFSET 0x6000
#endif
-#define CONFIG_SYS_MPC85xx_DDR_OFFSET 0x8000
-#define CONFIG_SYS_MPC85xx_DDR2_OFFSET 0x9000
-#define CONFIG_SYS_MPC85xx_DDR3_OFFSET 0xA000
+#define CONFIG_SYS_MPC8xxx_DDR_OFFSET 0x8000
+#define CONFIG_SYS_MPC8xxx_DDR2_OFFSET 0x9000
+#define CONFIG_SYS_MPC8xxx_DDR3_OFFSET 0xA000
#define CONFIG_SYS_FSL_CORENET_CLK_OFFSET 0xE1000
#define CONFIG_SYS_FSL_CORENET_RCPM_OFFSET 0xE2000
#define CONFIG_SYS_FSL_CORENET_SERDES_OFFSET 0xEA000
@@ -2929,9 +2932,9 @@ struct ccsr_pman {
#define CONFIG_SYS_FSL_CLUSTER_1_L2_OFFSET 0xC20000
#else
#define CONFIG_SYS_MPC85xx_ECM_OFFSET 0x0000
-#define CONFIG_SYS_MPC85xx_DDR_OFFSET 0x2000
+#define CONFIG_SYS_MPC8xxx_DDR_OFFSET 0x2000
#define CONFIG_SYS_MPC85xx_LBC_OFFSET 0x5000
-#define CONFIG_SYS_MPC85xx_DDR2_OFFSET 0x6000
+#define CONFIG_SYS_MPC8xxx_DDR2_OFFSET 0x6000
#define CONFIG_SYS_MPC85xx_ESPI_OFFSET 0x7000
#define CONFIG_SYS_MPC85xx_PCI1_OFFSET 0x8000
#define CONFIG_SYS_MPC85xx_PCIX_OFFSET 0x8000
@@ -2998,12 +3001,12 @@ struct ccsr_pman {
(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_CORENET_RCPM_OFFSET)
#define CONFIG_SYS_MPC85xx_ECM_ADDR \
(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_ECM_OFFSET)
-#define CONFIG_SYS_MPC85xx_DDR_ADDR \
- (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR_OFFSET)
-#define CONFIG_SYS_MPC85xx_DDR2_ADDR \
- (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR2_OFFSET)
-#define CONFIG_SYS_MPC85xx_DDR3_ADDR \
- (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR3_OFFSET)
+#define CONFIG_SYS_MPC8xxx_DDR_ADDR \
+ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC8xxx_DDR_OFFSET)
+#define CONFIG_SYS_MPC8xxx_DDR2_ADDR \
+ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC8xxx_DDR2_OFFSET)
+#define CONFIG_SYS_MPC8xxx_DDR3_ADDR \
+ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC8xxx_DDR3_OFFSET)
#define CONFIG_SYS_LBC_ADDR \
(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_LBC_OFFSET)
#define CONFIG_SYS_IFC_ADDR \
diff --git a/arch/powerpc/include/asm/immap_86xx.h b/arch/powerpc/include/asm/immap_86xx.h
index cc338e4739..2a704fe6b7 100644
--- a/arch/powerpc/include/asm/immap_86xx.h
+++ b/arch/powerpc/include/asm/immap_86xx.h
@@ -1252,10 +1252,10 @@ typedef struct immap {
extern immap_t *immr;
-#define CONFIG_SYS_MPC86xx_DDR_OFFSET 0x2000
-#define CONFIG_SYS_MPC86xx_DDR_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_DDR_OFFSET)
-#define CONFIG_SYS_MPC86xx_DDR2_OFFSET 0x6000
-#define CONFIG_SYS_MPC86xx_DDR2_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_DDR2_OFFSET)
+#define CONFIG_SYS_MPC8xxx_DDR_OFFSET 0x2000
+#define CONFIG_SYS_MPC8xxx_DDR_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC8xxx_DDR_OFFSET)
+#define CONFIG_SYS_MPC8xxx_DDR2_OFFSET 0x6000
+#define CONFIG_SYS_MPC8xxx_DDR2_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC8xxx_DDR2_OFFSET)
#define CONFIG_SYS_MPC86xx_DMA_OFFSET 0x21000
#define CONFIG_SYS_MPC86xx_DMA_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC86xx_DMA_OFFSET)
#define CONFIG_SYS_MPC86xx_PIC_OFFSET 0x40000
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 7aa3231ad4..19fe250305 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -1342,4 +1342,10 @@ void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
#endif
#endif /* CONFIG_MACH_SPECIFIC */
+#if defined(CONFIG_MPC85xx) || defined(CONFIG_440)
+ #define EPAPR_MAGIC (0x45504150)
+#else
+ #define EPAPR_MAGIC (0x65504150)
+#endif
+
#endif /* __ASM_PPC_PROCESSOR_H */
diff --git a/arch/powerpc/include/asm/spl.h b/arch/powerpc/include/asm/spl.h
new file mode 100644
index 0000000000..f43bc23c92
--- /dev/null
+++ b/arch/powerpc/include/asm/spl.h
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2012
+ * Texas Instruments, <www.ti.com>
+ *
+ * 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 _ASM_SPL_H_
+#define _ASM_SPL_H_
+
+#define BOOT_DEVICE_NOR 1
+
+/* Linker symbols */
+extern char __bss_start[], __bss_end__[];
+
+#endif
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 808021c42e..844fe8636d 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -38,13 +38,28 @@ endif
LIB = $(obj)lib$(ARCH).o
-SOBJS-y += ppccache.o
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+ifdef MINIMAL
+COBJS-y += cache.o
+else
+
SOBJS-y += ppcstring.o
+
+SOBJS-y += ppccache.o
SOBJS-y += ticks.o
SOBJS-y += reloc.o
COBJS-$(CONFIG_BAT_RW) += bat_rw.o
+ifndef CONFIG_SPL_BUILD
COBJS-y += board.o
+endif
COBJS-y += bootm.o
COBJS-y += cache.o
COBJS-y += extable.o
@@ -53,6 +68,11 @@ COBJS-$(CONFIG_CMD_KGDB) += kgdb.o
COBJS-${CONFIG_CMD_IDE} += ide.o
COBJS-y += time.o
+# Don't include the MPC5xxx special memcpy into the
+# SPL U-Boot image. memcpy is used in the SPL NOR
+# flash driver. And we need the real, fast memcpy
+# here. We have no problems with unaligned access.
+ifndef CONFIG_SPL_BUILD
# Workaround for local bus unaligned access problems
# on MPC512x and MPC5200
ifdef CONFIG_MPC512X
@@ -63,6 +83,13 @@ ifdef CONFIG_MPC5200
$(obj)ppcstring.o: AFLAGS += -Dmemcpy=__memcpy
COBJS-y += memcpy_mpc5200.o
endif
+endif
+
+endif # not minimal
+
+ifdef CONFIG_SPL_BUILD
+COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o
+endif
COBJS += $(sort $(COBJS-y))
@@ -75,12 +102,6 @@ TARGETS += $(LIB)
all: $(TARGETS)
$(LIB): $(obj).depend $(OBJS)
- @if ! $(CROSS_COMPILE)readelf -S $(OBJS) | grep -q '\.fixup.*PROGBITS';\
- then \
- echo "ERROR: Your compiler doesn't generate .fixup sections!";\
- echo " Upgrade to a recent toolchain."; \
- exit 1; \
- fi;
$(call cmd_link_o_target, $(OBJS))
$(LIBGCC): $(obj).depend $(LGOBJS)
diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c
index ac5bd6d4f1..7088293a36 100644
--- a/arch/powerpc/lib/bootm.c
+++ b/arch/powerpc/lib/bootm.c
@@ -87,12 +87,6 @@ static void boot_jump_linux(bootm_headers_t *images)
* r8: 0
* r9: 0
*/
-#if defined(CONFIG_MPC85xx) || defined(CONFIG_440)
- #define EPAPR_MAGIC (0x45504150)
-#else
- #define EPAPR_MAGIC (0x65504150)
-#endif
-
debug (" Booting using OF flat tree...\n");
WATCHDOG_RESET ();
(*kernel) ((bd_t *)of_flat_tree, 0, 0, EPAPR_MAGIC,
diff --git a/arch/powerpc/lib/spl.c b/arch/powerpc/lib/spl.c
new file mode 100644
index 0000000000..502c93bebe
--- /dev/null
+++ b/arch/powerpc/lib/spl.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2012 Stefan Roese <sr@denx.de>
+ *
+ * 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.
+ */
+#include <common.h>
+#include <config.h>
+#include <spl.h>
+#include <image.h>
+#include <linux/compiler.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * This function jumps to an image with argument. Normally an FDT or ATAGS
+ * image.
+ * arg: Pointer to paramter image in RAM
+ */
+#ifdef CONFIG_SPL_OS_BOOT
+void __noreturn jump_to_image_linux(void *arg)
+{
+ debug("Entering kernel arg pointer: 0x%p\n", arg);
+ typedef void (*image_entry_arg_t)(void *, ulong r4, ulong r5, ulong r6,
+ ulong r7, ulong r8, ulong r9)
+ __attribute__ ((noreturn));
+ image_entry_arg_t image_entry =
+ (image_entry_arg_t)spl_image.entry_point;
+
+ image_entry(arg, 0, 0, EPAPR_MAGIC, CONFIG_SYS_BOOTMAPSZ, 0, 0);
+}
+#endif /* CONFIG_SPL_OS_BOOT */
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index 56fd77acea..24b5ce8e30 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -274,8 +274,8 @@ void enable_hlt(void);
static inline void trigger_address_error(void)
{
+ set_bl_bit();
__asm__ __volatile__ (
- "ldc %0, sr\n\t"
"mov.l @%1, %0"
:
: "r" (0x10000000), "r" (0x80000001)
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index 7f1fc188cb..57324b6174 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -28,12 +28,13 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).o
-START = start.o start16.o resetvec.o
-COBJS = interrupts.o cpu.o
+START-y = start.o
+RESET_OBJS-$(CONFIG_X86_NO_RESET_VECTOR) += resetvec.o start16.o
+COBJS = interrupts.o cpu.o timer.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
-START := $(addprefix $(obj),$(START))
+START := $(addprefix $(obj),$(START-y) $(RESET_OBJS-))
all: $(obj).depend $(START) $(LIB)
diff --git a/arch/x86/cpu/coreboot/Makefile b/arch/x86/cpu/coreboot/Makefile
index 13f5f8a2f0..b1d3e959f8 100644
--- a/arch/x86/cpu/coreboot/Makefile
+++ b/arch/x86/cpu/coreboot/Makefile
@@ -33,12 +33,13 @@ 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) += sysinfo.o
-
-SOBJS-$(CONFIG_SYS_COREBOOT) += coreboot_car.o
+COBJS-$(CONFIG_SYS_COREBOOT) += timestamp.o
+COBJS-$(CONFIG_PCI) += pci.o
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
diff --git a/arch/x86/cpu/coreboot/coreboot_car.S b/arch/x86/cpu/coreboot/car.S
index 3cc25755fd..3cc25755fd 100644
--- a/arch/x86/cpu/coreboot/coreboot_car.S
+++ b/arch/x86/cpu/coreboot/car.S
diff --git a/arch/x86/cpu/coreboot/config.mk b/arch/x86/cpu/coreboot/config.mk
new file mode 100644
index 0000000000..4858fc3728
--- /dev/null
+++ b/arch/x86/cpu/coreboot/config.mk
@@ -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
diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c
new file mode 100644
index 0000000000..9c9431e0d9
--- /dev/null
+++ b/arch/x86/cpu/coreboot/coreboot.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2008
+ * Graeme Russ, graeme.russ@gmail.com.
+ *
+ * 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
+ */
+
+#include <common.h>
+#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;
+
+/*
+ * Miscellaneous platform dependent initializations
+ */
+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;
+}
+
+int board_early_init_f(void)
+{
+ return 0;
+}
+
+int board_early_init_r(void)
+{
+ /* CPU Speed to 100MHz */
+ gd->cpu_clk = 100000000;
+
+ /* Crystal is 33.000MHz */
+ gd->bus_clk = 33000000;
+
+ return 0;
+}
+
+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)
+{
+ return 0;
+}
+
+#ifndef CONFIG_SYS_NO_FLASH
+ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
+{
+ return 0;
+}
+#endif
+
+int board_eth_init(bd_t *bis)
+{
+ return pci_eth_init(bis);
+}
+
+#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;
+}
diff --git a/arch/x86/cpu/coreboot/pci.c b/arch/x86/cpu/coreboot/pci.c
new file mode 100644
index 0000000000..8f94167480
--- /dev/null
+++ b/arch/x86/cpu/coreboot/pci.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2008,2009
+ * Graeme Russ, <graeme.russ@gmail.com>
+ *
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <asm/pci.h>
+
+static struct pci_controller coreboot_hose;
+
+static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev,
+ struct pci_config_table *table)
+{
+ u8 secondary;
+ hose->read_byte(hose, dev, PCI_SECONDARY_BUS, &secondary);
+ hose->last_busno = max(hose->last_busno, secondary);
+ pci_hose_scan_bus(hose, secondary);
+}
+
+static struct pci_config_table pci_coreboot_config_table[] = {
+ /* vendor, device, class, bus, dev, func */
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, &config_pci_bridge },
+ {}
+};
+
+void pci_init_board(void)
+{
+ coreboot_hose.config_table = pci_coreboot_config_table;
+ coreboot_hose.first_busno = 0;
+ coreboot_hose.last_busno = 0;
+
+ pci_set_region(coreboot_hose.regions + 0, 0x0, 0x0, 0xffffffff,
+ PCI_REGION_MEM);
+ coreboot_hose.region_count = 1;
+
+ pci_setup_type1(&coreboot_hose);
+
+ pci_register_hose(&coreboot_hose);
+
+ pci_hose_scan(&coreboot_hose);
+}
diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c
index f8fdac6319..76274cb88e 100644
--- a/arch/x86/cpu/coreboot/sdram.c
+++ b/arch/x86/cpu/coreboot/sdram.c
@@ -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/sysinfo.c b/arch/x86/cpu/coreboot/sysinfo.c
deleted file mode 100644
index 9b3e660dde..0000000000
--- a/arch/x86/cpu/coreboot/sysinfo.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * This file is part of the libpayload project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- * Copyright (C) 2009 coresystems GmbH
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <asm/arch-coreboot/sysinfo.h>
-
-/*
- * This needs to be in the .data section so that it's copied over during
- * relocation. By default it's put in the .bss section which is simply filled
- * with zeroes when transitioning from "ROM", which is really RAM, to other
- * RAM.
- */
-struct sysinfo_t lib_sysinfo __attribute__((section(".data")));
diff --git a/arch/x86/cpu/coreboot/tables.c b/arch/x86/cpu/coreboot/tables.c
index 0e3451bb22..b116d59555 100644
--- a/arch/x86/cpu/coreboot/tables.c
+++ b/arch/x86/cpu/coreboot/tables.c
@@ -28,11 +28,20 @@
* SUCH DAMAGE.
*/
+#include <common.h>
#include <asm/arch-coreboot/ipchecksum.h>
#include <asm/arch-coreboot/sysinfo.h>
#include <asm/arch-coreboot/tables.h>
/*
+ * This needs to be in the .data section so that it's copied over during
+ * relocation. By default it's put in the .bss section which is simply filled
+ * with zeroes when transitioning from "ROM", which is really RAM, to other
+ * RAM.
+ */
+struct sysinfo_t lib_sysinfo __attribute__((section(".data")));
+
+/*
* Some of this is x86 specific, and the rest of it is generic. Right now,
* since we only support x86, we'll avoid trying to make lots of infrastructure
* we don't need. If in the future, we want to use coreboot on some other
@@ -72,22 +81,45 @@ static void cb_parse_memory(unsigned char *ptr, struct sysinfo_t *info)
static void cb_parse_serial(unsigned char *ptr, struct sysinfo_t *info)
{
struct cb_serial *ser = (struct cb_serial *)ptr;
- if (ser->type != CB_SERIAL_TYPE_IO_MAPPED)
- return;
- info->ser_ioport = ser->baseaddr;
+ info->serial = ser;
}
-static void cb_parse_optiontable(unsigned char *ptr, struct sysinfo_t *info)
+static void cb_parse_vbnv(unsigned char *ptr, struct sysinfo_t *info)
{
- info->option_table = (struct cb_cmos_option_table *)ptr;
+ struct cb_vbnv *vbnv = (struct cb_vbnv *)ptr;
+
+ info->vbnv_start = vbnv->vbnv_start;
+ info->vbnv_size = vbnv->vbnv_size;
}
-static void cb_parse_checksum(unsigned char *ptr, struct sysinfo_t *info)
+static void cb_parse_gpios(unsigned char *ptr, struct sysinfo_t *info)
{
- struct cb_cmos_checksum *cmos_cksum = (struct cb_cmos_checksum *)ptr;
- info->cmos_range_start = cmos_cksum->range_start;
- info->cmos_range_end = cmos_cksum->range_end;
- info->cmos_checksum_location = cmos_cksum->location;
+ int i;
+ struct cb_gpios *gpios = (struct cb_gpios *)ptr;
+
+ info->num_gpios = (gpios->count < SYSINFO_MAX_GPIOS) ?
+ (gpios->count) : SYSINFO_MAX_GPIOS;
+
+ for (i = 0; i < info->num_gpios; i++)
+ info->gpios[i] = gpios->gpios[i];
+}
+
+static void cb_parse_vdat(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_vdat *vdat = (struct cb_vdat *) ptr;
+
+ info->vdat_addr = vdat->vdat_addr;
+ info->vdat_size = vdat->vdat_size;
+}
+
+static void cb_parse_tstamp(unsigned char *ptr, struct sysinfo_t *info)
+{
+ info->tstamp_table = ((struct cb_cbmem_tab *)ptr)->cbmem_tab;
+}
+
+static void cb_parse_cbmem_cons(unsigned char *ptr, struct sysinfo_t *info)
+{
+ info->cbmem_cons = ((struct cb_cbmem_tab *)ptr)->cbmem_tab;
}
static void cb_parse_framebuffer(unsigned char *ptr, struct sysinfo_t *info)
@@ -95,6 +127,11 @@ static void cb_parse_framebuffer(unsigned char *ptr, struct sysinfo_t *info)
info->framebuffer = (struct cb_framebuffer *)ptr;
}
+static void cb_parse_string(unsigned char *ptr, char **info)
+{
+ *info = (char *)((struct cb_string *)ptr)->string;
+}
+
static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
{
struct cb_header *header;
@@ -125,6 +162,9 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
/* Now, walk the tables. */
ptr += header->header_bytes;
+ /* Inintialize some fields to sentinel values. */
+ info->vbnv_start = info->vbnv_size = (uint32_t)(-1);
+
for (i = 0; i < header->table_entries; i++) {
struct cb_record *rec = (struct cb_record *)ptr;
@@ -142,11 +182,35 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
case CB_TAG_SERIAL:
cb_parse_serial(ptr, info);
break;
- case CB_TAG_CMOS_OPTION_TABLE:
- cb_parse_optiontable(ptr, info);
+ case CB_TAG_VERSION:
+ cb_parse_string(ptr, &info->version);
+ break;
+ case CB_TAG_EXTRA_VERSION:
+ cb_parse_string(ptr, &info->extra_version);
+ break;
+ case CB_TAG_BUILD:
+ cb_parse_string(ptr, &info->build);
+ break;
+ case CB_TAG_COMPILE_TIME:
+ cb_parse_string(ptr, &info->compile_time);
+ break;
+ case CB_TAG_COMPILE_BY:
+ cb_parse_string(ptr, &info->compile_by);
+ break;
+ case CB_TAG_COMPILE_HOST:
+ cb_parse_string(ptr, &info->compile_host);
+ break;
+ case CB_TAG_COMPILE_DOMAIN:
+ cb_parse_string(ptr, &info->compile_domain);
+ break;
+ case CB_TAG_COMPILER:
+ cb_parse_string(ptr, &info->compiler);
break;
- case CB_TAG_OPTION_CHECKSUM:
- cb_parse_checksum(ptr, info);
+ case CB_TAG_LINKER:
+ cb_parse_string(ptr, &info->linker);
+ break;
+ case CB_TAG_ASSEMBLER:
+ cb_parse_string(ptr, &info->assembler);
break;
/*
* FIXME we should warn on serial if coreboot set up a
@@ -155,6 +219,21 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
case CB_TAG_FRAMEBUFFER:
cb_parse_framebuffer(ptr, info);
break;
+ case CB_TAG_GPIO:
+ cb_parse_gpios(ptr, info);
+ break;
+ case CB_TAG_VDAT:
+ cb_parse_vdat(ptr, info);
+ break;
+ case CB_TAG_TIMESTAMPS:
+ cb_parse_tstamp(ptr, info);
+ break;
+ case CB_TAG_CBMEM_CONSOLE:
+ cb_parse_cbmem_cons(ptr, info);
+ break;
+ case CB_TAG_VBNV:
+ cb_parse_vbnv(ptr, info);
+ break;
}
ptr += rec->size;
@@ -166,18 +245,12 @@ static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
/* == Architecture specific == */
/* This is the x86 specific stuff. */
-/* Assume no translation or that memory is identity mapped. */
-static void *phys_to_virt(unsigned long virt)
-{
- return (void *)(uintptr_t)virt;
-}
-
int get_coreboot_info(struct sysinfo_t *info)
{
- int ret = cb_parse_header(phys_to_virt(0x00000000), 0x1000, info);
+ int ret = cb_parse_header((void *)0x00000000, 0x1000, info);
if (ret != 1)
- ret = cb_parse_header(phys_to_virt(0x000f0000), 0x1000, info);
+ ret = cb_parse_header((void *)0x000f0000, 0x1000, info);
return (ret == 1) ? 0 : -1;
}
diff --git a/arch/x86/cpu/coreboot/timestamp.c b/arch/x86/cpu/coreboot/timestamp.c
new file mode 100644
index 0000000000..2ca7a57bce
--- /dev/null
+++ b/arch/x86/cpu/coreboot/timestamp.c
@@ -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());
+}
diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index e9bb0d770a..315e87afeb 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -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>
@@ -90,12 +91,6 @@ static void load_gdt(const u64 *boot_gdt, u16 num_entries)
asm volatile("lgdtl %0\n" : : "m" (gdt));
}
-void init_gd(gd_t *id, u64 *gdt_addr)
-{
- id->gd_addr = (ulong)id;
- setup_gdt(id, gdt_addr);
-}
-
void setup_gdt(gd_t *id, u64 *gdt_addr)
{
/* CS: code, read/execute, 4 GB, base 0 */
@@ -121,6 +116,11 @@ void setup_gdt(gd_t *id, u64 *gdt_addr)
load_fs(X86_GDT_ENTRY_32BIT_FS);
}
+int __weak x86_cleanup_before_linux(void)
+{
+ return 0;
+}
+
int x86_cpu_init_f(void)
{
const u32 em_rst = ~X86_CR0_EM;
@@ -148,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();
@@ -201,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)
+{
+}
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
index 43ec3f8b08..dd30a05a9d 100644
--- a/arch/x86/cpu/interrupts.c
+++ b/arch/x86/cpu/interrupts.c
@@ -28,10 +28,14 @@
*/
#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" \
@@ -41,72 +45,6 @@
"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
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
index ee0dabe4bc..e960e21f6e 100644
--- a/arch/x86/cpu/start.S
+++ b/arch/x86/cpu/start.S
@@ -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
@@ -83,13 +91,33 @@ car_init_ret:
* or fully initialised SDRAM - we really don't care which)
* starting at CONFIG_SYS_CAR_ADDR to be used as a temporary stack
*/
- movl $CONFIG_SYS_INIT_SP_ADDR, %esp
- /* Initialise the Global Data Pointer */
- movl $CONFIG_SYS_INIT_GD_ADDR, %eax
- movl %eax, %edx
- addl $GENERATED_GBL_DATA_SIZE, %edx
- call init_gd;
+ /* Stack grows down from top of CAR */
+ movl $(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE), %esp
+
+ /* Reserve space on stack for global data */
+ subl $GENERATED_GBL_DATA_SIZE, %esp
+
+ /* Align global data to 16-byte boundary */
+ andl $0xfffffff0, %esp
+
+ /* Setup first parameter to setup_gdt */
+ movl %esp, %eax
+
+ /* Reserve space for global descriptor table */
+ subl $X86_GDT_SIZE, %esp
+
+ /* Align temporary global descriptor table to 16-byte boundary */
+ andl $0xfffffff0, %esp
+
+ /* Set second parameter to setup_gdt */
+ movl %esp, %edx
+
+ /* gd->gd_addr = gd (Required to allow gd->xyz to work) */
+ movl %eax, (%eax)
+
+ /* Setup global descriptor table so gd->xyz works */
+ call setup_gdt
/* Set parameter to board_init_f() to boot flags */
xorl %eax, %eax
@@ -113,9 +141,42 @@ board_init_f_r_trampoline:
* %eax = Address of top of new stack
*/
- /* Setup stack in RAM */
+ /* Stack grows down from top of SDRAM */
movl %eax, %esp
+ /* Reserve space on stack for global data */
+ subl $GENERATED_GBL_DATA_SIZE, %esp
+
+ /* Align global data to 16-byte boundary */
+ andl $0xfffffff0, %esp
+
+ /* Setup first parameter to memcpy (and setup_gdt) */
+ movl %esp, %eax
+
+ /* Setup second parameter to memcpy */
+ fs movl 0, %edx
+
+ /* Set third parameter to memcpy */
+ movl $GENERATED_GBL_DATA_SIZE, %ecx
+
+ /* Copy global data from CAR to SDRAM stack */
+ call memcpy
+
+ /* Reserve space for global descriptor table */
+ subl $X86_GDT_SIZE, %esp
+
+ /* Align global descriptor table to 16-byte boundary */
+ andl $0xfffffff0, %esp
+
+ /* Set second parameter to setup_gdt */
+ movl %esp, %edx
+
+ /* gd->gd_addr = gd (Required to allow gd->xyz to work) */
+ movl %eax, (%eax)
+
+ /* Setup global descriptor table so gd->xyz works */
+ call setup_gdt
+
/* Re-enter U-Boot by calling board_init_f_r */
call board_init_f_r
diff --git a/arch/x86/cpu/start16.S b/arch/x86/cpu/start16.S
index cc393ff54f..603bf1d2d3 100644
--- a/arch/x86/cpu/start16.S
+++ b/arch/x86/cpu/start16.S
@@ -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/cpu/timer.c b/arch/x86/cpu/timer.c
new file mode 100644
index 0000000000..149109d4f4
--- /dev/null
+++ b/arch/x86/cpu/timer.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2011 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>
+
+unsigned long timer_get_us(void)
+{
+ printf("timer_get_us used but not implemented.\n");
+ return 0;
+}
diff --git a/arch/x86/cpu/u-boot.lds b/arch/x86/cpu/u-boot.lds
index a1ecefafc6..0c6f0e31d8 100644
--- a/arch/x86/cpu/u-boot.lds
+++ b/arch/x86/cpu/u-boot.lds
@@ -86,6 +86,8 @@ SECTIONS
__bios_start = LOADADDR(.bios);
__bios_size = SIZEOF(.bios);
+#ifndef CONFIG_X86_NO_RESET_VECTOR
+
/*
* The following expressions place the 16-bit Real-Mode code and
* Reset Vector at the end of the Flash ROM
@@ -95,4 +97,5 @@ SECTIONS
. = RESET_VEC_LOC;
.resetvec : AT (CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE + RESET_VEC_LOC)) { KEEP(*(.resetvec)); }
+#endif
}
diff --git a/arch/x86/dts/coreboot.dtsi b/arch/x86/dts/coreboot.dtsi
new file mode 100644
index 0000000000..4862a59704
--- /dev/null
+++ b/arch/x86/dts/coreboot.dtsi
@@ -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
index 0000000000..b41d241de2
--- /dev/null
+++ b/arch/x86/dts/skeleton.dtsi
@@ -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/sysinfo.h b/arch/x86/include/asm/arch-coreboot/sysinfo.h
index 5c44e1a47c..77ae304969 100644
--- a/arch/x86/include/asm/arch-coreboot/sysinfo.h
+++ b/arch/x86/include/asm/arch-coreboot/sysinfo.h
@@ -30,32 +30,52 @@
#ifndef _COREBOOT_SYSINFO_H
#define _COREBOOT_SYSINFO_H
+#include <common.h>
#include <compiler.h>
+#include <fdt.h>
+#include <asm/arch/tables.h>
/* Allow a maximum of 16 memory range definitions. */
#define SYSINFO_MAX_MEM_RANGES 16
+/* Allow a maximum of 8 GPIOs */
+#define SYSINFO_MAX_GPIOS 8
struct sysinfo_t {
- unsigned int cpu_khz;
- unsigned short ser_ioport;
- unsigned long ser_base; /* for mmapped serial */
-
int n_memranges;
-
struct memrange {
unsigned long long base;
unsigned long long size;
unsigned int type;
} memrange[SYSINFO_MAX_MEM_RANGES];
- struct cb_cmos_option_table *option_table;
u32 cmos_range_start;
u32 cmos_range_end;
u32 cmos_checksum_location;
+ u32 vbnv_start;
+ u32 vbnv_size;
+
+ char *version;
+ char *extra_version;
+ char *build;
+ char *compile_time;
+ char *compile_by;
+ char *compile_host;
+ char *compile_domain;
+ char *compiler;
+ char *linker;
+ char *assembler;
struct cb_framebuffer *framebuffer;
- unsigned long *mbtable; /** Pointer to the multiboot table */
+ int num_gpios;
+ struct cb_gpio gpios[SYSINFO_MAX_GPIOS];
+
+ void *vdat_addr;
+ u32 vdat_size;
+ void *tstamp_table;
+ void *cbmem_cons;
+
+ struct cb_serial *serial;
};
extern struct sysinfo_t lib_sysinfo;
diff --git a/arch/x86/include/asm/arch-coreboot/tables.h b/arch/x86/include/asm/arch-coreboot/tables.h
index c28697375f..ad34a8b0f1 100644
--- a/arch/x86/include/asm/arch-coreboot/tables.h
+++ b/arch/x86/include/asm/arch-coreboot/tables.h
@@ -164,6 +164,55 @@ struct cb_framebuffer {
u8 reserved_mask_size;
};
+#define CB_TAG_GPIO 0x0013
+#define GPIO_MAX_NAME_LENGTH 16
+struct cb_gpio {
+ u32 port;
+ u32 polarity;
+ u32 value;
+ u8 name[GPIO_MAX_NAME_LENGTH];
+};
+
+struct cb_gpios {
+ u32 tag;
+ u32 size;
+
+ u32 count;
+ struct cb_gpio gpios[0];
+};
+
+#define CB_TAG_FDT 0x0014
+struct cb_fdt {
+ uint32_t tag;
+ uint32_t size; /* size of the entire entry */
+ /* the actual FDT gets placed here */
+};
+
+#define CB_TAG_VDAT 0x0015
+struct cb_vdat {
+ uint32_t tag;
+ uint32_t size; /* size of the entire entry */
+ void *vdat_addr;
+ uint32_t vdat_size;
+};
+
+#define CB_TAG_TIMESTAMPS 0x0016
+#define CB_TAG_CBMEM_CONSOLE 0x0017
+#define CB_TAG_MRC_CACHE 0x0018
+struct cb_cbmem_tab {
+ uint32_t tag;
+ uint32_t size;
+ void *cbmem_tab;
+};
+
+#define CB_TAG_VBNV 0x0019
+struct cb_vbnv {
+ uint32_t tag;
+ uint32_t size;
+ uint32_t vbnv_start;
+ uint32_t vbnv_size;
+};
+
#define CB_TAG_CMOS_OPTION_TABLE 0x00c8
struct cb_cmos_option_table {
u32 tag;
@@ -238,4 +287,29 @@ struct sysinfo_t;
int get_coreboot_info(struct sysinfo_t *info);
+#define CBMEM_TOC_RESERVED 512
+#define MAX_CBMEM_ENTRIES 16
+#define CBMEM_MAGIC 0x434f5245
+
+struct cbmem_entry {
+ u32 magic;
+ u32 id;
+ u64 base;
+ u64 size;
+} __packed;
+
+#define CBMEM_ID_FREESPACE 0x46524545
+#define CBMEM_ID_GDT 0x4c474454
+#define CBMEM_ID_ACPI 0x41435049
+#define CBMEM_ID_CBTABLE 0x43425442
+#define CBMEM_ID_PIRQ 0x49525154
+#define CBMEM_ID_MPTABLE 0x534d5054
+#define CBMEM_ID_RESUME 0x5245534d
+#define CBMEM_ID_RESUME_SCRATCH 0x52455343
+#define CBMEM_ID_SMBIOS 0x534d4254
+#define CBMEM_ID_TIMESTAMP 0x54494d45
+#define CBMEM_ID_MRCDATA 0x4d524344
+#define CBMEM_ID_CONSOLE 0x434f4e53
+#define CBMEM_ID_NONE 0x00000000
+
#endif
diff --git a/arch/x86/include/asm/arch-coreboot/timestamp.h b/arch/x86/include/asm/arch-coreboot/timestamp.h
new file mode 100644
index 0000000000..d104912e06
--- /dev/null
+++ b/arch/x86/include/asm/arch-coreboot/timestamp.h
@@ -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
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
index c7a38f237a..5a7e4cba2b 100644
--- a/arch/x86/include/asm/bitops.h
+++ b/arch/x86/include/asm/bitops.h
@@ -351,6 +351,11 @@ static __inline__ int ffs(int x)
}
#define PLATFORM_FFS
+static inline int __ilog2(unsigned int x)
+{
+ return generic_fls(x) - 1;
+}
+
/**
* hweightN - returns the hamming weight of a N-bit word
* @x: the word to weigh
diff --git a/arch/x86/include/asm/cache.h b/arch/x86/include/asm/cache.h
index 87c9e0be42..d4678d4916 100644
--- a/arch/x86/include/asm/cache.h
+++ b/arch/x86/include/asm/cache.h
@@ -32,4 +32,20 @@
#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
index 0000000000..aa8be30bac
--- /dev/null
+++ b/arch/x86/include/asm/control_regs.h
@@ -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
diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h
index bce999f41c..dc6402b67d 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -33,9 +33,13 @@
#ifndef __ASSEMBLY__
-typedef struct global_data {
+#include <asm/u-boot.h>
+
+typedef struct global_data gd_t;
+
+struct global_data {
/* NOTE: gd_addr MUST be first member of struct global_data! */
- unsigned long gd_addr; /* Location of Global Data */
+ gd_t *gd_addr; /* Location of Global Data */
bd_t *bd;
unsigned long flags;
unsigned int baudrate;
@@ -52,12 +56,12 @@ typedef struct global_data {
unsigned long relocaddr; /* Start address of U-Boot in RAM */
unsigned long start_addr_sp; /* start_addr_stackpointer */
unsigned long gdt_addr; /* Location of GDT */
- unsigned long new_gd_addr; /* New location of Global Data */
phys_size_t ram_size; /* RAM size */
unsigned long reset_status; /* reset status register at boot */
+ const void *fdt_blob; /* Our device tree, NULL if none */
void **jt; /* jump table */
char env_buf[32]; /* buffer for getenv() before reloc. */
-} gd_t;
+};
static inline gd_t *get_fs_gd_ptr(void)
{
@@ -74,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/nios2/include/asm/status_led.h b/arch/x86/include/asm/gpio.h
index 20f8d90195..0a37a85ad1 100644
--- a/arch/nios2/include/asm/status_led.h
+++ b/arch/x86/include/asm/gpio.h
@@ -1,7 +1,5 @@
/*
- * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
- * Scott McNutt <smcnutt@psyent.com>
- *
+ * Copyright (c) 2012, Google Inc. All rights reserved.
* See file CREDITS for list of people who contributed to this
* project.
*
@@ -20,12 +18,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
-#ifndef __ASM_STATUS_LED_H__
-#define __ASM_STATUS_LED_H__
-typedef unsigned led_id_t;
-extern void __led_init (led_id_t mask, int state);
-extern void __led_set (led_id_t mask, int state);
-inline void __led_toggle (led_id_t mask);
+#ifndef _X86_GPIO_H_
+#define _X86_GPIO_H_
+
+#include <asm-generic/gpio.h>
-#endif /* __ASM_STATUS_LED_H__ */
+#endif /* _X86_GPIO_H_ */
diff --git a/arch/x86/include/asm/init_helpers.h b/arch/x86/include/asm/init_helpers.h
index 8afb443290..2f437e0343 100644
--- a/arch/x86/include/asm/init_helpers.h
+++ b/arch/x86/include/asm/init_helpers.h
@@ -29,7 +29,6 @@ int display_dram_config(void);
int init_baudrate_f(void);
int calculate_relocation_address(void);
-int copy_gd_to_ram_f_r(void);
int init_cache_f_r(void);
int set_reloc_flag_r(void);
@@ -38,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_ */
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 9b757d489e..86bac90e8e 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -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
@@ -36,6 +38,8 @@
#define IO_SPACE_LIMIT 0xffff
+#include <asm/types.h>
+
#ifdef __KERNEL__
@@ -135,7 +139,7 @@ out:
#ifdef SLOW_IO_BY_JUMPING
#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:"
#else
-#define __SLOW_DOWN_IO "\noutb %%al,$0x80"
+#define __SLOW_DOWN_IO "\noutb %%al,$0xed"
#endif
#ifdef REALLY_SLOW_IO
@@ -218,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;
}
/*
@@ -231,7 +235,15 @@ 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);
}
+/*
+ * TODO: The kernel offers some more advanced versions of barriers, it might
+ * have some advantages to use them instead of the simple one here.
+ */
+#define dmb() __asm__ __volatile__ ("" : : : "memory")
+#define __iormb() dmb()
+#define __iowmb() dmb()
+
#endif
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
new file mode 100644
index 0000000000..50175994cf
--- /dev/null
+++ b/arch/x86/include/asm/msr-index.h
@@ -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
index 0000000000..6030633d10
--- /dev/null
+++ b/arch/x86/include/asm/msr.h
@@ -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
index 0000000000..6842da500a
--- /dev/null
+++ b/arch/x86/include/asm/mtrr.h
@@ -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 */
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 37cc7e3a0f..6d68ab6c92 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -24,7 +24,7 @@
*/
#ifndef _PCI_I386_H_
-#define _PCI_I386_H_ 1
+#define _PCI_I386_H_
#define DEFINE_PCI_DEVICE_TABLE(_table) \
const struct pci_device_id _table[]
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 6eb518063b..17f27cbb68 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -41,6 +41,7 @@ enum {
#else
/* NOTE: If the above enum is modified, this define must be checked */
#define X86_GDT_ENTRY_32BIT_DS 3
+#define X86_GDT_NUM_ENTRIES 7
#endif
#define X86_GDT_SIZE (X86_GDT_NUM_ENTRIES * X86_GDT_ENTRY_SIZE)
diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h
index 9a40e383eb..e9fde88f7d 100644
--- a/arch/x86/include/asm/types.h
+++ b/arch/x86/include/asm/types.h
@@ -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__ */
diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h
index 878a1ee77b..99062e5955 100644
--- a/arch/x86/include/asm/u-boot-x86.h
+++ b/arch/x86/include/asm/u-boot-x86.h
@@ -40,6 +40,7 @@ int cpu_init_f(void);
void init_gd(gd_t *id, u64 *gdt_addr);
void setup_gdt(gd_t *id, u64 *gdt_addr);
int init_cache(void);
+int cleanup_before_linux(void);
/* cpu/.../timer.c */
void timer_isr(void *);
@@ -62,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_ */
diff --git a/arch/x86/include/asm/u-boot.h b/arch/x86/include/asm/u-boot.h
index da667c50a4..2f45c7b3d7 100644
--- a/arch/x86/include/asm/u-boot.h
+++ b/arch/x86/include/asm/u-boot.h
@@ -36,6 +36,9 @@
#ifndef _U_BOOT_H_
#define _U_BOOT_H_ 1
+#include <config.h>
+#include <compiler.h>
+
typedef struct bd_info {
unsigned long bi_memstart; /* start of DRAM memory */
phys_size_t bi_memsize; /* size of DRAM memory in bytes */
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 51836dacca..0a52cc896c 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -25,11 +25,16 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(ARCH).o
+ifeq ($(CONFIG_X86_NO_REAL_MODE),)
SOBJS-$(CONFIG_SYS_PC_BIOS) += bios.o
SOBJS-$(CONFIG_SYS_PCI_BIOS) += bios_pci.o
-SOBJS-$(CONFIG_SYS_X86_REALMODE) += realmode_switch.o
+COBJS-y += realmode.o
+SOBJS-y += realmode_switch.o
COBJS-$(CONFIG_SYS_PC_BIOS) += bios_setup.o
+COBJS-$(CONFIG_VIDEO_VGA) += video_bios.o
+endif
+
COBJS-y += board.o
COBJS-y += bootm.o
COBJS-y += cmd_boot.o
@@ -41,12 +46,11 @@ COBJS-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o
COBJS-$(CONFIG_SYS_GENERIC_TIMER) += pcat_timer.o
COBJS-$(CONFIG_PCI) += pci.o
COBJS-$(CONFIG_PCI) += pci_type1.o
-COBJS-$(CONFIG_SYS_X86_REALMODE) += realmode.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_bios.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)
diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c
index e5caf13561..22bc26dde9 100644
--- a/arch/x86/lib/board.c
+++ b/arch/x86/lib/board.c
@@ -36,6 +36,7 @@
#include <stdio_dev.h>
#include <asm/u-boot-x86.h>
#include <asm/relocate.h>
+#include <asm/processor.h>
#include <asm/init_helpers.h>
#include <asm/init_wrappers.h>
@@ -98,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,
@@ -121,7 +129,6 @@ init_fnc_t *init_sequence_f[] = {
* initialise the CPU caches (to speed up the relocation process)
*/
init_fnc_t *init_sequence_f_r[] = {
- copy_gd_to_ram_f_r,
init_cache_f_r,
copy_uboot_to_ram,
clear_bss,
@@ -154,6 +161,9 @@ init_fnc_t *init_sequence_r[] = {
#ifndef CONFIG_SYS_NO_FLASH
flash_init_r,
#endif
+#ifdef CONFIG_SPI
+ init_func_spi;
+#endif
env_relocate_r,
#ifdef CONFIG_PCI
pci_init_r,
@@ -164,9 +174,6 @@ init_fnc_t *init_sequence_r[] = {
#ifdef CONFIG_MISC_INIT_R
misc_init_r,
#endif
-#if defined(CONFIG_CMD_PCMCIA) && !defined(CONFIG_CMD_IDE)
- pci_init_r,
-#endif
#if defined(CONFIG_CMD_KGDB)
kgdb_init_r,
#endif
diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c
index 9ec34ff992..3eec9a61d6 100644
--- a/arch/x86/lib/init_helpers.c
+++ b/arch/x86/lib/init_helpers.c
@@ -28,9 +28,11 @@
#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;
@@ -83,51 +85,17 @@ int calculate_relocation_address(void)
* requirements
*/
- /* Global Data is at top of available memory */
+ /* Stack is at top of available memory */
dest_addr = gd->ram_size;
- dest_addr -= GENERATED_GBL_DATA_SIZE;
- dest_addr &= ~15;
- gd->new_gd_addr = dest_addr;
-
- /* GDT is below Global Data */
- dest_addr -= X86_GDT_SIZE;
- dest_addr &= ~15;
- gd->gdt_addr = dest_addr;
-
- /* Stack is below GDT */
- 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);
- return 0;
-}
-
-int copy_gd_to_ram_f_r(void)
-{
- gd_t *ram_gd;
-
- /*
- * Global data is still in temporary memory (the CPU cache).
- * calculate_relocation_address() has set gd->new_gd_addr to
- * where the global data lives in RAM but getting it there
- * safely is a bit tricky due to the 'F-Segment Hack' that
- * we need to use for x86
- */
- ram_gd = (gd_t *)gd->new_gd_addr;
- memcpy((void *)ram_gd, gd, sizeof(gd_t));
-
- /*
- * Reload the Global Descriptor Table so FS points to the
- * in-RAM copy of Global Data (calculate_relocation_address()
- * has already calculated the in-RAM location of the GDT)
- */
- ram_gd->gd_addr = (ulong)ram_gd;
- init_gd(ram_gd, (u64 *)gd->gdt_addr);
+ /* Stack is at the bottom, so it can grow down */
+ gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN;
return 0;
}
@@ -195,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
diff --git a/arch/x86/lib/init_wrappers.c b/arch/x86/lib/init_wrappers.c
index 71449fe6fa..cca018fa9b 100644
--- a/arch/x86/lib/init_wrappers.c
+++ b/arch/x86/lib/init_wrappers.c
@@ -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/pcat_timer.c b/arch/x86/lib/pcat_timer.c
index 6b3db69447..b0b6637f3a 100644
--- a/arch/x86/lib/pcat_timer.c
+++ b/arch/x86/lib/pcat_timer.c
@@ -39,7 +39,7 @@ int timer_init(void)
* Timer 0 is used to increment system_tick 1000 times/sec
* Timer 1 was used for DRAM refresh in early PC's
* Timer 2 is used to drive the speaker
- * (to stasrt a beep: write 3 to port 0x61,
+ * (to start a beep: write 3 to port 0x61,
* to stop it again: write 0)
*/
outb(PIT_CMD_CTR0 | PIT_CMD_BOTH | PIT_CMD_MODE2,
diff --git a/arch/x86/lib/physmem.c b/arch/x86/lib/physmem.c
new file mode 100644
index 0000000000..18f0e62acd
--- /dev/null
+++ b/arch/x86/lib/physmem.c
@@ -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;
+}
diff --git a/arch/x86/lib/relocate.c b/arch/x86/lib/relocate.c
index 200baaba6a..23edca9526 100644
--- a/arch/x86/lib/relocate.c
+++ b/arch/x86/lib/relocate.c
@@ -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;
}
diff --git a/arch/x86/lib/timer.c b/arch/x86/lib/timer.c
index fd7032e92c..a13424b3e3 100644
--- a/arch/x86/lib/timer.c
+++ b/arch/x86/lib/timer.c
@@ -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;
+}
diff --git a/arch/x86/lib/video.c b/arch/x86/lib/video.c
index 3d6b24d620..20e2416ae1 100644
--- a/arch/x86/lib/video.c
+++ b/arch/x86/lib/video.c
@@ -222,8 +222,10 @@ int video_init(void)
int drv_video_init(void)
{
+#ifndef CONFIG_X86_NO_REAL_MODE
if (video_bios_init())
return 1;
+#endif
return video_init();
}
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 22142864c2..46af391f29 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -36,6 +36,10 @@
#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:
@@ -171,7 +175,7 @@ struct boot_params *load_zimage(char *image, unsigned long kernel_size,
else
*load_address = (void *)ZIMAGE_LOAD_ADDR;
-#if defined CONFIG_ZBOOT_32
+#if (defined CONFIG_ZBOOT_32 || defined CONFIG_X86_NO_REAL_MODE)
printf("Building boot_params at 0x%8.8lx\n", (ulong)setup_base);
memset(setup_base, 0, sizeof(*setup_base));
setup_base->hdr = params->hdr;
@@ -237,7 +241,7 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
struct setup_header *hdr = &setup_base->hdr;
int bootproto = get_boot_protocol(hdr);
-#if defined CONFIG_ZBOOT_32
+#if (defined CONFIG_ZBOOT_32 || defined CONFIG_X86_NO_REAL_MODE)
setup_base->e820_entries = install_e820_map(
ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map);
#endif
@@ -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)