diff options
Diffstat (limited to 'arch')
178 files changed, 11729 insertions, 2741 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 6e5544f9d7..e5f57efa49 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -368,6 +368,7 @@ config TARGET_AM335X_EVM select DM select DM_SERIAL select DM_GPIO + select TI_I2C_BOARD_DETECT config TARGET_AM335X_SL50 bool "Support am335x_sl50" @@ -380,6 +381,7 @@ config TARGET_AM43XX_EVM bool "Support am43xx_evm" select CPU_V7 select SUPPORT_SPL + select TI_I2C_BOARD_DETECT config TARGET_BAV335X bool "Support bav335x" @@ -448,6 +450,7 @@ config ARCH_KEYSTONE bool "TI Keystone" select CPU_V7 select SUPPORT_SPL + select CMD_POWEROFF config ARCH_MX7 bool "Freescale MX7" diff --git a/arch/arm/config.mk b/arch/arm/config.mk index 8fa57ecfd8..9af6c37218 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -122,6 +122,10 @@ ifdef CONFIG_OF_EMBED OBJCOPYFLAGS += -j .dtb.init.rodata endif +ifdef CONFIG_EFI_LOADER +OBJCOPYFLAGS += -j .efi_runtime -j .efi_runtime_rel +endif + ifneq ($(CONFIG_IMX_CONFIG),) ifdef CONFIG_SPL ifndef CONFIG_SPL_BUILD diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c index b6db23e981..399b07c542 100644 --- a/arch/arm/cpu/arm926ejs/lpc32xx/devices.c +++ b/arch/arm/cpu/arm926ejs/lpc32xx/devices.c @@ -45,10 +45,10 @@ void lpc32xx_uart_init(unsigned int uart_id) #if !CONFIG_IS_ENABLED(OF_CONTROL) static const struct ns16550_platdata lpc32xx_uart[] = { - { UART3_BASE, 2, CONFIG_SYS_NS16550_CLK }, - { UART4_BASE, 2, CONFIG_SYS_NS16550_CLK }, - { UART5_BASE, 2, CONFIG_SYS_NS16550_CLK }, - { UART6_BASE, 2, CONFIG_SYS_NS16550_CLK }, + { .base = UART3_BASE, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK }, + { .base = UART4_BASE, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK }, + { .base = UART5_BASE, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK }, + { .base = UART6_BASE, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK }, }; #if defined(CONFIG_LPC32XX_HSUART) diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index e8d5be32b4..a99cbf9de0 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -40,14 +40,14 @@ DECLARE_GLOBAL_DATA_PTR; #if !CONFIG_IS_ENABLED(OF_CONTROL) static const struct ns16550_platdata am33xx_serial[] = { - { CONFIG_SYS_NS16550_COM1, 2, CONFIG_SYS_NS16550_CLK }, + { .base = CONFIG_SYS_NS16550_COM1, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK }, # ifdef CONFIG_SYS_NS16550_COM2 - { CONFIG_SYS_NS16550_COM2, 2, CONFIG_SYS_NS16550_CLK }, + { .base = CONFIG_SYS_NS16550_COM2, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK }, # ifdef CONFIG_SYS_NS16550_COM3 - { CONFIG_SYS_NS16550_COM3, 2, CONFIG_SYS_NS16550_CLK }, - { CONFIG_SYS_NS16550_COM4, 2, CONFIG_SYS_NS16550_CLK }, - { CONFIG_SYS_NS16550_COM5, 2, CONFIG_SYS_NS16550_CLK }, - { CONFIG_SYS_NS16550_COM6, 2, CONFIG_SYS_NS16550_CLK }, + { .base = CONFIG_SYS_NS16550_COM3, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK }, + { .base = CONFIG_SYS_NS16550_COM4, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK }, + { .base = CONFIG_SYS_NS16550_COM5, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK }, + { .base = CONFIG_SYS_NS16550_COM6, .reg_shift = 2, .clock = CONFIG_SYS_NS16550_CLK }, # endif # endif }; diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index a34675c795..91a3debe91 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -548,7 +548,8 @@ void imx_setup_hdmi(void) { struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR; - int reg; + int reg, count; + u8 val; /* Turn on HDMI PHY clock */ reg = readl(&mxc_ccm->CCGR2); @@ -565,6 +566,16 @@ void imx_setup_hdmi(void) |(CHSCCDR_IPU_PRE_CLK_540M_PFD << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET); writel(reg, &mxc_ccm->chsccdr); + + /* Clear the overflow condition */ + if (readb(&hdmi->ih_fc_stat2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK) { + /* TMDS software reset */ + writeb((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, &hdmi->mc_swrstz); + val = readb(&hdmi->fc_invidconf); + /* Need minimum 3 times to write to clear the register */ + for (count = 0 ; count < 5 ; count++) + writeb(val, &hdmi->fc_invidconf); + } } #endif diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c index e28b79568d..cb41055b91 100644 --- a/arch/arm/cpu/armv7/omap-common/clocks-common.c +++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c @@ -339,7 +339,8 @@ void configure_mpu_dpll(void) debug("MPU DPLL locked\n"); } -#if defined(CONFIG_USB_EHCI_OMAP) || defined(CONFIG_USB_XHCI_OMAP) +#if defined(CONFIG_USB_EHCI_OMAP) || defined(CONFIG_USB_XHCI_OMAP) || \ + defined(CONFIG_USB_MUSB_OMAP2PLUS) static void setup_usb_dpll(void) { const struct dpll_params *params; @@ -406,7 +407,8 @@ static void setup_dplls(void) /* MPU dpll */ configure_mpu_dpll(); -#if defined(CONFIG_USB_EHCI_OMAP) || defined(CONFIG_USB_XHCI_OMAP) +#if defined(CONFIG_USB_EHCI_OMAP) || defined(CONFIG_USB_XHCI_OMAP) || \ + defined(CONFIG_USB_MUSB_OMAP2PLUS) setup_usb_dpll(); #endif params = get_ddr_dpll_params(*dplls_data); @@ -769,7 +771,7 @@ void lock_dpll(u32 const base) wait_for_lock(base); } -void setup_clocks_for_console(void) +static void setup_clocks_for_console(void) { /* Do not add any spl_debug prints in this function */ clrsetbits_le32((*prcm)->cm_l4per_clkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, @@ -853,14 +855,31 @@ void do_disable_clocks(u32 const *clk_domains, disable_clock_domain(clk_domains[i]); } -void prcm_init(void) +/** + * setup_early_clocks() - Setup early clocks needed for SoC + * + * Setup clocks for console, SPL basic initialization clocks and initialize + * the timer. This is invoked prior prcm_init. + */ +void setup_early_clocks(void) { switch (omap_hw_init_context()) { case OMAP_INIT_CONTEXT_SPL: case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR: case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH: + setup_clocks_for_console(); enable_basic_clocks(); timer_init(); + /* Fall through */ + } +} + +void prcm_init(void) +{ + switch (omap_hw_init_context()) { + case OMAP_INIT_CONTEXT_SPL: + case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR: + case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH: scale_vcores(*omap_vcores); setup_dplls(); setup_warmreset_time(); diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c index bf7bf262c7..9a9c764b4d 100644 --- a/arch/arm/cpu/armv7/omap-common/emif-common.c +++ b/arch/arm/cpu/armv7/omap-common/emif-common.c @@ -163,7 +163,11 @@ void emif_update_timings(u32 base, const struct emif_regs *regs) { struct emif_reg_struct *emif = (struct emif_reg_struct *)base; - writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl_shdw); + if (!is_dra7xx()) + writel(regs->ref_ctrl, &emif->emif_sdram_ref_ctrl_shdw); + else + writel(regs->ref_ctrl_final, &emif->emif_sdram_ref_ctrl_shdw); + writel(regs->sdram_tim1, &emif->emif_sdram_tim_1_shdw); writel(regs->sdram_tim2, &emif->emif_sdram_tim_2_shdw); writel(regs->sdram_tim3, &emif->emif_sdram_tim_3_shdw); @@ -191,6 +195,7 @@ void emif_update_timings(u32 base, const struct emif_regs *regs) } } +#ifndef CONFIG_OMAP44XX static void omap5_ddr3_leveling(u32 base, const struct emif_regs *regs) { struct emif_reg_struct *emif = (struct emif_reg_struct *)base; @@ -246,33 +251,39 @@ static void update_hwleveling_output(u32 base, const struct emif_regs *regs) { struct emif_reg_struct *emif = (struct emif_reg_struct *)base; u32 *emif_ext_phy_ctrl_reg, *emif_phy_status; - u32 reg, i; + u32 reg, i, phy; emif_phy_status = (u32 *)&emif->emif_ddr_phy_status[7]; + phy = readl(&emif->emif_ddr_phy_ctrl_1); /* Update PHY_REG_RDDQS_RATIO */ emif_ext_phy_ctrl_reg = (u32 *)&emif->emif_ddr_ext_phy_ctrl_7; - for (i = 0; i < PHY_RDDQS_RATIO_REGS; i++) { - reg = readl(emif_phy_status++); - writel(reg, emif_ext_phy_ctrl_reg++); - writel(reg, emif_ext_phy_ctrl_reg++); - } + if (!(phy & EMIF_DDR_PHY_CTRL_1_RDLVL_MASK_MASK)) + for (i = 0; i < PHY_RDDQS_RATIO_REGS; i++) { + reg = readl(emif_phy_status++); + writel(reg, emif_ext_phy_ctrl_reg++); + writel(reg, emif_ext_phy_ctrl_reg++); + } /* Update PHY_REG_FIFO_WE_SLAVE_RATIO */ emif_ext_phy_ctrl_reg = (u32 *)&emif->emif_ddr_ext_phy_ctrl_2; - for (i = 0; i < PHY_FIFO_WE_SLAVE_RATIO_REGS; i++) { - reg = readl(emif_phy_status++); - writel(reg, emif_ext_phy_ctrl_reg++); - writel(reg, emif_ext_phy_ctrl_reg++); - } + emif_phy_status = (u32 *)&emif->emif_ddr_phy_status[12]; + if (!(phy & EMIF_DDR_PHY_CTRL_1_RDLVLGATE_MASK_MASK)) + for (i = 0; i < PHY_FIFO_WE_SLAVE_RATIO_REGS; i++) { + reg = readl(emif_phy_status++); + writel(reg, emif_ext_phy_ctrl_reg++); + writel(reg, emif_ext_phy_ctrl_reg++); + } /* Update PHY_REG_WR_DQ/DQS_SLAVE_RATIO */ emif_ext_phy_ctrl_reg = (u32 *)&emif->emif_ddr_ext_phy_ctrl_12; - for (i = 0; i < PHY_REG_WR_DQ_SLAVE_RATIO_REGS; i++) { - reg = readl(emif_phy_status++); - writel(reg, emif_ext_phy_ctrl_reg++); - writel(reg, emif_ext_phy_ctrl_reg++); - } + emif_phy_status = (u32 *)&emif->emif_ddr_phy_status[17]; + if (!(phy & EMIF_DDR_PHY_CTRL_1_WRLVL_MASK_MASK)) + for (i = 0; i < PHY_REG_WR_DQ_SLAVE_RATIO_REGS; i++) { + reg = readl(emif_phy_status++); + writel(reg, emif_ext_phy_ctrl_reg++); + writel(reg, emif_ext_phy_ctrl_reg++); + } /* Disable Leveling */ writel(regs->emif_ddr_phy_ctlr_1, &emif->emif_ddr_phy_ctrl_1); @@ -323,8 +334,10 @@ static void dra7_ddr3_init(u32 base, const struct emif_regs *regs) { struct emif_reg_struct *emif = (struct emif_reg_struct *)base; - if (warm_reset()) + if (warm_reset()) { emif_reset_phy(base); + writel(0x0, &emif->emif_pwr_mgmt_ctrl); + } do_ext_phy_settings(base, regs); writel(regs->ref_ctrl | EMIF_REG_INITREF_DIS_MASK, @@ -393,6 +406,7 @@ static void ddr3_init(u32 base, const struct emif_regs *regs) else dra7_ddr3_init(base, regs); } +#endif #ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS #define print_timing_reg(reg) debug(#reg" - 0x%08x\n", (reg)) @@ -1166,7 +1180,7 @@ static void do_sdram_init(u32 base) #endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */ /* - * Initializing the LPDDR2 device can not happen from SDRAM. + * Initializing the DDR device can not happen from SDRAM. * Changing the timing registers in EMIF can happen(going from one * OPP to another) */ @@ -1174,15 +1188,19 @@ static void do_sdram_init(u32 base) if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_LPDDR2) lpddr2_init(base, regs); +#ifndef CONFIG_OMAP44XX else ddr3_init(base, regs); +#endif } +#ifdef CONFIG_OMAP54X if (warm_reset() && (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) && !is_dra7xx()) { set_lpmode_selfrefresh(base); emif_reset_phy(base); omap5_ddr3_leveling(base, regs); } +#endif /* Write to the shadow registers */ emif_update_timings(base, regs); @@ -1317,6 +1335,8 @@ void dmm_init(u32 base) &hw_lisa_map_regs->dmm_lisa_map_1); writel(lisa_map_regs->dmm_lisa_map_0, &hw_lisa_map_regs->dmm_lisa_map_0); + + setbits_le32(MA_PRIORITY, MA_HIMEM_INTERLEAVE_UN_MASK); } /* diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index 80794f9c61..01c2d576c9 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -35,13 +35,13 @@ static void set_mux_conf_regs(void) { switch (omap_hw_init_context()) { case OMAP_INIT_CONTEXT_SPL: - set_muxconf_regs_essential(); + set_muxconf_regs(); break; case OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL: break; case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR: case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH: - set_muxconf_regs_essential(); + set_muxconf_regs(); break; } } @@ -84,34 +84,36 @@ void __weak srcomp_enable(void) { } -#ifdef CONFIG_ARCH_CPU_INIT -/* - * SOC specific cpu init +/** + * do_board_detect() - Detect board description + * + * Function to detect board description. This is expected to be + * overridden in the SoC family board file where desired. */ -int arch_cpu_init(void) +void __weak do_board_detect(void) { -#ifdef CONFIG_SPL - save_omap_boot_params(); -#endif - return 0; } -#endif /* CONFIG_ARCH_CPU_INIT */ -/* - * Routine: s_init - * Description: Does early system init of watchdog, muxing, andclocks +void s_init(void) +{ +} + +/** + * early_system_init - Does Early system initialization. + * + * Does early system init of watchdog, muxing, andclocks * Watchdog disable is done always. For the rest what gets done - * depends on the boot mode in which this function is executed - * 1. s_init of SPL running from SRAM - * 2. s_init of U-Boot running from FLASH - * 3. s_init of U-Boot loaded to SDRAM by SPL - * 4. s_init of U-Boot loaded to SDRAM by ROM code using the + * depends on the boot mode in which this function is executed when + * 1. SPL running from SRAM + * 2. U-Boot running from FLASH + * 3. U-Boot loaded to SDRAM by SPL + * 4. U-Boot loaded to SDRAM by ROM code using the * Configuration Header feature * Please have a look at the respective functions to see what gets * done in each of these cases * This function is called with SRAM stack. */ -void s_init(void) +void early_system_init(void) { init_omap_revision(); hw_data_init(); @@ -125,16 +127,17 @@ void s_init(void) set_mux_conf_regs(); #ifdef CONFIG_SPL_BUILD srcomp_enable(); - setup_clocks_for_console(); - do_io_settings(); #endif + setup_early_clocks(); + do_board_detect(); prcm_init(); } #ifdef CONFIG_SPL_BUILD void board_init_f(ulong dummy) { + early_system_init(); #ifdef CONFIG_BOARD_EARLY_INIT_F board_early_init_f(); #endif @@ -143,6 +146,12 @@ void board_init_f(ulong dummy) } #endif +int arch_cpu_init_dm(void) +{ + early_system_init(); + return 0; +} + /* * Routine: wait_for_command_complete * Description: Wait for posting to finish on watchdog diff --git a/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds b/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds index ccd0c8352e..8fec715ca5 100644 --- a/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds +++ b/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds @@ -35,7 +35,7 @@ SECTIONS . = ALIGN(4); .u_boot_list : { - KEEP(*(SORT(.u_boot_list*_i2c_*))); + KEEP(*(SORT(.u_boot_list*))); } >.sram . = ALIGN(4); diff --git a/arch/arm/cpu/armv7/omap3/boot.c b/arch/arm/cpu/armv7/omap3/boot.c index 44d7c30662..64b242b752 100644 --- a/arch/arm/cpu/armv7/omap3/boot.c +++ b/arch/arm/cpu/armv7/omap3/boot.c @@ -57,12 +57,16 @@ u32 omap_sys_boot_device(void) return boot_devices[sys_boot]; } -char omap_reboot_mode(void) +int omap_reboot_mode(char *mode, unsigned int length) { u32 reboot_mode; char c; - reboot_mode = readl((u32 *)(OMAP34XX_SCRATCHPAD + 4)); + if (length < 2) + return -1; + + reboot_mode = readl((u32 *)(OMAP34XX_SCRATCHPAD + + OMAP_REBOOT_REASON_OFFSET)); c = (reboot_mode >> 24) & 0xff; if (c != 'B') @@ -74,23 +78,27 @@ char omap_reboot_mode(void) c = reboot_mode & 0xff; - return c; + mode[0] = c; + mode[1] = '\0'; + + return 0; } int omap_reboot_mode_clear(void) { - writel(0, (u32 *)(OMAP34XX_SCRATCHPAD + 4)); + writel(0, (u32 *)(OMAP34XX_SCRATCHPAD + OMAP_REBOOT_REASON_OFFSET)); return 0; } -int omap_reboot_mode_store(char c) +int omap_reboot_mode_store(char *mode) { u32 reboot_mode; - reboot_mode = 'B' << 24 | 'M' << 16 | c; + reboot_mode = 'B' << 24 | 'M' << 16 | mode[0]; - writel(reboot_mode, (u32 *)(OMAP34XX_SCRATCHPAD + 4)); + writel(reboot_mode, (u32 *)(OMAP34XX_SCRATCHPAD + + OMAP_REBOOT_REASON_OFFSET)); return 0; } diff --git a/arch/arm/cpu/armv7/omap4/Kconfig b/arch/arm/cpu/armv7/omap4/Kconfig index df27ea10a2..49adb8ec5b 100644 --- a/arch/arm/cpu/armv7/omap4/Kconfig +++ b/arch/arm/cpu/armv7/omap4/Kconfig @@ -13,6 +13,9 @@ config TARGET_OMAP4_PANDA config TARGET_OMAP4_SDP4430 bool "TI OMAP4 SDP4430" +config TARGET_KC1 + bool "Amazon Kindle Fire (first generation)" + endchoice config SYS_SOC @@ -21,5 +24,6 @@ config SYS_SOC source "board/gumstix/duovero/Kconfig" source "board/ti/panda/Kconfig" source "board/ti/sdp4430/Kconfig" +source "board/amazon/kc1/Kconfig" endif diff --git a/arch/arm/cpu/armv7/omap4/boot.c b/arch/arm/cpu/armv7/omap4/boot.c index 4b5aa770e7..7f5791e9ed 100644 --- a/arch/arm/cpu/armv7/omap4/boot.c +++ b/arch/arm/cpu/armv7/omap4/boot.c @@ -9,6 +9,7 @@ #include <common.h> #include <asm/io.h> #include <asm/omap_common.h> +#include <asm/arch/sys_proto.h> #include <spl.h> static u32 boot_devices[] = { @@ -58,3 +59,47 @@ u32 omap_sys_boot_device(void) return boot_devices[sys_boot]; } + +int omap_reboot_mode(char *mode, unsigned int length) +{ + unsigned int limit; + unsigned int i; + + if (length < 2) + return -1; + + if (!warm_reset()) + return -1; + + limit = (length < OMAP_REBOOT_REASON_SIZE) ? length : + OMAP_REBOOT_REASON_SIZE; + + for (i = 0; i < (limit - 1); i++) + mode[i] = readb((u8 *)(OMAP44XX_SAR_RAM_BASE + + OMAP_REBOOT_REASON_OFFSET + i)); + + mode[i] = '\0'; + + return 0; +} + +int omap_reboot_mode_clear(void) +{ + writeb(0, (u8 *)(OMAP44XX_SAR_RAM_BASE + OMAP_REBOOT_REASON_OFFSET)); + + return 0; +} + +int omap_reboot_mode_store(char *mode) +{ + unsigned int i; + + for (i = 0; i < (OMAP_REBOOT_REASON_SIZE - 1) && mode[i] != '\0'; i++) + writeb(mode[i], (u8 *)(OMAP44XX_SAR_RAM_BASE + + OMAP_REBOOT_REASON_OFFSET + i)); + + writeb('\0', (u8 *)(OMAP44XX_SAR_RAM_BASE + + OMAP_REBOOT_REASON_OFFSET + i)); + + return 0; +} diff --git a/arch/arm/cpu/armv7/omap4/emif.c b/arch/arm/cpu/armv7/omap4/emif.c index e89032be75..403c3c6146 100644 --- a/arch/arm/cpu/armv7/omap4/emif.c +++ b/arch/arm/cpu/armv7/omap4/emif.c @@ -96,7 +96,7 @@ static const struct lpddr2_ac_timings const* &timings_jedec_400_mhz }; -static const struct lpddr2_device_timings jedec_default_timings = { +const struct lpddr2_device_timings jedec_default_timings = { .ac_timings = jedec_ac_timings, .min_tck = &min_tck_jedec }; diff --git a/arch/arm/cpu/armv7/omap4/hw_data.c b/arch/arm/cpu/armv7/omap4/hw_data.c index 029533c851..02c06c1577 100644 --- a/arch/arm/cpu/armv7/omap4/hw_data.c +++ b/arch/arm/cpu/armv7/omap4/hw_data.c @@ -355,6 +355,10 @@ void enable_basic_clocks(void) (*prcm)->cm_l4per_gptimer2_clkctrl, (*prcm)->cm_wkup_wdtimer2_clkctrl, (*prcm)->cm_l4per_uart3_clkctrl, + (*prcm)->cm_l4per_i2c1_clkctrl, + (*prcm)->cm_l4per_i2c2_clkctrl, + (*prcm)->cm_l4per_i2c3_clkctrl, + (*prcm)->cm_l4per_i2c4_clkctrl, 0 }; @@ -372,10 +376,14 @@ void enable_basic_clocks(void) setbits_le32((*prcm)->cm_wkup_gptimer1_clkctrl, GPTIMER1_CLKCTRL_CLKSEL_MASK); - /* Enable optional 48M functional clock for USB PHY */ + /* Enable optional 48M functional clock for USB PHY */ setbits_le32((*prcm)->cm_l3init_usbphy_clkctrl, USBPHY_CLKCTRL_OPTFCLKEN_PHY_48M_MASK); + /* Enable 32 KHz clock for USB PHY */ + setbits_le32((*prcm)->cm_coreaon_usb_phy1_core_clkctrl, + USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K); + do_enable_clocks(clk_domains_essential, clk_modules_hw_auto_essential, clk_modules_explicit_en_essential, @@ -391,7 +399,6 @@ void enable_basic_uboot_clocks(void) u32 const clk_modules_hw_auto_essential[] = { (*prcm)->cm_l3init_hsusbotg_clkctrl, (*prcm)->cm_l3init_usbphy_clkctrl, - (*prcm)->cm_l3init_usbphy_clkctrl, (*prcm)->cm_clksel_usb_60mhz, (*prcm)->cm_l3init_hsusbtll_clkctrl, 0 @@ -399,10 +406,6 @@ void enable_basic_uboot_clocks(void) u32 const clk_modules_explicit_en_essential[] = { (*prcm)->cm_l4per_mcspi1_clkctrl, - (*prcm)->cm_l4per_i2c1_clkctrl, - (*prcm)->cm_l4per_i2c2_clkctrl, - (*prcm)->cm_l4per_i2c3_clkctrl, - (*prcm)->cm_l4per_i2c4_clkctrl, (*prcm)->cm_l3init_hsusbhost_clkctrl, 0 }; diff --git a/arch/arm/cpu/armv7/omap4/prcm-regs.c b/arch/arm/cpu/armv7/omap4/prcm-regs.c index a09581e55b..2f0e1e851a 100644 --- a/arch/arm/cpu/armv7/omap4/prcm-regs.c +++ b/arch/arm/cpu/armv7/omap4/prcm-regs.c @@ -129,6 +129,7 @@ struct prcm_regs const omap4_prcm = { .cm_div_m2_dpll_unipro = 0x4a0081d0, .cm_ssc_deltamstep_dpll_unipro = 0x4a0081e8, .cm_ssc_modfreqdiv_dpll_unipro = 0x4a0081ec, + .cm_coreaon_usb_phy1_core_clkctrl = 0x4a008640, /* cm2.core */ .cm_l3_1_clkstctrl = 0x4a008700, diff --git a/arch/arm/cpu/armv7/omap4/sdram_elpida.c b/arch/arm/cpu/armv7/omap4/sdram_elpida.c index 4462c72c7a..78b4f09ce2 100644 --- a/arch/arm/cpu/armv7/omap4/sdram_elpida.c +++ b/arch/arm/cpu/armv7/omap4/sdram_elpida.c @@ -147,14 +147,14 @@ void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs) #else -static const struct lpddr2_device_details elpida_2G_S4_details = { +const struct lpddr2_device_details elpida_2G_S4_details = { .type = LPDDR2_TYPE_S4, .density = LPDDR2_DENSITY_2Gb, .io_width = LPDDR2_IO_WIDTH_32, .manufacturer = LPDDR2_MANUFACTURER_ELPIDA }; -static const struct lpddr2_device_details elpida_4G_S4_details = { +const struct lpddr2_device_details elpida_4G_S4_details = { .type = LPDDR2_TYPE_S4, .density = LPDDR2_DENSITY_4Gb, .io_width = LPDDR2_IO_WIDTH_32, @@ -278,7 +278,7 @@ static const struct lpddr2_ac_timings *elpida_ac_timings[MAX_NUM_SPEEDBINS] = { &timings_elpida_400_mhz }; -static const struct lpddr2_device_timings elpida_2G_S4_timings = { +const struct lpddr2_device_timings elpida_2G_S4_timings = { .ac_timings = elpida_ac_timings, .min_tck = &min_tck_elpida, }; diff --git a/arch/arm/cpu/armv7/omap5/Kconfig b/arch/arm/cpu/armv7/omap5/Kconfig index bfa264eccc..026bf24ddc 100644 --- a/arch/arm/cpu/armv7/omap5/Kconfig +++ b/arch/arm/cpu/armv7/omap5/Kconfig @@ -12,9 +12,11 @@ config TARGET_OMAP5_UEVM config TARGET_DRA7XX_EVM bool "TI DRA7XX" + select TI_I2C_BOARD_DETECT config TARGET_BEAGLE_X15 bool "BeagleBoard X15" + select TI_I2C_BOARD_DETECT endchoice diff --git a/arch/arm/cpu/armv7/omap5/sdram.c b/arch/arm/cpu/armv7/omap5/sdram.c index a8d63c23c8..7dc5bb7e4a 100644 --- a/arch/arm/cpu/armv7/omap5/sdram.c +++ b/arch/arm/cpu/armv7/omap5/sdram.c @@ -137,81 +137,6 @@ const struct emif_regs emif_regs_ddr3_532_mhz_1cs_es2 = { .emif_rd_wr_exec_thresh = 0x40000305 }; -const struct emif_regs emif_1_regs_ddr3_532_mhz_1cs_dra_es1 = { - .sdram_config_init = 0x61851ab2, - .sdram_config = 0x61851ab2, - .sdram_config2 = 0x08000000, - .ref_ctrl = 0x000040F1, - .ref_ctrl_final = 0x00001035, - .sdram_tim1 = 0xCCCF36B3, - .sdram_tim2 = 0x308F7FDA, - .sdram_tim3 = 0x027F88A8, - .read_idle_ctrl = 0x00050000, - .zq_config = 0x0007190B, - .temp_alert_config = 0x00000000, - .emif_ddr_phy_ctlr_1_init = 0x0024400B, - .emif_ddr_phy_ctlr_1 = 0x0E24400B, - .emif_ddr_ext_phy_ctrl_1 = 0x10040100, - .emif_ddr_ext_phy_ctrl_2 = 0x00910091, - .emif_ddr_ext_phy_ctrl_3 = 0x00950095, - .emif_ddr_ext_phy_ctrl_4 = 0x009B009B, - .emif_ddr_ext_phy_ctrl_5 = 0x009E009E, - .emif_rd_wr_lvl_rmp_win = 0x00000000, - .emif_rd_wr_lvl_rmp_ctl = 0x80000000, - .emif_rd_wr_lvl_ctl = 0x00000000, - .emif_rd_wr_exec_thresh = 0x00000305 -}; - -const struct emif_regs emif_2_regs_ddr3_532_mhz_1cs_dra_es1 = { - .sdram_config_init = 0x61851B32, - .sdram_config = 0x61851B32, - .sdram_config2 = 0x08000000, - .ref_ctrl = 0x000040F1, - .ref_ctrl_final = 0x00001035, - .sdram_tim1 = 0xCCCF36B3, - .sdram_tim2 = 0x308F7FDA, - .sdram_tim3 = 0x027F88A8, - .read_idle_ctrl = 0x00050000, - .zq_config = 0x0007190B, - .temp_alert_config = 0x00000000, - .emif_ddr_phy_ctlr_1_init = 0x0024400B, - .emif_ddr_phy_ctlr_1 = 0x0E24400B, - .emif_ddr_ext_phy_ctrl_1 = 0x10040100, - .emif_ddr_ext_phy_ctrl_2 = 0x00910091, - .emif_ddr_ext_phy_ctrl_3 = 0x00950095, - .emif_ddr_ext_phy_ctrl_4 = 0x009B009B, - .emif_ddr_ext_phy_ctrl_5 = 0x009E009E, - .emif_rd_wr_lvl_rmp_win = 0x00000000, - .emif_rd_wr_lvl_rmp_ctl = 0x80000000, - .emif_rd_wr_lvl_ctl = 0x00000000, - .emif_rd_wr_exec_thresh = 0x00000305 -}; - -const struct emif_regs emif_1_regs_ddr3_666_mhz_1cs_dra_es1 = { - .sdram_config_init = 0x61862B32, - .sdram_config = 0x61862B32, - .sdram_config2 = 0x08000000, - .ref_ctrl = 0x0000514C, - .ref_ctrl_final = 0x0000144A, - .sdram_tim1 = 0xD113781C, - .sdram_tim2 = 0x305A7FDA, - .sdram_tim3 = 0x409F86A8, - .read_idle_ctrl = 0x00050000, - .zq_config = 0x5007190B, - .temp_alert_config = 0x00000000, - .emif_ddr_phy_ctlr_1_init = 0x0024400D, - .emif_ddr_phy_ctlr_1 = 0x0E24400D, - .emif_ddr_ext_phy_ctrl_1 = 0x10040100, - .emif_ddr_ext_phy_ctrl_2 = 0x00A400A4, - .emif_ddr_ext_phy_ctrl_3 = 0x00A900A9, - .emif_ddr_ext_phy_ctrl_4 = 0x00B000B0, - .emif_ddr_ext_phy_ctrl_5 = 0x00B000B0, - .emif_rd_wr_lvl_rmp_win = 0x00000000, - .emif_rd_wr_lvl_rmp_ctl = 0x80000000, - .emif_rd_wr_lvl_ctl = 0x00000000, - .emif_rd_wr_exec_thresh = 0x00000305 -}; - const struct dmm_lisa_map_regs lisa_map_4G_x_2_x_2 = { .dmm_lisa_map_0 = 0x0, .dmm_lisa_map_1 = 0x0, @@ -220,53 +145,6 @@ const struct dmm_lisa_map_regs lisa_map_4G_x_2_x_2 = { .is_ma_present = 0x1 }; -/* - * DRA752 EVM board has 1.5 GB of memory - * EMIF1 --> 2Gb * 2 = 512MB - * EMIF2 --> 2Gb * 4 = 1GB - * so mapping 1GB interleaved and 512MB non-interleaved - */ -const struct dmm_lisa_map_regs lisa_map_2G_x_2_x_2_2G_x_1_x_2 = { - .dmm_lisa_map_0 = 0x0, - .dmm_lisa_map_1 = 0x80640300, - .dmm_lisa_map_2 = 0xC0500220, - .dmm_lisa_map_3 = 0xFF020100, - .is_ma_present = 0x1 -}; - -/* - * DRA752 EVM EMIF1 ONLY CONFIGURATION - */ -const struct dmm_lisa_map_regs lisa_map_2G_x_1_x_2 = { - .dmm_lisa_map_0 = 0x0, - .dmm_lisa_map_1 = 0x0, - .dmm_lisa_map_2 = 0x80500100, - .dmm_lisa_map_3 = 0xFF020100, - .is_ma_present = 0x1 -}; - -/* - * DRA752 EVM EMIF2 ONLY CONFIGURATION - */ -const struct dmm_lisa_map_regs lisa_map_2G_x_2_x_2 = { - .dmm_lisa_map_0 = 0x0, - .dmm_lisa_map_1 = 0x0, - .dmm_lisa_map_2 = 0x80600200, - .dmm_lisa_map_3 = 0xFF020100, - .is_ma_present = 0x1 -}; - -/* - * DRA722 EVM EMIF1 CONFIGURATION - */ -const struct dmm_lisa_map_regs lisa_map_2G_x_2 = { - .dmm_lisa_map_0 = 0x0, - .dmm_lisa_map_1 = 0x0, - .dmm_lisa_map_2 = 0x80600100, - .dmm_lisa_map_3 = 0xFF020100, - .is_ma_present = 0x1 -}; - static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs) { switch (omap_revision()) { @@ -280,25 +158,9 @@ static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs) *regs = &emif_regs_532_mhz_2cs_es2; break; case OMAP5432_ES2_0: + default: *regs = &emif_regs_ddr3_532_mhz_1cs_es2; break; - case DRA752_ES1_0: - case DRA752_ES1_1: - case DRA752_ES2_0: - switch (emif_nr) { - case 1: - *regs = &emif_1_regs_ddr3_532_mhz_1cs_dra_es1; - break; - case 2: - *regs = &emif_2_regs_ddr3_532_mhz_1cs_dra_es1; - break; - } - break; - case DRA722_ES1_0: - *regs = &emif_1_regs_ddr3_666_mhz_1cs_dra_es1; - break; - default: - *regs = &emif_1_regs_ddr3_532_mhz_1cs_dra_es1; } } @@ -313,16 +175,9 @@ static void emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs case OMAP5430_ES2_0: case OMAP5432_ES1_0: case OMAP5432_ES2_0: + default: *dmm_lisa_regs = &lisa_map_4G_x_2_x_2; break; - case DRA752_ES1_0: - case DRA752_ES1_1: - case DRA752_ES2_0: - *dmm_lisa_regs = &lisa_map_2G_x_2_x_2_2G_x_1_x_2; - break; - case DRA722_ES1_0: - default: - *dmm_lisa_regs = &lisa_map_2G_x_2; } } @@ -643,11 +498,12 @@ static void do_ext_phy_settings_dra7(u32 base, const struct emif_regs *regs) u32 *emif_ext_phy_ctrl_base = 0; u32 emif_nr; const u32 *ext_phy_ctrl_const_regs; - u32 i, hw_leveling, size; + u32 i, hw_leveling, size, phy; emif_nr = (base == EMIF1_BASE) ? 1 : 2; hw_leveling = regs->emif_rd_wr_lvl_rmp_ctl >> EMIF_REG_RDWRLVL_EN_SHIFT; + phy = regs->emif_ddr_phy_ctlr_1_init; emif_ext_phy_ctrl_base = (u32 *)&(emif->emif_ddr_ext_phy_ctrl_1); @@ -657,18 +513,35 @@ static void do_ext_phy_settings_dra7(u32 base, const struct emif_regs *regs) writel(ext_phy_ctrl_const_regs[0], &emif_ext_phy_ctrl_base[0]); writel(ext_phy_ctrl_const_regs[0], &emif_ext_phy_ctrl_base[1]); - if (!hw_leveling) { - /* - * Copy the predefined PHY register values - * in case of sw leveling - */ - for (i = 1; i < 25; i++) { + /* + * Copy the predefined PHY register values + * if leveling is disabled. + */ + if (phy & EMIF_DDR_PHY_CTRL_1_RDLVLGATE_MASK_MASK) + for (i = 1; i < 6; i++) { writel(ext_phy_ctrl_const_regs[i], &emif_ext_phy_ctrl_base[i * 2]); writel(ext_phy_ctrl_const_regs[i], &emif_ext_phy_ctrl_base[i * 2 + 1]); } - } else { + + if (phy & EMIF_DDR_PHY_CTRL_1_RDLVL_MASK_MASK) + for (i = 6; i < 11; i++) { + writel(ext_phy_ctrl_const_regs[i], + &emif_ext_phy_ctrl_base[i * 2]); + writel(ext_phy_ctrl_const_regs[i], + &emif_ext_phy_ctrl_base[i * 2 + 1]); + } + + if (phy & EMIF_DDR_PHY_CTRL_1_WRLVL_MASK_MASK) + for (i = 11; i < 25; i++) { + writel(ext_phy_ctrl_const_regs[i], + &emif_ext_phy_ctrl_base[i * 2]); + writel(ext_phy_ctrl_const_regs[i], + &emif_ext_phy_ctrl_base[i * 2 + 1]); + } + + if (hw_leveling) { /* * Write the init value for HW levling to occur */ diff --git a/arch/arm/cpu/armv8/cache.S b/arch/arm/cpu/armv8/cache.S index ab8c08917a..a9f4fec387 100644 --- a/arch/arm/cpu/armv8/cache.S +++ b/arch/arm/cpu/armv8/cache.S @@ -10,6 +10,7 @@ #include <asm-offsets.h> #include <config.h> #include <asm/macro.h> +#include <asm/system.h> #include <linux/linkage.h> /* @@ -160,3 +161,56 @@ ENTRY(__asm_flush_l3_cache) ret ENDPROC(__asm_flush_l3_cache) .weak __asm_flush_l3_cache + +/* + * void __asm_switch_ttbr(ulong new_ttbr) + * + * Safely switches to a new page table. + */ +ENTRY(__asm_switch_ttbr) + /* x2 = SCTLR (alive throghout the function) */ + switch_el x4, 3f, 2f, 1f +3: mrs x2, sctlr_el3 + b 0f +2: mrs x2, sctlr_el2 + b 0f +1: mrs x2, sctlr_el1 +0: + + /* Unset CR_M | CR_C | CR_I from SCTLR to disable all caches */ + movn x1, #(CR_M | CR_C | CR_I) + and x1, x2, x1 + switch_el x4, 3f, 2f, 1f +3: msr sctlr_el3, x1 + b 0f +2: msr sctlr_el2, x1 + b 0f +1: msr sctlr_el1, x1 +0: isb + + /* This call only clobbers x30 (lr) and x9 (unused) */ + mov x3, x30 + bl __asm_invalidate_tlb_all + + /* From here on we're running safely with caches disabled */ + + /* Set TTBR to our first argument */ + switch_el x4, 3f, 2f, 1f +3: msr ttbr0_el3, x0 + b 0f +2: msr ttbr0_el2, x0 + b 0f +1: msr ttbr0_el1, x0 +0: isb + + /* Restore original SCTLR and thus enable caches again */ + switch_el x4, 3f, 2f, 1f +3: msr sctlr_el3, x2 + b 0f +2: msr sctlr_el2, x2 + b 0f +1: msr sctlr_el1, x2 +0: isb + + ret x3 +ENDPROC(__asm_switch_ttbr) diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 71f0020c7f..d1bd06bedf 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -2,6 +2,9 @@ * (C) Copyright 2013 * David Feng <fenghua@phytium.com.cn> * + * (C) Copyright 2016 + * Alexander Graf <agraf@suse.de> + * * SPDX-License-Identifier: GPL-2.0+ */ @@ -13,137 +16,388 @@ DECLARE_GLOBAL_DATA_PTR; #ifndef CONFIG_SYS_DCACHE_OFF -#ifdef CONFIG_SYS_FULL_VA -static void set_ptl1_entry(u64 index, u64 ptl2_entry) +/* + * With 4k page granule, a virtual address is split into 4 lookup parts + * spanning 9 bits each: + * + * _______________________________________________ + * | | | | | | | + * | 0 | Lv0 | Lv1 | Lv2 | Lv3 | off | + * |_______|_______|_______|_______|_______|_______| + * 63-48 47-39 38-30 29-21 20-12 11-00 + * + * mask page size + * + * Lv0: FF8000000000 -- + * Lv1: 7FC0000000 1G + * Lv2: 3FE00000 2M + * Lv3: 1FF000 4K + * off: FFF + */ + +static u64 get_tcr(int el, u64 *pips, u64 *pva_bits) { - u64 *pgd = (u64 *)gd->arch.tlb_addr; - u64 value; + u64 max_addr = 0; + u64 ips, va_bits; + u64 tcr; + int i; + + /* Find the largest address we need to support */ + for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) + max_addr = max(max_addr, mem_map[i].base + mem_map[i].size); + + /* Calculate the maximum physical (and thus virtual) address */ + if (max_addr > (1ULL << 44)) { + ips = 5; + va_bits = 48; + } else if (max_addr > (1ULL << 42)) { + ips = 4; + va_bits = 44; + } else if (max_addr > (1ULL << 40)) { + ips = 3; + va_bits = 42; + } else if (max_addr > (1ULL << 36)) { + ips = 2; + va_bits = 40; + } else if (max_addr > (1ULL << 32)) { + ips = 1; + va_bits = 36; + } else { + ips = 0; + va_bits = 32; + } + + if (el == 1) { + tcr = TCR_EL1_RSVD | (ips << 32) | TCR_EPD1_DISABLE; + } else if (el == 2) { + tcr = TCR_EL2_RSVD | (ips << 16); + } else { + tcr = TCR_EL3_RSVD | (ips << 16); + } - value = ptl2_entry | PTL1_TYPE_TABLE; - pgd[index] = value; + /* PTWs cacheable, inner/outer WBWA and inner shareable */ + tcr |= TCR_TG0_4K | TCR_SHARED_INNER | TCR_ORGN_WBWA | TCR_IRGN_WBWA; + tcr |= TCR_T0SZ(va_bits); + + if (pips) + *pips = ips; + if (pva_bits) + *pva_bits = va_bits; + + return tcr; } -static void set_ptl2_block(u64 ptl1, u64 bfn, u64 address, u64 memory_attrs) +#define MAX_PTE_ENTRIES 512 + +static int pte_type(u64 *pte) { - u64 *pmd = (u64 *)ptl1; - u64 value; + return *pte & PTE_TYPE_MASK; +} - value = address | PTL2_TYPE_BLOCK | PTL2_BLOCK_AF; - value |= memory_attrs; - pmd[bfn] = value; +/* Returns the LSB number for a PTE on level <level> */ +static int level2shift(int level) +{ + /* Page is 12 bits wide, every level translates 9 bits */ + return (12 + 9 * (3 - level)); } -static struct mm_region mem_map[] = CONFIG_SYS_MEM_MAP; +static u64 *find_pte(u64 addr, int level) +{ + int start_level = 0; + u64 *pte; + u64 idx; + u64 va_bits; + int i; + + debug("addr=%llx level=%d\n", addr, level); + + get_tcr(0, NULL, &va_bits); + if (va_bits < 39) + start_level = 1; + + if (level < start_level) + return NULL; + + /* Walk through all page table levels to find our PTE */ + pte = (u64*)gd->arch.tlb_addr; + for (i = start_level; i < 4; i++) { + idx = (addr >> level2shift(i)) & 0x1FF; + pte += idx; + debug("idx=%llx PTE %p at level %d: %llx\n", idx, pte, i, *pte); + + /* Found it */ + if (i == level) + return pte; + /* PTE is no table (either invalid or block), can't traverse */ + if (pte_type(pte) != PTE_TYPE_TABLE) + return NULL; + /* Off to the next level */ + pte = (u64*)(*pte & 0x0000fffffffff000ULL); + } -#define PTL1_ENTRIES CONFIG_SYS_PTL1_ENTRIES -#define PTL2_ENTRIES CONFIG_SYS_PTL2_ENTRIES + /* Should never reach here */ + return NULL; +} -static void setup_pgtables(void) +/* Returns and creates a new full table (512 entries) */ +static u64 *create_table(void) { - int l1_e, l2_e; - unsigned long pmd = 0; - unsigned long address; - - /* Setup the PMD pointers */ - for (l1_e = 0; l1_e < CONFIG_SYS_MEM_MAP_SIZE; l1_e++) { - gd->arch.pmd_addr[l1_e] = gd->arch.tlb_addr + - PTL1_ENTRIES * sizeof(u64); - gd->arch.pmd_addr[l1_e] += PTL2_ENTRIES * sizeof(u64) * l1_e; - gd->arch.pmd_addr[l1_e] = ALIGN(gd->arch.pmd_addr[l1_e], - 0x10000UL); + u64 *new_table = (u64*)gd->arch.tlb_fillptr; + u64 pt_len = MAX_PTE_ENTRIES * sizeof(u64); + + /* Allocate MAX_PTE_ENTRIES pte entries */ + gd->arch.tlb_fillptr += pt_len; + + if (gd->arch.tlb_fillptr - gd->arch.tlb_addr > gd->arch.tlb_size) + panic("Insufficient RAM for page table: 0x%lx > 0x%lx. " + "Please increase the size in get_page_table_size()", + gd->arch.tlb_fillptr - gd->arch.tlb_addr, + gd->arch.tlb_size); + + /* Mark all entries as invalid */ + memset(new_table, 0, pt_len); + + return new_table; +} + +static void set_pte_table(u64 *pte, u64 *table) +{ + /* Point *pte to the new table */ + debug("Setting %p to addr=%p\n", pte, table); + *pte = PTE_TYPE_TABLE | (ulong)table; +} + +/* Add one mm_region map entry to the page tables */ +static void add_map(struct mm_region *map) +{ + u64 *pte; + u64 addr = map->base; + u64 size = map->size; + u64 attrs = map->attrs | PTE_TYPE_BLOCK | PTE_BLOCK_AF; + u64 blocksize; + int level; + u64 *new_table; + + while (size) { + pte = find_pte(addr, 0); + if (pte && (pte_type(pte) == PTE_TYPE_FAULT)) { + debug("Creating table for addr 0x%llx\n", addr); + new_table = create_table(); + set_pte_table(pte, new_table); + } + + for (level = 1; level < 4; level++) { + pte = find_pte(addr, level); + blocksize = 1ULL << level2shift(level); + debug("Checking if pte fits for addr=%llx size=%llx " + "blocksize=%llx\n", addr, size, blocksize); + if (size >= blocksize && !(addr & (blocksize - 1))) { + /* Page fits, create block PTE */ + debug("Setting PTE %p to block addr=%llx\n", + pte, addr); + *pte = addr | attrs; + addr += blocksize; + size -= blocksize; + break; + } else if ((pte_type(pte) == PTE_TYPE_FAULT)) { + /* Page doesn't fit, create subpages */ + debug("Creating subtable for addr 0x%llx " + "blksize=%llx\n", addr, blocksize); + new_table = create_table(); + set_pte_table(pte, new_table); + } + } + } +} + +/* Splits a block PTE into table with subpages spanning the old block */ +static void split_block(u64 *pte, int level) +{ + u64 old_pte = *pte; + u64 *new_table; + u64 i = 0; + /* level describes the parent level, we need the child ones */ + int levelshift = level2shift(level + 1); + + if (pte_type(pte) != PTE_TYPE_BLOCK) + panic("PTE %p (%llx) is not a block. Some driver code wants to " + "modify dcache settings for an range not covered in " + "mem_map.", pte, old_pte); + + new_table = create_table(); + debug("Splitting pte %p (%llx) into %p\n", pte, old_pte, new_table); + + for (i = 0; i < MAX_PTE_ENTRIES; i++) { + new_table[i] = old_pte | (i << levelshift); + + /* Level 3 block PTEs have the table type */ + if ((level + 1) == 3) + new_table[i] |= PTE_TYPE_TABLE; + + debug("Setting new_table[%lld] = %llx\n", i, new_table[i]); } - /* Setup the page tables */ - for (l1_e = 0; l1_e < PTL1_ENTRIES; l1_e++) { - if (mem_map[pmd].base == - (uintptr_t)l1_e << PTL2_BITS) { - set_ptl1_entry(l1_e, gd->arch.pmd_addr[pmd]); - - for (l2_e = 0; l2_e < PTL2_ENTRIES; l2_e++) { - address = mem_map[pmd].base - + (uintptr_t)l2_e * BLOCK_SIZE; - set_ptl2_block(gd->arch.pmd_addr[pmd], l2_e, - address, mem_map[pmd].attrs); + /* Set the new table into effect */ + set_pte_table(pte, new_table); +} + +enum pte_type { + PTE_INVAL, + PTE_BLOCK, + PTE_LEVEL, +}; + +/* + * This is a recursively called function to count the number of + * page tables we need to cover a particular PTE range. If you + * call this with level = -1 you basically get the full 48 bit + * coverage. + */ +static int count_required_pts(u64 addr, int level, u64 maxaddr) +{ + int levelshift = level2shift(level); + u64 levelsize = 1ULL << levelshift; + u64 levelmask = levelsize - 1; + u64 levelend = addr + levelsize; + int r = 0; + int i; + enum pte_type pte_type = PTE_INVAL; + + for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) { + struct mm_region *map = &mem_map[i]; + u64 start = map->base; + u64 end = start + map->size; + + /* Check if the PTE would overlap with the map */ + if (max(addr, start) <= min(levelend, end)) { + start = max(addr, start); + end = min(levelend, end); + + /* We need a sub-pt for this level */ + if ((start & levelmask) || (end & levelmask)) { + pte_type = PTE_LEVEL; + break; } - pmd++; - } else { - set_ptl1_entry(l1_e, 0); + /* Lv0 can not do block PTEs, so do levels here too */ + if (level <= 0) { + pte_type = PTE_LEVEL; + break; + } + + /* PTE is active, but fits into a block */ + pte_type = PTE_BLOCK; } } + + /* + * Block PTEs at this level are already covered by the parent page + * table, so we only need to count sub page tables. + */ + if (pte_type == PTE_LEVEL) { + int sublevel = level + 1; + u64 sublevelsize = 1ULL << level2shift(sublevel); + + /* Account for the new sub page table ... */ + r = 1; + + /* ... and for all child page tables that one might have */ + for (i = 0; i < MAX_PTE_ENTRIES; i++) { + r += count_required_pts(addr, sublevel, maxaddr); + addr += sublevelsize; + + if (addr >= maxaddr) { + /* + * We reached the end of address space, no need + * to look any further. + */ + break; + } + } + } + + return r; } -#else +/* Returns the estimated required size of all page tables */ +u64 get_page_table_size(void) +{ + u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64); + u64 size = 0; + u64 va_bits; + int start_level = 0; + + get_tcr(0, NULL, &va_bits); + if (va_bits < 39) + start_level = 1; + + /* Account for all page tables we would need to cover our memory map */ + size = one_pt * count_required_pts(0, start_level - 1, 1ULL << va_bits); + + /* + * We need to duplicate our page table once to have an emergency pt to + * resort to when splitting page tables later on + */ + size *= 2; + + /* + * We may need to split page tables later on if dcache settings change, + * so reserve up to 4 (random pick) page tables for that. + */ + size += one_pt * 4; + + return size; +} -inline void set_pgtable_section(u64 *page_table, u64 index, u64 section, - u64 memory_type, u64 attribute) +static void setup_pgtables(void) { - u64 value; + int i; - value = section | PMD_TYPE_SECT | PMD_SECT_AF; - value |= PMD_ATTRINDX(memory_type); - value |= attribute; - page_table[index] = value; + /* + * Allocate the first level we're on with invalidate entries. + * If the starting level is 0 (va_bits >= 39), then this is our + * Lv0 page table, otherwise it's the entry Lv1 page table. + */ + create_table(); + + /* Now add all MMU table entries one after another to the table */ + for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) + add_map(&mem_map[i]); + + /* Create the same thing once more for our emergency page table */ + create_table(); } -inline void set_pgtable_table(u64 *page_table, u64 index, u64 *table_addr) +static void setup_all_pgtables(void) { - u64 value; + u64 tlb_addr = gd->arch.tlb_addr; + + /* Reset the fill ptr */ + gd->arch.tlb_fillptr = tlb_addr; - value = (u64)table_addr | PMD_TYPE_TABLE; - page_table[index] = value; + /* Create normal system page tables */ + setup_pgtables(); + + /* Create emergency page tables */ + gd->arch.tlb_addr = gd->arch.tlb_fillptr; + setup_pgtables(); + gd->arch.tlb_emerg = gd->arch.tlb_addr; + gd->arch.tlb_addr = tlb_addr; } -#endif /* to activate the MMU we need to set up virtual memory */ __weak void mmu_setup(void) { -#ifndef CONFIG_SYS_FULL_VA - bd_t *bd = gd->bd; - u64 *page_table = (u64 *)gd->arch.tlb_addr, i, j; -#endif int el; -#ifdef CONFIG_SYS_FULL_VA - unsigned long coreid = read_mpidr() & CONFIG_COREID_MASK; - - /* Set up page tables only on BSP */ - if (coreid == BSP_COREID) - setup_pgtables(); -#else - /* Setup an identity-mapping for all spaces */ - for (i = 0; i < (PGTABLE_SIZE >> 3); i++) { - set_pgtable_section(page_table, i, i << SECTION_SHIFT, - MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE); - } - - /* Setup an identity-mapping for all RAM space */ - for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { - ulong start = bd->bi_dram[i].start; - ulong end = bd->bi_dram[i].start + bd->bi_dram[i].size; - for (j = start >> SECTION_SHIFT; - j < end >> SECTION_SHIFT; j++) { - set_pgtable_section(page_table, j, j << SECTION_SHIFT, - MT_NORMAL, PMD_SECT_NON_SHARE); - } - } + /* Set up page tables only once */ + if (!gd->arch.tlb_fillptr) + setup_all_pgtables(); -#endif - /* load TTBR0 */ el = current_el(); - if (el == 1) { - set_ttbr_tcr_mair(el, gd->arch.tlb_addr, - TCR_EL1_RSVD | TCR_FLAGS | TCR_EL1_IPS_BITS, - MEMORY_ATTRIBUTES); - } else if (el == 2) { - set_ttbr_tcr_mair(el, gd->arch.tlb_addr, - TCR_EL2_RSVD | TCR_FLAGS | TCR_EL2_IPS_BITS, - MEMORY_ATTRIBUTES); - } else { - set_ttbr_tcr_mair(el, gd->arch.tlb_addr, - TCR_EL3_RSVD | TCR_FLAGS | TCR_EL3_IPS_BITS, - MEMORY_ATTRIBUTES); - } + set_ttbr_tcr_mair(el, gd->arch.tlb_addr, get_tcr(el, NULL, NULL), + MEMORY_ATTRIBUTES); + /* enable the mmu */ set_sctlr(get_sctlr() | CR_M); } @@ -228,36 +482,99 @@ u64 *__weak arch_get_page_table(void) { return NULL; } -#ifndef CONFIG_SYS_FULL_VA +static bool is_aligned(u64 addr, u64 size, u64 align) +{ + return !(addr & (align - 1)) && !(size & (align - 1)); +} + +static u64 set_one_region(u64 start, u64 size, u64 attrs, int level) +{ + int levelshift = level2shift(level); + u64 levelsize = 1ULL << levelshift; + u64 *pte = find_pte(start, level); + + /* Can we can just modify the current level block PTE? */ + if (is_aligned(start, size, levelsize)) { + *pte &= ~PMD_ATTRINDX_MASK; + *pte |= attrs; + debug("Set attrs=%llx pte=%p level=%d\n", attrs, pte, level); + + return levelsize; + } + + /* Unaligned or doesn't fit, maybe split block into table */ + debug("addr=%llx level=%d pte=%p (%llx)\n", start, level, pte, *pte); + + /* Maybe we need to split the block into a table */ + if (pte_type(pte) == PTE_TYPE_BLOCK) + split_block(pte, level); + + /* And then double-check it became a table or already is one */ + if (pte_type(pte) != PTE_TYPE_TABLE) + panic("PTE %p (%llx) for addr=%llx should be a table", + pte, *pte, start); + + /* Roll on to the next page table level */ + return 0; +} + void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size, enum dcache_option option) { - u64 *page_table = arch_get_page_table(); - u64 upto, end; - - if (page_table == NULL) - return; + u64 attrs = PMD_ATTRINDX(option); + u64 real_start = start; + u64 real_size = size; + + debug("start=%lx size=%lx\n", (ulong)start, (ulong)size); + + /* + * We can not modify page tables that we're currently running on, + * so we first need to switch to the "emergency" page tables where + * we can safely modify our primary page tables and then switch back + */ + __asm_switch_ttbr(gd->arch.tlb_emerg); + + /* + * Loop through the address range until we find a page granule that fits + * our alignment constraints, then set it to the new cache attributes + */ + while (size > 0) { + int level; + u64 r; + + for (level = 1; level < 4; level++) { + r = set_one_region(start, size, attrs, level); + if (r) { + /* PTE successfully replaced */ + size -= r; + start += r; + break; + } + } - end = ALIGN(start + size, (1 << MMU_SECTION_SHIFT)) >> - MMU_SECTION_SHIFT; - start = start >> MMU_SECTION_SHIFT; - for (upto = start; upto < end; upto++) { - page_table[upto] &= ~PMD_ATTRINDX_MASK; - page_table[upto] |= PMD_ATTRINDX(option); } - asm volatile("dsb sy"); - __asm_invalidate_tlb_all(); - asm volatile("dsb sy"); - asm volatile("isb"); - start = start << MMU_SECTION_SHIFT; - end = end << MMU_SECTION_SHIFT; - flush_dcache_range(start, end); - asm volatile("dsb sy"); + + /* We're done modifying page tables, switch back to our primary ones */ + __asm_switch_ttbr(gd->arch.tlb_addr); + + /* + * Make sure there's nothing stale in dcache for a region that might + * have caches off now + */ + flush_dcache_range(real_start, real_start + real_size); } -#endif #else /* CONFIG_SYS_DCACHE_OFF */ +/* + * For SPL builds, we may want to not have dcache enabled. Any real U-Boot + * running however really wants to have dcache and the MMU active. Check that + * everything is sane and give the developer a hint if it isn't. + */ +#ifndef CONFIG_SPL_BUILD +#error Please describe your MMU layout in CONFIG_SYS_MEM_MAP and enable dcache. +#endif + void invalidate_dcache_all(void) { } diff --git a/arch/arm/cpu/armv8/exceptions.S b/arch/arm/cpu/armv8/exceptions.S index baf9401e64..4f4f526f93 100644 --- a/arch/arm/cpu/armv8/exceptions.S +++ b/arch/arm/cpu/armv8/exceptions.S @@ -82,31 +82,65 @@ vectors: _do_bad_sync: exception_entry bl do_bad_sync + b exception_exit _do_bad_irq: exception_entry bl do_bad_irq + b exception_exit _do_bad_fiq: exception_entry bl do_bad_fiq + b exception_exit _do_bad_error: exception_entry bl do_bad_error + b exception_exit _do_sync: exception_entry bl do_sync + b exception_exit _do_irq: exception_entry bl do_irq + b exception_exit _do_fiq: exception_entry bl do_fiq + b exception_exit _do_error: exception_entry bl do_error + b exception_exit + +exception_exit: + ldp x2, x0, [sp],#16 + switch_el x11, 3f, 2f, 1f +3: msr elr_el3, x2 + b 0f +2: msr elr_el2, x2 + b 0f +1: msr elr_el1, x2 +0: + ldp x1, x2, [sp],#16 + ldp x3, x4, [sp],#16 + ldp x5, x6, [sp],#16 + ldp x7, x8, [sp],#16 + ldp x9, x10, [sp],#16 + ldp x11, x12, [sp],#16 + ldp x13, x14, [sp],#16 + ldp x15, x16, [sp],#16 + ldp x17, x18, [sp],#16 + ldp x19, x20, [sp],#16 + ldp x21, x22, [sp],#16 + ldp x23, x24, [sp],#16 + ldp x25, x26, [sp],#16 + ldp x27, x28, [sp],#16 + ldp x29, x30, [sp],#16 + eret diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index 6ea28ed5cb..7404bd932a 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -26,6 +26,14 @@ DECLARE_GLOBAL_DATA_PTR; +static struct mm_region layerscape_mem_map[] = { + { + /* List terminator */ + 0, + } +}; +struct mm_region *mem_map = layerscape_mem_map; + void cpu_name(char *name) { struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); @@ -48,6 +56,25 @@ void cpu_name(char *name) } #ifndef CONFIG_SYS_DCACHE_OFF +static void set_pgtable_section(u64 *page_table, u64 index, u64 section, + u64 memory_type, u64 attribute) +{ + u64 value; + + value = section | PTE_TYPE_BLOCK | PTE_BLOCK_AF; + value |= PMD_ATTRINDX(memory_type); + value |= attribute; + page_table[index] = value; +} + +static void set_pgtable_table(u64 *page_table, u64 index, u64 *table_addr) +{ + u64 value; + + value = (u64)table_addr | PTE_TYPE_TABLE; + page_table[index] = value; +} + /* * Set the block entries according to the information of the table. */ @@ -114,10 +141,10 @@ static int find_table(const struct sys_mmu_table *list, temp_base -= block_size; - if ((level_table[index - 1] & PMD_TYPE_MASK) == - PMD_TYPE_TABLE) { + if ((level_table[index - 1] & PTE_TYPE_MASK) == + PTE_TYPE_TABLE) { level_table = (u64 *)(level_table[index - 1] & - ~PMD_TYPE_MASK); + ~PTE_TYPE_MASK); level++; continue; } else { @@ -220,7 +247,7 @@ static inline int final_secure_ddr(u64 *level0_table, struct table_info table = {}; struct sys_mmu_table ddr_entry = { 0, 0, BLOCK_SIZE_L1, MT_NORMAL, - PMD_SECT_OUTER_SHARE | PMD_SECT_NS + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }; u64 index; @@ -243,7 +270,7 @@ static inline int final_secure_ddr(u64 *level0_table, ddr_entry.virt_addr = phys_addr; ddr_entry.phys_addr = phys_addr; ddr_entry.size = CONFIG_SYS_MEM_RESERVE_SECURE; - ddr_entry.attribute = PMD_SECT_OUTER_SHARE; + ddr_entry.attribute = PTE_BLOCK_OUTER_SHARE; ret = find_table(&ddr_entry, &table, level0_table); if (ret) { printf("MMU error: could not find secure ddr table\n"); diff --git a/arch/arm/cpu/armv8/u-boot-spl.lds b/arch/arm/cpu/armv8/u-boot-spl.lds index 4df339c84a..cc427c3583 100644 --- a/arch/arm/cpu/armv8/u-boot-spl.lds +++ b/arch/arm/cpu/armv8/u-boot-spl.lds @@ -54,6 +54,8 @@ SECTIONS *(.__end) } >.sram + _image_binary_end = .; + .bss_start : { . = ALIGN(8); KEEP(*(.__bss_start)); diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds index 4c12222370..fd15ad5963 100644 --- a/arch/arm/cpu/armv8/u-boot.lds +++ b/arch/arm/cpu/armv8/u-boot.lds @@ -42,6 +42,22 @@ SECTIONS . = ALIGN(8); + .efi_runtime : { + __efi_runtime_start = .; + *(efi_runtime_text) + *(efi_runtime_data) + __efi_runtime_stop = .; + } + + .efi_runtime_rel : { + __efi_runtime_rel_start = .; + *(.relaefi_runtime_text) + *(.relaefi_runtime_data) + __efi_runtime_rel_stop = .; + } + + . = ALIGN(8); + .image_copy_end : { *(.__image_copy_end) diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c index c71f29152d..5dd3cd86cf 100644 --- a/arch/arm/cpu/armv8/zynqmp/cpu.c +++ b/arch/arm/cpu/armv8/zynqmp/cpu.c @@ -8,6 +8,7 @@ #include <common.h> #include <asm/arch/hardware.h> #include <asm/arch/sys_proto.h> +#include <asm/armv8/mmu.h> #include <asm/io.h> #define ZYNQ_SILICON_VER_MASK 0xF000 @@ -15,6 +16,53 @@ DECLARE_GLOBAL_DATA_PTR; +static struct mm_region zynqmp_mem_map[] = { + { + .base = 0x0UL, + .size = 0x80000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + .base = 0x80000000UL, + .size = 0x70000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .base = 0xf8000000UL, + .size = 0x07e00000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .base = 0xffe00000UL, + .size = 0x00200000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + .base = 0x400000000UL, + .size = 0x200000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .base = 0x600000000UL, + .size = 0x800000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + .base = 0xe00000000UL, + .size = 0xf200000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* List terminator */ + 0, + } +}; +struct mm_region *mem_map = zynqmp_mem_map; + static unsigned int zynqmp_get_silicon_version_secure(void) { u32 ver; @@ -44,172 +92,3 @@ unsigned int zynqmp_get_silicon_version(void) return ZYNQMP_CSU_VERSION_SILICON; } - -#ifndef CONFIG_SYS_DCACHE_OFF -#include <asm/armv8/mmu.h> - -#define SECTION_SHIFT_L1 30UL -#define SECTION_SHIFT_L2 21UL -#define BLOCK_SIZE_L0 0x8000000000UL -#define BLOCK_SIZE_L1 (1 << SECTION_SHIFT_L1) -#define BLOCK_SIZE_L2 (1 << SECTION_SHIFT_L2) - -#define TCR_TG1_4K (1 << 31) -#define TCR_EPD1_DISABLE (1 << 23) -#define ZYNQMO_VA_BITS 40 -#define ZYNQMP_TCR TCR_TG1_4K | \ - TCR_EPD1_DISABLE | \ - TCR_SHARED_OUTER | \ - TCR_SHARED_INNER | \ - TCR_IRGN_WBWA | \ - TCR_ORGN_WBWA | \ - TCR_T0SZ(ZYNQMO_VA_BITS) - -#define MEMORY_ATTR PMD_SECT_AF | PMD_SECT_INNER_SHARE | \ - PMD_ATTRINDX(MT_NORMAL) | \ - PMD_TYPE_SECT -#define DEVICE_ATTR PMD_SECT_AF | PMD_SECT_PXN | \ - PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_NGNRNE) | \ - PMD_TYPE_SECT - -/* 4K size is required to place 512 entries in each level */ -#define TLB_TABLE_SIZE 0x1000 - -struct attr_tbl { - u32 num; - u64 attr; -}; - -static struct attr_tbl attr_tbll1t0[4] = { {16, 0x0}, - {8, DEVICE_ATTR}, - {32, MEMORY_ATTR}, - {456, DEVICE_ATTR} - }; -static struct attr_tbl attr_tbll2t3[4] = { {0x180, DEVICE_ATTR}, - {0x40, 0x0}, - {0x3F, DEVICE_ATTR}, - {0x1, MEMORY_ATTR} - }; - -/* - * This mmu table looks as below - * Level 0 table contains two entries to 512GB sizes. One is Level1 Table 0 - * and other Level1 Table1. - * Level1 Table0 contains entries for each 1GB from 0 to 511GB. - * Level1 Table1 contains entries for each 1GB from 512GB to 1TB. - * Level2 Table0, Level2 Table1, Level2 Table2 and Level2 Table3 contains - * entries for each 2MB starting from 0GB, 1GB, 2GB and 3GB respectively. - */ -static void zynqmp_mmu_setup(void) -{ - int el; - u32 index_attr; - u64 i, section_l1t0, section_l1t1; - u64 section_l2t0, section_l2t1, section_l2t2, section_l2t3; - u64 *level0_table = (u64 *)gd->arch.tlb_addr; - u64 *level1_table_0 = (u64 *)(gd->arch.tlb_addr + TLB_TABLE_SIZE); - u64 *level1_table_1 = (u64 *)(gd->arch.tlb_addr + (2 * TLB_TABLE_SIZE)); - u64 *level2_table_0 = (u64 *)(gd->arch.tlb_addr + (3 * TLB_TABLE_SIZE)); - u64 *level2_table_1 = (u64 *)(gd->arch.tlb_addr + (4 * TLB_TABLE_SIZE)); - u64 *level2_table_2 = (u64 *)(gd->arch.tlb_addr + (5 * TLB_TABLE_SIZE)); - u64 *level2_table_3 = (u64 *)(gd->arch.tlb_addr + (6 * TLB_TABLE_SIZE)); - - level0_table[0] = - (u64)level1_table_0 | PMD_TYPE_TABLE; - level0_table[1] = - (u64)level1_table_1 | PMD_TYPE_TABLE; - - /* - * set level 1 table 0, covering 0 to 512GB - * set level 1 table 1, covering 512GB to 1TB - */ - section_l1t0 = 0; - section_l1t1 = BLOCK_SIZE_L0; - - index_attr = 0; - for (i = 0; i < 512; i++) { - level1_table_0[i] = section_l1t0; - level1_table_0[i] |= attr_tbll1t0[index_attr].attr; - attr_tbll1t0[index_attr].num--; - if (attr_tbll1t0[index_attr].num == 0) - index_attr++; - level1_table_1[i] = section_l1t1; - level1_table_1[i] |= DEVICE_ATTR; - section_l1t0 += BLOCK_SIZE_L1; - section_l1t1 += BLOCK_SIZE_L1; - } - - level1_table_0[0] = - (u64)level2_table_0 | PMD_TYPE_TABLE; - level1_table_0[1] = - (u64)level2_table_1 | PMD_TYPE_TABLE; - level1_table_0[2] = - (u64)level2_table_2 | PMD_TYPE_TABLE; - level1_table_0[3] = - (u64)level2_table_3 | PMD_TYPE_TABLE; - - section_l2t0 = 0; - section_l2t1 = section_l2t0 + BLOCK_SIZE_L1; /* 1GB */ - section_l2t2 = section_l2t1 + BLOCK_SIZE_L1; /* 2GB */ - section_l2t3 = section_l2t2 + BLOCK_SIZE_L1; /* 3GB */ - - index_attr = 0; - - for (i = 0; i < 512; i++) { - level2_table_0[i] = section_l2t0 | MEMORY_ATTR; - level2_table_1[i] = section_l2t1 | MEMORY_ATTR; - level2_table_2[i] = section_l2t2 | DEVICE_ATTR; - level2_table_3[i] = section_l2t3 | - attr_tbll2t3[index_attr].attr; - attr_tbll2t3[index_attr].num--; - if (attr_tbll2t3[index_attr].num == 0) - index_attr++; - section_l2t0 += BLOCK_SIZE_L2; - section_l2t1 += BLOCK_SIZE_L2; - section_l2t2 += BLOCK_SIZE_L2; - section_l2t3 += BLOCK_SIZE_L2; - } - - /* flush new MMU table */ - flush_dcache_range(gd->arch.tlb_addr, - gd->arch.tlb_addr + gd->arch.tlb_size); - - /* point TTBR to the new table */ - el = current_el(); - set_ttbr_tcr_mair(el, gd->arch.tlb_addr, - ZYNQMP_TCR, MEMORY_ATTRIBUTES); - - set_sctlr(get_sctlr() | CR_M); -} - -int arch_cpu_init(void) -{ - icache_enable(); - __asm_invalidate_dcache_all(); - __asm_invalidate_tlb_all(); - return 0; -} - -/* - * This function is called from lib/board.c. - * It recreates MMU table in main memory. MMU and d-cache are enabled earlier. - * There is no need to disable d-cache for this operation. - */ -void enable_caches(void) -{ - /* The data cache is not active unless the mmu is enabled */ - if (!(get_sctlr() & CR_M)) { - invalidate_dcache_all(); - __asm_invalidate_tlb_all(); - zynqmp_mmu_setup(); - } - puts("Enabling Caches...\n"); - - set_sctlr(get_sctlr() | CR_C); -} - -u64 *arch_get_page_table(void) -{ - return (u64 *)(gd->arch.tlb_addr + 0x3000); -} -#endif diff --git a/arch/arm/cpu/u-boot-spl.lds b/arch/arm/cpu/u-boot-spl.lds index c5b4f7ce5e..068163b73a 100644 --- a/arch/arm/cpu/u-boot-spl.lds +++ b/arch/arm/cpu/u-boot-spl.lds @@ -32,15 +32,8 @@ SECTIONS } . = ALIGN(4); -#ifdef CONFIG_SPL_DM .u_boot_list : { - KEEP(*(SORT(.u_boot_list_*_driver_*))); - KEEP(*(SORT(.u_boot_list_*_uclass_*))); - } -#endif - . = .; - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*_i2c_*))); + KEEP(*(SORT(.u_boot_list*))); } . = ALIGN(4); diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index e148ab7513..13aa4fa488 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -90,6 +90,36 @@ SECTIONS . = ALIGN(4); + .__efi_runtime_start : { + *(.__efi_runtime_start) + } + + .efi_runtime : { + *(efi_runtime_text) + *(efi_runtime_data) + } + + .__efi_runtime_stop : { + *(.__efi_runtime_stop) + } + + .efi_runtime_rel_start : + { + *(.__efi_runtime_rel_start) + } + + .efi_runtime_rel : { + *(.relefi_runtime_text) + *(.relefi_runtime_data) + } + + .efi_runtime_rel_stop : + { + *(.__efi_runtime_rel_stop) + } + + . = ALIGN(4); + .image_copy_end : { *(.__image_copy_end) diff --git a/arch/arm/dts/exynos4210-pinctrl-uboot.dtsi b/arch/arm/dts/exynos4210-pinctrl-uboot.dtsi index 0ff41d0028..b76c77d719 100644 --- a/arch/arm/dts/exynos4210-pinctrl-uboot.dtsi +++ b/arch/arm/dts/exynos4210-pinctrl-uboot.dtsi @@ -9,21 +9,21 @@ /{ pinctrl_0: pinctrl@11400000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; compatible = "samsung,exynos4210-pinctrl"; }; pinctrl_1: pinctrl@11000000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; gpx0: gpx0 { - reg = <0xc00>; + reg = <0xc00 0x20>; }; }; pinctrl_2: pinctrl@03860000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; }; }; diff --git a/arch/arm/dts/exynos4x12-pinctrl-uboot.dtsi b/arch/arm/dts/exynos4x12-pinctrl-uboot.dtsi index 8e5a6c6118..33ecc148a7 100644 --- a/arch/arm/dts/exynos4x12-pinctrl-uboot.dtsi +++ b/arch/arm/dts/exynos4x12-pinctrl-uboot.dtsi @@ -9,37 +9,37 @@ /{ pinctrl_0: pinctrl@11400000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; gpf0: gpf0 { - reg = <0x180>; + reg = <0x180 0x20>; }; gpj0: gpj0 { - reg = <0x240>; + reg = <0x240 0x20>; }; }; pinctrl_1: pinctrl@11000000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; gpk0: gpk0 { - reg = <0x40>; + reg = <0x40 0x20>; }; gpm0: gpm0 { - reg = <0x260>; + reg = <0x260 0x20>; }; gpx0: gpx0 { - reg = <0xc00>; + reg = <0xc00 0x20>; }; }; pinctrl_2: pinctrl@03860000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; }; pinctrl_3: pinctrl@106E0000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; }; }; diff --git a/arch/arm/dts/exynos5250-pinctrl-uboot.dtsi b/arch/arm/dts/exynos5250-pinctrl-uboot.dtsi index 068c5f696f..b8c0526def 100644 --- a/arch/arm/dts/exynos5250-pinctrl-uboot.dtsi +++ b/arch/arm/dts/exynos5250-pinctrl-uboot.dtsi @@ -9,34 +9,34 @@ /{ pinctrl_0: pinctrl@11400000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; gpc4: gpc4 { - reg = <0x2e0>; + reg = <0x2e0 0x20>; }; gpx0: gpx0 { - reg = <0xc00>; + reg = <0xc00 0x20>; }; }; pinctrl_1: pinctrl@13400000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; }; pinctrl_2: pinctrl@10d10000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; gpv2: gpv2 { - reg = <0x060>; + reg = <0x060 0x20>; }; gpv4: gpv4 { - reg = <0xc0>; + reg = <0xc0 0x20>; }; }; pinctrl_3: pinctrl@03860000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; }; }; diff --git a/arch/arm/dts/exynos54xx-pinctrl-uboot.dtsi b/arch/arm/dts/exynos54xx-pinctrl-uboot.dtsi index 635a1b0d3a..341194f5a7 100644 --- a/arch/arm/dts/exynos54xx-pinctrl-uboot.dtsi +++ b/arch/arm/dts/exynos54xx-pinctrl-uboot.dtsi @@ -14,29 +14,29 @@ */ pinctrl@14010000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; }; pinctrl@13400000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; gpy7 { }; gpx0 { - reg = <0xc00>; + reg = <0xc00 0x0>; }; }; pinctrl@13410000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; }; pinctrl@14000000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; }; pinctrl@03860000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; }; }; diff --git a/arch/arm/dts/k2g.dtsi b/arch/arm/dts/k2g.dtsi index bbc2cf91b9..a3ed444d3c 100644 --- a/arch/arm/dts/k2g.dtsi +++ b/arch/arm/dts/k2g.dtsi @@ -81,5 +81,12 @@ }; #include "k2g-netcp.dtsi" + + pmmc: pmmc@2900000 { + compatible = "ti,power-processor"; + reg = <0x02900000 0x40000>; + ti,lpsc_module = <1>; + }; + }; }; diff --git a/arch/arm/dts/rk3288.dtsi b/arch/arm/dts/rk3288.dtsi index e51c75c150..3dab0fc83e 100644 --- a/arch/arm/dts/rk3288.dtsi +++ b/arch/arm/dts/rk3288.dtsi @@ -9,6 +9,7 @@ #include <dt-bindings/clock/rk3288-cru.h> #include <dt-bindings/power-domain/rk3288.h> #include <dt-bindings/thermal/thermal.h> +#include <dt-bindings/video/rk3288.h> #include "skeleton.dtsi" / { @@ -683,6 +684,10 @@ reg = <1>; remote-endpoint = <&hdmi_in_vopb>; }; + vopb_out_lvds: endpoint@2 { + reg = <2>; + remote-endpoint = <&lvds_in_vopb>; + }; }; }; @@ -719,7 +724,10 @@ reg = <1>; remote-endpoint = <&hdmi_in_vopl>; }; - + vopl_out_lvds: endpoint@2 { + reg = <2>; + remote-endpoint = <&lvds_in_vopl>; + }; }; }; @@ -786,6 +794,34 @@ }; }; + lvds: lvds@ff96c000 { + compatible = "rockchip,rk3288-lvds"; + reg = <0xff96c000 0x4000>; + clocks = <&cru PCLK_LVDS_PHY>; + clock-names = "pclk_lvds"; + pinctrl-names = "default"; + pinctrl-0 = <&lcdc0_ctl>; + rockchip,grf = <&grf>; + status = "disabled"; + ports { + #address-cells = <1>; + #size-cells = <0>; + lvds_in: port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + lvds_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_lvds>; + }; + lvds_in_vopl: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_lvds>; + }; + }; + }; + }; + hdmi_audio: hdmi_audio { compatible = "rockchip,rk3288-hdmi-audio"; i2s-controller = <&i2s>; @@ -1109,6 +1145,15 @@ }; }; + lcdc0 { + lcdc0_ctl: lcdc0-ctl { + rockchip,pins = <1 24 RK_FUNC_1 &pcfg_pull_none>, + <1 25 RK_FUNC_1 &pcfg_pull_none>, + <1 26 RK_FUNC_1 &pcfg_pull_none>, + <1 27 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + sdmmc { sdmmc_clk: sdmmc-clk { rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none>; diff --git a/arch/arm/dts/s5pc110-pinctrl.dtsi b/arch/arm/dts/s5pc110-pinctrl.dtsi index 2e9d552daa..07e76c0985 100644 --- a/arch/arm/dts/s5pc110-pinctrl.dtsi +++ b/arch/arm/dts/s5pc110-pinctrl.dtsi @@ -9,7 +9,7 @@ / { pinctrl@e0200000 { #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; gpa0: gpa0 { gpio-controller; #gpio-cells = <2>; @@ -251,7 +251,7 @@ }; gph0: gph0 { - reg = <0xc00>; + reg = <0xc00 0x20>; gpio-controller; #gpio-cells = <2>; }; diff --git a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h index 15ade84c48..93bbda3324 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/cpu.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/cpu.h @@ -117,48 +117,48 @@ static const struct sys_mmu_table early_mmu_table[] = { #ifdef CONFIG_FSL_LSCH3 { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE, - CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PMD_SECT_NON_SHARE }, + CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE }, /* For IFC Region #1, only the first 4MB is cache-enabled */ { CONFIG_SYS_FSL_IFC_BASE1, CONFIG_SYS_FSL_IFC_BASE1, - CONFIG_SYS_FSL_IFC_SIZE1_1, MT_NORMAL, PMD_SECT_NON_SHARE }, + CONFIG_SYS_FSL_IFC_SIZE1_1, MT_NORMAL, PTE_BLOCK_NON_SHARE }, { CONFIG_SYS_FSL_IFC_BASE1 + CONFIG_SYS_FSL_IFC_SIZE1_1, CONFIG_SYS_FSL_IFC_BASE1 + CONFIG_SYS_FSL_IFC_SIZE1_1, CONFIG_SYS_FSL_IFC_SIZE1 - CONFIG_SYS_FSL_IFC_SIZE1_1, - MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE }, + MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, { CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FSL_IFC_BASE1, - CONFIG_SYS_FSL_IFC_SIZE1, MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE }, + CONFIG_SYS_FSL_IFC_SIZE1, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, - PMD_SECT_OUTER_SHARE | PMD_SECT_NS }, + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, /* Map IFC region #2 up to CONFIG_SYS_FLASH_BASE for NAND boot */ { CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FLASH_BASE - CONFIG_SYS_FSL_IFC_BASE2, - MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE }, + MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, { CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, - PMD_SECT_OUTER_SHARE | PMD_SECT_NS }, + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, #elif defined(CONFIG_FSL_LSCH2) { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE, - CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PMD_SECT_NON_SHARE }, + CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE }, { CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_QSPI_BASE, CONFIG_SYS_FSL_QSPI_BASE, - CONFIG_SYS_FSL_QSPI_SIZE, MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE }, + CONFIG_SYS_FSL_QSPI_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, { CONFIG_SYS_FSL_IFC_BASE, CONFIG_SYS_FSL_IFC_BASE, - CONFIG_SYS_FSL_IFC_SIZE, MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE }, + CONFIG_SYS_FSL_IFC_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1, - CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, PMD_SECT_OUTER_SHARE }, + CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, PTE_BLOCK_OUTER_SHARE }, { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2, - CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, PMD_SECT_OUTER_SHARE }, + CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, PTE_BLOCK_OUTER_SHARE }, #endif }; @@ -166,96 +166,96 @@ static const struct sys_mmu_table final_mmu_table[] = { #ifdef CONFIG_FSL_LSCH3 { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE, - CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PMD_SECT_NON_SHARE }, + CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE }, { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, - PMD_SECT_OUTER_SHARE | PMD_SECT_NS }, + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, { CONFIG_SYS_FSL_QSPI_BASE2, CONFIG_SYS_FSL_QSPI_BASE2, CONFIG_SYS_FSL_QSPI_SIZE2, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_IFC_BASE2, CONFIG_SYS_FSL_IFC_BASE2, - CONFIG_SYS_FSL_IFC_SIZE2, MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE }, + CONFIG_SYS_FSL_IFC_SIZE2, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, { CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_MC_BASE, CONFIG_SYS_FSL_MC_BASE, CONFIG_SYS_FSL_MC_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_NI_BASE, CONFIG_SYS_FSL_NI_BASE, CONFIG_SYS_FSL_NI_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, /* For QBMAN portal, only the first 64MB is cache-enabled */ { CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_SIZE_1, MT_NORMAL, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN | PMD_SECT_NS }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN | PTE_BLOCK_NS }, { CONFIG_SYS_FSL_QBMAN_BASE + CONFIG_SYS_FSL_QBMAN_SIZE_1, CONFIG_SYS_FSL_QBMAN_BASE + CONFIG_SYS_FSL_QBMAN_SIZE_1, CONFIG_SYS_FSL_QBMAN_SIZE - CONFIG_SYS_FSL_QBMAN_SIZE_1, - MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_PCIE1_PHYS_ADDR, CONFIG_SYS_PCIE1_PHYS_ADDR, CONFIG_SYS_PCIE1_PHYS_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_PCIE2_PHYS_ADDR, CONFIG_SYS_PCIE2_PHYS_ADDR, CONFIG_SYS_PCIE2_PHYS_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_PCIE3_PHYS_ADDR, CONFIG_SYS_PCIE3_PHYS_ADDR, CONFIG_SYS_PCIE3_PHYS_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, #if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A) { CONFIG_SYS_PCIE4_PHYS_ADDR, CONFIG_SYS_PCIE4_PHYS_ADDR, CONFIG_SYS_PCIE4_PHYS_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, #endif { CONFIG_SYS_FSL_WRIOP1_BASE, CONFIG_SYS_FSL_WRIOP1_BASE, CONFIG_SYS_FSL_WRIOP1_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_AIOP1_BASE, CONFIG_SYS_FSL_AIOP1_BASE, CONFIG_SYS_FSL_AIOP1_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_PEBUF_BASE, CONFIG_SYS_FSL_PEBUF_BASE, CONFIG_SYS_FSL_PEBUF_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, - PMD_SECT_OUTER_SHARE | PMD_SECT_NS }, + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, #elif defined(CONFIG_FSL_LSCH2) { CONFIG_SYS_FSL_BOOTROM_BASE, CONFIG_SYS_FSL_BOOTROM_BASE, CONFIG_SYS_FSL_BOOTROM_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_BASE, CONFIG_SYS_FSL_CCSR_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_OCRAM_BASE, CONFIG_SYS_FSL_OCRAM_BASE, - CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PMD_SECT_NON_SHARE }, + CONFIG_SYS_FSL_OCRAM_SIZE, MT_NORMAL, PTE_BLOCK_NON_SHARE }, { CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_BASE, CONFIG_SYS_FSL_DCSR_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_QSPI_BASE, CONFIG_SYS_FSL_QSPI_BASE, CONFIG_SYS_FSL_QSPI_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_IFC_BASE, CONFIG_SYS_FSL_IFC_BASE, - CONFIG_SYS_FSL_IFC_SIZE, MT_DEVICE_NGNRNE, PMD_SECT_NON_SHARE }, + CONFIG_SYS_FSL_IFC_SIZE, MT_DEVICE_NGNRNE, PTE_BLOCK_NON_SHARE }, { CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_BASE1, CONFIG_SYS_FSL_DRAM_SIZE1, MT_NORMAL, - PMD_SECT_OUTER_SHARE | PMD_SECT_NS }, + PTE_BLOCK_OUTER_SHARE | PTE_BLOCK_NS }, { CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_BASE, CONFIG_SYS_FSL_QBMAN_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_DRAM_BASE2, CONFIG_SYS_FSL_DRAM_BASE2, - CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, PMD_SECT_OUTER_SHARE }, + CONFIG_SYS_FSL_DRAM_SIZE2, MT_NORMAL, PTE_BLOCK_OUTER_SHARE }, { CONFIG_SYS_PCIE1_PHYS_ADDR, CONFIG_SYS_PCIE1_PHYS_ADDR, CONFIG_SYS_PCIE1_PHYS_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_PCIE2_PHYS_ADDR, CONFIG_SYS_PCIE2_PHYS_ADDR, CONFIG_SYS_PCIE2_PHYS_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_PCIE3_PHYS_ADDR, CONFIG_SYS_PCIE3_PHYS_ADDR, CONFIG_SYS_PCIE3_PHYS_SIZE, MT_DEVICE_NGNRNE, - PMD_SECT_NON_SHARE | PMD_SECT_PXN | PMD_SECT_UXN }, + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { CONFIG_SYS_FSL_DRAM_BASE3, CONFIG_SYS_FSL_DRAM_BASE3, - CONFIG_SYS_FSL_DRAM_SIZE3, MT_NORMAL, PMD_SECT_OUTER_SHARE }, + CONFIG_SYS_FSL_DRAM_SIZE3, MT_NORMAL, PTE_BLOCK_OUTER_SHARE }, #endif }; #endif diff --git a/arch/arm/include/asm/arch-omap3/omap.h b/arch/arm/include/asm/arch-omap3/omap.h index 2c94a814ef..bc0e02a200 100644 --- a/arch/arm/include/asm/arch-omap3/omap.h +++ b/arch/arm/include/asm/arch-omap3/omap.h @@ -249,6 +249,8 @@ struct gpio { /* ABB tranxdone mask */ #define OMAP_ABB_MPU_TXDONE_MASK (0x1 << 26) +#define OMAP_REBOOT_REASON_OFFSET 0x04 + /* Boot parameters */ #ifndef __ASSEMBLY__ struct omap_boot_parameters { @@ -260,9 +262,9 @@ struct omap_boot_parameters { unsigned int boot_device_descriptor; }; -char omap_reboot_mode(void); +int omap_reboot_mode(char *mode, unsigned int length); int omap_reboot_mode_clear(void); -int omap_reboot_mode_store(char c); +int omap_reboot_mode_store(char *mode); #endif #endif diff --git a/arch/arm/include/asm/arch-omap4/clock.h b/arch/arm/include/asm/arch-omap4/clock.h index f3a682a197..a408c0cd41 100644 --- a/arch/arm/include/asm/arch-omap4/clock.h +++ b/arch/arm/include/asm/arch-omap4/clock.h @@ -134,8 +134,11 @@ /* CM_DSS_DSS_CLKCTRL */ #define DSS_CLKCTRL_OPTFCLKEN_MASK 0xF00 +/* CM_COREAON_USB_PHY_CORE_CLKCTRL */ +#define USBPHY_CORE_CLKCTRL_OPTFCLKEN_CLK32K (1 << 8) + /* CM_L3INIT_USBPHY_CLKCTRL */ -#define USBPHY_CLKCTRL_OPTFCLKEN_PHY_48M_MASK 8 +#define USBPHY_CLKCTRL_OPTFCLKEN_PHY_48M_MASK (1 << 8) /* CM_MPU_MPU_CLKCTRL */ #define MPU_CLKCTRL_CLKSEL_EMIF_DIV_MODE_SHIFT 24 diff --git a/arch/arm/include/asm/arch-omap4/omap.h b/arch/arm/include/asm/arch-omap4/omap.h index 4712722950..5ccda6ee94 100644 --- a/arch/arm/include/asm/arch-omap4/omap.h +++ b/arch/arm/include/asm/arch-omap4/omap.h @@ -120,6 +120,10 @@ struct s32ktimer { /* ABB tranxdone mask */ #define OMAP_ABB_MPU_TXDONE_MASK (0x1 << 7) +#define OMAP44XX_SAR_RAM_BASE 0x4a326000 +#define OMAP_REBOOT_REASON_OFFSET 0xA0C +#define OMAP_REBOOT_REASON_SIZE 0x0F + /* Boot parameters */ #ifndef __ASSEMBLY__ struct omap_boot_parameters { @@ -129,6 +133,10 @@ struct omap_boot_parameters { unsigned char reset_reason; unsigned char ch_flags; }; + +int omap_reboot_mode(char *mode, unsigned int length); +int omap_reboot_mode_clear(void); +int omap_reboot_mode_store(char *mode); #endif #endif diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h index f30f865391..c9f0b3a14b 100644 --- a/arch/arm/include/asm/arch-omap4/sys_proto.h +++ b/arch/arm/include/asm/arch-omap4/sys_proto.h @@ -18,6 +18,7 @@ DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS extern const struct emif_regs emif_regs_elpida_200_mhz_2cs; extern const struct emif_regs emif_regs_elpida_380_mhz_1cs; extern const struct emif_regs emif_regs_elpida_400_mhz_1cs; @@ -25,6 +26,17 @@ extern const struct emif_regs emif_regs_elpida_400_mhz_2cs; extern const struct dmm_lisa_map_regs lisa_map_2G_x_1_x_2; extern const struct dmm_lisa_map_regs lisa_map_2G_x_2_x_2; extern const struct dmm_lisa_map_regs ma_lisa_map_2G_x_2_x_2; +#else +extern const struct lpddr2_device_details elpida_2G_S4_details; +extern const struct lpddr2_device_details elpida_4G_S4_details; +#endif + +#ifdef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS +extern const struct lpddr2_device_timings jedec_default_timings; +#else +extern const struct lpddr2_device_timings elpida_2G_S4_timings; +#endif + struct omap_sysinfo { char *board_string; }; @@ -34,11 +46,12 @@ void gpmc_init(void); void watchdog_init(void); u32 get_device_type(void); void do_set_mux(u32 base, struct pad_conf_entry const *array, int size); -void set_muxconf_regs_essential(void); +void set_muxconf_regs(void); u32 wait_on_value(u32, u32, void *, u32); void sdelay(unsigned long); -void setup_clocks_for_console(void); +void setup_early_clocks(void); void prcm_init(void); +void do_board_detect(void); void bypass_dpll(u32 const base); void freq_update_core(void); u32 get_sys_clk_freq(void); @@ -51,7 +64,6 @@ void save_omap_boot_params(void); void init_omap_revision(void); void do_io_settings(void); void sri2c_init(void); -void gpi2c_init(void); int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data); u32 warm_reset(void); void force_emif_self_refresh(void); diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h b/arch/arm/include/asm/arch-omap5/sys_proto.h index 7fcb783894..804266a1b6 100644 --- a/arch/arm/include/asm/arch-omap5/sys_proto.h +++ b/arch/arm/include/asm/arch-omap5/sys_proto.h @@ -45,11 +45,12 @@ void watchdog_init(void); u32 get_device_type(void); void do_set_mux(u32 base, struct pad_conf_entry const *array, int size); void do_set_mux32(u32 base, struct pad_conf_entry const *array, int size); -void set_muxconf_regs_essential(void); +void set_muxconf_regs(void); u32 wait_on_value(u32, u32, void *, u32); void sdelay(unsigned long); -void setup_clocks_for_console(void); +void setup_early_clocks(void); void prcm_init(void); +void do_board_detect(void); void bypass_dpll(u32 const base); void freq_update_core(void); u32 get_sys_clk_freq(void); @@ -62,7 +63,6 @@ void save_omap_boot_params(void); void init_omap_revision(void); void do_io_settings(void); void sri2c_init(void); -void gpi2c_init(void); int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data); u32 warm_reset(void); void force_emif_self_refresh(void); diff --git a/arch/arm/include/asm/arch-rockchip/lvds_rk3288.h b/arch/arm/include/asm/arch-rockchip/lvds_rk3288.h new file mode 100644 index 0000000000..121a8985d1 --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/lvds_rk3288.h @@ -0,0 +1,97 @@ +/* + * Copyright 2016 Rockchip Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARCH_LVDS_RK3288_H +#define _ASM_ARCH_LVDS_RK3288_H + +#define RK3288_LVDS_CH0_REG0 0x00 +#define RK3288_LVDS_CH0_REG0_LVDS_EN BIT(7) +#define RK3288_LVDS_CH0_REG0_TTL_EN BIT(6) +#define RK3288_LVDS_CH0_REG0_LANECK_EN BIT(5) +#define RK3288_LVDS_CH0_REG0_LANE4_EN BIT(4) +#define RK3288_LVDS_CH0_REG0_LANE3_EN BIT(3) +#define RK3288_LVDS_CH0_REG0_LANE2_EN BIT(2) +#define RK3288_LVDS_CH0_REG0_LANE1_EN BIT(1) +#define RK3288_LVDS_CH0_REG0_LANE0_EN BIT(0) + +#define RK3288_LVDS_CH0_REG1 0x04 +#define RK3288_LVDS_CH0_REG1_LANECK_BIAS BIT(5) +#define RK3288_LVDS_CH0_REG1_LANE4_BIAS BIT(4) +#define RK3288_LVDS_CH0_REG1_LANE3_BIAS BIT(3) +#define RK3288_LVDS_CH0_REG1_LANE2_BIAS BIT(2) +#define RK3288_LVDS_CH0_REG1_LANE1_BIAS BIT(1) +#define RK3288_LVDS_CH0_REG1_LANE0_BIAS BIT(0) + +#define RK3288_LVDS_CH0_REG2 0x08 +#define RK3288_LVDS_CH0_REG2_RESERVE_ON BIT(7) +#define RK3288_LVDS_CH0_REG2_LANECK_LVDS_MODE BIT(6) +#define RK3288_LVDS_CH0_REG2_LANE4_LVDS_MODE BIT(5) +#define RK3288_LVDS_CH0_REG2_LANE3_LVDS_MODE BIT(4) +#define RK3288_LVDS_CH0_REG2_LANE2_LVDS_MODE BIT(3) +#define RK3288_LVDS_CH0_REG2_LANE1_LVDS_MODE BIT(2) +#define RK3288_LVDS_CH0_REG2_LANE0_LVDS_MODE BIT(1) +#define RK3288_LVDS_CH0_REG2_PLL_FBDIV8 BIT(0) + +#define RK3288_LVDS_CH0_REG3 0x0c +#define RK3288_LVDS_CH0_REG3_PLL_FBDIV_MASK 0xff + +#define RK3288_LVDS_CH0_REG4 0x10 +#define RK3288_LVDS_CH0_REG4_LANECK_TTL_MODE BIT(5) +#define RK3288_LVDS_CH0_REG4_LANE4_TTL_MODE BIT(4) +#define RK3288_LVDS_CH0_REG4_LANE3_TTL_MODE BIT(3) +#define RK3288_LVDS_CH0_REG4_LANE2_TTL_MODE BIT(2) +#define RK3288_LVDS_CH0_REG4_LANE1_TTL_MODE BIT(1) +#define RK3288_LVDS_CH0_REG4_LANE0_TTL_MODE BIT(0) + +#define RK3288_LVDS_CH0_REG5 0x14 +#define RK3288_LVDS_CH0_REG5_LANECK_TTL_DATA BIT(5) +#define RK3288_LVDS_CH0_REG5_LANE4_TTL_DATA BIT(4) +#define RK3288_LVDS_CH0_REG5_LANE3_TTL_DATA BIT(3) +#define RK3288_LVDS_CH0_REG5_LANE2_TTL_DATA BIT(2) +#define RK3288_LVDS_CH0_REG5_LANE1_TTL_DATA BIT(1) +#define RK3288_LVDS_CH0_REG5_LANE0_TTL_DATA BIT(0) + +#define RK3288_LVDS_CFG_REGC 0x30 +#define RK3288_LVDS_CFG_REGC_PLL_ENABLE 0x00 +#define RK3288_LVDS_CFG_REGC_PLL_DISABLE 0xff + +#define RK3288_LVDS_CH0_REGD 0x34 +#define RK3288_LVDS_CH0_REGD_PLL_PREDIV_MASK 0x1f + +#define RK3288_LVDS_CH0_REG20 0x80 +#define RK3288_LVDS_CH0_REG20_MSB 0x45 +#define RK3288_LVDS_CH0_REG20_LSB 0x44 + +#define RK3288_LVDS_CFG_REG21 0x84 +#define RK3288_LVDS_CFG_REG21_TX_ENABLE 0x92 +#define RK3288_LVDS_CFG_REG21_TX_DISABLE 0x00 + +/* fbdiv value is split over 2 registers, with bit8 in reg2 */ +#define RK3288_LVDS_PLL_FBDIV_REG2(_fbd) \ + (_fbd & BIT(8) ? RK3288_LVDS_CH0_REG2_PLL_FBDIV8 : 0) +#define RK3288_LVDS_PLL_FBDIV_REG3(_fbd) \ + (_fbd & RK3288_LVDS_CH0_REG3_PLL_FBDIV_MASK) +#define RK3288_LVDS_PLL_PREDIV_REGD(_pd) \ + (_pd & RK3288_LVDS_CH0_REGD_PLL_PREDIV_MASK) + +#define RK3288_LVDS_SOC_CON6_SEL_VOP_LIT BIT(3) + +#define LVDS_FMT_MASK (7 << 16) +#define LVDS_MSB (1 << 3) +#define LVDS_DUAL (1 << 4) +#define LVDS_FMT_1 (1 << 5) +#define LVDS_TTL_EN (1 << 6) +#define LVDS_START_PHASE_RST_1 (1 << 7) +#define LVDS_DCLK_INV (1 << 8) +#define LVDS_CH0_EN (1 << 11) +#define LVDS_CH1_EN (1 << 12) +#define LVDS_PWRDN (1 << 15) + +#define LVDS_24BIT (0 << 1) +#define LVDS_18BIT (1 << 1) + + +#endif diff --git a/arch/arm/include/asm/arch-rockchip/vop_rk3288.h b/arch/arm/include/asm/arch-rockchip/vop_rk3288.h index 0104ba3f2a..0ce3d6746f 100644 --- a/arch/arm/include/asm/arch-rockchip/vop_rk3288.h +++ b/arch/arm/include/asm/arch-rockchip/vop_rk3288.h @@ -89,6 +89,7 @@ enum { enum vop_modes { VOP_MODE_EDP = 0, VOP_MODE_HDMI, + VOP_MODE_LVDS, VOP_MODE_NONE, VOP_MODE_AUTO_DETECT, VOP_MODE_UNKNOWN, diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index 897f010207..0d08ed3ba8 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -22,32 +22,19 @@ * calculated specifically. */ -#ifndef CONFIG_SYS_FULL_VA -#define VA_BITS (42) /* 42 bits virtual address */ -#else #define VA_BITS CONFIG_SYS_VA_BITS -#define PTL2_BITS CONFIG_SYS_PTL2_BITS -#endif +#define PTE_BLOCK_BITS CONFIG_SYS_PTL2_BITS + +/* + * block/section address mask and size definitions. + */ /* PAGE_SHIFT determines the page size */ #undef PAGE_SIZE -#define PAGE_SHIFT 16 +#define PAGE_SHIFT 12 #define PAGE_SIZE (1 << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) -/* - * block/section address mask and size definitions. - */ -#ifndef CONFIG_SYS_FULL_VA -#define SECTION_SHIFT 29 -#define SECTION_SIZE (UL(1) << SECTION_SHIFT) -#define SECTION_MASK (~(SECTION_SIZE-1)) -#else -#define BLOCK_SHIFT CONFIG_SYS_BLOCK_SHIFT -#define BLOCK_SIZE (UL(1) << BLOCK_SHIFT) -#define BLOCK_MASK (~(BLOCK_SIZE-1)) -#endif - /***************************************************************/ /* @@ -70,63 +57,28 @@ * */ -#ifdef CONFIG_SYS_FULL_VA -/* - * Level 1 descriptor (PGD). - */ - -#define PTL1_TYPE_MASK (3 << 0) -#define PTL1_TYPE_TABLE (3 << 0) - -#define PTL1_TABLE_PXN (1UL << 59) -#define PTL1_TABLE_XN (1UL << 60) -#define PTL1_TABLE_AP (1UL << 61) -#define PTL1_TABLE_NS (1UL << 63) +#define PTE_TYPE_MASK (3 << 0) +#define PTE_TYPE_FAULT (0 << 0) +#define PTE_TYPE_TABLE (3 << 0) +#define PTE_TYPE_BLOCK (1 << 0) - -/* - * Level 2 descriptor (PMD). - */ - -#define PTL2_TYPE_MASK (3 << 0) -#define PTL2_TYPE_FAULT (0 << 0) -#define PTL2_TYPE_TABLE (3 << 0) -#define PTL2_TYPE_BLOCK (1 << 0) +#define PTE_TABLE_PXN (1UL << 59) +#define PTE_TABLE_XN (1UL << 60) +#define PTE_TABLE_AP (1UL << 61) +#define PTE_TABLE_NS (1UL << 63) /* * Block */ -#define PTL2_MEMTYPE(x) ((x) << 2) -#define PTL2_BLOCK_NON_SHARE (0 << 8) -#define PTL2_BLOCK_OUTER_SHARE (2 << 8) -#define PTL2_BLOCK_INNER_SHARE (3 << 8) -#define PTL2_BLOCK_AF (1 << 10) -#define PTL2_BLOCK_NG (1 << 11) -#define PTL2_BLOCK_PXN (UL(1) << 53) -#define PTL2_BLOCK_UXN (UL(1) << 54) - -#else -/* - * Level 2 descriptor (PMD). - */ -#define PMD_TYPE_MASK (3 << 0) -#define PMD_TYPE_FAULT (0 << 0) -#define PMD_TYPE_TABLE (3 << 0) -#define PMD_TYPE_SECT (1 << 0) - -/* - * Section - */ -#define PMD_SECT_NS (1 << 5) -#define PMD_SECT_NON_SHARE (0 << 8) -#define PMD_SECT_OUTER_SHARE (2 << 8) -#define PMD_SECT_INNER_SHARE (3 << 8) -#define PMD_SECT_AF (1 << 10) -#define PMD_SECT_NG (1 << 11) -#define PMD_SECT_PXN (UL(1) << 53) -#define PMD_SECT_UXN (UL(1) << 54) - -#endif +#define PTE_BLOCK_MEMTYPE(x) ((x) << 2) +#define PTE_BLOCK_NS (1 << 5) +#define PTE_BLOCK_NON_SHARE (0 << 8) +#define PTE_BLOCK_OUTER_SHARE (2 << 8) +#define PTE_BLOCK_INNER_SHARE (3 << 8) +#define PTE_BLOCK_AF (1 << 10) +#define PTE_BLOCK_NG (1 << 11) +#define PTE_BLOCK_PXN (UL(1) << 53) +#define PTE_BLOCK_UXN (UL(1) << 54) /* * AttrIndx[2:0] @@ -154,38 +106,13 @@ #define TCR_TG0_4K (0 << 14) #define TCR_TG0_64K (1 << 14) #define TCR_TG0_16K (2 << 14) - -#ifndef CONFIG_SYS_FULL_VA -#define TCR_EL1_IPS_BITS (UL(3) << 32) /* 42 bits physical address */ -#define TCR_EL2_IPS_BITS (3 << 16) /* 42 bits physical address */ -#define TCR_EL3_IPS_BITS (3 << 16) /* 42 bits physical address */ -#else -#define TCR_EL1_IPS_BITS CONFIG_SYS_TCR_EL1_IPS_BITS -#define TCR_EL2_IPS_BITS CONFIG_SYS_TCR_EL2_IPS_BITS -#define TCR_EL3_IPS_BITS CONFIG_SYS_TCR_EL3_IPS_BITS -#endif - -/* PTWs cacheable, inner/outer WBWA and inner shareable */ -#define TCR_FLAGS (TCR_TG0_64K | \ - TCR_SHARED_INNER | \ - TCR_ORGN_WBWA | \ - TCR_IRGN_WBWA | \ - TCR_T0SZ(VA_BITS)) +#define TCR_EPD1_DISABLE (1 << 23) #define TCR_EL1_RSVD (1 << 31) #define TCR_EL2_RSVD (1 << 31 | 1 << 23) #define TCR_EL3_RSVD (1 << 31 | 1 << 23) #ifndef __ASSEMBLY__ -#ifndef CONFIG_SYS_FULL_VA - -void set_pgtable_section(u64 *page_table, u64 index, - u64 section, u64 memory_type, - u64 attribute); -void set_pgtable_table(u64 *page_table, u64 index, - u64 *table_addr); - -#endif static inline void set_ttbr_tcr_mair(int el, u64 table, u64 tcr, u64 attr) { asm volatile("dsb sy"); @@ -212,6 +139,8 @@ struct mm_region { u64 size; u64 attrs; }; + +extern struct mm_region *mem_map; #endif #endif /* _ASM_ARMV8_MMU_H_ */ diff --git a/arch/arm/include/asm/emif.h b/arch/arm/include/asm/emif.h index 7986e6e794..b00decec6d 100644 --- a/arch/arm/include/asm/emif.h +++ b/arch/arm/include/asm/emif.h @@ -478,6 +478,12 @@ #define EMIF_REG_DLL_SLAVE_DLY_CTRL_SHDW_MASK (0xFF << 4) #define EMIF_EMIF_DDR_PHY_CTRL_1_BASE_VAL_SHDW_SHIFT 12 #define EMIF_EMIF_DDR_PHY_CTRL_1_BASE_VAL_SHDW_MASK (0xFFFFF << 12) +#define EMIF_DDR_PHY_CTRL_1_WRLVL_MASK_SHIFT 25 +#define EMIF_DDR_PHY_CTRL_1_WRLVL_MASK_MASK (1 << 25) +#define EMIF_DDR_PHY_CTRL_1_RDLVLGATE_MASK_SHIFT 26 +#define EMIF_DDR_PHY_CTRL_1_RDLVLGATE_MASK_MASK (1 << 26) +#define EMIF_DDR_PHY_CTRL_1_RDLVL_MASK_SHIFT 27 +#define EMIF_DDR_PHY_CTRL_1_RDLVL_MASK_MASK (1 << 27) /* DDR_PHY_CTRL_2 */ #define EMIF_REG_DDR_PHY_CTRL_2_SHIFT 0 @@ -539,6 +545,9 @@ /* Memory Adapter */ #define MA_BASE 0x482AF040 +#define MA_PRIORITY 0x482A2000 +#define MA_HIMEM_INTERLEAVE_UN_SHIFT 8 +#define MA_HIMEM_INTERLEAVE_UN_MASK (1 << 8) /* DMM_LISA_MAP */ #define EMIF_SYS_ADDR_SHIFT 24 @@ -905,8 +914,8 @@ struct dmm_lisa_map_regs { /* Maximum delay before Low Power Modes */ #define REG_CS_TIM 0x0 -#define REG_SR_TIM 0x0 -#define REG_PD_TIM 0x0 +#define REG_SR_TIM 0xF +#define REG_PD_TIM 0xF /* EMIF_PWR_MGMT_CTRL register */ @@ -914,7 +923,7 @@ struct dmm_lisa_map_regs { ((REG_CS_TIM << EMIF_REG_CS_TIM_SHIFT) & EMIF_REG_CS_TIM_MASK)|\ ((REG_SR_TIM << EMIF_REG_SR_TIM_SHIFT) & EMIF_REG_SR_TIM_MASK)|\ ((REG_PD_TIM << EMIF_REG_PD_TIM_SHIFT) & EMIF_REG_PD_TIM_MASK)|\ - ((LP_MODE_DISABLE << EMIF_REG_LP_MODE_SHIFT)\ + ((LP_MODE_SELF_REFRESH << EMIF_REG_LP_MODE_SHIFT)\ & EMIF_REG_LP_MODE_MASK) |\ ((DPD_DISABLE << EMIF_REG_DPD_EN_SHIFT)\ & EMIF_REG_DPD_EN_MASK))\ diff --git a/arch/arm/include/asm/fsl_secure_boot.h b/arch/arm/include/asm/fsl_secure_boot.h index 0da0599738..a32a1d7222 100644 --- a/arch/arm/include/asm/fsl_secure_boot.h +++ b/arch/arm/include/asm/fsl_secure_boot.h @@ -20,17 +20,12 @@ #define CONFIG_CMD_BLOB #define CONFIG_FSL_SEC_MON #define CONFIG_SHA_PROG_HW_ACCEL -#define CONFIG_RSA #define CONFIG_RSA_FREESCALE_EXP #ifndef CONFIG_FSL_CAAM #define CONFIG_FSL_CAAM #endif -#ifndef CONFIG_DM -#define CONFIG_DM -#endif - #define CONFIG_KEY_REVOCATION #ifndef CONFIG_SYS_RAMBOOT /* The key used for verification of next level images diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index dcfa0985b5..77d2653e27 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -38,10 +38,11 @@ struct arch_global_data { unsigned long long timer_reset_value; #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) unsigned long tlb_addr; -#if defined(CONFIG_SYS_FULL_VA) - unsigned long pmd_addr[CONFIG_SYS_PTL1_ENTRIES]; -#endif unsigned long tlb_size; +#if defined(CONFIG_ARM64) + unsigned long tlb_fillptr; + unsigned long tlb_emerg; +#endif #endif #ifdef CONFIG_OMAP_COMMON diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index d7b81c101b..aef31266ce 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -617,6 +617,9 @@ void disable_edma3_clocks(void); void omap_die_id(unsigned int *die_id); +/* Initialize general purpose I2C(0) on the SoC */ +void gpi2c_init(void); + /* ABB */ #define OMAP_ABB_NOMINAL_OPP 0 #define OMAP_ABB_FAST_OPP 1 @@ -710,7 +713,9 @@ static inline u8 is_dra72x(void) #define OMAP_SRAM_SCRATCH_VCORES_PTR (SRAM_SCRATCH_SPACE_ADDR + 0x1C) #define OMAP_SRAM_SCRATCH_SYS_CTRL (SRAM_SCRATCH_SPACE_ADDR + 0x20) #define OMAP_SRAM_SCRATCH_BOOT_PARAMS (SRAM_SCRATCH_SPACE_ADDR + 0x24) -#define OMAP5_SRAM_SCRATCH_SPACE_END (SRAM_SCRATCH_SPACE_ADDR + 0x28) +#define OMAP_SRAM_SCRATCH_BOARD_EEPROM_START (SRAM_SCRATCH_SPACE_ADDR + 0x28) +#define OMAP_SRAM_SCRATCH_BOARD_EEPROM_END (SRAM_SCRATCH_SPACE_ADDR + 0x200) +#define OMAP_SRAM_SCRATCH_SPACE_END (OMAP_SRAM_SCRATCH_BOARD_EEPROM_END) /* Boot parameters */ #define DEVICE_DATA_OFFSET 0x18 diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 026e7ef83b..ac1173d189 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -17,18 +17,15 @@ #define CR_WXN (1 << 19) /* Write Permision Imply XN */ #define CR_EE (1 << 25) /* Exception (Big) Endian */ -#ifndef CONFIG_SYS_FULL_VA -#define PGTABLE_SIZE (0x10000) -#else -#define PGTABLE_SIZE CONFIG_SYS_PGTABLE_SIZE -#endif +#ifndef __ASSEMBLY__ + +u64 get_page_table_size(void); +#define PGTABLE_SIZE get_page_table_size() /* 2MB granularity */ #define MMU_SECTION_SHIFT 21 #define MMU_SECTION_SIZE (1 << MMU_SECTION_SHIFT) -#ifndef __ASSEMBLY__ - enum dcache_option { DCACHE_OFF = 0x3, }; @@ -97,6 +94,7 @@ void __asm_flush_dcache_range(u64 start, u64 end); void __asm_invalidate_tlb_all(void); void __asm_invalidate_icache_all(void); int __asm_flush_l3_cache(void); +void __asm_switch_ttbr(u64 new_ttbr); void armv8_switch_to_el2(void); void armv8_switch_to_el1(void); diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index f3db7b58cb..7a0fb5862e 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -6,7 +6,8 @@ # lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _ashldi3.o _ashrdi3.o _divsi3.o \ - _lshrdi3.o _modsi3.o _udivsi3.o _umodsi3.o div0.o + _lshrdi3.o _modsi3.o _udivsi3.o _umodsi3.o div0.o \ + _uldivmod.o ifdef CONFIG_CPU_V7M obj-y += vectors_m.o crt0.o diff --git a/arch/arm/lib/_uldivmod.S b/arch/arm/lib/_uldivmod.S new file mode 100644 index 0000000000..426c2f2406 --- /dev/null +++ b/arch/arm/lib/_uldivmod.S @@ -0,0 +1,245 @@ +/* + * Copyright 2010, Google Inc. + * + * Brought in from coreboot uldivmod.S + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <linux/linkage.h> +#include <asm/assembler.h> + +/* We don't use Thumb instructions for now */ +#define ARM(x...) x +#define THUMB(x...) + +/* + * A, Q = r0 + (r1 << 32) + * B, R = r2 + (r3 << 32) + * A / B = Q ... R + */ + +A_0 .req r0 +A_1 .req r1 +B_0 .req r2 +B_1 .req r3 +C_0 .req r4 +C_1 .req r5 +D_0 .req r6 +D_1 .req r7 + +Q_0 .req r0 +Q_1 .req r1 +R_0 .req r2 +R_1 .req r3 + +THUMB( +TMP .req r8 +) + +ENTRY(__aeabi_uldivmod) + stmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) lr} + @ Test if B == 0 + orrs ip, B_0, B_1 @ Z set -> B == 0 + beq L_div_by_0 + @ Test if B is power of 2: (B & (B - 1)) == 0 + subs C_0, B_0, #1 + sbc C_1, B_1, #0 + tst C_0, B_0 + tsteq B_1, C_1 + beq L_pow2 + @ Test if A_1 == B_1 == 0 + orrs ip, A_1, B_1 + beq L_div_32_32 + +L_div_64_64: +/* CLZ only exists in ARM architecture version 5 and above. */ +#ifdef HAVE_CLZ + mov C_0, #1 + mov C_1, #0 + @ D_0 = clz A + teq A_1, #0 + clz D_0, A_1 + clzeq ip, A_0 + addeq D_0, D_0, ip + @ D_1 = clz B + teq B_1, #0 + clz D_1, B_1 + clzeq ip, B_0 + addeq D_1, D_1, ip + @ if clz B - clz A > 0 + subs D_0, D_1, D_0 + bls L_done_shift + @ B <<= (clz B - clz A) + subs D_1, D_0, #32 + rsb ip, D_0, #32 + movmi B_1, B_1, lsl D_0 +ARM( orrmi B_1, B_1, B_0, lsr ip ) +THUMB( lsrmi TMP, B_0, ip ) +THUMB( orrmi B_1, B_1, TMP ) + movpl B_1, B_0, lsl D_1 + mov B_0, B_0, lsl D_0 + @ C = 1 << (clz B - clz A) + movmi C_1, C_1, lsl D_0 +ARM( orrmi C_1, C_1, C_0, lsr ip ) +THUMB( lsrmi TMP, C_0, ip ) +THUMB( orrmi C_1, C_1, TMP ) + movpl C_1, C_0, lsl D_1 + mov C_0, C_0, lsl D_0 +L_done_shift: + mov D_0, #0 + mov D_1, #0 + @ C: current bit; D: result +#else + @ C: current bit; D: result + mov C_0, #1 + mov C_1, #0 + mov D_0, #0 + mov D_1, #0 +L_lsl_4: + cmp B_1, #0x10000000 + cmpcc B_1, A_1 + cmpeq B_0, A_0 + bcs L_lsl_1 + @ B <<= 4 + mov B_1, B_1, lsl #4 + orr B_1, B_1, B_0, lsr #28 + mov B_0, B_0, lsl #4 + @ C <<= 4 + mov C_1, C_1, lsl #4 + orr C_1, C_1, C_0, lsr #28 + mov C_0, C_0, lsl #4 + b L_lsl_4 +L_lsl_1: + cmp B_1, #0x80000000 + cmpcc B_1, A_1 + cmpeq B_0, A_0 + bcs L_subtract + @ B <<= 1 + mov B_1, B_1, lsl #1 + orr B_1, B_1, B_0, lsr #31 + mov B_0, B_0, lsl #1 + @ C <<= 1 + mov C_1, C_1, lsl #1 + orr C_1, C_1, C_0, lsr #31 + mov C_0, C_0, lsl #1 + b L_lsl_1 +#endif +L_subtract: + @ if A >= B + cmp A_1, B_1 + cmpeq A_0, B_0 + bcc L_update + @ A -= B + subs A_0, A_0, B_0 + sbc A_1, A_1, B_1 + @ D |= C + orr D_0, D_0, C_0 + orr D_1, D_1, C_1 +L_update: + @ if A == 0: break + orrs ip, A_1, A_0 + beq L_exit + @ C >>= 1 + movs C_1, C_1, lsr #1 + movs C_0, C_0, rrx + @ if C == 0: break + orrs ip, C_1, C_0 + beq L_exit + @ B >>= 1 + movs B_1, B_1, lsr #1 + mov B_0, B_0, rrx + b L_subtract +L_exit: + @ Note: A, B & Q, R are aliases + mov R_0, A_0 + mov R_1, A_1 + mov Q_0, D_0 + mov Q_1, D_1 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc} + +L_div_32_32: + @ Note: A_0 & r0 are aliases + @ Q_1 r1 + mov r1, B_0 + bl __aeabi_uidivmod + mov R_0, r1 + mov R_1, #0 + mov Q_1, #0 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc} + +L_pow2: +#ifdef HAVE_CLZ + @ Note: A, B and Q, R are aliases + @ R = A & (B - 1) + and C_0, A_0, C_0 + and C_1, A_1, C_1 + @ Q = A >> log2(B) + @ Note: B must not be 0 here! + clz D_0, B_0 + add D_1, D_0, #1 + rsbs D_0, D_0, #31 + bpl L_1 + clz D_0, B_1 + rsb D_0, D_0, #31 + mov A_0, A_1, lsr D_0 + add D_0, D_0, #32 +L_1: + movpl A_0, A_0, lsr D_0 +ARM( orrpl A_0, A_0, A_1, lsl D_1 ) +THUMB( lslpl TMP, A_1, D_1 ) +THUMB( orrpl A_0, A_0, TMP ) + mov A_1, A_1, lsr D_0 + @ Mov back C to R + mov R_0, C_0 + mov R_1, C_1 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc} +#else + @ Note: A, B and Q, R are aliases + @ R = A & (B - 1) + and C_0, A_0, C_0 + and C_1, A_1, C_1 + @ Q = A >> log2(B) + @ Note: B must not be 0 here! + @ Count the leading zeroes in B. + mov D_0, #0 + orrs B_0, B_0, B_0 + @ If B is greater than 1 << 31, divide A and B by 1 << 32. + moveq A_0, A_1 + moveq A_1, #0 + moveq B_0, B_1 + @ Count the remaining leading zeroes in B. + movs B_1, B_0, lsl #16 + addeq D_0, #16 + moveq B_0, B_0, lsr #16 + tst B_0, #0xff + addeq D_0, #8 + moveq B_0, B_0, lsr #8 + tst B_0, #0xf + addeq D_0, #4 + moveq B_0, B_0, lsr #4 + tst B_0, #0x3 + addeq D_0, #2 + moveq B_0, B_0, lsr #2 + tst B_0, #0x1 + addeq D_0, #1 + @ Shift A to the right by the appropriate amount. + rsb D_1, D_0, #32 + mov Q_0, A_0, lsr D_0 + orr Q_0, A_1, lsl D_1 + mov Q_1, A_1, lsr D_0 + @ Move C to R + mov R_0, C_0 + mov R_1, C_1 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc} +#endif + +L_div_by_0: + bl __div0 + @ As wrong as it could be + mov Q_0, #0 + mov Q_1, #0 + mov R_0, #0 + mov R_1, #0 + ldmfd sp!, {r4, r5, r6, r7, THUMB(TMP,) pc} +ENDPROC(__aeabi_uldivmod) diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c index ec3fb77f85..ed83043abb 100644 --- a/arch/arm/lib/interrupts.c +++ b/arch/arm/lib/interrupts.c @@ -22,6 +22,7 @@ #include <common.h> #include <asm/proc-armv/ptrace.h> #include <asm/u-boot-arm.h> +#include <efi_loader.h> DECLARE_GLOBAL_DATA_PTR; @@ -165,6 +166,7 @@ void show_regs (struct pt_regs *regs) void do_undefined_instruction (struct pt_regs *pt_regs) { + efi_restore_gd(); printf ("undefined instruction\n"); show_regs (pt_regs); bad_mode (); @@ -172,6 +174,7 @@ void do_undefined_instruction (struct pt_regs *pt_regs) void do_software_interrupt (struct pt_regs *pt_regs) { + efi_restore_gd(); printf ("software interrupt\n"); show_regs (pt_regs); bad_mode (); @@ -179,6 +182,7 @@ void do_software_interrupt (struct pt_regs *pt_regs) void do_prefetch_abort (struct pt_regs *pt_regs) { + efi_restore_gd(); printf ("prefetch abort\n"); show_regs (pt_regs); bad_mode (); @@ -186,6 +190,7 @@ void do_prefetch_abort (struct pt_regs *pt_regs) void do_data_abort (struct pt_regs *pt_regs) { + efi_restore_gd(); printf ("data abort\n"); show_regs (pt_regs); bad_mode (); @@ -193,6 +198,7 @@ void do_data_abort (struct pt_regs *pt_regs) void do_not_used (struct pt_regs *pt_regs) { + efi_restore_gd(); printf ("not used\n"); show_regs (pt_regs); bad_mode (); @@ -200,6 +206,7 @@ void do_not_used (struct pt_regs *pt_regs) void do_fiq (struct pt_regs *pt_regs) { + efi_restore_gd(); printf ("fast interrupt request\n"); show_regs (pt_regs); bad_mode (); @@ -208,6 +215,7 @@ void do_fiq (struct pt_regs *pt_regs) #ifndef CONFIG_USE_IRQ void do_irq (struct pt_regs *pt_regs) { + efi_restore_gd(); printf ("interrupt request\n"); show_regs (pt_regs); bad_mode (); diff --git a/arch/arm/lib/interrupts_64.c b/arch/arm/lib/interrupts_64.c index b476722556..7c9cfce69f 100644 --- a/arch/arm/lib/interrupts_64.c +++ b/arch/arm/lib/interrupts_64.c @@ -7,6 +7,7 @@ #include <common.h> #include <linux/compiler.h> +#include <efi_loader.h> int interrupt_init(void) @@ -41,6 +42,7 @@ void show_regs(struct pt_regs *regs) */ void do_bad_sync(struct pt_regs *pt_regs, unsigned int esr) { + efi_restore_gd(); printf("Bad mode in \"Synchronous Abort\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); panic("Resetting CPU ...\n"); @@ -51,6 +53,7 @@ void do_bad_sync(struct pt_regs *pt_regs, unsigned int esr) */ void do_bad_irq(struct pt_regs *pt_regs, unsigned int esr) { + efi_restore_gd(); printf("Bad mode in \"Irq\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); panic("Resetting CPU ...\n"); @@ -61,6 +64,7 @@ void do_bad_irq(struct pt_regs *pt_regs, unsigned int esr) */ void do_bad_fiq(struct pt_regs *pt_regs, unsigned int esr) { + efi_restore_gd(); printf("Bad mode in \"Fiq\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); panic("Resetting CPU ...\n"); @@ -71,6 +75,7 @@ void do_bad_fiq(struct pt_regs *pt_regs, unsigned int esr) */ void do_bad_error(struct pt_regs *pt_regs, unsigned int esr) { + efi_restore_gd(); printf("Bad mode in \"Error\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); panic("Resetting CPU ...\n"); @@ -81,6 +86,7 @@ void do_bad_error(struct pt_regs *pt_regs, unsigned int esr) */ void do_sync(struct pt_regs *pt_regs, unsigned int esr) { + efi_restore_gd(); printf("\"Synchronous Abort\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); panic("Resetting CPU ...\n"); @@ -91,6 +97,7 @@ void do_sync(struct pt_regs *pt_regs, unsigned int esr) */ void do_irq(struct pt_regs *pt_regs, unsigned int esr) { + efi_restore_gd(); printf("\"Irq\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); panic("Resetting CPU ...\n"); @@ -101,6 +108,7 @@ void do_irq(struct pt_regs *pt_regs, unsigned int esr) */ void do_fiq(struct pt_regs *pt_regs, unsigned int esr) { + efi_restore_gd(); printf("\"Fiq\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); panic("Resetting CPU ...\n"); @@ -114,6 +122,7 @@ void do_fiq(struct pt_regs *pt_regs, unsigned int esr) */ void __weak do_error(struct pt_regs *pt_regs, unsigned int esr) { + efi_restore_gd(); printf("\"Error\" handler, esr 0x%08x\n", esr); show_regs(pt_regs); panic("Resetting CPU ...\n"); diff --git a/arch/arm/lib/sections.c b/arch/arm/lib/sections.c index a1205c370d..6a94522418 100644 --- a/arch/arm/lib/sections.c +++ b/arch/arm/lib/sections.c @@ -27,4 +27,8 @@ char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start"))); char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); char __secure_start[0] __attribute__((section(".__secure_start"))); char __secure_end[0] __attribute__((section(".__secure_end"))); +char __efi_runtime_start[0] __attribute__((section(".__efi_runtime_start"))); +char __efi_runtime_stop[0] __attribute__((section(".__efi_runtime_stop"))); +char __efi_runtime_rel_start[0] __attribute__((section(".__efi_runtime_rel_start"))); +char __efi_runtime_rel_stop[0] __attribute__((section(".__efi_runtime_rel_stop"))); char _end[0] __attribute__((section(".__end"))); diff --git a/arch/arm/mach-at91/arm926ejs/u-boot-spl.lds b/arch/arm/mach-at91/arm926ejs/u-boot-spl.lds index acadd1d4c4..1b0420611e 100644 --- a/arch/arm/mach-at91/arm926ejs/u-boot-spl.lds +++ b/arch/arm/mach-at91/arm926ejs/u-boot-spl.lds @@ -30,6 +30,9 @@ SECTIONS .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram . = ALIGN(4); + .u_boot_list : { KEEP(*(SORT(.u_boot_list*))) } > .sram + + . = ALIGN(4); __image_copy_end = .; .end : diff --git a/arch/arm/mach-at91/armv7/u-boot-spl.lds b/arch/arm/mach-at91/armv7/u-boot-spl.lds index eccca43a42..c667c5555b 100644 --- a/arch/arm/mach-at91/armv7/u-boot-spl.lds +++ b/arch/arm/mach-at91/armv7/u-boot-spl.lds @@ -37,6 +37,9 @@ SECTIONS .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram . = ALIGN(4); + .u_boot_list : { KEEP(*(SORT(.u_boot_list*))) } > .sram + + . = ALIGN(4); __image_copy_end = .; .end : diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index a8d3e2f230..5d1c5c5ccb 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -22,6 +22,9 @@ config TARGET_OMAPL138_LCDK config TARGET_CALIMAIN bool "Calimain board" +config TARGET_LEGOEV3 + bool "LEGO MINDSTORMS EV3" + endchoice config SYS_SOC @@ -31,5 +34,6 @@ source "board/Barix/ipam390/Kconfig" source "board/davinci/da8xxevm/Kconfig" source "board/davinci/ea20/Kconfig" source "board/omicron/calimain/Kconfig" +source "board/lego/ev3/Kconfig" endif diff --git a/arch/arm/mach-davinci/da850_pinmux.c b/arch/arm/mach-davinci/da850_pinmux.c index 6105f6390c..758109e98d 100644 --- a/arch/arm/mach-davinci/da850_pinmux.c +++ b/arch/arm/mach-davinci/da850_pinmux.c @@ -12,6 +12,16 @@ #include <asm/arch/pinmux_defs.h> /* SPI pin muxer settings */ +const struct pinmux_config spi0_pins_base[] = { + { pinmux(3), 1, 0 }, /* SPI0_CLK */ + { pinmux(3), 1, 2 }, /* SPI0_SOMI */ + { pinmux(3), 1, 3 }, /* SPI0_SIMO */ +}; + +const struct pinmux_config spi0_pins_scs0[] = { + { pinmux(4), 1, 1 }, /* SPI0_SCS[0] */ +}; + const struct pinmux_config spi1_pins_base[] = { { pinmux(5), 1, 2 }, /* SPI1_CLK */ { pinmux(5), 1, 4 }, /* SPI1_SOMI */ diff --git a/arch/arm/mach-davinci/include/mach/hardware.h b/arch/arm/mach-davinci/include/mach/hardware.h index a4eb0bd89b..2a0360a785 100644 --- a/arch/arm/mach-davinci/include/mach/hardware.h +++ b/arch/arm/mach-davinci/include/mach/hardware.h @@ -503,6 +503,7 @@ struct davinci_syscfg_regs { #define DAVINCI_SYSCFG_SUSPSRC_SPI0 (1 << 21) #define DAVINCI_SYSCFG_SUSPSRC_SPI1 (1 << 22) #define DAVINCI_SYSCFG_SUSPSRC_UART0 (1 << 18) +#define DAVINCI_SYSCFG_SUSPSRC_UART1 (1 << 19) #define DAVINCI_SYSCFG_SUSPSRC_UART2 (1 << 20) #define DAVINCI_SYSCFG_SUSPSRC_TIMER0 (1 << 27) diff --git a/arch/arm/mach-keystone/Makefile b/arch/arm/mach-keystone/Makefile index ffd9eadb0a..b2ffe5bc2f 100644 --- a/arch/arm/mach-keystone/Makefile +++ b/arch/arm/mach-keystone/Makefile @@ -8,8 +8,15 @@ obj-y += init.o obj-y += psc.o obj-y += clock.o +obj-y += mon.o +ifndef CONFIG_SPL_BUILD obj-y += cmd_clock.o obj-y += cmd_mon.o +obj-y += cmd_poweroff.o +obj-y += cmd_ddr3.o +endif obj-y += msmc.o -obj-y += ddr3.o cmd_ddr3.o +obj-y += ddr3.o obj-y += keystone.o +obj-$(CONFIG_K2E_EVM) += ddr3_spd.o +obj-$(CONFIG_K2HK_EVM) += ddr3_spd.o diff --git a/arch/arm/mach-keystone/clock-k2e.c b/arch/arm/mach-keystone/clock-k2e.c deleted file mode 100644 index 7d163a4b1a..0000000000 --- a/arch/arm/mach-keystone/clock-k2e.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Keystone2: get clk rate for K2E - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, <www.ti.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/arch/clock.h> -#include <asm/arch/clock_defs.h> - -/** - * pll_freq_get - get pll frequency - * Fout = Fref * NF(mult) / NR(prediv) / OD - * @pll: pll identifier - */ -static unsigned long pll_freq_get(int pll) -{ - unsigned long mult = 1, prediv = 1, output_div = 2; - unsigned long ret; - u32 tmp, reg; - - if (pll == CORE_PLL) { - ret = external_clk[sys_clk]; - if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { - /* PLL mode */ - tmp = __raw_readl(KS2_MAINPLLCTL0); - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | - (pllctl_reg_read(pll, mult) & - PLLM_MULT_LO_MASK)) + 1; - output_div = ((pllctl_reg_read(pll, secctl) >> - PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; - - ret = ret / prediv / output_div * mult; - } - } else { - switch (pll) { - case PASS_PLL: - ret = external_clk[pa_clk]; - reg = KS2_PASSPLLCTL0; - break; - case DDR3_PLL: - ret = external_clk[ddr3a_clk]; - reg = KS2_DDR3APLLCTL0; - break; - default: - return 0; - } - - tmp = __raw_readl(reg); - - if (!(tmp & PLLCTL_BYPASS)) { - /* Bypass disabled */ - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; - output_div = ((tmp >> PLL_CLKOD_SHIFT) & - PLL_CLKOD_MASK) + 1; - ret = ((ret / prediv) * mult) / output_div; - } - } - - return ret; -} - -unsigned long clk_get_rate(unsigned int clk) -{ - switch (clk) { - case core_pll_clk: return pll_freq_get(CORE_PLL); - case pass_pll_clk: return pll_freq_get(PASS_PLL); - case ddr3_pll_clk: return pll_freq_get(DDR3_PLL); - case sys_clk0_1_clk: - case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); - case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); - case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); - case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); - case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; - case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; - case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; - case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; - case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; - case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; - case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; - case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; - case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; - case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; - case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; - default: - break; - } - - return 0; -} diff --git a/arch/arm/mach-keystone/clock-k2hk.c b/arch/arm/mach-keystone/clock-k2hk.c deleted file mode 100644 index 2e368910bf..0000000000 --- a/arch/arm/mach-keystone/clock-k2hk.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Keystone2: get clk rate for K2HK - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, <www.ti.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/arch/clock.h> -#include <asm/arch/clock_defs.h> - -/** - * pll_freq_get - get pll frequency - * Fout = Fref * NF(mult) / NR(prediv) / OD - * @pll: pll identifier - */ -static unsigned long pll_freq_get(int pll) -{ - unsigned long mult = 1, prediv = 1, output_div = 2; - unsigned long ret; - u32 tmp, reg; - - if (pll == CORE_PLL) { - ret = external_clk[sys_clk]; - if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { - /* PLL mode */ - tmp = __raw_readl(KS2_MAINPLLCTL0); - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | - (pllctl_reg_read(pll, mult) & - PLLM_MULT_LO_MASK)) + 1; - output_div = ((pllctl_reg_read(pll, secctl) >> - PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; - - ret = ret / prediv / output_div * mult; - } - } else { - switch (pll) { - case PASS_PLL: - ret = external_clk[pa_clk]; - reg = KS2_PASSPLLCTL0; - break; - case TETRIS_PLL: - ret = external_clk[tetris_clk]; - reg = KS2_ARMPLLCTL0; - break; - case DDR3A_PLL: - ret = external_clk[ddr3a_clk]; - reg = KS2_DDR3APLLCTL0; - break; - case DDR3B_PLL: - ret = external_clk[ddr3b_clk]; - reg = KS2_DDR3BPLLCTL0; - break; - default: - return 0; - } - - tmp = __raw_readl(reg); - - if (!(tmp & PLLCTL_BYPASS)) { - /* Bypass disabled */ - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; - output_div = ((tmp >> PLL_CLKOD_SHIFT) & - PLL_CLKOD_MASK) + 1; - ret = ((ret / prediv) * mult) / output_div; - } - } - - return ret; -} - -unsigned long clk_get_rate(unsigned int clk) -{ - switch (clk) { - case core_pll_clk: return pll_freq_get(CORE_PLL); - case pass_pll_clk: return pll_freq_get(PASS_PLL); - case tetris_pll_clk: return pll_freq_get(TETRIS_PLL); - case ddr3a_pll_clk: return pll_freq_get(DDR3A_PLL); - case ddr3b_pll_clk: return pll_freq_get(DDR3B_PLL); - case sys_clk0_1_clk: - case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); - case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); - case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); - case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); - case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; - case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; - case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; - case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; - case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; - case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; - case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; - case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; - case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; - case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; - case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; - default: - break; - } - - return 0; -} diff --git a/arch/arm/mach-keystone/clock-k2l.c b/arch/arm/mach-keystone/clock-k2l.c deleted file mode 100644 index 0004059192..0000000000 --- a/arch/arm/mach-keystone/clock-k2l.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Keystone2: get clk rate for K2L - * - * (C) Copyright 2012-2014 - * Texas Instruments Incorporated, <www.ti.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/arch/clock.h> -#include <asm/arch/clock_defs.h> - -/** - * pll_freq_get - get pll frequency - * Fout = Fref * NF(mult) / NR(prediv) / OD - * @pll: pll identifier - */ -static unsigned long pll_freq_get(int pll) -{ - unsigned long mult = 1, prediv = 1, output_div = 2; - unsigned long ret; - u32 tmp, reg; - - if (pll == CORE_PLL) { - ret = external_clk[sys_clk]; - if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN) { - /* PLL mode */ - tmp = __raw_readl(KS2_MAINPLLCTL0); - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = (((tmp & PLLM_MULT_HI_SMASK) >> 6) | - (pllctl_reg_read(pll, mult) & - PLLM_MULT_LO_MASK)) + 1; - output_div = ((pllctl_reg_read(pll, secctl) >> - PLL_CLKOD_SHIFT) & PLL_CLKOD_MASK) + 1; - - ret = ret / prediv / output_div * mult; - } - } else { - switch (pll) { - case PASS_PLL: - ret = external_clk[pa_clk]; - reg = KS2_PASSPLLCTL0; - break; - case TETRIS_PLL: - ret = external_clk[tetris_clk]; - reg = KS2_ARMPLLCTL0; - break; - case DDR3_PLL: - ret = external_clk[ddr3a_clk]; - reg = KS2_DDR3APLLCTL0; - break; - default: - return 0; - } - - tmp = __raw_readl(reg); - if (!(tmp & PLLCTL_BYPASS)) { - /* Bypass disabled */ - prediv = (tmp & PLL_DIV_MASK) + 1; - mult = ((tmp >> PLL_MULT_SHIFT) & PLL_MULT_MASK) + 1; - output_div = ((tmp >> PLL_CLKOD_SHIFT) & - PLL_CLKOD_MASK) + 1; - ret = ((ret / prediv) * mult) / output_div; - } - } - - return ret; -} - -unsigned long clk_get_rate(unsigned int clk) -{ - switch (clk) { - case core_pll_clk: return pll_freq_get(CORE_PLL); - case pass_pll_clk: return pll_freq_get(PASS_PLL); - case tetris_pll_clk: return pll_freq_get(TETRIS_PLL); - case ddr3_pll_clk: return pll_freq_get(DDR3_PLL); - case sys_clk0_1_clk: - case sys_clk0_clk: return pll_freq_get(CORE_PLL) / pll0div_read(1); - case sys_clk1_clk: return pll_freq_get(CORE_PLL) / pll0div_read(2); - case sys_clk2_clk: return pll_freq_get(CORE_PLL) / pll0div_read(3); - case sys_clk3_clk: return pll_freq_get(CORE_PLL) / pll0div_read(4); - case sys_clk0_2_clk: return clk_get_rate(sys_clk0_clk) / 2; - case sys_clk0_3_clk: return clk_get_rate(sys_clk0_clk) / 3; - case sys_clk0_4_clk: return clk_get_rate(sys_clk0_clk) / 4; - case sys_clk0_6_clk: return clk_get_rate(sys_clk0_clk) / 6; - case sys_clk0_8_clk: return clk_get_rate(sys_clk0_clk) / 8; - case sys_clk0_12_clk: return clk_get_rate(sys_clk0_clk) / 12; - case sys_clk0_24_clk: return clk_get_rate(sys_clk0_clk) / 24; - case sys_clk1_3_clk: return clk_get_rate(sys_clk1_clk) / 3; - case sys_clk1_4_clk: return clk_get_rate(sys_clk1_clk) / 4; - case sys_clk1_6_clk: return clk_get_rate(sys_clk1_clk) / 6; - case sys_clk1_12_clk: return clk_get_rate(sys_clk1_clk) / 12; - default: - break; - } - - return 0; -} diff --git a/arch/arm/mach-keystone/clock.c b/arch/arm/mach-keystone/clock.c index 5c6051e76d..b25db1e3fe 100644 --- a/arch/arm/mach-keystone/clock.c +++ b/arch/arm/mach-keystone/clock.c @@ -228,18 +228,21 @@ void init_plls(void) } } -static int get_max_speed(u32 val, u32 speed_supported) +static int get_max_speed(u32 val, u32 speed_supported, int *spds) { int speed; /* Left most setbit gives the speed */ for (speed = DEVSPEED_NUMSPDS; speed >= 0; speed--) { if ((val & BIT(speed)) & speed_supported) - return speeds[speed]; + return spds[speed]; } - /* If no bit is set, use SPD800 */ - return SPD800; + /* If no bit is set, return minimum speed */ + if (cpu_is_k2g()) + return SPD200; + else + return SPD800; } static inline u32 read_efuse_bootrom(void) @@ -250,24 +253,24 @@ static inline u32 read_efuse_bootrom(void) return __raw_readl(KS2_EFUSE_BOOTROM); } -int get_max_arm_speed(void) +int get_max_arm_speed(int *spds) { u32 armspeed = read_efuse_bootrom(); armspeed = (armspeed & DEVSPEED_ARMSPEED_MASK) >> DEVSPEED_ARMSPEED_SHIFT; - return get_max_speed(armspeed, ARM_SUPPORTED_SPEEDS); + return get_max_speed(armspeed, ARM_SUPPORTED_SPEEDS, spds); } -int get_max_dev_speed(void) +int get_max_dev_speed(int *spds) { u32 devspeed = read_efuse_bootrom(); devspeed = (devspeed & DEVSPEED_DEVSPEED_MASK) >> DEVSPEED_DEVSPEED_SHIFT; - return get_max_speed(devspeed, DEV_SUPPORTED_SPEEDS); + return get_max_speed(devspeed, DEV_SUPPORTED_SPEEDS, spds); } /** diff --git a/arch/arm/mach-keystone/cmd_mon.c b/arch/arm/mach-keystone/cmd_mon.c index a539d5d275..6a9bdc9601 100644 --- a/arch/arm/mach-keystone/cmd_mon.c +++ b/arch/arm/mach-keystone/cmd_mon.c @@ -9,25 +9,9 @@ #include <common.h> #include <command.h> +#include <mach/mon.h> asm(".arch_extension sec\n\t"); -static int mon_install(u32 addr, u32 dpsc, u32 freq) -{ - int result; - - __asm__ __volatile__ ( - "stmfd r13!, {lr}\n" - "mov r0, %1\n" - "mov r1, %2\n" - "mov r2, %3\n" - "blx r0\n" - "ldmfd r13!, {lr}\n" - : "=&r" (result) - : "r" (addr), "r" (dpsc), "r" (freq) - : "cc", "r0", "r1", "r2", "memory"); - return result; -} - static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { @@ -64,39 +48,6 @@ static void core_spin(void) } } -int mon_power_on(int core_id, void *ep) -{ - int result; - - asm volatile ( - "stmfd r13!, {lr}\n" - "mov r1, %1\n" - "mov r2, %2\n" - "mov r0, #0\n" - "smc #0\n" - "ldmfd r13!, {lr}\n" - : "=&r" (result) - : "r" (core_id), "r" (ep) - : "cc", "r0", "r1", "r2", "memory"); - return result; -} - -int mon_power_off(int core_id) -{ - int result; - - asm volatile ( - "stmfd r13!, {lr}\n" - "mov r1, %1\n" - "mov r0, #1\n" - "smc #1\n" - "ldmfd r13!, {lr}\n" - : "=&r" (result) - : "r" (core_id) - : "cc", "r0", "r1", "memory"); - return result; -} - int do_mon_power(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { diff --git a/arch/arm/mach-keystone/cmd_poweroff.c b/arch/arm/mach-keystone/cmd_poweroff.c new file mode 100644 index 0000000000..1b127a8092 --- /dev/null +++ b/arch/arm/mach-keystone/cmd_poweroff.c @@ -0,0 +1,28 @@ +/* + * Keystone EVM : Power off + * + * (C) Copyright 2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <asm/arch/mon.h> +#include <asm/arch/psc_defs.h> +#include <asm/arch/hardware.h> + +int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + mon_power_off(0); + + psc_disable_module(KS2_LPSC_TETRIS); + psc_disable_domain(KS2_TETRIS_PWR_DOMAIN); + + asm volatile ("isb\n" + "dsb\n" + "wfi\n"); + + return 0; +} diff --git a/arch/arm/mach-keystone/ddr3_spd.c b/arch/arm/mach-keystone/ddr3_spd.c new file mode 100644 index 0000000000..c541886787 --- /dev/null +++ b/arch/arm/mach-keystone/ddr3_spd.c @@ -0,0 +1,463 @@ +/* + * Keystone2: DDR3 SPD configuration + * + * (C) Copyright 2015-2016 Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +#include <i2c.h> +#include <ddr_spd.h> +#include <asm/arch/ddr3.h> +#include <asm/arch/hardware.h> + +#define DUMP_DDR_CONFIG 0 /* set to 1 to debug */ +#define debug_ddr_cfg(fmt, args...) \ + debug_cond(DUMP_DDR_CONFIG, fmt, ##args) + +static void dump_phy_config(struct ddr3_phy_config *ptr) +{ + debug_ddr_cfg("\npllcr 0x%08X\n", ptr->pllcr); + debug_ddr_cfg("pgcr1_mask 0x%08X\n", ptr->pgcr1_mask); + debug_ddr_cfg("pgcr1_val 0x%08X\n", ptr->pgcr1_val); + debug_ddr_cfg("ptr0 0x%08X\n", ptr->ptr0); + debug_ddr_cfg("ptr1 0x%08X\n", ptr->ptr1); + debug_ddr_cfg("ptr2 0x%08X\n", ptr->ptr2); + debug_ddr_cfg("ptr3 0x%08X\n", ptr->ptr3); + debug_ddr_cfg("ptr4 0x%08X\n", ptr->ptr4); + debug_ddr_cfg("dcr_mask 0x%08X\n", ptr->dcr_mask); + debug_ddr_cfg("dcr_val 0x%08X\n", ptr->dcr_val); + debug_ddr_cfg("dtpr0 0x%08X\n", ptr->dtpr0); + debug_ddr_cfg("dtpr1 0x%08X\n", ptr->dtpr1); + debug_ddr_cfg("dtpr2 0x%08X\n", ptr->dtpr2); + debug_ddr_cfg("mr0 0x%08X\n", ptr->mr0); + debug_ddr_cfg("mr1 0x%08X\n", ptr->mr1); + debug_ddr_cfg("mr2 0x%08X\n", ptr->mr2); + debug_ddr_cfg("dtcr 0x%08X\n", ptr->dtcr); + debug_ddr_cfg("pgcr2 0x%08X\n", ptr->pgcr2); + debug_ddr_cfg("zq0cr1 0x%08X\n", ptr->zq0cr1); + debug_ddr_cfg("zq1cr1 0x%08X\n", ptr->zq1cr1); + debug_ddr_cfg("zq2cr1 0x%08X\n", ptr->zq2cr1); + debug_ddr_cfg("pir_v1 0x%08X\n", ptr->pir_v1); + debug_ddr_cfg("pir_v2 0x%08X\n\n", ptr->pir_v2); +}; + +static void dump_emif_config(struct ddr3_emif_config *ptr) +{ + debug_ddr_cfg("\nsdcfg 0x%08X\n", ptr->sdcfg); + debug_ddr_cfg("sdtim1 0x%08X\n", ptr->sdtim1); + debug_ddr_cfg("sdtim2 0x%08X\n", ptr->sdtim2); + debug_ddr_cfg("sdtim3 0x%08X\n", ptr->sdtim3); + debug_ddr_cfg("sdtim4 0x%08X\n", ptr->sdtim4); + debug_ddr_cfg("zqcfg 0x%08X\n", ptr->zqcfg); + debug_ddr_cfg("sdrfc 0x%08X\n\n", ptr->sdrfc); +}; + +#define TEMP NORMAL_TEMP +#define VBUS_CLKPERIOD 1.875 /* Corresponds to vbus=533MHz, */ +#define PLLGS_VAL (4000.0 / VBUS_CLKPERIOD) /* 4 us */ +#define PLLPD_VAL (1000.0 / VBUS_CLKPERIOD) /* 1 us */ +#define PLLLOCK_VAL (100000.0 / VBUS_CLKPERIOD) /* 100 us */ +#define PLLRST_VAL (9000.0 / VBUS_CLKPERIOD) /* 9 us */ +#define PHYRST_VAL 0x10 +#define DDR_TERM RZQ_4_TERM +#define SDRAM_DRIVE RZQ_7_IMP +#define DYN_ODT ODT_DISABLE + +enum srt { + NORMAL_TEMP, + EXTENDED_TEMP +}; + +enum out_impedance { + RZQ_6_IMP = 0, + RZQ_7_IMP +}; + +enum die_term { + ODT_DISABLE = 0, + RZQ_4_TERM, + RZQ_2_TERM, + RZQ_6_TERM, + RZQ_12_TERM, + RZQ_8_TERM +}; + +struct ddr3_sodimm { + u32 t_ck; + u32 freqsel; + u32 t_xp; + u32 t_cke; + u32 t_pllpd; + u32 t_pllgs; + u32 t_phyrst; + u32 t_plllock; + u32 t_pllrst; + u32 t_rfc; + u32 t_xs; + u32 t_dinit0; + u32 t_dinit1; + u32 t_dinit2; + u32 t_dinit3; + u32 t_rtp; + u32 t_wtr; + u32 t_rp; + u32 t_rcd; + u32 t_ras; + u32 t_rrd; + u32 t_rc; + u32 t_faw; + u32 t_mrd; + u32 t_mod; + u32 t_wlo; + u32 t_wlmrd; + u32 t_xsdll; + u32 t_xpdll; + u32 t_ckesr; + u32 t_dllk; + u32 t_wr; + u32 t_wr_bin; + u32 cas; + u32 cwl; + u32 asr; + u32 pasr; + u32 t_refprd; + u8 sdram_type; + u8 ibank; + u8 pagesize; + u8 t_rrd2; + u8 t_ras_max; + u8 t_zqcs; + u32 refresh_rate; + u8 t_csta; + + u8 rank; + u8 mirrored; + u8 buswidth; +}; + +static u8 cas_latancy(u16 temp) +{ + int loop; + u8 cas_bin = 0; + + for (loop = 0; loop < 32; loop += 2, temp >>= 1) { + if (temp & 0x0001) + cas_bin = (loop > 15) ? loop - 15 : loop; + } + + return cas_bin; +} + +static int ddr3_get_size_in_mb(ddr3_spd_eeprom_t *buf) +{ + return (((buf->organization & 0x38) >> 3) + 1) * + (256 << (buf->density_banks & 0xf)); +} + +static int ddrtimingcalculation(ddr3_spd_eeprom_t *buf, struct ddr3_sodimm *spd, + struct ddr3_spd_cb *spd_cb) +{ + u32 mtb, clk_freq; + + if ((buf->mem_type != 0x0b) || + ((buf->density_banks & 0x70) != 0x00)) + return 1; + + spd->sdram_type = 0x03; + spd->ibank = 0x03; + + mtb = buf->mtb_dividend * 1000 / buf->mtb_divisor; + + spd->t_ck = buf->tck_min * mtb; + + spd_cb->ddrspdclock = 2000000 / spd->t_ck; + clk_freq = spd_cb->ddrspdclock / 2; + + spd->rank = ((buf->organization & 0x38) >> 3) + 1; + if (spd->rank > 2) + return 1; + + spd->pagesize = (buf->addressing & 0x07) + 1; + if (spd->pagesize > 3) + return 1; + + spd->buswidth = 8 << (buf->bus_width & 0x7); + if ((spd->buswidth < 16) || (spd->buswidth > 64)) + return 1; + + spd->mirrored = buf->mod_section.unbuffered.addr_mapping & 1; + + printf("DDR3A Speed will be configured for %d Operation.\n", + spd_cb->ddrspdclock); + if (spd_cb->ddrspdclock == 1333) { + spd->t_xp = ((3 * spd->t_ck) > 6000) ? + 3 : ((5999 / spd->t_ck) + 1); + spd->t_cke = ((3 * spd->t_ck) > 5625) ? + 3 : ((5624 / spd->t_ck) + 1); + } else if (spd_cb->ddrspdclock == 1600) { + spd->t_xp = ((3 * spd->t_ck) > 6000) ? + 3 : ((5999 / spd->t_ck) + 1); + spd->t_cke = ((3 * spd->t_ck) > 5000) ? + 3 : ((4999 / spd->t_ck) + 1); + } else { + printf("Unsupported DDR3 speed %d\n", spd_cb->ddrspdclock); + return 1; + } + + spd->t_xpdll = (spd->t_ck > 2400) ? 10 : 24000 / spd->t_ck; + spd->t_ckesr = spd->t_cke + 1; + + /* SPD Calculated Values */ + spd->cas = cas_latancy((buf->caslat_msb << 8) | + buf->caslat_lsb); + + spd->t_wr = (buf->twr_min * mtb) / spd->t_ck; + spd->t_wr_bin = (spd->t_wr / 2) & 0x07; + + spd->t_rcd = ((buf->trcd_min * mtb) - 1) / spd->t_ck + 1; + spd->t_rrd = ((buf->trrd_min * mtb) - 1) / spd->t_ck + 1; + spd->t_rp = (((buf->trp_min * mtb) - 1) / spd->t_ck) + 1; + + spd->t_ras = (((buf->tras_trc_ext & 0x0f) << 8 | buf->tras_min_lsb) * + mtb) / spd->t_ck; + + spd->t_rc = (((((buf->tras_trc_ext & 0xf0) << 4) | buf->trc_min_lsb) * + mtb) - 1) / spd->t_ck + 1; + + spd->t_rfc = (buf->trfc_min_lsb | (buf->trfc_min_msb << 8)) * mtb / + 1000; + spd->t_wtr = (buf->twtr_min * mtb) / spd->t_ck; + spd->t_rtp = (buf->trtp_min * mtb) / spd->t_ck; + + spd->t_xs = (((spd->t_rfc + 10) * 1000) / spd->t_ck); + spd->t_rfc = ((spd->t_rfc * 1000) - 1) / spd->t_ck + 1; + + spd->t_faw = (((buf->tfaw_msb << 8) | buf->tfaw_min) * mtb) / spd->t_ck; + spd->t_rrd2 = ((((buf->tfaw_msb << 8) | + buf->tfaw_min) * mtb) / (4 * spd->t_ck)) - 1; + + /* Hard-coded values */ + spd->t_mrd = 0x00; + spd->t_mod = 0x00; + spd->t_wlo = 0x0C; + spd->t_wlmrd = 0x28; + spd->t_xsdll = 0x200; + spd->t_ras_max = 0x0F; + spd->t_csta = 0x05; + spd->t_dllk = 0x200; + + /* CAS Write Latency */ + if (spd->t_ck >= 2500) + spd->cwl = 0; + else if (spd->t_ck >= 1875) + spd->cwl = 1; + else if (spd->t_ck >= 1500) + spd->cwl = 2; + else if (spd->t_ck >= 1250) + spd->cwl = 3; + else if (spd->t_ck >= 1071) + spd->cwl = 4; + else + spd->cwl = 5; + + /* SD:RAM Thermal and Refresh Options */ + spd->asr = (buf->therm_ref_opt & 0x04) >> 2; + spd->pasr = (buf->therm_ref_opt & 0x80) >> 7; + spd->t_zqcs = 64; + + spd->t_refprd = (TEMP == NORMAL_TEMP) ? 7812500 : 3906250; + spd->t_refprd = spd->t_refprd / spd->t_ck; + + spd->refresh_rate = spd->t_refprd; + spd->t_refprd = spd->t_refprd * 5; + + /* Set MISC PHY space registers fields */ + if ((clk_freq / 2) >= 166 && (clk_freq / 2 < 275)) + spd->freqsel = 0x03; + else if ((clk_freq / 2) > 225 && (clk_freq / 2 < 385)) + spd->freqsel = 0x01; + else if ((clk_freq / 2) > 335 && (clk_freq / 2 < 534)) + spd->freqsel = 0x00; + + spd->t_dinit0 = 500000000 / spd->t_ck; /* CKE low time 500 us */ + spd->t_dinit1 = spd->t_xs; + spd->t_dinit2 = 200000000 / spd->t_ck; /* Reset low time 200 us */ + /* Time from ZQ initialization command to first command (1 us) */ + spd->t_dinit3 = 1000000 / spd->t_ck; + + spd->t_pllgs = PLLGS_VAL + 1; + spd->t_pllpd = PLLPD_VAL + 1; + spd->t_plllock = PLLLOCK_VAL + 1; + spd->t_pllrst = PLLRST_VAL; + spd->t_phyrst = PHYRST_VAL; + + spd_cb->ddr_size_gbyte = ddr3_get_size_in_mb(buf) / 1024; + + return 0; +} + +static void init_ddr3param(struct ddr3_spd_cb *spd_cb, + struct ddr3_sodimm *spd) +{ + spd_cb->phy_cfg.pllcr = (spd->freqsel & 3) << 18 | 0xE << 13; + spd_cb->phy_cfg.pgcr1_mask = (IODDRM_MASK | ZCKSEL_MASK); + spd_cb->phy_cfg.pgcr1_val = ((1 << 2) | (1 << 7) | (1 << 23)); + spd_cb->phy_cfg.ptr0 = ((spd->t_pllpd & 0x7ff) << 21) | + ((spd->t_pllgs & 0x7fff) << 6) | (spd->t_phyrst & 0x3f); + spd_cb->phy_cfg.ptr1 = ((spd->t_plllock & 0xffff) << 16) | + (spd->t_pllrst & 0x1fff); + spd_cb->phy_cfg.ptr2 = 0; + spd_cb->phy_cfg.ptr3 = ((spd->t_dinit1 & 0x1ff) << 20) | + (spd->t_dinit0 & 0xfffff); + spd_cb->phy_cfg.ptr4 = ((spd->t_dinit3 & 0x3ff) << 18) | + (spd->t_dinit2 & 0x3ffff); + + spd_cb->phy_cfg.dcr_mask = PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK; + spd_cb->phy_cfg.dcr_val = 1 << 10; + + if (spd->mirrored) { + spd_cb->phy_cfg.dcr_mask |= NOSRA_MASK | UDIMM_MASK; + spd_cb->phy_cfg.dcr_val |= (1 << 27) | (1 << 29); + } + + spd_cb->phy_cfg.dtpr0 = (spd->t_rc & 0x3f) << 26 | + (spd->t_rrd & 0xf) << 22 | + (spd->t_ras & 0x3f) << 16 | (spd->t_rcd & 0xf) << 12 | + (spd->t_rp & 0xf) << 8 | (spd->t_wtr & 0xf) << 4 | + (spd->t_rtp & 0xf); + spd_cb->phy_cfg.dtpr1 = (spd->t_wlo & 0xf) << 26 | + (spd->t_wlmrd & 0x3f) << 20 | (spd->t_rfc & 0x1ff) << 11 | + (spd->t_faw & 0x3f) << 5 | (spd->t_mod & 0x7) << 2 | + (spd->t_mrd & 0x3); + + spd_cb->phy_cfg.dtpr2 = 0 << 31 | 1 << 30 | 0 << 29 | + (spd->t_dllk & 0x3ff) << 19 | (spd->t_ckesr & 0xf) << 15; + + spd_cb->phy_cfg.dtpr2 |= (((spd->t_xp > spd->t_xpdll) ? + spd->t_xp : spd->t_xpdll) & + 0x1f) << 10; + + spd_cb->phy_cfg.dtpr2 |= (((spd->t_xs > spd->t_xsdll) ? + spd->t_xs : spd->t_xsdll) & + 0x3ff); + + spd_cb->phy_cfg.mr0 = 1 << 12 | (spd->t_wr_bin & 0x7) << 9 | 0 << 8 | + 0 << 7 | ((spd->cas & 0x0E) >> 1) << 4 | 0 << 3 | + (spd->cas & 0x01) << 2; + + spd_cb->phy_cfg.mr1 = 0 << 12 | 0 << 11 | 0 << 7 | 0 << 3 | + ((DDR_TERM >> 2) & 1) << 9 | ((DDR_TERM >> 1) & 1) << 6 | + (DDR_TERM & 0x1) << 2 | ((SDRAM_DRIVE >> 1) & 1) << 5 | + (SDRAM_DRIVE & 1) << 1 | 0 << 0; + + spd_cb->phy_cfg.mr2 = DYN_ODT << 9 | TEMP << 7 | (spd->asr & 1) << 6 | + (spd->cwl & 7) << 3 | (spd->pasr & 7); + + spd_cb->phy_cfg.dtcr = (spd->rank == 2) ? 0x730035C7 : 0x710035C7; + spd_cb->phy_cfg.pgcr2 = (0xF << 20) | ((int)spd->t_refprd & 0x3ffff); + + spd_cb->phy_cfg.zq0cr1 = 0x0000005D; + spd_cb->phy_cfg.zq1cr1 = 0x0000005B; + spd_cb->phy_cfg.zq2cr1 = 0x0000005B; + + spd_cb->phy_cfg.pir_v1 = 0x00000033; + spd_cb->phy_cfg.pir_v2 = 0x0000FF81; + + /* EMIF Registers */ + spd_cb->emif_cfg.sdcfg = spd->sdram_type << 29 | (DDR_TERM & 7) << 25 | + (DYN_ODT & 3) << 22 | (spd->cwl & 0x7) << 14 | + (spd->cas & 0xf) << 8 | (spd->ibank & 3) << 5 | + (spd->buswidth & 3) << 12 | (spd->pagesize & 3); + + if (spd->rank == 2) + spd_cb->emif_cfg.sdcfg |= 1 << 3; + + spd_cb->emif_cfg.sdtim1 = ((spd->t_wr - 1) & 0x1f) << 25 | + ((spd->t_ras - 1) & 0x7f) << 18 | + ((spd->t_rc - 1) & 0xff) << 10 | + (spd->t_rrd2 & 0x3f) << 4 | + ((spd->t_wtr - 1) & 0xf); + + spd_cb->emif_cfg.sdtim2 = 0x07 << 10 | ((spd->t_rp - 1) & 0x1f) << 5 | + ((spd->t_rcd - 1) & 0x1f); + + spd_cb->emif_cfg.sdtim3 = ((spd->t_xp - 2) & 0xf) << 28 | + ((spd->t_xs - 1) & 0x3ff) << 18 | + ((spd->t_xsdll - 1) & 0x3ff) << 8 | + ((spd->t_rtp - 1) & 0xf) << 4 | ((spd->t_cke) & 0xf); + + spd_cb->emif_cfg.sdtim4 = (spd->t_csta & 0xf) << 28 | + ((spd->t_ckesr - 1) & 0xf) << 24 | + ((spd->t_zqcs - 1) & 0xff) << 16 | + ((spd->t_rfc - 1) & 0x3ff) << 4 | + (spd->t_ras_max & 0xf); + + spd_cb->emif_cfg.sdrfc = (spd->refresh_rate - 1) & 0xffff; + + /* TODO zqcfg value fixed ,May be required correction for K2E evm. */ + spd_cb->emif_cfg.zqcfg = (spd->rank == 2) ? 0xF0073200 : 0x70073200; +} + +static int ddr3_read_spd(ddr3_spd_eeprom_t *spd_params) +{ + int ret; + int old_bus; + + i2c_init(CONFIG_SYS_DAVINCI_I2C_SPEED, CONFIG_SYS_DAVINCI_I2C_SLAVE); + + old_bus = i2c_get_bus_num(); + i2c_set_bus_num(1); + + ret = i2c_read(0x53, 0, 1, (unsigned char *)spd_params, 256); + + i2c_set_bus_num(old_bus); + + if (ret) { + printf("Cannot read DIMM params\n"); + return 1; + } + + if (ddr3_spd_check(spd_params)) + return 1; + + return 0; +} + +int ddr3_get_size(void) +{ + ddr3_spd_eeprom_t spd_params; + + if (ddr3_read_spd(&spd_params)) + return 0; + + return ddr3_get_size_in_mb(&spd_params) / 1024; +} + +int ddr3_get_dimm_params_from_spd(struct ddr3_spd_cb *spd_cb) +{ + struct ddr3_sodimm spd; + ddr3_spd_eeprom_t spd_params; + + memset(&spd, 0, sizeof(spd)); + + if (ddr3_read_spd(&spd_params)) + return 1; + + if (ddrtimingcalculation(&spd_params, &spd, spd_cb)) { + printf("Timing caclulation error\n"); + return 1; + } + + strncpy(spd_cb->dimm_name, (char *)spd_params.mpart, 18); + spd_cb->dimm_name[18] = '\0'; + + init_ddr3param(spd_cb, &spd); + + dump_emif_config(&spd_cb->emif_cfg); + dump_phy_config(&spd_cb->phy_cfg); + + return 0; +} diff --git a/arch/arm/mach-keystone/include/mach/clock-k2g.h b/arch/arm/mach-keystone/include/mach/clock-k2g.h index 214c1d3a83..74de6202fe 100644 --- a/arch/arm/mach-keystone/include/mach/clock-k2g.h +++ b/arch/arm/mach-keystone/include/mach/clock-k2g.h @@ -12,8 +12,8 @@ #define PLLSET_CMD_LIST "<pa|arm|ddr3>" -#define DEV_SUPPORTED_SPEEDS 0xfff -#define ARM_SUPPORTED_SPEEDS 0xfff +#define DEV_SUPPORTED_SPEEDS 0x1ff +#define ARM_SUPPORTED_SPEEDS 0xff #define KS2_CLK1_6 sys_clk0_6_clk diff --git a/arch/arm/mach-keystone/include/mach/clock.h b/arch/arm/mach-keystone/include/mach/clock.h index cdcff3baee..72724aa4a9 100644 --- a/arch/arm/mach-keystone/include/mach/clock.h +++ b/arch/arm/mach-keystone/include/mach/clock.h @@ -63,8 +63,12 @@ #define CLOCK_INDEXES_LIST CLK_LIST(GENERATE_INDX_STR) enum { + SPD200, + SPD400, + SPD600, SPD800, SPD850, + SPD900, SPD1000, SPD1200, SPD1250, @@ -124,8 +128,8 @@ struct pll_init_data *get_pll_init_data(int pll); unsigned long clk_get_rate(unsigned int clk); unsigned long clk_round_rate(unsigned int clk, unsigned long hz); int clk_set_rate(unsigned int clk, unsigned long hz); -int get_max_dev_speed(void); -int get_max_arm_speed(void); +int get_max_dev_speed(int *spds); +int get_max_arm_speed(int *spds); void pll_pa_clk_sel(void); #endif diff --git a/arch/arm/mach-keystone/include/mach/ddr3.h b/arch/arm/mach-keystone/include/mach/ddr3.h index a22c237c80..5feffe825b 100644 --- a/arch/arm/mach-keystone/include/mach/ddr3.h +++ b/arch/arm/mach-keystone/include/mach/ddr3.h @@ -48,6 +48,14 @@ struct ddr3_emif_config { unsigned int sdrfc; }; +struct ddr3_spd_cb { + char dimm_name[32]; + struct ddr3_phy_config phy_cfg; + struct ddr3_emif_config emif_cfg; + unsigned int ddrspdclock; + int ddr_size_gbyte; +}; + u32 ddr3_init(void); void ddr3_reset_ddrphy(void); void ddr3_init_ecc(u32 base, u32 ddr3_size); @@ -58,5 +66,6 @@ void ddr3_err_reset_workaround(void); void ddr3_enable_ecc(u32 base, int test); void ddr3_init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg); void ddr3_init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg); +int ddr3_get_size(void); #endif diff --git a/arch/arm/mach-keystone/include/mach/hardware-k2g.h b/arch/arm/mach-keystone/include/mach/hardware-k2g.h index fa4162fe99..ca2a119d39 100644 --- a/arch/arm/mach-keystone/include/mach/hardware-k2g.h +++ b/arch/arm/mach-keystone/include/mach/hardware-k2g.h @@ -10,7 +10,7 @@ #ifndef __ASM_ARCH_HARDWARE_K2G_H #define __ASM_ARCH_HARDWARE_K2G_H -#define KS2_NUM_DSPS 0 +#define KS2_NUM_DSPS 1 /* Power and Sleep Controller (PSC) Domains */ #define KS2_LPSC_ALWAYSON 0 @@ -30,7 +30,10 @@ #define KS2_LPSC_MCASP 15 #define KS2_LPSC_SR 16 #define KS2_LPSC_MSMC 17 -#define KS2_LPSC_GEM 18 +#ifdef KS2_LPSC_GEM_0 +#undef KS2_LPSC_GEM_0 +#endif +#define KS2_LPSC_GEM_0 18 #define KS2_LPSC_ARM 19 #define KS2_LPSC_ASRC 20 #define KS2_LPSC_ICSS 21 diff --git a/arch/arm/mach-keystone/include/mach/hardware-k2l.h b/arch/arm/mach-keystone/include/mach/hardware-k2l.h index 4f1197ea92..a59e071359 100644 --- a/arch/arm/mach-keystone/include/mach/hardware-k2l.h +++ b/arch/arm/mach-keystone/include/mach/hardware-k2l.h @@ -105,4 +105,11 @@ /* NETCP */ #define KS2_NETCP_BASE 0x26000000 +#ifndef __ASSEMBLY__ +static inline int ddr3_get_size(void) +{ + return 2; +} +#endif + #endif /* __ASM_ARCH_HARDWARE_K2L_H */ diff --git a/arch/arm/mach-keystone/include/mach/hardware.h b/arch/arm/mach-keystone/include/mach/hardware.h index edebcd7bc5..8ca19bbcdb 100644 --- a/arch/arm/mach-keystone/include/mach/hardware.h +++ b/arch/arm/mach-keystone/include/mach/hardware.h @@ -160,6 +160,7 @@ typedef volatile unsigned int *dv_reg_p; #define KS2_LPSC_GEM_0 15 #define KS2_LPSC_TETRIS 52 #define KS2_TETRIS_PWR_DOMAIN 31 +#define KS2_GEM_0_PWR_DOMAIN 8 /* Chip configuration unlock codes and registers */ #define KS2_KICK0 (KS2_DEVICE_STATE_CTRL_BASE + 0x38) diff --git a/arch/arm/mach-keystone/include/mach/mon.h b/arch/arm/mach-keystone/include/mach/mon.h index 33a28764bc..eb7aa938af 100644 --- a/arch/arm/mach-keystone/include/mach/mon.h +++ b/arch/arm/mach-keystone/include/mach/mon.h @@ -7,9 +7,11 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#ifndef _MON_H_ -#define _MON_H_ +#ifndef _MACH_MON_H_ +#define _MACH_MON_H_ +int mon_install(u32 addr, u32 dpsc, u32 freq); +int mon_power_on(int core_id, void *ep); int mon_power_off(int core_id); #endif diff --git a/arch/arm/mach-keystone/include/mach/psc_defs.h b/arch/arm/mach-keystone/include/mach/psc_defs.h index 70d22cf217..6e6e7fd433 100644 --- a/arch/arm/mach-keystone/include/mach/psc_defs.h +++ b/arch/arm/mach-keystone/include/mach/psc_defs.h @@ -30,9 +30,9 @@ #define BOOTBITMASK(x, y) ((((((u32)1 << (((u32)x) - ((u32)y) + (u32)1)) - \ (u32)1)) << ((u32)y))) -#define BOOT_READ_BITFIELD(z, x, y) (((u32)z) & BOOTBITMASK(x, y)) >> (y) -#define BOOT_SET_BITFIELD(z, f, x, y) (((u32)z) & ~BOOTBITMASK(x, y)) | \ - ((((u32)f) << (y)) & BOOTBITMASK(x, y)) +#define BOOT_READ_BITFIELD(z, x, y) ((((u32)z) & BOOTBITMASK(x, y)) >> (y)) +#define BOOT_SET_BITFIELD(z, f, x, y) ((((u32)z) & ~BOOTBITMASK(x, y)) | \ + ((((u32)f) << (y)) & BOOTBITMASK(x, y))) /* PDCTL */ #define PSC_REG_PDCTL_SET_NEXT(x, y) BOOT_SET_BITFIELD((x), (y), 0, 0) @@ -56,6 +56,8 @@ #define PSC_REG_MDSTAT_GET_STATUS(x) BOOT_READ_BITFIELD((x), 5, 0) #define PSC_REG_MDSTAT_GET_LRSTZ(x) BOOT_READ_BITFIELD((x), 8, 8) #define PSC_REG_MDSTAT_GET_LRSTDONE(x) BOOT_READ_BITFIELD((x), 9, 9) +#define PSC_REG_MDSTAT_GET_MRSTZ(x) BOOT_READ_BITFIELD((x), 10, 10) +#define PSC_REG_MDSTAT_GET_MRSTDONE(x) BOOT_READ_BITFIELD((x), 11, 11) /* PDCTL states */ #define PSC_REG_VAL_PDCTL_NEXT_ON 1 @@ -86,5 +88,7 @@ u32 psc_get_domain_num(u32 mod_num); int psc_enable_module(u32 mod_num); int psc_disable_module(u32 mod_num); int psc_disable_domain(u32 domain_num); +int psc_module_keep_in_reset_enabled(u32 mod_num, bool gate_clocks); +int psc_module_release_from_reset(u32 mod_num); #endif /* _PSC_DEFS_H_ */ diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c index 11a9357db4..beb8a767c4 100644 --- a/arch/arm/mach-keystone/keystone.c +++ b/arch/arm/mach-keystone/keystone.c @@ -9,10 +9,8 @@ #include <common.h> #include <asm/io.h> -#include <asm/arch/mon.h> #include <asm/arch/psc_defs.h> #include <asm/arch/hardware.h> -#include <asm/arch/hardware.h> /** * cpu_to_bus - swap bytes of the 32-bit data if the device is BE @@ -30,22 +28,6 @@ int cpu_to_bus(u32 *ptr, u32 length) return 0; } -static int turn_off_myself(void) -{ - printf("Turning off ourselves\r\n"); - mon_power_off(0); - - psc_disable_module(KS2_LPSC_TETRIS); - psc_disable_domain(KS2_TETRIS_PWR_DOMAIN); - - asm volatile ("isb\n" - "dsb\n" - "wfi\n"); - - printf("What! Should not see that\n"); - return 0; -} - static void turn_off_all_dsps(int num_dsps) { int i; @@ -54,22 +36,11 @@ static void turn_off_all_dsps(int num_dsps) if (psc_disable_module(i + KS2_LPSC_GEM_0)) printf("Cannot disable module for #%d DSP", i); - if (psc_disable_domain(i + 8)) + if (psc_disable_domain(i + KS2_GEM_0_PWR_DOMAIN)) printf("Cannot disable domain for #%d DSP", i); } } -int do_killme_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - return turn_off_myself(); -} - -U_BOOT_CMD( - killme, 1, 0, do_killme_cmd, - "turn off main ARM core", - "turn off main ARM core. Should not live after that :(\n" -); - int misc_init_r(void) { char *env; diff --git a/arch/arm/mach-keystone/mon.c b/arch/arm/mach-keystone/mon.c new file mode 100644 index 0000000000..256f6300ed --- /dev/null +++ b/arch/arm/mach-keystone/mon.c @@ -0,0 +1,63 @@ +/* + * K2HK: secure kernel command file + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <mach/mon.h> +asm(".arch_extension sec\n\t"); + +int mon_install(u32 addr, u32 dpsc, u32 freq) +{ + int result; + + __asm__ __volatile__ ( + "stmfd r13!, {lr}\n" + "mov r0, %1\n" + "mov r1, %2\n" + "mov r2, %3\n" + "blx r0\n" + "ldmfd r13!, {lr}\n" + : "=&r" (result) + : "r" (addr), "r" (dpsc), "r" (freq) + : "cc", "r0", "r1", "r2", "memory"); + return result; +} + +int mon_power_on(int core_id, void *ep) +{ + int result; + + asm volatile ( + "stmfd r13!, {lr}\n" + "mov r1, %1\n" + "mov r2, %2\n" + "mov r0, #0\n" + "smc #0\n" + "ldmfd r13!, {lr}\n" + : "=&r" (result) + : "r" (core_id), "r" (ep) + : "cc", "r0", "r1", "r2", "memory"); + return result; +} + +int mon_power_off(int core_id) +{ + int result; + + asm volatile ( + "stmfd r13!, {lr}\n" + "mov r1, %1\n" + "mov r0, #1\n" + "smc #1\n" + "ldmfd r13!, {lr}\n" + : "=&r" (result) + : "r" (core_id) + : "cc", "r0", "r1", "memory"); + return result; +} diff --git a/arch/arm/mach-keystone/psc.c b/arch/arm/mach-keystone/psc.c index 237e776e87..ff042a6db2 100644 --- a/arch/arm/mach-keystone/psc.c +++ b/arch/arm/mach-keystone/psc.c @@ -13,24 +13,27 @@ #include <asm/processor.h> #include <asm/arch/psc_defs.h> +/** + * psc_delay() - delay for psc + * + * Return: 10 + */ int psc_delay(void) { udelay(10); return 10; } -/* - * FUNCTION PURPOSE: Wait for end of transitional state - * - * DESCRIPTION: Polls pstat for the selected domain and waits for transitions - * to be complete. +/** + * psc_wait() - Wait for end of transitional state + * @domain_num: GPSC domain number * - * Since this is boot loader code it is *ASSUMED* that interrupts - * are disabled and no other core is mucking around with the psc - * at the same time. + * Polls pstat for the selected domain and waits for transitions to be complete. + * Since this is boot loader code it is *ASSUMED* that interrupts are disabled + * and no other core is mucking around with the psc at the same time. * - * Returns 0 when the domain is free. Returns -1 if a timeout - * occurred waiting for the completion. + * Return: 0 when the domain is free. Returns -1 if a timeout occurred waiting + * for the completion. */ int psc_wait(u32 domain_num) { @@ -59,6 +62,10 @@ int psc_wait(u32 domain_num) return 0; } +/** + * psc_get_domain_num() - Get the domain number + * @mod_num: LPSC module number + */ u32 psc_get_domain_num(u32 mod_num) { u32 domain_num; @@ -70,20 +77,19 @@ u32 psc_get_domain_num(u32 mod_num) return domain_num; } -/* - * FUNCTION PURPOSE: Power up/down a module - * - * DESCRIPTION: Powers up/down the requested module and the associated power - * domain if required. No action is taken it the module is - * already powered up/down. +/** + * psc_set_state() - powers up/down a module + * @mod_num: LPSC module number + * @state: 1 to enable, 0 to disable. * - * This only controls modules. The domain in which the module - * resides will be left in the power on state. Multiple modules - * can exist in a power domain, so powering down the domain based - * on a single module is not done. + * Powers up/down the requested module and the associated power domain if + * required. No action is taken it the module is already powered up/down. + * This only controls modules. The domain in which the module resides will + * be left in the power on state. Multiple modules can exist in a power + * domain, so powering down the domain based on a single module is not done. * - * Returns 0 on success, -1 if the module can't be powered up, or - * if there is a timeout waiting for the transition. + * Return: 0 on success, -1 if the module can't be powered up, or if there is a + * timeout waiting for the transition. */ int psc_set_state(u32 mod_num, u32 state) { @@ -136,15 +142,16 @@ int psc_set_state(u32 mod_num, u32 state) return psc_wait(domain_num); } -/* - * FUNCTION PURPOSE: Power up a module +/** + * psc_enable_module() - power up a module + * @mod_num: LPSC module number + * + * Powers up the requested module and the associated power domain + * if required. No action is taken it the module is already powered up. * - * DESCRIPTION: Powers up the requested module and the associated power domain - * if required. No action is taken it the module is already - * powered up. + * Return: 0 on success, -1 if the module can't be powered up, or + * if there is a timeout waiting for the transition. * - * Returns 0 on success, -1 if the module can't be powered up, or - * if there is a timeout waiting for the transition. */ int psc_enable_module(u32 mod_num) { @@ -158,12 +165,11 @@ int psc_enable_module(u32 mod_num) return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_ON); } -/* - * FUNCTION PURPOSE: Power down a module +/** + * psc_disable_module() - Power down a module + * @mod_num: LPSC module number * - * DESCRIPTION: Powers down the requested module. - * - * Returns 0 on success, -1 on failure or timeout. + * Return: 0 on success, -1 on failure or timeout. */ int psc_disable_module(u32 mod_num) { @@ -179,13 +185,16 @@ int psc_disable_module(u32 mod_num) return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE); } -/* - * FUNCTION PURPOSE: Set the reset isolation bit in mdctl +/** + * psc_set_reset_iso() - Set the reset isolation bit in mdctl + * @mod_num: LPSC module number + * + * The reset isolation enable bit is set. The state of the module is not + * changed. * - * DESCRIPTION: The reset isolation enable bit is set. The state of the module - * is not changed. Returns 0 if the module config showed that - * reset isolation is supported. Returns 1 otherwise. This is not - * an error, but setting the bit in mdctl has no effect. + * Return: 0 if the module config showed that reset isolation is supported. + * Returns 1 otherwise. This is not an error, but setting the bit in mdctl + * has no effect. */ int psc_set_reset_iso(u32 mod_num) { @@ -204,10 +213,9 @@ int psc_set_reset_iso(u32 mod_num) return 1; } -/* - * FUNCTION PURPOSE: Disable a power domain - * - * DESCRIPTION: The power domain is disabled +/** + * psc_disable_domain() - Disable a power domain + * @domain_num: GPSC domain number */ int psc_disable_domain(u32 domain_num) { @@ -225,3 +233,107 @@ int psc_disable_domain(u32 domain_num) return psc_wait(domain_num); } + +/** + * psc_module_keep_in_reset_enabled() - Keep module in enabled,in-reset state + * @mod_num: LPSC module number + * @gate_clocks: Can the clocks be gated on this module? + * + * Enable the module, but do not release the module from local reset. This is + * necessary for many processor systems on keystone SoCs to allow for system + * initialization from a master processor prior to releasing the processor + * from reset. + */ +int psc_module_keep_in_reset_enabled(u32 mod_num, bool gate_clocks) +{ + u32 mdctl, ptcmd, mdstat; + u32 next_state; + int domain_num = psc_get_domain_num(mod_num); + int timeout = 100000; + + /* Wait for any previous transitions to complete */ + psc_wait(domain_num); + mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); + /* Should be set 0 to assert Local reset */ + if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1))) { + mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0); + __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); + /* Wait for transition to take place */ + psc_wait(domain_num); + } + + /* Clear Module reset */ + mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); + next_state = gate_clocks ? PSC_REG_VAL_MDCTL_NEXT_OFF : + PSC_REG_VAL_MDCTL_NEXT_ON; + mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, next_state); + __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); + /* Trigger PD transition */ + ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD); + ptcmd |= (u32)(1 << domain_num); + __raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD); + psc_wait(domain_num); + + mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num)); + while (timeout) { + mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num)); + + if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) && + PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) && + PSC_REG_MDSTAT_GET_LRSTDONE(mdstat)) + break; + timeout--; + } + + if (!timeout) { + printf("%s: Timedout waiting for mdstat(0x%08x) to change\n", + __func__, mdstat); + return -ETIMEDOUT; + } + return 0; +} + +/** + * psc_module_release_from_reset() - Release the module from reset + * @mod_num: LPSC module number + * + * This is the follow through for the command 'psc_module_keep_in_reset_enabled' + * Allowing the module to be released from reset once all required inits are + * complete for the module. Typically, this allows the processor module to start + * execution. + */ +int psc_module_release_from_reset(u32 mod_num) +{ + u32 mdctl, mdstat; + int domain_num = psc_get_domain_num(mod_num); + int timeout = 100000; + + /* Wait for any previous transitions to complete */ + psc_wait(domain_num); + mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); + /* Should be set to 1 to de-assert Local reset */ + if ((mdctl & PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0))) { + mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 1); + __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num)); + /* Wait for transition to take place */ + psc_wait(domain_num); + } + mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num)); + while (timeout) { + mdstat = __raw_readl(KS2_PSC_BASE + PSC_REG_MDSTAT(mod_num)); + + if (!(PSC_REG_MDSTAT_GET_STATUS(mdstat) & 0x30) && + PSC_REG_MDSTAT_GET_MRSTDONE(mdstat) && + PSC_REG_MDSTAT_GET_LRSTDONE(mdstat)) + break; + timeout--; + } + + if (!timeout) { + printf("%s: Timedout waiting for mdstat(0x%08x) to change\n", + __func__, mdstat); + return -ETIMEDOUT; + } + + return 0; +} diff --git a/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c b/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c index e3ca870074..ec8305cff8 100644 --- a/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c +++ b/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c @@ -37,7 +37,7 @@ struct rk3036_sdram_priv { /* use integer mode, 396MHz dpll setting * refdiv, fbdiv, postdiv1, postdiv2 */ -const struct pll_div dpll_init_cfg = {1, 66, 4, 1}; +const struct pll_div dpll_init_cfg = {1, 50, 3, 1}; /* 396Mhz ddr timing */ const struct rk3036_ddr_timing ddr_timing = {0x18c, diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c index 6a54368fe3..e133cca57a 100644 --- a/arch/arm/mach-rockchip/rk3288-board-spl.c +++ b/arch/arm/mach-rockchip/rk3288-board-spl.c @@ -114,7 +114,7 @@ static void configure_l2ctlr(void) #ifdef CONFIG_SPL_MMC_SUPPORT static int configure_emmc(struct udevice *pinctrl) { -#ifndef CONFIG_TARGET_ROCK2 +#if !defined(CONFIG_TARGET_ROCK2) && !defined(CONFIG_TARGET_FIREFLY_RK3288) struct gpio_desc desc; int ret; diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c index e9e2211c82..71330cb26d 100644 --- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c @@ -561,14 +561,14 @@ static void dram_all_config(const struct dram_info *dram, &sdram_params->ch[chan]; sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan); - sys_reg |= chan << SYS_REG_CHINFO_SHIFT(chan); + sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(chan); sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan); sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan); - sys_reg |= info->bk == 3 ? 1 << SYS_REG_BK_SHIFT(chan) : 0; + sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(chan); sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan); sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan); - sys_reg |= info->bw << SYS_REG_BW_SHIFT(chan); - sys_reg |= info->dbw << SYS_REG_DBW_SHIFT(chan); + sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(chan); + sys_reg |= (2 >>info->dbw) << SYS_REG_DBW_SHIFT(chan); dram_cfg_rbc(&dram->chan[chan], chan, sdram_params); } @@ -720,13 +720,13 @@ size_t sdram_size_mb(struct rk3288_pmu *pmu) rank = 1 + (sys_reg >> SYS_REG_RANK_SHIFT(ch) & SYS_REG_RANK_MASK); col = 9 + (sys_reg >> SYS_REG_COL_SHIFT(ch) & SYS_REG_COL_MASK); - bk = sys_reg & (1 << SYS_REG_BK_SHIFT(ch)) ? 3 : 0; + bk = 3 - ((sys_reg >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK) ; cs0_row = 13 + (sys_reg >> SYS_REG_CS0_ROW_SHIFT(ch) & SYS_REG_CS0_ROW_MASK); cs1_row = 13 + (sys_reg >> SYS_REG_CS1_ROW_SHIFT(ch) & SYS_REG_CS1_ROW_MASK); - bw = (sys_reg >> SYS_REG_BW_SHIFT(ch)) & - SYS_REG_BW_MASK; + bw = (2 >> (sys_reg >> SYS_REG_BW_SHIFT(ch)) & + SYS_REG_BW_MASK); row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) & SYS_REG_ROW_3_4_MASK; @@ -756,7 +756,7 @@ static int veyron_init(struct dram_info *priv) struct udevice *pmic; int ret; - ret = uclass_first_device(UCLASS_PMIC, &pmic); + ret = uclass_first_device_err(UCLASS_PMIC, &pmic); if (ret) return ret; diff --git a/arch/arm/mach-tegra/arm64-mmu.c b/arch/arm/mach-tegra/arm64-mmu.c index c2276523cb..501c4f00c4 100644 --- a/arch/arm/mach-tegra/arm64-mmu.c +++ b/arch/arm/mach-tegra/arm64-mmu.c @@ -12,120 +12,22 @@ #include <asm/system.h> #include <asm/armv8/mmu.h> -DECLARE_GLOBAL_DATA_PTR; - -#define SECTION_SHIFT_L1 30UL -#define SECTION_SHIFT_L2 21UL -#define BLOCK_SIZE_L0 0x8000000000UL -#define BLOCK_SIZE_L1 (1 << SECTION_SHIFT_L1) -#define BLOCK_SIZE_L2 (1 << SECTION_SHIFT_L2) - -#define TCR_TG1_4K (1 << 31) -#define TCR_EPD1_DISABLE (1 << 23) -#define TEGRA_VA_BITS 40 -#define TEGRA_TCR TCR_TG1_4K | \ - TCR_EPD1_DISABLE | \ - TCR_SHARED_OUTER | \ - TCR_SHARED_INNER | \ - TCR_IRGN_WBWA | \ - TCR_ORGN_WBWA | \ - TCR_T0SZ(TEGRA_VA_BITS) - -#define MEMORY_ATTR PMD_SECT_AF | PMD_SECT_INNER_SHARE | \ - PMD_ATTRINDX(MT_NORMAL) | \ - PMD_TYPE_SECT -#define DEVICE_ATTR PMD_SECT_AF | PMD_SECT_PXN | \ - PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_NGNRNE) | \ - PMD_TYPE_SECT - -/* 4K size is required to place 512 entries in each level */ -#define TLB_TABLE_SIZE 0x1000 - -/* - * This mmu table looks as below - * Level 0 table contains two entries to 512GB sizes. One is Level1 Table 0 - * and other Level1 Table1. - * Level1 Table0 contains entries for each 1GB from 0 to 511GB. - * Level1 Table1 contains entries for each 1GB from 512GB to 1TB. - * Level2 Table0, Level2 Table1, Level2 Table2 and Level2 Table3 contains - * entries for each 2MB starting from 0GB, 1GB, 2GB and 3GB respectively. - */ -void mmu_setup(void) -{ - int el; - u64 i, section_l1t0, section_l1t1; - u64 section_l2t0, section_l2t1, section_l2t2, section_l2t3; - u64 *level0_table = (u64 *)gd->arch.tlb_addr; - u64 *level1_table_0 = (u64 *)(gd->arch.tlb_addr + TLB_TABLE_SIZE); - u64 *level1_table_1 = (u64 *)(gd->arch.tlb_addr + (2 * TLB_TABLE_SIZE)); - u64 *level2_table_0 = (u64 *)(gd->arch.tlb_addr + (3 * TLB_TABLE_SIZE)); - u64 *level2_table_1 = (u64 *)(gd->arch.tlb_addr + (4 * TLB_TABLE_SIZE)); - u64 *level2_table_2 = (u64 *)(gd->arch.tlb_addr + (5 * TLB_TABLE_SIZE)); - u64 *level2_table_3 = (u64 *)(gd->arch.tlb_addr + (6 * TLB_TABLE_SIZE)); - - /* Invalidate all table entries */ - memset(level0_table, 0, PGTABLE_SIZE); - - level0_table[0] = - (u64)level1_table_0 | PMD_TYPE_TABLE; - level0_table[1] = - (u64)level1_table_1 | PMD_TYPE_TABLE; - - /* - * set level 1 table 0, covering 0 to 512GB - * set level 1 table 1, covering 512GB to 1TB - */ - section_l1t0 = 0; - section_l1t1 = BLOCK_SIZE_L0; - - for (i = 0; i < 512; i++) { - level1_table_0[i] = section_l1t0; - if (i >= 4) - level1_table_0[i] |= MEMORY_ATTR; - level1_table_1[i] = section_l1t1; - level1_table_1[i] |= MEMORY_ATTR; - section_l1t0 += BLOCK_SIZE_L1; - section_l1t1 += BLOCK_SIZE_L1; +static struct mm_region tegra_mem_map[] = { + { + .base = 0x0UL, + .size = 0x80000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .base = 0x80000000UL, + .size = 0xff80000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + /* List terminator */ + 0, } +}; - level1_table_0[0] = - (u64)level2_table_0 | PMD_TYPE_TABLE; - level1_table_0[1] = - (u64)level2_table_1 | PMD_TYPE_TABLE; - level1_table_0[2] = - (u64)level2_table_2 | PMD_TYPE_TABLE; - level1_table_0[3] = - (u64)level2_table_3 | PMD_TYPE_TABLE; - - section_l2t0 = 0; - section_l2t1 = section_l2t0 + BLOCK_SIZE_L1; /* 1GB */ - section_l2t2 = section_l2t1 + BLOCK_SIZE_L1; /* 2GB */ - section_l2t3 = section_l2t2 + BLOCK_SIZE_L1; /* 3GB */ - - for (i = 0; i < 512; i++) { - level2_table_0[i] = section_l2t0 | DEVICE_ATTR; - level2_table_1[i] = section_l2t1 | DEVICE_ATTR; - level2_table_2[i] = section_l2t2 | MEMORY_ATTR; - level2_table_3[i] = section_l2t3 | MEMORY_ATTR; - section_l2t0 += BLOCK_SIZE_L2; - section_l2t1 += BLOCK_SIZE_L2; - section_l2t2 += BLOCK_SIZE_L2; - section_l2t3 += BLOCK_SIZE_L2; - } - - /* flush new MMU table */ - flush_dcache_range(gd->arch.tlb_addr, - gd->arch.tlb_addr + gd->arch.tlb_size); - - /* point TTBR to the new table */ - el = current_el(); - set_ttbr_tcr_mair(el, gd->arch.tlb_addr, - TEGRA_TCR, MEMORY_ATTRIBUTES); - - set_sctlr(get_sctlr() | CR_M); -} - -u64 *arch_get_page_table(void) -{ - return (u64 *)(gd->arch.tlb_addr + (3 * TLB_TABLE_SIZE)); -} +struct mm_region *mem_map = tegra_mem_map; diff --git a/arch/arm/mach-zynq/u-boot-spl.lds b/arch/arm/mach-zynq/u-boot-spl.lds index ecdf6a031e..9a59164c87 100644 --- a/arch/arm/mach-zynq/u-boot-spl.lds +++ b/arch/arm/mach-zynq/u-boot-spl.lds @@ -38,16 +38,11 @@ SECTIONS } > .sram . = ALIGN(4); -#ifdef CONFIG_SPL_DM .u_boot_list : { - KEEP(*(SORT(.u_boot_list_*_driver_*))); - KEEP(*(SORT(.u_boot_list_*_uclass_*))); + KEEP(*(SORT(.u_boot_list*))); } > .sram . = ALIGN(4); -#endif - - . = .; _image_binary_end = .; diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 6977dd641a..3eb3440be8 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -10,6 +10,7 @@ #include <common.h> #include <command.h> +#include <fdt_support.h> #include <image.h> #include <u-boot/zlib.h> #include <asm/byteorder.h> diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h index a3b07c6ad0..002b839fd4 100644 --- a/arch/mips/include/asm/cacheops.h +++ b/arch/mips/include/asm/cacheops.h @@ -16,7 +16,7 @@ static inline void mips_cache(int op, const volatile void *addr) #ifdef __GCC_HAVE_BUILTIN_MIPS_CACHE __builtin_mips_cache(op, addr); #else - __asm__ __volatile__("cache %0, %1" : : "i"(op), "R"(addr)); + __asm__ __volatile__("cache %0, 0(%1)" : : "i"(op), "r"(addr)); #endif } diff --git a/arch/nios2/cpu/cpu.c b/arch/nios2/cpu/cpu.c index be7f99c1de..4f0f8fc5f8 100644 --- a/arch/nios2/cpu/cpu.c +++ b/arch/nios2/cpu/cpu.c @@ -63,11 +63,9 @@ int arch_cpu_init_dm(void) struct udevice *dev; int ret; - ret = uclass_first_device(UCLASS_CPU, &dev); + ret = uclass_first_device_err(UCLASS_CPU, &dev); if (ret) return ret; - if (!dev) - return -ENODEV; gd->ram_size = CONFIG_SYS_SDRAM_SIZE; #ifndef CONFIG_ROM_STUBS diff --git a/arch/powerpc/include/asm/fsl_secure_boot.h b/arch/powerpc/include/asm/fsl_secure_boot.h index c45cace552..826f9c960e 100644 --- a/arch/powerpc/include/asm/fsl_secure_boot.h +++ b/arch/powerpc/include/asm/fsl_secure_boot.h @@ -76,13 +76,8 @@ #define CONFIG_CMD_BLOB #define CONFIG_FSL_SEC_MON #define CONFIG_SHA_PROG_HW_ACCEL -#define CONFIG_RSA #define CONFIG_RSA_FREESCALE_EXP -#ifndef CONFIG_DM -#define CONFIG_DM -#endif - #ifndef CONFIG_FSL_CAAM #define CONFIG_FSL_CAAM #endif diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index a0bd344ed1..4ef27dc87a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -8,6 +8,9 @@ choice prompt "Mainboard vendor" default VENDOR_EMULATION +config VENDOR_CONGATEC + bool "congatec" + config VENDOR_COREBOOT bool "coreboot" @@ -26,6 +29,7 @@ config VENDOR_INTEL endchoice # board-specific options below +source "board/congatec/Kconfig" source "board/coreboot/Kconfig" source "board/efi/Kconfig" source "board/emulation/Kconfig" @@ -34,6 +38,7 @@ source "board/intel/Kconfig" # platform-specific options below source "arch/x86/cpu/baytrail/Kconfig" +source "arch/x86/cpu/broadwell/Kconfig" source "arch/x86/cpu/coreboot/Kconfig" source "arch/x86/cpu/ivybridge/Kconfig" source "arch/x86/cpu/qemu/Kconfig" @@ -266,6 +271,78 @@ config ENABLE_MRC_CACHE to be used for speeding up boot time on future reboots and/or power cycles. +config HAVE_MRC + bool "Add a System Agent binary" + depends on !HAVE_FSP + help + Select this option to add a System Agent binary to + the resulting U-Boot image. MRC stands for Memory Reference Code. + It is a binary blob which U-Boot uses to set up SDRAM. + + Note: Without this binary U-Boot will not be able to set up its + SDRAM so will not boot. + +config CACHE_MRC_BIN + bool + depends on HAVE_MRC + default n + help + Enable caching for the memory reference code binary. This uses an + MTRR (memory type range register) to turn on caching for the section + of SPI flash that contains the memory reference code. This makes + SDRAM init run faster. + +config CACHE_MRC_SIZE_KB + int + depends on HAVE_MRC + default 512 + help + Sets the size of the cached area for the memory reference code. + This ends at the end of SPI flash (address 0xffffffff) and is + measured in KB. Typically this is set to 512, providing for 0.5MB + of cached space. + +config DCACHE_RAM_BASE + hex + depends on HAVE_MRC + help + Sets the base of the data cache area in memory space. This is the + start address of the cache-as-RAM (CAR) area and the address varies + depending on the CPU. Once CAR is set up, read/write memory becomes + available at this address and can be used temporarily until SDRAM + is working. + +config DCACHE_RAM_SIZE + hex + depends on HAVE_MRC + default 0x40000 + help + Sets the total size of the data cache area in memory space. This + sets the size of the cache-as-RAM (CAR) area. Note that much of the + CAR space is required by the MRC. The CAR space available to U-Boot + is normally at the start and typically extends to 1/4 or 1/2 of the + available size. + +config DCACHE_RAM_MRC_VAR_SIZE + hex + depends on HAVE_MRC + help + This is the amount of CAR (Cache as RAM) reserved for use by the + memory reference code. This depends on the implementation of the + memory reference code and must be set correctly or the board will + not boot. + +config HAVE_REFCODE + bool "Add a Reference Code binary" + help + Select this option to add a Reference Code binary to the resulting + U-Boot image. This is an Intel binary blob that handles system + initialisation, in this case the PCH and System Agent. + + Note: Without this binary (on platforms that need it such as + broadwell) U-Boot will be missing some critical setup steps. + Various peripherals may fail to work. + config SMP bool "Enable Symmetric Multiprocessing" default n @@ -449,6 +526,16 @@ config I8042_KEYB config DM_KEYBOARD default y +config SEABIOS + bool "Support booting SeaBIOS" + help + SeaBIOS is an open source implementation of a 16-bit X86 BIOS. + It can run in an emulator or natively on X86 hardware with the use + of coreboot/U-Boot. By turning on this option, U-Boot prepares + all the configuration tables that are necessary to boot SeaBIOS. + + Check http://www.seabios.org/SeaBIOS for details. + source "arch/x86/lib/efi/Kconfig" endmenu diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 2ff237701d..2667e0b478 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -18,7 +18,9 @@ AFLAGS_call32.o := -fpic -fshort-wchar extra-y += call32.o +obj-y += intel_common/ obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/ +obj-$(CONFIG_INTEL_BROADWELL) += broadwell/ obj-$(CONFIG_SYS_COREBOOT) += coreboot/ obj-$(CONFIG_EFI_APP) += efi/ obj-$(CONFIG_QEMU) += qemu/ diff --git a/arch/x86/cpu/broadwell/Kconfig b/arch/x86/cpu/broadwell/Kconfig new file mode 100644 index 0000000000..1ce3848be3 --- /dev/null +++ b/arch/x86/cpu/broadwell/Kconfig @@ -0,0 +1,30 @@ +# +# Copyright (C) 2016 Google Inc. +# +# SPDX-License-Identifier: GPL-2.0 + +config INTEL_BROADWELL + bool + select CACHE_MRC_BIN + +if INTEL_BROADWELL + +config DCACHE_RAM_BASE + default 0xff7c0000 + +config DCACHE_RAM_SIZE + default 0x40000 + +config DCACHE_RAM_MRC_VAR_SIZE + default 0x30000 + +config CPU_SPECIFIC_OPTIONS + def_bool y + select SMM_TSEG + select X86_RAMTEST + +config SMM_TSEG_SIZE + hex + default 0x800000 + +endif diff --git a/arch/x86/cpu/broadwell/Makefile b/arch/x86/cpu/broadwell/Makefile new file mode 100644 index 0000000000..7edb6f6f19 --- /dev/null +++ b/arch/x86/cpu/broadwell/Makefile @@ -0,0 +1,17 @@ +# +# Copyright (c) 2016 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += cpu.o +obj-y += iobp.o +obj-y += lpc.o +obj-y += me.o +obj-y += northbridge.o +obj-y += pch.o +obj-y += pinctrl_broadwell.o +obj-y += power_state.o +obj-y += refcode.o +obj-y += sata.o +obj-y += sdram.o diff --git a/arch/x86/cpu/broadwell/cpu.c b/arch/x86/cpu/broadwell/cpu.c new file mode 100644 index 0000000000..3ba21aacec --- /dev/null +++ b/arch/x86/cpu/broadwell/cpu.c @@ -0,0 +1,761 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + * + * Based on code from coreboot src/soc/intel/broadwell/cpu.c + */ + +#include <common.h> +#include <dm.h> +#include <cpu.h> +#include <asm/cpu.h> +#include <asm/cpu_x86.h> +#include <asm/cpu_common.h> +#include <asm/intel_regs.h> +#include <asm/msr.h> +#include <asm/post.h> +#include <asm/turbo.h> +#include <asm/arch/cpu.h> +#include <asm/arch/pch.h> +#include <asm/arch/rcb.h> + +struct cpu_broadwell_priv { + bool ht_disabled; +}; + +/* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */ +static const u8 power_limit_time_sec_to_msr[] = { + [0] = 0x00, + [1] = 0x0a, + [2] = 0x0b, + [3] = 0x4b, + [4] = 0x0c, + [5] = 0x2c, + [6] = 0x4c, + [7] = 0x6c, + [8] = 0x0d, + [10] = 0x2d, + [12] = 0x4d, + [14] = 0x6d, + [16] = 0x0e, + [20] = 0x2e, + [24] = 0x4e, + [28] = 0x6e, + [32] = 0x0f, + [40] = 0x2f, + [48] = 0x4f, + [56] = 0x6f, + [64] = 0x10, + [80] = 0x30, + [96] = 0x50, + [112] = 0x70, + [128] = 0x11, +}; + +/* Convert POWER_LIMIT_1_TIME MSR value to seconds */ +static const u8 power_limit_time_msr_to_sec[] = { + [0x00] = 0, + [0x0a] = 1, + [0x0b] = 2, + [0x4b] = 3, + [0x0c] = 4, + [0x2c] = 5, + [0x4c] = 6, + [0x6c] = 7, + [0x0d] = 8, + [0x2d] = 10, + [0x4d] = 12, + [0x6d] = 14, + [0x0e] = 16, + [0x2e] = 20, + [0x4e] = 24, + [0x6e] = 28, + [0x0f] = 32, + [0x2f] = 40, + [0x4f] = 48, + [0x6f] = 56, + [0x10] = 64, + [0x30] = 80, + [0x50] = 96, + [0x70] = 112, + [0x11] = 128, +}; + +int arch_cpu_init_dm(void) +{ + struct udevice *dev; + int ret; + + /* Start up the LPC so we have serial */ + ret = uclass_first_device(UCLASS_LPC, &dev); + if (ret) + return ret; + if (!dev) + return -ENODEV; + ret = cpu_set_flex_ratio_to_tdp_nominal(); + if (ret) + return ret; + + return 0; +} + +void set_max_freq(void) +{ + msr_t msr, perf_ctl, platform_info; + + /* Check for configurable TDP option */ + platform_info = msr_read(MSR_PLATFORM_INFO); + + if ((platform_info.hi >> 1) & 3) { + /* Set to nominal TDP ratio */ + msr = msr_read(MSR_CONFIG_TDP_NOMINAL); + perf_ctl.lo = (msr.lo & 0xff) << 8; + } else { + /* Platform Info bits 15:8 give max ratio */ + msr = msr_read(MSR_PLATFORM_INFO); + perf_ctl.lo = msr.lo & 0xff00; + } + + perf_ctl.hi = 0; + msr_write(IA32_PERF_CTL, perf_ctl); + + debug("CPU: frequency set to %d MHz\n", + ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK); +} + +int arch_cpu_init(void) +{ + post_code(POST_CPU_INIT); + + return x86_cpu_init_f(); +} + +int print_cpuinfo(void) +{ + char processor_name[CPU_MAX_NAME_LEN]; + const char *name; + int ret; + + set_max_freq(); + + ret = cpu_common_init(); + if (ret) + return ret; + gd->arch.pei_boot_mode = PEI_BOOT_NONE; + + /* Print processor name */ + name = cpu_get_name(processor_name); + printf("CPU: %s\n", name); + + return 0; +} + +/* + * The core 100MHz BLCK is disabled in deeper c-states. One needs to calibrate + * the 100MHz BCLCK against the 24MHz BLCK to restore the clocks properly + * when a core is woken up + */ +static int pcode_ready(void) +{ + int wait_count; + const int delay_step = 10; + + wait_count = 0; + do { + if (!(readl(MCHBAR_REG(BIOS_MAILBOX_INTERFACE)) & + MAILBOX_RUN_BUSY)) + return 0; + wait_count += delay_step; + udelay(delay_step); + } while (wait_count < 1000); + + return -ETIMEDOUT; +} + +static u32 pcode_mailbox_read(u32 command) +{ + int ret; + + ret = pcode_ready(); + if (ret) { + debug("PCODE: mailbox timeout on wait ready\n"); + return ret; + } + + /* Send command and start transaction */ + writel(command | MAILBOX_RUN_BUSY, MCHBAR_REG(BIOS_MAILBOX_INTERFACE)); + + ret = pcode_ready(); + if (ret) { + debug("PCODE: mailbox timeout on completion\n"); + return ret; + } + + /* Read mailbox */ + return readl(MCHBAR_REG(BIOS_MAILBOX_DATA)); +} + +static int pcode_mailbox_write(u32 command, u32 data) +{ + int ret; + + ret = pcode_ready(); + if (ret) { + debug("PCODE: mailbox timeout on wait ready\n"); + return ret; + } + + writel(data, MCHBAR_REG(BIOS_MAILBOX_DATA)); + + /* Send command and start transaction */ + writel(command | MAILBOX_RUN_BUSY, MCHBAR_REG(BIOS_MAILBOX_INTERFACE)); + + ret = pcode_ready(); + if (ret) { + debug("PCODE: mailbox timeout on completion\n"); + return ret; + } + + return 0; +} + +/* @dev is the CPU device */ +static void initialize_vr_config(struct udevice *dev) +{ + int ramp, min_vid; + msr_t msr; + + debug("Initializing VR config\n"); + + /* Configure VR_CURRENT_CONFIG */ + msr = msr_read(MSR_VR_CURRENT_CONFIG); + /* + * Preserve bits 63 and 62. Bit 62 is PSI4 enable, but it is only valid + * on ULT systems + */ + msr.hi &= 0xc0000000; + msr.hi |= (0x01 << (52 - 32)); /* PSI3 threshold - 1A */ + msr.hi |= (0x05 << (42 - 32)); /* PSI2 threshold - 5A */ + msr.hi |= (0x14 << (32 - 32)); /* PSI1 threshold - 20A */ + msr.hi |= (1 << (62 - 32)); /* Enable PSI4 */ + /* Leave the max instantaneous current limit (12:0) to default */ + msr_write(MSR_VR_CURRENT_CONFIG, msr); + + /* Configure VR_MISC_CONFIG MSR */ + msr = msr_read(MSR_VR_MISC_CONFIG); + /* Set the IOUT_SLOPE scalar applied to dIout in U10.1.9 format */ + msr.hi &= ~(0x3ff << (40 - 32)); + msr.hi |= (0x200 << (40 - 32)); /* 1.0 */ + /* Set IOUT_OFFSET to 0 */ + msr.hi &= ~0xff; + /* Set entry ramp rate to slow */ + msr.hi &= ~(1 << (51 - 32)); + /* Enable decay mode on C-state entry */ + msr.hi |= (1 << (52 - 32)); + /* Set the slow ramp rate */ + msr.hi &= ~(0x3 << (53 - 32)); + /* Configure the C-state exit ramp rate */ + ramp = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "intel,slow-ramp", + -1); + if (ramp != -1) { + /* Configured slow ramp rate */ + msr.hi |= ((ramp & 0x3) << (53 - 32)); + /* Set exit ramp rate to slow */ + msr.hi &= ~(1 << (50 - 32)); + } else { + /* Fast ramp rate / 4 */ + msr.hi |= (0x01 << (53 - 32)); + /* Set exit ramp rate to fast */ + msr.hi |= (1 << (50 - 32)); + } + /* Set MIN_VID (31:24) to allow CPU to have full control */ + msr.lo &= ~0xff000000; + min_vid = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "intel,min-vid", + 0); + msr.lo |= (min_vid & 0xff) << 24; + msr_write(MSR_VR_MISC_CONFIG, msr); + + /* Configure VR_MISC_CONFIG2 MSR */ + msr = msr_read(MSR_VR_MISC_CONFIG2); + msr.lo &= ~0xffff; + /* + * Allow CPU to control minimum voltage completely (15:8) and + * set the fast ramp voltage in 10mV steps + */ + if (cpu_get_family_model() == BROADWELL_FAMILY_ULT) + msr.lo |= 0x006a; /* 1.56V */ + else + msr.lo |= 0x006f; /* 1.60V */ + msr_write(MSR_VR_MISC_CONFIG2, msr); + + /* Set C9/C10 VCC Min */ + pcode_mailbox_write(MAILBOX_BIOS_CMD_WRITE_C9C10_VOLTAGE, 0x1f1f); +} + +static int calibrate_24mhz_bclk(void) +{ + int err_code; + int ret; + + ret = pcode_ready(); + if (ret) + return ret; + + /* A non-zero value initiates the PCODE calibration */ + writel(~0, MCHBAR_REG(BIOS_MAILBOX_DATA)); + writel(MAILBOX_RUN_BUSY | MAILBOX_BIOS_CMD_FSM_MEASURE_INTVL, + MCHBAR_REG(BIOS_MAILBOX_INTERFACE)); + + ret = pcode_ready(); + if (ret) + return ret; + + err_code = readl(MCHBAR_REG(BIOS_MAILBOX_INTERFACE)) & 0xff; + + debug("PCODE: 24MHz BLCK calibration response: %d\n", err_code); + + /* Read the calibrated value */ + writel(MAILBOX_RUN_BUSY | MAILBOX_BIOS_CMD_READ_CALIBRATION, + MCHBAR_REG(BIOS_MAILBOX_INTERFACE)); + + ret = pcode_ready(); + if (ret) + return ret; + + debug("PCODE: 24MHz BLCK calibration value: 0x%08x\n", + readl(MCHBAR_REG(BIOS_MAILBOX_DATA))); + + return 0; +} + +static void configure_pch_power_sharing(void) +{ + u32 pch_power, pch_power_ext, pmsync, pmsync2; + int i; + + /* Read PCH Power levels from PCODE */ + pch_power = pcode_mailbox_read(MAILBOX_BIOS_CMD_READ_PCH_POWER); + pch_power_ext = pcode_mailbox_read(MAILBOX_BIOS_CMD_READ_PCH_POWER_EXT); + + debug("PCH Power: PCODE Levels 0x%08x 0x%08x\n", pch_power, + pch_power_ext); + + pmsync = readl(RCB_REG(PMSYNC_CONFIG)); + pmsync2 = readl(RCB_REG(PMSYNC_CONFIG2)); + + /* + * Program PMSYNC_TPR_CONFIG PCH power limit values + * pmsync[0:4] = mailbox[0:5] + * pmsync[8:12] = mailbox[6:11] + * pmsync[16:20] = mailbox[12:17] + */ + for (i = 0; i < 3; i++) { + u32 level = pch_power & 0x3f; + pch_power >>= 6; + pmsync &= ~(0x1f << (i * 8)); + pmsync |= (level & 0x1f) << (i * 8); + } + writel(pmsync, RCB_REG(PMSYNC_CONFIG)); + + /* + * Program PMSYNC_TPR_CONFIG2 Extended PCH power limit values + * pmsync2[0:4] = mailbox[23:18] + * pmsync2[8:12] = mailbox_ext[6:11] + * pmsync2[16:20] = mailbox_ext[12:17] + * pmsync2[24:28] = mailbox_ext[18:22] + */ + pmsync2 &= ~0x1f; + pmsync2 |= pch_power & 0x1f; + + for (i = 1; i < 4; i++) { + u32 level = pch_power_ext & 0x3f; + pch_power_ext >>= 6; + pmsync2 &= ~(0x1f << (i * 8)); + pmsync2 |= (level & 0x1f) << (i * 8); + } + writel(pmsync2, RCB_REG(PMSYNC_CONFIG2)); +} + +static int bsp_init_before_ap_bringup(struct udevice *dev) +{ + int ret; + + initialize_vr_config(dev); + ret = calibrate_24mhz_bclk(); + if (ret) + return ret; + configure_pch_power_sharing(); + + return 0; +} + +int cpu_config_tdp_levels(void) +{ + msr_t platform_info; + + /* Bits 34:33 indicate how many levels supported */ + platform_info = msr_read(MSR_PLATFORM_INFO); + return (platform_info.hi >> 1) & 3; +} + +static void set_max_ratio(void) +{ + msr_t msr, perf_ctl; + + perf_ctl.hi = 0; + + /* Check for configurable TDP option */ + if (turbo_get_state() == TURBO_ENABLED) { + msr = msr_read(MSR_NHM_TURBO_RATIO_LIMIT); + perf_ctl.lo = (msr.lo & 0xff) << 8; + } else if (cpu_config_tdp_levels()) { + /* Set to nominal TDP ratio */ + msr = msr_read(MSR_CONFIG_TDP_NOMINAL); + perf_ctl.lo = (msr.lo & 0xff) << 8; + } else { + /* Platform Info bits 15:8 give max ratio */ + msr = msr_read(MSR_PLATFORM_INFO); + perf_ctl.lo = msr.lo & 0xff00; + } + msr_write(IA32_PERF_CTL, perf_ctl); + + debug("cpu: frequency set to %d\n", + ((perf_ctl.lo >> 8) & 0xff) * CPU_BCLK); +} + +int broadwell_init(struct udevice *dev) +{ + struct cpu_broadwell_priv *priv = dev_get_priv(dev); + int num_threads; + int num_cores; + msr_t msr; + int ret; + + msr = msr_read(CORE_THREAD_COUNT_MSR); + num_threads = (msr.lo >> 0) & 0xffff; + num_cores = (msr.lo >> 16) & 0xffff; + debug("CPU has %u cores, %u threads enabled\n", num_cores, + num_threads); + + priv->ht_disabled = num_threads == num_cores; + + ret = bsp_init_before_ap_bringup(dev); + if (ret) + return ret; + + set_max_ratio(); + + return ret; +} + +static void configure_mca(void) +{ + msr_t msr; + const unsigned int mcg_cap_msr = 0x179; + int i; + int num_banks; + + msr = msr_read(mcg_cap_msr); + num_banks = msr.lo & 0xff; + msr.lo = 0; + msr.hi = 0; + /* + * TODO(adurbin): This should only be done on a cold boot. Also, some + * of these banks are core vs package scope. For now every CPU clears + * every bank + */ + for (i = 0; i < num_banks; i++) + msr_write(MSR_IA32_MC0_STATUS + (i * 4), msr); +} + +static void enable_lapic_tpr(void) +{ + msr_t msr; + + msr = msr_read(MSR_PIC_MSG_CONTROL); + msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */ + msr_write(MSR_PIC_MSG_CONTROL, msr); +} + + +static void configure_c_states(void) +{ + msr_t msr; + + msr = msr_read(MSR_PMG_CST_CONFIG_CONTROL); + msr.lo |= (1 << 31); /* Timed MWAIT Enable */ + msr.lo |= (1 << 30); /* Package c-state Undemotion Enable */ + msr.lo |= (1 << 29); /* Package c-state Demotion Enable */ + msr.lo |= (1 << 28); /* C1 Auto Undemotion Enable */ + msr.lo |= (1 << 27); /* C3 Auto Undemotion Enable */ + msr.lo |= (1 << 26); /* C1 Auto Demotion Enable */ + msr.lo |= (1 << 25); /* C3 Auto Demotion Enable */ + msr.lo &= ~(1 << 10); /* Disable IO MWAIT redirection */ + /* The deepest package c-state defaults to factory-configured value */ + msr_write(MSR_PMG_CST_CONFIG_CONTROL, msr); + + msr = msr_read(MSR_MISC_PWR_MGMT); + msr.lo &= ~(1 << 0); /* Enable P-state HW_ALL coordination */ + msr_write(MSR_MISC_PWR_MGMT, msr); + + msr = msr_read(MSR_POWER_CTL); + msr.lo |= (1 << 18); /* Enable Energy Perf Bias MSR 0x1b0 */ + msr.lo |= (1 << 1); /* C1E Enable */ + msr.lo |= (1 << 0); /* Bi-directional PROCHOT# */ + msr_write(MSR_POWER_CTL, msr); + + /* C-state Interrupt Response Latency Control 0 - package C3 latency */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_1024_NS | C_STATE_LATENCY_CONTROL_0_LIMIT; + msr_write(MSR_C_STATE_LATENCY_CONTROL_0, msr); + + /* C-state Interrupt Response Latency Control 1 */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_1024_NS | C_STATE_LATENCY_CONTROL_1_LIMIT; + msr_write(MSR_C_STATE_LATENCY_CONTROL_1, msr); + + /* C-state Interrupt Response Latency Control 2 - package C6/C7 short */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_1024_NS | C_STATE_LATENCY_CONTROL_2_LIMIT; + msr_write(MSR_C_STATE_LATENCY_CONTROL_2, msr); + + /* C-state Interrupt Response Latency Control 3 - package C8 */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_1024_NS | C_STATE_LATENCY_CONTROL_3_LIMIT; + msr_write(MSR_C_STATE_LATENCY_CONTROL_3, msr); + + /* C-state Interrupt Response Latency Control 4 - package C9 */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_1024_NS | C_STATE_LATENCY_CONTROL_4_LIMIT; + msr_write(MSR_C_STATE_LATENCY_CONTROL_4, msr); + + /* C-state Interrupt Response Latency Control 5 - package C10 */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_1024_NS | C_STATE_LATENCY_CONTROL_5_LIMIT; + msr_write(MSR_C_STATE_LATENCY_CONTROL_5, msr); +} + +static void configure_misc(void) +{ + msr_t msr; + + msr = msr_read(MSR_IA32_MISC_ENABLE); + msr.lo |= (1 << 0); /* Fast String enable */ + msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */ + msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */ + msr_write(MSR_IA32_MISC_ENABLE, msr); + + /* Disable thermal interrupts */ + msr.lo = 0; + msr.hi = 0; + msr_write(MSR_IA32_THERM_INTERRUPT, msr); + + /* Enable package critical interrupt only */ + msr.lo = 1 << 4; + msr.hi = 0; + msr_write(MSR_IA32_PACKAGE_THERM_INTERRUPT, msr); +} + +static void configure_thermal_target(struct udevice *dev) +{ + int tcc_offset; + msr_t msr; + + tcc_offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "intel,tcc-offset", 0); + + /* Set TCC activaiton offset if supported */ + msr = msr_read(MSR_PLATFORM_INFO); + if ((msr.lo & (1 << 30)) && tcc_offset) { + msr = msr_read(MSR_TEMPERATURE_TARGET); + msr.lo &= ~(0xf << 24); /* Bits 27:24 */ + msr.lo |= (tcc_offset & 0xf) << 24; + msr_write(MSR_TEMPERATURE_TARGET, msr); + } +} + +static void configure_dca_cap(void) +{ + struct cpuid_result cpuid_regs; + msr_t msr; + + /* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */ + cpuid_regs = cpuid(1); + if (cpuid_regs.ecx & (1 << 18)) { + msr = msr_read(MSR_IA32_PLATFORM_DCA_CAP); + msr.lo |= 1; + msr_write(MSR_IA32_PLATFORM_DCA_CAP, msr); + } +} + +static void set_energy_perf_bias(u8 policy) +{ + msr_t msr; + int ecx; + + /* Determine if energy efficient policy is supported */ + ecx = cpuid_ecx(0x6); + if (!(ecx & (1 << 3))) + return; + + /* Energy Policy is bits 3:0 */ + msr = msr_read(MSR_IA32_ENERGY_PERFORMANCE_BIAS); + msr.lo &= ~0xf; + msr.lo |= policy & 0xf; + msr_write(MSR_IA32_ENERGY_PERFORMANCE_BIAS, msr); + + debug("cpu: energy policy set to %u\n", policy); +} + +/* All CPUs including BSP will run the following function */ +static void cpu_core_init(struct udevice *dev) +{ + /* Clear out pending MCEs */ + configure_mca(); + + /* Enable the local cpu apics */ + enable_lapic_tpr(); + + /* Configure C States */ + configure_c_states(); + + /* Configure Enhanced SpeedStep and Thermal Sensors */ + configure_misc(); + + /* Thermal throttle activation offset */ + configure_thermal_target(dev); + + /* Enable Direct Cache Access */ + configure_dca_cap(); + + /* Set energy policy */ + set_energy_perf_bias(ENERGY_POLICY_NORMAL); + + /* Enable Turbo */ + turbo_enable(); +} + +/* + * Configure processor power limits if possible + * This must be done AFTER set of BIOS_RESET_CPL + */ +void cpu_set_power_limits(int power_limit_1_time) +{ + msr_t msr; + msr_t limit; + unsigned power_unit; + unsigned tdp, min_power, max_power, max_time; + u8 power_limit_1_val; + + msr = msr_read(MSR_PLATFORM_INFO); + if (power_limit_1_time > ARRAY_SIZE(power_limit_time_sec_to_msr)) + power_limit_1_time = 28; + + if (!(msr.lo & PLATFORM_INFO_SET_TDP)) + return; + + /* Get units */ + msr = msr_read(MSR_PKG_POWER_SKU_UNIT); + power_unit = 2 << ((msr.lo & 0xf) - 1); + + /* Get power defaults for this SKU */ + msr = msr_read(MSR_PKG_POWER_SKU); + tdp = msr.lo & 0x7fff; + min_power = (msr.lo >> 16) & 0x7fff; + max_power = msr.hi & 0x7fff; + max_time = (msr.hi >> 16) & 0x7f; + + debug("CPU TDP: %u Watts\n", tdp / power_unit); + + if (power_limit_time_msr_to_sec[max_time] > power_limit_1_time) + power_limit_1_time = power_limit_time_msr_to_sec[max_time]; + + if (min_power > 0 && tdp < min_power) + tdp = min_power; + + if (max_power > 0 && tdp > max_power) + tdp = max_power; + + power_limit_1_val = power_limit_time_sec_to_msr[power_limit_1_time]; + + /* Set long term power limit to TDP */ + limit.lo = 0; + limit.lo |= tdp & PKG_POWER_LIMIT_MASK; + limit.lo |= PKG_POWER_LIMIT_EN; + limit.lo |= (power_limit_1_val & PKG_POWER_LIMIT_TIME_MASK) << + PKG_POWER_LIMIT_TIME_SHIFT; + + /* Set short term power limit to 1.25 * TDP */ + limit.hi = 0; + limit.hi |= ((tdp * 125) / 100) & PKG_POWER_LIMIT_MASK; + limit.hi |= PKG_POWER_LIMIT_EN; + /* Power limit 2 time is only programmable on server SKU */ + + msr_write(MSR_PKG_POWER_LIMIT, limit); + + /* Set power limit values in MCHBAR as well */ + writel(limit.lo, MCHBAR_REG(MCH_PKG_POWER_LIMIT_LO)); + writel(limit.hi, MCHBAR_REG(MCH_PKG_POWER_LIMIT_HI)); + + /* Set DDR RAPL power limit by copying from MMIO to MSR */ + msr.lo = readl(MCHBAR_REG(MCH_DDR_POWER_LIMIT_LO)); + msr.hi = readl(MCHBAR_REG(MCH_DDR_POWER_LIMIT_HI)); + msr_write(MSR_DDR_RAPL_LIMIT, msr); + + /* Use nominal TDP values for CPUs with configurable TDP */ + if (cpu_config_tdp_levels()) { + msr = msr_read(MSR_CONFIG_TDP_NOMINAL); + limit.hi = 0; + limit.lo = msr.lo & 0xff; + msr_write(MSR_TURBO_ACTIVATION_RATIO, limit); + } +} + +static int broadwell_get_info(struct udevice *dev, struct cpu_info *info) +{ + msr_t msr; + + msr = msr_read(IA32_PERF_CTL); + info->cpu_freq = ((msr.lo >> 8) & 0xff) * BROADWELL_BCLK * 1000000; + info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU | + 1 << CPU_FEAT_UCODE | 1 << CPU_FEAT_DEVICE_ID; + + return 0; +} + +static int broadwell_get_count(struct udevice *dev) +{ + return 4; +} + +static int cpu_x86_broadwell_probe(struct udevice *dev) +{ + if (dev->seq == 0) { + cpu_core_init(dev); + return broadwell_init(dev); + } + + return 0; +} + +static const struct cpu_ops cpu_x86_broadwell_ops = { + .get_desc = cpu_x86_get_desc, + .get_info = broadwell_get_info, + .get_count = broadwell_get_count, +}; + +static const struct udevice_id cpu_x86_broadwell_ids[] = { + { .compatible = "intel,core-i3-gen5" }, + { } +}; + +U_BOOT_DRIVER(cpu_x86_broadwell_drv) = { + .name = "cpu_x86_broadwell", + .id = UCLASS_CPU, + .of_match = cpu_x86_broadwell_ids, + .bind = cpu_x86_bind, + .probe = cpu_x86_broadwell_probe, + .ops = &cpu_x86_broadwell_ops, + .priv_auto_alloc_size = sizeof(struct cpu_broadwell_priv), +}; diff --git a/arch/x86/cpu/broadwell/iobp.c b/arch/x86/cpu/broadwell/iobp.c new file mode 100644 index 0000000000..5eed849812 --- /dev/null +++ b/arch/x86/cpu/broadwell/iobp.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * Modified from coreboot + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <errno.h> +#include <asm/intel_regs.h> +#include <asm/io.h> +#include <asm/arch/pch.h> + +#define IOBP_RETRY 1000 + +/* IO Buffer Programming */ +#define IOBPIRI 0x2330 +#define IOBPD 0x2334 +#define IOBPS 0x2338 +#define IOBPS_READY 0x0001 +#define IOBPS_TX_MASK 0x0006 +#define IOBPS_MASK 0xff00 +#define IOBPS_READ 0x0600 +#define IOBPS_WRITE 0x0700 +#define IOBPU 0x233a +#define IOBPU_MAGIC 0xf000 +#define IOBP_PCICFG_READ 0x0400 +#define IOBP_PCICFG_WRITE 0x0500 + +static inline int iobp_poll(void) +{ + unsigned try; + + for (try = IOBP_RETRY; try > 0; try--) { + u16 status = readw(RCB_REG(IOBPS)); + if ((status & IOBPS_READY) == 0) + return 1; + udelay(10); + } + + printf("IOBP: timeout waiting for transaction to complete\n"); + return 0; +} + +int pch_iobp_trans_start(u32 address, int op) +{ + if (!iobp_poll()) + return 0; + + /* Set the address */ + writel(address, RCB_REG(IOBPIRI)); + + /* READ OPCODE */ + clrsetbits_le16(RCB_REG(IOBPS), IOBPS_MASK, op); + + return 1; +} + +int pch_iobp_trans_finish(void) +{ + u16 status; + + /* Undocumented magic */ + writew(IOBPU_MAGIC, RCB_REG(IOBPU)); + + /* Set ready bit */ + setbits_le16(RCB_REG(IOBPS), IOBPS_READY); + + if (!iobp_poll()) + return 1; + + /* Check for successful transaction */ + status = readw(RCB_REG(IOBPS)); + if (status & IOBPS_TX_MASK) + return 1; + + return 0; +} + +u32 pch_iobp_read(u32 address) +{ + if (!pch_iobp_trans_start(address, IOBPS_READ)) + return 0; + if (pch_iobp_trans_finish()) { + printf("IOBP: read 0x%08x failed\n", address); + return 0; + } + + /* Read IOBP data */ + return readl(RCB_REG(IOBPD)); +} + +int pch_iobp_write(u32 address, u32 data) +{ + if (!pch_iobp_trans_start(address, IOBPS_WRITE)) + return -EIO; + + writel(data, RCB_REG(IOBPD)); + + if (pch_iobp_trans_finish()) { + printf("IOBP: write 0x%08x failed\n", address); + return -EIO; + } + + return 0; +} + +int pch_iobp_update(u32 address, u32 andvalue, u32 orvalue) +{ + u32 data = pch_iobp_read(address); + + /* Update the data */ + data &= andvalue; + data |= orvalue; + + return pch_iobp_write(address, data); +} + +int pch_iobp_exec(u32 addr, u16 op_code, u8 route_id, u32 *data, u8 *resp) +{ + if (!data || !resp) + return 0; + + *resp = -1; + if (!iobp_poll()) + return -EIO; + + writel(addr, RCB_REG(IOBPIRI)); + clrsetbits_le16(RCB_REG(IOBPS), 0xff00, op_code); + writew(IOBPU_MAGIC | route_id, RCB_REG(IOBPU)); + + writel(*data, RCB_REG(IOBPD)); + /* Set IOBPS[0] to trigger IOBP transaction*/ + setbits_le16(RCB_REG(IOBPS), 1); + + if (!iobp_poll()) + return -EIO; + + *resp = (readw(RCB_REG(IOBPS)) & IOBPS_TX_MASK) >> 1; + *data = readl(RCB_REG(IOBPD)); + + return 0; +} diff --git a/arch/x86/cpu/broadwell/lpc.c b/arch/x86/cpu/broadwell/lpc.c new file mode 100644 index 0000000000..ee3ac1820d --- /dev/null +++ b/arch/x86/cpu/broadwell/lpc.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * From coreboot broadwell support + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <pch.h> +#include <asm/intel_regs.h> +#include <asm/io.h> +#include <asm/lpc_common.h> +#include <asm/arch/pch.h> +#include <asm/arch/spi.h> + +static void set_spi_speed(void) +{ + u32 fdod; + u8 ssfc; + + /* Observe SPI Descriptor Component Section 0 */ + writel(0x1000, SPI_REG(SPIBAR_FDOC)); + + /* Extract the Write/Erase SPI Frequency from descriptor */ + fdod = readl(SPI_REG(SPIBAR_FDOD)); + fdod >>= 24; + fdod &= 7; + + /* Set Software Sequence frequency to match */ + ssfc = readb(SPI_REG(SPIBAR_SSFC + 2)); + ssfc &= ~7; + ssfc |= fdod; + writeb(ssfc, SPI_REG(SPIBAR_SSFC + 2)); +} + +static int broadwell_lpc_early_init(struct udevice *dev) +{ + set_spi_speed(); + + return 0; +} + +static int lpc_init_extra(struct udevice *dev) +{ + return 0; +} + +static int broadwell_lpc_probe(struct udevice *dev) +{ + int ret; + + if (!(gd->flags & GD_FLG_RELOC)) { + ret = lpc_common_early_init(dev); + if (ret) { + debug("%s: lpc_early_init() failed\n", __func__); + return ret; + } + + return broadwell_lpc_early_init(dev); + } + + return lpc_init_extra(dev); +} + +static const struct udevice_id broadwell_lpc_ids[] = { + { .compatible = "intel,broadwell-lpc" }, + { } +}; + +U_BOOT_DRIVER(broadwell_lpc_drv) = { + .name = "lpc", + .id = UCLASS_LPC, + .of_match = broadwell_lpc_ids, + .probe = broadwell_lpc_probe, +}; diff --git a/arch/x86/cpu/broadwell/me.c b/arch/x86/cpu/broadwell/me.c new file mode 100644 index 0000000000..e03b87c40f --- /dev/null +++ b/arch/x86/cpu/broadwell/me.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + * + * Based on code from coreboot src/soc/intel/broadwell/me_status.c + */ + +#include <common.h> +#include <errno.h> +#include <asm/arch/me.h> + +static inline void me_read_dword_ptr(struct udevice *dev, void *ptr, int offset) +{ + u32 dword; + + dm_pci_read_config32(dev, offset, &dword); + memcpy(ptr, &dword, sizeof(dword)); +} + +int intel_me_hsio_version(struct udevice *dev, uint16_t *versionp, + uint16_t *checksump) +{ + int count; + u32 hsiover; + struct me_hfs hfs; + + /* Query for HSIO version, overloads H_GS and HFS */ + dm_pci_write_config32(dev, PCI_ME_H_GS, + ME_HSIO_MESSAGE | ME_HSIO_CMD_GETHSIOVER); + + /* Must wait for ME acknowledgement */ + for (count = ME_RETRY; count > 0; --count) { + me_read_dword_ptr(dev, &hfs, PCI_ME_HFS); + if (hfs.bios_msg_ack) + break; + udelay(ME_DELAY); + } + if (!count) { + debug("ERROR: ME failed to respond\n"); + return -ETIMEDOUT; + } + + /* HSIO version should be in HFS_5 */ + dm_pci_read_config32(dev, PCI_ME_HFS5, &hsiover); + *versionp = hsiover >> 16; + *checksump = hsiover & 0xffff; + + debug("ME: HSIO Version : %d (CRC 0x%04x)\n", + *versionp, *checksump); + + /* Reset registers to normal behavior */ + dm_pci_write_config32(dev, PCI_ME_H_GS, + ME_HSIO_MESSAGE | ME_HSIO_CMD_GETHSIOVER); + + return 0; +} diff --git a/arch/x86/cpu/broadwell/northbridge.c b/arch/x86/cpu/broadwell/northbridge.c new file mode 100644 index 0000000000..aa64808e45 --- /dev/null +++ b/arch/x86/cpu/broadwell/northbridge.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2011 The Chromium Authors + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <asm/io.h> +#include <asm/arch/iomap.h> +#include <asm/arch/pch.h> + +static int broadwell_northbridge_early_init(struct udevice *dev) +{ + /* Move earlier? */ + dm_pci_write_config32(dev, PCIEXBAR + 4, 0); + /* 64MiB - 0-63 buses */ + dm_pci_write_config32(dev, PCIEXBAR, MCFG_BASE_ADDRESS | 4 | 1); + + dm_pci_write_config32(dev, MCHBAR, MCH_BASE_ADDRESS | 1); + dm_pci_write_config32(dev, DMIBAR, DMI_BASE_ADDRESS | 1); + dm_pci_write_config32(dev, EPBAR, EP_BASE_ADDRESS | 1); + writel(EDRAM_BASE_ADDRESS | 1, MCH_BASE_ADDRESS + EDRAMBAR); + writel(GDXC_BASE_ADDRESS | 1, MCH_BASE_ADDRESS + GDXCBAR); + + /* Set C0000-FFFFF to access RAM on both reads and writes */ + dm_pci_write_config8(dev, PAM0, 0x30); + dm_pci_write_config8(dev, PAM1, 0x33); + dm_pci_write_config8(dev, PAM2, 0x33); + dm_pci_write_config8(dev, PAM3, 0x33); + dm_pci_write_config8(dev, PAM4, 0x33); + dm_pci_write_config8(dev, PAM5, 0x33); + dm_pci_write_config8(dev, PAM6, 0x33); + + /* Device enable: IGD and Mini-HD */ + dm_pci_write_config32(dev, DEVEN, DEVEN_D0EN | DEVEN_D2EN | DEVEN_D3EN); + + return 0; +} + +static int broadwell_northbridge_probe(struct udevice *dev) +{ + if (!(gd->flags & GD_FLG_RELOC)) + return broadwell_northbridge_early_init(dev); + + return 0; +} + +static const struct udevice_id broadwell_northbridge_ids[] = { + { .compatible = "intel,broadwell-northbridge" }, + { } +}; + +U_BOOT_DRIVER(broadwell_northbridge_drv) = { + .name = "broadwell_northbridge", + .id = UCLASS_NORTHBRIDGE, + .of_match = broadwell_northbridge_ids, + .probe = broadwell_northbridge_probe, +}; diff --git a/arch/x86/cpu/broadwell/pch.c b/arch/x86/cpu/broadwell/pch.c new file mode 100644 index 0000000000..f0798a7f9e --- /dev/null +++ b/arch/x86/cpu/broadwell/pch.c @@ -0,0 +1,540 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <pch.h> +#include <asm/cpu.h> +#include <asm/gpio.h> +#include <asm/i8259.h> +#include <asm/intel_regs.h> +#include <asm/io.h> +#include <asm/ioapic.h> +#include <asm/lpc_common.h> +#include <asm/pch_common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/gpio.h> +#include <asm/arch/iomap.h> +#include <asm/arch/pch.h> +#include <asm/arch/pm.h> +#include <asm/arch/rcb.h> +#include <asm/arch/spi.h> + +#define BIOS_CTRL 0xdc + +bool cpu_is_ult(void) +{ + u32 fm = cpu_get_family_model(); + + return fm == BROADWELL_FAMILY_ULT || fm == HASWELL_FAMILY_ULT; +} + +static int broadwell_pch_early_init(struct udevice *dev) +{ + struct gpio_desc desc; + struct udevice *bus; + pci_dev_t bdf; + int ret; + + dm_pci_write_config32(dev, PCH_RCBA, RCB_BASE_ADDRESS | 1); + + dm_pci_write_config32(dev, PMBASE, ACPI_BASE_ADDRESS | 1); + dm_pci_write_config8(dev, ACPI_CNTL, ACPI_EN); + dm_pci_write_config32(dev, GPIO_BASE, GPIO_BASE_ADDRESS | 1); + dm_pci_write_config8(dev, GPIO_CNTL, GPIO_EN); + + /* Enable IOAPIC */ + writew(0x1000, RCB_REG(OIC)); + /* Read back for posted write */ + readw(RCB_REG(OIC)); + + /* Set HPET address and enable it */ + clrsetbits_le32(RCB_REG(HPTC), 3, 1 << 7); + /* Read back for posted write */ + readl(RCB_REG(HPTC)); + /* Enable HPET to start counter */ + setbits_le32(HPET_BASE_ADDRESS + 0x10, 1 << 0); + + setbits_le32(RCB_REG(GCS), 1 << 5); + + /* + * Enable PP3300_AUTOBAHN_EN after initial GPIO setup + * to prevent possible brownout. This will cause the GPIOs to be set + * up if it has not been done already. + */ + ret = gpio_request_by_name(dev, "power-enable-gpio", 0, &desc, + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + if (ret) + return ret; + + /* 8.14 Additional PCI Express Programming Steps, step #1 */ + bdf = PCI_BDF(0, 0x1c, 0); + bus = pci_get_controller(dev); + pci_bus_clrset_config32(bus, bdf, 0xf4, 0x60, 0); + pci_bus_clrset_config32(bus, bdf, 0xf4, 0x80, 0x80); + pci_bus_clrset_config32(bus, bdf, 0xe2, 0x30, 0x30); + + return 0; +} + +static void pch_misc_init(struct udevice *dev) +{ + /* Setup SLP signal assertion, SLP_S4=4s, SLP_S3=50ms */ + dm_pci_clrset_config8(dev, GEN_PMCON_3, 3 << 4 | 1 << 10, + 1 << 3 | 1 << 11 | 1 << 12); + /* Prepare sleep mode */ + clrsetio_32(ACPI_BASE_ADDRESS + PM1_CNT, SLP_TYP, SCI_EN); + + /* Setup NMI on errors, disable SERR */ + clrsetio_8(0x61, 0xf0, 1 << 2); + /* Disable NMI sources */ + setio_8(0x70, 1 << 7); + /* Indicate DRAM init done for MRC */ + dm_pci_clrset_config8(dev, GEN_PMCON_2, 0, 1 << 7); + + /* Clear status bits to prevent unexpected wake */ + setbits_le32(RCB_REG(0x3310), 0x0000002f); + clrsetbits_le32(RCB_REG(0x3f02), 0x0000000f, 0); + /* Enable PCIe Relaxed Order */ + setbits_le32(RCB_REG(0x2314), 1 << 31 | 1 << 7); + setbits_le32(RCB_REG(0x1114), 1 << 15 | 1 << 14); + /* Setup SERIRQ, enable continuous mode */ + dm_pci_clrset_config8(dev, SERIRQ_CNTL, 0, 1 << 7 | 1 << 6); +}; + +static void pch_enable_ioapic(void) +{ + u32 reg32; + + io_apic_set_id(0x02); + + /* affirm full set of redirection table entries ("write once") */ + reg32 = io_apic_read(0x01); + + /* PCH-LP has 39 redirection entries */ + reg32 &= ~0x00ff0000; + reg32 |= 0x00270000; + + io_apic_write(0x01, reg32); + + /* + * Select Boot Configuration register (0x03) and + * use Processor System Bus (0x01) to deliver interrupts. + */ + io_apic_write(0x03, 0x01); +} + +/* Enable all requested GPE */ +void enable_all_gpe(u32 set1, u32 set2, u32 set3, u32 set4) +{ + outl(set1, ACPI_BASE_ADDRESS + GPE0_EN(GPE_31_0)); + outl(set2, ACPI_BASE_ADDRESS + GPE0_EN(GPE_63_32)); + outl(set3, ACPI_BASE_ADDRESS + GPE0_EN(GPE_94_64)); + outl(set4, ACPI_BASE_ADDRESS + GPE0_EN(GPE_STD)); +} + +/* + * Enable GPIO SMI events - it would be good to put this in the GPIO driver + * but it would need a new driver operation. + */ +int enable_alt_smi(struct udevice *pch, u32 mask) +{ + struct pch_lp_gpio_regs *regs; + u32 gpiobase; + int ret; + + ret = pch_get_gpio_base(pch, &gpiobase); + if (ret) { + debug("%s: invalid GPIOBASE address (%08x)\n", __func__, + gpiobase); + return -EINVAL; + } + + regs = (struct pch_lp_gpio_regs *)gpiobase; + setio_32(regs->alt_gpi_smi_en, mask); + + return 0; +} + +static int pch_power_options(struct udevice *dev) +{ + int pwr_on_after_power_fail = MAINBOARD_POWER_OFF; + const char *state; + u32 enable[4]; + u16 reg16; + int ret; + + dm_pci_read_config16(dev, GEN_PMCON_3, ®16); + reg16 &= 0xfffe; + switch (pwr_on_after_power_fail) { + case MAINBOARD_POWER_OFF: + reg16 |= 1; + state = "off"; + break; + case MAINBOARD_POWER_ON: + reg16 &= ~1; + state = "on"; + break; + case MAINBOARD_POWER_KEEP: + reg16 &= ~1; + state = "state keep"; + break; + default: + state = "undefined"; + } + dm_pci_write_config16(dev, GEN_PMCON_3, reg16); + debug("Set power %s after power failure.\n", state); + + /* GPE setup based on device tree configuration */ + ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, + "intel,gpe0-en", enable, ARRAY_SIZE(enable)); + if (ret) + return -EINVAL; + enable_all_gpe(enable[0], enable[1], enable[2], enable[3]); + + /* SMI setup based on device tree configuration */ + enable_alt_smi(dev, fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "intel,alt-gp-smi-enable", 0)); + + return 0; +} + +/* Magic register settings for power management */ +static void pch_pm_init_magic(struct udevice *dev) +{ + dm_pci_write_config8(dev, 0xa9, 0x46); + clrbits_le32(RCB_REG(0x232c), 1), + setbits_le32(RCB_REG(0x1100), 0x0000c13f); + clrsetbits_le32(RCB_REG(0x2320), 0x60, 0x10); + writel(0x00012fff, RCB_REG(0x3314)); + clrsetbits_le32(RCB_REG(0x3318), 0x000f0330, 0x0dcf0400); + writel(0x04000000, RCB_REG(0x3324)); + writel(0x00041400, RCB_REG(0x3368)); + writel(0x3f8ddbff, RCB_REG(0x3388)); + writel(0x00007001, RCB_REG(0x33ac)); + writel(0x00181900, RCB_REG(0x33b0)); + writel(0x00060A00, RCB_REG(0x33c0)); + writel(0x06200840, RCB_REG(0x33d0)); + writel(0x01010101, RCB_REG(0x3a28)); + writel(0x040c0404, RCB_REG(0x3a2c)); + writel(0x9000000a, RCB_REG(0x3a9c)); + writel(0x03808033, RCB_REG(0x2b1c)); + writel(0x80000009, RCB_REG(0x2b34)); + writel(0x022ddfff, RCB_REG(0x3348)); + writel(0x00000001, RCB_REG(0x334c)); + writel(0x0001c000, RCB_REG(0x3358)); + writel(0x3f8ddbff, RCB_REG(0x3380)); + writel(0x0001c7e1, RCB_REG(0x3384)); + writel(0x0001c7e1, RCB_REG(0x338c)); + writel(0x0001c000, RCB_REG(0x3398)); + writel(0x00181900, RCB_REG(0x33a8)); + writel(0x00080000, RCB_REG(0x33dc)); + writel(0x00000001, RCB_REG(0x33e0)); + writel(0x0000040c, RCB_REG(0x3a20)); + writel(0x01010101, RCB_REG(0x3a24)); + writel(0x01010101, RCB_REG(0x3a30)); + dm_pci_clrset_config32(dev, 0xac, 0x00200000, 0); + setbits_le32(RCB_REG(0x0410), 0x00000003); + setbits_le32(RCB_REG(0x2618), 0x08000000); + setbits_le32(RCB_REG(0x2300), 0x00000002); + setbits_le32(RCB_REG(0x2600), 0x00000008); + writel(0x00007001, RCB_REG(0x33b4)); + writel(0x022ddfff, RCB_REG(0x3350)); + writel(0x00000001, RCB_REG(0x3354)); + /* Power Optimizer */ + setbits_le32(RCB_REG(0x33d4), 0x08000000); + /* + * This stops the LCD from turning on: + * setbits_le32(RCB_REG(0x33c8), 0x08000080); + */ + writel(0x0000883c, RCB_REG(0x2b10)); + writel(0x1e0a4616, RCB_REG(0x2b14)); + writel(0x40000005, RCB_REG(0x2b24)); + writel(0x0005db01, RCB_REG(0x2b20)); + writel(0x05145005, RCB_REG(0x3a80)); + writel(0x00001005, RCB_REG(0x3a84)); + setbits_le32(RCB_REG(0x33d4), 0x2fff2fb1); + setbits_le32(RCB_REG(0x33c8), 0x00008000); +}; + +static int pch_type(struct udevice *dev) +{ + u16 type; + + dm_pci_read_config16(dev, PCI_DEVICE_ID, &type); + + return type; +} + +/* Return 1 if PCH type is WildcatPoint */ +static int pch_is_wpt(struct udevice *dev) +{ + return ((pch_type(dev) & 0xfff0) == 0x9cc0) ? 1 : 0; +} + +/* Return 1 if PCH type is WildcatPoint ULX */ +static int pch_is_wpt_ulx(struct udevice *dev) +{ + u16 lpcid = pch_type(dev); + + switch (lpcid) { + case PCH_WPT_BDW_Y_SAMPLE: + case PCH_WPT_BDW_Y_PREMIUM: + case PCH_WPT_BDW_Y_BASE: + return 1; + } + + return 0; +} + +static u32 pch_read_soft_strap(int id) +{ + clrbits_le32(SPI_REG(SPIBAR_FDOC), 0x00007ffc); + setbits_le32(SPI_REG(SPIBAR_FDOC), 0x00004000 | id * 4); + + return readl(SPI_REG(SPIBAR_FDOD)); +} + +static void pch_enable_mphy(struct udevice *dev) +{ + u32 data_and = 0xffffffff; + u32 data_or = (1 << 14) | (1 << 13) | (1 << 12); + + data_or |= (1 << 0); + if (pch_is_wpt(dev)) { + data_and &= ~((1 << 7) | (1 << 6) | (1 << 3)); + data_or |= (1 << 5) | (1 << 4); + + if (pch_is_wpt_ulx(dev)) { + /* Check if SATA and USB3 MPHY are enabled */ + u32 strap19 = pch_read_soft_strap(19); + strap19 &= ((1 << 31) | (1 << 30)); + strap19 >>= 30; + if (strap19 == 3) { + data_or |= (1 << 3); + debug("Enable ULX MPHY PG control in single domain\n"); + } else if (strap19 == 0) { + debug("Enable ULX MPHY PG control in split domains\n"); + } else { + debug("Invalid PCH Soft Strap 19 configuration\n"); + } + } else { + data_or |= (1 << 3); + } + } + + pch_iobp_update(0xCF000000, data_and, data_or); +} + +static void pch_init_deep_sx(bool deep_sx_enable_ac, bool deep_sx_enable_dc) +{ + if (deep_sx_enable_ac) { + setbits_le32(RCB_REG(DEEP_S3_POL), DEEP_S3_EN_AC); + setbits_le32(RCB_REG(DEEP_S5_POL), DEEP_S5_EN_AC); + } + + if (deep_sx_enable_dc) { + setbits_le32(RCB_REG(DEEP_S3_POL), DEEP_S3_EN_DC); + setbits_le32(RCB_REG(DEEP_S5_POL), DEEP_S5_EN_DC); + } + + if (deep_sx_enable_ac || deep_sx_enable_dc) { + setbits_le32(RCB_REG(DEEP_SX_CONFIG), + DEEP_SX_WAKE_PIN_EN | DEEP_SX_GP27_PIN_EN); + } +} + +/* Power Management init */ +static void pch_pm_init(struct udevice *dev) +{ + debug("PCH PM init\n"); + + pch_init_deep_sx(false, false); + pch_enable_mphy(dev); + pch_pm_init_magic(dev); + + if (pch_is_wpt(dev)) { + setbits_le32(RCB_REG(0x33e0), 1 << 4 | 1 << 1); + setbits_le32(RCB_REG(0x2b1c), 1 << 22 | 1 << 14 | 1 << 13); + writel(0x16bf0002, RCB_REG(0x33e4)); + setbits_le32(RCB_REG(0x33e4), 0x1); + } + + pch_iobp_update(0xCA000000, ~0UL, 0x00000009); + + /* Set RCBA 0x2b1c[29]=1 if DSP disabled */ + if (readl(RCB_REG(FD)) & PCH_DISABLE_ADSPD) + setbits_le32(RCB_REG(0x2b1c), 1 << 29); +} + +static void pch_cg_init(struct udevice *dev) +{ + struct udevice *bus = pci_get_controller(dev); + u32 reg32; + u16 reg16; + ulong val; + + /* DMI */ + setbits_le32(RCB_REG(0x2234), 0xf); + + dm_pci_read_config16(dev, GEN_PMCON_1, ®16); + reg16 &= ~(1 << 10); /* Disable BIOS_PCI_EXP_EN for native PME */ + if (pch_is_wpt(dev)) + reg16 &= ~(1 << 11); + else + reg16 |= 1 << 11; + reg16 |= 1 << 5 | 1 << 6 | 1 << 7 | 1 << 12; + reg16 |= 1 << 2; /* PCI CLKRUN# Enable */ + dm_pci_write_config16(dev, GEN_PMCON_1, reg16); + + /* + * RCBA + 0x2614[27:25,14:13,10,8] = 101,11,1,1 + * RCBA + 0x2614[23:16] = 0x20 + * RCBA + 0x2614[30:28] = 0x0 + * RCBA + 0x2614[26] = 1 (IF 0:2.0@0x08 >= 0x0b) + */ + clrsetbits_le32(RCB_REG(0x2614), 0x64ff0000, 0x0a206500); + + /* Check for 0:2.0@0x08 >= 0x0b */ + pci_bus_read_config(bus, PCI_BDF(0, 0x2, 0), 0x8, &val, PCI_SIZE_8); + if (pch_is_wpt(dev) || val >= 0x0b) + setbits_le32(RCB_REG(0x2614), 1 << 26); + + setbits_le32(RCB_REG(0x900), 0x0000031f); + + reg32 = readl(RCB_REG(CG)); + if (readl(RCB_REG(0x3454)) & (1 << 4)) + reg32 &= ~(1 << 29); /* LPC Dynamic */ + else + reg32 |= (1 << 29); /* LPC Dynamic */ + reg32 |= 1 << 31; /* LP LPC */ + reg32 |= 1 << 30; /* LP BLA */ + if (readl(RCB_REG(0x3454)) & (1 << 4)) + reg32 &= ~(1 << 29); + else + reg32 |= 1 << 29; + reg32 |= 1 << 28; /* GPIO Dynamic */ + reg32 |= 1 << 27; /* HPET Dynamic */ + reg32 |= 1 << 26; /* Generic Platform Event Clock */ + if (readl(RCB_REG(BUC)) & PCH_DISABLE_GBE) + reg32 |= 1 << 23; /* GbE Static */ + if (readl(RCB_REG(FD)) & PCH_DISABLE_HD_AUDIO) + reg32 |= 1 << 21; /* HDA Static */ + reg32 |= 1 << 22; /* HDA Dynamic */ + writel(reg32, RCB_REG(CG)); + + /* PCH-LP LPC */ + if (pch_is_wpt(dev)) + clrsetbits_le32(RCB_REG(0x3434), 0x1f, 0x17); + else + setbits_le32(RCB_REG(0x3434), 0x7); + + /* SPI */ + setbits_le32(RCB_REG(0x38c0), 0x3c07); + + pch_iobp_update(0xCE00C000, ~1UL, 0x00000000); +} + +static void systemagent_init(void) +{ + /* Enable Power Aware Interrupt Routing */ + clrsetbits_8(MCHBAR_REG(MCH_PAIR), 0x7, 0x4); /* Fixed Priority */ + + /* + * Set bits 0+1 of BIOS_RESET_CPL to indicate to the CPU + * that BIOS has initialized memory and power management + */ + setbits_8(MCHBAR_REG(BIOS_RESET_CPL), 3); + debug("Set BIOS_RESET_CPL\n"); + + /* Configure turbo power limits 1ms after reset complete bit */ + mdelay(1); + + cpu_set_power_limits(28); +} + +static int broadwell_pch_init(struct udevice *dev) +{ + int ret; + + /* Enable upper 128 bytes of CMOS */ + setbits_le32(RCB_REG(RC), 1 << 2); + + /* + * TODO: TCO timer halt - this hangs + * setio_16(ACPI_BASE_ADDRESS + TCO1_CNT, TCO_TMR_HLT); + */ + + /* Disable unused device (always) */ + setbits_le32(RCB_REG(FD), PCH_DISABLE_ALWAYS); + + pch_misc_init(dev); + + /* Interrupt configuration */ + pch_enable_ioapic(); + + /* Initialize power management */ + ret = pch_power_options(dev); + if (ret) + return ret; + pch_pm_init(dev); + pch_cg_init(dev); + systemagent_init(); + + return 0; +} + +static int broadwell_pch_probe(struct udevice *dev) +{ + if (!(gd->flags & GD_FLG_RELOC)) + return broadwell_pch_early_init(dev); + else + return broadwell_pch_init(dev); +} + +static int broadwell_pch_get_spi_base(struct udevice *dev, ulong *sbasep) +{ + u32 rcba; + + dm_pci_read_config32(dev, PCH_RCBA, &rcba); + /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable */ + rcba = rcba & 0xffffc000; + *sbasep = rcba + 0x3800; + + return 0; +} + +static int broadwell_set_spi_protect(struct udevice *dev, bool protect) +{ + return lpc_set_spi_protect(dev, BIOS_CTRL, protect); +} + +static int broadwell_get_gpio_base(struct udevice *dev, u32 *gbasep) +{ + dm_pci_read_config32(dev, GPIO_BASE, gbasep); + *gbasep &= PCI_BASE_ADDRESS_IO_MASK; + + return 0; +} + +static const struct pch_ops broadwell_pch_ops = { + .get_spi_base = broadwell_pch_get_spi_base, + .set_spi_protect = broadwell_set_spi_protect, + .get_gpio_base = broadwell_get_gpio_base, +}; + +static const struct udevice_id broadwell_pch_ids[] = { + { .compatible = "intel,broadwell-pch" }, + { } +}; + +U_BOOT_DRIVER(broadwell_pch) = { + .name = "broadwell_pch", + .id = UCLASS_PCH, + .of_match = broadwell_pch_ids, + .probe = broadwell_pch_probe, + .ops = &broadwell_pch_ops, +}; diff --git a/arch/x86/cpu/broadwell/pinctrl_broadwell.c b/arch/x86/cpu/broadwell/pinctrl_broadwell.c new file mode 100644 index 0000000000..2a3fcedd0d --- /dev/null +++ b/arch/x86/cpu/broadwell/pinctrl_broadwell.c @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <pch.h> +#include <pci.h> +#include <asm/cpu.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <asm/pci.h> +#include <asm/arch/gpio.h> +#include <dt-bindings/gpio/x86-gpio.h> +#include <dm/pinctrl.h> + +DECLARE_GLOBAL_DATA_PTR; + +enum { + MAX_GPIOS = 95, +}; + +#define PIRQ_SHIFT 16 +#define CONF_MASK 0xffff + +struct pin_info { + int node; + int phandle; + bool mode_gpio; + bool dir_input; + bool invert; + bool trigger_level; + bool output_high; + bool sense_disable; + bool owner_gpio; + bool route_smi; + bool irq_enable; + bool reset_rsmrst; + bool pirq_apic_route; +}; + +static int broadwell_pinctrl_read_configs(struct udevice *dev, + struct pin_info *conf, int max_pins) +{ + const void *blob = gd->fdt_blob; + int count = 0; + int node; + + debug("%s: starting\n", __func__); + for (node = fdt_first_subnode(blob, dev->of_offset); + node > 0; + node = fdt_next_subnode(blob, node)) { + int phandle = fdt_get_phandle(blob, node); + + if (!phandle) + continue; + if (count == max_pins) + return -ENOSPC; + + /* We've found a new configuration */ + memset(conf, '\0', sizeof(*conf)); + conf->node = node; + conf->phandle = phandle; + conf->mode_gpio = fdtdec_get_bool(blob, node, "mode-gpio"); + if (fdtdec_get_int(blob, node, "direction", -1) == PIN_INPUT) + conf->dir_input = true; + conf->invert = fdtdec_get_bool(blob, node, "invert"); + if (fdtdec_get_int(blob, node, "trigger", -1) == TRIGGER_LEVEL) + conf->trigger_level = true; + if (fdtdec_get_int(blob, node, "output-value", -1) == 1) + conf->output_high = true; + conf->sense_disable = fdtdec_get_bool(blob, node, + "sense-disable"); + if (fdtdec_get_int(blob, node, "owner", -1) == OWNER_GPIO) + conf->owner_gpio = true; + if (fdtdec_get_int(blob, node, "route", -1) == ROUTE_SMI) + conf->route_smi = true; + conf->irq_enable = fdtdec_get_bool(blob, node, "irq-enable"); + conf->reset_rsmrst = fdtdec_get_bool(blob, node, + "reset-rsmrst"); + if (fdtdec_get_int(blob, node, "pirq-apic", -1) == + PIRQ_APIC_ROUTE) + conf->pirq_apic_route = true; + debug("config: phandle=%d\n", phandle); + count++; + conf++; + } + debug("%s: Found %d configurations\n", __func__, count); + + return count; +} + +static int broadwell_pinctrl_lookup_phandle(struct pin_info *conf, + int conf_count, int phandle) +{ + int i; + + for (i = 0; i < conf_count; i++) { + if (conf[i].phandle == phandle) + return i; + } + + return -ENOENT; +} + +static int broadwell_pinctrl_read_pins(struct udevice *dev, + struct pin_info *conf, int conf_count, int gpio_conf[], + int num_gpios) +{ + const void *blob = gd->fdt_blob; + int count = 0; + int node; + + for (node = fdt_first_subnode(blob, dev->of_offset); + node > 0; + node = fdt_next_subnode(blob, node)) { + int len, i; + const u32 *prop = fdt_getprop(blob, node, "config", &len); + + if (!prop) + continue; + + /* There are three cells per pin */ + count = len / (sizeof(u32) * 3); + debug("Found %d GPIOs to configure\n", count); + for (i = 0; i < count; i++) { + uint gpio = fdt32_to_cpu(prop[i * 3]); + uint phandle = fdt32_to_cpu(prop[i * 3 + 1]); + int val; + + if (gpio >= num_gpios) { + debug("%s: GPIO %d out of range\n", __func__, + gpio); + return -EDOM; + } + val = broadwell_pinctrl_lookup_phandle(conf, conf_count, + phandle); + if (val < 0) { + debug("%s: Cannot find phandle %d\n", __func__, + phandle); + return -EINVAL; + } + gpio_conf[gpio] = val | + fdt32_to_cpu(prop[i * 3 + 2]) << PIRQ_SHIFT; + } + } + + return 0; +} + +static void broadwell_pinctrl_commit(struct pch_lp_gpio_regs *regs, + struct pin_info *pin_info, + int gpio_conf[], int count) +{ + u32 owner_gpio[GPIO_BANKS] = {0}; + u32 route_smi[GPIO_BANKS] = {0}; + u32 irq_enable[GPIO_BANKS] = {0}; + u32 reset_rsmrst[GPIO_BANKS] = {0}; + u32 pirq2apic = 0; + int set, bit, gpio = 0; + + for (gpio = 0; gpio < MAX_GPIOS; gpio++) { + int confnum = gpio_conf[gpio] & CONF_MASK; + struct pin_info *pin = &pin_info[confnum]; + u32 val; + + val = pin->mode_gpio << CONFA_MODE_SHIFT | + pin->dir_input << CONFA_DIR_SHIFT | + pin->invert << CONFA_INVERT_SHIFT | + pin->trigger_level << CONFA_TRIGGER_SHIFT | + pin->output_high << CONFA_OUTPUT_SHIFT; + outl(val, ®s->config[gpio].conf_a); + outl(pin->sense_disable << CONFB_SENSE_SHIFT, + ®s->config[gpio].conf_b); + + /* Determine set and bit based on GPIO number */ + set = gpio / GPIO_PER_BANK; + bit = gpio % GPIO_PER_BANK; + + /* Apply settings to set specific bits */ + owner_gpio[set] |= pin->owner_gpio << bit; + route_smi[set] |= pin->route_smi << bit; + irq_enable[set] |= pin->irq_enable << bit; + reset_rsmrst[set] |= pin->reset_rsmrst << bit; + + /* PIRQ to IO-APIC map */ + if (pin->pirq_apic_route) + pirq2apic |= gpio_conf[gpio] >> PIRQ_SHIFT; + debug("gpio %d: conf %d, mode_gpio %d, dir_input %d, output_high %d\n", + gpio, confnum, pin->mode_gpio, pin->dir_input, + pin->output_high); + } + + for (set = 0; set < GPIO_BANKS; set++) { + outl(owner_gpio[set], ®s->own[set]); + outl(route_smi[set], ®s->gpi_route[set]); + outl(irq_enable[set], ®s->gpi_ie[set]); + outl(reset_rsmrst[set], ®s->rst_sel[set]); + } + + outl(pirq2apic, ®s->pirq_to_ioxapic); +} + +static int broadwell_pinctrl_probe(struct udevice *dev) +{ + struct pch_lp_gpio_regs *regs; + struct pin_info conf[12]; + int gpio_conf[MAX_GPIOS]; + struct udevice *pch; + int conf_count; + u32 gpiobase; + int ret; + + ret = uclass_first_device(UCLASS_PCH, &pch); + if (ret) + return ret; + if (!pch) + return -ENODEV; + debug("%s: start\n", __func__); + + /* Only init once, before relocation */ + if (gd->flags & GD_FLG_RELOC) + return 0; + + /* + * Get the memory/io base address to configure every pins. + * IOBASE is used to configure the mode/pads + * GPIOBASE is used to configure the direction and default value + */ + ret = pch_get_gpio_base(pch, &gpiobase); + if (ret) { + debug("%s: invalid GPIOBASE address (%08x)\n", __func__, + gpiobase); + return -EINVAL; + } + + conf_count = broadwell_pinctrl_read_configs(dev, conf, + ARRAY_SIZE(conf)); + if (conf_count < 0) { + debug("%s: Cannot read configs: err=%d\n", __func__, ret); + return conf_count; + } + + /* + * Assume that pin settings are provided for every pin. Pins not + * mentioned will get the first config mentioned in the list. + */ + ret = broadwell_pinctrl_read_pins(dev, conf, conf_count, gpio_conf, + MAX_GPIOS); + if (ret) { + debug("%s: Cannot read pin settings: err=%d\n", __func__, ret); + return ret; + } + + regs = (struct pch_lp_gpio_regs *)gpiobase; + broadwell_pinctrl_commit(regs, conf, gpio_conf, ARRAY_SIZE(conf)); + + debug("%s: done\n", __func__); + + return 0; +} + +static const struct udevice_id broadwell_pinctrl_match[] = { + { .compatible = "intel,x86-broadwell-pinctrl", + .data = X86_SYSCON_PINCONF }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(broadwell_pinctrl) = { + .name = "broadwell_pinctrl", + .id = UCLASS_SYSCON, + .of_match = broadwell_pinctrl_match, + .probe = broadwell_pinctrl_probe, +}; diff --git a/arch/x86/cpu/broadwell/power_state.c b/arch/x86/cpu/broadwell/power_state.c new file mode 100644 index 0000000000..2b9a6bf3a1 --- /dev/null +++ b/arch/x86/cpu/broadwell/power_state.c @@ -0,0 +1,90 @@ +/* + * From coreboot src/soc/intel/broadwell/romstage/power_state.c + * + * Copyright (C) 2016 Google, Inc. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <pci.h> +#include <asm/io.h> +#include <asm/intel_regs.h> +#include <asm/arch/iomap.h> +#include <asm/arch/lpc.h> +#include <asm/arch/pch.h> +#include <asm/arch/pm.h> + +/* Return 0, 3, or 5 to indicate the previous sleep state. */ +static int prev_sleep_state(struct chipset_power_state *ps) +{ + /* Default to S0. */ + int prev_sleep_state = SLEEP_STATE_S0; + + if (ps->pm1_sts & WAK_STS) { + switch ((ps->pm1_cnt & SLP_TYP) >> SLP_TYP_SHIFT) { +#if CONFIG_HAVE_ACPI_RESUME + case SLP_TYP_S3: + prev_sleep_state = SLEEP_STATE_S3; + break; +#endif + case SLP_TYP_S5: + prev_sleep_state = SLEEP_STATE_S5; + break; + } + /* Clear SLP_TYP. */ + outl(ps->pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT); + } + + if (ps->gen_pmcon3 & (PWR_FLR | SUS_PWR_FLR)) + prev_sleep_state = SLEEP_STATE_S5; + + return prev_sleep_state; +} + +static void dump_power_state(struct chipset_power_state *ps) +{ + debug("PM1_STS: %04x\n", ps->pm1_sts); + debug("PM1_EN: %04x\n", ps->pm1_en); + debug("PM1_CNT: %08x\n", ps->pm1_cnt); + debug("TCO_STS: %04x %04x\n", ps->tco1_sts, ps->tco2_sts); + + debug("GPE0_STS: %08x %08x %08x %08x\n", + ps->gpe0_sts[0], ps->gpe0_sts[1], + ps->gpe0_sts[2], ps->gpe0_sts[3]); + debug("GPE0_EN: %08x %08x %08x %08x\n", + ps->gpe0_en[0], ps->gpe0_en[1], + ps->gpe0_en[2], ps->gpe0_en[3]); + + debug("GEN_PMCON: %04x %04x %04x\n", + ps->gen_pmcon1, ps->gen_pmcon2, ps->gen_pmcon3); + + debug("Previous Sleep State: S%d\n", + ps->prev_sleep_state); +} + +/* Fill power state structure from ACPI PM registers */ +void power_state_get(struct udevice *pch_dev, struct chipset_power_state *ps) +{ + ps->pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS); + ps->pm1_en = inw(ACPI_BASE_ADDRESS + PM1_EN); + ps->pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT); + ps->tco1_sts = inw(ACPI_BASE_ADDRESS + TCO1_STS); + ps->tco2_sts = inw(ACPI_BASE_ADDRESS + TCO2_STS); + ps->gpe0_sts[0] = inl(ACPI_BASE_ADDRESS + GPE0_STS(0)); + ps->gpe0_sts[1] = inl(ACPI_BASE_ADDRESS + GPE0_STS(1)); + ps->gpe0_sts[2] = inl(ACPI_BASE_ADDRESS + GPE0_STS(2)); + ps->gpe0_sts[3] = inl(ACPI_BASE_ADDRESS + GPE0_STS(3)); + ps->gpe0_en[0] = inl(ACPI_BASE_ADDRESS + GPE0_EN(0)); + ps->gpe0_en[1] = inl(ACPI_BASE_ADDRESS + GPE0_EN(1)); + ps->gpe0_en[2] = inl(ACPI_BASE_ADDRESS + GPE0_EN(2)); + ps->gpe0_en[3] = inl(ACPI_BASE_ADDRESS + GPE0_EN(3)); + + dm_pci_read_config16(pch_dev, GEN_PMCON_1, &ps->gen_pmcon1); + dm_pci_read_config16(pch_dev, GEN_PMCON_2, &ps->gen_pmcon2); + dm_pci_read_config16(pch_dev, GEN_PMCON_3, &ps->gen_pmcon3); + + ps->prev_sleep_state = prev_sleep_state(ps); + + dump_power_state(ps); +} diff --git a/arch/x86/cpu/broadwell/refcode.c b/arch/x86/cpu/broadwell/refcode.c new file mode 100644 index 0000000000..436c6c49c3 --- /dev/null +++ b/arch/x86/cpu/broadwell/refcode.c @@ -0,0 +1,113 @@ +/* + * Read a coreboot rmodule and execute it. + * The rmodule_header struct is from coreboot. + * + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <errno.h> +#include <asm/arch/pei_data.h> + +#define RMODULE_MAGIC 0xf8fe +#define RMODULE_VERSION_1 1 + +/* + * All fields with '_offset' in the name are byte offsets into the flat blob. + * The linker and the linker script takes are of assigning the values. + */ +struct rmodule_header { + uint16_t magic; + uint8_t version; + uint8_t type; + /* The payload represents the program's loadable code and data */ + uint32_t payload_begin_offset; + uint32_t payload_end_offset; + /* Begin and of relocation information about the program module */ + uint32_t relocations_begin_offset; + uint32_t relocations_end_offset; + /* + * The starting address of the linked program. This address is vital + * for determining relocation offsets as the relocation info and other + * symbols (bss, entry point) need this value as a basis to calculate + * the offsets. + */ + uint32_t module_link_start_address; + /* + * The module_program_size is the size of memory used while running + * the program. The program is assumed to consume a contiguous amount + * of memory + */ + uint32_t module_program_size; + /* This is program's execution entry point */ + uint32_t module_entry_point; + /* + * Optional parameter structure that can be used to pass data into + * the module + */ + uint32_t parameters_begin; + uint32_t parameters_end; + /* BSS section information so the loader can clear the bss */ + uint32_t bss_begin; + uint32_t bss_end; + /* Add some room for growth */ + uint32_t padding[4]; +} __packed; + +int cpu_run_reference_code(void) +{ + struct pei_data _pei_data __aligned(8); + struct pei_data *pei_data = &_pei_data; + asmlinkage int (*func)(void *); + struct rmodule_header *hdr; + char *src, *dest; + int ret, dummy; + int size; + + hdr = (struct rmodule_header *)CONFIG_X86_REFCODE_ADDR; + debug("Extracting code from rmodule at %p\n", hdr); + if (hdr->magic != RMODULE_MAGIC) { + debug("Invalid rmodule magic\n"); + return -EINVAL; + } + if (hdr->module_link_start_address != 0) { + debug("Link start address must be 0\n"); + return -EPERM; + } + if (hdr->module_entry_point != 0) { + debug("Entry point must be 0\n"); + return -EPERM; + } + + memset(pei_data, '\0', sizeof(struct pei_data)); + broadwell_fill_pei_data(pei_data); + mainboard_fill_pei_data(pei_data); + pei_data->saved_data = (void *)&dummy; + + src = (char *)hdr + hdr->payload_begin_offset; + dest = (char *)CONFIG_X86_REFCODE_RUN_ADDR; + + size = hdr->payload_end_offset - hdr->payload_begin_offset; + debug("Copying refcode from %p to %p, size %x\n", src, dest, size); + memcpy(dest, src, size); + + size = hdr->bss_end - hdr->bss_begin; + debug("Zeroing BSS at %p, size %x\n", dest + hdr->bss_begin, size); + memset(dest + hdr->bss_begin, '\0', size); + + func = (asmlinkage int (*)(void *))dest; + debug("Running reference code at %p\n", func); +#ifdef DEBUG + print_buffer(CONFIG_X86_REFCODE_RUN_ADDR, (void *)func, 1, 0x40, 0); +#endif + ret = func(pei_data); + if (ret != 0) { + debug("Reference code returned %d\n", ret); + return -EL2HLT; + } + debug("Refereence code completed\n"); + + return 0; +} diff --git a/arch/x86/cpu/broadwell/sata.c b/arch/x86/cpu/broadwell/sata.c new file mode 100644 index 0000000000..dfb8486d06 --- /dev/null +++ b/arch/x86/cpu/broadwell/sata.c @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * From coreboot src/soc/intel/broadwell/sata.c + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <asm/intel_regs.h> +#include <asm/lpc_common.h> +#include <asm/pch_common.h> +#include <asm/pch_common.h> +#include <asm/arch/pch.h> + +struct sata_platdata { + int port_map; + uint port0_gen3_tx; + uint port1_gen3_tx; + uint port0_gen3_dtle; + uint port1_gen3_dtle; + + /* + * SATA DEVSLP Mux + * 0 = port 0 DEVSLP on DEVSLP0/GPIO33 + * 1 = port 3 DEVSLP on DEVSLP0/GPIO33 + */ + int devslp_mux; + + /* + * DEVSLP Disable + * 0: DEVSLP is enabled + * 1: DEVSLP is disabled + */ + int devslp_disable; +}; + +static void broadwell_sata_init(struct udevice *dev) +{ + struct sata_platdata *plat = dev_get_platdata(dev); + u32 reg32; + u8 *abar; + u16 reg16; + int port; + + debug("SATA: Initializing controller in AHCI mode.\n"); + + /* Set timings */ + dm_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE); + dm_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE); + + /* for AHCI, Port Enable is managed in memory mapped space */ + dm_pci_read_config16(dev, 0x92, ®16); + reg16 &= ~0xf; + reg16 |= 0x8000 | plat->port_map; + dm_pci_write_config16(dev, 0x92, reg16); + udelay(2); + + /* Setup register 98h */ + dm_pci_read_config32(dev, 0x98, ®32); + reg32 &= ~((1 << 31) | (1 << 30)); + reg32 |= 1 << 23; + reg32 |= 1 << 24; /* Enable MPHY Dynamic Power Gating */ + dm_pci_write_config32(dev, 0x98, reg32); + + /* Setup register 9Ch */ + reg16 = 0; /* Disable alternate ID */ + reg16 = 1 << 5; /* BWG step 12 */ + dm_pci_write_config16(dev, 0x9c, reg16); + + /* SATA Initialization register */ + reg32 = 0x183; + reg32 |= (plat->port_map ^ 0xf) << 24; + reg32 |= (plat->devslp_mux & 1) << 15; + dm_pci_write_config32(dev, 0x94, reg32); + + /* Initialize AHCI memory-mapped space */ + dm_pci_read_config32(dev, PCI_BASE_ADDRESS_5, ®32); + abar = (u8 *)reg32; + debug("ABAR: %p\n", abar); + + /* CAP (HBA Capabilities) : enable power management */ + clrsetbits_le32(abar + 0x00, 0x00020060 /* SXS+EMS+PMS */, + 0x0c006000 /* PSC+SSC+SALP+SSS */ | + 1 << 18); /* SAM: SATA AHCI MODE ONLY */ + + /* PI (Ports implemented) */ + writel(plat->port_map, abar + 0x0c); + (void) readl(abar + 0x0c); /* Read back 1 */ + (void) readl(abar + 0x0c); /* Read back 2 */ + + /* CAP2 (HBA Capabilities Extended)*/ + if (plat->devslp_disable) { + clrbits_le32(abar + 0x24, 1 << 3); + } else { + /* Enable DEVSLP */ + setbits_le32(abar + 0x24, 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2); + + for (port = 0; port < 4; port++) { + if (!(plat->port_map & (1 << port))) + continue; + /* DEVSLP DSP */ + setbits_le32(abar + 0x144 + (0x80 * port), 1 << 1); + } + } + + /* Static Power Gating for unused ports */ + reg32 = readl(RCB_REG(0x3a84)); + /* Port 3 and 2 disabled */ + if ((plat->port_map & ((1 << 3)|(1 << 2))) == 0) + reg32 |= (1 << 24) | (1 << 26); + /* Port 1 and 0 disabled */ + if ((plat->port_map & ((1 << 1)|(1 << 0))) == 0) + reg32 |= (1 << 20) | (1 << 18); + writel(reg32, RCB_REG(0x3a84)); + + /* Set Gen3 Transmitter settings if needed */ + if (plat->port0_gen3_tx) + pch_iobp_update(SATA_IOBP_SP0_SECRT88, + ~(SATA_SECRT88_VADJ_MASK << + SATA_SECRT88_VADJ_SHIFT), + (plat->port0_gen3_tx & + SATA_SECRT88_VADJ_MASK) + << SATA_SECRT88_VADJ_SHIFT); + + if (plat->port1_gen3_tx) + pch_iobp_update(SATA_IOBP_SP1_SECRT88, + ~(SATA_SECRT88_VADJ_MASK << + SATA_SECRT88_VADJ_SHIFT), + (plat->port1_gen3_tx & + SATA_SECRT88_VADJ_MASK) + << SATA_SECRT88_VADJ_SHIFT); + + /* Set Gen3 DTLE DATA / EDGE registers if needed */ + if (plat->port0_gen3_dtle) { + pch_iobp_update(SATA_IOBP_SP0DTLE_DATA, + ~(SATA_DTLE_MASK << SATA_DTLE_DATA_SHIFT), + (plat->port0_gen3_dtle & SATA_DTLE_MASK) + << SATA_DTLE_DATA_SHIFT); + + pch_iobp_update(SATA_IOBP_SP0DTLE_EDGE, + ~(SATA_DTLE_MASK << SATA_DTLE_EDGE_SHIFT), + (plat->port0_gen3_dtle & SATA_DTLE_MASK) + << SATA_DTLE_EDGE_SHIFT); + } + + if (plat->port1_gen3_dtle) { + pch_iobp_update(SATA_IOBP_SP1DTLE_DATA, + ~(SATA_DTLE_MASK << SATA_DTLE_DATA_SHIFT), + (plat->port1_gen3_dtle & SATA_DTLE_MASK) + << SATA_DTLE_DATA_SHIFT); + + pch_iobp_update(SATA_IOBP_SP1DTLE_EDGE, + ~(SATA_DTLE_MASK << SATA_DTLE_EDGE_SHIFT), + (plat->port1_gen3_dtle & SATA_DTLE_MASK) + << SATA_DTLE_EDGE_SHIFT); + } + + /* + * Additional Programming Requirements for Power Optimizer + */ + + /* Step 1 */ + pch_common_sir_write(dev, 0x64, 0x883c9003); + + /* Step 2: SIR 68h[15:0] = 880Ah */ + reg32 = pch_common_sir_read(dev, 0x68); + reg32 &= 0xffff0000; + reg32 |= 0x880a; + pch_common_sir_write(dev, 0x68, reg32); + + /* Step 3: SIR 60h[3] = 1 */ + reg32 = pch_common_sir_read(dev, 0x60); + reg32 |= (1 << 3); + pch_common_sir_write(dev, 0x60, reg32); + + /* Step 4: SIR 60h[0] = 1 */ + reg32 = pch_common_sir_read(dev, 0x60); + reg32 |= (1 << 0); + pch_common_sir_write(dev, 0x60, reg32); + + /* Step 5: SIR 60h[1] = 1 */ + reg32 = pch_common_sir_read(dev, 0x60); + reg32 |= (1 << 1); + pch_common_sir_write(dev, 0x60, reg32); + + /* Clock Gating */ + pch_common_sir_write(dev, 0x70, 0x3f00bf1f); + pch_common_sir_write(dev, 0x54, 0xcf000f0f); + pch_common_sir_write(dev, 0x58, 0x00190000); + clrsetbits_le32(RCB_REG(0x333c), 0x00300000, 0x00c00000); + + dm_pci_read_config32(dev, 0x300, ®32); + reg32 |= 1 << 17 | 1 << 16 | 1 << 19; + reg32 |= 1 << 31 | 1 << 30 | 1 << 29; + dm_pci_write_config32(dev, 0x300, reg32); + + dm_pci_read_config32(dev, 0x98, ®32); + reg32 |= 1 << 29; + dm_pci_write_config32(dev, 0x98, reg32); + + /* Register Lock */ + dm_pci_read_config32(dev, 0x9c, ®32); + reg32 |= 1 << 31; + dm_pci_write_config32(dev, 0x9c, reg32); +} + +static int broadwell_sata_enable(struct udevice *dev) +{ + struct sata_platdata *plat = dev_get_platdata(dev); + struct gpio_desc desc; + u16 map; + int ret; + + /* + * Set SATA controller mode early so the resource allocator can + * properly assign IO/Memory resources for the controller. + */ + map = 0x0060; + + map |= (plat->port_map ^ 0x3f) << 8; + dm_pci_write_config16(dev, 0x90, map); + + ret = gpio_request_by_name(dev, "reset-gpio", 0, &desc, GPIOD_IS_OUT); + if (ret) + return ret; + + return 0; +} + +static int broadwell_sata_ofdata_to_platdata(struct udevice *dev) +{ + struct sata_platdata *plat = dev_get_platdata(dev); + const void *blob = gd->fdt_blob; + int node = dev->of_offset; + + plat->port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0); + plat->port0_gen3_tx = fdtdec_get_int(blob, node, + "intel,sata-port0-gen3-tx", 0); + + return 0; +} + +static int broadwell_sata_probe(struct udevice *dev) +{ + if (!(gd->flags & GD_FLG_RELOC)) + return broadwell_sata_enable(dev); + else + broadwell_sata_init(dev); + + return 0; +} + +static const struct udevice_id broadwell_ahci_ids[] = { + { .compatible = "intel,wildcatpoint-ahci" }, + { } +}; + +U_BOOT_DRIVER(ahci_broadwell_drv) = { + .name = "ahci_broadwell", + .id = UCLASS_DISK, + .of_match = broadwell_ahci_ids, + .ofdata_to_platdata = broadwell_sata_ofdata_to_platdata, + .probe = broadwell_sata_probe, + .platdata_auto_alloc_size = sizeof(struct sata_platdata), +}; diff --git a/arch/x86/cpu/broadwell/sdram.c b/arch/x86/cpu/broadwell/sdram.c new file mode 100644 index 0000000000..4bf5d15b26 --- /dev/null +++ b/arch/x86/cpu/broadwell/sdram.c @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * From coreboot src/soc/intel/broadwell/romstage/raminit.c + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <pci.h> +#include <syscon.h> +#include <asm/cpu.h> +#include <asm/io.h> +#include <asm/lpc_common.h> +#include <asm/mrccache.h> +#include <asm/mrc_common.h> +#include <asm/mtrr.h> +#include <asm/pci.h> +#include <asm/arch/iomap.h> +#include <asm/arch/me.h> +#include <asm/arch/pch.h> +#include <asm/arch/pei_data.h> +#include <asm/arch/pm.h> + +ulong board_get_usable_ram_top(ulong total_size) +{ + return mrc_common_board_get_usable_ram_top(total_size); +} + +void dram_init_banksize(void) +{ + mrc_common_dram_init_banksize(); +} + +void broadwell_fill_pei_data(struct pei_data *pei_data) +{ + pei_data->pei_version = PEI_VERSION; + pei_data->board_type = BOARD_TYPE_ULT; + pei_data->pciexbar = MCFG_BASE_ADDRESS; + pei_data->smbusbar = SMBUS_BASE_ADDRESS; + pei_data->ehcibar = EARLY_EHCI_BAR; + pei_data->xhcibar = EARLY_XHCI_BAR; + pei_data->gttbar = EARLY_GTT_BAR; + pei_data->pmbase = ACPI_BASE_ADDRESS; + pei_data->gpiobase = GPIO_BASE_ADDRESS; + pei_data->tseg_size = CONFIG_SMM_TSEG_SIZE; + pei_data->temp_mmio_base = EARLY_TEMP_MMIO; + pei_data->tx_byte = sdram_console_tx_byte; + pei_data->ddr_refresh_2x = 1; +} + +static inline void pei_data_usb2_port(struct pei_data *pei_data, int port, + uint16_t length, uint8_t enable, + uint8_t oc_pin, uint8_t location) +{ + pei_data->usb2_ports[port].length = length; + pei_data->usb2_ports[port].enable = enable; + pei_data->usb2_ports[port].oc_pin = oc_pin; + pei_data->usb2_ports[port].location = location; +} + +static inline void pei_data_usb3_port(struct pei_data *pei_data, int port, + uint8_t enable, uint8_t oc_pin, + uint8_t fixed_eq) +{ + pei_data->usb3_ports[port].enable = enable; + pei_data->usb3_ports[port].oc_pin = oc_pin; + pei_data->usb3_ports[port].fixed_eq = fixed_eq; +} + +void mainboard_fill_pei_data(struct pei_data *pei_data) +{ + /* DQ byte map for Samus board */ + const u8 dq_map[2][6][2] = { + { { 0x0F, 0xF0 }, { 0x00, 0xF0 }, { 0x0F, 0xF0 }, + { 0x0F, 0x00 }, { 0xFF, 0x00 }, { 0xFF, 0x00 } }, + { { 0x0F, 0xF0 }, { 0x00, 0xF0 }, { 0x0F, 0xF0 }, + { 0x0F, 0x00 }, { 0xFF, 0x00 }, { 0xFF, 0x00 } } }; + /* DQS CPU<>DRAM map for Samus board */ + const u8 dqs_map[2][8] = { + { 2, 0, 1, 3, 6, 4, 7, 5 }, + { 2, 1, 0, 3, 6, 5, 4, 7 } }; + + pei_data->ec_present = 1; + + /* One installed DIMM per channel */ + pei_data->dimm_channel0_disabled = 2; + pei_data->dimm_channel1_disabled = 2; + + memcpy(pei_data->dq_map, dq_map, sizeof(dq_map)); + memcpy(pei_data->dqs_map, dqs_map, sizeof(dqs_map)); + + /* P0: HOST PORT */ + pei_data_usb2_port(pei_data, 0, 0x0080, 1, 0, + USB_PORT_BACK_PANEL); + /* P1: HOST PORT */ + pei_data_usb2_port(pei_data, 1, 0x0080, 1, 1, + USB_PORT_BACK_PANEL); + /* P2: RAIDEN */ + pei_data_usb2_port(pei_data, 2, 0x0080, 1, USB_OC_PIN_SKIP, + USB_PORT_BACK_PANEL); + /* P3: SD CARD */ + pei_data_usb2_port(pei_data, 3, 0x0040, 1, USB_OC_PIN_SKIP, + USB_PORT_INTERNAL); + /* P4: RAIDEN */ + pei_data_usb2_port(pei_data, 4, 0x0080, 1, USB_OC_PIN_SKIP, + USB_PORT_BACK_PANEL); + /* P5: WWAN (Disabled) */ + pei_data_usb2_port(pei_data, 5, 0x0000, 0, USB_OC_PIN_SKIP, + USB_PORT_SKIP); + /* P6: CAMERA */ + pei_data_usb2_port(pei_data, 6, 0x0040, 1, USB_OC_PIN_SKIP, + USB_PORT_INTERNAL); + /* P7: BT */ + pei_data_usb2_port(pei_data, 7, 0x0040, 1, USB_OC_PIN_SKIP, + USB_PORT_INTERNAL); + + /* P1: HOST PORT */ + pei_data_usb3_port(pei_data, 0, 1, 0, 0); + /* P2: HOST PORT */ + pei_data_usb3_port(pei_data, 1, 1, 1, 0); + /* P3: RAIDEN */ + pei_data_usb3_port(pei_data, 2, 1, USB_OC_PIN_SKIP, 0); + /* P4: RAIDEN */ + pei_data_usb3_port(pei_data, 3, 1, USB_OC_PIN_SKIP, 0); +} + +static unsigned long get_top_of_ram(struct udevice *dev) +{ + /* + * Base of DPR is top of usable DRAM below 4GiB. The register has + * 1 MiB alignment and reports the TOP of the range, the base + * must be calculated from the size in MiB in bits 11:4. + */ + u32 dpr, tom; + + dm_pci_read_config32(dev, DPR, &dpr); + tom = dpr & ~((1 << 20) - 1); + + debug("dpt %08x tom %08x\n", dpr, tom); + /* Subtract DMA Protected Range size if enabled */ + if (dpr & DPR_EPM) + tom -= (dpr & DPR_SIZE_MASK) << 16; + + return (unsigned long)tom; +} + +/** + * sdram_find() - Find available memory + * + * This is a bit complicated since on x86 there are system memory holes all + * over the place. We create a list of available memory blocks + * + * @dev: Northbridge device + */ +static int sdram_find(struct udevice *dev) +{ + struct memory_info *info = &gd->arch.meminfo; + ulong top_of_ram; + + top_of_ram = get_top_of_ram(dev); + mrc_add_memory_area(info, 0, top_of_ram); + + /* Add MTRRs for memory */ + mtrr_add_request(MTRR_TYPE_WRBACK, 0, 2ULL << 30); + + return 0; +} + +static int prepare_mrc_cache(struct pei_data *pei_data) +{ + struct mrc_data_container *mrc_cache; + struct mrc_region entry; + int ret; + + ret = mrccache_get_region(NULL, &entry); + if (ret) + return ret; + mrc_cache = mrccache_find_current(&entry); + if (!mrc_cache) + return -ENOENT; + + pei_data->saved_data = mrc_cache->data; + pei_data->saved_data_size = mrc_cache->data_size; + debug("%s: at %p, size %x checksum %04x\n", __func__, + pei_data->saved_data, pei_data->saved_data_size, + mrc_cache->checksum); + + return 0; +} + +int reserve_arch(void) +{ + return mrccache_reserve(); +} + +int dram_init(void) +{ + struct pei_data _pei_data __aligned(8); + struct pei_data *pei_data = &_pei_data; + struct udevice *dev, *me_dev, *pch_dev; + struct chipset_power_state ps; + const void *spd_data; + int ret, size; + + memset(pei_data, '\0', sizeof(struct pei_data)); + + /* Print ME state before MRC */ + ret = syscon_get_by_driver_data(X86_SYSCON_ME, &me_dev); + if (ret) + return ret; + intel_me_status(me_dev); + + /* Save ME HSIO version */ + ret = uclass_first_device(UCLASS_PCH, &pch_dev); + if (ret) + return ret; + if (!pch_dev) + return -ENODEV; + power_state_get(pch_dev, &ps); + + intel_me_hsio_version(me_dev, &ps.hsio_version, &ps.hsio_checksum); + + broadwell_fill_pei_data(pei_data); + mainboard_fill_pei_data(pei_data); + + ret = uclass_first_device(UCLASS_NORTHBRIDGE, &dev); + if (ret) + return ret; + if (!dev) + return -ENODEV; + size = 256; + ret = mrc_locate_spd(dev, size, &spd_data); + if (ret) + return ret; + memcpy(pei_data->spd_data[0][0], spd_data, size); + memcpy(pei_data->spd_data[1][0], spd_data, size); + + ret = prepare_mrc_cache(pei_data); + if (ret) + debug("prepare_mrc_cache failed: %d\n", ret); + + debug("PEI version %#x\n", pei_data->pei_version); + ret = mrc_common_init(dev, pei_data, true); + if (ret) + return ret; + debug("Memory init done\n"); + + ret = sdram_find(dev); + if (ret) + return ret; + gd->ram_size = gd->arch.meminfo.total_32bit_memory; + debug("RAM size %llx\n", (unsigned long long)gd->ram_size); + + debug("MRC output data length %#x at %p\n", pei_data->data_to_save_size, + pei_data->data_to_save); + /* S3 resume: don't save scrambler seed or MRC data */ + if (pei_data->boot_mode != SLEEP_STATE_S3) { + /* + * This will be copied to SDRAM in reserve_arch(), then written + * to SPI flash in mrccache_save() + */ + gd->arch.mrc_output = (char *)pei_data->data_to_save; + gd->arch.mrc_output_len = pei_data->data_to_save_size; + } + gd->arch.pei_meminfo = pei_data->meminfo; + + return 0; +} + +/* Use this hook to save our SDRAM parameters */ +int misc_init_r(void) +{ + int ret; + + ret = mrccache_save(); + if (ret) + printf("Unable to save MRC data: %d\n", ret); + else + debug("Saved MRC cache data\n"); + + return 0; +} + +void board_debug_uart_init(void) +{ + struct udevice *bus = NULL; + + /* com1 / com2 decode range */ + pci_x86_write_config(bus, PCH_DEV_LPC, LPC_IO_DEC, 1 << 4, PCI_SIZE_16); + + pci_x86_write_config(bus, PCH_DEV_LPC, LPC_EN, COMA_LPC_EN, + PCI_SIZE_16); +} + +static const struct udevice_id broadwell_syscon_ids[] = { + { .compatible = "intel,me", .data = X86_SYSCON_ME }, + { .compatible = "intel,gma", .data = X86_SYSCON_GMA }, + { } +}; + +U_BOOT_DRIVER(syscon_intel_me) = { + .name = "intel_me_syscon", + .id = UCLASS_SYSCON, + .of_match = broadwell_syscon_ids, +}; diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c index 32f595d537..7115e7a151 100644 --- a/arch/x86/cpu/coreboot/sdram.c +++ b/arch/x86/cpu/coreboot/sdram.c @@ -9,7 +9,6 @@ #include <common.h> #include <asm/e820.h> #include <asm/arch/sysinfo.h> -#include <asm/arch/tables.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/x86/cpu/coreboot/tables.c b/arch/x86/cpu/coreboot/tables.c index 2b12b19ba2..543e51d96a 100644 --- a/arch/x86/cpu/coreboot/tables.c +++ b/arch/x86/cpu/coreboot/tables.c @@ -10,7 +10,6 @@ #include <common.h> #include <net.h> #include <asm/arch/sysinfo.h> -#include <asm/arch/tables.h> /* * This needs to be in the .data section so that it's copied over during diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 6c3a748f75..233a6c8695 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -27,6 +27,7 @@ #include <asm/control_regs.h> #include <asm/cpu.h> #include <asm/lapic.h> +#include <asm/microcode.h> #include <asm/mp.h> #include <asm/msr.h> #include <asm/mtrr.h> @@ -71,7 +72,7 @@ struct cpuinfo_x86 { * List of cpu vendor strings along with their normalized * id values. */ -static struct { +static const struct { int vendor; const char *name; } x86_vendors[] = { @@ -333,6 +334,16 @@ static inline void get_fms(struct cpuinfo_x86 *c, uint32_t tfms) c->x86_model += ((tfms >> 16) & 0xF) << 4; } +u32 cpu_get_family_model(void) +{ + return gd->arch.x86_device & 0x0fff0ff0; +} + +u32 cpu_get_stepping(void) +{ + return gd->arch.x86_mask; +} + int x86_cpu_init_f(void) { const u32 em_rst = ~X86_CR0_EM; @@ -459,14 +470,14 @@ void flush_cache(unsigned long dummy1, unsigned long dummy2) __weak void reset_cpu(ulong addr) { /* Do a hard reset through the chipset's reset control register */ - outb(SYS_RST | RST_CPU, PORT_RESET); + outb(SYS_RST | RST_CPU, IO_PORT_RESET); for (;;) cpu_hlt(); } void x86_full_reset(void) { - outb(FULL_RST | SYS_RST | RST_CPU, PORT_RESET); + outb(FULL_RST | SYS_RST | RST_CPU, IO_PORT_RESET); } int dcache_status(void) diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile new file mode 100644 index 0000000000..804c539ca4 --- /dev/null +++ b/arch/x86/cpu/intel_common/Makefile @@ -0,0 +1,16 @@ +# +# Copyright (c) 2016 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_HAVE_MRC) += car.o +obj-y += cpu.o +obj-y += lpc.o +obj-$(CONFIG_HAVE_MRC) += me_status.o +ifndef CONFIG_TARGET_EFI +obj-y += microcode.o +endif +obj-y += pch.o +obj-$(CONFIG_HAVE_MRC) += report_platform.o +obj-$(CONFIG_HAVE_MRC) += mrc.o diff --git a/arch/x86/cpu/ivybridge/car.S b/arch/x86/cpu/intel_common/car.S index 1defabf91f..6e0db96c01 100644 --- a/arch/x86/cpu/ivybridge/car.S +++ b/arch/x86/cpu/intel_common/car.S @@ -12,12 +12,12 @@ */ #include <common.h> +#include <asm/microcode.h> #include <asm/msr-index.h> #include <asm/mtrr.h> #include <asm/post.h> #include <asm/processor.h> #include <asm/processor-flags.h> -#include <asm/arch/microcode.h> #define MTRR_PHYS_BASE_MSR(reg) (0x200 + 2 * (reg)) #define MTRR_PHYS_MASK_MSR(reg) (0x200 + 2 * (reg) + 1) @@ -237,5 +237,7 @@ mtrr_table_end: .align 4 _dt_ucode_base_size: /* These next two fields are filled in by ifdtool */ +.globl ucode_base +ucode_base: /* Declared in microcode.h */ .long 0 /* microcode base */ .long 0 /* microcode size */ diff --git a/arch/x86/cpu/intel_common/cpu.c b/arch/x86/cpu/intel_common/cpu.c new file mode 100644 index 0000000000..93e4505e4d --- /dev/null +++ b/arch/x86/cpu/intel_common/cpu.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <asm/cpu_common.h> +#include <asm/intel_regs.h> +#include <asm/lapic.h> +#include <asm/lpc_common.h> +#include <asm/msr.h> +#include <asm/mtrr.h> +#include <asm/post.h> +#include <asm/microcode.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int report_bist_failure(void) +{ + if (gd->arch.bist != 0) { + post_code(POST_BIST_FAILURE); + printf("BIST failed: %08x\n", gd->arch.bist); + return -EFAULT; + } + + return 0; +} + +int cpu_common_init(void) +{ + struct udevice *dev, *lpc; + int ret; + + /* Halt if there was a built in self test failure */ + ret = report_bist_failure(); + if (ret) + return ret; + + enable_lapic(); + + ret = microcode_update_intel(); + if (ret && ret != -EEXIST) + return ret; + + /* Enable upper 128bytes of CMOS */ + writel(1 << 2, RCB_REG(RC)); + + /* Early chipset init required before RAM init can work */ + uclass_first_device(UCLASS_NORTHBRIDGE, &dev); + + ret = uclass_first_device(UCLASS_LPC, &lpc); + if (ret) + return ret; + if (!lpc) + return -ENODEV; + + /* Cause the SATA device to do its early init */ + uclass_first_device(UCLASS_DISK, &dev); + + return 0; +} + +int cpu_set_flex_ratio_to_tdp_nominal(void) +{ + msr_t flex_ratio, msr; + u8 nominal_ratio; + + /* Check for Flex Ratio support */ + flex_ratio = msr_read(MSR_FLEX_RATIO); + if (!(flex_ratio.lo & FLEX_RATIO_EN)) + return -EINVAL; + + /* Check for >0 configurable TDPs */ + msr = msr_read(MSR_PLATFORM_INFO); + if (((msr.hi >> 1) & 3) == 0) + return -EINVAL; + + /* Use nominal TDP ratio for flex ratio */ + msr = msr_read(MSR_CONFIG_TDP_NOMINAL); + nominal_ratio = msr.lo & 0xff; + + /* See if flex ratio is already set to nominal TDP ratio */ + if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio) + return 0; + + /* Set flex ratio to nominal TDP ratio */ + flex_ratio.lo &= ~0xff00; + flex_ratio.lo |= nominal_ratio << 8; + flex_ratio.lo |= FLEX_RATIO_LOCK; + msr_write(MSR_FLEX_RATIO, flex_ratio); + + /* Set flex ratio in soft reset data register bits 11:6 */ + clrsetbits_le32(RCB_REG(SOFT_RESET_DATA), 0x3f << 6, + (nominal_ratio & 0x3f) << 6); + + debug("CPU: Soft reset to set up flex ratio\n"); + + /* Set soft reset control to use register value */ + setbits_le32(RCB_REG(SOFT_RESET_CTRL), 1); + + /* Issue warm reset, will be "CPU only" due to soft reset data */ + outb(0x0, IO_PORT_RESET); + outb(SYS_RST | RST_CPU, IO_PORT_RESET); + cpu_hlt(); + + /* Not reached */ + return -EINVAL; +} diff --git a/arch/x86/cpu/intel_common/lpc.c b/arch/x86/cpu/intel_common/lpc.c new file mode 100644 index 0000000000..03cb45b636 --- /dev/null +++ b/arch/x86/cpu/intel_common/lpc.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <pch.h> +#include <pci.h> +#include <asm/intel_regs.h> +#include <asm/io.h> +#include <asm/lpc_common.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Enable Prefetching and Caching */ +static void enable_spi_prefetch(struct udevice *pch) +{ + u8 reg8; + + dm_pci_read_config8(pch, 0xdc, ®8); + reg8 &= ~(3 << 2); + reg8 |= (2 << 2); /* Prefetching and Caching Enabled */ + dm_pci_write_config8(pch, 0xdc, reg8); +} + +static void enable_port80_on_lpc(struct udevice *pch) +{ + /* Enable port 80 POST on LPC */ + dm_pci_write_config32(pch, PCH_RCBA_BASE, RCB_BASE_ADDRESS | 1); + clrbits_le32(RCB_REG(GCS), 4); +} + +/** + * lpc_early_init() - set up LPC serial ports and other early things + * + * @dev: LPC device + * @return 0 if OK, -ve on error + */ +int lpc_common_early_init(struct udevice *dev) +{ + struct udevice *pch = dev->parent; + struct reg_info { + u32 base; + u32 size; + } values[4], *ptr; + int count; + int i; + + count = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset, + "intel,gen-dec", (u32 *)values, + sizeof(values) / sizeof(u32)); + if (count < 0) + return -EINVAL; + + /* Set COM1/COM2 decode range */ + dm_pci_write_config16(pch, LPC_IO_DEC, 0x0010); + + /* Enable PS/2 Keyboard/Mouse, EC areas and COM1 */ + dm_pci_write_config16(pch, LPC_EN, KBC_LPC_EN | MC_LPC_EN | + GAMEL_LPC_EN | COMA_LPC_EN); + + /* Write all registers but use 0 if we run out of data */ + count = count * sizeof(u32) / sizeof(values[0]); + for (i = 0, ptr = values; i < ARRAY_SIZE(values); i++, ptr++) { + u32 reg = 0; + + if (i < count) + reg = ptr->base | PCI_COMMAND_IO | (ptr->size << 16); + dm_pci_write_config32(pch, LPC_GENX_DEC(i), reg); + } + + enable_spi_prefetch(pch); + + /* This is already done in start.S, but let's do it in C */ + enable_port80_on_lpc(pch); + + return 0; +} + +int lpc_set_spi_protect(struct udevice *dev, int bios_ctrl, bool protect) +{ + uint8_t bios_cntl; + + /* Adjust the BIOS write protect and SMM BIOS Write Protect Disable */ + dm_pci_read_config8(dev, bios_ctrl, &bios_cntl); + if (protect) { + bios_cntl &= ~BIOS_CTRL_BIOSWE; + bios_cntl |= BIT(5); + } else { + bios_cntl |= BIOS_CTRL_BIOSWE; + bios_cntl &= ~BIT(5); + } + dm_pci_write_config8(dev, bios_ctrl, bios_cntl); + + return 0; +} diff --git a/arch/x86/cpu/ivybridge/me_status.c b/arch/x86/cpu/intel_common/me_status.c index 15cf69f40e..130d219bc9 100644 --- a/arch/x86/cpu/ivybridge/me_status.c +++ b/arch/x86/cpu/intel_common/me_status.c @@ -128,7 +128,14 @@ static const char *const me_progress_policy_values[] = { [0x10] = "Required VSCC values for flash parts do not match", }; -void intel_me_status(struct me_hfs *hfs, struct me_gmes *gmes) + +/** + * _intel_me_status() - Check Intel Management Engine status + * + * struct hfs: Firmware status + * struct gmes: Management engine status + */ +static void _intel_me_status(struct me_hfs *hfs, struct me_gmes *gmes) { /* Check Current States */ debug("ME: FW Partition Table : %s\n", @@ -193,3 +200,14 @@ void intel_me_status(struct me_hfs *hfs, struct me_gmes *gmes) } debug("\n"); } + +void intel_me_status(struct udevice *me_dev) +{ + struct me_hfs hfs; + struct me_gmes gmes; + + pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS); + pci_read_dword_ptr(me_dev, &gmes, PCI_ME_GMES); + + _intel_me_status(&hfs, &gmes); +} diff --git a/arch/x86/cpu/ivybridge/microcode_intel.c b/arch/x86/cpu/intel_common/microcode.c index 2440a97c48..daf0d69494 100644 --- a/arch/x86/cpu/ivybridge/microcode_intel.c +++ b/arch/x86/cpu/intel_common/microcode.c @@ -12,10 +12,12 @@ #include <fdtdec.h> #include <libfdt.h> #include <asm/cpu.h> +#include <asm/microcode.h> #include <asm/msr.h> #include <asm/msr-index.h> #include <asm/processor.h> -#include <asm/arch/microcode.h> + +DECLARE_GLOBAL_DATA_PTR; /** * struct microcode_update - standard microcode header from Intel @@ -62,8 +64,12 @@ static int microcode_decode_node(const void *blob, int node, return 0; } -static inline uint32_t microcode_read_rev(void) +int microcode_read_rev(void) { + /* Quark does not have microcode MSRs */ +#ifdef CONFIG_INTEL_QUARK + return 0; +#else /* * Some Intel CPUs can be very finicky about the CPUID sequence used. * So this is implemented in assembly so that it works reliably. @@ -88,6 +94,7 @@ static inline uint32_t microcode_read_rev(void) ); return high; +#endif } static void microcode_read_cpu(struct microcode_update *cpu) diff --git a/arch/x86/cpu/intel_common/mrc.c b/arch/x86/cpu/intel_common/mrc.c new file mode 100644 index 0000000000..01b6e866b5 --- /dev/null +++ b/arch/x86/cpu/intel_common/mrc.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <syscon.h> +#include <asm/cpu.h> +#include <asm/gpio.h> +#include <asm/intel_regs.h> +#include <asm/mrc_common.h> +#include <asm/pch_common.h> +#include <asm/post.h> +#include <asm/arch/me.h> +#include <asm/report_platform.h> + +static const char *const ecc_decoder[] = { + "inactive", + "active on IO", + "disabled on IO", + "active" +}; + +ulong mrc_common_board_get_usable_ram_top(ulong total_size) +{ + struct memory_info *info = &gd->arch.meminfo; + uintptr_t dest_addr = 0; + struct memory_area *largest = NULL; + int i; + + /* Find largest area of memory below 4GB */ + + for (i = 0; i < info->num_areas; i++) { + struct memory_area *area = &info->area[i]; + + if (area->start >= 1ULL << 32) + continue; + if (!largest || area->size > largest->size) + largest = area; + } + + /* If no suitable area was found, return an error. */ + assert(largest); + if (!largest || largest->size < (2 << 20)) + panic("No available memory found for relocation"); + + dest_addr = largest->start + largest->size; + + return (ulong)dest_addr; +} + +void mrc_common_dram_init_banksize(void) +{ + struct memory_info *info = &gd->arch.meminfo; + int num_banks; + int i; + + for (i = 0, num_banks = 0; i < info->num_areas; i++) { + struct memory_area *area = &info->area[i]; + + if (area->start >= 1ULL << 32) + continue; + gd->bd->bi_dram[num_banks].start = area->start; + gd->bd->bi_dram[num_banks].size = area->size; + num_banks++; + } +} + +int mrc_add_memory_area(struct memory_info *info, uint64_t start, + uint64_t end) +{ + struct memory_area *ptr; + + if (info->num_areas == CONFIG_NR_DRAM_BANKS) + return -ENOSPC; + + ptr = &info->area[info->num_areas]; + ptr->start = start; + ptr->size = end - start; + info->total_memory += ptr->size; + if (ptr->start < (1ULL << 32)) + info->total_32bit_memory += ptr->size; + debug("%d: memory %llx size %llx, total now %llx / %llx\n", + info->num_areas, ptr->start, ptr->size, + info->total_32bit_memory, info->total_memory); + info->num_areas++; + + return 0; +} + +/* + * Dump in the log memory controller configuration as read from the memory + * controller registers. + */ +void report_memory_config(void) +{ + u32 addr_decoder_common, addr_decode_ch[2]; + int i; + + addr_decoder_common = readl(MCHBAR_REG(0x5000)); + addr_decode_ch[0] = readl(MCHBAR_REG(0x5004)); + addr_decode_ch[1] = readl(MCHBAR_REG(0x5008)); + + debug("memcfg DDR3 clock %d MHz\n", + (readl(MCHBAR_REG(0x5e04)) * 13333 * 2 + 50) / 100); + debug("memcfg channel assignment: A: %d, B % d, C % d\n", + addr_decoder_common & 3, + (addr_decoder_common >> 2) & 3, + (addr_decoder_common >> 4) & 3); + + for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) { + u32 ch_conf = addr_decode_ch[i]; + debug("memcfg channel[%d] config (%8.8x):\n", i, ch_conf); + debug(" ECC %s\n", ecc_decoder[(ch_conf >> 24) & 3]); + debug(" enhanced interleave mode %s\n", + ((ch_conf >> 22) & 1) ? "on" : "off"); + debug(" rank interleave %s\n", + ((ch_conf >> 21) & 1) ? "on" : "off"); + debug(" DIMMA %d MB width x%d %s rank%s\n", + ((ch_conf >> 0) & 0xff) * 256, + ((ch_conf >> 19) & 1) ? 16 : 8, + ((ch_conf >> 17) & 1) ? "dual" : "single", + ((ch_conf >> 16) & 1) ? "" : ", selected"); + debug(" DIMMB %d MB width x%d %s rank%s\n", + ((ch_conf >> 8) & 0xff) * 256, + ((ch_conf >> 20) & 1) ? 16 : 8, + ((ch_conf >> 18) & 1) ? "dual" : "single", + ((ch_conf >> 16) & 1) ? ", selected" : ""); + } +} + +int mrc_locate_spd(struct udevice *dev, int size, const void **spd_datap) +{ + const void *blob = gd->fdt_blob; + int spd_index; + struct gpio_desc desc[4]; + int spd_node; + int node; + int ret; + + ret = gpio_request_list_by_name(dev, "board-id-gpios", desc, + ARRAY_SIZE(desc), GPIOD_IS_IN); + if (ret < 0) { + debug("%s: gpio ret=%d\n", __func__, ret); + return ret; + } + spd_index = dm_gpio_get_values_as_int(desc, ret); + debug("spd index %d\n", spd_index); + + node = fdt_first_subnode(blob, dev->of_offset); + if (node < 0) + return -EINVAL; + for (spd_node = fdt_first_subnode(blob, node); + spd_node > 0; + spd_node = fdt_next_subnode(blob, spd_node)) { + int len; + + if (fdtdec_get_int(blob, spd_node, "reg", -1) != spd_index) + continue; + *spd_datap = fdt_getprop(blob, spd_node, "data", &len); + if (len < size) { + printf("Missing SPD data\n"); + return -EINVAL; + } + + debug("Using SDRAM SPD data for '%s'\n", + fdt_get_name(blob, spd_node, NULL)); + return 0; + } + + printf("No SPD data found for index %d\n", spd_index); + return -ENOENT; +} + +asmlinkage void sdram_console_tx_byte(unsigned char byte) +{ +#ifdef DEBUG + putc(byte); +#endif +} + +/** + * Find the PEI executable in the ROM and execute it. + * + * @me_dev: Management Engine device + * @pei_data: configuration data for UEFI PEI reference code + */ +static int sdram_initialise(struct udevice *dev, struct udevice *me_dev, + void *pei_data, bool use_asm_linkage) +{ + unsigned version; + const char *data; + + report_platform_info(dev); + debug("Starting UEFI PEI System Agent\n"); + + debug("PEI data at %p:\n", pei_data); + + data = (char *)CONFIG_X86_MRC_ADDR; + if (data) { + int rv; + ulong start; + + debug("Calling MRC at %p\n", data); + post_code(POST_PRE_MRC); + start = get_timer(0); + if (use_asm_linkage) { + asmlinkage int (*func)(void *); + + func = (asmlinkage int (*)(void *))data; + rv = func(pei_data); + } else { + int (*func)(void *); + + func = (int (*)(void *))data; + rv = func(pei_data); + } + post_code(POST_MRC); + if (rv) { + switch (rv) { + case -1: + printf("PEI version mismatch.\n"); + break; + case -2: + printf("Invalid memory frequency.\n"); + break; + default: + printf("MRC returned %x.\n", rv); + } + printf("Nonzero MRC return value.\n"); + return -EFAULT; + } + debug("MRC execution time %lu ms\n", get_timer(start)); + } else { + printf("UEFI PEI System Agent not found.\n"); + return -ENOSYS; + } + + version = readl(MCHBAR_REG(MCHBAR_PEI_VERSION)); + debug("System Agent Version %d.%d.%d Build %d\n", + version >> 24 , (version >> 16) & 0xff, + (version >> 8) & 0xff, version & 0xff); + +#if CONFIG_USBDEBUG + /* mrc.bin reconfigures USB, so reinit it to have debug */ + early_usbdebug_init(); +#endif + + return 0; +} + +int mrc_common_init(struct udevice *dev, void *pei_data, bool use_asm_linkage) +{ + struct udevice *me_dev; + int ret; + + ret = syscon_get_by_driver_data(X86_SYSCON_ME, &me_dev); + if (ret) + return ret; + + ret = sdram_initialise(dev, me_dev, pei_data, use_asm_linkage); + if (ret) + return ret; + quick_ram_check(); + post_code(POST_DRAM); + report_memory_config(); + + return 0; +} diff --git a/arch/x86/cpu/intel_common/pch.c b/arch/x86/cpu/intel_common/pch.c new file mode 100644 index 0000000000..1f05b44586 --- /dev/null +++ b/arch/x86/cpu/intel_common/pch.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <dm.h> +#include <asm/pch_common.h> + +u32 pch_common_sir_read(struct udevice *dev, int idx) +{ + u32 data; + + dm_pci_write_config32(dev, SATA_SIRI, idx); + dm_pci_read_config32(dev, SATA_SIRD, &data); + + return data; +} + +void pch_common_sir_write(struct udevice *dev, int idx, u32 value) +{ + dm_pci_write_config32(dev, SATA_SIRI, idx); + dm_pci_write_config32(dev, SATA_SIRD, value); +} diff --git a/arch/x86/cpu/ivybridge/report_platform.c b/arch/x86/cpu/intel_common/report_platform.c index c78322aef9..05e1cf9cdb 100644 --- a/arch/x86/cpu/ivybridge/report_platform.c +++ b/arch/x86/cpu/intel_common/report_platform.c @@ -9,8 +9,8 @@ #include <common.h> #include <asm/cpu.h> #include <asm/pci.h> +#include <asm/report_platform.h> #include <asm/arch/pch.h> -#include <asm/arch/sandybridge.h> static void report_cpu_info(void) { diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index c40200bf85..10dc4d47f0 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -249,7 +249,7 @@ int interrupt_init(void) int ret; /* Try to set up the interrupt router, but don't require one */ - ret = uclass_first_device(UCLASS_IRQ, &dev); + ret = uclass_first_device_err(UCLASS_IRQ, &dev); if (ret && ret != -ENODEV) return ret; diff --git a/arch/x86/cpu/ioapic.c b/arch/x86/cpu/ioapic.c index 112a9c63b4..d15e86c1c5 100644 --- a/arch/x86/cpu/ioapic.c +++ b/arch/x86/cpu/ioapic.c @@ -7,6 +7,7 @@ #include <common.h> #include <asm/io.h> #include <asm/ioapic.h> +#include <asm/lapic.h> u32 io_apic_read(u32 reg) { @@ -19,3 +20,18 @@ void io_apic_write(u32 reg, u32 val) writel(reg, IO_APIC_INDEX); writel(val, IO_APIC_DATA); } + +void io_apic_set_id(int ioapic_id) +{ + int bsp_lapicid = lapicid(); + + debug("IOAPIC: Initialising IOAPIC at %08x\n", IO_APIC_ADDR); + debug("IOAPIC: Bootstrap Processor Local APIC = %#02x\n", bsp_lapicid); + + if (ioapic_id) { + debug("IOAPIC: ID = 0x%02x\n", ioapic_id); + /* Set IOAPIC ID if it has been specified */ + io_apic_write(0x00, (io_apic_read(0x00) & 0xf0ffffff) | + (ioapic_id << 24)); + } +} diff --git a/arch/x86/cpu/ivybridge/Kconfig b/arch/x86/cpu/ivybridge/Kconfig index 0819347b59..e23d01a08f 100644 --- a/arch/x86/cpu/ivybridge/Kconfig +++ b/arch/x86/cpu/ivybridge/Kconfig @@ -7,43 +7,18 @@ config NORTHBRIDGE_INTEL_IVYBRIDGE bool - select CACHE_MRC_BIN + select CACHE_MRC_BIN if HAVE_MRC if NORTHBRIDGE_INTEL_IVYBRIDGE -config CACHE_MRC_BIN - bool - default n - -config CACHE_MRC_SIZE_KB - int - default 512 - config DCACHE_RAM_BASE - hex default 0xff7e0000 config DCACHE_RAM_SIZE - hex default 0x20000 -config HAVE_MRC - bool "Add a System Agent binary" - help - Select this option to add a System Agent binary to - the resulting U-Boot image. MRC stands for Memory Reference Code. - It is a binary blob which U-Boot uses to set up SDRAM. - - Note: Without this binary U-Boot will not be able to set up its - SDRAM so will not boot. - config DCACHE_RAM_MRC_VAR_SIZE - hex default 0x4000 - help - This is the amount of CAR (Cache as RAM) reserved for use by the - memory reference code. This should be set to 16KB (0x4000 hex) - so that MRC has enough space to run. config CPU_SPECIFIC_OPTIONS def_bool y diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile index 9203219f31..9cdb07bdf2 100644 --- a/arch/x86/cpu/ivybridge/Makefile +++ b/arch/x86/cpu/ivybridge/Makefile @@ -7,16 +7,12 @@ ifdef CONFIG_HAVE_FSP obj-y += fsp_configs.o ivybridge.o else -obj-y += car.o obj-y += cpu.o obj-y += early_me.o obj-y += gma.o obj-y += lpc.o -obj-y += me_status.o obj-y += model_206ax.o -obj-y += microcode_intel.o obj-y += northbridge.o -obj-y += report_platform.o obj-y += sata.o obj-y += sdram.o endif diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c index 9972b0ae7f..4c039ac9c6 100644 --- a/arch/x86/cpu/ivybridge/bd82x6x.c +++ b/arch/x86/cpu/ivybridge/bd82x6x.c @@ -11,8 +11,10 @@ #include <pch.h> #include <syscon.h> #include <asm/cpu.h> +#include <asm/intel_regs.h> #include <asm/io.h> #include <asm/lapic.h> +#include <asm/lpc_common.h> #include <asm/pci.h> #include <asm/arch/bd82x6x.h> #include <asm/arch/model_206ax.h> @@ -187,20 +189,7 @@ static int bd82x6x_pch_get_spi_base(struct udevice *dev, ulong *sbasep) static int bd82x6x_set_spi_protect(struct udevice *dev, bool protect) { - uint8_t bios_cntl; - - /* Adjust the BIOS write protect and SMM BIOS Write Protect Disable */ - dm_pci_read_config8(dev, BIOS_CTRL, &bios_cntl); - if (protect) { - bios_cntl &= ~BIOS_CTRL_BIOSWE; - bios_cntl |= BIT(5); - } else { - bios_cntl |= BIOS_CTRL_BIOSWE; - bios_cntl &= ~BIT(5); - } - dm_pci_write_config8(dev, BIOS_CTRL, bios_cntl); - - return 0; + return lpc_set_spi_protect(dev, BIOS_CTRL, protect); } static int bd82x6x_get_gpio_base(struct udevice *dev, u32 *gbasep) diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c index 948833c028..0f9390517f 100644 --- a/arch/x86/cpu/ivybridge/cpu.c +++ b/arch/x86/cpu/ivybridge/cpu.c @@ -17,15 +17,18 @@ #include <fdtdec.h> #include <pch.h> #include <asm/cpu.h> +#include <asm/cpu_common.h> +#include <asm/intel_regs.h> #include <asm/io.h> #include <asm/lapic.h> +#include <asm/lpc_common.h> +#include <asm/microcode.h> #include <asm/msr.h> #include <asm/mtrr.h> #include <asm/pci.h> #include <asm/post.h> #include <asm/processor.h> #include <asm/arch/model_206ax.h> -#include <asm/arch/microcode.h> #include <asm/arch/pch.h> #include <asm/arch/sandybridge.h> @@ -33,51 +36,11 @@ DECLARE_GLOBAL_DATA_PTR; static int set_flex_ratio_to_tdp_nominal(void) { - msr_t flex_ratio, msr; - u8 nominal_ratio; - /* Minimum CPU revision for configurable TDP support */ if (cpuid_eax(1) < IVB_CONFIG_TDP_MIN_CPUID) return -EINVAL; - /* Check for Flex Ratio support */ - flex_ratio = msr_read(MSR_FLEX_RATIO); - if (!(flex_ratio.lo & FLEX_RATIO_EN)) - return -EINVAL; - - /* Check for >0 configurable TDPs */ - msr = msr_read(MSR_PLATFORM_INFO); - if (((msr.hi >> 1) & 3) == 0) - return -EINVAL; - - /* Use nominal TDP ratio for flex ratio */ - msr = msr_read(MSR_CONFIG_TDP_NOMINAL); - nominal_ratio = msr.lo & 0xff; - - /* See if flex ratio is already set to nominal TDP ratio */ - if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio) - return 0; - - /* Set flex ratio to nominal TDP ratio */ - flex_ratio.lo &= ~0xff00; - flex_ratio.lo |= nominal_ratio << 8; - flex_ratio.lo |= FLEX_RATIO_LOCK; - msr_write(MSR_FLEX_RATIO, flex_ratio); - - /* Set flex ratio in soft reset data register bits 11:6 */ - clrsetbits_le32(RCB_REG(SOFT_RESET_DATA), 0x3f << 6, - (nominal_ratio & 0x3f) << 6); - - /* Set soft reset control to use register value */ - setbits_le32(RCB_REG(SOFT_RESET_CTRL), 1); - - /* Issue warm reset, will be "CPU only" due to soft reset data */ - outb(0x0, PORT_RESET); - outb(SYS_RST | RST_CPU, PORT_RESET); - cpu_hlt(); - - /* Not reached */ - return -EINVAL; + return cpu_set_flex_ratio_to_tdp_nominal(); } int arch_cpu_init(void) @@ -104,9 +67,9 @@ int arch_cpu_init_dm(void) /* TODO(sjg@chromium.org): Get rid of gd->hose */ gd->hose = hose; - ret = uclass_first_device(UCLASS_LPC, &dev); - if (!dev) - return -ENODEV; + ret = uclass_first_device_err(UCLASS_LPC, &dev); + if (ret) + return ret; /* * We should do as little as possible before the serial console is @@ -162,17 +125,6 @@ static void enable_usb_bar(struct udevice *bus) pci_bus_write_config(bus, usb3, PCI_COMMAND, cmd, PCI_SIZE_32); } -static int report_bist_failure(void) -{ - if (gd->arch.bist != 0) { - post_code(POST_BIST_FAILURE); - printf("BIST failed: %08x\n", gd->arch.bist); - return -EFAULT; - } - - return 0; -} - int print_cpuinfo(void) { enum pei_boot_mode_t boot_mode = PEI_BOOT_NONE; @@ -183,20 +135,6 @@ int print_cpuinfo(void) uint16_t pm1_sts; int ret; - /* Halt if there was a built in self test failure */ - ret = report_bist_failure(); - if (ret) - return ret; - - enable_lapic(); - - ret = microcode_update_intel(); - if (ret) - return ret; - - /* Enable upper 128bytes of CMOS */ - writel(1 << 2, RCB_REG(RC)); - /* TODO: cmos_post_init() */ if (readl(MCHBAR_REG(SSKPD)) == 0xCAFE) { debug("soft reset detected\n"); @@ -207,17 +145,9 @@ int print_cpuinfo(void) reset_cpu(0); } - /* Early chipset init required before RAM init can work */ - uclass_first_device(UCLASS_NORTHBRIDGE, &dev); - - ret = uclass_first_device(UCLASS_LPC, &lpc); + ret = cpu_common_init(); if (ret) return ret; - if (!dev) - return -ENODEV; - - /* Cause the SATA device to do its early init */ - uclass_first_device(UCLASS_DISK, &dev); /* Check PM1_STS[15] to see if we are waking from Sx */ pm1_sts = inw(DEFAULT_PMBASE + PM1_STS); @@ -236,15 +166,15 @@ int print_cpuinfo(void) post_code(POST_EARLY_INIT); /* Enable SPD ROMs and DDR-III DRAM */ - ret = uclass_first_device(UCLASS_I2C, &dev); + ret = uclass_first_device_err(UCLASS_I2C, &dev); if (ret) return ret; - if (!dev) - return -ENODEV; /* Prepare USB controller early in S3 resume */ - if (boot_mode == PEI_BOOT_RESUME) + if (boot_mode == PEI_BOOT_RESUME) { + uclass_first_device(UCLASS_LPC, &lpc); enable_usb_bar(pci_get_controller(lpc->parent)); + } gd->arch.pei_boot_mode = boot_mode; diff --git a/arch/x86/cpu/ivybridge/early_me.c b/arch/x86/cpu/ivybridge/early_me.c index b1df77d571..cda96ab398 100644 --- a/arch/x86/cpu/ivybridge/early_me.c +++ b/arch/x86/cpu/ivybridge/early_me.c @@ -27,35 +27,6 @@ static const char *const me_ack_values[] = { [ME_HFS_ACK_CONTINUE] = "Continue to boot" }; -static inline void pci_read_dword_ptr(struct udevice *me_dev, void *ptr, - int offset) -{ - u32 dword; - - dm_pci_read_config32(me_dev, offset, &dword); - memcpy(ptr, &dword, sizeof(dword)); -} - -static inline void pci_write_dword_ptr(struct udevice *me_dev, void *ptr, - int offset) -{ - u32 dword = 0; - - memcpy(&dword, ptr, sizeof(dword)); - dm_pci_write_config32(me_dev, offset, dword); -} - -void intel_early_me_status(struct udevice *me_dev) -{ - struct me_hfs hfs; - struct me_gmes gmes; - - pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS); - pci_read_dword_ptr(me_dev, &gmes, PCI_ME_GMES); - - intel_me_status(&hfs, &gmes); -} - int intel_early_me_init(struct udevice *me_dev) { int count; @@ -159,7 +130,7 @@ int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev, debug("ME: Requested BIOS Action: %s\n", me_ack_values[hfs.ack_data]); /* Check status after acknowledgement */ - intel_early_me_status(me_dev); + intel_me_status(me_dev); switch (hfs.ack_data) { case ME_HFS_ACK_CONTINUE: diff --git a/arch/x86/cpu/ivybridge/gma.c b/arch/x86/cpu/ivybridge/gma.c index 3b6291e905..37e2e6ead8 100644 --- a/arch/x86/cpu/ivybridge/gma.c +++ b/arch/x86/cpu/ivybridge/gma.c @@ -12,6 +12,7 @@ #include <errno.h> #include <fdtdec.h> #include <pci_rom.h> +#include <asm/intel_regs.h> #include <asm/io.h> #include <asm/mtrr.h> #include <asm/pci.h> @@ -812,9 +813,9 @@ int gma_func0_init(struct udevice *dev) writew(0x0010, RCB_REG(DISPBDF)); setbits_le32(RCB_REG(FD2), PCH_ENABLE_DBDF); - ret = uclass_first_device(UCLASS_NORTHBRIDGE, &nbridge); - if (!nbridge) - return -ENODEV; + ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &nbridge); + if (ret) + return ret; rev = bridge_silicon_revision(nbridge); sandybridge_setup_graphics(nbridge, dev); diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c index 9ab5ed3ff9..88ab7973fd 100644 --- a/arch/x86/cpu/ivybridge/lpc.c +++ b/arch/x86/cpu/ivybridge/lpc.c @@ -13,9 +13,11 @@ #include <rtc.h> #include <pci.h> #include <asm/acpi.h> +#include <asm/intel_regs.h> #include <asm/interrupt.h> #include <asm/io.h> #include <asm/ioapic.h> +#include <asm/lpc_common.h> #include <asm/pci.h> #include <asm/arch/pch.h> @@ -404,26 +406,6 @@ static void pch_fixups(struct udevice *pch) setbits_le32(RCB_REG(0x21a8), 0x3); } -/* - * Enable Prefetching and Caching. - */ -static void enable_spi_prefetch(struct udevice *pch) -{ - u8 reg8; - - dm_pci_read_config8(pch, 0xdc, ®8); - reg8 &= ~(3 << 2); - reg8 |= (2 << 2); /* Prefetching and Caching Enabled */ - dm_pci_write_config8(pch, 0xdc, reg8); -} - -static void enable_port80_on_lpc(struct udevice *pch) -{ - /* Enable port 80 POST on LPC */ - dm_pci_write_config32(pch, PCH_RCBA_BASE, DEFAULT_RCBA | 1); - clrbits_le32(RCB_REG(GCS), 4); -} - static void set_spi_speed(void) { u32 fdod; @@ -440,54 +422,6 @@ static void set_spi_speed(void) clrsetbits_8(RCB_REG(SPI_FREQ_SWSEQ), 7, fdod); } -/** - * lpc_early_init() - set up LPC serial ports and other early things - * - * @dev: LPC device - * @return 0 if OK, -ve on error - */ -static int lpc_early_init(struct udevice *dev) -{ - struct reg_info { - u32 base; - u32 size; - } values[4], *ptr; - int count; - int i; - - count = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset, - "intel,gen-dec", (u32 *)values, - sizeof(values) / sizeof(u32)); - if (count < 0) - return -EINVAL; - - /* Set COM1/COM2 decode range */ - dm_pci_write_config16(dev->parent, LPC_IO_DEC, 0x0010); - - /* Enable PS/2 Keyboard/Mouse, EC areas and COM1 */ - dm_pci_write_config16(dev->parent, LPC_EN, KBC_LPC_EN | MC_LPC_EN | - GAMEL_LPC_EN | COMA_LPC_EN); - - /* Write all registers but use 0 if we run out of data */ - count = count * sizeof(u32) / sizeof(values[0]); - for (i = 0, ptr = values; i < ARRAY_SIZE(values); i++, ptr++) { - u32 reg = 0; - - if (i < count) - reg = ptr->base | PCI_COMMAND_IO | (ptr->size << 16); - dm_pci_write_config32(dev->parent, LPC_GENX_DEC(i), reg); - } - - enable_spi_prefetch(dev->parent); - - /* This is already done in start.S, but let's do it in C */ - enable_port80_on_lpc(dev->parent); - - set_spi_speed(); - - return 0; -} - static int lpc_init_extra(struct udevice *dev) { struct udevice *pch = dev->parent; @@ -550,9 +484,12 @@ static int lpc_init_extra(struct udevice *dev) static int bd82x6x_lpc_early_init(struct udevice *dev) { + set_spi_speed(); + /* Setting up Southbridge. In the northbridge code. */ debug("Setting up static southbridge registers\n"); - dm_pci_write_config32(dev->parent, PCH_RCBA_BASE, DEFAULT_RCBA | 1); + dm_pci_write_config32(dev->parent, PCH_RCBA_BASE, + RCB_BASE_ADDRESS | 1); dm_pci_write_config32(dev->parent, PMBASE, DEFAULT_PMBASE | 1); /* Enable ACPI BAR */ @@ -573,7 +510,7 @@ static int bd82x6x_lpc_probe(struct udevice *dev) int ret; if (!(gd->flags & GD_FLG_RELOC)) { - ret = lpc_early_init(dev); + ret = lpc_common_early_init(dev); if (ret) { debug("%s: lpc_early_init() failed\n", __func__); return ret; diff --git a/arch/x86/cpu/ivybridge/model_206ax.c b/arch/x86/cpu/ivybridge/model_206ax.c index 9654600cf1..cef425669c 100644 --- a/arch/x86/cpu/ivybridge/model_206ax.c +++ b/arch/x86/cpu/ivybridge/model_206ax.c @@ -17,6 +17,7 @@ #include <asm/cpu_x86.h> #include <asm/lapic.h> #include <asm/msr.h> +#include <asm/msr-index.h> #include <asm/mtrr.h> #include <asm/processor.h> #include <asm/speedstep.h> @@ -363,7 +364,7 @@ static void set_max_ratio(void) msr = msr_read(MSR_PLATFORM_INFO); perf_ctl.lo = msr.lo & 0xff00; } - msr_write(IA32_PERF_CTL, perf_ctl); + msr_write(MSR_IA32_PERF_CTL, perf_ctl); debug("model_x06ax: frequency set to %d\n", ((perf_ctl.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK); @@ -455,9 +456,10 @@ static int model_206ax_get_info(struct udevice *dev, struct cpu_info *info) { msr_t msr; - msr = msr_read(IA32_PERF_CTL); + msr = msr_read(MSR_IA32_PERF_CTL); info->cpu_freq = ((msr.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK * 1000000; - info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU; + info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU | + 1 << CPU_FEAT_UCODE; return 0; } diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c index a066607a18..f7e0bc3f18 100644 --- a/arch/x86/cpu/ivybridge/northbridge.c +++ b/arch/x86/cpu/ivybridge/northbridge.c @@ -12,6 +12,7 @@ #include <asm/msr.h> #include <asm/acpi.h> #include <asm/cpu.h> +#include <asm/intel_regs.h> #include <asm/io.h> #include <asm/pci.h> #include <asm/processor.h> @@ -167,8 +168,8 @@ static void sandybridge_setup_northbridge_bars(struct udevice *dev) debug("Setting up static registers\n"); dm_pci_write_config32(dev, EPBAR, DEFAULT_EPBAR | 1); dm_pci_write_config32(dev, EPBAR + 4, (0LL + DEFAULT_EPBAR) >> 32); - dm_pci_write_config32(dev, MCHBAR, DEFAULT_MCHBAR | 1); - dm_pci_write_config32(dev, MCHBAR + 4, (0LL + DEFAULT_MCHBAR) >> 32); + dm_pci_write_config32(dev, MCHBAR, MCH_BASE_ADDRESS | 1); + dm_pci_write_config32(dev, MCHBAR + 4, (0LL + MCH_BASE_ADDRESS) >> 32); /* 64MB - busses 0-63 */ dm_pci_write_config32(dev, PCIEXBAR, DEFAULT_PCIEXBAR | 5); dm_pci_write_config32(dev, PCIEXBAR + 4, diff --git a/arch/x86/cpu/ivybridge/sata.c b/arch/x86/cpu/ivybridge/sata.c index a59d9edce5..c3d1057c29 100644 --- a/arch/x86/cpu/ivybridge/sata.c +++ b/arch/x86/cpu/ivybridge/sata.c @@ -9,28 +9,13 @@ #include <dm.h> #include <fdtdec.h> #include <asm/io.h> +#include <asm/pch_common.h> #include <asm/pci.h> #include <asm/arch/pch.h> #include <asm/arch/bd82x6x.h> DECLARE_GLOBAL_DATA_PTR; -static inline u32 sir_read(struct udevice *dev, int idx) -{ - u32 data; - - dm_pci_write_config32(dev, SATA_SIRI, idx); - dm_pci_read_config32(dev, SATA_SIRD, &data); - - return data; -} - -static inline void sir_write(struct udevice *dev, int idx, u32 value) -{ - dm_pci_write_config32(dev, SATA_SIRI, idx); - dm_pci_write_config32(dev, SATA_SIRD, value); -} - static void common_sata_init(struct udevice *dev, unsigned int port_map) { u32 reg32; @@ -177,27 +162,27 @@ static void bd82x6x_sata_init(struct udevice *dev, struct udevice *pch) pch_iobp_update(pch, SATA_IOBP_SP1G3IR, 0, port_tx); /* Additional Programming Requirements */ - sir_write(dev, 0x04, 0x00001600); - sir_write(dev, 0x28, 0xa0000033); - reg32 = sir_read(dev, 0x54); + pch_common_sir_write(dev, 0x04, 0x00001600); + pch_common_sir_write(dev, 0x28, 0xa0000033); + reg32 = pch_common_sir_read(dev, 0x54); reg32 &= 0xff000000; reg32 |= 0x5555aa; - sir_write(dev, 0x54, reg32); - sir_write(dev, 0x64, 0xcccc8484); - reg32 = sir_read(dev, 0x68); + pch_common_sir_write(dev, 0x54, reg32); + pch_common_sir_write(dev, 0x64, 0xcccc8484); + reg32 = pch_common_sir_read(dev, 0x68); reg32 &= 0xffff0000; reg32 |= 0xcccc; - sir_write(dev, 0x68, reg32); - reg32 = sir_read(dev, 0x78); + pch_common_sir_write(dev, 0x68, reg32); + reg32 = pch_common_sir_read(dev, 0x78); reg32 &= 0x0000ffff; reg32 |= 0x88880000; - sir_write(dev, 0x78, reg32); - sir_write(dev, 0x84, 0x001c7000); - sir_write(dev, 0x88, 0x88338822); - sir_write(dev, 0xa0, 0x001c7000); - sir_write(dev, 0xc4, 0x0c0c0c0c); - sir_write(dev, 0xc8, 0x0c0c0c0c); - sir_write(dev, 0xd4, 0x10000000); + pch_common_sir_write(dev, 0x78, reg32); + pch_common_sir_write(dev, 0x84, 0x001c7000); + pch_common_sir_write(dev, 0x88, 0x88338822); + pch_common_sir_write(dev, 0xa0, 0x001c7000); + pch_common_sir_write(dev, 0xc4, 0x0c0c0c0c); + pch_common_sir_write(dev, 0xc8, 0x0c0c0c0c); + pch_common_sir_write(dev, 0xd4, 0x10000000); pch_iobp_update(pch, 0xea004001, 0x3fffffff, 0xc0000000); pch_iobp_update(pch, 0xea00408a, 0xfffffcff, 0x00000100); @@ -229,11 +214,9 @@ static int bd82x6x_sata_probe(struct udevice *dev) struct udevice *pch; int ret; - ret = uclass_first_device(UCLASS_PCH, &pch); + ret = uclass_first_device_err(UCLASS_PCH, &pch); if (ret) return ret; - if (!pch) - return -ENODEV; if (!(gd->flags & GD_FLG_RELOC)) bd82x6x_sata_enable(dev); diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c index e23c422cd0..e35e543c3e 100644 --- a/arch/x86/cpu/ivybridge/sdram.c +++ b/arch/x86/cpu/ivybridge/sdram.c @@ -23,9 +23,12 @@ #include <asm/processor.h> #include <asm/gpio.h> #include <asm/global_data.h> +#include <asm/intel_regs.h> #include <asm/mrccache.h> +#include <asm/mrc_common.h> #include <asm/mtrr.h> #include <asm/pci.h> +#include <asm/report_platform.h> #include <asm/arch/me.h> #include <asm/arch/pei_data.h> #include <asm/arch/pch.h> @@ -38,57 +41,14 @@ DECLARE_GLOBAL_DATA_PTR; #define CMOS_OFFSET_MRC_SEED_S3 156 #define CMOS_OFFSET_MRC_SEED_CHK 160 -/* - * 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. - */ ulong board_get_usable_ram_top(ulong total_size) { - struct memory_info *info = &gd->arch.meminfo; - uintptr_t dest_addr = 0; - struct memory_area *largest = NULL; - int i; - - /* Find largest area of memory below 4GB */ - - for (i = 0; i < info->num_areas; i++) { - struct memory_area *area = &info->area[i]; - - if (area->start >= 1ULL << 32) - continue; - if (!largest || area->size > largest->size) - largest = area; - } - - /* If no suitable area was found, return an error. */ - assert(largest); - if (!largest || largest->size < (2 << 20)) - panic("No available memory found for relocation"); - - dest_addr = largest->start + largest->size; - - return (ulong)dest_addr; + return mrc_common_board_get_usable_ram_top(total_size); } void dram_init_banksize(void) { - struct memory_info *info = &gd->arch.meminfo; - int num_banks; - int i; - - for (i = 0, num_banks = 0; i < info->num_areas; i++) { - struct memory_area *area = &info->area[i]; - - if (area->start >= 1ULL << 32) - continue; - gd->bd->bi_dram[num_banks].start = area->start; - gd->bd->bi_dram[num_banks].size = area->size; - num_banks++; - } + mrc_common_dram_init_banksize(); } static int read_seed_from_cmos(struct pei_data *pei_data) @@ -215,164 +175,10 @@ int misc_init_r(void) return 0; } -static const char *const ecc_decoder[] = { - "inactive", - "active on IO", - "disabled on IO", - "active" -}; - -/* - * Dump in the log memory controller configuration as read from the memory - * controller registers. - */ -static void report_memory_config(void) +static void post_system_agent_init(struct udevice *dev, struct udevice *me_dev, + struct pei_data *pei_data) { - u32 addr_decoder_common, addr_decode_ch[2]; - int i; - - addr_decoder_common = readl(MCHBAR_REG(0x5000)); - addr_decode_ch[0] = readl(MCHBAR_REG(0x5004)); - addr_decode_ch[1] = readl(MCHBAR_REG(0x5008)); - - debug("memcfg DDR3 clock %d MHz\n", - (readl(MCHBAR_REG(0x5e04)) * 13333 * 2 + 50) / 100); - debug("memcfg channel assignment: A: %d, B % d, C % d\n", - addr_decoder_common & 3, - (addr_decoder_common >> 2) & 3, - (addr_decoder_common >> 4) & 3); - - for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) { - u32 ch_conf = addr_decode_ch[i]; - debug("memcfg channel[%d] config (%8.8x):\n", i, ch_conf); - debug(" ECC %s\n", ecc_decoder[(ch_conf >> 24) & 3]); - debug(" enhanced interleave mode %s\n", - ((ch_conf >> 22) & 1) ? "on" : "off"); - debug(" rank interleave %s\n", - ((ch_conf >> 21) & 1) ? "on" : "off"); - debug(" DIMMA %d MB width x%d %s rank%s\n", - ((ch_conf >> 0) & 0xff) * 256, - ((ch_conf >> 19) & 1) ? 16 : 8, - ((ch_conf >> 17) & 1) ? "dual" : "single", - ((ch_conf >> 16) & 1) ? "" : ", selected"); - debug(" DIMMB %d MB width x%d %s rank%s\n", - ((ch_conf >> 8) & 0xff) * 256, - ((ch_conf >> 20) & 1) ? 16 : 8, - ((ch_conf >> 18) & 1) ? "dual" : "single", - ((ch_conf >> 16) & 1) ? ", selected" : ""); - } -} - -static void post_system_agent_init(struct pei_data *pei_data) -{ - /* If PCIe init is skipped, set the PEG clock gating */ - if (!pei_data->pcie_init) - setbits_le32(MCHBAR_REG(0x7010), 1); -} - -static asmlinkage void console_tx_byte(unsigned char byte) -{ -#ifdef DEBUG - putc(byte); -#endif -} - -static int recovery_mode_enabled(void) -{ - return false; -} - -/** - * Find the PEI executable in the ROM and execute it. - * - * @dev: Northbridge device - * @pei_data: configuration data for UEFI PEI reference code - */ -int sdram_initialise(struct udevice *dev, struct udevice *me_dev, - struct pei_data *pei_data) -{ - unsigned version; - const char *data; uint16_t done; - int ret; - - report_platform_info(dev); - - /* Wait for ME to be ready */ - ret = intel_early_me_init(me_dev); - if (ret) - return ret; - ret = intel_early_me_uma_size(me_dev); - if (ret < 0) - return ret; - - debug("Starting UEFI PEI System Agent\n"); - - /* - * Do not pass MRC data in for recovery mode boot, - * Always pass it in for S3 resume. - */ - if (!recovery_mode_enabled() || - pei_data->boot_mode == PEI_BOOT_RESUME) { - ret = prepare_mrc_cache(pei_data); - if (ret) - debug("prepare_mrc_cache failed: %d\n", ret); - } - - /* If MRC data is not found we cannot continue S3 resume. */ - if (pei_data->boot_mode == PEI_BOOT_RESUME && !pei_data->mrc_input) { - debug("Giving up in sdram_initialize: No MRC data\n"); - reset_cpu(0); - } - - /* Pass console handler in pei_data */ - pei_data->tx_byte = console_tx_byte; - - debug("PEI data at %p, size %x:\n", pei_data, sizeof(*pei_data)); - - data = (char *)CONFIG_X86_MRC_ADDR; - if (data) { - int rv; - int (*func)(struct pei_data *); - ulong start; - - debug("Calling MRC at %p\n", data); - post_code(POST_PRE_MRC); - start = get_timer(0); - func = (int (*)(struct pei_data *))data; - rv = func(pei_data); - post_code(POST_MRC); - if (rv) { - switch (rv) { - case -1: - printf("PEI version mismatch.\n"); - break; - case -2: - printf("Invalid memory frequency.\n"); - break; - default: - printf("MRC returned %x.\n", rv); - } - printf("Nonzero MRC return value.\n"); - return -EFAULT; - } - debug("MRC execution time %lu ms\n", get_timer(start)); - } else { - printf("UEFI PEI System Agent not found.\n"); - return -ENOSYS; - } - -#if CONFIG_USBDEBUG - /* mrc.bin reconfigures USB, so reinit it to have debug */ - early_usbdebug_init(); -#endif - - version = readl(MCHBAR_REG(0x5034)); - debug("System Agent Version %d.%d.%d Build %d\n", - version >> 24 , (version >> 16) & 0xff, - (version >> 8) & 0xff, version & 0xff); - debug("MRC output data length %#x at %p\n", pei_data->mrc_output_len, - pei_data->mrc_output); /* * Send ME init done for SandyBridge here. This is done inside the @@ -383,25 +189,16 @@ int sdram_initialise(struct udevice *dev, struct udevice *me_dev, if (BASE_REV_SNB == done) intel_early_me_init_done(dev, me_dev, ME_INIT_STATUS_SUCCESS); else - intel_early_me_status(me_dev); - - post_system_agent_init(pei_data); - report_memory_config(); + intel_me_status(me_dev); - /* S3 resume: don't save scrambler seed or MRC data */ - if (pei_data->boot_mode != PEI_BOOT_RESUME) { - /* - * This will be copied to SDRAM in reserve_arch(), then written - * to SPI flash in mrccache_save() - */ - gd->arch.mrc_output = (char *)pei_data->mrc_output; - gd->arch.mrc_output_len = pei_data->mrc_output_len; - ret = write_seeds_to_cmos(pei_data); - if (ret) - debug("Failed to write seeds to CMOS: %d\n", ret); - } + /* If PCIe init is skipped, set the PEG clock gating */ + if (!pei_data->pcie_init) + setbits_le32(MCHBAR_REG(0x7010), 1); +} - return 0; +static int recovery_mode_enabled(void) +{ + return false; } int reserve_arch(void) @@ -409,87 +206,16 @@ int reserve_arch(void) return mrccache_reserve(); } -static int copy_spd(struct pei_data *peid) +static int copy_spd(struct udevice *dev, struct pei_data *peid) { - const int gpio_vector[] = {41, 42, 43, 10, -1}; - int spd_index; - const void *blob = gd->fdt_blob; - int node, spd_node; - int ret, i; - - for (i = 0; ; i++) { - if (gpio_vector[i] == -1) - break; - ret = gpio_requestf(gpio_vector[i], "spd_id%d", i); - if (ret) { - debug("%s: Could not request gpio %d\n", __func__, - gpio_vector[i]); - return ret; - } - } - spd_index = gpio_get_values_as_int(gpio_vector); - debug("spd index %d\n", spd_index); - node = fdtdec_next_compatible(blob, 0, COMPAT_MEMORY_SPD); - if (node < 0) { - printf("SPD data not found.\n"); - return -ENOENT; - } - - for (spd_node = fdt_first_subnode(blob, node); - spd_node > 0; - spd_node = fdt_next_subnode(blob, spd_node)) { - const char *data; - int len; - - if (fdtdec_get_int(blob, spd_node, "reg", -1) != spd_index) - continue; - data = fdt_getprop(blob, spd_node, "data", &len); - if (len < sizeof(peid->spd_data[0])) { - printf("Missing SPD data\n"); - return -EINVAL; - } - - debug("Using SDRAM SPD data for '%s'\n", - fdt_get_name(blob, spd_node, NULL)); - memcpy(peid->spd_data[0], data, sizeof(peid->spd_data[0])); - break; - } - - if (spd_node < 0) { - printf("No SPD data found for index %d\n", spd_index); - return -ENOENT; - } + const void *data; + int ret; - return 0; -} + ret = mrc_locate_spd(dev, sizeof(peid->spd_data[0]), &data); + if (ret) + return ret; -/** - * add_memory_area() - Add a new usable memory area to our list - * - * Note: @start and @end must not span the first 4GB boundary - * - * @info: Place to store memory info - * @start: Start of this memory area - * @end: End of this memory area + 1 - */ -static int add_memory_area(struct memory_info *info, - uint64_t start, uint64_t end) -{ - struct memory_area *ptr; - - if (info->num_areas == CONFIG_NR_DRAM_BANKS) - return -ENOSPC; - - ptr = &info->area[info->num_areas]; - ptr->start = start; - ptr->size = end - start; - info->total_memory += ptr->size; - if (ptr->start < (1ULL << 32)) - info->total_32bit_memory += ptr->size; - debug("%d: memory %llx size %llx, total now %llx / %llx\n", - info->num_areas, ptr->start, ptr->size, - info->total_32bit_memory, info->total_memory); - info->num_areas++; + memcpy(peid->spd_data[0], data, sizeof(peid->spd_data[0])); return 0; } @@ -608,10 +334,10 @@ static int sdram_find(struct udevice *dev) debug("Available memory below 4GB: %lluM\n", tomk >> 10); /* Report the memory regions */ - add_memory_area(info, 1 << 20, 2 << 28); - add_memory_area(info, (2 << 28) + (2 << 20), 4 << 28); - add_memory_area(info, (4 << 28) + (2 << 20), tseg_base); - add_memory_area(info, 1ULL << 32, touud); + mrc_add_memory_area(info, 1 << 20, 2 << 28); + mrc_add_memory_area(info, (2 << 28) + (2 << 20), 4 << 28); + mrc_add_memory_area(info, (4 << 28) + (2 << 20), tseg_base); + mrc_add_memory_area(info, 1ULL << 32, touud); /* Add MTRRs for memory */ mtrr_add_request(MTRR_TYPE_WRBACK, 0, 2ULL << 30); @@ -680,9 +406,9 @@ static void rcba_config(void) int dram_init(void) { - struct pei_data pei_data __aligned(8) = { + struct pei_data _pei_data __aligned(8) = { .pei_version = PEI_VERSION, - .mchbar = DEFAULT_MCHBAR, + .mchbar = MCH_BASE_ADDRESS, .dmibar = DEFAULT_DMIBAR, .epbar = DEFAULT_EPBAR, .pciexbar = CONFIG_PCIE_ECAM_BASE, @@ -733,38 +459,84 @@ int dram_init(void) { 0, 4, 0x0000 }, /* P13= Empty */ }, }; + struct pei_data *pei_data = &_pei_data; struct udevice *dev, *me_dev; int ret; - ret = uclass_first_device(UCLASS_NORTHBRIDGE, &dev); + ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &dev); if (ret) return ret; - if (!dev) - return -ENODEV; ret = syscon_get_by_driver_data(X86_SYSCON_ME, &me_dev); if (ret) return ret; - debug("Boot mode %d\n", gd->arch.pei_boot_mode); - debug("mrc_input %p\n", pei_data.mrc_input); - pei_data.boot_mode = gd->arch.pei_boot_mode; - ret = copy_spd(&pei_data); - if (!ret) - ret = sdram_initialise(dev, me_dev, &pei_data); + ret = copy_spd(dev, pei_data); if (ret) return ret; + pei_data->boot_mode = gd->arch.pei_boot_mode; + debug("Boot mode %d\n", gd->arch.pei_boot_mode); + debug("mrc_input %p\n", pei_data->mrc_input); - rcba_config(); - quick_ram_check(); + /* + * Do not pass MRC data in for recovery mode boot, + * Always pass it in for S3 resume. + */ + if (!recovery_mode_enabled() || + pei_data->boot_mode == PEI_BOOT_RESUME) { + ret = prepare_mrc_cache(pei_data); + if (ret) + debug("prepare_mrc_cache failed: %d\n", ret); + } - writew(0xCAFE, MCHBAR_REG(SSKPD)); + /* If MRC data is not found we cannot continue S3 resume. */ + if (pei_data->boot_mode == PEI_BOOT_RESUME && !pei_data->mrc_input) { + debug("Giving up in sdram_initialize: No MRC data\n"); + reset_cpu(0); + } - post_code(POST_DRAM); + /* Pass console handler in pei_data */ + pei_data->tx_byte = sdram_console_tx_byte; - ret = sdram_find(dev); + /* Wait for ME to be ready */ + ret = intel_early_me_init(me_dev); if (ret) return ret; + ret = intel_early_me_uma_size(me_dev); + if (ret < 0) + return ret; + ret = mrc_common_init(dev, pei_data, false); + if (ret) + return ret; + + ret = sdram_find(dev); + if (ret) + return ret; gd->ram_size = gd->arch.meminfo.total_32bit_memory; + debug("MRC output data length %#x at %p\n", pei_data->mrc_output_len, + pei_data->mrc_output); + + post_system_agent_init(dev, me_dev, pei_data); + report_memory_config(); + + /* S3 resume: don't save scrambler seed or MRC data */ + if (pei_data->boot_mode != PEI_BOOT_RESUME) { + /* + * This will be copied to SDRAM in reserve_arch(), then written + * to SPI flash in mrccache_save() + */ + gd->arch.mrc_output = (char *)pei_data->mrc_output; + gd->arch.mrc_output_len = pei_data->mrc_output_len; + ret = write_seeds_to_cmos(pei_data); + if (ret) + debug("Failed to write seeds to CMOS: %d\n", ret); + } + + writew(0xCAFE, MCHBAR_REG(SSKPD)); + if (ret) + return ret; + + rcba_config(); + return 0; } diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c index fc2fb5bf44..2604a687ab 100644 --- a/arch/x86/cpu/mp_init.c +++ b/arch/x86/cpu/mp_init.c @@ -15,6 +15,7 @@ #include <asm/cpu.h> #include <asm/interrupt.h> #include <asm/lapic.h> +#include <asm/microcode.h> #include <asm/mp.h> #include <asm/msr.h> #include <asm/mtrr.h> @@ -195,7 +196,7 @@ static int save_bsp_msrs(char *start, int size) msr_count = 2 * num_var_mtrrs + NUM_FIXED_MTRRS + 1; if ((msr_count * sizeof(struct saved_msr)) > size) { - printf("Cannot mirror all %d msrs.\n", msr_count); + printf("Cannot mirror all %d msrs\n", msr_count); return -ENOSPC; } @@ -247,8 +248,10 @@ static int load_sipi_vector(atomic_t **ap_countp, int num_cpus) if (!stack) return -ENOMEM; params->stack_top = (u32)(stack + size); - - params->microcode_ptr = 0; +#if !defined(CONFIG_QEMU) && !defined(CONFIG_HAVE_FSP) + params->microcode_ptr = ucode_base; + debug("Microcode at %x\n", params->microcode_ptr); +#endif params->msr_table_ptr = (u32)msr_save; ret = save_bsp_msrs(msr_save, sizeof(msr_save)); if (ret < 0) @@ -283,21 +286,25 @@ static int check_cpu_devices(int expected_cpus) } /* Returns 1 for timeout. 0 on success */ -static int apic_wait_timeout(int total_delay, int delay_step) +static int apic_wait_timeout(int total_delay, const char *msg) { int total = 0; - int timeout = 0; + if (!(lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) + return 0; + + debug("Waiting for %s...", msg); while (lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY) { - udelay(delay_step); - total += delay_step; + udelay(50); + total += 50; if (total >= total_delay) { - timeout = 1; - break; + debug("timed out: aborting\n"); + return -ETIMEDOUT; } } + debug("done\n"); - return timeout; + return 0; } static int start_aps(int ap_count, atomic_t *num_aps) @@ -320,73 +327,42 @@ static int start_aps(int ap_count, atomic_t *num_aps) debug("Attempting to start %d APs\n", ap_count); - if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) { - debug("Waiting for ICR not to be busy..."); - if (apic_wait_timeout(1000, 50)) { - debug("timed out. Aborting.\n"); - return -1; - } else { - debug("done.\n"); - } - } + if (apic_wait_timeout(1000, "ICR not to be busy")) + return -ETIMEDOUT; /* Send INIT IPI to all but self */ lapic_write(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0)); lapic_write(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT); - debug("Waiting for 10ms after sending INIT.\n"); + debug("Waiting for 10ms after sending INIT\n"); mdelay(10); /* Send 1st SIPI */ - if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) { - debug("Waiting for ICR not to be busy..."); - if (apic_wait_timeout(1000, 50)) { - debug("timed out. Aborting.\n"); - return -1; - } else { - debug("done.\n"); - } - } + if (apic_wait_timeout(1000, "ICR not to be busy")) + return -ETIMEDOUT; lapic_write(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0)); lapic_write(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_STARTUP | sipi_vector); - debug("Waiting for 1st SIPI to complete..."); - if (apic_wait_timeout(10000, 50)) { - debug("timed out.\n"); - return -1; - } else { - debug("done.\n"); - } + if (apic_wait_timeout(10000, "first SIPI to complete")) + return -ETIMEDOUT; /* Wait for CPUs to check in up to 200 us */ wait_for_aps(num_aps, ap_count, 200, 15); /* Send 2nd SIPI */ - if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) { - debug("Waiting for ICR not to be busy..."); - if (apic_wait_timeout(1000, 50)) { - debug("timed out. Aborting.\n"); - return -1; - } else { - debug("done.\n"); - } - } + if (apic_wait_timeout(1000, "ICR not to be busy")) + return -ETIMEDOUT; lapic_write(LAPIC_ICR2, SET_LAPIC_DEST_FIELD(0)); lapic_write(LAPIC_ICR, LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_STARTUP | sipi_vector); - debug("Waiting for 2nd SIPI to complete..."); - if (apic_wait_timeout(10000, 50)) { - debug("timed out.\n"); - return -1; - } else { - debug("done.\n"); - } + if (apic_wait_timeout(10000, "second SIPI to complete")) + return -ETIMEDOUT; /* Wait for CPUs to check in */ if (wait_for_aps(num_aps, ap_count, 10000, 50)) { - debug("Not all APs checked in: %d/%d.\n", + debug("Not all APs checked in: %d/%d\n", atomic_read(num_aps), ap_count); return -1; } @@ -410,7 +386,7 @@ static int bsp_do_flight_plan(struct udevice *cpu, struct mp_params *mp_params) /* Wait for the APs to check in */ if (wait_for_aps(&rec->cpus_entered, num_aps, timeout_us, step_us)) { - debug("MP record %d timeout.\n", i); + debug("MP record %d timeout\n", i); ret = -1; } } @@ -430,7 +406,7 @@ static int init_bsp(struct udevice **devp) int ret; cpu_get_name(processor_name); - debug("CPU: %s.\n", processor_name); + debug("CPU: %s\n", processor_name); lapic_setup(); @@ -587,12 +563,16 @@ int mp_init(struct mp_params *p) int mp_init_cpu(struct udevice *cpu, void *unused) { + struct cpu_platdata *plat = dev_get_parent_platdata(cpu); + /* * Multiple APs are brought up simultaneously and they may get the same * seq num in the uclass_resolve_seq() during device_probe(). To avoid * this, set req_seq to the reg number in the device tree in advance. */ cpu->req_seq = fdtdec_get_int(gd->fdt_blob, cpu->of_offset, "reg", -1); + plat->ucode_version = microcode_read_rev(); + plat->device_id = gd->arch.x86_device; return device_probe(cpu); } diff --git a/arch/x86/cpu/qemu/fw_cfg.c b/arch/x86/cpu/qemu/fw_cfg.c index 5ea7a6e2e5..a0a3d08079 100644 --- a/arch/x86/cpu/qemu/fw_cfg.c +++ b/arch/x86/cpu/qemu/fw_cfg.c @@ -232,8 +232,7 @@ static struct fw_file *qemu_fwcfg_find_file(const char *name) * be ignored. * @return: 0 on success, or negative value on failure */ -static int bios_linker_allocate(struct bios_linker_entry *entry, - unsigned long *addr) +static int bios_linker_allocate(struct bios_linker_entry *entry, u32 *addr) { uint32_t size, align; struct fw_file *file; @@ -383,7 +382,7 @@ unsigned install_e820_map(unsigned max_entries, struct e820entry *entries) } /* This function loads and patches ACPI tables provided by QEMU */ -unsigned long write_acpi_tables(unsigned long addr) +u32 write_acpi_tables(u32 addr) { int i, ret = 0; struct fw_file *file; diff --git a/arch/x86/cpu/sipi_vector.S b/arch/x86/cpu/sipi_vector.S index 0c4a157f38..94c0f5a702 100644 --- a/arch/x86/cpu/sipi_vector.S +++ b/arch/x86/cpu/sipi_vector.S @@ -193,6 +193,7 @@ load_msr: mov c_handler, %esi call *%esi + /* This matches struct sipi_param */ .align 4 .globl sipi_params sipi_params: diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index 485868ff57..a5cba1cf2a 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -18,6 +18,14 @@ #include <generated/generic-asm-offsets.h> #include <generated/asm-offsets.h> +/* + * Define this to boot U-Boot from a 32-bit program which sets the GDT + * differently. This can be used to boot directly from any stage of coreboot, + * for example, bypassing the normal payload-loading feature. + * This is only useful for development. + */ +#undef LOAD_FROM_32_BIT + .section .text .code32 .globl _start @@ -68,6 +76,10 @@ _start: /* Save table pointer */ movl %ecx, %esi +#ifdef LOAD_FROM_32_BIT + lgdt gdt_ptr2 +#endif + /* Load the segement registers to match the GDT loaded in start16.S */ movl $(X86_GDT_ENTRY_32BIT_DS * X86_GDT_ENTRY_SIZE), %eax movw %ax, %fs @@ -220,3 +232,71 @@ multiboot_header: .long 0 /* entry addr */ .long CONFIG_SYS_TEXT_BASE + +#ifdef LOAD_FROM_32_BIT + /* + * The following Global Descriptor Table is just enough to get us into + * 'Flat Protected Mode' - It will be discarded as soon as the final + * GDT is setup in a safe location in RAM + */ +gdt_ptr2: + .word 0x1f /* limit (31 bytes = 4 GDT entries - 1) */ + .long gdt_rom2 /* base */ + + /* Some CPUs are picky about GDT alignment... */ + .align 16 +.globl gdt_rom2 +gdt_rom2: + /* + * The GDT table ... + * + * Selector Type + * 0x00 NULL + * 0x08 Unused + * 0x10 32bit code + * 0x18 32bit data/stack + */ + /* The NULL Desciptor - Mandatory */ + .word 0x0000 /* limit_low */ + .word 0x0000 /* base_low */ + .byte 0x00 /* base_middle */ + .byte 0x00 /* access */ + .byte 0x00 /* flags + limit_high */ + .byte 0x00 /* base_high */ + + /* Unused Desciptor - (matches Linux) */ + .word 0x0000 /* limit_low */ + .word 0x0000 /* base_low */ + .byte 0x00 /* base_middle */ + .byte 0x00 /* access */ + .byte 0x00 /* flags + limit_high */ + .byte 0x00 /* base_high */ + + /* + * The Code Segment Descriptor: + * - Base = 0x00000000 + * - Size = 4GB + * - Access = Present, Ring 0, Exec (Code), Readable + * - Flags = 4kB Granularity, 32-bit + */ + .word 0xffff /* limit_low */ + .word 0x0000 /* base_low */ + .byte 0x00 /* base_middle */ + .byte 0x9b /* access */ + .byte 0xcf /* flags + limit_high */ + .byte 0x00 /* base_high */ + + /* + * The Data Segment Descriptor: + * - Base = 0x00000000 + * - Size = 4GB + * - Access = Present, Ring 0, Non-Exec (Data), Writable + * - Flags = 4kB Granularity, 32-bit + */ + .word 0xffff /* limit_low */ + .word 0x0000 /* base_low */ + .byte 0x00 /* base_middle */ + .byte 0x93 /* access */ + .byte 0xcf /* flags + limit_high */ + .byte 0x00 /* base_high */ +#endif diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile index 84feb193d7..23156bb231 100644 --- a/arch/x86/dts/Makefile +++ b/arch/x86/dts/Makefile @@ -5,6 +5,8 @@ dtb-y += bayleybay.dtb \ chromebook_link.dtb \ chromebox_panther.dtb \ + chromebook_samus.dtb \ + conga-qeval20-qa3-e3845.dtb \ cougarcanyon2.dtb \ crownbay.dtb \ efi.dtb \ diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts index f85e55cd6d..fb1b31dc5e 100644 --- a/arch/x86/dts/chromebook_link.dts +++ b/arch/x86/dts/chromebook_link.dts @@ -1,5 +1,7 @@ /dts-v1/; +#include <dt-bindings/gpio/x86-gpio.h> + /include/ "skeleton.dtsi" /include/ "keyboard.dtsi" /include/ "serial.dtsi" @@ -62,115 +64,157 @@ intel,duplicate-por; }; - spd { - compatible = "memory-spd"; - #address-cells = <1>; - #size-cells = <0>; - elpida_4Gb_1600_x16 { - reg = <0>; - data = [92 10 0b 03 04 19 02 02 - 03 52 01 08 0a 00 fe 00 - 69 78 69 3c 69 11 18 81 - 20 08 3c 3c 01 40 83 81 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 0f 11 42 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 02 fe 00 - 11 52 00 00 00 07 7f 37 - 45 42 4a 32 30 55 47 36 - 45 42 55 30 2d 47 4e 2d - 46 20 30 20 02 fe 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00]; - }; - samsung_4Gb_1600_1.35v_x16 { - reg = <1>; - data = [92 11 0b 03 04 19 02 02 - 03 11 01 08 0a 00 fe 00 - 69 78 69 3c 69 11 18 81 - f0 0a 3c 3c 01 40 83 01 - 00 80 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 0f 11 02 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 80 ce 01 - 00 00 00 00 00 00 6a 04 - 4d 34 37 31 42 35 36 37 - 34 42 48 30 2d 59 4b 30 - 20 20 00 00 80 ce 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00]; - }; - micron_4Gb_1600_1.35v_x16 { - reg = <2>; - data = [92 11 0b 03 04 19 02 02 - 03 11 01 08 0a 00 fe 00 - 69 78 69 3c 69 11 18 81 - 20 08 3c 3c 01 40 83 05 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 0f 01 02 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 80 2c 00 - 00 00 00 00 00 00 ad 75 - 34 4b 54 46 32 35 36 36 - 34 48 5a 2d 31 47 36 45 - 31 20 45 31 80 2c 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 - ff ff ff ff ff ff ff ff - ff ff ff ff ff ff ff ff - ff ff ff ff ff ff ff ff - ff ff ff ff ff ff ff ff - ff ff ff ff ff ff ff ff - ff ff ff ff ff ff ff ff - ff ff ff ff ff ff ff ff - ff ff ff ff ff ff ff ff - ff ff ff ff ff ff ff ff - ff ff ff ff ff ff ff ff]; + pch_pinctrl { + compatible = "intel,x86-pinctrl"; + u-boot,dm-pre-reloc; + reg = <0 0>; + + gpio_a0 { + gpio-offset = <0 0>; + mode-gpio; + direction = <PIN_INPUT>; + }; + + gpio_a1 { + gpio-offset = <0>; + mode-gpio; + direction = <PIN_OUTPUT>; + output-value = <1>; + }; + + gpio_a3 { + gpio-offset = <0 3>; + mode-gpio; + direction = <PIN_INPUT>; + }; + + gpio_a5 { + gpio-offset = <0 5>; + mode-gpio; + direction = <PIN_INPUT>; + }; + + gpio_a6 { + gpio-offset = <0 6>; + mode-gpio; + direction = <PIN_OUTPUT>; + output-value = <1>; + }; + + gpio_a7 { + gpio-offset = <0 7>; + mode-gpio; + direction = <PIN_INPUT>; + invert; + }; + + gpio_a8 { + gpio-offset = <0 8>; + mode-gpio; + direction = <PIN_INPUT>; + invert; + }; + + gpio_a9 { + gpio-offset = <0 9>; + mode-gpio; + direction = <PIN_INPUT>; + }; + + gpio_a10 { + u-boot,dm-pre-reloc; + gpio-offset = <0 10>; + mode-gpio; + direction = <PIN_INPUT>; + }; + + gpio_a11 { + gpio-offset = <0 11>; + mode-gpio; + direction = <PIN_INPUT>; + }; + + gpio_a12 { + gpio-offset = <0 12>; + mode-gpio; + direction = <PIN_INPUT>; + invert; + }; + + gpio_a14 { + gpio-offset = <0 14>; + mode-gpio; + direction = <PIN_INPUT>; + invert; }; + + gpio_a15 { + gpio-offset = <0 15>; + mode-gpio; + direction = <PIN_INPUT>; + invert; + }; + + gpio_a21 { + gpio-offset = <0 21>; + mode-gpio; + direction = <PIN_INPUT>; + }; + + gpio_a24 { + gpio-offset = <0 24>; + mode-gpio; + output-value = <0>; + direction = <PIN_OUTPUT>; + }; + + gpio_a28 { + gpio-offset = <0 28>; + mode-gpio; + direction = <PIN_INPUT>; + }; + + gpio_b4 { + gpio-offset = <0x30 4>; + mode-gpio; + direction = <PIN_OUTPUT>; + output-value = <1>; + }; + + gpio_b9 { + u-boot,dm-pre-reloc; + gpio-offset = <0x30 9>; + mode-gpio; + direction = <PIN_INPUT>; + }; + + gpio_b10 { + u-boot,dm-pre-reloc; + gpio-offset = <0x30 10>; + mode-gpio; + direction = <PIN_INPUT>; + }; + + gpio_b11 { + u-boot,dm-pre-reloc; + gpio-offset = <0x30 11>; + mode-gpio; + direction = <PIN_INPUT>; + }; + + gpio_b25 { + gpio-offset = <0x30 25>; + mode-gpio; + direction = <PIN_INPUT>; + }; + + gpio_b28 { + gpio-offset = <0x30 28>; + mode-gpio; + direction = <PIN_OUTPUT>; + output-value = <1>; + }; + }; pci { @@ -185,7 +229,118 @@ northbridge@0,0 { reg = <0x00000000 0 0 0 0>; compatible = "intel,bd82x6x-northbridge"; + board-id-gpios = <&gpio_b 9 0>, <&gpio_b 10 0>, + <&gpio_b 11 0>, <&gpio_a 10 0>; u-boot,dm-pre-reloc; + spd { + #address-cells = <1>; + #size-cells = <0>; + elpida_4Gb_1600_x16 { + reg = <0>; + data = [92 10 0b 03 04 19 02 02 + 03 52 01 08 0a 00 fe 00 + 69 78 69 3c 69 11 18 81 + 20 08 3c 3c 01 40 83 81 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 11 42 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 02 fe 00 + 11 52 00 00 00 07 7f 37 + 45 42 4a 32 30 55 47 36 + 45 42 55 30 2d 47 4e 2d + 46 20 30 20 02 fe 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + samsung_4Gb_1600_1.35v_x16 { + reg = <1>; + data = [92 11 0b 03 04 19 02 02 + 03 11 01 08 0a 00 fe 00 + 69 78 69 3c 69 11 18 81 + f0 0a 3c 3c 01 40 83 01 + 00 80 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 11 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 80 ce 01 + 00 00 00 00 00 00 6a 04 + 4d 34 37 31 42 35 36 37 + 34 42 48 30 2d 59 4b 30 + 20 20 00 00 80 ce 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + micron_4Gb_1600_1.35v_x16 { + reg = <2>; + data = [92 11 0b 03 04 19 02 02 + 03 11 01 08 0a 00 fe 00 + 69 78 69 3c 69 11 18 81 + 20 08 3c 3c 01 40 83 05 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 01 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 80 2c 00 + 00 00 00 00 00 00 ad 75 + 34 4b 54 46 32 35 36 36 + 34 48 5a 2d 31 47 36 45 + 31 20 45 31 80 2c 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff]; + }; + }; }; gma@2,0 { @@ -249,23 +404,29 @@ }; }; - gpioa { + gpio_a: gpioa { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc; + #gpio-cells = <2>; + gpio-controller; reg = <0 0x10>; bank-name = "A"; }; - gpiob { + gpio_b: gpiob { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc; + #gpio-cells = <2>; + gpio-controller; reg = <0x30 0x10>; bank-name = "B"; }; - gpioc { + gpio_c: gpioc { compatible = "intel,ich6-gpio"; u-boot,dm-pre-reloc; + #gpio-cells = <2>; + gpio-controller; reg = <0x40 0x10>; bank-name = "C"; }; diff --git a/arch/x86/dts/chromebook_samus.dts b/arch/x86/dts/chromebook_samus.dts new file mode 100644 index 0000000000..5dd3e57cb9 --- /dev/null +++ b/arch/x86/dts/chromebook_samus.dts @@ -0,0 +1,628 @@ +/dts-v1/; + +#include <dt-bindings/gpio/x86-gpio.h> + +/include/ "skeleton.dtsi" +/include/ "keyboard.dtsi" +/include/ "serial.dtsi" +/include/ "rtc.dtsi" +/include/ "tsc_timer.dtsi" + +/ { + model = "Google Samus"; + compatible = "google,samus", "intel,broadwell"; + + aliases { + spi0 = &spi; + usb0 = &usb_0; + usb1 = &usb_1; + }; + + config { + silent_console = <0>; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "intel,core-i3-gen5"; + reg = <0>; + intel,apic-id = <0>; + intel,slow-ramp = <3>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "intel,core-i3-gen5"; + reg = <1>; + intel,apic-id = <1>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "intel,core-i3-gen5"; + reg = <2>; + intel,apic-id = <2>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "intel,core-i3-gen5"; + reg = <3>; + intel,apic-id = <3>; + }; + + }; + + chosen { + stdout-path = "/serial"; + }; + + keyboard { + intel,duplicate-por; + }; + + pch_pinctrl { + compatible = "intel,x86-broadwell-pinctrl"; + u-boot,dm-pre-reloc; + reg = <0 0>; + + /* Put this first: it is the default */ + gpio_unused: gpio-unused { + mode-gpio; + direction = <PIN_INPUT>; + owner = <OWNER_GPIO>; + sense-disable; + }; + + gpio_acpi_sci: acpi-sci { + mode-gpio; + direction = <PIN_INPUT>; + invert; + route = <ROUTE_SCI>; + }; + + gpio_acpi_smi: acpi-smi { + mode-gpio; + direction = <PIN_INPUT>; + invert; + route = <ROUTE_SMI>; + }; + + gpio_input: gpio-input { + mode-gpio; + direction = <PIN_INPUT>; + owner = <OWNER_GPIO>; + }; + + gpio_input_invert: gpio-input-invert { + mode-gpio; + direction = <PIN_INPUT>; + owner = <OWNER_GPIO>; + invert; + }; + + gpio_native: gpio-native { + }; + + gpio_out_high: gpio-out-high { + mode-gpio; + direction = <PIN_OUTPUT>; + output-value = <1>; + owner = <OWNER_GPIO>; + sense-disable; + }; + + gpio_out_low: gpio-out-low { + mode-gpio; + direction = <PIN_OUTPUT>; + output-value = <0>; + owner = <OWNER_GPIO>; + sense-disable; + }; + + gpio_pirq: gpio-pirq { + mode-gpio; + direction = <PIN_INPUT>; + owner = <OWNER_GPIO>; + pirq-apic = <PIRQ_APIC_ROUTE>; + }; + + soc_gpio@0 { + config = + <0 &gpio_unused 0>, /* unused */ + <1 &gpio_unused 0>, /* unused */ + <2 &gpio_unused 0>, /* unused */ + <3 &gpio_unused 0>, /* unused */ + <4 &gpio_native 0>, /* native: i2c0_sda_gpio4 */ + <5 &gpio_native 0>, /* native: i2c0_scl_gpio5 */ + <6 &gpio_native 0>, /* native: i2c1_sda_gpio6 */ + <7 &gpio_native 0>, /* native: i2c1_scl_gpio7 */ + <8 &gpio_acpi_sci 0>, /* pch_lte_wake_l */ + <9 &gpio_input_invert 0>, /* trackpad_int_l (wake) */ + <10 &gpio_acpi_sci 0>, /* pch_wlan_wake_l */ + <11 &gpio_unused 0>, /* unused */ + <12 &gpio_unused 0>, /* unused */ + <13 &gpio_pirq 3>, /* trackpad_int_l (pirql) */ + <14 &gpio_pirq 4>, /* touch_int_l (pirqm) */ + <15 &gpio_unused 0>, /* unused (strap) */ + <16 &gpio_input 0>, /* pch_wp */ + <17 &gpio_unused 0>, /* unused */ + <18 &gpio_unused 0>, /* unused */ + <19 &gpio_unused 0>, /* unused */ + <20 &gpio_native 0>, /* pcie_wlan_clkreq_l */ + <21 &gpio_out_high 0>, /* pp3300_ssd_en */ + <22 &gpio_unused 0>, /* unused */ + <23 &gpio_out_low 0>, /* pp3300_autobahn_en */ + <24 &gpio_unused 0>, /* unused */ + <25 &gpio_input 0>, /* ec_in_rw */ + <26 &gpio_unused 0>, /* unused */ + <27 &gpio_acpi_sci 0>, /* pch_wake_l */ + <28 &gpio_unused 0>, /* unused */ + <29 &gpio_unused 0>, /* unused */ + <30 &gpio_native 0>, /* native: pch_suswarn_l */ + <31 &gpio_native 0>, /* native: acok_buf */ + <32 &gpio_native 0>, /* native: lpc_clkrun_l */ + <33 &gpio_native 0>, /* native: ssd_devslp */ + <34 &gpio_acpi_smi 0>, /* ec_smi_l */ + <35 &gpio_acpi_smi 0>, /* pch_nmi_dbg_l (route in nmi_en) */ + <36 &gpio_acpi_sci 0>, /* ec_sci_l */ + <37 &gpio_unused 0>, /* unused */ + <38 &gpio_unused 0>, /* unused */ + <39 &gpio_unused 0>, /* unused */ + <40 &gpio_native 0>, /* native: pch_usb1_oc_l */ + <41 &gpio_native 0>, /* native: pch_usb2_oc_l */ + <42 &gpio_unused 0>, /* wlan_disable_l */ + <43 &gpio_out_high 0>, /* pp1800_codec_en */ + <44 &gpio_unused 0>, /* unused */ + <45 &gpio_acpi_sci 0>, /* dsp_int - codec wake */ + <46 &gpio_pirq 6>, /* hotword_det_l_3v3 (pirqo) - codec irq */ + <47 &gpio_out_low 0>, /* ssd_reset_l */ + <48 &gpio_unused 0>, /* unused */ + <49 &gpio_unused 0>, /* unused */ + <50 &gpio_unused 0>, /* unused */ + <51 &gpio_unused 0>, /* unused */ + <52 &gpio_input 0>, /* sim_det */ + <53 &gpio_unused 0>, /* unused */ + <54 &gpio_unused 0>, /* unused */ + <55 &gpio_unused 0>, /* unused */ + <56 &gpio_unused 0>, /* unused */ + <57 &gpio_out_high 0>, /* codec_reset_l */ + <58 &gpio_unused 0>, /* unused */ + <59 &gpio_out_high 0>, /* lte_disable_l */ + <60 &gpio_unused 0>, /* unused */ + <61 &gpio_native 0>, /* native: pch_sus_stat */ + <62 &gpio_native 0>, /* native: pch_susclk */ + <63 &gpio_native 0>, /* native: pch_slp_s5_l */ + <64 &gpio_unused 0>, /* unused */ + <65 &gpio_input 0>, /* ram_id3 */ + <66 &gpio_input 0>, /* ram_id3_old (strap) */ + <67 &gpio_input 0>, /* ram_id0 */ + <68 &gpio_input 0>, /* ram_id1 */ + <69 &gpio_input 0>, /* ram_id2 */ + <70 &gpio_unused 0>, /* unused */ + <71 &gpio_native 0>, /* native: modphy_en */ + <72 &gpio_unused 0>, /* unused */ + <73 &gpio_unused 0>, /* unused */ + <74 &gpio_unused 0>, /* unused */ + <75 &gpio_unused 0>, /* unused */ + <76 &gpio_unused 0>, /* unused */ + <77 &gpio_unused 0>, /* unused */ + <78 &gpio_unused 0>, /* unused */ + <79 &gpio_unused 0>, /* unused */ + <80 &gpio_unused 0>, /* unused */ + <81 &gpio_unused 0>, /* unused */ + <82 &gpio_native 0>, /* native: ec_rcin_l */ + <83 &gpio_native 0>, /* gspi0_cs */ + <84 &gpio_native 0>, /* gspi0_clk */ + <85 &gpio_native 0>, /* gspi0_miso */ + <86 &gpio_native 0>, /* gspi0_mosi (strap) */ + <87 &gpio_unused 0>, /* unused */ + <88 &gpio_unused 0>, /* unused */ + <89 &gpio_out_high 0>, /* pp3300_sd_en */ + <90 &gpio_unused 0>, /* unused */ + <91 &gpio_unused 0>, /* unused */ + <92 &gpio_unused 0>, /* unused */ + <93 &gpio_unused 0>, /* unused */ + <94 &gpio_unused 0>; /* unused */ + }; + }; + + pci { + compatible = "pci-x86"; + #address-cells = <3>; + #size-cells = <2>; + u-boot,dm-pre-reloc; + ranges = <0x02000000 0x0 0xe0000000 0xe0000000 0 0x10000000 + 0x42000000 0x0 0xd0000000 0xd0000000 0 0x10000000 + 0x01000000 0x0 0x1000 0x1000 0 0xefff>; + + northbridge@0,0 { + reg = <0x00000000 0 0 0 0>; + compatible = "intel,broadwell-northbridge"; + board-id-gpios = <&gpio_c 5 0>, <&gpio_c 4 0>, + <&gpio_c 3 0>, <&gpio_c 1 0>; + u-boot,dm-pre-reloc; + spd { + #address-cells = <1>; + #size-cells = <0>; + samsung_4 { + reg = <6>; + data = [91 20 f1 03 04 11 05 0b + 03 11 01 08 0a 00 50 01 + 78 78 90 50 90 11 50 e0 + 10 04 3c 3c 01 90 00 00 + 00 80 00 00 00 00 00 a8 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 11 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 80 ce 01 + 00 00 55 00 00 00 00 00 + 4b 34 45 38 45 33 30 34 + 45 44 2d 45 47 43 45 20 + 20 20 00 00 80 ce 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + hynix-h9ccnnnbltmlar-ntm-lpddr3-32 { + /* + * banks 8, ranks 2, rows 14, + * columns 10, density 4096 mb, x32 + */ + reg = <8>; + data = [91 20 f1 03 04 11 05 0b + 03 11 01 08 0a 00 50 01 + 78 78 90 50 90 11 50 e0 + 10 04 3c 3c 01 90 00 00 + 00 80 00 00 00 00 00 a8 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 01 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 80 ad 00 + 00 00 55 00 00 00 00 00 + 48 39 43 43 4e 4e 4e 42 + 4c 54 4d 4c 41 52 2d 4e + 54 4d 00 00 80 ad 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + samsung_8 { + reg = <10>; + data = [91 20 f1 03 04 12 05 0a + 03 11 01 08 0a 00 50 01 + 78 78 90 50 90 11 50 e0 + 10 04 3c 3c 01 90 00 00 + 00 80 00 00 00 00 00 a8 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 11 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 80 ce 01 + 00 00 55 00 00 00 00 00 + 4b 34 45 36 45 33 30 34 + 45 44 2d 45 47 43 45 20 + 20 20 00 00 80 ce 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + hynix-h9ccnnnbltmlar-ntm-lpddr3-16 { + /* + * banks 8, ranks 2, rows 14, + * columns 11, density 4096 mb, x16 + */ + reg = <12>; + data = [91 20 f1 03 04 12 05 0a + 03 11 01 08 0a 00 50 01 + 78 78 90 50 90 11 50 e0 + 10 04 3c 3c 01 90 00 00 + 00 80 00 00 00 00 00 a8 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 01 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 80 ad 00 + 00 00 55 00 00 00 00 00 + 48 39 43 43 4e 4e 4e 42 + 4c 54 4d 4c 41 52 2d 4e + 54 4d 00 00 80 ad 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + hynix-h9ccnnncltmlar-lpddr3 { + /* + * banks 8, ranks 2, rows 15, + * columns 11, density 8192 mb, x16 + */ + reg = <13>; + data = [91 20 f1 03 05 1a 05 0a + 03 11 01 08 0a 00 50 01 + 78 78 90 50 90 11 50 e0 + 90 06 3c 3c 01 90 00 00 + 00 80 00 00 00 00 00 a8 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 01 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 80 ad 00 + 00 00 55 00 00 00 00 00 + 48 39 43 43 4e 4e 4e 43 + 4c 54 4d 4c 41 52 00 00 + 00 00 00 00 80 ad 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + elpida-edfb232a1ma { + /* + * banks 8, ranks 2, rows 15, + * columns 11, density 8192 mb, x16 + */ + reg = <15>; + data = [91 20 f1 03 05 1a 05 0a + 03 11 01 08 0a 00 50 01 + 78 78 90 50 90 11 50 e0 + 90 06 3c 3c 01 90 00 00 + 00 80 00 00 00 00 00 a8 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 0f 01 02 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 02 fe 00 + 00 00 00 00 00 00 00 00 + 45 44 46 42 32 33 32 41 + 31 4d 41 2d 47 44 2d 46 + 00 00 00 00 02 fe 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00]; + }; + }; + }; + + gma@2,0 { + reg = <0x00001000 0 0 0 0>; + compatible = "intel,broadwell-igd"; + intel,dp-hotplug = <6 6 6>; + intel,port-select = <1>; /* eDP */ + intel,power-cycle-delay = <6>; + intel,power-up-delay = <2000>; + intel,power-down-delay = <500>; + intel,power-backlight-on-delay = <2000>; + intel,power-backlight-off-delay = <2000>; + intel,cpu-backlight = <0x00000200>; + intel,pch-backlight = <0x04000200>; + intel,pre-graphics-delay = <200>; + }; + + me@16,0 { + reg = <0x0000b000 0 0 0 0>; + compatible = "intel,me"; + u-boot,dm-pre-reloc; + }; + + usb_1: usb@14,0 { + reg = <0x0000a000 0 0 0 0>; + compatible = "xhci-pci"; + }; + + usb_0: usb@1d,0 { + status = "disabled"; + reg = <0x0000e800 0 0 0 0>; + compatible = "ehci-pci"; + }; + + pch@1f,0 { + reg = <0x0000f800 0 0 0 0>; + compatible = "intel,broadwell-pch"; + u-boot,dm-pre-reloc; + #address-cells = <1>; + #size-cells = <1>; + intel,pirq-routing = <0x8b 0x8a 0x8b 0x8b + 0x80 0x80 0x80 0x80>; + intel,gpi-routing = <0 0 0 0 0 0 0 2 + 1 0 0 0 0 0 0 0>; + /* Enable EC SMI source */ + intel,alt-gp-smi-enable = <0x0040>; + + /* EC-SCI is GPIO36 */ + intel,gpe0-en = <0 0x10 0 0>; + + power-enable-gpio = <&gpio_a 23 0>; + + spi: spi { + #address-cells = <1>; + #size-cells = <0>; + compatible = "intel,ich9-spi"; + spi-flash@0 { + #size-cells = <1>; + #address-cells = <1>; + reg = <0>; + compatible = "winbond,w25q64", + "spi-flash"; + memory-map = <0xff800000 0x00800000>; + rw-mrc-cache { + label = "rw-mrc-cache"; + reg = <0x003e0000 0x00010000>; + }; + }; + }; + + gpio_a: gpioa { + compatible = "intel,broadwell-gpio"; + u-boot,dm-pre-reloc; + #gpio-cells = <2>; + gpio-controller; + reg = <0 0>; + bank-name = "A"; + }; + + gpio_b: gpiob { + compatible = "intel,broadwell-gpio"; + u-boot,dm-pre-reloc; + #gpio-cells = <2>; + gpio-controller; + reg = <1 0>; + bank-name = "B"; + }; + + gpio_c: gpioc { + compatible = "intel,broadwell-gpio"; + u-boot,dm-pre-reloc; + #gpio-cells = <2>; + gpio-controller; + reg = <2 0>; + bank-name = "C"; + }; + + lpc { + compatible = "intel,broadwell-lpc"; + #address-cells = <1>; + #size-cells = <0>; + u-boot,dm-pre-reloc; + intel,gen-dec = <0x800 0xfc 0x900 0xfc>; + cros-ec@200 { + compatible = "google,cros-ec-lpc"; + reg = <0x204 1 0x200 1 0x880 0x80>; + + /* + * Describes the flash memory within + * the EC + */ + #address-cells = <1>; + #size-cells = <1>; + flash@8000000 { + reg = <0x08000000 0x20000>; + erase-value = <0xff>; + }; + }; + }; + }; + + sata@1f,2 { + compatible = "intel,wildcatpoint-ahci"; + reg = <0x0000fa00 0 0 0 0>; + u-boot,dm-pre-reloc; + intel,sata-mode = "ahci"; + intel,sata-port-map = <1>; + intel,sata-port0-gen3-tx = <0x72>; + reset-gpio = <&gpio_b 15 GPIO_ACTIVE_LOW>; + }; + + smbus: smbus@1f,3 { + compatible = "intel,ich-i2c"; + reg = <0x0000fb00 0 0 0 0>; + u-boot,dm-pre-reloc; + }; + }; + + tpm { + reg = <0xfed40000 0x5000>; + compatible = "infineon,slb9635lpc"; + }; + + microcode { + update@0 { +#include "microcode/mc0306d4_00000018.dtsi" + }; + }; + +}; diff --git a/arch/x86/dts/conga-qeval20-qa3-e3845.dts b/arch/x86/dts/conga-qeval20-qa3-e3845.dts new file mode 100644 index 0000000000..478dece1ae --- /dev/null +++ b/arch/x86/dts/conga-qeval20-qa3-e3845.dts @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> + * Copyright (C) 2016 Stefan Roese <sr@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; + +#include <dt-bindings/gpio/x86-gpio.h> +#include <dt-bindings/interrupt-router/intel-irq.h> + +/include/ "skeleton.dtsi" +/include/ "serial.dtsi" +/include/ "rtc.dtsi" +/include/ "tsc_timer.dtsi" + +/ { + model = "congatec-QEVAL20-QA3-E3845"; + compatible = "congatec,qeval20-qa3-e3845", "intel,baytrail"; + + aliases { + serial0 = &serial; + spi0 = &spi; + }; + + config { + silent_console = <0>; + }; + + pch_pinctrl { + compatible = "intel,x86-pinctrl"; + }; + + chosen { + stdout-path = "/serial"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "intel,baytrail-cpu"; + reg = <0>; + intel,apic-id = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "intel,baytrail-cpu"; + reg = <1>; + intel,apic-id = <2>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "intel,baytrail-cpu"; + reg = <2>; + intel,apic-id = <4>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "intel,baytrail-cpu"; + reg = <3>; + intel,apic-id = <6>; + }; + }; + + pci { + compatible = "intel,pci-baytrail", "pci-x86"; + #address-cells = <3>; + #size-cells = <2>; + u-boot,dm-pre-reloc; + ranges = <0x02000000 0x0 0x80000000 0x80000000 0 0x40000000 + 0x42000000 0x0 0xc0000000 0xc0000000 0 0x20000000 + 0x01000000 0x0 0x2000 0x2000 0 0xe000>; + + pch@1f,0 { + reg = <0x0000f800 0 0 0 0>; + compatible = "pci8086,0f1c", "intel,pch9"; + #address-cells = <1>; + #size-cells = <1>; + + irq-router { + compatible = "intel,irq-router"; + intel,pirq-config = "ibase"; + intel,ibase-offset = <0x50>; + intel,pirq-link = <8 8>; + intel,pirq-mask = <0xdee0>; + intel,pirq-routing = < + /* BayTrail PCI devices */ + PCI_BDF(0, 2, 0) INTA PIRQA + PCI_BDF(0, 3, 0) INTA PIRQA + PCI_BDF(0, 16, 0) INTA PIRQA + PCI_BDF(0, 17, 0) INTA PIRQA + PCI_BDF(0, 18, 0) INTA PIRQA + PCI_BDF(0, 19, 0) INTA PIRQA + PCI_BDF(0, 20, 0) INTA PIRQA + PCI_BDF(0, 21, 0) INTA PIRQA + PCI_BDF(0, 22, 0) INTA PIRQA + PCI_BDF(0, 23, 0) INTA PIRQA + PCI_BDF(0, 24, 0) INTA PIRQA + PCI_BDF(0, 24, 1) INTC PIRQC + PCI_BDF(0, 24, 2) INTD PIRQD + PCI_BDF(0, 24, 3) INTB PIRQB + PCI_BDF(0, 24, 4) INTA PIRQA + PCI_BDF(0, 24, 5) INTC PIRQC + PCI_BDF(0, 24, 6) INTD PIRQD + PCI_BDF(0, 24, 7) INTB PIRQB + PCI_BDF(0, 26, 0) INTA PIRQA + PCI_BDF(0, 27, 0) INTA PIRQA + PCI_BDF(0, 28, 0) INTA PIRQA + PCI_BDF(0, 28, 1) INTB PIRQB + PCI_BDF(0, 28, 2) INTC PIRQC + PCI_BDF(0, 28, 3) INTD PIRQD + PCI_BDF(0, 29, 0) INTA PIRQA + PCI_BDF(0, 30, 0) INTA PIRQA + PCI_BDF(0, 30, 1) INTD PIRQD + PCI_BDF(0, 30, 2) INTB PIRQB + PCI_BDF(0, 30, 3) INTC PIRQC + PCI_BDF(0, 30, 4) INTD PIRQD + PCI_BDF(0, 30, 5) INTB PIRQB + PCI_BDF(0, 31, 3) INTB PIRQB + + /* + * PCIe root ports downstream + * interrupts + */ + PCI_BDF(1, 0, 0) INTA PIRQA + PCI_BDF(1, 0, 0) INTB PIRQB + PCI_BDF(1, 0, 0) INTC PIRQC + PCI_BDF(1, 0, 0) INTD PIRQD + PCI_BDF(2, 0, 0) INTA PIRQB + PCI_BDF(2, 0, 0) INTB PIRQC + PCI_BDF(2, 0, 0) INTC PIRQD + PCI_BDF(2, 0, 0) INTD PIRQA + PCI_BDF(3, 0, 0) INTA PIRQC + PCI_BDF(3, 0, 0) INTB PIRQD + PCI_BDF(3, 0, 0) INTC PIRQA + PCI_BDF(3, 0, 0) INTD PIRQB + PCI_BDF(4, 0, 0) INTA PIRQD + PCI_BDF(4, 0, 0) INTB PIRQA + PCI_BDF(4, 0, 0) INTC PIRQB + PCI_BDF(4, 0, 0) INTD PIRQC + >; + }; + + spi: spi { + #address-cells = <1>; + #size-cells = <0>; + compatible = "intel,ich9-spi"; + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + compatible = "stmicro,n25q064a", + "spi-flash"; + memory-map = <0xff800000 0x00800000>; + rw-mrc-cache { + label = "rw-mrc-cache"; + reg = <0x006f0000 0x00010000>; + }; + }; + }; + + gpioa { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0 0x20>; + bank-name = "A"; + }; + + gpiob { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x20 0x20>; + bank-name = "B"; + }; + + gpioc { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x40 0x20>; + bank-name = "C"; + }; + + gpiod { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x60 0x20>; + bank-name = "D"; + }; + + gpioe { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0x80 0x20>; + bank-name = "E"; + }; + + gpiof { + compatible = "intel,ich6-gpio"; + u-boot,dm-pre-reloc; + reg = <0xA0 0x20>; + bank-name = "F"; + }; + }; + }; + + fsp { + compatible = "intel,baytrail-fsp"; + fsp,mrc-init-tseg-size = <0>; + fsp,mrc-init-mmio-size = <0x800>; + fsp,mrc-init-spd-addr1 = <0xa0>; + fsp,mrc-init-spd-addr2 = <0xa2>; + fsp,emmc-boot-mode = <2>; + fsp,enable-sdio; + fsp,enable-sdcard; + fsp,enable-hsuart1; + fsp,enable-spi; + fsp,enable-sata; + fsp,sata-mode = <1>; + fsp,enable-lpe; + fsp,lpss-sio-enable-pci-mode; + fsp,enable-dma0; + fsp,enable-dma1; + fsp,enable-i2c0; + fsp,enable-i2c1; + fsp,enable-i2c2; + fsp,enable-i2c3; + fsp,enable-i2c4; + fsp,enable-i2c5; + fsp,enable-i2c6; + fsp,enable-pwm0; + fsp,enable-pwm1; + fsp,igd-dvmt50-pre-alloc = <2>; + fsp,aperture-size = <2>; + fsp,gtt-size = <2>; + fsp,scc-enable-pci-mode; + fsp,os-selection = <4>; + fsp,emmc45-ddr50-enabled; + fsp,emmc45-retune-timer-value = <8>; + fsp,enable-igd; + fsp,enable-memory-down; + fsp,memory-down-params { + compatible = "intel,baytrail-fsp-mdp"; + fsp,dram-speed = <2>; /* 2=1333MHz */ + fsp,dram-type = <1>; /* 1=DDR3L */ + fsp,dimm-0-enable; + fsp,dimm-1-enable; + fsp,dimm-width = <1>; /* 1=x16, 2=x32 */ + fsp,dimm-density = <2>; /* 2=4Gbit */ + fsp,dimm-bus-width = <3>; /* 3=64bits */ + fsp,dimm-sides = <0>; /* 0=1 ranks -> 0x2b */ + + /* These following values might need a re-visit */ + fsp,dimm-tcl = <8>; + fsp,dimm-trpt-rcd = <8>; + fsp,dimm-twr = <8>; + fsp,dimm-twtr = <4>; + fsp,dimm-trrd = <6>; + fsp,dimm-trtp = <4>; + fsp,dimm-tfaw = <22>; + }; + }; + + microcode { + update@0 { +#include "microcode/m0130673322.dtsi" + }; + update@1 { +#include "microcode/m0130679901.dtsi" + }; + }; +}; diff --git a/arch/x86/dts/microcode/m7240651_0000001c.dtsi b/arch/x86/dts/microcode/m7240651_0000001c.dtsi new file mode 100644 index 0000000000..ab960177a5 --- /dev/null +++ b/arch/x86/dts/microcode/m7240651_0000001c.dtsi @@ -0,0 +1,1328 @@ +/* + * Copyright (c) <1995-2015>, Intel Corporation. + * All rights reserved. + * Redistribution. Redistribution and use in binary form, without modification, are + * permitted provided that the following conditions are met: + * .Redistributions must reproduce the above copyright notice and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * .Neither the name of Intel Corporation nor the names of its suppliers may be used + * to endorse or promote products derived from this software without specific prior + * written permission. + * .No reverse engineering, decompilation, or disassembly of this software is + * permitted. + * ."Binary form" includes any format commonly used for electronic conveyance + * which is a reversible, bit-exact translation of binary representation to ASCII or + * ISO text, for example, "uuencode." + * DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT + * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --- + * This is a device tree fragment. Use #include to add these properties to a + * node. + * + * Date: Wed Jan 7 17:15:10 CST 2015 + */ + +compatible = "intel,microcode"; +intel,header-version = <1>; +intel,update-revision = <0x1c>; +intel,date-code = <0x7032014>; +intel,processor-signature = <0x40651>; +intel,checksum = <0x4f9aa4c4>; +intel,loader-revision = <1>; +intel,processor-flags = <0x72>; + +/* The first 48-bytes are the public header which repeats the above data */ +data = < + 0x01000000 0x1c000000 0x14200307 0x51060400 + 0xc4a49a4f 0x01000000 0x72000000 0xd04f0000 + 0x00500000 0x00000000 0x00000000 0x00000000 + 0x00000000 0xa1000000 0x01000200 0x1c000000 + 0x02000000 0x31130000 0x02071420 0x31130000 + 0x01000000 0x51060400 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x36358054 0x2a09425b 0x907d339f 0xe56a8e53 + 0x877c79ee 0xe74bb340 0x4ada5820 0x1f5b6602 + 0xa30893a1 0xb7c4195b 0x5b421b4a 0xf6746a7d + 0x93416281 0x0596553a 0x0b287554 0x589d31e7 + 0xa74c6248 0x30f07a50 0x6ad9323b 0x68401630 + 0xf5d28452 0x15295b72 0x80923cf6 0x42c1b744 + 0xb3a77ce6 0xe763f1d6 0x3c1ff5cd 0xa180d141 + 0xb13139cc 0xa944a5f7 0x7df76b7f 0x5fa445fc + 0x365898f0 0x2e7e2d65 0xf3b12403 0x8c54b924 + 0xa5e7ca7b 0x79bfdedc 0x22590127 0x06c6830c + 0xb7ee2c3d 0xc8eec561 0xc699686b 0x3105503e + 0x44fa8bf0 0xf4a804b3 0x13f7e8ce 0x86c71229 + 0x4cc3e6fa 0x602929a5 0x89e3637d 0x017a25aa + 0x5450b21f 0x76c63f96 0xd39fcb5b 0xa469f358 + 0xb2bee3f6 0xb05e8ba5 0xa4ebc733 0x668bfe37 + 0x03447100 0x4e0cfdf0 0x962912aa 0x84b1559a + 0x07152000 0x3a6efbc9 0xc860ab11 0x846eff80 + 0xddab7ac3 0x7531c20f 0x348cb1b0 0x6c80ecf1 + 0x11000000 0x8e6aec93 0x0e9ee5e7 0x63a85483 + 0x70cc3265 0x6e1f946b 0x15b0efe6 0x72063a81 + 0x34a1d64b 0x2eaed2e7 0x17fd01b8 0xb10d73c6 + 0xc670afff 0x563a9699 0x48242b55 0x4f24da06 + 0x9470dbbd 0x43bd1bc4 0xdabd6685 0x2bb03087 + 0x3618fc0f 0xf583f057 0xf9b47ebc 0x900c7293 + 0x82e048b9 0xc2296a64 0xa65c78ab 0x29ded622 + 0xee3266ad 0x05c481f7 0x9f188cab 0x8848f8e9 + 0xdd1ec9df 0x9e22427c 0x2e0b3f71 0x6288ecbf + 0x761404d7 0xdfc9cd30 0x9747886a 0x5015f54d + 0x9ad0e3e6 0xf3af632b 0x9a7a43be 0x7e6abc2b + 0xac4ccd36 0x835d3a4c 0xa15be322 0x9dcf0226 + 0x166b5090 0xae4d5ead 0x6ce702fd 0xf1faec41 + 0x6a658558 0x4729daf1 0xea026e9a 0x63b58a33 + 0x3e7ade73 0x04101380 0xc56229d8 0xef888c8e + 0xfad2e07a 0x2ac82034 0x5c792e20 0x04940d3a + 0x0879333d 0x6df5c8c1 0x9a5f9d1a 0x4d4c298d + 0xf0a44f05 0xba3ceb1f 0x1ff4ca1f 0xfa8dce36 + 0x44567615 0x8dc04157 0x16e758d2 0x761fd567 + 0xf6fc6ee1 0xe97a8753 0x3f053256 0x6935fc3e + 0x382e2021 0xef7d3659 0x1bc3e873 0x94b35855 + 0x26fe0138 0xadf191a2 0x1c5753b8 0x5b84d843 + 0xde9e9a91 0x904daf5e 0xb6b66c98 0x0b632a82 + 0x9ee70409 0xb6ca0da2 0x250b4705 0x6911dc62 + 0x15cee70d 0x8afdcad4 0xfab41622 0xdf58a63b + 0x79b84df8 0xc05e3694 0x6b6cd7ff 0xd00350cf + 0xddd6b82a 0x0ce97cb8 0xc441b377 0xd1d2bde9 + 0xca3c3405 0x13780a0d 0x22da23cc 0xc9f3aebb + 0xd035bb82 0x277ed9c8 0xf0072c06 0x4367fc31 + 0x6eb8d7a5 0x4a9a39fb 0x98a20cea 0x0c6fc545 + 0xe034e39d 0x2287802b 0xee0fb9dc 0x39048886 + 0x0f52b54b 0x3fcd8c2f 0xf55411b3 0xc137b076 + 0x0d72cfc8 0x5e12539e 0xd6b15a49 0x8f0909dc + 0xe569ff90 0xfa2eb54f 0x04be7de0 0x0ece5d50 + 0x8e353099 0x953a24c7 0xb376aeac 0xed2c7023 + 0xa82bba36 0xd6a4f612 0xdfa59162 0x5197e043 + 0x06866ed8 0x73d1b8e5 0x387fcf84 0x2d732a5a + 0x57ec8dea 0xbdb45a07 0x05ea9330 0x2346dc7d + 0x7dc0ea9e 0x5e6cae0b 0x5fd87011 0xe55c5854 + 0x30594b42 0xd02e966f 0x70c19162 0x3b249ada + 0x60a41a7a 0x6b42fe07 0xefbc0f3e 0x2e5ef6e6 + 0x9866a716 0x74c9e22e 0x42d02dd4 0xc2d4b260 + 0xe90dca84 0x8214321b 0xe74708d8 0xc99fcf97 + 0x624eadab 0x34755e4c 0x3d4a47ba 0xe16f384b + 0x4abdd3b1 0x48e7f266 0x297d99ff 0xcb5e9a7f + 0x9746b708 0xe351ffd5 0x080fe8f0 0x50378abc + 0x50b1c296 0x82dd3d99 0x1aadfcb1 0xed57c439 + 0xa987788e 0xc2851395 0x7725195e 0xe64bce5e + 0xce0caad8 0xddb09dda 0x0556a6f0 0xfb33e1cb + 0x7c182dd6 0x215cd643 0x2b51ffd9 0x0f671e2c + 0x112f8694 0x6f87d52a 0x79f44703 0x9a9d7c83 + 0xb5cf88d5 0xbebc8431 0x9d20294d 0xfa3115b1 + 0x5f6060cf 0x2ec28285 0x84ec0af8 0x92097756 + 0x0e2708b0 0x47021fe6 0x82ca965b 0xd7a6f6dd + 0x9f30fda8 0xf0eb375a 0x2259c589 0x43e9d3a1 + 0x577f43c7 0xb9c36787 0x09e4ac2a 0x65eaffd3 + 0x82336701 0x4dcc6230 0x0ea73cdc 0x3f82ec72 + 0xf0fc3d01 0x0f3cea3c 0x92986f5c 0x8b230104 + 0xa9c9f5d0 0x3a36d583 0xfe4a5920 0xf72516f3 + 0x4dbfd936 0xe2109d97 0x2196ec82 0x7eda7515 + 0x07b1481e 0x763427cf 0xcec66b8f 0xf1a168c4 + 0xe24d3019 0xde4a518a 0x49eda80d 0x58a3bb89 + 0x7fe6cd4f 0x876a231b 0xc4349cbd 0x24761ec3 + 0x941b4e8d 0x485a71ca 0x13b5aa57 0x7a0901dc + 0xbc6a5361 0x226eb69a 0xacace9c3 0xc13d79f9 + 0x3e7dd201 0x0a3b78ec 0x0a7b8a7f 0x32bd5289 + 0x0079f978 0x745016ea 0x4f9b3b6a 0x45be9469 + 0xdb78b297 0x59107a2d 0x4d589a2a 0x71f90231 + 0xfdedd23d 0x8107d475 0xf7b38bbd 0xade2c969 + 0x3d452429 0x11a671f9 0x206a4cc4 0xf0dd5864 + 0x8d944e34 0x94108699 0xce16c2ff 0xac44a546 + 0x8022e1a0 0xd0bd4223 0x3a1564d2 0x10557cef + 0x4bdb2f98 0xe16180aa 0x06cbb4ee 0xbb244e1c + 0xd07a1335 0xb0e783d3 0x985b51b3 0x9c78ab34 + 0x017167c6 0xc69e173a 0x837f1b8e 0x582295bc + 0x06c58c52 0x96e40ebb 0xc7201a04 0x64175c43 + 0xe5bfffc5 0x66adad7a 0xb5497cba 0x551f9616 + 0xb073a953 0x22c3b782 0x00d30861 0x565f461e + 0xdf0c5bde 0x43c8b41d 0x8d0684dc 0xa8866b74 + 0x90b68be1 0xc3e6319c 0xdb45be3f 0xbc70cd9f + 0xbbe3f1eb 0x6aed93f2 0x5f3ccc9a 0xa7d4d8c2 + 0x0e0ff1b4 0xdeaa088f 0xe358f67f 0xe4871f57 + 0x20109153 0x6cc1ab8e 0xe643de66 0x1d3e3186 + 0xf2381609 0xcfd2ab4f 0x06884af6 0xc4f3a934 + 0x8cb92e34 0xf821a26d 0x3dadc95d 0xa45c233f + 0x29ae3af1 0x0dae8ae5 0xb0060fbb 0x07ce4601 + 0xd1ee82db 0x5eb3a5b8 0xaff1d25a 0xcdfa04c9 + 0x4d68b29c 0xc1dc4c66 0x8c05838b 0xad4b143a + 0xfbe918d8 0xe378431a 0xc7e27e08 0xe81258c4 + 0xf10507d1 0x37dc0b04 0xd6cedc24 0x0971915d + 0x17b54465 0x6dea1b32 0x5a4bc7b4 0x7119b193 + 0xa04dd0db 0xadfd8091 0x5b205c9b 0xe03b128e + 0x98e35227 0xb449ab74 0xae90803b 0x954f568e + 0xb9eb58ae 0x71b72a7c 0x59458b8d 0xb059ae4a + 0x4b72573d 0x18f32453 0x5b4f6b3f 0x69ddc2a7 + 0x3e2fcc75 0x091ed858 0xdd5d4a72 0x86353700 + 0x27fc1bfe 0xc4d8eeeb 0xddf44d9f 0x0f15d7a3 + 0x991dcfd4 0x00386677 0xee2673ba 0x1dbb99f7 + 0xa111f717 0x9634680b 0x62437316 0xfac01e1c + 0xd50676bd 0xaacf0ede 0xe1d7a34f 0xfecab518 + 0xcbd1de86 0xa426eb84 0x1bd25ae1 0x5a132262 + 0x2b611348 0x0d1635f4 0xefcdb98b 0xbcbefec0 + 0x68a28e90 0x6dec1461 0x2c7772de 0xf263e32d + 0xffca07ac 0xd267134d 0x204ecb5c 0x0c48c2b8 + 0xf1880ad4 0x04af8a4c 0xdfea69ec 0xd403d608 + 0xc2726b1d 0x7922cb45 0x57a4189c 0xd5fceeb1 + 0x8abe5b6f 0x63da5686 0xef01bd5a 0xa90f3abd + 0x48b8f807 0xdae82347 0x04748a1c 0x0dc6e20e + 0x1037d7f4 0x50dd982e 0x93532642 0x51ae7c60 + 0x5ad6d25a 0x0aae3f44 0xc1da2b21 0xe7f1ef94 + 0x3dd8d08f 0x2987f4f3 0xeb3e61aa 0xaf162753 + 0x557bf622 0x62d57d19 0x19c6bb30 0xb8a52c45 + 0x84551269 0x8ffd8fbe 0x4138c3cd 0x4fdffa1a + 0x0a7b326c 0x36e6fe1f 0x3d313ebc 0x2ff07422 + 0xabd14b1d 0x61f6f7ad 0xba5daec6 0xce7cc665 + 0xb401bad8 0x5ec17e06 0x9781d9cd 0x4d813af6 + 0xb1f33ea6 0xb77a0f3a 0x9712140b 0xfddf16bd + 0xc907de80 0x9154855b 0x17795d77 0x80990379 + 0xa2b5f0c4 0xf389d17a 0x2c8e805b 0xf8486c6e + 0x1a294bea 0xfb534124 0x7a3866d8 0x7fd8ba0f + 0x9726fd37 0xcc688de3 0xbeb96bd5 0x3c18e90f + 0xc78642fe 0x4e8f23a9 0xfebac657 0xda647c7e + 0xc6b3f0f5 0x394817f2 0xbdaa2296 0xd1adb9bf + 0xf3839d7a 0x40c9cd22 0x40d1aed0 0x1c2a84b2 + 0xde0e3519 0x83ea4c84 0xb624f803 0xd1806a2d + 0xf53472cc 0xf922e564 0xc13e4668 0x5aa22cc2 + 0x0b48fbf6 0x3435df92 0x853a14cd 0xd197a7cb + 0xeb4030ab 0xda2c86aa 0x5abb8deb 0xe77bf872 + 0x93be7405 0xe8a46779 0x18563dc4 0x0f8bf495 + 0xf1845360 0xd0bbd749 0x24ffe620 0x61ad9188 + 0x81fb37be 0xacc94ca1 0x5da13717 0xc8648c0d + 0xcdd81ef3 0x381abaae 0x9835b799 0x11e758fb + 0x2a0acde2 0x0fe63aba 0x28418753 0xf6d96bca + 0x5a86a3da 0x1e8d55df 0xea74c069 0x884dd7d2 + 0xfa4c92d7 0x04bafb9c 0xacb20e56 0xfbb38eb5 + 0x1a470fac 0xa675978b 0xbd3af904 0x7b0a8371 + 0xa2e5ecab 0x03960b7d 0x37047e44 0xf0fd199b + 0x4f90eb2a 0xab81c5b6 0xe6a6c469 0xf96b999e + 0x95533428 0x13c09787 0x480f77ab 0xb34c4102 + 0xa80a40f1 0x385db877 0xd419156c 0x188daa68 + 0xf689d54a 0x678510de 0xc83cce26 0x9d735d85 + 0x48b42341 0x11afcf0a 0x6e701d3d 0xc2fb6dcf + 0x0e9b8602 0xb5c4d48a 0x06ed18b1 0x29fcde19 + 0xe2e35d95 0xbbd34642 0x0759d520 0x1aee6392 + 0x96a8b1e3 0xf64aa62a 0xe42b65ac 0xdbf519c3 + 0xbcbd871f 0x64a2355d 0x4df65a91 0x9d8b3fa6 + 0x716f598b 0x37a689b2 0xf4f84dbf 0xdd237263 + 0xaa177b1c 0x48ff3cb7 0x3b6e0b49 0x70c79cfb + 0x85c0ddbd 0x42931bf6 0x9ccb32f6 0xc873127a + 0x92572ee1 0xda4f87c8 0xcba2c1ba 0x42df2525 + 0x6b5a7314 0xd423b148 0x9f7380bf 0x23acaca5 + 0x61b409e5 0x2c2e2ed7 0x2d3b5594 0x8a4a2761 + 0x2a72d8ba 0xcb98de9c 0xb78d7a49 0x00a5bc84 + 0x93f4dd85 0xa71757cb 0x1fa3addb 0x4ed1e934 + 0xd7203dc2 0x2528a3f3 0x06a68e68 0x7913bcec + 0x177eccf7 0x91668298 0x03c12f0a 0x0d1b89fa + 0x29f83160 0x5ca2933d 0x73edeb45 0xb538e9d5 + 0xcbe0a8b3 0x09fb71d2 0x65ec016c 0xfb8b5226 + 0x21258e35 0x04a30ede 0x6de2a03a 0x82e6bb06 + 0x871d140e 0x9241f880 0x6c91cad2 0x293f1938 + 0xb8fc261f 0x2cf7b048 0xd4b9e5a9 0x25197b75 + 0x24c87121 0x28db5c7a 0x39cda967 0xcf82e658 + 0x603477fe 0x8864f554 0x184aab4f 0x562fd6d5 + 0x3cf71faa 0xdc3a3a66 0x30b0285b 0xae2f7ccf + 0xaa086ce8 0xf9cd5e67 0x4e90546c 0xcdc9ba59 + 0xb5b630e8 0xc8f3729c 0xc2dfd2c2 0x6018ea7e + 0x6e95683e 0x65e3beca 0x3fccbe2a 0xfd4e58f5 + 0xb24a4997 0x19de4745 0x7751b723 0xe78d15f5 + 0x6873888f 0xf937aa82 0xb6b6ed45 0x7e56d48c + 0xf153a835 0xe1dddfab 0x5d776a12 0x03139774 + 0x54559692 0x13f04a88 0x078e6701 0x49e9e55c + 0xb7a0920e 0xb383aeb4 0xe1173fb3 0x2caeeac1 + 0x73a3d8f4 0x2282aa7a 0x6bd5f9bd 0x5f13344b + 0x8339c55e 0xad0695d7 0x78159348 0x09267b90 + 0xe3a09c12 0x157dfdd1 0x2ef4cfd6 0xcc4215e9 + 0x50d76d00 0x70b55dd4 0xcb87670d 0x08c0fa41 + 0x50bb4aa1 0xdb6d83e3 0x2a7c8da0 0x1e08420c + 0xc91a2399 0xd2a672c5 0xc7f7d8ed 0x45029a29 + 0x9ddcd81d 0xff3cf467 0x63009ce5 0xa50637b5 + 0x2ede7947 0x62aed401 0x1fafb3f1 0x8316fe04 + 0xd295aea6 0x06f749c0 0xf973da35 0xfe556c78 + 0xe01f5445 0x3528710b 0x0808a80b 0x0183fafb + 0x8e6543f2 0x07a2a03f 0x1a36adf1 0x47cd2210 + 0x4a193199 0xba188145 0x421cb065 0x94d0ae9e + 0x7d1c3cea 0x4a74541f 0x82c4933a 0x9fd224b6 + 0x89500178 0x2b78680a 0x567249f5 0xb222940d + 0x9ca89cf7 0x462ca6d0 0x79b2bff6 0x4f9d6387 + 0xca313485 0xce82bf7c 0x9f57b8b0 0xcaf9db91 + 0x8d1ab4a4 0x6936c06c 0xaa59840a 0xee9849a8 + 0x2d44e5b0 0x646620c1 0x9cb2661d 0xfe62a62a + 0xf530f23f 0x5eeab9b3 0x7295d528 0x84271a07 + 0xf48dad48 0x9da972b6 0xc5371843 0xd2a92d31 + 0x1e1f2f55 0x31bf76ba 0xfc86de0f 0x5b0e4b3a + 0x32717627 0x66cd0732 0x752dcd7a 0x7a2b4ca0 + 0x6e57b5be 0xd79693e6 0x761647db 0xd95d15c1 + 0x38f4efed 0x56ac1fad 0x246cdd2b 0xed296a1b + 0x1fd35031 0xdc2df3fe 0xcfc87844 0xb3fd91e2 + 0x1258f8bf 0xa045f907 0x1e47e52b 0xf9f938cc + 0x7cce7223 0x48fc9f8a 0x7aee764e 0x41dd6e6f + 0xc10c2c19 0x52aaede2 0x8c385a45 0x9e12f133 + 0x3db90d3a 0x27e28231 0x55be51d7 0x00e6368f + 0x1fd4fd3c 0x6def9a4b 0xdc93772f 0x457f3ac5 + 0x8eedc98f 0xae155751 0xf75cd60f 0xe898a7d9 + 0x7fc25a51 0x76bc5cd4 0x9b09de8b 0xb91799ff + 0xe3d3af8a 0xd147a45f 0xa9f5cf7d 0xa70ca9bb + 0xd0666030 0xe722ced8 0x25e9829b 0x1a507818 + 0x3c68043c 0x3c347881 0xeee5f72b 0x2578e4e9 + 0xd9907e3b 0x7022704e 0x37250966 0xa69e498c + 0xc91a7dfa 0xe75fca08 0x79def8ca 0x7575ed1f + 0x9c8a87c0 0x3bdfc7e4 0x902e19d1 0xd1681cae + 0x183ae48a 0xd4028c37 0xc207fabc 0xd716f9c9 + 0x7692210e 0xa55162f5 0x2a417afa 0xf760cf34 + 0x655a8c51 0xa947d18b 0x34300451 0xc86738b6 + 0x613af90e 0xaba61359 0xd4e36f5f 0x57d2a32e + 0x1d760d72 0xff0d5c4b 0x7a06a9a9 0xf3cc7635 + 0xd771a952 0x8abca0eb 0x7de39d60 0x2069cce6 + 0x2e62a5f5 0x0623c4d0 0xa2ecd9f9 0x890b4bc2 + 0x1f007c31 0x6094f199 0xe86eb4ea 0xe943af14 + 0xa25568a5 0xcd455f33 0x356397fc 0x5044a17f + 0x69f2a636 0x9ca1b4e6 0x83c302b7 0x8b1b163e + 0x5e2bf6cd 0x06219ec7 0xf3c5f611 0x91cf2805 + 0xda7fc176 0x9f699220 0xe12e12ed 0x542e44d0 + 0x3aa933f5 0x81dbddc1 0xa9e8484c 0x08ba7f51 + 0x46f25ac0 0x1a1eea19 0x2b89537a 0x76931ef8 + 0x382b0ea5 0x6897263f 0x2499d2d0 0xd6eee651 + 0x1f7bc0c4 0x3e175b1c 0xb2aacb80 0x1eb1a88b + 0x80952bdc 0xd379d2a5 0x5ed564f2 0xadb00e5e + 0x2bc146ae 0x0be7dde1 0x1685f647 0xbab0da68 + 0x14b078e9 0xc64ce2a0 0x3da71d96 0x76266660 + 0x243c5f18 0xce33dad7 0xb2397ee3 0x850fee64 + 0x60842053 0x85222609 0x96f95e16 0x0d34df66 + 0x42d77ad0 0x44394210 0xb7f0725f 0xed8963bb + 0xf198a6cb 0x49f0b0a1 0x91c10d80 0xc11643b4 + 0x9d472e20 0xe545e06e 0xdc0b2575 0xc5a73c70 + 0x5e129549 0x5fec143b 0xf4a54b6b 0x7376d098 + 0x94890946 0x6b159168 0xdbf5d559 0x2d15d2c5 + 0x62beed84 0x496ae635 0x830a8ba5 0x9485d01a + 0x18000f33 0x227d3a56 0x57a79da3 0x78fdeea8 + 0x9a4fd2b6 0x4c6c640b 0xb66dc174 0xd5ae918c + 0x08d64dad 0xb5c10d4e 0x8566cfc8 0x7fc417a6 + 0x8ea49797 0x57dc0ba6 0x88394257 0xb2243957 + 0xbd996dd2 0x514ba51e 0x9ce33543 0x9ec5575f + 0xd06a02a2 0x971925be 0x73f782e7 0x2ef325e8 + 0xd9e8ef23 0x1f8193d1 0xed943ab4 0xb6c70406 + 0xa68d5a01 0xc129e2fd 0x083ba4e4 0x88834b40 + 0x30c8fe6d 0x3e6beb66 0x8d27cd02 0x473b2a7b + 0xecf2d253 0xf3c0822d 0x426515b8 0x00e6b48c + 0xb320b7c2 0x85f26aa1 0xcdd377b3 0x1b19bb4a + 0xa66fc688 0x501c824a 0x28bfa4b6 0x2d069cc0 + 0xf76c85fb 0xf72511a4 0x7f809c21 0xacd48b6f + 0x656127d6 0x81d79e3f 0x611cff49 0xa04d85e3 + 0x2f470eba 0x1bf8e9ea 0xd493b7da 0x6cd63a57 + 0x0fbfa26b 0x4430e93e 0x79b59d39 0xacbc2656 + 0x25a9ba25 0xb87acac5 0x5f0a632f 0xfb1ecbea + 0xb18d5c43 0xfa68bbd8 0xb31f1bd4 0x604a4306 + 0x405e28ba 0x1165abed 0xb0b965e2 0xa9ad3f38 + 0x6ce908b9 0x9fa5aa6b 0x0775320b 0x2d287317 + 0x60bd9f4e 0x31cd01c7 0x626b8962 0x5f0f70ed + 0x589edf38 0x08f3ea97 0xd1fd07e7 0x621c0ecc + 0xd590dc2c 0xd514c36f 0x93788b25 0x79283a30 + 0x2c985995 0x0d40d7ee 0xf5911cc9 0x7da4569a + 0x86274827 0x5f6e7a2b 0xd8a9a6d1 0x629e34c2 + 0x624df9e2 0xcb351189 0x82ea6097 0x9f8d2cdd + 0x61cfb400 0x9d6c3b45 0xff19366c 0x79690958 + 0x6ed4ddf3 0x4b33e4e9 0x653f0b2f 0x83a591cc + 0xe1722cc4 0x856120d8 0x7b00c52c 0xf7674979 + 0x597c1d35 0x036883c1 0x4d08ef96 0xa0c8f2f7 + 0xf384e306 0x7300e5f4 0x83839ef9 0x20ad1d51 + 0x7e1f18a3 0x2098dd76 0xe6b65690 0x9bef2e5e + 0xb38d701b 0x2045cd61 0xa954fb21 0xc4dff68d + 0xc28b7666 0xbb9a4184 0xaafc7eb5 0x45456e66 + 0x67db7454 0x9a05253e 0x28122206 0x625d39a7 + 0x04592faa 0xdba42c40 0x9a3a4993 0xd3d6c2bf + 0x3c40982a 0x6431b67f 0x0ea7cedf 0x2b0ac9f7 + 0x9ea5d4d6 0xe791d5f0 0xaadd0723 0xe4fb9c43 + 0xc8201ba8 0xe1932301 0x0ce03a52 0x3496246e + 0xf137bc12 0x26a323c5 0x390958c7 0x483106ab + 0x6b86c7e1 0x7a66b1c9 0x241fad2f 0x952d52ee + 0x482ee92f 0x5c9a3c81 0xaf6a220b 0xe4009d00 + 0x2df7ab42 0x3b13f244 0x0a8e893e 0xf212a578 + 0x725e101c 0x8a1b9508 0xde355a1e 0x56e8280e + 0x5a98cf5d 0xb327ff63 0x534a0d5c 0x96da187c + 0x39ddcd11 0xc70595b2 0x46244641 0xf4e2f10e + 0x62859f24 0x6d6678d1 0x34aa8dd9 0x4fc01a56 + 0x6a64e34d 0xe17ed716 0x249c6ac3 0xd47d1fde + 0xaf3e638a 0x676ee17a 0x650eaff1 0x887e2825 + 0x4568605c 0xdafd3994 0xaa38516f 0xbfc697df + 0xe99c9a63 0xbd891af4 0x0a50dbce 0xcf7ef33c + 0x7ad7b95b 0x3e85b834 0x29149b84 0x82366554 + 0xd30e026a 0x111ab9f3 0xd5ef6860 0x9a28b5dd + 0x694cb602 0x97bab21e 0x476ec4a6 0xcf1e4c2a + 0xb41217a7 0x99548940 0xf1fc374f 0xed9cbc5c + 0xccb162c6 0x705553ac 0xa16ced27 0xd8a37721 + 0x2be25c67 0x955c09e3 0xd6528a68 0xe6fcf157 + 0x872eab32 0xb835c145 0xe05948f6 0x21d9cdbb + 0xf575408b 0x22ec501b 0x3c1ea4bb 0x4b7f3078 + 0x45efafca 0x4b5a64c8 0x8c3b74eb 0xd9876f32 + 0x808744e4 0xb486a14d 0xe91fe265 0x94e39478 + 0xb730a4f9 0xbc086921 0xe16b8506 0xaa6deeaa + 0x90d5c750 0x8e446d6e 0x9d67c80c 0x29625ab5 + 0x1953ad92 0x9394ad85 0x753b1636 0x1f844fa8 + 0x85af68a4 0x16867851 0x5ccc7e43 0x0afe0376 + 0x34e74ec9 0x1d5110e6 0x57261d88 0x812f0a62 + 0xd7c4b769 0xb2f30a49 0xc89e0d57 0x391f54ed + 0xc43f5790 0x9dcbe811 0x1e81afad 0x16b6d454 + 0xf5cefcd5 0x707e3d0b 0x5958fe66 0xba383ccb + 0x707291e2 0xc65a0a2f 0x747f9560 0x51db16a6 + 0x89462d49 0x438ead4e 0x6313b326 0x9472a519 + 0x6628fc48 0x1f95d3e4 0x06ac59d9 0x0149755d + 0x946d99fd 0x64e8be5a 0x7c56dd78 0x1ebe2d9a + 0x3544c47a 0xb02e58a7 0x1fcb9959 0x2ec10642 + 0x0a665998 0x4f198f24 0x82c4daa4 0x4cada36b + 0x3cbc1c5f 0xb4b58554 0xbe3040ca 0xa5e0f771 + 0xd6f10bdb 0xe8b8c75b 0x785128b2 0x2dba4eaa + 0xc22a1a20 0x57ca1766 0x950cebad 0x7164255a + 0x1ca5bfc5 0x32f879fd 0x633415c3 0x8671a86a + 0x97d1231e 0xb42eb0c7 0xdc7548dd 0x76073c5c + 0xffa2b6d9 0xccf1826a 0x13e25e0a 0x81f0d572 + 0x0872ee56 0xd7b0b7b7 0x6622b528 0x2eafee6d + 0x3fbde14f 0x60f14acd 0x10e6313b 0x2fd9c84b + 0xe95358d7 0x2a66a304 0xde93d150 0x0b903a36 + 0x66fe047b 0x5e2e0799 0xb75faa2d 0x01b31a01 + 0xb86a5e56 0x7688a8bf 0xaddd7310 0xd842a919 + 0x4257a4b5 0xd367ce43 0x90670d88 0x3d68096d + 0xb328ba2b 0xd3b5309e 0xb594e0a5 0x541ffbbf + 0xcf6628da 0xd2610017 0x9dbd7b08 0x147714e9 + 0xad5af7cc 0x14ed8059 0x0e4eb5b9 0xcecf70b3 + 0x797c47d4 0x2e9a5629 0xffc303ee 0x92adb18d + 0x38fc626b 0x28d90f28 0xe406e993 0xf786fcc0 + 0xb089ea66 0x2b298595 0xb57836ee 0x40e97ef5 + 0x7ee51371 0xeaa0c668 0x09abf083 0x827d5dab + 0x286d7caa 0x3b8abe7f 0x9207ecab 0xbcfd1c10 + 0xf32c77a0 0xb479119b 0x8fb80b72 0x04007837 + 0xdaea926c 0x0a45f5fa 0x898f4cfd 0xd6570824 + 0xe94c1364 0x85dcbdba 0xa836cc7c 0x82fbb300 + 0x8f0194d4 0xcc4e0c4b 0xecde1ec5 0x64fe947e + 0x491a07e8 0xf2fa274e 0x753bcc2a 0xf8acefdd + 0x8c08c75a 0xff4ea493 0x85d2950b 0xf0dde553 + 0xc81b49bd 0x61798da1 0x582f0e73 0xac899e79 + 0x37131e86 0x6fb7b794 0xa93e9bb2 0x543a052b + 0x4f7545d7 0x547c593e 0x1ae5b597 0x7e8921dd + 0xaf7738cb 0x1724cf35 0x38666b1d 0x45bed06d + 0xb02db85a 0xeba54624 0x6e82a670 0x4eb126e3 + 0x008c65a3 0xf89fc360 0x7554657c 0xd0fda40c + 0xcdb31573 0x3236ef91 0x35cc7d91 0x46dadb32 + 0x42385866 0xc7e9b5b5 0x421fbb07 0x98c6e1b7 + 0x74640f5b 0xa1164da1 0x2396c6f7 0xfc070c24 + 0xd1c9da6e 0x45d528cb 0xe7a1bfdb 0xfcccb5e5 + 0x331842c1 0x5e52068c 0x700df099 0x6a75f141 + 0xb16d4b01 0x9d4c0e0b 0x6294a17b 0xf2bdd77e + 0x8e0b4658 0x4864cea6 0x902b1b1a 0x40da3ae4 + 0xb21ec43f 0xb6aa1fcb 0x98c59e25 0x05d121f2 + 0x12df7d44 0x6ea64f78 0xbffb9638 0x56bd07d6 + 0x47951e5d 0xdcff5b07 0x00e039fd 0xf367d08c + 0x7f0391dc 0xf44bd71c 0x6e55aefd 0x6868e5e9 + 0x29e2ab06 0x0dafec72 0x465dd93d 0x92506550 + 0xb4e86b8c 0xa0c68258 0xe602ca48 0xed2bd7dd + 0xc0bbef81 0x759ab650 0x20429eb2 0x67b92b3b + 0x740860b8 0xa89f4d7e 0x9811aff4 0xc5090423 + 0xdeeaed1d 0x5694b80e 0x301bab2d 0x4e760e67 + 0x5f93041b 0xf922237c 0x7e9a501a 0xff974f99 + 0x70c1493c 0x7ade6d44 0x51924c7e 0x093c6617 + 0xcdc8d641 0xafce8c92 0x36df5db6 0x92ec9f36 + 0x44bcd121 0x3c693f2d 0xfdda3f10 0x5e1af637 + 0xc457c9d9 0x5c083fd8 0x3fb0ae4f 0xed10d011 + 0xccdd403e 0xe337f655 0x5cc5a0e7 0x83909519 + 0x9df20176 0x11082484 0x6b346426 0x22b3ffa0 + 0xf80f36cb 0x4e51aa9f 0x402f66c7 0x3fcba7c2 + 0x70718156 0x02c30feb 0xe4fab120 0x36ef1781 + 0xc7020c16 0x05843068 0x67a5b55e 0xb3ff0e87 + 0x56d90cdb 0x195ffa41 0x13c72463 0xaf6d776e + 0x94d7e951 0x1a68d757 0x68a9f6d6 0x987530e7 + 0x2bac05ae 0xfd4c2953 0x0637fadb 0x43978dac + 0xdbd6bf6f 0x3aa74e3f 0x9b05c191 0xd5206ef6 + 0x8e98538f 0xe3a0c4a0 0x289b963d 0xf20ffa7b + 0xd9212ce9 0x597553e9 0xf7629b53 0x5bd93bc3 + 0xbfa8e24d 0x8d64da85 0xc1480167 0xe5a7f74a + 0xf39af6c8 0x64ba7c27 0x8a4416c3 0xbef8e773 + 0x4533701b 0xe076c393 0x44fd530f 0xbaf32be6 + 0x91c38e6f 0xa92c973c 0xc6a31c09 0x601e3e71 + 0x7ab14696 0x3a738d1c 0x3a526f47 0x36428cf7 + 0x2d42a935 0x43c23b8a 0xa19717ed 0xde0f9dc3 + 0xe2e0d482 0xa61a571a 0x3b0737cb 0x83b5e88c + 0x1bb2460e 0xfcede58b 0x264126c3 0x8508e56d + 0x0b145431 0x4f5203eb 0x86739042 0xbcac8ef2 + 0x2ebdbad5 0xbdd600b1 0xa3769f70 0x2b64b113 + 0x510456d4 0xc2148b14 0x30d1b7f2 0x5baf8b95 + 0x5fb82f72 0xd7c4d86a 0x3c5550a0 0xed2d9573 + 0xc9cfa502 0xaf78d702 0xd76fd581 0xee87d5ab + 0xd70d8e22 0xc89a29bb 0x2611a169 0xed6b51cc + 0x274b1ae2 0xb48c88fa 0x793b6258 0x008e406b + 0xcfab29f6 0x38e3d921 0x01740270 0x6e70096a + 0xc7aefdc3 0xd80c45e6 0x2e44366b 0xe1c90426 + 0xc042cf77 0x22051e9b 0x540f3479 0x9f7f35bf + 0x5d1de0a7 0xd98a991e 0x55ec626b 0xd9ffc82c + 0xf16272ca 0xc09f7529 0x3fe2b13f 0x8b7e7b40 + 0x387b5d39 0x0dcbc77f 0xd5cd4849 0xd1d11cac + 0x3a81db4b 0x918f714b 0xfd36aaac 0x7d99c7a7 + 0xf17a14cd 0xd23a9976 0x779011d7 0x26697b23 + 0x22fc8d6a 0x46ecf917 0x7c91000b 0xc166ae9a + 0xca4ba72d 0x2a48862f 0x261e726b 0xd7531502 + 0x78bf5417 0x25389b56 0x61e5005c 0xc8033170 + 0x4e00e018 0x708cf6d4 0xf04cb696 0xcb3d0f20 + 0xb046e418 0x209d248f 0xded466bb 0x016d7f8a + 0x7959b87a 0xf784eaad 0x8d54961d 0x9b752161 + 0xe0119966 0xd7ab91db 0x11dbc152 0x3e47581d + 0x890d8481 0x6f3b72b4 0xbe486e2a 0x22eb5779 + 0xfde7df8b 0xf322e970 0xc002f7aa 0xcf26edfe + 0x4402cce3 0xb2c50725 0x039fb57b 0xb4763a8c + 0xda8833a0 0x7c622b2f 0x0196f2e8 0xcfdfa120 + 0x1d84466c 0x617f4810 0xa554e9b9 0x4a65213e + 0xa8e6447a 0xdd454003 0x2a191f8f 0xe90888e7 + 0x0cbb1e1e 0xc0014e3e 0xf8fa5110 0x14bf1e9f + 0x1f58cc1d 0x401eb5de 0xd389fc93 0x2e5c4138 + 0x9f8e7c4d 0x2a114200 0xa8480323 0x5568fe3a + 0x29aaa87f 0xe00d1ef1 0x6529b380 0xbb25daab + 0xd88cab32 0x6b81bb11 0x408a8c3f 0x03969bb9 + 0xf4e12ee9 0xe9ef423d 0x523ef85c 0xfea8abe9 + 0xd03d0d5b 0xd7f52b16 0x50924023 0x9f5ddf21 + 0x077c2d28 0x2d2de8ba 0xfb344a20 0xdacbc873 + 0x58d4b24a 0xc5c93dd3 0x2fd90431 0x5fade189 + 0xbf1eecd4 0x80e8e6ec 0xc34cc52c 0xaa7909f5 + 0x2b29ab08 0xa11b7aba 0xef0c9042 0x0ee739b2 + 0x528b4375 0xa469ce9f 0x99c5ea7a 0xada779c4 + 0x13b5f495 0xed8fada4 0x821438e1 0x0ef7b4fd + 0x0dadddb7 0xf7b0126e 0x0122aa70 0xe85c0393 + 0x43d987fe 0xcb807e6a 0x3d640cbe 0xb455abd3 + 0x16fb3f4d 0x186eff0d 0xed772eee 0x4b24f0a3 + 0xc7740459 0x47558d79 0x6aa1ff59 0x5b5edf38 + 0xc458a17a 0x82541e75 0x9ea3ebaa 0x2112cd2c + 0x3545f49b 0xfbf236f9 0x69dea934 0x5c17ca33 + 0x5e858504 0x01aac0c6 0x11ef33f6 0x8854c6f6 + 0x34ebd4cf 0x512345e7 0x2d3ce674 0x3037b243 + 0xba71633e 0xd416e216 0x5d98bd1b 0x169c473d + 0x27048f4e 0x70293e28 0x1e0f2644 0x8ee3457c + 0x7af12b70 0x0691621e 0xfc31ebfe 0x3b3c5afe + 0x1ac47d72 0xe9e14234 0x35773bfd 0xd8efb085 + 0xe9130b25 0xff66974a 0x0784ce95 0xea94b8bf + 0x5e19a597 0x734a65a6 0x90aa4fec 0x0ae1650b + 0xc98c92fb 0x6b454b49 0x0422fae7 0x0b3d3795 + 0x2d974bd2 0xc1da7d45 0x277b747a 0x4beb18f3 + 0x5da6e424 0x9a74f0a3 0xe8ab17e7 0xbd808cba + 0x30be527d 0x4e3cc912 0xca176f12 0x24de5a90 + 0x301bfd72 0x4809f186 0x3ad505de 0xe1d9c240 + 0x94c2293d 0xe1e00502 0x4f182e78 0x969de138 + 0x05153ec2 0x7beea3b0 0x94fc29a6 0x1dbea067 + 0xb34c9cf1 0xf03b6643 0x9fbed0c2 0x3b64555f + 0xfeb2cedb 0xc84fd85d 0xfb48aa5d 0xb435f74c + 0x1da90905 0xf4ff49f3 0xaef0b05e 0x372cc04b + 0xf275770a 0x83412ce8 0xcc8ef6f3 0x3cf61a91 + 0x8f825847 0x0ff84984 0x1911424c 0x5f7f6414 + 0x9d2b9e77 0x441aabe4 0x20a99f43 0x5bb7d84b + 0x01004cf9 0x794d2def 0xc2426978 0x3aee4a5e + 0x9023ce81 0xba06c7bf 0x86331c72 0x97ed04e4 + 0x9daa4d57 0xd80d4732 0xef0ce33d 0x7bb634f3 + 0x86b8c306 0x9117c5bc 0xd2493a34 0xf705284c + 0x081ecd4b 0x594cbab5 0xf1d18aa3 0x5f7065b2 + 0xc9f54c16 0x4ce69755 0xd673c1db 0xbac9cd34 + 0x149eebbc 0x3219fac8 0x90898889 0x048a66d8 + 0x09d33838 0xc77eb874 0x636af1ab 0x3911f3f2 + 0xb081e3f6 0x50b6cf1d 0x1b062c31 0x15921863 + 0x644d3d11 0xca8d9c94 0x1593d492 0x3d862993 + 0x4092dd00 0x8728936a 0x0c621f31 0x97c7e076 + 0x68672d98 0x27a3c786 0xc536e4c6 0x628aa80f + 0x7e3042b1 0xba983931 0x9233976f 0xd3e1feee + 0x454ddaec 0x7cbabe45 0x626f5680 0x86d62425 + 0x3747293e 0x7bbe541c 0x19a3ab12 0xf2505a05 + 0x2c2bdf16 0xf197013f 0x36d8c917 0x8469a25a + 0x954a3585 0x567d06c1 0x31190459 0xa9cf6769 + 0xee56d8ec 0xb2a25d79 0x4e9522be 0x5c53b346 + 0x2498f858 0xb53a56b6 0xbf1dd8b5 0x07cae034 + 0x77b831cf 0x56d025d2 0x23941f5d 0x41c94630 + 0x84c8f997 0x497a3f80 0x6f4851da 0xe11e1e22 + 0xa9cb39da 0x32573406 0xd2dd24fe 0x097b2c23 + 0x10fcf14b 0x76108b3c 0x791e9ac5 0x1588e2ee + 0xd76e51fb 0xed83c5d9 0x0921d0a3 0xe6ed2241 + 0x18b12102 0xcec961f1 0x018ceb98 0x9055f200 + 0xb8c139b2 0x0c6a8ea2 0x80113e98 0x168051ac + 0x275327b2 0x0c2a2b86 0x8fdabceb 0xb96339fb + 0xac03247a 0x8d016f69 0x52905c25 0xd43063f6 + 0x03859acb 0xb0b82819 0x662639c4 0x9df25b87 + 0x905c8493 0x2f82ced3 0xdc4ca8af 0x3be8fe34 + 0xca04372e 0x2bdcd311 0x21c4b1e7 0xa2026acf + 0x956cc1b9 0xcb12e0a8 0x210edfc1 0x4003fe60 + 0x7615d091 0x4ad2db99 0x2b78dac3 0x45a28b4b + 0xfaa2c78e 0x93f8851b 0xe819f776 0x301ba8a5 + 0xe8c611f4 0xb57a86a0 0x22ba84d0 0xe534ca91 + 0x353d9a80 0xba5eb547 0x767b440d 0xa0aa0501 + 0x27e91c51 0xce8f3edb 0xec1f28df 0x1d51c345 + 0x3501e714 0x535cac3a 0x414330de 0x798b4e98 + 0x49a151fb 0x5dbb2a08 0x8812c1d7 0x6dbd0647 + 0x229fe96d 0xf8880ecf 0x9fb56948 0xa42812fb + 0xb3bbeaea 0x7e301c94 0x3fcb5808 0xb7aab8b0 + 0x2cfc9729 0xc62adc08 0x9f8aeeda 0x79289a00 + 0xee2792e0 0x27fa60e7 0x3b758c80 0x2a5a64ed + 0x9452b3e7 0xd5a65d87 0xf5d0a791 0xf97be2a7 + 0x7191d713 0x8deac7dd 0xf8191187 0x052f7805 + 0xdadb6713 0x83cfab61 0x2b96f96b 0x7ac15508 + 0x5cb6d698 0xc13b3e8b 0xc0079fcd 0xddac8a5a + 0xe451de56 0x71713f63 0xbc068461 0x7936ad26 + 0xb9d78db7 0x111a6e9d 0x97038690 0x0586772f + 0xbf2baea3 0x7a09ab77 0xe9749e25 0x7c69d049 + 0xb4e8eb34 0x7032f28a 0xa558cbe0 0xa01328f4 + 0x080db42a 0x5b8fc345 0xfc6807e4 0x817e0aa0 + 0xcb2216cb 0xbb2b9376 0x03bd0b38 0x148e884e + 0x958f7457 0xa2a9b3eb 0xb08a2615 0x09a10c5f + 0xfbd37e19 0xc7cb96a3 0xd34445dd 0x87adbc72 + 0xc5f1ac9b 0x86259ac2 0x8a13ffaf 0x7e18ae06 + 0xa1b809fa 0x2cd861ce 0x6d70cfe1 0xc886b3b4 + 0x2fa9e7d1 0x746fcfd8 0x6cc1048e 0x3a90bcbe + 0xe128aa6d 0x17926080 0x32016f56 0xda94ed0c + 0x7e9378c5 0x5042aae9 0xa3dc912b 0x1623e997 + 0xc4b94ccd 0x307ae247 0x03247b7c 0x6c6d0108 + 0xd410be0b 0xb623d11e 0x9663c906 0x6bbfa5f8 + 0xc27210ad 0xc41c94ba 0x05e237e0 0xa668f183 + 0xec6065ec 0x26ca40fa 0x94fc5cd6 0x6a82dc1b + 0x1dc1d96b 0x7c005bff 0xf8366526 0x73c2cefd + 0xe528f243 0x14dfb490 0x15f80a8a 0x394b095b + 0x72775581 0xb7ea99a2 0x44f5c936 0x410bac20 + 0x1f5db398 0x117825a9 0x379c138b 0x602ee0ab + 0x2d3c0109 0x1f438f92 0xdf27eddf 0xb02293f3 + 0xfb38fa7a 0xa7a4e06b 0xdd9fe2d1 0x20e40a7d + 0x227ca003 0x17b74fcd 0x2cea8dba 0x6769ebe5 + 0xc949674c 0x8eaf9112 0xff8b63ab 0x4035bc30 + 0xc0aa874d 0x7ac4058b 0x21d0ef5e 0xf62af154 + 0x8b05b4c2 0x43c74cf3 0x842dc532 0x3c8a3e5f + 0x95d801bd 0xb5a83d10 0xadc1a8a7 0x670c26da + 0x4bf0507e 0x035e8bfb 0x46b1e6cc 0x7fc4c2d3 + 0xed22a187 0x5135992b 0x7d1371fd 0xc953608a + 0xeaa25648 0xc31bc809 0x8603bc0b 0xc8ad6d91 + 0x5fc84456 0x99b9e025 0xe829948f 0x5cbc3eee + 0xae8f59b7 0x3ec97bd3 0x3abce245 0x228bd681 + 0xb2b1ada9 0xead6e411 0xabd2e254 0x7e45dbdc + 0x8a50ec7e 0x24298ff0 0xf09d0f1d 0xb74d4551 + 0xac207b87 0x9f5a762b 0xd668e27c 0xe7e54ebc + 0x498656cf 0x1e5db0ff 0x52f38a55 0x7d2204ca + 0xf31dee2d 0x3959e778 0x69a7cd84 0xc37f5e23 + 0xc1bd4c03 0x7ee89c4e 0xbafcbb55 0x129ce932 + 0xaf91dc8d 0xe00eb9ab 0x8b019109 0x10b1a3cd + 0x687e815c 0xfdab2350 0x0a2b819c 0x07eb579b + 0xdb8287a1 0x061cf9a0 0x7205de9b 0x14fdb63b + 0x1e11e597 0xfa83c8d5 0x4a512886 0xfc901e00 + 0xb84bbaf3 0xc4014e8e 0x59fd5ace 0xcb6bb236 + 0xc97d40b7 0x879ff4d5 0x32ff0c8a 0x50535056 + 0xcadc03b3 0x93e571c9 0xe11ea5a4 0x1b815fd2 + 0xe138f177 0x3c5a8235 0x0d8e5621 0xa02662cc + 0xc9d27418 0xa4764016 0xa725d85f 0x4abdc3cb + 0xb3b67e4c 0x18352967 0x888cc657 0xb5803d8d + 0xa10faffa 0x43db196e 0x9e3af00f 0x448c0fc9 + 0x534a5eea 0xdf1276f5 0x38391564 0x3a3b84ea + 0x9e582ea3 0x633c5686 0x968e2d0f 0xf58ccfa9 + 0x51912f0c 0x757d93c0 0x6a552350 0xbc694325 + 0x6ae6c819 0xaf36dcd6 0xbcb68d50 0xf92263a5 + 0x1e7cd73d 0x6b7d1301 0xac441acf 0x5212030e + 0x0b44cdd2 0x56efc50f 0x8b3f7559 0x2356f8ba + 0xc36deb85 0xd0e9aee5 0xa6c60c4e 0xb0bd681e + 0xc2ee0867 0xf98bf1c1 0x12c63c40 0xe5782e98 + 0xb9901ad4 0xccba733f 0x045c4cf1 0xcb5b1e42 + 0xaaea0f67 0x8506733f 0x72c05b72 0x47a556b7 + 0x53e6c4b4 0xcf837da7 0x97b0767a 0x0d21fc30 + 0xac2c8d22 0x7941ee41 0xdc223433 0xee048605 + 0x32851301 0x4a8a02bf 0xb78b9b0e 0xbcef4f9e + 0xf8a69e38 0x9d96bb7b 0x48a60e1a 0x8c37a194 + 0x85f03df6 0xf96558ce 0x209de5cd 0x394f3931 + 0xf4ea2e34 0x5a772269 0xd0a90533 0x70da5e0d + 0xe6f946c1 0xb68e5b5c 0x3a5aeca8 0x8b1c27f7 + 0xa34ba11d 0x00964212 0x1e02f951 0x6bc0646a + 0x7651beb7 0x1ea01e5c 0x63a727c5 0xe9b419d3 + 0x39b5df2f 0xb50a4f30 0xa6e303ab 0xb39edb7b + 0x23486564 0xd3773590 0x07028db7 0x43150998 + 0x6ad0a086 0xd3c108b9 0x6ed00042 0xd3811dae + 0xa7174bf8 0x863b87fd 0xc7f973d5 0xaad2bb3c + 0x3cb5a2dc 0x753a86e4 0x3b6271d6 0x85edb580 + 0x3222df02 0xa402cb55 0xb34dd452 0xe974bb39 + 0xaf075f9b 0x4efc599b 0xb56033e0 0x7c725abe + 0x5f5b9862 0x9b4d05f4 0xdd89f80e 0x0d7aa2ec + 0x4a9a5ed7 0x1e127584 0x5b9e9642 0x7b38fc92 + 0xea3e5bac 0x23cfaebe 0x15341ce4 0x0a556611 + 0x85728991 0xeb785d51 0x1bb099b9 0x01e67032 + 0x9f922599 0x9d657a29 0xd842759a 0x26c3e32f + 0x88494390 0xb39ec049 0x3394958d 0x90511d85 + 0x5fae55b3 0x70b505c9 0x6687f4de 0x0fef1a3e + 0xb0972ddd 0xc4884dda 0x84394eaf 0x9a37d103 + 0x8d0fd419 0x2f4c109c 0x11fe6969 0xa374e237 + 0xc5a571f9 0x156bad26 0xd03e7f9f 0x581c80b8 + 0xe58c0bc9 0x8fde060e 0xd5518ab3 0x1e740775 + 0xff22caa5 0xbdc7a492 0xbf82cffa 0xa87e23c8 + 0xe35e4b27 0x5f730aa0 0x8da1b0e4 0xa8f15416 + 0x812fd749 0xc4147542 0xbcaf27d5 0x9981822b + 0x84e8bcf2 0x4465aca3 0xe1ee2fef 0x00a0358a + 0x2e5df776 0x563c9f8e 0xdd906c83 0xaa1a17e2 + 0x23bd41d7 0x6bfe1dba 0xf4a329e9 0xfc3c1993 + 0x460278a1 0x81bc8ee0 0x8ea301f2 0x8033a3ea + 0xcb7bada0 0xbf1d5fc5 0x373dad3c 0xc2f63e34 + 0x583dba2a 0x2a35ee8a 0x2800004d 0xd7a8ab40 + 0x1e6b529e 0x87a50cea 0x0d31b543 0xb180a106 + 0xd1f47e4c 0x84e80915 0x4c43e7bf 0x73a055d3 + 0xa3fc6dc4 0xec84ae87 0xe5547254 0xcb6be707 + 0xcc4eb60a 0xd8381b9d 0x7a030d2c 0x1be55721 + 0x7bd3f24f 0xce9d7482 0x5e03d45e 0x8790ba10 + 0x321eaffc 0xe0844c90 0xa4a17f8f 0xe01b527c + 0x66816314 0x3e3690e1 0xb1c30644 0x954ccf70 + 0x5f6d6ffd 0xc6823aef 0x73d98a2b 0x838f8ba1 + 0x7212df98 0x6326fcdd 0x74d3b3cc 0x17042050 + 0xcde9e524 0x29db5b8e 0x0cd3e7f0 0x65234e04 + 0x2c75a35a 0xfa032996 0x806d0908 0x1950cc6c + 0x76920d98 0xaaa006ab 0xea4d182c 0x51d030d0 + 0x6c282cfa 0x5267eec5 0x75c7010d 0x9d0bdc08 + 0x920ee8e0 0x5aaec307 0xf383fd0a 0x135e5ac7 + 0xbf4aaa43 0xe373c54f 0xf9f3fed5 0xd0be25c9 + 0x5a54cd3d 0x4aa0389c 0xc29665e7 0x777a4158 + 0x5b57415d 0xe6a422fe 0xdb6611f0 0x6f54ecfd + 0x28c28df6 0xd6f2988d 0x1789dfb9 0x27df77cb + 0x1fa26ed9 0xae0fd39a 0xf94c4bc1 0x65d042d0 + 0x88a5f87e 0x570b29e1 0xdc1330b6 0x06378e2d + 0x20b0b8c7 0xff319526 0x17b042f5 0xbbadff3b + 0xb8ef0bf1 0xa64ad683 0x6bdb49f2 0x760ab25c + 0xb417b977 0x8d92b175 0x6b65f954 0x220b8d37 + 0xa6badd1f 0x89e2df4f 0x0aa7d325 0x40a42a74 + 0xc0dad423 0x6e7bf809 0xac4aae6c 0xd9ddcb69 + 0x3cc5e5da 0x744133b3 0xec86b2b9 0x162f0ad0 + 0x15045bf8 0x460d946d 0xa506c28d 0xfbab3479 + 0x154692ff 0x3073b90a 0x92384f53 0xb33fcc5c + 0x0abc1983 0x532daae6 0x8091960c 0x36f5cea8 + 0x0c94471d 0x816b6d8f 0x5d3c99ea 0x80cb627b + 0xa4afd8d3 0x3a9ff641 0x30c90501 0xaea17610 + 0x3b511cfc 0x23304b93 0xb9ed3860 0x54785451 + 0xdb12df70 0x4e06805f 0xa849b8a3 0xe42a6f81 + 0x76c9bf2f 0xfa8c77f9 0x6bfdfc0d 0x8a2bad5c + 0x4e49ba6d 0xcbd6b2bc 0x3b181174 0xb4099608 + 0x0d420811 0x13ff2ffb 0x7d9be0ff 0x3f554804 + 0xc84fb966 0xaa6276e5 0x7645e15a 0x3e7ac11a + 0xa0f60ada 0x238badca 0x255e2d2c 0xf238b8b5 + 0x73739f1c 0x981daa16 0xc4fe7449 0x267af5a8 + 0xc6b8cb45 0xa34b380a 0xa6a5c773 0xe301778b + 0xdc4ee904 0x28af3bb2 0x68a42bd7 0x197656bd + 0x24d44d79 0x1d9d5f71 0xcaa55a1d 0xc2b5d1e6 + 0xf94f45c4 0x7c1ca577 0xcca26345 0x47a8e42d + 0x2dbe9f75 0x48295826 0x857c1f7e 0x45f9022c + 0x9d8fb30c 0xb9c10c73 0x53e98143 0x0cb261ac + 0xecb4ecba 0xaeaf602d 0xc8ddc19e 0xcad6221e + 0xdacdb56d 0xd0729d38 0x26019f2f 0x4988623e + 0x4d0eb009 0x771bce37 0x327e5ea4 0x6bce2ef3 + 0x415629f1 0x8c3e7f4b 0xbe2af3b0 0x8ee07f14 + 0xe95f1dd2 0x6517ad5d 0x694f9468 0xfdb0a74c + 0x99edc6de 0xe5d60fce 0x3e05765a 0x41d652ff + 0x034aa17b 0x8eace912 0xfb7aa25d 0xe38b179a + 0xdbc48363 0x727299c4 0xf59fbd14 0xfdd4549a + 0xe12a1562 0x9cf616ad 0x56a0fc70 0x5878fedf + 0x7006ed17 0x67b6a794 0x46690825 0x34df8caf + 0x89e9e2f0 0x9bfac410 0xb9e96bcc 0x1913d4a7 + 0x4a505351 0x44c2605e 0x45ba2b5e 0xa437684f + 0x1c781405 0xc6be10fb 0x409bfe58 0x63b0013f + 0xa90be299 0xb4089f7a 0x3fef5391 0x7a63871c + 0x0fca68c7 0x915b006a 0x48c61ed8 0xf8b462a5 + 0x29de81f1 0x9d001eed 0xc839aa5c 0x6818083f + 0xe9bfa7b1 0xb1be11d9 0x89bd0960 0x9bc6a6b6 + 0x17b8b5c2 0x7115c557 0xd9e0c250 0x4d24a387 + 0x95f37451 0x338692e3 0x647f5c6b 0xc4e89994 + 0x5f552dc4 0x89079a11 0x460cbfdf 0xd2652f47 + 0xdd57ff68 0x0dd2ffe4 0x0ba525aa 0x31e2e225 + 0xc1fba237 0xba2447c1 0xb9f554ee 0xd9387061 + 0x543951a5 0xb6089667 0xcb1d01b5 0xec66da11 + 0x5639c0f9 0x373d0ef4 0x53581b5d 0xc24ba72a + 0x0e2ccdd6 0x5e7f9e6f 0xe0201507 0x8aee59b8 + 0x08c35a68 0x93ae2c80 0x1a32a759 0xeb853473 + 0x7e63ba72 0x187c7db4 0x6f698b12 0xecbfced2 + 0x0d8d15c7 0x074406b4 0x9ddd36e5 0x099082e9 + 0xe4aadf97 0x01723d8c 0x59066199 0x538271d4 + 0x7af12596 0xf2b7fa43 0x0eca2126 0xf6194325 + 0xb3e2025a 0x2ff5c9dd 0x9a77e22f 0x52086e4f + 0xb7e8bd4d 0x90c72c53 0x2bd8928c 0x8ca5855d + 0x9f898915 0x173e43e9 0x9bbe3d12 0x384ef9ef + 0x452319b7 0xbc040cd1 0x703c650a 0xcb65da27 + 0x66034c72 0x70d56086 0xb12f756f 0x25492f7a + 0x1c593374 0x3a579886 0xf082d898 0xf8dc037a + 0xd45eda9b 0xb1a2a2a2 0xc5f03ee4 0x56d21d3b + 0xb2b26117 0xdc561e6e 0x8898d15d 0x5de5daa2 + 0x0bee75c5 0xac3b4578 0xf3a75d7b 0x4e0f8347 + 0xe0eb24fd 0xa9469170 0x35ce0c5c 0x74219b52 + 0x8bd0c8f7 0xb5cd84dd 0x98bac3e1 0x9aba924b + 0x19e3ee9e 0x0d3bf514 0x2b2fd328 0x47c6084b + 0xd7fe9866 0x8767b2cd 0xabb314b3 0xdefc6e37 + 0x31555b34 0x687feab0 0x1583ef18 0x70c92033 + 0xe6bf756c 0xf765f10f 0xb7b87e32 0x79f605be + 0x4c42e879 0xff8afa4d 0x36ad291a 0x7cffb06d + 0x7ec9d636 0xdcdf2dec 0xd3a8432e 0x7eb77583 + 0xeed53dbd 0xa178b9d4 0x85680ccb 0x15cbb728 + 0x65d25cb1 0x1e5f1cc6 0x32d7add3 0x0d2c8941 + 0xb7049d9a 0x6acde4b3 0x90b17afb 0x481b6151 + 0xa6f981e1 0xcd466bac 0xd28da681 0x0e1fe5ad + 0x8c15eaaf 0x82ca6cc6 0xd94f3a84 0x0abacfcb + 0xd8846fa0 0xb026ac09 0xfc947434 0x9380a723 + 0x9cab000a 0x575030fc 0x10634e19 0xc0d9ce62 + 0x0b3b8303 0x4359fd8a 0xf5dcc1bb 0x3e977300 + 0x681eacdb 0xb6c71eb7 0x71091ed9 0x644e7dcc + 0x9477da03 0x6c63c913 0xe0092603 0x3795d8bc + 0xe0a1eb1e 0xd2b70b75 0xc88a33b7 0x6a7f7f94 + 0xb3b1a895 0x4a32fdcd 0xda58e610 0xff3d2e17 + 0xa7d8b293 0x0e656a23 0xae671b1f 0xbb054522 + 0x7e41733a 0x83f84dd7 0xa5336e2a 0xf854b99f + 0x6695add6 0xc9a1df2d 0x6d5812ab 0x0ba66d9c + 0xbabaddc3 0x48b7416d 0x16bfa9ab 0xc84c227c + 0xc0e5394e 0x59e5eb4a 0xeed26fc2 0x6e1a811f + 0xf7e53bb7 0xd3104000 0xdec8eefc 0x7ff6b7bf + 0xd2677945 0x53b2a359 0xddb118ec 0xcfe0e0cd + 0xdccd7b6d 0xb3d71b5d 0xcef8518b 0x519be194 + 0xa58d8183 0x7f8cfea8 0xc8ac18f1 0x3511d390 + 0x4c6c5774 0xe9c5c986 0xdd8c2ac7 0xe6d7a259 + 0x6eb90668 0x77542650 0xba343d0a 0x994d8541 + 0x3d3ef48c 0xd6ae1127 0x9bc381e8 0x0a83a841 + 0xc56b846b 0xd2b05a9d 0xe79b14f2 0xf51d0a36 + 0x95791126 0x7baab402 0x6b0d95e1 0x1a275ddb + 0x39f53b9f 0x2ce8ff88 0xc01aeac4 0xec535e5f + 0x3827d4aa 0xf62e268c 0x6a069baf 0x1c2d87f0 + 0x11f08c17 0xdfab8da1 0x4962cb4a 0x0faff7ae + 0x0a73e186 0x0ce79d52 0xa35ad594 0x3ca44ced + 0xad35d996 0x4e90e6d1 0x68af0ac7 0xa866a665 + 0xba5420fe 0x440f36c8 0xf3a05cd1 0x42d925d2 + 0x355a4d16 0x3cbe6190 0xeb0a3ad9 0xb0283dbe + 0x6e6a87cf 0x4f34ee24 0xfdf93d66 0x18d77c49 + 0xced0c573 0x0e546aaf 0x557b511e 0x083c4cb6 + 0x4a0def79 0x84f303a1 0xd8d6896d 0x4f489dba + 0xbb77a0e7 0x137b4b37 0x4d4ec3f6 0x67d69767 + 0xca495a59 0x67d64a7e 0x5508c504 0x607a8c61 + 0x85894432 0x679a59f6 0x5e0bbbcd 0x3020ab69 + 0x5f82d53c 0x5edc4ca9 0x0de12d4d 0x6110948d + 0x19b32565 0x786f8a39 0x1deea5da 0x3c76c5a8 + 0xcdecd0c6 0xd4a2da42 0x195a1946 0x7636ebad + 0xc8350338 0x8e58aa25 0xc1880b7a 0xcc3400cb + 0x16d9390b 0x4ebb864a 0x66c56674 0xbe6d21c1 + 0xa539b9e0 0x607fb2c0 0xe9c0fa11 0xfc48169d + 0x7fbe8e6d 0x2a604636 0x0af25fd7 0x6bacb48e + 0xa1b6bc06 0xfa14057c 0xc7cdcc76 0x25fccb3e + 0x2c7a471d 0x7a167c84 0xa095f155 0xe70827e6 + 0x0352b136 0x09324b83 0xad3202ff 0x62962ee7 + 0x7003fd3d 0x1165f945 0x0cefca06 0x79d61619 + 0xce7d5448 0xaac42add 0x0b9f6b05 0x56ce5e02 + 0xb0ceac2b 0xe123be16 0x91b3225a 0xb270c869 + 0xe012966e 0xff796d3f 0xf342882c 0xed63fe08 + 0xac7ef0ee 0x9e2bfb86 0xa30080f2 0xc2f43b42 + 0x605fac6d 0x588d43a3 0x0f5f1c22 0x396b7482 + 0x8a2dd0e4 0x8422c5e1 0xb08657fc 0x931ed316 + 0xcc30d191 0x7fc6e305 0x271885d3 0xc88212fe + 0x8e8e3d7c 0xc1792b10 0x41a5303d 0xb690f3b0 + 0xc39ee3b6 0x96cede0b 0xc1382ec6 0x49267fc7 + 0x022738df 0xd1701f67 0x65d8aa02 0x8885b81f + 0x729a6eab 0xa9534a99 0x861d0933 0x277d9600 + 0x9a5a05ab 0xb9eb0bd1 0xad6760e0 0x72c2ef2e + 0x634f7b50 0xc26d77a6 0xe9b154d3 0xde3b33f5 + 0x213d64dc 0x6c243758 0x0bb289f7 0x217b8136 + 0xdc0095dd 0x188eeec7 0xb6ce8c31 0xf91074ce + 0x645ec280 0xb80a25fb 0xa86e0d99 0xe6286d6a + 0x5dd6b6f2 0x5243d686 0xb3f9634a 0x65d3fdaa + 0x5e868aa4 0x3039d124 0xbb8088a3 0x96870f96 + 0xc61274d3 0x35c317d3 0x05c58b64 0x7672442f + 0x02c72a1b 0xac258d31 0x86a8288f 0x071e12b4 + 0x9d038beb 0xf6fbbb2b 0x6ed7b5f3 0xc4f9fcdc + 0xf5ef49eb 0xfc5ebeae 0x43e4c4ff 0x5acc83d3 + 0xfc96ffed 0x90651cc8 0x18221103 0xe6a3f1d8 + 0xdf47a32a 0xb27b35bb 0x232aae32 0xd00be32b + 0x0849ab0f 0x0958ca28 0x91b6ca97 0xf984b343 + 0xaffa535d 0x123e77e7 0xf7e209ea 0x59174d7e + 0x68ee5e17 0xa8795f95 0x59a2199a 0x18091ea0 + 0x67b706d5 0x2bd6edb9 0x35cc965f 0xe0f9a923 + 0x495f7a6c 0xacad111d 0xa0c8ab69 0x300e7abb + 0x7383b901 0x5f389445 0x59abce2d 0x680369f0 + 0x8548c495 0x572ec514 0x1dd71294 0xafb52e6b + 0x9ec9177e 0xdbac3f44 0x1a12a547 0xd6251878 + 0xcf3f77a7 0xa571c92b 0xbd4d31ad 0x2a791fda + 0xb57bbe1c 0xdf3dc778 0xe68410fb 0xbff32015 + 0x7249e6cb 0xf57ff26a 0x9c49fa78 0x0988e756 + 0x2df657f1 0x56d59cd7 0x740d63b3 0xf193e10f + 0x155f523a 0x700736b8 0xeb79fcb9 0x65c419c1 + 0xea6c4e9c 0xe0d26e79 0x3abfa57e 0x9260c9bb + 0xbb2aab7f 0xbb14db51 0x89b26f39 0x7ffeb19b + 0x87c58bb7 0x4a821ea1 0xd0c77e0e 0x88a85e93 + 0x6e8131cd 0x19adffe6 0xfaeef425 0x99de85cd + 0xf29cdfc4 0xa42b5f32 0x742fe930 0xafaf2832 + 0x192fb41d 0x0c463d86 0x9815f049 0x2ec74d39 + 0x02814cf3 0xa724f39b 0x48e3ba20 0x96efa18b + 0xe1c9837f 0xa2d372c8 0x6b5abfa2 0x6595ce3a + 0xebcfc193 0xd07bda68 0xc3fc6ff6 0xf35a617c + 0xf6454a9d 0x887a767a 0xc6631983 0x7f01a27d + 0x817c6ab2 0xa34c3f76 0xd8f47831 0xc2e565fa + 0x93d3fcec 0x88c3e6fb 0x9d1743a3 0x833c8fd5 + 0x0fa12d7e 0x186d6353 0x74af27ed 0x9262576c + 0xb4904c37 0xe97ff03b 0x179051a6 0xe76ae3e7 + 0x0c0ccc23 0xb51bf186 0x68ecfae6 0xd7826d06 + 0x57f7740f 0x9352b1f4 0x2194c680 0x20edef77 + 0xf8fa25bd 0x00e30bd2 0x8164d603 0x74690299 + 0xb6748634 0x7e0945e7 0x8f94c14c 0x8ab50139 + 0x7bbe4cba 0x321184c7 0xf6eeea60 0x74ee1aa2 + 0x13271f47 0x29c7ed4e 0x320a94eb 0xd74cdb9e + 0xd617b96a 0x80333a88 0xb1f1da0c 0xb227c317 + 0xb2be59ed 0x8aa71728 0x37b60fad 0x0456f28a + 0xc9e07783 0xc6fc5381 0x5b6fd04d 0xf86034c5 + 0xf8d11346 0x2bcb1e88 0x00586361 0x25f66131 + 0x7942512a 0x5994973a 0x2e6f8180 0x792b3aa4 + 0xd3570bbe 0xb980c388 0x6bbac1d6 0xc2c958bb + 0x9a471500 0xbb4dd7a2 0x172aa1f6 0x1169027f + 0x6e2c7b1b 0xa2762787 0xd7a129d2 0xd48aa1a8 + 0xe4cad492 0x50ce92ed 0x0d94c689 0x6e132b53 + 0x13a9d0d1 0xb9c28b76 0xa1197ca0 0xb44a11d0 + 0x81fb3038 0xa41dfbee 0xff252eb8 0x6ce0df62 + 0xd71c1715 0x96770f3d 0x179b7736 0x6cac1bec + 0xc7cf8ea0 0x0f39262a 0xe51dbe11 0x34988c38 + 0xd56f75bb 0x0aefa928 0xaf5fc582 0x736d1002 + 0xbc07bacf 0x7fe2dadf 0xdea78951 0xb8d00e1c + 0xb2a2ccb3 0xb54a0519 0x7595a849 0x56b6ee9a + 0x389b1bc3 0xf4444795 0xf62bc28f 0x199ff3d8 + 0x4d82bdb7 0x8ebbfafa 0xb4d9e422 0x6b420bdb + 0x03191e66 0x3047f236 0x233de214 0xcdc8877d + 0x236cb79e 0x0fb239e5 0x1320ae46 0x6696a576 + 0xc26025bb 0x8bb094c5 0x85cc50b0 0xfa907646 + 0x8c9551a9 0xaa21fa1f 0x610dc418 0x6c4b4339 + 0x0179104b 0x0ee75662 0x11223470 0x46aa52c5 + 0x64d190da 0x0d21a99c 0x3de332aa 0x003d1e21 + 0xc7169b4e 0xfa926f18 0xa4c095fd 0xa9b19bea + 0xd388621d 0x7c27d919 0x2fa0e38e 0x99724539 + 0xd6a58e6b 0xf82acceb 0x07b11f3f 0x983e3ef2 + 0xe50bc4a1 0x519d45c9 0x3cf98ca4 0xf9d27135 + 0x5abf4d7c 0xc25777f7 0x4a1ed0aa 0xd9b90d97 + 0x1d1cc73a 0x79d1fa78 0x3cbbb84f 0x38a9bb70 + 0x6fe5ed83 0x71e96161 0x0d837c8d 0x0dad9b82 + 0xe6b8210a 0x63743d39 0xab76202c 0xe5d04da7 + 0x606e3794 0x3105d51c 0x726cef1a 0xa7689844 + 0x4ff57f92 0xf74852bd 0x53776432 0x0c18aaba + 0x6451a4a2 0xd79fdeda 0xe93e4f6e 0x199fb742 + 0x9a96c23f 0x00507b8d 0x7d64fb14 0x7e0ec4b1 + 0x6bb78854 0x026e1374 0xe2401e35 0x50f60683 + 0x095eb3bd 0xb2a061e5 0x5639f5c0 0x0e59d4d8 + 0x07a00a41 0xfb6255c8 0x6a51bc29 0xcbf61ff4 + 0xeca26823 0xd3848606 0xffafa5df 0xdf589c9b + 0xdbb81eec 0x421b063a 0x0a89e58b 0x660e9041 + 0x975328aa 0x9cea68a0 0xbedc93a1 0x2efb7f9f + 0x9751aa80 0xc7d173e4 0xbccc1b80 0x45ef35c4 + 0xcb762a58 0x21382865 0x52154f8d 0xb0a46943 + 0xb658fb6f 0x9f70699d 0x219d98c4 0xffb51a3c + 0xdb12adeb 0x670933ac 0x9ff86734 0x5c7e4f26 + 0xad69be04 0xd874314b 0x2b244637 0xb7d599c2 + 0x01a634c1 0x94529f7a 0x19d3ec4a 0x34421551 + 0x80715a0a 0xb2bdefad 0x37f13bfb 0xad39c855 + 0x81e03a33 0xb83972ac 0x7754de96 0x1625563c + 0xf7439a81 0x643ba9f0 0xcfc91790 0xbe960ad9 + 0x6bbd6a95 0x2dd914be 0x1db5f0bf 0xbd4fbc54 + 0x3c2d587b 0x18ad16d0 0xe992eab9 0x25184a40 + 0xc448ad96 0x600bc301 0x4a761bb7 0x2230e8c5 + 0xdfa3d66b 0xed52d799 0x6001a5db 0x76aee68a + 0xb9344897 0x85f9437b 0x7a333059 0xa3a87d63 + 0x463b8d49 0x895954ff 0xbf4b6e63 0x68bdf536 + 0xe8e022ab 0x9537a15b 0xbb928b33 0x1e20fd8b + 0x7553cfd7 0x6b2cf5e0 0xa01c8127 0x9f0d42a1 + 0x9e4c596e 0xa805f5c5 0x9dc7ff08 0x41c920ed + 0x018142b9 0x524c4b06 0x2fdbaa5e 0x1f55f01a + 0x78aff861 0xf412e1f5 0x634be8b9 0xb35b72cf + 0x652e2aa0 0xfaab7bc0 0x00eb703f 0x69f5d306 + 0x254128c8 0x239861a6 0xb4449272 0xa6fa0fd2 + 0x46f25a02 0x9cf57227 0x740a13ed 0x07d81a8d + 0x66342f60 0x0235484c 0x7c5184a9 0x849788af + 0x6c071f18 0x4edbe7c2 0xd1ddbe21 0x1f74304f + 0x799756f7 0xbf746dec 0x8f876f8c 0x498e0528 + 0xfae16a3b 0xa4546101 0xaf3e9bd8 0x86338967 + 0x02c84849 0x2d9f3572 0x7c6e58bd 0x58e5adef + 0xd7ebf566 0x5639904d 0x3a57c7b7 0xf067bf98 + 0xb5a6c6a9 0x152d6531 0x908f1ac7 0x6dc67c74 + 0xd483a80c 0x855b7ab4 0x417a3f7b 0x54526563 + 0xfb6fb861 0x370bc285 0x44acf8e2 0x3e08232a + 0x3dc911e6 0xb7362054 0x31a78230 0x01fec5db + 0xe23fa0d7 0x021435fb 0x7b5121aa 0xb4558a95 + 0xb2208b86 0x87fff4a9 0x8ee2fdaa 0xf7170909 + 0x8658fc90 0x7cc2ff89 0xc0465813 0xffff5751 + 0xe0e6dfad 0x5fe00d42 0x92f14f4c 0x8f2d1b50 + 0x6b320beb 0xed5dab57 0xe88610db 0xe9fb76ab + 0xf0910917 0xf3e9bf3d 0x0949c21c 0xea3a2edb + 0x32a955ff 0xc5a59efb 0x5babd7b5 0x5f6cf0d1 + 0x720a191f 0x2d79a1ba 0x788d6ce9 0xe6585b57 + 0xbf41d206 0xbbc34488 0xb216304e 0x0e4dfd32 + 0xcd9df645 0x76c91a2d 0x4a1623ca 0x20d0f0eb + 0x505fb401 0x3bbe87e3 0x59138510 0xa032e5b0 + 0x4c4bd1fd 0xa19bc006 0x57faf36f 0x24aeb37b + 0x9dfe2e39 0xa3918228 0x12ed3f76 0x1adc7868 + 0x52d54b6f 0x3b3bb87e 0x04217038 0x2ccca010 + 0x3dfe7d32 0x515a26ab 0x061deda8 0x8750ec31 + 0xda25aedb 0x63630030 0xfc45346b 0x21aba1c5 + 0xb4904998 0x749d2e6b 0x0f1909d3 0x132a6862 + 0x754eabce 0xa55c0618 0x5cd98176 0xb96737ff + 0xd8b05179 0x9c8e3da4 0x97f2e2e3 0xb61429ff + 0xbbdc939c 0x4aec61d9 0x4faf0e89 0x4f6cd1f4 + 0x10b5f482 0xd99b668c 0xe7ec4f14 0xd74e81f6 + 0xcd33f1de 0xd0f94d9d 0xc810f619 0xd8fbcc7e + 0xb6280ea7 0x0d382991 0xdbc5b115 0x6fd8f0f0 + 0xf55341e7 0x91e21353 0x17f9dc9b 0x37a575b7 + 0x6fc85088 0x6d0a7996 0x9827385e 0x4f623d15 + 0xc91112bf 0x80a59bf3 0xa9bb9866 0x16380b9d + 0xf8b5bfbc 0x054d65d4 0x6aae53ae 0xb25c9b40 + 0x5dcbbd8f 0x6ff8db9e 0x15158a2f 0xcdc10109 + 0x25e42ded 0x2fdea368 0xb7be3ccc 0x7b34ca65 + 0x97ad2729 0xcd32c218 0xedf23b2a 0x46693400 + 0xb84e3dca 0x40e671d5 0x5e0f7ce7 0xa94b7ae6 + 0xbe35d5d1 0x760d210b 0x9fd65609 0x6e36daa5 + 0xe56a2654 0x441641f5 0x673013fe 0xa65f7ff6 + 0x06500fa9 0x0b822091 0xa1d6851e 0x0b7a49df + 0x5c2b0f82 0x7ee49fd1 0xb4e85e7a 0x9d999c6f + 0x530758ac 0xd40876bc 0xe68ec478 0x4a84397e + 0x295fdf21 0xfacf7dea 0x509fe59c 0x7bc7ae8b + 0xe7e858f7 0x68050a7e 0xc88e0538 0x7da5cd9b + 0x41f64aff 0xc4b52ce6 0x0f2da494 0x74c60878 + 0x263f4e91 0xc6087f9c 0xe3fab089 0x2e15f961 + 0x03494236 0xa92f04da 0x99c18104 0x8612d706 + 0x50acaea4 0xd499bdc0 0x34cbe2a6 0xc9cfe5c4 + 0x487ccac6 0x756461b7 0xdd495436 0xadd5d979 + 0x9a9b3224 0x5b09e765 0x6d333eaa 0x1f9e7406 + 0x3c96a504 0x8fcd07e5 0x0c0578d2 0xcdce6073 + 0xa4bf4a2c 0x7d2f610b 0x8b1055b6 0x35b73bdb + 0x80b8fdc0 0xc5e5b334 0x932b95c2 0xa73a9bc9 + 0x391d05e7 0x7b4f34e3 0xe51f2431 0xe58e958c + 0x87cce4dd 0xf3300188 0xb3d528fd 0x2b855db1 + 0x4acbd783 0xc06ff27b 0x363c9e2d 0xf30403ab + 0x0b935c43 0x0dc7ebc5 0x316b4108 0xebdfac89 + 0x3ee8c912 0x8c9605aa 0xd8675a9e 0x481bac3b + 0xabc0325d 0xa8090333 0xaade994b 0x35cd1e8f + 0x98d7d180 0x8fbf0767 0x0c56bb25 0x285b14b9 + 0x2e3be447 0xb675ea9d 0x306ffe95 0xb767b19f + 0xdd02ef7a 0xd1b3f4ab 0x419dd098 0x49190362 + 0xd2a5d71e 0x88859a3a 0x618af917 0x06c10947 + 0x4362174f 0x98162338 0x09113545 0x25fea1e1 + 0x97c50ea2 0x1c222ff8 0xc142bda2 0x12004e77 + 0x5b0a3ac3 0x39a45dd0 0xa24ad6df 0xf48e542f + 0x9599ab56 0x6f857a2b 0x27cc03d4 0x69d4cc80 + 0x8c86b444 0xbd9d2f64 0xc0b8ea5c 0x636606a4 + 0x01d28968 0x3f6bdf13 0xe1673b48 0xcb14f95a + 0xc22b6c13 0x9abd6d91 0xb8ad10b5 0x424014e2 + 0x6b2057b6 0x40fb28d5 0xcf9edea5 0xd5582ab7 + 0xd2df8dff 0x2d19d5f5 0x6451bdab 0xad3872f1 + 0xdf1734da 0x71726dc7 0x8c13b61e 0x46d87bfb + 0xf0c4b8a3 0xe1b6913e 0x12eae34d 0xbfbe9831 + 0xe57174e5 0x72ff6118 0xd30e2c10 0xfdd503b3 + 0x7b305e6e 0xe1e1905d 0x5e0a883e 0x29cd08c3 + 0x25527858 0x9af006a7 0xf4d55499 0xdb5ed0b2 + 0x23826a83 0x949220f0 0x3dff8dca 0x0e843e66 + 0xf7d7a997 0xc3787919 0x43696ab9 0x66976447 + 0x859f3c9f 0x6ced7846 0xf7a459d3 0x8466d520 + 0xcef6f6cc 0x06d820a4 0x82bf0302 0x1511d393 + 0x08f0e990 0xeb88a7ca 0x8c552ada 0x55ed0dbe + 0xc8b687c9 0xd6161b47 0x9b87ec3c 0x76e64faf + 0x9bfe9a55 0x9ab7e327 0xef4ae25b 0x7257088b + 0x7776149e 0x8acce20d 0xf832a123 0xc516ee31 + 0xca07c786 0x2459b81d 0x140e0c0d 0x367db85d + 0x3bffab4c 0x2078946d 0xc934f40f 0x0d76c5c5 + 0x8d44882a 0xc6b1f0cd 0x546cd8b3 0x9c74ae80 + 0x980a4149 0xf8ca5118 0xa0e15063 0x97124c50 + 0x5286a809 0x736150f3 0xa48956b8 0x7695795a + 0xe02c0cbf 0x8a53d5f0 0xf714f228 0xdfb54386 + 0x7d9c8120 0xb72bcd71 0x5776b2bd 0xd44edd72 + 0xc24545c8 0xeeea089a 0xce6f3216 0xc242432d + 0x9c8c00ab 0xeb4c2000 0xefc993a9 0x76c0c3b7 + 0x34852175 0x9db64eb1 0xcfcc18f7 0x675e1eb8 + 0x53fc55ff 0xadbb0b97 0x451a2fda 0x3d336f25 + 0xa8f5f01f 0xa561b62e 0x90ef3703 0x6e65e157 + 0xee079b4a 0x2e4ff5ac 0xeaab1797 0x4c71bbb5 + 0xa6f79217 0xe8d7cd81 0x0624a162 0xf7991f76 + 0x973a2a07 0x3ed92be2 0x03ec00f1 0x91a7e0c8 + 0xf7451136 0x4752e136 0x6a38e92e 0x0d9e431d + 0xf78d8bea 0xe1fb4a67 0xa15d3be3 0x68086923 + 0x8c2ad79f 0x7a3cddf7 0xe8f075ed 0x31308caf + 0xfffb8a19 0xba0e0192 0x06e94877 0xcc4488dd + 0xf6ffaf00 0xc16ad424 0xf095df90 0xa42a0cdd + 0xaa0421ce 0x20463ee2 0x15922b14 0x86819d76 + 0xa821c16e 0x469c30dd 0x9bb8b07f 0xdcaf1680 + 0x548970f3 0xbe393dce 0x50664752 0x3070829e + 0x297aa70c 0x1ea3f37d 0x1597ca4f 0xa2d49ac5 + 0x2d4426bb 0xce3c8a3f 0xa39ee081 0x87969194 + 0x316a8c95 0x82895006 0xab8d9832 0xe96c273a + 0x57f10802 0xd36783cf 0xbfa33b16 0x07961517 + 0x81d565f2 0x544bd8aa 0x5d36a963 0xdc00af80 + 0x01807f25 0x0dfd2d77 0xf1ec7e36 0x96aaa6da + 0x105c6a0f 0x1df5acd5 0xe5c27278 0xf68b7079 + 0x2b650fc4 0xcac72bf6 0x962a9522 0xfacdff5c + 0x3f5ab5fa 0xb95652cf 0x020ede27 0x4795ceda + 0xcf78db92 0x205e00fa 0x5381c93e 0xe5c34716 + 0x7a3986e3 0x10059b03 0xee2f2cb0 0xb9ec2804 + 0xff9f887e 0xf98b9dc3 0xdccdfaad 0x0bcaf264 + 0x83cc2aa8 0x6492cfba 0xd5286e65 0x7b4b0153 + 0x3c594a01 0x087dae43 0x0f665e4e 0x428f546b + 0x8c291cbd 0xb06ce4fa 0x913398b2 0x9ec46154 + 0x21bed0c4 0x619594ae 0x44d419e7 0x7488e8b9 + 0x04b619ae 0x4636dfc8 0x60ab5413 0xab587fe4 + 0xac7a824f 0x8c4c3483 0xe03a23c0 0xecc61821 + 0x97f5e393 0x81025b1b 0x0f48dc0d 0xb6177cfb + 0x4e8dad6f 0x9191ae1d 0x218ed709 0xee75ca53 + 0x4df8c4b9 0xce540161 0x513f117f 0xff2e3333 + 0xedf68b2e 0x020f969a 0xf47e28f4 0x998b4b49 + 0xe51fd08b 0xb7a3bae0 0xff90cd39 0xf87efd12 + 0xdd8716f4 0x35f5bf62 0x361b8b7e 0xb714da0b + 0xce9f177d 0x1d16af9f 0x6646b103 0xb0ec56b3 + 0x0d192b3f 0x43668438 0x2a44a3b9 0x6af8564c + 0x7a85ad05 0x959c7854 0x3372d43a 0xbc442739 + 0x757d7f0b 0x56eda728 0x5a4fa815 0xc6df021b + 0x94f08dbc 0x88096982 0x8508397a 0xa9e4bba1 + 0x53d371dc 0xe0f0266d 0xd50d6686 0x1c8a2423 + 0x0c7a51b1 0x9fd0d8d9 0x3460fc63 0x8ce7b265 + 0xf03c63f9 0xbb9edb97 0xfdaa9a7b 0xd8281335 + 0xb8139d8c 0xb0a2b778 0x0bf660fd 0x94978ef9 + 0xab719015 0x4c65c585 0x2dbfb09f 0x01e570f8 + 0x57494752 0xc73cf0e2 0xc96c969f 0xa3720a39 + 0x69b09650 0x5e5616d6 0xcfc498cc 0xed8b9984 + 0xef3762e7 0xab56bea7 0x0409058a 0x6dcded2e + 0x54703a03 0xcdeea095 0x7a4552c9 0xff570e49 + 0x4f41930a 0x6bbee57e 0xd637b631 0x0e9da0a4 + 0xd02ecd00 0x5e6b109a 0x01356db5 0x31a1fef4 + 0x92665fa0 0x45d7a450 0x25fbae53 0x0d2ba9ef + 0x813e5181 0xccb91b2d 0x1e4f4d66 0xa414439a + 0x1d64caea 0x34d11aa9 0x7a74f4ad 0xd37c3b14 + 0xce81ad7d 0x04e6f9f5 0x123b8579 0x1e9d7869 + 0x5e8e4230 0xc54e32ca 0xe578cc0f 0xca6f3ec5 + 0xb3b7354d 0x3e729731 0xd3a67568 0xb037e3d4 + 0xcf106830 0x435366eb 0x34f3877a 0x768eb454 + 0x3996cabc 0xf75e0197 0xfb9f48f7 0x56751351 + 0x3ae2003a 0x0aa20116 0xe94261a5 0x86663fcf + 0x98d211e0 0xce0c0412 0xa97053c3 0x1c4d33f0 + 0x2c5dadf3 0xf9908b0e 0xc460e9a3 0x4c369445 + 0xab7fc6b2 0xeae2fdb9 0xc077c114 0xd1d137ff + 0x87f2af9c 0xec7ff39f 0xe0d0dd65 0x4056afa3 + 0xaf148be5 0xf211eb20 0x51eebb92 0x1f0708ea + 0x677930a7 0x7948c640 0x828a04cd 0x55cb7bc6 + 0xd0616d79 0x7c44642f 0x30fe3b36 0x2dcc7194 + 0xdcabc9ff 0x51aed4ad 0x0145f869 0xd82d0fa0 + 0x9206ba41 0x28e26a08 0x7a229c39 0xb97b85f5 + 0xe607c481 0x25d289fb 0xda5b13be 0x5ec82846 + 0x1e5b0716 0xff9b4ebd 0xf46cd510 0xad24837b + 0x62c67b10 0xc46a5a14 0xe23c84bb 0x37eeb2c3 + 0xdd6fe432 0x21fffbeb 0xef79f8f7 0xf80c12e9 + 0x2b69a807 0xf97831db 0x6eb12a25 0xae8aa1a1 + 0x8c97fd5f 0xd00a930c 0x5cabc5b9 0x4af113f3 + 0xdf3a260a 0xe55c9e4a 0x81bf0c20 0x330e7651 + 0x9bfc46dc 0xf87440bc 0xfe187c45 0x672eb3a4 + 0xf7de1d6b 0x6031a4c7 0x55a50174 0xaff41f12 + 0x26ca70d5 0x824b8396 0x958c7022 0x38a73ce0 + 0x491cbe0d 0x32ddda3d 0xff33cc7c 0x611090e6 + 0xdc0fd6b1 0xad2ea10d 0x3079126b 0xa6b7a1a8 + 0xb0d17458 0xa810c54d 0xcadacc10 0xd71f26c6 + 0x0d641f9a 0x74fb3008 0x042ed388 0x97cb23a4 + 0x46c147ab 0xaaa22296 0x63b85c64 0xdf1de1de + 0xbd426ea8 0x02feabf9 0x4e880ae9 0xe3c9f7d8 + 0xace7000e 0x0bd04b97 0x6faee32a 0x689676b3 + 0x654aaf12 0xb9fc6881 0x097034d2 0x98cbb76e + 0x18ed7d3d 0x5b9092a9 0x5b9b63cc 0x5c430f07 + 0x575297d7 0x3db1149a 0x283ca860 0x49d6753f + 0x93024c8e 0x22e0fa36 0xc6506f01 0x061aa1d1 + 0xec5a5637 0xf4fd13f0 0x063c3f57 0x3c254361 + 0x9daa76e4 0x68f1b15f 0x377794db 0x591dcb8e + 0xec348007 0xba29de34 0x485e35a6 0xdd00d226 + 0xa41fd95e 0xc29e20fe 0x960e7ff0 0xcdde850c + 0xaa2648dc 0x0e16d6bc 0x67e7fa58 0xb74cbc3a + 0x6c76533e 0xe6654f45 0x2b026d8e 0x87b719cd + 0xaf550f29 0x642dd61f 0x5626cd8a 0x729832ca + 0x9a5209ec 0x7ca92e53 0x92967783 0x8b683023 + 0x7230e183 0x2b46a17d 0x72ed9b62 0x8c3153d5 + 0x104b27a5 0x3a885152 0xa43ba8bc 0x0e38f466 + 0x550ebfc6 0x61aff7b4 0x7a48222e 0x4b1cb5f9 + 0x6214db4e 0x10184d25 0xfffd5568 0x082c65bf + 0x0de275b4 0x9db1d249 0x21948675 0x5a172a34 + 0x3ba61149 0xc843cbfe 0xf6e573a1 0x0aa69e59 + 0x643338ad 0xd14f414b 0xf0d93cc7 0xb2e2bac1 + 0xee2134ff 0xd2dcf80e 0x2f1b6a51 0x70925db3 + 0x30d2fa78 0x9d3c7564 0x49c0e04e 0x4fe8fa3e + 0x0f452a33 0x97fef85d 0xd6657569 0xb1c9f85e + 0x64aefba6 0xe1c08a12 0xa62951f9 0xcd3bf51c + 0x83514304 0x3fca58b0 0x6e083a1a 0x0fc56295 + 0xeae9908c 0x234fdfa0 0x5b153453 0x2628c616 + 0x13320f68 0xf7e8d3ec 0x136f83b3 0x824bb8fb + 0x63ca453e 0x834cce39 0xe792bc39 0xa567a0a1 + 0x7007c69d 0x9fe0329b 0x2bcba778 0xef681fcd + 0x1d26dd8c 0xac0f8fa8 0x4999ceb3 0x61164783 + 0x59343833 0x996d2444 0xcc4f9ccc 0xed898d1f + 0xb6b075bc 0x157a5bd1 0x7fab1605 0x3d55f3ec + 0xfb1dab64 0x43c51e43 0xddffd435 0xce1d1dbe + 0x689aec3c 0x6bfef5c9 0xad16f248 0x8c45d521 + 0x339ce8b4 0xa1c26fdf 0xe82ca875 0xb8d27297 + 0x84eef050 0x6cd69df8 0x953bf91a 0x01db2bc8 + 0x4a204142 0x2a85a038 0xe263a583 0x3f9e57cc + 0x4affc364 0xdb89a455 0x41e4f309 0x7cf4e647 + 0xd39ebc0e 0xd63ea965 0x382028bd 0xcaf7843a + 0xcba1aee9 0x962a38ba 0x64447f0b 0x22dac282 + 0xd724cd08 0x5b417c1f 0x5b2b5908 0x867ed01f + 0xef226386 0x20e7130c 0x1f9b12ab 0xb07b30ad + 0xdd75d29d 0x09eb3647 0x06294756 0xefe36da0 + 0x0d601f05 0x11f98b78 0xc8134be8 0x04b69ec6 + 0x6df37e2a 0xeb0d9335 0xf7b87d27 0xff234b32 + 0xdc7d9fc9 0xe0b92f02 0x11aa6f37 0x42310d88 + 0xe64b36e0 0x2069733d 0x4c1b80fe 0xb6269ec7 + 0x02c85bb1 0xc63c207a 0xe3ce412e 0x90cc4eaf + 0x88330bf0 0xba4c2e47 0x9efac5f5 0xea829249 + 0xd4373cae 0x1dc54d9c 0x18b04744 0x4ec0f396 + 0xad95f8db 0x14732778 0x812632c8 0x12a39947 + 0x2497f5a1 0x940abdcd 0x4b340eaf 0xbb52e0fc + 0x6992bbde 0x3180705b 0x5f15dda6 0x7ee9a828 + 0x5dd3a447 0xb81da4bc 0x898c4ed4 0xd4cfa48e + 0x3e648720 0xa061535c 0x38b0d519 0x714ea4e1 + 0x6558aaba 0x2e5d9832 0x32b10cb3 0x12f74683 + 0x8a2d1272 0x8bfea89d 0xb9b0d38a 0xc62060b8 + 0x4d6c0796 0xdde515af 0x4e69b74e 0xf9e066cb + 0x1178ccc0 0x8c49629f 0xb18e62f7 0x82570fb4 + 0x679990e3 0xeac06852 0x845ad85e 0x66fcdced + 0xcc8bab2a 0x4cccd967 0xa909d3da 0x16f2b84f + 0xff70b687 0x8e964680 0x3e490510 0xcc15ff7a + 0xffb0a318 0x30085e27 0x0c6294e7 0xf092ff84 + 0x1e8ae3ef 0xd9f4135f 0x4eeb655b 0x0b133b0e + 0x0da4c728 0x8a9ee7d2 0x7b0579a9 0xac385286 + 0x5c9ac211 0xb0674a9c 0xe533403a 0x4dced95c + 0x035f6f44 0xec76b93e 0xfb6db00d 0xa4ab917d + 0xae515afe 0xaac11faa 0x78bafa84 0x5a67e774 + 0xd2c3b6b8 0x6708f12b 0x867c2e37 0x826e1ee4 + 0x4b4ba1a4 0x4d93d7cc 0xb82afd9d 0xfa715ef8 + 0x17de030b 0x2e1a71ab 0xb567360c 0xfd8f16c1 + 0x5160138f 0xd9384a40 0x345b1c4b 0x058993ea + 0x3fcae8d7 0x4dc2e776 0x327b2dd1 0xe7d1d383 + 0xfa10dfcb 0x5ba3c956 0x54db7d48 0x37fb2526 + 0x055a1158 0x7796bad7 0xbd5a4832 0x33f01c7f + 0xf5fc6313 0xa7298449 0x43b6e7ce 0xfd3d144a + 0x087127c7 0xb11d0a54 0x792d388f 0x477ad5e6 + 0x7cff7375 0x17a424ab 0x4e798c03 0xae4b553d + 0x02c30177 0x82f30375 0x98b98ed7 0x8f741f98 + 0x7e777486 0x6ad3d150 0x1c2a0d72 0x3ea2735a + 0xd5d5116c 0x9d12505a 0x70a402b1 0x615c72a7 + 0x637f3650 0x99b10cb4 0x6a0de436 0x15621e35 + 0x61194a84 0xd34ee0d7 0xfdd70d84 0x8aca1c6d + 0xfac6878e 0xfa7b5771 0x3022330f 0xa7ed23ee + 0xe9763f69 0xc4d38e3c 0xa5fc726a 0xde7dbc91 + 0x65ad5383 0x7f7ad77f 0x8516fbc9 0x9623d563 + 0xcf8685c5 0x59f21315 0xc1b6b1d0 0x15eecc50 + 0x9009f44b 0x7a2a8ad7 0x766a354e 0x59a6b09d + 0x4cca7284 0xf6ef4ec7 0x388c54e5 0x3d34a34c + 0x49a780a3 0xc7a8bbfc 0xf25d8bec 0xf6a390f2 + 0x1cc94fda 0xf37f034e 0x2be39e36 0x760d4f1e + 0xdfcd71e7 0x55ed5a16 0x0bb9b028 0xe533d067 + 0x033f76bd 0x8ee3d55b 0xa3e59542 0x4fdb93a2 + 0xb47a605f 0xd0a02253 0x948c4cc9 0x4dededec + 0x715c7873 0x88bfe017 0x11095c7f 0x0f71d898 + 0x25837d56 0x8a276147 0xd09ff4b8 0x2c4fae22 + 0x2730915b 0xbb1fda31 0xd5cc59a8 0xd8dc28f6 + 0x12f2080c 0x4ad77d75 0x223648a3 0x73abafa4 + 0xfc9554f8 0x4cbaae79 0xdffe60f7 0x0a98e937 + 0xa8a8af70 0xd3cc1f77 0xae09e4ab 0x14f0caa3 + 0x63b21bc6 0x0a086fdf 0xa1a7b1a1 0x3314cbd4 + 0xb1732177 0x842a7e12 0x37ed7860 0x720daee9 + 0x2eeb8d06 0xb0098553 0x8cca4537 0x2a1c4180 + 0xf1f10adc 0x66d21bbf 0xdae7b1dd 0x030f8be5 + 0x184ef28c 0x4a1082b0 0xf5f73b3f 0x2bc852bc + 0x1893287c 0x7e1c6291 0x8272ba61 0x2aef57e0 + 0xec90742c 0xf9d46e63 0x85e84eef 0xd32c10c2 + 0xfa96b003 0x0fa221a7 0x9bdee2e2 0x9cee99df + 0x4071e863 0x3b4af098 0x15148a99 0xd525d447 + 0x1e8be181 0x73cd75fd 0x2f1e91da 0x9c7531a1 + 0x23c109e6 0x5172cf8b 0x69ca62a0 0x754c25f1 + 0xfa3a0cca 0x6201622b 0xc7cd058f 0x5d5ee3f5 + 0xda0a4d69 0xcded309c 0x5bd1fc91 0x1fa74d7c + 0x65bb3381 0x0811c460 0xbe6efec8 0x41edba24 + 0xe2237b32 0xbded2338 0xe923a277 0x90732deb + 0x73820616 0x53fd3be6 0x30df290f 0x0529d627 + 0x5216acf0 0x0df2f5e6 0xb7aae7fe 0x77a86a6e + 0x216c1fb6 0xde9d0bca 0x4c38b816 0x803cab8e + 0x4653e80d 0xe5323d3d 0x98336658 0xe9330b0b + 0xf5d154d1 0x2574745c 0x0b8b22e4 0x01cb6d85 + 0x7fd416a7 0xa74c5c80 0x1752811d 0x3fcfa0d8 + 0x1740f342 0x298908ba 0x8acda280 0x63fe7f51 + 0x697caa20 0x46772da7 0x6a2f5e16 0x8d56e593 + 0xed1df3f8 0x8a8f59d1 0x7660da2f 0x805c1ba3 + 0xf2b7438d 0xc175237d 0xb7e4002a 0x38cf4010 + 0xd7884e26 0x60e3abc8 0x3e3ce1df 0xb90f753b + 0xc3836140 0x2724bc78 0xd1014b33 0x7aad6cc2 + 0x502bb788 0x3cd6c11b 0xca0e8132 0x23a5f680 + 0x7fa541a1 0x2c73ce32 0x266d5568 0x26dca072 + 0xc0e425dd 0x04241fa6 0x102e59e1 0xc1ac9846 + 0x59e6807d 0xf7dd1309 0x4bf082da 0x43cd88b7 + 0x5628e73d 0xd244c48b 0x7bc83d1d 0xc0fb8023 + 0xd0d24f43 0x27c17ca3 0x486f80a5 0xae90bd2b + 0xbe4e4d0c 0xba06936a 0xd95432ac 0x84fcced7 + 0xa70c8cc9 0xc6b18bea 0xe01f8516 0x658ac202 + 0x63443276 0xc3626cac 0x0dceb29b 0xba20f2e7 + 0xaf50a259 0x1f7332f4 0x43885c55 0xf5dbfbb0 + 0x3174f3c4 0x5081d664 0x9309dab9 0xd2ef2193 + 0xbf01e367 0x44eac6f6 0x5a639230 0x53edebd1 + 0x15581102 0x785a8122 0xea11c074 0x04003b30 + 0x45c97b31 0xb5fdff79 0x16ed5a0f 0xb2ab6eaf + 0x524d6293 0x73df9c8d 0x1a6d65d5 0x442d7abc + 0x4f260f88 0x3078b81d 0x87e6b52d 0xc3bad689 + 0x55093e7d 0x9fdbb5b3 0xb805940d 0xbe18f822 + 0xfd262e29 0xc9eb61b4 0xabddb5a6 0x3ef2e4a6 + 0xfb8c082a 0xd6b8c59f 0xa710b259 0x36dd9814 + 0xaffee9e4 0xb7f3471a 0xbb9356fc 0x44600752 + 0x374907e2 0xfafc6297 0x20fd0007 0x05f324c3 + 0xa2037e3a 0x10ab66c7 0xe44175a1 0xaa4ee6bc + 0xe45a8ce6 0x020af65b 0x5e059ff8 0x98cc3cf1 + 0x06019b96 0x6d1c1922 0xdd0a2e8d 0x86837333 + 0x1a3e36d3 0x17e2e5f2 0xb32ef76b 0x559915a2 + 0xf9c22b32 0x079ee5dc 0x7a3d401a 0x60a10dd4 + 0x053758ce 0x2e005b70 0x3685e353 0xf4b6460b + 0xc7d789c8 0xc8ea82f2 0x8fc74f86 0x9f68e92d + 0x5a1e00ed 0xd0e8fada 0x197640c3 0xeaa6e62a + 0x023a7169 0xcc7fb17b 0x98dac1fe 0xe6c807a6 + 0x0560e399 0x9fb5e511 0x0882c18e 0xf4d767f0 + 0xb508a6e8 0xd27d2026 0x4681cbc7 0xadd7f6ba + 0x35f47df4 0xc72245c5 0x8e8b8a74 0xeb94e799 + 0x8396bff2 0x6c2bf652 0x1562b482 0x5e1d2d57 + 0xdff1c004 0xa29b50e6 0xff880a97 0x7fc22f15 + 0x89633cb9 0xd0ab4601 0xe7341887 0xc07bb55e + 0x71eb0aaa 0x4c0f2ba5 0xa7801724 0xf43a7964 + 0x434daf5a 0x68eedb3c 0x194eca3d 0x0bbfeeba + 0x67850a32 0xd23b1ae1 0xa6911d9b 0xce700d81 + 0x783928d1 0xae5c120d 0x71fa13b0 0x2006c22b + 0xf72f5d3d 0x1cd744de 0x0d9fc67f 0xafe8d24a + 0x82b5142f 0x2bbf5368 0x17959168 0x09655f9d + 0xcab7fad9 0x51e66c7a 0x2420988f 0x847754b5 + 0x0a4974ae 0xfa654071 0xcc725340 0x6fa4583a + 0xca3082e7 0xc0f9ce55 0xd7d2cadb 0x79a92e96 + 0x22298333 0x57c27396 0xc74fa5e2 0x4afe8a75 + 0xcf697c69 0x4f76031d 0x4621473c 0xad0abf11 + 0xc82cd007 0x2bbad261 0x39318b1c 0xdcb0e1a8 + 0x31ea902c 0x6e550361 0x784be9d0 0xb14a31e3 + 0xca23cfd2 0xa43e7604 0x72ebff4c 0xed80ec25 + 0x43baaa63 0x880434aa 0x36a6e985 0xc173ddfc + 0x11f1dd14 0xc7ee29ec 0xaebdcf8a 0x4c8445d5 + 0xaa772022 0x024d91b3 0x048082d0 0xcbaefb3d + 0x4b09b3a9 0x12cf71ef 0x7db43f55 0x93cdd0c1 + 0xa076bad7 0xb46de6fa 0x417dc418 0x324da83a + 0xff365817 0x155f3cdd 0xdac35be4 0x2fd2c82c + 0x11f1bc33 0xedce1813 0x6d7c9f85 0x5c114653 + 0x01c57aae 0x1b96107d 0xe1c9f66d 0xaea3a907 + 0xa884e213 0xf8f98e65 0x91532420 0x01ef2298 + 0x497045c1 0xce8fdb4c 0x27eb66f4 0x4f55e3f0 + 0xba804764 0x26bda14f 0xc9f7f582 0x36bc7f36 + 0x34c2aa75 0xe4f15089 0xb8f9ee73 0xd4266b10 + 0x0fc54a15 0x5aa528c9 0xf8dfec8a 0x508cea6b + 0x22b419f8 0xcf53de4d 0xbbd7e283 0xa14d1b71 + 0x9c32638c 0x1e361701 0x95b3f6bd 0x71ade23c + 0x7dbdaf13 0x703136d9 0xb50676c0 0x1275e5b3 + 0x15efee34 0x3389309d 0xab961f5d 0xf381dc6b + 0x20ade074 0xce316743 0x79d44d92 0x1d4fe039 + 0x6cfce315 0xb13ec789 0xf1a3d756 0x82ae906d + 0x26ef851b 0xd2ca8f32 0xadd6ac28 0x3bce1e22 + 0x2de58e91 0xa0e69d86 0x0a66678e 0x0556a657 + 0x19206ec1 0x078b1a5b 0x06a676bb 0x89e164b8 + 0xc37e2fb4 0x1a4dd1dd 0xea609b2d 0x4a5cab06 + 0x8a0e5f3a 0x5f92a2d8 0x150ac669 0x3dccaa31 + 0x9e0296b6 0xf351dbf1 0x5cfca2f5 0x73e865f8 + 0x078c8312 0xf50254ac 0xc9064d4a 0x4f7176d3 + 0x3effaf99 0xe134aa8f 0xb4601dc4 0x2ba07197 + 0x7bae54f0 0xdf72f3ed 0x867c5d82 0x732c07e3 + 0x24e20500 0x287fc531 0x96166ac1 0x97543ef5 + 0xed62f87e 0xfaa76a7c 0xed4ba778 0x4e115af9 + 0xa11b36aa 0xcff391a1 0xf27a1aed 0x171a552f + >; diff --git a/arch/x86/dts/microcode/mc0306d4_00000018.dtsi b/arch/x86/dts/microcode/mc0306d4_00000018.dtsi new file mode 100644 index 0000000000..3c7864255d --- /dev/null +++ b/arch/x86/dts/microcode/mc0306d4_00000018.dtsi @@ -0,0 +1,944 @@ +/* + * Copyright (c) <1995-2015>, Intel Corporation. + * All rights reserved. + * Redistribution. Redistribution and use in binary form, without modification, are + * permitted provided that the following conditions are met: + * .Redistributions must reproduce the above copyright notice and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * .Neither the name of Intel Corporation nor the names of its suppliers may be used + * to endorse or promote products derived from this software without specific prior + * written permission. + * .No reverse engineering, decompilation, or disassembly of this software is + * permitted. + * ."Binary form" includes any format commonly used for electronic conveyance + * which is a reversible, bit-exact translation of binary representation to ASCII or + * ISO text, for example, "uuencode." + * DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT + * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --- + * This is a device tree fragment. Use #include to add these properties to a + * node. + * + * Date: Wed Jan 7 17:15:10 CST 2015 + */ + +compatible = "intel,microcode"; +intel,header-version = <1>; +intel,update-revision = <0x18>; +intel,date-code = <0x12052014>; +intel,processor-signature = <0x306d4>; +intel,checksum = <0xc839f43b>; +intel,loader-revision = <1>; +intel,processor-flags = <0xc0>; + +/* The first 48-bytes are the public header which repeats the above data */ +data = < + 0x01000000 0x18000000 0x14200512 0xd4060300 + 0x3bf439c8 0x01000000 0xc0000000 0xd0370000 + 0x00380000 0x00000000 0x00000000 0x00000000 + 0x00000000 0xa1000000 0x01000200 0x18000000 + 0x00000000 0xe10d0000 0x05121420 0xe10d0000 + 0x01000000 0xd4060300 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0xdba22a66 0xbe0ad79b 0x0965992e 0xad84102f + 0xbf2a0939 0xcb0788e2 0xea0b1e6f 0x356e583f + 0x3f11d4e1 0x035508c3 0x0c066713 0xeaeff79b + 0xb66e752b 0x697be02e 0xc41dfd7c 0xb2c81198 + 0x3640cf86 0xaf4c5320 0x80650437 0x6c4e2b43 + 0x542e3a6a 0xfc4da788 0xf603a581 0x516b7367 + 0xb7112bbc 0xc9adf3bc 0xfeeec896 0x49cc8b68 + 0x96f9c416 0xd25c17e0 0x587a4d45 0x13fd7aa6 + 0x429e8d09 0xc22e6df8 0xa6678a73 0x17adc426 + 0x76676608 0x1d970d05 0x7c8a9968 0xf99cac21 + 0x617be229 0x7dfd1cd6 0x83ff0035 0x873612d4 + 0x9624b727 0xf667b8e9 0x710d9262 0x34dd59e1 + 0xbac69139 0x19577a36 0xdfe9f57a 0x11fdb95c + 0x698498f5 0x10f25341 0xa994b124 0x8839568c + 0x38fd5bac 0x93e671d2 0x92b2e916 0xd083650c + 0x4f1a50d2 0x00af9698 0x9faa6566 0xe98d3a0f + 0x5fdbf0c8 0x46a5b760 0x6329a5e3 0x39eba30e + 0xab088c0d 0x26aa5f2f 0x56bd3c1d 0x566259a8 + 0x11000000 0x70e23c2c 0x1b7d8466 0xa2f784d7 + 0xceb63ce5 0x9088234b 0x23b1d432 0x84eea8ef + 0x9d1888e9 0xfb2b8217 0x4fa7ac69 0x07c529a6 + 0x8b0694d1 0xba372800 0x4da8ad25 0x3cfde2b9 + 0xa7554683 0x8df70fe2 0x93b7f5b8 0x459ae846 + 0x1637173b 0xb8ca3f39 0x6a9dfbd3 0xe226e104 + 0xb9d194b2 0x02d64e76 0xdd310266 0xcc89892a + 0x448aaabe 0x4c29405c 0x4c0b2833 0x0f5839ad + 0x7a204f3f 0x4a6b292e 0x32d1af82 0x95b6e9a1 + 0x495ffbf1 0xf7eeebb6 0xac1ab767 0x43f8274c + 0xc579abad 0xd4a1a6aa 0x51b10e25 0x480ff530 + 0x49ec38b0 0xa647f4c6 0x65bc5a86 0x9731894e + 0x29be8858 0x1fce1d88 0xcb901a01 0xa924d206 + 0xb539d5d4 0x7574ca33 0xfa51c12d 0xe98cf6b4 + 0x0a601353 0xecdb49b0 0x475890ad 0xd75bd0b5 + 0x544de968 0x5c07241c 0x35ca668a 0x8250fa85 + 0xe5a95b37 0x7c71c685 0x82a38388 0xa7fcfd16 + 0x7a59cb4a 0x0df22455 0x0799852c 0x48156813 + 0xbad36d9a 0x1ff36daf 0xdcd1fa2f 0x330fe0bd + 0x128a91b0 0x45268039 0x04486df2 0x76f50789 + 0x24a188f9 0x248e3334 0x8ead8d52 0x5809c815 + 0x0e714a5a 0xd75f89e9 0xf8b8ab34 0xc4d8f517 + 0x96768393 0x85ab9591 0xd459e17c 0xd9cdf5cf + 0x18ab4829 0xffd32b98 0x3e665304 0x19b135d3 + 0x50ab83a9 0xf2d374f4 0xf6e8acbe 0x003d4478 + 0x921e16d5 0xc87aa4e0 0xa9b09093 0x55dffcf1 + 0x07cfbf0e 0xb3c82af2 0x0fa7b716 0xabc3ea4b + 0x79d6b5fa 0x026ab2a1 0x07311959 0xd7cfff59 + 0x7f061c87 0xca074525 0xbcee0015 0xe25287e1 + 0xa1f251c1 0x7742c342 0x2f23d962 0x1879e99a + 0x16c0872a 0x8c60144b 0x3517ad0c 0xa526c0be + 0x27e4e63a 0x88662d0c 0xa1f89b28 0xaafe70b1 + 0x7e4e3b36 0x52819340 0x3e07513c 0xb6ace619 + 0x2fd42cf6 0x38ea6c82 0x03feed66 0x1cce3d23 + 0x9cfdd0db 0xc6657c2b 0xb58edbd6 0xd7ffc707 + 0x605a4f83 0x4949c032 0x775572d6 0xada53d72 + 0x12feae5c 0x44a02e35 0x70559a73 0x2845ff91 + 0x4b38075d 0xbda74c3a 0x31ec0665 0xc145bb52 + 0xdc2374d0 0xdbd44f9c 0x3cbf5a72 0xf60fcbbb + 0xa23484a9 0xf701795b 0x8a40a369 0x0ec36d46 + 0xc0267c8a 0x391950c0 0xc3aa7a13 0xeffcdde0 + 0x8913df38 0x359a93a5 0x70f70984 0xcf8c068a + 0x8edaf2ac 0x3138e62a 0xe6b7e2a1 0x2ed66a90 + 0xd16a0d53 0x94917361 0x93d83fed 0xfa3779fe + 0x5e3bd293 0x683c6f3e 0xf7917a1c 0xc45084c7 + 0x80d9939c 0x37acefd3 0x6866acc7 0x19722a46 + 0x9eb5e80b 0xea4ba207 0xb8e9fcb8 0x9899dc0f + 0x1b5f2321 0x7426957b 0x73817bdf 0xb42c0062 + 0x8723c8dc 0xbc51864e 0xe20d1f1c 0xdf5a4816 + 0x37771401 0x5dfb8907 0x990296cd 0x960dc10b + 0xc3c9dd16 0x19d10cbd 0xe57d0d58 0xd82e36dc + 0xf05e5372 0x7714a18c 0xb3b3de0c 0x74dd8193 + 0x260b54da 0x3e1dfbd0 0xcedf5fc5 0xe180c7e6 + 0x765aef39 0x6d6886d1 0x3083d924 0x9887c0d3 + 0x6b29bf34 0x25924357 0x67f0279e 0x9272bad1 + 0x9eea3d30 0x31a66bfd 0x47c141a8 0x48c33fe7 + 0xe1af5c5d 0x3d79a63f 0xee926a91 0xcbcd3a90 + 0x3fae595e 0x5b90ffd3 0xc9127894 0x0f186052 + 0xd4ccf1ed 0x2894a66e 0xc5dbb07f 0x8a82716c + 0xa57ad9e7 0x5d202f63 0x62d36127 0x24ace962 + 0x0a40360f 0x5771a241 0x0c0857c1 0x3fb6f1d3 + 0xc3ae472f 0x7145d672 0x48ed8d2b 0xf8421334 + 0x561c7a80 0x45051ffc 0x148f4286 0x3daafb8c + 0xd1d3e9f3 0x5fda4d88 0x4720be58 0x28acd68f + 0xe2b89015 0x7cf21abb 0xa5770455 0x88cd0b21 + 0x1f61015c 0x85c93767 0xbab87e33 0x3124016a + 0x3237c6e2 0xd0a3f1e7 0xa8084779 0x20cd1c8a + 0x4b37b623 0x7358ed54 0x5aeac6d9 0x752b12c8 + 0xaea1bbf7 0x1af0b54e 0x5dd2ebe7 0xcb4ae47c + 0xda6fb0e6 0xe3059b17 0xd03924b2 0x444d92d9 + 0x79d705f0 0xff135399 0x243522ee 0x8f73dfd4 + 0xaca149fb 0x81958a52 0xfebd7b81 0xe3d768ef + 0x53e7bfb4 0xa4579a13 0x77e340e4 0x30185a9e + 0x0daa18d7 0x0bc68fe9 0x95161f27 0xce9c3ee4 + 0x91165754 0x1a89f7a4 0xc4058b46 0x1cd1fbd6 + 0x25251f7a 0xf9e578fd 0x761322c7 0x9c34727f + 0xe64ce289 0xa19548f5 0xa47bb64f 0x71abfcd1 + 0x9615e893 0x181d0f15 0xb09f0234 0x64f01f08 + 0x748db288 0xe25133c0 0x5a65f595 0x9f36c6f0 + 0xb19a11d9 0xc9cedd48 0x2ad66ebb 0x65e4a88d + 0x2c7399c5 0xc4e84387 0x79095cd6 0x52fdb70c + 0xdc1ae272 0xb41ce754 0x13f46a1e 0x3fb2ceae + 0x5aea9013 0x8301f6b8 0x41131a65 0xf7f2c7ec + 0xfa7c2862 0x3e6d24e8 0x7552e7d3 0x7747d8a2 + 0xff94b768 0xb8641288 0xc42661d5 0x7f44efed + 0x575c9e45 0xcd9e75b7 0x1002bb44 0x97ff1ee9 + 0x2e7f5038 0x192b8e0b 0x0e87610c 0xb11f44b8 + 0x0a138ef0 0x5a0956ae 0x62013ea2 0x834a8b1a + 0x61a8483b 0xc33f2e90 0x7c5ccc9b 0x9ae5fe00 + 0xeb3da13b 0x3f3c2f90 0xe13a11ff 0xc38e26f4 + 0x846f08c9 0xe0e38c95 0xa13a2f5c 0xa3581647 + 0xc93568c0 0xf85729c6 0x85952202 0x727faa0f + 0xcd5db4c6 0xcb1a9ed7 0xf2d4e44f 0x40ff5258 + 0x4cda46f6 0x9749f867 0x4cf2a738 0x24792ae0 + 0x263c3d21 0x30e690f9 0x9ce26384 0x9a0cafcf + 0xe2645e6c 0xeaac309e 0x84c0a218 0x2cdce2c0 + 0xb785c012 0x1034135c 0xa64a65e3 0x3c33ad10 + 0xae5eb84f 0xfd5543ef 0x12a6e1fe 0xffff2290 + 0x45fd07c4 0x70ca6410 0x17f1467c 0xa258a38f + 0x62e85ab1 0xbabd441a 0xf8af8d3b 0xabf0852b + 0x11ad60a6 0x6014d6a2 0xc8bf66db 0x45ec4ce4 + 0x986087af 0x82974e7f 0xab562d51 0x72f78c02 + 0x122a3857 0x51fc2d69 0xc2770e19 0x8e1f7793 + 0xd54890a2 0x542f78cc 0x2c0476c2 0xc6088dca + 0x467546fe 0x7bab798a 0xf6620dc0 0x42ae5b41 + 0xd3512796 0x9ce23558 0x02ecaf0d 0x9cf4f3dd + 0x0531f681 0x3b6e677e 0xebdce6ba 0x4f614ba7 + 0x452da3f4 0x8a6d2df8 0x4503a79c 0xb3feb459 + 0xe656f4ad 0xda10a8df 0x5b84c809 0x626bc361 + 0xaabe2b50 0xb5a17efe 0x5572c755 0x8e6836e0 + 0x367c73c8 0x5be0062f 0xe2b2a9c3 0x6284bf4b + 0x598615c1 0x71baa610 0x81e32b1c 0x082ecf94 + 0xb3545874 0xc22c034a 0xda702e7c 0xb80a2b0d + 0x9557a002 0x6cb7aae0 0x515042ba 0x022708c3 + 0xb2d4203b 0xb45abd33 0x3431b911 0xe6156b60 + 0x49b76c50 0x81b6ec6c 0x71dd0c0b 0x7375a7b9 + 0x0a81906b 0x7ae3793e 0x8e1c1229 0xf8654b9b + 0xab5b1861 0xbd559fe4 0x09d011e7 0xa6657fa5 + 0xafda83e0 0x6ac3a1e5 0xedfa3de7 0xb5cc149c + 0x84160e61 0x4da10346 0x3d909a8b 0xaa3821aa + 0x7d42b0b5 0xe6429fbf 0xef8191d7 0x5f19ca7c + 0xf000dc81 0xe1b6042e 0x695edd22 0xf66f9faf + 0x94f15f14 0x6637dbca 0x3f6dd338 0xc171dc51 + 0x1de48a49 0x06194b2e 0x012fab5e 0x9790216a + 0x7314c73a 0x24d68677 0x2bc20c64 0x60b4549a + 0xbb6a7844 0x4633fe4e 0xc25ea02d 0x712d631d + 0x658cff37 0x382e3a45 0xbc0bfc41 0x69625d2e + 0x779b2d65 0x9e50cde9 0x680b2c0c 0x6f21ed7c + 0x2c1b7dde 0xedd5512b 0xf4b250e4 0x03709be7 + 0x245c1b9e 0xedc82d72 0x5ef47b81 0x475587de + 0x545bd2c2 0x6c9c94d3 0xd5f6f4f1 0x7ff06558 + 0x2da62e15 0xa9db20b8 0x170b244b 0xf7057f09 + 0x7575eed5 0xafe033be 0x7b25af94 0xc42164fd + 0x5ebc49c5 0x5d232014 0x37a212ec 0x0d887adc + 0x63027728 0x49be2697 0x4273bc08 0xbee2466e + 0xc120abed 0x82fbab44 0x3f90149b 0x7776e0b4 + 0x61e41d7f 0x86b24a2f 0xa8a1b21f 0x3def1f04 + 0x5407d3c1 0x02e5b0dd 0x92e295a1 0x60e4ec8a + 0x8003c44a 0x98051d42 0xac009a9e 0x4f3cd1b3 + 0x61218b7f 0xfdbb36b1 0x5665bd25 0x4aedd5a8 + 0x4d39fba6 0xb68cf631 0x6babe008 0xcd3ce386 + 0x6aa5056d 0xff8cb27d 0x8f0e9bd7 0xe45c17c3 + 0xd0a58ad9 0x865cd5dc 0xf2f0b03c 0xf4d46121 + 0xfef3f7f1 0xfb576ce0 0xc7978309 0x8978a4a3 + 0xc753c0c5 0xcf17c69b 0x756b80c1 0xb4d3aade + 0x436feca1 0xd005f617 0x0f8eb00f 0x50b54f3d + 0x40d49450 0x4df95baa 0x5ae05c52 0x2425a579 + 0x31add124 0x08ac6a36 0x31503560 0x76249f63 + 0xaabf69da 0x4cda656b 0xb256550f 0x0e13c9e9 + 0x823ab41e 0x36471101 0x79b15b65 0xfc23e6d6 + 0x48062954 0xba766e67 0xeb980604 0x3b86b4e1 + 0x32e1cb12 0x49fa888a 0x272b1086 0x24c9a028 + 0x75e46e74 0xee13f4d7 0xd37b8ae3 0x41c8152f + 0xf69105bc 0x5970dc10 0xa8af57f4 0xc50f531f + 0x4fb94b31 0x5b18154e 0x3c6bfc4f 0xfdf46c0b + 0xdc126153 0xe84e0788 0x8b75deb6 0x6a7f5631 + 0x75d9dcee 0x300cf228 0x171aeb0f 0xe3a13a9b + 0x161a3425 0xfa983a1a 0xa66e7bed 0xb2105d9d + 0xece8e711 0x03ae5c21 0x67248545 0x07cda076 + 0x8cf9fca9 0xe8bedf35 0x540535e7 0xf6242dc1 + 0x6a0dc683 0xd3f47c01 0x7599d3ee 0x9951924e + 0x0c4a8350 0xd0cd23c1 0xe006e948 0xcc766fa6 + 0x45e18c01 0xe22d57b7 0x7a6151fe 0x3b91141d + 0x4d5ac707 0x8dcddccc 0x1e510e5d 0xf6e9d9c2 + 0x91666dac 0xd0a2d1b4 0xeaa3ac6c 0xa2e00e16 + 0xa63246f0 0x262f13fa 0xa57823f8 0x5c95de2f + 0x65ee4639 0xb4055029 0x31de658f 0x5cd17539 + 0x7e7e443e 0xb131b744 0xcb624716 0xba2cf483 + 0x050db2df 0xf66000bd 0x4af88f26 0x79805891 + 0xd60e929d 0xf4e25a0a 0xb3bfbc14 0x168e3992 + 0x23cb80d3 0x67219931 0x04e16cff 0x4a503cad + 0xdd996c1d 0x30a1ec3f 0x68235697 0x1337c96d + 0x6f0e9d6a 0x2a7d02b4 0xa42ccd20 0x2944c7f2 + 0x4bd8dadd 0x5bfed31e 0x364cf6f4 0x95af93b0 + 0xa0d7e152 0xb347369d 0x21a1ab6b 0x1f6709aa + 0x071df6e4 0x1477001e 0xc4b3c0fc 0x0e74f2c7 + 0x59370198 0x8594d6d0 0x2bfbb727 0xf2714c89 + 0x0612eff1 0x2e58f008 0x62034e53 0xac864f76 + 0xa82a588f 0xc0d235cb 0x7f81998f 0xda7f8738 + 0x147043e7 0x1fab95b4 0x5a9b9152 0x2a0dff34 + 0xad02f395 0x2aeaafc6 0x35b980e2 0xe3c647b3 + 0xa6614795 0x032dec1d 0x5d3681f5 0x331b46af + 0x071d39d7 0xaa4b2500 0x1aaca3f9 0xa6e24704 + 0x8940e5f8 0xe50f05a9 0xa951365b 0xb42aac38 + 0x64162823 0xa1626db3 0xf49079e1 0xb9e6bcb6 + 0x80e25b93 0x02be0153 0xf5e1bac0 0xf95bf7e9 + 0xa946853f 0xc4f9d796 0xf07b1bf5 0x29990e8d + 0xd2352d1d 0x05b9d92e 0xc5e8148a 0x568d7cd5 + 0x5ab01131 0x5055cdca 0x9f308cdd 0x57c089a5 + 0x04de25c0 0x0cfcd61a 0x3329c959 0xe22ea82f + 0xd8b4008d 0xc5c4a59c 0x79a2c70a 0x6289e906 + 0x88e4ed71 0x35fcd35f 0x3ccd08a3 0xc8208a79 + 0xbddf86e3 0x7f5c9c17 0xcd66e37d 0xf9e07134 + 0xc551e5df 0xfa42991a 0xda71803c 0x8eacbe09 + 0x55340d26 0xfbf8ccb4 0x995445c5 0xd8f0057d + 0xaacf78b7 0xc2ed5434 0x419c8c8e 0x190ddc7c + 0xb0a6b019 0xe5026481 0x36e103b8 0x1176be12 + 0xcd7ddd2e 0xf74b2d65 0x8ac34ef2 0x070621da + 0x86f45fdd 0xa89291cd 0xee1f9340 0xeb78ffd5 + 0x791b9276 0x26088a23 0x75affd0f 0x4747a454 + 0xd06ec97f 0xe02383f2 0xcec2f827 0x1506de3f + 0x0aa12b9d 0xf6b9b27c 0xb25fa254 0x366fff4b + 0x128898a3 0x5ac31f23 0x1032d9fe 0x21bb5327 + 0xf267e40e 0x0fe5f86b 0xa1c3645d 0xb5363718 + 0x27115b8f 0x2f78c7b2 0xbfac5b29 0xbc59ee60 + 0x2ae0c741 0xeb365235 0x1939b82d 0x6fdc2751 + 0x35a6214c 0x16c17151 0xe0d075c4 0x3e26b0be + 0xb2ba1aa9 0x8c47beab 0xfc10b0a9 0x840c2e42 + 0x0704c87a 0xc201acdf 0x24d01c4a 0xf1a18efa + 0xe7cb41f5 0x97764440 0x4cd84a1c 0x506b6764 + 0x2a01332b 0x73d34250 0x0c5a012a 0xda35525c + 0x1e517310 0x3cd323dc 0xeec3db79 0xaaf0f9c3 + 0x8381998b 0x1818375e 0x0c90cdf7 0x541fe193 + 0x7e1abaff 0x93ca023b 0x1c611c58 0x85ca0c92 + 0x6e9f0d62 0x678c6f34 0xcf2372af 0x4002ebcf + 0x4c0f7dbf 0x1669e554 0x927710d3 0x5dccb350 + 0x5589890e 0x5145c2e3 0x85ef0fff 0x41ce47aa + 0x15306329 0xd6f694a8 0x74ee2bbd 0x1b130ecc + 0x1f2f4dbd 0xadf2863d 0x4738662b 0x6e5da35d + 0x1956eafd 0x061591e2 0x644185e8 0xd34d0462 + 0x775fa0b1 0x7d71b4f4 0x85ea75ce 0x507d1e64 + 0x411a6419 0x87f4b639 0x185dd775 0x66774371 + 0x81f87023 0x76ad61c4 0x61426767 0x8842feed + 0x5a8dd486 0x81628b32 0xcf0554a7 0xec35b2a6 + 0xa6f1211b 0x3a530faa 0xb8f2b95a 0x46165fae + 0x84b6d85a 0x34126a4a 0xb71d6949 0xd5303cf7 + 0xc81b934a 0x23abdaad 0x4e38de65 0xe4bc40b5 + 0xf9fded30 0x600c220f 0xe454a988 0x44bf884d + 0x8ebe7abf 0x49e7323c 0xc337f0f4 0xc915a6b4 + 0xad840f6f 0x2904e39c 0x6e13805c 0x1405ab99 + 0x65b3d0f8 0x46fa4e7e 0x4601f77d 0x83aa67a7 + 0xd5c37bf7 0x59a27ae7 0x44a64475 0x08acb6f2 + 0x0585231c 0xbab7e362 0x1c06d067 0x5108bbeb + 0xa38e1021 0x87737dc1 0x8785745d 0xf4467d1a + 0xbc551f7e 0x79ee6adc 0xc2b30c70 0xc87ad73e + 0xbcd6b0bf 0x33a86752 0x52634166 0x89d5f10e + 0x91e2d134 0x57f7374d 0xe1c7a43b 0x2907696c + 0x00d255cb 0xb0269ea1 0xb861aac6 0xf7072a36 + 0x6d90c64e 0x1bca8e45 0xd1684253 0xfc087387 + 0x7dfa4e69 0xbddfdc43 0x0d9fec2b 0x1e73bc82 + 0x5196a19d 0x8f08c0a6 0xcce9cf1c 0x3f0bf337 + 0x337a4c38 0x128e9b16 0xd56199be 0x5a203b5a + 0x0fb0ebcd 0xeb904ed7 0x60401bfb 0xe86b3d01 + 0xc44855d9 0x3c82d2f3 0x7454b83e 0xcda7e219 + 0x461940f8 0xab5fb0bb 0x1fa4ec36 0x9eb827ab + 0xa2bc7a87 0x8b4c1014 0xd5cf15c2 0x99a1fb32 + 0x8eeaf0e5 0xf8599e9a 0xcbc08d33 0x168b622e + 0xdaabf05e 0xc85d4300 0x62e3675f 0x616ddb27 + 0xe6ff27b7 0xb1fcf2d8 0x29455053 0xc2a048ae + 0x4a150e99 0xe762b0f7 0xa07e5713 0xf4b49278 + 0x50d56365 0xc05fe7e0 0xe25fc8d0 0x668ccc7a + 0xdbc764c0 0xa115709a 0xd115ef67 0xfb175c42 + 0x8be2df10 0x0257aa42 0xeadded62 0x7fa3c865 + 0xa8762904 0x0d3ee70d 0x00d37cc6 0x8f628a87 + 0xb1fa42d3 0xf993b225 0xf6bd4689 0x10284206 + 0xcef0caa4 0xa7707899 0x3189591e 0x3a0d3353 + 0x4c0502e7 0x5a6ec45e 0x60c16132 0x617a783b + 0x8b5707d6 0xeb8225ee 0x0ec0d435 0xa03b9aeb + 0xb49e492a 0xda62ed21 0xc80922f9 0x62e20ffe + 0x94ba256b 0xcdc0a7ad 0xed9094df 0xf1162496 + 0xbe5c8441 0x1056d2a7 0xa5cebdf1 0x2a10fe80 + 0x3e1e6068 0x79dc9fdf 0x5c1966c8 0xf40f46ba + 0x01a63823 0x371791be 0x1ee4b60f 0x1e34887a + 0xb2546494 0x934d8e7e 0xccce6075 0x43639155 + 0x5b4167c0 0x2e980398 0xd9240e62 0xd3855dc1 + 0x6452c65b 0x17c1e0d1 0x8f0570e9 0x72a67c24 + 0x9396e4f7 0xaaca0d3b 0x7074d168 0x93bca0cc + 0x154d9819 0x862e8a96 0x265b0889 0x48648196 + 0x58757c9a 0x6c4434de 0x9a94c092 0x2bb30720 + 0x7bf2289e 0xcbf3e08f 0x198ff4c5 0xb85a63e1 + 0x4f8532fd 0x9a04f514 0x5d01e9bb 0x2228da69 + 0x6a839419 0x640854a4 0x1e39c53c 0x21a3447f + 0xc06a4b7c 0x17639783 0x0ebb7fd2 0x9008130c + 0x51a3af32 0x7be8fbb5 0x92d774e4 0x818cf273 + 0x14189dba 0xe464911f 0xdf793256 0x7b30af40 + 0xcdf7d976 0xfb1835ab 0x9baf7466 0x351df8f0 + 0xb21966b3 0x095d8a77 0x412bf19c 0x6a441613 + 0xfbef959b 0x835d0c26 0x10f034cd 0x79a81bcf + 0x2d94a8ec 0x1d958b28 0x23a79db2 0x901325be + 0xd539850d 0x42650b7e 0x04890acf 0x98abadb1 + 0x184e712d 0xfa3e9a72 0x1f894fe0 0x077ced24 + 0x695a9a9a 0x63500ffe 0x7a980a60 0x41e0b5c6 + 0x2d2556f1 0xe82ea5b9 0xc970fb41 0x54240b9a + 0xcb4284b2 0x53869a97 0x3c22f878 0xbdf50b40 + 0x4a3a96bc 0x55b1dbbb 0x41e81dc3 0x015fdccf + 0xda52cf10 0xc4bdbc67 0x2129cb71 0x092a0d5a + 0x9727c4d0 0x611f366a 0x69b21be5 0x80b25e64 + 0x11b22678 0xa2d292c2 0x86f593a8 0x242f7217 + 0x8c11b6b4 0x774f4a8d 0x334a586b 0x39ee197d + 0x13a12371 0x9f5d821a 0x538b0c79 0x61b469e1 + 0x709c21c7 0xbbc37965 0x26d983c4 0x3d718525 + 0x53e79653 0x6b735f2a 0x92fd62d8 0xe0d58ccd + 0x1f5056f1 0x88d5fd8b 0xfe488573 0x05192e1c + 0x88d53837 0xe4c42363 0x65397452 0x86e930ab + 0xfc0304f6 0xba309113 0x97fb93f4 0xe07d942e + 0x244fb082 0x605cea09 0x6607fc4b 0x559e0c5c + 0xb46f189b 0x6e978ed9 0x5ce7ca84 0x48d36ea4 + 0xd8a412d3 0x9457635b 0xc46dfbc6 0x68320030 + 0x3d7bca6f 0xbb0f1a2e 0x26d8a4c5 0xfae2b12a + 0x4cb600e6 0x717d989c 0x51e4b4e2 0xa6b48870 + 0x2440fbed 0x2cd1cf33 0xc239611c 0x3a1e002f + 0x476c15dc 0xee7cb307 0x98ece942 0xcfcb4a1e + 0x02eaf746 0x8cbdf634 0x03ce5b94 0x7f78259f + 0x613af17a 0x7bcc6669 0xd3c0cb00 0x58556e17 + 0xaba7f52c 0x9ccbcf0c 0x3d5627dd 0x4b746b6e + 0xdb9ab0be 0x885cf33e 0xb99bd48e 0xadb39777 + 0x3c322162 0x2120afef 0xec520198 0x5cfb2e63 + 0xbe88d15d 0x9a105c8e 0x98d30e63 0x74d91110 + 0x1d9d5e7c 0x02719a28 0x9990d84e 0xc28b6d44 + 0xbe169a16 0x03c0be89 0xe4eb87c0 0x46db0e17 + 0x9508dade 0x679609a3 0x870ed09c 0x9ae88d46 + 0xca3c7086 0xd7254c16 0xf2fbaf98 0x6c5e3557 + 0x2646cb6e 0x8f50c80a 0x7c92cf00 0xb19f271a + 0xb6c96021 0xc32274d4 0xec06eaa9 0xd537778e + 0x4c8e2f19 0x67d3d0f7 0xfe772c00 0x266e52db + 0x2055c351 0x3f86093f 0x4c8fb9b5 0x074f5f14 + 0x9b5584c2 0x0826b994 0xf7d876f1 0x9ffdb3ce + 0x16f4161c 0xaa09fe98 0x364a01a1 0xa9034411 + 0x1cf9ccff 0xf8bdbc56 0x163234d4 0xd472dfcc + 0xc5984f05 0x098afb9a 0xd83befd8 0xeeae0702 + 0xa3e60aa7 0x8d9ed50d 0x08f220ab 0x16b0cadd + 0xbac33ddd 0x3c0660ac 0x4ffc4724 0x59163570 + 0x21e10621 0xda718db8 0x2ac628a8 0xe265c9e1 + 0x8079e5d4 0x0731f649 0xe230a355 0x533783d2 + 0x462658ce 0x076c9a69 0xbe4e3190 0x2a7d4bf1 + 0xd6265bdf 0x1c6c2cb3 0x4dd404ff 0xd637aa7c + 0x5d296069 0xc471cbda 0x2dd1152b 0xaa2f5aad + 0xd5569ab0 0x1b91051f 0x1bd5e528 0x2ca45e00 + 0xf4362a7c 0xb007851c 0x53ef378c 0xffe36da7 + 0x4936dda5 0x287c714c 0x0ebad59c 0xd11ba069 + 0xab13390e 0x3b218471 0x2b60501e 0x02ec5c5b + 0xca1110dd 0x31bcfde1 0x476f8d1b 0x2f29815d + 0x9cb085db 0xeb38e651 0x060a92b8 0xa4f49f4d + 0xc7c0ca50 0x2cd3f097 0xe3c17f26 0x27829941 + 0xa926e7aa 0x5cfb05e3 0xdda38aa5 0x12fba6d5 + 0xf5d38006 0xa4dcc602 0x90fa19cd 0x5208a021 + 0x4e6e0b95 0x4c696856 0x794122e8 0x658b7743 + 0x2ab700ad 0x7f2ce02b 0x9e259629 0xee838708 + 0xbf0945f8 0x525bf0d8 0x3ce6ccf6 0x67d22cc0 + 0x24a32074 0x54abcf28 0xabcb8c9d 0x30b3df6a + 0x2518959f 0xa5f21be7 0x5af09abe 0x91bb6790 + 0xb474e40e 0xb67fa1e6 0x3789ffbe 0x4f808a4b + 0x2d70fab0 0x5458b074 0x3e3fdf85 0x091ee070 + 0xe5d088e2 0x506a6d21 0xa328091a 0xbea43770 + 0x9ca05528 0x650234a9 0x5932c91b 0x7ab51c8b + 0xd4668113 0x49a6e8c3 0x3a807613 0xd4b62e04 + 0xab0b8bb9 0xa23c4be3 0xa7bcf146 0x6ea34277 + 0x63c9d14b 0xae6e4e26 0x4a6ae304 0x193ed83b + 0x209550e3 0xc70ed0bb 0x3aeaa361 0x5607a188 + 0xed9a2363 0xdd1cc1f4 0xd60998ec 0x459fe1d0 + 0x16b6d58a 0x7f9b3375 0xf74dc98a 0x57e31f40 + 0xefd20034 0x608d76b4 0x338c06d4 0x05715557 + 0x3d68419c 0xec023bc2 0xfa15809c 0x6f0e0765 + 0x8871c594 0x447ea663 0xc08a742c 0x4de9276e + 0x769320d6 0x6a1f6e8f 0xe9d3b478 0xc1d91d1b + 0x12f3a537 0xa305b191 0x3d047654 0xde6261a0 + 0xda6c84bb 0x73bb62e7 0x2475e6f4 0x16ecbcb1 + 0x10520b50 0xc6a7f842 0x8d7db27d 0x78b3a952 + 0x2cc0269f 0x4f79ef66 0x9504cac2 0x60afeaec + 0x2d4943ad 0x1182160f 0x5410b2b3 0x74327c0f + 0x477fdd8a 0x466762b4 0xf8e4b844 0x926b93d6 + 0xbc6d3e62 0x33c375ee 0x0e12f9e0 0x3aca1a8d + 0xf50be175 0xd6e2b8c9 0x4796b992 0xafe57204 + 0x0fdfb7fb 0x7e015e92 0x9d979955 0x4b03a9c3 + 0x921eb90f 0xeff5e17d 0x7847054b 0xc0ec64a5 + 0x63e1008f 0xaccac4f0 0x8754b078 0x7ff52527 + 0x3502ccb6 0x64f9999a 0xad7bff9e 0xd84012be + 0xa4532db6 0xdb87e6a3 0x7307e716 0x6d598ce7 + 0xa87205a9 0x6d47d9a9 0xd756ab74 0xf701c09c + 0xc0813658 0xd80ac732 0x5c6acfbe 0x82c37423 + 0xbdaf6b96 0x867c5370 0x409ac9e5 0x544cd011 + 0x479a471b 0xb2b971e2 0x44125af9 0x54d69d91 + 0x17265b15 0xd44bbac2 0x109f65f4 0x4a9050f2 + 0xda218c9d 0x8f275d18 0xeaff7ccb 0xd459e75b + 0x4bd9916a 0x28e4d9c9 0x3554d418 0xd60ce8b1 + 0xef7ab774 0xb02c630d 0xe728cb94 0x56ffbdd7 + 0x9511604f 0x7e00d15d 0x9ff8a47e 0x7fb74ea4 + 0xe3e6024f 0x5cfff36f 0x7c390544 0x85cc394d + 0x52cd7726 0xfbf45702 0x510d4677 0xe8c46711 + 0x79e6a1bb 0xb461ecd7 0xe16ffae6 0xf1b172d1 + 0xb3b1a4ba 0x2ebfb00f 0x79a5ecac 0x8f665d34 + 0x74b9e936 0x7ba09e1b 0xfb70abbc 0x0ebb98f9 + 0x2c67728f 0xb774168e 0x960495e7 0xecd6da02 + 0x5d2cf994 0x729fc24a 0xe83e8980 0xe774ee6e + 0x7712b563 0xebbb9180 0x02c30dd6 0xaa20e61d + 0xc0fe3374 0xd0afd72a 0xf19d2e36 0x0a48798e + 0x24689266 0x52307c40 0xa1e2e457 0x014eac45 + 0x49fd15ad 0x30b5c7b6 0x2dcd426a 0xfaa533fb + 0xf488edb5 0xded71dfc 0x1ae2f406 0x35003b15 + 0xe6d5bf4f 0x26c7b1aa 0x827f94d5 0x3500e169 + 0xf8bccf40 0xb83b9225 0x7bc55cef 0x5d8076f5 + 0x0e6a9bd3 0xb2cface1 0x38309276 0x77cc1580 + 0xa4071e6d 0xd47b3ed0 0x03bfae46 0xeef86e2a + 0xe51fdaf7 0xcbbcc82d 0xf5954473 0x150a2ed3 + 0xcbc1e0b8 0x7d58dc94 0x13d07d55 0x3a3a2ea3 + 0x5ca2bf0f 0x319a2c8f 0x38272e56 0x7f3b7d21 + 0x52e66e0f 0x6b2cbad1 0x949d61a7 0x8ad83584 + 0x48ca6c14 0x9e0de59f 0x99194583 0x8e622c51 + 0x853c9f3b 0x2c0f7bf1 0x798bd6bc 0x4bad991c + 0xa1892d2a 0xde08b2fb 0x0e876ab7 0xf7a82b48 + 0xf83fe855 0x1aac18cf 0xf8840690 0x1c8ea52a + 0x2db7c7f4 0xadc97264 0xb86dab98 0xec0fae75 + 0xbf52444c 0x402dc511 0xea5f22c1 0x77cefcd7 + 0xafdb49b1 0xa4c18768 0x29ffbe2f 0xc90cfa84 + 0x8629b9e9 0x9b41e9a0 0xe2860242 0xb9be707f + 0xffd2df36 0x6c354f82 0x220a933b 0x803f6cef + 0xf2875c62 0x2b7a0a9d 0x4a2274be 0xbfe8f046 + 0xc6197471 0xd1b2c191 0x753af019 0xbaf163d2 + 0x8393df4d 0x305c7812 0xf5d17c5f 0xdea91b4b + 0xbdd865fe 0xc8032ad8 0xe8ef689a 0xae170616 + 0x224145e7 0x6484988a 0x9e625ade 0x1ec705f6 + 0x2fda2c16 0x148c7ccb 0x49e95d75 0x0e2054a7 + 0x29cb7332 0x838814ea 0x85ef2298 0x39a7fe1e + 0x8b21d915 0x315252b5 0x3b60c26b 0xb308bfe7 + 0x720bd93c 0x3a6de0c0 0xd71c7a68 0x20419415 + 0xf831561b 0x94320e63 0x454afe0e 0xb2cc70ac + 0x94c12717 0x1b696868 0xbe1a8c2f 0xacafb3cb + 0xc7204793 0xeaf23e5f 0xab6fe98f 0x2583ea2c + 0x17f2a1ad 0xb28d5a62 0x817ceae5 0xc2bf6074 + 0x3289a241 0xf767fcc9 0x15c56960 0xda53f933 + 0x84c86004 0x5567fce7 0x5d1b5686 0xf8c1e64a + 0xc2febdc6 0x6441bee6 0x013238a5 0x09be697d + 0xe6108228 0xe6fdf690 0x3a37e680 0xbf684807 + 0x7d6e181b 0xe2f80160 0xa406b842 0x2272c304 + 0xa685848b 0x2ab570f7 0x6cda90f7 0xbd9bba04 + 0x686c91eb 0x5ae22138 0x2fa89051 0x07dd9c21 + 0x6dfc3a4b 0xcc3ae7cf 0x9e20695c 0xfa5acf24 + 0xee3c87f6 0xc736e104 0xcb9dfd87 0x243e59bc + 0xbe81368f 0x664a7a31 0xb7bbc5c2 0xa3031adf + 0x9f621080 0x4e52d86b 0x781d58c9 0x0bccf470 + 0x27a7b3b7 0xeef78402 0x4803e4cb 0x02faf737 + 0xd8e3732d 0xcf5d5faa 0x2ede8270 0xf45fd038 + 0x712e1f21 0xb0f8e4cd 0xa65fe47b 0x574e4af2 + 0x82f7299d 0x3c7292dd 0x028f6647 0xf5ab722a + 0x0501ae52 0x71d85f04 0xb8876f1a 0x041d4e9a + 0x5f2a3ba8 0x4dcc877c 0x3b2eb2d8 0x5af1ba3e + 0x524f155e 0x4bcd507b 0x740a415d 0xbe8f0a84 + 0x792416bf 0x504f6044 0x693794e4 0x05af375c + 0x5a821cdd 0x9d0cf7de 0x2dee7380 0xfdcc6958 + 0xeb3cc177 0x45214a35 0x0d861c57 0x978eb2b5 + 0x49e94ccd 0xb7d29807 0xbbe42aa3 0x9e8167b8 + 0x1b2e66ec 0x1a852558 0x8620667d 0x921b5744 + 0x600a76b1 0x9e8b2619 0x2181b026 0x10899021 + 0x13c5f172 0xbb350b83 0x2bf1e986 0x1ebb04e9 + 0x58620ea5 0x23cfdea0 0x65284dbe 0x06992ec7 + 0x7f4b532f 0x20b2098f 0x454cae81 0x70ed8811 + 0xa42aebca 0xcd865e43 0x46b92384 0xf8ef596a + 0x508d9263 0x624be2cd 0x64beabc8 0xe5e5600b + 0x0b6fe12a 0x3bd2ecee 0xcb1d6cb9 0xaa99c074 + 0x602cfb7f 0x2a28fa52 0x1c6574ba 0x9a009599 + 0x830a9a44 0x76f3dd0e 0xa2d78afa 0xf0b6883c + 0x4534bde2 0x47e7b5ad 0x33b0c245 0xb423127c + 0x11c3bcc6 0xc5030dfc 0xfa601a28 0xd6e50b74 + 0xec319421 0xd7b4cb91 0x187ac29c 0x5910b534 + 0xb6f7fabe 0xf1598095 0x13696fd6 0x72f461c0 + 0xc829c1b6 0x307e82e0 0x06384256 0x96ce68ed + 0xade3ccdc 0x36104323 0xc38d1b2d 0x454ece6f + 0x0b3278d8 0x45481d47 0x11831990 0x3c200a76 + 0x5bd1e628 0xb60d823b 0xcbb70d10 0x09eb86ed + 0x71dbe1dd 0x5e6679dd 0xef00e7d4 0x90b21b63 + 0x015ad65d 0x18bacb30 0x98d0a8c3 0x548763f1 + 0x9e49b9d1 0xf44c0f8f 0x37343354 0xe6aea119 + 0xe2b4d264 0x2101d1e2 0xa674fc40 0x60be0419 + 0x1995c56d 0x6a231e92 0xd83fe708 0x3170fb0b + 0x4dd1d6e1 0xcf2add9e 0xcc7409f1 0xea7cd1ed + 0x983ff1c7 0xbae461d0 0xa57a6e96 0xca14aaf9 + 0x9307fe68 0x74b6b4d0 0x24b8a949 0x20d58cd6 + 0xef967871 0xa1864325 0x8d3b3aa0 0x34c0c597 + 0x5933d062 0x5449ac36 0xbf87ecc2 0xcd9b43a2 + 0xbaac5a4e 0x213e841a 0x924a5d57 0x427df332 + 0x58bc9ffa 0x47e1b043 0x5310fb39 0x1a5a8bff + 0xa960e1d3 0x8d920e63 0x51947394 0xffce6986 + 0x1219fc75 0xd525a15b 0x4954cd1d 0x090dac8c + 0xe7d67af8 0x61fa6500 0x580dce5a 0xd8b20392 + 0xebbabad5 0x902261ce 0x4709c45f 0x63f5f093 + 0x0c7ffec4 0xd9c42362 0x266635ee 0xb4d8ee7f + 0x4babf6ac 0x142fbe80 0x8c94361e 0xb441f02e + 0xc978eeab 0x4e2c656f 0x2a452c50 0x00bedb56 + 0x38f35e33 0x492cc875 0x5e426089 0xe20991cc + 0x05cb9776 0x80f82aca 0x3e707b20 0xe721d768 + 0xb9e11d21 0xc7b04197 0x702dffa5 0xb5d5278b + 0xf7ddf55b 0x34cb4625 0x72d7cc6f 0x01688b83 + 0x8dd7047b 0x136c28f2 0xf6b3f268 0x86aa4890 + 0x5b79b88c 0x6a749bc3 0x52e72956 0xe4681dce + 0x9ec89494 0x6b228a12 0x07f4b0f4 0xf9b32627 + 0x638477b0 0x67039726 0xf7662076 0x2f79edcb + 0xf691df67 0xca13f6df 0x57ccc011 0xec962324 + 0xef8cc24a 0x9d8025e7 0x2ca7bbc3 0x75d2b72e + 0x45551507 0x13afd42d 0x2e5003aa 0x023f6fb9 + 0x45864fa5 0xe48b0b3f 0xe3a94f23 0xd8fb7368 + 0x1c137c50 0x171d5dd7 0x8261a5a0 0x1ba63136 + 0x5d5b5de0 0xe125ea1b 0xf7cc2fdd 0xf72cd01f + 0x1c01f682 0x1efcc842 0x0c86c3ef 0x8e957708 + 0xeff24ee4 0x6d8bda6c 0xf98a33eb 0x86de2648 + 0xfeb7c7df 0x3fc9a0e4 0xaed7115d 0x9312ab35 + 0x0bd819eb 0x7fbdf8d7 0x4845b6b2 0x7b6a68a9 + 0x858dd4a3 0x8af681ce 0x46b01189 0x547fd68d + 0x68048d4f 0x918d68db 0xeabf798a 0xe375db3d + 0x2c1c3349 0x57d2742a 0xce4e3580 0xf1d6e7e4 + 0x0613fcf1 0xca597b8c 0xe2975483 0x37911e0b + 0x2df46d23 0xfb44f535 0x6f91f170 0x61bb2bc6 + 0x40abe763 0xca0800ed 0x6836ff32 0xd7caa95c + 0xd4b3e671 0xa199d337 0x508f50fb 0x236d15b5 + 0x6ba5516b 0x5a3d2cc2 0x72773aa3 0xc02e0100 + 0x2d693ca2 0x8c7197ce 0x4ff237c5 0xfe5f5425 + 0x6c81fad4 0x37ed5bff 0x4e6f15f4 0xb96632e6 + 0xa350b4f6 0xb794f156 0xf1a9ef94 0xb8b34906 + 0x796ff8cf 0x18004a47 0x2875881c 0x08aa0f18 + 0x0bdfdb68 0x37b5e1e7 0x9a06dfea 0x89c3396e + 0xb9a623cd 0xc5291de0 0x393d8116 0x89456f9c + 0x326340ff 0xdc5a0662 0xc2b26cfd 0xda691e6d + 0xe265c5a6 0x63d5b9f9 0xb6274b70 0xb6bfe1b3 + 0x759a6ee7 0x74ba0ff7 0x0cdffed3 0xe79eaa32 + 0x6d37a3ae 0x9e656661 0x99053f18 0x92c076f2 + 0x85d91c1a 0xe5f6ae78 0xc761684c 0xa2ed58c4 + 0xc5964ed2 0x25e05c62 0x4a7ede6e 0xcd6e604a + 0xaf2f625d 0xc514851c 0x23a8c422 0xd25fce42 + 0x6523c5dd 0x28e5f64d 0xeee3c3df 0xf86fa271 + 0x7585b65e 0xf18c6af3 0xbba32377 0xd6c36b69 + 0x4f06af8b 0xb98470fd 0x8ac7168b 0xa47e8caa + 0xd571a01b 0xf396a7a2 0x946eb1ca 0x9e41594c + 0x57d98825 0xfa266a98 0xc551ead4 0x0e2009b0 + 0x8f6214a9 0xc62f8b07 0x047ba2ae 0xcf997f73 + 0x464fd77d 0xbe6c485d 0x1e3c74e6 0x4785642b + 0xc9e9a42d 0x76018169 0x93da5ea7 0xa063d26f + 0xaefb0000 0xc1bd9b29 0xfd5ed7d2 0x5051a64b + 0x6212f993 0xdf87ef10 0x4405d858 0x6910bb52 + 0x05b44e71 0x1d8842d3 0xab9b8e17 0xe17f232c + 0x641fcf89 0x2316f0d9 0x2bff7423 0x9b4d59a2 + 0xf295feb7 0x3cb1024b 0x82d0d328 0xb219bef9 + 0xe04e5fb4 0xd0cd21c7 0x64c5a3d9 0x5df4b44c + 0x7c00ca01 0xd77a4d8e 0x4e816b03 0xf484574c + 0x115f09d5 0x1558368f 0x9b85f29e 0x0ecef9c4 + 0xeeeace91 0x3a32e3f1 0xad6fd9b4 0x20218447 + 0xa8aa5edb 0x1e106896 0x55de81bf 0x4ba7de0d + 0xa29a7747 0xf0cf718f 0x24180fc2 0xd3479f2b + 0xf659a715 0x01c8a481 0x5ebd565a 0xe3e0ee05 + 0xd4a19a92 0x8da0ae83 0x0946583c 0xf476c4de + 0x73042c0f 0x3810abb3 0xe71f9178 0xd6216e7d + 0xa2e15141 0x60e16159 0x38dcbe11 0xdc7d94a5 + 0xca8aca02 0xf5a25c1a 0xdcee90e1 0xcc07c633 + 0x27335ecd 0x115b0d2b 0x9adf0cae 0x5217dc1d + 0x3a328e6c 0xe7e3a325 0xcdb462a1 0x5c6df940 + 0xff1b85b4 0x148e76df 0xf0f019f5 0x5b5ed08f + 0x81153295 0x8555f5f9 0x764b7fdc 0x9dbb1e79 + 0xd81b8a8e 0x31e15324 0xf2b2b9d4 0x250fb6fe + 0x024bc486 0x0a39cbe5 0x4a009e01 0x3d039af3 + 0x76584b95 0xf984c46c 0xdab55b85 0xfaf909cc + 0xa4dd648b 0x04c4d4e3 0x872cd921 0x991dd11e + 0x7c4e8cde 0x477dabf2 0xa13bc54c 0x4e2dbcd8 + 0xea653454 0x01be58c0 0xeb6b81ed 0xb8e4d5c9 + 0x2e3a2ac1 0xff58c51b 0xa35c4875 0x42a6f09c + 0xbd997a7d 0x3c9a6d81 0x6d75c824 0xc2fde143 + 0x260dde42 0x111b58b7 0x5f259651 0xf5527705 + 0x43daca8f 0xf4fe9245 0x1fadcc67 0xd54c4b80 + 0xfcaa9de5 0xa207430c 0xa52c92ae 0x1ae04f5a + 0xf3993163 0x20468e5c 0xb325903d 0xfe60e527 + 0xeb3347d4 0x66ad072e 0xbdfbe6ea 0xc6f0171e + 0x4dea59ec 0x4a01e1ff 0xabb7691d 0x89dbe8ce + 0xe9f9515c 0x85dcaed3 0xe868b802 0xe6066418 + 0x3ad4d194 0x8a9b45ec 0xec668458 0x99988d97 + 0x8a2d5d09 0xa5e51bff 0x4ba2ab59 0x49d0f9cc + 0x32d4a755 0xe551a53f 0xe2ed3333 0x479af375 + 0xd59594e2 0x5b1aa2e5 0xcda9d597 0x4eafaf23 + 0xe2a61fcb 0xf1780210 0xc60d11d6 0x6a25a2a8 + 0xe6305341 0x6331cda0 0xe6b3a15b 0x81ccdaf7 + 0x70e54639 0x0147644d 0xb5ca5a68 0x3c6168f8 + 0x4ce074c9 0x28953351 0xaad39e3a 0x0c24286d + 0xfbbef853 0xbd6f478e 0x627ac1a4 0xbbb7d44e + 0xad3678c9 0x6d0db7b9 0x56a5c724 0xe63e302f + 0xe2a02a28 0xdb003a7f 0xc88a818d 0x349057e9 + 0xe7a28419 0x679d27ac 0x9a61215a 0x4987ed3a + 0x84d0082f 0x7d559771 0xd3ab253a 0x3d83b384 + 0xad86d59d 0x478b5fa3 0x1d0d11d3 0x61906eb4 + 0xfb4c8891 0xe447f821 0xf4d03e53 0x16194205 + 0x7553bf46 0x874ff696 0xb7519161 0x359a88de + 0x35768f21 0xc11a5205 0x25ac1ec9 0x562f4bee + 0xf8b5882d 0xacd9a2c0 0x57b17858 0x6485acfb + 0x06689873 0x2a9e033f 0xe83fb32a 0x7dc7bd8e + 0x6729bdc9 0xdfcecd9f 0xf464a795 0x0933f763 + 0x5484381a 0xfde55308 0xd5873742 0x2815e570 + 0xd5683ccb 0x622013bc 0xd6448119 0xfb39a031 + 0x17ddcb28 0xfa3c25d6 0x89e85bd3 0x6ddaea10 + 0x72f069a6 0xfa0010bd 0x599bb07e 0xceca10dd + 0xbff501be 0x96c6ed9e 0xa9d7785e 0xe377c74d + 0x7975e7b6 0x60cd7237 0x319b5753 0xa4b0198a + 0xb3f538fd 0xdb4fcc57 0x477cb507 0x13426540 + 0x10dba6aa 0xc9b14d8c 0xcb7f9771 0x773a080a + 0x7a67c398 0x0453e8e2 0x481b6b2b 0x9b3d793d + 0xe6889300 0xd47e53cc 0x78351de6 0xf1283909 + 0x132c54ce 0xfbc09021 0xf64207e1 0xec78babc + 0x5374b333 0x66a11168 0x006b8471 0x7992bc23 + 0x3e2ea4bd 0xf02a3524 0x25a2f444 0x1b4f081f + 0xdeff4ea9 0x061c2180 0x6c5de083 0x80f1db87 + 0x4496af2a 0x82c83438 0x34fc2256 0xc393b9c3 + 0x64de0032 0x9fec15b3 0xe981e3e3 0x251c6b01 + 0xfcbc4d29 0x97566352 0x90572893 0xa881f1e4 + 0x17fea149 0x1dcf992e 0xf4eb0b19 0x545ea3d8 + 0x5d4fc630 0xf564e3e5 0x038a135a 0x7869427e + 0x3986f63e 0x823abc15 0x42c9ecff 0x8656f8c4 + 0xa3513afa 0x94c02c0f 0xe2cbe687 0xb52bb2c9 + 0x41d689ed 0x3009e7e0 0x0e1231fb 0xc18608ec + 0x9ecf30c8 0x4f2acf57 0xb96466ab 0x771dcb5d + 0x6204b02c 0x9c8c464c 0x3e264f8a 0xa7c78a3a + 0xeaa73f22 0xbd171d59 0xd174abeb 0xa3b3a70b + 0x312c9ddd 0xa5ff4790 0x0a4ca492 0x9183ac0d + 0xa8635dca 0xdd377271 0xd46cf9ce 0x90b4095c + 0x38c982d5 0x85fb703d 0x16568137 0x95655d52 + 0x35571d35 0x15512332 0x79298134 0x4d303bda + 0x7ca35ddc 0x7c8ed239 0xc9338313 0xf0441879 + 0xbde54dad 0x9124c807 0x31472068 0x4cde4ec7 + 0x2d8d5493 0xf869f563 0x54dfdc4c 0xa98bf4af + 0xa98329b3 0x7b24af0d 0x843aa574 0x04c4f25d + 0x0c0740d7 0x966f3609 0x06da1093 0x9a250f63 + 0xd3af5750 0xdd07d38d 0x287cc6c7 0x6303340c + 0x6d04ed19 0x4ea61c81 0x3c579dc9 0xee249503 + 0x0960cd68 0x93cbdd8b 0xd5275e5b 0x15c1e2f2 + 0xfbfa5058 0x3d0f40c5 0xb1246e71 0x78231f1b + 0xda2621b9 0xb5e00b75 0xe998bc67 0x22309d27 + 0xe9704724 0x2fb68444 0xf9246baf 0xa998cf83 + 0x162a05f5 0x2ec3ffcd 0x2aeedfb2 0xc13ec87e + 0x45fcc3d5 0x0341705d 0xad0868c9 0xa07484f4 + 0x7c6e2fc2 0xf5bd829f 0xa23f047b 0xc72cfd16 + 0x6f14d642 0xf6d1a959 0x84f164ac 0x22f6021d + 0xc3cbaa9b 0xac2fcf81 0xc010d276 0x7f66a783 + 0x99d2d962 0x4653a56d 0x9e4417a2 0xc5df758b + 0x81b9f17d 0x8093c9df 0x1210ba7c 0x74479db3 + 0x70052b2e 0xf42615d1 0xa9ddbbe6 0xb474f7b2 + 0xff957756 0x5db2f22c 0xfca35900 0x3e0767f6 + 0x3eafdfce 0xadc39c53 0x8f0d0d2d 0xfc65f56d + 0x8d4ce235 0xa0e0b499 0xef44c5c9 0xa290e917 + 0xcd04f4d5 0xb2366959 0xfbab2931 0xb8dac162 + 0xf4bae7bb 0x7490170c 0x78a77eb1 0x04d33bda + 0x5c5b469d 0xd3458203 0xbc8e3645 0x9dbd6aef + 0x3ea1200a 0xdcb3dfa5 0xf79253a6 0x96879823 + 0x7a36d353 0xe16cd8a8 0x499f9bbc 0xc4099d6e + 0x74aa576f 0xa48c98a5 0xed25a004 0x324f5bfd + 0x5193ce4b 0x956bd528 0x38a9b924 0x98769348 + 0x1853a48c 0x9b3ae261 0xd71c1d95 0xe3fb6d5f + 0xf309081c 0xc5ab53ca 0x880c3fb6 0xa0fa0e16 + 0xbda16d70 0x3756710b 0xe8ee72e7 0x8da6aeaf + 0x49a7480e 0x59047188 0x2d5867fc 0x18e1f83a + 0xb98fc7d4 0x7e2305df 0x993cac23 0x5f5e19c6 + 0xa8aef4c8 0xc9ecb131 0xa040a339 0xb3945d85 + 0xeb429c99 0x527d61d7 0xa195d665 0xd1b681b2 + 0x42483ab0 0x89565bbe 0x44fe8885 0x255681e4 + 0x031684f4 0x01ce8260 0x69f25ac1 0xfd6141f4 + 0x169c543c 0xdead3786 0x6136226e 0x1fb88eb8 + 0xacc53c39 0x789959c3 0x6dfa8e26 0x49279437 + 0x634c1535 0x0175dca3 0xda399d3e 0xcd32949d + 0xcf09988b 0x9a010c05 0xd243ac3e 0xe74153b6 + 0x2af59e1a 0x115d4ffc 0xd395afa4 0xd4181746 + 0x5b8e60d7 0xb346ca14 0xac1ea235 0x52958a1a + 0x115115f2 0x455fac5e 0xc2bbf260 0xa864b1ac + 0x13fc88a4 0x9d91335d 0xb1cc7892 0x29c1eead + 0x73e9af84 0xda7621f8 0x84b3cfd4 0x9e2511ff + 0x6dc3fd01 0xba1632cf 0x147f2479 0x837fc832 + 0xe7202e3c 0x2e930e33 0x9ea8d482 0x9f5dd350 + 0xb06f2280 0xdfbf7d28 0xe31d9046 0x5ccd7499 + 0xa62388c4 0x5431fdb7 0xd3416108 0xcfb8c604 + 0x662f2db2 0xd7a56d3b 0xe8fd9a56 0xe4e57946 + 0x53481142 0x24916322 0x6c250fa9 0x24c851f3 + 0xe609cf4c 0xf7a0ee06 0xafcbd580 0xcd9e7379 + 0xcfe264dd 0x8726c1e1 0xdb3ddfe1 0xe7473e3e + 0x20fd7976 0xada2c111 0xf80dadbd 0xced0cec4 + 0x912cf624 0x2eaef48b 0x0fc034e8 0x6f2619d3 + 0x03fe697e 0x0c04b81f 0x38d17ce4 0x78a26b60 + 0xf9d09332 0xdfefe718 0x04041131 0x9e1e8100 + 0x98d8e870 0x211572af 0xf56c4b37 0xc70b1e44 + 0xd77e6579 0x33746b16 0x8c11a7e8 0x9eec2278 + 0xc7bc3cae 0x4c612876 0xfc5d327c 0xbb4c119b + 0x0c2d7e1a 0x8a92e750 0x0b06548c 0xeeee8880 + 0xa754ba28 0x547fdcf2 0x7b18b9cd 0xa93a0a15 + 0x2580071a 0x159f74d1 0x48d96771 0x3a0aee41 + 0xcfc016e5 0x120c5807 0x86bb365c 0x6f3f24c7 + 0x0d631f63 0x7d1b0b17 0x35c55629 0x7d9ebe26 + 0xf44f290e 0x766b236d 0x591a3b3f 0x995421ce + 0x5a349d56 0x2d17ee9b 0xb6c593e3 0xd43ab9ae + 0x7f485a47 0xb9a8f692 0xc8293101 0xff11133e + 0xb3e1b6d2 0xa413089d 0x7dbb2681 0xfaab0054 + 0xeb2ff101 0x04c2f766 0xb18ab18a 0xa1c43f80 + 0xd4224d92 0x119a3d41 0xee86ee70 0xae41a280 + 0x17b7ee57 0x090dc654 0xc74e84ef 0x955949af + 0x0333c342 0xadf3b86d 0x6271c4d2 0x3c3fd253 + 0xc24b6328 0x51a34fa3 0x0d898afc 0xd840baa8 + 0x39786d1d 0x206f0deb 0xece3e07f 0x38347ec5 + 0x1cd9e78e 0xf2cf3926 0x4b5a49ca 0xddc6a83a + 0x70e044b4 0x18fde019 0x711291e5 0xa5471bfa + 0x0e480499 0xf314286a 0xa889ece2 0x17a883ba + 0x5ce5b6c3 0x434698a9 0xb5942f8a 0xe997526e + 0x2e196486 0x0b246e6e 0xa6f9f7b0 0x5178bf49 + 0x951e67bf 0x65163ca3 0x0ceeb60f 0x619396ca + 0x7b0e9be5 0x018a7496 0x5fe43c40 0xdc46b25b + 0x7c1b755c 0xe169c1f9 0x60b9c194 0xc034f3d7 + 0x71ba48c6 0x191e34b7 0x967f6699 0x87d6f3bb + 0x4fea2e42 0x26806806 0xf29543b9 0xb7ae5c20 + 0x2d74fdd5 0xf7ae30be 0x875d57ec 0x0ee41c68 + 0xdc2e0b53 0x7528d325 0xf3664f15 0x1284283e + 0x52cf5dc6 0xe0de6b71 0xa1d4fd3e 0x6bffbfbf + 0x5d93c250 0x2909d669 0xad2b406c 0xaf314ead + 0x852db637 0x6f0dafaa 0xf0ba2e9c 0x5fab0466 + 0x293a53a3 0x150984ba 0xc80dac3d 0x0b7dd33c + 0x15aab949 0x3133af0e 0xbbb3cf96 0xa39df37e + 0x11363a9e 0x1026a7ae 0xbe3aa2e5 0x779e2367 + 0x8c85b28f 0x5f4fc644 0xc54c3fe3 0xc1efd114 + 0x493b3c46 0x57abca20 0xabb5d901 0xf5221b2e + 0xfe5c08e1 0xb4846d5f 0x3cc519bf 0x65cdd341 + 0x1e1722fc 0x58e1f060 0x67f4713b 0x3c3e5d70 + 0x6ae713ef 0xae232c4b 0xd19a8b3e 0x3ea2fe70 + 0x69cbbf74 0x84fbb46b 0x530cbab6 0x6c12523b + 0xe6a5ebb1 0x2c15d4e8 0xa9f829f8 0x061f11df + 0x3dd1c897 0x40e5b02e 0xf1bd2be9 0xde3758ef + 0xe74c4808 0x50647c58 0x73300e24 0x9be02b67 + 0x93db91c5 0x938394be 0xe309f7af 0xbb022fb7 + 0xb09a2334 0x4dd2eb10 0x205a418c 0xd4fc8abe + 0x05a37404 0x25875994 0xf811006a 0x6a5d7960 + 0x2e5c7407 0x1e6e5b52 0x6c8ea60d 0x10c4b0c9 + 0x6c6cfa35 0x988fcc09 0x51380a2f 0x4d5c5997 + 0xe22ae730 0xa105fa6b 0x7fe20fb7 0x147f6b40 + 0x7081a1d2 0xb09a7b60 0x2d5d50d5 0x79c546b0 + 0xb737523d 0x7eed21d1 0x96f66b37 0xd8c8ba27 + 0x7d16f558 0x48fd7c58 0xb5686869 0x786ab404 + 0xc9d54949 0x8c349784 0x216da4c3 0x5962a0f1 + 0xb140a6dc 0x5392328d 0xb3a47a23 0x3b585597 + 0x5a17d197 0x1e4d1038 0x0dec4861 0xb8d1ccd7 + 0x43be86b2 0x21b19259 0x254d4249 0xb9bb43ab + 0x948f120c 0xb3bcce67 0x6982d4ba 0x7c99716c + 0xd678c67b 0xb68a5c5e 0xf210aa0f 0xb3cbcfca + 0x50cc9f3f 0x79411663 0x75640c0c 0x218bc638 + 0x5d3bcb6b 0x397d0471 0x7e230dd3 0x411c5de1 + 0xaa6e32c2 0xfb7d334b 0xe26da740 0x08177310 + 0x614ffa51 0xd97df8ef 0x3da82027 0x1d4506c4 + 0x370e72ba 0xe8c53a4f 0x5e98e661 0xf862b904 + 0x7454fa0e 0x55cd72a6 0xc325981c 0x86964393 + 0xc5a4994a 0x6febc006 0x3ad46d49 0x07887add + 0x85467cf0 0xd5a4e16b 0x2263e16b 0x409eb91f + 0x16850708 0x59a84204 0x2ca0eeae 0x1d9f8297 + 0x5a798b91 0xeababa35 0x3eec48d5 0x38ab83ac + 0x54a4e800 0x1a639dcf 0x97fcbe2e 0x37b4eaea + 0x336897b3 0x1f8b6bd4 0xe8e75259 0xcb84e61f + 0x5447eff6 0x2d1a79a0 0xd4eddfea 0xd00a51e1 + 0x3fe09b2b 0x082d621c 0x803ef4a8 0x907fd068 + 0x0f004ca2 0x06586b32 0x114f062b 0x8695dbb1 + 0x2cd04b93 0x8b5f6611 0x44e20bd6 0xcdb157ed + 0x460cb121 0x9d2a78eb 0x445651ec 0xb7e28e8c + 0xe7873eda 0x1c4bb823 0x3987fe30 0x9260db87 + 0x9e48f941 0x8483c669 0x99c57df9 0xafe87033 + 0x1a0e008b 0xa365c3b9 0x1b9c2766 0x77f59bd5 + 0xeebaf899 0xdc58e157 0xeb8f6c97 0xd391dd2f + 0x43585717 0x52c9ddde 0x6f75c456 0x56875e7c + 0xa62a9ee9 0xdb8512af 0xfadf9ae4 0xb06622db + 0xce2874f0 0x72f71025 0xfd30b53c 0x363480c2 + 0x73d949de 0xb4b4a51d 0xd47377f9 0x7f1c60d4 + 0x61b71d19 0x914169a0 0x90726664 0xbddf5b56 + 0xca2e404d 0x83d911d4 0x8b9e8aee 0x93de56f6 + 0xefd8a1b5 0x063da123 0xc32325a9 0xdff4070b + 0xf8d332ca 0xbb5631e7 0x0d72d895 0xae6536cf + 0xb720dc2e 0x3267a20f 0xb3a65513 0xef0259de + 0x6073f44c 0xfe28a197 0x44354e41 0xf3877d1e + 0xbe31989a 0xad7b9d10 0xefe9094d 0x6cf1203c + 0xfd836cb8 0x2d72e93a 0xd586d005 0x47544bf8 + 0x6eba36e4 0xfaf1ed00 0x70b31a7f 0xf61de020 + 0xb394055e 0x8f6ba193 0xff117ce2 0xaa5df73b + 0x7ef7f2b7 0x892894eb 0xcf0d3758 0x40b3cd6a + 0x736ae2eb 0x4e704410 0xf1e0120a 0xeee9b92c + 0x51d98895 0xdf7d90fd 0xd964bb67 0x94608454 + 0xd3f2a01c 0x6591312d 0x9c10b22e 0xe2cd787c + 0x2171327c 0x9ccf1a68 0x1c631c38 0x388fddc8 + 0x23da128c 0xacaf8103 0xe740d8da 0x6f198b8b + 0xdbd4fb1d 0x4968f908 0x1d61e189 0x0d47b75e + 0xd7d78539 0x6c73fdca 0xa04b447b 0x3f68a675 + 0xedf244e6 0x7a68d0aa 0x07209716 0x211cad30 + 0x352331ef 0x63932a02 0xc1c5af9f 0xce932a20 + 0xee73803c 0x46e9accf 0x4bd7ad2a 0x54bb1661 + 0xdb10d4d7 0x914f03e0 0x8b0bf04e 0x24b7567c + 0x9ef64615 0x70dd716f 0xf5f298ae 0x2218f373 + 0xa1d2aabb 0xb72a21e6 0x111ad091 0xffa57188 + 0x962efef9 0xdce7b034 0xe12d6a21 0xd290a7e6 + 0xa6ee6ab8 0x74d46670 0x5aea6278 0x14dffad3 + 0x60329958 0x6d95d68c 0x6b59999a 0x80ea1f16 + 0x7b816c1e 0x053eaae0 0x808877e7 0xdce419e6 + 0x403a28fa 0x477fed42 0x2480777c 0xb7785739 + 0x1d59c924 0xa7e8e142 0x9efbc2d5 0xb82808e8 + 0x806d54cf 0xe64d2c08 0x9494b0d6 0xec78f0fd + 0xc3beba08 0xebdfdff3 0x924fe3ab 0x8ee535ad + 0x01258771 0x5392e4ae 0x825f0e60 0x3bf41cd6 + 0xb4e9b480 0x89cd0e08 0x5b685dba 0x4fde0c10 + 0x19fd913e 0x54de85bb 0x5d1aec47 0x6753c2d0 + 0xaac97246 0x50f375ca 0x0a675816 0x4e117cd8 + 0x343b6a0f 0x5698df73 0xd0539647 0x5c5faa01 + 0xdbf32a26 0x3a253a82 0x54186e46 0x583c0d5f + 0x1a2ad36e 0xd645fb14 0x706a19ec 0x134c40ba + 0x8875c39e 0x8b583b19 0xc8aa626c 0x6018f07f + 0xf4a7cfbf 0xde62fb7f 0x9c59be93 0xe00402cc + 0x30df55c5 0x2ef3001b 0xcbcdf288 0x770a9dfa + 0x1886b563 0x16971e68 0x49dfa90f 0xb9ddb0ea + 0xeea0426e 0x7d2d0829 0xfcb13e15 0xa6e618c9 + 0xb024d686 0xe19cf395 0x96c81494 0x9f75e130 + 0xcf381ed5 0xae054722 0x99613f82 0x5ccb2f89 + 0xca5fa36c 0xc35748e8 0xfb7cc7fe 0x9e3b5fb7 + 0x224fe96c 0xb67737ab 0x61a1c0c9 0x5a9b39b3 + 0x848b5ed7 0x6a5f39ab 0x13d2481b 0xd0ea612f + 0xc5d17885 0xe57789cd 0xcba8a318 0xe43fd3ac + 0x13b454e2 0x50102618 0xcf046014 0x69601090 + 0xa0ec1a47 0xa7db9e59 0x88add3f5 0xb2b82216 + 0x3c2a6a7f 0x15eea60a 0x9a00d090 0xea63733c + 0x7d317b24 0x08a914de 0x9b17cfbe 0xfed02775 + 0x59f09ba8 0x8074cf9d 0x57ab22b6 0x14e4868c + 0xb5854fd1 0x4d2c53ec 0x7b622ff4 0xfc29077b + 0xa2f7e260 0xfa978f24 0x3b7897bd 0xf45dcbb3 + 0xcc72ae95 0xdfbf2875 0xeeba4b54 0x2a4feb10 + 0x0bae1384 0x9bd07656 0x252ef6b2 0x9db74367 + 0x51b0216d 0x5c483bda 0x0f8e8eeb 0xc69db3f8 + 0x32cc1522 0x9d8a9bdc 0xaa4a31c2 0xe0b1bdb8 + 0xf24ce823 0x3a44a26a 0x267d7df5 0x4df12ff2 + 0x9482f5ca 0x147b78d2 0xc25c4d28 0x1217f735 + 0xf22c63c6 0x87b811fd 0xd41ce89c 0x8c90b884 + 0x4157cdc2 0x1742439e 0xab8856a7 0x1819942d + 0x5d8a70d7 0x1fb5207e 0x9058d58a 0xc78b784b + 0x20fda01e 0x7f816cc2 0x9f1c555b 0x1749477b + 0x8a118baf 0xa133adf1 0x9de1c2e0 0xd7789802 + 0xd3134b79 0xd3f54993 0x6eabfde9 0x663e74fd + 0xead073ed 0x6e51fcb3 0xe2a0bdc7 0x34485f45 + 0xe154b0fa 0xdd81169a 0x21974626 0x4efaade8 + 0x727937e1 0x247a7487 0x1536dc39 0x22325fc3 + 0x7e56e057 0xf34bf1b1 0x6b77bee0 0x118bb371 + 0x20a114a5 0x0702e1d1 0xa329e70a 0x83e5ef19 + 0x10f1f752 0xe0ae45c8 0x6ac475af 0xcb47e839 + 0x6459d01e 0xe8a47522 0x1f480fd9 0x6e0c6611 + 0xd6a9637a 0xf1b35f38 0x6ba628a7 0xf4416b14 + 0x497267fc 0x76ad7ddd 0x16efe4d0 0xd233f0b0 + 0xfaa51597 0x9d3697a7 0xb6909b88 0xc991a9df + 0xddc116c6 0x4cc6a52b 0xd15e6d12 0xb1563b55 + 0x3bb99d39 0x12371eab 0xa675583b 0x53287e8b + 0xe74070ec 0x340b4d6f 0xf33eb6b0 0x8e8c3ad6 + 0x35b4576b 0x43a1d05c 0x9198b643 0x159a622e + 0xde1c3cd7 0xd4647fed 0x84bd7e94 0xa4d0d67a + 0x14107be6 0x5d9f75a6 0xad1d6bd5 0x59c74b61 + 0x17212211 0x5cd5c479 0x9aba7a41 0x9c80f2e2 + 0x1dff7bc4 0x0566819e 0xf50213fc 0xd0350c46 + 0xf495b0b5 0x8c7a00f0 0xfa881cbf 0xb7cf571e + 0x0e59231f 0xb759f5fd 0x91ef47f3 0x58ee41dd + 0x9e65c3d2 0xa69d4ada 0xcafde4fe 0x5098e9b7 + 0x0f059288 0x605d1f4a 0xbd4914e0 0x6afaa6be + 0x3661622a 0xe9309570 0x08f002ba 0xe9ee73da + 0xc252f80a 0x3663b11a 0xa28797d0 0x88958ad5 + 0x1d8e5d1a 0x9c4e6ca2 0x431f1541 0x593c16fb + 0x9d5b62fd 0xccf1aeb6 0x23fcbe26 0x9a56b544 + 0x6cf42caa 0xd3fe2546 0xcbc80fc3 0xd9ca074a + 0xfb2c4a94 0x6ebc6cf5 0x7573610f 0x39340348 + 0x4c6de55e 0x89f3c9ec 0x5f614d03 0x9897c1c0 + 0x3ed97e01 0x522b7259 0x4d0264cf 0x14a5124a + 0x290bbdb5 0xbbee9d25 0xf77b9d44 0x1ec5e012 + 0x0c8cdc16 0x3955a4ff 0x1d97515f 0x2e38300f + 0x8e3fc3ee 0xc77c8545 0x864ac70c 0x8d284434 + 0x365a1b22 0xbcda59a3 0x770fa74a 0xa0056fa2 + 0xdbae9ad8 0xe8eedd38 0x5e31586e 0x0a1e34f6 + 0xb48ddc79 0xdf79f8e3 0xb2054bf4 0xba1163bc + 0x303e80e8 0xd2e8a56c 0xde97c1d8 0xfa2b2a99 + 0xe86f7090 0x7388aab9 0xa8f282f9 0x7800daed + 0x71e14e17 0xc9b64244 0xa85fdcd7 0x4693291a + 0x80f76ce5 0x6001086a 0xcc580b01 0xb8c71e6e + 0x1af096b3 0xc48de567 0xaa2e33fc 0x5bcb7fba + 0xa77b0012 0x1f176019 0x35c1e9aa 0xe175fbbe + 0xc4709fdd 0x5accf5dc 0x13262619 0xe10c57d9 + 0xf538e944 0x38175b54 0x1ecf81ae 0x41606deb + 0x7c3d899c 0x58adda6b 0x1a91c782 0x04201d47 + 0x1e99b49e 0x2df3d373 0xc32ed967 0xf0d3042e + 0x74cb3b44 0x298d582b 0xa2c41173 0x3c04031c + >; diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h index 0853248f80..9856fa6c43 100644 --- a/arch/x86/include/asm/acpi_table.h +++ b/arch/x86/include/asm/acpi_table.h @@ -390,4 +390,4 @@ void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs, void *dsdt); int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi, u8 cpu, u16 flags, u8 lint); -unsigned long write_acpi_tables(unsigned long start); +u32 write_acpi_tables(u32 start); diff --git a/arch/x86/include/asm/arch-broadwell/cpu.h b/arch/x86/include/asm/arch-broadwell/cpu.h new file mode 100644 index 0000000000..eb2046b867 --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/cpu.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __asm_arch_cpu_h +#define __asm_arch_cpu_h + +/* CPU types */ +#define HASWELL_FAMILY_ULT 0x40650 +#define BROADWELL_FAMILY_ULT 0x306d0 + +/* Supported CPUIDs */ +#define CPUID_HASWELL_A0 0x306c1 +#define CPUID_HASWELL_B0 0x306c2 +#define CPUID_HASWELL_C0 0x306c3 +#define CPUID_HASWELL_ULT_B0 0x40650 +#define CPUID_HASWELL_ULT 0x40651 +#define CPUID_HASWELL_HALO 0x40661 +#define CPUID_BROADWELL_C0 0x306d2 +#define CPUID_BROADWELL_D0 0x306d3 +#define CPUID_BROADWELL_E0 0x306d4 + +/* Broadwell bus clock is fixed at 100MHz */ +#define BROADWELL_BCLK 100 + +#define BROADWELL_FAMILY_ULT 0x306d0 + +#define CORE_THREAD_COUNT_MSR 0x35 + +#define MSR_VR_CURRENT_CONFIG 0x601 +#define MSR_VR_MISC_CONFIG 0x603 +#define MSR_PKG_POWER_SKU 0x614 +#define MSR_DDR_RAPL_LIMIT 0x618 +#define MSR_VR_MISC_CONFIG2 0x636 + +/* Latency times in units of 1024ns. */ +#define C_STATE_LATENCY_CONTROL_0_LIMIT 0x42 +#define C_STATE_LATENCY_CONTROL_1_LIMIT 0x73 +#define C_STATE_LATENCY_CONTROL_2_LIMIT 0x91 +#define C_STATE_LATENCY_CONTROL_3_LIMIT 0xe4 +#define C_STATE_LATENCY_CONTROL_4_LIMIT 0x145 +#define C_STATE_LATENCY_CONTROL_5_LIMIT 0x1ef + +void cpu_set_power_limits(int power_limit_1_time); + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/gpio.h b/arch/x86/include/asm/arch-broadwell/gpio.h new file mode 100644 index 0000000000..0ed881b72d --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/gpio.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * From Coreboot src/soc/intel/broadwell/include/soc/gpio.h + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __ASM_ARCH_GPIO +#define __ASM_ARCH_GPIO + +#define GPIO_PER_BANK 32 +#define GPIO_BANKS 3 + +struct broadwell_bank_platdata { + uint16_t base_addr; + const char *bank_name; + int bank; +}; + +/* PCH-LP GPIOBASE Registers */ +struct pch_lp_gpio_regs { + u32 own[GPIO_BANKS]; + u32 reserved0; + + u16 pirq_to_ioxapic; + u16 reserved1[3]; + u32 blink; + u32 ser_blink; + + u32 ser_blink_cmdsts; + u32 ser_blink_data; + u16 gpi_nmi_en; + u16 gpi_nmi_sts; + u32 reserved2; + + u32 gpi_route[GPIO_BANKS]; + u32 reserved3; + + u32 reserved4[4]; + + u32 alt_gpi_smi_sts; + u32 alt_gpi_smi_en; + u32 reserved5[2]; + + u32 rst_sel[GPIO_BANKS]; + u32 reserved6; + + u32 reserved9[3]; + u32 gpio_gc; + + u32 gpi_is[GPIO_BANKS]; + u32 reserved10; + + u32 gpi_ie[GPIO_BANKS]; + u32 reserved11; + + u32 reserved12[24]; + + struct { + u32 conf_a; + u32 conf_b; + } config[GPIO_BANKS * GPIO_PER_BANK]; +}; +check_member(pch_lp_gpio_regs, gpi_ie[0], 0x90); +check_member(pch_lp_gpio_regs, config[0], 0x100); + +enum { + CONFA_MODE_SHIFT = 0, + CONFA_MODE_GPIO = 1 << CONFA_MODE_SHIFT, + + CONFA_DIR_SHIFT = 2, + CONFA_DIR_INPUT = 1 << CONFA_DIR_SHIFT, + + CONFA_INVERT_SHIFT = 3, + CONFA_INVERT = 1 << CONFA_INVERT_SHIFT, + + CONFA_TRIGGER_SHIFT = 4, + CONFA_TRIGGER_LEVEL = 1 << CONFA_TRIGGER_SHIFT, + + CONFA_LEVEL_SHIFT = 30, + CONFA_LEVEL_HIGH = 1UL << CONFA_LEVEL_SHIFT, + + CONFA_OUTPUT_SHIFT = 31, + CONFA_OUTPUT_HIGH = 1UL << CONFA_OUTPUT_SHIFT, + + CONFB_SENSE_SHIFT = 2, + CONFB_SENSE_DISABLE = 1 << CONFB_SENSE_SHIFT, +}; + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/iomap.h b/arch/x86/include/asm/arch-broadwell/iomap.h new file mode 100644 index 0000000000..431bc23ef2 --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/iomap.h @@ -0,0 +1,53 @@ +/* + * From Coreboot soc/intel/broadwell/include/soc/iomap.h + * + * Copyright (C) 2016 Google Inc. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __asm_arch_iomap_h +#define __asm_arch_iomap_h + +#define MCFG_BASE_ADDRESS 0xf0000000 +#define MCFG_BASE_SIZE 0x4000000 + +#define HPET_BASE_ADDRESS 0xfed00000 + +#define MCH_BASE_ADDRESS 0xfed10000 +#define MCH_BASE_SIZE 0x8000 + +#define DMI_BASE_ADDRESS 0xfed18000 +#define DMI_BASE_SIZE 0x1000 + +#define EP_BASE_ADDRESS 0xfed19000 +#define EP_BASE_SIZE 0x1000 + +#define EDRAM_BASE_ADDRESS 0xfed80000 +#define EDRAM_BASE_SIZE 0x4000 + +#define GDXC_BASE_ADDRESS 0xfed84000 +#define GDXC_BASE_SIZE 0x1000 + +#define RCBA_BASE_ADDRESS 0xfed1c000 +#define RCBA_BASE_SIZE 0x4000 + +#define HPET_BASE_ADDRESS 0xfed00000 + +#define ACPI_BASE_ADDRESS 0x1000 +#define ACPI_BASE_SIZE 0x100 + +#define GPIO_BASE_ADDRESS 0x1400 +#define GPIO_BASE_SIZE 0x400 + +#define SMBUS_BASE_ADDRESS 0x0400 +#define SMBUS_BASE_SIZE 0x10 + +/* Temporary addresses used before relocation */ +#define EARLY_GTT_BAR 0xe0000000 +#define EARLY_XHCI_BAR 0xd7000000 +#define EARLY_EHCI_BAR 0xd8000000 +#define EARLY_UART_BAR 0x3f8 +#define EARLY_TEMP_MMIO 0xfed08000 + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/lpc.h b/arch/x86/include/asm/arch-broadwell/lpc.h new file mode 100644 index 0000000000..a718667400 --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/lpc.h @@ -0,0 +1,32 @@ +/* + * From coreboot soc/intel/broadwell/include/soc/lpc.h + * + * Copyright (C) 2016 Google Inc. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _ASM_ARCH_LPC_H +#define _ASM_ARCH_LPC_H + +#define GEN_PMCON_1 0xa0 +#define SMI_LOCK (1 << 4) +#define GEN_PMCON_2 0xa2 +#define SYSTEM_RESET_STS (1 << 4) +#define THERMTRIP_STS (1 << 3) +#define SYSPWR_FLR (1 << 1) +#define PWROK_FLR (1 << 0) +#define GEN_PMCON_3 0xa4 +#define SUS_PWR_FLR (1 << 14) +#define GEN_RST_STS (1 << 9) +#define RTC_BATTERY_DEAD (1 << 2) +#define PWR_FLR (1 << 1) +#define SLEEP_AFTER_POWER_FAIL (1 << 0) +#define GEN_PMCON_LOCK 0xa6 +#define SLP_STR_POL_LOCK (1 << 2) +#define ACPI_BASE_LOCK (1 << 1) +#define PMIR 0xac +#define PMIR_CF9LOCK (1 << 31) +#define PMIR_CF9GR (1 << 20) + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/me.h b/arch/x86/include/asm/arch-broadwell/me.h new file mode 100644 index 0000000000..a66a8bbac1 --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/me.h @@ -0,0 +1,200 @@ +/* + * From coreboot soc/intel/broadwell/include/soc/me.h + * + * Copyright (C) 2014 Google Inc. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _asm_arch_me_h +#define _asm_arch_me_h + +#include <asm/me_common.h> + +#define ME_INIT_STATUS_SUCCESS_OTHER 3 /* SEE ME9 BWG */ + +#define ME_HSIO_MESSAGE (7 << 28) +#define ME_HSIO_CMD_GETHSIOVER 1 +#define ME_HSIO_CMD_CLOSE 0 + +/* + * Apparently the GMES register is renamed to HFS2 (or HFSTS2 according + * to ME9 BWG). Sadly the PCH EDS and the ME BWG do not match on nomenclature. + */ +#define PCI_ME_HFS2 0x48 +/* Infrastructure Progress Values */ +#define ME_HFS2_PHASE_ROM 0 +#define ME_HFS2_PHASE_BUP 1 +#define ME_HFS2_PHASE_UKERNEL 2 +#define ME_HFS2_PHASE_POLICY 3 +#define ME_HFS2_PHASE_MODULE_LOAD 4 +#define ME_HFS2_PHASE_UNKNOWN 5 +#define ME_HFS2_PHASE_HOST_COMM 6 +/* Current State - Based on Infra Progress values. */ +/* ROM State */ +#define ME_HFS2_STATE_ROM_BEGIN 0 +#define ME_HFS2_STATE_ROM_DISABLE 6 +/* BUP State */ +#define ME_HFS2_STATE_BUP_INIT 0 +#define ME_HFS2_STATE_BUP_DIS_HOST_WAKE 1 +#define ME_HFS2_STATE_BUP_FLOW_DET 4 +#define ME_HFS2_STATE_BUP_VSCC_ERR 8 +#define ME_HFS2_STATE_BUP_CHECK_STRAP 0xa +#define ME_HFS2_STATE_BUP_PWR_OK_TIMEOUT 0xb +#define ME_HFS2_STATE_BUP_MANUF_OVRD_STRAP 0xd +#define ME_HFS2_STATE_BUP_M3 0x11 +#define ME_HFS2_STATE_BUP_M0 0x12 +#define ME_HFS2_STATE_BUP_FLOW_DET_ERR 0x13 +#define ME_HFS2_STATE_BUP_M3_CLK_ERR 0x15 +#define ME_HFS2_STATE_BUP_CPU_RESET_DID_TIMEOUT_MEM_MISSING 0x17 +#define ME_HFS2_STATE_BUP_M3_KERN_LOAD 0x18 +#define ME_HFS2_STATE_BUP_T32_MISSING 0x1c +#define ME_HFS2_STATE_BUP_WAIT_DID 0x1f +#define ME_HFS2_STATE_BUP_WAIT_DID_FAIL 0x20 +#define ME_HFS2_STATE_BUP_DID_NO_FAIL 0x21 +#define ME_HFS2_STATE_BUP_ENABLE_UMA 0x22 +#define ME_HFS2_STATE_BUP_ENABLE_UMA_ERR 0x23 +#define ME_HFS2_STATE_BUP_SEND_DID_ACK 0x24 +#define ME_HFS2_STATE_BUP_SEND_DID_ACK_ERR 0x25 +#define ME_HFS2_STATE_BUP_M0_CLK 0x26 +#define ME_HFS2_STATE_BUP_M0_CLK_ERR 0x27 +#define ME_HFS2_STATE_BUP_TEMP_DIS 0x28 +#define ME_HFS2_STATE_BUP_M0_KERN_LOAD 0x32 +/* Policy Module State */ +#define ME_HFS2_STATE_POLICY_ENTRY 0 +#define ME_HFS2_STATE_POLICY_RCVD_S3 3 +#define ME_HFS2_STATE_POLICY_RCVD_S4 4 +#define ME_HFS2_STATE_POLICY_RCVD_S5 5 +#define ME_HFS2_STATE_POLICY_RCVD_UPD 6 +#define ME_HFS2_STATE_POLICY_RCVD_PCR 7 +#define ME_HFS2_STATE_POLICY_RCVD_NPCR 8 +#define ME_HFS2_STATE_POLICY_RCVD_HOST_WAKE 9 +#define ME_HFS2_STATE_POLICY_RCVD_AC_DC 0xa +#define ME_HFS2_STATE_POLICY_RCVD_DID 0xb +#define ME_HFS2_STATE_POLICY_VSCC_NOT_FOUND 0xc +#define ME_HFS2_STATE_POLICY_VSCC_INVALID 0xd +#define ME_HFS2_STATE_POLICY_FPB_ERR 0xe +#define ME_HFS2_STATE_POLICY_DESCRIPTOR_ERR 0xf +#define ME_HFS2_STATE_POLICY_VSCC_NO_MATCH 0x10 +/* Current PM Event Values */ +#define ME_HFS2_PMEVENT_CLEAN_MOFF_MX_WAKE 0 +#define ME_HFS2_PMEVENT_MOFF_MX_WAKE_ERROR 1 +#define ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET 2 +#define ME_HFS2_PMEVENT_CLEAN_GLOBAL_RESET_ERROR 3 +#define ME_HFS2_PMEVENT_CLEAN_ME_RESET 4 +#define ME_HFS2_PMEVENT_ME_RESET_EXCEPTION 5 +#define ME_HFS2_PMEVENT_PSEUDO_ME_RESET 6 +#define ME_HFS2_PMEVENT_S0MO_SXM3 7 +#define ME_HFS2_PMEVENT_SXM3_S0M0 8 +#define ME_HFS2_PMEVENT_NON_PWR_CYCLE_RESET 9 +#define ME_HFS2_PMEVENT_PWR_CYCLE_RESET_M3 0xa +#define ME_HFS2_PMEVENT_PWR_CYCLE_RESET_MOFF 0xb +#define ME_HFS2_PMEVENT_SXMX_SXMOFF 0xc + +struct me_hfs2 { + u32 bist_in_progress:1; + u32 reserved1:2; + u32 invoke_mebx:1; + u32 cpu_replaced_sts:1; + u32 mbp_rdy:1; + u32 mfs_failure:1; + u32 warm_reset_request:1; + u32 cpu_replaced_valid:1; + u32 reserved2:4; + u32 mbp_cleared:1; + u32 reserved3:2; + u32 current_state:8; + u32 current_pmevent:4; + u32 progress_code:4; +} __packed; + +#define PCI_ME_HFS5 0x68 + +#define PCI_ME_H_GS2 0x70 +#define PCI_ME_MBP_GIVE_UP 0x01 + +/* ICC Messages */ +#define ICC_SET_CLOCK_ENABLES 0x3 +#define ICC_API_VERSION_LYNXPOINT 0x00030000 + +struct icc_header { + u32 api_version; + u32 icc_command; + u32 icc_status; + u32 length; + u32 reserved; +} __packed; + +struct icc_clock_enables_msg { + u32 clock_enables; + u32 clock_mask; + u32 no_response:1; + u32 reserved:31; +} __packed; + +/* + * ME to BIOS Payload Datastructures and definitions. The ordering of the + * structures follows the ordering in the ME9 BWG. + */ + +#define MBP_APPID_KERNEL 1 +#define MBP_APPID_INTEL_AT 3 +#define MBP_APPID_HWA 4 +#define MBP_APPID_ICC 5 +#define MBP_APPID_NFC 6 +/* Kernel items: */ +#define MBP_KERNEL_FW_VER_ITEM 1 +#define MBP_KERNEL_FW_CAP_ITEM 2 +#define MBP_KERNEL_ROM_BIST_ITEM 3 +#define MBP_KERNEL_PLAT_KEY_ITEM 4 +#define MBP_KERNEL_FW_TYPE_ITEM 5 +#define MBP_KERNEL_MFS_FAILURE_ITEM 6 +#define MBP_KERNEL_PLAT_TIME_ITEM 7 +/* Intel AT items: */ +#define MBP_INTEL_AT_STATE_ITEM 1 +/* ICC Items: */ +#define MBP_ICC_PROFILE_ITEM 1 +/* HWA Items: */ +#define MBP_HWA_REQUEST_ITEM 1 +/* NFC Items: */ +#define MBP_NFC_SUPPORT_DATA_ITEM 1 + +#define MBP_MAKE_IDENT(appid, item) ((appid << 8) | item) +#define MBP_IDENT(appid, item) \ + MBP_MAKE_IDENT(MBP_APPID_##appid, MBP_##appid##_##item##_ITEM) + +struct mbp_fw_version_name { + u32 major_version:16; + u32 minor_version:16; + u32 hotfix_version:16; + u32 build_version:16; +} __packed; + +struct icc_address_mask { + u16 icc_start_address; + u16 mask; +} __packed; + +struct mbp_icc_profile { + u8 num_icc_profiles; + u8 icc_profile_soft_strap; + u8 icc_profile_index; + u8 reserved; + u32 icc_reg_bundles; + struct icc_address_mask icc_address_mask[0]; +} __packed; + +struct me_bios_payload { + struct mbp_fw_version_name *fw_version_name; + struct mbp_mefwcaps *fw_capabilities; + struct mbp_rom_bist_data *rom_bist_data; + struct mbp_platform_key *platform_key; + struct mbp_plat_type *fw_plat_type; + struct mbp_icc_profile *icc_profile; + struct mbp_at_state *at_state; + u32 *mfsintegrity; + struct mbp_plat_time *plat_time; + struct mbp_nfc_data *nfc_data; +}; + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/pch.h b/arch/x86/include/asm/arch-broadwell/pch.h new file mode 100644 index 0000000000..3e346adfdc --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/pch.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __ASM_ARCH_PCH_H +#define __ASM_ARCH_PCH_H + +/* CPU bus clock is fixed at 100MHz */ +#define CPU_BCLK 100 + +#define PMBASE 0x40 +#define ACPI_CNTL 0x44 +#define ACPI_EN (1 << 7) + +#define GPIO_BASE 0x48 /* LPC GPIO Base Address Register */ +#define GPIO_CNTL 0x4C /* LPC GPIO Control Register */ +#define GPIO_EN (1 << 4) + +#define PCIEXBAR 0x60 + +#define PCH_DEV_LPC PCI_BDF(0, 0x1f, 0) + +/* RCB registers */ +#define OIC 0x31fe /* 16bit */ +#define HPTC 0x3404 /* 32bit */ +#define FD 0x3418 /* 32bit */ + +/* Function Disable 1 RCBA 0x3418 */ +#define PCH_DISABLE_ALWAYS (1 << 0) + +/* PM registers */ +#define TCO1_CNT 0x60 +#define TCO_TMR_HLT (1 << 11) + + +/* Device 0:0.0 PCI configuration space */ + +#define EPBAR 0x40 +#define MCHBAR 0x48 +#define PCIEXBAR 0x60 +#define DMIBAR 0x68 +#define GGC 0x50 /* GMCH Graphics Control */ +#define DEVEN 0x54 /* Device Enable */ +#define DEVEN_D7EN (1 << 14) +#define DEVEN_D4EN (1 << 7) +#define DEVEN_D3EN (1 << 5) +#define DEVEN_D2EN (1 << 4) +#define DEVEN_D1F0EN (1 << 3) +#define DEVEN_D1F1EN (1 << 2) +#define DEVEN_D1F2EN (1 << 1) +#define DEVEN_D0EN (1 << 0) +#define DPR 0x5c +#define DPR_EPM (1 << 2) +#define DPR_PRS (1 << 1) +#define DPR_SIZE_MASK 0xff0 + +#define MCHBAR_PEI_VERSION 0x5034 +#define BIOS_RESET_CPL 0x5da8 +#define EDRAMBAR 0x5408 +#define MCH_PAIR 0x5418 +#define GDXCBAR 0x5420 + +#define PAM0 0x80 +#define PAM1 0x81 +#define PAM2 0x82 +#define PAM3 0x83 +#define PAM4 0x84 +#define PAM5 0x85 +#define PAM6 0x86 + +/* PCODE MMIO communications live in the MCHBAR. */ +#define BIOS_MAILBOX_INTERFACE 0x5da4 +#define MAILBOX_RUN_BUSY (1 << 31) +#define MAILBOX_BIOS_CMD_READ_PCS 1 +#define MAILBOX_BIOS_CMD_WRITE_PCS 2 +#define MAILBOX_BIOS_CMD_READ_CALIBRATION 0x509 +#define MAILBOX_BIOS_CMD_FSM_MEASURE_INTVL 0x909 +#define MAILBOX_BIOS_CMD_READ_PCH_POWER 0xa +#define MAILBOX_BIOS_CMD_READ_PCH_POWER_EXT 0xb +#define MAILBOX_BIOS_CMD_READ_C9C10_VOLTAGE 0x26 +#define MAILBOX_BIOS_CMD_WRITE_C9C10_VOLTAGE 0x27 +/* Errors are returned back in bits 7:0. */ +#define MAILBOX_BIOS_ERROR_NONE 0 +#define MAILBOX_BIOS_ERROR_INVALID_COMMAND 1 +#define MAILBOX_BIOS_ERROR_TIMEOUT 2 +#define MAILBOX_BIOS_ERROR_ILLEGAL_DATA 3 +#define MAILBOX_BIOS_ERROR_RESERVED 4 +#define MAILBOX_BIOS_ERROR_ILLEGAL_VR_ID 5 +#define MAILBOX_BIOS_ERROR_VR_INTERFACE_LOCKED 6 +#define MAILBOX_BIOS_ERROR_VR_ERROR 7 +/* Data is passed through bits 31:0 of the data register. */ +#define BIOS_MAILBOX_DATA 0x5da0 + +/* SATA IOBP Registers */ +#define SATA_IOBP_SP0_SECRT88 0xea002688 +#define SATA_IOBP_SP1_SECRT88 0xea002488 + +#define SATA_SECRT88_VADJ_MASK 0xff +#define SATA_SECRT88_VADJ_SHIFT 16 + +#define SATA_IOBP_SP0DTLE_DATA 0xea002550 +#define SATA_IOBP_SP0DTLE_EDGE 0xea002554 +#define SATA_IOBP_SP1DTLE_DATA 0xea002750 +#define SATA_IOBP_SP1DTLE_EDGE 0xea002754 + +#define SATA_DTLE_MASK 0xF +#define SATA_DTLE_DATA_SHIFT 24 +#define SATA_DTLE_EDGE_SHIFT 16 + +/* Power Management */ +#define GEN_PMCON_1 0xa0 +#define SMI_LOCK (1 << 4) +#define GEN_PMCON_2 0xa2 +#define SYSTEM_RESET_STS (1 << 4) +#define THERMTRIP_STS (1 << 3) +#define SYSPWR_FLR (1 << 1) +#define PWROK_FLR (1 << 0) +#define GEN_PMCON_3 0xa4 +#define SUS_PWR_FLR (1 << 14) +#define GEN_RST_STS (1 << 9) +#define RTC_BATTERY_DEAD (1 << 2) +#define PWR_FLR (1 << 1) +#define SLEEP_AFTER_POWER_FAIL (1 << 0) +#define GEN_PMCON_LOCK 0xa6 +#define SLP_STR_POL_LOCK (1 << 2) +#define ACPI_BASE_LOCK (1 << 1) +#define PMIR 0xac +#define PMIR_CF9LOCK (1 << 31) +#define PMIR_CF9GR (1 << 20) + +/* Broadwell PCH (Wildcat Point) */ +#define PCH_WPT_HSW_U_SAMPLE 0x9cc1 +#define PCH_WPT_BDW_U_SAMPLE 0x9cc2 +#define PCH_WPT_BDW_U_PREMIUM 0x9cc3 +#define PCH_WPT_BDW_U_BASE 0x9cc5 +#define PCH_WPT_BDW_Y_SAMPLE 0x9cc6 +#define PCH_WPT_BDW_Y_PREMIUM 0x9cc7 +#define PCH_WPT_BDW_Y_BASE 0x9cc9 +#define PCH_WPT_BDW_H 0x9ccb + +#define SA_IGD_OPROM_VENDEV 0x80860406 + +/* Dynamically determine if the part is ULT */ +bool cpu_is_ult(void); + +u32 pch_iobp_read(u32 address); +int pch_iobp_write(u32 address, u32 data); +int pch_iobp_update(u32 address, u32 andvalue, u32 orvalue); +int pch_iobp_exec(u32 addr, u16 op_dcode, u8 route_id, u32 *data, u8 *resp); + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/pei_data.h b/arch/x86/include/asm/arch-broadwell/pei_data.h new file mode 100644 index 0000000000..b2cc8b8dc4 --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/pei_data.h @@ -0,0 +1,177 @@ +/* + * From Coreboot soc/intel/broadwell/include/soc/pei_data.h + * + * Copyright (C) 2014 Google Inc. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ASM_ARCH_PEI_DATA_H +#define ASM_ARCH_PEI_DATA_H + +#include <linux/linkage.h> + +#define PEI_VERSION 22 + +typedef void asmlinkage (*tx_byte_func)(unsigned char byte); + +enum board_type { + BOARD_TYPE_CRB_MOBILE = 0, /* CRB Mobile */ + BOARD_TYPE_CRB_DESKTOP, /* CRB Desktop */ + BOARD_TYPE_USER1, /* SV mobile */ + BOARD_TYPE_USER2, /* SV desktop */ + BOARD_TYPE_USER3, /* SV server */ + BOARD_TYPE_ULT, /* ULT */ + BOARD_TYPE_CRB_EMBDEDDED, /* CRB Embedded */ + BOARD_TYPE_UNKNOWN, +}; + +#define MAX_USB2_PORTS 14 +#define MAX_USB3_PORTS 6 +#define USB_OC_PIN_SKIP 8 + +enum usb2_port_location { + USB_PORT_BACK_PANEL = 0, + USB_PORT_FRONT_PANEL, + USB_PORT_DOCK, + USB_PORT_MINI_PCIE, + USB_PORT_FLEX, + USB_PORT_INTERNAL, + USB_PORT_SKIP, + USB_PORT_NGFF_DEVICE_DOWN, +}; + +struct usb2_port_setting { + /* + * Usb Port Length: + * [16:4] = length in inches in octal format + * [3:0] = decimal point + */ + uint16_t length; + uint8_t enable; + uint8_t oc_pin; + uint8_t location; +} __packed; + +struct usb3_port_setting { + uint8_t enable; + uint8_t oc_pin; + /* + * Set to 0 if trace length is > 5 inches + * Set to 1 if trace length is <= 5 inches + */ + uint8_t fixed_eq; +} __packed; + + +struct pei_data { + uint32_t pei_version; + + enum board_type board_type; + int boot_mode; + int ec_present; + int usbdebug; + + /* Base addresses */ + uint32_t pciexbar; + uint16_t smbusbar; + uint32_t xhcibar; + uint32_t ehcibar; + uint32_t gttbar; + uint32_t rcba; + uint32_t pmbase; + uint32_t gpiobase; + uint32_t temp_mmio_base; + uint32_t tseg_size; + + /* + * 0 = leave channel enabled + * 1 = disable dimm 0 on channel + * 2 = disable dimm 1 on channel + * 3 = disable dimm 0+1 on channel + */ + int dimm_channel0_disabled; + int dimm_channel1_disabled; + /* Set to 0 for memory down */ + uint8_t spd_addresses[4]; + /* Enable 2x Refresh Mode */ + int ddr_refresh_2x; + /* DQ pins are interleaved on board */ + int dq_pins_interleaved; + /* Limit DDR3 frequency */ + int max_ddr3_freq; + /* Disable self refresh */ + int disable_self_refresh; + /* Disable cmd power/CKEPD */ + int disable_cmd_pwr; + + /* USB port configuration */ + struct usb2_port_setting usb2_ports[MAX_USB2_PORTS]; + struct usb3_port_setting usb3_ports[MAX_USB3_PORTS]; + + /* + * USB3 board specific PHY tuning + */ + + /* Valid range: 0x69 - 0x80 */ + uint8_t usb3_txout_volt_dn_amp_adj[MAX_USB3_PORTS]; + /* Valid range: 0x80 - 0x9c */ + uint8_t usb3_txout_imp_sc_volt_amp_adj[MAX_USB3_PORTS]; + /* Valid range: 0x39 - 0x80 */ + uint8_t usb3_txout_de_emp_adj[MAX_USB3_PORTS]; + /* Valid range: 0x3d - 0x4a */ + uint8_t usb3_txout_imp_adj_volt_amp[MAX_USB3_PORTS]; + + /* Console output function */ + tx_byte_func tx_byte; + + /* + * DIMM SPD data for memory down configurations + * [CHANNEL][SLOT][SPD] + */ + uint8_t spd_data[2][2][512]; + + /* + * LPDDR3 DQ byte map + * [CHANNEL][ITERATION][2] + * + * Maps which PI clocks are used by what LPDDR DQ Bytes (from CPU side) + * DQByteMap[0] - ClkDQByteMap: + * - If clock is per rank, program to [0xFF, 0xFF] + * - If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF] + * - If clock is shared by 2 ranks but does not go to all bytes, + * Entry[i] defines which DQ bytes Group i services + * DQByteMap[1] - CmdNDQByteMap: [0] is CmdN/CAA and [1] is CmdN/CAB + * DQByteMap[2] - CmdSDQByteMap: [0] is CmdS/CAA and [1] is CmdS/CAB + * DQByteMap[3] - CkeDQByteMap : [0] is CKE /CAA and [1] is CKE /CAB + * For DDR, DQByteMap[3:1] = [0xFF, 0] + * DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0] + * since we have 1 CTL / rank + * DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0] + * since we have 1 CA Vref + */ + uint8_t dq_map[2][6][2]; + + /* + * LPDDR3 Map from CPU DQS pins to SDRAM DQS pins + * [CHANNEL][MAX_BYTES] + */ + uint8_t dqs_map[2][8]; + + /* Data read from flash and passed into MRC */ + const void *saved_data; + int saved_data_size; + + /* Disable use of saved data (can be set by mainboard) */ + int disable_saved_data; + + /* Data from MRC that should be saved to flash */ + void *data_to_save; + int data_to_save_size; + struct pei_memory_info meminfo; +} __packed; + +void mainboard_fill_pei_data(struct pei_data *pei_data); +void broadwell_fill_pei_data(struct pei_data *pei_data); + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/pm.h b/arch/x86/include/asm/arch-broadwell/pm.h new file mode 100644 index 0000000000..36ad842368 --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/pm.h @@ -0,0 +1,129 @@ +/* + * From coreboot src/soc/intel/broadwell/include/soc/pm.h + * + * Copyright (C) 2016 Google, Inc. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __ASM_ARCH_PM_H +#define __ASM_ARCH_PM_H + +#define PM1_STS 0x00 +#define WAK_STS (1 << 15) +#define PCIEXPWAK_STS (1 << 14) +#define PRBTNOR_STS (1 << 11) +#define RTC_STS (1 << 10) +#define PWRBTN_STS (1 << 8) +#define GBL_STS (1 << 5) +#define BM_STS (1 << 4) +#define TMROF_STS (1 << 0) +#define PM1_EN 0x02 +#define PCIEXPWAK_DIS (1 << 14) +#define RTC_EN (1 << 10) +#define PWRBTN_EN (1 << 8) +#define GBL_EN (1 << 5) +#define TMROF_EN (1 << 0) +#define PM1_CNT 0x04 +#define SLP_EN (1 << 13) +#define SLP_TYP (7 << 10) +#define SLP_TYP_SHIFT 10 +#define SLP_TYP_S0 0 +#define SLP_TYP_S1 1 +#define SLP_TYP_S3 5 +#define SLP_TYP_S4 6 +#define SLP_TYP_S5 7 +#define GBL_RLS (1 << 2) +#define BM_RLD (1 << 1) +#define SCI_EN (1 << 0) +#define PM1_TMR 0x08 +#define SMI_EN 0x30 +#define XHCI_SMI_EN (1 << 31) +#define ME_SMI_EN (1 << 30) +#define GPIO_UNLOCK_SMI_EN (1 << 27) +#define INTEL_USB2_EN (1 << 18) +#define LEGACY_USB2_EN (1 << 17) +#define PERIODIC_EN (1 << 14) +#define TCO_EN (1 << 13) +#define MCSMI_EN (1 << 11) +#define BIOS_RLS (1 << 7) +#define SWSMI_TMR_EN (1 << 6) +#define APMC_EN (1 << 5) +#define SLP_SMI_EN (1 << 4) +#define LEGACY_USB_EN (1 << 3) +#define BIOS_EN (1 << 2) +#define EOS (1 << 1) +#define GBL_SMI_EN (1 << 0) +#define SMI_STS 0x34 +#define UPWRC 0x3c +#define UPWRC_WS (1 << 8) +#define UPWRC_WE (1 << 1) +#define UPWRC_SMI (1 << 0) +#define GPE_CNTL 0x42 +#define SWGPE_CTRL (1 << 1) +#define DEVACT_STS 0x44 +#define PM2_CNT 0x50 +#define TCO1_CNT 0x60 +#define TCO_TMR_HLT (1 << 11) +#define TCO1_STS 0x64 +#define DMISCI_STS (1 << 9) +#define TCO2_STS 0x66 +#define TCO2_STS_SECOND_TO (1 << 1) + +#define GPE0_REG_MAX 4 +#define GPE0_REG_SIZE 32 +#define GPE0_STS(x) (0x80 + (x * 4)) +#define GPE_31_0 0 /* 0x80/0x90 = GPE[31:0] */ +#define GPE_63_32 1 /* 0x84/0x94 = GPE[63:32] */ +#define GPE_94_64 2 /* 0x88/0x98 = GPE[94:64] */ +#define GPE_STD 3 /* 0x8c/0x9c = Standard GPE */ +#define WADT_STS (1 << 18) +#define GP27_STS (1 << 16) +#define PME_B0_STS (1 << 13) +#define ME_SCI_STS (1 << 12) +#define PME_STS (1 << 11) +#define BATLOW_STS (1 << 10) +#define PCI_EXP_STS (1 << 9) +#define SMB_WAK_STS (1 << 7) +#define TCOSCI_STS (1 << 6) +#define SWGPE_STS (1 << 2) +#define HOT_PLUG_STS (1 << 1) +#define GPE0_EN(x) (0x90 + (x * 4)) +#define WADT_en (1 << 18) +#define GP27_EN (1 << 16) +#define PME_B0_EN (1 << 13) +#define ME_SCI_EN (1 << 12) +#define PME_EN (1 << 11) +#define BATLOW_EN (1 << 10) +#define PCI_EXP_EN (1 << 9) +#define TCOSCI_EN (1 << 6) +#define SWGPE_EN (1 << 2) +#define HOT_PLUG_EN (1 << 1) + +#define MAINBOARD_POWER_OFF 0 +#define MAINBOARD_POWER_ON 1 +#define MAINBOARD_POWER_KEEP 2 + +#define SLEEP_STATE_S0 0 +#define SLEEP_STATE_S3 3 +#define SLEEP_STATE_S5 5 + +struct chipset_power_state { + uint16_t pm1_sts; + uint16_t pm1_en; + uint32_t pm1_cnt; + uint16_t tco1_sts; + uint16_t tco2_sts; + uint32_t gpe0_sts[4]; + uint32_t gpe0_en[4]; + uint16_t gen_pmcon1; + uint16_t gen_pmcon2; + uint16_t gen_pmcon3; + int prev_sleep_state; + uint16_t hsio_version; + uint16_t hsio_checksum; +}; + +void power_state_get(struct udevice *pch_dev, struct chipset_power_state *ps); + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/rcb.h b/arch/x86/include/asm/arch-broadwell/rcb.h new file mode 100644 index 0000000000..44fcddd9c2 --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/rcb.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __asm_arch_rcba_h +#define __asm_arch_rcba_h + +#define PMSYNC_CONFIG 0x33c4 /* 32bit */ +#define PMSYNC_CONFIG2 0x33cc /* 32bit */ + +#define DEEP_S3_POL 0x3328 /* 32bit */ +#define DEEP_S3_EN_AC (1 << 0) +#define DEEP_S3_EN_DC (1 << 1) +#define DEEP_S5_POL 0x3330 /* 32bit */ +#define DEEP_S5_EN_AC (1 << 14) +#define DEEP_S5_EN_DC (1 << 15) +#define DEEP_SX_CONFIG 0x3334 /* 32bit */ +#define DEEP_SX_WAKE_PIN_EN (1 << 2) +#define DEEP_SX_ACPRESENT_PD (1 << 1) +#define DEEP_SX_GP27_PIN_EN (1 << 0) +#define PMSYNC_CONFIG 0x33c4 /* 32bit */ +#define PMSYNC_CONFIG2 0x33cc /* 32bit */ + +#define RC 0x3400 /* 32bit */ +#define HPTC 0x3404 /* 32bit */ +#define GCS 0x3410 /* 32bit */ +#define BUC 0x3414 /* 32bit */ +#define PCH_DISABLE_GBE (1 << 5) +#define FD 0x3418 /* 32bit */ +#define FDSW 0x3420 /* 8bit */ +#define DISPBDF 0x3424 /* 16bit */ +#define FD2 0x3428 /* 32bit */ +#define CG 0x341c /* 32bit */ + +/* Function Disable 1 RCBA 0x3418 */ +#define PCH_DISABLE_ALWAYS (1 << 0) +#define PCH_DISABLE_ADSPD (1 << 1) +#define PCH_DISABLE_SATA1 (1 << 2) +#define PCH_DISABLE_SMBUS (1 << 3) +#define PCH_DISABLE_HD_AUDIO (1 << 4) +#define PCH_DISABLE_EHCI2 (1 << 13) +#define PCH_DISABLE_LPC (1 << 14) +#define PCH_DISABLE_EHCI1 (1 << 15) +#define PCH_DISABLE_PCIE(x) (1 << (16 + x)) +#define PCH_DISABLE_THERMAL (1 << 24) +#define PCH_DISABLE_SATA2 (1 << 25) +#define PCH_DISABLE_XHCI (1 << 27) + +/* Function Disable 2 RCBA 0x3428 */ +#define PCH_DISABLE_KT (1 << 4) +#define PCH_DISABLE_IDER (1 << 3) +#define PCH_DISABLE_MEI2 (1 << 2) +#define PCH_DISABLE_MEI1 (1 << 1) +#define PCH_ENABLE_DBDF (1 << 0) + +#endif diff --git a/arch/x86/include/asm/arch-broadwell/spi.h b/arch/x86/include/asm/arch-broadwell/spi.h new file mode 100644 index 0000000000..aeb492609e --- /dev/null +++ b/arch/x86/include/asm/arch-broadwell/spi.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2014 Google Inc. + * + * This file is from coreboot soc/intel/broadwell/include/soc/spi.h + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _BROADWELL_SPI_H_ +#define _BROADWELL_SPI_H_ + +/* + * SPI Opcode Menu setup for SPIBAR lockdown + * should support most common flash chips. + */ + +#define SPIBAR_OFFSET 0x3800 +#define SPI_REG(x) (RCB_REG(SPIBAR_OFFSET + (x))) + +/* Reigsters within the SPIBAR */ +#define SPIBAR_SSFC 0x91 +#define SPIBAR_FDOC 0xb0 +#define SPIBAR_FDOD 0xb4 + +#define SPIBAR_PREOP 0x94 +#define SPIBAR_OPTYPE 0x96 +#define SPIBAR_OPMENU_LOWER 0x98 +#define SPIBAR_OPMENU_UPPER 0x9c + +#define SPI_OPMENU_0 0x01 /* WRSR: Write Status Register */ +#define SPI_OPTYPE_0 0x01 /* Write, no address */ + +#define SPI_OPMENU_1 0x02 /* BYPR: Byte Program */ +#define SPI_OPTYPE_1 0x03 /* Write, address required */ + +#define SPI_OPMENU_2 0x03 /* READ: Read Data */ +#define SPI_OPTYPE_2 0x02 /* Read, address required */ + +#define SPI_OPMENU_3 0x05 /* RDSR: Read Status Register */ +#define SPI_OPTYPE_3 0x00 /* Read, no address */ + +#define SPI_OPMENU_4 0x20 /* SE20: Sector Erase 0x20 */ +#define SPI_OPTYPE_4 0x03 /* Write, address required */ + +#define SPI_OPMENU_5 0x9f /* RDID: Read ID */ +#define SPI_OPTYPE_5 0x00 /* Read, no address */ + +#define SPI_OPMENU_6 0xd8 /* BED8: Block Erase 0xd8 */ +#define SPI_OPTYPE_6 0x03 /* Write, address required */ + +#define SPI_OPMENU_7 0x0b /* FAST: Fast Read */ +#define SPI_OPTYPE_7 0x02 /* Read, address required */ + +#define SPI_OPMENU_UPPER ((SPI_OPMENU_7 << 24) | (SPI_OPMENU_6 << 16) | \ + (SPI_OPMENU_5 << 8) | SPI_OPMENU_4) +#define SPI_OPMENU_LOWER ((SPI_OPMENU_3 << 24) | (SPI_OPMENU_2 << 16) | \ + (SPI_OPMENU_1 << 8) | SPI_OPMENU_0) + +#define SPI_OPTYPE ((SPI_OPTYPE_7 << 14) | (SPI_OPTYPE_6 << 12) | \ + (SPI_OPTYPE_5 << 10) | (SPI_OPTYPE_4 << 8) | \ + (SPI_OPTYPE_3 << 6) | (SPI_OPTYPE_2 << 4) | \ + (SPI_OPTYPE_1 << 2) | (SPI_OPTYPE_0)) + +#define SPI_OPPREFIX ((0x50 << 8) | 0x06) /* EWSR and WREN */ + +#define SPIBAR_HSFS 0x04 /* SPI hardware sequence status */ +#define SPIBAR_HSFS_FLOCKDN (1 << 15)/* Flash Configuration Lock-Down */ +#define SPIBAR_HSFS_SCIP (1 << 5) /* SPI Cycle In Progress */ +#define SPIBAR_HSFS_AEL (1 << 2) /* SPI Access Error Log */ +#define SPIBAR_HSFS_FCERR (1 << 1) /* SPI Flash Cycle Error */ +#define SPIBAR_HSFS_FDONE (1 << 0) /* SPI Flash Cycle Done */ +#define SPIBAR_HSFC 0x06 /* SPI hardware sequence control */ +#define SPIBAR_HSFC_BYTE_COUNT(c) (((c - 1) & 0x3f) << 8) +#define SPIBAR_HSFC_CYCLE_READ (0 << 1) /* Read cycle */ +#define SPIBAR_HSFC_CYCLE_WRITE (2 << 1) /* Write cycle */ +#define SPIBAR_HSFC_CYCLE_ERASE (3 << 1) /* Erase cycle */ +#define SPIBAR_HSFC_GO (1 << 0) /* GO: start SPI transaction */ +#define SPIBAR_FADDR 0x08 /* SPI flash address */ +#define SPIBAR_FDATA(n) (0x10 + (4 * n)) /* SPI flash data */ +#define SPIBAR_SSFS 0x90 +#define SPIBAR_SSFS_ERROR (1 << 3) +#define SPIBAR_SSFS_DONE (1 << 2) +#define SPIBAR_SSFC 0x91 +#define SPIBAR_SSFC_DATA (1 << 14) +#define SPIBAR_SSFC_GO (1 << 1) + +#endif diff --git a/arch/x86/include/asm/arch-coreboot/sysinfo.h b/arch/x86/include/asm/arch-coreboot/sysinfo.h index 2d5724503c..12b3b5d6ee 100644 --- a/arch/x86/include/asm/arch-coreboot/sysinfo.h +++ b/arch/x86/include/asm/arch-coreboot/sysinfo.h @@ -9,7 +9,7 @@ #ifndef _COREBOOT_SYSINFO_H #define _COREBOOT_SYSINFO_H -#include <asm/arch/tables.h> +#include <asm/coreboot_tables.h> /* Maximum number of memory range definitions */ #define SYSINFO_MAX_MEM_RANGES 32 @@ -56,4 +56,6 @@ struct sysinfo_t { extern struct sysinfo_t lib_sysinfo; +int get_coreboot_info(struct sysinfo_t *info); + #endif diff --git a/arch/x86/include/asm/arch-ivybridge/me.h b/arch/x86/include/asm/arch-ivybridge/me.h index eb1b73f92e..bc1bc8e778 100644 --- a/arch/x86/include/asm/arch-ivybridge/me.h +++ b/arch/x86/include/asm/arch-ivybridge/me.h @@ -9,225 +9,7 @@ #ifndef _ASM_INTEL_ME_H #define _ASM_INTEL_ME_H -#include <linux/compiler.h> -#include <linux/types.h> - -#define ME_RETRY 100000 /* 1 second */ -#define ME_DELAY 10 /* 10 us */ - -/* - * Management Engine PCI registers - */ - -#define PCI_CPU_MEBASE_L 0x70 /* Set by MRC */ -#define PCI_CPU_MEBASE_H 0x74 /* Set by MRC */ - -#define PCI_ME_HFS 0x40 -#define ME_HFS_CWS_RESET 0 -#define ME_HFS_CWS_INIT 1 -#define ME_HFS_CWS_REC 2 -#define ME_HFS_CWS_NORMAL 5 -#define ME_HFS_CWS_WAIT 6 -#define ME_HFS_CWS_TRANS 7 -#define ME_HFS_CWS_INVALID 8 -#define ME_HFS_STATE_PREBOOT 0 -#define ME_HFS_STATE_M0_UMA 1 -#define ME_HFS_STATE_M3 4 -#define ME_HFS_STATE_M0 5 -#define ME_HFS_STATE_BRINGUP 6 -#define ME_HFS_STATE_ERROR 7 -#define ME_HFS_ERROR_NONE 0 -#define ME_HFS_ERROR_UNCAT 1 -#define ME_HFS_ERROR_IMAGE 3 -#define ME_HFS_ERROR_DEBUG 4 -#define ME_HFS_MODE_NORMAL 0 -#define ME_HFS_MODE_DEBUG 2 -#define ME_HFS_MODE_DIS 3 -#define ME_HFS_MODE_OVER_JMPR 4 -#define ME_HFS_MODE_OVER_MEI 5 -#define ME_HFS_BIOS_DRAM_ACK 1 -#define ME_HFS_ACK_NO_DID 0 -#define ME_HFS_ACK_RESET 1 -#define ME_HFS_ACK_PWR_CYCLE 2 -#define ME_HFS_ACK_S3 3 -#define ME_HFS_ACK_S4 4 -#define ME_HFS_ACK_S5 5 -#define ME_HFS_ACK_GBL_RESET 6 -#define ME_HFS_ACK_CONTINUE 7 - -struct me_hfs { - u32 working_state:4; - u32 mfg_mode:1; - u32 fpt_bad:1; - u32 operation_state:3; - u32 fw_init_complete:1; - u32 ft_bup_ld_flr:1; - u32 update_in_progress:1; - u32 error_code:4; - u32 operation_mode:4; - u32 reserved:4; - u32 boot_options_present:1; - u32 ack_data:3; - u32 bios_msg_ack:4; -} __packed; - -#define PCI_ME_UMA 0x44 - -struct me_uma { - u32 size:6; - u32 reserved_1:10; - u32 valid:1; - u32 reserved_0:14; - u32 set_to_one:1; -} __packed; - -#define PCI_ME_H_GS 0x4c -#define ME_INIT_DONE 1 -#define ME_INIT_STATUS_SUCCESS 0 -#define ME_INIT_STATUS_NOMEM 1 -#define ME_INIT_STATUS_ERROR 2 - -struct me_did { - u32 uma_base:16; - u32 reserved:8; - u32 status:4; - u32 init_done:4; -} __packed; - -#define PCI_ME_GMES 0x48 -#define ME_GMES_PHASE_ROM 0 -#define ME_GMES_PHASE_BUP 1 -#define ME_GMES_PHASE_UKERNEL 2 -#define ME_GMES_PHASE_POLICY 3 -#define ME_GMES_PHASE_MODULE 4 -#define ME_GMES_PHASE_UNKNOWN 5 -#define ME_GMES_PHASE_HOST 6 - -struct me_gmes { - u32 bist_in_prog:1; - u32 icc_prog_sts:2; - u32 invoke_mebx:1; - u32 cpu_replaced_sts:1; - u32 mbp_rdy:1; - u32 mfs_failure:1; - u32 warm_rst_req_for_df:1; - u32 cpu_replaced_valid:1; - u32 reserved_1:2; - u32 fw_upd_ipu:1; - u32 reserved_2:4; - u32 current_state:8; - u32 current_pmevent:4; - u32 progress_code:4; -} __packed; - -#define PCI_ME_HERES 0xbc -#define PCI_ME_EXT_SHA1 0x00 -#define PCI_ME_EXT_SHA256 0x02 -#define PCI_ME_HER(x) (0xc0+(4*(x))) - -struct me_heres { - u32 extend_reg_algorithm:4; - u32 reserved:26; - u32 extend_feature_present:1; - u32 extend_reg_valid:1; -} __packed; - -/* - * Management Engine MEI registers - */ - -#define MEI_H_CB_WW 0x00 -#define MEI_H_CSR 0x04 -#define MEI_ME_CB_RW 0x08 -#define MEI_ME_CSR_HA 0x0c - -struct mei_csr { - u32 interrupt_enable:1; - u32 interrupt_status:1; - u32 interrupt_generate:1; - u32 ready:1; - u32 reset:1; - u32 reserved:3; - u32 buffer_read_ptr:8; - u32 buffer_write_ptr:8; - u32 buffer_depth:8; -} __packed; - -#define MEI_ADDRESS_CORE 0x01 -#define MEI_ADDRESS_AMT 0x02 -#define MEI_ADDRESS_RESERVED 0x03 -#define MEI_ADDRESS_WDT 0x04 -#define MEI_ADDRESS_MKHI 0x07 -#define MEI_ADDRESS_ICC 0x08 -#define MEI_ADDRESS_THERMAL 0x09 - -#define MEI_HOST_ADDRESS 0 - -struct mei_header { - u32 client_address:8; - u32 host_address:8; - u32 length:9; - u32 reserved:6; - u32 is_complete:1; -} __packed; - -#define MKHI_GROUP_ID_CBM 0x00 -#define MKHI_GROUP_ID_FWCAPS 0x03 -#define MKHI_GROUP_ID_MDES 0x08 -#define MKHI_GROUP_ID_GEN 0xff - -#define MKHI_GLOBAL_RESET 0x0b - -#define MKHI_FWCAPS_GET_RULE 0x02 - -#define MKHI_MDES_ENABLE 0x09 - -#define MKHI_GET_FW_VERSION 0x02 -#define MKHI_END_OF_POST 0x0c -#define MKHI_FEATURE_OVERRIDE 0x14 - -struct mkhi_header { - u32 group_id:8; - u32 command:7; - u32 is_response:1; - u32 reserved:8; - u32 result:8; -} __packed; - -struct me_fw_version { - u16 code_minor; - u16 code_major; - u16 code_build_number; - u16 code_hot_fix; - u16 recovery_minor; - u16 recovery_major; - u16 recovery_build_number; - u16 recovery_hot_fix; -} __packed; - - -#define HECI_EOP_STATUS_SUCCESS 0x0 -#define HECI_EOP_PERFORM_GLOBAL_RESET 0x1 - -#define CBM_RR_GLOBAL_RESET 0x01 - -#define GLOBAL_RESET_BIOS_MRC 0x01 -#define GLOBAL_RESET_BIOS_POST 0x02 -#define GLOBAL_RESET_MEBX 0x03 - -struct me_global_reset { - u8 request_origin; - u8 reset_type; -} __packed; - -enum me_bios_path { - ME_NORMAL_BIOS_PATH, - ME_S3WAKE_BIOS_PATH, - ME_ERROR_BIOS_PATH, - ME_RECOVERY_BIOS_PATH, - ME_DISABLE_BIOS_PATH, - ME_FIRMWARE_UPDATE_BIOS_PATH, -}; +#include <asm/me_common.h> struct __packed mbp_fw_version_name { u32 major_version:16; @@ -244,46 +26,6 @@ struct __packed mbp_icc_profile { u32 register_lock_mask[3]; }; -struct __packed mefwcaps_sku { - u32 full_net:1; - u32 std_net:1; - u32 manageability:1; - u32 small_business:1; - u32 l3manageability:1; - u32 intel_at:1; - u32 intel_cls:1; - u32 reserved:3; - u32 intel_mpc:1; - u32 icc_over_clocking:1; - u32 pavp:1; - u32 reserved_1:4; - u32 ipv6:1; - u32 kvm:1; - u32 och:1; - u32 vlan:1; - u32 tls:1; - u32 reserved_4:1; - u32 wlan:1; - u32 reserved_5:8; -}; - -struct __packed tdt_state_flag { - u16 lock_state:1; - u16 authenticate_module:1; - u16 s3authentication:1; - u16 flash_wear_out:1; - u16 flash_variable_security:1; - u16 wwan3gpresent:1; - u16 wwan3goob:1; - u16 reserved:9; -}; - -struct __packed tdt_state_info { - u8 state; - u8 last_theft_trigger; - struct tdt_state_flag flags; -}; - struct __packed platform_type_rule_data { u32 platform_target_usage_type:4; u32 platform_target_market_type:2; @@ -299,16 +41,6 @@ struct __packed mbp_fw_caps { u8 available; }; -struct __packed mbp_rom_bist_data { - u16 device_id; - u16 fuse_test_flags; - u32 umchid[4]; -}; - -struct __packed mbp_platform_key { - u32 key[8]; -}; - struct __packed mbp_plat_type { struct platform_type_rule_data rule_data; u8 available; @@ -325,67 +57,4 @@ struct __packed me_bios_payload { u32 mfsintegrity; }; -struct __packed mbp_header { - u32 mbp_size:8; - u32 num_entries:8; - u32 rsvd:16; -}; - -struct __packed mbp_item_header { - u32 app_id:8; - u32 item_id:8; - u32 length:8; - u32 rsvd:8; -}; - -struct __packed me_fwcaps { - u32 id; - u8 length; - struct mefwcaps_sku caps_sku; - u8 reserved[3]; -}; - -/** - * intel_me_status() - Check Intel Management Engine status - * - * struct hfs: Firmware status - * struct gmes: Management engine status - */ -void intel_me_status(struct me_hfs *hfs, struct me_gmes *gmes); - -/** - * intel_early_me_status() - Check early Management Engine Status - * - * @me_dev: Management engine PCI device - */ -void intel_early_me_status(struct udevice *me_dev); - -/** - * intel_early_me_init() - Early Intel Management Engine init - * - * @me_dev: Management engine PCI device - * @return 0 if OK, -ve on error - */ -int intel_early_me_init(struct udevice *me_dev); - -/** - * intel_early_me_uma_size() - Get UMA size from the Intel Management Engine - * - * @me_dev: Management engine PCI device - * @return UMA size if OK, -EINVAL on error - */ -int intel_early_me_uma_size(struct udevice *me_dev); - -/** - * intel_early_me_init_done() - Complete Intel Management Engine init - * - * @dev: Northbridge device - * @me_dev: Management engine PCI device - * @status: Status result (ME_INIT_...) - * @return 0 to continue to boot, -EINVAL on unknown result data, -ETIMEDOUT - * if ME did not respond - */ -int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev, - uint status); - #endif diff --git a/arch/x86/include/asm/arch-ivybridge/model_206ax.h b/arch/x86/include/asm/arch-ivybridge/model_206ax.h index d2f9006093..22f7929a82 100644 --- a/arch/x86/include/asm/arch-ivybridge/model_206ax.h +++ b/arch/x86/include/asm/arch-ivybridge/model_206ax.h @@ -15,13 +15,9 @@ #define CPUID_VMX (1 << 5) #define CPUID_SMX (1 << 6) #define MSR_FEATURE_CONFIG 0x13c -#define MSR_FLEX_RATIO 0x194 -#define FLEX_RATIO_LOCK (1 << 20) -#define FLEX_RATIO_EN (1 << 16) #define IA32_PLATFORM_DCA_CAP 0x1f8 #define IA32_MISC_ENABLE 0x1a0 #define MSR_TEMPERATURE_TARGET 0x1a2 -#define IA32_PERF_CTL 0x199 #define IA32_THERM_INTERRUPT 0x19b #define IA32_ENERGY_PERFORMANCE_BIAS 0x1b0 #define ENERGY_POLICY_PERFORMANCE 0 @@ -31,12 +27,8 @@ #define MSR_LT_LOCK_MEMORY 0x2e7 #define IA32_MC0_STATUS 0x401 -#define MSR_PIC_MSG_CONTROL 0x2e -#define PLATFORM_INFO_SET_TDP (1 << 29) - #define MSR_MISC_PWR_MGMT 0x1aa #define MISC_PWR_MGMT_EIST_HW_DIS (1 << 0) -#define MSR_TURBO_RATIO_LIMIT 0x1ad #define MSR_PKGC3_IRTL 0x60a #define MSR_PKGC6_IRTL 0x60b @@ -50,13 +42,6 @@ #define IRTL_33554432_NS (5 << 10) #define IRTL_RESPONSE_MASK (0x3ff) -/* long duration in low dword, short duration in high dword */ -#define PKG_POWER_LIMIT_MASK 0x7fff -#define PKG_POWER_LIMIT_EN (1 << 15) -#define PKG_POWER_LIMIT_CLAMP (1 << 16) -#define PKG_POWER_LIMIT_TIME_SHIFT 17 -#define PKG_POWER_LIMIT_TIME_MASK 0x7f - #define MSR_PP0_CURRENT_CONFIG 0x601 #define PP0_CURRENT_LIMIT (112 << 3) /* 112 A */ #define MSR_PP1_CURRENT_CONFIG 0x602 @@ -65,11 +50,9 @@ #define MSR_PKG_POWER_SKU 0x614 #define IVB_CONFIG_TDP_MIN_CPUID 0x306a2 -#define MSR_CONFIG_TDP_NOMINAL 0x648 #define MSR_CONFIG_TDP_LEVEL1 0x649 #define MSR_CONFIG_TDP_LEVEL2 0x64a #define MSR_CONFIG_TDP_CONTROL 0x64b -#define MSR_TURBO_ACTIVATION_RATIO 0x64c /* P-state configuration */ #define PSS_MAX_ENTRIES 8 diff --git a/arch/x86/include/asm/arch-ivybridge/pch.h b/arch/x86/include/asm/arch-ivybridge/pch.h index af3e8e747c..4725250d91 100644 --- a/arch/x86/include/asm/arch-ivybridge/pch.h +++ b/arch/x86/include/asm/arch-ivybridge/pch.h @@ -69,8 +69,6 @@ #define RTC_POWER_FAILED (1 << 1) #define SLEEP_AFTER_POWER_FAIL (1 << 0) -#define PMBASE 0x40 -#define ACPI_CNTL 0x44 #define BIOS_CNTL 0xDC #define GPIO_BASE 0x48 /* LPC GPIO Base Address Register */ #define GPIO_CNTL 0x4C /* LPC GPIO Control Register */ @@ -99,60 +97,11 @@ #define GPIO_CNTL 0x4C /* LPC GPIO Control Register */ #define GPIO_ROUT 0xb8 -#define LPC_IO_DEC 0x80 /* IO Decode Ranges Register */ -#define COMB_DEC_RANGE (1 << 4) /* 0x2f8-0x2ff (COM2) */ -#define COMA_DEC_RANGE (0 << 0) /* 0x3f8-0x3ff (COM1) */ -#define LPC_EN 0x82 /* LPC IF Enables Register */ -#define CNF2_LPC_EN (1 << 13) /* 0x4e/0x4f */ -#define CNF1_LPC_EN (1 << 12) /* 0x2e/0x2f */ -#define MC_LPC_EN (1 << 11) /* 0x62/0x66 */ -#define KBC_LPC_EN (1 << 10) /* 0x60/0x64 */ -#define GAMEH_LPC_EN (1 << 9) /* 0x208/0x20f */ -#define GAMEL_LPC_EN (1 << 8) /* 0x200/0x207 */ -#define FDD_LPC_EN (1 << 3) /* LPC_IO_DEC[12] */ -#define LPT_LPC_EN (1 << 2) /* LPC_IO_DEC[9:8] */ -#define COMB_LPC_EN (1 << 1) /* LPC_IO_DEC[6:4] */ -#define COMA_LPC_EN (1 << 0) /* LPC_IO_DEC[3:2] */ -#define LPC_GEN1_DEC 0x84 /* LPC IF Generic Decode Range 1 */ -#define LPC_GEN2_DEC 0x88 /* LPC IF Generic Decode Range 2 */ -#define LPC_GEN3_DEC 0x8c /* LPC IF Generic Decode Range 3 */ -#define LPC_GEN4_DEC 0x90 /* LPC IF Generic Decode Range 4 */ -#define LPC_GENX_DEC(x) (0x84 + 4 * (x)) -#define GEN_DEC_RANGE_256B 0xfc0000 /* 256 Bytes */ -#define GEN_DEC_RANGE_128B 0x7c0000 /* 128 Bytes */ -#define GEN_DEC_RANGE_64B 0x3c0000 /* 64 Bytes */ -#define GEN_DEC_RANGE_32B 0x1c0000 /* 32 Bytes */ -#define GEN_DEC_RANGE_16B 0x0c0000 /* 16 Bytes */ -#define GEN_DEC_RANGE_8B 0x040000 /* 8 Bytes */ -#define GEN_DEC_RANGE_4B 0x000000 /* 4 Bytes */ -#define GEN_DEC_RANGE_EN (1 << 0) /* Range Enable */ - /* PCI Configuration Space (D31:F1): IDE */ #define PCH_IDE_DEV PCI_BDF(0, 0x1f, 1) #define PCH_SATA_DEV PCI_BDF(0, 0x1f, 2) #define PCH_SATA2_DEV PCI_BDF(0, 0x1f, 5) -#define INTR_LN 0x3c -#define IDE_TIM_PRI 0x40 /* IDE timings, primary */ -#define IDE_DECODE_ENABLE (1 << 15) -#define IDE_SITRE (1 << 14) -#define IDE_ISP_5_CLOCKS (0 << 12) -#define IDE_ISP_4_CLOCKS (1 << 12) -#define IDE_ISP_3_CLOCKS (2 << 12) -#define IDE_RCT_4_CLOCKS (0 << 8) -#define IDE_RCT_3_CLOCKS (1 << 8) -#define IDE_RCT_2_CLOCKS (2 << 8) -#define IDE_RCT_1_CLOCKS (3 << 8) -#define IDE_DTE1 (1 << 7) -#define IDE_PPE1 (1 << 6) -#define IDE_IE1 (1 << 5) -#define IDE_TIME1 (1 << 4) -#define IDE_DTE0 (1 << 3) -#define IDE_PPE0 (1 << 2) -#define IDE_IE0 (1 << 1) -#define IDE_TIME0 (1 << 0) -#define IDE_TIM_SEC 0x42 /* IDE timings, secondary */ - #define IDE_SDMA_CNT 0x48 /* Synchronous DMA control */ #define IDE_SSDE1 (1 << 3) #define IDE_SSDE0 (1 << 2) @@ -211,13 +160,6 @@ #define SMBUS_TIMEOUT (10 * 1000 * 100) - -/* Root Complex Register Block */ -#define DEFAULT_RCBA 0xfed1c000 -#define RCB_REG(reg) (DEFAULT_RCBA + (reg)) - -#define PCH_RCBA_BASE 0xf0 - #define VCH 0x0000 /* 32bit */ #define VCAP1 0x0004 /* 32bit */ #define VCAP2 0x0008 /* 32bit */ @@ -339,16 +281,12 @@ #define SPI_FREQ_SWSEQ 0x3893 #define SPI_DESC_COMP0 0x38b0 #define SPI_FREQ_WR_ERA 0x38b4 -#define SOFT_RESET_CTRL 0x38f4 -#define SOFT_RESET_DATA 0x38f8 #define DIR_ROUTE(a, b, c, d) \ (((d) << DIR_IDR) | ((c) << DIR_ICR) | \ ((b) << DIR_IBR) | ((a) << DIR_IAR)) -#define RC 0x3400 /* 32bit */ #define HPTC 0x3404 /* 32bit */ -#define GCS 0x3410 /* 32bit */ #define BUC 0x3414 /* 32bit */ #define PCH_DISABLE_GBE (1 << 5) #define FD 0x3418 /* 32bit */ diff --git a/arch/x86/include/asm/arch-ivybridge/sandybridge.h b/arch/x86/include/asm/arch-ivybridge/sandybridge.h index d137d6786a..8e0f668f0b 100644 --- a/arch/x86/include/asm/arch-ivybridge/sandybridge.h +++ b/arch/x86/include/asm/arch-ivybridge/sandybridge.h @@ -38,7 +38,6 @@ #define IED_SIZE 0x400000 /* Northbridge BARs */ -#define DEFAULT_MCHBAR 0xfed10000 /* 16 KB */ #define DEFAULT_DMIBAR 0xfed18000 /* 4 KB */ #define DEFAULT_EPBAR 0xfed19000 /* 4 KB */ #define DEFAULT_RCBABASE 0xfed1c000 @@ -97,8 +96,6 @@ /* * MCHBAR */ -#define MCHBAR_REG(reg) (DEFAULT_MCHBAR + (reg)) - #define SSKPD 0x5d14 /* 16bit (scratchpad) */ #define BIOS_RESET_CPL 0x5da8 /* 8bit */ @@ -116,8 +113,4 @@ */ int bridge_silicon_revision(struct udevice *dev); -void report_platform_info(struct udevice *dev); - -void sandybridge_early_init(int chipset_type); - #endif diff --git a/arch/x86/include/asm/arch-coreboot/tables.h b/arch/x86/include/asm/coreboot_tables.h index e254484e75..15ccf9be6c 100644 --- a/arch/x86/include/asm/arch-coreboot/tables.h +++ b/arch/x86/include/asm/coreboot_tables.h @@ -9,8 +9,6 @@ #ifndef _COREBOOT_TABLES_H #define _COREBOOT_TABLES_H -#include <linux/compiler.h> - struct cbuint64 { u32 lo; u32 hi; @@ -30,8 +28,8 @@ struct cb_record { u32 size; }; -#define CB_TAG_UNUSED 0x0000 -#define CB_TAG_MEMORY 0x0001 +#define CB_TAG_UNUSED 0x0000 +#define CB_TAG_MEMORY 0x0001 struct cb_memory_range { struct cbuint64 start; @@ -39,13 +37,13 @@ struct cb_memory_range { u32 type; }; -#define CB_MEM_RAM 1 -#define CB_MEM_RESERVED 2 -#define CB_MEM_ACPI 3 -#define CB_MEM_NVS 4 -#define CB_MEM_UNUSABLE 5 -#define CB_MEM_VENDOR_RSVD 6 -#define CB_MEM_TABLE 16 +#define CB_MEM_RAM 1 +#define CB_MEM_RESERVED 2 +#define CB_MEM_ACPI 3 +#define CB_MEM_NVS 4 +#define CB_MEM_UNUSABLE 5 +#define CB_MEM_VENDOR_RSVD 6 +#define CB_MEM_TABLE 16 struct cb_memory { u32 tag; @@ -53,7 +51,7 @@ struct cb_memory { struct cb_memory_range map[0]; }; -#define CB_TAG_HWRPB 0x0002 +#define CB_TAG_HWRPB 0x0002 struct cb_hwrpb { u32 tag; @@ -61,7 +59,7 @@ struct cb_hwrpb { u64 hwrpb; }; -#define CB_TAG_MAINBOARD 0x0003 +#define CB_TAG_MAINBOARD 0x0003 struct cb_mainboard { u32 tag; @@ -71,16 +69,16 @@ struct cb_mainboard { u8 strings[0]; }; -#define CB_TAG_VERSION 0x0004 -#define CB_TAG_EXTRA_VERSION 0x0005 -#define CB_TAG_BUILD 0x0006 -#define CB_TAG_COMPILE_TIME 0x0007 -#define CB_TAG_COMPILE_BY 0x0008 -#define CB_TAG_COMPILE_HOST 0x0009 -#define CB_TAG_COMPILE_DOMAIN 0x000a -#define CB_TAG_COMPILER 0x000b -#define CB_TAG_LINKER 0x000c -#define CB_TAG_ASSEMBLER 0x000d +#define CB_TAG_VERSION 0x0004 +#define CB_TAG_EXTRA_VERSION 0x0005 +#define CB_TAG_BUILD 0x0006 +#define CB_TAG_COMPILE_TIME 0x0007 +#define CB_TAG_COMPILE_BY 0x0008 +#define CB_TAG_COMPILE_HOST 0x0009 +#define CB_TAG_COMPILE_DOMAIN 0x000a +#define CB_TAG_COMPILER 0x000b +#define CB_TAG_LINKER 0x000c +#define CB_TAG_ASSEMBLER 0x000d struct cb_string { u32 tag; @@ -88,19 +86,19 @@ struct cb_string { u8 string[0]; }; -#define CB_TAG_SERIAL 0x000f +#define CB_TAG_SERIAL 0x000f struct cb_serial { u32 tag; u32 size; -#define CB_SERIAL_TYPE_IO_MAPPED 1 -#define CB_SERIAL_TYPE_MEMORY_MAPPED 2 +#define CB_SERIAL_TYPE_IO_MAPPED 1 +#define CB_SERIAL_TYPE_MEMORY_MAPPED 2 u32 type; u32 baseaddr; u32 baud; }; -#define CB_TAG_CONSOLE 0x00010 +#define CB_TAG_CONSOLE 0x0010 struct cb_console { u32 tag; @@ -108,14 +106,14 @@ struct cb_console { u16 type; }; -#define CB_TAG_CONSOLE_SERIAL8250 0 -#define CB_TAG_CONSOLE_VGA 1 /* OBSOLETE */ -#define CB_TAG_CONSOLE_BTEXT 2 /* OBSOLETE */ -#define CB_TAG_CONSOLE_LOGBUF 3 -#define CB_TAG_CONSOLE_SROM 4 /* OBSOLETE */ -#define CB_TAG_CONSOLE_EHCI 5 +#define CB_TAG_CONSOLE_SERIAL8250 0 +#define CB_TAG_CONSOLE_VGA 1 /* OBSOLETE */ +#define CB_TAG_CONSOLE_BTEXT 2 /* OBSOLETE */ +#define CB_TAG_CONSOLE_LOGBUF 3 +#define CB_TAG_CONSOLE_SROM 4 /* OBSOLETE */ +#define CB_TAG_CONSOLE_EHCI 5 -#define CB_TAG_FORWARD 0x00011 +#define CB_TAG_FORWARD 0x0011 struct cb_forward { u32 tag; @@ -123,11 +121,11 @@ struct cb_forward { u64 forward; }; -#define CB_TAG_FRAMEBUFFER 0x0012 +#define CB_TAG_FRAMEBUFFER 0x0012 + struct cb_framebuffer { u32 tag; u32 size; - u64 physical_address; u32 x_resolution; u32 y_resolution; @@ -143,8 +141,9 @@ struct cb_framebuffer { u8 reserved_mask_size; }; -#define CB_TAG_GPIO 0x0013 -#define GPIO_MAX_NAME_LENGTH 16 +#define CB_TAG_GPIO 0x0013 +#define GPIO_MAX_NAME_LENGTH 16 + struct cb_gpio { u32 port; u32 polarity; @@ -155,36 +154,39 @@ struct cb_gpio { struct cb_gpios { u32 tag; u32 size; - u32 count; struct cb_gpio gpios[0]; }; -#define CB_TAG_FDT 0x0014 +#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 +#define CB_TAG_VDAT 0x0015 + struct cb_vdat { uint32_t tag; uint32_t size; /* size of the entire entry */ - void *vdat_addr; + void *vdat_addr; uint32_t vdat_size; }; -#define CB_TAG_TIMESTAMPS 0x0016 -#define CB_TAG_CBMEM_CONSOLE 0x0017 -#define CB_TAG_MRC_CACHE 0x0018 +#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; + void *cbmem_tab; }; -#define CB_TAG_VBNV 0x0019 +#define CB_TAG_VBNV 0x0019 + struct cb_vbnv { uint32_t tag; uint32_t size; @@ -192,15 +194,18 @@ struct cb_vbnv { uint32_t vbnv_size; }; -#define CB_TAG_CMOS_OPTION_TABLE 0x00c8 +#define CB_TAG_CMOS_OPTION_TABLE 0x00c8 + struct cb_cmos_option_table { u32 tag; u32 size; u32 header_length; }; -#define CB_TAG_OPTION 0x00c9 -#define CMOS_MAX_NAME_LENGTH 32 +#define CB_TAG_OPTION 0x00c9 + +#define CMOS_MAX_NAME_LENGTH 32 + struct cb_cmos_entries { u32 tag; u32 size; @@ -211,9 +216,9 @@ struct cb_cmos_entries { u8 name[CMOS_MAX_NAME_LENGTH]; }; +#define CB_TAG_OPTION_ENUM 0x00ca +#define CMOS_MAX_TEXT_LENGTH 32 -#define CB_TAG_OPTION_ENUM 0x00ca -#define CMOS_MAX_TEXT_LENGTH 32 struct cb_cmos_enums { u32 tag; u32 size; @@ -222,8 +227,9 @@ struct cb_cmos_enums { u8 text[CMOS_MAX_TEXT_LENGTH]; }; -#define CB_TAG_OPTION_DEFAULTS 0x00cb -#define CMOS_IMAGE_BUFFER_SIZE 128 +#define CB_TAG_OPTION_DEFAULTS 0x00cb +#define CMOS_IMAGE_BUFFER_SIZE 128 + struct cb_cmos_defaults { u32 tag; u32 size; @@ -232,9 +238,10 @@ struct cb_cmos_defaults { u8 default_set[CMOS_IMAGE_BUFFER_SIZE]; }; -#define CB_TAG_OPTION_CHECKSUM 0x00cc -#define CHECKSUM_NONE 0 -#define CHECKSUM_PCBIOS 1 +#define CB_TAG_OPTION_CHECKSUM 0x00cc +#define CHECKSUM_NONE 0 +#define CHECKSUM_PCBIOS 1 + struct cb_cmos_checksum { u32 tag; u32 size; @@ -262,13 +269,9 @@ struct cb_cmos_checksum { #define UNPACK_CB64(_in) \ ((((u64) _in.hi) << 32) | _in.lo) -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 +#define CBMEM_TOC_RESERVED 512 +#define MAX_CBMEM_ENTRIES 16 +#define CBMEM_MAGIC 0x434f5245 struct cbmem_entry { u32 magic; @@ -277,18 +280,28 @@ struct cbmem_entry { 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 +#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 + +/** + * write_coreboot_table() - write coreboot table + * + * This writes coreboot table at a given address. + * + * @addr: start address to write coreboot table + * @cfg_tables: pointer to configuration table memory area + */ +void write_coreboot_table(u32 addr, struct memory_area *cfg_tables); #endif diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index 18b0345986..789275792f 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -54,6 +54,7 @@ enum { X86_NONE, X86_SYSCON_ME, /* Intel Management Engine */ X86_SYSCON_GMA, /* Intel Graphics Media Accelerator */ + X86_SYSCON_PINCONF, /* Intel x86 pin configuration */ }; struct cpuid_result { @@ -260,4 +261,30 @@ void cpu_call32(ulong code_seg32, ulong target, ulong table); */ int cpu_jump_to_64bit(ulong setup_base, ulong target); +/** + * cpu_get_family_model() - Get the family and model for the CPU + * + * @return the CPU ID masked with 0x0fff0ff0 + */ +u32 cpu_get_family_model(void); + +/** + * cpu_get_stepping() - Get the stepping value for the CPU + * + * @return the CPU ID masked with 0xf + */ +u32 cpu_get_stepping(void); + +/** + * cpu_run_reference_code() - Run the platform reference code + * + * Some platforms require a binary blob to be executed once SDRAM is + * available. This is used to set up various platform features, such as the + * platform controller hub (PCH). This function should be implemented by the + * CPU-specific code. + * + * @return 0 on success, -ve on failure + */ +int cpu_run_reference_code(void); + #endif diff --git a/arch/x86/include/asm/cpu_common.h b/arch/x86/include/asm/cpu_common.h new file mode 100644 index 0000000000..562de3e27f --- /dev/null +++ b/arch/x86/include/asm/cpu_common.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __ASM_CPU_COMMON_H +#define __ASM_CPU_COMMON_H + +#define IA32_PERF_CTL 0x199 + +/** + * cpu_common_init() - Set up common CPU init + * + * This reports BIST failure, enables the LAPIC, updates microcode, enables + * the upper 128-bytes of CROM RAM, probes the northbridge, PCH, LPC and SATA. + * + * @return 0 if OK, -ve on error + */ +int cpu_common_init(void); + +/** + * cpu_set_flex_ratio_to_tdp_nominal() - Set up the maximum non-turbo rate + * + * If a change is needed, this function will do a soft reset so it takes + * effect. + * + * Some details are available here: + * http://forum.hwbot.org/showthread.php?t=76092 + * + * @return 0 if OK, -ve on error + */ +int cpu_set_flex_ratio_to_tdp_nominal(void); + +#endif diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index 0ca518ca38..3bc2ac24cf 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -19,6 +19,29 @@ enum pei_boot_mode_t { }; +struct dimm_info { + uint32_t dimm_size; + uint16_t ddr_type; + uint16_t ddr_frequency; + uint8_t rank_per_dimm; + uint8_t channel_num; + uint8_t dimm_num; + uint8_t bank_locator; + /* The 5th byte is '\0' for the end of string */ + uint8_t serial[5]; + /* The 19th byte is '\0' for the end of string */ + uint8_t module_part_number[19]; + uint16_t mod_id; + uint8_t mod_type; + uint8_t bus_width; +} __packed; + +struct pei_memory_info { + uint8_t dimm_cnt; + /* Maximum num of dimm is 8 */ + struct dimm_info dimm[8]; +} __packed; + struct memory_area { uint64_t start; uint64_t size; @@ -59,6 +82,7 @@ struct arch_global_data { enum pei_boot_mode_t pei_boot_mode; const struct pch_gpio_map *gpio_map; /* board GPIO map */ struct memory_info meminfo; /* Memory information */ + struct pei_memory_info pei_meminfo; /* PEI memory information */ #ifdef CONFIG_HAVE_FSP void *hob_list; /* FSP HOB list */ #endif diff --git a/arch/x86/include/asm/gpio.h b/arch/x86/include/asm/gpio.h index 403851b792..586ece6c10 100644 --- a/arch/x86/include/asm/gpio.h +++ b/arch/x86/include/asm/gpio.h @@ -6,148 +6,12 @@ #ifndef _X86_GPIO_H_ #define _X86_GPIO_H_ -#include <linux/compiler.h> #include <asm-generic/gpio.h> struct ich6_bank_platdata { uint16_t base_addr; const char *bank_name; + int offset; }; -#define GPIO_MODE_NATIVE 0 -#define GPIO_MODE_GPIO 1 -#define GPIO_MODE_NONE 1 - -#define GPIO_DIR_OUTPUT 0 -#define GPIO_DIR_INPUT 1 - -#define GPIO_NO_INVERT 0 -#define GPIO_INVERT 1 - -#define GPIO_LEVEL_LOW 0 -#define GPIO_LEVEL_HIGH 1 - -#define GPIO_NO_BLINK 0 -#define GPIO_BLINK 1 - -#define GPIO_RESET_PWROK 0 -#define GPIO_RESET_RSMRST 1 - -struct pch_gpio_set1 { - u32 gpio0:1; - u32 gpio1:1; - u32 gpio2:1; - u32 gpio3:1; - u32 gpio4:1; - u32 gpio5:1; - u32 gpio6:1; - u32 gpio7:1; - u32 gpio8:1; - u32 gpio9:1; - u32 gpio10:1; - u32 gpio11:1; - u32 gpio12:1; - u32 gpio13:1; - u32 gpio14:1; - u32 gpio15:1; - u32 gpio16:1; - u32 gpio17:1; - u32 gpio18:1; - u32 gpio19:1; - u32 gpio20:1; - u32 gpio21:1; - u32 gpio22:1; - u32 gpio23:1; - u32 gpio24:1; - u32 gpio25:1; - u32 gpio26:1; - u32 gpio27:1; - u32 gpio28:1; - u32 gpio29:1; - u32 gpio30:1; - u32 gpio31:1; -} __packed; - -struct pch_gpio_set2 { - u32 gpio32:1; - u32 gpio33:1; - u32 gpio34:1; - u32 gpio35:1; - u32 gpio36:1; - u32 gpio37:1; - u32 gpio38:1; - u32 gpio39:1; - u32 gpio40:1; - u32 gpio41:1; - u32 gpio42:1; - u32 gpio43:1; - u32 gpio44:1; - u32 gpio45:1; - u32 gpio46:1; - u32 gpio47:1; - u32 gpio48:1; - u32 gpio49:1; - u32 gpio50:1; - u32 gpio51:1; - u32 gpio52:1; - u32 gpio53:1; - u32 gpio54:1; - u32 gpio55:1; - u32 gpio56:1; - u32 gpio57:1; - u32 gpio58:1; - u32 gpio59:1; - u32 gpio60:1; - u32 gpio61:1; - u32 gpio62:1; - u32 gpio63:1; -} __packed; - -struct pch_gpio_set3 { - u32 gpio64:1; - u32 gpio65:1; - u32 gpio66:1; - u32 gpio67:1; - u32 gpio68:1; - u32 gpio69:1; - u32 gpio70:1; - u32 gpio71:1; - u32 gpio72:1; - u32 gpio73:1; - u32 gpio74:1; - u32 gpio75:1; -} __packed; - -/* - * This hilariously complex structure came from Coreboot. The - * setup_pch_gpios() function uses it. It could be move to device tree, or - * adjust to use masks instead of bitfields. - */ -struct pch_gpio_map { - struct { - const struct pch_gpio_set1 *mode; - const struct pch_gpio_set1 *direction; - const struct pch_gpio_set1 *level; - const struct pch_gpio_set1 *reset; - const struct pch_gpio_set1 *invert; - const struct pch_gpio_set1 *blink; - } set1; - struct { - const struct pch_gpio_set2 *mode; - const struct pch_gpio_set2 *direction; - const struct pch_gpio_set2 *level; - const struct pch_gpio_set2 *reset; - } set2; - struct { - const struct pch_gpio_set3 *mode; - const struct pch_gpio_set3 *direction; - const struct pch_gpio_set3 *level; - const struct pch_gpio_set3 *reset; - } set3; -}; - -int gpio_ich6_pinctrl_init(void); -void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio); -void ich_gpio_set_gpio_map(const struct pch_gpio_map *map); - #endif /* _X86_GPIO_H_ */ diff --git a/arch/x86/include/asm/intel_regs.h b/arch/x86/include/asm/intel_regs.h new file mode 100644 index 0000000000..d2a6d2690e --- /dev/null +++ b/arch/x86/include/asm/intel_regs.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __ASM_INTEL_REGS_H +#define __ASM_INTEL_REGS_H + +/* Access the memory-controller hub */ +#define MCH_BASE_ADDRESS 0xfed10000 +#define MCH_BASE_SIZE 0x8000 +#define MCHBAR_REG(reg) (MCH_BASE_ADDRESS + (reg)) + +#define MCHBAR_PEI_VERSION 0x5034 +#define MCH_PKG_POWER_LIMIT_LO 0x59a0 +#define MCH_PKG_POWER_LIMIT_HI 0x59a4 +#define MCH_DDR_POWER_LIMIT_LO 0x58e0 +#define MCH_DDR_POWER_LIMIT_HI 0x58e4 + +/* Access the Root Complex Register Block */ +#define RCB_BASE_ADDRESS 0xfed1c000 +#define RCB_REG(reg) (RCB_BASE_ADDRESS + (reg)) + +#define SOFT_RESET_CTRL 0x38f4 +#define SOFT_RESET_DATA 0x38f8 + +#endif diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index e0b25619cd..3156781dd3 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -202,7 +202,7 @@ out: * Talk about misusing macros.. */ #define __OUT1(s,x) \ -static inline void out##s(unsigned x value, unsigned short port) { +static inline void _out##s(unsigned x value, unsigned short port) { #define __OUT2(s,s1,s2) \ __asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" @@ -213,7 +213,7 @@ __OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \ __OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} #define __IN1(s) \ -static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v; +static inline RETURN_TYPE _in##s(unsigned short port) { RETURN_TYPE _v; #define __IN2(s,s1,s2) \ __asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" @@ -242,10 +242,18 @@ __IN(w,"") __IN(l,"") #undef RETURN_TYPE +#define inb(port) _inb((uintptr_t)(port)) +#define inw(port) _inw((uintptr_t)(port)) +#define inl(port) _inl((uintptr_t)(port)) + __OUT(b,"b",char) __OUT(w,"w",short) __OUT(l,,int) +#define outb(val, port) _outb(val, (uintptr_t)(port)) +#define outw(val, port) _outw(val, (uintptr_t)(port)) +#define outl(val, port) _outl(val, (uintptr_t)(port)) + __INS(b) __INS(w) __INS(l) @@ -254,6 +262,28 @@ __OUTS(b) __OUTS(w) __OUTS(l) +/* IO space accessors */ +#define clrio(type, addr, clear) \ + out##type(in##type(addr) & ~(clear), (addr)) + +#define setio(type, addr, set) \ + out##type(in##type(addr) | (set), (addr)) + +#define clrsetio(type, addr, clear, set) \ + out##type((in##type(addr) & ~(clear)) | (set), (addr)) + +#define clrio_32(addr, clear) clrio(l, addr, clear) +#define clrio_16(addr, clear) clrio(w, addr, clear) +#define clrio_8(addr, clear) clrio(b, addr, clear) + +#define setio_32(addr, set) setio(l, addr, set) +#define setio_16(addr, set) setio(w, addr, set) +#define setio_8(addr, set) setio(b, addr, set) + +#define clrsetio_32(addr, clear, set) clrsetio(l, addr, clear, set) +#define clrsetio_16(addr, clear, set) clrsetio(w, addr, clear, set) +#define clrsetio_8(addr, clear, set) clrsetio(b, addr, clear, set) + static inline void sync(void) { } diff --git a/arch/x86/include/asm/ioapic.h b/arch/x86/include/asm/ioapic.h index 77c443e9f5..2feed864fe 100644 --- a/arch/x86/include/asm/ioapic.h +++ b/arch/x86/include/asm/ioapic.h @@ -39,4 +39,6 @@ u32 io_apic_read(u32 reg); */ void io_apic_write(u32 reg, u32 val); +void io_apic_set_id(int ioapic_id); + #endif diff --git a/arch/x86/include/asm/lpc_common.h b/arch/x86/include/asm/lpc_common.h new file mode 100644 index 0000000000..a90a22db3d --- /dev/null +++ b/arch/x86/include/asm/lpc_common.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __ASM_LPC_COMMON_H +#define __ASM_LPC_COMMON_H + +#define PCH_RCBA_BASE 0xf0 + +#define RC 0x3400 /* 32bit */ +#define GCS 0x3410 /* 32bit */ + +#define PMBASE 0x40 +#define ACPI_CNTL 0x44 + +#define LPC_IO_DEC 0x80 /* IO Decode Ranges Register */ +#define COMB_DEC_RANGE (1 << 4) /* 0x2f8-0x2ff (COM2) */ +#define COMA_DEC_RANGE (0 << 0) /* 0x3f8-0x3ff (COM1) */ +#define LPC_EN 0x82 /* LPC IF Enables Register */ +#define CNF2_LPC_EN (1 << 13) /* 0x4e/0x4f */ +#define CNF1_LPC_EN (1 << 12) /* 0x2e/0x2f */ +#define MC_LPC_EN (1 << 11) /* 0x62/0x66 */ +#define KBC_LPC_EN (1 << 10) /* 0x60/0x64 */ +#define GAMEH_LPC_EN (1 << 9) /* 0x208/0x20f */ +#define GAMEL_LPC_EN (1 << 8) /* 0x200/0x207 */ +#define FDD_LPC_EN (1 << 3) /* LPC_IO_DEC[12] */ +#define LPT_LPC_EN (1 << 2) /* LPC_IO_DEC[9:8] */ +#define COMB_LPC_EN (1 << 1) /* LPC_IO_DEC[6:4] */ +#define COMA_LPC_EN (1 << 0) /* LPC_IO_DEC[3:2] */ +#define LPC_GEN1_DEC 0x84 /* LPC IF Generic Decode Range 1 */ +#define LPC_GEN2_DEC 0x88 /* LPC IF Generic Decode Range 2 */ +#define LPC_GEN3_DEC 0x8c /* LPC IF Generic Decode Range 3 */ +#define LPC_GEN4_DEC 0x90 /* LPC IF Generic Decode Range 4 */ +#define LPC_GENX_DEC(x) (0x84 + 4 * (x)) +#define GEN_DEC_RANGE_256B 0xfc0000 /* 256 Bytes */ +#define GEN_DEC_RANGE_128B 0x7c0000 /* 128 Bytes */ +#define GEN_DEC_RANGE_64B 0x3c0000 /* 64 Bytes */ +#define GEN_DEC_RANGE_32B 0x1c0000 /* 32 Bytes */ +#define GEN_DEC_RANGE_16B 0x0c0000 /* 16 Bytes */ +#define GEN_DEC_RANGE_8B 0x040000 /* 8 Bytes */ +#define GEN_DEC_RANGE_4B 0x000000 /* 4 Bytes */ +#define GEN_DEC_RANGE_EN (1 << 0) /* Range Enable */ + +/** + * lpc_common_early_init() - Set up common LPC init + * + * This sets up the legacy decode areas, GEN_DEC, SPI prefetch and Port80. It + * also puts the RCB in the correct place so that RCB_REG() works. + * + * @dev: LPC device (a child of the PCH) + * @return 0 on success, -ve on error + */ +int lpc_common_early_init(struct udevice *dev); + +int lpc_set_spi_protect(struct udevice *dev, int bios_ctrl, bool protect); + +#endif diff --git a/arch/x86/include/asm/me_common.h b/arch/x86/include/asm/me_common.h new file mode 100644 index 0000000000..2e2251cc1c --- /dev/null +++ b/arch/x86/include/asm/me_common.h @@ -0,0 +1,373 @@ +/* + * From Coreboot src/southbridge/intel/bd82x6x/me.h + * + * Coreboot copies lots of code around. Here we are trying to keep the common + * code in a separate file to reduce code duplication and hopefully make it + * easier to add new platform. + * + * Copyright (C) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __ASM_ME_COMMON_H +#define __ASM_ME_COMMON_H + +#include <linux/compiler.h> +#include <linux/types.h> +#include <pci.h> + +#define MCHBAR_PEI_VERSION 0x5034 + +#define ME_RETRY 100000 /* 1 second */ +#define ME_DELAY 10 /* 10 us */ + +/* + * Management Engine PCI registers + */ + +#define PCI_CPU_MEBASE_L 0x70 /* Set by MRC */ +#define PCI_CPU_MEBASE_H 0x74 /* Set by MRC */ + +#define PCI_ME_HFS 0x40 +#define ME_HFS_CWS_RESET 0 +#define ME_HFS_CWS_INIT 1 +#define ME_HFS_CWS_REC 2 +#define ME_HFS_CWS_NORMAL 5 +#define ME_HFS_CWS_WAIT 6 +#define ME_HFS_CWS_TRANS 7 +#define ME_HFS_CWS_INVALID 8 +#define ME_HFS_STATE_PREBOOT 0 +#define ME_HFS_STATE_M0_UMA 1 +#define ME_HFS_STATE_M3 4 +#define ME_HFS_STATE_M0 5 +#define ME_HFS_STATE_BRINGUP 6 +#define ME_HFS_STATE_ERROR 7 +#define ME_HFS_ERROR_NONE 0 +#define ME_HFS_ERROR_UNCAT 1 +#define ME_HFS_ERROR_IMAGE 3 +#define ME_HFS_ERROR_DEBUG 4 +#define ME_HFS_MODE_NORMAL 0 +#define ME_HFS_MODE_DEBUG 2 +#define ME_HFS_MODE_DIS 3 +#define ME_HFS_MODE_OVER_JMPR 4 +#define ME_HFS_MODE_OVER_MEI 5 +#define ME_HFS_BIOS_DRAM_ACK 1 +#define ME_HFS_ACK_NO_DID 0 +#define ME_HFS_ACK_RESET 1 +#define ME_HFS_ACK_PWR_CYCLE 2 +#define ME_HFS_ACK_S3 3 +#define ME_HFS_ACK_S4 4 +#define ME_HFS_ACK_S5 5 +#define ME_HFS_ACK_GBL_RESET 6 +#define ME_HFS_ACK_CONTINUE 7 + +struct me_hfs { + u32 working_state:4; + u32 mfg_mode:1; + u32 fpt_bad:1; + u32 operation_state:3; + u32 fw_init_complete:1; + u32 ft_bup_ld_flr:1; + u32 update_in_progress:1; + u32 error_code:4; + u32 operation_mode:4; + u32 reserved:4; + u32 boot_options_present:1; + u32 ack_data:3; + u32 bios_msg_ack:4; +} __packed; + +#define PCI_ME_UMA 0x44 + +struct me_uma { + u32 size:6; + u32 reserved_1:10; + u32 valid:1; + u32 reserved_0:14; + u32 set_to_one:1; +} __packed; + +#define PCI_ME_H_GS 0x4c +#define ME_INIT_DONE 1 +#define ME_INIT_STATUS_SUCCESS 0 +#define ME_INIT_STATUS_NOMEM 1 +#define ME_INIT_STATUS_ERROR 2 + +struct me_did { + u32 uma_base:16; + u32 reserved:7; + u32 rapid_start:1; /* Broadwell only */ + u32 status:4; + u32 init_done:4; +} __packed; + +#define PCI_ME_GMES 0x48 +#define ME_GMES_PHASE_ROM 0 +#define ME_GMES_PHASE_BUP 1 +#define ME_GMES_PHASE_UKERNEL 2 +#define ME_GMES_PHASE_POLICY 3 +#define ME_GMES_PHASE_MODULE 4 +#define ME_GMES_PHASE_UNKNOWN 5 +#define ME_GMES_PHASE_HOST 6 + +struct me_gmes { + u32 bist_in_prog:1; + u32 icc_prog_sts:2; + u32 invoke_mebx:1; + u32 cpu_replaced_sts:1; + u32 mbp_rdy:1; + u32 mfs_failure:1; + u32 warm_rst_req_for_df:1; + u32 cpu_replaced_valid:1; + u32 reserved_1:2; + u32 fw_upd_ipu:1; + u32 reserved_2:4; + u32 current_state:8; + u32 current_pmevent:4; + u32 progress_code:4; +} __packed; + +#define PCI_ME_HERES 0xbc +#define PCI_ME_EXT_SHA1 0x00 +#define PCI_ME_EXT_SHA256 0x02 +#define PCI_ME_HER(x) (0xc0+(4*(x))) + +struct me_heres { + u32 extend_reg_algorithm:4; + u32 reserved:26; + u32 extend_feature_present:1; + u32 extend_reg_valid:1; +} __packed; + +/* + * Management Engine MEI registers + */ + +#define MEI_H_CB_WW 0x00 +#define MEI_H_CSR 0x04 +#define MEI_ME_CB_RW 0x08 +#define MEI_ME_CSR_HA 0x0c + +struct mei_csr { + u32 interrupt_enable:1; + u32 interrupt_status:1; + u32 interrupt_generate:1; + u32 ready:1; + u32 reset:1; + u32 reserved:3; + u32 buffer_read_ptr:8; + u32 buffer_write_ptr:8; + u32 buffer_depth:8; +} __packed; + +#define MEI_ADDRESS_CORE 0x01 +#define MEI_ADDRESS_AMT 0x02 +#define MEI_ADDRESS_RESERVED 0x03 +#define MEI_ADDRESS_WDT 0x04 +#define MEI_ADDRESS_MKHI 0x07 +#define MEI_ADDRESS_ICC 0x08 +#define MEI_ADDRESS_THERMAL 0x09 + +#define MEI_HOST_ADDRESS 0 + +struct mei_header { + u32 client_address:8; + u32 host_address:8; + u32 length:9; + u32 reserved:6; + u32 is_complete:1; +} __packed; + +#define MKHI_GROUP_ID_CBM 0x00 +#define MKHI_GROUP_ID_FWCAPS 0x03 +#define MKHI_GROUP_ID_MDES 0x08 +#define MKHI_GROUP_ID_GEN 0xff + +#define MKHI_GET_FW_VERSION 0x02 +#define MKHI_END_OF_POST 0x0c +#define MKHI_FEATURE_OVERRIDE 0x14 + +/* Ivybridge only: */ +#define MKHI_GLOBAL_RESET 0x0b +#define MKHI_FWCAPS_GET_RULE 0x02 +#define MKHI_MDES_ENABLE 0x09 + +/* Broadwell only: */ +#define MKHI_GLOBAL_RESET 0x0b +#define MKHI_FWCAPS_GET_RULE 0x02 +#define MKHI_GROUP_ID_HMRFPO 0x05 +#define MKHI_HMRFPO_LOCK 0x02 +#define MKHI_HMRFPO_LOCK_NOACK 0x05 +#define MKHI_MDES_ENABLE 0x09 +#define MKHI_END_OF_POST_NOACK 0x1a + +struct mkhi_header { + u32 group_id:8; + u32 command:7; + u32 is_response:1; + u32 reserved:8; + u32 result:8; +} __packed; + +struct me_fw_version { + u16 code_minor; + u16 code_major; + u16 code_build_number; + u16 code_hot_fix; + u16 recovery_minor; + u16 recovery_major; + u16 recovery_build_number; + u16 recovery_hot_fix; +} __packed; + + +#define HECI_EOP_STATUS_SUCCESS 0x0 +#define HECI_EOP_PERFORM_GLOBAL_RESET 0x1 + +#define CBM_RR_GLOBAL_RESET 0x01 + +#define GLOBAL_RESET_BIOS_MRC 0x01 +#define GLOBAL_RESET_BIOS_POST 0x02 +#define GLOBAL_RESET_MEBX 0x03 + +struct me_global_reset { + u8 request_origin; + u8 reset_type; +} __packed; + +enum me_bios_path { + ME_NORMAL_BIOS_PATH, + ME_S3WAKE_BIOS_PATH, + ME_ERROR_BIOS_PATH, + ME_RECOVERY_BIOS_PATH, + ME_DISABLE_BIOS_PATH, + ME_FIRMWARE_UPDATE_BIOS_PATH, +}; + +struct __packed mefwcaps_sku { + u32 full_net:1; + u32 std_net:1; + u32 manageability:1; + u32 small_business:1; + u32 l3manageability:1; + u32 intel_at:1; + u32 intel_cls:1; + u32 reserved:3; + u32 intel_mpc:1; + u32 icc_over_clocking:1; + u32 pavp:1; + u32 reserved_1:4; + u32 ipv6:1; + u32 kvm:1; + u32 och:1; + u32 vlan:1; + u32 tls:1; + u32 reserved_4:1; + u32 wlan:1; + u32 reserved_5:8; +}; + +struct __packed tdt_state_flag { + u16 lock_state:1; + u16 authenticate_module:1; + u16 s3authentication:1; + u16 flash_wear_out:1; + u16 flash_variable_security:1; + u16 wwan3gpresent:1; /* ivybridge only */ + u16 wwan3goob:1; /* ivybridge only */ + u16 reserved:9; +}; + +struct __packed tdt_state_info { + u8 state; + u8 last_theft_trigger; + struct tdt_state_flag flags; +}; + +struct __packed mbp_rom_bist_data { + u16 device_id; + u16 fuse_test_flags; + u32 umchid[4]; +}; + +struct __packed mbp_platform_key { + u32 key[8]; +}; + +struct __packed mbp_header { + u32 mbp_size:8; + u32 num_entries:8; + u32 rsvd:16; +}; + +struct __packed mbp_item_header { + u32 app_id:8; + u32 item_id:8; + u32 length:8; + u32 rsvd:8; +}; + +struct __packed me_fwcaps { + u32 id; + u8 length; + struct mefwcaps_sku caps_sku; + u8 reserved[3]; +}; + +/** + * intel_me_status() - Check Intel Management Engine status + * + * @me_dev: Management engine PCI device + */ +void intel_me_status(struct udevice *me_dev); + +/** + * intel_early_me_init() - Early Intel Management Engine init + * + * @me_dev: Management engine PCI device + * @return 0 if OK, -ve on error + */ +int intel_early_me_init(struct udevice *me_dev); + +/** + * intel_early_me_uma_size() - Get UMA size from the Intel Management Engine + * + * @me_dev: Management engine PCI device + * @return UMA size if OK, -EINVAL on error + */ +int intel_early_me_uma_size(struct udevice *me_dev); + +/** + * intel_early_me_init_done() - Complete Intel Management Engine init + * + * @dev: Northbridge device + * @me_dev: Management engine PCI device + * @status: Status result (ME_INIT_...) + * @return 0 to continue to boot, -EINVAL on unknown result data, -ETIMEDOUT + * if ME did not respond + */ +int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev, + uint status); + +int intel_me_hsio_version(struct udevice *dev, uint16_t *version, + uint16_t *checksum); + +static inline void pci_read_dword_ptr(struct udevice *me_dev, void *ptr, + int offset) +{ + u32 dword; + + dm_pci_read_config32(me_dev, offset, &dword); + memcpy(ptr, &dword, sizeof(dword)); +} + +static inline void pci_write_dword_ptr(struct udevice *me_dev, void *ptr, + int offset) +{ + u32 dword = 0; + + memcpy(&dword, ptr, sizeof(dword)); + dm_pci_write_config32(me_dev, offset, dword); +} +#endif diff --git a/arch/x86/include/asm/arch-ivybridge/microcode.h b/arch/x86/include/asm/microcode.h index 67f32cc38f..29bf060889 100644 --- a/arch/x86/include/asm/arch-ivybridge/microcode.h +++ b/arch/x86/include/asm/microcode.h @@ -9,6 +9,9 @@ #ifndef __ASSEMBLY__ +/* This is a declaration for ucode_base in start.S */ +extern u32 ucode_base; + /** * microcode_update_intel() - Apply microcode updates * @@ -18,6 +21,15 @@ * not updates were found, -EINVAL if an update was invalid */ int microcode_update_intel(void); + +/** + * microcode_read_rev() - Read the microcode version + * + * This reads the microcode version of the currently running CPU + * + * @return microcode version number + */ +int microcode_read_rev(void); #endif /* __ASSEMBLY__ */ #endif diff --git a/arch/x86/include/asm/mrc_common.h b/arch/x86/include/asm/mrc_common.h new file mode 100644 index 0000000000..cad24f22ad --- /dev/null +++ b/arch/x86/include/asm/mrc_common.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __ASM_MRC_COMMON_H +#define __ASM_MRC_COMMON_H + +#include <linux/linkage.h> + +/** + * mrc_common_init() - Set up SDRAM + * + * This calls the memory reference code (MRC) to set up SDRAM + * + * @dev: Northbridge device + * @pei_data: Platform-specific data required by the MRC + * @use_asm_linkage: true if the call to MRC requires asmlinkage, false if it + * uses normal U-Boot calling + * @return 0 if OK, -ve on error + */ +int mrc_common_init(struct udevice *dev, void *pei_data, bool use_asm_linkage); + +asmlinkage void sdram_console_tx_byte(unsigned char byte); + +int mrc_locate_spd(struct udevice *dev, int size, const void **spd_datap); + +void report_memory_config(void); + +/** + * mrc_add_memory_area() - Add a new usable memory area to our list + * + * Note: @start and @end must not span the first 4GB boundary + * + * @info: Place to store memory info + * @start: Start of this memory area + * @end: End of this memory area + 1 + */ +int mrc_add_memory_area(struct memory_info *info, uint64_t start, + uint64_t end); + +/* + * 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. + */ +ulong mrc_common_board_get_usable_ram_top(ulong total_size); + +void mrc_common_dram_init_banksize(void); + +#endif diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 38dbb3137a..b2a03f469a 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -41,6 +41,9 @@ #define EFER_FFXSR (1<<_EFER_FFXSR) /* Intel MSRs. Some also available on other CPUs */ +#define MSR_PIC_MSG_CONTROL 0x2e +#define PLATFORM_INFO_SET_TDP (1 << 29) + #define MSR_IA32_PERFCTR0 0x000000c1 #define MSR_IA32_PERFCTR1 0x000000c2 #define MSR_FSB_FREQ 0x000000cd @@ -73,14 +76,27 @@ #define MSR_IA32_MCG_STATUS 0x0000017a #define MSR_IA32_MCG_CTL 0x0000017b +#define MSR_FLEX_RATIO 0x194 +#define FLEX_RATIO_LOCK (1 << 20) +#define FLEX_RATIO_EN (1 << 16) + #define MSR_IA32_MISC_ENABLES 0x000001a0 +#define MSR_TEMPERATURE_TARGET 0x1a2 #define MSR_OFFCORE_RSP_0 0x000001a6 #define MSR_OFFCORE_RSP_1 0x000001a7 +#define MSR_MISC_PWR_MGMT 0x1aa +#define MISC_PWR_MGMT_EIST_HW_DIS (1 << 0) #define MSR_NHM_TURBO_RATIO_LIMIT 0x000001ad #define MSR_IVT_TURBO_RATIO_LIMIT 0x000001ae +#define MSR_IA32_ENERGY_PERFORMANCE_BIAS 0x1b0 +#define ENERGY_POLICY_PERFORMANCE 0 +#define ENERGY_POLICY_NORMAL 6 +#define ENERGY_POLICY_POWERSAVE 15 + #define MSR_LBR_SELECT 0x000001c8 #define MSR_LBR_TOS 0x000001c9 +#define MSR_IA32_PLATFORM_DCA_CAP 0x1f8 #define MSR_POWER_CTL 0x000001fc #define MSR_LBR_NHM_FROM 0x00000680 #define MSR_LBR_NHM_TO 0x000006c0 @@ -147,7 +163,29 @@ #define MSR_PKG_POWER_SKU_UNIT 0x00000606 +#define MSR_C_STATE_LATENCY_CONTROL_0 0x60a +#define MSR_C_STATE_LATENCY_CONTROL_1 0x60b +#define MSR_C_STATE_LATENCY_CONTROL_2 0x60c +#define MSR_C_STATE_LATENCY_CONTROL_3 0x633 +#define MSR_C_STATE_LATENCY_CONTROL_4 0x634 +#define MSR_C_STATE_LATENCY_CONTROL_5 0x635 +#define IRTL_VALID (1 << 15) +#define IRTL_1_NS (0 << 10) +#define IRTL_32_NS (1 << 10) +#define IRTL_1024_NS (2 << 10) +#define IRTL_32768_NS (3 << 10) +#define IRTL_1048576_NS (4 << 10) +#define IRTL_33554432_NS (5 << 10) +#define IRTL_RESPONSE_MASK (0x3ff) + #define MSR_PKG_POWER_LIMIT 0x00000610 +/* long duration in low dword, short duration in high dword */ +#define PKG_POWER_LIMIT_MASK 0x7fff +#define PKG_POWER_LIMIT_EN (1 << 15) +#define PKG_POWER_LIMIT_CLAMP (1 << 16) +#define PKG_POWER_LIMIT_TIME_SHIFT 17 +#define PKG_POWER_LIMIT_TIME_MASK 0x7f + #define MSR_PKG_ENERGY_STATUS 0x00000611 #define MSR_PKG_PERF_STATUS 0x00000613 #define MSR_PKG_POWER_INFO 0x00000614 @@ -165,7 +203,8 @@ #define MSR_PP1_POWER_LIMIT 0x00000640 #define MSR_PP1_ENERGY_STATUS 0x00000641 #define MSR_PP1_POLICY 0x00000642 - +#define MSR_CONFIG_TDP_NOMINAL 0x00000648 +#define MSR_TURBO_ACTIVATION_RATIO 0x0000064c #define MSR_CORE_C1_RES 0x00000660 #define MSR_IACORE_RATIOS 0x0000066a #define MSR_IACORE_TURBO_RATIOS 0x0000066c diff --git a/arch/x86/include/asm/pch_common.h b/arch/x86/include/asm/pch_common.h new file mode 100644 index 0000000000..924ccc4db5 --- /dev/null +++ b/arch/x86/include/asm/pch_common.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __asm_pch_common_h +#define __asm_pch_common_h + +/* Common Intel SATA registers */ +#define SATA_SIRI 0xa0 /* SATA Indexed Register Index */ +#define SATA_SIRD 0xa4 /* SATA Indexed Register Data */ +#define SATA_SP 0xd0 /* Scratchpad */ + +#define INTR_LN 0x3c +#define IDE_TIM_PRI 0x40 /* IDE timings, primary */ +#define IDE_DECODE_ENABLE (1 << 15) +#define IDE_SITRE (1 << 14) +#define IDE_ISP_5_CLOCKS (0 << 12) +#define IDE_ISP_4_CLOCKS (1 << 12) +#define IDE_ISP_3_CLOCKS (2 << 12) +#define IDE_RCT_4_CLOCKS (0 << 8) +#define IDE_RCT_3_CLOCKS (1 << 8) +#define IDE_RCT_2_CLOCKS (2 << 8) +#define IDE_RCT_1_CLOCKS (3 << 8) +#define IDE_DTE1 (1 << 7) +#define IDE_PPE1 (1 << 6) +#define IDE_IE1 (1 << 5) +#define IDE_TIME1 (1 << 4) +#define IDE_DTE0 (1 << 3) +#define IDE_PPE0 (1 << 2) +#define IDE_IE0 (1 << 1) +#define IDE_TIME0 (1 << 0) +#define IDE_TIM_SEC 0x42 /* IDE timings, secondary */ + +#define SERIRQ_CNTL 0x64 + +/** + * pch_common_sir_read() - Read from a SATA indexed register + * + * @dev: SATA device + * @idx: Register index to read + * @return value read from register + */ +u32 pch_common_sir_read(struct udevice *dev, int idx); + +/** + * pch_common_sir_write() - Write to a SATA indexed register + * + * @dev: SATA device + * @idx: Register index to write + * @value: Value to write + */ +void pch_common_sir_write(struct udevice *dev, int idx, u32 value); + +#endif diff --git a/arch/x86/include/asm/post.h b/arch/x86/include/asm/post.h index f49ce992d1..6b774bdbe8 100644 --- a/arch/x86/include/asm/post.h +++ b/arch/x86/include/asm/post.h @@ -29,8 +29,8 @@ #define POST_CPU_INFO 0x2d #define POST_PRE_MRC 0x2e #define POST_MRC 0x2f -#define POST_DRAM 0x2f -#define POST_LAPIC 0x30 +#define POST_DRAM 0x30 +#define POST_LAPIC 0x31 #define POST_RAM_FAILURE 0xea #define POST_BIST_FAILURE 0xeb diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 7c77b90485..cefc633910 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -36,7 +36,7 @@ * * The naming follows Intel's naming. */ -#define PORT_RESET 0xcf9 +#define IO_PORT_RESET 0xcf9 enum { SYS_RST = 1 << 1, /* 0 for soft reset, 1 for hard reset */ diff --git a/arch/x86/include/asm/report_platform.h b/arch/x86/include/asm/report_platform.h new file mode 100644 index 0000000000..4607dd334e --- /dev/null +++ b/arch/x86/include/asm/report_platform.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __ARCH_REPORT_PLATFORM_H +#define __ARCH_REPORT_PLATFORM_H + +/** + * report_platform_info() - Report platform information + * + * This reports information about the CPU and chipset. + * + * @dev: Northbridge device + */ +void report_platform_info(struct udevice *dev); + +#endif diff --git a/arch/x86/include/asm/sipi.h b/arch/x86/include/asm/sipi.h index 25d7d311d2..da91a485d8 100644 --- a/arch/x86/include/asm/sipi.h +++ b/arch/x86/include/asm/sipi.h @@ -42,6 +42,7 @@ struct __packed sipi_params_16bit { * struct sipi_params - 32-bit SIP entry-point parameters * * These are used by the AP init code and must be set up before the APs start. + * The members must match with the sipi_params layout in sipi_vector.S. * * The stack area extends down from @stack_top, with @stack_size allocated * for each AP. diff --git a/arch/x86/include/asm/tables.h b/arch/x86/include/asm/tables.h index 0aa6d9b33e..ae9f0d0d62 100644 --- a/arch/x86/include/asm/tables.h +++ b/arch/x86/include/asm/tables.h @@ -14,6 +14,11 @@ */ #define ROM_TABLE_ADDR 0xf0000 +#define ROM_TABLE_ALIGN 1024 + +/* SeaBIOS expects coreboot tables at address range 0x0000-0x1000 */ +#define CB_TABLE_ADDR 0x800 + /** * table_compute_checksum() - Compute a table checksum * diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 4fc19365eb..dc90df2050 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -10,6 +10,7 @@ obj-y += bios_asm.o obj-y += bios_interrupts.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-y += cmd_boot.o +obj-y += coreboot_table.o obj-$(CONFIG_EFI) += efi/ obj-y += e820.o obj-y += gcc.o @@ -22,6 +23,7 @@ obj-y += cmd_mtrr.o obj-y += northbridge-uclass.o obj-$(CONFIG_I8259_PIC) += i8259.o obj-$(CONFIG_I8254_TIMER) += i8254.o +obj-y += pinctrl_ich6.o obj-y += pirq_routing.o obj-y += relocate.o obj-y += physmem.o diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 2ec5ad2fa4..790f6fbd0f 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -335,9 +335,9 @@ static void acpi_create_ssdt_generator(acpi_header_t *ssdt, * QEMU's version of write_acpi_tables is defined in * arch/x86/cpu/qemu/fw_cfg.c */ -unsigned long write_acpi_tables(unsigned long start) +u32 write_acpi_tables(u32 start) { - unsigned long current; + u32 current; struct acpi_rsdp *rsdp; struct acpi_rsdt *rsdt; struct acpi_xsdt *xsdt; diff --git a/arch/x86/lib/coreboot_table.c b/arch/x86/lib/coreboot_table.c new file mode 100644 index 0000000000..cb45a79857 --- /dev/null +++ b/arch/x86/lib/coreboot_table.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2016, Bin Meng <bmeng.cn@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <vbe.h> +#include <asm/coreboot_tables.h> +#include <asm/e820.h> + +/** + * cb_table_init() - initialize a coreboot table header + * + * This fills in the coreboot table header signature and the header bytes. + * Other fields are set to zero. + * + * @cbh: coreboot table header address + */ +static void cb_table_init(struct cb_header *cbh) +{ + memset(cbh, 0, sizeof(struct cb_header)); + memcpy(cbh->signature, "LBIO", 4); + cbh->header_bytes = sizeof(struct cb_header); +} + +/** + * cb_table_add_entry() - add a coreboot table entry + * + * This increases the coreboot table entry size with added table entry length + * and increases entry count by 1. + * + * @cbh: coreboot table header address + * @cbr: to be added table entry address + * @return: pointer to next table entry address + */ +static u32 cb_table_add_entry(struct cb_header *cbh, struct cb_record *cbr) +{ + cbh->table_bytes += cbr->size; + cbh->table_entries++; + + return (u32)cbr + cbr->size; +} + +/** + * cb_table_finalize() - finalize the coreboot table + * + * This calculates the checksum for all coreboot table entries as well as + * the checksum for the coreboot header itself. + * + * @cbh: coreboot table header address + */ +static void cb_table_finalize(struct cb_header *cbh) +{ + struct cb_record *cbr = (struct cb_record *)(cbh + 1); + + cbh->table_checksum = compute_ip_checksum(cbr, cbh->table_bytes); + cbh->header_checksum = compute_ip_checksum(cbh, cbh->header_bytes); +} + +void write_coreboot_table(u32 addr, struct memory_area *cfg_tables) +{ + struct cb_header *cbh = (struct cb_header *)addr; + struct cb_record *cbr; + struct cb_memory *mem; + struct cb_memory_range *map; + struct e820entry e820[32]; + struct cb_framebuffer *fb; + struct vesa_mode_info *vesa; + int i, num; + + cb_table_init(cbh); + cbr = (struct cb_record *)(cbh + 1); + + /* + * Two type of coreboot table entries are generated by us. + * They are 'struct cb_memory' and 'struct cb_framebuffer'. + */ + + /* populate memory map table */ + mem = (struct cb_memory *)cbr; + mem->tag = CB_TAG_MEMORY; + map = mem->map; + + /* first install e820 defined memory maps */ + num = install_e820_map(ARRAY_SIZE(e820), e820); + for (i = 0; i < num; i++) { + map->start.lo = e820[i].addr & 0xffffffff; + map->start.hi = e820[i].addr >> 32; + map->size.lo = e820[i].size & 0xffffffff; + map->size.hi = e820[i].size >> 32; + map->type = e820[i].type; + map++; + } + + /* then install all configuration tables */ + while (cfg_tables->size) { + map->start.lo = cfg_tables->start & 0xffffffff; + map->start.hi = cfg_tables->start >> 32; + map->size.lo = cfg_tables->size & 0xffffffff; + map->size.hi = cfg_tables->size >> 32; + map->type = CB_MEM_TABLE; + map++; + num++; + cfg_tables++; + } + mem->size = num * sizeof(struct cb_memory_range) + + sizeof(struct cb_record); + cbr = (struct cb_record *)cb_table_add_entry(cbh, cbr); + + /* populate framebuffer table if we have sane vesa info */ + vesa = &mode_info.vesa; + if (vesa->x_resolution && vesa->y_resolution) { + fb = (struct cb_framebuffer *)cbr; + fb->tag = CB_TAG_FRAMEBUFFER; + fb->size = sizeof(struct cb_framebuffer); + + fb->x_resolution = vesa->x_resolution; + fb->y_resolution = vesa->y_resolution; + fb->bits_per_pixel = vesa->bits_per_pixel; + fb->bytes_per_line = vesa->bytes_per_scanline; + fb->physical_address = vesa->phys_base_ptr; + fb->red_mask_size = vesa->red_mask_size; + fb->red_mask_pos = vesa->red_mask_pos; + fb->green_mask_size = vesa->green_mask_size; + fb->green_mask_pos = vesa->green_mask_pos; + fb->blue_mask_size = vesa->blue_mask_size; + fb->blue_mask_pos = vesa->blue_mask_pos; + fb->reserved_mask_size = vesa->reserved_mask_size; + fb->reserved_mask_pos = vesa->reserved_mask_pos; + + cbr = (struct cb_record *)cb_table_add_entry(cbh, cbr); + } + + cb_table_finalize(cbh); +} diff --git a/arch/x86/lib/fsp/fsp_car.S b/arch/x86/lib/fsp/fsp_car.S index 15b37512a5..fbe8aef540 100644 --- a/arch/x86/lib/fsp/fsp_car.S +++ b/arch/x86/lib/fsp/fsp_car.S @@ -102,6 +102,8 @@ temp_ram_init_romstack: temp_ram_init_params: _dt_ucode_base_size: /* These next two fields are filled in by ifdtool */ +.globl ucode_base +ucode_base: /* Declared in micrcode.h */ .long 0 /* microcode base */ .long 0 /* microcode size */ .long CONFIG_SYS_MONITOR_BASE /* code region base */ diff --git a/arch/x86/lib/mpspec.c b/arch/x86/lib/mpspec.c index 0faa582d77..6ab43f1055 100644 --- a/arch/x86/lib/mpspec.c +++ b/arch/x86/lib/mpspec.c @@ -297,7 +297,7 @@ static int mptable_add_intsrc(struct mp_config_table *mc, const u32 *cell; int i, ret; - ret = uclass_first_device(UCLASS_IRQ, &dev); + ret = uclass_first_device_err(UCLASS_IRQ, &dev); if (ret && ret != -ENODEV) { debug("%s: Cannot find irq router node\n", __func__); return ret; diff --git a/arch/x86/lib/pinctrl_ich6.c b/arch/x86/lib/pinctrl_ich6.c new file mode 100644 index 0000000000..3f94cdf2da --- /dev/null +++ b/arch/x86/lib/pinctrl_ich6.c @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <pch.h> +#include <pci.h> +#include <asm/cpu.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <asm/pci.h> +#include <dm/pinctrl.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define GPIO_USESEL_OFFSET(x) (x) +#define GPIO_IOSEL_OFFSET(x) (x + 4) +#define GPIO_LVL_OFFSET(x) ((x) ? (x) + 8 : 0xc) +#define GPI_INV 0x2c + +#define IOPAD_MODE_MASK 0x7 +#define IOPAD_PULL_ASSIGN_SHIFT 7 +#define IOPAD_PULL_ASSIGN_MASK (0x3 << IOPAD_PULL_ASSIGN_SHIFT) +#define IOPAD_PULL_STRENGTH_SHIFT 9 +#define IOPAD_PULL_STRENGTH_MASK (0x3 << IOPAD_PULL_STRENGTH_SHIFT) + +static int ich6_pinctrl_set_value(uint16_t base, unsigned offset, int value) +{ + if (value) + setio_32(base, 1UL << offset); + else + clrio_32(base, 1UL << offset); + + return 0; +} + +static int ich6_pinctrl_set_function(uint16_t base, unsigned offset, int func) +{ + if (func) + setio_32(base, 1UL << offset); + else + clrio_32(base, 1UL << offset); + + return 0; +} + +static int ich6_pinctrl_set_direction(uint16_t base, unsigned offset, int dir) +{ + if (!dir) + setio_32(base, 1UL << offset); + else + clrio_32(base, 1UL << offset); + + return 0; +} + +static int ich6_pinctrl_cfg_pin(s32 gpiobase, s32 iobase, int pin_node) +{ + bool is_gpio, invert; + u32 gpio_offset[2]; + int pad_offset; + int dir, val; + int ret; + + /* + * GPIO node is not mandatory, so we only do the pinmuxing if the + * node exists. + */ + ret = fdtdec_get_int_array(gd->fdt_blob, pin_node, "gpio-offset", + gpio_offset, 2); + if (!ret) { + /* Do we want to force the GPIO mode? */ + is_gpio = fdtdec_get_bool(gd->fdt_blob, pin_node, "mode-gpio"); + if (is_gpio) + ich6_pinctrl_set_function(GPIO_USESEL_OFFSET(gpiobase) + + gpio_offset[0], gpio_offset[1], + 1); + + dir = fdtdec_get_int(gd->fdt_blob, pin_node, "direction", -1); + if (dir != -1) + ich6_pinctrl_set_direction(GPIO_IOSEL_OFFSET(gpiobase) + + gpio_offset[0], gpio_offset[1], + dir); + + val = fdtdec_get_int(gd->fdt_blob, pin_node, "output-value", + -1); + if (val != -1) + ich6_pinctrl_set_value(GPIO_LVL_OFFSET(gpiobase) + + gpio_offset[0], gpio_offset[1], + val); + + invert = fdtdec_get_bool(gd->fdt_blob, pin_node, "invert"); + if (invert) + setio_32(gpiobase + GPI_INV, 1 << gpio_offset[1]); + debug("gpio %#x bit %d, is_gpio %d, dir %d, val %d, invert %d\n", + gpio_offset[0], gpio_offset[1], is_gpio, dir, val, + invert); + } + + /* if iobase is present, let's configure the pad */ + if (iobase != -1) { + int iobase_addr; + + /* + * The offset for the same pin for the IOBASE and GPIOBASE are + * different, so instead of maintaining a lookup table, + * the device tree should provide directly the correct + * value for both mapping. + */ + pad_offset = fdtdec_get_int(gd->fdt_blob, pin_node, + "pad-offset", -1); + if (pad_offset == -1) + return 0; + + /* compute the absolute pad address */ + iobase_addr = iobase + pad_offset; + + /* + * Do we need to set a specific function mode? + * If someone put also 'mode-gpio', this option will + * be just ignored by the controller + */ + val = fdtdec_get_int(gd->fdt_blob, pin_node, "mode-func", -1); + if (val != -1) + clrsetbits_le32(iobase_addr, IOPAD_MODE_MASK, val); + + /* Configure the pull-up/down if needed */ + val = fdtdec_get_int(gd->fdt_blob, pin_node, "pull-assign", -1); + if (val != -1) + clrsetbits_le32(iobase_addr, + IOPAD_PULL_ASSIGN_MASK, + val << IOPAD_PULL_ASSIGN_SHIFT); + + val = fdtdec_get_int(gd->fdt_blob, pin_node, "pull-strength", + -1); + if (val != -1) + clrsetbits_le32(iobase_addr, + IOPAD_PULL_STRENGTH_MASK, + val << IOPAD_PULL_STRENGTH_SHIFT); + + debug("%s: pad cfg [0x%x]: %08x\n", __func__, pad_offset, + readl(iobase_addr)); + } + + return 0; +} + +static int ich6_pinctrl_probe(struct udevice *dev) +{ + struct udevice *pch; + int pin_node; + int ret; + u32 gpiobase; + u32 iobase = -1; + + debug("%s: start\n", __func__); + ret = uclass_first_device(UCLASS_PCH, &pch); + if (ret) + return ret; + if (!pch) + return -ENODEV; + + /* + * Get the memory/io base address to configure every pins. + * IOBASE is used to configure the mode/pads + * GPIOBASE is used to configure the direction and default value + */ + ret = pch_get_gpio_base(pch, &gpiobase); + if (ret) { + debug("%s: invalid GPIOBASE address (%08x)\n", __func__, + gpiobase); + return -EINVAL; + } + + /* + * Get the IOBASE, this is not mandatory as this is not + * supported by all the CPU + */ + ret = pch_get_io_base(pch, &iobase); + if (ret && ret != -ENOSYS) { + debug("%s: invalid IOBASE address (%08x)\n", __func__, iobase); + return -EINVAL; + } + + for (pin_node = fdt_first_subnode(gd->fdt_blob, dev->of_offset); + pin_node > 0; + pin_node = fdt_next_subnode(gd->fdt_blob, pin_node)) { + /* Configure the pin */ + ret = ich6_pinctrl_cfg_pin(gpiobase, iobase, pin_node); + if (ret != 0) { + debug("%s: invalid configuration for the pin %d\n", + __func__, pin_node); + return ret; + } + } + debug("%s: done\n", __func__); + + return 0; +} + +static const struct udevice_id ich6_pinctrl_match[] = { + { .compatible = "intel,x86-pinctrl", .data = X86_SYSCON_PINCONF }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(ich6_pinctrl) = { + .name = "ich6_pinctrl", + .id = UCLASS_SYSCON, + .of_match = ich6_pinctrl_match, + .probe = ich6_pinctrl_probe, +}; diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c index 14b15cf389..a156f2ce31 100644 --- a/arch/x86/lib/tables.c +++ b/arch/x86/lib/tables.c @@ -10,6 +10,33 @@ #include <asm/smbios.h> #include <asm/tables.h> #include <asm/acpi_table.h> +#include <asm/coreboot_tables.h> + +/** + * Function prototype to write a specific configuration table + * + * @addr: start address to write the table + * @return: end address of the table + */ +typedef u32 (*table_write)(u32 addr); + +static table_write table_write_funcs[] = { +#ifdef CONFIG_GENERATE_PIRQ_TABLE + write_pirq_routing_table, +#endif +#ifdef CONFIG_GENERATE_SFI_TABLE + write_sfi_table, +#endif +#ifdef CONFIG_GENERATE_MP_TABLE + write_mp_table, +#endif +#ifdef CONFIG_GENERATE_ACPI_TABLE + write_acpi_tables, +#endif +#ifdef CONFIG_GENERATE_SMBIOS_TABLE + write_smbios_table, +#endif +}; u8 table_compute_checksum(void *v, int len) { @@ -39,26 +66,38 @@ void table_fill_string(char *dest, const char *src, size_t n, char pad) void write_tables(void) { - u32 __maybe_unused rom_table_end = ROM_TABLE_ADDR; - -#ifdef CONFIG_GENERATE_PIRQ_TABLE - rom_table_end = write_pirq_routing_table(rom_table_end); - rom_table_end = ALIGN(rom_table_end, 1024); -#endif -#ifdef CONFIG_GENERATE_SFI_TABLE - rom_table_end = write_sfi_table(rom_table_end); - rom_table_end = ALIGN(rom_table_end, 1024); + u32 rom_table_start = ROM_TABLE_ADDR; + u32 rom_table_end; +#ifdef CONFIG_SEABIOS + u32 high_table, table_size; + struct memory_area cfg_tables[ARRAY_SIZE(table_write_funcs) + 1]; #endif -#ifdef CONFIG_GENERATE_MP_TABLE - rom_table_end = write_mp_table(rom_table_end); - rom_table_end = ALIGN(rom_table_end, 1024); -#endif -#ifdef CONFIG_GENERATE_ACPI_TABLE - rom_table_end = write_acpi_tables(rom_table_end); - rom_table_end = ALIGN(rom_table_end, 1024); + int i; + + for (i = 0; i < ARRAY_SIZE(table_write_funcs); i++) { + rom_table_end = table_write_funcs[i](rom_table_start); + rom_table_end = ALIGN(rom_table_end, ROM_TABLE_ALIGN); + +#ifdef CONFIG_SEABIOS + table_size = rom_table_end - rom_table_start; + high_table = (u32)memalign(ROM_TABLE_ALIGN, table_size); + if (high_table) { + memset((void *)high_table, 0, table_size); + table_write_funcs[i](high_table); + + cfg_tables[i].start = high_table; + cfg_tables[i].size = table_size; + } else { + printf("%d: no memory for configuration tables\n", i); + } #endif -#ifdef CONFIG_GENERATE_SMBIOS_TABLE - rom_table_end = write_smbios_table(rom_table_end); - rom_table_end = ALIGN(rom_table_end, 1024); + + rom_table_start = rom_table_end; + } + +#ifdef CONFIG_SEABIOS + /* make sure the last item is zero */ + cfg_tables[i].size = 0; + write_coreboot_table(CB_TABLE_ADDR, cfg_tables); #endif } |